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,
|
createEmbeddedItem: this.#createEmbeddedItem,
|
||||||
configureSheet: this.#configureSheet,
|
configureSheet: this.#configureSheet,
|
||||||
toggleExpand: this.#toggleExpand,
|
toggleExpand: this.#toggleExpand,
|
||||||
|
executeTrigger: this.#executeTrigger,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -462,5 +463,16 @@ export class PlayerSheet extends
|
||||||
const item = await Item.create(data, { parent: this.actor });
|
const item = await Item.create(data, { parent: this.actor });
|
||||||
item?.sheet?.render({ force: true });
|
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
|
// #endregion Actions
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { clamp } from "../../utils/clamp.mjs";
|
||||||
const { getProperty, hasProperty, setProperty } = foundry.utils;
|
const { getProperty, hasProperty, setProperty } = foundry.utils;
|
||||||
|
|
||||||
export class AttributeItemData extends foundry.abstract.TypeDataModel {
|
export class AttributeItemData extends foundry.abstract.TypeDataModel {
|
||||||
// #region Schema
|
// MARK: Schema
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
return {
|
return {
|
||||||
|
|
@ -43,7 +43,6 @@ export class AttributeItemData extends foundry.abstract.TypeDataModel {
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
// #endregion Schema
|
|
||||||
|
|
||||||
// #region Lifecycle
|
// #region Lifecycle
|
||||||
async _preCreate(data, options, user) {
|
async _preCreate(data, options, user) {
|
||||||
|
|
@ -123,5 +122,30 @@ export class AttributeItemData extends foundry.abstract.TypeDataModel {
|
||||||
};
|
};
|
||||||
return null;
|
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
|
// #endregion Methods
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { toPrecision } from "../../utils/roundToPrecision.mjs";
|
import { toPrecision } from "../../utils/roundToPrecision.mjs";
|
||||||
|
|
||||||
export class GenericItemData extends foundry.abstract.TypeDataModel {
|
export class GenericItemData extends foundry.abstract.TypeDataModel {
|
||||||
|
// MARK: Schema
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
return {
|
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
|
* Calculates the total weight of the item based on the quantity of it, this
|
||||||
* rounds the number to the nearest 2 decimal places.
|
* 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;
|
const value = this.weight * this.quantity;
|
||||||
return toPrecision(Math.max(value, 0), 2);
|
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
|
// #region Roll Data
|
||||||
getRollData() {
|
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 = {
|
const data = {
|
||||||
carryCapacity: this.system.carryCapacity ?? null,
|
carryCapacity: this.system.carryCapacity ?? null,
|
||||||
|
...this.system.attr,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (`attr` in this.system) {
|
Hooks.call(`taf.getRollData`, data, this);
|
||||||
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;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,16 @@
|
||||||
data-foreign-uuid="{{ attr.uuid }}"
|
data-foreign-uuid="{{ attr.uuid }}"
|
||||||
>
|
>
|
||||||
<legend>
|
<legend>
|
||||||
|
{{#if attr.system.trigger}}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
data-action="executeTrigger"
|
||||||
|
>
|
||||||
{{ attr.name }}
|
{{ attr.name }}
|
||||||
|
</button>
|
||||||
|
{{else}}
|
||||||
|
{{ attr.name }}
|
||||||
|
{{/if}}
|
||||||
</legend>
|
</legend>
|
||||||
<div class="attr-range">
|
<div class="attr-range">
|
||||||
{{#if attr.system.isRange }}
|
{{#if attr.system.isRange }}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,14 @@
|
||||||
<div class="title grow">
|
<div class="title grow">
|
||||||
<span class="name">{{ name }}</span>
|
<span class="name">{{ name }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
{{#if system.trigger}}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
data-action="executeTrigger"
|
||||||
|
>
|
||||||
|
Roll
|
||||||
|
</button>
|
||||||
|
{{/if}}
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
id="{{uuid}}-value"
|
id="{{uuid}}-value"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue