local z=require(script.Parent.BaseMotor)local a=require(script.Parent.SingleMotor)local h=require(script.Parent.isMotor)local n=setmetatable({},z)n.__index=n local function P(z)if h(z)then return z end local P=typeof(z)if P=="\110\117\109\098\101\114"then return a.new(z,false)elseif P=="\116\097\098\108\101"then return n.new(z,false)end error(("\085\110\097\098\108\101 \116\111 \099\111\110\118\101\114\116 \037\113 \116\111 \109\111\116\111\114\059 \116\121\112\101 \037\115 \105\115 \117\110\115\117\112\112\111\114\116\101\100"):format(z,P),2)end function n.new(a,h)assert(a,"\077\105\115\115\105\110\103 \097\114\103\117\109\101\110\116 \035\049\058 \105\110\105\116\105\097\108\086\097\108\117\101\115")assert(typeof(a)=="\116\097\098\108\101","\105\110\105\116\105\097\108\086\097\108\117\101\115 \109\117\115\116 \098\101 \097 \116\097\098\108\101\033")assert(not a.step,"\105\110\105\116\105\097\108\086\097\108\117\101\115 \099\111\110\116\097\105\110\115 \100\105\115\097\108\108\111\119\101\100 \112\114\111\112\101\114\116\121 \"\115\116\101\112\"\046 \068\105\100 \121\111\117 \109\101\097\110 \116\111 \112\117\116 \097 \116\097\098\108\101 \111\102 \118\097\108\117\101\115 \104\101\114\101\063")local f=setmetatable(z.new(),n)if h~=nil then f._useImplicitConnections=h else f._useImplicitConnections=true end f._complete=true f._motors={}for z,a in pairs(a)do f._motors[z]=P(a)end return f end function n.step(a,z)if a._complete then return true end local h=true for a,n in pairs(a._motors)do local P=n:step(z)if not P then h=false end end a._onStep:fire(a:getValue())if h then if a._useImplicitConnections then a:stop()end a._complete=true a._onComplete:fire()end return h end function n.setGoal(a,z)assert(not z.step,"\103\111\097\108\115 \099\111\110\116\097\105\110\115 \100\105\115\097\108\108\111\119\101\100 \112\114\111\112\101\114\116\121 \"\115\116\101\112\"\046 \068\105\100 \121\111\117 \109\101\097\110 \116\111 \112\117\116 \097 \116\097\098\108\101 \111\102 \103\111\097\108\115 \104\101\114\101\063")a._complete=false a._onStart:fire()for z,h in pairs(z)do local n=assert(a._motors[z],("\085\110\107\110\111\119\110 \109\111\116\111\114 \102\111\114 \107\101\121 \037\115"):format(z))n:setGoal(h)end if a._useImplicitConnections then a:start()end end function n.getValue(z)local a={}for z,h in pairs(z._motors)do a[z]=h:getValue()end return a end function n.__tostring(z)return"\077\111\116\111\114\040\071\114\111\117\112\041"end return n
local BaseMotor = require(script.Parent.BaseMotor)
local SingleMotor = require(script.Parent.SingleMotor)

local isMotor = require(script.Parent.isMotor)

local GroupMotor = setmetatable({}, BaseMotor)
GroupMotor.__index = GroupMotor

local function toMotor(value)
	if isMotor(value) then
		return value
	end

	local valueType = typeof(value)

	if valueType == "number" then
		return SingleMotor.new(value, false)
	elseif valueType == "table" then
		return GroupMotor.new(value, false)
	end

	error(("Unable to convert %q to motor; type %s is unsupported"):format(value, valueType), 2)
end

function GroupMotor.new(initialValues, useImplicitConnections)
	assert(initialValues, "Missing argument #1: initialValues")
	assert(typeof(initialValues) == "table", "initialValues must be a table!")
	assert(
		not initialValues.step,
		'initialValues contains disallowed property "step". Did you mean to put a table of values here?'
	)

	local self = setmetatable(BaseMotor.new(), GroupMotor)

	if useImplicitConnections ~= nil then
		self._useImplicitConnections = useImplicitConnections
	else
		self._useImplicitConnections = true
	end

	self._complete = true
	self._motors = {}

	for key, value in pairs(initialValues) do
		self._motors[key] = toMotor(value)
	end

	return self
end

function GroupMotor:step(deltaTime)
	if self._complete then
		return true
	end

	local allMotorsComplete = true

	for _, motor in pairs(self._motors) do
		local complete = motor:step(deltaTime)
		if not complete then
			-- If any of the sub-motors are incomplete, the group motor will not be complete either
			allMotorsComplete = false
		end
	end

	self._onStep:fire(self:getValue())

	if allMotorsComplete then
		if self._useImplicitConnections then
			self:stop()
		end

		self._complete = true
		self._onComplete:fire()
	end

	return allMotorsComplete
end

function GroupMotor:setGoal(goals)
	assert(not goals.step, 'goals contains disallowed property "step". Did you mean to put a table of goals here?')

	self._complete = false
	self._onStart:fire()

	for key, goal in pairs(goals) do
		local motor = assert(self._motors[key], ("Unknown motor for key %s"):format(key))
		motor:setGoal(goal)
	end

	if self._useImplicitConnections then
		self:start()
	end
end

function GroupMotor:getValue()
	local values = {}

	for key, motor in pairs(self._motors) do
		values[key] = motor:getValue()
	end

	return values
end

function GroupMotor:__tostring()
	return "Motor(Group)"
end

return GroupMotor
