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

function Survival:SceneTest()
--[[ THIS TEST IS DONE AUTOMATICALLY BY THE GAME NOW; IT SCANS THE SCRIPT FOR ANY MENTIONS OF "GetArea" AND TESTS THE SCENES FOR HAVING THOSE USED AREAS DEFINED!
	-- See if the required areas are present in the test scene
	if not (TestScene:HasArea("LZ Team 1") and TestScene:HasArea("LZ Team 2")) then
		-- If the test scene failed the compatibility test, invalidate it
		TestScene = nil;
	end
--]]
end

function Survival:StartActivity()
	print("START! -- Survival:StartActivity()!");
	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;
					AudioMan:ClearMusicQueue();
					AudioMan:PlayMusic("Base.rte/Music/dBSoundworks/ccambient4.ogg", -1, -1);
				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

	-- Select a tech for the CPU player
	self.CPUTechName = rte.TechList[math.ceil(math.random() * #rte.TechList)];
	self.ESpawnTimer = Timer();
	self.LZ = SceneMan.Scene:GetArea("LZ Team 1");
	self.EnemyLZ = SceneMan.Scene:GetArea("LZ All");

	self.SurvivalTimer = Timer();
	
	if self.Difficulty <= GameActivity.CAKEDIFFICULTY then
		self.TimeLimit = 125000;
		self.timeDisplay = "two minutes";
		self:SetTeamFunds(10000 * rte.StartingFundsScale, Activity.TEAM_1);
		self.BaseSpawnTime = 6000;
		self.RandomSpawnTime = 8000;
	elseif self.Difficulty <= GameActivity.EASYDIFFICULTY then
		self.TimeLimit = 185000;
		self.timeDisplay = "three minutes";
		self:SetTeamFunds(5000 * rte.StartingFundsScale, Activity.TEAM_1);
		self.BaseSpawnTime = 5500;
		self.RandomSpawnTime = 7000;
	elseif self.Difficulty <= GameActivity.MEDIUMDIFFICULTY then
		self.TimeLimit = 245000;
		self.timeDisplay = "four minutes";
		self:SetTeamFunds(3000 * rte.StartingFundsScale, Activity.TEAM_1);
		self.BaseSpawnTime = 5000;
		self.RandomSpawnTime = 6000;
	elseif self.Difficulty <= GameActivity.HARDDIFFICULTY then
		self.TimeLimit = 305000;
		self.timeDisplay = "five minutes";
		self:SetTeamFunds(2000 * rte.StartingFundsScale, Activity.TEAM_1);
		self.BaseSpawnTime = 4500;
		self.RandomSpawnTime = 5000;
	elseif self.Difficulty <= GameActivity.NUTSDIFFICULTY then
		self.TimeLimit = 485000;
		self.timeDisplay = "eight minutes";
		self:SetTeamFunds(1000 * rte.StartingFundsScale, Activity.TEAM_1);
		self.BaseSpawnTime = 4000;
		self.RandomSpawnTime = 4500;
	elseif self.Difficulty <= GameActivity.MAXDIFFICULTY then
		self.TimeLimit = 605000;
		self.timeDisplay = "ten minutes";
		self:SetTeamFunds(1000 * rte.StartingFundsScale, Activity.TEAM_1);
		self.BaseSpawnTime = 3500;
		self.RandomSpawnTime = 4000;
	end
	
	-- CPU Funds are unlimited
	self:SetTeamFunds(1000000, self.CPUTeam);

	self.StartTimer = Timer();
	
	self.TimeLeft = (self.BaseSpawnTime + math.random(self.RandomSpawnTime)) * rte.SpawnIntervalScale;
end

function Survival:PauseActivity(pause)
		print("PAUSE! -- Survival:PauseActivity()!");
end

function Survival:EndActivity()
		print("END! -- Survival:EndActivity()!");
		
end

function Survival:UpdateActivity()
	self:ClearObjectivePoints();

	if self.ActivityState ~= Activity.OVER and self.ActivityState ~= Activity.EDITING then
		for player = Activity.PLAYER_1, Activity.MAXPLAYERCOUNT - 1 do
			if self:PlayerActive(player) and self:PlayerHuman(player) then
				--Display messages.
				if self.StartTimer:IsPastSimMS(3000) then
					local secondsLeft;
					secondsLeft = math.floor(self.SurvivalTimer:LeftTillSimMS(self.TimeLimit) / 1000);
					if (secondsLeft > 1) then
						FrameMan:SetScreenText(math.floor(self.SurvivalTimer:LeftTillSimMS(self.TimeLimit) / 1000) .. " seconds left", player, 0, 1000, false);
					else
						FrameMan:SetScreenText("1 second left!", player, 0, 1000, false);
					end
				else
					FrameMan:SetScreenText("Survive for " .. self.timeDisplay .. "!", 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);
					-- Now see if all brains of self player's team are dead, and if so, end the game
					if not MovableMan:GetFirstBrainActor(team) then
						self.WinnerTeam = self:OtherTeam(team);
						ActivityMan:EndActivity();
					end
				else
					self:AddObjectivePoint("Protect!", self:GetPlayerBrain(player).AboveHUDPos, self:GetTeamOfPlayer(player), GameActivity.ARROWDOWN);
				end
				
				--Check if the player has won.
				if self.SurvivalTimer:IsPastSimMS(self.TimeLimit) then
					self:ResetMessageTimer(player);
					FrameMan:ClearScreenText(player);
					FrameMan:SetScreenText("You survived!", player, 333, -1, false);
					
					self.WinnerTeam = Activity.TEAM_1;
					
					--Kill all enemies.
					for actor in MovableMan.Actors do
						if actor.Team ~= self.WinnerTeam then
							actor.Health = 0;
						end
					end

					ActivityMan:EndActivity();
				end
			end
		end

		--Spawn the AI.
		if self.CPUTeam ~= Activity.NOTEAM and self.ESpawnTimer:LeftTillSimMS(self.TimeLeft) <= 0 and MovableMan:GetMOIDCount() <= rte.MOIDCountMax then
			local ship, actorsInCargo
			
			if PosRand() < 0.5 then
				-- Set up the ship to deliver this stuff
				ship = RandomACDropShip("Any", self.CPUTechName);
				-- If we can't afford this dropship, then try a rocket instead
				if ship.TotalValue or 0 > self:GetTeamFunds(self.CPUTeam) then
					DeleteEntity(ship);
					ship = RandomACRocket("Any", self.CPUTechName);
				end
				actorsInCargo = rte.PassengerMax
			else
				ship = RandomACRocket("Any", self.CPUTechName);
				actorsInCargo = math.min(rte.PassengerMax, 2)
			end
			
			ship.Team = self.CPUTeam;
			
			-- Set the ship up with a cargo of a few armed and equipped actors
			for i = 1, actorsInCargo do
				-- Get any Actor from the CPU's native tech
				local passenger = nil;
				if math.random() >= rte.CrabToHumanSpawnRatio then
					passenger = RandomAHuman("Any", self.CPUTechName);
				else
					passenger = RandomACrab("Any", self.CPUTechName);
				end
				-- Equip it with tools and guns if it's a humanoid
				if IsAHuman(passenger) then
					passenger:AddInventoryItem(RandomHDFirearm("Primary Weapons", self.CPUTechName));
					passenger:AddInventoryItem(RandomHDFirearm("Secondary Weapons", self.CPUTechName));
					if PosRand() < 0.5 then
						passenger:AddInventoryItem(RandomHDFirearm("Diggers", self.CPUTechName));
					end
				end
				-- Set AI mode and team so it knows who and what to fight for!
				passenger.AIMode = Actor.AIMODE_BRAINHUNT;
				passenger.Team = self.CPUTeam;

				-- Check that we can afford to buy and to carry the weight of this passenger
				if ((ship.TotalValue or 0) + (passenger.TotalValue or 0)) <= self:GetTeamFunds(self.CPUTeam) and (ship.Mass + passenger.Mass) <= rte.ShipMassMax then
					-- Yes we can; so add it to the cargo hold
					ship:AddInventoryItem(passenger);
					passenger = nil;
				else
					-- Nope; just delete the nixed passenger and stop adding new ones
					-- This doesn't need to be explicitly deleted here, teh garbage collection would do it eventually..
					-- but since we're so sure we don't need it, might as well go ahead and do it here right away
					DeleteEntity(passenger);
					passenger = nil;
					
					if i < 2 then	-- Don't deliver empty craft
						DeleteEntity(ship);
						ship = nil;
					end
					
					break;
				end
			end
			
			if ship then
				-- Set the spawn point of the ship from orbit
				if self.playertally == 1 then
					for i = 1, #self.playerlist do
						if self.playerlist[i] == true then
							local sceneChunk = SceneMan.SceneWidth / 3;
							local checkPos = self:GetPlayerBrain(i - 1).Pos.X + (SceneMan.SceneWidth/2) + ( (sceneChunk/2) - (math.random()*sceneChunk) );
							if checkPos > SceneMan.SceneWidth then
								checkPos = checkPos - SceneMan.SceneWidth;
							elseif checkPos < 0 then
								checkPos = SceneMan.SceneWidth + checkPos;
							end
							ship.Pos = Vector(checkPos,-50);
							break;
						end
					end
				else
					if SceneMan.SceneWrapsX then
						ship.Pos = Vector(math.random() * SceneMan.SceneWidth, -50);
					else
						ship.Pos = Vector(RangeRand(100, SceneMan.SceneWidth-100), -50);
					end
				end

				-- Double-check if the computer can afford this ship and cargo, then subtract the total value from the team's funds
				local shipValue = ship.TotalValue or 0;
				if shipValue <= self:GetTeamFunds(self.CPUTeam) then
					-- Subtract the total value of the ship+cargo from the CPU team's funds
					self:ChangeTeamFunds(-shipValue, self.CPUTeam);
					-- Spawn the ship onto the scene
					MovableMan:AddActor(ship);
				else
					-- The ship and its contents is deleted if it can't be afforded
					-- This doesn't need to be explicitly deleted here, teh garbage collection would do it eventually..
					-- but since we're so sure we don't need it, might as well go ahead and do it here right away
					DeleteEntity(ship);
					ship = nil;
				end
			end

			self.ESpawnTimer:Reset();
			self.TimeLeft = (self.BaseSpawnTime + math.random(self.RandomSpawnTime) * rte.SpawnIntervalScale)
		end
	else
		self.StartTimer:Reset();
		self.SurvivalTimer:Reset();
	end
	
	self:YSortObjectivePoints();
end