Files
foundryvtt-reve-de-dragon/module/sommeil/dialog-nouveau-repos.js
T

197 lines
6.7 KiB
JavaScript

import { renderTemplate } from "../constants.js"
import { RdDTimestamp, RDD_HEURES_PAR_JOUR } from "../time/rdd-timestamp.js"
import { ChatUtility } from "../chat-utility.js"
import { DialogNouveauReposCD } from "./dialog-nouveau-repos-cd.js"
export class DialogNouveauRepos extends Dialog {
static async create(actor) {
if (!actor.isPersonnage()) return
const now = game.system.rdd.calendrier.timestamp
const heureCourante = now.heure
const hourDefs = RdDTimestamp.definitions()
const data = {
name: actor.name,
img: actor.img,
hourDefinitions: hourDefs,
heureDebutDefaut: heureCourante,
heureFinDefaut: Math.min(heureCourante + 7, 11),
}
const html = await renderTemplate(
"systems/foundryvtt-reve-de-dragon/templates/sommeil/dialog-nouveau-repos.hbs",
data
)
new DialogNouveauRepos(html, actor).render(true)
}
constructor(html, actor) {
super({
title: "Se reposer — " + actor.name,
content: html,
buttons: {
dormir: { label: "Dormir", callback: () => this._onDormir() },
chateauDormant: { label: "Passer Château Dormant", callback: () => this._onChateauDormant() }
}
}, {
classes: ["dialog-nouveau-repos"],
width: 450,
height: 'fit-content',
'z-index': 99999
})
this.actor = actor
}
activateListeners($html) {
super.activateListeners($html)
this.$html = $html
this.$html.find('select[name="heure-debut"], select[name="heure-fin"]').change(() => this._updateDuree())
this.$html.find('input[name="reveil-force"]').change(() => this._toggleReveilForce())
this._updateDuree()
}
_updateDuree() {
const debut = Number(this.$html.find('select[name="heure-debut"]').val())
const fin = Number(this.$html.find('select[name="heure-fin"]').val())
const duree = fin >= debut ? fin - debut + 1 : (RDD_HEURES_PAR_JOUR - debut) + fin + 1
this.$html.find('#duree-sommeil').text(duree)
}
_toggleReveilForce() {
const checked = this.$html.find('input[name="reveil-force"]').is(':checked')
this.$html.find('input[name="heures-force"]').prop('disabled', !checked)
}
async _onDormir() {
const debut = Number(this.$html.find('select[name="heure-debut"]').val())
const fin = Number(this.$html.find('select[name="heure-fin"]').val())
const reveilForce = this.$html.find('input[name="reveil-force"]').is(':checked')
const heuresForce = Number(this.$html.find('input[name="heures-force"]').val())
const duree = fin >= debut ? fin - debut + 1 : (RDD_HEURES_PAR_JOUR - debut) + fin + 1
const valide = await this._valider(debut, duree, reveilForce, heuresForce)
if (!valide) return
this.close()
await this._executerSommeil(debut, duree, reveilForce, heuresForce)
}
async _onChateauDormant() {
this.close()
const cdData = await DialogNouveauReposCD.prompt(this.actor)
if (cdData.stress.valeur > 0) {
await this.actor.distribuerStress('stress', cdData.stress.valeur, cdData.stress.motif)
}
await this.actor.update({
'system.sommeil': {
nouveaujour: true,
date: game.system.rdd.calendrier.getTimestampFinChateauDormant(),
moral: cdData.moral,
heures: 0
}
})
await this.actor.$dormirChateauDormant()
}
async _valider(debut, duree, reveilForce, heuresForce) {
const $av = this.$html.find('#avertissements')
$av.empty().show()
const fatigue = this.actor.system.sante.fatigue.value
const fatigueMin = this.actor.getFatigueMin()
const aFatigue = fatigue > fatigueMin
const aHeuresJour = this._aHeuresJour(debut, duree)
if (aHeuresJour && !aFatigue) {
$av.html('<p class="notification error">Vous n\'avez pas assez de fatigue pour dormir de jour.</p>')
return false
}
if (aHeuresJour && aFatigue) {
$av.append('<p class="notification warning">Vous vous réveillerez dès la fatigue récupérée (sommeil de jour).</p>')
}
if (reveilForce && heuresForce < duree) {
$av.append('<p class="notification info">Vous serez réveillé après ' + heuresForce + ' heures.</p>')
}
return true
}
_aHeuresJour(debut, duree) {
for (let h = 0; h < duree; h++) {
const heure = (debut + h) % RDD_HEURES_PAR_JOUR
if (heure > 0 && heure < 6) return true
}
return false
}
async _executerSommeil(heureDebut, duree, reveilForce, heuresForce) {
const message = {
whisper: ChatUtility.getOwners(this.actor),
content: this.actor.name + ': '
}
const dormi = { heures: 0, etat: 'dort', jetsReve: [] }
const insomnie = this.actor.system.sommeil?.insomnie || duree === 0
await this.actor.recupereEndurance({ message, demi: insomnie })
if (insomnie) {
message.content += 'Vous ne trouvez pas le sommeil'
} else {
const avaitFatigue = this.actor.system.sante.fatigue.value > this.actor.getFatigueMin()
if (!avaitFatigue && heureDebut >= 6 && heureDebut <= 11) {
duree = RDD_HEURES_PAR_JOUR - heureDebut + 1
}
let cdProcessed = false
let h = 0
while (true) {
if (dormi.etat !== 'dort') break
if (reveilForce && dormi.heures >= heuresForce) break
if (!avaitFatigue && h >= duree) break
if (avaitFatigue && this.actor.system.sante.fatigue.value <= this.actor.getFatigueMin()) break
const heureActuelle = (heureDebut + h) % RDD_HEURES_PAR_JOUR
await this.actor.$recupererEthylisme(message)
await this.actor.$recupererFatigue(message)
await this.actor.$jetRecuperationReve(dormi, message)
dormi.heures++
if (dormi.etat !== 'dort') break
if (heureActuelle === RDD_HEURES_PAR_JOUR - 1 && !cdProcessed) {
cdProcessed = true
const cdData = await DialogNouveauReposCD.prompt(this.actor)
if (cdData.stress.valeur > 0) {
await this.actor.distribuerStress('stress', cdData.stress.valeur, cdData.stress.motif)
}
await this.actor.update({
'system.sommeil': {
nouveaujour: true,
date: game.system.rdd.calendrier.getTimestampFinChateauDormant(),
moral: cdData.moral,
heures: Math.max(0, duree - h - 1)
}
})
await this.actor.$dormirChateauDormant()
}
h++
}
if (dormi.jetsReve.length > 0) {
message.content += 'Vous récupérez ' +
dormi.jetsReve.map(it => it < 0 ? '0 (réveil)' : it).join('+') +
' Points de rêve. '
}
if (dormi.etat === 'eveil') {
await this.actor.reveilReveDeDragon(message, dormi.heures)
}
message.content += `Vous avez dormi ${dormi.heures <= 1 ? 'une heure' : (dormi.heures + ' heures')}. `
}
await ChatMessage.create(message)
}
}