diff --git a/OpenRA.Mods.Common/Activities/CaptureActor.cs b/OpenRA.Mods.Common/Activities/CaptureActor.cs index a01fdee402..6d5b688bf7 100644 --- a/OpenRA.Mods.Common/Activities/CaptureActor.cs +++ b/OpenRA.Mods.Common/Activities/CaptureActor.cs @@ -9,6 +9,8 @@ */ #endregion +using System.Linq; +using OpenRA.Activities; using OpenRA.Mods.Common.Traits; using OpenRA.Traits; @@ -19,7 +21,7 @@ namespace OpenRA.Mods.Common.Activities readonly Actor actor; readonly Building building; readonly Capturable capturable; - readonly CapturesInfo capturesInfo; + readonly Captures[] captures; readonly Health health; public CaptureActor(Actor self, Actor target) @@ -27,7 +29,7 @@ namespace OpenRA.Mods.Common.Activities { actor = target; building = actor.TraitOrDefault(); - capturesInfo = self.Info.TraitInfo(); + captures = self.TraitsImplementing().ToArray(); capturable = target.Trait(); health = actor.Trait(); } @@ -50,9 +52,12 @@ namespace OpenRA.Mods.Common.Activities if (building != null && building.Locked) building.Unlock(); - if (actor.IsDead || capturable.BeingCaptured) + var activeCaptures = captures.FirstOrDefault(c => !c.IsTraitDisabled); + + if (actor.IsDead || capturable.BeingCaptured || activeCaptures == null) return; + var capturesInfo = activeCaptures.Info; var lowEnoughHealth = health.HP <= capturable.Info.CaptureThreshold * health.MaxHP / 100; if (!capturesInfo.Sabotage || lowEnoughHealth || actor.Owner.NonCombatant) { @@ -82,5 +87,13 @@ namespace OpenRA.Mods.Common.Activities self.Dispose(); }); } + + public override Activity Tick(Actor self) + { + if (captures.All(c => c.IsTraitDisabled)) + Cancel(self); + + return base.Tick(self); + } } } diff --git a/OpenRA.Mods.Common/Scripting/Properties/CaptureProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/CaptureProperties.cs index d4ab60c818..821d843d82 100644 --- a/OpenRA.Mods.Common/Scripting/Properties/CaptureProperties.cs +++ b/OpenRA.Mods.Common/Scripting/Properties/CaptureProperties.cs @@ -9,6 +9,8 @@ */ #endregion +using System.Collections.Generic; +using System.Linq; using Eluant; using OpenRA.Mods.Common.Activities; using OpenRA.Mods.Common.Traits; @@ -20,25 +22,33 @@ namespace OpenRA.Mods.Common.Scripting [ScriptPropertyGroup("Ability")] public class CaptureProperties : ScriptActorProperties { - readonly CapturesInfo normalInfo; + readonly Captures[] captures; readonly ExternalCapturesInfo externalInfo; public CaptureProperties(ScriptContext context, Actor self) : base(context, self) { - normalInfo = Self.Info.TraitInfoOrDefault(); + captures = Self.TraitsImplementing().ToArray(); externalInfo = Self.Info.TraitInfoOrDefault(); } [Desc("Captures the target actor.")] public void Capture(Actor target) { - var normalCapturable = target.Info.TraitInfoOrDefault(); + var capturable = target.Info.TraitInfoOrDefault(); + + if (capturable != null) + { + if (captures.Any(x => !x.IsTraitDisabled && x.Info.CaptureTypes.Contains(capturable.Type))) + { + Self.QueueActivity(new CaptureActor(Self, target)); + return; + } + } + var externalCapturable = target.Info.TraitInfoOrDefault(); - if (normalInfo != null && normalCapturable != null && normalInfo.CaptureTypes.Contains(normalCapturable.Type)) - Self.QueueActivity(new CaptureActor(Self, target)); - else if (externalInfo != null && externalCapturable != null && externalInfo.CaptureTypes.Contains(externalCapturable.Type)) + if (externalInfo != null && externalCapturable != null && externalInfo.CaptureTypes.Contains(externalCapturable.Type)) Self.QueueActivity(new ExternalCaptureActor(Self, Target.FromActor(target))); else throw new LuaException("Actor '{0}' cannot capture actor '{1}'!".F(Self, target)); diff --git a/OpenRA.Mods.Common/Traits/Captures.cs b/OpenRA.Mods.Common/Traits/Captures.cs index 1db3c86740..20ddb0adfa 100644 --- a/OpenRA.Mods.Common/Traits/Captures.cs +++ b/OpenRA.Mods.Common/Traits/Captures.cs @@ -18,7 +18,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { [Desc("This actor can capture other actors which have the Capturable: trait.")] - public class CapturesInfo : ITraitInfo + public class CapturesInfo : ConditionalTraitInfo { [Desc("Types of actors that it can capture, as long as the type also exists in the Capturable Type: trait.")] public readonly HashSet CaptureTypes = new HashSet { "building" }; @@ -41,22 +41,21 @@ namespace OpenRA.Mods.Common.Traits [VoiceReference] public readonly string Voice = "Action"; - public object Create(ActorInitializer init) { return new Captures(this); } + public override object Create(ActorInitializer init) { return new Captures(this); } } - public class Captures : IIssueOrder, IResolveOrder, IOrderVoice + public class Captures : ConditionalTrait, IIssueOrder, IResolveOrder, IOrderVoice { - public readonly CapturesInfo Info; - public Captures(CapturesInfo info) - { - Info = info; - } + : base(info) { } public IEnumerable Orders { get { + if (IsTraitDisabled) + yield break; + yield return new CaptureOrderTargeter(Info); } } @@ -79,7 +78,7 @@ namespace OpenRA.Mods.Common.Traits public void ResolveOrder(Actor self, Order order) { - if (order.OrderString != "CaptureActor") + if (order.OrderString != "CaptureActor" || IsTraitDisabled) return; var target = self.ResolveFrozenActorOrder(order, Color.Red);