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
68
tests/AcDream.Core.Tests/Physics/ObjectRangeMathTests.cs
Normal file
68
tests/AcDream.Core.Tests/Physics/ObjectRangeMathTests.cs
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
using System.Numerics;
|
||||
using AcDream.Core.Physics;
|
||||
|
||||
namespace AcDream.Core.Tests.Physics;
|
||||
|
||||
/// <summary>
|
||||
/// Conformance coverage for retail
|
||||
/// <c>ACCWeenieObject::ObjectsInRange @ 0x0058C1A0</c>. The external-container
|
||||
/// registration passes <c>useRadii=true</c> and <c>ignoreZDelta=false</c> at
|
||||
/// <c>gmExternalContainerUI::SetGroundObject @ 0x004CBBD0</c>.
|
||||
/// </summary>
|
||||
public sealed class ObjectRangeMathTests
|
||||
{
|
||||
[Fact]
|
||||
public void ExternalContainerRange_UsesSurfaceGapRatherThanCenterDistance()
|
||||
{
|
||||
var player = new Vector3(7.01f, 98.06f, -0.45f);
|
||||
var corpse = new Vector3(3.73f, 98.03f, -0.44f);
|
||||
|
||||
bool inRange = ObjectRangeMath.ObjectsInRange(
|
||||
player, firstRadius: 0.48f, firstHeight: 1.835f,
|
||||
corpse, secondRadius: 0.80f, secondHeight: 0.50f,
|
||||
range: 2.01,
|
||||
useRadii: true,
|
||||
ignoreZDelta: false);
|
||||
|
||||
Assert.True(inRange);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CenterDistanceMode_DoesNotSubtractObjectRadii()
|
||||
{
|
||||
bool inRange = ObjectRangeMath.ObjectsInRange(
|
||||
Vector3.Zero, firstRadius: 10f, firstHeight: 10f,
|
||||
new Vector3(3f, 0f, 0f), secondRadius: 10f, secondHeight: 10f,
|
||||
range: 2.0,
|
||||
useRadii: false,
|
||||
ignoreZDelta: false);
|
||||
|
||||
Assert.False(inRange);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IgnoreZDelta_UsesXyCenterDistanceAndTakesPrecedenceOverRadii()
|
||||
{
|
||||
bool inRange = ObjectRangeMath.ObjectsInRange(
|
||||
Vector3.Zero, firstRadius: 100f, firstHeight: 100f,
|
||||
new Vector3(3f, 4f, 1000f), secondRadius: 100f, secondHeight: 100f,
|
||||
range: 5.0,
|
||||
useRadii: true,
|
||||
ignoreZDelta: true);
|
||||
|
||||
Assert.True(inRange);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RangeBoundary_IsInclusive()
|
||||
{
|
||||
bool inRange = ObjectRangeMath.ObjectsInRange(
|
||||
Vector3.Zero, firstRadius: 0f, firstHeight: 0f,
|
||||
new Vector3(3f, 4f, 0f), secondRadius: 0f, secondHeight: 0f,
|
||||
range: 5.0,
|
||||
useRadii: false,
|
||||
ignoreZDelta: false);
|
||||
|
||||
Assert.True(inRange);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue