diff --git a/assets/icons/documents/actors/capybara.svg b/assets/icons/documents/actors/capybara.svg index 8fbe2c06..90deb64a 100644 --- a/assets/icons/documents/actors/capybara.svg +++ b/assets/icons/documents/actors/capybara.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/documents/actors/dark-squad.svg b/assets/icons/documents/actors/dark-squad.svg index 39ca794a..f21b4c5b 100644 --- a/assets/icons/documents/actors/dark-squad.svg +++ b/assets/icons/documents/actors/dark-squad.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/documents/actors/dragon-head.svg b/assets/icons/documents/actors/dragon-head.svg index 324ffbbb..d9e008f5 100644 --- a/assets/icons/documents/actors/dragon-head.svg +++ b/assets/icons/documents/actors/dragon-head.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/documents/actors/drama-masks.svg b/assets/icons/documents/actors/drama-masks.svg index 98b9b68b..84307da0 100644 --- a/assets/icons/documents/actors/drama-masks.svg +++ b/assets/icons/documents/actors/drama-masks.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/documents/actors/forest.svg b/assets/icons/documents/actors/forest.svg index fcdb8a9d..8f7117e8 100644 --- a/assets/icons/documents/actors/forest.svg +++ b/assets/icons/documents/actors/forest.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/documents/items/battered-axe.svg b/assets/icons/documents/items/battered-axe.svg index 436884bd..5d7be27d 100644 --- a/assets/icons/documents/items/battered-axe.svg +++ b/assets/icons/documents/items/battered-axe.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/documents/items/card-play.svg b/assets/icons/documents/items/card-play.svg index 5c29fc43..587cb1c1 100644 --- a/assets/icons/documents/items/card-play.svg +++ b/assets/icons/documents/items/card-play.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/documents/items/chest-armor.svg b/assets/icons/documents/items/chest-armor.svg index 03b82d48..2cef80a6 100644 --- a/assets/icons/documents/items/chest-armor.svg +++ b/assets/icons/documents/items/chest-armor.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/documents/items/family-tree.svg b/assets/icons/documents/items/family-tree.svg index 031f23da..d95c935d 100644 --- a/assets/icons/documents/items/family-tree.svg +++ b/assets/icons/documents/items/family-tree.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/documents/items/laurel-crown.svg b/assets/icons/documents/items/laurel-crown.svg index 38dbcd04..34a54d2a 100644 --- a/assets/icons/documents/items/laurel-crown.svg +++ b/assets/icons/documents/items/laurel-crown.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/documents/items/laurels.svg b/assets/icons/documents/items/laurels.svg index ae7398ec..2c3cdf63 100644 --- a/assets/icons/documents/items/laurels.svg +++ b/assets/icons/documents/items/laurels.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/documents/items/open-treasure-chest.svg b/assets/icons/documents/items/open-treasure-chest.svg index d66399f4..172a8003 100644 --- a/assets/icons/documents/items/open-treasure-chest.svg +++ b/assets/icons/documents/items/open-treasure-chest.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/documents/items/round-potion.svg b/assets/icons/documents/items/round-potion.svg index 0c235732..7f981914 100644 --- a/assets/icons/documents/items/round-potion.svg +++ b/assets/icons/documents/items/round-potion.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/documents/items/stars-stack.svg b/assets/icons/documents/items/stars-stack.svg index 2d446683..19c197f6 100644 --- a/assets/icons/documents/items/stars-stack.svg +++ b/assets/icons/documents/items/stars-stack.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/documents/items/village.svg b/assets/icons/documents/items/village.svg index b7c776a1..c28d742b 100644 --- a/assets/icons/documents/items/village.svg +++ b/assets/icons/documents/items/village.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/icons/documents/items/wolf-head.svg b/assets/icons/documents/items/wolf-head.svg index 7e57bbad..2be500c1 100644 --- a/assets/icons/documents/items/wolf-head.svg +++ b/assets/icons/documents/items/wolf-head.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/lang/en.json b/lang/en.json index a4a5edf0..5bab0e64 100755 --- a/lang/en.json +++ b/lang/en.json @@ -1451,7 +1451,7 @@ }, "triggerType": "Trigger Type", "triggeringActorType": "Triggering Actor Type", - "triggerError": "{trigger} trigger on {item}({itemUuid}) failed for {actor}. It's probably configured wrong." + "triggerError": "{trigger} trigger failed for {actor}. It's probably configured wrong." }, "WeaponFeature": { "barrier": { diff --git a/module/applications/dialogs/d20RollDialog.mjs b/module/applications/dialogs/d20RollDialog.mjs index 048797d8..e9140b56 100644 --- a/module/applications/dialogs/d20RollDialog.mjs +++ b/module/applications/dialogs/d20RollDialog.mjs @@ -160,7 +160,7 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio } if (rest.hasOwnProperty('trait')) { this.config.roll.trait = rest.trait; - if (!this.config.source.item && this.config.roll.trait) + if (!this.config.source.item) this.config.title = game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', { ability: game.i18n.localize(abilities[this.config.roll.trait]?.label) }); @@ -225,6 +225,7 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio } static async submitRoll(event) { + event.preventDefault(); await this.close({ submitted: true }); } diff --git a/module/applications/dialogs/groupRollDialog.mjs b/module/applications/dialogs/groupRollDialog.mjs index ebc80d39..7196d848 100644 --- a/module/applications/dialogs/groupRollDialog.mjs +++ b/module/applications/dialogs/groupRollDialog.mjs @@ -1,5 +1,4 @@ import { ResourceUpdateMap } from '../../data/action/baseAction.mjs'; -import { shouldUseHopeFearAutomation } from '../../helpers/utils.mjs'; import { emitGMUpdate, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs'; import Party from '../sheets/actors/party.mjs'; @@ -481,23 +480,20 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat await cls.create(msgData); - /* Handle resource updates for the finished GroupRoll */ - if (shouldUseHopeFearAutomation({ gmAsPlayer: true })) { - const resourceMap = new ResourceUpdateMap(actor); - if (totalRoll.isCritical) { - resourceMap.addResources([ - { key: 'stress', value: -1 }, - { key: 'hope', value: 1 } - ]); - } else if (totalRoll.withHope) { - resourceMap.addResources([{ key: 'hope', value: 1 }]); - } else { - resourceMap.addResources([{ key: 'fear', value: 1 }]); - } - - resourceMap.updateResources(); + const resourceMap = new ResourceUpdateMap(actor); + if (totalRoll.isCritical) { + resourceMap.addResources([ + { key: 'stress', value: -1, total: 1 }, + { key: 'hope', value: 1, total: 1 } + ]); + } else if (totalRoll.withHope) { + resourceMap.addResources([{ key: 'hope', value: 1, total: 1 }]); + } else { + resourceMap.addResources([{ key: 'fear', value: 1, total: 1 }]); } + resourceMap.updateResources(); + /* Fin */ this.cancelRoll({ confirm: false }); } diff --git a/module/applications/dialogs/tagTeamDialog.mjs b/module/applications/dialogs/tagTeamDialog.mjs index 19869a00..b2ce0258 100644 --- a/module/applications/dialogs/tagTeamDialog.mjs +++ b/module/applications/dialogs/tagTeamDialog.mjs @@ -1,6 +1,5 @@ -import { ResourceUpdateMap } from '../../data/action/baseAction.mjs'; import { MemberData } from '../../data/tagTeamData.mjs'; -import { getCritDamageBonus, shouldUseHopeFearAutomation } from '../../helpers/utils.mjs'; +import { getCritDamageBonus } from '../../helpers/utils.mjs'; import { emitGMUpdate, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs'; import Party from '../sheets/actors/party.mjs'; @@ -10,7 +9,6 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio constructor(party) { super({ id: `TagTeamDialog-${party.id}` }); - this.usesTagTeamHopeCost = true; this.party = party; this.partyMembers = party.system.partyMembers .filter(x => Party.DICE_ROLL_ACTOR_TYPES.includes(x.type)) @@ -22,9 +20,7 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio owned: member.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER) })); - this.initiator = { cost: - this.party.system.schema.fields.tagTeam.fields.initiator.fields.cost.initial - }; + this.initiator = { cost: 3 }; this.openForAllPlayers = true; this.tabGroups.application = Object.keys(party.system.tagTeam.members).length @@ -98,13 +94,9 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio ?.addEventListener('input', this.updateInitiatorMemberField.bind(this)); htmlElement - .querySelector('.initiator-cost-input') + .querySelector('.initiator-cost-field') ?.addEventListener('input', this.updateInitiatorCostField.bind(this)); - htmlElement - .querySelector('.initiator-cost-enabled-checkbox') - ?.addEventListener('change', this.toggleInitiatorCostEnabled.bind(this)); - htmlElement .querySelector('.openforall-field') ?.addEventListener('change', this.updateOpenForAllField.bind(this)); @@ -164,7 +156,6 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio .map(x => ({ value: x.id, label: x.name })); partContext.initiatorDisabled = !selectedMembers.length; partContext.openForAllPlayers = this.openForAllPlayers; - partContext.usesTagTeamHopeCost = this.usesTagTeamHopeCost; break; case 'tagTeamRoll': @@ -406,13 +397,6 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio this.render(); } - toggleInitiatorCostEnabled(_event) { - this.usesTagTeamHopeCost = !this.usesTagTeamHopeCost; - this.initiator.cost = this.usesTagTeamHopeCost ? - this.party.system.schema.fields.tagTeam.fields.initiator.fields.cost.initial : 0; - this.render(); - } - updateOpenForAllField(event) { this.openForAllPlayers = event.target.checked; this.render(); @@ -768,37 +752,32 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio /* Handle resource updates from the finished TagTeamRoll */ const tagTeamData = this.party.system.tagTeam; - - const actorResourceMaps = Object.keys(tagTeamData.members).reduce((acc, key) => { - acc[key] = new ResourceUpdateMap(game.actors.get(key)); - return acc; - }, {}); - - if (shouldUseHopeFearAutomation({ gmAsPlayer: true })) { - const fearResourceMap = actorResourceMaps[tagTeamData.initiator.memberId]; - for (const memberId in tagTeamData.members) { - const resourceMap = actorResourceMaps[memberId]; - if (finalRoll.isCritical) { - resourceMap.addResources([ - { key: 'stress', value: -1, enabled: true }, - { key: 'hope', value: 1, enabled: true } - ]); - } else if (finalRoll.withHope) { - resourceMap.addResources([{ key: 'hope', value: 1, enabled: true }]); - } else if (finalRoll.withFear) { - fearResourceMap.addResources([{ key: 'fear', value: 1, enabled: true }]); - } + const fearUpdate = { key: 'fear', value: null, total: null, enabled: true }; + for (let memberId in tagTeamData.members) { + const resourceUpdates = []; + const rollGivesHope = finalRoll.isCritical || finalRoll.withHope; + if (memberId === tagTeamData.initiator.memberId) { + const value = tagTeamData.initiator.cost + ? rollGivesHope + ? 1 - tagTeamData.initiator.cost + : -tagTeamData.initiator.cost + : 1; + resourceUpdates.push({ key: 'hope', value: value, total: -value, enabled: true }); + } else if (rollGivesHope) { + resourceUpdates.push({ key: 'hope', value: 1, total: -1, enabled: true }); + } + if (finalRoll.isCritical) resourceUpdates.push({ key: 'stress', value: -1, total: 1, enabled: true }); + if (finalRoll.withFear) { + fearUpdate.value = fearUpdate.value === null ? 1 : fearUpdate.value + 1; + fearUpdate.total = fearUpdate.total === null ? -1 : fearUpdate.total - 1; } - } - /* Even with Hope/Fear automation off, the hope cost of performing the TagTeamRoll can still optionally be subtracted */ - if (tagTeamData.initiator.cost) { - const resourceMap = actorResourceMaps[tagTeamData.initiator.memberId]; - resourceMap.addResources([{ key: 'hope', value: -tagTeamData.initiator.cost, enabled: true }]); + game.actors.get(memberId).modifyResource(resourceUpdates); } - for (const resourceMap of Object.values(actorResourceMaps)) - resourceMap.updateResources(); + if (fearUpdate.value) { + mainActor.modifyResource([fearUpdate]); + } /* Fin */ this.cancelRoll({ confirm: false }); diff --git a/module/applications/sheets-configs/adversary-settings.mjs b/module/applications/sheets-configs/adversary-settings.mjs index ff3f3039..57405675 100644 --- a/module/applications/sheets-configs/adversary-settings.mjs +++ b/module/applications/sheets-configs/adversary-settings.mjs @@ -10,7 +10,11 @@ export default class DHAdversarySettings extends DHBaseActorSettings { actions: { addExperience: DHAdversarySettings.#addExperience, removeExperience: DHAdversarySettings.#removeExperience - } + }, + dragDrop: [ + { dragSelector: null, dropSelector: '.tab.features' }, + { dragSelector: '.feature-item', dropSelector: null } + ] }; /**@override */ @@ -34,8 +38,7 @@ export default class DHAdversarySettings extends DHBaseActorSettings { }, features: { id: 'features', - template: 'systems/daggerheart/templates/sheets-settings/adversary-settings/features.hbs', - scrollable: [''] + template: 'systems/daggerheart/templates/sheets-settings/adversary-settings/features.hbs' } }; @@ -51,16 +54,12 @@ export default class DHAdversarySettings extends DHBaseActorSettings { async _prepareContext(options) { const context = await super._prepareContext(options); - // Get feature groups. Uncategorized go to actions - const featureFormsTypes = ['passive', 'action', 'reaction']; - const features = this.document.system.features.sort((a, b) => a.sort - b.sort); - const featureGroups = featureFormsTypes.map(t => ({ - featureForm: t, - label: _loc(CONFIG.DH.ITEM.featureForm[t]), - features: features.filter(f => f.system.featureForm === t) - })); - featureGroups[1].features.push(...features.filter(f => !featureFormsTypes.includes(f.system.featureForm))); - context.featureGroups = featureGroups; + const featureForms = ['passive', 'action', 'reaction']; + context.features = context.document.system.features.sort((a, b) => + a.system.featureForm !== b.system.featureForm + ? featureForms.indexOf(a.system.featureForm) - featureForms.indexOf(b.system.featureForm) + : a.sort - b.sort + ); return context; } @@ -98,4 +97,32 @@ export default class DHAdversarySettings extends DHBaseActorSettings { await this.actor.update({ [`system.experiences.${target.dataset.experience}`]: _del }); } + + 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) { + event.stopPropagation(); + const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); + + const item = await fromUuid(data.uuid); + if (item?.type === 'feature') { + if (data.fromInternal && item.parent?.uuid === this.actor.uuid) { + return; + } + + const itemData = item.toObject(); + delete itemData._id; + + await this.actor.createEmbeddedDocuments('Item', [itemData]); + } + } } diff --git a/module/applications/sheets-configs/environment-settings.mjs b/module/applications/sheets-configs/environment-settings.mjs index 954d6381..6d74f9c6 100644 --- a/module/applications/sheets-configs/environment-settings.mjs +++ b/module/applications/sheets-configs/environment-settings.mjs @@ -15,7 +15,7 @@ export default class DHEnvironmentSettings extends DHBaseActorSettings { dragDrop: [ { dragSelector: null, dropSelector: '.category-container' }, { dragSelector: null, dropSelector: '.tab.features' }, - { dragSelector: '.feature-item, .inventory-item[data-type="adversary"]', dropSelector: null } + { dragSelector: '.feature-item', dropSelector: null } ] }; @@ -32,13 +32,11 @@ export default class DHEnvironmentSettings extends DHBaseActorSettings { }, features: { id: 'features', - template: 'systems/daggerheart/templates/sheets-settings/environment-settings/features.hbs', - scrollable: [''] + template: 'systems/daggerheart/templates/sheets-settings/environment-settings/features.hbs' }, adversaries: { id: 'adversaries', - template: 'systems/daggerheart/templates/sheets-settings/environment-settings/adversaries.hbs', - scrollable: [''] + template: 'systems/daggerheart/templates/sheets-settings/environment-settings/adversaries.hbs' } }; @@ -54,16 +52,12 @@ export default class DHEnvironmentSettings extends DHBaseActorSettings { async _prepareContext(options) { const context = await super._prepareContext(options); - // Get feature groups. Uncategorized go to actions - const featureFormsTypes = ['passive', 'action', 'reaction']; - const features = this.document.system.features.sort((a, b) => a.sort - b.sort); - const featureGroups = featureFormsTypes.map(t => ({ - featureForm: t, - label: _loc(CONFIG.DH.ITEM.featureForm[t]), - features: features.filter(f => f.system.featureForm === t) - })); - featureGroups[1].features.push(...features.filter(f => !featureFormsTypes.includes(f.system.featureForm))); - context.featureGroups = featureGroups; + const featureForms = ['passive', 'action', 'reaction']; + context.features = context.document.system.features.sort((a, b) => + a.system.featureForm !== b.system.featureForm + ? featureForms.indexOf(a.system.featureForm) - featureForms.indexOf(b.system.featureForm) + : a.sort - b.sort + ); return context; } @@ -116,30 +110,33 @@ export default class DHEnvironmentSettings extends DHBaseActorSettings { } async _onDragStart(event) { - const element = event.currentTarget.closest('.inventory-item[data-type=adversary]'); - if (element) { - const adversaryData = { type: 'Actor', uuid: element.dataset.itemUuid }; - event.dataTransfer.setData('text/plain', JSON.stringify(adversaryData)); - event.dataTransfer.setDragImage(element, 60, 0); - } else { - return super._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) { event.stopPropagation(); const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); - const doc = await fromUuid(data.uuid); - if (doc?.type === 'adversary' && event.target.closest('.category-container')) { + const item = await fromUuid(data.uuid); + if (data.fromInternal && item?.parent?.uuid === this.actor.uuid) return; + + 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); - if (!current.includes(doc.uuid)) { - await this.actor.update({ [path]: [...current, doc.uuid] }); - } - return; + await this.actor.update({ + [path]: [...current, item.uuid] + }); + this.render(); + } else if (item.type === 'feature' && event.target.closest('.tab.features')) { + await this.actor.createEmbeddedDocuments('Item', [item]); + this.render(); } - - return super._onDrop(event); } } diff --git a/module/applications/sheets-configs/npc-settings.mjs b/module/applications/sheets-configs/npc-settings.mjs index 33cbc270..c187877c 100644 --- a/module/applications/sheets-configs/npc-settings.mjs +++ b/module/applications/sheets-configs/npc-settings.mjs @@ -27,8 +27,7 @@ export default class DHNPCSettings extends DHBaseActorSettings { }, features: { id: 'features', - template: 'systems/daggerheart/templates/sheets-settings/npc-settings/features.hbs', - scrollable: [''] + template: 'systems/daggerheart/templates/sheets-settings/npc-settings/features.hbs' } }; @@ -44,17 +43,43 @@ export default class DHNPCSettings extends DHBaseActorSettings { async _prepareContext(options) { const context = await super._prepareContext(options); - // Get feature groups. Uncategorized go to actions - const featureFormsTypes = ['passive', 'action', 'reaction']; - const features = this.document.system.features.sort((a, b) => a.sort - b.sort); - const featureGroups = featureFormsTypes.map(t => ({ - featureForm: t, - label: _loc(CONFIG.DH.ITEM.featureForm[t]), - features: features.filter(f => f.system.featureForm === t) - })); - featureGroups[1].features.push(...features.filter(f => !featureFormsTypes.includes(f.system.featureForm))); - context.featureGroups = featureGroups; + const featureForms = ['passive', 'action', 'reaction']; + context.features = context.document.system.features.sort((a, b) => + a.system.featureForm !== b.system.featureForm + ? featureForms.indexOf(a.system.featureForm) - featureForms.indexOf(b.system.featureForm) + : a.sort - b.sort + ); return context; } + + /* -------------------------------------------- */ + + 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) { + event.stopPropagation(); + const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); + + const item = await fromUuid(data.uuid); + if (item?.type === 'feature') { + if (data.fromInternal && item.parent?.uuid === this.actor.uuid) { + return; + } + + const itemData = item.toObject(); + delete itemData._id; + + await this.actor.createEmbeddedDocuments('Item', [itemData]); + } + } } diff --git a/module/applications/sheets/actors/adversary.mjs b/module/applications/sheets/actors/adversary.mjs index 85380392..c8d5a299 100644 --- a/module/applications/sheets/actors/adversary.mjs +++ b/module/applications/sheets/actors/adversary.mjs @@ -103,7 +103,7 @@ export default class AdversarySheet extends DHBaseActorSheet { context.resources.stress.emptyPips = context.resources.stress.max < maxResource ? maxResource - context.resources.stress.max : 0; - const featureForms = Object.keys(CONFIG.DH.ITEM.featureForm); + const featureForms = ['passive', 'action', 'reaction']; context.features = this.document.system.features.sort((a, b) => a.system.featureForm !== b.system.featureForm ? featureForms.indexOf(a.system.featureForm) - featureForms.indexOf(b.system.featureForm) @@ -131,15 +131,6 @@ export default class AdversarySheet extends DHBaseActorSheet { return context; } - /** @inheritdoc */ - _prepareTabs(group) { - const result = super._prepareTabs(group); - if (group === 'primary') { - result.notes.empty = !this.document.system.notes?.trim(); - } - return result; - } - /**@inheritdoc */ _attachPartListeners(partId, htmlElement, options) { super._attachPartListeners(partId, htmlElement, options); diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index 3a60e7ca..f0f8326f 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -809,7 +809,7 @@ export default class CharacterSheet extends DHBaseActorSheet { /* This could be avoided by baking config.costs into config.resourceUpdates. Didn't feel like messing with it at the time */ const costResources = - result.costs?.filter(x => x.enabled).map(cost => ({ ...cost, value: -cost.value })) || + result.costs?.filter(x => x.enabled).map(cost => ({ ...cost, value: -cost.value, total: -cost.total })) || {}; result.resourceUpdates.addResources(costResources); await result.resourceUpdates.updateResources(); diff --git a/module/applications/sheets/actors/environment.mjs b/module/applications/sheets/actors/environment.mjs index 60fb9071..f8ff74a6 100644 --- a/module/applications/sheets/actors/environment.mjs +++ b/module/applications/sheets/actors/environment.mjs @@ -72,22 +72,13 @@ export default class DhpEnvironment extends DHBaseActorSheet { return applicationOptions; } - /** @inheritdoc */ - _prepareTabs(group) { - const result = super._prepareTabs(group); - if (group === 'primary') { - result.potentialAdversaries.empty = foundry.utils.isEmpty(this.document.system.potentialAdversaries); - result.notes.empty = !this.document.system.notes?.trim(); - } - return result; - } - /**@inheritdoc */ async _preparePartContext(partId, context, options) { context = await super._preparePartContext(partId, context, options); switch (partId) { case 'header': await this._prepareHeaderContext(context, options); + break; case 'features': await this._prepareFeaturesContext(context, options); diff --git a/module/applications/sheets/api/actor-setting.mjs b/module/applications/sheets/api/actor-setting.mjs index fa434034..738f7002 100644 --- a/module/applications/sheets/api/actor-setting.mjs +++ b/module/applications/sheets/api/actor-setting.mjs @@ -1,15 +1,13 @@ import DHApplicationMixin from './application-mixin.mjs'; -const { ActorSheetV2 } = foundry.applications.sheets; +const { DocumentSheetV2 } = foundry.applications.api; -/** - * @typedef {import('@client/applications/_types.mjs').ApplicationClickAction} ApplicationClickAction - */ +/**@typedef {import('@client/applications/_types.mjs').ApplicationClickAction} ApplicationClickAction */ /** * Base settings sheet for Daggerheart actors. - * @extends {DHApplicationMixin} + * @extends {DHApplicationMixin} */ -export default class DHBaseActorSettings extends DHApplicationMixin(ActorSheetV2) { +export default class DHBaseActorSettings extends DHApplicationMixin(DocumentSheetV2) { /**@inheritdoc */ static DEFAULT_OPTIONS = { classes: ['dialog'], @@ -25,7 +23,7 @@ export default class DHBaseActorSettings extends DHApplicationMixin(ActorSheetV2 }, dragDrop: [ { dragSelector: null, dropSelector: '.tab.features' }, - { dragSelector: '.feature-item, .inventory-item[data-type="feature"]', dropSelector: null } + { dragSelector: '.feature-item', dropSelector: null } ] }; @@ -36,7 +34,7 @@ export default class DHBaseActorSettings extends DHApplicationMixin(ActorSheetV2 return options; } - /** @returns {foundry.documents.Actor} */ + /**@returns {foundry.documents.Actor} */ get actor() { return this.document; } @@ -75,32 +73,4 @@ export default class DHBaseActorSettings extends DHApplicationMixin(ActorSheetV2 return context; } - - async _onDragStart(event) { - const featureItemEl = event.currentTarget.closest('.feature-item, .inventory-item[data-type="feature"]'); - const feature = this.actor.items.get(featureItemEl?.dataset.itemId); - if (feature && event.target.closest('.tab.features')) { - const featureData = { ...feature.toDragData(), fromInternal: true }; - event.dataTransfer.setData('text/plain', JSON.stringify(featureData)); - event.dataTransfer.setDragImage(featureItemEl.querySelector('img'), 60, 0); - } - } - - async _onDrop(event) { - event.stopPropagation(); - const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); - const item = await fromUuid(data.uuid); - if (item?.type === 'feature') { - if (data.fromInternal && item.parent?.uuid === this.actor.uuid) { - return super._onDrop(event); - } - - const itemData = item.toObject(); - delete itemData._id; - await this.actor.createEmbeddedDocuments('Item', [itemData]); - } - } - - /** Setting sheets do not auto extend */ - async _autoExpandDescriptions() {} } diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs index d89237df..752dc80b 100644 --- a/module/applications/sheets/api/application-mixin.mjs +++ b/module/applications/sheets/api/application-mixin.mjs @@ -4,7 +4,6 @@ import { getDocFromElement, getDocFromElementSync, tagifyElement } from '../../. const typeSettingsMap = { character: 'extendCharacterDescriptions', adversary: 'extendAdversaryDescriptions', - npc: 'extendAdversaryDescriptions', environment: 'extendEnvironmentDescriptions', ancestry: 'extendItemDescriptions', community: 'extendItemDescriptions', @@ -263,7 +262,7 @@ export default function DHApplicationMixin(Base) { if (!!this.options.contextMenus.length) this._createContextMenus(); - this._autoExpandDescriptions(context); + this.#autoExtendDescriptions(context); } /** @inheritDoc */ @@ -382,35 +381,12 @@ export default function DHApplicationMixin(Base) { * @protected */ _onDrop(event) { - // Potentially handle subclasses that dont descend from actor/item sheet. + // Fallback to super, but note that config sheets don't have this option + // We still need this to avoid setting apps having issues event.stopPropagation(); return super._onDrop?.(event); } - /** @inheritdoc */ - _onSortItem(event, item) { - // If we are dragging a feature past its allowed feature form, put it in the front or in the back - const doc = this.actor.items.get(item.id); - const dropTargetEl = event.target.closest('[data-item-id]'); - const dropTarget = this.actor.items.get(dropTargetEl?.dataset.itemId); - if (doc?.type === 'feature' && dropTarget?.type === 'feature' && doc.system.featureForm !== dropTarget.system.featureForm) { - const siblings = this.actor.itemTypes.feature - .filter(f => f.system.featureForm === doc.system.featureForm) - .sort((a, b) => a.sort - b.sort); - if (siblings.length > 1) { - const featureForms = Object.keys(CONFIG.DH.ITEM.featureForm); - const thisFeatureIdx = featureForms.indexOf(doc.system.featureForm); - const targetFeatureIdx = featureForms.indexOf(dropTarget.system.featureForm); - const target = targetFeatureIdx < thisFeatureIdx ? siblings[0] : siblings.at(-1); - const sortUpdates = foundry.utils.performIntegerSort(doc, { target, siblings }); - const updateData = sortUpdates.map(u => ({ ...u.update, _id: u.target._id })); - return this.actor.updateEmbeddedDocuments('Item', updateData); - } - } - - return super._onSortItem?.(event, item); - } - /* -------------------------------------------- */ /* Context Menu */ /* -------------------------------------------- */ @@ -631,9 +607,8 @@ export default function DHApplicationMixin(Base) { /** * Extend inventory description when enabled in settings. * @returns {Promise} - * @protected */ - async _autoExpandDescriptions(context) { + async #autoExtendDescriptions(context) { const inventoryItems = this.element.querySelectorAll('.inventory-item[data-item-uuid]'); for (const el of inventoryItems) { // Get the doc uuid from the element @@ -736,7 +711,7 @@ export default function DHApplicationMixin(Base) { * @type {ApplicationClickAction} */ static async #onCreateDoc(event, target) { - const { documentClass, type, inVault, disabled, featureForm } = target.dataset; + const { documentClass, type, inVault, disabled } = target.dataset; const parentIsItem = this.document.documentName === 'Item'; const featureOnCharacter = this.document.parent?.type === 'character' && type === 'feature'; const parent = featureOnCharacter @@ -754,7 +729,6 @@ export default function DHApplicationMixin(Base) { identifier: this.document.system.isMulticlass ? 'multiclass' : null }; } - if (featureForm) systemData.featureForm = featureForm; const cls = type === 'action' ? game.system.api.models.actions.actionsTypes.base : getDocumentClass(documentClass); diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index ea4361b9..c71f5ef9 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -459,7 +459,8 @@ export class ResourceUpdateMap extends Map { } else if (!existing?.clear) { this.set(resource.key, { ...existing, - value: existing.value + (resource.value ?? 0) + value: existing.value + (resource.value ?? 0), + total: existing.total + (resource.total ?? 0) }); } } diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index 3b12da6f..8ae78ff8 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -315,12 +315,7 @@ export default class DhCharacter extends DhCreature { label: 'DAGGERHEART.ACTORS.Character.defaultDisadvantageDice' }) }) - }), - /** Accumulated armor score from all sources */ - armorScore: new fields.SchemaField({ - value: new fields.NumberField(), - max: new fields.NumberField() - }, { persisted: false }) + }) }; } diff --git a/module/data/registeredTriggers.mjs b/module/data/registeredTriggers.mjs index 64e7f93e..0b637930 100644 --- a/module/data/registeredTriggers.mjs +++ b/module/data/registeredTriggers.mjs @@ -150,14 +150,11 @@ export default class RegisteredTriggers extends Map { const result = await command(...args); if (result?.updates?.length) updates.push(...result.updates); } catch { - const item = await foundry.utils.fromUuid(itemUuid); const triggerName = game.i18n.localize(triggerData.label); - console.error( + ui.notifications.error( game.i18n.format('DAGGERHEART.CONFIG.Triggers.triggerError', { trigger: triggerName, - actor: currentActor?.name, - item: item?.name ?? '', - itemUuid: item?.uuid ?? '' + actor: currentActor?.name }) ); } diff --git a/module/dice/dualityRoll.mjs b/module/dice/dualityRoll.mjs index e2d967a3..1cfed094 100644 --- a/module/dice/dualityRoll.mjs +++ b/module/dice/dualityRoll.mjs @@ -1,6 +1,6 @@ import D20RollDialog from '../applications/dialogs/d20RollDialog.mjs'; import D20Roll from './d20Roll.mjs'; -import { parseRallyDice, setDiceSoNiceForDualityRoll, shouldUseHopeFearAutomation } from '../helpers/utils.mjs'; +import { parseRallyDice, setDiceSoNiceForDualityRoll } from '../helpers/utils.mjs'; import { getDiceSoNicePresets } from '../config/generalConfig.mjs'; import { updateResourcesForDualityReroll } from './helpers.mjs'; @@ -312,9 +312,11 @@ export default class DualityRoll extends D20Roll { } static async addDualityResourceUpdates(config) { + const automationSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation); + const hopeFearAutomation = automationSettings.hopeFear; if ( !config.source?.actor || - !shouldUseHopeFearAutomation() || + (game.user.isGM ? !hopeFearAutomation.gm : !hopeFearAutomation.players) || config.actionType === 'reaction' || config.skips?.resources ) @@ -332,15 +334,15 @@ export default class DualityRoll extends D20Roll { const fear = (config.roll.result.duality === -1 ? 1 : 0) - (config.rerolledRoll.result.duality === -1 ? 1 : 0); - if (hope !== 0) updates.push({ key: 'hope', value: hope, enabled: true }); - if (stress !== 0) updates.push({ key: 'stress', value: -1 * stress, enabled: true }); - if (fear !== 0) updates.push({ key: 'fear', value: fear, enabled: true }); + if (hope !== 0) updates.push({ key: 'hope', value: hope, total: -1 * hope, enabled: true }); + if (stress !== 0) updates.push({ key: 'stress', value: -1 * stress, total: stress, enabled: true }); + if (fear !== 0) updates.push({ key: 'fear', value: fear, total: -1 * fear, enabled: true }); } } else { if (config.roll.isCritical || config.roll.result.duality === 1) - updates.push({ key: 'hope', value: 1, enabled: true }); - if (config.roll.isCritical) updates.push({ key: 'stress', value: -1, enabled: true }); - if (config.roll.result.duality === -1) updates.push({ key: 'fear', value: 1, enabled: true }); + updates.push({ key: 'hope', value: 1, total: -1, enabled: true }); + if (config.roll.isCritical) updates.push({ key: 'stress', value: -1, total: 1, enabled: true }); + if (config.roll.result.duality === -1) updates.push({ key: 'fear', value: 1, total: -1, enabled: true }); } if (updates.length) { diff --git a/module/dice/helpers.mjs b/module/dice/helpers.mjs index 5f8a7bbb..35adb8b7 100644 --- a/module/dice/helpers.mjs +++ b/module/dice/helpers.mjs @@ -9,9 +9,9 @@ export function updateResourcesForDualityReroll(oldDuality, newDuality, actor) { const stress = (newDuality === 0 ? 1 : 0) - (oldDuality === 0 ? 1 : 0); const fear = (newDuality === -1 ? 1 : 0) - (oldDuality === -1 ? 1 : 0); - if (hope !== 0) updates.push({ key: 'hope', value: hope, enabled: true }); - if (stress !== 0) updates.push({ key: 'stress', value: -1 * stress, enabled: true }); - if (fear !== 0) updates.push({ key: 'fear', value: fear, enabled: true }); + if (hope !== 0) updates.push({ key: 'hope', value: hope, total: -1 * hope, enabled: true }); + if (stress !== 0) updates.push({ key: 'stress', value: -1 * stress, total: stress, enabled: true }); + if (fear !== 0) updates.push({ key: 'fear', value: fear, total: -1 * fear, enabled: true }); const resourceUpdates = new ResourceUpdateMap(actor); resourceUpdates.addResources(updates); diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs index 6467edd7..3c5192be 100644 --- a/module/helpers/utils.mjs +++ b/module/helpers/utils.mjs @@ -885,8 +885,3 @@ export async function triggerChatRollFx(rolls, options = { whisper: false, blind foundry.audio.AudioHelper.play({ src: CONFIG.sounds.dice }); } } - -export function shouldUseHopeFearAutomation(options = { gmAsPlayer: true }) { - const { hopeFear } = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation); - return (!game.user.isGM || options.gmAsPlayer) ? hopeFear.players : hopeFear.gm; -} \ No newline at end of file diff --git a/styles/less/dialog/tag-team-dialog/initialization.less b/styles/less/dialog/tag-team-dialog/initialization.less index e79ed65c..d6f7ad29 100644 --- a/styles/less/dialog/tag-team-dialog/initialization.less +++ b/styles/less/dialog/tag-team-dialog/initialization.less @@ -88,21 +88,9 @@ grid-template-columns: 1fr 1fr; gap: 8px; - .inactive { + &.inactive { opacity: 0.4; } - - .initiator-cost-fields { - display: flex; - flex-direction: column; - align-items: flex-start; - - .initiator-cost-inputs { - display: grid; - grid-template-columns: auto 1fr; - align-items: center; - } - } } footer { diff --git a/styles/less/sheets/actors/adversary/features.less b/styles/less/sheets/actors/adversary/features.less index f5bbd8aa..c7731df7 100644 --- a/styles/less/sheets/actors/adversary/features.less +++ b/styles/less/sheets/actors/adversary/features.less @@ -16,5 +16,15 @@ scrollbar-gutter: stable; .with-scroll-shadows(); } + > button { + --button-size: 1.75rem; + width: 1.75rem; + position: absolute; + inset: auto 16px 0 auto; + box-shadow: 0 0 5px @light-black; + } + &:has(> button) .feature-section { + padding-bottom: calc(1px + 1.75rem); + } } } diff --git a/styles/less/sheets/actors/environment/features.less b/styles/less/sheets/actors/environment/features.less index 295636a7..a8fff527 100644 --- a/styles/less/sheets/actors/environment/features.less +++ b/styles/less/sheets/actors/environment/features.less @@ -14,5 +14,15 @@ scrollbar-gutter: stable; .with-scroll-shadows(); } + > button { + --button-size: 1.75rem; + width: 1.75rem; + position: absolute; + inset: auto 16px 0 auto; + box-shadow: 0 0 5px @light-black; + } + &:has(> button) .feature-section { + padding-bottom: calc(1px + 1.75rem); + } } } diff --git a/styles/less/ui/game-pause/game-pause.less b/styles/less/ui/game-pause/game-pause.less index daf9a1e4..60d08bec 100644 --- a/styles/less/ui/game-pause/game-pause.less +++ b/styles/less/ui/game-pause/game-pause.less @@ -1,34 +1,23 @@ @import '../../utils/mixin.less'; #pause.dh-style { - animation: none; - - img { - width: 125px; - height: 125px; - } - figcaption { - --base-shadow: drop-shadow(2px 2px 2px black); position: absolute; margin-top: 24px; animation: pause-pulse 3s ease-in-out infinite; - font-size: var(--font-size-30); - letter-spacing: 0.18em; - filter: var(--base-shadow); } @keyframes pause-pulse { 0% { - filter: var(--base-shadow) drop-shadow(0 0 5px @secondary-blue); + filter: drop-shadow(0 0 5px @secondary-blue); } 50% { - filter: var(--base-shadow) drop-shadow(0 0 5px @golden-secondary); + filter: drop-shadow(0 0 5px @golden); } 100% { - filter: var(--base-shadow) drop-shadow(0 0 5px @secondary-blue); + filter: drop-shadow(0 0 5px @secondary-blue); } } } \ No newline at end of file diff --git a/styles/less/utils/fonts.less b/styles/less/utils/fonts.less index 72ee1a85..07da3389 100755 --- a/styles/less/utils/fonts.less +++ b/styles/less/utils/fonts.less @@ -10,7 +10,6 @@ --font-size-8: 0.5rem; --font-size-9: 0.5625rem; --font-size-22: 1.375rem; - --font-size-30: 1.875rem; } @font-title: ~"var(--dh-font-title, 'Cinzel Decorative'), serif"; diff --git a/templates/dialogs/tagTeamDialog/initialization.hbs b/templates/dialogs/tagTeamDialog/initialization.hbs index 40491e1b..0b92e68e 100644 --- a/templates/dialogs/tagTeamDialog/initialization.hbs +++ b/templates/dialogs/tagTeamDialog/initialization.hbs @@ -26,16 +26,11 @@ -
+
-
- - -
+
+ +
diff --git a/templates/sheets-settings/adversary-settings/features.hbs b/templates/sheets-settings/adversary-settings/features.hbs index 1cab8cfe..2f2f5f47 100644 --- a/templates/sheets-settings/adversary-settings/features.hbs +++ b/templates/sheets-settings/adversary-settings/features.hbs @@ -3,31 +3,27 @@ data-tab='{{tabs.features.id}}' data-group='{{tabs.features.group}}' > - {{#each featureGroups as |group|}} -
- - {{group.label}} - - - - -
    - {{#each group.features as |feature|}} - {{> 'daggerheart.inventory-item' - item=feature - type='feature' - actorType=@root.document.type - hideTags=true - hideContextMenu=true - hideResources=true - showActions=false - hideTooltip=true - }} - {{/each}} -
-
- {{/each}} -
- {{localize "DAGGERHEART.GENERAL.dropFeaturesHere"}} -
+ +
+ {{localize tabs.features.label}} +
    + {{#each @root.features as |feature|}} +
  • + +
    + {{feature.name}} +
    +
    + + +
    +
  • + {{/each}} +
+
+ {{localize "DAGGERHEART.GENERAL.dropFeaturesHere"}} +
+
\ No newline at end of file diff --git a/templates/sheets-settings/environment-settings/features.hbs b/templates/sheets-settings/environment-settings/features.hbs index 1cab8cfe..579fe74e 100644 --- a/templates/sheets-settings/environment-settings/features.hbs +++ b/templates/sheets-settings/environment-settings/features.hbs @@ -3,31 +3,24 @@ data-tab='{{tabs.features.id}}' data-group='{{tabs.features.group}}' > - {{#each featureGroups as |group|}} -
- - {{group.label}} - - - - -
    - {{#each group.features as |feature|}} - {{> 'daggerheart.inventory-item' - item=feature - type='feature' - actorType=@root.document.type - hideTags=true - hideContextMenu=true - hideResources=true - showActions=false - hideTooltip=true - }} - {{/each}} -
-
- {{/each}} -
- {{localize "DAGGERHEART.GENERAL.dropFeaturesHere"}} -
+ +
+ {{localize tabs.features.label}} +
    + {{#each @root.features as |feature|}} +
  • + +
    + {{feature.name}} +
    +
    + + +
    +
  • + {{/each}} +
+
\ No newline at end of file diff --git a/templates/sheets-settings/npc-settings/features.hbs b/templates/sheets-settings/npc-settings/features.hbs index 1cab8cfe..2f2f5f47 100644 --- a/templates/sheets-settings/npc-settings/features.hbs +++ b/templates/sheets-settings/npc-settings/features.hbs @@ -3,31 +3,27 @@ data-tab='{{tabs.features.id}}' data-group='{{tabs.features.group}}' > - {{#each featureGroups as |group|}} -
- - {{group.label}} - - - - -
    - {{#each group.features as |feature|}} - {{> 'daggerheart.inventory-item' - item=feature - type='feature' - actorType=@root.document.type - hideTags=true - hideContextMenu=true - hideResources=true - showActions=false - hideTooltip=true - }} - {{/each}} -
-
- {{/each}} -
- {{localize "DAGGERHEART.GENERAL.dropFeaturesHere"}} -
+ +
+ {{localize tabs.features.label}} +
    + {{#each @root.features as |feature|}} +
  • + +
    + {{feature.name}} +
    +
    + + +
    +
  • + {{/each}} +
+
+ {{localize "DAGGERHEART.GENERAL.dropFeaturesHere"}} +
+
\ No newline at end of file diff --git a/templates/sheets/actors/adversary/features.hbs b/templates/sheets/actors/adversary/features.hbs index 8430d454..685540e7 100644 --- a/templates/sheets/actors/adversary/features.hbs +++ b/templates/sheets/actors/adversary/features.hbs @@ -12,4 +12,9 @@ }} {{/each}} + {{#if @root.editable}} + + {{/if}} diff --git a/templates/sheets/actors/environment/features.hbs b/templates/sheets/actors/environment/features.hbs index 264d6bf5..1dbd4b94 100644 --- a/templates/sheets/actors/environment/features.hbs +++ b/templates/sheets/actors/environment/features.hbs @@ -14,5 +14,10 @@ showActions=@root.editable }} {{/each}} - + + {{#if @root.editable}} + + {{/if}} \ No newline at end of file diff --git a/templates/sheets/global/partials/inventory-item-V2.hbs b/templates/sheets/global/partials/inventory-item-V2.hbs index f7d22a30..523e9304 100644 --- a/templates/sheets/global/partials/inventory-item-V2.hbs +++ b/templates/sheets/global/partials/inventory-item-V2.hbs @@ -27,17 +27,17 @@ Parameters: >
{{!-- Image --}} -
- - {{#if (and item.usable (ne showActions false))}} - {{#if @root.isNPC}} - d20 - {{else}} - 2d12 - {{/if}} +
+ + {{#if item.usable}} + {{#if @root.isNPC}} + d20 + {{else}} + 2d12 {{/if}} + {{/if}}
{{!-- Name & Tags --}} @@ -46,10 +46,10 @@ Parameters: {{localize item.name}} {{#unless (or noExtensible (not item.system.description))}}{{/unless}} {{!-- Tags Start --}} - {{#if (not hideTags)}} + {{#if (not ../hideTags)}} {{#> "systems/daggerheart/templates/sheets/global/partials/item-tags.hbs" item}} {{#if (eq ../type 'feature')}} - {{#if (and system.featureForm (ne @root.document.type "character"))}} + {{#if (and system.featureForm (or (eq @root.document.type "adversary") (eq @root.document.type "environment")))}}
{{localize (concat "DAGGERHEART.CONFIG.FeatureForm." system.featureForm)}}