package.loaded.Constants = nil; require("Constants")

function EndlessSkirmish:StartActivity()
	collectgarbage("collect")
	
	for player = Activity.PLAYER_1, Activity.MAXPLAYERCOUNT - 1 do
		if self:PlayerActive(player) and self:PlayerHuman(player) then
			-- Check if we already have a brain assigned
			if not self:GetPlayerBrain(player) then
				local foundBrain = MovableMan:GetUnassignedBrain(self:GetTeamOfPlayer(player))
				-- If we can't find an unassigned brain in the scene to give each player, then force to go into editing mode to place one
				if not foundBrain then
					self.ActivityState = Activity.EDITING
					-- Open all doors so we can do pathfinding through them with the brain placement
					MovableMan:OpenAllDoors(true, Activity.NOTEAM)
					AudioMan:ClearMusicQueue()
					AudioMan:PlayMusic("Base.rte/Music/dBSoundworks/ccambient4.ogg", -1, -1)
					self:SetLandingZone(Vector(player*SceneMan.SceneWidth/4, 0), player)
				else
					-- Set the found brain to be the selected actor at start
					self:SetPlayerBrain(foundBrain, player)
					self:SwitchToActor(foundBrain, player, self:GetTeamOfPlayer(player))
					self:SetLandingZone(self:GetPlayerBrain(player).Pos, player)
					-- Set the observation target to the brain, so that if/when it dies, the view flies to it in observation mode
					self:SetObservationTarget(self:GetPlayerBrain(player).Pos, player)
				end
			end
		end
	end
	
	-- Set all actors defined in the ini-file to sentry mode
	for actor in MovableMan.AddedActors do
		if actor.ClassName == "AHuman" or actor.ClassName == "ACrab" then
			actor.AIMode = Actor.AIMODE_SENTRY
		end
	end
	
	if not self.CPUTeam or self.CPUTeam == Activity.NOTEAM then
		-- Add a CPU team if we only have a one team
		if self:OnlyOneTeamLeft() then
			for player = Activity.PLAYER_1, Activity.MAXPLAYERCOUNT - 1 do
				if self:PlayerActive(player) and self:PlayerHuman(player) then
					self.CPUTeam = self:GetTeamOfPlayer(player) + 1
					if self.CPUTeam > Activity.TEAM_4 then
						self.CPUTeam = Activity.TEAM_1
					end
				end
			end
		else
			self.CPUTeam = Activity.NOTEAM
		end
	end
	
	if self.Difficulty <= GameActivity.CAKEDIFFICULTY then
		self:SetTeamFunds(10000 * rte.StartingFundsScale, Activity.TEAM_1)
		self:SetTeamFunds(10000 * rte.StartingFundsScale, Activity.TEAM_2)
		self:SetTeamFunds(10000 * rte.StartingFundsScale, Activity.TEAM_3)
		self:SetTeamFunds(10000 * rte.StartingFundsScale, Activity.TEAM_4)
	elseif self.Difficulty <= GameActivity.EASYDIFFICULTY then
		self:SetTeamFunds(8000 * rte.StartingFundsScale, Activity.TEAM_1)
		self:SetTeamFunds(8000 * rte.StartingFundsScale, Activity.TEAM_2)
		self:SetTeamFunds(8000 * rte.StartingFundsScale, Activity.TEAM_3)
		self:SetTeamFunds(8000 * rte.StartingFundsScale, Activity.TEAM_4)
	elseif self.Difficulty <= GameActivity.MEDIUMDIFFICULTY then
		self:SetTeamFunds(6000 * rte.StartingFundsScale, Activity.TEAM_1)
		self:SetTeamFunds(6000 * rte.StartingFundsScale, Activity.TEAM_2)
		self:SetTeamFunds(6000 * rte.StartingFundsScale, Activity.TEAM_3)
		self:SetTeamFunds(6000 * rte.StartingFundsScale, Activity.TEAM_4)
	elseif self.Difficulty <= GameActivity.HARDDIFFICULTY then
		self:SetTeamFunds(4000 * rte.StartingFundsScale, Activity.TEAM_1)
		self:SetTeamFunds(4000 * rte.StartingFundsScale, Activity.TEAM_2)
		self:SetTeamFunds(4000 * rte.StartingFundsScale, Activity.TEAM_3)
		self:SetTeamFunds(4000 * rte.StartingFundsScale, Activity.TEAM_4)
	elseif self.Difficulty <= GameActivity.NUTSDIFFICULTY then
		self:SetTeamFunds(3000 * rte.StartingFundsScale, Activity.TEAM_1)
		self:SetTeamFunds(3000 * rte.StartingFundsScale, Activity.TEAM_2)
		self:SetTeamFunds(3000 * rte.StartingFundsScale, Activity.TEAM_3)
		self:SetTeamFunds(3000 * rte.StartingFundsScale, Activity.TEAM_4)
	elseif self.Difficulty <= GameActivity.MAXDIFFICULTY then
		self:SetTeamFunds(2000 * rte.StartingFundsScale, Activity.TEAM_1)
		self:SetTeamFunds(2000 * rte.StartingFundsScale, Activity.TEAM_2)
		self:SetTeamFunds(2000 * rte.StartingFundsScale, Activity.TEAM_3)
		self:SetTeamFunds(2000 * rte.StartingFundsScale, Activity.TEAM_4)
	end
	
	-- Initialize the AI
	if self.CPUTeam ~= Activity.NOTEAM then		
		self.AI = {}
		self.AI.bombChance = math.min(math.max(self.Difficulty/100, 0), 0.95)
		self.AI.SpawnTimer = Timer()
		self.AI.BombTimer = Timer()
		self.AI.HuntTimer = Timer()
		self.AI.timeToSpawn = 8000 - 50 * self.Difficulty			-- Time before the first AI spawn: from 8s to 3s
		self.AI.timeToBomb = 60000 - 400 * self.Difficulty			-- From 60s to 20s
		self.AI.baseSpawnTime = 16000 - 50 * self.Difficulty		-- From 16s to 10s
		self.AI.randomSpawnTime = 8000 - 40 * self.Difficulty		-- From 8s to 4s
		
		repeat
			self.AI.Tech = rte.TechList[math.random(#rte.TechList)]	-- Select a tech for the CPU player
		until self.AI.Tech ~= gPrevAITech
		gPrevAITech = self.AI.Tech	-- Store the AI tech in a global so we don't pick the same tech again next round
		
		-- Store data about terrain and enemy actors in the LZ map, use it to pick safe landing zones
		self.AI.LZmap = require("Activities/LandingZoneMap")	--self.AI.LZmap = dofile("Base.rte/Activities/LandingZoneMap.lua")	
		self.AI.LZmap:Initialize({self.CPUTeam})
		
		-- Store data about player teams: self.AI.OnPlayerTeam[Act.Team] is true if "Act" is an enemy to the AI
		self.AI.OnPlayerTeam = {}
		for player = Activity.PLAYER_1, Activity.MAXPLAYERCOUNT - 1 do
			if self:PlayerActive(player) and self:PlayerHuman(player) then
				self.AI.OnPlayerTeam[self:GetTeamOfPlayer(player)] = true
			end
		end
	end
	
	self.StartTimer = Timer()
end


function EndlessSkirmish:UpdateActivity()
	if self.ActivityState == Activity.OVER then
		return
	end
	
	if self.ActivityState == Activity.EDITING then
		-- Game is in editing or other modes, so open all does and reset the game running timer
		MovableMan:OpenAllDoors(true, Activity.NOTEAM)
		self.StartTimer:Reset()
	else	
		-- Close all doors after placing brains so our fortresses are secure
		if not self.StartTimer:IsPastSimMS(500) then
			MovableMan:OpenAllDoors(false, Activity.NOTEAM)
			
			-- Make sure all actors are in sentry mode
			for Act in MovableMan.Actors do
				if Act.ClassName == "AHuman" or Act.ClassName == "ACrab" then
					Act.AIMode = Actor.AIMODE_SENTRY
				end
			end
			
			if self.AI then
				self.AI.SpawnTimer:Reset()
				self.AI.BombTimer:Reset()
			end
		end
		
		-- Clear all objective markers, they get re-added each frame
		self:ClearObjectivePoints()
		-- Keep track of which teams we have set objective points for already, since multiple players can be on the same team
		local setTeam = { [Activity.TEAM_1] = false, [Activity.TEAM_2] = false, [Activity.TEAM_3] = false, [Activity.TEAM_4] = false }
		local teamtally = 0
		local playertally = 0
		for player = Activity.PLAYER_1, Activity.MAXPLAYERCOUNT - 1 do
			if self:PlayerActive(player) and self:PlayerHuman(player) then
				if not self.StartTimer:IsPastRealMS(3000) then
					FrameMan:SetScreenText("Fight to the end!", player, 333, 5000, true)
				end
				-- The current player's team
				local team = self:GetTeamOfPlayer(player)
				-- Check if any player's brain is dead
				if not MovableMan:IsActor(self:GetPlayerBrain(player)) then
					self:SetPlayerBrain(nil, player)
					self:ResetMessageTimer(player)
					FrameMan:ClearScreenText(player)
					FrameMan:SetScreenText("Your brain has been destroyed!", player, 333, -1, false)
				else
					playertally = playertally + 1
					if not setTeam[team] then
						-- Add objective points
						self:AddObjectivePoint("Protect!", self:GetPlayerBrain(player).AboveHUDPos, team, GameActivity.ARROWDOWN)
						for otherPlayer = Activity.PLAYER_1, Activity.MAXPLAYERCOUNT - 1 do
							if otherPlayer ~= player and self:PlayerActive(otherPlayer) and self:PlayerHuman(otherPlayer) and MovableMan:IsActor(self:GetPlayerBrain(otherPlayer)) then
								local otherTeam = self:GetTeamOfPlayer(otherPlayer)
								if otherTeam ~= team then
									self:AddObjectivePoint("Destroy!", self:GetPlayerBrain(otherPlayer).AboveHUDPos, team, GameActivity.ARROWDOWN)
								else
									self:AddObjectivePoint("Protect!", self:GetPlayerBrain(otherPlayer).AboveHUDPos, team, GameActivity.ARROWDOWN)
								end
							end
						end
						
						setTeam[team] = true
						teamtally = teamtally + 1
					end
				end
			end
		end
		
		-- Win/Lose Conditions player vs player
		if self.CPUTeam == Activity.NOTEAM then
			if teamtally < 2 then
				for team = Activity.TEAM_1, Activity.TEAM_4 do
					if setTeam[team] then
						self.WinnerTeam = team
						break
					end
				end
				
				ActivityMan:EndActivity()
				return
			end
		else
			-- Win/Lose Conditions player vs AI
			if playertally < 1 then
				self.WinnerTeam = self.CPUTeam
				ActivityMan:EndActivity()
				return
			end
			
			self.AI.LZmap:Update()	-- Update info about landing zones and player actors
			
			-- Check if any AI actors have reached their destination
			if self.AI.HuntTimer:IsPastSimMS(8000) then
				self.AI.HuntTimer:Reset()
				
				for Act in MovableMan.Actors do 
					if Act.Team == self.CPUTeam and Act.AIMode ~= Actor.AIMODE_GOLDDIG and (Act.ClassName == "AHuman" or Act.ClassName == "ACrab") then
						if (Act.AIMode == Actor.AIMODE_GOTO and SceneMan:ShortestDistance(Act:GetLastAIWaypoint(), Act.Pos, false).Largest < 100) or 
							Act.AIMode == Actor.AIMODE_SENTRY or Act.Age > 80000
						then
							-- Destination reached: hunt for the brain
							Act.AIMode = Actor.AIMODE_BRAINHUNT
						end
					end
				end
			end
			
			-- The AI have money to buy units
			if true then
				if self.AI.SpawnTimer:IsPastSimMS(self.AI.timeToSpawn) then
					if self.AI.AttackPos then	-- Search for a LZ from where to attack the target
						local closeLZx, closeLZobst, easyPathLZx, easyPathLZobst = self.AI.LZmap:FindLZ(self.CPUTeam, self.AI.AttackPos)
						if closeLZx then	-- Search done
							self.AI.SpawnTimer:Reset()
							
							local xPosLZ, obstacleHeight
							if closeLZx == easyPathLZx then
								xPosLZ = closeLZx
								obstacleHeight = closeLZobst
							elseif closeLZobst < 25 and easyPathLZobst < 25 then
								if math.random() < 0.5 then
									xPosLZ = closeLZx
									obstacleHeight = closeLZobst
								else
									xPosLZ = easyPathLZx
									obstacleHeight = easyPathLZobst
								end
							elseif closeLZobst > 100 then
								xPosLZ = easyPathLZx
								obstacleHeight = easyPathLZobst
							else
								if math.random() < 0.4 then
									xPosLZ = closeLZx
									obstacleHeight = closeLZobst
								else
									xPosLZ = easyPathLZx
									obstacleHeight = easyPathLZobst
								end
							end
							
							if obstacleHeight > 200 and math.random() < 0.4 then
								-- This target is very difficult to reach: cancel this attack and search for another target again soon
								self.AI.timeToSpawn = 500
								self.AI.AttackTarget = nil
								self.AI.AttackPos = nil
							else
								self.AI.timeToSpawn = (self.AI.baseSpawnTime + math.random(self.AI.randomSpawnTime)) * rte.SpawnIntervalScale
								
								if obstacleHeight < 30 then
									self:CreateHeavyDrop(xPosLZ, self.AI.AttackPos)
								elseif obstacleHeight < 100 then
									self:CreateMediumDrop(xPosLZ, self.AI.AttackPos)
								elseif obstacleHeight < 250 then
									self:CreateLightDrop(xPosLZ, self.AI.AttackPos)
								else
									self:CreateScoutDrop(xPosLZ, self.AI.AttackPos)
									
									-- This target is very difficult to reach: change target for the next attack
									self.AI.AttackTarget = nil
									self.AI.AttackPos = nil
								end
								
								if not MovableMan:IsActor(self.AI.AttackTarget) or math.random() < 0.4 then
									-- Change target for the next attack
									self.AI.AttackTarget = nil
									self.AI.AttackPos = nil
								else
									self.AI.AttackPos = Vector(self.AI.AttackTarget.Pos.X, self.AI.AttackTarget.Pos.Y)
								end
							end
						end
					else	-- Select a player actor as a target for the next attack
						local safePosX = self.AI.LZmap:FindSafeLZ(self.CPUTeam) or math.random(SceneMan.SceneWidth-1)
						if safePosX then
							local TargetActors = {}
							for Act in MovableMan.Actors do
								if self.AI.OnPlayerTeam[Act.Team] and (Act.ClassName == "AHuman" or Act.ClassName == "ACrab" or Act.ClassName == "Actor") then
									local distance = 20 * (SceneMan:ShortestDistance(Vector(safePosX, Act.Pos.Y), Act.Pos, false).Largest / SceneMan.SceneWidth)
									table.insert(TargetActors, {Act=Act, score=self.AI.LZmap:SurfaceProximity(Act.Pos)+distance})
								end
							end
							
							self.AI.AttackTarget = self:SelectTarget(TargetActors)
							if self.AI.AttackTarget then
								self.AI.AttackPos = Vector(self.AI.AttackTarget.Pos.X, self.AI.AttackTarget.Pos.Y)
							else
								-- No target found
								self.AI.SpawnTimer:Reset()
								self.AI.timeToSpawn = 5000
							end
						else
							-- No safe LZ found yet
							self.AI.SpawnTimer:Reset()
							self.AI.timeToSpawn = 5000
						end
					end
				elseif self.AI.BombTimer:IsPastSimMS(self.AI.timeToBomb) then
					self.AI.BombTimer:Reset()
					self.AI.timeToBomb = (20000 - self.Difficulty * 75) * rte.SpawnIntervalScale
					
					if math.random() < self.AI.bombChance then
						local bombPosX = self.AI.LZmap:FindBombTarget(self.CPUTeam)
						if bombPosX then
							self.AI.bombChance = math.max(self.AI.bombChance*0.85, 0.05)
							self:CreateBombDrop(bombPosX)
							self.AI.timeToBomb = (RangeRand(150, 250) * 100 - self.Difficulty * 120) * rte.SpawnIntervalScale	-- 20s to 8s
						end
					end
				end
			else	-- The AI is out of gold
				local enemyPresent = false
				local objectives = 0
				for Act in MovableMan.Actors do 
					if Act.Team == self.CPUTeam and not Act:IsDead() then
						if Act.ClassName ~= "ADoor" then
							enemyPresent = true
							
							-- Add objective points
							if Act.ClassName == "AHuman" or Act.ClassName == "ACrab" then
								objectives = objectives + 1
								if objectives > 3 then
									break
								end
								
								for team = Activity.TEAM_1, Activity.TEAM_4 do
									self:AddObjectivePoint("Destroy!", Act.AboveHUDPos, team, GameActivity.ARROWDOWN)
								end
							end
						end
					end
				end
				
				-- No AI actors left, remove the CPU-Team
				if not enemyPresent then
					self.CPUTeam = Activity.NOTEAM
				end
			end			
		end
	end
end

-- Pick an actor semi-randomly, with a larger probablility for actors with a lower score
function EndlessSkirmish:SelectTarget(TargetActors)
	if #TargetActors > 1 then
		table.sort(TargetActors, function(A, B) return A.score < B.score end)	-- Actors closer to the surface first
		
		local temperature = 5	-- a higher temperature means less random selection
		local sum = 0
		local worstScore = TargetActors[#TargetActors].score
		
		-- normalize the score
		for i, Data in pairs(TargetActors) do
			TargetActors[i].chance = 1 - Data.score / worstScore
			sum = sum + math.exp(temperature*TargetActors[i].chance)
		end
		
		-- use Softmax to pick one of the n best LZs
		if sum > 0 then
			local pick = math.random() * sum
			sum = 0
			for _, Data in pairs(TargetActors) do
				sum = sum + math.exp(temperature*Data.chance)
				if sum >= pick then
					return Data.Act
				end
			end
		end
		
		return TargetActors[1].Act
	elseif #TargetActors == 1 then
		return TargetActors[1].Act
	end
end

function EndlessSkirmish:CreateHeavyDrop(xPosLZ, Destination)
	local Craft = RandomACDropShip("Craft", self.AI.Tech)	-- Pick a craft to deliver with
	if Craft then
		-- The max allowed weight of this craft plus cargo
		local craftMaxMass = Craft.MaxMass
		if craftMaxMass < 0 then
			craftMaxMass = math.huge
		elseif craftMaxMass < 1 then
			craftMaxMass = Craft.Mass + 400	-- MaxMass not defined
		end
		
		Craft.Team = self.CPUTeam
		Craft.Pos = Vector(xPosLZ, -30)	-- Set the spawn point of the craft
		
		for _ = 1, math.random(2, rte.PassengerMax) do
      local Passenger
			if math.random() < rte.CrabToHumanSpawnRatio + self.Difficulty / 800 then
				Passenger = self:CreateCrab()
			elseif RangeRand(0, 105) < self.Difficulty then
				Passenger = self:CreateHeavyInfantry()
			else
				Passenger = self:CreateRandomInfantry()
			end
			
			if Passenger then
				if Destination then
					Passenger.AIMode = Actor.AIMODE_GOTO
					Passenger:AddAISceneWaypoint(Destination)
				end
				
				Craft:AddInventoryItem(Passenger)
				
				-- Stop adding actors when exceeding the weight limit
				if Craft.Mass > craftMaxMass then 
					break
				end
			end
		end
		
		-- Spawn the Craft onto the scene
		MovableMan:AddActor(Craft)
	end
end

function EndlessSkirmish:CreateMediumDrop(xPosLZ, Destination)
	-- Pick a craft to deliver with
	local Craft, actorsInCargo
	if math.random() < 0.6 then
		Craft = RandomACDropShip("Craft", self.AI.Tech)
		actorsInCargo = math.random(2, rte.PassengerMax)
	else
		Craft = RandomACRocket("Craft", self.AI.Tech)
		actorsInCargo = 2
	end
	
	if Craft then
		-- The max allowed weight of this craft plus cargo
		local craftMaxMass = Craft.MaxMass
		if craftMaxMass < 0 then
			craftMaxMass = math.huge
		elseif craftMaxMass < 1 then
			craftMaxMass = Craft.Mass + 400	-- MaxMass not defined
		end
		
		Craft.Team = self.CPUTeam
		Craft.Pos = Vector(xPosLZ, -30)	-- Set the spawn point of the craft
		
		for _ = 1, actorsInCargo do
      local Passenger
			if RangeRand(-5, 125) < self.Difficulty then
				Passenger = self:CreateMediumInfantry()
			elseif math.random() < 0.65 then
				Passenger = self:CreateRandomInfantry()
			else
				Passenger = self:CreateLightInfantry()
			end
			
			if Passenger then
				if Destination then
					Passenger.AIMode = Actor.AIMODE_GOTO
					Passenger:AddAISceneWaypoint(Destination)
				end
				
				Craft:AddInventoryItem(Passenger)
				
				-- Stop adding actors when exceeding the weight limit
				if Craft.Mass > craftMaxMass then 
					break
				end
			end
		end
		
		-- Spawn the Craft onto the scene
		MovableMan:AddActor(Craft)
	end
end

function EndlessSkirmish:CreateLightDrop(xPosLZ, Destination)
	-- Pick a craft to deliver with
	local Craft
	if math.random() < 0.6 then
		Craft = RandomACDropShip("Craft", self.AI.Tech)
	else
		Craft = RandomACRocket("Craft", self.AI.Tech)
	end
	
	if Craft then
		-- The max allowed weight of this craft plus cargo
		local craftMaxMass = Craft.MaxMass
		if craftMaxMass < 0 then
			craftMaxMass = math.huge
		elseif craftMaxMass < 1 then
			craftMaxMass = Craft.Mass + 400	-- MaxMass not defined
		end
		
		Craft.Team = self.CPUTeam
		Craft.Pos = Vector(xPosLZ, -30)	-- Set the spawn point of the craft
		
		for _ = 1, rte.PassengerMax do
      local Passenger
			if RangeRand(10, 200) < self.Difficulty then
				Passenger = self:CreateMediumInfantry()
			else
				Passenger = self:CreateLightInfantry()
			end
			
			if Passenger then
				if Destination then
					Passenger.AIMode = Actor.AIMODE_GOTO
					Passenger:AddAISceneWaypoint(Destination)
				end
				
				Craft:AddInventoryItem(Passenger)
				
				-- Stop adding actors when exceeding the weight limit
				if Craft.Mass > craftMaxMass then 
					break
				end
			end
		end
		
		-- Spawn the Craft onto the scene
		MovableMan:AddActor(Craft)
	end
end

function EndlessSkirmish:CreateScoutDrop(xPosLZ, Destination)
	-- Pick a craft to deliver with
	local Craft
	if math.random() < 0.6 then
		Craft = RandomACDropShip("Craft", self.AI.Tech)
	else
		Craft = RandomACRocket("Craft", self.AI.Tech)
	end
	
	if Craft then
		-- The max allowed weight of this craft plus cargo
		local craftMaxMass = Craft.MaxMass
		if craftMaxMass < 0 then
			craftMaxMass = math.huge
		elseif craftMaxMass < 1 then
			craftMaxMass = Craft.Mass + 400	-- MaxMass not defined
		end
		
		Craft.Team = self.CPUTeam
		Craft.Pos = Vector(xPosLZ, -30)	-- Set the spawn point of the craft
		
		for _ = 1, rte.PassengerMax do
      local Passenger
			if math.random() < 0.3 then
				Passenger = self:CreateLightInfantry()
			else
				Passenger = self:CreateScoutInfantry()
			end
			
			if Passenger then
				if Destination then
					Passenger.AIMode = Actor.AIMODE_GOTO
					Passenger:AddAISceneWaypoint(Destination)
				end
				
				Craft:AddInventoryItem(Passenger)
				
				-- Stop adding actors when exceeding the weight limit
				if Craft.Mass > craftMaxMass then 
					break
				end
			end
		end
		
		-- Spawn the Craft onto the scene
		MovableMan:AddActor(Craft)
	end
end

function EndlessSkirmish:CreateBombDrop(bombPosX)
	local Craft = RandomACDropShip("Craft", self.AI.Tech)	-- Pick a craft to deliver with
	if Craft then
		-- The max allowed weight of this craft plus cargo
		local craftMaxMass = Craft.MaxMass
		if craftMaxMass < 0 then
			craftMaxMass = math.huge
		elseif craftMaxMass < 1 then
			craftMaxMass = Craft.Mass + 400	-- MaxMass not defined
		end
		
		Craft.AIMode = Actor.AIMODE_GOTO	-- DropShips open doors at a high altitude in GoTo mode
		Craft.Team = self.CPUTeam
		Craft.Pos = Vector(bombPosX, -30)	-- Set the spawn point of the craft
		
		for _ = 3, 5 do
			Craft:AddInventoryItem(RandomTDExplosive("Payloads", self.AI.Tech))
			
			-- Stop adding bombs when exceeding the weight limit
			if Craft.Mass > craftMaxMass then 
				break
			end
		end
		
		-- Spawn the Craft onto the scene
		MovableMan:AddActor(Craft)
	end
end



function EndlessSkirmish:CreateCrab()
	local Passenger = RandomACrab("Mecha", self.AI.Tech)
	if Passenger then
		-- Set AI mode and team so it knows who and what to fight for!
		Passenger.AIMode = Actor.AIMODE_BRAINHUNT
		Passenger.Team = self.CPUTeam
		return Passenger
	end
end

-- Get any Actor from the CPU's native tech
function EndlessSkirmish:CreateRandomInfantry()
	local	Passenger = RandomAHuman("Actors", self.AI.Tech)
	if Passenger then
		Passenger:AddInventoryItem(RandomHDFirearm("Primary Weapons", self.AI.Tech))
		Passenger:AddInventoryItem(RandomHDFirearm("Secondary Weapons", self.AI.Tech))
		
		if math.random() < 0.4 then
			Passenger:AddInventoryItem(RandomTDExplosive("Grenades", self.AI.Tech))
			if math.random() < 0.5 then
				Passenger:AddInventoryItem(RandomTDExplosive("Grenades", self.AI.Tech))
			end
		elseif math.random() < 0.5 then
			Passenger:AddInventoryItem(RandomHDFirearm("Diggers", self.AI.Tech))
		end
		
		-- Set AI mode and team so it knows who and what to fight for!
		Passenger.AIMode = Actor.AIMODE_BRAINHUNT
		Passenger.Team = self.CPUTeam
		return Passenger
	end
end

function EndlessSkirmish:CreateLightInfantry()
	local	Passenger = RandomAHuman("Light Infantry", self.AI.Tech)
	if Passenger then
		Passenger:AddInventoryItem(RandomHDFirearm("Light Weapons", self.AI.Tech))
		Passenger:AddInventoryItem(RandomHDFirearm("Secondary Weapons", self.AI.Tech))
		
		if math.random() < 0.2 then
			Passenger:AddInventoryItem(RandomTDExplosive("Grenades", self.AI.Tech))
		end
		
		-- Set AI mode and team so it knows who and what to fight for!
		Passenger.AIMode = Actor.AIMODE_BRAINHUNT
		Passenger.Team = self.CPUTeam
		return Passenger
	end
end

function EndlessSkirmish:CreateHeavyInfantry()
	local	Passenger = RandomAHuman("Heavy Infantry", self.AI.Tech)
	if Passenger then
		Passenger:AddInventoryItem(RandomHDFirearm("Heavy Weapons", self.AI.Tech))
		Passenger:AddInventoryItem(RandomHDFirearm("Secondary Weapons", self.AI.Tech))
		
		if math.random() < 0.6 then
			Passenger:AddInventoryItem(RandomTDExplosive("Grenades", self.AI.Tech))
			Passenger:AddInventoryItem(RandomTDExplosive("Grenades", self.AI.Tech))
			if math.random() < 0.4 then
				Passenger:AddInventoryItem(RandomTDExplosive("Grenades", self.AI.Tech))
			end
		else
			Passenger:AddInventoryItem(RandomHDFirearm("Diggers", self.AI.Tech))
		end
		
		-- Set AI mode and team so it knows who and what to fight for!
		Passenger.AIMode = Actor.AIMODE_BRAINHUNT
		Passenger.Team = self.CPUTeam
		return Passenger
	end
end

function EndlessSkirmish:CreateMediumInfantry()
	local	Passenger = RandomAHuman("Heavy Infantry", self.AI.Tech)
	if Passenger then
		Passenger:AddInventoryItem(RandomHDFirearm("Light Weapons", self.AI.Tech))
		Passenger:AddInventoryItem(RandomHDFirearm("Secondary Weapons", self.AI.Tech))
		
		-- Set AI mode and team so it knows who and what to fight for!
		Passenger.AIMode = Actor.AIMODE_BRAINHUNT
		Passenger.Team = self.CPUTeam
		return Passenger
	end
end

function EndlessSkirmish:CreateEngineer()
	local Passenger = RandomAHuman("Light Infantry", self.AI.Tech)
	if Passenger then
		Passenger:AddInventoryItem(RandomHDFirearm("Light Weapons", self.AI.Tech))
		Passenger:AddInventoryItem(CreateHDFirearm("Medium Digger", "Base.rte"))
		
		-- Set AI mode and team so it knows who and what to fight for!
		Passenger.AIMode = Actor.AIMODE_GOLDDIG
		Passenger.Team = self.CPUTeam
		return Passenger
	end
end

function EndlessSkirmish:CreateScoutInfantry()
	local	Passenger = RandomAHuman("Light Infantry", self.AI.Tech)
	if Passenger then
		Passenger:AddInventoryItem(RandomHDFirearm("Secondary Weapons", self.AI.Tech))
		
		if math.random() < 0.6 then
			Passenger:AddInventoryItem(RandomTDExplosive("Grenades", self.AI.Tech))
		else
			Passenger:AddInventoryItem(RandomHDFirearm("Secondary Weapons", self.AI.Tech))
		end
		
		-- Set AI mode and team so it knows who and what to fight for!
		Passenger.AIMode = Actor.AIMODE_BRAINHUNT
		Passenger.Team = self.CPUTeam
		return Passenger
	end
end
