From 9581f072424717952e457483100f1726ba95ee40 Mon Sep 17 00:00:00 2001 From: Scott_NZ Date: Mon, 31 Dec 2012 14:47:34 +1300 Subject: [PATCH] Add first version of Soviet 01 classic --- OpenRA.Mods.RA/LimitedAmmo.cs | 10 +- .../Missions/Soviet01ClassicScript.cs | 159 +++ OpenRA.Mods.RA/OpenRA.Mods.RA.csproj | 1 + mods/ra/maps/soviet-01-classic/map.bin | Bin 0 -> 81925 bytes mods/ra/maps/soviet-01-classic/map.yaml | 920 ++++++++++++++++++ 5 files changed, 1088 insertions(+), 2 deletions(-) create mode 100644 OpenRA.Mods.RA/Missions/Soviet01ClassicScript.cs create mode 100644 mods/ra/maps/soviet-01-classic/map.bin create mode 100644 mods/ra/maps/soviet-01-classic/map.yaml diff --git a/OpenRA.Mods.RA/LimitedAmmo.cs b/OpenRA.Mods.RA/LimitedAmmo.cs index 2360889c17..f09d9776fb 100644 --- a/OpenRA.Mods.RA/LimitedAmmo.cs +++ b/OpenRA.Mods.RA/LimitedAmmo.cs @@ -1,4 +1,4 @@ -#region Copyright & License Information +#region Copyright & License Information /* * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made @@ -41,10 +41,16 @@ namespace OpenRA.Mods.RA ++ammo; return true; } + public bool TakeAmmo() + { + if (ammo <= 0) return false; + --ammo; + return true; + } public int ReloadTimePerAmmo() { return Info.ReloadTicks; } - public void Attacking(Actor self, Target target) { --ammo; } + public void Attacking(Actor self, Target target) { TakeAmmo(); } public IEnumerable GetPips(Actor self) { diff --git a/OpenRA.Mods.RA/Missions/Soviet01ClassicScript.cs b/OpenRA.Mods.RA/Missions/Soviet01ClassicScript.cs new file mode 100644 index 0000000000..1540bbb8e2 --- /dev/null +++ b/OpenRA.Mods.RA/Missions/Soviet01ClassicScript.cs @@ -0,0 +1,159 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using OpenRA.Traits; +using System.Drawing; +using OpenRA.Mods.RA.Move; +using OpenRA.Mods.RA.Buildings; +using OpenRA.Network; +using OpenRA.Scripting; +using OpenRA.FileFormats; +using OpenRA.Mods.RA.Air; +using OpenRA.Mods.RA.Activities; + +namespace OpenRA.Mods.RA.Missions +{ + class Soviet01ClassicScriptInfo : TraitInfo, Requires { } + + class Soviet01ClassicScript : IHasObjectives, IWorldLoaded, ITick + { + public event ObjectivesUpdatedEventHandler OnObjectivesUpdated = notify => { }; + + public IEnumerable Objectives { get { return objectives.Values; } } + + Dictionary objectives = new Dictionary + { + { DestroyID, new Objective(ObjectiveType.Primary, Destroy, ObjectiveStatus.InProgress) } + }; + + const int DestroyID = 0; + const string Destroy = "A pitiful excuse for resistance has blockaded itself in this village. Stalin has decided to make an example of them. Kill them all and destroy their homes. You will have Yak aircraft to use in teaching these rebels a lesson."; + + World world; + + Player ussr; + Player france; + + Actor startJeep; + Actor startJeepMovePoint; + + Actor airfield1; + Actor airfield2; + Actor airfield3; + Actor[] airfields; + + void MissionFailed() + { + if (ussr.WinState != WinState.Undefined) + { + return; + } + ussr.WinState = WinState.Lost; + foreach (var actor in world.Actors.Where(a => a.IsInWorld && a.Owner == ussr && !a.IsDead())) + { + actor.Kill(actor); + } + Sound.Play("misnlst1.aud"); + } + + void MissionAccomplished() + { + if (ussr.WinState != WinState.Undefined) + { + return; + } + ussr.WinState = WinState.Won; + Sound.Play("misnwon1.aud"); + } + + public void Tick(Actor self) + { + var unitsAndBuildings = world.Actors.Where(a => !a.IsDead() && a.IsInWorld && (a.HasTrait() || (a.HasTrait() && !a.HasTrait()))); + if (!unitsAndBuildings.Any(a => a.Owner == france)) + { + objectives[DestroyID].Status = ObjectiveStatus.Completed; + MissionAccomplished(); + } + else if (!unitsAndBuildings.Any(a => a.Owner == ussr)) + { + objectives[DestroyID].Status = ObjectiveStatus.Failed; + MissionFailed(); + } + } + + void LandYaks() + { + foreach (var airfield in airfields) + { + var entry = airfield.Location - new CVec(10, 0); + var yak = world.CreateActor("yak", new TypeDictionary + { + new OwnerInit(ussr), + new LocationInit(entry), + new FacingInit(Util.GetFacing(airfield.Location - entry, 0)), + new AltitudeInit(Rules.Info["yak"].Traits.Get().CruiseAltitude) + }); + while (yak.Trait().TakeAmmo()) { } + yak.QueueActivity(new ReturnToBase(yak, airfield)); + yak.QueueActivity(new ResupplyAircraft()); + } + } + + void MoveJeep() + { + startJeep.QueueActivity(new MoveAdjacentTo(Target.FromActor(startJeepMovePoint))); + startJeep.QueueActivity(new CallFunc(() => + { + var bridge = world.Actors + .Where(a => a.HasTrait() && !a.IsDead()) + .OrderBy(a => (startJeep.CenterLocation - a.CenterLocation).LengthSquared) + .First(); + Combat.DoExplosion(bridge, "Demolish", bridge.CenterLocation, 0); + world.WorldActor.Trait().AddEffect(15, bridge.CenterLocation.ToFloat2(), 6); + bridge.Kill(bridge); + })); + } + + public void WorldLoaded(World w) + { + world = w; + ussr = w.Players.Single(p => p.InternalName == "USSR"); + france = w.Players.Single(p => p.InternalName == "France"); + var actors = w.WorldActor.Trait().Actors; + startJeep = actors["StartJeep"]; + startJeepMovePoint = actors["StartJeepMovePoint"]; + airfield1 = actors["Airfield1"]; + airfield2 = actors["Airfield2"]; + airfield3 = actors["Airfield3"]; + airfields = new[] { airfield1, airfield2, airfield3 }; + Game.MoveViewport(startJeep.Location.ToFloat2()); + Game.ConnectionStateChanged += StopMusic; + Media.PlayFMVFullscreen(w, "soviet1.vqa", () => + { + PlayMusic(); + LandYaks(); + MoveJeep(); + }); + } + + void PlayMusic() + { + if (!Rules.InstalledMusic.Any()) + { + return; + } + var track = Rules.InstalledMusic.Random(Game.CosmeticRandom); + Sound.PlayMusicThen(track.Value, PlayMusic); + } + + void StopMusic(OrderManager orderManager) + { + if (!orderManager.GameStarted) + { + Sound.StopMusic(); + Game.ConnectionStateChanged -= StopMusic; + } + } + } +} diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 44b945aedf..c88eb29ed0 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -247,6 +247,7 @@ + diff --git a/mods/ra/maps/soviet-01-classic/map.bin b/mods/ra/maps/soviet-01-classic/map.bin new file mode 100644 index 0000000000000000000000000000000000000000..93624ab3550138b86309d6b97d820e98815feda0 GIT binary patch literal 81925 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