Inheritance: IIssueOrder, IResolveOrder, IOrderVoice
        public bool CanBeTargetedBy(Actor self, Actor captor, Captures captures)
        {
            if (captures.IsTraitDisabled)
            {
                return(false);
            }

            var stance = captor.Owner.RelationshipWith(self.Owner);

            if (stance.HasStance(PlayerRelationship.Enemy))
            {
                return(captures.Info.CaptureTypes.Overlaps(enemyCapturableTypes));
            }

            if (stance.HasStance(PlayerRelationship.Neutral))
            {
                return(captures.Info.CaptureTypes.Overlaps(neutralCapturableTypes));
            }

            if (stance.HasStance(PlayerRelationship.Ally))
            {
                return(captures.Info.CaptureTypes.Overlaps(allyCapturableTypes));
            }

            return(false);
        }
        public bool CanBeTargetedBy(Actor self, Actor captor, Captures captures)
        {
            if (captures.IsTraitDisabled)
            {
                return(false);
            }

            var stance = self.Owner.Stances[captor.Owner];

            if (stance.HasStance(Stance.Enemy))
            {
                return(captures.Info.CaptureTypes.Overlaps(enemyCapturableTypes));
            }

            if (stance.HasStance(Stance.Neutral))
            {
                return(captures.Info.CaptureTypes.Overlaps(neutralCapturableTypes));
            }

            if (stance.HasStance(Stance.Ally))
            {
                return(captures.Info.CaptureTypes.Overlaps(allyCapturableTypes));
            }

            return(false);
        }
        public bool CanBeTargetedBy(FrozenActor frozenActor, Actor captor, Captures captures)
        {
            if (captures.IsTraitDisabled)
            {
                return(false);
            }

            // TODO: FrozenActors don't yet have a way of caching conditions, so we can't filter disabled traits
            // This therefore assumes that all Capturable traits are enabled, which is probably wrong.
            // Actors with FrozenUnderFog should therefore not disable the Capturable trait.
            var stance = captor.Owner.RelationshipWith(frozenActor.Owner);

            return(frozenActor.Info.TraitInfos <CapturableInfo>()
                   .Any(c => c.ValidRelationships.HasStance(stance) && captures.Info.CaptureTypes.Overlaps(c.Types)));
        }
        /// <summary>
        /// Called by CaptureActor when the activity is ready to enter and capture the target.
        /// This method grants the capturing conditions on the captor and target and returns
        /// true if the captor is able to start entering or false if it needs to wait.
        /// </summary>
        public bool StartCapture(Actor self, Actor target, CaptureManager targetManager, out Captures captures)
        {
            captures = null;

            // Prevent a capture being restarted after it has been canceled during disposal
            if (self.WillDispose)
            {
                return(false);
            }

            if (target != currentTarget)
            {
                if (currentTarget != null)
                {
                    CancelCapture(self, currentTarget, currentTargetManager);
                }

                targetManager.currentCaptors.Add(self);
                currentTarget        = target;
                currentTargetManager = targetManager;
                currentTargetDelay   = 0;
            }
            else
            {
                currentTargetDelay += 1;
            }

            if (capturingToken == Actor.InvalidConditionToken)
            {
                capturingToken = self.GrantCondition(info.CapturingCondition);
            }

            if (targetManager.beingCapturedToken == Actor.InvalidConditionToken)
            {
                targetManager.beingCapturedToken = target.GrantCondition(targetManager.info.BeingCapturedCondition);
            }

            captures = enabledCaptures
                       .OrderBy(c => c.Info.CaptureDelay)
                       .FirstOrDefault(c => targetManager.CanBeTargetedBy(target, self, c));

            if (captures == null)
            {
                return(false);
            }

            // HACK: Make sure the target is not moving and at its normal position with respect to the cell grid
            var enterMobile = target.TraitOrDefault <Mobile>();

            if (enterMobile != null && enterMobile.IsMovingBetweenCells)
            {
                return(false);
            }

            if (progressWatchers.Any() || targetManager.progressWatchers.Any())
            {
                currentTargetTotal = captures.Info.CaptureDelay;
                if (move != null && captures.Info.ConsumedByCapture)
                {
                    var pos = target.GetTargetablePositions().PositionClosestTo(self.CenterPosition);
                    currentTargetTotal += move.EstimatedMoveDuration(self, self.CenterPosition, pos);
                }

                foreach (var w in progressWatchers)
                {
                    w.Update(self, self, target, currentTargetDelay, currentTargetTotal);
                }

                foreach (var w in targetManager.progressWatchers)
                {
                    w.Update(target, self, target, currentTargetDelay, currentTargetTotal);
                }
            }

            enteringCurrentTarget = currentTargetDelay >= captures.Info.CaptureDelay;
            return(enteringCurrentTarget);
        }
Esempio n. 5
0
 public CaptureOrderTargeter(Captures captures)
     : base("CaptureActor", 6, captures.Info.EnterCursor, true, true)
 {
     this.captures = captures;
 }
        /// <summary>
        /// Called by CaptureActor when the activity is ready to enter and capture the target.
        /// This method grants the capturing conditions on the captor and target and returns
        /// true if the captor is able to start entering or false if it needs to wait.
        /// </summary>
        public bool StartCapture(Actor self, Actor target, CaptureManager targetManager, out Captures captures)
        {
            captures = null;

            // Prevent a capture being restarted after it has been canceled during disposal
            if (self.WillDispose)
            {
                return(false);
            }

            if (target != currentTarget)
            {
                if (currentTarget != null)
                {
                    CancelCapture(self, currentTarget, currentTargetManager);
                }

                targetManager.currentCaptors.Add(self);
                currentTarget        = target;
                currentTargetManager = targetManager;
                currentTargetDelay   = 0;
            }
            else
            {
                currentTargetDelay += 1;
            }

            if (conditionManager != null && !string.IsNullOrEmpty(info.CapturingCondition) &&
                capturingToken == ConditionManager.InvalidConditionToken)
            {
                capturingToken = conditionManager.GrantCondition(self, info.CapturingCondition);
            }

            if (targetManager.conditionManager != null && !string.IsNullOrEmpty(targetManager.info.BeingCapturedCondition) &&
                targetManager.beingCapturedToken == ConditionManager.InvalidConditionToken)
            {
                targetManager.beingCapturedToken = targetManager.conditionManager.GrantCondition(target, targetManager.info.BeingCapturedCondition);
            }

            captures = enabledCaptures
                       .OrderBy(c => c.Info.CaptureDelay)
                       .FirstOrDefault(c => targetManager.CanBeTargetedBy(target, self, c));

            if (captures == null)
            {
                return(false);
            }

            if (progressWatchers.Any() || targetManager.progressWatchers.Any())
            {
                currentTargetTotal = captures.Info.CaptureDelay;
                if (move != null && captures.Info.ConsumedByCapture)
                {
                    var pos = target.GetTargetablePositions().PositionClosestTo(self.CenterPosition);
                    currentTargetTotal += move.EstimatedMoveDuration(self, self.CenterPosition, pos);
                }

                foreach (var w in progressWatchers)
                {
                    w.Update(self, self, target, currentTargetDelay, currentTargetTotal);
                }

                foreach (var w in targetManager.progressWatchers)
                {
                    w.Update(target, self, target, currentTargetDelay, currentTargetTotal);
                }
            }

            enteringCurrentTarget = currentTargetDelay >= captures.Info.CaptureDelay;
            return(enteringCurrentTarget);
        }