Fix Armament not working properly with value 0 in BurstDelays

This commit is contained in:
Gustas
2023-02-17 20:49:25 +02:00
committed by Matthias Mailänder
parent b7e0ed9b87
commit 4dec79a5fb
6 changed files with 24 additions and 34 deletions

View File

@@ -255,7 +255,7 @@ namespace OpenRA.Mods.Common.Activities
{ {
if (!attack.IsTraitPaused) if (!attack.IsTraitPaused)
foreach (var a in armaments) foreach (var a in armaments)
a.CheckFire(self, facing, target); a.CheckFire(self, facing, target, false);
} }
void IActivityNotifyStanceChanged.StanceChanged(Actor self, AutoTarget autoTarget, UnitStance oldStance, UnitStance newStance) void IActivityNotifyStanceChanged.StanceChanged(Actor self, AutoTarget autoTarget, UnitStance oldStance, UnitStance newStance)

View File

@@ -65,7 +65,7 @@ namespace OpenRA.Mods.Common.Traits
continue; continue;
inAttackRange = true; inAttackRange = true;
a.CheckFire(self, facing, target); a.CheckFire(self, facing, target, false);
} }
// Actors without armaments may want to trigger an action when it passes the target // Actors without armaments may want to trigger an action when it passes the target

View File

@@ -101,6 +101,9 @@ namespace OpenRA.Mods.Common.Traits
if (WeaponInfo.Burst > 1 && WeaponInfo.BurstDelays.Length > 1 && (WeaponInfo.BurstDelays.Length != WeaponInfo.Burst - 1)) if (WeaponInfo.Burst > 1 && WeaponInfo.BurstDelays.Length > 1 && (WeaponInfo.BurstDelays.Length != WeaponInfo.Burst - 1))
throw new YamlException($"Weapon '{weaponToLower}' has an invalid number of BurstDelays, must be single entry or Burst - 1."); throw new YamlException($"Weapon '{weaponToLower}' has an invalid number of BurstDelays, must be single entry or Burst - 1.");
if (WeaponInfo.ReloadDelay <= 0)
throw new YamlException($"Weapon '{weaponToLower}' ReloadDelay value must not be equal to or lower than 0");
base.RulesetLoaded(rules, ai); base.RulesetLoaded(rules, ai);
} }
} }
@@ -251,26 +254,32 @@ namespace OpenRA.Mods.Common.Traits
// Note: facing is only used by the legacy positioning code // Note: facing is only used by the legacy positioning code
// The world coordinate model uses Actor.Orientation // The world coordinate model uses Actor.Orientation
public virtual Barrel CheckFire(Actor self, IFacing facing, in Target target) public virtual bool CheckFire(Actor self, IFacing facing, in Target target, bool notifyAttacking)
{ {
if (!CanFire(self, target)) if (!CanFire(self, target))
return null; return false;
if (ticksSinceLastShot >= Weapon.ReloadDelay) if (ticksSinceLastShot >= Weapon.ReloadDelay)
Burst = Weapon.Burst; Burst = Weapon.Burst;
ticksSinceLastShot = 0; ticksSinceLastShot = 0;
do
{
// If Weapon.Burst == 1, cycle through all LocalOffsets, otherwise use the offset corresponding to current Burst
currentBarrel %= barrelCount;
var barrel = Weapon.Burst == 1 ? Barrels[currentBarrel] : Barrels[Burst % Barrels.Length];
currentBarrel++;
// If Weapon.Burst == 1, cycle through all LocalOffsets, otherwise use the offset corresponding to current Burst FireBarrel(self, facing, target, barrel);
currentBarrel %= barrelCount; UpdateBurst(self, target);
var barrel = Weapon.Burst == 1 ? Barrels[currentBarrel] : Barrels[Burst % Barrels.Length];
currentBarrel++;
FireBarrel(self, facing, target, barrel); if (notifyAttacking)
foreach (var notify in notifyAttacks)
notify.Attacking(self, target, this, barrel);
}
while (FireDelay == 0 && CanFire(self, target));
UpdateBurst(self, target); return true;
return barrel;
} }
protected virtual void FireBarrel(Actor self, IFacing facing, in Target target, Barrel barrel) protected virtual void FireBarrel(Actor self, IFacing facing, in Target target, Barrel barrel)

