Merge pull request 'v10' (#564) from VincentVk/foundryvtt-reve-de-dragon:v10 into v10
Reviewed-on: #564
This commit is contained in:
commit
14e76ac631
102
module/actor.js
102
module/actor.js
@ -33,8 +33,9 @@ import { RollDataAjustements } from "./rolldata-ajustements.js";
|
||||
import { DialogItemAchat } from "./dialog-item-achat.js";
|
||||
import { RdDItem } from "./item.js";
|
||||
import { RdDPossession } from "./rdd-possession.js";
|
||||
import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
||||
import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE, HIDE_DICE, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
||||
import { RdDConfirm } from "./rdd-confirm.js";
|
||||
import { DialogValidationEncaissement } from "./dialog-validation-encaissement.js";
|
||||
|
||||
const POSSESSION_SANS_DRACONIC = {
|
||||
img: 'systems/foundryvtt-reve-de-dragon/icons/entites/possession.webp',
|
||||
@ -120,7 +121,7 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
|
||||
if (isPersonnage) {
|
||||
const competences = await RdDUtility.loadCompendium(RdDItemCompetence.actorCompendium(actorData.type));
|
||||
const competences = await RdDUtility.loadItems(it => it.isCompetencePersonnage(), 'foundryvtt-reve-de-dragon.competences');
|
||||
actorData.items = competences.map(i => i.toObject());
|
||||
actorData.items = actorData.items.concat(Monnaie.monnaiesStandard());
|
||||
}
|
||||
@ -343,7 +344,7 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getDraconicList() {
|
||||
return this.items.filter(it => it.type == 'competence' && it.system.categorie == 'draconic')
|
||||
return this.items.filter(it => it.isCompetencePersonnage() && it.system.categorie == 'draconic')
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
getBestDraconic() {
|
||||
@ -2317,7 +2318,7 @@ export class RdDActor extends Actor {
|
||||
case "detection d'aura":
|
||||
return draconicList;
|
||||
case "annulation de magie":
|
||||
return draconicList.filter(it => !Grammar.toLowerCaseNoAccent(it.name).includes('thanatos'));
|
||||
return draconicList.filter(it => !RdDItemCompetence.isThanatos(it));
|
||||
}
|
||||
return [RdDItemCompetence.getVoieDraconic(draconicList, sort.system.draconic)];
|
||||
}
|
||||
@ -3330,20 +3331,39 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async encaisserDommages(rollData, attacker = undefined, defenderRoll = undefined) {
|
||||
async encaisserDommages(rollData, attacker = undefined, show = undefined) {
|
||||
if (attacker && !await attacker.accorder(this, 'avant-encaissement')) {
|
||||
return;
|
||||
}
|
||||
this.validerEncaissement(rollData, show);
|
||||
}
|
||||
|
||||
console.log("encaisserDommages", rollData)
|
||||
async validerEncaissement(rollData, show) {
|
||||
if (ReglesOptionelles.isUsing('validation-encaissement-gr') && !game.user.isGM) {
|
||||
RdDActor.remoteActorCall({
|
||||
actorId: this.id,
|
||||
method: 'validerEncaissement',
|
||||
args: [rollData, show]
|
||||
});
|
||||
return;
|
||||
}
|
||||
const armure = await this.computeArmure(rollData);
|
||||
if (ReglesOptionelles.isUsing('validation-encaissement-gr')) {
|
||||
DialogValidationEncaissement.validerEncaissement(this, rollData, armure, show, (encaissement, show) => this._appliquerEncaissement(encaissement, show));
|
||||
}
|
||||
else {
|
||||
let encaissement = await RdDUtility.jetEncaissement(rollData, armure, { showDice: SHOW_DICE });
|
||||
await this._appliquerEncaissement(encaissement, show)
|
||||
}
|
||||
}
|
||||
|
||||
async _appliquerEncaissement(encaissement, show) {
|
||||
let santeOrig = duplicate(this.system.sante);
|
||||
let encaissement = await this.jetEncaissement(rollData);
|
||||
|
||||
this.ajouterBlessure(encaissement); // Will upate the result table
|
||||
const perteVie = this.isEntite()
|
||||
? { newValue: 0 }
|
||||
: await this.santeIncDec("vie", - encaissement.vie);
|
||||
: await this.santeIncDec("vie", -encaissement.vie);
|
||||
const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance, encaissement.critiques > 0);
|
||||
|
||||
this.computeEtatGeneral();
|
||||
@ -3356,7 +3376,7 @@ export class RdDActor extends Actor {
|
||||
jetEndurance: perteEndurance.jetEndurance,
|
||||
endurance: santeOrig.endurance.value - perteEndurance.newValue,
|
||||
vie: this.isEntite() ? 0 : (santeOrig.vie.value - perteVie.newValue),
|
||||
show: defenderRoll?.show ?? {}
|
||||
show: show ?? {}
|
||||
});
|
||||
|
||||
await ChatUtility.createChatWithRollMode(this.name, {
|
||||
@ -3374,65 +3394,6 @@ export class RdDActor extends Actor {
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async jetEncaissement(rollData) {
|
||||
let formula = "2d10";
|
||||
|
||||
// Chaque dé fait au minmum la difficulté libre
|
||||
if (ReglesOptionelles.isUsing('degat-minimum-malus-libre')) {
|
||||
if (rollData.diffLibre < 0) {
|
||||
let valeurMin = Math.abs(rollData.diffLibre);
|
||||
formula += "min" + valeurMin;
|
||||
}
|
||||
}
|
||||
// Chaque dé fait au minmum la difficulté libre
|
||||
if (ReglesOptionelles.isUsing('degat-ajout-malus-libre')) {
|
||||
if (rollData.diffLibre < 0) {
|
||||
let valeurMin = Math.abs(rollData.diffLibre);
|
||||
formula += "+" + valeurMin;
|
||||
}
|
||||
}
|
||||
|
||||
let roll = await RdDDice.roll(formula);
|
||||
|
||||
// 1 dé fait au minmum la difficulté libre
|
||||
if (ReglesOptionelles.isUsing('degat-minimum-malus-libre-simple')) {
|
||||
if (rollData.diffLibre < 0) {
|
||||
let valeurMin = Math.abs(rollData.diffLibre);
|
||||
if (roll.terms[0].results[0].result < valeurMin) {
|
||||
roll.terms[0].results[0].result = valeurMin;
|
||||
} else if (roll.terms[0].results[1].result < valeurMin) {
|
||||
roll.terms[0].results[1].result = valeurMin;
|
||||
}
|
||||
roll._total = roll.terms[0].results[0].result + roll.terms[0].results[1].result;
|
||||
}
|
||||
}
|
||||
|
||||
const armure = await this.computeArmure(rollData);
|
||||
const jetTotal = roll.total + rollData.dmg.total - armure;
|
||||
|
||||
let encaissement = RdDUtility.selectEncaissement(jetTotal, rollData.dmg.mortalite)
|
||||
let over20 = Math.max(jetTotal - 20, 0);
|
||||
encaissement.dmg = rollData.dmg;
|
||||
encaissement.dmg.loc = rollData.dmg.loc ?? await RdDUtility.getLocalisation(this.type);
|
||||
encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;'
|
||||
encaissement.roll = roll;
|
||||
encaissement.armure = armure;
|
||||
encaissement.total = jetTotal;
|
||||
encaissement.vie = await RdDActor._evaluatePerte(encaissement.vie, over20);
|
||||
encaissement.endurance = await RdDActor._evaluatePerte(encaissement.endurance, over20);
|
||||
encaissement.penetration = rollData.arme?.system.penetration ?? 0;
|
||||
|
||||
return encaissement;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async _evaluatePerte(formula, over20) {
|
||||
let perte = new Roll(formula, { over20: over20 });
|
||||
await perte.evaluate({ async: true });
|
||||
return perte.total;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
ajouterBlessure(encaissement) {
|
||||
if (this.type == 'entite') return; // Une entité n'a pas de blessures
|
||||
@ -3699,8 +3660,7 @@ export class RdDActor extends Actor {
|
||||
actorId: achat.vendeurId ?? achat.acheteurId,
|
||||
method: 'achatVente',
|
||||
args: [achat]
|
||||
},
|
||||
);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4140,7 +4100,7 @@ export class RdDActor extends Actor {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async onPreUpdateItem(item, change, options, id) {
|
||||
if (item.type == 'competence' && item.system.defaut_carac && item.system.xp) {
|
||||
if (item.isCompetencePersonnage() && item.system.defaut_carac && item.system.xp) {
|
||||
await this.checkCompetenceXP(item.name, item.system.xp);
|
||||
}
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ export class ChatUtility {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static getUsers(filter) {
|
||||
return Misc.getUsers().filter(filter).map(user => user.id);
|
||||
return game.users.filter(filter).map(user => user.id);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
70
module/dialog-validation-encaissement.js
Normal file
70
module/dialog-validation-encaissement.js
Normal file
@ -0,0 +1,70 @@
|
||||
import { HIDE_DICE, SHOW_DICE } from "./constants.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
|
||||
/**
|
||||
* Extend the base Dialog entity by defining a custom window to perform roll.
|
||||
* @extends {Dialog}
|
||||
*/
|
||||
export class DialogValidationEncaissement extends Dialog {
|
||||
|
||||
static async validerEncaissement(actor, rollData, armure, show, onEncaisser) {
|
||||
let encaissement = await RdDUtility.jetEncaissement(rollData, armure, { showDice: HIDE_DICE });
|
||||
const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-validation-encaissement.html', {
|
||||
actor: actor,
|
||||
rollData: rollData,
|
||||
encaissement: encaissement,
|
||||
show: show
|
||||
});
|
||||
const dialog = new DialogValidationEncaissement(html, actor, rollData, armure, encaissement, show, onEncaisser);
|
||||
dialog.render(true);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
constructor(html, actor, rollData, armure, encaissement, show, onEncaisser) {
|
||||
// Common conf
|
||||
let buttons = {
|
||||
"valider": { label: "Valider", callback: html => this.validerEncaissement() },
|
||||
"annuler": { label: "Annuler", callback: html => { } },
|
||||
};
|
||||
|
||||
let dialogConf = {
|
||||
title: "Validation d'encaissement",
|
||||
content: html,
|
||||
buttons: buttons,
|
||||
default: "valider"
|
||||
}
|
||||
|
||||
let dialogOptions = {
|
||||
classes: ["rdddialog"],
|
||||
width: 350,
|
||||
height: 290
|
||||
}
|
||||
|
||||
// Select proper roll dialog template and stuff
|
||||
super(dialogConf, dialogOptions);
|
||||
|
||||
this.actor = actor
|
||||
this.rollData = rollData;
|
||||
this.armure = armure;
|
||||
this.encaissement = encaissement;
|
||||
this.show = show;
|
||||
this.onEncaisser = onEncaisser;
|
||||
this.forceDiceResult = {total: encaissement.roll.result };
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
html.find('input.encaissement-roll-result').keyup(async event => {
|
||||
this.forceDiceResult.total = event.currentTarget.value;
|
||||
this.encaissement = await RdDUtility.jetEncaissement(this.rollData, this.armure, { showDice: HIDE_DICE, forceDiceResult: this.forceDiceResult});
|
||||
$('label.encaissement-total').text(this.encaissement.total);
|
||||
$('label.encaissement-blessure').text(this.encaissement.blessures)
|
||||
});
|
||||
}
|
||||
|
||||
async validerEncaissement() {
|
||||
this.encaissement = await RdDUtility.jetEncaissement(this.rollData, this.armure, { showDice: SHOW_DICE, forceDiceResult: this.forceDiceResult});
|
||||
this.onEncaisser(this.encaissement, this.show)
|
||||
}
|
||||
}
|
@ -57,8 +57,8 @@ const competence_xp_cumul = _buildCumulXP();
|
||||
export class RdDItemCompetence extends Item {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static actorCompendium(actorType) {
|
||||
return compendiumCompetences[actorType];
|
||||
static actorCompendium(actorType = undefined) {
|
||||
return compendiumCompetences[actorType ?? 'personnage'];
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -89,22 +89,28 @@ export class RdDItemCompetence extends Item {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static isCompetenceArme(competence) {
|
||||
if (competence.isCompetence()) {
|
||||
switch (competence.system.categorie) {
|
||||
case 'melee':
|
||||
return competence.name != 'Esquive';
|
||||
return !Grammar.toLowerCaseNoAccent(competence.name).includes('esquive');
|
||||
case 'tir':
|
||||
case 'lancer':
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static isArmeUneMain(competence) {
|
||||
return competence.name.toLowerCase().includes("1 main");
|
||||
return RdDItemCompetence.isCompetenceArme(competence) && competence.name.toLowerCase().includes("1 main");
|
||||
}
|
||||
static isArme2Main(competence) {
|
||||
return competence.name.toLowerCase().includes("2 main");
|
||||
return RdDItemCompetence.isCompetenceArme(competence) && competence.name.toLowerCase().includes("2 main");
|
||||
}
|
||||
|
||||
static isThanatos(competence) {
|
||||
return competence.isCompetencePersonnage() && Grammar.toLowerCaseNoAccent(competence.name).includes('thanatos');
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -133,7 +139,7 @@ export class RdDItemCompetence extends Item {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static computeXP(competence) {
|
||||
const factor = competence.name.includes('Thanatos') ? 2 : 1; // Thanatos compte double !
|
||||
const factor = RdDItemCompetence.isThanatos(competence) ? 2 : 1; // Thanatos compte double !
|
||||
const xpNiveau = RdDItemCompetence.computeDeltaXP(competence.system.base, competence.system.niveau ?? competence.system.base);
|
||||
const xp = competence.system.xp ?? 0;
|
||||
const xpSort = competence.system.xp_sort ?? 0;
|
||||
@ -213,21 +219,14 @@ export class RdDItemCompetence extends Item {
|
||||
if (idOrName == undefined) {
|
||||
return undefined;
|
||||
}
|
||||
options = mergeObject(options, {
|
||||
preFilter: it => RdDItemCompetence.isCompetence(it),
|
||||
description: 'compétence',
|
||||
});
|
||||
return list.find(it => it.id == idOrName && RdDItemCompetence.isCompetence(it))
|
||||
options = mergeObject(options, { preFilter: it => it.isCompetence(), description: 'compétence', });
|
||||
return list.find(it => it.id == idOrName && it.isCompetence())
|
||||
?? Misc.findFirstLike(idOrName, list, options);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static findCompetences(list, name) {
|
||||
return Misc.findAllLike(name, list, { filter: it => RdDItemCompetence.isCompetence(it), description: 'compétence' });
|
||||
}
|
||||
|
||||
static isCompetence(item) {
|
||||
return item.type == 'competence' || item.type == 'competencecreature';
|
||||
return Misc.findAllLike(name, list, { filter: it => it.isCompetence(), description: 'compétence' });
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
@ -90,11 +90,10 @@ export class RdDItemSheet extends ItemSheet {
|
||||
if (this.item.type == 'tache' || this.item.type == 'livre' || this.item.type == 'meditation' || this.item.type == 'oeuvre') {
|
||||
formData.caracList = duplicate(game.system.model.Actor.personnage.carac)
|
||||
formData.caracList["reve-actuel"] = duplicate(game.system.model.Actor.personnage.reve.reve)
|
||||
formData.competences = await RdDUtility.loadCompendium('foundryvtt-reve-de-dragon.competences')
|
||||
formData.competences = await RdDUtility.loadItems(it => it.isCompetencePersonnage(), RdDItemCompetence.actorCompendium(this.actor?.type))
|
||||
}
|
||||
if (this.item.type == 'arme') {
|
||||
formData.competences = await RdDUtility.loadCompendium('foundryvtt-reve-de-dragon.competences', it => RdDItemCompetence.isCompetenceArme(it));
|
||||
console.log(formData.competences)
|
||||
formData.competences = await RdDUtility.loadItems(it => RdDItemCompetence.isCompetenceArme(it), RdDItemCompetence.actorCompendium(this.actor?.type))
|
||||
}
|
||||
if (this.item.type == 'recettecuisine') {
|
||||
formData.ingredients = await TextEditor.enrichHTML(this.object.system.ingredients, {async: true})
|
||||
@ -115,7 +114,7 @@ export class RdDItemSheet extends ItemSheet {
|
||||
formData.system.prdate = this.dateUpdated;
|
||||
this.dateUpdated = undefined;
|
||||
}
|
||||
RdDHerbes.updatePotionData(formData);
|
||||
await RdDHerbes.updatePotionData(formData);
|
||||
}
|
||||
if (formData.isOwned && this.item.type == 'herbe' && (formData.system.categorie == 'Soin' || formData.system.categorie == 'Repos')) {
|
||||
formData.isIngredientPotionBase = true;
|
||||
@ -160,7 +159,7 @@ export class RdDItemSheet extends ItemSheet {
|
||||
html.find(".categorie").change(event => this._onSelectCategorie(event));
|
||||
|
||||
html.find('.sheet-competence-xp').change((event) => {
|
||||
if (this.item.type == 'competence') {
|
||||
if (this.item.isCompetencePersonnage()) {
|
||||
RdDUtility.checkThanatosXP(this.item.name);
|
||||
}
|
||||
});
|
||||
|
@ -21,7 +21,7 @@ const typesObjetsOeuvres = ["oeuvre", "recettecuisine", "musique", "chant", "dan
|
||||
const typesObjetsDraconiques = ["queue", "ombre", "souffle", "tete", "signedraconique", "sortreserve"]
|
||||
const typesObjetsConnaissance = ["meditation", "recettealchimique", "sort"]
|
||||
const typesObjetsEffet = ["possession", "poison", "maladie"]
|
||||
const typesObjetsCompetence = ["competence", "compcreature"]
|
||||
const typesObjetsCompetence = ["competence", "competencecreature"]
|
||||
const encBrin = 0.00005; // un brin = 1 décigramme = 1/10g = 1/10000kg = 1/20000 enc
|
||||
const encPepin = 0.0007; /* un pépin de gemme = 1/10 cm3 = 1/1000 l = 3.5/1000 kg = 7/2000 kg = 7/1000 enc
|
||||
densité 3.5 (~2.3 à 4, parfois plus) -- https://www.juwelo.fr/guide-des-pierres/faits-et-chiffres/
|
||||
@ -29,7 +29,7 @@ densité 3.5 (~2.3 à 4, parfois plus) -- https://www.juwelo.fr/guide-des-pierre
|
||||
|
||||
export const defaultItemImg = {
|
||||
competence: "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp",
|
||||
compcreature: "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp",
|
||||
competencecreature: "systems/foundryvtt-reve-de-dragon/icons/competence_defaut.webp",
|
||||
arme: "systems/foundryvtt-reve-de-dragon/icons/armes_armures/epee_gnome.webp",
|
||||
armure: "systems/foundryvtt-reve-de-dragon/icons/armes_armures/armure_plaques.webp",
|
||||
conteneur: "systems/foundryvtt-reve-de-dragon/icons/objets/sac_a_dos.webp",
|
||||
@ -77,6 +77,9 @@ export class RdDItem extends Item {
|
||||
return typesObjetsOeuvres
|
||||
}
|
||||
|
||||
isCompetencePersonnage() {
|
||||
return this.type == 'competence'
|
||||
}
|
||||
isCompetence() {
|
||||
return typesObjetsCompetence.includes(this.type)
|
||||
}
|
||||
@ -180,8 +183,8 @@ export class RdDItem extends Item {
|
||||
this.system.magique = categorie.includes('enchante');
|
||||
if (this.system.magique) {
|
||||
if (categorie.includes('soin') || categorie.includes('repos')) {
|
||||
// TODO: utiliser calculePointsRepos / calculePointsGuerison
|
||||
this.system.puissance = RdDHerbes.calculePuissancePotion(this);
|
||||
// TODO: utiliser calculPointsRepos / calculPointsGuerison
|
||||
this.system.puissance = RdDHerbes.calculPuissancePotion(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -112,16 +112,12 @@ export class Misc {
|
||||
return Misc.firstConnectedGM()?.id ?? game.user.id;
|
||||
}
|
||||
|
||||
static getUsers() {
|
||||
return game.version ? game.users : game.users.entities;
|
||||
}
|
||||
|
||||
static getActiveUser(id) {
|
||||
return Misc.getUsers().find(u => u.id == id && u.active);
|
||||
return game.users.find(u => u.id == id && u.active);
|
||||
}
|
||||
|
||||
static firstConnectedGM() {
|
||||
return Misc.getUsers().filter(u => u.isGM && u.active).sort(Misc.ascending(u => u.id)).find(u => u.isGM && u.active);
|
||||
return game.users.filter(u => u.isGM && u.active).sort(Misc.ascending(u => u.id)).find(u => u.isGM && u.active);
|
||||
|
||||
}
|
||||
|
||||
@ -142,7 +138,7 @@ export class Misc {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static findPlayer(name) {
|
||||
return Misc.findFirstLike(name, Misc.getUsers(), { description: 'joueur' });
|
||||
return Misc.findFirstLike(name, game.users, { description: 'joueur' });
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
@ -721,12 +721,12 @@ export class RdDCombat {
|
||||
}
|
||||
}
|
||||
|
||||
isVisible(token, defender) {
|
||||
return canvas.effects.visibility.testVisibility(defender.center, { object: token })
|
||||
isVisible(token, defenderToken) {
|
||||
return canvas.effects.visibility.testVisibility(defenderToken.center, { object: token })
|
||||
}
|
||||
|
||||
distance(t, defenderToken) {
|
||||
return Number(canvas.grid.measureDistances([{ ray: new Ray(t.center, defenderToken.center) }], { gridSpaces: false })).toFixed(1);
|
||||
distance(token, defenderToken) {
|
||||
return Number(canvas.grid.measureDistances([{ ray: new Ray(token.center, defenderToken.center) }], { gridSpaces: false })).toFixed(1);
|
||||
}
|
||||
|
||||
_ajustementPortee(dist, arme) {
|
||||
@ -878,7 +878,7 @@ export class RdDCombat {
|
||||
attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker.getBonusDegat(), this.defender.isEntite());
|
||||
let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} }
|
||||
attackerRoll.show = {
|
||||
cible: this.target ? this.defender.system.name : 'la cible',
|
||||
cible: this.target ? this.defender.name : 'la cible',
|
||||
isRecul: (attackerRoll.particuliere == 'force' || attackerRoll.tactique == 'charge')
|
||||
}
|
||||
await RdDResolutionTable.displayRollData(attackerRoll, this.attacker, 'chat-resultat-attaque.html');
|
||||
@ -1303,7 +1303,7 @@ export class RdDCombat {
|
||||
attackerRoll.defenderTokenId = defenderTokenId;
|
||||
|
||||
await this.computeRecul(defenderRoll);
|
||||
this.defender.encaisserDommages(attackerRoll, this.attacker, defenderRoll);
|
||||
this.defender.encaisserDommages(attackerRoll, this.attacker, defenderRoll?.show);
|
||||
}
|
||||
else { // envoi à un GM: les joueurs n'ont pas le droit de modifier les personnages qu'ils ne possèdent pas
|
||||
game.socket.emit(SYSTEM_SOCKET_ID, {
|
||||
|
@ -132,18 +132,15 @@ export class RdDDice {
|
||||
}
|
||||
}
|
||||
|
||||
static async roll(formula, options = { showDice: SHOW_DICE, rollMode: undefined }) {
|
||||
const roll = new Roll(formula);
|
||||
await roll.evaluate({ async: true });
|
||||
if (options.showDice != HIDE_DICE) {
|
||||
await this.showDiceSoNice(roll, options.rollMode ?? game.settings.get("core", "rollMode"));
|
||||
}
|
||||
return roll;
|
||||
static async rollTotal(formula, options = { showDice: HIDE_DICE }) {
|
||||
return (await RdDDice.roll(formula, options)).total;
|
||||
}
|
||||
|
||||
static async rollTotal(formula, options = { showDice: HIDE_DICE}) {
|
||||
const roll = await RdDDice.roll(formula, options);
|
||||
return roll.total;
|
||||
static async roll(formula, options = { showDice: SHOW_DICE, rollMode: undefined }) {
|
||||
const roll = new Roll(RdDDice._formulaOrFake(formula, options));
|
||||
await roll.evaluate({ async: true });
|
||||
await this.showDiceSoNice(roll, options);
|
||||
return roll;
|
||||
}
|
||||
|
||||
static async rollOneOf(array) {
|
||||
@ -160,12 +157,93 @@ export class RdDDice {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async showDiceSoNice(roll, rollMode) {
|
||||
if (game.modules.get("dice-so-nice")?.active) {
|
||||
if (game.dice3d) {
|
||||
static async showDiceSoNice(roll, options) {
|
||||
if (options.showDice == HIDE_DICE || !game.modules.get("dice-so-nice")?.active || !game.dice3d) {
|
||||
return;
|
||||
}
|
||||
|
||||
let { whisper, blind } = RdDDice._getWhisperBlind(options);
|
||||
if (options.forceDiceResult?.total) {
|
||||
let terms = await RdDDice._getForcedTerms(options);
|
||||
if (terms) {
|
||||
await game.dice3d.show({ throws: [{ dice: terms }] })
|
||||
return;
|
||||
}
|
||||
}
|
||||
await game.dice3d.showForRoll(roll, game.user, true, whisper, blind);
|
||||
}
|
||||
|
||||
static _formulaOrFake(formula, options) {
|
||||
if (options?.forceDiceResult?.total) {
|
||||
options.forceDiceResult.formula = formula;
|
||||
return options.forceDiceResult.total.toString()
|
||||
}
|
||||
return formula;
|
||||
}
|
||||
|
||||
static async _getForcedTerms(options) {
|
||||
const total = options.forceDiceResult.total;
|
||||
switch (options.forceDiceResult.formula) {
|
||||
case '1d100':
|
||||
return terms1d100(total);
|
||||
case "2d10":
|
||||
return await terms2d10(total);
|
||||
}
|
||||
return undefined;
|
||||
|
||||
function terms1d100(total) {
|
||||
const unites = total % 10;
|
||||
const dizaines = Math.floor(total / 10);
|
||||
return [{
|
||||
resultLabel: dizaines * 10,
|
||||
d100Result: total,
|
||||
result: dizaines,
|
||||
type: "d100",
|
||||
vectors: [],
|
||||
options: {}
|
||||
},
|
||||
{
|
||||
resultLabel: unites,
|
||||
d100Result: total,
|
||||
result: unites,
|
||||
type: "d10",
|
||||
vectors: [],
|
||||
options: {}
|
||||
}];
|
||||
}
|
||||
|
||||
async function terms2d10(total) {
|
||||
if (total>20 || total<2) { return undefined }
|
||||
let first = await RdDDice.d10();
|
||||
let second = Math.min(total-first, 10);
|
||||
first = Math.max(first, total-second);
|
||||
return [{
|
||||
resultLabel:first,
|
||||
result: first,
|
||||
type: "d10",
|
||||
vectors: [],
|
||||
options: {}
|
||||
},
|
||||
{
|
||||
resultLabel: second,
|
||||
result: second,
|
||||
type: "d10",
|
||||
vectors: [],
|
||||
options: {}
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
static async d10() {
|
||||
let roll = new Roll('1d10');
|
||||
await roll.evaluate({ async: true });
|
||||
return roll.total;
|
||||
}
|
||||
|
||||
static _getWhisperBlind(options) {
|
||||
let whisper = null;
|
||||
let blind = false;
|
||||
rollMode = rollMode ?? game.settings.get("core", "rollMode");
|
||||
let rollMode = options.rollMode ?? game.settings.get("core", "rollMode");
|
||||
switch (rollMode) {
|
||||
case "blindroll": //GM only
|
||||
blind = true;
|
||||
@ -179,8 +257,6 @@ export class RdDDice {
|
||||
whisper = [game.user.id];
|
||||
break;
|
||||
}
|
||||
await game.dice3d.showForRoll(roll, game.user, true, whisper, blind);
|
||||
}
|
||||
}
|
||||
return { whisper, blind };
|
||||
}
|
||||
}
|
@ -1,74 +1,73 @@
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
import { RdDCalendrier } from "./rdd-calendrier.js";
|
||||
import { Grammar } from "./grammar.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class RdDHerbes extends Item {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static isHerbeSoin( botaniqueItem ) {
|
||||
return botaniqueItem.categorie == 'Soin';
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
static isHerbeRepos( botaniqueItem ) {
|
||||
return botaniqueItem.categorie == 'Repos';
|
||||
static async initializeHerbes() {
|
||||
this.herbesSoins = await RdDHerbes.listCategorieHerbes('Soin');
|
||||
this.herbesRepos = await RdDHerbes.listCategorieHerbes('Repos');
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async initializeHerbes( ) {
|
||||
this.herbesSoins = await RdDUtility.loadCompendium('foundryvtt-reve-de-dragon.botanique', item => this.isHerbeSoin(item));
|
||||
this.herbesRepos = await RdDUtility.loadCompendium('foundryvtt-reve-de-dragon.botanique', item => this.isHerbeRepos(item));
|
||||
static async listCategorieHerbes(categorie) {
|
||||
return await RdDUtility.loadItems(
|
||||
it => it.type == 'herbe' && it.system.categorie.toLowerCase() == categorie.toLowerCase(),
|
||||
'foundryvtt-reve-de-dragon.botanique');
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static buildHerbesList(listeHerbes, max) {
|
||||
let list = {}
|
||||
for ( let herbe of listeHerbes) {
|
||||
for (let herbe of listeHerbes) {
|
||||
let brins = max - herbe.system.niveau;
|
||||
list[herbe.system.name] = `${herbe.system.name} (Bonus: ${herbe.system.niveau}, Brins: ${brins})`;
|
||||
list[herbe.name] = `${herbe.name} (Bonus: ${herbe.system.niveau}, Brins: ${brins})`;
|
||||
}
|
||||
list['Autre'] = 'Autre (Bonus: variable, Brins: variable)'
|
||||
return list;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static updatePotionData( formData ) {
|
||||
formData.herbesSoins = this.buildHerbesList(this.herbesSoins, 12);
|
||||
formData.herbesRepos = this.buildHerbesList(this.herbesRepos, 7);
|
||||
static async updatePotionData(formData) {
|
||||
formData.isSoins = formData.system.categorie.includes('Soin');
|
||||
formData.isRepos = formData.system.categorie.includes('Repos');
|
||||
if (formData.isSoins) {
|
||||
RdDHerbes.calculBonusHerbe(formData, this.herbesSoins, 12);
|
||||
}
|
||||
if (formData.isRepos) {
|
||||
RdDHerbes.calculBonusHerbe(formData, this.herbesRepos, 7);
|
||||
}
|
||||
formData.herbesSoins = RdDHerbes.buildHerbesList(this.herbesSoins, 12);
|
||||
formData.herbesRepos = RdDHerbes.buildHerbesList(this.herbesRepos, 7);
|
||||
formData.jourMoisOptions = RdDCalendrier.buildJoursMois();
|
||||
formData.dateActuelle = game.system.rdd.calendrier.getDateFromIndex();
|
||||
formData.splitDate = game.system.rdd.calendrier.getNumericDateFromIndex(formData.system.prdate);
|
||||
|
||||
if (formData.system.categorie.includes('Soin') ) {
|
||||
formData.isHerbe = true;
|
||||
this.computeHerbeBonus(formData, this.herbesSoins, 12);
|
||||
} else if (formData.system.categorie.includes('Repos')) {
|
||||
formData.isRepos = true;
|
||||
this.computeHerbeBonus(formData, this.herbesRepos, 7);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static calculePuissancePotion( potion ) {
|
||||
static calculPuissancePotion(potion) {
|
||||
return potion.system.herbebonus * potion.system.pr;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static calculePointsRepos( potion ) {
|
||||
static calculPointsRepos(potion) {
|
||||
return potion.system.herbebonus * potion.system.pr;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static calculePointsGuerison( potion ){
|
||||
static calculPointsGuerison(potion) {
|
||||
return potion.system.herbebonus * potion.system.pr;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static computeHerbeBonus( formData, herbesList, max) {
|
||||
if ( Number(formData.system.herbebrins) ) {
|
||||
let herbe = herbesList.find(item => item.name.toLowerCase() == formData.system.herbe.toLowerCase() );
|
||||
if( herbe ) {
|
||||
let brinsBase = max - herbe.system.niveau;
|
||||
formData.system.herbebonus = Math.max(herbe.system.niveau - Math.max(brinsBase - formData.system.herbebrins, 0), 0);
|
||||
static calculBonusHerbe(formData, herbesList, max) {
|
||||
if (Number(formData.system.herbebrins)) {
|
||||
let herbe = herbesList.find(item => item.name.toLowerCase() == formData.system.herbe.toLowerCase());
|
||||
if (herbe) {
|
||||
const brinsRequis = max - herbe.system.niveau;
|
||||
const brinsManquants = Math.max(brinsRequis - formData.system.herbebrins, 0);
|
||||
formData.system.herbebonus = Math.max(herbe.system.niveau - brinsManquants, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -142,10 +142,8 @@ export class RdDResolutionTable {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async rollChances(chances, diviseur, forceDiceResult = -1) {
|
||||
if (forceDiceResult <= 0 || forceDiceResult > 100) {
|
||||
forceDiceResult = -1;
|
||||
}
|
||||
chances.roll = await RdDDice.rollTotal((forceDiceResult == -1) ? "1d100" : `${forceDiceResult}`, chances);
|
||||
chances.forceDiceResult = forceDiceResult <= 0 || forceDiceResult > 100 ? undefined : {total: forceDiceResult};
|
||||
chances.roll = await RdDDice.rollTotal( "1d100", chances);
|
||||
mergeObject(chances, this.computeReussite(chances, chances.roll, diviseur), { overwrite: true });
|
||||
return chances;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { ENTITE_BLURETTE, ENTITE_INCARNE, ENTITE_NONINCARNE } from "./constants.js";
|
||||
import { ENTITE_BLURETTE, ENTITE_INCARNE} from "./constants.js";
|
||||
|
||||
/**
|
||||
* Extend the base Dialog entity by defining a custom window to perform roll.
|
||||
@ -33,7 +33,7 @@ export class RdDEncaisser extends Dialog {
|
||||
let dialogOptions = {
|
||||
classes: ["rdddialog"],
|
||||
width: 320,
|
||||
height: 240
|
||||
height: 260
|
||||
}
|
||||
|
||||
// Select proper roll dialog template and stuff
|
||||
|
@ -144,6 +144,7 @@ export class RdDRoll extends Dialog {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async onAction(action, html) {
|
||||
this.rollData.forceDiceResult = Number.parseInt($('#force-dice-result').val()) ?? -1;
|
||||
await RdDResolutionTable.rollData(this.rollData);
|
||||
console.log("RdDRoll -=>", this.rollData, this.rollData.rolled);
|
||||
this.actor.setRollWindowsOpened(false);
|
||||
|
@ -2,16 +2,22 @@ export class RdDRollTables {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async genericGetTableResult(tableName, toChat) {
|
||||
let table = game.tables.find(table => table.name.toLowerCase() == tableName.toLowerCase())
|
||||
if ( !table) {
|
||||
const pack = game.packs.get("foundryvtt-reve-de-dragon.tables-diverses");
|
||||
const index = await pack.getIndex();
|
||||
const entry = index.find(e => e.name === tableName);
|
||||
table = await pack.getDocument(entry._id);
|
||||
}
|
||||
let table = RdDRollTables.getWorldTable() ?? (await RdDRollTables.getSystemTable(tableName));
|
||||
const draw = await table.draw({ displayChat: toChat, rollMode: "gmroll"});
|
||||
//console.log("RdDRollTables", tableName, toChat, ":", draw);
|
||||
return draw.results.length > 0 ? draw.results[0] : undefined;
|
||||
|
||||
}
|
||||
|
||||
static getWorldTable() {
|
||||
return game.tables.find(table => table.name.toLowerCase() == tableName.toLowerCase());
|
||||
}
|
||||
|
||||
static async getSystemTable(tableName) {
|
||||
const pack = game.packs.get("foundryvtt-reve-de-dragon.tables-diverses");
|
||||
const index = await pack.getIndex();
|
||||
const entry = index.find(e => e.name === tableName);
|
||||
return await pack.getDocument(entry._id);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
@ -13,6 +13,7 @@ import { Monnaie } from "./item-monnaie.js";
|
||||
import { RdDPossession } from "./rdd-possession.js";
|
||||
import { RdDNameGen } from "./rdd-namegen.js";
|
||||
import { RdDConfirm } from "./rdd-confirm.js";
|
||||
import { RdDActor } from "./actor.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
// This table starts at 0 -> niveau -10
|
||||
@ -213,6 +214,7 @@ export class RdDUtility {
|
||||
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-carac.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-sort.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-encaisser.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/dialog-validation-encaissement.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-meditation.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/dialog-tmr.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/dialog-roll-alchimie.html',
|
||||
@ -652,7 +654,68 @@ export class RdDUtility {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static selectEncaissement(degats, mortalite) {
|
||||
static async jetEncaissement(rollData, armure, options = { showDice: HIDE_DICE }) {
|
||||
let formula = "2d10";
|
||||
|
||||
// Chaque dé fait au minmum la difficulté libre
|
||||
if (ReglesOptionelles.isUsing('degat-minimum-malus-libre')) {
|
||||
if (rollData.diffLibre < 0) {
|
||||
let valeurMin = Math.abs(rollData.diffLibre);
|
||||
formula += "min" + valeurMin;
|
||||
}
|
||||
}
|
||||
// Chaque dé fait au minmum la difficulté libre
|
||||
if (ReglesOptionelles.isUsing('degat-ajout-malus-libre')) {
|
||||
if (rollData.diffLibre < 0) {
|
||||
let valeurMin = Math.abs(rollData.diffLibre);
|
||||
formula += "+" + valeurMin;
|
||||
}
|
||||
}
|
||||
|
||||
let roll = await RdDDice.roll(formula, options);
|
||||
|
||||
// 1 dé fait au minmum la difficulté libre
|
||||
if (ReglesOptionelles.isUsing('degat-minimum-malus-libre-simple')) {
|
||||
if (rollData.diffLibre < 0) {
|
||||
let valeurMin = Math.abs(rollData.diffLibre);
|
||||
if (roll.terms[0].results[0].result < valeurMin) {
|
||||
roll.terms[0].results[0].result = valeurMin;
|
||||
} else if (roll.terms[0].results[1].result < valeurMin) {
|
||||
roll.terms[0].results[1].result = valeurMin;
|
||||
}
|
||||
roll._total = roll.terms[0].results[0].result + roll.terms[0].results[1].result;
|
||||
}
|
||||
}
|
||||
|
||||
return await RdDUtility.prepareEncaissement(rollData, roll, armure);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async prepareEncaissement(rollData, roll, armure) {
|
||||
const jetTotal = roll.total + rollData.dmg.total - armure;
|
||||
let encaissement = RdDUtility._selectEncaissement(jetTotal, rollData.dmg.mortalite);
|
||||
let over20 = Math.max(jetTotal - 20, 0);
|
||||
encaissement.dmg = rollData.dmg;
|
||||
encaissement.dmg.loc = rollData.dmg.loc ?? await RdDUtility.getLocalisation(this.type);
|
||||
encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;';
|
||||
encaissement.roll = roll;
|
||||
encaissement.armure = armure;
|
||||
encaissement.total = jetTotal;
|
||||
encaissement.vie = await RdDUtility._evaluatePerte(encaissement.vie, over20);
|
||||
encaissement.endurance = await RdDUtility._evaluatePerte(encaissement.endurance, over20);
|
||||
encaissement.penetration = rollData.arme?.system.penetration ?? 0;
|
||||
encaissement.blessures = (
|
||||
encaissement.critiques> 0 ? "Critique":
|
||||
encaissement.graves> 0 ? "Grave":
|
||||
encaissement.legeres> 0 ? "Légère":
|
||||
encaissement.eraflures>0 ? "Contusions/Eraflures":
|
||||
'Aucune'
|
||||
);
|
||||
return encaissement;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static _selectEncaissement(degats, mortalite) {
|
||||
const table = definitionsEncaissement[mortalite] === undefined ? definitionsEncaissement["mortel"] : definitionsEncaissement[mortalite];
|
||||
for (let encaissement of table) {
|
||||
if ((encaissement.minimum === undefined || encaissement.minimum <= degats)
|
||||
@ -663,6 +726,13 @@ export class RdDUtility {
|
||||
return duplicate(table[0]);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async _evaluatePerte(formula, over20) {
|
||||
let perte = new Roll(formula, { over20: over20 });
|
||||
await perte.evaluate({ async: true });
|
||||
return perte.total;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static currentFatigueMalus(value, max) {
|
||||
if (ReglesOptionelles.isUsing("appliquer-fatigue")) {
|
||||
@ -683,17 +753,28 @@ export class RdDUtility {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async loadCompendiumData(compendium) {
|
||||
const pack = game.packs.get(compendium);
|
||||
return await pack?.getDocuments() ?? [];
|
||||
static async loadItems(filter, compendium) {
|
||||
let items = game.items.filter(filter);
|
||||
if (compendium) {
|
||||
const ids = items.map(it => it.id);
|
||||
const names = items.map(it => it.name.toLowerCase());
|
||||
items = items.concat(await RdDUtility.loadCompendium(compendium, it => !ids.includes(it.id) && !names.includes(it.name.toLowerCase()) && filter(it)));
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async loadCompendium(compendium, filter = item => true) {
|
||||
static async loadCompendium(compendium, filter = it => true) {
|
||||
let compendiumData = await RdDUtility.loadCompendiumData(compendium);
|
||||
return compendiumData.filter(filter);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async loadCompendiumData(compendium) {
|
||||
const pack = game.packs.get(compendium);
|
||||
return await pack?.getDocuments() ?? [];
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async responseNombreAstral(callData) {
|
||||
let actor = game.actors.get(callData.id);
|
||||
|
@ -2,29 +2,32 @@ import { SYSTEM_RDD } from "./constants.js";
|
||||
import { Misc } from "./misc.js";
|
||||
|
||||
const listeReglesOptionelles = [
|
||||
{ name: 'recul', group: 'Règles de combat', descr: "Appliquer le recul en cas de particulière en force ou de charge" },
|
||||
{ name: 'resistanceArmeParade', group: 'Règles de combat', descr: "Faire le jet de résistance des armes lors de parades pouvant les endommager" },
|
||||
{ name: 'deteriorationArmure', group: 'Règles de combat', descr: "Tenir compte de la détérioration des armures" },
|
||||
{ name: 'defenseurDesarme', group: 'Règles de combat', descr: "Le défenseur peut être désarmé en parant une particulière en force ou une charge avec une arme autre qu'un bouclier" },
|
||||
{ name: 'categorieParade', group: 'Règles de combat', descr: "Le défenseur doit obtenir une significative en cas de parade avec des armes de catégories différentes" },
|
||||
{ name: 'tripleSignificative', group: 'Règles de combat', descr: "En cas de demi-surprise, d'attaque particulière en finesse, et de catégories d'armes différentes, le défenseur doit obtenir 1/8 des chances de succès" },
|
||||
{ name: 'degat-minimum-malus-libre-simple', group: 'Règles de combat', descr: "Le malus libre d'attaque remplace une des valeurs de dés d'encaissement si elle est plus petite. Exemple : la difficulté libre de l'attaquant est de -4. Sur le jet d'encaissement, si 1 résultat est inférieur à 4, alors il devient 4.", default: false },
|
||||
{ name: 'degat-minimum-malus-libre', group: 'Règles de combat', descr: "Le malus libre d'attaque remplace une valeur de dés d'encaissement si elle est plus petite. Exemple : la difficulté libre de l'attaquant est de -4. Sur le jet d'encaissement, tout résultat inférieur à 4 devient 4.", default: false },
|
||||
{ name: 'degat-ajout-malus-libre', group: 'Règles de combat', descr: "Le malus libre d'attaque s'ajoute au jet d'encaissement et aux autres bonus. Exemple : la difficulté libre de l'attaquant est de -4. Le jet d'encaissement est effectué à 2d10+4, plus les bonus de situation et d'armes.", default: false },
|
||||
{ name: 'astrologie', group: 'Règles générales', descr: "Appliquer les ajustements astrologiques aux jets de chance et aux rituels"},
|
||||
{ name: 'afficher-prix-joueurs', group: 'Règles générales', descr: "Afficher le prix de l'équipement des joueurs", uniquementJoueur: true},
|
||||
{ name: 'appliquer-fatigue', group: 'Règles générales', descr: "Appliquer les règles de fatigue"},
|
||||
{ name: 'afficher-colonnes-reussite', group: 'Règles générales', descr: "Afficher le nombre de colonnes de réussite ou d'échec", default: false },
|
||||
{ name: 'confirmation-tmr', group: 'Confirmations', descr: "Confirmer pour monter dans les TMR", scope: "client"},
|
||||
{ name: 'confirmation-vider', group: 'Confirmations', descr: "Confirmer pour vider l'équipement", scope: "client"},
|
||||
{ name: 'confirmation-supprimer-lien-acteur', group: 'Confirmations', descr: "Confirmer pour détacher un animal/suivant/véhicule", scope: "client"},
|
||||
{ name: 'confirmation-supprimer-equipement', group: 'Confirmations', descr: "Confirmer la suppression des équipements", scope: "client"},
|
||||
{ name: 'confirmation-supprimer-oeuvre', group: 'Confirmations', descr: "Confirmer la suppression des oeuvres", scope: "client"},
|
||||
{ name: 'confirmation-supprimer-connaissance', group: 'Confirmations', descr: "Confirmer la suppression des connaissances", scope: "client"},
|
||||
{ name: 'confirmation-supprimer-draconique', group: 'Confirmations', descr: "Confirmer la suppression des queues, souffles, têtes", scope: "client"},
|
||||
{ name: 'confirmation-supprimer-effet', group: 'Confirmations', descr: "Confirmer la suppression des effets", scope: "client"},
|
||||
{ name: 'confirmation-supprimer-competence', group: 'Confirmations', descr: "Confirmer la suppression des compétences", scope: "client"},
|
||||
{ name: 'confirmation-supprimer-autres', group: 'Confirmations', descr: "Confirmer la suppression des autres types d'Objets", scope: "client"},
|
||||
{ group: 'Règles de combat', name: 'recul', descr: "Appliquer le recul en cas de particulière en force ou de charge" },
|
||||
{ group: 'Règles de combat', name: 'resistanceArmeParade', descr: "Faire le jet de résistance des armes lors de parades pouvant les endommager" },
|
||||
{ group: 'Règles de combat', name: 'deteriorationArmure', descr: "Tenir compte de la détérioration des armures" },
|
||||
{ group: 'Règles de combat', name: 'defenseurDesarme', descr: "Le défenseur peut être désarmé en parant une particulière en force ou une charge avec une arme autre qu'un bouclier" },
|
||||
{ group: 'Règles de combat', name: 'categorieParade', descr: "Le défenseur doit obtenir une significative en cas de parade avec des armes de catégories différentes" },
|
||||
{ group: 'Règles de combat', name: 'tripleSignificative', descr: "En cas de demi-surprise, d'attaque particulière en finesse, et de catégories d'armes différentes, le défenseur doit obtenir 1/8 des chances de succès" },
|
||||
{ group: 'Règles de combat', name: 'degat-minimum-malus-libre-simple', descr: "Le malus libre d'attaque remplace une des valeurs de dés d'encaissement si elle est plus petite. Exemple : la difficulté libre de l'attaquant est de -4. Sur le jet d'encaissement, si le plus petit dé est inférieur à 4, alors il devient 4.", default: false },
|
||||
{ group: 'Règles de combat', name: 'degat-minimum-malus-libre', descr: "Le malus libre d'attaque remplace une valeur de dés d'encaissement si elle est plus petite. Exemple : la difficulté libre de l'attaquant est de -4. Sur le jet d'encaissement, tout résultat inférieur à 4 devient 4.", default: false },
|
||||
{ group: 'Règles de combat', name: 'degat-ajout-malus-libre', descr: "Le malus libre d'attaque s'ajoute au jet d'encaissement et aux autres bonus. Exemple : la difficulté libre de l'attaquant est de -4. Le jet d'encaissement est effectué à 2d10+4, plus les bonus de situation et d'armes.", default: false },
|
||||
{ group: 'Règles de combat', name: 'validation-encaissement-gr', descr: "Le Gardien des Rêves doit valider les jets d'encaissement et peut les changer.", default: false },
|
||||
|
||||
{ group: 'Règles générales', name: 'astrologie', descr: "Appliquer les ajustements astrologiques aux jets de chance et aux rituels"},
|
||||
{ group: 'Règles générales', name: 'afficher-prix-joueurs', descr: "Afficher le prix de l'équipement des joueurs", uniquementJoueur: true},
|
||||
{ group: 'Règles générales', name: 'appliquer-fatigue', descr: "Appliquer les règles de fatigue"},
|
||||
{ group: 'Règles générales', name: 'afficher-colonnes-reussite', descr: "Afficher le nombre de colonnes de réussite ou d'échec", default: false },
|
||||
|
||||
{ group: 'Confirmations', name: 'confirmation-tmr', descr: "Confirmer pour monter dans les TMR", scope: "client"},
|
||||
{ group: 'Confirmations', name: 'confirmation-vider', descr: "Confirmer pour vider l'équipement", scope: "client"},
|
||||
{ group: 'Confirmations', name: 'confirmation-supprimer-lien-acteur', descr: "Confirmer pour détacher un animal/suivant/véhicule", scope: "client"},
|
||||
{ group: 'Confirmations', name: 'confirmation-supprimer-equipement', descr: "Confirmer la suppression des équipements", scope: "client"},
|
||||
{ group: 'Confirmations', name: 'confirmation-supprimer-oeuvre', descr: "Confirmer la suppression des oeuvres", scope: "client"},
|
||||
{ group: 'Confirmations', name: 'confirmation-supprimer-connaissance', descr: "Confirmer la suppression des connaissances", scope: "client"},
|
||||
{ group: 'Confirmations', name: 'confirmation-supprimer-draconique', descr: "Confirmer la suppression des queues, souffles, têtes", scope: "client"},
|
||||
{ group: 'Confirmations', name: 'confirmation-supprimer-effet', descr: "Confirmer la suppression des effets", scope: "client"},
|
||||
{ group: 'Confirmations', name: 'confirmation-supprimer-competence', descr: "Confirmer la suppression des compétences", scope: "client"},
|
||||
{ group: 'Confirmations', name: 'confirmation-supprimer-autres', descr: "Confirmer la suppression des autres types d'Objets", scope: "client"},
|
||||
];
|
||||
|
||||
const uniquementJoueur = listeReglesOptionelles.filter(it => it.uniquementJoueur).map(it=>it.name);
|
||||
@ -73,7 +76,7 @@ export class ReglesOptionelles extends FormApplication {
|
||||
const regles = listeReglesOptionelles.filter(it => game.user.isGM || it.scope == "client").map(it => {
|
||||
it = duplicate(it);
|
||||
it.id = ReglesOptionelles._getIdRegle(it.name);
|
||||
it.active = ReglesOptionelles.isUsing(it.name);
|
||||
it.active = ReglesOptionelles.isSet(it.name);
|
||||
return it;
|
||||
});
|
||||
formData.regles = regles;
|
||||
@ -85,11 +88,11 @@ export class ReglesOptionelles extends FormApplication {
|
||||
if (game.user.isGM && uniquementJoueur.includes(name)) {
|
||||
return true;
|
||||
}
|
||||
return game.settings.get(SYSTEM_RDD, ReglesOptionelles._getIdRegle(name));
|
||||
return ReglesOptionelles.isSet(name);
|
||||
}
|
||||
|
||||
static isSet(name) {
|
||||
return ReglesOptionelles.isUsing(name);
|
||||
return game.settings.get(SYSTEM_RDD, ReglesOptionelles._getIdRegle(name));
|
||||
}
|
||||
|
||||
static set(name, value) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
<form class="encaisse-roll-dialog">
|
||||
<h2 class="encaisserdialog" id="encaisserTitle"></h2>
|
||||
<div class="form-group">
|
||||
<label class="competence-label">Modificateurs aux Dommages:</label>
|
||||
<select class="competence-value" name="modificateurDegats" id="modificateurDegats" data-dtype="number">
|
||||
<div class="flexrow">
|
||||
<label>Modificateurs aux Dommages:</label>
|
||||
<select class="competence-value flex-shrink" name="modificateurDegats" id="modificateurDegats" data-dtype="number">
|
||||
{{#select modificateurDegats}}
|
||||
{{#each ajustementsEncaissement as |key|}}
|
||||
<option value={{key}}>{{numberFormat key decimals=0 sign=true}}</option>
|
||||
@ -10,9 +10,9 @@
|
||||
{{/select}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="competence-label">Cas particuliers:</label>
|
||||
<select class="competence-value" name="encaisserSpecial" id="encaisserSpecial" data-dtype="String">
|
||||
<div class="flexcol">
|
||||
<label >Cas particuliers:</label>
|
||||
<select name="encaisserSpecial" id="encaisserSpecial" data-dtype="String">
|
||||
<option value="aucun">Aucun</option>
|
||||
<option value="noarmure">Ne pas compter les Armures</option>
|
||||
<option value="chute">Chute : Limiter les armures à 2 PA</option>
|
||||
|
45
templates/dialog-validation-encaissement.html
Normal file
45
templates/dialog-validation-encaissement.html
Normal file
@ -0,0 +1,45 @@
|
||||
<form class="dialog-validation-encaissement">
|
||||
<div class="flexrow flex-center">
|
||||
<div class="flex-shrink"><img class="chat-icon" src="icons/svg/bones.svg" alt="Encaisser des dommages" /></div>
|
||||
<div><h4>Encaissement de {{actor.name}}</h4></div>
|
||||
<div class="flex-shrink"><img class="chat-icon" src="{{actor.img}}" title="{{actor.name}}" alt="{{actor.name}}" /></div>
|
||||
</div>
|
||||
<ul>
|
||||
<li class="flexrow flex-group-left">
|
||||
<label>Jet d'encaissement</label>
|
||||
<input class="encaissement-roll-result" type="number" value="{{encaissement.roll.result}}" min="2" max="20" data-dtype="Number" />
|
||||
</li>
|
||||
<li class="flexrow flex-group-left">
|
||||
<label>Total</label>
|
||||
<span class="tooltip tooltip-dotted">
|
||||
<label class="encaissement-total">{{encaissement.total}}</label>
|
||||
<div class="tooltiptext ttt-ajustements">
|
||||
<div>Armure: {{encaissement.armure}}</div>
|
||||
{{#if rollData.dmg.penetration}}
|
||||
<div>Pénétration: -{{rollData.dmg.penetration}}</div>
|
||||
{{/if}}
|
||||
<hr>
|
||||
{{#if rollData.dmg.dmgArme}}
|
||||
<div>+dom arme: {{numberFormat rollData.dmg.dmgArme decimals=0 sign=true}}</div>
|
||||
{{/if}}
|
||||
{{#if rollData.dmg.dmgActor}}
|
||||
<div>+dom attaquant: {{numberFormat rollData.dmg.dmgActor decimals=0 sign=true}}</div>
|
||||
{{/if}}
|
||||
{{#if rollData.dmg.dmgParticuliere}}
|
||||
<div>+dom particulière: {{numberFormat rollData.dmg.dmgParticuliere decimals=0 sign=true}}</div>
|
||||
{{/if}}
|
||||
{{#if rollData.dmg.dmgTactique}}
|
||||
<div>+dom tactique: {{numberFormat rollData.dmg.dmgTactique decimals=0 sign=true}}</div>
|
||||
{{/if}}
|
||||
{{#if rollData.dmg.dmgSurprise}}
|
||||
<div>+dom surprise: {{numberFormat rollData.dmg.dmgSurprise decimals=0 sign=true}}</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</span>
|
||||
</li>
|
||||
<li class="flexrow flex-group-left">
|
||||
<label>Blessure ({{rollData.dmg.mortalite}})</label>
|
||||
<label class="encaissement-blessure">{{encaissement.blessures}}</label>
|
||||
</li>
|
||||
</ul>
|
||||
</form>
|
@ -41,7 +41,7 @@
|
||||
{{/select}}
|
||||
</select>
|
||||
</div>
|
||||
{{#if isHerbe}}
|
||||
{{#if isSoins}}
|
||||
<div class="form-group">
|
||||
<label>Herbe</label>
|
||||
<select name="system.herbe" class="herbe" data-dtype="String">
|
||||
@ -86,7 +86,7 @@
|
||||
<label for="xp">Permanente ? </label>
|
||||
<input class="attribute-value" type="checkbox" name="system.prpermanent" {{#if system.prpermanent}}checked{{/if}}/>
|
||||
</div>
|
||||
{{#if isHerbe}}
|
||||
{{#if isSoins}}
|
||||
<div class="form-group">
|
||||
<label for="xp">Points de guérison </label>
|
||||
<label for="xp">{{pointsGuerison}}</label>
|
||||
|
Loading…
Reference in New Issue
Block a user