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, 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') 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 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 actors = TextRollCaracCompetence.getSelectedActors(actor) 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) { await actor.rollCaracCompetence(caracCode, competence, diff) } else { await actor.doRollCaracCompetence(caracCode, competence, diff) } } else { 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) { return selected } actor = actor ?? RdDUtility.getSelectedActor() if (actor) { return [actor] } return [] } constructor(context) { this.context = context } async replaceRollCaracCompetence() { 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.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.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) { 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 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, { relativeTo: object, secrets: object?.isOwner, async: true }) } static async rollText(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) } } }