mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-15 08:32:41 +00:00
B2: Removed shield/counterspell from Mage/Sorcerer defaults and hellish_rebuke/counterspell
from Warlock — reactions are EffectReaction and combat has no reaction window yet, so
auto-granting them just litters the spellbook with dead entries. Substituted L1/L3
staples (sleep, fly, burning_hands, chromatic_orb where class-tagged appropriately).
B3: Replaced the stale "Mage, Cleric, Ranger, and Arcane Trickster (L5+)" enumeration in
!cast/!spells learn/!prepare error paths with class-aware route hints via a new
spellRouteHintFor() helper.
R15: Removed the duplicate hand-authored healing_word_spell entry; Cleric default now
references the canonical SRD healing_word (cleric/druid/bard tagged). parseSpell
and lookupSpell now resolve "healing word" deterministically.
R16: !cast --drop now appends "(slot refunded)" when applicable.
R17: Prep-cap message rewritten to "Your prepared list is full (N/N)."
R19: Removed shillelagh from Druid default — the overlay flags it cleric/ranger only and
it has no real attack profile yet (BuffSelf, no DamageDice).
Bonus correctness: dndSpellRegistry now unions Classes on overlay collision instead of
replacing wholesale. The hand-authored buildSpellList() entries were tagged Mage-only,
so every Sorcerer/Warlock/Bard/Druid spell that collided with the SRD silently lost its
class list — meaning auto-granted defaults were rejected at the classOK gate. Union
merge restores SRD coverage without forcing a hand-edit of every overlay entry.
Tests:
- TestDefaultKnownSpellsHaveNoReactions covers B2.
- TestDefaultKnownSpellsAreCastableByClass guards the overlay-narrow regression.
- TestHealingWordResolvesDeterministically covers R15.
- TestCastNonCasterErrorHasNoClassEnumeration covers B3.
- Existing dnd_prepare_test.go updated to reference healing_word.
391 lines
24 KiB
Go
391 lines
24 KiB
Go
package plugin
|
||
|
||
// Phase 9 spell registry data. All 76 in-scope spells from
|
||
// gogobee_spell_system.md. Reaction spells (Shield, Counterspell,
|
||
// Absorb Elements) are included with EffectReaction so the registry is
|
||
// complete; SP2's !cast refuses them with a "Phase 11" note.
|
||
|
||
func buildSpellList() []SpellDefinition {
|
||
mage := []DnDClass{ClassMage}
|
||
cleric := []DnDClass{ClassCleric}
|
||
ranger := []DnDClass{ClassRanger}
|
||
mageCleric := []DnDClass{ClassMage, ClassCleric}
|
||
clericRanger := []DnDClass{ClassCleric, ClassRanger}
|
||
rangerCleric := []DnDClass{ClassRanger, ClassCleric}
|
||
allCasters := []DnDClass{ClassMage, ClassCleric, ClassRanger}
|
||
|
||
return []SpellDefinition{
|
||
// ── Cantrips (level 0) ────────────────────────────────────────────────
|
||
{ID: "fire_bolt", Name: "Fire Bolt", Level: 0, School: "evocation",
|
||
Classes: mage, Effect: EffectDamageAttack, CastTime: CastAction,
|
||
AttackRoll: true, DamageDice: "1d10", DamageType: "fire",
|
||
Description: "Hurl a mote of fire at a target.",
|
||
Upcast: "2d10 at L5, 3d10 at L11"},
|
||
{ID: "toll_the_dead", Name: "Toll the Dead", Level: 0, School: "necromancy",
|
||
Classes: mageCleric, Effect: EffectDamageSave, CastTime: CastAction,
|
||
SaveStat: "WIS", DamageDice: "1d8", DamageType: "necrotic",
|
||
Description: "1d8 necrotic; 1d12 if target is missing HP."},
|
||
{ID: "chill_touch", Name: "Chill Touch", Level: 0, School: "necromancy",
|
||
Classes: mageCleric, Effect: EffectDamageAttack, CastTime: CastAction,
|
||
AttackRoll: true, DamageDice: "1d8", DamageType: "necrotic",
|
||
Description: "Spectral hand — target can't heal until next turn."},
|
||
{ID: "poison_spray", Name: "Poison Spray", Level: 0, School: "conjuration",
|
||
Classes: mage, Effect: EffectDamageSave, CastTime: CastAction,
|
||
SaveStat: "CON", DamageDice: "1d12", DamageType: "poison",
|
||
Description: "Puff of noxious gas; CON save or full damage."},
|
||
{ID: "shocking_grasp", Name: "Shocking Grasp", Level: 0, School: "evocation",
|
||
Classes: mage, Effect: EffectDamageAttack, CastTime: CastAction,
|
||
AttackRoll: true, DamageDice: "1d8", DamageType: "lightning",
|
||
Description: "Lightning leaps from your touch; target loses Reaction."},
|
||
{ID: "sacred_flame", Name: "Sacred Flame", Level: 0, School: "evocation",
|
||
Classes: cleric, Effect: EffectDamageSave, CastTime: CastAction,
|
||
SaveStat: "DEX", DamageDice: "1d8", DamageType: "radiant",
|
||
Description: "Flame-like radiance descends; ignores cover."},
|
||
{ID: "guidance", Name: "Guidance", Level: 0, School: "divination",
|
||
Classes: clericRanger, Effect: EffectUtility, CastTime: CastAction,
|
||
Concentration: true,
|
||
Description: "+1d4 to one ability check (self or ally)."},
|
||
{ID: "shillelagh", Name: "Shillelagh", Level: 0, School: "transmutation",
|
||
Classes: rangerCleric, Effect: EffectBuffSelf, CastTime: CastBonusAction,
|
||
Concentration: true,
|
||
Description: "Club/staff uses WIS for attack+damage; 1d8."},
|
||
{ID: "thorn_whip", Name: "Thorn Whip", Level: 0, School: "transmutation",
|
||
Classes: ranger, Effect: EffectDamageAttack, CastTime: CastAction,
|
||
AttackRoll: true, DamageDice: "1d6", DamageType: "piercing",
|
||
Description: "Vine of thorns; pull target 10 ft."},
|
||
{ID: "mending", Name: "Mending", Level: 0, School: "transmutation",
|
||
Classes: allCasters, Effect: EffectUtility, CastTime: CastAction,
|
||
Description: "Repair one non-magical item. Out of combat only."},
|
||
{ID: "message", Name: "Message", Level: 0, School: "transmutation",
|
||
Classes: mage, Effect: EffectUtility, CastTime: CastAction,
|
||
Description: "Whisper to target up to 120 ft."},
|
||
{ID: "minor_illusion", Name: "Minor Illusion", Level: 0, School: "illusion",
|
||
Classes: mage, Effect: EffectUtility, CastTime: CastAction,
|
||
Description: "Create a sound or image."},
|
||
|
||
// ── 1st level — Mage ──────────────────────────────────────────────────
|
||
{ID: "magic_missile", Name: "Magic Missile", Level: 1, School: "evocation",
|
||
Classes: mage, Effect: EffectDamageAuto, CastTime: CastAction,
|
||
DamageDice: "3d4+3", DamageType: "force",
|
||
Description: "Three darts × 1d4+1 force; auto-hit.",
|
||
Upcast: "+1 dart per slot above 1st"},
|
||
{ID: "thunderwave", Name: "Thunderwave", Level: 1, School: "evocation",
|
||
Classes: mage, Effect: EffectDamageSave, CastTime: CastAction,
|
||
SaveStat: "CON", DamageDice: "2d8", DamageType: "thunder", AOE: true,
|
||
Description: "Wave of force in 15 ft cube; push 10 ft.",
|
||
Upcast: "+1d8 per slot above 1st"},
|
||
{ID: "mage_armor", Name: "Mage Armor", Level: 1, School: "abjuration",
|
||
Classes: mage, Effect: EffectBuffSelf, CastTime: CastAction,
|
||
Description: "AC = 13 + DEX mod (no armor required) for 8 hours."},
|
||
{ID: "burning_hands", Name: "Burning Hands", Level: 1, School: "evocation",
|
||
Classes: mage, Effect: EffectDamageSave, CastTime: CastAction,
|
||
SaveStat: "DEX", DamageDice: "3d6", DamageType: "fire", AOE: true,
|
||
Description: "Cone of fire; DEX save half.",
|
||
Upcast: "+1d6 per slot above 1st"},
|
||
{ID: "detect_magic", Name: "Detect Magic", Level: 1, School: "divination",
|
||
Classes: mage, Effect: EffectUtility, CastTime: CastRitual,
|
||
Concentration: true,
|
||
Description: "Sense magic within 30 ft. Ritual castable (no slot)."},
|
||
{ID: "fog_cloud", Name: "Fog Cloud", Level: 1, School: "conjuration",
|
||
Classes: []DnDClass{ClassMage, ClassRanger}, Effect: EffectBuffSelf, CastTime: CastAction,
|
||
Concentration: true,
|
||
Description: "20 ft heavily obscured radius. Attacks inside have disadvantage."},
|
||
{ID: "grease", Name: "Grease", Level: 1, School: "conjuration",
|
||
Classes: mage, Effect: EffectControl, CastTime: CastAction,
|
||
SaveStat: "DEX", AOE: true,
|
||
Description: "10 ft square; DEX save or Prone. Difficult terrain."},
|
||
{ID: "shield", Name: "Shield", Level: 1, School: "abjuration",
|
||
Classes: mage, Effect: EffectReaction, CastTime: CastReaction,
|
||
Description: "+5 AC as Reaction until next turn. (Phase 11)"},
|
||
{ID: "sleep", Name: "Sleep", Level: 1, School: "enchantment",
|
||
Classes: mage, Effect: EffectControl, CastTime: CastAction,
|
||
AOE: true,
|
||
Description: "Incapacitate creatures totaling 5d8 HP (weakest first).",
|
||
Upcast: "+2d8 per slot above 1st"},
|
||
{ID: "chromatic_orb", Name: "Chromatic Orb", Level: 1, School: "evocation",
|
||
Classes: mage, Effect: EffectDamageAttack, CastTime: CastAction,
|
||
AttackRoll: true, DamageDice: "3d8", DamageType: "varies",
|
||
Description: "3d8 of chosen damage type.",
|
||
Upcast: "+1d8 per slot above 1st"},
|
||
|
||
// ── 1st level — Cleric ────────────────────────────────────────────────
|
||
{ID: "cure_wounds", Name: "Cure Wounds", Level: 1, School: "evocation",
|
||
Classes: clericRanger, Effect: EffectSpellHeal, CastTime: CastAction,
|
||
DamageDice: "1d8",
|
||
Description: "Heal 1d8 + WIS mod HP. Touch.",
|
||
Upcast: "+1d8 per slot above 1st"},
|
||
{ID: "bless", Name: "Bless", Level: 1, School: "enchantment",
|
||
Classes: cleric, Effect: EffectBuffAlly, CastTime: CastAction,
|
||
Concentration: true,
|
||
Description: "Up to 3 targets: +1d4 to attack rolls and saves. 1 min."},
|
||
{ID: "inflict_wounds", Name: "Inflict Wounds", Level: 1, School: "necromancy",
|
||
Classes: cleric, Effect: EffectDamageAttack, CastTime: CastAction,
|
||
AttackRoll: true, DamageDice: "3d10", DamageType: "necrotic",
|
||
Description: "3d10 necrotic. Melee spell attack.",
|
||
Upcast: "+1d10 per slot above 1st"},
|
||
{ID: "guiding_bolt", Name: "Guiding Bolt", Level: 1, School: "evocation",
|
||
Classes: cleric, Effect: EffectDamageAttack, CastTime: CastAction,
|
||
AttackRoll: true, DamageDice: "4d6", DamageType: "radiant",
|
||
Description: "Next attack on target has advantage.",
|
||
Upcast: "+1d6 per slot above 1st"},
|
||
{ID: "shield_of_faith", Name: "Shield of Faith", Level: 1, School: "abjuration",
|
||
Classes: cleric, Effect: EffectBuffAlly, CastTime: CastBonusAction,
|
||
Concentration: true,
|
||
Description: "+2 AC to one target. 10 min."},
|
||
// `healing_word_spell` was a hand-authored alias for `healing_word`
|
||
// that collided on display name with the SRD entry. Removed to make
|
||
// parseSpell("healing word") deterministic; Cleric default now points
|
||
// at the canonical SRD `healing_word` (cleric/druid/bard tagged).
|
||
{ID: "command", Name: "Command", Level: 1, School: "enchantment",
|
||
Classes: cleric, Effect: EffectControl, CastTime: CastAction,
|
||
SaveStat: "WIS",
|
||
Description: "One-word command (Flee/Grovel/Halt). 1 turn.",
|
||
Upcast: "+1 target per slot above 1st"},
|
||
{ID: "protection_from_evil", Name: "Protection from Evil and Good", Level: 1, School: "abjuration",
|
||
Classes: cleric, Effect: EffectBuffAlly, CastTime: CastAction,
|
||
Concentration: true,
|
||
Description: "Aberrations/fiends/undead have disadvantage vs. target."},
|
||
|
||
// ── 1st level — Ranger ────────────────────────────────────────────────
|
||
{ID: "hunters_mark", Name: "Hunter's Mark", Level: 1, School: "divination",
|
||
Classes: ranger, Effect: EffectBuffSelf, CastTime: CastBonusAction,
|
||
Concentration: true,
|
||
Description: "+1d6 damage to marked target; track as bonus action. 1 hr."},
|
||
{ID: "ensnaring_strike", Name: "Ensnaring Strike", Level: 1, School: "conjuration",
|
||
Classes: ranger, Effect: EffectControl, CastTime: CastBonusAction,
|
||
Concentration: true, SaveStat: "STR",
|
||
Description: "On hit: STR save or Restrained; 1d6/turn."},
|
||
{ID: "speak_with_animals", Name: "Speak with Animals", Level: 1, School: "divination",
|
||
Classes: ranger, Effect: EffectUtility, CastTime: CastRitual,
|
||
Description: "Communicate with beasts. 10 min."},
|
||
{ID: "absorb_elements", Name: "Absorb Elements", Level: 1, School: "abjuration",
|
||
Classes: ranger, Effect: EffectReaction, CastTime: CastReaction,
|
||
Description: "Reaction: resistance to incoming elemental damage. (Phase 11)"},
|
||
|
||
// ── 2nd level — Mage ──────────────────────────────────────────────────
|
||
{ID: "scorching_ray", Name: "Scorching Ray", Level: 2, School: "evocation",
|
||
Classes: mage, Effect: EffectDamageAuto, CastTime: CastAction,
|
||
DamageDice: "6d6", DamageType: "fire",
|
||
Description: "3 rays × 2d6 fire; each is a separate auto-hit.",
|
||
Upcast: "+1 ray per slot above 2nd"},
|
||
{ID: "mirror_image", Name: "Mirror Image", Level: 2, School: "illusion",
|
||
Classes: mage, Effect: EffectBuffSelf, CastTime: CastAction,
|
||
Description: "3 duplicates absorb hits."},
|
||
{ID: "misty_step", Name: "Misty Step", Level: 2, School: "conjuration",
|
||
Classes: mage, Effect: EffectBuffSelf, CastTime: CastBonusAction,
|
||
Description: "Bonus-action teleport up to 30 ft."},
|
||
{ID: "hold_person", Name: "Hold Person", Level: 2, School: "enchantment",
|
||
Classes: mageCleric, Effect: EffectControl, CastTime: CastAction,
|
||
Concentration: true, SaveStat: "WIS",
|
||
Description: "Paralyzed; auto-crit melee while held.",
|
||
Upcast: "+1 target per slot above 2nd"},
|
||
{ID: "shatter", Name: "Shatter", Level: 2, School: "evocation",
|
||
Classes: mage, Effect: EffectDamageSave, CastTime: CastAction,
|
||
SaveStat: "CON", DamageDice: "3d8", DamageType: "thunder", AOE: true,
|
||
Description: "3d8 thunder in 10 ft sphere.",
|
||
Upcast: "+1d8 per slot above 2nd"},
|
||
{ID: "blur", Name: "Blur", Level: 2, School: "illusion",
|
||
Classes: mage, Effect: EffectBuffSelf, CastTime: CastAction,
|
||
Concentration: true,
|
||
Description: "All attacks vs. you have disadvantage."},
|
||
{ID: "web", Name: "Web", Level: 2, School: "conjuration",
|
||
Classes: mage, Effect: EffectControl, CastTime: CastAction,
|
||
Concentration: true, SaveStat: "STR", AOE: true,
|
||
Description: "20 ft cube; Restrained (STR DC to escape)."},
|
||
{ID: "levitate", Name: "Levitate", Level: 2, School: "transmutation",
|
||
Classes: mage, Effect: EffectUtility, CastTime: CastAction,
|
||
Concentration: true, SaveStat: "CON",
|
||
Description: "Float up to 20 ft; immune to ground-based effects."},
|
||
{ID: "knock", Name: "Knock", Level: 2, School: "transmutation",
|
||
Classes: mage, Effect: EffectUtility, CastTime: CastAction,
|
||
Description: "Open any mundane lock or magically sealed door."},
|
||
|
||
// ── 2nd level — Cleric ────────────────────────────────────────────────
|
||
{ID: "spiritual_weapon", Name: "Spiritual Weapon", Level: 2, School: "evocation",
|
||
Classes: cleric, Effect: EffectBuffSelf, CastTime: CastBonusAction,
|
||
DamageDice: "1d8",
|
||
Description: "Bonus-action spectral weapon attacks 1d8+WIS each turn. 1 min.",
|
||
Upcast: "+1d8 per 2 slots above 2nd"},
|
||
{ID: "lesser_restoration", Name: "Lesser Restoration", Level: 2, School: "abjuration",
|
||
Classes: clericRanger, Effect: EffectUtility, CastTime: CastAction,
|
||
Description: "Remove one condition (Blinded/Deafened/Paralyzed/Poisoned)."},
|
||
{ID: "prayer_of_healing", Name: "Prayer of Healing", Level: 2, School: "evocation",
|
||
Classes: cleric, Effect: EffectSpellHeal, CastTime: CastAction,
|
||
DamageDice: "2d8",
|
||
Description: "Up to 6 targets: 2d8 + WIS mod HP. Out of combat only."},
|
||
{ID: "silence", Name: "Silence", Level: 2, School: "illusion",
|
||
Classes: clericRanger, Effect: EffectUtility, CastTime: CastAction,
|
||
Concentration: true,
|
||
Description: "No sound in 20 ft sphere; no verbal spells."},
|
||
{ID: "aid", Name: "Aid", Level: 2, School: "abjuration",
|
||
Classes: cleric, Effect: EffectBuffAlly, CastTime: CastAction,
|
||
Description: "3 targets: +5 max HP and current HP. 8 hr.",
|
||
Upcast: "+5 HP per slot above 2nd"},
|
||
{ID: "augury", Name: "Augury", Level: 2, School: "divination",
|
||
Classes: cleric, Effect: EffectUtility, CastTime: CastRitual,
|
||
Description: "Omen about action in next 30 min. TwinBee delivers."},
|
||
|
||
// ── 2nd level — Ranger ────────────────────────────────────────────────
|
||
{ID: "pass_without_trace", Name: "Pass Without Trace", Level: 2, School: "abjuration",
|
||
Classes: ranger, Effect: EffectBuffSelf, CastTime: CastAction,
|
||
Concentration: true,
|
||
Description: "+10 to Stealth; can't be tracked magically."},
|
||
{ID: "spike_growth", Name: "Spike Growth", Level: 2, School: "transmutation",
|
||
Classes: ranger, Effect: EffectDamageAuto, CastTime: CastAction,
|
||
Concentration: true, DamageDice: "2d4", DamageType: "piercing", AOE: true,
|
||
Description: "20 ft radius; 2d4 per 5 ft moved through. Difficult terrain."},
|
||
{ID: "beast_sense", Name: "Beast Sense", Level: 2, School: "divination",
|
||
Classes: ranger, Effect: EffectUtility, CastTime: CastRitual,
|
||
Concentration: true,
|
||
Description: "See/hear through a beast's senses."},
|
||
{ID: "cordon_of_arrows", Name: "Cordon of Arrows", Level: 2, School: "transmutation",
|
||
Classes: ranger, Effect: EffectBuffSelf, CastTime: CastAction,
|
||
Description: "4 arrows guard area; fire on intruders (1d6+DEX). 8 hr."},
|
||
{ID: "find_traps", Name: "Find Traps", Level: 2, School: "divination",
|
||
Classes: ranger, Effect: EffectUtility, CastTime: CastAction,
|
||
Description: "Detect presence of traps within 120 ft."},
|
||
|
||
// ── 3rd level — Mage ──────────────────────────────────────────────────
|
||
{ID: "fireball", Name: "Fireball", Level: 3, School: "evocation",
|
||
Classes: mage, Effect: EffectDamageSave, CastTime: CastAction,
|
||
SaveStat: "DEX", DamageDice: "8d6", DamageType: "fire", AOE: true,
|
||
Description: "8d6 fire in 20 ft radius. DEX save half.",
|
||
Upcast: "+1d6 per slot above 3rd"},
|
||
{ID: "lightning_bolt", Name: "Lightning Bolt", Level: 3, School: "evocation",
|
||
Classes: mage, Effect: EffectDamageSave, CastTime: CastAction,
|
||
SaveStat: "DEX", DamageDice: "8d6", DamageType: "lightning", AOE: true,
|
||
Description: "8d6 lightning in 100 ft line. DEX save half.",
|
||
Upcast: "+1d6 per slot above 3rd"},
|
||
{ID: "counterspell", Name: "Counterspell", Level: 3, School: "abjuration",
|
||
Classes: mage, Effect: EffectReaction, CastTime: CastReaction,
|
||
Description: "Reaction: cancel a spell of 3rd level or lower. (Phase 11)"},
|
||
{ID: "fly", Name: "Fly", Level: 3, School: "transmutation",
|
||
Classes: mage, Effect: EffectBuffAlly, CastTime: CastAction,
|
||
Concentration: true,
|
||
Description: "Target gains 60 ft fly speed. 10 min."},
|
||
{ID: "hypnotic_pattern", Name: "Hypnotic Pattern", Level: 3, School: "illusion",
|
||
Classes: mage, Effect: EffectControl, CastTime: CastAction,
|
||
Concentration: true, SaveStat: "WIS", AOE: true,
|
||
Description: "Creatures in 30 ft cube: Incapacitated, speed 0."},
|
||
{ID: "dispel_magic", Name: "Dispel Magic", Level: 3, School: "abjuration",
|
||
Classes: mageCleric, Effect: EffectUtility, CastTime: CastAction,
|
||
Description: "End one magical effect on target."},
|
||
{ID: "slow", Name: "Slow", Level: 3, School: "transmutation",
|
||
Classes: mage, Effect: EffectControl, CastTime: CastAction,
|
||
Concentration: true, SaveStat: "WIS", AOE: true,
|
||
Description: "Up to 6 targets: halve speed, -2 AC, no reactions."},
|
||
{ID: "animate_dead", Name: "Animate Dead", Level: 3, School: "necromancy",
|
||
Classes: mageCleric, Effect: EffectUtility, CastTime: CastAction,
|
||
Description: "Animate up to 3 corpses as skeletons/zombies. 24 hr."},
|
||
|
||
// ── 3rd level — Cleric ────────────────────────────────────────────────
|
||
{ID: "spirit_guardians", Name: "Spirit Guardians", Level: 3, School: "conjuration",
|
||
Classes: cleric, Effect: EffectDamageSave, CastTime: CastAction,
|
||
Concentration: true, SaveStat: "WIS", DamageDice: "3d8",
|
||
DamageType: "radiant", AOE: true,
|
||
Description: "15 ft aura: 3d8/turn to enemies. WIS save half.",
|
||
Upcast: "+1d8 per slot above 3rd"},
|
||
{ID: "revivify", Name: "Revivify", Level: 3, School: "necromancy",
|
||
Classes: cleric, Effect: EffectUtility, CastTime: CastAction,
|
||
MaterialCost: 300,
|
||
Description: "Restore a creature dead <1 min to 1 HP. 300-coin diamond."},
|
||
{ID: "mass_healing_word", Name: "Mass Healing Word", Level: 3, School: "evocation",
|
||
Classes: cleric, Effect: EffectSpellHeal, CastTime: CastBonusAction,
|
||
DamageDice: "1d4",
|
||
Description: "Up to 6 targets: 1d4 + WIS mod HP."},
|
||
{ID: "beacon_of_hope", Name: "Beacon of Hope", Level: 3, School: "abjuration",
|
||
Classes: cleric, Effect: EffectBuffAlly, CastTime: CastAction,
|
||
Concentration: true,
|
||
Description: "Targets have advantage on WIS saves and death saves; max healing."},
|
||
{ID: "remove_curse", Name: "Remove Curse", Level: 3, School: "abjuration",
|
||
Classes: cleric, Effect: EffectUtility, CastTime: CastAction,
|
||
Description: "End one curse on target or object."},
|
||
|
||
// ── 3rd level — Ranger ────────────────────────────────────────────────
|
||
{ID: "lightning_arrow", Name: "Lightning Arrow", Level: 3, School: "transmutation",
|
||
Classes: ranger, Effect: EffectDamageSave, CastTime: CastBonusAction,
|
||
SaveStat: "DEX", DamageDice: "4d8", DamageType: "lightning", AOE: true,
|
||
Description: "Ranged: 4d8 lightning on hit; 2d8 to creatures within 10 ft."},
|
||
{ID: "conjure_barrage", Name: "Conjure Barrage", Level: 3, School: "conjuration",
|
||
Classes: ranger, Effect: EffectDamageSave, CastTime: CastAction,
|
||
SaveStat: "DEX", DamageDice: "3d8", DamageType: "varies", AOE: true,
|
||
Description: "3d8 of weapon type in 60 ft cone. DEX save half."},
|
||
{ID: "water_walk", Name: "Water Walk", Level: 3, School: "transmutation",
|
||
Classes: ranger, Effect: EffectUtility, CastTime: CastRitual,
|
||
Description: "Up to 10 targets walk on liquid surfaces. 1 hr."},
|
||
{ID: "plant_growth", Name: "Plant Growth", Level: 3, School: "transmutation",
|
||
Classes: ranger, Effect: EffectUtility, CastTime: CastAction,
|
||
Description: "100 ft difficult terrain; or enhance crops."},
|
||
{ID: "nondetection", Name: "Nondetection", Level: 3, School: "abjuration",
|
||
Classes: ranger, Effect: EffectUtility, CastTime: CastAction,
|
||
Description: "Target undetectable by divination magic. 8 hr."},
|
||
|
||
// ── 4th level (Mage / Cleric) ─────────────────────────────────────────
|
||
{ID: "banishment", Name: "Banishment", Level: 4, School: "abjuration",
|
||
Classes: cleric, Effect: EffectControl, CastTime: CastAction,
|
||
Concentration: true, SaveStat: "CHA",
|
||
Description: "Send extraplanar creature to home plane temporarily."},
|
||
{ID: "polymorph", Name: "Polymorph", Level: 4, School: "transmutation",
|
||
Classes: mage, Effect: EffectControl, CastTime: CastAction,
|
||
Concentration: true, SaveStat: "WIS",
|
||
Description: "Transform target into beast. Max CR = target's level."},
|
||
{ID: "ice_storm", Name: "Ice Storm", Level: 4, School: "evocation",
|
||
Classes: mage, Effect: EffectDamageSave, CastTime: CastAction,
|
||
SaveStat: "DEX", DamageDice: "6d6", DamageType: "cold", AOE: true,
|
||
Description: "2d8 bludgeoning + 4d6 cold in 20 ft cylinder."},
|
||
{ID: "wall_of_fire", Name: "Wall of Fire", Level: 4, School: "evocation",
|
||
Classes: mage, Effect: EffectDamageSave, CastTime: CastAction,
|
||
Concentration: true, SaveStat: "DEX", DamageDice: "5d8",
|
||
DamageType: "fire", AOE: true,
|
||
Description: "60 ft wall; 5d8 fire to those passing through."},
|
||
{ID: "greater_invisibility", Name: "Greater Invisibility", Level: 4, School: "illusion",
|
||
Classes: mage, Effect: EffectBuffSelf, CastTime: CastAction,
|
||
Concentration: true,
|
||
Description: "Target invisible; attacks have advantage; can't be targeted. 1 min."},
|
||
{ID: "guardian_of_faith", Name: "Guardian of Faith", Level: 4, School: "conjuration",
|
||
Classes: cleric, Effect: EffectBuffSelf, CastTime: CastAction,
|
||
Description: "Spectral guardian deals 20 radiant to approaching enemies."},
|
||
{ID: "death_ward", Name: "Death Ward", Level: 4, School: "abjuration",
|
||
Classes: cleric, Effect: EffectBuffAlly, CastTime: CastAction,
|
||
Description: "Next time target would drop to 0 HP: drops to 1 instead. 8 hr."},
|
||
{ID: "freedom_of_movement", Name: "Freedom of Movement", Level: 4, School: "abjuration",
|
||
Classes: clericRanger, Effect: EffectBuffAlly, CastTime: CastAction,
|
||
Description: "Target ignores Difficult terrain, paralysis, restraint. 1 hr."},
|
||
|
||
// ── 5th level (Mage / Cleric) ─────────────────────────────────────────
|
||
{ID: "cone_of_cold", Name: "Cone of Cold", Level: 5, School: "evocation",
|
||
Classes: mage, Effect: EffectDamageSave, CastTime: CastAction,
|
||
SaveStat: "CON", DamageDice: "8d8", DamageType: "cold", AOE: true,
|
||
Description: "8d8 cold in 60 ft cone. CON save half.",
|
||
Upcast: "+1d8 per slot above 5th"},
|
||
{ID: "hold_monster", Name: "Hold Monster", Level: 5, School: "enchantment",
|
||
Classes: mage, Effect: EffectControl, CastTime: CastAction,
|
||
Concentration: true, SaveStat: "WIS",
|
||
Description: "Paralyze any creature type."},
|
||
{ID: "wall_of_force", Name: "Wall of Force", Level: 5, School: "evocation",
|
||
Classes: mage, Effect: EffectBuffSelf, CastTime: CastAction,
|
||
Concentration: true,
|
||
Description: "Invisible impenetrable wall."},
|
||
{ID: "scrying", Name: "Scrying", Level: 5, School: "divination",
|
||
Classes: mageCleric, Effect: EffectUtility, CastTime: CastAction,
|
||
Concentration: true, SaveStat: "WIS",
|
||
Description: "Observe target at any distance."},
|
||
{ID: "mass_cure_wounds", Name: "Mass Cure Wounds", Level: 5, School: "evocation",
|
||
Classes: cleric, Effect: EffectSpellHeal, CastTime: CastAction,
|
||
DamageDice: "3d8",
|
||
Description: "Up to 6 targets: 3d8 + WIS mod HP."},
|
||
{ID: "flame_strike", Name: "Flame Strike", Level: 5, School: "evocation",
|
||
Classes: cleric, Effect: EffectDamageSave, CastTime: CastAction,
|
||
SaveStat: "DEX", DamageDice: "8d6", DamageType: "fire", AOE: true,
|
||
Description: "4d6 fire + 4d6 radiant in 10 ft cylinder."},
|
||
{ID: "divine_word", Name: "Divine Word", Level: 5, School: "evocation",
|
||
Classes: cleric, Effect: EffectControl, CastTime: CastBonusAction,
|
||
SaveStat: "WIS",
|
||
Description: "Targets suffer effects based on HP. Kills below 20 HP."},
|
||
{ID: "raise_dead", Name: "Raise Dead", Level: 5, School: "necromancy",
|
||
Classes: cleric, Effect: EffectUtility, CastTime: CastAction,
|
||
MaterialCost: 500,
|
||
Description: "Restore a creature dead up to 10 days. 500-coin diamond."},
|
||
}
|
||
}
|