daggerheart/module/documents/item.mjs
WBHarry 187ee3e1bd
Refactor/84 data models structure (#131)
* - Move all DataModel item files to a new 'items' subfolder for better organization
- Add _module.mjs file to simplify imports
- Update all import paths
- Rename class for use the new acronym DH

* FIX: remove unnecessary import

* FEAT: BaseDataItem class
add TODO comments for future improvements
FIX: Remove effect field on template
FIX: remove unused DhpEffects file

* FEAT: new FormulaField class
FEAT: add getRollData on BaseDataItem Class
FEAT: weapon
FIX: remove inventoryWeapon field on Weapon Data Model

* FEAT: add class prepareBaseData for domains

* FEAT: new ForeignDocumentUUIDField
FIX: Remove unnecessary fields
FEAT: use ForeignDocumentUUIDField in the Item Class DataModel

* FIX: remove wrong option in String Field

* FIX: remove unused import

* FIX: ADD htmlFields description in manifest

* FIX: minor fixes

* REFACTOR: rename folder `data/items` -> `data/item`
REFACTOR: rename folder `data/messages` -> `data/chat-message`.

* FIX: imports
FIX: items sheet new paths
FIX: ItemDataModelMetadata type jsdoc

* FEAT: formatting code
FIX: fix fields used
FEAT: add jsdoc

* 110 - Class Data Model (#111)

* Added PreCreate/Create/Delete logic for Class/Subclass and set it as foreignUUID fields in PC

* Moved methods into TypedModelData

* Simplified Subclass

* Fixed up data model and a basic placeholder template (#117)

* 118 - adversary data model (#119)

* Fixed datamodel and set up basic template in new style

* Added in a temp attack button, because why not

* Restored HitPoints counting up

* 113 - Character Data Model (#114)

* Improved Character datamodel

* Removed additional unneccessary getters

* Preliminary cleanup in the class sheet

* Cleanup of 'pc' references

* Corrected Duality rolling from Character

* Fix to damage roll

* Added a basic BaseDataActor data model

* Gathered exports

* getRollData recursion fix

* Feature/112 items use action datamodel (#127)

* Create new actions classes

* actions types - attack roll

* fixes before merge

* First PR

* Add daggerheart.css to gitignore

* Update ToDo

* Remove console log

* Fixed chat /dr roll

* Remove jQuery

* Fixed so the different chat themes work again

* Fixed duality roll buttons

* Fix to advantage/disadvantage shortcut

* Extand action to other item types

* Roll fixes

* Fixes to adversary rolls

* resources

* Fixed adversary dice

---------

Co-authored-by: WBHarry <williambjrklund@gmail.com>

* Feature/116-implementation-of-pseudo-documents (#125)

* FEAT: add baseDataModel logic

* FEAT: new PseudoDocumentsField
FIX: BasePseudoDocument 's getEmbeddedDocument

* FEAT: PseudoDocument class

* FEAT: add TypedPseudoDocument
REFACTOR: PreudoDocument
FIX: Typos Bug

* FIX: CONFIG types

* FEAT: basic PseudoDocumentSheet

* FIX: remove schema
ADD: input of example

---------

Co-authored-by: Joaquin Pereyra <joaquinpereyra98@users.noreply.github.com>
Co-authored-by: WBHarry <williambjrklund@gmail.com>

* Levelup Followup (#126)

* Levelup applies bonuses to character

* Added visualisation of domain card levels

* Fixed domaincard level max for selections in a tier

* A trait can now only be level up once within the same tier

---------

Co-authored-by: Joaquin Pereyra <joaquinpereyra98@users.noreply.github.com>
Co-authored-by: joaquinpereyra98 <24190917+joaquinpereyra98@users.noreply.github.com>
Co-authored-by: Dapoulp <74197441+Dapoulp@users.noreply.github.com>
2025-06-13 14:17:13 +02:00

144 lines
5.4 KiB
JavaScript

export default class DhpItem extends Item {
/** @inheritdoc */
getEmbeddedDocument(embeddedName, id, { invalid = false, strict = false } = {}) {
const systemEmbeds = this.system.constructor.metadata.embedded ?? {};
if (embeddedName in systemEmbeds) {
const path = `system.${systemEmbeds[embeddedName]}`;
return foundry.utils.getProperty(this, path).get(id) ?? null;
}
return super.getEmbeddedDocument(embeddedName, id, { invalid, strict });
}
/** @inheritDoc */
prepareEmbeddedDocuments() {
super.prepareEmbeddedDocuments();
for (const action of this.system.actions ?? []) action.prepareData();
}
/**
* @inheritdoc
* @param {object} options - Options which modify the getRollData method.
* @returns
*/
getRollData(options = {}) {
let data;
if (this.system.getRollData) data = this.system.getRollData(options);
else {
const actorRollData = this.actor?.getRollData(options) ?? {};
data = { ...actorRollData, item: { ...this.system } };
}
if (data?.item) {
data.item.flags = { ...this.flags };
data.item.name = this.name;
}
return data;
}
isInventoryItem() {
return ['weapon', 'armor', 'miscellaneous', 'consumable'].includes(this.type);
}
static async createDialog(data = {}, { parent = null, pack = null, ...options } = {}) {
const documentName = this.metadata.name;
const types = game.documentTypes[documentName].filter(t => t !== CONST.BASE_DOCUMENT_TYPE);
let collection;
if (!parent) {
if (pack) collection = game.packs.get(pack);
else collection = game.collections.get(documentName);
}
const folders = collection?._formatFolderSelectOptions() ?? [];
const label = game.i18n.localize(this.metadata.label);
const title = game.i18n.format('DOCUMENT.Create', { type: label });
const typeObjects = types.reduce((obj, t) => {
const label = CONFIG[documentName]?.typeLabels?.[t] ?? t;
obj[t] = { value: t, label: game.i18n.has(label) ? game.i18n.localize(label) : t };
return obj;
}, {});
// Render the document creation form
const html = await foundry.applications.handlebars.renderTemplate(
'systems/daggerheart/templates/sidebar/documentCreate.hbs',
{
folders,
name: data.name || game.i18n.format('DOCUMENT.New', { type: label }),
folder: data.folder,
hasFolders: folders.length >= 1,
type: data.type || CONFIG[documentName]?.defaultType || typeObjects.armor,
types: {
Items: [typeObjects.armor, typeObjects.weapon, typeObjects.consumable, typeObjects.miscellaneous],
Character: [
typeObjects.class,
typeObjects.subclass,
typeObjects.ancestry,
typeObjects.community,
typeObjects.feature,
typeObjects.domainCard
]
},
hasTypes: types.length > 1
}
);
// Render the confirmation dialog window
return Dialog.prompt({
title: title,
content: html,
label: title,
callback: html => {
const form = html[0].querySelector('form');
const fd = new FormDataExtended(form);
foundry.utils.mergeObject(data, fd.object, { inplace: true });
if (!data.folder) delete data.folder;
if (types.length === 1) data.type = types[0];
if (!data.name?.trim()) data.name = this.defaultName();
return this.create(data, { parent, pack, renderSheet: true });
},
rejectClose: false,
options
});
}
async selectActionDialog() {
const content = await foundry.applications.handlebars.renderTemplate(
'systems/daggerheart/templates/views/actionSelect.hbs',
{ actions: this.system.actions }
),
title = 'Select Action',
type = 'div',
data = {};
return Dialog.prompt({
title,
// label: title,
content,
type,
callback: html => {
const form = html[0].querySelector('form'),
fd = new foundry.applications.ux.FormDataExtended(form);
return this.system.actions.find(a => a._id === fd.object.actionId);
},
rejectClose: false
});
}
async use(event) {
const actions = this.system.actions;
let response;
if (actions?.length) {
let action = actions[0];
if (actions.length > 1 && !event?.shiftKey) {
// Actions Choice Dialog
action = await this.selectActionDialog();
}
if (action) response = action.use(event);
// Check Target
// If action.roll => Roll Dialog
// Else If action.cost => Cost Dialog
// Then
// Apply Cost
// Apply Effect
}
// Display Item Card in chat
return response;
}
}