From c6d64e09d5293d33c25746a8d4d2bbdc8143b76f Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Thu, 28 Nov 2024 00:38:34 +0100 Subject: [PATCH 1/4] Fix: saisie des bonus de cases --- changelog.md | 4 + module/actor/export-scriptarium/mapping.js | 2 +- module/item-sheet.js | 107 +++-- module/item-sort.js | 83 ++-- module/rdd-herbes.js | 8 +- module/tmr-utility.js | 448 ++++++++++----------- templates/item-sort-sheet.html | 21 +- 7 files changed, 351 insertions(+), 322 deletions(-) diff --git a/changelog.md b/changelog.md index 5995c39d..dd0886a4 100644 --- a/changelog.md +++ b/changelog.md @@ -1,4 +1,8 @@ # 12.0 +## 12.0.24 - Les ajustements d'Astrobazzarh +- corrections + - on peut maintenant saisir et supprimer les bonus de cases de manière intuitive + ## 12.0.23 - La bibliothèque d'Astrobazzarh - corrections mineures - meilleure gestion de la parade des armes naturelles diff --git a/module/actor/export-scriptarium/mapping.js b/module/actor/export-scriptarium/mapping.js index 2f94c522..e93b7b5c 100644 --- a/module/actor/export-scriptarium/mapping.js +++ b/module/actor/export-scriptarium/mapping.js @@ -269,7 +269,7 @@ export class Mapping { } static bonusCase(sort) { - const list = RdDItemSort.bonuscaseStringToList(sort.system.bonuscase).sort(Misc.descending(it => it.bonus)) + const list = RdDItemSort.stringToBonuscases(sort.system.bonuscase).sort(Misc.descending(it => it.bonus)) if (list.length > 0) { const bonus = list[0] return `+${bonus.bonus}% en ${bonus.case}` diff --git a/module/item-sheet.js b/module/item-sheet.js index dd58ab6f..e8f3af78 100644 --- a/module/item-sheet.js +++ b/module/item-sheet.js @@ -13,6 +13,7 @@ import { Misc } from "./misc.js"; import { RdDTimestamp } from "./time/rdd-timestamp.js"; import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; import { ITEM_TYPES, RdDItem } from "./item.js"; +import { FLEUVE_COORD, TMRUtility } from "./tmr-utility.js"; /** * Extend the basic ItemSheet for RdD specific items @@ -100,55 +101,59 @@ export class RdDItemSheet extends ItemSheet { descriptionmj: await TextEditor.enrichHTML(this.item.system.descriptionmj, { async: true }), isComestible: this.item.getUtilisationCuisine(), options: RdDSheetUtility.mergeDocumentRights(this.options, this.item, this.isEditable), + competences: await SystemCompendiums.getCompetences('personnage'), + categories: RdDItem.getCategories(this.item.type), } + if (this.item.type == ITEM_TYPES.competencecreature) { formData.isparade = RdDItemCompetenceCreature.isParade(this.item) formData.isdommages = RdDItemCompetenceCreature.isDommages(this.item) } - - const competences = await SystemCompendiums.getCompetences('personnage'); - formData.categories = RdDItem.getCategories(this.item.type) - if (this.item.type == 'tache' || this.item.type == 'livre' || this.item.type == 'meditation' || this.item.type == 'oeuvre') { + if (this.item.type == ITEM_TYPES.tache || + this.item.type == ITEM_TYPES.livre || + this.item.type == ITEM_TYPES.meditation || + this.item.type == ITEM_TYPES.oeuvre) { formData.caracList = foundry.utils.duplicate(game.model.Actor.personnage.carac) formData.caracList["reve-actuel"] = foundry.utils.duplicate(game.model.Actor.personnage.reve.reve) - formData.competences = competences; } - if (this.item.type == 'arme') { - formData.competences = competences.filter(it => it.isCompetenceArme()) + if (this.item.type == ITEM_TYPES.arme) { + formData.competences = formData.competences.filter(it => it.isCompetenceArme()) } - if (['sort', 'sortreserve'].includes(this.item.type)) { - formData.competences = competences.filter(it => RdDItemCompetence.isDraconic(it)); - } - if (this.item.type == 'recettecuisine') { + if (this.item.type == ITEM_TYPES.recettecuisine) { formData.ingredients = await TextEditor.enrichHTML(this.object.system.ingredients, { async: true }) } - if (this.item.type == 'extraitpoetique') { + if (this.item.type == ITEM_TYPES.extraitpoetique) { formData.extrait = await TextEditor.enrichHTML(this.object.system.extrait, { async: true }) formData.texte = await TextEditor.enrichHTML(this.object.system.texte, { async: true }) } - if (this.item.type == 'recettealchimique') { - RdDAlchimie.processManipulation(this.item, this.actor && this.actor.id); + if (this.item.type == ITEM_TYPES.recettealchimique) { + RdDAlchimie.processManipulation(this.item, this.actor?.id); formData.manipulation_update = await TextEditor.enrichHTML(this.object.system.manipulation_update, { async: true }) formData.utilisation = await TextEditor.enrichHTML(this.object.system.utilisation, { async: true }) formData.enchantement = await TextEditor.enrichHTML(this.object.system.enchantement, { async: true }) formData.sureffet = await TextEditor.enrichHTML(this.object.system.sureffet, { async: true }) } - if (this.item.type == 'gemme') { + if (this.item.type == ITEM_TYPES.gemme) { formData.gemmeTypeList = RdDGemme.getGemmeTypeOptionList(); - RdDGemme.calculDataDerivees(this.item); + RdDGemme.calculDataDerivees(this.item) } - if (this.item.type == 'potion') { - await RdDHerbes.addPotionFormData(formData); + if (this.item.type == ITEM_TYPES.potion) { + RdDHerbes.calculFormData(formData, this.item) } - if (formData.options.isOwned && this.item.type == 'herbe' && (formData.system.categorie == 'Soin' || formData.system.categorie == 'Repos')) { - formData.isIngredientPotionBase = true; + if (this.item.type == ITEM_TYPES.herbe) { + if (formData.options.isOwned && ['Soin', 'Repos'].includes(formData.system.categorie)) { + formData.isIngredientPotionBase = true; + } } - if (this.item.type == 'sortreserve') { + if (this.item.type == ITEM_TYPES.sortreserve) { const sortId = this.item.system.sortid; + formData.competences = formData.competences.filter(it => RdDItemCompetence.isDraconic(it)); formData.sort = formData.options.isOwned ? this.item.actor.items.get(sortId) : game.items.get(sortId); } - formData.bonusCaseList = RdDItemSort.getBonusCaseList(formData, true); - + if (this.item.type == ITEM_TYPES.sort) { + formData.competences = formData.competences.filter(it => RdDItemCompetence.isDraconic(it)); + formData.bonusCaseList = RdDItemSort.getBonusCaseList(this.item); + } return formData; } @@ -185,6 +190,9 @@ export class RdDItemSheet extends ItemSheet { } } }) + this.html.find('.delete-bonus-case').click((event) => { + this.supprimerBonusCase(event.currentTarget.attributes['data-deleteCoord'].value) + }) this.html.find('.date-enchantement').change((event) => { const jour = Number(this.html.find('input.date-enchantement[name="enchantement.jour"]').val()); @@ -264,23 +272,66 @@ export class RdDItemSheet extends ItemSheet { } } + async supprimerBonusCase(deleteCoord){ + if (this.item.type == ITEM_TYPES.sort) { + const oldList = RdDItemSort.getBonusCaseList(this.item) + const newList = oldList.filter(it => it.case != deleteCoord); + if (newList.length != oldList.length) { + await this.item.update({ + 'system.bonuscase': RdDItemSort.bonuscasesToString(newList) + }) + } + } + } + /* -------------------------------------------- */ /** @override */ _updateObject(event, formData) { switch (this.item.type) { case ITEM_TYPES.sort: - // Données de bonus de cases ? - formData['system.bonuscase'] = RdDItemSort.buildBonuscaseFromArrays(formData.bonusValue, formData.caseValue) + formData['system.bonuscase'] = RdDItemSort.bonuscasesToString(RdDItemSheet._listCaseTmr( + formData.caseTmrCoord, + formData.caseTmrBonus, + formData.caseTmrAdd + )) break case ITEM_TYPES.competence: - if (formData['system.niveau'] == undefined) { - formData['system.niveau'] = formData['system.base'] - } + formData['system.niveau'] = formData.system.niveau ?? formData.system.base + break } return this.item.update(formData); } + /* -------------------------------------------- */ + /** + * reconstruit les bonus de cases + * @param {*} caseTmrCoord tableau des coordonées + * @param {*} caseTmrBonus tableau des bonus + * @param {*} caseTmrAdd case à ajouter + * @returns list d'objets {coord, bonus} + */ + static _listCaseTmr(caseTmrCoord, caseTmrBonus, caseTmrAdd) { + const listCaseTmrCoord = caseTmrCoord == undefined ? [] : Array.isArray(caseTmrCoord) ? caseTmrCoord : [caseTmrCoord] + const listCaseTmrBonus = caseTmrBonus == undefined ? [] : Array.isArray(caseTmrBonus) ? caseTmrBonus : [caseTmrBonus] + if (caseTmrAdd != undefined && caseTmrAdd != '' && TMRUtility.verifyTMRCoord(caseTmrAdd) && !listCaseTmrCoord.includes(caseTmrAdd)) { + listCaseTmrCoord.push(TMRUtility.getTMR(caseTmrAdd).coord) + listCaseTmrBonus.push(1) + } + + const list = []; + const caseChecked = {}; + for (let i = 0; i < listCaseTmrBonus.length && i < listCaseTmrCoord.length; i++) { + const coord = listCaseTmrCoord[i] == FLEUVE_COORD ? FLEUVE_COORD : (listCaseTmrCoord[i]?.toUpperCase() ?? 'A1') + const bonus = listCaseTmrBonus[i] ?? 0 + if (TMRUtility.verifyTMRCoord(coord) && bonus >= 0 && !caseChecked[coord]) { + caseChecked[coord] = coord + list.push({ case: coord, bonus: bonus }) + } + } + return list + } + /* -------------------------------------------- */ async _onDragStart(event) { } diff --git a/module/item-sort.js b/module/item-sort.js index d49228e6..5519f657 100644 --- a/module/item-sort.js +++ b/module/item-sort.js @@ -2,7 +2,7 @@ import { Grammar } from "./grammar.js"; import { RdDItemCompetence } from "./item-competence.js"; import { ITEM_TYPES } from "./item.js"; import { Misc } from "./misc.js"; -import { TMRUtility } from "./tmr-utility.js"; +import { FLEUVE_COORD, TMRType, TMRUtility } from "./tmr-utility.js"; const VOIES_DRACONIC = [ { code: 'O', label: "Voie d'Oniros", short: 'Oniros', ordre: 'a' }, @@ -80,89 +80,60 @@ export class RdDItemSort extends Item { return variable; } - /* -------------------------------------------- */ - static buildBonusCaseList(bonuscase, newCase) { - const list = RdDItemSort.bonuscaseStringToList(bonuscase) - if (newCase) { - list.push({ case: "Nouvelle", bonus: 0 }) - } - return list; - } - /** * Retourne une liste de bonus/case pour un item-sheet * @param {} item */ - static getBonusCaseList(item, newCase = false) { + static getBonusCaseList(item) { // Gestion spéciale case bonus if (item.type == ITEM_TYPES.sort) { - return RdDItemSort.buildBonusCaseList(item.system.bonuscase, newCase); + return RdDItemSort.stringToBonuscases(item.system.bonuscase) } - return undefined; - } - - /* -------------------------------------------- */ - /** Met à jour les données de formulaire - * si static des bonus de cases sont présents - * */ - static buildBonuscaseFromArrays(bonuses, coords) { - if (bonuses) { - const list = []; - const caseCheck = {}; - for (let i = 0; i < bonuses.length && i < coords.length; i++) { - const coord = coords[i] == 'Fleuve' ? 'Fleuve' : (coords[i]?.toUpperCase() ?? 'A1'); - const bonus = bonuses[i] || 0; - if (TMRUtility.verifyTMRCoord(coord) && bonus > 0 && caseCheck[coord] == undefined) { - caseCheck[coord] = bonus; - list.push({ case: coord, bonus: bonus }); - } - } - return RdDItemSort._bonuscaseListToString(list); - } - return undefined; + return []; } /* -------------------------------------------- */ static incrementBonusCase(actor, sort, coord) { - if (TMRUtility.getTMR(coord).type == "fleuve") { - coord = 'Fleuve'; + if (TMRUtility.isFleuve(coord)) { + coord = FLEUVE_COORD; + } + let list = RdDItemSort.stringToBonuscases(sort.system.bonuscase); + const existing = list.find(it => it.case == coord) + const bonus = Number(existing?.bonus ?? 0) + 1 + if (existing) { + existing.bonus = bonus + } + else { + list.push({ case: coord, bonus: 1 }) } - const list = RdDItemSort.buildBonusCaseList(sort.system.bonuscase, false); - const bonus = Number(list.find(it => it.case == coord)?.bonus ?? 0); - const modified = { case: coord, bonus: bonus + 1 }; - const bonuscase = RdDItemSort._bonuscaseListToString( - list.filter(it => it.case != coord).concat(modified) - ); - - // Sauvegarde/update - actor.updateEmbeddedDocuments('Item', [{ _id: sort._id, 'system.bonuscase': bonuscase }]); + actor.updateEmbeddedDocuments('Item', [{ _id: sort._id, 'system.bonuscase': RdDItemSort.bonuscasesToString(list) }]); } /* -------------------------------------------- */ static getCaseBonus(sort, coord) { - const isFleuve = TMRUtility.getTMR(coord).type == "fleuve"; - - let bc = RdDItemSort.buildBonusCaseList(sort.system.bonuscase, false) - .filter(it => it.case == coord || (isFleuve && it.case == 'Fleuve')) - .find(it => true) + const search = TMRUtility.isFleuve(coord) + ? it => it.case == 'Fleuve' + : it => it.case == coord; + const bc = RdDItemSort.stringToBonuscases(sort.system.bonuscase) + .find(search) return Number(bc?.bonus ?? 0); } - static _bonuscaseListToString(list) { + static bonuscasesToString(list) { return list.map(it => `${it.case}:${it.bonus}`) .sort(Misc.ascending()) .join(','); } - static bonuscaseStringToList(bonuscase) { + + static stringToBonuscases(bonuscase) { if (bonuscase == undefined || bonuscase == '') { return [] } - return bonuscase.split(',').map(it => { - const b = it.split(':'); - return { case: b[0], bonus: b[1] }; - }); + return bonuscase.split(',') + .map(it => it.split(':')) + .map(it => { return { case: it[0], bonus: it[1] } }); } } \ No newline at end of file diff --git a/module/rdd-herbes.js b/module/rdd-herbes.js index 4d650e27..2a94b5ff 100644 --- a/module/rdd-herbes.js +++ b/module/rdd-herbes.js @@ -28,9 +28,9 @@ export class RdDHerbes extends Item { } /* -------------------------------------------- */ - static async addPotionFormData(formData) { - formData.isSoins = formData.system.categorie.includes('Soin'); - formData.isRepos = formData.system.categorie.includes('Repos'); + static calculFormData(formData, item) { + formData.isSoins = item.system.categorie.includes('Soin'); + formData.isRepos = item.system.categorie.includes('Repos'); if (formData.isSoins) { RdDHerbes.calculBonusHerbe(formData, this.herbesSoins, 12); } @@ -40,7 +40,7 @@ export class RdDHerbes extends Item { formData.herbesSoins = RdDHerbes.buildHerbesList(this.herbesSoins, 12); formData.herbesRepos = RdDHerbes.buildHerbesList(this.herbesRepos, 7); formData.dateActuelle = game.system.rdd.calendrier.dateCourante(); - formData.enchantement = RdDTimestamp.splitIndexDate(formData.system.prdate); + formData.enchantement = RdDTimestamp.splitIndexDate(item.system.prdate); } /* -------------------------------------------- */ diff --git a/module/tmr-utility.js b/module/tmr-utility.js index c7aa21d7..c6010725 100644 --- a/module/tmr-utility.js +++ b/module/tmr-utility.js @@ -2,228 +2,216 @@ import { Misc } from "./misc.js"; import { Grammar } from "./grammar.js"; import { RdDDice } from "./rdd-dice.js"; -/* -------------------------------------------- */ -const TMRMapping = { - A1: { type: "cite", label: "Cité Vide" }, - B1: { type: "plaines", label: "Plaines d’Assorh" }, - C1: { type: "necropole", label: "Nécropole de Kroak" }, - D1: { type: "fleuve", label: "Fleuve de l'Oubli" }, - E1: { type: "monts", label: "Monts de Kanaï" }, - F1: { type: "cite", label: "Cité Glauque" }, - G1: { type: "desolation", label: "Désolation de Jamais" }, - H1: { type: "lac", label: "Lac d’Anticalme" }, - I1: { type: "plaines", label: "Plaines Grises" }, - J1: { type: "monts", label: "Monts Fainéants" }, - K1: { type: "cite", label: "Cité d’Onkause" }, - L1: { type: "fleuve", label: "Fleuve de l'Oubli" }, - M1: { type: "cite", label: "Cité Jalouse" }, - - A2: { type: "desert", label: "Désert de Mieux" }, - B2: { type: "collines", label: "Collines de Dawell" }, - C2: { type: "marais", label: "Marais Glignants" }, - D2: { type: "cite", label: "Cité de Frost" }, - E2: { type: "plaines", label: "Plaines de Fiask" }, - F2: { type: "lac", label: "Lac de Misère" }, - G2: { type: "marais", label: "Marais Nuisants" }, - H2: { type: "collines", label: "Collines de Parta" }, - I2: { type: "foret", label: "Forêt Fade" }, - J2: { type: "desert", label: "Désert de Poly" }, - K2: { type: "foret", label: "Forêt Tamée" }, - L2: { type: "fleuve", label: "Fleuve de l'Oubli" }, - M2: { type: "necropole", label: "Nécropole de Logos" }, - - A3: { type: "desolation", label: "Désolation de Demain" }, - B3: { type: "plaines", label: "Plaines de Rubéga" }, - C3: { type: "fleuve", label: "Fleuve de l'Oubli" }, - D3: { type: "gouffre", label: "Gouffre d’Oki" }, - E3: { type: "foret", label: "Forêt d’Estoubh" }, - F3: { type: "fleuve", label: "Fleuve de l'Oubli" }, - G3: { type: "gouffre", label: "Gouffre de Sun" }, - H3: { type: "foret", label: "Forêt de Ganna" }, - I3: { type: "monts", label: "Monts Grinçants" }, - J3: { type: "cite", label: "Cité Venin" }, - K3: { type: "plaines", label: "Plaines de Dois" }, - L3: { type: "lac", label: "Lac Laineux" }, - M3: { type: "monts", label: "Monts de Vdah" }, - - A4: { type: "foret", label: "Forêt de Falconax" }, - B4: { type: "monts", label: "Monts Crâneurs" }, - C4: { type: "pont", label: "Pont de Giolii" }, - D4: { type: "lac", label: "Lac de Foam" }, - E4: { type: "plaines", label: "Plaines d’Orti" }, - F4: { type: "fleuve", label: "Fleuve de l'Oubli" }, - G4: { type: "sanctuaire", label: "Sanctuaire Blanc" }, - H4: { type: "plaines", label: "Plaines de Psark" }, - I4: { type: "plaines", label: "Plaines de Xiax" }, - J4: { type: "collines", label: "Collines d’Encre" }, - K4: { type: "pont", label: "Pont de Fah" }, - L4: { type: "sanctuaire", label: "Sanctuaire Mauve" }, - M4: { type: "gouffre", label: "Gouffre Grisant" }, - - A5: { type: "plaines", label: "Plaines de Trilkh" }, - B5: { type: "collines", label: "Collines de Tanegy" }, - C5: { type: "marais", label: "Marais Flouants" }, - D5: { type: "fleuve", label: "Fleuve de l'Oubli" }, - E5: { type: "monts", label: "Monts Brûlants" }, - F5: { type: "cite", label: "Cité de Panople" }, - G5: { type: "pont", label: "Pont d’Ik" }, - H5: { type: "desert", label: "Désert de Krane" }, - I5: { type: "desolation", label: "Désolation de Toujours" }, - J5: { type: "marais", label: "Marais de Jab" }, - K5: { type: "fleuve", label: "Fleuve de l'Oubli" }, - L5: { type: "collines", label: "Collines Suaves" }, - M5: { type: "cite", label: "Cité Rimarde" }, - - A6: { type: "necropole", label: "Nécropole de Zniak" }, - B6: { type: "foret", label: "Forêt de Bust" }, - C6: { type: "cite", label: "Cité Pavois" }, - D6: { type: "fleuve", label: "Fleuve de l'Oubli" }, - E6: { type: "sanctuaire", label: "Sanctuaire de Plaine" }, - F6: { type: "fleuve", label: "Fleuve de l'Oubli" }, - G6: { type: "marais", label: "Marais Glutants" }, - H6: { type: "monts", label: "Monts Gurdes" }, - I6: { type: "necropole", label: "Nécropole de Xotar" }, - J6: { type: "lac", label: "Lac d’Iaupe" }, - K6: { type: "desolation", label: "Désolation de Poor" }, - L6: { type: "foret", label: "Forêt Gueuse" }, - M6: { type: "desolation", label: "Désolation de Presque" }, - - A7: { type: "plaines", label: "Plaines de l’Arc" }, - B7: { type: "marais", label: "Marais Bluants" }, - C7: { type: "fleuve", label: "Fleuve de l'Oubli" }, - D7: { type: "plaines", label: "Plaines d’Affa" }, - E7: { type: "foret", label: "Forêt de Glusks" }, - F7: { type: "fleuve", label: "Fleuve de l'Oubli" }, - G7: { type: "cite", label: "Cité de Terwa" }, - H7: { type: "gouffre", label: "Gouffre de Kapfa" }, - I7: { type: "plaines", label: "Plaines de Troo" }, - J7: { type: "fleuve", label: "Fleuve de l'Oubli" }, - K7: { type: "cite", label: "Cité de Kolix" }, - L7: { type: "gouffre", label: "Gouffre d’Episophe" }, - M7: { type: "desert", label: "Désert de Lave" }, - - A8: { type: "gouffre", label: "Gouffre de Shok" }, - B8: { type: "fleuve", label: "Fleuve de l'Oubli" }, - C8: { type: "foret", label: "Forêt Turmide" }, - D8: { type: "cite", label: "Cité d’Olak" }, - E8: { type: "plaines", label: "Plaines d’Iolise" }, - F8: { type: "lac", label: "Lac des Chats" }, - G8: { type: "plaines", label: "Plaines Sans Joie" }, - H8: { type: "foret", label: "Forêt d’Ourf" }, - I8: { type: "fleuve", label: "Fleuve de l'Oubli" }, - J8: { type: "monts", label: "Monts Barask" }, - K8: { type: "desert", label: "Désert de Fumée" }, - L8: { type: "monts", label: "Monts Tavelés" }, - M8: { type: "plaines", label: "Plaines Lavées" }, - - A9: { type: "collines", label: "Collines de Korrex" }, - B9: { type: "lac", label: "Lac de Lucre" }, - C9: { type: "monts", label: "Monts Tuméfiés" }, - D9: { type: "pont", label: "Pont d’Orx" }, - E9: { type: "fleuve", label: "Fleuve de l'Oubli" }, - F9: { type: "plaines", label: "Plaines de Foe" }, - G9: { type: "desolation", label: "Désolation de Sel" }, - H9: { type: "collines", label: "Collines de Noirseul" }, - I9: { type: "fleuve", label: "Fleuve de l'Oubli" }, - J9: { type: "marais", label: "Marais Gronchants" }, - K9: { type: "sanctuaire", label: "Sanctuaire Noir" }, - L9: { type: "collines", label: "Collines Cornues" }, - M9: { type: "necropole", label: "Nécropole de Zonar" }, - - A10: { type: "sanctuaire", label: "Sanctuaire d’Olis" }, - B10: { type: "monts", label: "Monts Salés" }, - C10: { type: "marais", label: "Marais de Dom" }, - D10: { type: "fleuve", label: "Fleuve de l'Oubli" }, - E10: { type: "gouffre", label: "Gouffre de Junk" }, - F10: { type: "marais", label: "Marais Zultants" }, - G10: { type: "cite", label: "Cité de Sergal" }, - H10: { type: "plaines", label: "Plaines Noires" }, - I10: { type: "lac", label: "Lac Wanito" }, - J10: { type: "fleuve", label: "Fleuve de l'Oubli" }, - K10: { type: "plaines", label: "Plaines Jaunes" }, - L10: { type: "desert", label: "Désert de Nicrop" }, - M10: { type: "foret", label: "Forêt de Jajou" }, - - A11: { type: "desolation", label: "Désolation d’Hier" }, - B11: { type: "cite", label: "Cité de Brilz" }, - C11: { type: "pont", label: "Pont de Roï" }, - D11: { type: "desolation", label: "Désolation de Partout" }, - E11: { type: "lac", label: "Lac de Glinster" }, - F11: { type: "cite", label: "Cité de Noape" }, - G11: { type: "fleuve", label: "Fleuve de l'Oubli" }, - H11: { type: "fleuve", label: "Fleuve de l'Oubli" }, - I11: { type: "pont", label: "Pont de Yalm" }, - J11: { type: "plaines", label: "Plaines de Miltiar" }, - K11: { type: "cite", label: "Cité Tonnerre" }, - L11: { type: "collines", label: "Collines de Kol" }, - M11: { type: "cite", label: "Cité Crapaud" }, - - A12: { type: "plaines", label: "Plaines Sages" }, - B12: { type: "fleuve", label: "Fleuve de l'Oubli" }, - C12: { type: "lac", label: "Lac de Fricassa" }, - D12: { type: "collines", label: "Collines d’Huaï" }, - E12: { type: "monts", label: "Monts Ajourés" }, - F12: { type: "necropole", label: "Nécropole de Throat" }, - G12: { type: "plaines", label: "Plaines de Lufmil" }, - H12: { type: "collines", label: "Collines de Tooth" }, - I12: { type: "gouffre", label: "Gouffre Abimeux" }, - J12: { type: "cite", label: "Cité Folle" }, - K12: { type: "desolation", label: "Désolation d’Amour" }, - L12: { type: "plaines", label: "Plaines Venteuses" }, - M12: { type: "collines", label: "Collines Révulsantes" }, - - A13: { type: "fleuve", label: "Fleuve de l'Oubli" }, - B13: { type: "gouffre", label: "Gouffre des Litiges" }, - C13: { type: "desert", label: "Désert de Neige" }, - D13: { type: "cite", label: "Cité Sordide" }, - E13: { type: "plaines", label: "Plaines de Xnez" }, - F13: { type: "foret", label: "Forêt des Cris" }, - G13: { type: "plaines", label: "Plaines Calcaires" }, - H13: { type: "desolation", label: "Désolation de Rien" }, - I13: { type: "monts", label: "Monts Bigleux" }, - J13: { type: "gouffre", label: "Gouffre de Gromph" }, - K13: { type: "foret", label: "Forêt de Kluth" }, - L13: { type: "monts", label: "Monts Dormants" }, - M13: { type: "plaines", label: "Plaines d’Anjou" }, - - A14: { type: "collines", label: "Collines de Stolis" }, - B14: { type: "necropole", label: "Nécropole de Gorlo" }, - C14: { type: "foret", label: "Forêt de Bissam" }, - D14: { type: "sanctuaire", label: "Sanctuaire Plat" }, - E14: { type: "monts", label: "Monts de Quath" }, - F14: { type: "plaines", label: "Plaines Brisées" }, - G14: { type: "desert", label: "Désert de Sek" }, - H14: { type: "plaines", label: "Plaines Blanches" }, - I14: { type: "cite", label: "Cité Destituée" }, - J14: { type: "desert", label: "Désert de Sank" }, - K14: { type: "necropole", label: "Nécropole d’Antinéar" }, - L14: { type: "plaines", label: "Plaines de Jislith" }, - M14: { type: "desolation", label: "Désolation d’Après" }, - - A15: { type: "cite", label: "Cité de Mielh" }, - C15: { type: "plaines", label: "Plaines de Toué" }, - E15: { type: "foret", label: "Forêt des Furies" }, - G15: { type: "plaines", label: "Plaines des Soupirs" }, - I15: { type: "monts", label: "Monts des Dragées" }, - K15: { type: "collines", label: "Collines Pourpres" }, - M15: { type: "cite", label: "Cité de Klana" } +export const TMRType = { + cite: { type: 'cite', name: "cité", genre: "f" }, + sanctuaire: { type: 'sanctuaire', name: "sanctuaire", genre: 'm' }, + plaines: { type: 'plaines', name: "plaines", genre: "fp" }, + pont: { type: 'pont', name: "pont", genre: "m" }, + collines: { type: 'collines', name: "collines", genre: "p" }, + foret: { type: 'foret', name: "forêt", genre: "f" }, + monts: { type: 'monts', name: "monts", genre: "p" }, + desert: { type: 'desert', name: "désert", genre: "m" }, + fleuve: { type: 'fleuve', name: "fleuve", genre: "m" }, + lac: { type: 'lac', name: "lac", genre: "m" }, + marais: { type: 'marais', name: "marais", genre: "m" }, + gouffre: { type: 'gouffre', name: "gouffre", genre: "m" }, + necropole: { type: 'necropole', name: "nécropole", genre: "f" }, + desolation: { type: 'desolation', name: "désolation", genre: "f" } } -export const TMRType = { - cite: { name: "cité", genre: "f" }, - sanctuaire: { name: "sanctuaire", genre: 'm' }, - plaines: { name: "plaines", genre: "fp" }, - pont: { name: "pont", genre: "m" }, - collines: { name: "collines", genre: "p" }, - foret: { name: "forêt", genre: "f" }, - monts: { name: "monts", genre: "p" }, - desert: { name: "désert", genre: "m" }, - fleuve: { name: "fleuve", genre: "m" }, - lac: { name: "lac", genre: "m" }, - marais: { name: "marais", genre: "m" }, - gouffre: { name: "gouffre", genre: "m" }, - necropole: { name: "nécropole", genre: "f" }, - desolation: { name: "désolation", genre: "f" } +export const FLEUVE_COORD = 'Fleuve' + +const TMRMapping = { + Fleuve: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + A1: { type: TMRType.cite.type, label: "Cité Vide" }, + B1: { type: TMRType.plaines.type, label: "Plaines d’Assorh" }, + C1: { type: TMRType.necropole.type, label: "Nécropole de Kroak" }, + D1: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + E1: { type: TMRType.monts.type, label: "Monts de Kanaï" }, + F1: { type: TMRType.cite.type, label: "Cité Glauque" }, + G1: { type: TMRType.desolation.type, label: "Désolation de Jamais" }, + H1: { type: TMRType.lac.type, label: "Lac d’Anticalme" }, + I1: { type: TMRType.plaines.type, label: "Plaines Grises" }, + J1: { type: TMRType.monts.type, label: "Monts Fainéants" }, + K1: { type: TMRType.cite.type, label: "Cité d’Onkause" }, + L1: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + M1: { type: TMRType.cite.type, label: "Cité Jalouse" }, + A2: { type: TMRType.desert.type, label: "Désert de Mieux" }, + B2: { type: TMRType.collines.type, label: "Collines de Dawell" }, + C2: { type: TMRType.marais.type, label: "Marais Glignants" }, + D2: { type: TMRType.cite.type, label: "Cité de Frost" }, + E2: { type: TMRType.plaines.type, label: "Plaines de Fiask" }, + F2: { type: TMRType.lac.type, label: "Lac de Misère" }, + G2: { type: TMRType.marais.type, label: "Marais Nuisants" }, + H2: { type: TMRType.collines.type, label: "Collines de Parta" }, + I2: { type: TMRType.foret.type, label: "Forêt Fade" }, + J2: { type: TMRType.desert.type, label: "Désert de Poly" }, + K2: { type: TMRType.foret.type, label: "Forêt Tamée" }, + L2: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + M2: { type: TMRType.necropole.type, label: "Nécropole de Logos" }, + A3: { type: TMRType.desolation.type, label: "Désolation de Demain" }, + B3: { type: TMRType.plaines.type, label: "Plaines de Rubéga" }, + C3: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + D3: { type: TMRType.gouffre.type, label: "Gouffre d’Oki" }, + E3: { type: TMRType.foret.type, label: "Forêt d’Estoubh" }, + F3: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + G3: { type: TMRType.gouffre.type, label: "Gouffre de Sun" }, + H3: { type: TMRType.foret.type, label: "Forêt de Ganna" }, + I3: { type: TMRType.monts.type, label: "Monts Grinçants" }, + J3: { type: TMRType.cite.type, label: "Cité Venin" }, + K3: { type: TMRType.plaines.type, label: "Plaines de Dois" }, + L3: { type: TMRType.lac.type, label: "Lac Laineux" }, + M3: { type: TMRType.monts.type, label: "Monts de Vdah" }, + A4: { type: TMRType.foret.type, label: "Forêt de Falconax" }, + B4: { type: TMRType.monts.type, label: "Monts Crâneurs" }, + C4: { type: TMRType.pont.type, label: "Pont de Giolii" }, + D4: { type: TMRType.lac.type, label: "Lac de Foam" }, + E4: { type: TMRType.plaines.type, label: "Plaines d’Orti" }, + F4: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + G4: { type: TMRType.sanctuaire.type, label: "Sanctuaire Blanc" }, + H4: { type: TMRType.plaines.type, label: "Plaines de Psark" }, + I4: { type: TMRType.plaines.type, label: "Plaines de Xiax" }, + J4: { type: TMRType.collines.type, label: "Collines d’Encre" }, + K4: { type: TMRType.pont.type, label: "Pont de Fah" }, + L4: { type: TMRType.sanctuaire.type, label: "Sanctuaire Mauve" }, + M4: { type: TMRType.gouffre.type, label: "Gouffre Grisant" }, + A5: { type: TMRType.plaines.type, label: "Plaines de Trilkh" }, + B5: { type: TMRType.collines.type, label: "Collines de Tanegy" }, + C5: { type: TMRType.marais.type, label: "Marais Flouants" }, + D5: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + E5: { type: TMRType.monts.type, label: "Monts Brûlants" }, + F5: { type: TMRType.cite.type, label: "Cité de Panople" }, + G5: { type: TMRType.pont.type, label: "Pont d’Ik" }, + H5: { type: TMRType.desert.type, label: "Désert de Krane" }, + I5: { type: TMRType.desolation.type, label: "Désolation de Toujours" }, + J5: { type: TMRType.marais.type, label: "Marais de Jab" }, + K5: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + L5: { type: TMRType.collines.type, label: "Collines Suaves" }, + M5: { type: TMRType.cite.type, label: "Cité Rimarde" }, + A6: { type: TMRType.necropole.type, label: "Nécropole de Zniak" }, + B6: { type: TMRType.foret.type, label: "Forêt de Bust" }, + C6: { type: TMRType.cite.type, label: "Cité Pavois" }, + D6: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + E6: { type: TMRType.sanctuaire.type, label: "Sanctuaire de Plaine" }, + F6: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + G6: { type: TMRType.marais.type, label: "Marais Glutants" }, + H6: { type: TMRType.monts.type, label: "Monts Gurdes" }, + I6: { type: TMRType.necropole.type, label: "Nécropole de Xotar" }, + J6: { type: TMRType.lac.type, label: "Lac d’Iaupe" }, + K6: { type: TMRType.desolation.type, label: "Désolation de Poor" }, + L6: { type: TMRType.foret.type, label: "Forêt Gueuse" }, + M6: { type: TMRType.desolation.type, label: "Désolation de Presque" }, + A7: { type: TMRType.plaines.type, label: "Plaines de l’Arc" }, + B7: { type: TMRType.marais.type, label: "Marais Bluants" }, + C7: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + D7: { type: TMRType.plaines.type, label: "Plaines d’Affa" }, + E7: { type: TMRType.foret.type, label: "Forêt de Glusks" }, + F7: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + G7: { type: TMRType.cite.type, label: "Cité de Terwa" }, + H7: { type: TMRType.gouffre.type, label: "Gouffre de Kapfa" }, + I7: { type: TMRType.plaines.type, label: "Plaines de Troo" }, + J7: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + K7: { type: TMRType.cite.type, label: "Cité de Kolix" }, + L7: { type: TMRType.gouffre.type, label: "Gouffre d’Episophe" }, + M7: { type: TMRType.desert.type, label: "Désert de Lave" }, + A8: { type: TMRType.gouffre.type, label: "Gouffre de Shok" }, + B8: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + C8: { type: TMRType.foret.type, label: "Forêt Turmide" }, + D8: { type: TMRType.cite.type, label: "Cité d’Olak" }, + E8: { type: TMRType.plaines.type, label: "Plaines d’Iolise" }, + F8: { type: TMRType.lac.type, label: "Lac des Chats" }, + G8: { type: TMRType.plaines.type, label: "Plaines Sans Joie" }, + H8: { type: TMRType.foret.type, label: "Forêt d’Ourf" }, + I8: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + J8: { type: TMRType.monts.type, label: "Monts Barask" }, + K8: { type: TMRType.desert.type, label: "Désert de Fumée" }, + L8: { type: TMRType.monts.type, label: "Monts Tavelés" }, + M8: { type: TMRType.plaines.type, label: "Plaines Lavées" }, + A9: { type: TMRType.collines.type, label: "Collines de Korrex" }, + B9: { type: TMRType.lac.type, label: "Lac de Lucre" }, + C9: { type: TMRType.monts.type, label: "Monts Tuméfiés" }, + D9: { type: TMRType.pont.type, label: "Pont d’Orx" }, + E9: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + F9: { type: TMRType.plaines.type, label: "Plaines de Foe" }, + G9: { type: TMRType.desolation.type, label: "Désolation de Sel" }, + H9: { type: TMRType.collines.type, label: "Collines de Noirseul" }, + I9: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + J9: { type: TMRType.marais.type, label: "Marais Gronchants" }, + K9: { type: TMRType.sanctuaire.type, label: "Sanctuaire Noir" }, + L9: { type: TMRType.collines.type, label: "Collines Cornues" }, + M9: { type: TMRType.necropole.type, label: "Nécropole de Zonar" }, + A10: { type: TMRType.sanctuaire.type, label: "Sanctuaire d’Olis" }, + B10: { type: TMRType.monts.type, label: "Monts Salés" }, + C10: { type: TMRType.marais.type, label: "Marais de Dom" }, + D10: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + E10: { type: TMRType.gouffre.type, label: "Gouffre de Junk" }, + F10: { type: TMRType.marais.type, label: "Marais Zultants" }, + G10: { type: TMRType.cite.type, label: "Cité de Sergal" }, + H10: { type: TMRType.plaines.type, label: "Plaines Noires" }, + I10: { type: TMRType.lac.type, label: "Lac Wanito" }, + J10: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + K10: { type: TMRType.plaines.type, label: "Plaines Jaunes" }, + L10: { type: TMRType.desert.type, label: "Désert de Nicrop" }, + M10: { type: TMRType.foret.type, label: "Forêt de Jajou" }, + A11: { type: TMRType.desolation.type, label: "Désolation d’Hier" }, + B11: { type: TMRType.cite.type, label: "Cité de Brilz" }, + C11: { type: TMRType.pont.type, label: "Pont de Roï" }, + D11: { type: TMRType.desolation.type, label: "Désolation de Partout" }, + E11: { type: TMRType.lac.type, label: "Lac de Glinster" }, + F11: { type: TMRType.cite.type, label: "Cité de Noape" }, + G11: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + H11: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + I11: { type: TMRType.pont.type, label: "Pont de Yalm" }, + J11: { type: TMRType.plaines.type, label: "Plaines de Miltiar" }, + K11: { type: TMRType.cite.type, label: "Cité Tonnerre" }, + L11: { type: TMRType.collines.type, label: "Collines de Kol" }, + M11: { type: TMRType.cite.type, label: "Cité Crapaud" }, + A12: { type: TMRType.plaines.type, label: "Plaines Sages" }, + B12: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + C12: { type: TMRType.lac.type, label: "Lac de Fricassa" }, + D12: { type: TMRType.collines.type, label: "Collines d’Huaï" }, + E12: { type: TMRType.monts.type, label: "Monts Ajourés" }, + F12: { type: TMRType.necropole.type, label: "Nécropole de Throat" }, + G12: { type: TMRType.plaines.type, label: "Plaines de Lufmil" }, + H12: { type: TMRType.collines.type, label: "Collines de Tooth" }, + I12: { type: TMRType.gouffre.type, label: "Gouffre Abimeux" }, + J12: { type: TMRType.cite.type, label: "Cité Folle" }, + K12: { type: TMRType.desolation.type, label: "Désolation d’Amour" }, + L12: { type: TMRType.plaines.type, label: "Plaines Venteuses" }, + M12: { type: TMRType.collines.type, label: "Collines Révulsantes" }, + A13: { type: TMRType.fleuve.type, label: "Fleuve de l'Oubli" }, + B13: { type: TMRType.gouffre.type, label: "Gouffre des Litiges" }, + C13: { type: TMRType.desert.type, label: "Désert de Neige" }, + D13: { type: TMRType.cite.type, label: "Cité Sordide" }, + E13: { type: TMRType.plaines.type, label: "Plaines de Xnez" }, + F13: { type: TMRType.foret.type, label: "Forêt des Cris" }, + G13: { type: TMRType.plaines.type, label: "Plaines Calcaires" }, + H13: { type: TMRType.desolation.type, label: "Désolation de Rien" }, + I13: { type: TMRType.monts.type, label: "Monts Bigleux" }, + J13: { type: TMRType.gouffre.type, label: "Gouffre de Gromph" }, + K13: { type: TMRType.foret.type, label: "Forêt de Kluth" }, + L13: { type: TMRType.monts.type, label: "Monts Dormants" }, + M13: { type: TMRType.plaines.type, label: "Plaines d’Anjou" }, + A14: { type: TMRType.collines.type, label: "Collines de Stolis" }, + B14: { type: TMRType.necropole.type, label: "Nécropole de Gorlo" }, + C14: { type: TMRType.foret.type, label: "Forêt de Bissam" }, + D14: { type: TMRType.sanctuaire.type, label: "Sanctuaire Plat" }, + E14: { type: TMRType.monts.type, label: "Monts de Quath" }, + F14: { type: TMRType.plaines.type, label: "Plaines Brisées" }, + G14: { type: TMRType.desert.type, label: "Désert de Sek" }, + H14: { type: TMRType.plaines.type, label: "Plaines Blanches" }, + I14: { type: TMRType.cite.type, label: "Cité Destituée" }, + J14: { type: TMRType.desert.type, label: "Désert de Sank" }, + K14: { type: TMRType.necropole.type, label: "Nécropole d’Antinéar" }, + L14: { type: TMRType.plaines.type, label: "Plaines de Jislith" }, + M14: { type: TMRType.desolation.type, label: "Désolation d’Après" }, + A15: { type: TMRType.cite.type, label: "Cité de Mielh" }, + C15: { type: TMRType.plaines.type, label: "Plaines de Toué" }, + E15: { type: TMRType.foret.type, label: "Forêt des Furies" }, + G15: { type: TMRType.plaines.type, label: "Plaines des Soupirs" }, + I15: { type: TMRType.monts.type, label: "Monts des Dragées" }, + K15: { type: TMRType.collines.type, label: "Collines Pourpres" }, + M15: { type: TMRType.cite.type, label: "Cité de Klana" } } /* -------------------------------------------- */ @@ -251,13 +239,16 @@ const TMR_MOVE = { */ export class TMRUtility { static init() { + for (let coord in TMRMapping) { - const tmr = TMRMapping[coord]; - tmr.coord = coord; - tmr.oddq = TMRUtility.coordTMRToOddq(coord); - tmr.genre = TMRType[tmr.type].genre; + const tmr = TMRMapping[coord] + tmr.coord = coord + tmr.genre = TMRType[tmr.type].genre + if (coord != FLEUVE_COORD) { + tmr.oddq = TMRUtility.coordTMRToOddq(coord) + } } - let tmrByType = Misc.classify(Object.values(TMRMapping)); + let tmrByType = Misc.classify(Object.values(TMRMapping).filter(it => it.coord != FLEUVE_COORD)) for (const [type, list] of Object.entries(tmrByType)) { TMRType[type].list = list; } @@ -265,14 +256,17 @@ export class TMRUtility { /* -------------------------------------------- */ static verifyTMRCoord(coord) { - return Grammar.equalsInsensitive(coord, 'Fleuve') || TMRUtility.getTMR(coord); + return Grammar.equalsInsensitive(coord, FLEUVE_COORD) || TMRUtility.getTMR(coord); } /* -------------------------------------------- */ static getTMR(coord) { - return coord == 'Fleuve' ? TMRMapping['D1'] : TMRMapping[coord]; + return coord == FLEUVE_COORD ? TMRMapping['D1'] : TMRMapping[coord]; } + static isFleuve(coord) { + return TMRMapping[coord]?.type == TMRType.fleuve.type + } static getTMRLabel(coord) { return TMRUtility.getTMR(coord)?.label ?? (coord + ": case inconnue"); } diff --git a/templates/item-sort-sheet.html b/templates/item-sort-sheet.html index cd386fb1..0368c24c 100644 --- a/templates/item-sort-sheet.html +++ b/templates/item-sort-sheet.html @@ -37,7 +37,7 @@
- +
@@ -59,14 +59,23 @@
- {{#each bonusCaseList as |bcData key|}} +
- - - + + +
+ {{#each bonusCaseList as |caseTmr key|}} +
+ + + + +
{{/each}} - +
{{>"systems/foundryvtt-reve-de-dragon/templates/partial-item-description.html"}} From 6af5a85dc19c7fafd3d91ded6e4d4071966ee2dc Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Thu, 28 Nov 2024 00:43:39 +0100 Subject: [PATCH 2/4] Corrections des tirages tmr/rencontres MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - on n'affiche plus le compendium d'origine des rencontres dans le tchat - utilisation de ChatMessageData#rolls (compat future v14) - le résultat d'un d100 n'a pas à afficher de signe '%' - utilistaion des types de TMR plutôt que les noms en minuscules --- module/rdd-commands.js | 17 +++++++++-------- module/settings/system-compendiums.js | 9 +++------ module/tmr-rencontres.js | 13 +++++-------- module/tmr-utility.js | 12 ++++++------ templates/chat-compendium-table-roll.hbs | 7 +++++-- 5 files changed, 28 insertions(+), 30 deletions(-) diff --git a/module/rdd-commands.js b/module/rdd-commands.js index fcaa5b4f..aabd3dc0 100644 --- a/module/rdd-commands.js +++ b/module/rdd-commands.js @@ -360,13 +360,14 @@ export class RdDCommands { async getTMRAleatoire(msg, params) { if (params.length < 2) { - let type = params[0]; - const tmr = await TMRUtility.getTMRAleatoire(type ? (it => it.type == type) : (it => true)); - return RdDCommands._chatAnswer(msg, `Case aléatoire: ${tmr.coord} - ${tmr.label}`); - } - else { - return false; + let type = params[0] + const solvedTerrain = TMRUtility.findTMRLike(type)?.type + if (solvedTerrain){ + const tmr = await TMRUtility.getTMRAleatoire(type ? (it => it.type == solvedTerrain) : (it => true)) + return RdDCommands._chatAnswer(msg, `Case aléatoire: ${tmr.coord} - ${tmr.label}`) + } } + return false; } async findTMR(msg, params) { @@ -384,11 +385,11 @@ export class RdDCommands { async tableRencontres(msg, params) { if (params && params.length > 0) { const search = Misc.join(params, ' '); - const solvedTerrain = TMRUtility.findTMRLike(search); + const solvedTerrain = TMRUtility.findTMRLike(search) if (solvedTerrain == undefined) { return RdDCommands._chatAnswer(msg, 'Aucune TMR correspondant à ' + search); } - return await game.system.rdd.rencontresTMR.chatTable(solvedTerrain); + return await game.system.rdd.rencontresTMR.chatTable(solvedTMRType.name) } return false; } diff --git a/module/settings/system-compendiums.js b/module/settings/system-compendiums.js index dc631caf..317f2054 100644 --- a/module/settings/system-compendiums.js +++ b/module/settings/system-compendiums.js @@ -284,23 +284,20 @@ export class CompendiumTableHelpers { } /* -------------------------------------------- */ - static async tableRowToChatMessage(row, type = 'Item') { + static async tableRowToChatMessage(row, type, options = {showSource: true}) { if (!row) { return; } - const percentages = (row.total == 100) ? '%' : '' const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table-roll.hbs', { roll: row.roll, document: row.document, - percentages, typeName: Misc.typeName(type, row.document?.type ?? 'objet'), isGM: game.user.isGM, + options }); const messageData = { - // flavor: flavorContent, user: game.user.id, - type: CONST.CHAT_MESSAGE_TYPES.ROLL, - roll: row.roll, + rolls: [row.roll], sound: CONFIG.sounds.dice, content: flavorContent }; diff --git a/module/tmr-rencontres.js b/module/tmr-rencontres.js index ef8ea61a..61ad4ead 100644 --- a/module/tmr-rencontres.js +++ b/module/tmr-rencontres.js @@ -26,22 +26,19 @@ export class TMRRencontres { * @param {*} forcedRoll */ async rollRencontre(terrain, forcedRoll) { - terrain = TMRUtility.findTMRLike(terrain); - if (terrain == undefined) { + const tmrType = TMRUtility.findTMRLike(terrain)?.type + if (tmrType == undefined) { return undefined; } if (forcedRoll && (forcedRoll <= 0 || forcedRoll > 100)) { forcedRoll = undefined; } - const codeTerrain = Grammar.toLowerCaseNoAccent(terrain) - const filtreMauvaise = codeTerrain == 'mauvaise' ? it => it.system.mauvaiseRencontre : it => !it.system.mauvaiseRencontre; - const frequence = it => it.system.frequence[codeTerrain]; + const filtreMauvaise = tmrType == 'mauvaise' ? it => it.system.mauvaiseRencontre : it => !it.system.mauvaiseRencontre; + const frequence = it => it.system.frequence[tmrType]; const row = await this.table.getRandom(frequence, filtreMauvaise, forcedRoll); if (row) { - console.log("DORM", row); - //row.document.system.computedForce = new Roll(row.document.system.formula).roll({async: false}).total; - await CompendiumTableHelpers.tableRowToChatMessage(row); + await CompendiumTableHelpers.tableRowToChatMessage(row, 'Item', {showSource: false}); } return row?.document; diff --git a/module/tmr-utility.js b/module/tmr-utility.js index c6010725..e8ae35e6 100644 --- a/module/tmr-utility.js +++ b/module/tmr-utility.js @@ -284,18 +284,18 @@ export class TMRUtility { static findTMRLike(type, options = { inclusMauvaise: true }) { const choix = [...Object.values(TMRType)] if (options.inclusMauvaise) { - choix.push({ name: 'Mauvaise' }); + choix.push({ name: 'Mauvaise', type: 'mauvaise'}); } - const selection = Misc.findAllLike(type, choix).map(it => it.name); + const selection = Misc.findAllLike(type, choix) if (selection.length == 0) { ui.notifications.warn(`Un type de TMR doit être indiqué, '${type}' n'est pas trouvé dans ${choix}`); - return undefined; + return undefined } if (selection.length > 1) { - ui.notifications.warn(`Plusieurs types de TMR pourraient correspondre à '${type}': ${selection}`); + ui.notifications.warn(`Plusieurs types de TMR pourraient correspondre à '${type}': ${selection.map(it => it.name)}`); return undefined; } - return selection[0]; + return selection[0] } static typeTmrName(type) { @@ -320,7 +320,7 @@ export class TMRUtility { /* -------------------------------------------- */ static deplacement(coordOrig, moveName) { const tmrMove = TMR_MOVE[moveName]; - if (! tmrMove) { + if (!tmrMove) { ui.notifications.error(`Le déplacement dans les TMR '${moveName}' est inconnu`) return coordOrig } diff --git a/templates/chat-compendium-table-roll.hbs b/templates/chat-compendium-table-roll.hbs index 2981d9af..2f5a76c0 100644 --- a/templates/chat-compendium-table-roll.hbs +++ b/templates/chat-compendium-table-roll.hbs @@ -1,6 +1,9 @@

Tirage aléatoire: {{document.name}}

-
Tirage de {{typeName}} aléatoire depuis {{document.pack}}
-
Jet {{roll.formula}} : {{roll.total}}{{percentages}}
+
+ Tirage de {{typeName}} aléatoire + {{#if options.showSource}} depuis {{document.pack}}{{/if}} +
+
Jet {{roll.formula}} : {{roll.total}}

From 8be4c3343fd458d17d9d82e4199bb4e85dce3c17 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Fri, 29 Nov 2024 22:11:24 +0100 Subject: [PATCH 3/4] Fix: les tas de conteneurs --- changelog.md | 2 ++ module/actor.js | 11 ++++++----- module/actor/base-actor.js | 14 +++++++++++++- module/item.js | 4 ++++ 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/changelog.md b/changelog.md index dd0886a4..325878fc 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,8 @@ # 12.0 ## 12.0.24 - Les ajustements d'Astrobazzarh - corrections + - les tas dans les conteneurs peuvent être désempilés sans rendre le conteneur inutilisable + - les conteneurs ne peuvent plus être empilés (pour éviter que le contenu de Schroedinger quand on les sépare) - on peut maintenant saisir et supprimer les bonus de cases de manière intuitive ## 12.0.23 - La bibliothèque d'Astrobazzarh diff --git a/module/actor.js b/module/actor.js index 081103ee..badb3492 100644 --- a/module/actor.js +++ b/module/actor.js @@ -3017,15 +3017,16 @@ export class RdDActor extends RdDBaseActorSang { case 'queue': case 'ombre': case 'souffle': - await this.onDeleteOwnedDraconique(item, options, id); - break; + await this.onDeleteOwnedDraconique(item, options, id) + break case 'casetmr': - await this.onDeleteOwnedCaseTmr(item, options, id); - break; + await this.onDeleteOwnedCaseTmr(item, options, id) + break case 'empoignade': await RdDEmpoignade.deleteLinkedEmpoignade(this.id, item) - break; + break } + super.onDeleteItem(item, options, id) } /* -------------------------------------------- */ diff --git a/module/actor/base-actor.js b/module/actor/base-actor.js index 349d1973..a1456895 100644 --- a/module/actor/base-actor.js +++ b/module/actor/base-actor.js @@ -213,8 +213,20 @@ export class RdDBaseActor extends Actor { /* -------------------------------------------- */ async onPreUpdateItem(item, change, options, id) { } async onCreateItem(item, options, id) { } - async onDeleteItem(item, options, id) { } async onUpdateActor(update, options, actorId) { } + async onDeleteItem(item, options, id) { + if (item.isInventaire()) { + this._removeItemFromConteneur(item) + } + } + + _removeItemFromConteneur(item) { + this.items.filter(it => it.isConteneur() && it.system.contenu.includes(item.id)) + .forEach(conteneur => { + const nouveauContenu = conteneur.system.contenu.filter(id => id != item.id); + conteneur.update({ 'system.contenu': nouveauContenu }); + }); + } async onTimeChanging(oldTimestamp, newTimestamp) { this.items.filter(it => it.isFinPeriode(oldTimestamp, newTimestamp)) diff --git a/module/item.js b/module/item.js index b45373e2..ace79129 100644 --- a/module/item.js +++ b/module/item.js @@ -571,6 +571,7 @@ export class RdDItem extends Item { else { await this.quantiteIncDec(item.system.quantite); } + // TODO: suppression dans les conteneurs! await item.delete(); } @@ -601,6 +602,9 @@ export class RdDItem extends Item { if (!other || !this.isInventaire()) { return [false, undefined]; } + if (this.isConteneur()){ + return [false, `Impossible de regrouper des conteneurs, ils ne sont pas empilables`]; + } if (this.system.quantite == undefined) { return [false, `Impossible de regrouper des ${this.type}, ils ne sont pas empilables`]; } From 9b1a179a71d2b5370181f891be4660c7e9959c7a Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Fri, 29 Nov 2024 23:32:21 +0100 Subject: [PATCH 4/4] Corrections voies draconic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Utilisation du nom de voie (Oniros au lieu de Voie d'Oniros) - compatible anciens sorts - migration des objets existants - amélioration de l'affichage de la liste des sorts --- changelog.md | 3 ++ module/actor/export-scriptarium/mapping.js | 18 +++------- module/item-sheet.js | 2 +- module/item-sort.js | 38 +++++++++++++++------- module/migrations.js | 28 +++++++++++++++- module/rdd-main.js | 2 ++ templates/actor/hr-sorts.html | 15 +++++---- templates/enum-draconic.html | 2 +- 8 files changed, 74 insertions(+), 34 deletions(-) diff --git a/changelog.md b/changelog.md index 325878fc..250213e5 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,8 @@ # 12.0 ## 12.0.24 - Les ajustements d'Astrobazzarh +- amélioration + - meilleure gestion des noms des voies de draconic + - affichage du détail des sorts avec le nom de voie, 'court', la difficulté, le coût - corrections - les tas dans les conteneurs peuvent être désempilés sans rendre le conteneur inutilisable - les conteneurs ne peuvent plus être empilés (pour éviter que le contenu de Schroedinger quand on les sépare) diff --git a/module/actor/export-scriptarium/mapping.js b/module/actor/export-scriptarium/mapping.js index e93b7b5c..e36db5ff 100644 --- a/module/actor/export-scriptarium/mapping.js +++ b/module/actor/export-scriptarium/mapping.js @@ -238,7 +238,7 @@ export class Mapping { static prepareSorts(actor) { const codeVoies = Mapping.getCompetencesCategorie(actor, CATEGORIES_DRACONIC) - .map(it => RdDItemSort.getVoieCode(it)) + .map(it => RdDItemSort.getCodeVoie(it.name)) return actor.itemTypes[ITEM_TYPES.sort].map(it => Mapping.prepareSort(it, codeVoies)) .sort(Misc.ascending(it => `${it.voie} : ${it.description}`)) @@ -246,7 +246,7 @@ export class Mapping { static prepareSort(sort, voies) { return { - voie: RdDItemSort.getCodeDraconic(sort, voies), + voie: RdDItemSort.getCode(sort, voies), description: Mapping.descriptionSort(sort), bonus: Mapping.bonusCase(sort) } @@ -255,17 +255,9 @@ export class Mapping { static descriptionSort(sort) { const ptSeuil = Array(sort.system.coutseuil).map(it => '*') const caseTMR = sort.system.caseTMRspeciale.length > 0 ? Mapping.toVar(sort.system.caseTMRspeciale) : Misc.upperFirst(TMRType[sort.system.caseTMR].name) - const ptreve = Mapping.addSpaceToNonNumeric(sort.system.ptreve) - const diff = Mapping.addSpaceToNonNumeric(sort.system.difficulte) - return `${sort.name}${ptSeuil} (${caseTMR}) R${diff} r${ptreve}` - } - - static addSpaceToNonNumeric(value) { - return Number.isNumeric(value) || /[-\d].*/.match(String(value)) ? value : ' ' + Mapping.toVar(value) - } - - static toVar(value) { - return value.replace('variable', 'var') + const coutReve = 'r' + RdDItemSort.addSpaceToNonNumeric(sort.system.ptreve) + const diff = 'R' + RdDItemSort.addSpaceToNonNumeric(sort.system.difficulte) + return `${sort.name}${ptSeuil} (${caseTMR}) ${diff} ${coutReve}` } static bonusCase(sort) { diff --git a/module/item-sheet.js b/module/item-sheet.js index e8f3af78..e25aaddd 100644 --- a/module/item-sheet.js +++ b/module/item-sheet.js @@ -296,7 +296,7 @@ export class RdDItemSheet extends ItemSheet { )) break case ITEM_TYPES.competence: - formData['system.niveau'] = formData.system.niveau ?? formData.system.base + formData['system.niveau'] = formData['system.niveau'] ?? formData['system.base'] break } diff --git a/module/item-sort.js b/module/item-sort.js index 5519f657..fd7be217 100644 --- a/module/item-sort.js +++ b/module/item-sort.js @@ -2,19 +2,32 @@ import { Grammar } from "./grammar.js"; import { RdDItemCompetence } from "./item-competence.js"; import { ITEM_TYPES } from "./item.js"; import { Misc } from "./misc.js"; -import { FLEUVE_COORD, TMRType, TMRUtility } from "./tmr-utility.js"; +import { FLEUVE_COORD, TMRUtility } from "./tmr-utility.js"; -const VOIES_DRACONIC = [ +export const VOIES_DRACONIC = [ { code: 'O', label: "Voie d'Oniros", short: 'Oniros', ordre: 'a' }, { code: 'H', label: "Voie d'Hypnos", short: 'Hypnos', ordre: 'b' }, { code: 'N', label: "Voie de Narcos", short: 'Narcos', ordre: 'c' }, { code: 'T', label: "Voie de Thanatos", short: 'Thanatos', ordre: 'd' }, - { code: 'O/H/N/T', label: "Oniros/Hypnos/Narcos/Thanatos", short: 'Oniros/Hypnos/Narcos/Thanatos', ordre: 'e' }, - { code: 'O/H/N', label: "Oniros/Hypnos/Narcos", short: "Oniros/Hypnos/Narcos", ordre: 'f' } + { code: 'O/H/N/T', label: "Oniros/Hypnos/Narcos/Thanatos", short: 'O/H/N/T', ordre: 'e' }, + { code: 'O/H/N', label: "Oniros/Hypnos/Narcos", short: "O/H/N", ordre: 'f' } ] /* -------------------------------------------- */ export class RdDItemSort extends Item { + static preloadHandlebars() { + Handlebars.registerHelper('itemSort-spaceIfText', val => RdDItemSort.addSpaceToNonNumeric(val)) + Handlebars.registerHelper('itemSort-codeDraconic', voie => RdDItemSort.getCode(voie)) + Handlebars.registerHelper('itemSort-shortDraconic', voie => RdDItemSort.getShortVoie(voie)) + } + + static addSpaceToNonNumeric(value) { + return Number.isNumeric(value) || ['-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'].includes( String(value).charAt[0]) ? value : ' ' + RdDItemSort.toVar(value) + } + + static toVar(value) { + return value ? value.replace('variable', 'var') : '' + } static getDraconicsSort(competencesDraconic, sort) { // se baser sur la voie du sort? @@ -33,20 +46,23 @@ export class RdDItemSort extends Item { return (VOIES_DRACONIC.find(it => it.code == code)?.ordre ?? '?') } - static getVoieCode(voie) { - return VOIES_DRACONIC.find(it => voie.name.includes(it.short))?.code ?? '?' + static getCodeVoie(voie) { + return VOIES_DRACONIC.find(it => [it.code, it.short, it.label].includes(voie))?.code ?? '?' } - static getCodeDraconic(sort, voies = ['O', 'H', 'N', 'T']) { + static getShortVoie(voie) { + return VOIES_DRACONIC.find(it => [it.code, it.short, it.label].includes(voie))?.short ?? voie + } + + static getCode(sort, codeVoies = ['O', 'H', 'N', 'T']) { switch (Grammar.toLowerCaseNoAccent(sort.name)) { case "lecture d'aura": case "detection d'aura": - return RdDItemSort.$voiesConnues('O/H/N/T', voies) + return RdDItemSort.$voiesConnues('O/H/N/T', codeVoies) case "annulation de magie": - return RdDItemSort.$voiesConnues('O/H/N', voies) + return RdDItemSort.$voiesConnues('O/H/N', codeVoies) } - const voie = VOIES_DRACONIC.find(it => it.label.includes(sort.system.draconic)) - return voie?.code ?? sort.system.draconic + return RdDItemSort.getCodeVoie(sort.system.draconic) } static $voiesConnues(voiesSort, voies) { diff --git a/module/migrations.js b/module/migrations.js index c608d08a..26c84756 100644 --- a/module/migrations.js +++ b/module/migrations.js @@ -5,7 +5,7 @@ import { Monnaie } from "./item-monnaie.js"; import { RdDItem, ITEM_TYPES } from "./item.js"; import { RdDTimestamp } from "./time/rdd-timestamp.js"; import { RdDRaretes } from "./item/raretes.js"; -import { RdDCalendrier } from "./time/rdd-calendrier.js"; +import { VOIES_DRACONIC } from "./item-sort.js"; class Migration { get code() { return "sample"; } @@ -530,6 +530,32 @@ class _11_2_20_MigrationAstrologie extends Migration { } } +class _12_0_24_MigrationVoieSorts extends Migration { + get code() { return "migration-voies-sorts" } + get version() { return "12.0.24" } + + async migrate() { + await this.applyItemsUpdates(items => items + .filter(it => ITEM_TYPES.sort == it.type) + .map(it => this.migrateSort(it)) + ) + } + migrateSort(it) { + return { + _id: it.id, + 'system.draconic': this.convertDraconic(it.system.draconic), + } + } + convertDraconic(draconic) { + for (let v of VOIES_DRACONIC) { + if ([v.label, v.short, v.code].includes(draconic)) { + return v.short + } + } + return draconic + } +} + export class Migrations { static getMigrations() { return [ diff --git a/module/rdd-main.js b/module/rdd-main.js index 0cfce70a..5b857b87 100644 --- a/module/rdd-main.js +++ b/module/rdd-main.js @@ -69,6 +69,7 @@ import { ExportScriptarium } from "./actor/export-scriptarium/export-scriptarium import { AppPersonnageAleatoire } from "./actor/random/app-personnage-aleatoire.js" import { RdDActorExportSheet } from "./actor/export-scriptarium/actor-encart-sheet.js" import { RdDStatBlockParser } from "./apps/rdd-import-stats.js" +import { RdDItemSort } from "./item-sort.js" /** * RdD system @@ -122,6 +123,7 @@ export class SystemReveDeDragon { // preload handlebars templates RdDUtility.preloadHandlebarsTemplates() AppPersonnageAleatoire.preloadHandlebars() + RdDItemSort.preloadHandlebars() /* -------------------------------------------- */ ReglesOptionnelles.initSettings() diff --git a/templates/actor/hr-sorts.html b/templates/actor/hr-sorts.html index 4146cfcb..7cb9249f 100644 --- a/templates/actor/hr-sorts.html +++ b/templates/actor/hr-sorts.html @@ -4,14 +4,15 @@ {{#each (trier sorts) as |sort key|}}
  • - - {{sort.name}} - - {{#if sort.system.caseTMRspeciale}}{{sort.system.caseTMRspeciale}}{{else}}{{upperFirst sort.system.caseTMR}}{{/if}} - - - {{#if sort.system.isrituel}}Rituel{{/if}} - {{sort.system.draconic}}/{{sort.system.difficulte}} + {{itemSort-shortDraconic sort.system.draconic}} + {{sort.name}}{{#if sort.system.isrituel}} + {{/if}} + + {{#if sort.system.caseTMRspeciale}}{{sort.system.caseTMRspeciale}}{{else}}{{upperFirst sort.system.caseTMR}}{{/if}} + + R{{itemSort-spaceIfText sort.system.difficulte}} r{{itemSort-spaceIfText sort.system.ptreve}}
    +
    diff --git a/templates/enum-draconic.html b/templates/enum-draconic.html index b86b8839..a53391bc 100644 --- a/templates/enum-draconic.html +++ b/templates/enum-draconic.html @@ -1,6 +1,6 @@ {{#each (trier @root.competences) as |competence key|}} {{#if (eq competence.system.categorie 'draconic')}} - + {{/if}} {{/each}}