UX S3: SRD copy-edit pass — sanitize jargon + curated overrides

Plumbed through the open5e importer so regen stays safe:

- New cmd/open5e-import/desc_overrides.go holds two per-ID override
  maps (spellDescOverride, magicItemDescOverride) and a regex-driven
  cleanDesc sanitizer. Override wins outright; otherwise the SRD
  first-sentence runs through cleanDesc, which strips the phrases
  the S3 acceptance criteria forbid (saving throw[s], spell slot,
  within range, 5-foot, DC <n>, "(save DC X)" parentheticals,
  "constitution score is N", "out to a range of N feet"). A small
  post-pass repairs the orphan stubs the strippers leave behind
  (" and." trailers, "must make." after the saving-throw object
  is gone).

- gen.go (spells) + magicitems.go now call spellDescription /
  magicItemDescription instead of raw firstSentence; same hand-
  authored override pattern, same cleanDesc fallthrough.

- Override coverage: the 19 SRD-only spells that show up in
  defaultKnownSpells (call_lightning, charm_person, vicious_mockery,
  …) plus ~35 high-visibility magic items (Amulet of Health, every
  Belt of Giant Strength variant, Cloak of Displacement, etc.).
  Tone is outcome-first second-person with bite — these surface
  in the spellbook and the curio shop, so they get to be funny.

- tuned.go (R21) + magicitems.go strip "(...)" from emitted Names
  via stripNameParenthetical. Slug keeps the variant; only the
  display text loses the qualifier. Two bestiary entries
  (giant_rat_diseased, deep_gnome_svirfneblin) and stone_of_good_luck
  affected.

- Regenerated all three data files. Acceptance grep is clean:
  zero hits for any banned phrase in Description/Desc fields.

- New cmd/open5e-import/desc_overrides_test.go covers the
  sanitizer regressions, orphan-repair, name-strip, and the
  override-wins-but-fallthrough-still-sanitizes path.

Conflicts: none. S4 (magic-item UX) wanted this in first so the
new curio renderer consumes clean text — ready for it now.
This commit is contained in:
prosolis
2026-05-14 21:53:06 -07:00
parent c48e12a296
commit 1512f6cc50
8 changed files with 474 additions and 169 deletions

View File

@@ -0,0 +1,152 @@
package main
import (
"regexp"
"strings"
)
// Description-cleaning hooks shared by the spell and magic-item generators.
//
// The Open5e dump descriptions are SRD prose pulled verbatim — they leak
// "within range," "WIS saving throw," "your Constitution score is 19," and
// other rules-text the game now hides. This file handles two layers:
//
// - A sanitizer (cleanDesc) strips the worst jargon clauses from the auto
// first-sentence and tidies the result. Used as the default path.
// - Per-ID override maps win outright when a description needs more than
// mechanical scrubbing (e.g. Amulet of Health's "score is 19," all of
// the Mage default-list cantrips). Hand-author here, not in the
// generated file — these survive a regen.
// spellDescOverride wins over the auto-derived first-sentence Description
// when the slug matches. Cover anything that surfaces in the player's
// spellbook listing (defaultKnownSpells) or the !spells available command.
//
// Tone target: outcome-first, second person, plain English. No DC, no slot
// jargon, no "within range." Match the voice already in dnd_spells_data.go.
var spellDescOverride = map[string]string{
// SRD-only spells that appear in defaultKnownSpells (no hand-authored
// overlay in dnd_spells_data.go). Sourced from the S3 surfaced-spells
// audit; each gives the player a one-line read of what it does, with
// just enough bite that the spellbook isn't a phone book.
"call_lightning": "Summon a sulking thundercloud, then ask it — politely — to drop a bolt on someone you dislike.",
"charm_person": "Sweet-talk a humanoid into treating you as their new favourite acquaintance. Wears off; they may notice.",
"conjure_animals": "Call up a posse of summoned beasts. They are very enthusiastic and only mostly trained.",
"eldritch_blast": "A beam of crackling otherworldly Whatever streaks at a target. Your patron's preferred greeting.",
"entangle": "The ground sprouts rude, grabby roots in a patch. Anyone caught looks undignified at best.",
"faerie_fire": "Outline targets in glittery light. They can't hide; you hit them more easily; they hate it.",
"fear": "Project a cone of pure dread. Brave folk turn and run; less brave folk were already running.",
"flaming_sphere": "A rolling ball of fire shows up and goes wherever you point. Carpet not included.",
"haste": "An ally surges with speed — extra ground, sharper defences, an extra swing. Brief, glorious, exhausting.",
"healing_word": "Bark a healing syllable across the battlefield. An ally finds themselves slightly less dead.",
"heat_metal": "Their weapon, their armour, their belt buckle — glowing red-hot. Hard to grip. Worse to wear.",
"heroism": "An ally takes courage. No fear, more grit, slightly insufferable battle cries.",
"hideous_laughter": "Target collapses in a fit of unstoppable giggling. Awkward for them, very funny for you.",
"insect_plague": "A swarm of biting locusts boils up in an area. Everyone inside has Opinions about it.",
"invisibility": "An ally fades from sight. Lasts until they attack, cast, or yell something dramatic.",
"produce_flame": "A flame springs to your palm. Use it as a torch, or sling it at someone. Multipurpose.",
"ray_of_frost": "A freezing beam catches a target and leaves them sluggish, frosted, and visibly cross.",
"vampiric_touch": "Drain life from a target. The damage you deal patches you up. Frowned upon at parties.",
"vicious_mockery": "Hurl an insult so cutting it physically hurts. Their next swing wobbles in shame.",
// Hand-authored overlay descriptions in dnd_spells_data.go are the
// canonical text and win at registry merge time, so they don't need
// entries here. If a spell ever moves out of buildSpellList(), add it
// above.
}
// magicItemDescOverride wins over the auto-derived Desc when the slug
// matches. Priority targets: items the plan called out by name (Amulet of
// Health, Belt of Giant Strength) and any item whose SRD blurb leaks rules
// math or names a spell the player can't cast.
var magicItemDescOverride = map[string]string{
"amulet_of_health": "Hums against your collarbone and quietly upgrades your constitution to 'bothersome to kill.'",
"belt_of_giant_strength_hill": "Buckle it on; suddenly you can deadlift the bartender. Hill-giant grade.",
"belt_of_giant_strength_stone": "Buckle it on; the floor creaks where you weren't standing yesterday. Stone-giant grade.",
"belt_of_giant_strength_frost": "Buckle it on; doors come off their hinges when you knock politely. Frost-giant grade.",
"belt_of_giant_strength_fire": "Buckle it on; furniture rearranges itself to be elsewhere. Fire-giant grade.",
"belt_of_giant_strength_cloud": "Buckle it on; you arm-wrestle siege engines for fun. Cloud-giant grade.",
"belt_of_giant_strength_storm": "Buckle it on; the world feels strangely flimsy. Storm-giant grade.",
"belt_of_hill_giant_strength": "Buckle it on; suddenly you can deadlift the bartender. Hill-giant grade.",
"belt_of_stone_giant_strength": "Buckle it on; the floor creaks where you weren't standing yesterday. Stone-giant grade.",
"belt_of_frost_giant_strength": "Buckle it on; doors come off their hinges when you knock politely. Frost-giant grade.",
"belt_of_fire_giant_strength": "Buckle it on; furniture rearranges itself to be elsewhere. Fire-giant grade.",
"belt_of_cloud_giant_strength": "Buckle it on; you arm-wrestle siege engines for fun. Cloud-giant grade.",
"belt_of_storm_giant_strength": "Buckle it on; the world feels strangely flimsy. Storm-giant grade.",
"belt_of_dwarvenkind": "A stout dwarven belt — beard not included, hardiness very much included.",
"boots_of_levitation": "Float upward at will. Down is a separate problem you'll figure out later.",
"boots_of_speed": "Click the heels together; the world starts moving at a polite walking pace.",
"boots_of_striding_and_springing": "Tireless stride and effortless hops. Ceilings: now optional.",
"boots_of_the_winterlands": "Snow doesn't slow you, cold doesn't bite, and your tracks tactfully erase themselves.",
"bracers_of_archery": "Steady your bow arm — your arrows hit harder and find seams in armour they shouldn't.",
"bracers_of_defense": "Light bracers that quietly turn aside blows. No armour required, no questions asked.",
"brooch_of_shielding": "Pinned to your cloak. Eats incoming bolts of force like they're hors d'oeuvres.",
"cloak_of_displacement": "Bends light around you. Attackers keep swinging at where you obviously are, and missing.",
"cloak_of_elvenkind": "Pulls shadows around you whether you asked or not. Watchful eyes slide right off.",
"cloak_of_protection": "A perfectly ordinary travelling cloak that perfectly extraordinarily refuses to let you get hit.",
"cloak_of_resistance": "Wards off one kind of harm — fire, frost, lightning, poison, or some other unpleasant Tuesday.",
"cloak_of_the_bat": "By night you glide instead of fall; on a really good night, you fly. Daytime: just a cloak.",
"cloak_of_the_manta_ray": "Underwater, you swim like a manta and breathe like you're on land. On land, you look damp.",
"gauntlets_of_ogre_power": "Heavy gauntlets that lend you an ogre's strength and an ogre's complete disregard for door frames.",
"headband_of_intellect": "Slips on, makes you think clever thoughts you have no business thinking. People notice.",
"ring_of_protection": "A plain ring. Quietly turns aside blows you'd otherwise take. Refuses to explain how.",
"ring_of_regeneration": "Wounds knit themselves back together while you wear it. Slowly. Smugly.",
"ring_of_resistance": "Wards off one kind of harm — fire, frost, lightning, poison, or another flavour of bad day.",
"ring_of_swimming": "Slip through water faster than any swimmer should. Dolphins file complaints.",
"ring_of_warmth": "Cold weather no longer applies to you. Chill damage softens; you become unbearable in winter.",
"slippers_of_spider_climbing": "Walk up walls and across ceilings as if the floor were merely a suggestion.",
}
// cleanDesc strips the worst SRD jargon from a description before it lands in
// the generated file. It is intentionally conservative: drop offending phrases,
// collapse the resulting whitespace, leave the rest of the sentence alone. Any
// description that still reads poorly after this pass should get a hand-authored
// entry in spellDescOverride / magicItemDescOverride above.
func cleanDesc(s string) string {
if s == "" {
return s
}
for _, pat := range descScrub {
s = pat.ReplaceAllString(s, "")
}
// Collapse runs of whitespace and tidy stray punctuation orphans left
// behind by deletions ("a creature and ", " , ", " .").
s = reSpaces.ReplaceAllString(s, " ")
s = strings.ReplaceAll(s, " ,", ",")
s = strings.ReplaceAll(s, " .", ".")
s = strings.ReplaceAll(s, "( )", "")
// Repair sentence stubs left by clause-strippers — "...must make." after
// the saving-throw object is gone, or trailing " and." where one half of
// a coordinated noun phrase was removed. These are conservative: they
// only fire when the orphan sits at end-of-sentence.
s = reOrphanMustMake.ReplaceAllString(s, "$1")
s = reOrphanTrailingAnd.ReplaceAllString(s, ".")
s = strings.TrimSpace(s)
return s
}
var (
reSpaces = regexp.MustCompile(`\s+`)
reOrphanMustMake = regexp.MustCompile(`(?i)\s+must\s+(?:make|succeed on|attempt)([.,;])`)
reOrphanTrailingAnd = regexp.MustCompile(`(?i),?\s+and\.`)
descScrub = []*regexp.Regexp{
// Range / distance jargon.
regexp.MustCompile(`(?i)\s*\bwithin range\b`),
regexp.MustCompile(`(?i)\s*\bwithin \d+ feet(?: of [a-z ]+?)?`),
regexp.MustCompile(`(?i)\s+\d+-foot[- ](?:radius|cone|cube|line|sphere|square)`),
regexp.MustCompile(`(?i)\s+(?:out to a range of\s*)?\d+ feet\b`),
regexp.MustCompile(`(?i)\s+out to a range of\b`),
// Save / DC / slot jargon.
regexp.MustCompile(`(?i)\s*\b(?:Strength|Dexterity|Constitution|Intelligence|Wisdom|Charisma)\s+saving throws?\b`),
regexp.MustCompile(`(?i)\s*\bsaving throws?\b`),
regexp.MustCompile(`(?i)\s*\(save(?:\s+DC\s*\d+)?\)`),
regexp.MustCompile(`(?i)\s*\bDC\s*\d+\b`),
regexp.MustCompile(`(?i)\s*\b(?:using|cast(?:ing)?(?: it)? with) a spell slot of \d+(?:st|nd|rd|th) level or higher\b`),
regexp.MustCompile(`(?i)\s*\bspell slot\b`),
// Cross-references and stat-block leakage.
regexp.MustCompile(`(?i)\s*\bsee the spell\b`),
regexp.MustCompile(`(?i)\s*\b(?:wisdom|strength|dexterity|constitution|intelligence|charisma)\s+save\b`),
regexp.MustCompile(`(?i)\s*\b(?:wisdom|strength|dexterity|constitution|intelligence|charisma)\s+score\s+is\s+\d+\b`),
regexp.MustCompile(`(?i)\s*\bconstitution score\b`),
}
)

View File

@@ -0,0 +1,122 @@
package main
import (
"strings"
"testing"
)
// TestCleanDescStripsJargon — the S3 acceptance criteria translated into
// regression cases. Any phrase listed here must not survive the sanitizer.
func TestCleanDescStripsJargon(t *testing.T) {
cases := []struct {
name string
in string
mustNot []string
}{
{
name: "saving throw + DC",
in: "Each creature in the area must make a Dexterity saving throw (DC 15) or take damage.",
mustNot: []string{
"saving throw", "DC 15", "DC15",
},
},
{
name: "saving throws plural",
in: "You have advantage on saving throws against spells.",
mustNot: []string{"saving throws"},
},
{
name: "within range",
in: "Hurl a bolt at a creature within range.",
mustNot: []string{"within range"},
},
{
name: "5-foot radius",
in: "Each creature in a 5-foot radius takes damage.",
mustNot: []string{"5-foot"},
},
{
name: "spell slot upcast clause",
in: "When you cast this spell using a spell slot of 2nd level or higher, the damage increases.",
mustNot: []string{"spell slot"},
},
{
name: "constitution score",
in: "Your Constitution score is 19 while you wear this amulet.",
mustNot: []string{"Constitution score"},
},
{
name: "(save DC X) parenthetical",
in: "You can use an action to cast the detect thoughts spell (save DC 13) from it.",
mustNot: []string{"(save", "DC 13"},
},
{
name: "wisdom save",
in: "Forces a wisdom save against the caster.",
mustNot: []string{"wisdom save"},
},
{
name: "out to a range of feet",
in: "You have darkvision out to a range of 60 feet.",
mustNot: []string{"feet", "out to a range"},
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
got := cleanDesc(tc.in)
low := strings.ToLower(got)
for _, ban := range tc.mustNot {
if strings.Contains(low, strings.ToLower(ban)) {
t.Errorf("cleanDesc kept banned phrase %q\n in: %q\n out: %q", ban, tc.in, got)
}
}
})
}
}
// TestCleanDescRepairsOrphans — the strippers leave dangling stubs ("must
// make.", " and."); the post-pass is meant to tidy them so player-facing
// prose doesn't end mid-clause.
func TestCleanDescRepairsOrphans(t *testing.T) {
in := "You gain a +1 bonus to ability checks and saving throws."
got := cleanDesc(in)
if strings.HasSuffix(got, " and.") {
t.Errorf("orphan trailing 'and.' survived: %q", got)
}
in2 := "Up to three creatures of your choice that you can see must make charisma saving throws."
got2 := cleanDesc(in2)
if strings.Contains(strings.ToLower(got2), "must make.") {
t.Errorf("orphan 'must make.' survived: %q", got2)
}
}
// TestStripNameParenthetical — bestiary R21 / magic-item alias names.
func TestStripNameParenthetical(t *testing.T) {
cases := map[string]string{
"Giant Rat (Diseased)": "Giant Rat",
"Deep Gnome (Svirfneblin)": "Deep Gnome",
"Stone of Good Luck (Luckstone)": "Stone of Good Luck",
"Ordinary Name": "Ordinary Name",
"": "",
}
for in, want := range cases {
if got := stripNameParenthetical(in); got != want {
t.Errorf("stripNameParenthetical(%q) = %q, want %q", in, got, want)
}
}
}
// TestSpellOverrideWins — the curated descriptions for the SRD-only default
// spells must beat the auto first-sentence path.
func TestSpellOverrideWins(t *testing.T) {
got := spellDescription("vicious_mockery", "anything could go here")
if got != spellDescOverride["vicious_mockery"] {
t.Errorf("override didn't win: got %q", got)
}
// Unknown ID falls through to cleanDesc.
in := "Hurl a bolt at a creature within range."
got = spellDescription("unknown_spell_xyz", in)
if strings.Contains(got, "within range") {
t.Errorf("fallthrough didn't sanitize: %q", got)
}
}

View File

