start refactoring AttackBase
This commit is contained in:
@@ -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; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user