Ajouts combat #68
- gestion de la feinte (sauf initiative) - gestion du bonus à l'attaque de la charge - dégats de corps à corps - bonus dégâts si surprise, début de gestion de surprise totale
This commit is contained in:
parent
c8a2d69e0f
commit
f3453a46e7
148
module/actor.js
148
module/actor.js
@ -125,6 +125,7 @@ export class RdDActor extends Actor {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getBonusDegat() {
|
getBonusDegat() {
|
||||||
|
// TODO: gérer séparation et +dom créature/entité indépendament de la compétence
|
||||||
return Misc.toInt(this.data.data.attributs.plusdom.value);
|
return Misc.toInt(this.data.data.attributs.plusdom.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,54 +170,13 @@ export class RdDActor extends Actor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async performRoll(rollData, attacker = undefined) {
|
|
||||||
rollData.surprise = this.getSurprise();
|
|
||||||
|
|
||||||
// Manage weapon categories when parrying (cf. page 115 )
|
|
||||||
if (rollData.arme && rollData.attackerRoll) { // Manage parade depending on weapon type, and change roll results
|
|
||||||
let attCategory = RdDItemArme.getCategorieArme(rollData.attackerRoll.arme);
|
|
||||||
let defCategory = RdDItemArme.getCategorieArme(rollData.arme);
|
|
||||||
if (defCategory == "bouclier")
|
|
||||||
rollData.needSignificative = false;
|
|
||||||
else if (attCategory != defCategory)
|
|
||||||
rollData.needSignificative = true;
|
|
||||||
// Do we need to make resistance roll for defender ?
|
|
||||||
if (attCategory.match("epee") && (defCategory == "hache" || defCategory == "lance"))
|
|
||||||
rollData.needResist = true;
|
|
||||||
}
|
|
||||||
if (!this.isEntiteCauchemar() && rollData.particuliereAttaque == "finesse") {
|
|
||||||
rollData.needSignificative = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// garder le résultat
|
|
||||||
await RdDResolutionTable.rollData(rollData);
|
|
||||||
|
|
||||||
//console.log("performRoll", rollData)
|
|
||||||
if ( !rollData.attackerRoll) {// Store in the registry if not a defense roll
|
|
||||||
game.system.rdd.rollDataHandler[this.data._id] = rollData;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rollData.rolled.isPart && rollData.arme && !rollData.attackerRoll) { // Réussite particulière avec attaque -> choix !
|
|
||||||
let message = "<strong>Réussite particulière en attaque</strong>";
|
|
||||||
message = message + "<br><a class='chat-card-button' id='particuliere-attaque' data-mode='force' data-attackerId='" + this.data._id + "'>Attaquer en Force</a>";
|
|
||||||
// Finesse et Rapidité seulement en mêlée et si la difficulté libre est de -1 minimum
|
|
||||||
if (rollData.selectedCarac.label == "Mêlée" && rollData.diffLibre < 0 ) {
|
|
||||||
message = message + "<br><a class='chat-card-button' id='particuliere-attaque' data-mode='rapidite' data-attackerId='"+ this.data._id + "'>Attaquer en Rapidité</a>";
|
|
||||||
message = message + "<br><a class='chat-card-button' id='particuliere-attaque' data-mode='finesse' data-attackerId='"+ this.data._id + "'>Attaquer en Finesse</a>";
|
|
||||||
}
|
|
||||||
ChatMessage.create( {content : message, whisper: ChatMessage.getWhisperRecipients( this.name ) } );
|
|
||||||
} else {
|
|
||||||
this.continueRoll(rollData, attacker);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async computeDeteriorationArme( rollData ) {
|
async computeDeteriorationArme( rollData ) {
|
||||||
const attackerRoll = rollData.attackerRoll;
|
const attackerRoll = rollData.attackerRoll;
|
||||||
if (rollData.arme && attackerRoll) { // C'est une parade
|
if (rollData.arme && attackerRoll) { // C'est une parade
|
||||||
// Est-ce que l'attaque est une particulière, en force ou charge et que l'attaque n'en est pas une ?
|
// Est-ce que l'attaque est une particulière, en force ou charge et que l'attaque n'en est pas une ?
|
||||||
if ( (rollData.needResist || attackerRoll.particuliereAttaque == 'force' || attackerRoll.isCharge)
|
if ( (rollData.needResist || attackerRoll.particuliereAttaque == 'force' || attackerRoll.tactique == 'charge')
|
||||||
&& !rollData.rolled.isPart ) {
|
&& !rollData.rolled.isPart ) {
|
||||||
const dmg = attackerRoll.dmg.dmgArme + attackerRoll.dmg.dmgActor;
|
const dmg = attackerRoll.dmg.dmgArme + attackerRoll.dmg.dmgActor;
|
||||||
let resistance = Misc.toInt(rollData.arme.data.resistance);
|
let resistance = Misc.toInt(rollData.arme.data.resistance);
|
||||||
@ -252,7 +212,7 @@ export class RdDActor extends Actor {
|
|||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async computeRecul( rollData, encaisser = undefined ) { // Calcul du recul (p. 132)
|
async computeRecul( rollData, encaisser = undefined ) { // Calcul du recul (p. 132)
|
||||||
if ( rollData.arme || encaisser ) {
|
if ( rollData.arme || encaisser ) {
|
||||||
if ( (rollData.attackerRoll.particuliereAttaque && rollData.attackerRoll.particuliereAttaque == 'force') || rollData.attackerRoll.isCharge) {
|
if ( (rollData.attackerRoll.particuliereAttaque && rollData.attackerRoll.particuliereAttaque == 'force') || rollData.attackerRoll.tactique == 'charge') {
|
||||||
let reculNiveau = Misc.toInt(this.data.data.carac.taille.value) - (rollData.attackerRoll.forceValue+rollData.attackerRoll.arme.data.dommagesReels);
|
let reculNiveau = Misc.toInt(this.data.data.carac.taille.value) - (rollData.attackerRoll.forceValue+rollData.attackerRoll.arme.data.dommagesReels);
|
||||||
let recul = await RdDResolutionTable.roll( 10, reculNiveau );
|
let recul = await RdDResolutionTable.roll( 10, reculNiveau );
|
||||||
let msg = "";
|
let msg = "";
|
||||||
@ -273,103 +233,12 @@ export class RdDActor extends Actor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
async continueRoll(rollData, attacker = undefined) {
|
|
||||||
let rolled = rollData.rolled;
|
|
||||||
let quality = rolled.quality
|
|
||||||
|
|
||||||
console.log(">>> ROLL", rollData, rolled);
|
|
||||||
this._appliquerAjoutExperience(rollData)
|
|
||||||
|
|
||||||
let resumeCompetence = (rollData.competence) ? rollData.competence.name : (rollData.diffLibre + rollData.diffConditions);
|
|
||||||
let explications = "<br>Points de taches : " + rolled.ptTache + ", ajustement qualité: " + rolled.ptQualite;
|
|
||||||
|
|
||||||
// Fight management !
|
|
||||||
let defenseMsg;
|
|
||||||
let encaisser = false;
|
|
||||||
if (rollData.arme || (rollData.competence && rollData.competence.name.toLowerCase() == 'esquive') ) {
|
|
||||||
explications = ""
|
|
||||||
// In case of fight, replace the message per dommages + localization. it indicates if result is OK or not
|
|
||||||
if (rollData.attackerRoll) { // Defense case !
|
|
||||||
if (rolled.isSign || (!rollData.needSignificative && rolled.isSuccess)) {
|
|
||||||
await this.computeDeteriorationArme( rollData );
|
|
||||||
explications += "<br><strong>Attaque parée/esquivée !</strong>";
|
|
||||||
} else {
|
|
||||||
explications += "<br><strong>Esquive/Parade échouée, encaissement !</strong>";
|
|
||||||
if (rollData.needSignificative)
|
|
||||||
explications += " Significative nécessaire!";
|
|
||||||
}
|
|
||||||
encaisser = rollData.needSignificative ? !rolled.isSign : !rolled.isSuccess;
|
|
||||||
await this.computeRecul( rollData, encaisser );
|
|
||||||
} else { // This is the attack roll!
|
|
||||||
if (rolled.isSuccess) {
|
|
||||||
let target = this._getTarget();
|
|
||||||
if (await this.targetEntiteNonAccordee(target, 'avant-defense')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message spécial pour la rapidité, qui reste difficile à gérer automatiquement
|
|
||||||
if ( rollData.particuliereAttaque == 'rapidite') {
|
|
||||||
ChatMessage.create( { content: "Vous avez attaqué en Rapidité. Ce cas n'est pas géré autmatiquement, donc suivez les directives de votre MJ pour gérer ce cas.",
|
|
||||||
whisper: ChatMessage.getWhisperRecipients( this.name ) } );
|
|
||||||
}
|
|
||||||
|
|
||||||
rollData.dmg = RdDCombat.calculBonusDegats(rollData, this);
|
|
||||||
|
|
||||||
if (target)
|
|
||||||
{
|
|
||||||
rollData.mortalite = RdDActor._calculMortaliteEncaissement(rollData, target);
|
|
||||||
defenseMsg = RdDUtility.buildDefenseChatCard(this, target, rollData);
|
|
||||||
explications += "<br><strong>Cible</strong> : " + target.actor.data.name;
|
|
||||||
}
|
|
||||||
explications += "<br>Encaissement : " + rollData.degats + "<br>Localisation : " + rollData.dmg.loc.label;
|
|
||||||
} else {
|
|
||||||
explications = "<br>Echec ! Pas de dégâts";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save it for fight in the flags area
|
|
||||||
game.system.rdd.rollDataHandler[this.data._id] = duplicate(rollData);
|
|
||||||
|
|
||||||
// Final chat message
|
|
||||||
let chatOptions = {
|
|
||||||
content: "<strong>Test : " + rollData.selectedCarac.label + " / " + resumeCompetence + "</strong>"
|
|
||||||
+ "<br>Difficultés <strong>libre : " + rollData.diffLibre + "</strong> / conditions : " + Misc.toSignedString(rollData.diffConditions) +" / état : " + rollData.etat
|
|
||||||
+ RdDResolutionTable.explain(rolled)
|
|
||||||
+ explications
|
|
||||||
}
|
|
||||||
|
|
||||||
ChatUtility.chatWithRollMode(chatOptions, this.name)
|
|
||||||
|
|
||||||
// This an attack, generate the defense message
|
|
||||||
if (defenseMsg) {
|
|
||||||
defenseMsg.rollData = duplicate(rollData);
|
|
||||||
if (defenseMsg.toSocket) {
|
|
||||||
game.socket.emit("system.foundryvtt-reve-de-dragon", {
|
|
||||||
msg: "msg_defense",
|
|
||||||
data: defenseMsg
|
|
||||||
});
|
|
||||||
if ( game.user.isGM ) { // Always push the message to the MJ
|
|
||||||
ChatMessage.create(defenseMsg);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
defenseMsg.whisper = [game.user];
|
|
||||||
ChatMessage.create(defenseMsg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get damages!
|
|
||||||
if (encaisser) {
|
|
||||||
this.encaisserDommages(rollData.attackerRoll, attacker);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
getSurprise() {
|
getSurprise() {
|
||||||
if (this.isEntiteCauchemar()) {
|
if (this.isEntiteCauchemar()) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
// TODO: gérer une liste de flags demi-surprise (avec icône sur le token)?
|
||||||
if ( this.data.data.sante.sonne.value) {
|
if ( this.data.data.sante.sonne.value) {
|
||||||
return 'demi';
|
return 'demi';
|
||||||
}
|
}
|
||||||
@ -386,13 +255,6 @@ export class RdDActor extends Actor {
|
|||||||
return this.getSurprise() == 'totale';
|
return this.getSurprise() == 'totale';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static _calculMortaliteEncaissement(rollData, target) {
|
|
||||||
const mortalite = target.actor.isEntiteCauchemar() ? "cauchemar" : (rollData.mortalite ? rollData.mortalite : "mortel");
|
|
||||||
console.log("Mortalité : ", mortalite, target.actor.data.type);
|
|
||||||
return mortalite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async dormirChateauDormant() {
|
async dormirChateauDormant() {
|
||||||
let message = {
|
let message = {
|
||||||
@ -1905,7 +1767,7 @@ export class RdDActor extends Actor {
|
|||||||
armure: armure
|
armure: armure
|
||||||
}).roll();
|
}).roll();
|
||||||
RdDDice.show(rollEncaissement);
|
RdDDice.show(rollEncaissement);
|
||||||
let result = RdDUtility.computeBlessuresSante(rollEncaissement.total, attackerRoll.mortalite, attackerRoll.dmg.loc);
|
let result = RdDUtility.computeBlessuresSante(rollEncaissement.total, attackerRoll.dmg.mortalite, attackerRoll.dmg.loc);
|
||||||
result.endurance = Math.max(result.endurance, -Number(this.data.data.sante.endurance.value));
|
result.endurance = Math.max(result.endurance, -Number(this.data.data.sante.endurance.value));
|
||||||
await this.santeIncDec("vie", result.vie);
|
await this.santeIncDec("vie", result.vie);
|
||||||
await this.santeIncDec("endurance", result.endurance, (result.critiques > 0));
|
await this.santeIncDec("endurance", result.endurance, (result.critiques > 0));
|
||||||
|
@ -44,26 +44,34 @@ export class RdDItemArme extends Item {
|
|||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static armeUneOuDeuxMains(arme, aUneMain) {
|
static armeUneOuDeuxMains(arme, aUneMain) {
|
||||||
arme.data.unemain = arme.data.unemain || !arme.data.deuxmains;
|
if (arme) {
|
||||||
const uneOuDeuxMains = arme.data.unemain && arme.data.deuxmains;
|
arme.data.unemain = arme.data.unemain || !arme.data.deuxmains;
|
||||||
const containsSlash = !Number.isInteger(arme.data.dommages) && arme.data.dommages.includes("/");
|
const uneOuDeuxMains = arme.data.unemain && arme.data.deuxmains;
|
||||||
if (containsSlash) { // Sanity check
|
const containsSlash = !Number.isInteger(arme.data.dommages) && arme.data.dommages.includes("/");
|
||||||
arme = duplicate(arme);
|
if (containsSlash) { // Sanity check
|
||||||
|
arme = duplicate(arme);
|
||||||
|
|
||||||
const tableauDegats = arme.data.dommages.split("/");
|
const tableauDegats = arme.data.dommages.split("/");
|
||||||
if (aUneMain)
|
if (aUneMain)
|
||||||
arme.data.dommagesReels = Number(tableauDegats[0]);
|
arme.data.dommagesReels = Number(tableauDegats[0]);
|
||||||
else // 2 mains
|
else // 2 mains
|
||||||
arme.data.dommagesReels = Number(tableauDegats[1]);
|
arme.data.dommagesReels = Number(tableauDegats[1]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
arme.data.dommagesReels = Number(arme.data.dommages);
|
arme.data.dommagesReels = Number(arme.data.dommages);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uneOuDeuxMains != containsSlash) {
|
if (uneOuDeuxMains != containsSlash) {
|
||||||
ui.notifications.info("Les dommages de l'arme à 1/2 mains " + arme.name + " ne sont pas corrects (ie sous la forme X/Y)");
|
ui.notifications.info("Les dommages de l'arme à 1/2 mains " + arme.name + " ne sont pas corrects (ie sous la forme X/Y)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return arme;
|
return arme;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static mainsNues() {
|
||||||
|
return {
|
||||||
|
name: "Mains nues",
|
||||||
|
data: { unemain: true, deuxmains: false, dommages: 0, dommagesReels: 0, mortalite: 'non-mortel' }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
86
module/rdd-bonus.js
Normal file
86
module/rdd-bonus.js
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import { RdDUtility } from "./rdd-utility.js";
|
||||||
|
|
||||||
|
const conditionsTactiques = [
|
||||||
|
{ type: '', descr: '', dmg: 0, attaque: 0, parade: 0, esquive: true },
|
||||||
|
{ type: 'charge', descr: 'Charge', dmg: 2, attaque: 4, parade: -4, esquive: false },
|
||||||
|
{ type: 'feinte', descr: 'Feinte', dmg: 1, attaque: 1, parade: 0, esquive: true },
|
||||||
|
{ type: 'pret', descr: 'prêt', dmg: 0, attaque: 0, parade: 0, esquive: true },
|
||||||
|
{ type: 'demi', descr: 'Demi-surprise', dmg: 1, attaque: 0, parade: 0, esquive: true },
|
||||||
|
{ type: 'totale', descr: 'Surprise totale', dmg: 10, attaque: 6, parade: 0, esquive: true },
|
||||||
|
];
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
export class RdDBonus {
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static _find(condition) {
|
||||||
|
return conditionsTactiques.find(e => e.type == condition) || conditionsTactiques.find(e => e.type == 'pret');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static dmg(rollData, dmgActor, isCauchemar = false) {
|
||||||
|
let dmg = { total: 0, loc: RdDUtility.getLocalisation() };
|
||||||
|
if (rollData.arme && rollData.arme.name.toLowerCase() == "esquive") {
|
||||||
|
// Specific case management
|
||||||
|
ui.notifications.warn("Calcul de bonus dégats sur eswquive");
|
||||||
|
} else {
|
||||||
|
dmg.dmgArme = RdDBonus._dmgArme(rollData);
|
||||||
|
dmg.ignoreArmure = 0; // TODO: calculer pour arcs et arbaletes, gérer pour lmes créatures
|
||||||
|
dmg.dmgTactique = RdDBonus.dmgBonus(rollData.tactique);
|
||||||
|
dmg.dmgParticuliere = RdDBonus._dmgParticuliere(rollData);
|
||||||
|
dmg.dmgSurprise = RdDBonus.dmgBonus(rollData.surpriseDefenseur);
|
||||||
|
dmg.dmgActor = rollData.selectedCarac ? RdDBonus._dmgPerso(dmgActor, rollData.selectedCarac.label, dmg.dmgArme) : 0;
|
||||||
|
dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere;
|
||||||
|
dmg.mortalite = RdDBonus._calculMortalite(rollData, isCauchemar)
|
||||||
|
}
|
||||||
|
return dmg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static description(condition) {
|
||||||
|
return RdDBonus._find(condition).descr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static dmgBonus(condition) {
|
||||||
|
return RdDBonus._find(condition).dmg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static bonusAttaque(condition) {
|
||||||
|
return RdDBonus._find(condition).attaque;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static _calculMortalite(rollData, isCauchemar) {
|
||||||
|
if (isCauchemar){
|
||||||
|
return "cauchemar";
|
||||||
|
}if (rollData.dmg && rollData.dmg.mortalite) {
|
||||||
|
return rollData.dmg.mortalite;
|
||||||
|
}
|
||||||
|
if (rollData.arme && rollData.arme.data.mortalite) {
|
||||||
|
return rollData.arme.data.mortalite;
|
||||||
|
}
|
||||||
|
return "mortel";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static _dmgArme(rollData) {
|
||||||
|
return rollData.arme ? parseInt(rollData.arme.data.dommages) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static _dmgPerso(dmgActor, categorie, dmgArme) {
|
||||||
|
switch (categorie) {
|
||||||
|
case "Tir": return 0;
|
||||||
|
case "Lancer": return Math.max(0, Math.min(dmgArme, dmgActor));
|
||||||
|
}
|
||||||
|
return dmgActor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static _dmgParticuliere(rollData) {
|
||||||
|
return rollData.particuliereAttaque == 'force' ? 5 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,11 +1,10 @@
|
|||||||
import { RdDActor } from "./actor.js";
|
|
||||||
import { ChatUtility } from "./chat-utility.js";
|
import { ChatUtility } from "./chat-utility.js";
|
||||||
import { RdDItemArme } from "./item-arme.js";
|
import { RdDItemArme } from "./item-arme.js";
|
||||||
import { RdDItemCompetence } from "./item-competence.js";
|
import { RdDItemCompetence } from "./item-competence.js";
|
||||||
import { Misc } from "./misc.js";
|
import { Misc } from "./misc.js";
|
||||||
|
import { RdDBonus } from "./rdd-bonus.js";
|
||||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||||
import { RdDRoll } from "./rdd-roll.js";
|
import { RdDRoll } from "./rdd-roll.js";
|
||||||
import { RdDUtility } from "./rdd-utility.js";
|
|
||||||
|
|
||||||
export class RdDCombat {
|
export class RdDCombat {
|
||||||
|
|
||||||
@ -75,7 +74,6 @@ export class RdDCombat {
|
|||||||
ui.notifications.warn("Action automatisée impossible, le jet de l'attaquant a été perdu (suite à un raffraichissement?)")
|
ui.notifications.warn("Action automatisée impossible, le jet de l'attaquant a été perdu (suite à un raffraichissement?)")
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO: enlever le ChatMessage?
|
|
||||||
switch (button) {
|
switch (button) {
|
||||||
case '#particuliere-attaque': return await this.choixParticuliere(rollData, event.currentTarget.attributes['data-mode'].value);
|
case '#particuliere-attaque': return await this.choixParticuliere(rollData, event.currentTarget.attributes['data-mode'].value);
|
||||||
case '#parer-button': return this.parade(rollData, event.currentTarget.attributes['data-armeid'].value);
|
case '#parer-button': return this.parade(rollData, event.currentTarget.attributes['data-armeid'].value);
|
||||||
@ -84,6 +82,41 @@ export class RdDCombat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static isEchec(rollData) {
|
||||||
|
switch (rollData.surprise) {
|
||||||
|
case 'demi': return !rollData.rolled.isSign;
|
||||||
|
case 'totale': return true;
|
||||||
|
}
|
||||||
|
return rollData.rolled.isEchec;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static isEchecTotal(rollData) {
|
||||||
|
if (rollData.arme && rollData.surprise == 'demi') {
|
||||||
|
return rollData.rolled.isEchec;
|
||||||
|
}
|
||||||
|
return rollData.rolled.isETotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static isParticuliere(rollData) {
|
||||||
|
if (rollData.arme && rollData.surprise) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return rollData.rolled.isPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
static isReussite(rollData) {
|
||||||
|
switch (rollData.surprise) {
|
||||||
|
case 'demi': return rollData.rolled.isSign;
|
||||||
|
case 'totale': return false;
|
||||||
|
}
|
||||||
|
return rollData.rolled.isSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async attaque(competence, arme) {
|
async attaque(competence, arme) {
|
||||||
if (!await this.accorderEntite('avant-attaque')) {
|
if (!await this.accorderEntite('avant-attaque')) {
|
||||||
@ -99,10 +132,10 @@ export class RdDCombat {
|
|||||||
label: 'Attaque: ' + (arme ? arme.name : competence.name),
|
label: 'Attaque: ' + (arme ? arme.name : competence.name),
|
||||||
callbacks: [
|
callbacks: [
|
||||||
this.attacker.createCallbackExperience(),
|
this.attacker.createCallbackExperience(),
|
||||||
{ condition: RdDResolutionTable.isParticuliere, action: r => this._onAttaqueParticuliere(r) },
|
{ condition: RdDCombat.isParticuliere, action: r => this._onAttaqueParticuliere(r) },
|
||||||
{ condition: r => (RdDResolutionTable.isReussite(r) && !RdDResolutionTable.isParticuliere(r)), action: r => this._onAttaqueNormale(r) },
|
{ condition: r => (RdDCombat.isReussite(r) && !RdDCombat.isParticuliere(r)), action: r => this._onAttaqueNormale(r) },
|
||||||
{ condition: RdDResolutionTable.isEchecTotal, action: r => this._onAttaqueEchecTotal(r) },
|
{ condition: RdDCombat.isEchecTotal, action: r => this._onAttaqueEchecTotal(r) },
|
||||||
{ condition: RdDResolutionTable.isEchec, action: r => this._onAttaqueEchec(r) }
|
{ condition: RdDCombat.isEchec, action: r => this._onAttaqueEchec(r) }
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
dialog.render(true);
|
dialog.render(true);
|
||||||
@ -113,16 +146,21 @@ export class RdDCombat {
|
|||||||
let rollData = {
|
let rollData = {
|
||||||
coupsNonMortels: false,
|
coupsNonMortels: false,
|
||||||
competence: competence,
|
competence: competence,
|
||||||
surprise: this.attacker.getSurprise()
|
surprise: this.attacker.getSurprise(),
|
||||||
|
surpriseDefenseur: this.defender.getSurprise()
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.attacker.isCreature()) {
|
if (this.attacker.isCreature()) {
|
||||||
this._modifieRollDataCreature(rollData, competence);
|
this._modifieRollDataCreature(rollData, competence);
|
||||||
}
|
}
|
||||||
else {
|
else if (arme) {
|
||||||
// Usual competence
|
// Usual competence
|
||||||
rollData.arme = RdDItemArme.armeUneOuDeuxMains(arme, RdDItemCompetence.isArmeUneMain(competence));
|
rollData.arme = RdDItemArme.armeUneOuDeuxMains(arme, RdDItemCompetence.isArmeUneMain(competence));
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// sans armes: à mains nues
|
||||||
|
rollData.arme = RdDItemArme.mainsNues();
|
||||||
|
}
|
||||||
return rollData;
|
return rollData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,6 +177,11 @@ export class RdDCombat {
|
|||||||
dommagesReels: competence.data.dommages
|
dommagesReels: competence.data.dommages
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// rollData.dmg = {
|
||||||
|
// dmgArme: competence.data.dommages,
|
||||||
|
// total: competence.data.dommages
|
||||||
|
// };
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
@ -172,13 +215,12 @@ export class RdDCombat {
|
|||||||
whisper: ChatMessage.getWhisperRecipients(this.attacker.name)
|
whisper: ChatMessage.getWhisperRecipients(this.attacker.name)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
rollData.dmg = RdDCombat.calculBonusDegats(rollData, this.attacker);
|
rollData.dmg = RdDBonus.dmg(rollData, this.attacker.getBonusDegat(), this.defender.isEntiteCauchemar());
|
||||||
|
|
||||||
if (this.target) {
|
if (this.target) {
|
||||||
rollData.mortalite = this._calculMortaliteEncaissement(rollData);
|
|
||||||
explications += "<br><strong>Cible</strong> : " + this.defender.data.name;
|
explications += "<br><strong>Cible</strong> : " + this.defender.data.name;
|
||||||
}
|
}
|
||||||
explications += "<br>Encaissement à "+ Misc.toSignedString(rollData.dmg.total)+ " (" + rollData.dmg.loc.label+")";
|
explications += "<br>Encaissement à " + Misc.toSignedString(rollData.dmg.total) + " (" + rollData.dmg.loc.label + ")";
|
||||||
|
|
||||||
// Save rollData for defender
|
// Save rollData for defender
|
||||||
game.system.rdd.rollDataHandler[this.attackerId] = duplicate(rollData);
|
game.system.rdd.rollDataHandler[this.attackerId] = duplicate(rollData);
|
||||||
@ -202,14 +244,16 @@ export class RdDCombat {
|
|||||||
|
|
||||||
let content = "<strong>" + this.defender.name + "</strong> doit se défendre :<span class='chat-card-button-area'>";
|
let content = "<strong>" + this.defender.name + "</strong> doit se défendre :<span class='chat-card-button-area'>";
|
||||||
|
|
||||||
// parades
|
if (this.defender.getSurprise() != 'totale') {
|
||||||
for (const arme of this._filterArmesParade(this.defender.data.items, rollData.competence.data.categorie)) {
|
// parades
|
||||||
content += "<br><a class='chat-card-button' id='parer-button' data-attackerId='" + this.attackerId + "' data-defenderTokenId='" + this.defenderTokenId + "' data-armeid='" + arme._id + "'>Parer avec " + arme.name + "</a>";
|
for (const arme of this._filterArmesParade(this.defender.data.items, rollData.competence.data.categorie)) {
|
||||||
}
|
content += "<br><a class='chat-card-button' id='parer-button' data-attackerId='" + this.attackerId + "' data-defenderTokenId='" + this.defenderTokenId + "' data-armeid='" + arme._id + "'>Parer avec " + arme.name + "</a>";
|
||||||
|
}
|
||||||
// esquive
|
|
||||||
if (rollData.competence.data.categorie == 'melee' || rollData.competence.data.categorie == "lancer" || rollData.competence.data.categorie == 'competencecreature') {
|
// esquive
|
||||||
content += "<br><a class='chat-card-button' id='esquiver-button' data-attackerId='" + this.attackerId + "' data-defenderTokenId='" + this.defenderTokenId + "'>Esquiver</a>";
|
if (rollData.competence.data.categorie == 'melee' || rollData.competence.data.categorie == "lancer" || rollData.competence.data.categorie == 'competencecreature') {
|
||||||
|
content += "<br><a class='chat-card-button' id='esquiver-button' data-attackerId='" + this.attackerId + "' data-defenderTokenId='" + this.defenderTokenId + "'>Esquiver</a>";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// encaisser
|
// encaisser
|
||||||
@ -257,13 +301,6 @@ export class RdDCombat {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* -------------------------------------------- */
|
|
||||||
_calculMortaliteEncaissement(rollData) {
|
|
||||||
const mortalite = this.defender.isEntiteCauchemar() ? "cauchemar" : (rollData.mortalite ? rollData.mortalite : "mortel");
|
|
||||||
console.log("Mortalité : ", mortalite, this.defender.data.type);
|
|
||||||
return mortalite;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
_onAttaqueEchecTotal(rollData) {
|
_onAttaqueEchecTotal(rollData) {
|
||||||
console.log("RdDCombat.onEchecTotal >>>", rollData);
|
console.log("RdDCombat.onEchecTotal >>>", rollData);
|
||||||
@ -306,10 +343,10 @@ export class RdDCombat {
|
|||||||
label: 'Parade: ' + (arme ? arme.name : rollData.competence.name),
|
label: 'Parade: ' + (arme ? arme.name : rollData.competence.name),
|
||||||
callbacks: [
|
callbacks: [
|
||||||
this.defender.createCallbackExperience(),
|
this.defender.createCallbackExperience(),
|
||||||
{ condition: RdDResolutionTable.isParticuliere, action: r => this._onParadeParticuliere(r) },
|
{ condition: RdDCombat.isParticuliere, action: r => this._onParadeParticuliere(r) },
|
||||||
{ condition: RdDResolutionTable.isReussite, action: r => this._onParadeNormale(r) },
|
{ condition: RdDCombat.isReussite, action: r => this._onParadeNormale(r) },
|
||||||
{ condition: RdDResolutionTable.isEchecTotal, action: r => this._onParadeEchecTotal(r) },
|
{ condition: RdDCombat.isEchecTotal, action: r => this._onParadeEchecTotal(r) },
|
||||||
{ condition: RdDResolutionTable.isEchec, action: r => this._onParadeEchec(r) }
|
{ condition: RdDCombat.isEchec, action: r => this._onParadeEchec(r) }
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
dialog.render(true);
|
dialog.render(true);
|
||||||
@ -334,6 +371,7 @@ export class RdDCombat {
|
|||||||
competence: competence,
|
competence: competence,
|
||||||
arme: arme.data,
|
arme: arme.data,
|
||||||
surprise: this.defender.getSurprise(),
|
surprise: this.defender.getSurprise(),
|
||||||
|
surpriseDefenseur: this.defender.getSurprise(),
|
||||||
needSignificative: this._needSignificative(attackerRoll) || RdDItemArme.needParadeSignificative(armeAttaque, armeParade),
|
needSignificative: this._needSignificative(attackerRoll) || RdDItemArme.needParadeSignificative(armeAttaque, armeParade),
|
||||||
needResist: this._needResist(armeAttaque, armeParade),
|
needResist: this._needResist(armeAttaque, armeParade),
|
||||||
carac: this.defender.data.data.carac
|
carac: this.defender.data.data.carac
|
||||||
@ -401,7 +439,7 @@ export class RdDCombat {
|
|||||||
console.log("RdDCombat._onParadeEchec >>>", rollData);
|
console.log("RdDCombat._onParadeEchec >>>", rollData);
|
||||||
|
|
||||||
let explications = "<br><strong>Parade échouée, encaissement !</strong> ";
|
let explications = "<br><strong>Parade échouée, encaissement !</strong> ";
|
||||||
explications += RdDCombat.descriptionSurprise(rollData.surprise);
|
explications += RdDBonus.description(rollData.surprise);
|
||||||
if (rollData.needSignificative) {
|
if (rollData.needSignificative) {
|
||||||
explications += " Significative nécessaire!";
|
explications += " Significative nécessaire!";
|
||||||
}
|
}
|
||||||
@ -436,10 +474,10 @@ export class RdDCombat {
|
|||||||
label: 'Esquiver',
|
label: 'Esquiver',
|
||||||
callbacks: [
|
callbacks: [
|
||||||
this.defender.createCallbackExperience(),
|
this.defender.createCallbackExperience(),
|
||||||
{ condition: RdDResolutionTable.isParticuliere, action: r => this._onEsquiveParticuliere(r) },
|
{ condition: RdDCombat.isParticuliere, action: r => this._onEsquiveParticuliere(r) },
|
||||||
{ condition: RdDResolutionTable.isReussite, action: r => this._onEsquiveNormale(r) },
|
{ condition: RdDCombat.isReussite, action: r => this._onEsquiveNormale(r) },
|
||||||
{ condition: RdDResolutionTable.isEchecTotal, action: r => this._onEsquiveEchecTotal(r) },
|
{ condition: RdDCombat.isEchecTotal, action: r => this._onEsquiveEchecTotal(r) },
|
||||||
{ condition: RdDResolutionTable.isEchec, action: r => this._onEsquiveEchec(r) },
|
{ condition: RdDCombat.isEchec, action: r => this._onEsquiveEchec(r) },
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
dialog.render(true);
|
dialog.render(true);
|
||||||
@ -452,6 +490,7 @@ export class RdDCombat {
|
|||||||
attackerRoll: attackerRoll,
|
attackerRoll: attackerRoll,
|
||||||
competence: competence,
|
competence: competence,
|
||||||
surprise: this.defender.getSurprise(),
|
surprise: this.defender.getSurprise(),
|
||||||
|
surpriseDefenseur: this.defender.getSurprise(),
|
||||||
needSignificative: this._needSignificative(attackerRoll),
|
needSignificative: this._needSignificative(attackerRoll),
|
||||||
carac: this.defender.data.data.carac
|
carac: this.defender.data.data.carac
|
||||||
};
|
};
|
||||||
@ -497,7 +536,7 @@ export class RdDCombat {
|
|||||||
console.log("RdDCombat._onEsquiveEchec >>>", rollData);
|
console.log("RdDCombat._onEsquiveEchec >>>", rollData);
|
||||||
|
|
||||||
let explications = "<br><strong>Esquive échouée, encaissement !</strong> ";
|
let explications = "<br><strong>Esquive échouée, encaissement !</strong> ";
|
||||||
explications += RdDCombat.descriptionSurprise(rollData.surprise);
|
explications += RdDBonus.description(rollData.surprise);
|
||||||
if (rollData.needSignificative) {
|
if (rollData.needSignificative) {
|
||||||
explications += " Significative nécessaire!";
|
explications += " Significative nécessaire!";
|
||||||
}
|
}
|
||||||
@ -567,65 +606,4 @@ export class RdDCombat {
|
|||||||
return rolled.isSuccess;
|
return rolled.isSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static calculBonusDegats(rollData, actor) {
|
|
||||||
let dmg = { total: 0, loc: RdDUtility.getLocalisation() };
|
|
||||||
if (rollData.arme.name.toLowerCase() == "esquive") {
|
|
||||||
// Specific case management
|
|
||||||
ui.notifications.warn("Calcul de bonus dégats sur eswquive")
|
|
||||||
return dmg;
|
|
||||||
}
|
|
||||||
dmg.dmgArme = RdDCombat._dmgArme(rollData);
|
|
||||||
dmg.ignoreArmure = 0; // TODO: calculer pour arcs et arbaletes, gérer pour lmes créatures
|
|
||||||
dmg.dmgTactique= RdDCombat._dmgTactique(rollData);
|
|
||||||
dmg.dmgParticuliere= RdDCombat._dmgParticuliere(rollData);
|
|
||||||
dmg.dmgSurprise= RdDCombat._dmgSurprise(rollData);
|
|
||||||
dmg.dmgActor = RdDCombat._dmgActor(actor.getBonusDegat(), rollData.selectedCarac.label, dmg.dmgArme);
|
|
||||||
dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere;
|
|
||||||
return dmg;
|
|
||||||
}
|
|
||||||
|
|
||||||
static _dmgArme(rollData) {
|
|
||||||
return parseInt(rollData.arme.data.dommages);
|
|
||||||
}
|
|
||||||
|
|
||||||
static _dmgActor(bonusDegat, categorie, dmgArme) {
|
|
||||||
switch (categorie) {
|
|
||||||
case "Tir": return 0;
|
|
||||||
case "Lancer": return Math.max(0, Math.min(dmgArme, bonusDegat));
|
|
||||||
}
|
|
||||||
return bonusDegat;
|
|
||||||
}
|
|
||||||
|
|
||||||
static _dmgTactique(rollData) {
|
|
||||||
return rollData.isCharge ? 2 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static _dmgParticuliere(rollData) {
|
|
||||||
return rollData.particuliereAttaque == 'force' ? 5 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static _dmgSurprise(rollData) {
|
|
||||||
if (rollData.surprise) {
|
|
||||||
switch (rollData.surprise) {
|
|
||||||
case 'demi': return 1;
|
|
||||||
case 'totale': return 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
static descriptionSurprise(surprise) {
|
|
||||||
if (surprise) {
|
|
||||||
switch (surprise) {
|
|
||||||
case 'demi': return 'demi-surprise';
|
|
||||||
case 'totale': return 'surprise totale';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -242,10 +242,9 @@ export class RdDResolutionTable {
|
|||||||
static buildHTMLResults( caracValue, levelValue) {
|
static buildHTMLResults( caracValue, levelValue) {
|
||||||
let cell = this.computeChances( caracValue, levelValue);
|
let cell = this.computeChances( caracValue, levelValue);
|
||||||
let descr = $('<span class="span-valeur competence-label">');
|
let descr = $('<span class="span-valeur competence-label">');
|
||||||
descr.append("Réussite : "+cell.score+ " - Particulière : " + cell.part + " - Significative : " + cell.sign);
|
descr.append("Particulière : " + cell.part+ " - Significative : " + cell.sign + " - Réussite : "+cell.score);
|
||||||
descr.append("<br>Echec Particulier : " + cell.epart + " - Echec Total : " + cell.etotal );
|
descr.append("<br>Echec Particulier : " + cell.epart + " - Echec Total : " + cell.etotal );
|
||||||
descr.append("</span>");
|
descr.append("</span>");
|
||||||
|
|
||||||
return descr;
|
return descr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,8 +37,8 @@ export class RdDEncaisser extends Dialog {
|
|||||||
dmg:{
|
dmg:{
|
||||||
total: Number(this.modifier),
|
total: Number(this.modifier),
|
||||||
loc: { result: 0, label: "Corps" },
|
loc: { result: 0, label: "Corps" },
|
||||||
},
|
mortalite: mortalite
|
||||||
mortalite: mortalite
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
import { HtmlUtility } from "./html-utility.js";
|
import { HtmlUtility } from "./html-utility.js";
|
||||||
import { RdDItemSort } from "./item-sort.js";
|
import { RdDItemSort } from "./item-sort.js";
|
||||||
import { Misc } from "./misc.js";
|
import { Misc } from "./misc.js";
|
||||||
|
import { RdDBonus } from "./rdd-bonus.js";
|
||||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extend the base Dialog entity to select roll parameters
|
* Extend the base Dialog entity to select roll parameters
|
||||||
* @extends {Dialog}
|
* @extends {Dialog}
|
||||||
*/
|
*/
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
export class RdDRoll extends Dialog {
|
export class RdDRoll extends Dialog {
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static async create(actor, rollData, dialogConfig, ...actions) {
|
static async create(actor, rollData, dialogConfig, ...actions) {
|
||||||
|
|
||||||
RdDRoll._ensureCorrectActions(actions);
|
RdDRoll._ensureCorrectActions(actions);
|
||||||
@ -25,7 +26,7 @@ export class RdDRoll extends Dialog {
|
|||||||
return new RdDRoll(actor, rollData, html, options, actions);
|
return new RdDRoll(actor, rollData, html, options, actions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static _setDefaultOptions(actor, rollData) {
|
static _setDefaultOptions(actor, rollData) {
|
||||||
|
|
||||||
let defaultRollData = {
|
let defaultRollData = {
|
||||||
@ -38,7 +39,7 @@ export class RdDRoll extends Dialog {
|
|||||||
diffLibre: 0,
|
diffLibre: 0,
|
||||||
editLibre: true,
|
editLibre: true,
|
||||||
editConditions: true,
|
editConditions: true,
|
||||||
forceValue : actor.getForceValue(),
|
forceValue: actor.getForceValue(),
|
||||||
malusArmureValue: (actor.type == 'personnage ' && actor.data.data.attributs && actor.data.data.attributs.malusarmure) ? actor.data.data.attributs.malusarmure.value : 0,
|
malusArmureValue: (actor.type == 'personnage ' && actor.data.data.attributs && actor.data.data.attributs.malusarmure) ? actor.data.data.attributs.malusarmure.value : 0,
|
||||||
surencMalusFlag: actor.type == 'personnage ' ? (actor.data.data.compteurs.surenc.value < 0) : false,
|
surencMalusFlag: actor.type == 'personnage ' ? (actor.data.data.compteurs.surenc.value < 0) : false,
|
||||||
surencMalusValue: actor.type == 'personnage ' ? actor.data.data.compteurs.surenc.value : 0,
|
surencMalusValue: actor.type == 'personnage ' ? actor.data.data.compteurs.surenc.value : 0,
|
||||||
@ -48,10 +49,10 @@ export class RdDRoll extends Dialog {
|
|||||||
encValueForNatation: actor.encombrementTotal ? Math.floor(actor.encombrementTotal) : 0,
|
encValueForNatation: actor.encombrementTotal ? Math.floor(actor.encombrementTotal) : 0,
|
||||||
ajustementAstrologique: actor.ajustementAstrologique()
|
ajustementAstrologique: actor.ajustementAstrologique()
|
||||||
}
|
}
|
||||||
mergeObject(rollData, defaultRollData, { overwrite: false } );
|
mergeObject(rollData, defaultRollData, { overwrite: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
static _ensureCorrectActions(actions) {
|
static _ensureCorrectActions(actions) {
|
||||||
if (actions.length == 0) {
|
if (actions.length == 0) {
|
||||||
throw 'No action defined';
|
throw 'No action defined';
|
||||||
@ -63,7 +64,7 @@ export class RdDRoll extends Dialog {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
constructor(actor, rollData, html, options, actions) {
|
constructor(actor, rollData, html, options, actions) {
|
||||||
let conf = {
|
let conf = {
|
||||||
title: actions[0].label,
|
title: actions[0].label,
|
||||||
@ -81,7 +82,7 @@ export class RdDRoll extends Dialog {
|
|||||||
this.rollData = rollData;
|
this.rollData = rollData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
async onAction(action, html) {
|
async onAction(action, html) {
|
||||||
await RdDResolutionTable.rollData(this.rollData);
|
await RdDResolutionTable.rollData(this.rollData);
|
||||||
console.log("RdDRoll -=>", this.rollData, this.rollData.rolled);
|
console.log("RdDRoll -=>", this.rollData, this.rollData.rolled);
|
||||||
@ -101,19 +102,26 @@ export class RdDRoll extends Dialog {
|
|||||||
this.bringToTop();
|
this.bringToTop();
|
||||||
|
|
||||||
var rollData = this.rollData;
|
var rollData = this.rollData;
|
||||||
|
var actor = this.actor;
|
||||||
|
|
||||||
function updateRollResult(rollData) {
|
function updateRollResult(rollData) {
|
||||||
let caracValue = parseInt(rollData.selectedCarac.value)
|
let caracValue = parseInt(rollData.selectedCarac.value)
|
||||||
let rollLevel = RdDRoll._computeFinalLevel(rollData);
|
let rollLevel = RdDRoll._computeFinalLevel(rollData);
|
||||||
|
rollData.dmg = rollData.attackerRoll ? rollData.attackerRoll.dmg : RdDBonus.dmg(rollData, actor.getBonusDegat());
|
||||||
rollData.finalLevel = rollLevel;
|
rollData.finalLevel = rollLevel;
|
||||||
rollData.caracValue = caracValue
|
rollData.caracValue = caracValue;
|
||||||
|
rollData.diffConditions = RdDBonus.bonusAttaque(rollData.surpriseDefenseur);
|
||||||
|
rollData.coupsNonMortels = (rollData.attackerRoll ? rollData.attackerRoll.dmg.mortalite : rollData.dmg.mortalite) == 'non-mortel';
|
||||||
|
let dmgText = Misc.toSignedString(rollData.dmg.total);
|
||||||
|
if (rollData.coupsNonMortels) {
|
||||||
|
dmgText = '(' + dmgText + ')';
|
||||||
|
}
|
||||||
|
|
||||||
HtmlUtility._showControlWhen(".etat-general", !RdDRoll._isIgnoreEtatGeneral(rollData));
|
HtmlUtility._showControlWhen(".etat-general", !RdDRoll._isIgnoreEtatGeneral(rollData));
|
||||||
|
|
||||||
// Sort management
|
// Sort management
|
||||||
if (rollData.selectedSort) {
|
if (rollData.selectedSort) {
|
||||||
rollData.bonus = RdDItemSort.getCaseBonus( rollData.selectedSort, rollData.coord ),
|
rollData.bonus = RdDItemSort.getCaseBonus(rollData.selectedSort, rollData.coord),
|
||||||
//console.log("Toggle show/hide", rollData.selectedSort);
|
//console.log("Toggle show/hide", rollData.selectedSort);
|
||||||
HtmlUtility._showControlWhen("#div-sort-difficulte", RdDItemSort.isDifficulteVariable(rollData.selectedSort))
|
HtmlUtility._showControlWhen("#div-sort-difficulte", RdDItemSort.isDifficulteVariable(rollData.selectedSort))
|
||||||
HtmlUtility._showControlWhen("#div-sort-ptreve", RdDItemSort.isCoutVariable(rollData.selectedSort))
|
HtmlUtility._showControlWhen("#div-sort-ptreve", RdDItemSort.isCoutVariable(rollData.selectedSort))
|
||||||
@ -122,6 +130,9 @@ export class RdDRoll extends Dialog {
|
|||||||
// Mise à jour valeurs
|
// Mise à jour valeurs
|
||||||
$("#roll-param").text(rollData.selectedCarac.value + " / " + Misc.toSignedString(rollData.finalLevel));
|
$("#roll-param").text(rollData.selectedCarac.value + " / " + Misc.toSignedString(rollData.finalLevel));
|
||||||
$("#compdialogTitle").text(RdDRoll._getTitle(rollData));
|
$("#compdialogTitle").text(RdDRoll._getTitle(rollData));
|
||||||
|
$('#coupsNonMortels').prop('checked', rollData.coupsNonMortels);
|
||||||
|
$("#dmg-arme-actor").text(dmgText);
|
||||||
|
$("#defenseur-surprise").text(RdDBonus.description(rollData.surpriseDefenseur));
|
||||||
$(".table-resolution").remove();
|
$(".table-resolution").remove();
|
||||||
$("#resolutionTable").append(RdDResolutionTable.buildHTMLTableExtract(caracValue, rollLevel));
|
$("#resolutionTable").append(RdDResolutionTable.buildHTMLTableExtract(caracValue, rollLevel));
|
||||||
$(".span-valeur").remove();
|
$(".span-valeur").remove();
|
||||||
@ -168,7 +179,7 @@ export class RdDRoll extends Dialog {
|
|||||||
html.find('#sort').change((event) => {
|
html.find('#sort').change((event) => {
|
||||||
let sortKey = Misc.toInt(event.currentTarget.value);
|
let sortKey = Misc.toInt(event.currentTarget.value);
|
||||||
this.rollData.selectedSort = rollData.sortList[sortKey]; // Update the selectedCarac
|
this.rollData.selectedSort = rollData.sortList[sortKey]; // Update the selectedCarac
|
||||||
this.rollData.bonus = RdDItemSort.getCaseBonus( rollData.selectedSort, rollData.coord );
|
this.rollData.bonus = RdDItemSort.getCaseBonus(rollData.selectedSort, rollData.coord);
|
||||||
RdDItemSort.setCoutReveReel(rollData.selectedSort);
|
RdDItemSort.setCoutReveReel(rollData.selectedSort);
|
||||||
//console.log("RdDRollSelectDialog - Sort selection", rollData.selectedSort);
|
//console.log("RdDRollSelectDialog - Sort selection", rollData.selectedSort);
|
||||||
updateRollResult(rollData);
|
updateRollResult(rollData);
|
||||||
@ -186,10 +197,12 @@ export class RdDRoll extends Dialog {
|
|||||||
updateRollResult(rollData);
|
updateRollResult(rollData);
|
||||||
});
|
});
|
||||||
html.find('#coupsNonMortels').change((event) => {
|
html.find('#coupsNonMortels').change((event) => {
|
||||||
this.rollData.mortalite = event.currentTarget.checked ? "non-mortel" : "mortel";
|
this.rollData.dmg.mortalite = event.currentTarget.checked ? "non-mortel" : "mortel";
|
||||||
|
updateRollResult(rollData);
|
||||||
});
|
});
|
||||||
html.find('#isCharge').change((event) => {
|
html.find('#tactique-combat').change((event) => {
|
||||||
this.rollData.isCharge = event.currentTarget.checked;
|
this.rollData.tactique = event.currentTarget.value;
|
||||||
|
updateRollResult(rollData);
|
||||||
});
|
});
|
||||||
html.find('#surencMalusApply').change((event) => {
|
html.find('#surencMalusApply').change((event) => {
|
||||||
this.rollData.surencMalusApply = event.currentTarget.checked;
|
this.rollData.surencMalusApply = event.currentTarget.checked;
|
||||||
@ -209,11 +222,38 @@ export class RdDRoll extends Dialog {
|
|||||||
static _computeFinalLevel(rollData) {
|
static _computeFinalLevel(rollData) {
|
||||||
const etat = RdDRoll._isIgnoreEtatGeneral(rollData) ? 0 : Misc.toInt(rollData.etat);
|
const etat = RdDRoll._isIgnoreEtatGeneral(rollData) ? 0 : Misc.toInt(rollData.etat);
|
||||||
const diffConditions = Misc.toInt(rollData.diffConditions);
|
const diffConditions = Misc.toInt(rollData.diffConditions);
|
||||||
let malusEnc = (rollData.surencMalusApply) ? rollData.surencMalusValue : 0;
|
const malusEnc = (rollData.surencMalusApply) ? rollData.surencMalusValue : 0;
|
||||||
let diffLibre = Misc.toInt(rollData.diffLibre);
|
const bonusTactique = RdDBonus.bonusAttaque(rollData.tactique);
|
||||||
let malusEncNatation = (rollData.useEncForNatation) ? -rollData.encValueForNatation : 0;
|
const malusEncNatation = (rollData.useEncForNatation) ? -rollData.encValueForNatation : 0;
|
||||||
let ajustementChance = rollData.selectedCarac.label.toLowerCase().includes('chance') ? rollData.ajustementAstrologique : 0;
|
const ajustementChance = rollData.selectedCarac.label.toLowerCase().includes('chance') ? rollData.ajustementAstrologique : 0;
|
||||||
// Gestion malus armure
|
// Gestion malus armure
|
||||||
|
const malusArmureValue = RdDRoll._computeMalusArmure(rollData);
|
||||||
|
|
||||||
|
const diffLibre = RdDRoll._computeDiffLibre(rollData);
|
||||||
|
const diffCompetence = RdDRoll._computeDiffCompetence(rollData);
|
||||||
|
|
||||||
|
return etat + diffCompetence + diffLibre + diffConditions + malusEnc + malusEncNatation + malusArmureValue + ajustementChance + bonusTactique;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _computeDiffCompetence(rollData) {
|
||||||
|
if (rollData.competence) {
|
||||||
|
return Misc.toInt(rollData.competence.data.niveau);
|
||||||
|
}
|
||||||
|
if (rollData.draconicList) {
|
||||||
|
return Misc.toInt(rollData.selectedDraconic.data.niveau);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _computeDiffLibre(rollData) {
|
||||||
|
let diffLibre = Misc.toInt(rollData.diffLibre);
|
||||||
|
if (rollData.draconicList && rollData.selectedSort) {
|
||||||
|
return RdDItemSort.getDifficulte(rollData.selectedSort, diffLibre);
|
||||||
|
}
|
||||||
|
return diffLibre;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _computeMalusArmure(rollData) {
|
||||||
let malusArmureValue = 0;
|
let malusArmureValue = 0;
|
||||||
if (rollData.malusArmureValue != 0 && (rollData.selectedCarac.label == "Agilité" || rollData.selectedCarac.label == "Dérobée")) {
|
if (rollData.malusArmureValue != 0 && (rollData.selectedCarac.label == "Agilité" || rollData.selectedCarac.label == "Dérobée")) {
|
||||||
$("#addon-message").text("Malus armure appliqué : " + rollData.malusArmureValue);
|
$("#addon-message").text("Malus armure appliqué : " + rollData.malusArmureValue);
|
||||||
@ -221,17 +261,7 @@ export class RdDRoll extends Dialog {
|
|||||||
} else {
|
} else {
|
||||||
$("#addon-message").text("");
|
$("#addon-message").text("");
|
||||||
}
|
}
|
||||||
|
return malusArmureValue;
|
||||||
let diffCompetence = 0;
|
|
||||||
if (rollData.competence) {
|
|
||||||
diffCompetence = Misc.toInt(rollData.competence.data.niveau);
|
|
||||||
}
|
|
||||||
else if (rollData.draconicList) {
|
|
||||||
diffCompetence = Misc.toInt(rollData.selectedDraconic.data.niveau);
|
|
||||||
diffLibre = RdDItemSort.getDifficulte(rollData.selectedSort, diffLibre);
|
|
||||||
}
|
|
||||||
|
|
||||||
return etat + diffCompetence + diffLibre + diffConditions + malusEnc + malusEncNatation + malusArmureValue + ajustementChance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
@ -285,14 +285,6 @@ export class RdDTMRDialog extends Dialog {
|
|||||||
return rencontre;
|
return rencontre;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
|
||||||
performRoll(html) {
|
|
||||||
if (this.viewOnly) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.actor.performRoll(this.rollData);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
updateValuesDisplay() {
|
updateValuesDisplay() {
|
||||||
let ptsreve = document.getElementById("tmr-pointsreve-value");
|
let ptsreve = document.getElementById("tmr-pointsreve-value");
|
||||||
|
@ -9,8 +9,13 @@
|
|||||||
{{/each}}
|
{{/each}}
|
||||||
{{/select}}
|
{{/select}}
|
||||||
</select>
|
</select>
|
||||||
|
<label></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
{{#if attackerRoll}}
|
||||||
|
<label for="categorie">Difficulté</label>
|
||||||
|
<label>{{diffLibre}}</label>
|
||||||
|
{{else}}
|
||||||
<label for="categorie">Difficulté libre</label>
|
<label for="categorie">Difficulté libre</label>
|
||||||
<select name="diffLibre" id="diffLibre" data-dtype="number" {{#unless editLibre}}disabled{{/unless}}>
|
<select name="diffLibre" id="diffLibre" data-dtype="number" {{#unless editLibre}}disabled{{/unless}}>
|
||||||
{{#select diffLibre}}
|
{{#select diffLibre}}
|
||||||
@ -19,6 +24,7 @@
|
|||||||
{{/each}}
|
{{/each}}
|
||||||
{{/select}}
|
{{/select}}
|
||||||
</select>
|
</select>
|
||||||
|
{{/if}}
|
||||||
<label for="categorie"> Conditions</label>
|
<label for="categorie"> Conditions</label>
|
||||||
<select name="diffConditions" id="diffConditions" data-dtype="number" {{#unless editConditions}}disabled{{/unless}}>
|
<select name="diffConditions" id="diffConditions" data-dtype="number" {{#unless editConditions}}disabled{{/unless}}>
|
||||||
{{#select diffConditions}}
|
{{#select diffConditions}}
|
||||||
@ -27,30 +33,38 @@
|
|||||||
{{/each}}
|
{{/each}}
|
||||||
{{/select}}
|
{{/select}}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{{#if arme}}
|
{{#if arme}}
|
||||||
<div>
|
<div class="form-group">
|
||||||
<label>Arme : {{arme.name}}</label>
|
{{#if attackerRoll}}
|
||||||
<label>Degats : {{arme.data.dommagesReels}}</label>
|
{{#if attackerRoll.tactique}}
|
||||||
<label for="xp">Coups Non Mortels ? </label>
|
<label for="categorie">Tactique: {{attackerRoll.tactique}}</label>
|
||||||
<input class="attribute-value" type="checkbox" id="coupsNonMortels" name="coupsNonMortels" {{#if coupsNonMortels}}checked{{/if}}/>
|
{{/if}}
|
||||||
</div>
|
<label for="categorie">Dégats:</label><label id="dmg-arme-actor"></label>
|
||||||
{{#unless attackerRoll}}
|
<label></label>
|
||||||
<div>
|
{{else}}
|
||||||
<label>Est une charge ?</label>
|
<label for="categorie">Tactique:</label>
|
||||||
<input class="attribute-value" type="checkbox" id="isCharge" name="isCharge" {{#if isCharge}}checked{{/if}}/>
|
<select name="tactique-combat" id="tactique-combat" data-dtype="String" {{#unless editConditions}}disabled{{/unless}}>
|
||||||
</div>
|
<option value="Attaque normale">Attaque normale</option>
|
||||||
{{/unless}}
|
<option value="charge">Charge</option>
|
||||||
|
<option value="feinte">Feinte</option>
|
||||||
|
</select>
|
||||||
|
<label for="categorie">Dégats:</label><label id="dmg-arme-actor"></label>
|
||||||
|
<label>Non Mortel</label>
|
||||||
|
<input class="attribute-value" type="checkbox" id="coupsNonMortels" name="coupsNonMortels" {{#if coupsNonMortels}}checked{{/if}}/>
|
||||||
|
{{/if}}
|
||||||
|
{{#if surpriseDefenseur}}
|
||||||
|
<label for="categorie" id="defenseur-surprise"></label>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="categorie">Etat général:</label><label>{{numberFormat etat decimals=0 sign=true}}</label>
|
||||||
|
<label>Ajustement final:</label><label id="roll-param">10 / 0</label> <label name="addon-message" id="addon-message"></label>
|
||||||
|
</div>
|
||||||
|
|
||||||
{{>"systems/foundryvtt-reve-de-dragon/templates/dialog-roll-surenc.html"}}
|
{{>"systems/foundryvtt-reve-de-dragon/templates/dialog-roll-surenc.html"}}
|
||||||
{{>"systems/foundryvtt-reve-de-dragon/templates/dialog-roll-natation.html"}}
|
{{>"systems/foundryvtt-reve-de-dragon/templates/dialog-roll-natation.html"}}
|
||||||
<div class="form-group etat-general">
|
|
||||||
<label for="categorie">Etat général</label><label>{{numberFormat etat decimals=0 sign=true}}</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label>Ajustement final : </label><label id="roll-param">10 / 0</label> <label name="addon-message" id="addon-message"></label>
|
|
||||||
</div>
|
|
||||||
<div id="resolutionTable">
|
<div id="resolutionTable">
|
||||||
</div>
|
</div>
|
||||||
<div id="resolutionValeurs">
|
<div id="resolutionValeurs">
|
||||||
|
Loading…
Reference in New Issue
Block a user