From 51bb515a4da4693e15ee0c1c0e42989317aecc11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20R=C3=A4tzel?= Date: Wed, 11 Nov 2015 14:32:38 +0100 Subject: [PATCH] prevent allied units from autoattack building which is being captured. resolves #6170. --- AUTHORS | 1 + OpenRA.Mods.Common/Traits/AutoTarget.cs | 11 +++++++++-- OpenRA.Mods.Common/Traits/ExternalCapturable.cs | 10 +++++++++- OpenRA.Mods.Common/TraitsInterfaces.cs | 5 +++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/AUTHORS b/AUTHORS index 22f5703607..906e22b4c9 100644 --- a/AUTHORS +++ b/AUTHORS @@ -90,6 +90,7 @@ Also thanks to: * Matthijs Benschop (Nerdie) * Max621 * Max Ugrumov (katzsmile) + * Michael Rätzel * Michael Sztolcman (s1w_) * Mustafa Alperen Seki (MustaphaTR) * Neil Shivkar (havok13888) diff --git a/OpenRA.Mods.Common/Traits/AutoTarget.cs b/OpenRA.Mods.Common/Traits/AutoTarget.cs index fea4f3eaf7..9120e2abcc 100644 --- a/OpenRA.Mods.Common/Traits/AutoTarget.cs +++ b/OpenRA.Mods.Common/Traits/AutoTarget.cs @@ -168,7 +168,8 @@ namespace OpenRA.Mods.Common.Traits Actor ChooseTarget(Actor self, WDist range, bool allowMove) { var inRange = self.World.FindActorsInCircle(self.CenterPosition, range) - .Where(a => !a.Info.HasTraitInfo()); + .Where(a => + !a.TraitsImplementing().Any(t => t.PreventsAutoTarget(a, self))); // Armaments are enumerated in attack.Armaments in construct order // When autotargeting, first choose targets according to the used armament construct order @@ -207,7 +208,13 @@ namespace OpenRA.Mods.Common.Traits [Desc("Will not get automatically targeted by enemy (like walls)")] class AutoTargetIgnoreInfo : TraitInfo { } - class AutoTargetIgnore { } + class AutoTargetIgnore : IPreventsAutoTarget + { + public bool PreventsAutoTarget(Actor self, Actor attacker) + { + return true; + } + } public class StanceInit : IActorInit { diff --git a/OpenRA.Mods.Common/Traits/ExternalCapturable.cs b/OpenRA.Mods.Common/Traits/ExternalCapturable.cs index a4949a7fe5..7d8f658356 100644 --- a/OpenRA.Mods.Common/Traits/ExternalCapturable.cs +++ b/OpenRA.Mods.Common/Traits/ExternalCapturable.cs @@ -24,6 +24,9 @@ namespace OpenRA.Mods.Common.Traits [Desc("Seconds it takes to change the owner.", "You might want to add a ExternalCapturableBar: trait, too.")] public readonly int CaptureCompleteTime = 15; + [Desc("Whether to prevent autotargeting this actor while it is being captured by an ally.")] + public readonly bool PreventsAutoTarget = true; + public bool CanBeTargetedBy(Actor captor, Player owner) { var c = captor.Info.TraitInfoOrDefault(); @@ -49,7 +52,7 @@ namespace OpenRA.Mods.Common.Traits public object Create(ActorInitializer init) { return new ExternalCapturable(init.Self, this); } } - public class ExternalCapturable : ITick, ISync + public class ExternalCapturable : ITick, ISync, IPreventsAutoTarget { [Sync] public int CaptureProgressTime = 0; [Sync] public Actor Captor; @@ -91,5 +94,10 @@ namespace OpenRA.Mods.Common.Traits else CaptureProgressTime++; } + + public bool PreventsAutoTarget(Actor self, Actor attacker) + { + return Info.PreventsAutoTarget && Captor != null && attacker.AppearsFriendlyTo(Captor); + } } } diff --git a/OpenRA.Mods.Common/TraitsInterfaces.cs b/OpenRA.Mods.Common/TraitsInterfaces.cs index 26f0403e3a..e3b60646f1 100644 --- a/OpenRA.Mods.Common/TraitsInterfaces.cs +++ b/OpenRA.Mods.Common/TraitsInterfaces.cs @@ -121,4 +121,9 @@ namespace OpenRA.Mods.Common.Traits { void ModifyDeathActorInit(Actor self, TypeDictionary init); } + + public interface IPreventsAutoTarget + { + bool PreventsAutoTarget(Actor self, Actor attacker); + } }