diff --git a/OpenRA.Game/Traits/AttackBase.cs b/OpenRA.Game/Traits/AttackBase.cs index 4001cf4254..3b897c7a4a 100644 --- a/OpenRA.Game/Traits/AttackBase.cs +++ b/OpenRA.Game/Traits/AttackBase.cs @@ -44,7 +44,7 @@ namespace OpenRA.Traits public virtual object Create(ActorInitializer init) { return new AttackBase(init.self); } } - public class AttackBase : IIssueOrder, IResolveOrder, ITick + public class AttackBase : IIssueOrder, IResolveOrder, ITick, IExplodeModifier { [Sync] public Actor target; @@ -77,6 +77,8 @@ namespace OpenRA.Traits return true; } + public bool ShouldExplode(Actor self) { return !IsReloading(); } + public bool IsReloading() { return (primaryFireDelay > 0) || (secondaryFireDelay > 0); diff --git a/OpenRA.Game/Traits/StoresOre.cs b/OpenRA.Game/Traits/StoresOre.cs index 62f4f32abb..cc74a9f6fe 100644 --- a/OpenRA.Game/Traits/StoresOre.cs +++ b/OpenRA.Game/Traits/StoresOre.cs @@ -27,11 +27,10 @@ namespace OpenRA.Traits public readonly int PipCount = 0; public readonly PipType PipColor = PipType.Yellow; public readonly int Capacity = 0; - [WeaponReference] public readonly string DeathWeapon = null; public object Create(ActorInitializer init) { return new StoresOre(init.self, this); } } - class StoresOre : IPips, INotifyCapture, INotifyDamage + class StoresOre : IPips, INotifyCapture, INotifyDamage, IExplodeModifier { readonly PlayerResources Player; readonly StoresOreInfo Info; @@ -57,16 +56,7 @@ namespace OpenRA.Traits public void Damaged(Actor self, AttackInfo e) { if (self.IsDead && Player.GetSiloFullness() > 0) - { - if (Info.DeathWeapon != null) - { - Combat.DoExplosion(e.Attacker, Info.DeathWeapon, - self.CenterLocation.ToInt2(), 0); - } - - // Lose the stored ore - Player.TakeOre(Stored(self)); - } + Player.TakeOre(Stored(self)); // Lose the stored ore } public IEnumerable GetPips(Actor self) @@ -75,5 +65,7 @@ namespace OpenRA.Traits i => (Player.GetSiloFullness() > i * 1.0f / Info.PipCount) ? Info.PipColor : PipType.Transparent ); } + + public bool ShouldExplode(Actor self) { return Player.GetSiloFullness() > 0; } } } diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 6242b253a2..b4b7a67ee7 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -61,6 +61,7 @@ namespace OpenRA.Traits public interface ITerrainCost { float GetTerrainCost(int2 cell, Actor forActor); } public interface IDisable { bool Disabled { get; } } + public interface IExplodeModifier { bool ShouldExplode(Actor self); } public interface IOccupySpace { diff --git a/OpenRA.Mods.RA/Explodes.cs b/OpenRA.Mods.RA/Explodes.cs index fb9fcf561a..d09ccfdea2 100644 --- a/OpenRA.Mods.RA/Explodes.cs +++ b/OpenRA.Mods.RA/Explodes.cs @@ -18,6 +18,7 @@ */ #endregion +using System.Linq; using OpenRA.Traits; namespace OpenRA.Mods.RA @@ -49,12 +50,10 @@ namespace OpenRA.Mods.RA string ChooseWeaponForExplosion(Actor self) { + var shouldExplode = self.traits.WithInterface().All(a => a.ShouldExplode(self)); + var info = self.Info.Traits.Get(); - var attack = self.traits.GetOrDefault(); - - if (attack == null) return info.Weapon; - - return attack.IsReloading() ? info.EmptyWeapon : info.Weapon; + return shouldExplode ? info.Weapon : info.EmptyWeapon; } } } diff --git a/OpenRA.Mods.RA/Harvester.cs b/OpenRA.Mods.RA/Harvester.cs index a01e862dc6..66f43baeda 100755 --- a/OpenRA.Mods.RA/Harvester.cs +++ b/OpenRA.Mods.RA/Harvester.cs @@ -32,13 +32,11 @@ namespace OpenRA.Mods.RA public readonly int PipCount = 7; public readonly PipType PipColor = PipType.Yellow; public readonly string[] Resources = { }; - [WeaponReference] - public readonly string DeathWeapon = null; public object Create(ActorInitializer init) { return new Harvester(init.self, this); } } - public class Harvester : IIssueOrder, IResolveOrder, INotifyDamage, IPips, IRenderModifier + public class Harvester : IIssueOrder, IResolveOrder, INotifyDamage, IPips, IRenderModifier, IExplodeModifier { Dictionary contents = new Dictionary(); @@ -143,16 +141,8 @@ namespace OpenRA.Mods.RA public void Damaged(Actor self, AttackInfo e) { if (self.IsDead) - { - if (Info.DeathWeapon != null && contents.Count > 0) - { - Combat.DoExplosion(e.Attacker, Info.DeathWeapon, - self.CenterLocation.ToInt2(), 0); - } - if (LinkedProc != null) LinkedProc.traits.WithInterface().FirstOrDefault().UnlinkHarvester(LinkedProc,self); - } } public void LinkProc(Actor self, Actor proc) @@ -185,6 +175,8 @@ namespace OpenRA.Mods.RA public IEnumerable ModifyRender(Actor self, IEnumerable r) { return Visible ? r : new Renderable[] { }; - } + } + + public bool ShouldExplode(Actor self) { return !IsEmpty; } } } diff --git a/OpenRA.Mods.RA/OreRefinery.cs b/OpenRA.Mods.RA/OreRefinery.cs index 268e919852..17a0be666c 100755 --- a/OpenRA.Mods.RA/OreRefinery.cs +++ b/OpenRA.Mods.RA/OreRefinery.cs @@ -36,13 +36,11 @@ namespace OpenRA.Mods.RA public readonly int Capacity = 0; public readonly int ProcessTick = 25; public readonly int ProcessAmount = 50; - [WeaponReference] - public readonly string DeathWeapon = null; public object Create(ActorInitializer init) { return new OreRefinery(init.self, this); } } - class OreRefinery : ITick, IAcceptOre, INotifyDamage, INotifySold, INotifyCapture, IPips + class OreRefinery : ITick, IAcceptOre, INotifyDamage, INotifySold, INotifyCapture, IPips, IExplodeModifier { readonly Actor self; readonly OreRefineryInfo Info; @@ -106,14 +104,9 @@ namespace OpenRA.Mods.RA public void Damaged (Actor self, AttackInfo e) { - if (self.IsDead) { - if (Info.DeathWeapon != null && Ore > 0) { - Combat.DoExplosion (e.Attacker, Info.DeathWeapon, self.CenterLocation.ToInt2 (), 0); - } - + if (self.IsDead) foreach (var harv in LinkedHarv) harv.traits.Get ().UnlinkProc(harv, self); - } } public int2 DeliverOffset {get{ return Info.DockOffset; }} @@ -146,5 +139,7 @@ namespace OpenRA.Mods.RA return Graphics.Util.MakeArray (Info.PipCount, i => (Ore * 1f / Info.Capacity > i * 1f / Info.PipCount) ? Info.PipColor : PipType.Transparent); } + + public bool ShouldExplode(Actor self) { return Ore > 0; } } }