diff --git a/module/actor-sheet.js b/module/actor-sheet.js index ed649231..d35afefe 100644 --- a/module/actor-sheet.js +++ b/module/actor-sheet.js @@ -14,6 +14,7 @@ import { RdDCarac } from "./rdd-carac.js"; import { RdDItem } from "./item.js"; import { DialogSplitItem } from "./dialog-split-item.js"; import { ReglesOptionelles } from "./regles-optionelles.js"; +import { DialogRepos } from "./dialog-repos.js"; /* -------------------------------------------- */ export class RdDActorSheet extends ActorSheet { @@ -372,11 +373,8 @@ export class RdDActorSheet extends ActorSheet { this.actor.displayTMR("rapide"); }); - html.find('.dormir-une-heure').click(async event => { - this.actor.dormir(1); - }); - html.find('.dormir-chateau-dormant').click(async event => { - this.actor.dormirChateauDormant(); + html.find('.repos').click(async event => { + await DialogRepos.create(this.actor); }); html.find('.enlever-tous-effets').click(async event => { this.actor.enleverTousLesEffets(); diff --git a/module/actor.js b/module/actor.js index 6609d976..05a27000 100644 --- a/module/actor.js +++ b/module/actor.js @@ -33,7 +33,6 @@ import { RollDataAjustements } from "./rolldata-ajustements.js"; import { DialogItemAchat } from "./dialog-item-achat.js"; import { RdDItem } from "./item.js"; - /* -------------------------------------------- */ /** * Extend the base Actor entity by defining a custom roll data structure which is ideal for the Simple system. @@ -55,7 +54,7 @@ export class RdDActor extends Actor { switch (sockmsg.msg) { case "msg_remote_actor_call": return RdDActor.onRemoteActorCall(sockmsg.data); - case "msg_reset_nombre_astral": + case "msg_reset_nombre_astral": console.log("RESET ASTRAL", game.user.character); game.user.character.resetNombreAstral(); return; @@ -371,18 +370,23 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ getBestDraconic() { const list = this.getDraconicList(); + return duplicate(list[0]); + } + getDraconicOrZero() { + const list = this.getDraconicList().filter(it => Misc.data(it).data.niveau >= 0); if (list.length == 0) { - return { name: "Aucun", data: { name: "Aucun", data: { niveau: 0 } } }; + return { name: "Aucun", data: { niveau: 0 } }; } return duplicate(list[0]); } + getDemiReve() { return Misc.templateData(this).reve.tmrpos.coord; } /* -------------------------------------------- */ async verifierPotionsEnchantees() { - let potionsEnchantees = this.filterItemsData(it => it.type == 'potion' && it.data.categorie.toLowerCase().includes('enchant') ); + let potionsEnchantees = this.filterItemsData(it => it.type == 'potion' && it.data.categorie.toLowerCase().includes('enchant')); for (let potion of potionsEnchantees) { if (!potion.prpermanent) { console.log(potion); @@ -432,6 +436,34 @@ export class RdDActor extends Actor { return ''; } + + /* -------------------------------------------- */ + async grisReve(nGrisReve) { + let message = { + whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), + content: `${nGrisReve} jours de gris rêve sont passés. ` + }; + for (let i = 0; i < nGrisReve; i++) { + await this.dormir(6, { grisReve: true }); + const blessures = duplicate(Misc.templateData(this).blessures); + await this._recupererBlessures(message, "legere", blessures.legeres.liste.filter(b => b.active), []); + await this._recupererBlessures(message, "grave", blessures.graves.liste.filter(b => b.active), blessures.legeres.liste); + await this._recupererBlessures(message, "critique", blessures.critiques.liste.filter(b => b.active), blessures.graves.liste); + await this.update({ "data.blessures": blessures }); + await this._recupererVie(message); + + const moralActuel = Misc.toInt(Misc.templateData(this).compteurs.moral.value); + if (moralActuel != 0) { + await this.moralIncDec(-Math.sign(moralActuel)); + } + await this._recupereChance(); + await this.transformerStress(); + this.bonusRecuperationPotion = 0; // Reset potion + } + ChatMessage.create(message); + this.sheet.render(true); + } + /* -------------------------------------------- */ async dormirChateauDormant() { let message = { @@ -452,8 +484,10 @@ export class RdDActor extends Actor { this.bonusRecuperationPotion = 0; // Reset potion await this.retourSust(message); await this.verifierPotionsEnchantees(); - message.content = `A la fin Chateau Dormant, ${message.content}
Un nouveau jour se lève`; - ChatMessage.create(message); + if (message.content != "") { + message.content = `A la fin Chateau Dormant, ${message.content}
Un nouveau jour se lève`; + ChatMessage.create(message); + } this.sheet.render(true); } @@ -588,22 +622,45 @@ export class RdDActor extends Actor { } /* -------------------------------------------- */ - async dormir(heures) { + async dormir(heures, options = { grisReve: false }) { let message = { whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), - content: `${this.name}: Vous dormez ${heures == 1 ? 'une' : heures} heure${heures == 1 ? '' : 's'}.` + content: "" }; await this.recupereEndurance(message); - for (let i = 0; i < heures; i++) { + let sep = "" + let recuperationReve = ""; + let i = 0; + for (; i < heures; i++) { await this._recupererEthylisme(message); await this.recupererFatigue(message); - await this.recuperationReve(message, 1); - if (EffetsDraconiques.isDonDoubleReve(this)) { - await this.recuperationReve(message, 2); + if (!options.grisReve) { + let r = await this.recuperationReve(message); + if (r >= 0) { + recuperationReve += sep + r; + sep = "+"; + } + + if (r >= 0 && EffetsDraconiques.isDonDoubleReve(this)) { + r = await this.recuperationReve(message); + if (r >= 0) { + recuperationReve += sep + r; + } + } + if (r < 0) { + i++;// rêve de dragon pendant l'heure en cours + break; + } } } - ChatMessage.create(message); + if (!options.grisReve) { + message.content = `${this.name}: Vous dormez ${i == 0 ? 'une' : i} heure${i == 1 ? '' : 's'}. ` + + (recuperationReve == "" ? "" : `Vous récupérez ${recuperationReve} Points de rêve. `) + + message.content; + ChatMessage.create(message); + } this.sheet.render(true); + return i; } /* -------------------------------------------- */ @@ -635,7 +692,6 @@ export class RdDActor extends Actor { let fatigue = Misc.templateData(this).sante.fatigue.value; const fatigueMin = this._computeFatigueMin(); if (fatigue <= fatigueMin) { - message.content += "Vous êtes déjà reposé. "; return; } fatigue = Math.max(fatigueMin, this._calculRecuperationSegment(fatigue)); @@ -667,27 +723,24 @@ export class RdDActor extends Actor { } /* -------------------------------------------- */ - async recuperationReve(message, demiHeure) { + async recuperationReve(message) { const seuil = Misc.templateData(this).reve.seuil.value; const reveActuel = this.getReveActuel(); - if (reveActuel >= seuil) { - if (demiHeure == 1) { - message.content += `Vous avez suffisament rêvé, au delà de votre seuil. `; - } - } - else { + if (reveActuel < seuil) { let deRecuperation = await RdDDice.rollTotal("1dr"); console.log("recuperationReve", deRecuperation); if (deRecuperation >= 7) { // Rêve de Dragon ! - message.content += `Vous faites un Rêve de Dragon de ${deRecuperation} Points de rêve! `; + message.content += `Vous faites un Rêve de Dragon de ${deRecuperation} Points de rêve qui vous réveille! `; await this.combattreReveDeDragon(deRecuperation); + return -1; } else { - message.content += `Vous récupérez ${deRecuperation} Points de rêve. `; await this.reveActuelIncDec(deRecuperation); + return deRecuperation; } } + return 0; } /* -------------------------------------------- */ @@ -724,7 +777,7 @@ export class RdDActor extends Actor { async combattreReveDeDragon(force) { let rollData = { actor: this, - competence: duplicate(this.getBestDraconic()), + competence: duplicate(this.getDraconicOrZero()), canClose: false, rencontre: duplicate(TMRRencontres.getRencontre('rdd')), tmr: true, @@ -744,7 +797,7 @@ export class RdDActor extends Actor { label: 'Maîtriser le Rêve de Dragon', callbacks: [ this.createCallbackExperience(), - { action: r => this.resultCombatReveDeDragon(r) } + { action: async r => this.resultCombatReveDeDragon(r) } ] } ); @@ -898,7 +951,7 @@ export class RdDActor extends Actor { async updateCompetenceXP(compName, newXp) { let comp = this.getCompetence(compName); if (comp) { - if ( isNaN(newXp) || typeof(newXp) != 'number') newXp = 0; + if (isNaN(newXp) || typeof (newXp) != 'number') newXp = 0; this.checkCompetenceXP(compName, newXp); const update = { _id: comp.id, 'data.xp': newXp }; await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity @@ -913,7 +966,7 @@ export class RdDActor extends Actor { async updateCompetenceXPSort(compName, compValue) { let comp = this.getCompetence(compName); if (comp) { - if ( isNaN(compValue) || typeof(compValue) != 'number') compValue = 0; + if (isNaN(compValue) || typeof (compValue) != 'number') compValue = 0; const update = { _id: comp.id, 'data.xp_sort': compValue }; await this.updateEmbeddedDocuments('Item', [update]); // Updates one EmbeddedEntity this.updateExperienceLog("XP Sort", compValue, "XP modifié en sort de " + compName); @@ -1454,7 +1507,7 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ getSonne() { - let data = Misc.templateData(this); + let data = Misc.templateData(this); return !this.isEntiteCauchemar() && (data.sante?.sonne?.value ?? false); } @@ -1694,14 +1747,14 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async jetDeMoral(situation, messageReussi = undefined, messageManque = undefined) { let jetMoral = await this._jetMoral(situation) - - let defaultMessage = `Vous ${jetMoral.ajustement > 0 ? "gagnez du moral" : jetMoral.ajustement < 0 ? "perdez du moral" : "gardez votre moral"}.`; - let finMessage = jetMoral.succes ? (messageReussi != undefined ? messageReussi : defaultMessage) : (messageManque != undefined ? messageManque : defaultMessage); - let message = `Jet de moral ${jetMoral.succes ? "réussi" : "manqué"} en situation ${situation} (${jetMoral.jet}/${jetMoral.difficulte}).
${finMessage}`; - ChatMessage.create({ - whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), - content: message - }); + if (jetMoral.ajustement != 0) { + let defaultMessage = jetMoral.ajustement > 0 ? "Vous gagnez du moral" : "Vous perdez du moral"; + let finMessage = jetMoral.succes ? (messageReussi != undefined ? messageReussi : defaultMessage) : (messageManque != undefined ? messageManque : defaultMessage); + ChatMessage.create({ + whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), + content: `${finMessage} - jet ${jetMoral.succes ? "réussi" : "manqué"} en situation ${situation} (${jetMoral.jet}/${jetMoral.difficulte}).` + }); + } return jetMoral.ajustement; } @@ -2166,7 +2219,7 @@ export class RdDActor extends Actor { it = duplicate(Misc.data(it)) it.data.defaut_carac = "reve"; return it; - }); + }); for (let sort of sortList) { let draconicsSort = this.getDraconicsSort(draconicList, sort).map(it => it.name); for (let index = 0; index < draconicList.length && sort.data.listIndex == undefined; index++) { @@ -2923,7 +2976,7 @@ export class RdDActor extends Actor { const deletions = toDelete.map(it => it._id); await this.deleteEmbeddedDocuments("Item", deletions); } - + /* -------------------------------------------- */ async ajouteNombreAstral(data) { // Gestion expérience (si existante) @@ -3497,7 +3550,7 @@ export class RdDActor extends Actor { async ajouterDeniers(gain, fromActorId = undefined) { gain = Number.parseInt(gain); - if (gain == 0){ + if (gain == 0) { return; } if (fromActorId && !game.user.isGM) { @@ -4038,7 +4091,7 @@ export class RdDActor extends Actor { effet.flags.core.statusId = effet.id; let effectArray = await this.createEmbeddedDocuments('ActiveEffect', [effet]); //if (effectArray[0]) { - //await effectArray[0].setFlag('core', 'statusId', effet.id); + //await effectArray[0].setFlag('core', 'statusId', effet.id); //} } diff --git a/module/dialog-repos.js b/module/dialog-repos.js new file mode 100644 index 00000000..e63ee31c --- /dev/null +++ b/module/dialog-repos.js @@ -0,0 +1,56 @@ +import { Misc } from "./misc.js"; + +export class DialogRepos extends Dialog { + + static async create(actor) { + let actorData = Misc.data(actor) + const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-repos.html", actorData); + new DialogRepos(html, actor).render(true); + } + + constructor(html, actor) { + let options = { classes: ["DialogCreateSigneDraconiqueActorsActors"], width: 500, height: 400, 'z-index': 99999 }; + let conf = { + title: "Se reposer", + content: html, + default: "repos", + buttons: { + "repos": { label: "Se reposer", callback: async it => { this.repos(); } } + } + }; + super(conf, options); + this.actor = actor; + } + + async repos() { + await $("[name='nb-heures']").change(); + await $("[name='nb-jours']").change(); + const selection = await $("[name='repos']:checked").val(); + const nbHeures = Number.parseInt(await $("[name='nb-heures']").val()); + const nbJours = Number.parseInt(await $("[name='nb-jours']").val()); + switch (selection) { + case "sieste": { + await this.actor.dormir(nbHeures); + return; + } + case "nuit": { + let heuresDormies = await this.actor.dormir(nbHeures); + if (heuresDormies == nbHeures){ + await this.actor.dormirChateauDormant(); + } + return; + } + case "chateau-dormant": + await this.actor.dormirChateauDormant(); + return; + case "gris-reve": { + await this.actor.grisReve(nbJours); + return; + } + } + } + /* -------------------------------------------- */ + activateListeners(html) { + super.activateListeners(html); + } +} \ No newline at end of file diff --git a/module/rdd-astrologie-editeur.js b/module/rdd-astrologie-editeur.js index 65ea242d..75913483 100644 --- a/module/rdd-astrologie-editeur.js +++ b/module/rdd-astrologie-editeur.js @@ -25,7 +25,7 @@ /* -------------------------------------------- */ async resetNombreAstraux() { game.system.rdd.calendrier.resetNombreAstral(); - await game.system.rdd.calendrier.rebuildListeNombreAstral( 'reset' ); + await game.system.rdd.calendrier.rebuildListeNombreAstral(); game.system.rdd.calendrier.showAstrologieEditor(); } diff --git a/module/rdd-calendrier.js b/module/rdd-calendrier.js index 72aed10b..e4479202 100644 --- a/module/rdd-calendrier.js +++ b/module/rdd-calendrier.js @@ -88,7 +88,7 @@ export class RdDCalendrier extends Application { // nombre astral if (game.user.isGM) { this.listeNombreAstral = this._loadListNombreAstral(); - await this.rebuildListeNombreAstral(); // Ensure always up-to-date + await this.rebuildListeNombreAstral(false); // Ensure always up-to-date } console.log(this.calendrier, this.calendrierPos, this.listeNombreAstral); } @@ -148,13 +148,15 @@ export class RdDCalendrier extends Application { } /* -------------------------------------------- */ - async ajouterNombreAstral(index, showdice = true) { - const nombreAstral = await RdDDice.rollTotal("1dh", { showDice: showdice, rollMode: "selfroll" }); + async ajouterNombreAstral(index, showDice = true) { + const nombreAstral = await RdDDice.rollTotal("1dh", { showDice: showDice, hideDice: !showDice, rollMode: "selfroll" }); const dateFuture = this.getDateFromIndex(index); - ChatMessage.create({ - whisper: ChatMessage.getWhisperRecipients("GM"), - content: `Le chiffre astrologique du ${dateFuture} sera le ${nombreAstral}` - }); + if (showDice) { + ChatMessage.create({ + whisper: ChatMessage.getWhisperRecipients("GM"), + content: `Le chiffre astrologique du ${dateFuture} sera le ${nombreAstral}` + }); + } return { nombreAstral: nombreAstral, valeursFausses: [], @@ -197,7 +199,7 @@ export class RdDCalendrier extends Application { } /* -------------------------------------------- */ - async rebuildListeNombreAstral( raison = 'incjour') { + async rebuildListeNombreAstral(showDice = true) { if (game.user.isGM) { let jourCourant = this.getCurrentDayIndex(); @@ -208,7 +210,7 @@ export class RdDCalendrier extends Application { if (na) { newList[i] = duplicate(na); } else { - newList[i] = await this.ajouterNombreAstral(dayIndex, raison == 'incjour' ); + newList[i] = await this.ajouterNombreAstral(dayIndex, showDice ); } } console.log("SAVE list", newList, jourCourant); @@ -438,7 +440,7 @@ export class RdDCalendrier extends Application { this.calendrier.heureRdD = RdDCalendrier.getDefSigne(calendrierData.heureKey); // Index dans heuresList game.settings.set("foundryvtt-reve-de-dragon", "calendrier", duplicate(this.calendrier)); - await this.rebuildListeNombreAstral( 'reset' ); + await this.rebuildListeNombreAstral(); game.socket.emit("system.foundryvtt-reve-de-dragon", { msg: "msg_sync_time", diff --git a/module/rdd-dice.js b/module/rdd-dice.js index ec3afc10..cc4121c4 100644 --- a/module/rdd-dice.js +++ b/module/rdd-dice.js @@ -134,12 +134,14 @@ export class RdDDice { static async roll(formula, options = { showDice: false, rollMode: undefined }) { const roll = new Roll(formula); await roll.evaluate({ async: true }); - roll.showDice = options.showDice; - await RdDDice.show(roll, options.rollMode ?? game.settings.get("core", "rollMode")); + if (!options.hideDice) { + roll.showDice = options.showDice; + await RdDDice.show(roll, options.rollMode ?? game.settings.get("core", "rollMode")); + } return roll; } - static async rollTotal(formula, options = { showDice: false }) { + static async rollTotal(formula, options = { showDice: false, hideDice: false }) { const roll = await RdDDice.roll(formula, options); return roll.total; } diff --git a/templates/actor-sheet.html b/templates/actor-sheet.html index 4358a4a1..e6da1fc8 100644 --- a/templates/actor-sheet.html +++ b/templates/actor-sheet.html @@ -57,8 +57,7 @@
Encaisser des dommages Remise à neuf - Dormir une heure - Chateau Dormant + Se reposer {{#if data.attributs.hautrevant.value}} Montée dans les Terres Médianes ! Montée accélérée dans les Terres Médianes ! diff --git a/templates/dialog-repos.html b/templates/dialog-repos.html new file mode 100644 index 00000000..48aabdd2 --- /dev/null +++ b/templates/dialog-repos.html @@ -0,0 +1,38 @@ +
+
+
+
+ {{name}} +

{{name}} se repose

+
+
+ + +
+
+
+ + +
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+
\ No newline at end of file