diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 279ac6de3e..b693f68d15 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -331,6 +331,7 @@ + diff --git a/OpenRA.Mods.RA/Render/RenderInfantry.cs b/OpenRA.Mods.RA/Render/RenderInfantry.cs index c6211e4f47..e6786db3e6 100644 --- a/OpenRA.Mods.RA/Render/RenderInfantry.cs +++ b/OpenRA.Mods.RA/Render/RenderInfantry.cs @@ -21,10 +21,8 @@ namespace OpenRA.Mods.RA.Render { public readonly int MinIdleWaitTicks = 30; public readonly int MaxIdleWaitTicks = 110; - public readonly bool SpawnsCorpse = true; public readonly string MoveAnimation = "run"; public readonly string AttackAnimation = "shoot"; - public readonly string DeathAnimationPrefix = "die"; public readonly string[] IdleAnimations = { }; public readonly string[] StandAnimations = { "stand" }; @@ -48,7 +46,7 @@ namespace OpenRA.Mods.RA.Render } } - public class RenderInfantry : RenderSimple, INotifyAttack, INotifyKilled, INotifyIdle + public class RenderInfantry : RenderSimple, INotifyAttack, INotifyIdle { readonly RenderInfantryInfo info; readonly IMove move; @@ -151,29 +149,6 @@ namespace OpenRA.Mods.RA.Render } } - // TODO: Possibly move this into a separate trait - public void Killed(Actor self, AttackInfo e) - { - // Killed by some non-standard means - if (e.Warhead == null) - return; - - if (info.SpawnsCorpse) - { - SpawnCorpse(self, info.DeathAnimationPrefix + (e.Warhead.DeathType)); - } - } - - public void SpawnCorpse(Actor self, string sequence) - { - self.World.AddFrameEndTask(w => - { - if (!self.Destroyed) - w.Add(new Corpse(w, self.CenterPosition, GetImage(self), - sequence, info.PlayerPalette + self.Owner.InternalName)); - }); - } - enum AnimationState { Idle, diff --git a/OpenRA.Mods.RA/Render/WithDeathAnimation.cs b/OpenRA.Mods.RA/Render/WithDeathAnimation.cs new file mode 100644 index 0000000000..c1ec7aeeb3 --- /dev/null +++ b/OpenRA.Mods.RA/Render/WithDeathAnimation.cs @@ -0,0 +1,75 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System.Linq; +using OpenRA.Mods.RA.Effects; +using OpenRA.Mods.RA.Render; +using OpenRA.Traits; + +namespace OpenRA.Mods.RA.Render +{ + [Desc("This actor has a death animation.")] + public class WithDeathAnimationInfo : ITraitInfo, Requires + { + [Desc("Sequence to play when this actor is killed by a warhead.")] + public readonly string DeathSequence = "die"; + public readonly string DeathSequencePalette = "player"; + [Desc("Custom death animation palette is a player palette BaseName")] + public readonly bool DeathPaletteIsPlayerPalette = true; + [Desc("Should DeathType-specific sequences be used (sequence name = DeathSequence + DeathType).")] + public readonly bool UseDeathTypeSuffix = true; + [Desc("Sequence to play when this actor is crushed.")] + public readonly string CrushedSequence = "die-crushed"; + public readonly string CrushedSequencePalette = "effect"; + [Desc("Custom crushed animation palette is a player palette BaseName")] + public readonly bool CrushedPaletteIsPlayerPalette = false; + + public object Create(ActorInitializer init) { return new WithDeathAnimation(init.self, this); } + } + + public class WithDeathAnimation : INotifyKilled + { + public readonly WithDeathAnimationInfo Info; + readonly RenderSimple renderSimple; + + public WithDeathAnimation(Actor self, WithDeathAnimationInfo info) + { + Info = info; + renderSimple = self.Trait(); + } + + public void Killed(Actor self, AttackInfo e) + { + // Killed by some non-standard means. This includes being crushed + // by a vehicle (Actors with Crushable trait will spawn CrushedSequence instead). + if (e.Warhead == null) + return; + + var sequence = Info.DeathSequence; + if (Info.UseDeathTypeSuffix) + sequence += e.Warhead.DeathType; + + var palette = Info.DeathSequencePalette; + if (Info.DeathPaletteIsPlayerPalette) + palette += self.Owner.InternalName; + + SpawnDeathAnimation(self, sequence, palette); + } + + public void SpawnDeathAnimation(Actor self, string sequence, string palette) + { + self.World.AddFrameEndTask(w => + { + if (!self.Destroyed) + w.Add(new Corpse(w, self.CenterPosition, renderSimple.GetImage(self), sequence, palette)); + }); + } + } +}