diff --git a/mods/cnc/bits/scripts/campaign-global.lua b/mods/cnc/bits/scripts/campaign-global.lua new file mode 100644 index 0000000000..b8fbf6dfb1 --- /dev/null +++ b/mods/cnc/bits/scripts/campaign-global.lua @@ -0,0 +1,158 @@ +--[[ + Copyright 2007-2019 The OpenRA Developers (see AUTHORS) + 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. +]] + +Difficulty = Map.LobbyOption("difficulty") + +IdleHunt = function(actor) + if actor.HasProperty("Hunt") and not actor.IsDead then + Trigger.OnIdle(actor, actor.Hunt) + end +end + +InitObjectives = function(player) + Trigger.OnObjectiveAdded(player, function(p, id) + Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") + end) + + Trigger.OnObjectiveCompleted(player, function(p, id) + Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") + end) + Trigger.OnObjectiveFailed(player, function(p, id) + Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") + end) + + Trigger.OnPlayerLost(player, function() + Trigger.AfterDelay(DateTime.Seconds(1), function() + Media.PlaySpeechNotification(player, "Lose") + end) + end) + Trigger.OnPlayerWon(player, function() + Trigger.AfterDelay(DateTime.Seconds(1), function() + Media.PlaySpeechNotification(player, "Win") + end) + end) +end + +ReinforceWithLandingCraft = function(player, units, transportStart, transportUnload, rallypoint) + local transport = Actor.Create("oldlst", true, { Owner = player, Facing = 0, Location = transportStart }) + local subcell = 0 + Utils.Do(units, function(a) + transport.LoadPassenger(Actor.Create(a, false, { Owner = transport.Owner, Facing = transport.Facing, Location = transportUnload, SubCell = subcell })) + subcell = subcell + 1 + end) + + transport.ScriptedMove(transportUnload) + + transport.CallFunc(function() + Utils.Do(units, function() + local a = transport.UnloadPassenger() + a.IsInWorld = true + a.MoveIntoWorld(transport.Location - CVec.New(0, 1)) + + if rallypoint then + a.Move(rallypoint) + end + end) + end) + + transport.Wait(5) + transport.ScriptedMove(transportStart) + transport.Destroy() +end + +RepairBuilding = function(owner, actor, modifier) + Trigger.OnDamaged(actor, function(building) + if building.Owner == owner and building.Health < building.MaxHealth * modifier then + building.StartBuildingRepairs() + end + end) +end + +RepairNamedActors = function(owner, modifier) + Utils.Do(Map.NamedActors, function(actor) + if actor.Owner == owner and actor.HasProperty("StartBuildingRepairs") then + RepairBuilding(owner, actor, modifier) + end + end) +end + +ProduceUnits = function(player, factory, delay, toBuild, after) + if factory.IsDead or factory.Owner ~= player then + return + end + + factory.Build(toBuild(), function(units) + if delay and delay() > 0 then + Trigger.AfterDelay(delay(), function() ProduceUnits(player, factory, delay, toBuild, after) end) + end + + if after then + after(units) + end + end) +end + +CheckForBase = function(player, buildingTypes) + local count = 0 + + Utils.Do(buildingTypes, function(name) + if #player.GetActorsByType(name) > 0 then + count = count + 1 + end + end) + + return count == #buildingTypes +end + +RebuildUnit = function(unit, player, factory) + Trigger.OnKilled(unit[1], function() + ProduceUnits(player, factory, nil, function() return { unit[1].Type } end, function(actors) + RebuildUnit(actors, player, factory) + end) + end) +end + +MoveAndHunt = function(actors, path) + Utils.Do(actors, function(actor) + if not actor or actor.IsDead then + return + end + + Utils.Do(path, function(point) + actor.AttackMove(point.Location) + end) + + IdleHunt(actor) + end) +end + +Searches = 0 +GetAirstrikeTarget = function(player) + local list = player.GetGroundAttackers() + + if #list == 0 then + return + end + + local target = list[DateTime.GameTime % #list + 1].CenterPosition + + local sams = Map.ActorsInCircle(target, WDist.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(player) + else + Searches = 0 + return nil + end +end diff --git a/mods/cnc/maps/cnc64gdi01/cnc64gdi01.lua b/mods/cnc/maps/cnc64gdi01/cnc64gdi01.lua index 13b9c0c836..7a1f6ab1bc 100644 --- a/mods/cnc/maps/cnc64gdi01/cnc64gdi01.lua +++ b/mods/cnc/maps/cnc64gdi01/cnc64gdi01.lua @@ -6,11 +6,10 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + CommandoReinforcements = { "rmbo" } MCVReinforcements = { "mcv" } -inf1 = { "e4" } - AutocreateSquads = { { "stnk", "stnk" }, @@ -31,40 +30,22 @@ HeliPatrolPaths = AttackTriggers = { AttackTrigger1, AttackTrigger2, AttackTrigger3, AttackTrigger4 } -harvester = { "harv" } - SamSites = { SAM01, SAM02 } WorldLoaded = function() - player = Player.GetPlayer("GDI") - enemy = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) + InitObjectives(GDI) - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) - - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - destroySAMsCenterObjective = player.AddPrimaryObjective("Destroy the SAM sites protecting the Obelisk.") - destroyObeliskObjective = player.AddPrimaryObjective("Destroy the Obelisk.") - destroyBiotechCenterObjective = player.AddPrimaryObjective("Destroy the biotech facility.") + DestroySAMs = GDI.AddObjective("Destroy the SAM sites protecting the Obelisk.") + DestroyObelisk = GDI.AddObjective("Destroy the Obelisk.") + DestroyBiotechCenter = GDI.AddObjective("Destroy the biotech facility.") Trigger.OnAllKilled(SamSites, function() - AirSupport = Actor.Create("airstrike.proxy", true, { Owner = player }) + AirSupport = Actor.Create("airstrike.proxy", true, { Owner = GDI }) AirSupportEnabled = true - player.MarkCompletedObjective(destroySAMsCenterObjective) + GDI.MarkCompletedObjective(DestroySAMs) end) Trigger.OnDamaged(Obelisk01, function() @@ -72,86 +53,69 @@ WorldLoaded = function() end) Trigger.OnKilled(Obelisk01, function() - player.MarkCompletedObjective(destroyObeliskObjective) - Trigger.AfterDelay(DateTime.Seconds(5), function() Reinforce(MCVReinforcements) end) + GDI.MarkCompletedObjective(DestroyObelisk) + + Trigger.AfterDelay(DateTime.Seconds(5), function() + Media.PlaySpeechNotification(GDI, "Reinforce") + ReinforceWithLandingCraft(GDI, MCVReinforcements, lstStart.Location, lstEnd.Location, UnitsRally.Location) + end) + ObeliskFlare.Destroy() - if AirSupportEnabled then AirSupport.Destroy() end + if AirSupportEnabled then + AirSupport.Destroy() + end end) Trigger.OnKilled(Biolab, function() - player.MarkCompletedObjective(destroyBiotechCenterObjective) + GDI.MarkCompletedObjective(DestroyBiotechCenter) end) Trigger.OnCapture(Biolab, function() - Biolab.Kill() + Trigger.AfterDelay(DateTime.Seconds(1), Biolab.Kill) end) - Trigger.OnDamaged(Biolab, HuntTriggerFunction) + Trigger.OnDamaged(Biolab, function() + Utils.Do(Nod.GetGroundAttackers(), IdleHunt) + end) - AIRepairBuildings(enemy) - AIRebuildHarvesters(enemy) + RepairNamedActors(Nod, 0.9) + Trigger.AfterDelay(0, function() + local harv = Nod.GetActorsByType("harv")[1] + local toBuild = function() return { "harv" } end + RebuildHarvesters(harv, toBuild) + end) + + local vehicleToBuild = function() return Utils.Random(AutocreateSquads) end Utils.Do(AttackTriggers, function(a) Trigger.OnKilledOrCaptured(a, function() - NodVehicleProduction(Utils.Random(AutocreateSquads)) + ProduceUnits(Nod, Airfield, nil, vehicleToBuild) end) end) + Trigger.AfterDelay(DateTime.Seconds(150), function() + ProduceUnits(Nod, Airfield, function() return DateTime.Seconds(150) end, vehicleToBuild) + end) - Trigger.AfterDelay(DateTime.Seconds(150), AutoCreateTeam) Trigger.AfterDelay(DateTime.Minutes(5), HeliHunt) - NodInfantryProduction() + local toBuild = function() return { "e4" } end + local delay = function() return DateTime.Seconds(15) end + ProduceUnits(Nod, HandOfNod, delay, toBuild) Camera.Position = UnitsRally.CenterPosition - ObeliskFlare = Actor.Create('flare', true, { Owner = player, Location = Flare.Location }) - Reinforce(CommandoReinforcements) + ObeliskFlare = Actor.Create("flare", true, { Owner = GDI, Location = Flare.Location }) + + Media.PlaySpeechNotification(GDI, "Reinforce") + ReinforceWithLandingCraft(GDI, CommandoReinforcements, lstStart.Location, lstEnd.Location, UnitsRally.Location) end Tick = function() - if DateTime.GameTime > DateTime.Seconds(5) and player.HasNoRequiredUnits() then - player.MarkFailedObjective(destroyBiotechCenterObjective) + if DateTime.GameTime > DateTime.Seconds(5) and GDI.HasNoRequiredUnits() then + GDI.MarkFailedObjective(DestroyBiotechCenter) end end -Reinforce = function(units) - Media.PlaySpeechNotification(player, "Reinforce") - ReinforceWithLandingCraft(units, lstStart.Location, lstEnd.Location, UnitsRally.Location) -end - -ReinforceWithLandingCraft = function(units, transportStart, transportUnload, rallypoint) - local transport = Actor.Create("oldlst", true, { Owner = player, Facing = 0, Location = transportStart }) - local subcell = 0 - Utils.Do(units, function(a) - transport.LoadPassenger(Actor.Create(a, false, { Owner = transport.Owner, Facing = transport.Facing, Location = transportUnload, SubCell = subcell })) - subcell = subcell + 1 - end) - - transport.ScriptedMove(transportUnload) - - transport.CallFunc(function() - Utils.Do(units, function() - local a = transport.UnloadPassenger() - a.IsInWorld = true - a.MoveIntoWorld(transport.Location - CVec.New(0, 1)) - - if rallypoint ~= nil then - a.Move(rallypoint) - end - end) - end) - - transport.Wait(5) - transport.ScriptedMove(transportStart) - transport.Destroy() -end - -HuntTriggerFunction = function() - local list = enemy.GetGroundAttackers() - Utils.Do(list, function(unit) - IdleHunt(unit) - end) -end - +-- Overwrite the default to send the units to UnitsRally first IdleHunt = function(unit) if not unit.IsDead then Trigger.OnIdle(unit, function() @@ -161,71 +125,19 @@ IdleHunt = function(unit) end end -NodInfantryProduction = function() - if HandOfNod.IsDead or HandOfNod.Owner == player then - return - end - HandOfNod.Build(inf1, SquadHunt) - Trigger.AfterDelay(DateTime.Seconds(15), NodInfantryProduction) -end - -NodVehicleProduction = function(Squad) - if Airfield.IsDead or not Airfield.Owner == enemy then - return - end - Airfield.Build(Squad, SquadHunt) -end - -AIRepairBuildings = function(ai) - Utils.Do(Map.NamedActors, function(actor) - if actor.Owner == ai and actor.HasProperty("StartBuildingRepairs") then - Trigger.OnDamaged(actor, function(building) - if building.Owner == ai and building.Health < 0.9 * building.MaxHealth then - building.StartBuildingRepairs() - end - end) - end - end) -end - HeliHunt = function() - local helicopters = enemy.GetActorsByType("heli") local patrolpath = Utils.Random(HeliPatrolPaths) - - Utils.Do(helicopters, function(actor) + Utils.Do(Nod.GetActorsByType("heli"), function(actor) Trigger.OnIdle(actor, function() actor.Patrol(patrolpath) end) end) end -SquadHunt = function(actors) - Utils.Do(actors, function(actor) - Trigger.OnIdle(actor, function() - actor.AttackMove(UnitsRally.Location, 50) - actor.Hunt() +RebuildHarvesters = function(harv, toBuild) + Trigger.OnRemovedFromWorld(harv, function() + ProduceUnits(Nod, Airfield, nil, toBuild, function(unit) + RebuildHarvesters(unit, toBuild) end) end) end - -AIRebuildHarvesters = function(ai) - if AIHarvesterCount == NIL or AIHarvesterCount == 0 then - AIHarvesterCount = #ai.GetActorsByType("harv") - IsBuildingHarvester = false - end - - local CurrentHarvesterCount = #ai.GetActorsByType("harv") - - if CurrentHarvesterCount < AIHarvesterCount and Airfield.Owner == enemy and not IsBuildingHarvester and not Airfield.IsDead then - IsBuildingHarvester = true - Airfield.Build(harvester, function() - IsBuildingHarvester = false - end) - end - Trigger.AfterDelay(DateTime.Seconds(5), function() AIRebuildHarvesters(ai) end) -end - -AutoCreateTeam = function() - NodVehicleProduction(Utils.Random(AutocreateSquads)) - Trigger.AfterDelay(DateTime.Seconds(150), AutoCreateTeam) -end diff --git a/mods/cnc/maps/cnc64gdi01/rules.yaml b/mods/cnc/maps/cnc64gdi01/rules.yaml index ef4a5aa7b7..f0d7f79c1c 100644 --- a/mods/cnc/maps/cnc64gdi01/rules.yaml +++ b/mods/cnc/maps/cnc64gdi01/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: cnc64gdi01.lua + Scripts: campaign-global.lua, cnc64gdi01.lua MusicPlaylist: StartingMusic: aoi MissionData: diff --git a/mods/cnc/maps/funpark01/rules.yaml b/mods/cnc/maps/funpark01/rules.yaml index 5525eae4ea..9eb95e7f8b 100644 --- a/mods/cnc/maps/funpark01/rules.yaml +++ b/mods/cnc/maps/funpark01/rules.yaml @@ -1,10 +1,10 @@ World: LuaScript: - Scripts: scj01ea.lua + Scripts: campaign-global.lua, scj01ea.lua MusicPlaylist: StartingMusic: j1 MissionData: - Briefing: There have been some reports of strange animals in this area. \n\nTake your units to investigate, and report back your findings. + Briefing: There have been some reports of strange animals in this area.\n\nTake your units to investigate, and report back your findings. BriefingVideo: generic.vqa StartVideo: dino.vqa MapOptions: @@ -17,6 +17,7 @@ World: easy: Easy normal: Normal Default: easy + Locked: false Player: EnemyWatcher: diff --git a/mods/cnc/maps/funpark01/scj01ea.lua b/mods/cnc/maps/funpark01/scj01ea.lua index 834a5acaff..c63ba7e922 100644 --- a/mods/cnc/maps/funpark01/scj01ea.lua +++ b/mods/cnc/maps/funpark01/scj01ea.lua @@ -6,90 +6,49 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + RifleReinforcments = { "e1", "e1", "e1", "bike" } BazookaReinforcments = { "e3", "e3", "e3", "bike" } BikeReinforcments = { "bike" } - -ReinforceWithLandingCraft = function(units, transportStart, transportUnload, rallypoint) - local transport = Actor.Create("oldlst", true, { Owner = player, Facing = 0, Location = transportStart }) - local subcell = 0 - Utils.Do(units, function(a) - transport.LoadPassenger(Actor.Create(a, false, { Owner = transport.Owner, Facing = transport.Facing, Location = transportUnload, SubCell = subcell })) - subcell = subcell + 1 - end) - - transport.ScriptedMove(transportUnload) - - transport.CallFunc(function() - Utils.Do(units, function() - local a = transport.UnloadPassenger() - a.IsInWorld = true - a.MoveIntoWorld(transport.Location - CVec.New(0, 1)) - - if rallypoint ~= nil then - a.Move(rallypoint) - end - end) - end) - - transport.Wait(5) - transport.ScriptedMove(transportStart) - transport.Destroy() - - Media.PlaySpeechNotification(player, "Reinforce") -end - WorldLoaded = function() - player = Player.GetPlayer("Nod") + Nod = Player.GetPlayer("Nod") dinosaur = Player.GetPlayer("Dinosaur") civilian = Player.GetPlayer("Civilian") - InvestigateObj = player.AddPrimaryObjective("Investigate the nearby village for reports of \nstrange activity.") + InvestigateObj = Nod.AddObjective("Investigate the nearby village for reports of\nstrange activity.") - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) + InitObjectives(Nod) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) - - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) - - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - ReachVillageObj = player.AddPrimaryObjective("Reach the village.") + ReachVillageObj = Nod.AddObjective("Reach the village.") Trigger.OnPlayerDiscovered(civilian, function(_, discoverer) - if discoverer == player and not player.IsObjectiveCompleted(ReachVillageObj) then + if discoverer == Nod and not Nod.IsObjectiveCompleted(ReachVillageObj) then if not dinosaur.HasNoRequiredUnits() then - KillDinos = player.AddPrimaryObjective("Kill all creatures in the area.") + KillDinos = Nod.AddObjective("Kill all creatures in the area.") end - player.MarkCompletedObjective(ReachVillageObj) + Nod.MarkCompletedObjective(ReachVillageObj) end end) - DinoTric.Patrol({WP0.Location, WP1.Location}, true, 3) - DinoTrex.Patrol({WP2.Location, WP3.Location}, false) - Trigger.OnIdle(DinoTrex, DinoTrex.Hunt) + DinoTric.Patrol({ WP0.Location, WP1.Location }, true, 3) + Trigger.OnDamaged(DinoTric, function() + DinoTric.Stop() + IdleHunt(DinoTric) + end) - ReinforceWithLandingCraft(RifleReinforcments, SeaEntryA.Location, BeachReinforceA.Location, BeachReinforceA.Location) + DinoTrex.AttackMove(WP2.Location) + DinoTrex.AttackMove(WP3.Location) + IdleHunt(DinoTrex) + + ReinforceWithLandingCraft(Nod, RifleReinforcments, SeaEntryA.Location, BeachReinforceA.Location, BeachReinforceA.Location) Trigger.AfterDelay(DateTime.Seconds(3), function() InitialUnitsArrived = true end) - Trigger.AfterDelay(DateTime.Seconds(15), function() ReinforceWithLandingCraft(BazookaReinforcments, SeaEntryB.Location, BeachReinforceB.Location, BeachReinforceB.Location) end) + Trigger.AfterDelay(DateTime.Seconds(15), function() ReinforceWithLandingCraft(Nod, BazookaReinforcments, SeaEntryB.Location, BeachReinforceB.Location, BeachReinforceB.Location) end) if Map.LobbyOption("difficulty") == "easy" then - Trigger.AfterDelay(DateTime.Seconds(25), function() ReinforceWithLandingCraft(BikeReinforcments, SeaEntryA.Location, BeachReinforceA.Location, BeachReinforceA.Location) end) - Trigger.AfterDelay(DateTime.Seconds(30), function() ReinforceWithLandingCraft(BikeReinforcments, SeaEntryB.Location, BeachReinforceB.Location, BeachReinforceB.Location) end) + Trigger.AfterDelay(DateTime.Seconds(25), function() ReinforceWithLandingCraft(Nod, BikeReinforcments, SeaEntryA.Location, BeachReinforceA.Location, BeachReinforceA.Location) end) + Trigger.AfterDelay(DateTime.Seconds(30), function() ReinforceWithLandingCraft(Nod, BikeReinforcments, SeaEntryB.Location, BeachReinforceB.Location, BeachReinforceB.Location) end) end Camera.Position = CameraStart.CenterPosition @@ -97,12 +56,13 @@ end Tick = function() if InitialUnitsArrived then - if player.HasNoRequiredUnits() then - player.MarkFailedObjective(InvestigateObj) + if Nod.HasNoRequiredUnits() then + Nod.MarkFailedObjective(InvestigateObj) end + if dinosaur.HasNoRequiredUnits() then - if KillDinos then player.MarkCompletedObjective(KillDinos) end - player.MarkCompletedObjective(InvestigateObj) + if KillDinos then Nod.MarkCompletedObjective(KillDinos) end + Nod.MarkCompletedObjective(InvestigateObj) end end end diff --git a/mods/cnc/maps/gdi01/gdi01.lua b/mods/cnc/maps/gdi01/gdi01.lua index fae2fcb1a2..5a05a1848a 100644 --- a/mods/cnc/maps/gdi01/gdi01.lua +++ b/mods/cnc/maps/gdi01/gdi01.lua @@ -6,6 +6,7 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + MCVReinforcements = { "mcv" } InfantryReinforcements = { "e1", "e1", "e1" } VehicleReinforcements = { "jeep" } @@ -13,83 +14,28 @@ NodPatrol = { "e1", "e1" } GDIBaseBuildings = { "pyle", "fact", "nuke" } SendNodPatrol = function() - Reinforcements.Reinforce(enemy, NodPatrol, { nod0.Location, nod1.Location }, 15, function(soldier) + Reinforcements.Reinforce(Nod, NodPatrol, { nod0.Location, nod1.Location }, 15, function(soldier) soldier.AttackMove(nod2.Location) - soldier.Move(nod3.Location) - soldier.Hunt() + soldier.AttackMove(nod3.Location) + IdleHunt(soldier) end) end -ReinforceWithLandingCraft = function(units, transportStart, transportUnload, rallypoint) - local transport = Actor.Create("oldlst", true, { Owner = player, Facing = 0, Location = transportStart }) - local subcell = 0 - Utils.Do(units, function(a) - transport.LoadPassenger(Actor.Create(a, false, { Owner = transport.Owner, Facing = transport.Facing, Location = transportUnload, SubCell = subcell })) - subcell = subcell + 1 - end) - - transport.ScriptedMove(transportUnload) - - transport.CallFunc(function() - Utils.Do(units, function() - local a = transport.UnloadPassenger() - a.IsInWorld = true - a.MoveIntoWorld(transport.Location - CVec.New(0, 1)) - - if rallypoint ~= nil then - a.Move(rallypoint) - end - end) - end) - - transport.Wait(5) - transport.ScriptedMove(transportStart) - transport.Destroy() -end - Reinforce = function(units) - Media.PlaySpeechNotification(player, "Reinforce") - ReinforceWithLandingCraft(units, lstStart.Location, lstEnd.Location, reinforcementsTarget.Location) -end - -CheckForBase = function(player) - local buildings = 0 - - Utils.Do(GDIBaseBuildings, function(name) - if #player.GetActorsByType(name) > 0 then - buildings = buildings + 1 - end - end) - - return buildings == #GDIBaseBuildings + Media.PlaySpeechNotification(GDI, "Reinforce") + ReinforceWithLandingCraft(GDI, units, lstStart.Location, lstEnd.Location, reinforcementsTarget.Location) end WorldLoaded = function() - player = Player.GetPlayer("GDI") - enemy = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) + InitObjectives(GDI) - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) + secureAreaObjective = GDI.AddObjective("Eliminate all Nod forces in the area.") + beachheadObjective = GDI.AddObjective("Establish a beachhead.", "Secondary", false) - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - secureAreaObjective = player.AddPrimaryObjective("Eliminate all Nod forces in the area.") - beachheadObjective = player.AddSecondaryObjective("Establish a beachhead.") - - ReinforceWithLandingCraft(MCVReinforcements, lstStart.Location + CVec.New(2, 0), lstEnd.Location + CVec.New(2, 0), mcvTarget.Location) + ReinforceWithLandingCraft(GDI, MCVReinforcements, lstStart.Location + CVec.New(2, 0), lstEnd.Location + CVec.New(2, 0), mcvTarget.Location) Reinforce(InfantryReinforcements) SendNodPatrol() @@ -99,16 +45,16 @@ WorldLoaded = function() end Tick = function() - if enemy.HasNoRequiredUnits() then - player.MarkCompletedObjective(secureAreaObjective) + if Nod.HasNoRequiredUnits() then + GDI.MarkCompletedObjective(secureAreaObjective) end - if DateTime.GameTime > DateTime.Seconds(5) and player.HasNoRequiredUnits() then - player.MarkFailedObjective(beachheadObjective) - player.MarkFailedObjective(secureAreaObjective) + if DateTime.GameTime > DateTime.Seconds(5) and GDI.HasNoRequiredUnits() then + GDI.MarkFailedObjective(beachheadObjective) + GDI.MarkFailedObjective(secureAreaObjective) end - if DateTime.GameTime % DateTime.Seconds(1) == 0 and not player.IsObjectiveCompleted(beachheadObjective) and CheckForBase(player) then - player.MarkCompletedObjective(beachheadObjective) + if DateTime.GameTime % DateTime.Seconds(1) == 0 and not GDI.IsObjectiveCompleted(beachheadObjective) and CheckForBase(GDI, GDIBaseBuildings) then + GDI.MarkCompletedObjective(beachheadObjective) end end diff --git a/mods/cnc/maps/gdi01/rules.yaml b/mods/cnc/maps/gdi01/rules.yaml index f30f7cb46b..342940baed 100644 --- a/mods/cnc/maps/gdi01/rules.yaml +++ b/mods/cnc/maps/gdi01/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: gdi01.lua + Scripts: campaign-global.lua, gdi01.lua MusicPlaylist: StartingMusic: aoi MissionData: diff --git a/mods/cnc/maps/gdi02/gdi02.lua b/mods/cnc/maps/gdi02/gdi02.lua index 0787cb71fa..7d7ad0aef9 100644 --- a/mods/cnc/maps/gdi02/gdi02.lua +++ b/mods/cnc/maps/gdi02/gdi02.lua @@ -6,6 +6,7 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + nodInBaseTeam = { RushBuggy, RushRifle1, RushRifle2, RushRifle3 } MobileConstructionVehicle = { "mcv" } EngineerReinforcements = { "e6", "e6", "e6" } @@ -13,36 +14,9 @@ VehicleReinforcements = { "jeep" } AttackerSquadSize = 3 -ReinforceWithLandingCraft = function(units, transportStart, transportUnload, rallypoint) - local transport = Actor.Create("oldlst", true, { Owner = player, Facing = 0, Location = transportStart }) - local subcell = 0 - Utils.Do(units, function(a) - transport.LoadPassenger(Actor.Create(a, false, { Owner = transport.Owner, Facing = transport.Facing, Location = transportUnload, SubCell = subcell })) - subcell = subcell + 1 - end) - - transport.ScriptedMove(transportUnload) - - transport.CallFunc(function() - Utils.Do(units, function() - local a = transport.UnloadPassenger() - a.IsInWorld = true - a.MoveIntoWorld(transport.Location - CVec.New(0, 1)) - - if rallypoint ~= nil then - a.Move(rallypoint) - end - end) - end) - - transport.Wait(5) - transport.ScriptedMove(transportStart) - transport.Destroy() -end - Reinforce = function(units) - Media.PlaySpeechNotification(player, "Reinforce") - ReinforceWithLandingCraft(units, lstStart.Location, lstEnd.Location) + Media.PlaySpeechNotification(GDI, "Reinforce") + ReinforceWithLandingCraft(GDI, units, lstStart.Location, lstEnd.Location) end BridgeheadSecured = function() @@ -53,54 +27,39 @@ BridgeheadSecured = function() end NodAttack = function() - local nodUnits = enemy.GetGroundAttackers() + local nodUnits = Nod.GetGroundAttackers() if #nodUnits > AttackerSquadSize * 2 then local attackers = Utils.Skip(nodUnits, #nodUnits - AttackerSquadSize) Utils.Do(attackers, function(unit) unit.AttackMove(NodAttackWaypoint.Location) - Trigger.OnIdle(unit, unit.Hunt) + IdleHunt(unit) end) Trigger.OnAllKilled(attackers, function() Trigger.AfterDelay(DateTime.Seconds(15), NodAttack) end) end end WorldLoaded = function() - player = Player.GetPlayer("GDI") - enemy = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) + InitObjectives(GDI) - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) + nodObjective = Nod.AddObjective("Destroy all GDI troops.") + gdiObjective1 = GDI.AddObjective("Eliminate all Nod forces in the area.") + gdiObjective2 = GDI.AddObjective("Capture the Tiberium refinery.", "Secondary", false) - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - nodObjective = enemy.AddPrimaryObjective("Destroy all GDI troops.") - gdiObjective1 = player.AddPrimaryObjective("Eliminate all Nod forces in the area.") - gdiObjective2 = player.AddSecondaryObjective("Capture the Tiberium refinery.") - - Trigger.OnCapture(NodRefinery, function() player.MarkCompletedObjective(gdiObjective2) end) - Trigger.OnKilled(NodRefinery, function() player.MarkFailedObjective(gdiObjective2) end) + Trigger.OnCapture(NodRefinery, function() GDI.MarkCompletedObjective(gdiObjective2) end) + Trigger.OnKilled(NodRefinery, function() GDI.MarkFailedObjective(gdiObjective2) end) Trigger.OnAllKilled(nodInBaseTeam, BridgeheadSecured) end Tick = function() - if player.HasNoRequiredUnits() then - enemy.MarkCompletedObjective(nodObjective) + if GDI.HasNoRequiredUnits() then + Nod.MarkCompletedObjective(nodObjective) end - if enemy.HasNoRequiredUnits() then - player.MarkCompletedObjective(gdiObjective1) + + if Nod.HasNoRequiredUnits() then + GDI.MarkCompletedObjective(gdiObjective1) end end diff --git a/mods/cnc/maps/gdi02/rules.yaml b/mods/cnc/maps/gdi02/rules.yaml index 254025ac18..ff7d520372 100644 --- a/mods/cnc/maps/gdi02/rules.yaml +++ b/mods/cnc/maps/gdi02/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: gdi02.lua + Scripts: campaign-global.lua, gdi02.lua MusicPlaylist: StartingMusic: befeared MissionData: diff --git a/mods/cnc/maps/gdi03/gdi03.lua b/mods/cnc/maps/gdi03/gdi03.lua index 782ffdafc4..37538c91a1 100644 --- a/mods/cnc/maps/gdi03/gdi03.lua +++ b/mods/cnc/maps/gdi03/gdi03.lua @@ -6,6 +6,7 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + SamSites = { Sam1, Sam2, Sam3, Sam4 } Sam4Guards = { Sam4Guard0, Sam4Guard1, Sam4Guard2, Sam4Guard3, Sam4Guard4, HiddenBuggy } NodInfantrySquad = { "e1", "e1", "e1", "e1", "e1" } @@ -14,7 +15,7 @@ InfantryReinforcements = { "e1", "e1", "e1", "e1", "e1", "e2", "e2", "e2", "e2", JeepReinforcements = { "jeep", "jeep", "jeep" } AttackPlayer = function() - if NodBarracks.IsDead or NodBarracks.Owner == player then + if NodBarracks.IsDead or NodBarracks.Owner == GDI then return end @@ -44,65 +45,35 @@ AttackPlayer = function() end SendReinforcements = function() - Reinforcements.Reinforce(player, JeepReinforcements, { VehicleStart.Location, VehicleStop.Location }) - Reinforcements.Reinforce(player, InfantryReinforcements, { InfantryStart.Location, InfantryStop.Location }, 5) + Reinforcements.Reinforce(GDI, JeepReinforcements, { VehicleStart.Location, VehicleStop.Location }) + Reinforcements.Reinforce(GDI, InfantryReinforcements, { InfantryStart.Location, InfantryStop.Location }, 5) Trigger.AfterDelay(DateTime.Seconds(3), function() - Reinforcements.Reinforce(player, { "mcv" }, { VehicleStart.Location, MCVwaypoint.Location }) + Reinforcements.Reinforce(GDI, { "mcv" }, { VehicleStart.Location, MCVwaypoint.Location }) InitialUnitsArrived = true end) - Media.PlaySpeechNotification(player, "Reinforce") + Media.PlaySpeechNotification(GDI, "Reinforce") end WorldLoaded = function() - player = Player.GetPlayer("GDI") - enemy = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) + InitObjectives(GDI) - nodObjective = enemy.AddPrimaryObjective("Destroy all GDI troops.") - gdiMainObjective = player.AddPrimaryObjective("Eliminate all Nod forces in the area.") - gdiAirSupportObjective = player.AddSecondaryObjective("Destroy the SAM sites to receive air support.") - - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) + DestroyNod = GDI.AddObjective("Eliminate all Nod forces in the area.") + local airSupportObjective = GDI.AddObjective("Destroy the SAM sites to receive air support.", "Secondary", false) Trigger.OnAllKilled(SamSites, function() - player.MarkCompletedObjective(gdiAirSupportObjective) - Actor.Create("airstrike.proxy", true, { Owner = player }) + GDI.MarkCompletedObjective(airSupportObjective) + Actor.Create("airstrike.proxy", true, { Owner = GDI }) end) - Utils.Do(Map.NamedActors, function(actor) - if actor.Owner == enemy and actor.HasProperty("StartBuildingRepairs") then - Trigger.OnDamaged(actor, function(building) - if building.Owner == enemy and building.Health < 0.25 * building.MaxHealth then - building.StartBuildingRepairs() - end - end) - end - end) + RepairNamedActors(Nod, 0.25) Trigger.OnDamaged(Sam4, function() - Utils.Do(Sam4Guards, function(sam4Guard) - if not sam4Guard.IsDead then - Trigger.OnIdle(sam4Guard, sam4Guard.Hunt) - end - end) + Utils.Do(Sam4Guards, IdleHunt) end) - InitialUnitsArrived = false SendReinforcements() Camera.Position = MCVwaypoint.CenterPosition @@ -112,11 +83,12 @@ end Tick = function() if InitialUnitsArrived then - if player.HasNoRequiredUnits() then - enemy.MarkCompletedObjective(nodObjective) + if GDI.HasNoRequiredUnits() then + GDI.MarkFailedObjective(DestroyNod) end - if enemy.HasNoRequiredUnits() then - player.MarkCompletedObjective(gdiMainObjective) + + if Nod.HasNoRequiredUnits() then + GDI.MarkCompletedObjective(DestroyNod) end end end diff --git a/mods/cnc/maps/gdi03/rules.yaml b/mods/cnc/maps/gdi03/rules.yaml index 26d65b6735..30ed064a05 100644 --- a/mods/cnc/maps/gdi03/rules.yaml +++ b/mods/cnc/maps/gdi03/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: gdi03.lua + Scripts: campaign-global.lua, gdi03.lua MusicPlaylist: StartingMusic: crep226m MissionData: diff --git a/mods/cnc/maps/gdi04a/gdi04a.lua b/mods/cnc/maps/gdi04a/gdi04a.lua index 9c93b287ac..61e5d2122e 100644 --- a/mods/cnc/maps/gdi04a/gdi04a.lua +++ b/mods/cnc/maps/gdi04a/gdi04a.lua @@ -6,11 +6,12 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + AutoTrigger = { CPos.New(51, 47), CPos.New(52, 47), CPos.New(53, 47), CPos.New(54, 47) } GDIHeliTrigger = { CPos.New(27, 55), CPos.New(27, 56), CPos.New(28, 56), CPos.New(28, 57), CPos.New(28, 58), CPos.New(28, 59)} -Nod1Units = { "e1", "e1", "e3", "e3" } -Auto1Units = { "e1", "e1", "e3" } +NodUnits = { "e1", "e1", "e3", "e3" } +AutoUnits = { "e1", "e1", "e3" } KillsUntilReinforcements = 12 HeliDelay = { 83, 137, 211 } @@ -18,148 +19,113 @@ HeliDelay = { 83, 137, 211 } GDIReinforcements = { "e2", "e2", "e2", "e2", "e2" } GDIReinforcementsWaypoints = { GDIReinforcementsEntry.Location, GDIReinforcementsWP1.Location } -NodHelis = { +NodHelis = +{ { delay = DateTime.Seconds(HeliDelay[1]), entry = { NodHeliEntry.Location, NodHeliLZ1.Location }, types = { "e1", "e1", "e3" } }, { delay = DateTime.Seconds(HeliDelay[2]), entry = { NodHeliEntry.Location, NodHeliLZ2.Location }, types = { "e1", "e1", "e1", "e1" } }, { delay = DateTime.Seconds(HeliDelay[3]), entry = { NodHeliEntry.Location, NodHeliLZ3.Location }, types = { "e1", "e1", "e3" } } } +Kills = 0 +NodUnitKilled = function() + Kills = Kills + 1 + + if Kills == KillsUntilReinforcements then + GDI.MarkCompletedObjective(ReinforcementsObjective) + SendGDIReinforcements() + end +end + SendHeli = function(heli) - units = Reinforcements.ReinforceWithTransport(enemy, "tran", heli.types, heli.entry, { heli.entry[1] }) + local units = Reinforcements.ReinforceWithTransport(Nod, "tran", heli.types, heli.entry, { heli.entry[1] }) Utils.Do(units[2], function(actor) - actor.Hunt() - Trigger.OnIdle(actor, actor.Hunt) - Trigger.OnKilled(actor, KillCounter) + IdleHunt(actor) + Trigger.OnKilled(actor, NodUnitKilled) end) Trigger.AfterDelay(heli.delay, function() SendHeli(heli) end) end SendGDIReinforcements = function() - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.ReinforceWithTransport(player, "apc", GDIReinforcements, GDIReinforcementsWaypoints, nil, function(apc, team) + Media.PlaySpeechNotification(GDI, "Reinforce") + Reinforcements.ReinforceWithTransport(GDI, "apc", GDIReinforcements, GDIReinforcementsWaypoints, nil, function(apc, team) table.insert(team, apc) Trigger.OnAllKilled(team, function() Trigger.AfterDelay(DateTime.Seconds(5), SendGDIReinforcements) end) Utils.Do(team, function(unit) unit.Stance = "Defend" end) end) end -BuildNod1 = function() - if HandOfNod.IsDead then - return - end - - local func = function(team) +BuildNod = function() + local after = function(team) Utils.Do(team, function(actor) Trigger.OnIdle(actor, actor.Hunt) - Trigger.OnKilled(actor, KillCounter) + Trigger.OnKilled(actor, NodUnitKilled) end) - Trigger.OnAllKilled(team, BuildNod1) + Trigger.OnAllKilled(team, BuildNod) end - if not HandOfNod.Build(Nod1Units, func) then - Trigger.AfterDelay(DateTime.Seconds(5), BuildNod1) - end + ProduceUnits(Nod, HandOfNod, nil, function() return NodUnits end, after) end -BuildAuto1 = function() - if HandOfNod.IsDead then - return - end - - local func = function(team) +BuildAuto = function() + local after = function(team) Utils.Do(team, function(actor) Trigger.OnIdle(actor, actor.Hunt) - Trigger.OnKilled(actor, KillCounter) + Trigger.OnKilled(actor, NodUnitKilled) end) end - if not HandOfNod.IsDead and HandOfNod.Build(Auto1Units, func) then - Trigger.AfterDelay(DateTime.Seconds(5), BuildAuto1) - end + local delay = function() return DateTime.Seconds(5) end + ProduceUnits(Nod, HandOfNod, delay, function() return AutoUnits end, after) end -kills = 0 -KillCounter = function() kills = kills + 1 end - -ReinforcementsSent = false Tick = function() - enemy.Cash = 1000 + Nod.Cash = 1000 - if not ReinforcementsSent and kills >= KillsUntilReinforcements then - ReinforcementsSent = true - player.MarkCompletedObjective(reinforcementsObjective) - SendGDIReinforcements() - end - - if player.HasNoRequiredUnits() then - Trigger.AfterDelay(DateTime.Seconds(1), function() player.MarkFailedObjective(gdiObjective) end) + if GDI.HasNoRequiredUnits() then + Trigger.AfterDelay(DateTime.Seconds(1), function() GDI.MarkFailedObjective(GDIObjective) end) end end SetupWorld = function() - Utils.Do(enemy.GetGroundAttackers(enemy), function(unit) - Trigger.OnKilled(unit, KillCounter) - end) - - Utils.Do(player.GetGroundAttackers(), function(unit) - unit.Stance = "Defend" + Utils.Do(Nod.GetGroundAttackers(Nod), function(unit) + Trigger.OnKilled(unit, NodUnitKilled) end) Hunter1.Hunt() Hunter2.Hunt() - Trigger.OnRemovedFromWorld(crate, function() player.MarkCompletedObjective(gdiObjective) end) + Trigger.OnRemovedFromWorld(crate, function() GDI.MarkCompletedObjective(GDIObjective) end) end WorldLoaded = function() - player = Player.GetPlayer("GDI") - enemy = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") SetupWorld() - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) + InitObjectives(GDI) - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) + GDIObjective = GDI.AddObjective("Retrieve the crate with the stolen rods.") + ReinforcementsObjective = GDI.AddObjective("Eliminate " .. KillsUntilReinforcements .. " Nod units for reinforcements.", "Secondary", false) - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - - gdiObjective = player.AddPrimaryObjective("Retrieve the crate with the stolen rods.") - reinforcementsObjective = player.AddSecondaryObjective("Eliminate " .. KillsUntilReinforcements .. " Nod units for reinforcements.") - enemy.AddPrimaryObjective("Defend against the GDI forces.") - - BuildNod1() + BuildNod() Utils.Do(NodHelis, function(heli) Trigger.AfterDelay(heli.delay, function() SendHeli(heli) end) end) - autoTrigger = false Trigger.OnEnteredFootprint(AutoTrigger, function(a, id) - if not autoTrigger and a.Owner == player then + if not autoTrigger and a.Owner == GDI then autoTrigger = true Trigger.RemoveFootprintTrigger(id) - BuildAuto1() + BuildAuto() end end) - gdiHeliTrigger = false Trigger.OnEnteredFootprint(GDIHeliTrigger, function(a, id) - if not gdiHeliTrigger and a.Owner == player then + if not gdiHeliTrigger and a.Owner == GDI then gdiHeliTrigger = true Trigger.RemoveFootprintTrigger(id) - Reinforcements.ReinforceWithTransport(player, "tran", nil, { GDIHeliEntry.Location, GDIHeliLZ.Location }) + Reinforcements.ReinforceWithTransport(GDI, "tran", nil, { GDIHeliEntry.Location, GDIHeliLZ.Location }) end end) diff --git a/mods/cnc/maps/gdi04a/rules.yaml b/mods/cnc/maps/gdi04a/rules.yaml index aaa6e24231..f30e998d59 100644 --- a/mods/cnc/maps/gdi04a/rules.yaml +++ b/mods/cnc/maps/gdi04a/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: gdi04a.lua + Scripts: campaign-global.lua, gdi04a.lua MusicPlaylist: StartingMusic: fist226m MissionData: diff --git a/mods/cnc/maps/gdi04b/gdi04b.lua b/mods/cnc/maps/gdi04b/gdi04b.lua index 3060eadd76..30c1085a46 100644 --- a/mods/cnc/maps/gdi04b/gdi04b.lua +++ b/mods/cnc/maps/gdi04b/gdi04b.lua @@ -6,6 +6,7 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + BhndTrigger = { CPos.New(39, 21), CPos.New(40, 21), CPos.New(41, 21) } Atk1Trigger = { CPos.New(35, 37) } Atk2Trigger = { CPos.New(9, 44), CPos.New(10, 44), CPos.New(11, 44), CPos.New(12, 44), CPos.New(13, 44) } @@ -23,30 +24,34 @@ GDIReinforcementsWaypoints = { GDIReinforcementsEntry.Location, GDIReinforcement NodHeli = { { HeliEntry.Location, NodHeliLZ.Location }, { "e1", "e1", "e3", "e3" } } +Kills = 0 +NodUnitKilled = function() + Kills = Kills + 1 + + if Kills == KillsUntilReinforcements then + GDI.MarkCompletedObjective(ReinforcementsObjective) + SendGDIReinforcements() + end +end + SendHeli = function(heli) - units = Reinforcements.ReinforceWithTransport(enemy, "tran", heli[2], heli[1], { heli[1][1] }) + local units = Reinforcements.ReinforceWithTransport(Nod, "tran", heli[2], heli[1], { heli[1][1] }) Utils.Do(units[2], function(actor) - actor.Hunt() - Trigger.OnIdle(actor, actor.Hunt) - Trigger.OnKilled(actor, KillCounter) + IdleHunt(actor) + Trigger.OnKilled(actor, NodUnitKilled) end) end SendGDIReinforcements = function() - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.ReinforceWithTransport(player, "apc", GDIReinforcements, GDIReinforcementsWaypoints, nil, function(apc, team) + Media.PlaySpeechNotification(GDI, "Reinforce") + Reinforcements.ReinforceWithTransport(GDI, "apc", GDIReinforcements, GDIReinforcementsWaypoints, nil, function(apc, team) table.insert(team, apc) Trigger.OnAllKilled(team, function() Trigger.AfterDelay(DateTime.Seconds(5), SendGDIReinforcements) end) - Utils.Do(team, function(unit) unit.Stance = "Defend" end) end) end Build = function(unitTypes, repeats, func) - if HandOfNod.IsDead then - return - end - - local innerFunc = function(units) + local after = function(units) Utils.Do(units, func) if repeats then Trigger.OnAllKilled(units, function() @@ -62,135 +67,92 @@ Build = function(unitTypes, repeats, func) end end -BuildNod1 = function() - Build(NodxUnits, false, function(actor) - Trigger.OnKilled(actor, KillCounter) - actor.Patrol({ NodPatrol1.Location, NodPatrol2.Location, NodPatrol3.Location, NodPatrol4.Location }, false) - Trigger.OnIdle(actor, actor.Hunt) - end) -end - -BuildNod2 = function() - Build(NodxUnits, false, function(actor) - Trigger.OnKilled(actor, KillCounter) - actor.Patrol({ NodPatrol1.Location, NodPatrol2.Location }, false) - Trigger.OnIdle(actor, actor.Hunt) - end) -end - -BuildAuto = function() - Build(AutoUnits, true, function(actor) - Trigger.OnKilled(actor, KillCounter) - Trigger.OnIdle(actor, actor.Hunt) - end) -end - -ReinforcementsSent = false -kills = 0 -KillCounter = function() kills = kills + 1 end Tick = function() - enemy.Cash = 1000 + Nod.Cash = 1000 - if not ReinforcementsSent and kills >= KillsUntilReinforcements then - ReinforcementsSent = true - player.MarkCompletedObjective(reinforcementsObjective) - SendGDIReinforcements() - end - - if player.HasNoRequiredUnits() then + if GDI.HasNoRequiredUnits() then Trigger.AfterDelay(DateTime.Seconds(1), function() - player.MarkFailedObjective(gdiObjective) + GDI.MarkFailedObjective(gdiObjective) end) end end SetupWorld = function() - Utils.Do(enemy.GetGroundAttackers(), function(unit) - Trigger.OnKilled(unit, KillCounter) + Utils.Do(Nod.GetGroundAttackers(), function(unit) + Trigger.OnKilled(unit, NodUnitKilled) end) - Utils.Do(player.GetGroundAttackers(), function(unit) - unit.Stance = "Defend" - end) + Utils.Do(Hunters, IdleHunt) - Utils.Do(Hunters, function(actor) actor.Hunt() end) - - Trigger.OnRemovedFromWorld(crate, function() player.MarkCompletedObjective(gdiObjective) end) + Trigger.OnRemovedFromWorld(crate, function() GDI.MarkCompletedObjective(GDIObjective) end) end WorldLoaded = function() - player = Player.GetPlayer("GDI") - enemy = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) + InitObjectives(GDI) - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) - - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - gdiObjective = player.AddPrimaryObjective("Retrieve the crate with the stolen rods.") - reinforcementsObjective = player.AddSecondaryObjective("Eliminate " .. KillsUntilReinforcements .. " Nod units for reinforcements.") - enemy.AddPrimaryObjective("Defend against the GDI forces.") + GDIObjective = GDI.AddObjective("Retrieve the crate with the stolen rods.") + ReinforcementsObjective = GDI.AddObjective("Eliminate " .. KillsUntilReinforcements .. " Nod units for reinforcements.", "Secondary", false) SetupWorld() - bhndTrigger = false Trigger.OnExitedFootprint(BhndTrigger, function(a, id) - if not bhndTrigger and a.Owner == player then + if not bhndTrigger and a.Owner == GDI then bhndTrigger = true Trigger.RemoveFootprintTrigger(id) SendHeli(NodHeli) end end) - atk1Trigger = false Trigger.OnExitedFootprint(Atk1Trigger, function(a, id) - if not atk1Trigger and a.Owner == player then + if not atk1Trigger and a.Owner == GDI then atk1Trigger = true Trigger.RemoveFootprintTrigger(id) - BuildNod1() - end - end) - atk2Trigger = false - Trigger.OnEnteredFootprint(Atk2Trigger, function(a, id) - if not atk2Trigger and a.Owner == player then - atk2Trigger = true - Trigger.RemoveFootprintTrigger(id) - BuildNod2() - end - end) - - autoTrigger = false - Trigger.OnEnteredFootprint(AutoTrigger, function(a, id) - if not autoTrigger and a.Owner == player then - autoTrigger = true - Trigger.RemoveFootprintTrigger(id) - BuildAuto() - Trigger.AfterDelay(DateTime.Seconds(4), function() - tank.Hunt() + Build(NodxUnits, false, function(actor) + Trigger.OnKilled(actor, NodUnitKilled) + actor.Patrol({ NodPatrol1.Location, NodPatrol2.Location, NodPatrol3.Location, NodPatrol4.Location }, false) + Trigger.OnIdle(actor, actor.Hunt) + end) + end + end) + + Trigger.OnEnteredFootprint(Atk2Trigger, function(a, id) + if not atk2Trigger and a.Owner == GDI then + atk2Trigger = true + Trigger.RemoveFootprintTrigger(id) + + Build(NodxUnits, false, function(actor) + Trigger.OnKilled(actor, NodUnitKilled) + actor.Patrol({ NodPatrol1.Location, NodPatrol2.Location }, false) + IdleHunt(actor) + end) + end + end) + + Trigger.OnEnteredFootprint(AutoTrigger, function(a, id) + if not autoTrigger and a.Owner == GDI then + autoTrigger = true + Trigger.RemoveFootprintTrigger(id) + + Build(AutoUnits, true, function(actor) + Trigger.OnKilled(actor, NodUnitKilled) + IdleHunt(actor) + end) + + Trigger.AfterDelay(DateTime.Seconds(4), function() + IdleHunt(tank) end) end end) - gdiHeliTrigger = false Trigger.OnEnteredFootprint(GDIHeliTrigger, function(a, id) - if not gdiHeliTrigger and a.Owner == player then + if not gdiHeliTrigger and a.Owner == GDI then gdiHeliTrigger = true Trigger.RemoveFootprintTrigger(id) - Reinforcements.ReinforceWithTransport(player, "tran", nil, { HeliEntry.Location, GDIHeliLZ.Location }) + Reinforcements.ReinforceWithTransport(GDI, "tran", nil, { HeliEntry.Location, GDIHeliLZ.Location }) end end) diff --git a/mods/cnc/maps/gdi04b/rules.yaml b/mods/cnc/maps/gdi04b/rules.yaml index 52ff6e64bf..1cf712f95c 100644 --- a/mods/cnc/maps/gdi04b/rules.yaml +++ b/mods/cnc/maps/gdi04b/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: gdi04b.lua + Scripts: campaign-global.lua, gdi04b.lua MusicPlaylist: StartingMusic: fist226m MissionData: diff --git a/mods/cnc/maps/gdi04c/gdi04c.lua b/mods/cnc/maps/gdi04c/gdi04c.lua index 15b41e5370..50d09a20a5 100644 --- a/mods/cnc/maps/gdi04c/gdi04c.lua +++ b/mods/cnc/maps/gdi04c/gdi04c.lua @@ -6,6 +6,7 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + LoseTriggerHouses = { TrigLos2Farm1, TrigLos2Farm2, TrigLos2Farm3, TrigLos2Farm4 } TownAttackTrigger = { CPos.New(54, 38), CPos.New(55, 38), CPos.New(56, 38), CPos.New(57, 38) } GDIReinforcementsTrigger = { CPos.New(32, 51), CPos.New(32, 52), CPos.New(33, 52) } @@ -44,83 +45,56 @@ TownAttackAction = function(actor) end AttackTown = function() - Reinforcements.Reinforce(enemy, TownAttackWave1, { NodReinfEntry.Location, NodReinfRally.Location }, DateTime.Seconds(0.25), TownAttackAction) + Reinforcements.Reinforce(Nod, TownAttackWave1, { NodReinfEntry.Location, NodReinfRally.Location }, DateTime.Seconds(0.25), TownAttackAction) Trigger.AfterDelay(DateTime.Seconds(2), function() - Reinforcements.Reinforce(enemy, TownAttackWave2, { NodReinfEntry.Location, NodReinfRally.Location }, DateTime.Seconds(1), TownAttackAction) + Reinforcements.Reinforce(Nod, TownAttackWave2, { NodReinfEntry.Location, NodReinfRally.Location }, DateTime.Seconds(1), TownAttackAction) end) Trigger.AfterDelay(DateTime.Seconds(4), function() - Reinforcements.Reinforce(enemy, TownAttackWave3, { NodReinfEntry.Location, NodReinfRally.Location }, DateTime.Seconds(1), TownAttackAction) + Reinforcements.Reinforce(Nod, TownAttackWave3, { NodReinfEntry.Location, NodReinfRally.Location }, DateTime.Seconds(1), TownAttackAction) end) end SendGDIReinforcements = function() - Reinforcements.Reinforce(player, GDIReinforcementsPart1, { GDIReinfEntry1.Location, GDIReinfRally1.Location }, DateTime.Seconds(1), function(actor) - Media.PlaySpeechNotification(player, "Reinforce") - actor.Move(GDIReinfRally3.Location) - actor.Stance = "Defend" - end) + Media.PlaySpeechNotification(GDI, "Reinforce") + Reinforcements.Reinforce(GDI, GDIReinforcementsPart1, { GDIReinfEntry1.Location, GDIReinfRally1.Location, GDIReinfRally3.Location }, DateTime.Seconds(1)) + Trigger.AfterDelay(DateTime.Seconds(5), function() - Reinforcements.ReinforceWithTransport(player, "apc", GDIReinforcementsPart2, { GDIReinfEntry2.Location, GDIReinfRally2.Location }, nil, function(apc, team) - Media.PlaySpeechNotification(player, "Reinforce") - apc.Move(GDIUnloadWpt.Location) - apc.UnloadPassengers() - Utils.Do(team, function(unit) unit.Stance = "Defend" end) - end) + Media.PlaySpeechNotification(GDI, "Reinforce") + local apc = Reinforcements.ReinforceWithTransport(GDI, "apc", GDIReinforcementsPart2, { GDIReinfEntry2.Location, GDIReinfRally2.Location, GDIUnloadWpt.Location })[1] + apc.UnloadPassengers() end) end WorldLoaded = function() - player = Player.GetPlayer("GDI") - enemy = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) + InitObjectives(GDI) Trigger.OnAllKilled(LoseTriggerHouses, function() - player.MarkFailedObjective(gdiObjective1) + GDI.MarkFailedObjective(DefendTown) end) - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) + NodObjective = Nod.AddPrimaryObjective("Destroy all GDI troops.") + DefendTown = GDI.AddPrimaryObjective("Defend the town of Białystok.") + EliminateNod = GDI.AddPrimaryObjective("Eliminate all Nod forces in the area.") - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - nodObjective = enemy.AddPrimaryObjective("Destroy all GDI troops.") - gdiObjective1 = player.AddPrimaryObjective("Defend the town of Białystok.") - gdiObjective2 = player.AddPrimaryObjective("Eliminate all Nod forces in the area.") - - townAttackTrigger = false Trigger.OnExitedFootprint(TownAttackTrigger, function(a, id) - if not townAttackTrigger and a.Owner == player then + if not townAttackTrigger and a.Owner == GDI then townAttackTrigger = true Trigger.RemoveFootprintTrigger(id) AttackTown() end end) - gdiReinforcementsTrigger = false Trigger.OnEnteredFootprint(GDIReinforcementsTrigger, function(a, id) - if not gdiReinforcementsTrigger and a.Owner == player then + if not gdiReinforcementsTrigger and a.Owner == GDI then gdiReinforcementsTrigger = true Trigger.RemoveFootprintTrigger(id) SendGDIReinforcements() end end) - Utils.Do(player.GetGroundAttackers(), function(unit) - unit.Stance = "Defend" - end) - Trigger.AfterDelay(1, function() FollowCivvieWpts(civvie1, Civvie1Wpts) FollowCivvieWpts(civvie2, Civvie2Wpts) @@ -130,11 +104,12 @@ WorldLoaded = function() end Tick = function() - if player.HasNoRequiredUnits() then - enemy.MarkCompletedObjective(nodObjective) + if GDI.HasNoRequiredUnits() then + Nod.MarkCompletedObjective(NodObjective) end - if enemy.HasNoRequiredUnits() then - player.MarkCompletedObjective(gdiObjective1) - player.MarkCompletedObjective(gdiObjective2) + + if Nod.HasNoRequiredUnits() then + GDI.MarkCompletedObjective(DefendTown) + GDI.MarkCompletedObjective(EliminateNod) end end diff --git a/mods/cnc/maps/gdi04c/rules.yaml b/mods/cnc/maps/gdi04c/rules.yaml index cda80f7ab7..8fe9733b21 100644 --- a/mods/cnc/maps/gdi04c/rules.yaml +++ b/mods/cnc/maps/gdi04c/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: gdi04c.lua + Scripts: campaign-global.lua, gdi04c.lua MusicPlaylist: StartingMusic: ind MissionData: diff --git a/mods/cnc/maps/gdi05a/gdi05a.lua b/mods/cnc/maps/gdi05a/gdi05a.lua index e87a9d16d2..c6bf55a2a9 100644 --- a/mods/cnc/maps/gdi05a/gdi05a.lua +++ b/mods/cnc/maps/gdi05a/gdi05a.lua @@ -6,6 +6,7 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + RepairThreshold = { easy = 0.3, normal = 0.6, hard = 0.9 } ActorRemovals = @@ -18,17 +19,16 @@ ActorRemovals = GdiTanks = { "mtnk", "mtnk" } GdiApc = { "apc" } GdiInfantry = { "e1", "e1", "e1", "e1", "e1", "e2", "e2", "e2", "e2", "e2" } -GdiBase = { GdiNuke1, GdiNuke2, GdiProc, GdiSilo1, GdiSilo2, GdiPyle, GdiWeap, GdiHarv } +GDIBase = { GdiNuke1, GdiNuke2, GdiProc, GdiSilo1, GdiSilo2, GdiPyle, GdiWeap, GdiHarv } NodSams = { Sam1, Sam2, Sam3, Sam4 } CoreNodBase = { NodConYard, NodRefinery, HandOfNod, Airfield } -Grd1UnitTypes = { "bggy" } -Grd1Path = { waypoint4.Location, waypoint5.Location, waypoint10.Location } -Grd1Delay = { easy = DateTime.Minutes(2), normal = DateTime.Minutes(1), hard = DateTime.Seconds(30) } -Grd2UnitTypes = { "bggy" } -Grd2Path = { waypoint0.Location, waypoint1.Location, waypoint2.Location } -Grd3Units = { GuardTank1, GuardTank2 } -Grd3Path = { waypoint4.Location, waypoint5.Location, waypoint9.Location } +Guard1UnitTypes = { "bggy" } +Guard1Path = { waypoint4.Location, waypoint5.Location, waypoint10.Location } +Guard1Delay = { easy = DateTime.Minutes(2), normal = DateTime.Minutes(1), hard = DateTime.Seconds(30) } +Guard2UnitTypes = { "bggy" } +Guard2Path = { waypoint0.Location, waypoint1.Location, waypoint2.Location } +Guard3Path = { waypoint4.Location, waypoint5.Location, waypoint9.Location } AttackDelayMin = { easy = DateTime.Minutes(1), normal = DateTime.Seconds(45), hard = DateTime.Seconds(30) } AttackDelayMax = { easy = DateTime.Minutes(2), normal = DateTime.Seconds(90), hard = DateTime.Minutes(1) } @@ -57,165 +57,120 @@ AttackUnitTypes = { factory = Airfield, types = { "ltnk" } }, } } + AttackPaths = { { waypoint0.Location, waypoint1.Location, waypoint2.Location, waypoint3.Location }, { waypoint4.Location, waypoint9.Location, waypoint7.Location, waypoint8.Location }, } -Build = function(factory, units, action) - if factory.IsDead or factory.Owner ~= enemy then - return - end - - if not factory.Build(units, action) then - Trigger.AfterDelay(DateTime.Seconds(5), function() - Build(factory, units, action) - end) - end -end - Attack = function() - local production = Utils.Random(AttackUnitTypes[Map.LobbyOption("difficulty")]) + local production = Utils.Random(AttackUnitTypes[Difficulty]) local path = Utils.Random(AttackPaths) - Build(production.factory, production.types, function(units) + local toBuild = function() return production.types end + ProduceUnits(Nod, production.factory, nil, toBuild, function(units) Utils.Do(units, function(unit) - if unit.Owner ~= enemy then return end unit.Patrol(path, false) - Trigger.OnIdle(unit, unit.Hunt) + IdleHunt(unit) end) end) - Trigger.AfterDelay(Utils.RandomInteger(AttackDelayMin[Map.LobbyOption("difficulty")], AttackDelayMax[Map.LobbyOption("difficulty")]), Attack) + Trigger.AfterDelay(Utils.RandomInteger(AttackDelayMin[Difficulty], AttackDelayMax[Difficulty]), Attack) end -Grd1Action = function() - Build(Airfield, Grd1UnitTypes, function(units) +Guard1Action = function() + ProduceUnits(Nod, Airfield, nil, function() return Guard1UnitTypes end, function(units) + Trigger.OnAllKilled(units, function() + Trigger.AfterDelay(Guard1Delay[Difficulty], Guard1Action) + end) + Utils.Do(units, function(unit) - if unit.Owner ~= enemy then return end - Trigger.OnKilled(unit, function() - Trigger.AfterDelay(Grd1Delay[Map.LobbyOption("difficulty")], Grd1Action) - end) - unit.Patrol(Grd1Path, true, DateTime.Seconds(7)) + unit.Patrol(Guard1Path, true, DateTime.Seconds(7)) end) end) end -Grd2Action = function() - Build(Airfield, Grd2UnitTypes, function(units) +Guard2Action = function() + ProduceUnits(Nod, Airfield, nil, function() return Guard2UnitTypes end, function(units) Utils.Do(units, function(unit) - if unit.Owner ~= enemy then return end - unit.Patrol(Grd2Path, true, DateTime.Seconds(5)) + unit.Patrol(Guard2Path, true, DateTime.Seconds(5)) end) end) end -Grd3Action = function() - local unit - for i, u in ipairs(Grd3Units) do - if not u.IsDead then - unit = u - break - end - end - - if unit ~= nil then - Trigger.OnKilled(unit, function() - Grd3Action() - end) - - unit.Patrol(Grd3Path, true, DateTime.Seconds(11)) - end -end - -DiscoverGdiBase = function(actor, discoverer) - if baseDiscovered or not discoverer == player then +DiscoverGDIBase = function(actor, discoverer) + if BaseDiscovered or not discoverer == GDI then return end - Utils.Do(GdiBase, function(actor) - actor.Owner = player + Utils.Do(GDIBase, function(actor) + actor.Owner = GDI end) - baseDiscovered = true + BaseDiscovered = true - gdiObjective3 = player.AddPrimaryObjective("Eliminate all Nod forces in the area.") - player.MarkCompletedObjective(gdiObjective1) + EliminateNod = GDI.AddObjective("Eliminate all Nod forces in the area.") + GDI.MarkCompletedObjective(FindBase) Attack() end SetupWorld = function() - Utils.Do(ActorRemovals[Map.LobbyOption("difficulty")], function(unit) + Utils.Do(ActorRemovals[Difficulty], function(unit) unit.Destroy() end) - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.Reinforce(player, GdiTanks, { GdiTankEntry.Location, GdiTankRallyPoint.Location }, DateTime.Seconds(1), function(actor) actor.Stance = "Defend" end) - Reinforcements.Reinforce(player, GdiApc, { GdiApcEntry.Location, GdiApcRallyPoint.Location }, DateTime.Seconds(1), function(actor) actor.Stance = "Defend" end) - Reinforcements.Reinforce(player, GdiInfantry, { GdiInfantryEntry.Location, GdiInfantryRallyPoint.Location }, 15, function(actor) actor.Stance = "Defend" end) + Media.PlaySpeechNotification(GDI, "Reinforce") + Reinforcements.Reinforce(GDI, GdiTanks, { GdiTankEntry.Location, GdiTankRallyPoint.Location }, DateTime.Seconds(1), function(actor) actor.Stance = "Defend" end) + Reinforcements.Reinforce(GDI, GdiApc, { GdiApcEntry.Location, GdiApcRallyPoint.Location }, DateTime.Seconds(1), function(actor) actor.Stance = "Defend" end) + Reinforcements.Reinforce(GDI, GdiInfantry, { GdiInfantryEntry.Location, GdiInfantryRallyPoint.Location }, 15, function(actor) actor.Stance = "Defend" end) - Trigger.OnPlayerDiscovered(gdiBase, DiscoverGdiBase) + Trigger.OnPlayerDiscovered(AbandonedBase, DiscoverGDIBase) - Utils.Do(Map.NamedActors, function(actor) - if actor.Owner == enemy and actor.HasProperty("StartBuildingRepairs") then - Trigger.OnDamaged(actor, function(building) - if building.Owner == enemy and building.Health < RepairThreshold[Map.LobbyOption("difficulty")] * building.MaxHealth then - building.StartBuildingRepairs() - end - end) - end - end) + RepairNamedActors(Nod, RepairThreshold[Difficulty]) Trigger.OnAllKilled(NodSams, function() - player.MarkCompletedObjective(gdiObjective2) - Actor.Create("airstrike.proxy", true, { Owner = player }) + GDI.MarkCompletedObjective(DestroySAMs) + Actor.Create("airstrike.proxy", true, { Owner = GDI }) end) - GdiHarv.Stop() - NodHarv.FindResources() - if Map.LobbyOption("difficulty") ~= "easy" then + Trigger.AfterDelay(0, function() + GdiHarv.Stop() + end) + + if Difficulty ~= "easy" then Trigger.OnDamaged(NodHarv, function() - Utils.Do(enemy.GetGroundAttackers(), function(unit) + Utils.Do(Nod.GetGroundAttackers(), function(unit) unit.AttackMove(NodHarv.Location) - if Map.LobbyOption("difficulty") == "hard" then - unit.Hunt() + if Difficulty == "hard" then + IdleHunt(unit) end end) end) end - Trigger.AfterDelay(DateTime.Seconds(45), Grd1Action) - Trigger.AfterDelay(DateTime.Minutes(3), Grd2Action) - Grd3Action() + Trigger.AfterDelay(DateTime.Seconds(45), Guard1Action) + Trigger.AfterDelay(DateTime.Minutes(3), Guard2Action) + + Trigger.OnKilled(GuardTank1, function() + if not GuardTank2.IsDead then + GuardTank2.Patrol(Guard3Path, true, DateTime.Seconds(11)) + end + end) + + GuardTank1.Patrol(Guard3Path, true, DateTime.Seconds(11)) end WorldLoaded = function() - gdiBase = Player.GetPlayer("AbandonedBase") - player = Player.GetPlayer("GDI") - enemy = Player.GetPlayer("Nod") + AbandonedBase = Player.GetPlayer("AbandonedBase") + GDI = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) + InitObjectives(GDI) - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) - - nodObjective = enemy.AddPrimaryObjective("Destroy all GDI troops.") - gdiObjective1 = player.AddPrimaryObjective("Find the GDI base.") - gdiObjective2 = player.AddSecondaryObjective("Destroy all SAM sites to receive air support.") + NodObjective = Nod.AddObjective("Destroy all GDI troops.") + FindBase = GDI.AddObjective("Find the GDI base.") + DestroySAMs = GDI.AddObjective("Destroy all SAM sites to receive air support.", "Secondary", false) SetupWorld() @@ -223,12 +178,11 @@ WorldLoaded = function() end Tick = function() - if player.HasNoRequiredUnits() then - if DateTime.GameTime > 2 then - enemy.MarkCompletedObjective(nodObjective) - end + if DateTime.GameTime > 2 and GDI.HasNoRequiredUnits() then + Nod.MarkCompletedObjective(NodObjective) end - if baseDiscovered and enemy.HasNoRequiredUnits() then - player.MarkCompletedObjective(gdiObjective3) + + if BaseDiscovered and Nod.HasNoRequiredUnits() then + GDI.MarkCompletedObjective(EliminateNod) end end diff --git a/mods/cnc/maps/gdi05a/rules.yaml b/mods/cnc/maps/gdi05a/rules.yaml index 81753efc4c..0de22f55ed 100644 --- a/mods/cnc/maps/gdi05a/rules.yaml +++ b/mods/cnc/maps/gdi05a/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: gdi05a.lua + Scripts: campaign-global.lua, gdi05a.lua MusicPlaylist: StartingMusic: rain MissionData: @@ -34,6 +34,7 @@ World: normal: Normal hard: Hard Default: easy + Locked: false Player: EnemyWatcher: diff --git a/mods/cnc/maps/gdi05b/gdi05b.lua b/mods/cnc/maps/gdi05b/gdi05b.lua index 67bffb472b..d1757cc4c8 100644 --- a/mods/cnc/maps/gdi05b/gdi05b.lua +++ b/mods/cnc/maps/gdi05b/gdi05b.lua @@ -6,6 +6,7 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + AllToHuntTrigger = { Silo1, Proc1, Silo2, Silo3, Silo4, Afld1, Hand1, Nuke1, Nuke2, Nuke3, Fact1 @@ -43,17 +44,10 @@ Atk5CellTriggers = CPos.New(49,53), CPos.New(48,53), CPos.New(50,52), CPos.New(49,52) } -GdiBase = { GdiNuke1, GdiProc1, GdiWeap1, GdiNuke2, GdiPyle1, GdiSilo1, GdiSilo2, GdiHarv } -GdiUnits = { "e2", "e2", "e2", "e2", "e1", "e1", "e1", "e1", "mtnk", "mtnk", "jeep", "jeep", "apc" } +GDIBase = { GdiNuke1, GdiProc1, GdiWeap1, GdiNuke2, GdiPyle1, GdiSilo1, GdiSilo2, GdiHarv } +GDIUnits = { "e2", "e2", "e2", "e2", "e1", "e1", "e1", "e1", "mtnk", "mtnk", "jeep", "jeep", "apc" } NodSams = { Sam1, Sam2, Sam3, Sam4 } -AllToHunt = function() - local list = enemy.GetGroundAttackers() - Utils.Do(list, function(unit) - unit.Hunt() - end) -end - MoveThenHunt = function(actors, path) Utils.Do(actors, function(actor) actor.Patrol(path, false) @@ -64,139 +58,107 @@ end AutoCreateTeam = function() local team = Utils.Random(AutoCreateTeams) for type, count in pairs(team.types) do - MoveThenHunt(Utils.Take(count, enemy.GetActorsByType(type)), team.route) + MoveThenHunt(Utils.Take(count, Nod.GetActorsByType(type)), team.route) end Trigger.AfterDelay(Utils.RandomInteger(AutoAtkMinDelay, AutoAtkMaxDelay), AutoCreateTeam) end -DiscoverGdiBase = function(actor, discoverer) - if baseDiscovered or not discoverer == player then +DiscoverGDIBase = function(actor, discoverer) + if BaseDiscovered or not discoverer == GDI then return end - Utils.Do(GdiBase, function(actor) - actor.Owner = player + Utils.Do(GDIBase, function(actor) + actor.Owner = GDI end) - baseDiscovered = true + BaseDiscovered = true - gdiObjective3 = player.AddPrimaryObjective("Eliminate all Nod forces in the area.") - player.MarkCompletedObjective(gdiObjective1) + EliminateNod = GDI.AddObjective("Eliminate all Nod forces in the area.") + GDI.MarkCompletedObjective(FindBase) end Atk1TriggerFunction = function() - MoveThenHunt(Utils.Take(2, enemy.GetActorsByType('e1')), AtkRoute1) - MoveThenHunt(Utils.Take(3, enemy.GetActorsByType('e3')), AtkRoute1) + MoveThenHunt(Utils.Take(2, Nod.GetActorsByType('e1')), AtkRoute1) + MoveThenHunt(Utils.Take(3, Nod.GetActorsByType('e3')), AtkRoute1) end Atk2TriggerFunction = function() - MoveThenHunt(Utils.Take(3, enemy.GetActorsByType('e1')), AtkRoute2) - MoveThenHunt(Utils.Take(3, enemy.GetActorsByType('e3')), AtkRoute2) + MoveThenHunt(Utils.Take(3, Nod.GetActorsByType('e1')), AtkRoute2) + MoveThenHunt(Utils.Take(3, Nod.GetActorsByType('e3')), AtkRoute2) end Atk3TriggerFunction = function() - MoveThenHunt(Utils.Take(1, enemy.GetActorsByType('bggy')), AtkRoute1) + MoveThenHunt(Utils.Take(1, Nod.GetActorsByType('bggy')), AtkRoute1) end Atk4TriggerFunction = function() - MoveThenHunt(Utils.Take(1, enemy.GetActorsByType('bggy')), AtkRoute2) + MoveThenHunt(Utils.Take(1, Nod.GetActorsByType('bggy')), AtkRoute2) end Atk5TriggerFunction = function() - MoveThenHunt(Utils.Take(1, enemy.GetActorsByType('ltnk')), AtkRoute2) + MoveThenHunt(Utils.Take(1, Nod.GetActorsByType('ltnk')), AtkRoute2) end -StartProduction = function(type) - if Hand1.IsInWorld and Hand1.Owner == enemy then - Hand1.Build(type) - Trigger.AfterDelay(DateTime.Seconds(30), function() StartProduction(type) end) - end -end - -InsertGdiUnits = function() - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.Reinforce(player, GdiUnits, { UnitsEntry.Location, UnitsRally.Location }, 15) -end - -IdleHunt = function(unit) - if not unit.IsDead then - Trigger.OnIdle(unit, unit.Hunt) - end +InsertGDIUnits = function() + Media.PlaySpeechNotification(GDI, "Reinforce") + Reinforcements.Reinforce(GDI, GDIUnits, { UnitsEntry.Location, UnitsRally.Location }, 15) end WorldLoaded = function() - player = Player.GetPlayer("GDI") - gdiBase = Player.GetPlayer("AbandonedBase") - enemy = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") + AbandonedBase = Player.GetPlayer("AbandonedBase") + Nod = Player.GetPlayer("Nod") - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) + InitObjectives(GDI) - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) + RepairNamedActors(Nod, RepairThreshold) - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - Utils.Do(Map.NamedActors, function(actor) - if actor.Owner == enemy and actor.HasProperty("StartBuildingRepairs") then - Trigger.OnDamaged(actor, function(building) - if building.Owner == enemy and building.Health < RepairThreshold * building.MaxHealth then - building.StartBuildingRepairs() - end - end) - end - end) - - gdiObjective1 = player.AddPrimaryObjective("Find the GDI base.") - gdiObjective2 = player.AddSecondaryObjective("Destroy all SAM sites to receive air support.") - nodObjective = enemy.AddPrimaryObjective("Destroy all GDI troops.") + FindBase = GDI.AddObjective("Find the GDI base.") + DestroySAMs = GDI.AddObjective("Destroy all SAM sites to receive air support.", "Secondary", false) + NodObjective = Nod.AddObjective("Destroy all GDI troops.") Trigger.AfterDelay(Atk1Delay, Atk1TriggerFunction) Trigger.AfterDelay(Atk2Delay, Atk2TriggerFunction) Trigger.AfterDelay(Atk3Delay, Atk3TriggerFunction) Trigger.AfterDelay(Atk4Delay, Atk4TriggerFunction) Trigger.OnEnteredFootprint(Atk5CellTriggers, function(a, id) - if a.Owner == player then + if a.Owner == GDI then Atk5TriggerFunction() Trigger.RemoveFootprintTrigger(id) end end) Trigger.AfterDelay(AutoAtkStartDelay, AutoCreateTeam) - Trigger.OnAllRemovedFromWorld(AllToHuntTrigger, AllToHunt) + Trigger.OnAllRemovedFromWorld(AllToHuntTrigger, function() + Utils.Do(Nod.GetGroundAttackers(), IdleHunt) + end) - Trigger.AfterDelay(DateTime.Seconds(40), function() StartProduction({ "e1" }) end) + Trigger.AfterDelay(DateTime.Seconds(40), function() + local delay = function() return DateTime.Seconds(30) end + local toBuild = function() return { "e1" } end + ProduceUnits(Nod, Hand1, delay, toBuild) + end) - Trigger.OnPlayerDiscovered(gdiBase, DiscoverGdiBase) + Trigger.OnPlayerDiscovered(AbandonedBase, DiscoverGDIBase) Trigger.OnAllKilled(NodSams, function() - player.MarkCompletedObjective(gdiObjective2) - Actor.Create("airstrike.proxy", true, { Owner = player }) + GDI.MarkCompletedObjective(DestroySAMs) + Actor.Create("airstrike.proxy", true, { Owner = GDI }) end) Camera.Position = UnitsRally.CenterPosition - InsertGdiUnits() + InsertGDIUnits() end Tick = function() - if player.HasNoRequiredUnits() then - if DateTime.GameTime > 2 then - enemy.MarkCompletedObjective(nodObjective) - end + if DateTime.GameTime > 2 and GDI.HasNoRequiredUnits() then + Nod.MarkCompletedObjective(NodObjective) end - if baseDiscovered and enemy.HasNoRequiredUnits() then - player.MarkCompletedObjective(gdiObjective3) + + if BaseDiscovered and Nod.HasNoRequiredUnits() then + GDI.MarkCompletedObjective(EliminateNod) end end diff --git a/mods/cnc/maps/gdi05b/rules.yaml b/mods/cnc/maps/gdi05b/rules.yaml index 555b9cc858..1c877382c6 100644 --- a/mods/cnc/maps/gdi05b/rules.yaml +++ b/mods/cnc/maps/gdi05b/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: gdi05b.lua + Scripts: campaign-global.lua, gdi05b.lua MusicPlaylist: StartingMusic: rain MissionData: diff --git a/mods/cnc/maps/gdi06/gdi06.lua b/mods/cnc/maps/gdi06/gdi06.lua index 9741a9d296..3f6bc10758 100644 --- a/mods/cnc/maps/gdi06/gdi06.lua +++ b/mods/cnc/maps/gdi06/gdi06.lua @@ -6,6 +6,7 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + IslandSamSites = { SAM01, SAM02 } NodBase = { PowerPlant1, PowerPlant2, PowerPlant3, PowerPlant4, PowerPlant5, Refinery, HandOfNod, Silo1, Silo2, Silo3, Silo4, ConYard, CommCenter } @@ -13,7 +14,8 @@ FlameSquad = { FlameGuy1, FlameGuy2, FlameGuy3 } FlameSquadRoute = { waypoint4.Location, waypoint12.Location, waypoint4.Location, waypoint6.Location } FootPatrol1Squad = { MiniGunner1, MiniGunner2, RocketSoldier1 } -FootPatrol1Route = { +FootPatrol1Route = +{ waypoint4.Location, waypoint12.Location, waypoint13.Location, @@ -24,24 +26,28 @@ FootPatrol1Route = { } FootPatrol2Squad = { MiniGunner3, MiniGunner4 } -FootPatrol2Route = { +FootPatrol2Route = +{ waypoint14.Location, waypoint16.Location } FootPatrol3Squad = { MiniGunner5, MiniGunner6 } -FootPatrol3Route = { +FootPatrol3Route = +{ waypoint15.Location, waypoint17.Location } -FootPatrol4Route = { +FootPatrol4Route = +{ waypoint4.Location, waypoint5.Location } FootPatrol5Squad = { RocketSoldier2, RocketSoldier3, RocketSoldier4 } -FootPatrol5Route = { +FootPatrol5Route = +{ waypoint4.Location, waypoint12.Location, waypoint13.Location, @@ -49,7 +55,8 @@ FootPatrol5Route = { waypoint9.Location, } -Buggy1Route = { +Buggy1Route = +{ waypoint6.Location, waypoint7.Location, waypoint2.Location, @@ -60,7 +67,8 @@ Buggy1Route = { waypoint7.Location } -Buggy2Route = { +Buggy2Route = +{ waypoint6.Location, waypoint10.Location, waypoint11.Location, @@ -75,32 +83,15 @@ AttackUnits = { LightTank2, LightTank3 } KillCounter = 0 WorldLoaded = function() - player = Player.GetPlayer("GDI") - enemy = Player.GetPlayer("Nod") - civilian = Player.GetPlayer("Neutral") + GDI = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) + InitObjectives(GDI) - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) - - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - if Map.LobbyOption("difficulty") == "easy" then + if Difficulty == "easy" then CommandoType = "rmbo.easy" KillCounterHuntThreshold = 30 - elseif Map.LobbyOption("difficulty") == "hard" then + elseif Difficulty == "hard" then CommandoType = "rmbo.hard" KillCounterHuntThreshold = 15 else @@ -108,21 +99,21 @@ WorldLoaded = function() KillCounterHuntThreshold = 20 end - destroyObjective = player.AddPrimaryObjective("Destroy the Nod ********.") + DestroyObjective = GDI.AddObjective("Destroy the Nod ********.") Trigger.OnKilled(Airfield, function() - player.MarkCompletedObjective(destroyObjective) + GDI.MarkCompletedObjective(DestroyObjective) end) Utils.Do(NodBase, function(structure) Trigger.OnKilled(structure, function() - player.MarkCompletedObjective(destroyObjective) + GDI.MarkCompletedObjective(DestroyObjective) end) end) Trigger.OnAllKilled(IslandSamSites, function() - TransportFlare = Actor.Create('flare', true, { Owner = player, Location = Flare.Location }) - Reinforcements.ReinforceWithTransport(player, 'tran', nil, { lstStart.Location, TransportRally.Location }) + TransportFlare = Actor.Create('flare', true, { Owner = GDI, Location = Flare.Location }) + Reinforcements.ReinforceWithTransport(GDI, 'tran', nil, { lstStart.Location, TransportRally.Location }) end) Trigger.OnKilled(CivFleeTrigger, function() @@ -140,7 +131,7 @@ WorldLoaded = function() end) Trigger.OnEnteredFootprint(AttackCellTriggerActivator, function(a, id) - if a.Owner == player then + if a.Owner == GDI then Utils.Do(AttackUnits, function(unit) if not unit.IsDead then unit.AttackMove(waypoint10.Location) @@ -151,10 +142,21 @@ WorldLoaded = function() end) Utils.Do(HuntTriggerActivator, function(unit) - Trigger.OnDamaged(unit, HuntTriggerFunction) + Trigger.OnDamaged(unit, function() + Utils.Do(Nod.GetGroundAttackers(), IdleHunt) + end) end) - Trigger.AfterDelay(5, NodKillCounter) + Trigger.AfterDelay(5, function() + Utils.Do(Nod.GetGroundAttackers(), function(unit) + Trigger.OnKilled(unit, function() + KillCounter = KillCounter + 1 + if KillCounter >= KillCounterHuntThreshold then + Utils.Do(Nod.GetGroundAttackers(), IdleHunt) + end + end) + end) + end) Utils.Do(FootPatrol1Squad, function(unit) unit.Patrol(FootPatrol1Route, true) @@ -178,68 +180,12 @@ WorldLoaded = function() Buggy2.Patrol(Buggy2Route, true, 25) Camera.Position = UnitsRally.CenterPosition - Reinforce({ CommandoType }) + Media.PlaySpeechNotification(GDI, "Reinforce") + ReinforceWithLandingCraft(GDI, { CommandoType }, lstStart.Location, lstEnd.Location, UnitsRally.Location) end Tick = function() - if DateTime.GameTime > DateTime.Seconds(5) and player.HasNoRequiredUnits() then - player.MarkFailedObjective(destroyObjective) - end -end - -Reinforce = function(units) - Media.PlaySpeechNotification(player, "Reinforce") - ReinforceWithLandingCraft(units, lstStart.Location, lstEnd.Location, UnitsRally.Location) -end - -ReinforceWithLandingCraft = function(units, transportStart, transportUnload, rallypoint) - local transport = Actor.Create("oldlst", true, { Owner = player, Facing = 0, Location = transportStart }) - local subcell = 0 - Utils.Do(units, function(a) - transport.LoadPassenger(Actor.Create(a, false, { Owner = transport.Owner, Facing = transport.Facing, Location = transportUnload, SubCell = subcell })) - subcell = subcell + 1 - end) - - transport.ScriptedMove(transportUnload) - - transport.CallFunc(function() - Utils.Do(units, function() - local a = transport.UnloadPassenger() - a.IsInWorld = true - a.MoveIntoWorld(transport.Location - CVec.New(0, 1)) - - if rallypoint ~= nil then - a.Move(rallypoint) - end - end) - end) - - transport.Wait(5) - transport.ScriptedMove(transportStart) - transport.Destroy() -end - -NodKillCounter = function() - local enemyUnits = enemy.GetGroundAttackers() - Utils.Do(enemyUnits, function(unit) - Trigger.OnKilled(unit, function() - KillCounter = KillCounter + 1 - if KillCounter >= KillCounterHuntThreshold then - HuntTriggerFunction() - end - end) - end) -end - -HuntTriggerFunction = function() - local list = enemy.GetGroundAttackers() - Utils.Do(list, function(unit) - IdleHunt(unit) - end) -end - -IdleHunt = function(unit) - if not unit.IsDead then - Trigger.OnIdle(unit, unit.Hunt) + if DateTime.GameTime > DateTime.Seconds(5) and GDI.HasNoRequiredUnits() then + GDI.MarkFailedObjective(DestroyObjective) end end diff --git a/mods/cnc/maps/gdi06/rules.yaml b/mods/cnc/maps/gdi06/rules.yaml index ec6c5c4bc4..8e095ee486 100644 --- a/mods/cnc/maps/gdi06/rules.yaml +++ b/mods/cnc/maps/gdi06/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: gdi06.lua + Scripts: campaign-global.lua, gdi06.lua MusicPlaylist: BackgroundMusic: rain-ambient StartingMusic: rain @@ -40,6 +40,7 @@ World: normal: Normal hard: Hard Default: easy + Locked: false Player: PlayerResources: diff --git a/mods/cnc/maps/gdi07/gdi07.lua b/mods/cnc/maps/gdi07/gdi07.lua index 9eece62a78..877f73fccc 100644 --- a/mods/cnc/maps/gdi07/gdi07.lua +++ b/mods/cnc/maps/gdi07/gdi07.lua @@ -6,6 +6,7 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + InfantryReinforcements = { "e1", "e1", "e2" } JeepReinforcements = { "jeep" } TankReinforcements = { "mtnk" } @@ -16,68 +17,25 @@ SamSites = { sam1, sam2, sam3, sam4 } NodBase = { handofnod, nodpower1, nodpower2, nodpower3, nodairfield, nodrefinery, nodconyard } HiddenNodUnits = { sleeper1, sleeper2, sleeper3, sleeper4 } -ReinforceWithLandingCraft = function(units, transportStart, transportUnload, rallypoint) - local transport = Actor.Create("oldlst", true, { Owner = GDI, Facing = 0, Location = transportStart }) - local subcell = 0 - Utils.Do(units, function(a) - transport.LoadPassenger(Actor.Create(a, false, { Owner = transport.Owner, Facing = transport.Facing, Location = transportUnload, SubCell = subcell })) - subcell = subcell + 1 - end) - - transport.ScriptedMove(transportUnload) - Media.PlaySpeechNotification(player, "Reinforce") - - transport.CallFunc(function() - Utils.Do(units, function() - local a = transport.UnloadPassenger() - a.IsInWorld = true - a.MoveIntoWorld(transport.Location - CVec.New(0, 1)) - - if rallypoint ~= nil then - a.Move(rallypoint) - end - end) - end) - - transport.Wait(5) - transport.ScriptedMove(transportStart) - transport.Destroy() -end - -CheckForBase = function(player) - local buildings = 0 - - Utils.Do(GDIBaseBuildings, function(name) - if #GDI.GetActorsByType(name) > 0 then - buildings = buildings + 1 - end - end) - - return buildings == #GDIBaseBuildings -end - SendReinforcements = function() Trigger.AfterDelay(DateTime.Seconds(20), function() - ReinforceWithLandingCraft(BaseReinforcements, spawnpoint3.Location - CVec.New(0, -4), spawnpoint3.Location - CVec.New(0, -1), waypoint26.Location) + ReinforceWithLandingCraft(GDI, BaseReinforcements, spawnpoint3.Location - CVec.New(0, -4), spawnpoint3.Location - CVec.New(0, -1), waypoint26.Location) end) Trigger.AfterDelay(DateTime.Seconds(10), function() - ReinforceWithLandingCraft(TankReinforcements, spawnpoint2.Location - CVec.New(0, -4), spawnpoint2.Location - CVec.New(0, -1), waypoint10.Location) - - ReinforceWithLandingCraft(TankReinforcements, spawnpoint3.Location - CVec.New(0, -4), spawnpoint3.Location - CVec.New(0, -1), waypoint10.Location) + ReinforceWithLandingCraft(GDI, TankReinforcements, spawnpoint2.Location - CVec.New(0, -4), spawnpoint2.Location - CVec.New(0, -1), waypoint10.Location) + ReinforceWithLandingCraft(GDI, TankReinforcements, spawnpoint3.Location - CVec.New(0, -4), spawnpoint3.Location - CVec.New(0, -1), waypoint10.Location) end) Trigger.AfterDelay(DateTime.Seconds(5), function() - ReinforceWithLandingCraft(JeepReinforcements, spawnpoint1.Location - CVec.New(0, -4), spawnpoint1.Location - CVec.New(0, -1), waypoint10.Location) + ReinforceWithLandingCraft(GDI, JeepReinforcements, spawnpoint1.Location - CVec.New(0, -4), spawnpoint1.Location - CVec.New(0, -1), waypoint10.Location) end) - ReinforceWithLandingCraft(InfantryReinforcements, spawnpoint2.Location - CVec.New(0, -4), spawnpoint2.Location - CVec.New(0, -1), waypoint10.Location) - - ReinforceWithLandingCraft(InfantryReinforcements, spawnpoint3.Location - CVec.New(0, -4), spawnpoint3.Location - CVec.New(0, -1), waypoint10.Location) + ReinforceWithLandingCraft(GDI, InfantryReinforcements, spawnpoint2.Location - CVec.New(0, -4), spawnpoint2.Location - CVec.New(0, -1), waypoint10.Location) + ReinforceWithLandingCraft(GDI, InfantryReinforcements, spawnpoint3.Location - CVec.New(0, -4), spawnpoint3.Location - CVec.New(0, -1), waypoint10.Location) end AttackPlayer = function() - Trigger.AfterDelay(DateTime.Seconds(40), function() for type, count in pairs({ ['e3'] = 3, ['e4'] = 2 }) do atk1Actors = Utils.Take(count, Nod.GetActorsByType(type)) @@ -145,16 +103,11 @@ AttackPlayer = function() Utils.Do(NodBase, function(actor) Trigger.OnRemovedFromWorld(actor, function() - Utils.Do(Nod.GetGroundAttackers(Nod), function(unit) - unit.Hunt() - end) + Utils.Do(Nod.GetGroundAttackers(Nod), IdleHunt) end) end) - Utils.Do(HiddenNodUnits, function(actor) - actor.Hunt() - end) - + Utils.Do(HiddenNodUnits, IdleHunt) end WorldLoaded = function() @@ -163,35 +116,16 @@ WorldLoaded = function() Camera.Position = spawnpoint2.CenterPosition - Trigger.OnObjectiveAdded(GDI, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) + InitObjectives(GDI) - Trigger.OnObjectiveCompleted(GDI, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - - Trigger.OnObjectiveFailed(GDI, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) - - Trigger.OnPlayerWon(GDI, function() - Media.PlaySpeechNotification(Nod, "Win") - end) - - Trigger.OnPlayerLost(GDI, function() - Media.PlaySpeechNotification(Nod, "Lose") - end) - - gdiMainObjective = GDI.AddPrimaryObjective("Destroy remaining Nod structures and units.") - gdiBaseObjective = GDI.AddSecondaryObjective("Construct all available buildings.") - nodObjective = Nod.AddPrimaryObjective("Kill all enemies!") + DestroyNod = GDI.AddObjective("Destroy remaining Nod structures and units.") + ConstructBase = GDI.AddObjective("Construct all available buildings.", "Secondary", false) SendReinforcements() - gdiAirSupportObjective = GDI.AddSecondaryObjective("Destroy the SAM sites to receive air support.") + local destroySAMs = GDI.AddSecondaryObjective("Destroy the SAM sites to receive air support.") Trigger.OnAllKilled(SamSites, function() - GDI.MarkCompletedObjective(gdiAirSupportObjective) + GDI.MarkCompletedObjective(destroySAMs) Actor.Create("airstrike.proxy", true, { Owner = GDI }) end) @@ -201,13 +135,15 @@ end Tick = function() if DateTime.GameTime > DateTime.Seconds(5) then if GDI.HasNoRequiredUnits() then - Nod.MarkCompletedObjective(nodObjective) + GDI.MarkFailedObjective(DestroyNod) end + if Nod.HasNoRequiredUnits() then - GDI.MarkCompletedObjective(gdiMainObjective) + GDI.MarkCompletedObjective(DestroyNod) end - if not GDI.IsObjectiveCompleted(gdiBaseObjective) and DateTime.GameTime % DateTime.Seconds(1) == 0 and CheckForBase() then - GDI.MarkCompletedObjective(gdiBaseObjective) + + if not GDI.IsObjectiveCompleted(ConstructBase) and DateTime.GameTime % DateTime.Seconds(1) == 0 and CheckForBase(GDI, GDIBaseBuildings) then + GDI.MarkCompletedObjective(ConstructBase) end end end diff --git a/mods/cnc/maps/gdi07/rules.yaml b/mods/cnc/maps/gdi07/rules.yaml index 7e1d2b612a..f98d931b06 100644 --- a/mods/cnc/maps/gdi07/rules.yaml +++ b/mods/cnc/maps/gdi07/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: gdi07.lua + Scripts: campaign-global.lua, gdi07.lua MissionData: Briefing: Previous mission objective not complete.\nAirfield was to be targeted. \n\nNew objective: Build up a base and Destroy remaining Nod structures and units.\n\nReinforcements will be provided. BriefingVideo: gdi7.vqa diff --git a/mods/cnc/maps/nod01/nod01.lua b/mods/cnc/maps/nod01/nod01.lua index 4a34dd5ba6..50b921ead8 100644 --- a/mods/cnc/maps/nod01/nod01.lua +++ b/mods/cnc/maps/nod01/nod01.lua @@ -6,6 +6,7 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + InitialForcesA = { "bggy", "e1", "e1", "e1", "e1" } InitialForcesB = { "e1", "e1", "bggy", "e1", "e1" } @@ -13,62 +14,40 @@ RifleInfantryReinforcements = { "e1", "e1" } RocketInfantryReinforcements = { "e3", "e3", "e3", "e3", "e3" } SendInitialForces = function() - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.Reinforce(player, InitialForcesA, { StartSpawnPointLeft.Location, StartRallyPoint.Location }, 5) - Reinforcements.Reinforce(player, InitialForcesB, { StartSpawnPointRight.Location, StartRallyPoint.Location }, 10) + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.Reinforce(Nod, InitialForcesA, { StartSpawnPointLeft.Location, StartRallyPoint.Location }, 5) + Reinforcements.Reinforce(Nod, InitialForcesB, { StartSpawnPointRight.Location, StartRallyPoint.Location }, 10) end SendFirstInfantryReinforcements = function() - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.Reinforce(player, RifleInfantryReinforcements, { StartSpawnPointRight.Location, StartRallyPoint.Location }, 15) + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.Reinforce(Nod, RifleInfantryReinforcements, { StartSpawnPointRight.Location, StartRallyPoint.Location }, 15) end SendSecondInfantryReinforcements = function() - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.Reinforce(player, RifleInfantryReinforcements, { StartSpawnPointLeft.Location, StartRallyPoint.Location }, 15) + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.Reinforce(Nod, RifleInfantryReinforcements, { StartSpawnPointLeft.Location, StartRallyPoint.Location }, 15) end SendLastInfantryReinforcements = function() - Media.PlaySpeechNotification(player, "Reinforce") - - -- Move the units properly into the map before they start attacking - local forces = Reinforcements.Reinforce(player, RocketInfantryReinforcements, { VillageSpawnPoint.Location, VillageRallyPoint.Location }, 8) - Utils.Do(forces, function(a) - a.Stance = "Defend" - a.CallFunc(function() a.Stance = "AttackAnything" end) - end) + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.Reinforce(Nod, RocketInfantryReinforcements, { VillageSpawnPoint.Location, VillageRallyPoint.Location }, 8) end WorldLoaded = function() - player = Player.GetPlayer("Nod") - enemy = Player.GetPlayer("GDI") - villagers = Player.GetPlayer("Villagers") + Nod = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") + Villagers = Player.GetPlayer("Villagers") - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) + InitObjectives(Nod) - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) - - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - NodObjective1 = player.AddPrimaryObjective("Kill Nikoomba.") - NodObjective2 = player.AddPrimaryObjective("Destroy the village.") - NodObjective3 = player.AddSecondaryObjective("Destroy all GDI troops in the area.") - GDIObjective1 = enemy.AddPrimaryObjective("Eliminate all Nod forces.") + KillNikoomba = Nod.AddObjective("Kill Nikoomba.") + DestroyVillage = Nod.AddObjective("Destroy the village.") + DestroyGDI = Nod.AddObjective("Destroy all GDI troops in the area.", "Secondary", false) + GDIObjective = GDI.AddObjective("Eliminate all Nod forces.") Trigger.OnKilled(Nikoomba, function() - player.MarkCompletedObjective(NodObjective1) + Nod.MarkCompletedObjective(KillNikoomba) Trigger.AfterDelay(DateTime.Seconds(1), function() SendLastInfantryReinforcements() end) @@ -83,14 +62,16 @@ end Tick = function() if DateTime.GameTime > 2 then - if player.HasNoRequiredUnits() then - enemy.MarkCompletedObjective(GDIObjective1) + if Nod.HasNoRequiredUnits() then + GDI.MarkCompletedObjective(GDIObjective) end - if villagers.HasNoRequiredUnits() then - player.MarkCompletedObjective(NodObjective2) + + if Villagers.HasNoRequiredUnits() then + Nod.MarkCompletedObjective(DestroyVillage) end - if enemy.HasNoRequiredUnits() then - player.MarkCompletedObjective(NodObjective3) + + if GDI.HasNoRequiredUnits() then + Nod.MarkCompletedObjective(DestroyGDI) end end end diff --git a/mods/cnc/maps/nod01/rules.yaml b/mods/cnc/maps/nod01/rules.yaml index 30229c1e69..fb0e2252df 100644 --- a/mods/cnc/maps/nod01/rules.yaml +++ b/mods/cnc/maps/nod01/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: nod01.lua + Scripts: campaign-global.lua, nod01.lua MusicPlaylist: StartingMusic: nomercy VictoryMusic: nod_win1 diff --git a/mods/cnc/maps/nod02a/nod02a.lua b/mods/cnc/maps/nod02a/nod02a.lua index f4f4c01961..8246a98b08 100644 --- a/mods/cnc/maps/nod02a/nod02a.lua +++ b/mods/cnc/maps/nod02a/nod02a.lua @@ -6,271 +6,112 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + NodUnits = { "bggy", "e1", "e1", "e1", "e1", "e1", "bggy", "e1", "e1", "e1", "bggy" } NodBaseBuildings = { "hand", "fact", "nuke" } -DfndActorTriggerActivator = { Refinery, Barracks, Powerplant, Yard } -Atk3ActorTriggerActivator = { Guard1, Guard2, Guard3, Guard4, Guard5, Guard6, Guard7 } +GDIBase = { Refinery, Barracks, Powerplant, Yard } +Guards = { Guard1, Guard2, Guard3, Guard4, Guard5, Guard6, Guard7 } Atk1CellTriggerActivator = { CPos.New(45,37), CPos.New(44,37), CPos.New(45,36), CPos.New(44,36), CPos.New(45,35), CPos.New(44,35), CPos.New(45,34), CPos.New(44,34) } Atk4CellTriggerActivator = { CPos.New(50,47), CPos.New(49,47), CPos.New(48,47), CPos.New(47,47), CPos.New(46,47), CPos.New(45,47), CPos.New(44,47), CPos.New(43,47), CPos.New(42,47), CPos.New(41,47), CPos.New(40,47), CPos.New(39,47), CPos.New(38,47), CPos.New(37,47), CPos.New(50,46), CPos.New(49,46), CPos.New(48,46), CPos.New(47,46), CPos.New(46,46), CPos.New(45,46), CPos.New(44,46), CPos.New(43,46), CPos.New(42,46), CPos.New(41,46), CPos.New(40,46), CPos.New(39,46), CPos.New(38,46) } -Atk2TriggerFunctionTime = DateTime.Seconds(40) -Atk5TriggerFunctionTime = DateTime.Minutes(1) + DateTime.Seconds(15) -Atk6TriggerFunctionTime = DateTime.Minutes(1) + DateTime.Seconds(20) -Atk7TriggerFunctionTime = DateTime.Seconds(50) -Pat1TriggerFunctionTime = DateTime.Seconds(30) - Atk1Waypoints = { waypoint2, waypoint4, waypoint5, waypoint6 } Atk2Waypoints = { waypoint2, waypoint5, waypoint7, waypoint6 } Atk3Waypoints = { waypoint2, waypoint4, waypoint5, waypoint9 } Atk4Waypoints = { waypoint0, waypoint8, waypoint9 } Pat1Waypoints = { waypoint0, waypoint1, waypoint2, waypoint3 } -UnitToRebuild = 'e1' -GDIStartUnits = 0 +GetAttackers = function(amount) + local units = GDI.GetActorsByType("e1") -getActors = function(owner, units) - local maxUnits = 0 - local actors = { } - for type, count in pairs(units) do - local globalActors = Utils.Where(Map.ActorsInWorld, function(actor) - return actor.Owner == owner and actor.Type == type and not actor.IsDead - end) - if #globalActors < count then - maxUnits = #globalActors - else - maxUnits = count - end - for i = 1, maxUnits, 1 do - actors[#actors + 1] = globalActors[i] - end + if amount > #units then + return units end - return actors -end -InsertNodUnits = function() - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.Reinforce(player, NodUnits, { UnitsEntry.Location, UnitsRally.Location }, 15) - Reinforcements.Reinforce(player, { "mcv" }, { McvEntry.Location, McvRally.Location }) -end - -OnAnyDamaged = function(actors, func) - Utils.Do(actors, function(actor) - Trigger.OnDamaged(actor, func) - end) -end - -CheckForBase = function(player) - local buildings = 0 - - Utils.Do(NodBaseBuildings, function(name) - if #player.GetActorsByType(name) > 0 then - buildings = buildings + 1 - end - end) - - return buildings == #NodBaseBuildings -end - -DfndTriggerFunction = function() - local list = enemy.GetGroundAttackers() - Utils.Do(list, function(unit) - IdleHunt(unit) - end) -end - -Atk2TriggerFunction = function() - local MyActors = getActors(enemy, { ['e1'] = 3 }) - Utils.Do(MyActors, function(actor) - Atk2Movement(actor) - end) -end - -Atk3TriggerFunction = function() - if not Atk3TriggerSwitch then - Atk3TriggerSwitch = true - MyActors = getActors(enemy, { ['e1'] = 4 }) - Utils.Do(MyActors, function(actor) - Atk3Movement(actor) - end) - end -end - -Atk5TriggerFunction = function() - local MyActors = getActors(enemy, { ['e1'] = 3 }) - Utils.Do(MyActors, function(actor) - Atk2Movement(actor) - end) -end - -Atk6TriggerFunction = function() - local MyActors = getActors(enemy, { ['e1'] = 4 }) - Utils.Do(MyActors, function(actor) - Atk3Movement(actor) - end) -end - -Atk7TriggerFunction = function() - local MyActors = getActors(enemy, { ['e1'] = 3 }) - Utils.Do(MyActors, function(actor) - Atk4Movement(actor) - end) -end - -Pat1TriggerFunction = function() - local MyActors = getActors(enemy, { ['e1'] = 3 }) - Utils.Do(MyActors, function(actor) - Pat1Movement(actor) - end) -end - -Atk1Movement = function(unit) - Utils.Do(Atk1Waypoints, function(waypoint) - unit.AttackMove(waypoint.Location) - end) - IdleHunt(unit) -end - -Atk2Movement = function(unit) - Utils.Do(Atk2Waypoints, function(waypoint) - unit.AttackMove(waypoint.Location) - end) - IdleHunt(unit) -end - -Atk3Movement = function(unit) - Utils.Do(Atk3Waypoints, function(waypoint) - unit.AttackMove(waypoint.Location) - end) - IdleHunt(unit) -end - -Atk4Movement = function(unit) - Utils.Do(Atk4Waypoints, function(waypoint) - unit.AttackMove(waypoint.Location) - end) - IdleHunt(unit) -end - -Pat1Movement = function(unit) - Utils.Do(Pat1Waypoints, function(waypoint) - unit.Move(waypoint.Location) - end) - IdleHunt(unit) + return Utils.Take(amount, units) end WorldLoaded = function() - player = Player.GetPlayer("Nod") - enemy = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") + InitObjectives(Nod) + + BuildBase = Nod.AddObjective("Build a base.") + DestroyGDI = Nod.AddObjective("Destroy the GDI base.") + GDIObjective = GDI.AddObjective("Kill all enemies.") + + Utils.Do(Guards, function(actor) + Trigger.OnDamaged(actor, function() + if Atk3TriggerSwitch then + return + end + + Atk3TriggerSwitch = true + MoveAndHunt(GetAttackers(4), Atk3Waypoints) + end) end) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") + Trigger.OnAllRemovedFromWorld(GDIBase, function() + Utils.Do(GDI.GetGroundAttackers(), IdleHunt) end) - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") + Trigger.AfterDelay(DateTime.Seconds(40), function() + MoveAndHunt(GetAttackers(3), Atk2Waypoints) end) - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") + Trigger.AfterDelay(DateTime.Minutes(1) + DateTime.Seconds(15), function() + MoveAndHunt(GetAttackers(3), Atk2Waypoints) end) - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") + Trigger.AfterDelay(DateTime.Minutes(1) + DateTime.Seconds(20), function() + MoveAndHunt(GetAttackers(3), Atk3Waypoints) end) - NodObjective1 = player.AddPrimaryObjective("Build a base.") - NodObjective2 = player.AddPrimaryObjective("Destroy the GDI base.") - GDIObjective = enemy.AddPrimaryObjective("Kill all enemies.") + Trigger.AfterDelay(DateTime.Seconds(50), function() + MoveAndHunt(GetAttackers(3), Atk4Waypoints) + end) - OnAnyDamaged(Atk3ActorTriggerActivator, Atk3TriggerFunction) - Trigger.OnAllRemovedFromWorld(DfndActorTriggerActivator, DfndTriggerFunction) - - Trigger.AfterDelay(Atk2TriggerFunctionTime, Atk2TriggerFunction) - Trigger.AfterDelay(Atk5TriggerFunctionTime, Atk5TriggerFunction) - Trigger.AfterDelay(Atk6TriggerFunctionTime, Atk6TriggerFunction) - Trigger.AfterDelay(Atk7TriggerFunctionTime, Atk7TriggerFunction) - Trigger.AfterDelay(Pat1TriggerFunctionTime, Pat1TriggerFunction) + Trigger.AfterDelay(DateTime.Seconds(30), function() + MoveAndHunt(GetAttackers(3), Pat1Waypoints) + end) Trigger.OnEnteredFootprint(Atk1CellTriggerActivator, function(a, id) - if a.Owner == player then - MyActors = getActors(enemy, { ['e1'] = 5 }) - Utils.Do(MyActors, function(actor) - Atk1Movement(actor) - end) + if a.Owner == Nod then + MoveAndHunt(GetAttackers(5), Atk1Waypoints) Trigger.RemoveFootprintTrigger(id) end end) Trigger.OnEnteredFootprint(Atk4CellTriggerActivator, function(a, id) - if a.Owner == player then - MyActors = getActors(enemy, { ['e1'] = 3 } ) - Utils.Do(MyActors, function(actor) - Atk2Movement(actor) - end) + if a.Owner == Nod then + MoveAndHunt(GetAttackers(3), Atk2Waypoints) Trigger.RemoveFootprintTrigger(id) end end) - Trigger.AfterDelay(0, getStartUnits) - InsertNodUnits() + Trigger.AfterDelay(0, function() + Utils.Do(GDI.GetActorsByType("e1"), function(unit) + RebuildUnit({ unit }, GDI, Barracks) + end) + end) + + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.Reinforce(Nod, NodUnits, { UnitsEntry.Location, UnitsRally.Location }, 15) + Reinforcements.Reinforce(Nod, { "mcv" }, { McvEntry.Location, McvRally.Location }) end Tick = function() - if enemy.HasNoRequiredUnits() then - player.MarkCompletedObjective(NodObjective2) + if GDI.HasNoRequiredUnits() then + Nod.MarkCompletedObjective(DestroyGDI) end - if player.HasNoRequiredUnits() then - if DateTime.GameTime > 2 then - enemy.MarkCompletedObjective(GDIObjective) - end + if DateTime.GameTime > 2 and Nod.HasNoRequiredUnits() then + GDI.MarkCompletedObjective(GDIObjective) end - if DateTime.GameTime % DateTime.Seconds(1) == 0 and not player.IsObjectiveCompleted(NodObjective1) and CheckForBase(player) then - player.MarkCompletedObjective(NodObjective1) - end - - if DateTime.GameTime % DateTime.Seconds(3) == 0 and Barracks.IsInWorld and Barracks.Owner == enemy then - checkProduction(enemy) - end -end - -checkProduction = function(player) - local Units = Utils.Where(Map.ActorsInWorld, function(actor) - return actor.Owner == player and actor.Type == UnitToRebuild - end) - - if #Units < GDIStartUnits then - local unitsToProduce = GDIStartUnits - #Units - if Barracks.IsInWorld and unitsToProduce > 0 then - local UnitsType = { } - for i = 1, unitsToProduce, 1 do - UnitsType[i] = UnitToRebuild - end - Barracks.Build(UnitsType) - end - end -end - -getStartUnits = function() - local Units = Utils.Where(Map.ActorsInWorld, function(actor) - return actor.Owner == enemy - end) - Utils.Do(Units, function(unit) - if unit.Type == UnitToRebuild then - GDIStartUnits = GDIStartUnits + 1 - end - end) -end - -IdleHunt = function(unit) - if not unit.IsDead then - Trigger.OnIdle(unit, unit.Hunt) + if DateTime.GameTime % DateTime.Seconds(1) == 0 and not Nod.IsObjectiveCompleted(BuildBase) and CheckForBase(Nod, NodBaseBuildings) then + Nod.MarkCompletedObjective(BuildBase) end end diff --git a/mods/cnc/maps/nod02a/rules.yaml b/mods/cnc/maps/nod02a/rules.yaml index d7bdefa741..53b7bec1f0 100644 --- a/mods/cnc/maps/nod02a/rules.yaml +++ b/mods/cnc/maps/nod02a/rules.yaml @@ -4,7 +4,7 @@ Player: World: LuaScript: - Scripts: nod02a.lua + Scripts: campaign-global.lua, nod02a.lua MusicPlaylist: StartingMusic: ind2 VictoryMusic: nod_win1 diff --git a/mods/cnc/maps/nod02b/nod02b.lua b/mods/cnc/maps/nod02b/nod02b.lua index 28877ab680..615a7acda7 100644 --- a/mods/cnc/maps/nod02b/nod02b.lua +++ b/mods/cnc/maps/nod02b/nod02b.lua @@ -6,239 +6,98 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + NodUnits = { "bggy", "e1", "e1", "e1", "e1", "e1", "bggy", "e1", "e1", "e1", "bggy" } NodBaseBuildings = { "hand", "fact", "nuke" } -Grd2ActorTriggerActivator = { Refinery, Yard } -Atk4ActorTriggerActivator = { Guard1 } -Atk3ActorTriggerActivator = { Guard4 } -Atk6ActorTriggerActivator = { Guard2, Guard3 } -HuntActorTriggerActivator = { Refinery, Yard, Barracks, Plant, Silo1, Silo2 } +GDIBase = { Refinery, Yard, Barracks, Plant, Silo1, Silo2 } -Atk8TriggerFunctionTime = DateTime.Minutes(1) + DateTime.Seconds(25) -Atk7TriggerFunctionTime = DateTime.Minutes(1) + DateTime.Seconds(20) +GDIWaypoints1 = { waypoint0, waypoint1, waypoint2, waypoint3 } +GDIWaypoints2 = { waypoint0, waypoint1, waypoint4, waypoint5, waypoint6, waypoint7, waypoint9 } -Gdi1Waypoints = { waypoint0, waypoint1, waypoint2, waypoint3 } -Gdi3Waypoints = { waypoint0, waypoint1, waypoint4, waypoint5, waypoint6, waypoint7, waypoint9 } +GetAttackers = function(amount) + local units = GDI.GetActorsByType("e1") -UnitToRebuild = 'e1' -GDIStartUnits = 0 - -Grd2TriggerFunction = function() - if not Grd2TriggerSwitch then - Grd2TriggerSwitch = true - MyActors = getActors(enemy, { ['e1'] = 5 }) - Utils.Do(MyActors, function(actor) - Gdi5Movement(actor) - end) + if amount > #units then + return units end -end -Atk8TriggerFunction = function() - MyActors = getActors(enemy, { ['e1'] = 2 }) - Utils.Do(MyActors, function(actor) - Gdi1Movement(actor) - end) -end - -Atk7TriggerFunction = function() - MyActors = getActors(enemy, { ['e1'] = 3 }) - Utils.Do(MyActors, function(actor) - Gdi3Movement(actor) - end) -end - -Atk4TriggerFunction = function() - MyActors = getActors(enemy, { ['e1'] = 3 }) - Utils.Do(MyActors, function(actor) - Gdi3Movement(actor) - end) -end - -Atk3TriggerFunction = function() - MyActors = getActors(enemy, { ['e1'] = 2 }) - Utils.Do(MyActors, function(actor) - Gdi1Movement(actor) - end) -end - -Atk6TriggerFunction = function() - MyActors = getActors(enemy, { ['e1'] = 2 }) - Utils.Do(MyActors, function(actor) - Gdi1Movement(actor) - end) -end - -Atk5TriggerFunction = function() - if not Atk5TriggerSwitch then - Atk5TriggerSwitch = true - MyActors = getActors(enemy, { ['e1'] = 3 }) - Utils.Do(MyActors, function(actor) - Gdi3Movement(actor) - end) - end -end - -HuntTriggerFunction = function() - local list = enemy.GetGroundAttackers() - Utils.Do(list, function(unit) - IdleHunt(unit) - end) -end - -Gdi5Movement = function(unit) - IdleHunt(unit) -end - -Gdi1Movement = function(unit) - Utils.Do(Gdi1Waypoints, function(waypoint) - unit.AttackMove(waypoint.Location) - end) - IdleHunt(unit) -end - -Gdi3Movement = function(unit) - Utils.Do(Gdi3Waypoints, function(waypoint) - unit.AttackMove(waypoint.Location) - end) - IdleHunt(unit) + return Utils.Take(amount, units) end WorldLoaded = function() - player = Player.GetPlayer("Nod") - enemy = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") + InitObjectives(Nod) + + GDIObjective = GDI.AddObjective("Kill all enemies.") + BuildBase = Nod.AddObjective("Build a base.") + DestroyGDI = Nod.AddObjective("Destroy all GDI units.") + + Utils.Do({ Refinery, Yard }, function(actor) + Trigger.OnDamaged(actor, function() + if not Grd2TriggerSwitch then + Grd2TriggerSwitch = true + Utils.Do(GetAttackers(5), IdleHunt) + end + end) end) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") + Trigger.AfterDelay(DateTime.Minutes(1) + DateTime.Seconds(25), function() + MoveAndHunt(GetAttackers(2), GDIWaypoints1) end) - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") + Trigger.AfterDelay(DateTime.Minutes(1) + DateTime.Seconds(20), function() + MoveAndHunt(GetAttackers(3), GDIWaypoints2) end) - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") + Trigger.OnKilled(Guard1, function() + MoveAndHunt(GetAttackers(3), GDIWaypoints2) end) - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") + Trigger.OnKilled(Guard4, function() + MoveAndHunt(GetAttackers(2), GDIWaypoints1) end) - GDIObjective = enemy.AddPrimaryObjective("Kill all enemies.") - NodObjective1 = player.AddPrimaryObjective("Build a base.") - NodObjective2 = player.AddPrimaryObjective("Destroy all GDI units.") + Trigger.OnAllKilled({ Guard2, Guard3 }, function() + MoveAndHunt(GetAttackers(2), GDIWaypoints1) + end) - OnAnyDamaged(Grd2ActorTriggerActivator, Grd2TriggerFunction) - Trigger.AfterDelay(Atk8TriggerFunctionTime, Atk8TriggerFunction) - Trigger.AfterDelay(Atk7TriggerFunctionTime, Atk7TriggerFunction) - Trigger.OnAllRemovedFromWorld(Atk4ActorTriggerActivator, Atk4TriggerFunction) - Trigger.OnAllRemovedFromWorld(Atk3ActorTriggerActivator, Atk3TriggerFunction) - Trigger.OnDamaged(Harvester, Atk5TriggerFunction) - Trigger.OnAllRemovedFromWorld(HuntActorTriggerActivator, HuntTriggerFunction) + Trigger.OnDamaged(Harvester, function() + if Atk5TriggerSwitch then + return + end - Trigger.AfterDelay(0, getStartUnits) - Harvester.FindResources() + Atk5TriggerSwitch = true + MoveAndHunt(GetAttackers(3), GDIWaypoints2) + end) - InsertNodUnits() + Trigger.OnAllRemovedFromWorld(GDIBase, function() + Utils.Do(GDI.GetGroundAttackers(), IdleHunt) + end) + + Trigger.AfterDelay(0, function() + Utils.Do(GDI.GetActorsByType("e1"), function(unit) + RebuildUnit({ unit }, GDI, Barracks) + end) + end) + + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.Reinforce(Nod, NodUnits, { UnitsEntry.Location, UnitsRally.Location }, 15) + Reinforcements.Reinforce(Nod, { "mcv" }, { McvEntry.Location, McvRally.Location }) end Tick = function() - if player.HasNoRequiredUnits() then - if DateTime.GameTime > 2 then - enemy.MarkCompletedObjective(GDIObjective) - end + if DateTime.GameTime > 2 and Nod.HasNoRequiredUnits() then + GDI.MarkCompletedObjective(GDIObjective) end - if enemy.HasNoRequiredUnits() then - player.MarkCompletedObjective(NodObjective2) + if GDI.HasNoRequiredUnits() then + Nod.MarkCompletedObjective(DestroyGDI) end - if DateTime.GameTime % DateTime.Seconds(1) == 0 and not player.IsObjectiveCompleted(NodObjective1) and CheckForBase(player) then - player.MarkCompletedObjective(NodObjective1) - end - - if DateTime.GameTime % DateTime.Seconds(3) == 0 and Barracks.IsInWorld and Barracks.Owner == enemy then - checkProduction(enemy) - end -end - -CheckForBase = function(player) - local buildings = 0 - - Utils.Do(NodBaseBuildings, function(name) - if #player.GetActorsByType(name) > 0 then - buildings = buildings + 1 - end - end) - - return buildings == #NodBaseBuildings -end - -OnAnyDamaged = function(actors, func) - Utils.Do(actors, function(actor) - Trigger.OnDamaged(actor, func) - end) -end - -getActors = function(owner, units) - local maxUnits = 0 - local actors = { } - for type, count in pairs(units) do - local globalActors = Utils.Where(Map.ActorsInWorld, function(actor) - return actor.Owner == owner and actor.Type == type and not actor.IsDead - end) - if #globalActors < count then - maxUnits = #globalActors - else - maxUnits = count - end - for i = 1, maxUnits, 1 do - actors[#actors + 1] = globalActors[i] - end - end - return actors -end - -checkProduction = function(player) - local Units = Utils.Where(Map.ActorsInWorld, function(actor) - return actor.Owner == player and actor.Type == UnitToRebuild - end) - - if #Units < GDIStartUnits then - local unitsToProduce = GDIStartUnits - #Units - if Barracks.IsInWorld and unitsToProduce > 0 then - local UnitsType = { } - for i = 1, unitsToProduce, 1 do - UnitsType[i] = UnitToRebuild - end - Barracks.Build(UnitsType) - end - end -end - -getStartUnits = function() - local Units = Utils.Where(Map.ActorsInWorld, function(actor) - return actor.Owner == enemy - end) - Utils.Do(Units, function(unit) - if unit.Type == UnitToRebuild then - GDIStartUnits = GDIStartUnits + 1 - end - end) -end - -InsertNodUnits = function() - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.Reinforce(player, NodUnits, { UnitsEntry.Location, UnitsRally.Location }, 15) - Reinforcements.Reinforce(player, { "mcv" }, { McvEntry.Location, McvRally.Location }) -end - -IdleHunt = function(unit) - if not unit.IsDead then - Trigger.OnIdle(unit, unit.Hunt) + if DateTime.GameTime % DateTime.Seconds(1) == 0 and not Nod.IsObjectiveCompleted(BuildBase) and CheckForBase(Nod, NodBaseBuildings) then + Nod.MarkCompletedObjective(BuildBase) end end diff --git a/mods/cnc/maps/nod02b/rules.yaml b/mods/cnc/maps/nod02b/rules.yaml index e55a664333..9407d78484 100644 --- a/mods/cnc/maps/nod02b/rules.yaml +++ b/mods/cnc/maps/nod02b/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: nod02b.lua + Scripts: campaign-global.lua, nod02b.lua MusicPlaylist: StartingMusic: ind2 VictoryMusic: nod_win1 diff --git a/mods/cnc/maps/nod03a/nod03a.lua b/mods/cnc/maps/nod03a/nod03a.lua index 8cb9c15c5b..4f384d84ce 100644 --- a/mods/cnc/maps/nod03a/nod03a.lua +++ b/mods/cnc/maps/nod03a/nod03a.lua @@ -6,61 +6,42 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + NodUnits = { "bike", "e3", "e1", "bggy", "e1", "e3", "bike", "bggy" } FirstAttackWave = { "e1", "e1", "e1", "e2", } SecondThirdAttackWave = { "e1", "e1", "e2", } SendAttackWave = function(units, spawnPoint) - Reinforcements.Reinforce(enemy, units, { spawnPoint }, DateTime.Seconds(1), function(actor) + Reinforcements.Reinforce(GDI, units, { spawnPoint }, DateTime.Seconds(1), function(actor) actor.AttackMove(PlayerBase.Location) end) end -InsertNodUnits = function() - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.Reinforce(player, NodUnits, { NodEntry.Location, NodRallyPoint.Location }) - Trigger.AfterDelay(DateTime.Seconds(9), function() - Reinforcements.Reinforce(player, { "mcv" }, { NodEntry.Location, PlayerBase.Location }) - end) -end - WorldLoaded = function() - player = Player.GetPlayer("Nod") - enemy = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) + InitObjectives(Nod) - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) - - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - gdiObjective = enemy.AddPrimaryObjective("Eliminate all Nod forces in the area.") - nodObjective1 = player.AddPrimaryObjective("Capture the prison.") - nodObjective2 = player.AddSecondaryObjective("Destroy all GDI forces.") + CapturePrison = Nod.AddObjective("Capture the prison.") + DestroyGDI = Nod.AddObjective("Destroy all GDI forces.", "Secondary", false) Trigger.OnCapture(TechCenter, function() Trigger.AfterDelay(DateTime.Seconds(2), function() - player.MarkCompletedObjective(nodObjective1) + Nod.MarkCompletedObjective(CapturePrison) end) end) Trigger.OnKilled(TechCenter, function() - player.MarkFailedObjective(nodObjective1) + Nod.MarkFailedObjective(CapturePrison) + end) + + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.Reinforce(Nod, NodUnits, { NodEntry.Location, NodRallyPoint.Location }) + Trigger.AfterDelay(DateTime.Seconds(9), function() + Reinforcements.Reinforce(Nod, { "mcv" }, { NodEntry.Location, PlayerBase.Location }) end) - InsertNodUnits() Trigger.AfterDelay(DateTime.Seconds(20), function() SendAttackWave(FirstAttackWave, AttackWaveSpawnA.Location) end) Trigger.AfterDelay(DateTime.Seconds(50), function() SendAttackWave(SecondThirdAttackWave, AttackWaveSpawnB.Location) end) Trigger.AfterDelay(DateTime.Seconds(100), function() SendAttackWave(SecondThirdAttackWave, AttackWaveSpawnC.Location) end) @@ -68,11 +49,12 @@ end Tick = function() if DateTime.GameTime > 2 then - if player.HasNoRequiredUnits() then - enemy.MarkCompletedObjective(gdiObjective) + if Nod.HasNoRequiredUnits() then + Nod.MarkFailedObjective(CapturePrison) end - if enemy.HasNoRequiredUnits() then - player.MarkCompletedObjective(nodObjective2) + + if GDI.HasNoRequiredUnits() then + Nod.MarkCompletedObjective(DestroyGDI) end end end diff --git a/mods/cnc/maps/nod03a/rules.yaml b/mods/cnc/maps/nod03a/rules.yaml index 00df314dab..385588d32b 100644 --- a/mods/cnc/maps/nod03a/rules.yaml +++ b/mods/cnc/maps/nod03a/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: nod03a.lua + Scripts: campaign-global.lua, nod03a.lua MusicPlaylist: StartingMusic: chrg226m VictoryMusic: nod_win1 diff --git a/mods/cnc/maps/nod03b/nod03b.lua b/mods/cnc/maps/nod03b/nod03b.lua index 3e72001b62..645b0f40c1 100644 --- a/mods/cnc/maps/nod03b/nod03b.lua +++ b/mods/cnc/maps/nod03b/nod03b.lua @@ -6,6 +6,7 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + NodUnits = { "e1", "e1", "bggy", "bike", "e1", "e1", "bike", "bggy", "e1", "e1" } Engineers = { "e6", "e6", "e6" } FirstAttackWaveUnits = { "e1", "e1", "e2" } @@ -13,7 +14,7 @@ SecondAttackWaveUnits = { "e1", "e1", "e1" } ThirdAttackWaveUnits = { "e1", "e1", "e1", "e2" } SendAttackWave = function(units, action) - Reinforcements.Reinforce(enemy, units, { GDIBarracksSpawn.Location, WP0.Location, WP1.Location }, 15, action) + Reinforcements.Reinforce(GDI, units, { GDIBarracksSpawn.Location, WP0.Location, WP1.Location }, 15, action) end FirstAttackWave = function(soldier) @@ -31,50 +32,33 @@ SecondAttackWave = function(soldier) soldier.AttackMove(PlayerBase.Location) end -InsertNodUnits = function() - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.Reinforce(player, { "mcv" }, { McvEntry.Location, McvDeploy.Location }) - Reinforcements.Reinforce(player, NodUnits, { NodEntry.Location, NodRallypoint.Location }) - Trigger.AfterDelay(DateTime.Seconds(15), function() - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.Reinforce(player, Engineers, { McvEntry.Location, PlayerBase.Location }) - end) -end - WorldLoaded = function() - player = Player.GetPlayer("Nod") - enemy = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") + InitObjectives(Nod) + + CapturePrison = Nod.AddObjective("Capture the prison.") + DestroyGDI = Nod.AddObjective("Destroy all GDI forces.", "Secondary", false) + + Trigger.OnKilled(TechCenter, function() + Nod.MarkFailedObjective(CapturePrison) end) - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) - - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - gdiObjective = enemy.AddPrimaryObjective("Eliminate all Nod forces in the area.") - nodObjective1 = player.AddPrimaryObjective("Capture the prison.") - nodObjective2 = player.AddSecondaryObjective("Destroy all GDI forces.") - - Trigger.OnKilled(TechCenter, function() player.MarkFailedObjective(nodObjective1) end) Trigger.OnCapture(TechCenter, function() Trigger.AfterDelay(DateTime.Seconds(2), function() - player.MarkCompletedObjective(nodObjective1) + Nod.MarkCompletedObjective(CapturePrison) end) end) - InsertNodUnits() + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.Reinforce(Nod, { "mcv" }, { McvEntry.Location, McvDeploy.Location }) + Reinforcements.Reinforce(Nod, NodUnits, { NodEntry.Location, NodRallypoint.Location }) + Trigger.AfterDelay(DateTime.Seconds(15), function() + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.Reinforce(Nod, Engineers, { McvEntry.Location, PlayerBase.Location }) + end) + Trigger.AfterDelay(DateTime.Seconds(40), function() SendAttackWave(FirstAttackWaveUnits, FirstAttackWave) end) Trigger.AfterDelay(DateTime.Seconds(80), function() SendAttackWave(SecondAttackWaveUnits, SecondAttackWave) end) Trigger.AfterDelay(DateTime.Seconds(140), function() SendAttackWave(ThirdAttackWaveUnits, FirstAttackWave) end) @@ -82,12 +66,12 @@ end Tick = function() if DateTime.GameTime > 2 then - if player.HasNoRequiredUnits() then - enemy.MarkCompletedObjective(gdiObjective) + if Nod.HasNoRequiredUnits() then + Nod.MarkFailedObjective(CapturePrison) end - if enemy.HasNoRequiredUnits() then - player.MarkCompletedObjective(nodObjective2) + if GDI.HasNoRequiredUnits() then + Nod.MarkCompletedObjective(DestroyGDI) end end end diff --git a/mods/cnc/maps/nod03b/rules.yaml b/mods/cnc/maps/nod03b/rules.yaml index defe9c94e9..ca09228bad 100644 --- a/mods/cnc/maps/nod03b/rules.yaml +++ b/mods/cnc/maps/nod03b/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: nod03b.lua + Scripts: campaign-global.lua, nod03b.lua MusicPlaylist: StartingMusic: chrg226m VictoryMusic: nod_win1 diff --git a/mods/cnc/maps/nod04a/nod04a.lua b/mods/cnc/maps/nod04a/nod04a.lua index 6076939618..32d9fdeba1 100644 --- a/mods/cnc/maps/nod04a/nod04a.lua +++ b/mods/cnc/maps/nod04a/nod04a.lua @@ -6,17 +6,18 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] -NodUnitsBuggy = { 'bggy', 'bggy', 'bggy', 'bggy', 'bggy' } -NodUnitsBikes = { 'bike', 'bike', 'bike' } -NodUnitsGunner = { 'e1', 'e1', 'e1', 'e1', 'e1', 'e1' } -NodUnitsRocket = { 'e3', 'e3', 'e3', 'e3', 'e3', 'e3' } -Atk6Units = { 'c1', 'c2', 'c3' } -Atk5Units = { 'e1', 'e1', 'e2', 'e2' } -Atk1Units = { 'e1', 'e1' } -XxxxUnits = { 'jeep' } -YyyyUnits = { 'e1', 'e1', 'e2' } -ZzzzUnits = { 'e1', 'e1', 'e2', 'e2' } +NodUnitsBuggy = { "bggy", "bggy", "bggy", "bggy", "bggy" } +NodUnitsBikes = { "bike", "bike", "bike" } +NodUnitsGunner = { "e1", "e1", "e1", "e1", "e1", "e1" } +NodUnitsRocket = { "e3", "e3", "e3", "e3", "e3", "e3" } + +Atk6Units = { "c1", "c2", "c3" } +Atk5Units = { "e1", "e1", "e2", "e2" } +Atk1Units = { "e1", "e1" } +JeepReinforcements = { "jeep" } +GDIUnits = { "e1", "e1", "e2" } +ApcUnits = { "e1", "e1", "e2", "e2" } Spawnpoint = { waypoint0.Location } Atk6WaypointsPart1 = { waypoint1.Location, waypoint2.Location, waypoint3.Location, waypoint4.Location } @@ -41,133 +42,40 @@ DelxCellTriggerActivator = { CPos.New(42,20), CPos.New(41,20), CPos.New(40,20), DelyCellTriggerActivator = { CPos.New(31,28), CPos.New(30,28), CPos.New(31,27), CPos.New(30,27), CPos.New(31,26), CPos.New(30,26), CPos.New(31,25), CPos.New(30,25), CPos.New(31,24), CPos.New(30,24) } DelzCellTriggerActivator = { CPos.New(18,20), CPos.New(17,20), CPos.New(16,20), CPos.New(15,20), CPos.New(14,20), CPos.New(13,20), CPos.New(12,20), CPos.New(11,20), CPos.New(25,19), CPos.New(24,19), CPos.New(23,19), CPos.New(22,19), CPos.New(21,19), CPos.New(20,19), CPos.New(19,19), CPos.New(18,19), CPos.New(17,19), CPos.New(16,19), CPos.New(15,19), CPos.New(14,19), CPos.New(13,19), CPos.New(12,19), CPos.New(11,19), CPos.New(25,18), CPos.New(24,18), CPos.New(23,18), CPos.New(22,18), CPos.New(21,18), CPos.New(20,18), CPos.New(19,18) } -Atk3TriggerCounter = 2 - -Atk1TriggerFunctionTime = DateTime.Seconds(20) -XxxxTriggerFunctionTime = DateTime.Seconds(50) -YyyyTriggerFunctionTime = DateTime.Minutes(1) + DateTime.Seconds(40) -ZzzzTriggerFunctionTime = DateTime.Minutes(2) + DateTime.Seconds(30) - NodCiviliansActors = { NodCiv1, NodCiv2, NodCiv3, NodCiv4, NodCiv5, NodCiv6, NodCiv7, NodCiv8, NodCiv9 } -Atk6TriggerFunction = function() - Reinforcements.ReinforceWithTransport(enemy, 'apc', Atk6Units, Atk6WaypointsPart1, Atk6WaypointsPart2, - function(transport, cargo) - Utils.Do(cargo, function(actor) - IdleHunt(actor) - end) - end, - function(unit) - IdleHunt(unit) - end) +SendJeepReinforcements = function() + if not PreventJeepReinforcements then + local units = Reinforcements.Reinforce(GDI, JeepReinforcements, Spawnpoint, 15) + MoveAndHunt(units, Atk2Waypoints) + end end -Atk5TriggerFunction = function () - if not Atk5TriggerSwitch then - Atk5TriggerSwitch = true - Reinforcements.ReinforceWithTransport(enemy, 'apc', Atk5Units, Atk5Waypoints, nil, +SendGDIReinforcements = function() + if not PreventGDIReinforcements then + local units = Reinforcements.Reinforce(GDI, GDIUnits, Spawnpoint, 15) + MoveAndHunt(units, Atk4Waypoints) + end +end + +SendApcReinforcements = function() + if not PreventApcReinforcements then + Reinforcements.ReinforceWithTransport(GDI, "apc", ApcUnits, Atk5Waypoints, nil, function(transport, cargo) transport.UnloadPassengers() - Utils.Do(cargo, function(actor) - IdleHunt(actor) - end) - end, - function(unit) - IdleHunt(unit) - end) + Utils.Do(cargo, IdleHunt) + end, IdleHunt) end end -Atk1TriggerFunction = function() - Reinforcements.Reinforce(enemy, Atk1Units, Spawnpoint, 15, - function(actor) - Atk1Movement(actor) - end) -end - -XxxxTriggerFunction = function() - if not XxxxTriggerSwitch then - Reinforcements.Reinforce(enemy, XxxxUnits, Spawnpoint, 15, - function(actor) - Atk2Movement(actor) - end) - end -end - -YyyyTriggerFunction = function() - if not YyyyTriggerSwitch then - Reinforcements.Reinforce(enemy, YyyyUnits, Spawnpoint, 15, - function(actor) - Atk4Movement(actor) - end) - end -end - -ZzzzTriggerFunction = function() - if not ZzzzTriggerSwitch then - Reinforcements.ReinforceWithTransport(enemy, 'apc', ZzzzUnits, Atk5Waypoints, nil, - function(transport, cargo) - transport.UnloadPassengers() - Utils.Do(cargo, function(actor) - IdleHunt(actor) - end) - end, - function(unit) - IdleHunt(unit) - end) - end -end - -Atk3Movement = function(unit) - Utils.Do(Atk3Waypoints, function(waypoint) - unit.AttackMove(waypoint.Location) - end) - IdleHunt(unit) -end - -Atk2Movement = function(unit) - Utils.Do(Atk2Waypoints, function(waypoint) - unit.AttackMove(waypoint.Location) - end) - IdleHunt(unit) -end - -Atk1Movement = function(unit) - Utils.Do(Atk1Waypoints, function(waypoint) - unit.AttackMove(waypoint.Location) - end) - IdleHunt(unit) -end - -GcivMovement = function(unit) - Utils.Do(GcivWaypoints, function(waypoint) - unit.AttackMove(waypoint.Location) - end) -end - -Atk4Movement = function(unit) - Utils.Do(Atk4Waypoints, function(waypoint) - unit.AttackMove(waypoint.Location) - end) - IdleHunt(unit) -end - -InsertNodUnits = function() - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.Reinforce(player, NodUnitsBuggy, { UnitsEntryBuggy.Location, UnitsRallyBuggy.Location }, 11) - Reinforcements.Reinforce(player, NodUnitsBikes, { UnitsEntryBikes.Location, UnitsRallyBikes.Location }, 15) - Reinforcements.Reinforce(player, NodUnitsGunner, { UnitsEntryGunner.Location, UnitsRallyGunner.Location }, 15) - Reinforcements.Reinforce(player, NodUnitsRocket, { UnitsEntryRocket.Location, UnitsRallyRocket.Location }, 15) -end - CreateCivilians = function(actor, discoverer) Utils.Do(NodCiviliansActors, function(actor) - actor.Owner = player + actor.Owner = Nod end) - NodObjective2 = player.AddPrimaryObjective("Protect the civilians that support Nod.") + ProtectCivilians = Nod.AddPrimaryObjective("Protect the civilians that support Nod.") Trigger.OnAllKilled(NodCiviliansActors, function() - player.MarkFailedObjective(NodObjective2) + Nod.MarkFailedObjective(ProtectCivilians) end) Utils.Do(GcivActors, function(actor) @@ -180,102 +88,93 @@ CreateCivilians = function(actor, discoverer) end WorldLoaded = function() - player = Player.GetPlayer("Nod") + Nod = Player.GetPlayer("Nod") NodSupporter = Player.GetPlayer("NodSupporter") - enemy = Player.GetPlayer("GDI") + GDI = Player.GetPlayer("GDI") - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") + InitObjectives(Nod) + + Trigger.OnAnyKilled(Atk6ActorTriggerActivator, function() + Reinforcements.ReinforceWithTransport(GDI, "apc", Atk6Units, Atk6WaypointsPart1, Atk6WaypointsPart2, + function(transport, cargo) + Utils.Do(cargo, IdleHunt) + end, IdleHunt) end) - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) - - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - Trigger.OnAnyKilled(Atk6ActorTriggerActivator, Atk6TriggerFunction) - - OnAnyDamaged(Atk5ActorTriggerActivator, Atk5TriggerFunction) - - Trigger.OnEnteredFootprint(Atk3CellTriggerActivator, function(a, id) - if a.Owner == player then - for type, count in pairs({ ['e1'] = 3, ['e2'] = 2, ['mtnk'] = 1 }) do - local myActors = Utils.Take(count, enemy.GetActorsByType(type)) - Utils.Do(myActors, function(actor) - Atk3Movement(actor) - end) + Utils.Do(Atk5ActorTriggerActivator, function(actor) + Trigger.OnDamaged(actor, function() + if Atk5TriggerSwitch then + return end - Atk3TriggerCounter = Atk3TriggerCounter - 1 - if Atk3TriggerCounter < 0 then - Trigger.RemoveFootprintTrigger(id) + Atk5TriggerSwitch = true + Reinforcements.ReinforceWithTransport(GDI, "apc", Atk5Units, Atk5Waypoints, nil, + function(transport, cargo) + transport.UnloadPassengers() + Utils.Do(cargo, IdleHunt) + end, IdleHunt) + end) + end) + + Trigger.OnEnteredFootprint(Atk3CellTriggerActivator, function(a, id) + if a.Owner == Nod then + Trigger.RemoveFootprintTrigger(id) + + for type, count in pairs({ ["e1"] = 3, ["e2"] = 2, ["mtnk"] = 1 }) do + MoveAndHunt(Utils.Take(count, GDI.GetActorsByType(type)), Atk3Waypoints) end end end) Trigger.OnEnteredFootprint(Atk2CellTriggerActivator, function(a, id) - if a.Owner == player then - MyActors = Utils.Take(1, enemy.GetActorsByType('jeep')) - Utils.Do(MyActors, function(actor) - Atk2Movement(actor) - end) + if a.Owner == Nod then + MoveAndHunt(Utils.Take(1, GDI.GetActorsByType("jeep")), Atk2Waypoints) Trigger.RemoveFootprintTrigger(id) end end) Trigger.OnEnteredFootprint(GcivCellTriggerActivator, function(a, id) - if a.Owner == player then - Utils.Do(GcivActors, function(actor) - GcivMovement(actor) - end) + if a.Owner == Nod then + MoveAndHunt(GcivActors, GcivWaypoints) Trigger.RemoveFootprintTrigger(id) end end) - Trigger.AfterDelay(Atk1TriggerFunctionTime, Atk1TriggerFunction) - Trigger.OnEnteredFootprint(Atk4CellTriggerActivator, function(a, id) - if a.Owner == player then - for type, count in pairs({ ['e1'] = 2,['e2'] = 1 }) do - local myActors = Utils.Take(count, enemy.GetActorsByType(type)) - Utils.Do(myActors, function(actor) - Atk4Movement(actor) - end) + if a.Owner == Nod then + for type, count in pairs({ ["e1"] = 2,["e2"] = 1 }) do + MoveAndHunt(Utils.Take(count, GDI.GetActorsByType(type)), Atk4Waypoints) end Trigger.RemoveFootprintTrigger(id) end end) - Trigger.AfterDelay(XxxxTriggerFunctionTime, XxxxTriggerFunction) - Trigger.AfterDelay(YyyyTriggerFunctionTime, YyyyTriggerFunction) - Trigger.AfterDelay(ZzzzTriggerFunctionTime, ZzzzTriggerFunction) + Trigger.AfterDelay(DateTime.Seconds(20), function() + local units = Reinforcements.Reinforce(GDI, Atk1Units, Spawnpoint, 15) + MoveAndHunt(units, Atk1Waypoints) + end) + + Trigger.AfterDelay(DateTime.Seconds(50), SendJeepReinforcements) + Trigger.AfterDelay(DateTime.Minutes(1) + DateTime.Seconds(40), SendGDIReinforcements) + Trigger.AfterDelay(DateTime.Minutes(2) + DateTime.Seconds(30), SendApcReinforcements) Trigger.OnEnteredFootprint(DelxCellTriggerActivator, function(a, id) - if a.Owner == player then - XxxxTriggerSwitch = true + if a.Owner == Nod then + PreventJeepReinforcements = true Trigger.RemoveFootprintTrigger(id) end end) Trigger.OnEnteredFootprint(DelyCellTriggerActivator, function(a, id) - if a.Owner == player then - YyyyTriggerSwitch = true + if a.Owner == Nod then + PreventGDIReinforcements = true Trigger.RemoveFootprintTrigger(id) end end) Trigger.OnEnteredFootprint(DelzCellTriggerActivator, function(a, id) - if a.Owner == player then - ZzzzTriggerSwitch = true + if a.Owner == Nod then + PreventApcReinforcements = true Trigger.RemoveFootprintTrigger(id) end end) @@ -283,35 +182,26 @@ WorldLoaded = function() Trigger.OnPlayerDiscovered(NodSupporter, CreateCivilians) Trigger.OnAllKilled(WinActorTriggerActivator, function() - player.MarkCompletedObjective(NodObjective1) - if NodObjective2 then - player.MarkCompletedObjective(NodObjective2) + Nod.MarkCompletedObjective(KillGDI) + + if ProtectCivilians then + Nod.MarkCompletedObjective(ProtectCivilians) end end) - GDIObjective = enemy.AddPrimaryObjective("Eliminate all Nod forces in the area.") - NodObjective1 = player.AddPrimaryObjective("Kill all civilian GDI supporters.") + KillGDI = Nod.AddObjective("Kill all civilian GDI supporters.") + + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.Reinforce(Nod, NodUnitsBuggy, { UnitsEntryBuggy.Location, UnitsRallyBuggy.Location }, 11) + Reinforcements.Reinforce(Nod, NodUnitsBikes, { UnitsEntryBikes.Location, UnitsRallyBikes.Location }, 15) + Reinforcements.Reinforce(Nod, NodUnitsGunner, { UnitsEntryGunner.Location, UnitsRallyGunner.Location }, 15) + Reinforcements.Reinforce(Nod, NodUnitsRocket, { UnitsEntryRocket.Location, UnitsRallyRocket.Location }, 15) - InsertNodUnits() Camera.Position = waypoint6.CenterPosition end Tick = function() - if player.HasNoRequiredUnits() then - if DateTime.GameTime > 2 then - enemy.MarkCompletedObjective(GDIObjective) - end - end -end - -OnAnyDamaged = function(actors, func) - Utils.Do(actors, function(actor) - Trigger.OnDamaged(actor, func) - end) -end - -IdleHunt = function(unit) - if not unit.IsDead then - Trigger.OnIdle(unit, unit.Hunt) + if DateTime.GameTime > 2 and Nod.HasNoRequiredUnits() then + Nod.MarkFailedObjective(KillGDI) end end diff --git a/mods/cnc/maps/nod04a/rules.yaml b/mods/cnc/maps/nod04a/rules.yaml index 33250ad116..adf261c681 100644 --- a/mods/cnc/maps/nod04a/rules.yaml +++ b/mods/cnc/maps/nod04a/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: nod04a.lua + Scripts: campaign-global.lua, nod04a.lua MusicPlaylist: StartingMusic: valkyrie VictoryMusic: nod_win1 diff --git a/mods/cnc/maps/nod04b/nod04b.lua b/mods/cnc/maps/nod04b/nod04b.lua index 0e63bafac8..fa74b0fb6d 100644 --- a/mods/cnc/maps/nod04b/nod04b.lua +++ b/mods/cnc/maps/nod04b/nod04b.lua @@ -6,18 +6,19 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] -NodUnitsBuggy = { 'bggy', 'bggy', 'bike', 'bike' } -NodUnitsRocket = { 'e3', 'e3', 'e3', 'e3', 'e3', 'e3' } -NodUnitsGunner = { 'e1', 'e1', 'e1', 'e1', 'e1', 'e1' } -Apc3CellTriggerActivator = { CPos.New(28,58), CPos.New(27,58), CPos.New(28,57), CPos.New(27,57), CPos.New(28,56), CPos.New(27,56), CPos.New(28,55), CPos.New(27,55), CPos.New(28,54), CPos.New(27,54), CPos.New(28,53), CPos.New(27,53) } +NodUnitsBuggy = { "bggy", "bggy", "bike", "bike" } +NodUnitsRocket = { "e3", "e3", "e3", "e3", "e3", "e3" } +NodUnitsGunner = { "e1", "e1", "e1", "e1", "e1", "e1" } + +Apc3Trigger = { CPos.New(28,58), CPos.New(27,58), CPos.New(28,57), CPos.New(27,57), CPos.New(28,56), CPos.New(27,56), CPos.New(28,55), CPos.New(27,55), CPos.New(28,54), CPos.New(27,54), CPos.New(28,53), CPos.New(27,53) } Civ1CellTriggerActivator = { CPos.New(24,52), CPos.New(23,52), CPos.New(22,52), CPos.New(23,51), CPos.New(22,51), CPos.New(21,51) } Civ2CellTriggerActivator = { CPos.New(26,54), CPos.New(25,54), CPos.New(24,54), CPos.New(25,53), CPos.New(24,53), CPos.New(23,53) } -Apc1Units = { 'c2', 'c3', 'c4', 'c5' } +Apc1Units = { "c2", "c3", "c4", "c5" } -WinActorTriggerActivator = { Civilian1, Civilian2, Civilian3, Civilian4, Civilian5, Civilian6, Civilian7, Civilian8, CivBuilding1, CivBuilding2, CivBuilding3, CivBuilding4, CivBuilding5, CivBuilding6, CivBuilding7, CivBuilding8, CivBuilding9, CivBuilding10, CivBuilding11, CivBuilding12, CivBuilding13, CivBuilding14 } -Apc2ActorTriggerActivator = { NodGunner1, NodGunner2, NodGunner3 } +TargetActors = { Civilian1, Civilian2, Civilian3, Civilian4, Civilian5, Civilian6, Civilian7, Civilian8, CivBuilding1, CivBuilding2, CivBuilding3, CivBuilding4, CivBuilding5, CivBuilding6, CivBuilding7, CivBuilding8, CivBuilding9, CivBuilding10, CivBuilding11, CivBuilding12, CivBuilding13, CivBuilding14 } +Apc2Trigger = { NodGunner1, NodGunner2, NodGunner3 } Apc1Waypoints = { waypoint0.Location, waypoint11.Location, waypoint10.Location, waypoint8.Location, waypoint9.Location } Apc2Waypoints = { waypoint8, waypoint7, waypoint6, waypoint5, waypoint4 } @@ -26,148 +27,75 @@ Civ1Waypoints = { waypoint3, waypoint2, waypoint3, waypoint1, waypoint2, waypoin Civ2Waypoints = { waypoint3, waypoint2, waypoint1, waypoint11, waypoint10, waypoint8, waypoint9 } Hummer1Waypoints = { waypoint8, waypoint7, waypoint6, waypoint5, waypoint4, waypoint3, waypoint2, waypoint1, waypoint0, waypoint11, waypoint10, waypoint8 } -Apc1TriggerFunctionTime = DateTime.Seconds(3) - -Apc1TriggerFunction = function() - Reinforcements.ReinforceWithTransport(enemy, 'apc', Apc1Units, Apc1Waypoints, nil, - function(transport, cargo) - Utils.Do(cargo, function(actor) - IdleHunt(actor) - end) - end, - nil) -end - -Hum1TriggerFunction = function(actor, discoverer) - MyActors = Utils.Take(2, enemy.GetActorsByType('jeep')) - Utils.Do(MyActors, function(actor) - MoveAndHunt(actor, Hummer1Waypoints) - end) -end - -Movement = function(unit) - if unit ~= nil then - Utils.Do(Civ1Waypoints, function(waypoint) - unit.AttackMove(waypoint.Location) - end) - end -end - -MoveAndHunt = function(unit) - if unit ~= nil then - Utils.Do(Apc2Waypoints, function(waypoint) - unit.AttackMove(waypoint.Location) - end) - IdleHunt(unit) - end -end - -Apc2TriggerFunction = function() - MyActors = Utils.Take(1, enemy.GetActorsByType('apc')) - Utils.Do(MyActors, function(actor) - MoveAndHunt(actor, Apc2Waypoints) - end) -end - -WinTriggerFunction = function() - player.MarkCompletedObjective(NodObjective1) -end - -InsertNodUnits = function() - Camera.Position = CameraPoint.CenterPosition - - Media.PlaySpeechNotification(player, "Reinforce") - Trigger.AfterDelay(DateTime.Seconds(1), function() - Reinforcements.ReinforceWithTransport(player, 'tran', NodUnitsBuggy, { EntryPointVehicle.Location, RallyPointVehicle.Location }, { EntryPointVehicle.Location }, nil, nil) - end) - Reinforcements.ReinforceWithTransport(player, 'tran', NodUnitsRocket, { EntryPointRocket.Location, RallyPointRocket.Location }, { EntryPointRocket.Location }, nil, nil) - Reinforcements.ReinforceWithTransport(player, 'tran', NodUnitsGunner, { EntryPointGunner.Location, RallyPointGunner.Location }, { EntryPointGunner.Location }, nil, nil) -end - WorldLoaded = function() - player = Player.GetPlayer("Nod") - enemy = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") - Trigger.AfterDelay(Apc1TriggerFunctionTime, Apc1TriggerFunction) + Trigger.AfterDelay(DateTime.Seconds(3), function() + Reinforcements.ReinforceWithTransport(GDI, "apc", Apc1Units, Apc1Waypoints, nil, + function(transport, cargo) + Utils.Do(cargo, IdleHunt) + end) + end) Trigger.OnEnteredFootprint(Civ2CellTriggerActivator, function(a, id) - if a.Owner == player then - for type, count in pairs({ ['c6'] = 1, ['c7'] = 1, ['c8'] = 1, ['c9'] = 1 }) do - MyActors = Utils.Take(count, enemy.GetActorsByType(type)) - Utils.Do(MyActors, function(actor) - Movement(actor, Civ2Waypoints) - end) + if a.Owner == Nod then + for type, count in pairs({ ["c6"] = 1, ["c7"] = 1, ["c8"] = 1, ["c9"] = 1 }) do + MoveAndHunt(Utils.Take(count, GDI.GetActorsByType(type)), Civ2Waypoints) end Trigger.RemoveFootprintTrigger(id) end end) Trigger.OnEnteredFootprint(Civ1CellTriggerActivator, function(a, id) - if a.Owner == player then - for type, count in pairs({ ['c2'] = 1, ['c3'] = 1, ['c4'] = 1, ['c5'] = 1 }) do - MyActors = Utils.Take(count, enemy.GetActorsByType(type)) - Utils.Do(MyActors, function(actor) - Movement(actor, Civ1Waypoints) - end) + if a.Owner == Nod then + for type, count in pairs({ ["c2"] = 1, ["c3"] = 1, ["c4"] = 1, ["c5"] = 1 }) do + MoveAndHunt(Utils.Take(count, GDI.GetActorsByType(type)), Civ1Waypoints) end Trigger.RemoveFootprintTrigger(id) end end) - Trigger.OnDiscovered(Convoi, Hum1TriggerFunction) + Trigger.OnDiscovered(Convoi, function() + MoveAndHunt(Utils.Take(2, GDI.GetActorsByType("jeep")), Hummer1Waypoints) + end) - Trigger.OnAllRemovedFromWorld(Apc2ActorTriggerActivator, Apc2TriggerFunction) + Trigger.OnAllRemovedFromWorld(Apc2Trigger, function() + MoveAndHunt(Utils.Take(1, GDI.GetActorsByType("apc")), Apc2Waypoints) + end) - Trigger.OnEnteredFootprint(Apc3CellTriggerActivator, function(a, id) - if a.Owner == player then - MoveAndHunt(enemy.GetActorsByType('apc')[1], Apc3Waypoints) + Trigger.OnEnteredFootprint(Apc3Trigger, function(a, id) + if a.Owner == Nod then + MoveAndHunt(Utils.Take(1, GDI.GetActorsByType("apc"), Apc3Waypoints)) Trigger.RemoveFootprintTrigger(id) end end) - Trigger.OnAllRemovedFromWorld(WinActorTriggerActivator, WinTriggerFunction) - - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") + Trigger.OnAllRemovedFromWorld(TargetActors, function() + Nod.MarkCompletedObjective(KillCivilians) end) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") + InitObjectives(Nod) + + KillCivilians = Nod.AddObjective("Destroy the village and kill all civilians.") + KillGDI = Nod.AddObjective("Kill all GDI units in the area.", "Secondary", false) + + Camera.Position = CameraPoint.CenterPosition + + Media.PlaySpeechNotification(Nod, "Reinforce") + Trigger.AfterDelay(DateTime.Seconds(1), function() + Reinforcements.ReinforceWithTransport(Nod, "tran", NodUnitsBuggy, { EntryPointVehicle.Location, RallyPointVehicle.Location }, { EntryPointVehicle.Location }, nil, nil) end) - - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) - - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) - - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - GDIObjective = enemy.AddPrimaryObjective("Kill all enemies.") - NodObjective1 = player.AddPrimaryObjective("Destroy the village and kill all civilians.") - NodObjective2 = player.AddSecondaryObjective("Kill all GDI units in the area.") - - InsertNodUnits() + Reinforcements.ReinforceWithTransport(Nod, "tran", NodUnitsRocket, { EntryPointRocket.Location, RallyPointRocket.Location }, { EntryPointRocket.Location }, nil, nil) + Reinforcements.ReinforceWithTransport(Nod, "tran", NodUnitsGunner, { EntryPointGunner.Location, RallyPointGunner.Location }, { EntryPointGunner.Location }, nil, nil) end Tick = function() - if player.HasNoRequiredUnits() then - if DateTime.GameTime > 2 then - enemy.MarkCompletedObjective(GDIObjective) - end + if DateTime.GameTime > 2 and Nod.HasNoRequiredUnits() then + Nod.MarkFailedObjective(KillCivilians) end - if enemy.HasNoRequiredUnits() then - player.MarkCompletedObjective(NodObjective2) - end -end - -IdleHunt = function(unit) - if not unit.IsDead then - Trigger.OnIdle(unit, unit.Hunt) + if GDI.HasNoRequiredUnits() then + Nod.MarkCompletedObjective(KillGDI) end end diff --git a/mods/cnc/maps/nod04b/rules.yaml b/mods/cnc/maps/nod04b/rules.yaml index bdd9511763..acc2a7343d 100644 --- a/mods/cnc/maps/nod04b/rules.yaml +++ b/mods/cnc/maps/nod04b/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: nod04b.lua + Scripts: campaign-global.lua, nod04b.lua MusicPlaylist: StartingMusic: warfare VictoryMusic: nod_win1 diff --git a/mods/cnc/maps/nod05/nod05.lua b/mods/cnc/maps/nod05/nod05.lua index d18d6295fb..e50dc7698c 100644 --- a/mods/cnc/maps/nod05/nod05.lua +++ b/mods/cnc/maps/nod05/nod05.lua @@ -6,52 +6,44 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + 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 } +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 } +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 } +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 } +AllWaypoints = { GDI1Waypoints, GDI2Waypoints, GDI3Waypoints, GDI5Waypoints, GDI11Waypoints, GDI12Waypoints } PrimaryTargets = { Tower1, Tower2, CommCenter, Silo1, Silo2, Silo3, Refinery, Barracks, Plant1, Plant2, Yard, Factory } -GDIStartUnits = { } - SendGDIAirstrike = function() - if not CommCenter.IsDead and CommCenter.Owner == enemy then - local target = getAirstrikeTarget() + if not CommCenter.IsDead and CommCenter.Owner == GDI then + local target = GetAirstrikeTarget(Nod) if target then CommCenter.SendAirstrike(target, false, Facing.NorthEast + 4) @@ -62,284 +54,146 @@ SendGDIAirstrike = function() end end -YyyyTriggerFunction = function() - if not YyyyTriggerSwitch then - for type, count in pairs(Gdi2Units) do - MyActors = Utils.Take(count, enemy.GetActorsByType(type)) - Utils.Do(MyActors, function(actor) - WaypointMovementAndHunt(actor, Gdi2Waypoints) - end) - end +SendGDI2Units = function() + if DontSendGDI2 then + return + end + + for type, count in pairs(GDI2Units) do + MoveAndHunt(Utils.Take(count, GDI.GetActorsByType(type)), GDI2Waypoints) end end -ZzzzTriggerFunction = function() - if not ZzzzTriggerSwitch then - for type, count in pairs(Gdi1Units) do - MyActors = Utils.Take(count, enemy.GetActorsByType(type)) - Utils.Do(MyActors, function(actor) - WaypointMovementAndHunt(actor, Gdi1Waypoints) - end) - end +SendGDI1Units = function() + if DontSendGDI1 then + return + end + + for type, count in pairs(GDI1Units) do + MoveAndHunt(Utils.Take(count, GDI.GetActorsByType(type)), GDI1Waypoints) end end -Grd1TriggerFunction = function() - MyActors = Utils.Take(2, enemy.GetActorsByType('jeep')) - Utils.Do(MyActors, function(actor) - WaypointMovementAndHunt(actor, Gdi5Waypoints) - end) -end - -Atk5TriggerFunction = function() - WaypointMovementAndHunt(enemy.GetActorsByType('mtnk')[1], Gdi12Waypoints) -end - -Atk2TriggerFunction = function() - for type, count in pairs(Gdi1Units) do - MyActors = Utils.Take(count, enemy.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, enemy.GetActorsByType(type)) - Utils.Do(MyActors, function(actor) - WaypointMovementAndHunt(actor, Gdi2Waypoints) - end) - end -end - -Atk4TriggerFunction = function() - WaypointMovementAndHunt(enemy.GetActorsByType('jeep')[1], Gdi3Waypoints) -end - -Atk6TriggerFunction = function() - WaypointMovementAndHunt(enemy.GetActorsByType('mtnk')[1], Gdi2Waypoints) -end - -Atk1TriggerFunction = function() - local cargo = Reinforcements.ReinforceWithTransport(enemy, 'tran', GDIReinforceUnits, { waypoint9.Location, waypoint26.Location }, { waypoint9.Location })[2] - Utils.Do(cargo, IdleHunt) -end - -AutoTriggerFunction = function() +AutoPatrol = 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, enemy.GetActorsByType(type)) - Utils.Do(MyActors, function(actor) - WaypointMovementAndHunt(actor, waypoints) + MoveAndHunt(Utils.Take(count, GDI.GetActorsByType(type)), waypoints) + end + + Trigger.AfterDelay(DateTime.Seconds(45), AutoPatrol) +end + +RebuildStartUnits = function() + local types = { "e1", "e2", "jeep", "mtnk" } + local factories = { Barracks, Barracks, Factory, Factory } + + for i = 1, 4 do + Utils.Do(GDI.GetActorsByType(types[i]), function(actor) + RebuildUnit({ actor }, GDI, factories[i]) end) end end -HuntTriggerFunction = function() - local list = enemy.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 - - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.Reinforce(player, NodUnitsVehicle, { UnitsEntry.Location, UnitsRallyVehicle.Location }, 1) - Reinforcements.Reinforce(player, NodUnitsRocket, { UnitsEntry.Location, UnitsRallyRocket.Location }, 50) - Reinforcements.Reinforce(player, NodUnitsGunner, { UnitsEntry.Location, UnitsRallyGunner.Location }, 50) - Trigger.AfterDelay(DateTime.Seconds(6), function() - Reinforcements.Reinforce(player, { 'mcv' }, { UnitsEntry.Location, UnitsRallyMCV.Location }) - end) -end - WorldLoaded = function() - player = Player.GetPlayer("Nod") - enemy = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") - InsertNodUnits() + Camera.Position = UnitsEntry.CenterPosition - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") + Media.PlaySpeechNotification(Nod, "Reinforce") + 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) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) + InitObjectives(Nod) - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) - - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) - - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - NodObjective1 = player.AddPrimaryObjective("Build 3 SAMs.") - NodObjective2 = player.AddPrimaryObjective("Destroy the GDI base.") - GDIObjective = enemy.AddPrimaryObjective("Kill all enemies.") + BuildSAMObjective = Nod.AddObjective("Build 3 SAMs.") + DestroyGDI = Nod.AddObjective("Destroy the GDI base.") + GDIObjective = GDI.AddObjective("Kill all enemies.") Trigger.AfterDelay(AirstrikeDelay, SendGDIAirstrike) - Trigger.AfterDelay(YyyyTriggerFunctionTime, YyyyTriggerFunction) - Trigger.AfterDelay(ZzzzTriggerFunctionTime, ZzzzTriggerFunction) + Trigger.AfterDelay(DateTime.Minutes(1) + DateTime.Seconds(30), SendGDI2Units) + Trigger.AfterDelay(DateTime.Minutes(2) + DateTime.Seconds(30), SendGDI1Units) Trigger.OnEnteredFootprint(DelyCellTriggerActivator, function(a, id) - if a.Owner == player then - YyyyTriggerSwitch = true + if a.Owner == Nod then + DontSendGDI2 = true Trigger.RemoveFootprintTrigger(id) end end) Trigger.OnEnteredFootprint(DelzCellTriggerActivator, function(a, id) - if a.Owner == player then - ZzzzTriggerSwitch = true + if a.Owner == Nod then + DontSendGDI1 = true Trigger.RemoveFootprintTrigger(id) end end) - Trigger.AfterDelay(Grd1TriggerFunctionTime, Grd1TriggerFunction) - Trigger.OnEnteredFootprint(Atk5CellTriggerActivator, function(a, id) - if a.Owner == player then - Atk5TriggerFunction() + if a.Owner == Nod then + MoveAndHunt(Utils.Take(1, GDI.GetActorsByType("mtnk")), GDI12Waypoints) Trigger.RemoveFootprintTrigger(id) end end) - Trigger.AfterDelay(Atk2TriggerFunctionTime, Atk2TriggerFunction) - Trigger.AfterDelay(Atk3TriggerFunctionTime, Atk3TriggerFunction) - Trigger.AfterDelay(Atk4TriggerFunctionTime, Atk4TriggerFunction) - Trigger.AfterDelay(Atk6TriggerFunctionTime, Atk6TriggerFunction) + Trigger.AfterDelay(DateTime.Seconds(3), function() + MoveAndHunt(Utils.Take(2, GDI.GetActorsByType("jeep")), GDI5Waypoints) + end) + + Trigger.AfterDelay(DateTime.Minutes(1) + DateTime.Seconds(10), function() + for type, count in pairs(GDI1Units) do + MoveAndHunt(Utils.Take(count, GDI.GetActorsByType(type)), GDI1Waypoints) + end + end) + + Trigger.AfterDelay(DateTime.Minutes(3) + DateTime.Seconds(10), function() + for type, count in pairs(GDI2Units) do + MoveAndHunt(Utils.Take(count, GDI.GetActorsByType(type)), GDI2Waypoints) + end + end) + + Trigger.AfterDelay(DateTime.Minutes(4) + DateTime.Seconds(40), function() + MoveAndHunt(Utils.Take(1, GDI.GetActorsByType("jeep")), GDI3Waypoints) + end) + + Trigger.AfterDelay(DateTime.Minutes(2) + DateTime.Seconds(30), function() + MoveAndHunt(Utils.Take(1, GDI.GetActorsByType("mtnk")), GDI1Waypoints) + end) Trigger.OnEnteredFootprint(Atk1CellTriggerActivator, function(a, id) - if a.Owner == player then - Atk1TriggerFunction() + if a.Owner == Nod then + local cargo = Reinforcements.ReinforceWithTransport(GDI, "tran", GDIReinforceUnits, { waypoint9.Location, waypoint26.Location }, { waypoint9.Location })[2] + Utils.Do(cargo, IdleHunt) Trigger.RemoveFootprintTrigger(id) end end) - Trigger.OnDiscovered(Tower1, AutoTriggerFunction) - Trigger.OnDiscovered(Tower2, AutoTriggerFunction) - Trigger.OnAllKilledOrCaptured(PrimaryTargets, function() - player.MarkCompletedObjective(NodObjective2) - HuntTriggerFunction() + Nod.MarkCompletedObjective(DestroyGDI) + Utils.Do(GDI.GetGroundAttackers(), IdleHunt) end) - Trigger.AfterDelay(0, getStartUnits) + Trigger.AfterDelay(0, RebuildStartUnits) + + AutoPatrol() end Tick = function() - if player.HasNoRequiredUnits() then - if DateTime.GameTime > 2 then - enemy.MarkCompletedObjective(GDIObjective) - end + if DateTime.GameTime > 2 and Nod.HasNoRequiredUnits() then + GDI.MarkCompletedObjective(GDIObjective) end - if not player.IsObjectiveCompleted(NodObjective1) and CheckForSams(player) then - player.MarkCompletedObjective(NodObjective1) - end - - if DateTime.GameTime % DateTime.Seconds(3) == 0 then - checkProduction(enemy) - end - - if DateTime.GameTime % DateTime.Seconds(45) == 0 then - AutoTriggerFunction() + if not Nod.IsObjectiveCompleted(BuildSAMObjective) and CheckForSams(Nod) then + Nod.MarkCompletedObjective(BuildSAMObjective) end end -IdleHunt = function(unit) - if not unit.IsDead then - Trigger.OnIdle(unit, unit.Hunt) - end -end - -CheckForSams = function(player) - local sams = player.GetActorsByType("sam") +CheckForSams = function(Nod) + local sams = Nod.GetActorsByType("sam") return #sams >= 3 end - -checkProduction = function(player) - local Units = Utils.Where(Map.ActorsInWorld, function(actor) - return actor.Owner == enemy - 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 and Factory.Owner == enemy then - Factory.Build(UnitsType) - elseif (type == 'e1' or type == 'e2') and not Barracks.IsDead and Barracks.Owner == enemy then - Barracks.Build(UnitsType) - end - end - UnitsType = { } - end -end - -getStartUnits = function() - local Units = Utils.Where(Map.ActorsInWorld, function(actor) - return actor.Owner == enemy 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 = player.GetGroundAttackers() - - if #list == 0 then - return - end - - local target = list[DateTime.GameTime % #list + 1].CenterPosition - - local sams = Map.ActorsInCircle(target, WDist.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/maps/nod05/rules.yaml b/mods/cnc/maps/nod05/rules.yaml index 5a4d7fc84e..91fc04a820 100644 --- a/mods/cnc/maps/nod05/rules.yaml +++ b/mods/cnc/maps/nod05/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: nod05.lua + Scripts: campaign-global.lua, nod05.lua MusicPlaylist: StartingMusic: airstrik VictoryMusic: nod_win1 diff --git a/mods/cnc/maps/nod06a/nod06a.lua b/mods/cnc/maps/nod06a/nod06a.lua index e965ebce19..d8f8c13763 100644 --- a/mods/cnc/maps/nod06a/nod06a.lua +++ b/mods/cnc/maps/nod06a/nod06a.lua @@ -6,6 +6,7 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + NodStartUnitsRight = { tough = { 'ltnk', 'bike', 'e1', 'e1', 'e3', 'e3' }, @@ -13,6 +14,7 @@ NodStartUnitsRight = normal = { 'ltnk', 'bike', 'bike', 'e1', 'e1', 'e1', 'e3', 'e3', 'e3', 'e3' }, easy = { 'ltnk', 'ltnk', 'bike', 'bike', 'e1', 'e1', 'e1', 'e1', 'e3', 'e3', 'e3', 'e3' } } + NodStartUnitsLeft = { tough = { 'ltnk', 'ltnk', 'bggy', 'e1', 'e1', 'e1', 'e3', 'e3', 'e3' }, @@ -20,21 +22,22 @@ NodStartUnitsLeft = normal = { 'ltnk', 'ltnk', 'bggy', 'bggy', 'e1', 'e1', 'e1', 'e1', 'e3', 'e3', 'e3', 'e3', 'e3' }, easy = { 'ltnk', 'ltnk', 'ltnk', 'bggy', 'e1', 'e1', 'e1', 'e1', 'e1', 'e1', 'e3', 'e3', 'e3', 'e3', 'e3' } } + Chn1Units = { 'e1', 'e1', 'e1', 'e1', 'e1' } Chn2Units = { 'e2', 'e2', 'e2', 'e2', 'e2' } Obj2Units = { 'ltnk', 'bike', 'e1', 'e1', 'e1' } Chn3CellTriggerActivator = { CPos.New(49,58), CPos.New(48,58), CPos.New(49,57), CPos.New(48,57), CPos.New(49,56), CPos.New(48,56), CPos.New(49,55), CPos.New(48,55) } DzneCellTriggerActivator = { CPos.New(61,45), CPos.New(60,45), CPos.New(59,45), CPos.New(58,45), CPos.New(57,45), CPos.New(61,44), CPos.New(60,44), CPos.New(59,44), CPos.New(58,44), CPos.New(57,44), CPos.New(61,43), CPos.New(60,43), CPos.New(58,43), CPos.New(57,43), CPos.New(61,42), CPos.New(60,42), CPos.New(59,42), CPos.New(58,42), CPos.New(57,42), CPos.New(61,41), CPos.New(60,41), CPos.New(59,41), CPos.New(58,41), CPos.New(57,41) } -Win1CellTriggerActivator = { CPos.New(59,43) } -Win2CellTriggerActivator = { CPos.New(54,58), CPos.New(53,58), CPos.New(52,58), CPos.New(54,57), CPos.New(53,57), CPos.New(52,57), CPos.New(54,56), CPos.New(53,56), CPos.New(52,56), CPos.New(54,55), CPos.New(53,55), CPos.New(52,55) } +DetonatorArea = { CPos.New(59,43) } +EvacuationArea = { CPos.New(54,58), CPos.New(53,58), CPos.New(52,58), CPos.New(54,57), CPos.New(53,57), CPos.New(52,57), CPos.New(54,56), CPos.New(53,56), CPos.New(52,56), CPos.New(54,55), CPos.New(53,55), CPos.New(52,55) } Grd2ActorTriggerActivator = { Guard1, Guard2, Guard3 } Atk1ActorTriggerActivator = { Atk1Activator1, Atk1Activator2 } Atk2ActorTriggerActivator = { Atk2Activator1, Atk2Activator2 } Chn1ActorTriggerActivator = { Chn1Activator1, Chn1Activator2, Chn1Activator3, Chn1Activator4, Chn1Activator5 } Chn2ActorTriggerActivator = { Chn2Activator1, Chn2Activator2, Chn2Activator3 } -Obj2ActorTriggerActivator = { Chn1Activator1, Chn1Activator2, Chn1Activator3, Chn1Activator4, Chn1Activator5, Chn2Activator1, Chn2Activator2, Chn2Activator3, Atk3Activator } +GDIVillage = { Chn1Activator1, Chn1Activator2, Chn1Activator3, Chn1Activator4, Chn1Activator5, Chn2Activator1, Chn2Activator2, Chn2Activator3, Atk3Activator } Chn1Waypoints = { ChnEntry.Location, waypoint5.Location } Chn2Waypoints = { ChnEntry.Location, waypoint6.Location } @@ -43,22 +46,10 @@ Gdi4Waypoints = { waypoint4, waypoint10, waypoint9, waypoint11, waypoint9, waypo Gdi5Waypoints = { waypoint1, waypoint4 } Gdi6Waypoints = { waypoint2, waypoints3 } -Grd1TriggerFunctionTime = DateTime.Seconds(3) - -Grd1TriggerFunction = function() - MyActors = Utils.Take(2, enemy.GetActorsByType('mtnk')) - Utils.Do(MyActors, function(actor) - MovementAndHunt(actor, Gdi3Waypoints) - end) -end - Grd2TriggerFunction = function() if not Grd2Switch then for type, count in pairs({ ['e1'] = 2, ['e2'] = 1, ['jeep'] = 1 }) do - MyActors = Utils.Take(count, enemy.GetActorsByType(type)) - Utils.Do(MyActors, function(actor) - MovementAndHunt(actor, Gdi4Waypoints) - end) + MoveAndHunt(Utils.Take(count, GDI.GetActorsByType(type)), Gdi4Waypoints) end Grd2Swicth = true end @@ -67,10 +58,7 @@ end Atk1TriggerFunction = function() if not Atk1Switch then for type, count in pairs({ ['e1'] = 3, ['e2'] = 3, ['jeep'] = 1 }) do - MyActors = Utils.Take(count, enemy.GetActorsByType(type)) - Utils.Do(MyActors, function(actor) - MovementAndHunt(actor, Gdi5Waypoints) - end) + MoveAndHunt(Utils.Take(count, GDI.GetActorsByType(type)), Gdi5Waypoints) end Atk1Switch = true end @@ -79,10 +67,7 @@ end Atk2TriggerFunction = function() if not Atk2Switch then for type, count in pairs({ ['mtnk'] = 1, ['jeep'] = 1 }) do - MyActors = Utils.Take(count, enemy.GetActorsByType(type)) - Utils.Do(MyActors, function(actor) - MovementAndHunt(actor, Gdi6Waypoints) - end) + MoveAndHunt(Utils.Take(count, GDI.GetActorsByType(type)), Gdi6Waypoints) end Atk2Switch = true end @@ -92,7 +77,7 @@ Atk3TriggerFunction = function() if not Atk3Switch then Atk3Switch = true if not CommCenter.IsDead then - local targets = player.GetGroundAttackers() + local targets = Nod.GetGroundAttackers() local target = targets[DateTime.GameTime % #targets + 1].CenterPosition if target then @@ -102,143 +87,101 @@ Atk3TriggerFunction = function() end end -Chn1TriggerFunction = function() - local cargo = Reinforcements.ReinforceWithTransport(enemy, 'tran', Chn1Units, Chn1Waypoints, { waypoint14.Location })[2] - Utils.Do(cargo, function(actor) - IdleHunt(actor) - end) -end - -Chn2TriggerFunction = function() - local cargo = Reinforcements.ReinforceWithTransport(enemy, 'tran', Chn2Units, Chn2Waypoints, { waypoint14.Location })[2] - Utils.Do(cargo, function(actor) - IdleHunt(actor) - end) -end - -Obj2TriggerFunction = function() - player.MarkCompletedObjective(NodObjective2) - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.Reinforce(player, Obj2Units, { Obj2UnitsEntry.Location, waypoint13.Location }, 15) -end - -MovementAndHunt = function(unit, waypoints) - if unit ~= nil then - Utils.Do(waypoints, function(waypoint) - unit.AttackMove(waypoint.Location) - end) - IdleHunt(unit) - end -end - InsertNodUnits = function() - local difficulty = Map.LobbyOption("difficulty") - NodStartUnitsRight = NodStartUnitsRight[difficulty] - NodStartUnitsLeft = NodStartUnitsLeft[difficulty] + NodStartUnitsRight = NodStartUnitsRight[Difficulty] + NodStartUnitsLeft = NodStartUnitsLeft[Difficulty] Camera.Position = UnitsRallyRight.CenterPosition - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.Reinforce(player, NodStartUnitsLeft, { UnitsEntryLeft.Location, UnitsRallyLeft.Location }, 15) - Reinforcements.Reinforce(player, NodStartUnitsRight, { UnitsEntryRight.Location, UnitsRallyRight.Location }, 15) + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.Reinforce(Nod, NodStartUnitsLeft, { UnitsEntryLeft.Location, UnitsRallyLeft.Location }, 15) + Reinforcements.Reinforce(Nod, NodStartUnitsRight, { UnitsEntryRight.Location, UnitsRallyRight.Location }, 15) end WorldLoaded = function() - player = Player.GetPlayer("Nod") - enemy = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) + InitObjectives(Nod) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) - - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) - - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - NodObjective1 = player.AddPrimaryObjective("Steal the GDI nuclear detonator.") - NodObjective2 = player.AddSecondaryObjective("Destroy the houses of the GDI supporters\nin the village.") - - GDIObjective = enemy.AddPrimaryObjective("Stop the Nod taskforce from escaping with the detonator.") + StealDetonator = Nod.AddObjective("Steal the GDI nuclear detonator.") + DestroyVillage = Nod.AddObjective("Destroy the houses of the GDI supporters\nin the village.", "Secondary", false) InsertNodUnits() - Trigger.AfterDelay(Grd1TriggerFunctionTime, Grd1TriggerFunction) + Trigger.AfterDelay(DateTime.Seconds(3), function() + MoveAndHunt(Utils.Take(2, GDI.GetActorsByType("mtnk")), Gdi3Waypoints) + end) Utils.Do(Grd2ActorTriggerActivator, function(actor) Trigger.OnDiscovered(actor, Grd2TriggerFunction) end) - OnAnyDamaged(Atk1ActorTriggerActivator, Atk1TriggerFunction) + Utils.Do(Atk1ActorTriggerActivator, function(actor) + Trigger.OnDamaged(actor, Atk1TriggerFunction) + end) - OnAnyDamaged(Atk2ActorTriggerActivator, Atk2TriggerFunction) + Utils.Do(Atk2ActorTriggerActivator, function(actor) + Trigger.OnDamaged(actor, Atk2TriggerFunction) + end) - if Map.LobbyOption("difficulty") == "tough" then + if Difficulty == "tough" then Trigger.OnDamaged(Atk3Activator, Atk3TriggerFunction) end - Trigger.OnAllKilled(Chn1ActorTriggerActivator, Chn1TriggerFunction) + Trigger.OnAllKilled(Chn1ActorTriggerActivator, function() + local cargo = Reinforcements.ReinforceWithTransport(GDI, 'tran', Chn1Units, Chn1Waypoints, { waypoint14.Location })[2] + Utils.Do(cargo, IdleHunt) + end) - Trigger.OnAllKilled(Chn2ActorTriggerActivator, Chn2TriggerFunction) + Trigger.OnAllKilled(Chn2ActorTriggerActivator, function() + local cargo = Reinforcements.ReinforceWithTransport(GDI, 'tran', Chn2Units, Chn2Waypoints, { waypoint14.Location })[2] + Utils.Do(cargo, IdleHunt) + end) Trigger.OnEnteredFootprint(Chn3CellTriggerActivator, function(a, id) - if a.Owner == player then - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.ReinforceWithTransport(player, 'tran', nil, { ChnEntry.Location, waypoint17.Location }, nil, nil, nil) + if a.Owner == Nod then + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.ReinforceWithTransport(Nod, 'tran', nil, { ChnEntry.Location, waypoint17.Location }) Trigger.RemoveFootprintTrigger(id) end end) Trigger.OnEnteredFootprint(DzneCellTriggerActivator, function(a, id) - if a.Owner == player then - Actor.Create('flare', true, { Owner = player, Location = waypoint17.Location }) + if a.Owner == Nod then + Actor.Create('flare', true, { Owner = Nod, Location = waypoint17.Location }) Trigger.RemoveFootprintTrigger(id) end end) - Trigger.OnAllRemovedFromWorld(Obj2ActorTriggerActivator, Obj2TriggerFunction) + Trigger.OnAllRemovedFromWorld(GDIVillage, function() + Nod.MarkCompletedObjective(DestroyVillage) + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.Reinforce(Nod, Obj2Units, { Obj2UnitsEntry.Location, waypoint13.Location }, 15) + end) - Trigger.OnEnteredFootprint(Win1CellTriggerActivator, function(a, id) - if a.Owner == player then - NodObjective3 = player.AddPrimaryObjective("Move to the evacuation point.") - player.MarkCompletedObjective(NodObjective1) + Trigger.OnEnteredFootprint(DetonatorArea, function(a, id) + if a.Owner == Nod then + EvacuateObjective = Nod.AddObjective("Move to the evacuation point.") + Nod.MarkCompletedObjective(StealDetonator) Trigger.RemoveFootprintTrigger(id) end end) - Trigger.OnEnteredFootprint(Win2CellTriggerActivator, function(a, id) - if a.Owner == player and NodObjective3 then - player.MarkCompletedObjective(NodObjective3) + Trigger.OnEnteredFootprint(EvacuationArea, function(a, id) + if a.Owner == Nod and EvacuateObjective then + Nod.MarkCompletedObjective(EvacuateObjective) Trigger.RemoveFootprintTrigger(id) end end) end Tick = function() - if DateTime.GameTime > 2 and player.HasNoRequiredUnits() then - enemy.MarkCompletedObjective(GDIObjective) + if DateTime.GameTime > 2 and Nod.HasNoRequiredUnits() then + Nod.MarkFailedObjective(StealDetonator) + + if EvacuateObjective then + Nod.MarkFailedObjective(EvacuateObjective) + end end end - -IdleHunt = function(unit) - if not unit.IsDead then - Trigger.OnIdle(unit, unit.Hunt) - end -end - -OnAnyDamaged = function(actors, func) - Utils.Do(actors, function(actor) - Trigger.OnDamaged(actor, func) - end) -end diff --git a/mods/cnc/maps/nod06a/rules.yaml b/mods/cnc/maps/nod06a/rules.yaml index 06a2b1a3c5..ed47381bcd 100644 --- a/mods/cnc/maps/nod06a/rules.yaml +++ b/mods/cnc/maps/nod06a/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: nod06a.lua + Scripts: campaign-global.lua, nod06a.lua MusicPlaylist: StartingMusic: rout VictoryMusic: nod_win1 @@ -18,6 +18,7 @@ World: hard: Hard tough: Real tough guy Default: normal + Locked: false Player: EnemyWatcher: diff --git a/mods/cnc/maps/nod06b/nod06b.lua b/mods/cnc/maps/nod06b/nod06b.lua index 444300e6e5..60b321dba6 100644 --- a/mods/cnc/maps/nod06b/nod06b.lua +++ b/mods/cnc/maps/nod06b/nod06b.lua @@ -6,6 +6,7 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + NodUnitsVehicle1 = { tough = { 'bggy', 'bike', 'bike' }, @@ -13,6 +14,7 @@ NodUnitsVehicle1 = normal = { 'bggy', 'bggy', 'bike', 'bike', 'bike' }, easy = { 'bggy', 'bggy', 'bggy', 'bike', 'bike', 'bike', 'bike' } } + NodUnitsVehicle2 = { tough = { 'ltnk', 'ltnk' }, @@ -20,6 +22,7 @@ NodUnitsVehicle2 = normal = { 'ltnk', 'ltnk', 'ltnk', 'ltnk' }, easy = { 'ltnk', 'ltnk', 'ltnk', 'ltnk', 'ltnk' } } + NodUnitsGunner = { tough = { 'e1', 'e1', 'e1', 'e1' }, @@ -27,6 +30,7 @@ NodUnitsGunner = normal = { 'e1', 'e1', 'e1', 'e1', 'e1', 'e1', 'e1' }, easy = { 'e1', 'e1', 'e1', 'e1', 'e1', 'e1', 'e1', 'e1', 'e1', 'e1' } } + NodUnitsRocket = { tough = { 'e3', 'e3', 'e3', 'e3' }, @@ -34,6 +38,7 @@ NodUnitsRocket = normal = { 'e3', 'e3', 'e3', 'e3', 'e3', 'e3', 'e3' }, easy = { 'e3', 'e3', 'e3', 'e3', 'e3', 'e3', 'e3', 'e3', 'e3', 'e3' } } + Gdi1Units = { 'e1', 'e1', 'e2', 'e2', 'e2' } Obj2Units = { 'ftnk', 'e4', 'e4' } @@ -53,183 +58,118 @@ Chn1Waypoints = { ChnEntry.Location, waypoint0.Location } Chn2Waypoints = { ChnEntry.Location, waypoint0.Location } Gdi5Waypoint = { waypoint1, waypoint2, waypoint3, waypoint4, waypoint5, waypoint6, waypoint7 } -HuntTriggerFunction = function() - local list = enemy.GetGroundAttackers() - Utils.Do(list, function(unit) - IdleHunt(unit) +OnAnyDamaged = function(actors, func) + local triggered + Utils.Do(actors, function(actor) + Trigger.OnDamaged(actor, function() + if triggered then + return + end + + triggered = true + func() + end) end) end -Chn1TriggerFunction = function() - if not Chn1Switch then - local cargo = Reinforcements.ReinforceWithTransport(enemy, 'tran', Gdi1Units, Chn1Waypoints, { ChnEntry.Location })[2] - Utils.Do(cargo, function(actor) - IdleHunt(actor) - end) - Chn1Switch = true - end -end - -Atk1TriggerFunction = function() - if not Atk1Switch then - for type, count in pairs({ ['e2'] = 2, ['jeep'] = 1, ['e1'] = 2}) do - MyActors = Utils.Take(count, enemy.GetActorsByType(type)) - Utils.Do(MyActors, function(actor) - IdleHunt(actor) - end) - end - Atk1Switch = true - end -end - -Atk2TriggerFunction = function() - if not Atk2Switch then - for type, count in pairs({ ['e2'] = 2, ['e1'] = 2}) do - MyActors = Utils.Take(count, enemy.GetActorsByType(type)) - Utils.Do(MyActors, function(actor) - MoveAndHunt(actor, Gdi5Waypoint) - end) - end - Atk2Switch = true - end -end - -Chn2TriggerFunction = function() - if not Chn2Switch then - local cargo = Reinforcements.ReinforceWithTransport(enemy, 'tran', Gdi1Units, Chn2Waypoints, { ChnEntry.Location })[2] - Utils.Do(cargo, function(actor) - IdleHunt(actor) - end) - Chn2Switch = true - end -end - -Obj2TriggerFunction = function() - player.MarkCompletedObjective(NodObjective2) - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.Reinforce(player, Obj2Units, { Obj2UnitsEntry.Location, waypoint13.Location }, 15) -end - -MoveAndHunt = function(unit, waypoints) - if unit ~= nil then - Utils.Do(waypoints, function(waypoint) - unit.AttackMove(waypoint.Location) - end) - IdleHunt(unit) - end -end - InsertNodUnits = function() - local difficulty = Map.LobbyOption("difficulty") - NodUnitsVehicle1 = NodUnitsVehicle1[difficulty] - NodUnitsVehicle2 = NodUnitsVehicle2[difficulty] - NodUnitsGunner = NodUnitsGunner[difficulty] - NodUnitsRocket = NodUnitsRocket[difficulty] - - Media.PlaySpeechNotification(player, "Reinforce") + NodUnitsVehicle1 = NodUnitsVehicle1[Difficulty] + NodUnitsVehicle2 = NodUnitsVehicle2[Difficulty] + NodUnitsGunner = NodUnitsGunner[Difficulty] + NodUnitsRocket = NodUnitsRocket[Difficulty] + + Media.PlaySpeechNotification(Nod, "Reinforce") Camera.Position = UnitsRallyVehicle2.CenterPosition - Reinforcements.Reinforce(player, NodUnitsVehicle1, { UnitsEntryVehicle.Location, UnitsRallyVehicle1.Location }, 10) - Reinforcements.Reinforce(player, NodUnitsVehicle2, { UnitsEntryVehicle.Location, UnitsRallyVehicle2.Location }, 15) - Reinforcements.Reinforce(player, NodUnitsGunner, { UnitsEntryGunner.Location, UnitsRallyGunner.Location }, 15) - Reinforcements.Reinforce(player, NodUnitsRocket, { UnitsEntryRocket.Location, UnitsRallyRocket.Location }, 25) + Reinforcements.Reinforce(Nod, NodUnitsVehicle1, { UnitsEntryVehicle.Location, UnitsRallyVehicle1.Location }, 10) + Reinforcements.Reinforce(Nod, NodUnitsVehicle2, { UnitsEntryVehicle.Location, UnitsRallyVehicle2.Location }, 15) + Reinforcements.Reinforce(Nod, NodUnitsGunner, { UnitsEntryGunner.Location, UnitsRallyGunner.Location }, 15) + Reinforcements.Reinforce(Nod, NodUnitsRocket, { UnitsEntryRocket.Location, UnitsRallyRocket.Location }, 25) end WorldLoaded = function() - player = Player.GetPlayer("Nod") - enemy = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) + InitObjectives(Nod) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) - - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) - - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - NodObjective1 = player.AddPrimaryObjective("Steal the GDI nuclear detonator.") - NodObjective2 = player.AddSecondaryObjective("Destroy the houses of the GDI supporters\nin the village.") - - GDIObjective = enemy.AddPrimaryObjective("Stop the Nod taskforce from escaping with the detonator.") + StealDetonator = Nod.AddObjective("Steal the GDI nuclear detonator.") + DestroyVillage = Nod.AddObjective("Destroy the houses of the GDI supporters\nin the village.", "Secondary", false) InsertNodUnits() Trigger.OnEnteredFootprint(HuntCellTriggerActivator, function(a, id) - if a.Owner == player then - HuntTriggerFunction() + if a.Owner == Nod then + Utils.Do(GDI.GetGroundAttackers(), IdleHunt) Trigger.RemoveFootprintTrigger(id) end end) Trigger.OnEnteredFootprint(DzneCellTriggerActivator, function(a, id) - if a.Owner == player then - Actor.Create('flare', true, { Owner = player, Location = waypoint17.Location }) + if a.Owner == Nod then + Actor.Create('flare', true, { Owner = Nod, Location = waypoint17.Location }) Trigger.RemoveFootprintTrigger(id) end end) - - Trigger.OnAllRemovedFromWorld(Obj2ActorTriggerActivator, Obj2TriggerFunction) + + Trigger.OnAllRemovedFromWorld(Obj2ActorTriggerActivator, function() + Nod.MarkCompletedObjective(DestroyVillage) + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.Reinforce(Nod, Obj2Units, { Obj2UnitsEntry.Location, waypoint13.Location }, 15) + end) Trigger.OnEnteredFootprint(Win1CellTriggerActivator, function(a, id) - if a.Owner == player then - NodObjective3 = player.AddPrimaryObjective("Move to the evacuation point.") - player.MarkCompletedObjective(NodObjective1) + if a.Owner == Nod then + EvacuateObjective = Nod.AddObjective("Move to the evacuation point.") + Nod.MarkCompletedObjective(StealDetonator) Trigger.RemoveFootprintTrigger(id) end end) Trigger.OnEnteredFootprint(Win2CellTriggerActivator, function(a, id) - if a.Owner == player and NodObjective3 then - player.MarkCompletedObjective(NodObjective3) + if a.Owner == Nod and EvacuateObjective then + Nod.MarkCompletedObjective(EvacuateObjective) Trigger.RemoveFootprintTrigger(id) end end) - OnAnyDamaged(Chn1ActorTriggerActivator, Chn1TriggerFunction) + OnAnyDamaged(Chn1ActorTriggerActivator, function() + local cargo = Reinforcements.ReinforceWithTransport(GDI, 'tran', Gdi1Units, Chn1Waypoints, { ChnEntry.Location })[2] + Utils.Do(cargo, IdleHunt) + end) - OnAnyDamaged(Atk1ActorTriggerActivator, Atk1TriggerFunction) + OnAnyDamaged(Atk1ActorTriggerActivator, function() + for type, count in pairs({ ['e2'] = 2, ['jeep'] = 1, ['e1'] = 2}) do + Utils.Do(Utils.Take(count, GDI.GetActorsByType(type)), IdleHunt) + end + end) - OnAnyDamaged(Atk2ActorTriggerActivator, Atk2TriggerFunction) + OnAnyDamaged(Atk2ActorTriggerActivator, function() + for type, count in pairs({ ['e2'] = 2, ['e1'] = 2}) do + MoveAndHunt(Utils.Take(count, GDI.GetActorsByType(type)), Gdi5Waypoint) + end + end) - OnAnyDamaged(Chn2ActorTriggerActivator, Chn2TriggerFunction) + OnAnyDamaged(Chn2ActorTriggerActivator, function() + local cargo = Reinforcements.ReinforceWithTransport(GDI, 'tran', Gdi1Units, Chn2Waypoints, { ChnEntry.Location })[2] + Utils.Do(cargo, IdleHunt) + end) Trigger.OnEnteredFootprint(ChnCellTriggerActivator, function(a, id) - if a.Owner == player then - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.ReinforceWithTransport(player, 'tran', nil, { ChnEntry.Location, waypoint17.Location }, nil, nil, nil) + if a.Owner == Nod then + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.ReinforceWithTransport(Nod, 'tran', nil, { ChnEntry.Location, waypoint17.Location }, nil, nil, nil) Trigger.RemoveFootprintTrigger(id) end end) end Tick = function() - if player.HasNoRequiredUnits() then - if DateTime.GameTime > 2 then - enemy.MarkCompletedObjective(GDIObjective) + if DateTime.GameTime > 2 and Nod.HasNoRequiredUnits() then + Nod.MarkFailedObjective(StealDetonator) + + if EvacuateObjective then + Nod.MarkFailedObjective(EvacuateObjective) end end end - -IdleHunt = function(unit) - if not unit.IsDead then - Trigger.OnIdle(unit, unit.Hunt) - end -end - -OnAnyDamaged = function(actors, func) - Utils.Do(actors, function(actor) - Trigger.OnDamaged(actor, func) - end) -end diff --git a/mods/cnc/maps/nod06b/rules.yaml b/mods/cnc/maps/nod06b/rules.yaml index 034a077c65..fbd86d7ced 100644 --- a/mods/cnc/maps/nod06b/rules.yaml +++ b/mods/cnc/maps/nod06b/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: nod06b.lua + Scripts: campaign-global.lua, nod06b.lua MusicPlaylist: StartingMusic: rout VictoryMusic: nod_win1 @@ -18,6 +18,7 @@ World: hard: Hard tough: Real tough guy Default: normal + Locked: false Player: PlayerResources: diff --git a/mods/cnc/maps/nod06c/nod06c.lua b/mods/cnc/maps/nod06c/nod06c.lua index 47e0459b78..ddf6ba156d 100644 --- a/mods/cnc/maps/nod06c/nod06c.lua +++ b/mods/cnc/maps/nod06c/nod06c.lua @@ -17,6 +17,7 @@ DzneCellTriggerActivator = { CPos.New(26,24), CPos.New(25,24), CPos.New(24,24), ChinCellTriggerActivator = { CPos.New(31,49), CPos.New(30,49), CPos.New(29,49), CPos.New(28,49), CPos.New(27,49), CPos.New(26,49), CPos.New(25,49), CPos.New(24,49), CPos.New(23,49), CPos.New(22,49), CPos.New(21,49), CPos.New(20,49), CPos.New(31,48), CPos.New(30,48), CPos.New(29,48), CPos.New(28,48), CPos.New(27,48), CPos.New(26,48), CPos.New(25,48), CPos.New(24,48), CPos.New(23,48), CPos.New(22,48), CPos.New(21,48), CPos.New(20,48), CPos.New(31,47), CPos.New(30,47), CPos.New(29,47), CPos.New(28,47), CPos.New(27,47), CPos.New(26,47), CPos.New(25,47), CPos.New(24,47), CPos.New(23,47), CPos.New(22,47), CPos.New(21,47), CPos.New(20,47) } Atk2ActorTriggerActivator = { Atk2Actor1, Atk2Actor2, Atk2Actor3, Atk2Actor4, Atk2Actor5, Atk2Actor6 } +BuildingsToCapture = { Barracks, Factory, Yard } Gdi1Units = { 'e1', 'e1', 'e1', 'e2', 'e2' } Gdi2Units = { 'e1', 'e1', 'e3', 'e3', 'e3' } @@ -27,152 +28,112 @@ Gdi5Units = { 'e1', 'e2', 'e2', 'e3', 'e3' } AllUnits = { Gdi1Units, Gdi2Units, Gdi3Units, Gdi4Units, Gdi5Units } Grd1Waypoints = { waypoint0, waypoint1, waypoint2, waypoint3, waypoint4, waypoint5 } -Atk1TriggerFunctionTime = DateTime.Seconds(3) -ProdTriggerFunctionTime = DateTime.Minutes(5) - -Atk1TriggerFunction = function() - for type, count in pairs({ ['e1'] = 2, ['e2'] = 3 }) do - MyActors = Utils.Take(count, enemy.GetActorsByType(type)) - Utils.Do(MyActors, function(actor) - MovementAndHunt(actor, Grd1Waypoints) - end) - end -end - -Atk2TriggerFunction = function() - for type, count in pairs({ ['e1'] = 2, ['e2'] = 3 , ['jeep'] = 1}) do - MyActors = Utils.Take(count, enemy.GetActorsByType(type)) - Utils.Do(MyActors, function(actor) - IdleHunt(actor) - end) - end -end +ProductionDelay = DateTime.Minutes(5) ProdTriggerFunction = function() - local Units = AllUnits[DateTime.GameTime % #AllUnits + 1] - - Utils.Do(Units, function(UnitType) - if (UnitType == 'jeep' or UnitType == 'mtnk') and not Factory.IsDead and Factory.Owner == enemy then - Factory.Build({UnitType}) - elseif (UnitType == 'e1' or UnitType == 'e2' or UnitType == 'e3') and not Barracks.IsDead and Barracks.Owner == enemy then - Barracks.Build({UnitType}) + local units = AllUnits[DateTime.GameTime % #AllUnits + 1] + Utils.Do(units, function(unitType) + if (unitType == 'jeep' or unitType == 'mtnk') and not Factory.IsDead and Factory.Owner == GDI then + Factory.Build({ unitType }) + elseif (unitType == 'e1' or unitType == 'e2' or unitType == 'e3') and not Barracks.IsDead and Barracks.Owner == GDI then + Barracks.Build({ unitType }) end end) - local list = enemy.GetGroundAttackers() - local counter = 1 - while counter <= 5 do - counter = counter + 1 - if counter <= #list then - IdleHunt(list[counter]) - end - end + Utils.Do(Utils.Take(5, GDI.GetGroundAttackers()), IdleHunt) - Trigger.AfterDelay(ProdTriggerFunctionTime, ProdTriggerFunction) -end - -MovementAndHunt = function(unit, waypoints) - if unit ~= nil then - Utils.Do(waypoints, function(waypoint) - unit.AttackMove(waypoint.Location) - end) - IdleHunt(unit) - end + Trigger.AfterDelay(ProductionDelay, ProdTriggerFunction) end InsertNodUnits = function() Camera.Position = UnitsRallyRight.CenterPosition - - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.Reinforce(player, NodStartUnitsVehicle, { UnitsEntryMiddle.Location, UnitsRallyMiddle.Location }, 30) - Reinforcements.Reinforce(player, NodStartUnitsMiddle, { UnitsEntryMiddle.Location, UnitsRallyMiddle.Location }, 15) - Reinforcements.Reinforce(player, NodStartUnitsLeft, { UnitsEntryLeft.Location, UnitsRallyLeft.Location }, 15) - Reinforcements.Reinforce(player, NodStartUnitsRight, { UnitsEntryRight.Location, UnitsRallyRight.Location }, 15) + + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.Reinforce(Nod, NodStartUnitsVehicle, { UnitsEntryMiddle.Location, UnitsRallyMiddle.Location }, 30) + Reinforcements.Reinforce(Nod, NodStartUnitsMiddle, { UnitsEntryMiddle.Location, UnitsRallyMiddle.Location }, 15) + Reinforcements.Reinforce(Nod, NodStartUnitsLeft, { UnitsEntryLeft.Location, UnitsRallyLeft.Location }, 15) + Reinforcements.Reinforce(Nod, NodStartUnitsRight, { UnitsEntryRight.Location, UnitsRallyRight.Location }, 15) end WorldLoaded = function() - player = Player.GetPlayer("Nod") - enemy = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) + InitObjectives(Nod) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) - - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) - - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - NodObjective1 = player.AddPrimaryObjective("Steal the GDI nuclear detonator.") - NodObjective3 = player.AddSecondaryObjective("Infiltrate the barracks, weapon factory and \nthe construction yard.") - GDIObjective = enemy.AddPrimaryObjective("Stop the Nod taskforce from escaping with the detonator.") + NodObjective1 = Nod.AddObjective("Steal the GDI nuclear detonator.") + InfiltrateObjective = Nod.AddObjective("Infiltrate the barracks, weapon factory and\nthe construction yard.", "Secondary", false) InsertNodUnits() - Trigger.AfterDelay(Atk1TriggerFunctionTime, Atk1TriggerFunction) + Trigger.AfterDelay(DateTime.Seconds(3), function() + for type, count in pairs({ ['e1'] = 2, ['e2'] = 3 }) do + MoveAndHunt(Utils.Take(count, GDI.GetActorsByType(type)), Grd1Waypoints) + end + end) - Trigger.OnAllKilled(Atk2ActorTriggerActivator, Atk2TriggerFunction) + Trigger.OnAllKilled(Atk2ActorTriggerActivator, function() + for type, count in pairs({ ['e1'] = 2, ['e2'] = 3 , ['jeep'] = 1}) do + Utils.Do(Utils.Take(count, GDI.GetActorsByType(type)), IdleHunt) + end + end) Trigger.OnEnteredFootprint(ChinCellTriggerActivator, function(a, id) - if a.Owner == player then - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.ReinforceWithTransport(player, 'tran', nil, { ChnEntry.Location, waypoint10.Location }, nil, nil, nil) + if a.Owner == Nod then + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.ReinforceWithTransport(Nod, 'tran', nil, { ChnEntry.Location, waypoint10.Location }, nil, nil, nil) Trigger.RemoveFootprintTrigger(id) end end) Trigger.OnEnteredFootprint(DzneCellTriggerActivator, function(a, id) - if a.Owner == player then - Actor.Create('flare', true, { Owner = player, Location = waypoint10.Location }) + if a.Owner == Nod then + Actor.Create('flare', true, { Owner = Nod, Location = waypoint10.Location }) Trigger.RemoveFootprintTrigger(id) end end) Trigger.OnEnteredFootprint(Win1CellTriggerActivator, function(a, id) - if a.Owner == player then - NodObjective2 = player.AddPrimaryObjective("Move to the evacuation point.") - player.MarkCompletedObjective(NodObjective1) + if a.Owner == Nod then + EvacuateObjective = Nod.AddObjective("Move to the evacuation point.") + Nod.MarkCompletedObjective(NodObjective1) Trigger.RemoveFootprintTrigger(id) end end) Trigger.OnEnteredFootprint(Win2CellTriggerActivator, function(a, id) - if a.Owner == player and NodObjective2 then - player.MarkCompletedObjective(NodObjective2) + if a.Owner == Nod and EvacuateObjective then + Nod.MarkCompletedObjective(EvacuateObjective) Trigger.RemoveFootprintTrigger(id) end end) - Trigger.AfterDelay(ProdTriggerFunctionTime, ProdTriggerFunction) + Trigger.AfterDelay(ProductionDelay, ProdTriggerFunction) + + Trigger.OnAnyKilled(BuildingsToCapture, function() + if not Nod.IsObjectiveCompleted(InfiltrateObjective) then + Nod.MarkFailedObjective(InfiltrateObjective) + end + end) + + Utils.Do(BuildingsToCapture, function(building) + local captured = 0 + Trigger.OnCapture(building, function() + captured = captured + 1 + + if captured == 3 then + Nod.MarkCompletedObjective(InfiltrateObjective) + end + end) + end) end Tick = function() - if DateTime.GameTime > 2 and player.HasNoRequiredUnits() then - enemy.MarkCompletedObjective(GDIObjective) - end + if DateTime.GameTime > 2 and Nod.HasNoRequiredUnits() then + Nod.MarkFailedObjective(StealDetonator) - if DateTime.GameTime % 5 == 0 and Barracks.Owner == player and Factory.Owner == player and Yard.Owner == player then - player.MarkCompletedObjective(NodObjective3) - end - - if DateTime.GameTime % 7 == 0 and not player.IsObjectiveCompleted(NodObjective3) and (Barracks.IsDead or Factory.IsDead or Yard.IsDead) then - player.MarkFailedObjective(NodObjective3) - end -end - -IdleHunt = function(unit) - if not unit.IsDead then - Trigger.OnIdle(unit, unit.Hunt) + if EvacuateObjective then + Nod.MarkFailedObjective(EvacuateObjective) + end end end diff --git a/mods/cnc/maps/nod06c/rules.yaml b/mods/cnc/maps/nod06c/rules.yaml index ad0cde2d9b..8260381f7c 100644 --- a/mods/cnc/maps/nod06c/rules.yaml +++ b/mods/cnc/maps/nod06c/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: nod06c.lua + Scripts: campaign-global.lua, nod06c.lua MusicPlaylist: StartingMusic: rout VictoryMusic: nod_win1 diff --git a/mods/cnc/maps/nod07a/nod07a-AI.lua b/mods/cnc/maps/nod07a/nod07a-AI.lua index 5a02ad25a1..eca88a0cf6 100644 --- a/mods/cnc/maps/nod07a/nod07a-AI.lua +++ b/mods/cnc/maps/nod07a/nod07a-AI.lua @@ -6,6 +6,7 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + AttackPaths = { { AttackPath1 }, { AttackPath2 } } GDIBase = { GDICYard, GDIPyle, GDIWeap, GDIHQ, GDIProc, GDINuke1, GDINuke2, GDINuke3, GDIBuilding1, GDIBuilding2, GDIBuilding3, GDIBuilding4, GDIBuilding5, GDIBuilding6, GDIBuilding7, GDIBuilding8 } InfantryAttackGroup = { } @@ -19,39 +20,33 @@ VehicleProductionCooldown = DateTime.Minutes(4) VehicleProductionTypes = { "jeep", "jeep", "mtnk", "mtnk", "mtnk" } StartingCash = 4000 -BaseProc = { type = "proc", pos = CPos.New(22, 51), cost = 1500, exists = true } -BaseNuke1 = { type = "nuke", pos = CPos.New(16, 56), cost = 500, exists = true } -BaseNuke2 = { type = "nuke", pos = CPos.New(18, 57), cost = 500, exists = true } -BaseNuke3 = { type = "nuke", pos = CPos.New(27, 51), cost = 500, exists = true } -InfantryProduction = { type = "pyle", pos = CPos.New(18, 54), cost = 500, exists = true } -VehicleProduction = { type = "weap", pos = CPos.New(27, 55), cost = 2000, exists = true } +BaseProc = { type = "proc", pos = CPos.New(22, 51), cost = 1500 } +BaseNuke1 = { type = "nuke", pos = CPos.New(16, 56), cost = 500 } +BaseNuke2 = { type = "nuke", pos = CPos.New(18, 57), cost = 500 } +BaseNuke3 = { type = "nuke", pos = CPos.New(27, 51), cost = 500 } +InfantryProduction = { type = "pyle", pos = CPos.New(18, 54), cost = 500 } +VehicleProduction = { type = "weap", pos = CPos.New(27, 55), cost = 2000 } BaseBuildings = { BaseProc, BaseNuke1, BaseNuke2, BaseNuke3, InfantryProduction, VehicleProduction } -BuildBase = function(cyard) - Utils.Do(BaseBuildings, function(building) - if not building.exists and not cyardIsBuilding then - BuildBuilding(building, cyard) - return - end - end) - Trigger.AfterDelay(DateTime.Seconds(10), function() BuildBase(cyard) end) -end - BuildBuilding = function(building, cyard) - cyardIsBuilding = true + if CyardIsBuilding or GDI.Cash < building.cost then + Trigger.AfterDelay(DateTime.Seconds(10), function() BuildBuilding(building, cyard) end) + return + end + CyardIsBuilding = true + + GDI.Cash = GDI.Cash - building.cost Trigger.AfterDelay(Actor.BuildTime(building.type), function() - cyardIsBuilding = false + CyardIsBuilding = false - if cyard.IsDead or cyard.Owner ~= enemy then + if cyard.IsDead or cyard.Owner ~= GDI then + GDI.Cash = GDI.Cash + building.cost return end - local actor = Actor.Create(building.type, true, { Owner = enemy, Location = building.pos }) - enemy.Cash = enemy.Cash - building.cost - - building.exists = true + local actor = Actor.Create(building.type, true, { Owner = GDI, Location = building.pos }) if actor.Type == 'pyle' or actor.Type == 'hand' then Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceInfantry(actor) end) @@ -59,37 +54,19 @@ BuildBuilding = function(building, cyard) Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceVehicle(actor) end) end - Trigger.OnKilled(actor, function() building.exists = false end) - - Trigger.OnDamaged(actor, function(building) - if building.Owner == enemy and building.Health < building.MaxHealth * 3/4 then - building.StartBuildingRepairs() - end + Trigger.OnKilled(actor, function() + BuildBuilding(building, cyard) end) - Trigger.AfterDelay(DateTime.Seconds(10), function() BuildBase(cyard) end) + RepairBuilding(GDI, actor, 0.75) end) end CheckForHarvester = function() - local harv = enemy.GetActorsByType("harv") + local harv = GDI.GetActorsByType("harv") return #harv > 0 end -IdleHunt = function(unit) - if not unit.IsDead then - Trigger.OnIdle(unit, unit.Hunt) - end -end - -IdlingUnits = function(enemy) - local lazyUnits = enemy.GetGroundAttackers() - - Utils.Do(lazyUnits, function(unit) - IdleHunt(unit) - end) -end - ProduceHarvester = function(building) if not buildingHarvester then buildingHarvester = true @@ -100,10 +77,11 @@ ProduceHarvester = function(building) end ProduceInfantry = function(building) - if building.IsDead or building.Owner ~= enemy then + if building.IsDead or building.Owner ~= GDI then return elseif not CheckForHarvester() then Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceInfantry(building) end) + return end local delay = Utils.RandomInteger(DateTime.Seconds(3), DateTime.Seconds(9)) @@ -113,22 +91,22 @@ ProduceInfantry = function(building) InfantryAttackGroup[#InfantryAttackGroup + 1] = unit[1] if #InfantryAttackGroup >= InfantryGroupSize then - SendUnits(InfantryAttackGroup, Path) + MoveAndHunt(InfantryAttackGroup, Path) InfantryAttackGroup = { } Trigger.AfterDelay(InfantryProductionCooldown, function() ProduceInfantry(building) end) else Trigger.AfterDelay(delay, function() ProduceInfantry(building) end) end end) - end ProduceVehicle = function(building) - if building.IsDead or building.Owner ~= enemy then + if building.IsDead or building.Owner ~= GDI then return elseif not CheckForHarvester() then ProduceHarvester(building) Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceVehicle(building) end) + return end local delay = Utils.RandomInteger(DateTime.Seconds(12), DateTime.Seconds(17)) @@ -138,7 +116,7 @@ ProduceVehicle = function(building) VehicleAttackGroup[#VehicleAttackGroup + 1] = unit[1] if #VehicleAttackGroup >= VehicleGroupSize then - SendUnits(VehicleAttackGroup, Path) + MoveAndHunt(VehicleAttackGroup, Path) VehicleAttackGroup = { } Trigger.AfterDelay(VehicleProductionCooldown, function() ProduceVehicle(building) end) else @@ -147,55 +125,35 @@ ProduceVehicle = function(building) end) end -SendUnits = function(units, waypoints) - Utils.Do(units, function(unit) - if not unit.IsDead then - Utils.Do(waypoints, function(waypoint) - unit.AttackMove(waypoint.Location) - end) - IdleHunt(unit) - end - end) +StartAI = function() + RepairNamedActors(GDI, 0.75) + + GDI.Cash = StartingCash + + Trigger.AfterDelay(DateTime.Minutes(2), function() ProduceInfantry(GDIPyle) end) + Trigger.AfterDelay(DateTime.Minutes(3), function() ProduceVehicle(GDIWeap) end) end -StartAI = function(cyard) - Utils.Do(Map.NamedActors, function(actor) - if actor.Owner == enemy and actor.HasProperty("StartBuildingRepairs") then - Trigger.OnDamaged(actor, function(building) - if building.Owner == enemy and building.Health < 3/4 * building.MaxHealth then - building.StartBuildingRepairs() - end - end) - end - end) - enemy.Cash = StartingCash - BuildBase(cyard) -end - -Trigger.OnAllKilledOrCaptured(GDIBase, function() - IdlingUnits(enemy) +Trigger.OnKilled(GDIProc, function() + BuildBuilding(BaseProc, GDICYard) end) -Trigger.OnKilled(GDIProc, function(building) - BaseProc.exists = false +Trigger.OnKilled(GDINuke1, function() + BuildBuilding(BaseNuke1, GDICYard) end) -Trigger.OnKilled(GDINuke1, function(building) - BaseNuke1.exists = false +Trigger.OnKilled(GDINuke2, function() + BuildBuilding(BaseNuke2, GDICYard) end) -Trigger.OnKilled(GDINuke2, function(building) - BaseNuke2.exists = false +Trigger.OnKilled(GDINuke3, function() + BuildBuilding(BaseNuke3, GDICYard) end) -Trigger.OnKilled(GDINuke3, function(building) - BaseNuke3.exists = false +Trigger.OnKilled(GDIPyle, function() + BuildBuilding(InfantryProduction, GDICYard) end) -Trigger.OnKilled(GDIPyle, function(building) - InfantryProduction.exists = false -end) - -Trigger.OnKilled(GDIWeap, function(building) - VehicleProduction.exists = false +Trigger.OnKilled(GDIWeap, function() + BuildBuilding(VehicleProduction, GDICYard) end) diff --git a/mods/cnc/maps/nod07a/nod07a.lua b/mods/cnc/maps/nod07a/nod07a.lua index 4fbe6632ac..94366f7fc8 100644 --- a/mods/cnc/maps/nod07a/nod07a.lua +++ b/mods/cnc/maps/nod07a/nod07a.lua @@ -6,29 +6,30 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] -GDI1 = { teamType = "atk", units = { ['e2'] = 3 }, waypoints = { waypoint0, waypoint1, waypoint2, waypoint14 }, delay = 40 } -GDI2 = { teamType = "atk", units = { ['mtnk'] = 2 }, waypoints = { waypoint0, waypoint1, waypoint2, waypoint3, waypoint4, waypoint9 }, delay = 30 } -GDI3 = { teamType = "atk", units = { ['e2'] = 4 }, waypoints = { waypoint0, waypoint4, waypoint5, waypoint6, waypoint7, waypoint8 }, delay = 40 } -GDI4 = { teamType = "atk", units = { ['e1'] = 1, ['e2'] = 2 }, waypoints = { waypoint0, waypoint4, waypoint9 }, delay = 30 } -GDI5 = { teamType = "atk", units = { ['mtnk'] = 1 }, waypoints = { waypoint0, waypoint4, waypoint10, waypoint11, waypoint12, waypoint13 }, delay = 80 } -GDI6 = { teamType = "atk", units = { ['mtnk'] = 1 }, waypoints = { waypoint0, waypoint4, waypoint9 }, delay = 50 } -GDI7 = { teamType = "atk", units = { ['jeep'] = 1 }, waypoints = { waypoint0, waypoint4, waypoint5, waypoint6, waypoint7, waypoint8 }, delay = 40 } -GDI8 = { teamType = "rei", units = { ['e2'] = 3, ['e6'] = 2 }, waypoints = { waypoint12, waypoint11, waypoint10, waypoint4, waypoint5, waypoint8 }, delay = 8 } -GDI9 = { teamType = "atk", units = { ['e2'] = 4 }, waypoints = { waypoint8 }, delay = 80 } -GDI10 = { teamType = "atk", units = { ['e2'] = 4 }, waypoints = { waypoint14 }, delay = 0 } + +GDI1 = { teamType = "atk", units = { "e2", "e2", "e2" }, waypoints = { waypoint0, waypoint1, waypoint2, waypoint14 }, delay = 40 } +GDI2 = { teamType = "atk", units = { "mtnk", "mtnk" }, waypoints = { waypoint0, waypoint1, waypoint2, waypoint3, waypoint4, waypoint9 }, delay = 30 } +GDI3 = { teamType = "atk", units = { "e2", "e2", "e2", "e2" }, waypoints = { waypoint0, waypoint4, waypoint5, waypoint6, waypoint7, waypoint8 }, delay = 40 } +GDI4 = { teamType = "atk", units = { "e1", "e2", "e2" }, waypoints = { waypoint0, waypoint4, waypoint9 }, delay = 30 } +GDI5 = { teamType = "atk", units = { "mtnk" }, waypoints = { waypoint0, waypoint4, waypoint10, waypoint11, waypoint12, waypoint13 }, delay = 80 } +GDI6 = { teamType = "atk", units = { "mtnk" }, waypoints = { waypoint0, waypoint4, waypoint9 }, delay = 50 } +GDI7 = { teamType = "atk", units = { "jeep" }, waypoints = { waypoint0, waypoint4, waypoint5, waypoint6, waypoint7, waypoint8 }, delay = 40 } +GDI8 = { teamType = "rei", units = { "e2", "e2", "e2", "e6", "e6" }, waypoints = { waypoint12, waypoint11, waypoint10, waypoint4, waypoint5, waypoint8 }, delay = 8 } +GDI9 = { teamType = "atk", units = { "e2", "e2", "e2", "e2" }, waypoints = { waypoint8 }, delay = 80 } +GDI10 = { teamType = "atk", units = { "e2", "e2", "e2", "e2" }, waypoints = { waypoint14 }, delay = 0 } AirstrikeDelay = DateTime.Minutes(2) + DateTime.Seconds(20) AutoAttackWaves = { GDI3, GDI4, GDI5, GDI6, GDI7, GDI8, GDI9, GDI10 } IntroAttackWaves = { GDI1, GDI2 } -WhitelistedStructures = { 'afld', 'hand', 'hq', 'nuke', 'silo', 'proc', 'sam' } +WhitelistedStructures = { "afld", "hand", "hq", "nuke", "silo", "proc", "sam" } -NodUnitsBikes = { 'bike', 'bike', 'bike' } -NodUnitsEngineers = { 'e6', 'e6' } -NodUnitsRockets = { 'e3', 'e3', 'e3', 'e3' } -NodUnitsGunners = { 'e1', 'e1', 'e1', 'e1' } -NodUnitsFlamers = { 'e4', 'e4', 'e4', 'e4' } -ReinforcementsRockets = { 'e3', 'e3', 'e3', 'e3', 'e3' } +NodUnitsBikes = { "bike", "bike", "bike" } +NodUnitsEngineers = { "e6", "e6" } +NodUnitsRockets = { "e3", "e3", "e3", "e3" } +NodUnitsGunners = { "e1", "e1", "e1", "e1" } +NodUnitsFlamers = { "e4", "e4", "e4", "e4" } +ReinforcementsRockets = { "e3", "e3", "e3", "e3", "e3" } NodBase = { NodBuilding1, NodBuilding2, NodBuilding3, NodHarvester } @@ -37,98 +38,42 @@ ReinforcementsTrigger = { CPos.New(35, 23), CPos.New(34, 23), CPos.New(35, 22), CaptureStructures = function(actor) for i = 1, #WhitelistedStructures do - structures = player.GetActorsByType(WhitelistedStructures[i]) - if #structures > 0 then - if not actor.IsDead and not structures[1].IsDead then - actor.Capture(structures[1]) - return - end + structures = Nod.GetActorsByType(WhitelistedStructures[i]) + if #structures > 0 and not actor.IsDead and not structures[1].IsDead then + actor.Capture(structures[1]) + return end end end CheckForSams = function() - local sams = player.GetActorsByType("sam") + local sams = Nod.GetActorsByType("sam") return #sams >= 3 end -searches = 0 -getAirstrikeTarget = function() - local list = player.GetGroundAttackers() - - if #list == 0 then - return - end - - local target = list[DateTime.GameTime % #list + 1].CenterPosition - - local sams = Map.ActorsInCircle(target, WDist.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 - -GetCargo = function(team) - cargo = { } - for type, count in pairs(team.units) do - for i = 1, count, 1 do - cargo[#cargo + 1] = type - end - end - return cargo -end - InsertNodUnits = function() - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.Reinforce(player, { 'ltnk'}, { ReinforcementsTopSpawn.Location, ReinforcementsTank1Rally.Location }, 1) - Reinforcements.Reinforce(player, NodUnitsEngineers, { ReinforcementsTopSpawn.Location, ReinforcementsEngineersRally.Location }, 10) - Reinforcements.Reinforce(player, NodUnitsRockets, { ReinforcementsTopSpawn.Location, ReinforcementsRocketsRally.Location }, 10) + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.Reinforce(Nod, { "ltnk" }, { ReinforcementsTopSpawn.Location, ReinforcementsTank1Rally.Location }, 1) + Reinforcements.Reinforce(Nod, NodUnitsEngineers, { ReinforcementsTopSpawn.Location, ReinforcementsEngineersRally.Location }, 10) + Reinforcements.Reinforce(Nod, NodUnitsRockets, { ReinforcementsTopSpawn.Location, ReinforcementsRocketsRally.Location }, 10) Trigger.AfterDelay(DateTime.Seconds(3), function() - Reinforcements.Reinforce(player, NodUnitsGunners, { ReinforcementsBottomSpawn.Location, ReinforcementsGunnersRally.Location }, 10) - Reinforcements.Reinforce(player, NodUnitsFlamers, { ReinforcementsTopSpawn.Location, ReinforcementsFlamersRally.Location }, 10) - Reinforcements.Reinforce(player, { 'ltnk'}, { ReinforcementsBottomSpawn.Location, ReinforcementsTank2Rally.Location }, 10) + Reinforcements.Reinforce(Nod, NodUnitsGunners, { ReinforcementsBottomSpawn.Location, ReinforcementsGunnersRally.Location }, 10) + Reinforcements.Reinforce(Nod, NodUnitsFlamers, { ReinforcementsTopSpawn.Location, ReinforcementsFlamersRally.Location }, 10) + Reinforcements.Reinforce(Nod, { "ltnk" }, { ReinforcementsBottomSpawn.Location, ReinforcementsTank2Rally.Location }, 10) end) end SendAttackWave = function(team) - for type, amount in pairs(team.units) do - count = 0 - actors = enemy.GetActorsByType(type) - Utils.Do(actors, function(actor) - if actor.IsIdle and count < amount then - SetAttackWaypoints(actor, team.waypoints) - if actor.Type == "e6" then - CaptureStructures(actor) - else - IdleHunt(actor) - end - count = count + 1 - end - end) - end -end - -SetAttackWaypoints = function(actor, waypoints) - if not actor.IsDead then - Utils.Do(waypoints, function(waypoint) - actor.AttackMove(waypoint.Location) - end) - end + Utils.Do(team.units, function(unitType) + local actors = Utils.Where(GDI.GetActorsByType(unitType), function(unit) return unit.IsIdle end) + MoveAndHunt(Utils.Take(1, actors), team.waypoints) + end) end SendGDIAirstrike = function(hq, delay) - if not hq.IsDead and hq.Owner == enemy then - local target = getAirstrikeTarget() + if not hq.IsDead and hq.Owner == GDI then + local target = GetAirstrikeTarget(Nod) if target then hq.SendAirstrike(target, false, Facing.NorthEast + 4) @@ -147,22 +92,27 @@ SendWaves = function(counter, Waves) elseif team.teamType == "rei" then SendReinforcementsWave(team) end + Trigger.AfterDelay(DateTime.Seconds(team.delay), function() SendWaves(counter + 1, Waves) end) end end SendReinforcementsWave = function(team) - Reinforcements.ReinforceWithTransport(enemy, "apc", GetCargo(team), { ReinforcementsGDISpawn.Location, waypoint12.Location}, nil, function(transport, passengers) - SetReinforcementsWaypoints(transport, team.waypoints) + Reinforcements.ReinforceWithTransport(GDI, "apc", team.units, { ReinforcementsGDISpawn.Location, waypoint12.Location }, nil, function(transport, passengers) + Utils.Do(team.waypoints, function(waypoint) + transport.Move(waypoint.Location) + end) + transport.UnloadPassengers() Trigger.OnPassengerExited(transport, function(_, passenger) Utils.Do(passengers, function(actor) - if actor.Type == "e6" then + if actor.Type == "e6" then CaptureStructures(actor) else IdleHunt(actor) end end) + if not transport.HasPassengers then IdleHunt(transport) end @@ -170,58 +120,42 @@ SendReinforcementsWave = function(team) end) end -SetReinforcementsWaypoints = function(actor, waypoints) - if not actor.IsDead then - Utils.Do(waypoints, function(waypoint) - actor.Move(waypoint.Location) - end) - end -end - -StartWaves = function(Waves) - SendWaves(1, Waves) -end - Trigger.OnEnteredFootprint(AbandonedBaseTrigger, function(a, id) - if not abandonedBaseTrigger and a.Owner == player then + if not abandonedBaseTrigger and a.Owner == Nod then abandonedBaseTrigger = true + Trigger.RemoveFootprintTrigger(id) - FlareCamera = Actor.Create("camera", true, { Owner = player, Location = waypoint25.Location }) - Flare = Actor.Create("flare", true, { Owner = player, Location = waypoint25.Location }) + FlareCamera = Actor.Create("camera", true, { Owner = Nod, Location = waypoint25.Location }) + Flare = Actor.Create("flare", true, { Owner = Nod, Location = waypoint25.Location }) Utils.Do(NodBase, function(actor) if not actor.IsDead then - actor.Owner = player + actor.Owner = Nod end end) - player.MarkCompletedObjective(NodObjective1) + Nod.MarkCompletedObjective(FindBase) Trigger.AfterDelay(DateTime.Seconds(3), function() - Media.PlaySpeechNotification(player, "NewOptions") + Media.PlaySpeechNotification(Nod, "NewOptions") end) end end) Trigger.OnEnteredFootprint(ReinforcementsTrigger, function(a, id) - if not reinforcementsTrigger and a.Owner == player and a.Type ~= 'harv' then + if not reinforcementsTrigger and a.Owner == Nod and a.Type ~= "harv" then reinforcementsTrigger = true + Trigger.RemoveFootprintTrigger(id) Trigger.AfterDelay(DateTime.Seconds(5), function() - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.ReinforceWithTransport(player, 'tran.in', ReinforcementsRockets, { ReinforcementsHelicopterSpawn.Location, waypoint24.Location }, { ReinforcementsHelicopterSpawn.Location }, nil, nil) + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.ReinforceWithTransport(Nod, "tran.in", ReinforcementsRockets, { ReinforcementsHelicopterSpawn.Location, waypoint24.Location }, { ReinforcementsHelicopterSpawn.Location }) end) - StartWaves(IntroAttackWaves) + SendWaves(1, IntroAttackWaves) Trigger.AfterDelay(AirstrikeDelay, function() SendGDIAirstrike(GDIHQ, AirstrikeDelay) end) - - Trigger.AfterDelay(DateTime.Minutes(2), function() ProduceInfantry(GDIPyle) end) - - Trigger.AfterDelay(DateTime.Minutes(3), function() ProduceVehicle(GDIWeap) end) - - Trigger.AfterDelay(DateTime.Minutes(3), function()StartWaves(AutoAttackWaves) end) - + Trigger.AfterDelay(DateTime.Minutes(3), function() SendWaves(1, AutoAttackWaves) end) Trigger.AfterDelay(DateTime.Minutes(2), function() Flare.Destroy() FlareCamera.Destroy() @@ -230,49 +164,31 @@ Trigger.OnEnteredFootprint(ReinforcementsTrigger, function(a, id) end) WorldLoaded = function() - player = Player.GetPlayer("Nod") - enemy = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") Camera.Position = waypoint26.CenterPosition InsertNodUnits() - StartAI(GDICYard) + StartAI() - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) + InitObjectives(Nod) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) - - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) - - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - NodObjective1 = player.AddPrimaryObjective("Find the Nod base.") - NodObjective2 = player.AddPrimaryObjective("Eliminate all GDI forces in the area.") - NodObjective3 = player.AddSecondaryObjective("Build 3 SAMs to fend off the GDI bombers.") - GDIObjective = enemy.AddPrimaryObjective("Eliminate all Nod forces in the area.") + FindBase = Nod.AddObjective("Find the Nod base.") + EliminateGDI = Nod.AddObjective("Eliminate all GDI forces in the area.") + BuildSAMs = Nod.AddObjective("Build 3 SAMs to fend off the GDI bombers.", "Secondary", false) + GDIObjective = GDI.AddObjective("Eliminate all Nod forces in the area.") end Tick = function() - if DateTime.GameTime > 2 and player.HasNoRequiredUnits() then - enemy.MarkCompletedObjective(GDIObjective) + if DateTime.GameTime > 2 and Nod.HasNoRequiredUnits() then + GDI.MarkCompletedObjective(GDIObjective) end - if DateTime.GameTime > 2 and enemy.HasNoRequiredUnits() then - player.MarkCompletedObjective(NodObjective2) + if DateTime.GameTime > 2 and GDI.HasNoRequiredUnits() then + Nod.MarkCompletedObjective(EliminateGDI) end - if not player.IsObjectiveCompleted(NodObjective3) and CheckForSams() then - player.MarkCompletedObjective(NodObjective3) + if not Nod.IsObjectiveCompleted(BuildSAMs) and CheckForSams() then + Nod.MarkCompletedObjective(BuildSAMs) end end diff --git a/mods/cnc/maps/nod07a/rules.yaml b/mods/cnc/maps/nod07a/rules.yaml index 31498a64ad..7c05275f65 100644 --- a/mods/cnc/maps/nod07a/rules.yaml +++ b/mods/cnc/maps/nod07a/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: nod07a.lua, nod07a-AI.lua + Scripts: campaign-global.lua, nod07a.lua, nod07a-AI.lua MusicPlaylist: StartingMusic: justdoit VictoryMusic: nod_win1 diff --git a/mods/cnc/maps/nod07b/nod07b-AI.lua b/mods/cnc/maps/nod07b/nod07b-AI.lua index 2265fd3ac9..58115d556f 100644 --- a/mods/cnc/maps/nod07b/nod07b-AI.lua +++ b/mods/cnc/maps/nod07b/nod07b-AI.lua @@ -6,6 +6,7 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + AttackPaths = { { AttackPath1 }, { AttackPath2 } } GDIBase = { GDICYard, GDIPyle, GDIWeap, GDIHQ, GDIProc, GDINuke1, GDINuke2, GDINuke3, GDIBuilding1, GDIBuilding2, GDIBuilding3, GDIBuilding4, GDIBuilding5, GDIBuilding6, GDIBuilding7, GDIBuilding8, GDIBuilding9 } InfantryAttackGroup = { } @@ -19,39 +20,33 @@ VehicleProductionCooldown = DateTime.Minutes(4) VehicleProductionTypes = { "jeep", "jeep", "mtnk", "mtnk", "mtnk" } StartingCash = 4000 -BaseProc = { type = "proc", pos = CPos.New(49, 36), cost = 1500, exists = true } -BaseNuke1 = { type = "nuke", pos = CPos.New(52, 36), cost = 500, exists = true } -BaseNuke2 = { type = "nuke", pos = CPos.New(54, 36), cost = 500, exists = true } -BaseNuke3 = { type = "nuke", pos = CPos.New(56, 36), cost = 500, exists = true } -InfantryProduction = { type = "pyle", pos = CPos.New(52, 39), cost = 500, exists = true } -VehicleProduction = { type = "weap", pos = CPos.New(55, 39), cost = 2000, exists = true } +BaseProc = { type = "proc", pos = CPos.New(49, 36), cost = 1500 } +BaseNuke1 = { type = "nuke", pos = CPos.New(52, 36), cost = 500 } +BaseNuke2 = { type = "nuke", pos = CPos.New(54, 36), cost = 500 } +BaseNuke3 = { type = "nuke", pos = CPos.New(56, 36), cost = 500 } +InfantryProduction = { type = "pyle", pos = CPos.New(52, 39), cost = 500 } +VehicleProduction = { type = "weap", pos = CPos.New(55, 39), cost = 2000 } BaseBuildings = { BaseProc, BaseNuke1, BaseNuke2, BaseNuke3, InfantryProduction, VehicleProduction } -BuildBase = function(cyard) - Utils.Do(BaseBuildings, function(building) - if not building.exists and not cyardIsBuilding then - BuildBuilding(building, cyard) - return - end - end) - Trigger.AfterDelay(DateTime.Seconds(10), function() BuildBase(cyard) end) -end - BuildBuilding = function(building, cyard) - cyardIsBuilding = true + if CyardIsBuilding or GDI.Cash < building.cost then + Trigger.AfterDelay(DateTime.Seconds(10), function() BuildBuilding(building, cyard) end) + return + end + CyardIsBuilding = true + + GDI.Cash = GDI.Cash - building.cost Trigger.AfterDelay(Actor.BuildTime(building.type), function() - cyardIsBuilding = false + CyardIsBuilding = false - if cyard.IsDead or cyard.Owner ~= enemy then + if cyard.IsDead or cyard.Owner ~= GDI then + GDI.Cash = GDI.Cash + building.cost return end - local actor = Actor.Create(building.type, true, { Owner = enemy, Location = building.pos }) - enemy.Cash = enemy.Cash - building.cost - - building.exists = true + local actor = Actor.Create(building.type, true, { Owner = GDI, Location = building.pos }) if actor.Type == 'pyle' or actor.Type == 'hand' then Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceInfantry(actor) end) @@ -59,37 +54,19 @@ BuildBuilding = function(building, cyard) Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceVehicle(actor) end) end - Trigger.OnKilled(actor, function() building.exists = false end) - - Trigger.OnDamaged(actor, function(building) - if building.Owner == enemy and building.Health < building.MaxHealth * 3/4 then - building.StartBuildingRepairs() - end + Trigger.OnKilled(actor, function() + BuildBuilding(building, cyard) end) - Trigger.AfterDelay(DateTime.Seconds(10), function() BuildBase(cyard) end) + RepairBuilding(GDI, actor, 0.75) end) end CheckForHarvester = function() - local harv = enemy.GetActorsByType("harv") + local harv = GDI.GetActorsByType("harv") return #harv > 0 end -IdleHunt = function(unit) - if not unit.IsDead then - Trigger.OnIdle(unit, unit.Hunt) - end -end - -IdlingUnits = function(enemy) - local lazyUnits = enemy.GetGroundAttackers() - - Utils.Do(lazyUnits, function(unit) - IdleHunt(unit) - end) -end - ProduceHarvester = function(building) if not buildingHarvester then buildingHarvester = true @@ -100,10 +77,11 @@ ProduceHarvester = function(building) end ProduceInfantry = function(building) - if building.IsDead or building.Owner ~= enemy then + if building.IsDead or building.Owner ~= GDI then return elseif not CheckForHarvester() then Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceInfantry(building) end) + return end local delay = Utils.RandomInteger(DateTime.Seconds(3), DateTime.Seconds(9)) @@ -113,22 +91,23 @@ ProduceInfantry = function(building) InfantryAttackGroup[#InfantryAttackGroup + 1] = unit[1] if #InfantryAttackGroup >= InfantryGroupSize then - SendUnits(InfantryAttackGroup, Path) + MoveAndHunt(InfantryAttackGroup, Path) InfantryAttackGroup = { } Trigger.AfterDelay(InfantryProductionCooldown, function() ProduceInfantry(building) end) else Trigger.AfterDelay(delay, function() ProduceInfantry(building) end) end end) - + end ProduceVehicle = function(building) - if building.IsDead or building.Owner ~= enemy then + if building.IsDead or building.Owner ~= GDI then return elseif not CheckForHarvester() then ProduceHarvester(building) Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceVehicle(building) end) + return end local delay = Utils.RandomInteger(DateTime.Seconds(12), DateTime.Seconds(17)) @@ -138,7 +117,7 @@ ProduceVehicle = function(building) VehicleAttackGroup[#VehicleAttackGroup + 1] = unit[1] if #VehicleAttackGroup >= VehicleGroupSize then - SendUnits(VehicleAttackGroup, Path) + MoveAndHunt(VehicleAttackGroup, Path) VehicleAttackGroup = { } Trigger.AfterDelay(VehicleProductionCooldown, function() ProduceVehicle(building) end) else @@ -147,55 +126,39 @@ ProduceVehicle = function(building) end) end -SendUnits = function(units, waypoints) - Utils.Do(units, function(unit) - if not unit.IsDead then - Utils.Do(waypoints, function(waypoint) - unit.AttackMove(waypoint.Location) - end) - IdleHunt(unit) - end - end) -end +StartAI = function() + RepairNamedActors(GDI, 0.75) -StartAI = function(cyard) - Utils.Do(Map.NamedActors, function(actor) - if actor.Owner == enemy and actor.HasProperty("StartBuildingRepairs") then - Trigger.OnDamaged(actor, function(building) - if building.Owner == enemy and building.Health < 3/4 * building.MaxHealth then - building.StartBuildingRepairs() - end - end) - end - end) - enemy.Cash = StartingCash - BuildBase(cyard) + GDI.Cash = StartingCash + + Trigger.AfterDelay(DateTime.Minutes(2), function() ProduceInfantry(GDIPyle) end) + Trigger.AfterDelay(DateTime.Minutes(3), function() ProduceVehicle(GDIWeap) end) end Trigger.OnAllKilledOrCaptured(GDIBase, function() - IdlingUnits(enemy) + Utils.Do(GDI.GetGroundAttackers(), IdleHunt) end) Trigger.OnKilled(GDIProc, function(building) - BaseProc.exists = false + BuildBuilding(BaseProc, GDICYard) end) Trigger.OnKilled(GDINuke1, function(building) - BaseNuke1.exists = false + BuildBuilding(BaseNuke1, GDICYard) end) Trigger.OnKilled(GDINuke2, function(building) - BaseNuke2.exists = false + BuildBuilding(BaseNuke2, GDICYard) end) Trigger.OnKilled(GDINuke3, function(building) - BaseNuke3.exists = false + BuildBuilding(BaseNuke3, GDICYard) end) Trigger.OnKilled(GDIPyle, function(building) - InfantryProduction.exists = false + BuildBuilding(InfantryProduction, GDICYard) end) Trigger.OnKilled(GDIWeap, function(building) - VehicleProduction.exists = false + BuildBuilding(VehicleProduction, GDICYard) end) diff --git a/mods/cnc/maps/nod07b/nod07b.lua b/mods/cnc/maps/nod07b/nod07b.lua index c0852eef86..9a6784cb0e 100644 --- a/mods/cnc/maps/nod07b/nod07b.lua +++ b/mods/cnc/maps/nod07b/nod07b.lua @@ -6,36 +6,37 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + WaypointGroup1 = { waypoint0, waypoint15 } WaypointGroup2 = { waypoint0, waypoint1, waypoint2, waypoint3, waypoint4, waypoint5, waypoint8 } WaypointGroup3 = { waypoint0, waypoint1, waypoint2, waypoint3, waypoint9, waypoint10, waypoint11, waypoint6, waypoint7 } WaypointGroup4 = { waypoint9, waypoint10, waypoint11, waypoint6, waypoint7, waypoint14 } -GDI1 = { units = { ['e2'] = 2, ['e6'] = 1 }, waypoints = WaypointGroup4, delay = 40 } -GDI2 = { units = { ['e1'] = 1, ['e2'] = 1}, waypoints = WaypointGroup3, delay = 40 } -GDI3 = { units = { ['e2'] = 1, ['e3'] = 1, ['jeep'] = 1 }, waypoints = WaypointGroup2, delay = 40 } -GDI4 = { units = { ['mtnk'] = 1 }, waypoints = WaypointGroup3, delay = 40 } -GDI5 = { units = { ['e1'] = 1, ['e2'] = 2 }, waypoints = WaypointGroup2, delay = 40 } -GDI6 = { units = { ['e2'] = 2, ['e2'] = 3 }, waypoints = WaypointGroup1, delay = 40 } -Auto1 = { units = { ['e1'] = 3, ['e2'] = 2 }, waypoints = WaypointGroup3, delay = 40 } -Auto2 = { units = { ['e1'] = 1, ['e2'] = 2 }, waypoints = WaypointGroup2, delay = 40 } -Auto3 = { units = { ['e1'] = 1, ['e3'] = 2 }, waypoints = WaypointGroup2, delay = 40 } -Auto4 = { units = { ['e2'] = 2, ['e3'] = 2 }, waypoints = WaypointGroup3, delay = 40 } -Auto5 = { units = { ['jeep'] = 1 }, waypoints = WaypointGroup2, delay = 50 } -Auto6 = { units = { ['jeep'] = 1 }, waypoints = WaypointGroup3, delay = 40 } -Auto7 = { units = { ['mtnk'] = 1 }, waypoints = WaypointGroup2, delay = 50 } -Auto8 = { units = { ['mtnk'] = 1 }, waypoints = WaypointGroup3, delay = 30 } +GDI1 = { units = { "e2", "e2", "e6" }, waypoints = WaypointGroup4, delay = 40 } +GDI2 = { units = { "e1", "e2" }, waypoints = WaypointGroup3, delay = 40 } +GDI3 = { units = { "e2", "e3", "jeep" }, waypoints = WaypointGroup2, delay = 40 } +GDI4 = { units = { "mtnk" }, waypoints = WaypointGroup3, delay = 40 } +GDI5 = { units = { "e1", "e2" }, waypoints = WaypointGroup2, delay = 40 } +GDI6 = { units = { "e2", "e2", "e2", "e2", "e2" }, waypoints = WaypointGroup1, delay = 40 } +Auto1 = { units = { "e1", "e1", "e1", "e2", "e2" }, waypoints = WaypointGroup3, delay = 40 } +Auto2 = { units = { "e1", "e2", "e2" }, waypoints = WaypointGroup2, delay = 40 } +Auto3 = { units = { "e1", "e3", "e3" }, waypoints = WaypointGroup2, delay = 40 } +Auto4 = { units = { "e2", "e2", "e3", "e3" }, waypoints = WaypointGroup3, delay = 40 } +Auto5 = { units = { "jeep" }, waypoints = WaypointGroup2, delay = 50 } +Auto6 = { units = { "jeep" }, waypoints = WaypointGroup3, delay = 40 } +Auto7 = { units = { "mtnk" }, waypoints = WaypointGroup2, delay = 50 } +Auto8 = { units = { "mtnk" }, waypoints = WaypointGroup3, delay = 30 } AirstrikeDelay = DateTime.Minutes(2) + DateTime.Seconds(10) AutoAttackWaves = { Auto1, Auto2, Auto3, Auto4, Auto5, Auto6, Auto7, Auto8 } -WhitelistedStructures = { 'afld', 'hand', 'hq', 'nuke', 'silo', 'proc', 'sam' } +WhitelistedStructures = { "afld", "hand", "hq", "nuke", "silo", "proc", "sam" } -NodUnitsTanks = { 'ltnk', 'ltnk', 'ltnk' } -NodUnitsBikes = { 'bike', 'bike', 'bike' } -NodUnitsBuggys = { 'bggy', 'bggy', 'bggy' } -NodUnitsRockets = { 'e3', 'e3', 'e3' } -NodUnitsGunners = { 'e1', 'e1', 'e1' } +NodUnitsTanks = { "ltnk", "ltnk", "ltnk" } +NodUnitsBikes = { "bike", "bike", "bike" } +NodUnitsBuggys = { "bggy", "bggy", "bggy" } +NodUnitsRockets = { "e3", "e3", "e3" } +NodUnitsGunners = { "e1", "e1", "e1" } Atk1 = { CPos.New(11, 43), CPos.New(10, 43), CPos.New(9, 43), CPos.New(8, 43), CPos.New(7, 43), CPos.New(6, 43), CPos.New(5, 43), CPos.New(11, 42), CPos.New(10, 42), CPos.New(9, 42), CPos.New(8, 42), CPos.New(7, 42), CPos.New(6, 42), CPos.New(5, 42), CPos.New(23, 38), CPos.New(22, 38), CPos.New(21, 38), CPos.New(20, 38), CPos.New(19, 38), CPos.New(24, 37), CPos.New(23, 37), CPos.New(22, 37), CPos.New(21, 37), CPos.New(20, 37), CPos.New(19, 37) } Atk2 = { CPos.New(16, 52), CPos.New(15, 52), CPos.New(14, 52), CPos.New(13, 52), CPos.New(12, 52), CPos.New(11, 52), CPos.New(10, 52), CPos.New(9, 52), CPos.New(8, 52), CPos.New(16, 51), CPos.New(15, 51), CPos.New(14, 51), CPos.New(13, 51), CPos.New(12, 51), CPos.New(11, 51), CPos.New(10, 51), CPos.New(9, 51), CPos.New(8, 51), CPos.New(31, 44), CPos.New(30, 44), CPos.New(29, 44), CPos.New(28, 44), CPos.New(27, 44), CPos.New(26, 44), CPos.New(25, 44), CPos.New(24, 44), CPos.New(23, 44), CPos.New(22, 44), CPos.New(21, 44), CPos.New(31, 43), CPos.New(30, 43), CPos.New(29, 43), CPos.New(28, 43), CPos.New(27, 43), CPos.New(26, 43), CPos.New(25, 43), CPos.New(24, 43), CPos.New(23, 43), CPos.New(22, 43), CPos.New(21, 43) } @@ -44,97 +45,42 @@ Atk4 = { CPos.New(54, 47), CPos.New(53, 47), CPos.New(52, 47), CPos.New(51, 47), CaptureStructures = function(actor) for i = 1, #WhitelistedStructures do - structures = player.GetActorsByType(WhitelistedStructures[i]) - if #structures > 0 then - if not actor.IsDead and not structures[1].IsDead then - actor.Capture(structures[1]) - return - end + structures = Nod.GetActorsByType(WhitelistedStructures[i]) + if #structures > 0 and not actor.IsDead and not structures[1].IsDead then + actor.Capture(structures[1]) + return end end end CheckForSams = function() - local sams = player.GetActorsByType("sam") + local sams = Nod.GetActorsByType("sam") return #sams >= 3 end -searches = 0 -getAirstrikeTarget = function() - local list = player.GetGroundAttackers() - - if #list == 0 then - return - end - - local target = list[DateTime.GameTime % #list + 1].CenterPosition - - local sams = Map.ActorsInCircle(target, WDist.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 - -GetCargo = function(team) - cargo = { } - for type, count in pairs(team.units) do - for i = 1, count, 1 do - cargo[#cargo + 1] = type - end - end - return cargo -end - InsertNodUnits = function() - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.Reinforce(player, NodUnitsBikes, { ReinforcementsSpawnLeft.Location, ReinforcementsBikesRally.Location }, 1) - Reinforcements.Reinforce(player, NodUnitsBuggys, { ReinforcementsSpawnRight.Location, ReinforcementsBuggyRally.Location }, 50) - Reinforcements.Reinforce(player, NodUnitsGunners, { ReinforcementsSpawnLeft.Location, ReinforcementsGunnersRally.Location }, 50) - Reinforcements.Reinforce(player, NodUnitsRockets, { ReinforcementsSpawnRight.Location, ReinforcementsRocketsRally.Location }, 50) + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.Reinforce(Nod, NodUnitsBikes, { ReinforcementsSpawnLeft.Location, ReinforcementsBikesRally.Location }, 1) + Reinforcements.Reinforce(Nod, NodUnitsBuggys, { ReinforcementsSpawnRight.Location, ReinforcementsBuggyRally.Location }, 50) + Reinforcements.Reinforce(Nod, NodUnitsGunners, { ReinforcementsSpawnLeft.Location, ReinforcementsGunnersRally.Location }, 50) + Reinforcements.Reinforce(Nod, NodUnitsRockets, { ReinforcementsSpawnRight.Location, ReinforcementsRocketsRally.Location }, 50) + Trigger.AfterDelay(DateTime.Seconds(6), function() - Reinforcements.Reinforce(player, { 'mcv' }, { ReinforcementsSpawnCenter.Location, ReinforcementsMCVRally.Location }) - Reinforcements.Reinforce(player, NodUnitsTanks, { ReinforcementsSpawnCenter.Location, ReinforcementsTanksRally.Location }, 50) + Reinforcements.Reinforce(Nod, { "mcv" }, { ReinforcementsSpawnCenter.Location, ReinforcementsMCVRally.Location }) + Reinforcements.Reinforce(Nod, NodUnitsTanks, { ReinforcementsSpawnCenter.Location, ReinforcementsTanksRally.Location }, 50) end) end SendAttackWave = function(team) - for type, amount in pairs(team.units) do - count = 0 - actors = enemy.GetActorsByType(type) - Utils.Do(actors, function(actor) - if actor.IsIdle and count < amount then - SetAttackWaypoints(actor, team.waypoints) - if actor.Type == "e6" then - CaptureStructures(actor) - else - IdleHunt(actor) - end - count = count + 1 - end - end) - end -end - -SetAttackWaypoints = function(actor, waypoints) - if not actor.IsDead then - Utils.Do(waypoints, function(waypoint) - actor.AttackMove(waypoint.Location) - end) - end + Utils.Do(team.units, function(unitType) + local actors = Utils.Where(GDI.GetActorsByType(unitType), function(unit) return unit.IsIdle end) + MoveAndHunt(Utils.Take(1, actors), team.waypoints) + end) end SendGDIAirstrike = function(hq, delay) - if not hq.IsDead and hq.Owner == enemy then - local target = getAirstrikeTarget() + if not hq.IsDead and hq.Owner == GDI then + local target = GetAirstrikeTarget(Nod) if target then hq.SendAirstrike(target, false, Facing.NorthEast + 4) @@ -154,17 +100,18 @@ SendWaves = function(counter, Waves) end SendReinforcementsWave = function(team) - Reinforcements.ReinforceWithTransport(enemy, "apc", GetCargo(team), { ReinforcementsGDISpawn.Location, waypoint12.Location}, nil, function(transport, passengers) - SetReinforcementsWaypoints(transport, team.waypoints) + Reinforcements.ReinforceWithTransport(GDI, "apc", GetCargo(team), { ReinforcementsGDISpawn.Location, waypoint12.Location}, nil, function(transport, passengers) + MoveAndHunt(transport, team.waypoints) transport.UnloadPassengers() Trigger.OnPassengerExited(transport, function(_, passenger) Utils.Do(passengers, function(actor) - if actor.Type == "e6" then + if actor.Type == "e6" then CaptureStructures(actor) else IdleHunt(actor) end end) + if not transport.HasPassengers then IdleHunt(transport) end @@ -172,102 +119,69 @@ SendReinforcementsWave = function(team) end) end -SetReinforcementsWaypoints = function(actor, waypoints) - if not actor.IsDead then - Utils.Do(waypoints, function(waypoint) - actor.Move(waypoint.Location) - end) - IdleHunt(actor) - end -end - -StartWaves = function() - SendWaves(1, AutoAttackWaves) -end - - - Trigger.OnEnteredFootprint(Atk1, function(a, id) - if not atk1Trigger and a.Owner == player then + if not atk1Trigger and a.Owner == Nod then atk1Trigger = true SendAttackWave(GDI5) + Trigger.RemoveFootprintTrigger(id) end end) Trigger.OnEnteredFootprint(Atk2, function(a, id) - if not atk2Trigger and a.Owner == player then + if not atk2Trigger and a.Owner == Nod then atk2Trigger = true SendAttackWave(GDI4) + Trigger.RemoveFootprintTrigger(id) end end) Trigger.OnEnteredFootprint(Atk3, function(a, id) - if not atk3Trigger and a.Owner == player then + if not atk3Trigger and a.Owner == Nod then atk3Trigger = true SendAttackWave(GDI6) + Trigger.RemoveFootprintTrigger(id) end end) Trigger.OnEnteredFootprint(Atk4, function(a, id) - if not atk4Trigger and a.Owner == player then + if not atk4Trigger and a.Owner == Nod then atk4Trigger = true SendReinforcementsWave(GDI1) + Trigger.RemoveFootprintTrigger(id) end end) WorldLoaded = function() - player = Player.GetPlayer("Nod") - enemy = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") Camera.Position = waypoint26.CenterPosition InsertNodUnits() - StartAI(GDICYard) + StartAI() Trigger.AfterDelay(DateTime.Seconds(10), function() SendAttackWave(GDI2) end) Trigger.AfterDelay(DateTime.Seconds(55), function() SendAttackWave(GDI2) end) Trigger.AfterDelay(DateTime.Seconds(85), function() SendAttackWave(GDI3) end) Trigger.AfterDelay(AirstrikeDelay, function() SendGDIAirstrike(GDIHQ, AirstrikeDelay) end) - Trigger.AfterDelay(DateTime.Minutes(2), function() ProduceInfantry(GDIPyle) end) - Trigger.AfterDelay(DateTime.Minutes(3), function() ProduceVehicle(GDIWeap) end) + Trigger.OnPlayerDiscovered(GDI, function() SendWaves(1, AutoAttackWaves) end) - Trigger.OnPlayerDiscovered(player, StartWaves) + InitObjectives(Nod) - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) - - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) - - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) - - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - NodObjective1 = player.AddPrimaryObjective("Eliminate all GDI forces in the area.") - NodObjective2 = player.AddSecondaryObjective("Build 3 SAMs to fend off the GDI bombers.") - GDIObjective = enemy.AddPrimaryObjective("Eliminate all Nod forces in the area.") + EliminateGDI = Nod.AddObjective("Eliminate all GDI forces in the area.") + BuildSAMs = Nod.AddObjective("Build 3 SAMs to fend off the GDI bombers.", "Secondary", false) end Tick = function() - if DateTime.GameTime > 2 and player.HasNoRequiredUnits() then - enemy.MarkCompletedObjective(GDIObjective) + if DateTime.GameTime > 2 and Nod.HasNoRequiredUnits() then + Nod.MarkFailedObjective(EliminateGDI) end - if DateTime.GameTime > 2 and enemy.HasNoRequiredUnits() then - player.MarkCompletedObjective(NodObjective1) + if DateTime.GameTime > 2 and GDI.HasNoRequiredUnits() then + Nod.MarkCompletedObjective(EliminateGDI) end - if not player.IsObjectiveCompleted(NodObjective2) and CheckForSams() then - player.MarkCompletedObjective(NodObjective2) + if not Nod.IsObjectiveCompleted(BuildSAMs) and CheckForSams() then + Nod.MarkCompletedObjective(BuildSAMs) end end diff --git a/mods/cnc/maps/nod07b/rules.yaml b/mods/cnc/maps/nod07b/rules.yaml index 2f789abcd6..f570cf4374 100644 --- a/mods/cnc/maps/nod07b/rules.yaml +++ b/mods/cnc/maps/nod07b/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: nod07b.lua, nod07b-AI.lua + Scripts: campaign-global.lua, nod07b.lua, nod07b-AI.lua MusicPlaylist: StartingMusic: justdoit VictoryMusic: nod_win1 diff --git a/mods/cnc/maps/nod07c/map.yaml b/mods/cnc/maps/nod07c/map.yaml index b916633271..42e4cc5ad4 100644 --- a/mods/cnc/maps/nod07c/map.yaml +++ b/mods/cnc/maps/nod07c/map.yaml @@ -727,13 +727,13 @@ Actors: Location: 48,54 Owner: GDI ScriptTags: GDIBuilding - GDIBuilding9: gtwr + GuardTower1: gtwr Location: 36,51 Owner: GDI - GDIBuilding10: gtwr + GuardTower2: gtwr Location: 36,57 Owner: GDI - GDIBuilding11: gtwr + GuardTower3: gtwr Location: 55,48 Owner: GDI GDIHpad: hpad.in diff --git a/mods/cnc/maps/nod07c/nod07c.lua b/mods/cnc/maps/nod07c/nod07c.lua index 7016290006..cf50b1d3de 100644 --- a/mods/cnc/maps/nod07c/nod07c.lua +++ b/mods/cnc/maps/nod07c/nod07c.lua @@ -6,85 +6,68 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] -NodUnitsVehicles1 = { 'bggy', 'bggy', 'bike', 'bike' } -NodUnitsVehicles2 = { 'ltnk', 'ltnk' } -NodUnitsEngineers = { 'e6', 'e6', 'e6', 'e6' } -NodUnitsRockets = { 'e3', 'e3', 'e3', 'e3' } -NodUnitsGunners = { 'e1', 'e1', 'e1', 'e1' } -NodUnitsFlamers = { 'e4', 'e4', 'e4', 'e4' } -GDI1 = { units = { ['e1'] = 2 }, waypoints = { waypoint0.Location, waypoint1.Location, waypoint2.Location, waypoint8.Location, waypoint2.Location, waypoint9.Location, waypoint2.Location } } -GDI2 = { units = { ['e1'] = 10, ['e2'] = 8, ['mtnk'] = 1, ['jeep'] = 1 }, waypoints = { waypoint12.Location, waypoint15.Location, waypoint0.Location } } -GDI3 = { units = { ['jeep'] = 1 }, waypoints = { waypoint0.Location, waypoint1.Location, waypoint3.Location, waypoint4.Location, waypoint3.Location, waypoint2.Location, waypoint5.Location, waypoint6.Location, waypoint2.Location, waypoint7.Location } } -MTANK = { units = { ['mtnk'] = 1 }, waypoints = { waypoint14.Location, waypoint5.Location } } +NodUnitsVehicles1 = { "bggy", "bggy", "bike", "bike" } +NodUnitsVehicles2 = { "ltnk", "ltnk" } +NodUnitsEngineers = { "e6", "e6", "e6", "e6" } +NodUnitsRockets = { "e3", "e3", "e3", "e3" } +NodUnitsGunners = { "e1", "e1", "e1", "e1" } +NodUnitsFlamers = { "e4", "e4", "e4", "e4" } -targetsKilled = 0 +GDI1 = { units = { "e1", "e1" }, waypoints = { waypoint0.Location, waypoint1.Location, waypoint2.Location, waypoint8.Location, waypoint2.Location, waypoint9.Location, waypoint2.Location } } +GDI2 = { units = { "e1", "e1", "e1", "e1", "e1", "e1", "e1", "e1", "e1", "e1", "e2", "e2", "e2", "e2", "e2", "e2", "e2", "e2", "mtnk", "jeep" }, waypoints = { waypoint12.Location, waypoint15.Location, waypoint0.Location } } +GDI3 = { units = { "jeep" }, waypoints = { waypoint0.Location, waypoint1.Location, waypoint3.Location, waypoint4.Location, waypoint3.Location, waypoint2.Location, waypoint5.Location, waypoint6.Location, waypoint2.Location, waypoint7.Location } } +MTANK = { units = { "mtnk" }, waypoints = { waypoint14.Location, waypoint5.Location } } + +TargetsKilled = 0 AutoGuard = function(guards) Utils.Do(guards, function(guard) - Trigger.OnDamaged(guard, function(guard, attacker) + Trigger.OnDamaged(guard, function() if not guard.IsDead then - guard.Hunt() + IdleHunt(guard) end end) end) end InsertNodUnits = function() - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.Reinforce(player, { 'ltnk' }, { ReinforcementsTopSpawn.Location, ReinforcementsTankRally.Location }, 1) - local Engineers = Reinforcements.Reinforce(player, NodUnitsEngineers, { ReinforcementsTopSpawn.Location, ReinforcementsEngineersRally.Location }, 10) - Reinforcements.Reinforce(player, NodUnitsRockets, { ReinforcementsBottomSpawn.Location, ReinforcementsRocketsRally.Location }, 10) + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.Reinforce(Nod, { "ltnk" }, { ReinforcementsTopSpawn.Location, ReinforcementsTankRally.Location }, 1) + + local engineers = Reinforcements.Reinforce(Nod, NodUnitsEngineers, { ReinforcementsTopSpawn.Location, ReinforcementsEngineersRally.Location }, 10) + Reinforcements.Reinforce(Nod, NodUnitsRockets, { ReinforcementsBottomSpawn.Location, ReinforcementsRocketsRally.Location }, 10) + Trigger.AfterDelay(DateTime.Seconds(3), function() - Reinforcements.Reinforce(player, NodUnitsGunners, { ReinforcementsBottomSpawn.Location, ReinforcementsGunnersRally.Location }, 10) - Reinforcements.Reinforce(player, NodUnitsFlamers, { ReinforcementsTopSpawn.Location, ReinforcementsFlamersRally.Location }, 10) + Reinforcements.Reinforce(Nod, NodUnitsGunners, { ReinforcementsBottomSpawn.Location, ReinforcementsGunnersRally.Location }, 10) + Reinforcements.Reinforce(Nod, NodUnitsFlamers, { ReinforcementsTopSpawn.Location, ReinforcementsFlamersRally.Location }, 10) end) + Trigger.AfterDelay(DateTime.Seconds(5), function() - local unitsA = Reinforcements.ReinforceWithTransport(player, 'tran.in', NodUnitsVehicles1, { GunboatRight.Location, ReinforcementsHelicopter1Rally.Location }, { GunboatRight.Location })[2] + Reinforcements.ReinforceWithTransport(Nod, "tran.in", NodUnitsVehicles1, { GunboatRight.Location, ReinforcementsHelicopter1Rally.Location }, { GunboatRight.Location }) Trigger.AfterDelay(DateTime.Seconds(3), function() - local unitsB = Reinforcements.ReinforceWithTransport(player, 'tran.in', NodUnitsVehicles2, { GunboatRight.Location, ReinforcementsHelicopter2Rally.Location }, { GunboatRight.Location })[2] - - Utils.Do(unitsB, function(unit) - unitsA[#unitsA + 1] = unit - end) - - Trigger.OnAllKilled(unitsA, function() - if not defendersActive then - defendersActive = true - player.MarkFailedObjective(NodObjective4) - end - end) + Reinforcements.ReinforceWithTransport(Nod, "tran.in", NodUnitsVehicles2, { GunboatRight.Location, ReinforcementsHelicopter2Rally.Location }, { GunboatRight.Location }) end) end) - Trigger.OnAllRemovedFromWorld(Engineers, function() - if not player.IsObjectiveCompleted(NodObjective1) then - player.MarkFailedObjective(NodObjective1) + Trigger.OnAllRemovedFromWorld(engineers, function() + if not Nod.IsObjectiveCompleted(CaptureHelipad) then + Nod.MarkFailedObjective(CaptureHelipad) end end) end -DiscoveredSideEntrance = function(_,discoverer) - if not defendersActive then - defendersActive = true - player.MarkFailedObjective(NodObjective4) +DiscoveredMainEntrance = function() + if Nod.IsObjectiveCompleted(DistractGuardsObjective) then + return end -end -DiscoveredMainEntrance = function(_,discoverer) - if not defendersActive then - SendDefenders(GDI2) - end -end - -SendDefenders = function(team) - defendersActive = true - player.MarkCompletedObjective(NodObjective4) + Nod.MarkCompletedObjective(DistractGuardsObjective) Trigger.AfterDelay(DateTime.Seconds(3), function() - for type, amount in pairs(team.units) do - local actors = Utils.Take(amount, enemy.GetActorsByType(type)) + for type, amount in pairs(GDI2.units) do + local actors = Utils.Take(amount, GDI.GetActorsByType(type)) Utils.Do(actors, function(actor) if actor.IsIdle then actor.AttackMove(waypoint0.Location) @@ -94,109 +77,82 @@ SendDefenders = function(team) end) end -SendGuards = function(team) - for type, amount in pairs(team.units) do - local actors = Utils.Take(amount, enemy.GetActorsByType(type)) - Utils.Do(actors, function(actor) - if actor.IsIdle then - actor.Patrol(team.waypoints, true, DateTime.Seconds(25)) - end - end) - end -end - Trigger.OnKilled(GDIHpad, function() - if not player.IsObjectiveCompleted(NodObjective1) then - player.MarkFailedObjective(NodObjective1) + if not Nod.IsObjectiveCompleted(CaptureHelipad) then + Nod.MarkFailedObjective(CaptureHelipad) end end) Trigger.OnKilled(GDIOrca, function() - if not player.IsObjectiveCompleted(NodObjective3) then - player.MarkFailedObjective(NodObjective3) + if not Nod.IsObjectiveCompleted(UseOrcaObjective) then + Nod.MarkFailedObjective(UseOrcaObjective) end end) -Trigger.OnDamaged(GDIBuilding11, function() +Trigger.OnDamaged(GuardTower3, function() SendGuards(MTANK) end) Utils.Do(Map.ActorsWithTag("Village"), function(actor) Trigger.OnKilled(actor, function() - targetsKilled = targetsKilled + 1 + TargetsKilled = TargetsKilled + 1 end) end) Utils.Do(Map.ActorsWithTag("GDIBuilding"), function(actor) Trigger.OnKilledOrCaptured(actor, function() - player.MarkFailedObjective(NodObjective2) + Nod.MarkFailedObjective(NoCaptureObjective) end) end) Trigger.OnCapture(GDIHpad, function() - hpadCaptured = true - player.MarkCompletedObjective(NodObjective1) + Nod.MarkCompletedObjective(CaptureHelipad) if not GDIOrca.IsDead then - GDIOrca.Owner = player + GDIOrca.Owner = Nod end - Actor.Create("camera", true, { Owner = player, Location = waypoint25.Location }) - Actor.Create("flare", true, { Owner = player, Location = waypoint25.Location }) + + Actor.Create("camera", true, { Owner = Nod, Location = waypoint25.Location }) + Actor.Create("flare", true, { Owner = Nod, Location = waypoint25.Location }) end) WorldLoaded = function() - player = Player.GetPlayer("Nod") - enemy = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") Camera.Position = waypoint26.CenterPosition InsertNodUnits() - SendGuards(GDI1) - SendGuards(GDI3) - AutoGuard(enemy.GetGroundAttackers()) + AutoGuard(GDI.GetGroundAttackers()) - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") + InitObjectives(Nod) + + Trigger.OnDiscovered(GuardTower1, DiscoveredMainEntrance) + Trigger.OnDiscovered(GuardTower2, DiscoveredMainEntrance) + Trigger.OnDiscovered(GuardTower3, function() + if not Nod.IsObjectiveCompleted(DistractGuardsObjective) then + Nod.MarkFailedObjective(DistractGuardsObjective) + end end) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) - - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) - - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - Trigger.OnDiscovered(GDIBuilding9, DiscoveredMainEntrance) - Trigger.OnDiscovered(GDIBuilding10, DiscoveredMainEntrance) - Trigger.OnDiscovered(GDIBuilding11, DiscoveredSideEntrance) - - NodObjective1 = player.AddPrimaryObjective("Capture the GDI helipad.") - NodObjective2 = player.AddPrimaryObjective("Don't capture or destroy any other\nGDI main building.") - NodObjective3 = player.AddPrimaryObjective("Use the GDI orca to wreak havoc at the village.") - NodObjective4 = player.AddSecondaryObjective("Distract the guards by attacking the\nmain entrance with your vehicles.") - GDIObjective = enemy.AddPrimaryObjective("Kill all enemies.") + CaptureHelipad = Nod.AddObjective("Capture the GDI helipad.") + NoCaptureObjective = Nod.AddObjective("Don't capture or destroy any other\nGDI main building.") + UseOrcaObjective = Nod.AddObjective("Use the GDI orca to wreak havoc at the village.") + DistractGuardsObjective = Nod.AddObjective("Distract the guards by attacking the\nmain entrance with your vehicles.", "Secondary", false) + GDIObjective = GDI.AddObjective("Kill all enemies.") end Tick = function() - if DateTime.GameTime > 2 and player.HasNoRequiredUnits() then - enemy.MarkCompletedObjective(GDIObjective) + if DateTime.GameTime > 2 and Nod.HasNoRequiredUnits() then + GDI.MarkCompletedObjective(GDIObjective) end - if targetsKilled >= 15 then - player.MarkCompletedObjective(NodObjective2) - player.MarkCompletedObjective(NodObjective3) + if TargetsKilled >= 15 then + Nod.MarkCompletedObjective(NoCaptureObjective) + Nod.MarkCompletedObjective(UseOrcaObjective) end - if enemy.Resources >= enemy.ResourceCapacity * 0.75 then - enemy.Resources = enemy.ResourceCapacity * 0.25 + if GDI.Resources >= GDI.ResourceCapacity * 0.75 then + GDI.Resources = GDI.ResourceCapacity * 0.25 end end diff --git a/mods/cnc/maps/nod07c/rules.yaml b/mods/cnc/maps/nod07c/rules.yaml index 709e472f39..a40ae1cd93 100644 --- a/mods/cnc/maps/nod07c/rules.yaml +++ b/mods/cnc/maps/nod07c/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: nod07c.lua + Scripts: campaign-global.lua, nod07c.lua MusicPlaylist: StartingMusic: justdoit VictoryMusic: nod_win1 diff --git a/mods/cnc/maps/nod08a/nod08a-AI.lua b/mods/cnc/maps/nod08a/nod08a-AI.lua index e59ccaf724..334c991233 100644 --- a/mods/cnc/maps/nod08a/nod08a-AI.lua +++ b/mods/cnc/maps/nod08a/nod08a-AI.lua @@ -6,6 +6,7 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + AttackPaths = { { AttackPath1 }, { AttackPath2 }, { AttackPath3 } } GDIBase = { GDICYard, GDIPyle, GDIWeap, GDIHQ, GDIProc, GDINuke1, GDINuke2, GDINuke3, GDIBuilding1, GDIBuilding2, GDIBuilding3, GDIBuilding4, GDIBuilding5, GDIBuilding6, GDIBuilding7, GDIBuilding8, GDIBuilding9 } GDIOrcas = { GDIOrca1, GDIOrca2 } @@ -20,48 +21,40 @@ VehicleProductionCooldown = DateTime.Minutes(4) VehicleProductionTypes = { "jeep", "jeep", "mtnk", "mtnk", "mtnk" } StartingCash = 4000 -BaseProc = { type = "proc", pos = CPos.New(50, 16), cost = 1500, exists = true } -BaseNuke1 = { type = "nuke", pos = CPos.New(60, 17), cost = 500, exists = true } -BaseNuke2 = { type = "nuke", pos = CPos.New(59, 19), cost = 500, exists = true } -BaseNuke3 = { type = "nuke", pos = CPos.New(57, 18), cost = 500, exists = true } -BaseNuke4 = { type = "nuke", pos = CPos.New(58, 16), cost = 500, exists = true } -InfantryProduction = { type = "pyle", pos = CPos.New(53, 14), cost = 500, exists = true } -VehicleProduction = { type = "weap", pos = CPos.New(48, 13), cost = 2000, exists = true } +BaseProc = { type = "proc", pos = CPos.New(50, 16), cost = 1500 } +BaseNuke1 = { type = "nuke", pos = CPos.New(60, 17), cost = 500 } +BaseNuke2 = { type = "nuke", pos = CPos.New(59, 19), cost = 500 } +BaseNuke3 = { type = "nuke", pos = CPos.New(57, 18), cost = 500 } +BaseNuke4 = { type = "nuke", pos = CPos.New(58, 16), cost = 500 } +InfantryProduction = { type = "pyle", pos = CPos.New(53, 14), cost = 500 } +VehicleProduction = { type = "weap", pos = CPos.New(48, 13), cost = 2000 } BaseBuildings = { BaseProc, BaseNuke1, BaseNuke2, BaseNuke3, BaseNuke4, InfantryProduction, VehicleProduction } AutoGuard = function(guards) Utils.Do(guards, function(guard) - Trigger.OnDamaged(guard, function(guard) - IdleHunt(guard) - end) + Trigger.OnDamaged(guard, IdleHunt) end) end -BuildBase = function(cyard) - Utils.Do(BaseBuildings, function(building) - if not building.exists and not cyardIsBuilding then - BuildBuilding(building, cyard) - return - end - end) - Trigger.AfterDelay(DateTime.Seconds(10), function() BuildBase(cyard) end) -end - BuildBuilding = function(building, cyard) - cyardIsBuilding = true + if CyardIsBuilding or GDI.Cash < building.cost then + Trigger.AfterDelay(DateTime.Seconds(10), function() BuildBuilding(building, cyard) end) + return + end + CyardIsBuilding = true + + GDI.Cash = GDI.Cash - building.cost Trigger.AfterDelay(Actor.BuildTime(building.type), function() - cyardIsBuilding = false + CyardIsBuilding = false - if cyard.IsDead or cyard.Owner ~= enemy then + if cyard.IsDead or cyard.Owner ~= GDI then + GDI.Cash = GDI.Cash + building.cost return end - local actor = Actor.Create(building.type, true, { Owner = enemy, Location = building.pos }) - enemy.Cash = enemy.Cash - building.cost - - building.exists = true + local actor = Actor.Create(building.type, true, { Owner = GDI, Location = building.pos }) if actor.Type == 'pyle' or actor.Type == 'hand' then Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceInfantry(actor) end) @@ -69,28 +62,25 @@ BuildBuilding = function(building, cyard) Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceVehicle(actor) end) end - Trigger.OnKilled(actor, function() building.exists = false end) - - Trigger.OnDamaged(actor, function(building) - if building.Owner == enemy and building.Health < building.MaxHealth * 3/4 then - building.StartBuildingRepairs() - end + Trigger.OnKilled(actor, function() + BuildBuilding(building, cyard) end) - Trigger.AfterDelay(DateTime.Seconds(10), function() BuildBase(cyard) end) + RepairBuilding(GDI, actor, 0.75) end) end CheckForHarvester = function() - local harv = enemy.GetActorsByType("harv") + local harv = GDI.GetActorsByType("harv") return #harv > 0 end GuardBase = function() Utils.Do(GDIBase, function(building) - Trigger.OnDamaged(building, function(guard) + Trigger.OnDamaged(building, function() Utils.Do(GDIOrcas, function(guard) if not guard.IsDead and not building.IsDead then + guard.Stop() guard.Guard(building) end end) @@ -98,20 +88,6 @@ GuardBase = function() end) end -IdleHunt = function(unit) - if not unit.IsDead then - Trigger.OnIdle(unit, unit.Hunt) - end -end - -IdlingUnits = function(enemy) - local lazyUnits = enemy.GetGroundAttackers() - - Utils.Do(lazyUnits, function(unit) - IdleHunt(unit) - end) -end - ProduceHarvester = function(building) if not buildingHarvester then buildingHarvester = true @@ -122,10 +98,11 @@ ProduceHarvester = function(building) end ProduceInfantry = function(building) - if building.IsDead or building.Owner ~= enemy then + if building.IsDead or building.Owner ~= GDI then return elseif not CheckForHarvester() then Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceInfantry(building) end) + return end local delay = Utils.RandomInteger(DateTime.Seconds(3), DateTime.Seconds(9)) @@ -135,22 +112,23 @@ ProduceInfantry = function(building) InfantryAttackGroup[#InfantryAttackGroup + 1] = unit[1] if #InfantryAttackGroup >= InfantryGroupSize then - SendUnits(InfantryAttackGroup, Path) + MoveAndHunt(InfantryAttackGroup, Path) InfantryAttackGroup = { } Trigger.AfterDelay(InfantryProductionCooldown, function() ProduceInfantry(building) end) else Trigger.AfterDelay(delay, function() ProduceInfantry(building) end) end end) - + end ProduceVehicle = function(building) - if building.IsDead or building.Owner ~= enemy then + if building.IsDead or building.Owner ~= GDI then return elseif not CheckForHarvester() then ProduceHarvester(building) Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceVehicle(building) end) + return end local delay = Utils.RandomInteger(DateTime.Seconds(12), DateTime.Seconds(17)) @@ -160,7 +138,7 @@ ProduceVehicle = function(building) VehicleAttackGroup[#VehicleAttackGroup + 1] = unit[1] if #VehicleAttackGroup >= VehicleGroupSize then - SendUnits(VehicleAttackGroup, Path) + MoveAndHunt(VehicleAttackGroup, Path) VehicleAttackGroup = { } Trigger.AfterDelay(VehicleProductionCooldown, function() ProduceVehicle(building) end) else @@ -169,60 +147,41 @@ ProduceVehicle = function(building) end) end -SendUnits = function(units, waypoints) - Utils.Do(units, function(unit) - if not unit.IsDead then - Utils.Do(waypoints, function(waypoint) - unit.AttackMove(waypoint.Location) - end) - IdleHunt(unit) - end - end) -end +StartAI = function() + RepairNamedActors(GDI, 0.75) -StartAI = function(cyard) - Utils.Do(Map.NamedActors, function(actor) - if actor.Owner == enemy and actor.HasProperty("StartBuildingRepairs") then - Trigger.OnDamaged(actor, function(building) - if building.Owner == enemy and building.Health < 3/4 * building.MaxHealth then - building.StartBuildingRepairs() - end - end) - end - end) - enemy.Cash = StartingCash - BuildBase(cyard) + GDI.Cash = StartingCash GuardBase() end Trigger.OnAllKilledOrCaptured(GDIBase, function() - IdlingUnits(enemy) + Utils.Do(GDI.GetGroundAttackers(), IdleHunt) end) Trigger.OnKilled(GDIProc, function(building) - BaseProc.exists = false + BuildBuilding(BaseProc, GDICYard) end) Trigger.OnKilled(GDINuke1, function(building) - BaseNuke1.exists = false + BuildBuilding(BaseNuke1, GDICYard) end) Trigger.OnKilled(GDINuke2, function(building) - BaseNuke2.exists = false + BuildBuilding(BaseNuke2, GDICYard) end) Trigger.OnKilled(GDINuke3, function(building) - BaseNuke3.exists = false + BuildBuilding(BaseNuke3, GDICYard) end) Trigger.OnKilled(GDINuke4, function(building) - BaseNuke4.exists = false + BuildBuilding(BaseNuke4, GDICYard) end) Trigger.OnKilled(GDIPyle, function(building) - InfantryProduction.exists = false + BuildBuilding(InfantryProduction, GDICYard) end) Trigger.OnKilled(GDIWeap, function(building) - VehicleProduction.exists = false + BuildBuilding(VehicleProduction, GDICYard) end) diff --git a/mods/cnc/maps/nod08a/nod08a.lua b/mods/cnc/maps/nod08a/nod08a.lua index 96c43e9024..5eca4960c1 100644 --- a/mods/cnc/maps/nod08a/nod08a.lua +++ b/mods/cnc/maps/nod08a/nod08a.lua @@ -6,6 +6,7 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + WaypointGroup1 = { waypoint0, waypoint1, waypoint2, waypoint3, waypoint6, waypoint10 } WaypointGroup2 = { waypoint0, waypoint1, waypoint2, waypoint3, waypoint6, waypoint7, waypoint8, waypoint9, waypoint10 } WaypointGroup3 = { waypoint0, waypoint1, waypoint2, waypoint3, waypoint4, waypoint5 } @@ -38,79 +39,36 @@ NodBaseTrigger = { CPos.New(52, 52), CPos.New(52, 53), CPos.New(52, 54), CPos.Ne AirstrikeDelay = DateTime.Minutes(2) + DateTime.Seconds(20) NodBaseCapture = function() - nodBaseTrigger = true - player.MarkCompletedObjective(NodObjective1) + FlareCamera = Actor.Create("camera", true, { Owner = Nod, Location = waypoint25.Location }) + Flare = Actor.Create("flare", true, { Owner = Nod, Location = waypoint25.Location }) + + SendHelicopter() + + Nod.MarkCompletedObjective(LocateNodBase) + Utils.Do(NodBase, function(actor) - actor.Owner = player + actor.Owner = Nod end) + Trigger.AfterDelay(DateTime.Seconds(1), function() - Media.PlaySpeechNotification(player, "NewOptions") + Media.PlaySpeechNotification(Nod, "NewOptions") end) end -searches = 0 -getAirstrikeTarget = function() - local list = player.GetGroundAttackers() - - if #list == 0 then - return - end - - local target = list[DateTime.GameTime % #list + 1].CenterPosition - - local sams = Map.ActorsInCircle(target, WDist.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 - ---Provide the player with a helicopter until the outpost got captured +-- Provide the Nod with a helicopter until the outpost got captured SendHelicopter = function() Trigger.AfterDelay(DateTime.Seconds(5), function() - if not outpostCaptured then - Media.PlaySpeechNotification(player, "Reinforce") - TransportHelicopter = Reinforcements.ReinforceWithTransport(player, 'tran', nil, { ReinforcementsHelicopterSpawn.Location, waypoint15.Location })[1] - Trigger.OnKilled(TransportHelicopter, function() - SendHelicopter() - end) + if not Nod.IsObjectiveCompleted(CaptureGDIOutpost) then + Media.PlaySpeechNotification(Nod, "Reinforce") + TransportHelicopter = Reinforcements.ReinforceWithTransport(Nod, 'tran', nil, { ReinforcementsHelicopterSpawn.Location, waypoint15.Location })[1] + Trigger.OnKilled(TransportHelicopter, SendHelicopter) end end) end -SendAttackWave = function(team) - for type, amount in pairs(team.units) do - count = 0 - actors = enemy.GetActorsByType(type) - Utils.Do(actors, function(actor) - if actor.IsIdle and count < amount then - SetAttackWaypoints(actor, team.waypoints) - IdleHunt(actor) - count = count + 1 - end - end) - end -end - -SetAttackWaypoints = function(actor, waypoints) - if not actor.IsDead then - Utils.Do(waypoints, function(waypoint) - actor.AttackMove(waypoint.Location) - end) - end -end - SendGDIAirstrike = function(hq, delay) - if not hq.IsDead and hq.Owner == enemy then - local target = getAirstrikeTarget() + if not hq.IsDead and hq.Owner == GDI then + local target = GetAirstrikeTarget(Nod) if target then hq.SendAirstrike(target, false, Facing.NorthEast + 4) @@ -124,40 +82,35 @@ end SendWaves = function(counter, Waves) if counter <= #Waves then local team = Waves[counter] - SendAttackWave(team) + + for type, amount in pairs(team.units) do + MoveAndHunt(Utils.Take(amount, GDI.GetActorsByType(type)), team.waypoints) + end + Trigger.AfterDelay(DateTime.Seconds(team.delay), function() SendWaves(counter + 1, Waves) end) end end -StartWaves = function() - SendWaves(1, AutoAttackWaves) -end - Trigger.OnAllKilled(IntroGuards, function() - FlareCamera = Actor.Create("camera", true, { Owner = player, Location = waypoint25.Location }) - Flare = Actor.Create("flare", true, { Owner = player, Location = waypoint25.Location }) - SendHelicopter() - player.MarkCompletedObjective(NodObjective1) - NodBaseCapture() + if not Nod.IsObjectiveCompleted(LocateNodBase) then + NodBaseCapture() + end end) Trigger.OnAllKilledOrCaptured(Outpost, function() - if not outpostCaptured then - outpostCaptured = true + if not Nod.IsObjectiveCompleted(CaptureGDIOutpost) then + Nod.MarkCompletedObjective(CaptureGDIOutpost) Trigger.AfterDelay(DateTime.Minutes(1), function() - if not GDIHQ.IsDead and (not NodHand.IsDead or not NodNuke.IsDead) then - local airstrikeproxy = Actor.Create("airstrike.proxy", false, { Owner = enemy }) + local airstrikeproxy = Actor.Create("airstrike.proxy", false, { Owner = GDI }) airstrikeproxy.SendAirstrike(AirstrikeTarget.CenterPosition, false, Facing.NorthEast + 4) airstrikeproxy.Destroy() end end) Trigger.AfterDelay(DateTime.Seconds(15), function() - Utils.Do(OutpostGuards, function(unit) - IdleHunt(unit) - end) + Utils.Do(OutpostGuards, IdleHunt) end) Trigger.AfterDelay(DateTime.Minutes(1), function() @@ -165,8 +118,7 @@ Trigger.OnAllKilledOrCaptured(Outpost, function() Flare.Destroy() end) - player.MarkCompletedObjective(NodObjective2) - Trigger.AfterDelay(DateTime.Minutes(1), function() StartWaves() end) + Trigger.AfterDelay(DateTime.Minutes(1), function() SendWaves(1, AutoAttackWaves) end) Trigger.AfterDelay(AirstrikeDelay, function() SendGDIAirstrike(GDIHQ, AirstrikeDelay) end) Trigger.AfterDelay(DateTime.Minutes(2), function() ProduceInfantry(GDIPyle) end) Trigger.AfterDelay(DateTime.Minutes(3), function() ProduceVehicle(GDIWeap) end) @@ -175,65 +127,50 @@ end) Trigger.OnCapture(OutpostCYard, function() Trigger.AfterDelay(DateTime.Seconds(4), function() - Media.PlaySpeechNotification(player, "NewOptions") + Media.PlaySpeechNotification(Nod, "NewOptions") end) end) Trigger.OnAnyKilled(Outpost, function() - if not outpostCaptured then - player.MarkFailedObjective(NodObjective2) + if not Nod.IsObjectiveCompleted(CaptureGDIOutpost) then + Nod.MarkFailedObjective(CaptureGDIOutpost) end end) Trigger.OnEnteredFootprint(NodBaseTrigger, function(a, id) - if not nodBaseTrigger and a.Owner == player then + if not Nod.IsObjectiveCompleted(LocateNodBase) and a.Owner == Nod then NodBaseCapture() + Trigger.RemoveFootprintTrigger(id) end end) WorldLoaded = function() - player = Player.GetPlayer("Nod") - enemy = Player.GetPlayer("GDI") - Camera.Position = waypoint26.CenterPosition - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.ReinforceWithTransport(player, 'tran.in', IntroReinforcements, { ReinforcementsHelicopterSpawn.Location, ReinforcementsHelicopterRally.Location }, { ReinforcementsHelicopterSpawn.Location }, nil, nil) + Nod = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") - StartAI(GDICYard) + Camera.Position = waypoint26.CenterPosition + + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.ReinforceWithTransport(Nod, "tran.in", IntroReinforcements, { ReinforcementsHelicopterSpawn.Location, ReinforcementsHelicopterRally.Location }, { ReinforcementsHelicopterSpawn.Location }) + + StartAI() AutoGuard(IntroGuards) AutoGuard(OutpostGuards) - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) + InitObjectives(Nod) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) - - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) - - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - NodObjective1 = player.AddPrimaryObjective("Locate the Nod base.") - NodObjective2 = player.AddPrimaryObjective("Capture the GDI outpost.") - NodObjective3 = player.AddPrimaryObjective("Eliminate all GDI forces in the area.") - GDIObjective = enemy.AddPrimaryObjective("Eliminate all Nod forces in the area.") + LocateNodBase = Nod.AddObjective("Locate the Nod base.") + CaptureGDIOutpost = Nod.AddObjective("Capture the GDI outpost.") + EliminateGDI = Nod.AddObjective("Eliminate all GDI forces in the area.") + GDIObjective = GDI.AddObjective("Eliminate all Nod forces in the area.") end Tick = function() - if DateTime.GameTime > 2 and player.HasNoRequiredUnits() then - enemy.MarkCompletedObjective(GDIObjective) + if DateTime.GameTime > 2 and Nod.HasNoRequiredUnits() then + GDI.MarkCompletedObjective(GDIObjective) end - if DateTime.GameTime > 2 and enemy.HasNoRequiredUnits() then - player.MarkCompletedObjective(NodObjective3) + if DateTime.GameTime > 2 and GDI.HasNoRequiredUnits() then + Nod.MarkCompletedObjective(EliminateGDI) end end diff --git a/mods/cnc/maps/nod08a/rules.yaml b/mods/cnc/maps/nod08a/rules.yaml index 827b44df0e..8e3ab0a143 100644 --- a/mods/cnc/maps/nod08a/rules.yaml +++ b/mods/cnc/maps/nod08a/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: nod08a.lua, nod08a-AI.lua + Scripts: campaign-global.lua, nod08a.lua, nod08a-AI.lua MusicPlaylist: StartingMusic: linefire VictoryMusic: nod_win1 diff --git a/mods/cnc/maps/nod08b/nod08b-AI.lua b/mods/cnc/maps/nod08b/nod08b-AI.lua index cef07af659..797511df86 100644 --- a/mods/cnc/maps/nod08b/nod08b-AI.lua +++ b/mods/cnc/maps/nod08b/nod08b-AI.lua @@ -6,6 +6,7 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + AttackPaths = { { AttackPath1 }, { AttackPath2 }, { AttackPath3 } } GDIBase = { GDICYard, GDIPyle, GDIWeap, GDIHQ, GDINuke1, GDINuke2, GDINuke3, GDINuke4, GDIProc, GDIBuilding1, GDIBuilding2, GDIBuilding3, GDIBuilding4, GDIBuilding5, GDIBuilding6, GDIBuilding7, GDIBuilding8, GDIBuilding9, GDIBuilding10, GDIBuilding11, GDIBuilding12, GDIBuilding13 } GDIOrcas = { GDIOrca1, GDIOrca2 } @@ -20,48 +21,40 @@ VehicleProductionCooldown = DateTime.Minutes(4) VehicleProductionTypes = { "jeep", "jeep", "mtnk", "mtnk", "mtnk" } StartingCash = 4000 -BaseProc = { type = "proc", pos = CPos.New(19, 48), cost = 1500, exists = true } -BaseNuke1 = { type = "nuke", pos = CPos.New(9, 53), cost = 500, exists = true } -BaseNuke2 = { type = "nuke", pos = CPos.New(7, 52), cost = 500, exists = true } -BaseNuke3 = { type = "nuke", pos = CPos.New(11, 53), cost = 500, exists = true } -BaseNuke4 = { type = "nuke", pos = CPos.New(13, 52), cost = 500, exists = true } -InfantryProduction = { type = "pyle", pos = CPos.New(15, 52), cost = 500, exists = true } -VehicleProduction = { type = "weap", pos = CPos.New(8, 48), cost = 2000, exists = true } +BaseProc = { type = "proc", pos = CPos.New(19, 48), cost = 1500 } +BaseNuke1 = { type = "nuke", pos = CPos.New(9, 53), cost = 500 } +BaseNuke2 = { type = "nuke", pos = CPos.New(7, 52), cost = 500 } +BaseNuke3 = { type = "nuke", pos = CPos.New(11, 53), cost = 500 } +BaseNuke4 = { type = "nuke", pos = CPos.New(13, 52), cost = 500 } +InfantryProduction = { type = "pyle", pos = CPos.New(15, 52), cost = 500 } +VehicleProduction = { type = "weap", pos = CPos.New(8, 48), cost = 2000 } BaseBuildings = { BaseProc, BaseNuke1, BaseNuke2, BaseNuke3, BaseNuke4, InfantryProduction, VehicleProduction } AutoGuard = function(guards) Utils.Do(guards, function(guard) - Trigger.OnDamaged(guard, function(guard) - IdleHunt(guard) - end) + Trigger.OnDamaged(guard, IdleHunt) end) end -BuildBase = function(cyard) - Utils.Do(BaseBuildings, function(building) - if not building.exists and not cyardIsBuilding then - BuildBuilding(building, cyard) - return - end - end) - Trigger.AfterDelay(DateTime.Seconds(10), function() BuildBase(cyard) end) -end - BuildBuilding = function(building, cyard) - cyardIsBuilding = true + if CyardIsBuilding or GDI.Cash < building.cost then + Trigger.AfterDelay(DateTime.Seconds(10), function() BuildBuilding(building, cyard) end) + return + end + CyardIsBuilding = true + + GDI.Cash = GDI.Cash - building.cost Trigger.AfterDelay(Actor.BuildTime(building.type), function() - cyardIsBuilding = false + CyardIsBuilding = false - if cyard.IsDead or cyard.Owner ~= enemy then + if cyard.IsDead or cyard.Owner ~= GDI then + GDI.Cash = GDI.Cash + building.cost return end - local actor = Actor.Create(building.type, true, { Owner = enemy, Location = building.pos }) - enemy.Cash = enemy.Cash - building.cost - - building.exists = true + local actor = Actor.Create(building.type, true, { Owner = GDI, Location = building.pos }) if actor.Type == 'pyle' or actor.Type == 'hand' then Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceInfantry(actor) end) @@ -69,28 +62,25 @@ BuildBuilding = function(building, cyard) Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceVehicle(actor) end) end - Trigger.OnKilled(actor, function() building.exists = false end) - - Trigger.OnDamaged(actor, function(building) - if building.Owner == enemy and building.Health < building.MaxHealth * 3/4 then - building.StartBuildingRepairs() - end + Trigger.OnKilled(actor, function() + BuildBuilding(building, cyard) end) - Trigger.AfterDelay(DateTime.Seconds(10), function() BuildBase(cyard) end) + RepairBuilding(GDI, actor, 0.75) end) end CheckForHarvester = function() - local harv = enemy.GetActorsByType("harv") + local harv = GDI.GetActorsByType("harv") return #harv > 0 end GuardBase = function() Utils.Do(GDIBase, function(building) - Trigger.OnDamaged(building, function(guard) + Trigger.OnDamaged(building, function() Utils.Do(GDIOrcas, function(guard) if not guard.IsDead and not building.IsDead then + guard.Stop() guard.Guard(building) end end) @@ -98,20 +88,6 @@ GuardBase = function() end) end -IdleHunt = function(unit) - if not unit.IsDead then - Trigger.OnIdle(unit, unit.Hunt) - end -end - -IdlingUnits = function(enemy) - local lazyUnits = enemy.GetGroundAttackers() - - Utils.Do(lazyUnits, function(unit) - IdleHunt(unit) - end) -end - ProduceHarvester = function(building) if not buildingHarvester then buildingHarvester = true @@ -122,10 +98,11 @@ ProduceHarvester = function(building) end ProduceInfantry = function(building) - if building.IsDead or building.Owner ~= enemy then + if building.IsDead or building.Owner ~= GDI then return elseif not CheckForHarvester() then Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceInfantry(building) end) + return end local delay = Utils.RandomInteger(DateTime.Seconds(3), DateTime.Seconds(9)) @@ -135,22 +112,23 @@ ProduceInfantry = function(building) InfantryAttackGroup[#InfantryAttackGroup + 1] = unit[1] if #InfantryAttackGroup >= InfantryGroupSize then - SendUnits(InfantryAttackGroup, Path) + MoveAndHunt(InfantryAttackGroup, Path) InfantryAttackGroup = { } Trigger.AfterDelay(InfantryProductionCooldown, function() ProduceInfantry(building) end) else Trigger.AfterDelay(delay, function() ProduceInfantry(building) end) end end) - + end ProduceVehicle = function(building) - if building.IsDead or building.Owner ~= enemy then + if building.IsDead or building.Owner ~= GDI then return elseif not CheckForHarvester() then ProduceHarvester(building) Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceVehicle(building) end) + return end local delay = Utils.RandomInteger(DateTime.Seconds(12), DateTime.Seconds(17)) @@ -160,7 +138,7 @@ ProduceVehicle = function(building) VehicleAttackGroup[#VehicleAttackGroup + 1] = unit[1] if #VehicleAttackGroup >= VehicleGroupSize then - SendUnits(VehicleAttackGroup, Path) + MoveAndHunt(VehicleAttackGroup, Path) VehicleAttackGroup = { } Trigger.AfterDelay(VehicleProductionCooldown, function() ProduceVehicle(building) end) else @@ -169,60 +147,41 @@ ProduceVehicle = function(building) end) end -SendUnits = function(units, waypoints) - Utils.Do(units, function(unit) - if not unit.IsDead then - Utils.Do(waypoints, function(waypoint) - unit.AttackMove(waypoint.Location) - end) - IdleHunt(unit) - end - end) -end +StartAI = function() + RepairNamedActors(GDI, 0.75) -StartAI = function(cyard) - Utils.Do(Map.NamedActors, function(actor) - if actor.Owner == enemy and actor.HasProperty("StartBuildingRepairs") then - Trigger.OnDamaged(actor, function(building) - if building.Owner == enemy and building.Health < 3/4 * building.MaxHealth then - building.StartBuildingRepairs() - end - end) - end - end) - enemy.Cash = StartingCash - BuildBase(cyard) + GDI.Cash = StartingCash GuardBase() end Trigger.OnAllKilledOrCaptured(GDIBase, function() - IdlingUnits(enemy) + Utils.Do(GDI.GetGroundAttackers(), IdleHunt) end) Trigger.OnKilled(GDIProc, function(building) - BaseProc.exists = false + BuildBuilding(BaseProc, GDICYard) end) Trigger.OnKilled(GDINuke1, function(building) - BaseNuke1.exists = false + BuildBuilding(BaseNuke1, GDICYard) end) Trigger.OnKilled(GDINuke2, function(building) - BaseNuke2.exists = false + BuildBuilding(BaseNuke2, GDICYard) end) Trigger.OnKilled(GDINuke3, function(building) - BaseNuke3.exists = false + BuildBuilding(BaseNuke3, GDICYard) end) Trigger.OnKilled(GDINuke4, function(building) - BaseNuke4.exists = false + BuildBuilding(BaseNuke4, GDICYard) end) Trigger.OnKilled(GDIPyle, function(building) - InfantryProduction.exists = false + BuildBuilding(InfantryProduction, GDICYard) end) Trigger.OnKilled(GDIWeap, function(building) - VehicleProduction.exists = false + BuildBuilding(VehicleProduction, GDICYard) end) diff --git a/mods/cnc/maps/nod08b/nod08b.lua b/mods/cnc/maps/nod08b/nod08b.lua index e17a3df8aa..28447bf5e2 100644 --- a/mods/cnc/maps/nod08b/nod08b.lua +++ b/mods/cnc/maps/nod08b/nod08b.lua @@ -6,6 +6,7 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + WaypointGroup1 = { waypoint1, waypoint2, waypoint3, waypoint9, waypoint10 } WaypointGroup2 = { waypoint5, waypoint6, waypoint7, waypoint8 } WaypointGroup3 = { waypoint1, waypoint2, waypoint4, waypoint11 } @@ -36,79 +37,30 @@ NodBaseTrigger = { CPos.New(52, 2), CPos.New(52, 3), CPos.New(52, 4), CPos.New(5 AirstrikeDelay = DateTime.Minutes(2) + DateTime.Seconds(30) NodBaseCapture = function() - nodBaseTrigger = true - player.MarkCompletedObjective(NodObjective1) + Nod.MarkCompletedObjective(LocateNodBase) Utils.Do(NodBase, function(actor) - actor.Owner = player + actor.Owner = Nod end) + Trigger.AfterDelay(DateTime.Seconds(1), function() - Media.PlaySpeechNotification(player, "NewOptions") + Media.PlaySpeechNotification(Nod, "NewOptions") end) end -searches = 0 -getAirstrikeTarget = function() - local list = player.GetGroundAttackers() - - if #list == 0 then - return - end - - local target = list[DateTime.GameTime % #list + 1].CenterPosition - - local sams = Map.ActorsInCircle(target, WDist.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 - ---Provide the player with a helicopter until the outpost got captured +-- Provide Nod with a helicopter until the outpost got captured SendHelicopter = function() Trigger.AfterDelay(DateTime.Seconds(5), function() - if not outpostCaptured then - Media.PlaySpeechNotification(player, "Reinforce") - TransportHelicopter = Reinforcements.ReinforceWithTransport(player, 'tran', nil, { ReinforcementsHelicopterSpawn.Location, waypoint0.Location })[1] - Trigger.OnKilled(TransportHelicopter, function() - SendHelicopter() - end) + if not Nod.IsObjectiveCompleted(CaptureGDIOutpost) then + Media.PlaySpeechNotification(Nod, "Reinforce") + local heli = Reinforcements.ReinforceWithTransport(Nod, "tran", nil, { ReinforcementsHelicopterSpawn.Location, waypoint0.Location })[1] + Trigger.OnKilled(heli, SendHelicopter) end end) end -SendAttackWave = function(team) - for type, amount in pairs(team.units) do - count = 0 - actors = enemy.GetActorsByType(type) - Utils.Do(actors, function(actor) - if actor.IsIdle and count < amount then - SetAttackWaypoints(actor, team.waypoints) - IdleHunt(actor) - count = count + 1 - end - end) - end -end - -SetAttackWaypoints = function(actor, waypoints) - if not actor.IsDead then - Utils.Do(waypoints, function(waypoint) - actor.AttackMove(waypoint.Location) - end) - end -end - SendGDIAirstrike = function(hq, delay) - if not hq.IsDead and hq.Owner == enemy then - local target = getAirstrikeTarget() + if not hq.IsDead and hq.Owner == GDI then + local target = GetAirstrikeTarget(Nod) if target then hq.SendAirstrike(target, false, Facing.NorthEast + 4) @@ -122,41 +74,38 @@ end SendWaves = function(counter, Waves) if counter <= #Waves then local team = Waves[counter] - SendAttackWave(team) + + for type, amount in pairs(team.units) do + MoveAndHunt(Utils.Take(amount, GDI.GetActorsByType(type)), team.waypoints) + end + Trigger.AfterDelay(DateTime.Seconds(team.delay), function() SendWaves(counter + 1, Waves) end) end end -StartWaves = function() - SendWaves(1, AutoAttackWaves) -end - Trigger.OnAllKilled(IntroGuards, function() - FlareCamera1 = Actor.Create("camera", true, { Owner = player, Location = waypoint25.Location }) - FlareCamera2 = Actor.Create("camera", true, { Owner = player, Location = FlareExtraCamera.Location }) - Flare = Actor.Create("flare", true, { Owner = player, Location = waypoint25.Location }) + FlareCamera1 = Actor.Create("camera", true, { Owner = Nod, Location = waypoint25.Location }) + FlareCamera2 = Actor.Create("camera", true, { Owner = Nod, Location = FlareExtraCamera.Location }) + Flare = Actor.Create("flare", true, { Owner = Nod, Location = waypoint25.Location }) SendHelicopter() - player.MarkCompletedObjective(NodObjective1) + Nod.MarkCompletedObjective(LocateNodBase) NodBaseCapture() end) Trigger.OnAllKilledOrCaptured(Outpost, function() - if not outpostCaptured then - outpostCaptured = true + if not Nod.IsObjectiveCompleted(CaptureGDIOutpost) then + Nod.MarkCompletedObjective(CaptureGDIOutpost) Trigger.AfterDelay(DateTime.Minutes(1), function() - if not GDIHQ.IsDead and (not NodHand.IsDead or not NodNuke.IsDead) then - local airstrikeproxy = Actor.Create("airstrike.proxy", false, { Owner = enemy }) + local airstrikeproxy = Actor.Create("airstrike.proxy", false, { Owner = GDI }) airstrikeproxy.SendAirstrike(AirstrikeTarget.CenterPosition, false, Facing.NorthEast + 4) airstrikeproxy.Destroy() end end) Trigger.AfterDelay(DateTime.Seconds(15), function() - Utils.Do(OutpostGuards, function(unit) - IdleHunt(unit) - end) + Utils.Do(OutpostGuards, IdleHunt) end) Trigger.AfterDelay(DateTime.Minutes(1), function() @@ -165,8 +114,7 @@ Trigger.OnAllKilledOrCaptured(Outpost, function() Flare.Destroy() end) - player.MarkCompletedObjective(NodObjective2) - Trigger.AfterDelay(DateTime.Minutes(1), function() StartWaves() end) + Trigger.AfterDelay(DateTime.Minutes(1), function() SendWaves(1, AutoAttackWaves) end) Trigger.AfterDelay(AirstrikeDelay, function() SendGDIAirstrike(GDIHQ, AirstrikeDelay) end) Trigger.AfterDelay(DateTime.Minutes(2), function() ProduceInfantry(GDIPyle) end) Trigger.AfterDelay(DateTime.Minutes(3), function() ProduceVehicle(GDIWeap) end) @@ -175,64 +123,49 @@ end) Trigger.OnCapture(OutpostCYard, function() Trigger.AfterDelay(DateTime.Seconds(4), function() - Media.PlaySpeechNotification(player, "NewOptions") + Media.PlaySpeechNotification(Nod, "NewOptions") end) end) Trigger.OnAnyKilled(Outpost, function() - if not outpostCaptured then - player.MarkFailedObjective(NodObjective2) + if not Nod.IsObjectiveCompleted(CaptureGDIOutpost) then + Nod.MarkFailedObjective(CaptureGDIOutpost) end end) Trigger.OnEnteredFootprint(NodBaseTrigger, function(a, id) - if not nodBaseTrigger and a.Owner == player then + if not Nod.IsObjectiveCompleted(LocateNodBase) and a.Owner == Nod then NodBaseCapture() + Trigger.RemoveFootprintTrigger(id) end end) WorldLoaded = function() - player = Player.GetPlayer("Nod") - enemy = Player.GetPlayer("GDI") + Nod = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") + Camera.Position = waypoint26.CenterPosition - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.ReinforceWithTransport(player, 'tran.in', IntroReinforcements, { ReinforcementsHelicopterSpawn.Location, ReinforcementsHelicopterRally.Location }, { ReinforcementsHelicopterSpawn.Location }, nil, nil) - StartAI(GDICYard) - AutoGuard(enemy.GetGroundAttackers()) + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.ReinforceWithTransport(Nod, "tran.in", IntroReinforcements, { ReinforcementsHelicopterSpawn.Location, ReinforcementsHelicopterRally.Location }, { ReinforcementsHelicopterSpawn.Location }) - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) + StartAI() + AutoGuard(GDI.GetGroundAttackers()) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) + InitObjectives(Nod) - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) - - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) - - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - NodObjective1 = player.AddPrimaryObjective("Locate the Nod base.") - NodObjective2 = player.AddPrimaryObjective("Capture the GDI outpost.") - NodObjective3 = player.AddPrimaryObjective("Eliminate all GDI forces in the area.") - GDIObjective = enemy.AddPrimaryObjective("Eliminate all Nod forces in the area.") + LocateNodBase = Nod.AddObjective("Locate the Nod base.") + CaptureGDIOutpost = Nod.AddObjective("Capture the GDI outpost.") + NodObjective3 = Nod.AddObjective("Eliminate all GDI forces in the area.") + GDIObjective = GDI.AddObjective("Eliminate all Nod forces in the area.") end Tick = function() - if DateTime.GameTime > 2 and player.HasNoRequiredUnits() then - enemy.MarkCompletedObjective(GDIObjective) + if DateTime.GameTime > 2 and Nod.HasNoRequiredUnits() then + GDI.MarkCompletedObjective(GDIObjective) end - if DateTime.GameTime > 2 and enemy.HasNoRequiredUnits() then - player.MarkCompletedObjective(NodObjective3) + if DateTime.GameTime > 2 and GDI.HasNoRequiredUnits() then + Nod.MarkCompletedObjective(NodObjective3) end end diff --git a/mods/cnc/maps/nod08b/rules.yaml b/mods/cnc/maps/nod08b/rules.yaml index dfd42249d3..a7cea47ca9 100644 --- a/mods/cnc/maps/nod08b/rules.yaml +++ b/mods/cnc/maps/nod08b/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: nod08b.lua, nod08b-AI.lua + Scripts: campaign-global.lua, nod08b.lua, nod08b-AI.lua MusicPlaylist: StartingMusic: linefire VictoryMusic: nod_win1 diff --git a/mods/cnc/maps/nod09/nod09-AI.lua b/mods/cnc/maps/nod09/nod09-AI.lua index 9994fc5e52..893760ed46 100644 --- a/mods/cnc/maps/nod09/nod09-AI.lua +++ b/mods/cnc/maps/nod09/nod09-AI.lua @@ -6,62 +6,59 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] + AttackPaths = { { AttackPath1 }, { AttackPath2 } } + GDIBase = { GDICYard, GDIPyle, GDIWeap, GDIHQ, GDIProc, GDINuke1, GDINuke2, GDINuke3, GDIBuilding1, GDIBuilding2, GDIBuilding3, GDIBuilding4, GDIBuilding5, GDIBuilding6, GDIBuilding7, GDIBuilding8, GDIBuilding9, GDIBuilding10, GDIBuilding11 } GDIOrcas = { GDIOrca1, GDIOrca2 } + InfantryAttackGroup = { } InfantryGroupSize = 5 InfantryProductionCooldown = DateTime.Minutes(3) InfantryProductionTypes = { "e1", "e1", "e2" } HarvesterProductionType = { "harv" } + VehicleAttackGroup = { } VehicleGroupSize = 5 VehicleProductionCooldown = DateTime.Minutes(3) VehicleProductionTypes = { "jeep", "jeep", "mtnk", "mtnk", "mtnk", "msam" } + StartingCash = 4000 -BaseProc = { type = "proc", pos = CPos.New(54, 10), cost = 1500, exists = true } -BaseNuke1 = { type = "nuke", pos = CPos.New(57, 7), cost = 500, exists = true } -BaseNuke2 = { type = "nuke", pos = CPos.New(55, 7), cost = 500, exists = true } -BaseNuke3 = { type = "nuke", pos = CPos.New(59, 7), cost = 500, exists = true } -BaseNuke4 = { type = "nuke", pos = CPos.New(59, 10), cost = 500, exists = true } -InfantryProduction = { type = "pyle", pos = CPos.New(49, 4), cost = 500, exists = true } -VehicleProduction = { type = "weap", pos = CPos.New(51, 7), cost = 2000, exists = true } +BaseProc = { type = "proc", pos = CPos.New(54, 10), cost = 1500 } +BaseNuke1 = { type = "nuke", pos = CPos.New(57, 7), cost = 500 } +BaseNuke2 = { type = "nuke", pos = CPos.New(55, 7), cost = 500 } +BaseNuke3 = { type = "nuke", pos = CPos.New(59, 7), cost = 500 } +BaseNuke4 = { type = "nuke", pos = CPos.New(59, 10), cost = 500 } +InfantryProduction = { type = "pyle", pos = CPos.New(49, 4), cost = 500 } +VehicleProduction = { type = "weap", pos = CPos.New(51, 7), cost = 2000 } BaseBuildings = { BaseProc, BaseNuke1, BaseNuke2, BaseNuke3, BaseNuke4, InfantryProduction, VehicleProduction } AutoGuard = function(guards) Utils.Do(guards, function(guard) - Trigger.OnDamaged(guard, function(guard) - IdleHunt(guard) - end) + Trigger.OnDamaged(guard, IdleHunt) end) end -BuildBase = function(cyard) - Utils.Do(BaseBuildings, function(building) - if not building.exists and not cyardIsBuilding then - BuildBuilding(building, cyard) - return - end - end) - Trigger.AfterDelay(DateTime.Seconds(10), function() BuildBase(cyard) end) -end - BuildBuilding = function(building, cyard) - cyardIsBuilding = true + if CyardIsBuilding or GDI.Cash < building.cost then + Trigger.AfterDelay(DateTime.Seconds(10), function() BuildBuilding(building, cyard) end) + return + end + CyardIsBuilding = true + + GDI.Cash = GDI.Cash - building.cost Trigger.AfterDelay(Actor.BuildTime(building.type), function() - cyardIsBuilding = false + CyardIsBuilding = false - if cyard.IsDead or cyard.Owner ~= enemy then + if cyard.IsDead or cyard.Owner ~= GDI then + GDI.Cash = GDI.Cash + building.cost return end - local actor = Actor.Create(building.type, true, { Owner = enemy, Location = building.pos }) - enemy.Cash = enemy.Cash - building.cost - - building.exists = true + local actor = Actor.Create(building.type, true, { Owner = GDI, Location = building.pos }) if actor.Type == 'pyle' or actor.Type == 'hand' then Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceInfantry(actor) end) @@ -69,28 +66,25 @@ BuildBuilding = function(building, cyard) Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceVehicle(actor) end) end - Trigger.OnKilled(actor, function() building.exists = false end) - - Trigger.OnDamaged(actor, function(building) - if building.Owner == enemy and building.Health < building.MaxHealth * 3/4 then - building.StartBuildingRepairs() - end + Trigger.OnKilled(actor, function() + BuildBuilding(building, cyard) end) - Trigger.AfterDelay(DateTime.Seconds(10), function() BuildBase(cyard) end) + RepairBuilding(GDI, actor, 0.75) end) end CheckForHarvester = function() - local harv = enemy.GetActorsByType("harv") + local harv = GDI.GetActorsByType("harv") return #harv > 0 end GuardBase = function() Utils.Do(GDIBase, function(building) - Trigger.OnDamaged(building, function(guard) + Trigger.OnDamaged(building, function() Utils.Do(GDIOrcas, function(guard) if not guard.IsDead and not building.IsDead then + guard.Stop() guard.Guard(building) end end) @@ -98,20 +92,6 @@ GuardBase = function() end) end -IdleHunt = function(unit) - if not unit.IsDead then - Trigger.OnIdle(unit, unit.Hunt) - end -end - -IdlingUnits = function(enemy) - local lazyUnits = enemy.GetGroundAttackers() - - Utils.Do(lazyUnits, function(unit) - IdleHunt(unit) - end) -end - ProduceHarvester = function(building) if not buildingHarvester then buildingHarvester = true @@ -122,10 +102,11 @@ ProduceHarvester = function(building) end ProduceInfantry = function(building) - if building.IsDead or building.Owner ~= enemy then + if building.IsDead or building.Owner ~= GDI then return elseif not CheckForHarvester() then Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceInfantry(building) end) + return end local delay = Utils.RandomInteger(DateTime.Seconds(3), DateTime.Seconds(9)) @@ -135,22 +116,23 @@ ProduceInfantry = function(building) InfantryAttackGroup[#InfantryAttackGroup + 1] = unit[1] if #InfantryAttackGroup >= InfantryGroupSize then - SendUnits(InfantryAttackGroup, Path) + MoveAndHunt(InfantryAttackGroup, Path) InfantryAttackGroup = { } Trigger.AfterDelay(InfantryProductionCooldown, function() ProduceInfantry(building) end) else Trigger.AfterDelay(delay, function() ProduceInfantry(building) end) end end) - + end ProduceVehicle = function(building) - if building.IsDead or building.Owner ~= enemy then + if building.IsDead or building.Owner ~= GDI then return elseif not CheckForHarvester() then ProduceHarvester(building) Trigger.AfterDelay(DateTime.Seconds(10), function() ProduceVehicle(building) end) + return end local delay = Utils.RandomInteger(DateTime.Seconds(12), DateTime.Seconds(17)) @@ -160,7 +142,7 @@ ProduceVehicle = function(building) VehicleAttackGroup[#VehicleAttackGroup + 1] = unit[1] if #VehicleAttackGroup >= VehicleGroupSize then - SendUnits(VehicleAttackGroup, Path) + MoveAndHunt(VehicleAttackGroup, Path) VehicleAttackGroup = { } Trigger.AfterDelay(VehicleProductionCooldown, function() ProduceVehicle(building) end) else @@ -169,60 +151,45 @@ ProduceVehicle = function(building) end) end -SendUnits = function(units, waypoints) - Utils.Do(units, function(unit) - if not unit.IsDead then - Utils.Do(waypoints, function(waypoint) - unit.AttackMove(waypoint.Location) - end) - IdleHunt(unit) - end - end) -end +StartAI = function() + RepairNamedActors(GDI, 0.75) -StartAI = function(cyard) - Utils.Do(Map.NamedActors, function(actor) - if actor.Owner == enemy and actor.HasProperty("StartBuildingRepairs") then - Trigger.OnDamaged(actor, function(building) - if building.Owner == enemy and building.Health < 3/4 * building.MaxHealth then - building.StartBuildingRepairs() - end - end) - end - end) - enemy.Cash = StartingCash - BuildBase(cyard) + GDI.Cash = StartingCash GuardBase() end Trigger.OnAllKilledOrCaptured(GDIBase, function() - IdlingUnits(enemy) + Utils.Do(GDI.GetGroundAttackers(), IdleHunt) +end) + +Trigger.OnAllKilledOrCaptured(GDIBase, function() + Utils.Do(GDI.GetGroundAttackers(), IdleHunt) end) Trigger.OnKilled(GDIProc, function(building) - BaseProc.exists = false + BuildBuilding(BaseProc, GDICYard) end) Trigger.OnKilled(GDINuke1, function(building) - BaseNuke1.exists = false + BuildBuilding(BaseNuke1, GDICYard) end) Trigger.OnKilled(GDINuke2, function(building) - BaseNuke2.exists = false + BuildBuilding(BaseNuke2, GDICYard) end) Trigger.OnKilled(GDINuke3, function(building) - BaseNuke3.exists = false + BuildBuilding(BaseNuke3, GDICYard) end) Trigger.OnKilled(GDINuke4, function(building) - BaseNuke4.exists = false + BuildBuilding(BaseNuke4, GDICYard) end) Trigger.OnKilled(GDIPyle, function(building) - InfantryProduction.exists = false + BuildBuilding(InfantryProduction, GDICYard) end) Trigger.OnKilled(GDIWeap, function(building) - VehicleProduction.exists = false + BuildBuilding(VehicleProduction, GDICYard) end) diff --git a/mods/cnc/maps/nod09/nod09.lua b/mods/cnc/maps/nod09/nod09.lua index ab73fa7d24..e4f1fcb92b 100644 --- a/mods/cnc/maps/nod09/nod09.lua +++ b/mods/cnc/maps/nod09/nod09.lua @@ -6,9 +6,10 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] -if Map.LobbyOption("difficulty") == "easy" then + +if Difficulty == "easy" then Rambo = "rmbo.easy" -elseif Map.LobbyOption("difficulty") == "hard" then +elseif Difficulty == "hard" then Rambo = "rmbo.hard" else Rambo = "rmbo" @@ -45,61 +46,14 @@ RocketTrigger = { CPos.New(20, 15), CPos.New(21, 15), CPos.New(22, 15), CPos.New AirstrikeDelay = DateTime.Minutes(2) + DateTime.Seconds(30) -CheckForSams = function(player) - local sams = player.GetActorsByType("sam") +CheckForSams = function(Nod) + local sams = Nod.GetActorsByType("sam") return #sams >= 3 end -searches = 0 -getAirstrikeTarget = function() - local list = player.GetGroundAttackers() - - if #list == 0 then - return - end - - local target = list[DateTime.GameTime % #list + 1].CenterPosition - - local sams = Map.ActorsInCircle(target, WDist.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 - -SendAttackWave = function(team) - for type, amount in pairs(team.units) do - count = 0 - local actors = enemy.GetActorsByType(type) - Utils.Do(actors, function(actor) - if actor.IsIdle and count < amount then - SetAttackWaypoints(actor, team.waypoints) - IdleHunt(actor) - count = count + 1 - end - end) - end -end - -SetAttackWaypoints = function(actor, waypoints) - if not actor.IsDead then - Utils.Do(waypoints, function(waypoint) - actor.AttackMove(waypoint.Location) - end) - end -end - SendGDIAirstrike = function(hq, delay) - if not hq.IsDead and hq.Owner == enemy then - local target = getAirstrikeTarget() + if not hq.IsDead and hq.Owner == GDI then + local target = GetAirstrikeTarget(Nod) if target then hq.SendAirstrike(target, false, Facing.NorthEast + 4) @@ -113,14 +67,18 @@ end SendWaves = function(counter, Waves) if counter <= #Waves then local team = Waves[counter] - SendAttackWave(team) + + for type, amount in pairs(team.units) do + MoveAndHunt(Utils.Take(amount, GDI.GetActorsByType(type)), team.waypoints) + end + Trigger.AfterDelay(DateTime.Seconds(team.delay), function() SendWaves(counter + 1, Waves) end) end end StartPatrols = function() - local mtnks = enemy.GetActorsByType("mtnk") - local msams = enemy.GetActorsByType("msam") + local mtnks = GDI.GetActorsByType("mtnk") + local msams = GDI.GetActorsByType("msam") if #mtnks >= 1 then mtnks[1].Patrol(Patrol1Waypoints, true, 20) @@ -131,82 +89,82 @@ StartPatrols = function() end end -StartWaves = function() - SendWaves(1, AutoAttackWaves) -end - Trigger.OnEnteredFootprint(NodBaseTrigger, function(a, id) - if not nodBaseTrigger and a.Owner == player then - nodBaseTrigger = true - player.MarkCompletedObjective(NodObjective3) - NodCYard.Owner = player + if not Nod.IsObjectiveCompleted(LocateNodBase) and a.Owner == Nod then + Trigger.RemoveFootprintTrigger(id) - local walls = nodBase.GetActorsByType("brik") + Nod.MarkCompletedObjective(LocateNodBase) + NodCYard.Owner = Nod + + local walls = NodBase.GetActorsByType("brik") Utils.Do(walls, function(actor) - actor.Owner = player + actor.Owner = Nod end) Trigger.AfterDelay(DateTime.Seconds(2), function() - Media.PlaySpeechNotification(player, "NewOptions") + Media.PlaySpeechNotification(Nod, "NewOptions") end) end end) Trigger.OnEnteredFootprint(RocketTrigger, function(a, id) - if not rocketTrigger and a.Owner == player then - rocketTrigger = true - player.MarkCompletedObjective(NodObjective1) + if not Nod.IsObjectiveCompleted(SecureFirstLanding) and a.Owner == Nod then + Trigger.RemoveFootprintTrigger(id) + + Nod.MarkCompletedObjective(SecureFirstLanding) Trigger.AfterDelay(DateTime.Seconds(5), function() - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.ReinforceWithTransport(player, 'tran.in', RocketReinforcements, { HelicopterEntryRocket.Location, HelicopterGoalRocket.Location }, { HelicopterEntryRocket.Location }, nil, nil) + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.ReinforceWithTransport(Nod, "tran.in", RocketReinforcements, { HelicopterEntryRocket.Location, HelicopterGoalRocket.Location }, { HelicopterEntryRocket.Location }, nil, nil) end) Trigger.AfterDelay(DateTime.Seconds(10), function() - FlareEngineerCamera1 = Actor.Create("camera", true, { Owner = player, Location = FlareEngineer.Location }) - FlareEngineerCamera2 = Actor.Create("camera", true, { Owner = player, Location = CameraEngineerPath.Location }) - FlareEngineer = Actor.Create("flare", true, { Owner = player, Location = FlareEngineer.Location }) + EngineerFlareCamera1 = Actor.Create("camera", true, { Owner = Nod, Location = FlareEngineer.Location }) + EngineerFlareCamera2 = Actor.Create("camera", true, { Owner = Nod, Location = CameraEngineerPath.Location }) + EngineerFlare = Actor.Create("flare", true, { Owner = Nod, Location = FlareEngineer.Location }) end) Trigger.AfterDelay(DateTime.Minutes(1), function() - FlareRocketCamera.Destroy() - FlareRocket.Destroy() + RocketFlareCamera.Destroy() + RocketFlare.Destroy() end) end end) Trigger.OnEnteredFootprint(EngineerTrigger, function(a, id) - if not engineerTrigger and a.Owner == player then - engineerTrigger = true - player.MarkCompletedObjective(NodObjective2) + if not Nod.IsObjectiveCompleted(SecureSecondLanding) and a.Owner == Nod then + Trigger.RemoveFootprintTrigger(id) + + Nod.MarkCompletedObjective(SecureSecondLanding) Trigger.AfterDelay(DateTime.Seconds(5), function() - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.ReinforceWithTransport(player, 'tran.in', EngineerReinforcements, { HelicopterEntryEngineer.Location, HelicopterGoalEngineer.Location }, { HelicopterEntryEngineer.Location }, nil, nil) + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.ReinforceWithTransport(Nod, "tran.in", EngineerReinforcements, { HelicopterEntryEngineer.Location, HelicopterGoalEngineer.Location }, { HelicopterEntryEngineer.Location }, nil, nil) end) Trigger.AfterDelay(DateTime.Minutes(1), function() - FlareEngineerCamera1.Destroy() - FlareEngineerCamera2.Destroy() - FlareEngineer.Destroy() + if EngineerFlareCamera1 then + EngineerFlareCamera1.Destroy() + EngineerFlareCamera2.Destroy() + EngineerFlare.Destroy() + end end) end end) Trigger.OnKilledOrCaptured(OutpostProc, function() - if not outpostCaptured then - outpostCaptured = true + if not Nod.IsObjectiveCompleted(CaptureRefinery) then if OutpostProc.IsDead then - player.MarkFailedObjective(NodObjective4) + Nod.MarkFailedObjective(CaptureRefinery) else - player.MarkCompletedObjective(NodObjective4) - player.Cash = 1000 + Nod.MarkCompletedObjective(CaptureRefinery) + Nod.Cash = 1000 end StartPatrols() - Trigger.AfterDelay(DateTime.Minutes(1), function() StartWaves() end) + Trigger.AfterDelay(DateTime.Minutes(1), function() SendWaves(1, AutoAttackWaves) end) Trigger.AfterDelay(AirstrikeDelay, function() SendGDIAirstrike(GDIHQ, AirstrikeDelay) end) Trigger.AfterDelay(DateTime.Minutes(3), function() ProduceInfantry(GDIPyle) end) Trigger.AfterDelay(DateTime.Minutes(3), function() ProduceVehicle(GDIWeap) end) @@ -214,58 +172,42 @@ Trigger.OnKilledOrCaptured(OutpostProc, function() end) WorldLoaded = function() - player = Player.GetPlayer("Nod") - enemy = Player.GetPlayer("GDI") - nodBase = Player.GetPlayer("NodBase") + Nod = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") + NodBase = Player.GetPlayer("NodBase") Camera.Position = CameraIntro.CenterPosition - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.ReinforceWithTransport(player, 'tran.in', RmboReinforcements, { HelicopterEntryRmbo.Location, HelicopterGoalRmbo.Location }, { HelicopterEntryRmbo.Location }, nil, nil) - FlareRocketCamera = Actor.Create("camera", true, { Owner = player, Location = FlareRocket.Location }) - FlareRocket = Actor.Create("flare", true, { Owner = player, Location = FlareRocket.Location }) - StartAI(GDICYard) - AutoGuard(enemy.GetGroundAttackers()) + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.ReinforceWithTransport(Nod, "tran.in", RmboReinforcements, { HelicopterEntryRmbo.Location, HelicopterGoalRmbo.Location }, { HelicopterEntryRmbo.Location }) - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) + RocketFlareCamera = Actor.Create("camera", true, { Owner = Nod, Location = FlareRocket.Location }) + RocketFlare = Actor.Create("flare", true, { Owner = Nod, Location = FlareRocket.Location }) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) + StartAI() + AutoGuard(GDI.GetGroundAttackers()) - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) + InitObjectives(Nod) - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) - - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - NodObjective1 = player.AddPrimaryObjective("Secure the first landing zone.") - NodObjective2 = player.AddPrimaryObjective("Secure the second landing zone.") - NodObjective3 = player.AddPrimaryObjective("Locate the Nod base.") - NodObjective4 = player.AddPrimaryObjective("Capture the refinery.") - NodObjective5 = player.AddPrimaryObjective("Eliminate all GDI forces in the area.") - NodObjective6 = player.AddSecondaryObjective("Build 3 SAMs to fend off the GDI bombers.") - GDIObjective = enemy.AddPrimaryObjective("Eliminate all Nod forces in the area.") + SecureFirstLanding = Nod.AddObjective("Secure the first landing zone.") + SecureSecondLanding = Nod.AddObjective("Secure the second landing zone.") + LocateNodBase = Nod.AddObjective("Locate the Nod base.") + CaptureRefinery = Nod.AddObjective("Capture the refinery.") + EliminateGDI = Nod.AddObjective("Eliminate all GDI forces in the area.") + BuildSAMs = Nod.AddObjective("Build 3 SAMs to fend off the GDI bombers.", "Secondary", false) + GDIObjective = GDI.AddObjective("Eliminate all Nod forces in the area.") end Tick = function() - if DateTime.GameTime > 2 and player.HasNoRequiredUnits() then - enemy.MarkCompletedObjective(GDIObjective) + if DateTime.GameTime > 2 and Nod.HasNoRequiredUnits() then + GDI.MarkCompletedObjective(GDIObjective) end - if DateTime.GameTime > 2 and enemy.HasNoRequiredUnits() then - player.MarkCompletedObjective(NodObjective5) + if DateTime.GameTime > 2 and GDI.HasNoRequiredUnits() then + Nod.MarkCompletedObjective(EliminateGDI) end - if not player.IsObjectiveCompleted(NodObjective6) and CheckForSams(player) then - player.MarkCompletedObjective(NodObjective6) + if not Nod.IsObjectiveCompleted(BuildSAMs) and CheckForSams(Nod) then + Nod.MarkCompletedObjective(BuildSAMs) end end diff --git a/mods/cnc/maps/nod09/rules.yaml b/mods/cnc/maps/nod09/rules.yaml index f0014ca2e6..4ea68a4d79 100644 --- a/mods/cnc/maps/nod09/rules.yaml +++ b/mods/cnc/maps/nod09/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: nod09.lua, nod09-AI.lua + Scripts: campaign-global.lua, nod09.lua, nod09-AI.lua MusicPlaylist: StartingMusic: march VictoryMusic: nod_win1 @@ -35,6 +35,7 @@ World: normal: Normal hard: Hard Default: easy + Locked: false Player: PlayerResources: diff --git a/mods/cnc/maps/nod10a/nod10a.lua b/mods/cnc/maps/nod10a/nod10a.lua index 352278fe9b..78f7281c0b 100644 --- a/mods/cnc/maps/nod10a/nod10a.lua +++ b/mods/cnc/maps/nod10a/nod10a.lua @@ -6,96 +6,64 @@ the License, or (at your option) any later version. For more information, see COPYING. ]] -if Map.LobbyOption("difficulty") == "easy" then + +if Difficulty == "easy" then Rambo = "rmbo.easy" -elseif Map.LobbyOption("difficulty") == "hard" then +elseif Difficulty == "hard" then Rambo = "rmbo.hard" else Rambo = "rmbo" end -GDIBuildings = { ConYard, PowerPlant1, PowerPlant2, PowerPlant3, PowerPlant4, -Barracks, CommCenter, WeaponsFactory, GuardTower1, GuardTower2, GuardTower3 } +GDIBuildings = { ConYard, PowerPlant1, PowerPlant2, PowerPlant3, PowerPlant4, Barracks, CommCenter, WeaponsFactory, GuardTower1, GuardTower2, GuardTower3 } - -function RepairBuilding(building, attacker) - if not building.IsDead and building.Owner == enemy then - building.StartBuildingRepairs(enemy) - end -end - - -ChinookTrigger = false - - -function ReinforceWithChinook(_, discoverer) - if not ChinookTrigger and discoverer == player then +ReinforceWithChinook = function(_, discoverer) + if not ChinookTrigger and discoverer == Nod then ChinookTrigger = true Trigger.AfterDelay(DateTime.Seconds(1), function() - TransportFlare = Actor.Create('flare', true, { Owner = player, Location = DefaultFlareLocation.Location }) - Media.PlaySpeechNotification(player, "Reinforce") - Reinforcements.ReinforceWithTransport(player, 'tran', nil, { ChinookEntry.Location, ChinookTarget.Location }) + Actor.Create("flare", true, { Owner = Nod, Location = DefaultFlareLocation.Location }) + Media.PlaySpeechNotification(Nod, "Reinforce") + Reinforcements.ReinforceWithTransport(Nod, "tran", nil, { ChinookEntry.Location, ChinookTarget.Location }) end) end end +CreateScientist = function() + local scientist = Actor.Create("CHAN", true, { Owner = GDI, Location = ScientistLocation.Location }) + + KillScientistObjective = Nod.AddObjective("Kill the GDI scientist.") + Nod.MarkCompletedObjective(DestroyTechCenterObjective) -function CreateScientist() - scientist = Actor.Create('CHAN', true, { Owner = enemy, Location = ScientistLocation.Location }) - killScientistObjective = player.AddPrimaryObjective("Kill the GDI scientist.") Trigger.OnKilled(scientist, function() - player.MarkCompletedObjective(killScientistObjective) + Nod.MarkCompletedObjective(KillScientistObjective) end) - player.MarkCompletedObjective(destroyTechCenterObjective) end +WorldLoaded = function() + Nod = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") -function WorldLoaded() - player = Player.GetPlayer("Nod") - enemy = Player.GetPlayer("GDI") - - enemy.Cash = 10000 + GDI.Cash = 10000 Camera.Position = DefaultCameraPosition.CenterPosition - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) - - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) - - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) + InitObjectives(Nod) Utils.Do(GDIBuildings, function(building) - Trigger.OnDamaged(building, RepairBuilding) + RepairBuilding(GDI, building, 0.75) end) - gdiObjective = enemy.AddPrimaryObjective("Eliminate all Nod forces in the area.") - destroyTechCenterObjective = player.AddPrimaryObjective("Destroy the GDI R&D center.") + DestroyTechCenterObjective = Nod.AddObjective("Destroy the GDI R&D center.") - Actor.Create(Rambo, true, { Owner = player, Location = RamboLocation.Location }) + Actor.Create(Rambo, true, { Owner = Nod, Location = RamboLocation.Location }) Trigger.OnDiscovered(TechCenter, ReinforceWithChinook) - Trigger.OnKilled(TechCenter, CreateScientist) end - -function Tick() - if DateTime.GameTime > 2 then - if player.HasNoRequiredUnits() then - enemy.MarkCompletedObjective(gdiObjective) - end +Tick = function() + if DateTime.GameTime > 2 and Nod.HasNoRequiredUnits() then + Nod.MarkFailedObjective(DestroyTechCenterObjective) end end diff --git a/mods/cnc/maps/nod10a/rules.yaml b/mods/cnc/maps/nod10a/rules.yaml index 9558ae0759..86060c27eb 100644 --- a/mods/cnc/maps/nod10a/rules.yaml +++ b/mods/cnc/maps/nod10a/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: nod10a.lua + Scripts: campaign-global.lua, nod10a.lua MissionData: Briefing: GDI is developing an orbital weapon. Our spies have told us of a large lake near the location of the R&D center.\n\nFind the base, and use the sniper to eliminate their scientist. BackgroundVideo: kanepre.vqa @@ -30,6 +30,7 @@ World: normal: Normal hard: Hard Default: easy + Locked: false -LegacyBridgeLayer: ^CivBuilding: diff --git a/mods/cnc/maps/nod10b/nod10b.lua b/mods/cnc/maps/nod10b/nod10b.lua index b46f0ce69d..6d32477662 100644 --- a/mods/cnc/maps/nod10b/nod10b.lua +++ b/mods/cnc/maps/nod10b/nod10b.lua @@ -7,132 +7,62 @@ information, see COPYING. ]] -if Map.LobbyOption("difficulty") == "easy" then +if Difficulty == "easy" then Rambo = "rmbo.easy" -elseif Map.LobbyOption("difficulty") == "hard" then +elseif Difficulty == "hard" then Rambo = "rmbo.hard" else Rambo = "rmbo" end -GDIBuildings = {ConYard, PowerPlant1, PowerPlant2, PowerPlant3, PowerPlant4, PowerPlant5, Barracks, -Silo1, Silo2, WeaponsFactory, CommCenter, GuardTower1, GuardTower2} +GDIBuildings = { ConYard, PowerPlant1, PowerPlant2, PowerPlant3, PowerPlant4, PowerPlant5, Barracks, Silo1, Silo2, WeaponsFactory, CommCenter, GuardTower1, GuardTower2 } +Mammoths = { Mammoth1, Mammoth2, Mammoth3 } +Grenadiers = { Grenadier1, Grenadier2, Grenadier3, Grenadier4 } +MediumTanks = { MediumTank1, MediumTank2 } +Riflemen = { Rifleman1, Rifleman2, Rifleman3, Rifleman4 } -function RepairBuilding(building, attacker) - if not building.IsDead and building.Owner == enemy then - building.StartBuildingRepairs(enemy) - end -end +MammothPatrolPath = { MammothWaypoint1.Location, MammothWaypoint2.Location } +RiflemenPatrolPath = { RiflemenWaypoint1.Location, RiflemenWaypoint2.Location } +InfantrySquad = { "e1", "e1", "e1", "e1", "e1" } -Mammoths = {Mammoth1, Mammoth2, Mammoth3} -Grenadiers = {Grenadier1, Grenadier2, Grenadier3, Grenadier4} -MediumTanks = {MediumTank1, MediumTank2} -Riflemen = {Rifleman1, Rifleman2, Rifleman3, Rifleman4} +DeliverCommando = function() + Media.PlaySpeechNotification(Nod, "Reinforce") + local rambo = Reinforcements.ReinforceWithTransport(Nod, "tran.in", { Rambo }, { ChinookEntry.Location, ChinookTarget.Location }, { ChinookEntry.Location })[2][1] -MammothPatrolPath = {MammothWaypoint1.Location, MammothWaypoint2.Location} -RiflemenPatrolPath = {RiflemenWaypoint1.Location, RiflemenWaypoint2.Location} - -DamageTrigger = false - - -function TankDamaged(tank, attacker) - if not DamageTrigger then - DamageTrigger = true - Utils.Do(Grenadiers, function(grenadier) - if not grenadier.IsDead then - grenadier.AttackMove(tank.Location) - end - end) - end -end - - -function GrenadierDamaged(grenadier, attacker) - if not DamageTrigger then - DamageTrigger = true - Utils.Do(MediumTanks, function(tank) - if not tank.IsDead then - tank.AttackMove(grenadier.Location) - end - end) - end -end - - -InfantrySquad = {"e1", "e1", "e1", "e1", "e1"} - - -function MoveToNorthEntrance(squad) - Utils.Do(squad, function(unit) - if not unit.IsDead then - unit.AttackMove(NorthEntrance.Location) - end - end) -end - - -function EnteredFromNorth(actor, id) - if actor.Owner == player then - Trigger.RemoveFootprintTrigger(id) - if not Barracks.IsDead and Barracks.Owner == enemy then - Barracks.Build(InfantrySquad, MoveToNorthEntrance) - end - end -end - - -function DeliverCommando() - Media.PlaySpeechNotification(player, "Reinforce") - units = Reinforcements.ReinforceWithTransport(player, 'tran.in', {Rambo}, {ChinookEntry.Location, ChinookTarget.Location}, {ChinookEntry.Location}) - rambo = units[2][1] - Trigger.OnKilled(rambo, function(a, k) - player.MarkFailedObjective(keepRamboAliveObjective) + Trigger.OnKilled(rambo, function() + Nod.MarkFailedObjective(KeepRamboAliveObjective) end) - Trigger.OnPlayerWon(player, function(player) + + Trigger.OnPlayerWon(Nod, function(Nod) if not rambo.IsDead then - player.MarkCompletedObjective(keepRamboAliveObjective) + Nod.MarkCompletedObjective(KeepRamboAliveObjective) end end) end +WorldLoaded = function() + Nod = Player.GetPlayer("Nod") + GDI = Player.GetPlayer("GDI") -function WorldLoaded() - player = Player.GetPlayer("Nod") - enemy = Player.GetPlayer("GDI") - - enemy.Cash = 10000 + GDI.Cash = 10000 Camera.Position = DefaultCameraPosition.CenterPosition - Trigger.OnObjectiveAdded(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") - end) - Trigger.OnObjectiveCompleted(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") - end) - Trigger.OnObjectiveFailed(player, function(p, id) - Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") - end) - Trigger.OnPlayerWon(player, function() - Media.PlaySpeechNotification(player, "Win") - end) + InitObjectives(Nod) - Trigger.OnPlayerLost(player, function() - Media.PlaySpeechNotification(player, "Lose") - end) - - gdiObjective = enemy.AddPrimaryObjective("Eliminate all Nod forces in the area.") - warFactoryObjective = player.AddPrimaryObjective("Destroy or capture the Weapons Factory.") - destroyTanksObjective = player.AddPrimaryObjective("Destroy the Mammoth tanks in the R&D base.") - keepRamboAliveObjective = player.AddSecondaryObjective("Keep your Commando alive.") + GDIObjective = GDI.AddPrimaryObjective("Eliminate all Nod forces in the area.") + WarFactoryObjective = Nod.AddPrimaryObjective("Destroy or capture the Weapons Factory.") + DestroyTanksObjective = Nod.AddPrimaryObjective("Destroy the Mammoth tanks in the R&D base.") + KeepRamboAliveObjective = Nod.AddObjective("Keep your Commando alive.", "Secondary", false) Trigger.OnKilledOrCaptured(WeaponsFactory, function() - player.MarkCompletedObjective(warFactoryObjective) + Nod.MarkCompletedObjective(WarFactoryObjective) end) + Trigger.OnAllKilled(Mammoths, function() - player.MarkCompletedObjective(destroyTanksObjective) + Nod.MarkCompletedObjective(DestroyTanksObjective) end) Trigger.AfterDelay(DateTime.Seconds(1), DeliverCommando) @@ -142,18 +72,56 @@ function WorldLoaded() end) Utils.Do(MediumTanks, function(tank) - Trigger.OnDamaged(tank, TankDamaged) + Trigger.OnDamaged(tank, function() + if DamageTrigger then + return + end + + DamageTrigger = true + Utils.Do(Grenadiers, function(grenadier) + if not grenadier.IsDead then + grenadier.AttackMove(tank.Location) + end + end) + end) end) Utils.Do(Grenadiers, function(grenadier) - Trigger.OnDamaged(grenadier, GrenadierDamaged) + Trigger.OnDamaged(grenadier, function() + if DamageTrigger then + return + end + + DamageTrigger = true + Utils.Do(MediumTanks, function(tank) + if not tank.IsDead then + tank.AttackMove(grenadier.Location) + end + end) + end) end) Utils.Do(GDIBuildings, function(building) - Trigger.OnDamaged(building, RepairBuilding) + RepairBuilding(GDI, building, 0.75) end) - Trigger.OnEnteredFootprint({NorthEntrance.Location}, EnteredFromNorth) + Trigger.OnEnteredFootprint({ NorthEntrance.Location }, function(a, id) + if a.Owner == Nod then + Trigger.RemoveFootprintTrigger(id) + + if Barracks.IsDead or Barracks.Owner ~= GDI then + return + end + + Barracks.Build(InfantrySquad, function(squad) + Utils.Do(squad, function(unit) + if not unit.IsDead then + unit.AttackMove(NorthEntrance.Location) + end + end) + end) + end + end) Utils.Do(Riflemen, function(rifleman) rifleman.Patrol(RiflemenPatrolPath) @@ -162,11 +130,8 @@ function WorldLoaded() PatrollingMammoth.Patrol(MammothPatrolPath) end - -function Tick() - if DateTime.GameTime > 2 then - if player.HasNoRequiredUnits() then - enemy.MarkCompletedObjective(gdiObjective) - end +Tick = function() + if DateTime.GameTime > 2 and Nod.HasNoRequiredUnits() then + GDI.MarkCompletedObjective(GDIObjective) end end diff --git a/mods/cnc/maps/nod10b/rules.yaml b/mods/cnc/maps/nod10b/rules.yaml index ebe6e8f1bc..2917320292 100644 --- a/mods/cnc/maps/nod10b/rules.yaml +++ b/mods/cnc/maps/nod10b/rules.yaml @@ -1,6 +1,6 @@ World: LuaScript: - Scripts: nod10b.lua + Scripts: campaign-global.lua, nod10b.lua MissionData: Briefing: GDI is developing a new, heavily armored tank. Our spies have located the GDI R&D base.\n\nUse your small strike force to locate and penetrate the center. Be sure to destroy the tanks in the base and the factory. BackgroundVideo: kanepre.vqa @@ -15,6 +15,7 @@ World: normal: Normal hard: Hard Default: easy + Locked: false -LegacyBridgeLayer: Player: diff --git a/mods/cnc/mod.yaml b/mods/cnc/mod.yaml index ec37281b08..d5e57bf133 100644 --- a/mods/cnc/mod.yaml +++ b/mods/cnc/mod.yaml @@ -29,6 +29,7 @@ Packages: cnc|bits/jungle cnc|bits/desert cnc|bits/ss + cnc|bits/scripts cnc|uibits MapFolders: diff --git a/mods/cnc/rules/campaign-maprules.yaml b/mods/cnc/rules/campaign-maprules.yaml index 525ce35f8e..d7f9658452 100644 --- a/mods/cnc/rules/campaign-maprules.yaml +++ b/mods/cnc/rules/campaign-maprules.yaml @@ -15,6 +15,13 @@ World: MapOptions: ShortGameCheckboxLocked: True ShortGameCheckboxEnabled: False + ScriptLobbyDropdown@difficulty: + ID: difficulty + Label: Difficulty + Values: + normal: Normal + Default: normal + Locked: true Player: -ConquestVictoryConditions: