import { TYPES } from "../item.js" import { RdDItemCompetence } from "../item-competence.js" import { ChatUtility } from "../chat-utility.js" import { Misc } from "../misc.js" const CODES_COMPETENCES_VOYAGE = ['Extérieur', 'Forêt', 'Montagne', 'Marais', 'Glace', 'Equitation'] const TABLEAU_FATIGUE_MARCHE = [ { code: "aise", label: "Aisé", description: "Route ou chemin", survies: ['Extérieur', 'Equitation'], vitesses: [{ vitesse: 4, fatigue: 1 }, { vitesse: 6, fatigue: 2 }, { vitesse: 8, fatigue: 3 }, { vitesse: 10, fatigue: 4 }, { vitesse: 12, fatigue: 6 }], }, { code: "malaise", label: "Malaisé", description: "Hors piste (herbes et buissons)", survies: ['Extérieur', 'Equitation'], vitesses: [{ vitesse: 4, fatigue: 2 }, { vitesse: 6, fatigue: 3 }, { vitesse: 8, fatigue: 4 }, { vitesse: 10, fatigue: 6 }], }, { code: "difficile", label: "Difficile", description: "Hors piste (collines, forêt)", survies: ['Extérieur', 'Forêt', 'Glace', 'Equitation'], vitesses: [{ vitesse: 4, fatigue: 3 }, { vitesse: 6, fatigue: 4 }, { vitesse: 8, fatigue: 6 }], }, { code: "tresdifficile", label: "Très difficile", description: "Hors piste (montagne, jungle, marais)", survies: ['Forêt', 'Montagne', 'Marais', 'Glace'], vitesses: [{ vitesse: 4, fatigue: 4 }, { vitesse: 6, fatigue: 6 }], }, ] export class DialogFatigueVoyage extends Dialog { static dialog = undefined static async create() { if (!game.user.isGM) { return } if (!DialogFatigueVoyage.dialog) { const parameters = { tableauFatigueMarche: TABLEAU_FATIGUE_MARCHE, playerActors: game.actors.filter(actor => actor.isPersonnageJoueur()) .map(actor => DialogFatigueVoyage.prepareActorParameters(actor)), nombreHeures: 1, } DialogFatigueVoyage.setModeDeplacement(parameters, undefined, undefined) const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/voyage/dialog-fatigue-voyage.hbs", parameters); DialogFatigueVoyage.dialog = new DialogFatigueVoyage(html, parameters); } DialogFatigueVoyage.dialog.render(true); } static setModeDeplacement(parameters, code, vitesse) { const ligneFatigueMarche = TABLEAU_FATIGUE_MARCHE.find(it => it.code == code) ?? TABLEAU_FATIGUE_MARCHE[0] const rythme = ligneFatigueMarche.vitesses.find(it => it.vitesse == vitesse) ?? ligneFatigueMarche.vitesses[0] parameters.typeTerrain = ligneFatigueMarche parameters.vitesseDeplacement = rythme.vitesse parameters.fatigueHoraire = rythme.fatigue parameters.playerActors.forEach(voyageur => DialogFatigueVoyage.selectSurvie(voyageur, parameters.typeTerrain.code) ) } static prepareActorParameters(actor) { const actorParameters = { id: actor.id, actor: actor, selected: true, ajustementFatigue: 0, survies: {} } const competencesVoyage = {} CODES_COMPETENCES_VOYAGE.forEach(codeSurvie => { competencesVoyage[codeSurvie] = RdDItemCompetence.findCompetence(actor.itemTypes[TYPES.competence], codeSurvie, { onMessage: () => { } }) }) TABLEAU_FATIGUE_MARCHE.forEach(terrain => { actorParameters.survies[terrain.code] = Misc.join( terrain.survies.map(survie => { const niveau = competencesVoyage[survie]?.system.niveau return `${survie}: ${niveau}` }), ', ') }) return actorParameters } static selectSurvie(actorParameters, code) { actorParameters.survieCourante = actorParameters.survies[code] } constructor(html, parameters) { const options = { classes: ["dialog-fatigue-voyage"], width: 600, height: 'fit-content', 'max-height': 900, 'z-index': 99999 } const conf = { title: "Fatigue de voyage", content: html, buttons: {} } super(conf, options); this.parameters = parameters this.controls = {} } activateListeners(html) { if (this.html == undefined) { html.find('select[name="code-terrain"]').trigger("focus") } this.html = html; super.activateListeners(html); this.html.find('select[name="code-terrain"]').change(event => this.changeParameters()) this.html.find('select[name="vitesse-deplacement"]').change(event => this.changeParameters()) this.html.find('input[name="nombre-heures"]').change(event => this.changeParameters()) this.html.find('.list-item input[name="ajustement-fatigue"]').change(event => this.changeParameters()) this.html.find('button[name="appliquer-fatigue"]').click(event => this.appliquerFatigue()) } changeParameters() { this.changeTerrain(this.html.find('select[name="code-terrain"]').val()) this.changeVitesse(this.html.find('select[name="vitesse-deplacement"]').val()) this.changeNombreHeures(this.html.find('input[name="nombre-heures"]').val()) this.setFatigue() } async changeTerrain(codeTerrain) { if (this.parameters.typeTerrain.code != codeTerrain) { const selectVitesseDeplacement = this.html.find('select[name="vitesse-deplacement"]') const vitesse = selectVitesseDeplacement.val() selectVitesseDeplacement.empty() DialogFatigueVoyage.setModeDeplacement(this.parameters, codeTerrain, vitesse) this.parameters.typeTerrain.vitesses.forEach(async rythme => { selectVitesseDeplacement.append(await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/voyage/option-vitesse-fatigue.hbs', rythme)) }) selectVitesseDeplacement.val(this.parameters.vitesseDeplacement).change() Promise.all(this.getActorRows() .map(async row => row.find('label.voyage-liste-survies').text(this.$extractActorParameters(row).survieCourante) )) } } async changeVitesse(vitesse) { if (this.parameters.vitesseDeplacement != vitesse) { DialogFatigueVoyage.setModeDeplacement(this.parameters, this.parameters.typeTerrain.code, vitesse) } } async changeNombreHeures(nombreHeures) { this.parameters.nombreHeures = parseInt(nombreHeures) } async setFatigue() { const baseFatigue = this.parameters.nombreHeures * this.parameters.fatigueHoraire this.html.find('input[name="base-fatigue"]').val(baseFatigue) this.updateActorTotalFatigue(baseFatigue) } async updateActorTotalFatigue(baseFatigue) { Promise.all(this.getActorRows() .map(async row => { const actor = this.$extractActorParameters(row) row.find('input[name="total-fatigue"]').val(actor.ajustement + baseFatigue) })) } async appliquerFatigue() { const fatigueBase = parseInt(this.html.find('input[name="base-fatigue"]').val() ?? 0) this.getActorRows() .map(row => this.$extractActorParameters(row)) .filter(it => it.selected) .forEach(async it => { const perteFatigue = fatigueBase + it.ajustement ChatMessage.create({ whisper: ChatUtility.getWhisperRecipientsAndGMs(it.actor.name), content: await renderTemplate( 'systems/foundryvtt-reve-de-dragon/templates/voyage/chat-fatigue_voyage.hbs', foundry.utils.mergeObject(it, { parameters: this.parameters, fatigueBase: fatigueBase, perteFatigue: perteFatigue, isVoyage: fatigueBase == this.parameters.nombreHeures * this.parameters.fatigueHoraire }, { inplace: false }) ), }) await it.actor.santeIncDec("fatigue", perteFatigue) }) } getActorRows() { return jQuery.map( this.html.find('div.fatigue-actors-list li.list-item'), it => this.html.find(it)) } $extractActorParameters(actorRow) { const actorId = actorRow.data('actor-id') const actorParameters = this.parameters.playerActors.find(it => it.id == actorId) const actor = game.actors.get(actorId) if (!actor) { ui.notifications.warn(`Acteur ${it.actorId} introuvable`) return {} } actorParameters.ajustement = parseInt(actorRow.find('input[name="ajustement-fatigue"]').val() ?? 0) actorParameters.selected = actor && actorRow.find('input[name="selectionner-acteur"]').is(':checked') return actorParameters } async close() { DialogFatigueVoyage.dialog = undefined await super.close() } }