CaptureActor as Enter subclass & fixes 6658
This commit is contained in:
@@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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>())
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user