From 24732ae6351035f3d601755104fa1ea1c51e3c35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Sun, 31 Aug 2014 10:48:22 +0200 Subject: [PATCH] port allies-02 to new Lua API --- OpenRA.Mods.RA/OpenRA.Mods.RA.csproj | 1 + .../Scripting/Global/TriggerGlobal.cs | 21 +++ .../Properties/TransformProperties.cs | 34 ++++ OpenRA.Mods.RA/Scripting/ScriptTriggers.cs | 9 +- mods/ra/maps/allies-02-classic/allies02.lua | 150 ++++++++++++------ mods/ra/maps/allies-02-classic/map.yaml | 52 +++--- mods/ra/notifications.yaml | 10 ++ 7 files changed, 202 insertions(+), 75 deletions(-) create mode 100644 OpenRA.Mods.RA/Scripting/Properties/TransformProperties.cs diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 01f3e2520f..f77f30a290 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -539,6 +539,7 @@ + diff --git a/OpenRA.Mods.RA/Scripting/Global/TriggerGlobal.cs b/OpenRA.Mods.RA/Scripting/Global/TriggerGlobal.cs index c4bd716d91..d67f17035e 100644 --- a/OpenRA.Mods.RA/Scripting/Global/TriggerGlobal.cs +++ b/OpenRA.Mods.RA/Scripting/Global/TriggerGlobal.cs @@ -171,6 +171,27 @@ namespace OpenRA.Mods.RA.Scripting GetScriptTriggers(a).RegisterCallback(Trigger.OnRemovedFromWorld, func, context); } + [Desc("Call a function when all of the actors in a group have been removed from the world. " + + "The callback function will be called as func().")] + public void OnAllRemovedFromWorld(Actor[] actors, LuaFunction func) + { + var group = actors.ToList(); + + var copy = (LuaFunction)func.CopyReference(); + Action OnMemberRemoved = m => + { + group.Remove(m); + if (!group.Any()) + { + copy.Call().Dispose(); + copy.Dispose(); + } + }; + + foreach (var a in group) + GetScriptTriggers(a).OnRemovedInternal += OnMemberRemoved; + } + [Desc("Call a function when this actor is captured. The callback function " + "will be called as func(Actor self, Actor captor, Player oldOwner, Player newOwner).")] public void OnCapture(Actor a, LuaFunction func) diff --git a/OpenRA.Mods.RA/Scripting/Properties/TransformProperties.cs b/OpenRA.Mods.RA/Scripting/Properties/TransformProperties.cs new file mode 100644 index 0000000000..6f5f656bc4 --- /dev/null +++ b/OpenRA.Mods.RA/Scripting/Properties/TransformProperties.cs @@ -0,0 +1,34 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 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 OpenRA.Scripting; +using OpenRA.Traits; + +namespace OpenRA.Mods.RA.Scripting +{ + [ScriptPropertyGroup("Transform")] + public class TransformProperties : ScriptActorProperties, Requires + { + readonly Transforms transforms; + + public TransformProperties(ScriptContext context, Actor self) + : base(context, self) + { + transforms = self.Trait(); + } + + [ScriptActorPropertyActivity] + [Desc("Queue a new transformation.")] + public void Deploy() + { + transforms.DeployTransform(true); + } + } +} \ No newline at end of file diff --git a/OpenRA.Mods.RA/Scripting/ScriptTriggers.cs b/OpenRA.Mods.RA/Scripting/ScriptTriggers.cs index c507a09616..b7d226c742 100644 --- a/OpenRA.Mods.RA/Scripting/ScriptTriggers.cs +++ b/OpenRA.Mods.RA/Scripting/ScriptTriggers.cs @@ -26,7 +26,8 @@ namespace OpenRA.Mods.RA.Scripting public sealed class ScriptTriggers : INotifyIdle, INotifyDamage, INotifyKilled, INotifyProduction, INotifyObjectivesUpdated, INotifyCapture, INotifyAddedToWorld, INotifyRemovedFromWorld, IDisposable { - public event Action OnKilledInternal = _ => {}; + public event Action OnKilledInternal = _ => { }; + public event Action OnRemovedInternal = _ => { }; public Dictionary>> Triggers = new Dictionary>>(); @@ -58,7 +59,7 @@ namespace OpenRA.Mods.RA.Scripting public void Killed(Actor self, AttackInfo e) { - // Run lua callbacks + // Run Lua callbacks foreach (var f in Triggers[Trigger.OnKilled]) using (var a = self.ToLuaValue(f.Second)) using (var b = e.Attacker.ToLuaValue(f.Second)) @@ -133,9 +134,13 @@ namespace OpenRA.Mods.RA.Scripting public void RemovedFromWorld(Actor self) { + // Run Lua callbacks foreach (var f in Triggers[Trigger.OnRemovedFromWorld]) using (var a = self.ToLuaValue(f.Second)) f.First.Call(a).Dispose(); + + // Run any internally bound callbacks + OnRemovedInternal(self); } public void Clear(Trigger trigger) diff --git a/mods/ra/maps/allies-02-classic/allies02.lua b/mods/ra/maps/allies-02-classic/allies02.lua index 616478a37c..3c3899417b 100644 --- a/mods/ra/maps/allies-02-classic/allies02.lua +++ b/mods/ra/maps/allies-02-classic/allies02.lua @@ -1,76 +1,132 @@ -JeepReinforcements = { "e1", "e1", "e1", "jeep" } -JeepReinforcementsInterval = 15 -TruckNames = { "truk", "truk", "truk" } -TruckInterval = 25 -TruckDelay = 75 -FirstJeepReinforcementsDelay = 125 -SecondJeepReinforcementsDelay = 250 +ConstructionVehicleReinforcements = { "mcv" } +ConstructionVehiclePath = { ReinforcementsEntryPoint.Location, DeployPoint.Location } -SendMcvReinforcements = function() - Media.PlaySpeechNotification("ReinforcementsArrived") - local mcv = Actor.Create("mcv", { Owner = player, Location = ReinforcementsEntryPoint.Location }) - Actor.Move(mcv, McvDeployPoint.Location) - Actor.DeployTransform(mcv) +JeepReinforcements = { "e1", "e1", "e1", "jeep" } +JeepPath = { ReinforcementsEntryPoint.Location, ReinforcementsRallyPoint.Location } + +TruckReinforcements = { "truk", "truk", "truk" } +TruckPath = { TruckEntryPoint.Location, TruckRallyPoint.Location } + +SendConstructionVehicleReinforcements = function() + local mcv = Reinforcements.Reinforce(player, ConstructionVehicleReinforcements, ConstructionVehiclePath)[1] end SendJeepReinforcements = function() - Media.PlaySpeechNotification("ReinforcementsArrived") - Reinforcements.Reinforce(player, JeepReinforcements, ReinforcementsEntryPoint.Location, ReinforcementsRallyPoint.Location, JeepReinforcementsInterval) + Media.PlaySpeechNotification(player, "ReinforcementsArrived") + Reinforcements.Reinforce(player, JeepReinforcements, JeepPath, Utils.Seconds(1)) end RunInitialActivities = function() - Actor.Harvest(Harvester) + Harvester.FindResources() end MissionAccomplished = function() - Mission.MissionOver({ player }, nil, true) - Media.PlayMovieFullscreen("montpass.vqa") + Media.PlaySpeechNotification(player, "Win") + Trigger.AfterDelay(Utils.Seconds(1), function() + Media.PlayMovieFullscreen("montpass.vqa") + end) end MissionFailed = function() - Mission.MissionOver(nil, { player }, true) - Media.PlayMovieFullscreen("frozen.vqa") + Media.PlaySpeechNotification(player, "Lose") + Trigger.AfterDelay(Utils.Seconds(1), function() + Media.PlayMovieFullscreen("frozen.vqa") + end) end Tick = function() - Mission.TickTakeOre(ussr) + ussr.Resources = ussr.Resources - (0.01 * ussr.ResourceCapacity / 25) - if Mission.RequiredUnitsAreDestroyed(player) then - MissionFailed() - end - if not trucksSent and Mission.RequiredUnitsAreDestroyed(ussr) and Mission.RequiredUnitsAreDestroyed(badGuy) then + if ukraine.HasNoRequiredUnits() then SendTrucks() - trucksSent = true + player.MarkCompletedObjective(ConquestObjective) + end + + if player.HasNoRequiredUnits() then + player.MarkFailedObjective(ConquestObjective) end end +ConvoyOnSite = false SendTrucks = function() - Media.PlaySpeechNotification("ConvoyApproaching") - OpenRA.RunAfterDelay(TruckDelay, function() - local trucks = Reinforcements.Reinforce(france, TruckNames, TruckEntryPoint.Location, TruckRallyPoint.Location, TruckInterval, - function(truck) - Actor.Move(truck, TruckExitPoint.Location) - Actor.RemoveSelf(truck) + if not ConvoyOnSite then + ConvoyOnSite = true + ConvoyObjective = player.AddPrimaryObjective("Escort the convoy") + Media.PlaySpeechNotification(player, "ConvoyApproaching") + Trigger.AfterDelay(Utils.Seconds(3), function() + ConvoyUnharmed = true + local trucks = Reinforcements.Reinforce(france, TruckReinforcements, TruckPath, Utils.Seconds(1), + function(truck) + Trigger.OnIdle(truck, function() truck.Move(TruckExitPoint.Location) end) + end) + count = 0 + Trigger.OnEnteredFootprint( { TruckExitPoint.Location }, function(a, id) + if a.Owner == france then + count = count + 1 + a.Destroy() + if count == 3 then + player.MarkCompletedObjective(ConvoyObjective) + Trigger.RemoveFootprintTrigger(id) + end + end end) - local trucksTeam = Team.New(trucks) - Team.AddEventHandler(trucksTeam.OnAllRemovedFromWorld, MissionAccomplished) - Team.AddEventHandler(trucksTeam.OnAnyKilled, MissionFailed) + Trigger.OnAnyKilled(trucks, ConvoyCasualites) + end) + end +end + +ConvoyCasualites = function() + Media.PlaySpeechNotification(player, "ConvoyUnitLost") + if ConvoyUnharmed then + ConvoyUnharmed = false + Trigger.AfterDelay(Utils.Seconds(1), function() player.MarkFailedObjective(ConvoyObjective) end) + end +end + +ConvoyTimer = function(delay, notification) + Trigger.AfterDelay(delay, function() + if not ConvoyOnSite then + Media.PlaySpeechNotification(player, notification) + end end) end WorldLoaded = function() - player = OpenRA.GetPlayer("Greece") - france = OpenRA.GetPlayer("France") - ussr = OpenRA.GetPlayer("USSR") - badGuy = OpenRA.GetPlayer("BadGuy") - + player = Player.GetPlayer("Greece") + france = Player.GetPlayer("France") + ussr = Player.GetPlayer("USSR") + ukraine = Player.GetPlayer("Ukraine") + + ConquestObjective = player.AddPrimaryObjective("Secure the area.") + ussr.AddPrimaryObjective("Defend your base.") + ukraine.AddPrimaryObjective("Destroy the convoy.") + RunInitialActivities() - - SendMcvReinforcements() - OpenRA.RunAfterDelay(FirstJeepReinforcementsDelay, SendJeepReinforcements) - OpenRA.RunAfterDelay(SecondJeepReinforcementsDelay, SendJeepReinforcements) - - OpenRA.SetViewportCenterPosition(ReinforcementsEntryPoint.CenterPosition) - - Media.PlayMovieFullscreen("ally2.vqa", function() Media.PlayMovieFullscreen("mcv.vqa", Media.PlayRandomMusic) end) + + SendConstructionVehicleReinforcements() + Trigger.AfterDelay(Utils.Seconds(5), SendJeepReinforcements) + Trigger.AfterDelay(Utils.Seconds(10), SendJeepReinforcements) + + Trigger.AfterDelay(Utils.Minutes(10), SendTrucks) + + Trigger.OnPlayerLost(player, MissionFailed) + Trigger.OnPlayerWon(player, MissionAccomplished) + + Trigger.OnObjectiveCompleted(player, function(p, id) + Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective completed") + end) + Trigger.OnObjectiveFailed(player, function(p, id) + Media.DisplayMessage(p.GetObjectiveDescription(id), "Objective failed") + end) + + Camera.Position = ReinforcementsEntryPoint.CenterPosition + + Media.PlayMovieFullscreen("ally2.vqa", function() Media.PlayMovieFullscreen("mcv.vqa") end) + + ConvoyTimer(Utils.Seconds(3), "TenMinutesRemaining") + ConvoyTimer(Utils.Minutes(5), "WarningFiveMinutesRemaining") + ConvoyTimer(Utils.Minutes(6), "WarningFourMinutesRemaining") + ConvoyTimer(Utils.Minutes(7), "WarningThreeMinutesRemaining") + ConvoyTimer(Utils.Minutes(8), "WarningTwoMinutesRemaining") + ConvoyTimer(Utils.Minutes(9), "WarningOneMinuteRemaining") end \ No newline at end of file diff --git a/mods/ra/maps/allies-02-classic/map.yaml b/mods/ra/maps/allies-02-classic/map.yaml index b96f01489c..18b4d8771c 100644 --- a/mods/ra/maps/allies-02-classic/map.yaml +++ b/mods/ra/maps/allies-02-classic/map.yaml @@ -6,7 +6,7 @@ RequiresMod: ra Title: Allies 02: Five to one -Description: A critical supply convoy is due through this area in 25 minutes, but Soviet forces have blocked the road in several places.\n\nUnless you can clear them out, those supplies will never make it to the front.\n\nThe convoy will come from the northwest, and time is short so work quickly. +Description: A critical supply convoy is due through this area in 10 minutes, but Soviet forces have blocked the road in several places.\n\nUnless you can clear them out, those supplies will never make it to the front.\n\nThe convoy will come from the northwest, and time is short so work quickly. Author: Westwood Studios @@ -34,26 +34,26 @@ Players: Name: USSR Race: soviet ColorRamp: 3,255,127 - Allies: BadGuy - Enemies: Greece + Allies: Ukraine + Enemies: Greece, France PlayerReference@France: Name: France Race: allies + NonCombatant: True ColorRamp: 115,115,143 - Allies: Greece - Enemies: USSR,BadGuy + Allies: Greece, France + Enemies: USSR, Ukraine PlayerReference@Neutral: Name: Neutral OwnsWorld: True NonCombatant: True Race: allies - Enemies: Greece - PlayerReference@BadGuy: - Name: BadGuy + PlayerReference@Ukraine: + Name: Ukraine Race: soviet ColorRamp: 3,255,127 Allies: USSR - Enemies: Greece + Enemies: Greece, France PlayerReference@Greece: Name: Greece Playable: True @@ -66,7 +66,7 @@ Players: LockSpawn: True LockTeam: True Allies: France - Enemies: USSR,BadGuy + Enemies: USSR, Ukraine Actors: EntryPoint: t06 @@ -240,7 +240,7 @@ Actors: Actor56: tc03 Location: 43,70 Owner: Neutral - Actor57: weap + SovietWarfactory: weap Location: 60,66 Owner: USSR Health: 1 @@ -480,7 +480,7 @@ Actors: SubCell: 0 Actor103: e1 Location: 77,74 - Owner: BadGuy + Owner: Ukraine Health: 1 Facing: 128 SubCell: 2 @@ -612,67 +612,67 @@ Actors: SubCell: 1 Actor125: dog Location: 78,75 - Owner: BadGuy + Owner: Ukraine Health: 1 Facing: 160 SubCell: 1 Actor126: e1 Location: 71,61 - Owner: BadGuy + Owner: Ukraine Health: 1 Facing: 160 SubCell: 0 Actor127: dog Location: 70,61 - Owner: BadGuy + Owner: Ukraine Health: 1 Facing: 96 SubCell: 4 Actor128: e1 Location: 50,46 - Owner: BadGuy + Owner: Ukraine Health: 1 Facing: 32 SubCell: 1 Actor129: e1 Location: 49,47 - Owner: BadGuy + Owner: Ukraine Health: 1 Facing: 64 SubCell: 0 Actor130: e2 Location: 49,49 - Owner: BadGuy + Owner: Ukraine Health: 1 Facing: 160 SubCell: 1 Actor131: e2 Location: 47,46 - Owner: BadGuy + Owner: Ukraine Health: 1 Facing: 96 SubCell: 3 Actor132: e2 Location: 48,63 - Owner: BadGuy + Owner: Ukraine Health: 1 Facing: 0 SubCell: 1 Actor133: e1 Location: 49,63 - Owner: BadGuy + Owner: Ukraine Health: 1 Facing: 96 SubCell: 2 Actor134: e1 Location: 74,81 - Owner: BadGuy + Owner: Ukraine Health: 1 Facing: 64 SubCell: 3 Actor135: e2 Location: 75,83 - Owner: BadGuy + Owner: Ukraine Health: 1 Facing: 96 SubCell: 0 @@ -751,7 +751,7 @@ Actors: waypoint94: waypoint Location: 90,46 Owner: Neutral - McvDeployPoint: waypoint + DeployPoint: waypoint Location: 89,51 Owner: Neutral waypoint96: waypoint @@ -875,8 +875,8 @@ Rules: -CrateSpawner: -SpawnMPUnits: -MPStartLocations: - LuaScriptInterface: - LuaScripts: allies02.lua + LuaScript: + Scripts: allies02.lua ObjectivesPanel: PanelName: MISSION_OBJECTIVES ^Vehicle: diff --git a/mods/ra/notifications.yaml b/mods/ra/notifications.yaml index 29d5620211..b88fa806ce 100644 --- a/mods/ra/notifications.yaml +++ b/mods/ra/notifications.yaml @@ -28,12 +28,22 @@ Speech: SignalFlareNorth: flaren1 AlliedReinforcementsArrived: aarrive1 ConvoyApproaching: convyap1 + ConvoyUnitLost: convlst1 TargetFreed: targfre1 TargetRescued: targres1 ObjectiveMet: objmet1 ObjectiveNotMet: objnmet1 ObjectiveReached: objrch1 ObjectiveNotReached: objnrch1 + TenMinutesRemaining: 10minr + TwentyMinutesRemaining: 20minr + ThirtyMinutesRemaining: 30minr + FourtyMinutesRemaining: 40minr + WarningOneMinuteRemaining: 1minr + WarningTwoMinutesRemaining: 2minr + WarningThreeMinutesRemaining: 3minr + WarningFourMinutesRemaining: 4minr + WarningFiveMinutesRemaining: 5minr Sounds: Notifications: