From b87f40609336f3c269824649f707cd40f4ef8f64 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 11 Jan 2025 00:44:59 +0100 Subject: [PATCH 1/9] =?UTF-8?q?Ajouter=20de=20"jet=20de=20d=C3=A9s"=20dans?= =?UTF-8?q?=20les=20descriptions,?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On peut maintenant ajouter des liens dans les descriptions (acteurs, items) et autres champs similaires. --- changelog.md | 5 ++ module/actor-sheet.js | 5 +- module/actor.js | 44 +++-------------- module/actor/base-actor-reve-sheet.js | 2 + module/actor/base-actor-reve.js | 33 +++++++++++++ module/actor/base-actor-sheet.js | 5 +- module/apps/rdd-text-roll.js | 54 +++++++++++++++++++++ module/apps/xregexp-all.js | 4 +- module/item-sheet.js | 28 ++++++----- module/item/race.js | 6 +-- module/rdd-alchimie.js | 2 +- module/rdd-carac.js | 35 +++++++++++-- template.json | 4 +- templates/apps/link-text-roll.hbs | 8 +++ templates/item-recettealchimique-sheet.html | 2 +- 15 files changed, 169 insertions(+), 68 deletions(-) create mode 100644 module/apps/rdd-text-roll.js create mode 100644 templates/apps/link-text-roll.hbs diff --git a/changelog.md b/changelog.md index fc9a85ac..42d945b1 100644 --- a/changelog.md +++ b/changelog.md @@ -1,4 +1,9 @@ # 12.0 +## 12.0.34 - la tête d'Astrobazzarh +- on peut ajouter des liens "jet de dés" dans les descriptions, notes, ... +- les liens "jet de dés" peuvent être utilisés pour un acteur, ou les items de l'acteurs +- les liens "jet de dés" d'"un item non lié à un acteur agit sur les tokens sélectionnés + ## 12.0.33 - la vieillesse d'Astrobazzarh - retour de l'expérience pour les joueurs - suppression du message "Pas de caractéristique" sur les jets d'odorat-goût diff --git a/module/actor-sheet.js b/module/actor-sheet.js index 4436fbcf..c96dfc13 100644 --- a/module/actor-sheet.js +++ b/module/actor-sheet.js @@ -19,6 +19,7 @@ import { RdDBaseActorSangSheet } from "./actor/base-actor-sang-sheet.js"; import { RdDCoeur } from "./coeur/rdd-coeur.js"; import { AppPersonnageAleatoire } from "./actor/random/app-personnage-aleatoire.js"; import { RdDItemRace } from "./item/race.js"; +import { RdDTextEditor } from "./apps/rdd-text-roll.js"; /* -------------------------------------------- */ /** @@ -44,8 +45,8 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { cssClass: this.isEditable ? "editable" : "locked", limited: this.actor.limited, owner: this.actor.isOwner, - biographie: await TextEditor.enrichHTML(this.actor.system.biographie, { async: true }), - notes: await TextEditor.enrichHTML(this.actor.system.notes, { async: true }), + biographie: await RdDTextEditor.enrichHTML(this.actor.system.biographie), + notes: await RdDTextEditor.enrichHTML(this.actor.system.notes), }); foundry.utils.mergeObject(formData.calc, { surenc: this.actor.computeMalusSurEncombrement(), diff --git a/module/actor.js b/module/actor.js index 76c5d3b6..ec2ac7cf 100644 --- a/module/actor.js +++ b/module/actor.js @@ -17,7 +17,7 @@ import { RdDItemSigneDraconique } from "./item/signedraconique.js"; import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; import { EffetsDraconiques } from "./tmr/effets-draconiques.js"; import { Draconique } from "./tmr/draconique.js"; -import { LIST_CARAC, RdDCarac } from "./rdd-carac.js"; +import { LIST_CARAC_PERSONNAGE, RdDCarac } from "./rdd-carac.js"; import { DialogConsommer } from "./dialog-item-consommer.js"; import { DialogFabriquerPotion } from "./dialog-fabriquer-potion.js"; import { RollDataAjustements } from "./rolldata-ajustements.js"; @@ -662,15 +662,15 @@ export class RdDActor extends RdDBaseActorSang { /* -------------------------------------------- */ async updateCarac(caracName, to) { to = Number(to) - if (!RdDItemRace.checkRacialMax(this, caracName, to)){ + if (!RdDItemRace.checkRacialMax(this, caracName, to)) { return } - if (caracName == LIST_CARAC.reve.code) { + if (caracName == LIST_CARAC_PERSONNAGE.reve.code) { if (to > Misc.toInt(this.system.reve.seuil.value)) { this.setPointsDeSeuil(to); } } - if (caracName == LIST_CARAC.chance.code) { + if (caracName == LIST_CARAC_PERSONNAGE.chance.code) { if (to > Misc.toInt(this.system.compteurs.chance.value)) { this.setPointsDeChance(to); } @@ -1387,7 +1387,7 @@ export class RdDActor extends RdDBaseActorSang { } await RdDResolutionTable.rollData(ethylismeData.jetVie); - this._gererExperience(ethylismeData.jetVie); + this.gererExperience(ethylismeData.jetVie); RollDataAjustements.calcul(ethylismeData.jetVie, this); if (ethylismeData.jetVie.rolled.isSuccess) { ethylisme.nb_doses++; @@ -1419,7 +1419,7 @@ export class RdDActor extends RdDBaseActorSang { finalLevel: Number(ethylisme.value) + Number(this.system.compteurs.moral.value) } await RdDResolutionTable.rollData(ethylismeData.jetVolonte); - this._gererExperience(ethylismeData.jetVolonte); + this.gererExperience(ethylismeData.jetVolonte); RollDataAjustements.calcul(ethylismeData.jetVolonte, this); } } @@ -1799,38 +1799,8 @@ export class RdDActor extends RdDBaseActorSang { } } - /** - * Méthode pour faire un jet prédéterminer sans ouvrir la fenêtre de dialogue - * @param {*} caracName - * @param {*} compName - * @param {*} diff - * @param {*} options - * @returns - */ - async doRollCaracCompetence(caracName, compName, diff, options = { title: "" }) { - const carac = this.getCaracByName(caracName); - if (!carac) { - ui.notifications.warn(`${this.name} n'a pas de caractéristique correspondant à ${caracName}`) - return; - } - const competence = this.getCompetence(compName); - let rollData = { - alias: this.getAlias(), - caracValue: Number(carac.value), - selectedCarac: carac, - competence: competence, - diffLibre: diff, - show: { title: options?.title ?? '' } - }; - RollDataAjustements.calcul(rollData, this); - await RdDResolutionTable.rollData(rollData); - this._gererExperience(rollData); - await RdDResolutionTable.displayRollData(rollData, this) - return rollData.rolled; - } - /* -------------------------------------------- */ - _gererExperience(rollData) { + gererExperience(rollData) { const callback = this.createCallbackExperience(); if (callback.condition(rollData)) { callback.action(rollData); diff --git a/module/actor/base-actor-reve-sheet.js b/module/actor/base-actor-reve-sheet.js index 996f8f08..6d387ae5 100644 --- a/module/actor/base-actor-reve-sheet.js +++ b/module/actor/base-actor-reve-sheet.js @@ -1,3 +1,4 @@ +import { RdDTextEditor } from "../apps/rdd-text-roll.js"; import { Grammar } from "../grammar.js"; import { ITEM_TYPES } from "../item.js"; import { RdDSheetUtility } from "../rdd-sheet-utility.js"; @@ -47,6 +48,7 @@ export class RdDBaseActorReveSheet extends RdDBaseActorSheet { } }], { renderSheet: true }) ) + this.html.find('.roll-carac-competence').click(async event => await RdDTextEditor.rollText(event, this.actor)) if (this.options.vueDetaillee) { // On carac change diff --git a/module/actor/base-actor-reve.js b/module/actor/base-actor-reve.js index 69777d32..bb71912f 100644 --- a/module/actor/base-actor-reve.js +++ b/module/actor/base-actor-reve.js @@ -22,6 +22,7 @@ import { RdDCombat } from "../rdd-combat.js"; import { RdDEmpoignade } from "../rdd-empoignade.js"; import { RdDPossession } from "../rdd-possession.js"; import { BASE_CORPS_A_CORPS, BASE_ESQUIVE, POSSESSION_SANS_DRACONIC } from "../item/base-items.js"; +import { RollDataAjustements } from "../rolldata-ajustements.js"; /** * Classe de base pour les acteurs disposant de rêve (donc, pas des objets) @@ -293,6 +294,38 @@ export class RdDBaseActorReve extends RdDBaseActor { createCallbackAppelAuMoral() { return this.createEmptyCallback(); } async _onCloseRollDialog(html) { } + /** + * Méthode pour faire un jet prédéterminer sans ouvrir la fenêtre de dialogue + * @param {*} caracName code ou label de la caractéristique. On peut utiliser 'intel' pour Intellect. + * @param {*} compName nom de compétence ou nom abrégé. + * @param {*} diff difficulté (0 si undefined) + * @param {*} options + * @returns le jet effectué + */ + async doRollCaracCompetence(caracName, compName, diff, options = { title: "" }) { + const carac = this.getCaracByName(caracName); + if (!carac) { + ui.notifications.warn(`${this.name} n'a pas de caractéristique correspondant à ${caracName}`) + return + } + const competence = this.getCompetence(compName); + let rollData = { + alias: this.getAlias(), + caracValue: Number(carac.value), + selectedCarac: carac, + competence: competence, + diffLibre: diff ?? 0, + show: { title: options?.title ?? '' } + } + RollDataAjustements.calcul(rollData, this); + await RdDResolutionTable.rollData(rollData); + this.gererExperience(rollData); + await RdDResolutionTable.displayRollData(rollData, this) + return rollData.rolled; + } + + gererExperience(rollData) { } + /* -------------------------------------------- */ async roll() { RdDEmpoignade.checkEmpoignadeEnCours(this) diff --git a/module/actor/base-actor-sheet.js b/module/actor/base-actor-sheet.js index 5d88b2f4..96b13827 100644 --- a/module/actor/base-actor-sheet.js +++ b/module/actor/base-actor-sheet.js @@ -5,6 +5,7 @@ import { RdDSheetUtility } from "../rdd-sheet-utility.js"; import { Monnaie } from "../item-monnaie.js"; import { RdDItem, ITEM_TYPES } from "../item.js"; import { RdDItemCompetenceCreature } from "../item-competencecreature.js"; +import { RdDTextEditor } from "../apps/rdd-text-roll.js"; /* -------------------------------------------- */ /** @@ -35,8 +36,8 @@ export class RdDBaseActorSheet extends ActorSheet { img: this.actor.img, name: this.actor.name, system: this.actor.system, - description: await TextEditor.enrichHTML(this.actor.system.description, { async: true }), - notesmj: await TextEditor.enrichHTML(this.actor.system.notesmj, { async: true }), + description: await RdDTextEditor.enrichHTML(this.actor.system.description), + notesmj: await RdDTextEditor.enrichHTML(this.actor.system.notesmj), options: RdDSheetUtility.mergeDocumentRights(this.options, this.actor, this.isEditable), effects: this.actor.effects } diff --git a/module/apps/rdd-text-roll.js b/module/apps/rdd-text-roll.js new file mode 100644 index 00000000..bb9beb11 --- /dev/null +++ b/module/apps/rdd-text-roll.js @@ -0,0 +1,54 @@ +import "./xregexp-all.js"; +import { RdDCarac } from "../rdd-carac.js"; +import { SystemCompendiums } from "../settings/system-compendiums.js"; +import { RdDItemCompetence } from "../item-competence.js"; +import { ACTOR_TYPES } from "../item.js"; + +const XREGEXP_ROLL = XRegExp("@roll\\[(?[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+)(\\/(?[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+))?(/(?[\\+\\-]?\\d+))?\\]", 'giu') + +export class RdDTextEditor { + static async enrichHTML(text) { + const rddTextEditor = new RdDTextEditor(text) + const replacedRolls = await rddTextEditor.replaceRolls() + return await TextEditor.enrichHTML(replacedRolls, { async: true }) + } + + constructor(text) { + this.original = text + } + + async replaceRolls() { + if (!this.updated) { + this.updated = this.original + await XRegExp.forEach(this.original, XREGEXP_ROLL, async (rollMatch, i) => await this._replaceOneRoll(rollMatch)) + } + return this.updated + } + + async _replaceOneRoll(rollMatch) { + const carac = RdDCarac.caracDetails(rollMatch.carac); + const competence = rollMatch.competence ? RdDItemCompetence.findCompetence(await SystemCompendiums.getCompetences(ACTOR_TYPES.personnage), + rollMatch.competence) : undefined + + if (carac) { + + const replacement = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/apps/link-text-roll.hbs`, { + carac: carac, + competence: competence?.name, + diff: rollMatch.diff + }); + this.updated = this.updated.replace(rollMatch[0], replacement); + } + } + + static async rollText(event, actor) { + const caracCode = event.currentTarget.attributes['data-carac-code'].value; + const competence = event.currentTarget.attributes['data-competence']?.value; + const diff = event.currentTarget.attributes['data-diff']?.value + + const path = RdDCarac.caracDetails(caracCode)?.path + const actors = actor ? [actor] : canvas.tokens.controlled.map(it => it.actor).filter(it => it) + actors.filter(it => foundry.utils.getProperty(it, path) != undefined) + .forEach(it => it.doRollCaracCompetence(caracCode, competence, diff)) + } +} \ No newline at end of file diff --git a/module/apps/xregexp-all.js b/module/apps/xregexp-all.js index 19543a64..9655338b 100644 --- a/module/apps/xregexp-all.js +++ b/module/apps/xregexp-all.js @@ -2002,7 +2002,7 @@ XRegExp.exec = function (str, regex, pos, sticky) { */ -XRegExp.forEach = function (str, regex, callback) { +XRegExp.forEach = async function (str, regex, callback) { var pos = 0; var i = -1; var match; @@ -2014,7 +2014,7 @@ XRegExp.forEach = function (str, regex, callback) { // at least. Actually, because of the way `XRegExp.exec` caches globalized versions of // regexes, mutating the regex will not have any effect on the iteration or matched strings, // which is a nice side effect that brings extra safety. - callback(match, ++i, str, regex); + await callback(match, ++i, str, regex); pos = match.index + (match[0].length || 1); } }; diff --git a/module/item-sheet.js b/module/item-sheet.js index e25aaddd..90c3c339 100644 --- a/module/item-sheet.js +++ b/module/item-sheet.js @@ -12,8 +12,9 @@ import { SystemCompendiums } from "./settings/system-compendiums.js"; import { Misc } from "./misc.js"; import { RdDTimestamp } from "./time/rdd-timestamp.js"; import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; -import { ITEM_TYPES, RdDItem } from "./item.js"; +import { ACTOR_TYPES, ITEM_TYPES, RdDItem } from "./item.js"; import { FLEUVE_COORD, TMRUtility } from "./tmr-utility.js"; +import { RdDTextEditor } from "./apps/rdd-text-roll.js"; /** * Extend the basic ItemSheet for RdD specific items @@ -97,11 +98,11 @@ export class RdDItemSheet extends ItemSheet { name: this.item.name, system: this.item.system, actorId: this.actor?.id, - description: await TextEditor.enrichHTML(this.item.system.description, { async: true }), - descriptionmj: await TextEditor.enrichHTML(this.item.system.descriptionmj, { async: true }), + description: await RdDTextEditor.enrichHTML(this.item.system.description), + descriptionmj: await RdDTextEditor.enrichHTML(this.item.system.descriptionmj), isComestible: this.item.getUtilisationCuisine(), options: RdDSheetUtility.mergeDocumentRights(this.options, this.item, this.isEditable), - competences: await SystemCompendiums.getCompetences('personnage'), + competences: await SystemCompendiums.getCompetences(ACTOR_TYPES.personnage), categories: RdDItem.getCategories(this.item.type), } @@ -120,18 +121,18 @@ export class RdDItemSheet extends ItemSheet { formData.competences = formData.competences.filter(it => it.isCompetenceArme()) } if (this.item.type == ITEM_TYPES.recettecuisine) { - formData.ingredients = await TextEditor.enrichHTML(this.object.system.ingredients, { async: true }) + formData.ingredients = await RdDTextEditor.enrichHTML(this.object.system.ingredients) } if (this.item.type == ITEM_TYPES.extraitpoetique) { - formData.extrait = await TextEditor.enrichHTML(this.object.system.extrait, { async: true }) - formData.texte = await TextEditor.enrichHTML(this.object.system.texte, { async: true }) + formData.extrait = await RdDTextEditor.enrichHTML(this.object.system.extrait) + formData.texte = await RdDTextEditor.enrichHTML(this.object.system.texte) } if (this.item.type == ITEM_TYPES.recettealchimique) { - RdDAlchimie.processManipulation(this.item, this.actor?.id); - formData.manipulation_update = await TextEditor.enrichHTML(this.object.system.manipulation_update, { async: true }) - formData.utilisation = await TextEditor.enrichHTML(this.object.system.utilisation, { async: true }) - formData.enchantement = await TextEditor.enrichHTML(this.object.system.enchantement, { async: true }) - formData.sureffet = await TextEditor.enrichHTML(this.object.system.sureffet, { async: true }) + const manipulation = RdDAlchimie.processManipulation(this.item, this.actor?.id); + formData.manipulation = await RdDTextEditor.enrichHTML(manipulation) + formData.utilisation = await RdDTextEditor.enrichHTML(this.object.system.utilisation) + formData.enchantement = await RdDTextEditor.enrichHTML(this.object.system.enchantement) + formData.sureffet = await RdDTextEditor.enrichHTML(this.object.system.sureffet) } if (this.item.type == ITEM_TYPES.gemme) { formData.gemmeTypeList = RdDGemme.getGemmeTypeOptionList(); @@ -207,6 +208,7 @@ export class RdDItemSheet extends ItemSheet { this.html.find('.creer-potion-base').click((event) => this._getEventActor(event).actionHerbe(this.item)); this.html.find('input[name="system.cacher_points_de_tache"]').change(async event => await this.item.update({ 'system.cacher_points_de_tache': event.currentTarget.checked })); + this.html.find('.roll-carac-competence').click(async event => await RdDTextEditor.rollText(event, this.actor)) this.html.find('.alchimie-tache a').click((event) => { let actor = this._getEventActor(event); if (actor) { @@ -272,7 +274,7 @@ export class RdDItemSheet extends ItemSheet { } } - async supprimerBonusCase(deleteCoord){ + async supprimerBonusCase(deleteCoord) { if (this.item.type == ITEM_TYPES.sort) { const oldList = RdDItemSort.getBonusCaseList(this.item) const newList = oldList.filter(it => it.case != deleteCoord); diff --git a/module/item/race.js b/module/item/race.js index 13fb921e..49216f3a 100644 --- a/module/item/race.js +++ b/module/item/race.js @@ -1,6 +1,6 @@ import { ITEM_TYPES, RdDItem } from "../item.js"; import { Misc } from "../misc.js"; -import { LIST_CARAC, RdDCarac } from "../rdd-carac.js"; +import { LIST_CARAC_PERSONNAGE, RdDCarac } from "../rdd-carac.js"; export class RdDItemRace extends RdDItem { @@ -12,7 +12,7 @@ export class RdDItemRace extends RdDItem { static checkRacialMax(actor, code, value) { const race = RdDItemRace.getRace(actor) - if (code == LIST_CARAC.force.code) { + if (code == LIST_CARAC_PERSONNAGE.force.code) { if (!race.isForceValid(actor, value)) { ui.notifications.warn(race.system.carac.force.limitmessage) return false @@ -55,7 +55,7 @@ export class RdDItemRace extends RdDItem { if (value == undefined) { value = path ? foundry.utils.getProperty(actor, path) : 0 } - if (code == LIST_CARAC.force.code) { + if (code == LIST_CARAC_PERSONNAGE.force.code) { return value >= this.getForceMax(actor) } const max = foundry.utils.getProperty(this, path) ?? -1 diff --git a/module/rdd-alchimie.js b/module/rdd-alchimie.js index 0a58d09d..678f6295 100644 --- a/module/rdd-alchimie.js +++ b/module/rdd-alchimie.js @@ -20,7 +20,7 @@ export class RdDAlchimie { } } } - recette.system.manipulation_update = manip; + return manip; } /* -------------------------------------------- */ diff --git a/module/rdd-carac.js b/module/rdd-carac.js index 29fec0f9..76ad5b88 100644 --- a/module/rdd-carac.js +++ b/module/rdd-carac.js @@ -37,7 +37,7 @@ const TABLE_CARACTERISTIQUES_DERIVEES = { 32: { xp: 180, niveau: 11, poids: "1501-2000", poidsMin: 1501, poidsMax: 2000, plusdom: +11, sconst: 10, sust: 17 } }; -export const LIST_CARAC = { +export const LIST_CARAC_PERSONNAGE = { 'taille': { code: 'taille', label: 'Taille', isCarac: true, path: 'system.carac.taille.value' }, 'apparence': { code: 'apparence', label: 'Apparence', isCarac: true, path: 'system.carac.apparence.value' }, 'constitution': { code: 'constitution', label: 'Constitution', isCarac: true, path: 'system.carac.constitution.value' }, @@ -56,18 +56,43 @@ export const LIST_CARAC = { 'beaute': { code: 'beaute', label: 'Beauté', isCarac: false, path: 'system.background.beaute.value' } } +export const LIST_CARAC_AUTRES = { + 'perception': { code: 'perception', label: 'Perception', path: 'system.carac.perception.value' }, +} + +const LIST_CARAC_DERIVEE = { + 'melee': { code: "melee", label: 'Mêlée', path: 'system.carac.melee.value' }, + 'tir': { code: "tir", label: 'Tir', path: 'system.carac.tir.value' }, + 'lancer': { code: "lancer", label: 'Lancer', path: 'system.carac.lancer.value' }, + 'derobee': { code: "derobee", label: 'Dérobée', path: 'system.carac.derobee.value' }, + 'chance-actuelle': { code: "chance-actuelle", label: 'Chance actuelle', path: 'system.carac.lancer.value' }, + 'reve-actuel': { code: "reve-actuel", label: 'Rêve actuel', path: 'system.reve.reve.value' }, +} + +const LIST_CARAC_ROLL = Object.values(LIST_CARAC_PERSONNAGE).filter(it => it.isCarac && it.code != 'taille') + .concat(Object.values(LIST_CARAC_AUTRES)) + .concat(Object.values(LIST_CARAC_DERIVEE)) + export class RdDCarac { + static caracDetails(name) { + let entry = Misc.findFirstLike(name, LIST_CARAC_ROLL, { mapper: it => it.code, description: 'caractéristique', onMessage: m => { } }) + if (entry && entry.length > 0) { + return entry + } + return Misc.findFirstLike(name, LIST_CARAC_ROLL, { mapper: it => it.label, description: 'caractéristique' }) + } + static carac(code) { - return LIST_CARAC[code] + return LIST_CARAC_PERSONNAGE[code] } static label(code) { - return RdDCarac.carac(code)?.label ?? '---' - } + return RdDCarac.carac(code)?.label ?? '---' + } static caracs(filter = it => it.isCarac) { - return Object.values(LIST_CARAC).filter(filter) + return Object.values(LIST_CARAC_PERSONNAGE).filter(filter) } static isAgiliteOuDerobee(selectedCarac) { diff --git a/template.json b/template.json index 1e617c7e..f1835b56 100644 --- a/template.json +++ b/template.json @@ -3,9 +3,9 @@ "types": ["personnage", "creature", "entite", "commerce", "vehicule"], "templates": { "description": { - "description": "Description ...", + "description": "", "race": "", - "notesmj": "Notes du MJ" + "notesmj": "" }, "subacteurs": { "subacteurs": { diff --git a/templates/apps/link-text-roll.hbs b/templates/apps/link-text-roll.hbs new file mode 100644 index 00000000..2e8c306d --- /dev/null +++ b/templates/apps/link-text-roll.hbs @@ -0,0 +1,8 @@ + +{{~uppercase carac.label~}} +{{#if competence}} / {{upperFirst competence}}{{/if~}} +{{#if diff}} à {{diff}}{{/if~}} + diff --git a/templates/item-recettealchimique-sheet.html b/templates/item-recettealchimique-sheet.html index 08a5f589..af88c741 100644 --- a/templates/item-recettealchimique-sheet.html +++ b/templates/item-recettealchimique-sheet.html @@ -9,7 +9,7 @@
- {{editor manipulation_update target="system.manipulation" button=true owner=options.isOwner editable=options.editable engine="prosemirror"}} + {{editor manipulation target="system.manipulation" button=true owner=options.isOwner editable=options.editable engine="prosemirror"}}
From 7e736a00d7fbcbb86270d607317e7d2f5b798eb9 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 11 Jan 2025 02:19:56 +0100 Subject: [PATCH 2/9] Gestion des blocs secrets dans les descriptions --- changelog.md | 1 + module/actor-sheet.js | 4 ++-- module/actor/base-actor-sheet.js | 4 ++-- module/apps/rdd-text-roll.js | 8 ++++++-- module/item-sheet.js | 18 +++++++++--------- module/rdd-main.js | 2 +- module/rdd-utility.js | 2 +- 7 files changed, 22 insertions(+), 17 deletions(-) diff --git a/changelog.md b/changelog.md index 42d945b1..0901f10d 100644 --- a/changelog.md +++ b/changelog.md @@ -3,6 +3,7 @@ - on peut ajouter des liens "jet de dés" dans les descriptions, notes, ... - les liens "jet de dés" peuvent être utilisés pour un acteur, ou les items de l'acteurs - les liens "jet de dés" d'"un item non lié à un acteur agit sur les tokens sélectionnés +- gestion des blocs secrets dans les descriptions ## 12.0.33 - la vieillesse d'Astrobazzarh - retour de l'expérience pour les joueurs diff --git a/module/actor-sheet.js b/module/actor-sheet.js index c96dfc13..257835ab 100644 --- a/module/actor-sheet.js +++ b/module/actor-sheet.js @@ -45,8 +45,8 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { cssClass: this.isEditable ? "editable" : "locked", limited: this.actor.limited, owner: this.actor.isOwner, - biographie: await RdDTextEditor.enrichHTML(this.actor.system.biographie), - notes: await RdDTextEditor.enrichHTML(this.actor.system.notes), + biographie: await RdDTextEditor.enrichHTML(this.actor.system.biographie, this.actor), + notes: await RdDTextEditor.enrichHTML(this.actor.system.notes, this.actor), }); foundry.utils.mergeObject(formData.calc, { surenc: this.actor.computeMalusSurEncombrement(), diff --git a/module/actor/base-actor-sheet.js b/module/actor/base-actor-sheet.js index 96b13827..c6a3fb7d 100644 --- a/module/actor/base-actor-sheet.js +++ b/module/actor/base-actor-sheet.js @@ -36,8 +36,8 @@ export class RdDBaseActorSheet extends ActorSheet { img: this.actor.img, name: this.actor.name, system: this.actor.system, - description: await RdDTextEditor.enrichHTML(this.actor.system.description), - notesmj: await RdDTextEditor.enrichHTML(this.actor.system.notesmj), + description: await RdDTextEditor.enrichHTML(this.actor.system.description, this.actor), + notesmj: await RdDTextEditor.enrichHTML(this.actor.system.notesmj, this.actor), options: RdDSheetUtility.mergeDocumentRights(this.options, this.actor, this.isEditable), effects: this.actor.effects } diff --git a/module/apps/rdd-text-roll.js b/module/apps/rdd-text-roll.js index bb9beb11..0dd65f91 100644 --- a/module/apps/rdd-text-roll.js +++ b/module/apps/rdd-text-roll.js @@ -7,10 +7,14 @@ import { ACTOR_TYPES } from "../item.js"; const XREGEXP_ROLL = XRegExp("@roll\\[(?[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+)(\\/(?[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+))?(/(?[\\+\\-]?\\d+))?\\]", 'giu') export class RdDTextEditor { - static async enrichHTML(text) { + static async enrichHTML(text, object) { const rddTextEditor = new RdDTextEditor(text) const replacedRolls = await rddTextEditor.replaceRolls() - return await TextEditor.enrichHTML(replacedRolls, { async: true }) + return await TextEditor.enrichHTML(replacedRolls, { + relativeTo: object, + secrets: object?.isOwner, + async: true + }) } constructor(text) { diff --git a/module/item-sheet.js b/module/item-sheet.js index 90c3c339..3f2b6bde 100644 --- a/module/item-sheet.js +++ b/module/item-sheet.js @@ -98,8 +98,8 @@ export class RdDItemSheet extends ItemSheet { name: this.item.name, system: this.item.system, actorId: this.actor?.id, - description: await RdDTextEditor.enrichHTML(this.item.system.description), - descriptionmj: await RdDTextEditor.enrichHTML(this.item.system.descriptionmj), + description: await RdDTextEditor.enrichHTML(this.item.system.description, this.item), + descriptionmj: await RdDTextEditor.enrichHTML(this.item.system.descriptionmj, this.item), isComestible: this.item.getUtilisationCuisine(), options: RdDSheetUtility.mergeDocumentRights(this.options, this.item, this.isEditable), competences: await SystemCompendiums.getCompetences(ACTOR_TYPES.personnage), @@ -121,18 +121,18 @@ export class RdDItemSheet extends ItemSheet { formData.competences = formData.competences.filter(it => it.isCompetenceArme()) } if (this.item.type == ITEM_TYPES.recettecuisine) { - formData.ingredients = await RdDTextEditor.enrichHTML(this.object.system.ingredients) + formData.ingredients = await RdDTextEditor.enrichHTML(this.item.system.ingredients, this.item) } if (this.item.type == ITEM_TYPES.extraitpoetique) { - formData.extrait = await RdDTextEditor.enrichHTML(this.object.system.extrait) - formData.texte = await RdDTextEditor.enrichHTML(this.object.system.texte) + formData.extrait = await RdDTextEditor.enrichHTML(this.item.system.extrait, this.item) + formData.texte = await RdDTextEditor.enrichHTML(this.item.system.texte, this.item) } if (this.item.type == ITEM_TYPES.recettealchimique) { const manipulation = RdDAlchimie.processManipulation(this.item, this.actor?.id); - formData.manipulation = await RdDTextEditor.enrichHTML(manipulation) - formData.utilisation = await RdDTextEditor.enrichHTML(this.object.system.utilisation) - formData.enchantement = await RdDTextEditor.enrichHTML(this.object.system.enchantement) - formData.sureffet = await RdDTextEditor.enrichHTML(this.object.system.sureffet) + formData.manipulation = await RdDTextEditor.enrichHTML(manipulation, this.item) + formData.utilisation = await RdDTextEditor.enrichHTML(this.item.system.utilisation, this.item) + formData.enchantement = await RdDTextEditor.enrichHTML(this.item.system.enchantement, this.item) + formData.sureffet = await RdDTextEditor.enrichHTML(this.item.system.sureffet, this.item) } if (this.item.type == ITEM_TYPES.gemme) { formData.gemmeTypeList = RdDGemme.getGemmeTypeOptionList(); diff --git a/module/rdd-main.js b/module/rdd-main.js index 15181c78..5e93c66b 100644 --- a/module/rdd-main.js +++ b/module/rdd-main.js @@ -128,7 +128,7 @@ export class SystemReveDeDragon { console.log(`Initializing Reve de Dragon System Settings`) // preload handlebars templates - RdDUtility.preloadHandlebarsTemplates() + await RdDUtility.preloadHandlebarsTemplates() AppPersonnageAleatoire.preloadHandlebars() RdDItemSort.preloadHandlebars() diff --git a/module/rdd-utility.js b/module/rdd-utility.js index 7dc4774a..85cff4ba 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -339,7 +339,7 @@ export class RdDUtility { Handlebars.registerHelper('typeTmr-name', type => TMRUtility.typeTmrName(type)); Handlebars.registerHelper('effetRencontre-name', coord => TMRUtility.typeTmrName(coord)); - return loadTemplates(templatePaths); + await loadTemplates(templatePaths); } static getItem(itemId, actorId = undefined) { From 06aff9a3c0effe353bb30d77e24e7e009c851824 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 11 Jan 2025 02:21:11 +0100 Subject: [PATCH 3/9] =?UTF-8?q?Liens=20jets=20de=20d=C3=A9s=20dans=20les?= =?UTF-8?q?=20journaux?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- changelog.md | 1 + module/journal/journal-sheet.js | 28 ++++++++++++++++++++++++++++ module/rdd-main.js | 2 ++ 3 files changed, 31 insertions(+) create mode 100644 module/journal/journal-sheet.js diff --git a/changelog.md b/changelog.md index 0901f10d..1f3b5e0b 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,6 @@ # 12.0 ## 12.0.34 - la tête d'Astrobazzarh +- on peut ajouter des liens "jet de dés" dans les journaux texte - on peut ajouter des liens "jet de dés" dans les descriptions, notes, ... - les liens "jet de dés" peuvent être utilisés pour un acteur, ou les items de l'acteurs - les liens "jet de dés" d'"un item non lié à un acteur agit sur les tokens sélectionnés diff --git a/module/journal/journal-sheet.js b/module/journal/journal-sheet.js new file mode 100644 index 00000000..852a2d15 --- /dev/null +++ b/module/journal/journal-sheet.js @@ -0,0 +1,28 @@ +import { RdDTextEditor } from "../apps/rdd-text-roll.js"; +import { SYSTEM_RDD } from "../constants.js"; +import { Misc } from "../misc.js"; + + +export class RdDJournalSheet extends JournalTextPageSheet { + static register() { + DocumentSheetConfig.unregisterSheet(JournalEntryPage, "core", JournalTextPageSheet) + DocumentSheetConfig.registerSheet(JournalEntryPage, + SYSTEM_RDD, + RdDJournalSheet, { + types: ["text"], + makeDefault: true, + }); + } + + async getData(options) { + const journalData = await super.getData(options); + journalData.editor.content = await RdDTextEditor.enrichHTML(journalData.document.text.content, this.object) + return journalData + } + + activateListeners(html) { + super.activateListeners(html); + + html.find('.roll-carac-competence').click(async event => await RdDTextEditor.rollText(event, this.actor)) + } +} \ No newline at end of file diff --git a/module/rdd-main.js b/module/rdd-main.js index 5e93c66b..126d3278 100644 --- a/module/rdd-main.js +++ b/module/rdd-main.js @@ -75,6 +75,7 @@ import { ExportScriptarium } from "./actor/export-scriptarium/export-scriptarium import { AppPersonnageAleatoire } from "./actor/random/app-personnage-aleatoire.js" import { RdDActorExportSheet } from "./actor/export-scriptarium/actor-encart-sheet.js" import { RdDStatBlockParser } from "./apps/rdd-import-stats.js" +import { RdDJournalSheet } from "./journal/journal-sheet.js" /** * RdD system @@ -196,6 +197,7 @@ export class SystemReveDeDragon { RdDItemSheet.register(RdDIngredientItemSheet) RdDItemSheet.register(RdDServiceItemSheet) RdDItemSheet.register(RdDBlessureItemSheet) + RdDJournalSheet.register() Items.registerSheet(SYSTEM_RDD, RdDItemInventaireSheet, { types: [ From 792558ac84f155767ae7d52f76e6f8fa63eb5e9c Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 11 Jan 2025 17:32:43 +0100 Subject: [PATCH 4/9] Support @roll[2d6] --- changelog.md | 3 +- module/actor/base-actor-reve-sheet.js | 2 +- module/apps/rdd-text-roll.js | 138 +++++++++++++----- module/constants.js | 16 +- module/item-sheet.js | 2 +- module/journal/journal-sheet.js | 2 +- module/rdd-main.js | 1 + module/rdd-roll.js | 2 +- ...bs => link-text-roll-carac-competence.hbs} | 2 +- templates/apps/link-text-roll-foundry.hbs | 3 + templates/partial-roll-competences.html | 4 +- 11 files changed, 119 insertions(+), 56 deletions(-) rename templates/apps/{link-text-roll.hbs => link-text-roll-carac-competence.hbs} (84%) create mode 100644 templates/apps/link-text-roll-foundry.hbs diff --git a/changelog.md b/changelog.md index 1f3b5e0b..6c9c2de4 100644 --- a/changelog.md +++ b/changelog.md @@ -3,8 +3,9 @@ - on peut ajouter des liens "jet de dés" dans les journaux texte - on peut ajouter des liens "jet de dés" dans les descriptions, notes, ... - les liens "jet de dés" peuvent être utilisés pour un acteur, ou les items de l'acteurs -- les liens "jet de dés" d'"un item non lié à un acteur agit sur les tokens sélectionnés +- les liens "jet de dés" d'un item non lié à un acteur agit sur les tokens sélectionnés - gestion des blocs secrets dans les descriptions +- on peut ajouter des liens "jet de dés" pour appeler une formule de foundry ## 12.0.33 - la vieillesse d'Astrobazzarh - retour de l'expérience pour les joueurs diff --git a/module/actor/base-actor-reve-sheet.js b/module/actor/base-actor-reve-sheet.js index 6d387ae5..6c0fc1ff 100644 --- a/module/actor/base-actor-reve-sheet.js +++ b/module/actor/base-actor-reve-sheet.js @@ -48,7 +48,7 @@ export class RdDBaseActorReveSheet extends RdDBaseActorSheet { } }], { renderSheet: true }) ) - this.html.find('.roll-carac-competence').click(async event => await RdDTextEditor.rollText(event, this.actor)) + this.html.find('.roll-text').click(async event => await RdDTextEditor.rollText(event, this.actor)) if (this.options.vueDetaillee) { // On carac change diff --git a/module/apps/rdd-text-roll.js b/module/apps/rdd-text-roll.js index 0dd65f91..bc99b087 100644 --- a/module/apps/rdd-text-roll.js +++ b/module/apps/rdd-text-roll.js @@ -4,55 +4,113 @@ import { SystemCompendiums } from "../settings/system-compendiums.js"; import { RdDItemCompetence } from "../item-competence.js"; import { ACTOR_TYPES } from "../item.js"; -const XREGEXP_ROLL = XRegExp("@roll\\[(?[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+)(\\/(?[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+))?(/(?[\\+\\-]?\\d+))?\\]", 'giu') +const REGEXP_ROLL_CARAC_COMP = "(?[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+)(\\/(?[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+))?(/(?[\\+\\-]?\\d+))?" +const XREGEXP_ROLL_CARAC_COMP = XRegExp("@roll\\[" + REGEXP_ROLL_CARAC_COMP + "\\]", 'giu') + +const REGEXP_ROLL_FORMULA = "(?[^\\[\\]]+)" +const XREGEXP_ROLL_FORMULA = XRegExp("@roll\\[" + REGEXP_ROLL_FORMULA + "\\]", 'giu') + +/** + * classe pour gérer les jets de caractéristique/compétence depuis + * les journaux/descriptions + */ +class TextRollCaracCompetence { + + static async onReplaceRoll(context) { + const competences = await SystemCompendiums.getCompetences(ACTOR_TYPES.personnage); + const handler = new TextRollCaracCompetence(context.text, competences) + context.text = await handler.replaceRollCaracCompetence() + } + + static async onRollText(event, actor) { + const caracCode = event.currentTarget.attributes['data-carac-code']?.value + if (caracCode) { + const competence = event.currentTarget.attributes['data-competence']?.value + const diff = event.currentTarget.attributes['data-diff']?.value + + const path = RdDCarac.caracDetails(caracCode)?.path + const actors = actor ? [actor] : canvas.tokens.controlled.map(it => it.actor).filter(it => it) + actors.filter(it => foundry.utils.getProperty(it, path) != undefined) + .forEach(it => it.doRollCaracCompetence(caracCode, competence, diff)) + } + } + + constructor(text, competences) { + this.text = text + this.competences = competences + } + + async replaceRollCaracCompetence() { + await XRegExp.forEach(this.text, XREGEXP_ROLL_CARAC_COMP, async (rollMatch, i) => await this._replaceOne(rollMatch, i)) + return this.text + } + + async _replaceOne(rollMatch, i) { + const carac = RdDCarac.caracDetails(rollMatch.carac) + if (carac) { + const competence = rollMatch.competence ? RdDItemCompetence.findCompetence(this.competences, rollMatch.competence) : undefined + const replacement = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/apps/link-text-roll-carac-competence.hbs`, { + carac: carac, + competence: competence?.name, + diff: rollMatch.diff + }) + this.text = this.text.replace(rollMatch[0], replacement) + } + } +} + +class TextRollFoundry { + + static async onReplaceRoll(context) { + const handler = new TextRollFoundry(context.text) + context.text = await handler.replaceRolls() + } + + static async onRollText(event, actor) { + const rollFoundry = event.currentTarget.attributes['data-roll-foundry']?.value + if (rollFoundry) { + const roll = new Roll(rollFoundry) + await roll.evaluate() + await roll.toMessage() + } + } + + constructor(text) { + this.text = text + } + + async replaceRolls() { + await XRegExp.forEach(this.text, XREGEXP_ROLL_FORMULA, async (rollMatch, i) => await this._replaceOne(rollMatch, i)) + return this.text + } + + async _replaceOne(rollMatch, i) { + if (rollMatch.formula) { + const replacement = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/apps/link-text-roll-foundry.hbs`, { + formula: rollMatch.formula, + }) + this.text = this.text.replace(rollMatch[0], replacement) + } + } +} + export class RdDTextEditor { + static async enrichHTML(text, object) { - const rddTextEditor = new RdDTextEditor(text) - const replacedRolls = await rddTextEditor.replaceRolls() - return await TextEditor.enrichHTML(replacedRolls, { + const context = { text } + await TextRollCaracCompetence.onReplaceRoll(context) + await TextRollFoundry.onReplaceRoll(context) + return await TextEditor.enrichHTML(context.text, { relativeTo: object, secrets: object?.isOwner, async: true }) } - constructor(text) { - this.original = text - } - - async replaceRolls() { - if (!this.updated) { - this.updated = this.original - await XRegExp.forEach(this.original, XREGEXP_ROLL, async (rollMatch, i) => await this._replaceOneRoll(rollMatch)) - } - return this.updated - } - - async _replaceOneRoll(rollMatch) { - const carac = RdDCarac.caracDetails(rollMatch.carac); - const competence = rollMatch.competence ? RdDItemCompetence.findCompetence(await SystemCompendiums.getCompetences(ACTOR_TYPES.personnage), - rollMatch.competence) : undefined - - if (carac) { - - const replacement = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/apps/link-text-roll.hbs`, { - carac: carac, - competence: competence?.name, - diff: rollMatch.diff - }); - this.updated = this.updated.replace(rollMatch[0], replacement); - } - } - static async rollText(event, actor) { - const caracCode = event.currentTarget.attributes['data-carac-code'].value; - const competence = event.currentTarget.attributes['data-competence']?.value; - const diff = event.currentTarget.attributes['data-diff']?.value - - const path = RdDCarac.caracDetails(caracCode)?.path - const actors = actor ? [actor] : canvas.tokens.controlled.map(it => it.actor).filter(it => it) - actors.filter(it => foundry.utils.getProperty(it, path) != undefined) - .forEach(it => it.doRollCaracCompetence(caracCode, competence, diff)) + await TextRollCaracCompetence.onRollText(event, actor) + await TextRollFoundry.onRollText(event, actor) } + } \ No newline at end of file diff --git a/module/constants.js b/module/constants.js index a930be62..58088ed8 100644 --- a/module/constants.js +++ b/module/constants.js @@ -1,13 +1,13 @@ -export const SYSTEM_RDD = 'foundryvtt-reve-de-dragon'; -export const SYSTEM_SOCKET_ID = 'system.foundryvtt-reve-de-dragon'; -export const LOG_HEAD = 'RdD | '; +export const SYSTEM_RDD = 'foundryvtt-reve-de-dragon' +export const SYSTEM_SOCKET_ID = 'system.foundryvtt-reve-de-dragon' +export const LOG_HEAD = 'RdD | ' -export const HIDE_DICE = 'hide'; -export const SHOW_DICE = 'show'; +export const HIDE_DICE = 'hide' +export const SHOW_DICE = 'show' -export const ENTITE_INCARNE = 'incarne'; -export const ENTITE_NONINCARNE = 'nonincarne'; -export const ENTITE_BLURETTE = 'blurette'; +export const ENTITE_INCARNE = 'incarne' +export const ENTITE_NONINCARNE = 'nonincarne' +export const ENTITE_BLURETTE = 'blurette' export const RDD_CONFIG = { niveauEthylisme : [ diff --git a/module/item-sheet.js b/module/item-sheet.js index 3f2b6bde..13cf5e91 100644 --- a/module/item-sheet.js +++ b/module/item-sheet.js @@ -208,7 +208,7 @@ export class RdDItemSheet extends ItemSheet { this.html.find('.creer-potion-base').click((event) => this._getEventActor(event).actionHerbe(this.item)); this.html.find('input[name="system.cacher_points_de_tache"]').change(async event => await this.item.update({ 'system.cacher_points_de_tache': event.currentTarget.checked })); - this.html.find('.roll-carac-competence').click(async event => await RdDTextEditor.rollText(event, this.actor)) + this.html.find('.roll-text').click(async event => await RdDTextEditor.rollText(event, this.actor)) this.html.find('.alchimie-tache a').click((event) => { let actor = this._getEventActor(event); if (actor) { diff --git a/module/journal/journal-sheet.js b/module/journal/journal-sheet.js index 852a2d15..9e864635 100644 --- a/module/journal/journal-sheet.js +++ b/module/journal/journal-sheet.js @@ -23,6 +23,6 @@ export class RdDJournalSheet extends JournalTextPageSheet { activateListeners(html) { super.activateListeners(html); - html.find('.roll-carac-competence').click(async event => await RdDTextEditor.rollText(event, this.actor)) + html.find('.roll-text').click(async event => await RdDTextEditor.rollText(event, this.actor)) } } \ No newline at end of file diff --git a/module/rdd-main.js b/module/rdd-main.js index 126d3278..e00089d6 100644 --- a/module/rdd-main.js +++ b/module/rdd-main.js @@ -76,6 +76,7 @@ import { AppPersonnageAleatoire } from "./actor/random/app-personnage-aleatoire. import { RdDActorExportSheet } from "./actor/export-scriptarium/actor-encart-sheet.js" import { RdDStatBlockParser } from "./apps/rdd-import-stats.js" import { RdDJournalSheet } from "./journal/journal-sheet.js" +import { RdDTextEditor } from "./apps/rdd-text-roll.js" /** * RdD system diff --git a/module/rdd-roll.js b/module/rdd-roll.js index c7c69271..b76e64b0 100644 --- a/module/rdd-roll.js +++ b/module/rdd-roll.js @@ -173,7 +173,7 @@ export class RdDRoll extends Dialog { this.updateRollResult(html); this.html.find("[name='diffLibre']").val(this.rollData.diffLibre); }); - this.html.find('.roll-carac-competence').change((event) => { + this.html.find('.roll-text').change((event) => { const competence = event.currentTarget.value this.rollData.competence = this.rollData.competences.find(it => Grammar.equalsInsensitive(it.name, competence)) this.updateRollResult(html); diff --git a/templates/apps/link-text-roll.hbs b/templates/apps/link-text-roll-carac-competence.hbs similarity index 84% rename from templates/apps/link-text-roll.hbs rename to templates/apps/link-text-roll-carac-competence.hbs index 2e8c306d..93652db1 100644 --- a/templates/apps/link-text-roll.hbs +++ b/templates/apps/link-text-roll-carac-competence.hbs @@ -1,4 +1,4 @@ - diff --git a/templates/apps/link-text-roll-foundry.hbs b/templates/apps/link-text-roll-foundry.hbs new file mode 100644 index 00000000..7902ab20 --- /dev/null +++ b/templates/apps/link-text-roll-foundry.hbs @@ -0,0 +1,3 @@ + +{{~formula~}} + diff --git a/templates/partial-roll-competences.html b/templates/partial-roll-competences.html index 10785bd6..e69a9063 100644 --- a/templates/partial-roll-competences.html +++ b/templates/partial-roll-competences.html @@ -1,7 +1,7 @@ {{#if @root.competences}}
- - {{#select ''}} {{>"systems/foundryvtt-reve-de-dragon/templates/enum-competence.html"}} {{/select}} From 551438f514618da7b8cf281a1b943d94a2347e7e Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 11 Jan 2025 18:59:22 +0100 Subject: [PATCH 5/9] =?UTF-8?q?Correction=20sur=20les=20liens=20de=20jets?= =?UTF-8?q?=20de=20d=C3=A9s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - correction jet de rêve actuel - utilisation du personnage du joueur --- changelog.md | 9 +++++++-- module/apps/rdd-text-roll.js | 14 +++++++++++++- module/rdd-carac.js | 2 +- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/changelog.md b/changelog.md index 6c9c2de4..3eeb282d 100644 --- a/changelog.md +++ b/changelog.md @@ -3,9 +3,14 @@ - on peut ajouter des liens "jet de dés" dans les journaux texte - on peut ajouter des liens "jet de dés" dans les descriptions, notes, ... - les liens "jet de dés" peuvent être utilisés pour un acteur, ou les items de l'acteurs -- les liens "jet de dés" d'un item non lié à un acteur agit sur les tokens sélectionnés +- les liens "jet avec caractéristiques" s'appliquent: + - à tous les tokens sélectionnés + - sinon, à l'acteur propriétaire d'un Item + - sinon, au personnage du joueur + - gestion des blocs secrets dans les descriptions -- on peut ajouter des liens "jet de dés" pour appeler une formule de foundry +- on peut ajouter des liens "jet de dés" pour appeler une formule dés de foundry + ## 12.0.33 - la vieillesse d'Astrobazzarh - retour de l'expérience pour les joueurs diff --git a/module/apps/rdd-text-roll.js b/module/apps/rdd-text-roll.js index bc99b087..bca89208 100644 --- a/module/apps/rdd-text-roll.js +++ b/module/apps/rdd-text-roll.js @@ -3,6 +3,7 @@ import { RdDCarac } from "../rdd-carac.js"; import { SystemCompendiums } from "../settings/system-compendiums.js"; import { RdDItemCompetence } from "../item-competence.js"; import { ACTOR_TYPES } from "../item.js"; +import { RdDUtility } from "../rdd-utility.js"; const REGEXP_ROLL_CARAC_COMP = "(?[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+)(\\/(?[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+))?(/(?[\\+\\-]?\\d+))?" const XREGEXP_ROLL_CARAC_COMP = XRegExp("@roll\\[" + REGEXP_ROLL_CARAC_COMP + "\\]", 'giu') @@ -29,11 +30,22 @@ class TextRollCaracCompetence { const diff = event.currentTarget.attributes['data-diff']?.value const path = RdDCarac.caracDetails(caracCode)?.path - const actors = actor ? [actor] : canvas.tokens.controlled.map(it => it.actor).filter(it => it) + const actors = TextRollCaracCompetence.getSelectedActors(actor) actors.filter(it => foundry.utils.getProperty(it, path) != undefined) .forEach(it => it.doRollCaracCompetence(caracCode, competence, diff)) } } + static getSelectedActors(actor) { + const selected = canvas.tokens.controlled.map(it => it.actor).filter(it => it) + if (selected.length > 0){ + return selected + } + actor = actor ?? RdDUtility.getSelectedActor() + if (actor) { + return [actor] + } + return [] + } constructor(text, competences) { this.text = text diff --git a/module/rdd-carac.js b/module/rdd-carac.js index 76ad5b88..f5ad6b31 100644 --- a/module/rdd-carac.js +++ b/module/rdd-carac.js @@ -77,7 +77,7 @@ export class RdDCarac { static caracDetails(name) { let entry = Misc.findFirstLike(name, LIST_CARAC_ROLL, { mapper: it => it.code, description: 'caractéristique', onMessage: m => { } }) - if (entry && entry.length > 0) { + if (entry) { return entry } return Misc.findFirstLike(name, LIST_CARAC_ROLL, { mapper: it => it.label, description: 'caractéristique' }) From 1b75decb18c2dc4c0d6b7516ff21e7979eaac442 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 11 Jan 2025 19:29:29 +0100 Subject: [PATCH 6/9] =?UTF-8?q?Utiliser=20les=20fen=C3=AAtres=20de=20jets?= =?UTF-8?q?=20pour=20les=20jets?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- module/actor-sheet.js | 2 +- module/actor/base-actor-reve-sheet.js | 2 +- module/actor/base-actor-reve.js | 8 +++++--- module/apps/rdd-text-roll.js | 18 ++++++++++++++++-- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/module/actor-sheet.js b/module/actor-sheet.js index 257835ab..7831bce3 100644 --- a/module/actor-sheet.js +++ b/module/actor-sheet.js @@ -222,7 +222,7 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { } // Points de reve actuel - this.html.find('.roll-reve-actuel').click(async event => this.actor.rollCarac('reve-actuel', true)) + this.html.find('.roll-reve-actuel').click(async event => this.actor.rollCarac('reve-actuel', {resistance:true})) this.html.find('.empoignade-label a').click(async event => RdDEmpoignade.onAttaqueEmpoignadeFromItem(RdDSheetUtility.getItem(event, this.actor))) this.html.find('.roll-arme').click(async event => this.actor.rollArme(foundry.utils.duplicate(this._getEventArmeCombat(event)), 'competence')) diff --git a/module/actor/base-actor-reve-sheet.js b/module/actor/base-actor-reve-sheet.js index 6c0fc1ff..2e5fa022 100644 --- a/module/actor/base-actor-reve-sheet.js +++ b/module/actor/base-actor-reve-sheet.js @@ -28,7 +28,7 @@ export class RdDBaseActorReveSheet extends RdDBaseActorSheet { this.html.find('.button-encaissement').click(async event => this.actor.encaisser()) this.html.find('.roll-carac').click(async event => { - this.actor.rollCarac(Grammar.toLowerCaseNoAccent(event.currentTarget.attributes['data-carac-name'].value))}); + this.actor.rollCarac(Grammar.toLowerCaseNoAccent(event.currentTarget.attributes['data-carac-name'].value))}) this.html.find('.roll-competence').click(async event => this.actor.rollCompetence(RdDSheetUtility.getItemId(event))); this.html.find('.endurance-plus').click(async event => this.actor.santeIncDec("endurance", 1)); this.html.find('.endurance-moins').click(async event => this.actor.santeIncDec("endurance", -1)); diff --git a/module/actor/base-actor-reve.js b/module/actor/base-actor-reve.js index bb71912f..1d21d9b7 100644 --- a/module/actor/base-actor-reve.js +++ b/module/actor/base-actor-reve.js @@ -344,14 +344,15 @@ export class RdDBaseActorReve extends RdDBaseActor { competences: this.itemTypes['competence'] }, callbackAction: r => this.$onRollCaracResult(r) - }); + }) } /* -------------------------------------------- */ - async rollCarac(caracName, jetResistance = undefined) { + async rollCarac(caracName, options = {}) { if (Grammar.equalsInsensitive(caracName, 'taille')) { return } + foundry.utils.mergeObject(options, { resistance: false, diff: 0 }, { overwrite: false }) RdDEmpoignade.checkEmpoignadeEnCours(this) let selectedCarac = this.getCaracByName(caracName) console.log("selectedCarac", selectedCarac) @@ -362,7 +363,8 @@ export class RdDBaseActorReve extends RdDBaseActor { rollData: { selectedCarac: selectedCarac, competences: this.itemTypes['competence'], - jetResistance: jetResistance ? caracName : undefined + diffLibre: options.diff ?? 0, + jetResistance: options.resistance ? caracName : undefined }, callbackAction: r => this.$onRollCaracResult(r) }); diff --git a/module/apps/rdd-text-roll.js b/module/apps/rdd-text-roll.js index bca89208..7a808d61 100644 --- a/module/apps/rdd-text-roll.js +++ b/module/apps/rdd-text-roll.js @@ -32,12 +32,26 @@ class TextRollCaracCompetence { const path = RdDCarac.caracDetails(caracCode)?.path const actors = TextRollCaracCompetence.getSelectedActors(actor) actors.filter(it => foundry.utils.getProperty(it, path) != undefined) - .forEach(it => it.doRollCaracCompetence(caracCode, competence, diff)) + .forEach(it => TextRollCaracCompetence.doRoll(it, caracCode, competence, diff)) } } + static async doRoll(actor, caracCode, competence, diff) { + if (competence) { + if (actor.type == ACTOR_TYPES.personnage) { + actor.rollCaracCompetence(caracCode, competence, diff) + } + else { + actor.doRollCaracCompetence(caracCode, competence, diff) + } + } + else { + actor.rollCarac(caracCode, { diff }) + } + } + static getSelectedActors(actor) { const selected = canvas.tokens.controlled.map(it => it.actor).filter(it => it) - if (selected.length > 0){ + if (selected.length > 0) { return selected } actor = actor ?? RdDUtility.getSelectedActor() From 57c41a02189a72fe74430c09dbbcc54a9720416e Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 11 Jan 2025 19:45:58 +0100 Subject: [PATCH 7/9] =?UTF-8?q?Utiliser=20perception/reve=20pour=20les=20c?= =?UTF-8?q?r=C3=A9atures?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ces caractéristiques remplacent toutes les autres --- module/actor/base-actor-reve.js | 1 - module/actor/base-actor.js | 6 ++++-- module/actor/creature.js | 12 ++++++++++++ module/actor/entite.js | 9 +++++++++ module/apps/rdd-text-roll.js | 8 +++----- 5 files changed, 28 insertions(+), 8 deletions(-) diff --git a/module/actor/base-actor-reve.js b/module/actor/base-actor-reve.js index 1d21d9b7..ae40b532 100644 --- a/module/actor/base-actor-reve.js +++ b/module/actor/base-actor-reve.js @@ -346,7 +346,6 @@ export class RdDBaseActorReve extends RdDBaseActor { callbackAction: r => this.$onRollCaracResult(r) }) } - /* -------------------------------------------- */ async rollCarac(caracName, options = {}) { if (Grammar.equalsInsensitive(caracName, 'taille')) { diff --git a/module/actor/base-actor.js b/module/actor/base-actor.js index 544dd711..a4962cfa 100644 --- a/module/actor/base-actor.js +++ b/module/actor/base-actor.js @@ -81,7 +81,6 @@ export class RdDBaseActor extends Actor { } } - static getRealActor(actorId, tokenId) { if (tokenId) { let token = canvas.tokens.get(tokenId) @@ -161,8 +160,11 @@ export class RdDBaseActor extends Actor { return RdDBaseActor.$findCaracByName(carac, name); } + mapCarac(caracCode) { return caracCode } + getCaracByName(name) { - switch (Grammar.toLowerCaseNoAccent(name)) { + name = this.mapCarac(Grammar.toLowerCaseNoAccent(name)) + switch (name) { case 'reve-actuel': case 'reve actuel': return this.getCaracReveActuel(); case 'chance-actuelle': case 'chance-actuelle': diff --git a/module/actor/creature.js b/module/actor/creature.js index c2f51b27..78d3f0cc 100644 --- a/module/actor/creature.js +++ b/module/actor/creature.js @@ -1,4 +1,6 @@ +import { Grammar } from "../grammar.js"; import { ITEM_TYPES } from "../item.js"; +import { LIST_CARAC_AUTRES } from "../rdd-carac.js"; import { RdDBaseActorSang } from "./base-actor-sang.js"; export class RdDCreature extends RdDBaseActorSang { @@ -32,4 +34,14 @@ export class RdDCreature extends RdDBaseActorSang { } } + mapCarac(caracCode) { + switch (caracCode) { + case 'vue': case 'ouie': + case 'odoratgout': + case 'empathie': + return 'perception' + } + return caracCode + } + } diff --git a/module/actor/entite.js b/module/actor/entite.js index ef11b95a..ee6e480b 100644 --- a/module/actor/entite.js +++ b/module/actor/entite.js @@ -117,4 +117,13 @@ export class RdDEntite extends RdDBaseActorReve { super.setEntiteReveAccordee(actor) } } + + mapCarac(caracCode) { + switch (caracCode) { + case 'taille': + return caracCode + } + return 'reve' + } + } diff --git a/module/apps/rdd-text-roll.js b/module/apps/rdd-text-roll.js index 7a808d61..e8c47af7 100644 --- a/module/apps/rdd-text-roll.js +++ b/module/apps/rdd-text-roll.js @@ -24,18 +24,16 @@ class TextRollCaracCompetence { } static async onRollText(event, actor) { - const caracCode = event.currentTarget.attributes['data-carac-code']?.value + const caracCode = event.currentTarget.attributes['data-carac-code']?.value if (caracCode) { const competence = event.currentTarget.attributes['data-competence']?.value const diff = event.currentTarget.attributes['data-diff']?.value - - const path = RdDCarac.caracDetails(caracCode)?.path const actors = TextRollCaracCompetence.getSelectedActors(actor) - actors.filter(it => foundry.utils.getProperty(it, path) != undefined) - .forEach(it => TextRollCaracCompetence.doRoll(it, caracCode, competence, diff)) + actors.forEach(it => TextRollCaracCompetence.doRoll(it, caracCode, competence, diff)) } } static async doRoll(actor, caracCode, competence, diff) { + caracCode = actor.mapCarac(caracCode) if (competence) { if (actor.type == ACTOR_TYPES.personnage) { actor.rollCaracCompetence(caracCode, competence, diff) From ab0f7e563f49e30670e512d2178623f4af3b07d8 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 11 Jan 2025 20:26:15 +0100 Subject: [PATCH 8/9] =?UTF-8?q?Ajout=20de=20jets=20de=20d=C3=A9s=20dans=20?= =?UTF-8?q?les=20compendiums?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../creature_Chrasme_yL1XStIKWxGnhKvR.yml | 53 ++++--- .../creature_Drakkule_kPDswxsWVnSYitfL.yml | 4 +- .../creature_Grincette_VCRmWnhzCF9tJTD0.yml | 2 +- .../creature_Harpie_BgXjyfnolHRQNWCj.yml | 4 +- .../creature_Sir_ne_NZfwIplunfOuuzuD.yml | 4 +- .../creature_Tournedent_e4KXDpAj4seWov6A.yml | 4 +- .../jeu_Le_tisonnier_mRzHzrubRkyqHUTC.yml | 5 +- .../entite_Haine_TBvcGbyEzW0Eoctf.yml | 2 +- .../entite_Peur_M6cQoL6oeAX5IOYa.yml | 2 +- .../entite_Porte_poisse_wcHy6fiEWUnLBSUv.yml | 4 +- .../entite_Quauquemaire_47YUryMgpq1UnLuB.yml | 4 +- .../entite_Squelette_Fl95F6S0OrCbqQbY.yml | 4 +- .../herbe_Herbe_de_lune_x4wGXTdmrzaOn8Sh.yml | 4 +- ...ge_Marmiton_de_Pavois_kB7OSWKvd6m9v0dB.yml | 4 +- .../maladie_Fi_vre_brune_nyruCPiWDd8Scv44.yml | 20 ++- ...umentation_MJ_Joueurs_7uGrUHGdPu0EmIu2.yml | 140 +++++++++++++++++- ...e_Potion_de_Dext_rit__47Wrb4HZnXprP43E.yml | 8 +- ...mique_Potion_de_Force_lGGUyONSD7vJpxsb.yml | 3 +- .../sort_D_rision_7q0zFbBhxYdf6OZ2.yml | 8 +- .../sort_Fatigue_2lsRjTYEef4HdQDB.yml | 2 +- .../sort_Fou_rire_ze53LdwhuqUFMvqw.yml | 2 +- ...t_Marmitons_de_Pavois_CRLUPWjMpBxO5jkV.yml | 2 +- .../sort_Peur_KnyfTatO8GmV5wtt.yml | 2 +- .../sort_Transfiguration_ktFI49xqZ0mGfTzt.yml | 2 +- .../sort_Tympan_d_Hypnos_D9eSbTGp3i5gdbc5.yml | 2 +- ...__caille_d_activit____sEBhR48HagKNbkob.yml | 6 +- .../sort_Brouillard_3JPK8LhnK2RpKoeF.yml | 6 +- ...t_Animer_un_squelette_O1QllxIvIkWxntmO.yml | 2 +- .../sort_Fletrissement_2Bf9INN5L1WSTrnf.yml | 2 +- ..._Griffe_de_Thanatos___gZHrkEnR88mEv67I.yml | 2 +- ...morbide_de_Thanatos___qaCjZ5V874ZImf9l.yml | 2 +- ...llissement_instantan__dArTQtFwTssAyl90.yml | 2 +- ...ete_Pr_sent_des_cit_s_E4a4O1IdrgbNGpVy.yml | 3 +- ...privoiser_les_animaux_wlbbh75GZWks3Ehb.yml | 15 +- ...ete_Don_d_orientation_slnKVCfHbLwbXi4Z.yml | 13 +- ...contr_ler_son_sommeil_N6guZDGzzZjt9GrR.yml | 15 +- ...de_sentir_le_mensonge_OZZbiBiLlM6Y8lEY.yml | 11 +- ..._Don_de_voir_la_magie_QWouooLkM7pE2yG1.yml | 15 +- 38 files changed, 272 insertions(+), 113 deletions(-) diff --git a/packs_src/animaux/creature_Chrasme_yL1XStIKWxGnhKvR.yml b/packs_src/animaux/creature_Chrasme_yL1XStIKWxGnhKvR.yml index aa436ff8..38b30080 100644 --- a/packs_src/animaux/creature_Chrasme_yL1XStIKWxGnhKvR.yml +++ b/packs_src/animaux/creature_Chrasme_yL1XStIKWxGnhKvR.yml @@ -184,16 +184,16 @@ system: value: '+0' label: +dom derivee: true - vitesse: - type: string - value: 12/28 - label: Vitesse - derivee: true encombrement: type: number value: 0 label: Encombrement derivee: false + vitesse: + type: string + value: 12/28 + label: Vitesse + derivee: true protection: type: number value: 4 @@ -207,28 +207,19 @@ system: value: 0 label: Sur-encombrement description: >- -

Description

- -

Description Le chrasme (prononcer krasme) est une sorte de cafard - géant à carapace de crabe aux jointures poilues. Il mesure en - moyenne 1 m de haut sur 1m50 de long, et peut peser jusqu’à 50 - kg. Doté de mandibules acérées et puissantes, il est - redouté pour son venin mortel.

- -

Mœurs

- -

Le chrasme vit dans les lieux sombres, cavernes et souterrains, où - il se nourrit de tout. Paranos le Moindre affirme qu’à - défaut d’une meilleure chère, il peut même se - sustenter de cailloux. Il déteste la lumière comme son cousin - de petite taille, mais a toutefois un comportement différent: au lieu - de fuir, il entre dans une rage féroce et se rue sur le porteur de - lumière pour le réduire en charpie. Savez-vous, cher Paranos, - que vous nous faites un peu peur ?

- -

Venin

-

@UUID[Compendium.foundryvtt-reve-de-dragon.maladies-et-poisons.Item.cFMUtU6LZG0mKeDl]{Venin - de chrasme}

+

Description

Description Le chrasme (prononcer krasme) est une + sorte de cafard géant à carapace de crabe aux jointures poilues. Il mesure + en moyenne 1 m de haut sur 1m50 de long, et peut peser jusqu’à 50 kg. Doté + de mandibules acérées et puissantes, il est redouté pour son venin + mortel.

Mœurs

Le chrasme vit dans les lieux sombres, cavernes + et souterrains, où il se nourrit de tout. Paranos le Moindre affirme qu’à + défaut d’une meilleure chère, il peut même se sustenter de cailloux. Il + déteste la lumière comme son cousin de petite taille, mais a toutefois un + comportement différent: au lieu de fuir, il entre dans une rage féroce et se + rue sur le porteur de lumière pour le réduire en charpie. Savez-vous, cher + Paranos, que vous nous faites un peu peur + ?

Venin

@UUID[Compendium.foundryvtt-reve-de-dragon.maladies-et-poisons.Item.cFMUtU6LZG0mKeDl]{Venin + de chrasme}

race: '' notesmj: '' ownership: @@ -311,7 +302,13 @@ prototypeToken: texture: null _stats: systemId: foundryvtt-reve-de-dragon - systemVersion: 12.0.22 + systemVersion: 12.0.32 coreVersion: '12.331' + createdTime: null + modifiedTime: 1736537299708 + lastModifiedBy: Hp9ImM4o9YRTSdfu + compendiumSource: null + duplicateSource: null +flags: {} _key: '!actors!yL1XStIKWxGnhKvR' diff --git a/packs_src/animaux/creature_Drakkule_kPDswxsWVnSYitfL.yml b/packs_src/animaux/creature_Drakkule_kPDswxsWVnSYitfL.yml index 12c4e2d0..aeb51359 100644 --- a/packs_src/animaux/creature_Drakkule_kPDswxsWVnSYitfL.yml +++ b/packs_src/animaux/creature_Drakkule_kPDswxsWVnSYitfL.yml @@ -203,10 +203,10 @@ system:

En combat, quand un drakkule réussit une particulière et cause au moins une blessure légère, il reste accroché - à sa victime qui perd alors automatiquement 1d6 points + à sa victime qui perd alors automatiquement @roll[1d6] points d’endurance par round sous l’effet de la saignée. Quand l’endurance tombe à zéro, le drakkule continue à - la vider de son sang à raison de 1d6 points de vie par round. Le + la vider de son sang à raison de @roll[1d6] points de vie par round. Le drakkule ne se détache que blessé gravement ou sonné. Pour se dégager, la victime ne peut utiliser que Corps à corps (totaliser 2 points d’empoignade) ou une diff --git a/packs_src/animaux/creature_Grincette_VCRmWnhzCF9tJTD0.yml b/packs_src/animaux/creature_Grincette_VCRmWnhzCF9tJTD0.yml index c927f53b..96ed2854 100644 --- a/packs_src/animaux/creature_Grincette_VCRmWnhzCF9tJTD0.yml +++ b/packs_src/animaux/creature_Grincette_VCRmWnhzCF9tJTD0.yml @@ -137,7 +137,7 @@ system: elles-mêmes, leur grincement involontaire est une torture. Toute personne se trouvant dans un rayon de 10m doit manquer un jet d’OUÏE à +5. Si le jet réussit, perte de 1 point - d’endurance, puis jet de VOLONTÉ à -5. Si le jet de + d’endurance, puis jet de @roll[volonté/-5]. Si le jet de VOLONTÉ échoue, le personnage est sonné jusqu’à la fin du round suivant.

diff --git a/packs_src/animaux/creature_Harpie_BgXjyfnolHRQNWCj.yml b/packs_src/animaux/creature_Harpie_BgXjyfnolHRQNWCj.yml index c534c1e1..6e0f8474 100644 --- a/packs_src/animaux/creature_Harpie_BgXjyfnolHRQNWCj.yml +++ b/packs_src/animaux/creature_Harpie_BgXjyfnolHRQNWCj.yml @@ -174,8 +174,8 @@ system: agressivité s’appliquant aux humanoïdes. S’agissant d’un pouvoir inné, elles n’ont ni à monter dans les TMR, ni à dépenser de points de rêve. La victime - doit jouer un jet de résistance standard, r-8, et en cas - d’échec, réussir un jet de VOLONTÉ à -3 + doit jouer un jet de résistance standard, @roll[reve-actuel/-8], et en cas + d’échec, réussir un jet de @roll[Volonté/-3] pour pouvoir attaquer la harpie. Le JR n’est à jouer qu’une seule fois, tandis qu’en cas d’échec, le jet de VOLONTÉ est à jouer tous les rounds. La non diff --git a/packs_src/animaux/creature_Sir_ne_NZfwIplunfOuuzuD.yml b/packs_src/animaux/creature_Sir_ne_NZfwIplunfOuuzuD.yml index 683a46cc..8486a270 100644 --- a/packs_src/animaux/creature_Sir_ne_NZfwIplunfOuuzuD.yml +++ b/packs_src/animaux/creature_Sir_ne_NZfwIplunfOuuzuD.yml @@ -201,7 +201,7 @@ system:

La sirène a un chant attractif pouvant porter jusqu’à 50 m. Toute personne, homme ou femme, percevant ce chant, même faible - et lointain, doit tenter un jet de VOLONTÉ à -3. Sur toute + et lointain, doit tenter un jet de @roll[Volonté/-3]. Sur toute réussite, le personnage est libre de sa décision"; sur tout échec, il est irrésistiblement attiré vers la source du chant. Quand plusieurs sirènes chantent simultanément, le jet @@ -220,7 +220,7 @@ system: corps, même visage. Certaines sirènes, plus rarement, donnent des illusions d’hommes. Contrairement aux illusions des Yeux d’Hypnos, l’illusion des sirènes donne lieu à un - jet de résistance (standard, r-8). Comme pour les chants, ce JR est + jet de résistance (standard, @roll[reve-actuel/-8]). Comme pour les chants, ce JR est global : s’il réussit, toutes les sirènes apparaissent sous leur véritable apparence; s’il échoue, toutes sont perçues sous leur apparence illusoire.

diff --git a/packs_src/animaux/creature_Tournedent_e4KXDpAj4seWov6A.yml b/packs_src/animaux/creature_Tournedent_e4KXDpAj4seWov6A.yml index 98f11884..de43bd41 100644 --- a/packs_src/animaux/creature_Tournedent_e4KXDpAj4seWov6A.yml +++ b/packs_src/animaux/creature_Tournedent_e4KXDpAj4seWov6A.yml @@ -228,8 +228,8 @@ system: désolations et autres lieux où Thanatos a laissé son empreinte. Ils possèdent le même pouvoir de non agressivité s’appliquant aux humanoïdes que la harpie. La - victime doit jouer un jet de résistance standard, r-8, et en cas - d’échec, réussir un jet de VOLONTÉ à -3 + victime doit jouer un jet de résistance standard, @roll[reve-actuel/-8], et en cas + d’échec, réussir un jet de @roll[Volonté/-3] pour pouvoir attaquer le tournedent. Le JR n’est à jouer qu’une seule fois, et en cas d’échec, le jet de VOLONTÉ est à jouer tous les rounds. La non agressivité diff --git a/packs_src/arts-et-divertissements/jeu_Le_tisonnier_mRzHzrubRkyqHUTC.yml b/packs_src/arts-et-divertissements/jeu_Le_tisonnier_mRzHzrubRkyqHUTC.yml index 9c4c7dbd..e35b63c9 100644 --- a/packs_src/arts-et-divertissements/jeu_Le_tisonnier_mRzHzrubRkyqHUTC.yml +++ b/packs_src/arts-et-divertissements/jeu_Le_tisonnier_mRzHzrubRkyqHUTC.yml @@ -17,9 +17,8 @@ system: à long terme, mais tout autant de l’empathie pour bluffer lors des surenchères.

-

Pour simuler une partie, jouer un jet de CHANCE à zéro - (ajusté astrologiquement), suivi d’un jet d’EMPATHIE/Jeu - à zéro, et additionner les points de tâche obtenus par +

Pour simuler une partie, jouer un jet de @roll[chance/0] + (ajusté astrologiquement), suivi d’un jet d’@roll[EMPATHIE/Jeu/0], et additionner les points de tâche obtenus par les deux jets. Le vainqueur est celui qui en totalise le plus.

descriptionmj: '' type: carte diff --git a/packs_src/entites-de-cauchemar/entite_Haine_TBvcGbyEzW0Eoctf.yml b/packs_src/entites-de-cauchemar/entite_Haine_TBvcGbyEzW0Eoctf.yml index c8c0630f..09f3173c 100644 --- a/packs_src/entites-de-cauchemar/entite_Haine_TBvcGbyEzW0Eoctf.yml +++ b/packs_src/entites-de-cauchemar/entite_Haine_TBvcGbyEzW0Eoctf.yml @@ -104,7 +104,7 @@ system: Dès qu’il se sent lésé, offensé, victime d’un tort même insignifiant, il faut qu’il se venge et que sa vengeance soit mortelle. Il peut jouer un jet de - VOLONTÉ/ moral à zéro. Si le jet réussit, il + @roll[Volonté/0] (avec moral). Si le jet réussit, il peut encore laisser couver sa haine ; s’il échoue, il doit agir immédiatement. Il est conseillé que le gardien des rêves prenne alors le contrôle du personnage s’il s’agit diff --git a/packs_src/entites-de-cauchemar/entite_Peur_M6cQoL6oeAX5IOYa.yml b/packs_src/entites-de-cauchemar/entite_Peur_M6cQoL6oeAX5IOYa.yml index 4bd670a4..cea95732 100644 --- a/packs_src/entites-de-cauchemar/entite_Peur_M6cQoL6oeAX5IOYa.yml +++ b/packs_src/entites-de-cauchemar/entite_Peur_M6cQoL6oeAX5IOYa.yml @@ -104,7 +104,7 @@ system: pareille. Son moral tombe directement à -3 et ne pourra pas remonter tant que durera la possession. Chaque fois qu’une action dangereuse se présente, incluant toute action de combat y compris l’esquive, - la victime doit jouer un jet de VOLONTÉ/moral à zéro. + la victime doit jouer un jet de @roll[Volonté/0] avec moral. Si ce jet échoue, la victime ne fait rien que trembler et claquer des dents.

race: '' diff --git a/packs_src/entites-de-cauchemar/entite_Porte_poisse_wcHy6fiEWUnLBSUv.yml b/packs_src/entites-de-cauchemar/entite_Porte_poisse_wcHy6fiEWUnLBSUv.yml index 30f7ed83..4f364523 100644 --- a/packs_src/entites-de-cauchemar/entite_Porte_poisse_wcHy6fiEWUnLBSUv.yml +++ b/packs_src/entites-de-cauchemar/entite_Porte_poisse_wcHy6fiEWUnLBSUv.yml @@ -132,8 +132,8 @@ system: les désolations et les ruines. Il combat avec son bec acéré. Outre les dommages qu’il cause (+dom +1), chaque fois qu’il porte un coup, même une simple - contusion-éraflure, sa victime doit réussir un jet de points - de rêve actuels ajusté négativement au niveau de + contusion-éraflure, sa victime doit réussir un jet de @roll[reve-actuel] + ajusté négativement au niveau de l’entité, ou perdre 1 point de chance. Les points de chance ainsi perdus peuvent être regagnés selon la règle normale. Détruite, l’entité ne laisse pour tout vestige diff --git a/packs_src/entites-de-cauchemar/entite_Quauquemaire_47YUryMgpq1UnLuB.yml b/packs_src/entites-de-cauchemar/entite_Quauquemaire_47YUryMgpq1UnLuB.yml index 20146a4a..87e4803f 100644 --- a/packs_src/entites-de-cauchemar/entite_Quauquemaire_47YUryMgpq1UnLuB.yml +++ b/packs_src/entites-de-cauchemar/entite_Quauquemaire_47YUryMgpq1UnLuB.yml @@ -158,8 +158,8 @@ system:

Les quauquemaires hantent les endroits lugubres et désolés, les ruines principalement. Ils chantent au coucher du soleil, et leur chant est si lugubre, prometteur d’angoisse et de cauchemar, que quiconque - l’entend et manque un jet de points de rêve actuels - ajusté négativement au niveau de l’entité, ne + l’entend et manque un jet de points de @roll[reve-actuel] ajusté + négativement au niveau de l’entité, ne fait que des cauchemars hideux au cours de sa prochaine nuit de sommeil. En termes de règles, cela signifie : pas de souvenir de l’archétype et donc pas de jet de stress au matin ; pas de diff --git a/packs_src/entites-de-cauchemar/entite_Squelette_Fl95F6S0OrCbqQbY.yml b/packs_src/entites-de-cauchemar/entite_Squelette_Fl95F6S0OrCbqQbY.yml index 9fe35cff..7115d80f 100644 --- a/packs_src/entites-de-cauchemar/entite_Squelette_Fl95F6S0OrCbqQbY.yml +++ b/packs_src/entites-de-cauchemar/entite_Squelette_Fl95F6S0OrCbqQbY.yml @@ -134,8 +134,8 @@ system: nécropoles, catacombes et autres lieux de sépulture. Comme les autres entités, leur raison d’être est de détruire. Le spectacle d’un squelette est d’une horreur - tellement contre nature qu’il demande un jet de VOLONTÉ - à -3. En cas d’échec, le personnage est frappé + tellement contre nature qu’il demande un jet de @roll[Volonté/-3]. + En cas d’échec, le personnage est frappé d’effroi. En termes de règles, il est en demi- surprise jusqu’à la fin du round suivant. Une fois détruit, les ossements constitutifs du squelette s’éparpillent sur le sol, diff --git a/packs_src/faune-flore-mineraux/herbe_Herbe_de_lune_x4wGXTdmrzaOn8Sh.yml b/packs_src/faune-flore-mineraux/herbe_Herbe_de_lune_x4wGXTdmrzaOn8Sh.yml index a71b8131..18e55d31 100644 --- a/packs_src/faune-flore-mineraux/herbe_Herbe_de_lune_x4wGXTdmrzaOn8Sh.yml +++ b/packs_src/faune-flore-mineraux/herbe_Herbe_de_lune_x4wGXTdmrzaOn8Sh.yml @@ -19,8 +19,8 @@ system: dans une pipe ou préparée en décoction. Dans les deux cas, une dose doit être composée de 7 brins. Dès la dose absorbée (bue ou fumée), le consommateur doit jouer un JR - r-force, c’est-à-dire un jet de points de rêve - ajusté négativement à la force de l’herbe. Si le + r-force, c’est-à-dire un jet de @roll[reve-actuel] ajusté + négativement à la force de l’herbe. Si le JR réussit, aucun effet ne se produit"; s’il échoue, le consommateur gagne immédiatement un nombre de points de rêve égal à la force de l’herbe, puis en échange, diff --git a/packs_src/invocations/personnage_Marmiton_de_Pavois_kB7OSWKvd6m9v0dB.yml b/packs_src/invocations/personnage_Marmiton_de_Pavois_kB7OSWKvd6m9v0dB.yml index 4ff4775b..1e0594e2 100644 --- a/packs_src/invocations/personnage_Marmiton_de_Pavois_kB7OSWKvd6m9v0dB.yml +++ b/packs_src/invocations/personnage_Marmiton_de_Pavois_kB7OSWKvd6m9v0dB.yml @@ -506,8 +506,8 @@ system:

VOLONTÉ/moral à - - (degré d’exotisme) + (Cuisine)

+ border-box; user-select: text;">@roll[Volonté/Cuisibe] (avec moral) à - + (degré d’exotisme)

Préambule\n

Ce système pour Foundry est une implémentation de Rêve de Dragon, un jeu de Denis Gerfaud, publié dans sa troisième édition par \"Le Scriptarium\". Rêve de Dragon est une marque déposée par \"Scriptarium\". Tous les droits leur en reviennent naturellement.\_

\n

Merci à Scriptarium (Jidus et Roland Barthelémy) pour l'autorisation d'utilisation des silhouettes de créatures et les Terres Médianes du Rêve.

\n

Crédits :\_

\n
    \n
  • Développement : LeRatierBretonnien & VincentVk
  • \n
  • Compendiums, tests et relectures : Grendel, VincentVk, Fred, Mickael Nome et Fab
  • \n
  • Icones/tokens : Grendel, VincentVk
  • \n
  • Graphisme et styles : Mandar, VincentVk
  • \n
\n

Pour nous contacter : https://discord.gg/pPSDNJk\_ , channel #reve-de-dragon

\n

Créer un Personnage

\n

Tout se fait manuellement à l'heure actuelle, il convient donc procéder comme suit :

\n

Caractéristiques, compétences, équipement

\n
    \n
  • débloquer: pour permettre la saisie rapide des caractéristiques et compétences
  • \n
  • Renseignez les caractéristiques dans l'onglet concerné (le total s'affiche en bas, il doit faire 160).
  • \n
  • Renseignez les niveaux de compétences nécessaires (pareil pour un total de 3000 XP)
  • \n
  • Ouvrez le compendium de l'équipement et faites glisser/déplacer sur l'équipement que vous souhaitez
  • \n
  • Pensez à équiper les armes et les armures pour qu'elles soient utilisables dans les combats
  • \n
\n

Pour aller plus loin sur les compétences:

\n
    \n
  • Filtrer: n'afficher que les compétences avec un niveau supérieur à la base
  • \n
  • Vue détaillée: permet d'accéder à l'archétypes, aux boutons pour éditer les compétences (et choisir une difficulté/caractéristique par défaut), et aux boutons pour allouer du stress
  • \n
\n

Haut-Rêvant

\n

Si votre personnage est haut-rêvant, allez dans le menu Compendium.

\n
    \n
  • Il faut commencer par lui affecter la Tête de Dragon\_ \"Don de haut-rêve\" pour qu'il puisse monter dans les TMR
  • \n
  • Attribuez-lui des sorts en faisant un glisser/déplacer depuis le compendium des Sorts d'Hypnos etc.
  • \n
\n

C'est aussi dans l'onglet Haut-Rêve du personnage que vous pouvez ajouter des têtes, queues, souffles de dragons, (ouvrez le compendium correspondant et faites glisser/déplacer), ainsi que modifier le seuil de rêve.

\n

Partie haute

\n

Les principaux compteurs (vie, endurance, fatigue et rêve, sonné) sont visibles dans la partie haute. Un clic sur le rêve à cet endroit permet de faire un jet de points actuels de rêve (par exemple, un jet de résistance).

\n

Plusieurs boutons sont disponibles:

\n
    \n
  • Encaisser des dommages
  • \n
  • Remise à neuf (Uniquement pour le MJ) pour enlever toutes les blessures/états du personnage.
  • \n
  • \_Le sommeil (dormir une heure, une nuit, gris rêve)
  • \n
  • Montée dans les Terres Médianes
  • \n
  • Montée rapide
  • \n
  • Regarder ses terres médianes (sans monter)
  • \n
\n

Combat

\n

Pour l'initiative et les attaques, des options sont disponibles sur le token (menu contextuel). A droite, l'initiative (préfixe I:), à gauche les attaques (préfixe A:).

\n

Une fois l'initiative réglée, l'attaquant sélectionne sa cible, puis utilise l'option d'attaque avec cette arme souhaitée (il peut aussi utiliser l'arme dans la feuille de persionnage). La fenêtre de jet de résolution est alors ouverte pour choisir sa difficulté libre, et différents ajustements liés aux conditions et tactiques.\_

\n

Si l'attaque réussit, le défenseur recevra un message dans le tchat avec ses actions de défense -ou d'encaissement- disponibles, selon ses compétences : Encaisser, Esquiver, Parer, ...

\n

Un click sur ces actions génère le jet de riposte et produit les résultats. En cas d'échec, le défenseur aura de nouveau un message lui demandant d'encaisser, pour lui donner l'opportunité de faire appel à la chance ou à la destinée.

\n

Si décidément ce n'est pas son jour, il peut cliquer sur le lien pour encaisser, les blessures et l'état général sont automatiquement mis à jour.

\n

Faire un test de Compétence / Caractéristique

\n

Pour réaliser un jet, il suffit de cliquer sur le nom d'une caractéristique, sur une compétence ou sur un objet. Ce clic ouvre la boite de dialogue des jets, qui permet de paramétrer les différentes options (difficulté, compétence/carac, etc). Le lancer affiche les résultats dans le tchat, avec le résultat, la qualité de la réussite, les points d'expérience éventuels à répartir (pour les caractéristiques dérivées) et les points de taches.

\n

L'état général du personnage est automatiquement pris en compte.

\n

De nombreux cas particuliers (interprêter une oeuvre, cuisiner, recette alchimiques, tâches de lecture, de soins, ...) sont aussi disponibles (savoirs et tâches).

\n

Haut Rêve

\n

Pour monter dans les Terres Médianes, il suffit de cliquer sur l'un des boutons \"Monter dans les Terres Médianes!\" sur la feuille de personnage.

\n

La fiche des TMR apparait alors, vous permettant de vous déplacer. Le point de rêve de montée, la fatigue, les rencontres, les cases humides sont automatiquement gérés.

\n

Lorsque vous êtes sur la bonne case, il vous suffit de cliquer sur 'Lancer le sort', qui ouvre la boite de dialogue du lancement.

\n

Si un signe draconique peut être lu dans cette case, il suffit de cliquer sur 'Lire un signe draconique', qui ouvre la boite de dialogue de lecture.

\n

Divers

\n

Certains raccourcis de commandes sont disponibles directement dans le tchat, quelques exemples:

\n
    \n
  • /aide: donne la liste des (nombreuses) commandes disponibles
  • \n
  • /table [table]: effectue un tirage sur la table correspondante (queues, ombres, tete, tetehr, souffle, tarot)
  • \n
  • /rdd: ouvre la table de résolution
  • \n
  • /rdd odor vigil -3: effectue un jet d'Odorat-Goût / Vigilance à -3 pour les tokens sélectionnés
  • \n
  • /rdd 12 0: effectue un jet avec une caractéristique de 12 dans la colonne 0
  • \n
  • /tmra: Tire une case aléatoire des TMR
  • \n
  • /tmra forêt: Tire une forêt aléatoire des TMR
  • \n
  • /tmrr [type de case] [1-100]: détermine la rencontre correspondant au jet de dés pour le type de case
  • \n
  • /signe + et /signe -: permet d'ajouter et enlever des signes draconiques éphémères
  • \n
\n

Il y en a bien d'autres!

\n

\_

\n

Ce qui n'est pas implémenté

\n
    \n
  • Les combats d'empoignade (et certaines spécificités du pugilat)
  • \n
  • Les retours que vous nous ferez via discord (channel #rêve-de-dragon) ;-)
  • \n
\n

" + content: >- +

Préambule

+

Ce système pour Foundry est une implémentation de Rêve de Dragon, + un jeu de Denis Gerfaud, publié dans sa troisième édition par + Scriptarium. Rêve de Dragon est + une marque déposée par Scriptarium. Tous les droits leur en reviennent + naturellement.

+

Merci à Scriptarium (Jidus et Roland Barthelémy) pour l'autorisation + d'utilisation des silhouettes de créatures et les Terres Médianes du + Rêve.

+

Crédits :

+
    +
  • Développement : LeRatierBretonnien & VincentVk
  • +
  • Compendiums, tests et relectures : Grendel, VincentVk, Fred, Mickael Nome et Fab
  • +
  • Icones/tokens : Grendel, VincentVk
  • +
  • Graphisme et styles : Mandar, VincentVk
  • +
+

Pour nous contacter : https://discord.gg/pPSDNJk , channel #reve-de-dragon

+

Créer un Personnage

+

Tout se fait manuellement à l'heure actuelle, il convient donc + procéder comme suit :

+

Caractéristiques, compétences, équipement

+
    +
  • Vue détaillée: pour permettre la saisie + rapide des caractéristiques et compétences
  • +
  • Renseignez les caractéristiques dans l'onglet concerné (le total + s'affiche en bas, il doit faire 160).
  • +
  • Renseignez les niveaux de compétences nécessaires (pareil pour un + total de 3000 XP)
  • +
  • Ouvrez le compendium de l'équipement et faites glisser/déplacer + sur l'équipement que vous souhaitez
  • +
  • Pensez à équiper les armes et les armures pour qu'elles soient + utilisables dans les combats
  • +
+

Pour aller plus loin sur les compétences:

+
    +
  • Filtrer: n'afficher que les compétences avec un niveau supérieur + à la base
  • +
  • Vue détaillée: permet d'accéder à l'archétypes, aux boutons pour + éditer les compétences (et choisir une difficulté/caractéristique par + défaut), et aux boutons pour allouer du stress
  • +
+

Haut-Rêvant

+

Si votre personnage est haut-rêvant, il faut commencer par lui + affecter la Tête de Dragon "Don de haut-rêve" depuis le compendium, + ou depuis l'onglet haut-rêve (pour le MJ) pour qu'il puisse monter + dans les TMR

+

C'est aussi dans l'onglet Haut-Rêve du personnage que vous pouvez + ajouter des têtes, queues, souffles de dragons, (ouvrez le compendium + correspondant et faites glisser/déplacer), ainsi que modifier le + seuil de rêve.

+

Partie haute

+

Les principaux compteurs (vie, endurance, fatigue et rêve, sonné) + sont visibles dans la partie haute. Un clic sur le rêve à cet endroit + permet de faire un jet de points actuels de rêve (par exemple, un + jet de résistance).

+

Plusieurs boutons sont disponibles:

+
    +
  • Encaisser des dommages
  • +
  • Remise à neuf (Uniquement pour le MJ) pour enlever toutes les blessures/états du personnage.
  • +
  • Le sommeil (dormir une heure, une nuit, gris rêve)
  • +
  • Montée dans les Terres Médianes
  • +
  • Montée rapide
  • +
  • Regarder ses terres médianes (sans monter)
  • +
+

Combat

+

Pour l'initiative et les attaques, des options sont disponibles + sur le token (menu contextuel). A droite, l'initiative (préfixe + I:), à gauche les attaques (préfixe A:). +

+

Une fois l'initiative réglée, l'attaquant sélectionne sa + cible, puis utilise l'option d'attaque avec cette + arme souhaitée (il peut aussi utiliser l'arme dans la feuille + de persionnage). La fenêtre de jet de résolution est alors + ouverte pour choisir sa difficulté libre, et différents + ajustements liés aux conditions et tactiques.

+

Si l'attaque réussit, le défenseur recevra un message dans le tchat + avec ses actions de défense -ou d'encaissement- disponibles, selon + ses compétences : Encaisser, Esquiver, Parer, ...

+

Un click sur ces actions génère le jet de riposte et produit les + résultats. En cas d'échec, le défenseur aura de nouveau un message + lui demandant d'encaisser, pour lui donner l'opportunité de faire + appel à la chance ou à la destinée.

+

Si décidément ce n'est pas son jour, il peut cliquer sur le lien + pour encaisser, les blessures et l'état général sont automatiquement + mis à jour.

+

Faire un test de Compétence / Caractéristique

+

Pour réaliser un jet, il suffit de cliquer sur le nom d'une + caractéristique, sur une compétence ou sur un objet. Ce clic ouvre + la boite de dialogue des jets, qui permet de paramétrer les différentes + options (difficulté, compétence/carac, etc). Le lancer affiche les + résultats dans le tchat, avec le résultat, la qualité de la + réussite, les points d'expérience éventuels à répartir (pour + les caractéristiques dérivées) et les points de taches.

+

L'état général du personnage est automatiquement pris en + compte.

+

De nombreux cas particuliers (interprêter une oeuvre, + cuisiner, recette alchimiques, tâches de lecture, de soins, ...) + sont aussi disponibles (savoirs et tâches).

+

Haut Rêve

+

Pour monter dans les Terres Médianes, il suffit de cliquer + sur l'un des boutons "Monter dans les Terres Médianes!" + sur la feuille de personnage.

+

La fiche des TMR apparait alors, vous permettant de vous + déplacer. Le point de rêve de montée, la fatigue, les rencontres, + les cases humides sont automatiquement gérés.

+

Lorsque vous êtes sur la bonne case, il vous suffit de cliquer + sur 'Lancer le sort', qui ouvre la boite de dialogue du lancement.

+

Si un signe draconique peut être lu dans cette case, il + suffit de cliquer sur 'Lire un signe draconique', qui ouvre la + boite de dialogue de lecture.

+

Divers

+

Certains raccourcis de commandes sont disponibles directement + dans le tchat, quelques exemples:

+
    +
  • /aide: donne la liste des (nombreuses) commandes + disponibles
  • +
  • /table [table]: effectue un tirage sur la table + correspondante (queues, ombres, tete, tetehr, souffle, tarot)
  • +
  • /rdd: ouvre la table de résolution
  • +
  • /rdd odor vigil -3: effectue un jet + d'Odorat-Goût / Vigilance à -3 pour les tokens sélectionnés
  • +
  • /rdd 12 0: effectue un jet avec une + caractéristique de 12 dans la colonne 0
  • +
  • /tmra: Tire une case aléatoire des TMR
  • +
  • /tmra forêt: Tire une forêt aléatoire des TMR
  • +
  • /tmrr [type de case] [1-100]: détermine la + rencontre correspondant au jet de dés pour le type de case
  • +
  • /signe + et /signe -: permet + d'ajouter et enlever des signes draconiques éphémères
  • +
+

Il y en a bien d'autres!

+

+

Ce qui n'est pas implémenté

+
    +
  • Les retours que vous nous ferez via discord + (channel #rêve-de-dragon) ;-)
  • +
+

_id: p0xOSy6tZwU4DOq5 image: {} video: diff --git a/packs_src/recettes-alchimiques/recettealchimique_Potion_de_Dext_rit__47Wrb4HZnXprP43E.yml b/packs_src/recettes-alchimiques/recettealchimique_Potion_de_Dext_rit__47Wrb4HZnXprP43E.yml index 2e04329b..06a28d94 100644 --- a/packs_src/recettes-alchimiques/recettealchimique_Potion_de_Dext_rit__47Wrb4HZnXprP43E.yml +++ b/packs_src/recettes-alchimiques/recettealchimique_Potion_de_Dext_rit__47Wrb4HZnXprP43E.yml @@ -16,10 +16,10 @@ system:

Il confère un bonus de +5 à tous les jets de DEXTÉRITÉ, de Tir et de Lancer, et est suivi d’une perte - de 1d6 points d’endurance.

+ de @roll[1d6] points d’endurance.

enchantement: >-

Si la potion est enchantée, l’effet magique n’a lieu - que si un jet de résistance standard est échoué.

+ que si un jet de résistance standard @roll[reve-actuel] est échoué.

L’effet se produit alors dans le round consécutif au jet de résistance (au lieu de 2 minutes) et voit sa durée @@ -32,8 +32,8 @@ system: sur-effet se produise  : la perte totale du goût et de l’odorat (ODORAT-GOÛT tombe à zéro).

-

Pour le regain, jouer tous les matins un jet d’ODORAT- GOÛT - (originel) à zéro et regagner selon le barème des +

Pour le regain, jouer tous les matins un jet + @roll[odorat-gout] (originel)et regagner selon le barème des points de tâche.

manipulation: >-
  • Piler à froid 2 doigts de graisse de carpe et diff --git a/packs_src/recettes-alchimiques/recettealchimique_Potion_de_Force_lGGUyONSD7vJpxsb.yml b/packs_src/recettes-alchimiques/recettealchimique_Potion_de_Force_lGGUyONSD7vJpxsb.yml index e9fa51b3..5b296625 100644 --- a/packs_src/recettes-alchimiques/recettealchimique_Potion_de_Force_lGGUyONSD7vJpxsb.yml +++ b/packs_src/recettes-alchimiques/recettealchimique_Potion_de_Force_lGGUyONSD7vJpxsb.yml @@ -23,7 +23,8 @@ system: points d’endurance.

    enchantement: >-

    Si la potion est enchantée, l’effet magique n’a lieu - que si un jet de résistance standard est échoué.

    + que si un jet de résistance standard @roll[reve-actuel] est + échoué.

    L’effet se produit alors dans le round consécutif au jet de résistance (au lieu de 2 minutes) et voit sa durée diff --git a/packs_src/sorts-hypnos/sort_D_rision_7q0zFbBhxYdf6OZ2.yml b/packs_src/sorts-hypnos/sort_D_rision_7q0zFbBhxYdf6OZ2.yml index 4f0ba601..ea0c5bc8 100644 --- a/packs_src/sorts-hypnos/sort_D_rision_7q0zFbBhxYdf6OZ2.yml +++ b/packs_src/sorts-hypnos/sort_D_rision_7q0zFbBhxYdf6OZ2.yml @@ -18,8 +18,8 @@ system:

    Si un personnage ainsi rendu dérisoire participe à un combat, il peut tenter une fois par round de lancer une plaisanterie en guise d’attaque - (tout en esquivant/parant normalement). Il joue pour cela APPARENCE/ Comédie - à -1d4 (ce d4 résume les conditions ponctuelles plus ou moins propices, et + (tout en esquivant/parant normalement). Il joue pour cela @roll[APPARENCE/Comédie] + à -@roll[1d4] (ce d4 résume les conditions ponctuelles plus ou moins propices, et il est en fait soustrait du bonus de +4 conféré par le sort). Puis selon la réussite, on obtient un ajustement :

    @@ -56,10 +56,10 @@ system:

    Tous les autres engagés dans la mêlée capables de comprendre la blague, y - compris les compagnons du plaisantin, jouent alors VOLONTÉ/moins + compris les compagnons du plaisantin, jouent alors @roll[Volonté] moins moral à + (ajustement) + (Comédie facultativement). Tout échec provoque un état de demi-surprise pour la fin du round et tout le round suivant. En - cas d’échec total à son jet d’APPARENCE/Comédie, le plaisantin est le seul à + cas d’échec total à son jet d’@roll[Apparence/Comédie], le plaisantin est le seul à rire de sa blague, et entre automatiquement en demi-surprise jusqu’à la fin du round suivant.

    descriptionmj: '' diff --git a/packs_src/sorts-hypnos/sort_Fatigue_2lsRjTYEef4HdQDB.yml b/packs_src/sorts-hypnos/sort_Fatigue_2lsRjTYEef4HdQDB.yml index 47dbf595..e0854c27 100644 --- a/packs_src/sorts-hypnos/sort_Fatigue_2lsRjTYEef4HdQDB.yml +++ b/packs_src/sorts-hypnos/sort_Fatigue_2lsRjTYEef4HdQDB.yml @@ -7,7 +7,7 @@ system: description: >-

    Ce sort provoque l’illusion d’une grande fatigue, qui est interprétée comme une fatigue réelle. La victime marque instantanément 6 cases de - fatigue, puis joue un jet de VOLONTÉ à -5 avec un éventuel bonus de +1 par + fatigue, puis joue un jet de @roll[Volonté/-5] avec un éventuel bonus de +1 par point de CONSTITUTION au-dessus de 15. Si le jet de VOLONTÉ réussit, il n’y a pas d’autre conséquence que les cases de fatigue. Si le jet échoue, tout dépend alors de l’activité actuelle de la cible. Si elle est en condition de diff --git a/packs_src/sorts-hypnos/sort_Fou_rire_ze53LdwhuqUFMvqw.yml b/packs_src/sorts-hypnos/sort_Fou_rire_ze53LdwhuqUFMvqw.yml index 9a776e63..41005c9f 100644 --- a/packs_src/sorts-hypnos/sort_Fou_rire_ze53LdwhuqUFMvqw.yml +++ b/packs_src/sorts-hypnos/sort_Fou_rire_ze53LdwhuqUFMvqw.yml @@ -9,7 +9,7 @@ system: humanoïdes. La suggestion d’une idée drolatique plonge la cible dans un irrépressible fou-rire, automatique le premier round. Puis pour les rounds suivants, la cible doit réussir un jet de - VOLONTÉ/ moins moral à -5, ou continuer à + @roll[Volonté/-5] moins moral, ou continuer à rire. Tant que la cible rit, elle est considérée en demi-surprise.

    descriptionmj: '' diff --git a/packs_src/sorts-hypnos/sort_Marmitons_de_Pavois_CRLUPWjMpBxO5jkV.yml b/packs_src/sorts-hypnos/sort_Marmitons_de_Pavois_CRLUPWjMpBxO5jkV.yml index 230bd310..1a32a3d1 100644 --- a/packs_src/sorts-hypnos/sort_Marmitons_de_Pavois_CRLUPWjMpBxO5jkV.yml +++ b/packs_src/sorts-hypnos/sort_Marmitons_de_Pavois_CRLUPWjMpBxO5jkV.yml @@ -25,7 +25,7 @@ system: pouvant aller de 0 à 7 (1d8-1). Pour en supporter le goût "étrange et venu d’ailleurs", les convives doivent réussir un jet de :

    -

    VOLONTÉ/moral à - (degré d’exotisme) + (Cuisine)

    +

    @roll[Volonté/Cuisine] (avec moral) à - (degré d’exotisme)

    Si le jet est réussi, le personnage n’est pas choqué par l’exotisme et peut même en apprécier la gastronomie. Pour tout échec, le personnage est diff --git a/packs_src/sorts-hypnos/sort_Peur_KnyfTatO8GmV5wtt.yml b/packs_src/sorts-hypnos/sort_Peur_KnyfTatO8GmV5wtt.yml index 81ef2e50..8e09b0e8 100644 --- a/packs_src/sorts-hypnos/sort_Peur_KnyfTatO8GmV5wtt.yml +++ b/packs_src/sorts-hypnos/sort_Peur_KnyfTatO8GmV5wtt.yml @@ -7,7 +7,7 @@ system: description: >-

    L’effet de Peur ne s’applique qu’aux humanoïdes. La suggestion d’une horreur intense cause une peur réelle. La victime doit réussir un jet de - VOLONTÉ à -5 ou être sonnée en cas d’échec. Le jet de VOLONTÉ doit être + @roll[Volonté/-5] ou être sonnée en cas d’échec. Le jet de VOLONTÉ doit être renouvelé de round en round jusqu’à ce qu’il réussisse. Tant qu’il échoue, la victime reste en demi-surprise.

    descriptionmj: '' diff --git a/packs_src/sorts-hypnos/sort_Transfiguration_ktFI49xqZ0mGfTzt.yml b/packs_src/sorts-hypnos/sort_Transfiguration_ktFI49xqZ0mGfTzt.yml index 668f3f86..5bacca35 100644 --- a/packs_src/sorts-hypnos/sort_Transfiguration_ktFI49xqZ0mGfTzt.yml +++ b/packs_src/sorts-hypnos/sort_Transfiguration_ktFI49xqZ0mGfTzt.yml @@ -18,7 +18,7 @@ system: impossible d’obtenir le sosie parfait de quelqu’un, tout comme il est difficile à un peintre d’obtenir un portrait parfaitement ressemblant. Si un haut-rêvant désire donner à sa cible la même apparence que quelqu’un - d’autre, il doit jouer un jet de VUE à -8, et obtiendra une ressemblance + d’autre, il doit jouer un jet de @roll[Vue/-8], et obtiendra une ressemblance plus ou moins approchante selon son genre de résultat. Inventer un humanoïde anonyme quoique doté de traits spécifiques (blond, gros nez, une verrue au menton, etc.) s’obtient sans problème. Comme toujours en ce qui concerne diff --git a/packs_src/sorts-hypnos/sort_Tympan_d_Hypnos_D9eSbTGp3i5gdbc5.yml b/packs_src/sorts-hypnos/sort_Tympan_d_Hypnos_D9eSbTGp3i5gdbc5.yml index 79f7ce21..dbc9b376 100644 --- a/packs_src/sorts-hypnos/sort_Tympan_d_Hypnos_D9eSbTGp3i5gdbc5.yml +++ b/packs_src/sorts-hypnos/sort_Tympan_d_Hypnos_D9eSbTGp3i5gdbc5.yml @@ -18,7 +18,7 @@ system: @UUID[Compendium.foundryvtt-reve-de-dragon.rappel-des-regles.JournalEntry.ZmMoOtUdgjMd4cNs]{Conflit de sens}. Le cri illusoire d’un animal doit être le cri d’un animal connu, et vouloir donner à un humanoïde la même voix que quelqu’un d’autre demande - un jet d’OUÏE à -8, avec les mêmes remarques que pour Transfiguration. Noter + un jet d’@roll[Ouie/-8], avec les mêmes remarques que pour Transfiguration. Noter que seule la voix est changée, sans affecter en rien le contenu du discours. Enfin, de même que la taille reste la même pour les illusions visuelles, le volume sonore de l’illusion auditive est celui de la cible. Une souris ne diff --git a/packs_src/sorts-narcos/sort__caille_d_activit____sEBhR48HagKNbkob.yml b/packs_src/sorts-narcos/sort__caille_d_activit____sEBhR48HagKNbkob.yml index 6ee5668f..c2abed2f 100644 --- a/packs_src/sorts-narcos/sort__caille_d_activit____sEBhR48HagKNbkob.yml +++ b/packs_src/sorts-narcos/sort__caille_d_activit____sEBhR48HagKNbkob.yml @@ -37,9 +37,9 @@ system: créateur de l'objet et non de l'utilisateur, et quand le sort a une durée HN, c'est également l'heure de naissance du créateur. Le seul paramétrage inutile est l'heure de naissance de la cible en prévision du jet de - résistance. Quand un JR est possible, il est toujours r-8, quelle que soit - la cible. S'il réussit, le sort se dissipe aussitôt sans revenir vers - l'utilisateur.

    + résistance. Quand un JR est possible, il est toujours @roll[reve-actuel/-8], + quelle que soit la cible. S'il réussit, le sort se dissipe aussitôt sans + revenir vers l'utilisateur.

    L'objet réussit son lancer, sans jet de dés. Lancer un sort via un objet magique n'est pas plus économique en points de rêve que de la lancer diff --git a/packs_src/sorts-oniros/sort_Brouillard_3JPK8LhnK2RpKoeF.yml b/packs_src/sorts-oniros/sort_Brouillard_3JPK8LhnK2RpKoeF.yml index 03f72abe..d1f76bab 100644 --- a/packs_src/sorts-oniros/sort_Brouillard_3JPK8LhnK2RpKoeF.yml +++ b/packs_src/sorts-oniros/sort_Brouillard_3JPK8LhnK2RpKoeF.yml @@ -12,9 +12,9 @@ system: arrêtant totalement la vue. De l’intérieur, il est pareillement impossible de voir ce qui se passe à l’extérieur"; on peut seulement tenter de voir ce qui se passe - à l’intérieur en réussissant un jet de VUE - ajusté négativement par le nombre de points de rêve - dépensés.

    + à l’intérieur en réussissant un jet de + @roll[Vue] ajusté négativement par le nombre de points de + rêve dépensés.

    descriptionmj: '' draconic: Oniros duree: HN diff --git a/packs_src/sorts-thanatos/sort_Animer_un_squelette_O1QllxIvIkWxntmO.yml b/packs_src/sorts-thanatos/sort_Animer_un_squelette_O1QllxIvIkWxntmO.yml index 7d0d1ad7..9ca59fb8 100644 --- a/packs_src/sorts-thanatos/sort_Animer_un_squelette_O1QllxIvIkWxntmO.yml +++ b/packs_src/sorts-thanatos/sort_Animer_un_squelette_O1QllxIvIkWxntmO.yml @@ -19,7 +19,7 @@ system: zombis, et contrairement aux entités de cauchemar incarnées qui peuvent dépasser cette limite, la caractéristique RÊVE d'un squelette invoqué ne peut jamais dépasser sa caractéristique TAILLE. Sa hideur est telle que - quiconque l'aperçoit doit réussir un jet de VOLONTÉ à -3 ou être en + quiconque l'aperçoit doit réussir un jet de @roll[VOLONTÉ/-3] ou être en demi-surprise jusqu'à la fin du round suivant.

    Un squelette invoqué est aux ordres de son invocateur et n'agit qu'aux diff --git a/packs_src/sorts-thanatos/sort_Fletrissement_2Bf9INN5L1WSTrnf.yml b/packs_src/sorts-thanatos/sort_Fletrissement_2Bf9INN5L1WSTrnf.yml index 2a626268..e21f2376 100644 --- a/packs_src/sorts-thanatos/sort_Fletrissement_2Bf9INN5L1WSTrnf.yml +++ b/packs_src/sorts-thanatos/sort_Fletrissement_2Bf9INN5L1WSTrnf.yml @@ -13,7 +13,7 @@ system: à zéro) ou subir en retour l'effet de son sort.

    Le flétrissement n'est pas définitif. Chaque jour, à lextrême fin du - Château Dormant, la victime peur jouer un jet d'APPARENCE à zéro en prenant + Château Dormant, la victime peur jouer un jet d'@roll[APPARENCE/0] en prenant non pas son APPARENCE actuelle, mais son APPARENCE initiale. Toute réussite : regain de 1 point en APPARENCE et de 2 points de Beauté. Tout échec : pas de regain pour aujourd'hui. Dans tous les cas, ni l'APPARENCE ni la Beauté diff --git a/packs_src/sorts-thanatos/sort_Griffe_de_Thanatos___gZHrkEnR88mEv67I.yml b/packs_src/sorts-thanatos/sort_Griffe_de_Thanatos___gZHrkEnR88mEv67I.yml index 25fb01ae..8acfb03a 100644 --- a/packs_src/sorts-thanatos/sort_Griffe_de_Thanatos___gZHrkEnR88mEv67I.yml +++ b/packs_src/sorts-thanatos/sort_Griffe_de_Thanatos___gZHrkEnR88mEv67I.yml @@ -10,7 +10,7 @@ system: maîtrise. Cette dernière est automatique, comme avec les écailles de Narcos, mais au lieu de coûter des points de rêve, elle coûte un nombre de points de vie égal au nombre de griffes, chaque point de vie perdu - s'accompagnant d'une perte d'1d6 points d'endurance. Il n'y a pas de jet de + s'accompagnant d'une perte d'@roll[1d6] points d'endurance. Il n'y a pas de jet de résistance. La maîtrise (et la perte de points de vie) a lieu au moment où l'objet contenant la griffe est utilisé selon sa fonction : arme frappant, bague au doigt, bracelet au poignet, etc. Si l'objet n'a pas de fonction diff --git a/packs_src/sorts-thanatos/sort_Griffe_morbide_de_Thanatos___qaCjZ5V874ZImf9l.yml b/packs_src/sorts-thanatos/sort_Griffe_morbide_de_Thanatos___qaCjZ5V874ZImf9l.yml index d7917b5f..00eff156 100644 --- a/packs_src/sorts-thanatos/sort_Griffe_morbide_de_Thanatos___qaCjZ5V874ZImf9l.yml +++ b/packs_src/sorts-thanatos/sort_Griffe_morbide_de_Thanatos___qaCjZ5V874ZImf9l.yml @@ -8,7 +8,7 @@ system:

    Le principe de fonctionnement de la griffe morbide de Thanatos est analogue à celui de la simple griffe. C'en est une variante plus mortelle. La maîtrise ayant lieu, la victime perd autant de points de vie qu'il y a de - griffes morbides, ainsi que 1d6 points d'endurance par point de vie perdu, + griffes morbides, ainsi que @roll[1d6] points d'endurance par point de vie perdu, puis joue une JR standard r-8. JR réussi, l'effet s'arrête là ; JR échoué, le mal s'est implanté en elle. Tous les jours, à l'extrême fin du Château Dormant, la victime de la griffe morbide doit tenter un jet de Vie et en diff --git a/packs_src/souffles-de-dragon/souffle_Vieillissement_instantan__dArTQtFwTssAyl90.yml b/packs_src/souffles-de-dragon/souffle_Vieillissement_instantan__dArTQtFwTssAyl90.yml index 7c8923fc..31924f7f 100644 --- a/packs_src/souffles-de-dragon/souffle_Vieillissement_instantan__dArTQtFwTssAyl90.yml +++ b/packs_src/souffles-de-dragon/souffle_Vieillissement_instantan__dArTQtFwTssAyl90.yml @@ -4,7 +4,7 @@ type: souffle img: systems/foundryvtt-reve-de-dragon/icons/souffle_dragon.webp system: description: >- -

    Le vieillissement est de 1d7 ans. Jouer un jet de Constitution ajusté +

    Le vieillissement est de 1d7 ans. Jouer un jet de @roll[Constitution] ajusté négativement au nombre d’années perdues. En cas d’échec, perte définitive d’un point en Constitution.

    descriptionmj: '' diff --git a/packs_src/tetes-de-dragon-pour-haut-revants/tete_Pr_sent_des_cit_s_E4a4O1IdrgbNGpVy.yml b/packs_src/tetes-de-dragon-pour-haut-revants/tete_Pr_sent_des_cit_s_E4a4O1IdrgbNGpVy.yml index ddb604d0..ab2d97f4 100644 --- a/packs_src/tetes-de-dragon-pour-haut-revants/tete_Pr_sent_des_cit_s_E4a4O1IdrgbNGpVy.yml +++ b/packs_src/tetes-de-dragon-pour-haut-revants/tete_Pr_sent_des_cit_s_E4a4O1IdrgbNGpVy.yml @@ -10,7 +10,8 @@ system: rêves, soit un Passeur, soit un Messager, dès qu’elle est visitée par le demi-rêve du haut-rêvant. Il n’y a pas de d7 à tirer, le haut-rêvant choisit librement ce qu’il préfère, et la rencontre est considérée automatiquement - maîtrisée, Fleurs, Messagers et Passeurs ayant une force de 2d6 points. Dès + maîtrisée, Fleurs, Messagers et Passeurs ayant une force de @roll[2d6] + points. Dès qu’elle a offert son présent, la cité redevient normale en ce qui concerne le tirage des rencontres; il n’y a qu’un seul présent par cité. La tête de Dragon prend fin dès que toutes les cités (22) ont été visitées; entretemps, diff --git a/packs_src/tetes-de-dragon-pour-tous-personnages/tete_Don_d_apprivoiser_les_animaux_wlbbh75GZWks3Ehb.yml b/packs_src/tetes-de-dragon-pour-tous-personnages/tete_Don_d_apprivoiser_les_animaux_wlbbh75GZWks3Ehb.yml index bafd10ec..5cbd9065 100644 --- a/packs_src/tetes-de-dragon-pour-tous-personnages/tete_Don_d_apprivoiser_les_animaux_wlbbh75GZWks3Ehb.yml +++ b/packs_src/tetes-de-dragon-pour-tous-personnages/tete_Don_d_apprivoiser_les_animaux_wlbbh75GZWks3Ehb.yml @@ -5,13 +5,13 @@ flags: {} img: systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp system: description: >- -

    Un jet d’Empathie à zéro permet de rendre amical un animal non agressif - ou de rendre neutre un animal agressif. Les animaux restent neutres\amicaux +

    Un jet d’@roll[empathie/0] permet de rendre amical un animal non agressif + ou de rendre neutre un animal agressif. Les animaux restent neutres/amicaux jusqu’à ce qu’un événement significatif, agression ou autre, vienne tout remettre en question. Ce n’est pas un lien magique. Un seul jet par animal. Un animal rendu neutre par ce don ne peut pas ensuite être rendu amical par - un second jet. Enfin l’étendue de la neutralité\ amitié de l’animal dépend - de chaque espèce et est à décider dans chaque cas particulier par le gardien + un second jet. Enfin l’étendue de la neutralité/amitié de l’animal dépend de + chaque espèce et est à décider dans chaque cas particulier par le gardien des rêves. Cumulable.

    descriptionmj: '' frequence: 6 @@ -24,7 +24,12 @@ folder: null sort: 0 _stats: systemId: foundryvtt-reve-de-dragon - systemVersion: 12.0.22 + systemVersion: 12.0.33 coreVersion: '12.331' + createdTime: null + modifiedTime: 1736617623199 + lastModifiedBy: Hp9ImM4o9YRTSdfu + compendiumSource: null + duplicateSource: null _key: '!items!wlbbh75GZWks3Ehb' diff --git a/packs_src/tetes-de-dragon-pour-tous-personnages/tete_Don_d_orientation_slnKVCfHbLwbXi4Z.yml b/packs_src/tetes-de-dragon-pour-tous-personnages/tete_Don_d_orientation_slnKVCfHbLwbXi4Z.yml index 6d095c5b..6eaf7100 100644 --- a/packs_src/tetes-de-dragon-pour-tous-personnages/tete_Don_d_orientation_slnKVCfHbLwbXi4Z.yml +++ b/packs_src/tetes-de-dragon-pour-tous-personnages/tete_Don_d_orientation_slnKVCfHbLwbXi4Z.yml @@ -5,9 +5,9 @@ flags: {} img: systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp system: description: >- -

    Un jet d’Empathie à zéro permet de deviner la direction du nord, et d’une - manière générale de retrouver une certaine direction quand on est perdu ou - par manque de visibilité (nuit, brouillard, souterrain, etc.). +

    Un jet d’@roll[empathie/0] permet de deviner la direction du nord, et + d’une manière générale de retrouver une certaine direction quand on est + perdu ou par manque de visibilité (nuit, brouillard, souterrain, etc.). Cumulable.

    descriptionmj: '' frequence: 6 @@ -20,7 +20,12 @@ folder: null sort: 0 _stats: systemId: foundryvtt-reve-de-dragon - systemVersion: 12.0.22 + systemVersion: 12.0.33 coreVersion: '12.331' + createdTime: null + modifiedTime: 1736617654367 + lastModifiedBy: Hp9ImM4o9YRTSdfu + compendiumSource: null + duplicateSource: null _key: '!items!slnKVCfHbLwbXi4Z' diff --git a/packs_src/tetes-de-dragon-pour-tous-personnages/tete_Don_de_contr_ler_son_sommeil_N6guZDGzzZjt9GrR.yml b/packs_src/tetes-de-dragon-pour-tous-personnages/tete_Don_de_contr_ler_son_sommeil_N6guZDGzzZjt9GrR.yml index 2342e74e..7897b4ee 100644 --- a/packs_src/tetes-de-dragon-pour-tous-personnages/tete_Don_de_contr_ler_son_sommeil_N6guZDGzzZjt9GrR.yml +++ b/packs_src/tetes-de-dragon-pour-tous-personnages/tete_Don_de_contr_ler_son_sommeil_N6guZDGzzZjt9GrR.yml @@ -5,10 +5,10 @@ flags: {} img: systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp system: description: >- -

    Un jet de Volonté à zéro permet de s’endormir instantanément et de dormir - au moins jusqu’à la fin de la prochaine heure, même sans aucun point de - fatigue. Permet également de se réveiller au bout d’un laps de temps donné, - "programmé" au moment de s’endormir. Cumulable.

    +

    Un jet de @roll[Volonté/0] permet de s’endormir instantanément et de + dormir au moins jusqu’à la fin de la prochaine heure, même sans aucun point + de fatigue. Permet également de se réveiller au bout d’un laps de temps + donné, "programmé" au moment de s’endormir. Cumulable.

    descriptionmj: '' frequence: 6 hautrevant: false @@ -20,7 +20,12 @@ folder: null sort: 0 _stats: systemId: foundryvtt-reve-de-dragon - systemVersion: 12.0.22 + systemVersion: 12.0.33 coreVersion: '12.331' + createdTime: null + modifiedTime: 1736617674311 + lastModifiedBy: Hp9ImM4o9YRTSdfu + compendiumSource: null + duplicateSource: null _key: '!items!N6guZDGzzZjt9GrR' diff --git a/packs_src/tetes-de-dragon-pour-tous-personnages/tete_Don_de_sentir_le_mensonge_OZZbiBiLlM6Y8lEY.yml b/packs_src/tetes-de-dragon-pour-tous-personnages/tete_Don_de_sentir_le_mensonge_OZZbiBiLlM6Y8lEY.yml index 008782a3..1aaf2044 100644 --- a/packs_src/tetes-de-dragon-pour-tous-personnages/tete_Don_de_sentir_le_mensonge_OZZbiBiLlM6Y8lEY.yml +++ b/packs_src/tetes-de-dragon-pour-tous-personnages/tete_Don_de_sentir_le_mensonge_OZZbiBiLlM6Y8lEY.yml @@ -5,8 +5,8 @@ flags: {} img: systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp system: description: >- -

    Un jet d’Empathie à zéro permet de deviner que l’on vous ment, sans pour - autant connaître la teneur du mensonge. Ne s’applique qu’au mensonge +

    Un jet d’@roll[empathie/0] permet de deviner que l’on vous ment, sans + pour autant connaître la teneur du mensonge. Ne s’applique qu’au mensonge volontaire, pas au mensonge par omission ni par ignorance. Cumulable.

    descriptionmj: '' frequence: 6 @@ -19,7 +19,12 @@ folder: null sort: 0 _stats: systemId: foundryvtt-reve-de-dragon - systemVersion: 12.0.22 + systemVersion: 12.0.33 coreVersion: '12.331' + createdTime: null + modifiedTime: 1736617720094 + lastModifiedBy: Hp9ImM4o9YRTSdfu + compendiumSource: null + duplicateSource: null _key: '!items!OZZbiBiLlM6Y8lEY' diff --git a/packs_src/tetes-de-dragon-pour-tous-personnages/tete_Don_de_voir_la_magie_QWouooLkM7pE2yG1.yml b/packs_src/tetes-de-dragon-pour-tous-personnages/tete_Don_de_voir_la_magie_QWouooLkM7pE2yG1.yml index abc2babd..de464b52 100644 --- a/packs_src/tetes-de-dragon-pour-tous-personnages/tete_Don_de_voir_la_magie_QWouooLkM7pE2yG1.yml +++ b/packs_src/tetes-de-dragon-pour-tous-personnages/tete_Don_de_voir_la_magie_QWouooLkM7pE2yG1.yml @@ -5,10 +5,10 @@ flags: {} img: systems/foundryvtt-reve-de-dragon/icons/tete_dragon.webp system: description: >- -

    Un jet de VUE à zéro permet de distinguer une aura bleutée délimitant les - zones magiques d’Oniros ou entourant les objets enchantés ou les créatures - soumises à l’effet d’un sort ou d’un rituel. Un seul essai par zone, objet - ou personnage. Cumulable.

    +

    Un jet de @roll[vue/0] permet de distinguer une aura bleutée délimitant + les zones magiques d’Oniros ou entourant les objets enchantés ou les + créatures soumises à l’effet d’un sort ou d’un rituel. Un seul essai par + zone, objet ou personnage. Cumulable.

    descriptionmj: '' frequence: 6 hautrevant: false @@ -20,7 +20,12 @@ folder: null sort: 0 _stats: systemId: foundryvtt-reve-de-dragon - systemVersion: 12.0.22 + systemVersion: 12.0.33 coreVersion: '12.331' + createdTime: null + modifiedTime: 1736617743760 + lastModifiedBy: Hp9ImM4o9YRTSdfu + compendiumSource: null + duplicateSource: null _key: '!items!QWouooLkM7pE2yG1' From d53da1f01157d04e3533284be2711bbace8e0081 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sun, 12 Jan 2025 02:38:31 +0100 Subject: [PATCH 9/9] Jets d'alchimie dans descriptions/journaux On ne se limite plus aux manipulations alchimiques, et les jets apparaissent comme tous les autres types de jets --- changelog.md | 2 + module/apps/rdd-import-stats.js | 1 - module/apps/rdd-text-roll.js | 130 ++++++++++++++---- module/item-sheet.js | 15 +- module/rdd-alchimie.js | 45 +----- styles/simple.css | 9 +- templates/apps/link-text-roll-alchimie.hbs | 8 ++ .../apps/link-text-roll-carac-competence.hbs | 1 + templates/apps/link-text-roll-foundry.hbs | 4 +- 9 files changed, 129 insertions(+), 86 deletions(-) create mode 100644 templates/apps/link-text-roll-alchimie.hbs diff --git a/changelog.md b/changelog.md index 3eeb282d..cfcb7cbc 100644 --- a/changelog.md +++ b/changelog.md @@ -10,6 +10,8 @@ - gestion des blocs secrets dans les descriptions - on peut ajouter des liens "jet de dés" pour appeler une formule dés de foundry +- les liens "manipulation alchimiques" peuvent être dans les descriptions, notes, ... +- les "manipulation alchimiques" fonctionnent comme tous les autres jets ## 12.0.33 - la vieillesse d'Astrobazzarh diff --git a/module/apps/rdd-import-stats.js b/module/apps/rdd-import-stats.js index 78ea64ed..d07cdc39 100644 --- a/module/apps/rdd-import-stats.js +++ b/module/apps/rdd-import-stats.js @@ -34,7 +34,6 @@ const XREGEXP_WEAPON_MANIEMENT = "(?(" + Misc.join(Object.keys(MANIEM const XREGEXP_SORT_VOIE = "(?[OHNT](\\/[OHNT])*)" const XREGEXP_SORT_NAME = "(?[^\\(]+)" -// const XREGEXP_SORT_CASE = "(?([A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+|[A-M]\\d{1,2})+)" const XREGEXP_SORT_CASE = "(?([A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+|[A-M]\\d{1,2}))" const XREGEXP_SORT = "(" + XREGEXP_SORT_VOIE diff --git a/module/apps/rdd-text-roll.js b/module/apps/rdd-text-roll.js index e8c47af7..c0249edf 100644 --- a/module/apps/rdd-text-roll.js +++ b/module/apps/rdd-text-roll.js @@ -2,8 +2,15 @@ import "./xregexp-all.js"; import { RdDCarac } from "../rdd-carac.js"; import { SystemCompendiums } from "../settings/system-compendiums.js"; import { RdDItemCompetence } from "../item-competence.js"; -import { ACTOR_TYPES } from "../item.js"; +import { ACTOR_TYPES, ITEM_TYPES } from "../item.js"; import { RdDUtility } from "../rdd-utility.js"; +import { Misc } from "../misc.js"; +import { RdDAlchimie } from "../rdd-alchimie.js"; + +const REGEX_ALCHIMIE_TERMES = "(?(\\w|-)+)" +const REGEX_ALCHIMIE_MANIP = "(?(couleur|consistance))" +const XREGEXP_ROLL_ALCHIMIE = XRegExp("@roll\\[" + REGEX_ALCHIMIE_MANIP + "\\s+" + REGEX_ALCHIMIE_TERMES + "\\]", 'giu') +const XREGEXP_ROLL_ALCHIMIE_MANIP = XRegExp("@" + REGEX_ALCHIMIE_MANIP + "\\{" + REGEX_ALCHIMIE_TERMES + "\\}", 'giu') const REGEXP_ROLL_CARAC_COMP = "(?[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+)(\\/(?[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+))?(/(?[\\+\\-]?\\d+))?" const XREGEXP_ROLL_CARAC_COMP = XRegExp("@roll\\[" + REGEXP_ROLL_CARAC_COMP + "\\]", 'giu') @@ -11,42 +18,109 @@ const XREGEXP_ROLL_CARAC_COMP = XRegExp("@roll\\[" + REGEXP_ROLL_CARAC_COMP + "\ const REGEXP_ROLL_FORMULA = "(?[^\\[\\]]+)" const XREGEXP_ROLL_FORMULA = XRegExp("@roll\\[" + REGEXP_ROLL_FORMULA + "\\]", 'giu') + +/** + * classe pour gérer les jets d'alchimie + */ +class TextRollAlchimie { + static async onRollText(event, actor) { + actor = TextRollAlchimie.getSelectedActor(actor) + if (actor) { + const recetteId = event.currentTarget.attributes['data-recette-id']?.value + const manip = event.currentTarget.attributes['data-manip'].value + const termes = event.currentTarget.attributes['data-termes'].value + if (recetteId) { + await actor.effectuerTacheAlchimie(recetteId, manip, termes) + } + else { + const carac = RdDCarac.caracDetails(RdDAlchimie.getCaracTache(manip)) + const diff = RdDAlchimie.getDifficulte(termes) + await actor.rollCaracCompetence(carac.code, 'Alchimie', diff) + } + } + } + + static getSelectedActor(actor) { + actor = actor ?? RdDUtility.getSelectedActor() + if (actor && actor.type == ACTOR_TYPES.personnage) { + return actor + } + return undefined + } + + static async onReplaceRoll(context) { + const handler = new TextRollAlchimie(context) + context.text = await handler.replaceManipulationAlchimie() + } + + constructor(context) { + this.context = context + } + + async replaceManipulationAlchimie() { + await XRegExp.forEach(this.context.text, XREGEXP_ROLL_ALCHIMIE, async (rollMatch, i) => await this._replaceOneAlchimie(rollMatch, i)) + await XRegExp.forEach(this.context.text, XREGEXP_ROLL_ALCHIMIE_MANIP, async (rollMatch, i) => await this._replaceOneAlchimie(rollMatch, i)) + return this.context.text + } + + async _replaceOneAlchimie(rollMatch, i) { + if (rollMatch.termes && rollMatch.manip) { + const manip = rollMatch.manip + await this._replaceManip(manip, rollMatch, i) + } + } + + async _replaceManip(manip, rollMatch, i) { + const termes = rollMatch.termes + const carac = RdDCarac.caracDetails(RdDAlchimie.getCaracTache(manip)) + const diff = RdDAlchimie.getDifficulte(termes) + const recette = (this.context.object instanceof Item && this.context.object.type == ITEM_TYPES.recettealchimique) ? this.context.object : undefined + const replacement = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/apps/link-text-roll-alchimie.hbs`, { + manip, + termes, + recette, + carac, + diff + }) + this.context.text = this.context.text.replace(rollMatch[0], replacement); + } +} + /** * classe pour gérer les jets de caractéristique/compétence depuis * les journaux/descriptions */ class TextRollCaracCompetence { - static async onReplaceRoll(context) { - const competences = await SystemCompendiums.getCompetences(ACTOR_TYPES.personnage); - const handler = new TextRollCaracCompetence(context.text, competences) - context.text = await handler.replaceRollCaracCompetence() - } - static async onRollText(event, actor) { - const caracCode = event.currentTarget.attributes['data-carac-code']?.value + const caracCode = event.currentTarget.attributes['data-carac-code']?.value if (caracCode) { const competence = event.currentTarget.attributes['data-competence']?.value const diff = event.currentTarget.attributes['data-diff']?.value const actors = TextRollCaracCompetence.getSelectedActors(actor) - actors.forEach(it => TextRollCaracCompetence.doRoll(it, caracCode, competence, diff)) + actors.forEach(async it => await TextRollCaracCompetence.doRoll(it, caracCode, competence, diff)) } } static async doRoll(actor, caracCode, competence, diff) { caracCode = actor.mapCarac(caracCode) if (competence) { if (actor.type == ACTOR_TYPES.personnage) { - actor.rollCaracCompetence(caracCode, competence, diff) + await actor.rollCaracCompetence(caracCode, competence, diff) } else { - actor.doRollCaracCompetence(caracCode, competence, diff) + await actor.doRollCaracCompetence(caracCode, competence, diff) } } else { - actor.rollCarac(caracCode, { diff }) + await actor.rollCarac(caracCode, { diff }) } } + static async onReplaceRoll(context) { + const handler = new TextRollCaracCompetence(context) + context.text = await handler.replaceRollCaracCompetence() + } + static getSelectedActors(actor) { const selected = canvas.tokens.controlled.map(it => it.actor).filter(it => it) if (selected.length > 0) { @@ -59,30 +133,32 @@ class TextRollCaracCompetence { return [] } - constructor(text, competences) { - this.text = text - this.competences = competences + constructor(context) { + this.context = context } async replaceRollCaracCompetence() { - await XRegExp.forEach(this.text, XREGEXP_ROLL_CARAC_COMP, async (rollMatch, i) => await this._replaceOne(rollMatch, i)) - return this.text + await XRegExp.forEach(this.context.text, XREGEXP_ROLL_CARAC_COMP, async (rollMatch, i) => await this._replaceOne(rollMatch, i)) + return this.context.text } async _replaceOne(rollMatch, i) { const carac = RdDCarac.caracDetails(rollMatch.carac) if (carac) { - const competence = rollMatch.competence ? RdDItemCompetence.findCompetence(this.competences, rollMatch.competence) : undefined + const competence = rollMatch.competence ? RdDItemCompetence.findCompetence(this.context.competences, rollMatch.competence) : undefined const replacement = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/apps/link-text-roll-carac-competence.hbs`, { carac: carac, competence: competence?.name, diff: rollMatch.diff }) - this.text = this.text.replace(rollMatch[0], replacement) + this.context.text = this.context.text.replace(rollMatch[0], replacement) } } } +/** + * classe pour gérer les jets de dés (formules Foundry) + */ class TextRollFoundry { static async onReplaceRoll(context) { @@ -118,11 +194,12 @@ class TextRollFoundry { } } - export class RdDTextEditor { static async enrichHTML(text, object) { - const context = { text } + const competences = await SystemCompendiums.getCompetences(ACTOR_TYPES.personnage); + const context = { text, competences, object } + await TextRollAlchimie.onReplaceRoll(context) await TextRollCaracCompetence.onReplaceRoll(context) await TextRollFoundry.onReplaceRoll(context) return await TextEditor.enrichHTML(context.text, { @@ -133,8 +210,15 @@ export class RdDTextEditor { } static async rollText(event, actor) { - await TextRollCaracCompetence.onRollText(event, actor) - await TextRollFoundry.onRollText(event, actor) + const rollMode = event.currentTarget.attributes['data-roll-mode']?.value; + switch (rollMode) { + case 'foundry': + return await TextRollFoundry.onRollText(event, actor) + case 'carac': + return await TextRollCaracCompetence.onRollText(event, actor) + case 'alchimie': + return await TextRollAlchimie.onRollText(event, actor) + } } } \ No newline at end of file diff --git a/module/item-sheet.js b/module/item-sheet.js index 13cf5e91..4fe2838d 100644 --- a/module/item-sheet.js +++ b/module/item-sheet.js @@ -1,6 +1,5 @@ import { RdDItemSort } from "./item-sort.js"; import { RdDUtility } from "./rdd-utility.js"; -import { RdDAlchimie } from "./rdd-alchimie.js"; import { RdDItemCompetence } from "./item-competence.js"; import { RdDHerbes } from "./rdd-herbes.js"; import { RdDGemme } from "./rdd-gemme.js"; @@ -128,8 +127,7 @@ export class RdDItemSheet extends ItemSheet { formData.texte = await RdDTextEditor.enrichHTML(this.item.system.texte, this.item) } if (this.item.type == ITEM_TYPES.recettealchimique) { - const manipulation = RdDAlchimie.processManipulation(this.item, this.actor?.id); - formData.manipulation = await RdDTextEditor.enrichHTML(manipulation, this.item) + formData.manipulation = await RdDTextEditor.enrichHTML(this.item.system.manipulation, this.item) formData.utilisation = await RdDTextEditor.enrichHTML(this.item.system.utilisation, this.item) formData.enchantement = await RdDTextEditor.enrichHTML(this.item.system.enchantement, this.item) formData.sureffet = await RdDTextEditor.enrichHTML(this.item.system.sureffet, this.item) @@ -209,17 +207,6 @@ export class RdDItemSheet extends ItemSheet { this.html.find('input[name="system.cacher_points_de_tache"]').change(async event => await this.item.update({ 'system.cacher_points_de_tache': event.currentTarget.checked })); this.html.find('.roll-text').click(async event => await RdDTextEditor.rollText(event, this.actor)) - this.html.find('.alchimie-tache a').click((event) => { - let actor = this._getEventActor(event); - if (actor) { - let recetteId = event.currentTarget.attributes['data-recette-id'].value; - let tacheName = event.currentTarget.attributes['data-alchimie-tache'].value; - let tacheData = event.currentTarget.attributes['data-alchimie-data'].value; - actor.effectuerTacheAlchimie(recetteId, tacheName, tacheData); - } else { - ui.notifications.info("Impossible trouver un acteur pour réaliser cette tache Alchimique."); - } - }); if (this.actor) { this.html.find('.item-split').click(async event => RdDSheetUtility.splitItem(RdDSheetUtility.getItem(event, this.actor), this.actor, this.getActionRenderItem())); diff --git a/module/rdd-alchimie.js b/module/rdd-alchimie.js index 678f6295..66bb6ec3 100644 --- a/module/rdd-alchimie.js +++ b/module/rdd-alchimie.js @@ -1,48 +1,8 @@ -/* -------------------------------------------- */ import { Misc } from "./misc.js"; -const matchOperations = new RegExp(/@(\w*){([\w\-]+)}/ig); -const matchOperationTerms = new RegExp(/@(\w*){([\w\-]+)}/i); -/* -------------------------------------------- */ export class RdDAlchimie { - - /* -------------------------------------------- */ - static processManipulation(recette, actorId = undefined) { - let manip = recette.system.manipulation; - let matchArray = manip.match(matchOperations); - if (matchArray) { - for (let matchStr of matchArray) { - let result = matchStr.match(matchOperationTerms); - if (result[1] && result[2]) { - let commande = Misc.upperFirst(result[1]); - let replacement = this[`_alchimie${commande}`](recette, result[2], actorId); - manip = manip.replace(result[0], replacement); - } - } - } - return manip; - } - - /* -------------------------------------------- */ - static _alchimieCouleur(recette, couleurs, actorId) { - return RdDAlchimie._alchimieLink(recette, couleurs, actorId, 'couleur', 'Température'); - } - - /* -------------------------------------------- */ - static _alchimieConsistance(recette, consistances, actorId) { - return RdDAlchimie._alchimieLink(recette, consistances, actorId, 'consistance', 'Consistance'); - } - - static _alchimieLink(recette, termes, actorId, tacheAlchimie, labelTache) { - const difficulte = RdDAlchimie.getDifficulte(termes); - const link = actorId ? ` ` : ''; - const endLink = actorId ? '' : ''; - return `${link}${labelTache} ${termes} (${difficulte})${endLink}`; - } - - /* -------------------------------------------- */ - static getDifficulte(aspects) { - let elements = aspects.split('-'); + static getDifficulte(termes) { + let elements = termes.split('-'); let composantes = elements.length; let distincts = Object.keys(Misc.classifyFirst(elements, it => it)).length; if (distincts == 1) { @@ -58,5 +18,4 @@ export class RdDAlchimie { } return 'intellect'; } - } diff --git a/styles/simple.css b/styles/simple.css index 78b2d63e..01525844 100644 --- a/styles/simple.css +++ b/styles/simple.css @@ -1067,12 +1067,13 @@ li label.compteur { max-width: 90%; } -.alchimie-tache { +a.roll-text.content-link { + color: hsla(300, 70%, 40%, 0.5); font-weight: bold; - background: rgb(182, 180, 179); - border: 1px solid rgba(72, 46, 28, 1); + border: 1px solid var(--color-border-dark-tertiary); border-radius: 0.25rem; - color: rgba(212, 27, 27, 0.5); + white-space: nowrap; + word-break: break-all; } .window-app.sheet .window-content .tooltip:hover .tooltiptext { diff --git a/templates/apps/link-text-roll-alchimie.hbs b/templates/apps/link-text-roll-alchimie.hbs new file mode 100644 index 00000000..e52fd8d3 --- /dev/null +++ b/templates/apps/link-text-roll-alchimie.hbs @@ -0,0 +1,8 @@ + +{{~manip}} {{termes~}} + diff --git a/templates/apps/link-text-roll-carac-competence.hbs b/templates/apps/link-text-roll-carac-competence.hbs index 93652db1..e692ad4e 100644 --- a/templates/apps/link-text-roll-carac-competence.hbs +++ b/templates/apps/link-text-roll-carac-competence.hbs @@ -1,4 +1,5 @@ diff --git a/templates/apps/link-text-roll-foundry.hbs b/templates/apps/link-text-roll-foundry.hbs index 7902ab20..2d12f06b 100644 --- a/templates/apps/link-text-roll-foundry.hbs +++ b/templates/apps/link-text-roll-foundry.hbs @@ -1,3 +1,5 @@ - + {{~formula~}}