From f48ba0ff8656a9f38d63f49fa29f156474072c35 Mon Sep 17 00:00:00 2001 From: abcdefg30 Date: Mon, 7 Aug 2017 13:53:49 +0200 Subject: [PATCH] Find alternative landing spots for blocked reinforcements --- .../Scripting/Global/ReinforcementsGlobal.cs | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs b/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs index 678f6d56ca..1c29681d7c 100644 --- a/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs +++ b/OpenRA.Mods.Common/Scripting/Global/ReinforcementsGlobal.cs @@ -109,10 +109,12 @@ namespace OpenRA.Mods.Common.Scripting "been supplied. Afterwards, the transport will follow the exitPath and leave the map, " + "unless a custom exitFunc has been supplied. actionFunc will be called as " + "actionFunc(Actor transport, Actor[] cargo). exitFunc will be called as exitFunc(Actor transport). " + + "dropRange determines how many cells away the transport will try to land " + + "if the actual destination is blocked (if the transport is an aircraft). " + "Returns a table in which the first value is the transport, " + "and the second a table containing the deployed units.")] public LuaTable ReinforceWithTransport(Player owner, string actorType, string[] cargoTypes, CPos[] entryPath, CPos[] exitPath = null, - LuaFunction actionFunc = null, LuaFunction exitFunc = null) + LuaFunction actionFunc = null, LuaFunction exitFunc = null, int dropRange = 3) { var transport = CreateActor(owner, actorType, true, entryPath[0], entryPath.Length > 1 ? entryPath[1] : (CPos?)null); var cargo = transport.TraitOrDefault(); @@ -143,17 +145,35 @@ namespace OpenRA.Mods.Common.Scripting } else { - var aircraftInfo = transport.Info.TraitInfoOrDefault(); - if (aircraftInfo != null) + var aircraft = transport.TraitOrDefault(); + if (aircraft != null) { - if (aircraftInfo.VTOL) + var destination = entryPath.Last(); + + // Try to find an alternative landing spot if we can't land at the current destination + if (!aircraft.CanLand(destination) && dropRange > 0) { - transport.QueueActivity(new Turn(transport, aircraftInfo.InitialFacing)); + foreach (var c in transport.World.Map.FindTilesInCircle(destination, dropRange)) + { + if (!aircraft.CanLand(c)) + continue; + + destination = c; + break; + } + } + + if (aircraft.Info.VTOL) + { + if (destination != entryPath.Last()) + Move(transport, destination); + + transport.QueueActivity(new Turn(transport, aircraft.Info.InitialFacing)); transport.QueueActivity(new HeliLand(transport, true)); } else { - transport.QueueActivity(new Land(transport, Target.FromCell(transport.World, entryPath.Last()))); + transport.QueueActivity(new Land(transport, Target.FromCell(transport.World, destination))); } transport.QueueActivity(new Wait(15)); @@ -165,7 +185,7 @@ namespace OpenRA.Mods.Common.Scripting transport.QueueActivity(new WaitFor(() => cargo.IsEmpty(transport))); } - transport.QueueActivity(new Wait(aircraftInfo != null ? 50 : 25)); + transport.QueueActivity(new Wait(aircraft != null ? 50 : 25)); } if (exitFunc != null)