mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 03:31:07 +01:00
Feature/349 items actions macro use (#356)
* Added itemUse macro on drag to hotbar * Fixed item.type logic * Added support for actionMacro drag from items * Added MacroDrag for Attacks * Fixed so UseItem macros get the img set
This commit is contained in:
parent
d7e024be02
commit
f15483c722
7 changed files with 181 additions and 5 deletions
|
|
@ -140,6 +140,7 @@ Hooks.once('init', () => {
|
||||||
CONFIG.Combat.documentClass = documents.DhpCombat;
|
CONFIG.Combat.documentClass = documents.DhpCombat;
|
||||||
CONFIG.ui.combat = applications.ui.DhCombatTracker;
|
CONFIG.ui.combat = applications.ui.DhCombatTracker;
|
||||||
CONFIG.ui.chat = applications.ui.DhChatLog;
|
CONFIG.ui.chat = applications.ui.DhChatLog;
|
||||||
|
CONFIG.ui.hotbar = applications.ui.DhHotbar;
|
||||||
CONFIG.Token.rulerClass = placeables.DhTokenRuler;
|
CONFIG.Token.rulerClass = placeables.DhTokenRuler;
|
||||||
|
|
||||||
CONFIG.ui.resources = applications.ui.DhFearTracker;
|
CONFIG.ui.resources = applications.ui.DhFearTracker;
|
||||||
|
|
|
||||||
|
|
@ -1537,7 +1537,11 @@
|
||||||
"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",
|
||||||
"featureIsMissing": "Feature is missing"
|
"featureIsMissing": "Feature is missing",
|
||||||
|
"actionIsMissing": "Action is missing",
|
||||||
|
"attackIsMissing": "Attack is missing",
|
||||||
|
"unownedActionMacro": "Cannot make a Use macro for an Action not on your character",
|
||||||
|
"unownedAttackMacro": "Cannot make a Use macro for an Attack that doesn't belong to one of your characters"
|
||||||
},
|
},
|
||||||
"Tooltip": {
|
"Tooltip": {
|
||||||
"openItemWorld": "Open Item World",
|
"openItemWorld": "Open Item World",
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
||||||
actions: {
|
actions: {
|
||||||
openSettings: DHBaseActorSheet.#openSettings
|
openSettings: DHBaseActorSheet.#openSettings
|
||||||
},
|
},
|
||||||
dragDrop: []
|
dragDrop: [{ dragSelector: '.inventory-item[data-type="attack"]', dropSelector: null }]
|
||||||
};
|
};
|
||||||
|
|
||||||
/**@type {typeof DHBaseActorSettings}*/
|
/**@type {typeof DHBaseActorSettings}*/
|
||||||
|
|
@ -49,4 +49,27 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
||||||
static async #openSettings() {
|
static async #openSettings() {
|
||||||
await this.settingSheet.render({ force: true });
|
await this.settingSheet.render({ force: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/* Application Drag/Drop */
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On dragStart on the item.
|
||||||
|
* @param {DragEvent} event - The drag event
|
||||||
|
*/
|
||||||
|
async _onDragStart(event) {
|
||||||
|
const attackItem = event.currentTarget.closest('.inventory-item[data-type="attack"]');
|
||||||
|
|
||||||
|
if (attackItem) {
|
||||||
|
const attackData = {
|
||||||
|
type: 'Attack',
|
||||||
|
actorUuid: this.document.uuid,
|
||||||
|
img: this.document.system.attack.img,
|
||||||
|
fromInternal: true
|
||||||
|
};
|
||||||
|
event.dataTransfer.setData('text/plain', JSON.stringify(attackData));
|
||||||
|
event.dataTransfer.setDragImage(attackItem.querySelector('img'), 60, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,8 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
||||||
},
|
},
|
||||||
dragDrop: [
|
dragDrop: [
|
||||||
{ dragSelector: null, dropSelector: '.tab.features .drop-section' },
|
{ dragSelector: null, dropSelector: '.tab.features .drop-section' },
|
||||||
{ dragSelector: '.feature-item', dropSelector: null }
|
{ dragSelector: '.feature-item', dropSelector: null },
|
||||||
|
{ dragSelector: '.action-item', dropSelector: null }
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -258,6 +259,23 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
||||||
const featureData = { type: 'Item', data: { ...feature.toObject(), _id: null }, fromInternal: true };
|
const featureData = { type: 'Item', data: { ...feature.toObject(), _id: null }, fromInternal: true };
|
||||||
event.dataTransfer.setData('text/plain', JSON.stringify(featureData));
|
event.dataTransfer.setData('text/plain', JSON.stringify(featureData));
|
||||||
event.dataTransfer.setDragImage(featureItem.querySelector('img'), 60, 0);
|
event.dataTransfer.setDragImage(featureItem.querySelector('img'), 60, 0);
|
||||||
|
} else {
|
||||||
|
const actionItem = event.currentTarget.closest('.action-item');
|
||||||
|
if (actionItem) {
|
||||||
|
const action = this.document.system.actions[actionItem.dataset.index];
|
||||||
|
if (!action) {
|
||||||
|
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.actionIsMissing'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const actionData = {
|
||||||
|
type: 'Action',
|
||||||
|
data: { ...action.toObject(), id: action.id, itemUuid: this.document.uuid },
|
||||||
|
fromInternal: true
|
||||||
|
};
|
||||||
|
event.dataTransfer.setData('text/plain', JSON.stringify(actionData));
|
||||||
|
event.dataTransfer.setDragImage(actionItem.querySelector('img'), 60, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,3 +2,4 @@ export { default as DhChatLog } from './chatLog.mjs';
|
||||||
export { default as DhCombatTracker } from './combatTracker.mjs';
|
export { default as DhCombatTracker } from './combatTracker.mjs';
|
||||||
export * as DhCountdowns from './countdowns.mjs';
|
export * as DhCountdowns from './countdowns.mjs';
|
||||||
export { default as DhFearTracker } from './fearTracker.mjs';
|
export { default as DhFearTracker } from './fearTracker.mjs';
|
||||||
|
export { default as DhHotbar } from './hotbar.mjs';
|
||||||
|
|
|
||||||
129
module/applications/ui/hotbar.mjs
Normal file
129
module/applications/ui/hotbar.mjs
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
export default class DhHotbar extends foundry.applications.ui.Hotbar {
|
||||||
|
constructor(options) {
|
||||||
|
super(options);
|
||||||
|
|
||||||
|
this.setupHooks();
|
||||||
|
}
|
||||||
|
|
||||||
|
static async useItem(uuid) {
|
||||||
|
const item = await fromUuid(uuid);
|
||||||
|
if (!item) {
|
||||||
|
return ui.notifications.warn('WARNING.ObjectDoesNotExist', {
|
||||||
|
format: {
|
||||||
|
name: game.i18n.localize('Document'),
|
||||||
|
identifier: uuid
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await item.use({});
|
||||||
|
}
|
||||||
|
|
||||||
|
static async useAction(itemUuid, actionId) {
|
||||||
|
const item = await foundry.utils.fromUuid(itemUuid);
|
||||||
|
if (!item) {
|
||||||
|
return ui.notifications.warn('WARNING.ObjectDoesNotExist', {
|
||||||
|
format: {
|
||||||
|
name: game.i18n.localize('Document'),
|
||||||
|
identifier: itemUuid
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const action = item.system.actions.find(x => x.id === actionId);
|
||||||
|
if (!action) {
|
||||||
|
return ui.notifications.warn('DAGGERHEART.UI.Notifications.actionIsMissing');
|
||||||
|
}
|
||||||
|
|
||||||
|
await action.use({});
|
||||||
|
}
|
||||||
|
|
||||||
|
static async useAttack(actorUuid) {
|
||||||
|
const actor = await foundry.utils.fromUuid(actorUuid);
|
||||||
|
if (!actor) {
|
||||||
|
return ui.notifications.warn('WARNING.ObjectDoesNotExist', {
|
||||||
|
format: {
|
||||||
|
name: game.i18n.localize('Document'),
|
||||||
|
identifier: actorUuid
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const attack = actor.system.attack;
|
||||||
|
if (!attack) {
|
||||||
|
return ui.notifications.warn('DAGGERHEART.UI.Notifications.attackIsMissing');
|
||||||
|
}
|
||||||
|
|
||||||
|
await attack.use({});
|
||||||
|
}
|
||||||
|
|
||||||
|
setupHooks() {
|
||||||
|
Hooks.on('hotbarDrop', (bar, data, slot) => {
|
||||||
|
if (data.type === 'Item') {
|
||||||
|
const item = foundry.utils.fromUuidSync(data.uuid);
|
||||||
|
if (item.uuid.startsWith('Compendium') || !item.isOwned || !item.isOwner) return true;
|
||||||
|
|
||||||
|
switch (item.type) {
|
||||||
|
case 'ancestry':
|
||||||
|
case 'community':
|
||||||
|
case 'class':
|
||||||
|
case 'subclass':
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
this.createItemMacro(item, slot);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (data.type === 'Action') {
|
||||||
|
const item = foundry.utils.fromUuidSync(data.data.itemUuid);
|
||||||
|
if (item.uuid.startsWith('Compendium')) return true;
|
||||||
|
if (!item.isOwned || !item.isOwner) {
|
||||||
|
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.unownedActionMacro'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.createActionMacro(data, slot);
|
||||||
|
return false;
|
||||||
|
} else if (data.type === 'Attack') {
|
||||||
|
const actor = foundry.utils.fromUuidSync(data.actorUuid);
|
||||||
|
if (actor.uuid.startsWith('Compendium')) return true;
|
||||||
|
if (!actor.isOwner) {
|
||||||
|
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.unownedAttackMacro'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.createAttackMacro(data, slot);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async createItemMacro(data, slot) {
|
||||||
|
const macro = await Macro.implementation.create({
|
||||||
|
name: `${game.i18n.localize('Display')} ${name}`,
|
||||||
|
type: CONST.MACRO_TYPES.SCRIPT,
|
||||||
|
img: data.img,
|
||||||
|
command: `await game.system.api.applications.ui.DhHotbar.useItem("${data.uuid}");`
|
||||||
|
});
|
||||||
|
await game.user.assignHotbarMacro(macro, slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
async createActionMacro(data, slot) {
|
||||||
|
const macro = await Macro.implementation.create({
|
||||||
|
name: `${game.i18n.localize('Display')} ${name}`,
|
||||||
|
type: CONST.MACRO_TYPES.SCRIPT,
|
||||||
|
img: data.data.img,
|
||||||
|
command: `await game.system.api.applications.ui.DhHotbar.useAction("${data.data.itemUuid}", "${data.data.id}");`
|
||||||
|
});
|
||||||
|
await game.user.assignHotbarMacro(macro, slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
async createAttackMacro(data, slot) {
|
||||||
|
const macro = await Macro.implementation.create({
|
||||||
|
name: `${game.i18n.localize('Display')} ${name}`,
|
||||||
|
type: CONST.MACRO_TYPES.SCRIPT,
|
||||||
|
img: data.img,
|
||||||
|
command: `await game.system.api.applications.ui.DhHotbar.useAttack("${data.actorUuid}");`
|
||||||
|
});
|
||||||
|
await game.user.assignHotbarMacro(macro, slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -135,8 +135,8 @@ export const registerCountdownHooks = () => {
|
||||||
if (application) {
|
if (application) {
|
||||||
foundry.applications.instances.get(application)?.render();
|
foundry.applications.instances.get(application)?.render();
|
||||||
} else {
|
} else {
|
||||||
foundry.applications.instances.get('narrative-countdowns').render();
|
foundry.applications.instances.get('narrative-countdowns')?.render();
|
||||||
foundry.applications.instances.get('encounter-countdowns').render();
|
foundry.applications.instances.get('encounter-countdowns')?.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue