From c972b39687b5cabfa48ea5b5c19e77803fe3acf5 Mon Sep 17 00:00:00 2001 From: UberWaffe Date: Wed, 9 Jul 2014 17:58:06 +0200 Subject: [PATCH] Custom Warheads refactor Changes included: Warhead code split out of weapon code and refactored. Warhead functionality now split into several classes, each handling one effect/impact. Additional custom warheads can now be defined and called via yaml. Custom warheads inherit the abstract class Warhead, which provides target check functions. Custom warheads have to define their own impact functions, and can also define their own replacement for check functions. --- OpenRA.Game/FieldLoader.cs | 10 +- OpenRA.Game/GameRules/Warhead.cs | 102 +++ .../Warheads/AbsoluteSpreadDamageWarhead.cs | 84 ++ .../GameRules/Warheads/DamageWarhead.cs | 59 ++ .../Warheads/HealthPercentageDamageWarhead.cs | 71 ++ .../Warheads/PerCellDamageWarhead.cs | 65 ++ .../GameRules/Warheads/SpreadDamageWarhead.cs | 83 ++ OpenRA.Game/GameRules/WeaponInfo.cs | 189 ++--- OpenRA.Game/OpenRA.Game.csproj | 6 + OpenRA.Game/Traits/Health.cs | 4 +- OpenRA.Game/Traits/TraitsInterfaces.cs | 4 +- OpenRA.Mods.Cnc/Effects/IonCannon.cs | 4 +- OpenRA.Mods.Cnc/PoisonedByTiberium.cs | 4 +- OpenRA.Mods.D2k/DamagedWithoutFoundation.cs | 4 +- OpenRA.Mods.RA/AI/AttackOrFleeFuzzy.cs | 8 +- OpenRA.Mods.RA/Activities/Leap.cs | 2 +- OpenRA.Mods.RA/Air/FallsToEarth.cs | 6 +- OpenRA.Mods.RA/Armament.cs | 2 +- OpenRA.Mods.RA/Attack/AttackBase.cs | 9 +- OpenRA.Mods.RA/Attack/AttackPopupTurreted.cs | 4 +- OpenRA.Mods.RA/Bridge.cs | 4 +- OpenRA.Mods.RA/Combat.cs | 232 ------ OpenRA.Mods.RA/Crates/ExplodeCrateAction.cs | 4 +- OpenRA.Mods.RA/Effects/Bullet.cs | 2 +- OpenRA.Mods.RA/Effects/GravityBomb.cs | 2 +- OpenRA.Mods.RA/Effects/LaserZap.cs | 2 +- OpenRA.Mods.RA/Effects/Missile.cs | 2 +- OpenRA.Mods.RA/Effects/NukeLaunch.cs | 4 +- OpenRA.Mods.RA/Effects/TeslaZap.cs | 2 +- OpenRA.Mods.RA/Explodes.cs | 13 +- OpenRA.Mods.RA/GainsExperience.cs | 2 +- OpenRA.Mods.RA/GainsUnitUpgrades.cs | 2 +- OpenRA.Mods.RA/Invulnerable.cs | 2 +- OpenRA.Mods.RA/IronCurtainable.cs | 2 +- OpenRA.Mods.RA/MadTank.cs | 11 +- OpenRA.Mods.RA/OpenRA.Mods.RA.csproj | 5 +- .../Scripting/ScriptInvulnerable.cs | 2 +- OpenRA.Mods.RA/TakeCover.cs | 2 +- .../Warheads/CreateEffectWarhead.cs | 86 +++ .../Warheads/CreateResourceWarhead.cs | 66 ++ .../Warheads/DestroyResourceWarhead.cs | 47 ++ OpenRA.Mods.RA/Warheads/LeaveSmudgeWarhead.cs | 58 ++ OpenRA.Utility/UpgradeRules.cs | 174 +++++ mods/cnc/maps/gdi01/map.yaml | 4 +- mods/cnc/maps/gdi04a/map.yaml | 2 +- mods/cnc/maps/gdi04b/map.yaml | 2 +- mods/cnc/maps/gdi04c/map.yaml | 2 +- mods/cnc/weapons.yaml | 518 ++++++++----- mods/d2k/weapons.yaml | 277 ++++--- mods/ra/maps/allies-01-classic/map.yaml | 2 +- mods/ra/maps/allies-02-classic/map.yaml | 2 +- .../maps/drop-zone-battle-of-tikiaki/map.yaml | 2 +- mods/ra/maps/drop-zone-w/map.yaml | 20 +- mods/ra/maps/drop-zone/map.yaml | 2 +- mods/ra/maps/fort-lonestar/map.yaml | 78 +- mods/ra/maps/intervention/map.yaml | 2 +- mods/ra/maps/training-camp/map.yaml | 47 +- mods/ra/weapons.yaml | 728 +++++++++++------- mods/ts/weapons.yaml | 374 +++++---- 59 files changed, 2275 insertions(+), 1233 deletions(-) create mode 100644 OpenRA.Game/GameRules/Warhead.cs create mode 100644 OpenRA.Game/GameRules/Warheads/AbsoluteSpreadDamageWarhead.cs create mode 100644 OpenRA.Game/GameRules/Warheads/DamageWarhead.cs create mode 100644 OpenRA.Game/GameRules/Warheads/HealthPercentageDamageWarhead.cs create mode 100644 OpenRA.Game/GameRules/Warheads/PerCellDamageWarhead.cs create mode 100644 OpenRA.Game/GameRules/Warheads/SpreadDamageWarhead.cs delete mode 100644 OpenRA.Mods.RA/Combat.cs create mode 100644 OpenRA.Mods.RA/Warheads/CreateEffectWarhead.cs create mode 100644 OpenRA.Mods.RA/Warheads/CreateResourceWarhead.cs create mode 100644 OpenRA.Mods.RA/Warheads/DestroyResourceWarhead.cs create mode 100644 OpenRA.Mods.RA/Warheads/LeaveSmudgeWarhead.cs diff --git a/OpenRA.Game/FieldLoader.cs b/OpenRA.Game/FieldLoader.cs index ac884c8ba7..9b2dcb920c 100644 --- a/OpenRA.Game/FieldLoader.cs +++ b/OpenRA.Game/FieldLoader.cs @@ -509,10 +509,16 @@ namespace OpenRA internal Func GetLoader(Type type) { - const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static; + const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.FlattenHierarchy; if (!string.IsNullOrEmpty(Loader)) - return (Func)Delegate.CreateDelegate(typeof(Func), type.GetMethod(Loader, flags)); + { + var method = type.GetMethod(Loader, flags); + if (method == null) + throw new InvalidOperationException("{0} does not specify a loader function '{1}'".F(type.Name, Loader)); + + return (Func)Delegate.CreateDelegate(typeof(Func), method); + } return null; } diff --git a/OpenRA.Game/GameRules/Warhead.cs b/OpenRA.Game/GameRules/Warhead.cs new file mode 100644 index 0000000000..6285d01e7f --- /dev/null +++ b/OpenRA.Game/GameRules/Warhead.cs @@ -0,0 +1,102 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System.Collections.Generic; +using System.Linq; +using OpenRA.Effects; +using OpenRA.Traits; + +namespace OpenRA.GameRules +{ + [Desc("Base warhead class. This can be used to derive other warheads from.")] + public abstract class Warhead + { + [Desc("What types of targets are affected.")] + public readonly string[] ValidTargets = { "Air", "Ground", "Water" }; + + [Desc("What types of targets are unaffected.", "Overrules ValidTargets.")] + public readonly string[] InvalidTargets = { }; + + [Desc("Delay in ticks before applying the warhead effect.","0 = instant (old model).")] + public readonly int Delay = 0; + + public abstract void DoImpact(Target target, Actor firedBy, float firepowerModifier); + + public abstract float EffectivenessAgainst(ActorInfo ai); + + public bool IsValidAgainst(Target target, World world, Actor firedBy) + { + if (target.Type == TargetType.Actor) + return IsValidAgainst(target.Actor, firedBy); + + if (target.Type == TargetType.FrozenActor) + return IsValidAgainst(target.FrozenActor, firedBy); + + if (target.Type == TargetType.Terrain) + { + var cell = world.Map.CellContaining(target.CenterPosition); + if (!world.Map.Contains(cell)) + return false; + + var cellInfo = world.Map.GetTerrainInfo(cell); + if (!ValidTargets.Intersect(cellInfo.TargetTypes).Any() + || InvalidTargets.Intersect(cellInfo.TargetTypes).Any()) + return false; + + return true; + } + + return false; + } + + public bool IsValidAgainst(Actor victim, Actor firedBy) + { + // 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()) + return false; + + return true; + } + + public bool IsValidAgainst(FrozenActor victim, Actor firedBy) + { + // 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) + return false; + if (!targetList.Intersect(targetable.GetTargetTypes()).Any()) + return false; + + return true; + } + } +} diff --git a/OpenRA.Game/GameRules/Warheads/AbsoluteSpreadDamageWarhead.cs b/OpenRA.Game/GameRules/Warheads/AbsoluteSpreadDamageWarhead.cs new file mode 100644 index 0000000000..223fb720d6 --- /dev/null +++ b/OpenRA.Game/GameRules/Warheads/AbsoluteSpreadDamageWarhead.cs @@ -0,0 +1,84 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using OpenRA.Effects; +using OpenRA.Traits; + +namespace OpenRA.GameRules +{ + public class AbsoluteSpreadDamageWarhead : DamageWarhead + { + [Desc("Maximum spread of the associated SpreadFactor.")] + public readonly WRange[] Spread = { new WRange(43) }; + + [Desc("What factor to multiply the Damage by for this spread range.", "Each factor specified must have an associated Spread defined.")] + public readonly float[] SpreadFactor = { 1f }; + + public override void DoImpact(Target target, Actor firedBy, float firepowerModifier) + { + // Used by traits that damage a single actor, rather than a position + if (target.Type == TargetType.Actor) + DoImpact(target.Actor, firedBy, firepowerModifier); + else + DoImpact(target.CenterPosition, firedBy, firepowerModifier); + } + + public void DoImpact(WPos pos, Actor firedBy, float firepowerModifier) + { + var world = firedBy.World; + + for (var i = 0; i < Spread.Length; i++) + { + var currentSpread = Spread[i]; + var currentFactor = SpreadFactor[i]; + var previousSpread = WRange.Zero; + if (i > 0) + previousSpread = Spread[i - 1]; + if (currentFactor <= 0f) + continue; + + var hitActors = world.FindActorsInCircle(pos, currentSpread); + if (previousSpread.Range > 0) + hitActors.Except(world.FindActorsInCircle(pos, previousSpread)); + + foreach (var victim in hitActors) + if (IsValidAgainst(victim, firedBy)) + { + var damage = GetDamageToInflict(victim, firedBy, firepowerModifier * currentFactor); + victim.InflictDamage(firedBy, damage, this); + } + } + } + + public void DoImpact(Actor victim, Actor firedBy, float firepowerModifier) + { + if (IsValidAgainst(victim, firedBy)) + { + var currentFactor = SpreadFactor[0]; + var damage = (int)GetDamageToInflict(victim, firedBy, firepowerModifier * currentFactor); + victim.InflictDamage(firedBy, damage, this); + } + } + + public int GetDamageToInflict(Actor target, Actor firedBy, float modifier) + { + var healthInfo = target.Info.Traits.GetOrDefault(); + if (healthInfo == null) + return 0; + + var rawDamage = (float)Damage; + + return (int)(rawDamage * modifier * EffectivenessAgainst(target.Info)); + } + } +} diff --git a/OpenRA.Game/GameRules/Warheads/DamageWarhead.cs b/OpenRA.Game/GameRules/Warheads/DamageWarhead.cs new file mode 100644 index 0000000000..a20cbd7435 --- /dev/null +++ b/OpenRA.Game/GameRules/Warheads/DamageWarhead.cs @@ -0,0 +1,59 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using OpenRA.Effects; +using OpenRA.Traits; + +namespace OpenRA.GameRules +{ + public abstract class DamageWarhead : Warhead + { + [Desc("How much (raw) damage to deal")] + public readonly int Damage = 0; + + [Desc("Infantry death animation to use")] + public readonly string InfDeath = "1"; + + [Desc("Whether we should prevent prone response for infantry.")] + public readonly bool PreventProne = false; + + [Desc("By what percentage should damage be modified against prone infantry.")] + public readonly int ProneModifier = 50; + + [FieldLoader.LoadUsing("LoadVersus")] + [Desc("Damage vs each armortype. 0% = can't target.")] + public readonly Dictionary Versus; + + public static object LoadVersus(MiniYaml yaml) + { + var nd = yaml.ToDictionary(); + return nd.ContainsKey("Versus") + ? nd["Versus"].ToDictionary(my => FieldLoader.GetValue("(value)", my.Value)) + : new Dictionary(); + } + + public override float EffectivenessAgainst(ActorInfo ai) + { + var health = ai.Traits.GetOrDefault(); + if (health == null) + return 0f; + + var armor = ai.Traits.GetOrDefault(); + if (armor == null || armor.Type == null) + return 1f; + + float versus; + return Versus.TryGetValue(armor.Type, out versus) ? versus : 1f; + } + } +} diff --git a/OpenRA.Game/GameRules/Warheads/HealthPercentageDamageWarhead.cs b/OpenRA.Game/GameRules/Warheads/HealthPercentageDamageWarhead.cs new file mode 100644 index 0000000000..fbbf802629 --- /dev/null +++ b/OpenRA.Game/GameRules/Warheads/HealthPercentageDamageWarhead.cs @@ -0,0 +1,71 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using OpenRA.Effects; +using OpenRA.Traits; + +namespace OpenRA.GameRules +{ + public class HealthPercentageDamageWarhead : DamageWarhead + { + [Desc("Size of the area. Damage will be applied to this area.", "If two spreads are defined, the area of effect is a ring, where the second value is the inner radius.")] + public readonly WRange[] Spread = { new WRange(43), WRange.Zero }; + + public override void DoImpact(Target target, Actor firedBy, float firepowerModifier) + { + // Used by traits that damage a single actor, rather than a position + if (target.Type == TargetType.Actor) + DoImpact(target.Actor, firedBy, firepowerModifier); + else + DoImpact(target.CenterPosition, firedBy, firepowerModifier); + } + + public void DoImpact(WPos pos, Actor firedBy, float firepowerModifier) + { + var world = firedBy.World; + var range = Spread[0]; + var hitActors = world.FindActorsInCircle(pos, range); + if (Spread.Length > 1 && Spread[1].Range > 0) + hitActors.Except(world.FindActorsInCircle(pos, Spread[1])); + + foreach (var victim in hitActors) + DoImpact(victim, firedBy, firepowerModifier); + } + + public void DoImpact(Actor victim, Actor firedBy, float firepowerModifier) + { + if (IsValidAgainst(victim, firedBy)) + { + var damage = GetDamageToInflict(victim, firedBy, firepowerModifier); + if (damage != 0) // will be 0 if the target doesn't have HealthInfo + { + var healthInfo = victim.Info.Traits.Get(); + damage = (float)(damage / 100 * healthInfo.HP); + } + + victim.InflictDamage(firedBy, (int)damage, this); + } + } + + public float GetDamageToInflict(Actor target, Actor firedBy, float modifier) + { + var healthInfo = target.Info.Traits.GetOrDefault(); + if (healthInfo == null) + return 0; + + var rawDamage = (float)Damage; + + return rawDamage * modifier * EffectivenessAgainst(target.Info); + } + } +} diff --git a/OpenRA.Game/GameRules/Warheads/PerCellDamageWarhead.cs b/OpenRA.Game/GameRules/Warheads/PerCellDamageWarhead.cs new file mode 100644 index 0000000000..4641834223 --- /dev/null +++ b/OpenRA.Game/GameRules/Warheads/PerCellDamageWarhead.cs @@ -0,0 +1,65 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using OpenRA.Effects; +using OpenRA.Traits; + +namespace OpenRA.GameRules +{ + public class PerCellDamageWarhead : DamageWarhead + { + [Desc("Size of the area. Damage will be applied to this area.")] + public readonly int[] Size = { 0, 0 }; + + public override void DoImpact(Target target, Actor firedBy, float firepowerModifier) + { + // Used by traits that damage a single actor, rather than a position + if (target.Type == TargetType.Actor) + DoImpact(target.Actor, firedBy, firepowerModifier); + else + DoImpact(target.CenterPosition, firedBy, firepowerModifier); + } + + public void DoImpact(WPos pos, Actor firedBy, float firepowerModifier) + { + var world = firedBy.World; + var targetTile = world.Map.CellContaining(pos); + var minRange = (Size.Length > 1 && Size[1] > 0) ? Size[1] : 0; + var affectedTiles = world.Map.FindTilesInAnnulus(targetTile, minRange, Size[0]); + + foreach (var t in affectedTiles) + foreach (var victim in world.ActorMap.GetUnitsAt(t)) + DoImpact(victim, firedBy, firepowerModifier); + } + + public void DoImpact(Actor victim, Actor firedBy, float firepowerModifier) + { + if (IsValidAgainst(victim, firedBy)) + { + var damage = GetDamageToInflict(victim, firedBy, firepowerModifier); + victim.InflictDamage(firedBy, damage, this); + } + } + + public int GetDamageToInflict(Actor target, Actor firedBy, float modifier) + { + var healthInfo = target.Info.Traits.GetOrDefault(); + if (healthInfo == null) + return 0; + + var rawDamage = (float)Damage; + + return (int)(rawDamage * modifier * EffectivenessAgainst(target.Info)); + } + } +} diff --git a/OpenRA.Game/GameRules/Warheads/SpreadDamageWarhead.cs b/OpenRA.Game/GameRules/Warheads/SpreadDamageWarhead.cs new file mode 100644 index 0000000000..f9af6ea087 --- /dev/null +++ b/OpenRA.Game/GameRules/Warheads/SpreadDamageWarhead.cs @@ -0,0 +1,83 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using OpenRA.Effects; +using OpenRA.Traits; + +namespace OpenRA.GameRules +{ + public class SpreadDamageWarhead : DamageWarhead + { + [Desc("For Normal DamageModel: Distance from the explosion center at which damage is 1/2.")] + public readonly WRange Spread = new WRange(43); + + public override void DoImpact(Target target, Actor firedBy, float firepowerModifier) + { + // Used by traits that damage a single actor, rather than a position + if (target.Type == TargetType.Actor) + DoImpact(target.Actor, firedBy, firepowerModifier); + else + DoImpact(target.CenterPosition, firedBy, firepowerModifier); + } + + public void DoImpact(WPos pos, Actor firedBy, float firepowerModifier) + { + var world = firedBy.World; + var maxSpread = new WRange((int)(Spread.Range * (float)Math.Log(Math.Abs(Damage), 2))); + var hitActors = world.FindActorsInCircle(pos, maxSpread); + + foreach (var victim in hitActors) + if (IsValidAgainst(victim, firedBy)) + { + var damage = (int)GetDamageToInflict(pos, victim, firedBy, firepowerModifier); + victim.InflictDamage(firedBy, damage, this); + } + } + + public void DoImpact(Actor victim, Actor firedBy, float firepowerModifier) + { + if (IsValidAgainst(victim, firedBy)) + { + var damage = GetDamageToInflict(victim.CenterPosition, victim, firedBy, firepowerModifier); + victim.InflictDamage(firedBy, damage, this); + } + } + + public int GetDamageToInflict(WPos pos, Actor target, Actor firedBy, float modifier) + { + var healthInfo = target.Info.Traits.GetOrDefault(); + if (healthInfo == null) + return 0; + + var distance = Math.Max(0, (target.CenterPosition - pos).Length - healthInfo.Radius.Range); + var falloff = (float)GetDamageFalloff(distance * 1f / Spread.Range); + var rawDamage = (float)(falloff * Damage); + + return (int)(rawDamage * modifier * EffectivenessAgainst(target.Info)); + } + + static readonly float[] falloff = + { + 1f, 0.3678795f, 0.1353353f, 0.04978707f, + 0.01831564f, 0.006737947f, 0.002478752f, 0.000911882f + }; + + static float GetDamageFalloff(float x) + { + var u = (int)x; + if (u >= falloff.Length - 1) return 0; + var t = x - u; + return (falloff[u] * (1 - t)) + (falloff[u + 1] * t); + } + } +} diff --git a/OpenRA.Game/GameRules/WeaponInfo.cs b/OpenRA.Game/GameRules/WeaponInfo.cs index ea77199b37..23ba47a914 100644 --- a/OpenRA.Game/GameRules/WeaponInfo.cs +++ b/OpenRA.Game/GameRules/WeaponInfo.cs @@ -8,6 +8,7 @@ */ #endregion +using System; using System.Collections.Generic; using System.Linq; using OpenRA.Effects; @@ -15,83 +16,6 @@ using OpenRA.Traits; namespace OpenRA.GameRules { - public class WarheadInfo - { - [Desc("Distance from the explosion center at which damage is 1/2.")] - public readonly WRange Spread = new WRange(43); - [Desc("Maximum Spread. If a value >= Spread is set, this sets a fixed maximum area of damage.")] - public readonly WRange MaxSpread = new WRange(0); - [FieldLoader.LoadUsing("LoadVersus")] - [Desc("Damage vs each armortype. 0% = can't target.")] - public readonly Dictionary Versus; - [Desc("Can this damage resource patches?")] - public readonly bool DestroyResources = false; - [Desc("Will this splatter resources and which?")] - public readonly string AddsResourceType = null; - [Desc("Explosion effect to use.")] - public readonly string Explosion = null; - [Desc("Palette to use for explosion effect.")] - public readonly string ExplosionPalette = "effect"; - [Desc("Explosion effect on hitting water (usually a splash).")] - public readonly string WaterExplosion = null; - [Desc("Palette to use for effect on hitting water (usually a splash).")] - public readonly string WaterExplosionPalette = "effect"; - [Desc("Type of smudge to apply to terrain.")] - public readonly string[] SmudgeType = { }; - [Desc("Size of the explosion. provide 2 values for a ring effect (outer/inner).")] - public readonly int[] Size = { 0, 0 }; - [Desc("Infantry death animation to use")] - public readonly string InfDeath = "1"; - [Desc("Sound to play on impact.")] - public readonly string ImpactSound = null; - [Desc("Sound to play on impact with water")] - public readonly string WaterImpactSound = null; - [Desc("How much (raw) damage to deal")] - public readonly int Damage = 0; - [Desc("Delay in ticks before dealing the damage, 0 = instant (old model).")] - public readonly int Delay = 0; - [Desc("Which damage model to use.")] - public readonly DamageModel DamageModel = DamageModel.Normal; - [Desc("Whether we should prevent prone response for infantry.")] - public readonly bool PreventProne = false; - [Desc("By what percentage should damage be modified against prone infantry.")] - public readonly int ProneModifier = 50; - - public float EffectivenessAgainst(ActorInfo ai) - { - var health = ai.Traits.GetOrDefault(); - if (health == null) - return 0f; - - var armor = ai.Traits.GetOrDefault(); - if (armor == null || armor.Type == null) - return 1; - - float versus; - return Versus.TryGetValue(armor.Type, out versus) ? versus : 1; - } - - public WarheadInfo(MiniYaml yaml) - { - FieldLoader.Load(this, yaml); - } - - static object LoadVersus(MiniYaml y) - { - var nd = y.ToDictionary(); - return nd.ContainsKey("Versus") - ? nd["Versus"].ToDictionary(my => FieldLoader.GetValue("(value)", my.Value)) - : new Dictionary(); - } - } - - public enum DamageModel - { - Normal, // classic RA damage model: point actors, distance-based falloff - PerCell, // like RA's "nuke damage" - HealthPercentage // for MAD Tank - } - public class ProjectileArgs { public WeaponInfo Weapon; @@ -107,20 +31,38 @@ namespace OpenRA.GameRules public class WeaponInfo { + [Desc("The maximum range the weapon can fire.")] public readonly WRange Range = WRange.Zero; + + [Desc("The sound played when the weapon is fired.")] public readonly string[] Report = null; - [Desc("Rate of Fire")] + + [Desc("Rate of Fire = Delay in ticks between reloading ammo magazines.")] public readonly int ROF = 1; + + [Desc("Number of shots in a single ammo magazine.")] public readonly int Burst = 1; + public readonly bool Charges = false; + public readonly string Palette = "effect"; + + [Desc("What types of targets are affected.")] public readonly string[] ValidTargets = { "Ground", "Water" }; + + [Desc("What types of targets are unaffected.", "Overrules ValidTargets.")] public readonly string[] InvalidTargets = { }; + + [Desc("Delay in ticks between firing shots from the same ammo magazine.")] public readonly int BurstDelay = 5; + + [Desc("The minimum range the weapon can fire.")] public readonly WRange MinRange = WRange.Zero; - [FieldLoader.LoadUsing("LoadProjectile")] public IProjectileInfo Projectile; - [FieldLoader.LoadUsing("LoadWarheads")] public List Warheads; + [FieldLoader.LoadUsing("LoadProjectile")] + public readonly IProjectileInfo Projectile; + [FieldLoader.LoadUsing("LoadWarheads")] + public readonly List Warheads = new List(); public WeaponInfo(string name, MiniYaml content) { @@ -139,47 +81,24 @@ namespace OpenRA.GameRules static object LoadWarheads(MiniYaml yaml) { - var ret = new List(); - foreach (var w in yaml.Nodes) - if (w.Key.Split('@')[0] == "Warhead") - ret.Add(new WarheadInfo(w.Value)); + var retList = new List(); + foreach (var node in yaml.Nodes.Where(n => n.Key.StartsWith("Warhead"))) + { + var ret = Game.CreateObject(node.Value.Value + "Warhead"); + FieldLoader.Load(ret, node.Value); + retList.Add(ret); + } - return ret; + return retList; } - public bool IsValidAgainst(Actor a) - { - var targetable = a.TraitOrDefault(); - if (targetable == null || !ValidTargets.Intersect(targetable.TargetTypes).Any() - || InvalidTargets.Intersect(targetable.TargetTypes).Any()) - return false; - - if (Warheads.All(w => w.EffectivenessAgainst(a.Info) <= 0)) - return false; - - return true; - } - - public bool IsValidAgainst(FrozenActor a) - { - var targetable = a.Info.Traits.GetOrDefault(); - if (targetable == null || !ValidTargets.Intersect(targetable.GetTargetTypes()).Any() - || InvalidTargets.Intersect(targetable.GetTargetTypes()).Any()) - return false; - - if (Warheads.All(w => w.EffectivenessAgainst(a.Info) <= 0)) - return false; - - return true; - } - - public bool IsValidAgainst(Target target, World world) + public bool IsValidAgainst(Target target, World world, Actor firedBy) { if (target.Type == TargetType.Actor) - return IsValidAgainst(target.Actor); + return IsValidAgainst(target.Actor, firedBy); if (target.Type == TargetType.FrozenActor) - return IsValidAgainst(target.FrozenActor); + return IsValidAgainst(target.FrozenActor, firedBy); if (target.Type == TargetType.Terrain) { @@ -197,5 +116,47 @@ namespace OpenRA.GameRules return false; } + + 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; + + var targetable = victim.Info.Traits.GetOrDefault(); + if (targetable == null || !ValidTargets.Intersect(targetable.GetTargetTypes()).Any() + || InvalidTargets.Intersect(targetable.GetTargetTypes()).Any()) + return false; + + return true; + } + + public void Impact(WPos pos, Actor firedBy, float damageModifier) + { + foreach (var wh in Warheads) + { + Action a; + + a = () => wh.DoImpact(Target.FromPos(pos), firedBy, damageModifier); + if (wh.Delay > 0) + firedBy.World.AddFrameEndTask( + w => w.Add(new DelayedAction(wh.Delay, a))); + else + a(); + } + } } } diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index 3ed4d44984..d445a21d54 100644 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -75,6 +75,12 @@ + + + + + + diff --git a/OpenRA.Game/Traits/Health.cs b/OpenRA.Game/Traits/Health.cs index a8b7608999..9955ec78ed 100755 --- a/OpenRA.Game/Traits/Health.cs +++ b/OpenRA.Game/Traits/Health.cs @@ -98,7 +98,7 @@ namespace OpenRA.Traits nd.AppliedDamage(repairer, self, ai); } - public void InflictDamage(Actor self, Actor attacker, int damage, WarheadInfo warhead, bool ignoreModifiers) + public void InflictDamage(Actor self, Actor attacker, int damage, DamageWarhead warhead, bool ignoreModifiers) { if (IsDead) return; /* overkill! don't count extra hits as more kills! */ @@ -177,7 +177,7 @@ namespace OpenRA.Traits return (health == null) ? DamageState.Undamaged : health.DamageState; } - public static void InflictDamage(this Actor self, Actor attacker, int damage, WarheadInfo warhead) + public static void InflictDamage(this Actor self, Actor attacker, int damage, DamageWarhead warhead) { if (self.Destroyed) return; var health = self.TraitOrDefault(); diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 72b9a86610..cf084f3b27 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -27,7 +27,7 @@ namespace OpenRA.Traits public class AttackInfo { public Actor Attacker; - public WarheadInfo Warhead; + public DamageWarhead Warhead; public int Damage; public DamageState DamageState; public DamageState PreviousDamageState; @@ -149,7 +149,7 @@ namespace OpenRA.Traits } public interface IRenderModifier { IEnumerable ModifyRender(Actor self, WorldRenderer wr, IEnumerable r); } - public interface IDamageModifier { float GetDamageModifier(Actor attacker, WarheadInfo warhead); } + public interface IDamageModifier { float GetDamageModifier(Actor attacker, DamageWarhead warhead); } public interface ISpeedModifier { decimal GetSpeedModifier(); } public interface IFirepowerModifier { float GetFirepowerModifier(); } public interface ILoadsPalettes { void LoadPalettes(WorldRenderer wr); } diff --git a/OpenRA.Mods.Cnc/Effects/IonCannon.cs b/OpenRA.Mods.Cnc/Effects/IonCannon.cs index bae6c15d46..0beb1c56dd 100644 --- a/OpenRA.Mods.Cnc/Effects/IonCannon.cs +++ b/OpenRA.Mods.Cnc/Effects/IonCannon.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using OpenRA.Effects; +using OpenRA.GameRules; using OpenRA.Graphics; using OpenRA.Mods.RA; using OpenRA.Traits; @@ -44,7 +45,8 @@ namespace OpenRA.Mods.Cnc.Effects void Finish(World world) { world.AddFrameEndTask(w => w.Remove(this)); - Combat.DoExplosion(firedBy.PlayerActor, weapon, target.CenterPosition); + var weapon = world.Map.Rules.Weapons[this.weapon.ToLowerInvariant()]; + weapon.Impact(target.CenterPosition, firedBy.PlayerActor, 1f); } } } diff --git a/OpenRA.Mods.Cnc/PoisonedByTiberium.cs b/OpenRA.Mods.Cnc/PoisonedByTiberium.cs index 8c8c13aa1c..967589b6fb 100644 --- a/OpenRA.Mods.Cnc/PoisonedByTiberium.cs +++ b/OpenRA.Mods.Cnc/PoisonedByTiberium.cs @@ -11,6 +11,7 @@ using System.Linq; using OpenRA.Traits; using OpenRA.Mods.RA; +using OpenRA.GameRules; namespace OpenRA.Mods.Cnc { @@ -42,8 +43,7 @@ namespace OpenRA.Mods.Cnc if (!info.Resources.Contains(r.Info.Name)) return; var weapon = self.World.Map.Rules.Weapons[info.Weapon.ToLowerInvariant()]; - - self.InflictDamage(self.World.WorldActor, weapon.Warheads[0].Damage, weapon.Warheads[0]); + weapon.Impact(self.CenterPosition, self.World.WorldActor, 1f); poisonTicks = weapon.ROF; } } diff --git a/OpenRA.Mods.D2k/DamagedWithoutFoundation.cs b/OpenRA.Mods.D2k/DamagedWithoutFoundation.cs index 66d34db29b..51d9b001db 100644 --- a/OpenRA.Mods.D2k/DamagedWithoutFoundation.cs +++ b/OpenRA.Mods.D2k/DamagedWithoutFoundation.cs @@ -65,9 +65,7 @@ namespace OpenRA.Mods.D2k if (health.HP <= damageThreshold || --damageTicks > 0) return; - foreach (var w in weapon.Warheads) - health.InflictDamage(self, self.World.WorldActor, w.Damage, w, false); - + weapon.Impact(self.CenterPosition, self.World.WorldActor, 1f); damageTicks = weapon.ROF; } } diff --git a/OpenRA.Mods.RA/AI/AttackOrFleeFuzzy.cs b/OpenRA.Mods.RA/AI/AttackOrFleeFuzzy.cs index b8cbb12de8..e5b0d4232c 100644 --- a/OpenRA.Mods.RA/AI/AttackOrFleeFuzzy.cs +++ b/OpenRA.Mods.RA/AI/AttackOrFleeFuzzy.cs @@ -13,6 +13,7 @@ using System.Collections.Generic; using System.Linq; using AI.Fuzzy.Library; using OpenRA.Mods.RA.Move; +using OpenRA.GameRules; using OpenRA.Traits; namespace OpenRA.Mods.RA.AI @@ -195,8 +196,11 @@ namespace OpenRA.Mods.RA.AI var sumOfDamage = 0; var arms = a.TraitsImplementing(); foreach (var arm in arms) - if (arm.Weapon.Warheads[0] != null) - sumOfDamage += arm.Weapon.Warheads[0].Damage; + { + var warhead = arm.Weapon.Warheads.Select(w => w as DamageWarhead).FirstOrDefault(w => w != null); + if (warhead != null) + sumOfDamage += warhead.Damage; + } return sumOfDamage; }); } diff --git a/OpenRA.Mods.RA/Activities/Leap.cs b/OpenRA.Mods.RA/Activities/Leap.cs index ff5b56edd2..465d7247c5 100644 --- a/OpenRA.Mods.RA/Activities/Leap.cs +++ b/OpenRA.Mods.RA/Activities/Leap.cs @@ -63,7 +63,7 @@ namespace OpenRA.Mods.RA.Activities mobile.IsMoving = false; self.World.ActorMap.GetUnitsAt(mobile.toCell, mobile.toSubCell) - .Except(new []{self}).Where(t => weapon.IsValidAgainst(t)) + .Except(new []{self}).Where(t => weapon.IsValidAgainst(t, self)) .Do(t => t.Kill(self)); return NextActivity; diff --git a/OpenRA.Mods.RA/Air/FallsToEarth.cs b/OpenRA.Mods.RA/Air/FallsToEarth.cs index 5099953e2f..5a7d468256 100755 --- a/OpenRA.Mods.RA/Air/FallsToEarth.cs +++ b/OpenRA.Mods.RA/Air/FallsToEarth.cs @@ -8,6 +8,7 @@ */ #endregion +using OpenRA.GameRules; using OpenRA.Traits; namespace OpenRA.Mods.RA.Air @@ -51,7 +52,10 @@ namespace OpenRA.Mods.RA.Air if (self.CenterPosition.Z <= 0) { if (info.Explosion != null) - Combat.DoExplosion(self, info.Explosion, self.CenterPosition); + { + var weapon = self.World.Map.Rules.Weapons[info.Explosion.ToLowerInvariant()]; + weapon.Impact(self.CenterPosition, self, 1f); + } self.Destroy(); return null; diff --git a/OpenRA.Mods.RA/Armament.cs b/OpenRA.Mods.RA/Armament.cs index b71e115d40..aee2b84e2f 100644 --- a/OpenRA.Mods.RA/Armament.cs +++ b/OpenRA.Mods.RA/Armament.cs @@ -142,7 +142,7 @@ namespace OpenRA.Mods.RA if (Weapon.MinRange != WRange.Zero && target.IsInRange(self.CenterPosition, Weapon.MinRange)) return null; - if (!Weapon.IsValidAgainst(target, self.World)) + if (!Weapon.IsValidAgainst(target, self.World, self)) return null; var barrel = Barrels[Burst % Barrels.Length]; diff --git a/OpenRA.Mods.RA/Attack/AttackBase.cs b/OpenRA.Mods.RA/Attack/AttackBase.cs index 4af7245ee1..b9705d7ef0 100644 --- a/OpenRA.Mods.RA/Attack/AttackBase.cs +++ b/OpenRA.Mods.RA/Attack/AttackBase.cs @@ -12,6 +12,7 @@ using System; using System.Collections.Generic; using System.Drawing; using System.Linq; +using OpenRA.GameRules; using OpenRA.Mods.RA.Buildings; using OpenRA.Traits; @@ -87,11 +88,11 @@ namespace OpenRA.Mods.RA { get { - var armament = Armaments.FirstOrDefault(); + var armament = Armaments.FirstOrDefault(a => a.Weapon.Warheads.Any(w => (w is DamageWarhead))); if (armament == null) yield break; - var negativeDamage = armament.Weapon.Warheads[0].Damage < 0; + var negativeDamage = (armament.Weapon.Warheads.FirstOrDefault(w => (w is DamageWarhead)) as DamageWarhead).Damage < 0; yield return new AttackOrderTargeter(this, "Attack", 6, negativeDamage); } } @@ -134,13 +135,13 @@ namespace OpenRA.Mods.RA public abstract Activity GetAttackActivity(Actor self, Target newTarget, bool allowMove); - public bool HasAnyValidWeapons(Target t) { return Armaments.Any(a => a.Weapon.IsValidAgainst(t, self.World)); } + public bool HasAnyValidWeapons(Target t) { return Armaments.Any(a => a.Weapon.IsValidAgainst(t, self.World, self)); } public WRange GetMaximumRange() { return Armaments.Select(a => a.Weapon.Range).Append(WRange.Zero).Max(); } - public Armament ChooseArmamentForTarget(Target t) { return Armaments.FirstOrDefault(a => a.Weapon.IsValidAgainst(t, self.World)); } + public Armament ChooseArmamentForTarget(Target t) { return Armaments.FirstOrDefault(a => a.Weapon.IsValidAgainst(t, self.World, self)); } public void AttackTarget(Target target, bool queued, bool allowMove) { diff --git a/OpenRA.Mods.RA/Attack/AttackPopupTurreted.cs b/OpenRA.Mods.RA/Attack/AttackPopupTurreted.cs index 6354a5e4e9..a4a66b8a92 100644 --- a/OpenRA.Mods.RA/Attack/AttackPopupTurreted.cs +++ b/OpenRA.Mods.RA/Attack/AttackPopupTurreted.cs @@ -22,6 +22,8 @@ namespace OpenRA.Mods.RA [Desc("How many game ticks should pass before closing the actor's turret.")] public int CloseDelay = 125; public int DefaultFacing = 0; + + [Desc("The factor damage received is multiplied by while this actor is closed.")] public float ClosedDamageMultiplier = 0.5f; public override object Create(ActorInitializer init) { return new AttackPopupTurreted(init, this); } @@ -103,7 +105,7 @@ namespace OpenRA.Mods.RA } } - public float GetDamageModifier(Actor attacker, WarheadInfo warhead) + public float GetDamageModifier(Actor attacker, DamageWarhead warhead) { return state == PopupState.Closed ? info.ClosedDamageMultiplier : 1f; } diff --git a/OpenRA.Mods.RA/Bridge.cs b/OpenRA.Mods.RA/Bridge.cs index 7177156f11..5a066bc9cc 100644 --- a/OpenRA.Mods.RA/Bridge.cs +++ b/OpenRA.Mods.RA/Bridge.cs @@ -11,6 +11,7 @@ using System.Collections.Generic; using System.Linq; using OpenRA.Effects; +using OpenRA.GameRules; using OpenRA.Graphics; using OpenRA.Primitives; using OpenRA.Traits; @@ -294,7 +295,8 @@ namespace OpenRA.Mods.RA var initialDamage = Health.DamageState; self.World.AddFrameEndTask(w => { - Combat.DoExplosion(saboteur, "Demolish", self.CenterPosition); + var weapon = saboteur.World.Map.Rules.Weapons["demolish"]; + weapon.Impact(self.CenterPosition, saboteur, 1f); self.World.WorldActor.Trait().AddEffect(15, self.CenterPosition, 6); self.Kill(saboteur); }); diff --git a/OpenRA.Mods.RA/Combat.cs b/OpenRA.Mods.RA/Combat.cs deleted file mode 100644 index 53b376497e..0000000000 --- a/OpenRA.Mods.RA/Combat.cs +++ /dev/null @@ -1,232 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation. For more information, - * see COPYING. - */ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using OpenRA.Effects; -using OpenRA.GameRules; -using OpenRA.Mods.RA.Effects; -using OpenRA.Traits; - -namespace OpenRA.Mods.RA -{ - // some utility bits that are shared between various things - public static class Combat - { - static string GetImpactSound(WarheadInfo warhead, bool isWater) - { - if (isWater && warhead.WaterImpactSound != null) - return warhead.WaterImpactSound; - - if (warhead.ImpactSound != null) - return warhead.ImpactSound; - - return null; - } - - public static void DoImpact(WPos pos, WarheadInfo warhead, WeaponInfo weapon, Actor firedBy, float firepowerModifier) - { - var world = firedBy.World; - var targetTile = world.Map.CellContaining(pos); - - if (!world.Map.Contains(targetTile)) - return; - - var isWater = pos.Z <= 0 && world.Map.GetTerrainInfo(targetTile).IsWater; - var explosionType = isWater ? warhead.WaterExplosion : warhead.Explosion; - var explosionTypePalette = isWater ? warhead.WaterExplosionPalette : warhead.ExplosionPalette; - - if (explosionType != null) - world.AddFrameEndTask(w => w.Add(new Explosion(w, pos, explosionType, explosionTypePalette))); - - Sound.Play(GetImpactSound(warhead, isWater), pos); - - var smudgeLayers = world.WorldActor.TraitsImplementing().ToDictionary(x => x.Info.Type); - var resLayer = warhead.DestroyResources || !string.IsNullOrEmpty(warhead.AddsResourceType) ? world.WorldActor.Trait() : null; - - if (warhead.Size[0] > 0) - { - var allCells = world.Map.FindTilesInCircle(targetTile, warhead.Size[0]).ToList(); - - // `smudgeCells` might want to just be an outer shell of the cells: - IEnumerable smudgeCells = allCells; - if (warhead.Size.Length == 2) - smudgeCells = smudgeCells.Except(world.Map.FindTilesInCircle(targetTile, warhead.Size[1])); - - // Draw the smudges: - foreach (var sc in smudgeCells) - { - var smudgeType = world.Map.GetTerrainInfo(sc).AcceptsSmudgeType.FirstOrDefault(t => warhead.SmudgeType.Contains(t)); - if (smudgeType == null) continue; - - SmudgeLayer smudgeLayer; - if (!smudgeLayers.TryGetValue(smudgeType, out smudgeLayer)) - throw new NotImplementedException("Unknown smudge type `{0}`".F(smudgeType)); - - smudgeLayer.AddSmudge(sc); - if (warhead.DestroyResources) - resLayer.Destroy(sc); - } - - // Destroy all resources in range, not just the outer shell: - if (warhead.DestroyResources) - foreach (var cell in allCells) - resLayer.Destroy(cell); - - // Splatter resources: - if (!string.IsNullOrEmpty(warhead.AddsResourceType)) - { - var resourceType = world.WorldActor.TraitsImplementing() - .FirstOrDefault(t => t.Info.Name == warhead.AddsResourceType); - - if (resourceType == null) - Log.Write("debug", "Warhead defines an invalid resource type '{0}'".F(warhead.AddsResourceType)); - else - { - foreach (var cell in allCells) - { - if (!resLayer.CanSpawnResourceAt(resourceType, cell)) - continue; - - var splash = world.SharedRandom.Next(1, resourceType.Info.MaxDensity - resLayer.GetResourceDensity(cell)); - resLayer.AddResource(resourceType, cell, splash); - } - } - } - } - else - { - var smudgeType = world.Map.GetTerrainInfo(targetTile).AcceptsSmudgeType.FirstOrDefault(t => warhead.SmudgeType.Contains(t)); - if (smudgeType != null) - { - SmudgeLayer smudgeLayer; - if (!smudgeLayers.TryGetValue(smudgeType, out smudgeLayer)) - throw new NotImplementedException("Unknown smudge type `{0}`".F(smudgeType)); - - smudgeLayer.AddSmudge(targetTile); - } - } - - if (warhead.DestroyResources) - world.WorldActor.Trait().Destroy(targetTile); - - switch (warhead.DamageModel) - { - case DamageModel.Normal: - { - var spreadMax = warhead.MaxSpread.Range; - var maxSpreadCalculation = spreadMax >= warhead.Spread.Range ? spreadMax : (warhead.Spread.Range * (float)Math.Log(Math.Abs(warhead.Damage), 2)); - - var maxSpread = new WRange((int)(maxSpreadCalculation)); - var hitActors = world.FindActorsInCircle(pos, maxSpread); - - foreach (var victim in hitActors) - { - var damage = (int)GetDamageToInflict(pos, victim, warhead, weapon, firepowerModifier, true); - victim.InflictDamage(firedBy, damage, warhead); - } - } - break; - - case DamageModel.PerCell: - { - foreach (var t in world.Map.FindTilesInCircle(targetTile, warhead.Size[0])) - { - foreach (var unit in world.ActorMap.GetUnitsAt(t)) - { - var damage = (int)GetDamageToInflict(pos, unit, warhead, weapon, firepowerModifier, false); - unit.InflictDamage(firedBy, damage, warhead); - } - } - } - break; - - case DamageModel.HealthPercentage: - { - var range = new WRange(warhead.Size[0] * 1024); - var hitActors = world.FindActorsInCircle(pos, range); - - foreach (var victim in hitActors) - { - var damage = GetDamageToInflict(pos, victim, warhead, weapon, firepowerModifier, false); - if (damage != 0) // will be 0 if the target doesn't have HealthInfo - { - var healthInfo = victim.Info.Traits.Get(); - damage = (float)(damage / 100 * healthInfo.HP); - } - - victim.InflictDamage(firedBy, (int)damage, warhead); - } - } - break; - } - } - - public static void DoImpacts(WPos pos, Actor firedBy, WeaponInfo weapon, float damageModifier) - { - foreach (var wh in weapon.Warheads) - { - var warhead = wh; - Action a = () => DoImpact(pos, warhead, weapon, firedBy, damageModifier); - - if (warhead.Delay > 0) - firedBy.World.AddFrameEndTask( - w => w.Add(new DelayedAction(warhead.Delay, a))); - else - a(); - } - } - - public static void DoExplosion(Actor attacker, string weapontype, WPos pos) - { - var weapon = attacker.World.Map.Rules.Weapons[weapontype.ToLowerInvariant()]; - if (weapon.Report != null && weapon.Report.Any()) - Sound.Play(weapon.Report.Random(attacker.World.SharedRandom), pos); - - DoImpacts(pos, attacker, weapon, 1f); - } - - static readonly float[] falloff = - { - 1f, 0.3678795f, 0.1353353f, 0.04978707f, - 0.01831564f, 0.006737947f, 0.002478752f, 0.000911882f - }; - - static float GetDamageFalloff(float x) - { - var u = (int)x; - if (u >= falloff.Length - 1) return 0; - var t = x - u; - return (falloff[u] * (1 - t)) + (falloff[u + 1] * t); - } - - static float GetDamageToInflict(WPos pos, Actor target, WarheadInfo warhead, WeaponInfo weapon, float modifier, bool withFalloff) - { - // don't hit air units with splash from ground explosions, etc - if (!weapon.IsValidAgainst(target)) - return 0; - - var healthInfo = target.Info.Traits.GetOrDefault(); - if (healthInfo == null) - return 0; - - var rawDamage = (float)warhead.Damage; - if (withFalloff) - { - var distance = Math.Max(0, (target.CenterPosition - pos).Length - healthInfo.Radius.Range); - var falloff = (float)GetDamageFalloff(distance * 1f / warhead.Spread.Range); - rawDamage = (float)(falloff * rawDamage); - } - - return (float)(rawDamage * modifier * (float)warhead.EffectivenessAgainst(target.Info)); - } - } -} diff --git a/OpenRA.Mods.RA/Crates/ExplodeCrateAction.cs b/OpenRA.Mods.RA/Crates/ExplodeCrateAction.cs index 39bd0acf1d..ee19eb12a0 100644 --- a/OpenRA.Mods.RA/Crates/ExplodeCrateAction.cs +++ b/OpenRA.Mods.RA/Crates/ExplodeCrateAction.cs @@ -8,6 +8,7 @@ */ #endregion +using OpenRA.GameRules; using OpenRA.Traits; namespace OpenRA.Mods.RA @@ -28,7 +29,8 @@ namespace OpenRA.Mods.RA public override void Activate(Actor collector) { - Combat.DoExplosion(self, ((ExplodeCrateActionInfo)info).Weapon, collector.CenterPosition); + var weapon = self.World.Map.Rules.Weapons[((ExplodeCrateActionInfo)info).Weapon.ToLowerInvariant()]; + weapon.Impact(collector.CenterPosition, self, 1f); base.Activate(collector); } } diff --git a/OpenRA.Mods.RA/Effects/Bullet.cs b/OpenRA.Mods.RA/Effects/Bullet.cs index 8e3bfd1dd1..efc63893c0 100755 --- a/OpenRA.Mods.RA/Effects/Bullet.cs +++ b/OpenRA.Mods.RA/Effects/Bullet.cs @@ -172,7 +172,7 @@ namespace OpenRA.Mods.RA.Effects world.AddFrameEndTask(w => w.Remove(this)); - Combat.DoImpacts(pos, args.SourceActor, args.Weapon, args.FirepowerModifier); + args.Weapon.Impact(pos, args.SourceActor, args.FirepowerModifier); } } } diff --git a/OpenRA.Mods.RA/Effects/GravityBomb.cs b/OpenRA.Mods.RA/Effects/GravityBomb.cs index 163aee1e15..b05f703a26 100644 --- a/OpenRA.Mods.RA/Effects/GravityBomb.cs +++ b/OpenRA.Mods.RA/Effects/GravityBomb.cs @@ -56,7 +56,7 @@ namespace OpenRA.Mods.RA.Effects { pos += new WVec(0, 0, args.PassiveTarget.Z - pos.Z); world.AddFrameEndTask(w => w.Remove(this)); - Combat.DoImpacts(pos, args.SourceActor, args.Weapon, args.FirepowerModifier); + args.Weapon.Impact(pos, args.SourceActor, args.FirepowerModifier); } anim.Tick(); diff --git a/OpenRA.Mods.RA/Effects/LaserZap.cs b/OpenRA.Mods.RA/Effects/LaserZap.cs index 4309485db0..5c14c0637f 100644 --- a/OpenRA.Mods.RA/Effects/LaserZap.cs +++ b/OpenRA.Mods.RA/Effects/LaserZap.cs @@ -69,7 +69,7 @@ namespace OpenRA.Mods.RA.Effects if (hitanim != null) hitanim.PlayThen("idle", () => animationComplete = true); - Combat.DoImpacts(target, args.SourceActor, args.Weapon, args.FirepowerModifier); + args.Weapon.Impact(target, args.SourceActor, args.FirepowerModifier); doneDamage = true; } diff --git a/OpenRA.Mods.RA/Effects/Missile.cs b/OpenRA.Mods.RA/Effects/Missile.cs index 75282aa1b5..1dccf4f3cf 100755 --- a/OpenRA.Mods.RA/Effects/Missile.cs +++ b/OpenRA.Mods.RA/Effects/Missile.cs @@ -180,7 +180,7 @@ namespace OpenRA.Mods.RA.Effects if (ticks <= info.Arm) return; - Combat.DoImpacts(pos, args.SourceActor, args.Weapon, args.FirepowerModifier); + args.Weapon.Impact(pos, args.SourceActor, args.FirepowerModifier); } public IEnumerable Render(WorldRenderer wr) diff --git a/OpenRA.Mods.RA/Effects/NukeLaunch.cs b/OpenRA.Mods.RA/Effects/NukeLaunch.cs index 4b466e5003..7db0ba0ddb 100755 --- a/OpenRA.Mods.RA/Effects/NukeLaunch.cs +++ b/OpenRA.Mods.RA/Effects/NukeLaunch.cs @@ -11,6 +11,7 @@ using System.Collections.Generic; using System.Linq; using OpenRA.Effects; +using OpenRA.GameRules; using OpenRA.Graphics; using OpenRA.Traits; @@ -79,7 +80,8 @@ namespace OpenRA.Mods.RA.Effects void Explode(World world) { world.AddFrameEndTask(w => w.Remove(this)); - Combat.DoExplosion(firedBy.PlayerActor, weapon, pos); + var weapon = world.Map.Rules.Weapons[this.weapon.ToLowerInvariant()]; + weapon.Impact(pos, firedBy.PlayerActor, 1f); world.WorldActor.Trait().AddEffect(20, pos, 5); foreach (var a in world.ActorsWithTrait()) diff --git a/OpenRA.Mods.RA/Effects/TeslaZap.cs b/OpenRA.Mods.RA/Effects/TeslaZap.cs index d26d947028..1ef58210d3 100644 --- a/OpenRA.Mods.RA/Effects/TeslaZap.cs +++ b/OpenRA.Mods.RA/Effects/TeslaZap.cs @@ -47,7 +47,7 @@ namespace OpenRA.Mods.RA.Effects if (!doneDamage) { var pos = Args.GuidedTarget.IsValidFor(Args.SourceActor) ? Args.GuidedTarget.CenterPosition : Args.PassiveTarget; - Combat.DoImpacts(pos, Args.SourceActor, Args.Weapon, Args.FirepowerModifier); + Args.Weapon.Impact(pos, Args.SourceActor, Args.FirepowerModifier); doneDamage = true; } } diff --git a/OpenRA.Mods.RA/Explodes.cs b/OpenRA.Mods.RA/Explodes.cs index 269c3cafec..da310d9c6b 100644 --- a/OpenRA.Mods.RA/Explodes.cs +++ b/OpenRA.Mods.RA/Explodes.cs @@ -9,6 +9,7 @@ #endregion using System.Linq; +using OpenRA.GameRules; using OpenRA.Traits; namespace OpenRA.Mods.RA @@ -43,9 +44,15 @@ namespace OpenRA.Mods.RA if (explodesInfo.InfDeath != null && e.Warhead != null && !explodesInfo.InfDeath.Contains(e.Warhead.InfDeath)) return; - var weapon = ChooseWeaponForExplosion(self); - if (weapon != null) - Combat.DoExplosion(e.Attacker, weapon, self.CenterPosition); + var weaponName = ChooseWeaponForExplosion(self); + if (weaponName != null) + { + var weapon = e.Attacker.World.Map.Rules.Weapons[weaponName.ToLowerInvariant()]; + if (weapon.Report != null && weapon.Report.Any()) + Sound.Play(weapon.Report.Random(e.Attacker.World.SharedRandom), self.CenterPosition); + + weapon.Impact(self.CenterPosition, e.Attacker, 1f); + } } string ChooseWeaponForExplosion(Actor self) diff --git a/OpenRA.Mods.RA/GainsExperience.cs b/OpenRA.Mods.RA/GainsExperience.cs index 606df2a15d..60bbad63e7 100644 --- a/OpenRA.Mods.RA/GainsExperience.cs +++ b/OpenRA.Mods.RA/GainsExperience.cs @@ -82,7 +82,7 @@ namespace OpenRA.Mods.RA } } - public float GetDamageModifier(Actor attacker, WarheadInfo warhead) + public float GetDamageModifier(Actor attacker, DamageWarhead warhead) { return Level > 0 ? 1 / info.ArmorModifier[Level - 1] : 1; } diff --git a/OpenRA.Mods.RA/GainsUnitUpgrades.cs b/OpenRA.Mods.RA/GainsUnitUpgrades.cs index 3c75a0cfef..095a12cbd8 100644 --- a/OpenRA.Mods.RA/GainsUnitUpgrades.cs +++ b/OpenRA.Mods.RA/GainsUnitUpgrades.cs @@ -67,7 +67,7 @@ namespace OpenRA.Mods.RA return FirepowerLevel > 0 ? (1 + FirepowerLevel * info.FirepowerModifier) : 1; } - public float GetDamageModifier(Actor attacker, WarheadInfo warhead) + public float GetDamageModifier(Actor attacker, DamageWarhead warhead) { return ArmorLevel > 0 ? (1 / (1 + ArmorLevel * info.ArmorModifier)) : 1; } diff --git a/OpenRA.Mods.RA/Invulnerable.cs b/OpenRA.Mods.RA/Invulnerable.cs index 6147c6aab3..b05950fed7 100644 --- a/OpenRA.Mods.RA/Invulnerable.cs +++ b/OpenRA.Mods.RA/Invulnerable.cs @@ -18,6 +18,6 @@ namespace OpenRA.Mods.RA class Invulnerable : IDamageModifier { - public float GetDamageModifier(Actor attacker, WarheadInfo warhead) { return 0.0f; } + public float GetDamageModifier(Actor attacker, DamageWarhead warhead) { return 0.0f; } } } diff --git a/OpenRA.Mods.RA/IronCurtainable.cs b/OpenRA.Mods.RA/IronCurtainable.cs index 2336db3f6f..0c8db3f3ab 100644 --- a/OpenRA.Mods.RA/IronCurtainable.cs +++ b/OpenRA.Mods.RA/IronCurtainable.cs @@ -28,7 +28,7 @@ namespace OpenRA.Mods.RA RemainingTicks--; } - public float GetDamageModifier(Actor attacker, WarheadInfo warhead) + public float GetDamageModifier(Actor attacker, DamageWarhead warhead) { return (RemainingTicks > 0) ? 0.0f : 1.0f; } diff --git a/OpenRA.Mods.RA/MadTank.cs b/OpenRA.Mods.RA/MadTank.cs index 8de684e6c8..301de81d7c 100644 --- a/OpenRA.Mods.RA/MadTank.cs +++ b/OpenRA.Mods.RA/MadTank.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using System.Drawing; +using OpenRA.GameRules; using OpenRA.Mods.RA.Activities; using OpenRA.Mods.RA.Move; using OpenRA.Mods.RA.Orders; @@ -68,7 +69,10 @@ namespace OpenRA.Mods.RA if (++tick >= info.ThumpInterval) { if (info.ThumpDamageWeapon != null) - Combat.DoExplosion(self, info.ThumpDamageWeapon, self.CenterPosition); + { + var weapon = self.World.Map.Rules.Weapons[info.ThumpDamageWeapon.ToLowerInvariant()]; + weapon.Impact(self.CenterPosition, self, 1f); + } screenShaker.AddEffect(info.ThumpShakeTime, self.CenterPosition, info.ThumpShakeIntensity, info.ThumpShakeMultiplier); tick = 0; } @@ -104,7 +108,10 @@ namespace OpenRA.Mods.RA self.World.AddFrameEndTask(w => { if (info.DetonationWeapon != null) - Combat.DoExplosion(self, info.DetonationWeapon, self.CenterPosition); + { + var weapon = self.World.Map.Rules.Weapons[info.DetonationWeapon.ToLowerInvariant()]; + weapon.Impact(self.CenterPosition, self, 1f); + } self.Kill(self); }); } diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 8b1cd2025c..ec59485609 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -188,7 +188,6 @@ - @@ -288,6 +287,10 @@ + + + + diff --git a/OpenRA.Mods.RA/Scripting/ScriptInvulnerable.cs b/OpenRA.Mods.RA/Scripting/ScriptInvulnerable.cs index eb6356bb69..eebcf35013 100644 --- a/OpenRA.Mods.RA/Scripting/ScriptInvulnerable.cs +++ b/OpenRA.Mods.RA/Scripting/ScriptInvulnerable.cs @@ -20,7 +20,7 @@ namespace OpenRA.Mods.RA { public bool Invulnerable = false; - public float GetDamageModifier(Actor attacker, WarheadInfo warhead) + public float GetDamageModifier(Actor attacker, DamageWarhead warhead) { return Invulnerable ? 0.0f : 1.0f; } diff --git a/OpenRA.Mods.RA/TakeCover.cs b/OpenRA.Mods.RA/TakeCover.cs index 47caf44b2c..6d64de1782 100644 --- a/OpenRA.Mods.RA/TakeCover.cs +++ b/OpenRA.Mods.RA/TakeCover.cs @@ -61,7 +61,7 @@ namespace OpenRA.Mods.RA LocalOffset = WVec.Zero; } - public float GetDamageModifier(Actor attacker, WarheadInfo warhead) + public float GetDamageModifier(Actor attacker, DamageWarhead warhead) { return IsProne && warhead != null ? warhead.ProneModifier / 100f : 1f; } diff --git a/OpenRA.Mods.RA/Warheads/CreateEffectWarhead.cs b/OpenRA.Mods.RA/Warheads/CreateEffectWarhead.cs new file mode 100644 index 0000000000..1b2a6411d7 --- /dev/null +++ b/OpenRA.Mods.RA/Warheads/CreateEffectWarhead.cs @@ -0,0 +1,86 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System.Collections.Generic; +using System.Linq; +using OpenRA.Effects; +using OpenRA.GameRules; +using OpenRA.Traits; +using OpenRA.Mods.RA.Effects; + +namespace OpenRA.Mods.RA +{ + public class CreateEffectWarhead : Warhead + { + [Desc("Size of the area. An explosion animation will be created in each tile.", "Provide 2 values for a ring effect (outer/inner).")] + public readonly int[] Size = { 0, 0 }; + + [Desc("Explosion effect to use.")] + public readonly string Explosion = null; + + [Desc("Palette to use for explosion effect.")] + public readonly string ExplosionPalette = "effect"; + + [Desc("Explosion effect on hitting water (usually a splash).")] + public readonly string WaterExplosion = null; + + [Desc("Palette to use for effect on hitting water (usually a splash).")] + public readonly string WaterExplosionPalette = "effect"; + + [Desc("Sound to play on impact.")] + public readonly string ImpactSound = null; + + [Desc("Sound to play on impact with water")] + public readonly string WaterImpactSound = null; + + public override void DoImpact(Target target, Actor firedBy, float firepowerModifier) + { + DoImpact(target.CenterPosition, firedBy, firepowerModifier); + } + + public void DoImpact(WPos pos, Actor firedBy, float firepowerModifier) + { + var world = firedBy.World; + var targetTile = world.Map.CellContaining(pos); + + if (!world.Map.Contains(targetTile)) + return; + + var minRange = (Size.Length > 1 && Size[1] > 0) ? Size[1] : 0; + var allCells = world.Map.FindTilesInAnnulus(targetTile, minRange, Size[0]); + + // Draw the effects + foreach (var currentCell in allCells) + { + var currentPos = world.Map.CenterOfCell(currentCell); + // TODO: #5937 should go in here after rebase. + var isWater = currentPos.Z <= 0 && world.Map.GetTerrainInfo(currentCell).IsWater; + var explosionType = isWater ? WaterExplosion : Explosion; + var explosionTypePalette = isWater ? WaterExplosionPalette : ExplosionPalette; + + if (explosionType != null) + world.AddFrameEndTask(w => w.Add(new Explosion(w, currentPos, explosionType, explosionTypePalette))); + } + + string sound = null; + + var isTargetWater = pos.Z <= 0 && world.Map.GetTerrainInfo(targetTile).IsWater; + if (isTargetWater && WaterImpactSound != null) + sound = WaterImpactSound; + + if (ImpactSound != null) + sound = ImpactSound; + + Sound.Play(sound, pos); + } + + public override float EffectivenessAgainst(ActorInfo ai) { return 1f; } + } +} diff --git a/OpenRA.Mods.RA/Warheads/CreateResourceWarhead.cs b/OpenRA.Mods.RA/Warheads/CreateResourceWarhead.cs new file mode 100644 index 0000000000..8164f9cb1c --- /dev/null +++ b/OpenRA.Mods.RA/Warheads/CreateResourceWarhead.cs @@ -0,0 +1,66 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System.Collections.Generic; +using System.Linq; +using OpenRA.Effects; +using OpenRA.GameRules; +using OpenRA.Traits; + +namespace OpenRA.Mods.RA +{ + public class CreateResourceWarhead : Warhead + { + [Desc("Size of the area. The resources are seeded within this area.", "Provide 2 values for a ring effect (outer/inner).")] + public readonly int[] Size = { 0, 0 }; + + [Desc("Will this splatter resources and which?")] + public readonly string AddsResourceType = null; + + // TODO: Allow maximum resource splatter to be defined. (Per tile, and in total). + + public override void DoImpact(Target target, Actor firedBy, float firepowerModifier) + { + DoImpact(target.CenterPosition, firedBy, firepowerModifier); + } + + public void DoImpact(WPos pos, Actor firedBy, float firepowerModifier) + { + if (string.IsNullOrEmpty(AddsResourceType)) + return; + + var world = firedBy.World; + var targetTile = world.Map.CellContaining(pos); + var resLayer = world.WorldActor.Trait(); + + var minRange = (Size.Length > 1 && Size[1] > 0) ? Size[1] : 0; + var allCells = world.Map.FindTilesInAnnulus(targetTile, minRange, Size[0]); + + var resourceType = world.WorldActor.TraitsImplementing() + .FirstOrDefault(t => t.Info.Name == AddsResourceType); + + if (resourceType == null) + Log.Write("debug", "Warhead defines an invalid resource type '{0}'".F(AddsResourceType)); + else + { + foreach (var cell in allCells) + { + if (!resLayer.CanSpawnResourceAt(resourceType, cell)) + continue; + + var splash = world.SharedRandom.Next(1, resourceType.Info.MaxDensity - resLayer.GetResourceDensity(cell)); + resLayer.AddResource(resourceType, cell, splash); + } + } + } + + public override float EffectivenessAgainst(ActorInfo ai) { return 1f; } + } +} diff --git a/OpenRA.Mods.RA/Warheads/DestroyResourceWarhead.cs b/OpenRA.Mods.RA/Warheads/DestroyResourceWarhead.cs new file mode 100644 index 0000000000..3a21458e4b --- /dev/null +++ b/OpenRA.Mods.RA/Warheads/DestroyResourceWarhead.cs @@ -0,0 +1,47 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System.Collections.Generic; +using System.Linq; +using OpenRA.Effects; +using OpenRA.GameRules; +using OpenRA.Traits; + +namespace OpenRA.Mods.RA +{ + public class DestroyResourceWarhead : Warhead + { + [Desc("Size of the area. The resources are seeded within this area.", "Provide 2 values for a ring effect (outer/inner).")] + public readonly int[] Size = { 0, 0 }; + + // TODO: Allow maximum resource removal to be defined. (Per tile, and in total). + + public override void DoImpact(Target target, Actor firedBy, float firepowerModifier) + { + DoImpact(target.CenterPosition, firedBy, firepowerModifier); + } + + public void DoImpact(WPos pos, Actor firedBy, float firepowerModifier) + { + var world = firedBy.World; + var targetTile = world.Map.CellContaining(pos); + var resLayer = world.WorldActor.Trait(); + + var minRange = (Size.Length > 1 && Size[1] > 0) ? Size[1] : 0; + var allCells = world.Map.FindTilesInAnnulus(targetTile, minRange, Size[0]); + + // Destroy all resources in the selected tiles + foreach (var cell in allCells) + resLayer.Destroy(cell); + } + + public override float EffectivenessAgainst(ActorInfo ai) { return 1f; } + } +} diff --git a/OpenRA.Mods.RA/Warheads/LeaveSmudgeWarhead.cs b/OpenRA.Mods.RA/Warheads/LeaveSmudgeWarhead.cs new file mode 100644 index 0000000000..eea2c92e59 --- /dev/null +++ b/OpenRA.Mods.RA/Warheads/LeaveSmudgeWarhead.cs @@ -0,0 +1,58 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using OpenRA.Effects; +using OpenRA.GameRules; +using OpenRA.Traits; + +namespace OpenRA.Mods.RA +{ + public class LeaveSmudgeWarhead : Warhead + { + [Desc("Size of the area. A smudge will be created in each tile.", "Provide 2 values for a ring effect (outer/inner).")] + public readonly int[] Size = { 0, 0 }; + + [Desc("Type of smudge to apply to terrain.")] + public readonly string[] SmudgeType = { }; + + public override void DoImpact(Target target, Actor firedBy, float firepowerModifier) + { + DoImpact(target.CenterPosition, firedBy, firepowerModifier); + } + + public void DoImpact(WPos pos, Actor firedBy, float firepowerModifier) + { + var world = firedBy.World; + var targetTile = world.Map.CellContaining(pos); + var smudgeLayers = world.WorldActor.TraitsImplementing().ToDictionary(x => x.Info.Type); + + var minRange = (Size.Length > 1 && Size[1] > 0) ? Size[1] : 0; + var allCells = world.Map.FindTilesInAnnulus(targetTile, minRange, Size[0]); + + // Draw the smudges: + foreach (var sc in allCells) + { + var smudgeType = world.Map.GetTerrainInfo(sc).AcceptsSmudgeType.FirstOrDefault(t => SmudgeType.Contains(t)); + if (smudgeType == null) continue; + + SmudgeLayer smudgeLayer; + if (!smudgeLayers.TryGetValue(smudgeType, out smudgeLayer)) + throw new NotImplementedException("Unknown smudge type `{0}`".F(smudgeType)); + + smudgeLayer.AddSmudge(sc); + } + } + + public override float EffectivenessAgainst(ActorInfo ai) { return 1f; } + } +} diff --git a/OpenRA.Utility/UpgradeRules.cs b/OpenRA.Utility/UpgradeRules.cs index 064dd759f4..e6e46c7a8b 100644 --- a/OpenRA.Utility/UpgradeRules.cs +++ b/OpenRA.Utility/UpgradeRules.cs @@ -396,6 +396,180 @@ namespace OpenRA.Utility node.Key = "DestroyResources"; } + if (engineVersion < 20140720) + { + // Split out the warheads to individual warhead types. + if (depth == 0) + { + var warheadCounter = 0; + foreach(var curNode in node.Value.Nodes.ToArray()) + { + if (curNode.Key.Contains("Warhead") && curNode.Value.Value == null) + { + var newNodes = new List(); + var oldNodeAtName = ""; + if (curNode.Key.Contains('@')) + oldNodeAtName = "_" + curNode.Key.Split('@')[1]; + + // Per Cell Damage Model + if (curNode.Value.Nodes.Where(n => n.Key.Contains("DamageModel") && + n.Value.Value.Contains("PerCell")).Any()) + { + warheadCounter++; + + var newYaml = new List(); + + var keywords = new List{ "Size","Damage","InfDeath","PreventProne","ProneModifier","Delay","ValidTargets","InvalidTargets" }; + foreach(var keyword in keywords) + { + var temp = curNode.Value.Nodes.FirstOrDefault(n => n.Key == keyword); + if (temp != null) + newYaml.Add(new MiniYamlNode(keyword, temp.Value.Value)); + } + + var tempVersus = curNode.Value.Nodes.FirstOrDefault(n => n.Key == "Versus"); + if (tempVersus != null) + newYaml.Add(new MiniYamlNode("Versus", tempVersus.Value)); + + newNodes.Add(new MiniYamlNode("Warhead@" + warheadCounter.ToString() + "Dam" + oldNodeAtName, "PerCellDamage", newYaml)); + } + + // HealthPercentage damage model + if (curNode.Value.Nodes.Where(n => n.Key.Contains("DamageModel") && + n.Value.Value.Contains("HealthPercentage")).Any()) + { + warheadCounter++; + + var newYaml = new List(); + + var temp = curNode.Value.Nodes.FirstOrDefault(n => n.Key == "Size"); // New HealthPercentage warhead allows spreads, as opposed to size + if (temp != null) + { + var newValue = temp.Value.Value.Split(',').First() + "c0"; + if (temp.Value.Value.Contains(',')) + newValue = newValue + "," + temp.Value.Value.Split(',')[1] + "c0"; ; + + newYaml.Add(new MiniYamlNode("Spread", newValue)); + } + + var keywords = new List{ "Damage","InfDeath","PreventProne","ProneModifier","Delay","ValidTargets","InvalidTargets" }; + foreach(var keyword in keywords) + { + var temp2 = curNode.Value.Nodes.FirstOrDefault(n => n.Key == keyword); + if (temp2 != null) + newYaml.Add(new MiniYamlNode(keyword, temp2.Value.Value)); + } + + var tempVersus = curNode.Value.Nodes.FirstOrDefault(n => n.Key == "Versus"); + if (tempVersus != null) + newYaml.Add(new MiniYamlNode("Versus", tempVersus.Value)); + + newNodes.Add(new MiniYamlNode("Warhead@" + warheadCounter.ToString() + "Dam" + oldNodeAtName, "HealthPercentageDamage", newYaml)); + } + + // SpreadDamage + { // Always occurs, since by definition all warheads were SpreadDamage warheads before + warheadCounter++; + + var newYaml = new List(); + + var keywords = new List{ "Spread","Damage","InfDeath","PreventProne","ProneModifier","Delay","ValidTargets","InvalidTargets" }; + foreach(var keyword in keywords) + { + var temp = curNode.Value.Nodes.FirstOrDefault(n => n.Key == keyword); + if (temp != null) + newYaml.Add(new MiniYamlNode(keyword, temp.Value.Value)); + } + + var tempVersus = curNode.Value.Nodes.FirstOrDefault(n => n.Key == "Versus"); + if (tempVersus != null) + newYaml.Add(new MiniYamlNode("Versus", tempVersus.Value)); + + newNodes.Add(new MiniYamlNode("Warhead@" + warheadCounter.ToString() + "Dam" + oldNodeAtName, "SpreadDamage", newYaml)); + } + + // DestroyResource + if (curNode.Value.Nodes.Where(n => n.Key.Contains("DestroyResources") || + n.Key.Contains("Ore")).Any()) + { + warheadCounter++; + + var newYaml = new List(); + + var keywords = new List{ "Size","Delay","ValidTargets","InvalidTargets" }; + foreach(var keyword in keywords) + { + var temp = curNode.Value.Nodes.FirstOrDefault(n => n.Key == keyword); + if (temp != null) + newYaml.Add(new MiniYamlNode(keyword, temp.Value.Value)); + } + + newNodes.Add(new MiniYamlNode("Warhead@" + warheadCounter.ToString() + "Res" + oldNodeAtName, "DestroyResource", newYaml)); + } + + // CreateResource + if (curNode.Value.Nodes.Where(n => n.Key.Contains("AddsResourceType")).Any()) + { + warheadCounter++; + + var newYaml = new List(); + + var keywords = new List{ "AddsResourceType","Size","Delay","ValidTargets","InvalidTargets" }; + foreach(var keyword in keywords) + { + var temp = curNode.Value.Nodes.FirstOrDefault(n => n.Key == keyword); + if (temp != null) + newYaml.Add(new MiniYamlNode(keyword, temp.Value.Value)); + } + + newNodes.Add(new MiniYamlNode("Warhead@" + warheadCounter.ToString() + "Res" + oldNodeAtName, "CreateResource", newYaml)); + } + + // LeaveSmudge + if (curNode.Value.Nodes.Where(n => n.Key.Contains("SmudgeType")).Any()) + { + warheadCounter++; + + var newYaml = new List(); + + var keywords = new List{ "SmudgeType","Size","Delay","ValidTargets","InvalidTargets" }; + foreach(var keyword in keywords) + { + var temp = curNode.Value.Nodes.FirstOrDefault(n => n.Key == keyword); + if (temp != null) + newYaml.Add(new MiniYamlNode(keyword, temp.Value.Value)); + } + + newNodes.Add(new MiniYamlNode("Warhead@" + warheadCounter.ToString() + "Smu" + oldNodeAtName, "LeaveSmudge", newYaml)); + } + + // CreateEffect + if (curNode.Value.Nodes.Where(n => n.Key.Contains("Explosion") || + n.Key.Contains("WaterExplosion") || + n.Key.Contains("ImpactSound") || + n.Key.Contains("WaterImpactSound")).Any()) + { + warheadCounter++; + + var newYaml = new List(); + + var keywords = new List{ "Explosion","WaterExplosion","ImpactSound","WaterImpactSound","Delay","ValidTargets","InvalidTargets" }; + foreach(var keyword in keywords) + { + var temp = curNode.Value.Nodes.FirstOrDefault(n => n.Key == keyword); + if (temp != null) + newYaml.Add(new MiniYamlNode(keyword, temp.Value.Value)); + } + + newNodes.Add(new MiniYamlNode("Warhead@" + warheadCounter.ToString() + "Eff" + oldNodeAtName, "CreateEffect", newYaml)); + } + node.Value.Nodes.InsertRange(node.Value.Nodes.IndexOf(curNode),newNodes); + node.Value.Nodes.Remove(curNode); + } + } + } + } + UpgradeWeaponRules(engineVersion, ref node.Value.Nodes, node, depth + 1); } } diff --git a/mods/cnc/maps/gdi01/map.yaml b/mods/cnc/maps/gdi01/map.yaml index bc8fffa2d7..072923e57e 100644 --- a/mods/cnc/maps/gdi01/map.yaml +++ b/mods/cnc/maps/gdi01/map.yaml @@ -535,10 +535,10 @@ VoxelSequences: Weapons: BoatMissile: - Warhead: + Warhead: SpreadDamage Versus: Heavy: 50% - Damage: 50 + Damage: 50 Voices: diff --git a/mods/cnc/maps/gdi04a/map.yaml b/mods/cnc/maps/gdi04a/map.yaml index 618a85cd1c..95782d2f10 100644 --- a/mods/cnc/maps/gdi04a/map.yaml +++ b/mods/cnc/maps/gdi04a/map.yaml @@ -572,7 +572,7 @@ VoxelSequences: Weapons: Tiberium: - Warhead: + Warhead: SpreadDamage Damage: 6 Voices: diff --git a/mods/cnc/maps/gdi04b/map.yaml b/mods/cnc/maps/gdi04b/map.yaml index fe20a8c6f3..6b5a8782cf 100644 --- a/mods/cnc/maps/gdi04b/map.yaml +++ b/mods/cnc/maps/gdi04b/map.yaml @@ -653,7 +653,7 @@ VoxelSequences: Weapons: Tiberium: - Warhead: + Warhead: SpreadDamage Damage: 4 Voices: diff --git a/mods/cnc/maps/gdi04c/map.yaml b/mods/cnc/maps/gdi04c/map.yaml index 5c6b06be5f..35a8b22e92 100644 --- a/mods/cnc/maps/gdi04c/map.yaml +++ b/mods/cnc/maps/gdi04c/map.yaml @@ -913,7 +913,7 @@ VoxelSequences: Weapons: Rockets: - Warhead: + Warhead: SpreadDamage Versus: None: 20% diff --git a/mods/cnc/weapons.yaml b/mods/cnc/weapons.yaml index 1c078b1c8c..28cdfd538b 100644 --- a/mods/cnc/weapons.yaml +++ b/mods/cnc/weapons.yaml @@ -1,144 +1,181 @@ FlametankExplode: - Warhead: - Damage: 100 + Warhead@1Dam: SpreadDamage Spread: 1c0 - Explosion: big_napalm + Damage: 100 InfDeath: 5 + Warhead@2Eff: CreateEffect + Explosion: big_napalm ImpactSound: xplobig6.aud HeliCrash: - Warhead: - Damage: 40 + Warhead@1Dam: SpreadDamage Spread: 426 - Explosion: poof + Damage: 40 InfDeath: 4 + Warhead@2Eff: CreateEffect + Explosion: poof ImpactSound: xplos.aud HeliExplode: - Warhead: - Explosion: small_building + Warhead@1Dam: SpreadDamage InfDeath: 4 + Warhead@2Eff: CreateEffect + Explosion: small_building ImpactSound: xplos.aud UnitExplode: - Warhead: - Damage: 500 + Warhead@1Dam: SpreadDamage Spread: 426 + Damage: 500 + InfDeath: 4 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% + Warhead@2Eff: CreateEffect Explosion: poof - InfDeath: 4 ImpactSound: xplobig6.aud UnitExplodeSmall: - Warhead: - Damage: 40 + Warhead@1Dam: SpreadDamage Spread: 426 + Damage: 40 + InfDeath: 4 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% + Warhead@2Eff: CreateEffect Explosion: big_frag - InfDeath: 4 ImpactSound: xplobig4.aud GrenadierExplode: - Warhead: - Damage: 10 + Warhead@1Dam: SpreadDamage Spread: 256 + Damage: 10 + InfDeath: 3 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% + Warhead@2Eff: CreateEffect Explosion: poof - InfDeath: 3 ImpactSound: xplosml2.aud Atomic: ValidTargets: Ground, Air Report: nukemisl.aud - Warhead@impact: - Damage: 1500 #1000 + Warhead@1Dam_impact: SpreadDamage Spread: 1c0 + Damage: 1500 + InfDeath: 5 Versus: None: 100% Wood: 100% Light: 60% Heavy: 50% + Warhead@2Eff_impact: CreateEffect Explosion: 6 - InfDeath: 5 ImpactSound: nukexplo.aud - Warhead@areanukea: - Damage: 1000 #200 - SmudgeType: Scorch + Warhead@3Dam_areanukea: SpreadDamage Spread: 2c512 - Size: 3 - DestroyResources: true - Versus: - None: 100% - Wood: 100% - Light: 60% - Heavy: 50% + Damage: 1000 + InfDeath: 5 Delay: 3 - InfDeath: 5 + Versus: + None: 100% + Wood: 100% + Light: 60% + Heavy: 50% + Warhead@4Res_areanukea: DestroyResource + Size: 3 + Delay: 3 + Warhead@5Smu_areanukea: LeaveSmudge + SmudgeType: Scorch + Size: 3 + Delay: 3 + Warhead@6Eff_areanukea: CreateEffect ImpactSound: xplobig4.aud - Warhead@areanukeb: - Damage: 500 #200 - SmudgeType: Scorch + Delay: 3 + Warhead@7Dam_areanukeb: SpreadDamage Spread: 3c768 - Size: 4 - DestroyResources: true - Versus: - None: 100% - Wood: 100% - Light: 60% - Heavy: 50% + Damage: 500 + InfDeath: 5 Delay: 6 - InfDeath: 5 - Warhead@areanukec: - Damage: 200 - SmudgeType: Scorch - Spread: 5c0 - Size: 5 - DestroyResources: true Versus: None: 100% Wood: 100% Light: 60% Heavy: 50% - Delay: 9 + Warhead@8Res_areanukeb: DestroyResource + Size: 4 + Delay: 6 + Warhead@9Smu_areanukeb: LeaveSmudge + SmudgeType: Scorch + Size: 4 + Delay: 6 + Warhead@10Dam_areanukec: SpreadDamage + Spread: 5c0 + Damage: 200 InfDeath: 5 + Delay: 9 + Versus: + None: 100% + Wood: 100% + Light: 60% + Heavy: 50% + Warhead@11Res_areanukec: DestroyResource + Size: 5 + Delay: 9 + Warhead@12Smu_areanukec: LeaveSmudge + SmudgeType: Scorch + Size: 5 + Delay: 9 IonCannon: ValidTargets: Ground, Air - Warhead@impact: - Damage: 1000 - SmudgeType: Scorch + Warhead@1Dam_impact: SpreadDamage Spread: 1c0 - MaxSpread: 3c640 - DestroyResources: true + Damage: 1000 InfDeath: 5 - Warhead@area: - DamageModel: PerCell + Warhead@2Res_impact: DestroyResource + Warhead@3Smu_impact: LeaveSmudge + SmudgeType: Scorch + Warhead@4Dam_area: PerCellDamage + Size: 2,1 Damage: 0 + InfDeath: 5 + Delay: 3 + Warhead@5Dam_area: SpreadDamage + Damage: 0 + InfDeath: 5 + Delay: 3 + Warhead@6Res_area: DestroyResource + Size: 2,1 + Delay: 3 + Warhead@7Smu_area: LeaveSmudge SmudgeType: Scorch Size: 2,1 - DestroyResources: true Delay: 3 - InfDeath: 5 - Warhead@area2: - DamageModel: PerCell + Warhead@8Dam_area2: PerCellDamage + Size: 1 Damage: 0 + InfDeath: 5 + Delay: 3 + Warhead@9Dam_area2: SpreadDamage + Damage: 0 + InfDeath: 5 + Delay: 3 + Warhead@10Res_area2: DestroyResource + Size: 1 + Delay: 3 + Warhead@11Smu_area2: LeaveSmudge SmudgeType: Scorch Size: 1 - DestroyResources: true Delay: 3 - InfDeath: 5 Sniper: Report: RAMGUN2.AUD @@ -147,9 +184,9 @@ Sniper: Range: 6c0 Projectile: Bullet Speed: 1c682 - Warhead: - Damage: 100 + Warhead@1Dam: SpreadDamage Spread: 42 + Damage: 100 InfDeath: 2 HighV: @@ -158,15 +195,16 @@ HighV: Report: GUN8.AUD Projectile: Bullet Speed: 1c682 - Warhead: - Damage: 30 + Warhead@1Dam: SpreadDamage Spread: 683 + Damage: 30 + InfDeath: 2 Versus: None: 100% Wood: 50% Light: 70% Heavy: 35% - InfDeath: 2 + Warhead@2Eff: CreateEffect Explosion: piffs HeliAGGun: @@ -178,15 +216,16 @@ HeliAGGun: Report: gun5.aud Projectile: Bullet Speed: 1c682 - Warhead: - Damage: 20 + Warhead@1Dam: SpreadDamage Spread: 256 + Damage: 20 + InfDeath: 2 Versus: None: 100% Wood: 50% Light: 75% Heavy: 25% - InfDeath: 2 + Warhead@2Eff: CreateEffect Explosion: piffs HeliAAGun: @@ -198,15 +237,16 @@ HeliAAGun: Report: gun5.aud Projectile: Bullet Speed: 1c682 - Warhead: - Damage: 20 + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 20 + InfDeath: 2 Versus: None: 100% Wood: 50% Light: 50% Heavy: 25% - InfDeath: 2 + Warhead@2Eff: CreateEffect Explosion: piffs Pistol: @@ -216,16 +256,17 @@ Pistol: Report: GUN18.AUD Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 1 + InfDeath: 2 Versus: None: 100% Wood: 50% Light: 50% Heavy: 25% - InfDeath: 2 + Warhead@2Eff: CreateEffect Explosion: piff - Damage: 1 M16: ROF: 20 @@ -234,16 +275,17 @@ M16: Report: MGUN2.AUD Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 15 + InfDeath: 2 Versus: None: 100% Wood: 25% Light: 30% Heavy: 10% + Warhead@2Eff: CreateEffect Explosion: piff - InfDeath: 2 - Damage: 15 Rockets: ROF: 50 @@ -260,19 +302,21 @@ Rockets: ContrailLength: 8 Speed: 298 RangeLimit: 20 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 30 + InfDeath: 4 Versus: None: 50% Wood: 85% Light: 100% Heavy: 100% Concrete: 25% - InfDeath: 4 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: small_frag ImpactSound: xplos.aud - SmudgeType: Crater - Damage: 30 BikeRockets: ROF: 50 @@ -291,19 +335,21 @@ BikeRockets: ContrailLength: 8 Speed: 213 RangeLimit: 30 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 30 + InfDeath: 4 Versus: None: 25% Wood: 75% Light: 100% Heavy: 100% Concrete: 50% - InfDeath: 4 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: small_frag ImpactSound: xplos.aud - SmudgeType: Crater - Damage: 30 OrcaAGMissiles: ROF: 12 @@ -322,18 +368,20 @@ OrcaAGMissiles: ContrailLength: 8 Speed: 298 RangeLimit: 30 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 25 + InfDeath: 4 Versus: None: 50% Wood: 100% Light: 100% Heavy: 75% - InfDeath: 4 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: small_frag ImpactSound: xplos.aud - SmudgeType: Crater - Damage: 25 OrcaAAMissiles: ROF: 12 @@ -352,16 +400,18 @@ OrcaAAMissiles: ContrailLength: 8 Speed: 298 RangeLimit: 30 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 25 + InfDeath: 4 Versus: Light: 75% Heavy: 50% - InfDeath: 4 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: small_frag ImpactSound: xplos.aud - SmudgeType: Crater - Damage: 25 Flamethrower: ROF: 55 @@ -370,18 +420,20 @@ Flamethrower: Report: FLAMER2.AUD Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 341 + Damage: 40 + InfDeath: 5 Versus: None: 100% Wood: 100% Light: 100% Heavy: 20% - Explosion: small_napalm - InfDeath: 5 - ImpactSound: flamer2.aud + Warhead@2Smu: LeaveSmudge SmudgeType: Scorch - Damage: 40 + Warhead@3Eff: CreateEffect + Explosion: small_napalm + ImpactSound: flamer2.aud BigFlamer: ROF: 50 @@ -392,18 +444,20 @@ BigFlamer: Speed: 341 Burst: 2 BurstDelay: 25 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 341 + Damage: 75 + InfDeath: 5 Versus: None: 100% Wood: 100% Light: 67% Heavy: 25% - InfDeath: 5 + Warhead@2Smu: LeaveSmudge + SmudgeType: Scorch + Warhead@3Eff: CreateEffect Explosion: med_napalm ImpactSound: flamer2.aud - SmudgeType: Scorch - Damage: 75 Chemspray: ROF: 70 @@ -411,17 +465,19 @@ Chemspray: Report: FLAMER2.AUD Projectile: Bullet Speed: 1c682 - Warhead: - Damage: 80 + Warhead@1Dam: SpreadDamage Spread: 256 + Damage: 80 + InfDeath: 6 Versus: None: 100% Wood: 35% Light: 75% Heavy: 50% - InfDeath: 6 - Explosion: chemball + Warhead@2Smu: LeaveSmudge SmudgeType: Scorch + Warhead@3Eff: CreateEffect + Explosion: chemball ImpactSound: xplos.aud Grenade: @@ -434,18 +490,20 @@ Grenade: Angle: 62 Inaccuracy: 213 Image: BOMB - Warhead: + Warhead@1Dam: SpreadDamage Spread: 341 + Damage: 50 + InfDeath: 3 Versus: None: 100% Wood: 50% Light: 75% Heavy: 35% - InfDeath: 3 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: small_poof ImpactSound: xplos.aud - SmudgeType: Crater - Damage: 50 70mm: ROF: 30 @@ -454,19 +512,21 @@ Grenade: Projectile: Bullet Image: 120MM Speed: 853 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 25 + InfDeath: 4 Versus: None: 25% Wood: 75% Light: 100% Heavy: 100% Concrete: 50% - InfDeath: 4 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: small_frag ImpactSound: xplos.aud - SmudgeType: Crater - Damage: 25 105mm: ROF: 50 @@ -475,18 +535,20 @@ Grenade: Projectile: Bullet Image: 120MM Speed: 682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 30 + InfDeath: 4 Versus: None: 30% Wood: 75% Light: 75% Heavy: 100% - InfDeath: 4 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: small_frag ImpactSound: xplos.aud - SmudgeType: Crater - Damage: 30 120mm: ROF: 40 @@ -495,19 +557,21 @@ Grenade: Projectile: Bullet Image: 120MM Speed: 682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 40 + InfDeath: 4 Versus: None: 25% Wood: 100% Light: 100% Heavy: 100% Concrete: 50% - InfDeath: 4 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: small_frag ImpactSound: xplos.aud - SmudgeType: Crater - Damage: 40 120mmDual: ROF: 40 @@ -518,19 +582,21 @@ Grenade: Projectile: Bullet Image: 120MM Speed: 682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 40 + InfDeath: 4 Versus: None: 25% Wood: 100% Light: 100% Heavy: 100% Concrete: 100% - InfDeath: 4 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: small_frag ImpactSound: xplos.aud - SmudgeType: Crater - Damage: 40 TurretGun: ROF: 20 @@ -539,18 +605,20 @@ TurretGun: Projectile: Bullet Image: 120MM Speed: 853 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 40 + InfDeath: 4 Versus: None: 20% Wood: 25% Light: 100% Heavy: 100% - InfDeath: 4 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: small_frag ImpactSound: xplos.aud - SmudgeType: Crater - Damage: 40 MammothMissiles: ROF: 45 @@ -569,18 +637,20 @@ MammothMissiles: ContrailLength: 8 Speed: 341 RangeLimit: 35 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 298 + Damage: 45 + InfDeath: 4 Versus: None: 50% Wood: 75% Light: 100% Heavy: 50% - InfDeath: 4 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: small_frag ImpactSound: xplos.aud - SmudgeType: Crater - Damage: 45 227mm: ROF: 140 @@ -601,18 +671,20 @@ MammothMissiles: ContrailLength: 10 Trail: smokey Speed: 341 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 683 + Damage: 25 + InfDeath: 4 Versus: None: 35% Wood: 60% Light: 100% Heavy: 50% - InfDeath: 4 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: med_frag ImpactSound: xplos.aud - SmudgeType: Crater - Damage: 25 227mm.stnk: ROF: 70 @@ -631,18 +703,20 @@ MammothMissiles: ContrailLength: 8 Speed: 213 RangeLimit: 40 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 60 + InfDeath: 4 Versus: None: 25% Wood: 75% Light: 100% Heavy: 90% - InfDeath: 4 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: small_frag ImpactSound: xplos.aud - SmudgeType: Crater - Damage: 60 ArtilleryShell: ROF: 65 @@ -656,17 +730,19 @@ ArtilleryShell: Inaccuracy: 1c256 ContrailLength: 30 Image: 120MM - Warhead: - Damage: 150 + Warhead@1Dam: SpreadDamage Spread: 341 + Damage: 150 + InfDeath: 3 Versus: None: 100% Wood: 80% Light: 75% Heavy: 50% - InfDeath: 3 - Explosion: poof + Warhead@2Smu: LeaveSmudge SmudgeType: Crater + Warhead@3Eff: CreateEffect + Explosion: poof ImpactSound: XPLOSML2.AUD MachineGun: @@ -677,17 +753,18 @@ MachineGun: Report: MGUN11.AUD Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 15 + InfDeath: 2 Versus: None: 100% Wood: 20% Light: 50% Heavy: 20% Concrete: 10% - InfDeath: 2 + Warhead@2Eff: CreateEffect Explosion: piffs - Damage: 15 BoatMissile: ROF: 35 @@ -705,18 +782,20 @@ BoatMissile: ContrailLength: 8 Speed: 170 RangeLimit: 60 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 256 + Damage: 60 + InfDeath: 3 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% - InfDeath: 3 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: small_poof ImpactSound: xplos.aud - SmudgeType: Crater - Damage: 60 TowerMissle: ROF: 15 @@ -733,18 +812,20 @@ TowerMissle: ContrailLength: 8 Speed: 298 RangeLimit: 40 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 683 + Damage: 25 + InfDeath: 3 Versus: None: 50% Wood: 25% Light: 100% Heavy: 100% - InfDeath: 3 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: med_frag ImpactSound: xplos.aud - SmudgeType: Crater - Damage: 25 Vulcan: ValidTargets: Ground, Water @@ -753,15 +834,16 @@ Vulcan: Report: gun5.aud Projectile: Bullet Speed: 1c682 - Warhead: - Damage: 100 + Warhead@1Dam: SpreadDamage Spread: 426 + Damage: 100 + InfDeath: 2 Versus: None: 100% Wood: 25% Light: 100% Heavy: 35% - InfDeath: 2 + Warhead@2Eff: CreateEffect Explosion: piffs Napalm: @@ -772,33 +854,37 @@ Napalm: BurstDelay: 2 Projectile: GravityBomb Image: BOMBLET - Warhead: + Warhead@1Dam: SpreadDamage Spread: 341 + Damage: 300 + InfDeath: 5 Versus: None: 100% Wood: 100% Light: 100% Heavy: 80% - InfDeath: 5 + Warhead@2Smu: LeaveSmudge + SmudgeType: Scorch + Warhead@3Eff: CreateEffect Explosion: med_napalm WaterExplosion: med_napalm ImpactSound: flamer2.aud - SmudgeType: Scorch - Damage: 300 Napalm.Crate: - Warhead: + Warhead@1Dam: SpreadDamage Spread: 170 + Damage: 500 + InfDeath: 5 Versus: None: 90% Wood: 100% Light: 60% Heavy: 25% - InfDeath: 5 + Warhead@2Smu: LeaveSmudge + SmudgeType: Scorch + Warhead@3Eff: CreateEffect Explosion: med_napalm ImpactSound: flamer2.aud - SmudgeType: Scorch - Damage: 500 Laser: ROF: 1 @@ -808,13 +894,14 @@ Laser: Projectile: LaserZap BeamWidth: 2 HitAnim: laserfire - Warhead: + Warhead@1Dam: SpreadDamage Spread: 42 + Damage: 360 + InfDeath: 5 Versus: Wood: 50% - InfDeath: 5 + Warhead@2Smu: LeaveSmudge SmudgeType: Scorch - Damage: 360 SAMMissile: ROF: 15 @@ -830,7 +917,7 @@ SAMMissile: RangeLimit: 35 Trail: smokey ContrailLength: 8 - Warhead: AP + Warhead@1Dam: SpreadDamage Spread: 682 Versus: None: 100% @@ -838,10 +925,12 @@ SAMMissile: Light: 100% Heavy: 75% InfDeath: 4 + Damage: 30 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: small_frag ImpactSound: xplos.aud - SmudgeType: Crater - Damage: 30 HonestJohn: ROF: 200 @@ -857,45 +946,49 @@ HonestJohn: Speed: 187 RangeLimit: 35 Angle: 88 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 256 + Damage: 100 + InfDeath: 3 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% - InfDeath: 3 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: small_poof ImpactSound: xplos.aud - SmudgeType: Crater - Damage: 100 Tiberium: ROF: 16 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 42 - InfDeath: 6 Damage: 2 + InfDeath: 6 PreventProne: yes TiberiumExplosion: - Warhead: - Damage: 10 + Warhead@1Dam: SpreadDamage Spread: 9 - Size: 1,1 + Damage: 10 + InfDeath: 3 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% - Explosion: chemball - InfDeath: 3 - ImpactSound: xplosml2.aud + Warhead@2Res: CreateResource AddsResourceType: Tiberium + Size: 1,1 + Warhead@3Eff: CreateEffect + Explosion: chemball + ImpactSound: xplosml2.aud Heal: ROF: 4 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 42 Damage: -1 PreventProne: yes @@ -907,15 +1000,16 @@ APCGun: ValidTargets: Ground Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 15 Versus: None: 50% Wood: 50% Light: 100% Heavy: 50% + Warhead@2Eff: CreateEffect Explosion: small_poof - Damage: 15 APCGun.AA: ROF: 18 @@ -925,12 +1019,13 @@ APCGun.AA: Projectile: Bullet Speed: 1c682 High: true - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 25 Versus: Heavy: 50% + Warhead@2Eff: CreateEffect Explosion: small_poof - Damage: 25 Patriot: ROF: 25 @@ -947,7 +1042,7 @@ Patriot: Speed: 341 RangeLimit: 30 Angle: 88 - Warhead: AP + Warhead@1Dam: SpreadDamage Spread: 682 Versus: None: 100% @@ -955,77 +1050,80 @@ Patriot: Light: 100% Heavy: 75% InfDeath: 4 + Damage: 32 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: poof ImpactSound: xplos.aud - SmudgeType: Crater - Damage: 32 Tail: ROF: 30 Range: 1c0 Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 213 + Damage: 180 + InfDeath: 1 Versus: None: 90% Wood: 10% Light: 30% Heavy: 10% Concrete: 10% - InfDeath: 1 - Damage: 180 Horn: ROF: 20 Range: 1c0 Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 213 + Damage: 120 + InfDeath: 1 Versus: None: 90% Wood: 10% Light: 30% Heavy: 10% Concrete: 10% - InfDeath: 1 - Damage: 120 Teeth: ROF: 30 Range: 1c0 Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 213 + Damage: 180 + InfDeath: 1 Versus: None: 90% Wood: 10% Light: 30% Heavy: 10% Concrete: 10% - InfDeath: 1 - Damage: 180 Claw: ROF: 10 Range: 1c0 Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 213 + Damage: 60 + InfDeath: 1 Versus: None: 90% Wood: 10% Light: 30% Heavy: 10% Concrete: 10% - InfDeath: 1 - Damage: 60 Demolish: - Warhead: - ImpactSound: xplobig6.aud + Warhead@1Dam: SpreadDamage + Warhead@2Eff: CreateEffect Explosion: building + ImpactSound: xplobig6.aud diff --git a/mods/d2k/weapons.yaml b/mods/d2k/weapons.yaml index e0947637c1..73076340db 100644 --- a/mods/d2k/weapons.yaml +++ b/mods/d2k/weapons.yaml @@ -8,16 +8,17 @@ LMG: TrailInterval: 1 ContrailDelay: 0 ContrailUsePlayerColor: true - Warhead: + Warhead@1Dam: SpreadDamage Spread: 96 + Damage: 15 + InfDeath: 2 Versus: Wood: 25% Light: 40% Heavy: 10% Concrete: 20% + Warhead@2Eff: CreateEffect Explosion: piffs - InfDeath: 2 - Damage: 15 Bazooka: ROF: 50 @@ -32,18 +33,20 @@ Bazooka: Image: RPG ROT: 5 RangeLimit: 35 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 96 + Damage: 50 + InfDeath: 4 Versus: None: 10% Wood: 75% Light: 60% Heavy: 90% Concrete: 40% - Explosion: small_explosion - InfDeath: 4 + Warhead@2Smu: LeaveSmudge SmudgeType: SandCrater, RockCrater - Damage: 50 + Warhead@3Eff: CreateEffect + Explosion: small_explosion ImpactSound: EXPLSML1.WAV Sniper: @@ -56,16 +59,16 @@ Sniper: TrailInterval: 1 ContrailDelay: 0 ContrailUsePlayerColor: true - Warhead: - Damage: 60 + Warhead@1Dam: SpreadDamage Spread: 32 + Damage: 60 + InfDeath: 2 Versus: None: 100% Wood: 0% Light: 1% Heavy: 0% Concrete: 0% - InfDeath: 2 Vulcan: ROF: 30 @@ -78,16 +81,17 @@ Vulcan: TrailInterval: 1 ContrailDelay: 0 ContrailUsePlayerColor: true - Warhead: + Warhead@1Dam: SpreadDamage Spread: 96 + Damage: 30 + InfDeath: 2 Versus: Wood: 0% Light: 60% Heavy: 10% Concrete: 0% + Warhead@2Eff: CreateEffect Explosion: piffs - InfDeath: 2 - Damage: 30 Slung: ROF: 60 @@ -102,17 +106,18 @@ Slung: Angle: 88 Inaccuracy: 384 Image: MISSILE - Warhead: + Warhead@1Dam: SpreadDamage Spread: 192 + Damage: 30 + InfDeath: 4 Versus: None: 0% Wood: 75% Light: 40% Heavy: 90% Concrete: 50% + Warhead@2Eff: CreateEffect Explosion: small_explosion - InfDeath: 4 - Damage: 30 ImpactSound: EXPLLG5.WAV HMG: @@ -127,16 +132,17 @@ HMG: TrailInterval: 1 ContrailDelay: 0 ContrailUsePlayerColor: true - Warhead: + Warhead@1Dam: SpreadDamage Spread: 96 + Damage: 30 + InfDeath: 2 Versus: Wood: 15% Light: 45% Heavy: 20% Concrete: 20% + Warhead@2Eff: CreateEffect Explosion: piffs - InfDeath: 2 - Damage: 30 HMGo: ROF: 30 @@ -150,16 +156,17 @@ HMGo: TrailInterval: 1 ContrailDelay: 0 ContrailUsePlayerColor: true - Warhead: + Warhead@1Dam: SpreadDamage Spread: 96 + Damage: 40 + InfDeath: 2 Versus: Wood: 15% Light: 45% Heavy: 25% Concrete: 20% + Warhead@2Eff: CreateEffect Explosion: piffs - InfDeath: 2 - Damage: 40 QuadRockets: ROF: 40 @@ -175,19 +182,21 @@ QuadRockets: ROT: 10 Speed: 256 RangeLimit: 40 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 96 + Damage: 25 + InfDeath: 4 Versus: None: 35% Wood: 45% Light: 100% Heavy: 100% Concrete: 35% - InfDeath: 4 + Warhead@2Smu: LeaveSmudge + SmudgeType: SandCrater, RockCrater + Warhead@3Eff: CreateEffect Explosion: med_explosion ImpactSound: EXPLSML1.WAV - SmudgeType: SandCrater, RockCrater - Damage: 25 TurretGun: ROF: 35 @@ -199,18 +208,20 @@ TurretGun: Shadow: no Inaccuracy: 288 Image: 120mm - Warhead: + Warhead@1Dam: SpreadDamage Spread: 256 + Damage: 55 + InfDeath: 4 Versus: None: 50% Wood: 75% Light: 100% Concrete: 65% + Warhead@2Smu: LeaveSmudge + SmudgeType: SandCrater, RockCrater + Warhead@3Eff: CreateEffect Explosion: small_napalm ImpactSound: EXPLSML4.WAV - InfDeath: 4 - SmudgeType: SandCrater, RockCrater - Damage: 55 TowerMissile: ROF: 35 @@ -230,19 +241,21 @@ TowerMissile: Speed: 256 RangeLimit: 50 Angle: 110 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 384 + Damage: 50 + InfDeath: 3 Versus: None: 50% Wood: 45% Light: 100% Heavy: 50% Concrete: 35% - InfDeath: 3 + Warhead@2Smu: LeaveSmudge + SmudgeType: SandCrater, RockCrater + Warhead@3Eff: CreateEffect Explosion: small_explosion ImpactSound: EXPLMD1.WAV - SmudgeType: SandCrater, RockCrater - Damage: 50 90mm: ROF: 50 @@ -252,18 +265,20 @@ TowerMissile: Speed: 640 Inaccuracy: 384 Image: 120mm - Warhead: + Warhead@1Dam: SpreadDamage Spread: 256 + Damage: 40 + InfDeath: 4 Versus: None: 50% Wood: 50% Light: 100% Concrete: 50% + Warhead@2Smu: LeaveSmudge + SmudgeType: SandCrater, RockCrater + Warhead@3Eff: CreateEffect Explosion: small_napalm ImpactSound: EXPLSML4.WAV - InfDeath: 4 - SmudgeType: SandCrater, RockCrater - Damage: 40 90mma: ROF: 50 @@ -273,18 +288,20 @@ TowerMissile: Speed: 704 Inaccuracy: 352 Image: 120mm - Warhead: + Warhead@1Dam: SpreadDamage Spread: 256 + Damage: 40 + InfDeath: 4 Versus: None: 50% Wood: 50% Light: 100% Concrete: 50% + Warhead@2Smu: LeaveSmudge + SmudgeType: SandCrater, RockCrater + Warhead@3Eff: CreateEffect Explosion: small_napalm ImpactSound: EXPLSML4.WAV - InfDeath: 4 - SmudgeType: SandCrater, RockCrater - Damage: 40 DevBullet: ROF: 50 @@ -293,18 +310,20 @@ DevBullet: Projectile: Bullet Speed: 640 Image: doubleblastbullet - Warhead: + Warhead@1Dam: SpreadDamage Spread: 256 + Damage: 100 + InfDeath: 4 Versus: None: 100% Wood: 50% Light: 100% Heavy: 100% Concrete: 80% - Explosion: shockwave - InfDeath: 4 + Warhead@2Smu: LeaveSmudge SmudgeType: SandCrater, RockCrater - Damage: 100 + Warhead@3Eff: CreateEffect + Explosion: shockwave 227mm: ROF: 100 @@ -324,19 +343,21 @@ DevBullet: Image: MISSILE2 ROT: 5 ContrailLength: 5 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 384 + Damage: 60 + InfDeath: 4 Versus: None: 20% Wood: 50% Light: 100% Heavy: 50% Concrete: 80% - InfDeath: 4 + Warhead@2Smu: LeaveSmudge + SmudgeType: SandCrater, RockCrater + Warhead@3Eff: CreateEffect Explosion: mini_explosion ImpactSound: EXPLMD3.WAV - SmudgeType: SandCrater, RockCrater - Damage: 60 FakeMissile: ROF: 120 @@ -352,15 +373,17 @@ FakeMissile: Image: MISSILE ContrailLength: 15 ContrailUsePlayerColor: True - Warhead: + Warhead@1Dam: SpreadDamage Spread: 96 + Damage: 10 Versus: None: 0% Wood: 0% Concrete: 0% - Explosion: deviator + Warhead@2Smu: LeaveSmudge SmudgeType: SandCrater, RockCrater - Damage: 10 + Warhead@3Eff: CreateEffect + Explosion: deviator ImpactSound: EXPLSML2.WAV 155mm: @@ -376,19 +399,21 @@ FakeMissile: Inaccuracy: 1c256 ContrailLength: 20 Image: 155mm - Warhead: + Warhead@1Dam: SpreadDamage Spread: 384 + Damage: 100 + InfDeath: 3 Versus: None: 100% Wood: 80% Light: 75% Heavy: 50% Concrete: 100% + Warhead@2Smu: LeaveSmudge + SmudgeType: SandCrater, RockCrater + Warhead@3Eff: CreateEffect Explosion: large_explosion ImpactSound: EXPLLG3.WAV - InfDeath: 3 - SmudgeType: SandCrater, RockCrater - Damage: 100 Sound: ROF: 100 @@ -399,15 +424,15 @@ Sound: HitAnim: laserfire BeamDuration: 8 UsePlayerColor: true - Warhead: + Warhead@1Dam: SpreadDamage Spread: 32 + Damage: 150 + InfDeath: 6 Versus: None: 60% Wood: 85% Light: 80% Concrete: 75% - InfDeath: 6 - Damage: 150 ChainGun: ROF: 10 @@ -417,16 +442,17 @@ ChainGun: Projectile: Bullet Speed: 1c256 High: true - Warhead: + Warhead@1Dam: SpreadDamage Spread: 96 + Damage: 20 + InfDeath: 2 Versus: Wood: 50% Light: 60% Heavy: 25% Concrete: 25% + Warhead@2Eff: CreateEffect Explosion: piffs - InfDeath: 2 - Damage: 20 Heal: ROF: 160 @@ -434,26 +460,26 @@ Heal: Report: Projectile: Bullet Speed: 1c256 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 160 + Damage: -50 + InfDeath: 1 Versus: Wood: 0% Light: 0% Heavy: 0% Concrete: 0% - InfDeath: 1 - Damage: -50 WormJaw: ROF: 10 Range: 3c0 Report: WORM.WAV - Warhead: + Warhead@1Dam: SpreadDamage Spread: 160 + Damage: 100 Versus: Wood: 0% Concrete: 0% - Damage: 100 ParaBomb: ROF: 10 @@ -461,17 +487,19 @@ ParaBomb: Report: Projectile: GravityBomb Image: BOMBS - Warhead: + Warhead@1Dam: SpreadDamage Spread: 192 + Damage: 500 + InfDeath: 4 Versus: None: 30% Wood: 75% Light: 75% Concrete: 50% - Explosion: self_destruct - InfDeath: 4 + Warhead@2Smu: LeaveSmudge SmudgeType: Crater - Damage: 500 + Warhead@3Eff: CreateEffect + Explosion: self_destruct ImpactSound: EXPLLG3.WAV Napalm: @@ -479,121 +507,132 @@ Napalm: Range: 3c0 Projectile: GravityBomb Image: BOMBS - Warhead: + Warhead@1Dam: SpreadDamage Spread: 640 + Damage: 300 + InfDeath: 4 Versus: None: 20% Wood: 100% Light: 30% Heavy: 20% Concrete: 70% - InfDeath: 4 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: artillery ImpactSound: NAPALM1.WAV - SmudgeType: Crater - Damage: 300 Crush: - Warhead: - ImpactSound: CRUSH1.WAV + Warhead@1Dam: SpreadDamage Damage: 100 + Warhead@2Eff: CreateEffect + ImpactSound: CRUSH1.WAV Demolish: - Warhead: - ImpactSound: EXPLLG2.WAV + Warhead@1Dam: SpreadDamage + Warhead@2Eff: CreateEffect Explosion: building + ImpactSound: EXPLLG2.WAV Atomic: - Warhead: - Damage: 1800 + Warhead@1Dam: SpreadDamage Spread: 2c0 + Damage: 1800 + InfDeath: 5 Versus: None: 100% Wood: 100% Light: 100% Heavy: 50% Concrete: 50% + Warhead@2Eff: CreateEffect Explosion: nuke - InfDeath: 5 ImpactSound: EXPLLG2.WAV CrateNuke: - Warhead: - Damage: 800 + Warhead@1Dam: SpreadDamage Spread: 1c576 + Damage: 800 + InfDeath: 5 Versus: None: 20% Wood: 75% Light: 25% Heavy: 25% Concrete: 50% + Warhead@2Eff: CreateEffect Explosion: nuke - InfDeath: 5 ImpactSound: EXPLLG2.WAV CrateExplosion: - Warhead: - Damage: 400 + Warhead@1Dam: SpreadDamage Spread: 320 + Damage: 400 + InfDeath: 4 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% + Warhead@2Eff: CreateEffect Explosion: building - InfDeath: 4 ImpactSound: EXPLSML4.WAV UnitExplode: - Warhead: - Damage: 500 + Warhead@1Dam: SpreadDamage Spread: 320 + Damage: 500 + InfDeath: 4 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% + Warhead@2Eff: CreateEffect Explosion: building - InfDeath: 4 ImpactSound: EXPLMD1.WAV UnitExplodeSmall: - Warhead: - Damage: 60 + Warhead@1Dam: SpreadDamage Spread: 320 + Damage: 60 + InfDeath: 4 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% + Warhead@2Eff: CreateEffect Explosion: self_destruct - InfDeath: 4 ImpactSound: EXPLHG1.WAV, EXPLLG1.WAV, EXPLMD1.WAV, EXPLSML4.WAV UnitExplodeTiny: - Warhead: - Damage: 30 + Warhead@1Dam: SpreadDamage Spread: 224 + Damage: 30 + InfDeath: 4 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% + Warhead@2Eff: CreateEffect Explosion: med_explosion - InfDeath: 4 ImpactSound: EXPLMD2.WAV, EXPLSML1.WAV, EXPLSML2.WAV, EXPLSML3.WAV UnitExplodeScale: - Warhead: - Damage: 90 + Warhead@1Dam: SpreadDamage Spread: 416 + Damage: 90 + InfDeath: 4 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% + Warhead@2Eff: CreateEffect Explosion: building - InfDeath: 4 ImpactSound: EXPLLG2.WAV, EXPLLG3.WAV, EXPLLG5.WAV Grenade: @@ -606,22 +645,24 @@ Grenade: Angle: 62 Inaccuracy: 416 Image: BOMBS - Warhead: + Warhead@1Dam: SpreadDamage Spread: 192 + Damage: 60 + InfDeath: 3 Versus: None: 50% Wood: 100% Light: 25% Heavy: 5% - Explosion: med_explosion - InfDeath: 3 + Warhead@2Smu: LeaveSmudge SmudgeType: SandCrater - Damage: 60 + Warhead@3Eff: CreateEffect + Explosion: med_explosion ImpactSound: EXPLLG5.WAV Weathering: ROF: 100 - Warhead: + Warhead@1Dam: SpreadDamage Damage: 5 Shrapnel: @@ -634,31 +675,35 @@ Shrapnel: Angle: 91, 264 Inaccuracy: 416 Image: bombs - Warhead: + Warhead@1Dam: SpreadDamage Spread: 192 + Damage: 60 + InfDeath: 3 Versus: None: 50% Wood: 100% Light: 25% Heavy: 5% - Explosion: med_explosion - InfDeath: 3 + Warhead@2Smu: LeaveSmudge SmudgeType: SandCrater - Damage: 60 + Warhead@3Eff: CreateEffect + Explosion: med_explosion ImpactSound: EXPLLG5.WAV SpiceExplosion: - Warhead: - Damage: 10 + Warhead@1Dam: SpreadDamage Spread: 9 - Size: 2,2 + Damage: 10 + InfDeath: 3 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% - Explosion: med_explosion - InfDeath: 3 - ImpactSound: EXPLLG5.WAV + Warhead@2Res: CreateResource AddsResourceType: Spice + Size: 2,2 + Warhead@3Eff: CreateEffect + Explosion: med_explosion + ImpactSound: EXPLLG5.WAV diff --git a/mods/ra/maps/allies-01-classic/map.yaml b/mods/ra/maps/allies-01-classic/map.yaml index 8640ce3e31..3e9eafda8f 100644 --- a/mods/ra/maps/allies-01-classic/map.yaml +++ b/mods/ra/maps/allies-01-classic/map.yaml @@ -615,7 +615,7 @@ Weapons: Range: 5c0 ROF: 20 Burst: 1 - Warhead: + Warhead: SpreadDamage Damage: 20 Voices: diff --git a/mods/ra/maps/allies-02-classic/map.yaml b/mods/ra/maps/allies-02-classic/map.yaml index 873b9996da..c075d75304 100644 --- a/mods/ra/maps/allies-02-classic/map.yaml +++ b/mods/ra/maps/allies-02-classic/map.yaml @@ -951,7 +951,7 @@ Weapons: Range: 5c0 ROF: 20 Burst: 1 - Warhead: + Warhead: SpreadDamage Damage: 20 Voices: diff --git a/mods/ra/maps/drop-zone-battle-of-tikiaki/map.yaml b/mods/ra/maps/drop-zone-battle-of-tikiaki/map.yaml index bb3e1e50b8..52eae61774 100644 --- a/mods/ra/maps/drop-zone-battle-of-tikiaki/map.yaml +++ b/mods/ra/maps/drop-zone-battle-of-tikiaki/map.yaml @@ -364,7 +364,7 @@ Weapons: PortaTesla: ROF: 20 Range: 10c0 - Warhead: + Warhead: SpreadDamage Spread: 42 InfDeath: 5 Damage: 80 diff --git a/mods/ra/maps/drop-zone-w/map.yaml b/mods/ra/maps/drop-zone-w/map.yaml index 37bbc994d2..dba9624318 100644 --- a/mods/ra/maps/drop-zone-w/map.yaml +++ b/mods/ra/maps/drop-zone-w/map.yaml @@ -313,20 +313,22 @@ Weapons: Inaccuracy: 3c341 Image: 120MM ContrailLength: 30 - Warhead: + Warhead: SpreadDamage Spread: 128 Versus: None: 60% Wood: 75% Light: 60% Heavy: 25% + InfDeath: 2 + Damage: 250 + Warhead@1Eff: CreateEffect Explosion: large_explosion WaterExplosion: large_splash - InfDeath: 2 - SmudgeType: Crater - Damage: 250 ImpactSound: kaboom12.aud WaterImpactSound: splash9.aud + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater SubMissile: ROF: 250 Range: 32c0 @@ -340,19 +342,21 @@ Weapons: Image: MISSILE Trail: smokey ContrailLength: 30 - Warhead: + Warhead: SpreadDamage Spread: 426 Versus: None: 40% Light: 30% Heavy: 30% + InfDeath: blownaway + Damage: 400 + Warhead@1Eff: CreateEffect Explosion: large_explosion WaterExplosion: large_splash - InfDeath: blownaway - SmudgeType: Crater - Damage: 400 ImpactSound: kaboom12.aud WaterImpactSound: splash9.aud + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater Voices: diff --git a/mods/ra/maps/drop-zone/map.yaml b/mods/ra/maps/drop-zone/map.yaml index 447e6bb86e..5785d7ca5a 100644 --- a/mods/ra/maps/drop-zone/map.yaml +++ b/mods/ra/maps/drop-zone/map.yaml @@ -259,7 +259,7 @@ Weapons: PortaTesla: ROF: 20 Range: 10c0 - Warhead: + Warhead: SpreadDamage Spread: 42 InfDeath: 5 Damage: 80 diff --git a/mods/ra/maps/fort-lonestar/map.yaml b/mods/ra/maps/fort-lonestar/map.yaml index 7bc04b874a..acd4f33ba0 100644 --- a/mods/ra/maps/fort-lonestar/map.yaml +++ b/mods/ra/maps/fort-lonestar/map.yaml @@ -771,24 +771,26 @@ Weapons: Inaccuracy: 1c682 Image: 120MM ContrailLength: 50 - Warhead: + Warhead: SpreadDamage Spread: 256 Versus: None: 75% Wood: 75% Light: 75% Concrete: 100% + InfDeath: 4 + Damage: 150 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: self_destruct WaterExplosion: self_destruct - InfDeath: 4 - SmudgeType: Crater - Damage: 150 MammothTusk: ROF: 300 Range: 10c0 Report: MISSILE6.AUD Burst: 2 - ValidTargets: Ground, Air + ValidTargets: Ground, Air, Enemy, Neutral, Ally Projectile: Missile Speed: 128 Arm: 2 @@ -801,7 +803,7 @@ Weapons: Image: DRAGON ROT: 10 RangeLimit: 80 - Warhead: + Warhead: SpreadDamage Spread: 640 Versus: None: 125% @@ -809,16 +811,18 @@ Weapons: Light: 110% Heavy: 100% Concrete: 200% + InfDeath: 3 + Damage: 250 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: nuke WaterExplosion: nuke - InfDeath: 3 - SmudgeType: Crater - Damage: 250 TankNapalm: ROF: 40 Range: 8c0 Report: AACANON3.AUD - ValidTargets: Ground + ValidTargets: Ground, Enemy, Neutral, Ally Burst: 6 BurstDelay: 1 Projectile: Bullet @@ -827,7 +831,7 @@ Weapons: Inaccuracy: 2c512 Trail: smokey ContrailLength: 2 - Warhead: + Warhead: SpreadDamage Spread: 341 Versus: None: 90% @@ -835,31 +839,35 @@ Weapons: Light: 100% Heavy: 100% Concrete: 100% + InfDeath: 4 + Damage: 15 + Warhead@2Smu: LeaveSmudge + SmudgeType: Scorch + Warhead@3Eff: CreateEffect Explosion: small_explosion WaterExplosion: small_explosion - InfDeath: 4 - SmudgeType: Scorch ImpactSound: firebl3.aud - Damage: 15 ParaBomb: ROF: 5 Range: 5c0 Report: CHUTE1.AUD Projectile: GravityBomb Image: BOMBLET - Warhead: + Warhead: SpreadDamage Spread: 426 Versus: None: 125% Wood: 100% Light: 60% Concrete: 25% + InfDeath: 5 + Damage: 200 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: napalm ImpactSound: firebl3.aud WaterExplosion: napalm - InfDeath: 5 - SmudgeType: Crater - Damage: 200 155mm: ROF: 10 Range: 7c5 @@ -874,7 +882,7 @@ Weapons: Angle: 30 Inaccuracy: 1c682 ContrailLength: 2 - Warhead: + Warhead: SpreadDamage Spread: 426 Versus: None: 80% @@ -882,21 +890,23 @@ Weapons: Light: 60% Heavy: 75% Concrete: 35% + InfDeath: 5 + Damage: 10 + Warhead@2Smu: LeaveSmudge + SmudgeType: Scorch + Warhead@3Eff: CreateEffect Explosion: small_napalm WaterExplosion: small_napalm - InfDeath: 5 - SmudgeType: Scorch ImpactSound: firebl3.aud - Damage: 10 FLAK-23: ROF: 10 Range: 8c0 Report: AACANON3.AUD - ValidTargets: Air,Ground + ValidTargets: Air, Ground, Enemy, Neutral, Ally Projectile: Bullet Speed: 1c682 High: true - Warhead: + Warhead: SpreadDamage Spread: 213 Versus: None: 35% @@ -904,8 +914,11 @@ Weapons: Light: 30% Heavy: 40% Concrete: 30% - Explosion: med_explosion Damage: 25 + Warhead@2Smu: LeaveSmudge + SmudgeType: Scorch + Warhead@3Eff: CreateEffect + Explosion: med_explosion SCUD: ROF: 280 Range: 7c0 @@ -921,18 +934,20 @@ Weapons: Inaccuracy: 426 Image: V2 Angle: 216 - Warhead: + Warhead: SpreadDamage Spread: 853 Versus: None: 100% Wood: 90% Light: 80% Heavy: 70% + InfDeath: 3 + Damage: 500 + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: nuke WaterExplosion: large_splash - InfDeath: 3 - SmudgeType: Crater - Damage: 500 ImpactSound: kaboom1.aud WaterImpactSound: kaboom1.aud SilencedPPK: @@ -941,16 +956,17 @@ Weapons: Report: silppk.aud Projectile: Bullet Speed: 1c682 - Warhead: + Warhead: SpreadDamage Spread: 128 Versus: Wood: 0% Light: 0% Heavy: 50% Concrete: 0% - Explosion: piffs InfDeath: 2 Damage: 150 + Warhead@2Eff: CreateEffect + Explosion: piffs Voices: diff --git a/mods/ra/maps/intervention/map.yaml b/mods/ra/maps/intervention/map.yaml index bcc3e8dd43..68e346b5d2 100644 --- a/mods/ra/maps/intervention/map.yaml +++ b/mods/ra/maps/intervention/map.yaml @@ -2333,7 +2333,7 @@ Weapons: Nike: Range: 9c0 Maverick: - Warhead: + Warhead: SpreadDamage Damage: 175 Voices: diff --git a/mods/ra/maps/training-camp/map.yaml b/mods/ra/maps/training-camp/map.yaml index d2df90c9d0..befe08c63c 100644 --- a/mods/ra/maps/training-camp/map.yaml +++ b/mods/ra/maps/training-camp/map.yaml @@ -1076,12 +1076,10 @@ VoxelSequences: Weapons: CrateNuke: - Warhead@areanuke2: + Warhead@areanuke2: SpreadDamage DamageModel: PerCell Damage: 250 - SmudgeType: Scorch - Size: 4,3 - Ore: true + Size: 4 Versus: None: 90% Light: 60% @@ -1089,13 +1087,21 @@ Weapons: Concrete: 50% Delay: 12 InfDeath: 4 + Warhead@areanuke2Smu: LeaveSmudge + SmudgeType: Scorch + Size: 4,3 + Delay: 12 + Warhead@areanuke2Res: DestroyResource + DestroyResources: true + Size: 4,3 + Delay: 12 + Warhead@areanuke2Eff: CreateEffect ImpactSound: kaboom22 - Warhead@areanuke3: + Delay: 12 + Warhead@areanuke3: SpreadDamage DamageModel: PerCell Damage: 250 - SmudgeType: Scorch - Size: 3,2 - Ore: true + Size: 3 Versus: None: 90% Light: 60% @@ -1103,13 +1109,20 @@ Weapons: Concrete: 50% Delay: 24 InfDeath: 4 + Warhead@areanuke3Smu: LeaveSmudge + SmudgeType: Scorch + Size: 3,2 + Delay: 24 + Warhead@areanuke3Res: DestroyResource + DestroyResources: true + Size: 3,2 + Delay: 24 + Warhead@areanuke3Eff: CreateEffect ImpactSound: kaboom22 - Warhead@areanuke4: + Delay: 24 + Warhead@areanuke4: SpreadDamage DamageModel: PerCell Damage: 250 - SmudgeType: Scorch - Size: 2,1 - Ore: true Versus: None: 90% Light: 60% @@ -1117,7 +1130,17 @@ Weapons: Concrete: 50% Delay: 36 InfDeath: 4 + Warhead@areanuke4Smu: LeaveSmudge + SmudgeType: Scorch + Size: 2,1 + Delay: 36 + Warhead@areanuke4Res: DestroyResource + DestroyResources: true + Size: 2,1 + Delay: 36 + Warhead@areanuke4Eff: CreateEffect ImpactSound: kaboom22 + Delay: 36 Voices: diff --git a/mods/ra/weapons.yaml b/mods/ra/weapons.yaml index c0125d2b03..4aa72df11b 100644 --- a/mods/ra/weapons.yaml +++ b/mods/ra/weapons.yaml @@ -4,18 +4,19 @@ Colt45: Report: GUN5.AUD Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 42 + Damage: 50 + InfDeath: 2 Versus: None: 100% Wood: 0% Light: 0% Heavy: 0% Concrete: 0% + Warhead@2Eff: CreateEffect Explosion: piff WaterExplosion: water_piff - InfDeath: 2 - Damage: 50 ZSU-23: Burst: 2 @@ -27,15 +28,16 @@ ZSU-23: Projectile: Bullet Speed: 1c682 High: true - Warhead: + Warhead@1Dam: SpreadDamage Spread: 213 + Damage: 12 Versus: None: 30% Wood: 75% Light: 75% Concrete: 50% + Warhead@2Eff: CreateEffect Explosion: small_explosion_air - Damage: 12 Vulcan: ROF: 30 @@ -43,76 +45,87 @@ Vulcan: Report: GUN13.AUD Projectile: Bullet Speed: 1c682 - Warhead@1: + Warhead@1Dam_1: SpreadDamage Spread: 128 + Damage: 10 + InfDeath: 2 Versus: Wood: 50% Light: 60% Heavy: 25% Concrete: 25% + Warhead@2Eff_1: CreateEffect Explosion: piffs WaterExplosion: water_piffs - InfDeath: 2 - Damage: 10 - Warhead@2: + Warhead@3Dam_2: SpreadDamage Spread: 128 - Versus: - Wood: 50% - Light: 60% - Heavy: 25% - Concrete: 25% - Explosion: piffs - WaterExplosion: water_piffs - InfDeath: 2 Damage: 10 + InfDeath: 2 Delay: 2 - Warhead@3: - Spread: 128 Versus: Wood: 50% Light: 60% Heavy: 25% Concrete: 25% + Warhead@4Eff_2: CreateEffect Explosion: piffs WaterExplosion: water_piffs - InfDeath: 2 + Delay: 2 + Warhead@5Dam_3: SpreadDamage + Spread: 128 Damage: 10 + InfDeath: 2 Delay: 4 - Warhead@4: - Spread: 128 Versus: Wood: 50% Light: 60% Heavy: 25% Concrete: 25% + Warhead@6Eff_3: CreateEffect Explosion: piffs WaterExplosion: water_piffs - InfDeath: 2 + Delay: 4 + Warhead@7Dam_4: SpreadDamage + Spread: 128 Damage: 10 + InfDeath: 2 Delay: 6 - Warhead@5: - Spread: 128 Versus: Wood: 50% Light: 60% Heavy: 25% Concrete: 25% + Warhead@8Eff_4: CreateEffect Explosion: piffs WaterExplosion: water_piffs - InfDeath: 2 + Delay: 6 + Warhead@9Dam_5: SpreadDamage + Spread: 128 Damage: 10 + InfDeath: 2 Delay: 8 - Warhead@6: - Spread: 128 Versus: Wood: 50% Light: 60% Heavy: 25% Concrete: 25% + Warhead@10Eff_5: CreateEffect Explosion: piffs WaterExplosion: water_piffs - InfDeath: 2 + Delay: 8 + Warhead@11Dam_6: SpreadDamage + Spread: 128 Damage: 10 + InfDeath: 2 + Delay: 10 + Versus: + Wood: 50% + Light: 60% + Heavy: 25% + Concrete: 25% + Warhead@12Eff_6: CreateEffect + Explosion: piffs + WaterExplosion: water_piffs Delay: 10 Maverick: @@ -132,20 +145,22 @@ Maverick: Image: DRAGON ROT: 5 RangeLimit: 60 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 70 + InfDeath: 4 Versus: None: 30% Wood: 75% Light: 75% Concrete: 50% + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: med_explosion WaterExplosion: med_splash ImpactSound: kaboom25.aud WaterImpactSound: splash9.aud - InfDeath: 4 - SmudgeType: Crater - Damage: 70 FireballLauncher: ROF: 65 @@ -156,20 +171,22 @@ FireballLauncher: Speed: 204 Trail: fb2 Image: FB1 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 213 + Damage: 150 + InfDeath: 5 Versus: None: 90% Wood: 50% Light: 60% Heavy: 25% Concrete: 50% + Warhead@2Smu: LeaveSmudge + SmudgeType: Scorch + Warhead@3Eff: CreateEffect Explosion: napalm WaterExplosion: napalm - InfDeath: 5 - SmudgeType: Scorch ImpactSound: firebl3.aud - Damage: 150 Flamer: ROF: 50 @@ -182,20 +199,22 @@ Flamer: Image: fb3 Angle: 62 Inaccuracy: 853 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 341 + Damage: 8 + InfDeath: 5 Versus: None: 90% Wood: 100% Light: 60% Heavy: 25% Concrete: 50% + Warhead@2Smu: LeaveSmudge + SmudgeType: Scorch + Warhead@3Eff: CreateEffect Explosion: small_napalm WaterExplosion: small_napalm - InfDeath: 5 - SmudgeType: Scorch ImpactSound: firebl3.aud - Damage: 8 ChainGun: ROF: 10 @@ -205,18 +224,19 @@ ChainGun: Projectile: Bullet Speed: 1c682 High: true - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 30 + InfDeath: 2 Versus: None: 120% Wood: 50% Light: 60% Heavy: 25% Concrete: 25% + Warhead@2Eff: CreateEffect Explosion: piffs WaterExplosion: water_piffs - InfDeath: 2 - Damage: 30 ChainGun.Yak: ROF: 3 @@ -226,17 +246,18 @@ ChainGun.Yak: Projectile: Bullet Speed: 1c682 High: true - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 40 + InfDeath: 2 Versus: Wood: 50% Light: 60% Heavy: 25% Concrete: 25% + Warhead@2Eff: CreateEffect Explosion: piffs WaterExplosion: water_piffs - InfDeath: 2 - Damage: 40 Pistol: ROF: 7 @@ -244,17 +265,18 @@ Pistol: Report: GUN27.AUD Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 1 + InfDeath: 2 Versus: Wood: 50% Light: 60% Heavy: 25% Concrete: 25% + Warhead@2Eff: CreateEffect Explosion: piff WaterExplosion: water_piff - InfDeath: 2 - Damage: 1 M1Carbine: ROF: 20 @@ -262,17 +284,18 @@ M1Carbine: Report: GUN11.AUD Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 15 + InfDeath: 2 Versus: Wood: 25% Light: 30% Heavy: 10% Concrete: 10% + Warhead@2Eff: CreateEffect Explosion: piffs WaterExplosion: water_piffs - InfDeath: 2 - Damage: 15 Dragon: ROF: 50 @@ -289,18 +312,20 @@ Dragon: Image: DRAGON ROT: 5 RangeLimit: 35 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 50 + InfDeath: 4 Versus: None: 10% Wood: 75% Light: 35% Concrete: 20% + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: med_explosion WaterExplosion: med_splash - InfDeath: 4 - SmudgeType: Crater - Damage: 50 ImpactSound: kaboom25.aud WaterImpactSound: splash9.aud @@ -320,18 +345,20 @@ HellfireAG: Image: DRAGON ROT: 10 RangeLimit: 20 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 60 + InfDeath: 4 Versus: None: 30% Wood: 75% Light: 75% Concrete: 50% + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: med_explosion WaterExplosion: med_splash - InfDeath: 4 - SmudgeType: Crater - Damage: 60 ImpactSound: kaboom25.aud WaterImpactSound: splash9.aud @@ -351,19 +378,21 @@ HellfireAA: Image: DRAGON ROT: 10 RangeLimit: 20 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 40 + InfDeath: 4 Versus: None: 30% Wood: 75% Light: 75% Concrete: 50% + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: med_explosion_air WaterExplosion: med_splash ImpactSound: kaboom25.aud - InfDeath: 4 - SmudgeType: Crater - Damage: 40 Grenade: ROF: 60 @@ -375,18 +404,20 @@ Grenade: Angle: 62 Inaccuracy: 554 Image: BOMB - Warhead: + Warhead@1Dam: SpreadDamage Spread: 256 + Damage: 60 + InfDeath: 3 Versus: None: 50% Wood: 100% Light: 25% Heavy: 5% + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: med_explosion WaterExplosion: small_splash - InfDeath: 3 - SmudgeType: Crater - Damage: 60 ImpactSound: kaboom25.aud WaterImpactSound: splash9.aud @@ -397,18 +428,20 @@ Grenade: Projectile: Bullet Speed: 853 Image: 50CAL - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 16 + InfDeath: 4 Versus: None: 30% Wood: 40% Heavy: 40% Concrete: 30% + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: small_explosion WaterExplosion: small_splash - InfDeath: 4 - SmudgeType: Crater - Damage: 16 90mm: ROF: 50 @@ -417,20 +450,22 @@ Grenade: Projectile: Bullet Speed: 682 Image: 120MM - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 40 + InfDeath: 4 Versus: None: 20% Wood: 75% Light: 75% Concrete: 50% + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: small_explosion WaterExplosion: small_splash ImpactSound: kaboom12.aud WaterImpactSound: splash9.aud - InfDeath: 4 - SmudgeType: Crater - Damage: 40 105mm: ROF: 70 @@ -441,20 +476,22 @@ Grenade: Projectile: Bullet Speed: 682 Image: 120MM - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 40 + InfDeath: 4 Versus: None: 20% Wood: 75% Light: 75% Concrete: 50% + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: small_explosion WaterExplosion: small_splash ImpactSound: kaboom12.aud WaterImpactSound: splash9.aud - InfDeath: 4 - SmudgeType: Crater - Damage: 40 120mm: ROF: 90 @@ -465,20 +502,22 @@ Grenade: Projectile: Bullet Speed: 682 Image: 120MM - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 60 + InfDeath: 4 Versus: None: 20% Wood: 75% Light: 75% Concrete: 50% + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: small_explosion WaterExplosion: small_splash ImpactSound: kaboom12.aud WaterImpactSound: splash9.aud - InfDeath: 4 - SmudgeType: Crater - Damage: 60 TurretGun: ROF: 30 @@ -487,20 +526,22 @@ TurretGun: Projectile: Bullet Speed: 682 Image: 120MM - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 60 + InfDeath: 4 Versus: None: 20% Wood: 50% Light: 75% Concrete: 50% + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: small_explosion WaterExplosion: small_splash ImpactSound: kaboom12.aud WaterImpactSound: splash9.aud - InfDeath: 4 - SmudgeType: Crater - Damage: 60 MammothTusk: ROF: 60 @@ -517,20 +558,22 @@ MammothTusk: Image: DRAGON ROT: 15 RangeLimit: 40 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 256 + Damage: 50 + InfDeath: 3 Versus: None: 100% Wood: 75% Light: 60% Heavy: 25% + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: med_explosion_air WaterExplosion: med_splash ImpactSound: kaboom25.aud WaterImpactSound: splash9.aud - InfDeath: 3 - SmudgeType: Crater - Damage: 50 155mm: ROF: 85 @@ -544,21 +587,23 @@ MammothTusk: Inaccuracy: 1c682 Image: 120MM ContrailLength: 30 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 426 + Damage: 220 + InfDeath: 3 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% Concrete: 50% + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: artillery_explosion WaterExplosion: med_splash ImpactSound: kaboom15.aud WaterImpactSound: splash9.aud - InfDeath: 3 - SmudgeType: Crater - Damage: 220 M60mg: ROF: 30 @@ -567,17 +612,18 @@ M60mg: Burst: 5 Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 15 + InfDeath: 2 Versus: Wood: 10% Light: 30% Heavy: 10% Concrete: 10% + Warhead@2Eff: CreateEffect Explosion: piffs WaterExplosion: water_piffs - InfDeath: 2 - Damage: 15 Napalm: ROF: 20 @@ -586,78 +632,99 @@ Napalm: Image: BOMBLET Speed: 85 High: yes - Warhead: + Warhead@1Dam: SpreadDamage Spread: 170 + Damage: 100 + InfDeath: 5 Versus: None: 90% Light: 60% Heavy: 25% Concrete: 50% + Warhead@2Smu: LeaveSmudge + SmudgeType: Scorch + Warhead@3Eff: CreateEffect Explosion: napalm WaterExplosion: med_splash - InfDeath: 5 - SmudgeType: Scorch ImpactSound: firebl3.aud WaterImpactSound: splash9.aud - Damage: 100 CrateNapalm: - Warhead: + Warhead@1Dam: SpreadDamage Spread: 170 + Damage: 600 + InfDeath: 5 Versus: None: 90% Light: 60% Heavy: 25% Concrete: 50% + Warhead@2Smu: LeaveSmudge + SmudgeType: Scorch + Warhead@3Eff: CreateEffect Explosion: napalm WaterExplosion: napalm - InfDeath: 5 - SmudgeType: Scorch ImpactSound: firebl3.aud - Damage: 600 CrateExplosion: - Warhead: - Damage: 500 + Warhead@1Dam: SpreadDamage Spread: 426 + Damage: 500 + InfDeath: 4 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% + Warhead@2Eff: CreateEffect Explosion: self_destruct WaterExplosion: self_destruct - InfDeath: 4 ImpactSound: kaboom15.aud CrateNuke: - Warhead@impact: - Damage: 1000 + Warhead@1Dam_impact: SpreadDamage Spread: 256 - DestroyResources: true + Damage: 1000 + InfDeath: 5 Versus: None: 90% Light: 60% Heavy: 25% Concrete: 50% + Warhead@2Res_impact: DestroyResource + Warhead@3Eff_impact: CreateEffect Explosion: nuke WaterExplosion: nuke - InfDeath: 5 ImpactSound: kaboom1.aud - Warhead@areanuke: - DamageModel: PerCell - Damage: 250 - SmudgeType: Scorch + Warhead@4Dam_areanuke: PerCellDamage Size: 5,4 - DestroyResources: true + Damage: 250 + InfDeath: 5 + Delay: 4 Versus: None: 90% Light: 60% Heavy: 25% Concrete: 50% - Delay: 4 + Warhead@5Dam_areanuke: SpreadDamage + Damage: 250 InfDeath: 5 + Delay: 4 + Versus: + None: 90% + Light: 60% + Heavy: 25% + Concrete: 50% + Warhead@6Res_areanuke: DestroyResource + Size: 5,4 + Delay: 4 + Warhead@7Smu_areanuke: LeaveSmudge + SmudgeType: Scorch + Size: 5,4 + Delay: 4 + Warhead@8Eff_areanuke: CreateEffect ImpactSound: kaboom22.aud + Delay: 4 TeslaZap: ROF: 3 @@ -665,10 +732,10 @@ TeslaZap: Range: 8c512 Report: TESLA1.AUD Projectile: TeslaZap - Warhead: + Warhead@1Dam: SpreadDamage Spread: 42 - InfDeath: 6 Damage: 100 + InfDeath: 6 Versus: None: 1000% Wood: 60% @@ -686,19 +753,21 @@ Nike: ROT: 25 RangeLimit: 50 Speed: 341 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 50 + InfDeath: 3 Versus: None: 90% Wood: 0% Light: 90% Heavy: 50% Concrete: 0% + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: med_explosion_air ImpactSound: kaboom25.aud - InfDeath: 3 - SmudgeType: Crater - Damage: 50 RedEye: ROF: 50 @@ -713,18 +782,20 @@ RedEye: ROT: 20 RangeLimit: 30 Speed: 298 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 40 + InfDeath: 3 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: med_explosion_air ImpactSound: kaboom25.aud - InfDeath: 3 - SmudgeType: Crater - Damage: 40 8Inch: ROF: 250 @@ -738,18 +809,20 @@ RedEye: Inaccuracy: 2c938 Image: 120MM ContrailLength: 30 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 213 + Damage: 250 + InfDeath: 3 Versus: None: 60% Wood: 75% Light: 60% Heavy: 25% + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: artillery_explosion WaterExplosion: large_splash - InfDeath: 3 - SmudgeType: Crater - Damage: 250 ImpactSound: kaboom15.aud WaterImpactSound: splash9.aud @@ -766,17 +839,19 @@ SubMissile: Image: MISSILE Trail: smokey ContrailLength: 30 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 426 + Damage: 300 + InfDeath: 3 Versus: None: 40% Light: 30% Heavy: 30% + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: artillery_explosion WaterExplosion: large_splash - InfDeath: 3 - SmudgeType: Crater - Damage: 300 ImpactSound: kaboom15.aud WaterImpactSound: splash9.aud @@ -796,20 +871,22 @@ Stinger: RangeLimit: 50 TurboBoost: true Speed: 170 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 30 + InfDeath: 4 Versus: None: 30% Wood: 75% Light: 75% Concrete: 50% + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: med_explosion WaterExplosion: med_splash ImpactSound: kaboom25.aud WaterImpactSound: splash9.aud - InfDeath: 4 - SmudgeType: Crater - Damage: 30 TorpTube: ROF: 100 @@ -827,20 +904,22 @@ TorpTube: ROT: 1 RangeLimit: 160 BoundToTerrainType: Water - Warhead: + Warhead@1Dam: SpreadDamage Spread: 426 + Damage: 180 + InfDeath: 4 Versus: None: 30% Wood: 75% Light: 75% Concrete: 500% - WaterExplosion: large_splash - WaterImpactSound: splash9.aud - Explosion: large_explosion - ImpactSound: kaboom12.aud - InfDeath: 4 + Warhead@2Smu: LeaveSmudge SmudgeType: Crater - Damage: 180 + Warhead@3Eff: CreateEffect + Explosion: large_explosion + WaterExplosion: large_splash + ImpactSound: kaboom12.aud + WaterImpactSound: splash9.aud 2Inch: ROF: 60 @@ -849,20 +928,22 @@ TorpTube: Projectile: Bullet Speed: 426 Image: 120MM - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 25 + InfDeath: 4 Versus: None: 30% Wood: 75% Light: 75% Concrete: 50% + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: small_explosion WaterExplosion: med_splash ImpactSound: kaboom12.aud WaterImpactSound: splash9.aud - InfDeath: 4 - SmudgeType: Crater - Damage: 25 DepthCharge: ROF: 60 @@ -874,18 +955,20 @@ DepthCharge: Angle: 62 High: true Inaccuracy: 128 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 80 + InfDeath: 4 Versus: None: 30% Wood: 75% Light: 75% Concrete: 50% + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect WaterExplosion: large_splash WaterImpactSound: splash9.aud - InfDeath: 4 - SmudgeType: Crater - Damage: 80 ParaBomb: ROF: 10 @@ -895,18 +978,20 @@ ParaBomb: Image: PARABOMB Velocity: 43 Acceleration: 0 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 256 + Damage: 500 + InfDeath: 4 Versus: None: 30% Wood: 75% Light: 75% Concrete: 50% + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: self_destruct WaterExplosion: small_splash - InfDeath: 4 - SmudgeType: Crater - Damage: 500 ImpactSound: kaboom15.aud WaterImpactSound: splash9.aud @@ -915,15 +1000,15 @@ DogJaw: ROF: 10 Range: 3c0 Report: DOGG5P.AUD - Warhead: + Warhead@1Dam: SpreadDamage Spread: 213 + Damage: 100 + InfDeath: 1 Versus: Wood: 0% Light: 0% Heavy: 0% Concrete: 0% - InfDeath: 1 - Damage: 100 Heal: ROF: 80 @@ -931,15 +1016,15 @@ Heal: Report: HEAL2.AUD Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 213 + Damage: -50 + InfDeath: 1 Versus: Wood: 0% Light: 0% Heavy: 0% Concrete: 0% - InfDeath: 1 - Damage: -50 Repair: ROF: 80 @@ -948,16 +1033,16 @@ Repair: ValidTargets: Repair Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 213 + Damage: -20 + InfDeath: 1 Versus: None: 0% Wood: 0% Light: 100% Heavy: 100% Concrete: 0% - InfDeath: 1 - Damage: -20 SilencedPPK: ROF: 80 @@ -965,17 +1050,18 @@ SilencedPPK: Report: silppk.aud Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 150 + InfDeath: 2 Versus: Wood: 0% Light: 0% Heavy: 0% Concrete: 0% + Warhead@2Eff: CreateEffect Explosion: piffs WaterExplosion: water_piffs - InfDeath: 2 - Damage: 150 SCUD: ROF: 240 @@ -991,219 +1077,263 @@ SCUD: Inaccuracy: 213 Image: V2 Angle: 62 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 341 + Damage: 450 + InfDeath: 3 Versus: None: 90% Wood: 75% Light: 70% Heavy: 40% + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: napalm WaterExplosion: large_splash - InfDeath: 3 - SmudgeType: Crater - Damage: 450 ImpactSound: firebl3.aud WaterImpactSound: splash9.aud Atomic: ValidTargets: Ground, Water, Air - Warhead@impact: - Damage: 1500 + Warhead@1Dam_impact: SpreadDamage Spread: 1c0 + Damage: 1500 + InfDeath: 5 + Versus: + Concrete: 25% + Warhead@2Res_impact: DestroyResource + Size: 1 + Warhead@3Smu_impact: LeaveSmudge SmudgeType: Scorch Size: 1 - DestroyResources: true - Versus: - Concrete: 25% + Warhead@4Eff_impact: CreateEffect Explosion: nuke WaterExplosion: nuke - InfDeath: 5 ImpactSound: kaboom1.aud - Warhead@areanuke1: - Damage: 600 + Warhead@5Dam_areanuke1: SpreadDamage Spread: 2c0 + Damage: 600 + InfDeath: 5 + Delay: 5 + Versus: + Concrete: 25% + Warhead@6Res_areanuke1: DestroyResource + Size: 2 + Delay: 5 + Warhead@7Smu_areanuke1: LeaveSmudge SmudgeType: Scorch Size: 2 - DestroyResources: true + Delay: 5 + Warhead@8Eff_areanuke1: CreateEffect + ImpactSound: kaboom22.aud + Delay: 5 + Warhead@9Dam_areanuke2: SpreadDamage + Spread: 3c0 + Damage: 600 + InfDeath: 5 + Delay: 10 Versus: Concrete: 25% - Delay: 5 - InfDeath: 5 - ImpactSound: kaboom22.aud - Warhead@areanuke2: - Damage: 600 - Spread: 3c0 + Warhead@10Res_areanuke2: DestroyResource + Size: 3 + Delay: 10 + Warhead@11Smu_areanuke2: LeaveSmudge SmudgeType: Scorch Size: 3 - DestroyResources: true + Delay: 10 + Warhead@12Dam_areanuke3: SpreadDamage + Spread: 4c0 + Damage: 600 + InfDeath: 5 + Delay: 15 Versus: Concrete: 25% - Delay: 10 - InfDeath: 5 - Warhead@areanuke3: - Damage: 600 - Spread: 4c0 + Warhead@13Res_areanuke3: DestroyResource + Size: 4 + Delay: 15 + Warhead@14Smu_areanuke3: LeaveSmudge SmudgeType: Scorch Size: 4 - DestroyResources: true + Delay: 15 + Warhead@15Dam_areanuke4: SpreadDamage + Spread: 5c0 + Damage: 600 + InfDeath: 5 + Delay: 20 Versus: Concrete: 25% - Delay: 15 - InfDeath: 5 - Warhead@areanuke4: - Damage: 600 - Spread: 5c0 + Warhead@16Res_areanuke4: DestroyResource + Size: 5 + Delay: 20 + Warhead@17Smu_areanuke4: LeaveSmudge SmudgeType: Scorch Size: 5 - DestroyResources: true - Versus: - Concrete: 25% Delay: 20 - InfDeath: 5 MiniNuke: ValidTargets: Ground, Water, Air - Warhead@impact: - Damage: 1500 + Warhead@1Dam_impact: SpreadDamage Spread: 1c0 - Size: 1 - DestroyResources: true + Damage: 1500 + InfDeath: 5 Versus: Concrete: 25% + Warhead@2Res_impact: DestroyResource + Size: 1 + Warhead@3Eff_impact: CreateEffect Explosion: nuke WaterExplosion: nuke - InfDeath: 5 ImpactSound: kaboom1.aud - Warhead@areanuke1: - Damage: 600 + Warhead@4Dam_areanuke1: SpreadDamage Spread: 2c0 - Size: 2 - DestroyResources: true - Versus: - Concrete: 25% + Damage: 600 + InfDeath: 5 Delay: 5 - InfDeath: 5 + Versus: + Concrete: 25% + Warhead@5Res_areanuke1: DestroyResource + Size: 2 + Delay: 5 + Warhead@6Eff_areanuke1: CreateEffect ImpactSound: kaboom22.aud - Warhead@areanuke2: - Damage: 600 + Delay: 5 + Warhead@7Dam_areanuke2: SpreadDamage Spread: 3c0 - Size: 3 - DestroyResources: true - Versus: - Concrete: 25% - Delay: 10 - InfDeath: 5 - Warhead@areanuke3: Damage: 600 - Spread: 4c0 - Size: 4 - SmudgeType: Scorch - DestroyResources: true + InfDeath: 5 + Delay: 10 Versus: Concrete: 25% - Delay: 15 + Warhead@8Res_areanuke2: DestroyResource + Size: 3 + Delay: 10 + Warhead@9Dam_areanuke3: SpreadDamage + Spread: 4c0 + Damage: 600 InfDeath: 5 + Delay: 15 + Versus: + Concrete: 25% + Warhead@10Res_areanuke3: DestroyResource + Size: 4 + Delay: 15 + Warhead@11Smu_areanuke3: LeaveSmudge + SmudgeType: Scorch + Size: 4 + Delay: 15 UnitExplode: - Warhead: - Damage: 500 + Warhead@1Dam: SpreadDamage Spread: 426 + Damage: 500 + InfDeath: 4 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% + Warhead@2Eff: CreateEffect Explosion: self_destruct WaterExplosion: large_splash - InfDeath: 4 ImpactSound: kaboom22.aud WaterImpactSound: splash9.aud UnitExplodeShip: - Warhead: - Damage: 50 + Warhead@1Dam: SpreadDamage Spread: 426 + Damage: 50 + InfDeath: 4 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% + Warhead@2Eff: CreateEffect Explosion: building WaterExplosion: building - InfDeath: 4 ImpactSound: kaboom25.aud WaterImpactSound: kaboom25.aud UnitExplodeSubmarine: - Warhead: - Damage: 50 + Warhead@1Dam: SpreadDamage Spread: 426 + Damage: 50 + InfDeath: 4 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% + Warhead@2Eff: CreateEffect WaterExplosion: large_splash - InfDeath: 4 WaterImpactSound: splash9.aud UnitExplodeSmall: - Warhead: - Damage: 40 + Warhead@1Dam: SpreadDamage Spread: 426 + Damage: 40 + InfDeath: 4 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% + Warhead@2Eff: CreateEffect Explosion: large_explosion WaterExplosion: large_splash - InfDeath: 4 ImpactSound: kaboom15.aud WaterImpactSound: splash9.aud BarrelExplode: - Warhead: - Damage: 500 + Warhead@1Dam: SpreadDamage Spread: 426 + Damage: 500 + InfDeath: 4 + Delay: 5 Versus: None: 120% Wood: 200% Light: 50% Heavy: 25% Concrete: 10% - Explosion: napalm - InfDeath: 4 - ImpactSound: firebl3.aud + Warhead@2Smu: LeaveSmudge SmudgeType: Scorch - Delay: 5 Size: 2,1 + Delay: 5 + Warhead@3Eff: CreateEffect + Explosion: napalm + ImpactSound: firebl3.aud + Delay: 5 Crush: - Warhead: - ImpactSound: squishy2.aud + Warhead@1Dam: SpreadDamage Damage: 100 + Warhead@2Eff: CreateEffect + ImpactSound: squishy2.aud ATMine: - Warhead: + Warhead@1Dam: SpreadDamage Spread: 256 Damage: 400 - ImpactSound: mineblo1.aud + Warhead@2Eff: CreateEffect Explosion: large_explosion + ImpactSound: mineblo1.aud APMine: - Warhead: + Warhead@1Dam: SpreadDamage Spread: 256 Damage: 400 - ImpactSound: mine1.aud InfDeath: 3 + Warhead@2Eff: CreateEffect Explosion: napalm + ImpactSound: mine1.aud Demolish: - Warhead: - ImpactSound: kaboom25.aud + Warhead@1Dam: SpreadDamage + Warhead@2Eff: CreateEffect Explosion: building + ImpactSound: kaboom25.aud PortaTesla: ROF: 70 @@ -1211,10 +1341,10 @@ PortaTesla: Report: TESLA1.AUD Charges: yes Projectile: TeslaZap - Warhead: + Warhead@1Dam: SpreadDamage Spread: 42 - InfDeath: 6 Damage: 45 + InfDeath: 6 Versus: None: 1000% @@ -1224,10 +1354,10 @@ TTankZap: Report: TESLA1.AUD Charges: yes Projectile: TeslaZap - Warhead: + Warhead@1Dam: SpreadDamage Spread: 42 - InfDeath: 6 Damage: 100 + InfDeath: 6 Versus: None: 1000% @@ -1239,17 +1369,18 @@ FLAK-23: Projectile: Bullet Speed: 1c682 High: true - Warhead: + Warhead@1Dam: SpreadDamage Spread: 213 + Damage: 20 Versus: None: 40% Wood: 10% Light: 60% Heavy: 10% Concrete: 20% + Warhead@2Eff: CreateEffect Explosion: small_explosion_air WaterExplosion: small_splash - Damage: 20 Sniper: Report: GUN5.AUD @@ -1257,16 +1388,16 @@ Sniper: Range: 10c0 Projectile: Bullet Speed: 1c682 - Warhead: - Damage: 140 + Warhead@1Dam: SpreadDamage Spread: 42 + Damage: 140 + InfDeath: 2 Versus: None: 100% Wood: 0% Light: 0% Heavy: 0% Concrete: 0% - InfDeath: 2 APTusk: ROF: 60 @@ -1283,86 +1414,99 @@ APTusk: Image: DRAGON ROT: 10 RangeLimit: 22 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 30 + InfDeath: 4 Versus: None: 25% Wood: 75% Light: 75% Concrete: 50% + Warhead@2Smu: LeaveSmudge + SmudgeType: Crater + Warhead@3Eff: CreateEffect Explosion: med_explosion WaterExplosion: med_splash ImpactSound: kaboom25.aud WaterImpactSound: splash9.aud - InfDeath: 4 - SmudgeType: Crater - Damage: 30 Claw: ROF: 30 Range: 1c0 Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 213 + Damage: 33 + InfDeath: 1 Versus: None: 90% Wood: 10% Light: 30% Heavy: 10% Concrete: 10% - InfDeath: 1 - Damage: 33 Mandible: ROF: 10 Range: 1c0 Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 213 + Damage: 60 + InfDeath: 1 Versus: None: 90% Wood: 10% Light: 30% Heavy: 10% Concrete: 10% - InfDeath: 1 - Damage: 60 MADTankThump: InvalidTargets: MADTank - Warhead: - DamageModel: HealthPercentage + Warhead@1Dam: HealthPercentageDamage + Spread: 7c0,6c0 + Damage: 1 + Versus: + None: 0% + Warhead@2Dam: SpreadDamage Damage: 1 Versus: None: 0% - Size: 7,6 MADTankDetonate: InvalidTargets: MADTank - Warhead: - DamageModel: HealthPercentage + Warhead@1Dam: HealthPercentageDamage + Spread: 7c0,6c0 Damage: 19 Versus: None: 0% + Warhead@2Dam: SpreadDamage + Damage: 19 + Versus: + None: 0% + Warhead@3Smu: LeaveSmudge + SmudgeType: Crater Size: 7,6 + Warhead@4Eff: CreateEffect Explosion: med_explosion ImpactSound: mineblo1.aud - SmudgeType: Crater OreExplosion: - Warhead: - Damage: 10 + Warhead@1Dam: SpreadDamage Spread: 9 - Size: 1,1 + Damage: 10 + InfDeath: 3 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% - Explosion: med_explosion - InfDeath: 3 - ImpactSound: kaboom25.aud + Warhead@2Res: CreateResource AddsResourceType: Ore + Size: 1,1 + Warhead@3Eff: CreateEffect + Explosion: med_explosion + ImpactSound: kaboom25.aud diff --git a/mods/ts/weapons.yaml b/mods/ts/weapons.yaml index 3322c58a1f..d79f17dcf8 100644 --- a/mods/ts/weapons.yaml +++ b/mods/ts/weapons.yaml @@ -1,27 +1,29 @@ UnitExplode: - Warhead: - Damage: 500 + Warhead@1Dam: SpreadDamage Spread: 426 + Damage: 500 + InfDeath: 2 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% + Warhead@2Eff: CreateEffect Explosion: large_twlt - InfDeath: 2 ImpactSound: expnew09.aud UnitExplodeSmall: - Warhead: - Damage: 40 + Warhead@1Dam: SpreadDamage Spread: 426 + Damage: 40 + InfDeath: 2 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% + Warhead@2Eff: CreateEffect Explosion: medium_brnl - InfDeath: 2 ImpactSound: expnew13.aud Minigun: @@ -30,17 +32,18 @@ Minigun: Report: INFGUN3.AUD Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 12 + InfDeath: 1 + ProneModifier: 70 Versus: Wood: 60% Light: 40% Heavy: 25% Concrete: 10% + Warhead@2Eff: CreateEffect Explosion: piffpiff - InfDeath: 1 - Damage: 12 - ProneModifier: 70 Grenade: ROF: 60 @@ -52,17 +55,18 @@ Grenade: Angle: 62 Inaccuracy: 554 Image: DISCUS - Warhead: + Warhead@1Dam: SpreadDamage Spread: 171 + Damage: 40 + InfDeath: 3 + ProneModifier: 70 Versus: None: 100% Wood: 85% Light: 70% Heavy: 35% Concrete: 28% - InfDeath: 3 - Damage: 40 - ProneModifier: 70 + Warhead@2Eff: CreateEffect Explosion: large_grey_explosion ImpactSound: expnew13.aud @@ -81,16 +85,17 @@ Bazooka: Image: DRAGON ROT: 8 RangeLimit: 35 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 25 + InfDeath: 2 Versus: None: 25% Wood: 65% Light: 75% Heavy: 100% Concrete: 60% - InfDeath: 2 - Damage: 25 + Warhead@2Eff: CreateEffect Explosion: small_clsn ImpactSound: expnew12.aud @@ -109,16 +114,17 @@ MultiCluster: Image: DRAGON ROT: 8 RangeLimit: 35 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 65 + InfDeath: 3 Versus: None: 25% Wood: 65% Light: 75% Heavy: 100% Concrete: 60% - InfDeath: 3 - Damage: 65 + Warhead@2Eff: CreateEffect Explosion: large_explosion ImpactSound: expnew09.aud @@ -128,16 +134,16 @@ Heal: Report: HEALER1.AUD Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 213 + Damage: -50 + InfDeath: 1 + ProneModifier: 100 Versus: Wood: 0% Light: 0% Heavy: 0% Concrete: 0% - InfDeath: 1 - Damage: -50 - ProneModifier: 100 Sniper: ROF: 60 @@ -145,17 +151,17 @@ Sniper: Report: SILENCER.AUD Projectile: Bullet Speed: 1c682 - Warhead: - Damage: 150 - ProneModifier: 100 + Warhead@1Dam: SpreadDamage Spread: 42 + Damage: 150 + InfDeath: 1 + ProneModifier: 100 Versus: None: 100% Wood: 0% Light: 0% Heavy: 0% Concrete: 0% - InfDeath: 1 M1Carbine: ROF: 20 @@ -163,17 +169,18 @@ M1Carbine: Report: INFGUN3.AUD Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 15 + InfDeath: 1 + ProneModifier: 70 Versus: Wood: 60% Light: 40% Heavy: 25% Concrete: 10% + Warhead@2Eff: CreateEffect Explosion: piffpiff - InfDeath: 1 - Damage: 15 - ProneModifier: 70 LtRail: ROF: 60 @@ -184,17 +191,17 @@ LtRail: BeamWidth: 1 BeamDuration: 10 Color: 200,0,128,255 - Warhead: - Damage: 150 - ProneModifier: 100 + Warhead@1Dam: SpreadDamage Spread: 42 + Damage: 150 + InfDeath: 2 + ProneModifier: 100 Versus: None: 100% Wood: 130% Light: 150% Heavy: 110% Concrete: 5% - InfDeath: 2 CyCannon: ROF: 50 @@ -206,17 +213,18 @@ CyCannon: High: yes Shadow: true Image: TORPEDO - Warhead: + Warhead@1Dam: SpreadDamage Spread: 256 + Damage: 120 + InfDeath: 6 + ProneModifier: 100 Versus: None: 100% Wood: 65% Light: 75% Heavy: 50% Concrete: 40% - InfDeath: 6 - Damage: 120 - ProneModifier: 100 + Warhead@2Eff: CreateEffect Explosion: large_bang ImpactSound: expnew12.aud @@ -227,17 +235,18 @@ Vulcan3: Report: CYGUN1.AUD Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 10 + InfDeath: 1 + ProneModifier: 70 Versus: Wood: 60% Light: 40% Heavy: 25% Concrete: 10% + Warhead@2Eff: CreateEffect Explosion: piffpiff - InfDeath: 1 - Damage: 10 - ProneModifier: 70 Vulcan2: ROF: 50 @@ -246,18 +255,19 @@ Vulcan2: Report: TSGUN4.AUD Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 50 + InfDeath: 1 + ProneModifier: 70 Versus: None: 100% Wood: 60% Light: 40% Heavy: 25% Concrete: 10% + Warhead@2Eff: CreateEffect Explosion: piffpiff - InfDeath: 1 - Damage: 50 - ProneModifier: 70 Vulcan: ROF: 60 @@ -265,17 +275,18 @@ Vulcan: Report: CHAINGN1.AUD Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 20 + InfDeath: 1 + ProneModifier: 70 Versus: Wood: 60% Light: 40% Heavy: 25% Concrete: 10% + Warhead@2Eff: CreateEffect Explosion: piffpiff - InfDeath: 1 - Damage: 20 - ProneModifier: 70 FiendShard: ROF: 30 @@ -289,15 +300,15 @@ FiendShard: Inaccuracy: 512 Shadow: true Angle: 88 - Warhead: + Warhead@1Dam: SpreadDamage + Damage: 35 + InfDeath: 1 + ProneModifier: 100 Versus: Wood: 60% Light: 40% Heavy: 25% Concrete: 10% - InfDeath: 1 - Damage: 35 - ProneModifier: 100 JumpCannon: ROF: 40 @@ -306,17 +317,18 @@ JumpCannon: Report: JUMPJET1.AUD Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 15 + InfDeath: 1 + ProneModifier: 70 Versus: Wood: 60% Light: 40% Heavy: 25% Concrete: 10% + Warhead@2Eff: CreateEffect Explosion: piffpiff - InfDeath: 1 - Damage: 15 - ProneModifier: 70 HoverMissile: ROF: 68 @@ -334,16 +346,17 @@ HoverMissile: Image: DRAGON ROT: 8 RangeLimit: 35 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 30 + InfDeath: 2 Versus: None: 25% Wood: 65% Light: 75% Heavy: 100% Concrete: 60% - InfDeath: 2 - Damage: 30 + Warhead@2Eff: CreateEffect Explosion: small_clsn ImpactSound: expnew12.aud @@ -359,16 +372,17 @@ HoverMissile: Image: 120mm Shadow: true Angle: 62 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 50 + InfDeath: 2 Versus: None: 25% Wood: 65% Light: 75% Heavy: 100% Concrete: 60% - InfDeath: 2 - Damage: 50 + Warhead@2Eff: CreateEffect Explosion: medium_clsn ImpactSound: expnew14.aud @@ -388,17 +402,18 @@ MammothTusk: ROT: 10 Speed: 170 RangeLimit: 35 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 171 + Damage: 40 + InfDeath: 3 + ProneModifier: 70 Versus: None: 100% Wood: 85% Light: 70% Heavy: 35% Concrete: 28% - InfDeath: 3 - Damage: 40 - ProneModifier: 70 + Warhead@2Eff: CreateEffect Explosion: medium_bang ImpactSound: expnew12.aud @@ -408,17 +423,17 @@ Repair: Report: REPAIR11.AUD Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 213 + Damage: -50 + InfDeath: 1 + ProneModifier: 100 Versus: None: 0% Wood: 0% Light: 100% Heavy: 100% Concrete: 0% - InfDeath: 1 - Damage: -50 - ProneModifier: 100 SlimeAttack: ROF: 80 @@ -427,30 +442,30 @@ SlimeAttack: Report: VICER1.AUD Projectile: Bullet Speed: 426 - Warhead: + Warhead@1Dam: SpreadDamage + Damage: 100 + InfDeath: 2 + ProneModifier: 100 Versus: Wood: 25% Light: 30% Heavy: 10% Concrete: 10% - InfDeath: 2 - Damage: 100 - ProneModifier: 100 SuicideBomb: ROF: 1 Range: 0c512 Report: HUNTER2.AUD - Warhead: - Damage: 11000 + Warhead@1Dam: SpreadDamage Spread: 256 - DestroyResources: true + Damage: 11000 + InfDeath: 5 Versus: None: 90% Light: 60% Heavy: 25% Concrete: 50% - InfDeath: 5 + Warhead@2Res: DestroyResource 120mm: ROF: 80 @@ -458,16 +473,17 @@ SuicideBomb: Report: 120MMF.AUD Projectile: Bullet Speed: 1c512 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 70 + InfDeath: 2 Versus: None: 25% Wood: 65% Light: 75% Heavy: 100% Concrete: 60% - InfDeath: 2 - Damage: 70 + Warhead@2Eff: CreateEffect Explosion: large_clsn ImpactSound: expnew14.aud @@ -480,17 +496,17 @@ MechRailgun: Projectile: LaserZap Color: 200,0,255,255 BeamWidth: 3 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 42 + Damage: 200 + InfDeath: 5 + ProneModifier: 100 Versus: None: 200% Wood: 175% Light: 160% Heavy: 100% Concrete: 25% - InfDeath: 5 - Damage: 200 - ProneModifier: 100 AssaultCannon: ROF: 50 @@ -498,17 +514,18 @@ AssaultCannon: Report: TSGUN4.AUD Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 40 + InfDeath: 1 + ProneModifier: 70 Versus: Wood: 60% Light: 40% Heavy: 25% Concrete: 10% + Warhead@2Eff: CreateEffect Explosion: piffpiff - InfDeath: 1 - Damage: 40 - ProneModifier: 70 BikeMissile: ROF: 60 @@ -527,38 +544,40 @@ BikeMissile: ROT: 8 Speed: 213 RangeLimit: 35 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 256 + Damage: 40 + InfDeath: 2 Versus: None: 25% Wood: 65% Light: 75% Heavy: 100% Concrete: 60% - InfDeath: 2 - Damage: 40 + Warhead@2Eff: CreateEffect Explosion: small_clsn ImpactSound: expnew12.aud RaiderCannon: ROF: 55 Range: 4c0 - Burst: 2 #purely cosmetical, for alternate muzzle position + Burst: 2 BurstDelay: 55 Report: CHAINGN1.AUD Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 40 + InfDeath: 1 + ProneModifier: 70 Versus: Wood: 60% Light: 40% Heavy: 25% Concrete: 10% + Warhead@2Eff: CreateEffect Explosion: piffpiff - InfDeath: 1 - Damage: 40 - ProneModifier: 70 FireballLauncher: ROF: 50 @@ -570,17 +589,17 @@ FireballLauncher: Inacuracy: 384 Burst: 5 BurstDelay: 5 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 341 + Damage: 25 + InfDeath: 5 + ProneModifier: 100 Versus: None: 600% Wood: 148% Light: 59% Heavy: 6% Concrete: 2% - InfDeath: 5 - Damage: 25 - ProneModifier: 100 SonicZap: ROF: 120 @@ -591,13 +610,13 @@ SonicZap: Color: 200,0,255,255 BeamWidth: 12 BeamDuration: 50 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 42 + Damage: 100 + InfDeath: 5 Versus: Heavy: 80% Concrete: 60% - InfDeath: 5 - Damage: 100 Dragon: ROF: 50 @@ -615,16 +634,17 @@ Dragon: Image: DRAGON ROT: 8 RangeLimit: 35 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 30 + InfDeath: 2 Versus: None: 25% Wood: 65% Light: 75% Heavy: 100% Concrete: 60% - InfDeath: 2 - Damage: 30 + Warhead@2Eff: CreateEffect Explosion: small_clsn ImpactSound: expnew12.aud @@ -638,16 +658,17 @@ Dragon: Image: 120mm Shadow: true Angle: 62 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 36 + InfDeath: 2 Versus: None: 25% Wood: 65% Light: 75% Heavy: 100% Concrete: 60% - InfDeath: 2 - Damage: 36 + Warhead@2Eff: CreateEffect Explosion: medium_clsn ImpactSound: expnew14.aud @@ -663,17 +684,18 @@ Dragon: Shadow: true High: yes MinRange: 5c0 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 298 + Damage: 150 + InfDeath: 3 + ProneModifier: 100 Versus: None: 100% Wood: 85% Light: 68% Heavy: 35% Concrete: 35% - InfDeath: 3 - Damage: 150 - ProneModifier: 100 + Warhead@2Eff: CreateEffect Explosion: large_explosion ImpactSound: expnew09.aud @@ -693,16 +715,17 @@ Hellfire: Image: DRAGON ROT: 8 RangeLimit: 35 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 85 + Damage: 30 + InfDeath: 2 Versus: None: 30% Wood: 65% Light: 150% Heavy: 100% Concrete: 30% - InfDeath: 2 - Damage: 30 + Warhead@2Eff: CreateEffect Explosion: small_bang ImpactSound: expnew12.aud @@ -714,17 +737,18 @@ Bomb: Speed: 170 Image: canister Shadow: true - Warhead: + Warhead@1Dam: SpreadDamage Spread: 298 + Damage: 160 + InfDeath: 3 + ProneModifier: 100 Versus: None: 200% Wood: 90% Light: 75% Heavy: 32% Concrete: 100% - InfDeath: 3 - Damage: 160 - ProneModifier: 100 + Warhead@2Eff: CreateEffect Explosion: large_explosion ImpactSound: expnew09.aud @@ -743,16 +767,17 @@ Proton: Image: TORPEDO ROT: 1 RangeLimit: 35 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 20 + InfDeath: 3 Versus: None: 25% Wood: 65% Light: 75% Heavy: 100% Concrete: 60% - InfDeath: 3 - Damage: 20 + Warhead@2Eff: CreateEffect Explosion: small_bang ImpactSound: expnew12.aud @@ -763,17 +788,18 @@ HarpyClaw: Projectile: Bullet Speed: 1c682 ValidTargets: Ground, Air - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 60 + InfDeath: 1 + ProneModifier: 70 Versus: Wood: 60% Light: 40% Heavy: 25% Concrete: 10% + Warhead@2Eff: CreateEffect Explosion: piffpiff - InfDeath: 1 - Damage: 60 - ProneModifier: 70 Pistola: ROF: 20 @@ -781,49 +807,57 @@ Pistola: Report: GUN18.AUD Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 2 + InfDeath: 1 + ProneModifier: 70 Versus: Wood: 60% Light: 40% Heavy: 25% Concrete: 10% + Warhead@2Eff: CreateEffect Explosion: piff - InfDeath: 1 - Damage: 2 - ProneModifier: 70 Tiberium: ROF: 16 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 42 - InfDeath: 6 Damage: 2 + InfDeath: 6 PreventProne: yes TiberiumHeal: ROF: 16 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 42 - InfDeath: 6 Damage: -2 + InfDeath: 6 PreventProne: yes IonCannon: ValidTargets: Ground, Air - Warhead@impact: - Damage: 1000 + Warhead@1Dam_impact: SpreadDamage Spread: 1c0 + Damage: 1000 InfDeath: 5 - Explosion: ring1 ProneModifier: 100 - Warhead@area: - DamageModel: PerCell + Warhead@2Eff_impact: CreateEffect + Explosion: ring1 + Warhead@3Dam_area: PerCellDamage + Size: 2,1 Damage: 250 + InfDeath: 5 + Delay: 3 + Warhead@4Dam_area: SpreadDamage + Damage: 250 + InfDeath: 5 + Delay: 3 + Warhead@5Smu_area: LeaveSmudge SmudgeType: Scorch Size: 2,1 Delay: 3 - InfDeath: 5 VulcanTower: ROF: 26 @@ -831,16 +865,17 @@ VulcanTower: Report: CHAINGN1.AUD Projectile: Bullet Speed: 1c682 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 18 + InfDeath: 1 Versus: Wood: 60% Light: 40% Heavy: 25% Concrete: 10% + Warhead@2Eff: CreateEffect Explosion: piffpiff - InfDeath: 1 - Damage: 18 RPGTower: ROF: 80 @@ -853,17 +888,18 @@ RPGTower: Shadow: true Angle: 62 Image: canister - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 + Damage: 110 + InfDeath: 2 + ProneModifier: 70 Versus: None: 30% Wood: 75% Light: 90% Heavy: 100% Concrete: 70% - InfDeath: 2 - Damage: 110 - ProneModifier: 70 + Warhead@2Eff: CreateEffect Explosion: large_clsn ImpactSound: expnew14.aud @@ -882,10 +918,11 @@ SAMTower: Image: DRAGON ROT: 5 RangeLimit: 60 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 128 - InfDeath: 2 Damage: 33 + InfDeath: 2 + Warhead@2Eff: CreateEffect Explosion: small_clsn ImpactSound: expnew12.aud @@ -896,12 +933,13 @@ ObeliskLaser: Report: OBELRAY1.AUD Projectile: LaserZap BeamWidth: 4 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 42 - InfDeath: 5 - SmudgeType: Scorch Damage: 250 + InfDeath: 5 ProneModifier: 60 + Warhead@2Smu: LeaveSmudge + SmudgeType: Scorch TurretLaser: ROF: 40 @@ -910,24 +948,28 @@ TurretLaser: Projectile: LaserZap BeamWidth: 2 BeamDuration: 5 - Warhead: + Warhead@1Dam: SpreadDamage Spread: 42 - InfDeath: 5 - SmudgeType: Scorch Damage: 30 + InfDeath: 5 ProneModifier: 60 + Warhead@2Smu: LeaveSmudge + SmudgeType: Scorch TiberiumExplosion: - Warhead: - Damage: 10 + Warhead@1Dam: SpreadDamage Spread: 9 - Size: 1,1 + Damage: 10 + InfDeath: 3 Versus: None: 90% Wood: 75% Light: 60% Heavy: 25% - InfDeath: 3 + Warhead@2Res: CreateResource + AddsResourceType: Tiberium + Size: 1,1 + Warhead@3Eff: CreateEffect Explosion: large_explosion ImpactSound: expnew09.aud - AddsResourceType: Tiberium +