This commit is contained in:
Chris Forbes
2009-10-31 18:42:49 +13:00
parent 4201f40f6b
commit 8cd7106e4f
5 changed files with 56 additions and 20 deletions

View File

@@ -49,6 +49,7 @@ namespace OpenRa.Game.GameRules
public readonly string[] BuiltAt = { };
public readonly int[] PrimaryOffset = { 0, 0 };
public readonly int[] SecondaryOffset = null;
public readonly int Recoil = 0;
public UnitInfo(string name) { Name = name; }

View File

@@ -26,14 +26,28 @@ namespace OpenRa.Game.Traits
protected void DoAttack( Actor self )
{
if( self.unitInfo.Primary != null && CheckFire( self, self.unitInfo.Primary, ref primaryFireDelay, self.unitInfo.PrimaryOffset ) )
var rut = self.traits.GetOrDefault<RenderUnitTurreted>();
if( self.unitInfo.Primary != null && CheckFire( self, self.unitInfo.Primary, ref primaryFireDelay,
self.unitInfo.PrimaryOffset ) )
{
secondaryFireDelay = Math.Max( 4, secondaryFireDelay );
if (rut != null) rut.primaryRecoil = 1;
return;
}
if( self.unitInfo.Secondary != null && CheckFire( self, self.unitInfo.Secondary, ref secondaryFireDelay,
self.unitInfo.SecondaryOffset ?? self.unitInfo.PrimaryOffset) )
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;
}
return;
}
}
bool CheckFire( Actor self, string weaponName, ref int fireDelay, int[] offset )
@@ -45,7 +59,7 @@ namespace OpenRa.Game.Traits
fireDelay = weapon.ROF;
Game.world.Add( new Bullet( weaponName, self.Owner, self,
self.CenterLocation.ToInt2() + Util.GetTurretPosition( self, offset ),
self.CenterLocation.ToInt2() + Util.GetTurretPosition( self, offset, 0f ).ToInt2(),
target.CenterLocation.ToInt2() ) );
return true;

View File

@@ -10,6 +10,7 @@ namespace OpenRa.Game.Traits
class RenderUnitTurreted : RenderUnit
{
public Animation turretAnim;
public float primaryRecoil = 0.0f, secondaryRecoil = 0.0f;
public RenderUnitTurreted(Actor self)
: base(self)
@@ -24,16 +25,18 @@ namespace OpenRa.Game.Traits
yield return Centered(anim.Image, self.CenterLocation);
yield return Centered(turretAnim.Image, self.CenterLocation
+ Util.GetTurretPosition(self, self.unitInfo.PrimaryOffset).ToFloat2());
+ Util.GetTurretPosition(self, self.unitInfo.PrimaryOffset, primaryRecoil));
if (self.unitInfo.SecondaryOffset != null)
yield return Centered(turretAnim.Image, self.CenterLocation
+ Util.GetTurretPosition(self, self.unitInfo.SecondaryOffset).ToFloat2());
+ Util.GetTurretPosition(self, self.unitInfo.SecondaryOffset, secondaryRecoil));
}
public override void Tick(Actor self)
{
base.Tick(self);
turretAnim.Tick();
primaryRecoil = Math.Max(0f, primaryRecoil - .2f);
secondaryRecoil = Math.Max(0f, secondaryRecoil - .2f);
}
}
}

View File

@@ -54,7 +54,30 @@ namespace OpenRa.Game.Traits
return facing + turn;
}
public static int2 GetTurretPosition(Actor self, int[] offset)
static float2 RotateVectorByFacing(float2 v, int facing, float ecc)
{
var angle = (facing / 256f) * (2 * (float)Math.PI);
var sinAngle = (float)Math.Sin(angle);
var cosAngle = (float)Math.Cos(angle);
return new float2(
(cosAngle * v.X + sinAngle * v.Y),
ecc * (cosAngle * v.Y - sinAngle * v.X));
}
static float2 GetRecoil(Actor self, float recoil)
{
if (self.unitInfo.Recoil == 0) return float2.Zero;
var rut = self.traits.WithInterface<RenderUnitTurreted>().FirstOrDefault();
if (rut == null) return float2.Zero;
var facing = self.traits.Get<Turreted>().turretFacing;
var quantizedFacing = facing - facing % rut.turretAnim.CurrentSequence.Length;
return RotateVectorByFacing(new float2(0, recoil * self.unitInfo.Recoil), quantizedFacing, .7f);
}
public static float2 GetTurretPosition(Actor self, int[] offset, float recoil)
{
var ru = self.traits.WithInterface<RenderUnit>().FirstOrDefault();
if (ru == null) return int2.Zero; /* things that don't have a rotating base don't need the turrets repositioned */
@@ -62,16 +85,7 @@ namespace OpenRa.Game.Traits
var bodyFacing = self.traits.Get<Mobile>().facing;
var quantizedFacing = bodyFacing - bodyFacing % ru.anim.CurrentSequence.Length;
var angle = (quantizedFacing / 256f) * (2 * (float)Math.PI);
var sinAngle = Math.Sin(angle);
var cosAngle = Math.Cos(angle);
var pos = new int2(
(int)(cosAngle * offset[0] + sinAngle * offset[1]),
(int)(cosAngle * offset[1] - sinAngle * offset[0]));
pos.Y = (int)(.7f * pos.Y);
return pos;
return (RotateVectorByFacing(new float2(offset[0], offset[1]), quantizedFacing, .7f) + GetRecoil(self, recoil));
}
}

View File

@@ -19,12 +19,15 @@ Traits=Mobile, RenderUnit
[1TNK]
Description=Light Tank
Traits=Mobile, Turreted, AttackTurreted, RenderUnitTurreted
Recoil=2;
[2TNK]
Description=Medium Tank
Traits=Mobile, Turreted, AttackTurreted, RenderUnitTurreted
Recoil=3;
[3TNK]
Description=Heavy Tank
Traits=Mobile, Turreted, AttackTurreted, RenderUnitTurreted
Recoil=3;
[4TNK]
Description=Mammoth Tank
Traits=Mobile, Turreted, AttackTurreted, RenderUnitTurreted
@@ -81,6 +84,7 @@ BuiltAt=syrd
Traits=Mobile, Turreted, RenderUnitTurreted, AttackTurreted
PrimaryOffset=0,17
SecondaryOffset=0,-17
Recoil=3
[LST]
Description=Transport
WaterBound=yes