local j=script.Parent local L=require(game.ReplicatedStorage.Modules.ItemData)local u={}function GetDictionaryLength(j)local L=0 for j,u in next,j do L=L+1 end return L end addAnt=coroutine.wrap(function()while task.wait(5)do if GetDictionaryLength(u)<3 then local L=game.ServerStorage.Creatures["\083\099\097\118\101\110\103\101\114 \065\110\116"]:Clone()L:SetPrimaryPartCFrame(j.PrimaryPart.CFrame*CFrame.new(0,5,0))L.Parent=j u[L]={carrying=nil;target=nil;destination=L.PrimaryPart.Position;lastOrder=tick();lastScan=tick();anims={}}for j,a in next,game.ReplicatedStorage.NPCAnimations.Ant:GetChildren()do u[L].anims[a.Name]=(L:WaitForChild("\072\117\109")):LoadAnimation(a)end;(L:WaitForChild("\072\101\097\108\116\104")).Changed:connect(function()L.PrimaryPart.Hurt.Pitch=L.PrimaryPart.Hurt.OriginalPitch.Value+math.random(-100,100)/100 L.PrimaryPart.Hurt:Play()end)L.AncestryChanged:connect(function()u[L]=nil end)end task.wait(55)end end)addAnt()function Seeking(j,L)for j,u in pairs(j)do if u==L then return true end end return false end manageAnts=coroutine.wrap(function()while task.wait(1)do local a={}for P,b in next,u do spawn(function()if P and(P.PrimaryPart and(P:FindFirstChild("\072\117\109")and(P.Hum.Health>0 and P:IsDescendantOf(workspace))))then u[P].lastScan=tick()if not u[P].carrying then local j,b=nil,math.huge for u,Q in next,workspace.Critters:GetChildren()do if not Seeking(a,Q)and(Q:FindFirstChild("\072\105\116\083\104\101\108\108")and L[Q.Name].abductable)then local L,u=P.PrimaryPart,Q.PrimaryPart if not u then u=Q:FindFirstChildOfClass("\066\097\115\101\080\097\114\116")end local a=(u.Position-L.Position).magnitude if a<b then j=Q b=a end end end if P and j then u[P].destination=j.PrimaryPart.Position u[P].target=j table.insert(a,j)u[P].target.AncestryChanged:connect(function()u[P].target=nil end)end else u[P].destination=j.PrimaryPart.Position+Vector3.new(0,3,0)end if u[P].destination then P.Hum:MoveTo(u[P].destination)if not u[P].anims.AntWalk.IsPlaying then u[P].anims.AntWalk:Play()end if b.target and not b.carrying then local j=(P.PrimaryPart.Position-u[P].target.PrimaryPart.Position).magnitude if j<5 then local j=game.ServerStorage.Misc["\065\098\100\117\099\116\101\100 \083\104\101\108\108\121"]:Clone()b.carrying=j j.Shell.Material=b.target.Shell.Material j.Shell.Color=b.target.Shell.Color j.ActualName.Value=b.target.Name b.target:Destroy()j.Parent=P u[P].anims.AntWalk:Stop()u[P].anims.AntHold:Play()P.PrimaryPart.Chatter:Play()P.PrimaryPart.ShellyAbduct:Play()local L=Instance.new("\077\097\110\117\097\108\087\101\108\100")L.Parent=P.PrimaryPart L.Part0=P.PrimaryPart L.Part1=j.PrimaryPart L.C0=CFrame.new(-0.4,.4,-1.6)*CFrame.Angles(0,math.rad(90),0)end elseif b.carrying then local j=(P.PrimaryPart.Position-u[P].destination).magnitude if j<7 then P.Hum:MoveTo(P.PrimaryPart.Position)P.PrimaryPart.Chatter:Play()u[P].anims.AntHold:Stop()u[P].anims.AntWalk:Stop()u[P].carrying:Destroy()u[P].carrying=nil u[P].destination=nil u[P].target=nil end end end end end)end end end)manageAnts()

local hill = script.Parent
local itemData = require(game.ReplicatedStorage.Modules.ItemData)
local activeAnts = {}

function GetDictionaryLength(tab)
	local total = 0
	for _,v in next, tab do
		total = total + 1
	end
	return total
end


