121 lines
5.1 KiB
C#
121 lines
5.1 KiB
C#
using NeonSprawl.Server.Game.PositionState;
|
|
|
|
namespace NeonSprawl.Server.Tests.Game.Npc;
|
|
|
|
public sealed class AggroOperationsTests
|
|
{
|
|
private static InMemoryPositionStateStore CreatePositionStoreAt(double x, double y, double z)
|
|
{
|
|
var store = new InMemoryPositionStateStore(Options.Create(new GamePositionOptions
|
|
{
|
|
DevPlayerId = "dev-local-1",
|
|
DefaultPosition = new DefaultPositionOptions { X = x, Y = y, Z = z },
|
|
}));
|
|
return store;
|
|
}
|
|
|
|
[Fact]
|
|
public void TryAcquire_ShouldSetHolder_WhenRowEmpty()
|
|
{
|
|
// Arrange
|
|
var threatStore = new InMemoryThreatStateStore();
|
|
// Act
|
|
var acquired = AggroOperations.TryAcquire(
|
|
PrototypeNpcRegistry.PrototypeNpcMeleeId,
|
|
"dev-local-1",
|
|
threatStore);
|
|
threatStore.TryGet(PrototypeNpcRegistry.PrototypeNpcMeleeId, out var snapshot);
|
|
// Assert
|
|
Assert.True(acquired);
|
|
Assert.Equal("dev-local-1", snapshot.AggroHolderPlayerId);
|
|
}
|
|
|
|
[Fact]
|
|
public void TryAcquire_ShouldNoOp_WhenHolderAlreadySet()
|
|
{
|
|
// Arrange
|
|
var threatStore = new InMemoryThreatStateStore();
|
|
_ = AggroOperations.TryAcquire(PrototypeNpcRegistry.PrototypeNpcMeleeId, "dev-local-1", threatStore);
|
|
// Act
|
|
var secondAcquire = AggroOperations.TryAcquire(
|
|
PrototypeNpcRegistry.PrototypeNpcMeleeId,
|
|
"dev-local-1",
|
|
threatStore);
|
|
threatStore.TryGet(PrototypeNpcRegistry.PrototypeNpcMeleeId, out var snapshot);
|
|
// Assert
|
|
Assert.False(secondAcquire);
|
|
Assert.Equal("dev-local-1", snapshot.AggroHolderPlayerId);
|
|
}
|
|
|
|
[Fact]
|
|
public void TryClearOnLeashForPlayer_ShouldClearHolder_WhenPlayerBeyondLeashRadius()
|
|
{
|
|
// Arrange
|
|
var behaviorRegistry = PrototypeNpcTestFixtures.CreateBehaviorRegistry();
|
|
var threatStore = new InMemoryThreatStateStore();
|
|
var positions = CreatePositionStoreAt(0, 0, 0);
|
|
_ = AggroOperations.TryAcquire(PrototypeNpcRegistry.PrototypeNpcMeleeId, "dev-local-1", threatStore);
|
|
positions.TryApplyMoveTarget("dev-local-1", 12, 0, 12, out _);
|
|
// Act
|
|
AggroOperations.TryClearOnLeashForPlayer("dev-local-1", positions, behaviorRegistry, threatStore);
|
|
threatStore.TryGet(PrototypeNpcRegistry.PrototypeNpcMeleeId, out var snapshot);
|
|
// Assert
|
|
Assert.Null(snapshot.AggroHolderPlayerId);
|
|
}
|
|
|
|
[Fact]
|
|
public void TryClearOnLeashForPlayer_ShouldKeepHolder_WhenPlayerInsideLeashRadius()
|
|
{
|
|
// Arrange
|
|
var behaviorRegistry = PrototypeNpcTestFixtures.CreateBehaviorRegistry();
|
|
var threatStore = new InMemoryThreatStateStore();
|
|
var positions = CreatePositionStoreAt(0, 0, 0);
|
|
_ = AggroOperations.TryAcquire(PrototypeNpcRegistry.PrototypeNpcMeleeId, "dev-local-1", threatStore);
|
|
positions.TryApplyMoveTarget("dev-local-1", 1, 0, 1, out _);
|
|
// Act
|
|
AggroOperations.TryClearOnLeashForPlayer("dev-local-1", positions, behaviorRegistry, threatStore);
|
|
threatStore.TryGet(PrototypeNpcRegistry.PrototypeNpcMeleeId, out var snapshot);
|
|
// Assert
|
|
Assert.Equal("dev-local-1", snapshot.AggroHolderPlayerId);
|
|
}
|
|
|
|
[Fact]
|
|
public void TryClearOnLeashForPlayer_ShouldKeepHolder_WhenPlayerAtExactLeashRadius()
|
|
{
|
|
// Arrange
|
|
var behaviorRegistry = PrototypeNpcTestFixtures.CreateBehaviorRegistry();
|
|
var threatStore = new InMemoryThreatStateStore();
|
|
var positions = CreatePositionStoreAt(0, 0, 0);
|
|
_ = AggroOperations.TryAcquire(PrototypeNpcRegistry.PrototypeNpcMeleeId, "dev-local-1", threatStore);
|
|
// Melee anchor (-3, -3); leash 16.0 — X = 13 is exactly 16 m horizontal from anchor.
|
|
positions.TryApplyMoveTarget("dev-local-1", 13, 0, -3, out _);
|
|
// Act
|
|
AggroOperations.TryClearOnLeashForPlayer("dev-local-1", positions, behaviorRegistry, threatStore);
|
|
threatStore.TryGet(PrototypeNpcRegistry.PrototypeNpcMeleeId, out var snapshot);
|
|
// Assert
|
|
Assert.Equal("dev-local-1", snapshot.AggroHolderPlayerId);
|
|
}
|
|
|
|
[Fact]
|
|
public void TryAcquire_ShouldSetHolderAgain_AfterLeashClear()
|
|
{
|
|
// Arrange
|
|
var behaviorRegistry = PrototypeNpcTestFixtures.CreateBehaviorRegistry();
|
|
var threatStore = new InMemoryThreatStateStore();
|
|
var positions = CreatePositionStoreAt(0, 0, 0);
|
|
_ = AggroOperations.TryAcquire(PrototypeNpcRegistry.PrototypeNpcMeleeId, "dev-local-1", threatStore);
|
|
positions.TryApplyMoveTarget("dev-local-1", 12, 0, 12, out _);
|
|
AggroOperations.TryClearOnLeashForPlayer("dev-local-1", positions, behaviorRegistry, threatStore);
|
|
positions.TryApplyMoveTarget("dev-local-1", 0, 0, 0, out _);
|
|
// Act
|
|
var reacquired = AggroOperations.TryAcquire(
|
|
PrototypeNpcRegistry.PrototypeNpcMeleeId,
|
|
"dev-local-1",
|
|
threatStore);
|
|
threatStore.TryGet(PrototypeNpcRegistry.PrototypeNpcMeleeId, out var snapshot);
|
|
// Assert
|
|
Assert.True(reacquired);
|
|
Assert.Equal("dev-local-1", snapshot.AggroHolderPlayerId);
|
|
}
|
|
}
|