46 lines
2.3 KiB
C#
46 lines
2.3 KiB
C#
using Outnumbered.Domain;
|
|
using Xunit;
|
|
|
|
namespace Outnumbered.Tests;
|
|
|
|
// CombatResolver's pure reactive-sustain amounts (the engine does the HP/armor writes; these own the numbers). Expected
|
|
// ints are hand-known, exercising the (int)Math.Round (banker's, ToEven) rounding + the LifestealMinHeal floor.
|
|
public class CombatAmountsTests
|
|
{
|
|
// LifestealHeal = max(minHeal, (int)Round(dmgHealth * pct/100 * critMult)).
|
|
[Theory]
|
|
[InlineData(100, 10, 1.0, 2, 10)] // clean
|
|
[InlineData(100, 10, 1.5, 2, 15)] // crit multiplier
|
|
[InlineData(10, 25, 1.0, 2, 2)] // 2.5 -> ToEven -> 2
|
|
[InlineData(30, 25, 1.0, 2, 8)] // 7.5 -> ToEven -> 8
|
|
[InlineData(4, 25, 1.0, 2, 2)] // 1.0 -> 1, but minHeal floor binds -> 2
|
|
[InlineData(0, 10, 1.0, 2, 2)] // 0 -> floor binds
|
|
public void LifestealHeal_matches(double dmgHealth, double pct, double critMult, int minHeal, int expected) =>
|
|
Assert.Equal(expected, CombatResolver.LifestealHeal(dmgHealth, pct, critMult, minHeal));
|
|
|
|
[Fact]
|
|
public void LifestealHeal_accepts_fractional_thorns_input()
|
|
{
|
|
// The thorns-reflect path passes a FLOAT dmgHealth (no pre-truncation) with critMult 1.0. 33.6*10/100 = 3.36 -> 3.
|
|
Assert.Equal(3, CombatResolver.LifestealHeal(33.6, 10, 1.0, 2));
|
|
}
|
|
|
|
// ArmorLifestealGain = (int)Round(dmgHealth * pct/100 * critMult). No floor.
|
|
[Theory]
|
|
[InlineData(100, 10, 1.0, 10)]
|
|
[InlineData(10, 25, 1.0, 2)] // 2.5 -> 2
|
|
[InlineData(30, 25, 1.0, 8)] // 7.5 -> 8
|
|
[InlineData(0, 10, 1.0, 0)] // no floor -> 0
|
|
public void ArmorLifestealGain_matches(double dmgHealth, double pct, double critMult, int expected) =>
|
|
Assert.Equal(expected, CombatResolver.ArmorLifestealGain(dmgHealth, pct, critMult));
|
|
|
|
// ThornsReflect = (dmgHealth + dmgArmor) * pct/100 (a double). The caller deals it FLAT — no build/handicap re-applied —
|
|
// so the bot eats exactly this off the damage ACTUALLY taken (handicap already baked into dmg*).
|
|
[Theory]
|
|
[InlineData(50, 30, 10, 8.0)]
|
|
[InlineData(100, 0, 5, 5.0)]
|
|
[InlineData(250, 0, 10, 25.0)] // the 5x-handicap example: take 250, reflect 10% = 25
|
|
[InlineData(0, 0, 10, 0.0)]
|
|
public void ThornsReflect_matches(int dmgHealth, int dmgArmor, double pct, double expected) =>
|
|
T.Close(expected, CombatResolver.ThornsReflect(dmgHealth, dmgArmor, pct));
|
|
}
|