diff --git a/OpenRa.Game/MainWindow.cs b/OpenRa.Game/MainWindow.cs
index 14086e2779..92b4f4067f 100755
--- a/OpenRa.Game/MainWindow.cs
+++ b/OpenRa.Game/MainWindow.cs
@@ -63,6 +63,7 @@ namespace OpenRa.Game
Game.world.Add( new Actor( "mcv", Game.map.Offset + new int2( 9, 5 ), Game.players[ 0 ] ) );
Game.world.Add( new Actor( "jeep", Game.map.Offset + new int2( 9, 14 ), Game.players[ 1 ] ) );
Game.world.Add( new Actor( "3tnk", Game.map.Offset + new int2( 12, 7 ), Game.players[ 1 ] ) );
+ Game.world.Add(new Actor("apc", Game.map.Offset + new int2(13, 7), Game.players[1]));
Game.world.Add(new Actor("ca", Game.map.Offset + new int2(40, 7), Game.players[1]));
Game.world.Add(new Actor("e1", Game.map.Offset + new int2(9, 13), Game.players[1]));
Game.world.Add(new Actor("arty", Game.map.Offset + new int2(10, 13), Game.players[1]));
diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj
index f601117070..5cd94575af 100644
--- a/OpenRa.Game/OpenRa.Game.csproj
+++ b/OpenRa.Game/OpenRa.Game.csproj
@@ -153,6 +153,7 @@
+
diff --git a/OpenRa.Game/Traits/AttackTurreted.cs b/OpenRa.Game/Traits/AttackTurreted.cs
index 0dda1090c1..e79f5ddc28 100755
--- a/OpenRa.Game/Traits/AttackTurreted.cs
+++ b/OpenRa.Game/Traits/AttackTurreted.cs
@@ -13,6 +13,8 @@ namespace OpenRa.Game.Traits
protected int primaryFireDelay = 0;
protected int secondaryFireDelay = 0;
+ public float primaryRecoil = 0.0f, secondaryRecoil = 0.0f;
+
public AttackBase(Actor self) { }
protected bool CanAttack( Actor self )
@@ -25,6 +27,9 @@ namespace OpenRa.Game.Traits
if (primaryFireDelay > 0) --primaryFireDelay;
if (secondaryFireDelay > 0) --secondaryFireDelay;
+ primaryRecoil = Math.Max(0f, primaryRecoil - .2f);
+ secondaryRecoil = Math.Max(0f, secondaryRecoil - .2f);
+
if (target != null && target.IsDead) target = null; /* he's dead, jim. */
}
@@ -36,20 +41,15 @@ namespace OpenRa.Game.Traits
self.unitInfo.PrimaryOffset ) )
{
secondaryFireDelay = Math.Max( 4, secondaryFireDelay );
- if (rut != null) rut.primaryRecoil = 1;
+ primaryRecoil = 1;
return;
}
if (self.unitInfo.Secondary != null && CheckFire(self, self.unitInfo.Secondary, ref secondaryFireDelay,
self.unitInfo.SecondaryOffset ?? self.unitInfo.PrimaryOffset))
{
- if (rut != null)
- {
- if (self.unitInfo.SecondaryOffset != null)
- rut.secondaryRecoil = 1;
- else
- rut.primaryRecoil = 1;
- }
+ if (self.unitInfo.SecondaryOffset != null) secondaryRecoil = 1;
+ else primaryRecoil = 1;
return;
}
}
diff --git a/OpenRa.Game/Traits/RenderUnitMuzzleFlash.cs b/OpenRa.Game/Traits/RenderUnitMuzzleFlash.cs
new file mode 100644
index 0000000000..194cc8d2c8
--- /dev/null
+++ b/OpenRa.Game/Traits/RenderUnitMuzzleFlash.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using OpenRa.Game.Graphics;
+
+namespace OpenRa.Game.Traits
+{
+ class RenderUnitMuzzleFlash : RenderUnit
+ {
+ Animation muzzleFlash;
+
+ public RenderUnitMuzzleFlash(Actor self)
+ : base(self)
+ {
+ if (!self.unitInfo.MuzzleFlash) throw new InvalidOperationException("wtf??");
+
+ muzzleFlash = new Animation(self.unitInfo.Name);
+ muzzleFlash.PlayFetchIndex("muzzle",
+ () =>
+ {
+ var attack = self.traits.WithInterface().First();
+ var mobile = self.traits.WithInterface().First();
+ return (Util.QuantizeFacing(
+ mobile.facing, 8)) * 6 + (int)(attack.primaryRecoil * 5.9f);
+ });
+ }
+
+ public override void Tick(Actor self)
+ {
+ base.Tick(self);
+ muzzleFlash.Tick();
+ }
+
+ public override IEnumerable> Render(Actor self)
+ {
+ var attack = self.traits.WithInterface().First();
+ if (attack.primaryRecoil > 0)
+ return base.Render(self).Concat(new[] {Util.Centered(self,
+ muzzleFlash.Image, self.CenterLocation + new float2(
+ self.unitInfo.PrimaryOffset.ElementAtOrDefault(2),
+ self.unitInfo.PrimaryOffset.ElementAtOrDefault(3)))});
+ else
+ return base.Render(self);
+ }
+ }
+}
diff --git a/OpenRa.Game/Traits/RenderUnitTurreted.cs b/OpenRa.Game/Traits/RenderUnitTurreted.cs
index dce1b47a38..bcdac9a98d 100644
--- a/OpenRa.Game/Traits/RenderUnitTurreted.cs
+++ b/OpenRa.Game/Traits/RenderUnitTurreted.cs
@@ -11,7 +11,6 @@ namespace OpenRa.Game.Traits
{
public Animation turretAnim;
public Animation muzzleFlash;
- public float primaryRecoil = 0.0f, secondaryRecoil = 0.0f;
public RenderUnitTurreted(Actor self)
: base(self)
@@ -21,9 +20,11 @@ namespace OpenRa.Game.Traits
{
if (self.unitInfo.MuzzleFlash)
{
+ var attack = self.traits.WithInterface().First();
muzzleFlash = new Animation(self.unitInfo.Name);
muzzleFlash.PlayFetchIndex("muzzle",
- () => (Util.QuantizeFacing(self.traits.Get().turretFacing,8)) * 6 + (int)(primaryRecoil * 6));
+ () => (Util.QuantizeFacing(self.traits.Get().turretFacing,8)) * 6 + (int)(attack.primaryRecoil * 5.9f));
+ /* hack: recoil can be 1.0f, but don't overflow into next anim */
}
turretAnim.PlayFetchIndex("turret",
@@ -36,25 +37,24 @@ namespace OpenRa.Game.Traits
public override IEnumerable> Render(Actor self)
{
var mobile = self.traits.Get();
+ var attack = self.traits.WithInterface().FirstOrDefault();
yield return Util.Centered(self, anim.Image, self.CenterLocation);
yield return Util.Centered(self, turretAnim.Image, self.CenterLocation
- + Util.GetTurretPosition(self, self.unitInfo.PrimaryOffset, primaryRecoil));
+ + Util.GetTurretPosition(self, self.unitInfo.PrimaryOffset, attack.primaryRecoil));
if (self.unitInfo.SecondaryOffset != null)
yield return Util.Centered(self, turretAnim.Image, self.CenterLocation
- + Util.GetTurretPosition(self, self.unitInfo.SecondaryOffset, secondaryRecoil));
+ + Util.GetTurretPosition(self, self.unitInfo.SecondaryOffset, attack.secondaryRecoil));
- if (muzzleFlash != null && primaryRecoil > 0)
+ if (muzzleFlash != null && attack.primaryRecoil > 0)
yield return Util.Centered(self, muzzleFlash.Image, self.CenterLocation
- + Util.GetTurretPosition(self, self.unitInfo.PrimaryOffset, primaryRecoil));
+ + Util.GetTurretPosition(self, self.unitInfo.PrimaryOffset, attack.primaryRecoil));
}
public override void Tick(Actor self)
{
base.Tick(self);
turretAnim.Tick();
- primaryRecoil = Math.Max(0f, primaryRecoil - .2f);
- secondaryRecoil = Math.Max(0f, secondaryRecoil - .2f);
if (muzzleFlash != null)
muzzleFlash.Tick();
}
diff --git a/sequences.xml b/sequences.xml
index e3b88530a2..cc38b910b7 100644
--- a/sequences.xml
+++ b/sequences.xml
@@ -275,6 +275,7 @@
+
diff --git a/units.ini b/units.ini
index 02addd386d..5fd9cd1c0a 100755
--- a/units.ini
+++ b/units.ini
@@ -55,7 +55,9 @@ PrimaryOffset=0,0,0,-2
MuzzleFlash=yes
[APC]
Description=Armored Personnel Carrier
-Traits=Mobile, RenderUnit, AttackBase
+Traits=Mobile, AttackBase, RenderUnitMuzzleFlash
+PrimaryOffset=0,0,0,-4
+MuzzleFlash=yes
[MNLY]
Description=Minelayer
Traits=Mobile, RenderUnit