diff --git a/manifest.json b/manifest.json index db4330d6..26e2992a 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "obsidian-5e-statblocks", "name": "5e Statblocks", - "version": "1.5.1", + "version": "1.5.2", "description": "Create 5e styled statblocks in Obsidian.md", "minAppVersion": "0.12.0", "author": "Jeremy Valentine", diff --git a/package.json b/package.json index da8d6737..d06c7589 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "obsidian-5e-statblocks", - "version": "1.5.1", + "version": "1.5.2", "description": "Create 5e styled statblocks in Obsidian.md", "main": "main.js", "scripts": { diff --git a/src/importers/5eToolsImport.ts b/src/importers/5eToolsImport.ts index 629076a4..7f3cafed 100644 --- a/src/importers/5eToolsImport.ts +++ b/src/importers/5eToolsImport.ts @@ -1,4 +1,5 @@ import type { Monster } from "@types"; +import { Notice } from "obsidian"; export const ImportFrom5eTools = async ( ...files: File[] @@ -8,7 +9,10 @@ export const ImportFrom5eTools = async ( try { const monster = await buildMonsterFromFile(file); importedMonsters.set(monster.name, monster); - } catch (e) {} + } catch (e) { + new Notice("There was an issue importing the monster."); + console.error(e); + } } return importedMonsters; }; diff --git a/src/importers/CritterDBImport.ts b/src/importers/CritterDBImport.ts index 6cefc126..b505d1e9 100644 --- a/src/importers/CritterDBImport.ts +++ b/src/importers/CritterDBImport.ts @@ -28,142 +28,154 @@ async function buildMonsterFromFile(file: File): Promise> { monsters = [parsed]; } for (let monster of monsters) { - const importedMonster: Monster = { - name: monster.name, - source: "CritterDB", - type: monster.stats.race, - subtype: "", - size: monster.stats.size, - alignment: monster.stats.alignment, - hp: monster.stats.hitPoints, - hit_dice: `${Math.floor( - monster.stats.extraHealthFromConstitution / - monster.stats.abilityScoreModifiers.constitution - )}d${monster.stats.hitDieSize} + ${ - monster.stats.extraHealthFromConstitution - }`, - ac: monster.stats.armorClass, - speed: monster.stats.speed, - stats: [ - monster.stats.abilityScores.strength, - monster.stats.abilityScores.dexterity, - monster.stats.abilityScores.constitution, - monster.stats.abilityScores.intelligence, - monster.stats.abilityScores.wisdom, - monster.stats.abilityScores.charisma - ], - damage_immunities: - monster.stats.damageImmunities - ?.join("; ") - .toLowerCase() - .trim() ?? "", - damage_resistances: - monster.stats.damageResistances - ?.join(", ") - .toLowerCase() - .trim() ?? "", - damage_vulnerabilities: - monster.stats.damageVulnerabilities - ?.join(", ") - .toLowerCase() - .trim() ?? "", - condition_immunities: - monster.stats.conditionImmunities - ?.join(", ") - .toLowerCase() - .trim() ?? "", - saves: - monster.stats.savingThrows - ?.map((thr: any) => { - if ( - !("value" in thr) && - !("modifier" in thr) - ) - return; - return { - [thr.ability]: thr.value ?? thr.modifier - }; - }) - .filter((x: any) => x) ?? [], - skillsaves: - monster.stats.skills - ?.map((thr: any) => { - if ( - !("value" in thr) && - !("modifier" in thr) - ) - return; - return { - [thr.name]: thr.value ?? thr.modifier - }; - }) - .filter((x: any) => x) ?? [], - senses: monster.stats.senses?.join(", ").trim() ?? "", - languages: - monster.stats.languages?.join(", ").trim() ?? "", - cr: monster.stats.challengeRating ?? "", - traits: - monster.stats.additionalAbilities?.map( - (trait: { - name: string; - description: string; - }) => { - return { - name: trait.name, - desc: trait.description.replace( - /<[^>]*>/g, - "" + try { + const importedMonster: Monster = { + name: monster.name, + source: "CritterDB", + type: monster.stats.race, + subtype: "", + size: monster.stats.size, + alignment: monster.stats.alignment, + hp: monster.stats.hitPoints, + hit_dice: `${Math.floor( + monster.stats.extraHealthFromConstitution / + monster.stats.abilityScoreModifiers + .constitution + )}d${monster.stats.hitDieSize} + ${ + monster.stats.extraHealthFromConstitution + }`, + ac: monster.stats.armorClass, + speed: monster.stats.speed, + stats: [ + monster.stats.abilityScores.strength, + monster.stats.abilityScores.dexterity, + monster.stats.abilityScores.constitution, + monster.stats.abilityScores.intelligence, + monster.stats.abilityScores.wisdom, + monster.stats.abilityScores.charisma + ], + damage_immunities: + monster.stats.damageImmunities + ?.join("; ") + .toLowerCase() + .trim() ?? "", + damage_resistances: + monster.stats.damageResistances + ?.join(", ") + .toLowerCase() + .trim() ?? "", + damage_vulnerabilities: + monster.stats.damageVulnerabilities + ?.join(", ") + .toLowerCase() + .trim() ?? "", + condition_immunities: + monster.stats.conditionImmunities + ?.join(", ") + .toLowerCase() + .trim() ?? "", + saves: + monster.stats.savingThrows + ?.map((thr: any) => { + if ( + !("value" in thr) && + !("modifier" in thr) ) - }; - } - ) ?? [], - actions: - monster.stats.actions?.map( - (trait: { - name: string; - description: string; - }) => { - return { - name: trait.name, - desc: trait.description.replace( - /<[^>]*>/g, - "" + return; + return { + [thr.ability]: + thr.value ?? thr.modifier + }; + }) + .filter((x: any) => x) ?? [], + skillsaves: + monster.stats.skills + ?.map((thr: any) => { + if ( + !("value" in thr) && + !("modifier" in thr) ) - }; - } - ) ?? [], - reactions: - monster.stats.reactions?.map( - (trait: { - name: string; - description: string; - }) => { - return { - name: trait.name, - desc: trait.description.replace( - /<[^>]*>/g, - "" - ) - }; - } - ) ?? [], - legendary_actions: - monster.stats.legendaryActions?.map( - (trait: { - name: string; - description: string; - }) => { - return { - name: trait.name, - desc: trait.description.replace( - /<[^>]*>/g, - "" - ) - }; - } - ) ?? [] - }; - importedMonsters.set(importedMonster.name, importedMonster); + return; + return { + [thr.name]: + thr.value ?? thr.modifier + }; + }) + .filter((x: any) => x) ?? [], + senses: + monster.stats.senses?.join(", ").trim() ?? "", + languages: + monster.stats.languages?.join(", ").trim() ?? + "", + cr: monster.stats.challengeRating ?? "", + traits: + monster.stats.additionalAbilities?.map( + (trait: { + name: string; + description: string; + }) => { + return { + name: trait.name, + desc: trait.description.replace( + /<[^>]*>/g, + "" + ) + }; + } + ) ?? [], + actions: + monster.stats.actions?.map( + (trait: { + name: string; + description: string; + }) => { + return { + name: trait.name, + desc: trait.description.replace( + /<[^>]*>/g, + "" + ) + }; + } + ) ?? [], + reactions: + monster.stats.reactions?.map( + (trait: { + name: string; + description: string; + }) => { + return { + name: trait.name, + desc: trait.description.replace( + /<[^>]*>/g, + "" + ) + }; + } + ) ?? [], + legendary_actions: + monster.stats.legendaryActions?.map( + (trait: { + name: string; + description: string; + }) => { + return { + name: trait.name, + desc: trait.description.replace( + /<[^>]*>/g, + "" + ) + }; + } + ) ?? [] + }; + importedMonsters.set( + importedMonster.name, + importedMonster + ); + } catch (e) { + continue; + } } resolve(importedMonsters); diff --git a/src/importers/DnDAppFilesImport.ts b/src/importers/DnDAppFilesImport.ts index d7bdfe5e..399b0635 100644 --- a/src/importers/DnDAppFilesImport.ts +++ b/src/importers/DnDAppFilesImport.ts @@ -32,44 +32,51 @@ async function buildMonsterFromFile(file: File): Promise> { const importedMonsters: Map = new Map(); if (!monsters.length) return; for (let monster of Array.from(monsters)) { - const importedMonster: Monster = { - name: getParameter(monster, "name"), - size: getSize(monster), - type: getParameter(monster, "type"), - subtype: getParameter(monster, "subtype"), - alignment: getParameter(monster, "alignment"), - ac: getAC(monster), - hp: Number(getHP(monster, "hp")), - hit_dice: getHP(monster, "hit_dice"), - speed: getParameter(monster, "speed"), - stats: [ - Number(getParameter(monster, "str")), - Number(getParameter(monster, "dex")), - Number(getParameter(monster, "con")), - Number(getParameter(monster, "int")), - Number(getParameter(monster, "wis")), - Number(getParameter(monster, "cha")) - ], - saves: getSaves(monster), - skillsaves: getSkillSaves(monster), - damage_vulnerabilities: getParameter(monster, "vulnerable"), - damage_resistances: getParameter(monster, "resist"), - damage_immunities: getParameter(monster, "immune"), - condition_immunities: getParameter( - monster, - "conditionImmune" - ), - senses: getParameter(monster, "senses"), - languages: getParameter(monster, "languages"), - cr: getParameter(monster, "cr"), - traits: getTraits(monster, "trait"), - spells: getSpells(monster), - actions: getTraits(monster, "action"), - legendary_actions: getTraits(monster, "legendary"), - reactions: getTraits(monster, "reaction"), - source: getSource(monster) - }; - importedMonsters.set(importedMonster.name, importedMonster); + try { + const importedMonster: Monster = { + name: getParameter(monster, "name"), + size: getSize(monster), + type: getParameter(monster, "type"), + subtype: getParameter(monster, "subtype"), + alignment: getParameter(monster, "alignment"), + ac: getAC(monster), + hp: Number(getHP(monster, "hp")), + hit_dice: getHP(monster, "hit_dice"), + speed: getParameter(monster, "speed"), + stats: [ + Number(getParameter(monster, "str")), + Number(getParameter(monster, "dex")), + Number(getParameter(monster, "con")), + Number(getParameter(monster, "int")), + Number(getParameter(monster, "wis")), + Number(getParameter(monster, "cha")) + ], + saves: getSaves(monster), + skillsaves: getSkillSaves(monster), + damage_vulnerabilities: getParameter( + monster, + "vulnerable" + ), + damage_resistances: getParameter(monster, "resist"), + damage_immunities: getParameter(monster, "immune"), + condition_immunities: getParameter( + monster, + "conditionImmune" + ), + senses: getParameter(monster, "senses"), + languages: getParameter(monster, "languages"), + cr: getParameter(monster, "cr"), + traits: getTraits(monster, "trait"), + spells: getSpells(monster), + actions: getTraits(monster, "action"), + legendary_actions: getTraits(monster, "legendary"), + reactions: getTraits(monster, "reaction"), + source: getSource(monster) + }; + importedMonsters.set(importedMonster.name, importedMonster); + } catch (e) { + continue; + } } resolve(importedMonsters); }; @@ -92,10 +99,13 @@ function getTraits( for (let trait of Array.from(traits)) { const name = trait.getElementsByTagName("name"); if (!name) continue; + if (!name.length) continue; + if (!name[0].textContent) continue; if (name[0].textContent.includes("Spellcasting")) continue; const text = []; const traitTexts = trait.getElementsByTagName("text"); for (let index in traitTexts) { + if (!traitTexts[index]) text.push(traitTexts[index].textContent); } traitList.push({ diff --git a/versions.json b/versions.json index b6f5f69f..8ebd950f 100644 --- a/versions.json +++ b/versions.json @@ -4,5 +4,5 @@ "1.1.0": "0.12.0", "1.2.0": "0.12.0", "1.3.1": "0.12.0", - "1.5.1": "0.12.0" + "1.5.2": "0.12.0" } \ No newline at end of file