fix(interaction): bind selection to live incarnations

Carry local WorldEntity identity through render hits, lighting pulses, and deferred movement actions so GUID reuse cannot target a replacement. Reset all session-owned selection and ItemHolder state and prevent combat auto-target during teardown.
This commit is contained in:
Erik 2026-07-21 07:07:58 +02:00
parent c271383714
commit 047a4c83b5
19 changed files with 374 additions and 42 deletions

View file

@ -27,6 +27,7 @@ internal sealed class RetailSelectionLightingPulse
private readonly Func<double> _now;
private uint _serverGuid;
private uint _localEntityId;
private int _flipCount;
private double _nextFlip;
private RetailSelectionLighting _lighting;
@ -34,15 +35,16 @@ internal sealed class RetailSelectionLightingPulse
public RetailSelectionLightingPulse(Func<double>? now = null)
=> _now = now ?? MonotonicSeconds;
public void Start(uint serverGuid)
public void Start(uint serverGuid, uint localEntityId)
{
if (serverGuid == 0u)
if (serverGuid == 0u || localEntityId == 0u)
{
Clear();
return;
}
_serverGuid = serverGuid;
_localEntityId = localEntityId;
_flipCount = 1;
_lighting = RetailSelectionLighting.High;
_nextFlip = _now() + FlipIntervalSeconds;
@ -76,9 +78,16 @@ internal sealed class RetailSelectionLightingPulse
_nextFlip = now + FlipIntervalSeconds;
}
public bool TryGet(uint serverGuid, out RetailSelectionLighting lighting)
public bool TryGet(
uint serverGuid,
uint localEntityId,
out RetailSelectionLighting lighting)
{
if (_flipCount != 0 && serverGuid != 0u && serverGuid == _serverGuid)
if (_flipCount != 0
&& serverGuid != 0u
&& localEntityId != 0u
&& serverGuid == _serverGuid
&& localEntityId == _localEntityId)
{
lighting = _lighting;
return true;
@ -91,6 +100,7 @@ internal sealed class RetailSelectionLightingPulse
public void Clear()
{
_serverGuid = 0u;
_localEntityId = 0u;
_flipCount = 0;
_nextFlip = 0d;
_lighting = default;