diff --git a/system/lang/en-en.json b/system/lang/en-en.json index 317811c..af82c5a 100644 --- a/system/lang/en-en.json +++ b/system/lang/en-en.json @@ -19,6 +19,12 @@ "def.chat.pref": "Default Chat Prefix", "spe.chat.pref": "If specified, this string will be prefixed to all chat messages that are not already commands (such as /emote.)", "l5r5e": { + "global": { + "add": "Add", + "edit": "Edit", + "delete": "Delete", + "drop_here": "Drop here" + }, "logo": { "title": "Need help?", "content": "Follow the guide :", @@ -101,7 +107,6 @@ "supernatural": "supernatural", "equipped": "Equipped" }, - "add": "Add", "items": "Items", "feats": "Feats", "techniques": { diff --git a/system/lang/es-es.json b/system/lang/es-es.json index 06597c0..c4fdd88 100644 --- a/system/lang/es-es.json +++ b/system/lang/es-es.json @@ -19,12 +19,18 @@ "def.chat.pref": "Prefijo del chat por defecto", "spe.chat.pref": "Si está configurado, la cadena será prefijada para todos los mensajes de chat que no sean ya comandos (como /emote.)", "l5r5e": { + "global": { + "add": "Add", + "edit": "Edit", + "delete": "Delete", + "drop_here": "Drop here" + }, "logo": { - "título": "¿Necesitas ayuda?", - "contenido": "Sigue la guía :", - "Edge": "Ir a la página web de Edge-Studio", - "conducir": "¿Comprar un PDF del juego?", - "Discordia": "Discordia oficial de FoundryVTT", + "títle": "¿Necesitas ayuda?", + "content": "Sigue la guía :", + "edge": "Ir a la página web de Edge-Studio", + "drive": "¿Comprar un PDF del juego?", + "discord": "Discordia oficial de FoundryVTT", "src": "systems/l5r5e/assets/l5r-logo.webp", "alt": "Ayuda en línea", "edge-info": "tu navegador abrirá la página web de EDGE STUDIO", @@ -38,7 +44,7 @@ "title": "Anillos", "earth": "Tierra", "air": "Aire", - "WATER": "Agua", + "water": "Agua", "fire": "Fuego", "void": "Vacío" }, @@ -92,7 +98,6 @@ "sheathed": "Equipped / Sheathed", "readied": "Readied", "category": "Category", - "power": "Power", "deadliness": "Deadliness", "grips": "Grips" }, @@ -102,7 +107,6 @@ "supernatural": "supernatural", "equipped": "Equipped" }, - "add": "Add", "items": "Equipo", "feats": "Feats", "techniques": { @@ -203,7 +207,8 @@ "void": "Subsistir" } }, - "conflict": { + "attributes": { + "title": "Attributes", "endurance": "Aguante", "endurancetip": "(Tierra + Fuego) x2", "composure": "Compostura", @@ -216,7 +221,7 @@ "fatigue": "Fatiga", "strife": "Conflicto" }, - "attributes": { + "conflict": { "title": "Enfrentamiento", "stance": "Actitud", "stances": { diff --git a/system/lang/fr-fr.json b/system/lang/fr-fr.json index d5146f0..7df126e 100644 --- a/system/lang/fr-fr.json +++ b/system/lang/fr-fr.json @@ -22,7 +22,8 @@ "global": { "add": "Ajouter", "edit": "Modifier", - "delete": "Supprimer" + "delete": "Supprimer", + "drop_here": "Déposez ici" }, "logo": { "title": "Besoin d'aide ?", diff --git a/system/scripts/actors/twenty-questions-dialog.js b/system/scripts/actors/twenty-questions-dialog.js index d96e74b..ec0a843 100644 --- a/system/scripts/actors/twenty-questions-dialog.js +++ b/system/scripts/actors/twenty-questions-dialog.js @@ -94,30 +94,14 @@ export class TwentyQuestionsDialog extends FormApplication { noHonorSkillsList: ["commerce", "skulduggery", "medicine", "seafaring", "survival", "labor"], techniquesList: CONFIG.l5r5e.techniques, data: this.object.data, - errors: this.errors, - hasErrors: Object.keys(this.errors).length > 0, cache: this.cache, + errors: Object.keys(this.errors) + .map((key) => `${game.i18n.localize("l5r5e.rings." + key)} (${this.errors[key]})`) + .join(", "), // TODO better msg :D + hasErrors: Object.keys(this.errors).length > 0, }; } - /** - * Render the dialog - * @param force - * @param options - * @returns {Application} - */ - render(force, options) { - options = { - ...options, - }; - - if (force === undefined) { - force = true; - } - - return super.render(force, options); - } - /** * Listen to html elements * @override @@ -132,15 +116,15 @@ export class TwentyQuestionsDialog extends FormApplication { // Delete a dnd element html.find(`.property-delete`).on("click", (event) => { - const stepName = $(event.currentTarget).parents(".tq-drag-n-drop")[0].name; + const stepKey = $(event.currentTarget).parents(".tq-drag-n-drop").data("step"); const itemId = $(event.currentTarget).parents(".property").data("propertyId"); - this._deleteOwnedItem(stepName, itemId); + this._deleteOwnedItem(stepKey, itemId); this.render(false); }); // Submit button html.find("#generate").on("click", async (event) => { - this.object.toActor(this.actor); + await this.object.toActor(this.actor, flattenObject(this.cache)); await this.close({ submit: true, force: true }); }); } @@ -152,8 +136,9 @@ export class TwentyQuestionsDialog extends FormApplication { if (!["item", "technique", "peculiarity"].includes(type)) { return; } - if (event.target.name === "undefined") { - console.log("event.target.name is undefined"); + const stepKey = $(event.target).data("step"); + if (!stepKey) { + console.log("event stepKey is undefined"); return; } @@ -167,14 +152,19 @@ export class TwentyQuestionsDialog extends FormApplication { } // Get item const item = game.items.get(data.id); - if (!item || item.data.type !== type) { + if ( + !item || + (type !== "item" && item.data.type !== type) || + (type === "item" && !["item", "weapon", "armor"].includes(item.data.type)) + ) { + console.log("forbidden item for this drop zone", type, item.data.type); return; } // Add the item (step and cache) - this._addOwnedItem(item, event.target.name); + this._addOwnedItem(item, stepKey); // TODO specific event (no added honor if tech selected etc) - console.log(this.object.data.step3.techniques, this.cache); + console.log(this.object.data, this.cache); this.render(false); } catch (err) { @@ -217,9 +207,9 @@ export class TwentyQuestionsDialog extends FormApplication { this.cache = {}; TwentyQuestions.itemsList.forEach((stepName) => { // Check if current step value is a array - const store = getProperty(this.object.data, stepName); - if (!store || !Array.isArray(store)) { - setProperty(this.object.data, stepName, []); + let step = getProperty(this.object.data, stepName); + if (!step || !Array.isArray(step)) { + step = []; } // Init cache if not exist @@ -227,16 +217,17 @@ export class TwentyQuestionsDialog extends FormApplication { setProperty(this.cache, stepName, []); } - // Get linked Item, and store it in cache - const step = getProperty(this.object.data, stepName); - step.forEach((id, idx) => { + // Get linked Item, and store it in cache (delete null value and old items) + const newStep = []; + step.forEach((id) => { const item = game.items.get(id); - if (!item) { - step.splice(idx, 1); + if (!id || !item) { return; } + newStep.push(id); getProperty(this.cache, stepName).push(item); }); + setProperty(this.object.data, stepName, newStep); }); } @@ -263,12 +254,12 @@ export class TwentyQuestionsDialog extends FormApplication { _deleteOwnedItem(stepName, itemId) { // Delete from current step let step = getProperty(this.object.data, stepName); - step = step.filter((e) => e !== itemId); + step = step.filter((e) => !!e && e !== itemId); setProperty(this.object.data, stepName, step); // Delete from cache let cache = getProperty(this.cache, stepName); - cache = cache.filter((e) => e.id !== itemId); + cache = cache.filter((e) => !!e && e.id !== itemId); setProperty(this.cache, stepName, cache); } } diff --git a/system/scripts/actors/twenty-questions.js b/system/scripts/actors/twenty-questions.js index 2d82859..acd7b8e 100644 --- a/system/scripts/actors/twenty-questions.js +++ b/system/scripts/actors/twenty-questions.js @@ -28,7 +28,18 @@ export class TwentyQuestions { /** * Shortcut for all Items to build cache */ - static itemsList = ["step3.techniques"]; + static itemsList = [ + "step3.techniques", + "step3.school_ability", + "step3.equipment", + "step9.distinction", + "step10.adversity", + "step11.passion", + "step12.anxiety", + "step13.advantage", + "step13.disadvantage", + "step16.item", + ]; /** * Steps datas @@ -94,25 +105,25 @@ export class TwentyQuestions { }, step9: { success: "", - distinction: "", + distinction: [], }, step10: { difficulty: "", - adversity: "", + adversity: [], }, step11: { calms: "", - passion: "", + passion: [], }, step12: { worries: "", - anxiety: "", + anxiety: [], }, step13: { most_learn: "", skill: "", - advantage: "", - disadvantage: "", + advantage: [], + disadvantage: [], }, step14: { first_sight: "", @@ -123,7 +134,7 @@ export class TwentyQuestions { }, step16: { relations: "", - item: "", + item: [], }, step17: { parents_pov: "", @@ -155,10 +166,7 @@ export class TwentyQuestions { * Update object with form data */ updateFromForm(formData) { - this.data = { - ...this.data, - ...expandObject(formData), - }; + this.data = mergeObject(this.data, expandObject(formData)); } /** @@ -199,7 +207,7 @@ export class TwentyQuestions { /** * Fill a actor data from this object */ - toActor(actor) { + async toActor(actor, itemsCache) { const actorDatas = actor.data.data; const formData = this.data; @@ -254,13 +262,26 @@ export class TwentyQuestions { } }); - // TODO Items references + // Clear and add items to actor + const deleteIds = actor.data.items.map((e) => e._id); + await actor.deleteEmbeddedEntity("OwnedItem", deleteIds); + + // Add items in 20Q to actor + Object.values(itemsCache).forEach((types) => { + types.forEach((item) => { + const itemData = duplicate(item.data); + if (itemData.data?.bought_at_rank) { + itemData.data.bought_at_rank = 0; + } + actor.createEmbeddedEntity("OwnedItem", duplicate(itemData)); + }); + }); // Update actor actor.update({ name: (formData.step2.family + " " + formData.step19.firstname).trim(), data: actorDatas, - }); // , { diff: true } + }); // TODO Tmp console.log(actor); diff --git a/system/scripts/preloadTemplates.js b/system/scripts/preloadTemplates.js index 8759413..d4a9deb 100644 --- a/system/scripts/preloadTemplates.js +++ b/system/scripts/preloadTemplates.js @@ -14,6 +14,7 @@ export const PreloadTemplates = async function () { "systems/l5r5e/templates/actors/character/techniques.html", "systems/l5r5e/templates/actors/character/experience.html", "systems/l5r5e/templates/actors/character/advancement.html", + "systems/l5r5e/templates/actors/character/twenty-questions-item.html", // npc "systems/l5r5e/templates/actors/npc/identity.html", "systems/l5r5e/templates/actors/npc/narrative.html", diff --git a/system/templates/actors/character/twenty-questions-item.html b/system/templates/actors/character/twenty-questions-item.html new file mode 100644 index 0000000..7fe9bae --- /dev/null +++ b/system/templates/actors/character/twenty-questions-item.html @@ -0,0 +1,11 @@ +
+ + diff --git a/system/templates/actors/twenty-questions-dialog.html b/system/templates/actors/twenty-questions-dialog.html index b308d25..d669fe8 100644 --- a/system/templates/actors/twenty-questions-dialog.html +++ b/system/templates/actors/twenty-questions-dialog.html @@ -1,5 +1,7 @@