mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-06-06 12:54:16 +02:00
Merge branch 'main' into adjust-domain-card-size
This commit is contained in:
commit
d0ffbe77be
58 changed files with 1065 additions and 399 deletions
|
|
@ -57,6 +57,14 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
}
|
||||
],
|
||||
contextMenus: [
|
||||
{
|
||||
handler: CharacterSheet.#getCreationMainContextOptions,
|
||||
selector: '.character-details [data-action="editDoc"]',
|
||||
options: {
|
||||
parentClassHooks: false,
|
||||
fixed: true
|
||||
}
|
||||
},
|
||||
{
|
||||
handler: CharacterSheet.#getDomainCardContextOptions,
|
||||
selector: '[data-item-uuid][data-type="domainCard"]',
|
||||
|
|
@ -319,6 +327,56 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
/* Context Menu */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
static #getCreationMainContextOptions() {
|
||||
/** Returns true if the item is managed by the level up wizard. Such items shouldn't allow things like manual removal */
|
||||
function isItemWizardManaged(item) {
|
||||
const actor = item?.actor;
|
||||
if (!actor) return false;
|
||||
|
||||
// If levelup automation is off in general or for this character, all items are unmanaged
|
||||
// This is disabled until we have proper granted feature removal, for now this feature is to correct errors
|
||||
// const levelupAuto = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).levelupAuto;
|
||||
// if (!levelupAuto) return false;
|
||||
|
||||
// Core items aren't part of levelup data. TODO: add some way to flag a specific character as no auto leveling
|
||||
const classPair = actor.system.class;
|
||||
const coreItems = [actor.system.ancestry, actor.system.community, classPair?.value, classPair?.subclass];
|
||||
if (coreItems.includes(item)) return true;
|
||||
|
||||
const levelups = Object.values(actor.system.levelData?.levelups) ?? [];
|
||||
const uuid = item.uuid;
|
||||
const sourceUuid = item._stats.compendiumSource; // on older characters this may be missing
|
||||
return levelups.some(data => {
|
||||
if (item.type === 'subclass') {
|
||||
const selectedSubclasses = data.selections.map(s => s.secondaryData?.subclass).filter(s => !!s);
|
||||
return sourceUuid
|
||||
? selectedSubclasses.includes(sourceUuid)
|
||||
: selectedSubclasses.length && item.system.isMulticlass;
|
||||
}
|
||||
|
||||
const matchesCard = data.achievements.domainCards.some(i => i.itemUuid === uuid);
|
||||
const matchesSelection = data.selections.some(s => s.itemUuid === uuid);
|
||||
return matchesCard || matchesSelection;
|
||||
});
|
||||
}
|
||||
|
||||
return [
|
||||
{
|
||||
label: 'CONTROLS.CommonDelete',
|
||||
icon: 'fa-solid fa-trash',
|
||||
visible: target => {
|
||||
const doc = getDocFromElementSync(target);
|
||||
return doc?.isOwner && !isItemWizardManaged(doc);
|
||||
},
|
||||
onClick: async (event, target) => {
|
||||
const doc = await getDocFromElement(target);
|
||||
if (event.shiftKey) return doc.delete();
|
||||
else return doc.deleteDialog();
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the set of ContextMenu options for DomainCards.
|
||||
* @returns {import('@client/applications/ux/context-menu.mjs').ContextMenuEntry[]} - The Array of context options passed to the ContextMenu instance
|
||||
|
|
@ -335,7 +393,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
const doc = getDocFromElementSync(target);
|
||||
return doc?.isOwner && doc.system.inVault;
|
||||
},
|
||||
callback: async target => {
|
||||
onClick: async (_, target) => {
|
||||
const doc = await getDocFromElement(target);
|
||||
const actorLoadout = doc.actor.system.loadoutSlot;
|
||||
if (actorLoadout.available) return doc.update({ 'system.inVault': false });
|
||||
|
|
@ -349,7 +407,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
const doc = getDocFromElementSync(target);
|
||||
return doc?.isOwner && doc.system.inVault;
|
||||
},
|
||||
callback: async (target, event) => {
|
||||
onClick: async (event, target) => {
|
||||
const doc = await getDocFromElement(target);
|
||||
const actorLoadout = doc.actor.system.loadoutSlot;
|
||||
if (!actorLoadout.available) {
|
||||
|
|
@ -388,7 +446,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
const doc = getDocFromElementSync(target);
|
||||
return doc?.isOwner && !doc.system.inVault;
|
||||
},
|
||||
callback: async target => (await getDocFromElement(target)).update({ 'system.inVault': true })
|
||||
onClick: async (_, target) => (await getDocFromElement(target)).update({ 'system.inVault': true })
|
||||
}
|
||||
].map(option => ({
|
||||
...option,
|
||||
|
|
@ -414,7 +472,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
const doc = getDocFromElementSync(target);
|
||||
return doc.isOwner && doc && !doc.system.equipped;
|
||||
},
|
||||
callback: (target, event) => CharacterSheet.#toggleEquipItem.call(this, event, target)
|
||||
onClick: (event, target) => CharacterSheet.#toggleEquipItem.call(this, event, target)
|
||||
},
|
||||
{
|
||||
label: 'unequip',
|
||||
|
|
@ -423,7 +481,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
const doc = getDocFromElementSync(target);
|
||||
return doc.isOwner && doc && doc.system.equipped;
|
||||
},
|
||||
callback: (target, event) => CharacterSheet.#toggleEquipItem.call(this, event, target)
|
||||
onClick: (event, target) => CharacterSheet.#toggleEquipItem.call(this, event, target)
|
||||
}
|
||||
].map(option => ({
|
||||
...option,
|
||||
|
|
@ -718,7 +776,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
? {
|
||||
'system.linkedClass.uuid': {
|
||||
key: 'system.linkedClass.uuid',
|
||||
value: this.document.system.class.value._stats.compendiumSource
|
||||
value: this.document.system.class.value?._stats.compendiumSource
|
||||
}
|
||||
}
|
||||
: undefined,
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ export default class Party extends DHBaseActorSheet {
|
|||
actions: {
|
||||
openDocument: Party.#openDocument,
|
||||
deletePartyMember: Party.#deletePartyMember,
|
||||
deleteItem: Party.#deleteItem,
|
||||
toggleHope: Party.#toggleHope,
|
||||
toggleHitPoints: Party.#toggleHitPoints,
|
||||
toggleStress: Party.#toggleStress,
|
||||
|
|
@ -509,23 +508,4 @@ export default class Party extends DHBaseActorSheet {
|
|||
const newMembersList = currentMembers.filter(uuid => uuid !== doc.uuid);
|
||||
await this.document.update({ 'system.partyMembers': newMembersList });
|
||||
}
|
||||
|
||||
static async #deleteItem(event, target) {
|
||||
const doc = await getDocFromElement(target.closest('.inventory-item'));
|
||||
if (!event.shiftKey) {
|
||||
const confirmed = await foundry.applications.api.DialogV2.confirm({
|
||||
window: {
|
||||
title: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.title', {
|
||||
type: game.i18n.localize('TYPES.Actor.party'),
|
||||
name: doc.name
|
||||
})
|
||||
},
|
||||
content: game.i18n.format('DAGGERHEART.APPLICATIONS.DeleteConfirmation.text', { name: doc.name })
|
||||
});
|
||||
|
||||
if (!confirmed) return;
|
||||
}
|
||||
|
||||
this.document.deleteEmbeddedDocuments('Item', [doc.id]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -424,7 +424,7 @@ export default function DHApplicationMixin(Base) {
|
|||
const target = element.closest('[data-item-uuid]');
|
||||
return !target.dataset.disabled && target.dataset.itemType !== 'beastform';
|
||||
},
|
||||
callback: async target => (await getDocFromElement(target)).update({ disabled: true })
|
||||
onClick: async (_, target) => (await getDocFromElement(target)).update({ disabled: true })
|
||||
},
|
||||
{
|
||||
label: 'enableEffect',
|
||||
|
|
@ -433,7 +433,7 @@ export default function DHApplicationMixin(Base) {
|
|||
const target = element.closest('[data-item-uuid]');
|
||||
return target.dataset.disabled && target.dataset.itemType !== 'beastform';
|
||||
},
|
||||
callback: async target => (await getDocFromElement(target)).update({ disabled: false })
|
||||
onClick: async (_, target) => (await getDocFromElement(target)).update({ disabled: false })
|
||||
}
|
||||
].map(option => ({
|
||||
...option,
|
||||
|
|
@ -478,7 +478,9 @@ export default function DHApplicationMixin(Base) {
|
|||
(doc?.isOwner && (!doc?.hasOwnProperty('systemPath') || doc?.inCollection))
|
||||
);
|
||||
},
|
||||
callback: async target => (await getDocFromElement(target)).sheet.render({ force: true })
|
||||
onClick: async (_, target) => {
|
||||
return (await getDocFromElement(target)).sheet.render({ force: true });
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
|
|
@ -493,7 +495,7 @@ export default function DHApplicationMixin(Base) {
|
|||
!foundry.utils.isEmpty(doc?.damage?.parts);
|
||||
return doc?.isOwner && hasDamage;
|
||||
},
|
||||
callback: async (target, event) => {
|
||||
onClick: async (event, target) => {
|
||||
const doc = await getDocFromElement(target),
|
||||
action = doc?.system?.attack ?? doc;
|
||||
const config = action.prepareConfig(event);
|
||||
|
|
@ -513,7 +515,7 @@ export default function DHApplicationMixin(Base) {
|
|||
const doc = getDocFromElementSync(target);
|
||||
return doc?.isOwner && !(doc.type === 'domainCard' && doc.system.inVault);
|
||||
},
|
||||
callback: async (target, event) => (await getDocFromElement(target)).use(event)
|
||||
onClick: async (event, target) => (await getDocFromElement(target)).use(event)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -521,7 +523,7 @@ export default function DHApplicationMixin(Base) {
|
|||
options.push({
|
||||
label: 'DAGGERHEART.APPLICATIONS.ContextMenu.sendToChat',
|
||||
icon: 'fa-solid fa-message',
|
||||
callback: async target => (await getDocFromElement(target)).toChat(this.document.uuid)
|
||||
onClick: async (_, target) => (await getDocFromElement(target)).toChat(this.document.uuid)
|
||||
});
|
||||
|
||||
if (deletable)
|
||||
|
|
@ -533,7 +535,7 @@ export default function DHApplicationMixin(Base) {
|
|||
const doc = getDocFromElementSync(target);
|
||||
return doc?.isOwner !== false && target.dataset.itemType !== 'beastform';
|
||||
},
|
||||
callback: async (target, event) => {
|
||||
onClick: async (event, target) => {
|
||||
const doc = await getDocFromElement(target);
|
||||
if (event.shiftKey) return doc.delete();
|
||||
else return doc.deleteDialog();
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
|||
options.push({
|
||||
name: 'CONTROLS.CommonDelete',
|
||||
icon: '<i class="fa-solid fa-trash"></i>',
|
||||
callback: async target => {
|
||||
onClick: async (_, target) => {
|
||||
const feature = await getDocFromElement(target);
|
||||
if (!feature) return;
|
||||
const confirmed = await foundry.applications.api.DialogV2.confirm({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue