CaptureActor as Enter subclass & fixes 6658
This commit is contained in:
@@ -13,36 +13,45 @@ using OpenRA.Traits;
|
||||
|
||||
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 override Activity Tick(Actor self)
|
||||
public CaptureActor(Actor self, Actor target)
|
||||
: base(self, target)
|
||||
{
|
||||
if (IsCanceled || !target.IsValidFor(self))
|
||||
return NextActivity;
|
||||
actor = target;
|
||||
capturesInfo = self.Info.Traits.Get<CapturesInfo>();
|
||||
capturable = target.Trait<Capturable>();
|
||||
}
|
||||
|
||||
if (target.Type != TargetType.Actor)
|
||||
return NextActivity;
|
||||
protected override bool CanReserve(Actor self)
|
||||
{
|
||||
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>();
|
||||
if (b != null && b.Locked)
|
||||
return NextActivity;
|
||||
|
||||
var capturesInfo = self.Info.Traits.Get<CapturesInfo>();
|
||||
var capturableInfo = actor.Info.Traits.Get<CapturableInfo>();
|
||||
|
||||
var health = actor.Trait<Health>();
|
||||
if (b != null && !b.Lock())
|
||||
return;
|
||||
|
||||
self.World.AddFrameEndTask(w =>
|
||||
{
|
||||
if (actor.IsDead())
|
||||
if (b != null && b.Locked)
|
||||
b.Unlock();
|
||||
|
||||
if (actor.IsDead() || capturable.BeingCaptured)
|
||||
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)
|
||||
{
|
||||
var oldOwner = actor.Owner;
|
||||
@@ -63,8 +72,6 @@ namespace OpenRA.Mods.RA.Activities
|
||||
|
||||
self.Destroy();
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace OpenRA.Mods.RA.Activities
|
||||
readonly Activity inside;
|
||||
readonly IMove move;
|
||||
readonly int maxTries = 0;
|
||||
public Target Target { get { return target; } }
|
||||
Target target;
|
||||
State nextState = State.ApproachingOrEntering; // Hint/starting point for next state
|
||||
bool isEnteringOrInside = false; // Used to know if exiting should be used
|
||||
@@ -97,7 +98,6 @@ namespace OpenRA.Mods.RA.Activities
|
||||
inner.Cancel(self);
|
||||
if (isEnteringOrInside)
|
||||
Unreserve(self, true);
|
||||
isEnteringOrInside = false;
|
||||
}
|
||||
|
||||
// Cancel inner activity and mark as done unless already leaving or done
|
||||
@@ -178,6 +178,7 @@ namespace OpenRA.Mods.RA.Activities
|
||||
// Entering
|
||||
isEnteringOrInside = true;
|
||||
savedPos = self.CenterPosition; // Save position of self, before entering, for returning on exit
|
||||
|
||||
inner = move.MoveIntoTarget(self, target); // Enter
|
||||
|
||||
if (inner != null)
|
||||
|
||||
@@ -14,9 +14,9 @@ using OpenRA.Traits;
|
||||
namespace OpenRA.Mods.RA
|
||||
{
|
||||
[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 bool AllowAllies = false;
|
||||
public readonly bool AllowNeutral = true;
|
||||
@@ -25,6 +25,8 @@ namespace OpenRA.Mods.RA
|
||||
public readonly float CaptureThreshold = 0.5f;
|
||||
public readonly bool CancelActivity = false;
|
||||
|
||||
public object Create(ActorInitializer init) { return new Capturable(this); }
|
||||
|
||||
public bool CanBeTargetedBy(Actor captor, Player owner)
|
||||
{
|
||||
var c = captor.TraitOrDefault<Captures>();
|
||||
@@ -50,10 +52,16 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
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)
|
||||
{
|
||||
var info = self.Info.Traits.Get<CapturableInfo>();
|
||||
if (info.CancelActivity)
|
||||
BeingCaptured = true;
|
||||
self.World.AddFrameEndTask(w => BeingCaptured = false);
|
||||
|
||||
if (Info.CancelActivity)
|
||||
{
|
||||
var stop = new Order("Stop", self, false);
|
||||
foreach (var t in self.TraitsImplementing<IResolveOrder>())
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace OpenRA.Mods.RA
|
||||
self.CancelActivity();
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user