From d4bec37c6a6948c922a0f1c3a27242014591697d Mon Sep 17 00:00:00 2001 From: soul Date: Fri, 23 Oct 2026 13:34:18 +0200 Subject: [PATCH] Combat's release sweep leaves a weapon it already commanded alone: PilotCommand.Commands One command per weapon per step: the sweep released a gun the group loop had already released. Co-Authored-By: Claude Sonnet 5.5 --- Assets/Scripts/ServerShared/Agents/States/Combat.cs | 6 +++--- Assets/Scripts/ServerShared/Pilot.cs | 8 ++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Assets/Scripts/ServerShared/Agents/States/Combat.cs b/Assets/Scripts/ServerShared/Agents/States/Combat.cs index 045778f4e..7ee302dbd 100644 --- a/Assets/Scripts/ServerShared/Agents/States/Combat.cs +++ b/Assets/Scripts/ServerShared/Agents/States/Combat.cs @@ -163,14 +163,14 @@ public class CombatState : BaseState public override void OnExitState() => ReleaseUnwanted(); - // The AI's trigger level for an AutoWeapon is what it pulls this step: the weapon holds a down trigger until it is - // released, so every held one this step does not pull is let go, whether the target is gone, untracked, out of reach, + // The AI's trigger level for an AutoWeapon is what it commands this step: the weapon holds a down trigger until it is + // released, so every held one this step has no command for is let go, whether the target is gone, untracked, out of reach, // its group is not the pick, or Combat has ended. A plain gun is tapped and lets go of itself. private void ReleaseUnwanted() { var command = _agent.Ship.Command; foreach (var weapon in _agent.Ship.Weapons) - if (weapon is AutoWeapon && weapon.Firing && !command.Pulls(weapon)) command.Release(weapon); + if (weapon is AutoWeapon && weapon.Firing && !command.Commands(weapon)) command.Release(weapon); } // Overdrive to close a distant target ahead, through the same consumable gate as the vent (Agent.VentOnTrack). diff --git a/Assets/Scripts/ServerShared/Pilot.cs b/Assets/Scripts/ServerShared/Pilot.cs index dcfa655ae..0ef20f96c 100644 --- a/Assets/Scripts/ServerShared/Pilot.cs +++ b/Assets/Scripts/ServerShared/Pilot.cs @@ -94,6 +94,14 @@ public sealed class PilotCommand // The pilot's own pending decisions, which it reads back instead of the ship (that is last step's applied state). public TargetRef? Designated => Designations.Count > 0 ? Designations[Designations.Count - 1] : (TargetRef?) null; + // Whether this pilot has commanded a trigger, pull or release, for `behavior` this step. + public bool Commands(ActivatedBehavior behavior) + { + foreach (var trigger in Triggers) + if (ReferenceEquals(trigger.Behavior, behavior)) return true; + return false; + } + // Whether the last trigger this pilot commanded for `behavior` this step is a pull. public bool Pulls(ActivatedBehavior behavior) {