From e3e5e9eb00d38236649f7bb782a11d7f1db4c684 Mon Sep 17 00:00:00 2001 From: UberWaffe Date: Wed, 9 Jul 2014 17:58:06 +0200 Subject: [PATCH] Adds Diplomacy keywords for ValidTarget checks. Changes: Allows diplomacy stance checks to be done on warheads and weapons, using keywords in ValidTargets and InvalidTargets. --- OpenRA.Game/GameRules/Warhead.cs | 55 +++++++++++++------------- OpenRA.Game/GameRules/WeaponInfo.cs | 20 +++++----- OpenRA.Game/Traits/TraitsInterfaces.cs | 9 ++++- OpenRA.Utility/UpgradeRules.cs | 16 ++++---- 4 files changed, 55 insertions(+), 45 deletions(-) diff --git a/OpenRA.Game/GameRules/Warhead.cs b/OpenRA.Game/GameRules/Warhead.cs index 043e5772e6..8928e9f9b1 100644 --- a/OpenRA.Game/GameRules/Warhead.cs +++ b/OpenRA.Game/GameRules/Warhead.cs @@ -23,12 +23,20 @@ namespace OpenRA.GameRules [Desc("What types of targets are unaffected.", "Overrules ValidTargets.")] public readonly string[] InvalidTargets = { }; + + [Desc("What diplomatic stances are affected.")] + public readonly Stance ValidStances = Stance.Ally | Stance.Neutral | Stance.Enemy; + + [Desc("Can this warhead affect the actor that fired it.")] + public readonly bool AffectsParent = true; [Desc("Delay in ticks before applying the warhead effect.","0 = instant (old model).")] public readonly int Delay = 0; + ///Applies the warhead's effect against the target. public abstract void DoImpact(Target target, Actor firedBy, IEnumerable damageModifiers); + ///Checks if the warhead is valid against (can do something to) the target. public bool IsValidAgainst(Target target, World world, Actor firedBy) { if (target.Type == TargetType.Actor) @@ -58,53 +66,46 @@ namespace OpenRA.GameRules // assumption has been removed from the yaml definitions public virtual bool CanTargetActor(ActorInfo victim, Actor firedBy) { return false; } + ///Checks if the warhead is valid against (can do something to) the actor. public bool IsValidAgainst(Actor victim, Actor firedBy) { if (!CanTargetActor(victim.Info, firedBy)) return false; + if (!AffectsParent && victim == firedBy) + return false; + + var stance = firedBy.Owner.Stances[victim.Owner]; + if (!ValidStances.HasFlag(stance)) + return false; + // A target type is valid if it is in the valid targets list, and not in the invalid targets list. - return InTargetList(victim, firedBy, ValidTargets) && - !InTargetList(victim, firedBy, InvalidTargets); - } - - public static bool InTargetList(Actor victim, Actor firedBy, string[] targetList) - { - if (!targetList.Any()) - return false; - var targetable = victim.TraitOrDefault(); - if (targetable == null) - return false; - if (!targetList.Intersect(targetable.TargetTypes).Any()) + if (targetable == null || !ValidTargets.Intersect(targetable.TargetTypes).Any() + || InvalidTargets.Intersect(targetable.TargetTypes).Any()) return false; return true; } + ///Checks if the warhead is valid against (can do something to) the frozen actor. public bool IsValidAgainst(FrozenActor victim, Actor firedBy) { if (!CanTargetActor(victim.Info, firedBy)) return false; + // AffectsParent checks do not make sense for FrozenActors, so skip to stance checks + var stance = firedBy.Owner.Stances[victim.Owner]; + if (!ValidStances.HasFlag(stance)) + return false; + // A target type is valid if it is in the valid targets list, and not in the invalid targets list. - return InTargetList(victim, firedBy, ValidTargets) && - !InTargetList(victim, firedBy, InvalidTargets); - } - - public static bool InTargetList(FrozenActor victim, Actor firedBy, string[] targetList) - { - // Frozen Actors need to be handled slightly differently. Since FrozenActor.Actor can be null if the Actor is dead. - if (!targetList.Any()) - return false; - var targetable = victim.Info.Traits.GetOrDefault(); - if (targetable == null) + if (targetable == null || !ValidTargets.Intersect(targetable.GetTargetTypes()).Any() + || InvalidTargets.Intersect(targetable.GetTargetTypes()).Any()) return false; - if (!targetList.Intersect(targetable.GetTargetTypes()).Any()) - return false; - + return true; } - } + } } diff --git a/OpenRA.Game/GameRules/WeaponInfo.cs b/OpenRA.Game/GameRules/WeaponInfo.cs index 6a40d3186b..567d0602c9 100644 --- a/OpenRA.Game/GameRules/WeaponInfo.cs +++ b/OpenRA.Game/GameRules/WeaponInfo.cs @@ -92,6 +92,7 @@ namespace OpenRA.GameRules return retList; } + ///Checks if the weapon is valid against (can target) the target. public bool IsValidAgainst(Target target, World world, Actor firedBy) { if (target.Type == TargetType.Actor) @@ -117,30 +118,31 @@ namespace OpenRA.GameRules return false; } + ///Checks if the weapon is valid against (can target) the actor. public bool IsValidAgainst(Actor victim, Actor firedBy) { - if (!Warheads.Any(w => w.IsValidAgainst(victim, firedBy))) - return false; - var targetable = victim.TraitOrDefault(); if (targetable == null || !ValidTargets.Intersect(targetable.TargetTypes).Any() || InvalidTargets.Intersect(targetable.TargetTypes).Any()) return false; - return true; - } - - public bool IsValidAgainst(FrozenActor victim, Actor firedBy) - { - // Frozen Actors are treated slightly differently. if (!Warheads.Any(w => w.IsValidAgainst(victim, firedBy))) return false; + return true; + } + + ///Checks if the weapon is valid against (can target) the frozen actor. + public bool IsValidAgainst(FrozenActor victim, Actor firedBy) + { var targetable = victim.Info.Traits.GetOrDefault(); if (targetable == null || !ValidTargets.Intersect(targetable.GetTargetTypes()).Any() || InvalidTargets.Intersect(targetable.GetTargetTypes()).Any()) return false; + if (!Warheads.Any(w => w.IsValidAgainst(victim, firedBy))) + return false; + return true; } diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 1fa0b983f5..9eb5b166f8 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -22,7 +22,14 @@ namespace OpenRA.Traits // depends on the order of pips in WorldRenderer.cs! public enum PipType { Transparent, Green, Yellow, Red, Gray, Blue, Ammo, AmmoEmpty }; public enum TagType { None, Fake, Primary }; - public enum Stance { Enemy, Neutral, Ally }; + + [Flags] + public enum Stance + { + Enemy = 1, + Neutral = 2, + Ally = 4, + } [Flags] public enum ImpactType diff --git a/OpenRA.Utility/UpgradeRules.cs b/OpenRA.Utility/UpgradeRules.cs index ce95f9edab..38035f6eab 100644 --- a/OpenRA.Utility/UpgradeRules.cs +++ b/OpenRA.Utility/UpgradeRules.cs @@ -574,7 +574,7 @@ namespace OpenRA.Utility newYaml.Add(new MiniYamlNode("Size", newValue)); } - var keywords = new List{ "Damage", "InfDeath", "PreventProne", "ProneModifier", "Delay" }; + var keywords = new List { "Damage", "InfDeath", "PreventProne", "ProneModifier", "Delay" }; foreach(var keyword in keywords) { @@ -610,7 +610,7 @@ namespace OpenRA.Utility newYaml.Add(new MiniYamlNode("Spread", newValue)); } - var keywords = new List{ "Damage", "InfDeath", "PreventProne", "ProneModifier", "Delay" }; + var keywords = new List { "Damage", "InfDeath", "PreventProne", "ProneModifier", "Delay" }; foreach(var keyword in keywords) { @@ -637,7 +637,7 @@ namespace OpenRA.Utility var newYaml = new List(); - var keywords = new List{ "Spread", "Damage", "InfDeath", "PreventProne", "ProneModifier", "Delay" }; + var keywords = new List { "Spread", "Damage", "InfDeath", "PreventProne", "ProneModifier", "Delay" }; foreach(var keyword in keywords) { @@ -666,7 +666,7 @@ namespace OpenRA.Utility var newYaml = new List(); - var keywords = new List{ "Size", "Delay", "ValidTargets", "InvalidTargets" }; + var keywords = new List { "Size", "Delay", "ValidTargets", "InvalidTargets" }; foreach(var keyword in keywords) { var temp = curNode.Value.Nodes.FirstOrDefault(n => n.Key == keyword); @@ -684,7 +684,7 @@ namespace OpenRA.Utility var newYaml = new List(); - var keywords = new List{ "AddsResourceType", "Size", "Delay", "ValidTargets", "InvalidTargets" }; + var keywords = new List { "AddsResourceType", "Size", "Delay", "ValidTargets", "InvalidTargets" }; foreach(var keyword in keywords) { @@ -703,7 +703,7 @@ namespace OpenRA.Utility var newYaml = new List(); - var keywords = new List{ "SmudgeType", "Size", "Delay", "ValidTargets", "InvalidTargets" }; + var keywords = new List { "SmudgeType", "Size", "Delay", "ValidTargets", "InvalidTargets" }; foreach(var keyword in keywords) { @@ -723,7 +723,7 @@ namespace OpenRA.Utility var newYaml = new List(); - var keywords = new List{ "Explosion", "ImpactSound", "Delay", "ValidTargets", "InvalidTargets", "ValidImpactTypes", "InvalidImpactTypes" }; + var keywords = new List { "Explosion", "ImpactSound", "Delay", "ValidTargets", "InvalidTargets", "ValidImpactTypes", "InvalidImpactTypes" }; foreach(var keyword in keywords) { @@ -744,7 +744,7 @@ namespace OpenRA.Utility var newYaml = new List(); - var keywords = new List{ "WaterExplosion", "WaterImpactSound", "Delay", "ValidTargets", "InvalidTargets", "ValidImpactTypes", "InvalidImpactTypes" }; + var keywords = new List { "WaterExplosion", "WaterImpactSound", "Delay", "ValidTargets", "InvalidTargets", "ValidImpactTypes", "InvalidImpactTypes" }; foreach(var keyword in keywords) {