--[[ Copyright (c) The OpenRA Developers and Contributors This file is part of OpenRA, which is free software. It is made available to you under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. For more information, see COPYING. ]] WelcomeTeam = { Wel1, Wel2, Wel3, Wel4, Wel5 } Civilians = { Actor111, Actor112, Actor113, Actor114, Actor115, Actor116, Actor117, Actor118, Actor119, Actor120, Actor121 } RunForHelpCivs = { Actor109, Actor110 } CiviliansBuildings = { Actor35, Actor36, Actor37, Actor38, Actor39, Actor40, Actor41, Actor42, Actor43, Actor44, Actor45, Actor54, Actor55, Actor56, Actor57, Actor58 } OilDerricks = { Actor49, Actor50, Actor51, Actor52 } CivsMoneyBuildings = { Actor37, Actor41, Actor42, Actor44, Actor58 } ReinforcementsMammoths = { "htnk", "htnk" } ReinforcementsEngineers = { "e6", "e6", "e6", "e6", "e6" } CiviliansHelpTeam = { "mtnk", "mtnk", "msam" } BaseDefenseTeam = { Def1, Def2, Def3, Def4 } PatrolTeam = { Actor103, Actor122, Actor123 } PatrolPath = { waypoint2.Location, waypoint3.Location, waypoint4.Location, waypoint5.Location } CapturableStructures = { "afld", "hand", "hq", "nuke", "silo", "proc", "sam" } IonCannonTargets = { { "obli", "gun", "gtwr" }, { "harv" } } WelcomeTeamCellTrigger = { CPos.New(17,59), CPos.New(18,59), CPos.New(19,59), CPos.New(17,60), CPos.New(18,60), CPos.New(19,60), CPos.New(25,53), CPos.New(25,54), CPos.New(25,55), CPos.New(26,53), CPos.New(26,54), CPos.New(26,55) } CivsGDIHelpCellTrigger = { CPos.New(13,7) } GDIBaseEntranceCells = { CPos.New(16,5), CPos.New(16,6), CPos.New(16,7), CPos.New(16,8), CPos.New(17,4), CPos.New(17,5), CPos.New(17,6), CPos.New(17,7), CPos.New(17,8), CPos.New(18,4), CPos.New(18,5), CPos.New(19,4), CPos.New(8,15), CPos.New(9,15), CPos.New(10,15), CPos.New(11,15), CPos.New(12,15), CPos.New(13,15), CPos.New(14,15), CPos.New(9,16), CPos.New(10,16), CPos.New(11,16), CPos.New(12,16), CPos.New(13,16), CPos.New(14,16) } InnerGDIBaseEntranceCells = { CPos.New(7,5), CPos.New(7,6), CPos.New(7,7), CPos.New(8,6), CPos.New(8,7), CPos.New(9,6), CPos.New(9,7) } CaptureStructures = function(actor) local structures = Nod.GetActorsByTypes(CapturableStructures) local distance = 500 local captst = nil Utils.Do(structures, function(st) if not actor.IsDead and not st.IsDead and distance > (math.abs((actor.Location - st.Location).X) + math.abs((actor.Location - st.Location).Y)) then distance = math.abs((actor.Location - st.Location).X) + math.abs((actor.Location - st.Location).Y) captst = st end end) if captst then actor.Capture(captst) end end SendGDIAirstrike = function() if not GDIhq.IsDead and GDIhq.Owner == GDI then local target = GetAirstrikeTarget(Nod) if target then GDIhq.TargetAirstrike(target, Angle.SouthEast) else Trigger.AfterDelay(DateTime.Seconds(5), SendGDIAirstrike) end end end OilDerricksAstkSent = false OilDerricksAirstrike = function() if not OilDerricksAstkSent then SendGDIAirstrike() OilDerricksAstkSent = true end end CivsRunning = false RunForHelp = function() if not CivsRunning then Utils.Do(RunForHelpCivs, function(actor) actor.Move(CPos.New(53,45)) actor.Move(waypoint6.Location) actor.Move(waypoint4.Location) actor.Move(waypoint9.Location) actor.Move(waypoint2.Location) actor.Move(waypoint12.Location) actor.Move(waypoint6.Location) end) Trigger.OnEnteredFootprint(CivsGDIHelpCellTrigger, function(a, id) if a == RunForHelpCivs[1] or a == RunForHelpCivs[2] then Reinforcements.Reinforce(GDI, CiviliansHelpTeam, { CPos.New(2,9), CPos.New(3,9) }, 30, function(a) a.AttackMove(waypoint2.Location) a.AttackMove(waypoint9.Location) a.AttackMove(waypoint8.Location) IdleHunt(a) end) Trigger.RemoveFootprintTrigger(id) end end) CivsRunning = true local cam = Actor.Create("camera", true, { Owner = Nod, Location = CPos.New(53,44) }) Trigger.AfterDelay(125, cam.Destroy) Media.DisplayMessage(UserInterface.GetFluentMessage("civilians-running"), UserInterface.GetFluentMessage("nod-soldier")) end end CivsBuildingsToDestroy = 0 CheckVillageDestruction = function() CivsBuildingsToDestroy = CivsBuildingsToDestroy - 1 if CivsBuildingsToDestroy == 2 then Media.DisplayMessage(UserInterface.GetFluentMessage("village-destruction-warning")) elseif CivsBuildingsToDestroy == 0 then Reinforcements.Reinforce(GDI, ReinforcementsMammoths, { CPos.New(2,9), CPos.New(3,9) }, 40, function(a) a.AttackMove(waypoint11.Location) a.AttackMove(waypoint5.Location) a.AttackMove(waypoint4.Location) a.AttackMove(waypoint6.Location) IdleHunt(a) end) end end GuardBase = function() Utils.Do(GDIBase, function(building) GuardBuilding(building) end) end GuardBuilding = function(building) Trigger.OnDamaged(building, function(slf, atk, dmg) if atk.Type ~= "player" and not atk.IsDead and atk.Owner == Nod then Utils.Do(BaseDefenseTeam, function(guard) if not guard.IsDead and not building.IsDead then if guard.Stance == "Defend" then guard.Stop() guard.Stance = "AttackAnything" guard.AttackMove(atk.Location, 3) Trigger.OnIdle(guard, function() guard.AttackMove(waypoint12.Location, 3) guard.Stance = "Defend" Trigger.ClearAll(guard) end) end end end) end end) end StartGuard = function() Trigger.OnAllKilled(BaseDefenseTeam, function() table.insert(UniqueTeamsQueue, { team = DefenseTeams, job = "defend" }) end) Utils.Do(BaseDefenseTeam, function(guard) guard.Stance = "Defend" end) end StartPatrol = function() Trigger.OnAllKilled(PatrolTeam, function() table.insert(UniqueTeamsQueue, { team = PatrolTeams, job = "patrol" }) end) Utils.Do(PatrolTeam, function(a) Trigger.OnKilled(a, function() Utils.Do(PatrolTeam, function(a) if not a.IsDead then a.Stop() IdleHunt(a) end end) end) end) MoveAsGroup(PatrolTeam, PatrolPath, 1, true) end MoveAsGroup = function(team, path, i, loop) if i == 1 and not loop then Utils.Do(team, function(u) Trigger.OnDamaged(u, function() Utils.Do(team, function(u) if not u.IsDead then Trigger.Clear(u, "OnDamaged") IdleHunt(u) end end) end) end) end Utils.Do(team, function(a) if not a.IsDead then a.Stance = "AttackAnything" a.AttackMove(path[i], 2) Trigger.OnIdle(a, function() Trigger.Clear(a, "OnIdle") a.Stance = "Defend" local teamNumber = 0 local regrouped = false Utils.Do(team, function(a) if a.IsDead or a.Stance == "Defend" then teamNumber = teamNumber + 1 if teamNumber == #team then regrouped = true end end end) if regrouped then if i == #path then if loop == true then i = 1 else Trigger.AfterDelay(5, function() Utils.Do(team, function(a) if not a.IsDead then a.Stance = "AttackAnything" IdleHunt(a) end end) end) return end else i = i + 1 end Trigger.AfterDelay(20, function() MoveAsGroup(team, path, i, loop) end) end end) end end) end IonCannonOnline = false ICShotsCount = 0 FireIonCannon = function(timer) if IonCannonOnline then local ii = Utils.RandomInteger(1, 4) local targets = { } if ii < 3 then targets = Nod.GetActorsByTypes(IonCannonTargets[ii]) else targets = Nod.GetGroundAttackers() end if #targets > 0 then local rand = Utils.RandomInteger(1, #targets + 1) if not targets[rand].IsDead then GDIAdvComCenter.ActivateIonCannon(targets[rand].Location) if ICShotsCount < 2 then ICShotsCount = ICShotsCount + 1 if ICShotsCount > 1 then Nod.MarkFailedObjective(DestroyIonCannon) Trigger.ClearAll(GDIAdvComCenter) end end Trigger.AfterDelay(DateTime.Seconds(timer), function() FireIonCannon(timer) end) return end end Trigger.AfterDelay(DateTime.Seconds(1), function() FireIonCannon(timer) end) end end CheckObjectives = function() if GDI.HasNoRequiredUnits() then Nod.MarkCompletedObjective(EliminateAllGDI) end if Nod.HasNoRequiredUnits() then Nod.MarkFailedObjective(EliminateAllGDI) end Trigger.AfterDelay(25, CheckObjectives) end WorldLoaded = function() Nod = Player.GetPlayer("Nod") GDI = Player.GetPlayer("GDI") Camera.Position = PlayerStart.CenterPosition Flare = Actor.Create("flare", true, { Owner = Nod, Location = DefaultFlareLocation.Location }) Trigger.AfterDelay(DateTime.Minutes(1), Flare.Destroy) InitObjectives(Nod) EliminateAllGDI = AddPrimaryObjective(Nod, "eliminate-gdi-forces") FindAllCivMoney = AddSecondaryObjective(Nod, "take-civilians-money-crates") CheckObjectives() InitAi() Trigger.OnEnteredFootprint(WelcomeTeamCellTrigger, function(a, id) if a.Owner == Nod then Utils.Do(WelcomeTeam, function(a) if not a.IsDead then a.AttackMove(PlayerStart.Location) IdleHunt(a) end end) Trigger.RemoveFootprintTrigger(id) end end) Trigger.OnAllKilled(Civilians, function() local cargo = Reinforcements.ReinforceWithTransport(GDI, "tran", ReinforcementsEngineers, { CPos.New(0,32), waypoint10.Location }, { CPos.New(0,32) })[2] Utils.Do(cargo, function(engs) if engs.Type == "e6" then Trigger.OnIdle(engs, CaptureStructures) end end) end) Utils.Do(CiviliansBuildings, function(b) Trigger.OnKilled(b, CheckVillageDestruction) end) Utils.Do(OilDerricks, function(actor) Trigger.OnKilledOrCaptured(actor, OilDerricksAirstrike) end) Utils.Do(RunForHelpCivs, function(actor) Trigger.OnDiscovered(actor, RunForHelp) end) Trigger.OnEnteredFootprint(GDIBaseEntranceCells, function(a, id) if a.Owner == Nod and not BombTriggered then BombTriggered = true Trigger.AfterDelay(25, SendGDIAirstrike) Trigger.AfterDelay(150, SendGDIAirstrike) Trigger.AfterDelay(275, SendGDIAirstrike) Trigger.RemoveFootprintTrigger(id) end end) Trigger.OnCapture(GDIhq, function() GDIhq.GrantCondition("captured") end) Trigger.OnEnteredFootprint(InnerGDIBaseEntranceCells, function(a, id) if a.Owner == Nod and not InnerBaseEntered then InnerBaseEntered = true Reinforcements.Reinforce(GDI, ReinforcementsMammoths, { CPos.New(2,9), CPos.New(3,9) }, 40, IdleHunt) Trigger.RemoveFootprintTrigger(id) end end) Trigger.AfterDelay(5, function() StartPatrol() GuardBase() StartGuard() end) Trigger.OnAllKilled(CivsMoneyBuildings, function() Trigger.AfterDelay(1, function() Trigger.OnAllRemovedFromWorld(Utils.Where(Map.ActorsInWorld, function(a) return a.Type == "moneycrate" or a.Type == "smallmcrate" end), function() Nod.MarkCompletedObjective(FindAllCivMoney) end) end) end) Trigger.OnKilledOrCaptured(GDIAdvComCenter, function() if IonCannonOnline then IonCannonOnline = false else DestroyIonCannon = AddSecondaryObjective(Nod, "quickly-destroy-ion-cannon") end Nod.MarkCompletedObjective(DestroyIonCannon) PrepareOrcas() end) end