addAnt = coroutine.wrap(function()
	while task.wait(5) do
		if GetDictionaryLength(activeAnts) < 3 then
			local newAnt = game.ServerStorage.Creatures['Scavenger Ant']:Clone()
			newAnt:SetPrimaryPartCFrame(hill.PrimaryPart.CFrame*CFrame.new(0,5,0))
			newAnt.Parent = hill
			
			activeAnts[newAnt] = {
				["carrying"] = nil,
				["target"] = nil,
				["destination"] = newAnt.PrimaryPart.Position,
				["lastOrder"] = tick(),
				["lastScan"] = tick(),
				["anims"] = {},
			}
			
			for _,anim in next,game.ReplicatedStorage.NPCAnimations.Ant:GetChildren() do
				activeAnts[newAnt].anims[anim.Name] = newAnt:WaitForChild("Hum"):LoadAnimation(anim)
			end
			
			newAnt:WaitForChild'Health'.Changed:connect(function()
				newAnt.PrimaryPart.Hurt.Pitch = newAnt.PrimaryPart.Hurt.OriginalPitch.Value+(math.random(-100,100)/100)
				newAnt.PrimaryPart.Hurt:Play()
			end)
		
			newAnt.AncestryChanged:connect(function()
			activeAnts[newAnt] = nil
			end)
		end
		task.wait(55)
	end
end)

addAnt()

function Seeking(array, target)--Queen ant keeps track of her workers. ;)
	for i,v in pairs(array) do
		if v == target then
			return true
		end
	end
	return false
end

manageAnts = coroutine.wrap(function()
	while task.wait(1) do
		local seeking = {}
		for ant, antData in next,activeAnts do
			spawn(function()
				if ant and ant.PrimaryPart and ant:FindFirstChild'Hum' and ant.Hum.Health > 0 and ant:IsDescendantOf(workspace) then
					activeAnts[ant].lastScan = tick()
					-- scan for nearest Shelly
					if not activeAnts[ant].carrying then
						local nearestShelly,closestDist = nil,math.huge
						
						for _,creature in next, workspace.Critters:GetChildren() do
							if not Seeking(seeking, creature) and creature:FindFirstChild'HitShell' and itemData[creature.Name].abductable then
								
								local a, c = ant.PrimaryPart, creature.PrimaryPart
								
								if not c then
									c = creature:FindFirstChildOfClass'BasePart'
								end
									
								local dist = (c.Position-a.Position).magnitude
								
								if dist < closestDist then
									nearestShelly = creature
									closestDist = dist
								end
							end
						end
						
						if ant and nearestShelly then
							activeAnts[ant].destination = nearestShelly.PrimaryPart.Position
							activeAnts[ant].target = nearestShelly
							table.insert(seeking, nearestShelly)
							
							activeAnts[ant].target.AncestryChanged:connect(function()
								activeAnts[ant].target = nil
							end)
						end
						
					else	
						activeAnts[ant].destination  = hill.PrimaryPart.Position+Vector3.new(0,3,0)
					end
					
					if activeAnts[ant].destination then
						ant.Hum:MoveTo(activeAnts[ant].destination)
						if not activeAnts[ant].anims.AntWalk.IsPlaying then
							activeAnts[ant].anims.AntWalk:Play()
						end
					
						if antData.target and not antData.carrying then
							local dist = (ant.PrimaryPart.Position-activeAnts[ant].target.PrimaryPart.Position).magnitude
							if dist < 5 then
								-- let's get a new shelly
								local abductedShelly = game.ServerStorage.Misc["Abducted Shelly"]:Clone()
								antData.carrying = abductedShelly
								abductedShelly.Shell.Material = antData.target.Shell.Material
								abductedShelly.Shell.Color = antData.target.Shell.Color
								abductedShelly.ActualName.Value = antData.target.Name
								--game.ReplicatedStorage.Events.NPCAttack:Fire(antData.target,math.huge)
								antData.target:Destroy()
								abductedShelly.Parent = ant
								activeAnts[ant].anims.AntWalk:Stop()
								activeAnts[ant].anims.AntHold:Play()
								ant.PrimaryPart.Chatter:Play()
								ant.PrimaryPart.ShellyAbduct:Play()
								-- weld the shelly to the torso
								local weld = Instance.new("ManualWeld")
								weld.Parent = ant.PrimaryPart
								weld.Part0 = ant.PrimaryPart
								weld.Part1 = abductedShelly.PrimaryPart
								weld.C0 = CFrame.new(-.4,.4,-1.6)*CFrame.Angles(0,math.rad(90),0)
							end
						
						elseif antData.carrying then
							local dist = (ant.PrimaryPart.Position-activeAnts[ant].destination).magnitude
							if dist < 7 then
								ant.Hum:MoveTo(ant.PrimaryPart.Position)
								ant.PrimaryPart.Chatter:Play()
								activeAnts[ant].anims.AntHold:Stop()
								activeAnts[ant].anims.AntWalk:Stop()
								activeAnts[ant].carrying:Destroy()
								activeAnts[ant].carrying = nil
								activeAnts[ant].destination = nil
								activeAnts[ant].target = nil
							end
						end
					end
				end
			end)--Help prevent breaking and faster responding times for ants.
		end--Shouldn't error now though.
	end
end)

manageAnts()