@@ -142,7 +142,7 @@ func classify(s open5eSpell, classes []string) genSpell {
School: strings.ToLower(strings.TrimSpace(s.School)),
Classes: classes,
Concentration: s.RequiresConcentration,
Description: firstSentence(desc, 200),
Description: spellDescription(strings.ReplaceAll(s.Slug, "-", "_"), desc),
Upcast: firstSentence(strings.TrimSpace(s.HigherLevel), 200),
AOE: looksAOE(low),
}
@@ -240,6 +240,16 @@ func looksAOE(low string) bool {
return false
}
// spellDescription returns the description text emitted for a spell. A
// hand-authored override in spellDescOverride wins outright; otherwise the
// SRD first-sentence is run through cleanDesc to strip jargon clauses.
func spellDescription(id, raw string) string {
if s, ok := spellDescOverride[id]; ok {
return s
}
return firstSentence(cleanDesc(raw), 200)
}
// firstSentence trims free-text fields down to a single sentence, capped at
// max runes, so generated Description/Upcast stay terminal-friendly.
func firstSentence(s string, max int) string {

View File

@@ -171,9 +171,9 @@ func genMagicItems() error {
func classifyMagicItem(m open5eMagicItem) genMagicItem {
g := genMagicItem{
ID: strings.ReplaceAll(m.Slug, "-", "_"),
Name: m.Name,
Name: stripNameParenthetical(m.Name),
Attunement: strings.TrimSpace(m.RequiresAttunement) != "",
Desc: firstSentence(strings.TrimSpace(m.Desc), 200),
Desc: magicItemDescription(strings.ReplaceAll(m.Slug, "-", "_"), strings.TrimSpace(m.Desc)),
}
rarity := strings.ToLower(strings.TrimSpace(m.Rarity))
@@ -250,6 +250,15 @@ func inferSlot(kind, name string) string {
return ""
}
// magicItemDescription returns the Desc text emitted for an item. Override
// wins; otherwise the SRD first-sentence runs through cleanDesc.
func magicItemDescription(id, raw string) string {
if s, ok := magicItemDescOverride[id]; ok {
return s
}
return firstSentence(cleanDesc(raw), 200)
}
// ── Code emission ────────────────────────────────────────────────────────────
func emitMagicItems(items []genMagicItem) []byte {

View File

@@ -96,7 +96,7 @@ func tuneMonster(b genStatBlock) genTunedMonster {
ability := abilityFromTraits(b.Traits)
return genTunedMonster{
ID: b.Slug,
Name: b.Name,
Name: stripNameParenthetical(b.Name),
CR: b.CR,
HP: b.HP,
AC: ac,
@@ -110,6 +110,18 @@ func tuneMonster(b genStatBlock) genTunedMonster {
}
}
// stripNameParenthetical drops a trailing "(…)" qualifier from a monster
// name so the player-facing display reads "Giant Rat" rather than "Giant Rat
// (Diseased)". The slug still carries the variant, so the engine keeps both
// records distinct — only the display text loses the qualifier.
func stripNameParenthetical(name string) string {
i := strings.IndexByte(name, '(')
if i <= 0 {
return name
}
return strings.TrimSpace(name[:i])
}
// traitAbilityRules maps SRD special-ability names onto the engine's
// MonsterAbility effects. Each rule's Match list holds lowercase substrings; a
// creature's trait matches a rule if any substring is contained in the

View File

@@ -50,7 +50,7 @@ func buildTunedBestiarySRD() map[string]DnDMonsterTemplate {
"flying_snake": {ID: "flying_snake", Name: "Flying Snake", CR: 0.125, HP: 5, AC: 14, Attack: 1, AttackBonus: 0, Speed: 12, BlockRate: 0.05, XPValue: 25, Ability: &MonsterAbility{Name: "Evasive", Phase: "any", ProcChance: 0.3, Effect: "evade"}, Notes: "SRD-tuned baseline — Evasive (evade) wired from traits. Traits: Flyby"},
"giant_crab": {ID: "giant_crab", Name: "Giant Crab", CR: 0.125, HP: 13, AC: 15, Attack: 1, AttackBonus: 3, Speed: 12, BlockRate: 0.1, XPValue: 25, Notes: "SRD-tuned baseline — no ability wired (traits are non-combat). Traits: Amphibious"},
"giant_rat": {ID: "giant_rat", Name: "Giant Rat", CR: 0.125, HP: 7, AC: 12, Attack: 1, AttackBonus: 4, Speed: 12, BlockRate: 0, XPValue: 25, Ability: &MonsterAbility{Name: "Pack Tactics", Phase: "any", ProcChance: 0.3, Effect: "advantage"}, Notes: "SRD-tuned baseline — Pack Tactics (advantage) wired from traits. Traits: Keen Smell, Pack Tactics"},
"giant_rat_diseased": {ID: "giant_rat_diseased", Name: "Giant Rat (Diseased)", CR: 0.125, HP: 7, AC: 12, Attack: 1, AttackBonus: 4, Speed: 12, BlockRate: 0, XPValue: 25, Notes: "SRD-tuned baseline — no ability wired (traits are non-combat)."},
"giant_rat_diseased": {ID: "giant_rat_diseased", Name: "Giant Rat", CR: 0.125, HP: 7, AC: 12, Attack: 1, AttackBonus: 4, Speed: 12, BlockRate: 0, XPValue: 25, Notes: "SRD-tuned baseline — no ability wired (traits are non-combat)."},
"giant_weasel": {ID: "giant_weasel", Name: "Giant Weasel", CR: 0.125, HP: 9, AC: 13, Attack: 1, AttackBonus: 5, Speed: 16, BlockRate: 0.05, XPValue: 25, Notes: "SRD-tuned baseline — no ability wired (traits are non-combat). Traits: Keen Hearing and Smell"},
"guard": {ID: "guard", Name: "Guard", CR: 0.125, HP: 11, AC: 16, Attack: 1, AttackBonus: 3, Speed: 12, BlockRate: 0.1, XPValue: 25, Notes: "SRD-tuned baseline — no ability wired (traits are non-combat)."},
"kobold": {ID: "kobold", Name: "Kobold", CR: 0.125, HP: 5, AC: 12, Attack: 1, AttackBonus: 4, Speed: 12, BlockRate: 0, XPValue: 25, Ability: &MonsterAbility{Name: "Pack Tactics", Phase: "any", ProcChance: 0.3, Effect: "advantage"}, Notes: "SRD-tuned baseline — Pack Tactics (advantage) wired from traits. Traits: Sunlight Sensitivity, Pack Tactics"},
@@ -99,7 +99,7 @@ func buildTunedBestiarySRD() map[string]DnDMonsterTemplate {
"cockatrice": {ID: "cockatrice", Name: "Cockatrice", CR: 0.5, HP: 27, AC: 11, Attack: 2, AttackBonus: 3, Speed: 8, BlockRate: 0, XPValue: 100, Notes: "SRD-tuned baseline — no ability wired (traits are non-combat)."},
"crocodile": {ID: "crocodile", Name: "Crocodile", CR: 0.5, HP: 19, AC: 12, Attack: 2, AttackBonus: 4, Speed: 8, BlockRate: 0, XPValue: 100, Notes: "SRD-tuned baseline — no ability wired (traits are non-combat). Traits: Hold Breath"},
"darkmantle": {ID: "darkmantle", Name: "Darkmantle", CR: 0.5, HP: 22, AC: 11, Attack: 2, AttackBonus: 5, Speed: 6, BlockRate: 0, XPValue: 100, Notes: "SRD-tuned baseline — no ability wired (traits are non-combat). Traits: Echolocation, False Appearance"},
"deep_gnome_svirfneblin": {ID: "deep_gnome_svirfneblin", Name: "Deep Gnome (Svirfneblin)", CR: 0.5, HP: 16, AC: 15, Attack: 2, AttackBonus: 4, Speed: 8, BlockRate: 0.1, XPValue: 100, Ability: &MonsterAbility{Name: "Spellcasting", Phase: "opening", ProcChance: 0.5, Effect: "aoe"}, Notes: "SRD-tuned baseline — Spellcasting (aoe) wired from traits. Traits: Stone Camouflage, Gnome Cunning, Innate Spellcasting"},
"deep_gnome_svirfneblin": {ID: "deep_gnome_svirfneblin", Name: "Deep Gnome", CR: 0.5, HP: 16, AC: 15, Attack: 2, AttackBonus: 4, Speed: 8, BlockRate: 0.1, XPValue: 100, Ability: &MonsterAbility{Name: "Spellcasting", Phase: "opening", ProcChance: 0.5, Effect: "aoe"}, Notes: "SRD-tuned baseline — Spellcasting (aoe) wired from traits. Traits: Stone Camouflage, Gnome Cunning, Innate Spellcasting"},
"dust_mephit": {ID: "dust_mephit", Name: "Dust Mephit", CR: 0.5, HP: 17, AC: 12, Attack: 2, AttackBonus: 4, Speed: 12, BlockRate: 0, XPValue: 100, Ability: &MonsterAbility{Name: "Death Burst", Phase: "decisive", ProcChance: 1, Effect: "death_aoe"}, Notes: "SRD-tuned baseline — Death Burst (death_aoe) wired from traits. Traits: Death Burst, Innate Spellcasting (1/Day)"},
"giant_goat": {ID: "giant_goat", Name: "Giant Goat", CR: 0.5, HP: 19, AC: 11, Attack: 2, AttackBonus: 5, Speed: 16, BlockRate: 0, XPValue: 100, Ability: &MonsterAbility{Name: "Charge", Phase: "opening", ProcChance: 0.4, Effect: "bonus_damage"}, Notes: "SRD-tuned baseline — Charge (bonus_damage) wired from traits. Traits: Charge, Sure-Footed"},
"giant_sea_horse": {ID: "giant_sea_horse", Name: "Giant Sea Horse", CR: 0.5, HP: 16, AC: 13, Attack: 2, AttackBonus: 3, Speed: 16, BlockRate: 0.05, XPValue: 100, Ability: &MonsterAbility{Name: "Charge", Phase: "opening", ProcChance: 0.4, Effect: "bonus_damage"}, Notes: "SRD-tuned baseline — Charge (bonus_damage) wired from traits. Traits: Charge, Water Breathing"},

View File

@@ -15,61 +15,61 @@ package plugin
func buildSRDSpellList() []SpellDefinition {
return []SpellDefinition{
{ID: "acid_splash", Name: "Acid Splash", Level: 0, School: "conjuration", Classes: []DnDClass{ClassMage, ClassSorcerer}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "1d6", DamageType: "acid", Description: "You hurl a bubble of acid.", Upcast: "This spell's damage increases by 1d6 when you reach 5th level (2d6), 11th level (3d6), and 17th level (4d6)."},
{ID: "chill_touch", Name: "Chill Touch", Level: 0, School: "necromancy", Classes: []DnDClass{ClassMage, ClassSorcerer, ClassWarlock}, Effect: EffectDamageAttack, CastTime: CastAction, AttackRoll: true, DamageDice: "1d8", DamageType: "necrotic", Description: "You create a ghostly, skeletal hand in the space of a creature within range.", Upcast: "This spell's damage increases by 1d8 when you reach 5th level (2d8), 11th level (3d8), and 17th level (4d8)."},
{ID: "dancing_lights", Name: "Dancing Lights", Level: 0, School: "evocation", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You create up to four torch-sized lights within range, making them appear as torches, lanterns, or glowing orbs that hover in the air for the duration.", AOE: true},
{ID: "druidcraft", Name: "Druidcraft", Level: 0, School: "transmutation", Classes: []DnDClass{ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Description: "Whispering to the spirits of nature, you create one of the following effects within range:", AOE: true},
{ID: "eldritch_blast", Name: "Eldritch Blast", Level: 0, School: "evocation", Classes: []DnDClass{ClassWarlock}, Effect: EffectDamageAttack, CastTime: CastAction, AttackRoll: true, DamageDice: "1d10", DamageType: "force", Description: "A beam of crackling energy streaks toward a creature within range."},
{ID: "fire_bolt", Name: "Fire Bolt", Level: 0, School: "evocation", Classes: []DnDClass{ClassMage, ClassSorcerer}, Effect: EffectDamageAttack, CastTime: CastAction, AttackRoll: true, DamageDice: "1d10", DamageType: "fire", Description: "You hurl a mote of fire at a creature or object within range.", Upcast: "This spell's damage increases by 1d10 when you reach 5th level (2d10), 11th level (3d10), and 17th level (4d10)."},
{ID: "chill_touch", Name: "Chill Touch", Level: 0, School: "necromancy", Classes: []DnDClass{ClassMage, ClassSorcerer, ClassWarlock}, Effect: EffectDamageAttack, CastTime: CastAction, AttackRoll: true, DamageDice: "1d8", DamageType: "necrotic", Description: "You create a ghostly, skeletal hand in the space of a creature.", Upcast: "This spell's damage increases by 1d8 when you reach 5th level (2d8), 11th level (3d8), and 17th level (4d8)."},
{ID: "dancing_lights", Name: "Dancing Lights", Level: 0, School: "evocation", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You create up to four torch-sized lights, making them appear as torches, lanterns, or glowing orbs that hover in the air for the duration.", AOE: true},
{ID: "druidcraft", Name: "Druidcraft", Level: 0, School: "transmutation", Classes: []DnDClass{ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Description: "Whispering to the spirits of nature, you create one of the following effects: - You create a tiny, harmless sensory effect that predicts what the weather will be at your location for the next 24 hours…", AOE: true},
{ID: "eldritch_blast", Name: "Eldritch Blast", Level: 0, School: "evocation", Classes: []DnDClass{ClassWarlock}, Effect: EffectDamageAttack, CastTime: CastAction, AttackRoll: true, DamageDice: "1d10", DamageType: "force", Description: "A beam of crackling otherworldly Whatever streaks at a target. Your patron's preferred greeting."},
{ID: "fire_bolt", Name: "Fire Bolt", Level: 0, School: "evocation", Classes: []DnDClass{ClassMage, ClassSorcerer}, Effect: EffectDamageAttack, CastTime: CastAction, AttackRoll: true, DamageDice: "1d10", DamageType: "fire", Description: "You hurl a mote of fire at a creature or object.", Upcast: "This spell's damage increases by 1d10 when you reach 5th level (2d10), 11th level (3d10), and 17th level (4d10)."},
{ID: "guidance", Name: "Guidance", Level: 0, School: "divination", Classes: []DnDClass{ClassCleric, ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You touch one willing creature."},
{ID: "light", Name: "Light", Level: 0, School: "evocation", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Description: "You touch one object that is no larger than 10 feet in any dimension.", AOE: true},
{ID: "mage_hand", Name: "Mage Hand", Level: 0, School: "conjuration", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectBuffSelf, CastTime: CastAction, Description: "A spectral, floating hand appears at a point you choose within range."},
{ID: "light", Name: "Light", Level: 0, School: "evocation", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Description: "You touch one object that is no larger than in any dimension.", AOE: true},
{ID: "mage_hand", Name: "Mage Hand", Level: 0, School: "conjuration", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectBuffSelf, CastTime: CastAction, Description: "A spectral, floating hand appears at a point you choose."},
{ID: "mending", Name: "Mending", Level: 0, School: "transmutation", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassBard, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Description: "This spell repairs a single break or tear in an object you touch, such as a broken key, a torn cloak, or a leaking wineskin."},
{ID: "message", Name: "Message", Level: 0, School: "transmutation", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Description: "You point your finger toward a creature within range and whisper a message."},
{ID: "minor_illusion", Name: "Minor Illusion", Level: 0, School: "illusion", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Description: "You create a sound or an image of an object within range that lasts for the duration.", AOE: true},
{ID: "poison_spray", Name: "Poison Spray", Level: 0, School: "conjuration", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer, ClassWarlock}, Effect: EffectDamageSave, CastTime: CastAction, SaveStat: "CON", DamageDice: "1d12", DamageType: "poison", Description: "You extend your hand toward a creature you can see within range and project a puff of noxious gas from your palm.", Upcast: "This spell's damage increases by 1d12 when you reach 5th level (2d12), 11th level (3d12), and 17th level (4d12)."},
{ID: "message", Name: "Message", Level: 0, School: "transmutation", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Description: "You point your finger toward a creature and whisper a message."},
{ID: "minor_illusion", Name: "Minor Illusion", Level: 0, School: "illusion", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Description: "You create a sound or an image of an object that lasts for the duration.", AOE: true},
{ID: "poison_spray", Name: "Poison Spray", Level: 0, School: "conjuration", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer, ClassWarlock}, Effect: EffectDamageSave, CastTime: CastAction, SaveStat: "CON", DamageDice: "1d12", DamageType: "poison", Description: "You extend your hand toward a creature you can see and project a puff of noxious gas from your palm.", Upcast: "This spell's damage increases by 1d12 when you reach 5th level (2d12), 11th level (3d12), and 17th level (4d12)."},
{ID: "prestidigitation", Name: "Prestidigitation", Level: 0, School: "transmutation", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Description: "This spell is a minor magical trick that novice spellcasters use for practice."},
{ID: "produce_flame", Name: "Produce Flame", Level: 0, School: "conjuration", Classes: []DnDClass{ClassDruid}, Effect: EffectDamageAttack, CastTime: CastAction, AttackRoll: true, DamageDice: "1d8", DamageType: "fire", Description: "A flickering flame appears in your hand.", Upcast: "This spell's damage increases by 1d8 when you reach 5th level (2d8), 11th level (3d8), and 17th level (4d8).", AOE: true},
{ID: "ray_of_frost", Name: "Ray of Frost", Level: 0, School: "evocation", Classes: []DnDClass{ClassMage, ClassSorcerer}, Effect: EffectDamageAttack, CastTime: CastAction, AttackRoll: true, DamageDice: "1d8", DamageType: "cold", Description: "A frigid beam of blue-white light streaks toward a creature within range.", Upcast: "The spell's damage increases by 1d8 when you reach 5th level (2d8), 11th level (3d8), and 17th level (4d8)."},
{ID: "produce_flame", Name: "Produce Flame", Level: 0, School: "conjuration", Classes: []DnDClass{ClassDruid}, Effect: EffectDamageAttack, CastTime: CastAction, AttackRoll: true, DamageDice: "1d8", DamageType: "fire", Description: "A flame springs to your palm. Use it as a torch, or sling it at someone. Multipurpose.", Upcast: "This spell's damage increases by 1d8 when you reach 5th level (2d8), 11th level (3d8), and 17th level (4d8).", AOE: true},
{ID: "ray_of_frost", Name: "Ray of Frost", Level: 0, School: "evocation", Classes: []DnDClass{ClassMage, ClassSorcerer}, Effect: EffectDamageAttack, CastTime: CastAction, AttackRoll: true, DamageDice: "1d8", DamageType: "cold", Description: "A freezing beam catches a target and leaves them sluggish, frosted, and visibly cross.", Upcast: "The spell's damage increases by 1d8 when you reach 5th level (2d8), 11th level (3d8), and 17th level (4d8)."},
{ID: "resistance", Name: "Resistance", Level: 0, School: "abjuration", Classes: []DnDClass{ClassCleric, ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You touch one willing creature."},
{ID: "sacred_flame", Name: "Sacred Flame", Level: 0, School: "evocation", Classes: []DnDClass{ClassCleric}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "1d8", DamageType: "radiant", Description: "Flame-like radiance descends on a creature that you can see within range.", Upcast: "The spell's damage increases by 1d8 when you reach 5th level (2d8), 11th level (3d8), and 17th level (4d8)."},
{ID: "sacred_flame", Name: "Sacred Flame", Level: 0, School: "evocation", Classes: []DnDClass{ClassCleric}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "1d8", DamageType: "radiant", Description: "Flame-like radiance descends on a creature that you can see.", Upcast: "The spell's damage increases by 1d8 when you reach 5th level (2d8), 11th level (3d8), and 17th level (4d8)."},
{ID: "shillelagh", Name: "Shillelagh", Level: 0, School: "transmutation", Classes: []DnDClass{ClassDruid}, Effect: EffectUtility, CastTime: CastBonusAction, Description: "The wood of a club or a quarterstaff you are holding is imbued with nature's power."},
{ID: "shocking_grasp", Name: "Shocking Grasp", Level: 0, School: "evocation", Classes: []DnDClass{ClassMage, ClassSorcerer}, Effect: EffectDamageAttack, CastTime: CastAction, AttackRoll: true, DamageDice: "1d8", DamageType: "lightning", Description: "Lightning springs from your hand to deliver a shock to a creature you try to touch.", Upcast: "The spell's damage increases by 1d8 when you reach 5th level (2d8), 11th level (3d8), and 17th level (4d8)."},
{ID: "spare_the_dying", Name: "Spare the Dying", Level: 0, School: "necromancy", Classes: []DnDClass{ClassCleric}, Effect: EffectUtility, CastTime: CastAction, Description: "You touch a living creature that has 0 hit points."},
{ID: "thaumaturgy", Name: "Thaumaturgy", Level: 0, School: "transmutation", Classes: []DnDClass{ClassCleric}, Effect: EffectUtility, CastTime: CastAction, Description: "You manifest a minor wonder, a sign of supernatural power, within range."},
{ID: "thaumaturgy", Name: "Thaumaturgy", Level: 0, School: "transmutation", Classes: []DnDClass{ClassCleric}, Effect: EffectUtility, CastTime: CastAction, Description: "You manifest a minor wonder, a sign of supernatural power,."},
{ID: "true_strike", Name: "True Strike", Level: 0, School: "divination", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectBuffSelf, CastTime: CastAction, Concentration: true, Description: "You extend your hand and point a finger at a target in range."},
{ID: "vicious_mockery", Name: "Vicious Mockery", Level: 0, School: "enchantment", Classes: []DnDClass{ClassBard}, Effect: EffectDamageSave, CastTime: CastAction, SaveStat: "WIS", DamageDice: "1d4", DamageType: "psychic", Description: "You unleash a string of insults laced with subtle enchantments at a creature you can see within range.", Upcast: "This spell's damage increases by 1d4 when you reach 5th level (2d4), 11th level (3d4), and 17th level (4d4)."},
{ID: "vicious_mockery", Name: "Vicious Mockery", Level: 0, School: "enchantment", Classes: []DnDClass{ClassBard}, Effect: EffectDamageSave, CastTime: CastAction, SaveStat: "WIS", DamageDice: "1d4", DamageType: "psychic", Description: "Hurl an insult so cutting it physically hurts. Their next swing wobbles in shame.", Upcast: "This spell's damage increases by 1d4 when you reach 5th level (2d4), 11th level (3d4), and 17th level (4d4)."},
{ID: "alarm", Name: "Alarm", Level: 1, School: "abjuration", Classes: []DnDClass{ClassMage, ClassRanger}, Effect: EffectUtility, CastTime: CastRitual, Description: "You set an alarm against unwanted intrusion.", AOE: true},
{ID: "animal_friendship", Name: "Animal Friendship", Level: 1, School: "enchantment", Classes: []DnDClass{ClassRanger, ClassDruid, ClassBard}, Effect: EffectControl, CastTime: CastAction, SaveStat: "WIS", Description: "This spell lets you convince a beast that you mean it no harm.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, you can affect one additional beast for each slot level above 1st."},
{ID: "bane", Name: "Bane", Level: 1, School: "enchantment", Classes: []DnDClass{ClassCleric, ClassBard, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "Up to three creatures of your choice that you can see within range must make charisma saving throws.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, you can target one additional creature for each slot level above 1st."},
{ID: "bless", Name: "Bless", Level: 1, School: "enchantment", Classes: []DnDClass{ClassCleric, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You bless up to three creatures of your choice within range.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, you can target one additional creature for each slot level above 1st."},
{ID: "bane", Name: "Bane", Level: 1, School: "enchantment", Classes: []DnDClass{ClassCleric, ClassBard, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "Up to three creatures of your choice that you can see.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, you can target one additional creature for each slot level above 1st."},
{ID: "bless", Name: "Bless", Level: 1, School: "enchantment", Classes: []DnDClass{ClassCleric, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You bless up to three creatures of your choice.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, you can target one additional creature for each slot level above 1st."},
{ID: "burning_hands", Name: "Burning Hands", Level: 1, School: "evocation", Classes: []DnDClass{ClassMage, ClassCleric, ClassSorcerer, ClassWarlock}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "3d6", DamageType: "fire", Description: "As you hold your hands with thumbs touching and fingers spread, a thin sheet of flames shoots forth from your outstretched fingertips.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, the damage increases by 1d6 for each slot level above 1st.", AOE: true},
{ID: "charm_person", Name: "Charm Person", Level: 1, School: "enchantment", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Description: "You attempt to charm a humanoid you can see within range.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, you can target one additional creature for each slot level above 1st."},
{ID: "charm_person", Name: "Charm Person", Level: 1, School: "enchantment", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Description: "Sweet-talk a humanoid into treating you as their new favourite acquaintance. Wears off; they may notice.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, you can target one additional creature for each slot level above 1st."},
{ID: "color_spray", Name: "Color Spray", Level: 1, School: "illusion", Classes: []DnDClass{ClassMage, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Description: "A dazzling array of flashing, colored light springs from your hand.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, roll an additional 2d10 for each slot level above 1st.", AOE: true},
{ID: "command", Name: "Command", Level: 1, School: "enchantment", Classes: []DnDClass{ClassCleric, ClassWarlock, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Description: "You speak a one-word command to a creature you can see within range.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, you can affect one additional creature for each slot level above 1st."},
{ID: "command", Name: "Command", Level: 1, School: "enchantment", Classes: []DnDClass{ClassCleric, ClassWarlock, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Description: "You speak a one-word command to a creature you can see.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, you can affect one additional creature for each slot level above 1st."},
{ID: "comprehend_languages", Name: "Comprehend Languages", Level: 1, School: "divination", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastRitual, Description: "For the duration, you understand the literal meaning of any spoken language that you hear."},
{ID: "create_or_destroy_water", Name: "Create or Destroy Water", Level: 1, School: "transmutation", Classes: []DnDClass{ClassCleric, ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Description: "You either create or destroy water.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, you create or destroy 10 additional gallons of water, or the size of the cube increases by 5 feet, for each slot level above 1st.", AOE: true},
{ID: "cure_wounds", Name: "Cure Wounds", Level: 1, School: "evocation", Classes: []DnDClass{ClassCleric, ClassRanger, ClassDruid, ClassBard, ClassPaladin}, Effect: EffectSpellHeal, CastTime: CastAction, DamageDice: "1d8", Description: "A creature you touch regains a number of hit points equal to 1d8 + your spellcasting ability modifier.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, the healing increases by 1d8 for each slot level above 1st."},
{ID: "detect_evil_and_good", Name: "Detect Evil and Good", Level: 1, School: "divination", Classes: []DnDClass{ClassCleric, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "For the duration, you know if there is an aberration, celestial, elemental, fey, fiend, or undead within 30 feet of you, as well as where the creature is located."},
{ID: "detect_magic", Name: "Detect Magic", Level: 1, School: "divination", Classes: []DnDClass{ClassMage, ClassCleric, ClassRanger, ClassDruid, ClassBard, ClassSorcerer, ClassPaladin}, Effect: EffectBuffSelf, CastTime: CastRitual, Concentration: true, Description: "For the duration, you sense the presence of magic within 30 feet of you."},
{ID: "detect_poison_and_disease", Name: "Detect Poison and Disease", Level: 1, School: "divination", Classes: []DnDClass{ClassCleric, ClassRanger, ClassDruid, ClassPaladin}, Effect: EffectUtility, CastTime: CastRitual, Concentration: true, Description: "For the duration, you can sense the presence and location of poisons, poisonous creatures, and diseases within 30 feet of you."},
{ID: "detect_evil_and_good", Name: "Detect Evil and Good", Level: 1, School: "divination", Classes: []DnDClass{ClassCleric, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "For the duration, you know if there is an aberration, celestial, elemental, fey, fiend, or undeadou, as well as where the creature is located."},
{ID: "detect_magic", Name: "Detect Magic", Level: 1, School: "divination", Classes: []DnDClass{ClassMage, ClassCleric, ClassRanger, ClassDruid, ClassBard, ClassSorcerer, ClassPaladin}, Effect: EffectBuffSelf, CastTime: CastRitual, Concentration: true, Description: "For the duration, you sense the presence of magicou."},
{ID: "detect_poison_and_disease", Name: "Detect Poison and Disease", Level: 1, School: "divination", Classes: []DnDClass{ClassCleric, ClassRanger, ClassDruid, ClassPaladin}, Effect: EffectUtility, CastTime: CastRitual, Concentration: true, Description: "For the duration, you can sense the presence and location of poisons, poisonous creatures, and diseasesou."},
{ID: "disguise_self", Name: "Disguise Self", Level: 1, School: "illusion", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard, ClassSorcerer}, Effect: EffectBuffSelf, CastTime: CastAction, Description: "You make yourself - including your clothing, armor, weapons, and other belongings on your person - look different until the spell ends or until you use your action to dismiss it."},
{ID: "divine_favor", Name: "Divine Favor", Level: 1, School: "evocation", Classes: []DnDClass{ClassCleric, ClassPaladin}, Effect: EffectDamageAuto, CastTime: CastBonusAction, Concentration: true, DamageDice: "1d4", DamageType: "radiant", Description: "Your prayer empowers you with divine radiance."},
{ID: "entangle", Name: "Entangle", Level: 1, School: "conjuration", Classes: []DnDClass{ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "Grasping weeds and vines sprout from the ground in a 20-foot square starting form a point within range."},
{ID: "entangle", Name: "Entangle", Level: 1, School: "conjuration", Classes: []DnDClass{ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "The ground sprouts rude, grabby roots in a patch. Anyone caught looks undignified at best."},
{ID: "expeditious_retreat", Name: "Expeditious Retreat", Level: 1, School: "transmutation", Classes: []DnDClass{ClassMage, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastBonusAction, Concentration: true, Description: "This spell allows you to move at an incredible pace."},
{ID: "faerie_fire", Name: "Faerie Fire", Level: 1, School: "evocation", Classes: []DnDClass{ClassCleric, ClassDruid, ClassBard, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "Each object in a 20-foot cube within range is outlined in blue, green, or violet light (your choice).", AOE: true},
{ID: "faerie_fire", Name: "Faerie Fire", Level: 1, School: "evocation", Classes: []DnDClass{ClassCleric, ClassDruid, ClassBard, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "Outline targets in glittery light. They can't hide; you hit them more easily; they hate it.", AOE: true},
{ID: "false_life", Name: "False Life", Level: 1, School: "necromancy", Classes: []DnDClass{ClassMage, ClassSorcerer}, Effect: EffectBuffSelf, CastTime: CastAction, DamageDice: "1d4+4", Description: "Bolstering yourself with a necromantic facsimile of life, you gain 1d4 + 4 temporary hit points for the duration.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, you gain 5 additional temporary hit points for each slot level above 1st."},
{ID: "feather_fall", Name: "Feather Fall", Level: 1, School: "transmutation", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer}, Effect: EffectReaction, CastTime: CastReaction, Description: "Choose up to five falling creatures within range."},
{ID: "feather_fall", Name: "Feather Fall", Level: 1, School: "transmutation", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer}, Effect: EffectReaction, CastTime: CastReaction, Description: "Choose up to five falling creatures."},
{ID: "find_familiar", Name: "Find Familiar", Level: 1, School: "conjuration", Classes: []DnDClass{ClassMage}, Effect: EffectBuffSelf, CastTime: CastRitual, Description: "You gain the service of a familiar, a spirit that takes an animal form you choose: bat, cat, crab, frog (toad), hawk, lizard, octopus, owl, poisonous snake, fish (quipper), rat, raven, sea horse, spid…"},
{ID: "floating_disk", Name: "Floating Disk", Level: 1, School: "conjuration", Classes: []DnDClass{ClassMage}, Effect: EffectUtility, CastTime: CastRitual, Description: "This spell creates a circular, horizontal plane of force, 3 feet in diameter and 1 inch thick, that floats 3 feet above the ground in an unoccupied space of your choice that you can see within range."},
{ID: "fog_cloud", Name: "Fog Cloud", Level: 1, School: "conjuration", Classes: []DnDClass{ClassMage, ClassCleric, ClassRanger, ClassDruid, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You create a 20-foot-radius sphere of fog centered on a point within range.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, the radius of the fog increases by 20 feet for each slot level above 1st.", AOE: true},
{ID: "floating_disk", Name: "Floating Disk", Level: 1, School: "conjuration", Classes: []DnDClass{ClassMage}, Effect: EffectUtility, CastTime: CastRitual, Description: "This spell creates a circular, horizontal plane of force, in diameter and 1 inch thick, that floats above the ground in an unoccupied space of your choice that you can see."},
{ID: "fog_cloud", Name: "Fog Cloud", Level: 1, School: "conjuration", Classes: []DnDClass{ClassMage, ClassCleric, ClassRanger, ClassDruid, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You create a sphere of fog centered on a point.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, the radius of the fog increases by 20 feet for each slot level above 1st.", AOE: true},
{ID: "goodberry", Name: "Goodberry", Level: 1, School: "transmutation", Classes: []DnDClass{ClassRanger, ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Description: "Up to ten berries appear in your hand and are infused with magic for the duration."},
{ID: "grease", Name: "Grease", Level: 1, School: "conjuration", Classes: []DnDClass{ClassMage}, Effect: EffectUtility, CastTime: CastAction, Description: "Slick grease covers the ground in a 10-foot square centered on a point within range and turns it into difficult terrain for the duration.", AOE: true},
{ID: "guiding_bolt", Name: "Guiding Bolt", Level: 1, School: "evocation", Classes: []DnDClass{ClassCleric}, Effect: EffectDamageAttack, CastTime: CastAction, AttackRoll: true, DamageDice: "4d6", DamageType: "radiant", Description: "A flash of light streaks toward a creature of your choice within range.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, the damage increases by 1d6 for each slot level above 1st."},
{ID: "healing_word", Name: "Healing Word", Level: 1, School: "evocation", Classes: []DnDClass{ClassCleric, ClassDruid, ClassBard}, Effect: EffectSpellHeal, CastTime: CastBonusAction, DamageDice: "1d4", Description: "A creature of your choice that you can see within range regains hit points equal to 1d4 + your spellcasting ability modifier.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, the healing increases by 1d4 for each slot level above 1st."},
{ID: "grease", Name: "Grease", Level: 1, School: "conjuration", Classes: []DnDClass{ClassMage}, Effect: EffectUtility, CastTime: CastAction, Description: "Slick grease covers the ground in a centered on a point and turns it into difficult terrain for the duration.", AOE: true},
{ID: "guiding_bolt", Name: "Guiding Bolt", Level: 1, School: "evocation", Classes: []DnDClass{ClassCleric}, Effect: EffectDamageAttack, CastTime: CastAction, AttackRoll: true, DamageDice: "4d6", DamageType: "radiant", Description: "A flash of light streaks toward a creature of your choice.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, the damage increases by 1d6 for each slot level above 1st."},
{ID: "healing_word", Name: "Healing Word", Level: 1, School: "evocation", Classes: []DnDClass{ClassCleric, ClassDruid, ClassBard}, Effect: EffectSpellHeal, CastTime: CastBonusAction, DamageDice: "1d4", Description: "Bark a healing syllable across the battlefield. An ally finds themselves slightly less dead.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, the healing increases by 1d4 for each slot level above 1st."},
{ID: "hellish_rebuke", Name: "Hellish Rebuke", Level: 1, School: "evocation", Classes: []DnDClass{ClassWarlock, ClassPaladin}, Effect: EffectReaction, CastTime: CastReaction, SaveStat: "DEX", Description: "You point your finger, and the creature that damaged you is momentarily surrounded by hellish flames.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, the damage increases by 1d10 for each slot level above 1st."},
{ID: "heroism", Name: "Heroism", Level: 1, School: "enchantment", Classes: []DnDClass{ClassBard, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "A willing creature you touch is imbued with bravery."},
{ID: "hideous_laughter", Name: "Hideous Laughter", Level: 1, School: "enchantment", Classes: []DnDClass{ClassMage, ClassBard, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "A creature of your choice that you can see within range perceives everything as hilariously funny and falls into fits of laughter if this spell affects it."},
{ID: "hunters_mark", Name: "Hunter's Mark", Level: 1, School: "divination", Classes: []DnDClass{ClassRanger, ClassPaladin}, Effect: EffectUtility, CastTime: CastBonusAction, Concentration: true, Description: "You choose a creature you can see within range and mystically mark it as your quarry.", Upcast: "When you cast this spell using a spell slot of 3rd or 4th level, you can maintain your concentration on the spell for up to 8 hours."},
{ID: "heroism", Name: "Heroism", Level: 1, School: "enchantment", Classes: []DnDClass{ClassBard, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "An ally takes courage. No fear, more grit, slightly insufferable battle cries."},
{ID: "hideous_laughter", Name: "Hideous Laughter", Level: 1, School: "enchantment", Classes: []DnDClass{ClassMage, ClassBard, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "Target collapses in a fit of unstoppable giggling. Awkward for them, very funny for you."},
{ID: "hunters_mark", Name: "Hunter's Mark", Level: 1, School: "divination", Classes: []DnDClass{ClassRanger, ClassPaladin}, Effect: EffectUtility, CastTime: CastBonusAction, Concentration: true, Description: "You choose a creature you can see and mystically mark it as your quarry.", Upcast: "When you cast this spell using a spell slot of 3rd or 4th level, you can maintain your concentration on the spell for up to 8 hours."},
{ID: "identify", Name: "Identify", Level: 1, School: "divination", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard}, Effect: EffectUtility, CastTime: CastRitual, Description: "You choose one object that you must touch throughout the casting of the spell.", MaterialCost: 100},
{ID: "illusory_script", Name: "Illusory Script", Level: 1, School: "illusion", Classes: []DnDClass{ClassMage, ClassBard, ClassWarlock}, Effect: EffectUtility, CastTime: CastRitual, Description: "You write on parchment, paper, or some other suitable writing material and imbue it with a potent illusion that lasts for the duration.", MaterialCost: 10},
{ID: "inflict_wounds", Name: "Inflict Wounds", Level: 1, School: "necromancy", Classes: []DnDClass{ClassCleric}, Effect: EffectDamageAttack, CastTime: CastAction, AttackRoll: true, DamageDice: "3d10", DamageType: "necrotic", Description: "Make a melee spell attack against a creature you can reach.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, the damage increases by 1d10 for each slot level above 1st."},
@@ -78,16 +78,16 @@ func buildSRDSpellList() []SpellDefinition {
{ID: "mage_armor", Name: "Mage Armor", Level: 1, School: "abjuration", Classes: []DnDClass{ClassMage, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Description: "You touch a willing creature who isn't wearing armor, and a protective magical force surrounds it until the spell ends."},
{ID: "magic_missile", Name: "Magic Missile", Level: 1, School: "evocation", Classes: []DnDClass{ClassMage, ClassSorcerer}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "1d4+1", DamageType: "force", Description: "You create three glowing darts of magical force.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, the spell creates one more dart for each slot level above 1st."},
{ID: "protection_from_evil_and_good", Name: "Protection from Evil and Good", Level: 1, School: "abjuration", Classes: []DnDClass{ClassMage, ClassCleric, ClassWarlock, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "Until the spell ends, one willing creature you touch is protected against certain types of creatures: aberrations, celestials, elementals, fey, fiends, and undead."},
{ID: "purify_food_and_drink", Name: "Purify Food and Drink", Level: 1, School: "transmutation", Classes: []DnDClass{ClassCleric, ClassDruid, ClassPaladin}, Effect: EffectUtility, CastTime: CastRitual, Description: "All nonmagical food and drink within a 5-foot radius sphere centered on a point of your choice within range is purified and rendered free of poison and disease.", AOE: true},
{ID: "sanctuary", Name: "Sanctuary", Level: 1, School: "abjuration", Classes: []DnDClass{ClassCleric, ClassPaladin}, Effect: EffectUtility, CastTime: CastBonusAction, Description: "You ward a creature within range against attack."},
{ID: "purify_food_and_drink", Name: "Purify Food and Drink", Level: 1, School: "transmutation", Classes: []DnDClass{ClassCleric, ClassDruid, ClassPaladin}, Effect: EffectUtility, CastTime: CastRitual, Description: "All nonmagical food and drink within a sphere centered on a point of your choice is purified and rendered free of poison and disease.", AOE: true},
{ID: "sanctuary", Name: "Sanctuary", Level: 1, School: "abjuration", Classes: []DnDClass{ClassCleric, ClassPaladin}, Effect: EffectUtility, CastTime: CastBonusAction, Description: "You ward a creature against attack."},
{ID: "shield", Name: "Shield", Level: 1, School: "abjuration", Classes: []DnDClass{ClassMage, ClassSorcerer}, Effect: EffectReaction, CastTime: CastReaction, Description: "An invisible barrier of magical force appears and protects you."},
{ID: "shield_of_faith", Name: "Shield of Faith", Level: 1, School: "abjuration", Classes: []DnDClass{ClassCleric, ClassPaladin}, Effect: EffectBuffAlly, CastTime: CastBonusAction, Concentration: true, Description: "A shimmering field appears and surrounds a creature of your choice within range, granting it a +2 bonus to AC for the duration."},
{ID: "silent_image", Name: "Silent Image", Level: 1, School: "illusion", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer}, Effect: EffectBuffSelf, CastTime: CastAction, Concentration: true, Description: "You create the image of an object, a creature, or some other visible phenomenon that is no larger than a 15-foot cube.", AOE: true},
{ID: "shield_of_faith", Name: "Shield of Faith", Level: 1, School: "abjuration", Classes: []DnDClass{ClassCleric, ClassPaladin}, Effect: EffectBuffAlly, CastTime: CastBonusAction, Concentration: true, Description: "A shimmering field appears and surrounds a creature of your choice, granting it a +2 bonus to AC for the duration."},
{ID: "silent_image", Name: "Silent Image", Level: 1, School: "illusion", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer}, Effect: EffectBuffSelf, CastTime: CastAction, Concentration: true, Description: "You create the image of an object, a creature, or some other visible phenomenon that is no larger than a.", AOE: true},
{ID: "sleep", Name: "Sleep", Level: 1, School: "enchantment", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Description: "This spell sends creatures into a magical slumber.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, roll an additional 2d8 for each slot level above 1st.", AOE: true},
{ID: "speak_with_animals", Name: "Speak with Animals", Level: 1, School: "divination", Classes: []DnDClass{ClassCleric, ClassRanger, ClassDruid, ClassBard, ClassPaladin}, Effect: EffectBuffSelf, CastTime: CastRitual, Description: "You gain the ability to comprehend and verbally communicate with beasts for the duration."},
{ID: "thunderwave", Name: "Thunderwave", Level: 1, School: "evocation", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassBard, ClassSorcerer}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "2d8", DamageType: "thunder", Description: "A wave of thunderous force sweeps out from you.", Upcast: "When you cast this spell using a spell slot of 2nd level or higher, the damage increases by 1d8 for each slot level above 1st.", AOE: true},
{ID: "unseen_servant", Name: "Unseen Servant", Level: 1, School: "conjuration", Classes: []DnDClass{ClassMage, ClassBard, ClassWarlock}, Effect: EffectUtility, CastTime: CastRitual, Description: "This spell creates an invisible, mindless, shapeless force that performs simple tasks at your command until the spell ends."},
{ID: "acid_arrow", Name: "Acid Arrow", Level: 2, School: "evocation", Classes: []DnDClass{ClassMage, ClassDruid}, Effect: EffectDamageAttack, CastTime: CastAction, AttackRoll: true, DamageDice: "4d4", DamageType: "acid", Description: "A shimmering green arrow streaks toward a target within range and bursts in a spray of acid.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, the damage (both initial and later) increases by 1d4 for each slot level above 2nd."},
{ID: "acid_arrow", Name: "Acid Arrow", Level: 2, School: "evocation", Classes: []DnDClass{ClassMage, ClassDruid}, Effect: EffectDamageAttack, CastTime: CastAction, AttackRoll: true, DamageDice: "4d4", DamageType: "acid", Description: "A shimmering green arrow streaks toward a target and bursts in a spray of acid.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, the damage (both initial and later) increases by 1d4 for each slot level above 2nd."},
{ID: "aid", Name: "Aid", Level: 2, School: "abjuration", Classes: []DnDClass{ClassCleric, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Description: "Your spell bolsters your allies with toughness and resolve.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, a target's hit points increase by an additional 5 for each slot level above 2nd."},
{ID: "alter_self", Name: "Alter Self", Level: 2, School: "transmutation", Classes: []DnDClass{ClassMage, ClassSorcerer}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "1d6", DamageType: "slashing", Description: "You assume a different form."},
{ID: "animal_messenger", Name: "Animal Messenger", Level: 2, School: "enchantment", Classes: []DnDClass{ClassRanger, ClassDruid, ClassBard}, Effect: EffectUtility, CastTime: CastRitual, Description: "By means of this spell, you use an animal to deliver a message.", Upcast: "If you cast this spell using a spell slot of 3nd level or higher, the duration of the spell increases by 48 hours for each slot level above 2nd."},
@@ -100,125 +100,125 @@ func buildSRDSpellList() []SpellDefinition {
{ID: "branding_smite", Name: "Branding Smite", Level: 2, School: "evocation", Classes: []DnDClass{ClassPaladin}, Effect: EffectDamageAuto, CastTime: CastBonusAction, Concentration: true, DamageDice: "2d6", DamageType: "radiant", Description: "The next time you hit a creature with a weapon attack before this spell ends, the weapon gleams with astral radiance as you strike.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, the extra damage increases by 1d6 for each slot level above 2nd.", AOE: true},
{ID: "calm_emotions", Name: "Calm Emotions", Level: 2, School: "enchantment", Classes: []DnDClass{ClassCleric, ClassBard, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You attempt to suppress strong emotions in a group of people.", AOE: true},
{ID: "continual_flame", Name: "Continual Flame", Level: 2, School: "evocation", Classes: []DnDClass{ClassMage, ClassCleric}, Effect: EffectUtility, CastTime: CastAction, Description: "A flame, equivalent in brightness to a torch, springs forth from an object that you touch.", MaterialCost: 50},
{ID: "darkness", Name: "Darkness", Level: 2, School: "evocation", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "Magical darkness spreads from a point you choose within range to fill a 15-foot-radius sphere for the duration.", AOE: true},
{ID: "darkness", Name: "Darkness", Level: 2, School: "evocation", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "Magical darkness spreads from a point you choose to fill a sphere for the duration.", AOE: true},
{ID: "darkvision", Name: "Darkvision", Level: 2, School: "transmutation", Classes: []DnDClass{ClassMage, ClassRanger, ClassDruid, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Description: "You touch a willing creature to grant it the ability to see in the dark."},
{ID: "detect_thoughts", Name: "Detect Thoughts", Level: 2, School: "divination", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectControl, CastTime: CastAction, Concentration: true, SaveStat: "WIS", Description: "For the duration, you can read the thoughts of certain creatures."},
{ID: "enhance_ability", Name: "Enhance Ability", Level: 2, School: "transmutation", Classes: []DnDClass{ClassCleric, ClassDruid, ClassBard, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You touch a creature and bestow upon it a magical enhancement.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, you can target one additional creature for each slot level above 2nd."},
{ID: "enlargereduce", Name: "Enlarge/Reduce", Level: 2, School: "transmutation", Classes: []DnDClass{ClassMage, ClassSorcerer}, Effect: EffectControl, CastTime: CastAction, Concentration: true, SaveStat: "CON", Description: "You cause a creature or an object you can see within range to grow larger or smaller for the duration."},
{ID: "enthrall", Name: "Enthrall", Level: 2, School: "enchantment", Classes: []DnDClass{ClassBard, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Description: "You weave a distracting string of words, causing creatures of your choice that you can see within range and that can hear you to make a wisdom saving throw."},
{ID: "enlargereduce", Name: "Enlarge/Reduce", Level: 2, School: "transmutation", Classes: []DnDClass{ClassMage, ClassSorcerer}, Effect: EffectControl, CastTime: CastAction, Concentration: true, SaveStat: "CON", Description: "You cause a creature or an object you can see to grow larger or smaller for the duration."},
{ID: "enthrall", Name: "Enthrall", Level: 2, School: "enchantment", Classes: []DnDClass{ClassBard, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Description: "You weave a distracting string of words, causing creatures of your choice that you can see and that can hear you to make a."},
{ID: "find_steed", Name: "Find Steed", Level: 2, School: "conjuration", Classes: []DnDClass{ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Description: "You summon a spirit that assumes the form of an unusually intelligent, strong, and loyal steed, creating a long-lasting bond with it."},
{ID: "find_traps", Name: "Find Traps", Level: 2, School: "divination", Classes: []DnDClass{ClassCleric, ClassRanger, ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Description: "You sense the presence of any trap within range that is within line of sight."},
{ID: "find_traps", Name: "Find Traps", Level: 2, School: "divination", Classes: []DnDClass{ClassCleric, ClassRanger, ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Description: "You sense the presence of any trap that is within line of sight."},
{ID: "flame_blade", Name: "Flame Blade", Level: 2, School: "evocation", Classes: []DnDClass{ClassDruid}, Effect: EffectDamageAttack, CastTime: CastBonusAction, Concentration: true, AttackRoll: true, DamageDice: "3d6", DamageType: "fire", Description: "You evoke a fiery blade in your free hand.", Upcast: "When you cast this spell using a spell slot of 4th level or higher, the damage increases by 1d6 for every two slot levels above 2nd.", AOE: true},
{ID: "flaming_sphere", Name: "Flaming Sphere", Level: 2, School: "conjuration", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "2d6", DamageType: "fire", Description: "A 5-foot-diameter sphere of fire appears in an unoccupied space of your choice within range and lasts for the duration.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, the damage increases by 1d6 for each slot level above 2nd.", AOE: true},
{ID: "flaming_sphere", Name: "Flaming Sphere", Level: 2, School: "conjuration", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "2d6", DamageType: "fire", Description: "A rolling ball of fire shows up and goes wherever you point. Carpet not included.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, the damage increases by 1d6 for each slot level above 2nd.", AOE: true},
{ID: "gentle_repose", Name: "Gentle Repose", Level: 2, School: "necromancy", Classes: []DnDClass{ClassMage, ClassCleric}, Effect: EffectUtility, CastTime: CastRitual, Description: "You touch a corpse or other remains."},
{ID: "gust_of_wind", Name: "Gust of Wind", Level: 2, School: "evocation", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "A line of strong wind 60 feet long and 10 feet wide blasts from you in a direction you choose for the spell's duration.", AOE: true},
{ID: "heat_metal", Name: "Heat Metal", Level: 2, School: "transmutation", Classes: []DnDClass{ClassDruid, ClassBard}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "2d8", DamageType: "fire", Description: "Choose a manufactured metal object, such as a metal weapon or a suit of heavy or medium metal armor, that you can see within range.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, the damage increases by 1d8 for each slot level above 2nd."},
{ID: "hold_person", Name: "Hold Person", Level: 2, School: "enchantment", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassBard, ClassSorcerer, ClassWarlock, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "Choose a humanoid that you can see within range.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, you can target one additional humanoid for each slot level above 2nd."},
{ID: "invisibility", Name: "Invisibility", Level: 2, School: "illusion", Classes: []DnDClass{ClassMage, ClassDruid, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "A creature you touch becomes invisible until the spell ends.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, you can target one additional creature for each slot level above 2nd."},
{ID: "knock", Name: "Knock", Level: 2, School: "transmutation", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Description: "Choose an object that you can see within range."},
{ID: "gust_of_wind", Name: "Gust of Wind", Level: 2, School: "evocation", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "A line of strong wind long and wide blasts from you in a direction you choose for the spell's duration.", AOE: true},
{ID: "heat_metal", Name: "Heat Metal", Level: 2, School: "transmutation", Classes: []DnDClass{ClassDruid, ClassBard}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "2d8", DamageType: "fire", Description: "Their weapon, their armour, their belt buckle — glowing red-hot. Hard to grip. Worse to wear.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, the damage increases by 1d8 for each slot level above 2nd."},
{ID: "hold_person", Name: "Hold Person", Level: 2, School: "enchantment", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassBard, ClassSorcerer, ClassWarlock, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "Choose a humanoid that you can see.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, you can target one additional humanoid for each slot level above 2nd."},
{ID: "invisibility", Name: "Invisibility", Level: 2, School: "illusion", Classes: []DnDClass{ClassMage, ClassDruid, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "An ally fades from sight. Lasts until they attack, cast, or yell something dramatic.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, you can target one additional creature for each slot level above 2nd."},
{ID: "knock", Name: "Knock", Level: 2, School: "transmutation", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Description: "Choose an object that you can see."},
{ID: "lesser_restoration", Name: "Lesser Restoration", Level: 2, School: "abjuration", Classes: []DnDClass{ClassCleric, ClassRanger, ClassDruid, ClassBard, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Description: "You touch a creature and can end either one disease or one condition afflicting it."},
{ID: "levitate", Name: "Levitate", Level: 2, School: "transmutation", Classes: []DnDClass{ClassMage, ClassSorcerer}, Effect: EffectBuffSelf, CastTime: CastAction, Concentration: true, Description: "One creature or object of your choice that you can see within range rises vertically, up to 20 feet, and remains suspended there for the duration."},
{ID: "levitate", Name: "Levitate", Level: 2, School: "transmutation", Classes: []DnDClass{ClassMage, ClassSorcerer}, Effect: EffectBuffSelf, CastTime: CastAction, Concentration: true, Description: "One creature or object of your choice that you can see rises vertically, up to, and remains suspended there for the duration."},
{ID: "locate_animals_or_plants", Name: "Locate Animals or Plants", Level: 2, School: "divination", Classes: []DnDClass{ClassRanger, ClassDruid, ClassBard}, Effect: EffectUtility, CastTime: CastRitual, Description: "Describe or name a specific kind of beast or plant."},
{ID: "locate_object", Name: "Locate Object", Level: 2, School: "divination", Classes: []DnDClass{ClassMage, ClassCleric, ClassRanger, ClassDruid, ClassBard, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "Describe or name an object that is familiar to you."},
{ID: "magic_mouth", Name: "Magic Mouth", Level: 2, School: "illusion", Classes: []DnDClass{ClassMage, ClassBard}, Effect: EffectUtility, CastTime: CastRitual, Description: "You implant a message within an object in range, a message that is uttered when a trigger condition is met.", MaterialCost: 10},
{ID: "magic_weapon", Name: "Magic Weapon", Level: 2, School: "transmutation", Classes: []DnDClass{ClassMage, ClassCleric, ClassPaladin}, Effect: EffectBuffAlly, CastTime: CastBonusAction, Concentration: true, Description: "You touch a nonmagical weapon.", Upcast: "When you cast this spell using a spell slot of 4th level or higher, the bonus increases to +2."},
{ID: "mirror_image", Name: "Mirror Image", Level: 2, School: "illusion", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassSorcerer, ClassWarlock}, Effect: EffectBuffSelf, CastTime: CastAction, DamageDice: "1d20", Description: "Three illusionary duplicates of yourself appear in your space."},
{ID: "misty_step", Name: "Misty Step", Level: 2, School: "conjuration", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer, ClassWarlock, ClassPaladin}, Effect: EffectUtility, CastTime: CastBonusAction, Description: "Briefly surrounded by silvery mist, you teleport up to 30 feet to an unoccupied space that you can see."},
{ID: "moonbeam", Name: "Moonbeam", Level: 2, School: "evocation", Classes: []DnDClass{ClassDruid, ClassPaladin}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "2d10", DamageType: "radiant", Description: "A silvery beam of pale light shines down in a 5-foot-radius, 40-foot-high cylinder centered on a point within range.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, the damage increases by 1d10 for each slot level above 2nd.", AOE: true},
{ID: "misty_step", Name: "Misty Step", Level: 2, School: "conjuration", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer, ClassWarlock, ClassPaladin}, Effect: EffectUtility, CastTime: CastBonusAction, Description: "Briefly surrounded by silvery mist, you teleport up to to an unoccupied space that you can see."},
{ID: "moonbeam", Name: "Moonbeam", Level: 2, School: "evocation", Classes: []DnDClass{ClassDruid, ClassPaladin}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "2d10", DamageType: "radiant", Description: "A silvery beam of pale light shines down in a, 40-foot-high cylinder centered on a point.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, the damage increases by 1d10 for each slot level above 2nd.", AOE: true},
{ID: "pass_without_trace", Name: "Pass without Trace", Level: 2, School: "abjuration", Classes: []DnDClass{ClassCleric, ClassRanger, ClassDruid}, Effect: EffectBuffAlly, CastTime: CastAction, Concentration: true, Description: "A veil of shadows and silence radiates from you, masking you and your companions from detection.", AOE: true},
{ID: "prayer_of_healing", Name: "Prayer of Healing", Level: 2, School: "evocation", Classes: []DnDClass{ClassCleric}, Effect: EffectSpellHeal, CastTime: CastAction, DamageDice: "2d8", Description: "Up to six creatures of your choice that you can see within range each regain hit points equal to 2d8 + your spellcasting ability modifier.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, the healing increases by 1d8 for each slot level above 2nd."},
{ID: "prayer_of_healing", Name: "Prayer of Healing", Level: 2, School: "evocation", Classes: []DnDClass{ClassCleric}, Effect: EffectSpellHeal, CastTime: CastAction, DamageDice: "2d8", Description: "Up to six creatures of your choice that you can see each regain hit points equal to 2d8 + your spellcasting ability modifier.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, the healing increases by 1d8 for each slot level above 2nd."},
{ID: "protection_from_poison", Name: "Protection from Poison", Level: 2, School: "abjuration", Classes: []DnDClass{ClassCleric, ClassRanger, ClassDruid, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Description: "You touch a creature."},
{ID: "ray_of_enfeeblement", Name: "Ray of Enfeeblement", Level: 2, School: "necromancy", Classes: []DnDClass{ClassMage, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, AttackRoll: true, Description: "A black beam of enervating energy springs from your finger toward a creature within range."},
{ID: "rope_trick", Name: "Rope Trick", Level: 2, School: "transmutation", Classes: []DnDClass{ClassMage}, Effect: EffectUtility, CastTime: CastAction, Description: "You touch a length of rope that is up to 60 feet long."},
{ID: "scorching_ray", Name: "Scorching Ray", Level: 2, School: "evocation", Classes: []DnDClass{ClassMage, ClassCleric, ClassSorcerer, ClassWarlock}, Effect: EffectDamageAttack, CastTime: CastAction, AttackRoll: true, DamageDice: "2d6", DamageType: "fire", Description: "You create three rays of fire and hurl them at targets within range.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, you create one additional ray for each slot level above 2nd."},
{ID: "ray_of_enfeeblement", Name: "Ray of Enfeeblement", Level: 2, School: "necromancy", Classes: []DnDClass{ClassMage, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, AttackRoll: true, Description: "A black beam of enervating energy springs from your finger toward a creature."},
{ID: "rope_trick", Name: "Rope Trick", Level: 2, School: "transmutation", Classes: []DnDClass{ClassMage}, Effect: EffectUtility, CastTime: CastAction, Description: "You touch a length of rope that is up to long."},
{ID: "scorching_ray", Name: "Scorching Ray", Level: 2, School: "evocation", Classes: []DnDClass{ClassMage, ClassCleric, ClassSorcerer, ClassWarlock}, Effect: EffectDamageAttack, CastTime: CastAction, AttackRoll: true, DamageDice: "2d6", DamageType: "fire", Description: "You create three rays of fire and hurl them at targets.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, you create one additional ray for each slot level above 2nd."},
{ID: "see_invisibility", Name: "See Invisibility", Level: 2, School: "divination", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Description: "For the duration of the spell, you see invisible creatures and objects as if they were visible, and you can see through Ethereal."},
{ID: "shatter", Name: "Shatter", Level: 2, School: "evocation", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectDamageSave, CastTime: CastAction, SaveStat: "CON", DamageDice: "3d8", DamageType: "thunder", Description: "A sudden loud ringing noise, painfully intense, erupts from a point of your choice within range.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, the damage increases by 1d8 for each slot level above 2nd.", AOE: true},
{ID: "silence", Name: "Silence", Level: 2, School: "illusion", Classes: []DnDClass{ClassCleric, ClassRanger, ClassDruid, ClassBard}, Effect: EffectUtility, CastTime: CastRitual, Concentration: true, Description: "For the duration, no sound can be created within or pass through a 20-foot-radius sphere centered on a point you choose within range.", AOE: true},
{ID: "shatter", Name: "Shatter", Level: 2, School: "evocation", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectDamageSave, CastTime: CastAction, SaveStat: "CON", DamageDice: "3d8", DamageType: "thunder", Description: "A sudden loud ringing noise, painfully intense, erupts from a point of your choice.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, the damage increases by 1d8 for each slot level above 2nd.", AOE: true},
{ID: "silence", Name: "Silence", Level: 2, School: "illusion", Classes: []DnDClass{ClassCleric, ClassRanger, ClassDruid, ClassBard}, Effect: EffectUtility, CastTime: CastRitual, Concentration: true, Description: "For the duration, no sound can be created within or pass through a sphere centered on a point you choose.", AOE: true},
{ID: "spider_climb", Name: "Spider Climb", Level: 2, School: "transmutation", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "Until the spell ends, one willing creature you touch gains the ability to move up, down, and across vertical surfaces and upside down along ceilings, while leaving its hands free."},
{ID: "spike_growth", Name: "Spike Growth", Level: 2, School: "transmutation", Classes: []DnDClass{ClassCleric, ClassRanger, ClassDruid}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "2d4", DamageType: "piercing", Description: "The ground in a 20-foot radius centered on a point within range twists and sprouts hard spikes and thorns.", AOE: true},
{ID: "spiritual_weapon", Name: "Spiritual Weapon", Level: 2, School: "evocation", Classes: []DnDClass{ClassCleric}, Effect: EffectDamageAttack, CastTime: CastBonusAction, AttackRoll: true, DamageDice: "1d8", DamageType: "force", Description: "You create a floating, spectral weapon within range that lasts for the duration or until you cast this spell again.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, the damage increases by 1d8 for every two slot levels above the 2nd."},
{ID: "suggestion", Name: "Suggestion", Level: 2, School: "enchantment", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You suggest a course of activity (limited to a sentence or two) and magically influence a creature you can see within range that can hear and understand you."},
{ID: "spike_growth", Name: "Spike Growth", Level: 2, School: "transmutation", Classes: []DnDClass{ClassCleric, ClassRanger, ClassDruid}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "2d4", DamageType: "piercing", Description: "The ground in a centered on a point twists and sprouts hard spikes and thorns.", AOE: true},
{ID: "spiritual_weapon", Name: "Spiritual Weapon", Level: 2, School: "evocation", Classes: []DnDClass{ClassCleric}, Effect: EffectDamageAttack, CastTime: CastBonusAction, AttackRoll: true, DamageDice: "1d8", DamageType: "force", Description: "You create a floating, spectral weapon that lasts for the duration or until you cast this spell again.", Upcast: "When you cast this spell using a spell slot of 3rd level or higher, the damage increases by 1d8 for every two slot levels above the 2nd."},
{ID: "suggestion", Name: "Suggestion", Level: 2, School: "enchantment", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You suggest a course of activity (limited to a sentence or two) and magically influence a creature you can see that can hear and understand you."},
{ID: "warding_bond", Name: "Warding Bond", Level: 2, School: "abjuration", Classes: []DnDClass{ClassCleric}, Effect: EffectBuffAlly, CastTime: CastAction, Description: "This spell wards a willing creature you touch and creates a mystic connection between you and the target until the spell ends.", MaterialCost: 50},
{ID: "web", Name: "Web", Level: 2, School: "conjuration", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "2d4", DamageType: "fire", Description: "You conjure a mass of thick, sticky webbing at a point of your choice within range.", AOE: true},
{ID: "zone_of_truth", Name: "Zone of Truth", Level: 2, School: "enchantment", Classes: []DnDClass{ClassCleric, ClassBard, ClassPaladin}, Effect: EffectControl, CastTime: CastAction, SaveStat: "CHA", Description: "You create a magical zone that guards against deception in a 15-foot-radius sphere centered on a point of your choice within range.", AOE: true},
{ID: "web", Name: "Web", Level: 2, School: "conjuration", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "2d4", DamageType: "fire", Description: "You conjure a mass of thick, sticky webbing at a point of your choice.", AOE: true},
{ID: "zone_of_truth", Name: "Zone of Truth", Level: 2, School: "enchantment", Classes: []DnDClass{ClassCleric, ClassBard, ClassPaladin}, Effect: EffectControl, CastTime: CastAction, SaveStat: "CHA", Description: "You create a magical zone that guards against deception in a sphere centered on a point of your choice.", AOE: true},
{ID: "animate_dead", Name: "Animate Dead", Level: 3, School: "necromancy", Classes: []DnDClass{ClassMage, ClassCleric}, Effect: EffectUtility, CastTime: CastAction, Description: "This spell creates an undead servant.", Upcast: "When you cast this spell using a spell slot of 4th level or higher, you animate or reassert control over two additional undead creatures for each slot level above 3rd."},
{ID: "beacon_of_hope", Name: "Beacon of Hope", Level: 3, School: "abjuration", Classes: []DnDClass{ClassCleric, ClassPaladin}, Effect: EffectSpellHeal, CastTime: CastAction, Concentration: true, Description: "This spell bestows hope and vitality."},
{ID: "bestow_curse", Name: "Bestow Curse", Level: 3, School: "necromancy", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "1d8", DamageType: "necrotic", Description: "You touch a creature, and that creature must succeed on a wisdom saving throw or become cursed for the duration of the spell.", Upcast: "If you cast this spell using a spell slot of 4th level or higher, the duration is concentration, up to 10 minutes."},
{ID: "bestow_curse", Name: "Bestow Curse", Level: 3, School: "necromancy", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "1d8", DamageType: "necrotic", Description: "You touch a creature, and that creature must succeed on a or become cursed for the duration of the spell.", Upcast: "If you cast this spell using a spell slot of 4th level or higher, the duration is concentration, up to 10 minutes."},
{ID: "blink", Name: "Blink", Level: 3, School: "transmutation", Classes: []DnDClass{ClassMage, ClassCleric, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Description: "Roll a d20 at the end of each of your turns for the duration of the spell."},
{ID: "call_lightning", Name: "Call Lightning", Level: 3, School: "conjuration", Classes: []DnDClass{ClassCleric, ClassDruid}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "3d10", DamageType: "lightning", Description: "A storm cloud appears in the shape of a cylinder that is 10 feet tall with a 60-foot radius, centered on a point you can see 100 feet directly above you.", Upcast: "When you cast this spell using a spell slot of 4th or higher level, the damage increases by 1d10 for each slot level above 3rd.", AOE: true},
{ID: "clairvoyance", Name: "Clairvoyance", Level: 3, School: "divination", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectBuffSelf, CastTime: CastAction, Concentration: true, Description: "You create an invisible sensor within range in a location familiar to you (a place you have visited or seen before) or in an obvious location that is unfamiliar to you (such as behind a door, around a…", MaterialCost: 100},
{ID: "conjure_animals", Name: "Conjure Animals", Level: 3, School: "conjuration", Classes: []DnDClass{ClassRanger, ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You summon fey spirits that take the form of beasts and appear in unoccupied spaces that you can see within range.", Upcast: "When you cast this spell using certain higher-level spell slots, you choose one of the summoning options above, and more creatures appear: twice as many with a 5th-level slot, three times as many with…"},
{ID: "call_lightning", Name: "Call Lightning", Level: 3, School: "conjuration", Classes: []DnDClass{ClassCleric, ClassDruid}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "3d10", DamageType: "lightning", Description: "Summon a sulking thundercloud, then ask it — politely — to drop a bolt on someone you dislike.", Upcast: "When you cast this spell using a spell slot of 4th or higher level, the damage increases by 1d10 for each slot level above 3rd.", AOE: true},
{ID: "clairvoyance", Name: "Clairvoyance", Level: 3, School: "divination", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectBuffSelf, CastTime: CastAction, Concentration: true, Description: "You create an invisible sensor in a location familiar to you (a place you have visited or seen before) or in an obvious location that is unfamiliar to you (such as behind a door, around a corner, or i…", MaterialCost: 100},
{ID: "conjure_animals", Name: "Conjure Animals", Level: 3, School: "conjuration", Classes: []DnDClass{ClassRanger, ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "Call up a posse of summoned beasts. They are very enthusiastic and only mostly trained.", Upcast: "When you cast this spell using certain higher-level spell slots, you choose one of the summoning options above, and more creatures appear: twice as many with a 5th-level slot, three times as many with…"},
{ID: "counterspell", Name: "Counterspell", Level: 3, School: "abjuration", Classes: []DnDClass{ClassMage, ClassSorcerer, ClassWarlock, ClassPaladin}, Effect: EffectReaction, CastTime: CastReaction, Description: "You attempt to interrupt a creature in the process of casting a spell.", Upcast: "When you cast this spell using a spell slot of 4th level or higher, the interrupted spell has no effect if its level is less than or equal to the level of the spell slot you used."},
{ID: "create_food_and_water", Name: "Create Food and Water", Level: 3, School: "conjuration", Classes: []DnDClass{ClassCleric, ClassDruid, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Description: "You create 45 pounds of food and 30 gallons of water on the ground or in containers within range, enough to sustain up to fifteen humanoids or five steeds for 24 hours."},
{ID: "daylight", Name: "Daylight", Level: 3, School: "evocation", Classes: []DnDClass{ClassCleric, ClassRanger, ClassDruid, ClassSorcerer, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Description: "A 60-foot-radius sphere of light spreads out from a point you choose within range.", AOE: true},
{ID: "dispel_magic", Name: "Dispel Magic", Level: 3, School: "abjuration", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassBard, ClassSorcerer, ClassWarlock, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Description: "Choose one creature, object, or magical effect within range.", Upcast: "When you cast this spell using a spell slot of 4th level or higher, you automatically end the effects of a spell on the target if the spell's level is equal to or less than the level of the spell slot…"},
{ID: "fear", Name: "Fear", Level: 3, School: "illusion", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You project a phantasmal image of a creature's worst fears.", AOE: true},
{ID: "fireball", Name: "Fireball", Level: 3, School: "evocation", Classes: []DnDClass{ClassMage, ClassSorcerer}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "8d6", DamageType: "fire", Description: "A bright streak flashes from your pointing finger to a point you choose within range and then blossoms with a low roar into an explosion of flame.", Upcast: "When you cast this spell using a spell slot of 4th level or higher, the damage increases by 1d6 for each slot level above 3rd.", AOE: true},
{ID: "create_food_and_water", Name: "Create Food and Water", Level: 3, School: "conjuration", Classes: []DnDClass{ClassCleric, ClassDruid, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Description: "You create 45 pounds of food and 30 gallons of water on the ground or in containers, enough to sustain up to fifteen humanoids or five steeds for 24 hours."},
{ID: "daylight", Name: "Daylight", Level: 3, School: "evocation", Classes: []DnDClass{ClassCleric, ClassRanger, ClassDruid, ClassSorcerer, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Description: "A sphere of light spreads out from a point you choose.", AOE: true},
{ID: "dispel_magic", Name: "Dispel Magic", Level: 3, School: "abjuration", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassBard, ClassSorcerer, ClassWarlock, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Description: "Choose one creature, object, or magical effect.", Upcast: "When you cast this spell using a spell slot of 4th level or higher, you automatically end the effects of a spell on the target if the spell's level is equal to or less than the level of the spell slot…"},
{ID: "fear", Name: "Fear", Level: 3, School: "illusion", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "Project a cone of pure dread. Brave folk turn and run; less brave folk were already running.", AOE: true},
{ID: "fireball", Name: "Fireball", Level: 3, School: "evocation", Classes: []DnDClass{ClassMage, ClassSorcerer}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "8d6", DamageType: "fire", Description: "A bright streak flashes from your pointing finger to a point you choose and then blossoms with a low roar into an explosion of flame.", Upcast: "When you cast this spell using a spell slot of 4th level or higher, the damage increases by 1d6 for each slot level above 3rd.", AOE: true},
{ID: "fly", Name: "Fly", Level: 3, School: "transmutation", Classes: []DnDClass{ClassMage, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You touch a willing creature.", Upcast: "When you cast this spell using a spell slot of 4th level or higher, you can target one additional creature for each slot level above 3rd."},
{ID: "gaseous_form", Name: "Gaseous Form", Level: 3, School: "transmutation", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You transform a willing creature you touch, along with everything it's wearing and carrying, into a misty cloud for the duration."},
{ID: "glyph_of_warding", Name: "Glyph of Warding", Level: 3, School: "abjuration", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard}, Effect: EffectDamageSave, CastTime: CastAction, SaveStat: "DEX", DamageDice: "5d8", DamageType: "thunder", Description: "When you cast this spell, you inscribe a glyph that harms other creatures, either upon a surface (such as a table or a section of floor or wall) or within an object that can be closed (such as a book,…", Upcast: "When you cast this spell using a spell slot of 4th level or higher, the damage of an explosive runes glyph increases by 1d8 for each slot level above 3rd.", MaterialCost: 200, AOE: true},
{ID: "haste", Name: "Haste", Level: 3, School: "transmutation", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer, ClassPaladin}, Effect: EffectBuffAlly, CastTime: CastAction, Concentration: true, Description: "Choose a willing creature that you can see within range."},
{ID: "hypnotic_pattern", Name: "Hypnotic Pattern", Level: 3, School: "illusion", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You create a twisting pattern of colors that weaves through the air inside a 30-foot cube within range.", AOE: true},
{ID: "lightning_bolt", Name: "Lightning Bolt", Level: 3, School: "evocation", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "8d6", DamageType: "lightning", Description: "A stroke of lightning forming a line 100 feet long and 5 feet wide blasts out from you in a direction you choose.", Upcast: "When you cast this spell using a spell slot of 4th level or higher, the damage increases by 1d6 for each slot level above 3rd.", AOE: true},
{ID: "magic_circle", Name: "Magic Circle", Level: 3, School: "abjuration", Classes: []DnDClass{ClassMage, ClassCleric, ClassWarlock, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Description: "You create a 10-\u00ad--foot-\u00ad--radius, 20-\u00ad--foot-\u00ad--tall cylinder of magical energy centered on a point on the ground that you can see within range.", Upcast: "When you cast this spell using a spell slot of 4th level or higher, the duration increases by 1 hour for each slot level above 3rd.", MaterialCost: 100},
{ID: "major_image", Name: "Major Image", Level: 3, School: "illusion", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectBuffSelf, CastTime: CastAction, Concentration: true, DamageType: "thunder", Description: "You create the image of an object, a creature, or some other visible phenomenon that is no larger than a 20-foot cube.", Upcast: "When you cast this spell using a spell slot of 6th level or higher, the spell lasts until dispelled, without requiring your concentration.", AOE: true},
{ID: "mass_healing_word", Name: "Mass Healing Word", Level: 3, School: "evocation", Classes: []DnDClass{ClassCleric}, Effect: EffectSpellHeal, CastTime: CastBonusAction, DamageDice: "1d4", Description: "As you call out words of restoration, up to six creatures of your choice that you can see within range regain hit points equal to 1d4 + your spellcasting ability modifier.", Upcast: "When you cast this spell using a spell slot of 4th level or higher, the healing increases by 1d4 for each slot level above 3rd."},
{ID: "haste", Name: "Haste", Level: 3, School: "transmutation", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer, ClassPaladin}, Effect: EffectBuffAlly, CastTime: CastAction, Concentration: true, Description: "An ally surges with speed — extra ground, sharper defences, an extra swing. Brief, glorious, exhausting."},
{ID: "hypnotic_pattern", Name: "Hypnotic Pattern", Level: 3, School: "illusion", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You create a twisting pattern of colors that weaves through the air inside a.", AOE: true},
{ID: "lightning_bolt", Name: "Lightning Bolt", Level: 3, School: "evocation", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "8d6", DamageType: "lightning", Description: "A stroke of lightning forming a line long and wide blasts out from you in a direction you choose.", Upcast: "When you cast this spell using a spell slot of 4th level or higher, the damage increases by 1d6 for each slot level above 3rd.", AOE: true},
{ID: "magic_circle", Name: "Magic Circle", Level: 3, School: "abjuration", Classes: []DnDClass{ClassMage, ClassCleric, ClassWarlock, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Description: "You create a 10-\u00ad--foot-\u00ad--radius, 20-\u00ad--foot-\u00ad--tall cylinder of magical energy centered on a point on the ground that you can see.", Upcast: "When you cast this spell using a spell slot of 4th level or higher, the duration increases by 1 hour for each slot level above 3rd.", MaterialCost: 100},
{ID: "major_image", Name: "Major Image", Level: 3, School: "illusion", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectBuffSelf, CastTime: CastAction, Concentration: true, DamageType: "thunder", Description: "You create the image of an object, a creature, or some other visible phenomenon that is no larger than a.", Upcast: "When you cast this spell using a spell slot of 6th level or higher, the spell lasts until dispelled, without requiring your concentration.", AOE: true},
{ID: "mass_healing_word", Name: "Mass Healing Word", Level: 3, School: "evocation", Classes: []DnDClass{ClassCleric}, Effect: EffectSpellHeal, CastTime: CastBonusAction, DamageDice: "1d4", Description: "As you call out words of restoration, up to six creatures of your choice that you can see regain hit points equal to 1d4 + your spellcasting ability modifier.", Upcast: "When you cast this spell using a spell slot of 4th level or higher, the healing increases by 1d4 for each slot level above 3rd."},
{ID: "meld_into_stone", Name: "Meld into Stone", Level: 3, School: "transmutation", Classes: []DnDClass{ClassCleric, ClassDruid}, Effect: EffectDamageAuto, CastTime: CastRitual, DamageDice: "6d6", DamageType: "bludgeoning", Description: "You step into a stone object or surface large enough to fully contain your body, melding yourself and all the equipment you carry with the stone for the duration."},
{ID: "nondetection", Name: "Nondetection", Level: 3, School: "abjuration", Classes: []DnDClass{ClassMage, ClassCleric, ClassRanger, ClassBard}, Effect: EffectUtility, CastTime: CastAction, Description: "For the duration, you hide a target that you touch from divination magic.", MaterialCost: 25},
{ID: "phantom_steed", Name: "Phantom Steed", Level: 3, School: "illusion", Classes: []DnDClass{ClassMage}, Effect: EffectUtility, CastTime: CastRitual, Description: "A Large quasi-real, horselike creature appears on the ground in an unoccupied space of your choice within range."},
{ID: "phantom_steed", Name: "Phantom Steed", Level: 3, School: "illusion", Classes: []DnDClass{ClassMage}, Effect: EffectUtility, CastTime: CastRitual, Description: "A Large quasi-real, horselike creature appears on the ground in an unoccupied space of your choice."},
{ID: "plant_growth", Name: "Plant Growth", Level: 3, School: "transmutation", Classes: []DnDClass{ClassCleric, ClassRanger, ClassDruid, ClassBard, ClassWarlock, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Description: "This spell channels vitality into plants within a specific area.", AOE: true},
{ID: "protection_from_energy", Name: "Protection from Energy", Level: 3, School: "abjuration", Classes: []DnDClass{ClassMage, ClassCleric, ClassRanger, ClassDruid, ClassSorcerer, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "For the duration, the willing creature you touch has resistance to one damage type of your choice: acid, cold, fire, lightning, or thunder."},
{ID: "remove_curse", Name: "Remove Curse", Level: 3, School: "abjuration", Classes: []DnDClass{ClassMage, ClassCleric, ClassWarlock, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Description: "At your touch, all curses affecting one creature or object end."},
{ID: "revivify", Name: "Revivify", Level: 3, School: "conjuration", Classes: []DnDClass{ClassCleric, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Description: "You touch a creature that has died within the last minute.", MaterialCost: 300},
{ID: "sending", Name: "Sending", Level: 3, School: "evocation", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Description: "You send a short message of twenty-five words or less to a creature with which you are familiar."},
{ID: "sleet_storm", Name: "Sleet Storm", Level: 3, School: "conjuration", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "Until the spell ends, freezing rain and sleet fall in a 20-foot-tall cylinder with a 40-foot radius centered on a point you choose within range.", AOE: true},
{ID: "slow", Name: "Slow", Level: 3, School: "transmutation", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You alter time around up to six creatures of your choice in a 40-foot cube within range.", AOE: true},
{ID: "speak_with_dead", Name: "Speak with Dead", Level: 3, School: "necromancy", Classes: []DnDClass{ClassCleric, ClassBard}, Effect: EffectUtility, CastTime: CastAction, Description: "You grant the semblance of life and intelligence to a corpse of your choice within range, allowing it to answer the questions you pose."},
{ID: "speak_with_plants", Name: "Speak with Plants", Level: 3, School: "transmutation", Classes: []DnDClass{ClassRanger, ClassDruid, ClassBard}, Effect: EffectBuffSelf, CastTime: CastAction, Description: "You imbue plants within 30 feet of you with limited sentience and animation, giving them the ability to communicate with you and follow your simple commands."},
{ID: "sleet_storm", Name: "Sleet Storm", Level: 3, School: "conjuration", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "Until the spell ends, freezing rain and sleet fall in a 20-foot-tall cylinder with a centered on a point you choose.", AOE: true},
{ID: "slow", Name: "Slow", Level: 3, School: "transmutation", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You alter time around up to six creatures of your choice in a.", AOE: true},
{ID: "speak_with_dead", Name: "Speak with Dead", Level: 3, School: "necromancy", Classes: []DnDClass{ClassCleric, ClassBard}, Effect: EffectUtility, CastTime: CastAction, Description: "You grant the semblance of life and intelligence to a corpse of your choice, allowing it to answer the questions you pose."},
{ID: "speak_with_plants", Name: "Speak with Plants", Level: 3, School: "transmutation", Classes: []DnDClass{ClassRanger, ClassDruid, ClassBard}, Effect: EffectBuffSelf, CastTime: CastAction, Description: "You imbue plantsou with limited sentience and animation, giving them the ability to communicate with you and follow your simple commands."},
{ID: "spirit_guardians", Name: "Spirit Guardians", Level: 3, School: "conjuration", Classes: []DnDClass{ClassCleric}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "3d8", DamageType: "radiant", Description: "You call forth spirits to protect you.", Upcast: "When you cast this spell using a spell slot of 4th level or higher, the damage increases by 1d8 for each slot level above 3rd."},
{ID: "stinking_cloud", Name: "Stinking Cloud", Level: 3, School: "conjuration", Classes: []DnDClass{ClassMage, ClassDruid, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You create a 20-foot-radius sphere of yellow, nauseating gas centered on a point within range.", AOE: true},
{ID: "tiny_hut", Name: "Tiny Hut", Level: 3, School: "evocation", Classes: []DnDClass{ClassMage, ClassBard}, Effect: EffectUtility, CastTime: CastRitual, Description: "A 10-foot-radius immobile dome of force springs into existence around and above you and remains stationary for the duration.", AOE: true},
{ID: "stinking_cloud", Name: "Stinking Cloud", Level: 3, School: "conjuration", Classes: []DnDClass{ClassMage, ClassDruid, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You create a sphere of yellow, nauseating gas centered on a point.", AOE: true},
{ID: "tiny_hut", Name: "Tiny Hut", Level: 3, School: "evocation", Classes: []DnDClass{ClassMage, ClassBard}, Effect: EffectUtility, CastTime: CastRitual, Description: "A immobile dome of force springs into existence around and above you and remains stationary for the duration.", AOE: true},
{ID: "tongues", Name: "Tongues", Level: 3, School: "divination", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Description: "This spell grants the creature you touch the ability to understand any spoken language it hears."},
{ID: "vampiric_touch", Name: "Vampiric Touch", Level: 3, School: "necromancy", Classes: []DnDClass{ClassMage, ClassWarlock}, Effect: EffectDamageAttack, CastTime: CastAction, Concentration: true, AttackRoll: true, DamageDice: "3d6", DamageType: "necrotic", Description: "The touch of your shadow-wreathed hand can siphon life force from others to heal your wounds.", Upcast: "When you cast this spell using a spell slot of 4th level or higher, the damage increases by 1d6 for each slot level above 3rd."},
{ID: "water_breathing", Name: "Water Breathing", Level: 3, School: "transmutation", Classes: []DnDClass{ClassMage, ClassRanger, ClassDruid, ClassSorcerer}, Effect: EffectUtility, CastTime: CastRitual, Description: "This spell gives a maximum of ten willing creatures within range and you can see, the ability to breathe underwater until the end of its term."},
{ID: "vampiric_touch", Name: "Vampiric Touch", Level: 3, School: "necromancy", Classes: []DnDClass{ClassMage, ClassWarlock}, Effect: EffectDamageAttack, CastTime: CastAction, Concentration: true, AttackRoll: true, DamageDice: "3d6", DamageType: "necrotic", Description: "Drain life from a target. The damage you deal patches you up. Frowned upon at parties.", Upcast: "When you cast this spell using a spell slot of 4th level or higher, the damage increases by 1d6 for each slot level above 3rd."},
{ID: "water_breathing", Name: "Water Breathing", Level: 3, School: "transmutation", Classes: []DnDClass{ClassMage, ClassRanger, ClassDruid, ClassSorcerer}, Effect: EffectUtility, CastTime: CastRitual, Description: "This spell gives a maximum of ten willing creatures and you can see, the ability to breathe underwater until the end of its term."},
{ID: "water_walk", Name: "Water Walk", Level: 3, School: "transmutation", Classes: []DnDClass{ClassCleric, ClassRanger, ClassDruid, ClassSorcerer}, Effect: EffectUtility, CastTime: CastRitual, Description: "This spell grants the ability to move across any liquid surface-such as water, acid, mud, snow, quicksand, or lava-as if it were harmless solid ground (creatures crossing molten lava can still take da…"},
{ID: "wind_wall", Name: "Wind Wall", Level: 3, School: "evocation", Classes: []DnDClass{ClassCleric, ClassRanger, ClassDruid}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "3d8", DamageType: "bludgeoning", Description: "A wall of strong wind rises from the ground at a point you choose within range.", AOE: true},
{ID: "arcane_eye", Name: "Arcane Eye", Level: 4, School: "divination", Classes: []DnDClass{ClassMage, ClassCleric}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You create an invisible, magical eye within range that hovers in the air for the duration."},
{ID: "banishment", Name: "Banishment", Level: 4, School: "abjuration", Classes: []DnDClass{ClassMage, ClassCleric, ClassSorcerer, ClassWarlock, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You attempt to send one creature that you can see within range to another plane of existence.", Upcast: "When you cast this spell using a spell slot of 5th level or higher, you can target one additional creature for each slot level above 4th."},
{ID: "black_tentacles", Name: "Black Tentacles", Level: 4, School: "conjuration", Classes: []DnDClass{ClassMage, ClassWarlock}, Effect: EffectDamageSave, CastTime: CastAction, Concentration: true, SaveStat: "DEX", DamageDice: "3d6", DamageType: "bludgeoning", Description: "Squirming, ebony tentacles fill a 20-foot square on ground that you can see within range."},
{ID: "blight", Name: "Blight", Level: 4, School: "necromancy", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer, ClassWarlock}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "8d8", DamageType: "necrotic", Description: "Necromantic energy washes over a creature of your choice that you can see within range, draining moisture and vitality from it.", Upcast: "When you cast this spell using a spell slot of 5th level of higher, the damage increases by 1d8 for each slot level above 4th."},
{ID: "compulsion", Name: "Compulsion", Level: 4, School: "enchantment", Classes: []DnDClass{ClassBard}, Effect: EffectControl, CastTime: CastAction, Concentration: true, SaveStat: "WIS", Description: "Creatures of your choice that you can see within range and that can hear you must make a Wisdom saving throw."},
{ID: "wind_wall", Name: "Wind Wall", Level: 3, School: "evocation", Classes: []DnDClass{ClassCleric, ClassRanger, ClassDruid}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "3d8", DamageType: "bludgeoning", Description: "A wall of strong wind rises from the ground at a point you choose.", AOE: true},
{ID: "arcane_eye", Name: "Arcane Eye", Level: 4, School: "divination", Classes: []DnDClass{ClassMage, ClassCleric}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You create an invisible, magical eye that hovers in the air for the duration."},
{ID: "banishment", Name: "Banishment", Level: 4, School: "abjuration", Classes: []DnDClass{ClassMage, ClassCleric, ClassSorcerer, ClassWarlock, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You attempt to send one creature that you can see to another plane of existence.", Upcast: "When you cast this spell using a spell slot of 5th level or higher, you can target one additional creature for each slot level above 4th."},
{ID: "black_tentacles", Name: "Black Tentacles", Level: 4, School: "conjuration", Classes: []DnDClass{ClassMage, ClassWarlock}, Effect: EffectDamageSave, CastTime: CastAction, Concentration: true, SaveStat: "DEX", DamageDice: "3d6", DamageType: "bludgeoning", Description: "Squirming, ebony tentacles fill a on ground that you can see."},
{ID: "blight", Name: "Blight", Level: 4, School: "necromancy", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer, ClassWarlock}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "8d8", DamageType: "necrotic", Description: "Necromantic energy washes over a creature of your choice that you can see, draining moisture and vitality from it.", Upcast: "When you cast this spell using a spell slot of 5th level of higher, the damage increases by 1d8 for each slot level above 4th."},
{ID: "compulsion", Name: "Compulsion", Level: 4, School: "enchantment", Classes: []DnDClass{ClassBard}, Effect: EffectControl, CastTime: CastAction, Concentration: true, SaveStat: "WIS", Description: "Creatures of your choice that you can see and that can hear you must make a."},
{ID: "confusion", Name: "Confusion", Level: 4, School: "enchantment", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassBard, ClassSorcerer}, Effect: EffectControl, CastTime: CastAction, Concentration: true, SaveStat: "WIS", Description: "This spell assaults and twists creatures' minds, spawning delusions and provoking uncontrolled action.", Upcast: "When you cast this spell using a spell slot of 5th level or higher, the radius of the sphere increases by 5 feet for each slot level above 4th.", AOE: true},
{ID: "conjure_minor_elementals", Name: "Conjure Minor Elementals", Level: 4, School: "conjuration", Classes: []DnDClass{ClassMage, ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You summon elementals that appear in unoccupied spaces that you can see within range.", Upcast: "When you cast this spell using certain higher-level spell slots, you choose one of the summoning options above, and more creatures appear: twice as many with a 6th-level slot and three times as many w…"},
{ID: "conjure_woodland_beings", Name: "Conjure Woodland Beings", Level: 4, School: "conjuration", Classes: []DnDClass{ClassRanger, ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You summon fey creatures that appear in unoccupied spaces that you can see within range.", Upcast: "When you cast this spell using certain higher-level spell slots, you choose one of the summoning options above, and more creatures appear: twice as many with a 6th-level slot and three times as many w…"},
{ID: "control_water", Name: "Control Water", Level: 4, School: "transmutation", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "2d8", DamageType: "bludgeoning", Description: "Until the spell ends, you control any freestanding water inside an area you choose that is a cube up to 100 feet on a side."},
{ID: "conjure_minor_elementals", Name: "Conjure Minor Elementals", Level: 4, School: "conjuration", Classes: []DnDClass{ClassMage, ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You summon elementals that appear in unoccupied spaces that you can see.", Upcast: "When you cast this spell using certain higher-level spell slots, you choose one of the summoning options above, and more creatures appear: twice as many with a 6th-level slot and three times as many w…"},
{ID: "conjure_woodland_beings", Name: "Conjure Woodland Beings", Level: 4, School: "conjuration", Classes: []DnDClass{ClassRanger, ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You summon fey creatures that appear in unoccupied spaces that you can see.", Upcast: "When you cast this spell using certain higher-level spell slots, you choose one of the summoning options above, and more creatures appear: twice as many with a 6th-level slot and three times as many w…"},
{ID: "control_water", Name: "Control Water", Level: 4, School: "transmutation", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "2d8", DamageType: "bludgeoning", Description: "Until the spell ends, you control any freestanding water inside an area you choose that is a cube up to on a side."},
{ID: "death_ward", Name: "Death Ward", Level: 4, School: "abjuration", Classes: []DnDClass{ClassCleric, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Description: "You touch a creature and grant it a measure of protection from death."},
{ID: "dimension_door", Name: "Dimension Door", Level: 4, School: "conjuration", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard, ClassSorcerer, ClassWarlock, ClassPaladin}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "4d6", DamageType: "force", Description: "You teleport yourself from your current location to any other spot within range."},
{ID: "dimension_door", Name: "Dimension Door", Level: 4, School: "conjuration", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard, ClassSorcerer, ClassWarlock, ClassPaladin}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "4d6", DamageType: "force", Description: "You teleport yourself from your current location to any other spot."},
{ID: "divination", Name: "Divination", Level: 4, School: "divination", Classes: []DnDClass{ClassCleric, ClassDruid}, Effect: EffectUtility, CastTime: CastRitual, Description: "Your magic and an offering put you in contact with a god or a god's servants.", MaterialCost: 25},
{ID: "dominate_beast", Name: "Dominate Beast", Level: 4, School: "enchantment", Classes: []DnDClass{ClassCleric, ClassDruid, ClassSorcerer, ClassWarlock}, Effect: EffectBuffSelf, CastTime: CastAction, Concentration: true, Description: "You attempt to beguile a beast that you can see within range.", Upcast: "When you cast this spell with a 5th-\u00adlevel spell slot, the duration is concentration, up to 10 minutes."},
{ID: "dominate_beast", Name: "Dominate Beast", Level: 4, School: "enchantment", Classes: []DnDClass{ClassCleric, ClassDruid, ClassSorcerer, ClassWarlock}, Effect: EffectBuffSelf, CastTime: CastAction, Concentration: true, Description: "You attempt to beguile a beast that you can see.", Upcast: "When you cast this spell with a 5th-\u00adlevel spell slot, the duration is concentration, up to 10 minutes."},
{ID: "fabricate", Name: "Fabricate", Level: 4, School: "transmutation", Classes: []DnDClass{ClassMage}, Effect: EffectUtility, CastTime: CastAction, Description: "You convert raw materials into products of the same material.", AOE: true},
{ID: "faithful_hound", Name: "Faithful Hound", Level: 4, School: "conjuration", Classes: []DnDClass{ClassMage}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "4d8", DamageType: "piercing", Description: "You conjure a phantom watchdog in an unoccupied space that you can see within range, where it remains for the duration, until you dismiss it as an action, or until you move more than 100 feet away fro", AOE: true},
{ID: "fire_shield", Name: "Fire Shield", Level: 4, School: "evocation", Classes: []DnDClass{ClassMage, ClassWarlock}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "2d8", DamageType: "cold", Description: "Thin and vaporous flame surround your body for the duration of the spell, radiating a bright light bright light in a 10-foot radius and dim light for an additional 10 feet.", AOE: true},
{ID: "faithful_hound", Name: "Faithful Hound", Level: 4, School: "conjuration", Classes: []DnDClass{ClassMage}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "4d8", DamageType: "piercing", Description: "You conjure a phantom watchdog in an unoccupied space that you can see, where it remains for the duration, until you dismiss it as an action, or until you move more than away from it.", AOE: true},
{ID: "fire_shield", Name: "Fire Shield", Level: 4, School: "evocation", Classes: []DnDClass{ClassMage, ClassWarlock}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "2d8", DamageType: "cold", Description: "Thin and vaporous flame surround your body for the duration of the spell, radiating a bright light bright light in a and dim light for an additional.", AOE: true},
{ID: "freedom_of_movement", Name: "Freedom of Movement", Level: 4, School: "abjuration", Classes: []DnDClass{ClassCleric, ClassRanger, ClassDruid, ClassBard, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Description: "You touch a willing creature."},
{ID: "giant_insect", Name: "Giant Insect", Level: 4, School: "transmutation", Classes: []DnDClass{ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You transform up to ten centipedes, three spiders, five wasps, or one scorpion within range into giant versions of their natural forms for the duration.", AOE: true},
{ID: "giant_insect", Name: "Giant Insect", Level: 4, School: "transmutation", Classes: []DnDClass{ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You transform up to ten centipedes, three spiders, five wasps, or one scorpion into giant versions of their natural forms for the duration.", AOE: true},
{ID: "greater_invisibility", Name: "Greater Invisibility", Level: 4, School: "illusion", Classes: []DnDClass{ClassMage, ClassDruid, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You or a creature you touch becomes invisible until the spell ends."},
{ID: "guardian_of_faith", Name: "Guardian of Faith", Level: 4, School: "conjuration", Classes: []DnDClass{ClassCleric}, Effect: EffectControl, CastTime: CastAction, SaveStat: "DEX", Description: "A Large spectral guardian appears and hovers for the duration in an unoccupied space of your choice that you can see within range."},
{ID: "hallucinatory_terrain", Name: "Hallucinatory Terrain", Level: 4, School: "illusion", Classes: []DnDClass{ClassMage, ClassDruid, ClassBard, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Description: "You make natural terrain in a 150-foot cube in range look, sound, and smell like some other sort of natural terrain.", AOE: true},
{ID: "ice_storm", Name: "Ice Storm", Level: 4, School: "evocation", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassSorcerer, ClassPaladin}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "2d8", DamageType: "bludgeoning", Description: "A hail of rock-hard ice pounds to the ground in a 20-foot-radius, 40-foot-high cylinder centered on a point within range.", Upcast: "When you cast this spell using a spell slot of 5th level or higher, the bludgeoning damage increases by 1d8 for each slot level above 4th.", AOE: true},
{ID: "guardian_of_faith", Name: "Guardian of Faith", Level: 4, School: "conjuration", Classes: []DnDClass{ClassCleric}, Effect: EffectControl, CastTime: CastAction, SaveStat: "DEX", Description: "A Large spectral guardian appears and hovers for the duration in an unoccupied space of your choice that you can see."},
{ID: "hallucinatory_terrain", Name: "Hallucinatory Terrain", Level: 4, School: "illusion", Classes: []DnDClass{ClassMage, ClassDruid, ClassBard, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Description: "You make natural terrain in a in range look, sound, and smell like some other sort of natural terrain.", AOE: true},
{ID: "ice_storm", Name: "Ice Storm", Level: 4, School: "evocation", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassSorcerer, ClassPaladin}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "2d8", DamageType: "bludgeoning", Description: "A hail of rock-hard ice pounds to the ground in a, 40-foot-high cylinder centered on a point.", Upcast: "When you cast this spell using a spell slot of 5th level or higher, the bludgeoning damage increases by 1d8 for each slot level above 4th.", AOE: true},
{ID: "locate_creature", Name: "Locate Creature", Level: 4, School: "divination", Classes: []DnDClass{ClassMage, ClassCleric, ClassRanger, ClassDruid, ClassBard, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "Describe or name a creature that is familiar to you."},
{ID: "phantasmal_killer", Name: "Phantasmal Killer", Level: 4, School: "illusion", Classes: []DnDClass{ClassMage}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "4d10", DamageType: "psychic", Description: "You tap into the nightmares of a creature you can see within range and create an illusory manifestation of its deepest fears, visible only to that creature.", Upcast: "When you cast this spell using a spell slot of 5th level or higher, the damage increases by 1d10 for each slot level above 4th."},
{ID: "polymorph", Name: "Polymorph", Level: 4, School: "transmutation", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassBard, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "This spell transforms a creature that you can see within range into a new form."},
{ID: "private_sanctum", Name: "Private Sanctum", Level: 4, School: "abjuration", Classes: []DnDClass{ClassMage}, Effect: EffectUtility, CastTime: CastAction, Description: "You make an area within range magically secure.", Upcast: "When you cast this spell using a spell slot of 5th level or higher, you can increase the size of the cube by 100 feet for each slot level beyond 4th."},
{ID: "resilient_sphere", Name: "Resilient Sphere", Level: 4, School: "evocation", Classes: []DnDClass{ClassMage}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "A sphere of shimmering force encloses a creature or object of Large size or smaller within range."},
{ID: "phantasmal_killer", Name: "Phantasmal Killer", Level: 4, School: "illusion", Classes: []DnDClass{ClassMage}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "4d10", DamageType: "psychic", Description: "You tap into the nightmares of a creature you can see and create an illusory manifestation of its deepest fears, visible only to that creature.", Upcast: "When you cast this spell using a spell slot of 5th level or higher, the damage increases by 1d10 for each slot level above 4th."},
{ID: "polymorph", Name: "Polymorph", Level: 4, School: "transmutation", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassBard, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "This spell transforms a creature that you can see into a new form."},
{ID: "private_sanctum", Name: "Private Sanctum", Level: 4, School: "abjuration", Classes: []DnDClass{ClassMage}, Effect: EffectUtility, CastTime: CastAction, Description: "You make an area magically secure.", Upcast: "When you cast this spell using a spell slot of 5th level or higher, you can increase the size of the cube by 100 feet for each slot level beyond 4th."},
{ID: "resilient_sphere", Name: "Resilient Sphere", Level: 4, School: "evocation", Classes: []DnDClass{ClassMage}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "A sphere of shimmering force encloses a creature or object of Large size or smaller."},
{ID: "secret_chest", Name: "Secret Chest", Level: 4, School: "conjuration", Classes: []DnDClass{ClassMage}, Effect: EffectUtility, CastTime: CastAction, Description: "You hide a chest, and all its contents, on the Ethereal Plane.", MaterialCost: 5000},
{ID: "stone_shape", Name: "Stone Shape", Level: 4, School: "transmutation", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Description: "You touch a stone object of Medium size or smaller or a section of stone no more than 5 feet in any dimension and form it into any shape that suits your purpose."},
{ID: "stone_shape", Name: "Stone Shape", Level: 4, School: "transmutation", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Description: "You touch a stone object of Medium size or smaller or a section of stone no more than in any dimension and form it into any shape that suits your purpose."},
{ID: "stoneskin", Name: "Stoneskin", Level: 4, School: "abjuration", Classes: []DnDClass{ClassMage, ClassCleric, ClassRanger, ClassDruid, ClassSorcerer, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "This spell turns the flesh of a willing creature you touch as hard as stone.", MaterialCost: 100},
{ID: "wall_of_fire", Name: "Wall of Fire", Level: 4, School: "evocation", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassSorcerer, ClassWarlock}, Effect: EffectDamageSave, CastTime: CastAction, Concentration: true, SaveStat: "DEX", DamageDice: "5d8", DamageType: "fire", Description: "You create a wall of fire on a solid surface within range.", Upcast: "When you cast this spell using a level spell slot 5 or more, the damage of the spell increases by 1d8 for each level of higher spell slot to 4.", AOE: true},
{ID: "wall_of_fire", Name: "Wall of Fire", Level: 4, School: "evocation", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassSorcerer, ClassWarlock}, Effect: EffectDamageSave, CastTime: CastAction, Concentration: true, SaveStat: "DEX", DamageDice: "5d8", DamageType: "fire", Description: "You create a wall of fire on a solid surface.", Upcast: "When you cast this spell using a level spell slot 5 or more, the damage of the spell increases by 1d8 for each level of higher spell slot to 4.", AOE: true},
{ID: "animate_objects", Name: "Animate Objects", Level: 5, School: "transmutation", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "1d4+4", DamageType: "bludgeoning", Description: "Objects come to life at your command.", Upcast: "If you cast this spell using a spell slot of 6th level or higher, you can animate two additional objects for each slot level above 5th."},
{ID: "antilife_shell", Name: "Antilife Shell", Level: 5, School: "abjuration", Classes: []DnDClass{ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "A shimmering barrier extends out from you in a 10-foot radius and moves with you, remaining centered on you and hedging out creatures other than undead and constructs.", AOE: true},
{ID: "arcane_hand", Name: "Arcane Hand", Level: 5, School: "evocation", Classes: []DnDClass{ClassMage}, Effect: EffectDamageAttack, CastTime: CastAction, Concentration: true, AttackRoll: true, DamageDice: "4d8", DamageType: "force", Description: "You create a Large hand of shimmering, translucent force in an unoccupied space that you can see within range.", Upcast: "When you cast this spell using a spell slot of 6th level or higher, the damage from the clenched fist option increases by 2d8 and the damage from the grasping hand increases by 2d6 for each slot level…"},
{ID: "antilife_shell", Name: "Antilife Shell", Level: 5, School: "abjuration", Classes: []DnDClass{ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "A shimmering barrier extends out from you in a and moves with you, remaining centered on you and hedging out creatures other than undead and constructs.", AOE: true},
{ID: "arcane_hand", Name: "Arcane Hand", Level: 5, School: "evocation", Classes: []DnDClass{ClassMage}, Effect: EffectDamageAttack, CastTime: CastAction, Concentration: true, AttackRoll: true, DamageDice: "4d8", DamageType: "force", Description: "You create a Large hand of shimmering, translucent force in an unoccupied space that you can see.", Upcast: "When you cast this spell using a spell slot of 6th level or higher, the damage from the clenched fist option increases by 2d8 and the damage from the grasping hand increases by 2d6 for each slot level…"},
{ID: "awaken", Name: "Awaken", Level: 5, School: "transmutation", Classes: []DnDClass{ClassDruid, ClassBard}, Effect: EffectUtility, CastTime: CastAction, Description: "After spending the casting time tracing magical pathways within a precious gemstone, you touch a Huge or smaller beast or plant.", MaterialCost: 1000},
{ID: "cloudkill", Name: "Cloudkill", Level: 5, School: "conjuration", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "5d8", DamageType: "poison", Description: "You create a 20-foot-radius sphere of poisonous, yellow-green fog centered on a point you choose within range.", Upcast: "When you cast this spell using a spell slot of 6th level or higher, the damage increases by 1d8 for each slot level above 5th.", AOE: true},
{ID: "cloudkill", Name: "Cloudkill", Level: 5, School: "conjuration", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "5d8", DamageType: "poison", Description: "You create a sphere of poisonous, yellow-green fog centered on a point you choose.", Upcast: "When you cast this spell using a spell slot of 6th level or higher, the damage increases by 1d8 for each slot level above 5th.", AOE: true},
{ID: "commune", Name: "Commune", Level: 5, School: "divination", Classes: []DnDClass{ClassCleric, ClassPaladin}, Effect: EffectUtility, CastTime: CastRitual, Description: "You contact your deity or a divine proxy and ask up to three questions that can be answered with a yes or no."},
{ID: "commune_with_nature", Name: "Commune with Nature", Level: 5, School: "divination", Classes: []DnDClass{ClassRanger, ClassDruid, ClassPaladin}, Effect: EffectUtility, CastTime: CastRitual, Description: "You briefly become one with nature and gain knowledge of the surrounding territory."},
{ID: "cone_of_cold", Name: "Cone of Cold", Level: 5, School: "evocation", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "8d8", DamageType: "cold", Description: "A blast of cold air erupts from your hands.", Upcast: "When you cast this spell using a spell slot of 6th level or higher, the damage increases by 1d8 for each slot level above 5th.", AOE: true},
@@ -227,29 +227,29 @@ func buildSRDSpellList() []SpellDefinition {
{ID: "contagion", Name: "Contagion", Level: 5, School: "necromancy", Classes: []DnDClass{ClassCleric, ClassDruid}, Effect: EffectUtility, CastTime: CastAction, AttackRoll: true, Description: "Your touch inflicts disease."},
{ID: "creation", Name: "Creation", Level: 5, School: "illusion", Classes: []DnDClass{ClassMage, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Description: "You pull wisps of shadow material from the Shadowfell to create a nonliving object of vegetable matter within 'range': soft goods, rope, wood, or something similar.", Upcast: "When you cast this spell using a spell slot of 6th level or higher, the cube increases by 5 feet for each slot level above 5th.", AOE: true},
{ID: "dispel_evil_and_good", Name: "Dispel Evil and Good", Level: 5, School: "abjuration", Classes: []DnDClass{ClassCleric, ClassPaladin}, Effect: EffectBuffSelf, CastTime: CastAction, Concentration: true, AttackRoll: true, Description: "Shimmering energy surrounds and protects you from fey, undead, and creatures originating from beyond the Material Plane."},
{ID: "dominate_person", Name: "Dominate Person", Level: 5, School: "enchantment", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectBuffSelf, CastTime: CastAction, Concentration: true, Description: "You attempt to beguile a humanoid that you can see within range.", Upcast: "When you cast this spell using a 6th-level spell slot, the duration is concentration, up to 10 minutes."},
{ID: "dominate_person", Name: "Dominate Person", Level: 5, School: "enchantment", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectBuffSelf, CastTime: CastAction, Concentration: true, Description: "You attempt to beguile a humanoid that you can see.", Upcast: "When you cast this spell using a 6th-level spell slot, the duration is concentration, up to 10 minutes."},
{ID: "dream", Name: "Dream", Level: 5, School: "illusion", Classes: []DnDClass{ClassMage, ClassDruid, ClassBard, ClassWarlock}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "3d6", DamageType: "psychic", Description: "This spell shapes a creature's dreams."},
{ID: "flame_strike", Name: "Flame Strike", Level: 5, School: "evocation", Classes: []DnDClass{ClassCleric, ClassWarlock, ClassPaladin}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "4d6", DamageType: "fire", Description: "A vertical column of divine fire roars down from the heavens in a location you specify.", Upcast: "When you cast this spell using a spell slot of 6th level or higher, the fire damage or the radiant damage (your choice) increases by 1d6 for each slot level above 5th.", AOE: true},
{ID: "geas", Name: "Geas", Level: 5, School: "enchantment", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassBard, ClassPaladin}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "5d10", DamageType: "psychic", Description: "You place a magical command on a creature that you can see within range, forcing it to carry out some service or refrain from some action or course of activity as you decide.", Upcast: "When you cast this spell using a spell slot of 7th or 8th level, the duration is 1 year."},
{ID: "geas", Name: "Geas", Level: 5, School: "enchantment", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassBard, ClassPaladin}, Effect: EffectDamageAuto, CastTime: CastAction, DamageDice: "5d10", DamageType: "psychic", Description: "You place a magical command on a creature that you can see, forcing it to carry out some service or refrain from some action or course of activity as you decide.", Upcast: "When you cast this spell using a spell slot of 7th or 8th level, the duration is 1 year."},
{ID: "greater_restoration", Name: "Greater Restoration", Level: 5, School: "abjuration", Classes: []DnDClass{ClassCleric, ClassDruid, ClassBard}, Effect: EffectUtility, CastTime: CastAction, Description: "You imbue a creature you touch with positive energy to undo a debilitating effect.", MaterialCost: 100},
{ID: "hallow", Name: "Hallow", Level: 5, School: "evocation", Classes: []DnDClass{ClassCleric, ClassWarlock}, Effect: EffectUtility, CastTime: CastAction, Description: "You touch a point and infuse an area around it with holy (or unholy) power.", MaterialCost: 1000, AOE: true},
{ID: "hold_monster", Name: "Hold Monster", Level: 5, School: "enchantment", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard, ClassSorcerer, ClassWarlock, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "Choose a creature you can see within range.", Upcast: "When you cast this spell using a level 6 or higher location, you can target an additional creature for each level of location beyond the fifth."},
{ID: "insect_plague", Name: "Insect Plague", Level: 5, School: "conjuration", Classes: []DnDClass{ClassCleric, ClassDruid, ClassSorcerer}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "4d10", DamageType: "piercing", Description: "Swarming, biting locusts fill a 20-foot-radius sphere centered on a point you choose within range.", Upcast: "When you cast this spell using a spell slot of 6th level or higher, the damage increases by 1d10 for each slot level above 5th.", AOE: true},
{ID: "hold_monster", Name: "Hold Monster", Level: 5, School: "enchantment", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard, ClassSorcerer, ClassWarlock, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "Choose a creature you can see.", Upcast: "When you cast this spell using a level 6 or higher location, you can target an additional creature for each level of location beyond the fifth."},
{ID: "insect_plague", Name: "Insect Plague", Level: 5, School: "conjuration", Classes: []DnDClass{ClassCleric, ClassDruid, ClassSorcerer}, Effect: EffectDamageAuto, CastTime: CastAction, Concentration: true, DamageDice: "4d10", DamageType: "piercing", Description: "A swarm of biting locusts boils up in an area. Everyone inside has Opinions about it.", Upcast: "When you cast this spell using a spell slot of 6th level or higher, the damage increases by 1d10 for each slot level above 5th.", AOE: true},
{ID: "legend_lore", Name: "Legend Lore", Level: 5, School: "divination", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard}, Effect: EffectBuffSelf, CastTime: CastAction, Description: "Name or describe a person, place, or object.", MaterialCost: 50},
{ID: "mass_cure_wounds", Name: "Mass Cure Wounds", Level: 5, School: "conjuration", Classes: []DnDClass{ClassCleric, ClassDruid, ClassBard}, Effect: EffectSpellHeal, CastTime: CastAction, DamageDice: "3d8", Description: "A wave of healing energy washes out from a point of your choice within range.", Upcast: "When you cast this spell using a spell slot of 6th level or higher, the healing increases by 1d8 for each slot level above 5th.", AOE: true},
{ID: "mass_cure_wounds", Name: "Mass Cure Wounds", Level: 5, School: "conjuration", Classes: []DnDClass{ClassCleric, ClassDruid, ClassBard}, Effect: EffectSpellHeal, CastTime: CastAction, DamageDice: "3d8", Description: "A wave of healing energy washes out from a point of your choice.", Upcast: "When you cast this spell using a spell slot of 6th level or higher, the healing increases by 1d8 for each slot level above 5th.", AOE: true},
{ID: "mislead", Name: "Mislead", Level: 5, School: "illusion", Classes: []DnDClass{ClassMage, ClassBard}, Effect: EffectBuffSelf, CastTime: CastAction, Concentration: true, Description: "You become invisible at the same time that an illusory double of you appears where you are standing."},
{ID: "modify_memory", Name: "Modify Memory", Level: 5, School: "enchantment", Classes: []DnDClass{ClassMage, ClassCleric, ClassBard}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You attempt to reshape another creature's memories.", Upcast: "If you cast this spell using a spell slot of 6th level or higher, you can alter the target's memories of an event that took place up to 7 days ago (6th level), 30 days ago (7th level), 1 year ago (8th…"},
{ID: "passwall", Name: "Passwall", Level: 5, School: "transmutation", Classes: []DnDClass{ClassMage, ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Description: "A passage appears at a point of your choice that you can see on a wooden, plaster, or stone surface (such as a wall, a ceiling, or a floor) within range, and lasts for the duration."},
{ID: "passwall", Name: "Passwall", Level: 5, School: "transmutation", Classes: []DnDClass{ClassMage, ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Description: "A passage appears at a point of your choice that you can see on a wooden, plaster, or stone surface (such as a wall, a ceiling, or a floor), and lasts for the duration."},
{ID: "planar_binding", Name: "Planar Binding", Level: 5, School: "abjuration", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassBard}, Effect: EffectUtility, CastTime: CastAction, Description: "With this spell, you attempt to bind a celestial, an elemental, a fey, or a fiend to your service.", Upcast: "When you cast this spell using a spell slot of a higher level, the duration increases to 10 days with a 6th-level slot, to 30 days with a 7th-level slot, to 180 days with an 8th-level slot, and to a y…", MaterialCost: 1000},
{ID: "raise_dead", Name: "Raise Dead", Level: 5, School: "necromancy", Classes: []DnDClass{ClassCleric, ClassBard, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Description: "You return a dead creature you touch to life, provided that it has been dead no longer than 10 days.", MaterialCost: 500},
{ID: "reincarnate", Name: "Reincarnate", Level: 5, School: "transmutation", Classes: []DnDClass{ClassDruid}, Effect: EffectUtility, CastTime: CastAction, Description: "You touch a dead humanoid or a piece of a dead humanoid.", MaterialCost: 1000},
{ID: "scrying", Name: "Scrying", Level: 5, School: "divination", Classes: []DnDClass{ClassMage, ClassCleric, ClassDruid, ClassBard, ClassWarlock, ClassPaladin}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "You can see and hear a particular creature you choose that is on the same plane of existence as you.", MaterialCost: 1000},
{ID: "seeming", Name: "Seeming", Level: 5, School: "illusion", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectBuffSelf, CastTime: CastAction, Description: "This spell allows you to change the appearance of any number of creatures that you can see within range.", AOE: true},
{ID: "seeming", Name: "Seeming", Level: 5, School: "illusion", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer, ClassWarlock}, Effect: EffectBuffSelf, CastTime: CastAction, Description: "This spell allows you to change the appearance of any number of creatures that you can see.", AOE: true},
{ID: "telekinesis", Name: "Telekinesis", Level: 5, School: "transmutation", Classes: []DnDClass{ClassMage, ClassSorcerer, ClassWarlock}, Effect: EffectBuffSelf, CastTime: CastAction, Concentration: true, Description: "You gain the ability to move or manipulate creatures or objects by thought."},
{ID: "telepathic_bond", Name: "Telepathic Bond", Level: 5, School: "divination", Classes: []DnDClass{ClassMage}, Effect: EffectUtility, CastTime: CastRitual, Description: "You forge a telepathic link among up to eight willing creatures of your choice within range, psychically linking each creature to all the others for the duration.", AOE: true},
{ID: "telepathic_bond", Name: "Telepathic Bond", Level: 5, School: "divination", Classes: []DnDClass{ClassMage}, Effect: EffectUtility, CastTime: CastRitual, Description: "You forge a telepathic link among up to eight willing creatures of your choice, psychically linking each creature to all the others for the duration.", AOE: true},
{ID: "teleportation_circle", Name: "Teleportation Circle", Level: 5, School: "conjuration", Classes: []DnDClass{ClassMage, ClassBard, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Description: "As you cast the spell, you draw a 10-foot-diameter circle on the ground inscribed with sigils that link your location to a permanent teleportation circle of your choice whose sigil sequence you know a…"},
{ID: "tree_stride", Name: "Tree Stride", Level: 5, School: "conjuration", Classes: []DnDClass{ClassCleric, ClassRanger, ClassDruid, ClassPaladin}, Effect: EffectBuffSelf, CastTime: CastAction, Concentration: true, Description: "You gain the ability to enter a tree and move from inside it to inside another tree of the same kind within 500 feet."},
{ID: "wall_of_force", Name: "Wall of Force", Level: 5, School: "evocation", Classes: []DnDClass{ClassMage}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "An invisible wall of force springs into existence at a point you choose within range."},
{ID: "wall_of_stone", Name: "Wall of Stone", Level: 5, School: "evocation", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "A nonmagical wall of solid stone springs into existence at a point you choose within range."},
{ID: "tree_stride", Name: "Tree Stride", Level: 5, School: "conjuration", Classes: []DnDClass{ClassCleric, ClassRanger, ClassDruid, ClassPaladin}, Effect: EffectBuffSelf, CastTime: CastAction, Concentration: true, Description: "You gain the ability to enter a tree and move from inside it to inside another tree of the same kind."},
{ID: "wall_of_force", Name: "Wall of Force", Level: 5, School: "evocation", Classes: []DnDClass{ClassMage}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "An invisible wall of force springs into existence at a point you choose."},
{ID: "wall_of_stone", Name: "Wall of Stone", Level: 5, School: "evocation", Classes: []DnDClass{ClassMage, ClassDruid, ClassSorcerer}, Effect: EffectUtility, CastTime: CastAction, Concentration: true, Description: "A nonmagical wall of solid stone springs into existence at a point you choose."},
}
}

View File

@@ -15,7 +15,7 @@ package plugin
func buildSRDMagicItems() []MagicItem {
return []MagicItem{
{ID: "adamantine_armor", Name: "Adamantine Armor", Kind: MagicItemArmor, Rarity: RarityUncommon, Slot: DnDSlotChest, Value: 150, Desc: "This suit of armor is reinforced with adamantine, one of the hardest substances in existence."},
{ID: "amulet_of_health", Name: "Amulet of Health", Kind: MagicItemWondrous, Rarity: RarityRare, Attunement: true, Slot: DnDSlotAmulet, Value: 750, Desc: "Your Constitution score is 19 while you wear this amulet."},
{ID: "amulet_of_health", Name: "Amulet of Health", Kind: MagicItemWondrous, Rarity: RarityRare, Attunement: true, Slot: DnDSlotAmulet, Value: 750, Desc: "Hums against your collarbone and quietly upgrades your constitution to 'bothersome to kill.'"},
{ID: "amulet_of_proof_against_detection_and_location", Name: "Amulet of Proof against Detection and Location", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotAmulet, Value: 150, Desc: "While wearing this amulet, you are hidden from divination magic."},
{ID: "amulet_of_the_planes", Name: "Amulet of the Planes", Kind: MagicItemWondrous, Rarity: RarityVeryRare, Attunement: true, Slot: DnDSlotAmulet, Value: 2500, Desc: "While wearing this amulet, you can use an action to name a location that you are familiar with on another plane of existence."},
{ID: "animated_shield", Name: "Animated Shield", Kind: MagicItemArmor, Rarity: RarityVeryRare, Attunement: true, Slot: DnDSlotChest, Value: 2500, Desc: "While holding this shield, you can speak its command word as a bonus action to cause it to animate."},
@@ -27,22 +27,22 @@ func buildSRDMagicItems() []MagicItem {
{ID: "arrow_of_slaying", Name: "Arrow of Slaying", Kind: MagicItemWeapon, Rarity: RarityVeryRare, Slot: DnDSlotMainHand, Value: 2500, Desc: "An _arrow of slaying_ is a magic weapon meant to slay a particular kind of creature."},
{ID: "bag_of_beans", Name: "Bag of Beans", Kind: MagicItemWondrous, Rarity: RarityRare, Value: 750, Desc: "Inside this heavy cloth bag are 3d4 dry beans."},
{ID: "bag_of_devouring", Name: "Bag of Devouring", Kind: MagicItemWondrous, Rarity: RarityVeryRare, Slot: DnDSlotRing1, Value: 2500, Desc: "This bag superficially resembles a _bag of holding_ but is a feeding orifice for a gigantic extradimensional creature."},
{ID: "bag_of_holding", Name: "Bag of Holding", Kind: MagicItemWondrous, Rarity: RarityUncommon, Value: 150, Desc: "This bag has an interior space considerably larger than its outside dimensions, roughly 2 feet in diameter at the mouth and 4 feet deep."},
{ID: "bag_of_holding", Name: "Bag of Holding", Kind: MagicItemWondrous, Rarity: RarityUncommon, Value: 150, Desc: "This bag has an interior space considerably larger than its outside dimensions, roughly in diameter at the mouth and deep."},
{ID: "bag_of_tricks", Name: "Bag of Tricks", Kind: MagicItemWondrous, Rarity: RarityUncommon, Value: 150, Desc: "This ordinary bag, made from gray, rust, or tan cloth, appears empty."},
{ID: "bead_of_force", Name: "Bead of Force", Kind: MagicItemWondrous, Rarity: RarityRare, Value: 750, Desc: "This small black sphere measures 3/4 of an inch in diameter and weighs an ounce."},
{ID: "belt_of_dwarvenkind", Name: "Belt of Dwarvenkind", Kind: MagicItemWondrous, Rarity: RarityRare, Attunement: true, Value: 750, Desc: "While wearing this belt, you gain the following benefits:"},
{ID: "belt_of_dwarvenkind", Name: "Belt of Dwarvenkind", Kind: MagicItemWondrous, Rarity: RarityRare, Attunement: true, Value: 750, Desc: "A stout dwarven belt — beard not included, hardiness very much included."},
{ID: "belt_of_giant_strength", Name: "Belt of Giant Strength", Kind: MagicItemWondrous, Rarity: RarityCommon, Attunement: true, Value: 50, Desc: "While wearing this belt, your Strength score changes to a score granted by the belt."},
{ID: "berserker_axe", Name: "Berserker Axe", Kind: MagicItemWeapon, Rarity: RarityRare, Attunement: true, Slot: DnDSlotMainHand, Value: 750, Desc: "You gain a +1 bonus to attack and damage rolls made with this magic weapon."},
{ID: "boots_of_elvenkind", Name: "Boots of Elvenkind", Kind: MagicItemWondrous, Rarity: RarityUncommon, Slot: DnDSlotFeet, Value: 150, Desc: "While you wear these boots, your steps make no sound, regardless of the surface you are moving across."},
{ID: "boots_of_levitation", Name: "Boots of Levitation", Kind: MagicItemWondrous, Rarity: RarityRare, Attunement: true, Slot: DnDSlotFeet, Value: 750, Desc: "While you wear these boots, you can use an action to cast the _levitate_ spell on yourself at will."},
{ID: "boots_of_speed", Name: "Boots of Speed", Kind: MagicItemWondrous, Rarity: RarityRare, Attunement: true, Slot: DnDSlotFeet, Value: 750, Desc: "While you wear these boots, you can use a bonus action and click the boots' heels together."},
{ID: "boots_of_striding_and_springing", Name: "Boots of Striding and Springing", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotRing1, Value: 150, Desc: "While you wear these boots, your walking speed becomes 30 feet, unless your walking speed is higher, and your speed isn't reduced if you are encumbered or wearing heavy armor."},
{ID: "boots_of_the_winterlands", Name: "Boots of the Winterlands", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotFeet, Value: 150, Desc: "These furred boots are snug and feel quite warm."},
{ID: "boots_of_levitation", Name: "Boots of Levitation", Kind: MagicItemWondrous, Rarity: RarityRare, Attunement: true, Slot: DnDSlotFeet, Value: 750, Desc: "Float upward at will. Down is a separate problem you'll figure out later."},
{ID: "boots_of_speed", Name: "Boots of Speed", Kind: MagicItemWondrous, Rarity: RarityRare, Attunement: true, Slot: DnDSlotFeet, Value: 750, Desc: "Click the heels together; the world starts moving at a polite walking pace."},
{ID: "boots_of_striding_and_springing", Name: "Boots of Striding and Springing", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotRing1, Value: 150, Desc: "Tireless stride and effortless hops. Ceilings: now optional."},
{ID: "boots_of_the_winterlands", Name: "Boots of the Winterlands", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotFeet, Value: 150, Desc: "Snow doesn't slow you, cold doesn't bite, and your tracks tactfully erase themselves."},
{ID: "bowl_of_commanding_water_elementals", Name: "Bowl of Commanding Water Elementals", Kind: MagicItemWondrous, Rarity: RarityRare, Value: 750, Desc: "While this bowl is filled with water, you can use an action to speak the bowl's command word and summon a water elemental, as if you had cast the _conjure elemental_ spell."},
{ID: "bracers_of_archery", Name: "Bracers of Archery", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotHands, Value: 150, Desc: "While wearing these bracers, you have proficiency with the longbow and shortbow, and you gain a +2 bonus to damage rolls on ranged attacks made with such weapons."},
{ID: "bracers_of_defense", Name: "Bracers of Defense", Kind: MagicItemWondrous, Rarity: RarityRare, Attunement: true, Slot: DnDSlotHands, Value: 750, Desc: "While wearing these bracers, you gain a +2 bonus to AC if you are wearing no armor and using no shield."},
{ID: "bracers_of_archery", Name: "Bracers of Archery", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotHands, Value: 150, Desc: "Steady your bow arm — your arrows hit harder and find seams in armour they shouldn't."},
{ID: "bracers_of_defense", Name: "Bracers of Defense", Kind: MagicItemWondrous, Rarity: RarityRare, Attunement: true, Slot: DnDSlotHands, Value: 750, Desc: "Light bracers that quietly turn aside blows. No armour required, no questions asked."},
{ID: "brazier_of_commanding_fire_elementals", Name: "Brazier of Commanding Fire Elementals", Kind: MagicItemWondrous, Rarity: RarityRare, Value: 750, Desc: "While a fire burns in this brass brazier, you can use an action to speak the brazier's command word and summon a fire elemental, as if you had cast the _conjure elemental_ spell."},
{ID: "brooch_of_shielding", Name: "Brooch of Shielding", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotAmulet, Value: 150, Desc: "While wearing this brooch, you have resistance to force damage, and you have immunity to damage from the _magic missile_ spell."},
{ID: "brooch_of_shielding", Name: "Brooch of Shielding", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotAmulet, Value: 150, Desc: "Pinned to your cloak. Eats incoming bolts of force like they're hors d'oeuvres."},
{ID: "broom_of_flying", Name: "Broom of Flying", Kind: MagicItemWondrous, Rarity: RarityUncommon, Value: 150, Desc: "This wooden broom, which weighs 3 pounds, functions like a mundane broom until you stand astride it and speak its command word."},
{ID: "candle_of_invocation", Name: "Candle of Invocation", Kind: MagicItemWondrous, Rarity: RarityVeryRare, Attunement: true, Value: 2500, Desc: "This slender taper is dedicated to a deity and shares that deity's alignment."},
{ID: "cape_of_the_mountebank", Name: "Cape of the Mountebank", Kind: MagicItemWondrous, Rarity: RarityRare, Slot: DnDSlotChest, Value: 750, Desc: "This cape smells faintly of brimstone."},
@@ -51,11 +51,11 @@ func buildSRDMagicItems() []MagicItem {
{ID: "chime_of_opening", Name: "Chime of Opening", Kind: MagicItemWondrous, Rarity: RarityRare, Value: 750, Desc: "This hollow metal tube measures about 1 foot long and weighs 1 pound."},
{ID: "circlet_of_blasting", Name: "Circlet of Blasting", Kind: MagicItemWondrous, Rarity: RarityUncommon, Slot: DnDSlotHead, Value: 150, Desc: "While wearing this circlet, you can use an action to cast the _scorching ray_ spell with it."},
{ID: "cloak_of_arachnida", Name: "Cloak of Arachnida", Kind: MagicItemWondrous, Rarity: RarityVeryRare, Attunement: true, Slot: DnDSlotChest, Value: 2500, Desc: "This fine garment is made of black silk interwoven with faint silvery threads."},
{ID: "cloak_of_displacement", Name: "Cloak of Displacement", Kind: MagicItemWondrous, Rarity: RarityRare, Attunement: true, Slot: DnDSlotChest, Value: 750, Desc: "While you wear this cloak, it projects an illusion that makes you appear to be standing in a place near your actual location, causing any creature to have disadvantage on attack rolls against you."},
{ID: "cloak_of_elvenkind", Name: "Cloak of Elvenkind", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotChest, Value: 150, Desc: "While you wear this cloak with its hood up, Wisdom (Perception) checks made to see you have disadvantage, and you have advantage on Dexterity (Stealth) checks made to hide, as the cloak's color shifts…"},
{ID: "cloak_of_protection", Name: "Cloak of Protection", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotChest, Value: 150, Desc: "You gain a +1 bonus to AC and saving throws while you wear this cloak."},
{ID: "cloak_of_the_bat", Name: "Cloak of the Bat", Kind: MagicItemWondrous, Rarity: RarityRare, Attunement: true, Slot: DnDSlotChest, Value: 750, Desc: "While wearing this cloak, you have advantage on Dexterity (Stealth) checks."},
{ID: "cloak_of_the_manta_ray", Name: "Cloak of the Manta Ray", Kind: MagicItemWondrous, Rarity: RarityUncommon, Slot: DnDSlotChest, Value: 150, Desc: "While wearing this cloak with its hood up, you can breathe underwater, and you have a swimming speed of 60 feet."},
{ID: "cloak_of_displacement", Name: "Cloak of Displacement", Kind: MagicItemWondrous, Rarity: RarityRare, Attunement: true, Slot: DnDSlotChest, Value: 750, Desc: "Bends light around you. Attackers keep swinging at where you obviously are, and missing."},
{ID: "cloak_of_elvenkind", Name: "Cloak of Elvenkind", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotChest, Value: 150, Desc: "Pulls shadows around you whether you asked or not. Watchful eyes slide right off."},
{ID: "cloak_of_protection", Name: "Cloak of Protection", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotChest, Value: 150, Desc: "A perfectly ordinary travelling cloak that perfectly extraordinarily refuses to let you get hit."},
{ID: "cloak_of_the_bat", Name: "Cloak of the Bat", Kind: MagicItemWondrous, Rarity: RarityRare, Attunement: true, Slot: DnDSlotChest, Value: 750, Desc: "By night you glide instead of fall; on a really good night, you fly. Daytime: just a cloak."},
{ID: "cloak_of_the_manta_ray", Name: "Cloak of the Manta Ray", Kind: MagicItemWondrous, Rarity: RarityUncommon, Slot: DnDSlotChest, Value: 150, Desc: "Underwater, you swim like a manta and breathe like you're on land. On land, you look damp."},
{ID: "crystal_ball", Name: "Crystal Ball", Kind: MagicItemWondrous, Rarity: RarityCommon, Attunement: true, Value: 50, Desc: "The typical _crystal ball_, a very rare item, is about 6 inches in diameter."},
{ID: "cube_of_force", Name: "Cube of Force", Kind: MagicItemWondrous, Rarity: RarityRare, Attunement: true, Value: 750, Desc: "This cube is about an inch across."},
{ID: "cubic_gate", Name: "Cubic Gate", Kind: MagicItemWondrous, Rarity: RarityLegendary, Value: 8000, Desc: "This cube is 3 inches across and radiates palpable magical energy."},
@@ -87,24 +87,24 @@ func buildSRDMagicItems() []MagicItem {
{ID: "flame_tongue", Name: "Flame Tongue", Kind: MagicItemWeapon, Rarity: RarityRare, Attunement: true, Slot: DnDSlotMainHand, Value: 750, Desc: "You can use a bonus action to speak this magic sword's command word, causing flames to erupt from the blade."},
{ID: "folding_boat", Name: "Folding Boat", Kind: MagicItemWondrous, Rarity: RarityRare, Value: 750, Desc: "This object appears as a wooden box that measures 12 inches long, 6 inches wide, and 6 inches deep."},
{ID: "frost_brand", Name: "Frost Brand", Kind: MagicItemWeapon, Rarity: RarityVeryRare, Attunement: true, Slot: DnDSlotMainHand, Value: 2500, Desc: "When you hit with an attack using this magic sword, the target takes an extra 1d6 cold damage."},
{ID: "gauntlets_of_ogre_power", Name: "Gauntlets of Ogre Power", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotHands, Value: 150, Desc: "Your Strength score is 19 while you wear these gauntlets."},
{ID: "gauntlets_of_ogre_power", Name: "Gauntlets of Ogre Power", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotHands, Value: 150, Desc: "Heavy gauntlets that lend you an ogre's strength and an ogre's complete disregard for door frames."},
{ID: "gem_of_brightness", Name: "Gem of Brightness", Kind: MagicItemWondrous, Rarity: RarityUncommon, Value: 150, Desc: "This prism has 50 charges."},
{ID: "gem_of_seeing", Name: "Gem of Seeing", Kind: MagicItemWondrous, Rarity: RarityRare, Attunement: true, Value: 750, Desc: "This gem has 3 charges."},
{ID: "giant_slayer", Name: "Giant Slayer", Kind: MagicItemWeapon, Rarity: RarityRare, Slot: DnDSlotMainHand, Value: 750, Desc: "You gain a +1 bonus to attack and damage rolls made with this magic weapon."},
{ID: "glamoured_studded_leather", Name: "Glamoured Studded Leather", Kind: MagicItemArmor, Rarity: RarityRare, Slot: DnDSlotChest, Value: 750, Desc: "While wearing this armor, you gain a +1 bonus to AC."},
{ID: "gloves_of_missile_snaring", Name: "Gloves of Missile Snaring", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotRing1, Value: 150, Desc: "These gloves seem to almost meld into your hands when you don them."},
{ID: "gloves_of_swimming_and_climbing", Name: "Gloves of Swimming and Climbing", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotHands, Value: 150, Desc: "While wearing these gloves, climbing and swimming don't cost you extra movement, and you gain a +5 bonus to Strength (Athletics) checks made to climb or swim."},
{ID: "goggles_of_night", Name: "Goggles of Night", Kind: MagicItemWondrous, Rarity: RarityUncommon, Slot: DnDSlotHead, Value: 150, Desc: "While wearing these dark lenses, you have darkvision out to a range of 60 feet."},
{ID: "goggles_of_night", Name: "Goggles of Night", Kind: MagicItemWondrous, Rarity: RarityUncommon, Slot: DnDSlotHead, Value: 150, Desc: "While wearing these dark lenses, you have darkvision."},
{ID: "hammer_of_thunderbolts", Name: "Hammer of Thunderbolts", Kind: MagicItemWeapon, Rarity: RarityLegendary, Slot: DnDSlotMainHand, Value: 8000, Desc: "You gain a +1 bonus to attack and damage rolls made with this magic weapon."},
{ID: "handy_haversack", Name: "Handy Haversack", Kind: MagicItemWondrous, Rarity: RarityRare, Value: 750, Desc: "This backpack has a central pouch and two side pouches, each of which is an extradimensional space."},
{ID: "hat_of_disguise", Name: "Hat of Disguise", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotHead, Value: 150, Desc: "While wearing this hat, you can use an action to cast the _disguise self_ spell from it at will."},
{ID: "headband_of_intellect", Name: "Headband of Intellect", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotHead, Value: 150, Desc: "Your Intelligence score is 19 while you wear this headband."},
{ID: "headband_of_intellect", Name: "Headband of Intellect", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotHead, Value: 150, Desc: "Slips on, makes you think clever thoughts you have no business thinking. People notice."},
{ID: "helm_of_brilliance", Name: "Helm of Brilliance", Kind: MagicItemWondrous, Rarity: RarityVeryRare, Attunement: true, Slot: DnDSlotHead, Value: 2500, Desc: "This dazzling helm is set with 1d10 diamonds, 2d10 rubies, 3d10 fire opals, and 4d10 opals."},
{ID: "helm_of_comprehending_languages", Name: "Helm of Comprehending Languages", Kind: MagicItemWondrous, Rarity: RarityUncommon, Slot: DnDSlotHead, Value: 150, Desc: "While wearing this helm, you can use an action to cast the _comprehend languages_ spell from it at will."},
{ID: "helm_of_telepathy", Name: "Helm of Telepathy", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotHead, Value: 150, Desc: "While wearing this helm, you can use an action to cast the _detect thoughts_ spell (save DC 13) from it."},
{ID: "helm_of_telepathy", Name: "Helm of Telepathy", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotHead, Value: 150, Desc: "While wearing this helm, you can use an action to cast the _detect thoughts_ spell from it."},
{ID: "helm_of_teleportation", Name: "Helm of Teleportation", Kind: MagicItemWondrous, Rarity: RarityRare, Attunement: true, Slot: DnDSlotHead, Value: 750, Desc: "This helm has 3 charges."},
{ID: "holy_avenger", Name: "Holy Avenger", Kind: MagicItemWeapon, Rarity: RarityLegendary, Attunement: true, Slot: DnDSlotMainHand, Value: 8000, Desc: "You gain a +3 bonus to attack and damage rolls made with this magic weapon."},
{ID: "horn_of_blasting", Name: "Horn of Blasting", Kind: MagicItemWondrous, Rarity: RarityRare, Value: 750, Desc: "You can use an action to speak the horn's command word and then blow the horn, which emits a thunderous blast in a 30-foot cone that is audible 600 feet away."},
{ID: "horn_of_blasting", Name: "Horn of Blasting", Kind: MagicItemWondrous, Rarity: RarityRare, Value: 750, Desc: "You can use an action to speak the horn's command word and then blow the horn, which emits a thunderous blast in a that is audible away."},
{ID: "horn_of_valhalla", Name: "Horn of Valhalla", Kind: MagicItemWondrous, Rarity: RarityCommon, Value: 50, Desc: "You can use an action to blow this horn."},
{ID: "horseshoes_of_a_zephyr", Name: "Horseshoes of a Zephyr", Kind: MagicItemWondrous, Rarity: RarityVeryRare, Value: 2500, Desc: "These iron horseshoes come in a set of four."},
{ID: "horseshoes_of_speed", Name: "Horseshoes of Speed", Kind: MagicItemWondrous, Rarity: RarityRare, Value: 750, Desc: "These iron horseshoes come in a set of four."},
@@ -114,12 +114,12 @@ func buildSRDMagicItems() []MagicItem {
{ID: "iron_bands_of_binding", Name: "Iron Bands of Binding", Kind: MagicItemWondrous, Rarity: RarityRare, Value: 750, Desc: "This rusty iron sphere measures 3 inches in diameter and weighs 1 pound."},
{ID: "iron_flask", Name: "Iron Flask", Kind: MagicItemWondrous, Rarity: RarityLegendary, Value: 8000, Desc: "This iron bottle has a brass stopper."},
{ID: "javelin_of_lightning", Name: "Javelin of Lightning", Kind: MagicItemWeapon, Rarity: RarityUncommon, Slot: DnDSlotMainHand, Value: 150, Desc: "This javelin is a magic weapon."},
{ID: "lantern_of_revealing", Name: "Lantern of Revealing", Kind: MagicItemWondrous, Rarity: RarityUncommon, Value: 150, Desc: "While lit, this hooded lantern burns for 6 hours on 1 pint of oil, shedding bright light in a 30-foot radius and dim light for an additional 30 feet."},
{ID: "lantern_of_revealing", Name: "Lantern of Revealing", Kind: MagicItemWondrous, Rarity: RarityUncommon, Value: 150, Desc: "While lit, this hooded lantern burns for 6 hours on 1 pint of oil, shedding bright light in a and dim light for an additional."},
{ID: "luck_blade", Name: "Luck Blade", Kind: MagicItemWeapon, Rarity: RarityLegendary, Attunement: true, Slot: DnDSlotMainHand, Value: 8000, Desc: "You gain a +1 bonus to attack and damage rolls made with this magic weapon."},
{ID: "mace_of_disruption", Name: "Mace of Disruption", Kind: MagicItemWeapon, Rarity: RarityRare, Attunement: true, Slot: DnDSlotMainHand, Value: 750, Desc: "When you hit a fiend or an undead with this magic weapon, that creature takes an extra 2d6 radiant damage."},
{ID: "mace_of_smiting", Name: "Mace of Smiting", Kind: MagicItemWeapon, Rarity: RarityRare, Slot: DnDSlotMainHand, Value: 750, Desc: "You gain a +1 bonus to attack and damage rolls made with this magic weapon."},
{ID: "mace_of_terror", Name: "Mace of Terror", Kind: MagicItemWeapon, Rarity: RarityRare, Attunement: true, Slot: DnDSlotMainHand, Value: 750, Desc: "This magic weapon has 3 charges."},
{ID: "mantle_of_spell_resistance", Name: "Mantle of Spell Resistance", Kind: MagicItemWondrous, Rarity: RarityRare, Attunement: true, Slot: DnDSlotChest, Value: 750, Desc: "You have advantage on saving throws against spells while you wear this cloak."},
{ID: "mantle_of_spell_resistance", Name: "Mantle of Spell Resistance", Kind: MagicItemWondrous, Rarity: RarityRare, Attunement: true, Slot: DnDSlotChest, Value: 750, Desc: "You have advantage on against spells while you wear this cloak."},
{ID: "manual_of_bodily_health", Name: "Manual of Bodily Health", Kind: MagicItemWondrous, Rarity: RarityVeryRare, Value: 2500, Desc: "This book contains health and diet tips, and its words are charged with magic."},
{ID: "manual_of_gainful_exercise", Name: "Manual of Gainful Exercise", Kind: MagicItemWondrous, Rarity: RarityVeryRare, Value: 2500, Desc: "This book describes fitness exercises, and its words are charged with magic."},
{ID: "manual_of_golems", Name: "Manual of Golems", Kind: MagicItemWondrous, Rarity: RarityVeryRare, Value: 2500, Desc: "This tome contains information and incantations necessary to make a particular type of golem."},
@@ -128,7 +128,7 @@ func buildSRDMagicItems() []MagicItem {
{ID: "medallion_of_thoughts", Name: "Medallion of Thoughts", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotAmulet, Value: 150, Desc: "The medallion has 3 charges."},
{ID: "mirror_of_life_trapping", Name: "Mirror of Life Trapping", Kind: MagicItemWondrous, Rarity: RarityVeryRare, Value: 2500, Desc: "When this 4-foot-tall mirror is viewed indirectly, its surface shows faint images of creatures."},
{ID: "mithral_armor", Name: "Mithral Armor", Kind: MagicItemArmor, Rarity: RarityUncommon, Slot: DnDSlotChest, Value: 150, Desc: "Mithral is a light, flexible metal."},
{ID: "necklace_of_adaptation", Name: "Necklace of Adaptation", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotAmulet, Value: 150, Desc: "While wearing this necklace, you can breathe normally in any environment, and you have advantage on saving throws made against harmful gases and vapors (such as _cloudkill_ and _stinking cloud_ effect…"},
{ID: "necklace_of_adaptation", Name: "Necklace of Adaptation", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotAmulet, Value: 150, Desc: "While wearing this necklace, you can breathe normally in any environment, and you have advantage on made against harmful gases and vapors (such as _cloudkill_ and _stinking cloud_ effects, inhaled poi…"},
{ID: "necklace_of_fireballs", Name: "Necklace of Fireballs", Kind: MagicItemWondrous, Rarity: RarityRare, Slot: DnDSlotAmulet, Value: 750, Desc: "This necklace has 1d6 + 3 beads hanging from it."},
{ID: "necklace_of_prayer_beads", Name: "Necklace of Prayer Beads", Kind: MagicItemWondrous, Rarity: RarityRare, Attunement: true, Slot: DnDSlotAmulet, Value: 750, Desc: "This necklace has 1d4 + 2 magic beads made from aquamarine, black pearl, or topaz."},
{ID: "nine_lives_stealer", Name: "Nine Lives Stealer", Kind: MagicItemWeapon, Rarity: RarityVeryRare, Attunement: true, Slot: DnDSlotMainHand, Value: 2500, Desc: "You gain a +2 bonus to attack and damage rolls made with this magic weapon."},
@@ -137,7 +137,7 @@ func buildSRDMagicItems() []MagicItem {
{ID: "oil_of_sharpness", Name: "Oil of Sharpness", Kind: MagicItemPotion, Rarity: RarityVeryRare, Value: 2500, Desc: "This clear, gelatinous oil sparkles with tiny, ultrathin silver shards."},
{ID: "oil_of_slipperiness", Name: "Oil of Slipperiness", Kind: MagicItemPotion, Rarity: RarityUncommon, Value: 150, Desc: "This sticky black unguent is thick and heavy in the container, but it flows quickly when poured."},
{ID: "orb_of_dragonkind", Name: "Orb of Dragonkind", Kind: MagicItemWondrous, Rarity: RarityLegendary, Attunement: true, Value: 8000, Desc: "Ages past, elves and humans waged a terrible war against evil dragons."},
{ID: "pearl_of_power", Name: "Pearl of Power", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Value: 150, Desc: "While this pearl is on your person, you can use an action to speak its command word and regain one expended spell slot."},
{ID: "pearl_of_power", Name: "Pearl of Power", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Value: 150, Desc: "While this pearl is on your person, you can use an action to speak its command word and regain one expended."},
{ID: "periapt_of_health", Name: "Periapt of Health", Kind: MagicItemWondrous, Rarity: RarityUncommon, Slot: DnDSlotAmulet, Value: 150, Desc: "You are immune to contracting any disease while you wear this pendant."},
{ID: "periapt_of_proof_against_poison", Name: "Periapt of Proof against Poison", Kind: MagicItemWondrous, Rarity: RarityRare, Slot: DnDSlotAmulet, Value: 750, Desc: "This delicate silver chain has a brilliant-cut black gem pendant."},
{ID: "periapt_of_wound_closure", Name: "Periapt of Wound Closure", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotAmulet, Value: 150, Desc: "While you wear this pendant, you stabilize whenever you are dying at the start of your turn."},
@@ -146,7 +146,7 @@ func buildSRDMagicItems() []MagicItem {
{ID: "pipes_of_the_sewers", Name: "Pipes of the Sewers", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Value: 150, Desc: "You must be proficient with wind instruments to use these pipes."},
{ID: "plate_armor_of_etherealness", Name: "Plate Armor of Etherealness", Kind: MagicItemArmor, Rarity: RarityLegendary, Attunement: true, Slot: DnDSlotChest, Value: 8000, Desc: "While you're wearing this armor, you can speak its command word as an action to gain the effect of the _etherealness_ spell, which last for 10 minutes or until you remove the armor or use an action to…"},
{ID: "portable_hole", Name: "Portable Hole", Kind: MagicItemWondrous, Rarity: RarityRare, Value: 750, Desc: "This fine black cloth, soft as silk, is folded up to the dimensions of a handkerchief."},
{ID: "potion_of_animal_friendship", Name: "Potion of Animal Friendship", Kind: MagicItemPotion, Rarity: RarityUncommon, Value: 150, Desc: "When you drink this potion, you can cast the _animal friendship_ spell (save DC 13) for 1 hour at will."},
{ID: "potion_of_animal_friendship", Name: "Potion of Animal Friendship", Kind: MagicItemPotion, Rarity: RarityUncommon, Value: 150, Desc: "When you drink this potion, you can cast the _animal friendship_ spell for 1 hour at will."},
{ID: "potion_of_clairvoyance", Name: "Potion of Clairvoyance", Kind: MagicItemPotion, Rarity: RarityRare, Value: 750, Desc: "When you drink this potion, you gain the effect of the _clairvoyance_ spell."},
{ID: "potion_of_climbing", Name: "Potion of Climbing", Kind: MagicItemPotion, Rarity: RarityCommon, Value: 50, Desc: "When you drink this potion, you gain a climbing speed equal to your walking speed for 1 hour."},
{ID: "potion_of_diminution", Name: "Potion of Diminution", Kind: MagicItemPotion, Rarity: RarityRare, Value: 750, Desc: "When you drink this potion, you gain the \"reduce\" effect of the _enlarge/reduce_ spell for 1d4 hours (no concentration required)."},
@@ -157,7 +157,7 @@ func buildSRDMagicItems() []MagicItem {
{ID: "potion_of_healing", Name: "Potion of Healing", Kind: MagicItemPotion, Rarity: RarityCommon, Value: 50, Desc: "You regain hit points when you drink this potion."},
{ID: "potion_of_heroism", Name: "Potion of Heroism", Kind: MagicItemPotion, Rarity: RarityRare, Value: 750, Desc: "For 1 hour after drinking it, you gain 10 temporary hit points that last for 1 hour."},
{ID: "potion_of_invisibility", Name: "Potion of Invisibility", Kind: MagicItemPotion, Rarity: RarityVeryRare, Value: 2500, Desc: "This potion's container looks empty but feels as though it holds liquid."},
{ID: "potion_of_mind_reading", Name: "Potion of Mind Reading", Kind: MagicItemPotion, Rarity: RarityRare, Value: 750, Desc: "When you drink this potion, you gain the effect of the _detect thoughts_ spell (save DC 13)."},
{ID: "potion_of_mind_reading", Name: "Potion of Mind Reading", Kind: MagicItemPotion, Rarity: RarityRare, Value: 750, Desc: "When you drink this potion, you gain the effect of the _detect thoughts_ spell."},
{ID: "potion_of_poison", Name: "Potion of Poison", Kind: MagicItemPotion, Rarity: RarityUncommon, Value: 150, Desc: "This concoction looks, smells, and tastes like a _potion of healing_ or other beneficial potion."},
{ID: "potion_of_resistance", Name: "Potion of Resistance", Kind: MagicItemPotion, Rarity: RarityUncommon, Value: 150, Desc: "When you drink this potion, you gain resistance to one type of damage for 1 hour."},
{ID: "potion_of_speed", Name: "Potion of Speed", Kind: MagicItemPotion, Rarity: RarityVeryRare, Value: 2500, Desc: "When you drink this potion, you gain the effect of the _haste_ spell for 1 minute (no concentration required)."},
@@ -167,22 +167,22 @@ func buildSRDMagicItems() []MagicItem {
{ID: "ring_of_djinni_summoning", Name: "Ring of Djinni Summoning", Kind: MagicItemRing, Rarity: RarityLegendary, Attunement: true, Slot: DnDSlotRing1, Value: 8000, Desc: "While wearing this ring, you can speak its command word as an action to summon a particular djinni from the Elemental Plane of Air."},
{ID: "ring_of_elemental_command", Name: "Ring of Elemental Command", Kind: MagicItemRing, Rarity: RarityLegendary, Attunement: true, Slot: DnDSlotRing1, Value: 8000, Desc: "This ring is linked to one of the four Elemental Planes."},
{ID: "ring_of_evasion", Name: "Ring of Evasion", Kind: MagicItemRing, Rarity: RarityRare, Attunement: true, Slot: DnDSlotRing1, Value: 750, Desc: "This ring has 3 charges, and it regains 1d3 expended charges daily at dawn."},
{ID: "ring_of_feather_falling", Name: "Ring of Feather Falling", Kind: MagicItemRing, Rarity: RarityRare, Attunement: true, Slot: DnDSlotRing1, Value: 750, Desc: "When you fall while wearing this ring, you descend 60 feet per round and take no damage from falling."},
{ID: "ring_of_feather_falling", Name: "Ring of Feather Falling", Kind: MagicItemRing, Rarity: RarityRare, Attunement: true, Slot: DnDSlotRing1, Value: 750, Desc: "When you fall while wearing this ring, you descend per round and take no damage from falling."},
{ID: "ring_of_free_action", Name: "Ring of Free Action", Kind: MagicItemRing, Rarity: RarityRare, Attunement: true, Slot: DnDSlotRing1, Value: 750, Desc: "While you wear this ring, difficult terrain doesn't cost you extra movement."},
{ID: "ring_of_invisibility", Name: "Ring of Invisibility", Kind: MagicItemRing, Rarity: RarityLegendary, Attunement: true, Slot: DnDSlotRing1, Value: 8000, Desc: "While wearing this ring, you can turn invisible as an action."},
{ID: "ring_of_jumping", Name: "Ring of Jumping", Kind: MagicItemRing, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotRing1, Value: 150, Desc: "While wearing this ring, you can cast the _jump_ spell from it as a bonus action at will, but can target only yourself when you do so."},
{ID: "ring_of_mind_shielding", Name: "Ring of Mind Shielding", Kind: MagicItemRing, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotRing1, Value: 150, Desc: "While wearing this ring, you are immune to magic that allows other creatures to read your thoughts, determine whether you are lying, know your alignment, or know your creature type."},
{ID: "ring_of_protection", Name: "Ring of Protection", Kind: MagicItemRing, Rarity: RarityRare, Attunement: true, Slot: DnDSlotRing1, Value: 750, Desc: "You gain a +1 bonus to AC and saving throws while wearing this ring."},
{ID: "ring_of_regeneration", Name: "Ring of Regeneration", Kind: MagicItemRing, Rarity: RarityVeryRare, Attunement: true, Slot: DnDSlotRing1, Value: 2500, Desc: "While wearing this ring, you regain 1d6 hit points every 10 minutes, provided that you have at least 1 hit point."},
{ID: "ring_of_resistance", Name: "Ring of Resistance", Kind: MagicItemRing, Rarity: RarityRare, Attunement: true, Slot: DnDSlotRing1, Value: 750, Desc: "You have resistance to one damage type while wearing this ring."},
{ID: "ring_of_protection", Name: "Ring of Protection", Kind: MagicItemRing, Rarity: RarityRare, Attunement: true, Slot: DnDSlotRing1, Value: 750, Desc: "A plain ring. Quietly turns aside blows you'd otherwise take. Refuses to explain how."},
{ID: "ring_of_regeneration", Name: "Ring of Regeneration", Kind: MagicItemRing, Rarity: RarityVeryRare, Attunement: true, Slot: DnDSlotRing1, Value: 2500, Desc: "Wounds knit themselves back together while you wear it. Slowly. Smugly."},
{ID: "ring_of_resistance", Name: "Ring of Resistance", Kind: MagicItemRing, Rarity: RarityRare, Attunement: true, Slot: DnDSlotRing1, Value: 750, Desc: "Wards off one kind of harm — fire, frost, lightning, poison, or another flavour of bad day."},
{ID: "ring_of_shooting_stars", Name: "Ring of Shooting Stars", Kind: MagicItemRing, Rarity: RarityVeryRare, Attunement: true, Slot: DnDSlotRing1, Value: 2500, Desc: "While wearing this ring in dim light or darkness, you can cast _dancing lights_ and _light_ from the ring at will."},
{ID: "ring_of_spell_storing", Name: "Ring of Spell Storing", Kind: MagicItemRing, Rarity: RarityRare, Attunement: true, Slot: DnDSlotRing1, Value: 750, Desc: "This ring stores spells cast into it, holding them until the attuned wearer uses them."},
{ID: "ring_of_spell_turning", Name: "Ring of Spell Turning", Kind: MagicItemRing, Rarity: RarityLegendary, Attunement: true, Slot: DnDSlotRing1, Value: 8000, Desc: "While wearing this ring, you have advantage on saving throws against any spell that targets only you (not in an area of effect)."},
{ID: "ring_of_swimming", Name: "Ring of Swimming", Kind: MagicItemRing, Rarity: RarityUncommon, Slot: DnDSlotRing1, Value: 150, Desc: "You have a swimming speed of 40 feet while wearing this ring."},
{ID: "ring_of_spell_turning", Name: "Ring of Spell Turning", Kind: MagicItemRing, Rarity: RarityLegendary, Attunement: true, Slot: DnDSlotRing1, Value: 8000, Desc: "While wearing this ring, you have advantage on against any spell that targets only you (not in an area of effect)."},
{ID: "ring_of_swimming", Name: "Ring of Swimming", Kind: MagicItemRing, Rarity: RarityUncommon, Slot: DnDSlotRing1, Value: 150, Desc: "Slip through water faster than any swimmer should. Dolphins file complaints."},
{ID: "ring_of_telekinesis", Name: "Ring of Telekinesis", Kind: MagicItemRing, Rarity: RarityVeryRare, Attunement: true, Slot: DnDSlotRing1, Value: 2500, Desc: "While wearing this ring, you can cast the _telekinesis_ spell at will, but you can target only objects that aren't being worn or carried."},
{ID: "ring_of_the_ram", Name: "Ring of the Ram", Kind: MagicItemRing, Rarity: RarityRare, Attunement: true, Slot: DnDSlotRing1, Value: 750, Desc: "This ring has 3 charges, and it regains 1d3 expended charges daily at dawn."},
{ID: "ring_of_three_wishes", Name: "Ring of Three Wishes", Kind: MagicItemRing, Rarity: RarityLegendary, Slot: DnDSlotRing1, Value: 8000, Desc: "While wearing this ring, you can use an action to expend 1 of its 3 charges to cast the _wish_ spell from it."},
{ID: "ring_of_warmth", Name: "Ring of Warmth", Kind: MagicItemRing, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotRing1, Value: 150, Desc: "While wearing this ring, you have resistance to cold damage."},
{ID: "ring_of_warmth", Name: "Ring of Warmth", Kind: MagicItemRing, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotRing1, Value: 150, Desc: "Cold weather no longer applies to you. Chill damage softens; you become unbearable in winter."},
{ID: "ring_of_water_walking", Name: "Ring of Water Walking", Kind: MagicItemRing, Rarity: RarityUncommon, Slot: DnDSlotRing1, Value: 150, Desc: "While wearing this ring, you can stand on and move across any liquid surface as if it were solid ground."},
{ID: "ring_of_x_ray_vision", Name: "Ring of X-ray Vision", Kind: MagicItemRing, Rarity: RarityRare, Attunement: true, Slot: DnDSlotRing1, Value: 750, Desc: "While wearing this ring, you can use an action to speak its command word."},
{ID: "robe_of_eyes", Name: "Robe of Eyes", Kind: MagicItemWondrous, Rarity: RarityRare, Attunement: true, Slot: DnDSlotChest, Value: 750, Desc: "This robe is adorned with eyelike patterns."},
@@ -193,17 +193,17 @@ func buildSRDMagicItems() []MagicItem {
{ID: "rod_of_absorption", Name: "Rod of Absorption", Kind: MagicItemRod, Rarity: RarityVeryRare, Attunement: true, Slot: DnDSlotOffHand, Value: 2500, Desc: "While holding this rod, you can use your reaction to absorb a spell that is targeting only you and not with an area of effect."},
{ID: "rod_of_alertness", Name: "Rod of Alertness", Kind: MagicItemRod, Rarity: RarityVeryRare, Attunement: true, Slot: DnDSlotOffHand, Value: 2500, Desc: "This rod has a flanged head and the following properties."},
{ID: "rod_of_lordly_might", Name: "Rod of Lordly Might", Kind: MagicItemRod, Rarity: RarityLegendary, Attunement: true, Slot: DnDSlotOffHand, Value: 8000, Desc: "This rod has a flanged head, and it functions as a magic mace that grants a +3 bonus to attack and damage rolls made with it."},
{ID: "rod_of_rulership", Name: "Rod of Rulership", Kind: MagicItemRod, Rarity: RarityRare, Attunement: true, Slot: DnDSlotOffHand, Value: 750, Desc: "You can use an action to present the rod and command obedience from each creature of your choice that you can see within 120 feet of you."},
{ID: "rod_of_rulership", Name: "Rod of Rulership", Kind: MagicItemRod, Rarity: RarityRare, Attunement: true, Slot: DnDSlotOffHand, Value: 750, Desc: "You can use an action to present the rod and command obedience from each creature of your choice that you can seeou."},
{ID: "rod_of_security", Name: "Rod of Security", Kind: MagicItemRod, Rarity: RarityVeryRare, Slot: DnDSlotOffHand, Value: 2500, Desc: "While holding this rod, you can use an action to activate it."},
{ID: "rope_of_climbing", Name: "Rope of Climbing", Kind: MagicItemWondrous, Rarity: RarityUncommon, Value: 150, Desc: "This 60-foot length of silk rope weighs 3 pounds and can hold up to 3,000 pounds."},
{ID: "rope_of_entanglement", Name: "Rope of Entanglement", Kind: MagicItemWondrous, Rarity: RarityRare, Value: 750, Desc: "This rope is 30 feet long and weighs 3 pounds."},
{ID: "rope_of_entanglement", Name: "Rope of Entanglement", Kind: MagicItemWondrous, Rarity: RarityRare, Value: 750, Desc: "This rope is long and weighs 3 pounds."},
{ID: "scarab_of_protection", Name: "Scarab of Protection", Kind: MagicItemWondrous, Rarity: RarityLegendary, Attunement: true, Value: 8000, Desc: "If you hold this beetle-shaped medallion in your hand for 1 round, an inscription appears on its surface revealing its magical nature."},
{ID: "scimitar_of_speed", Name: "Scimitar of Speed", Kind: MagicItemWeapon, Rarity: RarityVeryRare, Attunement: true, Slot: DnDSlotMainHand, Value: 2500, Desc: "You gain a +2 bonus to attack and damage rolls made with this magic weapon."},
{ID: "shield_of_missile_attraction", Name: "Shield of Missile Attraction", Kind: MagicItemArmor, Rarity: RarityRare, Attunement: true, Slot: DnDSlotChest, Value: 750, Desc: "While holding this shield, you have resistance to damage from ranged weapon attacks."},
{ID: "slippers_of_spider_climbing", Name: "Slippers of Spider Climbing", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotFeet, Value: 150, Desc: "While you wear these light shoes, you can move up, down, and across vertical surfaces and upside down along ceilings, while leaving your hands free."},
{ID: "slippers_of_spider_climbing", Name: "Slippers of Spider Climbing", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotFeet, Value: 150, Desc: "Walk up walls and across ceilings as if the floor were merely a suggestion."},
{ID: "sovereign_glue", Name: "Sovereign Glue", Kind: MagicItemWondrous, Rarity: RarityLegendary, Value: 8000, Desc: "This viscous, milky-white substance can form a permanent adhesive bond between any two objects."},
{ID: "spell_scroll", Name: "Spell Scroll", Kind: MagicItemScroll, Rarity: RarityCommon, Value: 50, Desc: "A _spell scroll_ bears the words of a single spell, written in a mystical cipher."},
{ID: "spellguard_shield", Name: "Spellguard Shield", Kind: MagicItemArmor, Rarity: RarityVeryRare, Attunement: true, Slot: DnDSlotChest, Value: 2500, Desc: "While holding this shield, you have advantage on saving throws against spells and other magical effects, and spell attacks have disadvantage against you."},
{ID: "spellguard_shield", Name: "Spellguard Shield", Kind: MagicItemArmor, Rarity: RarityVeryRare, Attunement: true, Slot: DnDSlotChest, Value: 2500, Desc: "While holding this shield, you have advantage on against spells and other magical effects, and spell attacks have disadvantage against you."},
{ID: "sphere_of_annihilation", Name: "Sphere of Annihilation", Kind: MagicItemWondrous, Rarity: RarityLegendary, Value: 8000, Desc: "This 2-foot-diameter black sphere is a hole in the multiverse, hovering in space and stabilized by a magical field surrounding it."},
{ID: "staff_of_charming", Name: "Staff of Charming", Kind: MagicItemStaff, Rarity: RarityRare, Attunement: true, Slot: DnDSlotMainHand, Value: 750, Desc: "While holding this staff, you can use an action to expend 1 of its 10 charges to cast _charm person_, _command_, _or comprehend languages_ from it using your spell save DC."},
{ID: "staff_of_fire", Name: "Staff of Fire", Kind: MagicItemStaff, Rarity: RarityVeryRare, Attunement: true, Slot: DnDSlotMainHand, Value: 2500, Desc: "You have resistance to fire damage while you hold this staff."},
@@ -213,12 +213,12 @@ func buildSRDMagicItems() []MagicItem {
{ID: "staff_of_striking", Name: "Staff of Striking", Kind: MagicItemStaff, Rarity: RarityVeryRare, Attunement: true, Slot: DnDSlotMainHand, Value: 2500, Desc: "This staff can be wielded as a magic quarterstaff that grants a +3 bonus to attack and damage rolls made with it."},
{ID: "staff_of_swarming_insects", Name: "Staff of Swarming Insects", Kind: MagicItemStaff, Rarity: RarityVeryRare, Attunement: true, Slot: DnDSlotMainHand, Value: 2500, Desc: "This staff has 10 charges and regains 1d6 + 4 expended charges daily at dawn."},
{ID: "staff_of_the_magi", Name: "Staff of the Magi", Kind: MagicItemStaff, Rarity: RarityLegendary, Attunement: true, Slot: DnDSlotMainHand, Value: 8000, Desc: "This staff can be wielded as a magic quarterstaff that grants a +2 bonus to attack and damage rolls made with it."},
{ID: "staff_of_the_python", Name: "Staff of the Python", Kind: MagicItemStaff, Rarity: RarityVeryRare, Attunement: true, Slot: DnDSlotMainHand, Value: 2500, Desc: "You can use an action to speak this staff's command word and throw the staff on the ground within 10 feet of you."},
{ID: "staff_of_the_python", Name: "Staff of the Python", Kind: MagicItemStaff, Rarity: RarityVeryRare, Attunement: true, Slot: DnDSlotMainHand, Value: 2500, Desc: "You can use an action to speak this staff's command word and throw the staff on the groundou."},
{ID: "staff_of_the_woodlands", Name: "Staff of the Woodlands", Kind: MagicItemStaff, Rarity: RarityRare, Attunement: true, Slot: DnDSlotMainHand, Value: 750, Desc: "This staff can be wielded as a magic quarterstaff that grants a +2 bonus to attack and damage rolls made with it."},
{ID: "staff_of_thunder_and_lightning", Name: "Staff of Thunder and Lightning", Kind: MagicItemStaff, Rarity: RarityVeryRare, Attunement: true, Slot: DnDSlotMainHand, Value: 2500, Desc: "This staff can be wielded as a magic quarterstaff that grants a +2 bonus to attack and damage rolls made with it."},
{ID: "staff_of_withering", Name: "Staff of Withering", Kind: MagicItemStaff, Rarity: RarityRare, Attunement: true, Slot: DnDSlotMainHand, Value: 750, Desc: "This staff has 3 charges and regains 1d3 expended charges daily at dawn."},
{ID: "stone_of_controlling_earth_elementals", Name: "Stone of Controlling Earth Elementals", Kind: MagicItemWondrous, Rarity: RarityRare, Value: 750, Desc: "If the stone is touching the ground, you can use an action to speak its command word and summon an earth elemental, as if you had cast the _conjure elemental_ spell."},
{ID: "stone_of_good_luck_luckstone", Name: "Stone of Good Luck (Luckstone)", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Value: 150, Desc: "While this polished agate is on your person, you gain a +1 bonus to ability checks and saving throws."},
{ID: "stone_of_good_luck_luckstone", Name: "Stone of Good Luck", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Value: 150, Desc: "While this polished agate is on your person, you gain a +1 bonus to ability checks."},
{ID: "sun_blade", Name: "Sun Blade", Kind: MagicItemWeapon, Rarity: RarityRare, Attunement: true, Slot: DnDSlotMainHand, Value: 750, Desc: "This item appears to be a longsword hilt."},
{ID: "sword_of_life_stealing", Name: "Sword of Life Stealing", Kind: MagicItemWeapon, Rarity: RarityRare, Attunement: true, Slot: DnDSlotMainHand, Value: 750, Desc: "When you attack a creature with this magic weapon and roll a 20 on the attack roll, that target takes an extra 3d6 necrotic damage, provided that the target isn't a construct or an undead."},
{ID: "sword_of_sharpness", Name: "Sword of Sharpness", Kind: MagicItemWeapon, Rarity: RarityVeryRare, Attunement: true, Slot: DnDSlotMainHand, Value: 2500, Desc: "When you attack an object with this magic sword and hit, maximize your weapon damage dice against the target."},
@@ -248,7 +248,7 @@ func buildSRDMagicItems() []MagicItem {
{ID: "wand_of_wonder", Name: "Wand of Wonder", Kind: MagicItemWand, Rarity: RarityRare, Attunement: true, Slot: DnDSlotOffHand, Value: 750, Desc: "This wand has 7 charges."},
{ID: "weapon_1_2_or_3", Name: "Weapon, +1, +2, or +3", Kind: MagicItemWeapon, Rarity: RarityCommon, Slot: DnDSlotMainHand, Value: 50, Desc: "You have a bonus to attack and damage rolls made with this magic weapon."},
{ID: "well_of_many_worlds", Name: "Well of Many Worlds", Kind: MagicItemWondrous, Rarity: RarityLegendary, Value: 8000, Desc: "This fine black cloth, soft as silk, is folded up to the dimensions of a handkerchief."},
{ID: "wind_fan", Name: "Wind Fan", Kind: MagicItemWondrous, Rarity: RarityUncommon, Value: 150, Desc: "While holding this fan, you can use an action to cast the _gust of wind_ spell (save DC 13) from it."},
{ID: "wind_fan", Name: "Wind Fan", Kind: MagicItemWondrous, Rarity: RarityUncommon, Value: 150, Desc: "While holding this fan, you can use an action to cast the _gust of wind_ spell from it."},
{ID: "winged_boots", Name: "Winged Boots", Kind: MagicItemWondrous, Rarity: RarityUncommon, Attunement: true, Slot: DnDSlotFeet, Value: 150, Desc: "While you wear these boots, you have a flying speed equal to your walking speed."},
{ID: "wings_of_flying", Name: "Wings of Flying", Kind: MagicItemWondrous, Rarity: RarityRare, Attunement: true, Value: 750, Desc: "While wearing this cloak, you can use an action to speak its command word."},
}