diff --git a/assets/actions/empoignade.svg b/assets/actions/empoignade.svg new file mode 100644 index 00000000..3385ffc2 --- /dev/null +++ b/assets/actions/empoignade.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/ui/encaisser.svg b/assets/actions/encaisser.svg similarity index 100% rename from assets/ui/encaisser.svg rename to assets/actions/encaisser.svg diff --git a/changelog.md b/changelog.md index a690eebf..0cb72945 100644 --- a/changelog.md +++ b/changelog.md @@ -9,6 +9,12 @@ - Nouvelle fenêtre de jets de dés - Attaque/défense des créatures - les attaques/parades avec une arme trop lourde se font en demi-surprise + - empoignade + - l'empoignade est possible avec une initiative d'empoignade, ou en cours d'empoignade + - seule la dague, le pugilat et la dague sont possibles en cours d'empoignade + - jet de Dextérité/Dague pour utiliser la dague en cours d'empoignade + - attaquer avec une arme un empoigneur donne un +4 si pas d'empoignade + - les dommages de l'empoignade ajoutent/enlèvent un point d'empoignade ## 13.0.13 - L'épanouissement d'Illysis diff --git a/css/foundryvtt-reve-de-dragon.css b/css/foundryvtt-reve-de-dragon.css index a7739aef..8eb5bf83 100644 --- a/css/foundryvtt-reve-de-dragon.css +++ b/css/foundryvtt-reve-de-dragon.css @@ -648,6 +648,15 @@ select, .system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="coeur"] select[name="coeur"] { max-width: 4rem; } +.system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="empoignade"] img { + /* image de d100 */ + max-width: 1rem; + max-height: 1rem; + gap: 0; + margin: 0; + padding: 0; + filter: invert(0.8); +} .system-foundryvtt-reve-de-dragon .roll-dialog roll-conditions roll-section[name="tricher"] img { /* image de d100 */ max-width: 2.5rem; diff --git a/less/roll-dialog.less b/less/roll-dialog.less index 567c0f33..f2e4767b 100644 --- a/less/roll-dialog.less +++ b/less/roll-dialog.less @@ -224,6 +224,15 @@ max-width: 4rem; } + roll-conditions roll-section[name="empoignade"] img { + /* image de d100 */ + max-width: 1rem; + max-height: 1rem; + gap: 0; + margin: 0; + padding: 0; + filter: invert(0.8); + } roll-conditions roll-section[name="tricher"] img { /* image de d100 */ max-width: 2.5rem; diff --git a/module/actor.js b/module/actor.js index 24368810..6ab713b7 100644 --- a/module/actor.js +++ b/module/actor.js @@ -185,7 +185,7 @@ export class RdDActor extends RdDBaseActorSang { const actions = [] const uniques = [] - const addAttaque = (arme, main = undefined, action = 'attaque') => { + const addAttaque = (arme, main = undefined) => { const dommages = RdDItemArme.valeurMain(arme.system.dommages, main) const forceRequise = RdDItemArme.valeurMain(arme.system.force ?? 0, main) const ecaillesEfficacite = arme.system.magique ? arme.system.ecaille_efficacite : 0; @@ -229,7 +229,7 @@ export class RdDActor extends RdDBaseActorSang { }) addAttaque(RdDItemArme.pugilat(this), ATTAQUE_TYPE.CORPS_A_CORPS) - addAttaque(RdDItemArme.empoignade(this), ATTAQUE_TYPE.CORPS_A_CORPS, 'empoignade') + addAttaque(RdDItemArme.empoignade(this), ATTAQUE_TYPE.CORPS_A_CORPS) return actions } diff --git a/module/actor/base-actor-reve.js b/module/actor/base-actor-reve.js index 6379cfd7..1beb0c02 100644 --- a/module/actor/base-actor-reve.js +++ b/module/actor/base-actor-reve.js @@ -204,6 +204,7 @@ export class RdDBaseActorReve extends RdDBaseActor { getPossession(possessionId) { return this.itemTypes[ITEM_TYPES.possession].find(it => it.system.possessionid == possessionId); } + getEmpoignades() { return this.itemTypes[ITEM_TYPES.empoignade]; } diff --git a/module/constants.js b/module/constants.js index 37e45b6f..fbd60dc0 100644 --- a/module/constants.js +++ b/module/constants.js @@ -60,7 +60,7 @@ export const RDD_CONFIG = { icons: { armesDisparates: 'systems/foundryvtt-reve-de-dragon/assets/actions/armes-disparates.svg', demiReve: 'systems/foundryvtt-reve-de-dragon/assets/actions/sort.svg', - empoignade: 'systems/foundryvtt-reve-de-dragon/icons/empoignade.webp', + empoignade: 'systems/foundryvtt-reve-de-dragon/assets/actions/empoignade.svg', forceWeak: 'systems/foundryvtt-reve-de-dragon/assets/actions/weak.svg', }, encaissement: { diff --git a/module/initiative.mjs b/module/initiative.mjs index 4ddf5c10..d1ceed40 100644 --- a/module/initiative.mjs +++ b/module/initiative.mjs @@ -58,6 +58,7 @@ export class RdDInitiative { return { roll: roll, value: value, + rang: formule.phase.rang, init: formule.phase.rang + value / 100, label: formule.phase.label } diff --git a/module/item/arme.js b/module/item/arme.js index bd29ead1..74ff0d35 100644 --- a/module/item/arme.js +++ b/module/item/arme.js @@ -27,6 +27,7 @@ export const ATTAQUE_TYPE = { TIR: '(tir)', LANCER: '(lancer)' } +export const ATTAQUE_TYPE_MELEE = [ATTAQUE_TYPE.UNE_MAIN, ATTAQUE_TYPE.DEUX_MAINS, ATTAQUE_TYPE.CORPS_A_CORPS] export const CORPS_A_CORPS = 'Corps à corps' export const PUGILAT = 'pugilat' @@ -254,6 +255,14 @@ export class RdDItemArme extends RdDItem { return this.system.resistance > 0 || (this.system.tir != '' && this.system.portee_courte > 0) } + isEmpoignade() { + return this.system.mortalite == RDD_CONFIG.encaissement.empoignade + } + + isUtilisableEmpoigne() { + return this.system.baseInit == 3 || this.system.baseInit == 4 || this.system.competence == "Dague" + } + static pugilat(actor) { return RdDItemArme.$corpsACorps(actor, 'Pugilat', PUGILAT) } diff --git a/module/rdd-combat.js b/module/rdd-combat.js index 72d10848..15cf3f0b 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -56,6 +56,12 @@ export class RdDCombatManager extends Combat { } } + + static getCombatant(actorId, tokenId) { + return game.combat.combatants.find(it => it.actor.id == actorId && + it.token.id == tokenId + ); + } /* -------------------------------------------- */ async nextRound() { await this.finDeRound(); diff --git a/module/rdd-empoignade.js b/module/rdd-empoignade.js index dbdf0208..f25bdb24 100644 --- a/module/rdd-empoignade.js +++ b/module/rdd-empoignade.js @@ -4,6 +4,8 @@ import { ChatUtility } from "./chat-utility.js"; import { RdDRollResult } from "./rdd-roll-result.js"; import { RdDRoll } from "./rdd-roll.js"; import { MappingCreatureArme } from "./item/mapping-creature-arme.mjs"; +import { MAP_PHASE } from "./initiative.mjs"; +import { RdDCombatManager } from "./rdd-combat.js"; /* -------------------------------------------- */ export class RdDEmpoignade { @@ -12,6 +14,40 @@ export class RdDEmpoignade { static init() { } + /* -------------------------------------------- */ + static isCombatantEmpoignade(actorId, tokenId) { + const combatant = RdDCombatManager.getCombatant(actorId, tokenId) + return MAP_PHASE.empoignade.rang == combatant?.system.init.rang + } + + static async ajustementEmpoignade(attacker, defender, adjust = 1) { + const empoignade = RdDEmpoignade.getEmpoignade(attacker, defender) + if (empoignade) { + if (empoignade.system.empoigneurid == defender.id) { + adjust = - adjust + } + empoignade.system.pointsemp += adjust + RdDEmpoignade.$updateEtatEmpoignade(empoignade) + } + else { + RdDEmpoignade.$createEtatEmpoignade( { + name: `Empoignade de ${attacker.name} sur ${defender.name}`, + type: ITEM_TYPES.empoignade, + system: { + description: "", + empoignadeid: foundry.utils.randomID(16), + empoigneurid: attacker.id, + empoigneid: defender.id, + pointsemp: adjust, + empoigneurname: attacker.name, + empoignename: defender.name + } + } +) + } + } + + /* -------------------------------------------- */ static registerChatCallbacks(html) { $(html).on("click", '.defense-empoignade-cac', event => { @@ -237,10 +273,7 @@ export class RdDEmpoignade { if (rollData.rolled.isSuccess && isNouvelle) { - const objectEmpoignade = rollData.empoignade.toObject(); - // Creer l'empoignade sur attaquant/defenseur - attacker.creerObjetParMJ(objectEmpoignade); - defender.creerObjetParMJ(objectEmpoignade); + RdDEmpoignade.$createEtatEmpoignade(rollData.empoignade) } rollData.empoignade.isSuccess = rollData.rolled.isSuccess; @@ -259,7 +292,7 @@ export class RdDEmpoignade { return } - let empoignade = this.getEmpoignade(attacker, defender) + let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender) if (!empoignade) { ui.notifications.warn("Une erreur s'est produite : Aucune empoignade trouvée !!") @@ -316,6 +349,18 @@ export class RdDEmpoignade { } } + /* -------------------------------------------- */ + static async $createEtatEmpoignade(empoignade) { + console.log("CREATE Empoignade", empoignade) + + let defender = game.actors.get(empoignade.system.empoigneid) + let attacker = game.actors.get(empoignade.system.empoigneurid) + + // Creer l'empoignade sur attaquant/defenseur + await attacker.creerObjetParMJ(empoignade) + await defender.creerObjetParMJ(empoignade) + } + /* -------------------------------------------- */ static async $updateEtatEmpoignade(empoignade) { console.log("UPDATE Empoignade", empoignade) @@ -347,7 +392,7 @@ export class RdDEmpoignade { if (!RdDEmpoignade.isActionAutorisee("immobilise", attacker, defender)) { return } - let empoignade = this.getEmpoignade(attacker, defender) + let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender) empoignade.system.ausol = true await this.$updateEtatEmpoignade(empoignade) @@ -366,7 +411,7 @@ export class RdDEmpoignade { if (!RdDEmpoignade.isActionAutorisee("immobilise", attacker, defender)) { return } - let empoignade = this.getEmpoignade(attacker, defender) + let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender) await defender.setEffect(STATUSES.StatusProne, true); await this.$deleteEmpoignade(empoignade) @@ -382,7 +427,7 @@ export class RdDEmpoignade { if (!RdDEmpoignade.isActionAutorisee("immobilise", attacker, defender)) { return } - let empoignade = this.getEmpoignade(attacker, defender) + let empoignade = RdDEmpoignade.getEmpoignade(attacker, defender) //console.log("Perte d'endurance :!!!", perteMode) let endValue = defender.system.sante.endurance.value @@ -423,9 +468,17 @@ export class RdDEmpoignade { /* -------------------------------------------- */ static async createEmpoignade(attacker, defender) { return await Item.create({ - name: "Empoignade en cours de " + attacker.name + ' sur ' + defender.name, - type: 'empoignade', - system: { description: "", empoignadeid: foundry.utils.randomID(16), compteempoigne: 0, empoigneurid: attacker.id, empoigneid: defender.id, ptsemp: 0, empoigneurname: attacker.name, empoignename: defender.name } + name: "Empoignade de " + attacker.name + ' sur ' + defender.name, + type: ITEM_TYPES.empoignade, + system: { + description: "", + empoignadeid: foundry.utils.randomID(16), + empoigneurid: attacker.id, + empoigneid: defender.id, + pointsemp: 0, + empoigneurname: attacker.name, + empoignename: defender.name + } }, { temporary: true diff --git a/module/roll/chat-roll-result.mjs b/module/roll/chat-roll-result.mjs index d64212bd..bd464c92 100644 --- a/module/roll/chat-roll-result.mjs +++ b/module/roll/chat-roll-result.mjs @@ -12,6 +12,7 @@ import { RollTypeMeditation } from "./roll-type-meditation.mjs" import { PART_DEFENSE } from "./roll-part-defense.mjs" import { PART_ATTAQUE } from "./roll-part-attaque.mjs" import { RdDRollTables } from "../rdd-rolltables.js" +import { RdDEmpoignade } from "../rdd-empoignade.js" export default class ChatRollResult { static init() { @@ -133,6 +134,7 @@ export default class ChatRollResult { $(html).on("click", '.appel-chance', event => this.onClickAppelChance(event)) $(html).on("click", '.appel-destinee', event => this.onClickAppelDestinee(event)) $(html).on("click", '.encaissement', event => this.onClickEncaissement(event)) + $(html).on("click", '.point-empoignade', event => this.onClickMarquerEmpoignade(event)) $(html).on("click", '.resister-recul', event => this.onClickRecul(event)) $(html).on("click", '.choix-particuliere', event => this.onClickChoixParticuliere(event)) $(html).on("click", '.faire-gouter', event => this.onClickFaireGouter(event)) @@ -233,6 +235,15 @@ export default class ChatRollResult { await this.updateChatMessage(chatMessage, savedRoll) } + async onClickMarquerEmpoignade(event) { + const chatMessage = ChatUtility.getChatMessage(event) + const savedRoll = this.loadChatMessageRoll(chatMessage) + const attaque = savedRoll.attackerRoll + const attackerToken = attaque.ids.actorTokenId ? canvas.tokens.get(attaque.ids.actorTokenId) : undefined + const defenderToken = attaque.ids.opponentTokenId ? canvas.tokens.get(attaque.ids.opponentTokenId) : undefined + RdDEmpoignade.ajustementEmpoignade(attackerToken.actor, defenderToken.actor) + } + async onClickRecul(event) { const chatMessage = ChatUtility.getChatMessage(event) const savedRoll = this.loadChatMessageRoll(chatMessage) diff --git a/module/roll/roll-dialog-adapter.mjs b/module/roll/roll-dialog-adapter.mjs index 809b3258..f14ab1ec 100644 --- a/module/roll/roll-dialog-adapter.mjs +++ b/module/roll/roll-dialog-adapter.mjs @@ -124,7 +124,7 @@ export class RollDialogAdapter { const attaque = rollData.current.attaque; const choix = [] - const isEmpoignade = attaque.dmg.mortalite == 'empoignade'; + const isEmpoignade = attaque.dmg.mortalite == RDD_CONFIG.encaissement.empoignade const isCharge = attaque.tactique == 'charge' /* TODO: cas de créatures faisant des lancers, Glou, Glipzouk */ const isMeleeDiffNegative = (attaque.comp.type == ITEM_TYPES.competencecreature || rollData.current.carac.key == CARACS.MELEE) diff --git a/module/roll/roll-dialog.mjs b/module/roll/roll-dialog.mjs index d2eefe70..96667294 100644 --- a/module/roll/roll-dialog.mjs +++ b/module/roll/roll-dialog.mjs @@ -44,6 +44,7 @@ import { RollTypeCuisine } from "./roll-type-cuisine.mjs"; import { RollPartCuisine } from "./roll-part-cuisine.mjs"; import { OptionsAvancees, ROLL_DIALOG_V2_TEST } from "../settings/options-avancees.js"; import { ActorImpacts } from "../technical/actor-impacts.mjs"; +import { RollPartEmpoignade } from "./roll-part-empoignade.mjs"; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api @@ -85,6 +86,7 @@ const ROLL_PARTS = [ new RollPartConditions(), new RollPartEthylisme(), new RollPartMalusArmure(), + new RollPartEmpoignade(), new RollPartEncTotal(), new RollPartSurEnc(), new RollPartAppelMoral(), diff --git a/module/roll/roll-part-attaque.mjs b/module/roll/roll-part-attaque.mjs index 20b0c52b..6ca3827a 100644 --- a/module/roll/roll-part-attaque.mjs +++ b/module/roll/roll-part-attaque.mjs @@ -1,6 +1,10 @@ import { RDD_CONFIG } from "../constants.js" +import { ATTAQUE_TYPE_MELEE } from "../item/arme.js" import { RdDBonus } from "../rdd-bonus.js" -import { DIFF, ROLL_TYPE_ATTAQUE } from "./roll-constants.mjs" +import { CARACS } from "../rdd-carac.js" +import { RdDEmpoignade } from "../rdd-empoignade.js" +import { DIFF, ROLL_TYPE_ATTAQUE, ROLL_TYPE_COMP } from "./roll-constants.mjs" +import RollDialog from "./roll-dialog.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" @@ -12,6 +16,10 @@ export const PART_ATTAQUE = 'attaque' const TACTIQUES = RdDBonus.tactiques.filter(it => it.isTactique) +const FILTER_ATTAQUE_EMPOIGNADE = attaque => attaque.arme.isEmpoignade() +const FILTER_ATTAQUE_NON_EMPOIGNADE = attaque => !attaque.arme.isEmpoignade() +const FILTER_ATTAQUE_EMPOIGNE = attaque => attaque.arme.isUtilisableEmpoigne() && ATTAQUE_TYPE_MELEE.includes(attaque.main) + export class RollPartAttaque extends RollPartSelect { get code() { return PART_ATTAQUE } @@ -22,7 +30,8 @@ export class RollPartAttaque extends RollPartSelect { loadRefs(rollData) { const refs = this.getRefs(rollData) const attaques = rollData.active.actor.listAttaques() - refs.attaques = attaques.map(it => RollPartAttaque.$extractAttaque(it, rollData.active.actor)) + refs.all = attaques.map(it => RollPartAttaque.$extractAttaque(it, rollData.active.actor)) + this.filterAttaquesEmpoignade(rollData) refs.tactiques = TACTIQUES if (refs.attaques.length > 0) { const attaque = this.findAttaque(refs.attaques, this.getSaved(rollData)) @@ -30,6 +39,10 @@ export class RollPartAttaque extends RollPartSelect { } } + isAttaqueEmpoignade(it) { + return it.arme.isEmpoignade() + } + store(rollData, targetData) { super.store(rollData, targetData) this.getSaved(targetData).dmg = this.getCurrent(rollData).dmg @@ -59,10 +72,23 @@ export class RollPartAttaque extends RollPartSelect { } prepareContext(rollData) { + this.filterAttaquesEmpoignade(rollData) const current = this.getCurrent(rollData) current.dmg = RdDBonus.dmgRollV2(rollData, current) } + filterAttaquesEmpoignade(rollData) { + const refs = this.getRefs(rollData) + const isEmpoignade = RdDEmpoignade.isCombatantEmpoignade(rollData.ids.actorId, rollData.ids.actorTokenId) + refs.isEmpoignadeEnCours = RdDEmpoignade.isEmpoignadeEnCours(rollData.active.actor) + const filterAttaques = isEmpoignade ? + FILTER_ATTAQUE_EMPOIGNADE + : refs.isEmpoignadeEnCours + ? FILTER_ATTAQUE_EMPOIGNE + : FILTER_ATTAQUE_NON_EMPOIGNADE + refs.attaques = refs.all.filter(filterAttaques) + } + getAjustements(rollData) { const current = this.getCurrent(rollData) const tactique = current.tactique ? [{ label: current.tactique.label, value: current.tactique.attaque }] : [] @@ -79,6 +105,7 @@ export class RollPartAttaque extends RollPartSelect { const selectAttaque = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-attaque"]`) const selectTactique = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-tactique"]`) const checkMortalite = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="check-mortalite"]`) + const utiliserDagueEmpoignade = rollDialog.element.querySelector(`roll-section[name="${this.code}"] a.utiliser-dague-empoignade`) const current = this.getCurrent(rollDialog.rollData) selectAttaque.addEventListener("change", e => { @@ -99,6 +126,23 @@ export class RollPartAttaque extends RollPartSelect { current.dmg.mortalite = (e.currentTarget.checked ? RDD_CONFIG.encaissement.mortel : RDD_CONFIG.encaissement.nonmortel) rollDialog.render() }) + utiliserDagueEmpoignade?.addEventListener("click", e => { + e.preventDefault() + const rollData = rollDialog.rollData + this.utiliserDagueEmpoignade(rollData) + }) + } + + utiliserDagueEmpoignade(rollData) { + RollDialog.create({ + ids: { actorId: rollData.ids.actorId, actorTokenId: rollData.ids.actorTokenId }, + type: { allowed: [ROLL_TYPE_COMP], current: ROLL_TYPE_COMP }, + selected: { + carac: { key: CARACS.DEXTERITE, forced: true }, + comp: { key: 'Dague', forced: true }, + diff: { type: DIFF.IMPOSEE, value: -4 } + } + }) } impactOtherPart(part, rollData) { diff --git a/module/roll/roll-part-carac.mjs b/module/roll/roll-part-carac.mjs index 065549ca..55801b36 100644 --- a/module/roll/roll-part-carac.mjs +++ b/module/roll/roll-part-carac.mjs @@ -1,3 +1,4 @@ +import { Grammar } from "../grammar.js" import { RollPartSelect } from "./roll-part-select.mjs" import { ROLLDIALOG_SECTION } from "./roll-part.mjs" @@ -12,8 +13,14 @@ export class RollPartCarac extends RollPartSelect { loadRefs(rollData) { const refs = this.getRefs(rollData) + const selected = this.getSelected(rollData) const actor = rollData.active.actor refs.all = [...this.$getActorCaracs(actor), ...this.$getCaracCompetenceCreature(actor)] + .filter(c => !selected.forced || + (selected.key ? + Grammar.includesLowerCaseNoAccent(c.label, selected.key) + : c.key == '') + ) refs.caracs = refs.all this.$selectCarac(rollData) } diff --git a/module/roll/roll-part-comp.mjs b/module/roll/roll-part-comp.mjs index 06f3f5cc..e38832be 100644 --- a/module/roll/roll-part-comp.mjs +++ b/module/roll/roll-part-comp.mjs @@ -18,12 +18,16 @@ export class RollPartComp extends RollPartSelect { loadRefs(rollData) { const refs = this.getRefs(rollData) const selected = this.getSelected(rollData) - refs.all = this.$getActorComps(rollData) - .filter(comp => !selected.forced || - (selected.key ? - Grammar.includesLowerCaseNoAccent(comp.name, selected.key) - : comp.key == '') - ) + const all = this.$getActorComps(rollData) + if (selected.forced) { + refs.all = all.filter(comp => Grammar.equalsInsensitive(comp.label, selected.key)) + if (refs.all.length == 0) { + refs.all = all.filter(comp => Grammar.includesLowerCaseNoAccent(comp.label, selected.key)) + } + } + else { + refs.all = all + } refs.comps = refs.all this.$selectComp(rollData) } diff --git a/module/roll/roll-part-empoignade.mjs b/module/roll/roll-part-empoignade.mjs new file mode 100644 index 00000000..73c9bd65 --- /dev/null +++ b/module/roll/roll-part-empoignade.mjs @@ -0,0 +1,31 @@ +import { RDD_CONFIG } from "../constants.js" +import { ATTAQUE_TYPE_MELEE } from "../item/arme.js" +import { RdDEmpoignade } from "../rdd-empoignade.js" +import { ROLL_TYPE_ATTAQUE } from "./roll-constants.mjs" +import { PART_ATTAQUE } from "./roll-part-attaque.mjs" +import { RollPartCheckbox } from "./roll-part-checkbox.mjs" + +const EMPOIGNADE = "empoignade" + +export class RollPartEmpoignade extends RollPartCheckbox { + + get code() { return EMPOIGNADE } + + isValid(rollData) { + return RdDEmpoignade.isCombatantEmpoignade(rollData.ids.opponentId, rollData.ids.opponentTokenId) && + !RdDEmpoignade.isCombatantEmpoignade(rollData.ids.actorId, rollData.ids.actorTokenId) + } + + visible(rollData) { + return rollData.type.current == ROLL_TYPE_ATTAQUE && + ATTAQUE_TYPE_MELEE.includes(rollData.current[PART_ATTAQUE].main) && + RdDEmpoignade.isCombatantEmpoignade(rollData.ids.opponentId, rollData.ids.opponentTokenId) && + !RdDEmpoignade.isCombatantEmpoignade(rollData.ids.actorId, rollData.ids.actorTokenId) && + !RdDEmpoignade.isEmpoignadeEnCours(rollData.active.actor) + } + + + getCheckboxIcon(rollData) { return `` } + getCheckboxLabel(rollData) { return "vs. empoigneur" } + getCheckboxValue(rollData) { return 4 } +} diff --git a/module/roll/roll-type.mjs b/module/roll/roll-type.mjs index 4f7ed51e..bc21742c 100644 --- a/module/roll/roll-type.mjs +++ b/module/roll/roll-type.mjs @@ -47,6 +47,7 @@ export class RollType { } setDiffType(rollData, type) { + type = rollData.selected[PART_DIFF].type ?? type rollData.current[PART_DIFF].type = type this.setRollDataType(rollData) } diff --git a/templates/chat-demande-defense.hbs b/templates/chat-demande-defense.hbs index 75d544be..3d11987d 100644 --- a/templates/chat-demande-defense.hbs +++ b/templates/chat-demande-defense.hbs @@ -43,15 +43,20 @@ {{/if}} {{/unless}} - {{#unless (eq dmg.mortalite 'empoignade')}} + {{#if (eq dmg.mortalite 'empoignade')}} + + + Marquer le point d'empoignade + + {{else}} - + Encaisser à {{plusMoins dmg.total}} {{#if (eq dmg.mortalite 'non-mortel')~}}(non-mortel){{/if}} - {{/unless}} + {{/if}}
diff --git a/templates/roll/result/partial-encaissement.hbs b/templates/roll/result/partial-encaissement.hbs index 8adbcb60..469c9507 100644 --- a/templates/roll/result/partial-encaissement.hbs +++ b/templates/roll/result/partial-encaissement.hbs @@ -1,14 +1,14 @@ {{#if show.encaissement}} {{#if done.encaissement}} - + {{active.name}} a encaissé {{else}} - Encaisser à {{plusMoins attackerRoll.dmg.total}} + Encaisser à {{plusMoins attackerRoll.dmg.total}} {{#if (eq attackerRoll.dmg.mortalite 'non-mortel')~}}(non-mortel){{/if}} {{/if}} diff --git a/templates/roll/roll-part-attaque.hbs b/templates/roll/roll-part-attaque.hbs index 28b6e7dd..2b1bf3e9 100644 --- a/templates/roll/roll-part-attaque.hbs +++ b/templates/roll/roll-part-attaque.hbs @@ -15,19 +15,32 @@ {{selectOptions refs.tactiques selected=current.tactique.key valueAttr="key" labelAttr="label"}} - - {{#if (eq current.arme.system.mortalite 'empoignade')}} - Empoignade, pas de dommages directs - {{else}} - {{#if (and (ne current.arme.system.mortalite 'non-mortel') (eq current.dmg.penetration 0))}} - - {{/if}} + {{#if (and refs.isEmpoignadeEnCours (eq current.arme.system.competence 'Dague'))}} + + + Pour pouvoir attaquer avec une dague en cours d'empoignade, il faut réussir:
+ DEXTÉRITÉ / Dague à -4 +
En cas d'échec total, {{rollData.active.name}} sera désarmé. +
+
+ {{/if}} + {{#if (eq current.arme.system.mortalite 'empoignade')}} + + Empoignade, pas de dommages directs.
+ Si {{either rollData.opponent.name}} est équipé d'une arme de mêlée, ou attaque + à mains nues (pugilat), il bénéficie d'un bonus de +4 à son attaque. +
+ {{else}} + + {{#if (and (ne current.arme.system.mortalite 'non-mortel') (eq current.dmg.penetration 0))}} + + {{/if}} - {{/if}} - +
+ {{/if}} {{#if rollData.active.effets}}