/// <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); }
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); }
public Captures(Actor self, CapturesInfo info) : base(info) { captureManager = self.Trait <CaptureManager>(); }
/// <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); }
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); }