mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-03-07 22:46:12 +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": {
|
"fear": {
|
||||||
"name": "Fear",
|
"name": "Fear",
|
||||||
"hint": "The Fear pool of the GM."
|
"hint": "The Fear pool of the GM."
|
||||||
},
|
}
|
||||||
"hope": "Hope",
|
|
||||||
"hitPoints": "Hit Points",
|
|
||||||
"stress": "Stress",
|
|
||||||
"armorStack": "Armor Marks"
|
|
||||||
},
|
},
|
||||||
"VariantRules": {
|
"VariantRules": {
|
||||||
"FIELDS": {
|
"FIELDS": {
|
||||||
|
|
@ -1317,13 +1313,7 @@
|
||||||
"communityTitle": "Community Card",
|
"communityTitle": "Community Card",
|
||||||
"subclassFeatureTitle": "Subclass Feature"
|
"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": {
|
"Notifications": {
|
||||||
"adversaryMissing": "The linked adversary doesn't exist in the world.",
|
"adversaryMissing": "The linked adversary doesn't exist in the world.",
|
||||||
|
|
@ -1333,7 +1323,14 @@
|
||||||
"attackTargetDoesNotExist": "The target token no longer exists",
|
"attackTargetDoesNotExist": "The target token no longer exists",
|
||||||
"insufficentAdvancements": "You don't have enough advancements left.",
|
"insufficentAdvancements": "You don't have enough advancements left.",
|
||||||
"noAssignedPlayerCharacter": "You have no assigned character.",
|
"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",
|
"onlyUseableByPC": "This can only be used with a PC token",
|
||||||
"dualityParsing": "Duality roll not properly formated",
|
"dualityParsing": "Duality roll not properly formated",
|
||||||
"attributeFaulty": "The supplied Attribute doesn't exist",
|
"attributeFaulty": "The supplied Attribute doesn't exist",
|
||||||
|
|
@ -1363,13 +1360,7 @@
|
||||||
"damageAlreadyNone": "The damage has already been reduced to none",
|
"damageAlreadyNone": "The damage has already been reduced to none",
|
||||||
"noAvailableArmorMarks": "You have no more available armor marks",
|
"noAvailableArmorMarks": "You have no more available armor marks",
|
||||||
"notEnoughStress": "You don't have enough stress",
|
"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": {
|
"Tooltip": {
|
||||||
"openItemWorld": "Open Item World",
|
"openItemWorld": "Open Item World",
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,11 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
name: game.i18n.localize('DAGGERHEART.GENERAL.Experience.single'),
|
name: game.i18n.localize('DAGGERHEART.GENERAL.Experience.single'),
|
||||||
description: `${experience.name} ${
|
description: `${experience.name} ${
|
||||||
experience.modifier < 0 ? experience.modifier : `+${experience.modifier}`
|
experience.modifier < 0 ? experience.modifier : `+${experience.modifier}`
|
||||||
}`
|
}`,
|
||||||
|
source: {
|
||||||
|
actor: this.document.uuid,
|
||||||
|
item: null
|
||||||
|
}
|
||||||
};
|
};
|
||||||
const msg = new cls({
|
const msg = new cls({
|
||||||
type: 'abilityUse',
|
type: 'abilityUse',
|
||||||
|
|
|
||||||
|
|
@ -700,7 +700,11 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
img: card.img,
|
img: card.img,
|
||||||
name: card.name,
|
name: card.name,
|
||||||
description: card.system.effect,
|
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({
|
const msg = new cls({
|
||||||
type: 'abilityUse',
|
type: 'abilityUse',
|
||||||
|
|
@ -818,7 +822,11 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
img: item.img,
|
img: item.img,
|
||||||
name: item.name,
|
name: item.name,
|
||||||
description: item.system.description,
|
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({
|
const msg = new cls({
|
||||||
type: 'abilityUse',
|
type: 'abilityUse',
|
||||||
|
|
@ -839,7 +847,11 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
const cls = getDocumentClass('ChatMessage');
|
const cls = getDocumentClass('ChatMessage');
|
||||||
const systemData = {
|
const systemData = {
|
||||||
name: game.i18n.localize('DAGGERHEART.GENERAL.Experience.single'),
|
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({
|
const msg = new cls({
|
||||||
type: 'abilityUse',
|
type: 'abilityUse',
|
||||||
|
|
@ -875,7 +887,11 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
origin: this.document.id,
|
origin: this.document.id,
|
||||||
name: title,
|
name: title,
|
||||||
img: item.img,
|
img: item.img,
|
||||||
description: ability.description
|
description: ability.description,
|
||||||
|
source: {
|
||||||
|
actor: this.document.uuid,
|
||||||
|
item: item.uuid ?? item.id
|
||||||
|
}
|
||||||
};
|
};
|
||||||
const msg = new cls({
|
const msg = new cls({
|
||||||
type: 'abilityUse',
|
type: 'abilityUse',
|
||||||
|
|
@ -899,9 +915,14 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
origin: this.document.id,
|
origin: this.document.id,
|
||||||
name: item.name,
|
name: item.name,
|
||||||
img: item.img,
|
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({
|
const msg = new cls({
|
||||||
|
type: 'abilityUse',
|
||||||
user: game.user.id,
|
user: game.user.id,
|
||||||
system: systemData,
|
system: systemData,
|
||||||
content: await foundry.applications.handlebars.renderTemplate(
|
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
|
// Get the action data from the chat message
|
||||||
const actionData = message.system.actions[Number.parseInt(event.currentTarget.dataset.index)];
|
const actionData = message.system.actions[Number.parseInt(event.currentTarget.dataset.index)];
|
||||||
|
|
||||||
// Get the currently selected actor (from selected token)
|
// Get the currently selected actor (from selected token)
|
||||||
const actor = getCommandTarget();
|
const actor = getCommandTarget();
|
||||||
|
|
||||||
if (!actor) {
|
if (!actor) {
|
||||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.noSelectedToken'));
|
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.noTokenSelected'));
|
||||||
return;
|
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 {
|
try {
|
||||||
// Find any weapon or item on the selected actor to use as a template
|
// Get the source item from the chat message
|
||||||
const actorItems = actor.items.filter(item => item.system.actions?.length > 0);
|
const sourceItemUuid = message.system.source?.item;
|
||||||
let templateItem = actorItems.find(item => item.system.actions.some(a => a.type === actionData.type));
|
if (!sourceItemUuid) {
|
||||||
|
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.noSourceItem'));
|
||||||
if (!templateItem && actorItems.length > 0) {
|
return;
|
||||||
templateItem = actorItems[0]; // Use any item with actions as a fallback
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (templateItem) {
|
const sourceItem = await foundry.utils.fromUuid(sourceItemUuid);
|
||||||
// Use the template item's action structure but with our action data
|
if (!sourceItem) {
|
||||||
const { actionsTypes } = await import('../../data/action/_module.mjs');
|
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.sourceItemNotFound'));
|
||||||
const ActionClass = actionsTypes[actionData.type];
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (ActionClass) {
|
// Create a temporary copy of the item with a unique name
|
||||||
// Create the action with the template item's system as parent
|
const tempItemData = sourceItem.toObject();
|
||||||
const actionInstance = new ActionClass({
|
tempItemData._id = foundry.utils.randomID(); // Give it a new ID
|
||||||
...actionData,
|
const originalName = tempItemData.name;
|
||||||
_id: foundry.utils.randomID(),
|
tempItemData.name = `${tempItemData.name} (${foundry.utils.randomID()})`;
|
||||||
name: actionData.name || game.i18n.localize(`DAGGERHEART.ACTIONS.TYPES.${actionData.type}.name`)
|
|
||||||
}, { parent: templateItem.system });
|
|
||||||
|
|
||||||
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Final fallback - just show a notification
|
// Use the action
|
||||||
ui.notifications.info(`Using ${actionData.name || actionData.type} action with selected token: ${actor.name}`);
|
await action.use(event);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
// Clean up: delete the temporary item
|
||||||
|
await actor.deleteEmbeddedDocuments('Item', [tempItem.id]);
|
||||||
|
}
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Error using action from chat:', 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,
|
img: this.img,
|
||||||
name: this.name,
|
name: this.name,
|
||||||
description: this.description,
|
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({
|
const msg = new cls({
|
||||||
type: 'abilityUse',
|
type: 'abilityUse',
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,10 @@ export default class DHAbilityUse extends foundry.abstract.TypeDataModel {
|
||||||
img: new fields.StringField({}),
|
img: new fields.StringField({}),
|
||||||
name: new fields.StringField({}),
|
name: new fields.StringField({}),
|
||||||
description: 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(
|
actions: new fields.ArrayField(
|
||||||
new fields.ObjectField({
|
new fields.ObjectField({
|
||||||
name: new fields.StringField({}),
|
name: new fields.StringField({}),
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,7 @@ export default class DHItem extends foundry.documents.Item {
|
||||||
|
|
||||||
async toChat(origin) {
|
async toChat(origin) {
|
||||||
const cls = getDocumentClass('ChatMessage');
|
const cls = getDocumentClass('ChatMessage');
|
||||||
|
|
||||||
const systemData = {
|
const systemData = {
|
||||||
title:
|
title:
|
||||||
this.type === 'ancestry'
|
this.type === 'ancestry'
|
||||||
|
|
@ -127,9 +128,10 @@ export default class DHItem extends foundry.documents.Item {
|
||||||
actions: this.system.actions ?? [],
|
actions: this.system.actions ?? [],
|
||||||
source: {
|
source: {
|
||||||
actor: this.actor?.uuid ?? this.actor?.id ?? null,
|
actor: this.actor?.uuid ?? this.actor?.id ?? null,
|
||||||
item: this.id
|
item: this.uuid ?? this.id
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const msg = new cls({
|
const msg = new cls({
|
||||||
type: 'abilityUse',
|
type: 'abilityUse',
|
||||||
user: game.user.id,
|
user: game.user.id,
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ export const getCommandTarget = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!target) {
|
if (!target) {
|
||||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.noSelectedToken'));
|
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.noTokenSelected'));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (target.type !== 'character') {
|
if (target.type !== 'character') {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue