90 lines
2.4 KiB
JavaScript
90 lines
2.4 KiB
JavaScript
import { toPrecision } from "../../utils/roundToPrecision.mjs";
|
|
|
|
export class GenericItemData extends foundry.abstract.TypeDataModel {
|
|
// MARK: Schema
|
|
static defineSchema() {
|
|
const fields = foundry.data.fields;
|
|
return {
|
|
group: new fields.StringField({
|
|
blank: false,
|
|
trim: true,
|
|
initial: null,
|
|
nullable: true,
|
|
}),
|
|
weight: new fields.NumberField({
|
|
min: 0,
|
|
initial: 0,
|
|
nullable: false,
|
|
}),
|
|
quantity: new fields.NumberField({
|
|
integer: true,
|
|
initial: 1,
|
|
}),
|
|
equipped: new fields.BooleanField({
|
|
initial: true,
|
|
}),
|
|
trigger: new fields.DocumentUUIDField({
|
|
embedded: false,
|
|
relative: false,
|
|
type: foundry.documents.Macro.documentName,
|
|
}),
|
|
description: new fields.HTMLField({
|
|
blank: true,
|
|
trim: true,
|
|
initial: ``,
|
|
}),
|
|
};
|
|
};
|
|
|
|
// #region Methods
|
|
/**
|
|
* Calculates the total weight of the item based on the quantity of it, this
|
|
* rounds the number to the nearest 2 decimal places.
|
|
*/
|
|
get quantifiedWeight() {
|
|
const value = this.weight * this.quantity;
|
|
return toPrecision(Math.max(value, 0), 2);
|
|
};
|
|
|
|
/**
|
|
* Executes the macro associated with this item, if the macro cannot be
|
|
* found or if the user does not permission to execute it, it will not be
|
|
* executed. This also provides some extra context into the roll data for chat
|
|
* macros, so that they can refer to some properties of this specific item
|
|
* without actually needing to know which item called the macro.
|
|
*/
|
|
async execute() {
|
|
const macro = await fromUuid(this.trigger);
|
|
if (!macro || !macro.canExecute) { return };
|
|
|
|
// Provide the chat-specific context when required
|
|
if (macro.type === `chat`) {
|
|
const extraContext = {
|
|
name: this.parent.name,
|
|
quantity: this.quantity,
|
|
equipped: this.equipped ? 1 : 0,
|
|
};
|
|
|
|
Hooks.once(`taf.getRollData`, (data) => {
|
|
data.active = extraContext;
|
|
});
|
|
|
|
// Apply any roll data additions to the message flavour as well
|
|
// since that doesn't get formatted by the ChatLog
|
|
Hooks.once(`preCreateChatMessage`, (message) => {
|
|
if (message.flavor.includes(`@active`)) {
|
|
const flavor = message.flavor.replaceAll(
|
|
/@active\.(\w+)/g,
|
|
(fullMatch, key) => {
|
|
return extraContext[key] || fullMatch;
|
|
},
|
|
);
|
|
message.updateSource({ flavor });
|
|
};
|
|
});
|
|
};
|
|
|
|
await macro?.execute({ item: this.parent });
|
|
};
|
|
// #endregion Methods
|
|
};
|