diff --git a/OpenRA.Game/Actor.cs b/OpenRA.Game/Actor.cs index 6102305334..2fab1a1b8b 100644 --- a/OpenRA.Game/Actor.cs +++ b/OpenRA.Game/Actor.cs @@ -71,7 +71,7 @@ namespace OpenRA IOccupySpace occupySpace; readonly IFacing facing; - readonly Health health; + readonly IHealth health; readonly IRenderModifier[] renderModifiers; readonly IRender[] renders; readonly IDisable[] disables; @@ -103,7 +103,7 @@ namespace OpenRA VisualBounds = DetermineVisualBounds(); EffectiveOwner = TraitOrDefault(); facing = TraitOrDefault(); - health = TraitOrDefault(); + health = TraitOrDefault(); renderModifiers = TraitsImplementing().ToArray(); renders = TraitsImplementing().ToArray(); disables = TraitsImplementing().ToArray(); @@ -281,12 +281,28 @@ namespace OpenRA }); } - public void Kill(Actor attacker) + public DamageState GetDamageState() { - if (health == null) + if (Disposed) + return DamageState.Dead; + + return (health == null) ? DamageState.Undamaged : health.DamageState; + } + + public void InflictDamage(Actor attacker, int damage, IWarhead warhead) + { + if (Disposed || health == null) return; - health.InflictDamage(this, attacker, health.MaxHP, null, true); + health.InflictDamage(this, attacker, damage, warhead, false); + } + + public void Kill(Actor attacker) + { + if (Disposed || health == null) + return; + + health.Kill(this, attacker); } public bool IsDisabled() diff --git a/OpenRA.Game/Graphics/SelectionBarsRenderable.cs b/OpenRA.Game/Graphics/SelectionBarsRenderable.cs index 45cf7b9e36..0443c3ad62 100644 --- a/OpenRA.Game/Graphics/SelectionBarsRenderable.cs +++ b/OpenRA.Game/Graphics/SelectionBarsRenderable.cs @@ -74,7 +74,7 @@ namespace OpenRA.Graphics wlr.DrawLine(start + r, z + r, barColor2); } - Color GetHealthColor(Health health) + Color GetHealthColor(IHealth health) { var player = actor.World.RenderPlayer ?? actor.World.LocalPlayer; @@ -104,7 +104,7 @@ namespace OpenRA.Graphics health.DamageState == DamageState.Heavy ? Color.Yellow : Color.LimeGreen; } - void DrawHealthBar(WorldRenderer wr, Health health, float2 start, float2 end) + void DrawHealthBar(WorldRenderer wr, IHealth health, float2 start, float2 end) { if (health == null || health.IsDead) return; @@ -133,7 +133,7 @@ namespace OpenRA.Graphics wlr.DrawLine(start + q, z + q, healthColor); wlr.DrawLine(start + r, z + r, healthColor2); - if (health.DisplayHp != health.HP) + if (health.DisplayHP != health.HP) { var deltaColor = Color.OrangeRed; var deltaColor2 = Color.FromArgb( @@ -141,7 +141,7 @@ namespace OpenRA.Graphics deltaColor.R / 2, deltaColor.G / 2, deltaColor.B / 2); - var zz = float2.Lerp(start, end, (float)health.DisplayHp / health.MaxHP); + var zz = float2.Lerp(start, end, (float)health.DisplayHP / health.MaxHP); wlr.DrawLine(z + p, zz + p, deltaColor2); wlr.DrawLine(z + q, zz + q, deltaColor); @@ -155,7 +155,7 @@ namespace OpenRA.Graphics if (!actor.IsInWorld || actor.IsDead) return; - var health = actor.TraitOrDefault(); + var health = actor.TraitOrDefault(); var screenPos = wr.ScreenPxPosition(pos); var bounds = actor.VisualBounds; diff --git a/OpenRA.Game/Traits/Health.cs b/OpenRA.Game/Traits/Health.cs index 2771fab657..05821ded5a 100644 --- a/OpenRA.Game/Traits/Health.cs +++ b/OpenRA.Game/Traits/Health.cs @@ -26,15 +26,13 @@ namespace OpenRA.Traits public virtual object Create(ActorInitializer init) { return new Health(init, this); } } - public enum DamageState { Undamaged, Light, Medium, Heavy, Critical, Dead } - - public class Health : ISync, ITick + public class Health : IHealth, ISync, ITick { public readonly HealthInfo Info; [Sync] int hp; - public int DisplayHp { get; private set; } + public int DisplayHP { get; private set; } public Health(ActorInitializer init, HealthInfo info) { @@ -43,11 +41,11 @@ namespace OpenRA.Traits hp = init.Contains() ? init.Get() * MaxHP / 100 : MaxHP; - DisplayHp = hp; + DisplayHP = hp; } public int HP { get { return hp; } } - public int MaxHP; + public int MaxHP { get; private set; } public bool IsDead { get { return hp <= 0; } } public bool RemoveOnDeath = true; @@ -162,13 +160,18 @@ namespace OpenRA.Traits } } + public void Kill(Actor self, Actor attacker) + { + InflictDamage(self, attacker, MaxHP, null, true); + } + public void Tick(Actor self) { - if (hp > DisplayHp) - DisplayHp = hp; + if (hp > DisplayHP) + DisplayHP = hp; - if (DisplayHp > hp) - DisplayHp = (2 * DisplayHp + hp) / 3; + if (DisplayHP > hp) + DisplayHP = (2 * DisplayHP + hp) / 3; } } @@ -191,24 +194,4 @@ namespace OpenRA.Traits return value; } } - - public static class HealthExts - { - public static DamageState GetDamageState(this Actor self) - { - if (self.Disposed) - return DamageState.Dead; - - var health = self.TraitOrDefault(); - return (health == null) ? DamageState.Undamaged : health.DamageState; - } - - public static void InflictDamage(this Actor self, Actor attacker, int damage, IWarhead warhead) - { - if (self.Disposed) return; - var health = self.TraitOrDefault(); - if (health == null) return; - health.InflictDamage(self, attacker, damage, warhead, false); - } - } } diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 95cd22a7dc..800317fdf4 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -19,6 +19,20 @@ using OpenRA.Primitives; namespace OpenRA.Traits { + public enum DamageState { Undamaged, Light, Medium, Heavy, Critical, Dead } + + public interface IHealth + { + DamageState DamageState { get; } + int HP { get; } + int MaxHP { get; } + int DisplayHP { get; } + bool IsDead { get; } + + void InflictDamage(Actor self, Actor attacker, int damage, IWarhead warhead, bool ignoreModifiers); + void Kill(Actor self, Actor attacker); + } + // depends on the order of pips in WorldRenderer.cs! public enum PipType { Transparent, Green, Yellow, Red, Gray, Blue, Ammo, AmmoEmpty } public enum TagType { None, Fake, Primary }