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));
+ });
+ }
+ }
+}