CaptureActor as Enter subclass & fixes 6658

This commit is contained in:
atlimit8
2014-10-04 10:05:33 -05:00
parent 268c63f7df
commit 4783b1f646
4 changed files with 43 additions and 27 deletions

View File

@@ -13,36 +13,45 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities 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 CaptureActor(Actor self, Actor target)
: base(self, target)
public override Activity Tick(Actor self)
{ {
if (IsCanceled || !target.IsValidFor(self)) actor = target;
return NextActivity; capturesInfo = self.Info.Traits.Get<CapturesInfo>();
capturable = target.Trait<Capturable>();
}
if (target.Type != TargetType.Actor) protected override bool CanReserve(Actor self)
return NextActivity; {
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<Building>(); var b = actor.TraitOrDefault<Building>();
if (b != null && b.Locked) if (b != null && !b.Lock())
return NextActivity; return;
var capturesInfo = self.Info.Traits.Get<CapturesInfo>();
var capturableInfo = actor.Info.Traits.Get<CapturableInfo>();
var health = actor.Trait<Health>();
self.World.AddFrameEndTask(w => self.World.AddFrameEndTask(w =>
{ {
if (actor.IsDead()) if (b != null && b.Locked)
b.Unlock();
if (actor.IsDead() || capturable.BeingCaptured)
return; return;
var lowEnoughHealth = health.HP <= capturableInfo.CaptureThreshold * health.MaxHP; var health = actor.Trait<Health>();
var lowEnoughHealth = health.HP <= capturable.Info.CaptureThreshold * health.MaxHP;
if (!capturesInfo.Sabotage || lowEnoughHealth || actor.Owner.NonCombatant) if (!capturesInfo.Sabotage || lowEnoughHealth || actor.Owner.NonCombatant)
{ {
var oldOwner = actor.Owner; var oldOwner = actor.Owner;
@@ -63,8 +72,6 @@ namespace OpenRA.Mods.RA.Activities
self.Destroy(); self.Destroy();
}); });
return this;
} }
} }
} }

View File

@@ -24,6 +24,7 @@ namespace OpenRA.Mods.RA.Activities
readonly Activity inside; readonly Activity inside;
readonly IMove move; readonly IMove move;
readonly int maxTries = 0; readonly int maxTries = 0;
public Target Target { get { return target; } }
Target target; Target target;
State nextState = State.ApproachingOrEntering; // Hint/starting point for next state State nextState = State.ApproachingOrEntering; // Hint/starting point for next state
bool isEnteringOrInside = false; // Used to know if exiting should be used bool isEnteringOrInside = false; // Used to know if exiting should be used
@@ -97,7 +98,6 @@ namespace OpenRA.Mods.RA.Activities
inner.Cancel(self); inner.Cancel(self);
if (isEnteringOrInside) if (isEnteringOrInside)
Unreserve(self, true); Unreserve(self, true);
isEnteringOrInside = false;
} }
// Cancel inner activity and mark as done unless already leaving or done // Cancel inner activity and mark as done unless already leaving or done
@@ -178,6 +178,7 @@ namespace OpenRA.Mods.RA.Activities
// Entering // Entering
isEnteringOrInside = true; isEnteringOrInside = true;
savedPos = self.CenterPosition; // Save position of self, before entering, for returning on exit savedPos = self.CenterPosition; // Save position of self, before entering, for returning on exit
inner = move.MoveIntoTarget(self, target); // Enter inner = move.MoveIntoTarget(self, target); // Enter
if (inner != null) if (inner != null)

View File

@@ -14,9 +14,9 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA namespace OpenRA.Mods.RA
{ {
[Desc("This actor can be captured by a unit with Captures: trait.")] [Desc("This actor can be captured by a unit with Captures: trait.")]
class CapturableInfo : TraitInfo<Capturable> 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 string Type = "building";
public readonly bool AllowAllies = false; public readonly bool AllowAllies = false;
public readonly bool AllowNeutral = true; public readonly bool AllowNeutral = true;
@@ -25,6 +25,8 @@ namespace OpenRA.Mods.RA
public readonly float CaptureThreshold = 0.5f; public readonly float CaptureThreshold = 0.5f;
public readonly bool CancelActivity = false; public readonly bool CancelActivity = false;
public object Create(ActorInitializer init) { return new Capturable(this); }
public bool CanBeTargetedBy(Actor captor, Player owner) public bool CanBeTargetedBy(Actor captor, Player owner)
{ {
var c = captor.TraitOrDefault<Captures>(); var c = captor.TraitOrDefault<Captures>();
@@ -50,10 +52,16 @@ namespace OpenRA.Mods.RA
class Capturable : INotifyCapture 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) public void OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner)
{ {
var info = self.Info.Traits.Get<CapturableInfo>(); BeingCaptured = true;
if (info.CancelActivity) self.World.AddFrameEndTask(w => BeingCaptured = false);
if (Info.CancelActivity)
{ {
var stop = new Order("Stop", self, false); var stop = new Order("Stop", self, false);
foreach (var t in self.TraitsImplementing<IResolveOrder>()) foreach (var t in self.TraitsImplementing<IResolveOrder>())

View File

@@ -75,7 +75,7 @@ namespace OpenRA.Mods.RA
self.CancelActivity(); self.CancelActivity();
self.SetTargetLine(target, Color.Red); 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 class CaptureOrderTargeter : UnitOrderTargeter