diff --git a/OpenRA.Mods.Common/Activities/ExternalCaptureActor.cs b/OpenRA.Mods.Common/Activities/ExternalCaptureActor.cs index f980916933..2193cc8463 100644 --- a/OpenRA.Mods.Common/Activities/ExternalCaptureActor.cs +++ b/OpenRA.Mods.Common/Activities/ExternalCaptureActor.cs @@ -22,6 +22,8 @@ namespace OpenRA.Mods.Common.Activities readonly ExternalCapturesInfo capturesInfo; readonly Mobile mobile; readonly Target target; + readonly ConditionManager conditionManager; + int capturingToken = ConditionManager.InvalidConditionToken; public ExternalCaptureActor(Actor self, Target target) { @@ -29,18 +31,14 @@ namespace OpenRA.Mods.Common.Activities capturable = target.Actor.Trait(); capturesInfo = self.Info.TraitInfo(); mobile = self.Trait(); + conditionManager = self.TraitOrDefault(); } public override Activity Tick(Actor self) { - if (target.Type != TargetType.Actor) - return NextActivity; - - if (IsCanceled || !self.IsInWorld || self.IsDead || !target.IsValidFor(self)) + if (IsCanceled || !self.IsInWorld || self.IsDead || target.Type != TargetType.Actor || !target.IsValidFor(self)) { - if (capturable.CaptureInProgress) - capturable.EndCapture(); - + EndCapture(self); return NextActivity; } @@ -50,7 +48,7 @@ namespace OpenRA.Mods.Common.Activities return ActivityUtils.SequenceActivities(new MoveAdjacentTo(self, target), this); if (!capturable.CaptureInProgress) - capturable.BeginCapture(self); + BeginCapture(self); else { if (capturable.Captor != self) return NextActivity; @@ -75,7 +73,7 @@ namespace OpenRA.Mods.Common.Activities foreach (var t in target.Actor.TraitsImplementing()) t.OnCapture(target.Actor, self, oldOwner, self.Owner); - capturable.EndCapture(); + EndCapture(self); if (self.Owner.Stances[oldOwner].HasStance(capturesInfo.PlayerExperienceStances)) { @@ -92,5 +90,20 @@ namespace OpenRA.Mods.Common.Activities return this; } + + void BeginCapture(Actor self) + { + capturable.BeginCapture(self); + if (conditionManager != null && !string.IsNullOrEmpty(capturesInfo.CapturingCondition) && capturingToken == ConditionManager.InvalidConditionToken) + capturingToken = conditionManager.GrantCondition(self, capturesInfo.CapturingCondition); + } + + void EndCapture(Actor self) + { + if (capturable.CaptureInProgress) + capturable.EndCapture(); + if (capturingToken != ConditionManager.InvalidConditionToken) + capturingToken = conditionManager.RevokeCondition(self, capturingToken); + } } } diff --git a/OpenRA.Mods.Common/Traits/Cloak.cs b/OpenRA.Mods.Common/Traits/Cloak.cs index 0b99a4584b..f268de2512 100644 --- a/OpenRA.Mods.Common/Traits/Cloak.cs +++ b/OpenRA.Mods.Common/Traits/Cloak.cs @@ -173,6 +173,8 @@ namespace OpenRA.Mods.Common.Traits firstTick = false; } + protected override void TraitDisabled(Actor self) { Uncloak(); } + public bool IsVisible(Actor self, Player viewer) { if (!Cloaked || self.Owner.IsAlliedWith(viewer)) diff --git a/OpenRA.Mods.Common/Traits/ExternalCaptures.cs b/OpenRA.Mods.Common/Traits/ExternalCaptures.cs index 5dca4b7232..de3750efe8 100644 --- a/OpenRA.Mods.Common/Traits/ExternalCaptures.cs +++ b/OpenRA.Mods.Common/Traits/ExternalCaptures.cs @@ -34,6 +34,10 @@ namespace OpenRA.Mods.Common.Traits [VoiceReference] public readonly string Voice = "Action"; + [GrantedConditionReference] + [Desc("Condition granted when capturing.")] + public readonly string CapturingCondition = null; + public readonly string CaptureCursor = "ability"; public readonly string CaptureBlockedCursor = "move-blocked";