diff --git a/OpenRA.Mods.RA/Missions/Allies03Script.cs b/OpenRA.Mods.RA/Missions/Allies03Script.cs index 1fb042e246..3bc6cdc782 100644 --- a/OpenRA.Mods.RA/Missions/Allies03Script.cs +++ b/OpenRA.Mods.RA/Missions/Allies03Script.cs @@ -214,6 +214,8 @@ namespace OpenRA.Mods.RA.Missions if (!world.Actors.Any(a => (a.Owner == allies1 || a.Owner == allies2) && a.IsInWorld && !a.IsDead() && ((a.HasTrait() && !a.HasTrait()) || a.HasTrait()))) { + objectives[EvacuateID].Status = ObjectiveStatus.Failed; + OnObjectivesUpdated(true); MissionFailed("The remaining Allied forces in the area have been wiped out."); } } diff --git a/OpenRA.Mods.RA/Missions/Allies04Script.cs b/OpenRA.Mods.RA/Missions/Allies04Script.cs index cbd7e95f14..50afce34f6 100644 --- a/OpenRA.Mods.RA/Missions/Allies04Script.cs +++ b/OpenRA.Mods.RA/Missions/Allies04Script.cs @@ -8,10 +8,14 @@ */ #endregion +using System; using System.Collections.Generic; +using System.Drawing; using System.Linq; using OpenRA.FileFormats; using OpenRA.Mods.RA.Activities; +using OpenRA.Mods.RA.Air; +using OpenRA.Mods.RA.Buildings; using OpenRA.Mods.RA.Render; using OpenRA.Network; using OpenRA.Traits; @@ -28,11 +32,13 @@ namespace OpenRA.Mods.RA.Missions Dictionary objectives = new Dictionary { - { InfilitrateID, new Objective(ObjectiveType.Primary, Infiltrate, ObjectiveStatus.InProgress) } + { InfiltrateID, new Objective(ObjectiveType.Primary, "", ObjectiveStatus.InProgress) }, + { DestroyID, new Objective(ObjectiveType.Primary, "Secure the Soviet research laboratory and destroy the rest of the Soviet base.", ObjectiveStatus.Inactive) } }; - const int InfilitrateID = 0; - const string Infiltrate = "The Soviets are currently developing a new defensive system named the \"Iron Curtain\" at their main research laboratories. Get our Spy into their main research laboratories."; + const int InfiltrateID = 0; + const int DestroyID = 1; + const string Infiltrate = "The Soviets are currently developing a new defensive system named the \"Iron Curtain\" at their main research laboratories. Get our {0} into the Soviet research laboratories undetected."; Actor lstEntryPoint; Actor lstUnloadPoint; @@ -41,11 +47,14 @@ namespace OpenRA.Mods.RA.Missions Actor baseGuard; Actor baseGuardMovePos; Actor baseGuardTruckPos; - int baseGuardWait = 100; - bool baseGuardMoved; + Actor lab; + int baseGuardTicks = 100; Actor allies1Spy; Actor allies2Spy; + bool allies1SpyInfiltratedLab; + bool allies2SpyInfiltratedLab; + int frameInfiltrated = -1; Player allies; Player allies1; @@ -72,12 +81,58 @@ namespace OpenRA.Mods.RA.Missions CPos[] patrolPoints5; int currentPatrolPoint5; + CPos hind1EntryPoint; + PPos[] hind1Points; + CPos hind1ExitPoint; + + Actor reinforcementsEntryPoint; + Actor reinforcementsUnloadPoint; + + void MissionFailed(string text) + { + if (allies1.WinState != WinState.Undefined) + { + return; + } + allies1.WinState = allies2.WinState = WinState.Lost; + foreach (var actor in world.Actors.Where(a => a.IsInWorld && (a.Owner == allies1 || a.Owner == allies2) && !a.IsDead())) + { + actor.Kill(actor); + } + Game.AddChatLine(Color.Red, "Mission failed", text); + Sound.Play("misnlst1.aud"); + } + + void MissionAccomplished(string text) + { + if (allies1.WinState != WinState.Undefined) + { + return; + } + allies1.WinState = allies2.WinState = WinState.Won; + Game.AddChatLine(Color.Blue, "Mission accomplished", text); + Sound.Play("misnwon1.aud"); + } + public void Tick(Actor self) { + if (allies1.WinState != WinState.Undefined) + { + return; + } if (world.FrameNumber == 1) { InsertSpies(); } + if (world.FrameNumber == 600) + { + SendHind(hind1EntryPoint, hind1Points, hind1ExitPoint); + } + if (frameInfiltrated != -1 && world.FrameNumber == frameInfiltrated + 100) + { + Sound.Play("aarrivs1.aud"); + world.AddFrameEndTask(w => SendReinforcements()); + } PatrolTick(ref patrol1, ref currentPatrolPoint1, soviets, DogPatrol, patrolPoints1); PatrolTick(ref patrol2, ref currentPatrolPoint2, soviets, InfantryPatrol, patrolPoints2); PatrolTick(ref patrol3, ref currentPatrolPoint3, soviets, DogPatrol, patrolPoints3); @@ -85,6 +140,29 @@ namespace OpenRA.Mods.RA.Missions PatrolTick(ref patrol5, ref currentPatrolPoint5, soviets, DogPatrol, patrolPoints5); ManageSovietOre(); BaseGuardTick(); + if (allies1Spy.IsDead() || (allies2Spy != null && allies2Spy.IsDead())) + { + objectives[InfiltrateID].Status = ObjectiveStatus.Failed; + OnObjectivesUpdated(true); + MissionFailed("{0} spy was killed.".F(allies1 != allies2 ? "A" : "The")); + } + else if (lab.Destroyed) + { + MissionFailed("The research laboratory was destroyed."); + } + else if (!world.Actors.Any(a => (a.Owner == allies1 || a.Owner == allies2) && !a.IsDead() && (a.HasTrait() && !a.HasTrait()) || a.HasTrait())) + { + objectives[DestroyID].Status = ObjectiveStatus.Failed; + OnObjectivesUpdated(true); + MissionFailed("The remaining Allied forces in the area have been wiped out."); + } + else if (!world.Actors.Any(a => a.Owner == soviets && a.IsInWorld && !a.IsDead() && a.HasTrait() && !a.HasTrait() && a != lab) + && objectives[InfiltrateID].Status == ObjectiveStatus.Completed) + { + objectives[DestroyID].Status = ObjectiveStatus.Completed; + OnObjectivesUpdated(true); + MissionAccomplished("The Soviet research laboratory has been secured successfully."); + } } void ManageSovietOre() @@ -96,21 +174,54 @@ namespace OpenRA.Mods.RA.Missions void BaseGuardTick() { - if (!baseGuardMoved && !baseGuard.IsDead() && baseGuard.IsInWorld) + if (baseGuardTicks <= 0 || baseGuard.IsDead() || !baseGuard.IsInWorld) { - if (hijackTruck.Location == baseGuardTruckPos.Location) + return; + } + if (hijackTruck.Location == baseGuardTruckPos.Location) + { + if (--baseGuardTicks <= 0) { - if (--baseGuardWait <= 0) - { - baseGuard.QueueActivity(new Move.Move(baseGuardMovePos.Location)); - baseGuardMoved = true; - } - } - else - { - baseGuardWait = 100; + baseGuard.QueueActivity(new Move.Move(baseGuardMovePos.Location)); } } + else + { + baseGuardTicks = 100; + } + } + + void OnLabInfiltrated(Actor spy) + { + if (spy == allies1Spy) { allies1SpyInfiltratedLab = true; } + else if (spy == allies2Spy) { allies2SpyInfiltratedLab = true; } + if (allies1SpyInfiltratedLab && (allies2SpyInfiltratedLab || allies2Spy == null)) + { + objectives[InfiltrateID].Status = ObjectiveStatus.Completed; + objectives[DestroyID].Status = ObjectiveStatus.InProgress; + OnObjectivesUpdated(true); + frameInfiltrated = world.FrameNumber; + } + } + + void SendReinforcements() + { + var lst = world.CreateActor("lst", new TypeDictionary + { + new OwnerInit(allies1), + new LocationInit(reinforcementsEntryPoint.Location) + }); + lst.Trait().Load(lst, world.CreateActor(false, "mcv", new TypeDictionary { new OwnerInit(allies1) } )); + if (allies1 != allies2) + { + lst.Trait().Load(lst, world.CreateActor(false, "mcv", new TypeDictionary { new OwnerInit(allies2) })); + } + lst.QueueActivity(new Move.Move(reinforcementsUnloadPoint.Location)); + lst.QueueActivity(new Wait(10)); + lst.QueueActivity(new UnloadCargo(true)); + lst.QueueActivity(new Wait(10)); + lst.QueueActivity(new Move.Move(reinforcementsEntryPoint.Location)); + lst.QueueActivity(new RemoveSelf()); } void PatrolTick(ref Actor[] patrolActors, ref int currentPoint, Player owner, string[] actorNames, CPos[] points) @@ -134,6 +245,22 @@ namespace OpenRA.Mods.RA.Missions } } + void SendHind(CPos start, IEnumerable points, CPos exit) + { + var hind = world.CreateActor("hind", new TypeDictionary + { + new OwnerInit(soviets), + new LocationInit(start), + new FacingInit(Util.GetFacing(points.First().ToCPos() - start, 0)), + new AltitudeInit(Rules.Info["hind"].Traits.Get().CruiseAltitude), + }); + foreach (var point in points.Concat(new[] { Util.CenterOfCell(exit) })) + { + hind.QueueActivity(new AttackMove.AttackMoveActivity(hind, new HeliFly(point))); + } + hind.QueueActivity(new RemoveSelf()); + } + void InsertSpies() { var lst = world.CreateActor("lst", new TypeDictionary @@ -190,7 +317,7 @@ namespace OpenRA.Mods.RA.Missions baseGuard = actors["BaseGuard"]; baseGuardMovePos = actors["BaseGuardMovePos"]; baseGuardTruckPos = actors["BaseGuardTruckPos"]; - patrolPoints1 = new[] + patrolPoints1 = new[] { actors["PatrolPoint11"].Location, actors["PatrolPoint12"].Location, @@ -199,7 +326,7 @@ namespace OpenRA.Mods.RA.Missions actors["PatrolPoint15"].Location }; patrolPoints2 = patrolPoints1; - patrolPoints3 = new[] + patrolPoints3 = new[] { actors["PatrolPoint21"].Location, actors["PatrolPoint22"].Location, @@ -207,14 +334,14 @@ namespace OpenRA.Mods.RA.Missions actors["PatrolPoint24"].Location, actors["PatrolPoint25"].Location }; - patrolPoints4 = new[] + patrolPoints4 = new[] { actors["PatrolPoint31"].Location, actors["PatrolPoint32"].Location, actors["PatrolPoint33"].Location, actors["PatrolPoint34"].Location }; - patrolPoints5 = new[] + patrolPoints5 = new[] { actors["PatrolPoint41"].Location, actors["PatrolPoint42"].Location, @@ -222,6 +349,19 @@ namespace OpenRA.Mods.RA.Missions actors["PatrolPoint44"].Location, actors["PatrolPoint45"].Location }; + lab = actors["Lab"]; + lab.AddTrait(new Allies04InfiltrateAction(OnLabInfiltrated)); + hind1EntryPoint = actors["Hind1EntryPoint"].Location; + hind1Points = new[] + { + actors["Hind1Point1"].CenterLocation, + actors["Hind1Point2"].CenterLocation + }; + hind1ExitPoint = actors["Hind1ExitPoint"].Location; + reinforcementsEntryPoint = actors["ReinforcementsEntryPoint"]; + reinforcementsUnloadPoint = actors["ReinforcementsUnloadPoint"]; + objectives[InfiltrateID].Text = Infiltrate.F(allies1 != allies2 ? "spies" : "spy"); + OnObjectivesUpdated(false); SetupSubStances(); Game.MoveViewport(lstEntryPoint.Location.ToFloat2()); PlayMusic(); @@ -305,4 +445,19 @@ namespace OpenRA.Mods.RA.Missions return r.Select(a => a.WithPalette(Palette(hijackable.OldOwner))); } } + + class Allies04InfiltrateAction : IAcceptSpy + { + Action a; + + public Allies04InfiltrateAction(Action a) + { + this.a = a; + } + + public void OnInfiltrate(Actor self, Actor spy) + { + a(spy); + } + } } diff --git a/mods/ra/maps/allies-04/map.bin b/mods/ra/maps/allies-04/map.bin index fb3d17940f..588d076940 100644 Binary files a/mods/ra/maps/allies-04/map.bin and b/mods/ra/maps/allies-04/map.bin differ diff --git a/mods/ra/maps/allies-04/map.yaml b/mods/ra/maps/allies-04/map.yaml index 272d9964e5..1cdd75a343 100644 --- a/mods/ra/maps/allies-04/map.yaml +++ b/mods/ra/maps/allies-04/map.yaml @@ -147,8 +147,8 @@ Actors: Actor66: tc03 Location: 87,89 Owner: Neutral - Actor77: t16 - Location: 103,84 + Actor77: mine + Location: 96,85 Owner: Neutral Actor78: tc04 Location: 103,78 @@ -177,7 +177,7 @@ Actors: Actor51: barr Location: 93,70 Owner: Soviets - Actor3: miss + Lab: miss Location: 34,28 Owner: Soviets Actor45: brik @@ -890,7 +890,7 @@ Actors: Location: 91,43 Owner: Neutral Actor277: wood - Location: 86,45 + Location: 89,45 Owner: Neutral Actor278: wood Location: 87,45 @@ -1286,9 +1286,6 @@ Actors: Actor312: t17 Location: 88,100 Owner: Neutral - Actor407: t05 - Location: 75,98 - Owner: Neutral PatrolPoint13: waypoint Location: 81,86 Owner: Neutral @@ -1319,14 +1316,14 @@ Actors: Actor409: e1 Location: 76,59 Owner: Soviets - Actor410: e1 - Location: 78,59 + Actor410: v2rl + Location: 74,59 Owner: Soviets - Actor411: dog - Location: 75,58 + Actor3: dog + Location: 74,52 Owner: Soviets - Actor412: sbag - Location: 76,60 + Actor416: dog + Location: 82,73 Owner: Soviets Actor413: sbag Location: 75,60 @@ -1334,11 +1331,11 @@ Actors: Actor414: sbag Location: 74,60 Owner: Soviets - Actor415: sbag - Location: 78,60 + Actor412: proc + Location: 84,68 Owner: Soviets - Actor416: sbag - Location: 79,60 + Actor472: brl3 + Location: 77,101 Owner: Soviets Actor417: sbag Location: 73,60 @@ -1449,6 +1446,165 @@ Actors: BaseGuardTruckPos: waypoint Location: 64,36 Owner: Neutral + Hind1EntryPoint: waypoint + Location: 88,111 + Owner: Neutral + Hind1Point1: waypoint + Location: 67,91 + Owner: Neutral + Hind1Point2: waypoint + Location: 61,68 + Owner: Neutral + Hind1ExitPoint: waypoint + Location: 80,16 + Owner: Neutral + Actor411: e2 + Location: 73,53 + Owner: Soviets + Actor434: e1 + Location: 94,54 + Owner: Soviets + Actor435: dog + Location: 95,54 + Owner: Soviets + Actor436: e1 + Location: 82,44 + Owner: Soviets + Actor437: e1 + Location: 80,43 + Owner: Soviets + Actor438: dog + Location: 81,43 + Owner: Soviets + Actor439: e1 + Location: 109,48 + Owner: Soviets + Actor440: dog + Location: 108,48 + Owner: Soviets + Actor441: 3tnk + Location: 108,47 + Owner: Soviets + Actor442: brl3 + Location: 82,65 + Owner: Soviets + Actor443: brl3 + Location: 82,66 + Owner: Soviets + Actor444: barl + Location: 83,67 + Owner: Soviets + Actor445: brl3 + Location: 88,65 + Owner: Soviets + Actor446: barl + Location: 89,66 + Owner: Soviets + Actor447: barl + Location: 87,67 + Owner: Soviets + Actor448: brl3 + Location: 89,67 + Owner: Soviets + Actor450: barl + Location: 109,28 + Owner: Soviets + Actor449: brl3 + Location: 107,27 + Owner: Soviets + Actor454: e2 + Location: 38,32 + Owner: Soviets + Actor451: barl + Location: 108,29 + Owner: Soviets + Actor453: brl3 + Location: 38,31 + Owner: Soviets + Actor452: brl3 + Location: 38,36 + Owner: Soviets + Actor455: silo + Location: 82,67 + Owner: Soviets + Actor456: e1 + Location: 85,66 + Owner: Soviets + Actor457: t06 + Location: 101,92 + Owner: Neutral + Actor458: dog + Location: 57,88 + Owner: Soviets + Actor459: e1 + Location: 79,102 + Owner: Soviets + Actor460: sbag + Location: 80,103 + Owner: Soviets + Actor462: hpad + Location: 75,100 + Owner: Soviets + Actor463: sbag + Location: 79,103 + Owner: Soviets + Actor464: sbag + Location: 78,103 + Owner: Soviets + Actor465: sbag + Location: 77,103 + Owner: Soviets + Actor466: sbag + Location: 76,103 + Owner: Soviets + Actor467: sbag + Location: 76,102 + Owner: Soviets + Actor468: sbag + Location: 75,102 + Owner: Soviets + Actor469: sbag + Location: 74,102 + Owner: Soviets + Actor470: sbag + Location: 74,101 + Owner: Soviets + Actor471: powr + Location: 79,98 + Owner: Soviets + Actor415: sam + Location: 77,102 + Owner: Soviets + Actor475: brl3 + Location: 79,97 + Owner: Soviets + Actor407: ftur + Location: 76,98 + Owner: Soviets + Actor473: barl + Location: 78,98 + Owner: Soviets + Actor461: e2 + Location: 78,97 + Owner: Soviets + Actor481: fenc + Location: 82,99 + Owner: Soviets + Actor482: fenc + Location: 82,100 + Owner: Soviets + Actor483: fenc + Location: 81,99 + Owner: Soviets + Actor484: fenc + Location: 81,98 + Owner: Soviets + ReinforcementsEntryPoint: waypoint + Location: 92,111 + Owner: Neutral + ReinforcementsUnloadPoint: waypoint + Location: 92,103 + Owner: Neutral Smudges: @@ -1466,7 +1622,7 @@ Rules: -Selectable: SPY: RevealsShroud: - Range: 10 + Range: 8 Health: HP: 100 DontDestroyWhenInfiltrating: @@ -1515,9 +1671,107 @@ Rules: Mobile: Speed: 9 RevealsShroud: - Range: 10 + Range: 8 AttackMove: JustMove: yes + HIND: + AutoTarget: + E7: + Buildable: + Owner: None + TRAN: + Buildable: + Owner: None + BARR: + Buildable: + Owner: None + MIG: + Buildable: + Owner: None + HELI: + Buildable: + Owner: None + SS: + Buildable: + Owner: None + ARTY: + Buildable: + Owner: None + AGUN: + Buildable: + Owner: None + MSUB: + Buildable: + Owner: None + CA: + Buildable: + Owner: None + MSLO: + Buildable: + Owner: None + SPEN: + Buildable: + Owner: None + IRON: + Buildable: + Owner: None + PDOX: + Buildable: + Owner: None + TSLA: + Buildable: + Owner: None + FTUR: + Buildable: + Owner: None + SAM: + Buildable: + Owner: None + HPAD: + Buildable: + Owner: None + AFLD: + Buildable: + Owner: None + ATEK: + Buildable: + Owner: None + STEK: + Buildable: + Owner: None + 4TNK: + Buildable: + Owner: None + MCV: + Buildable: + Owner: None + APC: + Buildable: + Owner: None + MNLY.AP: + Buildable: + Owner: None + MNLY.AT: + Buildable: + Owner: None + TRUK: + Buildable: + Owner: None + TTNK: + Buildable: + Owner: None + FTRK: + Buildable: + Owner: None + CTNK: + Buildable: + Owner: None + MGG: + Buildable: + Owner: None + GAP: + Buildable: + Owner: None Sequences: truk: