Remove passing the warheads from DamageWarhead to AttackInfo.

Added a Damage class to pass damage value and damage(types) instead.
This removes a great amount of overhead and longterm opens possibilities to have damagetypes without warheads.
This commit is contained in:
Zimmermann Gyula
2016-06-24 13:18:15 +02:00
parent 6342b40bfd
commit cf8fff2b99
30 changed files with 69 additions and 64 deletions

View File

@@ -317,12 +317,12 @@ namespace OpenRA
return (health == null) ? DamageState.Undamaged : health.DamageState;
}
public void InflictDamage(Actor attacker, int damage, IWarhead warhead)
public void InflictDamage(Actor attacker, Damage damage)
{
if (Disposed || health == null)
return;
health.InflictDamage(this, attacker, damage, warhead, false);
health.InflictDamage(this, attacker, damage, false);
}
public void Kill(Actor attacker)

View File

@@ -41,7 +41,7 @@ namespace OpenRA.Traits
int DisplayHP { get; }
bool IsDead { get; }
void InflictDamage(Actor self, Actor attacker, int damage, IWarhead warhead, bool ignoreModifiers);
void InflictDamage(Actor self, Actor attacker, Damage damage, bool ignoreModifiers);
void Kill(Actor self, Actor attacker);
}
@@ -82,13 +82,30 @@ namespace OpenRA.Traits
public class AttackInfo
{
public int Damage;
public Damage Damage;
public Actor Attacker;
public IWarhead Warhead;
public DamageState DamageState;
public DamageState PreviousDamageState;
}
public class Damage
{
public readonly int Value;
public readonly HashSet<string> DamageTypes;
public Damage(int damage, HashSet<string> damageTypes)
{
Value = damage;
DamageTypes = damageTypes;
}
public Damage(int damage)
{
Value = damage;
DamageTypes = new HashSet<string>();
}
}
public interface ITick { void Tick(Actor self); }
public interface ITickRender { void TickRender(WorldRenderer wr, Actor self); }
public interface IRender { IEnumerable<IRenderable> Render(Actor self, WorldRenderer wr); }
@@ -249,7 +266,7 @@ namespace OpenRA.Traits
}
public interface IRenderModifier { IEnumerable<IRenderable> ModifyRender(Actor self, WorldRenderer wr, IEnumerable<IRenderable> r); }
public interface IDamageModifier { int GetDamageModifier(Actor attacker, IWarhead warhead); }
public interface IDamageModifier { int GetDamageModifier(Actor attacker, Damage damage); }
public interface ISpeedModifier { int GetSpeedModifier(); }
public interface IFirepowerModifier { int GetFirepowerModifier(); }
public interface IReloadModifier { int GetReloadModifier(); }

View File

@@ -112,7 +112,7 @@ namespace OpenRA.Mods.Cnc.Traits
}
}
public int GetDamageModifier(Actor attacker, IWarhead warhead)
public int GetDamageModifier(Actor attacker, Damage damage)
{
return state == PopupState.Closed ? info.ClosedDamageMultiplier : 100;
}

View File

@@ -69,7 +69,7 @@ namespace OpenRA.Mods.Common.Activities
else
{
var damage = health.MaxHP * capturesInfo.SabotageHPRemoval / 100;
actor.InflictDamage(self, damage, null);
actor.InflictDamage(self, new Damage(damage));
}
self.Dispose();

View File

@@ -71,7 +71,7 @@ namespace OpenRA.Mods.Common.Activities
return this;
}
self.InflictDamage(self, -hpToRepair, null);
self.InflictDamage(self, new Damage(-hpToRepair));
foreach (var depot in host.TraitsImplementing<INotifyRepair>())
depot.Repairing(host, self);

View File

@@ -36,7 +36,7 @@ namespace OpenRA.Mods.Common.Activities
if (health.DamageState == DamageState.Undamaged)
return;
target.InflictDamage(self, -health.MaxHP, null);
target.InflictDamage(self, new Damage(-health.MaxHP));
}
}
}

View File

@@ -29,7 +29,7 @@ namespace OpenRA.Mods.Common.Scripting
public int Health
{
get { return health.HP; }
set { health.InflictDamage(Self, Self, health.HP - value, null, true); }
set { health.InflictDamage(Self, Self, new Damage(health.HP - value), true); }
}
[Desc("Maximum health of the actor.")]
@@ -38,7 +38,7 @@ namespace OpenRA.Mods.Common.Scripting
[Desc("Kill the actor.")]
public void Kill()
{
health.InflictDamage(Self, Self, health.MaxHP, null, true);
health.InflictDamage(Self, Self, new Damage(health.MaxHP), true);
}
}
}

View File

@@ -113,7 +113,7 @@ namespace OpenRA.Mods.Common.Traits
return;
// don't retaliate against healers
if (e.Damage < 0)
if (e.Damage.Value < 0)
return;
Aggressor = attacker;

View File

@@ -292,7 +292,7 @@ namespace OpenRA.Mods.Common.Traits
KillUnitsOnBridge();
}
else
health.InflictDamage(self, repairer, -health.MaxHP, null, true);
health.InflictDamage(self, repairer, new Damage(-health.MaxHP), true);
if (direction < 0 ? neighbours[0] == null && neighbours[1] == null : Hut != null || neighbours[direction] == null)
onComplete(); // Done if single or reached other hut
});

View File

@@ -129,7 +129,7 @@ namespace OpenRA.Mods.Common.Traits
// activePlayers won't cause IndexOutOfRange because we capped the max amount of players
// to the length of the array
self.InflictDamage(self, -(hpToRepair * Info.RepairBonuses[activePlayers - 1] / 100), null);
self.InflictDamage(self, new Damage(-(hpToRepair * Info.RepairBonuses[activePlayers - 1] / 100)));
if (health.DamageState == DamageState.Undamaged)
{

View File

@@ -44,7 +44,7 @@ namespace OpenRA.Mods.Common.Traits
{
if (--ticks <= 0)
{
self.InflictDamage(self, info.Damage, null);
self.InflictDamage(self, new Damage(info.Damage));
ticks = info.Interval;
}
}

View File

@@ -116,14 +116,14 @@ namespace OpenRA.Mods.Common.Traits
public void Damaged(Actor self, AttackInfo e)
{
if (devMode == null || !devMode.ShowCombatGeometry || e.Damage == 0)
if (devMode == null || !devMode.ShowCombatGeometry || e.Damage.Value == 0)
return;
if (healthInfo == null)
return;
var maxHP = healthInfo.HP > 0 ? healthInfo.HP : 1;
var damageText = "{0} ({1}%)".F(-e.Damage, e.Damage * 100 / maxHP);
var damageText = "{0} ({1}%)".F(-e.Damage.Value, e.Damage.Value * 100 / maxHP);
self.World.AddFrameEndTask(w => w.Add(new FloatingText(self.CenterPosition, e.Attacker.Owner.Color.RGB, damageText, 30)));
}

View File

@@ -10,6 +10,7 @@
#endregion
using System.Linq;
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
@@ -28,7 +29,7 @@ namespace OpenRA.Mods.Common.Traits
{
foreach (var healable in collector.World.ActorsWithTrait<Health>().Where(tp => tp.Actor.Owner == collector.Owner))
if (!healable.Trait.IsDead)
healable.Trait.InflictDamage(healable.Actor, healable.Actor, -(healable.Trait.MaxHP - healable.Trait.HP), null, true);
healable.Trait.InflictDamage(healable.Actor, healable.Actor, new Damage(-(healable.Trait.MaxHP - healable.Trait.HP)), true);
base.Activate(collector);
}

View File

@@ -67,7 +67,7 @@ namespace OpenRA.Mods.Common.Traits
// Actors start with maximum damage applied
var delta = health.HP - damageThreshold;
if (delta > 0)
health.InflictDamage(self, self.World.WorldActor, delta, null, false);
health.InflictDamage(self, self.World.WorldActor, new Damage(delta), false);
}
public void Tick(Actor self)

View File

@@ -69,8 +69,7 @@ namespace OpenRA.Mods.Common.Traits
if (self.World.SharedRandom.Next(100) > info.Chance)
return;
var warhead = e.Warhead as DamageWarhead;
if (info.DeathTypes.Count > 0 && warhead != null && !warhead.DamageTypes.Overlaps(info.DeathTypes))
if (info.DeathTypes.Count > 0 && !e.Damage.DamageTypes.Overlaps(info.DeathTypes))
return;
var weapon = ChooseWeaponForExplosion(self);

View File

@@ -66,8 +66,7 @@ namespace OpenRA.Mods.Common.Traits
if (!info.ValidStances.HasStance(e.Attacker.Owner.Stances[self.Owner]))
return;
var warhead = e.Warhead as DamageWarhead;
if (info.DeathTypes.Count > 0 && warhead != null && !warhead.DamageTypes.Overlaps(info.DeathTypes))
if (info.DeathTypes.Count > 0 && !e.Damage.DamageTypes.Overlaps(info.DeathTypes))
return;
var cost = self.GetSellValue();

View File

