diff --git a/module/applications/sheets/actors/adversary.mjs b/module/applications/sheets/actors/adversary.mjs
index 2a18ad95..0603ae9d 100644
--- a/module/applications/sheets/actors/adversary.mjs
+++ b/module/applications/sheets/actors/adversary.mjs
@@ -1,19 +1,15 @@
import DHBaseActorSheet from '../api/base-actor.mjs';
-import DHActionConfig from '../../sheets-configs/action-config.mjs';
-import DHAdversarySettings from '../../sheets-configs/adversary-settings.mjs';
+
+/**@typedef {import('@client/applications/_types.mjs').ApplicationClickAction} ApplicationClickAction */
export default class AdversarySheet extends DHBaseActorSheet {
static DEFAULT_OPTIONS = {
classes: ['adversary'],
position: { width: 660, height: 766 },
actions: {
- reactionRoll: this.reactionRoll,
+ reactionRoll: AdversarySheet.#reactionRoll,
useItem: this.useItem,
toChat: this.toChat,
- attackConfigure: this.attackConfigure,
- addExperience: this.addExperience,
- removeExperience: this.removeExperience,
- openSettings: this.openSettings
},
window: {
resizable: true
@@ -51,7 +47,15 @@ export default class AdversarySheet extends DHBaseActorSheet {
return item;
}
- static async reactionRoll(event) {
+ /* -------------------------------------------- */
+ /* Application Clicks Actions */
+ /* -------------------------------------------- */
+
+ /**
+ * Performs a reaction roll for an Adversary.
+ * @type {ApplicationClickAction}
+ */
+ static #reactionRoll(event) {
const config = {
event: event,
title: `Reaction Roll: ${this.actor.name}`,
@@ -65,18 +69,23 @@ export default class AdversarySheet extends DHBaseActorSheet {
mute: true
}
};
+
this.actor.diceRoll(config);
}
- static async openSettings() {
- await new DHAdversarySettings(this.document).render(true);
- }
-
+ /**
+ *
+ * @type {ApplicationClickAction}
+ */
static async useItem(event) {
const action = this.getItem(event) ?? this.actor.system.attack;
action.use(event);
}
+ /**
+ *
+ * @type {ApplicationClickAction}
+ */
static async toChat(event, button) {
if (button?.dataset?.type === 'experience') {
const experience = this.document.system.experiences[button.dataset.uuid];
@@ -103,21 +112,4 @@ export default class AdversarySheet extends DHBaseActorSheet {
}
}
- static async attackConfigure(event) {
- await new DHActionConfig(this.document.system.attack).render(true);
- }
-
- static async addExperience() {
- const experienceId = foundry.utils.randomID();
- await this.document.update({
- [`system.experiences.${experienceId}`]: { id: experienceId, name: 'Experience', value: 1 }
- });
- }
-
- static async removeExperience(_, button) {
- await this.document.update({
- [`system.experiences.-=${button.dataset.experience}`]: null
- });
- }
-
}
diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs
index 06cc985e..6dc13fff 100644
--- a/module/applications/sheets/actors/character.mjs
+++ b/module/applications/sheets/actors/character.mjs
@@ -172,7 +172,8 @@ export default class CharacterSheet extends DHBaseActorSheet {
/**
* Get the set of ContextMenu options.
- * @returns {import('@client/applications/ux/context-menu.mjs').ContextMenuEntry[]} The Array of context options passed to the ContextMenu instance
+ * @returns {import('@client/applications/ux/context-menu.mjs').ContextMenuEntry[]} - The Array of context options passed to the ContextMenu instance
+ * @this {CharacterSheet}
* @protected
*/
static _getContextMenuOptions() {
@@ -199,7 +200,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
const item = getItem(el);
return ['weapon', 'armor'].includes(item.type) && !item.system.equipped;
},
- callback: CharacterSheet.toggleEquipItem.bind(this)
+ callback: CharacterSheet.#toggleEquipItem.bind(this)
}, {
name: 'DAGGERHEART.Sheets.PC.ContextMenu.Unequip',
icon: '',
@@ -207,7 +208,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
const item = getItem(el);
return ['weapon', 'armor'].includes(item.type) && item.system.equipped;
},
- callback: CharacterSheet.toggleEquipItem.bind(this)
+ callback: CharacterSheet.#toggleEquipItem.bind(this)
}, {
name: 'DAGGERHEART.Sheets.PC.ContextMenu.ToLoadout',
icon: '',
diff --git a/module/applications/sheets/actors/companion.mjs b/module/applications/sheets/actors/companion.mjs
index f064bb2a..ccf49b86 100644
--- a/module/applications/sheets/actors/companion.mjs
+++ b/module/applications/sheets/actors/companion.mjs
@@ -1,5 +1,7 @@
import DHBaseActorSheet from '../api/base-actor.mjs';
-import DHCompanionSettings from '../../sheets-configs/companion-settings.mjs';
+
+/**@typedef {import('@client/applications/_types.mjs').ApplicationClickAction} ApplicationClickAction */
+
export default class DhCompanionSheet extends DHBaseActorSheet {
static DEFAULT_OPTIONS = {
@@ -7,9 +9,8 @@ export default class DhCompanionSheet extends DHBaseActorSheet {
position: { width: 300 },
actions: {
viewActor: this.viewActor,
- openSettings: this.openSettings,
useItem: this.useItem,
- toChat: this.toChat
+ toChat: this.toChat,
},
};
@@ -30,6 +31,10 @@ export default class DhCompanionSheet extends DHBaseActorSheet {
}
};
+ /* -------------------------------------------- */
+ /* Application Clicks Actions */
+ /* -------------------------------------------- */
+
static async viewActor(_, button) {
const target = button.closest('[data-item-uuid]');
const actor = await foundry.utils.fromUuid(target.dataset.itemUuid);
@@ -73,8 +78,4 @@ export default class DhCompanionSheet extends DHBaseActorSheet {
item.toChat(this.document.id);
}
}
-
- static async openSettings() {
- await new DHCompanionSettings(this.document).render(true);
- }
}
diff --git a/module/applications/sheets/actors/environment.mjs b/module/applications/sheets/actors/environment.mjs
index 46fa382d..a66145d5 100644
--- a/module/applications/sheets/actors/environment.mjs
+++ b/module/applications/sheets/actors/environment.mjs
@@ -1,22 +1,22 @@
import DHBaseActorSheet from '../api/base-actor.mjs';
-import DHEnvironmentSettings from '../../sheets-configs/environment-settings.mjs';
+
+/**@typedef {import('@client/applications/_types.mjs').ApplicationClickAction} ApplicationClickAction */
export default class DhpEnvironment extends DHBaseActorSheet {
+ /**@inheritdoc */
static DEFAULT_OPTIONS = {
classes: ['environment'],
position: {
width: 500
},
actions: {
- addAdversary: this.addAdversary,
- deleteProperty: this.deleteProperty,
- openSettings: this.openSettings,
useItem: this.useItem,
toChat: this.toChat
},
dragDrop: [{ dragSelector: '.action-section .inventory-item', dropSelector: null }]
};
+ /**@override */
static PARTS = {
header: { template: 'systems/daggerheart/templates/sheets/actors/environment/header.hbs' },
features: { template: 'systems/daggerheart/templates/sheets/actors/environment/features.hbs' },
@@ -35,30 +35,22 @@ export default class DhpEnvironment extends DHBaseActorSheet {
}
};
+ /* -------------------------------------------- */
+
getItem(element) {
const itemId = (element.target ?? element).closest('[data-item-id]').dataset.itemId,
item = this.document.items.get(itemId);
return item;
}
- static async openSettings() {
- await new DHEnvironmentSettings(this.document).render(true);
- }
-
- static async addAdversary() {
- await this.document.update({
- [`system.potentialAdversaries.${foundry.utils.randomID()}.label`]: game.i18n.localize(
- 'DAGGERHEART.ACTORS.Environment.newAdversary'
- )
- });
- this.render();
- }
-
- static async deleteProperty(_, target) {
- await this.document.update({ [`${target.dataset.path}.-=${target.id}`]: null });
- this.render();
- }
+ /* -------------------------------------------- */
+ /* Application Clicks Actions */
+ /* -------------------------------------------- */
+ /**
+ *
+ * @type {ApplicationClickAction}
+ */
async viewAdversary(_, button) {
const target = button.closest('[data-item-uuid]');
const adversary = await foundry.utils.fromUuid(target.dataset.itemUuid);
@@ -67,7 +59,7 @@ export default class DhpEnvironment extends DHBaseActorSheet {
return;
}
- adversary.sheet.render(true);
+ adversary.sheet.render({ force: true });
}
static async useItem(event, button) {
diff --git a/module/applications/sheets/api/base-actor.mjs b/module/applications/sheets/api/base-actor.mjs
index 3a2187d7..0647857f 100644
--- a/module/applications/sheets/api/base-actor.mjs
+++ b/module/applications/sheets/api/base-actor.mjs
@@ -2,6 +2,8 @@ import DHApplicationMixin from './application-mixin.mjs';
const { ActorSheetV2 } = foundry.applications.sheets;
+/**@typedef {import('@client/applications/_types.mjs').ApplicationClickAction} ApplicationClickAction */
+
/**
* A base actor sheet extending {@link ActorSheetV2} via {@link DHApplicationMixin}
* @extends ActorSheetV2
@@ -17,14 +19,36 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
form: {
submitOnChange: true
},
- actions: {},
- dragDrop: []
+ actions: {
+ openSettings: DHBaseActorSheet.#openSettings
+ },
+ dragDrop: [],
};
+ /**
+ *
+ */
+ #settingSheet;
+
+ get settingSheet() {
+ const SheetClass = this.document.system.metadata.settingSheet;
+ return this.#settingSheet ??= SheetClass ? new SheetClass(this.document): null;
+ }
+
+ /**@inheritdoc */
async _prepareContext(_options) {
const context = await super._prepareContext(_options);
context.isNPC = this.document.isNPC;
-
return context;
}
+
+ /**
+ *
+ * @type {ApplicationClickAction}
+ */
+ static async #openSettings() {
+ await this.settingSheet.render({ force: true });
+ }
+
+
}
\ No newline at end of file
diff --git a/module/data/actor/adversary.mjs b/module/data/actor/adversary.mjs
index db7d2ca1..4dcea784 100644
--- a/module/data/actor/adversary.mjs
+++ b/module/data/actor/adversary.mjs
@@ -1,3 +1,4 @@
+import DHAdversarySettings from '../../applications/sheets-configs/adversary-settings.mjs';
import ActionField from '../fields/actionField.mjs';
import BaseDataActor from './base.mjs';
@@ -13,7 +14,8 @@ export default class DhpAdversary extends BaseDataActor {
static get metadata() {
return foundry.utils.mergeObject(super.metadata, {
label: 'TYPES.Actor.adversary',
- type: 'adversary'
+ type: 'adversary',
+ settingSheet: DHAdversarySettings,
});
}
diff --git a/module/data/actor/base.mjs b/module/data/actor/base.mjs
index a04138ff..d4afa51f 100644
--- a/module/data/actor/base.mjs
+++ b/module/data/actor/base.mjs
@@ -4,6 +4,7 @@
* @property {string} label - A localizable label used on application.
* @property {string} type - The system type that this data model represents.
* @property {Boolean} isNPC - This data model represents a NPC?
+ * @property {typeof foundry.applications.api.DocumentSheetV2} settingSheet - The sheet class used to render the settings UI for this actor type.
*/
export default class BaseDataActor extends foundry.abstract.TypeDataModel {
/** @returns {ActorDataModelMetadata}*/
@@ -12,9 +13,15 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel {
label: 'Base Actor',
type: 'base',
isNPC: true,
+ settingSheet: null,
};
}
+ /**@returns {ActorDataModelMetadata}*/
+ get metadata() {
+ return this.constructor.metadata;
+ }
+
/** @inheritDoc */
static defineSchema() {
const fields = foundry.data.fields;
diff --git a/module/data/actor/companion.mjs b/module/data/actor/companion.mjs
index 8745473f..1203cc96 100644
--- a/module/data/actor/companion.mjs
+++ b/module/data/actor/companion.mjs
@@ -3,6 +3,7 @@ import DhLevelData from '../levelData.mjs';
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
import ActionField from '../fields/actionField.mjs';
import { adjustDice, adjustRange } from '../../helpers/utils.mjs';
+import DHCompanionSettings from '../../applications/sheets-configs/companion-settings.mjs';
export default class DhCompanion extends BaseDataActor {
static LOCALIZATION_PREFIXES = ['DAGGERHEART.ACTORS.Companion'];
@@ -10,7 +11,8 @@ export default class DhCompanion extends BaseDataActor {
static get metadata() {
return foundry.utils.mergeObject(super.metadata, {
label: 'TYPES.Actor.companion',
- type: 'companion'
+ type: 'companion',
+ settingSheet: DHCompanionSettings
});
}
diff --git a/module/data/actor/environment.mjs b/module/data/actor/environment.mjs
index 2cd3338f..76990e88 100644
--- a/module/data/actor/environment.mjs
+++ b/module/data/actor/environment.mjs
@@ -1,5 +1,6 @@
import BaseDataActor from './base.mjs';
import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs';
+import DHEnvironmentSettings from '../../applications/sheets-configs/environment-settings.mjs';
export default class DhEnvironment extends BaseDataActor {
static LOCALIZATION_PREFIXES = ['DAGGERHEART.ACTORS.Environment'];
@@ -7,7 +8,8 @@ export default class DhEnvironment extends BaseDataActor {
static get metadata() {
return foundry.utils.mergeObject(super.metadata, {
label: 'TYPES.Actor.environment',
- type: 'environment'
+ type: 'environment',
+ settingSheet: DHEnvironmentSettings
});
}
diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs
index 1a250327..bddfb106 100644
--- a/module/data/item/base.mjs
+++ b/module/data/item/base.mjs
@@ -22,6 +22,11 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
};
}
+ /**@returns {ItemDataModelMetadata}*/
+ get metadata() {
+ return this.constructor.metadata;
+ }
+
/** @inheritDoc */
static defineSchema() {
const schema = {};
@@ -56,9 +61,9 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
/**@inheritdoc */
async _preCreate(data, options, user) {
// Skip if no initial action is required or actions already exist
- if (!this.constructor.metadata.hasInitialAction || !foundry.utils.isEmpty(this.actions)) return;
+ if (!this.metadata.hasInitialAction || !foundry.utils.isEmpty(this.actions)) return;
- const metadataType = this.constructor.metadata.type;
+ const metadataType = this.metadata.type;
const actionType = { weapon: 'attack' }[metadataType];
const ActionClass = game.system.api.models.actions.actionsTypes[actionType];
diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs
index c2c3a545..b48d8c26 100644
--- a/module/documents/actor.mjs
+++ b/module/documents/actor.mjs
@@ -11,7 +11,7 @@ export default class DhpActor extends foundry.documents.Actor {
* @returns {boolean}
*/
get isNPC() {
- return this.system.constructor.metadata.isNPC;
+ return this.system.metadata.isNPC;
}
async _preCreate(data, options, user) {
diff --git a/module/documents/item.mjs b/module/documents/item.mjs
index 21674009..3a9b705a 100644
--- a/module/documents/item.mjs
+++ b/module/documents/item.mjs
@@ -34,7 +34,7 @@ export default class DHItem extends foundry.documents.Item {
* @returns {boolean} Returns `true` if the item is an inventory item.
*/
get isInventoryItem() {
- return this.system.constructor.metadata.isInventoryItem ?? false;
+ return this.system.metadata.isInventoryItem ?? false;
}
/** @inheritdoc */
@@ -53,17 +53,17 @@ export default class DHItem extends foundry.documents.Item {
const isInventoryItem = CONFIG.Item.dataModels[type]?.metadata?.isInventoryItem;
const group =
isInventoryItem === true
- ? 'Inventory Items'
+ ? 'Inventory Items' //TODO localize
: isInventoryItem === false
- ? 'Character Items'
- : 'Other';
+ ? 'Character Items' //TODO localize
+ : 'Other'; //TODO localize
return { value: type, label, group };
}
);
if (!documentTypes.length) {
- throw new Error('No document types were permitted to be created.');
+ throw new Error('No document types were permitted to be created.'); //TODO localize
}
const sortedTypes = documentTypes.sort((a, b) => a.label.localeCompare(b.label, game.i18n.lang));