diff --git a/OpenRA.Mods.RA/Activities/Demolish.cs b/OpenRA.Mods.RA/Activities/Demolish.cs index cb9df8f8c7..a2d4189a0d 100644 --- a/OpenRA.Mods.RA/Activities/Demolish.cs +++ b/OpenRA.Mods.RA/Activities/Demolish.cs @@ -8,24 +8,28 @@ */ #endregion +using System.Collections.Generic; using System.Linq; using OpenRA.Effects; using OpenRA.Traits; namespace OpenRA.Mods.RA.Activities { - class Demolish : Activity + class Demolish : Enter { - readonly Target target; + readonly Actor target; + readonly IEnumerable demolishables; readonly int delay; readonly int flashes; readonly int flashesDelay; readonly int flashInterval; readonly int flashDuration; - public Demolish(Actor target, int delay, int flashes, int flashesDelay, int flashInterval, int flashDuration) + public Demolish(Actor self, Actor target, int delay, int flashes, int flashesDelay, int flashInterval, int flashDuration) + : base(self, target) { - this.target = Target.FromActor(target); + this.target = target; + demolishables = target.TraitsImplementing(); this.delay = delay; this.flashes = flashes; this.flashesDelay = flashesDelay; @@ -33,39 +37,35 @@ namespace OpenRA.Mods.RA.Activities this.flashDuration = flashDuration; } - public override Activity Tick(Actor self) + protected override bool CanReserve(Actor self) { - if (IsCanceled || !target.IsValidFor(self)) - return NextActivity; + return demolishables.Any(i => i.IsValidTarget(target, self)); + } + protected override void OnInside(Actor self) + { self.World.AddFrameEndTask(w => { + if (target.IsDead()) + return; + for (var f = 0; f < flashes; f++) w.Add(new DelayedAction(flashesDelay + f * flashInterval, () => - w.Add(new FlashTarget(target.Actor, ticks: flashDuration)))); + w.Add(new FlashTarget(target, ticks: flashDuration)))); w.Add(new DelayedAction(delay, () => { - // Can't demolish an already dead actor - if (target.Type != TargetType.Actor) + if (target.IsDead()) return; - - - var demolishable = target.Actor.TraitOrDefault(); - if (demolishable == null || !demolishable.IsValidTarget(target.Actor, self)) - return; - - var modifiers = target.Actor.TraitsImplementing() + var modifiers = target.TraitsImplementing() .Concat(self.Owner.PlayerActor.TraitsImplementing()) .Select(t => t.GetDamageModifier(self, null)); if (Util.ApplyPercentageModifiers(100, modifiers) > 0) - demolishable.Demolish(target.Actor, self); + demolishables.Do(d => d.Demolish(target, self)); })); }); - - return NextActivity; } } } diff --git a/OpenRA.Mods.RA/C4Demolition.cs b/OpenRA.Mods.RA/C4Demolition.cs index 2e220bd515..4c291439e4 100644 --- a/OpenRA.Mods.RA/C4Demolition.cs +++ b/OpenRA.Mods.RA/C4Demolition.cs @@ -76,8 +76,8 @@ namespace OpenRA.Mods.RA self.CancelActivity(); self.SetTargetLine(target, Color.Red); - self.QueueActivity(new Enter(self, target.Actor, new Demolish( - target.Actor, info.C4Delay, info.Flashes, info.FlashesDelay, info.FlashInterval, info.FlashDuration))); + self.QueueActivity(new Demolish(self, + target.Actor, info.C4Delay, info.Flashes, info.FlashesDelay, info.FlashInterval, info.FlashDuration)); } public string VoicePhraseForOrder(Actor self, Order order)