mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-16 00:52:40 +00:00
D&D: class passives + subclasses for the five caster classes
Adds signature class passives for Druid/Bard/Sorcerer/Warlock/Paladin in dnd_passives.go, each riding an existing CombatModifiers channel so a playable caster is no longer mechanically empty: Druid Wild Resilience (damage reduction), Bard Bardic Inspiration (initiative), Sorcerer Innate Sorcery (CHA-scaled pre-combat burst), Warlock Agonizing Blast (+10% damage), Paladin Divine Smite (level-scaled burst). Adds 15 subclasses (3 per caster, registry now 30) using canonical 5e archetype names, with passive-only L5/7/10/15 effects in applySubclassPassives — consistent with the majority of the original fifteen, no new resource pools or active abilities. subclassesForClass is now non-empty for casters, so the L5 !subclass prompt and sheet display light up through the existing generic plumbing. Tests: TestApplyClassPassives extended to all ten classes and the new channels; TestSubclassRegistry_* updated to expect 30 entries across all ten classes.
This commit is contained in:
@@ -340,6 +340,331 @@ func applySubclassPassives(stats *CombatStats, mods *CombatModifiers, c *DnDChar
|
||||
if c.Level >= 15 {
|
||||
mods.DamageReduct *= 0.90
|
||||
}
|
||||
|
||||
// ── Open5e caster scaffold — Druid / Bard / Sorcerer / Warlock /
|
||||
// Paladin subclasses. Passive-only, consistent with the majority of the
|
||||
// original fifteen (Champion, Thief, the Mage and Ranger subclasses):
|
||||
// no new resource pools or active abilities. Each L5/7/10/15 tier rides
|
||||
// an existing CombatModifiers channel — per-case notes name the 5e
|
||||
// ability each proxy stands in for. DamageReduct is initialized to 1.0
|
||||
// by DerivePlayerStats, so the `*=` reductions compose cleanly.
|
||||
case SubclassCircleLand:
|
||||
// L5 Natural Recovery: a measured self-heal — rides HealItem (fires
|
||||
// once at <50% HP). L7 Land's Stride: +2 Speed (initiative). L10
|
||||
// Nature's Ward: resistance to a slice of elemental/poison damage,
|
||||
// collapsed to a flat 8% incoming reduction. L15 Nature's Sanctuary:
|
||||
// foes hesitate to close — 1 round of SporeCloud — plus a further 10%.
|
||||
if c.Level >= 5 {
|
||||
mods.HealItem += 5
|
||||
}
|
||||
if c.Level >= 7 {
|
||||
stats.Speed += 2
|
||||
}
|
||||
if c.Level >= 10 {
|
||||
mods.DamageReduct *= 0.92
|
||||
}
|
||||
if c.Level >= 15 {
|
||||
mods.SporeCloud++
|
||||
mods.DamageReduct *= 0.90
|
||||
}
|
||||
case SubclassCircleMoon:
|
||||
// L5 Combat Wild Shape: a bestial form's HP pool — an ArcaneWardHP
|
||||
// buffer scaling with level — plus the form's heavier hits (+10%
|
||||
// damage). L7 Primal Strike: beast attacks bite harder (+5%). L10
|
||||
// Elemental Wild Shape: an elemental form's opening slam — a
|
||||
// FlatDmgStart burst. L15 Archdruid: the form barely tires — a flat
|
||||
// 15% incoming reduction.
|
||||
if c.Level >= 5 {
|
||||
if buf := 3 * c.Level; mods.ArcaneWardHP < buf {
|
||||
mods.ArcaneWardHP = buf
|
||||
}
|
||||
mods.DamageBonus += 0.10
|
||||
}
|
||||
if c.Level >= 7 {
|
||||
mods.DamageBonus += 0.05
|
||||
}
|
||||
if c.Level >= 10 {
|
||||
mods.FlatDmgStart += 8
|
||||
}
|
||||
if c.Level >= 15 {
|
||||
mods.DamageReduct *= 0.85
|
||||
}
|
||||
case SubclassCircleShepherd:
|
||||
// L5 Spirit Totem (Bear): a warding spirit grants a temp-HP buffer.
|
||||
// L7 Mighty Summoner: a conjured beast joins the fight — rides the
|
||||
// pet channel. L10 Guardian Spirit: the spirits mend you — HealItem.
|
||||
// L15 Faithful Summons: the conjured ally is tougher and strikes
|
||||
// more often.
|
||||
if c.Level >= 5 {
|
||||
if buf := 2 * c.Level; mods.ArcaneWardHP < buf {
|
||||
mods.ArcaneWardHP = buf
|
||||
}
|
||||
}
|
||||
if c.Level >= 7 {
|
||||
if mods.PetAttackProc < 0.25 {
|
||||
mods.PetAttackProc = 0.25
|
||||
}
|
||||
if dmg := 3 + c.Level/2; mods.PetAttackDmg < dmg {
|
||||
mods.PetAttackDmg = dmg
|
||||
}
|
||||
}
|
||||
if c.Level >= 10 {
|
||||
mods.HealItem += c.Level / 2
|
||||
}
|
||||
if c.Level >= 15 {
|
||||
if mods.PetAttackProc < 0.45 {
|
||||
mods.PetAttackProc = 0.45
|
||||
}
|
||||
if dmg := 8 + c.Level/2; mods.PetAttackDmg < dmg {
|
||||
mods.PetAttackDmg = dmg
|
||||
}
|
||||
}
|
||||
case SubclassCollegeLore:
|
||||
// L5 Cutting Words: a barbed quip throws the foe off — 2 rounds of
|
||||
// SporeCloud miss chance. L7 Additional Magical Secrets: borrowed
|
||||
// versatility, a flat +1 to attack rolls. L10 Peerless Skill: a
|
||||
// self-aimed Bardic Inspiration die on the opener (FirstAttackBonus).
|
||||
// L15: deeper Magical Secrets keep paying out — +10% damage.
|
||||
if c.Level >= 5 {
|
||||
mods.SporeCloud += 2
|
||||
}
|
||||
if c.Level >= 7 {
|
||||
stats.AttackBonus++
|
||||
}
|
||||
if c.Level >= 10 {
|
||||
mods.FirstAttackBonus += 5
|
||||
}
|
||||
if c.Level >= 15 {
|
||||
mods.DamageBonus += 0.10
|
||||
}
|
||||
case SubclassCollegeValor:
|
||||
// L5 Combat Inspiration: songs that sharpen the blade (+10% damage).
|
||||
// L7 Extra Attack: throughput — +1 attack and a further +10% damage
|
||||
// proxy for the second swing. L10 Battle Magic: a bonus-action
|
||||
// strike after a spell — a FlatDmgStart burst. L15: +1 AC, the
|
||||
// late-game shield half of Combat Inspiration.
|
||||
if c.Level >= 5 {
|
||||
mods.DamageBonus += 0.10
|
||||
}
|
||||
if c.Level >= 7 {
|
||||
stats.AttackBonus++
|
||||
mods.DamageBonus += 0.10
|
||||
}
|
||||
if c.Level >= 10 {
|
||||
mods.FlatDmgStart += 6
|
||||
}
|
||||
if c.Level >= 15 {
|
||||
stats.AC++
|
||||
}
|
||||
case SubclassCollegeGlamour:
|
||||
// L5 Mantle of Inspiration: a fey-glamour temp-HP buffer. L7 Mantle
|
||||
// of Majesty: the foe is briefly enthralled — skips its first
|
||||
// attack. L10 Enthralling Performance: lingering fascination — 2
|
||||
// rounds of SporeCloud miss chance. L15 Unbreakable Majesty: foes
|
||||
// struggle to bring themselves to strike you — a flat 15% reduction.
|
||||
if c.Level >= 5 {
|
||||
if buf := 2 * c.Level; mods.ArcaneWardHP < buf {
|
||||
mods.ArcaneWardHP = buf
|
||||
}
|
||||
}
|
||||
if c.Level >= 7 {
|
||||
mods.SpellEnemySkipFirst = true
|
||||
}
|
||||
if c.Level >= 10 {
|
||||
mods.SporeCloud += 2
|
||||
}
|
||||
if c.Level >= 15 {
|
||||
mods.DamageReduct *= 0.85
|
||||
}
|
||||
case SubclassDraconicBloodline:
|
||||
// L5 Draconic Resilience: scaled hide — +1 AC and an HP buffer. L7
|
||||
// Elemental Affinity: CHA folded into spell damage — +10%. L10
|
||||
// Dragon Wings: mobility and a tougher frame — an 8% reduction and a
|
||||
// small damage bump. L15 Draconic Presence: a frightful aura — 2
|
||||
// rounds of SporeCloud miss chance.
|
||||
if c.Level >= 5 {
|
||||
stats.AC++
|
||||
if mods.ArcaneWardHP < c.Level {
|
||||
mods.ArcaneWardHP = c.Level
|
||||
}
|
||||
}
|
||||
if c.Level >= 7 {
|
||||
mods.DamageBonus += 0.10
|
||||
}
|
||||
if c.Level >= 10 {
|
||||
mods.DamageReduct *= 0.92
|
||||
mods.DamageBonus += 0.05
|
||||
}
|
||||
if c.Level >= 15 {
|
||||
mods.SporeCloud += 2
|
||||
}
|
||||
case SubclassWildMagic:
|
||||
// L5 Tides of Chaos: fortune favors the opener — advantage on the
|
||||
// first attack. L7 Bend Luck: nudge a roll your way —
|
||||
// FirstAttackBonus. L10 Controlled Chaos: a surge you actually aimed
|
||||
// — a FlatDmgStart burst. L15 Spell Bombardment: dice that keep
|
||||
// exploding — +15% damage.
|
||||
if c.Level >= 5 {
|
||||
mods.AssassinateAdvantage = true
|
||||
}
|
||||
if c.Level >= 7 {
|
||||
mods.FirstAttackBonus += 3
|
||||
}
|
||||
if c.Level >= 10 {
|
||||
mods.FlatDmgStart += 10
|
||||
}
|
||||
if c.Level >= 15 {
|
||||
mods.DamageBonus += 0.15
|
||||
}
|
||||
case SubclassStormSorcery:
|
||||
// L5 Tempestuous Magic: the storm moves first — +1 initiative and
|
||||
// +2 Speed. L7 Heart of the Storm: a thunderclap as you cast — a
|
||||
// level-scaled FlatDmgStart burst. L10 Storm Guide: you ride the
|
||||
// weather — a small 5% reduction and 1 round of SporeCloud. L15
|
||||
// Storm's Fury: incoming blows are answered with lightning —
|
||||
// ReflectNext on the first hit.
|
||||
if c.Level >= 5 {
|
||||
mods.InitiativeBias += 1
|
||||
stats.Speed += 2
|
||||
}
|
||||
if c.Level >= 7 {
|
||||
mods.FlatDmgStart += 5 + c.Level/2
|
||||
}
|
||||
if c.Level >= 10 {
|
||||
mods.DamageReduct *= 0.95
|
||||
mods.SporeCloud++
|
||||
}
|
||||
if c.Level >= 15 {
|
||||
mods.ReflectNext += 0.30
|
||||
}
|
||||
case SubclassFiendPatron:
|
||||
// L5 Dark One's Blessing: temp HP as foes fall — modeled as an
|
||||
// up-front CHA-scaled buffer. L7 Dark One's Own Luck: a nudged roll
|
||||
// — FirstAttackBonus. L10 Fiendish Resilience: chosen resistance — a
|
||||
// flat 10% incoming reduction. L15 Hurl Through Hell: a foe sent
|
||||
// briefly to the lower planes — a heavy FlatDmgStart burst.
|
||||
if c.Level >= 5 {
|
||||
chaMod := abilityModifier(c.CHA)
|
||||
if chaMod < 0 {
|
||||
chaMod = 0
|
||||
}
|
||||
if buf := c.Level + chaMod; mods.ArcaneWardHP < buf {
|
||||
mods.ArcaneWardHP = buf
|
||||
}
|
||||
}
|
||||
if c.Level >= 7 {
|
||||
mods.FirstAttackBonus += 3
|
||||
}
|
||||
if c.Level >= 10 {
|
||||
mods.DamageReduct *= 0.90
|
||||
}
|
||||
if c.Level >= 15 {
|
||||
mods.FlatDmgStart += 12
|
||||
}
|
||||
case SubclassArchfeyPatron:
|
||||
// L5 Fey Presence: the foe is briefly charmed/frightened — skips its
|
||||
// first attack. L7 Misty Escape: you blink out of harm's way — 2
|
||||
// rounds of SporeCloud miss chance. L10 Beguiling Defenses: hostile
|
||||
// magic rebounds — ReflectNext on the first hit. L15 Dark Delirium:
|
||||
// the foe is lost in illusion — more SporeCloud and a small edge.
|
||||
if c.Level >= 5 {
|
||||
mods.SpellEnemySkipFirst = true
|
||||
}
|
||||
if c.Level >= 7 {
|
||||
mods.SporeCloud += 2
|
||||
}
|
||||
if c.Level >= 10 {
|
||||
mods.ReflectNext += 0.25
|
||||
}
|
||||
if c.Level >= 15 {
|
||||
mods.SporeCloud += 2
|
||||
mods.DamageBonus += 0.05
|
||||
}
|
||||
case SubclassGreatOldOne:
|
||||
// L5 Entropic Ward: a missed attack tilts the next exchange — a
|
||||
// small reduction and 1 round of SporeCloud. L7 Thought Shield:
|
||||
// psychic resilience — a flat 8% incoming reduction. L10 Create
|
||||
// Thrall: a dominated mind fights beside you — the pet channel. L15:
|
||||
// deeper psychic dominion keeps the thrall in the fight and sharpens
|
||||
// your own assault (+10% damage).
|
||||
if c.Level >= 5 {
|
||||
mods.DamageReduct *= 0.95
|
||||
mods.SporeCloud++
|
||||
}
|
||||
if c.Level >= 7 {
|
||||
mods.DamageReduct *= 0.92
|
||||
}
|
||||
if c.Level >= 10 {
|
||||
if mods.PetAttackProc < 0.30 {
|
||||
mods.PetAttackProc = 0.30
|
||||
}
|
||||
if dmg := 4 + c.Level/2; mods.PetAttackDmg < dmg {
|
||||
mods.PetAttackDmg = dmg
|
||||
}
|
||||
}
|
||||
if c.Level >= 15 {
|
||||
mods.DamageBonus += 0.10
|
||||
}
|
||||
case SubclassOathDevotion:
|
||||
// L5 Sacred Weapon: a blade lit with the oath — +1 attack and
|
||||
// radiant damage on every hit (DivineStrikePerHit, the channel the
|
||||
// Cleric domains use). L7 Aura of Devotion: a small warding aura —
|
||||
// 5% reduction. L10 Aura of Courage/Purity: the aura hardens — a
|
||||
// further 8% reduction. L15 Holy Nimbus: a radiant aura that sears
|
||||
// the foe on engagement — a FlatDmgStart burst.
|
||||
if c.Level >= 5 {
|
||||
stats.AttackBonus++
|
||||
mods.DivineStrikePerHit += 4
|
||||
}
|
||||
if c.Level >= 7 {
|
||||
mods.DamageReduct *= 0.95
|
||||
}
|
||||
if c.Level >= 10 {
|
||||
mods.DamageReduct *= 0.92
|
||||
}
|
||||
if c.Level >= 15 {
|
||||
mods.FlatDmgStart += 10
|
||||
}
|
||||
case SubclassOathVengeance:
|
||||
// L5 Vow of Enmity: advantage against the marked foe plus the focus
|
||||
// to press it — advantage on the opener and +10% damage. L7
|
||||
// Relentless Avenger: you keep pace with a fleeing target — +2 Speed
|
||||
// and a small damage bump. L10 Soul of Vengeance: an extra strike at
|
||||
// the marked foe — +10% damage. L15: the hunt never lets up —
|
||||
// a FlatDmgStart opener.
|
||||
if c.Level >= 5 {
|
||||
mods.AssassinateAdvantage = true
|
||||
mods.DamageBonus += 0.10
|
||||
}
|
||||
if c.Level >= 7 {
|
||||
stats.Speed += 2
|
||||
mods.DamageBonus += 0.05
|
||||
}
|
||||
if c.Level >= 10 {
|
||||
mods.DamageBonus += 0.10
|
||||
}
|
||||
if c.Level >= 15 {
|
||||
mods.FlatDmgStart += 6
|
||||
}
|
||||
case SubclassOathAncients:
|
||||
// L5 Nature's Wrath: the green and growing things slow the foe — a
|
||||
// small reduction. L7 Aura of Warding: resistance to spell damage —
|
||||
// a further 8% reduction. L10 Undying Sentinel: you refuse to fall —
|
||||
// survive one otherwise-lethal hit (DeathSave). L15 Elder Champion:
|
||||
// the old light blazes up — +1 attack and +10% damage.
|
||||
if c.Level >= 5 {
|
||||
mods.DamageReduct *= 0.95
|
||||
}
|
||||
if c.Level >= 7 {
|
||||
mods.DamageReduct *= 0.92
|
||||
}
|
||||
if c.Level >= 10 {
|
||||
mods.DeathSave = true
|
||||
}
|
||||
if c.Level >= 15 {
|
||||
stats.AttackBonus++
|
||||
mods.DamageBonus += 0.10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user