diff --git a/OpenRA.Mods.Common/Traits/Explodes.cs b/OpenRA.Mods.Common/Traits/Explodes.cs index 4eaa18c33a..3bc55dcd95 100644 --- a/OpenRA.Mods.Common/Traits/Explodes.cs +++ b/OpenRA.Mods.Common/Traits/Explodes.cs @@ -18,7 +18,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { [Desc("This actor explodes when killed.")] - public class ExplodesInfo : ITraitInfo, IRulesetLoaded + public class ExplodesInfo : ITraitInfo, IRulesetLoaded, Requires { [WeaponReference, FieldLoader.Require, Desc("Weapon to use for explosion if ammo/payload is loaded.")] public readonly string Weapon = "UnitExplode"; @@ -32,13 +32,16 @@ namespace OpenRA.Mods.Common.Traits [Desc("Chance that this actor will explode at all.")] public readonly int Chance = 100; + [Desc("Health level at which actor will explode.")] + public readonly int DamageThreshold = 0; + [Desc("DeathType(s) to apply upon explosion.")] public readonly HashSet DeathType = new HashSet(); public WeaponInfo WeaponInfo { get; private set; } public WeaponInfo EmptyWeaponInfo { get; private set; } - public object Create(ActorInitializer init) { return new Explodes(this); } + public object Create(ActorInitializer init) { return new Explodes(this, init.Self); } public void RulesetLoaded(Ruleset rules, ActorInfo ai) { WeaponInfo = string.IsNullOrEmpty(Weapon) ? null : rules.Weapons[Weapon.ToLowerInvariant()]; @@ -46,11 +49,17 @@ namespace OpenRA.Mods.Common.Traits } } - public class Explodes : INotifyKilled + public class Explodes : INotifyKilled, INotifyDamage { readonly ExplodesInfo info; - public Explodes(ExplodesInfo info) { this.info = info; } + readonly Health health; + + public Explodes(ExplodesInfo info, Actor self) + { + this.info = info; + health = self.Trait(); + } public void Killed(Actor self, AttackInfo e) { @@ -81,5 +90,14 @@ namespace OpenRA.Mods.Common.Traits var useFullExplosion = self.World.SharedRandom.Next(100) <= info.LoadedChance; return (shouldExplode && useFullExplosion) ? info.WeaponInfo : info.EmptyWeaponInfo; } + + public void Damaged(Actor self, AttackInfo e) + { + if (info.DamageThreshold == 0) + return; + + if (health.HP * 100 < info.DamageThreshold * health.MaxHP) + self.World.AddFrameEndTask(w => self.Kill(e.Attacker)); + } } } diff --git a/mods/ra/rules/civilian.yaml b/mods/ra/rules/civilian.yaml index f7e01e7ef0..8a61005f49 100644 --- a/mods/ra/rules/civilian.yaml +++ b/mods/ra/rules/civilian.yaml @@ -237,7 +237,6 @@ V19.Husk: WithIdleOverlay: StartSequence: fire-start Sequence: fire-loop - -Health: -Selectable: -Targetable: -Demolishable: diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml index 75d03035a8..0484dd29b4 100644 --- a/mods/ra/rules/defaults.yaml +++ b/mods/ra/rules/defaults.yaml @@ -506,6 +506,9 @@ -GivesBuildableArea: Health: HP: 100 + Explodes: + Weapon: Demolish + DamageThreshold: 90 RevealsShroud: Range: 4c0 Fake: diff --git a/mods/ra/rules/fakes.yaml b/mods/ra/rules/fakes.yaml index 7e2f81eeab..ec700defae 100644 --- a/mods/ra/rules/fakes.yaml +++ b/mods/ra/rules/fakes.yaml @@ -19,6 +19,10 @@ FACF: Image: FACT Valued: Cost: 250 + Health: + HP: 1500 + Armor: + Type: Wood WEAF: Inherits: ^FakeBuilding @@ -43,6 +47,10 @@ WEAF: Sequence: build-top Valued: Cost: 200 + Health: + HP: 1500 + Armor: + Type: Wood SYRF: Inherits: ^FakeBuilding @@ -68,6 +76,10 @@ SYRF: Image: SYRD Valued: Cost: 100 + Health: + HP: 1000 + Armor: + Type: Light EditorTilesetFilter: ExcludeTilesets: INTERIOR @@ -95,6 +107,10 @@ SPEF: Image: SPEN Valued: Cost: 100 + Health: + HP: 1000 + Armor: + Type: Light EditorTilesetFilter: ExcludeTilesets: INTERIOR @@ -119,6 +135,10 @@ DOMF: Image: DOME Valued: Cost: 180 + Health: + HP: 1000 + Armor: + Type: Wood RequiresPower: DisabledOverlay: @@ -143,6 +163,10 @@ ATEF: Image: ATEK Valued: Cost: 150 + Health: + HP: 400 + Armor: + Type: Wood RequiresPower: DisabledOverlay: @@ -169,6 +193,12 @@ PDOF: HasMinibib: Yes Valued: Cost: 150 + Health: + HP: 1000 + Armor: + Type: Wood + Explodes: + DamageThreshold: 50 RequiresPower: DisabledOverlay: @@ -193,6 +223,12 @@ MSLF: Image: MSLO Valued: Cost: 250 + Health: + HP: 1000 + Armor: + Type: Wood + Explodes: + DamageThreshold: 50 RequiresPower: DisabledOverlay: