diff --git a/module/actor.js b/module/actor.js
index acf82344..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));
@@ -1612,7 +1671,7 @@ export class RdDActor extends RdDBaseActor {
case 'heureux': case 'heureuse': return succes ? 1 : 0;
case 'malheureuse': case 'malheureux': return succes ? 0 : -1;
case 'neutre':
- if (succes && moral <= 0) return 1;
+ if (succes && moral < 0) return 1;
if (!succes && moral > 0) return -1;
}
return 0;
@@ -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..8730f7ee 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;
@@ -67,17 +69,17 @@ export class RdDCalendrier extends Application {
this.html.find('.calendar-btn').click(ev => this.onCalendarButton(ev));
- this.html.find('.calendar-btn-edit').click(ev => {
+ this.html.find('.calendar-set-datetime').click(ev => {
ev.preventDefault();
this.showCalendarEditor();
});
- this.html.find('.astrologie-btn-edit').click(ev => {
+ this.html.find('.calendar-astrologie').click(ev => {
ev.preventDefault();
this.showAstrologieEditor();
});
- this.html.find('#calendar-move-handle').mousedown(ev => {
+ this.html.find('.calendar-title').mousedown(ev => {
ev.preventDefault();
ev = ev || window.event;
let isRightMB = false;
@@ -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)
}
/* -------------------------------------------- */
@@ -428,13 +432,13 @@ export class RdDCalendrier extends Application {
if (game.user.isGM) {
dateHTML = dateHTML + "
Nombre Astral: " + (this.getNombreAstral() ?? "?");
}
- for (let handle of document.getElementsByClassName("calendar-date-rdd")) {
+ for (let handle of document.getElementsByClassName("calendar-title")) {
handle.innerHTML = dateHTML;
}
for (let heure of document.getElementsByClassName("calendar-heure-texte")) {
heure.innerHTML = calendrier.heure.label;
}
- for (const minute of document.getElementsByClassName("calendar-time-disp")) {
+ for (const minute of document.getElementsByClassName("calendar-minute-texte")) {
minute.innerHTML = `${calendrier.minute} minutes`;
}
for (const heureImg of document.getElementsByClassName("calendar-heure-img")) {
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/tirage/fenetre-recherche-tirage.js b/module/tirage/fenetre-recherche-tirage.js
index 9d4bbc8f..0f3da395 100644
--- a/module/tirage/fenetre-recherche-tirage.js
+++ b/module/tirage/fenetre-recherche-tirage.js
@@ -189,30 +189,6 @@ export class FenetreRechercheTirage extends Application {
const row = await CompendiumTableHelpers.getRandom(table, 'Item')
await CompendiumTableHelpers.tableRowToChatMessage(row, 'Item');
})
-
- // this.html.find('.recherche')
- // .each((index, field) => {
- // if (this.options.recherche) {
- // field.focus();
- // field.setSelectionRange(this.options.recherche.start, this.options.recherche.end);
- // }
- // })
- // .keyup(async event => {
- // const nouvelleRecherche = this._optionRecherche(event.currentTarget);
- // if (this.options.recherche?.text != nouvelleRecherche?.text) {
- // this.options.recherche = nouvelleRecherche;
- // if (this.timerRecherche) {
- // clearTimeout(this.timerRecherche);
- // }
- // this.timerRecherche = setTimeout(() => {
- // this.timerRecherche = undefined;
- // this.render(true);
- // }, 500);
- // }
- // })
- // .change(async event =>
- // this.options.recherche = this._optionRecherche(event.currentTarget)
- // );
}
showFilterGroup(groupDiv, show) {
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..9b8eb556 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;
}
@@ -1560,213 +1564,176 @@ table.table-nombres-astraux tr:hover {
position: absolute;
display: block;
}
-.calendar{
- min-width: 150px;
- grid-row: 1;
- grid-column: 1;
+
+.calendar {
+ min-width: 250px;
width: fit-content;
- height: 6rem;
+
+ display: grid;
+ grid-row: 2;
+ grid-column: 9;
+
+ min-height: 5rem;
+ height: fit-content;
margin: 0;
padding: 0;
border: 1px solid #000;
- border-radius: 3%;
- background: rgba(0, 0, 0, 0.5);
+ border-radius: 0.3rem;
+ background: hsla(0, 0%, 0%, 0.5);
font-family: "GoudyAcc";
z-index: 100;
}
-.calendar-hdr{
- display: grid;
- font-size: 1rem;
- margin: 0.1rem;
- padding: 0.2rem;
- height: fit-content;
- width: fit-content;
- min-width: 200px;
- border-bottom: 1px solid #111;
- color: #CCC;
- float: left;
-}
-.calendar-date-rdd {
- font-family: "GoudyAcc";
+
+.calendar-title {
+ grid-column: 1 / span 7;
+ grid-row: 1;
+
color: #CCC;
opacity: 90;
font-size: 0.9rem;
text-align: center;
- padding: 0;
- margin: 0;
- border: none;
- flex: 1;
}
-.calendar-date{
- grid-row: 1;
- grid-column: 2;
- float: left;
- text-align: center;
- padding-top: 0px;
- padding-bottom: 0px;
- margin-bottom: 5px;
- color: #CCC;
- cursor: pointer;
+.calendar-options {
+ grid-column: 8 / span 2;
}
-.calendar-date,
-.calendar-date-num {
- transition: 0.2s;
+.calendar-title,.calendar-options{
+ border-bottom: 1px solid hsla(0, 0%, 80%, 0.5);
}
-.calendar-date-num {
- grid-row: 1;
- grid-column: 2;
- float: left;
- text-align: center;
- padding-top: 0px;
- padding-bottom: 0px;
- margin-bottom: 5px;
- color: #CCC;
- opacity: 0;
- cursor: pointer;
+
+.calendar-avance-heure {
+ grid-column: 1 / span 3;
}
-.calendar-heure-img{
- width: 24px;
- height: 24px;
- flex-grow: 0;
- border-width: 0;
- opacity: 90;
- color: rgba(255, 255, 255, 0.5);
+
+.calendar-change-heure {
+ grid-column: 9 / span 1;
}
-.calendar-hdr:hover .calendar-date {
- opacity: 0;
+
+.calendar-change-heure .calendar-change-heure-grid {
+ display: grid;
+ grid-column: 1;
+ grid-row: 2;
+
+ margin: 2px;
+ grid-row-gap: 3px;
+ color: hsla(0, 0%, 80%, 0.5);
}
-.calendar-hdr:hover .calendar-date-num{
- opacity: 1;
-}
-.calendar-container{
- min-width: 250px;
- padding-top: 3px;
- padding-bottom: 20px;
-}
-.calendar-btn-container-left{
- width: 25%;
+
+.calendar-avance-heure .calendar-avance-heure-grid {
display: grid;
- float: left;
+ grid-column: 3;
+ grid-row: 2;
+
margin: 2px;
grid-row-gap: 3px;
- color: rgba(0, 0, 0, 0.5);
+ color: hsla(0, 0%, 80%, 0.5);
}
-.calendar-btn-container-right{
- width: 15%;
+
+.calendar-avance-heure .calendar-avance-heure-grid:hover {
+ color: #FFF;
+ cursor: pointer;
+}
+
+.calendar-affiche-heure {
+ grid-column: 4 / span 4;
+ grid-row: 2;
+}
+
+.calendar-affiche-heure .calendar-horloge {
display: grid;
- float: right;
- margin: 2px;
- grid-row-gap: 3px;
+ max-width: 100px;
+ float: left;
+ padding-top: 0px;
+ padding-bottom: 0px;
+ margin: 0 0.3rem 0 0.3rem;
+ color: #CCC;
+ text-align: center;
}
-.astrologie-btn-edit,
-.calendar-btn-edit{
+
+.calendar-affiche-heure .calendar-horloge .calendar-heure-texte {
+ font-size: 1.1rem;
+}
+.calendar-affiche-heure .calendar-horloge .calendar-minute-texte {
+ margin: 0;
+}
+
+.calendar-affiche-heure .calendar-horloge .calendar-heure-img{
+ width: 2rem;
+ height: 2rem;
+ float: left;
+ flex-grow: 0;
+ padding: 0.1rem;
+ border: 0;
+ opacity: 0.9;
+ color: hsla(0, 0%, 100%, 0.5);
+}
+
+.calendar :is(.calendar-astrologie,.calendar-set-datetime) {
grid-row: 1;
grid-column: 1;
}
-:is(.astrologie-btn-edit,.calendar-btn-edit,.calendar-btn){
- margin: auto;
+.calendar :is(.calendar-astrologie,.calendar-set-datetime,.calendar-btn) {
+ color: hsla(0, 0%, 100%, 0.5);
border: 1px solid rgba(0, 0, 0, 0);
- color: rgba(255, 255, 255, 0.5);
}
-:is(.astrologie-btn-edit,.calendar-btn-edit,.calendar-btn):hover {
- color: var(--color-controls-hover);
+.calendar :is(.calendar-astrologie,.calendar-set-datetime,.calendar-btn):hover {
+ color: var(--color-controls-hover);
border: 1px solid var(--color-control-border-hover);
cursor: pointer;
}
+.calendar .calendar-affiche-heure .calendar-horloge a {
+ border: 1px solid rgba(0, 0, 0, 0);
+}
+.calendar .calendar-affiche-heure .calendar-horloge a:hover {
+ color: var(--color-controls-hover);
+ border: 1px solid var(--color-control-border-hover);
+ cursor: pointer;
+}
-.calendar-1min{
+.calendar-avance-heure .calendar-1min {
grid-row: 1;
grid-column: 1;
- margin-left: 0.2rem;
}
-.calendar-5min{
+.calendar-avance-heure .calendar-5min {
grid-row: 1;
grid-column: 2;
}
-.calendar-15min{
+.calendar-avance-heure .calendar-15min {
grid-row: 1;
grid-column: 3;
- margin-right: 0.2rem;
}
-
-.calendar-30min{
+.calendar-avance-heure .calendar-30min {
grid-row: 2;
grid-column: 1;
- margin-left: 0.2rem;
}
-
-.calendar-60min{
+.calendar-avance-heure .calendar-60min {
grid-row: 2;
grid-column: 2;
}
-.calendar-1heure{
+.calendar-avance-heure .calendar-1heure {
grid-row: 2;
grid-column: 3;
- margin-right: 0.2rem;
}
.calendar-lyre{
grid-row: 1;
grid-column: 1;
- margin-left: 0.2rem;
- margin-right: 0.2rem;
}
-.calendar-vaisseau{
+.calendar-vaisseau {
grid-row: 2;
grid-column: 1;
- margin-left: 0.2rem;
- margin-right: 0.2rem;
}
-.img-calendar-forward{
- color: rgba(255, 255, 255, 0.5);
+
+.calendar-change-heure .calendar-btn:is(.calendar-lyre,.calendar-vaisseau) img {
+ color: hsla(0, 0%, 100%, 0.5);
vertical-align: bottom;
max-width: 1.2em;
max-height: 1.2em;
border-width: 0;
}
-.calendar-btn-container-left:hover{
- color: #FFF;
- border: 0px solid #000;
- cursor: pointer;
-}
-.calendar-weekday-time{
- display: grid;
- float: left;
- width: 55%;
- padding-top: 0px;
- padding-bottom: 0px;
- margin: auto;
- color: #CCC;
-}
-.calendar-weekday {
- grid-column: 1;
- grid-row: 1;
- text-align: center;
- font-size: 1.1rem;
- margin: auto;
-}
-.calendar-time{
- grid-column: 1;
- grid-row: 2;
- text-align: center;
- margin: auto;
- cursor: pointer;
- display: inline-flex;
-}
-.calendar-nombre-astral{
-grid-column: 2;
-grid-row: 2;
-font-size: 1.1rem;
-text-align: right;
-margin: auto;
-cursor: pointer;
-display: inline-flex;
-}
-.calendar-time-disp{
- position: relative;
- bottom: 6px;
+div.calendar-timestamp-edit select.calendar-signe-heure {
+ width: max-content;
}
/* Tooltip container */
diff --git a/system.json b/system.json
index 1b2908d1..8a593495 100644
--- a/system.json
+++ b/system.json
@@ -1,8 +1,8 @@
{
"id": "foundryvtt-reve-de-dragon",
"title": "Rêve de Dragon",
- "version": "10.6.13",
- "download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.6.13.zip",
+ "version": "10.6.14",
+ "download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-10.6.14.zip",
"manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v10/system.json",
"compatibility": {
"minimum": "10",
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/calendar-template.html b/templates/calendar-template.html
index d08c4750..4c77d5e8 100644
--- a/templates/calendar-template.html
+++ b/templates/calendar-template.html
@@ -1,47 +1,47 @@
{{jourDuMois}} {{mois.label}} ({{mois.saison}})
-