From a65d4511c58c701c5e0599bcf1523ae7881cc528 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Mon, 23 Oct 2023 22:04:45 +0200 Subject: [PATCH 1/6] =?UTF-8?q?Fix=20Macros=20de=20combat=20et=20corps=20?= =?UTF-8?q?=C3=A0=20corps?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - gestion des armes à 1/2 mains depuis les armes / le combat - gestion correcte des compétences d'attaques de créatures - message pour les macros de compétence d'arme --- module/actor.js | 38 +++++++++++++------- module/item-arme.js | 11 +++++- module/rdd-combat.js | 5 ++- module/rdd-hotbar-drop.js | 73 +++++++++++++++++++++++++++------------ 4 files changed, 89 insertions(+), 38 deletions(-) diff --git a/module/actor.js b/module/actor.js index 0b7e73a8..7aebcedd 100644 --- a/module/actor.js +++ b/module/actor.js @@ -232,6 +232,9 @@ export class RdDActor extends RdDBaseActor { /* -------------------------------------------- */ getCompetence(idOrName, options = {}) { + if (idOrName instanceof Item) { + return idOrName.isCompetence() ? idOrName : undefined + } return RdDItemCompetence.findCompetence(this.items, idOrName, options) } @@ -2139,7 +2142,7 @@ export class RdDActor extends RdDBaseActor { ui.notifications.info(`Aucun sort disponible en ${TMRUtility.getTMR(coord).label} !`); return; } - + const draconicList = this.computeDraconicAndSortIndex(sorts); const reve = duplicate(this.system.carac.reve); @@ -3073,24 +3076,35 @@ export class RdDActor extends RdDBaseActor { } /* -------------------------------------------- */ - getArmeCompetence(arme, competenceName) { - let comp = arme.system[competenceName] - if (!comp || comp.name == "") { - comp = arme.system[competenceName] + getCompetenceArme(arme, competenceName) { + switch (arme.type) { + case TYPES.competencecreature: + return arme.name + case TYPES.arme: + switch (competenceName) { + case 'competence': return arme.system.competence; + case 'unemain': return RdDItemArme.competence1Mains(arme); + case 'deuxmains': return RdDItemArme.competence2Mains(arme); + case 'tir': return arme.system.tir; + case 'lancer': return arme.system.lancer; + } } - if ( !comp || comp.name == "") { - comp = arme.system[competenceName] - } - return comp + return undefined } /* -------------------------------------------- */ - rollArme(arme, competenceName = "competence") { - let compToUse = this.getArmeCompetence(arme, competenceName) + /** + * + * @param {*} arme item d'arme/compétence de créature + * @param {*} categorieArme catégorie d'attaque à utiliser: competence (== melee), lancer, tir; naturelle, possession + * @returns + */ + rollArme(arme, categorieArme = "competence") { + let compToUse = this.getCompetenceArme(arme, categorieArme) if (!Targets.hasTargets()) { RdDConfirm.confirmer({ settingConfirmer: "confirmer-combat-sans-cible", - content: `

Voulez vous faire un jet de compétence ${competenceName} sans choisir de cible valide? + content: `

Voulez vous faire un jet de ${compToUse} sans choisir de cible valide?
Tous les jets de combats devront être gérés à la main

`, title: 'Ne pas utiliser les automatisation de combat', diff --git a/module/item-arme.js b/module/item-arme.js index b8c59dad..b4f50d6c 100644 --- a/module/item-arme.js +++ b/module/item-arme.js @@ -157,6 +157,13 @@ export class RdDItemArme extends Item { } return armeData; } + static competence2Mains(arme) { + return arme.system.competence.replace(" 1 main", " 2 mains"); + } + + static competence1Mains(arme) { + return arme.system.competence.replace(" 2 mains", " 1 main"); + } static isArmeUtilisable(arme) { return arme.type == 'arme' && arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0); @@ -172,6 +179,7 @@ export class RdDItemArme extends Item { static corpsACorps(mainsNuesActor) { const corpsACorps = { name: 'Corps à corps', + type: 'arme', img: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp', system: { equipe: true, @@ -181,6 +189,7 @@ export class RdDItemArme extends Item { dommagesReels: 0, mortalite: 'non-mortel', competence: 'Corps à corps', + deuxmains: true, categorie_parade: 'sans-armes' } }; @@ -195,7 +204,7 @@ export class RdDItemArme extends Item { mainsNues.system.baseInit = 4 return mainsNues; } - + static empoignade(mainsNuesActor) { const empoignade = RdDItemArme.corpsACorps(mainsNuesActor) empoignade.name = 'Empoignade' diff --git a/module/rdd-combat.js b/module/rdd-combat.js index ba99000f..ad434ba0 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -171,8 +171,7 @@ export class RdDCombatManager extends Combat { if (arme.system.unemain && arme.system.deuxmains && !dommages.includes("/")) { ui.notifications.info("Les dommages de l'arme à 1/2 mains " + arme.name + " ne sont pas corrects (ie sous la forme X/Y)"); } - if ((arme.system.unemain && arme.system.competence) || - (arme.system.competence.toLowerCase().includes("corps à corps"))) { + if (arme.system.unemain && arme.system.competence) { actions.push(RdDCombatManager.$prepareAttaqueArme({ arme: arme, infoMain: "(1 main)", @@ -187,7 +186,7 @@ export class RdDCombatManager extends Combat { arme: arme, infoMain: "(2 mains)", dommagesReel: Number(tableauDommages[1]), - competence: arme.system.competence.replace(" 1 main", " 2 mains"), + competence: RdDItemArme.competence2Mains(arme), carac: carac, competences: competences })); diff --git a/module/rdd-hotbar-drop.js b/module/rdd-hotbar-drop.js index bb8c61ec..e00e435b 100644 --- a/module/rdd-hotbar-drop.js +++ b/module/rdd-hotbar-drop.js @@ -1,13 +1,17 @@ +import { RdDItemCompetence } from "./item-competence.js"; +import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; import { TYPES } from "./item.js"; export class RdDHotbar { static async createItemMacro(item, slot, armeCompetence = undefined) { - let command = `game.system.rdd.RdDHotbar.rollMacro("${item.name}", "${item.type}"` + ((armeCompetence) ? `, "${armeCompetence}");` : `);`); - let macro = game.macros.contents.find(m => (m.name === item.name) && (m.command === command)); + const itemName = item.name; + let command = `game.system.rdd.RdDHotbar.rollMacro("${itemName}", "${item.type}", "${armeCompetence}");` + let macro = game.macros.contents.find(m => (m.name === itemName) && (m.command === command)); + let macroName = itemName + RdDHotbar.$macroNameSuffix(armeCompetence); if (!macro) { macro = await Macro.create({ - name: item.name, + name: macroName, type: "script", img: item.img, command: command @@ -16,29 +20,51 @@ export class RdDHotbar { await game.user.assignHotbarMacro(macro, slot); } + static $macroNameSuffix(armeCompetence){ + switch(armeCompetence) { + case 'unemain': return ' (1 main)'; + case 'deuxmains': return ' (2 main)'; + case 'tir': return ' (tir)'; + case 'lancer': return ' (lancer)'; + } + return '' + } + static async addToHotbar(item, slot) { - switch (item?.type ?? "") { + switch (item?.type ?? '') { case TYPES.arme: { // Les armes peuvent avoir plusieurs usages - if (item.system.competence != "") { - await this.createItemMacro(item, slot, "competence") + if (item.system.competence != '') { + if (item.system.unemain) { + await this.createItemMacro(item, slot, 'unemain') + slot++ + } + if (item.system.deuxmains) { + await this.createItemMacro(item, slot, 'deuxmains') + slot++ + } + } + if (item.system.lancer != '') { + await this.createItemMacro(item, slot, 'lancer') slot++ } - if (item.system.lancer != "") { - await this.createItemMacro(item, slot, "lancer") - slot++ - } - if (item.system.tir != "") { - await this.createItemMacro(item, slot, "lancer") + if (item.system.tir != '') { + await this.createItemMacro(item, slot, 'lancer') slot++ } } return - case TYPES.competence: case TYPES.competencecreature: + const categorie = RdDItemCompetenceCreature.getCategorieAttaque(item) ?? 'competence'; + await this.createItemMacro(item, slot, categorie) + return default: - await this.createItemMacro(item, slot) + case TYPES.competence: + if (RdDItemCompetence.isCompetenceArme(item)) { + ui.notifications.info(`La compétence de ${item.name} est une compétence d'arme, choisissez plutôt de créer la macro depuis l'onglet combat`); + } + await this.createItemMacro(item, slot, 'competence') return } } @@ -51,14 +77,13 @@ export class RdDHotbar { */ static initDropbar() { - Hooks.on("hotbarDrop", (bar, documentData, slot) => { + Hooks.on('hotbarDrop', (bar, documentData, slot) => { // Create item macro if rollable item - weapon, spell, prayer, trait, or skill - if (documentData.type == "Item") { + if (documentData.type == 'Item') { const item = fromUuidSync(documentData.uuid) ?? this.actor.items.get(documentData.uuid) - console.log("DROP", documentData, item) - switch (item?.type ?? "") - { + console.log('DROP', documentData, item) + switch (item?.type) { case TYPES.arme: case TYPES.competence: case TYPES.competencecreature: @@ -72,7 +97,7 @@ export class RdDHotbar { } /** Roll macro */ - static rollMacro(itemName, itemType, competenceName) { + static rollMacro(itemName, itemType, categorieArme = 'competence') { const speaker = ChatMessage.getSpeaker(); let actor; if (speaker.token) actor = game.actors.tokens[speaker.token]; @@ -88,10 +113,14 @@ export class RdDHotbar { // Trigger the item roll switch (item.type) { case TYPES.arme: - return actor.rollArme(item, competenceName); + return actor.rollArme(item, categorieArme); case TYPES.competence: + return actor.rollCompetence(item); case TYPES.competencecreature: - return actor.rollCompetence(itemName); + return item.system.iscombat && !item.system.isparade + ? actor.rollArme(item, categorieArme) + : actor.rollCompetence(item); + } } -- 2.35.3 From b74fc27079b2cf72ea6c96f907d95bc8bdbb32ac Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Mon, 23 Oct 2023 23:37:47 +0200 Subject: [PATCH 2/6] Minor cleanup --- module/actor.js | 12 ++++++------ module/item-arme.js | 12 ++++++------ module/item-competencecreature.js | 2 +- module/time/rdd-calendrier.js | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/module/actor.js b/module/actor.js index 7aebcedd..be0b90cf 100644 --- a/module/actor.js +++ b/module/actor.js @@ -291,13 +291,13 @@ export class RdDActor extends RdDBaseActor { } getPossession(possessionId) { - return this.items.find(it => it.type == TYPES.possession && it.system.possessionid == possessionId); + return this.itemTypes[TYPES.possession].find(it => it.system.possessionid == possessionId); } getPossessions() { - return this.items.filter(it => it.type == TYPES.possession); + return this.itemTypes[TYPES.possession]; } getEmpoignades() { - return this.items.filter(it => it.type == TYPES.empoignade); + return this.itemTypes[TYPES.empoignade]; } getDemiReve() { return this.system.reve.tmrpos.coord; @@ -549,7 +549,7 @@ export class RdDActor extends RdDBaseActor { /* -------------------------------------------- */ async _recuperationBlessures(message, isMaladeEmpoisonne) { const timestamp = game.system.rdd.calendrier.getTimestamp() - const blessures = this.filterItems(it => it.system.gravite > 0, 'blessure').sort(Misc.ascending(it => it.system.gravite)) + const blessures = this.filterItems(it => it.system.gravite > 0, TYPES.blessure).sort(Misc.ascending(it => it.system.gravite)) await Promise.all(blessures.map(b => b.recuperationBlessure({ actor: this, @@ -563,7 +563,7 @@ export class RdDActor extends RdDBaseActor { } async supprimerBlessures(filterToDelete) { - const toDelete = this.filterItems(filterToDelete, 'blessure') + const toDelete = this.filterItems(filterToDelete, TYPES.blessure) .map(it => it.id); await this.deleteEmbeddedDocuments('Item', toDelete); } @@ -571,7 +571,7 @@ export class RdDActor extends RdDBaseActor { /* -------------------------------------------- */ async _recupererVie(message, isMaladeEmpoisonne) { const tData = this.system - let blessures = this.filterItems(it => it.system.gravite > 0, 'blessure'); + let blessures = this.filterItems(it => it.system.gravite > 0, TYPES.blessure); if (blessures.length > 0) { return } diff --git a/module/item-arme.js b/module/item-arme.js index b4f50d6c..f1fa40c7 100644 --- a/module/item-arme.js +++ b/module/item-arme.js @@ -20,14 +20,14 @@ const nomCategorieParade = { export class RdDItemArme extends Item { static isArme(item) { - return RdDItemCompetenceCreature.getCategorieAttaque(item) || item.type == 'arme'; + return RdDItemCompetenceCreature.getCategorieAttaque(item) || item.type == TYPES.arme; } /* -------------------------------------------- */ static getArme(arme) { switch (arme ? arme.type : '') { - case 'arme': return arme; - case 'competencecreature': + case TYPES.arme: return arme; + case TYPES.competencecreature: return RdDItemCompetenceCreature.armeCreature(arme); } return RdDItemArme.mainsNues(); @@ -68,14 +68,14 @@ export class RdDItemArme extends Item { return armeData.system.categorie_parade; } // pour compatibilité avec des personnages existants - if (armeData.type == 'competencecreature' || armeData.system.categorie == 'creature') { + if (armeData.type == TYPES.competencecreature || armeData.system.categorie == 'creature') { return armeData.system.categorie_parade || (armeData.system.isparade ? 'armes-naturelles' : ''); } if (!armeData.type.match(/arme|competencecreature/)) { return ''; } if (armeData.system.competence == undefined) { - return 'competencecreature'; + return TYPES.competencecreature; } let compname = armeData.system.competence.toLowerCase(); if (compname.match(/^(dague de jet|javelot|fouet|arc|arbalête|fronde|hache de jet|fléau)$/)) return ''; @@ -179,7 +179,7 @@ export class RdDItemArme extends Item { static corpsACorps(mainsNuesActor) { const corpsACorps = { name: 'Corps à corps', - type: 'arme', + type: TYPES.arme, img: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp', system: { equipe: true, diff --git a/module/item-competencecreature.js b/module/item-competencecreature.js index 426a7aab..85f3f291 100644 --- a/module/item-competencecreature.js +++ b/module/item-competencecreature.js @@ -1,5 +1,5 @@ -import { RdDItem, TYPES } from "./item.js"; +import { TYPES } from "./item.js"; import { RdDCombatManager } from "./rdd-combat.js"; const categories = { diff --git a/module/time/rdd-calendrier.js b/module/time/rdd-calendrier.js index 0d62ca20..aeaadcc4 100644 --- a/module/time/rdd-calendrier.js +++ b/module/time/rdd-calendrier.js @@ -364,7 +364,7 @@ export class RdDCalendrier extends Application { if (request.rolled.isSuccess) { if (request.rolled.isPart) { // Gestion expérience (si existante) - request.competence = actor.getCompetence("astrologie") + request.competence = actor.getCompetence('Astrologie') request.selectedCarac = actor.system.carac["vue"]; actor.appliquerAjoutExperience(request, 'hide'); } -- 2.35.3 From 0ed90f6177f3db8425ac56d85287f3b74014459e Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Mon, 23 Oct 2023 23:40:03 +0200 Subject: [PATCH 3/6] =?UTF-8?q?Macros=20pour=20le=20corps=20=C3=A0=20corps?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cas particulier car 3 utilisations possibles, et pas d'armes --- module/actor-sheet.js | 7 +++++-- module/actor.js | 8 ++++++- module/item-arme.js | 28 ++++++++++++------------- module/item-competence.js | 7 +++---- module/item-sheet.js | 2 +- module/item.js | 26 +++++++++++++++++++++++ module/rdd-combat.js | 13 ++++++------ module/rdd-empoignade.js | 4 ++-- module/rdd-hotbar-drop.js | 44 +++++++++++++++++++++++++-------------- 9 files changed, 92 insertions(+), 47 deletions(-) diff --git a/module/actor-sheet.js b/module/actor-sheet.js index 790a6b8e..b1716797 100644 --- a/module/actor-sheet.js +++ b/module/actor-sheet.js @@ -81,9 +81,12 @@ export class RdDActorSheet extends RdDBaseActorSheet { }); // toujours avoir une liste d'armes (pour mettre esquive et corps à corps) - formData.combat = duplicate(formData.armes ?? []); + const actor = this.actor; + formData.combat = duplicate(formData.armes); RdDItemArme.computeNiveauArmes(formData.combat, formData.competences); - RdDItemArme.ajoutCorpsACorps(formData.combat, formData.competences, formData.system.carac); + formData.combat.push(RdDItemArme.mainsNues(actor)); + formData.combat.push(RdDItemArme.empoignade(actor)); + formData.esquives = this.actor.getCompetences("Esquive"); formData.combat = RdDCombatManager.listActionsArmes(formData.combat, formData.competences, formData.system.carac); formData.empoignades = this.actor.getEmpoignades(); diff --git a/module/actor.js b/module/actor.js index be0b90cf..b3f0e5f5 100644 --- a/module/actor.js +++ b/module/actor.js @@ -241,6 +241,12 @@ export class RdDActor extends RdDBaseActor { getCompetences(name) { return RdDItemCompetence.findCompetences(this.items, name) } + getCompetenceCorpsACorps(options = {}) { + return this.getCompetence("Corps à corps", options) + } + getCompetencesEsquive() { + return this.getCompetences("esquive") + } /* -------------------------------------------- */ getTache(id) { return this.findItemLike(id, 'tache'); @@ -3084,7 +3090,7 @@ export class RdDActor extends RdDBaseActor { switch (competenceName) { case 'competence': return arme.system.competence; case 'unemain': return RdDItemArme.competence1Mains(arme); - case 'deuxmains': return RdDItemArme.competence2Mains(arme); + case 'deuxmains': return RdDItemArme.competence2Mains(arme); case 'tir': return arme.system.tir; case 'lancer': return arme.system.lancer; } diff --git a/module/item-arme.js b/module/item-arme.js index f1fa40c7..bbc87102 100644 --- a/module/item-arme.js +++ b/module/item-arme.js @@ -169,19 +169,21 @@ export class RdDItemArme extends Item { return arme.type == 'arme' && arme.system.equipe && (arme.system.resistance > 0 || arme.system.portee_courte > 0); } - static ajoutCorpsACorps(armes, competences, carac) { - let corpsACorps = competences.find(it => it.name == 'Corps à corps') ?? { system: { niveau: -6 } }; - let init = RdDCombatManager.calculInitiative(corpsACorps.system.niveau, carac['melee'].value); - armes.push(RdDItemArme.mainsNues({ niveau: corpsACorps.system.niveau, initiative: init })); - armes.push(RdDItemArme.empoignade({ niveau: corpsACorps.system.niveau, initiative: init })); + static ajoutCorpsACorps(armes, actor) { + armes.push(RdDItemArme.mainsNues(actor)); + armes.push(RdDItemArme.empoignade(actor)); } - static corpsACorps(mainsNuesActor) { - const corpsACorps = { + static corpsACorps(actor) { + let competence = actor?.getCompetenceCorpsACorps() ?? { system: { niveau: -6 } }; + let melee = actor? actor.system.carac['melee'].value : 0 + return { + _id: competence?.id, name: 'Corps à corps', type: TYPES.arme, img: 'systems/foundryvtt-reve-de-dragon/icons/competence_corps_a_corps.webp', system: { + initiative: RdDCombatManager.calculInitiative(competence.system.niveau, melee), equipe: true, rapide: true, force: 0, @@ -192,21 +194,19 @@ export class RdDItemArme extends Item { deuxmains: true, categorie_parade: 'sans-armes' } - }; - mergeObject(corpsACorps.system, mainsNuesActor ?? {}, { overwrite: false }); - return corpsACorps; + } } - static mainsNues(mainsNuesActor) { - const mainsNues = RdDItemArme.corpsACorps(mainsNuesActor) + static mainsNues(actor) { + const mainsNues = RdDItemArme.corpsACorps(actor) mainsNues.name = 'Mains nues' mainsNues.system.cac = 'pugilat' mainsNues.system.baseInit = 4 return mainsNues; } - static empoignade(mainsNuesActor) { - const empoignade = RdDItemArme.corpsACorps(mainsNuesActor) + static empoignade(actor) { + const empoignade = RdDItemArme.corpsACorps(actor) empoignade.name = 'Empoignade' empoignade.system.cac = 'empoignade' empoignade.system.baseInit = 3 diff --git a/module/item-competence.js b/module/item-competence.js index 665e7d0f..19692f35 100644 --- a/module/item-competence.js +++ b/module/item-competence.js @@ -79,10 +79,9 @@ export class RdDItemCompetence extends Item { /* -------------------------------------------- */ static isCompetenceArme(competence) { - if (competence.isCompetence()) { + if (competence.isCompetence() && !competence.isCorpsACorps() && !competence.isEsquive()) { switch (competence.system.categorie) { case 'melee': - return !Grammar.toLowerCaseNoAccent(competence.name).includes('esquive'); case 'tir': case 'lancer': return true; @@ -93,10 +92,10 @@ export class RdDItemCompetence extends Item { /* -------------------------------------------- */ static isArmeUneMain(competence) { - return RdDItemCompetence.isCompetenceArme(competence) && competence.name.toLowerCase().includes("1 main"); + return competence.isCompetenceArme() && competence.name.toLowerCase().includes("1 main"); } static isArme2Main(competence) { - return RdDItemCompetence.isCompetenceArme(competence) && competence.name.toLowerCase().includes("2 main"); + return competence.isCompetenceArme() && competence.name.toLowerCase().includes("2 main"); } static isThanatos(competence) { diff --git a/module/item-sheet.js b/module/item-sheet.js index e2f5bd7c..e8864c86 100644 --- a/module/item-sheet.js +++ b/module/item-sheet.js @@ -113,7 +113,7 @@ export class RdDItemSheet extends ItemSheet { formData.competences = competences; } if (this.item.type == 'arme') { - formData.competences = competences.filter(it => RdDItemCompetence.isCompetenceArme(it)) + formData.competences = competences.filter(it => it.isCompetenceArme()) } if (['sort', 'sortreserve'].includes(this.item.type)) { formData.competences = competences.filter(it => RdDItemCompetence.isDraconic(it)); diff --git a/module/item.js b/module/item.js index 946e0a3d..35c1b053 100644 --- a/module/item.js +++ b/module/item.js @@ -220,6 +220,32 @@ export class RdDItem extends Item { isService() { return this.type == TYPES.service; } isCompetence() { return typesObjetsCompetence.includes(this.type) } + isEsquive() { + return (this.isCompetence() + && this.system.categorie == 'melee' + && Grammar.includesLowerCaseNoAccent(this.name, 'Esquive')); + } + + isCorpsACorps() { + return (this.isCompetence() + && this.system.categorie == 'melee' + && Grammar.includesLowerCaseNoAccent(this.name, 'Corps à Corps')); + } + + isCompetenceArme() { + if (this.isCompetence()) { + switch (this.system.categorie) { + case 'melee': + return !this.isCorpsACorps() && !this.isEsquive() + case 'tir': + case 'lancer': + return true; + } + } + return false; + } + + isCompetencePossession() { return TYPES.competencecreature == this.type && this.system.categorie == "possession" } isTemporel() { return typesObjetsTemporels.includes(this.type) } isOeuvre() { return typesObjetsOeuvres.includes(this.type) } diff --git a/module/rdd-combat.js b/module/rdd-combat.js index ad434ba0..ee434acd 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -75,7 +75,7 @@ export class RdDCombatManager extends Combat { } } } - + /************************************************************************************/ async rollInitiative(ids, formula = undefined, messageOptions = {}) { console.log(`${game.system.title} | Combat.rollInitiative()`, ids, formula, messageOptions); @@ -257,11 +257,10 @@ export class RdDCombatManager extends Combat { actions = RdDCombatManager.listActionsCreature(actor.itemTypes['competencecreature']); } else if (actor.isPersonnage()) { // Recupération des items 'arme' - const armes = actor.itemTypes['arme'].filter(it => RdDItemArme.isArmeUtilisable(it)) - .concat(RdDItemArme.empoignade()) - .concat(RdDItemArme.mainsNues()); - const competences = actor.itemTypes['competence']; + const armes = actor.itemTypes['arme'].filter(it => RdDItemArme.isArmeUtilisable(it)) + .concat(RdDItemArme.empoignade(actor)) + .concat(RdDItemArme.mainsNues(actor)); actions = RdDCombatManager.listActionsArmes(armes, competences, actor.system.carac); if (actor.system.attributs.hautrevant.value) { @@ -884,8 +883,8 @@ export class RdDCombat { } // # utilisation esquive - const corpsACorps = this.defender.getCompetence("Corps à corps", { onMessage: it => console.info(it, this.defender) }); - const esquives = duplicate(this.defender.getCompetences("esquive", { onMessage: it => console.info(it, this.defender) })) + const corpsACorps = this.defender.getCompetenceCorpsACorps({ onMessage: it => console.info(it, this.defender) }); + const esquives = duplicate(this.defender.getCompetencesEsquive()) esquives.forEach(e => e.system.nbUsage = e?._id ? this.defender.getItemUse(e._id) : 0); const paramChatDefense = { diff --git a/module/rdd-empoignade.js b/module/rdd-empoignade.js index 0694dc79..3991dd0c 100644 --- a/module/rdd-empoignade.js +++ b/module/rdd-empoignade.js @@ -181,7 +181,7 @@ export class RdDEmpoignade { let rollData = { mode, empoignade, attacker, defender, isEmpoignade: true, - competence: attacker.getCompetence("Corps à corps"), + competence: attacker.getCompetenceCorpsACorps(), selectedCarac: attacker.system.carac.melee, malusTaille: RdDEmpoignade.getMalusTaille(empoignade, attacker, defender) } @@ -210,7 +210,7 @@ export class RdDEmpoignade { mode: "immobilise", empoignade, attacker, defender, isEmpoignade: true, - competence: attacker.getCompetence("Corps à corps") + competence: attacker.getCompetenceCorpsACorps() } const msg = await ChatMessage.create({ whisper: ChatUtility.getWhisperRecipientsAndGMs(attacker.name), diff --git a/module/rdd-hotbar-drop.js b/module/rdd-hotbar-drop.js index e00e435b..f7229155 100644 --- a/module/rdd-hotbar-drop.js +++ b/module/rdd-hotbar-drop.js @@ -1,4 +1,4 @@ -import { RdDItemCompetence } from "./item-competence.js"; +import { RdDItemArme } from "./item-arme.js"; import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; import { TYPES } from "./item.js"; @@ -6,9 +6,9 @@ export class RdDHotbar { static async createItemMacro(item, slot, armeCompetence = undefined) { const itemName = item.name; + let macroName = itemName + RdDHotbar.$macroNameSuffix(armeCompetence); let command = `game.system.rdd.RdDHotbar.rollMacro("${itemName}", "${item.type}", "${armeCompetence}");` let macro = game.macros.contents.find(m => (m.name === itemName) && (m.command === command)); - let macroName = itemName + RdDHotbar.$macroNameSuffix(armeCompetence); if (!macro) { macro = await Macro.create({ name: macroName, @@ -20,12 +20,15 @@ export class RdDHotbar { await game.user.assignHotbarMacro(macro, slot); } - static $macroNameSuffix(armeCompetence){ - switch(armeCompetence) { + static $macroNameSuffix(armeCompetence) { + switch (armeCompetence) { case 'unemain': return ' (1 main)'; - case 'deuxmains': return ' (2 main)'; + case 'deuxmains': return ' (2 main)'; case 'tir': return ' (tir)'; case 'lancer': return ' (lancer)'; + case 'pugilat': return ' (pugilat)'; + case 'empoignade': return ' (empoignade)'; + } return '' } @@ -37,21 +40,17 @@ export class RdDHotbar { // Les armes peuvent avoir plusieurs usages if (item.system.competence != '') { if (item.system.unemain) { - await this.createItemMacro(item, slot, 'unemain') - slot++ + await this.createItemMacro(item, slot++, 'unemain') } if (item.system.deuxmains) { - await this.createItemMacro(item, slot, 'deuxmains') - slot++ + await this.createItemMacro(item, slot++, 'deuxmains') } } if (item.system.lancer != '') { - await this.createItemMacro(item, slot, 'lancer') - slot++ + await this.createItemMacro(item, slot++, 'lancer') } if (item.system.tir != '') { - await this.createItemMacro(item, slot, 'lancer') - slot++ + await this.createItemMacro(item, slot++, 'lancer') } } return @@ -61,10 +60,15 @@ export class RdDHotbar { return default: case TYPES.competence: - if (RdDItemCompetence.isCompetenceArme(item)) { - ui.notifications.info(`La compétence de ${item.name} est une compétence d'arme, choisissez plutôt de créer la macro depuis l'onglet combat`); + await this.createItemMacro(item, slot++, 'competence') + if (item.isCorpsACorps()) { + await this.createItemMacro(item, slot++, 'pugilat') + await this.createItemMacro(item, slot++, 'empoignade') + } + if (item.isCompetenceArme()) { + ui.notifications.info(`${item.name} est une compétence d'arme, la macro n'est pas liée à un arme.
+ Créez la macro depuis l'arme ou l'onglet combat pour garder les automatisations de combat.`); } - await this.createItemMacro(item, slot, 'competence') return } } @@ -115,6 +119,14 @@ export class RdDHotbar { case TYPES.arme: return actor.rollArme(item, categorieArme); case TYPES.competence: + if (item.isCorpsACorps()) { + switch (categorieArme) { + case 'pugilat': + return actor.rollArme(RdDItemArme.mainsNues(actor), 'competence'); + case 'empoignade': + return actor.rollArme(RdDItemArme.empoignade(actor), 'competence'); + } + } return actor.rollCompetence(item); case TYPES.competencecreature: return item.system.iscombat && !item.system.isparade -- 2.35.3 From c950f568fd69be5fe602615a75b77d094749dcdc Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Tue, 24 Oct 2023 00:30:00 +0200 Subject: [PATCH 4/6] =?UTF-8?q?Fix:=20les=20TMRs=20sont=20en=20arri=C3=A8r?= =?UTF-8?q?e=20plan?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- module/actor.js | 12 ++++-------- module/rdd-tmr-dialog.js | 19 ++++++++++++------- module/rdd-tmr-rencontre-dialog.js | 2 +- module/tmr/present-cites.js | 5 +++-- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/module/actor.js b/module/actor.js index b3f0e5f5..359ad860 100644 --- a/module/actor.js +++ b/module/actor.js @@ -2149,7 +2149,6 @@ export class RdDActor extends RdDBaseActor { return; } - const draconicList = this.computeDraconicAndSortIndex(sorts); const reve = duplicate(this.system.carac.reve); @@ -2169,7 +2168,10 @@ export class RdDActor extends RdDBaseActor { diffLibre: RdDItemSort.getDifficulte(sorts[0], -7), // Per default at startup coutreve: Array(30).fill().map((item, index) => 1 + index), }, - callbackAction: r => this._rollUnSortResult(r) + callbackAction: async r => { + await this._rollUnSortResult(r); + if (!r.isSortReserve) this.tmrApp?.close(); + } }); this.tmrApp?.setTMRPendingAction(dialog); } @@ -2262,17 +2264,11 @@ export class RdDActor extends RdDBaseActor { reveActuel = Math.max(reveActuel - rollData.depenseReve, 0); await this.update({ "system.reve.reve.value": reveActuel }); - if (rollData.isSortReserve) { - this.tmrApp.maximize(); // Re-display TMR - } else { - this.tmrApp.close(); // Close TMR ! - } // Final chat message await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-sort.html'); if (reveActuel == 0) { // 0 points de reve ChatMessage.create({ content: this.name + " est réduit à 0 Points de Rêve, et tombe endormi !" }); - closeTMR = true; } } diff --git a/module/rdd-tmr-dialog.js b/module/rdd-tmr-dialog.js index b3d0c63f..415f8574 100644 --- a/module/rdd-tmr-dialog.js +++ b/module/rdd-tmr-dialog.js @@ -39,7 +39,8 @@ export class RdDTMRDialog extends Dialog { content: html, buttons: { closeButton: { - label: "Fermer", callback: html => this.close() } + label: "Fermer", callback: html => this.close() + } }, default: "closeButton" } @@ -93,6 +94,9 @@ export class RdDTMRDialog extends Dialog { setTMRPendingAction(dialog) { this.subdialog = dialog + if (dialog instanceof Application) { + dialog.bringToTop(); + } } isDemiReveCache() { @@ -579,9 +583,12 @@ export class RdDTMRDialog extends Dialog { _presentCite(tmr) { const presentCite = this.casesSpeciales.find(c => EffetsDraconiques.presentCites.isCase(c, tmr.coord)); if (presentCite) { - this.minimize(); const caseData = presentCite; - EffetsDraconiques.presentCites.choisirUnPresent(caseData, (present => this._utiliserPresentCite(presentCite, present, tmr))); + const dialog = EffetsDraconiques.presentCites.choisirUnPresent(caseData, present => { + this._utiliserPresentCite(presentCite, present, tmr) + this.restoreTMRAfterAction(); + }); + this.setTMRPendingAction(dialog); } return presentCite; } @@ -607,8 +614,6 @@ export class RdDTMRDialog extends Dialog { presentCite: presentCite }; await this._tentativeMaitrise(rencontreData); - - this.maximize(); this.postRencontre(tmr); } @@ -815,22 +820,22 @@ export class RdDTMRDialog extends Dialog { /* -------------------------------------------- */ async _maitriserTMR(rollData, callbackMaitrise) { - this.minimize(); // Hide rollData.isTMRCache = rollData.actor.isTMRCache(); const dialog = await RdDRoll.create(this.actor, rollData, { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-maitrise-tmr.html', - close: html => { this.restoreTMRAfterAction(); } }, { name: rollData.maitrise.verbe, label: rollData.maitrise.action, callbacks: [ this.actor.createCallbackExperience(), + { action: r => { this.restoreTMRAfterAction() } }, { action: callbackMaitrise } ] } ); dialog.render(true); + this.setTMRPendingAction(dialog); } /* -------------------------------------------- */ diff --git a/module/rdd-tmr-rencontre-dialog.js b/module/rdd-tmr-rencontre-dialog.js index b5426e93..97c4dc2d 100644 --- a/module/rdd-tmr-rencontre-dialog.js +++ b/module/rdd-tmr-rencontre-dialog.js @@ -34,6 +34,7 @@ export class RdDTMRRencontreDialog extends Dialog { async onButtonAction(action) { this.toClose = true; + await this.actor.tmrApp?.restoreTMRAfterAction(); this.actor.tmrApp?.onActionRencontre(action, this.tmr, this.rencontre) } @@ -41,7 +42,6 @@ export class RdDTMRRencontreDialog extends Dialog { async close() { if (this.actor.tmrApp){ if (this.toClose) { - this.actor.tmrApp?.restoreTMRAfterAction(); return await super.close(); } else { diff --git a/module/tmr/present-cites.js b/module/tmr/present-cites.js index ff7027e4..d6bfb4d6 100644 --- a/module/tmr/present-cites.js +++ b/module/tmr/present-cites.js @@ -49,12 +49,13 @@ export class PresentCites extends Draconique { const presents = await game.system.rdd.rencontresTMR.getPresentsCite() const buttons = {}; presents.forEach(r => buttons['present'+r.id] = { icon: '', label: r.name, callback: async () => onChoixPresent(r) }); - let d = new Dialog({ + let dialog = new Dialog({ title: "Présent des cités", content: `La ${this.tmrLabel(casetmr)} vous offre un présent, faites votre choix`, buttons: buttons }); - d.render(true); + dialog.render(true); + return dialog } async ouvrirLePresent(actor, casetmr) { -- 2.35.3 From 407b4f82d96756756279410626b648d6c739e146 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Tue, 24 Oct 2023 00:43:16 +0200 Subject: [PATCH 5/6] Version 11.0.26 --- changelog.md | 17 +++++++++++++++++ system.json | 4 ++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/changelog.md b/changelog.md index 0e12f650..8562e96b 100644 --- a/changelog.md +++ b/changelog.md @@ -1,4 +1,21 @@ # v11.0 +## v11.0.26 - le crépuscule de Khrachtchoum +- gestion correcte des TMRs + - les TMRs ne sont jamais minimisées (par le système) quand le haut-rêvant est en demi-rêve + - lorsqu'une fenêtre liée aux demi-rêve est affichée, cliquer sur les TMRs n'a pas d'effet + - les lancers de sorts et lectures de signes sont affichées en premier plan + - Les effets qui ouvrent une fenêtre sont bien affichés en premier plan + - en cas de rencontre suivie de maîtrises/conquêtes, les fenêtres s'enchaînent +- Le drag&drop vers la barre de macro est corrigé + - pour les créatures, possibilités d'avoir les attaques ou autres compétences + - pour les personnages, les macros sont créées: + - pour les compétences + - pour le corps à corps, trois macros sont créées: compétence, pugilat, empoignade + - pour les armes + - deux macros sont créées pour les armes à 1/2 mains + - deux macros sont créées pour les armes de mélée et lancer + - 4 macros si votre arbalête se lance, tire, et se manie à 1 ou 2 mains... + ## v11.0.25 - la vision du rêve de Khrachtchoum - Les TMRs restent affichées tant que le Haut-rêvant est en demi-rêve diff --git a/system.json b/system.json index 477005af..202f21da 100644 --- a/system.json +++ b/system.json @@ -1,8 +1,8 @@ { "id": "foundryvtt-reve-de-dragon", "title": "Rêve de Dragon", - "version": "11.0.25", - "download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-11.0.25.zip", + "version": "11.0.26", + "download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-11.0.26.zip", "manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v11/system.json", "changelog": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/branch/v11/changelog.md", "compatibility": { -- 2.35.3 From 47f305d8658f5a6e340fd772a6092e8c2df59131 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Tue, 24 Oct 2023 00:50:00 +0200 Subject: [PATCH 6/6] =?UTF-8?q?Les=20attaques=20de=20cr=C3=A9atures=20fonc?= =?UTF-8?q?tionnent=20de=20nouveau?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- changelog.md | 1 + module/actor.js | 14 ++++++-------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/changelog.md b/changelog.md index 8562e96b..cda96642 100644 --- a/changelog.md +++ b/changelog.md @@ -15,6 +15,7 @@ - deux macros sont créées pour les armes à 1/2 mains - deux macros sont créées pour les armes de mélée et lancer - 4 macros si votre arbalête se lance, tire, et se manie à 1 ou 2 mains... +- les jets de compétences d'attaque des créatures fonctionnent de nouveau ## v11.0.25 - la vision du rêve de Khrachtchoum - Les TMRs restent affichées tant que le Haut-rêvant est en demi-rêve diff --git a/module/actor.js b/module/actor.js index 359ad860..7b41567c 100644 --- a/module/actor.js +++ b/module/actor.js @@ -2343,16 +2343,14 @@ export class RdDActor extends RdDBaseActor { /* -------------------------------------------- */ async rollCompetence(idOrName, options = { tryTarget: true }) { RdDEmpoignade.checkEmpoignadeEnCours(this) - let rollData = { - carac: this.system.carac, - competence: this.getCompetence(idOrName) - } - if (rollData.competence.type == TYPES.competencecreature) { - const arme = RdDItemCompetenceCreature.armeCreature(rollData.competence) + const competence = this.getCompetence(idOrName); + let rollData = { carac: this.system.carac, competence: competence } + if (competence.type == TYPES.competencecreature) { + const arme = RdDItemCompetenceCreature.armeCreature(competence) if (arme && options.tryTarget && Targets.hasTargets()) { Targets.selectOneToken(target => { if (arme.action == "possession") { - RdDPossession.onAttaquePossession(target, this, rollData.competence) + RdDPossession.onAttaquePossession(target, this, competence) } else { RdDCombat.rddCombatTarget(target, this).attaque(competence, arme) @@ -2366,7 +2364,7 @@ export class RdDActor extends RdDBaseActor { await this._openRollDialog({ name: 'jet-competence', - label: 'Jet ' + Grammar.apostrophe('de', rollData.competence.name), + label: 'Jet ' + Grammar.apostrophe('de', competence.name), template: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-competence.html', rollData: rollData, callbackAction: r => this.$onRollCompetence(r, options) -- 2.35.3