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 712f79acea..0f4193a349 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 b33e64e0e0..0ed899bf26 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 1148e35b16..62c387a024 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -189,7 +189,6 @@ - @@ -289,6 +288,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 afed5bc493..187eeea412 100644 --- a/OpenRA.Utility/UpgradeRules.cs +++ b/OpenRA.Utility/UpgradeRules.cs @@ -422,6 +422,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 925b4a96a5..b2a1b4383c 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 4a15874dd7..00669d8f17 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 2b09f60229..b1cde04edd 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 +