From 094326eb5b584e6ccebf356c1639d62ac172c5ef Mon Sep 17 00:00:00 2001 From: Paul Maskelyne Date: Wed, 4 Dec 2024 14:47:33 +0000 Subject: [PATCH] closes #968 --- RELEASE_NOTES.md | 7 ++ system/src/apps/ShadowdarklingImporterSD.mjs | 87 ++++++++++++++++---- system/src/sheets/PlayerSheetSD.mjs | 23 +----- system/src/utils/UtilitySD.mjs | 27 ++++++ 4 files changed, 106 insertions(+), 38 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 7e00f640..8874a003 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +1,10 @@ +# v3.2.2 + +## Chores +* [#968] Update Shadowdarklings import process to support Wands and Scrolls + +--- + # v3.2.1 ## Bugs diff --git a/system/src/apps/ShadowdarklingImporterSD.mjs b/system/src/apps/ShadowdarklingImporterSD.mjs index 67b19032..608cee43 100644 --- a/system/src/apps/ShadowdarklingImporterSD.mjs +++ b/system/src/apps/ShadowdarklingImporterSD.mjs @@ -44,6 +44,17 @@ export default class ShadowdarklingImporterSD extends FormApplication { html.on("paste", ".SDImporterJson", this._onPaste.bind(this)); } + /** @override */ + async getData(options) { + const data = { + actor: this.importedActor, + errors: this.errors, + gear: this.gear, + }; + + return data; + } + /** @inheritdoc */ _onSubmit(event) { event.preventDefault(); @@ -56,17 +67,6 @@ export default class ShadowdarklingImporterSD extends FormApplication { // required method } - /** @override */ - async getData(options) { - const data = { - actor: this.importedActor, - errors: this.errors, - gear: this.gear, - }; - - return data; - } - /** * Handles pasting of json data */ @@ -88,6 +88,22 @@ export default class ShadowdarklingImporterSD extends FormApplication { } } + async _createSpellScroll(item) { + const spell = await this._getSpellFromItem(item); + + if (spell) { + return await shadowdark.utils.createItemFromSpell("Scroll", spell); + } + } + + async _createSpellWand(item) { + const spell = await this._getSpellFromItem(item); + + if (spell) { + return await shadowdark.utils.createItemFromSpell("Wand", spell); + } + } + /** * finds matching items by category */ @@ -132,7 +148,7 @@ export default class ShadowdarklingImporterSD extends FormApplication { c.name.toLowerCase() === spell.sourceName.toLowerCase() ); - const itemIndex = pack.index.find( s => ( + const itemIndex = pack.index.find(s => ( (s.name.toLowerCase() === spell.bonusName.toLowerCase()) && (s.type === "Spell") && (s.system.class.includes(classObj?.uuid)) @@ -224,6 +240,32 @@ export default class ShadowdarklingImporterSD extends FormApplication { } } + async _getSpellFromItem(item) { + const [spellName, spellClass] = this._getSpellNameAndClassFromItem(item); + + if (!spellName || !spellClass) return; + + const classUuid = (await shadowdark.compendiums.classes()).find( + i => i.name === spellClass + ).uuid; + + const spell = (await shadowdark.compendiums.spells()).find(spell => { + return spellName.slugify() === spell.name.slugify() + && spell.system.class.includes(classUuid); + }); + + return spell; + } + + _getSpellNameAndClassFromItem(item) { + const {spellName, spellClass} = + /^(?[\w\s]+)\s+\(Tier\s+\d+,\s+(?\w+)\)/ + .exec(item.spellDesc ?? "") + ?.groups ?? [undefined, undefined]; + + return [spellName, spellClass]; + } + /** * Parses JSON data from shadowdarklings and tries to create an Player actor from it. * @param {JSON} json - JSON Data from the Shadowdarklings.net site @@ -400,10 +442,23 @@ export default class ShadowdarklingImporterSD extends FormApplication { // magic items (not implemented) for (const item of json.magicItems) { - this.errors.push({ - type: "Magic Item", - name: item.name, - }); + let newItem = undefined; + if (item.magicItemType === "magicSpellScroll") { + newItem = await this._createSpellScroll(item); + } + else if (item.magicItemType === "magicSpellWand") { + newItem = await this._createSpellWand(item); + } + + if (newItem) { + this.gear.push(newItem); + } + else { + this.errors.push({ + type: "Magic Item", + name: item.name, + }); + } } // Load Bonuses / talents & Spells diff --git a/system/src/sheets/PlayerSheetSD.mjs b/system/src/sheets/PlayerSheetSD.mjs index a53a164f..7dca5330 100644 --- a/system/src/sheets/PlayerSheetSD.mjs +++ b/system/src/sheets/PlayerSheetSD.mjs @@ -388,28 +388,7 @@ export default class PlayerSheetSD extends ActorSheetSD { } async _createItemFromSpell(spell, type) { - const name = (type !== "Spell") - ? game.i18n.format( - `SHADOWDARK.item.name_from_spell.${type}`, - {spellName: spell.name} - ) - : spell.name; - - const itemData = { - type, - name, - system: spell.system, - }; - - if (type === "Spell") { - itemData.img = spell.img; - } - else { - delete itemData.system.lost; - itemData.system.magicItem = true; - itemData.system.spellImg = spell.img; - itemData.system.spellName = spell.name; - } + const itemData = await shadowdark.utils.createItemFromSpell(type, spell); super._onDropItemCreate(itemData); } diff --git a/system/src/utils/UtilitySD.mjs b/system/src/utils/UtilitySD.mjs index 93792bd9..6348fcdf 100644 --- a/system/src/utils/UtilitySD.mjs +++ b/system/src/utils/UtilitySD.mjs @@ -70,6 +70,33 @@ export default class UtilitySD { } + static async createItemFromSpell(type, spell) { + const name = (type !== "Spell") + ? game.i18n.format( + `SHADOWDARK.item.name_from_spell.${type}`, + { spellName: spell.name } + ) + : spell.name; + + const itemData = { + type, + name, + system: spell.system, + }; + + if (type === "Spell") { + itemData.img = spell.img; + } + else { + delete itemData.system.lost; + itemData.system.magicItem = true; + itemData.system.spellImg = spell.img; + itemData.system.spellName = spell.name; + } + return itemData; + } + + static diceSound() { const sounds = [CONFIG.sounds.dice]; const src = sounds[0];