Example #1
0
            public override bool Tick(Actor self)
            {
                if (IsCanceling)
                {
                    return(true);
                }

                if (target.Type != TargetType.Invalid && !move.CanEnterTargetNow(self, target))
                {
                    QueueChild(new MoveAdjacentTo(self, target, targetLineColor: Color.Red));
                    return(false);
                }

                if (!initiated)
                {
                    // If the target has died while we were moving, we should abort detonation.
                    if (target.Type == TargetType.Invalid)
                    {
                        return(true);
                    }

                    if (mad.conditionManager != null && !string.IsNullOrEmpty(mad.info.DeployedCondition))
                    {
                        mad.conditionManager.GrantCondition(self, mad.info.DeployedCondition);
                    }

                    self.World.AddFrameEndTask(w => EjectDriver());
                    if (mad.info.ThumpSequence != null)
                    {
                        wfsb.PlayCustomAnimationRepeating(self, mad.info.ThumpSequence);
                    }

                    IsInterruptible = false;
                    initiated       = true;
                }

                if (++ticks % mad.info.ThumpInterval == 0)
                {
                    if (mad.info.ThumpDamageWeapon != null)
                    {
                        // Use .FromPos since this weapon needs to affect more than just the MadTank actor
                        mad.info.ThumpDamageWeaponInfo.Impact(Target.FromPos(self.CenterPosition), self, Enumerable.Empty <int>());
                    }

                    screenShaker.AddEffect(mad.info.ThumpShakeTime, self.CenterPosition, mad.info.ThumpShakeIntensity, mad.info.ThumpShakeMultiplier);
                }

                if (ticks == mad.info.ChargeDelay)
                {
                    Game.Sound.Play(SoundType.World, mad.info.ChargeSound, self.CenterPosition);
                }

                return(ticks == mad.info.ChargeDelay + mad.info.DetonationDelay);
            }
Example #2
0
            public override bool Tick(Actor self)
            {
                if (IsCanceling)
                {
                    return(true);
                }

                if (target.Type != TargetType.Invalid && !move.CanEnterTargetNow(self, target))
                {
                    QueueChild(new MoveAdjacentTo(self, target, targetLineColor: Color.Red));
                    return(false);
                }

                if (!initiated)
                {
                    // If the target has died while we were moving, we should abort detonation.
                    if (target.Type == TargetType.Invalid)
                    {
                        return(true);
                    }

                    if (csd.conditionManager != null && !string.IsNullOrEmpty(csd.info.DeployedCondition))
                    {
                        csd.conditionManager.GrantCondition(self, csd.info.DeployedCondition);
                    }

                    if (csd.info.ChargingSequence != null)
                    {
                        wfsb.PlayCustomAnimationRepeating(self, csd.info.ChargingSequence);
                    }

                    IsInterruptible = false;
                    initiated       = true;
                }

                if (++ticks % csd.info.ChargingInterval == 0)
                {
                    if (csd.info.ChargingDamageWeapon != null)
                    {
                        // Use .FromPos since this weapon needs to affect more than just the actor
                        csd.info.ThumpDamageWeaponInfo.Impact(Target.FromPos(self.CenterPosition), self);
                    }
                }

                if (ticks == csd.info.ChargeDelay)
                {
                    Game.Sound.Play(SoundType.World, csd.info.ChargeSound, self.CenterPosition);
                }

                return(ticks == csd.info.ChargeDelay + csd.info.DetonationDelay);
            }
Example #3
0
        public override bool Tick(Actor self)
        {
            // Update our view of the target
            bool targetIsHiddenActor;

            target = target.Recalculate(self.Owner, out targetIsHiddenActor);
            if (!targetIsHiddenActor && target.Type == TargetType.Actor)
            {
                lastVisibleTarget = Target.FromTargetPositions(target);
            }

            var oldUseLastVisibleTarget = useLastVisibleTarget;

            useLastVisibleTarget = targetIsHiddenActor || !target.IsValidFor(self);

            // Cancel immediately if the target died while we were entering it
            if (!IsCanceling && useLastVisibleTarget && lastState == EnterState.Entering)
            {
                Cancel(self, true);
            }

            TickInner(self, target, useLastVisibleTarget);

            // We need to wait for movement to finish before transitioning to
            // the next state or next activity
            if (!TickChild(self))
            {
                return(false);
            }

            // Note that lastState refers to what we have just *finished* doing
            switch (lastState)
            {
            case EnterState.Approaching:
            {
                // NOTE: We can safely cancel in this case because we know the
                // actor has finished any in-progress move activities
                if (IsCanceling)
                {
                    return(true);
                }

                // Lost track of the target
                if (useLastVisibleTarget && lastVisibleTarget.Type == TargetType.Invalid)
                {
                    return(true);
                }

                // We are not next to the target - lets fix that
                if (target.Type != TargetType.Invalid && !move.CanEnterTargetNow(self, target))
                {
                    // 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(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(true);
                }

                // Are we ready to move into the target?
                if (TryStartEnter(self, target.Actor))
                {
                    lastState = EnterState.Entering;
                    QueueChild(move.MoveIntoTarget(self, target));
                    return(false);
                }

                // Subclasses can cancel the activity during TryStartEnter
                // Return immediately to avoid an extra tick's delay
                if (IsCanceling)
                {
                    return(true);
                }

                return(false);
            }

            case EnterState.Entering:
            {
                // Check that we reached the requested position
                var targetPos = target.Positions.PositionClosestTo(self.CenterPosition);
                if (!IsCanceling && self.CenterPosition == targetPos && target.Type == TargetType.Actor)
                {
                    OnEnterComplete(self, target.Actor);
                }

                lastState = EnterState.Exiting;
                return(false);
            }

            case EnterState.Exiting:
            {
                QueueChild(move.ReturnToCell(self));
                lastState = EnterState.Finished;
                return(false);
            }
            }

            return(true);
        }
Example #4
0
 protected virtual ReserveStatus Reserve(Actor self)
 {
     return(!CanReserve(self) ? ReserveStatus.None : move.CanEnterTargetNow(self, target) ? ReserveStatus.Ready : ReserveStatus.TooFar);
 }