diff --git a/mods/cnc/maps/gdi04b/gdi04b.lua b/mods/cnc/maps/gdi04b/gdi04b.lua index 8f539d2073..bafbfd97d9 100644 --- a/mods/cnc/maps/gdi04b/gdi04b.lua +++ b/mods/cnc/maps/gdi04b/gdi04b.lua @@ -1,172 +1,198 @@ -NodxTemplate = { {HandOfNod, {"e1", "e1", "e3", "e3"}} } -AutoTemplate = { {HandOfNod, {"e1", "e1", "e1", "e3", "e3"}} } +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) } +AutoTrigger = { CPos.New(5, 30), CPos.New(6, 30), CPos.New(7, 30), CPos.New(8, 30), CPos.New(9, 30), CPos.New(10, 30), CPos.New(11, 30), CPos.New(12, 30), CPos.New(13, 30) } +GDIHeliTrigger = { CPos.New(11, 11), CPos.New(11, 12), CPos.New(11, 13), CPos.New(11, 14), CPos.New(11, 15), CPos.New(12, 15), CPos.New(13, 15), CPos.New(14, 15), CPos.New(15, 15), CPos.New(16, 15) } + +Hunters = { Hunter1, Hunter2, Hunter3, Hunter4, Hunter5 } +NodxUnits = { "e1", "e1", "e3", "e3" } +AutoUnits = { "e1", "e1", "e1", "e3", "e3" } KillsUntilReinforcements = 12 -kills = 0 -KillCounter = function() kills = kills + 1 end -GDIReinforcements = {"e2", "e2", "e2", "e2"} -GDIReinforcementsWaypoints = {GDIReinforcementsEntry, GDIReinforcementsWP1} +GDIReinforcements = { "e2", "e2", "e2", "e2", "e2" } +GDIReinforcementsWaypoints = { GDIReinforcementsEntry.Location, GDIReinforcementsWP1.Location } -NodHeli = {{HeliEntry, NodHeliLZ}, {"e1", "e1", "e3", "e3"}} +NodHeli = { { HeliEntry.Location, NodHeliLZ.Location }, { "e1", "e1", "e3", "e3" } } -SendHeli = function(heli, func) - Reinforcements.ReinforceWithCargo(nod, "tran", heli[1], heli[2], func) -end - -HeliAction = function(heliActor, team) - Actor.AfterMove(heliActor) - Actor.UnloadCargo(heliActor, true) - Actor.Wait(heliActor, Utils.Seconds(2)) - Actor.ScriptedMove(heliActor, HeliEntry.Location) - Actor.RemoveSelf(heliActor) - - Team.Do(team, function(actor) - Actor.Hunt(actor) - Actor.OnIdle(actor, Actor.Hunt) - Actor.OnKilled(actor, KillCounter) +SendHeli = function(heli) + 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) end) end SendGDIReinforcements = function() - Reinforcements.ReinforceWithCargo(player, "apc", GDIReinforcementsWaypoints, GDIReinforcements, function(apc, team) - Team.Add(team, apc) - Actor.OnKilled(apc, SendGDIReinforcements) - Team.Do(team, function(unit) Actor.SetStance(unit, "Defend") end) + Media.PlaySpeechNotification(gdi, "Reinforce") + Reinforcements.ReinforceWithTransport(gdi, "apc", GDIReinforcements, GDIReinforcementsWaypoints, nil, function(apc, team) + table.insert(team, apc) + Trigger.OnAllKilled(team, function() Trigger.AfterDelay(Utils.Seconds(5), SendGDIReinforcements) end) + Utils.Do(team, function(unit) unit.Stance = "Defend" end) end) end -Build = function(template, repeats, func) - Production.BuildTeamFromTemplate(nod, template, function(team) - Team.Do(team, func) +Build = function(unitTypes, repeats, func) + if HandOfNod.IsDead then + return + end + + local innerFunc = function(units) + Utils.Do(units, func) if repeats then - Team.AddEventHandler(team.OnAllKilled, function() - Build(template, repeats, func) + Trigger.OnAllKilled(units, function() + Build(unitTypes, repeats, func) end) end - end) + end + if not HandOfNod.Build(unitTypes, innerFunc) then + Trigger.AfterDelay(Utils.Seconds(5), function() + Build(unitTypes, repeats, func) + end) + end end BuildNod1 = function() - Build(NodxTemplate, false, function(actor) - Actor.OnKilled(actor, KillCounter) - Actor.Patrol(actor, {waypoint1, waypoint2, waypoint3, waypoint4}, 0, false) - Actor.OnIdle(actor, Actor.Hunt) + Build(NodxUnits, false, function(actor) + Trigger.OnKilled(actor, KillCounter) + actor.Patrol({ waypoint1.Location, waypoint2.Location, waypoint3.Location, waypoint4.Location }, false) + Trigger.OnIdle(actor, actor.Hunt) end) end BuildNod2 = function() - Build(NodxTemplate, false, function(actor) - Actor.OnKilled(actor, KillCounter) - Actor.Patrol(actor, {waypoint1, waypoint2}, 0, false) - Actor.OnIdle(actor, Actor.Hunt) + Build(NodxUnits, false, function(actor) + Trigger.OnKilled(actor, KillCounter) + actor.Patrol({ waypoint1.Location, waypoint2.Location }, false) + Trigger.OnIdle(actor, actor.Hunt) end) end BuildAuto = function() - Build(AutoTemplate, true, function(actor) - Actor.OnKilled(actor, KillCounter) - Actor.OnIdle(actor, Actor.Hunt) + Build(AutoUnits, true, function(actor) + Trigger.OnKilled(actor, KillCounter) + Trigger.OnIdle(actor, actor.Hunt) end) end --- FIXME: replace with real cell trigger when available -CellTrigger = function(player, trigger, radius, func) - local units = Map.FindUnitsInCircle(player, trigger, radius) - if #units > 0 then - func() - end -end - -BhndTriggered = false -Atk1Triggered = false -Atk2Triggered = false -AutoTriggered = false -GDIHeliTriggered = false ReinforcementsSent = false - +kills = 0 +KillCounter = function() kills = kills + 1 end Tick = function() + nod.Cash = 1000 + if not ReinforcementsSent and kills >= KillsUntilReinforcements then ReinforcementsSent = true + gdi.MarkCompletedObjective(reinforcementsObjective) SendGDIReinforcements() end - if Mission.RequiredUnitsAreDestroyed(player) then - OpenRA.RunAfterDelay(Utils.Seconds(1), MissionFailed) - end - - if not BhndTriggered then - CellTrigger(player, BhndTrigger, 2, function() - BhndTriggered = true - SendHeli(NodHeli, HeliAction) - end) - end - - if not Atk1Triggered then - CellTrigger(player, Atk1Trigger, 2, function() - Atk1Triggered = true - BuildNod1() - end) - elseif not Atk2Triggered then - CellTrigger(player, Atk2Trigger, 2, function() - Atk2Triggered = true - BuildNod2() - end) - elseif not AutoTriggered then - CellTrigger(player, AutoTrigger, 2, function() - AutoTriggered = true - BuildAuto() - OpenRA.RunAfterDelay(Utils.Seconds(5), function() - Actor.Hunt(tank) - end) - end) - elseif not GDIHeliTriggered then - CellTrigger(player, HeliTrigger, 2, function() - GDIHeliTriggered = true - Reinforcements.ReinforceWithCargo(player, "tran", {HeliEntry, GDIHeliLZ}, nil, Actor.AfterMove) + if gdi.HasNoRequiredUnits() then + Trigger.AfterDelay(Utils.Seconds(1), function() + gdi.MarkFailedObjective(gdiObjective) end) end end SetupWorld = function() - OpenRA.GiveCash(nod, 10000) - Production.EventHandlers.Setup(nod) - - Utils.Do(Mission.GetGroundAttackersOf(nod), function(unit) - Actor.OnKilled(unit, KillCounter) + Utils.Do(nod.GetGroundAttackers(), function(unit) + Trigger.OnKilled(unit, KillCounter) end) - Utils.Do(Mission.GetGroundAttackersOf(player), function(unit) - Actor.SetStance(unit, "Defend") + Utils.Do(gdi.GetGroundAttackers(), function(unit) + unit.Stance = "Defend" end) - hunters1 = Team.New({Hunter1, Hunter2}) - hunters2 = Team.New({Hunter3, Hunter4, Hunter5}) + Utils.Do(Hunters, function(actor) actor.Hunt() end) - OpenRA.RunAfterDelay(1, function() Team.Do(hunters1, Actor.Hunt) end) - OpenRA.RunAfterDelay(1, function() Team.Do(hunters2, Actor.Hunt) end) - - Actor.OnRemovedFromWorld(crate, MissionAccomplished) + Trigger.OnRemovedFromWorld(crate, function() gdi.MarkCompletedObjective(gdiObjective) end) end WorldLoaded = function() - Media.PlayMovieFullscreen("bkground.vqa", function() Media.PlayMovieFullscreen("nitejump.vqa") end) + gdi = Player.GetPlayer("GDI") + nod = Player.GetPlayer("Nod") - player = OpenRA.GetPlayer("GDI") - nod = OpenRA.GetPlayer("Nod") + Trigger.OnObjectiveAdded(gdi, function(p, id) + Media.DisplayMessage(p.GetObjectiveDescription(id), "New " .. string.lower(p.GetObjectiveType(id)) .. " objective") + end) + 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(gdi, "Win") + Trigger.AfterDelay(Utils.Seconds(1), function() + Media.PlayMovieFullscreen("burdet1.vqa") + end) + end) + + Trigger.OnPlayerLost(gdi, function() + Media.PlaySpeechNotification(gdi, "Lose") + Trigger.AfterDelay(Utils.Seconds(1), function() + Media.PlayMovieFullscreen("gameover.vqa") + end) + end) + + gdiObjective = gdi.AddPrimaryObjective("Retrieve the crate with the stolen rods.") + reinforcementsObjective = gdi.AddSecondaryObjective("Eliminate " .. KillsUntilReinforcements .. " Nod units for reinforcements.") + nod.AddPrimaryObjective("Defend against the GDI forces.") SetupWorld() - OpenRA.SetViewportCenterPosition(GDIReinforcementsWP1.CenterPosition) -end + bhndTrigger = false + Trigger.OnExitedFootprint(BhndTrigger, function(a, id) + if not bhndTrigger and a.Owner == gdi then + bhndTrigger = true + Trigger.RemoveFootprintTrigger(id) + SendHeli(NodHeli) + end + end) -MissionAccomplished = function() - Mission.MissionOver({ player }, nil, true) - Media.PlayMovieFullscreen("burdet1.vqa") -end + atk1Trigger = false + Trigger.OnExitedFootprint(Atk1Trigger, function(a, id) + if not atk1Trigger and a.Owner == gdi then + atk1Trigger = true + Trigger.RemoveFootprintTrigger(id) + BuildNod1() + end + end) -MissionFailed = function() - Mission.MissionOver(nil, { player }, true) - Media.PlayMovieFullscreen("gameover.vqa") + atk2Trigger = false + Trigger.OnEnteredFootprint(Atk2Trigger, function(a, id) + if not atk2Trigger and a.Owner == gdi then + atk2Trigger = true + Trigger.RemoveFootprintTrigger(id) + BuildNod2() + end + end) + + autoTrigger = false + Trigger.OnEnteredFootprint(AutoTrigger, function(a, id) + if not autoTrigger and a.Owner == gdi then + autoTrigger = true + Trigger.RemoveFootprintTrigger(id) + BuildAuto() + Trigger.AfterDelay(Utils.Seconds(4), function() + tank.Hunt() + end) + end + end) + + gdiHeliTrigger = false + Trigger.OnEnteredFootprint(GDIHeliTrigger, function(a, id) + if not gdiHeliTrigger and a.Owner == gdi then + gdiHeliTrigger = true + Trigger.RemoveFootprintTrigger(id) + Reinforcements.ReinforceWithTransport(gdi, "tran", nil, { HeliEntry.Location, GDIHeliLZ.Location }) + end + end) + + Camera.Position = GDIReinforcementsWP1.CenterPosition + + Media.PlayMovieFullscreen("bkground.vqa", function() Media.PlayMovieFullscreen("nitejump.vqa") end) end diff --git a/mods/cnc/maps/gdi04b/map.png b/mods/cnc/maps/gdi04b/map.png index 7884cb3264..4c734350ee 100644 Binary files a/mods/cnc/maps/gdi04b/map.png and b/mods/cnc/maps/gdi04b/map.png differ diff --git a/mods/cnc/maps/gdi04b/map.yaml b/mods/cnc/maps/gdi04b/map.yaml index 6041dc7d15..88b73b290b 100644 --- a/mods/cnc/maps/gdi04b/map.yaml +++ b/mods/cnc/maps/gdi04b/map.yaml @@ -597,21 +597,6 @@ Actors: crate: CRATE Location: 14,13 Owner: Neutral - BhndTrigger: waypoint - Location: 40,21 - Owner: Neutral - Atk1Trigger: waypoint - Location: 35,37 - Owner: Neutral - Atk2Trigger: waypoint - Location: 11,44 - Owner: Neutral - AutoTrigger: waypoint - Location: 12,30 - Owner: Neutral - HeliTrigger: waypoint - Location: 13,15 - Owner: Neutral HeliEntry: waypoint Location: 4,26 Owner: Neutral @@ -626,8 +611,8 @@ Rules: -SpawnMPUnits: -MPStartLocations: -CrateSpawner: - LuaScriptInterface: - LuaScripts: gdi04b.lua + LuaScript: + Scripts: gdi04b.lua ObjectivesPanel: PanelName: MISSION_OBJECTIVES Player: @@ -674,21 +659,20 @@ Rules: GenericVisibility: Enemy, Ally, Neutral GenericStancePrefix: false ShowOwnerRow: false - HARV: - -MustBeDestroyed: E3: AutoTarget: ScanRadius: 5 CRATE: Crate: Lifetime: 9999 - LuaScriptEvents: HealUnitsCrateAction: -RevealMapCrateAction: -GiveMcvCrateAction: -GiveCashCrateAction: -ExplodeCrateAction@fire: -GrantUpgradeCrateAction@cloak: + -DuplicateUnitCrateAction: + ScriptTriggers: Sequences: @@ -696,7 +680,7 @@ VoxelSequences: Weapons: Tiberium: - Warhead: SpreadDamage + Warhead@1Dam: SpreadDamage Damage: 4 Voices: diff --git a/mods/cnc/maps/gdi04c/map.png b/mods/cnc/maps/gdi04c/map.png index 4c734350ee..7884cb3264 100644 Binary files a/mods/cnc/maps/gdi04c/map.png and b/mods/cnc/maps/gdi04c/map.png differ