Merge branch 'ajustements-tooltips' into 'v1.2'

Gestion des ajustements unifiée

See merge request LeRatierBretonnien/foundryvtt-reve-de-dragon!103
This commit is contained in:
Leratier Bretonnien 2021-01-06 08:07:13 +00:00
commit 92fc7eac48
30 changed files with 532 additions and 376 deletions

View File

@ -161,38 +161,56 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
getReveActuel() { getReveActuel() {
return this.data.data.reve.reve.value; return this.data.data.reve?.reve?.value ?? this.data.data.carac.reve.value;
} }
getChanceActuel() { getChanceActuel() {
return this.data.data.compteurs.chance.value; return this.data.data.compteurs.chance?.value ?? 10;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
getForceValue() { getForceValue() {
return this.data.data.carac.force ? this.data.data.carac.force.value : this.data.data.carac.reve.value; return this.data.data.carac.force?.force ?? this.data.data.carac.reve.value;
}
getMoralTotal() {
return this.data.data.compteurs.moral?.value ?? 0;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
getBonusDegat() { getBonusDegat() {
// TODO: gérer séparation et +dom créature/entité indépendament de la compétence // 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);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
getProtectionNaturelle() { getProtectionNaturelle() {
return Misc.toInt(this.data.data.attributs.protection.value); return Misc.toInt(this.data.data.attributs.protection.value);
} }
getEtatGeneral() {
return this.data.data.compteurs.etat.value;
}
getMalusArmure() {
return this.data.data.attributs?.malusarmure?.value ?? 0;
}
getEncTotal() {
return Math.floor(this.encTotal ?? 0);
}
getSurenc(){
return this.data.data.compteurs?.surenc?.value ?? 0;
}
/* -------------------------------------------- */ /* -------------------------------------------- */
getCompetenceList() { getCompetenceList() {
return this.data.items.filter( (item) => item.type == 'competence'); return this.data.items.filter( (item) => item.type == 'competence');
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
getCompetence(compName) { getCompetence(compName) {
return RdDUtility.findCompetence(this.data.items, compName); return RdDUtility.findCompetence(this.data.items, compName);
} }
/* -------------------------------------------- */
getTache( id ) {
return this.data.items.find( item => item.type=='tache' && item._id == id );
}
getMeditation( id ) {
return this.data.items.find( item => item.type=='meditation' && item._id == id );
}
/* -------------------------------------------- */ /* -------------------------------------------- */
getBestDraconic() { getBestDraconic() {
const list = this.getDraconicList().sort((a, b) => b.data.niveau - a.data.niveau); const list = this.getDraconicList().sort((a, b) => b.data.niveau - a.data.niveau);
@ -203,10 +221,6 @@ export class RdDActor extends Actor {
return duplicate(list[0]); return duplicate(list[0]);
} }
getEncombrementTotal() {
return this.encTotal ? Math.floor(this.encTotal) : 0
}
/* -------------------------------------------- */ /* -------------------------------------------- */
async deleteSortReserve(sortReserve) { async deleteSortReserve(sortReserve) {
let reserve = duplicate(this.data.data.reve.reserve); let reserve = duplicate(this.data.data.reve.reserve);
@ -223,11 +237,6 @@ export class RdDActor extends Actor {
} }
} }
/* -------------------------------------------- */
getDiviseurSignificative() {
return this.getSurprise() == 'demi' ? 2 : 1;
}
/* -------------------------------------------- */ /* -------------------------------------------- */
getSurprise() { getSurprise() {
if (this.isEntiteCauchemar()) { if (this.isEntiteCauchemar()) {
@ -502,7 +511,7 @@ export class RdDActor extends Actor {
async combattreReveDeDragon(force){ async combattreReveDeDragon(force){
let draconic = this.getBestDraconic(); let draconic = this.getBestDraconic();
let niveau = Math.max(0, draconic.data.niveau); let niveau = Math.max(0, draconic.data.niveau);
let etat = this.data.data.compteurs.etat.value; let etat = this.getEtatGeneral();
let difficulte = niveau - etat - force; let difficulte = niveau - etat - force;
let reveActuel = this.getReveActuel(); let reveActuel = this.getReveActuel();
let rolled = await RdDResolutionTable.roll(reveActuel, difficulte); let rolled = await RdDResolutionTable.roll(reveActuel, difficulte);
@ -700,13 +709,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
detectSurEncombrement( ) { detectSurEncombrement( ) {
let diffEnc = Number(this.encTotal) - Number(this.data.data.attributs.encombrement.value); let diffEnc = Number(this.encTotal) - Number(this.data.data.attributs.encombrement.value);
if ( diffEnc > 0 ) { // Sur-encombrement return Math.max(0, Math.ceil(diffEnc));
let malus = Math.round( diffEnc);
malus = (malus == 0) ? 1 : malus; // Always 1 at least
//console.log("Sur enc malus", malus);
return malus;
}
return 0;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -770,7 +773,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
getEtatGeneral() { getEtatGeneral() {
return (this.data.data.compteurs && this.data.data.compteurs.etat) ? this.data.data.compteurs.etat.value : 0; return this.data.data.compteurs?.etat?.value ?? 0;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -784,11 +787,13 @@ export class RdDActor extends Actor {
} }
// Pour les autres // Pour les autres
let state = - (data.sante.vie.max - data.sante.vie.value); let state = - (data.sante.vie.max - data.sante.vie.value);
if (data.sante.fatigue) // Creatures n'ont pas de fatigue if (data.sante.fatigue){
// Creatures n'ont pas de fatigue
state += RdDUtility.currentFatigueMalus(data.sante.fatigue.value, data.sante.endurance.max); state += RdDUtility.currentFatigueMalus(data.sante.fatigue.value, data.sante.endurance.max);
if (data.compteurs && data.compteurs.ethylisme && data.compteurs.ethylisme.value < 0 ) { // Ajout de l'éthylisme
state += data.compteurs.ethylisme.value;
} }
// Ajout de l'éthylisme
state += Math.min(0, (data.compteurs?.ethylisme?.value ??0));
data.compteurs.etat.value = state; data.compteurs.etat.value = state;
if ( data.compteurs && data.compteurs.surenc) { if ( data.compteurs && data.compteurs.surenc) {
data.compteurs.surenc.value = - this.detectSurEncombrement(); data.compteurs.surenc.value = - this.detectSurEncombrement();
@ -1230,7 +1235,7 @@ export class RdDActor extends Actor {
async ethylismeTest() { async ethylismeTest() {
let rollData = { let rollData = {
vieValue: this.data.data.sante.vie.value, vieValue: this.data.data.sante.vie.value,
etat: this.data.data.compteurs.etat.value - Math.min(0, this.data.data.compteurs.ethylisme.value), // Pour les jets d'Ethylisme, on ignore le degré d'éthylisme (p.162) etat: this.getEtatGeneral() - Math.min(0, this.data.data.compteurs.ethylisme.value), // Pour les jets d'Ethylisme, on ignore le degré d'éthylisme (p.162)
diffNbDoses: -Number(this.data.data.compteurs.ethylisme.nb_doses || 0), diffNbDoses: -Number(this.data.data.compteurs.ethylisme.nb_doses || 0),
finalLevel: 0, finalLevel: 0,
diffConditions: 0, diffConditions: 0,
@ -1423,6 +1428,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async _appliquerAjoutExperience(rollData, display=true) { async _appliquerAjoutExperience(rollData, display=true) {
if (!this.isPersonnage()) return;
let xpResult = this.appliquerExperience( rollData.rolled, rollData.selectedCarac.label, rollData.competence); let xpResult = this.appliquerExperience( rollData.rolled, rollData.selectedCarac.label, rollData.competence);
if (display && xpResult.result ) { if (display && xpResult.result ) {
let xpmsg = "<br>Points d'expérience gagnés ! Carac: " + xpResult.xpCarac + ", Comp: " + xpResult.xpCompetence; let xpmsg = "<br>Points d'expérience gagnés ! Carac: " + xpResult.xpCarac + ", Comp: " + xpResult.xpCompetence;
@ -1634,7 +1640,7 @@ export class RdDActor extends Actor {
this.currentTMR.maximize(); // Re-display TMR this.currentTMR.maximize(); // Re-display TMR
} }
// Final chat message // Final chat message
await RdDResolutionTable.displayRollData(rollData, this.name, 'chat-resultat-sort.html'); RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-sort.html');
if (myReve.value == 0) { // 0 points de reve if (myReve.value == 0) { // 0 points de reve
ChatMessage.create({ content: this.name + " est réduit à 0 Points de Rêve, et tombe endormi !" }); ChatMessage.create({ content: this.name + " est réduit à 0 Points de Rêve, et tombe endormi !" });
@ -1653,7 +1659,7 @@ export class RdDActor extends Actor {
label: 'Jet ' + Grammar.apostrophe('de', rollData.selectedCarac.label), label: 'Jet ' + Grammar.apostrophe('de', rollData.selectedCarac.label),
callbacks: [ callbacks: [
this.createCallbackExperience(), this.createCallbackExperience(),
{ action: this._onRollCaracResult } { action: r => this._onRollCaracResult(r) }
] ]
} }
); );
@ -1663,7 +1669,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async _onRollCaracResult(rollData) { async _onRollCaracResult(rollData) {
// Final chat message // Final chat message
await RdDResolutionTable.displayRollData(rollData, this.name, 'chat-resultat-general.html'); RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-general.html');
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -1684,7 +1690,7 @@ export class RdDActor extends Actor {
label: 'Jet ' +Grammar.apostrophe('de', name), label: 'Jet ' +Grammar.apostrophe('de', name),
callbacks: [ callbacks: [
this.createCallbackExperience(), this.createCallbackExperience(),
{ action: this._competenceResult } { action: r => this._competenceResult(r) }
] ]
} ); } );
dialog.render(true); dialog.render(true);
@ -1708,11 +1714,6 @@ export class RdDActor extends Actor {
await this.createOwnedItem( tache, { renderSheet: true } ); await this.createOwnedItem( tache, { renderSheet: true } );
} }
/* -------------------------------------------- */
getTacheMeditation ( id ) {
return this.data.items.find( item => item._id == id );
}
/* -------------------------------------------- */ /* -------------------------------------------- */
async rollTache( id ) { async rollTache( id ) {
let tache = duplicate( this.getTache( id ) ); let tache = duplicate( this.getTache( id ) );
@ -1749,7 +1750,7 @@ export class RdDActor extends Actor {
this.updateEmbeddedEntity( "OwnedItem", rollData.tache); this.updateEmbeddedEntity( "OwnedItem", rollData.tache);
this.santeIncDec( "fatigue", rollData.tache.data.fatigue); this.santeIncDec( "fatigue", rollData.tache.data.fatigue);
RdDResolutionTable.displayRollData(rollData, this.name, 'chat-resultat-tache.html'); RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-tache.html');
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -1760,24 +1761,26 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async rollMeditation( id ) { async rollMeditation( id ) {
let meditation = duplicate( this.getTacheMeditation( id ) ); let meditation = duplicate(this.getMeditation(id));
let competence = duplicate(this.getCompetence(meditation.data.competence)); let competence = duplicate(this.getCompetence(meditation.data.competence));
competence.data.defaut_carac = "intellect"; // Meditation = tjs avec intellect competence.data.defaut_carac = "intellect"; // Meditation = tjs avec intellect
let meditationData = { let meditationData = {
competence: competence, competence: competence,
meditation: meditation, meditation: meditation,
diffConditions: 0, conditionMeditation: {
editLibre: false,
editConditions: true,
isHeure: false, isHeure: false,
isVeture: false, isVeture: false,
isComportement: false, isComportement: false,
isPurification: false, isPurification: false,
},
diffConditions: 0,
editLibre: false,
editConditions: true,
carac : { } carac : { }
}; };
meditationData.carac["intellect"] = duplicate(this.data.data.carac["intellect"]); meditationData.carac["intellect"] = duplicate(this.data.data.carac["intellect"]);
console.log("rollMedittion !!!", meditationData); console.log("rollMeditation !!!", meditationData);
const dialog = await RdDRoll.create(this, meditationData, {html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-meditation.html'}, { const dialog = await RdDRoll.create(this, meditationData, {html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-meditation.html'}, {
name: 'jet-meditation', name: 'jet-meditation',
@ -1805,7 +1808,6 @@ export class RdDActor extends Actor {
RdDResolutionTable.displayRollData(meditationData, this.name, 'chat-resultat-meditation.html'); RdDResolutionTable.displayRollData(meditationData, this.name, 'chat-resultat-meditation.html');
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
_meditationETotal(meditationData) { _meditationETotal(meditationData) {
meditationData.meditation.data.malus--; meditationData.meditation.data.malus--;
@ -1814,14 +1816,13 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async _competenceResult(rollData) { async _competenceResult(rollData) {
RdDResolutionTable.displayRollData(rollData, this.name, 'chat-resultat-competence.html') RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-competence.html')
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async rollAppelChance( ) async rollAppelChance( )
{ {
let rollData = { selectedCarac: this.getCaracByName('chance-actuelle'), surprise: '' }; let rollData = { selectedCarac: this.getCaracByName('chance-actuelle'), surprise: '' };
const dialog = await RdDRoll.create(this, rollData, const dialog = await RdDRoll.create(this, rollData,
{ html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html'}, { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html'},
{ {
@ -1841,7 +1842,7 @@ export class RdDActor extends Actor {
if (rollData.rolled.isSuccess) { if (rollData.rolled.isSuccess) {
await this.chanceActuelleIncDec(-1) await this.chanceActuelleIncDec(-1)
} }
RdDResolutionTable.displayRollData(rollData, this.name, 'chat-resultat-appelchance.html') RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-appelchance.html')
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -1940,15 +1941,13 @@ export class RdDActor extends Actor {
return { return {
label: 'Rêve actuel', label: 'Rêve actuel',
value: this.getReveActuel(), value: this.getReveActuel(),
type: "number", type: "number"
ignoreEtatGeneral: true
}; };
case 'chance-actuelle': case 'Chance actuelle': case 'chance-actuelle': case 'Chance actuelle':
return { return {
label: 'Chance actuelle', label: 'Chance actuelle',
value: this.getChanceActuel(), value: this.getChanceActuel(),
type: "number", type: "number"
ignoreEtatGeneral: true
}; };
} }
return RdDActor._findCaracByName(this.data.data.carac, caracName); return RdDActor._findCaracByName(this.data.data.carac, caracName);
@ -2210,7 +2209,7 @@ export class RdDActor extends Actor {
await entite.setEntiteReveAccordee(this); await entite.setEntiteReveAccordee(this);
} }
await RdDResolutionTable.displayRollData(rollData, this.name, 'chat-resultat-accorder-cauchemar.html'); await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-accorder-cauchemar.html');
if (rolled.isPart) { if (rolled.isPart) {
await this._appliquerAjoutExperience(rollData, true); await this._appliquerAjoutExperience(rollData, true);
} }

View File

@ -1,6 +1,6 @@
import { RdDItemCompetenceCreature } from "./item-competencecreature.js" import { RdDItemCompetenceCreature } from "./item-competencecreature.js"
const nomCcategorieParade = { const nomCategorieParade = {
"sans-armes": "Sans arme / armes naturelles", "sans-armes": "Sans arme / armes naturelles",
"hast": "Armes d'hast", "hast": "Armes d'hast",
"batons": "Bâtons", "batons": "Bâtons",
@ -31,9 +31,21 @@ export class RdDItemArme extends Item {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static getNomCategorieParade(it) { static getNomCategorieParade(arme) {
const categorie = it.data ? RdDItemArme.getCategorieParade(it) : it; const categorie = arme?.data ? RdDItemArme.getCategorieParade(arme) : arme;
return nomCcategorieParade[categorie]; return nomCategorieParade[categorie];
}
/* -------------------------------------------- */
static needArmeResist(armeAttaque, armeParade) {
if (!armeAttaque || !armeParade){
return false;
}
// Epées parant une arme de bois (cf. page 115 ), une résistance est nécessaire
let attCategory = RdDItemArme.getCategorieParade(armeAttaque);
let defCategory = RdDItemArme.getCategorieParade(armeParade);
return attCategory.match(/epees-/) && defCategory.match(/(haches|lances)/);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -74,6 +86,9 @@ export class RdDItemArme extends Item {
/* -------------------------------------------- */ /* -------------------------------------------- */
static needParadeSignificative(armeAttaque, armeParade) { static needParadeSignificative(armeAttaque, armeParade) {
if (!armeAttaque || !armeParade){
return false;
}
// categories d'armes à la parade (cf. page 115 ) // categories d'armes à la parade (cf. page 115 )
let attCategory = RdDItemArme.getCategorieParade(armeAttaque); let attCategory = RdDItemArme.getCategorieParade(armeAttaque);
let defCategory = RdDItemArme.getCategorieParade(armeParade); let defCategory = RdDItemArme.getCategorieParade(armeParade);

15
module/item-meditation.js Normal file
View File

@ -0,0 +1,15 @@
export class RdDItemMeditation {
static calculDifficulte(rollData) {
if (rollData.meditation) {
// Malus permanent éventuel
let diff = -rollData.meditation.data.malus ?? 0;
if (!rollData.conditionMeditation.isHeure) diff -= 2;
if (!rollData.conditionMeditation.isVeture) diff -= 2;
if (!rollData.conditionMeditation.isComportement) diff -= 2;
if (!rollData.conditionMeditation.isPurification) diff -= 2;
return diff;
}
return 0;
}
}

View File

@ -5,14 +5,20 @@
* to actual classes of the game system or of FoundryVTT * to actual classes of the game system or of FoundryVTT
*/ */
export class Misc { export class Misc {
static isFunction(v) {
return v && {}.toString.call(v) === '[object Function]';
}
static upperFirst(text) { static upperFirst(text) {
return text.charAt(0).toUpperCase() + text.slice(1); return text.charAt(0).toUpperCase() + text.slice(1);
} }
static toSignedString(number){ static toSignedString(number){
const value = parseInt(number) const value = parseInt(number)
const isPositiveNumber = value != NaN && value > 0; const isPositiveNumber = value != NaN && value > 0;
return isPositiveNumber ? "+"+number : number return isPositiveNumber ? "+"+number : number
} }
/** /**
* Converts the value to an integer, or to 0 if undefined/null/not representing integer * Converts the value to an integer, or to 0 if undefined/null/not representing integer
* @param {*} value value to convert to an integer using parseInt * @param {*} value value to convert to an integer using parseInt
@ -26,4 +32,13 @@ export class Misc {
const parsed = parseInt(value); const parsed = parseInt(value);
return isNaN(parsed) ? 0 : parsed; return isNaN(parsed) ? 0 : parsed;
} }
static getFractionHtml(diviseur) {
if (!diviseur || diviseur <= 1) return undefined;
switch (diviseur || 1) {
case 2: return '&frac12;';
case 4: return '&frac14;';
default: return '1/' + diviseur;
}
}
} }

View File

@ -13,7 +13,7 @@ export class RdDAstrologieJoueur extends Dialog {
let data = { nombres: this.organizeNombres( actor), let data = { nombres: this.organizeNombres( actor),
dates: game.system.rdd.calendrier.getJoursSuivants( 10 ), dates: game.system.rdd.calendrier.getJoursSuivants( 10 ),
etat: actor.data.data.compteurs.etat.value, etat: actor.getEtatGeneral(),
ajustementsConditions: CONFIG.RDD.ajustementsConditions, ajustementsConditions: CONFIG.RDD.ajustementsConditions,
astrologie: RdDUtility.findCompetence( actor.data.items, 'Astrologie') astrologie: RdDUtility.findCompetence( actor.data.items, 'Astrologie')
} }

View File

@ -1,3 +1,4 @@
import { RdDCarac } from "./rdd-carac.js";
import { RdDUtility } from "./rdd-utility.js"; import { RdDUtility } from "./rdd-utility.js";
const conditionsTactiques = [ const conditionsTactiques = [
@ -17,6 +18,16 @@ export class RdDBonus {
return conditionsTactiques.find(e => e.type == condition) || conditionsTactiques.find(e => e.type == 'pret'); return conditionsTactiques.find(e => e.type == condition) || conditionsTactiques.find(e => e.type == 'pret');
} }
static isAjustementAstrologique(rollData) {
return RdDCarac.isChance(rollData.selectedCarac) ||
rollData.selectedSort?.data.isrituel;
}
/* -------------------------------------------- */
static isDefenseAttaqueFinesse(rollData) {
return rollData.attackerRoll?.particuliere == 'finesse';
}
/* -------------------------------------------- */ /* -------------------------------------------- */
static dmg(rollData, dmgActor, isCauchemar = false) { static dmg(rollData, dmgActor, isCauchemar = false) {
let dmg = { total: 0, loc: RdDUtility.getLocalisation() }; let dmg = { total: 0, loc: RdDUtility.getLocalisation() };
@ -66,11 +77,11 @@ export class RdDBonus {
/* -------------------------------------------- */ /* -------------------------------------------- */
static _dmgArme(rollData) { static _dmgArme(rollData) {
return rollData.arme ? parseInt(rollData.arme.data.dommages) : 0; return parseInt(rollData.arme?.data.dommages ?? 0);
} }
static _peneration(rollData) { static _peneration(rollData) {
return rollData.arme ? parseInt(rollData.arme.data.penetration) : 0; return parseInt(rollData.arme?.data.penetration ?? 0);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */

30
module/rdd-carac.js Normal file
View File

@ -0,0 +1,30 @@
export class RdDCarac {
static isAgiliteOuDerivee(selectedCarac) {
return selectedCarac?.label.match(/(Agilité|Dérobée)/);
}
static isVolonte(selectedCarac) {
return selectedCarac?.label == 'Volonté';
}
static isChance(selectedCarac) {
return selectedCarac?.label?.toLowerCase()?.match(/chance( actuelle)?/);
}
static isReve(selectedCarac) {
return selectedCarac?.label?.toLowerCase()?.match(/r(e|ê)ve(( |-)actuel)?/);
}
static isIgnoreEtatGeneral(selectedCarac) {
return !selectedCarac ||
RdDCarac.isChance(selectedCarac) ||
RdDCarac.isReve(selectedCarac);
}
/**
* Lappel à la chance nest possible que pour recommencer les jets dactions physiques :
* tous les jets de combat, de FORCE, dAGILITÉ, de DEXTÉRITÉ, de Dérobée, dAPPARENCE,
* ainsi que de Perception active et volontaire.
*/
static isActionPhysique(selectedCarac) {
return selectedCarac?.label.match(/(Apparence|Force|Agilité|Dextérité|Vue|Ouïe|Odorat-Goût|Empathie|Mêlée|Tir|Lancer|Dérobée)/);
}
}

View File

@ -18,12 +18,12 @@ export class RdDCombat {
static createUsingTarget(attacker) { static createUsingTarget(attacker) {
const target = RdDCombat.getTarget(); const target = RdDCombat.getTarget();
if (target == undefined) { if (target == undefined) {
ui.notifications.warn((game.user.targets && game.user.targets.size > 1) ui.notifications.warn((game.user.targets?.size ?? 0) > 1
? "Vous devez choisir <strong>une seule</strong> cible à attaquer!" ? "Vous devez choisir <strong>une seule</strong> cible à attaquer!"
: "Vous devez choisir une cible à attaquer!"); : "Vous devez choisir une cible à attaquer!");
} }
const defender = target ? target.actor : undefined; const defender = target?.actor;
const defenderTokenId = target ? target.data._id : undefined; const defenderTokenId = target?.data._id;
return this.create(attacker, defender, defenderTokenId, target) return this.create(attacker, defender, defenderTokenId, target)
} }
@ -68,8 +68,8 @@ export class RdDCombat {
// envoyer le message au destinataire // envoyer le message au destinataire
if (!game.user.isGM || recipient.hasPlayerOwner) { if (!game.user.isGM || recipient.hasPlayerOwner) {
let data = { let data = {
attackerId: sender ? sender.data._id : undefined, attackerId: sender?.data._id,
defenderId: recipient ? recipient.data._id : undefined, defenderId: recipient?.data._id,
defenderTokenId: defenderTokenId, defenderTokenId: defenderTokenId,
rollData: duplicate(rollData), rollData: duplicate(rollData),
rollMode: true rollMode: true
@ -86,7 +86,7 @@ export class RdDCombat {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static _callJetDeVie( event ) { static _callJetDeVie(event) {
let actorId = event.currentTarget.attributes['data-actorId'].value; let actorId = event.currentTarget.attributes['data-actorId'].value;
let actor = game.actors.get(actorId); let actor = game.actors.get(actorId);
actor.jetVie(); actor.jetVie();
@ -103,7 +103,7 @@ export class RdDCombat {
html.on("click", '#chat-jet-vie', event => { html.on("click", '#chat-jet-vie', event => {
event.preventDefault(); event.preventDefault();
RdDCombat._callJetDeVie(event); RdDCombat._callJetDeVie(event);
} ); });
} }
@ -128,7 +128,7 @@ export class RdDCombat {
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': { case '#parer-button': {
const armeId = event.currentTarget.attributes['data-armeid']; const armeId = event.currentTarget.attributes['data-armeid'];
return this.parade(rollData, armeId ? armeId.value : undefined); return this.parade(rollData, armeId?.value);
} }
case '#esquiver-button': return this.esquive(rollData); case '#esquiver-button': return this.esquive(rollData);
case '#encaisser-button': return this.encaisser(rollData, event.currentTarget.attributes['data-defenderTokenId'].value); case '#encaisser-button': return this.encaisser(rollData, event.currentTarget.attributes['data-defenderTokenId'].value);
@ -182,7 +182,7 @@ export class RdDCombat {
options: { height: 540 } options: { height: 540 }
}, { }, {
name: 'jet-attaque', name: 'jet-attaque',
label: 'Attaque: ' + (arme ? arme.name : competence.name), label: 'Attaque: ' + (arme?.name ?? competence.name),
callbacks: [ callbacks: [
this.attacker.createCallbackExperience(), this.attacker.createCallbackExperience(),
{ condition: r => (RdDCombat.isReussite(r) && !RdDCombat.isParticuliere(r)), action: r => this._onAttaqueNormale(r) }, { condition: r => (RdDCombat.isReussite(r) && !RdDCombat.isParticuliere(r)), action: r => this._onAttaqueNormale(r) },
@ -212,7 +212,7 @@ export class RdDCombat {
} }
else { else {
// sans armes: à mains nues // sans armes: à mains nues
rollData.arme = RdDItemArme.mainsNues({niveau: competence.data.niveau}); rollData.arme = RdDItemArme.mainsNues({ niveau: competence.data.niveau });
} }
return rollData; return rollData;
} }
@ -247,7 +247,7 @@ export class RdDCombat {
cible: this.target ? this.defender.data.name : 'la cible', cible: this.target ? this.defender.data.name : 'la cible',
isRecul: (rollData.particuliere == 'force' || rollData.tactique == 'charge') isRecul: (rollData.particuliere == 'force' || rollData.tactique == 'charge')
} }
await RdDResolutionTable.displayRollData(rollData, this.attacker.name, 'chat-resultat-attaque.html'); await RdDResolutionTable.displayRollData(rollData, this.attacker, 'chat-resultat-attaque.html');
if (!await this.accorderEntite('avant-defense')) { if (!await this.accorderEntite('avant-defense')) {
return; return;
@ -304,7 +304,7 @@ export class RdDCombat {
return items.filter(item => RdDItemArme.getCategorieParade(item) == 'boucliers') return items.filter(item => RdDItemArme.getCategorieParade(item) == 'boucliers')
default: default:
// Le fléau ne peut être paré quau bouclier p115 // Le fléau ne peut être paré quau bouclier p115
if (competence.name == "Fléau"){ if (competence.name == "Fléau") {
return items.filter(item => RdDItemArme.getCategorieParade(item) == 'boucliers') return items.filter(item => RdDItemArme.getCategorieParade(item) == 'boucliers')
} }
return items.filter(item => RdDItemArme.getCategorieParade(item)); return items.filter(item => RdDItemArme.getCategorieParade(item));
@ -327,7 +327,7 @@ export class RdDCombat {
/* -------------------------------------------- */ /* -------------------------------------------- */
async _onAttaqueEchec(rollData) { async _onAttaqueEchec(rollData) {
console.log("RdDCombat.onAttaqueEchec >>>", rollData); console.log("RdDCombat.onAttaqueEchec >>>", rollData);
await RdDResolutionTable.displayRollData(rollData, this.attacker.name, 'chat-resultat-attaque.html'); await RdDResolutionTable.displayRollData(rollData, this.attacker, 'chat-resultat-attaque.html');
} }
@ -376,12 +376,12 @@ export class RdDCombat {
competence: this.defender.getCompetence(compName), competence: this.defender.getCompetence(compName),
arme: armeParade, arme: armeParade,
surprise: this.defender.getSurprise(), surprise: this.defender.getSurprise(),
needParadeSignificative: this.needParadeSignificative(attackerRoll, armeParade), needParadeSignificative: RdDItemArme.needParadeSignificative(armeAttaque, armeParade),
diviseur: this._getDiviseurSignificative(attackerRoll, armeParade), needResist: RdDItemArme.needArmeResist(armeAttaque, armeParade),
needResist: this._needArmeResist(armeAttaque, armeParade),
carac: this.defender.data.data.carac, carac: this.defender.data.data.carac,
show: {} show: {}
}; };
rollData.diviseur = this._getDiviseurSignificative(rollData);
if (isCreature) { if (isCreature) {
RdDItemCompetence.setRollDataCreature(rollData); RdDItemCompetence.setRollDataCreature(rollData);
} }
@ -389,34 +389,12 @@ export class RdDCombat {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
_getDiviseurSignificative(attackerRoll, armeParade = undefined) { _getDiviseurSignificative(rollData) {
let facteurSign = this.defender.getDiviseurSignificative(); let facteurSign = (this.defender.isDemiSurprise() || rollData.needParadeSignificative) ? 2 : 1;
if (RdDCombat.isAttaqueFinesse(attackerRoll)) { if (RdDBonus.isDefenseAttaqueFinesse(rollData)) {
facteurSign *= 2; facteurSign *= 2;
} }
if (this.needParadeSignificative(attackerRoll, armeParade)) { return facteurSign;
facteurSign *= 2;
}
return Math.min(4, facteurSign);
}
static isAttaqueFinesse(attackerRoll) {
return attackerRoll && attackerRoll.particuliere == 'finesse';
}
needParadeSignificative(attackerRoll, armeParade) {
return attackerRoll.arme && armeParade &&
RdDItemArme.needParadeSignificative(attackerRoll.arme, armeParade);
}
/* -------------------------------------------- */
_needArmeResist(armeAttaque, armeParade) {
// Epées parant une arme de bois (cf. page 115 ), une résistance est nécessaire
let attCategory = RdDItemArme.getCategorieParade(armeAttaque);
let defCategory = RdDItemArme.getCategorieParade(armeParade);
return attCategory.match(/epees-/) && defCategory.match(/(haches|lances)/);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -437,7 +415,7 @@ export class RdDCombat {
await this.computeRecul(rollData); await this.computeRecul(rollData);
await this.computeDeteriorationArme(rollData); await this.computeDeteriorationArme(rollData);
await RdDResolutionTable.displayRollData(rollData, this.defender.name, 'chat-resultat-parade.html'); await RdDResolutionTable.displayRollData(rollData, this.defender, 'chat-resultat-parade.html');
} }
@ -459,7 +437,7 @@ export class RdDCombat {
await this.computeRecul(rollData); await this.computeRecul(rollData);
await RdDResolutionTable.displayRollData(rollData, this.defender.name, 'chat-resultat-parade.html'); await RdDResolutionTable.displayRollData(rollData, this.defender, 'chat-resultat-parade.html');
this._sendMessageEncaisser(rollData.attackerRoll); this._sendMessageEncaisser(rollData.attackerRoll);
} }
@ -498,10 +476,10 @@ export class RdDCombat {
competence: competence, competence: competence,
surprise: this.defender.getSurprise(), surprise: this.defender.getSurprise(),
surpriseDefenseur: this.defender.getSurprise(), surpriseDefenseur: this.defender.getSurprise(),
diviseur: this._getDiviseurSignificative(attackerRoll),
carac: this.defender.data.data.carac, carac: this.defender.data.data.carac,
show: {} show: {}
}; };
rollData.diviseur = this._getDiviseurSignificative(rollData);
if (this.defender.isCreature()) { if (this.defender.isCreature()) {
RdDItemCompetence.setRollDataCreature(rollData); RdDItemCompetence.setRollDataCreature(rollData);
@ -522,7 +500,7 @@ export class RdDCombat {
async _onEsquiveNormale(rollData) { async _onEsquiveNormale(rollData) {
console.log("RdDCombat._onEsquiveNormal >>>", rollData); console.log("RdDCombat._onEsquiveNormal >>>", rollData);
await RdDResolutionTable.displayRollData(rollData, this.defender.name, 'chat-resultat-esquive.html'); await RdDResolutionTable.displayRollData(rollData, this.defender, 'chat-resultat-esquive.html');
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -542,7 +520,7 @@ export class RdDCombat {
await this.computeRecul(rollData); await this.computeRecul(rollData);
await RdDResolutionTable.displayRollData(rollData, this.defender.name, 'chat-resultat-esquive.html'); await RdDResolutionTable.displayRollData(rollData, this.defender, 'chat-resultat-esquive.html');
this._sendMessageEncaisser(rollData.attackerRoll); this._sendMessageEncaisser(rollData.attackerRoll);
} }
@ -600,7 +578,9 @@ export class RdDCombat {
if (this._isAttaqueCauseRecul(attaque)) { if (this._isAttaqueCauseRecul(attaque)) {
let impactRecul = this._computeImpactRecul(attaque); let impactRecul = this._computeImpactRecul(attaque);
const agilite = this.defender.data.data.carac.agilite.value; const agilite = this.defender.isEntiteCauchemar()
? this.defender.data.data.carac.reve.value
: this.defender.data.data.carac.agilite.value;
let rollRecul = await RdDResolutionTable.rollData({ caracValue: 10, finalLevel: impactRecul, showDice: false }); let rollRecul = await RdDResolutionTable.rollData({ caracValue: 10, finalLevel: impactRecul, showDice: false });
@ -679,7 +659,7 @@ export class RdDCombat {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async displayActorCombatStatus( actor ) { static async displayActorCombatStatus(actor) {
let rollMode = game.settings.get("core", "rollMode"); let rollMode = game.settings.get("core", "rollMode");
let rollData = { let rollData = {
alias: actor.name, alias: actor.name,
@ -691,9 +671,9 @@ export class RdDCombat {
isGrave: false, isGrave: false,
isCritique: false isCritique: false
} }
if ( actor.countBlessuresByName("critiques") > 0 ) { // Pour éviter le cumul grave + critique if (actor.countBlessuresByName("critiques") > 0) { // Pour éviter le cumul grave + critique
rollData.isCritique = true; rollData.isCritique = true;
} else if ( actor.countBlessuresByName("graves") > 0) { } else if (actor.countBlessuresByName("graves") > 0) {
rollData.isGrave = true; rollData.isGrave = true;
} }
let content = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-summary.html`, rollData); let content = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-summary.html`, rollData);
@ -701,10 +681,10 @@ export class RdDCombat {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static updateCombatRound( combat, data) { static updateCombatRound(combat, data) {
if (combat.data.round != 0 && combat.turns && combat.data.active) { if (combat.data.round != 0 && combat.turns && combat.data.active) {
let turn = combat.turns.find(t => t.tokenId == combat.current.tokenId); let turn = combat.turns.find(t => t.tokenId == combat.current.tokenId);
this.displayActorCombatStatus( turn.actor ); this.displayActorCombatStatus(turn.actor);
// TODO Playaudio ?? // TODO Playaudio ??
} }
} }

View File

@ -1,8 +1,6 @@
import { ChatUtility } from "./chat-utility.js"; import { ChatUtility } from "./chat-utility.js";
import { RdDItemArme } from "./item-arme.js"; import { RollDataAjustements as RollDataAjustements } from "./rolldata-ajustements.js";
import { Misc } from "./misc.js"; import { Misc } from "./misc.js";
import { RdDBonus } from "./rdd-bonus.js";
import { RdDCombat } from "./rdd-combat.js";
import { RdDDice } from "./rdd-dice.js"; import { RdDDice } from "./rdd-dice.js";
/** /**
@ -93,76 +91,16 @@ export class RdDResolutionTable {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async buildRollDataHtml(rollData, template = 'chat-resultat-general.html') { static async displayRollData(rollData, actor = undefined, template = 'chat-resultat-general.html') {
rollData.ajustements = RdDResolutionTable._buildAjustements(rollData); ChatUtility.chatWithRollMode(
rollData.show = rollData.show || {}; { content: await RdDResolutionTable.buildRollDataHtml(rollData, actor, template) },
actor?.userName ?? game.user.name)
return await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/${template}`, rollData);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async displayRollData(rollData, userName, template = 'chat-resultat-general.html') { static async buildRollDataHtml(rollData, actor, template = 'chat-resultat-general.html') {
rollData.show = rollData.show || {};
ChatUtility.chatWithRollMode( return await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/${template}`, rollData);
{ content: await RdDResolutionTable.buildRollDataHtml(rollData, template) },
userName)
}
static _buildAjustements(rollData) {
let list = [];
if (rollData.competence) {
list.push({ label: rollData.competence.name, value: rollData.competence.data.niveau });
}
if (rollData.tactique) {
const surprise = RdDBonus.find(rollData.tactique);
list.push({ label: surprise.descr, value: surprise.attaque });
}
if (rollData.surpriseDefenseur) {
const surprise = RdDBonus.find(rollData.surpriseDefenseur);
list.push({ label: surprise.descr, value: surprise.attaque });
}
if (rollData.diffLibre != undefined) {
const label = rollData.selectedSort ? rollData.selectedSort.name : 'Libre';
list.push({ label: label, value: rollData.diffLibre });
}
if (rollData.diffConditions != undefined) {
list.push({ label: 'Conditions', value: rollData.diffConditions });
}
if (rollData.etat != undefined) {
list.push({ label: 'Etat', value: rollData.etat });
}
if (rollData.selectedCarac != undefined && rollData.moral != undefined && rollData.selectedCarac.label == 'Volonté') {
list.push({ label: 'Moral', value: rollData.selectedCarac != undefined && rollData.moral != undefined && rollData.selectedCarac.label == 'Volonté' ? rollData.moral : undefined });
}
if (RdDResolutionTable.isAjustementAstrologique(rollData)) {
list.push({ label: 'Astrologique', value: rollData.ajustementAstrologique || 0 });
}
if (rollData.rolled.bonus && rollData.selectedSort) {
list.push({ descr: `Bonus de case: ${rollData.rolled.bonus}%` });
}
if (rollData.diviseur > 1) {
list.push({ descr: `Facteur significative &times;${RdDResolutionTable._getFractionHtml(rollData.diviseur)}` });
}
if (RdDCombat.isAttaqueFinesse(rollData.attackerRoll)) {
list.push({ descr: 'Attaque particulière en finesse' });
}
if (rollData.needParadeSignificative) {
const catAttaque = RdDItemArme.getNomCategorieParade(rollData.attackerRoll.arme);
const catParade = RdDItemArme.getNomCategorieParade(rollData.arme);
list.push({ descr: `${catAttaque} vs ${catParade}` });
}
if (rollData.surprise) {
list.push({ descr: RdDBonus.find(rollData.surprise).descr });
}
return list;
}
static _getFractionHtml(diviseur) {
if (!diviseur || diviseur <= 1) return undefined;
switch (diviseur || 1) {
case 2: return '&frac12;';
case 4: return '&frac14;';
default: return '1/' + diviseur;
}
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -182,7 +120,7 @@ export class RdDResolutionTable {
rolled.caracValue = caracValue; rolled.caracValue = caracValue;
rolled.finalLevel = finalLevel; rolled.finalLevel = finalLevel;
rolled.bonus = bonus; rolled.bonus = bonus;
rolled.factorHtml = RdDResolutionTable._getFractionHtml(diviseur); rolled.factorHtml = Misc.getFractionHtml(diviseur);
return rolled; return rolled;
} }
@ -225,10 +163,10 @@ export class RdDResolutionTable {
/* -------------------------------------------- */ /* -------------------------------------------- */
static isAjustementAstrologique(rollData) { static isAjustementAstrologique(rollData) {
if (rollData.selectedCarac && rollData.selectedCarac.label.toLowerCase().includes('chance')) { if (rollData.selectedCarac?.label.toLowerCase().includes('chance')) {
return true; return true;
} }
if (rollData.selectedSort && rollData.selectedSort.data.isrituel) { if (rollData.selectedSort?.data.isrituel) {
return true; return true;
} }
return false; return false;
@ -323,12 +261,12 @@ export class RdDResolutionTable {
/* -------------------------------------------- */ /* -------------------------------------------- */
static buildHTMLResults(caracValue, levelValue) { static buildHTMLResults(caracValue, levelValue) {
let cell = this.computeChances(caracValue, levelValue); let cell = this.computeChances(caracValue, levelValue);
cell.epart = cell.epart>99? 'N/A' : cell.epart; cell.epart = cell.epart > 99 ? 'N/A' : cell.epart;
cell.etotal = cell.etotal>100? 'N/A' : cell.etotal; cell.etotal = cell.etotal > 100 ? 'N/A' : cell.etotal;
cell.score = Math.min(cell.score, 99); cell.score = Math.min(cell.score, 99);
return ` return `
<span class="span-valeur competence-label"> <span class="table-proba-reussite competence-label">
Particulière: <span class="rdd-roll-part">${cell.part}</span> Particulière: <span class="rdd-roll-part">${cell.part}</span>
- Significative: <span class="rdd-roll-sign">${cell.sign}</span> - Significative: <span class="rdd-roll-sign">${cell.sign}</span>
- Réussite: <span class="rdd-roll-norm">${cell.score}</span> - Réussite: <span class="rdd-roll-norm">${cell.score}</span>

View File

@ -61,7 +61,7 @@ export class RdDRollResolutionTable extends Dialog {
async onAction(html) { async onAction(html) {
await RdDResolutionTable.rollData(this.rollData); await RdDResolutionTable.rollData(this.rollData);
console.log("RdDRollResolutionTable -=>", this.rollData, this.rollData.rolled); console.log("RdDRollResolutionTable -=>", this.rollData, this.rollData.rolled);
await RdDResolutionTable.displayRollData(this.rollData, game.user.name); await RdDResolutionTable.displayRollData(this.rollData);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -82,8 +82,8 @@ export class RdDRollResolutionTable extends Dialog {
$("#roll-param").text(rollData.selectedCarac.value + " / " + Misc.toSignedString(rollData.finalLevel)); $("#roll-param").text(rollData.selectedCarac.value + " / " + Misc.toSignedString(rollData.finalLevel));
$(".table-resolution").remove(); $(".table-resolution").remove();
$("#resolutionTable").append(RdDResolutionTable.buildHTMLTable(rollData.caracValue, rollData.finalLevel, 1, 20, -10, 10)); $("#resolutionTable").append(RdDResolutionTable.buildHTMLTable(rollData.caracValue, rollData.finalLevel, 1, 20, -10, 10));
$(".span-valeur").remove(); $(".table-proba-reussite").remove();
$("#resolutionValeurs").append(RdDResolutionTable.buildHTMLResults(rollData.caracValue, rollData.finalLevel)); $("#tableProbaReussite").append(RdDResolutionTable.buildHTMLResults(rollData.caracValue, rollData.finalLevel));
} }
// Setup everything onload // Setup everything onload

View File

@ -1,8 +1,11 @@
import { referenceAjustements, RollDataAjustements } from "./rolldata-ajustements.js";
import { HtmlUtility } from "./html-utility.js"; import { HtmlUtility } from "./html-utility.js";
import { RdDItemCompetence } from "./item-competence.js"; import { RdDItemCompetence } from "./item-competence.js";
import { RdDItemMeditation } from "./item-meditation.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 { RdDBonus } from "./rdd-bonus.js";
import { RdDCarac } from "./rdd-carac.js";
import { RdDResolutionTable } from "./rdd-resolution-table.js"; import { RdDResolutionTable } from "./rdd-resolution-table.js";
/** /**
@ -24,36 +27,40 @@ export class RdDRoll extends Dialog {
if (dialogConfig.options) { if (dialogConfig.options) {
mergeObject(options, dialogConfig.options, { overwrite: true }) mergeObject(options, dialogConfig.options, { overwrite: true })
} }
return new RdDRoll(actor, rollData, html, options, actions, dialogConfig.close ); return new RdDRoll(actor, rollData, html, options, actions, dialogConfig.close);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static _setDefaultOptions(actor, rollData) { static _setDefaultOptions(actor, rollData) {
let defaultRollData = { let defaultRollData = {
alias: actor.name, alias: actor.name,
ajustementsConditions: CONFIG.RDD.ajustementsConditions, ajustementsConditions: CONFIG.RDD.ajustementsConditions,
difficultesLibres: CONFIG.RDD.difficultesLibres, difficultesLibres: CONFIG.RDD.difficultesLibres,
etat: actor.data.data.compteurs.etat.value, etat: actor.getEtatGeneral(),
moral: actor.isPersonnage() ? actor.data.data.compteurs.moral.value : 0, moral: actor.getMoralTotal(),
carac: actor.data.data.carac, carac: actor.data.data.carac,
finalLevel: 0, finalLevel: 0,
diffConditions: rollData.arme ? RdDBonus.bonusAttaque(rollData.surpriseDefenseur) :0, diffConditions: rollData.arme ? RdDBonus.bonusAttaque(rollData.surpriseDefenseur) : 0,
diffLibre: rollData.competence?.data.default_diffLibre ?? 0, diffLibre: rollData.competence?.data.default_diffLibre ?? 0,
editLibre: true, editLibre: true,
editConditions: true, editConditions: true,
forceValue: actor.getForceValue(), forceValue: actor.getForceValue(),
malusArmureValue: (actor.isPersonnage() && actor.data.data.attributs && actor.data.data.attributs.malusarmure) ? actor.data.data.attributs.malusarmure.value : 0, malusArmureValue: actor.getMalusArmure(),
surencMalusFlag: actor.isPersonnage() ? (actor.data.data.compteurs.surenc.value < 0) : false, surencMalusFlag: actor.isPersonnage() ? (actor.data.data.compteurs.surenc.value < 0) : false,
surencMalusValue: actor.isPersonnage() ? actor.data.data.compteurs.surenc.value : 0, surencMalusValue: actor.getSurenc(),
surencMalusApply: false, useMalusSurenc: false,
use: {
surenc: false,
encTotal: false,
},
isMalusEncombrementTotal: RdDItemCompetence.isMalusEncombrementTotal(rollData.competence), isMalusEncombrementTotal: RdDItemCompetence.isMalusEncombrementTotal(rollData.competence),
useMalusEncTotal: false, useMalusEncTotal: false,
encTotal: actor.getEncombrementTotal(), encTotal: actor.getEncTotal(),
ajustementAstrologique: actor.ajustementAstrologique(), ajustementAstrologique: actor.ajustementAstrologique(),
surprise: actor.getSurprise() surprise: actor.getSurprise(),
} }
mergeObject(rollData, defaultRollData, { overwrite: false }); mergeObject(rollData, defaultRollData, { recursive: true, overwrite: false });
RollDataAjustements.calcul(rollData, actor);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -106,47 +113,10 @@ export class RdDRoll extends Dialog {
this.bringToTop(); this.bringToTop();
var rollData = this.rollData;
var actor = this.actor;
var dialog = this; var dialog = this;
function updateRollResult(rollData) { function onLoad() {
rollData.dmg = rollData.attackerRoll ? rollData.attackerRoll.dmg : RdDBonus.dmg(rollData, actor.getBonusDegat()); let rollData = dialog.rollData;
rollData.finalLevel = dialog._computeFinalLevel(rollData);
rollData.caracValue = parseInt(rollData.selectedCarac.value);
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($(".diffMoral"), rollData.selectedCarac == actor.data.data.carac.volonte);
HtmlUtility._showControlWhen($("#etat-general"), !dialog._isIgnoreEtatGeneral(rollData));
HtmlUtility._showControlWhen($("#ajust-astrologique"), RdDResolutionTable.isAjustementAstrologique(rollData));
// Sort management
if (rollData.selectedSort) {
rollData.bonus = RdDItemSort.getCaseBonus(rollData.selectedSort, rollData.coord),
//console.log("Toggle show/hide", rollData.selectedSort);
HtmlUtility._showControlWhen($("#div-sort-difficulte"), RdDItemSort.isDifficulteVariable(rollData.selectedSort))
HtmlUtility._showControlWhen($("#div-sort-ptreve"), RdDItemSort.isCoutVariable(rollData.selectedSort))
}
// Mise à jour valeurs
$("#roll-param").text(rollData.selectedCarac.value + " / " + Misc.toSignedString(rollData.finalLevel));
$("#compdialogTitle").text(dialog._getTitle(rollData));
$('#coupsNonMortels').prop('checked', rollData.coupsNonMortels);
$("#dmg-arme-actor").text(dmgText);
$("#defenseur-surprise").text(RdDBonus.description(rollData.surpriseDefenseur));
$(".table-resolution").remove();
$("#resolutionTable").append(RdDResolutionTable.buildHTMLTableExtract(rollData.caracValue, rollData.finalLevel));
$(".span-valeur").remove();
$("#resolutionValeurs").append(RdDResolutionTable.buildHTMLResults(rollData.caracValue, rollData.finalLevel));
}
// Setup everything onload
$(function () {
// Update html, according to data // Update html, according to data
if (rollData.competence) { if (rollData.competence) {
// Set the default carac from the competence item // Set the default carac from the competence item
@ -156,123 +126,142 @@ export class RdDRoll extends Dialog {
RdDItemSort.setCoutReveReel(rollData.selectedSort); RdDItemSort.setCoutReveReel(rollData.selectedSort);
$("#diffLibre").val(Misc.toInt(rollData.diffLibre)); $("#diffLibre").val(Misc.toInt(rollData.diffLibre));
$("#diffConditions").val(Misc.toInt(rollData.diffConditions)); $("#diffConditions").val(Misc.toInt(rollData.diffConditions));
updateRollResult(rollData); dialog.updateRollResult();
}); }
// Setup everything onload
$(function () { onLoad(); });
// Update ! // Update !
html.find('#diffLibre').change((event) => { html.find('#diffLibre').change((event) => {
rollData.diffLibre = Misc.toInt(event.currentTarget.value); // Update the selected bonus/malus this.rollData.diffLibre = Misc.toInt(event.currentTarget.value); // Update the selected bonus/malus
//console.log("RdDRollSelectDialog","BM CLICKED !!!", rollData); this.updateRollResult();
updateRollResult(rollData);
}); });
html.find('#diffConditions').change((event) => { html.find('#diffConditions').change((event) => {
rollData.diffConditions = Misc.toInt(event.currentTarget.value); // Update the selected bonus/malus this.rollData.diffConditions = Misc.toInt(event.currentTarget.value); // Update the selected bonus/malus
//console.log("RdDRollSelectDialog","BM CLICKED !!!", rollData); this.updateRollResult();
updateRollResult(rollData);
}); });
html.find('#carac').change((event) => { html.find('#carac').change((event) => {
let caracKey = event.currentTarget.value; let caracKey = event.currentTarget.value;
this.rollData.selectedCarac = rollData.carac[caracKey]; // Update the selectedCarac this.rollData.selectedCarac = this.rollData.carac[caracKey]; // Update the selectedCarac
//console.log("RdDRollSelectDialog","CARAC CLICKED !!!", rollData); this.updateRollResult();
updateRollResult(rollData);
}); });
html.find('#draconic').change((event) => { html.find('#draconic').change((event) => {
let draconicKey = Misc.toInt(event.currentTarget.value); let draconicKey = Misc.toInt(event.currentTarget.value);
this.rollData.competence = rollData.draconicList[draconicKey]; // Update the selectedCarac this.rollData.competence = this.rollData.draconicList[draconicKey]; // Update the selectedCarac
//console.log("RdDRollSelectDialog","CARAC CLICKED !!!", rollData); this.updateRollResult();
updateRollResult(rollData);
}); });
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 = this.rollData.sortList[sortKey]; // Update the selectedCarac
this.rollData.bonus = RdDItemSort.getCaseBonus(rollData.selectedSort, rollData.coord); this.rollData.bonus = RdDItemSort.getCaseBonus(this.rollData.selectedSort, this.rollData.coord);
RdDItemSort.setCoutReveReel(rollData.selectedSort); RdDItemSort.setCoutReveReel(this.rollData.selectedSort);
//console.log("RdDRollSelectDialog - Sort selection", rollData.selectedSort); this.updateRollResult();
updateRollResult(rollData);
}); });
html.find('#ptreve-variable').change((event) => { html.find('#ptreve-variable').change((event) => {
let ptreve = Misc.toInt(event.currentTarget.value); let ptreve = Misc.toInt(event.currentTarget.value);
this.rollData.selectedSort.data.ptreve_reel = ptreve; this.rollData.selectedSort.data.ptreve_reel = ptreve;
console.log("RdDRollSelectDialog - Cout reve", ptreve); console.log("RdDRollSelectDialog - Cout reve", ptreve);
updateRollResult(rollData); this.updateRollResult();
}); });
html.find('#ptreve-variable').change((event) => { html.find('#ptreve-variable').change((event) => {
let ptreve = Misc.toInt(event.currentTarget.value); let ptreve = Misc.toInt(event.currentTarget.value);
this.rollData.selectedSort.data.ptreve_reel = ptreve; // Update the selectedCarac this.rollData.selectedSort.data.ptreve_reel = ptreve; // Update the selectedCarac
console.log("RdDRollSelectDialog - Cout reve", ptreve); console.log("RdDRollSelectDialog - Cout reve", ptreve);
updateRollResult(rollData); this.updateRollResult();
}); });
html.find('#coupsNonMortels').change((event) => { html.find('#coupsNonMortels').change((event) => {
this.rollData.dmg.mortalite = event.currentTarget.checked ? "non-mortel" : "mortel"; this.rollData.dmg.mortalite = event.currentTarget.checked ? "non-mortel" : "mortel";
updateRollResult(rollData); this.updateRollResult();
}); });
html.find('#tactique-combat').change((event) => { html.find('#tactique-combat').change((event) => {
this.rollData.tactique = event.currentTarget.value; this.rollData.tactique = event.currentTarget.value;
updateRollResult(rollData); this.updateRollResult();
}); });
html.find('#surencMalusApply').change((event) => { html.find('#useMalusSurenc').change((event) => {
this.rollData.surencMalusApply = event.currentTarget.checked; this.rollData.useMalusSurenc = event.currentTarget.checked;
updateRollResult(rollData); this.updateRollResult();
}); });
html.find('#useMalusEncTotal').change((event) => { html.find('#useMalusEncTotal').change((event) => {
this.rollData.useMalusEncTotal = event.currentTarget.checked; this.rollData.useMalusEncTotal = event.currentTarget.checked;
updateRollResult(rollData); this.updateRollResult();
}); });
// Section Méditation // Section Méditation
html.find('#isHeure').change((event) => { html.find('.conditionMeditation').change((event) => {
this.rollData.isHeure = event.currentTarget.checked; let condition = event.currentTarget.attributes['id'].value;
updateRollResult(rollData); this.rollData.conditionMeditation[condition] = event.currentTarget.checked;
this.updateRollResult();
}); });
html.find('#isPurification').change((event) => {
this.rollData.isPurification = event.currentTarget.checked;
updateRollResult(rollData);
});
html.find('#isVeture').change((event) => {
this.rollData.isVeture = event.currentTarget.checked;
updateRollResult(rollData);
});
html.find('#isComportement').change((event) => {
this.rollData.isComportement = event.currentTarget.checked;
updateRollResult(rollData);
});
} }
/* -------------------------------------------- */ async updateRollResult() {
_isIgnoreEtatGeneral(rollData) { let rollData = this.rollData;
return rollData.selectedCarac.ignoreEtatGeneral;
rollData.dmg = rollData.attackerRoll?.dmg ?? RdDBonus.dmg(rollData, this.actor.getBonusDegat());
rollData.caracValue = parseInt(rollData.selectedCarac.value);
rollData.coupsNonMortels = (rollData.attackerRoll?.dmg.mortalite ?? rollData.dmg.mortalite) == 'non-mortel';
let dmgText = Misc.toSignedString(rollData.dmg.total);
if (rollData.coupsNonMortels) {
dmgText = '(' + dmgText + ')';
}
if (rollData.selectedSort) {
rollData.bonus = RdDItemSort.getCaseBonus(rollData.selectedSort, rollData.coord);
} }
/* -------------------------------------------- */ RollDataAjustements.calcul(rollData, this.actor);
_computeDiffMeditation( rollData ) { rollData.finalLevel = this._computeFinalLevel(rollData);
let diff = 0;
if ( rollData.meditation ) { HtmlUtility._showControlWhen($(".diffMoral"), rollData.ajustements.moralTotal.used);
diff = (!rollData.isHeure) ? diff - 2 : diff; HtmlUtility._showControlWhen($("#etat-general"), !RdDCarac.isIgnoreEtatGeneral(rollData.selectedCarac));
diff = (!rollData.isVeture) ? diff - 2 : diff; HtmlUtility._showControlWhen($("#ajust-astrologique"), RdDResolutionTable.isAjustementAstrologique(rollData));
diff = (!rollData.isComportement) ? diff - 2 : diff;
diff = (!rollData.isisPuritication) ? diff - 2 : diff; // Sort management
diff = diff - rollData.meditation.data.malus; // Malus permanent éventuel if (rollData.selectedSort) {
rollData.bonus = RdDItemSort.getCaseBonus(rollData.selectedSort, rollData.coord);
//console.log("Toggle show/hide", rollData.selectedSort);
HtmlUtility._showControlWhen($("#div-sort-difficulte"), RdDItemSort.isDifficulteVariable(rollData.selectedSort))
HtmlUtility._showControlWhen($("#div-sort-ptreve"), RdDItemSort.isCoutVariable(rollData.selectedSort))
} }
return diff;
// Mise à jour valeurs
$("#compdialogTitle").text(this._getTitle(rollData));
$('#coupsNonMortels').prop('checked', rollData.coupsNonMortels);
$("#dmg-arme-actor").text(dmgText);
$("#defenseur-surprise").text(RdDBonus.description(rollData.surpriseDefenseur));
$('.table-ajustement').remove();
$(".table-resolution").remove();
$(".table-proba-reussite").remove();
$("#tableAjustements").append(await this.buildAjustements(rollData));
$("#tableResolution").append(RdDResolutionTable.buildHTMLTableExtract(rollData.caracValue, rollData.finalLevel));
$("#tableProbaReussite").append(RdDResolutionTable.buildHTMLResults(rollData.caracValue, rollData.finalLevel));
}
async buildAjustements(rollData){
const html = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/dialog-roll-ajustements.html`, rollData);
return html;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
_computeFinalLevel(rollData) { _computeFinalLevel(rollData) {
const etat = this._isIgnoreEtatGeneral(rollData) ? 0 : Misc.toInt(rollData.etat); const etat = RdDCarac.isIgnoreEtatGeneral(rollData.selectedCarac) ? 0 : rollData.etat;
const diffConditions = Misc.toInt(rollData.diffConditions); const diffConditions = Misc.toInt(rollData.diffConditions);
const malusEnc = (rollData.surencMalusApply) ? rollData.surencMalusValue : 0; const malusSurenc = (rollData.useMalusSurenc) ? rollData.surencMalusValue : 0;
const bonusTactique = RdDBonus.bonusAttaque(rollData.tactique); const bonusTactique = RdDBonus.bonusAttaque(rollData.tactique);
const malusEncTotal = (rollData.useMalusEncTotal) ? -rollData.encTotal : 0; const malusEncTotal = (rollData.useMalusEncTotal) ? -rollData.encTotal : 0;
const ajustementChance = RdDResolutionTable.isAjustementAstrologique(rollData) ? rollData.ajustementAstrologique : 0; const ajustementChance = RdDResolutionTable.isAjustementAstrologique(rollData) ? rollData.ajustementAstrologique : 0;
// Gestion malus armure // Gestion malus armure
const malusArmureValue = this._computeMalusArmure(rollData); const malusArmureValue = this._computeMalusArmure(rollData);
const diffMeditation = this._computeDiffMeditation( rollData ); const diffMeditation = RdDItemMeditation.calculDifficulte(rollData);
const diffLibre = this._computeDiffLibre(rollData); const diffLibre = this._computeDiffLibre(rollData);
const diffCompetence = this._computeDiffCompetence(rollData); const diffCompetence = this._computeDiffCompetence(rollData);
const diffMoral = rollData.selectedCarac == this.actor.data.data.carac.volonte ? rollData.moral : 0; const diffMoral = rollData.selectedCarac == this.actor.data.data.carac.volonte ? rollData.moral : 0;
return etat + diffCompetence + diffLibre + diffMoral + diffConditions + malusEnc + malusEncTotal + malusArmureValue + diffMeditation + ajustementChance + bonusTactique; let ajust = RollDataAjustements.sum(rollData.ajustements);
return ajust;
//return etat + diffCompetence + diffLibre + diffMoral + diffConditions + malusSurenc + malusEncTotal + malusArmureValue + diffMeditation + ajustementChance + bonusTactique;
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -297,7 +286,7 @@ export class RdDRoll extends Dialog {
_computeMalusArmure(rollData) { _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 && (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);
malusArmureValue = rollData.malusArmureValue; malusArmureValue = rollData.malusArmureValue;
} else { } else {

View File

@ -239,7 +239,7 @@ export class RdDTMRDialog extends Dialog {
const draconic = this.actor.getBestDraconic(); const draconic = this.actor.getBestDraconic();
const carac = this.actor.getReveActuel(); const carac = this.actor.getReveActuel();
const etatGeneral = this.actor.data.data.compteurs.etat.value; const etatGeneral = this.actor.getEtatGeneral();
const difficulte = draconic.data.niveau - this.currentRencontre.force + etatGeneral; const difficulte = draconic.data.niveau - this.currentRencontre.force + etatGeneral;
console.log("Maitriser", carac, draconic.data.niveau, this.currentRencontre.force, etatGeneral); console.log("Maitriser", carac, draconic.data.niveau, this.currentRencontre.force, etatGeneral);
@ -329,7 +329,7 @@ export class RdDTMRDialog extends Dialog {
tmrpos.innerHTML = this.actor.data.data.reve.tmrpos.coord + " (" + tmr.label + ")"; tmrpos.innerHTML = this.actor.data.data.reve.tmrpos.coord + " (" + tmr.label + ")";
let etat = document.getElementById("tmr-etatgeneral-value"); let etat = document.getElementById("tmr-etatgeneral-value");
etat.innerHTML = this.actor.data.data.compteurs.etat.value; etat.innerHTML = this.actor.getEtatGeneral();
let refoulement = document.getElementById("tmr-refoulement-value"); let refoulement = document.getElementById("tmr-refoulement-value");
refoulement.innerHTML = this.actor.data.data.reve.refoulement.value; refoulement.innerHTML = this.actor.data.data.reve.refoulement.value;
@ -389,7 +389,7 @@ export class RdDTMRDialog extends Dialog {
let draconic = this.actor.getBestDraconic(); let draconic = this.actor.getBestDraconic();
let carac = this.actor.getReveActuel(); let carac = this.actor.getReveActuel();
const etatGeneral = this.actor.data.data.compteurs.etat.value const etatGeneral = this.actor.getEtatGeneral();
let difficulte = draconic.data.niveau - 7; let difficulte = draconic.data.niveau - 7;
let rolled = await RdDResolutionTable.roll(carac, difficulte); let rolled = await RdDResolutionTable.roll(carac, difficulte);

View File

@ -183,6 +183,7 @@ export class RdDUtility {
'systems/foundryvtt-reve-de-dragon/templates/niveau-ethylisme.html', 'systems/foundryvtt-reve-de-dragon/templates/niveau-ethylisme.html',
'systems/foundryvtt-reve-de-dragon/templates/casetmr-specific-list.html', 'systems/foundryvtt-reve-de-dragon/templates/casetmr-specific-list.html',
// Dialogs // Dialogs
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-ajustements.html',
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-resolution.html', 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-resolution.html',
'systems/foundryvtt-reve-de-dragon/templates/dialog-competence.html', 'systems/foundryvtt-reve-de-dragon/templates/dialog-competence.html',
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html', 'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html',
@ -673,10 +674,8 @@ export class RdDUtility {
/* -------------------------------------------- */ /* -------------------------------------------- */
static currentFatigueMalus( value, max) static currentFatigueMalus( value, max)
{ {
max = (max < 16) ? 16 : max; max = Math.max(1, Math.min(max, 60));
max = (max > 30) ? 30 : max; value = Math.min(max*2, Math.max(0, value));
value = (value > max*2) ? max*2 : value;
value = (value < 0) ? 0 : value;
let fatigueTab = fatigueMatrix[max]; let fatigueTab = fatigueMatrix[max];
let fatigueRem = value; let fatigueRem = value;

View File

@ -0,0 +1,150 @@
import { RdDItemArme } from "./item-arme.js";
import { RdDItemCompetence } from "./item-competence.js";
import { RdDItemMeditation } from "./item-meditation.js";
import { RdDItemSort } from "./item-sort.js";
import { Misc } from "./misc.js";
import { RdDBonus } from "./rdd-bonus.js";
import { RdDCarac } from "./rdd-carac.js";
/**
* tous les ajustements pouvant s'appliquer.
* un ajustement se compose de `function(rollData, actor)` :
* - isVisible: indique si l'ajustement sera visible (pour les cas il peut être sélectionné)
* - isUsed: évalue si l'ajustement indique s'il est actif ou non
* - getLabel: un libellé texte pour l'affichage de l'ajustement
* - getValue: une valeur numérique correspondant à un modificateur entier
* - getDescr: une valeur textuelle pour les informations non numériques (demi-surprise, bonus de case, ...)
*/
export const referenceAjustements = {
competence: {
isUsed: (rollData, actor) => rollData.competence,
getLabel: (rollData, actor) => rollData.competence?.name,
getValue: (rollData, actor) => rollData.competence?.data?.niveau,
},
meditation: {
isUsed: (rollData, actor) => rollData.meditation,
getLabel: (rollData, actor) => 'Méditation',
getValue: (rollData, actor) => RdDItemMeditation.calculDifficulte(rollData)
},
diffLibre: {
isUsed: (rollData, actor) => rollData.diffLibre != undefined,
getLabel: (rollData, actor) => rollData.selectedSort?.name ?? rollData.attackerRoll ? 'Imposée' : 'Libre',
getValue: (rollData, actor) => rollData.selectedSort
? RdDItemSort.getDifficulte(rollData.selectedSort, rollData.diffLibre)
: rollData.diffLibre ?? rollData.competence?.data.default_diffLibre ?? 0
},
diffConditions: {
isUsed: (rollData, actor) => rollData.diffConditions != undefined,
getLabel: (rollData, actor) => 'Conditions',
getValue: (rollData, actor) => rollData.diffConditions
},
tactique: {
isUsed: (rollData, actor) => rollData.tactique,
getLabel: (rollData, actor) => RdDBonus.find(rollData.tactique).descr,
getValue: (rollData, actor) => RdDBonus.find(rollData.tactique).attaque,
},
attaqueDefenseurSurpris: {
isUsed: (rollData, actor) => rollData.surpriseDefenseur,
getLabel: (rollData, actor) => RdDBonus.find(rollData.surpriseDefenseur).descr,
getValue: (rollData, actor) => RdDBonus.find(rollData.surpriseDefenseur).attaque,
},
etat: {
isUsed: (rollData, actor) => !RdDCarac.isIgnoreEtatGeneral(rollData.selectedCarac),
getLabel: (rollData, actor) => 'Etat général',
getValue: (rollData, actor) => actor.getEtatGeneral()
},
malusArmure: {
isVisible: (rollData, actor) => RdDCarac.isAgiliteOuDerivee(rollData.competence),
isUsed: (rollData, actor) => RdDCarac.isAgiliteOuDerivee(rollData.selectedCarac),
getLabel: (rollData, actor) => 'Malus armure',
getValue: (rollData, actor) => actor.getMalusArmure()
},
encTotal: {
isVisible: (rollData, actor) => RdDItemCompetence.isMalusEncombrementTotal(rollData.competence),
isUsed: (rollData, actor) => rollData.useMalusEncTotal,
getLabel: (rollData, actor) => 'Encombrement total',
getValue: (rollData, actor) => -actor.getEncTotal()
},
surenc: {
isVisible: (rollData, actor) => rollData.useMalusSurenc,
isUsed: (rollData, actor) => rollData.useMalusSurenc,
getLabel: (rollData, actor) => 'Sur-encombrement',
getValue: (rollData, actor) => actor.getSurenc()
},
moral: {
isVisible: (rollData, actor) => RdDCarac.isActionPhysique(rollData.selectedCarac),
isUsed: (rollData, actor) => rollData.use?.moral,
getLabel: (rollData, actor) => 'Moral',
getValue: (rollData, actor) => 1
},
moralTotal: {
isUsed: (rollData, actor) => RdDCarac.isVolonte(rollData.selectedCarac),
getLabel: (rollData, actor) => 'Moral',
getValue: (rollData, actor) => actor.getMoralTotal()
},
astrologique: {
isUsed: (rollData, actor) => RdDBonus.isAjustementAstrologique(rollData),
getLabel: (rollData, actor) => 'Astrologique',
getValue: (rollData, actor) => actor.ajustementAstrologique()
},
facteurSign: {
isUsed: (rollData, actor) => rollData.diviseur > 1,
getDescr: (rollData, actor) => rollData.diviseur > 1 ? `Facteur significative &times;${Misc.getFractionHtml(rollData.diviseur)}` : ''
},
finesse: {
isUsed: (rollData, actor) => RdDBonus.isDefenseAttaqueFinesse(rollData),
getDescr: (rollData, actor) => 'Attaque particulière en finesse',
},
armeParade: {
isUsed: (rollData, actor) => RdDItemArme.needParadeSignificative(rollData.attackerRoll?.arme, rollData.arme),
getDescr: (rollData, actor) => rollData.attackerRoll && rollData.arme? `${RdDItemArme.getNomCategorieParade(rollData.attackerRoll?.arme)} vs ${RdDItemArme.getNomCategorieParade(rollData.arme)}`: ''
},
surprise: {
isUsed: (rollData, actor) => actor.getSurprise(),
getDescr: (rollData, actor) => RdDBonus.find(actor.getSurprise()).descr
},
bonusCase: {
isUsed: (rollData, actor) => rollData.selectedSort && rollData.coord,
getDescr: (rollData, actor) => rollData.selectedSort && rollData.coord ? `Bonus de case: ${RdDItemSort.getCaseBonus(rollData.selectedSort, rollData.coord)}%`: ''
}
}
export class RollDataAjustements {
/* -------------------------------------------- */
static calcul(rollData, actor) {
rollData.ajustements = {};
for (var key in referenceAjustements) {
const reference = referenceAjustements[key];
rollData.ajustements[key] = {
used: reference.isUsed(rollData, actor),
label: reference.getLabel && reference.getLabel(rollData, actor),
value: reference.getValue && reference.getValue(rollData, actor),
descr: reference.getDescr && reference.getDescr(rollData, actor)
}
}
}
// /* -------------------------------------------- */
// static calculListe(ajustements, rollData, actor) {
// let list = [];
// for (var key in referenceAjustements) {
// if (referenceAjustements[key].isUsed(rollData, actor)) {
// list.push(Ajustements._apply(referenceAjustements[key], rollData, actor));
// }
// }
// return list;
// }
/* -------------------------------------------- */
static sum(ajustements) {
let sum = 0;
for (var key in ajustements) {
if (ajustements[key].used && !ajustements[key].descr) {
sum += ajustements[key].value;
}
}
return sum;
}
}

View File

@ -410,7 +410,7 @@ table {border: 1px solid #7a7971;}
background-color: lightblue; background-color: lightblue;
} }
#resolutionValeurs{ #tableProbaReussite{
font-size: 0.8rem; font-size: 0.8rem;
padding: 5px; padding: 5px;
} }
@ -737,6 +737,9 @@ ul, li {
.rdd-hud-menu label { .rdd-hud-menu label {
font-size: 0.75rem; font-size: 0.75rem;
} }
#token-hud .status-effects.active{
z-index: 2;
}
/* ======================================== */ /* ======================================== */
.item-checkbox { .item-checkbox {
height: 25px; height: 25px;
@ -1253,7 +1256,7 @@ display: inline-flex;
.tooltip .ttt-ajustements { .tooltip .ttt-ajustements {
width: 150px; width: 150px;
background: rgba(220,220,210,0.9); background: rgba(220,220,210,0.95);
border-radius: 6px; border-radius: 6px;
font-size: 0.9rem; font-size: 0.9rem;
padding: 3px 0; padding: 3px 0;

View File

@ -4,6 +4,7 @@
{{#if ajustements}} {{#if ajustements}}
<div class="tooltiptext ttt-ajustements"> <div class="tooltiptext ttt-ajustements">
{{#each ajustements as |item key|}} {{#each ajustements as |item key|}}
{{#if item.used}}
<div class="{{#if item.strong}}strong-text{{/if}}"> <div class="{{#if item.strong}}strong-text{{/if}}">
{{#if item.descr}} {{#if item.descr}}
{{{item.descr}}} {{{item.descr}}}
@ -11,6 +12,7 @@
{{item.label}}: {{numberFormat item.value decimals=0 sign=true}} {{item.label}}: {{numberFormat item.value decimals=0 sign=true}}
{{/if}} {{/if}}
</div> </div>
{{/if}}
{{/each}} {{/each}}
</div> </div>
{{/if}} {{/if}}

View File

@ -1,5 +1,5 @@
<h4>{{alias}} attaque: {{arme.name}}</h4> <h4>{{alias}} attaque: {{arme.name}}</h4>
<div>{{selectedCarac.label}} / {{competence.name}}, difficulté {{diffLibre}}</div> <div>{{selectedCarac.label}}{{#unless (eq selectedCarac.label competence.name)}} / {{competence.name}}{{/unless}}, difficulté {{diffLibre}}</div>
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}} {{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
<hr> <hr>
{{#if tactique}} {{#if tactique}}

View File

@ -1,7 +1,9 @@
<h4> <h4>
{{alias}} {{show.title}}: {{alias}} {{show.title}}:
{{#if selectedCarac}}{{selectedCarac.label}} {{#if selectedCarac}}{{selectedCarac.label}}
{{#if competence}} / {{competence.name}}{{/if}} {{#if competence}}
{{#unless (eq selectedCarac.label competence.name)}} / {{competence.name}}{{/unless}} / {{competence.name}}
{{/if}}
{{/if}} {{/if}}
</h4> </h4>
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}} {{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}

View File

@ -1,5 +1,5 @@
<h4>{{alias}} esquive</h4> <h4>{{alias}} esquive une attaque à {{diffLibre}}</h4>
<div>{{selectedCarac.label}} / {{competence.name}} attaque à {{diffLibre}}</div> <div>{{selectedCarac.label}}{{#unless (eq selectedCarac.label competence.name)}} / {{competence.name}}{{/unless}}</div>
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}} {{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
<hr> <hr>
<div> <div>

View File

@ -1,7 +1,7 @@
<h4> <h4>
{{alias}} {{#if show.title}}{{show.title}}: {{/if}} {{alias}} {{#if show.title}}{{show.title}}: {{/if}}
{{#if selectedCarac}}{{selectedCarac.label}} {{#if selectedCarac}}{{selectedCarac.label}}
{{#if competence}} / {{competence.name}}{{/if}} {{#if competence}}{{#unless (eq selectedCarac.label competence.name)}} / {{competence.name}}{{/unless}}{{/if}}
à {{diffLibre}} à {{diffLibre}}
{{/if}} {{/if}}
</h4> </h4>

View File

@ -1,5 +1,5 @@
<h4>{{alias}} pare: {{arme.name}}</h4> <h4>{{alias}} pare une attaque à {{diffLibre}} - {{arme.name}}</h4>
<div>{{selectedCarac.label}} / {{competence.name}}, attaque à {{diffLibre}}</div> <div>{{selectedCarac.label}}{{#unless (eq selectedCarac.label competence.name)}} / {{competence.name}}{{/unless}}</div>
{{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}} {{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}}
<hr> <hr>
<div> <div>

View File

@ -59,18 +59,15 @@
{{/if}} {{/if}}
</div> </div>
{{/if}} {{/if}}
<div class="form-group">
<label for="categorie">Ajustements</label>
<label for="categorie">Etat général: {{numberFormat etat decimals=0 sign=true}}</label>
<label for="categorie" id="ajust-astrologique">Astrologique: {{numberFormat ajustementAstrologique decimals=0 sign=true}}</label>
<label>Final: <label id="roll-param">10 / 0</label>&nbsp;&nbsp;&nbsp;<label name="addon-message" id="addon-message"></label></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-enctotal.html"}} {{>"systems/foundryvtt-reve-de-dragon/templates/dialog-roll-enctotal.html"}}
<div id="resolutionTable">
<div id="tableAjustements">
</div> </div>
<div id="resolutionValeurs"> <div id="tableResolution">
</div>
<div id="tableProbaReussite">
</div> </div>
</form> </form>

View File

@ -0,0 +1,19 @@
<div class="table-ajustement">
<label class="tooltip">
<span>Ajustement Final:</span>
<span id="roll-param">{{selectedCarac.value}} / {{numberFormat finalLevel decimals=0 sign=true}}</span>
<div class="tooltiptext ttt-ajustements">
{{#each ajustements as |item key|}}
{{#if item.used}}
<div class="{{#if item.strong}}strong-text{{/if}}">
{{#if item.descr}}
{{{item.descr}}}
{{else}}
{{item.label}}: {{numberFormat item.value decimals=0 sign=true}}
{{/if}}
</div>
{{/if}}
{{/each}}
</div>
</label>
</div>

View File

@ -20,15 +20,11 @@
<label class="diffMoral" for="categorie">Moral: {{#if (gt moral 0)}}+{{/if}}{{moral}}</label> <label class="diffMoral" for="categorie">Moral: {{#if (gt moral 0)}}+{{/if}}{{moral}}</label>
</div> </div>
{{>"systems/foundryvtt-reve-de-dragon/templates/dialog-roll-surenc.html"}} {{>"systems/foundryvtt-reve-de-dragon/templates/dialog-roll-surenc.html"}}
<div class="form-group"> <div id="tableAjustements">
<label for="categorie">Ajustements</label>
<label for="categorie" id="etat-general">Etat général: {{numberFormat etat decimals=0 sign=true}}</label>
<label for="categorie" id="ajust-astrologique">Astrologique: {{numberFormat ajustementAstrologique decimals=0 sign=true}}</label>
<label>Final: <label id="roll-param">10 / 0</label>&nbsp;&nbsp;&nbsp;<label name="addon-message" id="addon-message"></label></label>
</div> </div>
<div id="resolutionTable"> <div id="tableResolution">
</div> </div>
<div id="resolutionValeurs"> <div id="tableProbaReussite">
</div> </div>
</form> </form>

View File

@ -1,6 +1,7 @@
{{#if isMalusEncombrementTotal}} {{#if ajustements.encTotal.visible}}
<div class="form-group"> <div class="form-group">
<label for="xp">Appliquer l'encombrement total comme malus (-{{encTotal}} ) ? </label> <label>Appliquer l'encombrement total comme malus ({{encTotal}}) ? </label>
<input class="attribute-value" type="checkbox" id="useMalusEncTotal" name="useMalusEncTotal" {{#if useMalusEncTotal}}checked{{/if}}/> <input class="attribute-value" type="checkbox" id="ajustements-encTotal-apply"
name="ajustements.encTotal.apply" {{#if ajustements.encTotal.apply}}checked{{/if}}/>
</div> </div>
{{/if}} {{/if}}

View File

@ -21,9 +21,9 @@
<label>Ajustement final : <label id="roll-param">10 / 0</label>&nbsp;&nbsp;&nbsp;<label name="addon-message" id="addon-message"></label></label> <label>Ajustement final : <label id="roll-param">10 / 0</label>&nbsp;&nbsp;&nbsp;<label name="addon-message" id="addon-message"></label></label>
</div> </div>
<div id="resolutionTable"> <div id="tableResolution">
</div> </div>
<div id="resolutionValeurs"> <div id="tableProbaReussite">
</div> </div>
</form> </form>

View File

@ -24,19 +24,19 @@
<ul class="item-list"> <ul class="item-list">
<li class="item flexrow"> <li class="item flexrow">
<label for="categorie">Heure : {{meditation.data.heure}}</label> <label for="categorie">Heure : {{meditation.data.heure}}</label>
<input class="attribute-value" type="checkbox" id="isHeure" name="isHeure" {{#if isHeure}}checked{{/if}}/> <input class="attribute-value conditionMeditation" type="checkbox" id="isHeure" {{#if conditionMeditation.isHeure}}checked{{/if}}/>
</li> </li>
<li class="item flexrow"> <li class="item flexrow">
<label for="categorie">Purification : {{meditation.data.purification}}</label> <label for="categorie">Purification : {{meditation.data.purification}}</label>
<input class="attribute-value" type="checkbox" id="isPurification" name="isPurification" {{#if isPurification}}checked{{/if}}/> <input class="attribute-value conditionMeditation" type="checkbox" id="isPurification" {{#if conditionMeditation.isPurification}}checked{{/if}}/>
</li> </li>
<li class="item flexrow"> <li class="item flexrow">
<label for="categorie">Vêture : {{meditation.data.veture}}</label> <label for="categorie">Vêture : {{meditation.data.veture}}</label>
<input class="attribute-value" type="checkbox" id="isVeture" name="isVeture" {{#if isVeture}}checked{{/if}}/> <input class="attribute-value conditionMeditation" type="checkbox" id="isVeture" {{#if conditionMeditation.isVeture}}checked{{/if}}/>
</li> </li>
<li class="item flexrow"> <li class="item flexrow">
<label for="categorie">Comportement antérieur : {{meditation.data.comportement}})</label> <label for="categorie">Comportement antérieur : {{meditation.data.comportement}}</label>
<input class="attribute-value" type="checkbox" id="isComportement" name="isComportement" {{#if isComportement}}checked{{/if}}/> <input class="attribute-value conditionMeditation" type="checkbox" id="isComportement" {{#if conditionMeditation.isComportement}}checked{{/if}}/>
</li> </li>
</ul> </ul>
@ -51,14 +51,11 @@
</select> </select>
</div> </div>
<div class="form-group"> <div id="tableAjustements">
<label for="categorie">Ajustements</label>
<label for="categorie" id="etat-general">Etat général: {{numberFormat etat decimals=0 sign=true}}</label>
<label>Final: <label id="roll-param">10 / 0</label>&nbsp;&nbsp;&nbsp;<label name="addon-message" id="addon-message"></label></label>
</div> </div>
<div id="resolutionTable"> <div id="tableResolution">
</div> </div>
<div id="resolutionValeurs"> <div id="tableProbaReussite">
</div> </div>
</form> </form>

View File

@ -28,9 +28,11 @@
{{/select}} {{/select}}
</select> </select>
</div> </div>
<div id="resolutionTable"> <div id="tableAjustements">
</div> </div>
<div id="resolutionValeurs"> <div id="tableResolution">
</div>
<div id="tableProbaReussite">
</div> </div>
</form> </form>

View File

@ -57,15 +57,11 @@
</select> </select>
</div> </div>
<div class="form-group"> <div id="tableAjustements">
<label for="categorie">Ajustements</label>
<label for="categorie" id="etat-general">Etat général: {{numberFormat etat decimals=0 sign=true}}</label>
<label for="categorie" id="ajust-astrologique">Astrologique: {{numberFormat ajustementAstrologique decimals=0 sign=true}}</label>
<label>Final: <label id="roll-param">10 / 0</label>&nbsp;&nbsp;&nbsp;<label name="addon-message" id="addon-message"></label></label>
</div> </div>
<div id="resolutionTable"> <div id="tableResolution">
</div> </div>
<div id="resolutionValeurs"> <div id="tableProbaReussite">
</div> </div>
</form> </form>

View File

@ -1,6 +1,6 @@
{{#if surencMalusFlag}} {{#if surencMalusFlag}}
<div class="form-group"> <div class="form-group">
<label for="xp">Appliquer le malus de sur-encombrement ? </label> <label for="xp">Appliquer le malus de sur-encombrement ? </label>
<input class="attribute-value" type="checkbox" id="surencMalusApply" name="surencMalusApply" {{#if surencMalusApply}}checked{{/if}}/> <input class="attribute-value" type="checkbox" id="useMalusSurenc" name="useMalusSurenc" {{#if useMalusSurenc}}checked{{/if}}/>
</div> </div>
{{/if}} {{/if}}