mirror of
https://github.com/RoY7x/worldbuilding.git
synced 2025-04-30 02:31:41 -04:00
8: Refactor formula attributes
- Divided getRollData() into several helper methods to make it more organized. - Cleaned up usage of shorthand checks, but haven't entirely consolidated them yet. There's room to improve this, but further consolidation would likely require a regex to handle mapping inline roll syntax in the formulas to use the `@attr.KEY.value` format when `@KEY` is detected. This seemed like a solid compromise for now. - Refactored the _replaceData() helper method to match the Roll class' upcoming syntax, and added TODO comments to replace them once it's ready.
This commit is contained in:
parent
7c676b14ee
commit
00dfec6014
1 changed files with 111 additions and 85 deletions
196
module/actor.js
196
module/actor.js
|
@ -10,95 +10,130 @@ export class SimpleActor extends Actor {
|
||||||
const shorthand = game.settings.get("worldbuilding", "macroShorthand");
|
const shorthand = game.settings.get("worldbuilding", "macroShorthand");
|
||||||
const formulaAttributes = [];
|
const formulaAttributes = [];
|
||||||
|
|
||||||
// Re-map all attributes onto the base roll data
|
|
||||||
if ( !!shorthand ) {
|
|
||||||
for ( let [k, v] of Object.entries(data.attributes) ) {
|
|
||||||
if ( !(k in data) ) {
|
|
||||||
data[k] = v.value;
|
|
||||||
// Make an array of formula attributes for later reference.
|
|
||||||
if ( v.dtype == "Formula" ) formulaAttributes.push(k);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete data.attributes;
|
|
||||||
}
|
|
||||||
// Handle formula attributes when the short syntax is disabled.
|
// Handle formula attributes when the short syntax is disabled.
|
||||||
else {
|
this._applyShorthand(data, formulaAttributes, shorthand);
|
||||||
for ( let [k, v] of Object.entries(data.attributes) ) {
|
|
||||||
// Make an array of formula attributes for later reference.
|
|
||||||
if ( v.dtype == "Formula" ) formulaAttributes.push(k);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Map all items data using their slugified names
|
// Map all items data using their slugified names
|
||||||
data.items = this.data.items.reduce((obj, i) => {
|
this._applyItems(data, shorthand);
|
||||||
let key = i.name.slugify({strict: true});
|
|
||||||
let itemData = duplicate(i.data);
|
|
||||||
const itemAttributes = [];
|
|
||||||
|
|
||||||
// Add items as shorthand.
|
|
||||||
if ( !!shorthand ) {
|
|
||||||
for ( let [k, v] of Object.entries(itemData.attributes) ) {
|
|
||||||
if ( !(k in itemData) ) {
|
|
||||||
itemData[k] = v.value;
|
|
||||||
if ( v.dtype == "Formula" ) itemAttributes.push(k);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete itemData["attributes"];
|
|
||||||
}
|
|
||||||
// Add formula items when shorthand isn't enabled.
|
|
||||||
else {
|
|
||||||
for ( let [k, v] of Object.entries(itemData.attributes) ) {
|
|
||||||
if ( v.dtype == "Formula" ) itemAttributes.push(k);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate formula attributes after all other attributes have been handled.
|
|
||||||
for ( let k of itemAttributes ) {
|
|
||||||
// Shorthand.
|
|
||||||
if ( !!shorthand ) {
|
|
||||||
if ( itemData[k] ) {
|
|
||||||
itemData[k] = this._replaceData(itemData[k], itemData, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Full syntax.
|
|
||||||
else {
|
|
||||||
if ( itemData.attributes[k].value ) {
|
|
||||||
itemData.attributes[k].value = this._replaceData(itemData.attributes[k].value, itemData, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
obj[key] = itemData;
|
|
||||||
return obj;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
// Evaluate formula attributes after all other attributes have been handled,
|
// Evaluate formula attributes after all other attributes have been handled,
|
||||||
// including items.
|
// including items.
|
||||||
for ( let k of formulaAttributes ) {
|
this._applyFormulaReplacements(data, formulaAttributes, shorthand);
|
||||||
// Shorthand.
|
|
||||||
if ( !!shorthand ) {
|
// Remove the attributes if necessary.
|
||||||
if ( data[k] ) {
|
if ( !!shorthand ) {
|
||||||
data[k] = this._replaceData(data[k], data);
|
delete data.attributes;
|
||||||
}
|
delete data.attr;
|
||||||
}
|
delete data.abil;
|
||||||
// Full syntax.
|
|
||||||
else {
|
|
||||||
if ( data.attributes[k].value ) {
|
|
||||||
data.attributes[k].value = this._replaceData(data.attributes[k].value, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply shorthand syntax to actor roll data.
|
||||||
|
* @param {Object} data The actor's data object.
|
||||||
|
* @param {Array} formulaAttributes Array of attributes that are derived formulas.
|
||||||
|
* @param {Boolean} shorthand Whether or not the shorthand syntax is used.
|
||||||
|
*/
|
||||||
|
_applyShorthand(data, formulaAttributes, shorthand) {
|
||||||
|
// Handle formula attributes when the short syntax is disabled.
|
||||||
|
for ( let [k, v] of Object.entries(data.attributes) ) {
|
||||||
|
// Make an array of formula attributes for later reference.
|
||||||
|
if ( v.dtype == "Formula" ) formulaAttributes.push(k);
|
||||||
|
// Add shortened version of the attributes.
|
||||||
|
if ( !!shorthand ) {
|
||||||
|
if ( !(k in data) ) {
|
||||||
|
data[k] = v.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add items to the actor roll data object. Handles regular and shorthand
|
||||||
|
* syntax, and calculates derived formula attributes on the items.
|
||||||
|
* @param {Object} data The actor's data object.
|
||||||
|
* @param {Boolean} shorthand Whether or not the shorthand syntax is used.
|
||||||
|
*/
|
||||||
|
_applyItems(data, shorthand) {
|
||||||
|
// Map all items data using their slugified names
|
||||||
|
data.items = this.data.items.reduce((obj, i) => {
|
||||||
|
let key = i.name.slugify({strict: true});
|
||||||
|
let itemData = duplicate(i.data);
|
||||||
|
const itemAttributes = [];
|
||||||
|
|
||||||
|
// Add items to shorthand and note which ones are formula attributes.
|
||||||
|
for ( let [k, v] of Object.entries(itemData.attributes) ) {
|
||||||
|
if ( v.dtype == "Formula" ) itemAttributes.push(k);
|
||||||
|
// Add shortened version of the attributes.
|
||||||
|
if ( !!shorthand ) {
|
||||||
|
if ( !(k in itemData) ) {
|
||||||
|
itemData[k] = v.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate formula attributes after all other attributes have been handled.
|
||||||
|
for ( let k of itemAttributes ) {
|
||||||
|
if ( itemData.attributes[k].value ) {
|
||||||
|
itemData.attributes[k].value = this._replaceData(itemData.attributes[k].value, itemData);
|
||||||
|
itemData.attributes[k].value = this._replaceData(itemData.attributes[k].value, data, {missing: "0"});
|
||||||
|
// TODO: Replace with:
|
||||||
|
// itemData.attributes[k].value = Roll.replaceFormulaData(itemData.attributes[k].value, itemData);
|
||||||
|
// itemData.attributes[k].value = Roll.replaceFormulaData(itemData.attributes[k].value, data, {missing: "0"});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Duplicate values to shorthand.
|
||||||
|
if ( !!shorthand ) {
|
||||||
|
itemData[k] = itemData.attributes[k].value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the original attributes key if using the shorthand syntax.
|
||||||
|
if ( !!shorthand ) {
|
||||||
|
delete itemData.attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj[key] = itemData;
|
||||||
|
return obj;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply replacements for derived formula attributes.
|
||||||
|
* @param {Object} data The actor's data object.
|
||||||
|
* @param {Array} formulaAttributes Array of attributes that are derived formulas.
|
||||||
|
* @param {Boolean} shorthand Whether or not the shorthand syntax is used.
|
||||||
|
*/
|
||||||
|
_applyFormulaReplacements(data, formulaAttributes, shorthand) {
|
||||||
|
// Evaluate formula attributes after all other attributes have been handled,
|
||||||
|
// including items.
|
||||||
|
for ( let k of formulaAttributes ) {
|
||||||
|
if ( data.attributes[k].value ) {
|
||||||
|
data.attributes[k].value = this._replaceData(data.attributes[k].value, data, {missing: "0"});
|
||||||
|
// TODO: Replace with:
|
||||||
|
// data.attributes[k].value = Roll.replaceFormulaData(data.attributes[k].value, data, {missing: "0"});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Duplicate values to shorthand.
|
||||||
|
if ( !!shorthand ) {
|
||||||
|
data[k] = data.attributes[k].value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replace referenced data attributes in the roll formula with the syntax `@attr` with the corresponding key from
|
* Replace referenced data attributes in the roll formula with the syntax `@attr` with the corresponding key from
|
||||||
* the provided `data` object.
|
* the provided `data` object. This is a temporary helper function that will be replaced with Roll.replaceFormulaData()
|
||||||
|
* in Foundry 0.7.1.
|
||||||
|
*
|
||||||
* @param {String} formula The original formula within which to replace.
|
* @param {String} formula The original formula within which to replace.
|
||||||
|
* @param {Object} data Data object to use for value replacements.
|
||||||
|
* @param {Object} missing Value to use as missing replacements, such as {missing: "0"}.
|
||||||
* @return {String} The formula with attributes replaced with values.
|
* @return {String} The formula with attributes replaced with values.
|
||||||
*/
|
*/
|
||||||
_replaceData(formula, dataPrimary, dataSecondary = null) {
|
_replaceData(formula, data, {missing=null}={}) {
|
||||||
// Exit early if the formula is invalid.
|
// Exit early if the formula is invalid.
|
||||||
if ( typeof formula != "string" ) {
|
if ( typeof formula != "string" ) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -107,18 +142,9 @@ export class SimpleActor extends Actor {
|
||||||
// Replace attributes with their numeric equivalents.
|
// Replace attributes with their numeric equivalents.
|
||||||
let dataRgx = new RegExp(/@([a-z.0-9_\-]+)/gi);
|
let dataRgx = new RegExp(/@([a-z.0-9_\-]+)/gi);
|
||||||
let rollFormula = formula.replace(dataRgx, (match, term) => {
|
let rollFormula = formula.replace(dataRgx, (match, term) => {
|
||||||
// Try the primary data source first (ex: actor, item).
|
// Replace matches with the value, or the missing value.
|
||||||
let value = getProperty(dataPrimary, term);
|
let value = getProperty(data, term);
|
||||||
if ( value ) {
|
return value ? String(value).trim() : (missing != null ? missing : `@${term}`);
|
||||||
return String(value).trim();
|
|
||||||
}
|
|
||||||
// Try the secondary data source next (ex: actor that owns item);
|
|
||||||
else if (dataSecondary) {
|
|
||||||
value = getProperty(dataSecondary, term);
|
|
||||||
return value ? String(value).trim() : "0";
|
|
||||||
}
|
|
||||||
// Otherwise, return 0.
|
|
||||||
return "0";
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return rollFormula;
|
return rollFormula;
|
||||||
|
|
Loading…
Add table
Reference in a new issue