PeasentTypes = {"mwwand1","mwwand2","mwwand3","mwwand6","mwwand4","mwwand5","mwwand10","mwwand11","mwwand12"}
Noble = {"noble3","noble4","noble1","noble2"}
PropsList = {"mwconst1","mwconst2","mwconst3","mwconst4","mwconst5","mwconst6","mwconst7"}
Trees = {"tree1lv1", "tree2lv1", "tree3lv1", "tree4lv1", "tree5lv1" }


WorldLoaded = function()
	-- set up Player
	People = {}
	LumberShaks = {}
	Lumberer = {}
	
	CamelShacks = {}
	CamelTrader = {}
	
	--Timer = 50
	Timer = Utils.RandomInteger(625,1250)
	CamelTimer = Utils.RandomInteger(325,650)
	
	Trigger.AfterDelay(1, function()
		People = Player.GetPlayers(function(P)
			return P.InternalName ~= "Neutral" and P.InternalName ~= "Creeps" and P.InternalName ~= "Everyone"
		end)
	end)
	
	Trigger.AfterDelay(2,function()
		--print(tostring(#People) .. " player found")
		for i = 1,#People do
			
			local who = People[i]
			--print(who.Name .. " Triggeredd!")
						
			Trigger.AfterDelay(DateTime.Seconds(10),function()
				SpawnSettlers(who)
			end)
			Trigger.AfterDelay(DateTime.Seconds(10),function()
				SpawnCommander(who)
			end)
		end
		Trigger.AfterDelay(DateTime.Seconds(60),SpawnSmithWorker)
		
		LumberShaks = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
			return C.Type == "split5"
		end)
		if LumberShaks and #LumberShaks > 0 then
			for i = 1, #LumberShaks do
				table.insert(Lumberer,"empty")
				Trigger.AfterDelay(DateTime.Seconds(Utils.RandomInteger(1,2)),function()
					SpawnATree(LumberShaks[i])
				end)
			end
			Trigger.AfterDelay(DateTime.Seconds(Utils.RandomInteger(25,45)),CheckForLumberjacks)
		end
		
		CamelShacks = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
			return C.Type == "split6"
		end)
		if CamelShacks and #CamelShacks > 0 then
			for i = 1, #CamelShacks do
				table.insert(CamelTrader,"empty")
				Trigger.AfterDelay(DateTime.Seconds(Utils.RandomInteger(1,2)),function()
					SpawnACamel(CamelShacks[i])
				end)
			end
			Trigger.AfterDelay(DateTime.Seconds(Utils.RandomInteger(25,45)),CheckForCamelTrader)
		end
		
	
	end)
	Trigger.OnEnteredProximityTrigger(Map.CenterOfCell(CPos.New(64,64)),WDist.FromCells(128), function(a, id)		
		if (a.Type == "prop1" or a.Type == "prop2" or a.Type == "prop3" or a.Type == "prop4" or a.Type == "prop5" or a.Type == "prop6" or a.Type == "prop7" ) then

			Trigger.AfterDelay(DateTime.Seconds(7), function()
				if a and (not a.IsDead) then
					
					local who = a.Owner
					local entries = {}
					
					entries = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
						return C.Type == "factnew" and C.Owner == who
					end)

					if #entries > 0 then
						local Factry = Utils.Random(entries)
					end
					
					if Factry and #Factry > 0 then
					
						--print("Line 89, Returning Worker: " .. tostring(a.Location))
						local worker = Actor.Create("mwconst1back",true,{Owner = who,Location = a.Location+CVec.New(0,1)})
						worker.Move(Factry.Location+CVec.New(1,2),5)
						worker.Destroy()
					end
				end
			end)
		end
	end)
	

end

CheckForCamelTrader = function()

	if CamelShacks and #CamelShacks > 0 then
		for i = 1, #CamelShacks do
			if CamelTrader[i] == "empty" then
				--print("Line 107, Camel: " .. tostring(CamelShacks[i].Location))
				table.insert(CamelTrader,i,Actor.Create("cameltrader",true,{Owner = CamelShacks[i].Owner,Location = CamelShacks[i].Location}))
				CamelTrader[i].Move(CamelTrader[i].Location+CVec.New(0,1),3)
			elseif CamelTrader[i].IsDead then
				table.remove(CamelTrader,i)
				--print("Line 111, Camel: " .. tostring(CamelShacks[i].Location))
				table.insert(CamelTrader,i,Actor.Create("cameltrader",true,{Owner = CamelShacks[i].Owner,Location = CamelShacks[i].Location}))
				CamelTrader[i].Move(CamelTrader[i].Location+CVec.New(0,1),3)
			end
		end
		Trigger.AfterDelay(DateTime.Seconds(Utils.RandomInteger(25,45)),CheckForCamelTrader)
	end
end

CheckForLumberjacks = function()

	if LumberShaks and #LumberShaks > 0 then
		for i = 1, #LumberShaks do
			if Lumberer[i] == "empty" then
				table.insert(Lumberer,i,Actor.Create("mwlumberer",true,{Owner = LumberShaks[i].Owner,Location = LumberShaks[i].Location}))
				--print("Line 107, Lumberer: " .. tostring(LumberShaks[i].Location)); Lumberer[i].Move(Lumberer[i].Location+CVec.New(0,1),3)
			elseif Lumberer[i].IsDead then
				table.remove(Lumberer,i)
				--print("Line 107, Lumberer: " .. tostring(LumberShaks[i].Location)); table.insert(Lumberer,i,Actor.Create("mwlumberer",true,{Owner = LumberShaks[i].Owner,Location = LumberShaks[i].Location}))
				Lumberer[i].Move(Lumberer[i].Location+CVec.New(0,1),3)
			end
		end
		Trigger.AfterDelay(DateTime.Seconds(Utils.RandomInteger(25,45)),CheckForLumberjacks)
	end
end

SpawnACamel = function(Lactor)

	local actors = Map.ActorsInCircle(Map.CenterOfCell(Lactor.Location),WDist.FromCells(8),function(C)
		return (C.Type == "mwcamel" or C.Type == "grownmwcamel") and (not C.IsDead)
	end)
	
	if #actors < 9 and Lactor and (not Lactor.IsDead) then
		local camel = Actor.Create("mwcamel",true,{Owner = Lactor.Owner,Location = Lactor.Location+CVec.New(1,0)})
		camel.Move(camel.Location+CVec.New(0,1),3)
	end
	
end

SpawnATree = function(Lactor)

	local points = {}	
	local actors = Map.ActorsInCircle(Map.CenterOfCell(Lactor.Location),WDist.FromCells(5))
	local points2 = {}
	local points3 = {}
	
	for i = 1, 3 do
		table.insert(points,Lactor.Location+CVec.New(i-2,4))
		table.insert(points,Lactor.Location+CVec.New(i-2,-4))
	end
	for i = 1, 5 do
		table.insert(points,Lactor.Location+CVec.New(i-3,3))
		table.insert(points,Lactor.Location+CVec.New(i-3,-3))
	end
	for i = 1, 7 do
		table.insert(points,Lactor.Location+CVec.New(i-4,2))
		table.insert(points,Lactor.Location+CVec.New(i-4,-2))
	end
	for i = 1, 7 do
		table.insert(points,Lactor.Location+CVec.New(i-4,1))
		table.insert(points,Lactor.Location+CVec.New(i-4,-1))
	end
	for i = 1, 7 do
		table.insert(points,Lactor.Location+CVec.New(i-4,0))
	end
	--print("Aviavable Cells 0: " .. tostring(#points))
	for i = 1, #points do
		if Map.TerrainType(points[i]) == "Clear" then
			table.insert(points2,points[i])
		end
	end
	--print("Aviavable Cells 1: " .. tostring(#points2))
	for i = 1, #points2 do
		if filter(points2[i],actors) then
			table.insert(points3,points2[i])
		end
	end
	--print("Aviavable Cells 1 refined: " .. tostring(#points3))
	if #points3 > 0 then
		Actor.Create(Utils.Random(Trees),true,{Owner = Lactor.Owner,Location = Utils.Random(points3)})
	end
	
	
end

filter = function(coordinate ,arry)
	local Set = true
	for a = 1, #arry do
		if coordinate == arry[a].Location then
			Set = false
			break
		end
	end
	return Set
	
end




Talkagain = function(Actor)
	if Actor and (not Actor.IsDead) then
		Actor.GrantCondition("Talking",Utils.RandomInteger(150,500))
		Trigger.AfterDelay(DateTime.Seconds(Utils.RandomInteger(15,90)),function()
			if Actor and (not Actor.IsDead) then
				Talkagain(Actor)
			end
		end)
	end
end

SpawnCommander = function(Player)


	local who = Player
	local commander = {}
	local barracks = {}
	local stalls = {}
	local hut = nil

	commander = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
		return (C.Type == "mwcivcom" ) and C.Owner == who
	end)
	--print(who.Name .. " Checked for peasantss: " .. tostring(#peasantss))
	
	barracks = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
		return (C.Type == "barrnew" or C.Type == "handnew" ) and C.Owner == who
	end)
	
	stalls = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
		return (C.Type == "stall" or C.Type == "nodstall" ) and C.Owner == who
	end)
	
	if #barracks > 0 then 
		hut = Utils.Random(barracks)
	end
	
	if #commander < 1 and hut and #stalls > 0 and (not hut.IsDead) then
		print("Line 248: " .. tostring(hut.Location))			
		peasent = Actor.Create("mwcivcom",true,{Owner = who,Location = hut.Location+CVec.New(1,1)})
		peasent.Move(peasent.Location+CVec.New(0,2),3)
		--print(who.Name .. " peasants spawned!")
	
	end
	
	Trigger.AfterDelay(DateTime.Seconds(10+math.floor(100/((#stalls*2 + #barracks +2 )/2))),function()
		SpawnCommander(who)
	end)	
end

SpawnSmithWorker = function()

	for i = 1,#People do
	
		local who = People[i]
		local labor = {}
		local worksgops = {}
		local hut = nil
	
		labor = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
			return (C.Type == "mwwand9" ) and C.Owner == People[i]
		end)
		
		worksgops = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
			return (C.Type == "workshopnod" or C.Type == "workshopgdi" ) and C.Owner == People[i]
		end)
		
		if #worksgops > 0 then
			hut = Utils.Random(worksgops)
		end
		
		if #labor < #worksgops*2 and hut and (not hut.IsDead) then
			--print("Line 282, Labourer: " .. tostring(hut.Location))
			peasent = Actor.Create("mwwand9",true,{Owner = who,Location = hut.Location+CVec.New(1,0)})
			peasent.Move(peasent.Location+CVec.New(0,-1),3)

		
		end
		
	end

	for i = 1,#People do
	
		local who = People[i]
		local bursar = {}
		local procssmall = {}
		local procslarge = {}
		local hut = nil
		local facts = {}
	
		bursar = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
			return (C.Type == "mwwand8" ) and C.Owner == People[i]
		end)
		--print(who.Name .. " Checked for peasantss: " .. tostring(#peasantss))
		
		procssmall = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
			return C.Type == "zeroproc" and C.Owner == People[i]
		end)
		
		procslarge = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
			return C.Type == "procnew" and C.Owner == People[i]
		end)
		
		facts = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
			return C.Type == "factnew" and C.Owner == People[i]
		end)
		
		if #facts > 0 then
			hut = Utils.Random(facts)
		end
		
		
		if ((2 + #bursar*3) < (#procssmall + #procslarge*2)) and hut and (not hut.IsDead) then
			--print("Line 323, Taxer: " .. tostring(hut.Location))
			peasent = Actor.Create("mwwand8",true,{Owner = who,Location = hut.Location+CVec.New(1,2)})
			peasent.Move(peasent.Location+CVec.New(0,1),3)
			
		end
		
	end
	
	

	for i = 1,#People do
	
		local who = People[i]
		local blacksmiths = {}
		local smiths = nil
		local hut = nil
	
		blacksmiths = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
			return (C.Type == "mwwand7" ) and C.Owner == People[i]
		end)
		--print(who.Name .. " Checked for peasantss: " .. tostring(#peasantss))
		
		smiths = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
			return (C.Type == "hqnewnod" or C.Type == "hqnewgdi") and C.Owner == People[i]
		end)
		
		
		if #blacksmiths < #smiths then
		
			if #smiths > 0 then
				hut = Utils.Random(smiths)
			end
			
			if hut and (not hut.IsDead) then 
				--print("Line 357, Smith: " .. tostring(hut.Location))
				peasent = Actor.Create("mwwand7",true,{Owner = who,Location = hut.Location+CVec.New(1,1)})
				peasent.Move(peasent.Location+CVec.New(0,1),3)
			end
		end
		
	end
	Trigger.AfterDelay(DateTime.Seconds(60),SpawnSmithWorker)
end

SpawnSettlers = function(Player)


	local who = Player
	local hut = nil
	local largehuts = {}
	local huts = {}
	local peasantss = {}
	local peasent = nil
	local PeasType = nil
	local castles = {}
	local nobles = {}
	local Facts = {}
	local Chicken = {}
	
	peasantss = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
		return (C.Type == "mwwand1" or C.Type == "mwwand2" or C.Type == "mwwand3" or C.Type == "mwwand4" or C.Type == "mwwand5" or C.Type == "mwwand6" or C.Type == "mwwand10" or C.Type == "mwwand11" or C.Type == "mwwand12") and C.Owner == who
	end)
	
	Chicken = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
		return (C.Type == "mwchick1") and C.Owner == who
	end)
	
	huts = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
		return (C.Type == "nukenew") and C.Owner == who
	end)
	
	largehuts = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
		return (C.Type == "nuk2new") and C.Owner == who
	end)
	
	Facts = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
		return C.Type == "factnew" and C.Owner == who
	end)
	
	if #peasantss < (#huts*3 + #largehuts*5) then
	
		if #largehuts ~= 0 and #huts ~= 0 then
		
			local rnd = Utils.RandomInteger(1,3)
			if rnd == 1 and #huts > 0 then
				hut = Utils.Random(huts)
			elseif rnd == 2 and #largehuts > 0 then
				hut = Utils.Random(largehuts)
			end
			
		elseif #largehuts > 0 then
			hut = Utils.Random(largehuts)
		elseif #huts > 0 then
			hut = Utils.Random(huts)
		elseif #Facts > 0 then
			hut = Utils.Random(Facts)
		end
		
		PeasType = Utils.Random(PeasentTypes)
		
		if hut and (not hut.IsDead) then
			--print("Line 424, Peasant: " .. tostring(hut.Location))
			peasent = Actor.Create(PeasType,true,{Owner = who,Location = hut.Location+CVec.New(1,1)})
			peasent.Move(peasent.Location+CVec.New(0,1),3)
			table.insert(peasantss,peasent)
			
			Trigger.AfterDelay(DateTime.Seconds(Utils.RandomInteger(30,150)),function()
				if peasent and (not peasent.IsDead) then
					Talkagain(peasent)
				end
			end)
		
		
			if (#peasantss + #nobles) > #Chicken*3 and hut and (not hut.IsDead) then
				Trigger.AfterDelay(DateTime.Seconds(Utils.RandomInteger(25,100)),function()
					if hut and (not hut.IsDead) then
						--print("Line 439, Chicken: " .. tostring(hut.Location))
						local chicko = Actor.Create("mwchick1",true,{Owner = who,Location = hut.Location+CVec.New(1,2)})
						chicko.Move(chicko.Location+CVec.New(0,1),3)
					end
				end)
			end
		end
		
	end
	
	nobles = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
		return (C.Type == "noble1" or C.Type == "noble2" or C.Type == "noble3" or C.Type == "noble4") and C.Owner == who
	end)
	
	castles = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
		return (C.Type == "castle" or C.Type == "castle2") and C.Owner == who
	end)
	
	
	
	landlord = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
		return C.Type == "noble5" and C.Owner == who
	end)
	
	if #landlord < (#castles) and #castles > 0 then
	
		hut = Utils.Random(castles)
		peasent = nil
		
		if hut and (not hut.IsDead) then
			--print("Line 469, Noble: " .. tostring(hut.Location))
			peasent = Actor.Create("noble5",true,{Owner = who,Location = hut.Location+CVec.New(1,2)})
			peasent.Move(peasent.Location+CVec.New(0,1),3)
		
			Trigger.AfterDelay(DateTime.Seconds(Utils.RandomInteger(15,90)),function()
				if (not peasent.IsDead) and peasent then
					Talkagain(peasent)
				end
			end)
		end
	elseif #nobles < (#castles+4) and #castles > 0 then
		
		peasent = nil
		
		
		hut = Utils.Random(castles)
		PeasType = Utils.Random(Noble)
		
		if hut and (not hut.IsDead) then
			--print("Line 488, Noble: " .. tostring(hut.Location))
			peasent = Actor.Create(PeasType,true,{Owner = who,Location = hut.Location+CVec.New(1,2)})
			peasent.Move(peasent.Location+CVec.New(0,1),3)
			table.insert(peasantss,peasent)
		
			Trigger.AfterDelay(DateTime.Seconds(Utils.RandomInteger(15,90)),function()
				if peasent and (not peasent.IsDead) then
					Talkagain(peasent)
				end
			end)
		end
	end
	
	if (#largehuts + #huts) == 0 then
		Trigger.AfterDelay(DateTime.Seconds(10),function()
			SpawnSettlers(who)
		end)
	else
		Trigger.AfterDelay(DateTime.Seconds(10+math.floor(60/((#castles*3 +#largehuts*2 + #huts +2)/2))),function()
			SpawnSettlers(who)
		end)	
	end
	
	local Stuff = {}
	local Spawn = nil
	local dep = nil
	local here = {}
	local Factor = nil
	
	here = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
		return (C.Type == "nukenew" or C.Type == "nuk4new" or C.Type == "nuk5new" or C.Type == "nuk2new" or C.Type == "nuk3new") and C.Owner == who
	end)
	
	Stuff = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(C)
		return (C.Type == "mwconst1" or C.Type == "mwconstback" or C.Type == "prop1" or C.Type == "prop2" or C.Type == "prop3" or C.Type == "prop4" or C.Type == "prop5" or C.Type == "prop6" or C.Type == "prop7" ) and C.Owner == who
	end)
	
	if #peasantss > ((#Stuff+1)*4) and #here > 0 and #Facts > 0  then
		
		Spawn = Utils.Random(here)
		Factor = Utils.Random(Facts)

		
		Trigger.AfterDelay(DateTime.Seconds(Utils.RandomInteger(3,8)),function()
			if Spawn and Factor and (not Factor.IsDead) and (not Spawn.IsDead) then
				--print("Line 533, Props: " .. tostring(hut.Location))
				dep = Actor.Create(Utils.Random(PropsList),true,{Owner = who,Location = Factor.Location+CVec.New(1,1)})
				
				dep.Move(dep.Location+CVec.New(0,1),3)
				dep.Move(Spawn.Location+CVec.New(Utils.RandomInteger(-4,4),Utils.RandomInteger(-4,4)),5)
				dep.Deploy()
			end
		end)
		
	end
end

Tick = function()

	CamelTimer = CamelTimer-1
	Timer = Timer -1
	if Timer < 1 then
		if LumberShaks and #LumberShaks > 0 then
			for i = 1, #LumberShaks do
				SpawnATree(LumberShaks[i])
			end
		end
		Timer = Utils.RandomInteger(625,1250)
	end
	if CamelTimer < 1 then
		if CamelShacks and #CamelShacks > 0 then
			for i = 1, #CamelShacks do
				SpawnACamel(CamelShacks[i])
			end
		end
		CamelTimer = Utils.RandomInteger(325,650)
	end

end