From 24521f593f27b722c6057126061ac2fc2650b916 Mon Sep 17 00:00:00 2001 From: Booga Date: Fri, 16 May 2025 06:21:19 -0500 Subject: [PATCH] updated js for v12 --- module.json | 4 +- shadowdarklings-importer.js | 81 +++++++++++++++++++++---------------- 2 files changed, 48 insertions(+), 37 deletions(-) diff --git a/module.json b/module.json index 655c280..332cf0f 100644 --- a/module.json +++ b/module.json @@ -2,12 +2,12 @@ "name": "shadowdarklings-importer", "title": "Shadowdarklings.net Importer", "description": "Import JSON characters and items from shadowdarklings.net into Foundry VTT.", - "version": "1.0.3", + "version": "1.0.4", "author": "Booga", "minimumCoreVersion": "11", "compatibleCoreVersion": "12", "esmodules": ["shadowdarklings-importer.js"], "systems": ["shadowdark"], "manifest": "https://g.kht.dev/kyle/shadowdark-importer/module.json", - "download": "https://g.kht.dev/kyle/shadowdark-importer/archive/v1.0.3.zip" + "download": "https://g.kht.dev/kyle/shadowdark-importer/archive/v1.0.4.zip" } diff --git a/shadowdarklings-importer.js b/shadowdarklings-importer.js index a57f0f4..ec51cd8 100644 --- a/shadowdarklings-importer.js +++ b/shadowdarklings-importer.js @@ -1,5 +1,5 @@ // shadowdarklings-importer.js -Hooks.on("ready", function () { +Hooks.once("ready", function () { // Add button to Actors Directory Hooks.on("renderActorDirectory", (app, html, data) => { appendImportButton(html, app, "actor"); @@ -15,16 +15,15 @@ function appendImportButton(html, app, type) { `` ); importBtn.on("click", async () => { - const dialog = new ShadowdarklingsImportDialog(type); + const dialog = new ShadowdarklingsImportDialog(type, app); dialog.render(true); }); - html.find(".directory-footer").append(importBtn); } -// A dialog window to upload JSON and start the import process +// Upload dialog class ShadowdarklingsImportDialog extends Dialog { - constructor(type) { + constructor(type, app) { super({ title: `Import Shadowdarklings ${type === "actor" ? "Character/Monster" : "Item"}`, content: ` @@ -49,6 +48,7 @@ class ShadowdarklingsImportDialog extends Dialog { default: "import" }); this.type = type; + this.app = app; } async importJSON(html) { @@ -65,27 +65,30 @@ class ShadowdarklingsImportDialog extends Dialog { return; } - // Dispatch to appropriate handler if (this.type === "actor") { - return importShadowdarklingsActor(json); + return importShadowdarklingsActor(json, this.app); } else { - return importShadowdarklingsItem(json); + return importShadowdarklingsItem(json, this.app); } } } -// Example mapping function for actor -async function importShadowdarklingsActor(data) { - // Try to discern if this is a character or monster format - if (!data.name) { - ui.notifications.error("This JSON does not look like a Shadowdark character."); - return; - } +// Main actor importer +async function importShadowdarklingsActor(data, app) { + // Use system-defined actor types: 'pc' (player), 'npc' (monsters/opponents) + // Try to discern if this is a PC or NPC/Monster. + let actorType = "npc"; + // If class or level is present, it's likely a PC + if (data.class || data.level || data.background || data.player) actorType = "pc"; - // Very basic mapping, adjust as needed + // Allowed actor types + const allowedTypes = game.system.model.Actor ? Object.keys(game.system.model.Actor) : ["pc","npc"]; + if (!allowedTypes.includes(actorType)) actorType = allowedTypes[0]; // Fallback + + // Setup the document data const actorData = { name: data.name || "Imported Character", - type: data.class ? "character" : "npc", // Guess by "class" being present + type: actorType, system: { abilities: { str: { value: data.str }, @@ -96,60 +99,68 @@ async function importShadowdarklingsActor(data) { cha: { value: data.cha } }, ac: { value: data.ac }, - hp: { value: data.hp, max: data.hp }, + hp: { value: data.hp, max: data.hp || data.maxHp, min: 0 }, level: { value: data.level }, class: { value: data.class }, - race: { value: data.race }, - alignment: { value: data.alignment }, - // Add more mappings as fits your needs and data + ancestry: { value: data.race }, + alignment: { value: data.alignment } + // Extend as needed for your Shadowdark system version }, - // Optionally add avatar/portrait: img: data.img - // Optionally import inventory as embedded items, etc. + // Optionally add image + // img: data.img || "icons/svg/mystery-man.svg" }; - // Try to import inventory if present + // Try inventory import (if system supports embedded items in actors) if (Array.isArray(data.inventory)) { - actorData.items = data.inventory.map(itm => ({ + actorData.items = data.inventory.filter(i=>i.name).map(itm => ({ name: itm.name, - type: "equipment", // Guess, or use your actual item types + type: "equipment", // Or "gear" or your actual item type in Shadowdark system: { description: { value: itm.description || "" }, quantity: itm.quantity || 1, value: itm.value || "", - weight: itm.weight || "", + weight: itm.weight || "" } })); } - // Create the actor in the current folder + // Create the actor using v12 Documents API try { - await Actor.create(actorData); + const created = await Actor.createDocuments([actorData], {parent: game.actors}); ui.notifications.info(`${actorData.name} imported successfully!`); + // Optionally, highlight/select the imported actor + if (created.length && app) { + app._lastSelected = [created[0].id]; + app.render(); + } } catch (e) { console.error(e); ui.notifications.error("Actor import failed."); } } -async function importShadowdarklingsItem(data) { +// Items (single or list) +async function importShadowdarklingsItem(data, app) { // Accept single or array of items const items = Array.isArray(data) ? data : [data]; + let created = []; for (let itm of items) { if (!itm.name) continue; const itemData = { name: itm.name, - type: itm.type || "equipment", + type: itm.type || "equipment", // Check your Shadowdark item types! system: { description: { value: itm.description || "" }, - // Add other fields as needed - }, + quantity: itm.quantity || 1 + } }; try { - await Item.create(itemData); + const docs = await Item.createDocuments([itemData], {parent: game.items}); + created.push(...docs); } catch (e) { console.error(e); ui.notifications.warn(`Failed to import item: ${itm.name}`); } } - ui.notifications.info("Items imported."); + if (created.length > 0) ui.notifications.info("Items imported."); }