b451f83174
Captures the pre-Godot-port state of the codebase. This is the rollback anchor for the Godot port (M0 of theriapolis-rpg-implementation-plan-godot-port.md). All Phase 0 through Phase 6.5 work is included; Phase 7 is in flight. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
53 lines
1.4 KiB
C#
53 lines
1.4 KiB
C#
namespace Theriapolis.Core.Rules.Stats;
|
|
|
|
/// <summary>
|
|
/// Standard d20 XP-to-level table. Phase 5 awards XP and persists it but
|
|
/// does not act on level-up — <see cref="LevelForXp"/> is exposed for the
|
|
/// HUD to display "next level in N XP" without requiring a level-up
|
|
/// flow yet.
|
|
/// </summary>
|
|
public static class XpTable
|
|
{
|
|
/// <summary>XP threshold for each level 1..20. <c>Threshold[1] = 0</c> by convention.</summary>
|
|
public static readonly int[] Threshold = new[]
|
|
{
|
|
0, // index 0 unused
|
|
0, // level 1
|
|
300, // level 2
|
|
900,
|
|
2_700,
|
|
6_500,
|
|
14_000,
|
|
23_000,
|
|
34_000,
|
|
48_000,
|
|
64_000,
|
|
85_000,
|
|
100_000,
|
|
120_000,
|
|
140_000,
|
|
165_000,
|
|
195_000,
|
|
225_000,
|
|
265_000,
|
|
305_000,
|
|
355_000, // level 20
|
|
};
|
|
|
|
public static int LevelForXp(int xp)
|
|
{
|
|
if (xp < 0) throw new ArgumentOutOfRangeException(nameof(xp));
|
|
for (int lv = 20; lv >= 1; lv--)
|
|
if (xp >= Threshold[lv]) return lv;
|
|
return 1;
|
|
}
|
|
|
|
public static int XpRequiredForNextLevel(int currentLevel)
|
|
{
|
|
if (currentLevel < 1 || currentLevel > 20)
|
|
throw new ArgumentOutOfRangeException(nameof(currentLevel));
|
|
if (currentLevel == 20) return int.MaxValue;
|
|
return Threshold[currentLevel + 1];
|
|
}
|
|
}
|