diff --git a/src/module/actor/actor-prepared-data.ts b/src/module/actor/actor-prepared-data.ts index ab231637..5dd3ec59 100644 --- a/src/module/actor/actor-prepared-data.ts +++ b/src/module/actor/actor-prepared-data.ts @@ -23,6 +23,7 @@ interface DS4ActorPreparedDataDataBase { combatValues: DS4ActorPreparedDataDataCombatValues; rolling: DS4ActorPreparedDataDataRolling; checks: DS4ActorPreparedDataDataChecks; + customChecks: DS4ActorPreparedDataDataCustomChecks; } interface DS4ActorPreparedDataDataAttributes { @@ -66,6 +67,8 @@ type DS4ActorPreparedDataDataChecks = { [key in Check]: number; }; +type DS4ActorPreparedDataDataCustomChecks = Record; + // types interface DS4CharacterPreparedDataData extends DS4ActorPreparedDataDataBase { diff --git a/src/module/actor/actor.ts b/src/module/actor/actor.ts index 1bb05a07..3aea5317 100644 --- a/src/module/actor/actor.ts +++ b/src/module/actor/actor.ts @@ -110,6 +110,7 @@ export class DS4Actor extends Actor prepareDerivedData(): void { this._prepareCombatValues(); this._prepareChecks(); + this._prepareCustomChecks(); } /** @@ -122,7 +123,10 @@ export class DS4Actor extends Actor const checkProperties = Object.keys(DS4.i18n.checks) .filter((check) => check !== "defend") .map((check) => `data.checks.${check}`); - return combatValueProperties.concat(checkProperties); + const customCheckProperties = Object.keys(game.settings.get("ds4", "customChecks")).map( + (check) => `data.customChecks.${check}`, + ); + return combatValueProperties.concat(checkProperties).concat(customCheckProperties); } /** @@ -251,6 +255,25 @@ export class DS4Actor extends Actor }; } + protected _prepareCustomChecks(): void { + const customChecksSettings = game.settings.get("ds4", "customChecks"); + const data = this.data.data; + data.customChecks = {}; + Object.entries(customChecksSettings).forEach(([identifier, check]) => { + const replacedFormula = this._replaceFormulaData(check.formula); + console.log(replacedFormula); + data.customChecks[identifier] = Roll.MATH_PROXY.safeEval(replacedFormula); + }); + } + + protected _replaceFormulaData(formula: string): string { + const dataRgx = new RegExp(/@([a-z.0-9_\-]+)/gi); + return formula.replace(dataRgx, (match, term) => { + const value = getProperty(this.data, term); + return value !== undefined ? String(value).trim() : match; + }); + } + /** * Handle how changes to a Token attribute bar are applied to the Actor. * This only differs from the base implementation by also allowing negative values. diff --git a/src/module/global.d.ts b/src/module/global.d.ts index c560d623..4a81cb10 100644 --- a/src/module/global.d.ts +++ b/src/module/global.d.ts @@ -2,5 +2,6 @@ declare namespace ClientSettings { interface Values { "ds4.systemMigrationVersion": number; "ds4.useSlayingDiceForAutomatedChecks": boolean; + "ds4.customChecks": Record; } } diff --git a/src/module/settings.ts b/src/module/settings.ts index 938be7c0..954baa9a 100644 --- a/src/module/settings.ts +++ b/src/module/settings.ts @@ -18,4 +18,14 @@ export function registerSystemSettings(): void { type: Boolean, default: false, }); + + game.settings.register("ds4", "customChecks", { + name: "DS4.SettingsCustomChecks", + scope: "world", + config: false, + // eslint-disable-next-line + //@ts-ignore + type: Object, + default: {}, + }); } diff --git a/src/templates/sheets/actor/components/checks.hbs b/src/templates/sheets/actor/components/checks.hbs index e10f6712..05d58a23 100644 --- a/src/templates/sheets/actor/components/checks.hbs +++ b/src/templates/sheets/actor/components/checks.hbs @@ -3,4 +3,8 @@ {{> systems/ds4/templates/sheets/actor/components/check.hbs check-key=check-key check-target-number=(lookup ../data.checks check-key) check-label=check-label}} {{/each}} + {{#each data.customChecks as |check-target-number check-key|}} + {{> systems/ds4/templates/sheets/actor/components/check.hbs check-key=check-key + check-target-number=check-target-number check-label=check-key}} + {{/each}}