--[[

*** INSTRUCTIONS ***

This activity can be run on any scene with a "Bunker Breach LZ" and "Brain" area.
The player brains spawn in the "Bunker Breach LZ" area and the AI brain bot in the "Brain" area.
The script will look for player units and send reinforcements to attack them.

Add defender units by placing areas named:
"Sniper1" to "Sniper10"
"Light1" to "Light10"	<-- light actors, light weapons
"Heavy1" to "Heavy10"	<-- heavy actors, heavy weapons
"Crab1" to "Crab10"
"Turret1" to "Turret10"
"Engineer1" to "Engineer10"	<-- light actors, digger, gold dig AI-mode

Don't place more defenders than the MOID limit can handle (15 defenders plus 3 doors equals about 130 of 255 avaliable IDs).
--]]

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

function BunkerBreach:StartActivity()
	collectgarbage("collect")

	-- Select a tech for the CPU player
	self.CPUTechName = rte.TechList[math.random(#rte.TechList)]
	self:SetTeamFunds(math.ceil((3000+self.Difficulty*50)*rte.StartingFundsScale), self.CPUTeam)
	self:SetTeamFunds(math.ceil((6000-self.Difficulty*55)*rte.StartingFundsScale), Activity.TEAM_1)
	
	-- This line will filter out all scenes witout any "Bunker Breach LZ" area
	local PlayerLZ = SceneMan.Scene:GetArea("Bunker Breach LZ")

	-- Timers
	self.WinTimer = Timer()
	self.SpawnTimer = Timer()
	self.spawnDelay = (80000 - self.Difficulty * 250) * rte.SpawnIntervalScale
	self.HunterTimer = Timer()
	self.HunterDelay = 50000
	
	-- Store AI-actors that attack the player here
	self.HunterActors = {}

	-- Add player brains
	for player = Activity.PLAYER_1, Activity.MAXPLAYERCOUNT - 1 do
		if self:PlayerActive(player) and self:PlayerHuman(player) then
			local Brain = CreateAHuman("Brain Robot", "Base.rte")
			if Brain then
				local Weapon = CreateHDFirearm("SMG", "Base.rte")
				if Weapon then
					Brain:AddInventoryItem(Weapon)
				end

				local Digger = CreateHDFirearm("Medium Digger", "Base.rte")
				if Digger then
					Brain:AddInventoryItem(Digger)
				end

				Brain.AIMode = Actor.AIMODE_SENTRY
				Brain.Team = self:GetTeamOfPlayer(player)

				local lzX = PlayerLZ:GetRandomPoint().X

				-- make sure we are inside the scene
				if SceneMan.SceneWrapsX then
					if lzX < 0 then
						lzX = lzX + SceneMan.SceneWidth
					elseif lzX >= SceneMan.SceneWidth then
						lzX = lzX - SceneMan.SceneWidth
					end
				else
					lzX = math.max(math.min(lzX, SceneMan.SceneWidth-50), 50)
				end
				
				Brain.Pos = SceneMan:MovePointToGround(Vector(lzX, 0), Brain.Height*0.3, 3)
				self:SetPlayerBrain(Brain, player)
				self:SetObservationTarget(Brain.Pos, player)
				MovableMan:AddActor(Brain)
			end
		end
	end

	if SceneMan.Scene:HasArea("Brain") then
		self.CPUBrain = self:CreateBrainBot()
		if self.CPUBrain then
			self.CPUBrain.Pos = SceneMan.Scene:GetArea("Brain"):GetCenterPoint()
			MovableMan:AddActor(self.CPUBrain)
		end
	end

	local GuardArea = "Sniper"
	for i = 1, 10 do
		if SceneMan.Scene:HasArea(GuardArea..i) then
			local Guard = self:CreateSniper(Actor.AIMODE_SENTRY)
			if Guard then
				Guard.Pos = SceneMan.Scene:GetArea(GuardArea..i):GetCenterPoint()
				MovableMan:AddActor(Guard)
			end
		else
			break
		end
	end

	GuardArea = "Light"
	for i = 1, 10 do
		if SceneMan.Scene:HasArea(GuardArea..i) then
			local Guard = self:CreateLightInfantry(Actor.AIMODE_SENTRY)
			if Guard then
				Guard.Pos = SceneMan.Scene:GetArea(GuardArea..i):GetCenterPoint()
				MovableMan:AddActor(Guard)
			end
		else
			break
		end
	end

	GuardArea = "Heavy"
	for i = 1, 10 do
		if SceneMan.Scene:HasArea(GuardArea..i) then
			local Guard = self:CreateHeavyInfantry(Actor.AIMODE_SENTRY)
			if Guard then
				Guard.Pos = SceneMan.Scene:GetArea(GuardArea..i):GetCenterPoint()
				MovableMan:AddActor(Guard)
			end
		else
			break
		end
	end

	GuardArea = "Crab"
	for i = 1, 10 do
		if SceneMan.Scene:HasArea(GuardArea..i) then
			local Guard = self:CreateCrab(Actor.AIMODE_SENTRY)
			if Guard then
				Guard.Pos = SceneMan.Scene:GetArea(GuardArea..i):GetCenterPoint()
				MovableMan:AddActor(Guard)
			end
		else
			break
		end
	end

	GuardArea = "Turret"
	for i = 1, 10 do
		if SceneMan.Scene:HasArea(GuardArea..i) then
			local Guard = self:CreateTurret()
			if Guard then
				Guard.Pos = SceneMan.Scene:GetArea(GuardArea..i):GetCenterPoint()
				MovableMan:AddActor(Guard)
			end
		else
			break
		end
	end

	GuardArea = "Engineer"
	for i = 1, 10 do
		if SceneMan.Scene:HasArea(GuardArea..i) then
			local Guard = self:CreateEngineer()
			if Guard then
				Guard.Pos = SceneMan.Scene:GetArea(GuardArea..i):GetCenterPoint()
				MovableMan:AddActor(Guard)
			end
		else
			break
		end
	end

	-- Add fog
	if true then
		SceneMan:MakeAllUnseen(Vector(65, 65), self.CPUTeam)
		SceneMan:MakeAllUnseen(Vector(25, 25), Activity.TEAM_1)

		-- Lift the fog around friendly actors
		for Act in MovableMan.AddedActors do
			for ang = 0, math.pi*2, 0.1 do
				SceneMan:CastSeeRay(Act.Team, Act.EyePos, Vector(130+FrameMan.PlayerScreenWidth*0.5, 0):RadRotate(ang), Vector(), 1, 4)
			end
		end
		
		-- Assume that the AI has scouted the terrain
		for x = 0, SceneMan.SceneWidth-1, 65 do
			SceneMan:CastSeeRay(self.CPUTeam, Vector(x,0), Vector(0, SceneMan.SceneHeight), Vector(), 1, 9)
		end
	end
	
	-- Store data about terrain and enemy actors in the LZ map, use it to pick safe landing zones
	self.LZMap = require("Activities/LandingZoneMap")
	--self.LZMap = dofile("Base.rte/Activities/LandingZoneMap.lua")
	self.LZMap:Initialize({self.CPUTeam})	-- a list of AI teams
end

function BunkerBreach:UpdateActivity()
	if self.ActivityState == Activity.OVER then
		return
	end
	
	if self.WinTimer:IsPastRealMS(3000) then
		-- Check win conditions
		self.WinTimer:Reset()

		if not MovableMan:IsActor(self.CPUBrain) then
			self.WinnerTeam = Activity.TEAM_1
			MovableMan:KillAllActors(self.WinnerTeam)
			ActivityMan:EndActivity()
			return
		else
			local players = 0
			for player = Activity.PLAYER_1, Activity.MAXPLAYERCOUNT - 1 do
				if self:PlayerActive(player) and self:PlayerHuman(player) then
					local Brain = self:GetPlayerBrain(player)
					if not Brain then
						Brain = MovableMan:GetUnassignedBrain(Activity.TEAM_1)
						if Brain then
							self:SetPlayerBrain(Brain, player)
						end
					end
					
					if Brain and MovableMan:IsActor(Brain) then
						players = players + 1
						self:SetObservationTarget(Brain.Pos, player)
					else
						self:ResetMessageTimer(player)
						FrameMan:ClearScreenText(player)
						FrameMan:SetScreenText("Your brain has been destroyed!", player, 2000, -1, false)
					end
				end
			end
			
			if players < 1 then
				self.WinnerTeam = self.CPUTeam
				MovableMan:KillAllActors(self.WinnerTeam)
				ActivityMan:EndActivity()
				return
			end
		end
	elseif self.HunterTimer:IsPastSimMS(self.HunterDelay) then
		self.HunterTimer:Reset()
		self.HunterDelay = 5000
		
		if #self.HunterActors > 0 then
			local PruneList = {}
			for index, Hunter in pairs(self.HunterActors) do
				if not MovableMan:IsActor(Hunter) then
					table.insert(PruneList, index)
				else
					if Hunter.AIMode == Actor.AIMODE_GOTO then
						local Enemy = Hunter.MOMoveTarget
						if not MovableMan:IsActor(Enemy) then
							-- stop looking if the target is dead or two minutes has passed since the hunter was created
							if self.AttackActor and MovableMan:IsActor(self.AttackActor) then
								Hunter:ClearAIWaypoints()
								Hunter:AddAIMOWaypoint(self.AttackActor)
							else
								Hunter.AIMode = Actor.AIMODE_BRAINHUNT
								table.insert(PruneList, index)
							end
						elseif Hunter.Age > 120000 then
							Hunter.AIMode = Actor.AIMODE_BRAINHUNT
							table.insert(PruneList, index)							
						end
					end
				end
			end
			
			for _, index in pairs(PruneList) do
				self.HunterActors[index] = nil
			end
		end
	end
	
	self.LZMap:Update()
	
	if self:GetTeamFunds(self.CPUTeam) > 0 then
		if self.SpawnTimer:IsPastSimMS(self.spawnDelay) then
			if self.AttackActor and MovableMan:IsActor(self.AttackActor) then
				-- We have a target actor, search for a suitable LZ
				local easyPathLZx, easyPathLZobst, closeLZx, closeLZobst = self.LZMap:FindLZ(self.CPUTeam, self.AttackPos)
				if closeLZx then	-- Search done
					self.SpawnTimer:Reset()
					
					local xPosLZ, obstacleHeight
					if closeLZobst < 30 and easyPathLZobst < 30 then
						if math.random() < 0.5 then
							xPosLZ = closeLZx
							obstacleHeight = closeLZobst
						else
							xPosLZ = easyPathLZx
							obstacleHeight = easyPathLZobst
						end
					elseif closeLZobst > 100 and easyPathLZobst < 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.6 then
						-- This target is very difficult to reach: cancel this attack and search for another target
						self.AttackActor = nil
						self.AttackPos = nil
					else
						-- Attack target
						self.SpawnTimer:Reset()
						if MovableMan:IsActor(self.CPUBrain) and SceneMan:ShortestDistance(self.AttackActor.Pos, self.CPUBrain.Pos, false).Magnitude < 1000 then
							-- The player is close to the AI brain so spawn again soon
							self.spawnDelay = (30000 - self.Difficulty * 150) * rte.SpawnIntervalScale
						else
							self.spawnDelay = (70000 - self.Difficulty * 250) * rte.SpawnIntervalScale
						end
						
						if obstacleHeight < 30 then
							self:CreateHeavyDrop(xPosLZ)
						elseif obstacleHeight < 90 then
							self:CreateMediumDrop(xPosLZ)
						elseif obstacleHeight < 180 then
							self:CreateLightDrop(xPosLZ)
						else
							self:CreateScoutDrop(xPosLZ)
							
							-- This target is very difficult to reach: change target for the next attack
							self.AttackActor = nil
							self.AttackPos = nil
						end
						
						if self.AttackActor then
							if math.random() < 0.4 then
								-- Change target for the next attack
								self.AttackActor = nil
								self.AttackPos = nil
							else
								self.AttackPos = Vector(self.AttackActor.Pos.X, self.AttackActor.Pos.Y)
							end
						end
					end
				end
			else
				self.AttackActor = nil
				
				if MovableMan:GetMOIDCount() < rte.MOIDCountMax and MovableMan:IsActor(self.CPUBrain) then
					-- Check if the player is witin a cerain distance of the CPU brain
					local Intruders = {}
					local intruder_tally = 0
					for Intruder in MovableMan.Actors do
						if Intruder.Team ~= self.CPUTeam and Intruder.Health > 0 and
							not SceneMan:IsUnseen(Intruder.Pos.X, Intruder.Pos.Y, self.CPUTeam) and
							(Intruder.ClassName == "AHuman" or Intruder.ClassName == "ACrab" or Intruder.ClassName == "Actor")
						then
							local range = SceneMan:ShortestDistance(Intruder.Pos, self.CPUBrain.Pos, false).Largest + math.random(200)
							table.insert(Intruders, {Act=Intruder, score=range})
							intruder_tally = intruder_tally + 1
						end
					end
					
					if intruder_tally < 1 then
						self.SpawnTimer:Reset()
						self.spawnDelay = 10000
					else
						table.sort(Intruders, function(A, B) return A.score < B.score end)	-- the nearest intruder first
						self.AttackActor = Intruders[1].Act
						self.AttackPos = Vector(self.AttackActor.Pos.X, self.AttackActor.Pos.Y)
					end
				else
					self.SpawnTimer:Reset()
					self.spawnDelay = 10000
				end
			end
		end
	end
end


function BunkerBreach:CreateHeavyDrop(xPosLZ)
	local Craft = RandomACDropShip("Craft", self.CPUTechName)	-- 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 i = 1, math.random(2, rte.PassengerMax) do
			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
				Passenger:AddAIMOWaypoint(self.AttackActor)
				table.insert(self.HunterActors, Passenger)
				Craft:AddInventoryItem(Passenger)
				
				-- Stop adding actors when exceeding the weight limit
				if Craft.Mass > craftMaxMass then 
					break
				end
			end
		end
		
		-- Subtract the total value of the craft+cargo from the CPU team's funds
		self:ChangeTeamFunds(-Craft:GetTotalValue(0,3), self.CPUTeam)
		
		-- Spawn the Craft onto the scene
		MovableMan:AddActor(Craft)
	end
end

function BunkerBreach:CreateMediumDrop(xPosLZ)
	-- Pick a craft to deliver with
	local Craft, actorsInCargo
	if math.random() < 0.6 then
		Craft = RandomACDropShip("Craft", self.CPUTechName)
		actorsInCargo = math.random(2, rte.PassengerMax)
	else
		Craft = RandomACRocket("Craft", self.CPUTechName)
		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 i = 1, actorsInCargo do
			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
				Passenger:AddAIMOWaypoint(self.AttackActor)
				table.insert(self.HunterActors, Passenger)
				Craft:AddInventoryItem(Passenger)
				
				-- Stop adding actors when exceeding the weight limit
				if Craft.Mass > craftMaxMass then 
					break
				end
			end
		end
		
		-- Subtract the total value of the craft+cargo from the CPU team's funds
		self:ChangeTeamFunds(-Craft:GetTotalValue(0,3), self.CPUTeam)
		
		-- Spawn the Craft onto the scene
		MovableMan:AddActor(Craft)
	end
end

function BunkerBreach:CreateLightDrop(xPosLZ)
	-- Pick a craft to deliver with
	local Craft, actorsInCargo
	if math.random() < 0.6 then
		Craft = RandomACDropShip("Craft", self.CPUTechName)
	else
		Craft = RandomACRocket("Craft", self.CPUTechName)
	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 i = 1, rte.PassengerMax do
			if RangeRand(10, 200) < self.Difficulty then
				Passenger = self:CreateMediumInfantry()
			else
				Passenger = self:CreateLightInfantry()
			end
			
			if Passenger then
				Passenger:AddAIMOWaypoint(self.AttackActor)
				table.insert(self.HunterActors, Passenger)
				Craft:AddInventoryItem(Passenger)
				
				-- Stop adding actors when exceeding the weight limit
				if Craft.Mass > craftMaxMass then 
					break
				end
			end
		end
		
		-- Subtract the total value of the craft+cargo from the CPU team's funds
		self:ChangeTeamFunds(-Craft:GetTotalValue(0,3), self.CPUTeam)
		
		-- Spawn the Craft onto the scene
		MovableMan:AddActor(Craft)
	end
end

function BunkerBreach:CreateScoutDrop(xPosLZ)
	-- Pick a craft to deliver with
	local Craft, actorsInCargo
	if math.random() < 0.6 then
		Craft = RandomACDropShip("Craft", self.CPUTechName)
	else
		Craft = RandomACRocket("Craft", self.CPUTechName)
	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 i = 1, rte.PassengerMax do
			if math.random() < 0.3 then
				Passenger = self:CreateLightInfantry()
			else
				Passenger = self:CreateScoutInfantry()
			end
			
			if Passenger then
				Passenger:AddAIMOWaypoint(self.AttackActor)
				table.insert(self.HunterActors, Passenger)
				Craft:AddInventoryItem(Passenger)
				
				-- Stop adding actors when exceeding the weight limit
				if Craft.Mass > craftMaxMass then 
					break
				end
			end
		end
		
		-- Subtract the total value of the craft+cargo from the CPU team's funds
		self:ChangeTeamFunds(-Craft:GetTotalValue(0,3), self.CPUTeam)
		
		-- Spawn the Craft onto the scene
		MovableMan:AddActor(Craft)
	end
end


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

function BunkerBreach:CreateTurret(mode)
	local Passenger = RandomACrab("Turret", self.CPUTechName)
	if Passenger then
		-- Set AI mode and team so it knows who and what to fight for!
		Passenger.AIMode = mode or Actor.AIMODE_SENTRY
		Passenger.Team = self.CPUTeam
		return Passenger
	end
end

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

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

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

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

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

function BunkerBreach:CreateSniper(mode)
	local	Passenger
	if math.random() < 0.7 then
		Passenger = RandomAHuman("Light Infantry", self.CPUTechName)
	else
		Passenger = RandomAHuman("Heavy Infantry", self.CPUTechName)
	end
	
	if Passenger then
		Passenger:AddInventoryItem(RandomHDFirearm("Sniper Weapons", self.CPUTechName))
		Passenger:AddInventoryItem(RandomHDFirearm("Secondary Weapons", self.CPUTechName))
		
		-- Set AI mode and team so it knows who and what to fight for!
		Passenger.AIMode = mode or Actor.AIMODE_GOTO
		Passenger.Team = self.CPUTeam
		return Passenger
	end
end

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

function BunkerBreach:CreateBrainBot(mode)
	local Act = RandomAHuman("Brains", self.CPUTechName)
	if Act then
		Act:AddInventoryItem(RandomHDFirearm("Light Weapons", self.CPUTechName))
		Act:AddInventoryItem(CreateHDFirearm("Medium Digger", "Base.rte"))

		if PosRand() < 0.5 then
			Act:AddInventoryItem(RandomHDFirearm("Secondary Weapons", self.CPUTechName))
		end

		-- Set AI mode and team so it knows who and what to fight for!
		Act.AIMode = mode or Actor.AIMODE_SENTRY
		Act.Team = self.CPUTeam
		return Act
	end
end
