start refactoring AttackBase

This commit is contained in:
Chris Forbes
2010-07-31 14:06:38 +12:00
parent 2478b26a05
commit 42683f5966
3 changed files with 59 additions and 50 deletions

View File

@@ -36,34 +36,56 @@ namespace OpenRA.Mods.RA
public virtual object Create(ActorInitializer init) { return new AttackBase(init.self); } public virtual object Create(ActorInitializer init) { return new AttackBase(init.self); }
} }
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 int[] LocalOffset;
public Weapon(WeaponInfo info, int[] offset, int[] localOffset)
{
Info = info;
Burst = info.Burst;
Offset = offset;
LocalOffset = localOffset;
}
public bool IsReloading { get { return FireDelay > 0; } }
public void Tick()
{
if (FireDelay > 0) --FireDelay;
Recoil = Math.Max(0f, Recoil - .2f);
}
}
public class AttackBase : IIssueOrder, IResolveOrder, ITick, IExplodeModifier, IOrderCursor, IOrderVoice public class AttackBase : IIssueOrder, IResolveOrder, ITick, IExplodeModifier, IOrderCursor, IOrderVoice
{ {
public Target target; public Target target;
// time (in frames) until each weapon can fire again. public List<Weapon> Weapons = new List<Weapon>();
[Sync]
protected int primaryFireDelay = 0;
[Sync]
protected int secondaryFireDelay = 0;
int primaryBurst;
int secondaryBurst;
public float primaryRecoil = 0.0f, secondaryRecoil = 0.0f;
public AttackBase(Actor self) public AttackBase(Actor self)
{ {
var primaryWeapon = self.GetPrimaryWeapon(); var info = self.Info.Traits.Get<AttackBaseInfo>();
var secondaryWeapon = self.GetSecondaryWeapon();
primaryBurst = primaryWeapon != null ? primaryWeapon.Burst : 1; if (self.GetPrimaryWeapon() != null)
secondaryBurst = secondaryWeapon != null ? secondaryWeapon.Burst : 1; Weapons.Add(new Weapon(self.GetPrimaryWeapon(),
info.PrimaryOffset, info.PrimaryLocalOffset));
if (self.GetSecondaryWeapon() != null)
Weapons.Add(new Weapon(self.GetSecondaryWeapon(),
info.SecondaryOffset ?? info.PrimaryOffset, info.SecondaryLocalOffset));
} }
protected virtual bool CanAttack(Actor self) protected virtual bool CanAttack(Actor self)
{ {
if (!target.IsValid) return false; if (!target.IsValid) return false;
if ((primaryFireDelay > 0) && (secondaryFireDelay > 0)) return false; if (Weapons.All(w => w.IsReloading)) return false;
if (self.traits.WithInterface<IDisable>().Any(d => d.Disabled)) return false; if (self.traits.WithInterface<IDisable>().Any(d => d.Disabled)) return false;
return true; return true;
@@ -71,20 +93,14 @@ namespace OpenRA.Mods.RA
public bool ShouldExplode(Actor self) { return !IsReloading(); } public bool ShouldExplode(Actor self) { return !IsReloading(); }
public bool IsReloading() public bool IsReloading() { return Weapons.Any(w => w.IsReloading); }
{
return (primaryFireDelay > 0) || (secondaryFireDelay > 0);
}
List<Pair<int, Action>> delayedActions = new List<Pair<int, Action>>(); List<Pair<int, Action>> delayedActions = new List<Pair<int, Action>>();
public virtual void Tick(Actor self) public virtual void Tick(Actor self)
{ {
if (primaryFireDelay > 0) --primaryFireDelay; foreach (var w in Weapons)
if (secondaryFireDelay > 0) --secondaryFireDelay; w.Tick();
primaryRecoil = Math.Max(0f, primaryRecoil - .2f);
secondaryRecoil = Math.Max(0f, secondaryRecoil - .2f);
for (var i = 0; i < delayedActions.Count; i++) for (var i = 0; i < delayedActions.Count; i++)
{ {
@@ -111,23 +127,12 @@ namespace OpenRA.Mods.RA
var unit = self.traits.GetOrDefault<Unit>(); var unit = self.traits.GetOrDefault<Unit>();
var info = self.Info.Traits.Get<AttackBaseInfo>(); var info = self.Info.Traits.Get<AttackBaseInfo>();
if (info.PrimaryWeapon != null && CheckFire(self, unit, info.PrimaryWeapon, ref primaryFireDelay, foreach (var w in Weapons)
info.PrimaryOffset, ref primaryBurst, info.PrimaryLocalOffset)) if (CheckFire(self, unit, w.Info, ref w.FireDelay, w.Offset, ref w.Burst, w.LocalOffset))
{ w.Recoil = 1;
primaryRecoil = 1;
return;
}
if (info.SecondaryWeapon != null && CheckFire(self, unit, info.SecondaryWeapon, ref secondaryFireDelay,
info.SecondaryOffset ?? info.PrimaryOffset, ref secondaryBurst, info.SecondaryLocalOffset))
{
if (info.SecondaryOffset != null) secondaryRecoil = 1;
else primaryRecoil = 1;
return;
}
} }
bool CheckFire(Actor self, Unit unit, string weaponName, ref int fireDelay, int[] offset, ref int burst, int[] localOffset) bool CheckFire(Actor self, Unit unit, WeaponInfo weapon, ref int fireDelay, int[] offset, ref int burst, int[] localOffset)
{ {
if (fireDelay > 0) return false; if (fireDelay > 0) return false;
@@ -135,8 +140,6 @@ namespace OpenRA.Mods.RA
if (limitedAmmo != null && !limitedAmmo.HasAmmo()) if (limitedAmmo != null && !limitedAmmo.HasAmmo())
return false; return false;
var weapon = Rules.Weapons[weaponName.ToLowerInvariant()];
if (weapon.Range * weapon.Range * Game.CellSize * Game.CellSize if (weapon.Range * weapon.Range * Game.CellSize * Game.CellSize
< (target.CenterLocation - self.CenterLocation).LengthSquared) return false; < (target.CenterLocation - self.CenterLocation).LengthSquared) return false;
@@ -165,7 +168,7 @@ namespace OpenRA.Mods.RA
var args = new ProjectileArgs var args = new ProjectileArgs
{ {
weapon = Rules.Weapons[weaponName.ToLowerInvariant()], weapon = weapon,
firedBy = self, firedBy = self,
target = this.target, target = this.target,
@@ -289,5 +292,9 @@ namespace OpenRA.Mods.RA
Target.FromOrder(order), Target.FromOrder(order),
Math.Max(0, (int)weapon.Range))); Math.Max(0, (int)weapon.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; }
} }
} }

View File

@@ -42,8 +42,9 @@ namespace OpenRA.Mods.RA
charges = self.Info.Traits.Get<AttackTeslaInfo>().MaxCharges; charges = self.Info.Traits.Get<AttackTeslaInfo>().MaxCharges;
if( charges <= 0 ) if( charges <= 0 )
{ {
primaryFireDelay = Math.Max( primaryFireDelay, timeToRecharge ); foreach( var w in Weapons )
secondaryFireDelay = Math.Max( secondaryFireDelay, timeToRecharge ); w.FireDelay = Math.Max( w.FireDelay, timeToRecharge );
sameTarget = null; sameTarget = null;
} }
base.Tick( self ); base.Tick( self );
@@ -52,7 +53,8 @@ namespace OpenRA.Mods.RA
Actor sameTarget; Actor sameTarget;
public override int FireDelay( Actor self, AttackBaseInfo info ) public override int FireDelay( Actor self, AttackBaseInfo info )
{ {
primaryFireDelay = 8; foreach( var w in Weapons )
w.FireDelay = 8;
timeToRecharge = self.GetPrimaryWeapon().ROF; timeToRecharge = self.GetPrimaryWeapon().ROF;
--charges; --charges;

View File

@@ -34,24 +34,24 @@ namespace OpenRA.Mods.RA.Render
if( attackInfo.PrimaryOffset != null ) if( attackInfo.PrimaryOffset != null )
anims.Add("turret_1", new AnimationWithOffset( anims.Add("turret_1", new AnimationWithOffset(
turretAnim, turretAnim,
() => Combat.GetTurretPosition(self, unit, attackInfo.PrimaryOffset, attack.primaryRecoil), () => Combat.GetTurretPosition(self, unit, attackInfo.PrimaryOffset, attack.GetPrimaryRecoil()),
null) { ZOffset = 1 }); null) { ZOffset = 1 });
if (attackInfo.SecondaryOffset != null) if (attackInfo.SecondaryOffset != null)
anims.Add("turret_2", new AnimationWithOffset( anims.Add("turret_2", new AnimationWithOffset(
turretAnim, turretAnim,
() => Combat.GetTurretPosition(self, unit, attackInfo.SecondaryOffset, attack.secondaryRecoil), () => Combat.GetTurretPosition(self, unit, attackInfo.SecondaryOffset, attack.GetSecondaryRecoil()),
null) { ZOffset = 1 }); null) { ZOffset = 1 });
if( attackInfo.MuzzleFlash ) if( attackInfo.MuzzleFlash )
{ {
var muzzleFlash = new Animation( GetImage(self), () => self.traits.Get<Turreted>().turretFacing ); var muzzleFlash = new Animation( GetImage(self), () => self.traits.Get<Turreted>().turretFacing );
muzzleFlash.PlayFetchIndex( "muzzle", muzzleFlash.PlayFetchIndex( "muzzle",
() => (int)( attack.primaryRecoil * 5.9f ) ); /* hack: recoil can be 1.0f, but don't overflow into next anim */ () => (int)(attack.GetPrimaryRecoil() * 5.9f)); /* hack: recoil can be 1.0f, but don't overflow into next anim */
anims.Add( "muzzle_flash", new AnimationWithOffset( anims.Add( "muzzle_flash", new AnimationWithOffset(
muzzleFlash, muzzleFlash,
() => Combat.GetTurretPosition(self, unit, attackInfo.PrimaryOffset, attack.primaryRecoil), () => Combat.GetTurretPosition(self, unit, attackInfo.PrimaryOffset, attack.GetPrimaryRecoil()),
() => attack.primaryRecoil <= 0 ) ); () => attack.GetPrimaryRecoil() <= 0));
} }
} }
} }