View File

@@ -166,7 +166,7 @@ namespace OpenRA.Mods.Common.Traits
return; return;
foreach (var a in Armaments) foreach (var a in Armaments)
a.CheckFire(self, facing, target); a.CheckFire(self, facing, target, false);
} }
IEnumerable<IOrderTargeter> IIssueOrder.Orders IEnumerable<IOrderTargeter> IIssueOrder.Orders

View File

@@ -78,7 +78,6 @@ namespace OpenRA.Mods.Common.Traits
public class AttackGarrisoned : AttackFollow, INotifyPassengerEntered, INotifyPassengerExited, IRender public class AttackGarrisoned : AttackFollow, INotifyPassengerEntered, INotifyPassengerExited, IRender
{ {
public new readonly AttackGarrisonedInfo Info; public new readonly AttackGarrisonedInfo Info;
INotifyAttack[] notifyAttacks;
readonly Lazy<BodyOrientation> coords; readonly Lazy<BodyOrientation> coords;
readonly List<Armament> armaments; readonly List<Armament> armaments;
readonly List<AnimationWithOffset> muzzles; readonly List<AnimationWithOffset> muzzles;
@@ -98,12 +97,6 @@ namespace OpenRA.Mods.Common.Traits
paxRender = new Dictionary<Actor, RenderSprites>(); paxRender = new Dictionary<Actor, RenderSprites>();
} }
protected override void Created(Actor self)
{
notifyAttacks = self.TraitsImplementing<INotifyAttack>().ToArray();
base.Created(self);
}
protected override Func<IEnumerable<Armament>> InitializeGetArmaments(Actor self) protected override Func<IEnumerable<Armament>> InitializeGetArmaments(Actor self)
{ {
return () => armaments; return () => armaments;
@@ -171,8 +164,7 @@ namespace OpenRA.Mods.Common.Traits
paxFacing[a.Actor].Facing = targetYaw; paxFacing[a.Actor].Facing = targetYaw;
paxPos[a.Actor].SetCenterPosition(a.Actor, pos + PortOffset(self, port)); paxPos[a.Actor].SetCenterPosition(a.Actor, pos + PortOffset(self, port));
var barrel = a.CheckFire(a.Actor, facing, target); if (!a.CheckFire(a.Actor, facing, target, true))
if (barrel == null)
continue; continue;
if (a.Info.MuzzleSequence != null) if (a.Info.MuzzleSequence != null)
@@ -188,9 +180,6 @@ namespace OpenRA.Mods.Common.Traits
muzzles.Add(muzzleFlash); muzzles.Add(muzzleFlash);
muzzleAnim.PlayThen(sequence, () => muzzles.Remove(muzzleFlash)); muzzleAnim.PlayThen(sequence, () => muzzles.Remove(muzzleFlash));
} }
foreach (var npa in notifyAttacks)
npa.Attacking(self, target, a, barrel);
} }
} }

View File

@@ -85,15 +85,7 @@ namespace OpenRA.Mods.D2k.Activities
if (affectedPlayers.Contains(self.World.LocalPlayer)) if (affectedPlayers.Contains(self.World.LocalPlayer))
TextNotificationsManager.AddTransientLine(self.World.LocalPlayer, swallow.Info.WormAttackTextNotification); TextNotificationsManager.AddTransientLine(self.World.LocalPlayer, swallow.Info.WormAttackTextNotification);
var barrel = armament.CheckFire(self, facing, target); return armament.CheckFire(self, facing, target, true);
if (barrel == null)
return false;
// armament.CheckFire already calls INotifyAttack.PreparingAttack
foreach (var notify in self.TraitsImplementing<INotifyAttack>())
notify.Attacking(self, target, armament, barrel);
return true;
} }
public override bool Tick(Actor self) public override bool Tick(Actor self)