import { SYSTEM } from "../../config/system.mjs" export let RollHandler = null Hooks.once('tokenActionHudCoreApiReady', async (coreModule) => { /** * Extends Token Action HUD Core's RollHandler class and handles action events triggered when an action is clicked */ RollHandler = class RollHandler extends coreModule.api.RollHandler { /** * Handle action click * Called by Token Action HUD Core when an action is left or right-clicked * @override * @param {object} event The event * @param {string} encodedValue The encoded value */ async handleActionClick(event, encodedValue) { const [actionTypeId, actionId] = encodedValue.split('|') const knownCharacters = ['protagonist', 'creature'] // If single actor is selected if (this.actor) { await this.#handleAction(event, this.actor, this.token, actionTypeId, actionId) return } const controlledTokens = canvas.tokens.controlled .filter((token) => knownCharacters.includes(token.actor?.type)) // If multiple actors are selected for (const token of controlledTokens) { const actor = token.actor await this.#handleAction(event, actor, token, actionTypeId, actionId) } } /** * Handle action hover * Called by Token Action HUD Core when an action is hovered on or off * @override * @param {object} event The event * @param {string} encodedValue The encoded value */ async handleActionHover(event, encodedValue) { } /** * Handle group click * Called by Token Action HUD Core when a group is right-clicked while the HUD is locked * @override * @param {object} event The event * @param {object} group The group */ async handleGroupClick(event, group) { } /** * Handle action * @private * @param {object} event The event * @param {object} actor The actor * @param {object} token The token * @param {string} actionTypeId The action type id * @param {string} actionId The actionId */ async #handleAction(event, actor, token, actionTypeId, actionId) { console.log('Handling action', actionId, 'of type', actionTypeId, 'for actor', actor.name) switch (actionTypeId) { case 'characteristics': await this.#handleCharacteristicsAction(event, actor, actionId) break case 'skills': await this.#handleSkillsAction(event, actor, actionId) break case 'weapons': await this.#handleWeaponsAction(event, actor, actionId) break case 'damage': await this.#handleDamageAction(event, actor, actionId) break case 'lethality': await this.#handleLethalityAction(event, actor, actionId) break /* case 'rituals': await this.#handleRitualsAction(event, actor, actionId) break */ case 'utility': await this.#handleUtilityAction(token, actionId) break } } /** * Handle Characteristic action * @private * @param {object} event The event * @param {object} actor The actor * @param {string} actionId The action id */ async #handleCharacteristicsAction(event, actor, actionId) { let rollType if (actionId === 'wp' || actionId === 'hp') return if (actionId.includes('_add') || actionId.includes('_subtract')) { const attr = actionId.split('_')[0] const action = actionId.split('_')[1] console.log('Updating', attr, 'with action', action) const update = {} update.system = {} update.system[attr] = {} update.system[attr].value = action === 'add' ? this.actor.system[attr].value + 1 : this.actor.system[attr].value - 1 if (update.system[attr].value > this.actor.system[attr].max || update.system[attr].value < this.actor.system[attr].min) return return await this.actor.update(update) } if (actionId === 'san') { let item = foundry.utils.duplicate(actor.system.san) item.name = game.i18n.localize("CTHULHUETERNAL.Label.SAN") item.targetScore = item.value await actor.system.roll('san', item) } else if (actionId === 'luck') { let item = foundry.utils.duplicate(actor.system.characteristics.int) item.name = game.i18n.localize("CTHULHUETERNAL.Label.Luck") item.value = 10 item.targetScore = 50 await actor.system.roll('luck', item) } else { let item = foundry.utils.duplicate(actor.system.characteristics[actionId]) item.name = game.i18n.localize(`CTHULHUETERNAL.Label.${actionId}Long`) item.targetScore = item.value * 5 await actor.system.roll('char', item) } } /** * Handle Skill action * @private * @param {object} event The event * @param {object} actor The actor * @param {string} actionId The action id */ async #handleSkillsAction(event, actor, actionId) { const skill = actor.items.find(i => i.type === 'skill' && i.id === actionId) if (!skill) return ui.notifications.warn(`Skill not found for action id '${actionId}'`) await actor.system.roll('skill', skill) } /** * Handle Weapon action * @private * @param {object} event The event * @param {object} actor The actor * @param {string} actionId The action id */ async #handleWeaponsAction(event, actor, actionId) { let weapon = actor.items.find(i => i.type === 'weapon' && i.id === actionId) weapon.damageFormula = weapon.system.damage weapon.damageBonus = actor.system.damageBonus await actor.system.roll('weapon', weapon) } /** * Handle Damage action * @private * @param {object} event The event * @param {object} actor The actor * @param {string} actionId The action id */ async #handleDamageAction(event, actor, actionId) { let weapon = actor.items.find(i => i.type === 'weapon' && i.id === actionId) weapon.damageFormula = weapon.system.damage weapon.damageBonus = actor.system.damageBonus await actor.system.roll('damage', weapon) } /** * Handle Lethality action * @private * @param {object} event The event * @param {object} actor The actor * @param {string} actionId The action id */ async #handleLethalityAction(event, actor, actionId) { const item = await this.actor.items.get(actionId) if (item.system.damage !== '' && event.ctrlKey) { const isLethal = !item.system.isLethal await item.update({ 'system.isLethal': isLethal }) } else { const options = { actor: this.actor, rollType: 'lethality', key: item.system.lethality, item } /* TOFIX const roll = new DGLethalityRoll(item.system.damage, {}, options) await this.actor.sheet.processRoll(event, roll)*/ } } /** * Handle Ritual action * @private * @param {object} event The event * @param {object} actor The actor * @param {string} actionId The action id */ async #handleRitualsAction(event, actor, actionId) { const options = { actor: this.actor, rollType: 'ritual', key: actionId } const roll = new DGPercentileRoll('1D100', {}, options) await this.actor.sheet.processRoll(event, roll) } /** * Handle utility action * @private * @param {object} token The token * @param {string} actionId The action id */ async #handleUtilityAction(token, actionId) { switch (actionId) { case 'endTurn': if (game.combat?.current?.tokenId === token.id) { await game.combat?.nextTurn() } break } } } })