local C=game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local J=require(C.Shared.components)local function E(C)local E={}for C,J in C:query(J.Model,J.Target)do table.insert(E,J.model.PrimaryPart.CFrame.p)end for C,J,l,f in C:query(J.Roomba,J.Charge,J.Model)do if l.charge<=0 then continue end local T,w local Z=f.model.PrimaryPart.CFrame.p for C,J in ipairs(E)do local E=(Z-J).magnitude if not T or E<w then T=J w=E end end if T then local C=f.model.Roomba local J=C:GetMass()*20 if w<4 then J=0 end local E=C.CFrame.LookVector local l=(T-Z).unit J=J*E:Dot(l)C.VectorForce.Force=Vector3.new(J,0,0)local D=math.atan2(l.Z,l.X)local Q=math.atan2(E.Z,E.X)local j=math.deg(D-Q)j=j%360 j=(j+360)%360 if j>180 then j-=360 end local r=C.AssemblyAngularVelocity local X=math.sign(j)local s=((math.sqrt(math.abs(j))*X)*-1)*20 local A=r.Y*-12 local R=C:GetMass()*(s+A)C.Torque.Torque=Vector3.new(0,R,0)end end end return E
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Components = require(ReplicatedStorage.Shared.components)

local function roombasMove(world)
	local targets = {}
	for _, model in world:query(Components.Model, Components.Target) do
		table.insert(targets, model.model.PrimaryPart.CFrame.p)
	end

	for _, _, charge, model in world:query(Components.Roomba, Components.Charge, Components.Model) do
		if charge.charge <= 0 then
			continue
		end

		local closestPosition, closestDistance
		local currentPosition = model.model.PrimaryPart.CFrame.p

		for _, target in ipairs(targets) do
			local distance = (currentPosition - target).magnitude
			if not closestPosition or distance < closestDistance then
				closestPosition = target
				closestDistance = distance
			end
		end

		if closestPosition then
			local body = model.model.Roomba
			local force = body:GetMass() * 20

			if closestDistance < 4 then
				force = 0
			end

			local lookVector = body.CFrame.LookVector
			local desiredLookVector = (closestPosition - currentPosition).unit

			force = force * lookVector:Dot(desiredLookVector)
			body.VectorForce.Force = Vector3.new(force, 0, 0)

			local absoluteAngle = math.atan2(desiredLookVector.Z, desiredLookVector.X)
			local roombaAngle = math.atan2(lookVector.Z, lookVector.X)

			local angle = math.deg(absoluteAngle - roombaAngle)

			angle = angle % 360
			angle = (angle + 360) % 360
			if angle > 180 then
				angle -= 360
			end

			local angularVelocity = body.AssemblyAngularVelocity

			local sign = math.sign(angle)
			local motor = math.sqrt(math.abs(angle)) * sign * -1 * 20
			local friction = angularVelocity.Y * -12
			local torque = body:GetMass() * (motor + friction)

			body.Torque.Torque = Vector3.new(0, torque, 0)
		end
	end
end

return roombasMove
