Fix #2086 - don't let player capture if that same player (or friendly ally) is already capturing
This commit is contained in:
committed by
Chris Forbes
parent
5dd46b1b16
commit
e1907364e6
@@ -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());
|
||||||
|
|||||||
@@ -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,11 +41,13 @@ 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;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
public CaptureOrderTargeter(string[] captureTypes, Func<Actor, bool> useEnterCursor)
|
||||||
: base( "CaptureActor", 6, "enter", true, true)
|
: 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user