diff --git a/OpenRA.Mods.RA/Activities/LegacyCaptureActor.cs b/OpenRA.Mods.RA/Activities/LegacyCaptureActor.cs index 8c2fb6d2ea..a2ba106cca 100644 --- a/OpenRA.Mods.RA/Activities/LegacyCaptureActor.cs +++ b/OpenRA.Mods.RA/Activities/LegacyCaptureActor.cs @@ -9,9 +9,9 @@ #endregion using System.Linq; -using OpenRA.Traits; -using OpenRA.Mods.RA.Move; using OpenRA.Mods.RA.Buildings; +using OpenRA.Mods.RA.Move; +using OpenRA.Traits; namespace OpenRA.Mods.RA.Activities { @@ -26,26 +26,27 @@ namespace OpenRA.Mods.RA.Activities if (IsCanceled || target.Type != TargetType.Actor) return NextActivity; - var b = target.Actor.TraitOrDefault(); + var actor = target.Actor; + var b = actor.TraitOrDefault(); if (b != null && b.Locked) return NextActivity; var capturesInfo = self.Info.Traits.Get(); - var capturableInfo = target.Actor.Info.Traits.Get(); + var capturableInfo = actor.Info.Traits.Get(); - var health = target.Actor.Trait(); + var health = actor.Trait(); self.World.AddFrameEndTask(w => { 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()) - t.OnCapture(target.Actor, self, oldOwner, self.Owner); + foreach (var t in actor.TraitsImplementing()) + t.OnCapture(actor, self, oldOwner, self.Owner); if (b != null && b.Locked) b.Unlock(); @@ -53,7 +54,7 @@ namespace OpenRA.Mods.RA.Activities else { var damage = (int)(health.MaxHP * capturesInfo.SabotageHPRemoval); - target.Actor.InflictDamage(self, damage, null); + actor.InflictDamage(self, damage, null); } self.Destroy(); diff --git a/OpenRA.Mods.RA/LegacyCapturable.cs b/OpenRA.Mods.RA/LegacyCapturable.cs index 639dbddbb4..3375d1d024 100644 --- a/OpenRA.Mods.RA/LegacyCapturable.cs +++ b/OpenRA.Mods.RA/LegacyCapturable.cs @@ -15,7 +15,7 @@ using OpenRA.FileFormats; namespace OpenRA.Mods.RA { [Desc("This actor can be captured by a unit with LegacyCaptures: trait.")] - class LegacyCapturableInfo : ITraitInfo + class LegacyCapturableInfo : TraitInfo { [Desc("Type of actor (the LegacyCaptures: trait defines what Types it can capture).")] 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.")] public readonly float CaptureThreshold = 0.5f; - public object Create(ActorInitializer init) { return new LegacyCapturable(init.self, this); } - } - - class LegacyCapturable - { - [Sync] Actor self; - public LegacyCapturableInfo Info; - - public LegacyCapturable(Actor self, LegacyCapturableInfo info) - { - this.self = self; - Info = info; - } - - public bool CanBeTargetedBy(Actor captor) + public bool CanBeTargetedBy(Actor captor, Player owner) { var c = captor.TraitOrDefault(); if (c == null) return false; - var playerRelationship = self.Owner.Stances[captor.Owner]; - if (playerRelationship == Stance.Ally && !Info.AllowAllies) + var playerRelationship = owner.Stances[captor.Owner]; + if (playerRelationship == Stance.Ally && !AllowAllies) return false; - if (playerRelationship == Stance.Enemy && !Info.AllowEnemies) + if (playerRelationship == Stance.Enemy && !AllowEnemies) return false; - if (playerRelationship == Stance.Neutral && !Info.AllowNeutral) + if (playerRelationship == Stance.Neutral && !AllowNeutral) return false; - if (!c.Info.CaptureTypes.Contains(Info.Type)) + if (!c.Info.CaptureTypes.Contains(Type)) return false; return true; } } + + class LegacyCapturable { } } diff --git a/OpenRA.Mods.RA/LegacyCaptures.cs b/OpenRA.Mods.RA/LegacyCaptures.cs index e07b75afeb..8193145f8a 100644 --- a/OpenRA.Mods.RA/LegacyCaptures.cs +++ b/OpenRA.Mods.RA/LegacyCaptures.cs @@ -12,11 +12,11 @@ using System; using System.Collections.Generic; using System.Drawing; using System.Linq; +using OpenRA.FileFormats; using OpenRA.Mods.RA.Activities; using OpenRA.Mods.RA.Buildings; using OpenRA.Mods.RA.Orders; using OpenRA.Traits; -using OpenRA.FileFormats; namespace OpenRA.Mods.RA { @@ -36,11 +36,9 @@ namespace OpenRA.Mods.RA class LegacyCaptures : IIssueOrder, IResolveOrder, IOrderVoice { public readonly LegacyCapturesInfo Info; - readonly Actor self; public LegacyCaptures(Actor self, LegacyCapturesInfo info) { - this.self = self; Info = info; } @@ -48,73 +46,85 @@ namespace OpenRA.Mods.RA { get { - yield return new LegacyCaptureOrderTargeter(CanCapture); + yield return new LegacyCaptureOrderTargeter(Info.Sabotage); } } public Order IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued) { - if (order.OrderID == "LegacyCaptureActor") - return new Order(order.OrderID, self, queued) { TargetActor = target.Actor }; + if (order.OrderID != "LegacyCaptureActor") + 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) { - return (order.OrderString == "LegacyCaptureActor") ? "Attack" : null; + return order.OrderString == "LegacyCaptureActor" ? "Attack" : null; } public void ResolveOrder(Actor self, Order order) { - if (order.OrderString == "LegacyCaptureActor") - { - self.SetTargetLine(Target.FromOrder(order), Color.Red); + if (order.OrderString != "LegacyCaptureActor") + return; + var target = self.ResolveFrozenActorOrder(order, Color.Red); + if (target.Type != TargetType.Actor) + return; + + if (!order.Queued) self.CancelActivity(); - self.QueueActivity(new Enter(order.TargetActor, new LegacyCaptureActor(Target.FromOrder(order)))); - } - } - bool CanCapture(Actor target) - { - var c = target.TraitOrDefault(); - return c != null && c.CanBeTargetedBy(self); + self.SetTargetLine(target, Color.Red); + self.QueueActivity(new Enter(target.Actor, new LegacyCaptureActor(target))); } class LegacyCaptureOrderTargeter : UnitOrderTargeter { - readonly Func useCaptureCursor; + readonly bool sabotage; - public LegacyCaptureOrderTargeter(Func useCaptureCursor) + public LegacyCaptureOrderTargeter(bool sabotage) : 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) { - var canTargetActor = useCaptureCursor(target); - - if (canTargetActor) + var c = target.Info.Traits.GetOrDefault(); + if (c == null || !c.CanBeTargetedBy(self, target.Owner)) { - var c = target.Trait(); - var health = target.Trait(); - var lowEnoughHealth = health.HP <= c.Info.CaptureThreshold * health.MaxHP; - - cursor = lowEnoughHealth ? "enter" : "capture"; - - return true; + cursor = "enter-blocked"; + return false; } - cursor = "enter-blocked"; - return false; + var health = target.Trait(); + 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) { - // TODO: Not yet supported - return false; + var c = target.Info.Traits.GetOrDefault(); + if (c == null || !c.CanBeTargetedBy(self, target.Owner)) + { + cursor = "enter-blocked"; + return false; + } + + var health = target.Info.Traits.GetOrDefault(); + var lowEnoughHealth = target.HP <= c.CaptureThreshold * health.HP; + + cursor = !sabotage || lowEnoughHealth || target.Owner.NonCombatant + ? "capture" : "enter"; + + return true; } } }