diff --git a/src/main/java/dev/ebullient/convert/tools/dnd5e/Json2QuteSpellIndex.java b/src/main/java/dev/ebullient/convert/tools/dnd5e/Json2QuteSpellIndex.java index ecfc6c74..1b14433b 100644 --- a/src/main/java/dev/ebullient/convert/tools/dnd5e/Json2QuteSpellIndex.java +++ b/src/main/java/dev/ebullient/convert/tools/dnd5e/Json2QuteSpellIndex.java @@ -1,5 +1,6 @@ package dev.ebullient.convert.tools.dnd5e; +import static dev.ebullient.convert.StringUtil.isPresent; import static dev.ebullient.convert.StringUtil.toTitleCase; import java.util.ArrayList; @@ -170,7 +171,9 @@ private QuteNote createOtherList(String key, SpellRefByLevel spellsByOther) { text.add("## " + levelHeading); text.add(""); for (var entry : levelSpells) { - text.add("- " + entry.linkify() + " " + spellsByOther.reference.describe()); + SpellEntry.SpellReference spellRef = entry.getMostSpecificReference(key); + String desc = spellRef != null ? spellRef.describe() : ""; + text.add("- " + entry.linkify() + (isPresent(desc) ? " " + desc : "")); } } maybeAddBlankLine(text); diff --git a/src/main/java/dev/ebullient/convert/tools/dnd5e/SpellEntry.java b/src/main/java/dev/ebullient/convert/tools/dnd5e/SpellEntry.java index d6fcd347..7db51dc5 100644 --- a/src/main/java/dev/ebullient/convert/tools/dnd5e/SpellEntry.java +++ b/src/main/java/dev/ebullient/convert/tools/dnd5e/SpellEntry.java @@ -172,6 +172,23 @@ public SpellReference getReference(String key) { return ref; } + /** + * Returns the most specific reference for the given key, preferring specific + * (constraint-bearing) references over non-specific ones. Checks expandedList + * first, then references, returning whichever has a constraint (classLevel/spellLevel/asLevel). + */ + public SpellReference getMostSpecificReference(String key) { + SpellReference expandedRef = expandedList.get(key); + if (expandedRef != null && expandedRef.isSpecific()) { + return expandedRef; + } + SpellReference ref = references.get(key); + if (ref != null && ref.isSpecific()) { + return ref; + } + return ref != null ? ref : expandedRef; + } + public boolean inClassList(String x) { return classes.contains(x.toLowerCase()); } diff --git a/src/main/java/dev/ebullient/convert/tools/dnd5e/SpellIndex.java b/src/main/java/dev/ebullient/convert/tools/dnd5e/SpellIndex.java index 85e9b4ab..86065c2c 100644 --- a/src/main/java/dev/ebullient/convert/tools/dnd5e/SpellIndex.java +++ b/src/main/java/dev/ebullient/convert/tools/dnd5e/SpellIndex.java @@ -149,9 +149,12 @@ private void processClassRefs(SpellEntry spellEntry, JsonNode data, boolean expa String refKey = Tools5eIndexType.classtype.createKey(className, classSource); // Resolve reprints so we reference the newest version - refKey = index().getAliasOrDefault(refKey); - if (!index().isExcluded(refKey) && index().getOriginNoFallback(refKey) != null) { - spellEntry.addSpellReference(refKey, expanded); + String resolvedKey = index().getAliasOrDefault(refKey); + if (!refKey.equals(resolvedKey)) { + continue; // Skip old reprinted version; the canonical version is handled separately + } + if (!index().isExcluded(resolvedKey) && index().getOriginNoFallback(resolvedKey) != null) { + spellEntry.addSpellReference(resolvedKey, expanded); } } } @@ -178,9 +181,12 @@ private void processSubclassRefs(SpellEntry spellEntry, JsonNode data) { String refKey = "subclass|%s|%s|%s|%s".formatted( scName, className, classSource, scSource).toLowerCase(); // Resolve reprints so we reference the newest version - refKey = index().getAliasOrDefault(refKey); - if (!index().isExcluded(refKey) && index().getOriginNoFallback(refKey) != null) { - spellEntry.addSpellReference(refKey, false); + String resolvedKey = index().getAliasOrDefault(refKey); + if (!refKey.equals(resolvedKey)) { + continue; // Skip old reprinted version; the canonical version is handled separately + } + if (!index().isExcluded(resolvedKey) && index().getOriginNoFallback(resolvedKey) != null) { + spellEntry.addSpellReference(resolvedKey, false); } } }