diff --git a/lang/en.json b/lang/en.json index a6fa661c..40a10993 100755 --- a/lang/en.json +++ b/lang/en.json @@ -1261,7 +1261,11 @@ "fear": { "name": "Fear", "hint": "The Fear pool of the GM." - } + }, + "hope": "Hope", + "hitPoints": "Hit Points", + "stress": "Stress", + "armorStack": "Armor Marks" }, "VariantRules": { "FIELDS": { @@ -1313,7 +1317,13 @@ "communityTitle": "Community Card", "subclassFeatureTitle": "Subclass Feature" }, - "featureTitle": "Class Feature" + "featureTitle": "Class Feature", + "refundResources": { + "button": "Refund Resources", + "refunded": "Resources Refunded", + "confirmTitle": "Refund Resources", + "confirmText": "Are you sure you want to refund the following resources?" + } }, "Notifications": { "adversaryMissing": "The linked adversary doesn't exist in the world.", @@ -1353,7 +1363,13 @@ "damageAlreadyNone": "The damage has already been reduced to none", "noAvailableArmorMarks": "You have no more available armor marks", "notEnoughStress": "You don't have enough stress", - "damageIgnore": "{character} did not take damage" + "damageIgnore": "{character} did not take damage", + "actorNotFound": "Actor not found", + "noPermissionToRefund": "You don't have permission to refund resources for this actor", + "resourcesAlreadyRefunded": "Resources have already been refunded for this action", + "noResourcesToRefund": "No resources were spent that can be refunded", + "resourcesRefunded": "Resources have been successfully refunded", + "refundFailed": "Failed to refund resources" }, "Tooltip": { "openItemWorld": "Open Item World", diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs index 8a0ff3e0..298e5ff0 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -58,6 +58,9 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo html.querySelectorAll('.action-use-button').forEach(element => element.addEventListener('click', event => this.actionUseButton.call(this, event, data.message)) ); + html.querySelectorAll('.refund-resources-button').forEach(element => + element.addEventListener('click', event => this.onRefundResources.call(this, event, data.message)) + ); }; setupHooks() { @@ -295,4 +298,76 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo action.use(); }; + + /** + * Handle refunding resources spent during an action + * @param {MouseEvent} event + * @param {object} message + */ + onRefundResources = async (event, message) => { + event.stopPropagation(); + + // Get the actor who performed the action + const actor = await this.getActor(message.system.source.actor); + if (!actor) { + ui.notifications.warn(game.i18n.localize('DAGGERHEART.Notification.Warn.ActorNotFound')); + return; + } + + // Check if user has permission to refund resources + if (!actor.isOwner && !game.user.isGM) { + ui.notifications.warn(game.i18n.localize('DAGGERHEART.Notification.Warn.NoPermissionToRefund')); + return; + } + + // Check if resources were already refunded + if (message.system.resourcesRefunded) { + ui.notifications.info(game.i18n.localize('DAGGERHEART.Notification.Info.ResourcesAlreadyRefunded')); + return; + } + + // Get the resources that were spent (stored in the message) + const spentResources = message.system.spentResources; + if (!spentResources || spentResources.length === 0) { + ui.notifications.info(game.i18n.localize('DAGGERHEART.Notification.Info.NoResourcesToRefund')); + return; + } + + // Confirm refund with user + const confirm = await foundry.applications.api.DialogV2.confirm({ + window: { title: game.i18n.localize('DAGGERHEART.Chat.RefundResources.ConfirmTitle') }, + content: `

${game.i18n.localize('DAGGERHEART.Chat.RefundResources.ConfirmText')}

+ ` + }); + + if (!confirm) return; + + try { + // Refund the resources by inverting the values + const refundResources = spentResources.map(resource => ({ + ...resource, + value: -resource.value + })); + + await actor.modifyResource(refundResources); + + // Mark the message as refunded to prevent double refunding + const chatMessage = game.messages.get(message._id); + await chatMessage?.update({ + system: { resourcesRefunded: true } + }); + + // Show success notification + ui.notifications.info(game.i18n.localize('DAGGERHEART.Notification.Info.ResourcesRefunded')); + + // Disable the refund button visually + const button = event.currentTarget; + button.disabled = true; + button.textContent = game.i18n.localize('DAGGERHEART.Chat.RefundResources.Refunded'); + + } catch (error) { + console.error('Error refunding resources:', error); + ui.notifications.error(game.i18n.localize('DAGGERHEART.Notification.Error.RefundFailed')); + } + }; } diff --git a/module/documents/item.mjs b/module/documents/item.mjs index 21674009..3e9d51d8 100644 --- a/module/documents/item.mjs +++ b/module/documents/item.mjs @@ -124,7 +124,11 @@ export default class DHItem extends foundry.documents.Item { img: this.img, name: this.name, description: this.system.description, - actions: [] + actions: this.system.actions ?? [], + source: { + actor: this.actor?.uuid ?? this.actor?.id ?? null, + item: this.id + } }; const msg = new cls({ type: 'abilityUse', diff --git a/package.json b/package.json index d7b51dfd..e9d8f7fb 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,9 @@ "rollup": "^4.40.0" }, "scripts": { - "start": "concurrently \"rollup -c --watch\" \"node ../../../../FoundryDev/main.js --dataPath=../../../ --noupnp\" \"gulp\"", - "start-test": "node ./resources/app/main.js --dataPath=./ && rollup -c --watch && gulp", + "dev": "concurrently \"rollup -c --watch\" \"gulp\"", + "start": "concurrently \"rollup -c --watch\" \"node \\\"C:/Program Files/Foundry Virtual Tabletop V12/resources/app/main.js\\\" --dataPath=\\\"C:/Program Files/Foundry Virtual Tabletop V12/resources/app\\\" --noupnp\" \"gulp\"", + "start-test": "node \"C:/Program Files/Foundry Virtual Tabletop V12/resources/app/main.js\" --dataPath=\"C:/Program Files/Foundry Virtual Tabletop V12/resources/app\" && rollup -c --watch && gulp", "build": "npm run rollup && npm run gulp", "rollup": "rollup -c", "gulp": "gulp less", @@ -29,4 +30,4 @@ "lint-staged": { "**/*": "prettier --write --ignore-unknown" } -} +} \ No newline at end of file diff --git a/styles/daggerheart.css b/styles/daggerheart.css index 8fd6142e..f15583d2 100755 --- a/styles/daggerheart.css +++ b/styles/daggerheart.css @@ -4069,10 +4069,11 @@ body.theme-light.application.daggerheart .character-sidebar-sheet .experience-va .application.sheet.daggerheart.actor.dh-style.character .window-content { display: grid; grid-template-columns: 275px 1fr; - grid-template-rows: 283px 1fr; + grid-template-rows: auto 1fr; gap: 15px 0; height: 100%; width: 100%; + overflow: auto; } .application.sheet.daggerheart.actor.dh-style.character .window-content .character-sidebar-sheet { grid-row: 1 / span 2; @@ -4313,7 +4314,7 @@ body.theme-light.application.daggerheart .character-sidebar-sheet .experience-va .application.sheet.daggerheart.actor.dh-style.adversary .window-content { display: grid; grid-template-columns: 275px 1fr; - grid-template-rows: 283px 1fr; + grid-template-rows: auto 1fr; gap: 15px 0; height: 100%; width: 100%; diff --git a/templates/sheets/global/tabs/tab-actions.hbs b/templates/sheets/global/tabs/tab-actions.hbs index 54345bed..8b3a43d4 100644 --- a/templates/sheets/global/tabs/tab-actions.hbs +++ b/templates/sheets/global/tabs/tab-actions.hbs @@ -14,6 +14,7 @@ {{action.name}}
+