Gate weapon fire on the shooter's own stance, shared by player and AI
Weapon.StanceAllowsFire is the one shared gate: true with no target, else the shooter's own Entity.IsHostileTo(Target) -- not the target's stance toward the shooter. It lives on the Weapon base class so every weapon subtype and every caller (player input, TurretController, AI) goes through the same rule. Wired at the two places weapons actually start dealing damage: - InstantWeapon.Trigger (the base for InstantWeapon, AutoWeapon, ChargedWeapon and LockWeapon/Launcher, all of which route real firing through Trigger). - ConstantWeapon.Execute's continuous-beam loop, which stops firing (and raises OnStopFiring) the moment the shooter's stance disallows it. Also fixes LockWeapon's lock-building condition, which read the wrong direction (target.IsHostileTo(shooter) instead of shooter.IsHostileTo(target)) -- the same backwards check as the HUD lock indicator, fixed alongside this in ActionGameManager. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
2b33550cc1
commit
a351009956
4 changed files with 17 additions and 2 deletions
|
|
@ -75,6 +75,13 @@ public class ConstantWeapon : Weapon, IProgressBehavior, IEventBehavior
|
|||
public override bool Execute(float dt)
|
||||
{
|
||||
base.Execute(dt);
|
||||
if (_firing && !StanceAllowsFire)
|
||||
{
|
||||
// Safed: shooter has a target and hasn't declared hostility toward it.
|
||||
_firing = false;
|
||||
OnStopFiring?.Invoke();
|
||||
return false;
|
||||
}
|
||||
if (_firing)
|
||||
{
|
||||
if (!Entity.TryConsumeEnergy(Evaluate(_data.Energy) * dt))
|
||||
|
|
|
|||
|
|
@ -90,6 +90,9 @@ public class InstantWeapon : Weapon, IProgressBehavior, IEventBehavior
|
|||
|
||||
protected void Trigger()
|
||||
{
|
||||
// Safed: shooter has a target and hasn't declared hostility toward it.
|
||||
if (!StanceAllowsFire) return;
|
||||
|
||||
// If 1 ammo is consumed per burst, perform ammo and energy consumption here
|
||||
// UseAmmo returns false when triggering reload; cancel firing if that is the case
|
||||
if(_data.SingleAmmoBurst && (!Entity.TryConsumeEnergy(Energy) || !UseAmmo())) return;
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ public class LockWeapon : InstantWeapon
|
|||
_target = Entity.Target.Value;
|
||||
}
|
||||
|
||||
if (Entity.Target.Value != null && Entity.Target.Value.IsHostileTo(Entity))
|
||||
if (Entity.Target.Value != null && Entity.IsHostileTo(Entity.Target.Value))
|
||||
{
|
||||
LockSpeed = Evaluate(_data.LockSpeed);
|
||||
SensorImpact = Evaluate(_data.SensorImpact);
|
||||
|
|
|
|||
|
|
@ -94,7 +94,12 @@ public abstract class Weapon : Behavior, IActivatedBehavior
|
|||
{
|
||||
get => _firing;
|
||||
}
|
||||
|
||||
|
||||
// Single shared fire gate for player and AI shooters alike: weapons are safed by the
|
||||
// shooter's OWN declared stance toward its target, not the target's stance toward the shooter.
|
||||
// With no target set, behaviour is unchanged (nothing to be safe about).
|
||||
public bool StanceAllowsFire => Entity.Target.Value == null || Entity.IsHostileTo(Entity.Target.Value);
|
||||
|
||||
public Weapon(WeaponData data, EquippedItem item) : base(data, item)
|
||||
{
|
||||
_data = data;
|
||||
|
|
|
|||
Loading…
Reference in a new issue