forked from public/foundryvtt-reve-de-dragon
		
	
		
			
				
	
	
		
			200 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			200 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import { RdDItem } from "../item.js";
 | |
| import { Misc } from "../misc.js";
 | |
| import { RdDTimestamp } from "../time/rdd-timestamp.js";
 | |
| 
 | |
| const BASE_TACHE_SOIN_BLESSURE = {
 | |
|   type: "tache",
 | |
|   img: 'systems/foundryvtt-reve-de-dragon/icons/competence_chirurgie.webp',
 | |
|   system: { carac: "dexterite", competence: "Chirurgie", periodicite: "1 round", fatigue: 0, }
 | |
| }
 | |
| const TACHES_SOIN_BLESSURE = {
 | |
|   6: { name: 'Blessure critique', system: { difficulte: -6, points_de_tache: 6 } },
 | |
|   4: { name: 'Blessure grave', system: { difficulte: -4, points_de_tache: 4 } },
 | |
|   2: { name: 'Blessure légère', system: { difficulte: -2, points_de_tache: 2 } },
 | |
| }
 | |
| 
 | |
| const definitionsBlessures = [
 | |
|   { type: "contusion", gravite: 0, label: 'Contusion/éraflure', max: 100, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/eraflure.webp" },
 | |
|   { type: "legere", gravite: 2, label: 'Légère', max: 5, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/blessure.webp" },
 | |
|   { type: "grave", gravite: 4, label: 'Grave', max: 2, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/blessure.webp" },
 | |
|   { type: "critique", gravite: 6, label: 'Critique', max: 1, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/blessure.webp" },
 | |
|   { type: "mort", gravite: 8, label: 'Mort', max: 1, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/mort.webp" }
 | |
| ]
 | |
| 
 | |
| export class RdDItemBlessure extends RdDItem {
 | |
| 
 | |
|   static get defaultIcon() {
 | |
|     return "systems/foundryvtt-reve-de-dragon/icons/sante/blessure.webp";
 | |
|   }
 | |
| 
 | |
|   prepareDerivedData() {
 | |
|     super.prepareDerivedData();
 | |
|     this.system.label = this.getLabelGravite()
 | |
|   }
 | |
| 
 | |
|   static prepareTacheSoin(gravite) {
 | |
|     const tache = TACHES_SOIN_BLESSURE[gravite]
 | |
|     if (!tache) {
 | |
|       ui.notifications.warn(`Pas de tâche de soins pour une blessure ${gravite}`)
 | |
|       return undefined;
 | |
|     }
 | |
|     return mergeObject(duplicate(BASE_TACHE_SOIN_BLESSURE), tache)
 | |
|   }
 | |
|   static async createBlessure(actor, gravite, localisation = '', attacker) {
 | |
|     const definition = RdDItemBlessure.getDefinition(gravite)
 | |
|     const blessure = {
 | |
|       name: definition.label,
 | |
|       type: 'blessure',
 | |
|       img: definition.icon,
 | |
|       system: {
 | |
|         gravite: gravite,
 | |
|         difficulte: - gravite,
 | |
|         localisation: localisation,
 | |
|         origine: attacker?.name ?? ""
 | |
|       }
 | |
|     }
 | |
|     const blessures = await actor.createEmbeddedDocuments('Item', [blessure])
 | |
|     return blessures[0]
 | |
|   }
 | |
| 
 | |
|   static async createTacheSoinBlessure(actor, gravite) {
 | |
|     const tache = RdDItemBlessure.prepareTacheSoin(gravite)
 | |
|     if (tache) {
 | |
|       const taches = await actor.createEmbeddedDocuments('Item', [tache], { renderSheet: false });
 | |
|       return taches[0];
 | |
|     }
 | |
|     return undefined
 | |
|   }
 | |
| 
 | |
|   async updateTacheSoinBlessure(tache) {
 | |
|     if (tache) {
 | |
|       await tache.update({
 | |
|         system: {
 | |
|           itemId: this.id,
 | |
|           difficulte: Math.min(this.system.difficulte, tache.system.difficulte),
 | |
|           points_de_tache_courant: Math.max(0, this.system.premierssoins.tache)
 | |
|         }
 | |
|       });
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   async setSoinsBlessure(systemUpdate = {}) {
 | |
|     systemUpdate = mergeObject(systemUpdate, this.system, { overwrite: false }),
 | |
|       systemUpdate.soinscomplets.done = systemUpdate.premierssoins.done && systemUpdate.soinscomplets.done
 | |
|     await this.update({
 | |
|       img: this.getImgSoins(systemUpdate.gravite, systemUpdate.soinscomplets.done),
 | |
|       system: systemUpdate
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   async recuperationBlessure({ actor, timestamp, message, isMaladeEmpoisonne, blessures }) {
 | |
|     if (this.parent != actor || actor == undefined) {
 | |
|       return
 | |
|     }
 | |
|     if (new RdDTimestamp(this.system.temporel.fin).compare(timestamp) > 0) {
 | |
|       // attente periode
 | |
|       return
 | |
|     }
 | |
|     if (this.system.gravite > 0) {
 | |
|       const update = { system: { premierssoins: { bonus: 0 }, soinscomplets: { bonus: 0 } } }
 | |
|       const gravite = this.system.gravite;
 | |
|       const graviteMoindre = gravite - 2;
 | |
|       const moindres = blessures.filter(it => it.system.gravite == graviteMoindre, 'blessures').length
 | |
|       const label = this.getLabelGravite();
 | |
| 
 | |
|       let rolled = await actor.jetRecuperationConstitution(this.system.soinscomplets.bonus, message);
 | |
| 
 | |
|       if (rolled.isETotal) {
 | |
|         message.content += ` -- une blessure ${label} s'infecte (temps de guérison augmenté de ${gravite} jours, perte de vie)`;
 | |
|         await actor.santeIncDec("vie", -1);
 | |
|         mergeObject(update, {
 | |
|           system: { fin: { indexDate: timestamp.addJours(gravite).indexDate } }
 | |
|         });
 | |
|       }
 | |
|       else {
 | |
|         if (!isMaladeEmpoisonne && rolled.isSuccess && this.peutRetrograder(graviteMoindre, moindres)) {
 | |
|           message.content += ` -- une blessure ${label} cicatrise`;
 | |
|           mergeObject(update, {
 | |
|             system: { gravite: graviteMoindre, fin: { indexDate: timestamp.addJours(graviteMoindre).indexDate } }
 | |
|           });
 | |
|         }
 | |
|         else {
 | |
|           message.content += ` -- une blessure ${label} reste stable`;
 | |
|         }
 | |
|       }
 | |
|       await this.update(update);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   peutRetrograder(graviteMoindre, moindres) {
 | |
|     return moindres < RdDItemBlessure.getDefinition(graviteMoindre).max
 | |
|   }
 | |
| 
 | |
|   async calculerFinPeriodeTemporel(debut) {
 | |
|     return await debut.nouveauJour().addJours(this.system.gravite);
 | |
|   }
 | |
| 
 | |
|   async onFinPeriode(oldTimestamp, newTimestamp) {
 | |
|     if (this.system.gravite <= 0) {
 | |
|       await super.onFinPeriode(oldTimestamp, newTimestamp)
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   getImgSoins(gravite, soins) {
 | |
|     let img = 'blessure'
 | |
|     if (gravite > 6) {
 | |
|       img = 'mort'
 | |
|     }
 | |
|     if (gravite <= 0) {
 | |
|       img = 'eraflure'
 | |
|     }
 | |
|     return `systems/foundryvtt-reve-de-dragon/icons/sante/${soins ? 'blessure-soins' : img}.webp`
 | |
|   }
 | |
| 
 | |
|   getLabelGravite() {
 | |
|     return RdDItemBlessure.getDefinition(this.system.gravite).label
 | |
|   }
 | |
| 
 | |
|   static getDefinition(gravite) {
 | |
|     return definitionsBlessures.sort(Misc.ascending(it => it.gravite))
 | |
|       .find(it => it.gravite >= gravite);
 | |
|   }
 | |
|   static maxBlessures(gravite) {
 | |
|     return RdDItemBlessure.getDefinition(gravite).max
 | |
|   }
 | |
| 
 | |
|   isContusion() {
 | |
|     return this.system.gravite <= 0
 | |
|   }
 | |
|   isLegere() {
 | |
|     return this.system.gravite > 0 && this.system.gravite <= 2
 | |
|   }
 | |
|   isGrave() {
 | |
|     return this.system.gravite > 2 && this.system.gravite <= 4
 | |
|   }
 | |
|   isCritique() {
 | |
|     return this.system.gravite > 4 && this.system.gravite <= 6
 | |
|   }
 | |
|   isMort() {
 | |
|     return this.system.gravite > 6
 | |
|   }
 | |
| 
 | |
|   getProprietes() {
 | |
|     return [
 | |
|       RdDItem.propertyIfDefined('Causée par', this.system.origine, this.system.origine),
 | |
|       `<b>Heure et Date</b>: ${new RdDTimestamp(this.system.temporel.debut).formatDateHeure()}`,
 | |
|       RdDItem.propertyIfDefined('Blessé', this.parent?.name, this.parent),
 | |
|       `<b>Localisation</b>: ${this.system.localisation}`,
 | |
|       `<b>Gravité</b>: ${RdDItemBlessure.getDefinition(this.system.gravite).label}`,
 | |
|       `<b>Difficulté des soins</b>: ${this.system.difficulte}`,
 | |
|       (this.system.soinscomplets.done ?
 | |
|         `<b>Bonus soins complets</b>: ${this.system.soinscomplets.bonus}` :
 | |
|         (this.system.premierssoins.done ?
 | |
|           `<b>Bonus premiers soins</b>: ${this.system.premierssoins.bonus}` :
 | |
|           `<b>Points de tâche</b>: ${this.system.premierssoins.tache}`
 | |
|         )
 | |
|       ),
 | |
|     ];
 | |
|   }
 | |
| }
 |