Files
TheriapolisV3/Theriapolis.Tests/Combat/BehaviorTests.cs
T

79 lines
3.1 KiB
C#
Raw Normal View History

using Theriapolis.Core.Data;
using Theriapolis.Core.Entities.Ai;
using Theriapolis.Core.Rules.Character;
using Theriapolis.Core.Rules.Combat;
using Theriapolis.Core.Util;
using Xunit;
namespace Theriapolis.Tests.Combat;
public sealed class BehaviorTests
{
private readonly ContentResolver _content = new(new ContentLoader(TestHelpers.DataDirectory));
[Fact]
public void Brigand_MovesTowardTargetWhenOutOfReach()
{
var brigand = MakeNpc("brigand_footpad", new Vec2(0, 0), Allegiance.Hostile);
var hero = MakeNpc("brigand_footpad", new Vec2(5, 0), Allegiance.Player);
var enc = new Encounter(0xCAFEUL, 1, new[] { brigand, hero });
// Skip past initiative and start brigand's turn explicitly.
while (enc.CurrentActor.Id != brigand.Id) enc.EndTurn();
new BrigandBehavior().TakeTurn(brigand, new AiContext(enc));
Assert.True((int)brigand.Position.X > 0); // moved toward hero
}
[Fact]
public void WildAnimal_FleesBelowQuarterHp()
{
var wolf = MakeNpc("wolf", new Vec2(5, 0), Allegiance.Hostile);
var hero = MakeNpc("wolf", new Vec2(0, 0), Allegiance.Player);
wolf.CurrentHp = 1; // well below 25% of 11
var enc = new Encounter(0xCAFEUL, 1, new[] { wolf, hero });
while (enc.CurrentActor.Id != wolf.Id) enc.EndTurn();
var startX = (int)wolf.Position.X;
new WildAnimalBehavior().TakeTurn(wolf, new AiContext(enc));
Assert.True((int)wolf.Position.X > startX, "Wounded wolf should flee away from hero (positive X)");
}
[Fact]
public void Behavior_NoTargetMakesNoMoves()
{
var lone = MakeNpc("brigand_footpad", new Vec2(0, 0), Allegiance.Hostile);
var enc = new Encounter(0xCAFEUL, 1, new[] { lone });
var startPos = lone.Position;
new BrigandBehavior().TakeTurn(lone, new AiContext(enc));
Assert.Equal(startPos.X, lone.Position.X);
Assert.Equal(startPos.Y, lone.Position.Y);
}
[Fact]
public void Behavior_AttacksWhenInReach()
{
var brigand = MakeNpc("brigand_footpad", new Vec2(0, 0), Allegiance.Hostile);
var hero = MakeNpc("brigand_footpad", new Vec2(1, 0), Allegiance.Player);
var enc = new Encounter(0xCAFEUL, 1, new[] { brigand, hero });
while (enc.CurrentActor.Id != brigand.Id) enc.EndTurn();
int logBefore = enc.Log.Count;
new BrigandBehavior().TakeTurn(brigand, new AiContext(enc));
Assert.Contains(enc.Log.Skip(logBefore), e => e.Type == CombatLogEntry.Kind.Attack);
}
[Fact]
public void Registry_UnknownIdFallsBackToBrigand()
{
var b = BehaviorRegistry.For("nonsense_behavior");
Assert.IsType<BrigandBehavior>(b);
}
private Combatant MakeNpc(string templateId, Vec2 pos, Allegiance side)
{
var t = _content.Npcs.Templates.First(x => x.Id == templateId);
var swapped = t with { DefaultAllegiance = side.ToString().ToLowerInvariant() };
return Combatant.FromNpcTemplate(swapped, id: pos.X.GetHashCode() ^ pos.Y.GetHashCode(), pos);
}
}