neon-sprawl/server/NeonSprawl.Server.Tests/Game/Combat/NpcAttackOperationsTests.cs

161 lines
6.6 KiB
C#

using NeonSprawl.Server.Game.AbilityInput;
using NeonSprawl.Server.Game.Combat;
using NeonSprawl.Server.Game.PositionState;
namespace NeonSprawl.Server.Tests.Game.Combat;
public sealed class NpcAttackOperationsTests
{
private static InMemoryPositionStateStore CreatePositionStoreAt(double x, double y, double z) =>
new(Options.Create(new GamePositionOptions
{
DevPlayerId = "dev-local-1",
DefaultPosition = new DefaultPositionOptions { X = x, Y = y, Z = z },
}));
[Fact]
public void TryResolveTelegraphComplete_ShouldApplyCatalogDamage_WhenHolderMatchesAndInRange()
{
// Arrange
var abilityRegistry = PrototypeNpcTestFixtures.CreateAbilityRegistry();
var threatStore = new InMemoryThreatStateStore();
var playerHealthStore = new InMemoryPlayerCombatHealthStore();
var positionStore = CreatePositionStoreAt(-3.0, 0.5, -3.0);
_ = threatStore.TrySetHolder(PrototypeNpcRegistry.PrototypeNpcMeleeId, "dev-local-1");
// Act
var ok = NpcAttackOperations.TryResolveTelegraphComplete(
PrototypeNpcRegistry.PrototypeNpcMeleeId,
"dev-local-1",
PrototypeNpcAttackAbilityRegistry.PrototypeNpcMeleeStrike,
abilityRegistry,
positionStore,
playerHealthStore,
threatStore);
// Assert
Assert.True(ok);
playerHealthStore.TryGet("dev-local-1", out var snapshot);
Assert.Equal(85, snapshot.CurrentHp);
}
[Fact]
public void TryResolveTelegraphComplete_ShouldNoOp_WhenHolderOutOfAbilityMaxRange()
{
// Arrange
var abilityRegistry = PrototypeNpcTestFixtures.CreateAbilityRegistry();
var threatStore = new InMemoryThreatStateStore();
var playerHealthStore = new InMemoryPlayerCombatHealthStore();
var positionStore = CreatePositionStoreAt(10.0, 0.5, 10.0);
_ = threatStore.TrySetHolder(PrototypeNpcRegistry.PrototypeNpcMeleeId, "dev-local-1");
// Act
var ok = NpcAttackOperations.TryResolveTelegraphComplete(
PrototypeNpcRegistry.PrototypeNpcMeleeId,
"dev-local-1",
PrototypeNpcAttackAbilityRegistry.PrototypeNpcMeleeStrike,
abilityRegistry,
positionStore,
playerHealthStore,
threatStore);
// Assert
Assert.False(ok);
playerHealthStore.TryGet("dev-local-1", out var snapshot);
Assert.Equal(PlayerCombatHealthDefaults.MaxHp, snapshot.CurrentHp);
}
[Fact]
public void TryResolveTelegraphComplete_ShouldNoOp_WhenHolderBeyondAbilityMaxRangeButInsideAggroRadius()
{
// Arrange
var abilityRegistry = PrototypeNpcTestFixtures.CreateAbilityRegistry();
var threatStore = new InMemoryThreatStateStore();
var playerHealthStore = new InMemoryPlayerCombatHealthStore();
var positionStore = CreatePositionStoreAt(-10.0, 0.5, -3.0);
_ = threatStore.TrySetHolder(PrototypeNpcRegistry.PrototypeNpcMeleeId, "dev-local-1");
// Act
var ok = NpcAttackOperations.TryResolveTelegraphComplete(
PrototypeNpcRegistry.PrototypeNpcMeleeId,
"dev-local-1",
PrototypeNpcAttackAbilityRegistry.PrototypeNpcMeleeStrike,
abilityRegistry,
positionStore,
playerHealthStore,
threatStore);
// Assert
Assert.False(ok);
playerHealthStore.TryGet("dev-local-1", out var snapshot);
Assert.Equal(PlayerCombatHealthDefaults.MaxHp, snapshot.CurrentHp);
}
[Fact]
public void TryResolveTelegraphComplete_ShouldNoOp_WhenHolderCleared()
{
// Arrange
var abilityRegistry = PrototypeNpcTestFixtures.CreateAbilityRegistry();
var threatStore = new InMemoryThreatStateStore();
var playerHealthStore = new InMemoryPlayerCombatHealthStore();
var positionStore = CreatePositionStoreAt(-3.0, 0.5, -3.0);
_ = threatStore.TrySetHolder(PrototypeNpcRegistry.PrototypeNpcMeleeId, "dev-local-1");
_ = threatStore.TryClearHolder(PrototypeNpcRegistry.PrototypeNpcMeleeId);
// Act
var ok = NpcAttackOperations.TryResolveTelegraphComplete(
PrototypeNpcRegistry.PrototypeNpcMeleeId,
"dev-local-1",
PrototypeNpcAttackAbilityRegistry.PrototypeNpcMeleeStrike,
abilityRegistry,
positionStore,
playerHealthStore,
threatStore);
// Assert
Assert.False(ok);
playerHealthStore.TryGet("dev-local-1", out var snapshot);
Assert.Equal(PlayerCombatHealthDefaults.MaxHp, snapshot.CurrentHp);
}
[Fact]
public void TryResolveTelegraphComplete_ShouldNoOp_WhenHolderPlayerDiffers()
{
// Arrange
var abilityRegistry = PrototypeNpcTestFixtures.CreateAbilityRegistry();
var threatStore = new InMemoryThreatStateStore();
var playerHealthStore = new InMemoryPlayerCombatHealthStore();
var positionStore = CreatePositionStoreAt(-3.0, 0.5, -3.0);
_ = threatStore.TrySetHolder(PrototypeNpcRegistry.PrototypeNpcMeleeId, "other-player");
// Act
var ok = NpcAttackOperations.TryResolveTelegraphComplete(
PrototypeNpcRegistry.PrototypeNpcMeleeId,
"dev-local-1",
PrototypeNpcAttackAbilityRegistry.PrototypeNpcMeleeStrike,
abilityRegistry,
positionStore,
playerHealthStore,
threatStore);
// Assert
Assert.False(ok);
playerHealthStore.TryGet("dev-local-1", out var snapshot);
Assert.Equal(PlayerCombatHealthDefaults.MaxHp, snapshot.CurrentHp);
}
[Fact]
public void TryResolveTelegraphComplete_ShouldSucceedWithoutMutation_WhenAbilityBaseDamageZero()
{
// Arrange
var abilityRegistry = PrototypeNpcTestFixtures.CreateAbilityRegistry();
var threatStore = new InMemoryThreatStateStore();
var playerHealthStore = new InMemoryPlayerCombatHealthStore();
var positionStore = CreatePositionStoreAt(10.0, 0.5, 10.0);
_ = threatStore.TrySetHolder(PrototypeNpcRegistry.PrototypeNpcMeleeId, "dev-local-1");
// Act
var ok = NpcAttackOperations.TryResolveTelegraphComplete(
PrototypeNpcRegistry.PrototypeNpcMeleeId,
"dev-local-1",
PrototypeAbilityRegistry.PrototypeGuard,
abilityRegistry,
positionStore,
playerHealthStore,
threatStore);
// Assert
Assert.True(ok);
playerHealthStore.TryGet("dev-local-1", out var snapshot);
Assert.Equal(PlayerCombatHealthDefaults.MaxHp, snapshot.CurrentHp);
}
}