introduce collection of Turrets on AttackBase, too -- turret sharing w/ recoil works again
This commit is contained in:
@@ -37,22 +37,33 @@ namespace OpenRA.Mods.RA
|
||||
}
|
||||
|
||||
public class Barrel { public int2 Position; public int Facing; /* relative to turret */ }
|
||||
public class Turret
|
||||
{
|
||||
public float Recoil = 0.0f; // remaining recoil fraction
|
||||
public int2 UnitSpacePosition; // where, in the unit's local space.
|
||||
public int2 ScreenSpacePosition; // screen-space hack to make things line up good.
|
||||
|
||||
public Turret(int[] offset)
|
||||
{
|
||||
ScreenSpacePosition = offset.AbsOffset().ToInt2();
|
||||
UnitSpacePosition = offset.RelOffset().ToInt2();
|
||||
}
|
||||
}
|
||||
|
||||
public class Weapon
|
||||
{
|
||||
public WeaponInfo Info;
|
||||
public int FireDelay = 0; // time (in frames) until the weapon can fire again
|
||||
public int Burst = 0; // burst counter
|
||||
public float Recoil = 0.0f; // remaining recoil fraction
|
||||
|
||||
public int[] Offset;
|
||||
public Barrel[] Barrels;
|
||||
public Barrel[] Barrels; // where projectiles are spawned, in local turret space.
|
||||
public Turret Turret; // where this weapon is mounted
|
||||
|
||||
public Weapon(string weaponName, int[] offset, int[] localOffset)
|
||||
public Weapon(string weaponName, Turret turret, int[] localOffset)
|
||||
{
|
||||
Info = Rules.Weapons[weaponName.ToLowerInvariant()];
|
||||
Burst = Info.Burst;
|
||||
Offset = offset;
|
||||
Turret = turret;
|
||||
|
||||
var barrels = new List<Barrel>();
|
||||
for (var i = 0; i < localOffset.Length / 3; i++)
|
||||
@@ -74,13 +85,26 @@ namespace OpenRA.Mods.RA
|
||||
public void Tick()
|
||||
{
|
||||
if (FireDelay > 0) --FireDelay;
|
||||
Recoil = Math.Max(0f, Recoil - .2f);
|
||||
Turret.Recoil = Math.Max(0f, Turret.Recoil - .2f);
|
||||
}
|
||||
|
||||
public bool IsValidAgainst(Target target)
|
||||
{
|
||||
return Combat.WeaponValidForTarget(Info, target);
|
||||
}
|
||||
|
||||
public void FiredShot()
|
||||
{
|
||||
Turret.Recoil = 1;
|
||||
|
||||
if (--Burst > 0)
|
||||
FireDelay = Info.BurstDelay;
|
||||
else
|
||||
{
|
||||
FireDelay = Info.ROF;
|
||||
Burst = Info.Burst;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class AttackBase : IIssueOrder, IResolveOrder, ITick, IExplodeModifier, IOrderCursor, IOrderVoice
|
||||
@@ -88,18 +112,23 @@ namespace OpenRA.Mods.RA
|
||||
public Target target;
|
||||
|
||||
public List<Weapon> Weapons = new List<Weapon>();
|
||||
public List<Turret> Turrets = new List<Turret>();
|
||||
|
||||
public AttackBase(Actor self)
|
||||
{
|
||||
var info = self.Info.Traits.Get<AttackBaseInfo>();
|
||||
|
||||
Turrets.Add(new Turret(info.PrimaryOffset));
|
||||
if (info.SecondaryOffset != null)
|
||||
Turrets.Add(new Turret(info.SecondaryOffset));
|
||||
|
||||
if (info.PrimaryWeapon != null)
|
||||
Weapons.Add(new Weapon(info.PrimaryWeapon,
|
||||
info.PrimaryOffset, info.PrimaryLocalOffset));
|
||||
Turrets[0], info.PrimaryLocalOffset));
|
||||
|
||||
if (info.SecondaryWeapon != null)
|
||||
Weapons.Add(new Weapon(info.SecondaryWeapon,
|
||||
info.SecondaryOffset ?? info.PrimaryOffset, info.SecondaryLocalOffset));
|
||||
info.SecondaryOffset != null ? Turrets[1] : Turrets[0], info.SecondaryLocalOffset));
|
||||
}
|
||||
|
||||
protected virtual bool CanAttack(Actor self)
|
||||
@@ -149,7 +178,7 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
foreach (var w in Weapons)
|
||||
if (CheckFire(self, unit, w))
|
||||
w.Recoil = 1;
|
||||
w.FiredShot();
|
||||
}
|
||||
|
||||
bool CheckFire(Actor self, Unit unit, Weapon w)
|
||||
@@ -168,18 +197,10 @@ namespace OpenRA.Mods.RA
|
||||
var barrel = w.Barrels[w.Burst % w.Barrels.Length];
|
||||
|
||||
var fireOffset = new[] {
|
||||
w.Offset.ElementAtOrDefault(0) + barrel.Position.X,
|
||||
w.Offset.ElementAtOrDefault(1) + barrel.Position.Y,
|
||||
w.Offset.ElementAtOrDefault(2),
|
||||
w.Offset.ElementAtOrDefault(3) };
|
||||
|
||||
if (--w.Burst > 0)
|
||||
w.FireDelay = w.Info.BurstDelay;
|
||||
else
|
||||
{
|
||||
w.FireDelay = w.Info.ROF;
|
||||
w.Burst = w.Info.Burst;
|
||||
}
|
||||
w.Turret.UnitSpacePosition.X + barrel.Position.X,
|
||||
w.Turret.UnitSpacePosition.Y + barrel.Position.Y,
|
||||
w.Turret.ScreenSpacePosition.X,
|
||||
w.Turret.ScreenSpacePosition.Y }; // todo: retardage.
|
||||
|
||||
var destUnit = target.IsActor ? target.Actor.traits.GetOrDefault<Unit>() : null;
|
||||
|
||||
@@ -310,10 +331,6 @@ namespace OpenRA.Mods.RA
|
||||
Math.Max(0, (int)weapon.Info.Range)));
|
||||
}
|
||||
|
||||
/* temp hack */
|
||||
public float GetPrimaryRecoil() { return Weapons.Count > 0 ? Weapons[0].Recoil : 0; }
|
||||
public float GetSecondaryRecoil() { return Weapons.Count > 1 ? Weapons[1].Recoil : 0; }
|
||||
|
||||
public bool HasAnyValidWeapons(Target t) { return Weapons.Any(w => w.IsValidAgainst(t)); }
|
||||
public float GetMaximumRange() { return Weapons.Max(w => w.Info.Range); }
|
||||
|
||||
|
||||
@@ -202,5 +202,18 @@ namespace OpenRA.Mods.RA
|
||||
return (Util.RotateVectorByFacing(offset.RelOffset(), quantizedFacing, .7f) + GetRecoil(self, recoil))
|
||||
+ offset.AbsOffset();
|
||||
}
|
||||
|
||||
public static float2 GetTurretPosition(Actor self, Unit unit, Turret turret)
|
||||
{
|
||||
if (unit == null) return turret.ScreenSpacePosition;
|
||||
|
||||
var ru = self.traits.GetOrDefault<RenderUnit>();
|
||||
var numDirs = (ru != null) ? ru.anim.CurrentSequence.Facings : 8;
|
||||
var bodyFacing = unit.Facing;
|
||||
var quantizedFacing = Util.QuantizeFacing(bodyFacing, numDirs) * (256 / numDirs);
|
||||
|
||||
return (Util.RotateVectorByFacing(turret.UnitSpacePosition, quantizedFacing, .7f) + GetRecoil(self, turret.Recoil))
|
||||
+ turret.ScreenSpacePosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,27 +31,24 @@ namespace OpenRA.Mods.RA.Render
|
||||
var turretAnim = new Animation(GetImage(self), () => turreted.turretFacing );
|
||||
turretAnim.Play( "turret" );
|
||||
|
||||
if( attackInfo.PrimaryOffset != null )
|
||||
anims.Add("turret_1", new AnimationWithOffset(
|
||||
turretAnim,
|
||||
() => Combat.GetTurretPosition(self, unit, attackInfo.PrimaryOffset, attack.GetPrimaryRecoil()),
|
||||
null) { ZOffset = 1 });
|
||||
|
||||
if (attackInfo.SecondaryOffset != null)
|
||||
anims.Add("turret_2", new AnimationWithOffset(
|
||||
turretAnim,
|
||||
() => Combat.GetTurretPosition(self, unit, attackInfo.SecondaryOffset, attack.GetSecondaryRecoil()),
|
||||
for( var i = 0; i < attack.Turrets.Count; i++ )
|
||||
{
|
||||
var turret = attack.Turrets[i];
|
||||
anims.Add( "turret_{0}".F(i),
|
||||
new AnimationWithOffset( turretAnim,
|
||||
() => Combat.GetTurretPosition( self, unit, turret ),
|
||||
null) { ZOffset = 1 });
|
||||
|
||||
if (attackInfo.MuzzleFlash)
|
||||
{
|
||||
var muzzleFlash = new Animation( GetImage(self), () => self.traits.Get<Turreted>().turretFacing );
|
||||
var muzzleFlash = new Animation(GetImage(self), () => turreted.turretFacing);
|
||||
muzzleFlash.PlayFetchIndex("muzzle",
|
||||
() => (int)(attack.GetPrimaryRecoil() * 5.9f)); /* hack: recoil can be 1.0f, but don't overflow into next anim */
|
||||
anims.Add( "muzzle_flash", new AnimationWithOffset(
|
||||
muzzleFlash,
|
||||
() => Combat.GetTurretPosition(self, unit, attackInfo.PrimaryOffset, attack.GetPrimaryRecoil()),
|
||||
() => attack.GetPrimaryRecoil() <= 0));
|
||||
() => (int)(turret.Recoil * 5.9f)); /* hack: dumb crap */
|
||||
anims.Add("muzzle_flash_{0}".F(i),
|
||||
new AnimationWithOffset(muzzleFlash,
|
||||
() => Combat.GetTurretPosition(self, unit, turret),
|
||||
() => turret.Recoil <= 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user