From b2e9de810e05956984874b6c785d5f189e81351a Mon Sep 17 00:00:00 2001 From: ScottNZ Date: Mon, 16 Dec 2013 19:01:54 +1300 Subject: [PATCH 1/9] Add CPos.New etc functions to Lua standard library and helpers to LuaScriptInterface.cs. Rename Team.Create to Team.New. --- .../Scripting/LuaScriptInterface.cs | 42 ++++++++++++++++++ mods/cnc/maps/shellmap/shellmap.lua | 13 +----- mods/ra/lua/actor.lua | 18 +++++++- mods/ra/lua/map.lua | 44 +++++++++++++++++-- mods/ra/lua/mission.lua | 4 +- mods/ra/lua/openra.lua | 10 ++++- mods/ra/lua/team.lua | 2 +- mods/ra/maps/allies-01-classic/mission.lua | 4 +- mods/ra/maps/allies-02-classic/mission.lua | 2 +- 9 files changed, 117 insertions(+), 22 deletions(-) diff --git a/OpenRA.Mods.RA/Scripting/LuaScriptInterface.cs b/OpenRA.Mods.RA/Scripting/LuaScriptInterface.cs index 69345ff428..f47ee46e0b 100644 --- a/OpenRA.Mods.RA/Scripting/LuaScriptInterface.cs +++ b/OpenRA.Mods.RA/Scripting/LuaScriptInterface.cs @@ -9,6 +9,7 @@ #endregion using System; +using System.Collections; using System.Linq; using NLua; using OpenRA.Effects; @@ -49,6 +50,7 @@ namespace OpenRA.Mods.RA.Scripting context.Lua["WorldRenderer"] = wr; context.RegisterObject(this, "Internal", false); context.RegisterType(typeof(WVec), "WVec", true); + context.RegisterType(typeof(CVec), "CVec", true); context.RegisterType(typeof(WPos), "WPos", true); context.RegisterType(typeof(CPos), "CPos", true); context.RegisterType(typeof(WRot), "WRot", true); @@ -146,6 +148,19 @@ namespace OpenRA.Mods.RA.Scripting return ret != null; } + [LuaGlobal] + public object[] ActorsWithTrait(string className) + { + var type = Game.modData.ObjectCreator.FindType(className); + if (type == null) + throw new InvalidOperationException("Cannot locate type: {0}".F(className)); + + var method = typeof(World).GetMethod("ActorsWithTrait"); + var genericMethod = method.MakeGenericMethod(type); + var result = ((IEnumerable)genericMethod.Invoke(world, null)).Cast().ToArray(); + return result; + } + [LuaGlobal] public object TraitInfoOrDefault(string actorType, string className) { @@ -273,5 +288,32 @@ namespace OpenRA.Mods.RA.Scripting { return world.ActorsWithTrait().All(p => p.Actor.Owner != player); } + + [LuaGlobal] + public void AttackMove(Actor actor, CPos location) + { + if (actor.HasTrait()) + actor.QueueActivity(new AttackMove.AttackMoveActivity(actor, new Move.Move(location, 0))); + else + actor.QueueActivity(new Move.Move(location, 0)); + } + + [LuaGlobal] + public int GetRandomInteger(double low, double high) + { + return world.SharedRandom.Next((int)low, (int)high); + } + + [LuaGlobal] + public CPos GetRandomCell() + { + return world.ChooseRandomCell(world.SharedRandom); + } + + [LuaGlobal] + public CPos GetRandomEdgeCell() + { + return world.ChooseRandomEdgeCell(); + } } } diff --git a/mods/cnc/maps/shellmap/shellmap.lua b/mods/cnc/maps/shellmap/shellmap.lua index d47573a29e..ba266799b2 100644 --- a/mods/cnc/maps/shellmap/shellmap.lua +++ b/mods/cnc/maps/shellmap/shellmap.lua @@ -5,7 +5,7 @@ speed = 5 Tick = function() ticks = ticks + 1 local t = (ticks + 45) % (360 * speed) * (math.pi / 180) / speed; - OpenRA.SetViewportCenterPosition(WPos.op_Addition(viewportOrigin, MakeVec(-15360 * math.sin(t), 4096 * math.cos(t)))) + OpenRA.SetViewportCenterPosition(WPos.op_Addition(viewportOrigin, WVec.New(-15360 * math.sin(t), 4096 * math.cos(t)))) end WorldLoaded = function() @@ -16,7 +16,7 @@ WorldLoaded = function() local units = { boat1, boat2, boat3, boat4, lst1, lst2, lst3} for i, unit in ipairs(units) do - LoopTrack(unit, MakePos(8, unit.Location.Y), MakePos(87, unit.Location.Y)) + LoopTrack(unit, CPos.New(8, unit.Location.Y), CPos.New(87, unit.Location.Y)) end end @@ -34,13 +34,4 @@ CreateUnitsInTransport = function(transport, passengerNames) for i, passengerName in ipairs(passengerNames) do cargo:Load(transport, Actor.Create(passengerName, { AddToWorld = false, Owner = owner, Facing = { facing, "Int32" } })) end -end - --- TODO: The standard library should expose CPos.New() etc -MakePos = function(x, y) - return OpenRA.New("CPos", { {x, "Int32"}, {y, "Int32"} }) -end - -MakeVec = function(x, y) - return OpenRA.New("WVec", { {x, "Int32"}, {y, "Int32"}, {0, "Int32"} }) end \ No newline at end of file diff --git a/mods/ra/lua/actor.lua b/mods/ra/lua/actor.lua index 4e50e923b9..328b62bafc 100644 --- a/mods/ra/lua/actor.lua +++ b/mods/ra/lua/actor.lua @@ -24,7 +24,7 @@ Actor.Move = function(actor, location) end Actor.MoveNear = function(actor, location, nearEnough) - actor:QueueActivity(OpenRA.New("Move", { location, Map.GetWRangeFromCells(nearEnough) })) + actor:QueueActivity(OpenRA.New("Move", { location, WRange.FromCells(nearEnough) })) end Actor.ScriptedMove = function(actor, location) @@ -35,6 +35,10 @@ Actor.Teleport = function(actor, location) actor:QueueActivity(OpenRA.New("SimpleTeleport", { location })) end +Actor.AttackMove = function(actor, location) + Internal.AttackMove(actor, location) +end + Actor.HeliFly = function(actor, position) actor:QueueActivity(OpenRA.New("HeliFly", { position })) end @@ -119,6 +123,10 @@ Actor.Facing = function(actor) return Actor.Trait(actor, "IFacing"):get_Facing() end +Actor.IsIdle = function(actor) + return actor.IsIdle +end + Actor.SetStance = function(actor, stance) Internal.SetUnitStance(actor, stance) end @@ -135,6 +143,14 @@ Actor.OnRemovedFromWorld = function(actor, eh) Actor.Trait(actor, "LuaScriptEvents").OnRemovedFromWorld:Add(eh) end +Actor.ActorsWithTrait = function(className) + local ret = { } + for item in Utils.Enumerate(Internal.ActorsWithTrait(className)) do + table.insert(ret, item.Actor) + end + return ret +end + Actor.HasTrait = function(actor, className) return Internal.HasTrait(actor, className) end diff --git a/mods/ra/lua/map.lua b/mods/ra/lua/map.lua index 39ed982234..ae53c5fcd2 100644 --- a/mods/ra/lua/map.lua +++ b/mods/ra/lua/map.lua @@ -4,6 +4,44 @@ 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 +Map.GetRandomCell = function() + return Internal.GetRandomCell() +end + +Map.GetRandomEdgeCell = function() + return Internal.GetRandomEdgeCell() +end + +CPos.New = function(x, y) + return OpenRA.New("CPos", { { x, "Int32" }, { y, "Int32" } }) +end + +WPos.New = function(x, y, z) + if z == nil then + z = 0 + end + return OpenRA.New("WPos", { { x, "Int32" }, { y, "Int32" }, { z, "Int32" } }) +end + +WPos.FromCPos = function(location) + return WPos.New(location.X * 1024, location.Y * 1024, 0) +end + +CVec.New = function(x, y) + return OpenRA.New("CVec", { { x, "Int32" }, { y, "Int32" } }) +end + +WVec.New = function(x, y, z) + if z == nil then + z = 0 + end + return OpenRA.New("WVec", { { x, "Int32" }, { y, "Int32" }, { z, "Int32" } }) +end + +WRange.New = function(r) + return OpenRA.New("WRange", { { r, "Int32" } }) +end + +WRange.FromCells = function(cells) + return WRange.New(cells * 1024) +end diff --git a/mods/ra/lua/mission.lua b/mods/ra/lua/mission.lua index 94fca80214..ae942766ea 100644 --- a/mods/ra/lua/mission.lua +++ b/mods/ra/lua/mission.lua @@ -23,8 +23,8 @@ Mission.MissionOver = function(winners, losers, setWinStates) 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") + return Utils.Where(Actor.ActorsWithTrait("AttackBase"), function(actor) + return not Actor.IsDead(actor) and Actor.IsInWorld(actor) and Actor.Owner(actor) == player and Actor.HasTrait(actor, "Mobile") end) end diff --git a/mods/ra/lua/openra.lua b/mods/ra/lua/openra.lua index 64589a1ba1..16f1e02671 100644 --- a/mods/ra/lua/openra.lua +++ b/mods/ra/lua/openra.lua @@ -33,10 +33,18 @@ OpenRA.GetPlayer = function(internalName) return Utils.EnumerableFirstOrNil(World.Players, function(p) return p.InternalName == internalName end) end +OpenRA.GetPlayers = function(func) + return Utils.EnumerableWhere(World.Players, func) +end + OpenRA.SetWinState = function(player, winState) Internal.SetWinState(player, winState) end +OpenRA.GetRandomInteger = function(low, high) + return Internal.GetRandomInteger(low, high) +end + OpenRA.TakeOre = function(player, amount) Actor.Trait(player.PlayerActor, "PlayerResources"):TakeOre(amount) end @@ -67,4 +75,4 @@ end OpenRA.GetCash = function(player) return Actor.Trait(player.PlayerActor, "PlayerResources").Cash -end \ No newline at end of file +end diff --git a/mods/ra/lua/team.lua b/mods/ra/lua/team.lua index f77a0733ed..f81fed4bcc 100644 --- a/mods/ra/lua/team.lua +++ b/mods/ra/lua/team.lua @@ -1,6 +1,6 @@ Team = { } -Team.Create = function(actors) +Team.New = function(actors) local team = { } team.Actors = actors team.OnAllKilled = { } diff --git a/mods/ra/maps/allies-01-classic/mission.lua b/mods/ra/maps/allies-01-classic/mission.lua index c52bf6be7b..86e0198865 100644 --- a/mods/ra/maps/allies-01-classic/mission.lua +++ b/mods/ra/maps/allies-01-classic/mission.lua @@ -134,10 +134,10 @@ WorldLoaded = function() Actor.OnKilled(Lab, LabDestroyed) Actor.OnKilled(OilPump, OilPumpDestroyed) - labGuardsTeam = Team.Create({ LabGuard1, LabGuard2, LabGuard3 }) + labGuardsTeam = Team.New({ LabGuard1, LabGuard2, LabGuard3 }) Team.AddEventHandler(labGuardsTeam.OnAllKilled, LabGuardsKilled) - civiliansTeam = Team.Create({ Civilian1, Civilian2 }) + civiliansTeam = Team.New({ Civilian1, Civilian2 }) RunInitialActivities() diff --git a/mods/ra/maps/allies-02-classic/mission.lua b/mods/ra/maps/allies-02-classic/mission.lua index 1c2ae5d54d..4b5a237368 100644 --- a/mods/ra/maps/allies-02-classic/mission.lua +++ b/mods/ra/maps/allies-02-classic/mission.lua @@ -54,7 +54,7 @@ SendTrucks = function() Actor.Move(truck, TruckExitPoint.Location) Actor.RemoveSelf(truck) end) - local trucksTeam = Team.Create(trucks) + local trucksTeam = Team.New(trucks) Team.AddEventHandler(trucksTeam.OnAllRemovedFromWorld, MissionAccomplished) Team.AddEventHandler(trucksTeam.OnAnyKilled, MissionFailed) end) From e8fb96c55f4d896834bca514d066da5c43ec6401 Mon Sep 17 00:00:00 2001 From: ScottNZ Date: Mon, 16 Dec 2013 19:02:35 +1300 Subject: [PATCH 2/9] Add Lua cargo insertion code and Utils.Skip. Needed for Allies 03 Classic. --- mods/ra/lua/reinforcements.lua | 21 +++++++++++++++++++++ mods/ra/lua/team.lua | 2 +- mods/ra/lua/utils.lua | 12 +++++++++++- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/mods/ra/lua/reinforcements.lua b/mods/ra/lua/reinforcements.lua index 7f3046d6e1..b5f42f0b94 100644 --- a/mods/ra/lua/reinforcements.lua +++ b/mods/ra/lua/reinforcements.lua @@ -38,6 +38,27 @@ Reinforcements.PerformHelicopterExtraction = function(owner, helicopterName, pas return heli end +Reinforcements.PerformInsertion = function(owner, vehicleName, passengerNames, enterPath, exitPath) + local facing = { 0, "Int32" } + if #enterPath > 1 then + facing = { Map.GetFacing(CPos.op_Subtraction(enterPath[2], enterPath[1]), 0), "Int32" } + end + local vehicle = Actor.Create(vehicleName, { Owner = owner, Location = enterPath[1], Facing = facing }) + local cargo = Actor.Trait(vehicle, "Cargo") + local passengers = { } + for i, passengerName in ipairs(passengerNames) do + local passenger = Actor.Create(passengerName, { AddToWorld = false, Owner = owner }) + passengers[i] = passenger + cargo:Load(vehicle, passenger) + end + Utils.Do(Utils.Skip(enterPath, 1), function(l) Actor.ScriptedMove(vehicle, l) end) + Actor.UnloadCargo(vehicle, true) + Actor.Wait(vehicle, 25) + Utils.Do(exitPath, function(l) Actor.ScriptedMove(vehicle, l) end) + Actor.RemoveSelf(vehicle) + return vehicle, passengers +end + Reinforcements.Reinforce = function(owner, reinforcementNames, enterLocation, rallyPointLocation, interval, onCreateFunc) local facing = { Map.GetFacing(CPos.op_Subtraction(rallyPointLocation, enterLocation), 0), "Int32" } local reinforcements = { } diff --git a/mods/ra/lua/team.lua b/mods/ra/lua/team.lua index f81fed4bcc..6d41af2d23 100644 --- a/mods/ra/lua/team.lua +++ b/mods/ra/lua/team.lua @@ -57,5 +57,5 @@ Team.Contains = function(team, actor) end Team.Do = function(team, func) - Utils.ForEach(team.Actors, func) + Utils.Do(team.Actors, func) end \ No newline at end of file diff --git a/mods/ra/lua/utils.lua b/mods/ra/lua/utils.lua index 9a486d88dc..eab8cbe6d7 100644 --- a/mods/ra/lua/utils.lua +++ b/mods/ra/lua/utils.lua @@ -56,12 +56,22 @@ Utils.Any = function(array, func) return false end -Utils.ForEach = function(array, func) +Utils.Do = function(array, func) for i, item in ipairs(array) do func(item) end end +Utils.Skip = function(array, n) + local ret = { } + for i, item in ipairs(array) do + if i > n then + table.insert(ret, item) + end + end + return ret +end + Utils.TableToArray = function(luaTable) return Internal.TableToArray(luaTable) end \ No newline at end of file From 23cb4defa358f235b04489d1a16facf13f393a10 Mon Sep 17 00:00:00 2001 From: ScottNZ Date: Tue, 17 Dec 2013 18:07:54 +1300 Subject: [PATCH 3/9] Update KopiLua.dll with some more dangerous bits removed, and remove strong naming from KopiLua/NLua --- thirdparty/KopiLua.dll | Bin 245760 -> 245248 bytes thirdparty/NLua.dll | Bin 76288 -> 75776 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/thirdparty/KopiLua.dll b/thirdparty/KopiLua.dll index 18497eb8ff62589116f44aecf44cff90a507073d..5b7b8daa0acf5d184876abf5e100daf694b140cc 100644 GIT binary patch delta 27165 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�rg$grHF!8gPb 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 bl1yb-J%3+5z!ML(cSfDh4*nu_*~R|@AA7zO delta 28153 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%0D?Wnh*#A!PrJDysxJ-O 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 diff --git a/thirdparty/NLua.dll b/thirdparty/NLua.dll index 165ead6625708036013784eedc9ab1f2cbf32daf..c243e85849023e3785553af0fa5b8f9c30bdef96 100644 GIT binary patch delta 9985 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 From a4f3caa6e72980ef385fe8bd36188c4796842c08 Mon Sep 17 00:00:00 2001 From: ScottNZ Date: Wed, 18 Dec 2013 16:09:44 +1300 Subject: [PATCH 4/9] Moved mods/ra/lua to mods/common/lua --- mods/cnc/mod.yaml | 18 +++++++++--------- mods/{ra => common}/lua/actor.lua | 0 mods/{ra => common}/lua/map.lua | 0 mods/{ra => common}/lua/media.lua | 0 mods/{ra => common}/lua/mission.lua | 0 mods/{ra => common}/lua/openra.lua | 0 mods/{ra => common}/lua/reinforcements.lua | 0 mods/{ra => common}/lua/supportpowers.lua | 0 mods/{ra => common}/lua/team.lua | 0 mods/{ra => common}/lua/utils.lua | 0 mods/d2k/mod.yaml | 18 +++++++++--------- mods/ra/mod.yaml | 18 +++++++++--------- mods/ts/mod.yaml | 18 +++++++++--------- 13 files changed, 36 insertions(+), 36 deletions(-) rename mods/{ra => common}/lua/actor.lua (100%) rename mods/{ra => common}/lua/map.lua (100%) rename mods/{ra => common}/lua/media.lua (100%) rename mods/{ra => common}/lua/mission.lua (100%) rename mods/{ra => common}/lua/openra.lua (100%) rename mods/{ra => common}/lua/reinforcements.lua (100%) rename mods/{ra => common}/lua/supportpowers.lua (100%) rename mods/{ra => common}/lua/team.lua (100%) rename mods/{ra => common}/lua/utils.lua (100%) diff --git a/mods/cnc/mod.yaml b/mods/cnc/mod.yaml index 369bf87239..32fbde44b8 100644 --- a/mods/cnc/mod.yaml +++ b/mods/cnc/mod.yaml @@ -165,12 +165,12 @@ Fonts: 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 - mods/ra/lua/reinforcements.lua - mods/ra/lua/supportpowers.lua + mods/common/lua/utils.lua + mods/common/lua/openra.lua + mods/common/lua/map.lua + mods/common/lua/actor.lua + mods/common/lua/team.lua + mods/common/lua/media.lua + mods/common/lua/mission.lua + mods/common/lua/reinforcements.lua + mods/common/lua/supportpowers.lua diff --git a/mods/ra/lua/actor.lua b/mods/common/lua/actor.lua similarity index 100% rename from mods/ra/lua/actor.lua rename to mods/common/lua/actor.lua diff --git a/mods/ra/lua/map.lua b/mods/common/lua/map.lua similarity index 100% rename from mods/ra/lua/map.lua rename to mods/common/lua/map.lua diff --git a/mods/ra/lua/media.lua b/mods/common/lua/media.lua similarity index 100% rename from mods/ra/lua/media.lua rename to mods/common/lua/media.lua diff --git a/mods/ra/lua/mission.lua b/mods/common/lua/mission.lua similarity index 100% rename from mods/ra/lua/mission.lua rename to mods/common/lua/mission.lua diff --git a/mods/ra/lua/openra.lua b/mods/common/lua/openra.lua similarity index 100% rename from mods/ra/lua/openra.lua rename to mods/common/lua/openra.lua diff --git a/mods/ra/lua/reinforcements.lua b/mods/common/lua/reinforcements.lua similarity index 100% rename from mods/ra/lua/reinforcements.lua rename to mods/common/lua/reinforcements.lua diff --git a/mods/ra/lua/supportpowers.lua b/mods/common/lua/supportpowers.lua similarity index 100% rename from mods/ra/lua/supportpowers.lua rename to mods/common/lua/supportpowers.lua diff --git a/mods/ra/lua/team.lua b/mods/common/lua/team.lua similarity index 100% rename from mods/ra/lua/team.lua rename to mods/common/lua/team.lua diff --git a/mods/ra/lua/utils.lua b/mods/common/lua/utils.lua similarity index 100% rename from mods/ra/lua/utils.lua rename to mods/common/lua/utils.lua diff --git a/mods/d2k/mod.yaml b/mods/d2k/mod.yaml index 857a1c26e8..e670180373 100644 --- a/mods/d2k/mod.yaml +++ b/mods/d2k/mod.yaml @@ -145,12 +145,12 @@ Fonts: 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 - mods/ra/lua/reinforcements.lua - mods/ra/lua/supportpowers.lua + mods/common/lua/utils.lua + mods/common/lua/openra.lua + mods/common/lua/map.lua + mods/common/lua/actor.lua + mods/common/lua/team.lua + mods/common/lua/media.lua + mods/common/lua/mission.lua + mods/common/lua/reinforcements.lua + mods/common/lua/supportpowers.lua diff --git a/mods/ra/mod.yaml b/mods/ra/mod.yaml index 245e507a6c..ee635b4a62 100644 --- a/mods/ra/mod.yaml +++ b/mods/ra/mod.yaml @@ -165,12 +165,12 @@ Fonts: 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 - mods/ra/lua/reinforcements.lua - mods/ra/lua/supportpowers.lua + mods/common/lua/utils.lua + mods/common/lua/openra.lua + mods/common/lua/map.lua + mods/common/lua/actor.lua + mods/common/lua/team.lua + mods/common/lua/media.lua + mods/common/lua/mission.lua + mods/common/lua/reinforcements.lua + mods/common/lua/supportpowers.lua diff --git a/mods/ts/mod.yaml b/mods/ts/mod.yaml index ad335e599b..3c8cf26861 100644 --- a/mods/ts/mod.yaml +++ b/mods/ts/mod.yaml @@ -186,12 +186,12 @@ Fonts: 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 - mods/ra/lua/reinforcements.lua - mods/ra/lua/supportpowers.lua + mods/common/lua/utils.lua + mods/common/lua/openra.lua + mods/common/lua/map.lua + mods/common/lua/actor.lua + mods/common/lua/team.lua + mods/common/lua/media.lua + mods/common/lua/mission.lua + mods/common/lua/reinforcements.lua + mods/common/lua/supportpowers.lua From 061eb412caf75d2fcf12607bd40a265ea92a34f1 Mon Sep 17 00:00:00 2001 From: ScottNZ Date: Wed, 18 Dec 2013 16:10:17 +1300 Subject: [PATCH 5/9] Rename SupportPowers.Parabomb to SupportPowers.Airstrike --- mods/common/lua/supportpowers.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/common/lua/supportpowers.lua b/mods/common/lua/supportpowers.lua index 0dff9c6824..a7c96582db 100644 --- a/mods/common/lua/supportpowers.lua +++ b/mods/common/lua/supportpowers.lua @@ -1,6 +1,6 @@ SupportPowers = { } -SupportPowers.Parabomb = function(owner, planeName, enterLocation, bombLocation) +SupportPowers.Airstrike = 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 }) From 3cf06119f7319b92d732db7fb34e7e9e0eb889c7 Mon Sep 17 00:00:00 2001 From: ScottNZ Date: Wed, 18 Dec 2013 16:19:03 +1300 Subject: [PATCH 6/9] Update packaging scripts for mods/common --- Makefile | 1 + packaging/package-all.sh | 2 +- packaging/windows/OpenRA.nsi | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 514b1b8cbb..82f83944c0 100644 --- a/Makefile +++ b/Makefile @@ -314,6 +314,7 @@ install-core: default @$(INSTALL_DIR) "$(DATA_INSTALL_DIR)" @$(INSTALL_PROGRAM) $(foreach prog,$(CORE),$($(prog)_TARGET)) "$(DATA_INSTALL_DIR)" @$(INSTALL_DIR) "$(DATA_INSTALL_DIR)/mods" + @$(CP_R) mods/common "$(DATA_INSTALL_DIR)/mods/" @$(CP_R) mods/cnc "$(DATA_INSTALL_DIR)/mods/" @$(INSTALL_PROGRAM) $(mod_cnc_TARGET) "$(DATA_INSTALL_DIR)/mods/cnc" @$(CP_R) mods/ra "$(DATA_INSTALL_DIR)/mods/" diff --git a/packaging/package-all.sh b/packaging/package-all.sh index d64c6e6c98..8e27e3207b 100755 --- a/packaging/package-all.sh +++ b/packaging/package-all.sh @@ -29,7 +29,7 @@ markdown DOCUMENTATION.md > DOCUMENTATION.html FILES=('OpenRA.Game.exe' 'OpenRA.Editor.exe' 'OpenRA.Utility.exe' \ 'OpenRA.FileFormats.dll' 'OpenRA.Renderer.SdlCommon.dll' 'OpenRA.Renderer.Sdl2.dll' 'OpenRA.Renderer.Cg.dll' 'OpenRA.Renderer.Gl.dll' 'OpenRA.Renderer.Null.dll' 'OpenRA.Irc.dll' \ 'FreeSans.ttf' 'FreeSansBold.ttf' \ -'cg' 'glsl' 'mods/ra' 'mods/cnc' 'mods/d2k' \ +'cg' 'glsl' 'mods/common' 'mods/ra' 'mods/cnc' 'mods/d2k' \ 'AUTHORS' 'CHANGELOG' 'COPYING' \ 'README.html' 'CONTRIBUTING.html' 'DOCUMENTATION.html' \ 'global mix database.dat' 'GeoIP.dll' 'GeoIP.dat') diff --git a/packaging/windows/OpenRA.nsi b/packaging/windows/OpenRA.nsi index d9d90cc04c..8e82284283 100644 --- a/packaging/windows/OpenRA.nsi +++ b/packaging/windows/OpenRA.nsi @@ -58,6 +58,7 @@ SectionEnd Section "Game" GAME RMDir /r "$INSTDIR\mods" SetOutPath "$INSTDIR\mods" + File /r "${SRCDIR}\mods\common" File /r "${SRCDIR}\mods\cnc" File /r "${SRCDIR}\mods\d2k" File /r "${SRCDIR}\mods\ra" From 09b694095c7d96d8e81a6e6d580d55701f9eb3cc Mon Sep 17 00:00:00 2001 From: ScottNZ Date: Fri, 20 Dec 2013 19:05:24 +1300 Subject: [PATCH 7/9] Add Map.GetNamedActor for map actor lookup --- OpenRA.Mods.RA/Scripting/LuaScriptInterface.cs | 11 ++++++++++- mods/common/lua/map.lua | 4 ++++ mods/ra/maps/allies-01-classic/mission.lua | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/OpenRA.Mods.RA/Scripting/LuaScriptInterface.cs b/OpenRA.Mods.RA/Scripting/LuaScriptInterface.cs index f47ee46e0b..61979cc596 100644 --- a/OpenRA.Mods.RA/Scripting/LuaScriptInterface.cs +++ b/OpenRA.Mods.RA/Scripting/LuaScriptInterface.cs @@ -10,6 +10,7 @@ using System; using System.Collections; +using System.Collections.Generic; using System.Linq; using NLua; using OpenRA.Effects; @@ -34,6 +35,7 @@ namespace OpenRA.Mods.RA.Scripting public class LuaScriptInterface : IWorldLoaded, ITick { World world; + Dictionary mapActors; readonly LuaScriptContext context = new LuaScriptContext(); readonly LuaScriptInterfaceInfo info; @@ -45,6 +47,7 @@ namespace OpenRA.Mods.RA.Scripting public void WorldLoaded(World w, WorldRenderer wr) { world = w; + mapActors = world.WorldActor.Trait().Actors; context.Lua["World"] = w; context.Lua["WorldRenderer"] = wr; @@ -72,7 +75,7 @@ namespace OpenRA.Mods.RA.Scripting void AddMapActorGlobals() { - foreach (var kv in world.WorldActor.Trait().Actors) + foreach (var kv in mapActors) { if (context.Lua[kv.Key] != null) context.ShowErrorMessage("{0}: The global name '{1}' is reserved and may not be used by map actor {2}".F(GetType().Name, kv.Key, kv.Value), null); @@ -315,5 +318,11 @@ namespace OpenRA.Mods.RA.Scripting { return world.ChooseRandomEdgeCell(); } + + [LuaGlobal] + public Actor GetNamedActor(string actorName) + { + return mapActors[actorName]; + } } } diff --git a/mods/common/lua/map.lua b/mods/common/lua/map.lua index ae53c5fcd2..1b587cf780 100644 --- a/mods/common/lua/map.lua +++ b/mods/common/lua/map.lua @@ -12,6 +12,10 @@ Map.GetRandomEdgeCell = function() return Internal.GetRandomEdgeCell() end +Map.GetNamedActor = function(actorName) + return Internal.GetNamedActor(actorName) +end + CPos.New = function(x, y) return OpenRA.New("CPos", { { x, "Int32" }, { y, "Int32" } }) end diff --git a/mods/ra/maps/allies-01-classic/mission.lua b/mods/ra/maps/allies-01-classic/mission.lua index 86e0198865..2b4aeff727 100644 --- a/mods/ra/maps/allies-01-classic/mission.lua +++ b/mods/ra/maps/allies-01-classic/mission.lua @@ -72,7 +72,7 @@ end SendCruisers = function() for i, cruiser in ipairs(Cruisers) do local ca = Actor.Create(cruiser, { Owner = england, Location = SouthReinforcementsPoint.Location }) - Actor.Move(ca, _G["CruiserPoint" .. i].Location) + Actor.Move(ca, Map.GetNamedActor("CruiserPoint" .. i).Location) end end From 883b014888f0977c58df6ffd6bbb8d880aebdbe7 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 20 Dec 2013 18:57:29 +1300 Subject: [PATCH 8/9] Generalize reinforcement insertion / extraction. --- mods/common/lua/actor.lua | 22 ++++++- mods/common/lua/reinforcements.lua | 77 ++++++++-------------- mods/ra/maps/allies-01-classic/mission.lua | 8 +-- 3 files changed, 54 insertions(+), 53 deletions(-) diff --git a/mods/common/lua/actor.lua b/mods/common/lua/actor.lua index 328b62bafc..f2a6b92612 100644 --- a/mods/common/lua/actor.lua +++ b/mods/common/lua/actor.lua @@ -28,7 +28,19 @@ Actor.MoveNear = function(actor, location, nearEnough) end Actor.ScriptedMove = function(actor, location) - actor:QueueActivity(OpenRA.New("Move", { location })) + if Actor.HasTrait(actor, "Helicopter") then + actor:QueueActivity(OpenRA.New("HeliFly", { location.CenterPosition })) + else + actor:QueueActivity(OpenRA.New("Move", { location })) + end +end + +Actor.AfterMove = function(actor) + local heli = Actor.TraitOrDefault(actor, "Helicopter") + if heli ~= nil then + Actor.Turn(actor, heli.Info.InitialFacing) + Actor.HeliLand(actor, true) + end end Actor.Teleport = function(actor, location) @@ -173,4 +185,12 @@ end Actor.TraitInfo = function(actorType, className) return Internal.TraitInfo(actorType, className) +end + +Actor.InitialAltitude = function(actorName) + if Actor.HasTraitInfo("AircraftInfo") then + return Actor.TraitInfo(actorName, "AircraftInfo").CruiseAltitude + end + + return 0 end \ No newline at end of file diff --git a/mods/common/lua/reinforcements.lua b/mods/common/lua/reinforcements.lua index b5f42f0b94..0f20402fb8 100644 --- a/mods/common/lua/reinforcements.lua +++ b/mods/common/lua/reinforcements.lua @@ -1,62 +1,43 @@ Reinforcements = { } -Reinforcements.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") +Reinforcements.Insert = function(owner, transportName, passengerNames, enterPath, exitPath) + local facing = { Map.GetFacing(CPos.op_Subtraction(enterPath[2], enterPath[1]), 0), "Int32" } + local altitude = Actor.InitialAltitude(transportName) + local transport = Actor.Create(transportName, { Owner = owner, Location = enterPath[1], Facing = facing, Altitude = { altitude, "Int32" } }) + local cargo = Actor.Trait(transport, "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 + cargo:Load(transport, 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 + + Utils.Do(Utils.Skip(enterPath, 1), function(l) Actor.ScriptedMove(transport, l) end) + Actor.AfterMove(transport) + Actor.UnloadCargo(transport, true) + Actor.Wait(transport, 25) + Utils.Do(exitPath, function(l) Actor.ScriptedMove(transport, l) end) + Actor.RemoveSelf(transport) + return transport, passengers end -Reinforcements.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() - return Utils.All(passengers, function(passenger) return cargo.Passengers:Contains(passenger) end) +Reinforcements.Extract = function(owner, transportName, passengerNames, enterPath, exitPath) + local facing = { Map.GetFacing(CPos.op_Subtraction(enterPath[2], enterPath[1]), 0), "Int32" } + local altitude = Actor.InitialAltitude(transportName) + local transport = Actor.Create(transportName, { Owner = owner, Location = enterPath[1], Facing = facing, Altitude = { altitude, "Int32" } }) + local cargo = Actor.Trait(transport, "Cargo") + + Utils.Do(Utils.Skip(enterPath, 1), function(l) Actor.ScriptedMove(transport, l) end) + Actor.AfterMove(transport) + Actor.WaitFor(transport, function() + return Utils.All(passengerNames, function(passenger) return cargo.Passengers:Contains(passenger) end) end) - Actor.Wait(heli, 125) - Actor.HeliFly(heli, exitPosition) - Actor.RemoveSelf(heli) - return heli -end -Reinforcements.PerformInsertion = function(owner, vehicleName, passengerNames, enterPath, exitPath) - local facing = { 0, "Int32" } - if #enterPath > 1 then - facing = { Map.GetFacing(CPos.op_Subtraction(enterPath[2], enterPath[1]), 0), "Int32" } - end - local vehicle = Actor.Create(vehicleName, { Owner = owner, Location = enterPath[1], Facing = facing }) - local cargo = Actor.Trait(vehicle, "Cargo") - local passengers = { } - for i, passengerName in ipairs(passengerNames) do - local passenger = Actor.Create(passengerName, { AddToWorld = false, Owner = owner }) - passengers[i] = passenger - cargo:Load(vehicle, passenger) - end - Utils.Do(Utils.Skip(enterPath, 1), function(l) Actor.ScriptedMove(vehicle, l) end) - Actor.UnloadCargo(vehicle, true) - Actor.Wait(vehicle, 25) - Utils.Do(exitPath, function(l) Actor.ScriptedMove(vehicle, l) end) - Actor.RemoveSelf(vehicle) - return vehicle, passengers + Actor.Wait(transport, 125) + Utils.Do(exitPath, function(l) Actor.ScriptedMove(transport, l) end) + Actor.RemoveSelf(transport) + return transport end Reinforcements.Reinforce = function(owner, reinforcementNames, enterLocation, rallyPointLocation, interval, onCreateFunc) diff --git a/mods/ra/maps/allies-01-classic/mission.lua b/mods/ra/maps/allies-01-classic/mission.lua index 2b4aeff727..df16280cdc 100644 --- a/mods/ra/maps/allies-01-classic/mission.lua +++ b/mods/ra/maps/allies-01-classic/mission.lua @@ -13,8 +13,8 @@ CivilianWait = 150 BaseAlertDelay = 300 SendInsertionHelicopter = function() - local heli, passengers = Reinforcements.PerformHelicopterInsertion(player, InsertionHelicopterType, { TanyaType }, - InsertionEntry.CenterPosition, InsertionLZ.CenterPosition, InsertionEntry.CenterPosition) + local heli, passengers = Reinforcements.Insert(player, InsertionHelicopterType, { TanyaType }, + { InsertionEntry.Location, InsertionLZ.Location }, { InsertionEntry.Location }) tanya = passengers[1] Actor.OnKilled(tanya, TanyaKilled) end @@ -59,8 +59,8 @@ LabGuardsKilled = function() end SendExtractionHelicopter = function() - local heli = Reinforcements.PerformHelicopterExtraction(player, ExtractionHelicopterType, { einstein }, - SouthReinforcementsPoint.CenterPosition, ExtractionLZ.CenterPosition, ExtractionExitPoint.CenterPosition) + local heli = Reinforcements.Extract(player, ExtractionHelicopterType, { einstein }, + { SouthReinforcementsPoint.Location, ExtractionLZ.Location }, { ExtractionExitPoint.Location }) Actor.OnKilled(heli, HelicopterDestroyed) Actor.OnRemovedFromWorld(heli, HelicopterExtractionCompleted) end From 7ca5d56c1ffcabe0cb31ade9d1bf3ad907c7b575 Mon Sep 17 00:00:00 2001 From: ScottNZ Date: Fri, 20 Dec 2013 22:53:37 +1300 Subject: [PATCH 9/9] Move the TraitInfo stuff into rules.lua --- mods/cnc/mod.yaml | 1 + mods/common/lua/actor.lua | 20 -------------------- mods/common/lua/reinforcements.lua | 8 ++++---- mods/common/lua/rules.lua | 21 +++++++++++++++++++++ mods/common/lua/supportpowers.lua | 4 ++-- mods/d2k/mod.yaml | 1 + mods/ra/mod.yaml | 1 + mods/ts/mod.yaml | 1 + 8 files changed, 31 insertions(+), 26 deletions(-) create mode 100644 mods/common/lua/rules.lua diff --git a/mods/cnc/mod.yaml b/mods/cnc/mod.yaml index 32fbde44b8..95a65bcc11 100644 --- a/mods/cnc/mod.yaml +++ b/mods/cnc/mod.yaml @@ -174,3 +174,4 @@ LuaScripts: mods/common/lua/mission.lua mods/common/lua/reinforcements.lua mods/common/lua/supportpowers.lua + mods/common/lua/rules.lua diff --git a/mods/common/lua/actor.lua b/mods/common/lua/actor.lua index f2a6b92612..7e7dfd383c 100644 --- a/mods/common/lua/actor.lua +++ b/mods/common/lua/actor.lua @@ -173,24 +173,4 @@ 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 - -Actor.InitialAltitude = function(actorName) - if Actor.HasTraitInfo("AircraftInfo") then - return Actor.TraitInfo(actorName, "AircraftInfo").CruiseAltitude - end - - return 0 end \ No newline at end of file diff --git a/mods/common/lua/reinforcements.lua b/mods/common/lua/reinforcements.lua index 0f20402fb8..8d88de85be 100644 --- a/mods/common/lua/reinforcements.lua +++ b/mods/common/lua/reinforcements.lua @@ -2,8 +2,8 @@ Reinforcements = { } Reinforcements.Insert = function(owner, transportName, passengerNames, enterPath, exitPath) local facing = { Map.GetFacing(CPos.op_Subtraction(enterPath[2], enterPath[1]), 0), "Int32" } - local altitude = Actor.InitialAltitude(transportName) - local transport = Actor.Create(transportName, { Owner = owner, Location = enterPath[1], Facing = facing, Altitude = { altitude, "Int32" } }) + local altitude = { Rules.InitialAltitude(transportName), "Int32" } + local transport = Actor.Create(transportName, { Owner = owner, Location = enterPath[1], Facing = facing, Altitude = altitude }) local cargo = Actor.Trait(transport, "Cargo") local passengers = { } @@ -24,8 +24,8 @@ end Reinforcements.Extract = function(owner, transportName, passengerNames, enterPath, exitPath) local facing = { Map.GetFacing(CPos.op_Subtraction(enterPath[2], enterPath[1]), 0), "Int32" } - local altitude = Actor.InitialAltitude(transportName) - local transport = Actor.Create(transportName, { Owner = owner, Location = enterPath[1], Facing = facing, Altitude = { altitude, "Int32" } }) + local altitude = { Rules.InitialAltitude(transportName), "Int32" } + local transport = Actor.Create(transportName, { Owner = owner, Location = enterPath[1], Facing = facing, Altitude = altitude }) local cargo = Actor.Trait(transport, "Cargo") Utils.Do(Utils.Skip(enterPath, 1), function(l) Actor.ScriptedMove(transport, l) end) diff --git a/mods/common/lua/rules.lua b/mods/common/lua/rules.lua new file mode 100644 index 0000000000..17d50b563c --- /dev/null +++ b/mods/common/lua/rules.lua @@ -0,0 +1,21 @@ +Rules = { } + +Rules.HasTraitInfo = function(actorType, className) + return Internal.HasTraitInfo(actorType, className) +end + +Rules.TraitInfoOrDefault = function(actorType, className) + return Internal.TraitInfoOrDefault(actorType, className) +end + +Rules.TraitInfo = function(actorType, className) + return Internal.TraitInfo(actorType, className) +end + +Rules.InitialAltitude = function(actorType) + local ai = Rules.TraitInfoOrDefault(actorType, "AircraftInfo") + if ai ~= nil then + return ai.CruiseAltitude + end + return 0 +end \ No newline at end of file diff --git a/mods/common/lua/supportpowers.lua b/mods/common/lua/supportpowers.lua index a7c96582db..c899ddfa3b 100644 --- a/mods/common/lua/supportpowers.lua +++ b/mods/common/lua/supportpowers.lua @@ -2,7 +2,7 @@ SupportPowers = { } SupportPowers.Airstrike = 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 altitude = { Rules.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) @@ -13,7 +13,7 @@ end SupportPowers.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 altitude = { Rules.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) diff --git a/mods/d2k/mod.yaml b/mods/d2k/mod.yaml index e670180373..8b333357f2 100644 --- a/mods/d2k/mod.yaml +++ b/mods/d2k/mod.yaml @@ -154,3 +154,4 @@ LuaScripts: mods/common/lua/mission.lua mods/common/lua/reinforcements.lua mods/common/lua/supportpowers.lua + mods/common/lua/rules.lua diff --git a/mods/ra/mod.yaml b/mods/ra/mod.yaml index ee635b4a62..0e3a50dc6f 100644 --- a/mods/ra/mod.yaml +++ b/mods/ra/mod.yaml @@ -174,3 +174,4 @@ LuaScripts: mods/common/lua/mission.lua mods/common/lua/reinforcements.lua mods/common/lua/supportpowers.lua + mods/common/lua/rules.lua diff --git a/mods/ts/mod.yaml b/mods/ts/mod.yaml index 3c8cf26861..a0c2a3b28c 100644 --- a/mods/ts/mod.yaml +++ b/mods/ts/mod.yaml @@ -195,3 +195,4 @@ LuaScripts: mods/common/lua/mission.lua mods/common/lua/reinforcements.lua mods/common/lua/supportpowers.lua + mods/common/lua/rules.lua