-- ######################################################################### --
-- ##                   Author: Cobaltur                                  ## --
-- ## inspired by BrockSamson Insane Extension                            ## --
-- ## inspired by Extreme Script                                          ## --
-- ##                                                                     ## --
-- ##                                                                     ## --
-- ##                                                                     ## --
-- ##                         			                                      ## --
-- ##                                                                     ## --
-- ##                                                                     ## --
-- ## --------------------------------------------------------------------## --
-- ##           20 December 08                                            ## --
-- ##           Adjusted Options                                          ## --
-- ##           Added 7-60 minutes startup time options                   ## --
-- ##           Changed defaults                                          ## --
-- ##           Removed Restrictions                                                        ## --
-- ##           Completely disabled Artillery, Nukes & Naval              ## --
-- ##           Disabled Cinematics NISMode                               ## --
-- ## --------------------------------------------                        ## --
-- ##                                                                     ## --
-- ##           08 June 08 Cobaltur adoopted for map   	     		          ## --
-- ##                  -     Survival Campaign         		                ## --
-- ##           Waypoints extended						                            ## --
-- ##           Cinematics and Dialogs						                        ## --
-- ##           Objectives <-> playable Areas					                    ## --
-- ##           Defense , Fullfilled nuke defense                         ## --
-- ##           Shield and Turrets depend on difficulty                   ## --
-- ##            higher regen and recharge time -> shiels is longer down  ## --
-- ##           The Arch !								                                ## --
-- ##                                                                     ## --
-- ##          ----------  Initial Version--------------------------------## --
-- ##                                                                     ## --
-- ##           Survival *EXtremeDesertV3fA*				                      ## --
-- ##           Game Logic Script							                            ## -- 
-- ##           (c) tecxx@rrs.at						                            	## --
-- ##           29.11.07								                                  ## --
-- ######################################################################### --



---   difficulty  ; 5 is normal   good to know

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- imports and variables
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local ScenarioUtils = import('/lua/sim/ScenarioUtilities.lua');
local ScenarioFramework = import('/lua/ScenarioFramework.lua');
local Utilities = import('/lua/utilities.lua');
local Entity = import('/lua/sim/Entity.lua').Entity;
local Cinematics = import('/lua/cinematics.lua')
--local OpStrings = import('Survival_Campaign_v1b_strings.lua')
local OpStrings;
-------

local BaseManager = import('/lua/ai/opai/basemanager.lua')
local Cinematics = import('/lua/cinematics.lua')
local Objectives = import('/lua/ScenarioFramework.lua').Objectives
local PingGroups = import('/lua/ScenarioFramework.lua').PingGroups
local ScenarioPlatoonAI = import('/lua/ScenarioPlatoonAI.lua')
local TauntManager = import('/lua/TauntManager.lua')
local Explosions = import('/lua/defaultexplosions.lua')
ScenarioInfo.ARMY_1 = 1
ScenarioInfo.ARMY_2 = 2
ScenarioInfo.ARMY_3 = 3
ScenarioInfo.ARMY_4 = 4

-------
-- global vars
local gameEnd = false;		-- true when game is over
local beatTime = 1;			-- seconds to wait between game logic calculations
local playercount = 0;		-- how many human players?

-- survival mode
local HealthBuff = 1; -- health multiplier    --- what for bugs   
local numGatesOpen = 0; 	-- how many spawn gates are alive
local gates = {nil, nil, nil, nil, nil};	-- gate pointers
local numSpecialsOpen = 0;	-- how many special weapons are alive
local specials = {nil, nil, nil, nil}; -- special pointers
local antinukes = {nil, nil, nil, nil}; 
local killCount = { ARMY_1 = 0,		-- number of gates/specials killed by each player+2 ai's
					ARMY_2 = 0,
					ARMY_3 = 0,
					ARMY_4 = 0,
					ARMY_SUPERWEAPON = 0,
					ARMY_SURVIVAL_ENEMY = 0};

-- as we now make an objective line it would have been easier to set these values in the mission steps					
  
local platoonsize; -- depends on difficult level up to level 12
  
local finalrif_a; -- also accessible as gate4
local finalrif_b; -- also accessible as gate5

local ShowCinematiceUpToLevel = 7;
local ShowDialogs = 20;

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- engine invoked main functions
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-- this function is called once before game start, it does some player initialization
function OnPopulate()

	-- make default settings work
	if (ScenarioInfo.Options.opt_difficulty == nil) then
		ScenarioInfo.Options.opt_difficulty = 20;
	end
	if (ScenarioInfo.Options.opt_startupTime == nil) then
		ScenarioInfo.Options.opt_startupTime = 1200;   
	end
	if (ScenarioInfo.Options.opt_waveTime == nil) then
		ScenarioInfo.Options.opt_waveTime = 60;
	end
	if (ScenarioInfo.Options.opt_defenseObject == nil) then
		ScenarioInfo.Options.opt_defenseObject = 2;
	end
	
	ScenarioUtils.InitializeArmies();
	ScenarioFramework.SetPlayableArea('AREA_1', false);
	
	-- count number of players
	local armies = ListArmies();
	playercount = table.getn(armies) - 2;	-- num armies minus 2 ai players
  -- import('/lua/ui/campaign/campaignmanager.lua').campaignMode =true;
	LOG("___SE___ PlayerCount: "..playercount);
end


-- start of map script
function OnStart(self)
	-- initiate game modes and spawn players
	setupGame();
  ForkThread(spawnThread);
	MissionSetup1(); -- forks
  MissionSecondary_1_init()
	MissionSecondary_2_init()
  MissionSecondary_3_init()
	-- set score calculation to show total kills
	for index, brain in ArmyBrains do
		brain.CalculateScore = function(thisBrain)
			--return armyKills(thisBrain) + killCount[ArmyIndexer(thisBrain)]*1000;
      return armyKills(thisBrain) + killCount[ArmyIndexer(thisBrain)]*10000;
		end
	end 
  
end

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- main game logic
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

function MissionSetup1()

      --Creation of objective
 ---  MISSION 1      
  ScenarioInfo.SurvivalMission1End = Objectives.Kill(
          'primary',
          'incomplete', 
          OpStrings.EndGameTitle, 
          OpStrings.EndGameDescription,
          {
              MarkUnits = true,
              FlashVisible = false,
              Units = {gates[1]}
          }
      )
  ScenarioInfo.SurvivalMission1End:AddResultCallback(MissionSetup2);

  ---  MISSION 2
  ScenarioInfo.SurvivalMission2End = Objectives.Kill(
        'primary',
        'incomplete', 
        OpStrings.Mission2Title, 
        OpStrings.Mission2Description,
        {
            MarkUnits = true,
            FlashVisible = false,
            Units = {gates[2],gates[3]}
        }
    )
  ScenarioInfo.SurvivalMission2End:AddResultCallback(MissionSetupFinal);

  ---- Mission 3
  ScenarioInfo.SurvivalEndGame = Objectives.Kill(
        'primary',
        'incomplete', 
        OpStrings.EndGameTitle, 
        OpStrings.EndGameDescription,
        {
            MarkUnits = true,
            FlashVisible = false,
            Units = {finalrif_a, finalrif_b}
        }
    )
    ScenarioInfo.SurvivalEndGame:AddResultCallback(function(result)
        if(result) then
            PlayerWin()
        end
    end);  
	
  ForkThread(
		function()
			WaitSeconds(20)
      ScenarioFramework.Dialogue(OpStrings.fun1, nil, true)
			
--			if( ShowCinematiceUpToLevel >= ScenarioInfo.Options.opt_difficulty ) then
--				Cinematics.EnterNISMode()
--				Cinematics.CameraMoveToRectangle(ScenarioUtils.AreaToRect('AREA_VIS_1'), 3) -- take 5 sec to zoom in
--			end

		  ScenarioFramework.CreateVisibleAreaLocation( 15, ScenarioUtils.MarkerToPosition( 'Vis_1' ), 10, ArmyBrains[ScenarioInfo.ARMY_1] )
			WaitSeconds(2)
			ScenarioFramework.Dialogue(OpStrings.Mission1, nil, true)
			WaitSeconds(2)
		
			DefenseMissionSetup()

		
--			if( ShowCinematiceUpToLevel >= ScenarioInfo.Options.opt_difficulty ) then
--			Cinematics.ExitNISMode()
--			end
		end
	)

end

function MissionSecondary_1_init()
 ForkThread(
		function()
    	local obj = Objectives.CategoriesInArea(
		        'secondary',
		        'incomplete', 
		        "Wait for first t2 building", 
		        "Mission",
            'Build',
		        {
		            MarkArea = false,		            
                ShowProgress = false,
                Requirements = 
                {
                  {
                    Area = "AREA_CDR_DEFENSE", 
                    Category = categories.STRUCTURE * categories.TECH2 , 
                    CompareOp = '>=', 
                    Value = playercount/2,
                  },
                },
		        }
		  ) -- thread will be forked
      obj:AddResultCallback( MissionSecondary_1 );	
    end
  )
end

local objective_secondary_1 ={};

function MissionSecondary_1()

      WaitSeconds(5)
			ScenarioFramework.Dialogue(OpStrings.X1T_TU06_090, nil, true)
			for i = 1,8 do
        local area = 'AREA_T'..i
        local obj = Objectives.CategoriesInArea(
		        'secondary',
		        'incomplete', 
		        "Build defense", 
		        "Build a lot of t2 defenses",
            'Build',
		        {
		            MarkArea = true,		            
                ShowProgress = true,
                Requirements = 
                {
                  {
                    Area = area, 
                    Category = categories.STRUCTURE * categories.DEFENSE * categories.TECH2 * categories.DIRECTFIRE, 
                    CompareOp = '>=', 
                    Value = 1,
                  },
                },
		        }
		  ) -- thread will be forked
      table.insert(objective_secondary_1,obj);


       
      -- obj:AddResultCallback( function()
              -- LOG(" secondary completed");
              -- end
          -- );			
      end

end

function MissionSetup2() 
	--ForkThread(
	--	function()
			ScenarioFramework.SetPlayableArea('AREA_2', false);
      ScenarioFramework.Dialogue(OpStrings.X1T_TU06_020, nil, true)


			--if( ShowCinematiceUpToLevel >= ScenarioInfo.Options.opt_difficulty ) then
				--Cinematics.EnterNISMode()
			   ScenarioFramework.CreateVisibleAreaLocation( 20, ScenarioUtils.MarkerToPosition( 'Vis_2' ), 10, ArmyBrains[ScenarioInfo.ARMY_1] )
				--Cinematics.CameraMoveToRectangle(ScenarioUtils.AreaToRect('AREA_VIS_2'), 1.5) -- take 5 sec to zoom in

				 -- WaitSeconds(1)
			    ScenarioFramework.CreateVisibleAreaLocation( 20, ScenarioUtils.MarkerToPosition( 'Vis_3' ), 10, ArmyBrains[ScenarioInfo.ARMY_1] )
				 --Cinematics.CameraMoveToRectangle(ScenarioUtils.AreaToRect('AREA_VIS_3'), 1.5) -- take 5 sec to zoom in

				 -- WaitSeconds(1)
			--else
			--	 WaitSeconds(5)
			-- end

			ScenarioFramework.Dialogue(OpStrings.Mission_Setup_2, nil, true)
			-- WaitSeconds(2)
		
			 -- if( ShowCinematiceUpToLevel >= ScenarioInfo.Options.opt_difficulty ) then
				 -- Cinematics.ExitNISMode()
			 -- end

			WaitSeconds(10)
			
      removeRestrictions();
			ScenarioFramework.Dialogue(OpStrings.SecondaryMissionEnd_B, nil, true)
			
		--end
	--)
end


function MissionSetupFinal()
	
	ForkThread(
		function()
			ScenarioFramework.SetPlayableArea('AREA_3', false);
			ScenarioFramework.Dialogue(OpStrings.X1T_TU06_020, nil, true)

			WaitSeconds(5)
			
--			if( ShowCinematiceUpToLevel >= ScenarioInfo.Options.opt_difficulty ) then
--				Cinematics.EnterNISMode()
				
--			Cinematics.CameraMoveToRectangle(ScenarioUtils.AreaToRect('AREA_VIS_RIFT'), 3) -- take 5 sec to zoom in
--		end
      
		  ScenarioFramework.CreateVisibleAreaLocation( 35, ScenarioUtils.MarkerToPosition( 'Vis_Rift_a' ), 10, ArmyBrains[ScenarioInfo.ARMY_1] )
			ScenarioFramework.CreateVisibleAreaLocation( 35, ScenarioUtils.MarkerToPosition( 'Vis_Rift_b' ), 10, ArmyBrains[ScenarioInfo.ARMY_1] )
			ScenarioFramework.Dialogue(OpStrings.X06_DB01_020, nil, true)
			WaitSeconds(3)
		
--			if( ShowCinematiceUpToLevel >= ScenarioInfo.Options.opt_difficulty ) then
--			Cinematics.ExitNISMode()
--		end
      
      WaitSeconds(10)
      ScenarioFramework.Dialogue(OpStrings.SecondaryMissionEnd_B2, nil, true)
			removeRestrictions2();
			
      WaitSeconds(50)
			ScenarioFramework.Dialogue(OpStrings.X06_M03_030, nil, true)
			WaitSeconds(120)
			ScenarioFramework.Dialogue(OpStrings.X06_M03_130, nil, true)
			
		end
	)		
end


function MissionSecondary_2_init()
 ForkThread(
		function()
    
    	local obj = Objectives.CategoriesInArea(
		        'secondary',
		        'incomplete', 
		        "Wait for first t3 building", 
		        "Mission",
            'Build',
		        {
		            MarkArea = false,		            
                ShowProgress = false,
                Requirements = 
                {
                  {
                    Area = "AREA_CDR_DEFENSE", 
                    Category = categories.STRUCTURE * categories.TECH3 , 
                    CompareOp = '>=', 
                    Value = 1,
                  },
                },
		        }
		  ) -- thread will be forked
      obj:AddResultCallback( 
          function()
            --ScenarioFramework.Dialogue(OpStrings.SecondaryMissionStart_B, nil, true)
           	for i, obj in objective_secondary_1 do
              if(obj.Active) then
                obj:ManualResult(true);
              end
            end
          end
      );	
      

  end
  )
end

function MissionSecondary_3_init()
  -- LOG("sec 3 init")
 ForkThread(
		function()
    	local obj = Objectives.CategoriesInArea(
		        'secondary',
		        'incomplete', 
		        "Wait for first t3 building", 
		        "Mission",
            'Build',
		        {
		            MarkArea = false,		            
                ShowProgress = false,
                Requirements = 
                {
                  {
                    Area = "AREA_SHIELD_HINT", 
                    Category = categories.MOBILE + categories.LAND + categories.AIR,  --if any unit is in range
                    CompareOp = '>=', 
                    Value = 1,
                    ArmyIndex = 1,
                  },
                },
		        }
		  ) -- thread will be forked
      obj:AddResultCallback( 
          function()
        			ScenarioFramework.Dialogue(OpStrings.ShieldHint, nil, true)
          end
      );	
    end
  )
end



DefenseMissionSetup = function()
	-- currently nor forked
	-- execute in context of First Mission
	--Protect(Type,Complete,Title,Description,Target)

	ScenarioInfo.DefenseMission = Objectives.Protect(
		        'primary',
		        'incomplete', 
		        "Defense", 
		        "Defend the object at all cost or we will loose.",
		        {
		            Units = {ScenarioInfo.DefenseObject},
		            NumRequired = 1,
		            Timer = nil,
                PercentProgress = true,
		        }
		    )
	ScenarioInfo.DefenseMission:AddResultCallback(DefenseMissionLost);
	ScenarioFramework.PauseUnitDeath( ScenarioInfo.DefenseObject )
	
--	if( ShowCinematiceUpToLevel >= ScenarioInfo.Options.opt_difficulty ) then
--		Cinematics.CameraMoveToRectangle(ScenarioUtils.AreaToRect('AREA_CAM_DEFENSE'), 5) -- take 5 sec to zoom in
--	end
	ScenarioFramework.CreateVisibleAreaLocation( 65, ScenarioUtils.MarkerToPosition( 'HILL_CENTER' ), 0, ArmyBrains[ScenarioInfo.ARMY_1] )

	ScenarioFramework.Dialogue(OpStrings.X01_M02_035, nil, true)
	WaitSeconds(2)
  

	
end

DefenseMissionLost = function()

  local unit = ScenarioInfo.DefenseObject;
	Cinematics.EnterNISMode()
	Cinematics.CameraMoveToRectangle(ScenarioUtils.AreaToRect('AREA_CAM_DEFENSE'), 5) -- take 5 sec to zoom in

	local scale = 2;
  local Explosion = ScenarioInfo.DefenseObject #Entity(spec)
  local army = unit:GetArmy()

  Explosions.CreateConcussionRing( Explosion, scale )
  unit:ShakeCamera(50, 2, 0, 0.5)
  Explosions.CreateScalableUnitExplosion(unit)
  ForkThread( Explosions.CreateCompositeExplosionMeshes, Explosion )


	for i, army in ListArmies() do
		if (army == "ARMY_1" or army == "ARMY_2" or army == "ARMY_3" or army == "ARMY_4") then
		killAllCommanders(army);
		GetArmyBrain(army):OnDefeat();
		end
	end


	msgOut("The defense object has been destroyed. You have lost!");

	loopEnd = true;
	gameEnd = true;

  WaitSeconds(4)
  Cinematics.ExitNISMode()

end		


function PlayerWin()
  ForkThread(function()
LOG("___SE___ player win()");
    ScenarioInfo.DefenseObject:SetCanTakeDamage(false)
    ScenarioInfo.DefenseObject:SetCanBeKilled(false)
  	Cinematics.EnterNISMode()    
      
                ScenarioFramework.FlushDialogueQueue()
                while(ScenarioInfo.DialogueLock) do
                    WaitSeconds(0.2)
                end
                ScenarioFramework.Dialogue(OpStrings.FinalMissionWon, KillGame, true)
                
  	Cinematics.CameraMoveToRectangle(ScenarioUtils.AreaToRect('AREA_VIS_RIFT'),0.3) -- take 5 sec to zoom in

    WaitSeconds(4)
    UnlockInput()
  	Cinematics.ExitNISMode()    
      
  	
  end)
end
function KillGame()
LOG("___SE___ KillGame()");


		GetArmyBrain("ARMY_SURVIVAL_ENEMY"):OnDefeat();
		gameEnd = true;  

    ForkThread(
        function()
            WaitSeconds(4)
        		-- all gates down, display victory and end game
        		for i, army in ListArmies() do
        			if (army == "ARMY_1" or army == "ARMY_2" or army == "ARMY_3" or army == "ARMY_4" or
        			    army == "ARMY_5" or army == "ARMY_6" or army == "ARMY_7" or army == "ARMY_8") then
        				GetArmyBrain(army):OnVictory();
        			end
        		end            
            ScenarioFramework.EndOperationSafety() -- so our commanders got now longer be killed   -- parameter could be a list of protective units as well
            --local endDialog = import('/lua/SimDialogue.lua').Create(LOC("<LOC X1TU_0000>Congratulations, Commanders. You have defeated the enemy."), {LOC("<LOC _OK>")}	)
            -- endDialog.OnButtonPressed = function(self, info)
                -- ScenarioFramework.ExitGame()
            -- end
			-- import('/lua/SimDialogue.lua').Create(LOC("<LOC X1TU_0000>Congratulations, Commanders. You have defeated the enemy."), {LOC("<LOC _OK>")}	)
        end
    )
   
end


	
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- survival mode
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- unit tables, seperated by air/ground
-- unit tables designed by BrockSamson
-- Cobaltur : I removed the t2 from the first wave . It would be enough up form the 2nd ( 8min)
local unitTableGroundCoba = {
	{ -- Wave Set 1
		'UAL0106', -- aeon light assault
		'UAL0201', -- aeon light tank
		'URL0106', -- cybran light assault
		'URL0107', -- cybran heavy assault
		'UEL0106', -- uef light assault
		'UEL0201', -- uef medium tank
		'xsl0101', -- seraphim combat scout
		'xsl0201', -- seraphim medium tank

		'UAL0101', -- aeon scout
		'UAL0103', -- aeon t1 arty
		'URL0101', -- cybran scout
		'URL0103', -- cybran t1 arty
		'UEL0101', -- uef scout
		'UEL0103', -- uef t1 arty	
		'xsl0101', -- seraphim combat scout
		'xsl0103', -- seraphim light artillery
--no t2 in wave 1 to hard 
--		'UAL0202', -- aeon t2 tank
--		'UAL0205', -- aeon t2 aa
--		'URL0202', -- cybran t2 tank
		--'URL0203', -- cybran t2 amphibious tank
--		'URL0205', -- cybran t2 aa
--		'UEL0202', -- uef t2 tank
		--'UEL0203', -- uef t2 amphibious tank
--		'UEL0205', -- uef t2 aa	
--		'DRL0204', -- cybran t2 rocket
		--'DEL0204', -- uef t2 gatling
--		'xal0203', -- aeon t2 assault tank
		--'xsl0202', -- seraphim t2 assault bot
--		'xsl0203', -- seraphim t2 hover tank
--		'xsl0205', -- seraphim t2 anti air
	},
	{ -- Wave Set 2
		'UAL0201', -- aeon light tank
		'URL0107', -- cybran heavy assault
		'UEL0201', -- uef medium tank
		'xsl0201', -- seraphim medium tank

		'UAL0101', -- aeon scout
		'UAL0103', -- aeon t1 arty
		'URL0101', -- cybran scout
		'URL0103', -- cybran t1 arty
		'UEL0101', -- uef scout
		'UEL0103', -- uef t1 arty	
		'xsl0101', -- seraphim combat scout
		'xsl0103', -- seraphim light artillery

		'UAL0202', -- aeon t2 tank
		'UAL0111', -- aeon t2 missile launcher
		--'UAL0307', -- aeon t2 shield
		'UAL0205', -- aeon t2 aa
		'URL0202', -- cybran t2 tank
		'URL0203', -- cybran t2 amphibious tank
		'URL0111', -- cybran t2 missile launcher
		--'URL0306', -- cybran t2 stealth -- originally inactive here
		'URL0205', -- cybran t2 aa
		'UEL0202', -- uef t2 tank
		'UEL0203', -- uef t2 amphibious tank
		'UEL0111', -- uef t2 missile launcher
		--'UEL0307', -- uef t2 shield
		'UEL0205', -- uef t2 aa	
		'DRL0204', -- cybran t2 rocket
		'DEL0204', -- uef t2 gatling
		'xal0203', -- aeon t2 assault tank
		'xsl0202', -- seraphim t2 assault bot
		'xsl0203', -- seraphim t2 hover tank
		'xsl0205', -- seraphim t2 anti air
		'xsl0111', -- seraphim t2 mobile missile
	},
	{ -- Wave Set 3
		'UAL0202', -- aeon t2 tank
		'UAL0111', -- aeon t2 missile launcher
		'UAL0307', -- aeon t2 shield
		'UAL0205', -- aeon t2 aa
		'URL0202', -- cybran t2 tank
		'URL0203', -- cybran t2 amphibious tank
		'URL0111', -- cybran t2 missile launcher
--		'URL0306', -- cybran t2 stealth -- originally active here
		'URL0205', -- cybran t2 aa
		'UEL0202', -- uef t2 tank
		'UEL0203', -- uef t2 amphibious tank
		'UEL0111', -- uef t2 missile launcher
		'UEL0307', -- uef t2 shield
		'UEL0205', -- uef t2 aa	
		'DRL0204', -- cybran t2 rocket
		'DEL0204', -- uef t2 gatling
		'xal0203', -- aeon t2 assault tank
		'xsl0202', -- seraphim t2 assault bot
		'xsl0203', -- seraphim t2 hover tank
		'xsl0205', -- seraphim t2 anti air
		'xsl0111', -- seraphim t2 mobile missile
	},
	{ -- Wave Set 4
		'UAL0202', -- aeon t2 tank
		'UAL0111', -- aeon t2 missile launcher
		'UAL0307', -- aeon t2 shield
		'UAL0205', -- aeon t2 aa
		'URL0202', -- cybran t2 tank
		'URL0203', -- cybran t2 amphibious tank
		'URL0111', -- cybran t2 missile launcher
--		'URL0306', -- cybran t2 stealth -- originally active here
		'URL0205', -- cybran t2 aa
		'UEL0202', -- uef t2 tank
		'UEL0203', -- uef t2 amphibious tank
		'UEL0111', -- uef t2 missile launcher
		'UEL0307', -- uef t2 shield
		'UEL0205', -- uef t2 aa	
		'DRL0204', -- cybran t2 rocket
		'DEL0204', -- uef t2 gatling
		'xal0203', -- aeon t2 assault tank
		'xsl0202', -- seraphim t2 assault bot
		'xsl0203', -- seraphim t2 hover tank
		'xsl0205', -- seraphim t2 anti air
		'xsl0111', -- seraphim t2 mobile missile

		'UAL0303', -- aeon t3 assault bot
		'URL0303', -- cybran t3 assault bot
		'UEL0303', -- uef t3 assault bot
		'xsl0303', -- seraphim t3 siege tank
	},
	{ -- Wave Set 5
		'UAL0111', -- aeon t2 missile launcher
		'UAL0307', -- aeon t2 shield
		'UAL0205', -- aeon t2 aa
		'URL0203', -- cybran t2 amphibious tank
		'URL0111', -- cybran t2 missile launcher
		'URL0306', -- cybran t2 stealth
		'URL0205', -- cybran t2 aa
		'UEL0203', -- uef t2 amphibious tank
		'UEL0111', -- uef t2 missile launcher
		'UEL0307', -- uef t2 shield
		'UEL0205', -- uef t2 aa	
		'DRL0204', -- cybran t2 rocket
		'DEL0204', -- uef t2 gatling
		'xal0203', -- aeon t2 assault tank
		'xsl0202', -- seraphim t2 assault bot
		'xsl0205', -- seraphim t2 anti air
		'xsl0111', -- seraphim t2 mobile missile

		'UAL0303', -- aeon t3 assault bot
		'URL0303', -- cybran t3 assault bot
		'UEL0303', -- uef t3 assault bot
		'xsl0303', -- seraphim t3 siege tank
		'UAL0303', -- aeon t3 assault bot
		'URL0303', -- cybran t3 assault bot
		'UEL0303', -- uef t3 assault bot
		'xsl0303', -- seraphim t3 siege tank
	},
	{ -- Wave Set 6
		'UAL0111', -- aeon t2 missile launcher
		'UAL0307', -- aeon t2 shield
		'UAL0205', -- aeon t2 aa
		'URL0111', -- cybran t2 missile launcher
		'URL0306', -- cybran t2 stealth
		'URL0205', -- cybran t2 aa
		'UEL0111', -- uef t2 missile launcher
		'UEL0307', -- uef t2 shield
		'UEL0205', -- uef t2 aa	
		'xsl0205', -- seraphim t2 anti air
		'xsl0111', -- seraphim t2 mobile missile

		'UAL0303', -- aeon t3 assault bot
		'URL0303', -- cybran t3 assault bot
		'UEL0303', -- uef t3 assault bot
		'xsl0303', -- seraphim t3 siege tank
		'UAL0303', -- aeon t3 assault bot
		'URL0303', -- cybran t3 assault bot
		'UEL0303', -- uef t3 assault bot
		'xsl0303', -- seraphim t3 siege tank

		'DAL0310', -- aeon shield disruptor
		'xal0305', -- aeon sniper bot
		'xel0306', -- uef t3 mobile missile platform
		'xsl0307', -- seraphim t3 mobile shield gen
		'xsl0305', -- seraphim t3 sniper bot
	},
	{ -- Wave Set 7
		'UAL0111', -- aeon t2 missile launcher
		'UAL0307', -- aeon t2 shield
		'UAL0205', -- aeon t2 aa
		'URL0111', -- cybran t2 missile launcher
		'URL0306', -- cybran t2 stealth
		'URL0205', -- cybran t2 aa
		'UEL0111', -- uef t2 missile launcher
		'UEL0307', -- uef t2 shield
		'UEL0205', -- uef t2 aa	
		'xsl0205', -- seraphim t2 anti air
		'xsl0111', -- seraphim t2 mobile missile

		'UAL0303', -- aeon t3 assault bot
		'URL0303', -- cybran t3 assault bot
		'UEL0303', -- uef t3 assault bot
		'xsl0303', -- seraphim t3 siege tank
		'UAL0303', -- aeon t3 assault bot
		'URL0303', -- cybran t3 assault bot
		'UEL0303', -- uef t3 assault bot
		'xsl0303', -- seraphim t3 siege tank

		'DAL0310', -- aeon shield disruptor
		'xal0305', -- aeon sniper bot
		'xel0306', -- uef t3 mobile missile platform
		'xsl0307', -- seraphim t3 mobile shield gen
		'xsl0305', -- seraphim t3 sniper bot

		'xrl0305', -- cybran t3 armored assault bot
		'xel0305', -- uef t3 armored assault bot
		'xel0306', -- uef t3 mobile missile platform
		--'URS0201', -- cybran salem class -- originally active here
	},
	{ -- Wave Set 8
		'UAL0307', -- aeon t2 shield
		'UAL0205', -- aeon t2 aa
		'URL0306', -- cybran t2 stealth
		'URL0205', -- cybran t2 aa
		'UEL0307', -- uef t2 shield
		'UEL0205', -- uef t2 aa	
		'xsl0205', -- seraphim t2 anti air

		'UAL0303', -- aeon t3 assault bot
		'URL0303', -- cybran t3 assault bot
		'UEL0303', -- uef t3 assault bot
		'xsl0303', -- seraphim t3 siege tank

		'DAL0310', -- aeon shield disruptor
		'xal0305', -- aeon sniper bot
		'xel0306', -- uef t3 mobile missile platform
		'xsl0307', -- seraphim t3 mobile shield gen
		'xsl0305', -- seraphim t3 sniper bot

		'xrl0305', -- cybran t3 armored assault bot
		'xel0305', -- uef t3 armored assault bot
		'xrl0305', -- cybran t3 armored assault bot
		'xel0305', -- uef t3 armored assault bot
		'xel0306', -- uef t3 mobile missile platform
		--'URS0201', -- cybran salem class -- originally active here
		--'URS0201', -- cybran salem class
	},
	{ -- Wave Set 9
		'UAL0307', -- aeon t2 shield
		'UAL0205', -- aeon t2 aa
		'URL0306', -- cybran t2 stealth
		'URL0205', -- cybran t2 aa
		'UEL0307', -- uef t2 shield
		'UEL0205', -- uef t2 aa	
		'xsl0205', -- seraphim t2 anti air

		'DAL0310', -- aeon shield disruptor
		'xal0305', -- aeon sniper bot
		'xel0306', -- uef t3 mobile missile platform
		'xsl0307', -- seraphim t3 mobile shield gen
		'xsl0305', -- seraphim t3 sniper bot

		'xrl0305', -- cybran t3 armored assault bot
		'xel0305', -- uef t3 armored assault bot
		'xrl0305', -- cybran t3 armored assault bot
		'xel0305', -- uef t3 armored assault bot
		'xel0306', -- uef t3 mobile missile platform
		--'URS0201', -- cybran salem class
		--'URS0201', -- cybran salem class

		'xrl0305', -- cybran t3 armored assault bot
		'xel0305', -- uef t3 armored assault bot
		'xrl0305', -- cybran t3 armored assault bot
		'xel0305', -- uef t3 armored assault bot
		'xel0306', -- uef t3 mobile missile platform
    
    
		'UAL0301', -- aeon support commander
		'URL0301', -- cybran support commander 
		'UEL0301', -- uef support commander
		'xsl0301', -- seraphim support commander
	},
	{ -- Wave Set 10
		'UAL0307', -- aeon t2 shield
		'UAL0205', -- aeon t2 aa
		'URL0306', -- cybran t2 stealth
		'URL0205', -- cybran t2 aa
		'UEL0307', -- uef t2 shield
		'UEL0205', -- uef t2 aa	
		'xsl0205', -- seraphim t2 anti air

		'DAL0310', -- aeon shield disruptor
		'xal0305', -- aeon sniper bot
		'xel0306', -- uef t3 mobile missile platform
		'xsl0307', -- seraphim t3 mobile shield gen
		'xsl0305', -- seraphim t3 sniper bot

		'xrl0305', -- cybran t3 armored assault bot
		'xel0305', -- uef t3 armored assault bot
		'xrl0305', -- cybran t3 armored assault bot
		'xel0305', -- uef t3 armored assault bot
		'xel0306', -- uef t3 mobile missile platform

		'xrl0305', -- cybran t3 armored assault bot
		'xel0305', -- uef t3 armored assault bot
		'xrl0305', -- cybran t3 armored assault bot
		'xel0305', -- uef t3 armored assault bot
		'xel0306', -- uef t3 mobile missile platform

		--'URS0201', -- cybran salem class
		--'URS0201', -- cybran salem class

		'UAL0301', -- aeon support commander
		'URL0301', -- cybran support commander 
		'UEL0301', -- uef support commander
		'xsl0301', -- seraphim support commander
		'UAL0301', -- aeon support commander
		'URL0301', -- cybran support commander 
		'UEL0301', -- uef support commander
		'xsl0301', -- seraphim support commander

		'UAL0304', -- aeon t3 arty
		'URL0304', -- cybran t3 arty
		'UEL0304', -- uef t3 arty
		'xsl0304',	-- seraphim t3 heavy artillery
	},
	{ -- Wave Set 11  same as 10 but experimentals will be spawned too look in ....
		'UAL0307', -- aeon t2 shield
		'UAL0205', -- aeon t2 aa
		'URL0306', -- cybran t2 stealth
		'URL0205', -- cybran t2 aa
		'UEL0307', -- uef t2 shield
		'UEL0205', -- uef t2 aa	
		'xsl0205', -- seraphim t2 anti air

		'DAL0310', -- aeon shield disruptor
		'xal0305', -- aeon sniper bot
		'xel0306', -- uef t3 mobile missile platform
		'xsl0307', -- seraphim t3 mobile shield gen
		'xsl0305', -- seraphim t3 sniper bot

		'xrl0305', -- cybran t3 armored assault bot
		'xel0305', -- uef t3 armored assault bot
		'xrl0305', -- cybran t3 armored assault bot
		'xel0305', -- uef t3 armored assault bot
		'xel0306', -- uef t3 mobile missile platform

		'xrl0305', -- cybran t3 armored assault bot
		'xel0305', -- uef t3 armored assault bot
		'xrl0305', -- cybran t3 armored assault bot
		'xel0305', -- uef t3 armored assault bot
		'xel0306', -- uef t3 mobile missile platform
    
		--'URS0201', -- cybran salem class
		--'URS0201', -- cybran salem class

		'UAL0301', -- aeon support commander
		'URL0301', -- cybran support commander 
		'UEL0301', -- uef support commander
		'xsl0301', -- seraphim support commander
		'UAL0301', -- aeon support commander
		'URL0301', -- cybran support commander 
		'UEL0301', -- uef support commander
		'xsl0301', -- seraphim support commander

		'UAL0304', -- aeon t3 arty
		'URL0304', -- cybran t3 arty
		'UEL0304', -- uef t3 arty
		'xsl0304',	-- seraphim t3 heavy artillery
    
		'UAL0304', -- aeon t3 arty
		'URL0304', -- cybran t3 arty
		'UEL0304', -- uef t3 arty
		'xsl0304',	-- seraphim t3 heavy artillery    
	},
};

local unitTableExperimentalsCo = {
	{ -- Wave Set Special
		'URL0402', -- cybran monkeylord
		'URL0402', -- cybran monkeylord
		'URL0402', -- cybran monkeylord
		'URL0402', -- cybran monkeylord
		'UAL0401', -- aeon galactic colossus
		'UAL0401', -- aeon galactic colossus
		'UAL0401', -- aeon galactic colossus
		'xsl0401',	-- seraphim experimental assault bot
		'xsl0401',	-- seraphim experimental assault bot

		'UEL0401', -- uef fatboy
		'xrl0403',	-- cybran experimental megabot

	}	,
	
		{ -- Wave Set Special 40:00+
		'UAA0310', -- czar
		'URA0401', -- soul ripper
		'xsa0402', -- seraphim exp bomber
		'xsa0402', -- seraphim exp bomber
	},
}

local unitTableAirCoba = {
  { -- pseudo wave this is for compensating that air units are faster than land units
    -- so we want to delay the air waves a little bit
  },
	{ -- Wave Set 1
		'UAA0103',	-- aeon t1 bomber
		'UAA0102',	-- aeon interceptor
		'URA0103',	-- cybran bomber
		'URA0103',	-- cybran interceptor
		'xra0105', 	-- cybran t1 light gunship
		'UEA0103',	-- uef bomber
		'UEA0102',	-- uef interceptor
		'xsa0103',	-- seraphim bomber
		'xsa0102',	-- seraphim interceptor
	},
	{ -- Wave Set 2
		'UAA0103',	-- aeon t1 bomber
		'UAA0102',	-- aeon interceptor
		'URA0103',	-- cybran bomber
		'URA0103',	-- cybran interceptor
		'xra0105', 	-- cybran t1 light gunship
		'UEA0103',	-- uef bomber
		'UEA0102',	-- uef interceptor
		'xsa0103',	-- seraphim bomber
		'xsa0102',	-- seraphim interceptor

		'UAA0203',	-- aeon gunship
		'URA0203',	-- cybran gunship
		'UEA0203',	-- uef gunship
		'xsa0203',	-- seraphim gunship
		'DRA0202',	-- cybran corsair
		'DEA0202',	-- uef janus
		'xaa0202', 	-- aeon t2 combat fighter
		'xsa0202',	-- seraphim fighter/bomber
	},
	{ -- Wave Set 3
		'UAA0203',	-- aeon gunship
		'URA0203',	-- cybran gunship
		'UEA0203',	-- uef gunship
		'xsa0203',	-- seraphim gunship
		'DRA0202',	-- cybran corsair
		'DEA0202',	-- uef janus
		'xaa0202', 	-- aeon t2 combat fighter
		'xsa0202',	-- seraphim fighter/bomber
	},
	{ -- Wave Set 4
		'UAA0203',	-- aeon gunship
		'URA0203',	-- cybran gunship
		'UEA0203',	-- uef gunship
		'xsa0203',	-- seraphim gunship
		'DRA0202',	-- cybran corsair
		'DEA0202',	-- uef janus
		'xaa0202', 	-- aeon t2 combat fighter
		'xsa0202',	-- seraphim fighter/bomber

		'UAA0303',	-- aeon air superiority
		'URA0303',	-- cybran air superiority
		'UEA0303',	-- uef air superiority
		'xsa0303',	-- seraphim air superiority
		'UEA0305',	-- uef t3 gunship
		'xra0305', 	-- cybran T3 gunship
	},
	{ -- Wave Set 5
		'UAA0303',	-- aeon air superiority
		'UAA0303',	-- aeon air superiority
		'UAA0304',	-- aeon t3 bomber
		'xaa0305', 	-- aeon T3 AA gunship

    'URA0303',	-- cybran air superiority
		'URA0304',	-- cybran t3 bomber
		'xra0305', 	-- cybran T3 gunship

		'UEA0303',	-- uef air superiority
		'UEA0304',	-- uef t3 bomber
		'UEA0305',	-- uef t3 gunship

		'xsa0202',	-- seraphim fighter/bomber
		'xsa0303',	-- seraphim air superiority
		'xsa0304',	-- seraphim bomber
	},

};

-- times are now an offset to the first wave
local unitTableTimesCoba = {
	{ -- ground
		'0', -- 0m 1
		'180', -- 3m 
		'480', -- 8m 
		'720', -- 12m 
		'960', -- 16m 
		'1200', -- 20m 
		'1440', -- 24m 
		'1680', -- 28m 
		'1920', -- 32m 
		'2160', -- 36m 
    '2760', -- 44m 
	},
	{ -- air
		'0', -- 0m  empty wave
    '220', -- 2m 1
		'660', -- 6m 2
		'1140', -- 14m 3
		'1580', -- 23m 4
		'2200', -- 30m 5
--		'3300', -- 55 specials
	},
};

-- upgrades list for SCU's
local upgradeTable = {
	-- aeon
	A={
		'Shield',
		'ShieldHeavy',
		'StabilitySuppressant',
		'SystemIntegrityCompensator',
		},
	-- cybran
	R={
		'CloakingGenerator',
		'EMPCharge',
		'FocusConvertor',
		'NaniteMissileSystem',
		'SelfRepairSystem',
		'StealthGenerator', -- NOTE requires cloaking generator first
		},
	-- uef
	E={
		'AdvancedCoolingUpgrade',
		'HighExplosiveOrdnance',
		'RadarJammer',
		'Shield',
		'ShieldGeneratorField',
		},
	-- seraphim
	S={
		'DamageStabilization',
		'Missile',
		'Overcharge',
		'Shield',
		},
};

-- defines possible formations for the units
local formationTable = {
	'AttackFormation',
	'GrowthFormation',
	'SixWideFormation',
	'TravellingFormation',
};

setupGame = function()
	ScenarioInfo.Options.Victory = 'sandbox'; 			-- custom victory condition
	-- misc settings
	Utilities.UserConRequest("ui_ForceLifbarsOnEnemy");	--show enemy life bars


-- first I thought all the defense could be civilian and could be turned on and off 
-- but why? now the defense is every game there, better for testing
	ScenarioInfo.Options['CivilianAlliance'] = 'enemy';
-- not sure if this is special for this version
	
	-- setup army specific things
	for i, army in ListArmies() do
		if (army == "ARMY_1" or army == "ARMY_2" or army == "ARMY_3" or army == "ARMY_4") then 
			-- restrict players from building walls
      addRestricions(army);
      
			-- set alliances
			SetAlliance(army, "ARMY_SURVIVAL_ENEMY", 'Enemy'); 
			SetAlliance(army, "ARMY_SUPERWEAPON", 'Ally'); 
			SetAlliedVictory(army, true); 
			-- set alliance with all other hill players!
			for j, army2 in ListArmies() do
				if (army2 == "ARMY_1" or army2 == "ARMY_2" or army2 == "ARMY_3" or army2 == "ARMY_4") then 
					SetAlliance(army, army2, 'Ally'); 
				end
			end			
		end
	end

	
	-- spawnwaves and superweapon are enemies
	SetAlliance("ARMY_SURVIVAL_ENEMY", "ARMY_SUPERWEAPON", 'Enemy'); 
	-- spawnwaves don't have a unit cap
	SetIgnoreArmyUnitCap('ARMY_SURVIVAL_ENEMY', true);

	-- set difficulty options
	-- if (ScenarioInfo.Options.opt_difficulty == 1) then
		-- HealthBuff = 0.25;
	-- else
		-- HealthBuff = ((ScenarioInfo.Options.opt_difficulty - 1) / 2); -- so on 9 health is *4   on 5(normal) is *1
	-- end
	HealthBuff = (ScenarioInfo.Options.opt_difficulty -1)/ 4 -- so on 9 health is *2   on 5(normal) is *1
  
	--platoonsize = 5 + (ScenarioInfo.Options.opt_difficulty * 5);
	--  now that we spawn more groups we need  a lower count
  --   4,  9 , 12  , 15
  platoonsize = 10 + ScenarioInfo.Options.opt_difficulty;
  if(ScenarioInfo.Options.opt_difficulty>12) then
    platoonsize = 10 + 12;
  end
  
	-- the muliplier will be balanced by number of players which means how many plattos will be spawned at each gate ! see spawn fucntion

	-- before spawning the gates : or the health muliplier will effect muliple times
	adjustDefense(); 
	
	spawnAntinukes();
	spawnGates();
	spawnDefenseObject();


end

addRestricions = function( army )
--		ScenarioFramework.AddRestriction(army, categories.WALL);
    ScenarioFramework.AddRestriction(army, categories.STRUCTURE*categories.ARTILLERY);
    ScenarioFramework.AddRestriction(army, categories.url0401);
    ScenarioFramework.AddRestriction(army, categories.NUKE);
--    ScenarioFramework.AddRestriction(army, categories.ARTILLERY);
    ScenarioFramework.AddRestriction(army, categories.NAVAL);
    ScenarioFramework.RemoveRestriction(army, categories.TECH2*categories.ARTILLERY);
end

removeRestrictions = function() 
---   for i, army in ListArmies() do
---   if (army == "ARMY_1" or army == "ARMY_2" or army == "ARMY_3" or army == "ARMY_4") then 
---     ScenarioFramework.RemoveRestriction(army, 
---         categories.url0402 + --ML
---         categories.ual0401 + -- gc
---         categories.xrl0403 + --megalit
---         categories.xsl0401 + -- yo
---         categories.uel0401 + --fatboy
---         categories.uaa0310 + --zar
---         categories.xsa0402 + -- bomber
---         categories.ura0401  -- soulripper
---         );
--         ScenarioFramework.RemoveRestriction(army, categories.NUKE*categories.TECH3);
          ScenarioFramework.RemoveRestriction(army, categories.TECH2*categories.ARTILLERY);
--          ScenarioFramework.RemoveRestriction(army, categories.AIR)
--          ScenarioFramework.RemoveRestriction(army, categories.LAND)
--        end
--      end
end
removeRestrictions2 = function() 
--      for i, army in ListArmies() do
--        if (army == "ARMY_1" or army == "ARMY_2" or army == "ARMY_3" or army == "ARMY_4") then 
--          ScenarioFramework.RemoveRestriction(army, categories.EXPERIMENTAL)
--          ScenarioFramework.RemoveRestriction(army, categories.NUKE)
--        end
--      end
end

spawnDefenseObject = function()
	-- spawn the defense object

	if (ScenarioInfo.Options.opt_defenseObject < 5) then
		--object = "xac2101";--Aeon Temple
		
		--Black Sun 50k
		-- if (ScenarioInfo.Options.opt_defenseObject == 1 or 
        -- ScenarioInfo.Options.opt_defenseObject == 2 or
        -- ScenarioInfo.Options.opt_defenseObject == 3 ) then
		local object = "uec1901";	
		-- end

		--Aeon Temple 12k
		if (ScenarioInfo.Options.opt_defenseObject == 4) then
      -- QAI Mainframe  1k
      object = "xrc201";
		end
		local pos = ScenarioUtils.MarkerToPosition("HILL_CENTER");
		ScenarioInfo.DefenseObject =CreateUnitHPR( object, "ARMY_SUPERWEAPON", pos[1], pos[2], pos[3], 0,0,0);
		ScenarioInfo.DefenseObject:SetReclaimable(false);
		ScenarioInfo.DefenseObject:SetCapturable(false);

		--  to cheap to repair  unless we find a solution to increase econmy values
  	if (ScenarioInfo.Options.opt_defenseObject == 1) then
			ScenarioInfo.DefenseObject:SetMaxHealth( 10000 ); 
			ScenarioInfo.DefenseObject:SetHealth(nil,10000); 			
    end
  	if (ScenarioInfo.Options.opt_defenseObject == 3) then
			ScenarioInfo.DefenseObject:SetMaxHealth( 5000 ); 
			ScenarioInfo.DefenseObject:SetHealth(nil,5000); 			
    end
		
		
		--def:SetProductionPerSecondEnergy(99999); no benefits from the defense object


		-- set onkilled function
		ScenarioInfo.DefenseObject.OldOnKilled = ScenarioInfo.DefenseObject.OnKilled;
		ScenarioInfo.DefenseObject.OnKilled = function(self, instigator, type, overkillRatio)
      -- we keep this function to execute our mission code first
      -- it calls then the "old" function where the original is stored
      end
		
    -- damged percent based onto 50k
		if (ScenarioInfo.Options.opt_defenseObject == 2) then
      ScenarioFramework.CreateUnitDamagedTrigger(defenseObjectDamaged80, ScenarioInfo.DefenseObject, .2) -- 40000
		end 
		if (ScenarioInfo.Options.opt_defenseObject == 1) then
      ScenarioFramework.CreateUnitDamagedTrigger(defenseObjectDamaged12k, ScenarioInfo.DefenseObject, .86) -- 7000
		end 
	end
end


--- messages only once :(   perhaps later I will find a better solutuin
defenseObjectDamaged80 = function ()
  msgOut("Defense Object at 80%")
  ScenarioFramework.CreateUnitDamagedTrigger(defenseObjectDamaged50, ScenarioInfo.DefenseObject, .5)

end
defenseObjectDamaged50 = function ()
  msgOut("Defense Object at 50%")
  
  -- this is not possible , will end in recursive call and crahses the application
  --ScenarioFramework.CreateUnitDamagedTrigger(defenseObjectDamaged80, ScenarioInfo.DefenseObject, .2)
end

defenseObjectDamaged12k = function ()
  msgOut("Defense Object at 60%")
  ScenarioFramework.CreateUnitDamagedTrigger(defenseObjectDamaged5k, ScenarioInfo.DefenseObject, .92) -- 4000
end
defenseObjectDamaged5k = function ()
  msgOut("Defense Object at 33%")
end


spawnAntinukes = function()

	for i = 1, 4 do
		local an = "nukedefense_"..i;
		antinukes[i] = BuildArmedStrategicMissilesDefense( "xsb4302", "ARMY_SURVIVAL_ENEMY", an, 7 )	
    
   	antinukes[i].OldOnKilled = antinukes[i].OnKilled; -- keep the original kill function
		antinukes[i].myID = i;
		antinukes[i].OnKilled = antinukeHasBeenKilled;
    
	end
  local an = "nukedefense_"..Utilities.GetRandomInt(5, 6);
  BuildArmedStrategicMissilesDefense( "xsb4302", "ARMY_SURVIVAL_ENEMY", an, 7 )	
end

-- this does not work yet
adjustDefense = function() 

	local ai = GetArmyBrain("ARMY_SURVIVAL_ENEMY");


	local defenseMult = 1;	-- the defense should not vary as much as the vehicles
	if(HealthBuff>1) then
		defenseMult = 1+ (HealthBuff*0.2); -- 10 percent with each level
	elseif (HealthBuff<1) then
		defenseMult = 1- (HealthBuff*0.1);
	end

	
	local shieldMult = 1;	-- the defense should not vary as much as the vehicles
	if(HealthBuff>1) then
		-- yes they have double strength
		shieldMult = 2+ (HealthBuff*0.3); -- 30 percent with each level
	elseif (HealthBuff<1) then
		shieldMult = 2- ((5-HealthBuff)*0.3);
	end
	

	for subk, subv in ai:GetListOfUnits( categories.ALLUNITS, false ) do
		if ( subv.MyShield != nil ) then
			subv:SetMaxHealth(subv:GetHealth()  * HealthBuff*20);
			subv:SetHealth(subv, subv:GetHealth()  * HealthBuff*20);  
			subv.MyShield:SetMaxHealth(subv.MyShield:GetHealth()  * shieldMult);
			subv.MyShield:SetHealth(nil, (subv.MyShield:GetHealth() * shieldMult)); 
			subv.MyShield:SetRechargeTime(20*HealthBuff); -- because it becomes stronger with difficulty shields it should take longer to recharge
			subv.MyShield:SetShieldRegenStartTime(20) -- sera t3 default 1s	 
			--subv:SetShieldRegenRate(200* HealthBuff); -- sera  t3 default 168hp/s
			--subv:SetShieldRegenStartTime(5) -- sera t3 default 1s
			--subv:SetRechargeTime(25*HealthBuff); -- because it becomes stronger with difficulty shields it should take longer to recharge
			
		else 
			subv:SetMaxHealth(subv:GetHealth() * defenseMult ); -- so on normal the values are normal too
			subv:SetHealth(nil, subv:GetHealth() * defenseMult); 
		end
    end
end



-- it would have been easier to to an average healt  like  (a+b)/2  but then it would be twice hard to kill
--  because this way the damage would only be half
--  so we need threads to sync to the weakest of both
FinalRiftHealth = function()
    while(finalrif_a and not finalrif_a:IsDead() and finalrif_b and not finalrif_b:IsDead()) do
        local health1 = finalrif_a:GetHealth()
        local health2 = finalrif_b:GetHealth()

		local diff = health1 - health2;
		if( diff < 1000 and diff > 1000 ) then -- otherwise the regen does not work so well
			return;
		end
		
        if(health1 < health2) then
            finalrif_b:SetHealth(finalrif_b, health1)
        elseif(health2 < health1) then
            finalrif_a:SetHealth(finalrif_a, health2)
        end
        WaitSeconds(.5)
    end
end

-- we need them if only one half has been killed to kill the other half too
finalrif_a_Dead = function()
    if(finalrif_b and not finalrif_b:IsDead()) then
        finalrif_b:Kill()
    end
end

finalrif_b_Dead  = function()
    if(finalrif_a and not finalrif_a:IsDead()) then
        finalrif_a:Kill()
    end
end

spawnGates = function()
	-- spawn gates at the outer edges for enemy units to teleport in
	-- 8 gates have to be destroyed
	numGatesOpen = 4;
			
			
	-- yes we iterate 5 times because rift need 2 loops
	-- and the rift should double spawn units
	for i = 1,5 do 
		if (gates[i] == nil) then
			if( i==4 ) then
				local pos2 = ScenarioUtils.MarkerToPosition("Gate4"); -- renamed the rift to gate 5 makes it later easier 
				finalrif_a = CreateUnitHPR( "xsc1901", "ARMY_SURVIVAL_ENEMY", pos2[1], pos2[2], pos2[3], 0,-1.53,0);
				finalrif_a:SetMaxHealth(150000 * HealthBuff);
				finalrif_a:SetHealth(nil, (150000 * HealthBuff));
				finalrif_a:SetRegenRate(50* HealthBuff);
        finalrif_a.SpawnPos = ScenarioUtils.MarkerToPosition("RiftSpawn");
				gates[i]=finalrif_a;
			elseif( i==5 ) then
				local pos3 = ScenarioUtils.MarkerToPosition("Gate5");
				finalrif_b = CreateUnitHPR( "xsc1901", "ARMY_SURVIVAL_ENEMY", pos3[1], pos3[2], pos3[3], 0,1.60,0);
				finalrif_b:SetMaxHealth(150000 * HealthBuff);
				finalrif_b:SetHealth(nil, (150000 * HealthBuff));
				finalrif_b:SetRegenRate(50*HealthBuff);
        finalrif_b.SpawnPos = ScenarioUtils.MarkerToPosition("RiftSpawn");
				gates[i]=finalrif_b;

			else
				local gateName = "Gate"..i;
				local pos = ScenarioUtils.MarkerToPosition(gateName);
				local r = Utilities.GetRandomInt(1,4);
				local gateFaction;
				if (r == 1) then
					gateFaction = 'UAB0304';
				elseif (r == 2) then
					gateFaction = 'URB0304';
				elseif (r == 3) then
					gateFaction = 'UEB0304';
				else
					gateFaction = 'XSB0304';
				end
				gates[i] = CreateUnitHPR( gateFaction, "ARMY_SURVIVAL_ENEMY", pos[1], pos[2], pos[3], 0,0,0);
        gates[i].SpawnPos = pos;

-- mod here
				gates[i]:SetMaxHealth(50000 * HealthBuff);
				gates[i]:SetHealth(nil, (50000 * HealthBuff));
        if(i!=1) then
          gates[i]:SetRegenRate(50* HealthBuff);
        end
			
			end
			gates[i]:SetReclaimable(false);
			gates[i]:SetCapturable(false);
			gates[i]:SetProductionPerSecondEnergy(99999);

			-- remove gate wreckage
			local bpw = gates[i]:GetBlueprint();
			if (bpw != nil) then
				bpw.Wreckage = nil; -- bp.Wreckage.WreckageLayers.Land=false;
			end

			-- set gate onkilled function
			gates[i].OldOnKilled = gates[i].OnKilled; -- keep the original kill function
			gates[i].myID = i;
			gates[i].OnKilled = gateHasBeenKilled;
		end
	end
	
	--ForkThread(FinalRiftHealth); -- sync the rift healt
	ScenarioFramework.CreateUnitDeathTrigger(finalrif_a_Dead, finalrif_a);
	ScenarioFramework.CreateUnitDeathTrigger(finalrif_b_Dead, finalrif_b);

end

gateHasBeenKilled = function(self, instigator, type, overkillRatio) -- inline function
ForkThread( function()
  if(self==finalrif_a or self==finalrif_b) then
  	LOG("___SE___ rift half killed");
    local unit = self;
  	local scale = 2;
    local Explosion = finalrif_a #Entity(spec)

    Explosions.CreateConcussionRing( Explosion, scale )
    unit:ShakeCamera(50, 2, 0, 0.5)
    Explosions.CreateScalableUnitExplosion(unit)
    ForkThread( Explosions.CreateCompositeExplosionMeshes, Explosion )  
  end
	


	if(instigator != nil) then
		-- add points to player
		local instArmy = instigator:GetArmy();
		local armyName = ArmyIndexer(GetArmyBrain(instArmy));
		LOG("___SE___ gate killed, id="..self.myID.." instigator army: "..instArmy.."/"..armyName);
		killCount[armyName] = killCount[armyName] + 1;
    if(numGatesOpen>1) then
      msgOut("A gate was destroyed by " .. getUsername(instArmy) .. "! "..(numGatesOpen-1) .. " gates left.");
    end
	else
		-- this happens on destryoing on a rift half as expected
		-- hm figure out if deathtriggers are not neccessary
	end
	-- handle game logic
	gates[self.myID] = nil;
  
  local spos = self:GetPosition();
	
  self.OldOnKilled(self, instigator, type, overkillRatio) -- call the orignial onKill

  WaitSeconds(1)
  --spawn a nuke
  --fork
  nuke(spos);
    
	numGatesOpen = numGatesOpen - 1;  
--	if (numGatesOpen < 1) then
--		msgOut("All gates were destroyed!");
--	end

end
);
end

antinukeHasBeenKilled = function(self, instigator, type, overkillRatio) -- inline function
  antinukes[self.myID] = nil;
  LOG("____ Antinuked killed :" ..self.myID);
  self.OldOnKilled(self, instigator, type, overkillRatio) -- call the orignial onKill
end

    

spawnThread = function(self)
	LOG("___SE___ Spawn thread running!");
	-- wait before starting the unit spam
	local startupTime = ScenarioInfo.Options.opt_startupTime;
	local now = 1;

	LOG("___SEBS___ spawnThread: " .. startupTime .. now);
--	if (startupTime > 0) then
		while (now < startupTime) do
			now = GetGameTimeSeconds();
			local rest = startupTime - now;
			if (rest < 0) then rest = 0; end
			Sync.ObjectiveTimer = math.floor(rest);
			WaitSeconds(1);
		end
--	end
	Sync.ObjectiveTimer = 0;
	
	msgOut("Attack waves have spawned!");

-- the waves start at id 1
-- the while loop repeats every spawn interval to spawn a new wave

	-- set the default waves to 1
	local groundwaveid = 1;
	local airwaveid = 1;

	-- loop each wave interval to spawn a new set of waves
	while (gameEnd == false) do

		-- first figure out which wave sets to spawn
		now = GetGameTimeSeconds(); -- get the game time
		timetolerance = 5; -- tolerance because this tends to loop several seconds before the actual time, resulting in delayed wave sets

	-- check game time vs wave times to figure out which wave sets we are on

		local groundtimes = unitTableTimesCoba[1];

--		LOG("___SEBS___ groundtimes: " .. now .. "   " .. table.getn(groundtimes) .. "   " .. groundtimes[1]);

		for i = groundwaveid, table.getn(groundtimes) do -- loop through remaining ground waves
			if ((now + timetolerance ) >= tonumber(groundtimes[i])+ScenarioInfo.Options.opt_startupTime) then -- if the current time is past the time for this wave...
				groundwaveid = i; -- update the ground wave
        LOG("___SEBS___ groundwaveid: " .. groundwaveid );
			else -- if the next wave time hasn't been reached we can break the loop
				break -- break the loop 
			end
		end

		local airtimes = unitTableTimesCoba[2];

		for i = airwaveid, table.getn(airtimes) do -- loop through remaining ground waves
			if ((now + timetolerance) >= tonumber(airtimes[i])+ScenarioInfo.Options.opt_startupTime) then -- if the current time is past the time for this wave...
				airwaveid = i; -- update the ground wave
			else -- if the next wave time hasn't been reached we can break the loop
				break -- break the loop 
			end
		end

	-- now that we know which ground and air waves to spawn...

		-- spawn some waves
		spawnWaveCoba(groundwaveid, airwaveid);
    for i =1, 4 do
      if( antinukes[i]!=nil) then
        --LOG(" ___CO: antinuke " .. i -.." refilled");
        BuildTacticalMissiles( antinukes[i], 7 )
      end
    end

	-- now wait for next wave time
		
		-- wait for next wave
		local waitTime = ScenarioInfo.Options.opt_waveTime;
--		LOG("___SEBS___ waveTimes: " .. ScenarioInfo.Options.opt_waveTime .. waitTime);
		WaitSeconds(waitTime);

	end
	--no more waves to send, kill thread
	KillThread(self);
end



spawnWaveCoba = function(gwaveid, awaveid)
	
  if( numGatesOpen < 1 ) then
    return
  end
  AirCount = (platoonsize/2)+1; 
  
  -- ------------------------
  local spawnpoints = activeGates()
   for idx, gate in  spawnpoints do
    spawnwave( gate, unitTableGroundCoba[gwaveid], platoonsize-gwaveid); --less units each wave
    if(awaveid!=1) then
      spawnwave( gate, unitTableAirCoba[awaveid], AirCount);
    end
  end
  
  
  spawnwaveExperimentals(spawnpoints,gwaveid)
end

activeGates = function() 
  local gl = {}
  if(gates[1]!=nil ) then
    table.insert(gl,gates[1])
  elseif( gates[2]!=nil) then
    table.insert(gl,gates[2])
    if( gates[3]!=nil) then
      table.insert(gl,gates[3])
    end
  elseif( gates[3]!=nil) then
    table.insert(gl,gates[3])
  elseif( gates[4]!=nil and gates[5]!=nil) then
    table.insert(gl,gates[4]) -- or 5 does not matter for our purpose
  end
  
  return gl
end  


spawnwave = function(gate, spawntable, spawncount)
    local attackplan = getTopLevelAttackplan(gate.myID);
	  local plattooncount =table.getn(attackplan);
    for i = 1,plattooncount do
      local platoonUnits = spawnPlatton(gate.SpawnPos, spawntable, spawncount)
      startAttackMove(platoonUnits,gate.myID, attackplan[i]);
    end
end


spawnPlatton = function( pos, spawntable, spawncount )
  
	local spawnList = {}; -- empty spawn list
	local bpCount = table.getn(spawntable); -- how many unit types are available in this wave set

	-- pull a random entry from the available units table and add it to the spawning table
	-- repeat for as many units as we will spawn
	for c = 1, spawncount do
		local rr = Utilities.GetRandomInt(1, bpCount);
		table.insert(spawnList, spawntable[rr]);
	end

  -- create an empty array to combine spawned units to one platoon
  local platoonUnits = {};
  -- iterate through the blueprint-list we have just generated and spawn the units
  for index, bp in spawnList do
    doSpawnUnit(bp, pos, platoonUnits);
  end
  return platoonUnits
end




-- does the actual spawning of a unit
doSpawnUnit = function(bp, pos, platoon)
	--calculate offset position of unit
	local xside = math.random(0,1);
	local yside = math.random(0,1);
	local xoff = -10 + xside*16 + math.random(0,1)*4;
	local yoff = -10 + yside*16 + math.random(0,1)*4;

	-- spawn unit
	local unit = CreateUnitHPR( bp, "ARMY_SURVIVAL_ENEMY", pos[1]+2*xoff, pos[2], pos[3]+2*yoff, 0,0,0);		
	if (unit == nil) then
		return;
	end
	-- no wreckages after first round (to speed up game, can be removed when we all have quadcores/octacores ;=)
--	if (loop > 0) then
		local bp = unit:GetBlueprint();
		if (bp != nil) then
			bp.Wreckage = nil; -- bp.Wreckage.WreckageLayers.Land=false;
		end
--	end

	-- insert to platoon list
	table.insert(platoon, unit); 
	
	-- check for upgrades
	local skip = Utilities.GetRandomInt(1, 4);
	if (skip != 3) then	-- one out of four commanders has no upgrades
		if (bp == "UAL0301") then		-- aeon
			local ucnt = table.getn(upgradeTable["A"]);
			local enh = upgradeTable["A"][Utilities.GetRandomInt(1, ucnt)];
			unit:CreateEnhancement(enh);
		elseif (bp == "URL0301") then	-- cybran
			local ucnt = table.getn(upgradeTable["R"]);
			local enh = upgradeTable["R"][Utilities.GetRandomInt(1, ucnt)];
			if (enh == 'StealthGenerator') then	-- stealth needs cloaking first, bug in game
				unit:CreateEnhancement('CloakingGenerator');
			end
			unit:CreateEnhancement(enh);
		elseif (bp == "UEL0301") then	-- uef
			local ucnt = table.getn(upgradeTable["E"]);
			local enh = upgradeTable["E"][Utilities.GetRandomInt(1, ucnt)];
			unit:CreateEnhancement(enh);
		elseif (bp == "xsl0301") then	-- seraphim
			local ucnt = table.getn(upgradeTable["S"]);
			local enh = upgradeTable["S"][Utilities.GetRandomInt(1, ucnt)];
			unit:CreateEnhancement(enh);
		end
	end
	
	--apply buffs based on  difficulty
	unit:SetMaxHealth(unit:GetHealth() * HealthBuff);
	unit:SetHealth(nil, unit:GetHealth() * HealthBuff);
	--apply buffs based on  difficulty
--	local difficultyBuff = ScenarioInfo.Options.opt_difficulty;
--	unit:SetMaxHealth(unit:GetHealth()*difficultyBuff);
--	unit:SetHealth(nil, unit:GetHealth()*difficultyBuff);
end


local attackplan1 = {
  {
    {24,9}, {24,9},
    {24,8}, {24,8},
    {23,7},
    {6},
  },
  {
    {23,7},
    {6},
    {5},
    {4},
    {22,3},
  },
  {
    {4},
    {22,3},
    {21,2},{21,2},
    {21,1},{21,1},
  },
};

local attackplan2_3 ={
  {
    {22,5},{22,5},
    {22,4},{22,4},
    {3},
  },
  {
    {3},
    {21,2},{21,2},
    {21,1},{21,1},
  },
};

local attackplan2 ={
  {
    {21,1},
    {21,2},
    {3},
  },
  {
    {3},
    {22,4},
    {22,5},
  },
  {
    {23,6}, {23,6},
    {23,7}, {23,7},
    {23,8},
    {24,9},
  },
};

local attackplan3_2 ={
  {
    {24,9},{24,9},
    {24,8},{24,8},
    {7},
  },
  {
    {7},
    {23,6},{23,6},
    {23,5},{23,5},
  },
};

local attackplan3 ={
  {
    {24,9},
    {24,8},
    {7},
  },
    {7},
    {23,6},
    {23,5},
  {
  },
  {
    {22,4},{22,4},
    {22,5},{22,5},
    {22,2},
    {21,1},
  },
};

local attackplan4={
  {
    {34,9},{34,24,9},
    {24,8},
    {33,7},
  },
  {
    {34,8},
    {33,7},
    {23,6},
  },
  {
    {23,6},
    {5},
    {22,4},
  },
  {
    {22,4},
    {32,3},
    {31,2},  
  },
  {
    {32,3},
    {31,2},
    {31,1},{31,21,1},
  },
};

local xWave = 0;
spawnwaveExperimentals = function(spawnpoints, waveid) 
	if( waveid== table.getn(unitTableGroundCoba) ) then
    xWave = xWave-ScenarioInfo.Options.opt_difficulty; 
    if(xWave<0) then  
      xWave = 19;
      for player =1, playercount do
        -- local gate = spawnpoints[Utilities.GetRandomInt(1,table.getn(spawnpoints))];
        local gate = gates[Utilities.GetRandomInt(4,5)];
    		local EXPspawnList = {}; -- empty spawn list
    		local whichEXPList;
    		if( player==1 or player==3 ) then
    			whichEXPList = unitTableExperimentalsCo[1];
    		else
    			whichEXPList = unitTableExperimentalsCo[2];
    		end
    		local bpCount = table.getn(whichEXPList);
    		local rrr = Utilities.GetRandomInt(1, bpCount );
    		table.insert(EXPspawnList,whichEXPList[rrr]);

    		local experimentals = {};
    		for index, bp in EXPspawnList do
    			doSpawnUnit(bp, gate.SpawnPos, experimentals);
    		end
    		startAttackMove(experimentals,gate.myID,attackplan4[Utilities.GetRandomInt(1,table.getn(attackplan4))]);
      end
    end
	end	
end


getTopLevelAttackplan = function ( gateID ) 
  if(gateID==4 or gateID==5) then
    LOG("___:  Top plan")
    return attackplan4;
  elseif(gateID==2 ) then
    if(gates[3]==nil) then
      return attackplan2
    else
      return attackplan2_3
    end
  elseif(gateID==3 ) then
    if(gates[3]==nil) then
      return attackplan3
    else
      return attackplan3_2
    end
  else
    return attackplan1
  end
end


--forms a platoon to attack the hill with a given set of units
startAttackMove = function(units,gateID, partialAttackplan)	

	if (table.getn(units) > 0) then

		local aiBrain = GetArmyBrain("ARMY_SURVIVAL_ENEMY");
		local attackPlatoon = aiBrain:MakePlatoon('','');
		local fcnt = table.getn(formationTable);
		local formation = formationTable[Utilities.GetRandomInt(1, fcnt)];
		aiBrain:AssignUnitsToPlatoon(attackPlatoon, units, 'Attack', formation);

    local movepoints = partialAttackplan[Utilities.GetRandomInt(1, table.getn(partialAttackplan))]
    
    for idx, waypointid in movepoints do
          attackPlatoon:AggressiveMoveToLocation(ScenarioUtils.MarkerToPosition("WP".. waypointid));
    end

		-- continue
		local posCENTER = ScenarioUtils.MarkerToPosition('HILL_CENTER');
		attackPlatoon:AggressiveMoveToLocation(posCENTER);
	end
end

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- misc funcs
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

shake = function( orig )
    local markers = table.copy(orig)
    local retMarkers = {}
    local numMarkers = table.getn( markers )
    for i = 1, numMarkers do
        rand = Random(1, numMarkers + 1 - i)
        table.insert(retMarkers, markers[rand])
        table.remove(markers, rand)
    end
    return retMarkers -- double entries as input
end

function BuildArmedStrategicMissilesDefense( unitId,  forArmy, markerName, NumToBuild )
    local Strategic_Defense_1 = BuildUnitAtLocation( unitId, forArmy, markerName )
    BuildAntiNukes( Strategic_Defense_1, NumToBuild, markerName  )
				Strategic_Defense_1:SetMaxHealth(10000 * HealthBuff);
				Strategic_Defense_1:SetHealth(nil, (10000 * HealthBuff));
				Strategic_Defense_1:SetRegenRate(50); -- no multiplier !
    return Strategic_Defense_1;
end

function BuildAntiNukes( unit, markerName, NumToBuild ) 
    BuildTacticalMissiles( unit, markerName, NumToBuild )
end 

function BuildTacticalMissiles( unit, NumToBuild, markerName )
    if unit and unit != nil then
        unit:GiveTacticalSiloAmmo( NumToBuild )
        --LOG("MANIMAL:   Missiles Silo Ammo = ".. NumToBuild .." at "..markerName.."  .")
    else
        error('MANIMAL:  *ERROR* Attempting to build Missiles in a non-existent unit ')
    end

end

function BuildUnitAtLocation( unitId, forArmy, markerName )
    --[[  Spawn unitId @ markerName ]]--
    local spawnLoc = ScenarioUtils.MarkerToPosition( markerName )
    unit = CreateUnitHPR( unitId, forArmy, spawnLoc[1], spawnLoc[2], spawnLoc[3], 0, 0, 0 )
    --LOG("MANIMAL:  SPAWN  unitId = "..unitId..")  for Army = "..forArmy.."  at marker = "..markerName.."  .")
    return unit
end

-- spawn acu and kill it to create a fake nuke explosion :=) *hack hack hack, but the gpg devs said it's easiest way atm*
nuke = function(position)
	local acu = CreateUnitHPR( "ual0001", "ARMY_SURVIVAL_ENEMY", position[1], position[2], position[3], 0,0,0);
	if (acu != nil) then
		acu:Kill();
	end
end

-- kills all commanders of a specified army
killAllCommanders = function(army)
	local list = GetArmyBrain(army):GetListOfUnits(categories.COMMAND , false);
	for i, u in list do
		if (u:IsDead() == false) then
			u:Kill();
		end
	end
end


--given a player returns a proper username
getUsername = function(army)
	return GetArmyBrain(army).Nickname;
end

--given an ai brain returns an army index
function ArmyIndexer(aiBrain)
	local army = aiBrain:GetArmyIndex();
	for i, v in ListArmies() do
		if (i == army) then
			return v;
		end
	end
end

armyKills = function(brain)
	local kills = brain:GetArmyStat('Enemies_Killed',0.0).Value;
	return kills;
end

-- display mm:ss instead of seconds
secondsToTime = function(seconds)
	return string.format("%02d:%02d", math.floor(seconds/60), math.mod(seconds, 60));
end

-- display a text message
msgOut = function(text, army)
	local color = nil;
	if (army != nil) then
		local colorIndex = ScenarioInfo.ArmySetup[army].PlayerColor;
		color = import('/lua/GameColors.lua').GameColors.ArmyColors[colorIndex];
	end
	PrintText(text, 20, color, 10, 'center') ;	
end

-- this function creates all mex and hydrocarbon markers
-- resource scale script (c) Jotto, reworked by tecxx
function ScenarioUtils.CreateResources()
	-- fetch markers and iterate them
	local markers = ScenarioUtils.GetMarkers();
	for i, tblData in pairs(markers) do
		-- spawn resources?
		local doit = false;
		if (tblData.resource and not tblData.SpawnWithArmy) then
			-- standard resources, spawn it
			doit = true;
		elseif (tblData.resource and tblData.SpawnWithArmy) then
			-- resources bound to player, check if army is presend
			for j, army in ListArmies() do
				if (tblData.SpawnWithArmy == army) then
					doit = true;  -- we made sure the army is present, allow spawn
					break;
				end
			end
		end
		
		if (doit) then
			-- check type of resource and set parameters
			local bp, albedo, sx, sz, lod;
			if (tblData.type == "Mass") then
				albedo = "/env/common/splats/mass_marker.dds";
				bp = "/env/common/props/massDeposit01_prop.bp";
				sx = 2;
				sz = 2;
				lod = 100;
			else
				albedo = "/env/common/splats/hydrocarbon_marker.dds";
				bp = "/env/common/props/hydrocarbonDeposit01_prop.bp";
				sx = 6;
				sz = 6;
				lod = 200;
			end
			-- create the resource
			CreateResourceDeposit(tblData.type,	tblData.position[1], tblData.position[2], tblData.position[3], tblData.size);
			-- create the resource graphic on the map
			CreatePropHPR(bp, tblData.position[1], tblData.position[2], tblData.position[3], Random(0,360), 0, 0);
			-- create the resource icon on the map
			CreateSplat(
				tblData.position,           # Position
				0,                          # Heading (rotation)
				albedo,                     # Texture name for albedo
				sx, sz,                     # SizeX/Z
				lod,                        # LOD
				0,                          # Duration (0 == does not expire)
				-1,                         # army (-1 == not owned by any single army)
				0							# ???
			);
		end
	end
end

OpStrings = {

OPERATION_NAME = 'Operation: Survive',

EndGameTitle = 'Destroy the enemy rift',
EndGameDescription = 'Attack and destroy enemy rift. Hurry it is getting worse.',


-- BriefingData = {
  -- {phase = 0, character = '<LOC Date>Date', text = '<LOC X06_B01_000_010>10-August-3847'},
  -- {phase = 1, character = '<LOC Hall>Hall', text = '<LOC X06_B01_001_010>Somehting mystious is going on'},
  -- {phase = 1, character = '<LOC Princess>Princess', text = '<LOC X06_B01_001_030>Go and find out.'},
-- }

Mission1_old = {
  {text = 'Hmm what is this structure?  Let see what happens ...!', vid = 'X02_Celene_D01_03178.sfd', bank = 'X02_VO', cue=false, faction = 'Aeon'}
 },

 
 SecondaryMissionStart_B = {
  {text = '[{i Vendetta}]: You are not yet capable to build EXPERIMENTALS, Nukes or T3 Arty!.Blueprints are on the way, destroy the gate first', vid = 'X06_Vedetta_T01_04801.sfd', bank = 'X06_VO', cue = false, faction = 'Aeon'},
},
 SecondaryMissionEnd_B = {
  {text = '[{i Dostya}]: Blueprints of some EXPERIMENTALS and NUKES have been received. Waiting for last blueprints ....', vid = 'X04_Dostya_M01_03735.sfd', bank = 'X04_VO', cue = false, faction = 'Cybran'},
},

 SecondaryMissionEnd_B2 = {
  {text = '[{i Dostya}]: The latest blueprints have been received.', vid = 'X04_Dostya_M01_03735.sfd', bank = 'X04_VO', cue = false, faction = 'Cybran'},
},

 ShieldHint = {
  {text = 'I detect a strange kind of shield. It is much stronger but the recharge is very long and the down time is very long.', vid = 'X02_Celene_D01_03178.sfd', bank = 'X02_VO', cue=false, faction = 'Aeon'}
 },

 fun1= {
  {text = '[{i CybranComputer}]: what shall i do', vid = nil, bank = nil, cue = nil, faction = 'NONE'},
},


FinalMissionWon = {
  {text = '<LOC X06_M03_105_010>[{i Hall}]: The Arch is down! The Arch is down!', vid = 'X06_Hall_M03_04503.sfd', bank = 'X06_VO', cue = 'X06_Hall_M03_04503', faction = 'UEF'},
},


Mission1= {
  {text = '<LOC X04_M01_026_010>[{i HQ}]: Attack and destroy it. And watch out for a counter-attack. Those aliens are sneaky bastards.', vid = 'X04_HQ_M01_04877.sfd', bank = 'X04_VO', cue = 'X04_HQ_M01_04877', faction = 'NONE'},
},

MainObjective = {
  {text = 'We have to protect DEFENSE OBJECT', vid = 'X02_Celene_D01_03178.sfd', bank = 'X02_VO', cue=false, faction = 'Aeon'}
 },
  
 Gamend = {
  {text = '<LOC X1T_TU09_020_010>[{i Fletcher}]: Scratch one scumbag. I love seeing Order commanders going up like that.', vid = 'X1T_Fletcher_TU09_05077.sfd', bank = 'X1T_VO', cue = 'X1T_Fletcher_TU09_05077', faction = 'UEF'},
},
 
Mission2Title = '<LOC X06_M01_OBJ_010_010>Destroy the Forward Seraphim Position',
Mission2Description = '<LOC X06_M01_OBJ_010_010>Destroy the Forward Seraphim Position',



Mission_Setup_2 = {
  {text = '<LOC X01_M01_106_010>[{i Fletcher}]: Make yourself useful and destroy those bases.', vid = 'X01_Fletcher_M01_04817.sfd', bank = 'X01_VO', cue = 'X01_Fletcher_M01_04817', faction = 'UEF'},
},

X06_DB01_020 = {
  {text = '<LOC X06_DB01_020_010>[{i Hall}]: The Seraphim are pouring through the Rift at an alarming rate. There is no stopping them. We are doomed.', vid = 'X06_Hall_DB01_04029.sfd', bank = 'Briefings', cue = 'X06_Hall_DB01_04029', faction = 'UEF'},
},

X06_M03_030 = {
  {text = '<LOC X06_M03_030_010>[{i Brackman}]: You know what must be done, my child. Destroy the Arch.', vid = 'X06_Brackman_M03_03973.sfd', bank = 'X06_VO', cue = 'X06_Brackman_M03_03973', faction = 'Cybran'},
},
X06_M03_130 = {
  {text = '<LOC X06_M03_130_010>[{i Brackman}]: Focus your efforts on the Arch! It is all that matters!', vid = 'X06_Brackman_M03_03990.sfd', bank = 'X06_VO', cue = 'X06_Brackman_M03_03990', faction = 'Cybran'},
},


-- X1T_TU06_130 = {
  -- {text = '<LOC X1T_TU06_130_010>[{i Fletcher}]: Well, what do you know -- here come some enemy units. Good thing you built a point defense.', vid = 'X1T_Fletcher_TU06_05050.sfd', bank = 'X1T_VO', cue = 'X1T_Fletcher_TU06_05050', faction = 'UEF'},
-- }

X1T_TU06_020 = {
  {text = '<LOC X1T_TU06_020_010>[{i Fletcher}]: That a fella. Well done.', vid = 'X1T_Fletcher_TU06_05039.sfd', bank = 'X1T_VO', cue = 'X1T_Fletcher_TU06_05039', faction = 'UEF'},
},

X1T_TU03_070 = {
  {text = '<LOC X1T_TU03_070_010>[{i Fletcher}]: Destroy that unit, Commander.', vid = 'X1T_Fletcher_TU03_04998.sfd', bank = 'X1T_VO', cue = 'X1T_Fletcher_TU03_04998', faction = 'UEF'},
},

-- X1T_TU03_020 = {
  -- {text = '<LOC X1T_TU03_020_010>[{i Fletcher}]: Well done.', vid = 'X1T_Fletcher_TU03_04991.sfd', bank = 'X1T_VO', cue = 'X1T_Fletcher_TU03_04991', faction = 'UEF'},
-- }

X01_M02_035 = {
  {text = '<LOC X01_M02_035_020>[{i Hall}]: Protect those buildings, Commander!', vid = 'X01_Hall_M02_04240.sfd', bank = 'X01_VO', cue = 'X01_Hall_M02_04240', faction = 'UEF'},
  },
  
 -- E02_M02_010 = {
  -- {text = '<LOC E02_M02_010_010>[{i EarthCom}]: Sir, scans detect a large group of Aeon ground forces. They appear to be readying another attack. General Clarke has authorized you to receive the \'Air Cleaner\' Tech 2 Anti-Air Turret and the \'Triad\' Tech 2 Point Defense Turret. Upgrade any of your factories and construct a Tech 2 Engineer to build these new units. EarthCom out.', vid = 'E02_EarthCom_M02_0061.sfd', bank = 'E02_VO', cue = 'E02_EarthCom_M02_0061', faction = 'UEF'},
-- } 

X1T_TU06_090 = {
  {text = '<LOC X1T_TU06_090_010>[{i Fletcher}]: Never know when one of those damn aliens is going to show up, so always fortify your base with defensive structures. Point defenses offer decent protection and can fend off most land-based attacks. Build a point defense at the marked location.', vid = 'X1T_Fletcher_TU06_05046.sfd', bank = 'X1T_VO', cue = 'X1T_Fletcher_TU06_05046', faction = 'UEF'},
},
}
--EOF