diff --git a/OpenRA.sln b/OpenRA.sln index d1d53e0ee3..a2e37de2a1 100644 --- a/OpenRA.sln +++ b/OpenRA.sln @@ -38,6 +38,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tiberian Dawn Lua scripts", mods\cnc\maps\nod03b\nod03b.lua = mods\cnc\maps\nod03b\nod03b.lua mods\cnc\maps\nod04a\nod04a.lua = mods\cnc\maps\nod04a\nod04a.lua mods\cnc\maps\nod04b\nod04b.lua = mods\cnc\maps\nod04b\nod04b.lua + mods\cnc\maps\nod05\nod05.lua = mods\cnc\maps\nod05\nod05.lua mods\cnc\maps\shellmap\shellmap.lua = mods\cnc\maps\shellmap\shellmap.lua EndProjectSection EndProject diff --git a/mods/cnc/maps/nod05/map.bin b/mods/cnc/maps/nod05/map.bin new file mode 100644 index 0000000000..cfd826e67f Binary files /dev/null and b/mods/cnc/maps/nod05/map.bin differ diff --git a/mods/cnc/maps/nod05/map.png b/mods/cnc/maps/nod05/map.png new file mode 100644 index 0000000000..4fc28e2470 Binary files /dev/null and b/mods/cnc/maps/nod05/map.png differ diff --git a/mods/cnc/maps/nod05/map.yaml b/mods/cnc/maps/nod05/map.yaml new file mode 100644 index 0000000000..430da16baa --- /dev/null +++ b/mods/cnc/maps/nod05/map.yaml @@ -0,0 +1,525 @@ +MapFormat: 7 + +RequiresMod: cnc + +Title: Warthog Hunt + +Description: Our brothers within GDI tell us of A-10 strike jets scheduled to be deployed here soon. Our suppliers have delivered new Surface to Air Missiles to aid you. Use the SAMs to defend your base, then seek out their base and destroy it. + +Author: Westwood Studios + +Tileset: DESERT + +MapSize: 64,64 + +Bounds: 4,12,57,45 + +Visibility: MissionSelector + +Type: Campaign + +Videos: + BackgroundInfo: sethpre.vqa + Briefing: nod5.vqa + GameStart: samsite.vqa + GameWon: insites.vqa + GameLost: flag.vqa + +Options: + Crates: False + Creeps: False + Fog: True + Shroud: True + AllyBuildRadius: False + FragileAlliances: False + StartingCash: 5000 + ConfigurableStartingUnits: False + ShortGame: False + +Players: + PlayerReference@GDI: + Name: GDI + Race: gdi + ColorRamp: 31,222,183 + Allies: GDI + Enemies: Nod + PlayerReference@Neutral: + Name: Neutral + OwnsWorld: True + NonCombatant: True + Race: gdi + Allies: GDI + Enemies: Nod + PlayerReference@Nod: + Name: Nod + Playable: True + AllowBots: False + Required: True + LockRace: True + Race: nod + LockColor: True + ColorRamp: 3,255,127 + LockSpawn: True + LockTeam: True + Allies: Nod + Enemies: GDI + +Actors: + Actor0: sbag + Location: 30,22 + Owner: Neutral + Actor1: sbag + Location: 29,22 + Owner: Neutral + Actor2: sbag + Location: 28,22 + Owner: Neutral + Actor3: sbag + Location: 23,22 + Owner: Neutral + Actor4: sbag + Location: 22,22 + Owner: Neutral + Actor5: sbag + Location: 21,22 + Owner: Neutral + Actor6: sbag + Location: 20,22 + Owner: Neutral + Actor7: sbag + Location: 19,22 + Owner: Neutral + Actor8: sbag + Location: 30,21 + Owner: Neutral + Actor9: sbag + Location: 19,21 + Owner: Neutral + Actor10: sbag + Location: 18,21 + Owner: Neutral + Actor11: sbag + Location: 30,20 + Owner: Neutral + Actor12: sbag + Location: 30,19 + Owner: Neutral + Actor13: sbag + Location: 30,18 + Owner: Neutral + Actor14: sbag + Location: 30,17 + Owner: Neutral + Actor15: sbag + Location: 16,15 + Owner: Neutral + Actor16: sbag + Location: 16,14 + Owner: Neutral + Actor17: sbag + Location: 28,13 + Owner: Neutral + Actor18: sbag + Location: 27,13 + Owner: Neutral + Actor19: sbag + Location: 26,13 + Owner: Neutral + Actor20: sbag + Location: 25,13 + Owner: Neutral + Actor21: sbag + Location: 24,13 + Owner: Neutral + Actor22: sbag + Location: 23,13 + Owner: Neutral + Actor23: sbag + Location: 22,13 + Owner: Neutral + Actor24: sbag + Location: 21,13 + Owner: Neutral + Actor25: sbag + Location: 20,13 + Owner: Neutral + Actor26: sbag + Location: 19,13 + Owner: Neutral + Actor27: sbag + Location: 18,13 + Owner: Neutral + Actor28: sbag + Location: 17,13 + Owner: Neutral + Actor29: sbag + Location: 16,13 + Owner: Neutral + Actor30: t18 + Location: 52,25 + Owner: Neutral + Actor31: t18 + Location: 54,31 + Owner: Neutral + Actor32: t18 + Location: 17,39 + Owner: Neutral + Actor33: t08 + Location: 17,43 + Owner: Neutral + Actor34: t08 + Location: 23,37 + Owner: Neutral + Actor35: t08 + Location: 22,35 + Owner: Neutral + Actor36: t08 + Location: 15,37 + Owner: Neutral + Actor37: rock2 + Location: 8,50 + Owner: Neutral + Actor38: rock5 + Location: 18,49 + Owner: Neutral + Actor39: t08 + Location: 19,48 + Owner: Neutral + Actor40: t08 + Location: 21,52 + Owner: Neutral + Actor42: t08 + Location: 54,56 + Owner: Neutral + Actor43: t08 + Location: 31,49 + Owner: Neutral + Actor44: t08 + Location: 10,38 + Owner: Neutral + Actor45: t08 + Location: 6,41 + Owner: Neutral + Actor46: t08 + Location: 5,30 + Owner: Neutral + Actor47: t08 + Location: 10,16 + Owner: Neutral + Actor48: t08 + Location: 15,14 + Owner: Neutral + Actor49: t08 + Location: 19,23 + Owner: Neutral + Actor50: t08 + Location: 38,43 + Owner: Neutral + Actor51: t18 + Location: 47,21 + Owner: Neutral + Actor52: t18 + Location: 48,20 + Owner: Neutral + Actor53: t18 + Location: 30,21 + Owner: Neutral + Actor65: v24 + Location: 18,38 + Owner: Neutral + Actor66: v32 + Location: 19,41 + Owner: Special + Actor67: v30 + Location: 15,40 + Owner: Neutral + Actor68: v29 + Location: 17,40 + Owner: Neutral + Actor69: v28 + Location: 23,38 + Owner: Neutral + Actor70: v27 + Location: 23,36 + Owner: Neutral + Actor71: v27 + Location: 22,36 + Owner: Neutral + Actor72: v26 + Location: 16,37 + Owner: Neutral + Actor82: mtnk + Location: 21,21 + Owner: GDI + Actor83: mtnk + Location: 17,14 + Owner: GDI + Actor84: jeep + Location: 29,21 + Owner: GDI + Actor85: jeep + Location: 29,20 + Owner: GDI + Actor86: e2 + Location: 58,30 + Owner: GDI + SubCell: 2 + Actor87: e2 + Location: 57,29 + Owner: GDI + SubCell: 0 + Actor88: e1 + Location: 32,49 + Owner: GDI + SubCell: 1 + Actor89: e1 + Location: 7,30 + Owner: GDI + Facing: 128 + SubCell: 3 + Actor90: e2 + Location: 6,30 + Owner: GDI + Facing: 96 + SubCell: 1 + Actor91: e2 + Location: 8,28 + Owner: GDI + Facing: 160 + SubCell: 3 + Actor92: e2 + Location: 39,43 + Owner: GDI + SubCell: 1 + waypoint27: waypoint + Location: 39,36 + Owner: Neutral + waypoint26: waypoint + Location: 44,48 + Owner: Neutral + waypoint12: waypoint + Location: 6,20 + Owner: Neutral + waypoint11: waypoint + Location: 5,26 + Owner: Neutral + waypoint10: waypoint + Location: 35,13 + Owner: Neutral + waypoint9: waypoint + Location: 52,13 + Owner: Neutral + waypoint8: waypoint + Location: 47,55 + Owner: Neutral + waypoint7: waypoint + Location: 26,54 + Owner: Neutral + waypoint6: waypoint + Location: 56,37 + Owner: Neutral + waypoint5: waypoint + Location: 30,52 + Owner: Neutral + waypoint4: waypoint + Location: 12,47 + Owner: Neutral + waypoint3: waypoint + Location: 11,35 + Owner: Neutral + waypoint2: waypoint + Location: 55,42 + Owner: Neutral + waypoint1: waypoint + Location: 26,32 + Owner: Neutral + waypoint0: waypoint + Location: 26,25 + Owner: Neutral + UnitsEntry: waypoint + Location: 52,56 + Owner: Neutral + UnitsRallyVehicle: waypoint + Location: 51,49 + Owner: Neutral + UnitsRallyRocket: waypoint + Location: 49,49 + Owner: Neutral + UnitsRallyGunner: waypoint + Location: 53,49 + Owner: Neutral + UnitsRallyMCV: waypoint + Location: 51,52 + Owner: Neutral + Tower1: gtwr + Location: 28,21 + Owner: GDI + Tower2: gtwr + Location: 23,21 + Owner: GDI + Radar: hq + Location: 21,14 + Owner: GDI + Silo1: silo + Location: 16,20 + Owner: GDI + Silo2: silo + Location: 16,18 + Owner: GDI + Silo3: silo + Location: 16,16 + Owner: GDI + Refinery: proc + Location: 18,17 + Owner: GDI + Barracks: pyle + Location: 25,18 + Owner: GDI + Plant1: nuke + Location: 21,17 + Owner: GDI + Plant2: nuke + Location: 23,17 + Owner: GDI + Yard: fact + Location: 18,14 + Owner: GDI + Factory: weap + Location: 26,13 + Owner: GDI + +Smudges: + cr1 46,48 0: + +Rules: + Player: + -ConquestVictoryConditions: + MissionObjectives: + EarlyGameOver: true + World: + -CrateSpawner: + -SpawnMPUnits: + -MPStartLocations: + ObjectivesPanel: + PanelName: MISSION_OBJECTIVES + LuaScript: + Scripts: nod05.lua + ^Vehicle: + Tooltip: + GenericVisibility: Enemy + ShowOwnerRow: false + ^Tank: + Tooltip: + GenericVisibility: Enemy + ShowOwnerRow: false + ^Infantry: + Tooltip: + GenericVisibility: Enemy + ShowOwnerRow: false + ^Plane: + Tooltip: + GenericVisibility: Enemy + ShowOwnerRow: false + ^Ship: + Tooltip: + GenericVisibility: Enemy + ShowOwnerRow: false + ^Building: + Tooltip: + GenericVisibility: Enemy + ShowOwnerRow: false + NUK2: + Buildable: + Prerequisites: ~disabled + GUN: + Buildable: + Prerequisites: ~disabled + CYCL: + Buildable: + Prerequisites: ~disabled + FIX: + Buildable: + Prerequisites: ~disabled + HPAD: + Buildable: + Prerequisites: ~disabled + OBLI: + Buildable: + Prerequisites: ~disabled + BRIK: + Buildable: + Prerequisites: ~disabled + TMPL: + Buildable: + Prerequisites: ~disabled + E5: + Buildable: + Prerequisites: ~disabled + RMBO: + Buildable: + Prerequisites: ~disabled + MLRS: + Buildable: + Prerequisites: ~disabled + MCV: + Buildable: + Prerequisites: ~disabled + LST: + Buildable: + Prerequisites: ~disabled + C17: + Buildable: + Prerequisites: ~disabled + GTWR: + Buildable: + Prerequisites: ~disabled + WEAP: + Buildable: + Prerequisites: ~disabled + EYE: + Buildable: + Prerequisites: ~disabled + ATWR: + Buildable: + Prerequisites: ~disabled + HARV: + Buildable: + Prerequisites: ~disabled + FTNK: + Buildable: + Prerequisites: ~disabled + STNK: + Buildable: + Prerequisites: ~disabled + ARTY: + Buildable: + Prerequisites: ~disabled + E3: + Buildable: + Prerequisites: ~disabled + MTNK: + Buildable: + Prerequisites: ~disabled + HTNK: + Buildable: + Prerequisites: ~disabled + ORCA: + Buildable: + Prerequisites: ~disabled + MSAM: + Buildable: + Prerequisites: ~disabled + A10: + TargetableUnit: + +Sequences: + +VoxelSequences: + +Weapons: + +Voices: + +Notifications: + +Translations: diff --git a/mods/cnc/maps/nod05/nod05.lua b/mods/cnc/maps/nod05/nod05.lua new file mode 100644 index 0000000000..1a357bc22e --- /dev/null +++ b/mods/cnc/maps/nod05/nod05.lua @@ -0,0 +1,339 @@ +NodUnitsVehicle = { 'bike', 'bike', 'bggy', 'ltnk', 'bike', 'bike' } +NodUnitsRocket = { 'e1', 'e1', 'e1', 'e1' } +NodUnitsGunner = { 'e3', 'e3', 'e3', 'e3' } +GDIReinforceUnits = { 'e2', 'e2', 'e2', 'e2', 'e2' } + +Gdi1Units = { ['e1'] = 3, ['e2'] = 1 } +Gdi2Units = { ['e1'] = 2, ['e2'] = 1 } +Gdi3Units = { ['jeep'] = 1 } +Gdi4Units = { ['mtnk'] = 1 } +Gdi5Units = { ['e1'] = 1, ['e2'] = 2 } +Gdi6Units = { ['e1'] = 3 } +Gdi7Units = { ['e2'] = 2 } +Gdi8Units = { ['e2'] = 5 } + +AllUnits = { Gdi1Units, Gdi2Units, Gdi3Units, Gdi4Units, Gdi5Units, Gdi6Units, Gdi7Units, Gdi8Units } + +AirstrikeDelay = DateTime.Minutes(1) + DateTime.Seconds(40) +YyyyTriggerFunctionTime = DateTime.Minutes(1) + DateTime.Seconds(30) +ZzzzTriggerFunctionTime = DateTime.Minutes(2) + DateTime.Seconds(30) +Grd1TriggerFunctionTime = DateTime.Seconds(3) +Atk2TriggerFunctionTime = DateTime.Minutes(1) + DateTime.Seconds(10) +Atk3TriggerFunctionTime = DateTime.Minutes(3) + DateTime.Seconds(10) +Atk4TriggerFunctionTime = DateTime.Minutes(4) + DateTime.Seconds(40) +Atk6TriggerFunctionTime = DateTime.Minutes(2) + DateTime.Seconds(30) + +DelyCellTriggerActivator = { CPos.New(29,30), CPos.New(28,30), CPos.New(27,30), CPos.New(26,30), CPos.New(25,30), CPos.New(24,30), CPos.New(23,30), CPos.New(22,30), CPos.New(21,30), CPos.New(29,29), CPos.New(28,29), CPos.New(27,29), CPos.New(26,29), CPos.New(25,29), CPos.New(24,29), CPos.New(23,29), CPos.New(22,29) } +DelzCellTriggerActivator = { CPos.New(29,27), CPos.New(28,27), CPos.New(27,27), CPos.New(26,27), CPos.New(25,27), CPos.New(24,27), CPos.New(29,26), CPos.New(28,26), CPos.New(27,26), CPos.New(26,26), CPos.New(25,26), CPos.New(24,26) } +Atk5CellTriggerActivator = { CPos.New(10,33), CPos.New(9,33), CPos.New(8,33), CPos.New(9,32), CPos.New(8,32), CPos.New(7,32), CPos.New(8,31), CPos.New(7,31), CPos.New(6,31) } +Atk1CellTriggerActivator = { CPos.New(10,33), CPos.New(9,33), CPos.New(8,33), CPos.New(9,32), CPos.New(8,32), CPos.New(7,32), CPos.New(8,31), CPos.New(7,31), CPos.New(6,31) } + +Gdi1Waypoints = { waypoint0, waypoint1, waypoint3, waypoint4 } +Gdi2Waypoints = { waypoint0, waypoint1, waypoint3, waypoint4, waypoint5 } +Gdi3Waypoints = { waypoint0, waypoint1, waypoint2 } +Gdi5Waypoints = { waypoint0, waypoint1, waypoint3, waypoint1, waypoint6 } +Gdi11Waypoints = { waypoint0, waypoint1, waypoint3, waypoint4, waypoint7, waypoint8 } +Gdi12Waypoints = { waypoint0, waypoint1, waypoint3, waypoint11, waypoint12 } + +AllWaypoints = { Gdi1Waypoints, Gdi2Waypoints, Gdi3Waypoints, Gdi5Waypoints, Gdi11Waypoints, Gdi12Waypoints } + +HuntActorTriggerActivator = { Tower1, Tower2, Radar, Silo1, Silo2, Silo3, Refinery, Barracks, Plant1, Plant2, Yard, Factory } + +GDIStartUnits = { } + +SendGDIAirstrike = function() + if not Radar.IsDead then + local target = getAirstrikeTarget() + + if target then + Radar.SendAirstrike(target, false, 256 - 28) + Trigger.AfterDelay(AirstrikeDelay, SendGDIAirstrike) + else + Trigger.AfterDelay(AirstrikeDelay/4, SendGDIAirstrike) + end + end +end + +YyyyTriggerFunction = function() + if not YyyyTriggerSwitch then + for type, count in pairs(Gdi2Units) do + MyActors = Utils.Take(count, GDI.GetActorsByType(type)) + Utils.Do(MyActors, function(actor) + WaypointMovementAndHunt(actor, Gdi2Waypoints) + end) + end + end +end + +ZzzzTriggerFunction = function() + if not ZzzzTriggerSwitch then + for type, count in pairs(Gdi1Units) do + MyActors = Utils.Take(count, GDI.GetActorsByType(type)) + Utils.Do(MyActors, function(actor) + WaypointMovementAndHunt(actor, Gdi1Waypoints) + end) + end + end +end + +Grd1TriggerFunction = function() + MyActors = Utils.Take(2, GDI.GetActorsByType('jeep')) + Utils.Do(MyActors, function(actor) + WaypointMovementAndHunt(actor, Gdi5Waypoints) + end) +end + +Atk5TriggerFunction = function() + WaypointMovementAndHunt(GDI.GetActorsByType('mtnk')[1], Gdi12Waypoints) +end + +Atk2TriggerFunction = function() + for type, count in pairs(Gdi1Units) do + MyActors = Utils.Take(count, GDI.GetActorsByType(type)) + Utils.Do(MyActors, function(actor) + WaypointMovementAndHunt(actor, Gdi1Waypoints) + end) + end +end + +Atk3TriggerFunction = function() + for type, count in pairs(Gdi2Units) do + MyActors = Utils.Take(count, GDI.GetActorsByType(type)) + Utils.Do(MyActors, function(actor) + WaypointMovementAndHunt(actor, Gdi2Waypoints) + end) + end +end + +Atk4TriggerFunction = function() + WaypointMovementAndHunt(GDI.GetActorsByType('jeep')[1], Gdi3Waypoints) +end + +Atk6TriggerFunction = function() + WaypointMovementAndHunt(GDI.GetActorsByType('mtnk')[1], Gdi2Waypoints) +end + +Atk1TriggerFunction = function() + Reinforcements.ReinforceWithTransport(GDI, 'tran', GDIReinforceUnits, { waypoint9.Location, waypoint26.Location }, nil, + function(transport, cargo) + transport.UnloadPassengers() + Utils.Do(cargo, function(actor) + IdleHunt(actor) + end) + end) +end + +AutoTriggerFunction = function() + local units = AllUnits[DateTime.GameTime % #AllUnits + 1] + local waypoints = AllWaypoints[DateTime.GameTime % #AllWaypoints + 1] + + for type, count in pairs(units) do + MyActors = Utils.Take(count, GDI.GetActorsByType(type)) + Utils.Do(MyActors, function(actor) + WaypointMovementAndHunt(actor, waypoints) + end) + end +end + +HuntTriggerFunction = function() + local list = GDI.GetGroundAttackers() + Utils.Do(list, function(unit) + IdleHunt(unit) + end) +end + +WaypointMovementAndHunt = function(unit, waypoints) + if unit ~= nil then + Utils.Do(waypoints, function(waypoint) + unit.AttackMove(waypoint.Location) + end) + IdleHunt(unit) + end +end + +InsertNodUnits = function() + Camera.Position = UnitsEntry.CenterPosition + + Reinforcements.Reinforce(Nod, NodUnitsVehicle, { UnitsEntry.Location, UnitsRallyVehicle.Location }, 1) + Reinforcements.Reinforce(Nod, NodUnitsRocket, { UnitsEntry.Location, UnitsRallyRocket.Location }, 50) + Reinforcements.Reinforce(Nod, NodUnitsGunner, { UnitsEntry.Location, UnitsRallyGunner.Location }, 50) + Trigger.AfterDelay(DateTime.Seconds(6), function() + Reinforcements.Reinforce(Nod, { 'mcv' }, { UnitsEntry.Location, UnitsRallyMCV.Location }) + end) +end + +WorldLoaded = function() + GDI = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") + + InsertNodUnits() + + Trigger.OnObjectiveAdded(Nod, function(p, id) + Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") + end) + + Trigger.OnObjectiveCompleted(Nod, function(p, id) + Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") + end) + + Trigger.OnObjectiveFailed(Nod, function(p, id) + Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") + end) + + Trigger.OnPlayerWon(Nod, function() + Media.PlaySpeechNotification(Nod, "Win") + end) + + Trigger.OnPlayerLost(Nod, function() + Media.PlaySpeechNotification(Nod, "Lose") + end) + + NodObjective1 = Nod.AddPrimaryObjective("Build 3 SAMs") + NodObjective2 = Nod.AddPrimaryObjective("Destroy the GDI base") + GDIObjective = GDI.AddPrimaryObjective("Kill all enemies!") + + Trigger.AfterDelay(AirstrikeDelay, SendGDIAirstrike) + Trigger.AfterDelay(YyyyTriggerFunctionTime, YyyyTriggerFunction) + Trigger.AfterDelay(ZzzzTriggerFunctionTime, ZzzzTriggerFunction) + + Trigger.OnEnteredFootprint(DelyCellTriggerActivator, function(a, id) + if a.Owner == Nod then + YyyyTriggerSwitch = true + Trigger.RemoveFootprintTrigger(id) + end + end) + + Trigger.OnEnteredFootprint(DelzCellTriggerActivator, function(a, id) + if a.Owner == Nod then + ZzzzTriggerSwitch = true + Trigger.RemoveFootprintTrigger(id) + end + end) + + Trigger.AfterDelay(Grd1TriggerFunctionTime, Grd1TriggerFunction) + + Trigger.OnEnteredFootprint(Atk5CellTriggerActivator, function(a, id) + if a.Owner == Nod then + Atk5TriggerFunction() + Trigger.RemoveFootprintTrigger(id) + end + end) + + Trigger.AfterDelay(Atk2TriggerFunctionTime, Atk2TriggerFunction) + Trigger.AfterDelay(Atk3TriggerFunctionTime, Atk3TriggerFunction) + Trigger.AfterDelay(Atk4TriggerFunctionTime, Atk4TriggerFunction) + Trigger.AfterDelay(Atk6TriggerFunctionTime, Atk6TriggerFunction) + + Trigger.OnEnteredFootprint(Atk1CellTriggerActivator, function(a, id) + if a.Owner == Nod then + Atk1TriggerFunction() + Trigger.RemoveFootprintTrigger(id) + end + end) + + Trigger.OnDiscovered(Tower1, AutoTriggerFunction) + Trigger.OnDiscovered(Tower2, AutoTriggerFunction) + + Trigger.OnAllRemovedFromWorld(HuntActorTriggerActivator, HuntTriggerFunction) + + Trigger.AfterDelay(0, getStartUnits) +end + +Tick = function() + if Nod.HasNoRequiredUnits() then + if DateTime.GameTime > 2 then + GDI.MarkCompletedObjective(GDIObjective) + end + end + + if not Nod.IsObjectiveCompleted(NodObjective1) and CheckForSams(Nod) then + Nod.MarkCompletedObjective(NodObjective1) + end + + if GDI.HasNoRequiredUnits() then + Nod.MarkCompletedObjective(NodObjective2) + end + + if DateTime.GameTime % DateTime.Seconds(3) == 0 then + checkProduction(GDI) + end + + if DateTime.GameTime % DateTime.Seconds(45) == 0 then + AutoTriggerFunction() + end +end + +IdleHunt = function(unit) + if not unit.IsDead then + Trigger.OnIdle(unit, unit.Hunt) + end +end + +CheckForSams = function(player) + local baseBuildings = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(actor) + return actor.Owner == Nod and actor.Type == 'sam' end) + + return #baseBuildings >= 3 +end + +checkProduction = function(player) + local Units = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(actor) + return actor.Owner == GDI + end) + + local UnitsType = { } + for type, count in pairs(GDIStartUnits) do + counter = 0 + Utils.Do(Units, function(unit) + if unit.Type == type then + counter = counter + 1 + end + end) + if counter < count then + for i = 1, count - counter, 1 do + UnitsType[i] = type + end + end + if #UnitsType > 0 then + if (type == 'jeep' or type == 'mtnk') and not Factory.IsDead then + Factory.Build(UnitsType) + elseif (type == 'e1' or type == 'e2') and not Barracks.IsDead then + Barracks.Build(UnitsType) + end + end + UnitsType = { } + end +end + +getStartUnits = function() + local Units = Map.ActorsInBox(Map.TopLeft, Map.BottomRight, function(actor) + return actor.Owner == GDI and ( actor.Type == 'e2' or actor.Type == 'e1' or actor.Type == 'jeep' or actor.Type == 'mtnk') + end) + Utils.Do(Units, function(unit) + if not GDIStartUnits[unit.Type] then + GDIStartUnits[unit.Type] = 1 + else + GDIStartUnits[unit.Type] = GDIStartUnits[unit.Type] + 1 + end + end) +end + +searches = 0 +getAirstrikeTarget = function() + local list = Nod.GetGroundAttackers() + local target = list[DateTime.GameTime % #list + 1].CenterPosition + + local sams = Map.ActorsInCircle(target, WRange.New(8 * 1024), function(actor) + return actor.Type == "sam" end) + + if #sams == 0 then + searches = 0 + return target + elseif searches < 6 then + searches = searches + 1 + return getAirstrikeTarget() + else + searches = 0 + return nil + end +end diff --git a/mods/cnc/missions.yaml b/mods/cnc/missions.yaml index fda4916595..7a2d167356 100644 --- a/mods/cnc/missions.yaml +++ b/mods/cnc/missions.yaml @@ -16,3 +16,4 @@ Nod Campaign: ./mods/cnc/maps/nod03b ./mods/cnc/maps/nod04a ./mods/cnc/maps/nod04b + ./mods/cnc/maps/nod05