Make Tick return bool

This commit is contained in:
tovl
2019-05-14 21:13:25 +02:00
committed by teinarss
parent 09c1611239
commit 3790169db9
49 changed files with 328 additions and 318 deletions

View File

@@ -21,8 +21,7 @@ namespace OpenRA.Activities
/* /*
* Things to be aware of when writing activities: * Things to be aware of when writing activities:
* *
* - Use "return NextActivity" at least once somewhere in the tick method. * - Use "return true" at least once somewhere in the tick method.
* - Do not use "return new SomeActivity()" as that will break the queue. Queue the new activity and use "return NextActivity" instead.
* - Do not "reuse" (with "SequenceActivities", for example) activity objects that have already started running. * - Do not "reuse" (with "SequenceActivities", for example) activity objects that have already started running.
* Queue a new instance instead. * Queue a new instance instead.
* - Avoid calling actor.CancelActivity(). It is almost always a bug. Call activity.Cancel() instead. * - Avoid calling actor.CancelActivity(). It is almost always a bug. Call activity.Cancel() instead.
@@ -32,11 +31,13 @@ namespace OpenRA.Activities
public ActivityState State { get; private set; } public ActivityState State { get; private set; }
protected Activity ChildActivity { get; private set; } protected Activity ChildActivity { get; private set; }
public Activity NextActivity { get; protected set; } public Activity NextActivity { get; private set; }
public bool IsInterruptible { get; protected set; } public bool IsInterruptible { get; protected set; }
public bool ChildHasPriority { get; protected set; } public bool ChildHasPriority { get; protected set; }
public bool IsCanceling { get { return State == ActivityState.Canceling; } } public bool IsCanceling { get { return State == ActivityState.Canceling; } }
bool finishing;
bool lastRun;
public Activity() public Activity()
{ {
@@ -55,33 +56,60 @@ namespace OpenRA.Activities
State = ActivityState.Active; State = ActivityState.Active;
} }
// Only run the parent tick when the child is done.
// We must always let the child finish on its own before continuing.
if (ChildHasPriority) if (ChildHasPriority)
{ {
ChildActivity = ActivityUtils.RunActivity(self, ChildActivity); lastRun = TickChild(self) && (finishing || Tick(self));
if (ChildActivity != null) finishing |= lastRun;
return this;
} }
var ret = Tick(self); // The parent determines whether the child gets a chance at ticking.
else
lastRun = Tick(self);
// Avoid a single tick delay if the childactivity was just queued.
if (ChildActivity != null && ChildActivity.State == ActivityState.Queued) if (ChildActivity != null && ChildActivity.State == ActivityState.Queued)
ChildActivity = ActivityUtils.RunActivity(self, ChildActivity); {
if (ChildHasPriority)
lastRun = TickChild(self) && finishing;
else
TickChild(self);
}
if (ret != this) if (lastRun)
{ {
State = ActivityState.Done; State = ActivityState.Done;
OnLastRun(self); OnLastRun(self);
return NextActivity;
} }
return ret; return this;
}
protected bool TickChild(Actor self)
{
ChildActivity = ActivityUtils.RunActivity(self, ChildActivity);
return ChildActivity == null;
} }
/// <summary> /// <summary>
/// Runs every timestep as long as this activity is active. /// Called every tick to run activity logic. Returns false if the activity should
/// remain active, or true if it is complete. Cancelled activities must ensure they
/// return the actor to a consistent state before returning true.
///
/// Child activities can be queued using QueueChild, and these will be ticked
/// instead of the parent while they are active. Activities that need to run logic
/// in parallel with child activities should set ChildHasPriority to false and
/// manually call TickChildren.
///
/// Queuing one or more child activities and returning true is valid, and causes
/// the activity to be completed immediately (without ticking again) once the
/// children have completed.
/// </summary> /// </summary>
public virtual Activity Tick(Actor self) public virtual bool Tick(Actor self)
{ {
return NextActivity; return true;
} }
/// <summary> /// <summary>

View File

@@ -24,10 +24,10 @@ namespace OpenRA.Activities
Action a; Action a;
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (a != null) a(); if (a != null) a();
return NextActivity; return true;
} }
} }
} }

View File

@@ -37,10 +37,10 @@ namespace OpenRA.Mods.Cnc.Activities
this.minefield = minefield; this.minefield = minefield;
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (IsCanceling) if (IsCanceling)
return NextActivity; return true;
if (rearmableInfo != null && ammoPools.Any(p => p.Info.Name == info.AmmoPoolName && !p.HasAmmo())) if (rearmableInfo != null && ammoPools.Any(p => p.Info.Name == info.AmmoPoolName && !p.HasAmmo()))
{ {
@@ -50,20 +50,20 @@ namespace OpenRA.Mods.Cnc.Activities
.ClosestTo(self); .ClosestTo(self);
if (rearmTarget == null) if (rearmTarget == null)
return NextActivity; return true;
// Add a CloseEnough range of 512 to the Rearm/Repair activities in order to ensure that we're at the host actor // Add a CloseEnough range of 512 to the Rearm/Repair activities in order to ensure that we're at the host actor
QueueChild(new MoveAdjacentTo(self, Target.FromActor(rearmTarget))); QueueChild(new MoveAdjacentTo(self, Target.FromActor(rearmTarget)));
QueueChild(movement.MoveTo(self.World.Map.CellContaining(rearmTarget.CenterPosition), rearmTarget)); QueueChild(movement.MoveTo(self.World.Map.CellContaining(rearmTarget.CenterPosition), rearmTarget));
QueueChild(new Resupply(self, rearmTarget, new WDist(512))); QueueChild(new Resupply(self, rearmTarget, new WDist(512)));
return this; return false;
} }
if ((minefield == null || minefield.Contains(self.Location)) && ShouldLayMine(self, self.Location)) if ((minefield == null || minefield.Contains(self.Location)) && ShouldLayMine(self, self.Location))
{ {
LayMine(self); LayMine(self);
QueueChild(new Wait(20)); // A little wait after placing each mine, for show QueueChild(new Wait(20)); // A little wait after placing each mine, for show
return this; return false;
} }
if (minefield != null && minefield.Length > 0) if (minefield != null && minefield.Length > 0)
@@ -75,13 +75,13 @@ namespace OpenRA.Mods.Cnc.Activities
if (ShouldLayMine(self, p)) if (ShouldLayMine(self, p))
{ {
QueueChild(movement.MoveTo(p, 0)); QueueChild(movement.MoveTo(p, 0));
return this; return false;
} }
} }
} }
// TODO: Return somewhere likely to be safe (near rearm building) so we're not sitting out in the minefield. // TODO: Return somewhere likely to be safe (near rearm building) so we're not sitting out in the minefield.
return NextActivity; return true;
} }
static bool ShouldLayMine(Actor self, CPos p) static bool ShouldLayMine(Actor self, CPos p)

View File

@@ -70,11 +70,11 @@ namespace OpenRA.Mods.Cnc.Activities
attack.GrantLeapCondition(self); attack.GrantLeapCondition(self);
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
// Correct the visual position after we jumped // Correct the visual position after we jumped
if (canceled || jumpComplete) if (canceled || jumpComplete)
return NextActivity; return true;
if (target.Type != TargetType.Invalid) if (target.Type != TargetType.Invalid)
targetPosition = target.CenterPosition; targetPosition = target.CenterPosition;
@@ -100,7 +100,7 @@ namespace OpenRA.Mods.Cnc.Activities
QueueChild(mobile.VisualMove(self, position, self.World.Map.CenterOfSubCell(destinationCell, destinationSubCell))); QueueChild(mobile.VisualMove(self, position, self.World.Map.CenterOfSubCell(destinationCell, destinationSubCell)));
} }
return this; return false;
} }
protected override void OnLastRun(Actor self) protected override void OnLastRun(Actor self)

View File

@@ -72,10 +72,10 @@ namespace OpenRA.Mods.Cnc.Activities
attack.IsAiming = true; attack.IsAiming = true;
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (IsCanceling) if (IsCanceling)
return NextActivity; return true;
bool targetIsHiddenActor; bool targetIsHiddenActor;
target = target.Recalculate(self.Owner, out targetIsHiddenActor); target = target.Recalculate(self.Owner, out targetIsHiddenActor);
@@ -97,7 +97,7 @@ namespace OpenRA.Mods.Cnc.Activities
// Target is hidden or dead, and we don't have a fallback position to move towards // Target is hidden or dead, and we don't have a fallback position to move towards
if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self)) if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self))
return NextActivity; return true;
var pos = self.CenterPosition; var pos = self.CenterPosition;
var checkTarget = useLastVisibleTarget ? lastVisibleTarget : target; var checkTarget = useLastVisibleTarget ? lastVisibleTarget : target;
@@ -105,27 +105,27 @@ namespace OpenRA.Mods.Cnc.Activities
if (!checkTarget.IsInRange(pos, lastVisibleMaxRange) || checkTarget.IsInRange(pos, lastVisibleMinRange)) if (!checkTarget.IsInRange(pos, lastVisibleMaxRange) || checkTarget.IsInRange(pos, lastVisibleMinRange))
{ {
if (!allowMovement || lastVisibleMaxRange == WDist.Zero || lastVisibleMaxRange < lastVisibleMinRange) if (!allowMovement || lastVisibleMaxRange == WDist.Zero || lastVisibleMaxRange < lastVisibleMinRange)
return NextActivity; return true;
QueueChild(mobile.MoveWithinRange(target, lastVisibleMinRange, lastVisibleMaxRange, checkTarget.CenterPosition, Color.Red)); QueueChild(mobile.MoveWithinRange(target, lastVisibleMinRange, lastVisibleMaxRange, checkTarget.CenterPosition, Color.Red));
return this; return false;
} }
// Ready to leap, but target isn't visible // Ready to leap, but target isn't visible
if (targetIsHiddenActor || target.Type != TargetType.Actor) if (targetIsHiddenActor || target.Type != TargetType.Actor)
return NextActivity; return true;
// Target is not valid // Target is not valid
if (!target.IsValidFor(self) || !attack.HasAnyValidWeapons(target)) if (!target.IsValidFor(self) || !attack.HasAnyValidWeapons(target))
return NextActivity; return true;
var edible = target.Actor.TraitOrDefault<EdibleByLeap>(); var edible = target.Actor.TraitOrDefault<EdibleByLeap>();
if (edible == null || !edible.CanLeap(self)) if (edible == null || !edible.CanLeap(self))
return NextActivity; return true;
// Can't leap yet // Can't leap yet
if (attack.Armaments.All(a => a.IsReloading)) if (attack.Armaments.All(a => a.IsReloading))
return this; return false;
// Use CenterOfSubCell with ToSubCell instead of target.Centerposition // Use CenterOfSubCell with ToSubCell instead of target.Centerposition
// to avoid continuous facing adjustments as the target moves // to avoid continuous facing adjustments as the target moves
@@ -138,13 +138,13 @@ namespace OpenRA.Mods.Cnc.Activities
if (mobile.Facing != desiredFacing) if (mobile.Facing != desiredFacing)
{ {
QueueChild(new Turn(self, desiredFacing)); QueueChild(new Turn(self, desiredFacing));
return this; return false;
} }
QueueChild(new Leap(self, target, mobile, targetMobile, info.Speed.Length, attack, edible)); QueueChild(new Leap(self, target, mobile, targetMobile, info.Speed.Length, attack, edible));
// Re-queue the child activities to kill the target if it didn't die in one go // Re-queue the child activities to kill the target if it didn't die in one go
return this; return false;
} }
protected override void OnLastRun(Actor self) protected override void OnLastRun(Actor self)

View File

@@ -52,7 +52,7 @@ namespace OpenRA.Mods.Cnc.Activities
IsInterruptible = false; IsInterruptible = false;
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
var pc = self.TraitOrDefault<PortableChrono>(); var pc = self.TraitOrDefault<PortableChrono>();
if (teleporter == self && pc != null && (!pc.CanTeleport || IsCanceling)) if (teleporter == self && pc != null && (!pc.CanTeleport || IsCanceling))
@@ -60,7 +60,7 @@ namespace OpenRA.Mods.Cnc.Activities
if (killOnFailure) if (killOnFailure)
self.Kill(teleporter, killDamageTypes); self.Kill(teleporter, killDamageTypes);
return NextActivity; return true;
} }
var bestCell = ChooseBestDestinationCell(self, destination); var bestCell = ChooseBestDestinationCell(self, destination);
@@ -69,7 +69,7 @@ namespace OpenRA.Mods.Cnc.Activities
if (killOnFailure) if (killOnFailure)
self.Kill(teleporter, killDamageTypes); self.Kill(teleporter, killDamageTypes);
return NextActivity; return true;
} }
destination = bestCell.Value; destination = bestCell.Value;
@@ -112,7 +112,7 @@ namespace OpenRA.Mods.Cnc.Activities
building.PlayCustomAnimation(teleporter, "active"); building.PlayCustomAnimation(teleporter, "active");
} }
return NextActivity; return true;
} }
CPos? ChooseBestDestinationCell(Actor self, CPos destination) CPos? ChooseBestDestinationCell(Actor self, CPos destination)

View File

@@ -27,7 +27,7 @@ namespace OpenRA.Mods.Cnc.Activities
spriteOverlay = refinery.TraitOrDefault<WithDockingOverlay>(); spriteOverlay = refinery.TraitOrDefault<WithDockingOverlay>();
} }
public override Activity OnStateDock(Actor self) public override void OnStateDock(Actor self)
{ {
body.Docked = true; body.Docked = true;
@@ -42,11 +42,9 @@ namespace OpenRA.Mods.Cnc.Activities
} }
else else
dockingState = DockingState.Loop; dockingState = DockingState.Loop;
return this;
} }
public override Activity OnStateUndock(Actor self) public override void OnStateUndock(Actor self)
{ {
dockingState = DockingState.Wait; dockingState = DockingState.Wait;
@@ -65,8 +63,6 @@ namespace OpenRA.Mods.Cnc.Activities
dockingState = DockingState.Complete; dockingState = DockingState.Complete;
body.Docked = false; body.Docked = false;
} }
return this;
} }
} }
} }

View File

@@ -46,13 +46,13 @@ namespace OpenRA.Mods.Cnc.Traits
this.forceAttack = forceAttack; this.forceAttack = forceAttack;
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (IsCanceling || !target.IsValidFor(self)) if (IsCanceling || !target.IsValidFor(self))
return NextActivity; return true;
if (attack.IsTraitDisabled) if (attack.IsTraitDisabled)
return this; return false;
var weapon = attack.ChooseArmamentsForTarget(target, forceAttack).FirstOrDefault(); var weapon = attack.ChooseArmamentsForTarget(target, forceAttack).FirstOrDefault();
if (weapon != null) if (weapon != null)
@@ -60,13 +60,13 @@ namespace OpenRA.Mods.Cnc.Traits
// Check that AttackTDGunboatTurreted hasn't cancelled the target by modifying attack.Target // Check that AttackTDGunboatTurreted hasn't cancelled the target by modifying attack.Target
// Having both this and AttackTDGunboatTurreted modify that field is a horrible hack. // Having both this and AttackTDGunboatTurreted modify that field is a horrible hack.
if (hasTicked && attack.RequestedTarget.Type == TargetType.Invalid) if (hasTicked && attack.RequestedTarget.Type == TargetType.Invalid)
return NextActivity; return true;
attack.SetRequestedTarget(self, target); attack.SetRequestedTarget(self, target);
hasTicked = true; hasTicked = true;
} }
return NextActivity; return true;
} }
} }
} }

View File

@@ -94,13 +94,13 @@ namespace OpenRA.Mods.Cnc.Traits
this.forceAttack = forceAttack; this.forceAttack = forceAttack;
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (IsCanceling || !attack.CanAttack(self, target)) if (IsCanceling || !attack.CanAttack(self, target))
return NextActivity; return true;
if (attack.charges == 0) if (attack.charges == 0)
return this; return false;
foreach (var notify in self.TraitsImplementing<INotifyTeslaCharging>()) foreach (var notify in self.TraitsImplementing<INotifyTeslaCharging>())
notify.Charging(self, target); notify.Charging(self, target);
@@ -110,7 +110,7 @@ namespace OpenRA.Mods.Cnc.Traits
QueueChild(new Wait(attack.info.InitialChargeDelay)); QueueChild(new Wait(attack.info.InitialChargeDelay));
QueueChild(new ChargeFire(attack, target)); QueueChild(new ChargeFire(attack, target));
return this; return false;
} }
void IActivityNotifyStanceChanged.StanceChanged(Actor self, AutoTarget autoTarget, UnitStance oldStance, UnitStance newStance) void IActivityNotifyStanceChanged.StanceChanged(Actor self, AutoTarget autoTarget, UnitStance oldStance, UnitStance newStance)
@@ -145,18 +145,18 @@ namespace OpenRA.Mods.Cnc.Traits
this.target = target; this.target = target;
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (IsCanceling || !attack.CanAttack(self, target)) if (IsCanceling || !attack.CanAttack(self, target))
return NextActivity; return true;
if (attack.charges == 0) if (attack.charges == 0)
return NextActivity; return true;
attack.DoAttack(self, target); attack.DoAttack(self, target);
QueueChild(new Wait(attack.info.ChargeDelay)); QueueChild(new Wait(attack.info.ChargeDelay));
return this; return false;
} }
} }
} }

View File

@@ -32,7 +32,7 @@ namespace OpenRA.Mods.Common.Activities
acceleration = self.World.SharedRandom.Next(2) * 2 - 1; acceleration = self.World.SharedRandom.Next(2) * 2 - 1;
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (self.World.Map.DistanceAboveTerrain(self.CenterPosition).Length <= 0) if (self.World.Map.DistanceAboveTerrain(self.CenterPosition).Length <= 0)
{ {
@@ -43,7 +43,8 @@ namespace OpenRA.Mods.Common.Activities
} }
self.Kill(self); self.Kill(self);
return null; Cancel(self);
return true;
} }
if (info.Spins) if (info.Spins)
@@ -56,7 +57,7 @@ namespace OpenRA.Mods.Common.Activities
move -= new WVec(WDist.Zero, WDist.Zero, info.Velocity); move -= new WVec(WDist.Zero, WDist.Zero, info.Velocity);
aircraft.SetPosition(self, aircraft.CenterPosition + move); aircraft.SetPosition(self, aircraft.CenterPosition + move);
return this; return false;
} }
} }
} }

View File

@@ -100,7 +100,7 @@ namespace OpenRA.Mods.Common.Activities
return true; return true;
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
// Refuse to take off if it would land immediately again. // Refuse to take off if it would land immediately again.
if (aircraft.ForceLanding) if (aircraft.ForceLanding)
@@ -122,15 +122,15 @@ namespace OpenRA.Mods.Common.Activities
else else
VerticalTakeOffOrLandTick(self, aircraft, aircraft.Facing, aircraft.Info.CruiseAltitude); VerticalTakeOffOrLandTick(self, aircraft, aircraft.Facing, aircraft.Info.CruiseAltitude);
return this; return false;
} }
return NextActivity; return true;
} }
else if (dat <= aircraft.LandAltitude) else if (dat <= aircraft.LandAltitude)
{ {
QueueChild(new TakeOff(self, target)); QueueChild(new TakeOff(self, target));
return this; return false;
} }
bool targetIsHiddenActor; bool targetIsHiddenActor;
@@ -147,7 +147,7 @@ namespace OpenRA.Mods.Common.Activities
// Target is hidden or dead, and we don't have a fallback position to move towards // Target is hidden or dead, and we don't have a fallback position to move towards
if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self)) if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self))
return NextActivity; return true;
var checkTarget = useLastVisibleTarget ? lastVisibleTarget : target; var checkTarget = useLastVisibleTarget ? lastVisibleTarget : target;
var pos = aircraft.GetPosition(); var pos = aircraft.GetPosition();
@@ -158,7 +158,7 @@ namespace OpenRA.Mods.Common.Activities
var insideMaxRange = maxRange.Length > 0 && checkTarget.IsInRange(pos, maxRange); var insideMaxRange = maxRange.Length > 0 && checkTarget.IsInRange(pos, maxRange);
var insideMinRange = minRange.Length > 0 && checkTarget.IsInRange(pos, minRange); var insideMinRange = minRange.Length > 0 && checkTarget.IsInRange(pos, minRange);
if (insideMaxRange && !insideMinRange) if (insideMaxRange && !insideMinRange)
return NextActivity; return true;
var move = aircraft.Info.CanHover ? aircraft.FlyStep(desiredFacing) : aircraft.FlyStep(aircraft.Facing); var move = aircraft.Info.CanHover ? aircraft.FlyStep(desiredFacing) : aircraft.FlyStep(aircraft.Facing);
@@ -166,7 +166,7 @@ namespace OpenRA.Mods.Common.Activities
if (aircraft.Info.CanHover && insideMinRange) if (aircraft.Info.CanHover && insideMinRange)
{ {
FlyTick(self, aircraft, desiredFacing, aircraft.Info.CruiseAltitude, -move); FlyTick(self, aircraft, desiredFacing, aircraft.Info.CruiseAltitude, -move);
return this; return false;
} }
// The next move would overshoot, so consider it close enough or set final position if CanHover // The next move would overshoot, so consider it close enough or set final position if CanHover
@@ -186,11 +186,11 @@ namespace OpenRA.Mods.Common.Activities
if (dat != aircraft.Info.CruiseAltitude) if (dat != aircraft.Info.CruiseAltitude)
{ {
Fly.VerticalTakeOffOrLandTick(self, aircraft, aircraft.Facing, aircraft.Info.CruiseAltitude); Fly.VerticalTakeOffOrLandTick(self, aircraft, aircraft.Facing, aircraft.Info.CruiseAltitude);
return this; return false;
} }
} }
return NextActivity; return true;
} }
if (!aircraft.Info.CanHover) if (!aircraft.Info.CanHover)
@@ -216,7 +216,7 @@ namespace OpenRA.Mods.Common.Activities
FlyTick(self, aircraft, desiredFacing, aircraft.Info.CruiseAltitude); FlyTick(self, aircraft, desiredFacing, aircraft.Info.CruiseAltitude);
return this; return false;
} }
public override IEnumerable<Target> GetTargets(Actor self) public override IEnumerable<Target> GetTargets(Actor self)

View File

@@ -63,7 +63,7 @@ namespace OpenRA.Mods.Common.Activities
} }
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
// Refuse to take off if it would land immediately again. // Refuse to take off if it would land immediately again.
if (aircraft.ForceLanding) if (aircraft.ForceLanding)
@@ -73,16 +73,16 @@ namespace OpenRA.Mods.Common.Activities
{ {
// Cancel the requested target, but keep firing on it while in range // Cancel the requested target, but keep firing on it while in range
attackAircraft.ClearRequestedTarget(); attackAircraft.ClearRequestedTarget();
return NextActivity; return true;
} }
// Check that AttackFollow hasn't cancelled the target by modifying attack.Target // Check that AttackFollow hasn't cancelled the target by modifying attack.Target
// Having both this and AttackFollow modify that field is a horrible hack. // Having both this and AttackFollow modify that field is a horrible hack.
if (hasTicked && attackAircraft.RequestedTarget.Type == TargetType.Invalid) if (hasTicked && attackAircraft.RequestedTarget.Type == TargetType.Invalid)
return NextActivity; return true;
if (attackAircraft.IsTraitPaused) if (attackAircraft.IsTraitPaused)
return this; return false;
bool targetIsHiddenActor; bool targetIsHiddenActor;
target = target.Recalculate(self.Owner, out targetIsHiddenActor); target = target.Recalculate(self.Owner, out targetIsHiddenActor);
@@ -108,14 +108,14 @@ namespace OpenRA.Mods.Common.Activities
if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self)) if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self))
{ {
attackAircraft.ClearRequestedTarget(); attackAircraft.ClearRequestedTarget();
return NextActivity; return true;
} }
// If all valid weapons have depleted their ammo and Rearmable trait exists, return to RearmActor to reload and then resume the activity // If all valid weapons have depleted their ammo and Rearmable trait exists, return to RearmActor to reload and then resume the activity
if (rearmable != null && !useLastVisibleTarget && attackAircraft.Armaments.All(x => x.IsTraitPaused || !x.Weapon.IsValidAgainst(target, self.World, self))) if (rearmable != null && !useLastVisibleTarget && attackAircraft.Armaments.All(x => x.IsTraitPaused || !x.Weapon.IsValidAgainst(target, self.World, self)))
{ {
QueueChild(new ReturnToBase(self, aircraft.Info.AbortOnResupply)); QueueChild(new ReturnToBase(self, aircraft.Info.AbortOnResupply));
return this; return false;
} }
var pos = self.CenterPosition; var pos = self.CenterPosition;
@@ -128,12 +128,12 @@ namespace OpenRA.Mods.Common.Activities
if (checkTarget.IsInRange(pos, lastVisibleMaximumRange)) if (checkTarget.IsInRange(pos, lastVisibleMaximumRange))
{ {
attackAircraft.ClearRequestedTarget(); attackAircraft.ClearRequestedTarget();
return NextActivity; return true;
} }
// Fly towards the last known position // Fly towards the last known position
QueueChild(new Fly(self, target, WDist.Zero, lastVisibleMaximumRange, checkTarget.CenterPosition, Color.Red)); QueueChild(new Fly(self, target, WDist.Zero, lastVisibleMaximumRange, checkTarget.CenterPosition, Color.Red));
return this; return false;
} }
var delta = attackAircraft.GetTargetPosition(pos, target) - pos; var delta = attackAircraft.GetTargetPosition(pos, target) - pos;
@@ -160,7 +160,7 @@ namespace OpenRA.Mods.Common.Activities
Fly.VerticalTakeOffOrLandTick(self, aircraft, desiredFacing, aircraft.Info.CruiseAltitude); Fly.VerticalTakeOffOrLandTick(self, aircraft, desiredFacing, aircraft.Info.CruiseAltitude);
} }
return this; return false;
} }
void IActivityNotifyStanceChanged.StanceChanged(Actor self, AutoTarget autoTarget, UnitStance oldStance, UnitStance newStance) void IActivityNotifyStanceChanged.StanceChanged(Actor self, AutoTarget autoTarget, UnitStance oldStance, UnitStance newStance)

View File

@@ -27,20 +27,20 @@ namespace OpenRA.Mods.Common.Activities
this.turnSpeedOverride = turnSpeedOverride; this.turnSpeedOverride = turnSpeedOverride;
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (remainingTicks == 0 || (NextActivity != null && remainingTicks < 0)) if (remainingTicks == 0 || (NextActivity != null && remainingTicks < 0))
return NextActivity; return true;
// Refuse to take off if it would land immediately again. // Refuse to take off if it would land immediately again.
if (aircraft.ForceLanding) if (aircraft.ForceLanding)
{ {
Cancel(self); Cancel(self);
return NextActivity; return true;
} }
if (IsCanceling) if (IsCanceling)
return NextActivity; return true;
if (remainingTicks > 0) if (remainingTicks > 0)
remainingTicks--; remainingTicks--;
@@ -53,7 +53,7 @@ namespace OpenRA.Mods.Common.Activities
Fly.FlyTick(self, aircraft, desiredFacing, aircraft.Info.CruiseAltitude, move, turnSpeedOverride); Fly.FlyTick(self, aircraft, desiredFacing, aircraft.Info.CruiseAltitude, move, turnSpeedOverride);
return this; return false;
} }
} }
} }

View File

@@ -45,14 +45,14 @@ namespace OpenRA.Mods.Common.Activities
lastVisibleTarget = Target.FromPos(initialTargetPosition.Value); lastVisibleTarget = Target.FromPos(initialTargetPosition.Value);
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
// Refuse to take off if it would land immediately again. // Refuse to take off if it would land immediately again.
if (aircraft.ForceLanding) if (aircraft.ForceLanding)
Cancel(self); Cancel(self);
if (IsCanceling) if (IsCanceling)
return NextActivity; return true;
bool targetIsHiddenActor; bool targetIsHiddenActor;
target = target.Recalculate(self.Owner, out targetIsHiddenActor); target = target.Recalculate(self.Owner, out targetIsHiddenActor);
@@ -65,7 +65,7 @@ namespace OpenRA.Mods.Common.Activities
// If we are ticking again after previously sequencing a MoveWithRange then that move must have completed // If we are ticking again after previously sequencing a MoveWithRange then that move must have completed
// Either we are in range and can see the target, or we've lost track of it and should give up // Either we are in range and can see the target, or we've lost track of it and should give up
if (wasMovingWithinRange && targetIsHiddenActor) if (wasMovingWithinRange && targetIsHiddenActor)
return NextActivity; return true;
wasMovingWithinRange = false; wasMovingWithinRange = false;
@@ -75,7 +75,7 @@ namespace OpenRA.Mods.Common.Activities
// Target is hidden or dead, and we don't have a fallback position to move towards // Target is hidden or dead, and we don't have a fallback position to move towards
if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self)) if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self))
return NextActivity; return true;
var pos = self.CenterPosition; var pos = self.CenterPosition;
var checkTarget = useLastVisibleTarget ? lastVisibleTarget : target; var checkTarget = useLastVisibleTarget ? lastVisibleTarget : target;
@@ -85,12 +85,12 @@ namespace OpenRA.Mods.Common.Activities
if (checkTarget.IsInRange(pos, maxRange) && !checkTarget.IsInRange(pos, minRange)) if (checkTarget.IsInRange(pos, maxRange) && !checkTarget.IsInRange(pos, minRange))
{ {
Fly.FlyTick(self, aircraft, aircraft.Facing, aircraft.Info.CruiseAltitude); Fly.FlyTick(self, aircraft, aircraft.Facing, aircraft.Info.CruiseAltitude);
return useLastVisibleTarget ? NextActivity : this; return useLastVisibleTarget;
} }
wasMovingWithinRange = true; wasMovingWithinRange = true;
QueueChild(aircraft.MoveWithinRange(target, minRange, maxRange, checkTarget.CenterPosition, targetLineColor)); QueueChild(aircraft.MoveWithinRange(target, minRange, maxRange, checkTarget.CenterPosition, targetLineColor));
return this; return false;
} }
} }
} }

View File

@@ -23,20 +23,20 @@ namespace OpenRA.Mods.Common.Activities
aircraft = self.Trait<Aircraft>(); aircraft = self.Trait<Aircraft>();
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
// Refuse to take off if it would land immediately again. // Refuse to take off if it would land immediately again.
if (aircraft.ForceLanding) if (aircraft.ForceLanding)
{ {
Cancel(self); Cancel(self);
return NextActivity; return true;
} }
if (IsCanceling || !self.World.Map.Contains(self.Location)) if (IsCanceling || !self.World.Map.Contains(self.Location))
return NextActivity; return true;
Fly.FlyTick(self, aircraft, aircraft.Facing, aircraft.Info.CruiseAltitude); Fly.FlyTick(self, aircraft, aircraft.Facing, aircraft.Info.CruiseAltitude);
return this; return false;
} }
} }
} }

View File

@@ -27,21 +27,21 @@ namespace OpenRA.Mods.Common.Activities
cruiseAltitude = aircraft.Info.CruiseAltitude; cruiseAltitude = aircraft.Info.CruiseAltitude;
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
// Refuse to take off if it would land immediately again. // Refuse to take off if it would land immediately again.
if (aircraft.ForceLanding) if (aircraft.ForceLanding)
{ {
Cancel(self); Cancel(self);
return NextActivity; return true;
} }
if (IsCanceling || remainingTicks-- == 0) if (IsCanceling || remainingTicks-- == 0)
return NextActivity; return true;
Fly.FlyTick(self, aircraft, aircraft.Facing, cruiseAltitude); Fly.FlyTick(self, aircraft, aircraft.Facing, cruiseAltitude);
return this; return false;
} }
} }
} }

View File

@@ -71,7 +71,7 @@ namespace OpenRA.Mods.Common.Activities
target = Target.FromCell(self.World, self.Location); target = Target.FromCell(self.World, self.Location);
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (IsCanceling || target.Type == TargetType.Invalid) if (IsCanceling || target.Type == TargetType.Invalid)
{ {
@@ -88,15 +88,15 @@ namespace OpenRA.Mods.Common.Activities
if (dat > aircraft.LandAltitude && dat < aircraft.Info.CruiseAltitude) if (dat > aircraft.LandAltitude && dat < aircraft.Info.CruiseAltitude)
{ {
QueueChild(new TakeOff(self)); QueueChild(new TakeOff(self));
return this; return false;
} }
aircraft.RemoveInfluence(); aircraft.RemoveInfluence();
return NextActivity; return true;
} }
} }
else else
return NextActivity; return true;
} }
var pos = aircraft.GetPosition(); var pos = aircraft.GetPosition();
@@ -107,7 +107,7 @@ namespace OpenRA.Mods.Common.Activities
// We are already at the landing location. // We are already at the landing location.
if ((targetPosition - pos).LengthSquared == 0) if ((targetPosition - pos).LengthSquared == 0)
return NextActivity; return true;
// Look for free landing cell // Look for free landing cell
if (target.Type == TargetType.Terrain && !landingInitiated) if (target.Type == TargetType.Terrain && !landingInitiated)
@@ -119,7 +119,7 @@ namespace OpenRA.Mods.Common.Activities
{ {
Cancel(self, true); Cancel(self, true);
QueueChild(aircraft.MoveTo(landingCell, 0)); QueueChild(aircraft.MoveTo(landingCell, 0));
return this; return false;
} }
if (newLocation.Value != landingCell) if (newLocation.Value != landingCell)
@@ -138,7 +138,7 @@ namespace OpenRA.Mods.Common.Activities
if (desiredFacing != -1) if (desiredFacing != -1)
QueueChild(new Turn(self, desiredFacing)); QueueChild(new Turn(self, desiredFacing));
return this; return false;
} }
if (!aircraft.Info.VTOL && !finishedApproach) if (!aircraft.Info.VTOL && !finishedApproach)
@@ -198,7 +198,7 @@ namespace OpenRA.Mods.Common.Activities
// Fix a problem when the airplane is sent to land near the landing cell // Fix a problem when the airplane is sent to land near the landing cell
QueueChild(new Fly(self, Target.FromPos(w3), WDist.Zero, new WDist(turnRadius / 2))); QueueChild(new Fly(self, Target.FromPos(w3), WDist.Zero, new WDist(turnRadius / 2)));
finishedApproach = true; finishedApproach = true;
return this; return false;
} }
if (!landingInitiated) if (!landingInitiated)
@@ -215,7 +215,7 @@ namespace OpenRA.Mods.Common.Activities
self.NotifyBlocker(blockingCells); self.NotifyBlocker(blockingCells);
finishedApproach = false; finishedApproach = false;
return this; return false;
} }
if (aircraft.Info.LandingSounds.Length > 0) if (aircraft.Info.LandingSounds.Length > 0)
@@ -231,9 +231,9 @@ namespace OpenRA.Mods.Common.Activities
{ {
var landAltitude = self.World.Map.DistanceAboveTerrain(targetPosition) + aircraft.LandAltitude; var landAltitude = self.World.Map.DistanceAboveTerrain(targetPosition) + aircraft.LandAltitude;
if (Fly.VerticalTakeOffOrLandTick(self, aircraft, aircraft.Facing, landAltitude)) if (Fly.VerticalTakeOffOrLandTick(self, aircraft, aircraft.Facing, landAltitude))
return this; return false;
return NextActivity; return true;
} }
var d = targetPosition - pos; var d = targetPosition - pos;
@@ -244,13 +244,13 @@ namespace OpenRA.Mods.Common.Activities
{ {
var landingAltVec = new WVec(WDist.Zero, WDist.Zero, aircraft.LandAltitude); var landingAltVec = new WVec(WDist.Zero, WDist.Zero, aircraft.LandAltitude);
aircraft.SetPosition(self, targetPosition + landingAltVec); aircraft.SetPosition(self, targetPosition + landingAltVec);
return NextActivity; return true;
} }
var landingAlt = self.World.Map.DistanceAboveTerrain(targetPosition) + aircraft.LandAltitude; var landingAlt = self.World.Map.DistanceAboveTerrain(targetPosition) + aircraft.LandAltitude;
Fly.FlyTick(self, aircraft, d.Yaw.Facing, landingAlt); Fly.FlyTick(self, aircraft, d.Yaw.Facing, landingAlt);
return this; return false;
} }
} }
} }

View File

@@ -66,12 +66,12 @@ namespace OpenRA.Mods.Common.Activities
&& rearmable.RearmableAmmoPools.Any(p => !p.FullAmmo()); && rearmable.RearmableAmmoPools.Any(p => !p.FullAmmo());
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
// Refuse to take off if it would land immediately again. // Refuse to take off if it would land immediately again.
// Special case: Don't kill other deploy hotkey activities. // Special case: Don't kill other deploy hotkey activities.
if (aircraft.ForceLanding) if (aircraft.ForceLanding)
return NextActivity; return true;
// If a Cancel was triggered at this point, it's unlikely that previously queued child activities finished, // If a Cancel was triggered at this point, it's unlikely that previously queued child activities finished,
// so 'resupplied' needs to be set to false, else it + abortOnResupply might cause another Cancel // so 'resupplied' needs to be set to false, else it + abortOnResupply might cause another Cancel
@@ -84,7 +84,7 @@ namespace OpenRA.Mods.Common.Activities
self.CancelActivity(); self.CancelActivity();
if (resupplied || IsCanceling || self.IsDead) if (resupplied || IsCanceling || self.IsDead)
return NextActivity; return true;
if (dest == null || dest.IsDead || !Reservable.IsAvailableFor(dest, self)) if (dest == null || dest.IsDead || !Reservable.IsAvailableFor(dest, self))
dest = ChooseResupplier(self, true); dest = ChooseResupplier(self, true);
@@ -109,17 +109,17 @@ namespace OpenRA.Mods.Common.Activities
QueueChild(new Fly(self, target, WDist.Zero, aircraft.Info.WaitDistanceFromResupplyBase, targetLineColor: Color.Green)); QueueChild(new Fly(self, target, WDist.Zero, aircraft.Info.WaitDistanceFromResupplyBase, targetLineColor: Color.Green));
} }
return this; return false;
} }
QueueChild(new Fly(self, Target.FromActor(nearestResupplier), WDist.Zero, aircraft.Info.WaitDistanceFromResupplyBase, targetLineColor: Color.Green)); QueueChild(new Fly(self, Target.FromActor(nearestResupplier), WDist.Zero, aircraft.Info.WaitDistanceFromResupplyBase, targetLineColor: Color.Green));
QueueChild(new FlyCircle(self, aircraft.Info.NumberOfTicksToVerifyAvailableAirport)); QueueChild(new FlyCircle(self, aircraft.Info.NumberOfTicksToVerifyAvailableAirport));
return this; return false;
} }
// Prevent an infinite loop in case we'd return to the activity that called ReturnToBase in the first place. Go idle instead. // Prevent an infinite loop in case we'd return to the activity that called ReturnToBase in the first place. Go idle instead.
self.CancelActivity(); self.CancelActivity();
return NextActivity; return true;
} }
if (ShouldLandAtBuilding(self, dest)) if (ShouldLandAtBuilding(self, dest))
@@ -141,7 +141,7 @@ namespace OpenRA.Mods.Common.Activities
QueueChild(new Fly(self, Target.FromActor(dest))); QueueChild(new Fly(self, Target.FromActor(dest)));
resupplied = true; resupplied = true;
return this; return false;
} }
} }
} }

View File

@@ -62,13 +62,13 @@ namespace OpenRA.Mods.Common.Activities
Game.Sound.Play(SoundType.World, aircraft.Info.TakeoffSounds, self.World, aircraft.CenterPosition); Game.Sound.Play(SoundType.World, aircraft.Info.TakeoffSounds, self.World, aircraft.CenterPosition);
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
// Refuse to take off if it would land immediately again. // Refuse to take off if it would land immediately again.
if (aircraft.ForceLanding) if (aircraft.ForceLanding)
{ {
Cancel(self); Cancel(self);
return NextActivity; return true;
} }
var dat = self.World.Map.DistanceAboveTerrain(aircraft.CenterPosition); var dat = self.World.Map.DistanceAboveTerrain(aircraft.CenterPosition);
@@ -78,12 +78,12 @@ namespace OpenRA.Mods.Common.Activities
if (aircraft.Info.VTOL) if (aircraft.Info.VTOL)
{ {
Fly.VerticalTakeOffOrLandTick(self, aircraft, aircraft.Facing, aircraft.Info.CruiseAltitude); Fly.VerticalTakeOffOrLandTick(self, aircraft, aircraft.Facing, aircraft.Info.CruiseAltitude);
return this; return false;
} }
else else
{ {
Fly.FlyTick(self, aircraft, aircraft.Facing, aircraft.Info.CruiseAltitude); Fly.FlyTick(self, aircraft, aircraft.Facing, aircraft.Info.CruiseAltitude);
return this; return false;
} }
} }
@@ -91,14 +91,14 @@ namespace OpenRA.Mods.Common.Activities
if (moveToRallyPoint && NextActivity == null) if (moveToRallyPoint && NextActivity == null)
{ {
if (!aircraft.Info.VTOL && assignTargetOnFirstRun) if (!aircraft.Info.VTOL && assignTargetOnFirstRun)
return NextActivity; return true;
QueueChild(new AttackMoveActivity(self, () => move.MoveToTarget(self, target))); QueueChild(new AttackMoveActivity(self, () => move.MoveToTarget(self, target)));
moveToRallyPoint = false; moveToRallyPoint = false;
return this; return false;
} }
return NextActivity; return true;
} }
} }
} }

View File

@@ -83,10 +83,10 @@ namespace OpenRA.Mods.Common.Activities
return target.Recalculate(self.Owner, out targetIsHiddenActor); return target.Recalculate(self.Owner, out targetIsHiddenActor);
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (IsCanceling) if (IsCanceling)
return NextActivity; return true;
bool targetIsHiddenActor; bool targetIsHiddenActor;
target = RecalculateTarget(self, out targetIsHiddenActor); target = RecalculateTarget(self, out targetIsHiddenActor);
@@ -106,7 +106,7 @@ namespace OpenRA.Mods.Common.Activities
// If we are ticking again after previously sequencing a MoveWithRange then that move must have completed // If we are ticking again after previously sequencing a MoveWithRange then that move must have completed
// Either we are in range and can see the target, or we've lost track of it and should give up // Either we are in range and can see the target, or we've lost track of it and should give up
if (wasMovingWithinRange && targetIsHiddenActor) if (wasMovingWithinRange && targetIsHiddenActor)
return NextActivity; return true;
// Update target lines if required // Update target lines if required
if (useLastVisibleTarget != oldUseLastVisibleTarget) if (useLastVisibleTarget != oldUseLastVisibleTarget)
@@ -114,7 +114,7 @@ namespace OpenRA.Mods.Common.Activities
// Target is hidden or dead, and we don't have a fallback position to move towards // Target is hidden or dead, and we don't have a fallback position to move towards
if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self)) if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self))
return NextActivity; return true;
wasMovingWithinRange = false; wasMovingWithinRange = false;
var pos = self.CenterPosition; var pos = self.CenterPosition;
@@ -125,12 +125,12 @@ namespace OpenRA.Mods.Common.Activities
{ {
// We've reached the assumed position but it is not there or we can't move any further - give up // We've reached the assumed position but it is not there or we can't move any further - give up
if (checkTarget.IsInRange(pos, lastVisibleMaximumRange) || move == null || lastVisibleMaximumRange == WDist.Zero) if (checkTarget.IsInRange(pos, lastVisibleMaximumRange) || move == null || lastVisibleMaximumRange == WDist.Zero)
return NextActivity; return true;
// Move towards the last known position // Move towards the last known position
wasMovingWithinRange = true; wasMovingWithinRange = true;
QueueChild(move.MoveWithinRange(target, WDist.Zero, lastVisibleMaximumRange, checkTarget.CenterPosition, Color.Red)); QueueChild(move.MoveWithinRange(target, WDist.Zero, lastVisibleMaximumRange, checkTarget.CenterPosition, Color.Red));
return this; return false;
} }
attackStatus = AttackStatus.UnableToAttack; attackStatus = AttackStatus.UnableToAttack;
@@ -145,9 +145,9 @@ namespace OpenRA.Mods.Common.Activities
wasMovingWithinRange = true; wasMovingWithinRange = true;
if (attackStatus >= AttackStatus.NeedsToTurn) if (attackStatus >= AttackStatus.NeedsToTurn)
return this; return false;
return NextActivity; return true;
} }
protected virtual AttackStatus TickAttack(Actor self, AttackFrontal attack) protected virtual AttackStatus TickAttack(Actor self, AttackFrontal attack)

View File

@@ -37,10 +37,10 @@ namespace OpenRA.Mods.Common.Activities
harv.LinkProc(self, targetActor); harv.LinkProc(self, targetActor);
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (IsCanceling || isDocking) if (IsCanceling || isDocking)
return NextActivity; return true;
// Find the nearest best refinery if not explicitly ordered to a specific refinery: // Find the nearest best refinery if not explicitly ordered to a specific refinery:
if (harv.LinkedProc == null || !harv.LinkedProc.IsInWorld) if (harv.LinkedProc == null || !harv.LinkedProc.IsInWorld)
@@ -50,7 +50,7 @@ namespace OpenRA.Mods.Common.Activities
if (harv.LinkedProc == null) if (harv.LinkedProc == null)
{ {
QueueChild(new Wait(harv.Info.SearchForDeliveryBuildingDelay)); QueueChild(new Wait(harv.Info.SearchForDeliveryBuildingDelay));
return this; return false;
} }
var proc = harv.LinkedProc; var proc = harv.LinkedProc;
@@ -63,7 +63,7 @@ namespace OpenRA.Mods.Common.Activities
n.MovingToRefinery(self, proc, new FindAndDeliverResources(self)); n.MovingToRefinery(self, proc, new FindAndDeliverResources(self));
QueueChild(movement.MoveTo(proc.Location + iao.DeliveryOffset, 0)); QueueChild(movement.MoveTo(proc.Location + iao.DeliveryOffset, 0));
return this; return false;
} }
if (!isDocking) if (!isDocking)
@@ -71,10 +71,10 @@ namespace OpenRA.Mods.Common.Activities
QueueChild(new Wait(10)); QueueChild(new Wait(10));
isDocking = true; isDocking = true;
iao.OnDock(self, this); iao.OnDock(self, this);
return this; return false;
} }
return NextActivity; return true;
} }
} }
} }

View File

@@ -36,15 +36,15 @@ namespace OpenRA.Mods.Common.Activities
QueueChild(new Turn(self, deploy.Info.Facing)); QueueChild(new Turn(self, deploy.Info.Facing));
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (IsCanceling || initiated || (deploy.DeployState != DeployState.Deployed && moving)) if (IsCanceling || initiated || (deploy.DeployState != DeployState.Deployed && moving))
return NextActivity; return true;
QueueChild(new DeployInner(self, deploy)); QueueChild(new DeployInner(self, deploy));
initiated = true; initiated = true;
return this; return false;
} }
} }
@@ -61,14 +61,14 @@ namespace OpenRA.Mods.Common.Activities
IsInterruptible = false; IsInterruptible = false;
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
// Wait for deployment // Wait for deployment
if (deployment.DeployState == DeployState.Deploying || deployment.DeployState == DeployState.Undeploying) if (deployment.DeployState == DeployState.Deploying || deployment.DeployState == DeployState.Undeploying)
return this; return false;
if (initiated) if (initiated)
return NextActivity; return true;
if (deployment.DeployState == DeployState.Undeployed) if (deployment.DeployState == DeployState.Undeployed)
deployment.Deploy(); deployment.Deploy();
@@ -76,7 +76,7 @@ namespace OpenRA.Mods.Common.Activities
deployment.Undeploy(); deployment.Undeploy();
initiated = true; initiated = true;
return this; return false;
} }
} }
} }

View File

@@ -58,7 +58,7 @@ namespace OpenRA.Mods.Common.Activities
/// </summary> /// </summary>
protected virtual void OnEnterComplete(Actor self, Actor targetActor) { } protected virtual void OnEnterComplete(Actor self, Actor targetActor) { }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
// Update our view of the target // Update our view of the target
bool targetIsHiddenActor; bool targetIsHiddenActor;
@@ -81,9 +81,8 @@ namespace OpenRA.Mods.Common.Activities
// We need to wait for movement to finish before transitioning to // We need to wait for movement to finish before transitioning to
// the next state or next activity // the next state or next activity
ChildActivity = ActivityUtils.RunActivity(self, ChildActivity); if (!TickChild(self))
if (ChildActivity != null) return false;
return this;
// Note that lastState refers to what we have just *finished* doing // Note that lastState refers to what we have just *finished* doing
switch (lastState) switch (lastState)
@@ -93,11 +92,11 @@ namespace OpenRA.Mods.Common.Activities
// NOTE: We can safely cancel in this case because we know the // NOTE: We can safely cancel in this case because we know the
// actor has finished any in-progress move activities // actor has finished any in-progress move activities
if (IsCanceling) if (IsCanceling)
return NextActivity; return true;
// Lost track of the target // Lost track of the target
if (useLastVisibleTarget && lastVisibleTarget.Type == TargetType.Invalid) if (useLastVisibleTarget && lastVisibleTarget.Type == TargetType.Invalid)
return NextActivity; return true;
// We are not next to the target - lets fix that // We are not next to the target - lets fix that
if (target.Type != TargetType.Invalid && !move.CanEnterTargetNow(self, target)) if (target.Type != TargetType.Invalid && !move.CanEnterTargetNow(self, target))
@@ -105,28 +104,28 @@ namespace OpenRA.Mods.Common.Activities
// Target lines are managed by this trait, so we do not pass targetLineColor // Target lines are managed by this trait, so we do not pass targetLineColor
var initialTargetPosition = (useLastVisibleTarget ? lastVisibleTarget : target).CenterPosition; var initialTargetPosition = (useLastVisibleTarget ? lastVisibleTarget : target).CenterPosition;
QueueChild(move.MoveToTarget(self, target, initialTargetPosition)); QueueChild(move.MoveToTarget(self, target, initialTargetPosition));
return this; return false;
} }
// We are next to where we thought the target should be, but it isn't here // We are next to where we thought the target should be, but it isn't here
// There's not much more we can do here // There's not much more we can do here
if (useLastVisibleTarget || target.Type != TargetType.Actor) if (useLastVisibleTarget || target.Type != TargetType.Actor)
return NextActivity; return true;
// Are we ready to move into the target? // Are we ready to move into the target?
if (TryStartEnter(self, target.Actor)) if (TryStartEnter(self, target.Actor))
{ {
lastState = EnterState.Entering; lastState = EnterState.Entering;
QueueChild(move.MoveIntoTarget(self, target)); QueueChild(move.MoveIntoTarget(self, target));
return this; return false;
} }
// Subclasses can cancel the activity during TryStartEnter // Subclasses can cancel the activity during TryStartEnter
// Return immediately to avoid an extra tick's delay // Return immediately to avoid an extra tick's delay
if (IsCanceling) if (IsCanceling)
return NextActivity; return true;
return this; return false;
} }
case EnterState.Entering: case EnterState.Entering:
@@ -138,14 +137,14 @@ namespace OpenRA.Mods.Common.Activities
lastState = EnterState.Exiting; lastState = EnterState.Exiting;
QueueChild(move.MoveIntoWorld(self, self.Location)); QueueChild(move.MoveIntoWorld(self, self.Location));
return this; return false;
} }
case EnterState.Exiting: case EnterState.Exiting:
return NextActivity; return true;
} }
return this; return false;
} }
} }
} }

View File

@@ -76,20 +76,20 @@ namespace OpenRA.Mods.Common.Activities
} }
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (IsCanceling) if (IsCanceling)
return NextActivity; return true;
if (NextActivity != null) if (NextActivity != null)
{ {
// Interrupt automated harvesting after clearing the first cell. // Interrupt automated harvesting after clearing the first cell.
if (!harvInfo.QueueFullLoad && (hasHarvestedCell || harv.LastSearchFailed)) if (!harvInfo.QueueFullLoad && (hasHarvestedCell || harv.LastSearchFailed))
return NextActivity; return true;
// Interrupt automated harvesting after first complete harvest cycle. // Interrupt automated harvesting after first complete harvest cycle.
if (hasDeliveredLoad || harv.IsFull) if (hasDeliveredLoad || harv.IsFull)
return NextActivity; return true;
} }
// Are we full or have nothing more to gather? Deliver resources. // Are we full or have nothing more to gather? Deliver resources.
@@ -97,7 +97,7 @@ namespace OpenRA.Mods.Common.Activities
{ {
QueueChild(new DeliverResources(self)); QueueChild(new DeliverResources(self));
hasDeliveredLoad = true; hasDeliveredLoad = true;
return this; return false;
} }
// After a failed search, wait and sit still for a bit before searching again. // After a failed search, wait and sit still for a bit before searching again.
@@ -105,7 +105,7 @@ namespace OpenRA.Mods.Common.Activities
{ {
QueueChild(new Wait(harv.Info.WaitDuration)); QueueChild(new Wait(harv.Info.WaitDuration));
hasWaited = true; hasWaited = true;
return this; return false;
} }
hasWaited = false; hasWaited = false;
@@ -144,14 +144,14 @@ namespace OpenRA.Mods.Common.Activities
} }
} }
return this; return false;
} }
// If we get here, our search for resources was successful. Commence harvesting. // If we get here, our search for resources was successful. Commence harvesting.
QueueChild(new HarvestResource(self, closestHarvestableCell.Value)); QueueChild(new HarvestResource(self, closestHarvestableCell.Value));
lastHarvestedCell = closestHarvestableCell.Value; lastHarvestedCell = closestHarvestableCell.Value;
hasHarvestedCell = true; hasHarvestedCell = true;
return this; return false;
} }
/// <summary> /// <summary>

View File

@@ -47,10 +47,10 @@ namespace OpenRA.Mods.Common.Activities
claimLayer.TryClaimCell(self, targetCell); claimLayer.TryClaimCell(self, targetCell);
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (IsCanceling || harv.IsFull) if (IsCanceling || harv.IsFull)
return NextActivity; return true;
// Move towards the target cell // Move towards the target cell
if (self.Location != targetCell) if (self.Location != targetCell)
@@ -60,11 +60,11 @@ namespace OpenRA.Mods.Common.Activities
self.SetTargetLine(Target.FromCell(self.World, targetCell), Color.Red, false); self.SetTargetLine(Target.FromCell(self.World, targetCell), Color.Red, false);
QueueChild(move.MoveTo(targetCell, 2)); QueueChild(move.MoveTo(targetCell, 2));
return this; return false;
} }
if (!harv.CanHarvestCell(self, self.Location)) if (!harv.CanHarvestCell(self, self.Location))
return NextActivity; return true;
// Turn to one of the harvestable facings // Turn to one of the harvestable facings
if (harvInfo.HarvestFacings != 0) if (harvInfo.HarvestFacings != 0)
@@ -74,13 +74,13 @@ namespace OpenRA.Mods.Common.Activities
if (desired != current) if (desired != current)
{ {
QueueChild(new Turn(self, desired)); QueueChild(new Turn(self, desired));
return this; return false;
} }
} }
var resource = resLayer.Harvest(self.Location); var resource = resLayer.Harvest(self.Location);
if (resource == null) if (resource == null)
return NextActivity; return true;
harv.AcceptResource(self, resource); harv.AcceptResource(self, resource);
@@ -88,7 +88,7 @@ namespace OpenRA.Mods.Common.Activities
t.Harvested(self, resource); t.Harvested(self, resource);
QueueChild(new Wait(harvInfo.BaleLoadDelay)); QueueChild(new Wait(harvInfo.BaleLoadDelay));
return this; return false;
} }
protected override void OnLastRun(Actor self) protected override void OnLastRun(Actor self)

View File

@@ -19,7 +19,7 @@ namespace OpenRA.Mods.Common.Activities
{ {
public abstract class HarvesterDockSequence : Activity public abstract class HarvesterDockSequence : Activity
{ {
protected enum DockingState { Wait, Turn, Dock, Loop, Undock, Complete, Finished } protected enum DockingState { Wait, Turn, Dock, Loop, Undock, Complete }
protected readonly Actor Refinery; protected readonly Actor Refinery;
protected readonly Harvester Harv; protected readonly Harvester Harv;
@@ -45,35 +45,37 @@ namespace OpenRA.Mods.Common.Activities
EndDrag = refinery.CenterPosition + DragOffset; EndDrag = refinery.CenterPosition + DragOffset;
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
switch (dockingState) switch (dockingState)
{ {
case DockingState.Wait: case DockingState.Wait:
return this; return false;
case DockingState.Turn: case DockingState.Turn:
dockingState = DockingState.Dock; dockingState = DockingState.Dock;
QueueChild(new Turn(self, DockAngle)); QueueChild(new Turn(self, DockAngle));
if (IsDragRequired) if (IsDragRequired)
QueueChild(new Drag(self, StartDrag, EndDrag, DragLength)); QueueChild(new Drag(self, StartDrag, EndDrag, DragLength));
return this; return false;
case DockingState.Dock: case DockingState.Dock:
if (Refinery.IsInWorld && !Refinery.IsDead) if (Refinery.IsInWorld && !Refinery.IsDead)
foreach (var nd in Refinery.TraitsImplementing<INotifyDocking>()) foreach (var nd in Refinery.TraitsImplementing<INotifyDocking>())
nd.Docked(Refinery, self); nd.Docked(Refinery, self);
return OnStateDock(self); OnStateDock(self);
return false;
case DockingState.Loop: case DockingState.Loop:
if (!Refinery.IsInWorld || Refinery.IsDead || Harv.TickUnload(self, Refinery)) if (!Refinery.IsInWorld || Refinery.IsDead || Harv.TickUnload(self, Refinery))
dockingState = DockingState.Undock; dockingState = DockingState.Undock;
return this; return false;
case DockingState.Undock: case DockingState.Undock:
return OnStateUndock(self); OnStateUndock(self);
return false;
case DockingState.Complete: case DockingState.Complete:
if (Refinery.IsInWorld && !Refinery.IsDead) if (Refinery.IsInWorld && !Refinery.IsDead)
@@ -85,11 +87,7 @@ namespace OpenRA.Mods.Common.Activities
if (IsDragRequired) if (IsDragRequired)
QueueChild(new Drag(self, EndDrag, StartDrag, DragLength)); QueueChild(new Drag(self, EndDrag, StartDrag, DragLength));
dockingState = DockingState.Finished; return true;
return this;
case DockingState.Finished:
return NextActivity;
} }
throw new InvalidOperationException("Invalid harvester dock state"); throw new InvalidOperationException("Invalid harvester dock state");
@@ -106,8 +104,8 @@ namespace OpenRA.Mods.Common.Activities
yield return Target.FromActor(Refinery); yield return Target.FromActor(Refinery);
} }
public abstract Activity OnStateDock(Actor self); public abstract void OnStateDock(Actor self);
public abstract Activity OnStateUndock(Actor self); public abstract void OnStateUndock(Actor self);
} }
} }

View File

@@ -31,18 +31,18 @@ namespace OpenRA.Mods.Common.Activities
&& a.IsTargetableBy(self) && attack.HasAnyValidWeapons(Target.FromActor(a))); && a.IsTargetableBy(self) && attack.HasAnyValidWeapons(Target.FromActor(a)));
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (IsCanceling) if (IsCanceling)
return NextActivity; return true;
var target = targets.ClosestTo(self); var target = targets.ClosestTo(self);
if (target == null) if (target == null)
return this; return false;
QueueChild(new AttackMoveActivity(self, () => move.MoveTo(target.Location, 2))); QueueChild(new AttackMoveActivity(self, () => move.MoveTo(target.Location, 2)));
QueueChild(new Wait(25)); QueueChild(new Wait(25));
return this; return false;
} }
} }
} }

View File

@@ -50,7 +50,7 @@ namespace OpenRA.Mods.Common.Activities
token = conditionManager.GrantCondition(self, attackMove.Info.AssaultMoveCondition); token = conditionManager.GrantCondition(self, attackMove.Info.AssaultMoveCondition);
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
// We are not currently attacking a target, so scan for new targets. // We are not currently attacking a target, so scan for new targets.
if (!IsCanceling && ChildActivity != null && ChildActivity.NextActivity == null && autoTarget != null) if (!IsCanceling && ChildActivity != null && ChildActivity.NextActivity == null && autoTarget != null)
@@ -74,13 +74,9 @@ namespace OpenRA.Mods.Common.Activities
} }
} }
ChildActivity = ActivityUtils.RunActivity(self, ChildActivity); // The last queued childactivity is guaranteed to be the inner move, so if the childactivity
if (ChildActivity != null) // queue is empty it means we have reached our destination and there are no more enemies on our path.
return this; return TickChild(self);
// The last queued childactivity is guaranteed to be the inner move, so if we get here it means
// we have reached our destination and there are no more enemies on our path.
return NextActivity;
} }
protected override void OnLastRun(Actor self) protected override void OnLastRun(Actor self)

View File

@@ -34,10 +34,10 @@ namespace OpenRA.Mods.Common.Activities
IsInterruptible = false; IsInterruptible = false;
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (disableable != null && disableable.IsTraitDisabled) if (disableable != null && disableable.IsTraitDisabled)
return this; return false;
var pos = length > 1 var pos = length > 1
? WPos.Lerp(start, end, ticks, length - 1) ? WPos.Lerp(start, end, ticks, length - 1)
@@ -45,9 +45,9 @@ namespace OpenRA.Mods.Common.Activities
positionable.SetVisualPosition(self, pos); positionable.SetVisualPosition(self, pos);
if (++ticks >= length) if (++ticks >= length)
return NextActivity; return true;
return this; return false;
} }
public override IEnumerable<Target> GetTargets(Actor self) public override IEnumerable<Target> GetTargets(Actor self)

View File

@@ -45,10 +45,10 @@ namespace OpenRA.Mods.Common.Activities
lastVisibleTarget = Target.FromPos(initialTargetPosition.Value); lastVisibleTarget = Target.FromPos(initialTargetPosition.Value);
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (IsCanceling) if (IsCanceling)
return NextActivity; return true;
bool targetIsHiddenActor; bool targetIsHiddenActor;
target = target.Recalculate(self.Owner, out targetIsHiddenActor); target = target.Recalculate(self.Owner, out targetIsHiddenActor);
@@ -61,7 +61,7 @@ namespace OpenRA.Mods.Common.Activities
// If we are ticking again after previously sequencing a MoveWithRange then that move must have completed // If we are ticking again after previously sequencing a MoveWithRange then that move must have completed
// Either we are in range and can see the target, or we've lost track of it and should give up // Either we are in range and can see the target, or we've lost track of it and should give up
if (wasMovingWithinRange && targetIsHiddenActor) if (wasMovingWithinRange && targetIsHiddenActor)
return NextActivity; return true;
wasMovingWithinRange = false; wasMovingWithinRange = false;
@@ -71,7 +71,7 @@ namespace OpenRA.Mods.Common.Activities
// Target is hidden or dead, and we don't have a fallback position to move towards // Target is hidden or dead, and we don't have a fallback position to move towards
if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self)) if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self))
return NextActivity; return true;
var pos = self.CenterPosition; var pos = self.CenterPosition;
var checkTarget = useLastVisibleTarget ? lastVisibleTarget : target; var checkTarget = useLastVisibleTarget ? lastVisibleTarget : target;
@@ -79,12 +79,12 @@ namespace OpenRA.Mods.Common.Activities
// We've reached the required range - if the target is visible and valid then we wait // We've reached the required range - if the target is visible and valid then we wait
// otherwise if it is hidden or dead we give up // otherwise if it is hidden or dead we give up
if (checkTarget.IsInRange(pos, maxRange) && !checkTarget.IsInRange(pos, minRange)) if (checkTarget.IsInRange(pos, maxRange) && !checkTarget.IsInRange(pos, minRange))
return useLastVisibleTarget ? NextActivity : this; return useLastVisibleTarget;
// Move into range // Move into range
wasMovingWithinRange = true; wasMovingWithinRange = true;
QueueChild(move.MoveWithinRange(target, minRange, maxRange, checkTarget.CenterPosition, targetLineColor)); QueueChild(move.MoveWithinRange(target, minRange, maxRange, checkTarget.CenterPosition, targetLineColor));
return this; return false;
} }
} }
} }

View File

@@ -144,18 +144,18 @@ namespace OpenRA.Mods.Common.Activities
} }
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
// If the actor is inside a tunnel then we must let them move // If the actor is inside a tunnel then we must let them move
// all the way through before moving to the next activity // all the way through before moving to the next activity
if (IsCanceling && self.Location.Layer != CustomMovementLayerType.Tunnel) if (IsCanceling && self.Location.Layer != CustomMovementLayerType.Tunnel)
return NextActivity; return true;
if (mobile.IsTraitDisabled || mobile.IsTraitPaused) if (mobile.IsTraitDisabled || mobile.IsTraitPaused)
return this; return false;
if (destination == mobile.ToCell) if (destination == mobile.ToCell)
return NextActivity; return true;
if (path == null) if (path == null)
path = EvalPath(); path = EvalPath();
@@ -163,22 +163,21 @@ namespace OpenRA.Mods.Common.Activities
if (path.Count == 0) if (path.Count == 0)
{ {
destination = mobile.ToCell; destination = mobile.ToCell;
return this; return false;
} }
destination = path[0]; destination = path[0];
var nextCell = PopPath(self); var nextCell = PopPath(self);
if (nextCell == null) if (nextCell == null)
return this; return false;
var firstFacing = self.World.Map.FacingBetween(mobile.FromCell, nextCell.Value.First, mobile.Facing); var firstFacing = self.World.Map.FacingBetween(mobile.FromCell, nextCell.Value.First, mobile.Facing);
if (firstFacing != mobile.Facing) if (firstFacing != mobile.Facing)
{ {
path.Add(nextCell.Value.First); path.Add(nextCell.Value.First);
QueueChild(new Turn(self, firstFacing)); QueueChild(new Turn(self, firstFacing));
return this; return false;
} }
mobile.SetLocation(mobile.FromCell, mobile.FromSubCell, nextCell.Value.First, nextCell.Value.Second); mobile.SetLocation(mobile.FromCell, mobile.FromSubCell, nextCell.Value.First, nextCell.Value.Second);
@@ -192,7 +191,7 @@ namespace OpenRA.Mods.Common.Activities
(map.Grid.OffsetOfSubCell(mobile.FromSubCell) + map.Grid.OffsetOfSubCell(mobile.ToSubCell)) / 2; (map.Grid.OffsetOfSubCell(mobile.FromSubCell) + map.Grid.OffsetOfSubCell(mobile.ToSubCell)) / 2;
QueueChild(new MoveFirstHalf(this, from, to, mobile.Facing, mobile.Facing, 0)); QueueChild(new MoveFirstHalf(this, from, to, mobile.Facing, mobile.Facing, 0));
return this; return false;
} }
Pair<CPos, SubCell>? PopPath(Actor self) Pair<CPos, SubCell>? PopPath(Actor self)
@@ -309,10 +308,10 @@ namespace OpenRA.Mods.Common.Activities
} }
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (Move.mobile.IsTraitDisabled) if (Move.mobile.IsTraitDisabled)
return this; return false;
var ret = InnerTick(self, Move.mobile); var ret = InnerTick(self, Move.mobile);
@@ -322,10 +321,10 @@ namespace OpenRA.Mods.Common.Activities
UpdateCenterLocation(self, Move.mobile); UpdateCenterLocation(self, Move.mobile);
if (ret == this) if (ret == this)
return ret; return false;
Queue(ret); Queue(ret);
return NextActivity; return true;
} }
Activity InnerTick(Actor self, Mobile mobile) Activity InnerTick(Actor self, Mobile mobile)

View File

@@ -85,7 +85,7 @@ namespace OpenRA.Mods.Common.Activities
QueueChild(Mobile.MoveTo(() => CalculatePathToTarget(self))); QueueChild(Mobile.MoveTo(() => CalculatePathToTarget(self)));
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
bool targetIsHiddenActor; bool targetIsHiddenActor;
var oldTargetLocation = lastVisibleTargetLocation; var oldTargetLocation = lastVisibleTargetLocation;
@@ -119,11 +119,9 @@ namespace OpenRA.Mods.Common.Activities
if (!IsCanceling && shouldRepath) if (!IsCanceling && shouldRepath)
QueueChild(Mobile.MoveTo(() => CalculatePathToTarget(self))); QueueChild(Mobile.MoveTo(() => CalculatePathToTarget(self)));
ChildActivity = ActivityUtils.RunActivity(self, ChildActivity); // The last queued childactivity is guaranteed to be the inner move, so if the childactivity
if (ChildActivity != null) // queue is empty it means we have reached our destination.
return this; return TickChild(self);
return NextActivity;
} }
List<CPos> CalculatePathToTarget(Actor self) List<CPos> CalculatePathToTarget(Actor self)

View File

@@ -35,31 +35,28 @@ namespace OpenRA.Mods.Common.Activities
targetStartPos = target.Positions.PositionClosestTo(self.CenterPosition); targetStartPos = target.Positions.PositionClosestTo(self.CenterPosition);
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (IsCanceling || target.Type == TargetType.Invalid) if (IsCanceling || target.Type == TargetType.Invalid)
return NextActivity; return true;
if (mobile.IsTraitDisabled || mobile.IsTraitPaused) if (mobile.IsTraitDisabled || mobile.IsTraitPaused)
return this; return false;
var currentPos = self.CenterPosition; var currentPos = self.CenterPosition;
var targetPos = target.Positions.PositionClosestTo(currentPos); var targetPos = target.Positions.PositionClosestTo(currentPos);
// Give up if the target has moved too far // Give up if the target has moved too far
if (targetMovementThreshold > WDist.Zero && (targetPos - targetStartPos).LengthSquared > targetMovementThreshold.LengthSquared) if (targetMovementThreshold > WDist.Zero && (targetPos - targetStartPos).LengthSquared > targetMovementThreshold.LengthSquared)
return NextActivity; return true;
// Turn if required // Turn if required
var delta = targetPos - currentPos; var delta = targetPos - currentPos;
var facing = delta.HorizontalLengthSquared != 0 ? delta.Yaw.Facing : mobile.Facing; var facing = delta.HorizontalLengthSquared != 0 ? delta.Yaw.Facing : mobile.Facing;
if (facing != mobile.Facing) if (facing != mobile.Facing)
{ {
var turn = ActivityUtils.RunActivity(self, new Turn(self, facing)); QueueChild(new Turn(self, facing));
if (turn != null) return false;
QueueChild(turn);
return this;
} }
// Can complete the move in this step // Can complete the move in this step
@@ -67,13 +64,12 @@ namespace OpenRA.Mods.Common.Activities
if (delta.LengthSquared <= speed * speed) if (delta.LengthSquared <= speed * speed)
{ {
mobile.SetVisualPosition(self, targetPos); mobile.SetVisualPosition(self, targetPos);
return NextActivity; return true;
} }
// Move towards the target // Move towards the target
mobile.SetVisualPosition(self, currentPos + delta * speed / delta.Length); mobile.SetVisualPosition(self, currentPos + delta * speed / delta.Length);
return false;
return this;
} }
public override IEnumerable<Target> GetTargets(Actor self) public override IEnumerable<Target> GetTargets(Actor self)

View File

@@ -39,15 +39,15 @@ namespace OpenRA.Mods.Common.Activities
np.OnParachute(self); np.OnParachute(self);
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
var nextPosition = self.CenterPosition - fallVector; var nextPosition = self.CenterPosition - fallVector;
if (nextPosition.Z < groundLevel) if (nextPosition.Z < groundLevel)
return NextActivity; return true;
pos.SetVisualPosition(self, nextPosition); pos.SetVisualPosition(self, nextPosition);
return this; return false;
} }
protected override void OnLastRun(Actor self) protected override void OnLastRun(Actor self)

View File

@@ -54,41 +54,41 @@ namespace OpenRA.Mods.Common.Activities
carryall.ReserveCarryable(self, cargo); carryall.ReserveCarryable(self, cargo);
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (cargo != carryall.Carryable) if (cargo != carryall.Carryable)
return NextActivity; return true;
if (IsCanceling) if (IsCanceling)
{ {
if (carryall.State == Carryall.CarryallState.Reserved) if (carryall.State == Carryall.CarryallState.Reserved)
carryall.UnreserveCarryable(self); carryall.UnreserveCarryable(self);
return NextActivity; return true;
} }
if (cargo.IsDead || carryable.IsTraitDisabled || !cargo.AppearsFriendlyTo(self)) if (cargo.IsDead || carryable.IsTraitDisabled || !cargo.AppearsFriendlyTo(self))
{ {
carryall.UnreserveCarryable(self); carryall.UnreserveCarryable(self);
return NextActivity; return true;
} }
if (carryall.State != Carryall.CarryallState.Reserved) if (carryall.State != Carryall.CarryallState.Reserved)
return NextActivity; return true;
switch (state) switch (state)
{ {
case PickupState.Intercept: case PickupState.Intercept:
QueueChild(movement.MoveWithinRange(Target.FromActor(cargo), WDist.FromCells(4), targetLineColor: Color.Yellow)); QueueChild(movement.MoveWithinRange(Target.FromActor(cargo), WDist.FromCells(4), targetLineColor: Color.Yellow));
state = PickupState.LockCarryable; state = PickupState.LockCarryable;
return this; return false;
case PickupState.LockCarryable: case PickupState.LockCarryable:
if (!carryable.LockForPickup(cargo, self)) if (!carryable.LockForPickup(cargo, self))
Cancel(self); Cancel(self);
state = PickupState.Pickup; state = PickupState.Pickup;
return this; return false;
case PickupState.Pickup: case PickupState.Pickup:
{ {
@@ -103,11 +103,11 @@ namespace OpenRA.Mods.Common.Activities
// Remove our carryable from world // Remove our carryable from world
QueueChild(new CallFunc(() => Attach(self))); QueueChild(new CallFunc(() => Attach(self)));
QueueChild(new TakeOff(self)); QueueChild(new TakeOff(self));
return this; return false;
} }
} }
return NextActivity; return true;
} }
void Attach(Actor self) void Attach(Actor self)

View File

@@ -15,11 +15,12 @@ namespace OpenRA.Mods.Common.Activities
{ {
public class RemoveSelf : Activity public class RemoveSelf : Activity
{ {
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (IsCanceling) return NextActivity; if (IsCanceling) return true;
self.Dispose(); self.Dispose();
return null; Cancel(self);
return true;
} }
} }
} }

View File

@@ -73,7 +73,7 @@ namespace OpenRA.Mods.Common.Activities
pool.RemainingTicks = pool.Info.ReloadDelay; pool.RemainingTicks = pool.Info.ReloadDelay;
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
// HACK: If the activity is cancelled while we're already resupplying (or about to start resupplying), // HACK: If the activity is cancelled while we're already resupplying (or about to start resupplying),
// move actor outside the resupplier footprint // move actor outside the resupplier footprint
@@ -84,7 +84,7 @@ namespace OpenRA.Mods.Common.Activities
foreach (var notifyResupply in notifyResupplies) foreach (var notifyResupply in notifyResupplies)
notifyResupply.ResupplyTick(host.Actor, self, ResupplyType.None); notifyResupply.ResupplyTick(host.Actor, self, ResupplyType.None);
return this; return false;
} }
if (IsCanceling || host.Type == TargetType.Invalid if (IsCanceling || host.Type == TargetType.Invalid
@@ -94,7 +94,7 @@ namespace OpenRA.Mods.Common.Activities
foreach (var notifyResupply in notifyResupplies) foreach (var notifyResupply in notifyResupplies)
notifyResupply.ResupplyTick(host.Actor, self, ResupplyType.None); notifyResupply.ResupplyTick(host.Actor, self, ResupplyType.None);
return NextActivity; return true;
} }
if (activeResupplyTypes.HasFlag(ResupplyType.Repair)) if (activeResupplyTypes.HasFlag(ResupplyType.Repair))
@@ -112,10 +112,10 @@ namespace OpenRA.Mods.Common.Activities
if (aircraft != null) if (aircraft != null)
aircraft.AllowYieldingReservation(); aircraft.AllowYieldingReservation();
return NextActivity; return true;
} }
return this; return false;
} }
public override void Cancel(Actor self, bool keepQueue = false) public override void Cancel(Actor self, bool keepQueue = false)

View File

@@ -32,7 +32,7 @@ namespace OpenRA.Mods.Common.Activities
IsInterruptible = false; IsInterruptible = false;
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
var sellValue = self.GetSellValue(); var sellValue = self.GetSellValue();
@@ -49,7 +49,7 @@ namespace OpenRA.Mods.Common.Activities
self.World.AddFrameEndTask(w => w.Add(new FloatingText(self.CenterPosition, self.Owner.Color, FloatingText.FormatCashTick(refund), 30))); self.World.AddFrameEndTask(w => w.Add(new FloatingText(self.CenterPosition, self.Owner.Color, FloatingText.FormatCashTick(refund), 30)));
self.Dispose(); self.Dispose();
return this; return false;
} }
} }
} }

View File

@@ -20,11 +20,11 @@ namespace OpenRA.Mods.Common.Activities
public SimpleTeleport(CPos destination) { this.destination = destination; } public SimpleTeleport(CPos destination) { this.destination = destination; }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
self.Trait<IPositionable>().SetPosition(self, destination); self.Trait<IPositionable>().SetPosition(self, destination);
self.Generation++; self.Generation++;
return NextActivity; return true;
} }
} }
} }

View File

@@ -27,17 +27,16 @@ namespace OpenRA.Mods.Common.Activities
wda = self.Info.TraitInfo<WithDockingAnimationInfo>(); wda = self.Info.TraitInfo<WithDockingAnimationInfo>();
} }
public override Activity OnStateDock(Actor self) public override void OnStateDock(Actor self)
{ {
foreach (var trait in self.TraitsImplementing<INotifyHarvesterAction>()) foreach (var trait in self.TraitsImplementing<INotifyHarvesterAction>())
trait.Docked(); trait.Docked();
wsb.PlayCustomAnimation(self, wda.DockSequence, () => wsb.PlayCustomAnimationRepeating(self, wda.DockLoopSequence)); wsb.PlayCustomAnimation(self, wda.DockSequence, () => wsb.PlayCustomAnimationRepeating(self, wda.DockLoopSequence));
dockingState = DockingState.Loop; dockingState = DockingState.Loop;
return this;
} }
public override Activity OnStateUndock(Actor self) public override void OnStateUndock(Actor self)
{ {
wsb.PlayCustomAnimationBackwards(self, wda.DockSequence, wsb.PlayCustomAnimationBackwards(self, wda.DockSequence,
() => () =>
@@ -47,8 +46,6 @@ namespace OpenRA.Mods.Common.Activities
trait.Undocked(); trait.Undocked();
}); });
dockingState = DockingState.Wait; dockingState = DockingState.Wait;
return this;
} }
} }
} }

View File

@@ -43,17 +43,17 @@ namespace OpenRA.Mods.Common.Activities
QueueChild(new Land(self)); QueueChild(new Land(self));
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (IsCanceling) if (IsCanceling)
return NextActivity; return true;
// Prevent deployment in bogus locations // Prevent deployment in bogus locations
var transforms = self.TraitOrDefault<Transforms>(); var transforms = self.TraitOrDefault<Transforms>();
if (transforms != null && !transforms.CanDeploy()) if (transforms != null && !transforms.CanDeploy())
{ {
Cancel(self, true); Cancel(self, true);
return NextActivity; return true;
} }
foreach (var nt in self.TraitsImplementing<INotifyTransform>()) foreach (var nt in self.TraitsImplementing<INotifyTransform>())
@@ -68,10 +68,10 @@ namespace OpenRA.Mods.Common.Activities
// Wait forever // Wait forever
QueueChild(new WaitFor(() => false)); QueueChild(new WaitFor(() => false));
makeAnimation.Reverse(self, () => DoTransform(self)); makeAnimation.Reverse(self, () => DoTransform(self));
return this; return false;
} }
return NextActivity; return true;
} }
protected override void OnLastRun(Actor self) protected override void OnLastRun(Actor self)

View File

@@ -28,20 +28,20 @@ namespace OpenRA.Mods.Common.Activities
this.desiredFacing = desiredFacing; this.desiredFacing = desiredFacing;
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (IsCanceling) if (IsCanceling)
return NextActivity; return true;
if (mobile != null && (mobile.IsTraitDisabled || mobile.IsTraitPaused)) if (mobile != null && (mobile.IsTraitDisabled || mobile.IsTraitPaused))
return this; return false;
if (desiredFacing == facing.Facing) if (desiredFacing == facing.Facing)
return NextActivity; return true;
facing.Facing = Util.TickFacing(facing.Facing, desiredFacing, facing.TurnSpeed); facing.Facing = Util.TickFacing(facing.Facing, desiredFacing, facing.TurnSpeed);
return this; return false;
} }
} }
} }

View File

@@ -89,10 +89,10 @@ namespace OpenRA.Mods.Common.Activities
QueueChild(new Wait(cargo.Info.BeforeUnloadDelay)); QueueChild(new Wait(cargo.Info.BeforeUnloadDelay));
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (IsCanceling || cargo.IsEmpty(self)) if (IsCanceling || cargo.IsEmpty(self))
return NextActivity; return true;
if (cargo.CanUnload()) if (cargo.CanUnload())
{ {
@@ -107,7 +107,7 @@ namespace OpenRA.Mods.Common.Activities
{ {
self.NotifyBlocker(BlockedExitCells(actor)); self.NotifyBlocker(BlockedExitCells(actor));
QueueChild(new Wait(10)); QueueChild(new Wait(10));
return this; return false;
} }
cargo.Unload(self); cargo.Unload(self);
@@ -130,6 +130,7 @@ namespace OpenRA.Mods.Common.Activities
if (!unloadAll || !cargo.CanUnload()) if (!unloadAll || !cargo.CanUnload())
{ {
Cancel(self, true); Cancel(self, true);
if (cargo.Info.AfterUnloadDelay > 0) if (cargo.Info.AfterUnloadDelay > 0)
QueueChild(new Wait(cargo.Info.AfterUnloadDelay, false)); QueueChild(new Wait(cargo.Info.AfterUnloadDelay, false));
@@ -137,7 +138,7 @@ namespace OpenRA.Mods.Common.Activities
QueueChild(new TakeOff(self)); QueueChild(new TakeOff(self));
} }
return this; return false;
} }
} }
} }

View File

@@ -25,12 +25,12 @@ namespace OpenRA.Mods.Common.Activities
IsInterruptible = interruptible; IsInterruptible = interruptible;
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (IsCanceling) if (IsCanceling)
return NextActivity; return true;
return (remainingTicks-- == 0) ? NextActivity : this; return remainingTicks-- == 0;
} }
} }
@@ -45,12 +45,12 @@ namespace OpenRA.Mods.Common.Activities
IsInterruptible = interruptible; IsInterruptible = interruptible;
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (IsCanceling) if (IsCanceling)
return NextActivity; return true;
return (f == null || f()) ? NextActivity : this; return f == null || f();
} }
} }
} }

View File

@@ -30,12 +30,12 @@ namespace OpenRA.Mods.Common.Activities
QueueChild(inner); QueueChild(inner);
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (transportable != null) if (transportable != null)
transportable.MovementCancelled(self); transportable.MovementCancelled(self);
return NextActivity; return true;
} }
} }
} }

View File

@@ -27,7 +27,7 @@ namespace OpenRA.Mods.Common.Activities
this.context = context; this.context = context;
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
try try
{ {
@@ -40,7 +40,7 @@ namespace OpenRA.Mods.Common.Activities
} }
Dispose(); Dispose();
return NextActivity; return true;
} }
public override void Cancel(Actor self, bool keepQueue = false) public override void Cancel(Actor self, bool keepQueue = false)

View File

@@ -255,22 +255,22 @@ namespace OpenRA.Mods.Common.Traits
} }
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
if (IsCanceling) if (IsCanceling)
{ {
// Cancel the requested target, but keep firing on it while in range // Cancel the requested target, but keep firing on it while in range
attack.ClearRequestedTarget(); attack.ClearRequestedTarget();
return NextActivity; return true;
} }
// Check that AttackFollow hasn't cancelled the target by modifying attack.Target // Check that AttackFollow hasn't cancelled the target by modifying attack.Target
// Having both this and AttackFollow modify that field is a horrible hack. // Having both this and AttackFollow modify that field is a horrible hack.
if (hasTicked && attack.RequestedTarget.Type == TargetType.Invalid) if (hasTicked && attack.RequestedTarget.Type == TargetType.Invalid)
return NextActivity; return true;
if (attack.IsTraitPaused) if (attack.IsTraitPaused)
return this; return false;
bool targetIsHiddenActor; bool targetIsHiddenActor;
target = target.Recalculate(self.Owner, out targetIsHiddenActor); target = target.Recalculate(self.Owner, out targetIsHiddenActor);
@@ -317,7 +317,7 @@ namespace OpenRA.Mods.Common.Traits
if (wasMovingWithinRange && targetIsHiddenActor) if (wasMovingWithinRange && targetIsHiddenActor)
{ {
attack.ClearRequestedTarget(); attack.ClearRequestedTarget();
return NextActivity; return true;
} }
// Update target lines if required // Update target lines if required
@@ -328,7 +328,7 @@ namespace OpenRA.Mods.Common.Traits
if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self)) if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self))
{ {
attack.ClearRequestedTarget(); attack.ClearRequestedTarget();
return NextActivity; return true;
} }
var pos = self.CenterPosition; var pos = self.CenterPosition;
@@ -341,22 +341,22 @@ namespace OpenRA.Mods.Common.Traits
if (useLastVisibleTarget) if (useLastVisibleTarget)
{ {
attack.ClearRequestedTarget(); attack.ClearRequestedTarget();
return NextActivity; return true;
} }
return this; return false;
} }
// We can't move into range, so give up // We can't move into range, so give up
if (move == null || maxRange == WDist.Zero || maxRange < minRange) if (move == null || maxRange == WDist.Zero || maxRange < minRange)
{ {
attack.ClearRequestedTarget(); attack.ClearRequestedTarget();
return NextActivity; return true;
} }
wasMovingWithinRange = true; wasMovingWithinRange = true;
QueueChild(move.MoveWithinRange(target, minRange, maxRange, checkTarget.CenterPosition, Color.Red)); QueueChild(move.MoveWithinRange(target, minRange, maxRange, checkTarget.CenterPosition, Color.Red));
return this; return false;
} }
void IActivityNotifyStanceChanged.StanceChanged(Actor self, AutoTarget autoTarget, UnitStance oldStance, UnitStance newStance) void IActivityNotifyStanceChanged.StanceChanged(Actor self, AutoTarget autoTarget, UnitStance oldStance, UnitStance newStance)

View File

@@ -46,16 +46,16 @@ namespace OpenRA.Mods.Common.Traits
this.forceAttack = forceAttack; this.forceAttack = forceAttack;
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
// This activity can't move to reacquire hidden targets, so use the // This activity can't move to reacquire hidden targets, so use the
// Recalculate overload that invalidates hidden targets. // Recalculate overload that invalidates hidden targets.
target = target.RecalculateInvalidatingHiddenTargets(self.Owner); target = target.RecalculateInvalidatingHiddenTargets(self.Owner);
if (IsCanceling || !target.IsValidFor(self) || !attack.IsReachableTarget(target, allowMove)) if (IsCanceling || !target.IsValidFor(self) || !attack.IsReachableTarget(target, allowMove))
return NextActivity; return true;
attack.DoAttack(self, target); attack.DoAttack(self, target);
return this; return false;
} }
void IActivityNotifyStanceChanged.StanceChanged(Actor self, AutoTarget autoTarget, UnitStance oldStance, UnitStance newStance) void IActivityNotifyStanceChanged.StanceChanged(Actor self, AutoTarget autoTarget, UnitStance oldStance, UnitStance newStance)

View File

@@ -95,7 +95,7 @@ namespace OpenRA.Mods.D2k.Activities
return true; return true;
} }
public override Activity Tick(Actor self) public override bool Tick(Actor self)
{ {
switch (stance) switch (stance)
{ {
@@ -109,7 +109,7 @@ namespace OpenRA.Mods.D2k.Activities
break; break;
case AttackState.Burrowed: case AttackState.Burrowed:
if (--countdown > 0) if (--countdown > 0)
return this; return false;
var targetLocation = target.Actor.Location; var targetLocation = target.Actor.Location;
@@ -117,14 +117,14 @@ namespace OpenRA.Mods.D2k.Activities
if ((burrowLocation - targetLocation).Length > NearEnough) if ((burrowLocation - targetLocation).Length > NearEnough)
{ {
RevokeCondition(self); RevokeCondition(self);
return NextActivity; return true;
} }
// The target reached solid ground // The target reached solid ground
if (!positionable.CanEnterCell(targetLocation, null, false)) if (!positionable.CanEnterCell(targetLocation, null, false))
{ {
RevokeCondition(self); RevokeCondition(self);
return NextActivity; return true;
} }
var targets = self.World.ActorMap.GetActorsAt(targetLocation) var targets = self.World.ActorMap.GetActorsAt(targetLocation)
@@ -133,7 +133,7 @@ namespace OpenRA.Mods.D2k.Activities
if (!targets.Any()) if (!targets.Any())
{ {
RevokeCondition(self); RevokeCondition(self);
return NextActivity; return true;
} }
stance = AttackState.Attacking; stance = AttackState.Attacking;
@@ -144,7 +144,7 @@ namespace OpenRA.Mods.D2k.Activities
break; break;
case AttackState.Attacking: case AttackState.Attacking:
if (--countdown > 0) if (--countdown > 0)
return this; return false;
sandworm.IsAttacking = false; sandworm.IsAttacking = false;
@@ -156,10 +156,10 @@ namespace OpenRA.Mods.D2k.Activities
} }
RevokeCondition(self); RevokeCondition(self);
return NextActivity; return true;
} }
return this; return false;
} }
void RevokeCondition(Actor self) void RevokeCondition(Actor self)