Avancement messages défense & oeuvres

This commit is contained in:
2025-09-27 01:43:49 +02:00
parent d26ab59c51
commit 2741fc3fbf
31 changed files with 954 additions and 220 deletions

View File

@@ -17,9 +17,8 @@ import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
import { RdDInitiative } from "./initiative.mjs";
import RollDialog from "./roll/roll-dialog.mjs";
import { PART_DEFENSE } from "./roll/roll-part-defense.mjs";
import { PART_ATTAQUE } from "./roll/roll-part-attaque.mjs";
import { RollDialogAdapter } from "./roll/roll-dialog-adapter.mjs";
import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll/roll-constants.mjs";
import { DIFF, ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll/roll-constants.mjs";
/* -------------------------------------------- */
const premierRoundInit = [
@@ -413,6 +412,9 @@ export class RdDCombat {
'.appel-chance-attaque',
'.appel-destinee-attaque',
'.echec-total-attaque',
'.appel-chance',
'.chat-encaissement',
'.resister-recul',
]) {
$(html).on("click", button, event => {
const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(
@@ -807,8 +809,6 @@ export class RdDCombat {
/* -------------------------------------------- */
async _sendMessageDefense(attackerRoll, defenderRoll, essaisPrecedents = undefined) {
console.log("RdDCombat._sendMessageDefense", attackerRoll, defenderRoll, essaisPrecedents, " / ", this.attacker, this.target, this.attackerId, attackerRoll.competence.system.categorie);
this.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
if (essaisPrecedents) {
foundry.utils.mergeObject(attackerRoll.essais, essaisPrecedents, { overwrite: true });
@@ -980,18 +980,21 @@ export class RdDCombat {
opponentId: this.attackerId,
},
type: { allowed: ['defense'], current: 'defense' },
attaque: RollDialogAdapter.mapActionAttaque(attackerRoll),
attackerRoll: RollDialogAdapter.mapActionAttaque(attackerRoll),
passeArme: attackerRoll.passeArme,
}
await RollDialog.create(rollData, {
onRollDone: (dialog) => { dialog.close() },
onRollDone: (dialog) => {
// dialog.close()
},
customChatMessage: true,
callbacks: [async (roll) => {
this.removeChatMessageActionsPasseArme(roll.passeArme)
// defense: esquive / arme de parade / competence de défense
if (!RdDCombat.isParticuliere(roll))
if (!RdDCombat.isParticuliere(roll)) {
await roll.active.actor.incDecItemUse(roll.current[PART_DEFENSE].defense?.id,)
}
await this._onDefense(roll)
}]
})
@@ -1025,57 +1028,49 @@ export class RdDCombat {
}
async _onDefense(rollData) {
console.log("RdDCombat._onDefense >>>", rollData)
const isEsquive = rollData.current[PART_DEFENSE].isEsquive
const isParade = !isEsquive
if (RdDCombat.isReussite(rollData)) {
await this._onDefenseNormale(rollData)
if (isParade) {
await this.computeRecul(rollData)
await this.computeDeteriorationArme(rollData)
}
if (RdDCombat.isParticuliere(rollData)) {
await this._onDefenseParticuliere(rollData)
await this._onDefenseParticuliere(rollData, isEsquive)
}
}
else {
await this._onDefenseEchec(dialog, rollData)
//await this._sendMessageDefense(rollData.attackerRoll, rollData, { defense: true })
}
// TODO: modify chat message
this.removeChatMessageActionsPasseArme(rollData.passeArme)
}
async _onDefenseParticuliere(rollData) {
console.log("RdDCombat._onDefenseParticuliere >>>", rollData);
if (/*TODO: parade?*/!rollData.attackerRoll?.isPart) {
async _onDefenseParticuliere(rollData, isEsquive) {
if (isEsquive) {
ChatUtility.createChatWithRollMode(
{ content: "<strong>Vous pouvez esquiver une deuxième fois!</strong>" },
this.defender)
}
else if (/*TODO: parade?*/!rollData.attackerRoll?.particuliere) {
// TODO: attaquant doit jouer résistance et peut être désarmé p132
ChatUtility.createChatWithRollMode(
{ content: `(à gérer) L'attaquant doit jouer résistance et peut être désarmé (p132)` },
this.defender)
}
ChatUtility.createChatWithRollMode(
{ content: "<strong>Vous pouvez esquiver une deuxième fois!</strong>" },
this.defender);
}
async _onDefenseNormale(rollData) {
console.log("RdDCombat._onDefenseNormale >>>", rollData);
// console.log("RdDCombat._onEsquiveNormal >>>", rollData);
// await RdDRollResult.displayRollData(rollData, this.defender, 'chat-resultat-esquive.hbs');
// this.removeChatMessageActionsPasseArme(rollData.passeArme);
//TODO
await this.computeRecul(rollData);
await this.computeDeteriorationArme(rollData);
await RdDRollResult.displayRollData(rollData, this.defender, 'chat-resultat-parade.hbs');
this.removeChatMessageActionsPasseArme(rollData.passeArme);
}
async _onDefenseEchec(rollData) {
console.log("RdDCombat._onDefenseEchec >>>", rollData);
// console.log("RdDCombat._onEsquiveEchec >>>", rollData);
// await RdDRollResult.displayRollData(rollData, this.defender, 'chat-resultat-esquive.hbs');
// this.removeChatMessageActionsPasseArme(rollData.passeArme);
// this._sendMessageDefense(rollData.attackerRoll, rollData, { defense: true })
await RdDRollResult.displayRollData(rollData, this.defender, 'chat-resultat-parade.hbs');
this.removeChatMessageActionsPasseArme(rollData.passeArme);
this._sendMessageDefense(rollData.attackerRoll, rollData, { defense: true });
}
@@ -1214,7 +1209,7 @@ export class RdDCombat {
// Est-ce une parade normale?
if (defenderRoll.arme && attackerRoll && !defenderRoll.rolled.isPart) {
// Est-ce que l'attaque est une particulière en force ou une charge
if (defenderRoll.needResist || this._isForceOuCharge(attackerRoll)) {
if (defenderRoll.needResist || this._isForceOuCharge(attackerRoll, defenderRoll.v2)) {
defenderRoll.show = defenderRoll.show || {}
@@ -1262,7 +1257,7 @@ export class RdDCombat {
finalLevel: Misc.toInt(defenderRoll.competence.system.niveau) - dmg,
showDice: HIDE_DICE
});
defenderRoll.show.desarme = desarme.rolled.isEchec;
defenderRoll.show.desarme = desarme.rolled.isEchec
}
}
}
@@ -1270,39 +1265,47 @@ export class RdDCombat {
/* -------------------------------------------- */
async computeRecul(defenderRoll) { // Calcul du recul (p. 132)
const attackerRoll = defenderRoll.attackerRoll;
if (ReglesOptionnelles.isUsing('recul') && this._isForceOuCharge(attackerRoll)) {
const impact = this._computeImpactRecul(attackerRoll);
const rollRecul = await RdDResolutionTable.rollData({ caracValue: 10, finalLevel: impact });
if (rollRecul.rolled.isSuccess) {
defenderRoll.show.recul = 'encaisse';
} else if (rollRecul.rolled.isETotal || this._isReculCauseChute(impact)) {
defenderRoll.show.recul = 'chute';
await this.defender.setEffect(STATUSES.StatusProne, true);
}
else {
defenderRoll.show.recul = 'recul';
}
if (!ReglesOptionnelles.isUsing('recul')) {
return
}
const attackerRoll = defenderRoll.attackerRoll;
if (this._isForceOuCharge(attackerRoll, defenderRoll.v2)) {
const impact = this._computeImpactRecul(attackerRoll);
const rollRecul = await RdDResolutionTable.roll(10, impact)
defenderRoll.show.recul = await this.gererRecul(rollRecul, impact)
}
}
async gererRecul(rolled, impact) {
if (rolled.isSuccess) {
return 'encaisse'
}
if (rolled.isETotal || this._isReculCauseChute(impact)) {
await this.defender.setEffect(STATUSES.StatusProne, true)
return 'chute'
}
return 'recul'
}
/* -------------------------------------------- */
async _isReculCauseChute(impact) {
const agilite = this.defender.getAgilite();
const chute = await RdDResolutionTable.rollData({ caracValue: agilite, finalLevel: impact });
return chute.rolled.isEchec;
const agilite = this.defender.getAgilite()
const chute = await RdDResolutionTable.rollData({ caracValue: agilite, finalLevel: impact })
return chute.rolled.isEchec
}
_isForceOuCharge(attaque, isRollV2 = false /* TODO: delete roll V1 */) {
return attaque.particuliere == 'force' || 'charge' == (isRollV2 ? attaque.tactique?.key : attaque.tactique)
}
/* -------------------------------------------- */
_isForceOuCharge(attaque) {
return attaque.particuliere == 'force' || attaque.tactique == 'charge';
}
/* -------------------------------------------- */
_computeImpactRecul(attaque) {
const taille = this.defender.getTaille();
const force = this.attacker.getForce();
const dommages = attaque.arme.system.dommagesReels ?? attaque.arme.system.dommages;
_computeImpactRecul(attackerRoll) {
const taille = this.defender.getTaille()
const force = this.attacker.getForce()
const dommages = attackerRoll.dmg /* TODO: delete roll V1 */
? attackerRoll.dmg.dmgArme
: attackerRoll.arme.system.dommagesReels ?? attaque.arme.system.dommages;
return taille - (force + dommages);
}