From d743578f3f566fbe6ececd83fca762eefb9e6e4d Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Mon, 29 Mar 2021 09:17:00 +0200 Subject: [PATCH 01/10] Methode getItemOfType, Misc.data pour Item MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Passer par Misc.data/Misc.templateData pour les Item - Méthode getObjet pour obtenir un objet par id - Simplification du code sur les conteneurs On peut sortir un objet d'un conteneur # Conflicts: # module/actor.js --- module/actor.js | 206 ++++++++++++++++++++++++------------------ module/item-sheet.js | 2 +- module/rdd-combat.js | 6 +- module/rdd-utility.js | 35 ++++--- 4 files changed, 143 insertions(+), 106 deletions(-) diff --git a/module/actor.js b/module/actor.js index 9051a483..06dd5956 100644 --- a/module/actor.js +++ b/module/actor.js @@ -236,29 +236,35 @@ export class RdDActor extends Actor { return RdDItemCompetence.findCompetence(this.data.items, name); } /* -------------------------------------------- */ + getObjet(id) { + return id ? this.items.find(it => it._id == id) : undefined; + } + getItemOfType(type, id) { + return id ? this.data.items.find(it => it._id == id && it.type == type) : undefined; + } getTache(id) { - return this.data.items.find(item => item.type == 'tache' && item._id == id); + return this.getItemOfType(id, 'tache'); } getMeditation(id) { - return this.data.items.find(item => item.type == 'meditation' && item._id == id); + return this.getItemOfType(id, 'meditation'); } getChant(id) { - return this.data.items.find(item => item.type == 'chant' && item._id == id); + return this.getItemOfType(id, 'chant'); } getDanse(id) { - return this.data.items.find(item => item.type == 'danse' && item._id == id); + return this.getItemOfType(id, 'danse'); } getMusique(id) { - return this.data.items.find(item => item.type == 'musique' && item._id == id); + return this.getItemOfType(id, 'musique'); } getOeuvre(id, type = 'oeuvre') { - return this.data.items.find(item => item.type == type && item._id == id); + return this.getItemOfType(type, id); } getJeu(id) { - return this.data.items.find(item => item.type == 'jeu' && item._id == id); + return this.getItemOfType(id, 'jeu'); } getRecetteCuisine(id) { - return this.data.items.find(item => item.type == 'recettecuisine' && item._id == id); + return this.getItemOfType(id, 'recettecuisine'); } /* -------------------------------------------- */ getBestDraconic() { @@ -271,6 +277,7 @@ export class RdDActor extends Actor { getDemiReve() { return Misc.templateData(this).reve.tmrpos.coord; } + /* -------------------------------------------- */ async deleteSortReserve(sortReserve) { let reserve = duplicate(Misc.templateData(this).reve.reserve); @@ -768,42 +775,55 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ validateConteneur(itemId, conteneurId) { - let conteneurDest = this.items.find(conteneur => conteneurId == conteneur.id); // recup conteneur - let conteneurSrc = this.items.find(conteneur => itemId == conteneur.id && conteneur.type == 'conteneur'); - if (conteneurSrc) { // Si c'est un conteneur, il faut vérifier qu'on ne le déplace pas vers un sous-conteneur lui appartenant - for (let id of conteneurSrc.data.data.contenu) { - let subObjet = this.items.find(subobj => id == subobj.id); - if (subObjet && subObjet.id == conteneurDest.id) { - ui.notifications.warn("Impossible de déplacer un conteneur parent dans son fils !"); - return false; // Loop detected ! - } - if (subObjet && subObjet.type == 'conteneur') { - return this.validateConteneur(subObjet.id, conteneurId); - } - } + const dest = this.getObjet(conteneurId); + if (dest?.type != 'conteneur') { + ui.notifications.warn(`Impossible de déplacer un objet (${item.name}) vers un ${dest.type} qui n'est pas un conteneur (${dest.name}) !`); + return false; + } + const item = this.getObjet(itemId); + if (this._isConteneurContenu(item, conteneurId)) { + ui.notifications.warn(`Impossible de déplacer un conteneur parent (${item.name}) dans un de ses contenus ${dest.name} !`); + return false; // Loop detected ! } return true; } - /* -------------------------------------------- */ - getRecursiveEnc(objet) { - let sumEnc = 0; - if (objet.type == 'conteneur') { - for (let id of objet.data.data.contenu) { - let subobjet = this.items.find(objet => (id == objet.id)); - if (subobjet) { - if (subobjet && subobjet.type == 'conteneur') { - sumEnc += this.getRecursiveEnc(subobjet); - } else { - sumEnc += Number(subobjet.data.data.encombrement) * Number(subobjet.data.data.quantite); - } + _isConteneurContenu(item, conteneurId) { + if (item?.type == 'conteneur') { // Si c'est un conteneur, il faut vérifier qu'on ne le déplace pas vers un sous-conteneur lui appartenant + for (let id of Misc.templateData(item).contenu) { + let subObjet = this.getObjet(id); + if (subObjet?.id == conteneurId) { + return true; // Loop detected ! + } + if (subObjet?.type == 'conteneur') { + return this._isConteneurContenu(subObjet, conteneurId); } } - sumEnc += Number(objet.data.data.encombrement) - } else { - sumEnc += Number(objet.data.data.encombrement) * Number(objet.data.data.quantite); } - return sumEnc; + return false; + } + + /* -------------------------------------------- */ + getRecursiveEnc(objet) { + if (!objet) { + return 0; + } + const tplData = Misc.templateData(objet); + if (objet.type != 'conteneur') { + return Number(tplData.encombrement) * Number(tplData.quantite); + } + const encContenus = tplData.contenu.map(idContenu => this.getRecursiveEnc(this.getObjet(idContenu))); + return encContenus.reduce((a, b) => a + b, 0) + + Number(tplData.encombrement) /* TODO? Number(tplData.quantite) -- on pourrait avoir plusieurs conteneurs...*/ + } + + /* -------------------------------------------- */ + isConteneurSuffisant(itemId, conteneurId) { + if ( !conteneurId){ + // on peut toujours vider son sac + return true; + } + return this.validateConteneur(itemId, conteneurId) && this.testConteneurCapacite(itemId, conteneurId); } /* -------------------------------------------- */ @@ -811,34 +831,39 @@ export class RdDActor extends Actor { * pour recevoir le nouvel objet */ testConteneurCapacite(itemId, conteneurId) { - if (!conteneurId) return true; // pas de conteneur (porté sur soi), donc toujours OK. - let conteneur = this.items.find(conteneur => conteneurId == conteneur.id); // recup conteneur + let conteneur = this.getObjet(conteneurId); // recup conteneur (ou undefined) //console.log("Conteneur trouvé : ", conteneur); - if (conteneur && conteneur.type == "conteneur") { - // Calculer le total actuel des contenus - let encContenu = this.getRecursiveEnc(conteneur) - Number(conteneur.data.data.encombrement); - let nouvelObjet = this.items.find(objet => (itemId == objet.id)); // On chope l'objet - let newEnc = (nouvelObjet) ? this.getRecursiveEnc(nouvelObjet) : 0; // Calculer le total actuel du nouvel objet - //console.log( currentEnc, newEnc, conteneur.data.data.capacite, conteneur.name); - if (nouvelObjet && ((encContenu + newEnc) > Number(conteneur.data.data.capacite))) { - ui.notifications.warn("Capacité d'encombrement insuffisante dans le conteneur !"); - return false; - } + if (conteneur?.type != "conteneur") { + return true; + } + + const tplConteneur = Misc.templateData(conteneur); + // Calculer le total actuel des contenus + let encContenu = this.getRecursiveEnc(conteneur) - Number(tplConteneur.encombrement); + let nouvelObjet = this.getObjet(itemId); + let newEnc = this.getRecursiveEnc(nouvelObjet); // Calculer le total actuel du nouvel objet + //console.log( currentEnc, newEnc, tplConteneur.capacite, conteneur.name); + if (nouvelObjet && ((encContenu + newEnc) > Number(tplConteneur.capacite))) { + ui.notifications.warn( + `Le conteneur ${conteneur.name} a une capacité de ${tplConteneur.capacite}, et contient déjà ${encContenu}. + Impossible d'y ranger: ${nouvelObjet.name} d'encombrement ${newEnc}!`); + return false; } return true; } /* -------------------------------------------- */ buildSubConteneurObjetList(conteneurId, deleteList) { - let conteneur = this.items.find(conteneur => conteneurId == conteneur._id); // recup conteneur - if (conteneur && conteneur.type == 'conteneur') { // Si présent - for (let subId of conteneur.data.data.contenu) { - let subObj = this.items.find(subobjet => subId == subobjet._id); // recup conteneur - if (subObj && subObj.type == 'conteneur') { - this.buildSubConteneurObjetList(subId, deleteList); - } - if (subObj) // Robust... + let conteneur = this.getObjet(conteneurId); + if (conteneur?.type == 'conteneur') { // Si c'est un conteneur + for (let subId of Misc.templateData(conteneur).contenu) { + let subObj = this.getObjet(subId); + if (subObj) { + if (subObj.type == 'conteneur') { + this.buildSubConteneurObjetList(subId, deleteList); + } deleteList.push({ id: subId, conteneurId: conteneurId }); + } } } } @@ -858,11 +883,10 @@ export class RdDActor extends Actor { /** Supprime un item d'un conteneur, sur la base * de leurs ID */ async enleverDeConteneur(itemId, conteneurId) { - if (!conteneurId) return; // pas de conteneur (porté sur soi) - let conteneur = this.items.find(conteneur => conteneurId == conteneur.id); // recup conteneur - if (conteneur) { // Si présent - let data2use = duplicate(conteneur.data); - //console.log("Suppression du conteneur1", conteneurId, itemId, conteneur.data.data.contenu); + let conteneur = this.getObjet(conteneurId); + if (conteneur?.type == 'conteneur') { // Si présent + let data2use = duplicate(Misc.data(conteneur)); + //console.log("Suppression du conteneur1", conteneurId, itemId, data2use.data.contenu); let contenu = data2use.data.contenu; let index = contenu.indexOf(itemId); while (index >= 0) { // Force cleanup, itemId is unique @@ -877,10 +901,9 @@ export class RdDActor extends Actor { /** Ajoute un item dans un conteneur, sur la base * de leurs ID */ async ajouterAConteneur(itemId, conteneurId) { - if (!conteneurId) return; // pas de conteneur (porté sur soi) - let conteneur = this.items.find(conteneur => conteneurId == conteneur.id); - if (conteneur && conteneur.data.type == 'conteneur') { - let data2use = duplicate(conteneur.data); + let conteneur = this.getObjet(conteneurId); + if (conteneur?.type == 'conteneur') { + let data2use = duplicate(Misc.data(conteneur)); data2use.data.contenu.push(itemId); await this.updateEmbeddedEntity("OwnedItem", data2use); } @@ -889,10 +912,10 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ /** Fonction de remise à plat de l'équipement (ie vide les champs 'contenu') */ async nettoyerConteneurs() { - let conteneurList = this.items.filter(conteneur => conteneur.type == 'conteneur'); + let conteneurs = this.items.filter(it => it.type == 'conteneur'); let conteneurFixedList = []; - for (let conteneur of conteneurList) { - if (conteneur.data.data.contenu.length > 0) { + for (let conteneur of conteneurs) { + if (Misc.templateData(conteneur).contenu.length > 0) { conteneurFixedList.push({ _id: conteneur._id, 'data.contenu': [] }); } } @@ -1051,7 +1074,7 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async ajouterRefoulement(value = 1) { let refoulement = Misc.templateData(this).reve.refoulement.value + value; - let total = new Roll("1d20").evaluate( {async: false}).total; + let total = new Roll("1d20").evaluate({ async: false }).total; if (total <= refoulement) { refoulement = 0; await this.ajouterSouffle({ chat: true }); @@ -2127,7 +2150,7 @@ export class RdDActor extends Actor { async rollDanse(id) { const actorData = Misc.data(this); const artData = { art: 'danse', verbe: 'Danser', forceCarac: {} }; - const oeuvre = duplicate(this.getOeuvre(id, artData.art)); + const oeuvre = duplicate(this.getItemOfType(id, artData.art)); const selectedCarac = this._getCaracDanse(oeuvre); if (oeuvre.data.agilite) { artData.forceCarac['agilite'] = duplicate(actorData.data.carac.agilite); @@ -2149,7 +2172,7 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async rollMusique(id) { const artData = { art: 'musique', verbe: 'Jouer' }; - const oeuvre = duplicate(this.getOeuvre(id, artData.art)); + const oeuvre = duplicate(this.getItemOfType(id, artData.art)); await this._rollArt(artData, "ouie", oeuvre); } @@ -2181,7 +2204,7 @@ export class RdDActor extends Actor { async rollOeuvre(id) { const artData = { art: 'oeuvre', verbe: 'Interpréter' }; - const oeuvre = duplicate(this.getOeuvre(id)); + const oeuvre = duplicate(this.getItemOfType(id, artData.art)); await this._rollArt(artData, oeuvre.data.default_carac, oeuvre); } @@ -2799,14 +2822,13 @@ export class RdDActor extends Actor { || entite.isEntiteCauchemarAccordee(this)) { return true; } - - let rolled = await RdDResolutionTable.roll(this.getReveActuel(), - Number(entite.data.data.carac.niveau.value)); - const actorData = Misc.data(this); + const tplData = Misc.templateData(this); + let rolled = await RdDResolutionTable.roll(this.getReveActuel(), - Number(tplData.carac.niveau.value)); const rollData = { alias: this.name, rolled: rolled, entite: entite.name, - selectedCarac: actorData.data.carac.reve + selectedCarac: tplData.carac.reve }; if (rolled.isSuccess) { @@ -2890,7 +2912,7 @@ export class RdDActor extends Actor { if (dataObj) { dataObj.payload.data.cout = sumDenier / 100; // Mise à jour du prix en sols , avec le prix acheté dataObj.payload.data.quantite = quantite; - await this.createEmbeddedDocuments('Item',[dataObj.payload]); + await this.createEmbeddedDocuments('Item', [dataObj.payload]); msg += `
Et l'objet ${dataObj.payload.name} a été ajouté à votre inventaire.`; } } else { @@ -2958,15 +2980,8 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ listeVehicules() { - const actorData = Misc.data(this); - return this._buildActorLinksList( - actorData.data.subacteurs?.vehicules ?? [], - vehicle => { - return { - id: vehicle.id, name: vehicle.data.name, categorie: vehicle.data.data.categorie, - structure: vehicle.data.data.structure, img: vehicle.data.img - }; - }); + const listeVehichules = Misc.templateData(this).subacteurs?.vehicules ?? []; + return this._buildActorLinksList(listeVehichules, vehicle => RdDActor._vehicleData(vehicle)); } /* -------------------------------------------- */ @@ -2979,12 +2994,27 @@ export class RdDActor extends Actor { return this._buildActorLinksList(Misc.templateData(this).subacteurs?.montures ?? []); } - _buildActorLinksList(links, actorTransformation = it => { return { id: it.id, name: it.data.name, img: it.data.img }; }) { + _buildActorLinksList(links, actorTransformation = it => RdDActor._buildActorData(it)) { return links.map(link => game.actors.get(link.id)) .filter(it => it != null) .map(actorTransformation); } + static _vehicleData(vehicle) { + const vehicleData = Misc.data(vehicle); + return { + id: vehicle.id, + name: vehicleData.name, + img: vehicleData.img, + categorie: vehicleData.data.categorie, + structure: vehicleData.data.structure, + }; + } + + static _buildActorData(it) { + return { id: it.id, name: it.data.name, img: it.data.img }; + } + /* -------------------------------------------- */ async pushSubacteur(actor, dataArray, dataPath, dataName) { let alreadyPresent = dataArray.find(attached => attached.id == actor.data._id); diff --git a/module/item-sheet.js b/module/item-sheet.js index 5803f4b6..b8877907 100644 --- a/module/item-sheet.js +++ b/module/item-sheet.js @@ -124,7 +124,7 @@ export class RdDItemSheet extends ItemSheet { event.preventDefault(); let level = RdDItemCompetence.getNiveauBase(event.currentTarget.value); - this.object.data.data.base = level; + Misc.templateData(this.object).base = level; $("#base").val( level ); } diff --git a/module/rdd-combat.js b/module/rdd-combat.js index 79ea86d7..4650e50f 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -968,7 +968,7 @@ export class RdDCombat { surprise: this.defender.getSurprise(true), needParadeSignificative: ReglesOptionelles.isUsing('categorieParade') && RdDItemArme.needParadeSignificative(armeAttaque, armeParade), needResist: RdDItemArme.needArmeResist(armeAttaque, armeParade), - carac: this.defender.data.data.carac, + carac: Misc.templateData(this.defender).carac, show: {} }; defenderRoll.diviseurSignificative = this._getDiviseurSignificative(defenderRoll); @@ -1067,7 +1067,7 @@ export class RdDCombat { competence: competence, surprise: this.defender.getSurprise(true), surpriseDefenseur: this.defender.getSurprise(true), - carac: this.defender.data.data.carac, + carac: Misc.templateData(this.defender).carac, show: {} }; rollData.diviseurSignificative = this._getDiviseurSignificative(rollData); @@ -1252,7 +1252,7 @@ export class RdDCombat { return true; } - let rolled = await RdDResolutionTable.roll(this.attacker.getReveActuel(), - Number(this.defender.data.data.carac.niveau.value)); + let rolled = await RdDResolutionTable.roll(this.attacker.getReveActuel(), - Number(Misc.templateData(this.defender).carac.niveau.value)); let message = { content: "Jet de points actuels de rêve à " + rolled.finalLevel + RdDResolutionTable.explain(rolled) + "
", diff --git a/module/rdd-utility.js b/module/rdd-utility.js index 41f0d635..741662e8 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -256,30 +256,37 @@ export class RdDUtility { .concat(formData.potions) .concat(formData.herbes) .concat(formData.ingredients); - formData.competences = (formData.itemsByType.competence??[]).concat(formData.itemsByType.competencecreature??[]); + formData.competences = (formData.itemsByType.competence ?? []).concat(formData.itemsByType.competencecreature ?? []); } /* -------------------------------------------- */ static async processItemDropEvent(actorSheet, event) { let dragData = JSON.parse(event.dataTransfer.getData("text/plain")); console.log(dragData, actorSheet.actor.id); - let dropID = $(event.target).parents(".item").attr("data-item-id"); // Only relevant if container drop let objetId = dragData.id || dragData.data._id; console.log("DRAG", dragData); if (dragData.type == 'Item') { - if (dropID) { // Dropped over an item !!! - if (actorSheet.objetVersConteneur[objetId] != dropID && objetId != dropID) { - if (actorSheet.actor.validateConteneur(objetId, dropID) && actorSheet.actor.testConteneurCapacite(objetId, dropID)) { - await actorSheet.actor.enleverDeConteneur(objetId, actorSheet.objetVersConteneur[objetId]); - await actorSheet.actor.ajouterAConteneur(objetId, dropID); + if (dragData.actorId) { + if (dragData.actorId != actorSheet.actor.id) { + console.log("Moving objects", dragData); + actorSheet.actor.moveItemsBetweenActors(objetId, dragData.actorId); + return false; + } + else { + // rangement + const destId = $(event.target).parents(".item").attr("data-item-id"); + const srcId = actorSheet.objetVersConteneur[objetId]; + + if (srcId != destId && objetId != destId && actorSheet.actor.isConteneurSuffisant(objetId, destId)) { + if (srcId) { + await actorSheet.actor.enleverDeConteneur(objetId, srcId); + } + if (destId) { // Dropped over an item !!! + await actorSheet.actor.ajouterAConteneur(objetId, destId); + } } } } - if (dragData.actorId && dragData.actorId != actorSheet.actor.id) { // Un acteur est à l'origine de l'item -> deplacement - console.log("Moving objects"); - actorSheet.actor.moveItemsBetweenActors(objetId, dragData.actorId); - return false; - } actorSheet.actor.computeEncombrementTotalEtMalusArmure(); } else if (dragData.type == "Actor") { actorSheet.actor.addSubacteur(objetId); @@ -540,7 +547,7 @@ export class RdDUtility { html.on("click", '#payer-button', event => { let sumdenier = event.currentTarget.attributes['data-somme-denier'].value; let quantite = 1; - if ( event.currentTarget.attributes['data-quantite'] ) { + if (event.currentTarget.attributes['data-quantite']) { quantite = event.currentTarget.attributes['data-quantite'].value; } let jsondata = event.currentTarget.attributes['data-jsondata'] @@ -643,7 +650,7 @@ export class RdDUtility { /* -------------------------------------------- */ static async confirmerSuppression(actorSheet, li) { let itemId = li.data("item-id"); - let objet = actorSheet.actor.items.find(item => item._id == itemId); + let objet = actorSheet.actor.getObjet(itemId); let msgTxt = "

Etes vous certain de vouloir supprimer cet objet ?"; let buttons = { delete: { From 592f54af619aee87dd491bfcb772c23ed9227fbd Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Mon, 29 Mar 2021 14:41:25 +0200 Subject: [PATCH 02/10] Fix: bouton filtrer competences MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le niveau de base était incorrect --- module/item-competence.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/module/item-competence.js b/module/item-competence.js index 3c735cdd..3d99f97c 100644 --- a/module/item-competence.js +++ b/module/item-competence.js @@ -23,14 +23,14 @@ const limitesArchetypes = [ /* -------------------------------------------- */ const categorieCompetences = { - "generale": { level: "-4", label: "Générales" }, - "particuliere": { level: "-8", label: "Particulières" }, - "specialisee": { level: "-11", label: "Spécialisées" }, - "connaissance": { level: "-11", label: "Connaissances" }, - "draconic": { level: "-11", label: "Draconics" }, - "melee": { level: "-6", label: "Mêlée" }, - "tir": { level: "-8", label: "Tir" }, - "lancer": { level: "-8", label: "Lancer" } + "generale": { base: -4, label: "Générales" }, + "particuliere": { base: -8, label: "Particulières" }, + "specialisee": { base: -11, label: "Spécialisées" }, + "connaissance": { base: -11, label: "Connaissances" }, + "draconic": { base: -11, label: "Draconics" }, + "melee": { base: -6, label: "Mêlée" }, + "tir": { base: -8, label: "Tir" }, + "lancer": { base: -8, label: "Lancer" } } const compendiumCompetences = { From 31204cbf515288ff54aa51fc53a1df8c7a56b986 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Mon, 29 Mar 2021 18:08:18 +0200 Subject: [PATCH 03/10] Utilisation Misc.data --- module/actor.js | 97 +++++------- module/item-competence.js | 85 ++++++---- module/item-sheet.js | 13 +- module/misc.js | 22 ++- module/rdd-carac.js | 3 +- module/rdd-combat.js | 16 +- module/rdd-roll.js | 8 +- module/rdd-tmr-dialog.js | 30 ++-- module/rdd-utility.js | 5 +- module/tmr-rencontres.js | 166 ++++++++++---------- module/tmr/urgence-draconique.js | 13 +- templates/actor-sheet.html | 1 - templates/actor-vehicule-sheet.html | 2 +- templates/chat-demande-attaque-etotal.html | 4 +- templates/chat-demande-defense.html | 6 +- templates/chat-resultat-reve-de-dragon.html | 2 +- templates/item-competence-sheet.html | 4 +- templates/item-herbe-sheet.html | 4 +- templates/item-ingredient-sheet.html | 4 +- templates/item-livre-sheet.html | 2 +- templates/item-potion-sheet.html | 4 +- 21 files changed, 254 insertions(+), 237 deletions(-) diff --git a/module/actor.js b/module/actor.js index 06dd5956..98a714a7 100644 --- a/module/actor.js +++ b/module/actor.js @@ -240,8 +240,12 @@ export class RdDActor extends Actor { return id ? this.items.find(it => it._id == id) : undefined; } getItemOfType(type, id) { - return id ? this.data.items.find(it => it._id == id && it.type == type) : undefined; + return id ? this.items.find(it => it._id == id && it.type == type) : undefined; } + getMonnaie(id) { + return this.getItemOfType(id, 'monnaie'); + } + getTache(id) { return this.getItemOfType(id, 'tache'); } @@ -267,8 +271,12 @@ export class RdDActor extends Actor { return this.getItemOfType(id, 'recettecuisine'); } /* -------------------------------------------- */ + getDraconicList() { + return this.items.filter(it => Misc.data(it).type == 'competence' && Misc.templateData(it).categorie == 'draconic') + } + /* -------------------------------------------- */ getBestDraconic() { - const list = this.getDraconicList().sort((a, b) => b.data.data.niveau - a.data.data.niveau); + const list = this.getDraconicList().sort(Misc.descending(it => Misc.templateData(it).niveau)); if (list.length == 0) { return { name: "Aucun", data: { name: "Aucun", data: { niveau: -11 } } }; } @@ -296,7 +304,7 @@ export class RdDActor extends Actor { getSurprise(isCombat = undefined) { let niveauSurprise = Array.from(this.effects?.values() ?? []) .map(effect => StatusEffects.valeurSurprise(effect.data, isCombat)) - .reduce((a, b) => a + b, 0); + .reduce(Misc.sum(), 0); if (niveauSurprise > 1) { return 'totale'; } @@ -600,10 +608,10 @@ export class RdDActor extends Actor { async resultCombatReveDeDragon(rollData) { rollData.queues = []; if (rollData.rolled.isEchec) { - rollData.queues.push(await this.ajouterQueue()); + rollData.queues.push(Misc.data(await this.ajouterQueue())); } if (rollData.rolled.isETotal) { - rollData.queues.push(await this.ajouterQueue()); + rollData.queues.push(Misc.data(await this.ajouterQueue())); } if (rollData.rolled.isSuccess) { await this.updatePointDeSeuil(); @@ -621,31 +629,6 @@ export class RdDActor extends Actor { }); } - /* -------------------------------------------- */ - async appliquerReveDeDragon(roll, force) { - let message = ""; - if (roll.isSuccess) { - message += "
Vous gagnez " + force + " points de Rêve"; - await this.updatePointDeSeuil(); - await this.reveActuelIncDec(force); - } - if (roll.isPart) { - // TODO: Dialog pour choix entre HR opu général? - message += "
Vous gagnez une Tête de dragon: Demander à votre MJ d'effectuer un tirage sur la table des Hauts Rêvants ou des Vrais Rêvants, selon votre choix."; - } - if (roll.isEchec) { - message += "
Vous subissez une Queue de Dragon: " + await this.ajouterQueue(); - } - if (roll.isETotal) { - message += "
A cause de votre échec total, vous subissez une deuxième Queue de Dragon: " + await this.ajouterQueue(); - } - ChatMessage.create({ - whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), - content: message - }); - - } - /* -------------------------------------------- */ async sortMisEnReserve(rollData, sort) { let reserve = duplicate(Misc.templateData(this).reve.reserve.list); @@ -690,7 +673,7 @@ export class RdDActor extends Actor { let comp = this.getCompetence(compName); //console.log(comp); if (comp) { - const update = { _id: comp._id } + const update = { _id: comp.id } if (fieldName == "niveau") update['data.niveau'] = compValue; else if (fieldName == "dommages") @@ -718,7 +701,7 @@ export class RdDActor extends Actor { content: message }); } - const update = { _id: comp._id, 'data.niveau': nouveauNiveau }; + const update = { _id: comp.id, 'data.niveau': nouveauNiveau }; await this.updateEmbeddedEntity("Item", update); // Updates one EmbeddedEntity } else { console.log("Competence not found", compName); @@ -731,7 +714,7 @@ export class RdDActor extends Actor { if (comp) { compValue = compValue ?? 0; this.checkCompetenceXP(compName, compValue); - const update = { _id: comp._id, 'data.xp': compValue }; + const update = { _id: comp.id, 'data.xp': compValue }; await this.updateEmbeddedEntity("OwnedItem", update); // Updates one EmbeddedEntity } else { console.log("Competence not found", compName); @@ -744,7 +727,7 @@ export class RdDActor extends Actor { let comp = this.getCompetence(compName); if (comp) { compValue = compValue ?? 0; - const update = { _id: comp._id, 'data.xp_sort': compValue }; + const update = { _id: comp.id, 'data.xp_sort': compValue }; await this.updateEmbeddedEntity("OwnedItem", update); // Updates one EmbeddedEntity } else { console.log("Competence not found", compName); @@ -756,7 +739,7 @@ export class RdDActor extends Actor { let comp = this.getCompetence(compName); if (comp) { compValue = compValue ?? 0; - const update = { _id: comp._id, 'data.niveau_archetype': compValue }; + const update = { _id: comp.id, 'data.niveau_archetype': compValue }; await this.updateEmbeddedEntity("OwnedItem", update); // Updates one EmbeddedEntity } else { console.log("Competence not found", compName); @@ -813,13 +796,13 @@ export class RdDActor extends Actor { return Number(tplData.encombrement) * Number(tplData.quantite); } const encContenus = tplData.contenu.map(idContenu => this.getRecursiveEnc(this.getObjet(idContenu))); - return encContenus.reduce((a, b) => a + b, 0) + return encContenus.reduce(Misc.sum(), 0) + Number(tplData.encombrement) /* TODO? Number(tplData.quantite) -- on pourrait avoir plusieurs conteneurs...*/ } /* -------------------------------------------- */ isConteneurSuffisant(itemId, conteneurId) { - if ( !conteneurId){ + if (!conteneurId) { // on peut toujours vider son sac return true; } @@ -1099,7 +1082,7 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async ajouterQueue(options = { chat: false }) { let queue; - if (Misc.templateData(this).reve.reve.thanatosused) { + if (Misc.data(this).data.reve.reve.thanatosused) { queue = await RdDRollTables.getOmbre(); await this.update({ "data.reve.reve.thanatosused": false }); } @@ -1766,15 +1749,16 @@ export class RdDActor extends Actor { let draconicList = this.getDraconicList(); let bestDraconic = this.getBestDraconic(); for (let sort of sortList) { - let voie = sort.data.draconic.toLowerCase(); - let draconic = draconicList.find(it => it.data.data.categorie == 'draconic' && it.data.name.toLowerCase().includes(voie)); + let voie = sort.data.draconic; + let draconic = RdDItemCompetence.getVoieDraconic(draconicList, voie); //console.log(draconicList, bestDraconic, draconic, voie); if (sort.name.toLowerCase().includes('aura')) { draconic = bestDraconic; } - draconic = duplicate(draconic); + // TODO: duplicate sur Misc.data? + draconic = duplicate(Misc.data(draconic)); if (draconicDone[draconic.name] == undefined) { - draconic.data.data.defaut_carac = 'reve'; + draconic.data.defaut_carac = 'reve'; newDraconicList.push(draconic); draconicDone[draconic.name] = newDraconicList.length - 1; // Patch local pour relier facilement voie/compétence } @@ -1811,7 +1795,7 @@ export class RdDActor extends Actor { competence: draconicList[0], selectedSort: sortList[0], tmr: TMRUtility.getTMR(coord), - diffLibre: sortList[0].data.difficulte, // Per default at startup + diffLibre: RdDItemSort.getDifficulte(sortList[0], -7), // Per default at startup coutreve: Array(30).fill().map((item, index) => 1 + index), carac: { 'reve': duplicate(actorData.data.carac.reve) } } @@ -2054,23 +2038,25 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async rollTache(id) { - let tache = duplicate(this.getTache(id)); - let competence = this.getCompetence(tache.data.competence); - competence.data.data.defaut_carac = tache.data.carac; // Patch ! + const actorData = Misc.data(this); + const tacheData = Misc.data(this.getTache(id)); + const compData = duplicate(Misc.data(this.getCompetence(tacheData.data.competence))); + compData.data.defaut_carac = tacheData.data.carac; // Patch ! + let rollData = { - competence: competence, - tache: tache, - diffConditions: tache.data.difficulte, + competence: compData, + tache: tacheData, + diffConditions: tacheData.data.difficulte, use: { libre: false, conditions: false }, carac: {} }; - rollData.carac[tache.data.carac] = duplicate(Misc.templateData(this).carac[tache.data.carac]); // Single carac + rollData.carac[tacheData.data.carac] = duplicate(actorData.data.carac[tacheData.data.carac]); // Single carac console.log("rollTache !!!", rollData); const dialog = await RdDRoll.create(this, rollData, { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-competence.html' }, { name: 'jet-competence', - label: 'Jet de Tâche ' + tache.name, + label: 'Jet de Tâche ' + tacheData.name, callbacks: [ this.createCallbackExperience(), this.createCallbackAppelAuMoral(), @@ -2465,11 +2451,6 @@ export class RdDActor extends Actor { return this.data.items.filter(it => it.data.type == "sort"); } - /* -------------------------------------------- */ - getDraconicList() { - return this.data.items.filter(it => it.data.data.categorie == 'draconic') - } - /* -------------------------------------------- */ countMonteeLaborieuse() { // Return +1 par queue/ombre/souffle Montée Laborieuse présente let countMonteeLaborieuse = this.data.items.filter(it => EffetsDraconiques.isMonteeLaborieuse(it)).length; @@ -2928,9 +2909,9 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async monnaieIncDec(id, value) { - let monnaie = this.data.items.find(item => item.type == 'monnaie' && item.id == id); + let monnaie = this.getMonnaie(id); if (monnaie) { - const quantite = Math.max(0, monnaie.data.data.quantite + value); + const quantite = Math.max(0, Misc.templateData(monnaie).quantite + value); await this.updateEmbeddedEntity("OwnedItem", { _id: monnaie.id, 'data.quantite': quantite }); } } diff --git a/module/item-competence.js b/module/item-competence.js index 3d99f97c..85d38ef6 100644 --- a/module/item-competence.js +++ b/module/item-competence.js @@ -1,10 +1,11 @@ import { Grammar } from "./grammar.js"; +import { Misc } from "./misc.js"; const competenceTroncs = [["Esquive", "Dague", "Corps à corps"], ["Epée à 1 main", "Epée à 2 mains", "Hache à 1 main", "Hache à 2 mains", "Lance", "Masse à 1 main", "Masse à 2 mains"]]; -const competence_xp_par_niveau = [5, 5, 5, 10, 10, 10, 10, 15, 15, 15, 15, 20, 20, 20, 20, 30, 30, 40, 40, 60, 60, 100, 100, 100, 100, 100, 100, 100, 100, 100]; -const competence_niveau_max = competence_xp_par_niveau.length - 10; +const xp_par_niveau = [5, 5, 5, 10, 10, 10, 10, 15, 15, 15, 15, 20, 20, 20, 20, 30, 30, 40, 40, 60, 60, 100, 100, 100, 100, 100, 100, 100, 100, 100]; +const niveau_max = xp_par_niveau.length - 10; /* -------------------------------------------- */ const limitesArchetypes = [ { "niveau": 0, "nombreMax": 100, "nombre": 0 }, @@ -43,9 +44,9 @@ const compendiumCompetences = { function _buildCumulXP() { let cumulXP = { "-11": 0 }; let cumul = 0; - for (let i = 0; i <= competence_xp_par_niveau.length; i++) { + for (let i = 0; i <= xp_par_niveau.length; i++) { let level = i - 10; - cumul += competence_xp_par_niveau[i]; + cumul += xp_par_niveau[i]; cumulXP[level] = cumul; } return cumulXP; @@ -73,6 +74,20 @@ export class RdDItemCompetence extends Item { return categorieCompetences[category].label; } + /* -------------------------------------------- */ + static getCategorie(competence) { + return Misc.data(competence)?.data.categorie; + } + static isDraconic(competence) { + return Misc.data(competence).data.categorie == 'draconic'; + } + + /* -------------------------------------------- */ + static getVoieDraconic(competences, voie) { + voie = Grammar.toLowerCaseNoAccent(voie); + return competences.find(it => RdDItemCompetence.isDraconic(it) && Grammar.toLowerCaseNoAccent(Misc.data(it).name).includes(voie)); + } + /* -------------------------------------------- */ static getEsquive(competences) { return { name: 'Esquive', niveau: RdDItemCompetence.findCompetence(competences, 'Esquive')?.data.niveau ?? -6 }; @@ -80,9 +95,9 @@ export class RdDItemCompetence extends Item { /* -------------------------------------------- */ static isCompetenceArme(competence) { - switch (competence.data.data.categorie) { + switch (Misc.templateData(competence).categorie) { case 'melee': - return competence.data.name != 'Esquive'; + return Misc.data(competence).name != 'Esquive'; case 'tir': case 'lancer': return true; @@ -92,15 +107,15 @@ export class RdDItemCompetence extends Item { /* -------------------------------------------- */ static isArmeUneMain(competence) { - return competence?.name.toLowerCase().includes("1 main"); + return Misc.data(competence)?.name.toLowerCase().includes("1 main"); } static isArme2Main(competence) { - return competence?.name.toLowerCase().includes("2 main"); + return Misc.data(competence)?.name.toLowerCase().includes("2 main"); } /* -------------------------------------------- */ static isMalusEncombrementTotal(competence) { - return competence?.name.toLowerCase().match(/(natation|acrobatie)/); + return Misc.data(competence)?.name.toLowerCase().match(/(natation|acrobatie)/); } /* -------------------------------------------- */ @@ -117,17 +132,18 @@ export class RdDItemCompetence extends Item { /* -------------------------------------------- */ static computeTotalXP(competences) { const total = competences.map(c => RdDItemCompetence.computeXP(c)) - .reduce((a, b) => a + b, 0); + .reduce(Misc.sum(), 0); const economieTronc = RdDItemCompetence.computeEconomieXPTronc(competences); return total - economieTronc; } /* -------------------------------------------- */ static computeXP(competence) { - const factor = competence.name.includes('Thanatos') ? 2 : 1; // Thanatos compte double ! - const xpNiveau = RdDItemCompetence.computeDeltaXP(competence.data.base, competence.data.niveau ?? competence.data.base); - const xp = competence.data.xp ?? 0; - const xpSort = competence.data.xp_sort ?? 0; + const itemData = Misc.data(competence); + const factor = itemData.name.includes('Thanatos') ? 2 : 1; // Thanatos compte double ! + const xpNiveau = RdDItemCompetence.computeDeltaXP(itemData.data.base, itemData.data.niveau ?? itemData.data.base); + const xp = itemData.data.xp ?? 0; + const xpSort = itemData.data.xp_sort ?? 0; return factor * (xpNiveau + xp) + xpSort; } @@ -137,10 +153,10 @@ export class RdDItemCompetence extends Item { list => list.map(name => RdDItemCompetence.findCompetence(competences, name)) // calcul du coût xp jusqu'au niveau 0 maximum .map(it => RdDItemCompetence.computeDeltaXP(it?.data.base ?? -11, Math.min(it?.data.niveau ?? -11, 0))) - .sort((a, b) => b - a) // tri descendant + .sort(Misc.descending(x => x)) .splice(0, 1) // ignorer le coût xp le plus élevé - .reduce((a, b) => a + b, 0) - ).reduce((a, b) => a + b, 0); + .reduce(Misc.sum(), 0) + ).reduce(Misc.sum(), 0); } /* -------------------------------------------- */ @@ -153,10 +169,11 @@ export class RdDItemCompetence extends Item { /* -------------------------------------------- */ static computeCompetenceXPCost(competence) { - let xp = RdDItemCompetence.getDeltaXp(competence.data.base, competence.data.niveau ?? competence.data.base); - xp += competence.data.xp ?? 0; - if (competence.name.includes('Thanatos')) xp *= 2; /// Thanatos compte double ! - xp += competence.data.xp_sort ?? 0; + const compData = Misc.data(competence); + let xp = RdDItemCompetence.getDeltaXp(compData.data.base, compData.data.niveau ?? compData.data.base); + xp += compData.data.xp ?? 0; + if (compData.name.includes('Thanatos')) xp *= 2; /// Thanatos compte double ! + xp += compData.data.xp_sort ?? 0; return xp; } @@ -165,10 +182,10 @@ export class RdDItemCompetence extends Item { let economie = 0; for (let troncList of competenceTroncs) { let list = troncList.map(name => RdDItemCompetence.findCompetence(competences, name)) - .sort((c1, c2) => c2.data.niveau - c1.data.niveau); // tri du plus haut au plus bas + .sort(Misc.descending(c => Misc.templateData(c).niveau)); // tri du plus haut au plus bas list.splice(0, 1); // ignorer la plus élevée - list.forEach(c => { - economie += RdDItemCompetence.getDeltaXp(c.data.base, Math.min(c.data.niveau, 0)); + list.map(c => Misc.templateData(c)).forEach(tplData => { + economie += RdDItemCompetence.getDeltaXp(tplData.base, Math.min(tplData.niveau, 0)); }); } return economie; @@ -192,7 +209,7 @@ export class RdDItemCompetence extends Item { /* -------------------------------------------- */ static findCompetence(list, name) { - name = Grammar.toLowerCaseNoAccent(name); + name = Grammar.toLowerCaseNoAccent(name); const competences = list.filter(it => Grammar.toLowerCaseNoAccent(it.name).includes(name) && (it.type == "competence" || it.type == "competencecreature")); if (competences.length == 0) { return undefined; @@ -200,7 +217,7 @@ export class RdDItemCompetence extends Item { let competence = competences.find(it => Grammar.toLowerCaseNoAccent(it.name) == name); if (!competence) { competence = competences[0]; - if (competences.length>1) { + if (competences.length > 1) { const names = competences.map(it => it.name).reduce((a, b) => `${a}
${b}`); ui.notifications.info(`Plusieurs compétences possibles:
${names}
La première sera choisie: ${competence.name}`); } @@ -216,7 +233,7 @@ export class RdDItemCompetence extends Item { /* -------------------------------------------- */ static getCompetenceXp(niveau) { RdDItemCompetence._valideNiveau(niveau); - return niveau < -10 ? 0 : competence_xp_par_niveau[niveau + 10]; + return niveau < -10 ? 0 : xp_par_niveau[niveau + 10]; } /* -------------------------------------------- */ @@ -228,19 +245,19 @@ export class RdDItemCompetence extends Item { /* -------------------------------------------- */ static _valideNiveau(niveau) { - if (niveau < -11 || niveau > competence_niveau_max) { - console.warn(`Niveau ${niveau} en dehors des niveaux de compétences: [-11, ${competence_niveau_max} ]`); + if (niveau < -11 || niveau > niveau_max) { + console.warn(`Niveau ${niveau} en dehors des niveaux de compétences: [-11, ${niveau_max} ]`); } } /* -------------------------------------------- */ static computeResumeArchetype(competences) { const archetype = RdDItemCompetence.getLimitesArchetypes(); - competences.forEach(it => { - let niveau = Math.max(0, it.data.niveau_archetype); - archetype[niveau] = archetype[niveau] ?? { "niveau": niveau, "nombreMax": 0, "nombre": 0 }; - archetype[niveau].nombre = (archetype[niveau]?.nombre ?? 0) + 1; - }); + competences.map(it => Math.max(0, Misc.templateData(it).niveau_archetype)) + .forEach(niveau => { + archetype[niveau] = archetype[niveau] ?? { "niveau": niveau, "nombreMax": 0, "nombre": 0 }; + archetype[niveau].nombre = (archetype[niveau]?.nombre ?? 0) + 1; + }); return archetype; } diff --git a/module/item-sheet.js b/module/item-sheet.js index b8877907..229df96a 100644 --- a/module/item-sheet.js +++ b/module/item-sheet.js @@ -52,13 +52,16 @@ export class RdDItemSheet extends ItemSheet { console.log("3", objectData); let formData ={ - title: this.title, + title: objectData.name, id: objectData.id, type: objectData.type, img: objectData.img, name: objectData.name, data: objectData.data, - isGM: game.user.isGM + isGM: game.user.isGM, + owner: this.document.isOwner, + editable: this.isEditable, + cssClass: this.isEditable ? "editable" : "locked", } formData.categorieCompetences = RdDItemCompetence.getCategorieCompetences(); if ( formData.type == 'tache' || formData.type == 'livre' || formData.type == 'meditation' || formData.type == 'oeuvre') { @@ -90,15 +93,15 @@ export class RdDItemSheet extends ItemSheet { if (!this.options.editable) return; // Select competence categorie - html.find("#categorie").on("click", this._onClickSelectCategorie.bind(this) ); + html.find(".categorie").on("click", this._onClickSelectCategorie.bind(this) ); - html.find('#sheet-competence-xp').change((event) => { + html.find('.sheet-competence-xp').change((event) => { if ( this.object.data.type == 'competence') { RdDUtility.checkThanatosXP( this.object.data.name ); } } ); - html.find('#creer-tache-livre').click((event) => { + html.find('.creer-tache-livre').click((event) => { let actorId = event.currentTarget.attributes['data-actor-id'].value; let actor = game.actors.get( actorId ); actor.creerTacheDepuisLivre( this.item ); diff --git a/module/misc.js b/module/misc.js index d14e841e..d1f5eb9a 100644 --- a/module/misc.js +++ b/module/misc.js @@ -18,6 +18,24 @@ export class Misc { return isPositiveNumber ? "+" + number : number } + static sum() { + return (a, b) => a + b; + } + + static ascending(orderFunction) { + return (a, b) => Misc.sortingBy(orderFunction(a), orderFunction(b)); + } + + static descending(orderFunction) { + return (a, b) => Misc.sortingBy(orderFunction(b), orderFunction(a)); + } + + static sortingBy(a, b) { + if (a > b) return 1; + if (a < b) return -1; + return 0; + } + /** * Converts the value to an integer, or to 0 if undefined/null/not representing integer * @param {*} value value to convert to an integer using parseInt @@ -55,7 +73,7 @@ export class Misc { } return itemsBy; } - + static classifyInto(itemsBy, items, classifier = it => it.type, transform = it => it) { for (const item of items) { const classification = classifier(item); @@ -72,7 +90,7 @@ export class Misc { } static rollOneOf(array) { - return array[new Roll("1d" + array.length).evaluate( { async: false} ).total - 1]; + return array[new Roll("1d" + array.length).evaluate({ async: false }).total - 1]; } static distinct(array) { diff --git a/module/rdd-carac.js b/module/rdd-carac.js index 6dbe169c..e97c83ea 100644 --- a/module/rdd-carac.js +++ b/module/rdd-carac.js @@ -1,4 +1,5 @@ import { Grammar } from "./grammar.js"; +import { Misc } from "./misc.js"; const tableCaracDerivee = { // xp: coût pour passer du niveau inférieur à ce niveau @@ -61,7 +62,7 @@ export class RdDCarac { static computeTotal(carac, beaute = undefined) { const total = Object.values(carac).filter(c => !c.derivee) .map(it => parseInt(it.value)) - .reduce((a, b) => a + b, 0); + .reduce(Misc.sum(), 0); const beauteSuperieur10 = Math.max((beaute ?? 10) - 10, 0); return total + beauteSuperieur10; } diff --git a/module/rdd-combat.js b/module/rdd-combat.js index 4650e50f..c4450cdf 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -165,13 +165,7 @@ export class RdDCombatManager extends Combat { } } } - return armesEquipe.sort((a, b) => { - const nameA = a.name + (a.data.mainInfo ?? ''); - const nameB = b.name + (b.data.mainInfo ?? ''); - if (nameA > nameB) return 1; - if (nameA < nameB) return -1; - return 0; - }); + return armesEquipe.sort(Misc.ascending(armeData => armeData.name + (armeData.data.mainInfo ?? ''))); } /* -------------------------------------------- */ @@ -808,8 +802,8 @@ export class RdDCombat { const paramChatDefense = { passeArme: attackerRoll.passeArme, essais: attackerRoll.essais, - defender: this.defender, - attacker: this.attacker, + defender: Misc.data(this.defender), + attacker: Misc.data(this.attacker), attackerId: this.attackerId, esquiveUsage: esquiveUsage, defenderTokenId: this.defenderTokenId, @@ -851,7 +845,7 @@ export class RdDCombat { attackerId: this.attacker?.data._id, defenderId: this.defender?.data._id, defenderTokenId: this.defenderTokenId, - defenderRoll: duplicate(defenderRoll), + defenderRoll: defenderRoll, paramChatDefense: paramChatDefense, rollMode: true } @@ -887,7 +881,7 @@ export class RdDCombat { whisper: ChatUtility.getWhisperRecipientsAndGMs(this.attacker.name), content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.html', { attackerId: this.attackerId, - attacker: this.attacker, + attacker: Misc.data(this.attacker), defenderTokenId: this.defenderTokenId, essais: attackerRoll.essais }) diff --git a/module/rdd-roll.js b/module/rdd-roll.js index 521645a2..6c06a349 100644 --- a/module/rdd-roll.js +++ b/module/rdd-roll.js @@ -144,10 +144,10 @@ export class RdDRoll extends Dialog { console.log(rollData); // Update html, according to data if (rollData.competence) { - let compData = rollData.competence.data.data || rollData.competence.data; + const defaut_carac = Misc.templateData(rollData.competence).defaut_carac; // Set the default carac from the competence item - rollData.selectedCarac = rollData.carac[compData.defaut_carac]; - $("#carac").val(compData.defaut_carac); + rollData.selectedCarac = rollData.carac[defaut_carac]; + $("#carac").val(defaut_carac); } if (rollData.selectedSort) { $("#draconic").val(rollData.selectedSort.data.listIndex); // Uniquement a la selection du sort, pour permettre de changer @@ -184,8 +184,10 @@ export class RdDRoll extends Dialog { let sortKey = Misc.toInt(event.currentTarget.value); this.rollData.selectedSort = this.rollData.sortList[sortKey]; // Update the selectedCarac this.rollData.bonus = RdDItemSort.getCaseBonus(this.rollData.selectedSort, this.rollData.tmr.coord); + this.rollData.diffLibre = RdDItemSort.getDifficulte(this.rollData.selectedSort, -7) RdDItemSort.setCoutReveReel(this.rollData.selectedSort); $("#draconic").val(this.rollData.selectedSort.data.listIndex); // Uniquement a la selection du sort, pour permettre de changer + $("#diffLibre").val(this.rollData.diffLibre); this.updateRollResult(); }); html.find('#ptreve-variable').change((event) => { diff --git a/module/rdd-tmr-dialog.js b/module/rdd-tmr-dialog.js index 05665f24..fc4932ce 100644 --- a/module/rdd-tmr-dialog.js +++ b/module/rdd-tmr-dialog.js @@ -319,28 +319,28 @@ export class RdDTMRDialog extends Dialog { } /* -------------------------------------------- */ - async _tentativeMaitrise(rencontreData, presentCite) { - console.log("-> matriser", rencontreData); + async _tentativeMaitrise(rencData, presentCite) { + console.log("-> matriser", rencData); - rencontreData.reve = this.actor.getReveActuel(); - rencontreData.etat = this.actor.getEtatGeneral(); + rencData.reve = this.actor.getReveActuel(); + rencData.etat = this.actor.getEtatGeneral(); - RollDataAjustements.calcul(rencontreData, this.actor); + RollDataAjustements.calcul(rencData, this.actor); - rencontreData.rolled = rencontreData.presentCite - ? this._rollPresentCite(rencontreData) - : await RdDResolutionTable.roll(rencontreData.reve, RollDataAjustements.sum(rencontreData.ajustements)); + rencData.rolled = rencData.presentCite + ? this._rollPresentCite(rencData) + : await RdDResolutionTable.roll(rencData.reve, RollDataAjustements.sum(rencData.ajustements)); - let postProcess = await TMRRencontres.gererRencontre(this, rencontreData); + let postProcess = await TMRRencontres.gererRencontre(this, rencData); ChatMessage.create({ whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), - content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-rencontre-tmr.html`, rencontreData) + content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-rencontre-tmr.html`, rencData) }); if (postProcess) { /** Gère les rencontres avec du post-processing (passeur, messagers, tourbillons, ...) */ - await postProcess(this, rencontreData); + await postProcess(this, rencData); } else { this.currentRencontre = undefined; @@ -350,12 +350,12 @@ export class RdDTMRDialog extends Dialog { if (this.checkQuitterTMR()) { return; } - else if (rencontreData.rolled.isEchec && rencontreData.rencontre.isPersistant) { + else if (rencData.rolled.isEchec && rencData.rencontre.isPersistant) { setTimeout(() => { - rencontreData.nbRounds++; + rencData.nbRounds++; this.cumulFatigue += this.fatigueParCase; - this._tentativeMaitrise(rencontreData); - this._deleteTmrMessages(rencontreData.actor, rencontreData.nbRounds); + this._tentativeMaitrise(rencData); + this._deleteTmrMessages(rencData.actor, rencData.nbRounds); }, 2000); } } diff --git a/module/rdd-utility.js b/module/rdd-utility.js index 741662e8..502447cf 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -667,8 +667,9 @@ export class RdDUtility { label: "Annuler" } } - if (objet.data.type == 'conteneur' && objet.data.data.contenu.length > 0) { - msgTxt += "
Cet objet est aussi un conteneur avec du contenu : choisissez l'option de suppression"; + const docData = Misc.data(objet); + if (docData.type == 'conteneur' && docData.data.contenu.length > 0) { + msgTxt += "
Ce conteneur n'est pas vide. Choisissez l'option de suppression"; buttons['deleteall'] = { icon: '', label: "Supprimer le conteneur et tout son contenu", diff --git a/module/tmr-rencontres.js b/module/tmr-rencontres.js index 451f7b87..9fe59c92 100644 --- a/module/tmr-rencontres.js +++ b/module/tmr-rencontres.js @@ -8,11 +8,11 @@ import { TMRType } from "./tmr-utility.js"; const typeRencontres = { messager: { - msgSucces: (data) => `Le ${data.rencontre.name} vous propose d'emmener le message de votre un sort à ${data.rencontre.force} cases ${data.tmr.label}.`, - msgEchec: (data) => `Le ${data.rencontre.name} est pressé et continue son chemin d'une traite sans vous accorder un regard.`, - postSucces: (tmrDialog, data) => { - tmrDialog.setStateRencontre(data.rencontre.type); - tmrDialog.choisirCasePortee(data.tmr.coord, data.rencontre.force); + msgSucces: (rencData) => `Le ${rencData.rencontre.name} vous propose d'emmener le message de votre un sort à ${rencData.rencontre.force} cases ${rencData.tmr.label}.`, + msgEchec: (rencData) => `Le ${rencData.rencontre.name} est pressé et continue son chemin d'une traite sans vous accorder un regard.`, + postSucces: (tmrDialog, rencData) => { + tmrDialog.setStateRencontre(rencData.rencontre.type); + tmrDialog.choisirCasePortee(rencData.tmr.coord, rencData.rencontre.force); }, poesieSucces: { reference: "La chevelure, Charles Baudelaire", @@ -28,11 +28,11 @@ const typeRencontres = { }, passeur: { - msgSucces: (data) => `Le ${data.rencontre.name} vous propose de vous transporter à ${data.rencontre.force} cases des ${data.tmr.label}.`, - msgEchec: (data) => `Le prix que demande le ${data.rencontre.name} est trop élevé, vous êtes réduit à poursuivre votre chemin par vos propres moyens.`, - postSucces: (tmrDialog, data) => { - tmrDialog.setStateRencontre(data.rencontre.type); - tmrDialog.choisirCasePortee(data.tmr.coord, data.rencontre.force); + msgSucces: (rencData) => `Le ${rencData.rencontre.name} vous propose de vous transporter à ${rencData.rencontre.force} cases des ${rencData.tmr.label}.`, + msgEchec: (rencData) => `Le prix que demande le ${rencData.rencontre.name} est trop élevé, vous êtes réduit à poursuivre votre chemin par vos propres moyens.`, + postSucces: (tmrDialog, rencData) => { + tmrDialog.setStateRencontre(rencData.rencontre.type); + tmrDialog.choisirCasePortee(rencData.tmr.coord, rencData.rencontre.force); }, poesieSucces: { reference: "Femmes damnées (2), Charles Baudelaire", @@ -49,9 +49,9 @@ const typeRencontres = { }, fleur: { - msgSucces: (data) => `Vous cueillez la ${data.rencontre.name}, son parfum vous apporte ${data.rencontre.force} points de Rêve.`, - msgEchec: (data) => `La ${data.rencontre.name} se fâne et disparaît entre vos doigts.`, - postSucces: (tmrDialog, data) => tmrDialog.actor.reveActuelIncDec(data.rencontre.force), + msgSucces: (rencData) => `Vous cueillez la ${rencData.rencontre.name}, son parfum vous apporte ${rencData.rencontre.force} points de Rêve.`, + msgEchec: (rencData) => `La ${rencData.rencontre.name} se fâne et disparaît entre vos doigts.`, + postSucces: (tmrDialog, rencData) => tmrDialog.actor.reveActuelIncDec(rencData.rencontre.force), poesieSucces: { reference: "L'Ennemi, Charles Baudelaire", extrait: `Et qui sait si les fleurs nouvelles que je rêve @@ -66,9 +66,9 @@ const typeRencontres = { }, mangeur: { - msgSucces: (data) => `Le ${data.rencontre.name} claque de sa machoire dans le vide avant de fuir.`, - msgEchec: (data) => `Le ${data.rencontre.name} croque votre Rêve ! Il emporte ${data.rencontre.force} de vos points de rêve actuels`, - postEchec: (tmrDialog, data) => tmrDialog.actor.reveActuelIncDec(-data.rencontre.force), + msgSucces: (rencData) => `Le ${rencData.rencontre.name} claque de sa machoire dans le vide avant de fuir.`, + msgEchec: (rencData) => `Le ${rencData.rencontre.name} croque votre Rêve ! Il emporte ${rencData.rencontre.force} de vos points de rêve actuels`, + postEchec: (tmrDialog, rencData) => tmrDialog.actor.reveActuelIncDec(-rencData.rencontre.force), poesieSucces: { reference: "Conseil, Victor Hugo", extrait: `Rois ! la bure est souvent jalouse du velours. @@ -85,16 +85,16 @@ const typeRencontres = { }, changeur: { - msgSucces: (data) => `Le ${data.rencontre.name} vaincu accepte de vous déplacer sur une autre ${TMRType[data.tmr.type].name} de votre choix en échange de sa liberté.`, - msgEchec: (data) => { - data.newTMR = TMRUtility.getTMRAleatoire(it => it.type = data.tmr.type); - return `Le ${data.rencontre.name} vous embobine avec des promesses, et vous transporte en ${data.newTMR.label} sans attendre votre avis.`; + msgSucces: (rencData) => `Le ${rencData.rencontre.name} vaincu accepte de vous déplacer sur une autre ${TMRType[rencData.tmr.type].name} de votre choix en échange de sa liberté.`, + msgEchec: (rencData) => { + rencData.newTMR = TMRUtility.getTMRAleatoire(it => it.type = rencData.tmr.type); + return `Le ${rencData.rencontre.name} vous embobine avec des promesses, et vous transporte en ${rencData.newTMR.label} sans attendre votre avis.`; }, - postSucces: (tmrDialog, data) => { - tmrDialog.setStateRencontre(data.rencontre.type); - tmrDialog.choisirCaseType(data.tmr.type); + postSucces: (tmrDialog, rencData) => { + tmrDialog.setStateRencontre(rencData.rencontre.type); + tmrDialog.choisirCaseType(rencData.tmr.type); }, - postEchec: (tmrDialog, data) => tmrDialog.forceDemiRevePosition(data.newTMR.coord), + postEchec: (tmrDialog, rencData) => tmrDialog.forceDemiRevePosition(rencData.newTMR.coord), poesieSucces: { reference: "Caligula - IIIème chant, Gérard de Nerval", extrait: `Allez, que le caprice emporte @@ -111,9 +111,9 @@ const typeRencontres = { }, briseur: { - msgSucces: (data) => `Le ${data.rencontre.name} tente vainement de vous déconcentrer, avant de fuir sans demander son reste.`, - msgEchec: (data) => `Le ${data.rencontre.name} vous déconcentre au point de briser votre demi-rêve.`, - postEchec: (tmrDialog, data) => tmrDialog.close(), + msgSucces: (rencData) => `Le ${rencData.rencontre.name} tente vainement de vous déconcentrer, avant de fuir sans demander son reste.`, + msgEchec: (rencData) => `Le ${rencData.rencontre.name} vous déconcentre au point de briser votre demi-rêve.`, + postEchec: (tmrDialog, rencData) => tmrDialog.close(), poesieSucces: { reference: "Rêve de Dragon, Denis Gerfaud", extrait: `La légende affirme que ce sont les Gnomes qui furent @@ -134,8 +134,8 @@ const typeRencontres = { }, reflet: { - msgSucces: (data) => `Le ${data.rencontre.name} s'estompe dans l'oubli.`, - msgEchec: (data) => `Vous êtes submergé par un ${data.rencontre.name}, les souvenirs vous retiennent tant qu'il ne sera pas vaincu!`, + msgSucces: (rencData) => `Le ${rencData.rencontre.name} s'estompe dans l'oubli.`, + msgEchec: (rencData) => `Vous êtes submergé par un ${rencData.rencontre.name}, les souvenirs vous retiennent tant qu'il ne sera pas vaincu!`, poesieSucces: { reference: "Une charogne, Charles Baudelaire", extrait: `Les formes s'effaçaient et n'étaient plus qu'un rêve, @@ -152,9 +152,9 @@ const typeRencontres = { }, passeurfou: { - msgSucces: (data) => `Le ${data.rencontre.name} tente vainement de découvrir où vous avez caché vos réserves. Vous le chassez, et en déroute il part harceler un autre voyageur du rêve.`, - msgEchec: (data) => TMRRencontres.msgEchecPasseurFou(data), - postEchec: (tmrDialog, data) => TMRRencontres.postEchecPasseurFou(tmrDialog, data), + msgSucces: (rencData) => `Le ${rencData.rencontre.name} tente vainement de découvrir où vous avez caché vos réserves. Vous le chassez, et en déroute il part harceler un autre voyageur du rêve.`, + msgEchec: (rencData) => TMRRencontres.msgEchecPasseurFou(rencData), + postEchec: (tmrDialog, rencData) => TMRRencontres.postEchecPasseurFou(tmrDialog, rencData), poesieSucces: { reference: "Un Fou et un Sage, Jean de La Fontaine", extrait: `Certain Fou poursuivait à coups de pierre un Sage. @@ -174,9 +174,9 @@ const typeRencontres = { }, tbblanc: { - msgSucces: (data) => `Le ${data.rencontre.name} souleve une poussière blanche, vous tenez bon, et il tourbillonne en s'éloignant.`, - msgEchec: (data) => `Le souffle du ${data.rencontre.name} vous déstabilise et vous emmène dans un nuage de poussière.`, - postEchec: (tmrDialog, data) => TMRRencontres.onPostEchecTourbillon(tmrDialog, data, 1), + msgSucces: (rencData) => `Le ${rencData.rencontre.name} souleve une poussière blanche, vous tenez bon, et il tourbillonne en s'éloignant.`, + msgEchec: (rencData) => `Le souffle du ${rencData.rencontre.name} vous déstabilise et vous emmène dans un nuage de poussière.`, + postEchec: (tmrDialog, rencData) => TMRRencontres.onPostEchecTourbillon(tmrDialog, rencData, 1), poesieSucces: { reference: "Rêve de Dragon, Denis Gerfaud", extrait: `Le Premier Âge fut appelé l'Âge des Dragons. Ce fut le commencement @@ -191,9 +191,9 @@ const typeRencontres = { }, tbnoir: { - msgSucces: (data) => `Le ${data.rencontre.name} orageux vous enveloppe de fureur et d'éclairs, vous tenez bon face à la tempête qui s'éloigne sans vous éloigner de votre chemin.`, - msgEchec: (data) => `Le ${data.rencontre.name} furieux vous secoue tel un fichu de paille malmené par les vents, et vous emporte dans la tourmente.`, - postEchec: (tmrDialog, data) => TMRRencontres.onPostEchecTourbillon(tmrDialog, data, 2), + msgSucces: (rencData) => `Le ${rencData.rencontre.name} orageux vous enveloppe de fureur et d'éclairs, vous tenez bon face à la tempête qui s'éloigne sans vous éloigner de votre chemin.`, + msgEchec: (rencData) => `Le ${rencData.rencontre.name} furieux vous secoue tel un fichu de paille malmené par les vents, et vous emporte dans la tourmente.`, + postEchec: (tmrDialog, rencData) => TMRRencontres.onPostEchecTourbillon(tmrDialog, rencData, 2), poesieSucces: { reference: "Rêve de Dragon, Denis Gerfaud", extrait: `Car le Second Âge fut bel et bien celui des Magiciens. Durant cette période, les @@ -207,9 +207,9 @@ const typeRencontres = { }, tbrouge: { - msgSucces: (data) => `Le ${data.rencontre.name} s'abat avec violence mais vous êtes plus rapide et parvenez à lui échapper.`, - msgEchec: (data) => `Le ${data.rencontre.name} vous frappe de milliers de morsure et vous malmène à travers les terres médianes.`, - postEchec: (tmrDialog, data) => TMRRencontres.onPostEchecTourbillonRouge(tmrDialog, data), + msgSucces: (rencData) => `Le ${rencData.rencontre.name} s'abat avec violence mais vous êtes plus rapide et parvenez à lui échapper.`, + msgEchec: (rencData) => `Le ${rencData.rencontre.name} vous frappe de milliers de morsure et vous malmène à travers les terres médianes.`, + postEchec: (tmrDialog, rencData) => TMRRencontres.onPostEchecTourbillonRouge(tmrDialog, rencData), poesieSucces: { reference: "Qu'est-ce de votre vie ? une bouteille molle, Jean-Baptiste Chassignet", extrait: `Qu'est-ce de votre vie ? un tourbillon rouant @@ -228,10 +228,10 @@ const typeRencontres = { }, rdd: { - msgSucces: (data) => `A tout seigneur, tout honneur, vous faites face à un ${data.rencontre.name}. Vous le maîtrisez et récupérez ses rêves. Vous gagnez ses ${data.rencontre.force} points de rêve`, - msgEchec: (data) => `A tout seigneur, tout honneur, vous faites face à un ${data.rencontre.name}. La rencontre tourne au cauchemar, dans la lutte épique, vous subissez ${data.rolled.isETotal ? 'deux queues' : 'une queue'} de dragon!`, - postSucces: (tmrDialog, data) => TMRRencontres.onPostSuccessReveDeDragon(tmrDialog, data), - postEchec: (tmrDialog, data) => TMRRencontres.onPostEchecReveDeDragon(tmrDialog, data), + msgSucces: (rencData) => `A tout seigneur, tout honneur, vous faites face à un ${rencData.rencontre.name}. Vous le maîtrisez et récupérez ses rêves. Vous gagnez ses ${rencData.rencontre.force} points de rêve`, + msgEchec: (rencData) => `A tout seigneur, tout honneur, vous faites face à un ${rencData.rencontre.name}. La rencontre tourne au cauchemar, dans la lutte épique, vous subissez ${rencData.rolled.isETotal ? 'deux queues' : 'une queue'} de dragon!`, + postSucces: (tmrDialog, rencData) => TMRRencontres.onPostSuccessReveDeDragon(tmrDialog, rencData), + postEchec: (tmrDialog, rencData) => TMRRencontres.onPostEchecReveDeDragon(tmrDialog, rencData), poesieSucces: { reference: "Rêve de Dragon, Denis Gerfaud", extrait: `Le monde est Rêve de Dragons, mais nous ne savons @@ -349,7 +349,7 @@ export class TMRRencontres { return duplicate(rencontre); } else { - ui.notifications.info(`Pas de rencontre pour ${index}, seulement ${rencontresAll.length} rencontres sont connues.
Vous pouvez aussi essayer par type (ie: mangeur, fleur, fleur2d6, ...)`) + ui.notifications.info(`Pas de rencontre pour ${index}, seulement ${rencontresAll.length} rencontres sont connues.
Vous pouvez aussi essayer par type (ie: mangeur, fleur, fleur2d6, ...)`) } return undefined; } @@ -357,7 +357,7 @@ export class TMRRencontres { /* -------------------------------------------- */ static async getRencontreAleatoire(terrain, roll = undefined) { if (!roll || roll <= 0 || roll > 100) { - roll = new Roll("1d100").evaluate( {async: false}).total; + roll = new Roll("1d100").evaluate({ async: false }).total; } terrain = Grammar.toLowerCaseNoAccent(terrain); //console.log("getRencontreAleatoire", terrain, roll); @@ -386,7 +386,7 @@ export class TMRRencontres { rencontre.force = 7 + ddr.total; } else { - rencontre.force = new Roll(rencontre.force).evaluate( {async: false} ).total; + rencontre.force = new Roll(rencontre.force).evaluate({ async: false }).total; } return rencontre.force; } @@ -407,58 +407,58 @@ export class TMRRencontres { } /* -------------------------------------------- */ - static async gererRencontre(tmrDialog, data) { - let gestion = TMRRencontres.getGestionRencontre(data.rencontre.type); - if (data.rolled.isSuccess) { - data.message = gestion.msgSucces(data); - if (data.nbRounds > 1) { - data.message += ` Au total, vous avez passé ${data.nbRounds} rounds à vous battre!`; + static async gererRencontre(tmrDialog, rencData) { + let gestion = TMRRencontres.getGestionRencontre(rencData.rencontre.type); + if (rencData.rolled.isSuccess) { + rencData.message = gestion.msgSucces(rencData); + if (rencData.nbRounds > 1) { + rencData.message += ` Au total, vous avez passé ${rencData.nbRounds} rounds à vous battre!`; } - data.poesie = gestion.poesieSucces; + rencData.poesie = gestion.poesieSucces; return gestion.postSucces; } - data.message = gestion.msgEchec(data); - if (data.nbRounds > 1) { - data.message += ` Vous avez passé ${data.nbRounds} rounds à lutter!`; + rencData.message = gestion.msgEchec(rencData); + if (rencData.nbRounds > 1) { + rencData.message += ` Vous avez passé ${rencData.nbRounds} rounds à lutter!`; } - data.poesie = gestion.poesieEchec; + rencData.poesie = gestion.poesieEchec; return gestion.postEchec; } /* -------------------------------------------- */ - static msgEchecPasseurFou(data) { - data.sortReserve = data.actor.data.data.reve.reserve.list[0]; - if (data.sortReserve) { + static msgEchecPasseurFou(tmrData) { + tmrData.sortReserve = Misc.templateData(tmrData.actor).reve.reserve.list[0]; + if (tmrData.sortReserve) { // Passeur fou positionne sur la case d'un ort en réserve // TODO : Choisir le sort le plus loin ou au hasard - data.newTMR = TMRUtility.getTMR(data.sortReserve.coord); + tmrData.newTMR = TMRUtility.getTMR(tmrData.sortReserve.coord); } else { // Déplacement aléatoire de la force du Passeur Fou - const newCoord = Misc.rollOneOf(TMRUtility.getTMRPortee(data.tmr.coord, data.rencontre.force)); - data.newTMR = TMRUtility.getTMR(newCoord); + const newCoord = Misc.rollOneOf(TMRUtility.getTMRPortee(tmrData.tmr.coord, tmrData.rencontre.force)); + tmrData.newTMR = TMRUtility.getTMR(newCoord); } - if (data.sortReserve) { - return `Le ${data.rencontre.name} vous dérobe la clé de vos sorts. Vous vous saisissez de lui, mais dans un nuage violet, il vous emporte en ${data.newTMR.label} déclencher votre sort en réserve de ${data.sortReserve.name}.`; + if (tmrData.sortReserve) { + return `Le ${tmrData.rencontre.name} vous dérobe la clé de vos sorts. Vous vous saisissez de lui, mais dans un nuage violet, il vous emporte en ${tmrData.newTMR.label} déclencher votre sort en réserve de ${tmrData.sortReserve.name}.`; } else { - return `Le ${data.rencontre.name} tente de vous dérober la clé de vos sorts. Ne la trouvant pas, il déclenche un nuage violet et vous emporte en ${data.newTMR.label}`; + return `Le ${tmrData.rencontre.name} tente de vous dérober la clé de vos sorts. Ne la trouvant pas, il déclenche un nuage violet et vous emporte en ${tmrData.newTMR.label}`; } } - static async postEchecPasseurFou(tmrDialog, data) { - if (data.sortReserve) { - await tmrDialog.processSortReserve(data.sortReserve); + static async postEchecPasseurFou(tmrDialog, tmrData) { + if (tmrData.sortReserve) { + await tmrDialog.processSortReserve(tmrData.sortReserve); } - await tmrDialog.forceDemiRevePosition(data.newTMR.coord); - if (data.sortReserve) { + await tmrDialog.forceDemiRevePosition(tmrData.newTMR.coord); + if (tmrData.sortReserve) { tmrDialog.close(); } } /* -------------------------------------------- */ - static async onPostEchecTourbillon(tmrDialog, data, cases) { - await data.actor.reveActuelIncDec(-cases); - await TMRRencontres._toubillonner(tmrDialog, data.actor, cases); + static async onPostEchecTourbillon(tmrDialog, tmrData, cases) { + await tmrData.actor.reveActuelIncDec(-cases); + await TMRRencontres._toubillonner(tmrDialog, tmrData.actor, cases); } /* -------------------------------------------- */ @@ -469,22 +469,22 @@ export class TMRRencontres { } static async _toubillonner(tmrDialog, actor, cases) { - let coord = actor.data.data.reve.tmrpos.coord; + let coord = Misc.templateData(actor).reve.tmrpos.coord; for (let i = 0; i < cases; i++) { coord = TMRUtility.deplaceTMRAleatoire(actor, coord).coord; } await tmrDialog.forceDemiRevePosition(coord) } - static async onPostSuccessReveDeDragon(tmrDialog, data) { - if (data.rolled.isPart) { - await data.actor.appliquerExperience(data.rolled, 'reve', data.competence); + static async onPostSuccessReveDeDragon(tmrDialog, tmrData) { + if (tmrData.rolled.isPart) { + await tmrData.actor.appliquerExperience(tmrData.rolled, 'reve', tmrData.competence); } - await data.actor.resultCombatReveDeDragon(data); + await tmrData.actor.resultCombatReveDeDragon(tmrData); } - static async onPostEchecReveDeDragon(tmrDialog, data) { - await data.actor.resultCombatReveDeDragon(data); + static async onPostEchecReveDeDragon(tmrDialog, tmrData) { + await tmrData.actor.resultCombatReveDeDragon(tmrData); tmrDialog.close(); } } diff --git a/module/tmr/urgence-draconique.js b/module/tmr/urgence-draconique.js index 81543a29..1b43d1f3 100644 --- a/module/tmr/urgence-draconique.js +++ b/module/tmr/urgence-draconique.js @@ -1,5 +1,6 @@ import { ChatUtility } from "../chat-utility.js"; import { Grammar } from "../grammar.js"; +import { Misc } from "../misc.js"; import { RdDRollTables } from "../rdd-rolltables.js"; import { tmrColors, tmrConstants, tmrTokenZIndex, TMRUtility } from "../tmr-utility.js"; import { Draconique } from "./draconique.js"; @@ -14,22 +15,22 @@ export class UrgenceDraconique extends Draconique { match(item) { return Draconique.isQueueDragon(item) && Grammar.toLowerCaseNoAccent(item.name).includes('urgence draconique'); } manualMessage() { return false } async onActorCreateOwned(actor, queue) { - let coordSortsReserve = (actor.data.data.reve.reserve?.list.map(it => it.coord)) ?? []; + const coordSortsReserve = (Misc.templateData(actor).reve.reserve?.list.map(it => it.coord)) ?? []; if (coordSortsReserve.length == 0) { // La queue se transforme en idée fixe - let ideeFixe = await RdDRollTables.getIdeeFixe(); + const ideeFixe = await RdDRollTables.getIdeeFixe(); ChatMessage.create({ whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), - content: `En l'absence de sorts en réserve, l'urgence draconique de ${actor.name} se transforme en ${queue.name}` + content: `En l'absence de sorts en réserve, l'urgence draconique de ${actor.name} se transforme en ${ideeFixe.name}` }); await actor.createEmbeddedDocuments('Item',[ideeFixe]); await actor.deleteOwnedItem(queue._id); return; } else { - let demiReve = actor.getDemiReve(); - coordSortsReserve.sort((a, b) => TMRUtility.distanceTMR(a, demiReve) - TMRUtility.distanceTMR(b, demiReve)); - let tmr = TMRUtility.getTMR(coordSortsReserve[0]); + const demiReve = actor.getDemiReve(); + coordSortsReserve.sort(Misc.ascending(t => TMRUtility.distanceTMR(t, demiReve))); + const tmr = TMRUtility.getTMR(coordSortsReserve[0]); await this.createCaseTmr(actor, 'Urgence draconique: ' + tmr.label, tmr, queue._id); } } diff --git a/templates/actor-sheet.html b/templates/actor-sheet.html index 1d96f073..222e0e70 100644 --- a/templates/actor-sheet.html +++ b/templates/actor-sheet.html @@ -863,7 +863,6 @@

Biographie :

- {{log 'biographie' data.biographie}} {{editor content=data.biographie target="data.biographie" button=true owner=owner editable=editable}}

Notes :

diff --git a/templates/actor-vehicule-sheet.html b/templates/actor-vehicule-sheet.html index ddc2bf6e..af4165cf 100644 --- a/templates/actor-vehicule-sheet.html +++ b/templates/actor-vehicule-sheet.html @@ -27,7 +27,7 @@
  1. Catégorie - {{#select data.categorie}} {{>"systems/foundryvtt-reve-de-dragon/templates/enum-categorie-vehicule.html"}} {{/select}} diff --git a/templates/chat-demande-attaque-etotal.html b/templates/chat-demande-attaque-etotal.html index 77ef3a99..30aff21d 100644 --- a/templates/chat-demande-attaque-etotal.html +++ b/templates/chat-demande-attaque-etotal.html @@ -1,14 +1,14 @@

    Echec total en attaque


    - {{#if (eq attacker.data.type 'personnage')}} + {{#if (eq attacker.type 'personnage')}} {{#unless essais.attaqueChance}} Faire appel à la chance
    {{/unless}} - {{#if (gt attacker.data.data.compteurs.destinee.value 0)}} + {{#if (gt attacker.data.compteurs.destinee.value 0)}} Utiliser la destinée diff --git a/templates/chat-demande-defense.html b/templates/chat-demande-defense.html index 5f384da5..ff1ea42f 100644 --- a/templates/chat-demande-defense.html +++ b/templates/chat-demande-defense.html @@ -19,14 +19,14 @@ {{#unless (eq surprise 'totale')}} {{#if essais.defense}} {{#unless essais.defenseChance}} - {{#if (eq defender.data.type 'personnage')}} + {{#if (eq defender.type 'personnage')}} Faire appel à la chance
    {{/if}} - {{#if (eq defender.data.type 'personnage')}} - {{#if (gt defender.data.data.compteurs.destinee.value 0)}} + {{#if (eq defender.type 'personnage')}} + {{#if (gt defender.data.compteurs.destinee.value 0)}} Utiliser la destinée diff --git a/templates/chat-resultat-reve-de-dragon.html b/templates/chat-resultat-reve-de-dragon.html index f1aa7992..3bd7ae4e 100644 --- a/templates/chat-resultat-reve-de-dragon.html +++ b/templates/chat-resultat-reve-de-dragon.html @@ -15,7 +15,7 @@ Vous ne parvenez pas à vaincre le Rêve de Dragon, et prennez un violent coup de queue. Vous subissez {{#if rolled.isETotal}}deux queues{{else}}une queue{{/if}} de dragon! {{#each queues as | queue key|}} -
    {{queue.name}}: {{{queue.data.data.description}}} +
    {{queue.name}}: {{{queue.data.description}}} {{/each}} {{/if}} diff --git a/templates/item-competence-sheet.html b/templates/item-competence-sheet.html index 933f9ace..21663962 100644 --- a/templates/item-competence-sheet.html +++ b/templates/item-competence-sheet.html @@ -16,7 +16,7 @@
    - {{#select data.categorie}} {{>"systems/foundryvtt-reve-de-dragon/templates/enum-categorie-competence.html"}} {{/select}} @@ -28,7 +28,7 @@
    - +
    diff --git a/templates/item-herbe-sheet.html b/templates/item-herbe-sheet.html index 38234bc7..84cf84a6 100644 --- a/templates/item-herbe-sheet.html +++ b/templates/item-herbe-sheet.html @@ -27,7 +27,7 @@
    - {{#select data.rarete}} {{>"systems/foundryvtt-reve-de-dragon/templates/enum-rarete.html"}} {{/select}} @@ -35,7 +35,7 @@
    - {{#select data.categorie}} {{>"systems/foundryvtt-reve-de-dragon/templates/enum-categorie-ingredient.html"}} {{/select}} diff --git a/templates/item-ingredient-sheet.html b/templates/item-ingredient-sheet.html index 8ab2dded..6429cb9d 100644 --- a/templates/item-ingredient-sheet.html +++ b/templates/item-ingredient-sheet.html @@ -32,7 +32,7 @@
    - {{#select data.rarete}} {{>"systems/foundryvtt-reve-de-dragon/templates/enum-rarete.html"}} {{/select}} @@ -40,7 +40,7 @@
    - {{#select data.categorie}} {{>"systems/foundryvtt-reve-de-dragon/templates/enum-categorie-ingredient.html"}} {{/select}} diff --git a/templates/item-livre-sheet.html b/templates/item-livre-sheet.html index 2f8669dc..95224cc6 100644 --- a/templates/item-livre-sheet.html +++ b/templates/item-livre-sheet.html @@ -56,7 +56,7 @@
    {{#if isOwned}} {{/if}}
    diff --git a/templates/item-potion-sheet.html b/templates/item-potion-sheet.html index b5ed869d..041afe1e 100644 --- a/templates/item-potion-sheet.html +++ b/templates/item-potion-sheet.html @@ -22,7 +22,7 @@
    - {{#select data.rarete}} {{>"systems/foundryvtt-reve-de-dragon/templates/enum-rarete.html"}} {{/select}} @@ -30,7 +30,7 @@
    - {{#select data.categorie}} {{>"systems/foundryvtt-reve-de-dragon/templates/enum-categorie-ingredient.html"}} {{/select}} From 3735377a20130e496048c7ce7d936fc78e4c86ba Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Mon, 29 Mar 2021 19:43:23 +0200 Subject: [PATCH 04/10] Utiliser EmbeddedDocuments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit les méthodes Entity son deprecated/à ne plus utiliser --- module/actor.js | 40 ++++++++++++++++++++-------------------- module/item-sort.js | 2 +- module/rdd-combat.js | 6 +++--- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/module/actor.js b/module/actor.js index 98a714a7..56a4f06d 100644 --- a/module/actor.js +++ b/module/actor.js @@ -681,7 +681,7 @@ export class RdDActor extends Actor { else update['data.carac_value'] = compValue; //console.log(update); - const updated = await this.updateEmbeddedEntity("Item", update); // Updates one EmbeddedEntity + const updated = await this.updateEmbeddedDocuments("Item", update); // Updates one EmbeddedEntity } } @@ -702,7 +702,7 @@ export class RdDActor extends Actor { }); } const update = { _id: comp.id, 'data.niveau': nouveauNiveau }; - await this.updateEmbeddedEntity("Item", update); // Updates one EmbeddedEntity + await this.updateEmbeddedDocuments("Item", update); // Updates one EmbeddedEntity } else { console.log("Competence not found", compName); } @@ -715,7 +715,7 @@ export class RdDActor extends Actor { compValue = compValue ?? 0; this.checkCompetenceXP(compName, compValue); const update = { _id: comp.id, 'data.xp': compValue }; - await this.updateEmbeddedEntity("OwnedItem", update); // Updates one EmbeddedEntity + await this.updateEmbeddedDocuments("OwnedItem", update); // Updates one EmbeddedEntity } else { console.log("Competence not found", compName); } @@ -728,7 +728,7 @@ export class RdDActor extends Actor { if (comp) { compValue = compValue ?? 0; const update = { _id: comp.id, 'data.xp_sort': compValue }; - await this.updateEmbeddedEntity("OwnedItem", update); // Updates one EmbeddedEntity + await this.updateEmbeddedDocuments("OwnedItem", update); // Updates one EmbeddedEntity } else { console.log("Competence not found", compName); } @@ -740,7 +740,7 @@ export class RdDActor extends Actor { if (comp) { compValue = compValue ?? 0; const update = { _id: comp.id, 'data.niveau_archetype': compValue }; - await this.updateEmbeddedEntity("OwnedItem", update); // Updates one EmbeddedEntity + await this.updateEmbeddedDocuments("OwnedItem", update); // Updates one EmbeddedEntity } else { console.log("Competence not found", compName); } @@ -876,7 +876,7 @@ export class RdDActor extends Actor { contenu.splice(index, 1); index = contenu.indexOf(itemId); } - await this.updateEmbeddedEntity("OwnedItem", data2use); + await this.updateEmbeddedDocuments("OwnedItem", data2use); } } @@ -888,7 +888,7 @@ export class RdDActor extends Actor { if (conteneur?.type == 'conteneur') { let data2use = duplicate(Misc.data(conteneur)); data2use.data.contenu.push(itemId); - await this.updateEmbeddedEntity("OwnedItem", data2use); + await this.updateEmbeddedDocuments("OwnedItem", data2use); } } @@ -2071,7 +2071,7 @@ export class RdDActor extends Actor { async _tacheResult(rollData) { // Mise à jour de la tache rollData.tache.data.points_de_tache_courant += rollData.rolled.ptTache; - this.updateEmbeddedEntity("OwnedItem", rollData.tache); + this.updateEmbeddedDocuments("OwnedItem", rollData.tache); this.santeIncDec("fatigue", rollData.tache.data.fatigue); RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-tache.html'); @@ -2080,7 +2080,7 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ _tacheETotal(rollData) { rollData.tache.data.difficulte--; - this.updateEmbeddedEntity("OwnedItem", rollData.tache); + this.updateEmbeddedDocuments("OwnedItem", rollData.tache); } /* -------------------------------------------- */ @@ -2245,7 +2245,7 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ _meditationETotal(meditationData) { meditationData.meditation.data.malus--; - this.updateEmbeddedEntity("OwnedItem", meditationData.meditation); + this.updateEmbeddedDocuments("OwnedItem", meditationData.meditation); } /* -------------------------------------------- */ @@ -2348,7 +2348,7 @@ export class RdDActor extends Actor { xpComp = xp - xpCarac; competence = duplicate(competence); competence.data.xp = Misc.toInt(competence.data.xp) + xpComp; - await this.updateEmbeddedEntity("OwnedItem", competence); + await this.updateEmbeddedDocuments("OwnedItem", competence); } else { xpCarac = Math.max(xpCarac, 1); } @@ -2382,12 +2382,12 @@ export class RdDActor extends Actor { name: "Nombre Astral", type: "nombreastral", data: { value: data.nbAstral, istrue: data.isvalid, jourindex: Number(data.date), jourlabel: game.system.rdd.calendrier.getDateFromIndex(Number(data.date)) } }; - await this.createEmbeddedEntity("OwnedItem", item); + await this.createEmbeddedDocuments("OwnedItem", [item]); // Suppression des anciens nombres astraux let toDelete = this.data.items.filter(it => it.data.jourindex < game.system.rdd.calendrier.getCurrentDayIndex()); const deletions = toDelete.map(it => it._id); - await this.deleteEmbeddedEntity("OwnedItem", deletions); + await this.deleteEmbeddedDocuments("OwnedItem", deletions); // Affichage Dialog this.astrologieNombresAstraux(); @@ -2551,7 +2551,7 @@ export class RdDActor extends Actor { let itemData = Misc.itemData(item); const isEquipe = !itemData.data.equipe; let update = { _id: item._id, "data.equipe": isEquipe }; - await this.updateEmbeddedEntity("OwnedItem", update); + await this.updateEmbeddedDocuments("OwnedItem", update); this.computeEncombrementTotalEtMalusArmure(); // Mise à jour encombrement this.computePrixTotalEquipement(); // Mis à jour du prix total de l'équipement if (isEquipe) @@ -2608,7 +2608,7 @@ export class RdDActor extends Actor { } ChatMessage.create({ content: "Votre armure s'est détériorée, elle protège maintenant de " + itemData.data.protection }); } - this.updateEmbeddedEntity("OwnedItem", itemData); + this.updateEmbeddedDocuments("OwnedItem", itemData); } /* -------------------------------------------- */ @@ -2862,7 +2862,7 @@ export class RdDActor extends Actor { } for (const [valeur, nombre] of Object.entries(fortune)) { let piece = parValeur[valeur]; - await this.updateEmbeddedEntity("OwnedItem", { _id: piece._id, 'data.quantite': nombre }); + await this.updateEmbeddedDocuments("OwnedItem", { _id: piece._id, 'data.quantite': nombre }); } } @@ -2912,7 +2912,7 @@ export class RdDActor extends Actor { let monnaie = this.getMonnaie(id); if (monnaie) { const quantite = Math.max(0, Misc.templateData(monnaie).quantite + value); - await this.updateEmbeddedEntity("OwnedItem", { _id: monnaie.id, 'data.quantite': quantite }); + await this.updateEmbeddedDocuments("OwnedItem", { _id: monnaie.id, 'data.quantite': quantite }); } } @@ -3140,11 +3140,11 @@ export class RdDActor extends Actor { } /* -------------------------------------------- */ - async updateEmbeddedEntity(embeddedName, data, options) { - if (data && data['data.defaut_carac'] && data['data.xp']) { // C'est une compétence + async updateEmbeddedDocuments(embeddedName, data, options) { + if (data?.type == 'competence' && data['data.defaut_carac'] && data['data.xp']) { // C'est une compétence this.checkCompetenceXP(data['name'], data['data.xp']); } - return super.updateEmbeddedDocuments("Item", [data], options); + return super.updateEmbeddedDocuments(embeddedName, [data], options); } /* -------------------------------------------- */ diff --git a/module/item-sort.js b/module/item-sort.js index f9942b18..3c0afa72 100644 --- a/module/item-sort.js +++ b/module/item-sort.js @@ -106,7 +106,7 @@ export class RdDItemSort extends Item { // Sauvegarde/update let bonuscase = StringList.toString(); //console.log("Bonus cae :", bonuscase); - actor.updateEmbeddedEntity("OwnedItem", { _id: sort._id, 'data.bonuscase': bonuscase } ); + actor.updateEmbeddedDocuments("OwnedItem", { _id: sort._id, 'data.bonuscase': bonuscase } ); } /* -------------------------------------------- */ diff --git a/module/rdd-combat.js b/module/rdd-combat.js index c4450cdf..7f53d402 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -104,7 +104,7 @@ export class RdDCombatManager extends Combat { const roll = super._getInitiativeRoll(c, rollFormula); if (roll.total <= 0) roll.total = 0.00; console.log("Compute init for", rollFormula, roll.total); - await this.updateEmbeddedEntity("Combatant", { _id: c._id, initiative: roll.total }); + await this.updateEmbeddedDocuments("Combatant", { _id: c._id, initiative: roll.total }); // Send a chat message let rollMode = messageOptions.rollMode || game.settings.get("core", "rollMode"); @@ -1130,7 +1130,7 @@ export class RdDCombat { resistance -= perteResistance; defenderRoll.show.deteriorationArme = resistance <= 0 ? 'brise' : 'perte'; defenderRoll.show.perteResistance = perteResistance; - this.defender.updateEmbeddedEntity("OwnedItem", { _id: defenderRoll.arme._id, 'data.resistance': resistance }); + this.defender.updateEmbeddedDocuments("OwnedItem", { _id: defenderRoll.arme._id, 'data.resistance': resistance }); } } } else { @@ -1147,7 +1147,7 @@ export class RdDCombat { resistance -= dmg; defenderRoll.show.deteriorationArme = resistance <= 0 ? 'brise' : 'perte'; defenderRoll.show.perteResistance = dmg; - this.defender.updateEmbeddedEntity("OwnedItem", { _id: defenderRoll.arme._id, 'data.resistance': resistance }); + this.defender.updateEmbeddedDocuments("OwnedItem", { _id: defenderRoll.arme._id, 'data.resistance': resistance }); } } // Si l'arme de parade n'est pas un bouclier, jet de désarmement (p.132) From 049b46e3cc2d5f41c8bd330ef8964e8d67d0fa97 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Mon, 29 Mar 2021 19:44:21 +0200 Subject: [PATCH 05/10] =?UTF-8?q?Fix=20ActiveEffect=20demi-r=C3=AAve?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit L'ActiveEffect demi-rêve n'était plus supprimé --- module/actor.js | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/module/actor.js b/module/actor.js index 56a4f06d..7b09ba3f 100644 --- a/module/actor.js +++ b/module/actor.js @@ -3063,7 +3063,8 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ enleverTousLesEffets() { - this.deleteEmbeddedEntity('ActiveEffect', Array.from(this.effects?.keys() ?? [])); + const ids = Array.from(this.effects?.keys() ?? []); + this.deleteEmbeddedDocuments('ActiveEffect', ids); } /* -------------------------------------------- */ @@ -3102,41 +3103,37 @@ export class RdDActor extends Actor { } /* -------------------------------------------- */ - deleteStatusEffectById(id, options = { renderSheet: true }) { + deleteStatusEffectById(id) { const effects = Array.from(this.effects?.values()) .filter(it => it.data.flags.core?.statusId == id); - this._deleteStatusEffects(effects, options); + this._deleteStatusEffects(effects); } /* -------------------------------------------- */ - deleteStatusEffect(effect, options = { renderSheet: true }) { + deleteStatusEffect(effect) { const toDelete = Array.from(this.effects?.values()) .filter(it => StatusEffects.statusId(it.data) == StatusEffects.statusId(effect)); - this._deleteStatusEffects(toDelete, options); + this._deleteStatusEffects(toDelete); } /* -------------------------------------------- */ - _deleteStatusEffects(effects, options) { - this._deleteStatusEffectsByIds(effects.map(it => it.id), options); + _deleteStatusEffects(effects) { + const ids = effects.map(it => it.id); + this.deleteEmbeddedDocuments('ActiveEffect', ids); } /* -------------------------------------------- */ - _deleteStatusEffectsByIds(effectIds, options) { - this.deleteEmbeddedDocuments('ActiveEffect', [effectIds], options); - } - - /* -------------------------------------------- */ - async addStatusEffectById(id, options = { renderSheet: false }) { + async addStatusEffectById(id) { const statusEffect = CONFIG.statusEffects.find(it => it.id == id); - await this.addStatusEffect(statusEffect, options); + await this.addStatusEffect(statusEffect); } /* -------------------------------------------- */ - async addStatusEffect(statusEffect, options = { renderSheet: false }) { - this.deleteStatusEffectById(statusEffect.id, options); + async addStatusEffect(statusEffect) { + this.deleteStatusEffectById(statusEffect.id); const effet = duplicate(statusEffect); effet["flags.core.statusId"] = effet.id; - await this.createEmbeddedEntity('ActiveEffect', effet, options); + await this.createEmbeddedDocuments('ActiveEffect', [effet]); } /* -------------------------------------------- */ From 68cd086a2fc7d33860922be38bf8b8c20851f251 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Mon, 29 Mar 2021 20:09:25 +0200 Subject: [PATCH 06/10] Corrections StatusEffect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit changement du hook, et des méthodes pour les ajouter --- module/actor.js | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/module/actor.js b/module/actor.js index 7b09ba3f..173e375f 100644 --- a/module/actor.js +++ b/module/actor.js @@ -37,11 +37,15 @@ import { Monnaie } from "./item-monnaie.js"; export class RdDActor extends Actor { /* -------------------------------------------- */ static init() { - Hooks.on("deleteActiveEffect", (actor, effect, options) => actor.onDeleteActiveEffect(effect, options)); - Hooks.on("createActiveEffect", (actor, effect, options) => actor.onCreateActiveEffect(effect, options)); + Hooks.on("deleteActiveEffect", (effect, options, userId) => RdDActor.getParentActor(effect)?.onDeleteActiveEffect(effect, options)); Hooks.on("createOwnedItem", (actor, item, options, id) => actor.onCreateOwnedItem(item, options, id)); Hooks.on("deleteOwnedItem", (actor, item, options, id) => actor.onDeleteOwnedItem(item, options, id)); Hooks.on("updateActor", (actor, update, options, actorId) => actor.onUpdateActor(update, options, actorId)); + Hooks.on("createActiveEffect", (effect, options, userId) => RdDActor.getParentActor(effect)?.onCreateActiveEffect(effect, options)); + } + + static getParentActor(document){ + return document?.parent instanceof Actor ? document.parent : undefined } /* -------------------------------------------- */ @@ -3076,11 +3080,12 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async setStatusDemiReve(status) { + const demiReve = StatusEffects.demiReve(); if (status) { - await this.addStatusEffect(StatusEffects.demiReve()) + await this.addStatusEffect(demiReve) } else { - this.deleteStatusEffect(StatusEffects.demiReve()) + this.deleteStatusEffect(demiReve) } } @@ -3093,8 +3098,8 @@ export class RdDActor extends Actor { } /* -------------------------------------------- */ - async forceStatusEffectId(statusId, sonne) { - if (sonne) { + async forceStatusEffectId(statusId, isSet) { + if (isSet) { await this.addStatusEffectById(statusId); } else { @@ -3104,21 +3109,17 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ deleteStatusEffectById(id) { - const effects = Array.from(this.effects?.values()) - .filter(it => it.data.flags.core?.statusId == id); - this._deleteStatusEffects(effects); + const ids = Array.from(this.effects?.values()) + .filter(it => it.data.flags.core?.statusId == id) + .map(it => it.id); + this.deleteEmbeddedDocuments('ActiveEffect', ids); } /* -------------------------------------------- */ deleteStatusEffect(effect) { - const toDelete = Array.from(this.effects?.values()) - .filter(it => StatusEffects.statusId(it.data) == StatusEffects.statusId(effect)); - this._deleteStatusEffects(toDelete); - } - - /* -------------------------------------------- */ - _deleteStatusEffects(effects) { - const ids = effects.map(it => it.id); + const ids = Array.from(this.effects?.values()) + .filter(it => StatusEffects.statusId(it.data) == StatusEffects.statusId(effect)) + .map(it => it.id); this.deleteEmbeddedDocuments('ActiveEffect', ids); } @@ -3130,9 +3131,9 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async addStatusEffect(statusEffect) { - this.deleteStatusEffectById(statusEffect.id); const effet = duplicate(statusEffect); - effet["flags.core.statusId"] = effet.id; + this.deleteStatusEffectById(effet.id); + effet.flags.core.statusId = effet.id; await this.createEmbeddedDocuments('ActiveEffect', [effet]); } From 7f75361a08d232e5d9b575637689b11715879d6b Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Mon, 29 Mar 2021 20:11:32 +0200 Subject: [PATCH 07/10] Corrections de hooks --- module/actor.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/module/actor.js b/module/actor.js index 173e375f..e0fbc1d5 100644 --- a/module/actor.js +++ b/module/actor.js @@ -38,10 +38,10 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ static init() { Hooks.on("deleteActiveEffect", (effect, options, userId) => RdDActor.getParentActor(effect)?.onDeleteActiveEffect(effect, options)); - Hooks.on("createOwnedItem", (actor, item, options, id) => actor.onCreateOwnedItem(item, options, id)); - Hooks.on("deleteOwnedItem", (actor, item, options, id) => actor.onDeleteOwnedItem(item, options, id)); - Hooks.on("updateActor", (actor, update, options, actorId) => actor.onUpdateActor(update, options, actorId)); Hooks.on("createActiveEffect", (effect, options, userId) => RdDActor.getParentActor(effect)?.onCreateActiveEffect(effect, options)); + Hooks.on("createOwnedItem", (item, options, id) => RdDActor.getParentActor(item)?.onCreateOwnedItem(item, options, id)); + Hooks.on("deleteOwnedItem", (item, options, id) => RdDActor.getParentActor(item)?.onDeleteOwnedItem(item, options, id)); + Hooks.on("updateActor", (actor, change, options, actorId) => actor.onUpdateActor(change, options, actorId)); } static getParentActor(document){ From 0cd4c7c15895851df1b5213db36aa67e7f6747e5 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Mon, 29 Mar 2021 23:41:08 +0200 Subject: [PATCH 08/10] Avancement OwnedItems et Items MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - remplacer xxxOwnedItems par xxxEmbeddedDocuments - corrections des accès aux items vs itemData - corrections cases spéciales TMR et effets draconiques - correction monnaies/payer --- module/actor-entite-sheet.js | 4 +- module/actor-vehicule-sheet.js | 2 +- module/actor.js | 97 ++++++++++++++-------------- module/hook-renderChatLog.js | 6 +- module/item-sort.js | 2 +- module/rdd-combat.js | 14 ++-- module/rdd-main.js | 6 +- module/rdd-tmr-dialog.js | 8 ++- module/rdd-utility.js | 13 +++- module/tmr/conquete.js | 6 +- module/tmr/debordement.js | 2 +- module/tmr/desorientation.js | 2 +- module/tmr/draconique.js | 49 ++++++++------ module/tmr/fermeture-cites.js | 2 +- module/tmr/pelerinage.js | 4 +- module/tmr/periple.js | 2 +- module/tmr/pont-impraticable.js | 2 +- module/tmr/present-cites.js | 4 +- module/tmr/quete-eaux.js | 2 +- module/tmr/reserve-extensible.js | 2 +- module/tmr/terre-attache.js | 2 +- module/tmr/trou-noir.js | 2 +- module/tmr/urgence-draconique.js | 8 +-- system.json | 2 +- templates/item-casetmr-sheet.html | 2 +- templates/item-jeu-sheet.html | 2 +- templates/item-meditation-sheet.html | 8 +-- templates/item-oeuvre-sheet.html | 4 +- templates/post-item.html | 2 +- 29 files changed, 136 insertions(+), 125 deletions(-) diff --git a/module/actor-entite-sheet.js b/module/actor-entite-sheet.js index 41f444c0..b7a02afd 100644 --- a/module/actor-entite-sheet.js +++ b/module/actor-entite-sheet.js @@ -71,14 +71,14 @@ export class RdDActorEntiteSheet extends ActorSheet { // Update Inventory Item html.find('.item-edit').click(ev => { const li = $(ev.currentTarget).parents(".item"); - const item = this.actor.getOwnedItem(li.data("itemId")); + const item = this.actor.getEmbeddedDocuments('Item', li.data("itemId")); item.sheet.render(true); }); // Delete Inventory Item html.find('.item-delete').click(ev => { const li = $(ev.currentTarget).parents(".item"); - this.actor.deleteOwnedItem(li.data("itemId")); + this.actor.deleteEmbeddedDocuments('Item', [li.data("itemId")]); li.slideUp(200, () => this.render(false)); }); diff --git a/module/actor-vehicule-sheet.js b/module/actor-vehicule-sheet.js index 10ef7aaf..c6c62235 100644 --- a/module/actor-vehicule-sheet.js +++ b/module/actor-vehicule-sheet.js @@ -87,7 +87,7 @@ export class RdDActorVehiculeSheet extends ActorSheet { // Update Inventory Item html.find('.item-edit').click(ev => { const li = $(ev.currentTarget).parents(".item"); - const item = this.actor.getOwnedItem(li.data("itemId")); + const item = this.actor.getEmbeddedDocuments('Item', li.data("itemId")); item.sheet.render(true); }); // Delete Inventory Item diff --git a/module/actor.js b/module/actor.js index e0fbc1d5..6822a9d6 100644 --- a/module/actor.js +++ b/module/actor.js @@ -39,12 +39,14 @@ export class RdDActor extends Actor { static init() { Hooks.on("deleteActiveEffect", (effect, options, userId) => RdDActor.getParentActor(effect)?.onDeleteActiveEffect(effect, options)); Hooks.on("createActiveEffect", (effect, options, userId) => RdDActor.getParentActor(effect)?.onCreateActiveEffect(effect, options)); - Hooks.on("createOwnedItem", (item, options, id) => RdDActor.getParentActor(item)?.onCreateOwnedItem(item, options, id)); - Hooks.on("deleteOwnedItem", (item, options, id) => RdDActor.getParentActor(item)?.onDeleteOwnedItem(item, options, id)); + + Hooks.on("preUpdateItem", (item, change, options, id) => RdDActor.getParentActor(item)?.onPreUpdateItem(item, change, options, id)); + Hooks.on("createItem", (item, options, id) => RdDActor.getParentActor(item)?.onCreateItem(item, options, id)); + Hooks.on("deleteItem", (item, options, id) => RdDActor.getParentActor(item)?.onDeleteItem(item, options, id)); Hooks.on("updateActor", (actor, change, options, actorId) => actor.onUpdateActor(change, options, actorId)); } - static getParentActor(document){ + static getParentActor(document) { return document?.parent instanceof Actor ? document.parent : undefined } @@ -241,10 +243,10 @@ export class RdDActor extends Actor { } /* -------------------------------------------- */ getObjet(id) { - return id ? this.items.find(it => it._id == id) : undefined; + return id ? this.data.items.find(it => it.id == id) : undefined; } - getItemOfType(type, id) { - return id ? this.items.find(it => it._id == id && it.type == type) : undefined; + getItemOfType(id, type) { + return id ? this.data.items.find(it => it.id == id && it.type == type) : undefined; } getMonnaie(id) { return this.getItemOfType(id, 'monnaie'); @@ -266,7 +268,7 @@ export class RdDActor extends Actor { return this.getItemOfType(id, 'musique'); } getOeuvre(id, type = 'oeuvre') { - return this.getItemOfType(type, id); + return this.getItemOfType(id, type); } getJeu(id) { return this.getItemOfType(id, 'jeu'); @@ -685,7 +687,7 @@ export class RdDActor extends Actor { else update['data.carac_value'] = compValue; //console.log(update); - const updated = await this.updateEmbeddedDocuments("Item", update); // Updates one EmbeddedEntity + const updated = await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity } } @@ -706,7 +708,7 @@ export class RdDActor extends Actor { }); } const update = { _id: comp.id, 'data.niveau': nouveauNiveau }; - await this.updateEmbeddedDocuments("Item", update); // Updates one EmbeddedEntity + await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity } else { console.log("Competence not found", compName); } @@ -719,7 +721,7 @@ export class RdDActor extends Actor { compValue = compValue ?? 0; this.checkCompetenceXP(compName, compValue); const update = { _id: comp.id, 'data.xp': compValue }; - await this.updateEmbeddedDocuments("OwnedItem", update); // Updates one EmbeddedEntity + await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity } else { console.log("Competence not found", compName); } @@ -732,7 +734,7 @@ export class RdDActor extends Actor { if (comp) { compValue = compValue ?? 0; const update = { _id: comp.id, 'data.xp_sort': compValue }; - await this.updateEmbeddedDocuments("OwnedItem", update); // Updates one EmbeddedEntity + await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity } else { console.log("Competence not found", compName); } @@ -744,7 +746,7 @@ export class RdDActor extends Actor { if (comp) { compValue = compValue ?? 0; const update = { _id: comp.id, 'data.niveau_archetype': compValue }; - await this.updateEmbeddedDocuments("OwnedItem", update); // Updates one EmbeddedEntity + await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity } else { console.log("Competence not found", compName); } @@ -860,10 +862,7 @@ export class RdDActor extends Actor { let list = []; list.push({ id: itemId, conteneurId: undefined }); // Init list this.buildSubConteneurObjetList(itemId, list); - //console.log("List to delete", list); - for (let item of list) { - await this.deleteOwnedItem(item.id); - } + await this.deleteEmbeddedDocuments('Item', list.map(it => it.id)); } /* -------------------------------------------- */ @@ -880,7 +879,7 @@ export class RdDActor extends Actor { contenu.splice(index, 1); index = contenu.indexOf(itemId); } - await this.updateEmbeddedDocuments("OwnedItem", data2use); + await this.updateEmbeddedDocuments('Item', [data2use]); } } @@ -892,7 +891,7 @@ export class RdDActor extends Actor { if (conteneur?.type == 'conteneur') { let data2use = duplicate(Misc.data(conteneur)); data2use.data.contenu.push(itemId); - await this.updateEmbeddedDocuments("OwnedItem", data2use); + await this.updateEmbeddedDocuments('Item', [data2use]); } } @@ -907,7 +906,7 @@ export class RdDActor extends Actor { } } if (conteneurFixedList.length > 0) - await this.updateOwnedItem(conteneurFixedList); + await this.updateEmbeddedDocuments('Item', conteneurFixedList); } /* -------------------------------------------- */ @@ -935,11 +934,11 @@ export class RdDActor extends Actor { console.log('New conteneur filling!', newConteneur, newItemId, item); let contenu = duplicate(newConteneur.data.contenu); contenu.push(newItemId); - await this.updateOwnedItem({ _id: newConteneurId, 'data.contenu': contenu }); + await this.updateEmbeddedDocuments('Item', [{ _id: newConteneurId, 'data.contenu': contenu }]); } } for (let item of itemsList) { - await sourceActor.deleteOwnedItem(item.id); + await sourceActor.deleteEmbeddedDocuments('Item', [item.id]); } } @@ -1837,7 +1836,7 @@ export class RdDActor extends Actor { if (rencSpecial) { rencSpecial = duplicate(rencSpecial); // To keep it if (rencSpecial.type != 'souffle') { - this.deleteOwnedItem(rencSpecial._id); // Suppression dans la liste des queues + this.deleteEmbeddedDocuments('Item', [rencSpecial._id]); // Suppression dans la liste des queues addMsg = " La queue a été supprimée de votre fiche automatiquement"; } else { addMsg = " Vous devez gérer manuellement le décompte de mauvaises rencontres manuellement."; @@ -2075,7 +2074,7 @@ export class RdDActor extends Actor { async _tacheResult(rollData) { // Mise à jour de la tache rollData.tache.data.points_de_tache_courant += rollData.rolled.ptTache; - this.updateEmbeddedDocuments("OwnedItem", rollData.tache); + this.updateEmbeddedDocuments('Item', [rollData.tache]); this.santeIncDec("fatigue", rollData.tache.data.fatigue); RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-tache.html'); @@ -2084,7 +2083,7 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ _tacheETotal(rollData) { rollData.tache.data.difficulte--; - this.updateEmbeddedDocuments("OwnedItem", rollData.tache); + this.updateEmbeddedDocuments('Item', [rollData.tache]); } /* -------------------------------------------- */ @@ -2249,7 +2248,7 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ _meditationETotal(meditationData) { meditationData.meditation.data.malus--; - this.updateEmbeddedDocuments("OwnedItem", meditationData.meditation); + this.updateEmbeddedDocuments('Item', [meditationData.meditation]); } /* -------------------------------------------- */ @@ -2352,7 +2351,7 @@ export class RdDActor extends Actor { xpComp = xp - xpCarac; competence = duplicate(competence); competence.data.xp = Misc.toInt(competence.data.xp) + xpComp; - await this.updateEmbeddedDocuments("OwnedItem", competence); + await this.updateEmbeddedDocuments('Item', [competence]); } else { xpCarac = Math.max(xpCarac, 1); } @@ -2386,12 +2385,12 @@ export class RdDActor extends Actor { name: "Nombre Astral", type: "nombreastral", data: { value: data.nbAstral, istrue: data.isvalid, jourindex: Number(data.date), jourlabel: game.system.rdd.calendrier.getDateFromIndex(Number(data.date)) } }; - await this.createEmbeddedDocuments("OwnedItem", [item]); + await this.createEmbeddedDocuments("Item", [item]); // Suppression des anciens nombres astraux let toDelete = this.data.items.filter(it => it.data.jourindex < game.system.rdd.calendrier.getCurrentDayIndex()); const deletions = toDelete.map(it => it._id); - await this.deleteEmbeddedDocuments("OwnedItem", deletions); + await this.deleteEmbeddedDocuments("Item", deletions); // Affichage Dialog this.astrologieNombresAstraux(); @@ -2533,7 +2532,7 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ getArmeParade(armeParadeId) { - const item = armeParadeId ? this.getOwnedItem(armeParadeId) : undefined; + const item = armeParadeId ? this.getEmbeddedDocuments('Item', armeParadeId) : undefined; return RdDItemArme.getArmeData(item); } @@ -2550,12 +2549,12 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async equiperObjet(itemID) { - let item = this.getOwnedItem(itemID); + let item = this.getEmbeddedDocuments('Item', itemID); if (item?.data?.data) { let itemData = Misc.itemData(item); const isEquipe = !itemData.data.equipe; let update = { _id: item._id, "data.equipe": isEquipe }; - await this.updateEmbeddedDocuments("OwnedItem", update); + await this.updateEmbeddedDocuments('Item', [update]); this.computeEncombrementTotalEtMalusArmure(); // Mise à jour encombrement this.computePrixTotalEquipement(); // Mis à jour du prix total de l'équipement if (isEquipe) @@ -2595,7 +2594,7 @@ export class RdDActor extends Actor { if (!ReglesOptionelles.isUsing('deteriorationArmure')) { return; } - let itemData = duplicate(Misc.itemData(item)); + let itemData = duplicate(Misc.data(item)); itemData.data.deterioration = (itemData.data.deterioration ?? 0) + dmg; if (itemData.data.deterioration >= 10) { itemData.data.deterioration = 0; @@ -2612,7 +2611,7 @@ export class RdDActor extends Actor { } ChatMessage.create({ content: "Votre armure s'est détériorée, elle protège maintenant de " + itemData.data.protection }); } - this.updateEmbeddedDocuments("OwnedItem", itemData); + this.updateEmbeddedDocuments('Item', [itemData]); } /* -------------------------------------------- */ @@ -2857,17 +2856,18 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async optimizeArgent(sumDenier, monnaies) { - let parValeur = Misc.classifyFirst(monnaies, it => it.data.valeur_deniers); + let parValeur = Misc.classifyFirst(monnaies, it => Misc.templateData(it).valeur_deniers); let fortune = { 1000: Math.floor(sumDenier / 1000), // or 100: Math.floor(sumDenier / 100) % 10, // argent 10: Math.floor(sumDenier / 10) % 10, // bronze 1: sumDenier % 10 // étain } + let updates = [] for (const [valeur, nombre] of Object.entries(fortune)) { - let piece = parValeur[valeur]; - await this.updateEmbeddedDocuments("OwnedItem", { _id: piece._id, 'data.quantite': nombre }); + updates.push( { _id: parValeur[valeur]._id, 'data.quantite': nombre }); } + await this.updateEmbeddedDocuments('Item', updates); } /* -------------------------------------------- */ @@ -2881,8 +2881,8 @@ export class RdDActor extends Actor { sumDenier = Number(sumDenier); let denierDisponible = 0; - for (let piece of monnaies) { - denierDisponible += piece.data.valeur_deniers * Number(piece.data.quantite); + for (let pieceData of monnaies.map(m => Misc.data(m))) { + denierDisponible += pieceData.data.valeur_deniers * Number(pieceData.data.quantite); } console.log("DENIER", game.user.character, sumDenier, denierDisponible); @@ -2916,7 +2916,7 @@ export class RdDActor extends Actor { let monnaie = this.getMonnaie(id); if (monnaie) { const quantite = Math.max(0, Misc.templateData(monnaie).quantite + value); - await this.updateEmbeddedDocuments("OwnedItem", { _id: monnaie.id, 'data.quantite': quantite }); + await this.updateEmbeddedDocuments('Item', [{ _id: monnaie.id, 'data.quantite': quantite }]); } } @@ -3138,15 +3138,7 @@ export class RdDActor extends Actor { } /* -------------------------------------------- */ - async updateEmbeddedDocuments(embeddedName, data, options) { - if (data?.type == 'competence' && data['data.defaut_carac'] && data['data.xp']) { // C'est une compétence - this.checkCompetenceXP(data['name'], data['data.xp']); - } - return super.updateEmbeddedDocuments(embeddedName, [data], options); - } - - /* -------------------------------------------- */ - async onCreateOwnedItem(item, options, id) { + async onCreateItem(item, options, id) { switch (item.type) { case 'tete': case 'queue': @@ -3157,7 +3149,14 @@ export class RdDActor extends Actor { } } - async onDeleteOwnedItem(item, options, id) { + async onPreUpdateItem(item, change, options, id) { + const itemData = Misc.data(item); + if (itemData.type == 'competence' && itemData.data.defaut_carac && itemData.data.xp) { + await this.checkCompetenceXP(itemData.name, itemData.data.xp); + } + } + + async onDeleteItem(item, options, id) { switch (item.type) { case 'tete': case 'queue': diff --git a/module/hook-renderChatLog.js b/module/hook-renderChatLog.js index c34d03d8..64dec8c0 100644 --- a/module/hook-renderChatLog.js +++ b/module/hook-renderChatLog.js @@ -3,7 +3,7 @@ import { RdDUtility } from "./rdd-utility.js"; /* -------------------------------------------- */ // Activate chat listeners defined -Hooks.on('renderChatLog', (log, html, data) => { - RdDUtility.chatListeners(html); -}); +// Hooks.on('renderChatLog', (log, html, data) => { +// RdDUtility.chatListeners(html); +// }); diff --git a/module/item-sort.js b/module/item-sort.js index 3c0afa72..eeeaf634 100644 --- a/module/item-sort.js +++ b/module/item-sort.js @@ -106,7 +106,7 @@ export class RdDItemSort extends Item { // Sauvegarde/update let bonuscase = StringList.toString(); //console.log("Bonus cae :", bonuscase); - actor.updateEmbeddedDocuments("OwnedItem", { _id: sort._id, 'data.bonuscase': bonuscase } ); + actor.updateEmbeddedDocuments('Item', [{ _id: sort._id, 'data.bonuscase': bonuscase }] ); } /* -------------------------------------------- */ diff --git a/module/rdd-combat.js b/module/rdd-combat.js index 7f53d402..f9788418 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -104,7 +104,7 @@ export class RdDCombatManager extends Combat { const roll = super._getInitiativeRoll(c, rollFormula); if (roll.total <= 0) roll.total = 0.00; console.log("Compute init for", rollFormula, roll.total); - await this.updateEmbeddedDocuments("Combatant", { _id: c._id, initiative: roll.total }); + await this.updateEmbeddedDocuments("Combatant", [{ _id: c._id, initiative: roll.total }]); // Send a chat message let rollMode = messageOptions.rollMode || game.settings.get("core", "rollMode"); @@ -334,8 +334,8 @@ export class RdDCombat { static init() { this.initStorePasseArmes(); - Hooks.on("updateCombat", (combat, data) => { RdDCombat.onUpdateCombat(combat, data) }); - Hooks.on("preDeleteCombat", (combat, options) => { RdDCombat.onPreDeleteCombat(combat, options); }); + Hooks.on("updateCombat", (combat, change, options, userId) => { RdDCombat.onUpdateCombat(combat, change, options, userId) }); + Hooks.on("preDeleteCombat", (combat, options, userId) => { RdDCombat.onPreDeleteCombat(combat, options, userId); }); } /* -------------------------------------------- */ @@ -357,14 +357,14 @@ export class RdDCombat { } /* -------------------------------------------- */ - static onUpdateCombat(combat, data) { + static onUpdateCombat(combat, change, options, userId) { if (combat.data.round != 0 && combat.turns && combat.data.active) { RdDCombat.combatNouveauTour(combat); } } /* -------------------------------------------- */ - static onPreDeleteCombat(combat, options) { + static onPreDeleteCombat(combat, options, userId) { if (game.user.isGM) { combat.cleanItemUse(); ChatUtility.removeChatMessageContaining(`
    `) @@ -1130,7 +1130,7 @@ export class RdDCombat { resistance -= perteResistance; defenderRoll.show.deteriorationArme = resistance <= 0 ? 'brise' : 'perte'; defenderRoll.show.perteResistance = perteResistance; - this.defender.updateEmbeddedDocuments("OwnedItem", { _id: defenderRoll.arme._id, 'data.resistance': resistance }); + this.defender.updateEmbeddedDocuments('Item', [{ _id: defenderRoll.arme._id, 'data.resistance': resistance }]); } } } else { @@ -1147,7 +1147,7 @@ export class RdDCombat { resistance -= dmg; defenderRoll.show.deteriorationArme = resistance <= 0 ? 'brise' : 'perte'; defenderRoll.show.perteResistance = dmg; - this.defender.updateEmbeddedDocuments("OwnedItem", { _id: defenderRoll.arme._id, 'data.resistance': resistance }); + this.defender.updateEmbeddedDocuments('Item', [{ _id: defenderRoll.arme._id, 'data.resistance': resistance }]); } } // Si l'arme de parade n'est pas un bouclier, jet de désarmement (p.132) diff --git a/module/rdd-main.js b/module/rdd-main.js index 0f147060..8802a03e 100644 --- a/module/rdd-main.js +++ b/module/rdd-main.js @@ -153,6 +153,7 @@ Hooks.once("init", async function () { CONFIG.Combat.documentClass = RdDCombatManager; // préparation des différents modules + RdDUtility.init(); RdDCommands.init(); RdDCombat.init(); RdDCombatManager.init(), @@ -224,8 +225,3 @@ Hooks.on("chatMessage", (html, content, msg) => { return true; }); - -/* -------------------------------------------- */ -Hooks.on("renderChatMessage", async (app, html, msg) => { - RdDUtility.onRenderChatMessage(app, html, msg); -}); diff --git a/module/rdd-tmr-dialog.js b/module/rdd-tmr-dialog.js index fc4932ce..7c9d6a21 100644 --- a/module/rdd-tmr-dialog.js +++ b/module/rdd-tmr-dialog.js @@ -130,14 +130,16 @@ export class RdDTMRDialog extends Dialog { return EffetsDraconiques.rencontre.token(this.pixiTMR, rencontre, () => rencontre.coord); } _tokenCaseSpeciale(casetmr) { - const draconique = Draconique.get(casetmr.data.specific); - return draconique?.token(this.pixiTMR, casetmr, () => casetmr.data.coord); + const caseData = Misc.data(casetmr); + const draconique = Draconique.get(caseData.data.specific); + return draconique?.token(this.pixiTMR, caseData, () => caseData.data.coord); } _tokenSortEnReserve(sortEnReserve) { return EffetsDraconiques.sortReserve.token(this.pixiTMR, sortEnReserve.sort, () => sortEnReserve.coord); } _tokenDemiReve() { - return EffetsDraconiques.demiReve.token(this.pixiTMR, this.actor, () => Misc.data(this.actor).data.reve.tmrpos.coord); + const actorData = Misc.data(this.actor); + return EffetsDraconiques.demiReve.token(this.pixiTMR, actorData, () => actorData.data.reve.tmrpos.coord); } _updateDemiReve() { diff --git a/module/rdd-utility.js b/module/rdd-utility.js index 502447cf..743dde39 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -92,6 +92,13 @@ const definitionsEncaissement = { /* -------------------------------------------- */ export class RdDUtility { + + /* -------------------------------------------- */ + static async init() { + Hooks.on("renderChatMessage", async (app, html, msg) => RdDUtility.onRenderChatMessage(app, html, msg)); + Hooks.on('renderChatLog', (log, html, data) => RdDUtility.chatListeners(html)); + } + /* -------------------------------------------- */ static async preloadHandlebarsTemplates() { const templatePaths = [ @@ -544,7 +551,7 @@ export class RdDUtility { actor.tmrApp.lancerSortEnReserve(coord, sortId); }); // Gestion du bouton payer - html.on("click", '#payer-button', event => { + html.on("click", '.payer-button', event => { let sumdenier = event.currentTarget.attributes['data-somme-denier'].value; let quantite = 1; if (event.currentTarget.attributes['data-quantite']) { @@ -595,7 +602,7 @@ export class RdDUtility { let sumtotald = sumd + (sums * 100); let msgPayer = "La somme de " + sums + " Sols et " + sumd + " Deniers est à payer, cliquer sur le lien ci-dessous si besoin.
    "; - msgPayer += "Payer" + msgPayer += "Payer" ChatMessage.create({ content: msgPayer }); } @@ -658,7 +665,7 @@ export class RdDUtility { label: "Supprimer l'objet", callback: () => { console.log("Delete : ", itemId); - actorSheet.actor.deleteOwnedItem(itemId); + actorSheet.actor.deleteEmbeddedDocuments('Item', [itemId]); li.slideUp(200, () => actorSheet.render(false)); } }, diff --git a/module/tmr/conquete.js b/module/tmr/conquete.js index ba7dffeb..09bf1eef 100644 --- a/module/tmr/conquete.js +++ b/module/tmr/conquete.js @@ -29,14 +29,14 @@ export class Conquete extends Draconique { } async _creerConquete(actor, queue) { - let existants = actor.data.items.filter(it => this.isCase(it)).map(it => it.data.coord); + let existants = actor.data.items.filter(it => this.isCase(it)).map(it => Misc.data(it).data.coord); let possibles = TMRUtility.filterTMR(tmr => !TMRUtility.isCaseHumide(tmr) && !existants.includes(tmr.coord)); let conquete = Misc.rollOneOf(possibles); - await this.createCaseTmr(actor, 'Conquête: ' + conquete.label, conquete, queue._id); + await this.createCaseTmr(actor, 'Conquête: ' + conquete.label, conquete, queue.id); } async onActorDeleteCaseTmr(actor, casetmr) { - await actor.deleteOwnedItem(casetmr.data.sourceid); + await actor.deleteEmbeddedDocuments('Item', [casetmr.data.sourceid]); } } diff --git a/module/tmr/debordement.js b/module/tmr/debordement.js index 21e5a5fd..90362f29 100644 --- a/module/tmr/debordement.js +++ b/module/tmr/debordement.js @@ -14,7 +14,7 @@ export class Debordement extends Draconique { async onActorCreateOwned(actor, souffle) { const existants = actor.data.items.filter(it => this.isCase(it)).map(it => it.data.coord); const tmr = TMRUtility.getTMRAleatoire(it => !(TMRUtility.isCaseHumide(it) || existants.includes(it.coord))); - await this.createCaseTmr(actor, 'Debordement: ' + tmr.label, tmr, souffle._id); + await this.createCaseTmr(actor, 'Debordement: ' + tmr.label, tmr, souffle.id); } code() { return 'debordement' } diff --git a/module/tmr/desorientation.js b/module/tmr/desorientation.js index 1dcec96a..0fc1d46c 100644 --- a/module/tmr/desorientation.js +++ b/module/tmr/desorientation.js @@ -43,7 +43,7 @@ export class Desorientation extends Draconique { const existants = actor.data.items.filter(it => this.isCase(it)).map(it => it.data.coord); let tmrs = TMRUtility.filterTMR(it => it.type == type && !existants.includes(it.coord)); for (let tmr of tmrs) { - await this.createCaseTmr(actor, 'Désorientation: ' + tmr.label, tmr, souffle._id); + await this.createCaseTmr(actor, 'Désorientation: ' + tmr.label, tmr, souffle.id); } } diff --git a/module/tmr/draconique.js b/module/tmr/draconique.js index 6061d7d9..9ca5848e 100644 --- a/module/tmr/draconique.js +++ b/module/tmr/draconique.js @@ -1,3 +1,4 @@ +import { Misc } from "../misc.js"; import { TMRUtility } from "../tmr-utility.js"; import { PixiTMR } from "./pixi-tmr.js"; @@ -8,11 +9,11 @@ const registeredEffects = [ * Définition des informations d'une "draconique" (queue, ombre, tête, souffle) qui influence les TMR */ export class Draconique { - static isCaseTMR(element) { return element.type == 'casetmr'; } - static isQueueDragon(element) { return element.type == 'queue' || element.type == 'ombre'; } - static isSouffleDragon(element) { return element.type == 'souffle'; } - static isTeteDragon(element) { return element.type == 'tete'; } - static isQueueSouffle(it) { return Draconique.isQueueDragon(it) || Draconique.isSouffleDragon(it); } + static isCaseTMR(itemData) { return itemData.type == 'casetmr'; } + static isQueueDragon(itemData) { return itemData.type == 'queue' || itemData.type == 'ombre'; } + static isSouffleDragon(itemData) { return itemData.type == 'souffle'; } + static isTeteDragon(itemData) { return itemData.type == 'tete'; } + static isQueueSouffle(itemData) { return Draconique.isQueueDragon(itemData) || Draconique.isSouffleDragon(itemData); } tmrLabel(linkData) { return TMRUtility.getTMRLabel(linkData.data.coord); } @@ -37,7 +38,8 @@ export class Draconique { * @returns true si l'item correspond */ match(item) { - return Draconique.isQueueDragon(item) || Draconique.isSouffleDragon(item) || Draconique.isTeteDragon(item); + const itemData = Misc.data(item); + return Draconique.isQueueDragon(itemData) || Draconique.isSouffleDragon(itemData) || Draconique.isTeteDragon(itemData); } /** @@ -110,35 +112,40 @@ export class Draconique { /** * - * @param {*} it un item à tester + * @param {*} item un item à tester * @param {*} coord les coordonnées d'une case. Si undefined toute case du type correspondra, */ - isCase(it, coord = undefined) { - return Draconique.isCaseTMR(it) && it.data.specific == this.code() && (coord ? it.data.coord == coord : true); + isCase(item, coord = undefined) { + const itemData = Misc.data(item); + return Draconique.isCaseTMR(itemData) && itemData.data.specific == this.code() && (coord ? itemData.data.coord == coord : true); } - + find(list, coord = undefined) { - return list.find(c => this.isCase(c, coord)); + return list.find(c => this.isCase(Misc.data(c), coord)); } - + async createCaseTmr(actor, label, tmr, sourceId = undefined) { - await actor.createEmbeddedDocuments('Item',[{ - name: label, type: 'casetmr', img: this.img(), _id: randomID(16), + const casetmrData = { + name: label, type: 'casetmr', img: this.img(), data: { coord: tmr.coord, specific: this.code(), sourceid: sourceId } - }]); + }; + await actor.createEmbeddedDocuments('Item', [casetmrData]); } - + async deleteCasesTmr(actor, draconique) { - let caseTmrs = actor.data.items.filter(it => this.isCase(it) && it.data.sourceid == draconique._id); - for (let casetmr of caseTmrs) { - await actor.deleteOwnedItem(casetmr._id); - } + let caseTmrs = actor.data.items.filter(it => this.isCaseForSource(it, draconique)); + await actor.deleteEmbeddedDocuments('Item', caseTmrs.map(it => it.id)); + } + + isCaseForSource(item, draconique) { + const itemData = Misc.data(item); + return Draconique.isCaseTMR(itemData) && itemData.data.specific == this.code() && itemData.data.sourceid == draconique.id; } async onVisiteSupprimer(actor, tmr, onRemoveToken) { let existants = actor.data.items.filter(it => this.isCase(it, tmr.coord)); + await actor.deleteEmbeddedDocuments('Item', existants.map(it => it.id)); for (let casetmr of existants) { - await actor.deleteOwnedItem(casetmr._id); onRemoveToken(tmr, casetmr); } } diff --git a/module/tmr/fermeture-cites.js b/module/tmr/fermeture-cites.js index 8d695ae6..457d4a7b 100644 --- a/module/tmr/fermeture-cites.js +++ b/module/tmr/fermeture-cites.js @@ -32,7 +32,7 @@ export class FermetureCites extends Draconique { let existants = actor.data.items.filter(it => this.isCase(it)).map(it => it.data.coord); let ouvertes = TMRUtility.filterTMR(it => it.type == 'cite' && !existants.includes(it.coord)); for (let tmr of ouvertes) { - await this.createCaseTmr(actor, 'Fermeture: ' + tmr.label, tmr, souffle._id); + await this.createCaseTmr(actor, 'Fermeture: ' + tmr.label, tmr, souffle.id); } } } diff --git a/module/tmr/pelerinage.js b/module/tmr/pelerinage.js index ec9e4010..6a950478 100644 --- a/module/tmr/pelerinage.js +++ b/module/tmr/pelerinage.js @@ -14,7 +14,7 @@ export class Pelerinage extends Draconique { async onActorCreateOwned(actor, queue) { let tmr = TMRUtility.getTMRAleatoire(); - await this.createCaseTmr(actor, 'Pèlerinage: ' + tmr.label, tmr, queue._id); + await this.createCaseTmr(actor, 'Pèlerinage: ' + tmr.label, tmr, queue.id); } @@ -32,7 +32,7 @@ export class Pelerinage extends Draconique { } async onActorDeleteCaseTmr(actor, casetmr) { - await actor.deleteOwnedItem(casetmr.data.sourceid); + await actor.deleteEmbeddedDocuments('Item', [casetmr.data.sourceid]); } } diff --git a/module/tmr/periple.js b/module/tmr/periple.js index feba1a2b..30434196 100644 --- a/module/tmr/periple.js +++ b/module/tmr/periple.js @@ -16,7 +16,7 @@ export class Periple extends Draconique { let terrain = new Roll("1d2").evaluate().total == 1 ? 'sanctuaire' : 'necropole'; let tmrs = TMRUtility.getListTMR(terrain); for (let tmr of tmrs) { - await this.createCaseTmr(actor, 'Périple: ' + tmr.label, tmr, souffle._id); + await this.createCaseTmr(actor, 'Périple: ' + tmr.label, tmr, souffle.id); } } diff --git a/module/tmr/pont-impraticable.js b/module/tmr/pont-impraticable.js index 8470a939..1bde95fd 100644 --- a/module/tmr/pont-impraticable.js +++ b/module/tmr/pont-impraticable.js @@ -14,7 +14,7 @@ export class PontImpraticable extends Draconique { async onActorCreateOwned(actor, souffle) { const ponts = TMRUtility.getListTMR('pont'); for (let tmr of ponts) { - await this.createCaseTmr(actor, 'Pont impraticable: ' + tmr.label, tmr, souffle._id); + await this.createCaseTmr(actor, 'Pont impraticable: ' + tmr.label, tmr, souffle.id); } } diff --git a/module/tmr/present-cites.js b/module/tmr/present-cites.js index c6967b94..d3c992a7 100644 --- a/module/tmr/present-cites.js +++ b/module/tmr/present-cites.js @@ -40,7 +40,7 @@ export class PresentCites extends Draconique { else { let cites = TMRUtility.filterTMR(it => it.type == 'cite'); for (let tmr of cites) { - await this.createCaseTmr(actor, 'Présent: ' + tmr.label, tmr, tete._id); + await this.createCaseTmr(actor, 'Présent: ' + tmr.label, tmr, tete.id); } } } @@ -60,6 +60,6 @@ export class PresentCites extends Draconique { } async ouvrirLePresent(actor, casetmr) { - await actor.deleteOwnedItem(casetmr._id); + await actor.deleteEmbeddedDocuments('Item', [casetmr.id]); } } diff --git a/module/tmr/quete-eaux.js b/module/tmr/quete-eaux.js index df9866cd..95f92e9c 100644 --- a/module/tmr/quete-eaux.js +++ b/module/tmr/quete-eaux.js @@ -11,7 +11,7 @@ export class QueteEaux extends Draconique { match(item) { return Draconique.isTeteDragon(item) && Grammar.toLowerCaseNoAccent(item.name).includes("quete des eaux"); } manualMessage() { return "Vous devrez re-configurer votre Quête des Eaux une fois un lac ou marais vaincu" } async onActorCreateOwned(actor, tete) { - await this.createCaseTmr(actor, "Quête des eaux à déterminer", { coord: 'A0' }, tete._id); + await this.createCaseTmr(actor, "Quête des eaux à déterminer", { coord: 'A0' }, tete.id); } code() { return 'maitrisee' } diff --git a/module/tmr/reserve-extensible.js b/module/tmr/reserve-extensible.js index cc51420e..6ee92d7f 100644 --- a/module/tmr/reserve-extensible.js +++ b/module/tmr/reserve-extensible.js @@ -13,7 +13,7 @@ export class ReserveExtensible extends Draconique { async onActorCreateOwned(actor, tete) { const existants = actor.data.items.filter(it => this.isCase(it)).map(it => it.data.coord); const tmr = TMRUtility.getTMRAleatoire(it => !(it.type == 'fleuve' || existants.includes(it.coord))); - await this.createCaseTmr(actor, "Nouvelle Réserve extensible", tmr, tete._id); + await this.createCaseTmr(actor, "Nouvelle Réserve extensible", tmr, tete.id); } code() { return 'reserve_extensible' } diff --git a/module/tmr/terre-attache.js b/module/tmr/terre-attache.js index 2a6fb686..c5c85ef9 100644 --- a/module/tmr/terre-attache.js +++ b/module/tmr/terre-attache.js @@ -12,7 +12,7 @@ export class TerreAttache extends Draconique { manualMessage() { return "Vous pouvez re-configurer votre Terre d'Attache" } async onActorCreateOwned(actor, tete) { - await this.createCaseTmr(actor, "Terre d'attache à déterminer", { coord: 'A0' }, tete._id); + await this.createCaseTmr(actor, "Terre d'attache à déterminer", { coord: 'A0' }, tete.id); } code() { return 'attache' } diff --git a/module/tmr/trou-noir.js b/module/tmr/trou-noir.js index 10b86012..95a09e04 100644 --- a/module/tmr/trou-noir.js +++ b/module/tmr/trou-noir.js @@ -14,7 +14,7 @@ export class TrouNoir extends Draconique { async onActorCreateOwned(actor, souffle) { const existants = actor.data.items.filter(it => this.isCase(it)).map(it => it.data.coord); const tmr = TMRUtility.getTMRAleatoire(it => !(TMRUtility.isCaseHumide(it) || existants.includes(it.coord))); - await this.createCaseTmr(actor, 'Trou noir: ' + tmr.label, tmr, souffle._id); + await this.createCaseTmr(actor, 'Trou noir: ' + tmr.label, tmr, souffle.id); } code() { return 'trounoir' } diff --git a/module/tmr/urgence-draconique.js b/module/tmr/urgence-draconique.js index 1b43d1f3..9a6bad38 100644 --- a/module/tmr/urgence-draconique.js +++ b/module/tmr/urgence-draconique.js @@ -23,20 +23,20 @@ export class UrgenceDraconique extends Draconique { whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), content: `En l'absence de sorts en réserve, l'urgence draconique de ${actor.name} se transforme en ${ideeFixe.name}` }); - await actor.createEmbeddedDocuments('Item',[ideeFixe]); - await actor.deleteOwnedItem(queue._id); + await actor.createEmbeddedDocuments('Item', [ideeFixe]); + await actor.deleteEmbeddedDocuments('Item', [queue.id]); return; } else { const demiReve = actor.getDemiReve(); coordSortsReserve.sort(Misc.ascending(t => TMRUtility.distanceTMR(t, demiReve))); const tmr = TMRUtility.getTMR(coordSortsReserve[0]); - await this.createCaseTmr(actor, 'Urgence draconique: ' + tmr.label, tmr, queue._id); + await this.createCaseTmr(actor, 'Urgence draconique: ' + tmr.label, tmr, queue.id); } } async onActorDeleteCaseTmr(actor, casetmr) { - await actor.deleteOwnedItem(casetmr.data.sourceid); + await actor.deleteEmbeddedDocuments('Item', [casetmr.data.sourceid]); } code() { return 'urgence' } diff --git a/system.json b/system.json index 87a6205c..19c1932e 100644 --- a/system.json +++ b/system.json @@ -31,7 +31,7 @@ "name": "Fab" } ], - "esmodules": [ "module/rdd-main.js", "module/hook-renderChatLog.js" ], + "esmodules": [ "module/rdd-main.js"], "styles": ["styles/simple.css"], "media": [ { diff --git a/templates/item-casetmr-sheet.html b/templates/item-casetmr-sheet.html index 96e33db7..6e17106d 100644 --- a/templates/item-casetmr-sheet.html +++ b/templates/item-casetmr-sheet.html @@ -15,7 +15,7 @@
    diff --git a/templates/item-jeu-sheet.html b/templates/item-jeu-sheet.html index 68d7fe97..130bd8cf 100644 --- a/templates/item-jeu-sheet.html +++ b/templates/item-jeu-sheet.html @@ -11,7 +11,7 @@
    - {{#select item.data.competence}} + {{#select data.competence}} {{#each competences as |competence key|}} {{/each}} @@ -29,7 +29,7 @@
    @@ -49,7 +49,7 @@
    @@ -58,7 +58,7 @@ {{#if isGM}} - {{#select item.data.default_carac}} + {{#select data.default_carac}} {{>"systems/foundryvtt-reve-de-dragon/templates/competence-carac-defaut.html"}} {{/select}} @@ -19,7 +19,7 @@
    - {{#select item.data.type}} + {{#select data.type}} {{/select}}