Files
TheriapolisV3/Theriapolis.Tests/Loot/LootRollerTests.cs
T

82 lines
2.9 KiB
C#
Raw Normal View History

using Theriapolis.Core;
using Theriapolis.Core.Data;
using Theriapolis.Core.Loot;
using Theriapolis.Core.Util;
using Xunit;
namespace Theriapolis.Tests.Loot;
public sealed class LootRollerTests
{
private readonly ContentResolver _content = new(new ContentLoader(TestHelpers.DataDirectory));
[Fact]
public void LootTables_LoadCleanly()
{
Assert.True(_content.LootTables.Count >= 9, $"expected ≥9 loot tables, got {_content.LootTables.Count}");
Assert.Contains("loot_brigand_low", _content.LootTables.Keys);
Assert.Contains("loot_brigand_high", _content.LootTables.Keys);
Assert.Contains("loot_wild_low", _content.LootTables.Keys);
}
[Fact]
public void Roll_UnknownTable_ReturnsEmpty()
{
var rng = new SeededRng(0xCAFEUL);
var drops = LootRoller.Roll("not_a_table", _content.LootTables, _content.Items, rng);
Assert.Empty(drops);
}
[Fact]
public void Roll_EmptyTableId_ReturnsEmpty()
{
var rng = new SeededRng(0xCAFEUL);
var drops = LootRoller.Roll("", _content.LootTables, _content.Items, rng);
Assert.Empty(drops);
}
[Fact]
public void Roll_SameSeed_ProducesSameDrops()
{
var a = LootRoller.Roll("loot_brigand_high", _content.LootTables, _content.Items, new SeededRng(42UL));
var b = LootRoller.Roll("loot_brigand_high", _content.LootTables, _content.Items, new SeededRng(42UL));
Assert.Equal(a.Count, b.Count);
for (int i = 0; i < a.Count; i++)
{
Assert.Equal(a[i].Def.Id, b[i].Def.Id);
Assert.Equal(a[i].Qty, b[i].Qty);
}
}
[Fact]
public void Roll_QtyAlwaysWithinBounds()
{
// Roll many times; verify no result has qty outside the table-defined range.
var table = _content.LootTables["loot_brigand_high"];
var bounds = table.Drops.ToDictionary(d => d.ItemId, d => (d.QtyMin, d.QtyMax));
for (int seed = 0; seed < 50; seed++)
{
var drops = LootRoller.Roll("loot_brigand_high", _content.LootTables, _content.Items, new SeededRng((ulong)seed));
foreach (var drop in drops)
{
var (mn, mx) = bounds[drop.Def.Id];
Assert.InRange(drop.Qty, mn, mx);
}
}
}
[Fact]
public void Roll_OneHundredSamples_AverageDropCountIsReasonable()
{
// The "high" brigand table has 5 drops with cumulative chance summing
// around 1.95. Across 100 samples expect ≥50 total drops.
int totalDrops = 0;
for (int seed = 0; seed < 100; seed++)
{
var drops = LootRoller.Roll("loot_brigand_high", _content.LootTables, _content.Items, new SeededRng((ulong)seed));
totalDrops += drops.Count;
}
Assert.True(totalDrops >= 50, $"expected ≥50 drops in 100 samples, got {totalDrops}");
}
}