Spellcasting expansion
This commit is contained in:
@@ -1740,6 +1740,57 @@ tables:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWikiTemplateRendersClassProgressionSpellcastingAdvancementNotes(t *testing.T) {
|
||||||
|
ctx := testWikiTableContext(t, `
|
||||||
|
tables:
|
||||||
|
ClassProgression:
|
||||||
|
source: class_progression
|
||||||
|
rows:
|
||||||
|
levels: 1-4
|
||||||
|
columns:
|
||||||
|
- key: level
|
||||||
|
label: Lvl
|
||||||
|
value: "{{Level}}"
|
||||||
|
- key: notes
|
||||||
|
label: Notes
|
||||||
|
value: "{{SpellcastingAdvancementNote + if(present(SpellcastingAdvancementNote) && present(Notes), \" \", \"\") + Notes}}"
|
||||||
|
empty: ""
|
||||||
|
`)
|
||||||
|
page := wikiTemplatePage{
|
||||||
|
PageID: "classes:pale_master",
|
||||||
|
Category: "classes",
|
||||||
|
Key: "classes:pale_master",
|
||||||
|
Title: "Pale Master",
|
||||||
|
Row: map[string]any{
|
||||||
|
"SpellCaster": 0,
|
||||||
|
"ArcSpellLvlMod": 2,
|
||||||
|
"DivSpellLvlMod": 0,
|
||||||
|
"meta": map[string]any{
|
||||||
|
"wiki": map[string]any{
|
||||||
|
"progression_notes": map[string]any{
|
||||||
|
"3": "Manual level note.",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
got, err := ctx.renderWikiTemplateString("classes.html", `{{table:ClassProgression}}`, page)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("render table template: %v", err)
|
||||||
|
}
|
||||||
|
for _, expected := range []string{
|
||||||
|
`<tr><td>1</td><td>+1 level of existing arcane spellcasting class</td></tr>`,
|
||||||
|
`<tr><td>2</td><td></td></tr>`,
|
||||||
|
`<tr><td>3</td><td>+1 level of existing arcane spellcasting class Manual level note.</td></tr>`,
|
||||||
|
`<tr><td>4</td><td></td></tr>`,
|
||||||
|
} {
|
||||||
|
if !strings.Contains(got, expected) {
|
||||||
|
t.Fatalf("expected %q in rendered table:\n%s", expected, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestWikiTemplateHidesUnusedConfiguredClassSpellColumns(t *testing.T) {
|
func TestWikiTemplateHidesUnusedConfiguredClassSpellColumns(t *testing.T) {
|
||||||
ctx := testWikiTableContext(t, `
|
ctx := testWikiTableContext(t, `
|
||||||
tables:
|
tables:
|
||||||
|
|||||||
@@ -452,6 +452,7 @@ func (ctx *wikiContext) classProgressionRows(levels string, projections map[stri
|
|||||||
row["HasSpellProgression"] = hasSpellProgression(classRow)
|
row["HasSpellProgression"] = hasSpellProgression(classRow)
|
||||||
row["HasSpellsPerDay"] = hasPerDay
|
row["HasSpellsPerDay"] = hasPerDay
|
||||||
row["HasSpellsKnown"] = hasKnown
|
row["HasSpellsKnown"] = hasKnown
|
||||||
|
row["SpellcastingAdvancementNote"] = classSpellcastingAdvancementNote(classRow, level)
|
||||||
populateClassSpellProgressionFields(row, "SpellsPerDay", spellsPerDayByLevel[level])
|
populateClassSpellProgressionFields(row, "SpellsPerDay", spellsPerDayByLevel[level])
|
||||||
populateClassSpellProgressionFields(row, "SpellsKnown", spellsKnownByLevel[level])
|
populateClassSpellProgressionFields(row, "SpellsKnown", spellsKnownByLevel[level])
|
||||||
out = append(out, row)
|
out = append(out, row)
|
||||||
@@ -459,6 +460,35 @@ func (ctx *wikiContext) classProgressionRows(levels string, projections map[stri
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func classSpellcastingAdvancementNote(classRow map[string]any, level int) string {
|
||||||
|
if level < 1 || isClassSpellcaster(classRow) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
notes := []string{}
|
||||||
|
if advancesSpellcastingAtLevel(classRow, "ArcSpellLvlMod", level) {
|
||||||
|
notes = append(notes, "+1 level of existing arcane spellcasting class")
|
||||||
|
}
|
||||||
|
if advancesSpellcastingAtLevel(classRow, "DivSpellLvlMod", level) {
|
||||||
|
notes = append(notes, "+1 level of existing divine spellcasting class")
|
||||||
|
}
|
||||||
|
return strings.Join(notes, "; ")
|
||||||
|
}
|
||||||
|
|
||||||
|
func advancesSpellcastingAtLevel(classRow map[string]any, field string, level int) bool {
|
||||||
|
mod, err := asInt(fieldValue(classRow, field))
|
||||||
|
if err != nil || mod <= 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return roundedSpellcastingLevelAdvancement(level, mod) > roundedSpellcastingLevelAdvancement(level-1, mod)
|
||||||
|
}
|
||||||
|
|
||||||
|
func roundedSpellcastingLevelAdvancement(level, mod int) int {
|
||||||
|
if level <= 0 || mod <= 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return (level*2 + mod) / (mod * 2)
|
||||||
|
}
|
||||||
|
|
||||||
func (ctx *wikiContext) classProgressionNote(classRow map[string]any, level int) string {
|
func (ctx *wikiContext) classProgressionNote(classRow map[string]any, level int) string {
|
||||||
meta, err := parseExistingMetadata(classRow)
|
meta, err := parseExistingMetadata(classRow)
|
||||||
if err != nil || meta == nil {
|
if err != nil || meta == nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user