Merge pull request #6377 from Mailaender/allies-01-new-lua

Ported Allies 01 to the New Lua API
This commit is contained in:
obrakmann
2014-09-28 12:09:03 +02:00
10 changed files with 300 additions and 102 deletions

View File

@@ -561,6 +561,9 @@
<Compile Include="Warheads\SpreadDamageWarhead.cs" /> <Compile Include="Warheads\SpreadDamageWarhead.cs" />
<Compile Include="Scripting\Global\ReinforcementsGlobal.cs" /> <Compile Include="Scripting\Global\ReinforcementsGlobal.cs" />
<Compile Include="Scripting\Global\DateGlobal.cs" /> <Compile Include="Scripting\Global\DateGlobal.cs" />
<Compile Include="Scripting\Properties\HarvesterProperties.cs" />
<Compile Include="Scripting\Properties\HelicopterProperties.cs" />
<Compile Include="Scripting\Properties\PlaneProperties.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\OpenRA.Game\OpenRA.Game.csproj"> <ProjectReference Include="..\OpenRA.Game\OpenRA.Game.csproj">

View File

@@ -102,6 +102,38 @@ namespace OpenRA.Mods.RA.Scripting
GetScriptTriggers(a).OnKilledInternal += OnMemberKilled; GetScriptTriggers(a).OnKilledInternal += OnMemberKilled;
} }
[Desc("Call a function when one of the actors in a group is killed. The callback " +
"function will be called as func(Actor killed).")]
public void OnAnyKilled(LuaTable actors, LuaFunction func)
{
var group = new List<Actor>();
foreach (var kv in actors)
{
Actor actor;
if (!kv.Value.TryGetClrValue<Actor>(out actor))
throw new LuaException("OnAnyKilled requires a table of int,Actor pairs. Recieved {0},{1}".F(kv.Key.GetType().Name, kv.Value.GetType().Name));
group.Add(actor);
}
var called = false;
var copy = (LuaFunction)func.CopyReference();
Action<Actor> OnMemberKilled = m =>
{
if (called)
return;
using (var killed = m.ToLuaValue(context))
copy.Call(killed).Dispose();
copy.Dispose();
called = true;
};
foreach (var a in group)
GetScriptTriggers(a).OnKilledInternal += OnMemberKilled;
}
[Desc("Call a function when this actor produces another actor. " + [Desc("Call a function when this actor produces another actor. " +
"The callback function will be called as func(Actor producer, Actor produced).")] "The callback function will be called as func(Actor producer, Actor produced).")]
public void OnProduction(Actor a, LuaFunction func) public void OnProduction(Actor a, LuaFunction func)

View File

@@ -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("Harvester")]
public class HarvesterProperties : ScriptActorProperties, Requires<HarvesterInfo>
{
readonly Harvester harvester;
public HarvesterProperties(ScriptContext context, Actor self)
: base(context, self)
{
harvester = self.Trait<Harvester>();
}
[ScriptActorPropertyActivity]
[Desc("Search for nearby resources and begin harvesting.")]
public void FindResources()
{
harvester.ContinueHarvesting(self);
}
}
}

View File

@@ -0,0 +1,30 @@
#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.Mods.RA.Air;
using OpenRA.Scripting;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Scripting
{
[ScriptPropertyGroup("Movement")]
public class HelicopterProperties : ScriptActorProperties, Requires<HelicopterInfo>
{
public HelicopterProperties(ScriptContext context, Actor self)
: base(context, self) { }
[ScriptActorPropertyActivity]
[Desc("Fly within the cell grid.")]
public void Move(CPos cell)
{
self.QueueActivity(new HeliFly(self, Target.FromCell(self.World, cell)));
}
}
}

View File

@@ -34,5 +34,12 @@ namespace OpenRA.Mods.RA.Scripting
{ {
self.QueueActivity(new Move.Move(cell)); self.QueueActivity(new Move.Move(cell));
} }
[ScriptActorPropertyActivity]
[Desc("Leave the current position in a random direction.")]
public void Scatter()
{
self.Trait<Mobile>().Nudge(self, self, true);
}
} }
} }

View File

@@ -0,0 +1,30 @@
#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.Mods.RA.Air;
using OpenRA.Scripting;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Scripting
{
[ScriptPropertyGroup("Movement")]
public class PlaneProperties : ScriptActorProperties, Requires<PlaneInfo>
{
public PlaneProperties(ScriptContext context, Actor self)
: base(context, self) { }
[ScriptActorPropertyActivity]
[Desc("Fly within the cell grid.")]
public void Move(CPos cell)
{
self.QueueActivity(new Fly(self, Target.FromCell(self.World, cell)));
}
}
}

View File

