diff --git a/OpenRA.Mods.Common/Traits/Explodes.cs b/OpenRA.Mods.Common/Traits/Explodes.cs index 17cda90a7c..3fd58b3dd3 100644 --- a/OpenRA.Mods.Common/Traits/Explodes.cs +++ b/OpenRA.Mods.Common/Traits/Explodes.cs @@ -17,6 +17,8 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { + public enum ExplosionType { Footprint, CenterPosition } + [Desc("This actor explodes when killed.")] public class ExplodesInfo : ITraitInfo, IRulesetLoaded, Requires { @@ -38,6 +40,10 @@ namespace OpenRA.Mods.Common.Traits [Desc("DeathType(s) that trigger the explosion. Leave empty to always trigger an explosion.")] public readonly HashSet DeathTypes = new HashSet(); + [Desc("Possible values are CenterPosition (explosion at the actors' center) and ", + "Footprint (explosion on each occupied cell).")] + public readonly ExplosionType Type = ExplosionType.CenterPosition; + public WeaponInfo WeaponInfo { get; private set; } public WeaponInfo EmptyWeaponInfo { get; private set; } @@ -49,11 +55,11 @@ namespace OpenRA.Mods.Common.Traits } } - public class Explodes : INotifyKilled, INotifyDamage + public class Explodes : INotifyKilled, INotifyDamage, INotifyCreated { readonly ExplodesInfo info; - readonly Health health; + BuildingInfo buildingInfo; public Explodes(ExplodesInfo info, Actor self) { @@ -61,6 +67,11 @@ namespace OpenRA.Mods.Common.Traits health = self.Trait(); } + void INotifyCreated.Created(Actor self) + { + buildingInfo = self.Info.TraitInfoOrDefault(); + } + void INotifyKilled.Killed(Actor self, AttackInfo e) { if (!self.IsInWorld) @@ -79,6 +90,15 @@ namespace OpenRA.Mods.Common.Traits if (weapon.Report != null && weapon.Report.Any()) Game.Sound.Play(weapon.Report.Random(e.Attacker.World.SharedRandom), self.CenterPosition); + if (info.Type == ExplosionType.Footprint && buildingInfo != null) + { + var cells = FootprintUtils.UnpathableTiles(self.Info.Name, buildingInfo, self.Location); + foreach (var c in cells) + weapon.Impact(Target.FromPos(self.World.Map.CenterOfCell(c)), e.Attacker, Enumerable.Empty()); + + return; + } + // Use .FromPos since this actor is killed. Cannot use Target.FromActor weapon.Impact(Target.FromPos(self.CenterPosition), e.Attacker, Enumerable.Empty()); }