Merge pull request #6030 from UberWaffe/CustomWarheads
Custom Warheads refactor
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));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public bool IsValidAgainst(Actor a)
|
||||
var retList = new List<Warhead>();
|
||||
foreach (var node in yaml.Nodes.Where(n => n.Key.StartsWith("Warhead")))
|
||||
{
|
||||
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;
|
||||
var ret = Game.CreateObject<Warhead>(node.Value.Value + "Warhead");
|
||||
FieldLoader.Load(ret, node.Value);
|
||||
retList.Add(ret);
|
||||
}
|
||||
|
||||
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;
|
||||
return retList;
|
||||
}
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -189,7 +189,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" />
|
||||
@@ -289,6 +288,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; }
|
||||
}
|
||||
}
|
||||
@@ -422,6 +422,180 @@ namespace OpenRA.Utility
|
||||
node.Key = "DestroyResources";
|
||||
}
|
||||
|
||||
if (engineVersion < 20140720)
|
||||
{
|
||||
// Split out the warheads to individual warhead types.
|
||||
if (depth == 0)
|
||||
{
|
||||
var warheadCounter = 0;
|
||||
foreach(var curNode in node.Value.Nodes.ToArray())
|
||||
{
|
||||
if (curNode.Key.Contains("Warhead") && curNode.Value.Value == null)
|
||||
{
|
||||
var newNodes = new List<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,7 +535,7 @@ VoxelSequences:
|
||||
|
||||
Weapons:
|
||||
BoatMissile:
|
||||
Warhead:
|
||||
Warhead: SpreadDamage
|
||||
Versus:
|
||||
Heavy: 50%
|
||||
Damage: 50
|
||||
|
||||
@@ -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