diff --git a/lang/en.json b/lang/en.json index a824d379..7b8b45c7 100755 --- a/lang/en.json +++ b/lang/en.json @@ -113,9 +113,7 @@ "deleteTriggerTitle": "Delete Trigger", "deleteTriggerContent": "Are you sure you want to delete the {trigger} trigger?", "advantageState": "Advantage State", - "damageOnSave": "Damage on Save", - "useDefaultItemValues": "Use default Item values", - "itemDamageIsUsed": "Item Damage Is Used" + "damageOnSave": "Damage on Save" }, "RollField": { "diceRolling": { @@ -130,7 +128,7 @@ "attackModifier": "Attack Modifier", "attackName": "Attack Name", "criticalThreshold": "Critical Threshold", - "includeBase": { "label": "Use Item Damage" }, + "includeBase": { "label": "Include Item Damage" }, "groupAttack": { "label": "Group Attack" }, "multiplier": "Multiplier", "saveHint": "Set a default Trait to enable Reaction Roll. It can be changed later in Reaction Roll Dialog.", @@ -3235,7 +3233,6 @@ "Tooltip": { "disableEffect": "Disable Effect", "enableEffect": "Enable Effect", - "edit": "Edit", "openItemWorld": "Open Item World", "openActorWorld": "Open Actor World", "sendToChat": "Send to Chat", diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index 3b029771..f2686fdd 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -12,6 +12,8 @@ export default class CharacterSheet extends DHBaseActorSheet { static DEFAULT_OPTIONS = { classes: ['character'], position: { width: 850, height: 800 }, + /* Foundry adds disabled to all buttons and inputs if editPermission is missing. This is not desired. */ + editPermission: CONST.DOCUMENT_OWNERSHIP_LEVELS.OBSERVER, actions: { toggleVault: CharacterSheet.#toggleVault, rollAttribute: CharacterSheet.#rollAttribute, @@ -66,7 +68,7 @@ export default class CharacterSheet extends DHBaseActorSheet { } }, { - handler: CharacterSheet.#getEquipmentContextOptions, + handler: CharacterSheet.#getEquipamentContextOptions, selector: '[data-item-uuid][data-type="armor"], [data-item-uuid][data-type="weapon"]', options: { parentClassHooks: false, @@ -168,16 +170,6 @@ export default class CharacterSheet extends DHBaseActorSheet { return applicationOptions; } - /** @inheritdoc */ - _toggleDisabled(disabled) { - // Overriden to only disable text inputs by default. - // Everything else is done by checking @root.editable in the sheet - const form = this.form; - for (const input of form.querySelectorAll("input:not([type=search]), .editor.prosemirror")) { - input.disabled = disabled; - } - } - /** @inheritDoc */ async _onRender(context, options) { await super._onRender(context, options); @@ -323,11 +315,11 @@ export default class CharacterSheet extends DHBaseActorSheet { /**@type {import('@client/applications/ux/context-menu.mjs').ContextMenuEntry[]} */ const options = [ { - label: 'toLoadout', + name: 'toLoadout', icon: 'fa-solid fa-arrow-up', - visible: target => { + condition: target => { const doc = getDocFromElementSync(target); - return doc?.isOwner && doc.system.inVault; + return doc && doc.system.inVault; }, callback: async target => { const doc = await getDocFromElement(target); @@ -337,11 +329,11 @@ export default class CharacterSheet extends DHBaseActorSheet { } }, { - label: 'recall', + name: 'recall', icon: 'fa-solid fa-bolt-lightning', - visible: target => { + condition: target => { const doc = getDocFromElementSync(target); - return doc?.isOwner && doc.system.inVault; + return doc && doc.system.inVault; }, callback: async (target, event) => { const doc = await getDocFromElement(target); @@ -376,17 +368,17 @@ export default class CharacterSheet extends DHBaseActorSheet { } }, { - label: 'toVault', + name: 'toVault', icon: 'fa-solid fa-arrow-down', - visible: target => { + condition: target => { const doc = getDocFromElementSync(target); - return doc?.isOwner && !doc.system.inVault; + return doc && !doc.system.inVault; }, callback: async target => (await getDocFromElement(target)).update({ 'system.inVault': true }) } ].map(option => ({ ...option, - label: `DAGGERHEART.APPLICATIONS.ContextMenu.${option.label}`, + name: `DAGGERHEART.APPLICATIONS.ContextMenu.${option.name}`, icon: `` })); @@ -399,29 +391,29 @@ export default class CharacterSheet extends DHBaseActorSheet { * @this {CharacterSheet} * @protected */ - static #getEquipmentContextOptions() { + static #getEquipamentContextOptions() { const options = [ { - label: 'equip', + name: 'equip', icon: 'fa-solid fa-hands', - visible: target => { + condition: target => { const doc = getDocFromElementSync(target); - return doc.isOwner && doc && !doc.system.equipped; + return doc && !doc.system.equipped; }, callback: (target, event) => CharacterSheet.#toggleEquipItem.call(this, event, target) }, { - label: 'unequip', + name: 'unequip', icon: 'fa-solid fa-hands', - visible: target => { + condition: target => { const doc = getDocFromElementSync(target); - return doc.isOwner && doc && doc.system.equipped; + return doc && doc.system.equipped; }, callback: (target, event) => CharacterSheet.#toggleEquipItem.call(this, event, target) } ].map(option => ({ ...option, - label: `DAGGERHEART.APPLICATIONS.ContextMenu.${option.label}`, + name: `DAGGERHEART.APPLICATIONS.ContextMenu.${option.name}`, icon: `` })); diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs index e0110ae3..e93ce774 100644 --- a/module/applications/sheets/api/application-mixin.mjs +++ b/module/applications/sheets/api/application-mixin.mjs @@ -418,18 +418,18 @@ export default function DHApplicationMixin(Base) { /**@type {import('@client/applications/ux/context-menu.mjs').ContextMenuEntry[]} */ const options = [ { - label: 'disableEffect', + name: 'disableEffect', icon: 'fa-solid fa-lightbulb', - visible: element => { + condition: element => { const target = element.closest('[data-item-uuid]'); return !target.dataset.disabled && target.dataset.itemType !== 'beastform'; }, callback: async target => (await getDocFromElement(target)).update({ disabled: true }) }, { - label: 'enableEffect', + name: 'enableEffect', icon: 'fa-regular fa-lightbulb', - visible: element => { + condition: element => { const target = element.closest('[data-item-uuid]'); return target.dataset.disabled && target.dataset.itemType !== 'beastform'; }, @@ -437,7 +437,7 @@ export default function DHApplicationMixin(Base) { } ].map(option => ({ ...option, - label: `DAGGERHEART.APPLICATIONS.ContextMenu.${option.label}`, + name: `DAGGERHEART.APPLICATIONS.ContextMenu.${option.name}`, icon: `` })); @@ -468,14 +468,14 @@ export default function DHApplicationMixin(Base) { _getContextMenuCommonOptions({ usable = false, toChat = false, deletable = true }) { const options = [ { - label: 'CONTROLS.CommonEdit', + name: 'CONTROLS.CommonEdit', icon: 'fa-solid fa-pen-to-square', - visible: target => { + condition: target => { const { dataset } = target.closest('[data-item-uuid]'); const doc = getDocFromElementSync(target); return ( (!dataset.noCompendiumEdit && !doc) || - (doc?.isOwner && (!doc?.hasOwnProperty('systemPath') || doc?.inCollection)) + (doc && (!doc?.hasOwnProperty('systemPath') || doc?.inCollection)) ); }, callback: async target => (await getDocFromElement(target)).sheet.render({ force: true }) @@ -484,12 +484,11 @@ export default function DHApplicationMixin(Base) { if (usable) { options.unshift({ - label: 'DAGGERHEART.GENERAL.damage', + name: 'DAGGERHEART.GENERAL.damage', icon: 'fa-solid fa-explosion', - visible: target => { + condition: target => { const doc = getDocFromElementSync(target); return ( - doc?.isOwner && !foundry.utils.isEmpty(doc?.system?.attack?.damage.parts) || !foundry.utils.isEmpty(doc?.damage?.parts) ); @@ -508,11 +507,11 @@ export default function DHApplicationMixin(Base) { }); options.unshift({ - label: 'DAGGERHEART.APPLICATIONS.ContextMenu.useItem', + name: 'DAGGERHEART.APPLICATIONS.ContextMenu.useItem', icon: 'fa-solid fa-burst', - visible: target => { + condition: target => { const doc = getDocFromElementSync(target); - return doc?.isOwner && !(doc.type === 'domainCard' && doc.system.inVault); + return doc && !(doc.type === 'domainCard' && doc.system.inVault); }, callback: async (target, event) => (await getDocFromElement(target)).use(event) }); @@ -520,19 +519,18 @@ export default function DHApplicationMixin(Base) { if (toChat) options.push({ - label: 'DAGGERHEART.APPLICATIONS.ContextMenu.sendToChat', + name: 'DAGGERHEART.APPLICATIONS.ContextMenu.sendToChat', icon: 'fa-solid fa-message', callback: async target => (await getDocFromElement(target)).toChat(this.document.uuid) }); if (deletable) options.push({ - label: 'CONTROLS.CommonDelete', + name: 'CONTROLS.CommonDelete', icon: 'fa-solid fa-trash', - visible: element => { + condition: element => { const target = element.closest('[data-item-uuid]'); - const doc = getDocFromElementSync(target); - return doc?.isOwner && target.dataset.itemType !== 'beastform'; + return target.dataset.itemType !== 'beastform'; }, callback: async (target, event) => { const doc = await getDocFromElement(target); diff --git a/module/applications/sidebar/tabs/actorDirectory.mjs b/module/applications/sidebar/tabs/actorDirectory.mjs index 89da1426..1306de61 100644 --- a/module/applications/sidebar/tabs/actorDirectory.mjs +++ b/module/applications/sidebar/tabs/actorDirectory.mjs @@ -48,9 +48,9 @@ export default class DhActorDirectory extends foundry.applications.sidebar.tabs. const options = super._getEntryContextOptions(); options.push( { - label: 'DAGGERHEART.UI.Sidebar.actorDirectory.duplicateToNewTier', + name: 'DAGGERHEART.UI.Sidebar.actorDirectory.duplicateToNewTier', icon: ``, - visible: li => { + condition: li => { const actor = game.actors.get(li.dataset.entryId); return actor?.type === 'adversary' && actor.system.type !== 'social'; }, @@ -92,9 +92,9 @@ export default class DhActorDirectory extends foundry.applications.sidebar.tabs. } }, { - label: 'DAGGERHEART.UI.Sidebar.actorDirectory.activateParty', + name: 'DAGGERHEART.UI.Sidebar.actorDirectory.activateParty', icon: ``, - visible: li => { + condition: li => { const actor = game.actors.get(li.dataset.entryId); return actor && actor.type === 'party' && !actor.system.active; }, diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs index 34b25591..59939963 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -103,10 +103,23 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo _getEntryContextOptions() { return [ ...super._getEntryContextOptions(), + // { + // name: 'Reroll', + // icon: '', + // condition: li => { + // const message = game.messages.get(li.dataset.messageId); + + // return (game.user.isGM || message.isAuthor) && message.rolls.length > 0; + // }, + // callback: li => { + // const message = game.messages.get(li.dataset.messageId); + // new game.system.api.applications.dialogs.RerollDialog(message).render({ force: true }); + // } + // }, { - label: 'DAGGERHEART.UI.ChatLog.rerollDamage', + name: game.i18n.localize('DAGGERHEART.UI.ChatLog.rerollDamage'), icon: '', - visible: li => { + condition: li => { const message = game.messages.get(li.dataset.messageId); const hasRolledDamage = message.system.hasDamage ? Object.keys(message.system.damage).length > 0 diff --git a/module/applications/ui/combatTracker.mjs b/module/applications/ui/combatTracker.mjs index fb19a17e..1043e128 100644 --- a/module/applications/ui/combatTracker.mjs +++ b/module/applications/ui/combatTracker.mjs @@ -84,15 +84,15 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C _getCombatContextOptions() { return [ { - label: 'COMBAT.ClearMovementHistories', + name: 'COMBAT.ClearMovementHistories', icon: '', - visible: () => game.user.isGM && this.viewed?.combatants.size > 0, + condition: () => game.user.isGM && this.viewed?.combatants.size > 0, callback: () => this.viewed.clearMovementHistories() }, { - label: 'COMBAT.Delete', + name: 'COMBAT.Delete', icon: '', - visible: () => game.user.isGM && !!this.viewed, + condition: () => game.user.isGM && !!this.viewed, callback: () => this.viewed.endCombat() } ]; diff --git a/module/data/action/attackAction.mjs b/module/data/action/attackAction.mjs index f54ea282..5e93d70b 100644 --- a/module/data/action/attackAction.mjs +++ b/module/data/action/attackAction.mjs @@ -13,7 +13,7 @@ export default class DHAttackAction extends DHDamageAction { if (!!this.item?.system?.attack) { if (this.damage.includeBase) { const baseDamage = this.getParentDamage(); - this.damage.parts.hitPoints = new DHDamageData(baseDamage); + this.damage.parts.unshift(new DHDamageData(baseDamage)); } if (this.roll.useDefault) { this.roll.trait = this.item.system.attack.roll.trait; diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index f4835f34..0992350b 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -110,11 +110,6 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel return this._id; } - /** Returns true if the current user is the owner of the containing item */ - get isOwner() { - return this.item?.isOwner ?? true; - } - /** * Return Item the action is attached too. */ @@ -148,12 +143,6 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel : null; } - /** Returns true if the action is usable */ - get usable() { - const actor = this.actor; - return this.isOwner && actor?.type === 'character'; - } - static getRollType(parent) { return 'trait'; } diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs index cc198dc4..72718c5e 100644 --- a/module/data/item/base.mjs +++ b/module/data/item/base.mjs @@ -108,8 +108,6 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { } get actionsList() { - // No actions on non-characters - if (this.actor && this.actor.type !== 'character') return []; return this.actions; } diff --git a/module/data/item/weapon.mjs b/module/data/item/weapon.mjs index 75e6dc8e..9335037c 100644 --- a/module/data/item/weapon.mjs +++ b/module/data/item/weapon.mjs @@ -99,9 +99,7 @@ export default class DHWeapon extends AttachableItem { /* -------------------------------------------- */ get actionsList() { - // No actions on non-characters - if (this.actor && this.actor.type !== 'character') return []; - return [this.attack, ...super.actionsList]; + return [this.attack, ...this.actions]; } get customActions() { diff --git a/module/documents/item.mjs b/module/documents/item.mjs index 8ece56fa..a8b41b05 100644 --- a/module/documents/item.mjs +++ b/module/documents/item.mjs @@ -76,13 +76,6 @@ export default class DHItem extends foundry.documents.Item { return this.system.metadata.isInventoryItem ?? false; } - /** Returns true if the item can be used */ - get usable() { - const actor = this.actor; - const actionsList = this.system.actionsList; - return this.isOwner && actor?.type === 'character' && (actionsList?.size || actionsList?.length); - } - /** @inheritdoc */ static async createDialog(data = {}, createOptions = {}, options = {}) { const { folders, types, template, context = {}, ...dialogOptions } = options; diff --git a/styles/less/sheets/actors/character/sheet.less b/styles/less/sheets/actors/character/sheet.less index 68792c99..ee6580fd 100644 --- a/styles/less/sheets/actors/character/sheet.less +++ b/styles/less/sheets/actors/character/sheet.less @@ -11,6 +11,21 @@ padding-bottom: 0; overflow-x: auto; + &.viewMode { + button:not(.btn-toggle-view), + input:not(.search), + .controls, + .character-sidebar-sheet, + .img-portait, + .name-row, + .hope-section, + .downtime-section, + .character-traits, + .card-list { + pointer-events: none; + } + } + .character-sidebar-sheet { grid-row: 1 / span 2; grid-column: 1; diff --git a/styles/less/sheets/actors/character/sidebar.less b/styles/less/sheets/actors/character/sidebar.less index b159a8e8..e7027163 100644 --- a/styles/less/sheets/actors/character/sidebar.less +++ b/styles/less/sheets/actors/character/sidebar.less @@ -316,9 +316,9 @@ border-radius: 3px; background: light-dark(@dark-blue, @golden); clip-path: none; + cursor: pointer; display: flex; align-items: center; - justify-content: center; gap: 4px; border: 1px solid transparent; transition: all 0.3s ease; diff --git a/templates/actionTypes/damage.hbs b/templates/actionTypes/damage.hbs index 454d0413..192c5be5 100644 --- a/templates/actionTypes/damage.hbs +++ b/templates/actionTypes/damage.hbs @@ -21,7 +21,7 @@ {{!-- Handlebars uses Symbol.Iterator to produce index|key. This isn't compatible with our parts object, so we instead use applyTo, which is the same value --}} - {{#each source.parts as |dmg key|}} + {{#each source.parts as |dmg|}}