Custom Warheads refactor
Changes included: Warhead code split out of weapon code and refactored. Warhead functionality now split into several classes, each handling one effect/impact. Additional custom warheads can now be defined and called via yaml. Custom warheads inherit the abstract class Warhead, which provides target check functions. Custom warheads have to define their own impact functions, and can also define their own replacement for check functions.
This commit is contained in:
@@ -509,10 +509,16 @@ namespace OpenRA
|
||||
|
||||
internal Func<MiniYaml, object> 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<MiniYaml, object>)Delegate.CreateDelegate(typeof(Func<MiniYaml, object>), 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<MiniYaml, object>)Delegate.CreateDelegate(typeof(Func<MiniYaml, object>), method);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
102
OpenRA.Game/GameRules/Warhead.cs
Normal file
102
OpenRA.Game/GameRules/Warhead.cs
Normal file
@@ -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<ITargetable>();
|
||||
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<ITargetableInfo>();
|
||||
if (targetable == null)
|
||||
return false;
|
||||
if (!targetList.Intersect(targetable.GetTargetTypes()).Any())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<HealthInfo>();
|
||||
if (healthInfo == null)
|
||||
return 0;
|
||||
|
||||
var rawDamage = (float)Damage;
|
||||
|
||||
return (int)(rawDamage * modifier * EffectivenessAgainst(target.Info));
|
||||
}
|
||||
}
|
||||
}
|
||||
59
OpenRA.Game/GameRules/Warheads/DamageWarhead.cs
Normal file
59
OpenRA.Game/GameRules/Warheads/DamageWarhead.cs
Normal file
@@ -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<string, float> Versus;
|
||||
|
||||
public static object LoadVersus(MiniYaml yaml)
|
||||
{
|
||||
var nd = yaml.ToDictionary();
|
||||
return nd.ContainsKey("Versus")
|
||||
? nd["Versus"].ToDictionary(my => FieldLoader.GetValue<float>("(value)", my.Value))
|
||||
: new Dictionary<string, float>();
|
||||
}
|
||||
|
||||
public override float EffectivenessAgainst(ActorInfo ai)
|
||||
{
|
||||
var health = ai.Traits.GetOrDefault<HealthInfo>();
|
||||
if (health == null)
|
||||
return 0f;
|
||||
|
||||
var armor = ai.Traits.GetOrDefault<ArmorInfo>();
|
||||
if (armor == null || armor.Type == null)
|
||||
return 1f;
|
||||
|
||||
float versus;
|
||||
return Versus.TryGetValue(armor.Type, out versus) ? versus : 1f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<HealthInfo>();
|
||||
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<HealthInfo>();
|
||||
if (healthInfo == null)
|
||||
return 0;
|
||||
|
||||
var rawDamage = (float)Damage;
|
||||
|
||||
return rawDamage * modifier * EffectivenessAgainst(target.Info);
|
||||
}
|
||||
}
|
||||
}
|
||||
65
OpenRA.Game/GameRules/Warheads/PerCellDamageWarhead.cs
Normal file
65
OpenRA.Game/GameRules/Warheads/PerCellDamageWarhead.cs
Normal file
@@ -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<HealthInfo>();
|
||||
if (healthInfo == null)
|
||||
return 0;
|
||||
|
||||
var rawDamage = (float)Damage;
|
||||
|
||||
return (int)(rawDamage * modifier * EffectivenessAgainst(target.Info));
|
||||
}
|
||||
}
|
||||
}
|
||||
83
OpenRA.Game/GameRules/Warheads/SpreadDamageWarhead.cs
Normal file
83
OpenRA.Game/GameRules/Warheads/SpreadDamageWarhead.cs
Normal file
@@ -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<HealthInfo>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<string, float> 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<HealthInfo>();
|
||||
if (health == null)
|
||||
return 0f;
|
||||
|
||||
var armor = ai.Traits.GetOrDefault<ArmorInfo>();
|
||||
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<float>("(value)", my.Value))
|
||||
: new Dictionary<string, float>();
|
||||
}
|
||||
}
|
||||
|
||||
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<WarheadInfo> Warheads;
|
||||
[FieldLoader.LoadUsing("LoadProjectile")]
|
||||
public readonly IProjectileInfo Projectile;
|
||||
[FieldLoader.LoadUsing("LoadWarheads")]
|
||||
public readonly List<Warhead> Warheads = new List<Warhead>();
|
||||
|
||||
public WeaponInfo(string name, MiniYaml content)
|
||||
{
|
||||
@@ -139,47 +81,24 @@ namespace OpenRA.GameRules
|
||||
|
||||
static object LoadWarheads(MiniYaml yaml)
|
||||
{
|
||||
var ret = new List<WarheadInfo>();
|
||||
foreach (var w in yaml.Nodes)
|
||||
if (w.Key.Split('@')[0] == "Warhead")
|
||||
ret.Add(new WarheadInfo(w.Value));
|
||||
var retList = new List<Warhead>();
|
||||
foreach (var node in yaml.Nodes.Where(n => n.Key.StartsWith("Warhead")))
|
||||
{
|
||||
var ret = Game.CreateObject<Warhead>(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<ITargetable>();
|
||||
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<ITargetableInfo>();
|
||||
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<ITargetable>();
|
||||
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<ITargetableInfo>();
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,6 +75,12 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Actor.cs" />
|
||||
<Compile Include="GameRules\Warhead.cs" />
|
||||
<Compile Include="GameRules\Warheads\AbsoluteSpreadDamageWarhead.cs" />
|
||||
<Compile Include="GameRules\Warheads\DamageWarhead.cs" />
|
||||
<Compile Include="GameRules\Warheads\HealthPercentageDamageWarhead.cs" />
|
||||
<Compile Include="GameRules\Warheads\PerCellDamageWarhead.cs" />
|
||||
<Compile Include="GameRules\Warheads\SpreadDamageWarhead.cs" />
|
||||
<Compile Include="Graphics\QuadRenderer.cs" />
|
||||
<Compile Include="Download.cs" />
|
||||
<Compile Include="Effects\DelayedAction.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<Health>();
|
||||
|
||||
@@ -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<IRenderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<IRenderable> 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); }
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Armament>();
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<ScreenShaker>().AddEffect(15, self.CenterPosition, 6);
|
||||
self.Kill(saboteur);
|
||||
});
|
||||
|
||||
@@ -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<SmudgeLayer>().ToDictionary(x => x.Info.Type);
|
||||
var resLayer = warhead.DestroyResources || !string.IsNullOrEmpty(warhead.AddsResourceType) ? world.WorldActor.Trait<ResourceLayer>() : 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<CPos> 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<ResourceType>()
|
||||
.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<ResourceLayer>().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<HealthInfo>();
|
||||
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<HealthInfo>();
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<IRenderable> Render(WorldRenderer wr)
|
||||
|
||||
@@ -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<ScreenShaker>().AddEffect(20, pos, 5);
|
||||
|
||||
foreach (var a in world.ActorsWithTrait<NukePaletteEffect>())
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -188,7 +188,6 @@
|
||||
<Compile Include="ChronoshiftPaletteEffect.cs" />
|
||||
<Compile Include="Chronoshiftable.cs" />
|
||||
<Compile Include="Cloak.cs" />
|
||||
<Compile Include="Combat.cs" />
|
||||
<Compile Include="ConquestVictoryConditions.cs" />
|
||||
<Compile Include="ContainsCrate.cs" />
|
||||
<Compile Include="Crate.cs" />
|
||||
@@ -288,6 +287,10 @@
|
||||
<Compile Include="Player\ProductionQueue.cs" />
|
||||
<Compile Include="Player\ProvidesTechPrerequisite.cs" />
|
||||
<Compile Include="PortableChrono.cs" />
|
||||
<Compile Include="Warheads\DestroyResourceWarhead.cs" />
|
||||
<Compile Include="Warheads\CreateEffectWarhead.cs" />
|
||||
<Compile Include="Warheads\CreateResourceWarhead.cs" />
|
||||
<Compile Include="Warheads\LeaveSmudgeWarhead.cs" />
|
||||
<Compile Include="World\RadarPings.cs" />
|
||||
<Compile Include="Player\TechTree.cs" />
|
||||
<Compile Include="PrimaryBuilding.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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
86
OpenRA.Mods.RA/Warheads/CreateEffectWarhead.cs
Normal file
86
OpenRA.Mods.RA/Warheads/CreateEffectWarhead.cs
Normal file
@@ -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; }
|
||||
}
|
||||
}
|
||||
66
OpenRA.Mods.RA/Warheads/CreateResourceWarhead.cs
Normal file
66
OpenRA.Mods.RA/Warheads/CreateResourceWarhead.cs
Normal file
@@ -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<ResourceLayer>();
|
||||
|
||||
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<ResourceType>()
|
||||
.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; }
|
||||
}
|
||||
}
|
||||
47
OpenRA.Mods.RA/Warheads/DestroyResourceWarhead.cs
Normal file
47
OpenRA.Mods.RA/Warheads/DestroyResourceWarhead.cs
Normal file
@@ -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<ResourceLayer>();
|
||||
|
||||
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; }
|
||||
}
|
||||
}
|
||||
58
OpenRA.Mods.RA/Warheads/LeaveSmudgeWarhead.cs
Normal file
58
OpenRA.Mods.RA/Warheads/LeaveSmudgeWarhead.cs
Normal file
@@ -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<SmudgeLayer>().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; }
|
||||
}
|
||||
}
|
||||
@@ -396,6 +396,180 @@ namespace OpenRA.Utility
|
||||
node.Key = "DestroyResources";
|
||||
}
|
||||
|
||||
if (engineVersion < 20140720)
|
||||
{
|
||||
// Split out the warheads to individual warhead types.
|
||||
if (depth == 0)
|
||||
{
|
||||
var warheadCounter = 0;
|
||||
foreach(var curNode in node.Value.Nodes.ToArray())
|
||||
{
|
||||
if (curNode.Key.Contains("Warhead") && curNode.Value.Value == null)
|
||||
{
|
||||
var newNodes = new List<MiniYamlNode>();
|
||||
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<MiniYamlNode>();
|
||||
|
||||
var keywords = new List<String>{ "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<MiniYamlNode>();
|
||||
|
||||
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<String>{ "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<MiniYamlNode>();
|
||||
|
||||
var keywords = new List<String>{ "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<MiniYamlNode>();
|
||||
|
||||
var keywords = new List<String>{ "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<MiniYamlNode>();
|
||||
|
||||
var keywords = new List<String>{ "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<MiniYamlNode>();
|
||||
|
||||
var keywords = new List<String>{ "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<MiniYamlNode>();
|
||||
|
||||
var keywords = new List<String>{ "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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -535,10 +535,10 @@ VoxelSequences:
|
||||
|
||||
Weapons:
|
||||
BoatMissile:
|
||||
Warhead:
|
||||
Warhead: SpreadDamage
|
||||
Versus:
|
||||
Heavy: 50%
|
||||
Damage: 50
|
||||
Damage: 50
|
||||
|
||||
Voices:
|
||||
|
||||
|
||||
@@ -572,7 +572,7 @@ VoxelSequences:
|
||||
|
||||
Weapons:
|
||||
Tiberium:
|
||||
Warhead:
|
||||
Warhead: SpreadDamage
|
||||
Damage: 6
|
||||
|
||||
Voices:
|
||||
|
||||
@@ -653,7 +653,7 @@ VoxelSequences:
|
||||
|
||||
Weapons:
|
||||
Tiberium:
|
||||
Warhead:
|
||||
Warhead: SpreadDamage
|
||||
Damage: 4
|
||||
|
||||
Voices:
|
||||
|
||||
@@ -913,7 +913,7 @@ VoxelSequences:
|
||||
|
||||
Weapons:
|
||||
Rockets:
|
||||
Warhead:
|
||||
Warhead: SpreadDamage
|
||||
Versus:
|
||||
None: 20%
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
|
||||
@@ -615,7 +615,7 @@ Weapons:
|
||||
Range: 5c0
|
||||
ROF: 20
|
||||
Burst: 1
|
||||
Warhead:
|
||||
Warhead: SpreadDamage
|
||||
Damage: 20
|
||||
|
||||
Voices:
|
||||
|
||||
@@ -951,7 +951,7 @@ Weapons:
|
||||
Range: 5c0
|
||||
ROF: 20
|
||||
Burst: 1
|
||||
Warhead:
|
||||
Warhead: SpreadDamage
|
||||
Damage: 20
|
||||
|
||||
Voices:
|
||||
|
||||
@@ -364,7 +364,7 @@ Weapons:
|
||||
PortaTesla:
|
||||
ROF: 20
|
||||
Range: 10c0
|
||||
Warhead:
|
||||
Warhead: SpreadDamage
|
||||
Spread: 42
|
||||
InfDeath: 5
|
||||
Damage: 80
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -259,7 +259,7 @@ Weapons:
|
||||
PortaTesla:
|
||||
ROF: 20
|
||||
Range: 10c0
|
||||
Warhead:
|
||||
Warhead: SpreadDamage
|
||||
Spread: 42
|
||||
InfDeath: 5
|
||||
Damage: 80
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -2333,7 +2333,7 @@ Weapons:
|
||||
Nike:
|
||||
Range: 9c0
|
||||
Maverick:
|
||||
Warhead:
|
||||
Warhead: SpreadDamage
|
||||
Damage: 175
|
||||
|
||||
Voices:
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user