220 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			220 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import { ITEM_TYPES } from "../constants.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[ITEM_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.getOwners(it.actor),
 | |
|           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()
 | |
|   }
 | |
| 
 | |
| 
 | |
| } |