Adv 2.0 D&D Phase 10 SUB3c: Cleric L10/L15

Life/War/Trickery Domain L10/L15 capstones.

L10 Divine Strike (all 3 subclasses): +4 flat per weapon hit, scaling
to +9 at L14. New CombatModifiers.DivineStrikePerHit channel, gated on
Weapon != nil since 5e specs "weapon hit". Damage type (radiant/weapon/
poison) varies by domain but isn't tracked by the engine.

Life L15 Supreme Healing: heal-spell dice resolve at max instead of
rolled. Wired through resolveHealOutOfCombat via lifeDomainSupremeHealing
helper.

War L15 Avatar of Battle: 5e physical resistance vs. non-magical
weapons → flat 0.80 DamageReduct (softer than full 50% to account for
elemental hits).

Trickery L15 Improved Duplicity: 5e duplicates grant ally-flank
advantage; no allies in 1v1, so proxied passively as +1 SporeCloud
round and +5% damage (duplicates flicker around the foe).

10 new tests; cleric-suite green. Pre-existing rng flakes
(TestOrcRageFiresOnLowHP, TestSimulateCombat_FirstAttackBonus...) are
unrelated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
prosolis
2026-05-08 11:41:17 -07:00
parent fcd067b3c4
commit 83654eadc7
4 changed files with 233 additions and 1 deletions

View File

@@ -82,6 +82,13 @@ type CombatModifiers struct {
AssassinateAdvantage bool
AssassinateBonusDmg int
// Phase 10 SUB3c — Cleric Divine Strike. Flat bonus damage on every
// weapon hit (5e: "once per turn", which lands ~per round in our model).
// Damage type (radiant/weapon/poison) varies by Cleric subclass but is
// not tracked in our engine. Only fires on the weapon-dice damage path —
// no Weapon → no Divine Strike.
DivineStrikePerHit int
// Phase 10 SUB2b — Mage subclasses.
// ArcaneWardHP: flat HP buffer absorbed before player HP. Refilled at the
// start of each combat by Abjuration L5+ (2× Mage level, +prof at L7).
@@ -620,6 +627,13 @@ func resolvePlayerAttack(st *combatState, player, enemy *Combatant, phase *Comba
dmg = int(float64(dmg) * (1 + player.Mods.FrenzyDmgBonus))
}
}
// Phase 10 SUB3c — Divine Strike. Flat per-hit bonus on weapon hits only
// (5e specs "weapon hit"; no Weapon means we're on the legacy/non-weapon
// damage path and Divine Strike doesn't apply). Lands every hit because
// our 1v1 model has no concept of "once per turn" turn boundaries.
if player.Mods.DivineStrikePerHit > 0 && player.Stats.Weapon != nil {
dmg += player.Mods.DivineStrikePerHit
}
// Phase 10 SUB2a-ii — Assassin Death Strike proxy: bonus damage on the
// first hit only. Stacks on top of the Rogue's Sneak Attack auto-crit
// (which already doubled the base damage above) — the bonus itself is