Fixed using ItemLinkfield for Ancestry/Class/Subclass

This commit is contained in:
WBHarry 2025-07-22 01:39:51 +02:00
parent 060fe41730
commit 6336f2a60f
11 changed files with 70 additions and 113 deletions

View file

@ -1661,9 +1661,6 @@
"unownedAttackMacro": "Cannot make a Use macro for an Attack that doesn't belong to one of your characters",
"featureNotHope": "This feature is used as something else than a Hope feature and cannot be used here.",
"featureNotClass": "This feature is used as something else than a Class feature and cannot be used here.",
"featureNotFoundation": "This feature is used as something else than a Foundation feature and cannot be used here.",
"featureNotSpecialization": "This feature is used as something else than a Specialization feature and cannot be used here.",
"featureNotMastery": "This feature is used as something else than a Mastery feature and cannot be used here.",
"beastformMissingEffect": "The Beastform is missing a Beastform Effect. Cannot be used.",
"beastformToManyAdvantages": "You cannot select any more advantages.",
"beastformToManyFeatures": "You cannot select any more features.",

View file

@ -492,15 +492,29 @@ export default function DHApplicationMixin(Base) {
* Renders an embedded document.
* @type {ApplicationClickAction}
*/
static #editDoc(_event, target) {
static async #editDoc(_event, target) {
const doc = getDocFromElement(target);
if (doc) return doc.sheet.render({ force: true });
if (doc) {
const appId = this.element.id;
doc.apps[appId] = this;
const app = await doc.sheet.render({ force: true });
app.addEventListener(
'close',
() => {
delete doc.apps[appId];
},
{ once: true }
);
return;
}
// TODO: REDO this
const { actionId } = target.closest('[data-action-id]').dataset;
const { actions, attack } = this.document.system;
const action = attack?.id === actionId ? attack : actions?.find(a => a.id === actionId);
new DHActionConfig(action).render({ force: true });
const config = new DHActionConfig(action);
config.render({ force: true });
}
/**

View file

@ -181,7 +181,7 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
const feature = await cls.create({
type: 'feature',
name: cls.defaultName({ type: 'feature' }),
[`system.itemLinks.["${this.document.uuid}"]`]: CONFIG.DH.ITEM.featureSubTypes[type]
[`system.itemLinks.${this.document.uuid}`]: CONFIG.DH.ITEM.featureSubTypes[type]
});
await this.document.update({
'system.features': [...this.document.system.features, feature].map(f => f.uuid)
@ -192,7 +192,7 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
* Remove a feature from the item.
* @type {ApplicationClickAction}
*/
static async #deleteFeature(_, target) {
static async #deleteFeature(event, target) {
const feature = getDocFromElement(target);
if (!feature) return ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureIsMissing'));
await feature.update({ [`system.itemLinks.-=${this.document.uuid}`]: null });
@ -270,13 +270,19 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
if (data.fromInternal) return;
const target = event.target.closest('fieldset.drop-section');
const item = await fromUuid(data.uuid);
if (item?.type === 'feature') {
const { type } = target.dataset;
const previouslyLinked = item.system.itemLinks[this.document.uuid] !== undefined;
await item.update({ [`system.itemLinks.${this.document.uuid}`]: CONFIG.DH.ITEM.featureSubTypes[type] });
const current = this.document.system.features.map(x => x.uuid);
await this.document.update({ 'system.features': [...current, item.uuid] });
if (!previouslyLinked) {
const current = this.document.system.features.map(x => x.uuid);
await this.document.update({ 'system.features': [...current, item.uuid] });
} else {
this.render();
}
}
}
}

View file

@ -12,4 +12,22 @@ export default class AncestrySheet extends DHHeritageSheet {
...super.PARTS,
features: { template: 'systems/daggerheart/templates/sheets/items/ancestry/features.hbs' }
};
/* -------------------------------------------- */
/* Application Drag/Drop */
/* -------------------------------------------- */
/**
* On drop on the item.
* @param {DragEvent} event - The drag event
*/
async _onDrop(event) {
const target = event.target.closest('fieldset.drop-section');
const typeField =
this.document.system[target.dataset.type === 'primary' ? 'primaryFeature' : 'secondaryFeature'];
if (!typeField) {
super._onDrop(event);
}
}
}

View file

@ -87,27 +87,7 @@ export default class ClassSheet extends DHBaseItemSheet {
'system.subclasses': [...this.document.system.subclasses.map(x => x.uuid), item.uuid]
});
} else if (item.type === 'feature') {
if (target.classList.contains('hope-feature')) {
if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes.hope) {
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureNotHope'));
return;
}
await item.update({ 'system.subType': CONFIG.DH.ITEM.featureSubTypes.hope });
await this.document.update({
'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid]
});
} else if (target.classList.contains('class-feature')) {
if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes.class) {
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureNotClass'));
return;
}
await item.update({ 'system.subType': CONFIG.DH.ITEM.featureSubTypes.class });
await this.document.update({
'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid]
});
}
super._onDrop(event);
} else if (item.type === 'weapon') {
if (target.classList.contains('primary-weapon-section')) {
if (!this.document.system.characterGuide.suggestedPrimaryWeapon && !item.system.secondary)

View file

@ -5,8 +5,7 @@ export default class SubclassSheet extends DHBaseItemSheet {
static DEFAULT_OPTIONS = {
classes: ['subclass'],
position: { width: 600 },
window: { resizable: false },
actions: {}
window: { resizable: false }
};
/**@override */
@ -36,63 +35,4 @@ export default class SubclassSheet extends DHBaseItemSheet {
labelPrefix: 'DAGGERHEART.GENERAL.Tabs'
}
};
async _onDragStart(event) {
const featureItem = event.currentTarget.closest('.drop-section');
if (featureItem) {
const feature = this.document.system[featureItem.dataset.type];
if (!feature) {
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureIsMissing'));
return;
}
const featureData = { type: 'Item', data: { ...feature.toObject(), _id: null }, fromInternal: true };
event.dataTransfer.setData('text/plain', JSON.stringify(featureData));
event.dataTransfer.setDragImage(featureItem.querySelector('img'), 60, 0);
}
}
async _onDrop(event) {
event.stopPropagation();
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
if (data.fromInternal) return;
const item = await fromUuid(data.uuid);
const target = event.target.closest('fieldset.drop-section');
if (item.type === 'feature') {
if (target.dataset.type === 'foundation') {
if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes.foundation) {
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureNotFoundation'));
return;
}
await item.update({ 'system.subType': CONFIG.DH.ITEM.featureSubTypes.foundation });
await this.document.update({
'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid]
});
} else if (target.dataset.type === 'specialization') {
if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes.specialization) {
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureNotSpecialization'));
return;
}
await item.update({ 'system.subType': CONFIG.DH.ITEM.featureSubTypes.specialization });
await this.document.update({
'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid]
});
} else if (target.dataset.type === 'mastery') {
if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes.mastery) {
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureNotMastery'));
return;
}
await item.update({ 'system.subType': CONFIG.DH.ITEM.featureSubTypes.mastery });
await this.document.update({
'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid]
});
}
}
}
}

View file

@ -20,10 +20,12 @@ export default class DHAncestry extends BaseDataItem {
}
get primaryFeature() {
return this.features.find(x => x.system.itemLinks[this.parent.id] === CONFIG.DH.ITEM.featureSubTypes.primary);
return this.features.find(x => x.system.itemLinks[this.parent.uuid] === CONFIG.DH.ITEM.featureSubTypes.primary);
}
get secondaryFeature() {
return this.features.find(x => x.system.itemLinks[this.parent.id] === CONFIG.DH.ITEM.featureSubTypes.secondary);
return this.features.find(
x => x.system.itemLinks[this.parent.uuid] === CONFIG.DH.ITEM.featureSubTypes.secondary
);
}
}

View file

@ -52,17 +52,11 @@ export default class DHClass extends BaseDataItem {
}
get hopeFeatures() {
return (
this.features.filter(x => x?.system?.subType === CONFIG.DH.ITEM.featureSubTypes.hope) ??
(this.features.filter(x => !x).length > 0 ? {} : null)
);
return this.features.filter(x => x.system.itemLinks[this.parent.uuid] === CONFIG.DH.ITEM.featureSubTypes.hope);
}
get classFeatures() {
return (
this.features.filter(x => x?.system?.subType === CONFIG.DH.ITEM.featureSubTypes.class) ??
(this.features.filter(x => !x).length > 0 ? {} : null)
);
return this.features.filter(x => x.system.itemLinks[this.parent.uuid] === CONFIG.DH.ITEM.featureSubTypes.class);
}
async _preCreate(data, options, user) {

View file

@ -29,15 +29,21 @@ export default class DHSubclass extends BaseDataItem {
}
get foundationFeatures() {
return this.features.filter(x => x.system.subType === CONFIG.DH.ITEM.featureSubTypes.foundation);
return this.features.filter(
x => x.system.itemLinks[this.parent.uuid] === CONFIG.DH.ITEM.featureSubTypes.foundation
);
}
get specializationFeatures() {
return this.features.filter(x => x.system.subType === CONFIG.DH.ITEM.featureSubTypes.specialization);
return this.features.filter(
x => x.system.itemLinks[this.parent.uuid] === CONFIG.DH.ITEM.featureSubTypes.specialization
);
}
get masteryFeatures() {
return this.features.filter(x => x.system.subType === CONFIG.DH.ITEM.featureSubTypes.mastery);
return this.features.filter(
x => x.system.itemLinks[this.parent.uuid] === CONFIG.DH.ITEM.featureSubTypes.mastery
);
}
async _preCreate(data, options, user) {

View file

@ -3,7 +3,7 @@
data-tab='{{tabs.features.id}}'
data-group='{{tabs.features.group}}'
>
<fieldset class="one-column drop-section primary-feature">
<fieldset class="one-column drop-section primary-feature" data-type="primary">
<legend>
{{localize "DAGGERHEART.ITEMS.Ancestry.primaryFeature"}}
{{#unless document.system.primaryFeature}}<a><i data-action="addFeature" data-type="primary" class="fa-solid fa-plus icon-button"></i></a>{{/unless}}
@ -11,8 +11,8 @@
<div class="features-list">
{{#if document.system.primaryFeature}}
<div class="feature-item"
data-action="editFeature"
data-item-uuid="{{this.uuid}}"
data-action="editDoc"
data-item-uuid="{{document.system.primaryFeature.uuid}}"
>
<img class="image" src="{{document.system.primaryFeature.img}}" />
<span>{{document.system.primaryFeature.name}}</span>
@ -24,7 +24,7 @@
</div>
</fieldset>
<fieldset class="one-column drop-section secondary-feature">
<fieldset class="one-column drop-section secondary-feature" data-type="secondary">
<legend>
{{localize "DAGGERHEART.ITEMS.Ancestry.secondaryFeature"}}
{{#unless document.system.secondaryFeature}}<a><i data-action="addFeature" data-type="secondary" class="fa-solid fa-plus icon-button"></i></a>{{/unless}}
@ -32,8 +32,8 @@
<div class="features-list">
{{#if document.system.secondaryFeature}}
<div class="feature-item"
data-action="editFeature"
data-item-uuid="{{this.uuid}}"
data-action="editDoc"
data-item-uuid="{{document.system.secondaryFeature.uuid}}"
>
<img class="image" src="{{document.system.secondaryFeature.img}}" />
<span>{{document.system.secondaryFeature.name}}</span>

View file

@ -4,7 +4,7 @@
data-group='{{tabs.features.group}}'
>
<div class="two-columns even">
<fieldset class="drop-section hope-feature">
<fieldset class="drop-section" data-type="hope">
<legend>{{localize "DAGGERHEART.ITEMS.Class.hopeFeatures"}} <a><i class="fa-solid fa-plus icon-button" data-type="hope" data-action="addFeature"></i></a></legend>
<div class="feature-list">
{{#each source.system.hopeFeatures as |feature|}}
@ -13,7 +13,7 @@
</div>
</fieldset>
<fieldset class="drop-section class-feature">
<fieldset class="drop-section" data-type="class">
<legend>{{localize "DAGGERHEART.ITEMS.Class.classFeatures"}} <a><i class="fa-solid fa-plus icon-button" data-type="class" data-action="addFeature"></i></a></legend>
<div class="feature-list">
{{#each source.system.classFeatures as |feature|}}