diff --git a/assets/icons/dice/adv/d10.svg b/assets/icons/dice/adv/d10.svg new file mode 100644 index 00000000..4dc6a6f9 --- /dev/null +++ b/assets/icons/dice/adv/d10.svg @@ -0,0 +1,18 @@ + diff --git a/assets/icons/dice/adv/d12.svg b/assets/icons/dice/adv/d12.svg new file mode 100644 index 00000000..f9cf1301 --- /dev/null +++ b/assets/icons/dice/adv/d12.svg @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/assets/icons/dice/adv/d20.svg b/assets/icons/dice/adv/d20.svg new file mode 100644 index 00000000..098d3131 --- /dev/null +++ b/assets/icons/dice/adv/d20.svg @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/assets/icons/dice/adv/d4.svg b/assets/icons/dice/adv/d4.svg new file mode 100644 index 00000000..e52c5f46 --- /dev/null +++ b/assets/icons/dice/adv/d4.svg @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/assets/icons/dice/adv/d6.svg b/assets/icons/dice/adv/d6.svg new file mode 100644 index 00000000..5ea7ebc1 --- /dev/null +++ b/assets/icons/dice/adv/d6.svg @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/assets/icons/dice/adv/d8.svg b/assets/icons/dice/adv/d8.svg new file mode 100644 index 00000000..aa733008 --- /dev/null +++ b/assets/icons/dice/adv/d8.svg @@ -0,0 +1,16 @@ + diff --git a/assets/icons/dice/default/d10.svg b/assets/icons/dice/default/d10.svg new file mode 100644 index 00000000..cdca9728 --- /dev/null +++ b/assets/icons/dice/default/d10.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/dice/default/d12.svg b/assets/icons/dice/default/d12.svg new file mode 100644 index 00000000..e6271a75 --- /dev/null +++ b/assets/icons/dice/default/d12.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/dice/default/d20.svg b/assets/icons/dice/default/d20.svg new file mode 100644 index 00000000..4d3ac16e --- /dev/null +++ b/assets/icons/dice/default/d20.svg @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/assets/icons/dice/default/d4.svg b/assets/icons/dice/default/d4.svg new file mode 100644 index 00000000..db5ad410 --- /dev/null +++ b/assets/icons/dice/default/d4.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/dice/default/d6.svg b/assets/icons/dice/default/d6.svg new file mode 100644 index 00000000..6bc98c66 --- /dev/null +++ b/assets/icons/dice/default/d6.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/dice/default/d8.svg b/assets/icons/dice/default/d8.svg new file mode 100644 index 00000000..edf35cff --- /dev/null +++ b/assets/icons/dice/default/d8.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/icons/dice/disadv/d10.svg b/assets/icons/dice/disadv/d10.svg new file mode 100644 index 00000000..af4d0d19 --- /dev/null +++ b/assets/icons/dice/disadv/d10.svg @@ -0,0 +1,18 @@ + diff --git a/assets/icons/dice/disadv/d12.svg b/assets/icons/dice/disadv/d12.svg new file mode 100644 index 00000000..75a7073c --- /dev/null +++ b/assets/icons/dice/disadv/d12.svg @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/assets/icons/dice/disadv/d20.svg b/assets/icons/dice/disadv/d20.svg new file mode 100644 index 00000000..e4130440 --- /dev/null +++ b/assets/icons/dice/disadv/d20.svg @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/assets/icons/dice/disadv/d4.svg b/assets/icons/dice/disadv/d4.svg new file mode 100644 index 00000000..3ec74176 --- /dev/null +++ b/assets/icons/dice/disadv/d4.svg @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/assets/icons/dice/disadv/d6.svg b/assets/icons/dice/disadv/d6.svg new file mode 100644 index 00000000..7e79e2ed --- /dev/null +++ b/assets/icons/dice/disadv/d6.svg @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/assets/icons/dice/disadv/d8.svg b/assets/icons/dice/disadv/d8.svg new file mode 100644 index 00000000..999d818f --- /dev/null +++ b/assets/icons/dice/disadv/d8.svg @@ -0,0 +1,16 @@ + diff --git a/assets/icons/dice/fear/d10.svg b/assets/icons/dice/fear/d10.svg new file mode 100644 index 00000000..80236173 --- /dev/null +++ b/assets/icons/dice/fear/d10.svg @@ -0,0 +1,20 @@ + diff --git a/assets/icons/dice/fear/d12.svg b/assets/icons/dice/fear/d12.svg new file mode 100644 index 00000000..08841af4 --- /dev/null +++ b/assets/icons/dice/fear/d12.svg @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/assets/icons/dice/fear/d20.svg b/assets/icons/dice/fear/d20.svg new file mode 100644 index 00000000..bd4e12a8 --- /dev/null +++ b/assets/icons/dice/fear/d20.svg @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/assets/icons/dice/fear/d4.svg b/assets/icons/dice/fear/d4.svg new file mode 100644 index 00000000..b641d519 --- /dev/null +++ b/assets/icons/dice/fear/d4.svg @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/assets/icons/dice/fear/d6.svg b/assets/icons/dice/fear/d6.svg new file mode 100644 index 00000000..bcc3fac2 --- /dev/null +++ b/assets/icons/dice/fear/d6.svg @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/assets/icons/dice/fear/d8.svg b/assets/icons/dice/fear/d8.svg new file mode 100644 index 00000000..9a706322 --- /dev/null +++ b/assets/icons/dice/fear/d8.svg @@ -0,0 +1,16 @@ + diff --git a/assets/icons/dice/hope/d10.svg b/assets/icons/dice/hope/d10.svg new file mode 100644 index 00000000..e5566c21 --- /dev/null +++ b/assets/icons/dice/hope/d10.svg @@ -0,0 +1,20 @@ + diff --git a/assets/icons/dice/hope/d12.svg b/assets/icons/dice/hope/d12.svg new file mode 100644 index 00000000..a93766fe --- /dev/null +++ b/assets/icons/dice/hope/d12.svg @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/assets/icons/dice/hope/d20.svg b/assets/icons/dice/hope/d20.svg new file mode 100644 index 00000000..bb87a31e --- /dev/null +++ b/assets/icons/dice/hope/d20.svg @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/assets/icons/dice/hope/d4.svg b/assets/icons/dice/hope/d4.svg new file mode 100644 index 00000000..ab238828 --- /dev/null +++ b/assets/icons/dice/hope/d4.svg @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/assets/icons/dice/hope/d6.svg b/assets/icons/dice/hope/d6.svg new file mode 100644 index 00000000..26ea78ea --- /dev/null +++ b/assets/icons/dice/hope/d6.svg @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/assets/icons/dice/hope/d8.svg b/assets/icons/dice/hope/d8.svg new file mode 100644 index 00000000..584b0fdc --- /dev/null +++ b/assets/icons/dice/hope/d8.svg @@ -0,0 +1,16 @@ + diff --git a/daggerheart.mjs b/daggerheart.mjs index 81b404d5..82c56dff 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -124,7 +124,7 @@ Hooks.once('init', () => { CONFIG.Token.rulerClass = placeables.DhTokenRuler; CONFIG.ui.resources = applications.ui.DhFearTracker; - CONFIG.ux.ContextMenu = applications.ux.ContextMenu; + CONFIG.ux.ContextMenu = applications.ux.DHContextMenu; CONFIG.ux.TooltipManager = documents.DhTooltipManager; game.socket.on(`system.${SYSTEM.id}`, socketRegistration.handleSocketEvent); diff --git a/lang/en.json b/lang/en.json index 4c374458..500c032a 100755 --- a/lang/en.json +++ b/lang/en.json @@ -245,7 +245,8 @@ "potentialAdversaries": "Potential Adversaries", "adversaries": "Adversaries" }, - "basics": "Basics" + "basics": "Basics", + "dualityRoll": "Duality Roll" }, "ActionType": { "passive": "Passive", diff --git a/module/applications/dialogs/costSelectionDialog.mjs b/module/applications/dialogs/costSelectionDialog.mjs index cab0d36d..026aac46 100644 --- a/module/applications/dialogs/costSelectionDialog.mjs +++ b/module/applications/dialogs/costSelectionDialog.mjs @@ -30,7 +30,7 @@ export default class CostSelectionDialog extends HandlebarsApplicationMixin(Appl static PARTS = { costSelection: { id: 'costSelection', - template: 'systems/daggerheart/templates/dialogs/costSelection.hbs' + template: 'systems/daggerheart/templates/dialogs/dice-roll/costSelection.hbs' } }; diff --git a/module/applications/dialogs/d20RollDialog.mjs b/module/applications/dialogs/d20RollDialog.mjs index cf620e43..7eaeacb3 100644 --- a/module/applications/dialogs/d20RollDialog.mjs +++ b/module/applications/dialogs/d20RollDialog.mjs @@ -20,10 +20,12 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio static DEFAULT_OPTIONS = { tag: 'form', id: 'roll-selection', - classes: ['daggerheart', 'views', 'roll-selection'], + classes: ['daggerheart', 'dialog', 'dh-style', 'views', 'roll-selection'], position: { - width: 400, - height: 'auto' + width: 550 + }, + window: { + icon: 'fa-solid fa-dice' }, actions: { updateIsAdvantage: this.updateIsAdvantage, @@ -37,20 +39,29 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio } }; + get title() { + return this.config.title; + } + /** @override */ static PARTS = { - costSelection: { - id: 'costSelection', - template: 'systems/daggerheart/templates/dialogs/costSelection.hbs' + header: { + id: 'header', + template: 'systems/daggerheart/templates/dialogs/dice-roll/header.hbs' }, rollSelection: { id: 'rollSelection', - template: 'systems/daggerheart/templates/dialogs/rollSelection.hbs' + template: 'systems/daggerheart/templates/dialogs/dice-roll/rollSelection.hbs' + }, + costSelection: { + id: 'costSelection', + template: 'systems/daggerheart/templates/dialogs/dice-roll/costSelection.hbs' } }; async _prepareContext(_options) { const context = await super._prepareContext(_options); + context.rollConfig = this.config; context.hasRoll = !!this.config.roll; context.roll = this.roll; context.rollType = this.roll?.constructor.name; @@ -60,6 +71,7 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio })); context.selectedExperiences = this.config.experiences; context.advantage = this.config.roll?.advantage; + context.disadvantage = this.config.roll?.disadvantage; context.diceOptions = CONFIG.DH.GENERAL.diceTypes; context.canRoll = true; context.isLite = this.config.roll?.lite; @@ -75,7 +87,6 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio } context.extraFormula = this.config.extraFormula; context.formula = this.roll.constructFormula(this.config); - return context; } @@ -96,6 +107,9 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio static updateIsAdvantage(_, button) { const advantage = Number(button.dataset.advantage); + this.advantage = advantage === 1; + this.disadvantage = advantage === -1; + this.config.roll.advantage = this.config.roll.advantage === advantage ? 0 : advantage; this.render(); } diff --git a/module/applications/dialogs/damageDialog.mjs b/module/applications/dialogs/damageDialog.mjs index 84709251..442a1491 100644 --- a/module/applications/dialogs/damageDialog.mjs +++ b/module/applications/dialogs/damageDialog.mjs @@ -30,7 +30,7 @@ export default class DamageDialog extends HandlebarsApplicationMixin(Application static PARTS = { damageSelection: { id: 'damageSelection', - template: 'systems/daggerheart/templates/dialogs/damageSelection.hbs' + template: 'systems/daggerheart/templates/dialogs/dice-roll/damageSelection.hbs' } }; diff --git a/module/applications/dialogs/damageSelectionDialog.mjs b/module/applications/dialogs/damageSelectionDialog.mjs index f4f44bc8..5248e81d 100644 --- a/module/applications/dialogs/damageSelectionDialog.mjs +++ b/module/applications/dialogs/damageSelectionDialog.mjs @@ -44,7 +44,7 @@ export default class DamageSelectionDialog extends HandlebarsApplicationMixin(Ap static PARTS = { damageSelection: { id: 'damageSelection', - template: 'systems/daggerheart/templates/dialogs/damageSelection.hbs' + template: 'systems/daggerheart/templates/dialogs/dice-roll/damageSelection.hbs' } }; diff --git a/module/applications/sheets/actors/adversary.mjs b/module/applications/sheets/actors/adversary.mjs index a48c1fa4..c12775b1 100644 --- a/module/applications/sheets/actors/adversary.mjs +++ b/module/applications/sheets/actors/adversary.mjs @@ -85,7 +85,8 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) { static async reactionRoll(event) { const config = { event: event, - title: `${this.actor.name} - Reaction Roll`, + title: `Reaction Roll: ${this.actor.name}`, + headerTitle: 'Adversary Reaction Roll', roll: { // modifier: null, type: 'reaction' diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index e3fa7367..c74455b0 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -490,6 +490,19 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) { } } + static async rollAttribute(event, button) { + const abilityLabel = game.i18n.localize(abilities[button.dataset.attribute].label); + const config = { + event: event, + title: `${game.i18n.localize('DAGGERHEART.General.dualityRoll')}: ${this.actor.name}`, + headerTitle: game.i18n.format('DAGGERHEART.Chat.DualityRoll.AbilityCheckTitle', { ability: abilityLabel }), + roll: { + trait: button.dataset.attribute + } + }; + this.document.diceRoll(config); + } + /* -------------------------------------------- */ /* Filter Menus */ /* -------------------------------------------- */ diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs index 182a3539..2c8ad561 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -50,13 +50,13 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo element.addEventListener('mouseenter', this.hoverAdvantage) ); html.querySelectorAll('.advantage').forEach(element => - element.addEventListener('click', event => this.selectAdvantage.bind(this)(event, data.message)) + element.addEventListener('click', event => this.selectAdvantage.call(this, event, data.message)) ); html.querySelectorAll('.ability-use-button').forEach(element => - element.addEventListener('click', event => this.abilityUseButton.bind(this)(event, data.message)) + element.addEventListener('click', event => this.abilityUseButton.call(this, event, data.message)) ); html.querySelectorAll('.action-use-button').forEach(element => - element.addEventListener('click', event => this.actionUseButton.bind(this)(event, data.message)) + element.addEventListener('click', event => this.actionUseButton.call(this, event, data.message)) ); }; @@ -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, @@ -229,24 +229,54 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo } }; - onToggleTargets = async event => { + /** + * Toggle visibility of target containers. + * @param {MouseEvent} event + */ + onToggleTargets(event) { event.stopPropagation(); - $($(event.currentTarget).parent()).find('.target-container').toggleClass('hidden'); - }; + event.currentTarget.parentElement + ?.querySelectorAll('.target-container') + .forEach(el => el.classList.toggle('hidden')); + } - hoverAdvantage = event => { - $(event.currentTarget).siblings('.advantage').toggleClass('unused'); - }; + /** + * Highlight advantage icons on hover. + * @param {MouseEvent} event + */ + hoverAdvantage(event) { + const parent = event.currentTarget.parentElement; + if (!parent) return; - selectAdvantage = async (event, message) => { + parent.querySelectorAll('.advantage').forEach(el => { + if (el !== event.currentTarget) { + el.classList.toggle('unused'); + } + }); + } + + + /** + * Handle selecting an advantage and disable further selection. + * @param {MouseEvent} event + * @param {object} message + */ + async selectAdvantage(event, message) { event.stopPropagation(); const updateMessage = game.messages.get(message._id); - await updateMessage.update({ system: { advantageSelected: event.currentTarget.id === 'hope' ? 1 : 2 } }); + await updateMessage?.update({ + system: { advantageSelected: event.currentTarget.id === 'hope' ? 1 : 2 } + }); + + const parent = event.currentTarget.parentElement; + if (!parent) return; + + parent.querySelectorAll('.advantage').forEach(el => { + el.replaceWith(el.cloneNode(true)); + }); + } - $(event.currentTarget).siblings('.advantage').off('click'); - $(event.currentTarget).off('click'); - }; abilityUseButton = async (event, message) => { event.stopPropagation(); diff --git a/module/applications/ux/_module.mjs b/module/applications/ux/_module.mjs index 5ec0eecf..ead918fa 100644 --- a/module/applications/ux/_module.mjs +++ b/module/applications/ux/_module.mjs @@ -1,2 +1,2 @@ export { default as FilterMenu } from './filter-menu.mjs'; -export { default as ContextMenu } from './contextMenu.mjs'; +export { default as DHContextMenu } from './contextMenu.mjs'; diff --git a/module/applications/ux/contextMenu.mjs b/module/applications/ux/contextMenu.mjs index f7658d42..a913c450 100644 --- a/module/applications/ux/contextMenu.mjs +++ b/module/applications/ux/contextMenu.mjs @@ -1,4 +1,63 @@ -export default class DhContextMenu extends foundry.applications.ux.ContextMenu.implementation { +/** + * @typedef ContextMenuEntry + * @property {string} name The context menu label. Can be localized. + * @property {string} [icon] A string containing an HTML icon element for the menu item. + * @property {string} [classes] Additional CSS classes to apply to this menu item. + * @property {string} [group] An identifier for a group this entry belongs to. + * @property {ContextMenuJQueryCallback} callback The function to call when the menu item is clicked. + * @property {ContextMenuCondition|boolean} [condition] A function to call or boolean value to determine if this entry + * appears in the menu. + */ + +/** + * @callback ContextMenuCondition + * @param {jQuery|HTMLElement} html The element of the context menu entry. + * @returns {boolean} Whether the entry should be rendered in the context menu. + */ + +/** + * @callback ContextMenuCallback + * @param {HTMLElement} target The element that the context menu has been triggered for. + * @returns {unknown} + */ + +/** + * @callback ContextMenuJQueryCallback + * @param {HTMLElement|jQuery} target The element that the context menu has been triggered for. Will + * either be a jQuery object or an HTMLElement instance, depending + * on how the ContextMenu was configured. + * @returns {unknown} + */ + +/** + * @typedef ContextMenuOptions + * @property {string} [eventName="contextmenu"] Optionally override the triggering event which can spawn the menu. If + * the menu is using fixed positioning, this event must be a MouseEvent. + * @property {ContextMenuCallback} [onOpen] A function to call when the context menu is opened. + * @property {ContextMenuCallback} [onClose] A function to call when the context menu is closed. + * @property {boolean} [fixed=false] If true, the context menu is given a fixed position rather than being + * injected into the target. + * @property {boolean} [jQuery=true] If true, callbacks will be passed jQuery objects instead of HTMLElement + * instances. + */ + +/** + * @typedef ContextMenuRenderOptions + * @property {Event} [event] The event that triggered the context menu opening. + * @property {boolean} [animate=true] Animate the context menu opening. + */ + +/** + * A subclass of ContextMenu. + * @extends {foundry.applications.ux.ContextMenu} + */ +export default class DHContextMenu extends foundry.applications.ux.ContextMenu { + /** + * @param {HTMLElement|jQuery} container - The HTML element that contains the context menu targets. + * @param {string} selector - A CSS selector which activates the context menu. + * @param {ContextMenuEntry[]} menuItems - An Array of entries to display in the menu + * @param {ContextMenuOptions} [options] - Additional options to configure the context menu. + */ constructor(container, selector, menuItems, options) { super(container, selector, menuItems, options); @@ -6,12 +65,21 @@ export default class DhContextMenu extends foundry.applications.ux.ContextMenu.i this.#jQuery = options.jQuery; } + /** + * Whether to pass jQuery objects or HTMLElement instances to callback. + * @type {boolean} + */ #jQuery; + /**@inheritdoc */ activateListeners(menu) { menu.addEventListener('click', this.#onClickItem.bind(this)); } + /** + * Handle click events on context menu items. + * @param {PointerEvent} event The click event + */ #onClickItem(event) { event.preventDefault(); event.stopPropagation(); @@ -22,6 +90,12 @@ export default class DhContextMenu extends foundry.applications.ux.ContextMenu.i this.close(); } + /* -------------------------------------------- */ + + /** + * Trigger a context menu event in response to a normal click on a additional options button. + * @param {PointerEvent} event + */ static triggerContextMenu(event) { event.preventDefault(); event.stopPropagation(); diff --git a/module/applications/ux/filter-menu.mjs b/module/applications/ux/filter-menu.mjs index ff2fb036..93d8bbf0 100644 --- a/module/applications/ux/filter-menu.mjs +++ b/module/applications/ux/filter-menu.mjs @@ -197,10 +197,12 @@ export default class FilterMenu extends foundry.applications.ux.ContextMenu { } })); + const sort = arr => game.i18n.sortObjects(arr, 'name'); + return [ - ...game.i18n.sortObjects(typesFilters, 'name'), - ...game.i18n.sortObjects(burdenFilter, 'name'), - ...game.i18n.sortObjects(damageTypeFilter, 'name') + ...sort(typesFilters, 'name'), + ...sort(burdenFilter, 'name'), + ...sort(damageTypeFilter, 'name') ]; } diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index e752421c..b9faecc4 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -244,7 +244,6 @@ export default class DHBaseAction extends foundry.abstract.DataModel { } if (this.hasRoll) { - console.log(config); const rollConfig = this.prepareRoll(config); config.roll = rollConfig; config = await this.actor.diceRoll(config); diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs index c90202fb..7bef3e02 100644 --- a/module/data/item/base.mjs +++ b/module/data/item/base.mjs @@ -1,4 +1,4 @@ -// import { actionsTypes } from '../action/_module.mjs'; +import { actionsTypes } from '../action/_module.mjs'; /** * Describes metadata about the item data model type @@ -55,24 +55,28 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { return data; } + /**@inheritdoc */ async _preCreate(data, options, user) { + // Skip if no initial action is required or actions already exist if (!this.constructor.metadata.hasInitialAction || !foundry.utils.isEmpty(this.actions)) return; - const actionType = { - weapon: 'attack' - }[this.constructor.metadata.type], - cls = game.system.api.models.actionsTypes[actionType], - // cls = actionsTypes.attack, - action = new cls( - { - _id: foundry.utils.randomID(), - type: actionType, - name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].name), - ...cls.getSourceConfig(this.parent) - }, - { - parent: this.parent - } - ); + + const metadataType = this.constructor.metadata.type; + const actionType = { weapon: "attack" }[metadataType]; + const ActionClass = actionsTypes[actionType]; + + const action = new ActionClass( + { + _id: foundry.utils.randomID(), + type: actionType, + name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].name), + ...ActionClass.getSourceConfig(this.parent) + }, + { + parent: this.parent + } + ); + this.updateSource({ actions: [action] }); } + } diff --git a/module/helpers/handlebarsHelper.mjs b/module/helpers/handlebarsHelper.mjs index 6200b690..99c1ec84 100644 --- a/module/helpers/handlebarsHelper.mjs +++ b/module/helpers/handlebarsHelper.mjs @@ -7,49 +7,11 @@ export default class RegisterHandlebarsHelpers { join: this.join, add: this.add, subtract: this.subtract, - objectSelector: this.objectSelector, includes: this.includes, - debug: this.debug, - signedNumber: this.signedNumber, - length: this.length, - switch: this.switch, case: this.case, - eq: this.eq, - ne: this.ne, - lt: this.lt, - gt: this.gt, - lte: this.lte, - gte: this.gte, - and: this.and, - or: this.or }); } - static eq(v1, v2) { - return v1 === v2; - } - static ne(v1, v2) { - return v1 !== v2; - } - static lt(v1, v2) { - return v1 < v2; - } - static gt(v1, v2) { - return v1 > v2; - } - static lte(v1, v2) { - return v1 <= v2; - } - static gte(v1, v2) { - return v1 >= v2; - } - static and() { - return Array.prototype.every.call(arguments, Boolean); - } - static or() { - return Array.prototype.slice.call(arguments, 0, -1).some(Boolean); - } - static times(nr, block) { var accum = ''; for (var i = 0; i < nr; ++i) accum += block.fn(i); @@ -72,59 +34,11 @@ export default class RegisterHandlebarsHelpers { return (Number.isNaN(aNum) ? 0 : aNum) - (Number.isNaN(bNum) ? 0 : bNum); } - static objectSelector(options) { - let { title, values, titleFontSize, ids, style } = options.hash; - - const titleLength = getWidthOfText(title, titleFontSize, true, true); - const margins = 12; - - const buttons = options.fn(); - const nrButtons = Math.max($(buttons).length - 1, 1); - const iconWidth = 26; - - const texts = values - .reduce((acc, x, index) => { - if (x) { - acc.push( - `${x}` - ); - } - - return acc; - }, []) - .join(' '); - - const html = `