diff --git a/module/actor.js b/module/actor.js index 262f2d15..2fd87cb3 100644 --- a/module/actor.js +++ b/module/actor.js @@ -32,7 +32,7 @@ import { RdDConfirm } from "./rdd-confirm.js"; import { DialogValidationEncaissement } from "./dialog-validation-encaissement.js"; import { RdDRencontre } from "./item/rencontre.js"; import { Targets } from "./targets.js"; -import { DialogRepos } from "./dialog-repos.js"; +import { DialogRepos } from "./sommeil/dialog-repos.js"; import { RdDBaseActor } from "./actor/base-actor.js"; import { RdDTimestamp } from "./rdd-timestamp.js"; import { RdDItemTache } from "./item-tache.js"; @@ -208,6 +208,7 @@ export class RdDActor extends RdDBaseActor { } return etatGeneral } + /* -------------------------------------------- */ getActivePoisons() { return duplicate(this.items.filter(item => item.type == 'poison' && item.system.active)) @@ -359,6 +360,33 @@ export class RdDActor extends RdDBaseActor { dialog.render(true); } + async prepareChateauDormant(finChateauDormant, consignes) { + if (consignes.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 + } + }) + } + } + + 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 }); + } + } + async repos() { await DialogRepos.create(this); } @@ -370,7 +398,7 @@ export class RdDActor extends RdDBaseActor { content: `${nGrisReve} jours de gris rêve sont passés. ` }; for (let i = 0; i < nGrisReve; i++) { - await this.dormir(6, { grisReve: true }); + await this.dormir(4, { grisReve: true }); await this._recuperationSante(message); const moralActuel = Misc.toInt(this.system.compteurs.moral.value); @@ -381,6 +409,14 @@ export class RdDActor extends RdDBaseActor { await this.transformerStress(); this.bonusRecuperationPotion = 0; // Reset potion } + await this.update({ + "system.sommeil": { + nouveaujour: false, + moral: "neutre", + heures: 0 + } + }) + ChatMessage.create(message); this.sheet.render(true); } @@ -424,25 +460,35 @@ export class RdDActor extends RdDBaseActor { /* -------------------------------------------- */ async dormirChateauDormant() { - let message = { - whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), - content: "" - }; + if (!ReglesOptionelles.isUsing("chateau-dormant-gardien") || !this.system.sommeil || this.system.sommeil?.nouveaujour) { + const message = { + whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), + content: "" + }; - const blessures = duplicate(this.system.blessures) - await this._recuperationSante(message) - await this._jetDeMoralChateauDormant(message); - await this._recupereChance(); - await this.transformerStress(); - await this.retourSeuilDeReve(message); - this.bonusRecuperationPotion = 0; // Reset potion - await this.retourSust(message); - await this.verifierPotionsEnchantees(); - if (message.content != "") { - message.content = `A la fin Chateau Dormant, ${message.content}
Un nouveau jour se lève`; - ChatMessage.create(message); + await this._recuperationSante(message) + await this._jetDeMoralChateauDormant(message); + await this._recupereChance(); + if (!this.system.sommeil?.insomnie) { + await this.transformerStress(); + } + await this.retourSeuilDeReve(message); + this.bonusRecuperationPotion = 0; // Reset potion + await this.retourSust(message); + await this.verifierPotionsEnchantees(); + if (message.content != "") { + 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 + } + }); + this.sheet.render(true); } - this.sheet.render(true); } /* -------------------------------------------- */ @@ -456,9 +502,11 @@ export class RdDActor extends RdDBaseActor { } async _jetDeMoralChateauDormant(message) { - const jetMoral = await this._jetDeMoral('neutre'); - message.content += ' -- le moral ' + this._messageAjustementMoral(jetMoral.ajustement); + const etatMoral = this.system.sommeil?.moral ?? 'neutre'; + const jetMoral = await this._jetDeMoral(etatMoral); + message.content += ` -- le jet de moral est ${etatMoral}, le moral ` + this._messageAjustementMoral(jetMoral.ajustement); } + _messageAjustementMoral(ajustement) { switch (Math.sign(ajustement)) { case 1: @@ -591,59 +639,70 @@ export class RdDActor extends RdDBaseActor { } /* -------------------------------------------- */ - async dormir(heures, options = { grisReve: false }) { - let message = { + async dormir(sommeilHeures, options = { grisReve: false, chateauDormant: false }) { + const sommeil = !this.system.sommeil?.insomnie || options.grisReve; + const message = { whisper: ChatUtility.getWhisperRecipientsAndGMs(this.name), content: "" }; await this.recupereEndurance(message); let sep = "" let recuperationReve = ""; - let i = 0; - for (; i < heures; i++) { + let heuresDormies = 0; + for (; heuresDormies < sommeilHeures; heuresDormies++) { await this._recupererEthylisme(message); - await this.recupererFatigue(message); - if (!options.grisReve) { - let r = await this.recuperationReve(message); - if (r >= 0) { - recuperationReve += sep + r; - sep = "+"; - } + 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 && 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 (r < 0) { - i++;// rêve de dragon pendant l'heure en cours - break; - } } } if (!options.grisReve) { - message.content = `${this.name}: Vous dormez ${i == 0 ? 'une' : i} heure${i == 1 ? '' : 's'}. ` + 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); } - this.sheet.render(true); - return i; + if (options.chateauDormant && heuresDormies == sommeilHeures) { + await this.dormirChateauDormant(); + } + else { + this.sheet.render(true); + } } /* -------------------------------------------- */ async _recupererEthylisme(message) { - let ethylisme = duplicate(this.system.compteurs.ethylisme); - ethylisme.nb_doses = 0; - ethylisme.jet_moral = false; - if (ethylisme.value < 1) { - ethylisme.value = Math.min(ethylisme.value + 1, 1); - if (ethylisme.value <= 0) { - message.content += `Vous dégrisez un peu (${RdDUtility.getNomEthylisme(ethylisme.value)}). `; - } + let value = Math.min(Number.parseInt(this.system.compteurs.ethylisme.value) + 1, 1); + if (value <= 0) { + message.content += `Vous dégrisez un peu (${RdDUtility.getNomEthylisme(value)}). `; } - await this.update({ "system.compteurs.ethylisme": ethylisme }); + await this.update({ + "system.compteurs.ethylisme": { + nb_doses: 0, + jet_moral: false, + value: value + } + }); } /* -------------------------------------------- */ @@ -651,7 +710,7 @@ export class RdDActor extends RdDBaseActor { const manquant = this._computeEnduranceMax() - this.system.sante.endurance.value; if (manquant > 0) { await this.santeIncDec("endurance", manquant); - message.content += "Vous récuperez " + manquant + " points d'endurance. "; + message.content += `Vous récuperez ${manquant} points d'endurance. `; } } @@ -1012,12 +1071,12 @@ export class RdDActor extends RdDBaseActor { } /* -------------------------------------------- */ - distribuerStress(compteur, stress, motif) { + async distribuerStress(compteur, stress, motif) { if (game.user.isGM && this.hasPlayerOwner && this.isPersonnage()) { switch (compteur) { case 'stress': case 'experience': + await this.addCompteurValue(compteur, stress, motif); const message = `${this.name} a reçu ${stress} points ${compteur == 'stress' ? "de stress" : "d'expérience"} (raison : ${motif})`; - this.addCompteurValue(compteur, stress, motif); ui.notifications.info(message); game.users.players.filter(player => player.active && player.character?.id == this.id) .forEach(player => ChatUtility.notifyUser(player.id, 'info', message)); @@ -3779,9 +3838,10 @@ export class RdDActor extends RdDBaseActor { if (Misc.isUniqueConnectedGM()) { let draconique = Draconique.all().find(it => it.match(item)); if (draconique) { - draconique.onActorCreateOwned(this, item) + await draconique.onActorCreateOwned(this, item) this.notifyGestionTeteSouffleQueue(item, draconique.manualMessage()); } + await this.update({ 'system.sommeil.insomnie': EffetsDraconiques.isSujetInsomnie(this) }); } } @@ -3790,7 +3850,7 @@ export class RdDActor extends RdDBaseActor { if (Misc.isUniqueConnectedGM()) { let draconique = Draconique.all().find(it => it.match(item)); if (draconique) { - draconique.onActorDeleteOwned(this, item) + await draconique.onActorDeleteOwned(this, item) } } } @@ -3800,7 +3860,7 @@ export class RdDActor extends RdDBaseActor { if (Misc.isUniqueConnectedGM()) { let draconique = Draconique.all().find(it => it.isCase(item)); if (draconique) { - draconique.onActorDeleteCaseTmr(this, item) + await draconique.onActorDeleteCaseTmr(this, item) } } } diff --git a/module/dialog-repos.js b/module/dialog-repos.js deleted file mode 100644 index ec43ecc6..00000000 --- a/module/dialog-repos.js +++ /dev/null @@ -1,57 +0,0 @@ - -export class DialogRepos extends Dialog { - - static async create(actor) { - const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-repos.html", actor); - const dialog = new DialogRepos(html, actor); - dialog.render(true); - } - - constructor(html, actor) { - let options = { classes: ["DialogCreateSigneDraconiqueActorsActors"], width: 400, height: 'fit-content', '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; - } - activateListeners(html) { - super.activateListeners(html); - this.html = html; - } - /* -------------------------------------------- */ - - async repos() { - await this.html.find("[name='nb-heures']").change(); - await this.html.find("[name='nb-jours']").change(); - const selection = await this.html.find("[name='repos']:checked").val(); - const nbHeures = Number.parseInt(await this.html.find("[name='nb-heures']").val()); - const nbJours = Number.parseInt(await this.html.find("[name='nb-jours']").val()); - console.log("ACTOR", this.actor) - 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; - } - } - } -} \ No newline at end of file diff --git a/module/rdd-calendrier.js b/module/rdd-calendrier.js index 0b1f65af..a54f9e9a 100644 --- a/module/rdd-calendrier.js +++ b/module/rdd-calendrier.js @@ -7,6 +7,8 @@ import { Misc } from "./misc.js"; import { HIDE_DICE, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; import { DialogChronologie } from "./dialog-chronologie.js"; import { RdDTimestamp, WORLD_TIMESTAMP_SETTING } from "./rdd-timestamp.js"; +import { DialogChateauDormant } from "./sommeil/dialog-chateau-dormant.js"; +import { ReglesOptionelles } from "./settings/regles-optionelles.js"; const RDD_JOUR_PAR_MOIS = 28; const RDD_HEURES_PAR_JOUR = 12; @@ -169,7 +171,7 @@ export class RdDCalendrier extends Application { getCurrentMinute() { return this.timestamp.indexMinute; } getTimestampFinChateauDormant(nbJours = 0) { - return this.timestamp.nouveauJour().addJour(nbJours); + return this.timestamp.nouveauJour().addJours(nbJours); } getTimestampFinHeure(nbHeures = 0) { @@ -257,8 +259,12 @@ export class RdDCalendrier extends Application { /* -------------------------------------------- */ async setNewTimestamp(newTimestamp) { - game.actors.forEach(actor => actor.onTimeChanging(this.timestamp, newTimestamp)); + const oldTimestamp = this.timestamp; + game.actors.forEach(actor => actor.onTimeChanging(oldTimestamp, newTimestamp)); RdDTimestamp.setWorldTime(newTimestamp); + if (oldTimestamp.indexDate + 1 == newTimestamp.indexDate && ReglesOptionelles.isUsing("chateau-dormant-gardien")) { + await DialogChateauDormant.create(); + } this.timestamp = newTimestamp; await this.rebuildListeNombreAstral(); this.updateDisplay(); @@ -292,10 +298,8 @@ export class RdDCalendrier extends Application { async positionnerHeure(heure) { const indexDate = this.timestamp.indexDate; const addDay = this.timestamp.heure < heure ? 0 : 1; - await this.setNewTimestamp(new RdDTimestamp({ - indexDate: indexDate + addDay, indexHeure: 0 - }) - .addHeures(heure)) + const newTimestamp = new RdDTimestamp({ indexDate: indexDate + addDay}).addHeures(heure); + await this.setNewTimestamp(newTimestamp) } /* -------------------------------------------- */ diff --git a/module/rdd-commands.js b/module/rdd-commands.js index 49ac180a..ebab970a 100644 --- a/module/rdd-commands.js +++ b/module/rdd-commands.js @@ -2,7 +2,8 @@ import { DialogChronologie } from "./dialog-chronologie.js"; import { DialogCreateSigneDraconique } from "./dialog-create-signedraconique.js"; -import { DialogStress } from "./dialog-stress.js"; +import { DialogChateauDormant } from "./sommeil/dialog-chateau-dormant.js"; +import { DialogStress } from "./sommeil/dialog-stress.js"; import { RdDItemCompetence } from "./item-competence.js"; import { Misc } from "./misc.js"; import { RdDCarac } from "./rdd-carac.js"; @@ -13,7 +14,6 @@ import { RdDResolutionTable } from "./rdd-resolution-table.js"; import { RdDRollResolutionTable } from "./rdd-roll-resolution-table.js"; import { RdDRollTables } from "./rdd-rolltables.js"; import { RdDUtility } from "./rdd-utility.js"; -import { CompendiumTableHelpers } from "./settings/system-compendiums.js"; import { FenetreRechercheTirage } from "./tirage/fenetre-recherche-tirage.js"; import { TMRUtility } from "./tmr-utility.js"; @@ -77,6 +77,7 @@ export class RdDCommands { this.registerCommand({ path: ["/tirer", "rencontre"], func: (content, msg, params) => this.getRencontreTMR(params), descr: `Détermine une rencontre dans les TMR (synonyme de "/tmrr")` }); this.registerCommand({ path: ["/tirage"], func: (content, msg, params) => this.tirage(), descr: "Ouvre la fenêtre de recherche et tirage" }); + this.registerCommand({ path: ["/sommeil"], func: (content, msg, params) => this.sommeil(msg, params), descr: "Prépare le passage de journée pour chateau dormant" }); this.registerCommand({ path: ["/meteo"], func: (content, msg, params) => this.getMeteo(msg, params), descr: "Propose une météo marine" }); this.registerCommand({ path: ["/nom"], func: (content, msg, params) => RdDNameGen.getName(msg, params), descr: "Génère un nom aléatoire" }); @@ -462,13 +463,14 @@ export class RdDCommands { let name = params[params.length - 1]; if (name == undefined) { for (let actor of game.actors) { - actor.distribuerStress('stress', stress, motif); + // TODO: ne plus stresser les entités de cauchemar! + await actor.distribuerStress('stress', stress, motif); } } else { //console.log(stressValue, nomJoueur); let actor = Misc.findActor(name, game.actors.filter(it => it.hasPlayerOwner)) ?? Misc.findPlayer(name)?.character if (actor) { - actor.distribuerStress('stress', stress, motif); + await actor.distribuerStress('stress', stress, motif); } else { ui.notifications.warn(`Pas de personnage ou de joueur correspondant à ${name}!`); @@ -485,5 +487,8 @@ export class RdDCommands { async tirage() { FenetreRechercheTirage.create(); } + async sommeil() { + DialogChateauDormant.create(); + } } diff --git a/module/rdd-utility.js b/module/rdd-utility.js index 6c73014b..e69a57b0 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -235,6 +235,7 @@ export class RdDUtility { 'systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.html', 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-alchimie.html', 'systems/foundryvtt-reve-de-dragon/templates/dialog-astrologie-joueur.html', + 'systems/foundryvtt-reve-de-dragon/templates/sommeil/sommeil-actor-moral.hbs', // Calendrier 'systems/foundryvtt-reve-de-dragon/templates/calendar-template.html', 'systems/foundryvtt-reve-de-dragon/templates/calendar-editor-template.html', diff --git a/module/settings/regles-optionelles.js b/module/settings/regles-optionelles.js index 6253b238..04157cb5 100644 --- a/module/settings/regles-optionelles.js +++ b/module/settings/regles-optionelles.js @@ -17,6 +17,7 @@ const listeReglesOptionelles = [ { group: 'Règles générales', name: 'afficher-prix-joueurs', descr: "Afficher le prix de l'équipement des joueurs", uniquementJoueur: true}, { group: 'Règles générales', name: 'appliquer-fatigue', descr: "Appliquer les règles de fatigue"}, { group: 'Règles générales', name: 'afficher-colonnes-reussite', descr: "Afficher le nombre de colonnes de réussite ou d'échec", default: false }, + { group: 'Règles générales', name: 'chateau-dormant-gardien', descr: "Saisie des heures de sommeil/jets de moral par le gardien des rêves", default: true }, { group: 'Confirmations', name: 'confirmer-combat-sans-cible', descr: "Confirmer avant une attaque sans cible", scope: "client"}, { group: 'Confirmations', name: 'confirmation-tmr', descr: "Confirmer pour monter dans les TMR", scope: "client"}, diff --git a/module/sommeil/dialog-chateau-dormant.js b/module/sommeil/dialog-chateau-dormant.js new file mode 100644 index 00000000..bc1f8584 --- /dev/null +++ b/module/sommeil/dialog-chateau-dormant.js @@ -0,0 +1,108 @@ +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 dialogData = { + actorsSettings, + date: date, + motifStress: `Nuit du ${date}`, + finChateauDormant: game.system.rdd.calendrier.getTimestampFinChateauDormant() + }; + const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/sommeil/dialog-chateau-dormant.hbs", + dialogData); + + new DialogChateauDormant(dialogData, html) + .render(true); + } + + constructor(dialogData, html) { + const options = { + classes: ["rdd-dialog-chateau-dormant"], + width: 600, + height: 'fit-content', + 'z-index': 99999 + }; + const conf = { + title: "De Chateau dormant à Vaisseau", + content: html, + buttons: { + chateauDormant: { label: "Passer à Vaisseau!", callback: it => { this.onChateauDormant(); } } + } + }; + super(conf, options); + this.dialogData = dialogData; + } + + activateListeners(html) { + super.activateListeners(html); + this.html = html; + this.html.find('input.sommeil-insomnie').change(event => this.onInsomnie(event)); + this._activateListenerOnActorMoral(this.html); + } + + _activateListenerOnActorMoral(html) { + html.find(`span.sommeil-actor-moral a`).click(event => this.onActorMoral(event)); + } + + onInsomnie(event) { + const sommeilInsomnie = this.html.find(event.currentTarget); + const isInsomnie = sommeilInsomnie.is(':checked'); + const sommeilHeures = sommeilInsomnie.parents('.set-sommeil-actor').find('input.sommeil-heures'); + sommeilHeures.prop('disabled', isInsomnie); + if (isInsomnie) { + sommeilHeures.val('0'); + } + } + + async onActorMoral(event) { + 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); + } + } + + getActorSetting(actorId) { + return this.dialogData.actorsSettings.find(it => it.actor.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 actorRow = this.html.find(it); + const actorId = actorRow.data('actor-id'); + const actorSetting = this.getActorSetting(actorId); + return { + actorId, + 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, + } + } + }); + await Promise.all( + sommeilActors.filter(it => !it.ignorer) + .map(async it => await game.actors.get(it.actorId)?.prepareChateauDormant(this.dialogData.finChateauDormant, it)) + ) + } + +} \ No newline at end of file diff --git a/module/sommeil/dialog-repos.js b/module/sommeil/dialog-repos.js new file mode 100644 index 00000000..4e4c80b1 --- /dev/null +++ b/module/sommeil/dialog-repos.js @@ -0,0 +1,82 @@ +import { ReglesOptionelles } from "../settings/regles-optionelles.js"; + +export class DialogRepos extends Dialog { + + static async create(actor) { + if (!ReglesOptionelles.isUsing("chateau-dormant-gardien")) { + actor.system.sommeil = { + "nouveaujour": true, + "insomnie": false, + "moral": "neutre", + "heures": 4 + } + } + const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/sommeil/dialog-repos.html", actor); + const dialog = new DialogRepos(html, actor); + dialog.render(true); + } + + constructor(html, actor) { + let options = { classes: ["DialogCreateSigneDraconiqueActorsActors"], width: 400, height: 'fit-content', '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; + } + activateListeners(html) { + super.activateListeners(html); + this.html = html; + this.html.find(`.sommeil-actor-moral a`).click(event => this.onActorMoral(event)); + } + /* -------------------------------------------- */ + + async repos() { + const selection = await this.html.find("[name='repos']:checked").val(); + switch (selection) { + case "sieste": return await this.sieste(); + case "nuit": return await this.nuit(); + case "chateau-dormant": return await this.chateauDormant(); + case "gris-reve": return await this.grisReve(); + } + } + + async grisReve() { + await this.html.find("[name='nb-jours']").change(); + const nbJours = Number.parseInt(await this.html.find("[name='nb-jours']").val()); + await this.actor.grisReve(nbJours); + } + + async chateauDormant() { + await this.actor.dormirChateauDormant(); + } + + async nuit() { + await this.html.find("[name='sommeil.heures']").change(); + const sommeilHeures = Number.parseInt(await this.html.find("[name='sommeil.heures']").val()); + await this.actor.dormir(sommeilHeures, { chateauDormant: true }); + } + + async sieste() { + await this.html.find("[name='sieste.heures']").change(); + const siesteHeures = Number.parseInt(await this.html.find("[name='sieste.heures']").val()); + await this.actor.dormir(siesteHeures); + } + + async onActorMoral(event) { + 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}); + const htmlMoral = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/sommeil/sommeil-actor-moral.hbs', { + moral: situationMoral + }); + parentDiv.html(htmlMoral); + this.html.find(`.sommeil-actor-moral a`).click(event => this.onActorMoral(event)); + } +} diff --git a/module/dialog-stress.js b/module/sommeil/dialog-stress.js similarity index 92% rename from module/dialog-stress.js rename to module/sommeil/dialog-stress.js index f0b9b8e6..fd413798 100644 --- a/module/dialog-stress.js +++ b/module/sommeil/dialog-stress.js @@ -15,7 +15,7 @@ export class DialogStress extends Dialog { ) }; - const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-stress.html", dialogData); + const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/sommeil/dialog-stress.html", dialogData); new DialogStress(dialogData, html) .render(true); } @@ -50,7 +50,7 @@ export class DialogStress extends Dialog { this.dialogData.actors.filter(it => it.selected) .map(it => game.actors.get(it.id)) - .forEach(actor => actor.distribuerStress(compteur, stress, motif)); + .forEach(async actor => await actor.distribuerStress(compteur, stress, motif)); } async onSelectActor(event) { diff --git a/module/tmr/effets-draconiques.js b/module/tmr/effets-draconiques.js index f1674a31..06c9939a 100644 --- a/module/tmr/effets-draconiques.js +++ b/module/tmr/effets-draconiques.js @@ -164,6 +164,10 @@ export class EffetsDraconiques { return actor.items.find(it => EffetsDraconiques.urgenceDraconique.match(it)); } + static isSujetInsomnie(actor) { + return actor.items.find(it => ['queue', 'ombre'].includes(it.type) && Grammar.includesLowerCaseNoAccent(it.name, 'Insomnie')) ? true : false; + } + static isPeage(actor) { return EffetsDraconiques.filterItems(actor, Draconique.isSouffleDragon, 'péage').length > 0; } diff --git a/styles/simple.css b/styles/simple.css index e5999b92..c7207408 100644 --- a/styles/simple.css +++ b/styles/simple.css @@ -80,7 +80,8 @@ --background-custom-button: linear-gradient(to bottom, rgba(33, 55, 74, 0.988) 5%, rgba(21, 40, 51, 0.671) 100%); --background-custom-button-hover: linear-gradient(to bottom, rgb(128, 0, 0) 5%, rgb(62, 1, 1) 100%); - --background-tooltip: rgba(220,220,210,0.95); + --background-control-selected: linear-gradient(to bottom, hsla(0, 100%, 25%, 0.5) 5%, hsla(0, 100%, 12%, 0.5) 100%); + --background-tooltip: hsla(60, 12%, 85%, 0.95); --background-error:hsla(16, 100%, 50%, 0.8); } @@ -250,7 +251,10 @@ nav.sheet-tabs .item:after { /* =================== Autres ============ */ -.tabs .item.active, .blessures-list li ul li:first-child:hover, a:hover { +.tabs .item.active, +.blessures-list li ul li:first-child:hover, +i.moral-radio-checkmark-off:hover, +a:hover { text-shadow: 1px 0px 0px #ff6600; } @@ -514,7 +518,7 @@ input:is(.blessure-premiers_soins, .blessure-soins_complets) { border: 0; vertical-align: bottom; } -:is(.button-img,.button-effect-img:hover,.small-button-direction):hover { +:is(.button-img,.button-effect-img,.small-button-direction):hover { color: var(--color-controls-hover); border: 1px solid var(--color-control-border-hover); text-shadow: 1px 0px 0px #ff6600; @@ -602,13 +606,13 @@ input:is(.blessure-premiers_soins, .blessure-soins_complets) { margin-right: 0.2rem; margin-left: 0.2rem; } -.rdd.sheet .window-content .sheet-body .carac-list .caracteristique .flex-grow-1 { +.flex-grow-1 { flex-grow: 1; } -.rdd.sheet .window-content .sheet-body .carac-list .caracteristique .flex-grow-2 { +.flex-grow-2 { flex-grow: 2; } -.rdd.sheet .window-content .sheet-body .carac-list .caracteristique .flex-grow-3 { +.flex-grow-3 { flex-grow: 3; } diff --git a/template.json b/template.json index 2a49c793..52543e5f 100644 --- a/template.json +++ b/template.json @@ -528,6 +528,16 @@ "label": "Experience", "isInput": true } + }, + "sommeil": { + "nouveaujour": false, + "date":{ + "indexDate": -1, + "indexMinute": 0 + }, + "insomnie": false, + "moral": "", + "heures": 0 } } }, diff --git a/templates/dialog-repos.html b/templates/dialog-repos.html deleted file mode 100644 index f3a0c6d3..00000000 --- a/templates/dialog-repos.html +++ /dev/null @@ -1,34 +0,0 @@ -
- {{name}} -
-
-

{{name}} se repose

-
-
- - -
-

-
- - -
-
- - -
-
- - -
-

-
- - -
-
- - -
-
-
\ No newline at end of file diff --git a/templates/sommeil/dialog-chateau-dormant.hbs b/templates/sommeil/dialog-chateau-dormant.hbs new file mode 100644 index 00000000..98f708b2 --- /dev/null +++ b/templates/sommeil/dialog-chateau-dormant.hbs @@ -0,0 +1,48 @@ +
+
+
+ + +
+
+ +
+
diff --git a/templates/sommeil/dialog-repos.html b/templates/sommeil/dialog-repos.html new file mode 100644 index 00000000..ffc71c2c --- /dev/null +++ b/templates/sommeil/dialog-repos.html @@ -0,0 +1,53 @@ +
+ {{name}} +
+
+

{{name}} se repose

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

+ {{#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}} +

+
+ + +
+
+ + +
+
+
\ No newline at end of file diff --git a/templates/dialog-stress.html b/templates/sommeil/dialog-stress.html similarity index 100% rename from templates/dialog-stress.html rename to templates/sommeil/dialog-stress.html diff --git a/templates/sommeil/sommeil-actor-moral.hbs b/templates/sommeil/sommeil-actor-moral.hbs new file mode 100644 index 00000000..2198883b --- /dev/null +++ b/templates/sommeil/sommeil-actor-moral.hbs @@ -0,0 +1,11 @@ + + + + + + + + + + +