CombatState derives its optimum range once the weapons' stats are known, and re-derives on loadout change
A zone-spawned ship's CombatState sampled in its constructor, before any weapon had evaluated its stats, so the optimum range read 0 and never moved. It now marks the optimum stale on construction, on any equipment add/remove and on a weapon's online change, and samples at the next Update once every active weapon reports StatsKnown. ConsumableAiTests build the agent through Zone.Admit(piloted: true) and read the optimum without re-sampling; new rows pin the hold scope, hull-heading source, mixed paints, sight independence and the optimum across two guns and a refit. Not yet verified. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
2f1f392ecf
commit
bf32a82e32
3 changed files with 166 additions and 29 deletions
|
|
@ -17,20 +17,33 @@ public class CombatState : BaseState
|
|||
private const float OverdriveRangeFactor = 2f;
|
||||
private const float OverdriveArcDegrees = 15f;
|
||||
private float _optimumRange;
|
||||
private bool _optimumStale = true;
|
||||
private readonly List<(int index, float dps)> _availableGroups = new List<(int index, float dps)>();
|
||||
private readonly List<LockWeapon> _availableLockingWeapons = new List<LockWeapon>();
|
||||
|
||||
public CombatState(Agent agent) : base(agent)
|
||||
{
|
||||
SampleDps();
|
||||
foreach (var weapon in _agent.Ship.Weapons)
|
||||
{
|
||||
weapon.Item.Online.Subscribe(b => SampleDps());
|
||||
}
|
||||
foreach (var item in _agent.Ship.Equipment) Watch(item);
|
||||
_agent.Ship.Equipment.ObserveAdd().Subscribe(add => { Watch(add.Value); _optimumStale = true; });
|
||||
_agent.Ship.Equipment.ObserveRemove().Subscribe(_ => _optimumStale = true);
|
||||
}
|
||||
|
||||
// The optimum is a function of the loadout's evaluated stats, so it is re-derived whenever a weapon comes or goes
|
||||
// or changes online state, and only once every weapon that can run has evaluated its stats (a weapon evaluates on
|
||||
// its first active tick, after it comes online): a ship the zone just spawned samples over live stats, not zeros.
|
||||
private void Watch(EquippedItem item)
|
||||
{
|
||||
if (item.Behaviors.OfType<Weapon>().Any()) item.Online.Subscribe(_ => _optimumStale = true);
|
||||
}
|
||||
|
||||
public override void Update(float delta)
|
||||
{
|
||||
if (_optimumStale && _agent.Ship.Weapons.All(w => w.StatsKnown || !w.Item.Active.Value))
|
||||
{
|
||||
SampleDps();
|
||||
_optimumStale = false;
|
||||
}
|
||||
|
||||
var target = _agent.Ship.Target.Value.Entity;
|
||||
if (target == null) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -173,9 +173,13 @@ public abstract class Weapon : Behavior, IActivatedBehavior
|
|||
Tracking = Evaluate(_data.Tracking);
|
||||
}
|
||||
|
||||
// False until the first active tick has evaluated the stats above: before it they all read zero.
|
||||
public bool StatsKnown { get; private set; }
|
||||
|
||||
public override bool Execute(float dt)
|
||||
{
|
||||
UpdateStats();
|
||||
StatsKnown = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue