diff --git a/module/actor.js b/module/actor.js index 2fd87cb3..0e130098 100644 --- a/module/actor.js +++ b/module/actor.js @@ -360,31 +360,19 @@ export class RdDActor extends RdDBaseActor { dialog.render(true); } - async prepareChateauDormant(finChateauDormant, consignes) { - if (consignes.ignorer) { + async prepareChateauDormant(consigne) { + if (consigne.ignorer) { return; } - if (consignes.stress.valeur > 0) { - await this.distribuerStress('stress', consignes.stress.valeur, consignes.stress.motif); - } - if (!consignes.sommeil?.insomnie) { - await this.update({ - "system.sommeil": { - nouveaujour: true, - date: finChateauDormant, - moral: consignes.sommeil?.moral ?? 'neutre', - heures: consignes.sommeil?.heures ?? 4 - } - }) + if (consigne.stress.valeur > 0) { + await this.distribuerStress('stress', consigne.stress.valeur, consigne.stress.motif); } + await this.update({ 'system.sommeil': consigne.sommeil }) } async onTimeChanging(oldTimestamp, newTimestamp) { await super.onTimeChanging(oldTimestamp, newTimestamp); - const insomnie = EffetsDraconiques.isSujetInsomnie(this); - if (!this.system.sommeil || this.system.sommeil.insomnie || insomnie) { - await this.update({ 'system.sommeil.insomnie': insomnie }); - } + await this.setInfoSommeilInsomnie(); } async repos() { @@ -409,22 +397,15 @@ export class RdDActor extends RdDBaseActor { await this.transformerStress(); this.bonusRecuperationPotion = 0; // Reset potion } - await this.update({ - "system.sommeil": { - nouveaujour: false, - moral: "neutre", - heures: 0 - } - }) - + await this.resetInfoSommeil() ChatMessage.create(message); this.sheet.render(true); } async _recuperationSante(message) { const maladiesPoisons = this._maladiePoisons(message); - this._messageRecuperationMaladiePoisons(maladiesPoisons, message); const isMaladeEmpoisonne = maladiesPoisons.length > 0; + this._messageRecuperationMaladiePoisons(maladiesPoisons, message); const blessures = duplicate(this.system.blessures); await this._recupererBlessures(message, "legere", blessures.legeres.liste.filter(b => b.active), [], isMaladeEmpoisonne); await this._recupererBlessures(message, "grave", blessures.graves.liste.filter(b => b.active), blessures.legeres.liste, isMaladeEmpoisonne); @@ -438,10 +419,10 @@ export class RdDActor extends RdDBaseActor { return actifs; } - _messageRecuperationMaladiePoisons(actifs, message) { - if (actifs.length > 0) { - const identifies = actifs.filter(it => it.system.identifie); - const nonIdentifies = actifs.filter(it => !it.system.identifie); + _messageRecuperationMaladiePoisons(maladiesPoisons, message) { + if (maladiesPoisons.length > 0) { + const identifies = maladiesPoisons.filter(it => it.system.identifie); + const nonIdentifies = maladiesPoisons.filter(it => !it.system.identifie); message.content += 'Vous souffrez'; switch (nonIdentifies.length) { case 0: break; @@ -460,7 +441,7 @@ export class RdDActor extends RdDBaseActor { /* -------------------------------------------- */ async dormirChateauDormant() { - if (!ReglesOptionelles.isUsing("chateau-dormant-gardien") || !this.system.sommeil || this.system.sommeil?.nouveaujour) { + if (!ReglesOptionelles.isUsing("chateau-dormant-gardien") || !this.system.sommeil || this.system.sommeil.nouveaujour) { const message = { whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), content: "" @@ -469,9 +450,7 @@ export class RdDActor extends RdDBaseActor { await this._recuperationSante(message) await this._jetDeMoralChateauDormant(message); await this._recupereChance(); - if (!this.system.sommeil?.insomnie) { - await this.transformerStress(); - } + await this.transformerStress(); await this.retourSeuilDeReve(message); this.bonusRecuperationPotion = 0; // Reset potion await this.retourSust(message); @@ -480,17 +459,31 @@ export class RdDActor extends RdDBaseActor { message.content = `A la fin Chateau Dormant, ${message.content}
Un nouveau jour se lève`; ChatMessage.create(message); } - await this.update({ - "system.sommeil": { - nouveaujour: false, - moral: "neutre", - heures: 0 - } - }); + await this.resetInfoSommeil(); this.sheet.render(true); } } + async resetInfoSommeil() { + await this.update({ + 'system.sommeil': { + nouveaujour: false, + date: game.system.rdd.calendrier.getTimestamp(), + moral: "neutre", + heures: 0, + insomnie: EffetsDraconiques.isSujetInsomnie(this) + } + }); + } + + async setInfoSommeilInsomnie() { + await this.update({ 'system.sommeil.insomnie': EffetsDraconiques.isSujetInsomnie(this) }); + } + + async setInfoSommeilMoral(situationMoral) { + await this.update({ 'system.sommeil.moral': situationMoral }); + } + /* -------------------------------------------- */ async _recupereChance() { // On ne récupère un point de chance que si aucun appel à la chance dans la journée @@ -639,50 +632,32 @@ export class RdDActor extends RdDBaseActor { } /* -------------------------------------------- */ - async dormir(sommeilHeures, options = { grisReve: false, chateauDormant: false }) { - const sommeil = !this.system.sommeil?.insomnie || options.grisReve; + async dormir(heures, options = { grisReve: false, chateauDormant: false }) { const message = { whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), - content: "" + content: this.name + ': ' }; await this.recupereEndurance(message); - let sep = "" - let recuperationReve = ""; - let heuresDormies = 0; - for (; heuresDormies < sommeilHeures; heuresDormies++) { - await this._recupererEthylisme(message); - if (sommeil) { - await this.recupererFatigue(message); - if (!options.grisReve) { - if (sommeil) { - 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) { - heuresDormies++;// rêve de dragon pendant l'heure en cours - break; - } - } - } - } + if (this.system.sommeil?.insomnie || heures == 0) { + message.content += 'Vous ne trouvez pas le sommeil'; } + else { + let jetsReve = []; + let dormi = await this.dormirDesHeures(jetsReve, message, heures, options); + message.content += `Vous dormez ${dormi.heures <= 1 ? 'une heure' : (dormi.heures + ' heures')}. `; + if (jetsReve.length > 0) { + message.content += `Vous récupérez ${jetsReve.filter(it => it >= 0).reduce(Misc.joining("+"))} Points de rêve. `; + } + if (dormi.etat == 'eveil') { + message.content += 'Vous êtes réveillé par un Rêve de Dragon.' + } + options.chateauDormant = options.chateauDormant && dormi.heures == heures; + } + if (!options.grisReve) { - const repos = this.system.sommeil?.insomnie ? "vous reposez" : "dormez" - message.content = `${this.name}: Vous ${repos} ${heuresDormies <= 1 ? 'une heure' : (heuresDormies + ' heures')}. ` - + (recuperationReve == "" ? "" : `Vous récupérez ${recuperationReve} Points de rêve. `) - + message.content; ChatMessage.create(message); } - if (options.chateauDormant && heuresDormies == sommeilHeures) { + if (options.chateauDormant) { await this.dormirChateauDormant(); } else { @@ -690,6 +665,43 @@ export class RdDActor extends RdDBaseActor { } } + async dormirDesHeures(jetsReve, message, heures, options) { + const dormi = { heures: 1, etat: 'dort' }; + for (; dormi.heures <= heures && dormi.etat == 'dort'; dormi.heures++) { + await this._recupererEthylisme(message); + if (options.grisReve) { + await this.recupererFatigue(message); + } + else if (!this.system.sommeil?.insomnie) { + await this.recupererFatigue(message); + dormi.etat = await this.jetRecuperationReve(jetsReve, message); + if (dormi.etat == 'dort' && EffetsDraconiques.isDonDoubleReve(this)) { + dormi.etat = await this.jetRecuperationReve(jetsReve, message); + } + } + } + return dormi; + } + + /* -------------------------------------------- */ + async jetRecuperationReve(jetsReve, message) { + if (this.getReveActuel() < this.system.reve.seuil.value) { + let reve = await RdDDice.rollTotal("1dr"); + if (reve >= 7) { + // Rêve de Dragon ! + message.content += `Vous faites un Rêve de Dragon de ${reve} Points de rêve qui vous réveille! `; + await this.combattreReveDeDragon(reve); + jetsReve.push(-1); + return 'eveil'; + } + else { + await this.reveActuelIncDec(reve); + jetsReve.push(reve); + } + } + return 'dort'; + } + /* -------------------------------------------- */ async _recupererEthylisme(message) { let value = Math.min(Number.parseInt(this.system.compteurs.ethylisme.value) + 1, 1); @@ -750,27 +762,6 @@ export class RdDActor extends RdDBaseActor { return cumul; } - /* -------------------------------------------- */ - async recuperationReve(message) { - const seuil = this.system.reve.seuil.value; - const reveActuel = this.getReveActuel(); - 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 qui vous réveille! `; - await this.combattreReveDeDragon(deRecuperation); - return -1; - } - else { - await this.reveActuelIncDec(deRecuperation); - return deRecuperation; - } - } - return 0; - } - /* -------------------------------------------- */ async retourSeuilDeReve(message) { const seuil = this.system.reve.seuil.value; @@ -1922,7 +1913,7 @@ export class RdDActor extends RdDBaseActor { /* -------------------------------------------- */ async transformerStress() { const stress = Number(this.system.compteurs.stress.value); - if (stress <= 0) { + if (this.system.sommeil?.insomnie || stress <= 0) { return; } @@ -3841,7 +3832,7 @@ export class RdDActor extends RdDBaseActor { await draconique.onActorCreateOwned(this, item) this.notifyGestionTeteSouffleQueue(item, draconique.manualMessage()); } - await this.update({ 'system.sommeil.insomnie': EffetsDraconiques.isSujetInsomnie(this) }); + await this.setInfoSommeilInsomnie(); } } diff --git a/module/rdd-calendrier.js b/module/rdd-calendrier.js index 8730f7ee..68488757 100644 --- a/module/rdd-calendrier.js +++ b/module/rdd-calendrier.js @@ -170,6 +170,9 @@ export class RdDCalendrier extends Application { /* -------------------------------------------- */ getCurrentMinute() { return this.timestamp.indexMinute; } + getTimestamp() { + return this.timestamp; + } getTimestampFinChateauDormant(nbJours = 0) { return this.timestamp.nouveauJour().addJours(nbJours); } @@ -260,7 +263,7 @@ export class RdDCalendrier extends Application { /* -------------------------------------------- */ async setNewTimestamp(newTimestamp) { const oldTimestamp = this.timestamp; - game.actors.forEach(actor => actor.onTimeChanging(oldTimestamp, newTimestamp)); + await Promise.all(game.actors.map(async actor => await actor.onTimeChanging(oldTimestamp, newTimestamp))); RdDTimestamp.setWorldTime(newTimestamp); if (oldTimestamp.indexDate + 1 == newTimestamp.indexDate && ReglesOptionelles.isUsing("chateau-dormant-gardien")) { await DialogChateauDormant.create(); diff --git a/module/sommeil/dialog-chateau-dormant.js b/module/sommeil/dialog-chateau-dormant.js index bc1f8584..33ce5a28 100644 --- a/module/sommeil/dialog-chateau-dormant.js +++ b/module/sommeil/dialog-chateau-dormant.js @@ -1,16 +1,13 @@ +import { EffetsDraconiques } from "../tmr/effets-draconiques.js"; + export class DialogChateauDormant extends Dialog { static async create() { const date = game.system.rdd.calendrier.dateCourante(); - const actorsSettings = game.actors.filter(actor => actor.hasPlayerOwner && actor.isPersonnage()) - .map(actor => ({ - actor: actor, - insomnie: actor.system.sommeil?.insomnie, - moral: 'neutre' - })); + const actors = game.actors.filter(actor => actor.hasPlayerOwner && actor.isPersonnage()); const dialogData = { - actorsSettings, + actors: actors, date: date, motifStress: `Nuit du ${date}`, finChateauDormant: game.system.rdd.calendrier.getTimestampFinChateauDormant() @@ -65,44 +62,42 @@ export class DialogChateauDormant extends Dialog { const selected = this.html.find(event.currentTarget); const actorRow = selected.parents('.set-sommeil-actor'); const actorId = actorRow.data('actor-id'); - const actorSetting = this.getActorSetting(actorId); - if (actorSetting) { - actorSetting.moral = selected.data('moral'); - const htmlMoral = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/sommeil/sommeil-actor-moral.hbs', actorSetting) - actorRow.find('.sommeil-actor-moral').html(htmlMoral); - // re-attach listeners for actor row - this._activateListenerOnActorMoral(actorRow); - } + const actor = this.getActor(actorId); + actor.system.sommeil.moral = selected.data('moral'); + const htmlMoral = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/sommeil/sommeil-actor-moral.hbs', actor.system.sommeil) + actorRow.find('.sommeil-actor-moral').html(htmlMoral); + // re-attach listeners for actor row + this._activateListenerOnActorMoral(actorRow); } - getActorSetting(actorId) { - return this.dialogData.actorsSettings.find(it => it.actor.id == actorId); + getActor(actorId) { + return this.dialogData.actors.find(it => it.id == actorId); } async onChateauDormant() { const motifStress = this.html.find("form input[name='motifStress']").val(); - const sommeilActors = jQuery.map(this.html.find('li.set-sommeil-actor'), it => { + const consignesChateauDormant = jQuery.map(this.html.find('li.set-sommeil-actor'), it => { const actorRow = this.html.find(it); const actorId = actorRow.data('actor-id'); - const actorSetting = this.getActorSetting(actorId); + const actor = this.getActor(actorId); + const insomnie = actorRow.find('input.sommeil-insomnie').is(':checked'); return { - actorId, + actor, ignorer: actorRow.find('input.sommeil-ignorer').is(':checked'), stress: { motif: motifStress, valeur: Number.parseInt(actorRow.find('input.sommeil-stress').val()), }, sommeil: { - insomnie: actorRow.find('input.sommeil-insomnie').is(':checked'), - heures: Number.parseInt(actorRow.find('input.sommeil-heures').val()), - moral: actorSetting.moral, + nouveaujour: true, + date: this.dialogData.finChateauDormant, + insomnie: insomnie, + heures: insomnie ? 0 : Number.parseInt(actorRow.find('input.sommeil-heures').val()), + moral: actor.moral, } } }); - await Promise.all( - sommeilActors.filter(it => !it.ignorer) - .map(async it => await game.actors.get(it.actorId)?.prepareChateauDormant(this.dialogData.finChateauDormant, it)) - ) + consignesChateauDormant.forEach(async consigne => await consigne.actor.prepareChateauDormant(consigne)) } } \ No newline at end of file diff --git a/module/sommeil/dialog-repos.js b/module/sommeil/dialog-repos.js index 4e4c80b1..e0b0c050 100644 --- a/module/sommeil/dialog-repos.js +++ b/module/sommeil/dialog-repos.js @@ -1,4 +1,5 @@ import { ReglesOptionelles } from "../settings/regles-optionelles.js"; +import { EffetsDraconiques } from "../tmr/effets-draconiques.js"; export class DialogRepos extends Dialog { @@ -6,7 +7,7 @@ export class DialogRepos extends Dialog { if (!ReglesOptionelles.isUsing("chateau-dormant-gardien")) { actor.system.sommeil = { "nouveaujour": true, - "insomnie": false, + "insomnie": EffetsDraconiques.isSujetInsomnie(actor), "moral": "neutre", "heures": 4 } @@ -58,7 +59,8 @@ export class DialogRepos extends Dialog { async nuit() { await this.html.find("[name='sommeil.heures']").change(); - const sommeilHeures = Number.parseInt(await this.html.find("[name='sommeil.heures']").val()); + const val = await this.html.find("[name='sommeil.heures']").val(); + const sommeilHeures = Number.parseInt(val ?? '0'); await this.actor.dormir(sommeilHeures, { chateauDormant: true }); } @@ -72,7 +74,7 @@ export class DialogRepos extends Dialog { const selected = this.html.find(event.currentTarget); const parentDiv = selected.parents().find('.sommeil-actor-moral'); const situationMoral = selected.data('moral'); - await this.actor.update({"system.sommeil.moral": situationMoral}); + await this.actor.setInfoSommeilMoral(situationMoral); const htmlMoral = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/sommeil/sommeil-actor-moral.hbs', { moral: situationMoral }); diff --git a/templates/sommeil/dialog-chateau-dormant.hbs b/templates/sommeil/dialog-chateau-dormant.hbs index 98f708b2..509f93c9 100644 --- a/templates/sommeil/dialog-chateau-dormant.hbs +++ b/templates/sommeil/dialog-chateau-dormant.hbs @@ -14,29 +14,29 @@ Moral Ignorer - {{#each actorsSettings as |actorSetting|}} -
  • + {{#each actors as |actor|}} +
  • - + + value="{{#if actor.system.sommeil.insomnie}}0{{else}}4{{/if}}" + min="0" max="{{#if actor.system.sommeil.insomnie}}0{{else}}12{{/if}}" + {{#if actor.system.sommeil.insomnie}}disabled{{/if}}/> h - {{> "systems/foundryvtt-reve-de-dragon/templates/sommeil/sommeil-actor-moral.hbs" actorSetting}} + {{> "systems/foundryvtt-reve-de-dragon/templates/sommeil/sommeil-actor-moral.hbs" actor.system.sommeil}} diff --git a/templates/sommeil/dialog-repos.html b/templates/sommeil/dialog-repos.html index ffc71c2c..c3bcbbc4 100644 --- a/templates/sommeil/dialog-repos.html +++ b/templates/sommeil/dialog-repos.html @@ -4,41 +4,39 @@

    {{name}} se repose

    - {{#if system.sommeil.insomnie}} -
    - Insomnie, impossible de dormir -
    +
    + + +
    +

    + {{#if system.sommeil.nouveaujour}} +
    + + +
    +
    + + {{#if system.sommeil.insomnie}} + + {{else}} + + {{/if}} +
    +
    + +
    + {{> "systems/foundryvtt-reve-de-dragon/templates/sommeil/sommeil-actor-moral.hbs" system.sommeil}} +
    +
    {{else}}
    - - + Le gardien des rêves doit faire passer Chateau Dormant
    -

    - {{#if system.sommeil.nouveaujour}} -
    - - -
    -
    - - -
    -
    - -
    - {{> "systems/foundryvtt-reve-de-dragon/templates/sommeil/sommeil-actor-moral.hbs" system.sommeil}} -
    -
    - {{else}} -
    - Le gardien des rêves doit faire passer Chateau Dormant -
    - {{/if}} {{/if}}