Files
foundryvtt-reve-de-dragon/module/moral/apprecier.mjs

180 lines
5.8 KiB
JavaScript

import { ChatUtility } from "../chat-utility.js"
import { ITEM_TYPES } from "../constants.js"
import { SANS_COMPETENCE } from "../item/base-items.js"
import { Misc } from "../misc.js"
import { CARACS } from "../rdd-carac.js"
import { RdDUtility } from "../rdd-utility.js"
import { DIFF, ROLL_TYPE_COMP } from "../roll/roll-constants.mjs"
import RollDialog from "../roll/roll-dialog.mjs"
export const MORAL = {
MALHEUREUX: "malheureux",
NEUTRE: "neutre",
HEUREUX: "heureux",
TRESHEUREUX: "très heureux"
}
export const SITUATION_MORAL = {
[MORAL.MALHEUREUX]: "malheureuse",
[MORAL.NEUTRE]: "neutre",
[MORAL.HEUREUX]: "heureuse",
[MORAL.TRESHEUREUX]: "très heureuse",
}
export const APPRECIATION = {
CUISINE: {
bonmoment: "Cuisine", carac: CARACS.ODORATGOUT, competence: "Cuisine",
moral: MORAL.HEUREUX, jetComp: false, jetQualite: false, compMinimum: true
},
MUSIQUE: {
bonmoment: "Musique", carac: CARACS.OUIE, competence: "Musique",
moral: MORAL.HEUREUX, jetComp: false, jetQualite: false, compMinimum: true
},
CHANT: {
bonmoment: "Musique", carac: CARACS.OUIE, competence: "Chant",
moral: MORAL.HEUREUX, jetComp: false, jetQualite: false, compMinimum: true
},
DANSE: {
bonmoment: "Spectacle", carac: CARACS.EMPATHIE, competence: "Danse",
moral: MORAL.HEUREUX, jetComp: false, jetQualite: false, compMinimum: true
},
JEU: {
bonmoment: "Jeu", carac: CARACS.EMPATHIE, competence: "Jeu",
moral: MORAL.HEUREUX, jetComp: false, jetQualite: false, compMinimum: true
},
OEUVRE: {
bonmoment: "Spectacle", carac: CARACS.EMPATHIE, competence: "",
moral: MORAL.HEUREUX, jetComp: false, jetQualite: false, compMinimum: true
},
SERVICE: {
bonmoment: "Confort", carac: CARACS.EMPATHIE, competence: "",
moral: MORAL.HEUREUX, jetComp: false, jetQualite: false, compMinimum: false
},
}
export class Apprecier {
static isAppreciable(item) {
switch (item.type) {
case ITEM_TYPES.nourritureboisson:
case ITEM_TYPES.service:
return item.system.qualite > 0
case ITEM_TYPES.chant:
case ITEM_TYPES.musique:
case ITEM_TYPES.danse:
case ITEM_TYPES.oeuvre:
case ITEM_TYPES.jeu:
return true
}
return false
}
static qualite(qualite, roll = undefined, comp = undefined) {
if (roll && comp) {
return roll.rolled.isSuccess ? qualite : Math.min(qualite, comp.system.niveau)
}
return
}
static getAppreciation(qualite, appreciable, roll = undefined, comp = undefined) {
return {
qualite: (roll?.rolled.ptQualite ?? 0) + Apprecier.qualite(qualite, roll, comp),
appreciation: foundry.utils.duplicate(appreciable.system.appreciation),
messages: []
}
}
static onClickApprecier(roll) {
const appreciation = roll.result.appreciation
if (appreciation.moral == "") {
return
}
RdDUtility.doWithSelectedActor(
actor => new Apprecier(actor, appreciation, roll.result.qualite).apprecier(),
actor => actor.isPersonnage())
}
constructor(actor, appreciation, qualite) {
this.actor = actor
this.appreciation = foundry.utils.duplicate(appreciation)
this.appreciation.situation = SITUATION_MORAL[appreciation.moral]
this.qualite = qualite
this.raisons = []
}
apprecier(callbacks = []) {
if (this.qualite <= 0) {
this.raisons.push(`la qualité ${this.qualite} est insuffisante.`)
}
if (this.qualite <= this.actor.getMoralTotal()) {
this.raisons.push(`la qualité de ${this.qualite} est inférieure au moral de ${this.actor.getMoralTotal()}.`)
}
const competence = this.getCompetenceAppreciation()
if (this.appreciation.compMinimum && this.qualite <= competence.system.niveau && competence.system.niveau > 0 && competence.id) {
this.raisons.push(`la qualité ${this.qualite} est insuffisante pour le niveau ${competence.system.niveau} en ${competence.name}`)
}
const bonmoment = this.appreciation.bonmoment
if (!["", undefined].includes(bonmoment) && this.actor.system.compteurs.bonmoments.includes(bonmoment)) {
this.raisons.push(`du moral a déjà été gagné pour cause de ${bonmoment}`)
}
if (this.appreciation.carac != "") {
this.rollAppreciation(callbacks)
}
else {
this.rollMoral()
}
}
getCompetenceAppreciation() {
return [SANS_COMPETENCE.name, ""].includes(this.appreciation.competence) ? SANS_COMPETENCE : this.actor.getCompetence(this.appreciation.competence)
}
rollAppreciation(rollCallbacks = []) {
const competence = (this.appreciation.jetComp && this.appreciation.competence) ? this.appreciation.competence : ""
const rollData = {
ids: { actorId: this.actor.id },
type: { allowed: [ROLL_TYPE_COMP], current: ROLL_TYPE_COMP, appreciation: true },
selected: {
carac: { key: this.appreciation.carac, forced: true },
comp: { key: competence, forced: true },
diff: { type: DIFF.IMPOSEE },
apprecier: {
appreciation: this.appreciation,
qualite: this.qualite,
raisons: this.raisons
}
}
}
RollDialog.create(rollData, {
callbacks: [
async r => await this.onRollAppreciation(r),
...rollCallbacks
],
onRollDone: RollDialog.onRollDoneClose
})
}
async onRollAppreciation(roll) {
if (roll.rolled.isSuccess) {
await this.rollMoral()
}
else {
if (this.appreciation.moral == MORAL.TRESHEUREUX) {
await this.rollMoral(MORAL.HEUREUX)
}
}
}
async rollMoral(moral = undefined) {
if (this.raisons.length > 0) {
await ChatMessage.create({
whisper: ChatUtility.getOwners(this.actor),
content: 'Pas de jet de moral:' + Misc.concat(this.raisons.map(r => `<br> - ${r}`))
})
return
}
moral = moral ?? this.appreciation.moral
await this.actor.jetDeMoral(moral, this.appreciation.bonmoment)
}
}