diff --git a/OpenRA.Mods.RA/Armament.cs b/OpenRA.Mods.RA/Armament.cs index 2b819b44a6..3f23ff9a6e 100644 --- a/OpenRA.Mods.RA/Armament.cs +++ b/OpenRA.Mods.RA/Armament.cs @@ -44,6 +44,12 @@ namespace OpenRA.Mods.RA [Desc("Recoil recovery per-frame")] public readonly WRange RecoilRecovery = new WRange(9); + [Desc("Muzzle flash sequence to render")] + public readonly string MuzzleSequence = null; + + [Desc("Use multiple muzzle images if non-zero")] + public readonly int MuzzleSplitFacings = 0; + public object Create(ActorInitializer init) { return new Armament(init.self, this); } } diff --git a/OpenRA.Mods.RA/Render/WithMuzzleFlash.cs b/OpenRA.Mods.RA/Render/WithMuzzleFlash.cs index e59b182949..0b2e099fda 100644 --- a/OpenRA.Mods.RA/Render/WithMuzzleFlash.cs +++ b/OpenRA.Mods.RA/Render/WithMuzzleFlash.cs @@ -19,67 +19,56 @@ namespace OpenRA.Mods.RA.Render { class WithMuzzleFlashInfo : ITraitInfo, Requires, Requires, Requires { - [Desc("Sequence name to use")] - public readonly string Sequence = "muzzle"; - - [Desc("Armament name")] - public readonly string Armament = "primary"; - - [Desc("Are the muzzle facings split into multiple shps?")] - public readonly bool SplitFacings = false; - - [Desc("Number of separate facing images that are defined in the sequences.")] - public readonly int FacingCount = 8; - - public object Create(ActorInitializer init) { return new WithMuzzleFlash(init.self, this); } + public object Create(ActorInitializer init) { return new WithMuzzleFlash(init.self); } } class WithMuzzleFlash : INotifyAttack, IRender, ITick { - readonly WithMuzzleFlashInfo info; Dictionary visible = new Dictionary(); Dictionary anims = new Dictionary(); Func getFacing; - public WithMuzzleFlash(Actor self, WithMuzzleFlashInfo info) + public WithMuzzleFlash(Actor self) { - this.info = info; var render = self.Trait(); var facing = self.TraitOrDefault(); - var arm = self.TraitsImplementing() - .Single(a => a.Info.Name == info.Armament); - - foreach (var b in arm.Barrels) + foreach (var arm in self.TraitsImplementing()) { - var barrel = b; - var turreted = self.TraitsImplementing() - .FirstOrDefault(t => t.Name == arm.Info.Turret); + // Skip armaments that don't define muzzles + if (arm.Info.MuzzleSequence == null) + continue; - getFacing = turreted != null ? () => turreted.turretFacing : - facing != null ? (Func)(() => facing.Facing) : () => 0; + foreach (var b in arm.Barrels) + { + var barrel = b; + var turreted = self.TraitsImplementing() + .FirstOrDefault(t => t.Name == arm.Info.Turret); - var muzzleFlash = new Animation(render.GetImage(self), getFacing); - visible.Add(barrel, false); - anims.Add(barrel, - new AnimationWithOffset(muzzleFlash, - () => arm.MuzzleOffset(self, barrel), - () => !visible[barrel], - p => WithTurret.ZOffsetFromCenter(self, p, 2))); + getFacing = turreted != null ? () => turreted.turretFacing : + facing != null ? (Func)(() => facing.Facing) : () => 0; + + var muzzleFlash = new Animation(render.GetImage(self), getFacing); + visible.Add(barrel, false); + anims.Add(barrel, + new AnimationWithOffset(muzzleFlash, + () => arm.MuzzleOffset(self, barrel), + () => !visible[barrel], + p => WithTurret.ZOffsetFromCenter(self, p, 2))); + } } } public void Attacking(Actor self, Target target, Armament a, Barrel barrel) { - if (a.Info.Name != info.Armament) + var sequence = a.Info.MuzzleSequence; + if (sequence == null) return; + if (a.Info.MuzzleSplitFacings > 0) + sequence += Traits.Util.QuantizeFacing(getFacing(), a.Info.MuzzleSplitFacings).ToString(); + visible[barrel] = true; - var sequence = info.Sequence; - - if (info.SplitFacings) - sequence += Traits.Util.QuantizeFacing(getFacing(), info.FacingCount).ToString(); - anims[barrel].Animation.PlayThen(sequence, () => visible[barrel] = false); }