From 47c447830309425b1a91706b750a414c24e45d0b Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Fri, 3 Oct 2025 22:34:07 +0200 Subject: [PATCH] =?UTF-8?q?Roll=20V2=20sur=20comp=C3=A9tences&combat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Corrections associées Maintenant, active en mode rollV2 --- module/actor/base-actor-reve.js | 35 ++++++++++------ module/actor/export-scriptarium/mapping.js | 6 +-- module/item/arme.js | 48 +++++++++++----------- module/misc.js | 4 ++ module/rdd-combat.js | 11 +++-- module/rdd-hotbar-drop.js | 16 ++++---- module/rdd-roll.js | 5 +-- module/roll/chat-roll-result.mjs | 4 +- module/roll/roll-constants.mjs | 8 ++++ module/roll/roll-dialog.mjs | 4 +- module/roll/roll-part-attaque.mjs | 41 ++++++++++++++---- module/roll/roll-part-diff.mjs | 6 +-- 12 files changed, 118 insertions(+), 70 deletions(-) diff --git a/module/actor/base-actor-reve.js b/module/actor/base-actor-reve.js index 54688851..3d1ec42f 100644 --- a/module/actor/base-actor-reve.js +++ b/module/actor/base-actor-reve.js @@ -26,7 +26,8 @@ import { BASE_CORPS_A_CORPS, BASE_ESQUIVE, POSSESSION_SANS_DRACONIC } from "../i import { RollDataAjustements } from "../rolldata-ajustements-v1.js"; import { MappingCreatureArme } from "../item/mapping-creature-arme.mjs"; import RollDialog from "../roll/roll-dialog.mjs"; -import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_COMP, ROLL_TYPE_JEU, ROLL_TYPE_MEDITATION, ROLL_TYPE_OEUVRE, ROLL_TYPE_TACHE } from "../roll/roll-constants.mjs"; +import { ATTAQUE_ROLL_TYPES, DEFAULT_ROLL_TYPES, DIFF, ROLL_TYPE_ATTAQUE, ROLL_TYPE_COMP, ROLL_TYPE_JEU, ROLL_TYPE_MEDITATION, ROLL_TYPE_OEUVRE, ROLL_TYPE_TACHE } from "../roll/roll-constants.mjs"; +import { OptionsAvancees, ROLL_DIALOG_V2 } from "../settings/options-avancees.js"; /** * Classe de base pour les acteurs disposant de rêve (donc, pas des objets) @@ -410,22 +411,32 @@ export class RdDBaseActorReve extends RdDBaseActor { /* -------------------------------------------- */ async rollCompetenceV2(rollData) { - foundry.utils.mergeObject(rollData, { - ids: { - actorId: this.id - }, - type: { - allowed: [ROLL_TYPE_COMP, ROLL_TYPE_OEUVRE, ROLL_TYPE_TACHE, ROLL_TYPE_JEU, ROLL_TYPE_MEDITATION], - - } - }) - rollData.ids.actorId = rollData.ids.actorId ?? this.id + rollData.ids = rollData?.ids ?? {} + rollData.type = rollData.type ?? { allowed: DEFAULT_ROLL_TYPES } + rollData.ids.actorId = this.id await RollDialog.create(rollData) } async rollCompetence(idOrName, options = { tryTarget: true, arme: undefined }) { RdDEmpoignade.checkEmpoignadeEnCours(this) + const competence = this.getCompetence(idOrName); + if (competence.type != ITEM_TYPES.competencecreature && OptionsAvancees.isUsing(ROLL_DIALOG_V2)) { + const rollData = { + selected: { + comp: { key: competence.name }, + diff: { type: DIFF.LIBRE, value: competence.system.default_diffLibre ?? 0 } + } + } + if (options.arme) { + rollData.selected.attaque = { arme: { id: options.arme.id }, comp: { id: competence.id } } + rollData.type = { allowed: ATTAQUE_ROLL_TYPES } + } + + await this.rollCompetenceV2(rollData) + return + } + let rollData = { carac: this.system.carac, competence: competence, @@ -443,7 +454,7 @@ export class RdDBaseActorReve extends RdDBaseActor { RdDCombat.rddCombatTarget(target, this, token).attaque(competence, arme) } }); - return; + return } // Transformer la competence de créature MappingCreatureArme.setRollDataCreature(rollData) diff --git a/module/actor/export-scriptarium/mapping.js b/module/actor/export-scriptarium/mapping.js index df373d3b..acd18e4c 100644 --- a/module/actor/export-scriptarium/mapping.js +++ b/module/actor/export-scriptarium/mapping.js @@ -1,5 +1,5 @@ import { Grammar } from "../../grammar.js" -import { RdDItemArme } from "../../item/arme.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" @@ -141,7 +141,7 @@ export class Mapping { static prepareArmes(actor) { const armes = actor.items.filter(it => it.type == ITEM_TYPES.arme) - armes.push(RdDItemArme.corpsACorps(actor)); + armes.push(RdDItemArme.pugilat(actor)); armes.push(RdDItemArme.empoignade(actor)); return armes.map(arme => [ arme.system.unemain ? Mapping.prepareArme(actor, arme, '(1 main)') : undefined, @@ -175,7 +175,7 @@ export class Mapping { const dommages = Misc.toSignedString(dmgArme + RdDBonus.bonusDmg(actor, maniement, dmgArme)) switch (arme.system.mortalite) { case 'non-mortel': return `(${dommages})` - case 'empoignade': return '-' + case EMPOIGNADE: return '-' } return dommages } diff --git a/module/item/arme.js b/module/item/arme.js index 5cd4930d..b775a1b2 100644 --- a/module/item/arme.js +++ b/module/item/arme.js @@ -4,6 +4,7 @@ import { BASE_CORPS_A_CORPS } from "./base-items.js"; import { Grammar } from "../grammar.js"; import { RdDInitiative } from "../initiative.mjs"; import { MappingCreatureArme } from "./mapping-creature-arme.mjs"; +import { Misc } from "../misc.js"; const nomCategorieParade = { "sans-armes": "Sans arme", @@ -27,6 +28,10 @@ export const ATTAQUE_TYPE = { LANCER: '(lancer)' } +export const CORPS_A_CORPS = 'Corps à corps' +export const PUGILAT = 'pugilat' +export const EMPOIGNADE = 'empoignade' + /* -------------------------------------------- */ export class RdDItemArme extends RdDItem { @@ -63,7 +68,7 @@ export class RdDItemArme extends RdDItem { case ITEM_TYPES.competencecreature: return MappingCreatureArme.armeCreature(arme); } - return RdDItemArme.corpsACorps(); + return RdDItemArme.pugilat(); } static getCompetenceArme(arme, maniement) { @@ -77,6 +82,7 @@ export class RdDItemArme extends RdDItem { case ATTAQUE_TYPE.DEUX_MAINS: return arme.competence2Mains() case ATTAQUE_TYPE.TIR: case 'tir': return arme.system.tir case ATTAQUE_TYPE.LANCER: case 'lancer': return arme.system.lancer; + case ATTAQUE_TYPE.CORPS_A_CORPS: return CORPS_A_CORPS } } return undefined @@ -248,12 +254,20 @@ export class RdDItemArme extends RdDItem { return this.system.resistance > 0 || (this.system.tir != '' && this.system.portee_courte > 0) } - static corpsACorps(actor) { - let competence = actor?.getCompetenceCorpsACorps() ?? BASE_CORPS_A_CORPS - let melee = actor ? actor.system.carac['melee'].value : 0 + static pugilat(actor) { + return RdDItemArme.$corpsACorps(actor, 'Pugilat', PUGILAT) + } + + static empoignade(actor) { + return RdDItemArme.$corpsACorps(actor, 'Empoignade', EMPOIGNADE) + } + + static $corpsACorps(actor, name, cac, system) { + const competence = actor?.getCompetenceCorpsACorps() ?? BASE_CORPS_A_CORPS + const melee = actor ? actor.system.carac['melee'].value : 0 return new RdDItemArme({ - _id: competence.id, - name: 'Corps à corps', + _id: Misc.fakeId(cac), + name: name, type: ITEM_TYPES.arme, img: competence.img, system: { @@ -263,29 +277,15 @@ export class RdDItemArme extends RdDItem { force: 0, dommages: "0", dommagesReels: 0, - mortalite: 'non-mortel', - competence: 'Corps à corps', + mortalite: cac == EMPOIGNADE ? EMPOIGNADE : 'non-mortel', + competence: CORPS_A_CORPS, resistance: 1, - baseInit: 4, - cac: 'pugilat', + baseInit: cac == EMPOIGNADE ? 3 : 4, + cac: cac, deuxmains: true, categorie_parade: 'sans-armes' } }) } - static pugilat(actor) { - const pugilat = RdDItemArme.corpsACorps(actor) - pugilat.name = 'Pugilat' - return pugilat - } - - static empoignade(actor) { - const empoignade = RdDItemArme.corpsACorps(actor) - empoignade.name = 'Empoignade' - empoignade.system.cac = 'empoignade' - empoignade.system.baseInit = 3 - empoignade.system.mortalite = 'empoignade' - return empoignade - } } diff --git a/module/misc.js b/module/misc.js index 2a62683c..cca47cfb 100644 --- a/module/misc.js +++ b/module/misc.js @@ -65,6 +65,10 @@ export class Misc { return 0; } + static fakeId(base) { + return (base + foundry.utils.randomID(16)).substring(0, 16) + } + static typeName(type, subType) { return subType ? game.i18n.localize(`TYPES.${type}.${subType}`) : ''; diff --git a/module/rdd-combat.js b/module/rdd-combat.js index 4bcc5d6f..97d17ba8 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -10,14 +10,14 @@ import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; import { Targets } from "./targets.js"; import { RdDEmpoignade } from "./rdd-empoignade.js"; import { RdDRollResult } from "./rdd-roll-result.js"; -import { RdDItemArme } from "./item/arme.js"; +import { EMPOIGNADE, RdDItemArme } from "./item/arme.js"; 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 { RollDialogAdapter } from "./roll/roll-dialog-adapter.mjs"; import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll/roll-constants.mjs"; -import { OptionsAvancees, ROLL_DIALOG_V2_TEST } from "./settings/options-avancees.js"; +import { OptionsAvancees, ROLL_DIALOG_V2, ROLL_DIALOG_V2_TEST } from "./settings/options-avancees.js"; import { MappingCreatureArme } from "./item/mapping-creature-arme.mjs"; import { RollBasicParts } from "./roll/roll-basic-parts.mjs"; @@ -757,7 +757,10 @@ export class RdDCombat { if (!await this.attacker.accorder(this.defender, 'avant-attaque')) { return } - if (arme.system.cac == 'empoignade') { + if (OptionsAvancees.isUsing(ROLL_DIALOG_V2)) { + return this.attacker.rollCompetence(competence.name, { arme: arme }) + } + if (arme.system.cac == EMPOIGNADE) { RdDEmpoignade.onAttaqueEmpoignade(this.attacker, this.defender) return } @@ -810,7 +813,7 @@ export class RdDCombat { } else { // sans armes: à mains nues - rollData.arme = RdDItemArme.corpsACorps(this.attacker) + rollData.arme = RdDItemArme.pugilat(this.attacker) rollData.arme.system.niveau = competence.system.niveau rollData.arme.system.initiative = RdDInitiative.getRollInitiative(this.attacker.system.carac['melee'].value, competence.system.niveau); } diff --git a/module/rdd-hotbar-drop.js b/module/rdd-hotbar-drop.js index 84e004c6..5ee0087f 100644 --- a/module/rdd-hotbar-drop.js +++ b/module/rdd-hotbar-drop.js @@ -1,4 +1,4 @@ -import { ATTAQUE_TYPE, RdDItemArme } from "./item/arme.js"; +import { ATTAQUE_TYPE, EMPOIGNADE, PUGILAT, RdDItemArme } from "./item/arme.js"; import { ITEM_TYPES } from "./constants.js"; export class RdDHotbar { @@ -28,8 +28,8 @@ export class RdDHotbar { return ' ' + maniement case 'tir': return ' (tir)'; case 'lancer': return ' (lancer)'; - case 'pugilat': return ' (pugilat)'; - case 'empoignade': return ' (empoignade)'; + case PUGILAT: return ' (pugilat)'; + case EMPOIGNADE: return ' (empoignade)'; } return '' } @@ -63,8 +63,8 @@ export class RdDHotbar { case ITEM_TYPES.competence: await this.createItemMacro(item, slot++, 'competence') if (item.isCorpsACorps()) { - await this.createItemMacro(item, slot++, 'pugilat') - await this.createItemMacro(item, slot++, 'empoignade') + await this.createItemMacro(item, slot++, PUGILAT) + await this.createItemMacro(item, slot++, EMPOIGNADE) } else if (item.isCompetenceArme()) { ui.notifications.info(`${item.name} est une compétence d'arme, la macro n'est pas liée à un arme.
@@ -121,9 +121,9 @@ export class RdDHotbar { case ITEM_TYPES.competence: if (item.isCorpsACorps()) { switch (categorieArme) { - case 'pugilat': - return actor.rollArme(RdDItemArme.corpsACorps(actor)); - case 'empoignade': + case PUGILAT: + return actor.rollArme(RdDItemArme.pugilat(actor)); + case EMPOIGNADE: return actor.rollArme(RdDItemArme.empoignade(actor)); } } diff --git a/module/rdd-roll.js b/module/rdd-roll.js index 36217bae..65c08de6 100644 --- a/module/rdd-roll.js +++ b/module/rdd-roll.js @@ -9,6 +9,7 @@ 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 { EMPOIGNADE } from "./item/arme.js"; /** * Extend the base Dialog entity to select roll parameters @@ -333,10 +334,8 @@ 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("label.dmg-arme-actor").text(rollData.dmg.mortalite == 'empoignade' ? 'empoignade' : Misc.toSignedString(rollData.dmg.total)); + 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("[name='dmg-arme-actor']").text(rollData.dmg.mortalite == 'empoignade'? 'empoignade': Misc.toSignedString(rollData.dmg.total) ); - // this.html.find("[name='arme-mortalite']").text(rollData.dmg.mortalite); this.html.find("div.placeholder-ajustements").empty().append(adjustements); this.html.find("div.placeholder-resolution").empty().append(resolutionTable) } diff --git a/module/roll/chat-roll-result.mjs b/module/roll/chat-roll-result.mjs index 7898b5d1..69bfbbbf 100644 --- a/module/roll/chat-roll-result.mjs +++ b/module/roll/chat-roll-result.mjs @@ -5,6 +5,7 @@ import { RdDCombat } from "../rdd-combat.js" import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs" import { RdDResolutionTable } from "../rdd-resolution-table.js" import { RDD_CONFIG, renderTemplate } from "../constants.js" +import { EMPOIGNADE } from "../item/arme.js" export default class ChatRollResult { static init() { @@ -56,8 +57,7 @@ export default class ChatRollResult { isShowEncaissement(roll) { switch (roll.type.current) { case ROLL_TYPE_DEFENSE: - return roll.rolled.isEchec && - roll.attackerRoll?.dmg.mortalite != 'empoignade' + return roll.rolled.isEchec && roll.attackerRoll?.dmg.mortalite != EMPOIGNADE } return false } diff --git a/module/roll/roll-constants.mjs b/module/roll/roll-constants.mjs index cb36cf3c..7b5f54f9 100644 --- a/module/roll/roll-constants.mjs +++ b/module/roll/roll-constants.mjs @@ -9,6 +9,14 @@ export const ROLL_TYPE_OEUVRE = 'oeuvre' export const ROLL_TYPE_SORT = 'sort' export const ROLL_TYPE_TACHE = 'tache' +export const ATTAQUE_ROLL_TYPES = [ROLL_TYPE_ATTAQUE] +export const COMBAT_ROLL_TYPES = [ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE] +export const DEMIREVE_ROLL_TYPES = [ROLL_TYPE_SORT] +export const DEFAULT_ROLL_TYPES = [ROLL_TYPE_COMP, ROLL_TYPE_JEU, ROLL_TYPE_MEDITATION, ROLL_TYPE_CUISINE, ROLL_TYPE_OEUVRE, ROLL_TYPE_TACHE] +export const ALL_ROLL_TYPES = [...DEFAULT_ROLL_TYPES, ...COMBAT_ROLL_TYPES, ...DEMIREVE_ROLL_TYPES] + + + export const DIFF = { LIBRE: 'libre', ATTAQUE: 'attaque', diff --git a/module/roll/roll-dialog.mjs b/module/roll/roll-dialog.mjs index 82fcacc3..33cc625e 100644 --- a/module/roll/roll-dialog.mjs +++ b/module/roll/roll-dialog.mjs @@ -264,8 +264,8 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2 const potential = ALL_ROLL_TYPES.find(m => m.code == rollData.type.current)?.code const allowed = rollData.type.retry && potential ? [potential] - : (rollData.type.allowed ?? ALL_ROLL_TYPES.filter(m => m.isAllowed(rollData) && m.visible(rollData)).map(m => m.code)) - const rollType = allowed.find(c => c == rollData.type.current) ?? (allowed.length > 0 ? allowed[0].code : ROLL_TYPE_COMP); + : (rollData.type.allowed ?? ALL_ROLL_TYPES.filter(m => m.isAllowed(rollData) && m.visible(rollData)).map(m => m.code) ?? [ROLL_TYPE_COMP]) + const rollType = allowed.find(c => c == rollData.type.current) ?? allowed[0] rollData.type.allowed = allowed rollData.type.current = rollType diff --git a/module/roll/roll-part-attaque.mjs b/module/roll/roll-part-attaque.mjs index 6b2bc4ad..a9f69731 100644 --- a/module/roll/roll-part-attaque.mjs +++ b/module/roll/roll-part-attaque.mjs @@ -1,7 +1,8 @@ import { RdDBonus } from "../rdd-bonus.js" -import { ROLL_TYPE_ATTAQUE } from "./roll-constants.mjs" +import { DIFF, ROLL_TYPE_ATTAQUE } from "./roll-constants.mjs" import { PART_CARAC } from "./roll-part-carac.mjs" import { PART_COMP } from "./roll-part-comp.mjs" +import { PART_DIFF } from "./roll-part-diff.mjs" import { RollPartSelect } from "./roll-part-select.mjs" import { ROLLDIALOG_SECTION } from "./roll-part.mjs" @@ -22,7 +23,8 @@ export class RollPartAttaque extends RollPartSelect { refs.attaques = attaques.map(it => RollPartAttaque.$extractAttaque(it, rollData.active.actor)) refs.tactiques = TACTIQUES if (refs.attaques.length > 0) { - this.$selectAttaque(rollData) + const attaque = this.findAttaque(refs.attaques, this.getSaved(rollData)) + this.$selectAttaque(rollData, attaque?.key) } } @@ -32,19 +34,34 @@ export class RollPartAttaque extends RollPartSelect { } restore(rollData) { + const saved = this.getSaved(rollData) super.restore(rollData) - this.getCurrent(rollData).dmg = this.getSaved(rollData).dmg + if (saved.dmg) { + this.getCurrent(rollData).dmg = this.getSaved(rollData).dmg + } + } + + findAttaque(attaques, saved) { + return attaques.find(at => at.arme.id == saved?.arme?.id && + at.comp.id == saved?.comp?.id + ) } choices(refs) { return refs.attaques } static $extractAttaque(attaque, actor) { - return foundry.utils.mergeObject({ - key: `${attaque.action}::${attaque.label}`, - tactique: TACTIQUES[0] - }, - attaque - ) + // const extracted = foundry.utils.mergeObject({ + // key: `${attaque.action}::${attaque.label}`, + // tactique: TACTIQUES[0] + // }, + // attaque + // ) + // return extracted + // extracted.initialDiff = attaque.comp?.system.default_diffLibre ?? 0 + attaque.key = `${attaque.action}::${attaque.label}` + attaque.tactique = TACTIQUES[0] + attaque.initialDiff = attaque.comp?.system.default_diffLibre ?? 0 + return attaque } prepareContext(rollData) { @@ -101,6 +118,12 @@ export class RollPartAttaque extends RollPartSelect { switch (part.code) { case PART_CARAC: return part.filterCaracs(rollData, [current.carac.key]) case PART_COMP: return part.filterComps(rollData, [current.comp.name]) + case PART_DIFF: { + if (current.initialDiff) { + part.setDiff(rollData, { type: DIFF.ATTAQUE, value: current.initialDiff }) + current.initialDiff = undefined + } + } } } return undefined diff --git a/module/roll/roll-part-diff.mjs b/module/roll/roll-part-diff.mjs index 8ec99049..680dd9e8 100644 --- a/module/roll/roll-part-diff.mjs +++ b/module/roll/roll-part-diff.mjs @@ -51,10 +51,10 @@ export class RollPartDiff extends RollPart { ) } - setDiff(rollData, diffDefense) { + setDiff(rollData, diff) { const current = this.getCurrent(rollData) - current.value = diffDefense.diff - current.type = diffDefense.type + current.value = diff.diff + current.type = diff.type } getAjustements(rollData) {