From 16b92b45862bdda53ef98cbf1e64b1e1eb288b43 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Tue, 5 Jan 2021 18:43:13 +0100 Subject: [PATCH] Liste des ajustements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Après le travail sur les ChatMessage, centraliser les difficultés pour les dialog-roll afin d'afficher tous les ajustements sous forme de tooltips Les ajustements à améliorer: * malus armure * sur-encombrement * encombrement total + fix regression tâches + fix méditation isisPuritication --- module/actor.js | 105 ++++++------ module/item-arme.js | 23 ++- module/item-meditation.js | 15 ++ module/misc.js | 15 ++ module/rdd-astrologie-joueur.js | 2 +- module/rdd-bonus.js | 13 +- module/rdd-carac.js | 30 ++++ module/rdd-combat.js | 86 ++++------ module/rdd-resolution-table.js | 90 ++--------- module/rdd-roll-resolution-table.js | 6 +- module/rdd-roll.js | 203 +++++++++++------------- module/rdd-tmr-dialog.js | 6 +- module/rdd-utility.js | 3 +- module/rolldata-ajustements.js | 150 +++++++++++++++++ styles/simple.css | 4 +- templates/chat-infojet.html | 2 + templates/chat-resultat-attaque.html | 2 +- templates/chat-resultat-competence.html | 4 +- templates/chat-resultat-esquive.html | 4 +- templates/chat-resultat-general.html | 2 +- templates/chat-resultat-parade.html | 4 +- templates/dialog-competence.html | 13 +- templates/dialog-roll-ajustements.html | 19 +++ templates/dialog-roll-carac.html | 10 +- templates/dialog-roll-enctotal.html | 7 +- templates/dialog-roll-ethylisme.html | 4 +- templates/dialog-roll-meditation.html | 19 +-- templates/dialog-roll-resolution.html | 6 +- templates/dialog-roll-sort.html | 10 +- 29 files changed, 506 insertions(+), 351 deletions(-) create mode 100644 module/item-meditation.js create mode 100644 module/rdd-carac.js create mode 100644 module/rolldata-ajustements.js create mode 100644 templates/dialog-roll-ajustements.html diff --git a/module/actor.js b/module/actor.js index fab38106..d28bb0e2 100644 --- a/module/actor.js +++ b/module/actor.js @@ -161,55 +161,65 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ getReveActuel() { - return this.data.data.reve.reve.value; + return this.data.data.reve?.reve?.value ?? this.data.data.carac.reve.value; } getChanceActuel() { - return this.data.data.compteurs.chance.value; + return this.data.data.compteurs.chance?.value ?? 10; } - /* -------------------------------------------- */ getForceValue() { - return this.data.data.carac.force ? this.data.data.carac.force.value : this.data.data.carac.reve.value; + return this.data.data.carac.force?.force ?? this.data.data.carac.reve.value; + } + getMoralTotal() { + return this.data.data.compteurs.moral?.value ?? 0; } - /* -------------------------------------------- */ getBonusDegat() { // TODO: gérer séparation et +dom créature/entité indépendament de la compétence return Misc.toInt(this.data.data.attributs.plusdom.value); } - /* -------------------------------------------- */ getProtectionNaturelle() { return Misc.toInt(this.data.data.attributs.protection.value); } - + getEtatGeneral() { + return this.data.data.compteurs.etat.value; + } + getMalusArmure() { + return this.data.data.attributs?.malusarmure?.value ?? 0; + } + getEncTotal() { + return Math.floor(this.encTotal ?? 0); + } + getSurenc(){ + return this.data.data.compteurs?.surenc?.value ?? 0; + } /* -------------------------------------------- */ getCompetenceList() { return this.data.items.filter( (item) => item.type == 'competence'); - } - + } /* -------------------------------------------- */ getCompetence(compName) { return RdDUtility.findCompetence(this.data.items, compName); + } + /* -------------------------------------------- */ + getTache( id ) { + return this.data.items.find( item => item.type=='tache' && item._id == id ); } + getMeditation( id ) { + return this.data.items.find( item => item.type=='meditation' && item._id == id ); + } + /* -------------------------------------------- */ getBestDraconic() { const list = this.getDraconicList().sort((a, b) => b.data.niveau - a.data.niveau); if (list.length==0) { return { name: "none", niveau: -11 }; - } + } return duplicate(list[0]); - } - - getEncTotal() { - return Math.floor(this.encTotal ?? 0); - } - - getSurenc(){ - return this.data.data.compteurs?.surenc?.value ?? 0; - } + } /* -------------------------------------------- */ async deleteSortReserve(sortReserve) { @@ -227,11 +237,6 @@ export class RdDActor extends Actor { } } - /* -------------------------------------------- */ - getDiviseurSignificative() { - return this.getSurprise() == 'demi' ? 2 : 1; - } - /* -------------------------------------------- */ getSurprise() { if (this.isEntiteCauchemar()) { @@ -506,7 +511,7 @@ export class RdDActor extends Actor { async combattreReveDeDragon(force){ let draconic = this.getBestDraconic(); let niveau = Math.max(0, draconic.data.niveau); - let etat = this.data.data.compteurs.etat.value; + let etat = this.getEtatGeneral(); let difficulte = niveau - etat - force; let reveActuel = this.getReveActuel(); let rolled = await RdDResolutionTable.roll(reveActuel, difficulte); @@ -704,7 +709,7 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ detectSurEncombrement( ) { let diffEnc = Number(this.encTotal) - Number(this.data.data.attributs.encombrement.value); - return Math.min(0, Math.ceil(diffEnc)); + return Math.max(0, Math.ceil(diffEnc)); } /* -------------------------------------------- */ @@ -1230,7 +1235,7 @@ export class RdDActor extends Actor { async ethylismeTest() { let rollData = { vieValue: this.data.data.sante.vie.value, - etat: this.data.data.compteurs.etat.value - Math.min(0, this.data.data.compteurs.ethylisme.value), // Pour les jets d'Ethylisme, on ignore le degré d'éthylisme (p.162) + etat: this.getEtatGeneral() - Math.min(0, this.data.data.compteurs.ethylisme.value), // Pour les jets d'Ethylisme, on ignore le degré d'éthylisme (p.162) diffNbDoses: -Number(this.data.data.compteurs.ethylisme.nb_doses || 0), finalLevel: 0, diffConditions: 0, @@ -1423,6 +1428,7 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async _appliquerAjoutExperience(rollData, display=true) { + if (!this.isPersonnage()) return; let xpResult = this.appliquerExperience( rollData.rolled, rollData.selectedCarac.label, rollData.competence); if (display && xpResult.result ) { let xpmsg = "
Points d'expérience gagnés ! Carac: " + xpResult.xpCarac + ", Comp: " + xpResult.xpCompetence; @@ -1634,7 +1640,7 @@ export class RdDActor extends Actor { this.currentTMR.maximize(); // Re-display TMR } // Final chat message - await RdDResolutionTable.displayRollData(rollData, this.name, 'chat-resultat-sort.html'); + RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-sort.html'); if (myReve.value == 0) { // 0 points de reve ChatMessage.create({ content: this.name + " est réduit à 0 Points de Rêve, et tombe endormi !" }); @@ -1653,7 +1659,7 @@ export class RdDActor extends Actor { label: 'Jet ' + Grammar.apostrophe('de', rollData.selectedCarac.label), callbacks: [ this.createCallbackExperience(), - { action: this._onRollCaracResult } + { action: r => this._onRollCaracResult(r) } ] } ); @@ -1663,7 +1669,7 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async _onRollCaracResult(rollData) { // Final chat message - await RdDResolutionTable.displayRollData(rollData, this.name, 'chat-resultat-general.html'); + RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-general.html'); } /* -------------------------------------------- */ @@ -1684,7 +1690,7 @@ export class RdDActor extends Actor { label: 'Jet ' +Grammar.apostrophe('de', name), callbacks: [ this.createCallbackExperience(), - { action: this._competenceResult } + { action: r => this._competenceResult(r) } ] } ); dialog.render(true); @@ -1708,11 +1714,6 @@ export class RdDActor extends Actor { await this.createOwnedItem( tache, { renderSheet: true } ); } - /* -------------------------------------------- */ - getTacheMeditation ( id ) { - return this.data.items.find( item => item._id == id ); - } - /* -------------------------------------------- */ async rollTache( id ) { let tache = duplicate( this.getTache( id ) ); @@ -1749,7 +1750,7 @@ export class RdDActor extends Actor { this.updateEmbeddedEntity( "OwnedItem", rollData.tache); this.santeIncDec( "fatigue", rollData.tache.data.fatigue); - RdDResolutionTable.displayRollData(rollData, this.name, 'chat-resultat-tache.html'); + RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-tache.html'); } /* -------------------------------------------- */ @@ -1760,24 +1761,26 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async rollMeditation( id ) { - let meditation = duplicate( this.getTacheMeditation( id ) ); + let meditation = duplicate(this.getMeditation(id)); let competence = duplicate(this.getCompetence(meditation.data.competence)); competence.data.defaut_carac = "intellect"; // Meditation = tjs avec intellect let meditationData = { - competence: competence, + competence: competence, meditation: meditation, + conditionMeditation: { + isHeure: false, + isVeture: false, + isComportement: false, + isPurification: false, + }, diffConditions: 0, editLibre: false, editConditions: true, - isHeure: false, - isVeture: false, - isComportement: false, - isPurification: false, carac : { } }; meditationData.carac["intellect"] = duplicate(this.data.data.carac["intellect"]); - console.log("rollMedittion !!!", meditationData); + console.log("rollMeditation !!!", meditationData); const dialog = await RdDRoll.create(this, meditationData, {html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-meditation.html'}, { name: 'jet-meditation', @@ -1805,7 +1808,6 @@ export class RdDActor extends Actor { RdDResolutionTable.displayRollData(meditationData, this.name, 'chat-resultat-meditation.html'); } - /* -------------------------------------------- */ _meditationETotal(meditationData) { meditationData.meditation.data.malus--; @@ -1814,14 +1816,13 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async _competenceResult(rollData) { - RdDResolutionTable.displayRollData(rollData, this.name, 'chat-resultat-competence.html') + RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-competence.html') } /* -------------------------------------------- */ async rollAppelChance( ) { let rollData = { selectedCarac: this.getCaracByName('chance-actuelle'), surprise: '' }; - const dialog = await RdDRoll.create(this, rollData, { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html'}, { @@ -1841,7 +1842,7 @@ export class RdDActor extends Actor { if (rollData.rolled.isSuccess) { await this.chanceActuelleIncDec(-1) } - RdDResolutionTable.displayRollData(rollData, this.name, 'chat-resultat-appelchance.html') + RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-appelchance.html') } /* -------------------------------------------- */ @@ -1940,15 +1941,13 @@ export class RdDActor extends Actor { return { label: 'Rêve actuel', value: this.getReveActuel(), - type: "number", - ignoreEtatGeneral: true + type: "number" }; case 'chance-actuelle': case 'Chance actuelle': return { label: 'Chance actuelle', value: this.getChanceActuel(), - type: "number", - ignoreEtatGeneral: true + type: "number" }; } return RdDActor._findCaracByName(this.data.data.carac, caracName); @@ -2210,7 +2209,7 @@ export class RdDActor extends Actor { await entite.setEntiteReveAccordee(this); } - await RdDResolutionTable.displayRollData(rollData, this.name, 'chat-resultat-accorder-cauchemar.html'); + await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-accorder-cauchemar.html'); if (rolled.isPart) { await this._appliquerAjoutExperience(rollData, true); } diff --git a/module/item-arme.js b/module/item-arme.js index f3bec50e..642139d2 100644 --- a/module/item-arme.js +++ b/module/item-arme.js @@ -1,6 +1,6 @@ import { RdDItemCompetenceCreature } from "./item-competencecreature.js" -const nomCcategorieParade = { +const nomCategorieParade = { "sans-armes": "Sans arme / armes naturelles", "hast": "Armes d'hast", "batons": "Bâtons", @@ -31,9 +31,21 @@ export class RdDItemArme extends Item { } /* -------------------------------------------- */ - static getNomCategorieParade(it) { - const categorie = it.data ? RdDItemArme.getCategorieParade(it) : it; - return nomCcategorieParade[categorie]; + static getNomCategorieParade(arme) { + const categorie = arme?.data ? RdDItemArme.getCategorieParade(arme) : arme; + return nomCategorieParade[categorie]; + } + + /* -------------------------------------------- */ + static needArmeResist(armeAttaque, armeParade) { + if (!armeAttaque || !armeParade){ + return false; + } + // Epées parant une arme de bois (cf. page 115 ), une résistance est nécessaire + let attCategory = RdDItemArme.getCategorieParade(armeAttaque); + let defCategory = RdDItemArme.getCategorieParade(armeParade); + + return attCategory.match(/epees-/) && defCategory.match(/(haches|lances)/); } /* -------------------------------------------- */ @@ -74,6 +86,9 @@ export class RdDItemArme extends Item { /* -------------------------------------------- */ static needParadeSignificative(armeAttaque, armeParade) { + if (!armeAttaque || !armeParade){ + return false; + } // categories d'armes à la parade (cf. page 115 ) let attCategory = RdDItemArme.getCategorieParade(armeAttaque); let defCategory = RdDItemArme.getCategorieParade(armeParade); diff --git a/module/item-meditation.js b/module/item-meditation.js new file mode 100644 index 00000000..7ba0b076 --- /dev/null +++ b/module/item-meditation.js @@ -0,0 +1,15 @@ +export class RdDItemMeditation { + + static calculDifficulte(rollData) { + if (rollData.meditation) { + // Malus permanent éventuel + let diff = -rollData.meditation.data.malus ?? 0; + if (!rollData.conditionMeditation.isHeure) diff -= 2; + if (!rollData.conditionMeditation.isVeture) diff -= 2; + if (!rollData.conditionMeditation.isComportement) diff -= 2; + if (!rollData.conditionMeditation.isPurification) diff -= 2; + return diff; + } + return 0; + } +} \ No newline at end of file diff --git a/module/misc.js b/module/misc.js index cd3dc4f6..6b754e23 100644 --- a/module/misc.js +++ b/module/misc.js @@ -5,14 +5,20 @@ * to actual classes of the game system or of FoundryVTT */ export class Misc { + static isFunction(v) { + return v && {}.toString.call(v) === '[object Function]'; + } + static upperFirst(text) { return text.charAt(0).toUpperCase() + text.slice(1); } + static toSignedString(number){ const value = parseInt(number) const isPositiveNumber = value != NaN && value > 0; return isPositiveNumber ? "+"+number : number } + /** * 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 @@ -26,4 +32,13 @@ export class Misc { const parsed = parseInt(value); return isNaN(parsed) ? 0 : parsed; } + + static getFractionHtml(diviseur) { + if (!diviseur || diviseur <= 1) return undefined; + switch (diviseur || 1) { + case 2: return '½'; + case 4: return '¼'; + default: return '1/' + diviseur; + } + } } \ No newline at end of file diff --git a/module/rdd-astrologie-joueur.js b/module/rdd-astrologie-joueur.js index 3f9205e2..c231f0b7 100644 --- a/module/rdd-astrologie-joueur.js +++ b/module/rdd-astrologie-joueur.js @@ -13,7 +13,7 @@ export class RdDAstrologieJoueur extends Dialog { let data = { nombres: this.organizeNombres( actor), dates: game.system.rdd.calendrier.getJoursSuivants( 10 ), - etat: actor.data.data.compteurs.etat.value, + etat: actor.getEtatGeneral(), ajustementsConditions: CONFIG.RDD.ajustementsConditions, astrologie: RdDUtility.findCompetence( actor.data.items, 'Astrologie') } diff --git a/module/rdd-bonus.js b/module/rdd-bonus.js index aadd6e55..e2c5d622 100644 --- a/module/rdd-bonus.js +++ b/module/rdd-bonus.js @@ -1,3 +1,4 @@ +import { RdDCarac } from "./rdd-carac.js"; import { RdDUtility } from "./rdd-utility.js"; const conditionsTactiques = [ @@ -17,6 +18,16 @@ export class RdDBonus { return conditionsTactiques.find(e => e.type == condition) || conditionsTactiques.find(e => e.type == 'pret'); } + + static isAjustementAstrologique(rollData) { + return RdDCarac.isChance(rollData.selectedCarac) || + rollData.selectedSort?.data.isrituel; + } + /* -------------------------------------------- */ + static isDefenseAttaqueFinesse(rollData) { + return rollData.attackerRoll?.particuliere == 'finesse'; + } + /* -------------------------------------------- */ static dmg(rollData, dmgActor, isCauchemar = false) { let dmg = { total: 0, loc: RdDUtility.getLocalisation() }; @@ -50,7 +61,7 @@ export class RdDBonus { static bonusAttaque(condition) { return RdDBonus.find(condition).attaque; } - + /* -------------------------------------------- */ static _calculMortalite(rollData, isCauchemar) { if (isCauchemar){ diff --git a/module/rdd-carac.js b/module/rdd-carac.js new file mode 100644 index 00000000..921bbb6e --- /dev/null +++ b/module/rdd-carac.js @@ -0,0 +1,30 @@ +export class RdDCarac { + + static isAgiliteOuDerivee(selectedCarac) { + return selectedCarac?.label.match(/(Agilité|Dérobée)/); + } + static isVolonte(selectedCarac) { + return selectedCarac?.label == 'Volonté'; + } + static isChance(selectedCarac) { + return selectedCarac?.label?.toLowerCase()?.match(/chance( actuelle)?/); + } + static isReve(selectedCarac) { + return selectedCarac?.label?.toLowerCase()?.match(/r(e|ê)ve(( |-)actuel)?/); + } + + static isIgnoreEtatGeneral(selectedCarac) { + return !selectedCarac || + RdDCarac.isChance(selectedCarac) || + RdDCarac.isReve(selectedCarac); + } + + /** + * L’appel à la chance n’est possible que pour recommencer les jets d’actions physiques : + * tous les jets de combat, de FORCE, d’AGILITÉ, de DEXTÉRITÉ, de Dérobée, d’APPARENCE, + * ainsi que de Perception active et volontaire. + */ + static isActionPhysique(selectedCarac) { + return selectedCarac?.label.match(/(Apparence|Force|Agilité|Dextérité|Vue|Ouïe|Odorat-Goût|Empathie|Mêlée|Tir|Lancer|Dérobée)/); + } +} \ No newline at end of file diff --git a/module/rdd-combat.js b/module/rdd-combat.js index b1d755b0..e852c575 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -18,7 +18,7 @@ export class RdDCombat { static createUsingTarget(attacker) { const target = RdDCombat.getTarget(); if (target == undefined) { - ui.notifications.warn( (game.user.targets?.size ??0) > 1 + ui.notifications.warn((game.user.targets?.size ?? 0) > 1 ? "Vous devez choisir une seule cible à attaquer!" : "Vous devez choisir une cible à attaquer!"); } @@ -86,7 +86,7 @@ export class RdDCombat { } /* -------------------------------------------- */ - static _callJetDeVie( event ) { + static _callJetDeVie(event) { let actorId = event.currentTarget.attributes['data-actorId'].value; let actor = game.actors.get(actorId); actor.jetVie(); @@ -103,7 +103,7 @@ export class RdDCombat { html.on("click", '#chat-jet-vie', event => { event.preventDefault(); RdDCombat._callJetDeVie(event); - } ); + }); } @@ -212,7 +212,7 @@ export class RdDCombat { } else { // sans armes: à mains nues - rollData.arme = RdDItemArme.mainsNues({niveau: competence.data.niveau}); + rollData.arme = RdDItemArme.mainsNues({ niveau: competence.data.niveau }); } return rollData; } @@ -247,7 +247,7 @@ export class RdDCombat { cible: this.target ? this.defender.data.name : 'la cible', isRecul: (rollData.particuliere == 'force' || rollData.tactique == 'charge') } - await RdDResolutionTable.displayRollData(rollData, this.attacker.name, 'chat-resultat-attaque.html'); + await RdDResolutionTable.displayRollData(rollData, this.attacker, 'chat-resultat-attaque.html'); if (!await this.accorderEntite('avant-defense')) { return; @@ -304,7 +304,7 @@ export class RdDCombat { return items.filter(item => RdDItemArme.getCategorieParade(item) == 'boucliers') default: // Le fléau ne peut être paré qu’au bouclier p115 - if (competence.name == "Fléau"){ + if (competence.name == "Fléau") { return items.filter(item => RdDItemArme.getCategorieParade(item) == 'boucliers') } return items.filter(item => RdDItemArme.getCategorieParade(item)); @@ -327,8 +327,8 @@ export class RdDCombat { /* -------------------------------------------- */ async _onAttaqueEchec(rollData) { console.log("RdDCombat.onAttaqueEchec >>>", rollData); - await RdDResolutionTable.displayRollData(rollData, this.attacker.name, 'chat-resultat-attaque.html'); - + await RdDResolutionTable.displayRollData(rollData, this.attacker, 'chat-resultat-attaque.html'); + } /* -------------------------------------------- */ @@ -376,12 +376,12 @@ export class RdDCombat { competence: this.defender.getCompetence(compName), arme: armeParade, surprise: this.defender.getSurprise(), - needParadeSignificative: this.needParadeSignificative(attackerRoll, armeParade), - diviseur: this._getDiviseurSignificative(attackerRoll, armeParade), - needResist: this._needArmeResist(armeAttaque, armeParade), + needParadeSignificative: RdDItemArme.needParadeSignificative(armeAttaque, armeParade), + needResist: RdDItemArme.needArmeResist(armeAttaque, armeParade), carac: this.defender.data.data.carac, show: {} }; + rollData.diviseur = this._getDiviseurSignificative(rollData); if (isCreature) { RdDItemCompetence.setRollDataCreature(rollData); } @@ -389,34 +389,12 @@ export class RdDCombat { } /* -------------------------------------------- */ - _getDiviseurSignificative(attackerRoll, armeParade = undefined) { - let facteurSign = this.defender.getDiviseurSignificative(); - if (RdDCombat.isAttaqueFinesse(attackerRoll)) { + _getDiviseurSignificative(rollData) { + let facteurSign = (this.defender.isDemiSurprise() || rollData.needParadeSignificative) ? 2 : 1; + if (RdDBonus.isDefenseAttaqueFinesse(rollData)) { facteurSign *= 2; } - if (this.needParadeSignificative(attackerRoll, armeParade)) { - facteurSign *= 2; - } - return Math.min(4, facteurSign); - - } - - static isAttaqueFinesse(attackerRoll) { - return attackerRoll && attackerRoll.particuliere == 'finesse'; - } - - needParadeSignificative(attackerRoll, armeParade) { - return attackerRoll.arme && armeParade && - RdDItemArme.needParadeSignificative(attackerRoll.arme, armeParade); - } - - /* -------------------------------------------- */ - _needArmeResist(armeAttaque, armeParade) { - // Epées parant une arme de bois (cf. page 115 ), une résistance est nécessaire - let attCategory = RdDItemArme.getCategorieParade(armeAttaque); - let defCategory = RdDItemArme.getCategorieParade(armeParade); - - return attCategory.match(/epees-/) && defCategory.match(/(haches|lances)/); + return facteurSign; } /* -------------------------------------------- */ @@ -437,7 +415,7 @@ export class RdDCombat { await this.computeRecul(rollData); await this.computeDeteriorationArme(rollData); - await RdDResolutionTable.displayRollData(rollData, this.defender.name, 'chat-resultat-parade.html'); + await RdDResolutionTable.displayRollData(rollData, this.defender, 'chat-resultat-parade.html'); } @@ -459,7 +437,7 @@ export class RdDCombat { await this.computeRecul(rollData); - await RdDResolutionTable.displayRollData(rollData, this.defender.name, 'chat-resultat-parade.html'); + await RdDResolutionTable.displayRollData(rollData, this.defender, 'chat-resultat-parade.html'); this._sendMessageEncaisser(rollData.attackerRoll); } @@ -498,10 +476,10 @@ export class RdDCombat { competence: competence, surprise: this.defender.getSurprise(), surpriseDefenseur: this.defender.getSurprise(), - diviseur: this._getDiviseurSignificative(attackerRoll), carac: this.defender.data.data.carac, show: {} }; + rollData.diviseur = this._getDiviseurSignificative(rollData); if (this.defender.isCreature()) { RdDItemCompetence.setRollDataCreature(rollData); @@ -522,7 +500,7 @@ export class RdDCombat { async _onEsquiveNormale(rollData) { console.log("RdDCombat._onEsquiveNormal >>>", rollData); - await RdDResolutionTable.displayRollData(rollData, this.defender.name, 'chat-resultat-esquive.html'); + await RdDResolutionTable.displayRollData(rollData, this.defender, 'chat-resultat-esquive.html'); } /* -------------------------------------------- */ @@ -542,7 +520,7 @@ export class RdDCombat { await this.computeRecul(rollData); - await RdDResolutionTable.displayRollData(rollData, this.defender.name, 'chat-resultat-esquive.html'); + await RdDResolutionTable.displayRollData(rollData, this.defender, 'chat-resultat-esquive.html'); this._sendMessageEncaisser(rollData.attackerRoll); } @@ -600,7 +578,9 @@ export class RdDCombat { if (this._isAttaqueCauseRecul(attaque)) { let impactRecul = this._computeImpactRecul(attaque); - const agilite = this.defender.data.data.carac.agilite.value; + const agilite = this.defender.isEntiteCauchemar() + ? this.defender.data.data.carac.reve.value + : this.defender.data.data.carac.agilite.value; let rollRecul = await RdDResolutionTable.rollData({ caracValue: 10, finalLevel: impactRecul, showDice: false }); @@ -679,34 +659,34 @@ export class RdDCombat { } /* -------------------------------------------- */ - static async displayActorCombatStatus( actor ) { + static async displayActorCombatStatus(actor) { let rollMode = game.settings.get("core", "rollMode"); - let rollData = { - alias: actor.name, + let rollData = { + alias: actor.name, etatGeneral: actor.getEtatGeneral(), - isSonne: actor.getSonne(), + isSonne: actor.getSonne(), blessuresStatus: actor.computeResumeBlessure(), SConst: actor.getSConst(), actorId: actor.data._id, isGrave: false, isCritique: false } - if ( actor.countBlessuresByName("critiques") > 0 ) { // Pour éviter le cumul grave + critique + if (actor.countBlessuresByName("critiques") > 0) { // Pour éviter le cumul grave + critique rollData.isCritique = true; - } else if ( actor.countBlessuresByName("graves") > 0) { + } else if (actor.countBlessuresByName("graves") > 0) { rollData.isGrave = true; } let content = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-summary.html`, rollData); - ChatUtility.createChatMessage({ content: content }, rollMode, actor.name); + ChatUtility.createChatMessage({ content: content }, rollMode, actor.name); } /* -------------------------------------------- */ - static updateCombatRound( combat, data) { + static updateCombatRound(combat, data) { if (combat.data.round != 0 && combat.turns && combat.data.active) { let turn = combat.turns.find(t => t.tokenId == combat.current.tokenId); - this.displayActorCombatStatus( turn.actor ); + this.displayActorCombatStatus(turn.actor); // TODO Playaudio ?? } } - + } \ No newline at end of file diff --git a/module/rdd-resolution-table.js b/module/rdd-resolution-table.js index 521d760a..17bf951a 100644 --- a/module/rdd-resolution-table.js +++ b/module/rdd-resolution-table.js @@ -1,8 +1,6 @@ import { ChatUtility } from "./chat-utility.js"; -import { RdDItemArme } from "./item-arme.js"; +import { RollDataAjustements as RollDataAjustements } from "./rolldata-ajustements.js"; import { Misc } from "./misc.js"; -import { RdDBonus } from "./rdd-bonus.js"; -import { RdDCombat } from "./rdd-combat.js"; import { RdDDice } from "./rdd-dice.js"; /** @@ -93,76 +91,16 @@ export class RdDResolutionTable { } /* -------------------------------------------- */ - static async buildRollDataHtml(rollData, template = 'chat-resultat-general.html') { - rollData.ajustements = RdDResolutionTable._buildAjustements(rollData); - rollData.show = rollData.show || {}; - - return await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/${template}`, rollData); + static async displayRollData(rollData, actor = undefined, template = 'chat-resultat-general.html') { + ChatUtility.chatWithRollMode( + { content: await RdDResolutionTable.buildRollDataHtml(rollData, actor, template) }, + actor?.userName ?? game.user.name) } /* -------------------------------------------- */ - static async displayRollData(rollData, userName, template = 'chat-resultat-general.html') { - - ChatUtility.chatWithRollMode( - { content: await RdDResolutionTable.buildRollDataHtml(rollData, template) }, - userName) - } - - static _buildAjustements(rollData) { - let list = []; - if (rollData.competence) { - list.push({ label: rollData.competence.name, value: rollData.competence.data.niveau }); - } - if (rollData.tactique) { - const surprise = RdDBonus.find(rollData.tactique); - list.push({ label: surprise.descr, value: surprise.attaque }); - } - if (rollData.surpriseDefenseur) { - const surprise = RdDBonus.find(rollData.surpriseDefenseur); - list.push({ label: surprise.descr, value: surprise.attaque }); - } - if (rollData.diffLibre != undefined) { - const label = rollData.selectedSort?.name ?? 'Libre'; - list.push({ label: label, value: rollData.diffLibre }); - } - if (rollData.diffConditions != undefined) { - list.push({ label: 'Conditions', value: rollData.diffConditions }); - } - if (rollData.etat != undefined) { - list.push({ label: 'Etat', value: rollData.etat }); - } - if (rollData.selectedCarac?.label == 'Volonté' && rollData.moral != undefined) { - list.push({ label: 'Moral', value: rollData.moral }); - } - if (RdDResolutionTable.isAjustementAstrologique(rollData)) { - list.push({ label: 'Astrologique', value: rollData.ajustementAstrologique ?? 0 }); - } - if (rollData.rolled.bonus && rollData.selectedSort) { - list.push({ descr: `Bonus de case: ${rollData.rolled.bonus}%` }); - } - if (rollData.diviseur > 1) { - list.push({ descr: `Facteur significative ×${RdDResolutionTable._getFractionHtml(rollData.diviseur)}` }); - } - if (RdDCombat.isAttaqueFinesse(rollData.attackerRoll)) { - list.push({ descr: 'Attaque particulière en finesse' }); - } - if (rollData.needParadeSignificative) { - const catAttaque = RdDItemArme.getNomCategorieParade(rollData.attackerRoll.arme); - const catParade = RdDItemArme.getNomCategorieParade(rollData.arme); - list.push({ descr: `${catAttaque} vs ${catParade}` }); - } - if (rollData.surprise) { - list.push({ descr: RdDBonus.find(rollData.surprise).descr }); - } - return list; - } - static _getFractionHtml(diviseur) { - if (!diviseur || diviseur <= 1) return undefined; - switch (diviseur || 1) { - case 2: return '½'; - case 4: return '¼'; - default: return '1/' + diviseur; - } + static async buildRollDataHtml(rollData, actor, template = 'chat-resultat-general.html') { + rollData.show = rollData.show || {}; + return await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/${template}`, rollData); } /* -------------------------------------------- */ @@ -182,7 +120,7 @@ export class RdDResolutionTable { rolled.caracValue = caracValue; rolled.finalLevel = finalLevel; rolled.bonus = bonus; - rolled.factorHtml = RdDResolutionTable._getFractionHtml(diviseur); + rolled.factorHtml = Misc.getFractionHtml(diviseur); return rolled; } @@ -225,10 +163,10 @@ export class RdDResolutionTable { /* -------------------------------------------- */ static isAjustementAstrologique(rollData) { - if (rollData.selectedCarac && rollData.selectedCarac.label.toLowerCase().includes('chance')) { + if (rollData.selectedCarac?.label.toLowerCase().includes('chance')) { return true; } - if (rollData.selectedSort && rollData.selectedSort.data.isrituel) { + if (rollData.selectedSort?.data.isrituel) { return true; } return false; @@ -323,12 +261,12 @@ export class RdDResolutionTable { /* -------------------------------------------- */ static buildHTMLResults(caracValue, levelValue) { let cell = this.computeChances(caracValue, levelValue); - cell.epart = cell.epart>99? 'N/A' : cell.epart; - cell.etotal = cell.etotal>100? 'N/A' : cell.etotal; + cell.epart = cell.epart > 99 ? 'N/A' : cell.epart; + cell.etotal = cell.etotal > 100 ? 'N/A' : cell.etotal; cell.score = Math.min(cell.score, 99); return ` - + Particulière: ${cell.part} - Significative: ${cell.sign} - Réussite: ${cell.score} diff --git a/module/rdd-roll-resolution-table.js b/module/rdd-roll-resolution-table.js index fc6c1844..6603babc 100644 --- a/module/rdd-roll-resolution-table.js +++ b/module/rdd-roll-resolution-table.js @@ -61,7 +61,7 @@ export class RdDRollResolutionTable extends Dialog { async onAction(html) { await RdDResolutionTable.rollData(this.rollData); console.log("RdDRollResolutionTable -=>", this.rollData, this.rollData.rolled); - await RdDResolutionTable.displayRollData(this.rollData, game.user.name); + await RdDResolutionTable.displayRollData(this.rollData); } /* -------------------------------------------- */ @@ -82,8 +82,8 @@ export class RdDRollResolutionTable extends Dialog { $("#roll-param").text(rollData.selectedCarac.value + " / " + Misc.toSignedString(rollData.finalLevel)); $(".table-resolution").remove(); $("#resolutionTable").append(RdDResolutionTable.buildHTMLTable(rollData.caracValue, rollData.finalLevel, 1, 20, -10, 10)); - $(".span-valeur").remove(); - $("#resolutionValeurs").append(RdDResolutionTable.buildHTMLResults(rollData.caracValue, rollData.finalLevel)); + $(".table-proba-reussite").remove(); + $("#tableProbaReussite").append(RdDResolutionTable.buildHTMLResults(rollData.caracValue, rollData.finalLevel)); } // Setup everything onload diff --git a/module/rdd-roll.js b/module/rdd-roll.js index f81d4aa5..66277ce4 100644 --- a/module/rdd-roll.js +++ b/module/rdd-roll.js @@ -1,8 +1,11 @@ +import { referenceAjustements, RollDataAjustements } from "./rolldata-ajustements.js"; import { HtmlUtility } from "./html-utility.js"; import { RdDItemCompetence } from "./item-competence.js"; +import { RdDItemMeditation } from "./item-meditation.js"; import { RdDItemSort } from "./item-sort.js"; import { Misc } from "./misc.js"; import { RdDBonus } from "./rdd-bonus.js"; +import { RdDCarac } from "./rdd-carac.js"; import { RdDResolutionTable } from "./rdd-resolution-table.js"; /** @@ -24,18 +27,17 @@ export class RdDRoll extends Dialog { if (dialogConfig.options) { mergeObject(options, dialogConfig.options, { overwrite: true }) } - return new RdDRoll(actor, rollData, html, options, actions, dialogConfig.close ); + return new RdDRoll(actor, rollData, html, options, actions, dialogConfig.close); } /* -------------------------------------------- */ static _setDefaultOptions(actor, rollData) { - let defaultRollData = { alias: actor.name, ajustementsConditions: CONFIG.RDD.ajustementsConditions, difficultesLibres: CONFIG.RDD.difficultesLibres, - etat: actor.data.data.compteurs.etat.value, - moral: actor.isPersonnage() ? actor.data.data.compteurs.moral.value : 0, + etat: actor.getEtatGeneral(), + moral: actor.getMoralTotal(), carac: actor.data.data.carac, finalLevel: 0, diffConditions: rollData.arme ? RdDBonus.bonusAttaque(rollData.surpriseDefenseur) : 0, @@ -43,17 +45,22 @@ export class RdDRoll extends Dialog { editLibre: true, editConditions: true, forceValue: actor.getForceValue(), - malusArmureValue: actor.isPersonnage() ? actor.data.data.attributs?.malusarmure?.value ?? 0 : 0, + malusArmureValue: actor.getMalusArmure(), surencMalusFlag: actor.isPersonnage() ? (actor.data.data.compteurs.surenc.value < 0) : false, - surencMalusValue: actor.isPersonnage() ? actor.data.data.compteurs.surenc.value : 0, + surencMalusValue: actor.getSurenc(), useMalusSurenc: false, + use: { + surenc: false, + encTotal: false, + }, isMalusEncombrementTotal: RdDItemCompetence.isMalusEncombrementTotal(rollData.competence), useMalusEncTotal: false, encTotal: actor.getEncTotal(), ajustementAstrologique: actor.ajustementAstrologique(), - surprise: actor.getSurprise() + surprise: actor.getSurprise(), } - mergeObject(rollData, defaultRollData, { overwrite: false }); + mergeObject(rollData, defaultRollData, { recursive: true, overwrite: false }); + RollDataAjustements.calcul(rollData, actor); } /* -------------------------------------------- */ @@ -106,47 +113,10 @@ export class RdDRoll extends Dialog { this.bringToTop(); - var rollData = this.rollData; - var actor = this.actor; var dialog = this; - - function updateRollResult(rollData) { - rollData.dmg = rollData.attackerRoll?.dmg ?? RdDBonus.dmg(rollData, actor.getBonusDegat()); - rollData.finalLevel = dialog._computeFinalLevel(rollData); - rollData.caracValue = parseInt(rollData.selectedCarac.value); - rollData.coupsNonMortels = (rollData.attackerRoll?.dmg.mortalite ?? rollData.dmg.mortalite) == 'non-mortel'; - let dmgText = Misc.toSignedString(rollData.dmg.total); - if (rollData.coupsNonMortels) { - dmgText = '(' + dmgText + ')'; - } - - HtmlUtility._showControlWhen($(".diffMoral"), rollData.selectedCarac == actor.data.data.carac.volonte); - - HtmlUtility._showControlWhen($("#etat-general"), !dialog._isIgnoreEtatGeneral(rollData)); - HtmlUtility._showControlWhen($("#ajust-astrologique"), RdDResolutionTable.isAjustementAstrologique(rollData)); - - // Sort management - if (rollData.selectedSort) { - rollData.bonus = RdDItemSort.getCaseBonus(rollData.selectedSort, rollData.coord); - //console.log("Toggle show/hide", rollData.selectedSort); - HtmlUtility._showControlWhen($("#div-sort-difficulte"), RdDItemSort.isDifficulteVariable(rollData.selectedSort)) - HtmlUtility._showControlWhen($("#div-sort-ptreve"), RdDItemSort.isCoutVariable(rollData.selectedSort)) - } - - // Mise à jour valeurs - $("#roll-param").text(rollData.selectedCarac.value + " / " + Misc.toSignedString(rollData.finalLevel)); - $("#compdialogTitle").text(dialog._getTitle(rollData)); - $('#coupsNonMortels').prop('checked', rollData.coupsNonMortels); - $("#dmg-arme-actor").text(dmgText); - $("#defenseur-surprise").text(RdDBonus.description(rollData.surpriseDefenseur)); - $(".table-resolution").remove(); - $("#resolutionTable").append(RdDResolutionTable.buildHTMLTableExtract(rollData.caracValue, rollData.finalLevel)); - $(".span-valeur").remove(); - $("#resolutionValeurs").append(RdDResolutionTable.buildHTMLResults(rollData.caracValue, rollData.finalLevel)); - } - - // Setup everything onload - $(function () { + + function onLoad() { + let rollData = dialog.rollData; // Update html, according to data if (rollData.competence) { // Set the default carac from the competence item @@ -156,109 +126,126 @@ export class RdDRoll extends Dialog { RdDItemSort.setCoutReveReel(rollData.selectedSort); $("#diffLibre").val(Misc.toInt(rollData.diffLibre)); $("#diffConditions").val(Misc.toInt(rollData.diffConditions)); - updateRollResult(rollData); - }); + dialog.updateRollResult(); + } + + // Setup everything onload + $(function () { onLoad(); }); // Update ! html.find('#diffLibre').change((event) => { - rollData.diffLibre = Misc.toInt(event.currentTarget.value); // Update the selected bonus/malus - //console.log("RdDRollSelectDialog","BM CLICKED !!!", rollData); - updateRollResult(rollData); + this.rollData.diffLibre = Misc.toInt(event.currentTarget.value); // Update the selected bonus/malus + this.updateRollResult(); }); html.find('#diffConditions').change((event) => { - rollData.diffConditions = Misc.toInt(event.currentTarget.value); // Update the selected bonus/malus - //console.log("RdDRollSelectDialog","BM CLICKED !!!", rollData); - updateRollResult(rollData); + this.rollData.diffConditions = Misc.toInt(event.currentTarget.value); // Update the selected bonus/malus + this.updateRollResult(); }); html.find('#carac').change((event) => { let caracKey = event.currentTarget.value; - this.rollData.selectedCarac = rollData.carac[caracKey]; // Update the selectedCarac - //console.log("RdDRollSelectDialog","CARAC CLICKED !!!", rollData); - updateRollResult(rollData); + this.rollData.selectedCarac = this.rollData.carac[caracKey]; // Update the selectedCarac + this.updateRollResult(); }); html.find('#draconic').change((event) => { let draconicKey = Misc.toInt(event.currentTarget.value); - this.rollData.competence = rollData.draconicList[draconicKey]; // Update the selectedCarac - //console.log("RdDRollSelectDialog","CARAC CLICKED !!!", rollData); - updateRollResult(rollData); + this.rollData.competence = this.rollData.draconicList[draconicKey]; // Update the selectedCarac + this.updateRollResult(); }); html.find('#sort').change((event) => { let sortKey = Misc.toInt(event.currentTarget.value); - this.rollData.selectedSort = rollData.sortList[sortKey]; // Update the selectedCarac - this.rollData.bonus = RdDItemSort.getCaseBonus(rollData.selectedSort, rollData.coord); - RdDItemSort.setCoutReveReel(rollData.selectedSort); - //console.log("RdDRollSelectDialog - Sort selection", rollData.selectedSort); - updateRollResult(rollData); + this.rollData.selectedSort = this.rollData.sortList[sortKey]; // Update the selectedCarac + this.rollData.bonus = RdDItemSort.getCaseBonus(this.rollData.selectedSort, this.rollData.coord); + RdDItemSort.setCoutReveReel(this.rollData.selectedSort); + this.updateRollResult(); }); html.find('#ptreve-variable').change((event) => { let ptreve = Misc.toInt(event.currentTarget.value); this.rollData.selectedSort.data.ptreve_reel = ptreve; console.log("RdDRollSelectDialog - Cout reve", ptreve); - updateRollResult(rollData); + this.updateRollResult(); }); html.find('#ptreve-variable').change((event) => { let ptreve = Misc.toInt(event.currentTarget.value); this.rollData.selectedSort.data.ptreve_reel = ptreve; // Update the selectedCarac console.log("RdDRollSelectDialog - Cout reve", ptreve); - updateRollResult(rollData); + this.updateRollResult(); }); html.find('#coupsNonMortels').change((event) => { this.rollData.dmg.mortalite = event.currentTarget.checked ? "non-mortel" : "mortel"; - updateRollResult(rollData); + this.updateRollResult(); }); html.find('#tactique-combat').change((event) => { this.rollData.tactique = event.currentTarget.value; - updateRollResult(rollData); + this.updateRollResult(); }); html.find('#useMalusSurenc').change((event) => { this.rollData.useMalusSurenc = event.currentTarget.checked; - updateRollResult(rollData); + this.updateRollResult(); }); html.find('#useMalusEncTotal').change((event) => { this.rollData.useMalusEncTotal = event.currentTarget.checked; - updateRollResult(rollData); + this.updateRollResult(); }); // Section Méditation - html.find('#isHeure').change((event) => { - this.rollData.isHeure = event.currentTarget.checked; - updateRollResult(rollData); + html.find('.conditionMeditation').change((event) => { + let condition = event.currentTarget.attributes['id'].value; + this.rollData.conditionMeditation[condition] = event.currentTarget.checked; + this.updateRollResult(); }); - html.find('#isPurification').change((event) => { - this.rollData.isPurification = event.currentTarget.checked; - updateRollResult(rollData); - }); - html.find('#isVeture').change((event) => { - this.rollData.isVeture = event.currentTarget.checked; - updateRollResult(rollData); - }); - html.find('#isComportement').change((event) => { - this.rollData.isComportement = event.currentTarget.checked; - updateRollResult(rollData); - }); - } - /* -------------------------------------------- */ - _isIgnoreEtatGeneral(rollData) { - return rollData.selectedCarac.ignoreEtatGeneral; - } + async updateRollResult() { + let rollData = this.rollData; - /* -------------------------------------------- */ - _computeDiffMeditation( rollData ) { - let diff = 0; - if ( rollData.meditation ) { - diff = (!rollData.isHeure) ? diff - 2 : diff; - diff = (!rollData.isVeture) ? diff - 2 : diff; - diff = (!rollData.isComportement) ? diff - 2 : diff; - diff = (!rollData.isisPuritication) ? diff - 2 : diff; - diff = diff - rollData.meditation.data.malus; // Malus permanent éventuel + rollData.dmg = rollData.attackerRoll?.dmg ?? RdDBonus.dmg(rollData, this.actor.getBonusDegat()); + rollData.caracValue = parseInt(rollData.selectedCarac.value); + rollData.coupsNonMortels = (rollData.attackerRoll?.dmg.mortalite ?? rollData.dmg.mortalite) == 'non-mortel'; + let dmgText = Misc.toSignedString(rollData.dmg.total); + + if (rollData.coupsNonMortels) { + dmgText = '(' + dmgText + ')'; } - return diff; + if (rollData.selectedSort) { + rollData.bonus = RdDItemSort.getCaseBonus(rollData.selectedSort, rollData.coord); + } + + RollDataAjustements.calcul(rollData, this.actor); + rollData.finalLevel = this._computeFinalLevel(rollData); + + HtmlUtility._showControlWhen($(".diffMoral"), rollData.ajustements.moralTotal.used); + HtmlUtility._showControlWhen($("#etat-general"), !RdDCarac.isIgnoreEtatGeneral(rollData.selectedCarac)); + HtmlUtility._showControlWhen($("#ajust-astrologique"), RdDResolutionTable.isAjustementAstrologique(rollData)); + + // Sort management + if (rollData.selectedSort) { + rollData.bonus = RdDItemSort.getCaseBonus(rollData.selectedSort, rollData.coord); + //console.log("Toggle show/hide", rollData.selectedSort); + HtmlUtility._showControlWhen($("#div-sort-difficulte"), RdDItemSort.isDifficulteVariable(rollData.selectedSort)) + HtmlUtility._showControlWhen($("#div-sort-ptreve"), RdDItemSort.isCoutVariable(rollData.selectedSort)) + } + + // Mise à jour valeurs + $("#compdialogTitle").text(this._getTitle(rollData)); + $('#coupsNonMortels').prop('checked', rollData.coupsNonMortels); + $("#dmg-arme-actor").text(dmgText); + $("#defenseur-surprise").text(RdDBonus.description(rollData.surpriseDefenseur)); + $('.table-ajustement').remove(); + $(".table-resolution").remove(); + $(".table-proba-reussite").remove(); + $("#tableAjustements").append(await this.buildAjustements(rollData)); + $("#tableResolution").append(RdDResolutionTable.buildHTMLTableExtract(rollData.caracValue, rollData.finalLevel)); + $("#tableProbaReussite").append(RdDResolutionTable.buildHTMLResults(rollData.caracValue, rollData.finalLevel)); + } + + + async buildAjustements(rollData){ + const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-roll-ajustements.html`, rollData); + return html; } /* -------------------------------------------- */ _computeFinalLevel(rollData) { - const etat = this._isIgnoreEtatGeneral(rollData) ? 0 : Misc.toInt(rollData.etat); + const etat = RdDCarac.isIgnoreEtatGeneral(rollData.selectedCarac) ? 0 : rollData.etat; const diffConditions = Misc.toInt(rollData.diffConditions); const malusSurenc = (rollData.useMalusSurenc) ? rollData.surencMalusValue : 0; const bonusTactique = RdDBonus.bonusAttaque(rollData.tactique); @@ -267,12 +254,14 @@ export class RdDRoll extends Dialog { // Gestion malus armure const malusArmureValue = this._computeMalusArmure(rollData); - const diffMeditation = this._computeDiffMeditation( rollData ); + const diffMeditation = RdDItemMeditation.calculDifficulte(rollData); const diffLibre = this._computeDiffLibre(rollData); const diffCompetence = this._computeDiffCompetence(rollData); const diffMoral = rollData.selectedCarac == this.actor.data.data.carac.volonte ? rollData.moral : 0; - return etat + diffCompetence + diffLibre + diffMoral + diffConditions + malusSurenc + malusEncTotal + malusArmureValue + diffMeditation + ajustementChance + bonusTactique; + let ajust = RollDataAjustements.sum(rollData.ajustements); + return ajust; + //return etat + diffCompetence + diffLibre + diffMoral + diffConditions + malusSurenc + malusEncTotal + malusArmureValue + diffMeditation + ajustementChance + bonusTactique; } /* -------------------------------------------- */ @@ -297,7 +286,7 @@ export class RdDRoll extends Dialog { _computeMalusArmure(rollData) { let malusArmureValue = 0; - if (rollData.malusArmureValue != 0 && (rollData.selectedCarac.label == "Agilité" || rollData.selectedCarac.label == "Dérobée")) { + if (rollData.malusArmureValue && (rollData.selectedCarac.label == "Agilité" || rollData.selectedCarac.label == "Dérobée")) { $("#addon-message").text("Malus armure appliqué : " + rollData.malusArmureValue); malusArmureValue = rollData.malusArmureValue; } else { diff --git a/module/rdd-tmr-dialog.js b/module/rdd-tmr-dialog.js index 8bebbf2d..ebef73c7 100644 --- a/module/rdd-tmr-dialog.js +++ b/module/rdd-tmr-dialog.js @@ -239,7 +239,7 @@ export class RdDTMRDialog extends Dialog { const draconic = this.actor.getBestDraconic(); const carac = this.actor.getReveActuel(); - const etatGeneral = this.actor.data.data.compteurs.etat.value; + const etatGeneral = this.actor.getEtatGeneral(); const difficulte = draconic.data.niveau - this.currentRencontre.force + etatGeneral; console.log("Maitriser", carac, draconic.data.niveau, this.currentRencontre.force, etatGeneral); @@ -329,7 +329,7 @@ export class RdDTMRDialog extends Dialog { tmrpos.innerHTML = this.actor.data.data.reve.tmrpos.coord + " (" + tmr.label + ")"; let etat = document.getElementById("tmr-etatgeneral-value"); - etat.innerHTML = this.actor.data.data.compteurs.etat.value; + etat.innerHTML = this.actor.getEtatGeneral(); let refoulement = document.getElementById("tmr-refoulement-value"); refoulement.innerHTML = this.actor.data.data.reve.refoulement.value; @@ -389,7 +389,7 @@ export class RdDTMRDialog extends Dialog { let draconic = this.actor.getBestDraconic(); let carac = this.actor.getReveActuel(); - const etatGeneral = this.actor.data.data.compteurs.etat.value + const etatGeneral = this.actor.getEtatGeneral(); let difficulte = draconic.data.niveau - 7; let rolled = await RdDResolutionTable.roll(carac, difficulte); diff --git a/module/rdd-utility.js b/module/rdd-utility.js index 314e200a..d277ee83 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -183,6 +183,7 @@ export class RdDUtility { 'systems/foundryvtt-reve-de-dragon/templates/niveau-ethylisme.html', 'systems/foundryvtt-reve-de-dragon/templates/casetmr-specific-list.html', // Dialogs + 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-ajustements.html', 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-resolution.html', 'systems/foundryvtt-reve-de-dragon/templates/dialog-competence.html', 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html', @@ -673,7 +674,7 @@ export class RdDUtility { /* -------------------------------------------- */ static currentFatigueMalus( value, max) { - max = Math.min(1, Math.max(max, 60)); + max = Math.max(1, Math.min(max, 60)); value = Math.min(max*2, Math.max(0, value)); let fatigueTab = fatigueMatrix[max]; diff --git a/module/rolldata-ajustements.js b/module/rolldata-ajustements.js new file mode 100644 index 00000000..9a687a29 --- /dev/null +++ b/module/rolldata-ajustements.js @@ -0,0 +1,150 @@ +import { RdDItemArme } from "./item-arme.js"; +import { RdDItemCompetence } from "./item-competence.js"; +import { RdDItemMeditation } from "./item-meditation.js"; +import { RdDItemSort } from "./item-sort.js"; +import { Misc } from "./misc.js"; +import { RdDBonus } from "./rdd-bonus.js"; +import { RdDCarac } from "./rdd-carac.js"; + +/** + * tous les ajustements pouvant s'appliquer. + * un ajustement se compose de `function(rollData, actor)` : + * - isVisible: indique si l'ajustement sera visible (pour les cas où il peut être sélectionné) + * - isUsed: évalue si l'ajustement indique s'il est actif ou non + * - getLabel: un libellé texte pour l'affichage de l'ajustement + * - getValue: une valeur numérique correspondant à un modificateur entier + * - getDescr: une valeur textuelle pour les informations non numériques (demi-surprise, bonus de case, ...) + */ +export const referenceAjustements = { + competence: { + isUsed: (rollData, actor) => rollData.competence, + getLabel: (rollData, actor) => rollData.competence?.name, + getValue: (rollData, actor) => rollData.competence?.data?.niveau, + }, + meditation: { + isUsed: (rollData, actor) => rollData.meditation, + getLabel: (rollData, actor) => 'Méditation', + getValue: (rollData, actor) => RdDItemMeditation.calculDifficulte(rollData) + }, + diffLibre: { + isUsed: (rollData, actor) => rollData.diffLibre != undefined, + getLabel: (rollData, actor) => rollData.selectedSort?.name ?? rollData.attackerRoll ? 'Imposée' : 'Libre', + getValue: (rollData, actor) => rollData.selectedSort + ? RdDItemSort.getDifficulte(rollData.selectedSort, rollData.diffLibre) + : rollData.diffLibre ?? rollData.competence?.data.default_diffLibre ?? 0 + }, + diffConditions: { + isUsed: (rollData, actor) => rollData.diffConditions != undefined, + getLabel: (rollData, actor) => 'Conditions', + getValue: (rollData, actor) => rollData.diffConditions + }, + tactique: { + isUsed: (rollData, actor) => rollData.tactique, + getLabel: (rollData, actor) => RdDBonus.find(rollData.tactique).descr, + getValue: (rollData, actor) => RdDBonus.find(rollData.tactique).attaque, + }, + attaqueDefenseurSurpris: { + isUsed: (rollData, actor) => rollData.surpriseDefenseur, + getLabel: (rollData, actor) => RdDBonus.find(rollData.surpriseDefenseur).descr, + getValue: (rollData, actor) => RdDBonus.find(rollData.surpriseDefenseur).attaque, + }, + etat: { + isUsed: (rollData, actor) => !RdDCarac.isIgnoreEtatGeneral(rollData.selectedCarac), + getLabel: (rollData, actor) => 'Etat général', + getValue: (rollData, actor) => actor.getEtatGeneral() + }, + malusArmure: { + isVisible: (rollData, actor) => RdDCarac.isAgiliteOuDerivee(rollData.competence), + isUsed: (rollData, actor) => RdDCarac.isAgiliteOuDerivee(rollData.selectedCarac), + getLabel: (rollData, actor) => 'Malus armure', + getValue: (rollData, actor) => actor.getMalusArmure() + }, + encTotal: { + isVisible: (rollData, actor) => RdDItemCompetence.isMalusEncombrementTotal(rollData.competence), + isUsed: (rollData, actor) => rollData.useMalusEncTotal, + getLabel: (rollData, actor) => 'Encombrement total', + getValue: (rollData, actor) => -actor.getEncTotal() + }, + surenc: { + isVisible: (rollData, actor) => rollData.useMalusSurenc, + isUsed: (rollData, actor) => rollData.useMalusSurenc, + getLabel: (rollData, actor) => 'Sur-encombrement', + getValue: (rollData, actor) => actor.getSurenc() + }, + moral: { + isVisible: (rollData, actor) => RdDCarac.isActionPhysique(rollData.selectedCarac), + isUsed: (rollData, actor) => rollData.use?.moral, + getLabel: (rollData, actor) => 'Moral', + getValue: (rollData, actor) => 1 + }, + moralTotal: { + isUsed: (rollData, actor) => RdDCarac.isVolonte(rollData.selectedCarac), + getLabel: (rollData, actor) => 'Moral', + getValue: (rollData, actor) => actor.getMoralTotal() + }, + astrologique: { + isUsed: (rollData, actor) => RdDBonus.isAjustementAstrologique(rollData), + getLabel: (rollData, actor) => 'Astrologique', + getValue: (rollData, actor) => actor.ajustementAstrologique() + }, + facteurSign: { + isUsed: (rollData, actor) => rollData.diviseur > 1, + getDescr: (rollData, actor) => rollData.diviseur > 1 ? `Facteur significative ×${Misc.getFractionHtml(rollData.diviseur)}` : '' + }, + finesse: { + isUsed: (rollData, actor) => RdDBonus.isDefenseAttaqueFinesse(rollData), + getDescr: (rollData, actor) => 'Attaque particulière en finesse', + }, + armeParade: { + isUsed: (rollData, actor) => RdDItemArme.needParadeSignificative(rollData.attackerRoll?.arme, rollData.arme), + getDescr: (rollData, actor) => rollData.attackerRoll && rollData.arme? `${RdDItemArme.getNomCategorieParade(rollData.attackerRoll?.arme)} vs ${RdDItemArme.getNomCategorieParade(rollData.arme)}`: '' + }, + surprise: { + isUsed: (rollData, actor) => actor.getSurprise(), + getDescr: (rollData, actor) => RdDBonus.find(actor.getSurprise()).descr + }, + bonusCase: { + isUsed: (rollData, actor) => rollData.selectedSort && rollData.coord, + getDescr: (rollData, actor) => rollData.selectedSort && rollData.coord ? `Bonus de case: ${RdDItemSort.getCaseBonus(rollData.selectedSort, rollData.coord)}%`: '' + } +} + +export class RollDataAjustements { + + /* -------------------------------------------- */ + static calcul(rollData, actor) { + rollData.ajustements = {}; + for (var key in referenceAjustements) { + const reference = referenceAjustements[key]; + rollData.ajustements[key] = { + used: reference.isUsed(rollData, actor), + label: reference.getLabel && reference.getLabel(rollData, actor), + value: reference.getValue && reference.getValue(rollData, actor), + descr: reference.getDescr && reference.getDescr(rollData, actor) + } + } + } + + // /* -------------------------------------------- */ + // static calculListe(ajustements, rollData, actor) { + // let list = []; + // for (var key in referenceAjustements) { + // if (referenceAjustements[key].isUsed(rollData, actor)) { + // list.push(Ajustements._apply(referenceAjustements[key], rollData, actor)); + // } + // } + // return list; + // } + /* -------------------------------------------- */ + + static sum(ajustements) { + let sum = 0; + for (var key in ajustements) { + if (ajustements[key].used && !ajustements[key].descr) { + sum += ajustements[key].value; + } + } + return sum; + } + +} diff --git a/styles/simple.css b/styles/simple.css index d88dea36..ddcafc22 100644 --- a/styles/simple.css +++ b/styles/simple.css @@ -410,7 +410,7 @@ table {border: 1px solid #7a7971;} background-color: lightblue; } -#resolutionValeurs{ +#tableProbaReussite{ font-size: 0.8rem; padding: 5px; } @@ -1256,7 +1256,7 @@ display: inline-flex; .tooltip .ttt-ajustements { width: 150px; - background: rgba(220,220,210,0.9); + background: rgba(220,220,210,0.95); border-radius: 6px; font-size: 0.9rem; padding: 3px 0; diff --git a/templates/chat-infojet.html b/templates/chat-infojet.html index 1e89bd77..957ec522 100644 --- a/templates/chat-infojet.html +++ b/templates/chat-infojet.html @@ -4,6 +4,7 @@ {{#if ajustements}}
{{#each ajustements as |item key|}} + {{#if item.used}}
{{#if item.descr}} {{{item.descr}}} @@ -11,6 +12,7 @@ {{item.label}}: {{numberFormat item.value decimals=0 sign=true}} {{/if}}
+ {{/if}} {{/each}}
{{/if}} diff --git a/templates/chat-resultat-attaque.html b/templates/chat-resultat-attaque.html index 82cd90ed..5c5d8538 100644 --- a/templates/chat-resultat-attaque.html +++ b/templates/chat-resultat-attaque.html @@ -1,5 +1,5 @@

{{alias}} attaque: {{arme.name}}

-
{{selectedCarac.label}} / {{competence.name}}, difficulté {{diffLibre}}
+
{{selectedCarac.label}}{{#unless (eq selectedCarac.label competence.name)}} / {{competence.name}}{{/unless}}, difficulté {{diffLibre}}
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
{{#if tactique}} diff --git a/templates/chat-resultat-competence.html b/templates/chat-resultat-competence.html index b300af95..c0ee31d4 100644 --- a/templates/chat-resultat-competence.html +++ b/templates/chat-resultat-competence.html @@ -1,7 +1,9 @@

{{alias}} {{show.title}}: {{#if selectedCarac}}{{selectedCarac.label}} - {{#if competence}} / {{competence.name}}{{/if}} + {{#if competence}} + {{#unless (eq selectedCarac.label competence.name)}} / {{competence.name}}{{/unless}} / {{competence.name}} + {{/if}} {{/if}}

{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}} diff --git a/templates/chat-resultat-esquive.html b/templates/chat-resultat-esquive.html index ef04c432..4efa70dd 100644 --- a/templates/chat-resultat-esquive.html +++ b/templates/chat-resultat-esquive.html @@ -1,5 +1,5 @@ -

{{alias}} esquive

-
{{selectedCarac.label}} / {{competence.name}} attaque à {{diffLibre}}
+

{{alias}} esquive une attaque à {{diffLibre}}

+
{{selectedCarac.label}}{{#unless (eq selectedCarac.label competence.name)}} / {{competence.name}}{{/unless}}
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
diff --git a/templates/chat-resultat-general.html b/templates/chat-resultat-general.html index 0b83a504..35f60a46 100644 --- a/templates/chat-resultat-general.html +++ b/templates/chat-resultat-general.html @@ -1,7 +1,7 @@

{{alias}} {{#if show.title}}{{show.title}}: {{/if}} {{#if selectedCarac}}{{selectedCarac.label}} - {{#if competence}} / {{competence.name}}{{/if}} + {{#if competence}}{{#unless (eq selectedCarac.label competence.name)}} / {{competence.name}}{{/unless}}{{/if}} à {{diffLibre}} {{/if}}

diff --git a/templates/chat-resultat-parade.html b/templates/chat-resultat-parade.html index b1679ec7..25cc4636 100644 --- a/templates/chat-resultat-parade.html +++ b/templates/chat-resultat-parade.html @@ -1,5 +1,5 @@ -

{{alias}} pare: {{arme.name}}

-
{{selectedCarac.label}} / {{competence.name}}, attaque à {{diffLibre}}
+

{{alias}} pare une attaque à {{diffLibre}} - {{arme.name}}

+
{{selectedCarac.label}}{{#unless (eq selectedCarac.label competence.name)}} / {{competence.name}}{{/unless}}
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
diff --git a/templates/dialog-competence.html b/templates/dialog-competence.html index 01ea28dc..5bd5e70a 100644 --- a/templates/dialog-competence.html +++ b/templates/dialog-competence.html @@ -59,18 +59,15 @@ {{/if}}
{{/if}} -
- - - - -
{{>"systems/foundryvtt-reve-de-dragon/templates/dialog-roll-surenc.html"}} {{>"systems/foundryvtt-reve-de-dragon/templates/dialog-roll-enctotal.html"}} -
+ +
-
+
+
+
diff --git a/templates/dialog-roll-ajustements.html b/templates/dialog-roll-ajustements.html new file mode 100644 index 00000000..ffb2ec8f --- /dev/null +++ b/templates/dialog-roll-ajustements.html @@ -0,0 +1,19 @@ +
+ +
\ No newline at end of file diff --git a/templates/dialog-roll-carac.html b/templates/dialog-roll-carac.html index c7955bfb..95fac6ab 100644 --- a/templates/dialog-roll-carac.html +++ b/templates/dialog-roll-carac.html @@ -20,15 +20,11 @@
{{>"systems/foundryvtt-reve-de-dragon/templates/dialog-roll-surenc.html"}} -
- - - - +
-
+
-
+
diff --git a/templates/dialog-roll-enctotal.html b/templates/dialog-roll-enctotal.html index 06055843..085c40fa 100644 --- a/templates/dialog-roll-enctotal.html +++ b/templates/dialog-roll-enctotal.html @@ -1,6 +1,7 @@ -{{#if isMalusEncombrementTotal}} +{{#if ajustements.encTotal.visible}}
- - + +
{{/if}} diff --git a/templates/dialog-roll-ethylisme.html b/templates/dialog-roll-ethylisme.html index baeb1379..2a74d639 100644 --- a/templates/dialog-roll-ethylisme.html +++ b/templates/dialog-roll-ethylisme.html @@ -21,9 +21,9 @@
-
+
-
+
diff --git a/templates/dialog-roll-meditation.html b/templates/dialog-roll-meditation.html index 8a169720..85d089a6 100644 --- a/templates/dialog-roll-meditation.html +++ b/templates/dialog-roll-meditation.html @@ -24,19 +24,19 @@
  • - +
  • - +
  • - +
  • - - + +
@@ -51,14 +51,11 @@
-
- - - +
-
+
-
+
diff --git a/templates/dialog-roll-resolution.html b/templates/dialog-roll-resolution.html index 203d2a54..34feacf4 100644 --- a/templates/dialog-roll-resolution.html +++ b/templates/dialog-roll-resolution.html @@ -28,9 +28,11 @@ {{/select}}
-
+
-
+
+
+
diff --git a/templates/dialog-roll-sort.html b/templates/dialog-roll-sort.html index 6a4061a7..f247e9a6 100644 --- a/templates/dialog-roll-sort.html +++ b/templates/dialog-roll-sort.html @@ -57,15 +57,11 @@
-
- - - - +
-
+
-
+