feat(vfx): port retail hidden and teleport presentation
Preserve canonical live-object ownership across Hidden transitions and remote teleport placement so effects, collision, streaming, and targeting remain synchronized.
This commit is contained in:
parent
a51ebc66e9
commit
1e98d81448
46 changed files with 4883 additions and 127 deletions
65
tests/AcDream.App.Tests/Rendering/EntityPhysicsHostTests.cs
Normal file
65
tests/AcDream.App.Tests/Rendering/EntityPhysicsHostTests.cs
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
using System.Numerics;
|
||||
using AcDream.App.Rendering;
|
||||
using AcDream.Core.Physics;
|
||||
using AcDream.Core.Physics.Motion;
|
||||
|
||||
namespace AcDream.App.Tests.Rendering;
|
||||
|
||||
public sealed class EntityPhysicsHostTests
|
||||
{
|
||||
[Fact]
|
||||
public void NotifyHidden_FansNonOkStatusAndClearsWatcherSubscription()
|
||||
{
|
||||
const uint watcherId = 0x50000001u;
|
||||
const uint targetId = 0x70000001u;
|
||||
var hosts = new Dictionary<uint, IPhysicsObjHost>();
|
||||
var watcherUpdates = new List<TargetInfo>();
|
||||
|
||||
EntityPhysicsHost watcher = CreateHost(
|
||||
watcherId,
|
||||
hosts,
|
||||
watcherUpdates.Add);
|
||||
EntityPhysicsHost target = CreateHost(targetId, hosts, _ => { });
|
||||
hosts.Add(watcherId, watcher);
|
||||
hosts.Add(targetId, target);
|
||||
watcher.SetTarget(0u, targetId, 1f, 0.1);
|
||||
watcherUpdates.Clear();
|
||||
|
||||
target.NotifyHidden();
|
||||
|
||||
TargetInfo hidden = Assert.Single(watcherUpdates);
|
||||
Assert.Equal(TargetStatus.ExitWorld, hidden.Status);
|
||||
Assert.Null(watcher.TargetManager.TargetInfo);
|
||||
Assert.False(target.TargetManager.VoyeurTable!.ContainsKey(watcherId));
|
||||
|
||||
watcherUpdates.Clear();
|
||||
watcher.SetTarget(0u, targetId, 1f, 0.1);
|
||||
|
||||
TargetInfo restored = Assert.Single(watcherUpdates);
|
||||
Assert.Equal(TargetStatus.Ok, restored.Status);
|
||||
Assert.Equal(targetId, restored.ObjectId);
|
||||
Assert.True(target.TargetManager.VoyeurTable.ContainsKey(watcherId));
|
||||
}
|
||||
|
||||
private static EntityPhysicsHost CreateHost(
|
||||
uint id,
|
||||
IReadOnlyDictionary<uint, IPhysicsObjHost> hosts,
|
||||
Action<TargetInfo> update)
|
||||
{
|
||||
return new EntityPhysicsHost(
|
||||
id,
|
||||
getPosition: () => new Position(
|
||||
0x01010001u,
|
||||
new Vector3(id == 0x50000001u ? 0f : 2f, 0f, 0f),
|
||||
Quaternion.Identity),
|
||||
getVelocity: () => Vector3.Zero,
|
||||
getRadius: () => 0.5f,
|
||||
inContact: () => true,
|
||||
minterpMaxSpeed: () => 1f,
|
||||
curTime: () => 1.0,
|
||||
physicsTimerTime: () => 1.0,
|
||||
getObjectA: objectId => hosts.GetValueOrDefault(objectId),
|
||||
handleUpdateTarget: update,
|
||||
interruptCurrentMovement: () => { });
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue