예제 #1
0
        /// <summary>
        /// Called by CaptureActor when the activity finishes or is cancelled
        /// This method revokes the capturing conditions on the captor and target
        /// and resets any capturing progress.
        /// </summary>
        public void CancelCapture(Actor self, Actor target, CaptureManager targetManager)
        {
            if (currentTarget == null)
            {
                return;
            }

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

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

            if (capturingToken != Actor.InvalidConditionToken)
            {
                capturingToken = self.RevokeCondition(capturingToken);
            }

            if (targetManager.beingCapturedToken != Actor.InvalidConditionToken)
            {
                targetManager.beingCapturedToken = target.RevokeCondition(targetManager.beingCapturedToken);
            }

            currentTarget         = null;
            currentTargetManager  = null;
            currentTargetDelay    = 0;
            enteringCurrentTarget = false;
            targetManager.currentCaptors.Remove(self);
        }
예제 #2
0
        public bool CanBeTargetedBy(Actor self, Actor captor, CaptureManager captorManager)
        {
            var stance = captor.Owner.RelationshipWith(self.Owner);

            if (stance.HasStance(PlayerRelationship.Enemy))
            {
                return(captorManager.capturesTypes.Overlaps(enemyCapturableTypes));
            }

            if (stance.HasStance(PlayerRelationship.Neutral))
            {
                return(captorManager.capturesTypes.Overlaps(neutralCapturableTypes));
            }

            if (stance.HasStance(PlayerRelationship.Ally))
            {
                return(captorManager.capturesTypes.Overlaps(allyCapturableTypes));
            }

            return(false);
        }
        public bool CanBeTargetedBy(Actor self, Actor captor, CaptureManager captorManager)
        {
            var stance = self.Owner.Stances[captor.Owner];

            if (stance.HasStance(Stance.Enemy))
            {
                return(captorManager.capturesTypes.Overlaps(enemyCapturableTypes));
            }

            if (stance.HasStance(Stance.Neutral))
            {
                return(captorManager.capturesTypes.Overlaps(neutralCapturableTypes));
            }

            if (stance.HasStance(Stance.Ally))
            {
                return(captorManager.capturesTypes.Overlaps(allyCapturableTypes));
            }

            return(false);
        }
예제 #4
0
 public Captures(Actor self, CapturesInfo info)
     : base(info)
 {
     captureManager = self.Trait <CaptureManager>();
 }
예제 #5
0
        /// <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);
        }
예제 #6
0
        public Captures ValidCapturesWithLowestSabotageThreshold(Actor self, Actor captee, CaptureManager capteeManager)
        {
            if (captee.IsDead)
            {
                return(null);
            }

            foreach (var c in enabledCaptures.OrderBy(c => c.Info.SabotageThreshold))
            {
                if (capteeManager.CanBeTargetedBy(captee, self, c))
                {
                    return(c);
                }
            }

            return(null);
        }
        /// <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);
        }