diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
index 9cc732919d..1ba4218013 100644
--- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
+++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
@@ -440,6 +440,7 @@
+
diff --git a/OpenRA.Mods.RA/Render/WithBarrel.cs b/OpenRA.Mods.RA/Render/WithBarrel.cs
new file mode 100644
index 0000000000..e28cc4105b
--- /dev/null
+++ b/OpenRA.Mods.RA/Render/WithBarrel.cs
@@ -0,0 +1,102 @@
+#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.Collections.Generic;
+using System.Linq;
+using OpenRA.Graphics;
+using OpenRA.Mods.RA.Graphics;
+using OpenRA.Traits;
+
+namespace OpenRA.Mods.RA.Render
+{
+ [Desc("Renders barrels for units with the Turreted trait.")]
+ class WithBarrelInfo : ITraitInfo, IRenderActorPreviewSpritesInfo, Requires, Requires
+ {
+ [Desc("Sequence name to use")]
+ public readonly string Sequence = "barrel";
+
+ [Desc("Armament to use for recoil")]
+ public readonly string Armament = "primary";
+
+ [Desc("Turreted 'Barrel' key to display")]
+ public readonly string Barrel = "first";
+
+ [Desc("Visual offset")]
+ public readonly WVec LocalOffset = WVec.Zero;
+
+ public object Create(ActorInitializer init) { return new WithBarrel(init.self, this); }
+
+ public IEnumerable RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
+ {
+ var body = init.Actor.Traits.Get();
+ var armament = init.Actor.Traits.WithInterface()
+ .First(a => a.Name == Armament);
+ var t = init.Actor.Traits.WithInterface()
+ .First(tt => tt.Turret == armament.Turret);
+
+ var anim = new Animation(init.World, image, () => t.InitialFacing);
+ anim.Play(Sequence);
+
+ var turretOrientation = body.QuantizeOrientation(new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(t.InitialFacing)), facings);
+ var turretOffset = body.LocalToWorld(t.Offset.Rotate(turretOrientation));
+
+ yield return new SpriteActorPreview(anim, turretOffset, turretOffset.Y + turretOffset.Z, p, rs.Scale);
+ }
+ }
+
+ class WithBarrel
+ {
+ WithBarrelInfo info;
+ Actor self;
+ Armament armament;
+ Turreted turreted;
+ IBodyOrientation body;
+ Animation anim;
+
+ public WithBarrel(Actor self, WithBarrelInfo info)
+ {
+ this.self = self;
+ this.info = info;
+ body = self.Trait();
+ armament = self.TraitsImplementing()
+ .First(a => a.Info.Name == info.Armament);
+ turreted = self.TraitsImplementing()
+ .First(tt => tt.Name == armament.Info.Turret);
+
+ var rs = self.Trait();
+ anim = new Animation(self.World, rs.GetImage(self), () => turreted.turretFacing);
+ anim.Play(info.Sequence);
+ rs.Add("barrel_{0}".F(info.Barrel), new AnimationWithOffset(
+ anim, () => BarrelOffset(), null, () => false, p => WithTurret.ZOffsetFromCenter(self, p, 0)));
+
+ // Restrict turret facings to match the sprite
+ turreted.QuantizedFacings = anim.CurrentSequence.Facings;
+ }
+
+ WVec BarrelOffset()
+ {
+ var localOffset = info.LocalOffset + new WVec(-armament.Recoil, WRange.Zero, WRange.Zero);
+ var turretOffset = turreted != null ? turreted.Position(self) : WVec.Zero;
+ var turretOrientation = turreted != null ? turreted.LocalOrientation(self) : WRot.Zero;
+
+ var quantizedBody = body.QuantizeOrientation(self, self.Orientation);
+ var quantizedTurret = body.QuantizeOrientation(self, turretOrientation);
+ return turretOffset + body.LocalToWorld(localOffset.Rotate(quantizedTurret).Rotate(quantizedBody));
+ }
+
+ IEnumerable BarrelRotation()
+ {
+ var b = self.Orientation;
+ var qb = body.QuantizeOrientation(self, b);
+ yield return turreted.LocalOrientation(self) + WRot.FromYaw(b.Yaw - qb.Yaw);
+ yield return qb;
+ }
+ }
+}
diff --git a/OpenRA.Mods.RA/Render/WithTurret.cs b/OpenRA.Mods.RA/Render/WithTurret.cs
index 7f295feb86..c214e20a2c 100755
--- a/OpenRA.Mods.RA/Render/WithTurret.cs
+++ b/OpenRA.Mods.RA/Render/WithTurret.cs
@@ -16,7 +16,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.RA.Render
{
- [Desc("Renders barrels for units with the Turreted trait.")]
+ [Desc("Renders turrets for units with the Turreted trait.")]
class WithTurretInfo : ITraitInfo, IRenderActorPreviewSpritesInfo, Requires, Requires, Requires
{
[Desc("Sequence name to use")]