From 6cc594bb76672af9f7fdfa3817cf8e654f084ab5 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sun, 6 Dec 2020 19:29:10 +0100 Subject: [PATCH] =?UTF-8?q?Appel=20=C3=A0=20la=20chance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit + ajout RdDRoll pour jet avec callbacks --- module/actor-sheet.js | 4 + module/actor.js | 53 +++++++- module/rdd-resolution-table.js | 5 + module/rdd-roll.js | 230 +++++++++++++++++++++++++++++++++ templates/actor-sheet.html | 1 + 5 files changed, 292 insertions(+), 1 deletion(-) create mode 100644 module/rdd-roll.js diff --git a/module/actor-sheet.js b/module/actor-sheet.js index 075cbbd6..e7684b78 100644 --- a/module/actor-sheet.js +++ b/module/actor-sheet.js @@ -258,6 +258,10 @@ export class RdDActorSheet extends ActorSheet { this.actor.rollCarac( 'chance-actuel' ); }); + html.find('#chance-appel').click((event) => { + this.actor.appelChance(); + }); + // Roll Skill html.find('.competence-label a').click((event) => { let compName = event.currentTarget.text; diff --git a/module/actor.js b/module/actor.js index 02f0c1c9..ef417a35 100644 --- a/module/actor.js +++ b/module/actor.js @@ -6,6 +6,7 @@ import { RdDUtility } from "./rdd-utility.js"; import { TMRUtility } from "./tmr-utility.js"; import { RdDRollDialog } from "./rdd-roll-dialog.js"; +import { RdDRoll } from "./rdd-roll.js"; import { RdDTMRDialog } from "./rdd-tmr-dialog.js"; import { Misc } from "./misc.js"; @@ -107,6 +108,10 @@ export class RdDActor extends Actor { return this.data.data.reve.reve.value; } + getChanceActuel() { + return this.data.data.compteurs.chance.value; + } + /* -------------------------------------------- */ getBestDraconic() { const list = this.getDraconicList().sort((a, b) => b.data.niveau - a.data.niveau); @@ -1004,7 +1009,7 @@ export class RdDActor extends Actor { } /* -------------------------------------------- */ - async reveActuelIncDec( value ) { + async reveActuelIncDec( value ) { let reve = duplicate(this.data.data.reve.reve); reve.value = Math.max(reve.value + value, 0); await this.update( {"data.reve.reve": reve } ); @@ -1294,6 +1299,52 @@ export class RdDActor extends Actor { new RdDRollDialog("carac", html, rollData, this ).render(true); } + async appelChance( ) + { + let rollData = { + selectedCarac: this.getCaracByName('chance-actuelle'), + diffConditions: this.ajustementAstrologique() + } + + const dialog = await RdDRoll.create( + 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html', + this, + rollData, + { + name: 'appelChance', + label: 'Appel à la chance', + callbacks: [ + { action: rollData => this._appelChanceResultat(rollData) } + ] + } + ); + dialog.render(true); + } + + _appelChanceResultat(rollData) { + const message = { + user: game.user._id, + alias: this.name, + content: this.name + " fait appel à la chance" + RdDResolutionTable.explain(rollData.rolled) + }; + if (rollData.rolled.isSuccess) { + message.content += "
Dépense d'un point de chance, l'action peut être retentée" + this.chanceActuelleIncDec(-1) + } + ChatMessage.create(message); + } + + async chanceActuelleIncDec(value) { + let chance = duplicate(this.data.data.compteurs.chance); + chance.value = Math.max(chance.value + value, 0); + await this.update( {"data.compteurs.chance": chance } ); + } + + ajustementAstrologique() { + //TODO: selon heure et heure de naissance... + return 0; + } + getCaracByName(caracName) { switch (caracName) { diff --git a/module/rdd-resolution-table.js b/module/rdd-resolution-table.js index 4add9f4c..13ec0e76 100644 --- a/module/rdd-resolution-table.js +++ b/module/rdd-resolution-table.js @@ -97,6 +97,11 @@ export class RdDResolutionTable { } } + static async rollData(rollData ) { + rollData.rolled = await this.roll(rollData.caracValue, rollData.finalLevel, rollData.bonus); + return rollData; + } + /* -------------------------------------------- */ static async roll(caracValue, finalLevel, bonus = 0 ) { let chances = this.computeChances(caracValue, finalLevel); diff --git a/module/rdd-roll.js b/module/rdd-roll.js new file mode 100644 index 00000000..0766b793 --- /dev/null +++ b/module/rdd-roll.js @@ -0,0 +1,230 @@ +import { HtmlUtility } from "./html-utility.js"; +import { RdDItemSort } from "./item-sort.js"; +import { Misc } from "./misc.js"; +import { RdDResolutionTable } from "./rdd-resolution-table.js"; + +/** + * Extend the base Dialog entity to select roll parameters + * @extends {Dialog} + */ + +export class RdDRoll extends Dialog { + + static async create(htmlTemplate, actor, rollData, ...actions) { + RdDRoll._ensureCorrectActions(actions); + + RdDRoll._setDefaultOptions(actor, rollData); + + const html = await renderTemplate(htmlTemplate, rollData); + + return new RdDRoll(actor, rollData, html, { + classes: ["rdddialog"], + width: 600, height: 500, 'z-index': 99999 + }, actions); + } + + static _setDefaultOptions(actor, rollData) { + + mergeObject(rollData, + { + ajustementsConditions: CONFIG.RDD.ajustementsConditions, + difficultesLibres: CONFIG.RDD.difficultesLibres, + etat: actor.data.data.compteurs.etat.value, + finalLevel: 0, + diffConditions: 0, + diffLibre: 0, + malusArmureValue: 0, + surencMalusFlag: actor.data.data.attributs ? actor.data.data.attributs.malusarmure.value : 0, + surencMalusValue: actor.data.data.compteurs.surenc.value, + surencMalusApply: false, + isNatation: false, + useEncForNatation: false + }, + { overwrite: false }); + } + + static _ensureCorrectActions(actions) { + if (actions.length==0) { + throw 'No action defined'; + } + actions.forEach(action => { + if (action.callbacks == undefined) { + action.callbacks = [{action: r => console.log(action.name, r)}]; + } + }); + } + + constructor(actor, rollData, html, options, actions) { + let conf = { + title: actions[0].label, + content: html, + buttons: {}, + default: actions[0].name + }; + for (let action of actions) { + conf.buttons[action.name] = { label: action.label, callback: html => this.onAction(action, html) }; + } + + super(conf, options); + + this.actor = actor; + this.rollData = rollData; + } + + async onAction(action, html) { + await RdDResolutionTable.rollData(this.rollData); + if (action.callbacks) + for (let callback of action.callbacks) { + if (callback.condition == undefined || callback.condition(this.rollData.rolled)) { + callback.action(this.rollData); + } + } + } + + /* -------------------------------------------- */ + activateListeners(html) { + super.activateListeners(html); + + this.bringToTop(); + + var rollData = this.rollData; + + function updateRollResult(rollData) { + let caracValue = parseInt(rollData.selectedCarac.value) + let rollLevel = RdDRoll._computeFinalLevel(rollData); + + rollData.finalLevel = rollLevel; + rollData.caracValue = caracValue + + HtmlUtility._showControlWhen(".etat-general", !RdDRoll._isIgnoreEtatGeneral(rollData)); + + // Sort management + if (rollData.selectedSort) { + //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(RdDRoll._getTitle(rollData)); + $(".table-resolution").remove(); + $("#resolutionTable").append(RdDResolutionTable.buildHTMLTableExtract(caracValue, rollLevel)); + } + + // Setup everything onload + $(function () { + // Update html, according to data + if (rollData.competence) { + // Set the default carac from the competence item + rollData.selectedCarac = rollData.carac[rollData.competence.data.defaut_carac]; + $("#carac").val(rollData.competence.data.defaut_carac); + } + RdDItemSort.setCoutReveReel(rollData.selectedSort); + $("#diffLibre").val(Misc.toInt(rollData.diffLibre)); + $("#diffConditions").val(Misc.toInt(rollData.diffConditions)); + updateRollResult(rollData); + }); + + // 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); + }); + 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); + }); + 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); + }); + html.find('#draconic').change((event) => { + let draconicKey = Misc.toInt(event.currentTarget.value); + this.rollData.selectedDraconic = rollData.draconicList[draconicKey]; // Update the selectedCarac + //console.log("RdDRollSelectDialog","CARAC CLICKED !!!", rollData); + updateRollResult(rollData); + }); + html.find('#sort').change((event) => { + let sortKey = Misc.toInt(event.currentTarget.value); + this.rollData.selectedSort = rollData.sortList[sortKey]; // Update the selectedCarac + RdDItemSort.setCoutReveReel(rollData.selectedSort); + //console.log("RdDRollSelectDialog - Sort selection", rollData.selectedSort); + updateRollResult(rollData); + }); + 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); + }); + 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); + }); + html.find('#coupsNonMortels').change((event) => { + this.rollData.mortalite = event.currentTarget.checked ? "non-mortel" : "non-mortel"; + }); + html.find('#surencMalusApply').change((event) => { + this.rollData.surencMalusApply = event.currentTarget.checked; + updateRollResult(rollData); + }); + html.find('#useEncForNatation').change((event) => { + this.rollData.useEncForNatation = event.currentTarget.checked; + updateRollResult(rollData); + }); + } + + static _isIgnoreEtatGeneral(rollData) { + return rollData.selectedCarac.ignoreEtatGeneral; + } + + /* -------------------------------------------- */ + static _computeFinalLevel(rollData) { + const etat = RdDRoll._isIgnoreEtatGeneral(rollData) ? 0 : Misc.toInt(rollData.etat); + const diffConditions = Misc.toInt(rollData.diffConditions); + let malusEnc = (rollData.surencMalusApply) ? rollData.surencMalusValue : 0; + let diffLibre = Misc.toInt(rollData.diffLibre); + let malusEncNatation = (rollData.useEncForNatation) ? -rollData.encValueForNatation : 0; + + // Gestion malus armure + let malusArmureValue = 0; + if (rollData.malusArmureValue != 0 && (rollData.selectedCarac.label == "Agilité" || rollData.selectedCarac.label == "Dérobée")) { + $("#addon-message").text("Malus armure appliqué : " + rollData.malusArmureValue); + malusArmureValue = rollData.malusArmureValue; + } else { + $("#addon-message").text(""); + } + + let diffCompetence = 0; + if (rollData.competence) { + diffCompetence = Misc.toInt(rollData.competence.data.niveau); + } + else if (rollData.draconicList) { + diffCompetence = Misc.toInt(rollData.selectedDraconic.data.niveau); + diffLibre = RdDItemSort.getDifficulte(rollData.selectedSort, diffLibre); + } + + return etat + diffCompetence + diffLibre + diffConditions + malusEnc + malusEncNatation + malusArmureValue; + } + + /* -------------------------------------------- */ + static _getTitle(rollData) { + if (rollData.competence) { + // If a weapon is there, add it in the title + let armeTitle = (rollData.arme) ? " (" + rollData.arme.name + ") " : ""; + let niveau = Misc.toSignedString(rollData.competence.data.niveau); + return rollData.selectedCarac.label + "/" + rollData.competence.name + armeTitle + " " + niveau + } + if (rollData.draconicList) { + return rollData.selectedDraconic.name + " - " + rollData.selectedSort.name; + } + return rollData.selectedCarac.label; + } +} diff --git a/templates/actor-sheet.html b/templates/actor-sheet.html index c4d02e46..e4809b89 100644 --- a/templates/actor-sheet.html +++ b/templates/actor-sheet.html @@ -150,6 +150,7 @@ {{/if}} {{/each}} +