From e3e5e9eb00d38236649f7bb782a11d7f1db4c684 Mon Sep 17 00:00:00 2001 From: UberWaffe Date: Wed, 9 Jul 2014 17:58:06 +0200 Subject: [PATCH 1/3] 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) { From 81cb26116f25c21a33b6d23016c9857f8446fe4c Mon Sep 17 00:00:00 2001 From: UberWaffe Date: Fri, 8 Aug 2014 18:21:11 +0200 Subject: [PATCH 2/3] Ioncannon changed to limited Spread. (1000, 250, 100 damage in 1c1, 2c1, 2c512) --- mods/cnc/weapons.yaml | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/mods/cnc/weapons.yaml b/mods/cnc/weapons.yaml index 4fdbdae7f1..21c51aad4b 100644 --- a/mods/cnc/weapons.yaml +++ b/mods/cnc/weapons.yaml @@ -147,28 +147,24 @@ Atomic: IonCannon: ValidTargets: Ground, Air Warhead@1Dam_impact: SpreadDamage - Spread: 1c0 + Range: 0, 1c1, 2c1, 2c512 Damage: 100 - Falloff: 1000, 368, 135, 50, 18, 7, 0 + Falloff: 1000, 1000, 250, 100 InfDeath: 5 ValidTargets: Ground, Air - Warhead@2Res_impact: DestroyResource - Warhead@3Smu_impact: LeaveSmudge + Warhead@2Smu_impact: LeaveSmudge SmudgeType: Scorch - Warhead@4Res_area: DestroyResource - Size: 2,1 - Delay: 3 - Warhead@5Smu_area: LeaveSmudge - SmudgeType: Scorch - Size: 2,1 - Delay: 3 - Warhead@6Res_area2: DestroyResource - Size: 1 - Delay: 3 - Warhead@7Smu_area2: LeaveSmudge + Warhead@3Smu_area: LeaveSmudge SmudgeType: Scorch Size: 1 Delay: 3 + Warhead@4Res_area2: DestroyResource + Size: 2 + Delay: 6 + Warhead@5Smu_area2: LeaveSmudge + SmudgeType: Scorch + Size: 2,1 + Delay: 6 Sniper: Report: RAMGUN2.AUD From 1fbcdfc3c38fac149abbc4740b0044525dff2457 Mon Sep 17 00:00:00 2001 From: UberWaffe Date: Sat, 23 Aug 2014 11:25:50 +0200 Subject: [PATCH 3/3] AffectsParent defaulted to false. --- OpenRA.Game/GameRules/Warhead.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenRA.Game/GameRules/Warhead.cs b/OpenRA.Game/GameRules/Warhead.cs index 8928e9f9b1..95316875ea 100644 --- a/OpenRA.Game/GameRules/Warhead.cs +++ b/OpenRA.Game/GameRules/Warhead.cs @@ -28,7 +28,7 @@ namespace OpenRA.GameRules 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; + public readonly bool AffectsParent = false; [Desc("Delay in ticks before applying the warhead effect.","0 = instant (old model).")] public readonly int Delay = 0;