Enable frozen order: LegacyCaptureActor.

This commit is contained in:
Paul Chote
2013-08-10 12:06:04 +12:00
parent d27d5f449e
commit f2ecea4731
3 changed files with 66 additions and 67 deletions

View File

@@ -9,9 +9,9 @@
#endregion #endregion
using System.Linq; using System.Linq;
using OpenRA.Traits;
using OpenRA.Mods.RA.Move;
using OpenRA.Mods.RA.Buildings; using OpenRA.Mods.RA.Buildings;
using OpenRA.Mods.RA.Move;
using OpenRA.Traits;
namespace OpenRA.Mods.RA.Activities namespace OpenRA.Mods.RA.Activities
{ {
@@ -26,26 +26,27 @@ namespace OpenRA.Mods.RA.Activities
if (IsCanceled || target.Type != TargetType.Actor) if (IsCanceled || target.Type != TargetType.Actor)
return NextActivity; return NextActivity;
var b = target.Actor.TraitOrDefault<Building>(); var actor = target.Actor;
var b = actor.TraitOrDefault<Building>();
if (b != null && b.Locked) if (b != null && b.Locked)
return NextActivity; return NextActivity;
var capturesInfo = self.Info.Traits.Get<LegacyCapturesInfo>(); var capturesInfo = self.Info.Traits.Get<LegacyCapturesInfo>();
var capturableInfo = target.Actor.Info.Traits.Get<LegacyCapturableInfo>(); var capturableInfo = actor.Info.Traits.Get<LegacyCapturableInfo>();
var health = target.Actor.Trait<Health>(); var health = actor.Trait<Health>();
self.World.AddFrameEndTask(w => self.World.AddFrameEndTask(w =>
{ {
var lowEnoughHealth = health.HP <= capturableInfo.CaptureThreshold * health.MaxHP; var lowEnoughHealth = health.HP <= capturableInfo.CaptureThreshold * health.MaxHP;
if (!capturesInfo.Sabotage || lowEnoughHealth || target.Actor.Owner.NonCombatant) if (!capturesInfo.Sabotage || lowEnoughHealth || actor.Owner.NonCombatant)
{ {
var oldOwner = target.Actor.Owner; var oldOwner = actor.Owner;
target.Actor.ChangeOwner(self.Owner); actor.ChangeOwner(self.Owner);
foreach (var t in target.Actor.TraitsImplementing<INotifyCapture>()) foreach (var t in actor.TraitsImplementing<INotifyCapture>())
t.OnCapture(target.Actor, self, oldOwner, self.Owner); t.OnCapture(actor, self, oldOwner, self.Owner);
if (b != null && b.Locked) if (b != null && b.Locked)
b.Unlock(); b.Unlock();
@@ -53,7 +54,7 @@ namespace OpenRA.Mods.RA.Activities
else else
{ {
var damage = (int)(health.MaxHP * capturesInfo.SabotageHPRemoval); var damage = (int)(health.MaxHP * capturesInfo.SabotageHPRemoval);
target.Actor.InflictDamage(self, damage, null); actor.InflictDamage(self, damage, null);
} }
self.Destroy(); self.Destroy();

View File

@@ -15,7 +15,7 @@ using OpenRA.FileFormats;
namespace OpenRA.Mods.RA namespace OpenRA.Mods.RA
{ {
[Desc("This actor can be captured by a unit with LegacyCaptures: trait.")] [Desc("This actor can be captured by a unit with LegacyCaptures: trait.")]
class LegacyCapturableInfo : ITraitInfo class LegacyCapturableInfo : TraitInfo<LegacyCapturable>
{ {
[Desc("Type of actor (the LegacyCaptures: trait defines what Types it can capture).")] [Desc("Type of actor (the LegacyCaptures: trait defines what Types it can capture).")]
public readonly string Type = "building"; public readonly string Type = "building";
@@ -25,40 +25,28 @@ namespace OpenRA.Mods.RA
[Desc("Health percentage the target must be at (or below) before it can be captured.")] [Desc("Health percentage the target must be at (or below) before it can be captured.")]
public readonly float CaptureThreshold = 0.5f; public readonly float CaptureThreshold = 0.5f;
public object Create(ActorInitializer init) { return new LegacyCapturable(init.self, this); } public bool CanBeTargetedBy(Actor captor, Player owner)
}
class LegacyCapturable
{
[Sync] Actor self;
public LegacyCapturableInfo Info;
public LegacyCapturable(Actor self, LegacyCapturableInfo info)
{
this.self = self;
Info = info;
}
public bool CanBeTargetedBy(Actor captor)
{ {
var c = captor.TraitOrDefault<LegacyCaptures>(); var c = captor.TraitOrDefault<LegacyCaptures>();
if (c == null) if (c == null)
return false; return false;
var playerRelationship = self.Owner.Stances[captor.Owner]; var playerRelationship = owner.Stances[captor.Owner];
if (playerRelationship == Stance.Ally && !Info.AllowAllies) if (playerRelationship == Stance.Ally && !AllowAllies)
return false; return false;
if (playerRelationship == Stance.Enemy && !Info.AllowEnemies) if (playerRelationship == Stance.Enemy && !AllowEnemies)
return false; return false;
if (playerRelationship == Stance.Neutral && !Info.AllowNeutral) if (playerRelationship == Stance.Neutral && !AllowNeutral)
return false; return false;
if (!c.Info.CaptureTypes.Contains(Info.Type)) if (!c.Info.CaptureTypes.Contains(Type))
return false; return false;
return true; return true;
} }
} }
class LegacyCapturable { }
} }

View File

@@ -12,11 +12,11 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
using OpenRA.FileFormats;
using OpenRA.Mods.RA.Activities; using OpenRA.Mods.RA.Activities;
using OpenRA.Mods.RA.Buildings; using OpenRA.Mods.RA.Buildings;
using OpenRA.Mods.RA.Orders; using OpenRA.Mods.RA.Orders;
using OpenRA.Traits; using OpenRA.Traits;
using OpenRA.FileFormats;
namespace OpenRA.Mods.RA namespace OpenRA.Mods.RA
{ {
@@ -36,11 +36,9 @@ namespace OpenRA.Mods.RA
class LegacyCaptures : IIssueOrder, IResolveOrder, IOrderVoice class LegacyCaptures : IIssueOrder, IResolveOrder, IOrderVoice
{ {
public readonly LegacyCapturesInfo Info; public readonly LegacyCapturesInfo Info;
readonly Actor self;
public LegacyCaptures(Actor self, LegacyCapturesInfo info) public LegacyCaptures(Actor self, LegacyCapturesInfo info)
{ {
this.self = self;
Info = info; Info = info;
} }
@@ -48,73 +46,85 @@ namespace OpenRA.Mods.RA
{ {
get get
{ {
yield return new LegacyCaptureOrderTargeter(CanCapture); yield return new LegacyCaptureOrderTargeter(Info.Sabotage);
} }
} }
public Order IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued) public Order IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued)
{ {
if (order.OrderID == "LegacyCaptureActor") if (order.OrderID != "LegacyCaptureActor")
return new Order(order.OrderID, self, queued) { TargetActor = target.Actor }; return null;
return null; if (target.Type == TargetType.FrozenActor)
return new Order(order.OrderID, self, queued) { ExtraData = target.FrozenActor.ID };
return new Order(order.OrderID, self, queued) { TargetActor = target.Actor };
} }
public string VoicePhraseForOrder(Actor self, Order order) public string VoicePhraseForOrder(Actor self, Order order)
{ {
return (order.OrderString == "LegacyCaptureActor") ? "Attack" : null; return order.OrderString == "LegacyCaptureActor" ? "Attack" : null;
} }
public void ResolveOrder(Actor self, Order order) public void ResolveOrder(Actor self, Order order)
{ {
if (order.OrderString == "LegacyCaptureActor") if (order.OrderString != "LegacyCaptureActor")
{ return;
self.SetTargetLine(Target.FromOrder(order), Color.Red);
var target = self.ResolveFrozenActorOrder(order, Color.Red);
if (target.Type != TargetType.Actor)
return;
if (!order.Queued)
self.CancelActivity(); self.CancelActivity();
self.QueueActivity(new Enter(order.TargetActor, new LegacyCaptureActor(Target.FromOrder(order))));
}
}
bool CanCapture(Actor target) self.SetTargetLine(target, Color.Red);
{ self.QueueActivity(new Enter(target.Actor, new LegacyCaptureActor(target)));
var c = target.TraitOrDefault<LegacyCapturable>();
return c != null && c.CanBeTargetedBy(self);
} }
class LegacyCaptureOrderTargeter : UnitOrderTargeter class LegacyCaptureOrderTargeter : UnitOrderTargeter
{ {
readonly Func<Actor, bool> useCaptureCursor; readonly bool sabotage;
public LegacyCaptureOrderTargeter(Func<Actor, bool> useCaptureCursor) public LegacyCaptureOrderTargeter(bool sabotage)
: base("LegacyCaptureActor", 6, "enter", true, true) : base("LegacyCaptureActor", 6, "enter", true, true)
{ {
this.useCaptureCursor = useCaptureCursor; this.sabotage = sabotage;
} }
public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)
{ {
var canTargetActor = useCaptureCursor(target); var c = target.Info.Traits.GetOrDefault<LegacyCapturableInfo>();
if (c == null || !c.CanBeTargetedBy(self, target.Owner))
if (canTargetActor)
{ {
var c = target.Trait<LegacyCapturable>(); cursor = "enter-blocked";
var health = target.Trait<Health>(); return false;
var lowEnoughHealth = health.HP <= c.Info.CaptureThreshold * health.MaxHP;
cursor = lowEnoughHealth ? "enter" : "capture";
return true;
} }
cursor = "enter-blocked"; var health = target.Trait<Health>();
return false; var lowEnoughHealth = health.HP <= c.CaptureThreshold * health.MaxHP;
cursor = !sabotage || lowEnoughHealth || target.Owner.NonCombatant
? "capture" : "enter";
return true;
} }
public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor) public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor)
{ {
// TODO: Not yet supported var c = target.Info.Traits.GetOrDefault<LegacyCapturableInfo>();
return false; if (c == null || !c.CanBeTargetedBy(self, target.Owner))
{
cursor = "enter-blocked";
return false;
}
var health = target.Info.Traits.GetOrDefault<HealthInfo>();
var lowEnoughHealth = target.HP <= c.CaptureThreshold * health.HP;
cursor = !sabotage || lowEnoughHealth || target.Owner.NonCombatant
? "capture" : "enter";
return true;
} }
} }
} }