@@ -67,6 +67,6 @@ namespace OpenRA.Mods.RA.Widgets.Logic
parent.AddChild(widget); parent.AddChild(widget);
} }
} }
} }
} }

View File

@@ -1,151 +1,202 @@
InsertionHelicopterType = "tran.insertion" InsertionHelicopterType = "tran.insertion"
InsertionPath = { InsertionEntry.Location, InsertionLZ.Location }
ExtractionHelicopterType = "tran.extraction" ExtractionHelicopterType = "tran.extraction"
ExtractionPath = { SouthReinforcementsPoint.Location, ExtractionLZ.Location }
JeepReinforcements = { "jeep", "jeep" } JeepReinforcements = { "jeep", "jeep" }
JeepInterval = 50 TanyaReinforcements = { "e7" }
JeepDelay = 125
TanyaType = "e7"
EinsteinType = "einstein" EinsteinType = "einstein"
FlareType = "flare" FlareType = "flare"
Cruisers = { "ca", "ca", "ca", "ca" } CruisersReinforcements = { "ca", "ca", "ca", "ca" }
CruiserDelay = 250
CameraDelay = 125
CivilianWait = 150
BaseAlertDelay = 300
SendInsertionHelicopter = function() SendInsertionHelicopter = function()
local heli, passengers = Reinforcements.Insert(player, InsertionHelicopterType, { TanyaType }, local passengers = Reinforcements.ReinforceWithTransport(player, InsertionHelicopterType,
{ InsertionEntry.Location, InsertionLZ.Location }, { InsertionEntry.Location }) TanyaReinforcements, InsertionPath, { InsertionEntry.Location })[2]
tanya = passengers[1] local tanya = passengers[1]
Actor.OnKilled(tanya, TanyaKilled) Trigger.OnKilled(tanya, RescueFailed)
tanya.Stance = "HoldFire"
end end
SendJeeps = function() SendJeeps = function()
Media.PlaySpeechNotification("ReinforcementsArrived") Reinforcements.Reinforce(player, JeepReinforcements, InsertionPath, Utils.Seconds(2))
Reinforcements.Reinforce(player, JeepReinforcements, InsertionEntry.Location, InsertionLZ.Location, JeepInterval) Media.PlaySpeechNotification(player, "ReinforcementsArrived")
end end
RunInitialActivities = function() RunInitialActivities = function()
SendInsertionHelicopter() SendInsertionHelicopter()
Actor.Hunt(Patrol1) Patrol1.Hunt()
Actor.Hunt(Patrol2) Patrol2.Hunt()
Actor.Hunt(Patrol3) Patrol3.Hunt()
Actor.Hunt(Patrol4) Patrol4.Hunt()
Actor.Harvest(Harvester) Harvester.FindResources()
Team.Do(civiliansTeam, function(c) Civilian1.Wait(Utils.Seconds(6))
Actor.Wait(c, CivilianWait) Civilian2.Wait(Utils.Seconds(6))
Actor.Hunt(c) Civilian1.Hunt()
end) Civilian2.Hunt()
end end
LabGuardsKilled = function() LabGuardsKilled = function()
CreateEinstein() CreateEinstein()
Actor.Create(FlareType, { Owner = england, Location = ExtractionFlarePoint.Location }) Trigger.AfterDelay(Utils.Seconds(2), function()
Media.PlaySpeechNotification("SignalFlareNorth") Actor.Create(FlareType, true, { Owner = england, Location = ExtractionFlarePoint.Location })
SendExtractionHelicopter() Media.PlaySpeechNotification(player, "SignalFlareNorth")
SendExtractionHelicopter()
OpenRA.RunAfterDelay(BaseAlertDelay, function()
local ussrUnits = Mission.GetGroundAttackersOf(ussr)
for i, unit in ipairs(ussrUnits) do
Actor.Hunt(unit)
end
end) end)
OpenRA.RunAfterDelay(CruiserDelay, function() Trigger.AfterDelay(Utils.Seconds(10), function()
Media.PlaySpeechNotification("AlliedReinforcementsArrived") Media.PlaySpeechNotification(player, "AlliedReinforcementsArrived")
Actor.Create("camera", { Owner = player, Location = CruiserCameraPoint.Location }) Actor.Create("camera", true, { Owner = player, Location = CruiserCameraPoint.Location })
SendCruisers() SendCruisers()
end) end)
Trigger.AfterDelay(Utils.Seconds(12), function()
for i = 0, 2 do
Trigger.AfterDelay(Utils.Seconds(i), function()
Media.PlaySoundNotification(player, "AlertBuzzer")
end)
end
Utils.Do(sovietArmy, function(a)
if not a.IsDead and a.HasProperty("Hunt") then
Trigger.OnIdle(a, a.Hunt)
end
end)
end)
end end
SendExtractionHelicopter = function() SendExtractionHelicopter = function()
local heli = Reinforcements.Extract(player, ExtractionHelicopterType, { einstein }, heli = Reinforcements.ReinforceWithTransport(player, ExtractionHelicopterType, nil, ExtractionPath)[1]
{ SouthReinforcementsPoint.Location, ExtractionLZ.Location }, { ExtractionExitPoint.Location }) if not einstein.IsDead then
Actor.OnKilled(heli, HelicopterDestroyed) Trigger.OnRemovedFromWorld(einstein, EvacuateHelicopter)
Actor.OnRemovedFromWorld(heli, HelicopterExtractionCompleted) end
Trigger.OnKilled(heli, RescueFailed)
Trigger.OnRemovedFromWorld(heli, HelicopterGone)
end end
HelicopterExtractionCompleted = function() EvacuateHelicopter = function()
MissionAccomplished() if heli.HasPassengers then
heli.Move(ExtractionExitPoint.Location)
Trigger.OnIdle(heli, heli.Destroy)
end
end end
SendCruisers = function() SendCruisers = function()
for i, cruiser in ipairs(Cruisers) do local i = 1
local ca = Actor.Create(cruiser, { Owner = england, Location = SouthReinforcementsPoint.Location }) Utils.Do(CruisersReinforcements, function(cruiser)
Actor.Move(ca, Map.GetNamedActor("CruiserPoint" .. i).Location) local ca = Actor.Create(cruiser, true, { Owner = england, Location = SouthReinforcementsPoint.Location + CVec.New(2 * i, 0) })
end ca.Move(Map.NamedActor("CruiserPoint" .. i).Location)
i = i + 1
end)
end end
LabDestroyed = function(self, e) LabDestroyed = function()
if not einstein then if not einstein then
MissionFailed() RescueFailed()
end end
end end
EinsteinKilled = function(self, e) RescueFailed = function()
MissionFailed() player.MarkFailedObjective(SurviveObjective)
ussr.MarkCompletedObjective(DefendObjective)
end end
HelicopterDestroyed = function(self, e) OilPumpDestroyed = function()
MissionFailed() Trigger.AfterDelay(Utils.Seconds(5), SendJeeps)
end end
TanyaKilled = function(self, e) CiviliansKilled = function()
MissionFailed() player.MarkFailedObjective(CivilProtectionObjective)
end Media.PlaySpeechNotification(player, "ObjectiveNotMet")
collateralDamage = true
OilPumpDestroyed = function(self, e)
OpenRA.RunAfterDelay(JeepDelay, SendJeeps)
end end
CreateEinstein = function() CreateEinstein = function()
einstein = Actor.Create(EinsteinType, { Location = EinsteinSpawnPoint.Location, Owner = player }) player.MarkCompletedObjective(FindEinsteinObjective)
Actor.Scatter(einstein) Media.PlaySpeechNotification(player, "ObjectiveMet")
Actor.OnKilled(einstein, EinsteinKilled) einstein = Actor.Create(EinsteinType, true, { Location = EinsteinSpawnPoint.Location, Owner = player })
einstein.Scatter()
Trigger.OnKilled(einstein, RescueFailed)
ExtractObjective = player.AddPrimaryObjective("Wait for the helicopter and extract Einstein.")
Trigger.AfterDelay(Utils.Seconds(1), function() Media.PlaySpeechNotification(player, "TargetFreed") end)
end end
MissionAccomplished = function() HelicopterGone = function()
Mission.MissionOver({ player }, nil, true) if not heli.IsDead then
--Media.PlayMovieFullscreen("snowbomb.vqa") Media.PlaySpeechNotification(player, "TargetRescued")
end Trigger.AfterDelay(Utils.Seconds(1), function()
player.MarkCompletedObjective(ExtractObjective)
MissionFailed = function() player.MarkCompletedObjective(SurviveObjective)
Mission.MissionOver(nil, { player }, true) ussr.MarkFailedObjective(DefendObjective)
Media.PlayMovieFullscreen("bmap.vqa") if not collateralDamage then
end player.MarkCompletedObjective(CivilProtectionObjective)
end
SetUnitStances = function() end)
local playerUnits = Mission.GetGroundAttackersOf(player)
local ussrUnits = Mission.GetGroundAttackersOf(ussr)
for i, unit in ipairs(playerUnits) do
Actor.SetStance(unit, "Defend")
end end
end end
MissionAccomplished = function()
Media.PlaySpeechNotification(player, "Win")
--Trigger.AfterDelay(Utils.Seconds(1), function()
--Media.PlayMovieFullscreen("snowbomb.vqa") -- https://github.com/OpenRA/OpenRA/issues/4224
--end)
end
MissionFailed = function()
Media.PlaySpeechNotification(player, "Lose")
Trigger.AfterDelay(Utils.Seconds(1), function() Media.PlayMovieFullscreen("bmap.vqa") end)
end
SetUnitStances = function()
Utils.Do(Map.NamedActors, function(a)
if a.Owner == player then
a.Stance = "Defend"
end
end)
end
Tick = function() Tick = function()
Mission.TickTakeOre(ussr) ussr.Resources = ussr.Resources - (0.01 * ussr.ResourceCapacity / 25)
end end
WorldLoaded = function() WorldLoaded = function()
player = OpenRA.GetPlayer("Greece") player = Player.GetPlayer("Greece")
england = OpenRA.GetPlayer("England") england = Player.GetPlayer("England")
ussr = OpenRA.GetPlayer("USSR") ussr = Player.GetPlayer("USSR")
Actor.OnKilled(Lab, LabDestroyed) FindEinsteinObjective = player.AddPrimaryObjective("Find Einstein.")
Actor.OnKilled(OilPump, OilPumpDestroyed) SurviveObjective = player.AddPrimaryObjective("Tanya and Einstein must survive.")
england.AddPrimaryObjective("Destroy the soviet base after a successful rescue.")
labGuardsTeam = Team.New({ LabGuard1, LabGuard2, LabGuard3 }) CivilProtectionObjective = player.AddSecondaryObjective("Protect all civilians.")
Team.AddEventHandler(labGuardsTeam.OnAllKilled, LabGuardsKilled) DefendObjective = ussr.AddPrimaryObjective("Kill Tanya and keep Einstein hostage.")
civiliansTeam = Team.New({ Civilian1, Civilian2 }) 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)
Trigger.OnPlayerLost(player, MissionFailed)
Trigger.OnPlayerWon(player, MissionAccomplished)
Trigger.OnKilled(Lab, LabDestroyed)
Trigger.OnKilled(OilPump, OilPumpDestroyed)
sovietArmy = ussr.GetGroundAttackers()
labGuardsTeam = { LabGuard1, LabGuard2, LabGuard3 }
Trigger.OnAllKilled(labGuardsTeam, LabGuardsKilled)
collateralDamage = false
civilianTeam = { Civilian1, Civilian2 }
Trigger.OnAnyKilled(civilianTeam, CiviliansKilled)
RunInitialActivities() RunInitialActivities()
SetUnitStances() SetUnitStances()
OpenRA.RunAfterDelay(CameraDelay, function() Actor.Create("camera", { Owner = player, Location = BaseCameraPoint.Location }) end) Trigger.AfterDelay(Utils.Seconds(5), function() Actor.Create("camera", true, { Owner = player, Location = BaseCameraPoint.Location }) end)
OpenRA.SetViewportCenterPosition(InsertionLZ.CenterPosition) Camera.Position = InsertionLZ.CenterPosition
Media.PlayMovieFullscreen("ally1.vqa", function() Media.PlayMovieFullscreen("landing.vqa", Media.PlayRandomMusic) end) Media.PlayMovieFullscreen("ally1.vqa", function() Media.PlayMovieFullscreen("landing.vqa") end)
end end

