From 9013e8376ce94bb2f74b0f29a40d0bbdf176ef1f Mon Sep 17 00:00:00 2001 From: Scott_NZ Date: Mon, 4 Feb 2013 14:13:49 +1300 Subject: [PATCH] Start work on Monster Tank Madness mission --- OpenRA.Mods.RA/Missions/Allies04Script.cs | 21 +- OpenRA.Mods.RA/Missions/MissionUtils.cs | 29 + .../Missions/MonsterTankMadnessScript.cs | 217 ++ OpenRA.Mods.RA/OpenRA.Mods.RA.csproj | 1 + mods/ra/maps/monster-tank-madness/map.bin | Bin 0 -> 81925 bytes mods/ra/maps/monster-tank-madness/map.yaml | 2740 +++++++++++++++++ 6 files changed, 2990 insertions(+), 18 deletions(-) create mode 100644 OpenRA.Mods.RA/Missions/MonsterTankMadnessScript.cs create mode 100644 mods/ra/maps/monster-tank-madness/map.bin create mode 100644 mods/ra/maps/monster-tank-madness/map.yaml diff --git a/OpenRA.Mods.RA/Missions/Allies04Script.cs b/OpenRA.Mods.RA/Missions/Allies04Script.cs index f285d94936..9d1ab946e3 100644 --- a/OpenRA.Mods.RA/Missions/Allies04Script.cs +++ b/OpenRA.Mods.RA/Missions/Allies04Script.cs @@ -253,7 +253,7 @@ namespace OpenRA.Mods.RA.Missions foreach (var actor in world.Actors.Where(a => !a.IsDead() && a.HasTrait())) actor.QueueActivity(false, new Transform(actor, actor.Info.Traits.Get().ToActor) { SkipMakeAnims = true }); - lab.AddTrait(new Allies04TransformedAction(self => lab = self)); + lab.AddTrait(new TransformedAction(self => lab = self)); } } @@ -278,7 +278,7 @@ namespace OpenRA.Mods.RA.Missions allies2.PlayerActor.Trait().GiveCash(2500); })); - lst.AddTrait(new Allies04TransformedAction(self => + lst.AddTrait(new TransformedAction(self => { self.QueueActivity(new Wait(10)); self.QueueActivity(new Move.Move(reinforcementsEntryPoint.Location)); @@ -333,7 +333,7 @@ namespace OpenRA.Mods.RA.Missions lst.Trait().Load(lst, allies2Spy); } - lst.AddTrait(new Allies04TransformedAction(self => + lst.AddTrait(new TransformedAction(self => { self.QueueActivity(new Wait(10)); self.QueueActivity(new Move.Move(spyReinforcementsExitPoint.Location)); @@ -555,19 +555,4 @@ namespace OpenRA.Mods.RA.Missions } class Allies04TransformOnLabInfiltrate { } - - class Allies04TransformedAction : INotifyTransformed - { - Action a; - - public Allies04TransformedAction(Action a) - { - this.a = a; - } - - public void OnTransformed(Actor toActor) - { - a(toActor); - } - } } diff --git a/OpenRA.Mods.RA/Missions/MissionUtils.cs b/OpenRA.Mods.RA/Missions/MissionUtils.cs index 609372b5f0..0affece064 100644 --- a/OpenRA.Mods.RA/Missions/MissionUtils.cs +++ b/OpenRA.Mods.RA/Missions/MissionUtils.cs @@ -204,5 +204,34 @@ namespace OpenRA.Mods.RA.Missions Sound.Play("misnlst1.aud"); } + + public static void SpawnAndMoveActors(World world, Player player, string[] actorNames, CPos entry, CPos move, int facing) + { + foreach (var actor in actorNames) + { + world.CreateActor(actor, new TypeDictionary + { + new LocationInit(entry), + new OwnerInit(player), + new FacingInit(facing) + }) + .QueueActivity(new Move.Move(move)); + } + } + } + + class TransformedAction : INotifyTransformed + { + Action a; + + public TransformedAction(Action a) + { + this.a = a; + } + + public void OnTransformed(Actor toActor) + { + a(toActor); + } } } diff --git a/OpenRA.Mods.RA/Missions/MonsterTankMadnessScript.cs b/OpenRA.Mods.RA/Missions/MonsterTankMadnessScript.cs new file mode 100644 index 0000000000..77e9cb6fbe --- /dev/null +++ b/OpenRA.Mods.RA/Missions/MonsterTankMadnessScript.cs @@ -0,0 +1,217 @@ +#region Copyright & License Information +/* + * Copyright 2007-2012 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. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using OpenRA.Traits; +using OpenRA.FileFormats; +using OpenRA.Mods.RA.Activities; +using OpenRA.Mods.RA.Move; +using OpenRA.Mods.RA.Buildings; + +namespace OpenRA.Mods.RA.Missions +{ + class MonsterTankMadnessScriptInfo : ITraitInfo, Requires + { + public readonly string[] FirstStartUnits = null; + public readonly string[] SecondStartUnits = null; + public readonly string[] ThirdStartUnits = null; + public readonly string[] FirstBaseUnits = null; + + public object Create(ActorInitializer init) { return new MonsterTankMadnessScript(this); } + } + + class MonsterTankMadnessScript : IHasObjectives, IWorldLoaded, ITick + { + MonsterTankMadnessScriptInfo info; + + public MonsterTankMadnessScript(MonsterTankMadnessScriptInfo info) + { + this.info = info; + } + + public event Action OnObjectivesUpdated = notify => { }; + + public IEnumerable Objectives { get { return objectives.Values; } } + + Dictionary objectives = new Dictionary + { + { BriefingID, new Objective(ObjectiveType.Primary, Briefing, ObjectiveStatus.InProgress) } + }; + + const int BriefingID = 0; + const string Briefing = "Dr. Demitri, creator of a Soviet Super Tank, wants to defect." + + " We planned to extract him while the Soviets were testing their new weapon, but something has gone wrong." + + " The Super Tanks are out of control, and Demitri is missing -- likely hiding in the village to the far south." + + " Find our outpost and start repairs on it, then find and evacuate Demitri." + + " As for the tanks, we can reprogram them. Send a spy into the Soviet radar dome in the NE, turning the tanks on their creators."; + + World world; + + Player neutral; + Player greece; + Player ussr; + Player turkey; + + Actor startEntryPoint; + Actor startMovePoint; + Actor startBridgeEndPoint; + Actor alliedBaseTopLeft; + Actor alliedBaseBottomRight; + Actor alliedBaseProc; + Actor alliedBaseEntryPoint; + Actor alliedBaseMovePoint; + + Actor demitriChurch; + Actor demitriChurchSpawnPoint; + Actor demitriTriggerAreaCenter; + Actor demitri; + Actor demitriLZ; + Actor demitriLZFlare; + Actor demitriChinook; + + int baseTransferredTick = -1; + + void MissionAccomplished(string text) + { + MissionUtils.CoopMissionAccomplished(world, text, ussr); + } + + void MissionFailed(string text) + { + MissionUtils.CoopMissionFailed(world, text, ussr); + } + + public void Tick(Actor self) + { + if (greece.WinState != WinState.Undefined) return; + + if (world.FrameNumber == 1) + { + Sound.Play("reinfor1.aud"); + SpawnAndMoveBridgeUnits(info.FirstStartUnits); + } + + else if (world.FrameNumber == 25 * 3) + { + Sound.Play("reinfor1.aud"); + SpawnAndMoveBridgeUnits(info.SecondStartUnits); + } + + else if (world.FrameNumber == 25 * 8) + { + Sound.Play("reinfor1.aud"); + SpawnAndMoveBridgeUnits(info.ThirdStartUnits); + } + + if (baseTransferredTick == -1) + { + var actorsInBase = world.FindUnits(alliedBaseTopLeft.CenterLocation, alliedBaseBottomRight.CenterLocation).Where(a => !a.IsDead() && a.IsInWorld); + if (actorsInBase.Any(a => a.Owner == greece)) + { + foreach (var actor in actorsInBase) + { + // hack hack hack + actor.ChangeOwner(greece); + if (actor.Info.Name == "pbox") + { + actor.AddTrait(new TransformedAction(s => s.Trait().Load(s, + world.CreateActor(false, "e1", new TypeDictionary { new OwnerInit(greece) })))); + actor.QueueActivity(new Transform(actor, "hbox.e1") { SkipMakeAnims = true }); + } + else if (actor.Info.Name == "proc.nofreeactor") + { + actor.QueueActivity(new Transform(actor, "proc") { SkipMakeAnims = true }); + } + var building = actor.TraitOrDefault(); + if (building != null) + building.OnCapture(actor, actor, neutral, greece); + } + baseTransferredTick = world.FrameNumber; + } + } + else + { + + } + if (demitri == null) + { + if (demitriChurch.IsDead()) + MissionFailed("Dr. Demitri was killed."); + + else if (world.FindAliveCombatantActorsInCircle(demitriTriggerAreaCenter.CenterLocation, 3).Any(a => a.Owner == greece)) + { + demitri = world.CreateActor("demitri", new TypeDictionary + { + new OwnerInit(greece), + new LocationInit(demitriChurchSpawnPoint.Location) + }); + demitri.QueueActivity(new Move.Move(demitriTriggerAreaCenter.Location, 0)); + demitriLZFlare = world.CreateActor("flare", new TypeDictionary { new OwnerInit(greece), new LocationInit(demitriLZ.Location) }); + Sound.Play("flaren1.aud"); + var chinookEntry = new CPos(demitriLZ.Location.X, 0); + demitriChinook = MissionUtils.ExtractUnitWithChinook(world, greece, demitri, chinookEntry, demitriLZ.Location, chinookEntry); + } + } + else if (demitri.IsDead()) + MissionFailed("Dr. Demitri was killed."); + else if (demitriChinook != null && !demitriChinook.IsDead() && !world.Map.IsInMap(demitriChinook.Location) && demitriChinook.Trait().Passengers.Contains(demitri)) + { + demitriLZFlare.Destroy(); + Sound.Play("reinfor1.aud"); + SpawnAndMoveAlliedBaseUnits(info.FirstBaseUnits); + } + } + + void SpawnAndMoveBridgeUnits(string[] units) + { + MissionUtils.SpawnAndMoveActors(world, greece, units, startEntryPoint.Location, startMovePoint.Location, + Util.GetFacing(startBridgeEndPoint.CenterLocation - startEntryPoint.CenterLocation, 0)); + } + + void SpawnAndMoveAlliedBaseUnits(string[] units) + { + MissionUtils.SpawnAndMoveActors(world, greece, units, alliedBaseEntryPoint.Location, alliedBaseMovePoint.Location, + Util.GetFacing(alliedBaseMovePoint.CenterLocation - alliedBaseEntryPoint.CenterLocation, 0)); + } + + public void WorldLoaded(World w) + { + world = w; + + neutral = w.Players.Single(p => p.InternalName == "Neutral"); + greece = w.Players.Single(p => p.InternalName == "Greece"); + ussr = w.Players.Single(p => p.InternalName == "USSR"); + turkey = w.Players.Single(p => p.InternalName == "Turkey"); + + greece.PlayerActor.Trait().Cash = 0; + ussr.PlayerActor.Trait().Cash = 2000; + + var actors = w.WorldActor.Trait().Actors; + startEntryPoint = actors["StartEntryPoint"]; + startMovePoint = actors["StartMovePoint"]; + startBridgeEndPoint = actors["StartBridgeEndPoint"]; + alliedBaseTopLeft = actors["AlliedBaseTopLeft"]; + alliedBaseBottomRight = actors["AlliedBaseBottomRight"]; + alliedBaseProc = actors["AlliedBaseProc"]; + alliedBaseEntryPoint = actors["AlliedBaseEntryPoint"]; + alliedBaseMovePoint = actors["AlliedBaseMovePoint"]; + + demitriChurch = actors["DemitriChurch"]; + demitriChurchSpawnPoint = actors["DemitriChurchSpawnPoint"]; + demitriTriggerAreaCenter = actors["DemitriTriggerAreaCenter"]; + demitriLZ = actors["DemitriLZ"]; + + Game.MoveViewport(startEntryPoint.Location.ToFloat2()); + MissionUtils.PlayMissionMusic(); + } + } +} diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index c88eb29ed0..baed6d3c4d 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -246,6 +246,7 @@ + diff --git a/mods/ra/maps/monster-tank-madness/map.bin b/mods/ra/maps/monster-tank-madness/map.bin new file mode 100644 index 0000000000000000000000000000000000000000..00599aec5ee9c97da50b4b30b768e2afc5f8d603 GIT binary patch literal 81925 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