Make attributes rollable using Foundry macros
This commit is contained in:
parent
8f67bff2ec
commit
0cd8af77b2
6 changed files with 85 additions and 21 deletions
|
|
@ -37,6 +37,7 @@ export class PlayerSheet extends
|
|||
createEmbeddedItem: this.#createEmbeddedItem,
|
||||
configureSheet: this.#configureSheet,
|
||||
toggleExpand: this.#toggleExpand,
|
||||
executeTrigger: this.#executeTrigger,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -462,5 +463,16 @@ export class PlayerSheet extends
|
|||
const item = await Item.create(data, { parent: this.actor });
|
||||
item?.sheet?.render({ force: true });
|
||||
};
|
||||
|
||||
/**
|
||||
* Executes an embedded item's triggering Macro if it has one attached to it.
|
||||
*
|
||||
* @this {PlayerSheet}
|
||||
*/
|
||||
static async #executeTrigger(event, target) {
|
||||
const { itemUuid } = target.closest(`[data-item-uuid]`)?.dataset ?? {};
|
||||
const item = await fromUuid(itemUuid);
|
||||
await item?.system.execute?.();
|
||||
};
|
||||
// #endregion Actions
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { clamp } from "../../utils/clamp.mjs";
|
|||
const { getProperty, hasProperty, setProperty } = foundry.utils;
|
||||
|
||||
export class AttributeItemData extends foundry.abstract.TypeDataModel {
|
||||
// #region Schema
|
||||
// MARK: Schema
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
return {
|
||||
|
|
@ -43,7 +43,6 @@ export class AttributeItemData extends foundry.abstract.TypeDataModel {
|
|||
}),
|
||||
};
|
||||
};
|
||||
// #endregion Schema
|
||||
|
||||
// #region Lifecycle
|
||||
async _preCreate(data, options, user) {
|
||||
|
|
@ -123,5 +122,30 @@ export class AttributeItemData extends foundry.abstract.TypeDataModel {
|
|||
};
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 the min/value/max 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`) {
|
||||
Hooks.once(`taf.getRollData`, (data) => {
|
||||
data.active = {
|
||||
min: this.min,
|
||||
value: this.value,
|
||||
max: this.max,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
await macro?.execute({ item });
|
||||
};
|
||||
// #endregion Methods
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { toPrecision } from "../../utils/roundToPrecision.mjs";
|
||||
|
||||
export class GenericItemData extends foundry.abstract.TypeDataModel {
|
||||
// MARK: Schema
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
return {
|
||||
|
|
@ -35,6 +36,7 @@ export class GenericItemData extends foundry.abstract.TypeDataModel {
|
|||
};
|
||||
};
|
||||
|
||||
// #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.
|
||||
|
|
@ -43,4 +45,29 @@ export class GenericItemData extends foundry.abstract.TypeDataModel {
|
|||
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`) {
|
||||
Hooks.once(`taf.getRollData`, (data) => {
|
||||
data.active = {
|
||||
quantity: this.quantity,
|
||||
equipped: this.equipped ? 1 : 0,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
await macro?.execute({ item });
|
||||
};
|
||||
// #endregion Methods
|
||||
};
|
||||
|
|
|
|||
|
|
@ -66,28 +66,12 @@ export class TAFActor extends Actor {
|
|||
|
||||
// #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,
|
||||
...this.system.attr,
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
};
|
||||
};
|
||||
Hooks.call(`taf.getRollData`, data, this);
|
||||
|
||||
return data;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -6,7 +6,16 @@
|
|||
data-foreign-uuid="{{ attr.uuid }}"
|
||||
>
|
||||
<legend>
|
||||
{{#if attr.system.trigger}}
|
||||
<button
|
||||
type="button"
|
||||
data-action="executeTrigger"
|
||||
>
|
||||
{{ attr.name }}
|
||||
</button>
|
||||
{{else}}
|
||||
{{ attr.name }}
|
||||
{{/if}}
|
||||
</legend>
|
||||
<div class="attr-range">
|
||||
{{#if attr.system.isRange }}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,14 @@
|
|||
<div class="title grow">
|
||||
<span class="name">{{ name }}</span>
|
||||
</div>
|
||||
{{#if system.trigger}}
|
||||
<button
|
||||
type="button"
|
||||
data-action="executeTrigger"
|
||||
>
|
||||
Roll
|
||||
</button>
|
||||
{{/if}}
|
||||
<input
|
||||
type="number"
|
||||
id="{{uuid}}-value"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue