Fix #2086 - don't let player capture if that same player (or friendly ally) is already capturing

This commit is contained in:
Curtis Shmyr
2012-05-01 21:01:40 -06:00
committed by Chris Forbes
parent 5dd46b1b16
commit e1907364e6
3 changed files with 40 additions and 16 deletions

View File

@@ -28,8 +28,13 @@ namespace OpenRA.Mods.RA.Activities
if( !target.OccupiesSpace.OccupiedCells().Any( x => x.First == self.Location ) ) if( !target.OccupiesSpace.OccupiedCells().Any( x => x.First == self.Location ) )
return NextActivity; return NextActivity;
var capturable = target.TraitOrDefault<Capturable>();
if (capturable != null && capturable.CaptureInProgress && capturable.Captor.Owner.Stances[self.Owner] == Stance.Ally)
return NextActivity;
var sellable = target.TraitOrDefault<Sellable>(); var sellable = target.TraitOrDefault<Sellable>();
if (sellable != null && sellable.Selling) return NextActivity; if (sellable != null && sellable.Selling)
return NextActivity;
target.Trait<Capturable>().BeginCapture(target, self); target.Trait<Capturable>().BeginCapture(target, self);
self.World.AddFrameEndTask(w => self.Destroy()); self.World.AddFrameEndTask(w => self.Destroy());

View File

@@ -27,9 +27,9 @@ namespace OpenRA.Mods.RA
public class Capturable : ITick public class Capturable : ITick
{ {
[Sync] Actor captor = null; [Sync] public Actor Captor = null;
[Sync] public int CaptureProgressTime = 0; [Sync] public int CaptureProgressTime = 0;
public bool CaptureInProgress { get { return captor != null; } } public bool CaptureInProgress { get { return Captor != null; } }
public CapturableInfo Info; public CapturableInfo Info;
public Capturable(CapturableInfo info) public Capturable(CapturableInfo info)
@@ -41,10 +41,12 @@ namespace OpenRA.Mods.RA
{ {
CaptureProgressTime = 0; CaptureProgressTime = 0;
this.captor = captor; this.Captor = captor;
if (self.Owner != self.World.WorldActor.Owner) if (self.Owner != self.World.WorldActor.Owner)
{
self.ChangeOwner(self.World.WorldActor.Owner); self.ChangeOwner(self.World.WorldActor.Owner);
}
} }
public void Tick(Actor self) public void Tick(Actor self)
@@ -57,15 +59,15 @@ namespace OpenRA.Mods.RA
{ {
self.World.AddFrameEndTask(w => self.World.AddFrameEndTask(w =>
{ {
self.ChangeOwner(captor.Owner); self.ChangeOwner(Captor.Owner);
foreach (var t in self.TraitsImplementing<INotifyCapture>()) foreach (var t in self.TraitsImplementing<INotifyCapture>())
t.OnCapture(self, captor, self.Owner, captor.Owner); t.OnCapture(self, Captor, self.Owner, Captor.Owner);
foreach (var t in captor.World.ActorsWithTrait<INotifyOtherCaptured>()) foreach (var t in Captor.World.ActorsWithTrait<INotifyOtherCaptured>())
t.Trait.OnActorCaptured(t.Actor, self, captor, self.Owner, captor.Owner); t.Trait.OnActorCaptured(t.Actor, self, Captor, self.Owner, Captor.Owner);
captor = null; Captor = null;
}); });
} }
} }

View File

@@ -8,6 +8,7 @@
*/ */
#endregion #endregion
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
@@ -21,14 +22,17 @@ namespace OpenRA.Mods.RA
class CapturesInfo : ITraitInfo class CapturesInfo : ITraitInfo
{ {
public string[] CaptureTypes = {"building"}; 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 class Captures : IIssueOrder, IResolveOrder, IOrderVoice
{ {
public readonly CapturesInfo Info; public readonly CapturesInfo Info;
public Captures(CapturesInfo info) readonly Actor self;
public Captures(Actor self, CapturesInfo info)
{ {
this.self = self;
Info = info; Info = info;
} }
@@ -36,7 +40,7 @@ namespace OpenRA.Mods.RA
{ {
get 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) 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) public void ResolveOrder(Actor self, Order order)
{ {
if (order.OrderString == "CaptureActor") if (order.OrderString == "CaptureActor")
{ {
if (!CanEnter(order.TargetActor)) return;
self.SetTargetLine(Target.FromOrder(order), Color.Red); self.SetTargetLine(Target.FromOrder(order), Color.Red);
self.CancelActivity(); self.CancelActivity();
@@ -64,15 +71,24 @@ namespace OpenRA.Mods.RA
self.QueueActivity(new CaptureActor(order.TargetActor)); self.QueueActivity(new CaptureActor(order.TargetActor));
} }
} }
bool CanEnter(Actor target)
{
var c = target.TraitOrDefault<Capturable>();
return c != null && ( !c.CaptureInProgress || c.Captor.Owner.Stances[self.Owner] != Stance.Ally );
}
} }
class CaptureOrderTargeter : UnitTraitOrderTargeter<Capturable> class CaptureOrderTargeter : UnitTraitOrderTargeter<Capturable>
{ {
readonly string[] captureTypes; readonly string[] captureTypes;
public CaptureOrderTargeter(string[] captureTypes) readonly Func<Actor, bool> useEnterCursor;
: base( "CaptureActor", 6, "enter", true, true )
public CaptureOrderTargeter(string[] captureTypes, Func<Actor, bool> useEnterCursor)
: base( "CaptureActor", 6, "enter", true, true)
{ {
this.captureTypes = captureTypes; this.captureTypes = captureTypes;
this.useEnterCursor = useEnterCursor;
} }
public override bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceQueued, ref string cursor) 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; if( playerRelationship == Stance.Neutral && !ci.AllowNeutral ) return false;
IsQueued = forceQueued; IsQueued = forceQueued;
if (captureTypes.Contains(ci.Type)) if (captureTypes.Contains(ci.Type))
{ {
cursor = "enter"; cursor = useEnterCursor(target) ? "enter" : "enter-blocked";
return true; return true;
} }