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')}
+ ${spentResources.map(r => `- ${game.i18n.localize('DAGGERHEART.Resources.' + r.type)}: ${r.value}
`).join('')}
`
+ });
+
+ 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}}