diff --git a/OpenRA.Mods.RA/Activities/CaptureActor.cs b/OpenRA.Mods.RA/Activities/CaptureActor.cs index 5b82ff672f..dd22a4f412 100644 --- a/OpenRA.Mods.RA/Activities/CaptureActor.cs +++ b/OpenRA.Mods.RA/Activities/CaptureActor.cs @@ -28,8 +28,13 @@ namespace OpenRA.Mods.RA.Activities if( !target.OccupiesSpace.OccupiedCells().Any( x => x.First == self.Location ) ) return NextActivity; + var capturable = target.TraitOrDefault(); + if (capturable != null && capturable.CaptureInProgress && capturable.Captor.Owner.Stances[self.Owner] == Stance.Ally) + return NextActivity; + var sellable = target.TraitOrDefault(); - if (sellable != null && sellable.Selling) return NextActivity; + if (sellable != null && sellable.Selling) + return NextActivity; target.Trait().BeginCapture(target, self); self.World.AddFrameEndTask(w => self.Destroy()); diff --git a/OpenRA.Mods.RA/Capturable.cs b/OpenRA.Mods.RA/Capturable.cs index 2680f2b98b..04091911d3 100644 --- a/OpenRA.Mods.RA/Capturable.cs +++ b/OpenRA.Mods.RA/Capturable.cs @@ -27,9 +27,9 @@ namespace OpenRA.Mods.RA public class Capturable : ITick { - [Sync] Actor captor = null; + [Sync] public Actor Captor = null; [Sync] public int CaptureProgressTime = 0; - public bool CaptureInProgress { get { return captor != null; } } + public bool CaptureInProgress { get { return Captor != null; } } public CapturableInfo Info; public Capturable(CapturableInfo info) @@ -41,10 +41,12 @@ namespace OpenRA.Mods.RA { CaptureProgressTime = 0; - this.captor = captor; + this.Captor = captor; if (self.Owner != self.World.WorldActor.Owner) + { self.ChangeOwner(self.World.WorldActor.Owner); + } } public void Tick(Actor self) @@ -57,15 +59,15 @@ namespace OpenRA.Mods.RA { self.World.AddFrameEndTask(w => { - self.ChangeOwner(captor.Owner); + self.ChangeOwner(Captor.Owner); foreach (var t in self.TraitsImplementing()) - t.OnCapture(self, captor, self.Owner, captor.Owner); + t.OnCapture(self, Captor, self.Owner, Captor.Owner); - foreach (var t in captor.World.ActorsWithTrait()) - t.Trait.OnActorCaptured(t.Actor, self, captor, self.Owner, captor.Owner); + foreach (var t in Captor.World.ActorsWithTrait()) + t.Trait.OnActorCaptured(t.Actor, self, Captor, self.Owner, Captor.Owner); - captor = null; + Captor = null; }); } } diff --git a/OpenRA.Mods.RA/Captures.cs b/OpenRA.Mods.RA/Captures.cs index f7baa8e191..375a840a88 100644 --- a/OpenRA.Mods.RA/Captures.cs +++ b/OpenRA.Mods.RA/Captures.cs @@ -8,6 +8,7 @@ */ #endregion +using System; using System.Collections.Generic; using System.Drawing; using System.Linq; @@ -21,14 +22,17 @@ namespace OpenRA.Mods.RA class CapturesInfo : ITraitInfo { public string[] CaptureTypes = {"building"}; - public object Create(ActorInitializer init) { return new Captures(this); } + public object Create(ActorInitializer init) { return new Captures(init.self, this); } } class Captures : IIssueOrder, IResolveOrder, IOrderVoice { public readonly CapturesInfo Info; - public Captures(CapturesInfo info) + readonly Actor self; + + public Captures(Actor self, CapturesInfo info) { + this.self = self; Info = info; } @@ -36,7 +40,7 @@ namespace OpenRA.Mods.RA { get { - yield return new CaptureOrderTargeter(Info.CaptureTypes); + yield return new CaptureOrderTargeter(Info.CaptureTypes, target => CanEnter(target)); } } @@ -50,13 +54,16 @@ namespace OpenRA.Mods.RA public string VoicePhraseForOrder(Actor self, Order order) { - return (order.OrderString == "CaptureActor") ? "Attack" : null; + return (order.OrderString == "CaptureActor" + && CanEnter(order.TargetActor)) ? "Attack" : null; } public void ResolveOrder(Actor self, Order order) { if (order.OrderString == "CaptureActor") { + if (!CanEnter(order.TargetActor)) return; + self.SetTargetLine(Target.FromOrder(order), Color.Red); self.CancelActivity(); @@ -64,15 +71,24 @@ namespace OpenRA.Mods.RA self.QueueActivity(new CaptureActor(order.TargetActor)); } } + + bool CanEnter(Actor target) + { + var c = target.TraitOrDefault(); + return c != null && ( !c.CaptureInProgress || c.Captor.Owner.Stances[self.Owner] != Stance.Ally ); + } } class CaptureOrderTargeter : UnitTraitOrderTargeter { readonly string[] captureTypes; - public CaptureOrderTargeter(string[] captureTypes) - : base( "CaptureActor", 6, "enter", true, true ) + readonly Func useEnterCursor; + + public CaptureOrderTargeter(string[] captureTypes, Func useEnterCursor) + : base( "CaptureActor", 6, "enter", true, true) { this.captureTypes = captureTypes; + this.useEnterCursor = useEnterCursor; } public override bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceQueued, ref string cursor) @@ -87,9 +103,10 @@ namespace OpenRA.Mods.RA if( playerRelationship == Stance.Neutral && !ci.AllowNeutral ) return false; IsQueued = forceQueued; + if (captureTypes.Contains(ci.Type)) { - cursor = "enter"; + cursor = useEnterCursor(target) ? "enter" : "enter-blocked"; return true; }