@@ -112,10 +112,9 @@ namespace OpenRA.Mods.Common.Traits
var ai = new AttackInfo
{
Attacker = repairer,
Damage = -MaxHP,
Damage = new Damage(-MaxHP),
DamageState = DamageState,
PreviousDamageState = DamageState.Dead,
Warhead = null,
};
foreach (var nd in self.TraitsImplementing<INotifyDamage>()
@@ -131,7 +130,7 @@ namespace OpenRA.Mods.Common.Traits
nd.AppliedDamage(repairer, self, ai);
}
public void InflictDamage(Actor self, Actor attacker, int damage, IWarhead warhead, bool ignoreModifiers)
public void InflictDamage(Actor self, Actor attacker, Damage damage, bool ignoreModifiers)
{
// Overkill! Don't count extra hits as more kills!
if (IsDead)
@@ -140,16 +139,16 @@ namespace OpenRA.Mods.Common.Traits
var oldState = DamageState;
// Apply any damage modifiers
if (!ignoreModifiers && damage > 0)
if (!ignoreModifiers && damage.Value > 0)
{
var modifiers = self.TraitsImplementing<IDamageModifier>()
.Concat(self.Owner.PlayerActor.TraitsImplementing<IDamageModifier>())
.Select(t => t.GetDamageModifier(attacker, warhead));
.Select(t => t.GetDamageModifier(attacker, damage));
damage = Util.ApplyPercentageModifiers(damage, modifiers);
damage = new Damage(Util.ApplyPercentageModifiers(damage.Value, modifiers), damage.DamageTypes);
}
hp = (hp - damage).Clamp(0, MaxHP);
hp = (hp - damage.Value).Clamp(0, MaxHP);
var ai = new AttackInfo
{
@@ -157,7 +156,6 @@ namespace OpenRA.Mods.Common.Traits
Damage = damage,
DamageState = DamageState,
PreviousDamageState = oldState,
Warhead = warhead,
};
foreach (var nd in self.TraitsImplementing<INotifyDamage>()
@@ -191,7 +189,7 @@ namespace OpenRA.Mods.Common.Traits
public void Kill(Actor self, Actor attacker)
{
InflictDamage(self, attacker, MaxHP, null, true);
InflictDamage(self, attacker, new Damage(MaxHP), true);
}
public void Tick(Actor self)

View File

@@ -78,7 +78,7 @@ namespace OpenRA.Mods.Common.Traits
public void Damaged(Actor self, AttackInfo e)
{
if (e.Damage > 0)
if (e.Damage.Value > 0)
Panic();
}

View File

@@ -56,8 +56,7 @@ namespace OpenRA.Mods.Common.Traits
public void Damaged(Actor self, AttackInfo e)
{
var warhead = e.Warhead as DamageWarhead;
if (e.Damage <= 0 || warhead == null || !warhead.DamageTypes.Overlaps(info.DamageTriggers))
if (e.Damage.Value <= 0 || !e.Damage.DamageTypes.Overlaps(info.DamageTriggers))
return;
if (!IsProne)
@@ -79,16 +78,15 @@ namespace OpenRA.Mods.Common.Traits
get { return true; }
}
public int GetDamageModifier(Actor attacker, IWarhead warhead)
public int GetDamageModifier(Actor attacker, Damage damage)
{
if (!IsProne)
return 100;
var damageWh = warhead as DamageWarhead;
if (damageWh == null)
if (damage.DamageTypes.Count == 0)
return 100;
var modifierPercentages = info.DamageModifiers.Where(x => damageWh.DamageTypes.Contains(x.Key)).Select(x => x.Value);
var modifierPercentages = info.DamageModifiers.Where(x => damage.DamageTypes.Contains(x.Key)).Select(x => x.Value);
return Util.ApplyPercentageModifiers(100, modifierPercentages);
}

View File

@@ -41,10 +41,9 @@ namespace OpenRA.Mods.Common.Traits
this.self = self;
}
public int GetDamageModifier(Actor attacker, IWarhead warhead)
public int GetDamageModifier(Actor attacker, Damage damage)
{
var damageWh = warhead as DamageWarhead;
if (attacker.Owner.IsAlliedWith(self.Owner) && (damageWh != null && damageWh.Damage < 0) && !Info.ModifyHealing)
if (attacker.Owner.IsAlliedWith(self.Owner) && damage.Value < 0 && !Info.ModifyHealing)
return FullDamage;
var world = self.World;

View File

@@ -26,6 +26,6 @@ namespace OpenRA.Mods.Common.Traits
public DamageMultiplier(DamageMultiplierInfo info, string actorType)
: base(info, "DamageMultiplier", actorType) { }
public int GetDamageModifier(Actor attacker, IWarhead warhead) { return GetModifier(); }
public int GetDamageModifier(Actor attacker, Damage damage) { return GetModifier(); }
}
}

View File

@@ -65,7 +65,7 @@ namespace OpenRA.Mods.Common.Traits
if (!self.Info.HasTraitInfo<BuildingInfo>())
return;
if (e.Attacker.Owner.IsAlliedWith(self.Owner) && e.Damage <= 0)
if (e.Attacker.Owner.IsAlliedWith(self.Owner) && e.Damage.Value <= 0)
return;
if (self.World.WorldTick - lastAttackTime > info.NotifyInterval * 25)

View File

@@ -55,12 +55,11 @@ namespace OpenRA.Mods.Common.Traits.Render
public void Damaged(Actor self, AttackInfo e)
{
var warhead = e.Warhead as DamageWarhead;
if (info.DamageTypes.Count > 0 && (warhead != null && !warhead.DamageTypes.Overlaps(info.DamageTypes)))
if (info.DamageTypes.Count > 0 && !e.Damage.DamageTypes.Overlaps(info.DamageTypes))
return;
if (isSmoking) return;
if (e.Damage < 0) return; /* getting healed */
if (e.Damage.Value < 0) return; /* getting healed */
if (e.DamageState < info.MinimumDamageState) return;
if (e.DamageState > info.MaximumDamageState) return;

View File

@@ -84,7 +84,7 @@ namespace OpenRA.Mods.Common.Traits.Render
palette += self.Owner.InternalName;
// Killed by some non-standard means
if (e.Warhead == null || !(e.Warhead is DamageWarhead))
if (e.Damage.DamageTypes.Count == 0)
{
if (Info.FallbackSequence != null)
SpawnDeathAnimation(self, self.CenterPosition, rs.GetImage(self), Info.FallbackSequence, palette);
@@ -95,8 +95,7 @@ namespace OpenRA.Mods.Common.Traits.Render
var sequence = Info.DeathSequence;
if (Info.UseDeathTypeSuffix)
{
var warhead = e.Warhead as DamageWarhead;
var damageType = Info.DeathTypes.Keys.FirstOrDefault(warhead.DamageTypes.Contains);
var damageType = Info.DeathTypes.Keys.FirstOrDefault(e.Damage.DamageTypes.Contains);
if (damageType == null)
return;

View File

@@ -55,13 +55,13 @@ namespace OpenRA.Mods.Common.Traits
if (--ticks <= 0)
{
ticks = Info.Delay;
self.InflictDamage(self, -Info.Step, null);
self.InflictDamage(self, new Damage(-Info.Step));
}
}
public void Damaged(Actor self, AttackInfo e)
{
if (e.Damage > 0)
if (e.Damage.Value > 0)
damageTicks = Info.DamageCooldown;
}
}

View File

@@ -39,10 +39,7 @@ namespace OpenRA.Mods.Common.Traits.Sound
public void Killed(Actor self, AttackInfo e)
{
var warhead = e.Warhead as DamageWarhead;
// If the warhead is null, the actor was killed by some non-standard means
if (info.DeathTypes.Count == 0 || (warhead != null && warhead.DamageTypes.Overlaps(info.DeathTypes)))
if (info.DeathTypes.Count == 0 || e.Damage.DamageTypes.Overlaps(info.DeathTypes))
self.PlayVoiceLocal(info.Voice, info.VolumeMultiplier);
}
}

View File

@@ -72,8 +72,7 @@ namespace OpenRA.Mods.Common.Traits
if (self.World.SharedRandom.Next(100) > info.Probability)
return;
var warhead = e.Warhead as DamageWarhead;
if (info.DeathType != null && (warhead == null || !warhead.DamageTypes.Contains(info.DeathType)))
if (info.DeathType != null && !e.Damage.DamageTypes.Contains(info.DeathType))
return;
self.World.AddFrameEndTask(w =>

View File

@@ -70,7 +70,7 @@ namespace OpenRA.Mods.Common.Warheads
return;
var damage = Util.ApplyPercentageModifiers(Damage, damageModifiers.Append(DamageVersus(victim)));
victim.InflictDamage(firedBy, damage, this);
victim.InflictDamage(firedBy, new Damage(damage, DamageTypes));
}
}
}

View File

@@ -52,7 +52,7 @@ namespace OpenRA.Mods.Common.Warheads
// Damage is measured as a percentage of the target health
var damage = Util.ApplyPercentageModifiers(healthInfo.HP, damageModifiers.Append(Damage, DamageVersus(victim)));
victim.InflictDamage(firedBy, damage, this);
victim.InflictDamage(firedBy, new Damage(damage, DamageTypes));
}
}
}

View File

@@ -95,7 +95,7 @@ namespace OpenRA.Mods.RA.Traits
{
// Damage is inflicted by the chronosphere
if (!self.Disposed)
self.InflictDamage(chronosphere, int.MaxValue, null);
self.InflictDamage(chronosphere, new Damage(int.MaxValue));
});
return true;
}