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 ) )
|
||||
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>();
|
||||
if (sellable != null && sellable.Selling) return NextActivity;
|
||||
if (sellable != null && sellable.Selling)
|
||||
return NextActivity;
|
||||
|
||||
target.Trait<Capturable>().BeginCapture(target, self);
|
||||
self.World.AddFrameEndTask(w => self.Destroy());
|
||||
|
||||
@@ -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,11 +41,13 @@ 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<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>())
|
||||
t.Trait.OnActorCaptured(t.Actor, self, captor, self.Owner, captor.Owner);
|
||||
foreach (var t in Captor.World.ActorsWithTrait<INotifyOtherCaptured>())
|
||||
t.Trait.OnActorCaptured(t.Actor, self, Captor, self.Owner, Captor.Owner);
|
||||
|
||||
captor = null;
|
||||
Captor = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Capturable>();
|
||||
return c != null && ( !c.CaptureInProgress || c.Captor.Owner.Stances[self.Owner] != Stance.Ally );
|
||||
}
|
||||
}
|
||||
|
||||
class CaptureOrderTargeter : UnitTraitOrderTargeter<Capturable>
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user