From 9312a7e03aca8d6d757f6bf9b64652b6a4263872 Mon Sep 17 00:00:00 2001 From: ScottNZ Date: Fri, 29 Nov 2013 22:53:57 +1300 Subject: [PATCH 01/11] Add husk for V19 (oil pump) --- mods/ra/rules/civilian.yaml | 14 +++++++++++++- mods/ra/sequences/decorations.yaml | 15 ++++++++++++--- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/mods/ra/rules/civilian.yaml b/mods/ra/rules/civilian.yaml index 68a3f7091e..5b178ffb82 100644 --- a/mods/ra/rules/civilian.yaml +++ b/mods/ra/rules/civilian.yaml @@ -242,6 +242,19 @@ V19: ExcludeTilesets: DESERT Tooltip: Name: Oil Pump + LeavesHusk: + HuskActor: V19.Husk + AutoTargetIgnore: + +V19.Husk: + Inherits: ^CivBuilding + EditorTilesetFilter: + ExcludeTilesets: DESERT + Tooltip: + Name: Husk (Oil Pump) + WithFire: + -Health: + -Selectable: BARL: Inherits: ^TechBuilding @@ -327,7 +340,6 @@ OILB: ExternalCapturable: ExternalCapturableBar: EngineerRepairable: - -MustBeDestroyed: CashTrickler: Period: 250 Amount: 100 diff --git a/mods/ra/sequences/decorations.yaml b/mods/ra/sequences/decorations.yaml index 873d0cdd44..25a4038ed0 100644 --- a/mods/ra/sequences/decorations.yaml +++ b/mods/ra/sequences/decorations.yaml @@ -357,9 +357,18 @@ v19: idle: Start: 0 Length: 14 - damaged-idle: - Start: 14 - Length: 15 + +v19.husk: + idle: v19 + Start: 28 + fire-start: flmspt + Start: 0 + Length: * + Offset: 7,-15 + fire-loop: flmspt + Start: 50 + Length: * + Offset: 7,-15 utilpol1: idle: From 0527c883b9e0409d47e27916510e3597d6e708d8 Mon Sep 17 00:00:00 2001 From: ScottNZ Date: Fri, 29 Nov 2013 22:56:24 +1300 Subject: [PATCH 02/11] Move DeployTransform logic into its own method, and remove its CancelActivity call so it works properly when queued --- OpenRA.Mods.RA/Transforms.cs | 42 +++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/OpenRA.Mods.RA/Transforms.cs b/OpenRA.Mods.RA/Transforms.cs index 229db3eea4..2cc411ae33 100644 --- a/OpenRA.Mods.RA/Transforms.cs +++ b/OpenRA.Mods.RA/Transforms.cs @@ -68,29 +68,31 @@ namespace OpenRA.Mods.RA return null; } + public void DeployTransform() + { + var b = self.TraitOrDefault(); + + if (!CanDeploy() || (b != null && !b.Lock())) + { + foreach (var s in Info.NoTransformSounds) + Sound.PlayToPlayer(self.Owner, s); + return; + } + + if (self.HasTrait()) + self.QueueActivity(new Turn(Info.Facing)); + + var rb = self.TraitOrDefault(); + if (rb != null && self.Info.Traits.Get().HasMakeAnimation) + self.QueueActivity(new MakeAnimation(self, true, () => rb.PlayCustomAnim(self, "make"))); + + self.QueueActivity(new Transform(self, Info.IntoActor) { Offset = (CVec)Info.Offset, Facing = Info.Facing, Sounds = Info.TransformSounds }); + } + public void ResolveOrder( Actor self, Order order ) { if (order.OrderString == "DeployTransform") - { - var b = self.TraitOrDefault(); - - if (!CanDeploy() || (b != null && !b.Lock())) - { - foreach (var s in Info.NoTransformSounds) - Sound.PlayToPlayer(self.Owner, s); - return; - } - self.CancelActivity(); - - if (self.HasTrait()) - self.QueueActivity(new Turn(Info.Facing)); - - var rb = self.TraitOrDefault(); - if (rb != null && self.Info.Traits.Get().HasMakeAnimation) - self.QueueActivity(new MakeAnimation(self, true, () => rb.PlayCustomAnim(self, "make"))); - - self.QueueActivity(new Transform(self, Info.IntoActor) { Offset = (CVec)Info.Offset, Facing = Info.Facing, Sounds = Info.TransformSounds }); - } + DeployTransform(); } } } From b69508fb6be9e7b09001fbb71e4f04a9c49a29e9 Mon Sep 17 00:00:00 2001 From: ScottNZ Date: Fri, 29 Nov 2013 22:58:04 +1300 Subject: [PATCH 03/11] Remove MustBeDestroyed from ^TechBuilding --- mods/ra/rules/defaults.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml index e498b58415..9366e89531 100644 --- a/mods/ra/rules/defaults.yaml +++ b/mods/ra/rules/defaults.yaml @@ -308,6 +308,7 @@ FrozenUnderFog: StartsRevealed: true -GpsDot: + -MustBeDestroyed: ^AmmoBox: Inherits: ^TechBuilding From e4e6169f7fc1c02a5b064b5fda3fe3c95d6eda53 Mon Sep 17 00:00:00 2001 From: ScottNZ Date: Fri, 29 Nov 2013 23:01:18 +1300 Subject: [PATCH 04/11] Add a function to World for setting just the local pause state, and add a lock variable to prevent further pause state changes --- OpenRA.Game/World.cs | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/OpenRA.Game/World.cs b/OpenRA.Game/World.cs index 013d00bdfb..462fe8e82d 100644 --- a/OpenRA.Game/World.cs +++ b/OpenRA.Game/World.cs @@ -46,7 +46,7 @@ namespace OpenRA public bool ObserveAfterWinOrLose; public Player RenderPlayer { - get { return renderPlayer == null || (ObserveAfterWinOrLose && renderPlayer.WinState != WinState.Undefined)? null : renderPlayer; } + get { return renderPlayer == null || (ObserveAfterWinOrLose && renderPlayer.WinState != WinState.Undefined) ? null : renderPlayer; } set { renderPlayer = value; } } @@ -71,7 +71,7 @@ namespace OpenRA if (orderManager.Connection is ReplayConnection) return; - LocalPlayer = Players.FirstOrDefault(p => p.InternalName == pr); + LocalPlayer = Players.FirstOrDefault(p => p.InternalName == pr); RenderPlayer = LocalPlayer; } @@ -89,7 +89,7 @@ namespace OpenRA get { return orderGenerator_; } set { - Sync.AssertUnsynced( "The current order generator may not be changed from synced code" ); + Sync.AssertUnsynced("The current order generator may not be changed from synced code"); orderGenerator_ = value; } } @@ -145,16 +145,16 @@ namespace OpenRA wlh.WorldLoaded(this, wr); } - public Actor CreateActor( string name, TypeDictionary initDict ) + public Actor CreateActor(string name, TypeDictionary initDict) { - return CreateActor( true, name, initDict ); + return CreateActor(true, name, initDict); } - public Actor CreateActor( bool addToWorld, string name, TypeDictionary initDict ) + public Actor CreateActor(bool addToWorld, string name, TypeDictionary initDict) { - var a = new Actor( this, name, initDict ); - if( addToWorld ) - Add( a ); + var a = new Actor(this, name, initDict); + if (addToWorld) + Add(a); return a; } @@ -188,14 +188,23 @@ namespace OpenRA public bool Paused { get; internal set; } public bool PredictedPaused { get; internal set; } + public bool PauseStateLocked { get; set; } public bool IsShellmap = false; public void SetPauseState(bool paused) { + if (PauseStateLocked) + return; + IssueOrder(Order.PauseGame(paused)); PredictedPaused = paused; } + public void SetLocalPauseState(bool paused) + { + Paused = PredictedPaused = paused; + } + public void Tick() { if (!Paused && (!IsShellmap || Game.Settings.Game.ShowShellmap)) @@ -206,12 +215,12 @@ namespace OpenRA ni.Trait.TickIdle(ni.Actor); using (new PerfSample("tick_activities")) - foreach(var a in actors) + foreach (var a in actors) a.Tick(); ActorsWithTrait().DoTimed(x => x.Trait.Tick(x.Actor), "[{2}] Trait: {0} ({1:0.000} ms)", - Game.Settings.Debug.LongTickThreshold); + Game.Settings.Debug.LongTickThreshold); effects.DoTimed(e => e.Tick(this), "[{2}] Effect: {0} ({1:0.000} ms)", @@ -246,11 +255,11 @@ namespace OpenRA // hash all the actors foreach (var a in Actors) - ret += n++ * (int)(1+a.ActorID) * Sync.CalculateSyncHash(a); + ret += n++ * (int)(1 + a.ActorID) * Sync.CalculateSyncHash(a); // hash all the traits that tick foreach (var x in traitDict.ActorsWithTraitMultiple(this)) - ret += n++ * (int)(1+x.Actor.ActorID) * Sync.CalculateSyncHash(x.Trait); + ret += n++ * (int)(1 + x.Actor.ActorID) * Sync.CalculateSyncHash(x.Trait); // TODO: don't go over all effects foreach (var e in Effects) @@ -280,7 +289,7 @@ namespace OpenRA public override string ToString() { - return "{0}->{1}".F( Actor.Info.Name, Trait.GetType().Name ); + return "{0}->{1}".F(Actor.Info.Name, Trait.GetType().Name); } } } From 6a14434cffa7db999adef312f4ae1ef318825a59 Mon Sep 17 00:00:00 2001 From: ScottNZ Date: Fri, 29 Nov 2013 23:01:50 +1300 Subject: [PATCH 05/11] Add a CenterPosition helper to Viewport --- OpenRA.Game/Graphics/Viewport.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/OpenRA.Game/Graphics/Viewport.cs b/OpenRA.Game/Graphics/Viewport.cs index cc6ac5c0c2..4c61e2e18c 100755 --- a/OpenRA.Game/Graphics/Viewport.cs +++ b/OpenRA.Game/Graphics/Viewport.cs @@ -40,6 +40,9 @@ namespace OpenRA.Graphics // Viewport geometry (world-px) public int2 CenterLocation { get; private set; } + + public WPos CenterPosition { get { return worldRenderer.Position(CenterLocation); } } + public int2 TopLeft { get { return CenterLocation - viewportSize / 2; } } public int2 BottomRight { get { return CenterLocation + viewportSize / 2; } } int2 viewportSize; From e4d477b0e016e568a92274231a50cba041f8df6d Mon Sep 17 00:00:00 2001 From: ScottNZ Date: Fri, 29 Nov 2013 23:48:44 +1300 Subject: [PATCH 06/11] Add Lua standard library and supporting C#/yaml --- OpenRA.Mods.RA/Activities/Hunt.cs | 48 ++++++ OpenRA.Mods.RA/OpenRA.Mods.RA.csproj | 2 + OpenRA.Mods.RA/Scripting/LuaScriptEvents.cs | 40 +++++ .../Scripting/LuaScriptInterface.cs | 106 ++++++++++++- mods/cnc/mod.yaml | 9 ++ mods/cnc/rules/defaults.yaml | 23 +++ mods/d2k/mod.yaml | 9 ++ mods/d2k/rules/defaults.yaml | 14 +- mods/ra/lua/actor.lua | 147 ++++++++++++++++++ mods/ra/lua/map.lua | 9 ++ mods/ra/lua/media.lua | 20 +++ mods/ra/lua/mission.lua | 119 ++++++++++++++ mods/ra/lua/openra.lua | 69 ++++++++ mods/ra/lua/team.lua | 61 ++++++++ mods/ra/lua/utils.lua | 67 ++++++++ mods/ra/mod.yaml | 9 ++ mods/ra/rules/defaults.yaml | 20 +++ mods/ts/mod.yaml | 9 ++ mods/ts/rules/defaults.yaml | 11 +- 19 files changed, 787 insertions(+), 5 deletions(-) create mode 100644 OpenRA.Mods.RA/Activities/Hunt.cs create mode 100644 OpenRA.Mods.RA/Scripting/LuaScriptEvents.cs create mode 100644 mods/ra/lua/actor.lua create mode 100644 mods/ra/lua/map.lua create mode 100644 mods/ra/lua/media.lua create mode 100644 mods/ra/lua/mission.lua create mode 100644 mods/ra/lua/openra.lua create mode 100644 mods/ra/lua/team.lua create mode 100644 mods/ra/lua/utils.lua diff --git a/OpenRA.Mods.RA/Activities/Hunt.cs b/OpenRA.Mods.RA/Activities/Hunt.cs new file mode 100644 index 0000000000..863de0cd80 --- /dev/null +++ b/OpenRA.Mods.RA/Activities/Hunt.cs @@ -0,0 +1,48 @@ +#region Copyright & License Information +/* + * Copyright 2007-2013 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.Collections.Generic; +using System.Linq; +using OpenRA.Mods.RA.Buildings; +using OpenRA.Mods.RA.Move; +using OpenRA.Traits; + +namespace OpenRA.Mods.RA.Activities +{ + public class Hunt : Activity + { + readonly IEnumerable targets; + + public Hunt(Actor self) + { + var attack = self.Trait(); + targets = self.World.Actors.Where(a => self != a && !a.IsDead() && a.IsInWorld && a.AppearsHostileTo(self) + && a.HasTrait() && attack.HasAnyValidWeapons(Target.FromActor(a))); + } + + public override Activity Tick(Actor self) + { + if (IsCanceled) + return NextActivity; + + var target = targets.ClosestTo(self); + if (target == null) + return this; + + return Util.SequenceActivities( + new AttackMove.AttackMoveActivity(self, new Move.Move(target.Location, WRange.FromCells(2))), + new Wait(25), + this); + } + } + + public class HuntableInfo : TraitInfo { } + public class Huntable { } +} \ No newline at end of file diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 0ae49ce679..eba63a2dde 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -81,6 +81,7 @@ + @@ -338,6 +339,7 @@ + diff --git a/OpenRA.Mods.RA/Scripting/LuaScriptEvents.cs b/OpenRA.Mods.RA/Scripting/LuaScriptEvents.cs new file mode 100644 index 0000000000..a9a361b5be --- /dev/null +++ b/OpenRA.Mods.RA/Scripting/LuaScriptEvents.cs @@ -0,0 +1,40 @@ +#region Copyright & License Information +/* + * Copyright 2007-2013 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 OpenRA.Traits; + +namespace OpenRA.Mods.RA.Scripting +{ + public class LuaScriptEventsInfo : TraitInfo { } + + public class LuaScriptEvents : INotifyKilled, INotifyAddedToWorld, INotifyRemovedFromWorld + { + public event Action OnKilled = (self, e) => { }; + public event Action OnAddedToWorld = self => { }; + public event Action OnRemovedFromWorld = self => { }; + + public void Killed(Actor self, AttackInfo e) + { + OnKilled(self, e); + } + + public void AddedToWorld(Actor self) + { + OnAddedToWorld(self); + } + + public void RemovedFromWorld(Actor self) + { + OnRemovedFromWorld(self); + } + } +} diff --git a/OpenRA.Mods.RA/Scripting/LuaScriptInterface.cs b/OpenRA.Mods.RA/Scripting/LuaScriptInterface.cs index 43f449bb9d..db5c240a14 100644 --- a/OpenRA.Mods.RA/Scripting/LuaScriptInterface.cs +++ b/OpenRA.Mods.RA/Scripting/LuaScriptInterface.cs @@ -8,12 +8,16 @@ */ #endregion -using System; -using System.Linq; using LuaInterface; using OpenRA.Effects; using OpenRA.FileFormats; +using OpenRA.Mods.RA.Activities; +using OpenRA.Mods.RA.Air; +using OpenRA.Mods.RA.Missions; +using OpenRA.Scripting; using OpenRA.Traits; +using System; +using System.Linq; using WorldRenderer = OpenRA.Graphics.WorldRenderer; namespace OpenRA.Mods.RA.Scripting @@ -42,7 +46,7 @@ namespace OpenRA.Mods.RA.Scripting AddMapActorGlobals(); context.Lua["World"] = w; context.Lua["WorldRenderer"] = wr; - context.RegisterObject(this, "_OpenRA", false); + context.RegisterObject(this, "Internal", false); context.RegisterType(typeof(WVec), "WVec", true); context.RegisterType(typeof(WPos), "WPos", true); context.RegisterType(typeof(CPos), "CPos", true); @@ -161,5 +165,101 @@ namespace OpenRA.Mods.RA.Scripting { world.AddFrameEndTask(w => w.Add(new DelayedAction((int)delay, func))); } + + [LuaGlobal] + public void PlaySpeechNotification(Player player, string notification) + { + Sound.PlayNotification(player, "Speech", notification, player != null ? player.Country.Race : null); + } + + [LuaGlobal] + public void PlaySoundNotification(Player player, string notification) + { + Sound.PlayNotification(player, "Sounds", notification, player != null ? player.Country.Race : null); + } + + [LuaGlobal] + public void WaitFor(Actor actor, Func func) + { + actor.QueueActivity(new WaitFor(func)); + } + + [LuaGlobal] + public void CallFunc(Actor actor, Action func) + { + actor.QueueActivity(new CallFunc(func)); + } + + [LuaGlobal] + public int GetFacing(object vec, double currentFacing) + { + if (vec is CVec) + return Util.GetFacing((CVec)vec, (int)currentFacing); + if (vec is WVec) + return Util.GetFacing((WVec)vec, (int)currentFacing); + throw new ArgumentException("Unsupported vector type: {0}".F(vec.GetType())); + } + + [LuaGlobal] + public WRange GetWRangeFromCells(double cells) + { + return WRange.FromCells((int)cells); + } + + [LuaGlobal] + public void SetWinState(Player player, string winState) + { + player.WinState = Enum.Parse(winState); + } + + [LuaGlobal] + public void PlayRandomMusic() + { + MissionUtils.PlayMissionMusic(); + } + + [LuaGlobal] + public bool IsDead(Actor actor) + { + return actor.IsDead(); + } + + [LuaGlobal] + public void PlayMovieFullscreen(string movie, Action onComplete) + { + Media.PlayFMVFullscreen(world, movie, onComplete); + } + + [LuaGlobal] + public void FlyToPos(Actor actor, WPos pos) + { + actor.QueueActivity(Fly.ToPos(pos)); + } + + [LuaGlobal] + public void FlyAttackActor(Actor actor, Actor targetActor) + { + actor.QueueActivity(new FlyAttack(Target.FromActor(targetActor))); + } + + [LuaGlobal] + public void FlyAttackCell(Actor actor, CPos location) + { + actor.QueueActivity(new FlyAttack(Target.FromCell(location))); + } + + [LuaGlobal] + public void SetUnitStance(Actor actor, string stance) + { + var at = actor.TraitOrDefault(); + if (at != null) + at.stance = Enum.Parse(stance); + } + + [LuaGlobal] + public bool RequiredUnitsAreDestroyed(Player player) + { + return world.ActorsWithTrait().All(p => p.Actor.Owner != player); + } } } diff --git a/mods/cnc/mod.yaml b/mods/cnc/mod.yaml index 88f84b4832..f00675d58a 100644 --- a/mods/cnc/mod.yaml +++ b/mods/cnc/mod.yaml @@ -163,3 +163,12 @@ Fonts: TinyBold: Font:FreeSansBold.ttf Size:10 + +LuaScripts: + mods/ra/lua/utils.lua + mods/ra/lua/openra.lua + mods/ra/lua/map.lua + mods/ra/lua/actor.lua + mods/ra/lua/team.lua + mods/ra/lua/media.lua + mods/ra/lua/mission.lua diff --git a/mods/cnc/rules/defaults.yaml b/mods/cnc/rules/defaults.yaml index 8d2b0626be..42c27ad7fb 100644 --- a/mods/cnc/rules/defaults.yaml +++ b/mods/cnc/rules/defaults.yaml @@ -40,6 +40,8 @@ CloakDelay: 90 CloakSound: trans1.aud UncloakSound: trans1.aud + Huntable: + LuaScriptEvents: ^Tank: AppearsOnRadar: @@ -86,6 +88,8 @@ CloakDelay: 90 CloakSound: trans1.aud UncloakSound: trans1.aud + Huntable: + LuaScriptEvents: ^Helicopter: AppearsOnRadar: @@ -113,6 +117,8 @@ CombatDebugOverlay: BodyOrientation: UpdatesPlayerStatistics: + Huntable: + LuaScriptEvents: ^Infantry: AppearsOnRadar: @@ -170,6 +176,8 @@ DamageCooldown: 125 RequiresTech: InfantryHealing UpdatesPlayerStatistics: + Huntable: + LuaScriptEvents: ^CivInfantry: Inherits: ^Infantry @@ -247,6 +255,8 @@ AttackMove: AttackFrontal: UpdatesPlayerStatistics: + Huntable: + LuaScriptEvents: ^Plane: AppearsOnRadar: @@ -263,6 +273,8 @@ ActorLostNotification: CombatDebugOverlay: BodyOrientation: + Huntable: + LuaScriptEvents: ^Ship: AppearsOnRadar: @@ -286,6 +298,8 @@ Guardable: BodyOrientation: UpdatesPlayerStatistics: + Huntable: + LuaScriptEvents: ^Building: AppearsOnRadar: @@ -337,6 +351,8 @@ FrozenUnderFog: UpdatesPlayerStatistics: EngineerRepairable: + Huntable: + LuaScriptEvents: ^CivBuilding: Inherits: ^Building @@ -372,6 +388,7 @@ BodyOrientation: FrozenUnderFog: StartsRevealed: true + LuaScriptEvents: ^TechBuilding: Inherits: ^CivBuilding @@ -407,6 +424,7 @@ Palette: terrain FrozenUnderFog: StartsRevealed: true + LuaScriptEvents: ^Wall: AppearsOnRadar: @@ -437,6 +455,7 @@ Guardable: BodyOrientation: FrozenUnderFog: + LuaScriptEvents: ^Tree: Tooltip: @@ -460,6 +479,7 @@ BodyOrientation: FrozenUnderFog: StartsRevealed: true + LuaScriptEvents: ^Rock: Tooltip: @@ -477,6 +497,7 @@ BodyOrientation: FrozenUnderFog: StartsRevealed: true + LuaScriptEvents: ^Husk: Health: @@ -499,6 +520,7 @@ # AllowAllies: true # AllowNeutral: true # AllowEnemies: true + LuaScriptEvents: ^HelicopterHusk: Inherits: ^Husk @@ -524,3 +546,4 @@ DamagedSound: xplos.aud DestroyedSound: xplobig4.aud BodyOrientation: + LuaScriptEvents: diff --git a/mods/d2k/mod.yaml b/mods/d2k/mod.yaml index 02eaf01e8c..7fff8c53f6 100644 --- a/mods/d2k/mod.yaml +++ b/mods/d2k/mod.yaml @@ -144,3 +144,12 @@ Fonts: TinyBold: Font:FreeSansBold.ttf Size:10 + +LuaScripts: + mods/ra/lua/utils.lua + mods/ra/lua/openra.lua + mods/ra/lua/map.lua + mods/ra/lua/actor.lua + mods/ra/lua/team.lua + mods/ra/lua/media.lua + mods/ra/lua/mission.lua diff --git a/mods/d2k/rules/defaults.yaml b/mods/d2k/rules/defaults.yaml index 0afb310914..aed8639c40 100644 --- a/mods/d2k/rules/defaults.yaml +++ b/mods/d2k/rules/defaults.yaml @@ -35,6 +35,8 @@ RenderUnit: BodyOrientation: UpdatesPlayerStatistics: + Huntable: + LuaScriptEvents: ^Tank: AppearsOnRadar: @@ -73,6 +75,8 @@ RenderUnit: BodyOrientation: UpdatesPlayerStatistics: + Huntable: + LuaScriptEvents: ^Husk: Health: @@ -90,6 +94,7 @@ Tooltip: Name: Destroyed Tank BodyOrientation: + LuaScriptEvents: ^TowerHusk: Health: @@ -108,6 +113,7 @@ ProximityCaptor: Types:Husk BodyOrientation: + LuaScriptEvents: ^AircraftHusk: Inherits: ^Husk @@ -167,6 +173,8 @@ Guardable: BodyOrientation: UpdatesPlayerStatistics: + Huntable: + LuaScriptEvents: ^Plane: AppearsOnRadar: @@ -188,6 +196,8 @@ CombatDebugOverlay: BodyOrientation: UpdatesPlayerStatistics: + Huntable: + LuaScriptEvents: ^Helicopter: Inherits: ^Plane @@ -236,4 +246,6 @@ Range: 3 BodyOrientation: UpdatesPlayerStatistics: - WithCrumbleOverlay: \ No newline at end of file + WithCrumbleOverlay: + Huntable: + LuaScriptEvents: \ No newline at end of file diff --git a/mods/ra/lua/actor.lua b/mods/ra/lua/actor.lua new file mode 100644 index 0000000000..904b6a5be4 --- /dev/null +++ b/mods/ra/lua/actor.lua @@ -0,0 +1,147 @@ +Actor = { } + +Actor.Create = function(name, init) + if name == nil then error("No actor name specified", 2) end + if init.Owner == nil then error("No actor owner specified", 2) end + local td = OpenRA.New("TypeDictionary") + local addToWorld = true + for key, value in pairs(init) do + if key == "AddToWorld" then + addToWorld = value + else + td:Add(OpenRA.New(key .. "Init", { value })) + end + end + return World:CreateActor(addToWorld, name, td) +end + +Actor.Turn = function(actor, facing) + actor:QueueActivity(OpenRA.New("Turn", { { facing, "Int32" } })) +end + +Actor.Move = function(actor, location) + Actor.MoveNear(actor, location, 0) +end + +Actor.MoveNear = function(actor, location, nearEnough) + actor:QueueActivity(OpenRA.New("Move", { location, Map.GetWRangeFromCells(nearEnough) })) +end + +Actor.HeliFly = function(actor, position) + actor:QueueActivity(OpenRA.New("HeliFly", { position })) +end + +Actor.HeliLand = function(actor, requireSpace) + actor:QueueActivity(OpenRA.New("HeliLand", { requireSpace })) +end + +Actor.Fly = function(actor, position) + Internal.FlyToPos(actor, position) +end + +Actor.FlyAttackActor = function(actor, targetActor) + Internal.FlyAttackActor(actor, targetActor) +end + +Actor.FlyAttackCell = function(actor, location) + Internal.FlyAttackCell(actor, location) +end + +Actor.FlyOffMap = function(actor) + actor:QueueActivity(OpenRA.New("FlyOffMap")) +end + +Actor.Hunt = function(actor) + actor:QueueActivity(OpenRA.New("Hunt", { actor })) +end + +Actor.UnloadCargo = function(actor, unloadAll) + actor:QueueActivity(OpenRA.New("UnloadCargo", { unloadAll })) +end + +Actor.Harvest = function(actor) + actor:QueueActivity(OpenRA.New("FindResources")) +end + +Actor.Scatter = function(actor) + local mobile = Actor.Trait(actor, "Mobile") + mobile:Nudge(actor, actor, true) +end + +Actor.Wait = function(actor, period) + actor:QueueActivity(OpenRA.New("Wait", { { period, "Int32" } })) +end + +Actor.WaitFor = function(actor, func) + Internal.WaitFor(actor, func) +end + +Actor.CallFunc = function(actor, func) + Internal.CallFunc(actor, func) +end + +Actor.DeployTransform = function(actor) + Actor.CallFunc(actor, function() + Actor.Trait(actor, "Transforms"):DeployTransform() + end) +end + +Actor.RemoveSelf = function(actor) + actor:QueueActivity(OpenRA.New("RemoveSelf")) +end + +Actor.Stop = function(actor) + actor:CancelActivity() +end + +Actor.IsDead = function(actor) + return Internal.IsDead(actor) +end + +Actor.IsInWorld = function(actor) + return actor.IsInWorld +end + +Actor.Owner = function(actor) + return actor.Owner +end + +Actor.SetStance = function(actor, stance) + Internal.SetUnitStance(actor, stance) +end + +Actor.OnKilled = function(actor, eh) + Actor.Trait(actor, "LuaScriptEvents").OnKilled:Add(eh) +end + +Actor.OnAddedToWorld = function(actor, eh) + Actor.Trait(actor, "LuaScriptEvents").OnAddedToWorld:Add(eh) +end + +Actor.OnRemovedFromWorld = function(actor, eh) + Actor.Trait(actor, "LuaScriptEvents").OnRemovedFromWorld:Add(eh) +end + +Actor.HasTrait = function(actor, className) + return Internal.HasTrait(actor, className) +end + +Actor.TraitOrDefault = function(actor, className) + return Internal.TraitOrDefault(actor, className) +end + +Actor.Trait = function(actor, className) + return Internal.Trait(actor, className) +end + +Actor.HasTraitInfo = function(actorType, className) + return Internal.HasTraitInfo(actorType, className) +end + +Actor.TraitInfoOrDefault = function(actorType, className) + return Internal.TraitInfoOrDefault(actorType, className) +end + +Actor.TraitInfo = function(actorType, className) + return Internal.TraitInfo(actorType, className) +end \ No newline at end of file diff --git a/mods/ra/lua/map.lua b/mods/ra/lua/map.lua new file mode 100644 index 0000000000..39ed982234 --- /dev/null +++ b/mods/ra/lua/map.lua @@ -0,0 +1,9 @@ +Map = { } + +Map.GetFacing = function(vec, currentFacing) + return Internal.GetFacing(vec, currentFacing) +end + +Map.GetWRangeFromCells = function(cells) + return Internal.GetWRangeFromCells(cells) +end \ No newline at end of file diff --git a/mods/ra/lua/media.lua b/mods/ra/lua/media.lua new file mode 100644 index 0000000000..7400551f46 --- /dev/null +++ b/mods/ra/lua/media.lua @@ -0,0 +1,20 @@ +Media = { } + +Media.PlaySpeechNotification = function(notification, player) + Internal.PlaySpeechNotification(player, notification) +end + +Media.PlaySoundNotification = function(notification, player) + Internal.PlaySoundNotification(player, notification) +end + +Media.PlayRandomMusic = function() + Internal.PlayRandomMusic() +end + +Media.PlayMovieFullscreen = function(movie, onComplete) + if onComplete == nil then + onComplete = function() end + end + Internal.PlayMovieFullscreen(movie, onComplete) +end \ No newline at end of file diff --git a/mods/ra/lua/mission.lua b/mods/ra/lua/mission.lua new file mode 100644 index 0000000000..ed26c90e0a --- /dev/null +++ b/mods/ra/lua/mission.lua @@ -0,0 +1,119 @@ +Mission = { } + +Mission.PerformHelicopterInsertion = function(owner, helicopterName, passengerNames, enterPosition, unloadPosition, exitPosition) + local facing = { Map.GetFacing(WPos.op_Subtraction(unloadPosition, enterPosition), 0), "Int32" } + local altitude = { Actor.TraitInfo(helicopterName, "AircraftInfo").CruiseAltitude, "Int32" } + local heli = Actor.Create(helicopterName, { Owner = owner, CenterPosition = enterPosition, Facing = facing, Altitude = altitude }) + local cargo = Actor.Trait(heli, "Cargo") + local passengers = { } + for i, passengerName in ipairs(passengerNames) do + local passenger = Actor.Create(passengerName, { AddToWorld = false, Owner = owner }) + cargo:Load(heli, passenger) + passengers[i] = passenger + end + Actor.HeliFly(heli, unloadPosition) + Actor.Turn(heli, 0) + Actor.HeliLand(heli, true) + Actor.UnloadCargo(heli, true) + Actor.Wait(heli, 125) + Actor.HeliFly(heli, exitPosition) + Actor.RemoveSelf(heli) + return heli, passengers +end + +Mission.PerformHelicopterExtraction = function(owner, helicopterName, passengers, enterPosition, loadPosition, exitPosition) + local facing = { Map.GetFacing(WPos.op_Subtraction(loadPosition, enterPosition), 0), "Int32" } + local altitude = { Actor.TraitInfo(helicopterName, "AircraftInfo").CruiseAltitude, "Int32" } + local heli = Actor.Create(helicopterName, { Owner = owner, CenterPosition = enterPosition, Facing = facing, Altitude = altitude }) + local cargo = Actor.Trait(heli, "Cargo") + Actor.HeliFly(heli, loadPosition) + Actor.Turn(heli, 0) + Actor.HeliLand(heli, true) + Actor.WaitFor(heli, function() + for i, passenger in ipairs(passengers) do + if not cargo.Passengers:Contains(passenger) then + return false + end + end + return true + end) + Actor.Wait(heli, 125) + Actor.HeliFly(heli, exitPosition) + Actor.RemoveSelf(heli) + return heli +end + +Mission.Reinforce = function(owner, reinforcementNames, enterLocation, rallyPointLocation, interval, onCreateFunc) + local facing = { Map.GetFacing(CPos.op_Subtraction(rallyPointLocation, enterLocation), 0), "Int32" } + local ret = { } + for i = 1, #reinforcementNames do + local reinforcement = Actor.Create(reinforcementNames[i], { AddToWorld = false, Owner = owner, Location = enterLocation, Facing = facing }) + table.insert(ret, reinforcement) + OpenRA.RunAfterDelay((i - 1) * interval, function() + World:Add(reinforcement) + Actor.MoveNear(reinforcement, rallyPointLocation, 2) + if onCreateFunc ~= nil then + onCreateFunc(reinforcement) + end + end) + end + return ret +end + +Mission.Parabomb = function(owner, planeName, enterLocation, bombLocation) + local facing = { Map.GetFacing(CPos.op_Subtraction(bombLocation, enterLocation), 0), "Int32" } + local altitude = { Actor.TraitInfo(planeName, "AircraftInfo").CruiseAltitude, "Int32" } + local plane = Actor.Create(planeName, { Location = enterLocation, Owner = owner, Facing = facing, Altitude = altitude }) + Actor.Trait(plane, "AttackBomber"):SetTarget(bombLocation.CenterPosition) + Actor.Fly(plane, bombLocation.CenterPosition) + Actor.FlyOffMap(plane) + Actor.RemoveSelf(plane) +end + +Mission.Paradrop = function(owner, planeName, passengerNames, enterLocation, dropLocation) + local facing = { Map.GetFacing(CPos.op_Subtraction(dropLocation, enterLocation), 0), "Int32" } + local altitude = { Actor.TraitInfo(planeName, "AircraftInfo").CruiseAltitude, "Int32" } + local plane = Actor.Create(planeName, { Location = enterLocation, Owner = owner, Facing = facing, Altitude = altitude }) + Actor.FlyAttackCell(plane, dropLocation) + Actor.Trait(plane, "ParaDrop"):SetLZ(dropLocation) + local cargo = Actor.Trait(plane, "Cargo") + for i, passengerName in ipairs(passengerNames) do + cargo:Load(plane, Actor.Create(passengerName, { AddToWorld = false, Owner = owner })) + end +end + +Mission.MissionOver = function(winners, losers, setWinStates) + World:SetLocalPauseState(true) + World:set_PauseStateLocked(true) + if winners then + for i, player in ipairs(winners) do + Media.PlaySpeechNotification("Win", player) + if setWinStates then + OpenRA.SetWinState(player, "Won") + end + end + end + if losers then + for i, player in ipairs(losers) do + Media.PlaySpeechNotification("Lose", player) + if setWinStates then + OpenRA.SetWinState(player, "Lost") + end + end + end + Mission.MissionIsOver = true +end + +Mission.GetGroundAttackersOf = function(player) + return Utils.EnumerableWhere(World.Actors, function(actor) + return not Actor.IsDead(actor) and Actor.IsInWorld(actor) and Actor.Owner(actor) == player and Actor.HasTrait(actor, "AttackBase") and Actor.HasTrait(actor, "Mobile") + end) +end + +Mission.TickTakeOre = function(player) + OpenRA.TakeOre(player, 0.01 * OpenRA.GetOreCapacity(player) / 25) +end + +Mission.RequiredUnitsAreDestroyed = function(player) + return Internal.RequiredUnitsAreDestroyed(player) +end \ No newline at end of file diff --git a/mods/ra/lua/openra.lua b/mods/ra/lua/openra.lua new file mode 100644 index 0000000000..ae746d2db4 --- /dev/null +++ b/mods/ra/lua/openra.lua @@ -0,0 +1,69 @@ +OpenRA = { } + +OpenRA.New = function(className, args) + return Internal.New(className, args) +end + +OpenRA.RunAfterDelay = function(delay, func) + Internal.RunAfterDelay(delay, func) +end + +OpenRA.Debug = function(obj) + Internal.Debug(obj) +end + +OpenRA.SetViewportCenterPosition = function(position) + WorldRenderer.Viewport:Center(position) +end + +OpenRA.GetViewportCenterPosition = function() + return WorldRenderer.Viewport.CenterPosition +end + +OpenRA.GetDifficulty = function() + return World.LobbyInfo.GlobalSettings.Difficulty +end + +OpenRA.IsSinglePlayer = function() + return World.LobbyInfo:get_IsSinglePlayer() +end + +OpenRA.GetPlayer = function(internalName) + return Utils.EnumerableFirstOrNil(World.Players, function(p) return p.InternalName == internalName end) +end + +OpenRA.SetWinState = function(player, winState) + Internal.SetWinState(player, winState) +end + +OpenRA.TakeOre = function(player, amount) + Actor.Trait(player.PlayerActor, "PlayerResources"):TakeOre(amount) +end + +OpenRA.TakeCash = function(player, amount) + Actor.Trait(player.PlayerActor, "PlayerResources"):TakeCash(amount) +end + +OpenRA.GiveOre = function(player, amount) + Actor.Trait(player.PlayerActor, "PlayerResources"):GiveOre(amount) +end + +OpenRA.GiveCash = function(player, amount) + Actor.Trait(player.PlayerActor, "PlayerResources"):GiveCash(amount) +end + +OpenRA.CanGiveOre = function(player, amount) + return Actor.Trait(player.PlayerActor, "PlayerResources"):CanGiveOre(amount) +end + +OpenRA.GetOreCapacity = function(player) + return Actor.Trait(player.PlayerActor, "PlayerResources").OreCapacity +end + +OpenRA.GetOre = function(player) + return Actor.Trait(player.PlayerActor, "PlayerResources").Ore +end + +OpenRA.GetCash = function(player) + return Actor.Trait(player.PlayerActor, "PlayerResources").Cash +end \ No newline at end of file diff --git a/mods/ra/lua/team.lua b/mods/ra/lua/team.lua new file mode 100644 index 0000000000..f77a0733ed --- /dev/null +++ b/mods/ra/lua/team.lua @@ -0,0 +1,61 @@ +Team = { } + +Team.Create = function(actors) + local team = { } + team.Actors = actors + team.OnAllKilled = { } + team.OnAnyKilled = { } + team.OnAllRemovedFromWorld = { } + team.OnAnyRemovedFromWorld = { } + Team.AddActorEventHandlers(team) + return team +end + +Team.AddActorEventHandlers = function(team) + for i, actor in ipairs(team.Actors) do + + Actor.OnKilled(actor, function() + Team.InvokeHandlers(team.OnAnyKilled) + if Team.AllAreDead(team) then Team.InvokeHandlers(team.OnAllKilled) end + end) + + Actor.OnRemovedFromWorld(actor, function() + Team.InvokeHandlers(team.OnAnyRemovedFromWorld) + if not Team.AnyAreInWorld(team) then Team.InvokeHandlers(team.OnAllRemovedFromWorld) end + end) + end +end + +Team.InvokeHandlers = function(event) + for i, handler in ipairs(event) do + handler() + end +end + +Team.AllAreDead = function(team) + return Utils.All(team.Actors, Actor.IsDead) +end + +Team.AnyAreDead = function(team) + return Utils.Any(team.Actors, Actor.IsDead) +end + +Team.AllAreInWorld = function(team) + return Utils.All(team.Actors, Actor.IsInWorld) +end + +Team.AnyAreInWorld = function(team) + return Utils.Any(team.Actors, Actor.IsInWorld) +end + +Team.AddEventHandler = function(event, func) + table.insert(event, func) +end + +Team.Contains = function(team, actor) + return Utils.Any(team.Actors, function(a) return a == actor end) +end + +Team.Do = function(team, func) + Utils.ForEach(team.Actors, func) +end \ No newline at end of file diff --git a/mods/ra/lua/utils.lua b/mods/ra/lua/utils.lua new file mode 100644 index 0000000000..9a486d88dc --- /dev/null +++ b/mods/ra/lua/utils.lua @@ -0,0 +1,67 @@ +Utils = { } + +Utils.Enumerate = function(netEnumerable) + local enum = netEnumerable:GetEnumerator() + return function() + if enum:MoveNext() then + return enum:get_Current() + end + end +end + +Utils.EnumerableFirstOrNil = function(netEnumerable, func) + for item in Utils.Enumerate(netEnumerable) do + if func(item) then + return item + end + end + return nil +end + +Utils.EnumerableWhere = function(netEnumerable, func) + local ret = { } + for item in Utils.Enumerate(netEnumerable) do + if func(item) then + table.insert(ret, item) + end + end + return ret +end + +Utils.Where = function(array, func) + local ret = { } + for i, item in ipairs(array) do + if func(item) then + table.insert(ret, item) + end + end + return ret +end + +Utils.All = function(array, func) + for i, item in ipairs(array) do + if not func(item) then + return false + end + end + return true +end + +Utils.Any = function(array, func) + for i, item in ipairs(array) do + if func(item) then + return true + end + end + return false +end + +Utils.ForEach = function(array, func) + for i, item in ipairs(array) do + func(item) + end +end + +Utils.TableToArray = function(luaTable) + return Internal.TableToArray(luaTable) +end \ No newline at end of file diff --git a/mods/ra/mod.yaml b/mods/ra/mod.yaml index d694d00fd3..e36a9a7edb 100644 --- a/mods/ra/mod.yaml +++ b/mods/ra/mod.yaml @@ -164,3 +164,12 @@ Fonts: TinyBold: Font:FreeSansBold.ttf Size:10 + +LuaScripts: + mods/ra/lua/utils.lua + mods/ra/lua/openra.lua + mods/ra/lua/map.lua + mods/ra/lua/actor.lua + mods/ra/lua/team.lua + mods/ra/lua/media.lua + mods/ra/lua/mission.lua diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml index 9366e89531..87f214d0c2 100644 --- a/mods/ra/rules/defaults.yaml +++ b/mods/ra/rules/defaults.yaml @@ -42,6 +42,8 @@ SuccessRate: 20 EjectOnGround: yes EjectInAir: no + Huntable: + LuaScriptEvents: ^Tank: AppearsOnRadar: @@ -87,6 +89,8 @@ SuccessRate: 20 EjectOnGround: yes EjectInAir: no + Huntable: + LuaScriptEvents: ^Infantry: AppearsOnRadar: @@ -142,6 +146,8 @@ HealIfBelow: 1 DamageCooldown: 125 RequiresTech: InfantryHealing + Huntable: + LuaScriptEvents: ^Ship: AppearsOnRadar: @@ -174,6 +180,8 @@ Guard: Guardable: BodyOrientation: + Huntable: + LuaScriptEvents: ^Plane: AppearsOnRadar: @@ -203,6 +211,8 @@ UpdatesPlayerStatistics: CombatDebugOverlay: BodyOrientation: + Huntable: + LuaScriptEvents: ^Helicopter: Inherits: ^Plane @@ -252,6 +262,8 @@ FrozenUnderFog: GpsDot: String:Structure + Huntable: + LuaScriptEvents: ^Wall: AppearsOnRadar: @@ -287,6 +299,7 @@ Guardable: BodyOrientation: FrozenUnderFog: + LuaScriptEvents: ^TechBuilding: Inherits: ^Building @@ -391,6 +404,7 @@ BodyOrientation: FrozenUnderFog: StartsRevealed: true + LuaScriptEvents: ^Husk: Husk: @@ -408,6 +422,7 @@ BelowUnits: BodyOrientation: Chronoshiftable: + LuaScriptEvents: ^HelicopterHusk: Inherits: ^Husk @@ -442,6 +457,7 @@ Types:Bridge AutoTargetIgnore: BodyOrientation: + LuaScriptEvents: #Temperate Terrain Expansion ^SVBridge: @@ -459,6 +475,7 @@ Types:Bridge AutoTargetIgnore: BodyOrientation: + LuaScriptEvents: ^SHBridge: Tooltip: @@ -475,6 +492,7 @@ Types:Bridge AutoTargetIgnore: BodyOrientation: + LuaScriptEvents: ^STDBridge: Tooltip: @@ -491,6 +509,7 @@ Types:Bridge AutoTargetIgnore: BodyOrientation: + LuaScriptEvents: #Desert Terrain Expansion: ^Rock: @@ -512,6 +531,7 @@ BodyOrientation: FrozenUnderFog: StartsRevealed: true + LuaScriptEvents: ^DesertCivBuilding: Inherits: ^CivBuilding diff --git a/mods/ts/mod.yaml b/mods/ts/mod.yaml index 63adc87e73..0030ff7b92 100644 --- a/mods/ts/mod.yaml +++ b/mods/ts/mod.yaml @@ -185,3 +185,12 @@ Fonts: TinyBold: Font:FreeSansBold.ttf Size:10 + +LuaScripts: + mods/ra/lua/utils.lua + mods/ra/lua/openra.lua + mods/ra/lua/map.lua + mods/ra/lua/actor.lua + mods/ra/lua/team.lua + mods/ra/lua/media.lua + mods/ra/lua/mission.lua diff --git a/mods/ts/rules/defaults.yaml b/mods/ts/rules/defaults.yaml index 3ef39c5683..9c692cc530 100644 --- a/mods/ts/rules/defaults.yaml +++ b/mods/ts/rules/defaults.yaml @@ -36,6 +36,8 @@ Guardable: Range: 3 BodyOrientation: + Huntable: + LuaScriptEvents: ^Infantry: AppearsOnRadar: @@ -80,6 +82,8 @@ Guard: Guardable: BodyOrientation: + Huntable: + LuaScriptEvents: ^CivilianInfantry: Inherits: ^Infantry @@ -145,6 +149,8 @@ Guard: Guardable: BodyOrientation: + Huntable: + LuaScriptEvents: ^Wall: AppearsOnRadar: @@ -175,6 +181,7 @@ Sellable: UpdatesPlayerStatistics: BodyOrientation: + LuaScriptEvents: ^Helicopter: AppearsOnRadar: @@ -197,4 +204,6 @@ DrawLineToTarget: ActorLostNotification: CombatDebugOverlay: - BodyOrientation: \ No newline at end of file + BodyOrientation: + Huntable: + LuaScriptEvents: \ No newline at end of file From f7c39aaf3b25b09348c3bc0ecff2d44ed97d8a52 Mon Sep 17 00:00:00 2001 From: ScottNZ Date: Fri, 29 Nov 2013 23:49:14 +1300 Subject: [PATCH 07/11] Add some additional mission notifications to ra's notifications.yaml --- mods/ra/notifications.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mods/ra/notifications.yaml b/mods/ra/notifications.yaml index aeab522df8..ba56e3698c 100644 --- a/mods/ra/notifications.yaml +++ b/mods/ra/notifications.yaml @@ -24,7 +24,10 @@ Speech: NavalUnitLost: navylst1 AirUnitLost: aunitl1 BuildingCaptured: strucap1 - + ReinforcementsArrived: reinfor1 + SignalFlareNorth: flaren1 + AlliedReinforcementsArrived: aarrive1 + ConvoyApproaching: convyap1 Sounds: Notifications: From 1c09d4434b99b24c03ab5a7ba298ca27f5408477 Mon Sep 17 00:00:00 2001 From: ScottNZ Date: Fri, 29 Nov 2013 23:49:29 +1300 Subject: [PATCH 08/11] Fix Einstein's voice --- mods/ra/voices.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/ra/voices.yaml b/mods/ra/voices.yaml index 27b02ec431..5eab711aa4 100644 --- a/mods/ra/voices.yaml +++ b/mods/ra/voices.yaml @@ -78,8 +78,8 @@ CivilianFemaleVoice: EinsteinVoice: Voices: - Select: einah1,einok1,einyes1 - Move: einah1,einok1,einyes1 + Select: einah1 + Move: einok1,einyes1 Die: dedman1,dedman2,dedman3,dedman4,dedman5,dedman6,dedman7,dedman8,dedman10 ShokVoice: From 0ca8f41114611330bfa5aa398058299cc6ad1df0 Mon Sep 17 00:00:00 2001 From: ScottNZ Date: Fri, 29 Nov 2013 23:49:41 +1300 Subject: [PATCH 09/11] Add two Lua-powered single player missions --- mods/ra/maps/allies-01-classic/map.bin | Bin 0 -> 81925 bytes mods/ra/maps/allies-01-classic/map.yaml | 626 ++++++++++++++ mods/ra/maps/allies-01-classic/mission.lua | 151 ++++ mods/ra/maps/allies-02-classic/map.bin | Bin 0 -> 81925 bytes mods/ra/maps/allies-02-classic/map.yaml | 954 +++++++++++++++++++++ mods/ra/maps/allies-02-classic/mission.lua | 78 ++ 6 files changed, 1809 insertions(+) create mode 100644 mods/ra/maps/allies-01-classic/map.bin create mode 100644 mods/ra/maps/allies-01-classic/map.yaml create mode 100644 mods/ra/maps/allies-01-classic/mission.lua create mode 100644 mods/ra/maps/allies-02-classic/map.bin create mode 100644 mods/ra/maps/allies-02-classic/map.yaml create mode 100644 mods/ra/maps/allies-02-classic/mission.lua diff --git a/mods/ra/maps/allies-01-classic/map.bin b/mods/ra/maps/allies-01-classic/map.bin new file mode 100644 index 0000000000000000000000000000000000000000..c99d9acca037b1f2eeb0ba330f0b96b397670335 GIT binary patch literal 81925 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 Date: Fri, 29 Nov 2013 23:49:49 +1300 Subject: [PATCH 10/11] Update CHANGELOG --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 6edcfcdd2f..6ed0628ca7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -52,6 +52,7 @@ NEW: Adjusted Zombie build palette position. Fixed attack dogs causing crashes by attacking non-infantry. Disabled cloak/uncloak sound for camouflaged Pillbox. + Added two Lua-powered single player missions, ported from Red Alert's single player campaign. Tiberian Dawn: C&C mod renamed to Tiberian Dawn to resolve naming ambiguities. Fixed Bio Lab wrongly belonging to a hostile faction in East vs West 3. From aa5ea1a3cea3e2945df1c754322d609f37461fad Mon Sep 17 00:00:00 2001 From: ScottNZ Date: Sat, 30 Nov 2013 09:59:22 +1300 Subject: [PATCH 11/11] Fix bots not deploying their mcv as a result of the DeployTransform change --- OpenRA.Mods.RA/AI/HackyAI.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenRA.Mods.RA/AI/HackyAI.cs b/OpenRA.Mods.RA/AI/HackyAI.cs index 5c12c0935e..a5e8a46e68 100644 --- a/OpenRA.Mods.RA/AI/HackyAI.cs +++ b/OpenRA.Mods.RA/AI/HackyAI.cs @@ -738,8 +738,8 @@ namespace OpenRA.Mods.RA.AI if (desiredLocation == null) continue; - world.IssueOrder(new Order("Move", mcv, false) { TargetLocation = desiredLocation.Value }); - world.IssueOrder(new Order("DeployTransform", mcv, false)); + world.IssueOrder(new Order("Move", mcv, true) { TargetLocation = desiredLocation.Value }); + world.IssueOrder(new Order("DeployTransform", mcv, true)); } }