108 lines
3 KiB
JavaScript
108 lines
3 KiB
JavaScript
import { __ID__ } from "../consts.mjs";
|
|
|
|
const { Actor } = foundry.documents;
|
|
const { hasProperty } = foundry.utils;
|
|
|
|
export class TAFActor extends Actor {
|
|
|
|
// #region Lifecycle
|
|
/**
|
|
* This makes sure that the actor gets created with the global attributes if
|
|
* they exist, while still allowing programmatic creation through the API with
|
|
* specific attributes.
|
|
*/
|
|
async _preCreate(data, options, user) {
|
|
|
|
// Assign the defaults from the world setting if they exist
|
|
const defaults = game.settings.get(__ID__, `actorDefaultAttributes`) ?? {};
|
|
if (!hasProperty(data, `system.attr`)) {
|
|
const value = game.release.generation > 13 ? _replace(defaults) : defaults;
|
|
this.updateSource({ "system.==attr": value });
|
|
};
|
|
|
|
return super._preCreate(data, options, user);
|
|
};
|
|
|
|
/**
|
|
* This resets the cache of the item groupings whenever a descedant document
|
|
* gets changed (created, updated, deleted) so that we keep the cache as close
|
|
* to accurate as can be possible.
|
|
*/
|
|
_onEmbeddedDocumentChange(...args) {
|
|
super._onEmbeddedDocumentChange(...args);
|
|
this.#sortedTypes = null;
|
|
};
|
|
// #endregion Lifecycle
|
|
|
|
// #region Token Attributes
|
|
async modifyTokenAttribute(attribute, value, isDelta = false, isBar = true) {
|
|
const attr = foundry.utils.getProperty(this.system, attribute);
|
|
const current = isBar ? attr.value : attr;
|
|
const update = isDelta ? current + value : value;
|
|
if ( update === current ) {
|
|
return this;
|
|
};
|
|
|
|
// Determine the updates to make to the actor data
|
|
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
|
|
|
|
// #region Roll Data
|
|
getRollData() {
|
|
/*
|
|
All properties assigned during this phase of the roll data prep can potentially
|
|
be overridden by users creating attributes of the same key, if users shouldn't
|
|
be able to override, assign the property before the return of this function.
|
|
*/
|
|
const data = {
|
|
carryCapacity: this.system.carryCapacity ?? null,
|
|
};
|
|
|
|
if (`attr` in this.system) {
|
|
for (const attrID in this.system.attr) {
|
|
const attr = this.system.attr[attrID];
|
|
if (attr.isRange) {
|
|
data[attrID] = {
|
|
value: attr.value,
|
|
max: attr.max,
|
|
};
|
|
} else {
|
|
data[attrID] = attr.value;
|
|
};
|
|
};
|
|
};
|
|
|
|
return data;
|
|
};
|
|
// #endregion Roll Data
|
|
|
|
// #region Getters
|
|
#sortedTypes = null;
|
|
get itemTypes() {
|
|
if (this.#sortedTypes) return this.#sortedTypes;
|
|
const types = {};
|
|
for (const item of this.items) {
|
|
if (item.type !== `generic`) {
|
|
types[item.type] ??= [];
|
|
types[item.type].push(item);
|
|
} else {
|
|
const group = item.system.group?.toLowerCase() ?? `items`;
|
|
types[group] ??= [];
|
|
types[group].push(item);
|
|
};
|
|
};
|
|
return this.#sortedTypes = types;
|
|
};
|
|
// #endregion Getters
|
|
};
|