230 lines
8.0 KiB
JavaScript
230 lines
8.0 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, 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 foundry.utils.mergeObject(BASE_TACHE_SOIN_BLESSURE, tache, { inplace: false })
|
|
}
|
|
|
|
static async applyFullBlessure(actor, gravite) {
|
|
const definition = RdDItemBlessure.getDefinition(gravite)
|
|
|
|
let lostEndurance = 0
|
|
let lostVie = 0
|
|
if (definition.endurance) {
|
|
lostEndurance = await new Roll(definition.endurance).roll().total;
|
|
actor.santeIncDec("endurance", -Number(lostEndurance));
|
|
}
|
|
if (definition.vie) {
|
|
lostVie = definition.vie
|
|
actor.santeIncDec("vie", definition.vie)
|
|
}
|
|
|
|
await this.createBlessure(actor, gravite)
|
|
|
|
ChatMessage.create({
|
|
content: `Blessure ${definition.label} appliquée à ${actor.name}`+
|
|
`<br>Perte d'endurance : ${lostEndurance}`+
|
|
`<br>Perte de Vie : ${lostVie}`,
|
|
whisper: ChatUtility.getWhisperRecipientsAndGMs(actor.name)
|
|
});
|
|
|
|
}
|
|
|
|
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 = 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 = 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);
|
|
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.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}`
|
|
)
|
|
),
|
|
];
|
|
}
|
|
}
|