mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-03-07 14:36:13 +01:00
add working buttons and fix no token selected localization
This commit is contained in:
parent
c8d2429b53
commit
e4fa33082e
8 changed files with 97 additions and 107 deletions
31
lang/en.json
31
lang/en.json
|
|
@ -1261,11 +1261,7 @@
|
|||
"fear": {
|
||||
"name": "Fear",
|
||||
"hint": "The Fear pool of the GM."
|
||||
},
|
||||
"hope": "Hope",
|
||||
"hitPoints": "Hit Points",
|
||||
"stress": "Stress",
|
||||
"armorStack": "Armor Marks"
|
||||
}
|
||||
},
|
||||
"VariantRules": {
|
||||
"FIELDS": {
|
||||
|
|
@ -1317,13 +1313,7 @@
|
|||
"communityTitle": "Community Card",
|
||||
"subclassFeatureTitle": "Subclass 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?"
|
||||
}
|
||||
"featureTitle": "Class Feature"
|
||||
},
|
||||
"Notifications": {
|
||||
"adversaryMissing": "The linked adversary doesn't exist in the world.",
|
||||
|
|
@ -1333,7 +1323,14 @@
|
|||
"attackTargetDoesNotExist": "The target token no longer exists",
|
||||
"insufficentAdvancements": "You don't have enough advancements left.",
|
||||
"noAssignedPlayerCharacter": "You have no assigned character.",
|
||||
"noSelectedToken": "You have no selected token",
|
||||
"noTokenSelected": "No token is selected",
|
||||
"noSourceItem": "No source item found in chat message",
|
||||
"sourceItemNotFound": "Source item not found",
|
||||
"failedToCreateTemporaryItem": "Failed to create temporary item for action use",
|
||||
"actionNotFound": "Action '{id}' not found on source item",
|
||||
"actionTypeNotFound": "Action type '{type}' not found",
|
||||
"actionUseFailed": "Failed to use action '{action}': {error}",
|
||||
"actionNotAvailable": "This action is not available",
|
||||
"onlyUseableByPC": "This can only be used with a PC token",
|
||||
"dualityParsing": "Duality roll not properly formated",
|
||||
"attributeFaulty": "The supplied Attribute doesn't exist",
|
||||
|
|
@ -1363,13 +1360,7 @@
|
|||
"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",
|
||||
"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"
|
||||
"damageIgnore": "{character} did not take damage"
|
||||
},
|
||||
"Tooltip": {
|
||||
"openItemWorld": "Open Item World",
|
||||
|
|
|
|||
|
|
@ -122,7 +122,11 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
name: game.i18n.localize('DAGGERHEART.GENERAL.Experience.single'),
|
||||
description: `${experience.name} ${
|
||||
experience.modifier < 0 ? experience.modifier : `+${experience.modifier}`
|
||||
}`
|
||||
}`,
|
||||
source: {
|
||||
actor: this.document.uuid,
|
||||
item: null
|
||||
}
|
||||
};
|
||||
const msg = new cls({
|
||||
type: 'abilityUse',
|
||||
|
|
|
|||
|
|
@ -700,7 +700,11 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
img: card.img,
|
||||
name: card.name,
|
||||
description: card.system.effect,
|
||||
actions: card.system.actions
|
||||
actions: card.system.actions,
|
||||
source: {
|
||||
actor: card.actor?.uuid ?? card.actor?.id ?? null,
|
||||
item: card.uuid ?? card.id
|
||||
}
|
||||
};
|
||||
const msg = new cls({
|
||||
type: 'abilityUse',
|
||||
|
|
@ -818,7 +822,11 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
img: item.img,
|
||||
name: item.name,
|
||||
description: item.system.description,
|
||||
actions: item.system.actions
|
||||
actions: item.system.actions,
|
||||
source: {
|
||||
actor: item.actor?.uuid ?? item.actor?.id ?? null,
|
||||
item: item.uuid ?? item.id
|
||||
}
|
||||
};
|
||||
const msg = new cls({
|
||||
type: 'abilityUse',
|
||||
|
|
@ -839,7 +847,11 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
const cls = getDocumentClass('ChatMessage');
|
||||
const systemData = {
|
||||
name: game.i18n.localize('DAGGERHEART.GENERAL.Experience.single'),
|
||||
description: `${experience.name} ${experience.total < 0 ? experience.total : `+${experience.total}`}`
|
||||
description: `${experience.name} ${experience.total < 0 ? experience.total : `+${experience.total}`}`,
|
||||
source: {
|
||||
actor: this.document.uuid,
|
||||
item: null
|
||||
}
|
||||
};
|
||||
const msg = new cls({
|
||||
type: 'abilityUse',
|
||||
|
|
@ -875,7 +887,11 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
origin: this.document.id,
|
||||
name: title,
|
||||
img: item.img,
|
||||
description: ability.description
|
||||
description: ability.description,
|
||||
source: {
|
||||
actor: this.document.uuid,
|
||||
item: item.uuid ?? item.id
|
||||
}
|
||||
};
|
||||
const msg = new cls({
|
||||
type: 'abilityUse',
|
||||
|
|
@ -899,9 +915,14 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
origin: this.document.id,
|
||||
name: item.name,
|
||||
img: item.img,
|
||||
description: item.system.description
|
||||
description: item.system.description,
|
||||
source: {
|
||||
actor: item.actor?.uuid ?? item.actor?.id ?? null,
|
||||
item: item.uuid ?? item.id
|
||||
}
|
||||
};
|
||||
const msg = new cls({
|
||||
type: 'abilityUse',
|
||||
user: game.user.id,
|
||||
system: systemData,
|
||||
content: await foundry.applications.handlebars.renderTemplate(
|
||||
|
|
|
|||
|
|
@ -283,99 +283,63 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
|
||||
// Get the action data from the chat message
|
||||
const actionData = message.system.actions[Number.parseInt(event.currentTarget.dataset.index)];
|
||||
|
||||
// Get the currently selected actor (from selected token)
|
||||
const actor = getCommandTarget();
|
||||
|
||||
if (!actor) {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.noSelectedToken'));
|
||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.noTokenSelected'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to find the original action from the source item first
|
||||
const sourceActor = message.system.source?.actor ? await foundry.utils.fromUuid(message.system.source.actor) : null;
|
||||
const sourceItem = message.system.source?.item ? sourceActor?.items?.get(message.system.source.item) : null;
|
||||
|
||||
if (sourceItem && sourceActor) {
|
||||
// Find the specific action on the source item
|
||||
const sourceAction = sourceItem.system.actions?.find(a => a._id === actionData._id);
|
||||
if (sourceAction) {
|
||||
try {
|
||||
// Temporarily override the action's actor reference to use the selected actor
|
||||
const originalActor = sourceAction.actor;
|
||||
const originalItem = sourceAction.item;
|
||||
|
||||
// Create temporary getters that return our selected actor
|
||||
Object.defineProperty(sourceAction, 'actor', {
|
||||
get: () => actor,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
Object.defineProperty(sourceAction, 'item', {
|
||||
get: () => ({
|
||||
...originalItem,
|
||||
actor: actor,
|
||||
parent: actor
|
||||
}),
|
||||
configurable: true
|
||||
});
|
||||
|
||||
// Use the action
|
||||
await sourceAction.use(event);
|
||||
|
||||
// Restore the original references
|
||||
Object.defineProperty(sourceAction, 'actor', {
|
||||
get: () => originalActor,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
Object.defineProperty(sourceAction, 'item', {
|
||||
get: () => originalItem,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
return;
|
||||
} catch (e) {
|
||||
console.error('Error using source action from chat:', e);
|
||||
// Restore original references if there was an error
|
||||
delete sourceAction.actor;
|
||||
delete sourceAction.item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: Create action using an existing item from the selected actor
|
||||
try {
|
||||
// Find any weapon or item on the selected actor to use as a template
|
||||
const actorItems = actor.items.filter(item => item.system.actions?.length > 0);
|
||||
let templateItem = actorItems.find(item => item.system.actions.some(a => a.type === actionData.type));
|
||||
|
||||
if (!templateItem && actorItems.length > 0) {
|
||||
templateItem = actorItems[0]; // Use any item with actions as a fallback
|
||||
// Get the source item from the chat message
|
||||
const sourceItemUuid = message.system.source?.item;
|
||||
if (!sourceItemUuid) {
|
||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.noSourceItem'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (templateItem) {
|
||||
// Use the template item's action structure but with our action data
|
||||
const { actionsTypes } = await import('../../data/action/_module.mjs');
|
||||
const ActionClass = actionsTypes[actionData.type];
|
||||
const sourceItem = await foundry.utils.fromUuid(sourceItemUuid);
|
||||
if (!sourceItem) {
|
||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.sourceItemNotFound'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (ActionClass) {
|
||||
// Create the action with the template item's system as parent
|
||||
const actionInstance = new ActionClass({
|
||||
...actionData,
|
||||
_id: foundry.utils.randomID(),
|
||||
name: actionData.name || game.i18n.localize(`DAGGERHEART.ACTIONS.TYPES.${actionData.type}.name`)
|
||||
}, { parent: templateItem.system });
|
||||
// Create a temporary copy of the item with a unique name
|
||||
const tempItemData = sourceItem.toObject();
|
||||
tempItemData._id = foundry.utils.randomID(); // Give it a new ID
|
||||
const originalName = tempItemData.name;
|
||||
tempItemData.name = `${tempItemData.name} (${foundry.utils.randomID()})`;
|
||||
|
||||
await actionInstance.use(event);
|
||||
// Create the temporary item on the selected actor
|
||||
const [tempItem] = await actor.createEmbeddedDocuments('Item', [tempItemData]);
|
||||
|
||||
// Immediately rename it back to the original name for display purposes
|
||||
await tempItem.update({ name: originalName });
|
||||
|
||||
try {
|
||||
// Find the action on the temporary item
|
||||
const action = tempItem.system.actions?.find(a => a._id === actionData._id);
|
||||
if (!action) {
|
||||
ui.notifications.error(game.i18n.format('DAGGERHEART.UI.Notifications.actionNotFound', { id: actionData._id }));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Final fallback - just show a notification
|
||||
ui.notifications.info(`Using ${actionData.name || actionData.type} action with selected token: ${actor.name}`);
|
||||
// Use the action
|
||||
await action.use(event);
|
||||
|
||||
} finally {
|
||||
// Clean up: delete the temporary item
|
||||
await actor.deleteEmbeddedDocuments('Item', [tempItem.id]);
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
console.error('Error using action from chat:', e);
|
||||
ui.notifications.error(`Error using action: ${e.message}`);
|
||||
ui.notifications.error(game.i18n.format('DAGGERHEART.UI.Notifications.actionUseFailed', {
|
||||
action: actionData.name || actionData.type,
|
||||
error: e.message
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -568,7 +568,11 @@ export default class DHBaseAction extends foundry.abstract.DataModel {
|
|||
img: this.img,
|
||||
name: this.name,
|
||||
description: this.description,
|
||||
actions: []
|
||||
actions: [],
|
||||
source: {
|
||||
actor: this.item?.actor?.uuid ?? this.item?.actor?.id ?? null,
|
||||
item: this.item?.uuid ?? this.item?.id ?? null
|
||||
}
|
||||
};
|
||||
const msg = new cls({
|
||||
type: 'abilityUse',
|
||||
|
|
|
|||
|
|
@ -8,6 +8,10 @@ export default class DHAbilityUse extends foundry.abstract.TypeDataModel {
|
|||
img: new fields.StringField({}),
|
||||
name: new fields.StringField({}),
|
||||
description: new fields.StringField({}),
|
||||
source: new fields.SchemaField({
|
||||
actor: new fields.StringField({ nullable: true }),
|
||||
item: new fields.StringField({ nullable: true })
|
||||
}),
|
||||
actions: new fields.ArrayField(
|
||||
new fields.ObjectField({
|
||||
name: new fields.StringField({}),
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ export default class DHItem extends foundry.documents.Item {
|
|||
|
||||
async toChat(origin) {
|
||||
const cls = getDocumentClass('ChatMessage');
|
||||
|
||||
const systemData = {
|
||||
title:
|
||||
this.type === 'ancestry'
|
||||
|
|
@ -127,9 +128,10 @@ export default class DHItem extends foundry.documents.Item {
|
|||
actions: this.system.actions ?? [],
|
||||
source: {
|
||||
actor: this.actor?.uuid ?? this.actor?.id ?? null,
|
||||
item: this.id
|
||||
item: this.uuid ?? this.id
|
||||
}
|
||||
};
|
||||
|
||||
const msg = new cls({
|
||||
type: 'abilityUse',
|
||||
user: game.user.id,
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ export const getCommandTarget = () => {
|
|||
}
|
||||
}
|
||||
if (!target) {
|
||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.noSelectedToken'));
|
||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.noTokenSelected'));
|
||||
return null;
|
||||
}
|
||||
if (target.type !== 'character') {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue