From 0192919501894b843dbe035293d9ecb3c63f8294 Mon Sep 17 00:00:00 2001 From: Oliver Brakmann Date: Thu, 19 May 2016 23:05:01 +0200 Subject: [PATCH 1/7] Fix crash in Beacon ctor when it runs during instead of between ticks Causes an exception like below, for example when calling the Lua API's Beacon.New() method. ``Exception of type `System.InvalidOperationException`: Collection was modified; enumeration operation may not execute.`` --- OpenRA.Mods.Common/Effects/Beacon.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenRA.Mods.Common/Effects/Beacon.cs b/OpenRA.Mods.Common/Effects/Beacon.cs index dd849486d5..4f1de0ac5c 100644 --- a/OpenRA.Mods.Common/Effects/Beacon.cs +++ b/OpenRA.Mods.Common/Effects/Beacon.cs @@ -55,7 +55,7 @@ namespace OpenRA.Mods.Common.Effects } if (duration > 0) - owner.World.Add(new DelayedAction(duration, () => owner.World.Remove(this))); + owner.World.AddFrameEndTask(w => w.Add(new DelayedAction(duration, () => owner.World.Remove(this)))); } // Support power beacons are expected to clean themselves up From 5d2445a234094f8205df4c09c1bed606618bb5db Mon Sep 17 00:00:00 2001 From: Oliver Brakmann Date: Sun, 20 Mar 2016 23:14:36 +0100 Subject: [PATCH 2/7] Fix winstate logic for cooperative games --- OpenRA.Mods.Common/Traits/Player/MissionObjectives.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/OpenRA.Mods.Common/Traits/Player/MissionObjectives.cs b/OpenRA.Mods.Common/Traits/Player/MissionObjectives.cs index 074079546c..4def486404 100644 --- a/OpenRA.Mods.Common/Traits/Player/MissionObjectives.cs +++ b/OpenRA.Mods.Common/Traits/Player/MissionObjectives.cs @@ -214,8 +214,13 @@ namespace OpenRA.Mods.Common.Traits } if (Info.EarlyGameOver) + { foreach (var p in enemies) - p.PlayerActor.Trait().ForceDefeat(p); + { + p.WinState = WinState.Won; + p.World.OnPlayerWinStateChanged(p); + } + } } } else @@ -224,11 +229,13 @@ namespace OpenRA.Mods.Common.Traits player.World.OnPlayerWinStateChanged(player); if (Info.EarlyGameOver) + { foreach (var p in enemies) { p.WinState = WinState.Won; p.World.OnPlayerWinStateChanged(p); } + } } CheckIfGameIsOver(player); From d743c23482cbd7c64c261e7febd010fd91b6613d Mon Sep 17 00:00:00 2001 From: Oliver Brakmann Date: Wed, 18 May 2016 19:42:14 +0200 Subject: [PATCH 3/7] Add missing `Requires` to MissionObjectiveProperties --- .../Scripting/Properties/MissionObjectiveProperties.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenRA.Mods.Common/Scripting/Properties/MissionObjectiveProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/MissionObjectiveProperties.cs index 521aa3b5f3..7ce1dde2b3 100644 --- a/OpenRA.Mods.Common/Scripting/Properties/MissionObjectiveProperties.cs +++ b/OpenRA.Mods.Common/Scripting/Properties/MissionObjectiveProperties.cs @@ -12,11 +12,12 @@ using Eluant; using OpenRA.Mods.Common.Traits; using OpenRA.Scripting; +using OpenRA.Traits; namespace OpenRA.Mods.Common.Scripting { [ScriptPropertyGroup("MissionObjectives")] - public class MissionObjectiveProperties : ScriptPlayerProperties + public class MissionObjectiveProperties : ScriptPlayerProperties, Requires { readonly MissionObjectives mo; From 735975057d520d39b45da4bf2bf04ba6b54eff9c Mon Sep 17 00:00:00 2001 From: Oliver Brakmann Date: Mon, 2 May 2016 21:51:04 +0200 Subject: [PATCH 4/7] Add another way to call air strikes/paradrops to the Lua API --- .../Scripting/Properties/AirstrikeProperties.cs | 9 +++++++++ .../Scripting/Properties/ParatroopersProperties.cs | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/OpenRA.Mods.Common/Scripting/Properties/AirstrikeProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/AirstrikeProperties.cs index ccd5159c12..d4d1c38faa 100644 --- a/OpenRA.Mods.Common/Scripting/Properties/AirstrikeProperties.cs +++ b/OpenRA.Mods.Common/Scripting/Properties/AirstrikeProperties.cs @@ -32,5 +32,14 @@ namespace OpenRA.Mods.Common.Scripting { ap.SendAirstrike(Self, target, randomize, facing); } + + [Desc("Activate the actor's Airstrike Power.")] + public void SendAirstrikeFrom(CPos from, CPos to) + { + var i = Self.World.Map.CenterOfCell(from); + var j = Self.World.Map.CenterOfCell(to); + + ap.SendAirstrike(Self, j, false, (i - j).Yaw.Facing); + } } } \ No newline at end of file diff --git a/OpenRA.Mods.RA/Scripting/Properties/ParatroopersProperties.cs b/OpenRA.Mods.RA/Scripting/Properties/ParatroopersProperties.cs index d46605832c..62db33c119 100644 --- a/OpenRA.Mods.RA/Scripting/Properties/ParatroopersProperties.cs +++ b/OpenRA.Mods.RA/Scripting/Properties/ParatroopersProperties.cs @@ -32,5 +32,14 @@ namespace OpenRA.Mods.RA.Scripting { return pp.SendParatroopers(Self, target, randomize, facing); } + + [Desc("Activate the actor's Paratroopers Power. Returns the dropped units.")] + public Actor[] SendParatroopersFrom(CPos from, CPos to) + { + var i = Self.World.Map.CenterOfCell(from); + var j = Self.World.Map.CenterOfCell(to); + + return pp.SendParatroopers(Self, j, false, (i - j).Yaw.Facing); + } } } \ No newline at end of file From 09d1dacd95b849aebe5c5595700179b266176488 Mon Sep 17 00:00:00 2001 From: Oliver Brakmann Date: Sun, 15 May 2016 16:38:41 +0200 Subject: [PATCH 5/7] Add a Lua API method to randomize a collection --- OpenRA.Mods.Common/Scripting/Global/UtilsGlobal.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OpenRA.Mods.Common/Scripting/Global/UtilsGlobal.cs b/OpenRA.Mods.Common/Scripting/Global/UtilsGlobal.cs index 50ca3e5add..b5177936cc 100644 --- a/OpenRA.Mods.Common/Scripting/Global/UtilsGlobal.cs +++ b/OpenRA.Mods.Common/Scripting/Global/UtilsGlobal.cs @@ -93,6 +93,12 @@ namespace OpenRA.Mods.Common.Scripting return collection.Random(Context.World.SharedRandom).CopyReference(); } + [Desc("Returns the collection in a random order.")] + public LuaValue[] Shuffle(LuaValue[] collection) + { + return collection.Shuffle(Context.World.SharedRandom).ToArray(); + } + [Desc("Expands the given footprint one step along the coordinate axes, and (if requested) diagonals.")] public CPos[] ExpandFootprint(CPos[] footprint, bool allowDiagonal) { From ebba7fdaf1960ce52a5ccdf9e8dcb0f1dfd88d99 Mon Sep 17 00:00:00 2001 From: Oliver Brakmann Date: Wed, 18 May 2016 19:33:04 +0200 Subject: [PATCH 6/7] Add methods to retrieve player stats to Lua API --- OpenRA.Mods.Common/OpenRA.Mods.Common.csproj | 1 + .../Properties/PlayerStatsProperties.cs | 48 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 OpenRA.Mods.Common/Scripting/Properties/PlayerStatsProperties.cs diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index 59de2a6e3f..9f6d05bf23 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -245,6 +245,7 @@ + diff --git a/OpenRA.Mods.Common/Scripting/Properties/PlayerStatsProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/PlayerStatsProperties.cs new file mode 100644 index 0000000000..3e3b35e7f4 --- /dev/null +++ b/OpenRA.Mods.Common/Scripting/Properties/PlayerStatsProperties.cs @@ -0,0 +1,48 @@ +#region Copyright & License Information +/* + * Copyright 2007-2016 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. + */ +#endregion + +using Eluant; +using OpenRA.Mods.Common.Traits; +using OpenRA.Scripting; +using OpenRA.Traits; + +namespace OpenRA.Mods.Common.Scripting +{ + [ScriptPropertyGroup("Player")] + public class PlayerStatsProperties : ScriptPlayerProperties, Requires + { + readonly PlayerStatistics stats; + + public PlayerStatsProperties(ScriptContext context, Player player) + : base(context, player) + { + stats = player.PlayerActor.Trait(); + } + + [Desc("The combined value of units killed by this player.")] + public int KillsCost { get { return stats.KillsCost; } } + + [Desc("The combined value of all units lost by this player.")] + public int DeathsCost { get { return stats.DeathsCost; } } + + [Desc("The total number of units killed by this player.")] + public int UnitsKilled { get { return stats.UnitsKilled; } } + + [Desc("The total number of units lost by this player.")] + public int UnitsLost { get { return stats.UnitsDead; } } + + [Desc("The total number of buildings killed by this player.")] + public int BuildingsKilled { get { return stats.BuildingsKilled; } } + + [Desc("The total number of buildings lost by this player.")] + public int BuildingsLost { get { return stats.BuildingsDead; } } + } +} \ No newline at end of file From b3dd62b8915dcb016370cc7b21323842c479dcf8 Mon Sep 17 00:00:00 2001 From: Oliver Brakmann Date: Sun, 20 Mar 2016 23:15:36 +0100 Subject: [PATCH 7/7] Add Scott's Allies02 multiplayer mission as "Evacuation" --- OpenRA.sln | 1 + mods/ra/maps/evacuation/evacuation.lua | 363 +++++ mods/ra/maps/evacuation/map.bin | Bin 0 -> 81937 bytes mods/ra/maps/evacuation/map.png | Bin 0 -> 17580 bytes mods/ra/maps/evacuation/map.yaml | 1757 ++++++++++++++++++++++++ mods/ra/maps/evacuation/rules.yaml | 217 +++ 6 files changed, 2338 insertions(+) create mode 100644 mods/ra/maps/evacuation/evacuation.lua create mode 100644 mods/ra/maps/evacuation/map.bin create mode 100644 mods/ra/maps/evacuation/map.png create mode 100644 mods/ra/maps/evacuation/map.yaml create mode 100644 mods/ra/maps/evacuation/rules.yaml diff --git a/OpenRA.sln b/OpenRA.sln index 5da7941277..3ada58d6ec 100644 --- a/OpenRA.sln +++ b/OpenRA.sln @@ -68,6 +68,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Red Alert Lua scripts", "Re mods\ra\maps\fort-lonestar\fort-lonestar.lua = mods\ra\maps\fort-lonestar\fort-lonestar.lua mods\ra\maps\intervention\intervention.lua = mods\ra\maps\intervention\intervention.lua mods\ra\maps\monster-tank-madness\monster-tank-madness.lua = mods\ra\maps\monster-tank-madness\monster-tank-madness.lua + mods\ra\maps\evacuation\evacuation.lua = mods\ra\maps\evacuation\evacuation.lua mods\ra\maps\soviet-01\soviet01.lua = mods\ra\maps\soviet-01\soviet01.lua mods\ra\maps\soviet-02a\soviet02a.lua = mods\ra\maps\soviet-02a\soviet02a.lua mods\ra\maps\soviet-02b\soviet02b.lua = mods\ra\maps\soviet-02b\soviet02b.lua diff --git a/mods/ra/maps/evacuation/evacuation.lua b/mods/ra/maps/evacuation/evacuation.lua new file mode 100644 index 0000000000..72634e0587 --- /dev/null +++ b/mods/ra/maps/evacuation/evacuation.lua @@ -0,0 +1,363 @@ +DeathThreshold = +{ + Easy = 200, + Normal = 100, +} + +TanyaType = "e7" +TanyaStance = "AttackAnything" +if Map.Difficulty ~= "Easy" then + TanyaType = "e7.noautotarget" + TanyaStance = "HoldFire" +end + +RepairTriggerThreshold = +{ + Easy = 50, + Normal = 75, +} + +Sams = { Sam1, Sam2, Sam3, Sam4 } +TownUnits = +{ + Einstein, Engineer, + TownUnit01, TownUnit02, TownUnit03, TownUnit04, TownUnit05, TownUnit06, TownUnit07, + TownUnit08, TownUnit09, TownUnit10, TownUnit11, TownUnit12, TownUnit13, TownUnit14, +} + +ParabombDelay = DateTime.Seconds(30) +ParatroopersDelay = DateTime.Minutes(5) +Paratroopers = +{ + { + proxy = "powerproxy.paras1", + entry = BadgerEntryPoint1.Location, + drop = BadgerDropPoint1.Location, + }, + { + proxy = "powerproxy.paras2", + entry = BadgerEntryPoint1.Location + CVec.New(3, 0), + drop = BadgerDropPoint2.Location, + }, + { + proxy = "powerproxy.paras2", + entry = BadgerEntryPoint1.Location + CVec.New(6, 0), + drop = BadgerDropPoint3.Location, + }, +} + +AttackGroup = { } +AttackGroupSize = 5 +SovietInfantry = { "e1", "e2", "e3" } +SovietVehiclesUpgradeDelay = DateTime.Minutes(4) +SovietVehicleType = "Normal" +SovietVehicles = +{ + Normal = { "3tnk" }, + Upgraded = { "3tnk", "v2rl" }, +} +ProductionInterval = +{ + Easy = DateTime.Seconds(10), + Normal = DateTime.Seconds(2), +} + +ReinforcementsDelay = DateTime.Minutes(16) +ReinforcementsUnits = { "2tnk", "2tnk", "2tnk", "2tnk", "2tnk", "2tnk", "1tnk", "1tnk", "jeep", "e1", + "e1", "e1", "e1", "e3", "e3", "mcv", "truk", "truk", "truk", "truk", "truk", "truk" } + +SpawnAlliedReinforcements = function() + if allies2.IsLocalPlayer then + UserInterface.SetMissionText("") + Media.PlaySpeechNotification(allies2, "AlliedReinforcementsArrived") + end + Reinforcements.Reinforce(allies2, ReinforcementsUnits, { ReinforcementsEntryPoint.Location, Allies2BasePoint.Location }) +end + +Yak = nil +YakAttack = function(yak) + local targets = Map.ActorsInCircle(YakAttackPoint.CenterPosition, WDist.FromCells(10), function(a) + return a.Owner == allies1 and not a.IsDead and a ~= Einstein and a ~= Tanya and a ~= Engineer + end) + + if (#targets > 0) then + yak.Attack(Utils.Random(targets)) + end + yak.Move(Map.ClosestEdgeCell(yak.Location)) + yak.Destroy() + Trigger.OnRemovedFromWorld(Yak, function() + Yak = nil + end) +end + +SovietTownAttack = function() + local units = Utils.Shuffle(Utils.Where(Map.ActorsWithTag("TownAttacker"), function(a) return not a.IsDead end)) + + Utils.Do(Utils.Take(5, units), function(unit) + unit.AttackMove(TownPoint.Location) + Trigger.OnIdle(unit, unit.Hunt) + end) +end + +SendParabombs = function() + local proxy = Actor.Create("powerproxy.parabombs", false, { Owner = soviets }) + proxy.SendAirstrikeFrom(BadgerEntryPoint2.Location, ParabombPoint1.Location) + proxy.SendAirstrikeFrom(BadgerEntryPoint2.Location + CVec.New(0, 3), ParabombPoint2.Location) + proxy.Destroy() +end + +SendParatroopers = function() + Utils.Do(Paratroopers, function(para) + local proxy = Actor.Create(para.proxy, false, { Owner = soviets }) + local units = proxy.SendParatroopersFrom(para.entry, para.drop) + proxy.Destroy() + + Utils.Do(units, function(unit) + Trigger.OnIdle(unit, function(a) + if a.IsInWorld then + a.Hunt() + end + end) + end) + end) +end + +SendAttackGroup = function() + if #AttackGroup < AttackGroupSize then + return + end + + Utils.Do(AttackGroup, function(unit) + if not unit.IsDead then + Trigger.OnIdle(unit, unit.Hunt) + end + end) + + AttackGroup = { } +end + +ProduceInfantry = function() + if SovietBarracks.IsDead or SovietBarracks.Owner ~= soviets then + return + end + + soviets.Build({ Utils.Random(SovietInfantry) }, function(units) + table.insert(AttackGroup, units[1]) + SendAttackGroup() + Trigger.AfterDelay(ProductionInterval[Map.Difficulty], ProduceInfantry) + end) +end + +ProduceVehicles = function() + if SovietWarFactory.IsDead or SovietWarFactory.Owner ~= soviets then + return + end + + soviets.Build({ Utils.Random(SovietVehicles[SovietVehicleType]) }, function(units) + table.insert(AttackGroup, units[1]) + SendAttackGroup() + Trigger.AfterDelay(ProductionInterval[Map.Difficulty], ProduceVehicles) + end) +end + +NumBaseBuildings = function() + local buildings = Map.ActorsInBox(AlliedBaseTopLeft.CenterPosition, AlliedBaseBottomRight.CenterPosition, function(a) + return not a.IsDead and a.Owner == allies2 and a.HasProperty("StartBuildingRepairs") + end) + + return #buildings +end + +Tick = function() + if DateTime.GameTime > 1 and DateTime.GameTime % 25 == 0 and NumBaseBuildings() == 0 then + allies2.MarkFailedObjective(objHoldPosition) + end + + if not allies2.IsObjectiveCompleted(objCutSovietPower) and soviets.PowerState ~= "Normal" then + allies2.MarkCompletedObjective(objCutSovietPower) + end + + if not allies2.IsObjectiveCompleted(objLimitLosses) and allies2.UnitsLost > DeathThreshold[Map.Difficulty] then + allies2.MarkFailedObjective(objLimitLosses) + end + + if allies2.IsLocalPlayer and DateTime.GameTime <= ReinforcementsDelay then + UserInterface.SetMissionText("Allied reinforcements arrive in " .. Utils.FormatTime(ReinforcementsDelay - DateTime.GameTime)) + else + UserInterface.SetMissionText("") + end +end + +SetupSoviets = function() + soviets.Cash = 1000 + + if Map.Difficulty == "Easy" then + Utils.Do(Sams, function(sam) + local camera = Actor.Create("Camera.SAM", true, { Owner = allies1, Location = sam.Location }) + Trigger.OnKilledOrCaptured(sam, function() + camera.Destroy() + end) + end) + end + + local buildings = Utils.Where(Map.ActorsInWorld, function(self) return self.Owner == soviets and self.HasProperty("StartBuildingRepairs") end) + Utils.Do(buildings, function(actor) + Trigger.OnDamaged(actor, function(building) + if building.Owner == soviets and building.Health < (building.MaxHealth * RepairTriggerThreshold[Map.Difficulty] / 100) then + building.StartBuildingRepairs() + end + end) + end) + + SovietBarracks.IsPrimaryBuilding = true + SovietBarracks.RallyPoint = SovietRallyPoint.Location + SovietWarFactory.IsPrimaryBuilding = true + SovietWarFactory.RallyPoint = SovietRallyPoint.Location + + Trigger.AfterDelay(SovietVehiclesUpgradeDelay, function() SovietVehicleType = "Upgraded" end) + Trigger.AfterDelay(0, function() + ProduceInfantry() + ProduceVehicles() + end) +end + +SetupTriggers = function() + Trigger.OnKilled(Tanya, function() + allies1.MarkFailedObjective(objTanyaMustSurvive) + end) + + Trigger.OnAllKilledOrCaptured(Sams, function() + allies1.MarkCompletedObjective(objDestroySamSites) + objExtractEinstein = allies1.AddPrimaryObjective("Wait for a helicopter at the LZ and extract Einstein.") + Actor.Create("flare", true, { Owner = allies1, Location = ExtractionLZ.Location + CVec.New(1, -1) }) + Beacon.New(allies1, ExtractionLZ.CenterPosition) + Media.PlaySpeechNotification(allies1, "SignalFlareNorth") + + ExtractionHeli = Reinforcements.ReinforceWithTransport(allies1, "tran", nil, { ExtractionLZEntryPoint.Location, ExtractionLZ.Location })[1] + Trigger.OnKilled(ExtractionHeli, function() + allies1.MarkFailedObjective(objExtractEinstein) + end) + Trigger.OnPassengerEntered(ExtractionHeli, function(heli, passenger) + if passenger == Einstein then + heli.Move(ExtractionLZEntryPoint.Location) + heli.Destroy() + Trigger.OnRemovedFromWorld(heli, function() + allies2.MarkCompletedObjective(objLimitLosses) + allies2.MarkCompletedObjective(objHoldPosition) + allies1.MarkCompletedObjective(objTanyaMustSurvive) + allies1.MarkCompletedObjective(objEinsteinSurvival) + allies1.MarkCompletedObjective(objExtractEinstein) + end) + end + end) + end) + + Trigger.OnEnteredProximityTrigger(TownPoint.CenterPosition, WDist.FromCells(15), function(actor, trigger) + if actor.Owner == allies1 then + ReassignActors(TownUnits, neutral, allies1) + Utils.Do(TownUnits, function(a) a.Stance = "Defend" end) + allies1.MarkCompletedObjective(objFindEinstein) + objEinsteinSurvival = allies1.AddPrimaryObjective("Keep Einstein alive at all costs.") + Trigger.OnKilled(Einstein, function() + allies1.MarkFailedObjective(objEinsteinSurvival) + end) + Trigger.RemoveProximityTrigger(trigger) + SovietTownAttack() + end + end) + + Trigger.OnEnteredProximityTrigger(YakAttackPoint.CenterPosition, WDist.FromCells(5), function(actor, trigger) + if not (Yak == nil or Yak.IsDead) or actor.Owner ~= allies1 then + return + end + + Yak = Reinforcements.Reinforce(soviets, { "yak" }, { YakEntryPoint.Location, YakAttackPoint.Location + CVec.New(0, -10) }, 0, YakAttack)[1] + end) + + Trigger.AfterDelay(ParabombDelay, SendParabombs) + Trigger.AfterDelay(ParatroopersDelay, SendParatroopers) + Trigger.AfterDelay(ReinforcementsDelay, SpawnAlliedReinforcements) +end + +SpawnTanya = function() + Tanya = Actor.Create(TanyaType, true, { Owner = allies1, Location = TanyaLocation.Location }) + Tanya.Stance = TanyaStance + + if Map.Difficulty ~= "Easy" and allies1.IsLocalPlayer then + Trigger.AfterDelay(DateTime.Seconds(2), function() + Media.DisplayMessage("According to the rules of engagement I need your explicit orders to fire, Commander!", "Tanya") + end) + end +end + +ReassignActors = function(actors, from, to) + Utils.Do(actors, function(a) + if a.Owner == from then + a.Owner = to + a.Stance = "Defend" + end + end) +end + +WorldLoaded = function() + neutral = Player.GetPlayer("Neutral") + + -- Allies is the pre-set owner of units that get assigned to either the second player, if any, or the first player otherwise. + allies = Player.GetPlayer("Allies") + + -- Allies1 is the player starting on the right, controlling Tanya + allies1 = Player.GetPlayer("Allies1") + + -- Allies2 is the player starting on the left, defending the base + allies2 = Player.GetPlayer("Allies2") + + soviets = Player.GetPlayer("Soviets") + + Utils.Do({ allies1, allies2 }, function(player) + if player and player.IsLocalPlayer then + 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, "MissionAccomplished") + end) + + Trigger.OnPlayerLost(player, function() + Media.PlaySpeechNotification(player, "MissionFailed") + end) + end + end) + + if not allies2 or allies2.IsLocalPlayer then + Camera.Position = Allies2BasePoint.CenterPosition + else + Camera.Position = ChinookHusk.CenterPosition + end + + if not allies2 then + allies2 = allies1 + end + + ReassignActors(Map.ActorsInWorld, allies, allies2) + SpawnTanya() + + objTanyaMustSurvive = allies1.AddPrimaryObjective("Tanya must survive.") + objFindEinstein = allies1.AddPrimaryObjective("Find Einstein's crashed helicopter.") + objDestroySamSites = allies1.AddPrimaryObjective("Destroy the SAM sites.") + + objHoldPosition = allies2.AddPrimaryObjective("Hold your position and protect the base.") + objLimitLosses = allies2.AddSecondaryObjective("Do not lose more than " .. DeathThreshold[Map.Difficulty] .. " units.") + objCutSovietPower = allies2.AddSecondaryObjective("Take out the Soviet power grid.") + + SetupTriggers() + SetupSoviets() +end \ No newline at end of file diff --git a/mods/ra/maps/evacuation/map.bin b/mods/ra/maps/evacuation/map.bin new file mode 100644 index 0000000000000000000000000000000000000000..45e732c5499c4841decce1ac1f4c00d326b690c7 GIT binary patch literal 81937 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 literal 0 HcmV?d00001 diff --git a/mods/ra/maps/evacuation/map.png b/mods/ra/maps/evacuation/map.png new file mode 100644 index 0000000000000000000000000000000000000000..29bfd56141d446cc276292d22b5c68bcf60f7e55 GIT binary patch literal 17580 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