From 3670c003a40b3cfb2c123bf5cb95275ee2ebe9f8 Mon Sep 17 00:00:00 2001 From: Zimmermann Gyula Date: Thu, 20 Aug 2015 17:05:25 +0200 Subject: [PATCH] Prevent infiltrating allied targets unless explicitly set. --- OpenRA.Mods.RA/Activities/Infiltrate.cs | 11 ++++- .../Traits/Infiltration/Infiltrates.cs | 44 ++++++++++++++++--- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/OpenRA.Mods.RA/Activities/Infiltrate.cs b/OpenRA.Mods.RA/Activities/Infiltrate.cs index 325eff1903..4e566770a6 100644 --- a/OpenRA.Mods.RA/Activities/Infiltrate.cs +++ b/OpenRA.Mods.RA/Activities/Infiltrate.cs @@ -10,6 +10,7 @@ using OpenRA.Mods.Common.Activities; using OpenRA.Mods.Common.Traits; +using OpenRA.Mods.RA.Traits; using OpenRA.Traits; namespace OpenRA.Mods.RA.Activities @@ -20,17 +21,25 @@ namespace OpenRA.Mods.RA.Activities readonly Cloak cloak; + readonly Infiltrates infiltrates; + public Infiltrate(Actor self, Actor target) : base(self, target) { this.target = target; cloak = self.TraitOrDefault(); + + infiltrates = self.TraitOrDefault(); } protected override void OnInside(Actor self) { - if (target.IsDead || target.Owner == self.Owner) + if (target.IsDead) + return; + + var stance = self.Owner.Stances[target.Owner]; + if (!infiltrates.Info.ValidStances.HasStance(stance)) return; if (cloak != null && cloak.Info.UncloakOnInfiltrate) diff --git a/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs b/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs index dbdfa7015d..a53da96ba1 100644 --- a/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs +++ b/OpenRA.Mods.RA/Traits/Infiltration/Infiltrates.cs @@ -24,21 +24,24 @@ namespace OpenRA.Mods.RA.Traits [VoiceReference] public readonly string Voice = "Action"; + [Desc("What diplomatic stances can be infiltrated by this actor.")] + public readonly Stance ValidStances = Stance.Neutral | Stance.Enemy; + public object Create(ActorInitializer init) { return new Infiltrates(this); } } class Infiltrates : IIssueOrder, IResolveOrder, IOrderVoice { - readonly InfiltratesInfo info; + public readonly InfiltratesInfo Info; public Infiltrates(InfiltratesInfo info) { - this.info = info; + Info = info; } public IEnumerable Orders { - get { yield return new TargetTypeOrderTargeter(info.Types, "Infiltrate", 7, "enter", true, false); } + get { yield return new InfiltrationOrderTargeter(Info); } } public Order IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued) @@ -77,13 +80,13 @@ namespace OpenRA.Mods.RA.Traits ai = order.TargetActor.Info; var i = ai.Traits.GetOrDefault(); - return i != null && i.GetTargetTypes().Intersect(info.Types).Any(); + return i != null && i.GetTargetTypes().Intersect(Info.Types).Any(); } public string VoicePhraseForOrder(Actor self, Order order) { return order.OrderString == "Infiltrate" && IsValidOrder(self, order) - ? info.Voice : null; + ? Info.Voice : null; } public void ResolveOrder(Actor self, Order order) @@ -102,4 +105,35 @@ namespace OpenRA.Mods.RA.Traits self.QueueActivity(new Infiltrate(self, target.Actor)); } } + + class InfiltrationOrderTargeter : UnitOrderTargeter + { + readonly InfiltratesInfo info; + + public InfiltrationOrderTargeter(InfiltratesInfo info) + : base("Infiltrate", 7, "enter", true, false) + { + this.info = info; + } + + public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) + { + var stance = self.Owner.Stances[target.Owner]; + + if (!info.ValidStances.HasStance(stance)) + return false; + + return target.TraitsImplementing().Any(t => t.TargetTypes.Intersect(info.Types).Any()); + } + + public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor) + { + var stance = self.Owner.Stances[target.Owner]; + + if (!info.ValidStances.HasStance(stance)) + return false; + + return target.Info.Traits.WithInterface().Any(t => t.GetTargetTypes().Intersect(info.Types).Any()); + } + } }