Made Resupply canceling more robust

The following improvements are made here:
- merged and streamlined the two IsCanceling checks in Tick
  into one that covers both isCloseEnough cases
- isCloseEnough now only checks distance to host
  if host is still valid and otherwise returns 'false'
- called transports are now also cancelled when host becomes
  invalid, not only if the activity is cancelled via order
- aircraft now always take off if the host becomes invalid
- ground actors only try to leave if host is still existing
This commit is contained in:
reaperrr
2019-07-28 15:24:00 +02:00
committed by teinarss
parent ddc4c4ff06
commit ac3b3db7ac

View File

@@ -76,23 +76,25 @@ namespace OpenRA.Mods.Common.Activities
public override bool Tick(Actor self)
{
// HACK: If the activity is cancelled while we're already resupplying (or about to start resupplying),
// move actor outside the resupplier footprint.
// TODO: This check is nowhere near robust enough, and should be rewritten.
var isCloseEnough = closeEnough < WDist.Zero || (host.CenterPosition - self.CenterPosition).HorizontalLengthSquared <= closeEnough.LengthSquared;
if (IsCanceling && isCloseEnough)
{
foreach (var notifyResupply in notifyResupplies)
notifyResupply.ResupplyTick(host.Actor, self, ResupplyType.None);
var isHostInvalid = host.Type != TargetType.Actor || !host.Actor.IsInWorld;
var isCloseEnough = closeEnough < WDist.Zero || (!isHostInvalid && (host.CenterPosition - self.CenterPosition).HorizontalLengthSquared <= closeEnough.LengthSquared);
OnResupplyEnding(self);
return true;
}
else if (IsCanceling || host.Type != TargetType.Actor || !host.Actor.IsInWorld || host.Actor.IsDead)
// This ensures transports are also cancelled when the host becomes invalid
if (!IsCanceling && isHostInvalid)
Cancel(self, true);
if (IsCanceling || isHostInvalid)
{
// This is necessary to ensure host resupply actions (like animations) finish properly
foreach (var notifyResupply in notifyResupplies)
notifyResupply.ResupplyTick(host.Actor, self, ResupplyType.None);
// Only tick host INotifyResupply traits one last time if host is still alive
if (!isHostInvalid)
foreach (var notifyResupply in notifyResupplies)
notifyResupply.ResupplyTick(host.Actor, self, ResupplyType.None);
// HACK: If the activity is cancelled while we're on the host resupplying (or about to start resupplying),
// move actor outside the resupplier footprint to prevent it from blocking other actors.
// Additionally, if the host is no longer valid, make aircaft take off.
if (isCloseEnough || isHostInvalid)
OnResupplyEnding(self, isHostInvalid);
return true;
}
@@ -158,16 +160,16 @@ namespace OpenRA.Mods.Common.Activities
yield return n;
}
void OnResupplyEnding(Actor self)
void OnResupplyEnding(Actor self, bool isHostInvalid = false)
{
if (aircraft != null)
{
aircraft.AllowYieldingReservation();
if (wasRepaired ||
if (wasRepaired || isHostInvalid ||
(!stayOnResupplier && aircraft.Info.TakeOffOnResupply))
QueueChild(new TakeOff(self));
}
else if (!stayOnResupplier)
else if (!stayOnResupplier && !isHostInvalid)
{
// If there's no next activity, move to rallypoint if available, else just leave host if Repairable.
// Do nothing if RepairableNear (RepairableNear actors don't enter their host and will likely remain within closeEnough).