add buttons to card

This commit is contained in:
walther.johnson 2025-07-06 18:43:21 -06:00
parent ee4a5d17a6
commit 32a0e909fc
6 changed files with 107 additions and 9 deletions

View file

@ -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",

View file

@ -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: `<p>${game.i18n.localize('DAGGERHEART.Chat.RefundResources.ConfirmText')}</p>
<ul>${spentResources.map(r => `<li>${game.i18n.localize('DAGGERHEART.Resources.' + r.type)}: ${r.value}</li>`).join('')}</ul>`
});
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'));
}
};
}

View file

@ -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',

View file

@ -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"
}
}
}

View file

@ -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%;

View file

@ -14,6 +14,7 @@
<img class="image" src="{{action.img}}" />
<span>{{action.name}}</span>
<div class="controls">
<button class="action-use-button" data-index="{{index}}" type="button">Use</button>
<a data-action="removeAction"><i class="fa-solid fa-trash"></i></a>
</div>
</div>