diff --git a/lang/en.json b/lang/en.json index 500c032a..6052dfba 100755 --- a/lang/en.json +++ b/lang/en.json @@ -25,7 +25,9 @@ "notifications": { "adversaryMissing": "The linked adversary doesn't exist in the world.", "beastformInapplicable": "A beastform can only be applied to a Character.", - "beastformAlreadyApplied": "The character already has a beastform applied!" + "beastformAlreadyApplied": "The character already has a beastform applied!", + "featureIsMissing": "The feature doesn't exist. You should remove it.", + "featureIsFull": "You can only have 1 entry of this feature" } }, "Settings": { @@ -964,29 +966,6 @@ "Description": "This weapon can also be used with these statistics—{characterTrait}, {range}, {damage}." } }, - "Feature": { - "Type": { - "ancestry": "Ancestry", - "community": "Community", - "class": "Class", - "subclass": "Subclass", - "classHope": "Class Hope", - "domainCard": "Domain Card", - "equipment": "Equipment" - }, - "ValueType": { - "Normal": "Normal", - "Input": "Input", - "Dice": "Dice" - }, - "Max": "Max", - "NewEffect": "New Effect" - }, - "FeatureType": { - "Normal": "Normal", - "Input": "Input", - "Ticks": "Ticks" - }, "Application": { "Downtime": { "TakeDowntime": "Take Downtime" @@ -1499,7 +1478,7 @@ "Features": "Features", "Effects": "Effects", "activeEffects": "Active Effects", - "inativeEffects": "Inative Effects" + "inactiveEffects": "Inactive Effects" }, "DomainCard": { "Type": "Type", diff --git a/module/applications/characterCreation/characterCreation.mjs b/module/applications/characterCreation/characterCreation.mjs index 1dabc8c2..48ad3bfb 100644 --- a/module/applications/characterCreation/characterCreation.mjs +++ b/module/applications/characterCreation/characterCreation.mjs @@ -349,8 +349,8 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl } static async finish() { - const embeddedAncestries = await this.character.createEmbeddedDocuments('Item', [this.setup.ancestry]); - const embeddedCommunities = await this.character.createEmbeddedDocuments('Item', [this.setup.community]); + await this.character.createEmbeddedDocuments('Item', [this.setup.ancestry]); + await this.character.createEmbeddedDocuments('Item', [this.setup.community]); await this.character.createEmbeddedDocuments('Item', [this.setup.class]); await this.character.createEmbeddedDocuments('Item', [this.setup.subclass]); await this.character.createEmbeddedDocuments('Item', Object.values(this.setup.domainCards)); @@ -379,9 +379,7 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl await this.character.update({ system: { traits: this.setup.traits, - experiences: this.setup.experiences, - ancestry: embeddedAncestries[0].uuid, - community: embeddedCommunities[0].uuid + experiences: this.setup.experiences } }); diff --git a/module/applications/sheets-configs/adversary-settings.mjs b/module/applications/sheets-configs/adversary-settings.mjs index 22ad4b18..33899020 100644 --- a/module/applications/sheets-configs/adversary-settings.mjs +++ b/module/applications/sheets-configs/adversary-settings.mjs @@ -1,7 +1,3 @@ -import DHActionConfig from './action-config.mjs'; -import DHBaseItemSheet from '../sheets/api/base-item.mjs'; -import { actionsTypes } from '../../data/action/_module.mjs'; - const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; export default class DHAdversarySettings extends HandlebarsApplicationMixin(ApplicationV2) { @@ -9,6 +5,7 @@ export default class DHAdversarySettings extends HandlebarsApplicationMixin(Appl super({}); this.actor = actor; + this._dragDrop = this._createDragDropHandlers(); } get title() { @@ -26,15 +23,19 @@ export default class DHAdversarySettings extends HandlebarsApplicationMixin(Appl actions: { addExperience: this.#addExperience, removeExperience: this.#removeExperience, - addAction: this.#addAction, - editAction: this.#editAction, - removeAction: this.#removeAction + addFeature: this.#addFeature, + editFeature: this.#editFeature, + removeFeature: this.#removeFeature }, form: { handler: this.updateForm, submitOnChange: true, closeOnSubmit: false - } + }, + dragDrop: [ + { dragSelector: null, dropSelector: '.tab.features' }, + { dragSelector: '.feature-item', dropSelector: null } + ] }; static PARTS = { @@ -55,9 +56,9 @@ export default class DHAdversarySettings extends HandlebarsApplicationMixin(Appl id: 'experiences', template: 'systems/daggerheart/templates/sheets-settings/adversary-settings/experiences.hbs' }, - actions: { - id: 'actions', - template: 'systems/daggerheart/templates/sheets-settings/adversary-settings/actions.hbs' + features: { + id: 'features', + template: 'systems/daggerheart/templates/sheets-settings/adversary-settings/features.hbs' } }; @@ -86,13 +87,13 @@ export default class DHAdversarySettings extends HandlebarsApplicationMixin(Appl icon: null, label: 'DAGGERHEART.General.tabs.experiences' }, - actions: { + features: { active: false, cssClass: '', group: 'primary', - id: 'actions', + id: 'features', icon: null, - label: 'DAGGERHEART.General.tabs.actions' + label: 'DAGGERHEART.General.tabs.features' } }; @@ -107,6 +108,22 @@ export default class DHAdversarySettings extends HandlebarsApplicationMixin(Appl return context; } + _attachPartListeners(partId, htmlElement, options) { + super._attachPartListeners(partId, htmlElement, options); + + this._dragDrop.forEach(d => d.bind(htmlElement)); + } + + _createDragDropHandlers() { + return this.options.dragDrop.map(d => { + d.callbacks = { + dragstart: this._onDragStart.bind(this), + drop: this._onDrop.bind(this) + }; + return new foundry.applications.ux.DragDrop.implementation(d); + }); + } + _getTabs(tabs) { for (const v of Object.values(tabs)) { v.active = this.tabGroups[v.group] ? this.tabGroups[v.group] === v.id : v.active; @@ -130,46 +147,25 @@ export default class DHAdversarySettings extends HandlebarsApplicationMixin(Appl this.render(); } - static async #addAction(_event, _button) { - const actionType = await DHBaseItemSheet.selectActionType(); - if (!actionType) return; - try { - const cls = actionsTypes[actionType] ?? actionsTypes.attack, - action = new cls( - { - _id: foundry.utils.randomID(), - type: actionType, - name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].name), - ...cls.getSourceConfig(this.actor) - }, - { - parent: this.actor - } - ); - await this.actor.update({ 'system.actions': [...this.actor.system.actions, action] }); - await new DHActionConfig(this.actor.system.actions[this.actor.system.actions.length - 1]).render({ - force: true - }); - this.render(); - } catch (error) { - console.log(error); - } + static async #addFeature(_, _button) { + await this.actor.createEmbeddedDocuments('Item', [ + { + type: 'feature', + name: game.i18n.format('DOCUMENT.New', { type: game.i18n.localize('TYPES.Item.feature') }), + img: 'icons/skills/melee/weapons-crossed-swords-black.webp' + } + ]); + this.render(); } - static async #editAction(event, target) { + static async #editFeature(event, target) { event.stopPropagation(); - const actionIndex = target.dataset.index; - await new DHActionConfig(this.actor.system.actions[actionIndex]).render({ - force: true - }); + this.actor.items.get(target.id).sheet.render(true); } - static async #removeAction(event, target) { + static async #removeFeature(event, target) { event.stopPropagation(); - const actionIndex = target.dataset.index; - await this.actor.update({ - 'system.actions': this.actor.system.actions.filter((_, index) => index !== Number.parseInt(actionIndex)) - }); + await this.actor.deleteEmbeddedDocuments('Item', [target.id]); this.render(); } @@ -177,4 +173,26 @@ export default class DHAdversarySettings extends HandlebarsApplicationMixin(Appl await this.actor.update(formData.object); this.render(); } + + async _onDragStart(event) { + const featureItem = event.currentTarget.closest('.feature-item'); + + if (featureItem) { + const feature = this.actor.items.get(featureItem.id); + const featureData = { type: 'Item', uuid: feature.uuid, fromInternal: true }; + event.dataTransfer.setData('text/plain', JSON.stringify(featureData)); + event.dataTransfer.setDragImage(featureItem.querySelector('img'), 60, 0); + } + } + + async _onDrop(event) { + const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); + if (data.fromInternal) return; + + const item = await fromUuid(data.uuid); + if (item.type === 'feature') { + await this.actor.createEmbeddedDocuments('Item', [item]); + this.render(); + } + } } diff --git a/module/applications/sheets-configs/environment-settings.mjs b/module/applications/sheets-configs/environment-settings.mjs index 5e0c5cda..27969634 100644 --- a/module/applications/sheets-configs/environment-settings.mjs +++ b/module/applications/sheets-configs/environment-settings.mjs @@ -1,7 +1,3 @@ -import DHActionConfig from './action-config.mjs'; -import DHBaseItemSheet from '../sheets/api/base-item.mjs'; -import { actionsTypes } from '../../data/action/_module.mjs'; - const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; export default class DHEnvironmentSettings extends HandlebarsApplicationMixin(ApplicationV2) { @@ -25,9 +21,9 @@ export default class DHEnvironmentSettings extends HandlebarsApplicationMixin(Ap }, position: { width: 455, height: 'auto' }, actions: { - addAction: this.#addAction, - editAction: this.#editAction, - removeAction: this.#removeAction, + addFeature: this.#addFeature, + editFeature: this.#editFeature, + removeFeature: this.#removeFeature, addCategory: this.#addCategory, deleteProperty: this.#deleteProperty, viewAdversary: this.#viewAdversary, @@ -38,7 +34,11 @@ export default class DHEnvironmentSettings extends HandlebarsApplicationMixin(Ap submitOnChange: true, closeOnSubmit: false }, - dragDrop: [{ dragSelector: null, dropSelector: '.category-container' }] + dragDrop: [ + { dragSelector: null, dropSelector: '.category-container' }, + { dragSelector: null, dropSelector: '.tab.features' }, + { dragSelector: '.feature-item', dropSelector: null } + ] }; static PARTS = { @@ -51,9 +51,9 @@ export default class DHEnvironmentSettings extends HandlebarsApplicationMixin(Ap id: 'details', template: 'systems/daggerheart/templates/sheets-settings/environment-settings/details.hbs' }, - actions: { - id: 'actions', - template: 'systems/daggerheart/templates/sheets-settings/environment-settings/actions.hbs' + features: { + id: 'features', + template: 'systems/daggerheart/templates/sheets-settings/environment-settings/features.hbs' }, adversaries: { id: 'adversaries', @@ -70,13 +70,13 @@ export default class DHEnvironmentSettings extends HandlebarsApplicationMixin(Ap icon: null, label: 'DAGGERHEART.General.tabs.details' }, - actions: { + features: { active: false, cssClass: '', group: 'primary', - id: 'actions', + id: 'features', icon: null, - label: 'DAGGERHEART.General.tabs.actions' + label: 'DAGGERHEART.General.tabs.features' }, adversaries: { active: false, @@ -107,6 +107,7 @@ export default class DHEnvironmentSettings extends HandlebarsApplicationMixin(Ap _createDragDropHandlers() { return this.options.dragDrop.map(d => { d.callbacks = { + dragstart: this._onDragStart.bind(this), drop: this._onDrop.bind(this) }; return new foundry.applications.ux.DragDrop.implementation(d); @@ -122,46 +123,23 @@ export default class DHEnvironmentSettings extends HandlebarsApplicationMixin(Ap return tabs; } - static async #addAction(_event, _button) { - const actionType = await DHBaseItemSheet.selectActionType(); - if (!actionType) return; - try { - const cls = actionsTypes[actionType] ?? actionsTypes.attack, - action = new cls( - { - _id: foundry.utils.randomID(), - type: actionType, - name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].name), - ...cls.getSourceConfig(this.actor) - }, - { - parent: this.actor - } - ); - await this.actor.update({ 'system.actions': [...this.actor.system.actions, action] }); - await new DHActionConfig(this.actor.system.actions[this.actor.system.actions.length - 1]).render({ - force: true - }); - this.render(); - } catch (error) { - console.log(error); - } + static async #addFeature(_, _button) { + await this.actor.createEmbeddedDocuments('Item', [ + { + type: 'feature', + name: game.i18n.format('DOCUMENT.New', { type: game.i18n.localize('TYPES.Item.feature') }), + img: 'icons/magic/perception/orb-crystal-ball-scrying-blue.webp' + } + ]); + this.render(); } - static async #editAction(event, target) { - event.stopPropagation(); - const actionIndex = target.dataset.index; - await new DHActionConfig(this.actor.system.actions[actionIndex]).render({ - force: true - }); + static async #editFeature(_, target) { + this.actor.items.get(target.id).sheet.render(true); } - static async #removeAction(event, target) { - event.stopPropagation(); - const actionIndex = target.dataset.index; - await this.actor.update({ - 'system.actions': this.actor.system.actions.filter((_, index) => index !== Number.parseInt(actionIndex)) - }); + static async #removeFeature(_, target) { + await this.actor.deleteEmbeddedDocuments('Item', [target.id]); this.render(); } @@ -199,10 +177,23 @@ export default class DHEnvironmentSettings extends HandlebarsApplicationMixin(Ap this.render(); } + async _onDragStart(event) { + const featureItem = event.currentTarget.closest('.feature-item'); + + if (featureItem) { + const feature = this.actor.items.get(featureItem.id); + const featureData = { type: 'Item', uuid: feature.uuid, fromInternal: true }; + event.dataTransfer.setData('text/plain', JSON.stringify(featureData)); + event.dataTransfer.setDragImage(featureItem.querySelector('img'), 60, 0); + } + } + async _onDrop(event) { const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); + if (data.fromInternal) return; + const item = await fromUuid(data.uuid); - if (item.type === 'adversary') { + if (item.type === 'adversary' && event.target.closest('.category-container')) { const target = event.target.closest('.category-container'); const path = `system.potentialAdversaries.${target.dataset.potentialAdversary}.adversaries`; const current = foundry.utils.getProperty(this.actor, path).map(x => x.uuid); @@ -210,6 +201,9 @@ export default class DHEnvironmentSettings extends HandlebarsApplicationMixin(Ap [path]: [...current, item.uuid] }); this.render(); + } else if (item.type === 'feature' && event.target.closest('.tab.features')) { + await this.actor.createEmbeddedDocuments('Item', [item]); + this.render(); } } diff --git a/module/applications/sheets/actors/adversary.mjs b/module/applications/sheets/actors/adversary.mjs index c12775b1..17f56c02 100644 --- a/module/applications/sheets/actors/adversary.mjs +++ b/module/applications/sheets/actors/adversary.mjs @@ -29,19 +29,19 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) { static PARTS = { sidebar: { template: 'systems/daggerheart/templates/sheets/actors/adversary/sidebar.hbs' }, header: { template: 'systems/daggerheart/templates/sheets/actors/adversary/header.hbs' }, - actions: { template: 'systems/daggerheart/templates/sheets/actors/adversary/actions.hbs' }, + features: { template: 'systems/daggerheart/templates/sheets/actors/adversary/features.hbs' }, notes: { template: 'systems/daggerheart/templates/sheets/actors/adversary/notes.hbs' }, effects: { template: 'systems/daggerheart/templates/sheets/actors/adversary/effects.hbs' } }; static TABS = { - actions: { + features: { active: true, cssClass: '', group: 'primary', - id: 'actions', + id: 'features', icon: null, - label: 'DAGGERHEART.General.tabs.actions' + label: 'DAGGERHEART.General.tabs.features' }, notes: { active: false, @@ -71,9 +71,9 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) { return context; } - getAction(element) { + getItem(element) { const itemId = (element.target ?? element).closest('[data-item-id]').dataset.itemId, - item = this.document.system.actions.find(x => x.id === itemId); + item = this.document.items.get(itemId); return item; } @@ -109,7 +109,7 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) { } static async useItem(event) { - const action = this.getAction(event) ?? this.actor.system.attack; + const action = this.getItem(event) ?? this.actor.system.attack; action.use(event); } @@ -135,7 +135,7 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) { cls.create(msg.toObject()); } else { - const item = this.getAction(event) ?? this.document.system.attack; + const item = this.getItem(event) ?? this.document.system.attack; item.toChat(this.document.id); } } diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index c74455b0..9122122c 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -307,12 +307,12 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { getItem(element) { const listElement = (element.target ?? element).closest('[data-item-id]'); const itemId = listElement.dataset.itemId; - if (listElement.dataset.type === 'effect') { - return this.document.effects.get(itemId); - } else if (['armor', 'weapon', 'feature', 'consumable', 'miscellaneous'].includes(listElement.dataset.type)) { - return this.document.items.get(itemId); - } else { - return this.document.system[listElement.dataset.type].system.actions.find(x => x.id === itemId); + + switch (listElement.dataset.type) { + case 'effect': + return this.document.effects.get(itemId); + default: + return this.document.items.get(itemId); } } diff --git a/module/applications/sheets/actors/environment.mjs b/module/applications/sheets/actors/environment.mjs index 733e8e10..1182a764 100644 --- a/module/applications/sheets/actors/environment.mjs +++ b/module/applications/sheets/actors/environment.mjs @@ -26,7 +26,7 @@ export default class DhpEnvironment extends DaggerheartSheet(ActorSheetV2) { static PARTS = { header: { template: 'systems/daggerheart/templates/sheets/actors/environment/header.hbs' }, - actions: { template: 'systems/daggerheart/templates/sheets/actors/environment/actions.hbs' }, + features: { template: 'systems/daggerheart/templates/sheets/actors/environment/features.hbs' }, potentialAdversaries: { template: 'systems/daggerheart/templates/sheets/actors/environment/potentialAdversaries.hbs' }, @@ -34,13 +34,13 @@ export default class DhpEnvironment extends DaggerheartSheet(ActorSheetV2) { }; static TABS = { - actions: { + features: { active: true, cssClass: '', group: 'primary', - id: 'actions', + id: 'features', icon: null, - label: 'DAGGERHEART.General.tabs.actions' + label: 'DAGGERHEART.General.tabs.features' }, potentialAdversaries: { active: false, @@ -69,9 +69,9 @@ export default class DhpEnvironment extends DaggerheartSheet(ActorSheetV2) { return context; } - getAction(element) { + getItem(element) { const itemId = (element.target ?? element).closest('[data-item-id]').dataset.itemId, - item = this.document.system.actions.find(x => x.id === itemId); + item = this.document.items.get(itemId); return item; } @@ -114,7 +114,7 @@ export default class DhpEnvironment extends DaggerheartSheet(ActorSheetV2) { } static async useItem(event, button) { - const action = this.getAction(event); + const action = this.getItem(event); if (!action) { await this.viewAdversary(event, button); } else { @@ -123,7 +123,7 @@ export default class DhpEnvironment extends DaggerheartSheet(ActorSheetV2) { } static async toChat(event) { - const item = this.getAction(event); + const item = this.getItem(event); item.toChat(this.document.id); } diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs index 6f04acb4..3ba471db 100644 --- a/module/applications/sheets/api/application-mixin.mjs +++ b/module/applications/sheets/api/application-mixin.mjs @@ -128,12 +128,20 @@ export default function DHApplicationMixin(Base) { _createDragDropHandlers() { return this.options.dragDrop.map(d => { d.callbacks = { + dragstart: this._onDragStart.bind(this), drop: this._onDrop.bind(this) }; return new foundry.applications.ux.DragDrop.implementation(d); }); } + /** + * Handle dragStart event. + * @param {DragEvent} event + * @protected + */ + _onDragStart(event) {} + /** * Handle drop event. * @param {DragEvent} event diff --git a/module/applications/sheets/api/base-item.mjs b/module/applications/sheets/api/base-item.mjs index 47ba5188..5d09b942 100644 --- a/module/applications/sheets/api/base-item.mjs +++ b/module/applications/sheets/api/base-item.mjs @@ -1,6 +1,5 @@ -import DHApplicationMixin from './application-mixin.mjs'; import DHActionConfig from '../../sheets-configs/action-config.mjs'; -import { actionsTypes } from '../../../data/action/_module.mjs'; +import DHApplicationMixin from './application-mixin.mjs'; const { ItemSheetV2 } = foundry.applications.sheets; @@ -20,8 +19,15 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { actions: { addAction: DHBaseItemSheet.#addAction, editAction: DHBaseItemSheet.#editAction, - removeAction: DHBaseItemSheet.#removeAction - } + removeAction: DHBaseItemSheet.#removeAction, + addFeature: DHBaseItemSheet.#addFeature, + editFeature: DHBaseItemSheet.#editFeature, + removeFeature: DHBaseItemSheet.#removeFeature + }, + dragDrop: [ + { dragSelector: null, dropSelector: '.tab.features .drop-section' }, + { dragSelector: '.feature-item', dropSelector: null } + ] }; /* -------------------------------------------- */ @@ -93,7 +99,9 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { const actionType = await DHBaseItemSheet.selectActionType(); if (!actionType) return; try { - const cls = actionsTypes[actionType] ?? actionsTypes.attack, + const cls = + game.system.api.models.actions.actionsTypes[actionType] ?? + game.system.api.models.actions.actionsTypes.attack, action = new cls( { _id: foundry.utils.randomID(), @@ -136,4 +144,90 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { 'system.actions': this.document.system.actions.filter((_, index) => index !== Number.parseInt(actionIndex)) }); } + + /** + * Add a new feature to the item, prompting the user for its type. + * @param {PointerEvent} _event - The originating click event + * @param {HTMLElement} _button - The capturing HTML element which defines the [data-action="addFeature"] + */ + static async #addFeature(_event, _button) { + const feature = await game.items.documentClass.create({ + type: 'feature', + name: game.i18n.format('DOCUMENT.New', { type: game.i18n.localize('TYPES.Item.feature') }) + }); + await this.document.update({ + 'system.features': [...this.document.system.features.filter(x => x).map(x => x.uuid), feature.uuid] + }); + } + + /** + * Edit an existing feature on the item + * @param {PointerEvent} _event - The originating click event + * @param {HTMLElement} button - The capturing HTML element which defines the [data-action="editFeature"] + */ + static async #editFeature(_event, button) { + const target = button.closest('.feature-item'); + const feature = this.document.system.features.find(x => x?.id === target.id); + if (!feature) { + ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.notifications.featureIsMissing')); + return; + } + + feature.sheet.render(true); + } + + /** + * Remove a feature from the item. + * @param {PointerEvent} event - The originating click event + * @param {HTMLElement} button - The capturing HTML element which defines the [data-action="removeFeature"] + */ + static async #removeFeature(event, button) { + event.stopPropagation(); + const target = button.closest('.feature-item'); + + await this.document.update({ + 'system.features': this.document.system.features + .filter(feature => feature && feature.id !== target.id) + .map(x => x.uuid) + }); + } + + /* -------------------------------------------- */ + /* Application Drag/Drop */ + /* -------------------------------------------- */ + + /** + * On dragStart on the item. + * @param {DragEvent} event - The drag event + */ + async _onDragStart(event) { + const featureItem = event.currentTarget.closest('.feature-item'); + + if (featureItem) { + const feature = this.document.system.features.find(x => x?.id === featureItem.id); + if (!feature) { + ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.notifications.featureIsMissing')); + return; + } + + const featureData = { type: 'Item', data: { ...feature.toObject(), _id: null }, fromInternal: true }; + event.dataTransfer.setData('text/plain', JSON.stringify(featureData)); + event.dataTransfer.setDragImage(featureItem.querySelector('img'), 60, 0); + } + } + + /** + * On drop on the item. + * @param {DragEvent} event - The drag event + */ + async _onDrop(event) { + const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); + if (data.fromInternal) return; + + const item = await fromUuid(data.uuid); + if (item?.type === 'feature') { + const current = this.document.system.features.map(x => x.uuid); + await this.document.update({ 'system.features': [...current, item.uuid] }); + } + } } diff --git a/module/applications/sheets/api/heritage-sheet.mjs b/module/applications/sheets/api/heritage-sheet.mjs index 4938f5b0..d9a63388 100644 --- a/module/applications/sheets/api/heritage-sheet.mjs +++ b/module/applications/sheets/api/heritage-sheet.mjs @@ -10,9 +10,9 @@ export default class DHHeritageSheet extends DHBaseItemSheet { static PARTS = { tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' }, description: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-description.hbs' }, - actions: { - template: 'systems/daggerheart/templates/sheets/global/tabs/tab-actions.hbs', - scrollable: ['.actions'] + feature: { + template: 'systems/daggerheart/templates/sheets/global/tabs/tab-features.hbs', + scrollable: ['.feature'] }, effects: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-effects.hbs', @@ -23,7 +23,7 @@ export default class DHHeritageSheet extends DHBaseItemSheet { /** @override*/ static TABS = { primary: { - tabs: [{ id: 'description' }, { id: 'actions' }, { id: 'effects' }], + tabs: [{ id: 'description' }, { id: 'features' }, { id: 'effects' }], initial: 'description', labelPrefix: 'DAGGERHEART.Sheets.TABS' } diff --git a/module/applications/sheets/items/beastform.mjs b/module/applications/sheets/items/beastform.mjs index 9ce9b739..f1be204a 100644 --- a/module/applications/sheets/items/beastform.mjs +++ b/module/applications/sheets/items/beastform.mjs @@ -3,12 +3,7 @@ import DHBaseItemSheet from '../api/base-item.mjs'; export default class BeastformSheet extends DHBaseItemSheet { /**@inheritdoc */ static DEFAULT_OPTIONS = { - classes: ['beastform'], - dragDrop: [{ dragSelector: null, dropSelector: '.drop-section' }], - actions: { - editFeature: this.editFeature, - removeFeature: this.removeFeature - } + classes: ['beastform'] }; /**@override */ @@ -40,26 +35,4 @@ export default class BeastformSheet extends DHBaseItemSheet { return context; } - - static editFeature(event) { - const target = event.target.closest('[data-action="editFeature"]'); - const feature = this.document.system.features[target.dataset.index]; - feature.sheet.render({ force: true }); - } - - static async removeFeature(_, target) { - const current = this.document.system.features.map(x => x.uuid); - await this.document.update({ - 'system.features': current.filter((_, index) => index !== Number(target.dataset.index)) - }); - } - - async _onDrop(event) { - const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); - const item = await fromUuid(data.uuid); - if (item.type === 'feature') { - const current = this.document.system.features.map(x => x.uuid); - await this.document.update({ 'system.features': [...current, item.uuid] }); - } - } } diff --git a/module/applications/sheets/items/class.mjs b/module/applications/sheets/items/class.mjs index 2ba17346..f1e11623 100644 --- a/module/applications/sheets/items/class.mjs +++ b/module/applications/sheets/items/class.mjs @@ -1,6 +1,4 @@ import DHBaseItemSheet from '../api/base-item.mjs'; -import DHActionConfig from '../../sheets-configs/action-config.mjs'; -import { actionsTypes } from '../../../data/action/_module.mjs'; const { TextEditor } = foundry.applications.ux; @@ -169,71 +167,45 @@ export default class ClassSheet extends DHBaseItemSheet { doc.sheet.render({ force: true }); } - //TODO: redo this - async selectActionType() { - const content = await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/actionTypes/actionType.hbs', - { types: CONFIG.DH.ACTIONS.actionTypes } - ), - title = 'Select Action Type', - type = 'form', - data = {}; - return Dialog.prompt({ - title, - label: title, - content, - type, - callback: html => { - const form = html[0].querySelector('form'), - fd = new foundry.applications.ux.FormDataExtended(form); - foundry.utils.mergeObject(data, fd.object, { inplace: true }); - - return data; - }, - rejectClose: false - }); - } - - //TODO: redo this getActionPath(type) { return type === 'hope' ? 'hopeFeatures' : 'classFeatures'; } - //TODO: redo this static async addFeature(_, target) { const actionPath = this.getActionPath(target.dataset.type); - const actionType = await this.selectActionType(); - const cls = actionsTypes[actionType?.type] ?? actionsTypes.attack, - action = new cls( - { - _id: foundry.utils.randomID(), - systemPath: actionPath, - type: actionType.type, - name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType.type].name), - ...cls.getSourceConfig(this.document) - }, - { - parent: this.document - } - ); - await this.document.update({ [`system.${actionPath}`]: [...this.document.system[actionPath], action] }); - } - - //TODO: redo this - static async editFeature(_, target) { - const action = this.document.system[this.getActionPath(target.dataset.type)].find( - x => x._id === target.dataset.feature - ); - await new DHActionConfig(action).render(true); - } - - //TODO: redo this - static async deleteFeature(_, target) { - const actionPath = this.getActionPath(target.dataset.type); + const feature = await game.items.documentClass.create({ + type: 'feature', + name: game.i18n.format('DOCUMENT.New', { type: game.i18n.localize('TYPES.Item.feature') }) + }); await this.document.update({ - [`system.${actionPath}`]: this.document.system[actionPath].filter( - action => action._id !== target.dataset.feature - ) + [`system.${actionPath}`]: [ + ...this.document.system[actionPath].filter(x => x).map(x => x.uuid), + feature.uuid + ] + }); + } + + static async editFeature(_, button) { + const target = button.closest('.feature-item'); + const actionPath = this.getActionPath(button.dataset.type); + const feature = this.document.system[actionPath].find(x => x?.id === target.dataset.featureId); + if (!feature) { + ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.notifications.featureIsMissing')); + return; + } + + feature.sheet.render(true); + } + + static async deleteFeature(event, button) { + event.stopPropagation(); + const target = button.closest('.feature-item'); + const actionPath = this.getActionPath(button.dataset.type); + + await this.document.update({ + [`system.${actionPath}`]: this.document.system[actionPath] + .filter(feature => feature && feature.id !== target.dataset.featureId) + .map(x => x.uuid) }); } } diff --git a/module/applications/sheets/items/feature.mjs b/module/applications/sheets/items/feature.mjs index a5b8bd8f..4f3bb438 100644 --- a/module/applications/sheets/items/feature.mjs +++ b/module/applications/sheets/items/feature.mjs @@ -1,3 +1,5 @@ +import { actionsTypes } from '../../../data/action/_module.mjs'; +import DHActionConfig from '../../sheets-configs/action-config.mjs'; import DHBaseItemSheet from '../api/base-item.mjs'; export default class FeatureSheet extends DHBaseItemSheet { @@ -6,7 +8,12 @@ export default class FeatureSheet extends DHBaseItemSheet { id: 'daggerheart-feature', classes: ['feature'], position: { height: 600 }, - window: { resizable: true } + window: { resizable: true }, + actions: { + addAction: FeatureSheet.#addAction, + editAction: FeatureSheet.#editAction, + removeAction: FeatureSheet.#removeAction + } }; /**@override */ @@ -41,4 +48,83 @@ export default class FeatureSheet extends DHBaseItemSheet { return context; } + + /* -------------------------------------------- */ + /* Application Clicks Actions */ + /* -------------------------------------------- */ + + /** + * Render a dialog prompting the user to select an action type. + * + * @returns {Promise} An object containing the selected action type. + */ + static async selectActionType() { + const content = await foundry.applications.handlebars.renderTemplate( + 'systems/daggerheart/templates/actionTypes/actionType.hbs', + { types: CONFIG.DH.ACTIONS.actionTypes } + ), + title = 'Select Action Type'; + + return foundry.applications.api.DialogV2.prompt({ + window: { title }, + content, + ok: { + label: title, + callback: (event, button, dialog) => button.form.elements.type.value + } + }); + } + + /** + * Add a new action to the item, prompting the user for its type. + * @param {PointerEvent} _event - The originating click event + * @param {HTMLElement} _button - The capturing HTML element which defines the [data-action="addAction"] + */ + static async #addAction(_event, _button) { + const actionType = await FeatureSheet.selectActionType(); + if (!actionType) return; + try { + const cls = actionsTypes[actionType] ?? actionsTypes.attack, + action = new cls( + { + _id: foundry.utils.randomID(), + type: actionType, + name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].name), + ...cls.getSourceConfig(this.document) + }, + { + parent: this.document + } + ); + await this.document.update({ 'system.actions': [...this.document.system.actions, action] }); + await new DHActionConfig(this.document.system.actions[this.document.system.actions.length - 1]).render({ + force: true + }); + } catch (error) { + console.log(error); + } + } + + /** + * Edit an existing action on the item + * @param {PointerEvent} _event - The originating click event + * @param {HTMLElement} button - The capturing HTML element which defines the [data-action="editAction"] + */ + static async #editAction(_event, button) { + const action = this.document.system.actions[button.dataset.index]; + await new DHActionConfig(action).render({ force: true }); + } + + /** + * Remove an action from the item. + * @param {PointerEvent} event - The originating click event + * @param {HTMLElement} button - The capturing HTML element which defines the [data-action="removeAction"] + */ + static async #removeAction(event, button) { + event.stopPropagation(); + const actionIndex = button.closest('[data-index]').dataset.index; + await this.document.update({ + 'system.actions': this.document.system.actions.filter((_, index) => index !== Number.parseInt(actionIndex)) + }); + } } diff --git a/module/applications/sheets/items/subclass.mjs b/module/applications/sheets/items/subclass.mjs index 3c70d84a..3509ebf1 100644 --- a/module/applications/sheets/items/subclass.mjs +++ b/module/applications/sheets/items/subclass.mjs @@ -1,6 +1,4 @@ import DHBaseItemSheet from '../api/base-item.mjs'; -import DHActionConfig from '../../sheets-configs/action-config.mjs'; -import { actionsTypes } from '../../../data/action/_module.mjs'; export default class SubclassSheet extends DHBaseItemSheet { /**@inheritdoc */ @@ -39,101 +37,63 @@ export default class SubclassSheet extends DHBaseItemSheet { } }; - //TODO redo everything below this message - - static addFeature(_, target) { - if (target.dataset.type === 'action') this.addAction(target.dataset.level); - else this.addEffect(target.dataset.level); - } - - static async editFeature(_, target) { - if (target.dataset.type === 'action') this.editAction(target.dataset.level, target.dataset.feature); - else this.editEffect(target.dataset.feature); - } - - static async deleteFeature(_, target) { - if (target.dataset.type === 'action') this.removeAction(target.dataset.level, target.dataset.feature); - else this.removeEffect(target.dataset.level, target.dataset.feature); - } - - async #selectActionType() { - const content = await foundry.applications.handlebars.renderTemplate( - 'systems/daggerheart/templates/actionTypes/actionType.hbs', - { types: CONFIG.DH.ACTIONS.actionTypes } - ), - title = 'Select Action Type', - type = 'form', - data = {}; - return Dialog.prompt({ - title, - label: title, - content, - type, - callback: html => { - const form = html[0].querySelector('form'), - fd = new foundry.applications.ux.FormDataExtended(form); - foundry.utils.mergeObject(data, fd.object, { inplace: true }); - return data; - }, - rejectClose: false + static async addFeature(_, target) { + const feature = await game.items.documentClass.create({ + type: 'feature', + name: game.i18n.format('DOCUMENT.New', { type: game.i18n.localize('TYPES.Item.feature') }) }); - } - - async addAction(level) { - const actionType = await this.#selectActionType(); - const cls = actionsTypes[actionType?.type] ?? actionsTypes.attack, - action = new cls( - { - _id: foundry.utils.randomID(), - systemPath: `${level}.actions`, - type: actionType.type, - name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType.type].name), - ...cls.getSourceConfig(this.document) - }, - { - parent: this.document - } - ); - await this.document.update({ [`system.${level}.actions`]: [...this.document.system[level].actions, action] }); - await new DHActionConfig( - this.document.system[level].actions[this.document.system[level].actions.length - 1] - ).render(true); - } - - async addEffect(level) { - const embeddedItems = await this.document.createEmbeddedDocuments('ActiveEffect', [ - { name: game.i18n.localize('DAGGERHEART.Feature.NewEffect') } - ]); await this.document.update({ - [`system.${level}.effects`]: [ - ...this.document.system[level].effects.map(x => x.uuid), - embeddedItems[0].uuid - ] + [`system.${target.dataset.type}`]: feature.uuid }); } - async editAction(level, id) { - const action = this.document.system[level].actions.find(x => x._id === id); - await new DHActionConfig(action).render(true); + static async editFeature(_, button) { + const feature = this.document.system[button.dataset.type]; + if (!feature) { + ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.notifications.featureIsMissing')); + return; + } + + feature.sheet.render(true); } - async editEffect(id) { - const effect = this.document.effects.get(id); - effect.sheet.render(true); - } + static async deleteFeature(event, button) { + event.stopPropagation(); - async removeAction(level, id) { await this.document.update({ - [`system.${level}.actions`]: this.document.system[level].actions.filter(action => action._id !== id) + [`system.${button.dataset.type}`]: null }); } - async removeEffect(level, id) { - await this.document.effects.get(id).delete(); - await this.document.update({ - [`system.${level}.effects`]: this.document.system[level].effects - .filter(x => x && x.id !== id) - .map(effect => effect.uuid) - }); + async _onDragStart(event) { + const featureItem = event.currentTarget.closest('.drop-section'); + + if (featureItem) { + const feature = this.document.system[featureItem.dataset.type]; + if (!feature) { + ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.notifications.featureIsMissing')); + return; + } + + const featureData = { type: 'Item', data: { ...feature.toObject(), _id: null }, fromInternal: true }; + event.dataTransfer.setData('text/plain', JSON.stringify(featureData)); + event.dataTransfer.setDragImage(featureItem.querySelector('img'), 60, 0); + } + } + + async _onDrop(event) { + const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); + if (data.fromInternal) return; + + const item = await fromUuid(data.uuid); + if (item?.type === 'feature') { + const dropSection = event.target.closest('.drop-section'); + if (this.document.system[dropSection.dataset.type]) { + ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.notifications.featureIsFull')); + return; + } + + await this.document.update({ [`system.${dropSection.dataset.type}`]: item.uuid }); + } } } diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs index 2c8ad561..8b09a643 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -156,8 +156,8 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo getTargetList = (event, message) => { const targetSelection = event.target - .closest('.message-content') - .querySelector('.button-target-selection.target-selected'), + .closest('.message-content') + .querySelector('.button-target-selection.target-selected'), isHit = Boolean(targetSelection.dataset.targetHit); return { isHit, @@ -255,7 +255,6 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo }); } - /** * Handle selecting an advantage and disable further selection. * @param {MouseEvent} event @@ -277,7 +276,6 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo }); } - abilityUseButton = async (event, message) => { event.stopPropagation(); diff --git a/module/applications/ux/filter-menu.mjs b/module/applications/ux/filter-menu.mjs index 93d8bbf0..bc9e2f81 100644 --- a/module/applications/ux/filter-menu.mjs +++ b/module/applications/ux/filter-menu.mjs @@ -199,11 +199,7 @@ export default class FilterMenu extends foundry.applications.ux.ContextMenu { const sort = arr => game.i18n.sortObjects(arr, 'name'); - return [ - ...sort(typesFilters, 'name'), - ...sort(burdenFilter, 'name'), - ...sort(damageTypeFilter, 'name') - ]; + return [...sort(typesFilters, 'name'), ...sort(burdenFilter, 'name'), ...sort(damageTypeFilter, 'name')]; } /** diff --git a/module/config/itemConfig.mjs b/module/config/itemConfig.mjs index 6d8488ba..b446bc28 100644 --- a/module/config/itemConfig.mjs +++ b/module/config/itemConfig.mjs @@ -656,31 +656,47 @@ export const weaponFeatures = { export const featureTypes = { ancestry: { id: 'ancestry', - label: 'DAGGERHEART.Feature.Type.ancestry' + label: 'TYPES.Item.ancestry' }, community: { id: 'community', - label: 'DAGGERHEART.Feature.Type.community' + label: 'TYPES.Item.community' + }, + companion: { + id: 'companion', + label: 'TYPES.Actor.companion' }, class: { id: 'class', - label: 'DAGGERHEART.Feature.Type.class' + label: 'TYPES.Item.class' }, subclass: { id: 'subclass', - label: 'DAGGERHEART.Feature.Type.subclass' - }, - classHope: { - id: 'classHope', - label: 'DAGGERHEART.Feature.Type.classHope' + label: 'TYPES.Item.subclass' }, domainCard: { id: 'domainCard', - label: 'DAGGERHEART.Feature.Type.domainCard' + label: 'TYPES.Item.domainCard' }, - equipment: { - id: 'equipment', - label: 'DAGGERHEART.Feature.Type.equipment' + armor: { + id: 'armor', + label: 'TYPES.Item.armor' + }, + weapon: { + id: 'weapon', + label: 'TYPES.Item.weapon' + }, + consumable: { + id: 'consumable', + label: 'TYPES.Item.consumable' + }, + miscellaneous: { + id: 'miscellaneous', + label: 'TYPES.Item.miscellaneous' + }, + beastform: { + if: 'beastform', + label: 'TYPES.Item.beastform' } }; diff --git a/module/data/actor/adversary.mjs b/module/data/actor/adversary.mjs index ec2b96eb..35d816c5 100644 --- a/module/data/actor/adversary.mjs +++ b/module/data/actor/adversary.mjs @@ -43,7 +43,6 @@ export default class DhpAdversary extends BaseDataActor { hitPoints: resourceField(), stress: resourceField() }), - actions: new fields.ArrayField(new ActionField()), attack: new ActionField({ initial: { name: 'Attack', @@ -86,4 +85,8 @@ export default class DhpAdversary extends BaseDataActor { get attackBonus() { return this.attack.roll.bonus; } + + get features() { + return this.parent.items.filter(x => x.type === 'feature'); + } } diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index d9ea6eef..f94ce7d1 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -97,7 +97,6 @@ export default class DhCharacter extends BaseDataActor { value: new ForeignDocumentUUIDField({ type: 'Item', nullable: true }), subclass: new ForeignDocumentUUIDField({ type: 'Item', nullable: true }) }), - actions: new fields.ArrayField(new ActionField()), levelData: new fields.EmbeddedDataField(DhLevelData), bonuses: new fields.SchemaField({ armorScore: new fields.NumberField({ integer: true, initial: 0 }), @@ -198,6 +197,68 @@ export default class DhCharacter extends BaseDataActor { return this.parent.items.find(x => x.type === 'armor' && x.system.equipped); } + get sheetLists() { + const ancestryFeatures = [], + communityFeatures = [], + classFeatures = [], + subclassFeatures = [], + companionFeatures = [], + features = []; + + for (let item of this.parent.items) { + if (item.system.type === CONFIG.DH.ITEM.featureTypes.ancestry.id) { + ancestryFeatures.push(item); + } else if (item.system.type === CONFIG.DH.ITEM.featureTypes.community.id) { + communityFeatures.push(item); + } else if (item.system.type === CONFIG.DH.ITEM.featureTypes.class.id) { + classFeatures.push(item); + } else if (item.system.type === CONFIG.DH.ITEM.featureTypes.subclass.id) { + const subclassState = this.class.subclass.system.featureState; + const identifier = item.system.identifier; + if ( + identifier === 'foundationFeature' || + (identifier === 'specializationFeature' && subclassState >= 2) || + (identifier === 'masterFeature' && subclassState >= 3) + ) { + subclassFeatures.push(item); + } + } else if (item.system.type === CONFIG.DH.ITEM.featureTypes.companion.id) { + companionFeatures.push(item); + } else if (item.type === 'feature' && !item.system.type) { + features.push(item); + } + } + + return { + ancestryFeatures: { + title: `${game.i18n.localize('TYPES.Item.ancestry')} - ${this.ancestry?.name}`, + type: 'ancestry', + values: ancestryFeatures + }, + communityFeatures: { + title: `${game.i18n.localize('TYPES.Item.community')} - ${this.community?.name}`, + type: 'community', + values: communityFeatures + }, + classFeatures: { + title: `${game.i18n.localize('TYPES.Item.class')} - ${this.class.value?.name}`, + type: 'class', + values: classFeatures + }, + subclassFeatures: { + title: `${game.i18n.localize('TYPES.Item.subclass')} - ${this.class.subclass?.name}`, + type: 'subclass', + values: subclassFeatures + }, + companionFeatures: { + title: game.i18n.localize('DAGGERHEART.Sheets.PC.CompanionFeatures'), + type: 'companion', + values: companionFeatures + }, + features: { title: game.i18n.localize('DAGGERHEART.Sheets.PC.Features'), type: 'feature', values: features } + }; + } + get primaryWeapon() { return this.parent.items.find(x => x.type === 'weapon' && x.system.equipped && !x.system.secondary); } diff --git a/module/data/actor/environment.mjs b/module/data/actor/environment.mjs index db75612b..58bdc695 100644 --- a/module/data/actor/environment.mjs +++ b/module/data/actor/environment.mjs @@ -30,8 +30,11 @@ export default class DhEnvironment extends BaseDataActor { adversaries: new ForeignDocumentUUIDArrayField({ type: 'Actor' }) }) ), - actions: new fields.ArrayField(new ActionField()), notes: new fields.HTMLField() }; } + + get features() { + return this.parent.items.filter(x => x.type === 'feature'); + } } diff --git a/module/data/item/ancestry.mjs b/module/data/item/ancestry.mjs index 8af6e081..463fe6c1 100644 --- a/module/data/item/ancestry.mjs +++ b/module/data/item/ancestry.mjs @@ -1,4 +1,4 @@ -import ActionField from '../fields/actionField.mjs'; +import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs'; import BaseDataItem from './base.mjs'; export default class DHAncestry extends BaseDataItem { @@ -13,10 +13,9 @@ export default class DHAncestry extends BaseDataItem { /** @inheritDoc */ static defineSchema() { - const fields = foundry.data.fields; return { ...super.defineSchema(), - actions: new fields.ArrayField(new ActionField()) + features: new ForeignDocumentUUIDArrayField({ type: 'Item' }) }; } } diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs index 7bef3e02..1a250327 100644 --- a/module/data/item/base.mjs +++ b/module/data/item/base.mjs @@ -1,5 +1,3 @@ -import { actionsTypes } from '../action/_module.mjs'; - /** * Describes metadata about the item data model type * @typedef {Object} ItemDataModelMetadata @@ -61,8 +59,8 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { if (!this.constructor.metadata.hasInitialAction || !foundry.utils.isEmpty(this.actions)) return; const metadataType = this.constructor.metadata.type; - const actionType = { weapon: "attack" }[metadataType]; - const ActionClass = actionsTypes[actionType]; + const actionType = { weapon: 'attack' }[metadataType]; + const ActionClass = game.system.api.models.actions.actionsTypes[actionType]; const action = new ActionClass( { @@ -79,4 +77,31 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { this.updateSource({ actions: [action] }); } + _onCreate(data) { + if (!this.actor || this.actor.type !== 'character' || !this.features) return; + + this.actor.createEmbeddedDocuments( + 'Item', + this.features.map(feature => ({ + ...feature, + system: { + ...feature.system, + type: this.parent.type, + originId: data._id, + identifier: feature.identifier + } + })) + ); + } + + async _preDelete() { + if (!this.actor || this.actor.type !== 'character') return; + + const items = this.actor.items.filter(item => item.system.originId === this.parent.id); + if (items.length > 0) + await this.actor.deleteEmbeddedDocuments( + 'Item', + items.map(x => x.id) + ); + } } diff --git a/module/data/item/beastform.mjs b/module/data/item/beastform.mjs index b069f910..2f50ab21 100644 --- a/module/data/item/beastform.mjs +++ b/module/data/item/beastform.mjs @@ -39,10 +39,7 @@ export default class DHBeastform extends BaseDataItem { }; } - async _preCreate(data, options, user) { - const allowed = await super._preCreate(data, options, user); - if (allowed === false) return; - + async _preCreate() { if (!this.actor) return; if (this.actor.type !== 'character') { diff --git a/module/data/item/class.mjs b/module/data/item/class.mjs index 46ec6ff8..ad0d8082 100644 --- a/module/data/item/class.mjs +++ b/module/data/item/class.mjs @@ -1,7 +1,6 @@ import BaseDataItem from './base.mjs'; import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs'; import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs'; -import ActionField from '../fields/actionField.mjs'; export default class DHClass extends BaseDataItem { /** @inheritDoc */ @@ -28,8 +27,8 @@ export default class DHClass extends BaseDataItem { label: 'DAGGERHEART.Sheets.Class.HitPoints' }), evasion: new fields.NumberField({ initial: 0, integer: true, label: 'DAGGERHEART.Sheets.Class.Evasion' }), - hopeFeatures: new foundry.data.fields.ArrayField(new ActionField()), - classFeatures: new foundry.data.fields.ArrayField(new ActionField()), + hopeFeatures: new ForeignDocumentUUIDArrayField({ type: 'Item' }), + classFeatures: new ForeignDocumentUUIDArrayField({ type: 'Item' }), subclasses: new ForeignDocumentUUIDArrayField({ type: 'Item', required: false }), inventory: new fields.SchemaField({ take: new ForeignDocumentUUIDArrayField({ type: 'Item', required: false }), @@ -57,6 +56,10 @@ export default class DHClass extends BaseDataItem { return this.hopeFeatures.length > 0 ? this.hopeFeatures[0] : null; } + get features() { + return [...this.hopeFeatures.filter(x => x), ...this.classFeatures.filter(x => x)]; + } + async _preCreate(data, options, user) { const allowed = await super._preCreate(data, options, user); if (allowed === false) return; diff --git a/module/data/item/community.mjs b/module/data/item/community.mjs index d0ede69a..b2827242 100644 --- a/module/data/item/community.mjs +++ b/module/data/item/community.mjs @@ -1,4 +1,4 @@ -import ActionField from '../fields/actionField.mjs'; +import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs'; import BaseDataItem from './base.mjs'; export default class DHCommunity extends BaseDataItem { @@ -16,7 +16,7 @@ export default class DHCommunity extends BaseDataItem { const fields = foundry.data.fields; return { ...super.defineSchema(), - actions: new fields.ArrayField(new ActionField()) + features: new ForeignDocumentUUIDArrayField({ type: 'Item' }) }; } } diff --git a/module/data/item/feature.mjs b/module/data/item/feature.mjs index 85a9c42f..a5b5cb3c 100644 --- a/module/data/item/feature.mjs +++ b/module/data/item/feature.mjs @@ -16,6 +16,9 @@ export default class DHFeature extends BaseDataItem { const fields = foundry.data.fields; return { ...super.defineSchema(), + type: new fields.StringField({ choices: CONFIG.DH.ITEM.featureTypes, nullable: true, initial: null }), + originId: new fields.StringField({ nullable: true, initial: null }), + identifier: new fields.StringField(), actions: new fields.ArrayField(new ActionField()) }; } diff --git a/module/data/item/subclass.mjs b/module/data/item/subclass.mjs index 8590468e..eac1b288 100644 --- a/module/data/item/subclass.mjs +++ b/module/data/item/subclass.mjs @@ -1,15 +1,6 @@ -import ActionField from '../fields/actionField.mjs'; -import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs'; +import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs'; import BaseDataItem from './base.mjs'; -const featureSchema = () => { - return new foundry.data.fields.SchemaField({ - name: new foundry.data.fields.StringField({ required: true }), - effects: new ForeignDocumentUUIDArrayField({ type: 'ActiveEffect', required: false }), - actions: new foundry.data.fields.ArrayField(new ActionField()) - }); -}; - export default class DHSubclass extends BaseDataItem { /** @inheritDoc */ static get metadata() { @@ -31,20 +22,20 @@ export default class DHSubclass extends BaseDataItem { nullable: true, initial: null }), - foundationFeature: featureSchema(), - specializationFeature: featureSchema(), - masteryFeature: featureSchema(), + foundationFeature: new ForeignDocumentUUIDField({ type: 'Item' }), + specializationFeature: new ForeignDocumentUUIDField({ type: 'Item' }), + masteryFeature: new ForeignDocumentUUIDField({ type: 'Item' }), featureState: new fields.NumberField({ required: true, initial: 1, min: 1 }), isMulticlass: new fields.BooleanField({ initial: false }) }; } get features() { - return { - foundation: this.foundationFeature, - specialization: this.featureState >= 2 ? this.specializationFeature : null, - mastery: this.featureState === 3 ? this.masteryFeature : null - }; + return [ + { ...this.foundationFeature.toObject(), identifier: 'foundationFeature' }, + { ...this.specializationFeature.toObject(), identifier: 'specializationFeature' }, + { ...this.masteryFeature.toObject(), identifier: 'masteryFeature' } + ]; } async _preCreate(data, options, user) { diff --git a/module/data/item/weapon.mjs b/module/data/item/weapon.mjs index 30bed1e0..e6cfcbf0 100644 --- a/module/data/item/weapon.mjs +++ b/module/data/item/weapon.mjs @@ -1,4 +1,5 @@ import BaseDataItem from './base.mjs'; +import { actionsTypes } from '../action/_module.mjs'; import ActionField from '../fields/actionField.mjs'; export default class DHWeapon extends BaseDataItem { @@ -56,20 +57,20 @@ export default class DHWeapon extends BaseDataItem { const allowed = await super._preUpdate(changes, options, user); if (allowed === false) return false; - if (changes.system.features) { + if (changes.system?.features) { const removed = this.features.filter(x => !changes.system.features.includes(x)); const added = changes.system.features.filter(x => !this.features.includes(x)); - for (var feature of removed) { - for (var effectId of feature.effectIds) { + for (let weaponFeature of removed) { + for (var effectId of weaponFeature.effectIds) { await this.parent.effects.get(effectId).delete(); } - changes.system.actions = this.actions.filter(x => !feature.actionIds.includes(x._id)); + changes.system.actions = this.actions.filter(x => !weaponFeature.actionIds.includes(x._id)); } - for (var feature of added) { - const featureData = CONFIG.DH.ITEM.weaponFeatures[feature.value]; + for (let weaponFeature of added) { + const featureData = CONFIG.DH.ITEM.weaponFeatures[weaponFeature.value]; if (featureData.effects?.length > 0) { const embeddedItems = await this.parent.createEmbeddedDocuments('ActiveEffect', [ { @@ -78,18 +79,18 @@ export default class DHWeapon extends BaseDataItem { changes: featureData.effects.flatMap(x => x.changes) } ]); - feature.effectIds = embeddedItems.map(x => x.id); + weaponFeature.effectIds = embeddedItems.map(x => x.id); } if (featureData.actions?.length > 0) { const newActions = featureData.actions.map(action => { - const cls = CONFIG.DH.ACTIONS.actionsTypes[action.type]; + const cls = actionsTypes[action.type]; return new cls( { ...action, _id: foundry.utils.randomID(), name: game.i18n.localize(action.name) }, { parent: this } ); }); changes.system.actions = [...this.actions, ...newActions]; - feature.actionIds = newActions.map(x => x._id); + weaponFeature.actionIds = newActions.map(x => x._id); } } } diff --git a/module/dice/d20Roll.mjs b/module/dice/d20Roll.mjs index b36c0884..fab2c06d 100644 --- a/module/dice/d20Roll.mjs +++ b/module/dice/d20Roll.mjs @@ -143,7 +143,6 @@ export default class D20Roll extends DHRoll { : config.roll.advantage == this.ADV_MODE.DISADVANTAGE ? false : null; - setDiceSoNiceForDualityRoll(roll, advantageState); this.postEvaluate(roll, config); } diff --git a/module/helpers/handlebarsHelper.mjs b/module/helpers/handlebarsHelper.mjs index 99c1ec84..6db51225 100644 --- a/module/helpers/handlebarsHelper.mjs +++ b/module/helpers/handlebarsHelper.mjs @@ -8,7 +8,7 @@ export default class RegisterHandlebarsHelpers { add: this.add, subtract: this.subtract, includes: this.includes, - case: this.case, + case: this.case }); } @@ -34,12 +34,10 @@ export default class RegisterHandlebarsHelpers { return (Number.isNaN(aNum) ? 0 : aNum) - (Number.isNaN(bNum) ? 0 : bNum); } - static includes(list, item) { return list.includes(item); } - static case(value, options) { if (value == this.switch_value) { this.switch_break = true; diff --git a/module/systemRegistration/handlebars.mjs b/module/systemRegistration/handlebars.mjs index 4c2f7f1d..75a5aff6 100644 --- a/module/systemRegistration/handlebars.mjs +++ b/module/systemRegistration/handlebars.mjs @@ -5,8 +5,6 @@ export const preloadHandlebarsTemplates = async function () { 'systems/daggerheart/templates/sheets/global/partials/action-item.hbs', 'systems/daggerheart/templates/sheets/global/partials/domain-card-item.hbs', 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs', - 'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-features.hbs', - 'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-feature.hbs', 'systems/daggerheart/templates/components/card-preview.hbs', 'systems/daggerheart/templates/levelup/parts/selectable-card-preview.hbs', 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs', diff --git a/styles/daggerheart.css b/styles/daggerheart.css index ec100a38..fcae3193 100755 --- a/styles/daggerheart.css +++ b/styles/daggerheart.css @@ -2099,74 +2099,6 @@ div.daggerheart.views.multiclass { .daggerheart.views.roll-selection #roll-selection-costSelection footer { display: none; } -.daggerheart.views.roll-selection .roll-dialog-container .disadvantage, -.daggerheart.views.roll-selection .roll-dialog-container .advantage { - border: 2px solid #708090; - border-radius: 6px; - display: flex; - align-items: center; - padding: 4px; - margin-bottom: 6px; -} -.daggerheart.views.roll-selection .roll-dialog-container .disadvantage.selected, -.daggerheart.views.roll-selection .roll-dialog-container .advantage.selected { - filter: drop-shadow(0px 0px 3px red); -} -.daggerheart.views.roll-selection .roll-dialog-container .disadvantage input, -.daggerheart.views.roll-selection .roll-dialog-container .advantage input { - border: 0; -} -.daggerheart.views.roll-selection .roll-dialog-container .disadvantage button, -.daggerheart.views.roll-selection .roll-dialog-container .advantage button { - flex: 0; - border-radius: 50%; - height: 20px; - width: 20px; - display: flex; - align-items: center; - justify-content: center; - margin: 2px 0 2px 4px; - padding: 12px; -} -.daggerheart.views.roll-selection .roll-dialog-container .disadvantage button i, -.daggerheart.views.roll-selection .roll-dialog-container .advantage button i { - margin: 0; -} -.daggerheart.views.roll-selection .roll-dialog-container .roll-dialog-experience-container { - display: flex; - align-items: center; - flex-wrap: wrap; - gap: 4px; -} -.daggerheart.views.roll-selection .roll-dialog-container .roll-dialog-experience-container .roll-dialog-chip { - border: 1px solid black; - border-radius: 6px; - min-width: calc(33% - 2px); - flex: 1; - display: flex; - align-items: center; - justify-content: center; - gap: 4px; - cursor: pointer; - padding: 4px; - background: grey; - overflow: hidden; - font-weight: bold; -} -.daggerheart.views.roll-selection .roll-dialog-container .roll-dialog-experience-container .roll-dialog-chip.hover { - filter: drop-shadow(0 0 3px red); -} -.daggerheart.views.roll-selection .roll-dialog-container .roll-dialog-experience-container .roll-dialog-chip span { - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; -} -.daggerheart.views.roll-selection .roll-dialog-container .roll-dialog-experience-container .roll-dialog-chip.selected { - background: green; -} -.daggerheart.views.roll-selection .roll-dialog-container .roll-dialog-experience-container .roll-dialog-chip.selected span { - filter: drop-shadow(0 0 3px gold); -} .daggerheart.views.roll-selection .roll-dialog-container .hope-container { display: flex; gap: 8px; @@ -2217,25 +2149,6 @@ div.daggerheart.views.multiclass { .daggerheart.views.npc-roll-selection .npc-roll-dialog-container .selection-container .dice-container .advantage-container .advantage-button:hover { background: var(--button-hover-background-color); } -.daggerheart.views.npc-roll-selection .npc-roll-dialog-container .roll-dialog-experience-container { - display: flex; - align-items: flex-start; - flex-wrap: wrap; - gap: 4px; - flex: 1; - height: 100%; -} -.daggerheart.views.npc-roll-selection .npc-roll-dialog-container .roll-dialog-experience-container .experience-chip { - opacity: 0.6; - border-radius: 16px; - width: calc(50% - 4px); - white-space: nowrap; -} -.daggerheart.views.npc-roll-selection .npc-roll-dialog-container .roll-dialog-experience-container .experience-chip.active, -.daggerheart.views.npc-roll-selection .npc-roll-dialog-container .roll-dialog-experience-container .experience-chip:hover { - opacity: 1; - background: var(--button-hover-background-color); -} .daggerheart.views.multiclass .multiclass-container { margin-bottom: 16px; } @@ -3708,16 +3621,16 @@ div.daggerheart.views.multiclass { .daggerheart.dh-style.setting .trait-array-container .trait-array-item input { text-align: center; } -.themed.theme-dark .application.sheet.dh-style .character-header-sheet .trait, -.themed.theme-dark.application.sheet.dh-style .character-header-sheet .trait, -body.theme-dark .application .character-header-sheet .trait, -body.theme-dark.application .character-header-sheet .trait { +.themed.theme-dark .application.daggerheart.sheet.dh-style .character-header-sheet .trait, +.themed.theme-dark.application.daggerheart.sheet.dh-style .character-header-sheet .trait, +body.theme-dark .application.daggerheart .character-header-sheet .trait, +body.theme-dark.application.daggerheart .character-header-sheet .trait { background: url(../assets/svg/trait-shield.svg) no-repeat; } -.themed.theme-light .application.sheet.dh-style .character-header-sheet .trait, -.themed.theme-light.application.sheet.dh-style .character-header-sheet .trait, -body.theme-light .application .character-header-sheet .trait, -body.theme-light.application .character-header-sheet .trait { +.themed.theme-light .application.daggerheart.sheet.dh-style .character-header-sheet .trait, +.themed.theme-light.application.daggerheart.sheet.dh-style .character-header-sheet .trait, +body.theme-light .application.daggerheart .character-header-sheet .trait, +body.theme-light.application.daggerheart .character-header-sheet .trait { background: url('../assets/svg/trait-shield-light.svg') no-repeat; } .application.sheet.daggerheart.actor.dh-style.character .character-header-sheet { @@ -3880,28 +3793,28 @@ body.theme-light.application .character-header-sheet .trait { font-size: 20px; text-align: center; } -.themed.theme-dark .application.sheet.dh-style .character-sidebar-sheet, -.themed.theme-dark.application.sheet.dh-style .character-sidebar-sheet, -body.theme-dark .application .character-sidebar-sheet, -body.theme-dark.application .character-sidebar-sheet { +.themed.theme-dark .application.daggerheart.sheet.dh-style .character-sidebar-sheet, +.themed.theme-dark.application.daggerheart.sheet.dh-style .character-sidebar-sheet, +body.theme-dark .application.daggerheart .character-sidebar-sheet, +body.theme-dark.application.daggerheart .character-sidebar-sheet { background-image: url('../assets/parchments/dh-parchment-dark.png'); } -.themed.theme-dark .application.sheet.dh-style .character-sidebar-sheet .experience-value, -.themed.theme-dark.application.sheet.dh-style .character-sidebar-sheet .experience-value, -body.theme-dark .application .character-sidebar-sheet .experience-value, -body.theme-dark.application .character-sidebar-sheet .experience-value { +.themed.theme-dark .application.daggerheart.sheet.dh-style .character-sidebar-sheet .experience-value, +.themed.theme-dark.application.daggerheart.sheet.dh-style .character-sidebar-sheet .experience-value, +body.theme-dark .application.daggerheart .character-sidebar-sheet .experience-value, +body.theme-dark.application.daggerheart .character-sidebar-sheet .experience-value { background: url(../assets/svg/experience-shield.svg) no-repeat; } -.themed.theme-light .application.sheet.dh-style .character-sidebar-sheet, -.themed.theme-light.application.sheet.dh-style .character-sidebar-sheet, -body.theme-light .application .character-sidebar-sheet, -body.theme-light.application .character-sidebar-sheet { +.themed.theme-light .application.daggerheart.sheet.dh-style .character-sidebar-sheet, +.themed.theme-light.application.daggerheart.sheet.dh-style .character-sidebar-sheet, +body.theme-light .application.daggerheart .character-sidebar-sheet, +body.theme-light.application.daggerheart .character-sidebar-sheet { background: transparent; } -.themed.theme-light .application.sheet.dh-style .character-sidebar-sheet .experience-value, -.themed.theme-light.application.sheet.dh-style .character-sidebar-sheet .experience-value, -body.theme-light .application .character-sidebar-sheet .experience-value, -body.theme-light.application .character-sidebar-sheet .experience-value { +.themed.theme-light .application.daggerheart.sheet.dh-style .character-sidebar-sheet .experience-value, +.themed.theme-light.application.daggerheart.sheet.dh-style .character-sidebar-sheet .experience-value, +body.theme-light .application.daggerheart .character-sidebar-sheet .experience-value, +body.theme-light.application.daggerheart .character-sidebar-sheet .experience-value { background: url('../assets/svg/experience-shield-light.svg') no-repeat; } .application.sheet.dh-style .character-sidebar-sheet { @@ -4825,16 +4738,16 @@ body.theme-light.application .character-sidebar-sheet .experience-value { align-items: center; padding: 0 20px; } -.themed.theme-dark .application.sheet.dh-style.environment, -.themed.theme-dark.application.sheet.dh-style.environment, -body.theme-dark .application.environment, -body.theme-dark.application.environment { +.themed.theme-dark .application.daggerheart.sheet.dh-style.environment, +.themed.theme-dark.application.daggerheart.sheet.dh-style.environment, +body.theme-dark .application.daggerheart.environment, +body.theme-dark.application.daggerheart.environment { background-image: url('../assets/parchments/dh-parchment-dark.png'); } -.themed.theme-light .application.sheet.dh-style.environment, -.themed.theme-light.application.sheet.dh-style.environment, -body.theme-light .application.environment, -body.theme-light.application.environment { +.themed.theme-light .application.daggerheart.sheet.dh-style.environment, +.themed.theme-light.application.daggerheart.sheet.dh-style.environment, +body.theme-light .application.daggerheart.environment, +body.theme-light.application.daggerheart.environment { background: url('../assets/parchments/dh-parchment-light.png'); } .application.sheet.daggerheart.actor.dh-style.environment .tab { @@ -4884,122 +4797,78 @@ body.theme-light.application.environment { .application.daggerheart.dh-style.dialog .tab.experiences .experience-list .experience-item a { text-align: center; } -.application.daggerheart.dh-style.dialog .tab.actions { +.application.daggerheart.dh-style.dialog .tab.features { max-height: 450px; overflow-y: auto; scrollbar-width: thin; scrollbar-color: light-dark(#18162e, #f3c267) transparent; } -.application.daggerheart.dh-style.dialog .tab.actions .add-action-btn { +.application.daggerheart.dh-style.dialog .tab.features .add-feature-btn { width: 100%; margin-bottom: 12px; } -.application.daggerheart.dh-style.dialog .tab.actions .action-list { +.application.daggerheart.dh-style.dialog .tab.features .feature-list { display: flex; flex-direction: column; gap: 10px; } -.application.daggerheart.dh-style.dialog .tab.actions .action-list .action-item { +.application.daggerheart.dh-style.dialog .tab.features .feature-list .feature-item { display: grid; grid-template-columns: 40px 1fr auto; align-items: center; gap: 5px; border-radius: 3px; } -.application.daggerheart.dh-style.dialog .tab.actions .action-list .action-item img { +.application.daggerheart.dh-style.dialog .tab.features .feature-list .feature-item img { height: 40px; width: 40px; object-fit: cover; } -.application.daggerheart.dh-style.dialog .tab.actions .action-list .action-item .label { +.application.daggerheart.dh-style.dialog .tab.features .feature-list .feature-item .label { font-family: 'Montserrat', sans-serif; } -.application.daggerheart.dh-style.dialog .tab.actions .action-list .action-item .label .tags { - display: flex; - gap: 10px; -} -.application.daggerheart.dh-style.dialog .tab.actions .action-list .action-item .label .tags .tag { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - padding: 3px 5px; - font-size: 12px; - background: light-dark(#22222215, #efe6d815); - border: 1px solid light-dark(#222, #efe6d8); - border-radius: 3px; -} -.application.daggerheart.dh-style.dialog .tab.actions .action-list .action-item .label .tags .label { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - font-size: 12px; -} -.application.daggerheart.dh-style.dialog .tab.actions .action-list .action-item .controls { +.application.daggerheart.dh-style.dialog .tab.features .feature-list .feature-item .controls { display: flex; gap: 5px; } -.application.daggerheart.dh-style.dialog .tab.actions .action-list .action-item .controls a { +.application.daggerheart.dh-style.dialog .tab.features .feature-list .feature-item .controls a { text-align: center; } -.application.daggerheart.dh-style.dialog.environment-settings .tab.actions { +.application.daggerheart.dh-style.dialog.environment-settings .tab.features { max-height: 450px; overflow-y: auto; scrollbar-width: thin; scrollbar-color: light-dark(#18162e, #f3c267) transparent; } -.application.daggerheart.dh-style.dialog.environment-settings .tab.actions .add-action-btn { +.application.daggerheart.dh-style.dialog.environment-settings .tab.features .add-feature-btn { width: 100%; margin-bottom: 12px; } -.application.daggerheart.dh-style.dialog.environment-settings .tab.actions .action-list { +.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list { display: flex; flex-direction: column; gap: 10px; } -.application.daggerheart.dh-style.dialog.environment-settings .tab.actions .action-list .action-item { +.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list .feature-item { display: grid; grid-template-columns: 40px 1fr auto; align-items: center; gap: 5px; } -.application.daggerheart.dh-style.dialog.environment-settings .tab.actions .action-list .action-item img { +.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list .feature-item img { height: 40px; width: 40px; object-fit: cover; border-radius: 3px; } -.application.daggerheart.dh-style.dialog.environment-settings .tab.actions .action-list .action-item .label { +.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list .feature-item .label { font-family: 'Montserrat', sans-serif; } -.application.daggerheart.dh-style.dialog.environment-settings .tab.actions .action-list .action-item .label .tags { - display: flex; - gap: 10px; -} -.application.daggerheart.dh-style.dialog.environment-settings .tab.actions .action-list .action-item .label .tags .tag { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - padding: 3px 5px; - font-size: 12px; - background: light-dark(#22222215, #efe6d815); - border: 1px solid light-dark(#222, #efe6d8); - border-radius: 3px; -} -.application.daggerheart.dh-style.dialog.environment-settings .tab.actions .action-list .action-item .label .tags .label { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - font-size: 12px; -} -.application.daggerheart.dh-style.dialog.environment-settings .tab.actions .action-list .action-item .controls { +.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list .feature-item .controls { display: flex; gap: 5px; } -.application.daggerheart.dh-style.dialog.environment-settings .tab.actions .action-list .action-item .controls a { +.application.daggerheart.dh-style.dialog.environment-settings .tab.features .feature-list .feature-item .controls a { text-align: center; } .application.daggerheart.dh-style.dialog .tab.adversaries { @@ -5326,16 +5195,16 @@ body.theme-light.application.environment { .theme-light .application.sheet.daggerheart.actor.dh-style.companion .experience-list .experience-value { background: url('../assets/svg/experience-shield-light.svg') no-repeat; } -.themed.theme-dark .application.sheet.dh-style.companion, -.themed.theme-dark.application.sheet.dh-style.companion, -body.theme-dark .application.companion, -body.theme-dark.application.companion { +.themed.theme-dark .application.daggerheart.sheet.dh-style.companion, +.themed.theme-dark.application.daggerheart.sheet.dh-style.companion, +body.theme-dark .application.daggerheart.companion, +body.theme-dark.application.daggerheart.companion { background-image: url('../assets/parchments/dh-parchment-dark.png'); } -.themed.theme-light .application.sheet.dh-style.companion, -.themed.theme-light.application.sheet.dh-style.companion, -body.theme-light .application.companion, -body.theme-light.application.companion { +.themed.theme-light .application.daggerheart.sheet.dh-style.companion, +.themed.theme-light.application.daggerheart.sheet.dh-style.companion, +body.theme-light .application.daggerheart.companion, +body.theme-light.application.daggerheart.companion { background: url('../assets/parchments/dh-parchment-light.png'); } .application.sheet.daggerheart.actor.dh-style.adversary .window-content { @@ -5420,6 +5289,111 @@ body.theme-light.application.companion { justify-content: center; gap: 10px; } +.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container { + display: flex; + flex-direction: column; + gap: 12px; +} +.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .dices-section { + display: flex; + gap: 60px; + justify-content: center; +} +.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .dices-section .dice-option { + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; + width: 120px; +} +.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .dices-section .dice-option .dice-icon { + width: 70px; + height: 70px; + object-fit: contain; +} +.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .dices-section .dice-option .dice-select { + display: flex; + align-items: center; + gap: 10px; + height: 32px; +} +.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .dices-section .dice-option .dice-select .label { + font-family: 'Cinzel', serif; + font-style: normal; + font-weight: 700; + font-size: 16px; + line-height: 19px; + color: light-dark(#222, #efe6d8); +} +.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .experience-container { + display: flex; + gap: 10px; + flex-wrap: wrap; +} +.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .experience-container .experience-chip { + display: flex; + align-items: center; + border-radius: 5px; + width: fit-content; + gap: 5px; + cursor: pointer; + padding: 5px; + background: light-dark(#18162e10, #f3c26710); + color: light-dark(#18162e, #f3c267); +} +.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .experience-container .experience-chip .label { + font-family: 'Montserrat', sans-serif; + font-style: normal; + font-weight: 400; + font-size: 14px; + line-height: 17px; +} +.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .experience-container .experience-chip.selected { + background: light-dark(#18162e40, #f3c26740); +} +.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .advantage-chip, +.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .disadvantage-chip { + display: flex; + align-items: center; + border-radius: 5px; + width: fit-content; + gap: 5px; + cursor: pointer; + padding: 5px; + transition: all 0.3s ease; +} +.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .advantage-chip .label, +.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .disadvantage-chip .label { + font-family: 'Montserrat', sans-serif; + font-style: normal; + font-weight: 400; + font-size: 14px; + line-height: 17px; +} +.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .advantage-chip { + background: #40a64010; + color: #40a640; +} +.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .advantage-chip.selected { + color: #efe6d8; + background: linear-gradient(151.21deg, #40a640 7.21%, #011b01 92.79%); +} +.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .disadvantage-chip { + background: #e54e4e10; + color: #e54e4e; +} +.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .modifier-container .disadvantage-chip.selected { + color: #efe6d8; + background: linear-gradient(151.21deg, #e54e4e 7.21%, #3c0000 92.79%); +} +.application.daggerheart.dialog.dh-style.views.roll-selection .roll-dialog-container .formula-label { + font-family: 'Montserrat', sans-serif; + font-style: normal; + font-weight: 500; + font-size: 14px; + line-height: 17px; + color: light-dark(#222, #efe6d8); +} @keyframes glow { 0% { box-shadow: 0 0 1px 1px #f3c267; @@ -5513,17 +5487,17 @@ body.theme-light.application.companion { * @param {Rules} @darkRules - Styles to apply when `.theme-dark` is present * @param {Rules} @lightRules - Styles to apply when `.theme-light` is present */ -.themed.theme-dark .application.sheet.dh-style, -.themed.theme-dark.application.sheet.dh-style, -body.theme-dark .application, -body.theme-dark.application { +.themed.theme-dark .application.daggerheart.sheet.dh-style, +.themed.theme-dark.application.daggerheart.sheet.dh-style, +body.theme-dark .application.daggerheart, +body.theme-dark.application.daggerheart { background: rgba(24, 22, 46, 0.33); backdrop-filter: blur(9px); } -.themed.theme-light .application.sheet.dh-style, -.themed.theme-light.application.sheet.dh-style, -body.theme-light .application, -body.theme-light.application { +.themed.theme-light .application.daggerheart.sheet.dh-style, +.themed.theme-light.application.daggerheart.sheet.dh-style, +body.theme-light .application.daggerheart, +body.theme-light.application.daggerheart { background: url('../assets/parchments/dh-parchment-light.png') no-repeat center; } .application.sheet.dh-style { @@ -5571,18 +5545,18 @@ body.theme-light.application { .application.sheet.dh-style:not(.minimized) .window-content { opacity: 1; } -.themed.theme-dark .application.sheet.dh-style.dialog, -.themed.theme-dark.application.sheet.dh-style.dialog, -body.theme-dark .application.dialog, -body.theme-dark.application.dialog { +.themed.theme-dark .application.daggerheart.sheet.dh-style.dialog, +.themed.theme-dark.application.daggerheart.sheet.dh-style.dialog, +body.theme-dark .application.daggerheart.dialog, +body.theme-dark.application.daggerheart.dialog { background-image: url('../assets/parchments/dh-parchment-dark.png'); background-repeat: no-repeat; background-position: center; } -.themed.theme-light .application.sheet.dh-style.dialog, -.themed.theme-light.application.sheet.dh-style.dialog, -body.theme-light .application.dialog, -body.theme-light.application.dialog { +.themed.theme-light .application.daggerheart.sheet.dh-style.dialog, +.themed.theme-light.application.daggerheart.sheet.dh-style.dialog, +body.theme-light .application.daggerheart.dialog, +body.theme-light.application.daggerheart.dialog { background-image: url('../assets/parchments/dh-parchment-light.png'); background-repeat: no-repeat; background-position: center; diff --git a/styles/daggerheart.less b/styles/daggerheart.less index c6d43ae8..ebecdc95 100755 --- a/styles/daggerheart.less +++ b/styles/daggerheart.less @@ -35,9 +35,9 @@ @import './less/applications/header.less'; @import './less/applications/adversary-settings/sheet.less'; @import './less/applications/adversary-settings/experiences.less'; -@import './less/applications/adversary-settings/actions.less'; +@import './less/applications/adversary-settings/features.less'; -@import './less/applications/environment-settings/actions.less'; +@import './less/applications/environment-settings/features.less'; @import './less/applications/environment-settings/adversaries.less'; @import './less/applications//beastform.less'; diff --git a/styles/less/actors/adversary/actions.less b/styles/less/actors/adversary/actions.less index 97bb45e7..6ca46e90 100644 --- a/styles/less/actors/adversary/actions.less +++ b/styles/less/actors/adversary/actions.less @@ -1,20 +1,20 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; - -.application.sheet.daggerheart.actor.dh-style.adversary { - .tab.actions { - .action-section { - display: flex; - flex-direction: column; - gap: 10px; - overflow-y: auto; - mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%); - padding: 20px 0; - padding-top: 10px; - height: 95%; - - scrollbar-width: thin; - scrollbar-color: light-dark(@dark-blue, @golden) transparent; - } - } -} +@import '../../utils/colors.less'; +@import '../../utils/fonts.less'; + +.application.sheet.daggerheart.actor.dh-style.adversary { + .tab.features { + .feature-section { + display: flex; + flex-direction: column; + gap: 10px; + overflow-y: auto; + mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%); + padding: 20px 0; + padding-top: 10px; + height: 95%; + + scrollbar-width: thin; + scrollbar-color: light-dark(@dark-blue, @golden) transparent; + } + } +} diff --git a/styles/less/applications/adversary-settings/actions.less b/styles/less/applications/adversary-settings/actions.less deleted file mode 100644 index 55cf2828..00000000 --- a/styles/less/applications/adversary-settings/actions.less +++ /dev/null @@ -1,74 +0,0 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; - -.application.daggerheart.dh-style.dialog { - .tab.actions { - max-height: 450px; - overflow-y: auto; - scrollbar-width: thin; - scrollbar-color: light-dark(@dark-blue, @golden) transparent; - - .add-action-btn { - width: 100%; - margin-bottom: 12px; - } - - .action-list { - display: flex; - flex-direction: column; - gap: 10px; - - .action-item { - display: grid; - grid-template-columns: 40px 1fr auto; - align-items: center; - gap: 5px; - border-radius: 3px; - - img { - height: 40px; - width: 40px; - object-fit: cover; - } - - .label { - font-family: @font-body; - - .tags { - display: flex; - gap: 10px; - - .tag { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - padding: 3px 5px; - font-size: 12px; - - background: light-dark(@dark-15, @beige-15); - border: 1px solid light-dark(@dark, @beige); - border-radius: 3px; - } - - .label { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - font-size: 12px; - } - } - } - - .controls { - display: flex; - gap: 5px; - a { - text-align: center; - } - } - } - } - } -} diff --git a/styles/less/applications/adversary-settings/features.less b/styles/less/applications/adversary-settings/features.less new file mode 100644 index 00000000..5798bfa9 --- /dev/null +++ b/styles/less/applications/adversary-settings/features.less @@ -0,0 +1,48 @@ +@import '../../utils/colors.less'; +@import '../../utils/fonts.less'; + +.application.daggerheart.dh-style.dialog { + .tab.features { + max-height: 450px; + overflow-y: auto; + scrollbar-width: thin; + scrollbar-color: light-dark(@dark-blue, @golden) transparent; + + .add-feature-btn { + width: 100%; + margin-bottom: 12px; + } + + .feature-list { + display: flex; + flex-direction: column; + gap: 10px; + + .feature-item { + display: grid; + grid-template-columns: 40px 1fr auto; + align-items: center; + gap: 5px; + border-radius: 3px; + + img { + height: 40px; + width: 40px; + object-fit: cover; + } + + .label { + font-family: @font-body; + } + + .controls { + display: flex; + gap: 5px; + a { + text-align: center; + } + } + } + } + } +} diff --git a/styles/less/applications/environment-settings/actions.less b/styles/less/applications/environment-settings/actions.less deleted file mode 100644 index e4886ea9..00000000 --- a/styles/less/applications/environment-settings/actions.less +++ /dev/null @@ -1,74 +0,0 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; - -.application.daggerheart.dh-style.dialog.environment-settings { - .tab.actions { - max-height: 450px; - overflow-y: auto; - scrollbar-width: thin; - scrollbar-color: light-dark(@dark-blue, @golden) transparent; - - .add-action-btn { - width: 100%; - margin-bottom: 12px; - } - - .action-list { - display: flex; - flex-direction: column; - gap: 10px; - - .action-item { - display: grid; - grid-template-columns: 40px 1fr auto; - align-items: center; - gap: 5px; - - img { - height: 40px; - width: 40px; - object-fit: cover; - border-radius: 3px; - } - - .label { - font-family: @font-body; - - .tags { - display: flex; - gap: 10px; - - .tag { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - padding: 3px 5px; - font-size: 12px; - - background: light-dark(@dark-15, @beige-15); - border: 1px solid light-dark(@dark, @beige); - border-radius: 3px; - } - - .label { - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - font-size: 12px; - } - } - } - - .controls { - display: flex; - gap: 5px; - a { - text-align: center; - } - } - } - } - } -} diff --git a/styles/less/applications/environment-settings/features.less b/styles/less/applications/environment-settings/features.less new file mode 100644 index 00000000..e4bb039f --- /dev/null +++ b/styles/less/applications/environment-settings/features.less @@ -0,0 +1,48 @@ +@import '../../utils/colors.less'; +@import '../../utils/fonts.less'; + +.application.daggerheart.dh-style.dialog.environment-settings { + .tab.features { + max-height: 450px; + overflow-y: auto; + scrollbar-width: thin; + scrollbar-color: light-dark(@dark-blue, @golden) transparent; + + .add-feature-btn { + width: 100%; + margin-bottom: 12px; + } + + .feature-list { + display: flex; + flex-direction: column; + gap: 10px; + + .feature-item { + display: grid; + grid-template-columns: 40px 1fr auto; + align-items: center; + gap: 5px; + + img { + height: 40px; + width: 40px; + object-fit: cover; + border-radius: 3px; + } + + .label { + font-family: @font-body; + } + + .controls { + display: flex; + gap: 5px; + a { + text-align: center; + } + } + } + } + } +} diff --git a/styles/less/dialog/dice-roll/roll-selection.less b/styles/less/dialog/dice-roll/roll-selection.less index 1f7653d7..b2f05dc2 100644 --- a/styles/less/dialog/dice-roll/roll-selection.less +++ b/styles/less/dialog/dice-roll/roll-selection.less @@ -1,128 +1,128 @@ -@import '../../utils/colors.less'; -@import '../../utils/fonts.less'; - -.application.daggerheart.dialog.dh-style.views.roll-selection { - .roll-dialog-container { - display: flex; - flex-direction: column; - gap: 12px; - - .dices-section { - display: flex; - gap: 60px; - justify-content: center; - - .dice-option { - display: flex; - flex-direction: column; - align-items: center; - gap: 10px; - width: 120px; - - .dice-icon { - width: 70px; - height: 70px; - object-fit: contain; - } - .dice-select { - display: flex; - align-items: center; - gap: 10px; - height: 32px; - - .label { - font-family: @font-subtitle; - font-style: normal; - font-weight: 700; - font-size: 16px; - line-height: 19px; - - color: light-dark(@dark, @beige); - } - } - } - } - - .experience-container { - display: flex; - gap: 10px; - flex-wrap: wrap; - - .experience-chip { - display: flex; - align-items: center; - border-radius: 5px; - width: fit-content; - gap: 5px; - cursor: pointer; - padding: 5px; - background: light-dark(@dark-blue-10, @golden-10); - color: light-dark(@dark-blue, @golden); - - .label { - font-family: @font-body; - font-style: normal; - font-weight: 400; - font-size: 14px; - line-height: 17px; - } - - &.selected { - background: light-dark(@dark-blue-40, @golden-40); - } - } - } - - .modifier-container { - .advantage-chip, - .disadvantage-chip { - display: flex; - align-items: center; - border-radius: 5px; - width: fit-content; - gap: 5px; - cursor: pointer; - padding: 5px; - transition: all 0.3s ease; - - .label { - font-family: @font-body; - font-style: normal; - font-weight: 400; - font-size: 14px; - line-height: 17px; - } - } - - .advantage-chip { - background: @green-10; - color: @green; - - &.selected { - color: @beige; - background: @gradient-green; - } - } - - .disadvantage-chip { - background: @red-10; - color: @red; - - &.selected { - color: @beige; - background: @gradient-red; - } - } - } - - .formula-label { - font-family: @font-body; - font-style: normal; - font-weight: 500; - font-size: 14px; - line-height: 17px; - - color: light-dark(@dark, @beige); - } - } -} +@import '../../utils/colors.less'; +@import '../../utils/fonts.less'; + +.application.daggerheart.dialog.dh-style.views.roll-selection { + .roll-dialog-container { + display: flex; + flex-direction: column; + gap: 12px; + + .dices-section { + display: flex; + gap: 60px; + justify-content: center; + + .dice-option { + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; + width: 120px; + + .dice-icon { + width: 70px; + height: 70px; + object-fit: contain; + } + .dice-select { + display: flex; + align-items: center; + gap: 10px; + height: 32px; + + .label { + font-family: @font-subtitle; + font-style: normal; + font-weight: 700; + font-size: 16px; + line-height: 19px; + + color: light-dark(@dark, @beige); + } + } + } + } + + .experience-container { + display: flex; + gap: 10px; + flex-wrap: wrap; + + .experience-chip { + display: flex; + align-items: center; + border-radius: 5px; + width: fit-content; + gap: 5px; + cursor: pointer; + padding: 5px; + background: light-dark(@dark-blue-10, @golden-10); + color: light-dark(@dark-blue, @golden); + + .label { + font-family: @font-body; + font-style: normal; + font-weight: 400; + font-size: 14px; + line-height: 17px; + } + + &.selected { + background: light-dark(@dark-blue-40, @golden-40); + } + } + } + + .modifier-container { + .advantage-chip, + .disadvantage-chip { + display: flex; + align-items: center; + border-radius: 5px; + width: fit-content; + gap: 5px; + cursor: pointer; + padding: 5px; + transition: all 0.3s ease; + + .label { + font-family: @font-body; + font-style: normal; + font-weight: 400; + font-size: 14px; + line-height: 17px; + } + } + + .advantage-chip { + background: @green-10; + color: @green; + + &.selected { + color: @beige; + background: @gradient-green; + } + } + + .disadvantage-chip { + background: @red-10; + color: @red; + + &.selected { + color: @beige; + background: @gradient-red; + } + } + } + + .formula-label { + font-family: @font-body; + font-style: normal; + font-weight: 500; + font-size: 14px; + line-height: 17px; + + color: light-dark(@dark, @beige); + } + } +} diff --git a/templates/sheets-settings/adversary-settings/actions.hbs b/templates/sheets-settings/adversary-settings/actions.hbs deleted file mode 100644 index f766c24a..00000000 --- a/templates/sheets-settings/adversary-settings/actions.hbs +++ /dev/null @@ -1,34 +0,0 @@ -
- -
- {{localize tabs.actions.label}} -
    - {{#each document.system.actions as |action index|}} -
  • - -
    - {{action.name}} -
    -
    - {{localize (concat 'DAGGERHEART.Actions.Types.' action.type '.name')}} -
    -
    - {{localize (concat 'DAGGERHEART.ActionType.' action.actionType)}} -
    -
    -
    -
    - - -
    -
  • - {{/each}} -
-
-
\ No newline at end of file diff --git a/templates/sheets-settings/adversary-settings/features.hbs b/templates/sheets-settings/adversary-settings/features.hbs new file mode 100644 index 00000000..497bf1c6 --- /dev/null +++ b/templates/sheets-settings/adversary-settings/features.hbs @@ -0,0 +1,26 @@ +
+ +
+ {{localize tabs.features.label}} +
    + {{#each document.system.features as |feature|}} +
  • + +
    + {{feature.name}} +
    +
    + + +
    +
  • + {{/each}} +
+
+
\ No newline at end of file diff --git a/templates/sheets-settings/environment-settings/actions.hbs b/templates/sheets-settings/environment-settings/actions.hbs deleted file mode 100644 index f766c24a..00000000 --- a/templates/sheets-settings/environment-settings/actions.hbs +++ /dev/null @@ -1,34 +0,0 @@ -
- -
- {{localize tabs.actions.label}} -
    - {{#each document.system.actions as |action index|}} -
  • - -
    - {{action.name}} -
    -
    - {{localize (concat 'DAGGERHEART.Actions.Types.' action.type '.name')}} -
    -
    - {{localize (concat 'DAGGERHEART.ActionType.' action.actionType)}} -
    -
    -
    -
    - - -
    -
  • - {{/each}} -
-
-
\ No newline at end of file diff --git a/templates/sheets-settings/environment-settings/features.hbs b/templates/sheets-settings/environment-settings/features.hbs new file mode 100644 index 00000000..497bf1c6 --- /dev/null +++ b/templates/sheets-settings/environment-settings/features.hbs @@ -0,0 +1,26 @@ +
+ +
+ {{localize tabs.features.label}} +
    + {{#each document.system.features as |feature|}} +
  • + +
    + {{feature.name}} +
    +
    + + +
    +
  • + {{/each}} +
+
+
\ No newline at end of file diff --git a/templates/sheets/actors/adversary/actions.hbs b/templates/sheets/actors/adversary/actions.hbs deleted file mode 100644 index 1c7e46fb..00000000 --- a/templates/sheets/actors/adversary/actions.hbs +++ /dev/null @@ -1,11 +0,0 @@ -
-
- {{#if document.system.actions}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize tabs.actions.label) type='action'}} - {{/if}} -
-
\ No newline at end of file diff --git a/templates/sheets/actors/adversary/effects.hbs b/templates/sheets/actors/adversary/effects.hbs index 9046fff8..817b07ae 100644 --- a/templates/sheets/actors/adversary/effects.hbs +++ b/templates/sheets/actors/adversary/effects.hbs @@ -4,5 +4,5 @@ data-group='{{tabs.effects.group}}' > {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize 'DAGGERHEART.Sheets.Global.activeEffects') type='effect'}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize 'DAGGERHEART.Sheets.Global.inativeEffects') type='effect'}} + {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize 'DAGGERHEART.Sheets.Global.inactiveEffects') type='effect'}} \ No newline at end of file diff --git a/templates/sheets/actors/adversary/features.hbs b/templates/sheets/actors/adversary/features.hbs new file mode 100644 index 00000000..1a8d918e --- /dev/null +++ b/templates/sheets/actors/adversary/features.hbs @@ -0,0 +1,9 @@ +
+
+ {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize tabs.features.label) type='feature' values=document.system.features hideControls=true}} +
+
\ No newline at end of file diff --git a/templates/sheets/actors/character/effects.hbs b/templates/sheets/actors/character/effects.hbs index 9046fff8..817b07ae 100644 --- a/templates/sheets/actors/character/effects.hbs +++ b/templates/sheets/actors/character/effects.hbs @@ -4,5 +4,5 @@ data-group='{{tabs.effects.group}}' > {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize 'DAGGERHEART.Sheets.Global.activeEffects') type='effect'}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize 'DAGGERHEART.Sheets.Global.inativeEffects') type='effect'}} + {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize 'DAGGERHEART.Sheets.Global.inactiveEffects') type='effect'}} \ No newline at end of file diff --git a/templates/sheets/actors/character/features.hbs b/templates/sheets/actors/character/features.hbs index 1ac18a1e..6ec47c1f 100644 --- a/templates/sheets/actors/character/features.hbs +++ b/templates/sheets/actors/character/features.hbs @@ -4,7 +4,12 @@ data-group='{{tabs.features.group}}' >
- {{#if document.system.class.value}} + {{#each document.system.sheetLists}} + {{#if this.values}} + {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=this.title values=this.values}} + {{/if}} + {{/each}} + {{!-- {{#if document.system.class.value}} {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(concat (localize 'TYPES.Item.class') ' - ' document.system.class.value.name) type='class'}} {{/if}} {{#if document.system.class.subclass}} @@ -21,6 +26,6 @@ {{/if}} {{#if document.system.ancestry}} {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(concat (localize 'TYPES.Item.ancestry') ' - ' document.system.ancestry.name) type='ancestry'}} - {{/if}} + {{/if}} --}}
\ No newline at end of file diff --git a/templates/sheets/actors/companion/effects.hbs b/templates/sheets/actors/companion/effects.hbs index 9046fff8..817b07ae 100644 --- a/templates/sheets/actors/companion/effects.hbs +++ b/templates/sheets/actors/companion/effects.hbs @@ -4,5 +4,5 @@ data-group='{{tabs.effects.group}}' > {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize 'DAGGERHEART.Sheets.Global.activeEffects') type='effect'}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize 'DAGGERHEART.Sheets.Global.inativeEffects') type='effect'}} + {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize 'DAGGERHEART.Sheets.Global.inactiveEffects') type='effect'}} \ No newline at end of file diff --git a/templates/sheets/actors/environment/actions.hbs b/templates/sheets/actors/environment/actions.hbs deleted file mode 100644 index 48ee18a7..00000000 --- a/templates/sheets/actors/environment/actions.hbs +++ /dev/null @@ -1,9 +0,0 @@ -
-
- {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize tabs.actions.label) type='action'}} -
-
\ No newline at end of file diff --git a/templates/sheets/actors/environment/features.hbs b/templates/sheets/actors/environment/features.hbs new file mode 100644 index 00000000..6697e42c --- /dev/null +++ b/templates/sheets/actors/environment/features.hbs @@ -0,0 +1,9 @@ +
+
+ {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize tabs.features.label) type='feature' values=document.system.features hideControls=true }} +
+
\ No newline at end of file diff --git a/templates/sheets/global/partials/inventory-fieldset-items.hbs b/templates/sheets/global/partials/inventory-fieldset-items.hbs index cd99fe17..92d3a8a6 100644 --- a/templates/sheets/global/partials/inventory-fieldset-items.hbs +++ b/templates/sheets/global/partials/inventory-fieldset-items.hbs @@ -2,51 +2,29 @@ {{title}} diff --git a/templates/sheets/global/partials/inventory-item.hbs b/templates/sheets/global/partials/inventory-item.hbs index 2e0ea2e6..0dcc485a 100644 --- a/templates/sheets/global/partials/inventory-item.hbs +++ b/templates/sheets/global/partials/inventory-item.hbs @@ -1,4 +1,4 @@ -
  • +
  • {{#if isCompanion}} diff --git a/templates/sheets/global/tabs/tab-features.hbs b/templates/sheets/global/tabs/tab-features.hbs index 59a43655..8ea1d534 100644 --- a/templates/sheets/global/tabs/tab-features.hbs +++ b/templates/sheets/global/tabs/tab-features.hbs @@ -4,17 +4,17 @@ data-group='{{tabs.features.group}}' >
    - {{localize "DAGGERHEART.Sheets.Global.Features"}} + {{localize "DAGGERHEART.Sheets.Global.Features"}}
    - {{#each document.system.features as |feature index|}} + {{#each document.system.features as |feature|}}
    {{feature.name}}
    - +
    {{/each}} diff --git a/templates/sheets/items/class/features.hbs b/templates/sheets/items/class/features.hbs index 5d8d8a70..811d6ce5 100644 --- a/templates/sheets/items/class/features.hbs +++ b/templates/sheets/items/class/features.hbs @@ -7,7 +7,7 @@
    {{localize "DAGGERHEART.Sheets.Class.HopeFeatures"}}
    - {{#each source.system.hopeFeatures as |feature index|}} + {{#each source.system.hopeFeatures as |feature|}} {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='hope' feature=feature}} {{/each}}
    @@ -16,7 +16,7 @@
    {{localize "DAGGERHEART.Sheets.Class.ClassFeatures"}}
    - {{#each source.system.classFeatures as |feature index|}} + {{#each source.system.classFeatures as |feature|}} {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='class' feature=feature}} {{/each}}
    diff --git a/templates/sheets/items/subclass/features.hbs b/templates/sheets/items/subclass/features.hbs index d7f7cfd0..98dcb054 100644 --- a/templates/sheets/items/subclass/features.hbs +++ b/templates/sheets/items/subclass/features.hbs @@ -3,18 +3,42 @@ data-tab='{{tabs.features.id}}' data-group='{{tabs.features.group}}' > -
    - {{localize "DAGGERHEART.Sheets.Subclass.Tabs.Foundation"}} - {{> 'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-features.hbs' level='foundationFeature' feature=source.system.foundationFeature}} +
    + + {{localize "DAGGERHEART.Sheets.Subclass.Tabs.Foundation"}} + + + +
    + {{#if source.system.foundationFeature}} + {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='foundationFeature' feature=source.system.foundationFeature}} + {{/if}} +
    -
    - {{localize "DAGGERHEART.Sheets.Subclass.Tabs.Specialization"}} - {{> 'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-features.hbs' level='specializationFeature' feature=source.system.specializationFeature}} +
    + + {{localize "DAGGERHEART.Sheets.Subclass.Tabs.Specialization"}} + + + +
    + {{#if source.system.specializationFeature}} + {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='specializationFeature' feature=source.system.specializationFeature}} + {{/if}} +
    -
    - {{localize "DAGGERHEART.Sheets.Subclass.Tabs.Mastery"}} - {{> 'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-features.hbs' level='masteryFeature' feature=source.system.masteryFeature}} +
    + + {{localize "DAGGERHEART.Sheets.Subclass.Tabs.Mastery"}} + + + +
    + {{#if source.system.masteryFeature}} + {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' type='masteryFeature' feature=source.system.masteryFeature}} + {{/if}} +
    \ No newline at end of file diff --git a/templates/sheets/items/subclass/parts/subclass-feature.hbs b/templates/sheets/items/subclass/parts/subclass-feature.hbs deleted file mode 100644 index e818e406..00000000 --- a/templates/sheets/items/subclass/parts/subclass-feature.hbs +++ /dev/null @@ -1,30 +0,0 @@ -
  • -
    - -

    {{feature.name}}

    - {{#unless hideContrals}} - - {{/unless}} -
    -
  • \ No newline at end of file diff --git a/templates/sheets/items/subclass/parts/subclass-features.hbs b/templates/sheets/items/subclass/parts/subclass-features.hbs deleted file mode 100644 index 7bfb1496..00000000 --- a/templates/sheets/items/subclass/parts/subclass-features.hbs +++ /dev/null @@ -1,22 +0,0 @@ -
    -
    - {{localize "DAGGERHEART.Sheets.Subclass.SubclassFeature.Actions"}} - -
    - {{#each feature.actions}} - {{> 'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-feature.hbs' level=../level type="action" id=this._id feature=this}} - {{/each}} -
    -
    - -
    - {{localize "DAGGERHEART.Sheets.Subclass.SubclassFeature.Effects"}} - -
    - {{#each feature.effects}} - {{> 'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-feature.hbs' level=../level type="effect" id=this.id feature=this}} - {{/each}} -
    -
    -
    -