From 4783b1f64692eba4f7893f87848504144204e871 Mon Sep 17 00:00:00 2001 From: atlimit8 Date: Sat, 4 Oct 2014 10:05:33 -0500 Subject: [PATCH] CaptureActor as Enter subclass & fixes 6658 --- OpenRA.Mods.RA/Activities/CaptureActor.cs | 49 +++++++++++++---------- OpenRA.Mods.RA/Activities/Enter.cs | 3 +- OpenRA.Mods.RA/Capturable.cs | 16 ++++++-- OpenRA.Mods.RA/Captures.cs | 2 +- 4 files changed, 43 insertions(+), 27 deletions(-) diff --git a/OpenRA.Mods.RA/Activities/CaptureActor.cs b/OpenRA.Mods.RA/Activities/CaptureActor.cs index 0e24d260c2..33f0af15b7 100644 --- a/OpenRA.Mods.RA/Activities/CaptureActor.cs +++ b/OpenRA.Mods.RA/Activities/CaptureActor.cs @@ -13,36 +13,45 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Activities { - class CaptureActor : Activity + class CaptureActor : Enter { - Target target; + readonly Actor actor; + readonly Capturable capturable; + readonly CapturesInfo capturesInfo; - public CaptureActor(Target target) { this.target = target; } - - public override Activity Tick(Actor self) + public CaptureActor(Actor self, Actor target) + : base(self, target) { - if (IsCanceled || !target.IsValidFor(self)) - return NextActivity; + actor = target; + capturesInfo = self.Info.Traits.Get(); + capturable = target.Trait(); + } - if (target.Type != TargetType.Actor) - return NextActivity; + protected override bool CanReserve(Actor self) + { + return !capturable.BeingCaptured && capturable.Info.CanBeTargetedBy(self, actor.Owner); + } + + protected override void OnInside(Actor self) + { + if (actor.IsDead() || capturable.BeingCaptured) + return; - var actor = target.Actor; var b = actor.TraitOrDefault(); - if (b != null && b.Locked) - return NextActivity; - - var capturesInfo = self.Info.Traits.Get(); - var capturableInfo = actor.Info.Traits.Get(); - - var health = actor.Trait(); + if (b != null && !b.Lock()) + return; self.World.AddFrameEndTask(w => { - if (actor.IsDead()) + if (b != null && b.Locked) + b.Unlock(); + + if (actor.IsDead() || capturable.BeingCaptured) return; - var lowEnoughHealth = health.HP <= capturableInfo.CaptureThreshold * health.MaxHP; + var health = actor.Trait(); + + var lowEnoughHealth = health.HP <= capturable.Info.CaptureThreshold * health.MaxHP; if (!capturesInfo.Sabotage || lowEnoughHealth || actor.Owner.NonCombatant) { var oldOwner = actor.Owner; @@ -63,8 +72,6 @@ namespace OpenRA.Mods.RA.Activities self.Destroy(); }); - - return this; } } } diff --git a/OpenRA.Mods.RA/Activities/Enter.cs b/OpenRA.Mods.RA/Activities/Enter.cs index 9a699b862b..5a648bb647 100755 --- a/OpenRA.Mods.RA/Activities/Enter.cs +++ b/OpenRA.Mods.RA/Activities/Enter.cs @@ -24,6 +24,7 @@ namespace OpenRA.Mods.RA.Activities readonly Activity inside; readonly IMove move; readonly int maxTries = 0; + public Target Target { get { return target; } } Target target; State nextState = State.ApproachingOrEntering; // Hint/starting point for next state bool isEnteringOrInside = false; // Used to know if exiting should be used @@ -97,7 +98,6 @@ namespace OpenRA.Mods.RA.Activities inner.Cancel(self); if (isEnteringOrInside) Unreserve(self, true); - isEnteringOrInside = false; } // Cancel inner activity and mark as done unless already leaving or done @@ -178,6 +178,7 @@ namespace OpenRA.Mods.RA.Activities // Entering isEnteringOrInside = true; savedPos = self.CenterPosition; // Save position of self, before entering, for returning on exit + inner = move.MoveIntoTarget(self, target); // Enter if (inner != null) diff --git a/OpenRA.Mods.RA/Capturable.cs b/OpenRA.Mods.RA/Capturable.cs index b8dcf3600e..ef186484a5 100644 --- a/OpenRA.Mods.RA/Capturable.cs +++ b/OpenRA.Mods.RA/Capturable.cs @@ -14,9 +14,9 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA { [Desc("This actor can be captured by a unit with Captures: trait.")] - class CapturableInfo : TraitInfo + class CapturableInfo : ITraitInfo { - [Desc("Type of actor (the Captures: trait defines what Types it can capture).")] + [Desc("Type listed under Types in Captures: trait of actors that can capture this).")] public readonly string Type = "building"; public readonly bool AllowAllies = false; public readonly bool AllowNeutral = true; @@ -25,6 +25,8 @@ namespace OpenRA.Mods.RA public readonly float CaptureThreshold = 0.5f; public readonly bool CancelActivity = false; + public object Create(ActorInitializer init) { return new Capturable(this); } + public bool CanBeTargetedBy(Actor captor, Player owner) { var c = captor.TraitOrDefault(); @@ -50,10 +52,16 @@ namespace OpenRA.Mods.RA class Capturable : INotifyCapture { + public readonly CapturableInfo Info; + public bool BeingCaptured { get; private set; } + public Capturable(CapturableInfo info) { Info = info; } + public void OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner) { - var info = self.Info.Traits.Get(); - if (info.CancelActivity) + BeingCaptured = true; + self.World.AddFrameEndTask(w => BeingCaptured = false); + + if (Info.CancelActivity) { var stop = new Order("Stop", self, false); foreach (var t in self.TraitsImplementing()) diff --git a/OpenRA.Mods.RA/Captures.cs b/OpenRA.Mods.RA/Captures.cs index 5b5b9d6e05..c4ff5de9da 100644 --- a/OpenRA.Mods.RA/Captures.cs +++ b/OpenRA.Mods.RA/Captures.cs @@ -75,7 +75,7 @@ namespace OpenRA.Mods.RA self.CancelActivity(); self.SetTargetLine(target, Color.Red); - self.QueueActivity(new Enter(self, target.Actor, new CaptureActor(target))); + self.QueueActivity(new CaptureActor(self, target.Actor)); } class CaptureOrderTargeter : UnitOrderTargeter