ChatMessage.create est async, il faut donc de préférence l'appeler avec un await. Des effets secondaires avaient lieu (ordre de messages, updates ultérieurs parfois pas pris en compte)
241 lines
8.5 KiB
JavaScript
241 lines
8.5 KiB
JavaScript
import { RdDItem } from "../item.js";
|
|
import { Misc } from "../misc.js";
|
|
import { RdDTimestamp } from "../time/rdd-timestamp.js";
|
|
import { ChatUtility } from "../chat-utility.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, endurance: "1d4", vie: 0, label: 'Contusion/éraflure', max: 100, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/eraflure.webp" },
|
|
{ type: "legere", gravite: 2, endurance: "1d6", vie: 0, label: 'Légère', max: 5, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/blessure.webp" },
|
|
{ type: "grave", gravite: 4, endurance: "2d6", vie: -2, label: 'Grave', max: 2, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/blessure.webp" },
|
|
{ type: "critique", gravite: 6, endurance: "-100", vie: -4, label: 'Critique', max: 1, icon: "systems/foundryvtt-reve-de-dragon/icons/sante/blessure.webp" },
|
|
{ type: "mort", gravite: 8, endurance: "-100", vie: 0, 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 = RdDItemBlessure.getLabelGravite(this.system.gravite)
|
|
}
|
|
|
|
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 foundry.utils.mergeObject(BASE_TACHE_SOIN_BLESSURE, tache, { inplace: false })
|
|
}
|
|
|
|
static async applyFullBlessure(actor, gravite) {
|
|
const definition = foundry.utils.duplicate(RdDItemBlessure.getDefinition(gravite))
|
|
|
|
if (definition.vie) {
|
|
await actor.santeIncDec("vie", definition.vie)
|
|
}
|
|
const lostEndurance = await RdDItemBlessure.rollLostEndurance(definition.endurance)
|
|
if (lostEndurance) {
|
|
await actor.santeIncDec("endurance", -Number(lostEndurance));
|
|
}
|
|
await this.createBlessure(actor, gravite)
|
|
|
|
await ChatMessage.create({
|
|
//TODO: hbs
|
|
content: `Blessure ${definition.label} appliquée à ${actor.name}<br>Perte d'endurance : ${lostEndurance} (${definition.endurance})<br>Perte de Vie : ${definition.vie}`,
|
|
whisper: ChatUtility.getOwners(actor)
|
|
});
|
|
actor.sheet?.render()
|
|
}
|
|
|
|
static async rollLostEndurance(formula) {
|
|
if (formula) {
|
|
const roll = new Roll(formula)
|
|
await roll.evaluate()
|
|
return roll.total
|
|
}
|
|
return 0
|
|
}
|
|
|
|
static async createBlessure(actor, gravite, options = { localisation: '', origine: '', render: true }) {
|
|
const blessure = RdDItemBlessure.prepareBlessure(gravite, options);
|
|
const blessures = await actor.createEmbeddedDocuments('Item', [blessure], options)
|
|
return blessures[0]
|
|
}
|
|
|
|
static prepareBlessure(gravite, options = { localisation: '', origine: '' }) {
|
|
const definition = RdDItemBlessure.getDefinition(gravite);
|
|
return {
|
|
name: definition.label,
|
|
type: 'blessure',
|
|
img: definition.icon,
|
|
system: {
|
|
gravite: gravite,
|
|
vie: definition.vie,
|
|
endurance: definition.endurance,
|
|
difficulte: -gravite,
|
|
localisation: options.localisation,
|
|
origine: options.origine
|
|
}
|
|
}
|
|
}
|
|
|
|
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,
|
|
'system.difficulte': Math.min(this.system.difficulte, tache.system.difficulte),
|
|
'system.points_de_tache_courant': Math.max(0, this.system.premierssoins.tache)
|
|
});
|
|
}
|
|
}
|
|
|
|
async setSoinsBlessure(systemUpdate = {}) {
|
|
systemUpdate = foundry.utils.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 = RdDItemBlessure.getLabelGravite(this.system.gravite)
|
|
|
|
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);
|
|
foundry.utils.mergeObject(update, {
|
|
system: { fin: { indexDate: timestamp.addJours(gravite).indexDate } }
|
|
});
|
|
}
|
|
else {
|
|
if (!isMaladeEmpoisonne && rolled.isSuccess && this.peutRetrograder(graviteMoindre, moindres)) {
|
|
message.content += ` -- une blessure ${label} cicatrise`;
|
|
foundry.utils.mergeObject(update, {
|
|
system: {
|
|
gravite: graviteMoindre,
|
|
temporel: { fin: { indexDate: timestamp.addJours(graviteMoindre).indexDate } }
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
message.content += ` -- une blessure ${label} reste stable`;
|
|
}
|
|
}
|
|
await this.update(update)
|
|
}
|
|
}
|
|
|
|
peutRetrograder(graviteMoindre, moindres) {
|
|
return moindres < RdDItemBlessure.maxBlessures(graviteMoindre)
|
|
}
|
|
|
|
async calculerFinPeriodeTemporel(debut) {
|
|
return 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`
|
|
}
|
|
|
|
static getLabelGravite(gravite) {
|
|
return definitionsBlessures.find(it => it.gravite >= gravite).label
|
|
}
|
|
|
|
static getDefinition(gravite) {
|
|
return definitionsBlessures.find(it => it.gravite >= gravite)
|
|
}
|
|
|
|
static maxBlessures(gravite) {
|
|
return definitionsBlessures.find(it => it.gravite >= 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
|
|
}
|
|
isBleeding() {
|
|
return this.system.gravite > 2 && !this.system.premierssoins.done
|
|
}
|
|
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>: ${this.system.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}`
|
|
)
|
|
),
|
|
];
|
|
}
|
|
}
|