2025-01-11 00:44:59 +01:00
|
|
|
import "./xregexp-all.js";
|
|
|
|
import { RdDCarac } from "../rdd-carac.js";
|
|
|
|
import { SystemCompendiums } from "../settings/system-compendiums.js";
|
|
|
|
import { RdDItemCompetence } from "../item-competence.js";
|
2025-01-12 02:38:31 +01:00
|
|
|
import { ACTOR_TYPES, ITEM_TYPES } from "../item.js";
|
2025-01-11 18:59:22 +01:00
|
|
|
import { RdDUtility } from "../rdd-utility.js";
|
2025-01-12 02:38:31 +01:00
|
|
|
import { Misc } from "../misc.js";
|
|
|
|
import { RdDAlchimie } from "../rdd-alchimie.js";
|
|
|
|
|
|
|
|
const REGEX_ALCHIMIE_TERMES = "(?<termes>(\\w|-)+)"
|
|
|
|
const REGEX_ALCHIMIE_MANIP = "(?<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')
|
2025-01-11 00:44:59 +01:00
|
|
|
|
2025-01-11 17:32:43 +01:00
|
|
|
const REGEXP_ROLL_CARAC_COMP = "(?<carac>[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+)(\\/(?<competence>[A-Za-zÀ-ÖØ-öø-ÿ\\s\\-]+))?(/(?<diff>[\\+\\-]?\\d+))?"
|
|
|
|
const XREGEXP_ROLL_CARAC_COMP = XRegExp("@roll\\[" + REGEXP_ROLL_CARAC_COMP + "\\]", 'giu')
|
2025-01-11 00:44:59 +01:00
|
|
|
|
2025-01-11 17:32:43 +01:00
|
|
|
const REGEXP_ROLL_FORMULA = "(?<formula>[^\\[\\]]+)"
|
|
|
|
const XREGEXP_ROLL_FORMULA = XRegExp("@roll\\[" + REGEXP_ROLL_FORMULA + "\\]", 'giu')
|
2025-01-11 00:44:59 +01:00
|
|
|
|
2025-01-12 02:38:31 +01:00
|
|
|
|
2025-01-11 17:32:43 +01:00
|
|
|
/**
|
2025-01-12 02:38:31 +01:00
|
|
|
* classe pour gérer les jets d'alchimie
|
2025-01-11 17:32:43 +01:00
|
|
|
*/
|
2025-01-12 02:38:31 +01:00
|
|
|
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
|
|
|
|
}
|
2025-01-11 17:32:43 +01:00
|
|
|
|
|
|
|
static async onReplaceRoll(context) {
|
2025-01-12 02:38:31 +01:00
|
|
|
const handler = new TextRollAlchimie(context)
|
|
|
|
context.text = await handler.replaceManipulationAlchimie()
|
2025-01-11 00:44:59 +01:00
|
|
|
}
|
|
|
|
|
2025-01-12 02:38:31 +01:00
|
|
|
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 {
|
|
|
|
|
2025-01-11 17:32:43 +01:00
|
|
|
static async onRollText(event, actor) {
|
2025-01-12 02:38:31 +01:00
|
|
|
const caracCode = event.currentTarget.attributes['data-carac-code']?.value
|
2025-01-11 17:32:43 +01:00
|
|
|
if (caracCode) {
|
|
|
|
const competence = event.currentTarget.attributes['data-competence']?.value
|
|
|
|
const diff = event.currentTarget.attributes['data-diff']?.value
|
2025-01-11 18:59:22 +01:00
|
|
|
const actors = TextRollCaracCompetence.getSelectedActors(actor)
|
2025-01-12 02:38:31 +01:00
|
|
|
actors.forEach(async it => await TextRollCaracCompetence.doRoll(it, caracCode, competence, diff))
|
2025-01-11 00:44:59 +01:00
|
|
|
}
|
|
|
|
}
|
2025-01-11 19:29:29 +01:00
|
|
|
static async doRoll(actor, caracCode, competence, diff) {
|
2025-01-11 19:45:58 +01:00
|
|
|
caracCode = actor.mapCarac(caracCode)
|
2025-01-11 19:29:29 +01:00
|
|
|
if (competence) {
|
|
|
|
if (actor.type == ACTOR_TYPES.personnage) {
|
2025-01-12 02:38:31 +01:00
|
|
|
await actor.rollCaracCompetence(caracCode, competence, diff)
|
2025-01-11 19:29:29 +01:00
|
|
|
}
|
|
|
|
else {
|
2025-01-12 02:38:31 +01:00
|
|
|
await actor.doRollCaracCompetence(caracCode, competence, diff)
|
2025-01-11 19:29:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2025-01-12 02:38:31 +01:00
|
|
|
await actor.rollCarac(caracCode, { diff })
|
2025-01-11 19:29:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-01-12 02:38:31 +01:00
|
|
|
static async onReplaceRoll(context) {
|
|
|
|
const handler = new TextRollCaracCompetence(context)
|
|
|
|
context.text = await handler.replaceRollCaracCompetence()
|
|
|
|
}
|
|
|
|
|
2025-01-11 18:59:22 +01:00
|
|
|
static getSelectedActors(actor) {
|
|
|
|
const selected = canvas.tokens.controlled.map(it => it.actor).filter(it => it)
|
2025-01-11 19:29:29 +01:00
|
|
|
if (selected.length > 0) {
|
2025-01-11 18:59:22 +01:00
|
|
|
return selected
|
|
|
|
}
|
|
|
|
actor = actor ?? RdDUtility.getSelectedActor()
|
|
|
|
if (actor) {
|
|
|
|
return [actor]
|
|
|
|
}
|
|
|
|
return []
|
|
|
|
}
|
2025-01-11 00:44:59 +01:00
|
|
|
|
2025-01-12 02:38:31 +01:00
|
|
|
constructor(context) {
|
|
|
|
this.context = context
|
2025-01-11 17:32:43 +01:00
|
|
|
}
|
2025-01-11 00:44:59 +01:00
|
|
|
|
2025-01-11 17:32:43 +01:00
|
|
|
async replaceRollCaracCompetence() {
|
2025-01-12 02:38:31 +01:00
|
|
|
await XRegExp.forEach(this.context.text, XREGEXP_ROLL_CARAC_COMP, async (rollMatch, i) => await this._replaceOne(rollMatch, i))
|
|
|
|
return this.context.text
|
2025-01-11 17:32:43 +01:00
|
|
|
}
|
2025-01-11 00:44:59 +01:00
|
|
|
|
2025-01-11 17:32:43 +01:00
|
|
|
async _replaceOne(rollMatch, i) {
|
|
|
|
const carac = RdDCarac.caracDetails(rollMatch.carac)
|
|
|
|
if (carac) {
|
2025-01-12 02:38:31 +01:00
|
|
|
const competence = rollMatch.competence ? RdDItemCompetence.findCompetence(this.context.competences, rollMatch.competence) : undefined
|
2025-01-11 17:32:43 +01:00
|
|
|
const replacement = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/apps/link-text-roll-carac-competence.hbs`, {
|
2025-01-11 00:44:59 +01:00
|
|
|
carac: carac,
|
|
|
|
competence: competence?.name,
|
|
|
|
diff: rollMatch.diff
|
2025-01-11 17:32:43 +01:00
|
|
|
})
|
2025-01-12 02:38:31 +01:00
|
|
|
this.context.text = this.context.text.replace(rollMatch[0], replacement)
|
2025-01-11 00:44:59 +01:00
|
|
|
}
|
|
|
|
}
|
2025-01-11 17:32:43 +01:00
|
|
|
}
|
2025-01-11 00:44:59 +01:00
|
|
|
|
2025-01-12 02:38:31 +01:00
|
|
|
/**
|
|
|
|
* classe pour gérer les jets de dés (formules Foundry)
|
|
|
|
*/
|
2025-01-11 17:32:43 +01:00
|
|
|
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()
|
|
|
|
}
|
|
|
|
}
|
2025-01-11 00:44:59 +01:00
|
|
|
|
2025-01-11 17:32:43 +01:00
|
|
|
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
|
2025-01-11 00:44:59 +01:00
|
|
|
}
|
2025-01-11 17:32:43 +01:00
|
|
|
|
|
|
|
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) {
|
2025-01-12 02:38:31 +01:00
|
|
|
const competences = await SystemCompendiums.getCompetences(ACTOR_TYPES.personnage);
|
|
|
|
const context = { text, competences, object }
|
|
|
|
await TextRollAlchimie.onReplaceRoll(context)
|
2025-01-11 17:32:43 +01:00
|
|
|
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) {
|
2025-01-12 02:38:31 +01:00
|
|
|
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)
|
|
|
|
}
|
2025-01-11 17:32:43 +01:00
|
|
|
}
|
|
|
|
|
2025-01-11 00:44:59 +01:00
|
|
|
}
|