diff --git a/changelog.md b/changelog.md index 3adce903..7bb4e19d 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,10 @@ # 13.0 ## 13.0.14 - Le familier d'Illysis +- Amélioration des entités: + - l'attaquant ne sait plus que c'est une entité de cauchemar (surprise!) + - l'encaissement indique une blessure dans le tchat... même si ce n'est que de l'endurance + - les blurettes suivent les règles des entités de cauchemar (p322) - Nouvelle fenêtre de jets de dés - Attaque/défense des créatures diff --git a/module/actor/base-actor-reve.js b/module/actor/base-actor-reve.js index 9193dd5d..667253a0 100644 --- a/module/actor/base-actor-reve.js +++ b/module/actor/base-actor-reve.js @@ -1,4 +1,4 @@ -import { ENTITE_INCARNE, renderTemplate, SHOW_DICE, SYSTEM_RDD } from "../constants.js"; +import { renderTemplate, SHOW_DICE, SYSTEM_RDD } from "../constants.js"; import { Grammar } from "../grammar.js"; import { Misc } from "../misc.js"; import { RdDResolutionTable } from "../rdd-resolution-table.js"; @@ -670,7 +670,7 @@ export class RdDBaseActorReve extends RdDBaseActor { async accorder(entite, when = 'avant-encaissement') { if (when != game.settings.get(SYSTEM_RDD, "accorder-entite-cauchemar") || entite == undefined - || !entite.isEntite([ENTITE_INCARNE]) + || !entite.isEntiteIncarnee() || entite.isEntiteAccordee(this)) { return true } diff --git a/module/actor/base-actor.js b/module/actor/base-actor.js index a1a9b6cb..8c0c9b2a 100644 --- a/module/actor/base-actor.js +++ b/module/actor/base-actor.js @@ -215,9 +215,11 @@ export class RdDBaseActor extends Actor { return game.users.players.find(player => player.active && player.character?.id == this.id); } - isCreatureEntite() { return this.isCreature() || this.isEntite() } + isCreatureOuEntite() { return this.isCreature() || this.isEntite() } isCreature() { return false } - isEntite(typeentite = []) { return false } + isEntite() { return false } + isEntiteIncarnee() { return false } + isEntiteNonIncarnee() { return false } isHautRevant() { return false } isVehicule() { return false } isPersonnage() { return false } diff --git a/module/actor/entite-sheet.js b/module/actor/entite-sheet.js index 70303215..fb6bb820 100644 --- a/module/actor/entite-sheet.js +++ b/module/actor/entite-sheet.js @@ -43,7 +43,7 @@ export class RdDActorEntiteSheet extends RdDBaseActorReveSheet { this.html.find('.resonance-add').click(async event => await DialogSelect.select({ label: "Choisir un acteur à accorder", - list: game.actors.filter(it => it.isPersonnage() && it.prototypeToken.actorLink) + list: game.actors.filter(it => true) }, it => this.resonanceAdd(it.id)) ) diff --git a/module/actor/entite.js b/module/actor/entite.js index eeacd5e4..17eef287 100644 --- a/module/actor/entite.js +++ b/module/actor/entite.js @@ -1,5 +1,6 @@ -import { ENTITE_INCARNE, ENTITE_NONINCARNE } from "../constants.js"; +import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE } from "../constants.js"; import { ITEM_TYPES } from "../constants.js"; +import { RdDItemBlessure } from "../item/blessure.js"; import { Misc } from "../misc.js"; import { RdDCarac } from "../rdd-carac.js"; import { RdDEncaisser } from "../rdd-roll-encaisser.js"; @@ -16,11 +17,10 @@ export class RdDEntite extends RdDBaseActorReve { return item.type == ITEM_TYPES.competencecreature } - isEntite(typeentite = []) { - return (typeentite.length == 0 || typeentite.includes(this.system.definition.typeentite)); - } - - isNonIncarnee() { return this.isEntite([ENTITE_NONINCARNE]) } + isEntite() { return true } + isEntiteNonIncarnee() { return this.system.definition.typeentite == ENTITE_NONINCARNE } + isEntiteIncarnee() { return [ENTITE_INCARNE, ENTITE_BLURETTE].includes(this.system.definition.typeentite) } + isEntiteBlurette() { return this.system.definition.typeentite !== ENTITE_BLURETTE } getReveActuel() { return Misc.toInt(this.system.carac.reve?.value) @@ -49,20 +49,20 @@ export class RdDEntite extends RdDBaseActorReve { } async remiseANeuf() { - await this.removeEffects(e => true); - if (!this.isNonIncarnee()) { + if (!this.isEntiteNonIncarnee()) { await this.update({ 'system.sante.endurance.value': this.system.sante.endurance.max }); } + await this.removeEffects(e => true) } isDead() { - return this.isNonIncarnee() ? false : this.system.sante.endurance.value <= 0 + return this.isEntiteNonIncarnee() ? false : this.system.sante.endurance.value <= 0 } async santeIncDec(name, inc, isCritique = false) { - if (name == 'endurance' && !this.isNonIncarnee()) { + if (name == 'endurance' && !this.isEntiteNonIncarnee()) { const oldValue = this.system.sante.endurance.value; const endurance = Math.max(0, Math.min(oldValue + inc, @@ -78,7 +78,7 @@ export class RdDEntite extends RdDBaseActorReve { } async encaisser() { - if (this.isNonIncarnee()) { + if (this.isEntiteNonIncarnee()) { return } await RdDEncaisser.encaisser(this) @@ -89,15 +89,19 @@ export class RdDEntite extends RdDBaseActorReve { } async onAppliquerJetEncaissement(encaissement, attackerToken) { + if (this.isEntiteNonIncarnee()) { + return + } const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance); foundry.utils.mergeObject(encaissement, { resteEndurance: perteEndurance.newValue, - endurance: perteEndurance.perte - }); + endurance: perteEndurance.perte, + blessure: RdDItemBlessure.prepareBlessure(encaissement.gravite, encaissement.dmg?.loc.label ?? '', attackerToken) + }) } isEntiteAccordee(attacker) { - if (this.isEntite([ENTITE_INCARNE])) { + if (this.isEntiteIncarnee()) { let resonnance = this.system.sante.resonnance return (resonnance.actors.find(it => it == attacker.id)) } @@ -106,7 +110,7 @@ export class RdDEntite extends RdDBaseActorReve { /* -------------------------------------------- */ async setEntiteReveAccordee(actor) { - if (this.isEntite([ENTITE_INCARNE])) { + if (this.isEntiteIncarnee()) { if (this.system.sante.resonnance.actors.find(it => it == actor.id)) { // déjà accordé return diff --git a/module/actor/export-scriptarium/mapping.js b/module/actor/export-scriptarium/mapping.js index b16ca758..aca7d6f5 100644 --- a/module/actor/export-scriptarium/mapping.js +++ b/module/actor/export-scriptarium/mapping.js @@ -2,7 +2,7 @@ import { Grammar } from "../../grammar.js" import { EMPOIGNADE, RdDItemArme } from "../../item/arme.js" import { RdDItemCompetence } from "../../item-competence.js" import { RdDItemSort } from "../../item-sort.js" -import { ITEM_TYPES } from "../../constants.js" +import { ITEM_TYPES, RDD_CONFIG } from "../../constants.js" import { Misc } from "../../misc.js" import { RdDTimestamp } from "../../time/rdd-timestamp.js" import { RdDBonus } from "../../rdd-bonus.js" @@ -175,8 +175,8 @@ export class Mapping { const dmgArme = RdDItemArme.dommagesReels(arme, maniement) const dommages = Misc.toSignedString(dmgArme + RdDBonus.bonusDmg(actor, maniement, dmgArme)) switch (arme.system.mortalite) { - case 'non-mortel': return `(${dommages})` - case EMPOIGNADE: return '-' + case RDD_CONFIG.encaissement.nonmortel: return `(${dommages})` + case RDD_CONFIG.encaissement.empoignade: return '-' } return dommages } diff --git a/module/constants.js b/module/constants.js index 4dc65e74..37e45b6f 100644 --- a/module/constants.js +++ b/module/constants.js @@ -13,44 +13,44 @@ export const renderTemplate = foundry.applications.handlebars.renderTemplate export const RDD_CONFIG = { niveauEthylisme: [ - { value: "1", label: "Aucun" }, - { value: "0", label: "Eméché (0)" }, - { value: "-1", label: "Gris (-1)" }, - { value: "-2", label: "Pinté (-2)" }, - { value: "-3", label: "Pas Frais (-3)" }, - { value: "-4", label: "Ivre (-4)" }, - { value: "-5", label: "Bu (-5)" }, - { value: "-6", label: "Complètement fait (-6)" }, - { value: "-7", label: "Ivre mort (-7)" } + { value: '1', label: 'Aucun' }, + { value: '0', label: 'Eméché (0)' }, + { value: '-1', label: 'Gris (-1)' }, + { value: '-2', label: 'Pinté (-2)' }, + { value: '-3', label: 'Pas Frais (-3)' }, + { value: '-4', label: 'Ivre (-4)' }, + { value: '-5', label: 'Bu (-5)' }, + { value: '-6', label: 'Complètement fait (-6)' }, + { value: '-7', label: 'Ivre mort (-7)' } ], categorieEntite: { - "cauchemar": "Cauchemar", - "reve": "Rêve" + 'cauchemar': 'Cauchemar', + 'reve': 'Rêve' }, typeEntite: { - "incarne": "Incarnée", - "nonincarne": "Non Incarnée", - "blurette": "Blurette" + [ENTITE_INCARNE]: 'Incarnée', + [ENTITE_NONINCARNE]: 'Non Incarnée', + [ENTITE_BLURETTE]: 'Blurette' }, heuresRdD: [ - { value: "vaisseau", label: "Vaisseau", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd01.webp" }, - { value: "sirene", label: "Sirène", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd02.webp" }, - { value: "faucon", label: "Faucon", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd03.webp" }, - { value: "couronne", label: "Couronne", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd04.webp" }, - { value: "dragon", label: "Dragon", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd05.webp" }, - { value: "epees", label: "Epées", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd06.webp" }, - { value: "lyre", label: "Lyre", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd07.webp" }, - { value: "serpent", label: "Serpent", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd08.webp" }, - { value: "poissonacrobate", label: "Poisson Acrobate", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd09.webp" }, - { value: "araignee", label: "Araignée", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd10.webp" }, - { value: "roseau", label: "Roseau", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd11.webp" }, - { value: "chateaudormant", label: "Chateau Dormant", img: "systems/foundryvtt-reve-de-dragon/icons/heures/hd12.webp" } + { value: 'vaisseau', label: 'Vaisseau', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd01.webp' }, + { value: 'sirene', label: 'Sirène', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd02.webp' }, + { value: 'faucon', label: 'Faucon', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd03.webp' }, + { value: 'couronne', label: 'Couronne', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd04.webp' }, + { value: 'dragon', label: 'Dragon', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd05.webp' }, + { value: 'epees', label: 'Epées', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd06.webp' }, + { value: 'lyre', label: 'Lyre', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd07.webp' }, + { value: 'serpent', label: 'Serpent', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd08.webp' }, + { value: 'poissonacrobate', label: 'Poisson Acrobate', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd09.webp' }, + { value: 'araignee', label: 'Araignée', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd10.webp' }, + { value: 'roseau', label: 'Roseau', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd11.webp' }, + { value: 'chateaudormant', label: 'Chateau Dormant', img: 'systems/foundryvtt-reve-de-dragon/icons/heures/hd12.webp' } ], raretes: [ - { value: "Commune", label: "Commune" }, - { value: "Frequente", label: "Fréquente" }, - { value: "Rare", label: "Rare" }, - { value: "Rarissime", label: "Rarissime" } + { value: 'Commune', label: 'Commune' }, + { value: 'Frequente', label: 'Fréquente' }, + { value: 'Rare', label: 'Rare' }, + { value: 'Rarissime', label: 'Rarissime' } ], particuliere: { force: { key: 'force', descr: 'en force', img: 'systems/foundryvtt-reve-de-dragon/assets/ui/part-force.svg' }, @@ -62,10 +62,15 @@ export const RDD_CONFIG = { demiReve: 'systems/foundryvtt-reve-de-dragon/assets/actions/sort.svg', empoignade: 'systems/foundryvtt-reve-de-dragon/icons/empoignade.webp', forceWeak: 'systems/foundryvtt-reve-de-dragon/assets/actions/weak.svg', + }, + encaissement: { + mortel: 'mortel', + nonmortel: 'non-mortel', + entiteincarnee: 'entiteincarnee', + empoignade: 'empoignade' } } - export const ACTOR_TYPES = { personnage: 'personnage', creature: 'creature', diff --git a/module/item.js b/module/item.js index 44829cd2..a59e78ca 100644 --- a/module/item.js +++ b/module/item.js @@ -1,4 +1,4 @@ -import { ITEM_TYPES, renderTemplate } from "./constants.js"; +import { ITEM_TYPES, RDD_CONFIG, renderTemplate } from "./constants.js"; import { BASE_CORPS_A_CORPS, BASE_ESQUIVE, CATEGORIES_COMPETENCES, CATEGORIES_COMPETENCES_CREATURES } from "./item/base-items.js"; import { ITEM_ACTIONS, DEFAULT_ACTIONS, COMMON_ACTIONS } from "./item/item-actions.js"; @@ -629,7 +629,7 @@ export class RdDItem extends Item { _armeChatData() { return [ `Compétence: ${this.system.competence}`, - `Dommages: ${this.system.dommages} ${this.system.mortalite == 'non-mortel' ? '(Non mortel)' : ''}`, + `Dommages: ${this.system.dommages} ${this.system.mortalite == RDD_CONFIG.encaissement.nonmortel ? '(Non mortel)' : ''}`, `Force minimum: ${this.system.force}`, `Resistance: ${this.system.resistance}`, ...this._inventaireTemplateChatData() diff --git a/module/item/arme.js b/module/item/arme.js index b775a1b2..bd29ead1 100644 --- a/module/item/arme.js +++ b/module/item/arme.js @@ -1,4 +1,4 @@ -import { ITEM_TYPES } from "../constants.js"; +import { ITEM_TYPES, RDD_CONFIG } from "../constants.js"; import { RdDItem } from "../item.js"; import { BASE_CORPS_A_CORPS } from "./base-items.js"; import { Grammar } from "../grammar.js"; @@ -30,7 +30,7 @@ export const ATTAQUE_TYPE = { export const CORPS_A_CORPS = 'Corps à corps' export const PUGILAT = 'pugilat' -export const EMPOIGNADE = 'empoignade' +export const EMPOIGNADE = RDD_CONFIG.encaissement.empoignade /* -------------------------------------------- */ export class RdDItemArme extends RdDItem { @@ -259,10 +259,10 @@ export class RdDItemArme extends RdDItem { } static empoignade(actor) { - return RdDItemArme.$corpsACorps(actor, 'Empoignade', EMPOIGNADE) + return RdDItemArme.$corpsACorps(actor, 'Empoignade', RDD_CONFIG.encaissement.empoignade) } - static $corpsACorps(actor, name, cac, system) { + static $corpsACorps(actor, name, cac) { const competence = actor?.getCompetenceCorpsACorps() ?? BASE_CORPS_A_CORPS const melee = actor ? actor.system.carac['melee'].value : 0 return new RdDItemArme({ @@ -277,10 +277,10 @@ export class RdDItemArme extends RdDItem { force: 0, dommages: "0", dommagesReels: 0, - mortalite: cac == EMPOIGNADE ? EMPOIGNADE : 'non-mortel', + mortalite: cac == RDD_CONFIG.encaissement.empoignade ? RDD_CONFIG.encaissement.empoignade : RDD_CONFIG.encaissement.nonmortel, competence: CORPS_A_CORPS, resistance: 1, - baseInit: cac == EMPOIGNADE ? 3 : 4, + baseInit: cac == RDD_CONFIG.encaissement.empoignade ? 3 : 4, cac: cac, deuxmains: true, categorie_parade: 'sans-armes' diff --git a/module/item/blessure.js b/module/item/blessure.js index ac282db3..0bdb9b37 100644 --- a/module/item/blessure.js +++ b/module/item/blessure.js @@ -71,21 +71,25 @@ export class RdDItemBlessure extends RdDItem { return 0 } - static async createBlessure(actor, gravite, localisation = '', attackerToken) { - const definition = RdDItemBlessure.getDefinition(gravite) - const blessure = { + static async createBlessure(actor, gravite, localisation = '', attackerToken = undefined) { + const blessure = RdDItemBlessure.prepareBlessure(gravite, localisation, attackerToken); + const blessures = await actor.createEmbeddedDocuments('Item', [blessure]) + return blessures[0] + } + + static prepareBlessure(gravite, localisation, attackerToken) { + const definition = RdDItemBlessure.getDefinition(gravite); + return { name: definition.label, type: 'blessure', img: definition.icon, system: { gravite: gravite, - difficulte: - gravite, + difficulte: -gravite, localisation: localisation, origine: attackerToken?.name ?? "" } } - const blessures = await actor.createEmbeddedDocuments('Item', [blessure]) - return blessures[0] } static async createTacheSoinBlessure(actor, gravite) { diff --git a/module/rdd-bonus.js b/module/rdd-bonus.js index 2df7f67e..42d0f812 100644 --- a/module/rdd-bonus.js +++ b/module/rdd-bonus.js @@ -1,3 +1,4 @@ +import { RDD_CONFIG } from "./constants.js"; import { RdDItemArme } from "./item/arme.js"; import { RdDPossession } from "./rdd-possession.js"; import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; @@ -35,7 +36,7 @@ export class RdDBonus { } /* -------------------------------------------- */ - static dmg(rollData, actor, isEntiteIncarnee = false) { + static dmg(rollData, actor) { const diff = rollData.diffLibre; const dmgArme = RdDBonus.dmgArme(rollData.arme, rollData.arme?.system.dommagesReels) const forceRequise = rollData.arme ? RdDItemArme.valeurMain(rollData.arme.system.force ?? 0, RdDItemArme.getMainAttaque(rollData.competence)) : 0 @@ -48,12 +49,12 @@ export class RdDBonus { dmgTactique: RdDBonus.dmgBonus(rollData.tactique), dmgParticuliere: RdDBonus._dmgParticuliere(rollData), dmgSurprise: RdDBonus.dmgBonus(rollData.ajustements?.attaqueDefenseurSurpris?.used), - mortalite: RdDBonus._calculMortalite(rollData, isEntiteIncarnee), + mortalite: RdDBonus.mortalite(rollData.dmg?.mortalite, rollData.arme?.system.mortalite), dmgActor: RdDBonus.bonusDmg(actor, rollData.selectedCarac?.label.toLowerCase(), dmgArme), dmgForceInsuffisante: Math.min(0, actor.getForce() - forceRequise) } dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere + dmg.dmgForceInsuffisante - return dmg; + return dmg } static dmgRollV2(rollData, attaque) { @@ -68,7 +69,7 @@ export class RdDBonus { dmgTactique: attaque.tactique?.dmg ?? 0, dmgParticuliere: RdDBonus._dmgParticuliere(rollData), dmgSurprise: rollData.opponent?.surprise?.dmg ?? 0, - mortalite: RdDBonus.mortalite(attaque.dmg?.mortalite, arme?.system.mortalite, rollData.opponent?.actor?.isEntite()), + mortalite: RdDBonus.mortalite(attaque.dmg?.mortalite, arme?.system.mortalite), dmgActor: RdDBonus.bonusDmg(actor, attaque.carac.key, dmgArme, attaque.forceRequise), dmgForceInsuffisante: Math.min(0, actor.getForce() - (attaque.forceRequise ?? 0)), dmgDiffLibre: ReglesOptionnelles.isUsing('degat-ajout-malus-libre') ? Math.abs(attaque.diff ?? 0) : 0 @@ -93,15 +94,8 @@ export class RdDBonus { } /* -------------------------------------------- */ - static _calculMortalite(rollData, isEntiteIncarnee) { - return RdDBonus.mortalite(rollData.dmg?.mortalite, rollData.arme?.system.mortalite, isEntiteIncarnee) - } - - static mortalite(mortaliteSelect, mortaliteArme, isEntiteIncarnee) { - return isEntiteIncarnee ? "entiteincarnee" - : mortaliteSelect - ?? mortaliteArme - ?? "mortel"; + static mortalite(mortaliteSelect, mortaliteArme) { + return mortaliteSelect ?? mortaliteArme ?? RDD_CONFIG.encaissement.mortel } /* -------------------------------------------- */ diff --git a/module/rdd-combat.js b/module/rdd-combat.js index 58f01421..72d10848 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -1,5 +1,5 @@ import { ChatUtility } from "./chat-utility.js"; -import { ENTITE_BLURETTE, HIDE_DICE, renderTemplate, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; +import { HIDE_DICE, renderTemplate, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js"; import { Grammar } from "./grammar.js"; import { Misc } from "./misc.js"; import { RdDBonus } from "./rdd-bonus.js"; @@ -15,7 +15,7 @@ import { RdDItemCompetence } from "./item-competence.js"; import { MAP_PHASE, RdDInitiative } from "./initiative.mjs"; import RollDialog from "./roll/roll-dialog.mjs"; import { PART_DEFENSE } from "./roll/roll-part-defense.mjs"; -import { DIFF, ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll/roll-constants.mjs"; +import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll/roll-constants.mjs"; import { OptionsAvancees, ROLL_DIALOG_V2 } from "./settings/options-avancees.js"; import { MappingCreatureArme } from "./item/mapping-creature-arme.mjs"; import { RollBasicParts } from "./roll/roll-basic-parts.mjs"; @@ -601,7 +601,7 @@ export class RdDCombat { /* -------------------------------------------- */ async proposerAjustementTirLancer(rollData) { if (['tir', 'lancer'].includes(rollData.competence.system.categorie)) { - if (this.defender.isEntite([ENTITE_BLURETTE])) { + if (this.defender.isEntiteBlurette()) { ChatMessage.create({ content: `La cible est une blurette, l'arme à distance sera perdue dans le blurêve`, whisper: ChatUtility.getGMs() @@ -797,7 +797,7 @@ export class RdDCombat { essais: {} }; - if (this.attacker.isCreatureEntite()) { + if (this.attacker.isCreatureOuEntite()) { MappingCreatureArme.setRollDataCreature(rollData); } else if (arme) { @@ -866,7 +866,7 @@ export class RdDCombat { async _onAttaqueNormale(attackerRoll) { console.log("RdDCombat.onAttaqueNormale >>>", attackerRoll); - attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker, this.defender.isEntite()); + attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker); let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} } attackerRoll.show = { cible: this.defender?.getAlias() ?? 'la cible', @@ -1104,7 +1104,7 @@ export class RdDCombat { show: {} }; - if (this.defender.isCreatureEntite()) { + if (this.defender.isCreatureOuEntite()) { MappingCreatureArme.setRollDataCreature(defenderRoll); } @@ -1231,7 +1231,7 @@ export class RdDCombat { show: {} }; - if (this.defender.isCreatureEntite()) { + if (this.defender.isCreatureOuEntite()) { MappingCreatureArme.setRollDataCreature(rollData); } return rollData; diff --git a/module/rdd-empoignade.js b/module/rdd-empoignade.js index 475c6147..dbdf0208 100644 --- a/module/rdd-empoignade.js +++ b/module/rdd-empoignade.js @@ -184,7 +184,7 @@ export class RdDEmpoignade { selectedCarac: attacker.system.carac.melee, malusTaille: RdDEmpoignade.getMalusTaille(empoignade, attacker, defender) } - if (attacker.isCreatureEntite()) { + if (attacker.isCreatureOuEntite()) { MappingCreatureArme.setRollDataCreature(rollData) } if (empoignade.system.pointsemp >= 2) { diff --git a/module/rdd-possession.js b/module/rdd-possession.js index 1588a917..bf0b5c85 100644 --- a/module/rdd-possession.js +++ b/module/rdd-possession.js @@ -95,7 +95,7 @@ export class RdDPossession { static selectCompetenceDraconicOuPossession(rollData, rollingActor) { rollData.competence = rollingActor.getDraconicOuPossession(); - if (rollingActor.isCreatureEntite()) { + if (rollingActor.isCreatureOuEntite()) { const carac = rollingActor.system.carac rollData.carac = carac rollData.competence.system.defaut_carac = 'reve' diff --git a/module/rdd-roll-encaisser.js b/module/rdd-roll-encaisser.js index 058c93ff..813b1266 100644 --- a/module/rdd-roll-encaisser.js +++ b/module/rdd-roll-encaisser.js @@ -1,4 +1,4 @@ -import { ENTITE_BLURETTE, ENTITE_INCARNE, renderTemplate } from "./constants.js"; +import { ENTITE_NONINCARNE, RDD_CONFIG, renderTemplate } from "./constants.js"; import { RdDUtility } from "./rdd-utility.js"; /** @@ -16,34 +16,29 @@ export class RdDEncaisser extends Dialog { /* -------------------------------------------- */ constructor(html, actor) { - let dialogConf = { + if (actor.isEntiteNonIncarnee([ENTITE_NONINCARNE])) { + throw `${actor.name} est une entité non incarnée et ne peut pas subnir de dommages` + } + + const dialogConf = { title: "Jet d'Encaissement", content: html, - } - - if (!actor.isEntite()) { - dialogConf.default = "mortel"; - dialogConf.buttons = { - "mortel": { label: "Mortel", callback: html => this.performEncaisser("mortel") }, - "non-mortel": { label: "Non-mortel", callback: html => this.performEncaisser("non-mortel") }, - "sonne": { label: "Sonné", callback: html => this.actor.setSonne() }, - }; - } - else if (actor.isEntite([ENTITE_BLURETTE, ENTITE_INCARNE])) { - dialogConf.default = "entiteincarnee" - dialogConf.buttons = { - "entiteincarnee": { label: "Entité incarnée", callback: html => this.performEncaisser("entiteincarnee") } + default: RDD_CONFIG.encaissement.mortel, + buttons: { + [RDD_CONFIG.encaissement.mortel]: { label: "Mortel", callback: html => this.performEncaisser(RDD_CONFIG.encaissement.mortel) }, } } - - let dialogOptions = { - classes: ["rdd-roll-dialog"], - width: 320, - height: 'fit-content' + if (!actor.isEntite()) { + dialogConf.buttons[RDD_CONFIG.encaissement.nonmortel] = { label: "Non-mortel", callback: html => this.performEncaisser(RDD_CONFIG.encaissement.nonmortel) } + dialogConf.buttons["sonne"] = { label: "Sonné", callback: html => this.actor.setSonne() } } // Select proper roll dialog template and stuff - super(dialogConf, dialogOptions); + super(dialogConf, { + classes: ["rdd-roll-dialog"], + width: 320, + height: 'fit-content' + }); this.actor = actor; this.modifier = 0; diff --git a/module/rdd-roll.js b/module/rdd-roll.js index 3c369ecd..3c2bd93b 100644 --- a/module/rdd-roll.js +++ b/module/rdd-roll.js @@ -8,7 +8,7 @@ import { RdDCarac } from "./rdd-carac.js"; import { RdDResolutionTable } from "./rdd-resolution-table.js"; import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; import { Grammar } from "./grammar.js"; -import { ACTOR_TYPES, renderTemplate } from "./constants.js"; +import { ACTOR_TYPES, RDD_CONFIG, renderTemplate } from "./constants.js"; import { EMPOIGNADE } from "./item/arme.js"; /** @@ -206,7 +206,7 @@ export class RdDRoll extends Dialog { this.updateRollResult(html); }); this.html.find("input.check-mortalite").change((event) => { - this.rollData.dmg.mortalite = event.currentTarget.checked ? "non-mortel" : "mortel"; + this.rollData.dmg.mortalite = event.currentTarget.checked ? RDD_CONFIG.encaissement.nonmortel : RDD_CONFIG.encaissement.mortel; this.updateRollResult(html); }); this.html.find('.cuisine-proportions').change((event) => { @@ -333,7 +333,7 @@ export class RdDRoll extends Dialog { // Mise à jour valeurs this.html.find(".dialog-roll-title").text(this._getTitle(rollData)); - this.html.find("input.check-mortalite").prop('checked', rollData.dmg.mortalite == 'non-mortel'); + this.html.find("input.check-mortalite").prop('checked', rollData.dmg.mortalite == RDD_CONFIG.encaissement.nonmortel); this.html.find("label.dmg-arme-actor").text(rollData.dmg.mortalite == EMPOIGNADE ? EMPOIGNADE : Misc.toSignedString(rollData.dmg.total)); this.html.find("label.arme-mortalite").text(rollData.dmg.mortalite); this.html.find("div.placeholder-ajustements").empty().append(adjustements); diff --git a/module/rdd-utility.js b/module/rdd-utility.js index b37b79c5..4ffd88ff 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -75,30 +75,27 @@ const fatigueLineMalus = [0, -1, -2, -3, -4, -5, -6, -7]; /* -------------------------------------------- */ const nomEthylisme = ["Emeché", "Gris", "Pinté", "Pas frais", "Ivre", "Bu", "Complètement fait", "Ivre mort"]; -/* -------------------------------------------- */ -const definitionsEncaissement = { - "mortel": [ - { minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1 }, - { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0 }, - { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 2 }, - { minimum: 16, maximum: 19, endurance: "2d6", vie: "2", gravite: 4 }, - { minimum: 20, maximum: undefined, endurance: "100", vie: "4 + @over20", gravite: 6 }, - ], - "non-mortel": [ - { minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1 }, - { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0 }, - { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 0 }, - { minimum: 16, maximum: 19, endurance: "2d6", vie: "0", gravite: 2 }, - { minimum: 20, maximum: undefined, endurance: "100", vie: "0", gravite: 2 }, - ], - "entiteincarnee": [ - { minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1 }, - { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0 }, - { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 0 }, - { minimum: 16, maximum: 19, endurance: "2d6", vie: "0", gravite: 0 }, - { minimum: 20, maximum: undefined, endurance: "3d6 + @over20", vie: "0", gravite: 0 }, - ] -}; +const TABLE_ENCAISSEMENT_MORTEL = [ + { minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1 }, + { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0 }, + { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 2 }, + { minimum: 16, maximum: 19, endurance: "2d6", vie: "2", gravite: 4 }, + { minimum: 20, maximum: undefined, endurance: "100", vie: "4 + @over20", gravite: 6 }, +] +const TABLE_ENCAISSEMENT_NONMORTEL = [ + { minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1 }, + { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0 }, + { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 0 }, + { minimum: 16, maximum: 19, endurance: "2d6", vie: "0", gravite: 2 }, + { minimum: 20, maximum: undefined, endurance: "100", vie: "0", gravite: 2 }, +] +const TABLE_ENCAISSEMENT_ENTITE = [ + { minimum: undefined, maximum: 0, endurance: "0", vie: "0", gravite: -1 }, + { minimum: 1, maximum: 10, endurance: "1d4", vie: "0", gravite: 0 }, + { minimum: 11, maximum: 15, endurance: "1d6", vie: "0", gravite: 2 }, + { minimum: 16, maximum: 19, endurance: "2d6", vie: "0", gravite: 4 }, + { minimum: 20, maximum: undefined, endurance: "3d6 + @over20", vie: "0", gravite: 6 }, +] /* -------------------------------------------- */ export class RdDUtility { @@ -278,7 +275,7 @@ export class RdDUtility { Handlebars.registerHelper('plusMoins', diff => parseInt(diff) ? (diff > 0 ? '+' : '') + Math.round(diff) : diff) Handlebars.registerHelper('fractionOneN', n => new Handlebars.SafeString(Misc.getFractionOneN(n))) - + // Handle v12 removal of this helper Handlebars.registerHelper('select', function (selected, options) { const escapedValue = RegExp.escape(Handlebars.escapeExpression(selected)); @@ -286,7 +283,7 @@ export class RdDUtility { const html = options.fn(this); return html.replace(rgx, "$& selected"); }) - + // logic Handlebars.registerHelper('either', (a, b) => a ?? b); // string manipulation @@ -299,7 +296,7 @@ export class RdDUtility { Handlebars.registerHelper('grammar-un', str => Grammar.articleIndetermine(str)); Handlebars.registerHelper('grammar-accord', (genre, ...args) => Grammar.accord(genre, args)); Handlebars.registerHelper('json-stringify', object => JSON.stringify(object)) - + // math Handlebars.registerHelper('math-sum', (...values) => values.slice(0, -1).reduce(Misc.sum(), 0)) Handlebars.registerHelper('math-abs', diff => Math.abs(parseInt(diff))) @@ -613,20 +610,20 @@ export class RdDUtility { /* -------------------------------------------- */ static async getLocalisation(type = 'personnage') { - const loc = { result: await RdDDice.rollTotal("1d20")}; + const loc = { result: await RdDDice.rollTotal("1d20") }; if (type == 'personnage') { - if (loc.result <= 3) loc.txt = "Jambe, genou, pied, jarret"; - else if (loc.result <= 7) loc.txt = "Hanche, cuisse, fesse"; - else if (loc.result <= 9) loc.txt = "Ventre, reins"; - else if (loc.result <= 12) loc.txt = "Poitrine, dos"; - else if (loc.result <= 14) loc.txt = "Avant-bras, main, coude"; - else if (loc.result <= 18) loc.txt = "Epaule, bras, omoplate"; - else if (loc.result == 19) loc.txt = "Tête"; - else if (loc.result == 20) loc.txt = "Tête (visage)"; + if (loc.result <= 3) loc.txt = "Jambe, genou, pied, jarret"; + else if (loc.result <= 7) loc.txt = "Hanche, cuisse, fesse"; + else if (loc.result <= 9) loc.txt = "Ventre, reins"; + else if (loc.result <= 12) loc.txt = "Poitrine, dos"; + else if (loc.result <= 14) loc.txt = "Avant-bras, main, coude"; + else if (loc.result <= 18) loc.txt = "Epaule, bras, omoplate"; + else if (loc.result == 19) loc.txt = "Tête"; + else if (loc.result == 20) loc.txt = "Tête (visage)"; } else { - if (loc.result <= 7) loc.txt = "Jambes/Pattes"; - else if (loc.result <= 18) loc.txt = "Corps"; - else if (loc.result <= 20) loc.txt = "Tête"; + if (loc.result <= 7) loc.txt = "Jambes/Pattes"; + else if (loc.result <= 18) loc.txt = "Corps"; + else if (loc.result <= 20) loc.txt = "Tête"; } return loc } @@ -671,13 +668,13 @@ export class RdDUtility { } /* -------------------------------------------- */ - static async prepareEncaissement(actor, dmg, roll, armure) { + static async prepareEncaissement(targetActor, dmg, roll, armure) { const jetTotal = roll.total + dmg.total - armure - const encaissement = RdDUtility._selectEncaissement(jetTotal, dmg.mortalite); - const over20 = Math.max(jetTotal - 20, 0); + const encaissement = RdDUtility.$selectEncaissement(targetActor, jetTotal, dmg.mortalite) + const over20 = Math.max(jetTotal - 20, 0) encaissement.dmg = dmg if (ReglesOptionnelles.isUsing('localisation-aleatoire')) { - encaissement.dmg.loc = dmg.loc ?? await RdDUtility.getLocalisation(actor.type) + encaissement.dmg.loc = dmg.loc ?? await RdDUtility.getLocalisation(targetActor.type) encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;' } else { @@ -693,15 +690,21 @@ export class RdDUtility { } /* -------------------------------------------- */ - static _selectEncaissement(degats, mortalite) { - const table = definitionsEncaissement[mortalite] === undefined ? definitionsEncaissement["mortel"] : definitionsEncaissement[mortalite]; - for (let encaissement of table) { - if ((encaissement.minimum === undefined || encaissement.minimum <= degats) - && (encaissement.maximum === undefined || degats <= encaissement.maximum)) { - return foundry.utils.duplicate(encaissement); - } + static $selectEncaissement(targetActor, degats, mortalite) { + const table = RdDUtility.$getTableEncaissement(targetActor, mortalite) + const encaissement = table.find(it => ((it.minimum ?? degats) <= degats && degats <= (it.maximum ?? degats))) + return foundry.utils.duplicate(encaissement ?? table[0]) + } + + static $getTableEncaissement(targetActor, mortalite) { + if (targetActor.isEntite()) { + return TABLE_ENCAISSEMENT_ENTITE } - return foundry.utils.duplicate(table[0]); + switch (mortalite) { + case RDD_CONFIG.encaissement.nonmortel: return TABLE_ENCAISSEMENT_NONMORTEL + case RDD_CONFIG.encaissement.entiteincarnee: return TABLE_ENCAISSEMENT_ENTITE + } + return TABLE_ENCAISSEMENT_MORTEL } /* -------------------------------------------- */ diff --git a/module/roll/roll-part-attaque.mjs b/module/roll/roll-part-attaque.mjs index 914260e8..ccf27bc4 100644 --- a/module/roll/roll-part-attaque.mjs +++ b/module/roll/roll-part-attaque.mjs @@ -1,3 +1,4 @@ +import { RDD_CONFIG } from "../constants.js" import { RdDBonus } from "../rdd-bonus.js" import { DIFF, ROLL_TYPE_ATTAQUE } from "./roll-constants.mjs" import { PART_CARAC } from "./roll-part-carac.mjs" @@ -94,7 +95,7 @@ export class RollPartAttaque extends RollPartSelect { }) checkMortalite?.addEventListener("change", e => { - current.dmg.mortalite = (e.currentTarget.checked ? 'mortel' : 'non-mortel') + current.dmg.mortalite = (e.currentTarget.checked ? RDD_CONFIG.encaissement.mortel : RDD_CONFIG.encaissement.nonmortel) rollDialog.render() }) } diff --git a/templates/chat-resultat-encaissement.hbs b/templates/chat-resultat-encaissement.hbs index f10b9ee5..9a843721 100644 --- a/templates/chat-resultat-encaissement.hbs +++ b/templates/chat-resultat-encaissement.hbs @@ -21,12 +21,12 @@ {{~#unless (eq penetration 0)}} (pénétration de {{penetration}}){{/unless}} {{~/unless~}}, total: {{total}}
- {{alias}} - {{#if (eq dmg.mortalite 'entiteincarnee')}}subit le coup - {{else if mort}}vient de mourir + {{alias}} + {{log 'encaissement' this}} + {{#if mort}}vient de mourir {{else if blessure}} - {{#if (gt blessure.system.gravite 0)}}subit une blessure {{blessure.system.label}} - {{~else~}}subit une contusion + {{#if (gt blessure.system.gravite 0)}}subit une blessure {{blessure.name}} + {{~else~}}subit une éraflure {{~/if~}} {{~else~}}s'en sort sans une égratignure {{~/if~}}