public override Activity Tick(Actor self) { if (IsCanceled) { return(CanceledTick(self)); } // Check target validity if not exiting or done if (nextState != EnterState.Done && (target.Type != TargetType.Actor || !target.IsValidFor(self))) { AbortOrExit(self); } // If no current activity, tick next activity if (inner == null && FindAndTransitionToNextState(self) == EnterState.Done) { return(CanceledTick(self)); } // Run inner activity/InsideTick inner = inner == this ? InsideTick(self) : ActivityUtils.RunActivity(self, inner); // If we are finished, move on to next activity if (inner == null && nextState == EnterState.Done) { return(NextActivity); } return(this); }
public void Tick() { var wasIdle = IsIdle; CurrentActivity = ActivityUtils.RunActivity(this, CurrentActivity); if (!wasIdle && IsIdle) { foreach (var n in becomingIdles) { n.OnBecomingIdle(this); } // If IsIdle is true, it means the last CurrentActivity.Tick returned null. // If a next activity has been queued via OnBecomingIdle, we need to start running it now, // to avoid an 'empty' null tick where the actor will (visibly, if moving) do nothing. CurrentActivity = ActivityUtils.RunActivity(this, CurrentActivity); } else if (wasIdle) { foreach (var tickIdle in tickIdles) { tickIdle.TickIdle(this); } } }
Activity TryDeployTick(Actor self, out MiningState state) { // Wait for child wait activity to be done. // Could be wait or could be move to. if (ChildActivity != null) { ChildActivity = ActivityUtils.RunActivity(self, ChildActivity); state = MiningState.TryDeploy; return(this); } if (!deploy.IsValidTerrain(self.Location)) { // If we can't deploy, go back to scan state so that we scan try deploy again. state = MiningState.Scan; return(this); } // Issue deploy order and enter deploying state. //if (deploy. == DeployState.Undeployed) //{ IsInterruptible = false; tranforms.DeployTransform(true); //} state = MiningState.Deploying; return(this); }
public override Activity Tick(Actor self) { if (ChildActivity != null) { ChildActivity = ActivityUtils.RunActivity(self, ChildActivity); if (ChildActivity != null) { return(this); } } if (IsCanceling) { return(NextActivity); } var target = targets.ClosestTo(self); if (target == null) { return(this); } QueueChild(self, new AttackMoveActivity(self, () => move.MoveTo(target.Location, 2)), true); QueueChild(self, new Wait(25)); return(this); }
public override Activity Tick(Actor self) { if (ChildActivity != null) { ChildActivity = ActivityUtils.RunActivity(self, ChildActivity); if (ChildActivity != null) { return(this); } } if (IsCanceling || !attack.CanAttack(self, target)) { return(NextActivity); } if (attack.charges == 0) { return(NextActivity); } attack.DoAttack(self, target); QueueChild(self, new Wait(attack.info.ChargeDelay), true); return(this); }
public override Activity Tick(Actor self) { // Do turn first, if needed. if (ChildActivity != null) { ChildActivity = ActivityUtils.RunActivity(self, ChildActivity); return(this); } // Without this, turn for facing deploy angle will be canceled and immediately deploy! if (IsCanceled) { return(NextActivity); } if (IsInterruptible) { IsInterruptible = false; // must DEPLOY from now. deploy.Deploy(); return(this); } // Wait for deployment if (deploy.DeployState == DeployState.Deploying) { return(this); } // Failed or success, we are going to NextActivity. // Deploy() at the first run would have put DeployState == Deploying so // if we are back to DeployState.Undeployed, it means deploy failure. // Parent activity will see the status and will take appropriate action. return(NextActivity); }
public override Activity Tick(Actor self) { if (ChildActivity != null) { ChildActivity = ActivityUtils.RunActivity(self, ChildActivity); if (ChildActivity != null) { return(this); } } if (IsCanceling || !attack.CanAttack(self, target)) { return(NextActivity); } if (attack.charges == 0) { return(this); } foreach (var notify in self.TraitsImplementing <INotifyTeslaCharging>()) { notify.Charging(self, target); } if (!string.IsNullOrEmpty(attack.info.ChargeAudio)) { Game.Sound.Play(SoundType.World, attack.info.ChargeAudio, self.CenterPosition); } QueueChild(self, new Wait(attack.info.InitialChargeDelay), true); QueueChild(self, new ChargeFire(attack, target)); return(this); }
public override Activity Tick(Actor self) { if (ChildActivity != null) { ChildActivity = ActivityUtils.RunActivity(self, ChildActivity); if (ChildActivity != null) { return(this); } } if (IsCanceling || target.Type == TargetType.Invalid) { return(NextActivity); } if (mobile.IsTraitDisabled || mobile.IsTraitPaused) { return(this); } 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); } // 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(self, turn); } return(this); } // Can complete the move in this step var speed = mobile.MovementSpeedForCell(self, self.Location); if (delta.LengthSquared <= speed * speed) { mobile.SetVisualPosition(self, targetPos); return(NextActivity); } // Move towards the target mobile.SetVisualPosition(self, currentPos + delta * speed / delta.Length); return(this); }
public override Activity Tick(Actor self) { var targetIsValid = Target.IsValidFor(self); if (Target.Type == TargetT.Actor && canHideUnderFog && !Target.Actor.CanBeViewedByPlayer(self.Owner)) { if (inner != null) { inner.Cancel(self); } self.SetTargetLine(Target.FromCell(self.World, targetPosition), Color.Green); return(ActivityUtils.RunActivity(self, new AttackMoveActivity(self, Mobile.MoveTo(targetPosition, 0)))); } //Inner move order has completed if (inner == null) { if (IsCanceled || !repath || !targetIsValid) { return(NextActivity); } //Target has moved,and MoveAdjacentTo is still valid. inner = Mobile.MoveTo(() => CalculatePathToTarget(self)); repath = false; } if (targetIsValid) { //Check if the target has moved var oldTargetPosition = targetPosition; targetPosition = self.World.Map.CellContaining(Target.CenterPosition); var shouldStop = ShouldStop(self, oldTargetPosition); if (shouldStop || (!repath && ShouldRepath(self, oldTargetPosition))) { //Finish moving into the next cell and then repath. if (inner != null) { inner.Cancel(self); } repath = !shouldStop; } } else { //Target became invalid.Move to its last known position. Target = Target.FromCell(self.World, targetPosition); } //Ticks the inner move activity to actually move the actor. inner = ActivityUtils.RunActivity(self, inner); return(this); }
public override Activity Tick(Actor self) { if (ChildActivity != null) { ChildActivity = ActivityUtils.RunActivity(self, ChildActivity); return(this); } if (IsCanceling) { return(NextActivity); } if (rearmableInfo != null && ammoPools.Any(p => p.Info.Name == info.AmmoPoolName && !p.HasAmmo())) { // Rearm (and possibly repair) at rearm building, then back out here to refill the minefield some more var rearmTarget = self.World.Actors.Where(a => self.Owner.Stances[a.Owner] == Stance.Ally && rearmableInfo.RearmActors.Contains(a.Info.Name)) .ClosestTo(self); if (rearmTarget == null) { return(NextActivity); } // Add a CloseEnough range of 512 to the Rearm/Repair activities in order to ensure that we're at the host actor QueueChild(self, new MoveAdjacentTo(self, Target.FromActor(rearmTarget)), true); QueueChild(self, movement.MoveTo(self.World.Map.CellContaining(rearmTarget.CenterPosition), rearmTarget)); QueueChild(self, new Resupply(self, rearmTarget, new WDist(512))); return(this); } if ((minefield == null || minefield.Contains(self.Location)) && ShouldLayMine(self, self.Location)) { LayMine(self); QueueChild(self, new Wait(20), true); // A little wait after placing each mine, for show return(this); } if (minefield != null && minefield.Length > 0) { // Don't get stuck forever here for (var n = 0; n < 20; n++) { var p = minefield.Random(self.World.SharedRandom); if (ShouldLayMine(self, p)) { QueueChild(self, movement.MoveTo(p, 0), true); return(this); } } } // TODO: Return somewhere likely to be safe (near rearm building) so we're not sitting out in the minefield. return(NextActivity); }
Activity CanceledTick(Actor self) { if (inner == null) { return(ActivityUtils.RunActivity(self, NextActivity)); } inner.Cancel(self); inner.Queue(NextActivity); return(ActivityUtils.RunActivity(self, inner)); }
public override Activity Tick(Actor self) { if (IsCanceled) { wsb.PlayCustomAnimationRepeating(self, wsb.Info.Sequence); playanim = true; if (externalCondition != null) { Game.Debug("revoke: " + token); externalCondition.TryRevokeCondition(self, dockactor, token); } return(NextActivity); } if (ChildActivity != null) { ActivityUtils.RunActivity(self, ChildActivity); return(this); } if (playanim) { playanim = false; QueueChild(self.Trait <IMove>().VisualMove(self, self.CenterPosition, _d.CenterPosition)); QueueChild(new CallFunc(() => { var facing = self.Trait <IFacing>(); if (dockactor != null && facing != null && lockfacing) { var desiredFacing = (dockactor.CenterPosition - self.CenterPosition).HorizontalLengthSquared != 0 ? (dockactor.CenterPosition - self.CenterPosition).Yaw.Facing : facing.Facing; facing.Facing = desiredFacing; } wsb.PlayCustomAnimationRepeating(self, info.PreySequence); Game.Debug("Manager: " + externalCondition); if (externalCondition != null) { token = externalCondition.GrantCondition(dockactor, self); } })); } if (self.Info.TraitInfo <AcolytePreyInfo>().LeechesResources&& --ticks <= 0) { Leech(self); ticks = self.Info.TraitInfo <AcolytePreyInfo>().leechinterval; } return(this); }
public override Activity Tick(Actor self) { if (ChildActivity != null) { ChildActivity = ActivityUtils.RunActivity(self, ChildActivity); if (ChildActivity != null) { return(this); } } if (IsCanceling || isDocking) { return(NextActivity); } // Find the nearest best refinery if not explicitly ordered to a specific refinery: if (harv.LinkedProc == null || !harv.LinkedProc.IsInWorld) { harv.ChooseNewProc(self, null); } // No refineries exist; check again after delay defined in Harvester. if (harv.LinkedProc == null) { QueueChild(self, new Wait(harv.Info.SearchForDeliveryBuildingDelay), true); return(this); } var proc = harv.LinkedProc; var iao = proc.Trait <IAcceptResources>(); self.SetTargetLine(Target.FromActor(proc), Color.Green, false); if (self.Location != proc.Location + iao.DeliveryOffset) { foreach (var n in self.TraitsImplementing <INotifyHarvesterAction>()) { n.MovingToRefinery(self, proc, new FindAndDeliverResources(self)); } QueueChild(self, movement.MoveTo(proc.Location + iao.DeliveryOffset, 0), true); return(this); } if (!isDocking) { QueueChild(self, new Wait(10), true); isDocking = true; iao.OnDock(self, this); return(this); } return(NextActivity); }
public virtual void QueueChild(Actor self, Activity activity, bool pretick = false) { if (ChildActivity != null) { ChildActivity.Queue(self, activity); } else { ChildActivity = pretick ? ActivityUtils.RunActivity(self, activity) : activity; } }
public override Activity Tick(Actor self) { // Refuse to take off if it would land immediately again. if (aircraft.ForceLanding) { Cancel(self); return(NextActivity); } if (!target.IsValidFor(self)) { return(NextActivity); } // TODO: This should check whether there is ammo left that is actually suitable for the target if (ammoPools.All(x => !x.Info.SelfReloads && !x.HasAmmo())) { return(ActivityUtils.SequenceActivities(new ReturnToBase(self, aircraft.Info.AbortOnResupply), this)); } if (attackPlane != null) { attackPlane.DoAttack(self, target); } if (ChildActivity == null) { if (IsCanceled) { return(NextActivity); } // TODO: This should fire each weapon at its maximum range if (attackPlane != null && target.IsInRange(self.CenterPosition, attackPlane.Armaments.Where(Exts.IsTraitEnabled).Select(a => a.Weapon.MinRange).Min())) { ChildActivity = ActivityUtils.SequenceActivities(new FlyTimed(ticksUntilTurn, self), new Fly(self, target), new FlyTimed(ticksUntilTurn, self)); } else { ChildActivity = ActivityUtils.SequenceActivities(new Fly(self, target), new FlyTimed(ticksUntilTurn, self)); } // HACK: This needs to be done in this round-about way because TakeOff doesn't behave as expected when it doesn't have a NextActivity. if (self.World.Map.DistanceAboveTerrain(self.CenterPosition).Length < aircraft.Info.MinAirborneAltitude) { ChildActivity = ActivityUtils.SequenceActivities(new TakeOff(self), ChildActivity); } } ActivityUtils.RunActivity(self, ChildActivity); return(this); }
public override Activity Tick(Actor self) { // Refuse to take off if it would land immediately again. if (aircraft.ForceLanding) { Cancel(self); return(NextActivity); } if (!target.IsValidFor(self)) { return(NextActivity); } // If all valid weapons have depleted their ammo and RearmBuilding is defined, return to RearmBuilding to reload and then resume the activity if (!autoReloads && aircraft.Info.RearmBuildings.Any() && attackPlane.Armaments.All(x => x.IsTraitPaused || !x.Weapon.IsValidAgainst(target, self.World, self))) { return(ActivityUtils.SequenceActivities(new ReturnToBase(self, aircraft.Info.AbortOnResupply), this)); } if (attackPlane != null) { attackPlane.DoAttack(self, target); } if (ChildActivity == null) { if (IsCanceled) { return(NextActivity); } // TODO: This should fire each weapon at its maximum range if (attackPlane != null && target.IsInRange(self.CenterPosition, attackPlane.Armaments.Where(Exts.IsTraitEnabled).Select(a => a.Weapon.MinRange).Min())) { ChildActivity = ActivityUtils.SequenceActivities(new FlyTimed(ticksUntilTurn, self), new Fly(self, target), new FlyTimed(ticksUntilTurn, self)); } else { ChildActivity = ActivityUtils.SequenceActivities(new Fly(self, target), new FlyTimed(ticksUntilTurn, self)); } // HACK: This needs to be done in this round-about way because TakeOff doesn't behave as expected when it doesn't have a NextActivity. if (self.World.Map.DistanceAboveTerrain(self.CenterPosition).Length < aircraft.Info.MinAirborneAltitude) { ChildActivity = ActivityUtils.SequenceActivities(new TakeOff(self), ChildActivity); } } ActivityUtils.RunActivity(self, ChildActivity); return(this); }
public override Activity Tick(Actor self) { if (!target.IsValidFor(self)) { return(NextActivity); } // TODO: This should check whether there is ammo left that is actually suitable for the target if (ammoPools.All(x => !x.Info.SelfReloads && !x.HasAmmo())) { //var master = self.Trait<Spawned>().Master; //var tgt = Target.FromActor(master); //// We let the spawned to move closer then Enter. //// If we just let it enter, it "slides on the ground", targetable by ground units. //return ActivityUtils.SequenceActivities(new Fly(self, tgt, new WDist(1024*3), new WDist(1024*5)), new EnterSpawner(self, master, EnterBehaviour.Exit)); self.Trait <Spawned>().EnterSpawner(self); } if (attackPlane != null) { attackPlane.DoAttack(self, target); } if (inner == null) { if (IsCanceled) { return(NextActivity); } // TODO: This should fire each weapon at its maximum range if (attackPlane != null && target.IsInRange(self.CenterPosition, attackPlane.Armaments.Select(a => a.Weapon.MinRange).Min())) { inner = ActivityUtils.SequenceActivities(new FlyTimed(ticksUntilTurn, self), new Fly(self, target), new FlyTimed(ticksUntilTurn, self)); } else { inner = ActivityUtils.SequenceActivities(new Fly(self, target), new FlyTimed(ticksUntilTurn, self)); } // HACK: This needs to be done in this round-about way because TakeOff doesn't behave as expected when it doesn't have a NextActivity. if (self.World.Map.DistanceAboveTerrain(self.CenterPosition).Length < aircraft.Info.MinAirborneAltitude) { inner = ActivityUtils.SequenceActivities(new SpawnedTakeOff(self), inner); } } inner = ActivityUtils.RunActivity(self, inner); return(this); }
public override Activity Tick(Actor self) { if (aircraft.ForceLanding) { Cancel(self); return(NextActivity); } if (!target.IsValidFor(self)) { return(NextActivity); } if (!autoReloads && aircraft.Info.RearmBuildings.Any() && attackPlane.Armaments.All(x => x.IsTraitPaused || !x.Weapon.IsValidAgainst(target, self.World, self))) { return(ActivityUtils.SequenceActivities(new ReturnToBase(self, aircraft.Info.AbortOnResupply), this)); } if (attackPlane != null) { attackPlane.DoAttack(self, target); } if (ChildActivity == null) { if (IsCanceled) { return(NextActivity); } if (attackPlane != null && target.IsInRange(self.CenterPosition, attackPlane.Armaments.Where(Exts.IsTraitEnabled).Select(a => a.Weapon.MinRange).Min())) { ChildActivity = ActivityUtils.SequenceActivities(new FlyTimed(ticksUntilTurn, self), new Fly(self, target), new FlyTimed(ticksUntilTurn, self)); } else { ChildActivity = ActivityUtils.SequenceActivities(new Fly(self, target), new FlyTimed(ticksUntilTurn, self)); } if (self.World.Map.DistanceAboveTerrain(self.CenterPosition).Length < aircraft.Info.MinAirborneAltitude) { ChildActivity = ActivityUtils.SequenceActivities(new TakeOff(self), ChildActivity); } } ActivityUtils.RunActivity(self, ChildActivity); return(this); }
public void Tick() { var wasIdle = IsIdle; CurrentActivity = ActivityUtils.RunActivity(this, CurrentActivity); if (!wasIdle && IsIdle) { foreach (var n in TraitsImplementing <INotifyBecomingIdle>()) { n.OnBecomingIdle(this); } } }
public override Activity Tick(Actor self) { if (canceled) { return(NextActivity); } // Correct the visual position after we jumped if (jumpComplete) { if (ChildActivity == null) { return(NextActivity); } ChildActivity = ActivityUtils.RunActivity(self, ChildActivity); return(this); } if (target.Type != TargetType.Invalid) { targetPosition = target.CenterPosition; } var position = length > 1 ? WPos.Lerp(origin, targetPosition, ticks, length - 1) : targetPosition; mobile.SetVisualPosition(self, position); // We are at the destination if (++ticks >= length) { // Revoke the run condition attack.IsAiming = false; // Move to the correct subcells, if our target actor uses subcells // (This does not update the visual position!) mobile.SetLocation(destinationCell, destinationSubCell, destinationCell, destinationSubCell); // Revoke the condition before attacking, as it is usually used to pause the attack trait attack.RevokeLeapCondition(self); attack.DoAttack(self, target); jumpComplete = true; QueueChild(self, mobile.VisualMove(self, position, self.World.Map.CenterOfSubCell(destinationCell, destinationSubCell)), true); return(this); } return(this); }
public override Activity Tick(Actor self) { if (inner == null) { if (transportable != null) { transportable.MovementCancelled(self); } return(NextActivity); } inner = ActivityUtils.RunActivity(self, inner); return(this); }
public override Activity Tick(Actor self) { if (autoTarget != null && --scanTicks <= 0) { autoTarget.ScanAndAttack(self, true); scanTicks = ScanInterval; } if (inner == null) { return(NextActivity); } inner = ActivityUtils.RunActivity(self, inner); return(this); }
public override Activity Tick(Actor self) { if (ChildActivity != null) { ChildActivity = ActivityUtils.RunActivity(self, ChildActivity); if (ChildActivity != null) { return(this); } } // Refuse to take off if it would land immediately again. if (aircraft.ForceLanding) { Cancel(self); return(NextActivity); } var dat = self.World.Map.DistanceAboveTerrain(aircraft.CenterPosition); if (dat < aircraft.Info.CruiseAltitude) { // If we're a VTOL, rise before flying forward if (aircraft.Info.VTOL) { Fly.VerticalTakeOffOrLandTick(self, aircraft, aircraft.Facing, aircraft.Info.CruiseAltitude); return(this); } else { Fly.FlyTick(self, aircraft, aircraft.Facing, aircraft.Info.CruiseAltitude); return(this); } } // Checking for NextActivity == null again in case another activity was queued while taking off if (moveToRallyPoint && NextActivity == null) { QueueChild(self, new AttackMoveActivity(self, () => move.MoveToTarget(self, target)), true); moveToRallyPoint = false; return(this); } return(NextActivity); }
public override Activity Tick(Actor self) { if (ChildActivity != null) { ChildActivity = ActivityUtils.RunActivity(self, ChildActivity); if (ChildActivity != null) { return(this); } } if (transportable != null) { transportable.MovementCancelled(self); } return(NextActivity); }
public override Activity Tick(Actor self) { if (IsCanceled) { return(NextActivity); } if (ChildActivity != null) { ActivityUtils.RunActivity(self, ChildActivity); return(this); } // Prevent deployment in bogus locations var transforms = self.TraitOrDefault <Transforms>(); var building = self.TraitOrDefault <Building>(); if ((transforms != null && !transforms.CanDeploy()) || (building != null && !building.Lock())) { Cancel(self, true); return(NextActivity); } foreach (var nt in self.TraitsImplementing <INotifyTransform>()) { nt.BeforeTransform(self); } var makeAnimation = self.TraitOrDefault <WithMakeAnimation>(); if (!SkipMakeAnims && makeAnimation != null) { // Once the make animation starts the activity must not be stopped anymore. IsInterruptible = false; //wait forever QueueChild(new WaitFor(() => false)); makeAnimation.Reverse(self, () => DoTransform(self)); return(this); } return(NextActivity); }
public override Activity Tick(Actor self) { if (IsCanceled) { return(NextActivity); } if (inner == null) { var host = aircraft.GetActorBelow(); if (host == null) { return(NextActivity); } if (aircraft.IsPlane) { inner = ActivityUtils.SequenceActivities( aircraft.GetResupplyActivities(host) .Append(new AllowYieldingReservation(self)) .Append(new WaitFor(() => NextActivity != null || aircraft.ReservedActor == null)) .ToArray()); } else { // Helicopters should take off from their helipad immediately after resupplying. // HACK: Append NextActivity to TakeOff to avoid moving to the Rallypoint (if NextActivity is non-null). inner = ActivityUtils.SequenceActivities( aircraft.GetResupplyActivities(host) .Append(new AllowYieldingReservation(self)) .Append(new TakeOff(self)).Append(NextActivity).ToArray()); } } else { inner = ActivityUtils.RunActivity(self, inner); } // The inner == NextActivity check is needed here because of the TakeOff issue mentioned in the comment above. return(inner == null || inner == NextActivity ? NextActivity : this); }
public override Activity Tick(Actor self) { if (!target.IsValidFor(self)) { return(NextActivity); } // Move to the next activity only if all ammo pools are depleted and none reload automatically // TODO: This should check whether there is ammo left that is actually suitable for the target if (ammoPools.All(x => !x.Info.SelfReloads && !x.HasAmmo())) { return(ActivityUtils.SequenceActivities(new ReturnToBase(self), NextActivity)); } if (attackPlane != null) { attackPlane.DoAttack(self, target); } if (inner == null) { if (IsCanceled) { return(NextActivity); } // TODO: This should fire each weapon at its maximum range if (attackPlane != null && target.IsInRange(self.CenterPosition, attackPlane.Armaments.Select(a => a.Weapon.MinRange).Min())) { inner = ActivityUtils.SequenceActivities(new FlyTimed(ticksUntilTurn, self), new Fly(self, target), new FlyTimed(ticksUntilTurn, self)); } else { inner = ActivityUtils.SequenceActivities(new Fly(self, target), new FlyTimed(ticksUntilTurn, self)); } } inner = ActivityUtils.RunActivity(self, inner); return(this); }
public override Activity Tick(Actor self) { if (ChildActivity != null) { ChildActivity = ActivityUtils.RunActivity(self, ChildActivity); if (ChildActivity != null) { return(this); } } if (IsCanceling || initiated || (deploy.DeployState != DeployState.Deployed && moving)) { return(NextActivity); } QueueChild(self, new DeployInner(self, deploy), true); initiated = true; return(this); }
Activity DeployingTick(Actor self, out MiningState state) { // Deploying in progress if (ChildActivity != null) { ChildActivity = ActivityUtils.RunActivity(self, ChildActivity); state = MiningState.Deploying; return(this); } // deploy failure. if (!tranforms.CanDeploy()) { QueueChild(new Wait(15)); state = MiningState.Scan; return(this); } state = MiningState.Mining; return(this); }
public override Activity Tick(Actor self) { // We are not currently attacking a target, so scan for new targets. if (!IsCanceling && ChildActivity != null && ChildActivity.NextActivity == null && autoTarget != null) { // ScanForTarget already limits the scanning rate for performance so we don't need to do that here. var target = autoTarget.ScanForTarget(self, true, true); if (target.Type != TargetType.Invalid) { // We have found a target so cancel the current move activity and queue attack activities. ChildActivity.Cancel(self); var attackBases = autoTarget.ActiveAttackBases; foreach (var ab in attackBases) { QueueChild(self, ab.GetAttackActivity(self, target, true, false)); ab.OnQueueAttackActivity(self, target, false, true, false); } // Make sure to continue moving when the attack activities have finished. QueueChild(self, getInner()); } } if (ChildActivity != null) { 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); }