View File

@@ -580,8 +580,8 @@ Rules:
-CrateSpawner: -CrateSpawner:
-SpawnMPUnits: -SpawnMPUnits:
-MPStartLocations: -MPStartLocations:
LuaScriptInterface: LuaScript:
LuaScripts: allies01.lua Scripts: allies01.lua
ObjectivesPanel: ObjectivesPanel:
PanelName: MISSION_OBJECTIVES PanelName: MISSION_OBJECTIVES
TRAN.Extraction: TRAN.Extraction:
@@ -607,6 +607,9 @@ Rules:
^CivInfantry: ^CivInfantry:
RevealsShroud: RevealsShroud:
Range: 0c0 Range: 0c0
JEEP:
Cargo:
Types: Infantry, Einstein
Sequences: Sequences:

View File

@@ -28,6 +28,12 @@ Speech:
SignalFlareNorth: flaren1 SignalFlareNorth: flaren1
AlliedReinforcementsArrived: aarrive1 AlliedReinforcementsArrived: aarrive1
ConvoyApproaching: convyap1 ConvoyApproaching: convyap1
TargetFreed: targfre1
TargetRescued: targres1
ObjectiveMet: objmet1
ObjectiveNotMet: objnmet1
ObjectiveReached: objrch1
ObjectiveNotReached: objnrch1
Sounds: Sounds:
Notifications: Notifications:
@@ -41,4 +47,6 @@ Sounds:
ChatLine: scold1 ChatLine: scold1
ClickSound: ramenu1 ClickSound: ramenu1
ClickDisabledSound: ClickDisabledSound:
Beacon: beepslct Beacon: beepslct
AlertBuzzer: buzzy1
AlertBleep: bleep6