Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
                }
            }
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
            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);
        }
Beispiel #7
0
            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);
            }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
 Activity CanceledTick(Actor self)
 {
     if (inner == null)
     {
         return(ActivityUtils.RunActivity(self, NextActivity));
     }
     inner.Cancel(self);
     inner.Queue(NextActivity);
     return(ActivityUtils.RunActivity(self, inner));
 }
Beispiel #12
0
        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);
        }
Beispiel #13
0
        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);
        }
Beispiel #14
0
 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;
     }
 }
Beispiel #15
0
        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);
        }
Beispiel #16
0
        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);
        }
Beispiel #17
0
        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);
        }
Beispiel #18
0
        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);
        }
Beispiel #19
0
        public void Tick()
        {
            var wasIdle = IsIdle;

            CurrentActivity = ActivityUtils.RunActivity(this, CurrentActivity);

            if (!wasIdle && IsIdle)
            {
                foreach (var n in TraitsImplementing <INotifyBecomingIdle>())
                {
                    n.OnBecomingIdle(this);
                }
            }
        }
Beispiel #20
0
        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);
        }
Beispiel #22
0
        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);
        }
Beispiel #23
0
        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);
        }
Beispiel #24
0
        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);
        }
Beispiel #25
0
        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);
        }
Beispiel #27
0
        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);
        }
Beispiel #28
0
        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);
        }
Beispiel #29
0
        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);
        }