fix(items): use retail cylinder range for loot windows
Keep external-container visibility tied to the signed surface gap between the player and container physics cylinders, matching gmExternalContainerUI's authored UseRadius range watcher. This prevents a valid ViewContents response from being closed at ACE's natural approach endpoint. Port Position::cylinder_distance and ACCWeenieObject::ObjectsInRange into Core with conformance coverage for 3-D separation, overlap, mode precedence, and inclusive boundaries. Release build succeeds and all 5,895 tests pass with five intentional skips. Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
e6dd8bf6fa
commit
0f82a08f0a
6 changed files with 199 additions and 50 deletions
|
|
@ -13529,6 +13529,7 @@ public sealed class GameWindow : IDisposable
|
|||
private bool IsWithinExternalContainerUseRange(uint targetGuid)
|
||||
{
|
||||
if (_playerController is null
|
||||
|| !_entitiesByServerGuid.TryGetValue(_playerServerGuid, out var playerEntity)
|
||||
|| !_visibleEntitiesByServerGuid.TryGetValue(targetGuid, out var entity))
|
||||
{
|
||||
// The server remains authoritative for forced close. An entity can be
|
||||
|
|
@ -13540,10 +13541,24 @@ public sealed class GameWindow : IDisposable
|
|||
if (!LastSpawns.TryGetValue(targetGuid, out var spawn)
|
||||
|| spawn.UseRadius is not > 0f)
|
||||
return true;
|
||||
float useRadius = spawn.UseRadius.Value;
|
||||
float dx = entity.Position.X - _playerController.Position.X;
|
||||
float dy = entity.Position.Y - _playerController.Position.Y;
|
||||
return dx * dx + dy * dy <= useRadius * useRadius;
|
||||
|
||||
// gmExternalContainerUI::SetGroundObject @ 0x004CBBD0 registers the
|
||||
// root's UseRadius with useRadii=true and ignoreZDelta=false.
|
||||
// CPlayerSystem::CalculateObjectRangeChecks @ 0x0055F360 then calls
|
||||
// ACCWeenieObject::ObjectsInRange @ 0x0058C1A0, whose use-radii branch
|
||||
// compares the gap between both physics cylinders, not their centers.
|
||||
var playerCylinder = GetSetupCylinder(_playerServerGuid, playerEntity);
|
||||
var targetCylinder = GetSetupCylinder(targetGuid, entity);
|
||||
return AcDream.Core.Physics.ObjectRangeMath.ObjectsInRange(
|
||||
_playerController.Position,
|
||||
playerCylinder.Radius,
|
||||
playerCylinder.Height,
|
||||
entity.Position,
|
||||
targetCylinder.Radius,
|
||||
targetCylinder.Height,
|
||||
spawn.UseRadius.Value,
|
||||
useRadii: true,
|
||||
ignoreZDelta: false);
|
||||
}
|
||||
|
||||
private void InstallSpeculativeTurnToTarget(uint targetGuid)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue