Get items appearing on the sheet, still a lot to do but this is a strong step in the right direction
This commit is contained in:
parent
6b03d62234
commit
23a402f11a
9 changed files with 254 additions and 10 deletions
|
|
@ -2,10 +2,12 @@ import { __ID__, filePath } from "../consts.mjs";
|
|||
import { AttributeManager } from "./AttributeManager.mjs";
|
||||
import { attributeSorter } from "../utils/attributeSort.mjs";
|
||||
import { TAFDocumentSheetConfig } from "./TAFDocumentSheetConfig.mjs";
|
||||
import { toPrecision } from "../utils/roundToPrecision.mjs";
|
||||
|
||||
const { HandlebarsApplicationMixin } = foundry.applications.api;
|
||||
const { ActorSheetV2 } = foundry.applications.sheets;
|
||||
const { getProperty, hasProperty } = foundry.utils;
|
||||
const { TextEditor } = foundry.applications.ux;
|
||||
|
||||
const propertyToParts = {
|
||||
"name": [`header`],
|
||||
|
|
@ -39,6 +41,7 @@ export class PlayerSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
|||
actions: {
|
||||
manageAttributes: this.#manageAttributes,
|
||||
configureSheet: this.#configureSheet,
|
||||
toggleExpand: this.#toggleExpand,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -68,6 +71,15 @@ export class PlayerSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
|||
};
|
||||
// #endregion Options
|
||||
|
||||
// #region Instance Data
|
||||
/**
|
||||
* This Set is used to keep track of which items have had their full
|
||||
* details expanded so that it can be persisted across rerenders as
|
||||
* they occur.
|
||||
*/
|
||||
#expandedItems = new Set();
|
||||
// #endregion Instance Data
|
||||
|
||||
// #region Lifecycle
|
||||
_initializeApplicationOptions(options) {
|
||||
const sizing = getProperty(options.document, `flags.${__ID__}.PlayerSheet.size`) ?? {};
|
||||
|
|
@ -203,24 +215,73 @@ export class PlayerSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
|||
ctx.toggled = true;
|
||||
ctx.tabActive = this.tabGroups.primary === `content` || this.actor.items.size === 0;
|
||||
|
||||
const TextEditor = foundry.applications.ux.TextEditor.implementation;
|
||||
ctx.enriched = {
|
||||
system: {
|
||||
content: await TextEditor.enrichHTML(this.actor.system.content),
|
||||
content: await TextEditor.implementation.enrichHTML(this.actor.system.content),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
async _prepareItems(ctx) {
|
||||
ctx.tabActive = this.tabGroups.primary === `items`;
|
||||
|
||||
const weightUnit = game.settings.get(__ID__, `weightUnit`);
|
||||
let totalWeight = 0;
|
||||
|
||||
ctx.itemGroups = [];
|
||||
for (const [groupName, items] of Object.entries(this.actor.itemTypes)) {
|
||||
const preparedItems = [];
|
||||
|
||||
let summedWeight = 0;
|
||||
for (const item of items) {
|
||||
summedWeight += item.system.quantifiedWeight;
|
||||
preparedItems.push(await this._prepareItem(item));
|
||||
};
|
||||
totalWeight += summedWeight;
|
||||
|
||||
ctx.itemGroups.push({
|
||||
name: groupName.titleCase(),
|
||||
items: preparedItems,
|
||||
weight: toPrecision(summedWeight, 2) + weightUnit,
|
||||
});
|
||||
};
|
||||
|
||||
ctx.totalWeight = toPrecision(totalWeight, 2) + weightUnit;
|
||||
};
|
||||
|
||||
async _prepareItem(item) {};
|
||||
async _prepareItem(item) {
|
||||
const weightUnit = game.settings.get(__ID__, `weightUnit`)
|
||||
const ctx = {
|
||||
uuid: item.uuid,
|
||||
img: item.img,
|
||||
name: item.name,
|
||||
equipped: item.system.equipped,
|
||||
quantity: item.system.quantity,
|
||||
weight: item.system.quantifiedWeight + weightUnit,
|
||||
isExpanded: this.#expandedItems.has(item.uuid),
|
||||
canExpand: item.system.description.length > 0,
|
||||
};
|
||||
|
||||
ctx.description = ``;
|
||||
if (item.system.description.length > 0) {
|
||||
ctx.description = await TextEditor.implementation.enrichHTML(item.system.description);
|
||||
};
|
||||
|
||||
return ctx;
|
||||
};
|
||||
// #endregion Data Prep
|
||||
|
||||
// #region Actions
|
||||
#attributeManager = null;
|
||||
/** @this {PlayerSheet} */
|
||||
|
||||
/**
|
||||
* This action opens an instance of the AttributeManager application
|
||||
* so that the user can edit and update all of the attributes for the
|
||||
* actor. This persists the application instance for the duration of
|
||||
* the ActorSheet's lifespan.
|
||||
*
|
||||
* @this {PlayerSheet}
|
||||
*/
|
||||
static async #manageAttributes() {
|
||||
this.#attributeManager ??= new AttributeManager({ document: this.actor });
|
||||
if (this.#attributeManager.rendered) {
|
||||
|
|
@ -233,6 +294,13 @@ export class PlayerSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
|||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* This action overrides the default Foundry action in order to tell
|
||||
* it to open my custom DocumentSheetConfig application instead of
|
||||
* opening the non-customized sheet config app.
|
||||
*
|
||||
* @this {PlayerSheet}
|
||||
*/
|
||||
static async #configureSheet(event) {
|
||||
event.stopPropagation();
|
||||
if ( event.detail > 1 ) { return }
|
||||
|
|
@ -248,5 +316,27 @@ export class PlayerSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
|||
window: { windowId: this.window.windowId },
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* This action is used by the item lists in order to expand/collapse
|
||||
* the descriptions while maintaining that state across renders.
|
||||
*
|
||||
* @this {PlayerSheet}
|
||||
*/
|
||||
static async #toggleExpand(event, target) {
|
||||
if (event.srcElement instanceof HTMLInputElement) { return };
|
||||
|
||||
const { itemUuid } = target.closest(`[data-item-uuid]`)?.dataset ?? {};
|
||||
if (!itemUuid) { return };
|
||||
|
||||
const expanded = this.#expandedItems.has(itemUuid);
|
||||
if (expanded) {
|
||||
this.#expandedItems.delete(itemUuid);
|
||||
target.nextElementSibling.dataset.expanded = false;
|
||||
} else {
|
||||
this.#expandedItems.add(itemUuid);
|
||||
target.nextElementSibling.dataset.expanded = true;
|
||||
}
|
||||
};
|
||||
// #endregion Actions
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { toPrecision } from "../../utils/roundToPrecision.mjs";
|
||||
|
||||
export class GenericItemData extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
|
|
@ -28,4 +30,12 @@ export class GenericItemData extends foundry.abstract.TypeDataModel {
|
|||
}),
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
return toPrecision(this.weight * this.quantity, 2);
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,6 +13,15 @@ export function registerWorldSettings() {
|
|||
scope: `world`,
|
||||
});
|
||||
|
||||
game.settings.register(__ID__, `weightUnit`, {
|
||||
name: `taf.settings.weightUnit.name`,
|
||||
hint: `taf.settings.weightUnit.hint`,
|
||||
config: true,
|
||||
type: String,
|
||||
default: ``,
|
||||
scope: `world`,
|
||||
});
|
||||
|
||||
game.settings.register(__ID__, `canPlayersManageAttributes`, {
|
||||
name: `taf.settings.canPlayersManageAttributes.name`,
|
||||
hint: `taf.settings.canPlayersManageAttributes.hint`,
|
||||
|
|
|
|||
20
module/utils/roundToPrecision.mjs
Normal file
20
module/utils/roundToPrecision.mjs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* Takes a possibly-decimal value and rounds after a certain precision, keeping
|
||||
* only the specified amount of decimals.
|
||||
*
|
||||
* @param {number} value The value that is to be rounded.
|
||||
* @param {number} precision The number of decimal places to round to. Must be a
|
||||
* positive integer.
|
||||
* @returns The rounded number
|
||||
*/
|
||||
export function toPrecision(value, precision = 1) {
|
||||
if (!Number.isInteger(precision)) {
|
||||
throw `Precision must be an integer`;
|
||||
};
|
||||
if (precision < 0) {
|
||||
throw `Precision must be greater than or equal to 0`;
|
||||
};
|
||||
|
||||
const m = 10 ** precision;
|
||||
return Math.round(value * m) / m;
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue