Advertisement
Guest User

Untitled

a guest
Jul 30th, 2016
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 118.08 KB | None | 0 0
  1. -------------------------------------------------------------------------
  2. -------------------------------------------------------------------------
  3.  
  4. -- Script File for Mission 6 - CHERBOURG
  5.  
  6. -------------------------------------------------------------------------
  7. -------------------------------------------------------------------------
  8.  
  9. import("ScarUtil.scar")
  10. -- custom file for table ID's instead of the default WB generated file
  11. import("M06_Cherbourg_IDtables.scar")
  12. if Misc_IsCommandLineOptionSet("e3") then
  13. import("M06_CherbourgE3.scar")
  14. end
  15.  
  16.  
  17. function OnGameSetup()
  18. player1 = Setup_Player(1, 269005, TRACE_ALLIES, 1)
  19. player2 = Setup_Player(2, 269006, TRACE_AXIS, 2)
  20. end
  21.  
  22. function OnGameRestore()
  23. player1 = World_GetPlayerAt(1)
  24. player2 = World_GetPlayerAt(2)
  25.  
  26. -- function takes care of restoring all global mission parameters after a save/load
  27. Game_DefaultGameRestore()
  28.  
  29. end
  30.  
  31. -------------------------------------------------------------------------
  32.  
  33. -- [[ ONINIT ]]
  34.  
  35. -------------------------------------------------------------------------
  36.  
  37. function OnInit()
  38. g_MissionSpeechPath = "Mission06"
  39. Sound_PreCacheSinglePlayerSpeech( g_MissionSpeechPath )
  40. -- mute the sound before the NIS plays
  41. Util_MuteAmbientSound(true)
  42.  
  43. --[[ Set Difficulty ]]
  44. M06_Difficulty()
  45.  
  46. --[[ TECH TREE ]]
  47. TechTreeSetup()
  48.  
  49. --[[ PRESET GAME STATE ]]
  50. Game_Letterbox(true, 0)
  51. Game_FadeToBlack(true, 0)
  52.  
  53.  
  54. --[[ SET BINDINGS ]]
  55. M06_Bindings()
  56.  
  57. --[[ REGISTER OBJECTIVES ]]
  58. M06_Objective_Register()
  59.  
  60. --[[ MOD INITIAL STATS ]]
  61. M06_Set_StatMods()
  62.  
  63. --[[ SET RESTRICTIONS ]]
  64. M06_Restrictions()
  65.  
  66. --[[ SET INITIAL MOOD ]]
  67. M06_MOOD()
  68.  
  69. --[[ MISSION PRESETS ]]
  70. M06_Mission_Preset()
  71.  
  72. --[[ GAME START CHECK ]]
  73. Util_PlayMusic("Sound/Music/sp/M06/m06_ob1_takehq", 5, 20)
  74. Rule_Add(M06_Mission_Start)
  75.  
  76. -- use default veteran squads if necessary
  77. if not Player_HasPersistentSquadFile(player1) then
  78. Player_LoadPersistentSquadsFromFile(player1, "data:scenarios/sp/m06_cherbourg/default_veteran_squads.lua")
  79. end
  80.  
  81. end
  82.  
  83. Scar_AddInit(OnInit)
  84.  
  85. function M06_Difficulty()
  86.  
  87. -- get the difficulty
  88. if Game_GetSPDifficulty() ~= nil then
  89. g_dif = Game_GetSPDifficulty()
  90. end
  91.  
  92. -- set health bonus for player 1
  93. Setup_Difficulty(player1, g_dif)
  94.  
  95. -- set health handicap for player 2
  96. Setup_Difficulty(player2, g_dif)
  97.  
  98. end
  99.  
  100. function M06_Bindings()
  101.  
  102. if E3 ~= true then
  103. Scar_DebugConsoleExecute("bind([[ALT+1]], [[Scar_DoString('Util_StartNIS(EVENTS.NIS02)')]])")
  104. Scar_DebugConsoleExecute("bind([[ALT+2]], [[Scar_DoString('Util_StartNIS(EVENTS.NIS03)')]])")
  105. Scar_DebugConsoleExecute("bind([[ALT+3]], [[Scar_DoString('Util_StartNIS(EVENTS.NIS04)')]])")
  106. end
  107.  
  108. Scar_DebugConsoleExecute("bind([[ALT+I]], [[Scar_DoString('Util_InvulnerableSelection(true)')]])")
  109. Scar_DebugConsoleExecute("bind([[ALT+N]], [[Scar_DoString('Util_InvulnerableSelection(false)')]])")
  110.  
  111. Scar_DebugConsoleExecute("bind([[ALT+M]], [[Scar_DoString('Util_MergeSquads()')]])")
  112.  
  113. end
  114.  
  115.  
  116. function M06_Objective_Register()
  117.  
  118. --[[ *** MUST INITIALIZE THE OBJ TABLE BEFORE REGISTERING *** ]]
  119. Initialize_OBJ_TownSquare()
  120. Initialize_OBJ_NavalGuns()
  121. Initialize_OBJ_SecureAssets()
  122. Initialize_OBJ_AxisHQ()
  123. Initialize_OBJ_Garrison()
  124.  
  125. --[[ Registering Objectives ]]
  126. Objective_Register(OBJ_TownSquare)
  127. Objective_Register(OBJ_NavalGuns)
  128. Objective_Register(OBJ_SecureAssets)
  129. Objective_Register(OBJ_AxisHQ)
  130. Objective_Register(OBJ_Garrison)
  131.  
  132. end
  133.  
  134. function M06_Set_StatMods()
  135.  
  136. -- stops player1 from earning action points by killing enemy squads
  137. --Player_StopEarningActionPoints(player1)
  138.  
  139. -- pick an upgrade path for the player
  140.  
  141. -- initially set the allowed pop cap low
  142. -- once the player secures the HQ then increase the allowed pop cap
  143. Player_SetMaxPopulation(player1, CT_Personnel, 40)
  144. end
  145.  
  146. function M06_Restrictions()
  147.  
  148. --[[ UN/RESTRICT ABILITIES ]]
  149.  
  150. --[[ RESOURCES ]]
  151. Player_SetResource(player1, RT_Manpower, 400)
  152. Player_SetResource(player1, RT_Munition, 100)
  153. Player_SetResource(player1, RT_Fuel, 0)
  154.  
  155. Player_SetUpgradeAvailability(player1, UPG.ALLIES.CROCODILE_BULLDOZER, ITEM_REMOVED)
  156. end
  157.  
  158. function M06_MOOD()
  159. Player_SetDefaultSquadMoodMode(player1, MM_ForceTense)
  160. Player_SetDefaultSquadMoodMode(player2, MM_ForceTense)
  161. end
  162.  
  163.  
  164.  
  165.  
  166.  
  167. -------------------------------------------------------------------------
  168.  
  169. -- [[ MISSION Preset ]]
  170.  
  171. -------------------------------------------------------------------------
  172.  
  173. function M06_Mission_Preset()
  174. -- legacy from first iteration
  175. -- look to thin out what doesn't need to spawn
  176. -- for cpu saving - deg
  177. TownSquare_Init()
  178. Streets_Init()
  179. LongestDay_Init()
  180. NavalGuns_Init()
  181. Bridge_Init()
  182. SecureAssets_Init()
  183.  
  184. -- hide the NIS buildings
  185. EGroup_DeSpawn(eg_NIS06_04)
  186.  
  187. -- bridge setup
  188. EGroup_SetInvulnerable(eg_bridge, true, 0.1)
  189.  
  190. EGroup_SetPlayerOwner(eg_axishq2_1, player2)
  191. EGroup_SetPlayerOwner(eg_axishq2_2, player2)
  192. Cmd_InstantUpgrade(eg_axishq2_1, UPG.ALLIES.CONVERT_AMBIENT_BUILDING, 1)
  193. Cmd_InstantUpgrade(eg_axishq2_2, UPG.ALLIES.CONVERT_AMBIENT_BUILDING, 1)
  194.  
  195.  
  196. -- Optomization: despawn squads not in immedate combat
  197. t_bridge_reached = {false}
  198. t_port_granted = {false}
  199. t_bridge_crossed = {false}
  200. t_axishq_approach = {false}
  201.  
  202. t_respawn_squads = {
  203. {sgroup = sg_axis_retreat1, trigger = 1, target = t_bridge_reached, face = mkr_bridge_cross},
  204. {sgroup = sg_axis_retreat2, trigger = 1, target = t_bridge_reached, face = mkr_bridge_cross},
  205. {sgroup = sg_axis_retreat3, trigger = 1, target = t_bridge_reached, face = mkr_bridge_cross},
  206. {sgroup = sg_axis_retreat6, trigger = 1, target = t_bridge_crossed, face = mkr_bridge_cross},
  207. {sgroup = sg_axis_retreat7, trigger = 1, target = t_bridge_crossed, face = mkr_bridgeretreat2},
  208. {sgroup = sg_axis_retreat8, trigger = 1, target = t_bridge_reached, face = mkr_bridge_cross},
  209. {sgroup = sg_axis_retreat9, trigger = 1, target = t_bridge_crossed, face = mkr_bridge_cross},
  210. {sgroup = sg_axis_retreat10, trigger = 1, target = t_bridge_reached, face = mkr_bridge_cross},
  211. {sgroup = sg_axis_retreat11, trigger = 1, target = t_bridge_reached, face = mkr_bridge_cross},
  212. {sgroup = sg_axis_retreat12, trigger = 1, target = t_axishq_approach, face = mkr_retreat3},
  213. {sgroup = sg_axishq_stug1, trigger = 1, target = t_axishq_approach, face = mkr_retreat4},
  214. {sgroup = sg_axishq_stug2, trigger = 1, target = t_axishq_approach, face = mkr_retreat3},
  215. {sgroup = sg_port_stug1, trigger = 1, target = t_port_granted, face = mkr_port_atgun3},
  216. }
  217. -- despawn everybody
  218. for i = table.getn(t_respawn_squads), 1, -1 do
  219. local this = t_respawn_squads[i]
  220. --[[ this means a boolean refernce ]]
  221. if SGroup_IsEmpty(this.sgroup) == false then
  222.  
  223. local _Store = function (gID, idx, sID)
  224.  
  225. local blue = Squad_GetBlueprint(sID)
  226. t_respawn_squads[i].blue = blue
  227.  
  228. local pos = Squad_GetPosition(sID)
  229. t_respawn_squads[i].pos = pos
  230.  
  231. end
  232.  
  233. SGroup_ForEach(this.sgroup, _Store)
  234.  
  235. SGroup_DeSpawn(this.sgroup, true)
  236.  
  237. end
  238. end
  239. -- Manager function to respawn squads based on triggers
  240. Rule_AddInterval(Util_Optomize_ActiveSquads, 2.5)
  241. end
  242.  
  243.  
  244. function Util_Optomize_ActiveSquads()
  245. local count = table.getn(t_respawn_squads)
  246. if count == 0 then
  247. Rule_RemoveMe()
  248. else
  249.  
  250. for i = count, 1, -1 do
  251.  
  252. local this = t_respawn_squads[i]
  253.  
  254. --[[ this means a boolean refernce ]]
  255. if this.trigger == 1 then
  256. -- see if the flag table is true
  257. if this.target[1] == true then
  258. -- delete the old
  259. SGroup_DestroyAllSquads(this.sgroup)
  260. -- add the new
  261. --~ Util_CreateSquadsAtMarkerFacing(player2, this.sgroup, this.blue, this.pos, this.face, 1)
  262. Util_CreateSquads(player2, this.sgroup, this.blue, this.pos, nil, 1, nil, false, this.face)
  263. ATGun_AddGroup(this.sgroup, player1)
  264. table.remove(t_respawn_squads, i)
  265. end
  266.  
  267. --[[ sgroup underattack ]]
  268. elseif this.trigger == 2 then
  269. -- see if the target is under attack
  270. if SGroup_IsEmpty(this.target) or SGroup_IsUnderAttack(this.target, false, 10) then
  271. SGroup_ReSpawn(this.sgroup)
  272. table.remove(t_respawn_squads, i)
  273. end
  274.  
  275. --[[ egroup underattack ]]
  276. elseif this.trigger == 3 then
  277. -- see if the target is under attack
  278. if EGroup_IsEmpty(this.target) or EGroup_IsUnderAttack(this.target, false, 10) then
  279. SGroup_ReSpawn(this.sgroup)
  280. table.remove(t_respawn_squads, i)
  281. end
  282.  
  283. --[[ egroup captured by player1 ]]
  284. elseif this.trigger == 4 then
  285. -- see if the target has been captured by player1
  286. if EGroup_IsEmpty(this.target) or EGroup_IsCapturedByPlayer(this.target, player1, false) then
  287. SGroup_ReSpawn(this.sgroup)
  288. table.remove(t_respawn_squads, i)
  289. end
  290.  
  291. end
  292. end
  293. end
  294.  
  295. end
  296.  
  297.  
  298.  
  299. -------------------------------------------------------------------------
  300.  
  301. -- [[ MISSION START ]]
  302.  
  303. -------------------------------------------------------------------------
  304.  
  305. function M06_Mission_Start()
  306.  
  307. -- start opening NIS
  308. --[[ debug ]]
  309. Util_StartNIS(EVENTS.NIS02)
  310.  
  311.  
  312. -- add 'end NIS check'
  313. Rule_Add(M06_Mission_OpenNISOver)
  314.  
  315. Rule_RemoveMe()
  316. end
  317.  
  318.  
  319.  
  320. function M06_Mission_OpenNISOver()
  321.  
  322. if Event_IsAnyRunning() == false then
  323.  
  324. -- starting Resources
  325. Util_SetStartingResources(6)
  326.  
  327. -- hide the tree from the opening NIS
  328. EGroup_DeSpawn(eg_NIS06_02)
  329.  
  330. -- delay first objective
  331. Objective_Start(OBJ_TownSquare)
  332. Rule_AddOneShot(M06_DelayOBJ_ObjectiveName, 5)
  333.  
  334. -- sniper warning
  335. -- Util_StartIntel(EVENTS.TownSquare_SniperWarning)
  336.  
  337. --[[ add the starting units ]]
  338.  
  339. -- create snipers in buildings
  340. for i = 1, table.getn(eg_sniperhouse) do
  341. Util_CreateSquadsAndGarrison(player2, sg_axis_sniper[i], SBP.AXIS.SNIPER, eg_sniperhouse[i], 1)
  342. --[[ difficulty handle - range of snipers ]]
  343. Modify_WeaponRange(sg_axis_sniper[i], "hardpoint_01", 0.8)
  344. Modify_WeaponAccuracy(sg_axis_sniper[i], "hardpoint_01", 0.3)
  345. end
  346. -- create some pickups
  347. local ebps = {EBP.PICKUP.ALLIES.BAZOOKA, EBP.PICKUP.ALLIES.BAZOOKA, EBP.PICKUP.ALLIES.BAZOOKA}
  348. for i = 1, table.getn(mkr_pickup) do
  349. Util_CreateEntities(player2, eg_pickup[1], ebps[World_GetRand(1, 3)], mkr_pickup[i], 1)
  350. end
  351. -- create some resource drops
  352. local drop = {EBP.PICKUP.MUNITIONS, EBP.PICKUP.FUEL, EBP.PICKUP.MUNITIONS}
  353. for i = 1, table.getn(mkr_drop) do
  354. Util_CreateEntities(player2, eg_drop[1], drop[World_GetRand(1, 3)], mkr_drop[i], 1)
  355. end
  356.  
  357. -- End of the day stuff
  358. Rule_AddInterval(M06_UnitLoss_Failsafe, 11)
  359. Rule_AddInterval(M06_CheckPlayerFail, 5)
  360.  
  361. Rule_RemoveMe()
  362. end
  363.  
  364. end
  365.  
  366.  
  367.  
  368. function M06_CheckPlayerFail()
  369. if g_townsquare_complete ~= true then
  370.  
  371. elseif Player_HasLost(player1, CRITICAL_BUILDINGS.ALLIES) then
  372.  
  373. -- fail all objs that are not complete
  374.  
  375. -- trigger the end
  376. Rule_AddOneShot(M06_Fail_Delay, 5)
  377.  
  378. Rule_RemoveMe()
  379. end
  380. end
  381.  
  382. function M06_Fail_Delay()
  383. Game_EndSP(false, nil, true)
  384. end
  385.  
  386.  
  387.  
  388. function M06_DelayOBJ_ObjectiveName()
  389.  
  390. -- add obj
  391. -- Objective_Start(OBJ_TownSquare)
  392. -- Util_StartIntel(EVENTS.TownSquare_SniperWarning)
  393. Util_StartIntel(EVENTS.TownSquare_Start)
  394.  
  395.  
  396. end
  397.  
  398.  
  399. function M06_UnitLoss_Failsafe()
  400.  
  401. if g_townsquare_complete then
  402. Rule_RemoveMe()
  403. elseif SGroup_CountSpawned(Player_GetSquads(player1)) == 0 then
  404. -- give the player a hand
  405. Util_CreateSquadsAtMarker(player1, sg_player1_initial[1], SBP.ALLIES.RIFLEMEN, mkr_player1_start1, World_GetRand(1, 2), World_GetRand(4, 5))
  406. if Event_IsAnyRunning() == false then
  407. Camera_FocusOnPosition(Marker_GetPosition(mkr_player1_start1), true)
  408. end
  409. end
  410.  
  411. end
  412.  
  413.  
  414.  
  415.  
  416. -------------------------------------------------------------------------
  417. -- [[ Town Square ]]
  418. -------------------------------------------------------------------------
  419. -- The player must destroy all of the Nazis defending the town square
  420. -------------------------------------------------------------------------
  421. function Initialize_OBJ_TownSquare()
  422.  
  423. OBJ_TownSquare = {
  424.  
  425. SetupUI = function()
  426.  
  427. Objective_AddUIElements(OBJ_TownSquare, eg_axishq1, true, 269023, true, 1.5)
  428.  
  429. end,
  430.  
  431. OnStart = function()
  432.  
  433. g_cheatinactive = true
  434.  
  435. g_townsquare_granted = true
  436.  
  437. -- announce the goal
  438. -- Util_StartIntel(EVENTS.TownSquare_Start)
  439.  
  440. -- completion check
  441. g_ts_clearedcount = Util_DifVar({4, 3, 2}) -- dif handle
  442. Rule_AddInterval(TownSquare_Cleared, 1)
  443.  
  444. Rule_AddInterval(TownSquare_GarrisonWarning, 12)
  445.  
  446. end,
  447.  
  448. OnComplete = function()
  449.  
  450. g_townsquare_complete = true
  451.  
  452. -- award resource bonus - roughly the cost of a sherman and a motorpool
  453. Player_AddResource(player1, RT_Manpower, 700)
  454. Player_AddResource(player1, RT_Fuel, 200)
  455.  
  456. if g_cheat ~= true then
  457. -- tell the player they did good
  458. Util_StartIntel(EVENTS.TownSquare_Complete)
  459.  
  460. Rule_AddInterval(NavalGuns_Obj_GrantDelay, 10)
  461. end
  462.  
  463. -- the player has the HQ
  464. -- time to increase the allowed pop cap
  465. Player_SetMaxPopulation(player1, CT_Personnel, Util_DifVar({110, 85, 70}))
  466.  
  467. -- defend the street territories
  468. t_streetTerritory = {eg_territory4, eg_territory5, eg_territory6}
  469. Rule_AddInterval(Streets_TerritoryDefender, 5)
  470.  
  471. -- add the strike group bit
  472. t_strikerange = {1, 1}
  473. -- places to attack
  474. Rule_AddInterval(Streets_StrikeTeams, 50)
  475. Rule_AddOneShot(Streets_StrikeTeams_RampUp, 600)
  476.  
  477. -- change hq owner
  478. if EGroup_IsEmpty(eg_axishq1) == false then
  479. -- if the building took too much damage
  480. if g_axishq1_invul == true then
  481. EGroup_SetInvulnerable(eg_axishq1, false)
  482. end
  483.  
  484. EGroup_SetPlayerOwner(eg_retreat2, player1)
  485.  
  486. -- tell them to run
  487. Cmd_Ungarrison(eg_axishq1, Marker_GetPosition(mkr_navalguns2))
  488. Cmd_Move(sg_townsquaredefenders, mkr_navalguns, true)
  489.  
  490. -- hand over the hq
  491. EGroup_SetPlayerOwner(eg_axishq1, player1)
  492.  
  493. -- get rid of the previous retreat marker
  494. --EGroup_Kill(eg_initial_retreat)
  495.  
  496. -- set pop cap override
  497. Player_SetPopCapOverride(player1, 75)
  498.  
  499. Command_EntityPos(player1, eg_axishq1, CMD_RallyPoint, Marker_GetPosition(mkr_townsquare1))
  500.  
  501. end
  502.  
  503. -- add some new toys for the player
  504. Rule_AddOneShot(TownSquare_Cleared_BaseSetup, 2)
  505. -- construct thingy
  506. EGroup_InstantCaptureStrategicPoint(eg_constructability, player1)
  507. --EGroup_SetPlayerOwner(eg_constructability, player1)
  508.  
  509. g_cheat = false
  510.  
  511. Scar_Autosave(269251) -- Town Square Secure
  512.  
  513. end,
  514.  
  515. OnFail = function()
  516.  
  517. -- tell the player they failed
  518. Util_StartIntel(EVENTS.TownSquare_Fail)
  519.  
  520. end,
  521.  
  522. SitRep = {
  523. Movie = "SR_06-01",
  524. Force = true,
  525. SpeechTiming =
  526. {
  527. { 0.5, ACTOR.McKay, 260170 },
  528. { 6, ACTOR.McKay, 260190 },
  529. { 16.45, ACTOR.McKay, 260200 },
  530. },
  531. },
  532.  
  533. Title = 269020,
  534. Description = 269021,
  535. Type = OT_Primary,
  536. TitleEnd = 269028,
  537. Icon = IT_P_Attack,
  538.  
  539. -- custom Complete stuff
  540. CustomComplete = true,
  541. CustomTitle = 269032,
  542. CustomTarget = EGroup_GetPosition_EVEN_IF_EMPTY(eg_axishq1),
  543.  
  544. FOW =
  545. {
  546. { target = mkr_townsquare1, },
  547. },
  548.  
  549. }
  550.  
  551. end
  552.  
  553.  
  554.  
  555. -------------------------------------------------------------------------
  556. -- TOWN SQUARE
  557. -------------------------------------------------------------------------
  558.  
  559. function TownSquare_Init()
  560.  
  561. -- delay for permanent reinforcements
  562. g_reinf_delay1 = 250
  563. g_reinf_delay2 = 300
  564. timerID_1 = 1
  565.  
  566. -- create the axis
  567. -- create some pickups
  568. local markers = {mkr_townsquare_mtr1, mkr_townsquare_mtr2}
  569. local sgroups = {sg_townsquaremortar1, sg_townsquaremortar2}
  570. if Util_DifVar({false, true}) then
  571. for i = 1, Util_DifVar({1, 1, 2}) do
  572. Util_CreateSquadsAtMarker(player2, sgroups[i], SBP.AXIS.MORTAR, markers[i], 1)
  573. SGroup_AddGroup(sg_townsquaredefenders, sgroups[i])
  574. end
  575. else
  576. for i = 1, 2 do
  577. Util_CreateSquadsAtMarker(player2, sgroups[i], SBP.AXIS.GRENADIER, markers[i], 1)
  578. SGroup_AddGroup(sg_townsquaredefenders, sgroups[i])
  579. end
  580. end
  581.  
  582. -- the hmg troop
  583. Util_CreateSquadsAtMarker(player2, sg_townsquarehmg1, Util_DifVar({SBP.AXIS.VOLKSGRENADIER, SBP.AXIS.HEAVYMG}), mkr_townsquare_hmg, 1)
  584. SGroup_AddGroup(sg_townsquaredefenders, sg_townsquarehmg1)
  585.  
  586. -- define elements for the mortar barrages
  587. townsquare_mortars = {
  588. {zone = townsquare_mortarzone1, active = nil},
  589. {zone = townsquare_mortarzone2, active = nil},
  590. {zone = townsquare_mortarzone3, active = nil},
  591. {zone = townsquare_mortarzone4, active = nil},
  592. {zone = townsquare_mortarzone5, active = nil},
  593. {zone = townsquare_mortarzone6, active = nil},
  594. {zone = townsquare_mortarzone7, active = nil},
  595. {zone = townsquare_mortarzone8, active = nil},
  596. }
  597. townsquare_mortarorder1 = {1, 2, 3, 4, 5, 6, 7, 8}
  598. townsquare_mortarorder2 = {3, 4, 1, 2, 7, 8, 5, 6}
  599.  
  600. -- dif handle
  601. local response1 = {"inf2", "inf1", "veh1", "inf3"}
  602. local response2 = {"inf2", "inf1", "veh1", "inf3", "inf1"}
  603. local response3 = {"inf2", "inf1", "veh1", "inf3", "inf2", "inf3" }
  604. townsquare_responses = Util_DifVar({response1, response2, response3})
  605.  
  606. townsquare_prox = 30
  607.  
  608. mortars_waituntiltime1 = World_GetGameTime()
  609. mortars_waituntiltime2 = World_GetGameTime()
  610.  
  611. -- start initial checks
  612. Rule_AddInterval(TownSquare_SaveHQ, 1)
  613.  
  614. Rule_AddInterval(TownSquare_MortarsFire1, 1)
  615. Rule_AddInterval(TownSquare_MortarsFire2, 1)
  616.  
  617. -- reinforcements that come in when territories are secured
  618. Timer_Start(timerID_1, 400)
  619. Rule_AddInterval(TownSquare_BringInReinforcements1, 2)
  620. Rule_AddInterval(TownSquare_BringInReinforcements2, 2)
  621.  
  622. -- check every bit to see where the player is and fight back
  623. Rule_AddInterval(TownSquare_Response, 15)
  624.  
  625. end
  626.  
  627.  
  628.  
  629. -- tells the player to get inside a building
  630. function TownSquare_GarrisonWarning()
  631. if Event_IsAnyRunning() == false and g_warp2_street ~= true then
  632. Objective_Start(OBJ_Garrison)
  633. Rule_RemoveMe()
  634. end
  635. end
  636.  
  637.  
  638. -- bring in the Reinforcements after the player captures the first point
  639. -- this makes this more of a predictable mechanism - deg
  640. function TownSquare_BringInReinforcements1()
  641.  
  642. if g_townsquare_complete then
  643.  
  644. Rule_RemoveMe()
  645.  
  646. else
  647.  
  648. if EGroup_IsCapturedByPlayer(eg_territory[1], player1, false) or Timer_GetElapsed(timerID_1) >= g_reinf_delay1 then
  649.  
  650. if g_reinf_granted ~= true then
  651. -- used for rewards after the HQ is captured
  652. g_reinf2_granted = true
  653. t_reinf1_sbps = {SBP.ALLIES.CROCODILE, SBP.ALLIES.SHERMAN, SBP.ALLIES.ENGINEER}
  654. g_reinf_granted = true
  655. else
  656. -- used for rewards after the HQ is captured
  657. g_reinf1_granted = true
  658. t_reinf1_sbps = {SBP.ALLIES.MORTAR, SBP.ALLIES.SNIPER, SBP.ALLIES.HEAVYMG}
  659. end
  660.  
  661. Rule_AddIntervalEx(TownSquare_Reinforcements1, 4, 4)
  662. Rule_RemoveMe()
  663.  
  664. end
  665.  
  666. -- give the player a hint when they get near the territory marker
  667. if g_reinf1_warning ~= true and Prox_ArePlayersNearMarker(player1, EGroup_GetPosition_EVEN_IF_EMPTY(eg_territory[1]), false, 20) then
  668. g_reinf1_warning = true
  669. Util_StartIntel(EVENTS.CaptureTerritory1)
  670. end
  671.  
  672. end
  673.  
  674. end
  675.  
  676. function TownSquare_Reinforcements1()
  677.  
  678. for i = 1, table.getn(t_reinf1_sbps) do
  679. if SGroup_IsEmpty(sg_player1_reinf[i]) then
  680. Util_CreateSquadsAtMarkerFacing(player1, sg_player1_reinf[i], t_reinf1_sbps[i], mkr_player1_reinf1, mkr_townsquare1, 1)
  681. SGroup_AddGroup(sg_player1_reinf_1, sg_player1_reinf[i])
  682. SGroup_AddGroup(sg_player1_reinf_all, sg_player1_reinf[i])
  683. -- cheating until I figure out how much reinf I need
  684. Cmd_Move(sg_player1_reinf[i], Util_GetRandomPosition(mkr_reinf1_goto[2], 5))
  685. break
  686. end
  687. end
  688.  
  689. if SGroup_Count(sg_player1_reinf_all) == table.getn(t_reinf1_sbps) then
  690. if Rule_Exists(TownSquare_GetInBuildings) == false and g_GetInBuildings ~= true then
  691. Rule_AddInterval(TownSquare_GetInBuildings, 1)
  692. end
  693. Util_AddGenericEventCue_OnClick(39322, 39323, FocusOn_TownSquare_MortarTeam)
  694. Rule_RemoveMe()
  695. end
  696.  
  697. end
  698.  
  699. function FocusOn_TownSquare_MortarTeam()
  700. if SGroup_IsEmpty(sg_player1_reinf_1) == false then
  701. Camera_FocusOnPosition(SGroup_GetPosition_EVEN_IF_EMPTY(sg_player1_reinf_1), false)
  702. end
  703. end
  704. -- bring in the Reinforcements after the player captures the first point
  705. -- this makes this more of a predictable mechanism - deg
  706. function TownSquare_BringInReinforcements2()
  707.  
  708. if g_townsquare_complete then
  709.  
  710. Rule_RemoveMe()
  711.  
  712. else
  713.  
  714. if EGroup_IsCapturedByPlayer(eg_territory[12], player1, false) or Timer_GetElapsed(timerID_1) >= g_reinf_delay2 then
  715.  
  716. if g_reinf_granted ~= true then
  717. -- used for rewards after the HQ is captured
  718. g_reinf2_granted = true
  719. t_reinf2_sbps = {SBP.ALLIES.CROCODILE, SBP.ALLIES.SHERMAN, SBP.ALLIES.ENGINEER}
  720. g_reinf_granted = true
  721. else
  722. -- used for rewards after the HQ is captured
  723. g_reinf1_granted = true
  724. t_reinf2_sbps = {SBP.ALLIES.MORTAR, SBP.ALLIES.SNIPER, SBP.ALLIES.HEAVYMG}
  725. end
  726.  
  727. Rule_AddIntervalEx(TownSquare_Reinforcements2, 4, 4)
  728. Rule_RemoveMe()
  729.  
  730. end
  731.  
  732. -- give the player a hint when they get near the territory marker
  733. if g_reinf2_warning ~= true and Prox_ArePlayersNearMarker(player1, EGroup_GetPosition_EVEN_IF_EMPTY(eg_territory[12]), false, 20) then
  734. g_reinf2_warning = true
  735. Util_StartIntel(EVENTS.CaptureTerritory2)
  736. end
  737.  
  738. end
  739.  
  740. end
  741.  
  742. function TownSquare_Reinforcements2()
  743.  
  744. for i = 1, table.getn(t_reinf2_sbps) do
  745. if SGroup_IsEmpty(sg_player1_reinf[i+4]) then
  746. Util_CreateSquadsAtMarker(player1, sg_player1_reinf[i+4], t_reinf2_sbps[i], mkr_player1_reinf2, 1)
  747. SGroup_AddGroup(sg_player1_reinf_2, sg_player1_reinf[i+4])
  748. SGroup_AddGroup(sg_player1_reinf_all, sg_player1_reinf[i+4])
  749.  
  750. --move them to the point
  751. Cmd_Move(sg_player1_reinf[i+4], Util_GetRandomPosition(mkr_player1_reinf2_goto, 5))
  752. break
  753. end
  754. end
  755.  
  756. if SGroup_Count(sg_player1_reinf_all) == table.getn(t_reinf2_sbps) then
  757. if Rule_Exists(TownSquare_GetInBuildings) == false and g_GetInBuildings ~= true then
  758. Rule_AddInterval(TownSquare_GetInBuildings, 1)
  759. end
  760. Util_AddGenericEventCue_OnClick(39322, 39323, FocusOn_TownSquare_ShermanTeam)
  761. Rule_RemoveMe()
  762. end
  763.  
  764. end
  765.  
  766. function FocusOn_TownSquare_ShermanTeam()
  767. if SGroup_IsEmpty(sg_player1_reinf_2) == false then
  768. Camera_FocusOnPosition(SGroup_GetPosition_EVEN_IF_EMPTY(sg_player1_reinf_2), false)
  769. end
  770. end
  771.  
  772.  
  773.  
  774.  
  775.  
  776.  
  777.  
  778.  
  779.  
  780.  
  781.  
  782.  
  783.  
  784.  
  785.  
  786.  
  787. -- when the enemy spot the tank, they run into buildings
  788. function TownSquare_GetInBuildings()
  789.  
  790. if g_townsquare_complete then
  791.  
  792. Rule_RemoveMe()
  793.  
  794. elseif Prox_AreSquadsNearMarker(sg_player1_reinf_all, mkr_townsquare1, ANY) then
  795.  
  796. g_GetInBuildings = true
  797.  
  798. Cmd_Garrison(sg_townsquarehmg1, eg_axishq1)
  799. Cmd_Garrison(sg_townsquaregrenadiers, eg_axishq1)
  800.  
  801. --[[ create rocket squad ]]
  802. SGroup_Clear(sg_temp)
  803. Util_CreateSquadsAndGarrison(player2, sg_temp, SBP.AXIS.VOLKSGRENADIER, eg_axishq1, 1, true, 1)
  804. if Util_DifVar({false, false, true}) then
  805. Cmd_InstantUpgrade(sg_temp, UPG.AXIS.PANZERFAUST)
  806. end
  807.  
  808. Player_GetAllSquadsNearMarker(player1, sg_enemies, mkr_townsquare1)
  809. SGroup_AddGroup(sg_townsquaredefenders, sg_temp)
  810.  
  811. --[[ create garrison squad ]]
  812. SGroup_Clear(sg_temp)
  813. Util_CreateSquadsAtMarker(player2, sg_temp, SBP.AXIS.VOLKSGRENADIER, mkr_townsquare_spawn2, 1, 2)
  814. if Util_DifVar({false, false, false, true}) then
  815. Cmd_InstantUpgrade(sg_temp, UPG.AXIS.GREN_MG42)
  816. end
  817.  
  818. Cmd_Garrison(sg_temp, eg_axishq1)
  819. SGroup_AddGroup(sg_townsquaredefenders, sg_temp)
  820.  
  821. --[[ create ostwind ]]
  822. Util_CreateSquadsAtMarker(player2, sg_ts_ostwind, SBP.AXIS.OSTWIND, mkr_townsquare_spawn2, 1)
  823. g_ts_ostwind = true
  824. Cmd_AttackMove(sg_ts_ostwind, mkr_townsquare1)
  825. Util_StartIntel(EVENTS.Warning_OstwindInbound)
  826. Util_AddGenericEventCue_OnClick(269025, 39323, FocusOn_TownSquare_Ostwind)
  827.  
  828. Rule_RemoveMe()
  829.  
  830. end
  831.  
  832. end
  833.  
  834. -- show the ostwind
  835. function FocusOn_TownSquare_Ostwind()
  836. if SGroup_IsEmpty(sg_ts_ostwind) == false then
  837. local pos = SGroup_GetPosition_EVEN_IF_EMPTY(sg_ts_ostwind)
  838. FOW_RevealArea(pos, 30, 45)
  839. Camera_FocusOnPosition(pos, false)
  840. end
  841. end
  842.  
  843. -- when the enemy spot the tank, they run into buildings
  844. function TownSquare_SaveHQ()
  845.  
  846. if g_townsquare_complete then
  847.  
  848. Rule_RemoveMe()
  849.  
  850. elseif EGroup_GetAvgHealth(eg_axishq1) < 60 then
  851.  
  852. -- set the building invulnerable and call a flag
  853. EGroup_SetInvulnerable(eg_axishq1, true)
  854. -- the flag is used to remove the invulnerability
  855. -- when the player recieves the building
  856. g_axishq1_invul = true
  857.  
  858. Rule_RemoveMe()
  859.  
  860. end
  861.  
  862. end
  863.  
  864.  
  865. -- rules for the two mortar squads in the town square
  866. function TownSquare_MortarsFire1()
  867. if SGroup_Count(sg_townsquaremortar1) == 0 then
  868. -- mortar guys are dead, so remove the rule
  869. Rule_RemoveMe()
  870. else
  871. if World_GetGameTime() > mortars_waituntiltime1 then
  872. for n = 1, table.getn(townsquare_mortarorder1) do
  873. -- skip this one if team 2 are attacking it already
  874. if townsquare_mortars[townsquare_mortarorder1[n]].active ~= 2 then
  875. townsquare_mortars[townsquare_mortarorder1[n]].active = nil
  876. -- check to see if we should trigger this zone
  877. if Prox_ArePlayerMembersNearMarker(player1, townsquare_mortars[townsquare_mortarorder1[n]].zone, ANY) then
  878. -- fire mortars at this location, and don't check for another 30 seconds
  879. Cmd_Ability(sg_townsquaremortar1, ABILITY.AXIS.MORTAR_BARRAGE, Util_GetRandomPosition(townsquare_mortars[townsquare_mortarorder1[n]].zone), nil, true)
  880. mortars_waituntiltime1 = World_GetGameTime() + 30
  881. townsquare_mortars[townsquare_mortarorder1[n]].active = 1
  882. break
  883. end
  884. end
  885. end
  886. end
  887. end
  888. end
  889. function TownSquare_MortarsFire2()
  890. if SGroup_Count(sg_townsquaremortar2) == 0 then
  891. -- mortar guys are dead, so remove the rule
  892. Rule_RemoveMe()
  893. else
  894. if World_GetGameTime() > mortars_waituntiltime2 then
  895. for n = 1, table.getn(townsquare_mortarorder2) do
  896. -- skip this one if team 1 are attacking it already
  897. if townsquare_mortars[townsquare_mortarorder2[n]].active ~= 1 then
  898. townsquare_mortars[townsquare_mortarorder2[n]].active = nil
  899. -- check to see if we should trigger this zone
  900. if Prox_ArePlayerMembersNearMarker(player1, townsquare_mortars[townsquare_mortarorder2[n]].zone, ANY) then
  901. -- fire mortars at this location, and don't check for another 30 seconds
  902. Cmd_Ability(sg_townsquaremortar2, ABILITY.AXIS.MORTAR_BARRAGE, Util_GetRandomPosition(townsquare_mortars[townsquare_mortarorder2[n]].zone), nil, true)
  903. mortars_waituntiltime2 = World_GetGameTime() + 30
  904. townsquare_mortars[townsquare_mortarorder1[n]].active = 2
  905. break
  906. end
  907. end
  908. end
  909. end
  910. end
  911. end
  912.  
  913.  
  914.  
  915. -- trigger various responses and the player moves into the town square area
  916. function TownSquare_Response()
  917.  
  918. if g_townsquare_complete then
  919.  
  920. Rule_RemoveMe()
  921.  
  922. else
  923. -- check the zones of the town square
  924. -- farthest to nearest - allows the player to draw the defenses further from the center
  925. local goto = nil
  926. for i = table.getn(mkr_townsquare), 1, -1 do
  927. if Prox_ArePlayerMembersNearMarker(player1, mkr_townsquare[i], ANY, townsquare_prox) then
  928. goto = mkr_townsquare[i]
  929. break
  930. end
  931. end
  932.  
  933. -- if the player has entered one of the zones then
  934. if goto ~= nil then
  935. if SGroup_IsEmpty(sg_ts_response) or SGroup_Count(sg_ts_response) < 3 then
  936. local rand = World_GetRand(1, table.getn(townsquare_responses))
  937. local value = townsquare_responses[rand]
  938.  
  939. if value == "inf1" then
  940.  
  941. Util_CreateSquadsAtMarker(player2, sg_ts_response, SBP.AXIS.VOLKSGRENADIER, mkr_townsquare_spawn1, 1, 4)
  942.  
  943. elseif value == "inf2" then
  944.  
  945. Util_CreateSquadsAtMarker(player2, sg_ts_response, SBP.AXIS.GRENADIER, mkr_townsquare_spawn2, 1, 3)
  946.  
  947. elseif value == "inf3" then
  948.  
  949. sg_flame = SGroup_CreateIfNotFound("sg_flame")
  950. Util_CreateSquadsAtMarker(player2, sg_flame, SBP.AXIS.PIONEER, mkr_townsquare_spawn1, 1)
  951. Cmd_InstantUpgrade(sg_flame, UPG.AXIS.FLAMETHROWER)
  952. SGroup_AddGroup(sg_ts_response, sg_flame)
  953.  
  954. elseif value == "veh1" then
  955.  
  956. Util_CreateSquadsAtMarker(player2, sg_ts_ostwind, SBP.AXIS.MOTORCYCLE, mkr_townsquare_spawn2, 1)
  957. SGroup_AddGroup(sg_ts_response, sg_ts_ostwind)
  958.  
  959. end
  960.  
  961. Cmd_AttackMove(sg_ts_response, Marker_GetPosition(goto), nil, nil, 20)
  962. Cmd_AttackMove(sg_ts_response, Marker_GetPosition(mkr_basespawn2), true, nil, 30)
  963.  
  964. SGroup_AddGroup(sg_townsquaredefenders, sg_ts_response)
  965.  
  966. table.remove(townsquare_responses, rand)
  967.  
  968. if table.getn(townsquare_responses) == 0 then
  969. Rule_RemoveMe()
  970. end
  971. end
  972.  
  973. end
  974.  
  975. end
  976.  
  977. end
  978.  
  979. -- check the territory in the center of the town
  980. -- if the player captures it before the obj is complete
  981. -- they get the HQ
  982. function TownSquare_Captured()
  983.  
  984. if g_townsquare_complete then
  985.  
  986. Rule_RemoveMe()
  987.  
  988. elseif EGroup_IsCapturedByPlayer(eg_territory[8], player1, false) then
  989. -- tell the lot to attack
  990. if SGroup_IsEmpty(sg_townsquaredefenders) == false then
  991. Cmd_AttackMoveThenCapture(sg_townsquaredefenders, eg_territory[8], true)
  992. end
  993. -- change hq owner
  994. if EGroup_IsEmpty(eg_axishq1) == false then
  995. EGroup_SetPlayerOwner(eg_axishq1, player1)
  996. end
  997. Rule_RemoveMe()
  998. end
  999.  
  1000. end
  1001.  
  1002. -- check for the town centre being cleared
  1003. function TownSquare_Cleared()
  1004.  
  1005. if g_townsquare_complete then
  1006.  
  1007. Rule_RemoveMe()
  1008.  
  1009. elseif ( SGroup_Count(sg_townsquaredefenders) <= g_ts_clearedcount and SGroup_IsEmpty(sg_ts_ostwind) )
  1010. or ( SGroup_Count(sg_townsquaredefenders) <= g_ts_clearedcount+2 and g_ts_ostwind and SGroup_IsEmpty(sg_ts_ostwind) ) then
  1011.  
  1012. Rule_RemoveMe()
  1013. if EGroup_IsEmpty(eg_axishq1) == false then
  1014. Cmd_Ungarrison(eg_axishq1, Marker_GetPosition(mkr_navalguns2))
  1015. end
  1016.  
  1017. Objective_Complete(OBJ_TownSquare, true)
  1018.  
  1019. end
  1020.  
  1021. end
  1022.  
  1023.  
  1024. -- Post Action - After the Obj has been completed
  1025. function TownSquare_Cleared_BaseSetup()
  1026. --PLAYMUSIC cue
  1027. Util_PlayMusic("Sound/Music/sp/m06/M06_Ob2a_PostTownSqBattle", 5,0)
  1028.  
  1029. -- tell them to run AGAIN!
  1030. Cmd_Ungarrison(eg_axishq1, Marker_GetPosition(mkr_navalguns2))
  1031. Cmd_Move(sg_townsquaredefenders, mkr_navalguns, true)
  1032.  
  1033. -- clear out the tank traps
  1034. EGroup_Kill(eg_townsquare_cleartraps)
  1035.  
  1036. -- Add Resources
  1037. Player_AddResource(player1, RT_Munition, 400)
  1038. Player_AddResource(player1, RT_Fuel, 200)
  1039.  
  1040. if g_reinf1_granted ~= true and E3 ~= true then
  1041. Util_CreateSquadsAtMarker(player1, sg_player1_reinf[8], SBP.ALLIES.MORTAR, mkr_player1_reinf1, 1)
  1042. Util_AddGenericEventCue_OnClick(39322, 39323, FocusOn_TownSquare_Mortars)
  1043. Cmd_Move(sg_player1_reinf[8], mkr_townsquare1)
  1044. end
  1045. if g_reinf2_granted ~= true and E3 ~= true then
  1046. Util_CreateSquadsAtMarker(player1, sg_player1_reinf[9], SBP.ALLIES.SHERMAN, mkr_player1_reinf1, 1)
  1047. Util_AddGenericEventCue_OnClick(39322, 39323, FocusOn_TownSquare_Sherman)
  1048. Cmd_Move(sg_player1_reinf[9], mkr_townsquare1)
  1049. end
  1050.  
  1051.  
  1052. end
  1053.  
  1054. function FocusOn_TownSquare_Sherman()
  1055. if SGroup_IsEmpty(sg_player1_reinf[9]) == false then
  1056. Camera_FocusOnPosition(SGroup_GetPosition_EVEN_IF_EMPTY(sg_player1_reinf[9]), false)
  1057. end
  1058. end
  1059.  
  1060.  
  1061. function FocusOn_TownSquare_Mortars()
  1062. if SGroup_IsEmpty(sg_player1_reinf[8]) == false then
  1063. Camera_FocusOnPosition(SGroup_GetPosition_EVEN_IF_EMPTY(sg_player1_reinf[8]), false)
  1064. end
  1065. end
  1066.  
  1067.  
  1068.  
  1069.  
  1070.  
  1071.  
  1072.  
  1073.  
  1074.  
  1075.  
  1076.  
  1077.  
  1078.  
  1079.  
  1080. -------------------------------------------------------------------------
  1081.  
  1082. -- GARRISON
  1083.  
  1084. -------------------------------------------------------------------------
  1085. -- suggest to the player to garrison a building
  1086. -------------------------------------------------------------------------
  1087. function Initialize_OBJ_Garrison()
  1088.  
  1089. OBJ_Garrison = {
  1090.  
  1091. SetupUI = function()
  1092.  
  1093. --Objective_AddUIElements(OBJ_TownSquare, eg_suggestgarrison, true, 269142, true)
  1094. -- hint point
  1095. hint_garrisonID = HintPoint_Add( eg_suggestgarrison, 30, 269142 )
  1096.  
  1097. end,
  1098.  
  1099. OnStart = function()
  1100.  
  1101. -- announce the goal
  1102. Util_StartIntel(EVENTS.TownSquare_GarrisonWarning)
  1103.  
  1104. -- track the escalation
  1105. Rule_AddInterval(Garrison_CheckAmbientUse, 4)
  1106.  
  1107. end,
  1108.  
  1109. OnComplete = function()
  1110.  
  1111. -- award command point
  1112. -- Player_AddUnspentCommandPoints(player1, 1)
  1113.  
  1114. -- remove hint point
  1115. HintPoint_Remove(hint_garrisonID)
  1116.  
  1117. end,
  1118.  
  1119. OnFail = function()
  1120.  
  1121.  
  1122. end,
  1123.  
  1124. Title = 269140,
  1125. Description = 269141,
  1126. Type = OT_Secondary,
  1127. TitleEnd = 269143,
  1128. Icon = IT_S_Default,
  1129.  
  1130. }
  1131.  
  1132. end
  1133.  
  1134.  
  1135. -------------------------------------------------------------------------
  1136.  
  1137. -- GARRISON - Function
  1138.  
  1139. -------------------------------------------------------------------------
  1140.  
  1141.  
  1142. function Garrison_CheckAmbientUse()
  1143.  
  1144. if EGroup_HasUpgrade(Player_GetEntities(player1), UPG.ALLIES.CONVERT_AMBIENT_BUILDING, ANY) then
  1145.  
  1146. Objective_Complete(OBJ_Garrison)
  1147.  
  1148. Rule_RemoveMe()
  1149.  
  1150. else
  1151.  
  1152. -- something
  1153.  
  1154. end
  1155.  
  1156. end
  1157.  
  1158.  
  1159.  
  1160.  
  1161.  
  1162.  
  1163.  
  1164.  
  1165.  
  1166.  
  1167.  
  1168.  
  1169.  
  1170.  
  1171.  
  1172. -------------------------------------------------------------------------
  1173.  
  1174. -- STREETS
  1175.  
  1176. -------------------------------------------------------------------------
  1177.  
  1178. function Streets_Init()
  1179.  
  1180. -- create hmg's in buildings
  1181. for i = 1, 6 do
  1182. Util_CreateSquadsAndGarrison(player2, sg_axis_hmg[i], SBP.AXIS.HEAVYMG, eg_hmghouse[i], 1)
  1183. SGroup_AddGroup(sg_street_all, sg_axis_hmg[i])
  1184. end
  1185.  
  1186. -- special clauses for 'living battlefield'
  1187. -- custom case action for when key buildings collapse
  1188. if EGroup_IsEmpty(eg_hmghouse4) == false then
  1189. g_hmgpos4 = EGroup_GetPosition_EVEN_IF_EMPTY(eg_hmghouse4)
  1190. Rule_AddInterval(RetreatWhen_HMGBuilding4_Dies, 5)
  1191. end
  1192. if EGroup_IsEmpty(eg_hmghouse5) == false then
  1193. g_hmgpos5 = EGroup_GetPosition_EVEN_IF_EMPTY(eg_hmghouse5)
  1194. Rule_AddInterval(RetreatWhen_HMGBuilding5_Dies, 5)
  1195. end
  1196.  
  1197.  
  1198. -- define the squads that will populate the streets
  1199. t_street_retreat = {
  1200. sgroup = {
  1201. sg_street_retreat[1],
  1202. sg_street_retreat[2],
  1203. sg_street_retreat[3],
  1204. sg_street_retreat[4],
  1205. sg_street_retreat[5],
  1206. sg_street_retreat[6]},
  1207. marker = {
  1208. mkr_street_retreatA1,
  1209. mkr_street_retreatB1,
  1210. mkr_street_retreatC1,
  1211. mkr_street_retreatD1,
  1212. mkr_street_retreatE1,
  1213. mkr_street_retreatF1},
  1214. retreat = {
  1215. {mkr_street_retreatA2, mkr_street_retreatA3},
  1216. {mkr_street_retreatB2, mkr_street_retreatB3},
  1217. {mkr_street_retreatC2, mkr_street_retreatC3},
  1218. {mkr_street_retreatD2, mkr_street_retreatD3},
  1219. {mkr_street_retreatE2, mkr_street_retreatE3},
  1220. {mkr_street_retreatF2, mkr_street_retreatF3},},
  1221. justfellback = {false, false, false, false, false, false},
  1222. spawncount = {0, 0, 0, 0, 0, 0},
  1223. totalcount = Util_DifVar({1, 2, 3, 4}),
  1224. }
  1225. -- add the squads that will populate the streets
  1226. Rule_AddInterval(Streets_Retreaters_Create, 5)
  1227.  
  1228. -- reduce the stats of the stug in the town centre
  1229. Modify_WeaponRange(sg_townstug1, "hardpoint_01", 0.4)
  1230. Modify_UnitSpeed(sg_townstug1, 0.4)
  1231.  
  1232. -- list of automatically controlled territories
  1233. street_territories = {eg_flag_1, eg_flag_2, eg_flag_3, eg_flag_4, eg_flag_5, eg_flag_6, eg_flag_7, eg_flag_8, eg_flag_9, eg_flag_10, eg_flag_11, eg_flag_12, eg_flag_13, eg_flag_14, eg_flag_15, eg_flag_16}
  1234.  
  1235. -- list of trigger zones for the stug
  1236. street_stugdests = {stugtrigger1, stugtrigger2, stugtrigger3, stugtrigger4}
  1237. street_currentstugdest = nil
  1238.  
  1239. -- list of trigger zones for the wandering gun
  1240. street_wanderinggundests = {wanderinggundest1, wanderinggundest2, wanderinggundest3, wanderinggundest4}
  1241. street_currentwanderinggundest = nil
  1242. swid_wanderinggun1 = SyncWeapon_GetFromSGroup(sg_wanderinggun1)
  1243.  
  1244. g_stugpos = Marker_GetPosition(mkr_navalguns)
  1245. Rule_AddInterval(Streets_ManageStug1, 2)
  1246.  
  1247. Rule_AddInterval(Streets_ManageWanderingGun, 2)
  1248. --Rule_AddInterval(Streets_ManageTerritories, 2)
  1249.  
  1250. -- add a thing to create some stuff to attack the player at the midline
  1251. Rule_AddIntervalEx(Streets_Defender_Create, 4, 5)
  1252.  
  1253. end
  1254.  
  1255.  
  1256. -- create some groups to retreat/defend the streets
  1257. function Streets_Retreaters_Create()
  1258. if EGroup_IsEmpty(eg_navalgun_barracks) then
  1259.  
  1260. Rule_RemoveMe()
  1261.  
  1262. else
  1263.  
  1264. -- storing locally for brevity sake :)
  1265. local t = t_street_retreat
  1266.  
  1267. for i = 1, table.getn(t.marker) do
  1268. if SGroup_IsEmpty(t.sgroup[i]) then
  1269. -- create and go on to their marker
  1270. pos = Util_OffCameraPos(player1, mkr_navalguns2, t.marker[i])
  1271. Util_CreateSquadsAtMarker(player2, t.sgroup[i], SBP.AXIS.VOLKSGRENADIER, mkr_navalguns2, 1)
  1272. Util_GrantRandomUpgrade(t.sgroup[i])
  1273. Cmd_AttackMove(t.sgroup[i], t.marker[i])
  1274. SGroup_AddGroup(sg_street_all, t.sgroup[i])
  1275. SGroup_AddGroup(sg_street_retreat_all, t.sgroup[i])
  1276. t.spawncount[i] = t.spawncount[i]+1
  1277. break
  1278. end
  1279. end
  1280. -- to prevent a player blitz forcing early retreating
  1281. -- this function will loop until all the squads are out at once
  1282. if SGroup_Count(sg_street_retreat_all) == table.getn(t.marker) then
  1283. -- add the tracker
  1284. Rule_AddInterval(Streets_Retreaters_Track, 5)
  1285. Rule_RemoveMe()
  1286. end
  1287. end
  1288. end
  1289.  
  1290.  
  1291. function Streets_Retreaters_Track()
  1292. if EGroup_IsEmpty(eg_navalgun_barracks) or g_navalguns_reached then
  1293.  
  1294. Rule_RemoveMe()
  1295.  
  1296. else
  1297.  
  1298. -- storing locally for brevity sake :)
  1299. local t = t_street_retreat
  1300.  
  1301. for i = 1, table.getn(t.marker) do
  1302. -- if the group isn't empty
  1303. if SGroup_IsEmpty(t.sgroup[i]) == false then
  1304. -- have they yet to fall back? are they under strength?
  1305. if t.justfellback[i] == false and SGroup_TotalMembersCount(t.sgroup[i]) < 4 then
  1306.  
  1307. -- set the next retreat to be the new marker
  1308. if table.getn(t.retreat[i]) > 0 then
  1309. t.marker[i] = t.retreat[i][1]
  1310. table.remove(t.retreat[i], 1)
  1311. -- retreat to the next marker
  1312. Cmd_Move(t.sgroup[i], t.marker[i])
  1313.  
  1314. -- if there is no next retreat marker, jump inside a building
  1315. else
  1316. --Cmd_Retreat(t.sgroup[i]) - wasn't working? - deg
  1317. Cmd_AttackMove(t.sgroup[i], t.marker[i])
  1318. end
  1319.  
  1320. -- the fall back flag, once a squad 'falls back'
  1321. -- they do not fall back again until they are replaced
  1322. -- by a fresh squad (see below)
  1323. t.justfellback[i] = true
  1324.  
  1325. end
  1326.  
  1327. elseif t.spawncount[i] <= t.totalcount then
  1328. -- create and go on to their marker
  1329. Util_CreateSquadsAtMarker(player2, t.sgroup[i], SBP.AXIS.VOLKSGRENADIER, mkr_navalguns2, 1)
  1330. Util_GrantRandomUpgrade(t.sgroup[i])
  1331. Cmd_AttackMove(t.sgroup[i], t.marker[i])
  1332. SGroup_AddGroup(sg_street_retreat_all, t.sgroup[i])
  1333. SGroup_AddGroup(sg_street_all, t.sgroup[i])
  1334. -- reset the fall back flag
  1335. -- the new squad is allowed to fall back again
  1336. t.justfellback[i] = false
  1337. t.spawncount[i] = t.spawncount[i]+1
  1338. break
  1339. end
  1340. end
  1341. end
  1342. end
  1343.  
  1344.  
  1345.  
  1346.  
  1347.  
  1348.  
  1349.  
  1350.  
  1351.  
  1352.  
  1353.  
  1354.  
  1355.  
  1356.  
  1357.  
  1358.  
  1359.  
  1360.  
  1361.  
  1362. -- create some defenders
  1363. -- uses the same groups from the Naval Guns defenders
  1364. -- this is for unit count sake
  1365. -- I didn't see a problem with these guys running back to
  1366. -- the Naval Guns when *that* version of this function gets called - deg
  1367. function Streets_Defender_Create()
  1368. -- if the player hasn't reached the Naval guns
  1369. if g_navalguns_reached then
  1370.  
  1371. Rule_RemoveMe()
  1372.  
  1373. else
  1374. -- this function plays 5 times then removes
  1375. -- the breaks keep too many guys from spawning at once
  1376. local path = {"pth_street1", "pth_street2", "pth_street3", "pth_street4"}
  1377. local marker = {mkr_navalguns_def2, mkr_navalguns_def1, mkr_navalguns_def2, mkr_navalguns_def1}
  1378. local playersquads = Player_GetSquadCount(player2)
  1379. for i = 1, table.getn(marker) do
  1380. if SGroup_IsEmpty(sg_navalgun_defender[i]) and playersquads < 10 then
  1381. -- create and go on the path
  1382. Util_CreateSquadsAtMarker(player2, sg_navalgun_defender[i], SBP.AXIS.GRENADIER, mkr_navalguns, 1)
  1383. Cmd_SquadPath(sg_navalgun_defender[i], path[i], true, false, true, 5)
  1384. SGroup_AddGroup(sg_navalgun_defender_all, sg_navalgun_defender[i])
  1385. SGroup_AddGroup(sg_street_all, sg_navalgun_defender[i])
  1386. break
  1387. end
  1388. end
  1389. end
  1390. end
  1391.  
  1392.  
  1393.  
  1394.  
  1395.  
  1396.  
  1397. -- special function for HMG House 4 collapsing
  1398. function RetreatWhen_HMGBuilding4_Dies()
  1399. if EGroup_IsEmpty(eg_hmghouse4) then
  1400. Player_GetAllSquadsNearMarker(player2, sg_hmgretreat, g_hmgpos4, 30)
  1401. if SGroup_IsEmpty(sg_hmgretreat) == false then
  1402. -- they retreat
  1403. Util_StartIntel(EVENTS.Warning_GermansRetreat1)
  1404. Cmd_Move(sg_hmgretreat, mkr_street_retreatA3)
  1405.  
  1406. Rule_AddInterval(RetreatWhen_ReturnToTerritory14, 15)
  1407. end
  1408.  
  1409. Rule_RemoveMe()
  1410. end
  1411. end
  1412. -- return to recapture the point
  1413. function RetreatWhen_ReturnToTerritory14()
  1414.  
  1415. if g_navalguns_reached then
  1416.  
  1417. Rule_RemoveMe()
  1418.  
  1419. elseif EGroup_IsCapturedByPlayer(eg_territory14, player1, false) then
  1420.  
  1421. -- give it one go to recapture
  1422. -- more is annoying - deg
  1423. if SGroup_IsEmpty(sg_hmgretreat) == false then
  1424. Cmd_AttackMoveThenCapture(sg_hmgretreat, eg_territory14, true)
  1425.  
  1426. Rule_RemoveMe()
  1427. end
  1428. end
  1429.  
  1430. end
  1431.  
  1432. -- special function for HMG House 5 collapsing
  1433. function RetreatWhen_HMGBuilding5_Dies()
  1434. if EGroup_IsEmpty(eg_hmghouse5) then
  1435. Player_GetAllSquadsNearMarker(player2, sg_hmgretreat, g_hmgpos5, 30)
  1436. if SGroup_IsEmpty(sg_hmgretreat) == false then
  1437. -- they retreat
  1438. Util_StartIntel(EVENTS.Warning_GermansRetreat2)
  1439. Cmd_Move(sg_hmgretreat, mkr_street_retreatB3)
  1440.  
  1441. Rule_AddInterval(RetreatWhen_ReturnToTerritory4, 15)
  1442. end
  1443.  
  1444. Rule_RemoveMe()
  1445. end
  1446. end
  1447. -- return to recapture the point
  1448. function RetreatWhen_ReturnToTerritory4()
  1449.  
  1450. if g_navalguns_reached then
  1451.  
  1452. Rule_RemoveMe()
  1453.  
  1454. elseif EGroup_IsCapturedByPlayer(eg_territory4, player1, false) then
  1455.  
  1456. -- give it one go to recapture
  1457. -- more is annoying - deg
  1458. if SGroup_IsEmpty(sg_hmgretreat) == false then
  1459. Cmd_AttackMoveThenCapture(sg_hmgretreat, eg_territory4, true)
  1460.  
  1461. Rule_RemoveMe()
  1462. end
  1463. end
  1464.  
  1465. end
  1466.  
  1467.  
  1468.  
  1469.  
  1470.  
  1471.  
  1472.  
  1473.  
  1474.  
  1475.  
  1476.  
  1477.  
  1478. -- have the Stug prowl the town, when the player hits certain trigger points
  1479. function Streets_ManageStug1()
  1480.  
  1481. if SGroup_IsEmpty(sg_townstug1) then
  1482.  
  1483. if SGroup_IsEmpty(sg_navalgun_defender_all) == false then
  1484. Cmd_Move(sg_navalgun_defender_all, mkr_navalgun_AT1)
  1485. end
  1486. Player_GetAllSquadsNearMarker(player2, sg_stugretreat, g_stugpos, 30)
  1487. if SGroup_IsEmpty(sg_stugretreat) == false then
  1488. Cmd_Move(sg_stugretreat, mkr_navalgun_AT3)
  1489. end
  1490. Rule_AddInterval(Streets_ManageStug2, 120)
  1491. Rule_RemoveMe()
  1492.  
  1493. -- check to see if the stug is idle and not under attack
  1494. else
  1495.  
  1496. g_stugpos = SGroup_GetPosition_EVEN_IF_EMPTY(sg_townstug1)
  1497.  
  1498. if SGroup_IsMoving(sg_townstug1, false) == false and SGroup_IsUnderAttack(sg_townstug1, false, 2) == false then
  1499.  
  1500. for n = table.getn(street_stugdests), 1, -1 do
  1501.  
  1502. if Prox_ArePlayersNearMarker(player1, street_stugdests[n], ANY) then
  1503.  
  1504. street_currentstugdest = street_stugdests[n]
  1505. Cmd_AttackMove(sg_townstug1, street_stugdests[n])
  1506.  
  1507. -- music trigger
  1508. if g_streetmusic ~= true then
  1509. g_streetmusic = true
  1510. Rule_AddOneShot(Streets_StuggAttackMusic, 0)
  1511. end
  1512.  
  1513. break
  1514.  
  1515. end
  1516.  
  1517. end
  1518. end
  1519. end
  1520.  
  1521. end
  1522.  
  1523. -- music to play when the player enters the 'main street' area
  1524. function Streets_StuggAttackMusic()
  1525. -- trigger music here
  1526. Util_PlayMusic("Sound/Music/sp/m06/M06_Ob2b_City_Fight", 5, 5)
  1527. end
  1528.  
  1529. -- get another stugg when the first one dies
  1530. function Streets_ManageStug2()
  1531.  
  1532. -- positions to attack
  1533. local pos = {mkr_street_retreatA1, mkr_street_retreatA3, mkr_street_retreatC1, mkr_street_retreatF1}
  1534. local rand = World_GetRand(1, table.getn(pos))
  1535.  
  1536. -- remove the rule if the motor pool has been secured.
  1537. if g_motorpool_complete then
  1538. Rule_RemoveMe()
  1539. elseif SGroup_IsEmpty(sg_townstug1) then
  1540.  
  1541. -- has the player had no action in the last 90 seconds?
  1542. if SGroup_IsUnderAttack(Player_GetSquads(player1), false, 90) == false
  1543. and SGroup_IsEmpty(sg_stug[1]) == false then
  1544.  
  1545. SGroup_AddGroup(sg_townstug1, sg_stug[1])
  1546. SGroup_Clear(sg_stug[1])
  1547.  
  1548. Cmd_AttackMove(sg_townstug1, pos[rand])
  1549.  
  1550. end
  1551.  
  1552. else
  1553.  
  1554. Cmd_AttackMove(sg_townstug1, pos[rand])
  1555.  
  1556. end
  1557.  
  1558. end
  1559.  
  1560.  
  1561.  
  1562. -- have the Pak38 prowl the town, when the player hits certain other trigger points
  1563. function Streets_ManageWanderingGun()
  1564.  
  1565. if g_navalguns_reached then
  1566. Rule_RemoveMe()
  1567. else
  1568. if SGroup_IsEmpty(sg_wanderinggun1) then
  1569.  
  1570. Rule_RemoveMe()
  1571.  
  1572. else
  1573. for n = table.getn(street_wanderinggundests), 1, -1 do
  1574. if Prox_ArePlayersNearMarker(player1, street_wanderinggundests[n], ANY) then
  1575.  
  1576. Cmd_Move(sg_wanderinggun1, street_wanderinggundests[n])
  1577. Rule_AddInterval(Streets_WanderingGun_Stop, 1)
  1578.  
  1579. Rule_RemoveMe()
  1580. break
  1581. end
  1582. end
  1583. end
  1584. end
  1585.  
  1586. end
  1587.  
  1588. -- stop the gun so it can fire
  1589. function Streets_WanderingGun_Stop()
  1590. if g_navalguns_reached then
  1591. Rule_RemoveMe()
  1592. else
  1593.  
  1594. if SGroup_IsEmpty(sg_wanderinggun1) then
  1595.  
  1596. Rule_RemoveMe()
  1597.  
  1598. else
  1599. if SGroup_IsUnderAttack(sg_wanderinggun1, false, 10) then
  1600. Cmd_Stop(sg_wanderinggun1)
  1601. Rule_RemoveMe()
  1602. end
  1603. end
  1604. end
  1605. end
  1606.  
  1607.  
  1608.  
  1609.  
  1610. -- manage the behind-the-scenes capturing of street territories
  1611. -- 1-off territory response
  1612. -- can be elaborated - deg
  1613. function Streets_TerritoryDefender()
  1614.  
  1615. -- remove if the player reaches the Naval guns
  1616. -- so too many squads aren't being manufacted
  1617. if EGroup_IsEmpty(eg_navalgun_barracks) or g_navalguns_reached or table.getn(t_streetTerritory) == 0 then
  1618.  
  1619. Rule_RemoveMe()
  1620.  
  1621. else
  1622.  
  1623. for i = table.getn(t_streetTerritory), 1, -1 do
  1624. if EGroup_IsCapturedByPlayer(t_streetTerritory[i], player1, false) and g_navalguns_reached == false then
  1625. Util_CreateSquadsAtMarker(player2, sg_street_defender[i], SBP.AXIS.VOLKSGRENADIER, mkr_navalguns2, Util_DifVar({1, 1, 2}))
  1626. SGroup_AddGroup(sg_street_all, sg_street_defender[i])
  1627. SGroup_AddGroup(sg_street_defender_all, sg_street_defender[i])
  1628. Cmd_AttackMoveThenCapture(t_streetTerritory[i], t_streetTerritory[i])
  1629. table.remove(t_streetTerritory, i)
  1630. break
  1631. end
  1632. end
  1633.  
  1634. end
  1635.  
  1636. end
  1637.  
  1638.  
  1639. -- strike teams to aggress the player
  1640. function Streets_StrikeTeams()
  1641.  
  1642. -- get the spawn point
  1643. local spawn = mkr_axishq2_spawn3
  1644. if g_navalguns_doordead ~= true then
  1645. spawn = mkr_navalguns
  1646. end
  1647. -- is the strike group empty
  1648. if SGroup_IsEmpty(sg_street_strike) then
  1649. -- has the player had no fighting in the last minute?
  1650. if SGroup_IsUnderAttack(Player_GetSquads(player1), false, 60) == false
  1651. -- is the player clear of the spawn points?
  1652. and Prox_ArePlayersNearMarker(player1, spawn, false, 60) == false then
  1653.  
  1654. for i = 1, World_GetRand(t_strikerange[1], t_strikerange[2]) do
  1655. Util_CreateSquadsAtMarker(player2, sg_street_strike, Util_RandomInfSBP(), spawn, 1)
  1656. SGroup_AddGroup(sg_street_all, sg_street_strike)
  1657. Util_GrantRandomUpgrade(sg_street_strike)
  1658. print("strike team strike!")
  1659. end
  1660. -- on the first counter attack only!
  1661. if g_strikefirst ~= true then
  1662. g_strikefirst = true
  1663. Util_CreateSquadsAtMarker(player2, sg_street_strike, SBP.AXIS.PUMA, spawn, 1)
  1664. end
  1665.  
  1666. Cmd_AttackMove(sg_street_strike, EGroup_GetPosition_EVEN_IF_EMPTY(eg_axishq1), nil, nil, 30)
  1667.  
  1668. end
  1669.  
  1670. else
  1671. Cmd_AttackMove(sg_street_strike, EGroup_GetPosition_EVEN_IF_EMPTY(eg_axishq1), nil, nil, 30)
  1672. end
  1673.  
  1674.  
  1675. end
  1676.  
  1677. function Streets_StrikeTeams_RampUp()
  1678. t_strikerange = {2, 3}
  1679. end
  1680.  
  1681.  
  1682.  
  1683.  
  1684.  
  1685.  
  1686.  
  1687.  
  1688.  
  1689.  
  1690.  
  1691. -------------------------------------------------------------------------
  1692.  
  1693. -- LONGEST DAY - functions
  1694.  
  1695. -------------------------------------------------------------------------
  1696. function LongestDay_Init()
  1697.  
  1698. -- set the initial artillery type
  1699. g_longestday_artillery = ABILITY.SP.MORTARSTRIKE
  1700. --Cmd_Ability(player1, ABILITY.SP.MORTARSTRIKE, Misc_GetMouseOnTerrain())
  1701. --g_longestday_artillery = ABILITY.SP_ARTILLERY_M01_SINGLE
  1702. -- used for 'Escalation'
  1703. g_longestday_active = 0
  1704.  
  1705. -- create the first stugg
  1706. Util_CreateSquadsAtMarker(player2, sg_stug[1], SBP.AXIS.STUG, mkr_lowerdock1, 1)
  1707. SGroup_AddGroup(sg_axis_tank_all, sg_stug[1])
  1708.  
  1709. -- create the gunner
  1710. Util_CreateSquadsAtMarker(player2, sg_longest_gunner, SBP.AXIS.VOLKSGRENADIER, mkr_longestday1, 1)
  1711. Cmd_InstantUpgrade(sg_longest_gunner, UPG.AXIS.GREN_MG42)
  1712.  
  1713. -- create the spotter
  1714. Util_CreateSquadsAtMarker(player2, sg_longest_spotter, SBP.AXIS.OFFICER, mkr_bridgeretreat1, 1)
  1715.  
  1716. -- modify some units
  1717. Modify_WeaponRange(sg_stug[1], "hardpoint_01", 1.5)
  1718. -- Modify_SightRadius(sg_stug[1], 1.7)
  1719.  
  1720. Rule_AddInterval(LongestDay_Start, 2)
  1721.  
  1722. end
  1723.  
  1724. -- the madness is triggered when the player enters the area
  1725. function LongestDay_Start()
  1726.  
  1727. if g_bridge_reached or g_navalguns_reached then
  1728.  
  1729. Rule_RemoveMe()
  1730.  
  1731. else
  1732.  
  1733. if SGroup_IsEmpty(sg_longest_gunner) or SGroup_IsUnderAttack(sg_longest_gunner, false, 5) or Prox_ArePlayersNearMarker(player1, longestday_zone, ANY) then
  1734.  
  1735. Rule_AddInterval(LongestDay_HmgRetreats, 5)
  1736.  
  1737. Rule_RemoveMe()
  1738.  
  1739. end
  1740. -- recreate the spotter if dead
  1741. if SGroup_IsEmpty(sg_longest_spotter) then
  1742. Util_CreateSquadsAtMarker(player2, sg_longest_spotter, SBP.AXIS.OFFICER, mkr_bridgeretreat1, 1)
  1743. end
  1744.  
  1745. end
  1746.  
  1747. end
  1748.  
  1749.  
  1750. function LongestDay_HmgRetreats()
  1751.  
  1752. if g_bridge_reached or g_navalguns_reached then
  1753.  
  1754. Rule_RemoveMe()
  1755.  
  1756. else
  1757.  
  1758. if SGroup_IsEmpty(sg_longest_gunner) or SGroup_IsUnderAttack(sg_longest_gunner, false, 10) then
  1759. -- retreat the coward
  1760. Cmd_Move(sg_longest_gunner, mkr_longestday2)
  1761.  
  1762. -- start the action checks
  1763. LongestDay_KickOff()
  1764.  
  1765. Rule_RemoveMe()
  1766. end
  1767. -- recreate the spotter if dead
  1768. if SGroup_IsEmpty(sg_longest_spotter) then
  1769. Util_CreateSquadsAtMarker(player2, sg_longest_spotter, SBP.AXIS.OFFICER, mkr_bridgeretreat1, 1)
  1770. end
  1771.  
  1772. end
  1773.  
  1774. end
  1775.  
  1776. -- all the starting action
  1777. -- this was all in OnStart
  1778. -- but it moved here so we could bomb the player
  1779. -- before granting the obj
  1780. function LongestDay_KickOff()
  1781.  
  1782. -- start the action
  1783. t_LD = {
  1784. targets = {mkr_longestday1, mkr_longestday2, mkr_longestday3},
  1785. active = {false, false, false},
  1786. fire = {20, 20, 20},
  1787. freq = {5, 2, 7},
  1788. }
  1789. -- track the locations to fire on - slow rate
  1790. Rule_AddInterval(LongestDay_Track, 10)
  1791. -- command the firing - fast rate
  1792. Rule_AddInterval(LongestDay_Bomb, 1)
  1793.  
  1794. t_LDtanks = {
  1795. target = {mkr_lowerdock1, mkr_lowerdock2, mkr_lowerdock3, mkr_lowerdock4},
  1796. active = {true, false, false, false},
  1797. }
  1798. -- track the locations to spawn tanks - slow rate
  1799. Rule_AddInterval(LongestDay_TankTrack, 10)
  1800.  
  1801. -- the spotter
  1802. if SGroup_IsEmpty(sg_longest_spotter) then
  1803. Util_CreateSquadsAtMarker(player2, sg_longest_spotter, SBP.AXIS.OFFICER, mkr_bridgeretreat1, 1)
  1804. end
  1805. Cmd_Move(sg_longest_spotter, mkr_street_retreatA3)
  1806. -- track the spotter
  1807. Rule_AddInterval(LongestDay_SpotterDead, 5)
  1808.  
  1809. -- track the escalation
  1810. Rule_AddInterval(LongestDay_Escalate, 1)
  1811.  
  1812. end
  1813.  
  1814. function LongestDay_Escalate()
  1815.  
  1816. if g_longestday_active > 10 then
  1817. g_longestday_artillery = ABILITY.SP.MORTARSTRIKE_OFFMAP
  1818. Rule_RemoveMe()
  1819. elseif g_longestday_spotterdead then
  1820. Rule_RemoveMe()
  1821. end
  1822.  
  1823. end
  1824.  
  1825. function LongestDay_SpotterDead()
  1826.  
  1827. if SGroup_IsEmpty(sg_longest_spotter) then
  1828.  
  1829. g_bridge_reached = true
  1830.  
  1831. -- tell the player they did good
  1832. Util_StartIntel(EVENTS.LongestDay_Complete)
  1833.  
  1834. -- spotter dead flag
  1835. g_longestday_spotterdead = true
  1836.  
  1837. Rule_RemoveMe()
  1838.  
  1839. elseif g_navalguns_reached or g_bridge_reached or EGroup_IsCapturedByPlayer(eg_territory[2], player1, false) then
  1840.  
  1841. Cmd_Garrison(sg_longest_spotter, eg_bunkerbridge1, true, false)
  1842.  
  1843. eg_temp = EGroup_CreateIfNotFound("eg_temp")
  1844. Rule_AddInterval(LongestDay_SpotterRun, 2)
  1845.  
  1846. Rule_RemoveMe()
  1847. end
  1848.  
  1849. end
  1850.  
  1851. function LongestDay_SpotterRun()
  1852. if SGroup_IsEmpty(sg_longest_spotter) then
  1853.  
  1854. g_bridge_reached = true
  1855.  
  1856. -- tell the player they did good
  1857. Util_StartIntel(EVENTS.LongestDay_Complete)
  1858.  
  1859. -- spotter dead flag
  1860. g_longestday_spotterdead = true
  1861.  
  1862. Rule_RemoveMe()
  1863.  
  1864. elseif SGroup_GetGarrisonedBuildingEntity(sg_longest_spotter) ~= 0 then
  1865.  
  1866. -- remove hint point
  1867. HintPoint_Remove(hint_spotterID)
  1868. -- kill the sgroup
  1869. SGroup_Clear(sg_longest_spotter)
  1870.  
  1871. Rule_RemoveMe()
  1872. end
  1873.  
  1874. Cmd_Garrison(sg_longest_spotter, eg_bunkerbridge1, true, false)
  1875.  
  1876. end
  1877.  
  1878. -- track the tanks shooting at the player
  1879. function LongestDay_TankTrack()
  1880. for i = 1, 4 do
  1881. if t_LDtanks.active[i] == true and SGroup_IsEmpty(sg_stug[i]) and Prox_ArePlayersNearMarker(player1, mkr_lowerdock_spawn, false, 40) == false then
  1882. Util_CreateSquadsAtMarker(player2, sg_stug[i], SBP.AXIS.STUG, mkr_lowerdock_spawn, 1)
  1883. SGroup_AddGroup(sg_axis_tank_all, sg_stug[i])
  1884.  
  1885. -- modify some units
  1886. Modify_WeaponRange(sg_stug[i], "hardpoint_01", 1.5)
  1887. --Modify_SightRadius(sg_stug[i], 1.5)
  1888. Cmd_Move(sg_stug[i], t_LDtanks.target[i])
  1889. break
  1890. end
  1891. end
  1892.  
  1893. -- the remove condition
  1894. if EGroup_IsCapturedByPlayer(eg_territory[2], player1, false)
  1895. or EGroup_IsCapturedByPlayer(eg_territory[3], player1, false)
  1896. or (g_navalguns_reached or g_bridge_reached or g_longestday_spotterdead) then
  1897. Rule_RemoveMe()
  1898. end
  1899.  
  1900. end
  1901.  
  1902.  
  1903.  
  1904. -- bomb the bejeezuz out of the dock area
  1905. -- bombing intensifies as the player nears the center of the area
  1906. -- intensity is controlled by the 'freq' field found in LongestDay_Bomb()
  1907. function LongestDay_Track()
  1908. -- iterate through the targets and activate the ones with the player in it
  1909. for i = 1, table.getn(t_LD.targets) do
  1910. if Prox_ArePlayersNearMarker(player1, t_LD.targets[i], false, 20) then
  1911. t_LD.active[i] = true
  1912. t_LDtanks.active[i+1] = t_LD.active[i]
  1913.  
  1914. -- increment for 'Escalation'
  1915. g_longestday_active = g_longestday_active+1
  1916. else
  1917. t_LD.active[i] = false
  1918. end
  1919. end
  1920. -- the remove condition
  1921. if EGroup_IsCapturedByPlayer(eg_territory[2], player1, false)
  1922. or (g_navalguns_reached or g_bridge_reached or g_longestday_spotterdead) then
  1923. Rule_RemoveMe()
  1924. end
  1925. end
  1926.  
  1927.  
  1928. function LongestDay_Bomb()
  1929. -- iterate through the targets
  1930. -- if active, and the freq allows call in an attack
  1931. for i = 1, table.getn(t_LD.targets) do
  1932. if t_LD.active[i] == true and t_LD.fire[i] >= World_GetRand(t_LD.freq[i]-1, t_LD.freq[i]+1) then
  1933. local pos = Util_GetRandOffset(t_LD.targets[i], 20)
  1934.  
  1935. Cmd_Ability(player1, g_longestday_artillery, Util_GetRandomPosition(t_LD.targets[i], 20))
  1936. --Cmd_Ability(player1, ABILITY.SP_ARTILLERY_M01_SINGLE, Misc_GetMouseOnTerrain()) - debug
  1937.  
  1938. t_LD.fire[i] = 0
  1939.  
  1940. -- intel warning
  1941. if g_longestday_1stFire ~= true then
  1942.  
  1943. Util_StartIntel(EVENTS.LongestDay_Incoming)
  1944. g_longestday_1stFire = true
  1945.  
  1946. -- grant the medal op
  1947. Rule_AddInterval(LongestDay_GrantDelay, 5)
  1948.  
  1949. end
  1950. end
  1951. t_LD.fire[i] = t_LD.fire[i]+1
  1952. end
  1953.  
  1954. -- the remove condition
  1955. if EGroup_IsCapturedByPlayer(eg_territory[2], player1, false)
  1956. or (g_navalguns_reached or g_bridge_reached or g_longestday_spotterdead) then
  1957.  
  1958. Rule_RemoveMe()
  1959.  
  1960. end
  1961. end
  1962.  
  1963. function LongestDay_GrantDelay()
  1964. if Event_IsAnyRunning() == false then
  1965. -- hint point
  1966. hint_spotterID = HintPoint_Add( sg_longest_spotter, 30, 269122 )
  1967.  
  1968. -- announce the goal
  1969. Util_StartIntel(EVENTS.LongestDay_Start)
  1970. -- fow
  1971. local pos = Marker_GetPosition(mkr_street_retreatA3)
  1972. FOW_RevealArea(pos, 20, 120)
  1973.  
  1974. Rule_RemoveMe()
  1975. end
  1976. end
  1977.  
  1978.  
  1979.  
  1980.  
  1981.  
  1982.  
  1983.  
  1984.  
  1985.  
  1986.  
  1987.  
  1988.  
  1989.  
  1990.  
  1991.  
  1992.  
  1993. -------------------------------------------------------------------------
  1994. -- [[ NAVAL GUNS ]]
  1995. -------------------------------------------------------------------------
  1996. -- The player must destroy the Naval Guns before the bridge
  1997. -- to the axis hq can be crossed. The Naval Guns are keeping
  1998. -- the off map artillery at bay. Once the Naval Guns are destroyed
  1999. -- the bridge will be 'cleared' for the player and progress
  2000. -- can be made towards the HQ
  2001. -------------------------------------------------------------------------
  2002. function Initialize_OBJ_NavalGuns()
  2003.  
  2004. OBJ_NavalGuns = {
  2005.  
  2006. SetupUI = function()
  2007.  
  2008. Objective_AddUIElements(OBJ_NavalGuns, mkr_navalguns_objarrow, true, 269042, true)
  2009. -- hint point
  2010. hint_doorID = HintPoint_Add( eg_navalgun_door, 50, 269052 )
  2011.  
  2012. end,
  2013.  
  2014. OnStart = function()
  2015.  
  2016. -- announce the goal
  2017. Util_StartIntel(EVENTS.NavalGuns_Start)
  2018.  
  2019. -- add the detect function
  2020. Rule_AddInterval( NavalGuns_Door_DestroyedCheck, 3)
  2021.  
  2022. end,
  2023.  
  2024. OnComplete = function()
  2025.  
  2026. -- award command point
  2027. -- Player_AddUnspentCommandPoints(player1, 1)
  2028.  
  2029. -- only if the player hasn't completed the final obj
  2030. if g_axishq_complete ~= true then
  2031. -- tell the player they did good
  2032. Util_StartIntel(EVENTS.NavalGuns_Complete)
  2033.  
  2034. Rule_Add(NavalGuns_TriggerNIS)
  2035.  
  2036. Rule_AddInterval(NavalGuns_GrantOffMapArt_Delay, 5)
  2037. end
  2038.  
  2039. g_cheat = false
  2040.  
  2041. -- After the Portgun gets destroyed
  2042. Scar_Autosave(269252) -- Coastal Guns Destroyed
  2043.  
  2044. end,
  2045.  
  2046. OnFail = function()
  2047.  
  2048. -- tell the player they failed
  2049. --Util_StartIntel(EVENTS.NavalGuns_Fail)
  2050.  
  2051. end,
  2052.  
  2053. Title = 269040,
  2054. Description = 269041,
  2055. Type = OT_Primary,
  2056. TitleEnd = 269051,
  2057. Icon = IT_P_Attack,
  2058.  
  2059. FOW =
  2060. {
  2061. { target = mkr_navalguns, },
  2062. },
  2063.  
  2064. }
  2065.  
  2066. end
  2067.  
  2068.  
  2069. -------------------------------------------------------------------------
  2070.  
  2071. -- NAVAL GUNS - Functions
  2072.  
  2073. -------------------------------------------------------------------------
  2074.  
  2075. function NavalGuns_Init()
  2076.  
  2077. EGroup_SetInvulnerable(eg_navalguns, true)
  2078. EGroup_SetInvulnerable(eg_navalguns_bunker, true)
  2079.  
  2080. -- track the pak 38
  2081. Rule_AddInterval(NavalGuns_Pak_EventCue, 2)
  2082.  
  2083. end
  2084.  
  2085. function NavalGuns_Obj_GrantDelay()
  2086.  
  2087. if Event_IsAnyRunning() == false and Objective_IsStarted(OBJ_NavalGuns) == false then
  2088.  
  2089. Util_PlayMusic("Sound/Music/sp/m06/M06_Ob2a_PostTownSqBattle", 5, 5)
  2090.  
  2091. Objective_Start(OBJ_NavalGuns)
  2092.  
  2093. Rule_AddInterval( NavalGuns_Area_Check, 5)
  2094.  
  2095. Rule_RemoveMe()
  2096. end
  2097.  
  2098. end
  2099.  
  2100. function NavalGuns_Pak_EventCue()
  2101. if SGroup_IsEmpty(sg_navalgun_pak) then
  2102. Rule_RemoveMe()
  2103. elseif SGroup_IsDoingAttack(sg_navalgun_pak, false, 10) then
  2104. -- show where the bastard is
  2105. Util_AddGenericEventCue_OnClick(39322, 39323, FocusOn_NavalGun_Pak38)
  2106. Rule_RemoveMe()
  2107. end
  2108.  
  2109. end
  2110.  
  2111. function FocusOn_NavalGun_Pak38()
  2112. if SGroup_IsEmpty(sg_navalgun_pak) == false then
  2113. local pos = SGroup_GetPosition_EVEN_IF_EMPTY(sg_navalgun_pak)
  2114. FOW_RevealArea(pos, 15, 60)
  2115. Camera_FocusOnPosition(pos, false)
  2116. end
  2117. end
  2118.  
  2119. -- delay the ability grant until after the nis
  2120. function NavalGuns_GrantOffMapArt_Delay()
  2121.  
  2122. if Event_IsAnyRunning() == false then
  2123. --[[ unlock offmap artillery ]]
  2124. -- Player_SetAbilityAvailability(player1, ABILITY.COMMANDER_TREE.ALLIES.HOWITZER_SHOOT, ITEM_UNLOCKED)
  2125. Cmd_InstantUpgrade(player1, UPG.COMMANDER_TREE.ALLIES.INFANTRY_11)
  2126. --Modify_AbilityRechargeTime(player1, ABILITY.COMMANDER_TREE.ALLIES.HOWITZER_SHOOT, 4)
  2127.  
  2128. Rule_AddOneShot(NavalGuns_OffMapArt_Flash, .5)
  2129. Rule_AddOneShot(NavalGuns_OffMapArt_StopFlash, 60)
  2130.  
  2131. Rule_RemoveMe()
  2132. end
  2133.  
  2134. end
  2135.  
  2136. function NavalGuns_OffMapArt_Flash()
  2137. ui_offmapartID = UI_FlashAbilityButton(ABILITY.COMMANDER_TREE.ALLIES.HOWITZER_SHOOT, true, 1)
  2138. end
  2139.  
  2140. function NavalGuns_OffMapArt_StopFlash()
  2141. UI_StopFlashing(ui_offmapartID)
  2142. end
  2143.  
  2144. -- triggers a shift across the mission
  2145. -- the Naval Gun defenders dig in instead of pushing out
  2146. -- the Bridge defenders shift
  2147. function NavalGuns_Area_Check()
  2148.  
  2149. if g_navalguns_complete then
  2150.  
  2151. Rule_RemoveMe()
  2152.  
  2153. elseif Prox_ArePlayersNearMarker(player1, mkr_navalguns, false, 80) then
  2154.  
  2155.  
  2156. -- set the group to the owner
  2157. EGroup_SetPlayerOwner(eg_navalgun_door, player2) --[[ debug ]]
  2158.  
  2159. -- create some defenders
  2160. if Rule_Exists(NavalGuns_Defender_Create) == false then
  2161. Rule_AddIntervalEx(NavalGuns_Defender_Create, 4, 5)
  2162. end
  2163. Rule_AddInterval(NavalGuns_Defender_Track, 90)
  2164.  
  2165. -- add a check for the next intel event
  2166. Rule_AddInterval(NavalGuns_Area_Check2, 10)
  2167.  
  2168. Rule_RemoveMe()
  2169. end
  2170.  
  2171. end
  2172.  
  2173. -- triggers an intel event explaining how to achieve the obj
  2174. function NavalGuns_Area_Check2()
  2175.  
  2176. if g_navalguns_complete then
  2177.  
  2178. Rule_RemoveMe()
  2179.  
  2180. elseif Prox_ArePlayersNearMarker(player1, mkr_navalguns, false, 40) then
  2181.  
  2182. -- sound for approaching the guns
  2183. Util_PlayMusic("Sound/Music/sp/m06/M06_Ob2c_Firing_on_Portgun", 15, 5)
  2184.  
  2185. -- used for 'Longest Day'
  2186. g_navalguns_reached = true
  2187.  
  2188. if Rule_Exists(NavalGuns_Defender_Create) == false then
  2189. Rule_AddIntervalEx(NavalGuns_Defender_Create, Util_DifVar({17, 12, 8}), 3)
  2190. end
  2191.  
  2192. -- message indicating the next step
  2193. Util_StartIntel(EVENTS.NavalGuns_Target1)
  2194.  
  2195. Rule_RemoveMe()
  2196. end
  2197.  
  2198. end
  2199.  
  2200. -- create some defenders
  2201. function NavalGuns_Defender_Create()
  2202.  
  2203. if g_navalguns_complete then
  2204.  
  2205. Rule_RemoveMe()
  2206.  
  2207. else
  2208. local marker = {wanderinggundest2, wanderinggundest3}
  2209. for i = 1, 2 do
  2210. if ( EGroup_IsEmpty(eg_navalgun_barracks) and g_dif == GD_EASY ) or g_dif ~= GD_EASY then
  2211. -- from the Naval Gun Bunker
  2212. if SGroup_IsEmpty(sg_navalgun_defender[i]) and EGroup_IsEmpty(eg_navalgun_door) == false then
  2213. Util_CreateSquadsAtMarker(player2, sg_navalgun_defender[i], SBP.AXIS.GRENADIER, mkr_navalguns, 1)
  2214. Cmd_AttackMove(sg_navalgun_defender[i], Marker_GetPosition(marker[i]), nil, nil, 20)
  2215. SGroup_AddGroup(sg_navalgun_defender_all, sg_navalgun_defender[i])
  2216. break
  2217. else
  2218. Cmd_AttackMove(sg_navalgun_defender[i], Marker_GetPosition(marker[i]), nil, nil, 20)
  2219. break
  2220. end
  2221. end
  2222. -- from the Naval Gun Barracks
  2223. if SGroup_IsEmpty(sg_navalgun_defender[i]) and EGroup_IsEmpty(eg_navalgun_barracks) == false then
  2224. Util_CreateSquadsAtMarker(player2, sg_navalgun_defender[i], SBP.AXIS.GRENADIER, mkr_navalguns2, 1)
  2225. Cmd_AttackMove(sg_navalgun_defender[i], Marker_GetPosition(marker[i]), nil, nil, 20)
  2226. SGroup_AddGroup(sg_navalgun_defender_all, sg_navalgun_defender[i])
  2227. break
  2228. else
  2229. Cmd_AttackMove(sg_navalgun_defender[i], Marker_GetPosition(marker[i]), nil, nil, 20)
  2230. break
  2231. end
  2232. end
  2233. end
  2234.  
  2235. end
  2236.  
  2237. -- tracks the state of the Naval guns area and creates some more defenders
  2238. -- if the player hasn't secured the area
  2239. function NavalGuns_Defender_Track()
  2240.  
  2241. if g_navalguns_complete ~= true and EGroup_IsCapturedByPlayer(eg_territory7, player1, false) == false
  2242. and Prox_ArePlayersNearMarker(player1, mkr_navalguns, false, 60) then
  2243. -- create some more defenders
  2244. if Rule_Exists(NavalGuns_Defender_Create) == false then
  2245. Rule_AddIntervalEx(NavalGuns_Defender_Create, Util_DifVar({17, 12, 8}), 5)
  2246. end
  2247.  
  2248. elseif g_navalguns_complete == false or EGroup_IsCapturedByPlayer(eg_territory7, player1, false) then
  2249. Rule_RemoveMe()
  2250. end
  2251.  
  2252. end
  2253.  
  2254.  
  2255. -- report when the 'door' is destroyed
  2256. function NavalGuns_Door_DestroyedCheck()
  2257.  
  2258. if g_navalguns_complete then
  2259.  
  2260. Rule_RemoveMe()
  2261.  
  2262. elseif EGroup_IsEmpty(eg_navalgun_door) then
  2263. -- for strike teams
  2264. g_navalguns_doordead = true
  2265.  
  2266. -- make the guns vulnerable again
  2267. EGroup_SetInvulnerable(eg_navalguns, false)
  2268. EGroup_SetPlayerOwner(eg_navalguns, player2) --[[ debug ]]
  2269.  
  2270. -- hint point
  2271. hint_gunsID = HintPoint_Add( eg_navalguns, 40, 269053 )
  2272.  
  2273. -- message indicating the next step
  2274. Util_StartIntel(EVENTS.NavalGuns_Target2)
  2275.  
  2276. -- spawn the axis guys and run them out
  2277. SGroup_Clear(sg_temp)
  2278. Util_CreateSquadsAtMarker(player2, sg_temp, SBP.AXIS.VOLKSGRENADIER, mkr_navalguns, 1, 1)
  2279. Cmd_Move(sg_temp, mkr_axishq2_spawn3)
  2280.  
  2281. Rule_AddInterval( NavalGuns_Guns_DestroyedCheck, 1)
  2282.  
  2283. Rule_RemoveMe()
  2284. end
  2285.  
  2286. end
  2287.  
  2288. -- report when the 'guns' are destroyed
  2289. -- victory condition for this obj
  2290. function NavalGuns_Guns_DestroyedCheck()
  2291.  
  2292. if g_navalguns_complete then
  2293.  
  2294. Rule_RemoveMe()
  2295.  
  2296. elseif EGroup_IsEmpty(eg_navalguns) then
  2297.  
  2298. Objective_Complete(OBJ_NavalGuns)
  2299.  
  2300. Rule_RemoveMe()
  2301.  
  2302. end
  2303. end
  2304.  
  2305.  
  2306.  
  2307. -- make sure nothing else is in the way
  2308. -- the play the final NIS
  2309. function NavalGuns_TriggerNIS()
  2310.  
  2311. if Event_IsAnyRunning() == false then
  2312.  
  2313. Util_StartNIS(EVENTS.NIS03)
  2314.  
  2315. Rule_Add(NavalGuns_TriggerNISOver)
  2316.  
  2317. Rule_RemoveMe()
  2318. end
  2319.  
  2320. end
  2321.  
  2322. -- once the NIS is over go here
  2323. -- and end the mission
  2324. function NavalGuns_TriggerNISOver()
  2325.  
  2326. if Event_IsAnyRunning() == false then
  2327.  
  2328. Util_PlayMusic("Sound/Music/sp/m06/M06_Ob2a_PostTownSqBattle", 5, 0)
  2329. g_navalguns_complete = true
  2330.  
  2331. -- fow reveal for josh
  2332. local pos = Marker_GetPosition(mkr_bridge_cross)
  2333. FOW_RevealArea(pos, 40, 180)
  2334. local sgroup = {sg_stug[4], sg_stug[3], sg_bridgeretreaters2}
  2335. local marker = {bridge_retreatdest1, mkr_bridgedefense4, mkr_bridgedefense2}
  2336. for i = 1, 3 do
  2337. if SGroup_IsEmpty(sgroup[i]) == false then
  2338. if SGroup_IsUnderAttack(sgroup[i], false, 5) == false then
  2339. Cmd_AttackMove(sgroup[i], Marker_GetPosition(marker[i]), nil, nil, 10)
  2340. end
  2341. end
  2342. end
  2343. Rule_AddInterval(Bridge_JostleTroopsAround, 12)
  2344.  
  2345. -- for the bridge stugs
  2346. g_bridgestuf_num = 3
  2347.  
  2348. -- add the final objective if it hasn't been added yet
  2349. if g_axishq_granted ~= true then
  2350. print("naval guns > axis hq")
  2351. Rule_AddOneShot(AxisHQ_Obj_GrantDelay, 5)
  2352. g_axishq_granted = true
  2353. end
  2354.  
  2355. Rule_RemoveMe()
  2356. end
  2357.  
  2358. end
  2359.  
  2360.  
  2361. function Bridge_JostleTroopsAround()
  2362.  
  2363. local sgroup = {sg_stug[4], sg_stug[3], sg_bridgeretreaters2}
  2364. local marker = {mkr_bridge_cross, bridge_retreatdest1}
  2365. for i = 1, 3 do
  2366. if SGroup_IsEmpty(sgroup[i]) == false then
  2367. if SGroup_IsUnderAttack(sgroup[i], false, 5) then
  2368. Cmd_Move(sgroup[i], SGroup_GetPosition_EVEN_IF_EMPTY(sgroup[i]), true, nil, nil, 4, 5)
  2369. break
  2370. elseif SGroup_IsMoving(sgroup[i], false) then
  2371.  
  2372. else
  2373. SGroup_FaceMarker(sgroup[i], mkr_bridge_cross)
  2374. break
  2375. end
  2376. end
  2377. end
  2378.  
  2379. end
  2380.  
  2381.  
  2382.  
  2383.  
  2384.  
  2385.  
  2386.  
  2387.  
  2388.  
  2389.  
  2390.  
  2391.  
  2392.  
  2393.  
  2394.  
  2395.  
  2396.  
  2397. -------------------------------------------------------------------------
  2398.  
  2399. -- BRIDGE
  2400.  
  2401. -------------------------------------------------------------------------
  2402.  
  2403. function Bridge_Init()
  2404.  
  2405. sg_bridgemob_all = SGroup_CreateIfNotFound("sg_bridgemob_all")
  2406. sg_bridgemob_lead = SGroup_CreateIfNotFound("sg_bridgemob_lead")
  2407. sg_bridgemob = SGroup_CreateTable("sg_bridgemob%d", 5)
  2408.  
  2409. for i = 1, table.getn(sg_bridgeretreaters) do
  2410. Util_CreateSquadsAtMarker(player2, sg_bridgeretreaters[i], SBP.AXIS.VOLKSGRENADIER, mkr_bridgeretreat[i], 1)
  2411. Cmd_InstantUpgrade(sg_temp, UPG.AXIS.MP44)
  2412. end
  2413.  
  2414. Rule_AddInterval(Bridge_Check, 2)
  2415.  
  2416. -- add some people milling about
  2417. Rule_AddInterval(AxisHQ_OfficerManager, 17)
  2418.  
  2419. end
  2420.  
  2421. -- see when the player gets close to the bridge
  2422. function Bridge_Check()
  2423.  
  2424. if g_navalguns_reached or g_navalguns_complete or Prox_ArePlayersNearMarker(player1, mkr_bridge, false, 40) then
  2425.  
  2426. -- used for 'Longest Day'
  2427. g_bridge_reached = true
  2428. t_bridge_reached[1] = true
  2429.  
  2430. -- used for 'Secure Assets'
  2431. Rule_AddInterval(SecureAssets_GrantObj_Check, 5)
  2432. -- add the gears for 'Axis HQ'
  2433. Rule_AddOneShot(AxisHQ_Init, 3)
  2434.  
  2435. -- create hmg's in buildings
  2436. for i = 7, 12 do
  2437. Util_CreateSquadsAndGarrison(player2, sg_axis_hmg[i], SBP.AXIS.HEAVYMG, eg_hmghouse[i], 1)
  2438. end
  2439.  
  2440. for i = 1, table.getn(sg_bridgeretreaters) do
  2441. if SGroup_IsEmpty(sg_bridgeretreaters[i]) == false then
  2442. Cmd_Move(sg_bridgeretreaters[i], mkr_bridgedefense[i])
  2443. end
  2444. end
  2445. -- keep the squad in fighting shape
  2446. -- until the Naval guns are dead
  2447. Rule_AddInterval(Bridge_Defenders_Manager, 5)
  2448. -- hide squads
  2449. Rule_AddInterval(Bridge_Defenders_BuildingHide, 10)
  2450.  
  2451. -- move the stugs (if they exist) up to defend
  2452. t_Bridgetanks = {
  2453. target = {mkr_bridge, mkr_lowerdock1, mkr_bridgedefense4, mkr_bridgedefense2},
  2454. }
  2455. g_bridgestuf_num = 4
  2456. for i = 1, g_bridgestuf_num do
  2457. if SGroup_IsEmpty(sg_stug[i]) == false then
  2458. -- modify some units
  2459. Modify_WeaponRange(sg_stug[i], "hardpoint_01", 1)
  2460. --Modify_SightRadius(sg_stug[i], 0.5)
  2461. Cmd_Move(sg_stug[i], t_Bridgetanks.target[i])
  2462. --otherwise create them and move them up
  2463. else
  2464. Util_CreateSquadsAtMarker(player2, sg_stug[i], SBP.AXIS.STUG, mkr_lowerdock_spawn, 1)
  2465. SGroup_AddGroup(sg_axis_tank_all, sg_stug[i])
  2466.  
  2467. Cmd_Move(sg_stug[i], t_Bridgetanks.target[i])
  2468. end
  2469. end
  2470. Rule_AddInterval(Bridge_Tank_Manager, 62)
  2471.  
  2472. -- add the capture for the motorpool
  2473. Rule_AddInterval(Bridge_MotorPoolcapture, 4)
  2474.  
  2475. -- Check for the player getting across the bridge
  2476. Rule_AddInterval(Bridge_Cross_Check, 5)
  2477.  
  2478. Rule_RemoveMe()
  2479.  
  2480. end
  2481.  
  2482. end
  2483.  
  2484. function Bridge_Cross_Check()
  2485. if Prox_ArePlayersNearMarker(player1, mkr_bridge_cross, false, 40) then
  2486.  
  2487. g_bridge_crossed = true
  2488. t_bridge_crossed[1] = true
  2489. -- Once the player gets across the bridge
  2490. Util_PlayMusic("Sound/Music/sp/m06/M06_Ob2b_City_Fight", 5, 5)
  2491.  
  2492. -- attack the bridge area
  2493. -- the two stuggs hanging back
  2494. for i = 3, g_bridgestuf_num do
  2495. if SGroup_IsEmpty(sg_stug[i]) == false then
  2496. Cmd_Move(sg_stug[i], Util_GetRandomPosition(mkr_bridge_cross, 12))
  2497. end
  2498. end
  2499. -- spawn some guys from somewhere nearby
  2500.  
  2501. -- start the bridgemob
  2502.  
  2503. Rule_RemoveMe()
  2504. end
  2505. end
  2506.  
  2507. -- should generate a loop of enemies until the player takes out the motorpool
  2508. function Bridge_Mob_Start()
  2509. if EGroup_IsEmpty(eg_axis_motorpool) == false then
  2510.  
  2511. local sgroup = { all = sg_bridgemob_all, lead = sg_bridgemob_lead, mob = sg_bridgemob}
  2512.  
  2513. -- pick a random mob
  2514. local mobs = {mobType.V, mobType.VG, mobType.AT, mobType.AT, mobType.V}
  2515. local mType = mobs[World_GetRand(1,5)]
  2516.  
  2517. -- pick a random waypoint path
  2518. local paths = {
  2519. {mkr_lowerdock4, mkr_bridge_cross},
  2520. {mkr_motorpool4, mkr_bridge_stugdef2},
  2521. }
  2522. local path = paths[World_GetRand(1,2)]
  2523.  
  2524. local source = {stype = stype.BUILD, spawn = eg_axis_motorpool, rally = mkr_bridge_stugdef1}
  2525. local destination = {pace = pace.FAST, count = 0, move = true, way = path, capture = nil}
  2526. local dedication = false
  2527.  
  2528. -- add mob
  2529. MobRule_AddMob(player2, sgroup, mType, source, destination, dedication)
  2530.  
  2531. -- reset check
  2532. if Rule_Exists(Bridge_Mob_Reset) == false then
  2533. Rule_AddInterval(Bridge_Mob_Reset, 20)
  2534. end
  2535. end
  2536. end
  2537. -- reset once the mob gets too small
  2538. function Bridge_Mob_Reset()
  2539. if EGroup_IsEmpty(eg_axis_motorpool) then
  2540. Rule_RemoveMe()
  2541. elseif SGroup_Count(sg_bridgemob_all) < 2 and Rule_Exists(Bridge_Mob_Start) == false then
  2542. -- dif handle
  2543. Rule_AddOneShot(Bridge_Mob_Start, World_GetRand(30, 50))
  2544. end
  2545. end
  2546.  
  2547. -- track the tanks shooting at the player
  2548. function Bridge_Tank_Manager()
  2549.  
  2550. -- the remove condition
  2551. if g_navalguns_complete or g_motorpool_complete then
  2552. Rule_RemoveMe()
  2553. else
  2554. for i = 1, g_bridgestuf_num do
  2555. if SGroup_IsEmpty(sg_stug[i]) and Prox_ArePlayersNearMarker(player1, mkr_lowerdock_spawn, false, 40) == false then
  2556. Util_CreateSquadsAtMarker(player2, sg_stug[i], SBP.AXIS.STUG, mkr_lowerdock_spawn, 1)
  2557. SGroup_AddGroup(sg_axis_tank_all, sg_stug[i])
  2558.  
  2559. Cmd_AttackMove(sg_stug[i], t_Bridgetanks.target[i])
  2560.  
  2561. break
  2562. end
  2563. end
  2564. end
  2565.  
  2566. end
  2567.  
  2568.  
  2569. -- create reinforcements to clog the bridge until the player
  2570. -- completes the guns obj
  2571. function Bridge_Defenders_Manager()
  2572. for i = 1, table.getn(sg_bridgeretreaters) do
  2573. if SGroup_IsEmpty(sg_bridgeretreaters[i]) or SGroup_Count(sg_bridgeretreaters[i]) < 2 then
  2574. Util_CreateSquadsAtMarker(player2, sg_bridgeretreaters[i], Util_RandomInfSBP(), mkr_bridge_spawn, 1)
  2575. Util_GrantRandomUpgrade(sg_bridgeretreaters[i])
  2576. Cmd_AttackMove(sg_bridgeretreaters[i], mkr_bridgedefense[i], true)
  2577. end
  2578. end
  2579.  
  2580. -- the remove condition
  2581. if g_navalguns_complete then
  2582. Rule_RemoveMe()
  2583. end
  2584.  
  2585. end
  2586.  
  2587. -- runs guys inside of the buildings
  2588. function Bridge_Defenders_BuildingHide()
  2589.  
  2590. -- garrison the south building
  2591. if EGroup_IsEmpty(eg_bunkerbridge1) == false and SGroup_IsEmpty(sg_bridgeretreaters[1]) == false and SGroup_IsUnderAttack(sg_bridgeretreaters[1], false, 10) then
  2592. g_bridge_garrison1 = true
  2593. Cmd_Garrison(sg_bridgeretreaters[1], eg_bunkerbridge1, false, false)
  2594. end
  2595. -- garrison the north building
  2596. if EGroup_IsEmpty(eg_bunkerbridge2) == false and SGroup_IsEmpty(sg_bridgeretreaters[2]) == false and SGroup_IsUnderAttack(sg_bridgeretreaters[2], false, 10) then
  2597. g_bridge_garrison2 = true
  2598. Cmd_Garrison(sg_bridgeretreaters[2], eg_bunkerbridge2, false, false)
  2599. end
  2600.  
  2601. -- the remove condition
  2602. if (( EGroup_IsEmpty(eg_bunkerbridge1) or g_bridge_garrison1 ) and ( EGroup_IsEmpty(eg_bunkerbridge2) or g_bridge_garrison2 ))
  2603. or ( Rule_Exists(Bridge_Defenders_Manager) == false and SGroup_IsEmpty(sg_bridgeretreaters[1]) and SGroup_IsEmpty(sg_bridgeretreaters[2]) ) then
  2604. Rule_RemoveMe()
  2605. end
  2606.  
  2607. end
  2608.  
  2609.  
  2610. -- grants the player another motorpool on the far side of the bridge
  2611. function Bridge_MotorPoolcapture()
  2612.  
  2613. -- capture the spare motorpool
  2614. if EGroup_IsEmpty(eg_2ndmotorpool) == false then
  2615. if EGroup_IsCapturedByPlayer(eg_territory13, player1, false) then
  2616. EGroup_SetPlayerOwner(eg_2ndmotorpool, player1)
  2617. Util_StartIntel(EVENTS.Bridge_EarnedMotorPool)
  2618.  
  2619. hint_2ndMPID = HintPoint_Add( eg_2ndmotorpool, 50, 269024 )
  2620.  
  2621. Rule_RemoveMe()
  2622. end
  2623. else
  2624. Rule_RemoveMe()
  2625. end
  2626.  
  2627. end
  2628.  
  2629.  
  2630. function Bridge_MotorPool_UnHint()
  2631. egtemp = EGroup_CreateIfNotFound("egtemp")
  2632. Misc_GetSelectedEntities(egtemp, false)
  2633. if EGroup_Compare(eg_2ndmotorpool, egtemp) then
  2634. HintPoint_Remove(hint_2ndMPID)
  2635.  
  2636. Rule_RemoveMe()
  2637. end
  2638. end
  2639.  
  2640.  
  2641.  
  2642.  
  2643.  
  2644.  
  2645.  
  2646.  
  2647.  
  2648.  
  2649. -------------------------------------------------------------------------
  2650. -- Secure the German Assets
  2651. -------------------------------------------------------------------------
  2652. -- Medal Op
  2653. -- The player must save the German Assets
  2654. -- Pioneer squads are attempting to place charges
  2655. -- around desireable targets. Stop them before
  2656. -- they place the charges and reach the detonator.
  2657. -------------------------------------------------------------------------
  2658. function Initialize_OBJ_SecureAssets()
  2659.  
  2660. OBJ_SecureAssets = {
  2661.  
  2662. SetupUI = function()
  2663.  
  2664. t_securehints = {}
  2665.  
  2666. Objective_AddUIElements(OBJ_SecureAssets, mkr_secure_demotrigger, true, 269085, false)
  2667. local hintID = HintPoint_Add(mkr_secure_demotrigger, true, 269085)
  2668. table.insert(t_securehints, hintID)
  2669.  
  2670. end,
  2671.  
  2672. OnStart = function()
  2673.  
  2674. -- announce the goal
  2675. Util_StartIntel(EVENTS.SecureAssets_Start)
  2676.  
  2677. -- dif handle
  2678. g_timetosecure = Util_DifVar({180, 120, 90}) -- 2.5 min, 2 min, 1.5 min to detonate
  2679. -- add the counter
  2680. Objective_StartTimer(OBJ_SecureAssets, COUNT_DOWN, g_timetosecure)
  2681. -- can't find another way to do this
  2682. Rule_AddInterval(SecureAssets_TimerDone, g_timetosecure)
  2683.  
  2684. -- add the detect function
  2685. Rule_AddInterval(SecureAssets_WinCondition, 5)
  2686.  
  2687. Scar_Autosave(269253) -- Medal Opportunity
  2688.  
  2689. end,
  2690.  
  2691. OnComplete = function()
  2692.  
  2693. -- tell the player they did good
  2694. if g_axishq_complete ~= true then
  2695. Util_StartIntel(EVENTS.SecureAssets_Complete)
  2696. end
  2697.  
  2698. -- flag for complete
  2699. g_secure_complete = true
  2700.  
  2701. -- remove hints
  2702. for i = 1, table.getn(t_securehints) do
  2703. HintPoint_Remove(t_securehints[i])
  2704. end
  2705.  
  2706. end,
  2707.  
  2708. OnFail = function()
  2709. -- flag for fail
  2710. g_secure_complete = false
  2711.  
  2712. -- tell the player they failed
  2713. if g_axishq_complete ~= true then
  2714. Util_StartIntel(EVENTS.SecureAssets_Fail)
  2715. end
  2716.  
  2717. -- remove hints
  2718. if t_securehints ~= nil and table.getn(t_securehints) > 0 then
  2719. for i = 1, table.getn(t_securehints) do
  2720. HintPoint_Remove(t_securehints[i])
  2721. end
  2722. end
  2723.  
  2724. -- blow'em
  2725. EGroup_Kill(eg_fueltanks)
  2726. Rule_AddInterval(SecureAssets_DeadTime, .5)
  2727. end,
  2728.  
  2729. Title = 269080,
  2730. Description = 269081,
  2731. Type = OT_Medal,
  2732. MedalID = MEDALS.SOLDIERS_MEDAL_M06,
  2733. TitleEnd = 269096,
  2734. Icon = IT_M_Default,
  2735.  
  2736. FOW =
  2737. {
  2738. { target = mkr_secure_demotrigger, },
  2739. },
  2740.  
  2741. }
  2742.  
  2743. end
  2744.  
  2745.  
  2746.  
  2747. function SecureAssets_Init()
  2748. EGroup_SetPlayerOwner(eg_secure_demotrigger, player2)
  2749. Cmd_InstantUpgrade(eg_secure_demotrigger, UPG.ALLIES.CONVERT_AMBIENT_BUILDING, 1)
  2750.  
  2751. -- manage the default defense for the port section
  2752. Rule_AddInterval(SecureAssets_DefenseManager, 4)
  2753.  
  2754. end
  2755.  
  2756. -- keep a base level of resistance
  2757. function SecureAssets_DefenseManager()
  2758.  
  2759. if EGroup_IsEmpty(eg_secure_demotrigger) or g_secure_complete then
  2760.  
  2761. Rule_RemoveMe()
  2762.  
  2763. else
  2764. -- check the patrol
  2765. if SGroup_IsEmpty(sg_port_patrol) then
  2766.  
  2767. elseif SGroup_IsMoving(sg_port_patrol, true) == false then
  2768. Cmd_AttackMove(sg_port_patrol, Util_GetRandomPosition(mkr_port_patrol1, 60))
  2769. end
  2770. -- check the AT gun
  2771. if SGroup_IsEmpty(sg_port_atgun) then
  2772. if Rule_Exists(SecureAssets_ATGun) == false then
  2773. Rule_AddOneShot(SecureAssets_ATGun, World_GetRand(40, 60))
  2774. end
  2775. elseif SGroup_IsUnderAttack(sg_port_atgun, false, 10) and SGroup_IsMoving(sg_port_atgun, false) then
  2776. Cmd_Stop(sg_port_atgun)
  2777. end
  2778. end
  2779.  
  2780. end
  2781.  
  2782.  
  2783. -- re add the AT gun
  2784. function SecureAssets_ATGun()
  2785. if EGroup_IsEmpty(eg_secure_demotrigger) or g_secure_complete then
  2786. Rule_RemoveMe()
  2787. else
  2788. Util_CreateSquads(player2, sg_port_atgun, SBP.AXIS.PAK_38, mkr_secure_demotrigger, nil, 1, 4, nil, mkr_secure_demotrigger)
  2789. local marker = {mkr_port_atgun1, mkr_port_atgun2, mkr_port_atgun3}
  2790. Cmd_Move(sg_port_atgun, marker[World_GetRand(1, 3)])
  2791. end
  2792. end
  2793.  
  2794.  
  2795. function SecureAssets_GrantObj_Check()
  2796.  
  2797. if Prox_ArePlayersNearMarker(player1, fueldepot_trigger, false, 40) then
  2798.  
  2799. -- trigger the action now
  2800. Rule_AddOneShot(SecureAssets_GrantObj_Grant, 2)
  2801.  
  2802. Rule_AddInterval(SecureAssets_Ambush_Check, 5)
  2803. -- generate some baddies
  2804. -- dif handle
  2805. Rule_AddIntervalEx(SecureAssets_Defense, 5, Util_DifVar({3, 4, 5}))
  2806.  
  2807. Rule_RemoveMe()
  2808. end
  2809.  
  2810. end
  2811.  
  2812. -- spew out some guys to defend the target
  2813. function SecureAssets_Defense()
  2814. if EGroup_IsEmpty(eg_secure_demotrigger) or g_secure_complete then
  2815. Rule_RemoveMe()
  2816. else
  2817. sg_securedefense = SGroup_CreateIfNotFound("sg_securedefense")
  2818. Util_CreateSquadsAtMarker(player2, sg_securedefense, Util_RandomInfSBP3(), mkr_secure_demotrigger, 1)
  2819. Cmd_Move(sg_securedefense, Marker_GetPosition(mkr_retreat9), nil, nil, nil, nil, nil, 20)
  2820. end
  2821. end
  2822.  
  2823. -- is the stug there
  2824. function SecureAssets_Ambush_Check()
  2825.  
  2826. if Prox_ArePlayersNearMarker(player1, mkr_secure_target4, false, 50) then
  2827.  
  2828. g_port_granted = true
  2829. t_port_granted[1] = true
  2830. -- give the obj
  2831. Objective_Start(OBJ_SecureAssets)
  2832.  
  2833. Rule_AddInterval(Secure_Stug_AmbushResponse, 12)
  2834.  
  2835. Rule_RemoveMe()
  2836. end
  2837.  
  2838. end
  2839.  
  2840. function Secure_Stug_AmbushResponse()
  2841. local sgroup = {sg_port_stug1}
  2842. local marker = {mkr_port_patrol2}
  2843. for i = 1, table.getn(sgroup) do
  2844. if SGroup_IsEmpty(sgroup[i]) == false then
  2845.  
  2846. if SGroup_IsUnderAttack(sgroup[i], false, 10) then
  2847.  
  2848. local sgtemp = SGroup_CreateIfNotFound("sgtemp")
  2849.  
  2850. SGroup_GetLastAttacker( sgroup[i], sgtemp )
  2851. Cmd_Move(sgroup[i], SGroup_GetPosition_EVEN_IF_EMPTY(sgtemp), nil, nil, nil, World_GetRand(2, 5), 15)
  2852. SGroup_Clear(sgtemp)
  2853.  
  2854. elseif SGroup_IsMoving(sgroup[i], false) then
  2855.  
  2856. else
  2857. Cmd_Move(sgroup[i], marker[i])
  2858. end
  2859.  
  2860. end
  2861. end
  2862. end
  2863.  
  2864. -- this allows me to trigger the same stuff in two different ways
  2865. -- according to which trigger the player passes first
  2866. function SecureAssets_GrantObj_Grant()
  2867.  
  2868. -- add the Pioneer Manager info
  2869. g_secure_pioneersleft = 5
  2870.  
  2871. -- set up the groups
  2872. for i = 1, 5 do
  2873. EGroup_AddEGroup(eg_secure_target_all, eg_secure_target[i])
  2874. end
  2875. g_secure_originalcount = EGroup_Count(eg_secure_target_all)
  2876. t_secure = {}
  2877. t_secure.marker = { mkr_secure_target1, mkr_secure_target2, mkr_secure_target3, mkr_secure_target4, mkr_secure_target5, mkr_secure_demotrigger }
  2878. t_secure.egroup = {eg_secure_target1, eg_secure_target2, eg_secure_target3, eg_secure_target4, eg_secure_target5, eg_secure_demotrigger}
  2879. t_secure.marker[1] = t_secure.marker[1]
  2880. t_secure.egroup[1] = t_secure.egroup[1]
  2881. g_secure_demodone = false
  2882. -- add the manager
  2883. Rule_AddInterval(SecureAssets_Pioneer_Manager, 10)
  2884.  
  2885. end
  2886.  
  2887.  
  2888. function SecureAssets_Pioneer_Manager()
  2889. -- is the team empty
  2890. if EGroup_IsEmpty(eg_secure_demotrigger) then
  2891.  
  2892. Rule_RemoveMe()
  2893.  
  2894. elseif SGroup_IsEmpty(sg_secure_demoteam) then
  2895. -- are there more on deck?
  2896. if g_secure_pioneersleft > 0 and t_secure.marker[1] ~= nil then
  2897. Util_CreateSquadsAtMarker(player2, sg_secure_demoteam, SBP.AXIS.PIONEER, mkr_secure_demotrigger, 1)
  2898.  
  2899. Cmd_Move(sg_secure_demoteam, t_secure.marker[1])
  2900. -- create the gun support
  2901. if SGroup_IsEmpty(sg_secure_demoteam_support) then
  2902. Util_CreateSquadsAtMarker(player2, sg_secure_demoteam_support, SBP.AXIS.VOLKSGRENADIER, mkr_secure_demotrigger, 2)
  2903. Util_GrantRandomUpgrade(sg_secure_demoteam_support)
  2904. end
  2905. Cmd_AttackMove(sg_secure_demoteam_support, t_secure.marker[1])
  2906. -- decrement the pionner squad count
  2907. g_secure_pioneersleft = g_secure_pioneersleft-1
  2908. else
  2909. Rule_RemoveMe()
  2910. end
  2911.  
  2912. else
  2913.  
  2914. -- body guard attack if underattack
  2915. if SGroup_IsEmpty(sg_secure_demoteam_support) then
  2916. Util_CreateSquadsAtMarker(player2, sg_secure_demoteam_support, SBP.AXIS.VOLKSGRENADIER, mkr_secure_demotrigger, 2)
  2917. Util_GrantRandomUpgrade(sg_secure_demoteam_support)
  2918. Cmd_Move(sg_secure_demoteam_support, sg_secure_demoteam, true)
  2919. elseif SGroup_IsUnderAttack(sg_secure_demoteam, false, 10) then
  2920. Cmd_Move(sg_secure_demoteam_support, sg_secure_demoteam, true)
  2921. end
  2922.  
  2923. if table.getn(t_secure.egroup) == 0 or table.getn(t_secure.egroup) == nil then
  2924.  
  2925. g_secure_demodone = true
  2926.  
  2927. elseif EGroup_IsEmpty(t_secure.egroup[1]) == false and g_secure_demodone == false and Prox_AreSquadsNearMarker(sg_secure_demoteam, t_secure.marker[1], false, 10) then
  2928.  
  2929. g_secure_demodone = true
  2930.  
  2931. elseif EGroup_IsEmpty(t_secure.egroup[1]) == false and g_secure_demodone == true and Prox_AreSquadsNearMarker(sg_secure_demoteam, t_secure.marker[1], false, 20) then
  2932. -- they've successfully charged the goal
  2933. -- take it off the list
  2934. table.remove(t_secure.marker, 1)
  2935.  
  2936. -- add the egroup to the list of 'charged' groups
  2937. EGroup_AddEGroup(eg_secure_demogroup, t_secure.egroup[1])
  2938. table.remove(t_secure.egroup, 1)
  2939.  
  2940. -- is the table empty? ie are we to the final point?
  2941. if table.getn(t_secure.marker) > 0 then
  2942. -- send them to their next target
  2943. Cmd_Move(sg_secure_demoteam, t_secure.marker[1])
  2944. else
  2945. g_secure_chargesblown = true
  2946. end
  2947.  
  2948. -- reset the flag
  2949. g_secure_demodone = false
  2950.  
  2951. elseif EGroup_IsEmpty(t_secure.egroup[1]) then
  2952. -- somehow it's been destroyed
  2953. -- take it off the list
  2954. table.remove(t_secure.marker, 1)
  2955. table.remove(t_secure.egroup, 1)
  2956. if table.getn(t_secure.marker) > 0 then
  2957. -- send them to their next target
  2958. Cmd_Move(sg_secure_demoteam, t_secure.marker[1])
  2959. else
  2960. g_secure_chargesblown = true
  2961. end
  2962.  
  2963. -- reset the flag
  2964. g_secure_demodone = false
  2965.  
  2966. else
  2967. -- extra clause in case
  2968. end
  2969.  
  2970. end
  2971.  
  2972. -- set above when the table is empty
  2973. if g_secure_complete ~= nil then
  2974. Rule_RemoveMe()
  2975. end
  2976.  
  2977. end
  2978.  
  2979.  
  2980. function SecureAssets_WinCondition()
  2981. -- check the target is it alive?
  2982. if EGroup_IsEmpty(eg_secure_demotrigger) then
  2983.  
  2984. -- congrats
  2985. Objective_Complete(OBJ_SecureAssets)
  2986.  
  2987. Rule_RemoveMe()
  2988. elseif g_secureTimer then
  2989.  
  2990. -- aw shucks
  2991. Objective_Fail(OBJ_SecureAssets)
  2992.  
  2993. Rule_RemoveMe()
  2994. end
  2995. end
  2996.  
  2997. function SecureAssets_TimerDone()
  2998. g_secureTimer = true
  2999. end
  3000.  
  3001. function SecureAssets_DeadTime()
  3002. local count = EGroup_Count(eg_secure_demogroup)
  3003. if count > 1 then
  3004. eg_tempdemo = EGroup_CreateIfNotFound("eg_tempdemo")
  3005. EGroup_Add(eg_tempdemo, EGroup_GetRandomSpawnedEntity(eg_secure_demogroup))
  3006. EGroup_Kill(eg_tempdemo)
  3007. else
  3008. Rule_RemoveMe()
  3009. end
  3010. end
  3011.  
  3012.  
  3013.  
  3014.  
  3015.  
  3016.  
  3017.  
  3018.  
  3019.  
  3020.  
  3021.  
  3022.  
  3023.  
  3024.  
  3025.  
  3026.  
  3027.  
  3028.  
  3029.  
  3030.  
  3031.  
  3032.  
  3033.  
  3034.  
  3035.  
  3036.  
  3037. -------------------------------------------------------------------------
  3038.  
  3039. -- Motor Pool
  3040.  
  3041. -------------------------------------------------------------------------
  3042. -- grants the obj when the player attacks the first of the
  3043. -- MP tanks... ones before this were part of the bridge defense
  3044. -- and should not trigger the obj
  3045. function MotorPool_OBJ_Grant()
  3046.  
  3047. -- this is a thought, if the motorpool is already destroyed, skip the obj? - deg
  3048. if EGroup_IsEmpty(eg_axis_motorpool) then
  3049.  
  3050. Rule_RemoveMe()
  3051.  
  3052. elseif g_bridge_reached and SGroup_IsUnderAttack(sg_axis_tank_mp, false, 10) then
  3053.  
  3054. -- announce the goal
  3055. Util_StartIntel(EVENTS.MotorPool_Start)
  3056.  
  3057. -- start the action
  3058. Rule_AddOneShot(MotorPool_Action_Kickoff, 0)
  3059.  
  3060. -- here's the win condition tracker
  3061. Rule_AddInterval(MotorPool_Destroy_Check, 5)
  3062.  
  3063. Rule_RemoveMe()
  3064.  
  3065. end
  3066.  
  3067. end
  3068.  
  3069. function MotorPool_Action_Kickoff()
  3070. -- tracks the player to create some action near the motorpool
  3071. Rule_AddInterval(MotorPool_Officer_Check1, 5)
  3072.  
  3073. -- set up the tanks
  3074. Rule_AddIntervalEx(MotorPool_Tank_Create, 54, 4)
  3075. -- create the tanks to defend the space
  3076. Rule_AddInterval(MotorPool_Tank_Manager, 5)
  3077.  
  3078. -- watch the tank health and send repair crews when hurt
  3079. Rule_AddInterval(MotorPool_RepairCrew, 5)
  3080.  
  3081. end
  3082.  
  3083. -- create the tanks 1 at a time and roll to position
  3084. function MotorPool_Tank_Create()
  3085. if EGroup_IsEmpty(eg_axis_motorpool) then
  3086.  
  3087. Rule_RemoveMe()
  3088. else
  3089. local target = {mkr_motorpool1, mkr_motorpool2, mkr_motorpool3, mkr_motorpool4}
  3090. for i = 1, 4 do
  3091. if SGroup_IsEmpty(sg_motorpool_tank[i]) then
  3092. Util_CreateSquadsAtMarker(player2, sg_motorpool_tank[i], SBP.AXIS.STUG, mkr_lowerdock_spawn, 1)
  3093. SGroup_AddGroup(sg_axis_tank_all, sg_motorpool_tank[i])
  3094.  
  3095. Cmd_Move(sg_motorpool_tank[i], mkr_motorpool4)
  3096. Cmd_AttackMove(sg_motorpool_tank[i], target[i], true)
  3097. break
  3098. end
  3099. end
  3100. end
  3101. end
  3102.  
  3103.  
  3104.  
  3105.  
  3106. -- bunch of tanks that sit around and defend the Motor Pool
  3107. function MotorPool_Tank_Manager()
  3108.  
  3109. local target = {mkr_motorpool1, mkr_motorpool2, mkr_motorpool3, mkr_motorpool4}
  3110. for i = 1, 4 do
  3111. if SGroup_IsEmpty(sg_motorpool_tank[i]) == false then
  3112.  
  3113. if SGroup_GetAvgHealth(sg_motorpool_tank[i]) > .4 then
  3114.  
  3115. if SGroup_IsUnderAttack(sg_motorpool_tank[i], false, 10) then
  3116.  
  3117. local sgtemp = SGroup_CreateIfNotFound("sgtemp")
  3118.  
  3119. SGroup_GetLastAttacker( sg_motorpool_tank[i], sgtemp )
  3120. Cmd_Move(sg_motorpool_tank[i], SGroup_GetPosition_EVEN_IF_EMPTY(sgtemp), nil, nil, nil, World_GetRand(2, 6), 20)
  3121. SGroup_Clear(sgtemp)
  3122.  
  3123. elseif SGroup_IsMoving(sg_motorpool_tank[i], false) then
  3124.  
  3125. else
  3126. Cmd_AttackMove(sg_motorpool_tank[i], target[i])
  3127. end
  3128.  
  3129. else
  3130.  
  3131. if SGroup_IsMoving(sg_motorpool_tank[i], false) then
  3132. Cmd_Move(sg_motorpool_tank[i], EGroup_GetPosition_EVEN_IF_EMPTY(eg_territory3))
  3133. end
  3134.  
  3135. end
  3136.  
  3137. end
  3138. end
  3139.  
  3140. if EGroup_IsEmpty(eg_axis_motorpool) then
  3141. --Cmd_AttackMove(sg_axis_tank_all, tow)
  3142. Rule_RemoveMe()
  3143. end
  3144.  
  3145. end
  3146.  
  3147.  
  3148.  
  3149.  
  3150. function MotorPool_RepairCrew()
  3151.  
  3152. -- do some cool stuff with pioneers
  3153. if g_motorpool_complete or EGroup_IsEmpty(eg_axis_motorpool) then
  3154.  
  3155. Rule_RemoveMe()
  3156.  
  3157. else
  3158. for i = 1, 4 do
  3159. -- is the tank alive and hurt?
  3160. if SGroup_IsEmpty(sg_motorpool_tank[i]) == false and SGroup_GetAvgHealth(sg_motorpool_tank[i]) < .8 then
  3161. if SGroup_IsEmpty(sg_motorpool_repair[i]) then
  3162. -- create repair crew
  3163. Util_CreateSquadsAtMarker( player2, sg_motorpool_repair[i], SBP.AXIS.PIONEER, EGroup_GetPosition_EVEN_IF_EMPTY(eg_axis_motorpool), 1)
  3164. end
  3165. -- order them to repair the pnthr
  3166. Cmd_Ability( sg_motorpool_repair[i], ABILITY.REPAIR, sg_motorpool_tank[i], nil, true)
  3167. elseif SGroup_IsEmpty(sg_motorpool_tank[i]) and SGroup_IsEmpty(sg_motorpool_repair[i]) == false then
  3168. Cmd_Garrison(sg_motorpool_tank[i], eg_motorpool_hide)
  3169. end
  3170. end
  3171. end
  3172.  
  3173. end
  3174.  
  3175.  
  3176. -- creates an officer for the player to kill
  3177. function MotorPool_Officer_Check1()
  3178.  
  3179. if EGroup_IsEmpty(eg_axis_motorpool) then
  3180.  
  3181. Rule_RemoveMe()
  3182.  
  3183. else
  3184.  
  3185. if Prox_ArePlayersNearMarker(player1, EGroup_GetPosition_EVEN_IF_EMPTY(eg_axis_motorpool), false, 40) then
  3186. local pos = EGroup_GetPosition_EVEN_IF_EMPTY(eg_axis_motorpool)
  3187. Util_CreateSquadsAtMarker(player2, sg_mp_officer, SBP.AXIS.OFFICER, pos, 1)
  3188. --Cmd_AttackMove(sg_mp_officer, mkr_lowerdock_spawn)
  3189.  
  3190. -- warn the player
  3191. Util_StartIntel(EVENTS.MotorPool_Warning)
  3192.  
  3193. -- add the next step
  3194. Rule_AddInterval(MotorPool_Officer_Check2, 1)
  3195.  
  3196. Rule_RemoveMe()
  3197. end
  3198.  
  3199. end
  3200.  
  3201. end
  3202.  
  3203. -- this is a choice
  3204. -- NOT to alert the player to the Officer's death
  3205. -- if the Motorpool has already been destroyed
  3206. function MotorPool_Officer_Check2()
  3207.  
  3208. if EGroup_IsEmpty(eg_axis_motorpool) then
  3209.  
  3210. Rule_RemoveMe()
  3211.  
  3212. else
  3213.  
  3214. if SGroup_IsEmpty(sg_mp_officer) then
  3215.  
  3216. Rule_RemoveMe()
  3217.  
  3218. elseif SGroup_IsUnderAttack(sg_mp_officer, false, 7) then
  3219. -- the officer hides
  3220. Cmd_Garrison(sg_mp_officer, eg_motorpool_hide)
  3221. -- a squad spawns to support
  3222. local pos = EGroup_GetPosition_EVEN_IF_EMPTY(eg_axis_motorpool)
  3223. Util_CreateSquadsAtMarker(player2, sg_mp_support, SBP.AXIS.VOLKSGRENADIER, pos, 1)
  3224. Util_GrantRandomUpgrade(sg_mp_support)
  3225. --Cmd_AttackMove(sg_mp_support, mkr_lowerdock_spawn)
  3226.  
  3227. Rule_RemoveMe()
  3228. end
  3229.  
  3230. end
  3231.  
  3232. end
  3233.  
  3234.  
  3235. function MotorPool_Destroy_Check()
  3236.  
  3237. if EGroup_IsEmpty(eg_axis_motorpool) and SGroup_IsEmpty(sg_axis_tank_all) then
  3238.  
  3239. g_motorpool_complete = true
  3240.  
  3241. -- tell the player they did good
  3242. Util_StartIntel(EVENTS.MotorPool_Complete)
  3243.  
  3244. Rule_RemoveMe()
  3245.  
  3246. end
  3247.  
  3248. end
  3249.  
  3250.  
  3251.  
  3252.  
  3253.  
  3254.  
  3255.  
  3256.  
  3257.  
  3258.  
  3259.  
  3260.  
  3261.  
  3262.  
  3263. -------------------------------------------------------------------------
  3264. -- AXIS HQ
  3265. -------------------------------------------------------------------------
  3266. -- The player must destroy the Axis HQ
  3267. -- This objective is 'supposed' to be triggered by the completion of
  3268. -- the 'Naval Guns' obj but can be triggered early by the player
  3269. -- pushing too far across the bridge before completing the 'Guns' obj
  3270. -------------------------------------------------------------------------
  3271. function Initialize_OBJ_AxisHQ()
  3272.  
  3273. OBJ_AxisHQ = {
  3274.  
  3275. SetupUI = function()
  3276.  
  3277. Objective_AddUIElements(OBJ_AxisHQ, eg_axishq2_2, true, 269062, true)
  3278. -- add hint
  3279. hint_hqID = HintPoint_Add( eg_axishq2_2, 30, 269062 )
  3280. --Objective_AddUIElements(OBJ_AxisHQ, eg_axishq2_1, true, 269062, true)
  3281.  
  3282. end,
  3283.  
  3284. OnStart = function()
  3285.  
  3286. -- announce the goal
  3287. Util_StartIntel(EVENTS.AxisHQ_Start)
  3288.  
  3289. -- here's a intel prox check
  3290. Rule_AddInterval(AxisHQ_Check_Prox, 5)
  3291.  
  3292. -- here's an under attack check
  3293. Rule_AddInterval(AxisHQ_Check_Underattack, 5)
  3294.  
  3295. -- here's an extra special if the 'Naval Guns'
  3296. -- hasn't been completed
  3297. if g_navalguns_complete == false then
  3298. Rule_AddInterval( AxisHQ_Tank_Patrol_NoGuns, 15)
  3299. end
  3300.  
  3301. -- the basic one the player must deal with until the lower section is cleared
  3302. t_TPB_marker = {mkr_bridgedefense4, mkr_bridge_stugdef2}
  3303. Rule_AddInterval( AxisHQ_Tank_Patrol_Basic, 25)
  3304.  
  3305. -- the check that triggers the motorpool obj
  3306. Rule_AddInterval( MotorPool_OBJ_Grant, 5)
  3307.  
  3308. -- here's the win condition tracker
  3309. Rule_AddInterval(AxisHQ_Surrender_Check, 5)
  3310.  
  3311. -- add in a mob in 2 minutes
  3312. -- dif handle
  3313. Rule_AddOneShot(AxisHQ_Mob_Start, Util_DifVar({140, 120, 90}))
  3314.  
  3315. end,
  3316.  
  3317. OnComplete = function()
  3318.  
  3319. g_axishq_complete = true
  3320.  
  3321. -- award command point
  3322. -- Player_AddUnspentCommandPoints(player1, 1)
  3323.  
  3324. -- tell the player they did good
  3325. Util_StartIntel(EVENTS.AxisHQ_Complete)
  3326.  
  3327. -- otrigger the end NIS
  3328. Rule_Add(AxisHQ_TriggerNIS)
  3329.  
  3330. if g_navalguns_complete ~= true then
  3331. Objective_Complete(OBJ_NavalGuns, false)
  3332. end
  3333.  
  3334. end,
  3335.  
  3336. OnFail = function()
  3337.  
  3338. -- tell the player they failed
  3339. --Util_StartIntel(EVENTS.NavalGuns_Fail)
  3340.  
  3341. end,
  3342.  
  3343. SitRep = {
  3344. Movie = "SR_06-02",
  3345. Force = true,
  3346. SpeechTiming =
  3347. {
  3348. { 1.4, ACTOR.McKay, 260280 },
  3349. { 4.8, ACTOR.McKay, 260290 },
  3350. },
  3351. },
  3352.  
  3353. Title = 269060,
  3354. Description = 269061,
  3355. Type = OT_Primary,
  3356. TitleEnd = 269069,
  3357. Icon = IT_P_Attack,
  3358.  
  3359. }
  3360.  
  3361. end
  3362.  
  3363.  
  3364. -------------------------------------------------------------------------
  3365.  
  3366. -- AXIS HQ - Functions
  3367.  
  3368. -------------------------------------------------------------------------
  3369.  
  3370. -- added with the 'Bridge' check
  3371. function AxisHQ_Init()
  3372.  
  3373. sg_hqmob = SGroup_CreateTable("sg_hqmob%d", 5)
  3374. sg_hqmob_all = SGroup_CreateIfNotFound("sg_hqmob_all")
  3375. sg_hqmob_lead = SGroup_CreateIfNotFound("sg_hqmob_lead")
  3376.  
  3377. -- how many axis squads are allowed to be left
  3378. -- in the defender group 'only'
  3379. g_axishq_surrender = 5
  3380. -- how many traks defend the gate
  3381. g_axishq_traks = 2
  3382. -- counter for knocking on the front door of the HQ
  3383. g_axishq2_theyrehere = 0
  3384. -- how high the counter has to get before that spawn point shuts off
  3385. g_axishq2_herelimit = 10
  3386.  
  3387. -- multiply by the delay in of the rule AxisHQ_Defense1()
  3388. -- to get number of seconds
  3389. g_axishq2_gotime = 50
  3390. -- counter for gotime comparison
  3391. g_axishq2_counter = 0
  3392.  
  3393. -- allows the axis to keep spawning to create a 'wave' of enemy troops
  3394. g_axishq2_waveON = true
  3395.  
  3396. -- number of squads produced from each spawn point
  3397. -- will scale up, especially after one of the points
  3398. -- gets disabled
  3399. g_axishq2_squads = 3
  3400.  
  3401. t_axishq = {
  3402. allowspawn = {true, true},
  3403. spawn = {mkr_axishq2_spawn1, mkr_axishq2_spawn3},
  3404. egroup = {eg_axishq2_[2], eg_axishq2_[1]},
  3405. path = {
  3406. {"pth_axishq2_def1", "pth_axishq2_def2", "pth_axishq2_def1", "pth_axishq2_def2", "pth_axishq2_def1", "pth_axishq2_def2"},
  3407. {"pth_axishq2_def3", "pth_axishq2_def4", "pth_axishq2_def3", "pth_axishq2_def4", "pth_axishq2_def3", "pth_axishq2_def4"}},
  3408. sgroup = {
  3409. {sg_finalaxis[13], sg_finalaxis[14], sg_finalaxis[15], sg_finalaxis[4], sg_finalaxis[5], sg_finalaxis[6],},
  3410. {sg_finalaxis[7], sg_finalaxis[8], sg_finalaxis[9], sg_finalaxis[10], sg_finalaxis[11], sg_finalaxis[12],}},
  3411. target = {mkr_axishq2_spawn5, mkr_axishq2_spawn4, mkr_axishq2_rally1},
  3412. territory = {eg_territory9, eg_territory10},
  3413. spawncheck = {{}, {}}
  3414. }
  3415.  
  3416. for i = 1, 2 do
  3417. for y = 1, g_axishq2_squads do
  3418. t_axishq.spawncheck[i][y] = false
  3419. end
  3420. end
  3421.  
  3422.  
  3423.  
  3424. local path = {"pth_axishq2_gate1", "pth_axishq2_gate2", "pth_axishq2_gate3"}
  3425. local pause = {34, 0, 17}
  3426. for i = 1, 3 do
  3427. Util_CreateSquadsAtMarker(player2, sg_finalaxis[i], SBP.AXIS.GRENADIER, mkr_axishq2_spawn3, 1)
  3428. SGroup_AddGroup(sg_finalaxis_all, sg_finalaxis[i])
  3429. Cmd_SquadPath(sg_finalaxis[i], path[i], true, true, true, pause[i])
  3430. end
  3431.  
  3432. Rule_AddInterval(AxisHQ_Check_Gate, 5)
  3433. Rule_AddInterval(AxisHQ_Check_Chokepoint, 5)
  3434.  
  3435. -- other enemy behavior
  3436. RightSide_Kickoff()
  3437. end
  3438.  
  3439.  
  3440.  
  3441.  
  3442. -- have squads mill around the hq to add life
  3443. function AxisHQ_OfficerManager()
  3444.  
  3445. if g_axishq_endofficers then
  3446.  
  3447. -- they all run inside
  3448. if SGroup_IsEmpty(sg_axishq_officers_all)== false then
  3449. Cmd_Garrison(sg_axishq_officers_all, eg_axishq2_1)
  3450. end
  3451. Rule_RemoveMe()
  3452.  
  3453. else
  3454. local home = {mkr_axishq2_spawn3, mkr_axishq2_spawn1}
  3455. local wander = {mkr_finalmortar3, mkr_axishq2_spawn3, mkr_finalmortar1, mkr_axishq2_spawn1, mkr_finalmortar2, marker105, mkr_axishq2_prox}
  3456. for i = 1, 3 do
  3457. local rand = World_GetRand(1, table.getn(wander))
  3458. local pos = wander[rand]
  3459. if SGroup_IsEmpty(sg_axishq_officers[i]) then
  3460. Util_CreateSquadsAndGarrisonExit(player2, sg_axishq_officers[i], Util_RandomOffSBP(), eg_axishq2_1, 1, pos)
  3461. SGroup_AddGroup(sg_axishq_officers_all, sg_axishq_officers[i])
  3462. break
  3463. else
  3464. if SGroup_IsUnderAttack(sg_axishq_officers[i], false, 15) then
  3465. Cmd_MoveToClosestMarker(sg_axishq_officers[i], home)
  3466. elseif SGroup_IsMoving(sg_axishq_officers[i], true) == false then
  3467. Cmd_Move(sg_axishq_officers[i], pos)
  3468. break
  3469. end
  3470. end
  3471. end
  3472.  
  3473. end
  3474.  
  3475. end
  3476.  
  3477.  
  3478. -- returns a random SBP for the rule above
  3479. function Util_RandomOffSBP()
  3480. local sbps = {SBP.AXIS.OFFICER, SBP.AXIS.VOLKSGRENADIER, SBP.AXIS.OFFICER, SBP.AXIS.GRENADIER, SBP.AXIS.OFFICER, SBP.AXIS.PIONEER, SBP.AXIS.STORMTROOPER}
  3481. local rand = World_GetRand(1, table.getn(sbps))
  3482. return sbps[rand]
  3483. end
  3484.  
  3485.  
  3486.  
  3487.  
  3488. -- triggered by AxisHQ_Check_Chokepoint( ) or completing 'Naval Guns'
  3489. function AxisHQ_Obj_GrantDelay()
  3490. print("adding axis hq")
  3491. Objective_Start(OBJ_AxisHQ)
  3492.  
  3493. end
  3494.  
  3495.  
  3496.  
  3497.  
  3498. -- checks if the gate squad is attacked or if the
  3499. -- next proximity marker is crossed
  3500. function AxisHQ_Check_Gate()
  3501.  
  3502. -- if the gate crew gets attacked
  3503. if SGroup_IsUnderAttack(sg_finalaxis_all, false, 7) then
  3504.  
  3505. -- add the gate defense rule
  3506. Rule_AddInterval( AxisHQ_Gate_Manager, 5)
  3507.  
  3508. Rule_RemoveMe()
  3509.  
  3510. -- or someone crosses the gate
  3511. elseif Prox_ArePlayersNearMarker(player1, mkr_axishq2_spawn5, false, 30) then
  3512.  
  3513. -- order the gate defenders to get over there
  3514. if SGroup_IsEmpty(sg_finalaxis_all) == false then
  3515. Cmd_Stop(sg_finalaxis_all)
  3516. Cmd_AttackMove(sg_finalaxis_all, Marker_GetPosition(mkr_axishq2_spawn5), nil, nil, 20)
  3517. end
  3518.  
  3519. -- add the gate defense rule
  3520. Rule_AddInterval( AxisHQ_Gate_Manager, 5)
  3521.  
  3522. Rule_RemoveMe()
  3523. end
  3524. end
  3525.  
  3526.  
  3527. -- the Gate Defense manager is meant to be a fast attack group
  3528. -- make a halftrak and send it to the front
  3529. -- once it comes under attack, create a squad and have them defend it
  3530. function AxisHQ_Gate_Manager()
  3531.  
  3532. -- the default position
  3533. local pos = Marker_GetPosition(mkr_axishq2_spawn5)
  3534. -- if one of the groups is under attack
  3535. for i = 1, 5 do
  3536. if SGroup_IsEmpty(sg_finalaxis[i]) == false and SGroup_IsUnderAttack(sg_finalaxis[i], false, 7) then
  3537. -- store the position
  3538. pos = SGroup_GetPosition_EVEN_IF_EMPTY(sg_finalaxis[i])
  3539. break
  3540. end
  3541. end
  3542.  
  3543. -- the creation
  3544. for i = 1, 2 do
  3545. if SGroup_IsEmpty(sg_axishq_trak[i]) then
  3546. Util_CreateSquadsAtMarker(player2, sg_axishq_trak[i], SBP.AXIS.HALFTRACK, mkr_axishq2_spawn3, 1)
  3547. Util_CreateSquadsAndGarrison( player2, sg_finalaxis[i+3], SBP.AXIS.GRENADIER, sg_axishq_trak[i], 1 )
  3548. Util_GrantRandomUpgrade(sg_finalaxis[i+3])
  3549. Cmd_AttackMove(sg_axishq_trak[i], pos)
  3550. break
  3551. end
  3552. end
  3553.  
  3554. -- the unloading
  3555. for i = 1, 2 do
  3556. if SGroup_IsEmpty(sg_axishq_trak[i]) == false and SGroup_IsUnderAttack(sg_axishq_trak[i], false, 7) then
  3557.  
  3558. Cmd_Stop(sg_axishq_trak[i])
  3559. Cmd_Ungarrison(sg_axishq_trak[i], SGroup_GetPosition_EVEN_IF_EMPTY(sg_axishq_trak[i]))
  3560.  
  3561. end
  3562. end
  3563.  
  3564. -- do this last so all the stuff above has a chance to happen
  3565. if g_axishq_granted then
  3566. Rule_RemoveMe()
  3567. end
  3568.  
  3569. end
  3570.  
  3571.  
  3572.  
  3573.  
  3574.  
  3575.  
  3576.  
  3577.  
  3578.  
  3579. -- checks the choke point to the Axis HQ
  3580. -- this is the 'only' way into the Axis HQ
  3581. -- by being here, if the 'Naval Guns' obj has
  3582. -- not finished the player will trigger the Axis HQ obj
  3583. function AxisHQ_Check_Chokepoint()
  3584.  
  3585. if Prox_ArePlayersNearMarker(player1, mkr_axishq2_spawn4, false, 30) or Prox_ArePlayersNearMarker(player1, mkr_axishq2_spawn5, false, 30) then
  3586.  
  3587. -- for the axis officers mingling around
  3588. g_axishq_endofficers = true
  3589.  
  3590. t_axishq_approach[1] = true
  3591.  
  3592. -- order the gate defenders to get over there
  3593. if SGroup_IsEmpty(sg_finalaxis_all) == false then
  3594. Cmd_Stop(sg_finalaxis_all)
  3595. Cmd_AttackMove(sg_finalaxis_all, Marker_GetPosition(mkr_axishq2_spawn4), nil, nil, 30)
  3596. end
  3597.  
  3598. if g_axishq_granted ~= true then
  3599. print("chokepoint > axis hq")
  3600. -- for the 'Naval Guns' obj
  3601. -- stops that obj from adding this one
  3602. g_axishq_granted = true
  3603. -- adds the obj
  3604. Rule_AddOneShot(AxisHQ_Obj_GrantDelay, 0)
  3605. end
  3606.  
  3607. --mods the attack markers for the tanks
  3608. t_TPB_marker = {mkr_bridgedefense4, mkr_bridge_stugdef2, mkr_axishq2_spawn5, mkr_axishq2_spawn4, }
  3609.  
  3610. -- here's the combat manager
  3611. Rule_AddInterval(AxisHQ_Defense1, 5)
  3612. if Rule_Exists(AxisHQ_Defense1_Track) == false then
  3613. g_axishq_defdelay = 40
  3614. Rule_AddInterval(AxisHQ_Defense1_Track, g_axishq_defdelay)
  3615. end
  3616. -- mortar squads to defend the HQ
  3617. Rule_AddInterval(AxisHQ_MortarSquads, 27)
  3618.  
  3619.  
  3620. Rule_RemoveMe()
  3621. end
  3622.  
  3623. end
  3624.  
  3625.  
  3626.  
  3627. -- give the player instructions when close to the HQ
  3628. function AxisHQ_Check_Prox()
  3629.  
  3630. if Prox_ArePlayersNearMarker(player1, mkr_axishq2_prox, false, 40) or EGroup_IsUnderAttack(eg_axishq2, false, 10) then
  3631.  
  3632. --Once the player is Firing on the German HQ
  3633. Util_PlayMusic("Sound/Music/sp/m06/M06_Ob3_Firing_on_AxisHQ", 5, 2)
  3634.  
  3635. -- tell the player
  3636. Util_StartIntel(EVENTS.AxisHQ_KeepAttacking)
  3637.  
  3638. Rule_RemoveMe()
  3639. end
  3640.  
  3641. end
  3642. function AxisHQ_Check_Underattack()
  3643. if EGroup_IsUnderAttack(eg_axishq2, false, 10) then
  3644. Rule_AddInterval(AxisHQ_Stug_AmbushResponse, 12)
  3645. Rule_RemoveMe()
  3646. end
  3647. end
  3648.  
  3649. function AxisHQ_Stug_AmbushResponse()
  3650. local sgroup = {sg_axishq_stug1, sg_axishq_stug2}
  3651. local marker = {mkr_retreat5, mkr_retreat6}
  3652. for i = 1, 2 do
  3653. if SGroup_IsEmpty(sgroup[i]) == false then
  3654.  
  3655. if SGroup_IsUnderAttack(sgroup[i], false, 10) then
  3656.  
  3657. local sgtemp = SGroup_CreateIfNotFound("sgtemp")
  3658.  
  3659. SGroup_GetLastAttacker( sgroup[i], sgtemp )
  3660. Cmd_Move(sgroup[i], SGroup_GetPosition_EVEN_IF_EMPTY(sgtemp), nil, nil, nil, World_GetRand(2, 5), 15)
  3661. SGroup_Clear(sgtemp)
  3662.  
  3663. elseif SGroup_IsMoving(sgroup[i], false) then
  3664.  
  3665. else
  3666. Cmd_AttackMove(sgroup[i], marker[i])
  3667. end
  3668.  
  3669. end
  3670. end
  3671.  
  3672. end
  3673.  
  3674.  
  3675. -- create a tank patrol because the player didn't complete 'Naval Guns'
  3676. function AxisHQ_Tank_Patrol_NoGuns()
  3677.  
  3678. if g_navalguns_complete then
  3679.  
  3680. Rule_RemoveMe()
  3681.  
  3682. else
  3683.  
  3684. for i = 1, 2 do
  3685. if SGroup_IsEmpty(sg_axishq_tank[i]) and Prox_ArePlayersNearMarker(player1, mkr_bridge_spawn, false, 40) == false then
  3686. Util_CreateSquadsAtMarker(player2, sg_axishq_tank[i], Util_RandomTankSBP(), mkr_bridge_spawn, 1)
  3687. Cmd_SquadPath(sg_axishq_tank[i], "pth_axishq_tankpatrol", true, false, true, 0)
  3688. break
  3689. elseif SGroup_IsMoving(sg_axishq_tank[i], false) == false then
  3690. -- get the tank moving again
  3691. Cmd_AttackMove(sg_axishq_tank[i], mkr_townsquare1)
  3692. end
  3693. end
  3694.  
  3695. end
  3696.  
  3697. end
  3698.  
  3699.  
  3700. -- create a tank patrol regardless of the navalguns
  3701. function AxisHQ_Tank_Patrol_Basic()
  3702.  
  3703. if EGroup_IsEmpty(eg_axis_motorpool) or EGroup_IsCapturedByPlayer(eg_territory3, player1, false) then
  3704.  
  3705. Rule_RemoveMe()
  3706.  
  3707. else
  3708. local marker = t_TPB_marker
  3709. local rand = World_GetRand(1, table.getn(marker))
  3710. for i = 3, 4 do
  3711. if SGroup_IsEmpty(sg_axishq_tank[i]) and SGroup_Count(sg_axis_tank_all) < 4 and Prox_ArePlayersNearMarker(player1, mkr_lowerdock_spawn, false, 40) == false then
  3712. -- create the squad support
  3713. Util_CreateSquadsAtMarker(player2, sg_axishq_tank[i], Util_RandomInfSBP2(), mkr_lowerdock5, 1)
  3714. --Util_GrantRandomUpgrade(sg_axishq_tank[i])
  3715. -- create the tank
  3716. Util_CreateSquadsAtMarker(player2, sg_axishq_tank[i], Util_RandomLightTankSBP(), mkr_lowerdock5, 1)
  3717. SGroup_AddGroup(sg_axis_tank_mp, sg_axishq_tank[i])
  3718.  
  3719. Cmd_AttackMove(sg_axishq_tank[i], marker[rand])
  3720. break
  3721. elseif SGroup_IsMoving(sg_axishq_tank[i], false) == false then
  3722. -- get the tank moving again
  3723. Cmd_AttackMove(sg_axishq_tank[i], mkr_townsquare1)
  3724. end
  3725. end
  3726.  
  3727. end
  3728.  
  3729. end
  3730.  
  3731.  
  3732. -- create mortar squads
  3733. function AxisHQ_MortarSquads()
  3734.  
  3735. if EGroup_IsEmpty(eg_axishq2_2) then
  3736.  
  3737. Rule_RemoveMe()
  3738.  
  3739. else
  3740. for i = 3, 1, -1 do
  3741. if SGroup_IsEmpty(sg_axishq_mortar[i]) and Prox_ArePlayersNearMarker(player1, mkr_axishq2_spawn1, false, 40) == false then
  3742. Util_CreateSquadsAtMarker(player2, sg_axishq_mortar[i], SBP.AXIS.MORTAR, mkr_axishq2_spawn1, 1) --[[ debug ]]
  3743. Cmd_Move(sg_axishq_mortar[i], mkr_finalmortar[i], true) -- squad doesn't move
  3744. break
  3745. end
  3746. end
  3747.  
  3748. end
  3749.  
  3750. end
  3751.  
  3752. function AxisHQ_Defense1()
  3753.  
  3754. -- remove when the base is dead
  3755. if EGroup_IsEmpty(eg_axishq2) then
  3756.  
  3757. Rule_RemoveMe()
  3758.  
  3759. else
  3760.  
  3761. for i = 1, 2 do
  3762. if EGroup_IsEmpty(t_axishq.egroup[i]) == false --[[and SGroup_Count(sg_finalaxis_[i]) <= 3]] then
  3763.  
  3764. for y = 1, g_axishq2_squads do
  3765.  
  3766. -- if the group is empty create the group inside the house
  3767. if t_axishq.allowspawn[i] == true then
  3768.  
  3769. if t_axishq.spawncheck[i][y] ~= true and SGroup_IsEmpty(t_axishq.sgroup[i][y]) then
  3770.  
  3771. -- spawn check
  3772. t_axishq.spawncheck[i][y] = true
  3773.  
  3774. if SGroup_IsInHoldEntity(sg_finalaxis_[i], false) == false then
  3775. Util_CreateSquadsAndGarrison(player2, t_axishq.sgroup[i][y], Util_RandomInfSBP(), eg_axishq2, 1)
  3776. elseif y > 1 then
  3777. Util_CreateSquadsAtMarker(player2, t_axishq.sgroup[i][y], Util_RandomInfSBP(), t_axishq.spawn[i], 1)
  3778. Cmd_AttackMove(t_axishq.sgroup[i][y], Marker_GetPosition(t_axishq.target[1]), nil, nil, 20)
  3779. else
  3780. Util_CreateSquadsAndGarrison(player2, t_axishq.sgroup[i][y], Util_RandomInfSBP2(), eg_axishq2, 1)
  3781. end
  3782.  
  3783. Util_GrantRandomUpgrade(t_axishq.sgroup[i][y])
  3784. SGroup_AddGroup(sg_finalaxis_[i], t_axishq.sgroup[i][y])
  3785. SGroup_AddGroup(sg_finalaxis_all, t_axishq.sgroup[i][y])
  3786.  
  3787. break
  3788. end
  3789.  
  3790. end
  3791.  
  3792. end
  3793.  
  3794. end
  3795.  
  3796. end
  3797.  
  3798. -- manage the number of squads being created
  3799. if g_axishq2_squads ~= 6 and ( EGroup_IsEmpty(eg_axishq2_1) or EGroup_IsEmpty(eg_axishq2_2) ) then
  3800. g_axishq2_squads = 6
  3801. end
  3802.  
  3803. end
  3804.  
  3805. end
  3806.  
  3807. function AxisHQ_Defense1_Track()
  3808.  
  3809. if EGroup_IsEmpty(eg_axishq2) then
  3810.  
  3811. Rule_RemoveMe()
  3812.  
  3813. else
  3814.  
  3815. -- allows for large waves to be created
  3816. -- avoids the constant flow of baddies
  3817. for i = 1, 2 do
  3818. if SGroup_IsEmpty(sg_finalaxis_[i]) or SGroup_Count(sg_finalaxis_[i]) <=1 then
  3819. t_axishq.allowspawn[i] = true
  3820.  
  3821. -- the gate to stop a continual flow
  3822. for y = 1, g_axishq2_squads do
  3823. t_axishq.spawncheck[i][y] = false
  3824. end
  3825.  
  3826. -- increase the delay
  3827. Rule_AddOneShot(AxisHQ_Defense1_DelayUpdate, 1)
  3828. Rule_RemoveMe()
  3829. break
  3830. else
  3831. t_axishq.allowspawn[i] = false
  3832. end
  3833. end
  3834.  
  3835. -- track attack targets
  3836. -- based on what territory the player has captured
  3837. -- send the attacks above to a different location
  3838. if table.getn(t_axishq.territory) > 0 then
  3839. if EGroup_IsCapturedByPlayer(t_axishq.territory[1], player1, false) then
  3840. if table.getn(t_axishq.target) > 2 then
  3841. table.remove(t_axishq.target, 1)
  3842. end
  3843. table.remove(t_axishq.territory, 1)
  3844. end
  3845. end
  3846.  
  3847. end
  3848.  
  3849. end
  3850.  
  3851. function AxisHQ_Defense1_DelayUpdate()
  3852. --[[ difficulty balance ]]
  3853. -- time between groups
  3854. if g_axishq_defdelay < 200 then
  3855. g_axishq_defdelay = g_axishq_defdelay+20
  3856. end
  3857. -- number of units spawned
  3858. if g_axishq_defdelay == 65 then
  3859. g_axishq2_squads = 4
  3860. elseif g_axishq_defdelay == 100 then
  3861. g_axishq2_squads = 5
  3862. end
  3863. if Rule_Exists(AxisHQ_Defense1_Track) == false then
  3864. Rule_AddInterval(AxisHQ_Defense1_Track, g_axishq_defdelay)
  3865. end
  3866. end
  3867.  
  3868. -- should generate a loop of enemies until the player takes out the axis HQ
  3869. function AxisHQ_Mob_Start()
  3870. if EGroup_IsEmpty(eg_axishq2_2) == false then
  3871.  
  3872. local sgroup = { all = sg_hqmob_all, lead = sg_hqmob_lead, mob = sg_hqmob}
  3873.  
  3874. -- pick a random mob
  3875. local mobs = {mobType.VG, mobType.HMG, mobType.AT, mobType.AT, mobType.VG}
  3876. local mType = mobs[World_GetRand(1,5)]
  3877.  
  3878. -- pick a random waypoint path
  3879. local paths = {
  3880. {mkr_axishq2_prox, mkr_axishq2_spawn4},
  3881. {mkr_finalmortar1, mkr_motorpool2},}
  3882. local path = paths[World_GetRand(1,2)]
  3883.  
  3884. local source = {stype = stype.BUILD, spawn = eg_axishq2, rally = mkr_axishq2}
  3885. local destination = {pace = pace.FAST, count = 0, move = true, way = path, capture = nil}
  3886. local dedication = true
  3887.  
  3888. -- add mob
  3889. MobRule_AddMob(player2, sgroup, mType, source, destination, dedication)
  3890.  
  3891. -- reset check
  3892. if Rule_Exists(AxisHQ_Mob_Reset) then
  3893. Rule_AddInterval(AxisHQ_Mob_Reset, 20)
  3894. end
  3895. end
  3896. end
  3897. -- reset once the mob gets too small
  3898. function AxisHQ_Mob_Reset()
  3899. if EGroup_IsEmpty(eg_axishq2_2) then
  3900. Rule_RemoveMe()
  3901. elseif SGroup_Count(eg_axishq2) < 2 and Rule_Exists(AxisHQ_Mob_Start) == false then
  3902. -- dif handle
  3903. if EGroup_IsUnderAttack(egroup) then
  3904. Rule_AddOneShot(AxisHQ_Mob_Start, 0)
  3905. else
  3906. Rule_AddOneShot(AxisHQ_Mob_Start, World_GetRand(30, 50))
  3907. end
  3908. end
  3909. end
  3910.  
  3911. -- make the axis surrender if they drop below a certain count
  3912. function AxisHQ_Surrender_Check()
  3913.  
  3914. if EGroup_IsEmpty(eg_axishq2_2) and EGroup_IsEmpty(eg_axishq2_1) then
  3915.  
  3916. --~ if SGroup_Count(sg_finalaxis_all) <= g_axishq_surrender then
  3917. --~
  3918. --~ -- is the player anywhere near the HQ?
  3919. if Prox_ArePlayersNearMarker(player1, mkr_axishq2_spawn1, false, 150) then
  3920. -- the player has won
  3921. Objective_Complete(OBJ_AxisHQ)
  3922.  
  3923. -- if not, the player gets the extra task of inspecting the damage
  3924. else
  3925. Rule_AddInterval(AxisHQ_PlayerNear_Check, 10)
  3926. end
  3927.  
  3928. Rule_RemoveMe()
  3929.  
  3930.  
  3931. else
  3932.  
  3933. -- dif handle
  3934. if EGroup_GetAvgHealth(eg_axishq2_2) < Util_DifVar({.6, .5, .5}) then
  3935. print("eg_axishq2_2 health is "..EGroup_GetAvgHealth(eg_axishq2_2))
  3936. EGroup_Kill(eg_axishq2_2)
  3937. end
  3938. if EGroup_GetAvgHealth(eg_axishq2_1) < Util_DifVar({.4, .3, .3}) then
  3939. print("eg_axishq2_1 health is "..EGroup_GetAvgHealth(eg_axishq2_1))
  3940. EGroup_Kill(eg_axishq2_1)
  3941. end
  3942.  
  3943. end
  3944.  
  3945. end
  3946.  
  3947. -- the intent hear is to 'make' the player inspect the damage
  3948. -- forcing the player to approach the HQ instead of just nuking it
  3949. -- from afar with Off Map Art - deg
  3950. function AxisHQ_PlayerNear_Check()
  3951.  
  3952. if Prox_ArePlayersNearMarker(player1, mkr_axishq2_spawn1, false, 40) then
  3953. -- the player has won delay
  3954. Rule_Add(AxisHQ_PlayerNear_Delay)
  3955.  
  3956. Rule_RemoveMe()
  3957. end
  3958.  
  3959. end
  3960.  
  3961. -- a delay to allow for extra speech comments
  3962. function AxisHQ_PlayerNear_Delay()
  3963. if Event_IsAnyRunning() == false then
  3964. -- the player has won
  3965. Objective_Complete(OBJ_AxisHQ)
  3966. Rule_RemoveMe()
  3967. end
  3968. end
  3969.  
  3970. -- make sure nothing else is in the way
  3971. -- the play the final NIS
  3972. function AxisHQ_TriggerNIS()
  3973.  
  3974. if Event_IsAnyRunning() == false then -- and Objective_IsComplete(OBJ_NavalGuns) then
  3975.  
  3976. Rule_RemoveMe()
  3977.  
  3978. Util_StartNIS(EVENTS.NIS04)
  3979.  
  3980. Rule_Add(AxisHQ_TriggerNISOver)
  3981.  
  3982. end
  3983.  
  3984. end
  3985.  
  3986. -- once the NIS is over go here
  3987. -- and end the mission
  3988. function AxisHQ_TriggerNISOver()
  3989.  
  3990. if Event_IsAnyRunning() == false then
  3991.  
  3992. Game_EndSP( true, 229930, true)
  3993.  
  3994. Rule_RemoveMe()
  3995.  
  3996. end
  3997.  
  3998. end
  3999.  
  4000.  
  4001.  
  4002.  
  4003.  
  4004.  
  4005.  
  4006.  
  4007.  
  4008. function RightSide_Kickoff()
  4009.  
  4010. sg_axis_retreat = {}
  4011. for i = 1, 10 do
  4012. sg_axis_retreat[i] = SGroup_FromName("sg_axis_retreat"..i)
  4013. end
  4014.  
  4015. local markers = {
  4016. {mkr_retreat1, mkr_retreat4},--1
  4017. {mkr_motorpool1, mkr_retreat10},--2
  4018. {mkr_retreat11, mkr_retreat8},--3
  4019. {mkr_retreat13, mkr_retreat15},--4
  4020. {mkr_retreat13, mkr_retreat12},--5
  4021. {mkr_retreat12},--6
  4022. {mkr_retreat15, mkr_retreat14},--7
  4023. {mkr_retreat2, mkr_retreat3},--8
  4024. {mkr_retreat4, mkr_retreat6},--9
  4025. {mkr_retreat7, mkr_retreat10},--10
  4026. }
  4027. for i = 1, 10 do
  4028. Util_UnderConstantAttack_Add(sg_axis_retreat[i], markers[i], 1)
  4029. end
  4030.  
  4031. sg_axis_autocharge = SGroup_CreateTable("sg_axis_autocharge%d", 10)
  4032. t_counter_squads = {
  4033. {sgroup1 = sg_axis_retreat[1], sgroup2 = sg_axis_autocharge[1], egroup = eg_hmghouse13},
  4034. {sgroup1 = sg_axis_retreat[2], sgroup2 = sg_axis_autocharge[2], egroup = eg_2ndmotorpool},
  4035. {sgroup1 = sg_axis_retreat[3], sgroup2 = sg_axis_autocharge[3], egroup = eg_hmghouse7},
  4036. {sgroup1 = sg_axis_retreat[4], sgroup2 = sg_axis_autocharge[4], egroup = eg_hmghouse10},
  4037. {sgroup1 = sg_axis_retreat[6], sgroup2 = sg_axis_autocharge[6], egroup = eg_hmghouse9},
  4038. {sgroup1 = sg_axis_retreat[7], sgroup2 = sg_axis_autocharge[7], egroup = eg_hmghouse11},
  4039. {sgroup1 = sg_axis_retreat[8], sgroup2 = sg_axis_autocharge[8], egroup = eg_hmghouse13},
  4040. {sgroup1 = sg_axis_retreat[9], sgroup2 = sg_axis_autocharge[9], egroup = eg_hmghouse14},
  4041. {sgroup1 = sg_axis_retreat[10], sgroup2 = sg_axis_autocharge[10], egroup = eg_hmghouse8},
  4042. }
  4043. Rule_AddInterval(Enemy_CounterCharge_GenerateSquad, 5)
  4044.  
  4045. end
  4046.  
  4047.  
  4048. -- add a squad to the 'Under Constant Attack' check
  4049. function Util_UnderConstantAttack_Add(sgroupname, fallbacktable, attacklimit)
  4050. if t_constantattack == nil then
  4051. t_constantattack = {}
  4052. end
  4053.  
  4054. local insert = {sgroup = sgroupname, marker = fallbacktable, limit = attacklimit, underattack = 0}
  4055. table.insert(t_constantattack, insert)
  4056.  
  4057. if Rule_Exists(Util_UnderConstantAttack_Check) == false then
  4058. Rule_AddInterval(Util_UnderConstantAttack_Check, 5)
  4059. end
  4060. end
  4061. -- Under Constant Attack Check
  4062. -- seeks to make units fall back if they are under consistent attack for a period of time
  4063. -- as opposed to just getting shot at once in a given time space
  4064. -- they should also retreat if the number gets low.
  4065. function Util_UnderConstantAttack_Check()
  4066. local count = table.getn(t_constantattack)
  4067. if count == 0 then
  4068.  
  4069. Rule_RemoveMe()
  4070.  
  4071. else
  4072. for i = count, 1, -1 do
  4073. if SGroup_IsEmpty(t_constantattack[i].sgroup) then
  4074. table.remove(t_constantattack, i)
  4075. --print("group "..i.." empty")
  4076. else
  4077. local this = t_constantattack[i]
  4078.  
  4079. if SGroup_IsUnderAttack(this.sgroup, false, 5) then
  4080.  
  4081. this.underattack = this.underattack+1
  4082. --print("group "..i.." is under attack")
  4083.  
  4084. else
  4085. this.underattack = 0
  4086. end
  4087.  
  4088. -- not to be used on tanks
  4089. if this.underattack > this.limit --[[or SGroup_Count(this.sgroup) < 2]] then
  4090.  
  4091. Cmd_Move(this.sgroup, this.marker[1])
  4092. --Cmd_Retreat(this.sgroup, Marker_GetPosition(this.marker[1]))
  4093. --print("group "..i.." is retreating")
  4094.  
  4095. this.limit = this.limit+1
  4096.  
  4097. if table.getn(this.marker) > 1 then
  4098. table.remove(this.marker, 1)
  4099. end
  4100. end
  4101. end
  4102. end
  4103. end
  4104. end
  4105.  
  4106.  
  4107.  
  4108. -- if the target squad gets attacked
  4109. -- counter charge with the second generated squad
  4110. function Enemy_CounterCharge_GenerateSquad()
  4111. local count = table.getn(t_counter_squads)
  4112. if count == 0 then
  4113. Rule_RemoveMe()
  4114. else
  4115. for i = count, 1, -1 do
  4116. local this = t_counter_squads[i]
  4117. if SGroup_IsEmpty(this.sgroup1) == false and SGroup_IsUnderAttack(this.sgroup1, false, 10) then
  4118. if EGroup_IsEmpty(this.egroup) == false then
  4119. if SGroup_IsEmpty(this.sgroup2) then
  4120. Util_CreateSquadsAtMarker(player2, this.sgroup2, Util_RandomInfSBP2(), EGroup_GetPosition_EVEN_IF_EMPTY(this.egroup), 1)
  4121. end
  4122. Cmd_AttackMove(this.sgroup2, SGroup_GetPosition_EVEN_IF_EMPTY(this.sgroup1))
  4123. table.remove(t_counter_squads, i)
  4124. else
  4125. table.remove(t_counter_squads, i)
  4126. end
  4127. elseif SGroup_IsEmpty(this.sgroup1) then
  4128. table.remove(t_counter_squads, i)
  4129. end
  4130. end
  4131. end
  4132. end
  4133.  
  4134.  
  4135.  
  4136.  
  4137.  
  4138.  
  4139.  
  4140.  
  4141.  
  4142.  
  4143.  
  4144.  
  4145.  
  4146.  
  4147.  
  4148. -------------------------------------------------------------------------
  4149. --[[ Random Util Stuff ]]
  4150. -------------------------------------------------------------------------
  4151. -- should create the specified EBP if the player does not already have one
  4152. function Util_CreateEntitiesIfNotFoundAtMarker(player, egroup, ebp, pos)
  4153. if Player_HasBuilding( player, ebp ) ~= true then
  4154. Util_CreateEntities(player, egroup, ebp, pos, 1)
  4155. end
  4156. end
  4157.  
  4158. -- returns a random offset, same as Util_GetRandomPosition
  4159. -- but for a position value
  4160. function Util_GetRandOffset(pos, dist)
  4161. if (scartype(pos) == ST_MARKER) then
  4162. pos = Marker_GetPosition(pos)
  4163. end
  4164.  
  4165. local newpos = pos
  4166. newpos.x = World_GetRand(dist*-1, dist)
  4167. newpos.z = World_GetRand(dist*-1, dist)
  4168. return newpos
  4169. end
  4170.  
  4171. -- returns a random SBP for an armoured vehicle
  4172. function Util_RandomTankSBP()
  4173. local sbps = {SBP.AXIS.OSTWIND, SBP.AXIS.STUG, SBP.AXIS.HALFTRACK_STUKA}
  4174. local rand = World_GetRand(1, table.getn(sbps))
  4175. return sbps[rand]
  4176. end
  4177.  
  4178. -- returns a random SBP for a lighter armoured vehicle
  4179. function Util_RandomLightTankSBP()
  4180. local sbps = {SBP.AXIS.MOTORCYCLE, SBP.AXIS.PUMA, SBP.AXIS.HALFTRACK, SBP.AXIS.HALFTRACK_FLAME}
  4181. local rand = World_GetRand(1, table.getn(sbps))
  4182. return sbps[rand]
  4183. end
  4184.  
  4185. -- returns a random SBP for infantry
  4186. function Util_RandomInfSBP()
  4187. local sbps = {SBP.AXIS.VOLKSGRENADIER, SBP.AXIS.GRENADIER, SBP.AXIS.VOLKSGRENADIER}
  4188. local rand = World_GetRand(1, table.getn(sbps))
  4189. return sbps[rand]
  4190. end
  4191.  
  4192. -- returns a random SBP for infantry
  4193. function Util_RandomInfSBP2()
  4194. local sbps = {SBP.AXIS.VOLKSGRENADIER, SBP.AXIS.GRENADIER, SBP.AXIS.VOLKS_2PANZERF}
  4195. local rand = World_GetRand(1, table.getn(sbps))
  4196. return sbps[rand]
  4197. end
  4198.  
  4199. -- returns a random SBP for infantry
  4200. function Util_RandomInfSBP3()
  4201. local sbps = {SBP.AXIS.VOLKSGRENADIER, SBP.AXIS.GRENADIER, SBP.AXIS.VOLKS_2PANZERF, SBP.AXIS.HEAVYMG}
  4202. local rand = World_GetRand(1, table.getn(sbps))
  4203. return sbps[rand]
  4204. end
  4205.  
  4206. -- performs the Instant Upgrade but uses a randomly selected weapon
  4207. function Util_GrantRandomUpgrade(sgroup)
  4208.  
  4209. local upgrades1 = {false, UPG.AXIS.GREN_MG42, false, UPG.AXIS.GREN_MG42, false, false, false, false}
  4210. local upgrades2 = {false, UPG.AXIS.GREN_MG42, false, UPG.AXIS.GREN_MG42, false, false, false, false, UPG.AXIS.GREN_PANZERSCHRECK}
  4211. local upgrades3 = {false, UPG.AXIS.GREN_MG42, false, UPG.AXIS.GREN_MG42, false, UPG.AXIS.GREN_MG42, false, false, UPG.AXIS.GREN_PANZERSCHRECK}
  4212. local upgrades = Util_DifVar({upgrades1, upgrades2, upgrades3})
  4213. --[[ change the loadout set
  4214. if g_navalguns_complete then
  4215. table.insert(upgrades, UPG.AXIS.PANZERSCHRECK)
  4216. table.insert(upgrades, UPG.AXIS.PANZERSCHRECK)
  4217. end]]
  4218.  
  4219. local rand = World_GetRand(1, table.getn(upgrades))
  4220. if upgrades[rand] ~= false then
  4221. Cmd_InstantUpgrade(sgroup, upgrades[rand])
  4222. end
  4223. end
  4224.  
  4225. -- toggles invulnerability for a squad selection
  4226. function Util_InvulnerableSelection(boolean)
  4227. if boolean then
  4228. if Rule_Exists(_InvulnerableSelection) == false then
  4229. Rule_AddInterval(_InvulnerableSelection, 5)
  4230. end
  4231. else
  4232. Rule_RemoveIfExist(_InvulnerableSelection)
  4233. end
  4234. end
  4235.  
  4236. function _InvulnerableSelection(boolean)
  4237. _invsgroup = SGroup_CreateIfNotFound("_invsgroup")
  4238. if SGroup_IsEmpty(_invsgroup) == false then
  4239. SGroup_SetInvulnerable(_invsgroup, false)
  4240. end
  4241. Misc_GetSelectedSquads(_invsgroup, false)
  4242. if SGroup_IsEmpty(_invsgroup) == false then
  4243. SGroup_SetInvulnerable(_invsgroup, true)
  4244. end
  4245. end
  4246.  
  4247.  
  4248. function Util_OffCameraPos(player, origin, destination)
  4249. local pos = World_GetHiddenPositionOnPath(player, origin, destination, CHECK_OFFCAMERA)
  4250. if pos == nil then
  4251. pos = Marker_GetPosition(origin)
  4252. end
  4253. return pos
  4254. end
  4255.  
  4256.  
  4257. -------------------------------------------------------------------------
  4258. -------------------------------------------------------------------------
  4259.  
  4260. function Util_AddGenericEventCue_OnClick(title, descrip, functioName)
  4261. UI_CreateEventCueClickable( CUE.NORMAL.icon, CUE.NORMAL.sound, title, descrip, functioName, -1, false)
  4262. end
  4263.  
  4264. function Util_AddCombatEventCue_OnClick(title, descrip, functioName)
  4265. UI_CreateEventCueClickable( CUE.NORMAL.icon, CUE.NORMAL.sound, title, descrip, functioName, -1, false)
  4266. end
  4267.  
  4268. function Util_MergeSquads()
  4269.  
  4270. _merge = SGroup_CreateIfNotFound("_merge")
  4271. Misc_GetSelectedSquads(_merge, false)
  4272.  
  4273. if SGroup_IsEmpty(_merge) == false and SGroup_CountSpawned(_merge) > 1 then
  4274. local squadZero = SGroup_GetSpawnedSquadAt(_merge, 1)
  4275. for i = SGroup_CountSpawned(_merge), 2, -1 do
  4276. local squadID = SGroup_GetSpawnedSquadAt(_merge, i)
  4277. if ( Squad_Count(squadZero) + Squad_Count(squadZero) ) <= Squad_GetMax(squadZero)
  4278. and Squad_GetBaseUnitName(squadZero) == Squad_GetBaseUnitName(squadID) then
  4279. Squad_Merge(squadZero, squadID)
  4280. end
  4281. end
  4282. end
  4283.  
  4284. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement