first commit
This commit is contained in:
155
shadowdarklings-importer.js
Normal file
155
shadowdarklings-importer.js
Normal file
@@ -0,0 +1,155 @@
|
||||
// shadowdarklings-importer.js
|
||||
Hooks.on("ready", function () {
|
||||
// Add button to Actors Directory
|
||||
Hooks.on("renderActorDirectory", (app, html, data) => {
|
||||
appendImportButton(html, app, "actor");
|
||||
});
|
||||
// Add button to Items Directory
|
||||
Hooks.on("renderItemDirectory", (app, html, data) => {
|
||||
appendImportButton(html, app, "item");
|
||||
});
|
||||
});
|
||||
|
||||
function appendImportButton(html, app, type) {
|
||||
const importBtn = $(
|
||||
`<button class="shadowdarklings-importer"><i class="fas fa-file-import"></i> Shadowdarklings Import</button>`
|
||||
);
|
||||
importBtn.on("click", async () => {
|
||||
const dialog = new ShadowdarklingsImportDialog(type);
|
||||
dialog.render(true);
|
||||
});
|
||||
|
||||
html.find(".directory-footer").append(importBtn);
|
||||
}
|
||||
|
||||
// A dialog window to upload JSON and start the import process
|
||||
class ShadowdarklingsImportDialog extends Dialog {
|
||||
constructor(type) {
|
||||
super({
|
||||
title: `Import Shadowdarklings ${type === "actor" ? "Character/Monster" : "Item"}`,
|
||||
content: `
|
||||
<form>
|
||||
<div class="form-group">
|
||||
<label>Upload Shadowdarklings JSON:</label>
|
||||
<input type="file" name="json" accept="application/json"/>
|
||||
</div>
|
||||
</form>
|
||||
`,
|
||||
buttons: {
|
||||
import: {
|
||||
icon: '<i class="fas fa-file-import"></i>',
|
||||
label: "Import",
|
||||
callback: (html) => this.importJSON(html)
|
||||
},
|
||||
cancel: {
|
||||
icon: '<i class="fas fa-times"></i>',
|
||||
label: "Cancel"
|
||||
}
|
||||
},
|
||||
default: "import"
|
||||
});
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
async importJSON(html) {
|
||||
const file = html.find('input[name="json"]')[0]?.files[0];
|
||||
if (!file) {
|
||||
ui.notifications.error("No file selected!");
|
||||
return;
|
||||
}
|
||||
let json;
|
||||
try {
|
||||
json = JSON.parse(await file.text());
|
||||
} catch (err) {
|
||||
ui.notifications.error("Invalid JSON file.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Dispatch to appropriate handler
|
||||
if (this.type === "actor") {
|
||||
return importShadowdarklingsActor(json);
|
||||
} else {
|
||||
return importShadowdarklingsItem(json);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Very basic mapping, adjust as needed
|
||||
const actorData = {
|
||||
name: data.name || "Imported Character",
|
||||
type: data.class ? "character" : "npc", // Guess by "class" being present
|
||||
system: {
|
||||
abilities: {
|
||||
str: { value: data.str },
|
||||
dex: { value: data.dex },
|
||||
int: { value: data.int },
|
||||
wis: { value: data.wis },
|
||||
con: { value: data.con },
|
||||
cha: { value: data.cha }
|
||||
},
|
||||
ac: { value: data.ac },
|
||||
hp: { value: data.hp, max: data.hp },
|
||||
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
|
||||
},
|
||||
// Optionally add avatar/portrait: img: data.img
|
||||
// Optionally import inventory as embedded items, etc.
|
||||
};
|
||||
|
||||
// Try to import inventory if present
|
||||
if (Array.isArray(data.inventory)) {
|
||||
actorData.items = data.inventory.map(itm => ({
|
||||
name: itm.name,
|
||||
type: "equipment", // Guess, or use your actual item types
|
||||
system: {
|
||||
description: { value: itm.description || "" },
|
||||
quantity: itm.quantity || 1,
|
||||
value: itm.value || "",
|
||||
weight: itm.weight || "",
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
// Create the actor in the current folder
|
||||
try {
|
||||
await Actor.create(actorData);
|
||||
ui.notifications.info(`${actorData.name} imported successfully!`);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
ui.notifications.error("Actor import failed.");
|
||||
}
|
||||
}
|
||||
|
||||
async function importShadowdarklingsItem(data) {
|
||||
// Accept single or array of items
|
||||
const items = Array.isArray(data) ? data : [data];
|
||||
for (let itm of items) {
|
||||
if (!itm.name) continue;
|
||||
const itemData = {
|
||||
name: itm.name,
|
||||
type: itm.type || "equipment",
|
||||
system: {
|
||||
description: { value: itm.description || "" },
|
||||
// Add other fields as needed
|
||||
},
|
||||
};
|
||||
try {
|
||||
await Item.create(itemData);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
ui.notifications.warn(`Failed to import item: ${itm.name}`);
|
||||
}
|
||||
}
|
||||
ui.notifications.info("Items imported.");
|
||||
}
|
||||
Reference in New Issue
Block a user