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:
*
* - Use "return NextActivity" 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.
* - Use "return true" at least once somewhere in the tick method.
* - Do not "reuse" (with "SequenceActivities", for example) activity objects that have already started running.
* Queue a new instance 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; }
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 ChildHasPriority { get; protected set; }
public bool IsCanceling { get { return State == ActivityState.Canceling; } }
bool finishing;
bool lastRun;
public Activity()
{
@@ -55,33 +56,60 @@ namespace OpenRA.Activities
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)
{
ChildActivity = ActivityUtils.RunActivity(self, ChildActivity);
if (ChildActivity != null)
return this;
lastRun = TickChild(self) && (finishing || Tick(self));
finishing |= lastRun;
}
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)
ChildActivity = ActivityUtils.RunActivity(self, ChildActivity);
{
if (ChildHasPriority)
lastRun = TickChild(self) && finishing;
else
TickChild(self);
}
if (ret != this)
if (lastRun)
{
State = ActivityState.Done;
OnLastRun(self);
return NextActivity;
}
return ret;
return this;
}
protected bool TickChild(Actor self)
{
ChildActivity = ActivityUtils.RunActivity(self, ChildActivity);
return ChildActivity == null;
}
/// <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>
public virtual Activity Tick(Actor self)
public virtual bool Tick(Actor self)
{
return NextActivity;
return true;
}
/// <summary>

View File

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

View File

@@ -37,10 +37,10 @@ namespace OpenRA.Mods.Cnc.Activities
this.minefield = minefield;
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
if (IsCanceling)
return NextActivity;
return true;
if (rearmableInfo != null && ammoPools.Any(p => p.Info.Name == info.AmmoPoolName && !p.HasAmmo()))
{
@@ -50,20 +50,20 @@ namespace OpenRA.Mods.Cnc.Activities
.ClosestTo(self);
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
QueueChild(new MoveAdjacentTo(self, Target.FromActor(rearmTarget)));
QueueChild(movement.MoveTo(self.World.Map.CellContaining(rearmTarget.CenterPosition), rearmTarget));
QueueChild(new Resupply(self, rearmTarget, new WDist(512)));
return this;
return false;
}
if ((minefield == null || minefield.Contains(self.Location)) && ShouldLayMine(self, self.Location))
{
LayMine(self);
QueueChild(new Wait(20)); // A little wait after placing each mine, for show
return this;
return false;
}
if (minefield != null && minefield.Length > 0)
@@ -75,13 +75,13 @@ namespace OpenRA.Mods.Cnc.Activities
if (ShouldLayMine(self, p))
{
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.
return NextActivity;
return true;
}
static bool ShouldLayMine(Actor self, CPos p)

View File

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

View File

@@ -72,10 +72,10 @@ namespace OpenRA.Mods.Cnc.Activities
attack.IsAiming = true;
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
if (IsCanceling)
return NextActivity;
return true;
bool 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
if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self))
return NextActivity;
return true;
var pos = self.CenterPosition;
var checkTarget = useLastVisibleTarget ? lastVisibleTarget : target;
@@ -105,27 +105,27 @@ namespace OpenRA.Mods.Cnc.Activities
if (!checkTarget.IsInRange(pos, lastVisibleMaxRange) || checkTarget.IsInRange(pos, lastVisibleMinRange))
{
if (!allowMovement || lastVisibleMaxRange == WDist.Zero || lastVisibleMaxRange < lastVisibleMinRange)
return NextActivity;
return true;
QueueChild(mobile.MoveWithinRange(target, lastVisibleMinRange, lastVisibleMaxRange, checkTarget.CenterPosition, Color.Red));
return this;
return false;
}
// Ready to leap, but target isn't visible
if (targetIsHiddenActor || target.Type != TargetType.Actor)
return NextActivity;
return true;
// Target is not valid
if (!target.IsValidFor(self) || !attack.HasAnyValidWeapons(target))
return NextActivity;
return true;
var edible = target.Actor.TraitOrDefault<EdibleByLeap>();
if (edible == null || !edible.CanLeap(self))
return NextActivity;
return true;
// Can't leap yet
if (attack.Armaments.All(a => a.IsReloading))
return this;
return false;
// Use CenterOfSubCell with ToSubCell instead of target.Centerposition
// to avoid continuous facing adjustments as the target moves
@@ -138,13 +138,13 @@ namespace OpenRA.Mods.Cnc.Activities
if (mobile.Facing != desiredFacing)
{
QueueChild(new Turn(self, desiredFacing));
return this;
return false;
}
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
return this;
return false;
}
protected override void OnLastRun(Actor self)

View File

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

View File

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

View File

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

View File

@@ -94,13 +94,13 @@ namespace OpenRA.Mods.Cnc.Traits
this.forceAttack = forceAttack;
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
if (IsCanceling || !attack.CanAttack(self, target))
return NextActivity;
return true;
if (attack.charges == 0)
return this;
return false;
foreach (var notify in self.TraitsImplementing<INotifyTeslaCharging>())
notify.Charging(self, target);
@@ -110,7 +110,7 @@ namespace OpenRA.Mods.Cnc.Traits
QueueChild(new Wait(attack.info.InitialChargeDelay));
QueueChild(new ChargeFire(attack, target));
return this;
return false;
}
void IActivityNotifyStanceChanged.StanceChanged(Actor self, AutoTarget autoTarget, UnitStance oldStance, UnitStance newStance)
@@ -145,18 +145,18 @@ namespace OpenRA.Mods.Cnc.Traits
this.target = target;
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
if (IsCanceling || !attack.CanAttack(self, target))
return NextActivity;
return true;
if (attack.charges == 0)
return NextActivity;
return true;
attack.DoAttack(self, target);
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;
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
if (self.World.Map.DistanceAboveTerrain(self.CenterPosition).Length <= 0)
{
@@ -43,7 +43,8 @@ namespace OpenRA.Mods.Common.Activities
}
self.Kill(self);
return null;
Cancel(self);
return true;
}
if (info.Spins)
@@ -56,7 +57,7 @@ namespace OpenRA.Mods.Common.Activities
move -= new WVec(WDist.Zero, WDist.Zero, info.Velocity);
aircraft.SetPosition(self, aircraft.CenterPosition + move);
return this;
return false;
}
}
}

View File

@@ -100,7 +100,7 @@ namespace OpenRA.Mods.Common.Activities
return true;
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
// Refuse to take off if it would land immediately again.
if (aircraft.ForceLanding)
@@ -122,15 +122,15 @@ namespace OpenRA.Mods.Common.Activities
else
VerticalTakeOffOrLandTick(self, aircraft, aircraft.Facing, aircraft.Info.CruiseAltitude);
return this;
return false;
}
return NextActivity;
return true;
}
else if (dat <= aircraft.LandAltitude)
{
QueueChild(new TakeOff(self, target));
return this;
return false;
}
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
if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self))
return NextActivity;
return true;
var checkTarget = useLastVisibleTarget ? lastVisibleTarget : target;
var pos = aircraft.GetPosition();
@@ -158,7 +158,7 @@ namespace OpenRA.Mods.Common.Activities
var insideMaxRange = maxRange.Length > 0 && checkTarget.IsInRange(pos, maxRange);
var insideMinRange = minRange.Length > 0 && checkTarget.IsInRange(pos, minRange);
if (insideMaxRange && !insideMinRange)
return NextActivity;
return true;
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)
{
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
@@ -186,11 +186,11 @@ namespace OpenRA.Mods.Common.Activities
if (dat != aircraft.Info.CruiseAltitude)
{
Fly.VerticalTakeOffOrLandTick(self, aircraft, aircraft.Facing, aircraft.Info.CruiseAltitude);
return this;
return false;
}
}
return NextActivity;
return true;
}
if (!aircraft.Info.CanHover)
@@ -216,7 +216,7 @@ namespace OpenRA.Mods.Common.Activities
FlyTick(self, aircraft, desiredFacing, aircraft.Info.CruiseAltitude);
return this;
return false;
}
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.
if (aircraft.ForceLanding)
@@ -73,16 +73,16 @@ namespace OpenRA.Mods.Common.Activities
{
// Cancel the requested target, but keep firing on it while in range
attackAircraft.ClearRequestedTarget();
return NextActivity;
return true;
}
// Check that AttackFollow hasn't cancelled the target by modifying attack.Target
// Having both this and AttackFollow modify that field is a horrible hack.
if (hasTicked && attackAircraft.RequestedTarget.Type == TargetType.Invalid)
return NextActivity;
return true;
if (attackAircraft.IsTraitPaused)
return this;
return false;
bool targetIsHiddenActor;
target = target.Recalculate(self.Owner, out targetIsHiddenActor);
@@ -108,14 +108,14 @@ namespace OpenRA.Mods.Common.Activities
if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self))
{
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 (rearmable != null && !useLastVisibleTarget && attackAircraft.Armaments.All(x => x.IsTraitPaused || !x.Weapon.IsValidAgainst(target, self.World, self)))
{
QueueChild(new ReturnToBase(self, aircraft.Info.AbortOnResupply));
return this;
return false;
}
var pos = self.CenterPosition;
@@ -128,12 +128,12 @@ namespace OpenRA.Mods.Common.Activities
if (checkTarget.IsInRange(pos, lastVisibleMaximumRange))
{
attackAircraft.ClearRequestedTarget();
return NextActivity;
return true;
}
// Fly towards the last known position
QueueChild(new Fly(self, target, WDist.Zero, lastVisibleMaximumRange, checkTarget.CenterPosition, Color.Red));
return this;
return false;
}
var delta = attackAircraft.GetTargetPosition(pos, target) - pos;
@@ -160,7 +160,7 @@ namespace OpenRA.Mods.Common.Activities
Fly.VerticalTakeOffOrLandTick(self, aircraft, desiredFacing, aircraft.Info.CruiseAltitude);
}
return this;
return false;
}
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;
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
if (remainingTicks == 0 || (NextActivity != null && remainingTicks < 0))
return NextActivity;
return true;
// Refuse to take off if it would land immediately again.
if (aircraft.ForceLanding)
{
Cancel(self);
return NextActivity;
return true;
}
if (IsCanceling)
return NextActivity;
return true;
if (remainingTicks > 0)
remainingTicks--;
@@ -53,7 +53,7 @@ namespace OpenRA.Mods.Common.Activities
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);
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
// Refuse to take off if it would land immediately again.
if (aircraft.ForceLanding)
Cancel(self);
if (IsCanceling)
return NextActivity;
return true;
bool 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
// Either we are in range and can see the target, or we've lost track of it and should give up
if (wasMovingWithinRange && targetIsHiddenActor)
return NextActivity;
return true;
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
if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self))
return NextActivity;
return true;
var pos = self.CenterPosition;
var checkTarget = useLastVisibleTarget ? lastVisibleTarget : target;
@@ -85,12 +85,12 @@ namespace OpenRA.Mods.Common.Activities
if (checkTarget.IsInRange(pos, maxRange) && !checkTarget.IsInRange(pos, minRange))
{
Fly.FlyTick(self, aircraft, aircraft.Facing, aircraft.Info.CruiseAltitude);
return useLastVisibleTarget ? NextActivity : this;
return useLastVisibleTarget;
}
wasMovingWithinRange = true;
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>();
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
// Refuse to take off if it would land immediately again.
if (aircraft.ForceLanding)
{
Cancel(self);
return NextActivity;
return true;
}
if (IsCanceling || !self.World.Map.Contains(self.Location))
return NextActivity;
return true;
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;
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
// Refuse to take off if it would land immediately again.
if (aircraft.ForceLanding)
{
Cancel(self);
return NextActivity;
return true;
}
if (IsCanceling || remainingTicks-- == 0)
return NextActivity;
return true;
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);
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
if (IsCanceling || target.Type == TargetType.Invalid)
{
@@ -88,15 +88,15 @@ namespace OpenRA.Mods.Common.Activities
if (dat > aircraft.LandAltitude && dat < aircraft.Info.CruiseAltitude)
{
QueueChild(new TakeOff(self));
return this;
return false;
}
aircraft.RemoveInfluence();
return NextActivity;
return true;
}
}
else
return NextActivity;
return true;
}
var pos = aircraft.GetPosition();
@@ -107,7 +107,7 @@ namespace OpenRA.Mods.Common.Activities
// We are already at the landing location.
if ((targetPosition - pos).LengthSquared == 0)
return NextActivity;
return true;
// Look for free landing cell
if (target.Type == TargetType.Terrain && !landingInitiated)
@@ -119,7 +119,7 @@ namespace OpenRA.Mods.Common.Activities
{
Cancel(self, true);
QueueChild(aircraft.MoveTo(landingCell, 0));
return this;
return false;
}
if (newLocation.Value != landingCell)
@@ -138,7 +138,7 @@ namespace OpenRA.Mods.Common.Activities
if (desiredFacing != -1)
QueueChild(new Turn(self, desiredFacing));
return this;
return false;
}
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
QueueChild(new Fly(self, Target.FromPos(w3), WDist.Zero, new WDist(turnRadius / 2)));
finishedApproach = true;
return this;
return false;
}
if (!landingInitiated)
@@ -215,7 +215,7 @@ namespace OpenRA.Mods.Common.Activities
self.NotifyBlocker(blockingCells);
finishedApproach = false;
return this;
return false;
}
if (aircraft.Info.LandingSounds.Length > 0)
@@ -231,9 +231,9 @@ namespace OpenRA.Mods.Common.Activities
{
var landAltitude = self.World.Map.DistanceAboveTerrain(targetPosition) + aircraft.LandAltitude;
if (Fly.VerticalTakeOffOrLandTick(self, aircraft, aircraft.Facing, landAltitude))
return this;
return false;
return NextActivity;
return true;
}
var d = targetPosition - pos;
@@ -244,13 +244,13 @@ namespace OpenRA.Mods.Common.Activities
{
var landingAltVec = new WVec(WDist.Zero, WDist.Zero, aircraft.LandAltitude);
aircraft.SetPosition(self, targetPosition + landingAltVec);
return NextActivity;
return true;
}
var landingAlt = self.World.Map.DistanceAboveTerrain(targetPosition) + aircraft.LandAltitude;
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());
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
// Refuse to take off if it would land immediately again.
// Special case: Don't kill other deploy hotkey activities.
if (aircraft.ForceLanding)
return NextActivity;
return true;
// 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
@@ -84,7 +84,7 @@ namespace OpenRA.Mods.Common.Activities
self.CancelActivity();
if (resupplied || IsCanceling || self.IsDead)
return NextActivity;
return true;
if (dest == null || dest.IsDead || !Reservable.IsAvailableFor(dest, self))
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));
}
return this;
return false;
}
QueueChild(new Fly(self, Target.FromActor(nearestResupplier), WDist.Zero, aircraft.Info.WaitDistanceFromResupplyBase, targetLineColor: Color.Green));
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.
self.CancelActivity();
return NextActivity;
return true;
}
if (ShouldLandAtBuilding(self, dest))
@@ -141,7 +141,7 @@ namespace OpenRA.Mods.Common.Activities
QueueChild(new Fly(self, Target.FromActor(dest)));
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);
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
// Refuse to take off if it would land immediately again.
if (aircraft.ForceLanding)
{
Cancel(self);
return NextActivity;
return true;
}
var dat = self.World.Map.DistanceAboveTerrain(aircraft.CenterPosition);
@@ -78,12 +78,12 @@ namespace OpenRA.Mods.Common.Activities
if (aircraft.Info.VTOL)
{
Fly.VerticalTakeOffOrLandTick(self, aircraft, aircraft.Facing, aircraft.Info.CruiseAltitude);
return this;
return false;
}
else
{
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 (!aircraft.Info.VTOL && assignTargetOnFirstRun)
return NextActivity;
return true;
QueueChild(new AttackMoveActivity(self, () => move.MoveToTarget(self, target)));
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);
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
if (IsCanceling)
return NextActivity;
return true;
bool 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
// Either we are in range and can see the target, or we've lost track of it and should give up
if (wasMovingWithinRange && targetIsHiddenActor)
return NextActivity;
return true;
// Update target lines if required
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
if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self))
return NextActivity;
return true;
wasMovingWithinRange = false;
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
if (checkTarget.IsInRange(pos, lastVisibleMaximumRange) || move == null || lastVisibleMaximumRange == WDist.Zero)
return NextActivity;
return true;
// Move towards the last known position
wasMovingWithinRange = true;
QueueChild(move.MoveWithinRange(target, WDist.Zero, lastVisibleMaximumRange, checkTarget.CenterPosition, Color.Red));
return this;
return false;
}
attackStatus = AttackStatus.UnableToAttack;
@@ -145,9 +145,9 @@ namespace OpenRA.Mods.Common.Activities
wasMovingWithinRange = true;
if (attackStatus >= AttackStatus.NeedsToTurn)
return this;
return false;
return NextActivity;
return true;
}
protected virtual AttackStatus TickAttack(Actor self, AttackFrontal attack)

View File

@@ -37,10 +37,10 @@ namespace OpenRA.Mods.Common.Activities
harv.LinkProc(self, targetActor);
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
if (IsCanceling || isDocking)
return NextActivity;
return true;
// Find the nearest best refinery if not explicitly ordered to a specific refinery:
if (harv.LinkedProc == null || !harv.LinkedProc.IsInWorld)
@@ -50,7 +50,7 @@ namespace OpenRA.Mods.Common.Activities
if (harv.LinkedProc == null)
{
QueueChild(new Wait(harv.Info.SearchForDeliveryBuildingDelay));
return this;
return false;
}
var proc = harv.LinkedProc;
@@ -63,7 +63,7 @@ namespace OpenRA.Mods.Common.Activities
n.MovingToRefinery(self, proc, new FindAndDeliverResources(self));
QueueChild(movement.MoveTo(proc.Location + iao.DeliveryOffset, 0));
return this;
return false;
}
if (!isDocking)
@@ -71,10 +71,10 @@ namespace OpenRA.Mods.Common.Activities
QueueChild(new Wait(10));
isDocking = true;
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));
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
if (IsCanceling || initiated || (deploy.DeployState != DeployState.Deployed && moving))
return NextActivity;
return true;
QueueChild(new DeployInner(self, deploy));
initiated = true;
return this;
return false;
}
}
@@ -61,14 +61,14 @@ namespace OpenRA.Mods.Common.Activities
IsInterruptible = false;
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
// Wait for deployment
if (deployment.DeployState == DeployState.Deploying || deployment.DeployState == DeployState.Undeploying)
return this;
return false;
if (initiated)
return NextActivity;
return true;
if (deployment.DeployState == DeployState.Undeployed)
deployment.Deploy();
@@ -76,7 +76,7 @@ namespace OpenRA.Mods.Common.Activities
deployment.Undeploy();
initiated = true;
return this;
return false;
}
}
}

View File

@@ -58,7 +58,7 @@ namespace OpenRA.Mods.Common.Activities
/// </summary>
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
bool targetIsHiddenActor;
@@ -81,9 +81,8 @@ namespace OpenRA.Mods.Common.Activities
// We need to wait for movement to finish before transitioning to
// the next state or next activity
ChildActivity = ActivityUtils.RunActivity(self, ChildActivity);
if (ChildActivity != null)
return this;
if (!TickChild(self))
return false;
// Note that lastState refers to what we have just *finished* doing
switch (lastState)
@@ -93,11 +92,11 @@ namespace OpenRA.Mods.Common.Activities
// NOTE: We can safely cancel in this case because we know the
// actor has finished any in-progress move activities
if (IsCanceling)
return NextActivity;
return true;
// Lost track of the target
if (useLastVisibleTarget && lastVisibleTarget.Type == TargetType.Invalid)
return NextActivity;
return true;
// We are not next to the target - lets fix that
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
var initialTargetPosition = (useLastVisibleTarget ? lastVisibleTarget : target).CenterPosition;
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
// There's not much more we can do here
if (useLastVisibleTarget || target.Type != TargetType.Actor)
return NextActivity;
return true;
// Are we ready to move into the target?
if (TryStartEnter(self, target.Actor))
{
lastState = EnterState.Entering;
QueueChild(move.MoveIntoTarget(self, target));
return this;
return false;
}
// Subclasses can cancel the activity during TryStartEnter
// Return immediately to avoid an extra tick's delay
if (IsCanceling)
return NextActivity;
return true;
return this;
return false;
}
case EnterState.Entering:
@@ -138,14 +137,14 @@ namespace OpenRA.Mods.Common.Activities
lastState = EnterState.Exiting;
QueueChild(move.MoveIntoWorld(self, self.Location));
return this;
return false;
}
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)
return NextActivity;
return true;
if (NextActivity != null)
{
// Interrupt automated harvesting after clearing the first cell.
if (!harvInfo.QueueFullLoad && (hasHarvestedCell || harv.LastSearchFailed))
return NextActivity;
return true;
// Interrupt automated harvesting after first complete harvest cycle.
if (hasDeliveredLoad || harv.IsFull)
return NextActivity;
return true;
}
// Are we full or have nothing more to gather? Deliver resources.
@@ -97,7 +97,7 @@ namespace OpenRA.Mods.Common.Activities
{
QueueChild(new DeliverResources(self));
hasDeliveredLoad = true;
return this;
return false;
}
// 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));
hasWaited = true;
return this;
return 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.
QueueChild(new HarvestResource(self, closestHarvestableCell.Value));
lastHarvestedCell = closestHarvestableCell.Value;
hasHarvestedCell = true;
return this;
return false;
}
/// <summary>

View File

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

View File

@@ -19,7 +19,7 @@ namespace OpenRA.Mods.Common.Activities
{
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 Harvester Harv;
@@ -45,35 +45,37 @@ namespace OpenRA.Mods.Common.Activities
EndDrag = refinery.CenterPosition + DragOffset;
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
switch (dockingState)
{
case DockingState.Wait:
return this;
return false;
case DockingState.Turn:
dockingState = DockingState.Dock;
QueueChild(new Turn(self, DockAngle));
if (IsDragRequired)
QueueChild(new Drag(self, StartDrag, EndDrag, DragLength));
return this;
return false;
case DockingState.Dock:
if (Refinery.IsInWorld && !Refinery.IsDead)
foreach (var nd in Refinery.TraitsImplementing<INotifyDocking>())
nd.Docked(Refinery, self);
return OnStateDock(self);
OnStateDock(self);
return false;
case DockingState.Loop:
if (!Refinery.IsInWorld || Refinery.IsDead || Harv.TickUnload(self, Refinery))
dockingState = DockingState.Undock;
return this;
return false;
case DockingState.Undock:
return OnStateUndock(self);
OnStateUndock(self);
return false;
case DockingState.Complete:
if (Refinery.IsInWorld && !Refinery.IsDead)
@@ -85,11 +87,7 @@ namespace OpenRA.Mods.Common.Activities
if (IsDragRequired)
QueueChild(new Drag(self, EndDrag, StartDrag, DragLength));
dockingState = DockingState.Finished;
return this;
case DockingState.Finished:
return NextActivity;
return true;
}
throw new InvalidOperationException("Invalid harvester dock state");
@@ -106,8 +104,8 @@ namespace OpenRA.Mods.Common.Activities
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)));
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
if (IsCanceling)
return NextActivity;
return true;
var target = targets.ClosestTo(self);
if (target == null)
return this;
return false;
QueueChild(new AttackMoveActivity(self, () => move.MoveTo(target.Location, 2)));
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);
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
// We are not currently attacking a target, so scan for new targets.
if (!IsCanceling && ChildActivity != null && ChildActivity.NextActivity == null && autoTarget != null)
@@ -74,13 +74,9 @@ namespace OpenRA.Mods.Common.Activities
}
}
ChildActivity = ActivityUtils.RunActivity(self, ChildActivity);
if (ChildActivity != null)
return this;
// 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;
// The last queued childactivity is guaranteed to be the inner move, so if the childactivity
// queue is empty it means we have reached our destination and there are no more enemies on our path.
return TickChild(self);
}
protected override void OnLastRun(Actor self)

View File

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

View File

@@ -45,10 +45,10 @@ namespace OpenRA.Mods.Common.Activities
lastVisibleTarget = Target.FromPos(initialTargetPosition.Value);
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
if (IsCanceling)
return NextActivity;
return true;
bool 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
// Either we are in range and can see the target, or we've lost track of it and should give up
if (wasMovingWithinRange && targetIsHiddenActor)
return NextActivity;
return true;
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
if (useLastVisibleTarget && !lastVisibleTarget.IsValidFor(self))
return NextActivity;
return true;
var pos = self.CenterPosition;
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
// otherwise if it is hidden or dead we give up
if (checkTarget.IsInRange(pos, maxRange) && !checkTarget.IsInRange(pos, minRange))
return useLastVisibleTarget ? NextActivity : this;
return useLastVisibleTarget;
// Move into range
wasMovingWithinRange = true;
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
// all the way through before moving to the next activity
if (IsCanceling && self.Location.Layer != CustomMovementLayerType.Tunnel)
return NextActivity;
return true;
if (mobile.IsTraitDisabled || mobile.IsTraitPaused)
return this;
return false;
if (destination == mobile.ToCell)
return NextActivity;
return true;
if (path == null)
path = EvalPath();
@@ -163,22 +163,21 @@ namespace OpenRA.Mods.Common.Activities
if (path.Count == 0)
{
destination = mobile.ToCell;
return this;
return false;
}
destination = path[0];
var nextCell = PopPath(self);
if (nextCell == null)
return this;
return false;
var firstFacing = self.World.Map.FacingBetween(mobile.FromCell, nextCell.Value.First, mobile.Facing);
if (firstFacing != mobile.Facing)
{
path.Add(nextCell.Value.First);
QueueChild(new Turn(self, firstFacing));
return this;
return false;
}
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;
QueueChild(new MoveFirstHalf(this, from, to, mobile.Facing, mobile.Facing, 0));
return this;
return false;
}
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)
return this;
return false;
var ret = InnerTick(self, Move.mobile);
@@ -322,10 +321,10 @@ namespace OpenRA.Mods.Common.Activities
UpdateCenterLocation(self, Move.mobile);
if (ret == this)
return ret;
return false;
Queue(ret);
return NextActivity;
return true;
}
Activity InnerTick(Actor self, Mobile mobile)

View File

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

View File

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

View File

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

View File

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

View File

@@ -15,11 +15,12 @@ namespace OpenRA.Mods.Common.Activities
{
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();
return null;
Cancel(self);
return true;
}
}
}

View File

@@ -73,7 +73,7 @@ namespace OpenRA.Mods.Common.Activities
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),
// move actor outside the resupplier footprint
@@ -84,7 +84,7 @@ namespace OpenRA.Mods.Common.Activities
foreach (var notifyResupply in notifyResupplies)
notifyResupply.ResupplyTick(host.Actor, self, ResupplyType.None);
return this;
return false;
}
if (IsCanceling || host.Type == TargetType.Invalid
@@ -94,7 +94,7 @@ namespace OpenRA.Mods.Common.Activities
foreach (var notifyResupply in notifyResupplies)
notifyResupply.ResupplyTick(host.Actor, self, ResupplyType.None);
return NextActivity;
return true;
}
if (activeResupplyTypes.HasFlag(ResupplyType.Repair))
@@ -112,10 +112,10 @@ namespace OpenRA.Mods.Common.Activities
if (aircraft != null)
aircraft.AllowYieldingReservation();
return NextActivity;
return true;
}
return this;
return false;
}
public override void Cancel(Actor self, bool keepQueue = false)

View File

@@ -32,7 +32,7 @@ namespace OpenRA.Mods.Common.Activities
IsInterruptible = false;
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
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.Dispose();
return this;
return false;
}
}
}

View File

@@ -20,11 +20,11 @@ namespace OpenRA.Mods.Common.Activities
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.Generation++;
return NextActivity;
return true;
}
}
}

View File

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

View File

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

View File

@@ -28,20 +28,20 @@ namespace OpenRA.Mods.Common.Activities
this.desiredFacing = desiredFacing;
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
if (IsCanceling)
return NextActivity;
return true;
if (mobile != null && (mobile.IsTraitDisabled || mobile.IsTraitPaused))
return this;
return false;
if (desiredFacing == facing.Facing)
return NextActivity;
return true;
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));
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
if (IsCanceling || cargo.IsEmpty(self))
return NextActivity;
return true;
if (cargo.CanUnload())
{
@@ -107,7 +107,7 @@ namespace OpenRA.Mods.Common.Activities
{
self.NotifyBlocker(BlockedExitCells(actor));
QueueChild(new Wait(10));
return this;
return false;
}
cargo.Unload(self);
@@ -130,6 +130,7 @@ namespace OpenRA.Mods.Common.Activities
if (!unloadAll || !cargo.CanUnload())
{
Cancel(self, true);
if (cargo.Info.AfterUnloadDelay > 0)
QueueChild(new Wait(cargo.Info.AfterUnloadDelay, false));
@@ -137,7 +138,7 @@ namespace OpenRA.Mods.Common.Activities
QueueChild(new TakeOff(self));
}
return this;
return false;
}
}
}

View File

@@ -25,12 +25,12 @@ namespace OpenRA.Mods.Common.Activities
IsInterruptible = interruptible;
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
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;
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
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);
}
public override Activity Tick(Actor self)
public override bool Tick(Actor self)
{
if (transportable != null)
transportable.MovementCancelled(self);
return NextActivity;
return true;
}
}
}

View File

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

View File

@@ -46,16 +46,16 @@ namespace OpenRA.Mods.Common.Traits
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
// Recalculate overload that invalidates hidden targets.
target = target.RecalculateInvalidatingHiddenTargets(self.Owner);
if (IsCanceling || !target.IsValidFor(self) || !attack.IsReachableTarget(target, allowMove))
return NextActivity;
return true;
attack.DoAttack(self, target);
return this;
return false;
}
void IActivityNotifyStanceChanged.StanceChanged(Actor self, AutoTarget autoTarget, UnitStance oldStance, UnitStance newStance)

View File

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