mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-04-22 23:43:37 +02:00
Merge branch 'main' into feature/tag-team-rework
This commit is contained in:
commit
43114187b9
96 changed files with 1942 additions and 664 deletions
|
|
@ -32,6 +32,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
handleResourceDice: CharacterSheet.#handleResourceDice,
|
||||
advanceResourceDie: CharacterSheet.#advanceResourceDie,
|
||||
cancelBeastform: CharacterSheet.#cancelBeastform,
|
||||
toggleResourceManagement: CharacterSheet.#toggleResourceManagement,
|
||||
useDowntime: this.useDowntime,
|
||||
viewParty: CharacterSheet.#viewParty
|
||||
},
|
||||
|
|
@ -225,6 +226,9 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
async _preparePartContext(partId, context, options) {
|
||||
context = await super._preparePartContext(partId, context, options);
|
||||
switch (partId) {
|
||||
case 'header':
|
||||
await this._prepareHeaderContext(context, options);
|
||||
break;
|
||||
case 'loadout':
|
||||
await this._prepareLoadoutContext(context, options);
|
||||
break;
|
||||
|
|
@ -239,6 +243,12 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
return context;
|
||||
}
|
||||
|
||||
async _prepareHeaderContext(context, _options) {
|
||||
context.hasExtraResources = Object.keys(CONFIG.DH.RESOURCE.character.all).some(
|
||||
key => !CONFIG.DH.RESOURCE.character.base[key]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare render context for the Loadout part.
|
||||
* @param {ApplicationRenderContext} context
|
||||
|
|
@ -922,6 +932,78 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
});
|
||||
}
|
||||
|
||||
static async #toggleResourceManagement(event, button) {
|
||||
event.stopPropagation();
|
||||
const existingTooltip = document.body.querySelector('.locked-tooltip .resource-management-container');
|
||||
if (existingTooltip) {
|
||||
game.tooltip.dismissLockedTooltips();
|
||||
return;
|
||||
}
|
||||
|
||||
const extraResources = Object.values(CONFIG.DH.RESOURCE.character.all).reduce((acc, resource) => {
|
||||
if (CONFIG.DH.RESOURCE.character.base[resource.id]) return acc;
|
||||
|
||||
const resourceData = this.document.system.resources[resource.id];
|
||||
acc[resource.id] = {
|
||||
id: resource.id,
|
||||
label: game.i18n.localize(resource.label),
|
||||
value: resourceData.value,
|
||||
max: resourceData.max,
|
||||
fullIcon: resource.images?.full ?? { value: 'fa-solid fa-circle', isIcon: true },
|
||||
emptyIcon: resource.images?.empty ?? { value: 'fa-regular fa-circle', isIcon: true }
|
||||
};
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const html = document.createElement('div');
|
||||
html.innerHTML = await foundry.applications.handlebars.renderTemplate(
|
||||
`systems/daggerheart/templates/ui/tooltip/resourceManagement.hbs`,
|
||||
{
|
||||
resources: extraResources
|
||||
}
|
||||
);
|
||||
|
||||
const target = button.closest('.resource-section');
|
||||
|
||||
game.tooltip.dismissLockedTooltips();
|
||||
game.tooltip.activate(target, {
|
||||
html,
|
||||
locked: true,
|
||||
cssClass: 'bordered-tooltip',
|
||||
direction: 'DOWN',
|
||||
noOffset: true
|
||||
});
|
||||
|
||||
const resourceManager = target.querySelector('.resource-manager');
|
||||
resourceManager.classList.toggle('inverted');
|
||||
|
||||
Hooks.once(CONFIG.DH.HOOKS.hooksConfig.lockedTooltipDismissed, () => {
|
||||
resourceManager.classList.toggle('inverted');
|
||||
});
|
||||
|
||||
for (const element of html.querySelectorAll('.resource-value'))
|
||||
element.addEventListener('click', this.onUpdateResource.bind(this));
|
||||
}
|
||||
|
||||
async onUpdateResource(event) {
|
||||
const target = event.target.closest('.resource-value');
|
||||
const { resource, value: textValue } = target.dataset;
|
||||
|
||||
const inputValue = Number.parseInt(textValue);
|
||||
const decreasing = inputValue <= this.document.system.resources[resource].value;
|
||||
const value = decreasing ? inputValue - 1 : inputValue;
|
||||
await this.document.update({ [`system.resources.${resource}.value`]: value }, { render: false });
|
||||
|
||||
/* Update resource symbols */
|
||||
const section = target.closest('.resource-section');
|
||||
for (const element of section.querySelectorAll('.resource-value')) {
|
||||
const showFull = Number.parseInt(element.dataset.value) <= value;
|
||||
element.querySelector('.full').classList.toggle('hidden', !showFull);
|
||||
element.querySelector('.empty').classList.toggle('hidden', showFull);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the downtime application.
|
||||
* @type {ApplicationClickAction}
|
||||
|
|
|
|||
|
|
@ -264,15 +264,6 @@ export default class Party extends DHBaseActorSheet {
|
|||
).render({ force: true });
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the set of ContextMenu options for Consumable and Loot.
|
||||
* @returns {import('@client/applications/ux/context-menu.mjs').ContextMenuEntry[]} - The Array of context options passed to the ContextMenu instance
|
||||
* @this {CharacterSheet}
|
||||
* @protected
|
||||
*/
|
||||
static #getItemContextOptions() {
|
||||
return this._getContextMenuCommonOptions.call(this, { usable: true, toChat: true });
|
||||
}
|
||||
/* -------------------------------------------- */
|
||||
/* Filter Tracking */
|
||||
/* -------------------------------------------- */
|
||||
|
|
|
|||
|
|
@ -44,8 +44,32 @@ export default class DHBaseActorSettings extends DHApplicationMixin(DocumentShee
|
|||
const context = await super._prepareContext(options);
|
||||
context.isNPC = this.actor.isNPC;
|
||||
|
||||
if (context.systemFields.attack)
|
||||
if (context.systemFields.attack) {
|
||||
context.systemFields.attack.fields = this.actor.system.attack.schema.fields;
|
||||
}
|
||||
|
||||
// Create fake fields for actor configurable max resource value.
|
||||
const resourceConfig = CONFIG.DH.RESOURCE[this.actor.type]?.all;
|
||||
if (resourceConfig) {
|
||||
const relevant = ['hitPoints', 'stress'].filter(r => r in resourceConfig);
|
||||
context.resources = relevant.map(key => {
|
||||
const data = this.actor._source.system.resources[key];
|
||||
const config = resourceConfig[key];
|
||||
return {
|
||||
label: config.label,
|
||||
name: `system.resources.${key}.max`,
|
||||
value: data.max ?? config.max,
|
||||
tooltip: key === 'hitPoints' ? game.i18n.localize('DAGGERHEART.UI.Tooltip.maxHPClassBound') : null,
|
||||
field: new foundry.data.fields.NumberField({
|
||||
initial: config.max,
|
||||
integer: true,
|
||||
label: game.i18n.format('DAGGERHEART.GENERAL.maxWithThing', {
|
||||
thing: game.i18n.localize(config.label)
|
||||
})
|
||||
})
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -691,6 +691,9 @@ export default function DHApplicationMixin(Base) {
|
|||
case 'weapon':
|
||||
presets.folder = 'equipments.folders.weapons';
|
||||
break;
|
||||
case 'feature':
|
||||
presets.folder = 'features';
|
||||
break;
|
||||
case 'domainCard':
|
||||
presets.folder = 'domains';
|
||||
presets.filter = {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
|||
],
|
||||
dragDrop: [
|
||||
{ dragSelector: '.inventory-item[data-type="attack"]', dropSelector: null },
|
||||
{ dragSelector: ".currency[data-currency] .drag-handle", dropSelector: null }
|
||||
{ dragSelector: '.currency[data-currency] .drag-handle', dropSelector: null }
|
||||
]
|
||||
};
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
|||
value: context.source.system.gold[key]
|
||||
};
|
||||
}
|
||||
context.inventory.hasCurrency = Object.values(context.inventory.currencies).some((c) => c.enabled);
|
||||
context.inventory.hasCurrency = Object.values(context.inventory.currencies).some(c => c.enabled);
|
||||
}
|
||||
|
||||
return context;
|
||||
|
|
@ -270,7 +270,9 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
|||
currency
|
||||
});
|
||||
if (quantity) {
|
||||
originActor.update({ [`system.gold.${currency}`]: Math.max(0, originActor.system.gold[currency] - quantity) });
|
||||
originActor.update({
|
||||
[`system.gold.${currency}`]: Math.max(0, originActor.system.gold[currency] - quantity)
|
||||
});
|
||||
this.document.update({ [`system.gold.${currency}`]: this.document.system.gold[currency] + quantity });
|
||||
}
|
||||
return;
|
||||
|
|
@ -292,6 +294,15 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
|||
|
||||
/* Handling transfer of inventoryItems */
|
||||
if (item.system.metadata.isInventoryItem) {
|
||||
if (!this.document.testUserPermission(game.user, 'OWNER', { exact: true })) {
|
||||
return ui.notifications.error(
|
||||
game.i18n.format('DAGGERHEART.UI.Notifications.lackingItemTransferPermission', {
|
||||
user: game.user.name,
|
||||
target: this.document.name
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (item.system.metadata.isQuantifiable) {
|
||||
const actorItem = originActor.items.get(data.originId);
|
||||
const quantityTransfered = await game.system.api.applications.dialogs.ItemTransferDialog.configure({
|
||||
|
|
@ -300,14 +311,6 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
|||
});
|
||||
|
||||
if (quantityTransfered) {
|
||||
if (quantityTransfered === actorItem.system.quantity) {
|
||||
await originActor.deleteEmbeddedDocuments('Item', [data.originId]);
|
||||
} else {
|
||||
await actorItem.update({
|
||||
'system.quantity': actorItem.system.quantity - quantityTransfered
|
||||
});
|
||||
}
|
||||
|
||||
const existingItem = this.document.items.find(x => itemIsIdentical(x, item));
|
||||
if (existingItem) {
|
||||
await existingItem.update({
|
||||
|
|
@ -325,10 +328,18 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
|||
}
|
||||
]);
|
||||
}
|
||||
|
||||
if (quantityTransfered === actorItem.system.quantity) {
|
||||
await originActor.deleteEmbeddedDocuments('Item', [data.originId]);
|
||||
} else {
|
||||
await actorItem.update({
|
||||
'system.quantity': actorItem.system.quantity - quantityTransfered
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
await originActor.deleteEmbeddedDocuments('Item', [data.originId]);
|
||||
await this.document.createEmbeddedDocuments('Item', [item.toObject()]);
|
||||
await originActor.deleteEmbeddedDocuments('Item', [data.originId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -339,7 +350,7 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
|||
*/
|
||||
async _onDragStart(event) {
|
||||
// Handle drag/dropping currencies
|
||||
const currencyEl = event.currentTarget.closest(".currency[data-currency]");
|
||||
const currencyEl = event.currentTarget.closest('.currency[data-currency]');
|
||||
if (currencyEl) {
|
||||
const currency = currencyEl.dataset.currency;
|
||||
const data = { type: 'Currency', currency, originActor: this.document.uuid };
|
||||
|
|
@ -359,8 +370,8 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
|||
event.dataTransfer.setData('text/plain', JSON.stringify(attackData));
|
||||
event.dataTransfer.setDragImage(attackItem.querySelector('img'), 60, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const item = await getDocFromElement(event.target);
|
||||
if (item) {
|
||||
const dragData = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue