Rip out the _preUpdate handling, it's complicated and messy to maintain
This commit is contained in:
parent
7970cb64c8
commit
5073c972e8
3 changed files with 63 additions and 66 deletions
|
|
@ -1,8 +1,4 @@
|
||||||
import { __ID__ } from "../../consts.mjs";
|
import { __ID__ } from "../../consts.mjs";
|
||||||
import { Logger } from "../../utils/Logger.mjs";
|
|
||||||
import { EphemeralObjectField } from "../fields/EphemeralObjectField.mjs";
|
|
||||||
|
|
||||||
const { getProperty, hasProperty } = foundry.utils;
|
|
||||||
|
|
||||||
export class PlayerData extends foundry.abstract.TypeDataModel {
|
export class PlayerData extends foundry.abstract.TypeDataModel {
|
||||||
// #region Schema
|
// #region Schema
|
||||||
|
|
@ -19,7 +15,7 @@ export class PlayerData extends foundry.abstract.TypeDataModel {
|
||||||
nullable: true,
|
nullable: true,
|
||||||
initial: null,
|
initial: null,
|
||||||
}),
|
}),
|
||||||
attr: new EphemeralObjectField({ initial: {} }),
|
attr: new fields.ObjectField({ persisted: false, initial: {} }),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
// #endregion Schema
|
// #endregion Schema
|
||||||
|
|
@ -42,14 +38,6 @@ export class PlayerData extends foundry.abstract.TypeDataModel {
|
||||||
return super._preCreate(data, options, user);
|
return super._preCreate(data, options, user);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Ensures that the required data structures exist in order for the
|
|
||||||
* derived data to be able to populate itself correctly.
|
|
||||||
*/
|
|
||||||
prepareBaseData() {
|
|
||||||
this.attr = {};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For every attribute item that the character has, we want that data
|
* For every attribute item that the character has, we want that data
|
||||||
* accessible in the system data, so we create objects dynamically that
|
* accessible in the system data, so we create objects dynamically that
|
||||||
|
|
@ -69,29 +57,6 @@ export class PlayerData extends foundry.abstract.TypeDataModel {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* This handler makes it so that when a user updates the attributes
|
|
||||||
* using a "system.attr.*" property they correctly get removed from the
|
|
||||||
* update and are forwarded to the correct Item document instead
|
|
||||||
*/
|
|
||||||
async _preUpdate(data, options, user) {
|
|
||||||
if (hasProperty(data, `system.attr`)) {
|
|
||||||
Logger.info(`Forwarding attribute update(s) to embedded Item(s)`);
|
|
||||||
const items = this.parent.itemTypes?.attribute ?? [];
|
|
||||||
for (const attr of items) {
|
|
||||||
const key = `system.attr.${attr.system.key}`;
|
|
||||||
if (hasProperty(data, key)) {
|
|
||||||
let value = getProperty(data, key);
|
|
||||||
if (attr.system.isRange) {
|
|
||||||
attr.update({ system: value });
|
|
||||||
} else {
|
|
||||||
attr.update({ system: { value }});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
// #endregion Lifecycle
|
// #endregion Lifecycle
|
||||||
|
|
||||||
// #region Getters
|
// #region Getters
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { __ID__ } from "../consts.mjs";
|
import { __ID__ } from "../consts.mjs";
|
||||||
|
import { clamp } from "../utils/clamp.mjs";
|
||||||
|
|
||||||
const { Actor } = foundry.documents;
|
const { Actor } = foundry.documents;
|
||||||
const { deepClone, setProperty } = foundry.utils;
|
const { deepClone, setProperty } = foundry.utils;
|
||||||
|
|
@ -28,7 +29,30 @@ export class TAFActor extends Actor {
|
||||||
// #endregion Lifecycle
|
// #endregion Lifecycle
|
||||||
|
|
||||||
// #region Token Attributes
|
// #region Token Attributes
|
||||||
|
/**
|
||||||
|
* @override
|
||||||
|
* This override exists in order to support making updates to the Actor's
|
||||||
|
* embedded attribute Items from the token, or falling back to the default
|
||||||
|
* handling if it's not one of our attributes.
|
||||||
|
*/
|
||||||
async modifyTokenAttribute(attribute, value, isDelta = false, isBar = true) {
|
async modifyTokenAttribute(attribute, value, isDelta = false, isBar = true) {
|
||||||
|
if (attribute.startsWith(`attr.`)) {
|
||||||
|
const key = attribute.slice(5);
|
||||||
|
const attr = this.getAttribute(key);
|
||||||
|
value = isDelta ? attr.system.value + value : value;
|
||||||
|
value = clamp(attr.system.min, value, attr.system.max);
|
||||||
|
const updates = { system: { value } };
|
||||||
|
|
||||||
|
const allowed = Hooks.call(
|
||||||
|
`modifyTokenAttribute`,
|
||||||
|
{ attribute, value, isDelta, isBar, isEmbedded: true },
|
||||||
|
updates,
|
||||||
|
this
|
||||||
|
);
|
||||||
|
|
||||||
|
return allowed !== false ? await attr.update(updates) : this;
|
||||||
|
};
|
||||||
|
|
||||||
const attr = foundry.utils.getProperty(this.system, attribute);
|
const attr = foundry.utils.getProperty(this.system, attribute);
|
||||||
const current = isBar ? attr.value : attr;
|
const current = isBar ? attr.value : attr;
|
||||||
const update = isDelta ? current + value : value;
|
const update = isDelta ? current + value : value;
|
||||||
|
|
@ -36,18 +60,7 @@ export class TAFActor extends Actor {
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Determine the updates to make to the actor data
|
return super.modifyTokenAttribute(attribute, value, isDelta, isBar);
|
||||||
let updates;
|
|
||||||
if (isBar) {
|
|
||||||
updates = {[`system.${attribute}.value`]: Math.clamp(update, 0, attr.max)};
|
|
||||||
} else {
|
|
||||||
updates = {[`system.${attribute}`]: update};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Allow a hook to override these changes
|
|
||||||
const allowed = Hooks.call(`modifyTokenAttribute`, {attribute, value, isDelta, isBar}, updates, this);
|
|
||||||
|
|
||||||
return allowed !== false ? this.update(updates) : this;
|
|
||||||
};
|
};
|
||||||
// #endregion Token Attributes
|
// #endregion Token Attributes
|
||||||
|
|
||||||
|
|
@ -80,8 +93,15 @@ export class TAFActor extends Actor {
|
||||||
};
|
};
|
||||||
// #endregion Roll Data
|
// #endregion Roll Data
|
||||||
|
|
||||||
// #region Getters
|
// #region Methods
|
||||||
#sortedTypes = null;
|
#sortedTypes = null;
|
||||||
|
/**
|
||||||
|
* @override
|
||||||
|
* This override is intended to allow the "generic" item subtype to instead
|
||||||
|
* populate the Item types based on their "Group" property, for any other item
|
||||||
|
* subtype this function operates the same way that the default Foundry
|
||||||
|
* implementation does.
|
||||||
|
*/
|
||||||
get itemTypes() {
|
get itemTypes() {
|
||||||
if (this.#sortedTypes) { return this.#sortedTypes };
|
if (this.#sortedTypes) { return this.#sortedTypes };
|
||||||
const types = {};
|
const types = {};
|
||||||
|
|
@ -97,7 +117,29 @@ export class TAFActor extends Actor {
|
||||||
};
|
};
|
||||||
return this.#sortedTypes = types;
|
return this.#sortedTypes = types;
|
||||||
};
|
};
|
||||||
// #endregion Getters
|
|
||||||
|
/**
|
||||||
|
* Retrieves an attribute Item from the actor, used to more easily
|
||||||
|
*
|
||||||
|
* @param {string} key The unique identifier of the attribute
|
||||||
|
* @returns The attribute's Item document, or undefined if not found
|
||||||
|
*/
|
||||||
|
getAttribute(key) {
|
||||||
|
const attrs = this.itemTypes.attribute ?? [];
|
||||||
|
return attrs.find(attr => attr.system.key === key);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an embedded attribute Item with a new value.
|
||||||
|
*
|
||||||
|
* @param {string} key The unique identifier of the attribute
|
||||||
|
* @param {number} value The value to set the attribute to
|
||||||
|
*/
|
||||||
|
async setAttributeValue(key, value) {
|
||||||
|
const item = this.getAttribute(key);
|
||||||
|
await item?.update({system: { value }});
|
||||||
|
};
|
||||||
|
// #endregion Methods
|
||||||
|
|
||||||
// #region Data Migration
|
// #region Data Migration
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -83,8 +83,6 @@ export class TAFTokenDocument extends TokenDocument {
|
||||||
|
|
||||||
if (`value` in data && `max` in data) {
|
if (`value` in data && `max` in data) {
|
||||||
let editable = hasProperty(system, `${attribute}.value`);
|
let editable = hasProperty(system, `${attribute}.value`);
|
||||||
const isRange = getProperty(system, `${attribute}.isRange`);
|
|
||||||
if (isRange) {
|
|
||||||
return {
|
return {
|
||||||
type: `bar`,
|
type: `bar`,
|
||||||
attribute,
|
attribute,
|
||||||
|
|
@ -92,14 +90,6 @@ export class TAFTokenDocument extends TokenDocument {
|
||||||
max: parseInt(data.max || 0),
|
max: parseInt(data.max || 0),
|
||||||
editable,
|
editable,
|
||||||
};
|
};
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
type: `value`,
|
|
||||||
attribute: `${attribute}.value`,
|
|
||||||
value: Number(data.value),
|
|
||||||
editable,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Otherwise null
|
// Otherwise null
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue