mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 11:41:08 +01:00
[Fix] Itemlink Redux Revengeance (#399)
* Small random fixes * Added use of ItemLinkFields * Multiclass levelup fixes * Fixed our onCreate methods unintentionally being run on all clients * Remade apps handling * Added for all class items and subclass * Restored foreignDocumentUuidField * Improved * PR fxies * Fixed tooltip enrichment * . * Reverted silly change
This commit is contained in:
parent
fcba5041e9
commit
2a4777f1a0
61 changed files with 648 additions and 489 deletions
|
|
@ -205,7 +205,11 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
|
||||
_getSetupTabs(tabs) {
|
||||
for (const v of Object.values(tabs)) {
|
||||
v.active = this.tabGroups[v.group] ? this.tabGroups[v.group] === v.id : v.active;
|
||||
v.active = this.tabGroups[v.group]
|
||||
? this.tabGroups[v.group] === v.id
|
||||
: this.tabGroups.primary !== 'equipment'
|
||||
? v.active
|
||||
: false;
|
||||
v.cssClass = v.active ? 'active' : '';
|
||||
|
||||
switch (v.id) {
|
||||
|
|
@ -242,6 +246,16 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
marker.classList.remove('active');
|
||||
}
|
||||
}
|
||||
|
||||
if (tab === 'equipment') {
|
||||
this.tabGroups.setup = null;
|
||||
this.element.querySelector('section[data-group="setup"].active')?.classList?.remove?.('active');
|
||||
} else {
|
||||
this.tabGroups.setup = 'domainCards';
|
||||
this.element
|
||||
.querySelector('section[data-group="setup"][data-tab="domainCards"]')
|
||||
?.classList?.add?.('active');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -256,6 +270,11 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
});
|
||||
}
|
||||
|
||||
async _preFirstRender(_context, _options) {
|
||||
this.tabGroups.primary = 'setup';
|
||||
this.tabGroups.setup = 'ancestry';
|
||||
}
|
||||
|
||||
async _prepareContext(_options) {
|
||||
const context = await super._prepareContext(_options);
|
||||
context.tabs = this._getTabs(this.constructor.TABS);
|
||||
|
|
@ -266,7 +285,7 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
async _preparePartContext(partId, context) {
|
||||
switch (partId) {
|
||||
case 'footer':
|
||||
context.isLastTab = this.tabGroups.setup === 'domainCards';
|
||||
context.isLastTab = this.tabGroups.setup === 'domainCards' || this.tabGroups.primary !== 'setup';
|
||||
switch (this.tabGroups.setup) {
|
||||
case null:
|
||||
case 'ancestry':
|
||||
|
|
@ -321,10 +340,7 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
})
|
||||
};
|
||||
context.traits.nrTotal = Object.keys(context.traits.values).length;
|
||||
context.traits.nrSelected = Object.values(context.traits.values).reduce(
|
||||
(acc, trait) => acc + (trait.value !== null ? 1 : 0),
|
||||
0
|
||||
);
|
||||
context.traits.nrSelected = this.getNrSelectedTrait();
|
||||
|
||||
context.experience = {
|
||||
values: this.setup.experiences,
|
||||
|
|
@ -378,6 +394,10 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
choiceA: { suggestions: suggestions.inventory.choiceA, compendium: 'consumables' },
|
||||
choiceB: { suggestions: suggestions.inventory.choiceB, compendium: 'general-items' }
|
||||
};
|
||||
context.noInventoryChoices =
|
||||
suggestions.inventory.take.length === 0 &&
|
||||
suggestions.inventory.choiceA?.length === 0 &&
|
||||
suggestions.inventory.choiceB?.length === 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -408,7 +428,7 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
case 5:
|
||||
return Object.values(this.setup.experiences).every(x => x.name) ? 6 : 5;
|
||||
case 4:
|
||||
return Object.values(this.setup.traits).every(x => x.value !== null) ? 5 : 4;
|
||||
return this.getNrSelectedTrait() === 6 ? 5 : 4;
|
||||
case 3:
|
||||
return this.setup.class.uuid && this.setup.subclass.uuid ? 4 : 3;
|
||||
case 2:
|
||||
|
|
@ -418,6 +438,18 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
}
|
||||
}
|
||||
|
||||
getNrSelectedTrait() {
|
||||
const traitCompareArray = [
|
||||
...game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).traitArray
|
||||
];
|
||||
return Object.values(this.setup.traits).reduce((acc, x) => {
|
||||
const index = traitCompareArray.indexOf(x.value);
|
||||
traitCompareArray.splice(index, 1);
|
||||
acc += index !== -1;
|
||||
return acc;
|
||||
}, 0);
|
||||
}
|
||||
|
||||
async getEquipmentSuggestions(choiceA, choiceB) {
|
||||
if (!this.setup.class.uuid) return { inventory: { take: [] } };
|
||||
|
||||
|
|
@ -429,10 +461,15 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
? { ...characterGuide.suggestedSecondaryWeapon, uuid: characterGuide.suggestedSecondaryWeapon.uuid }
|
||||
: null,
|
||||
inventory: {
|
||||
take: inventory.take ?? [],
|
||||
take: inventory.take?.filter(x => x) ?? [],
|
||||
choiceA:
|
||||
inventory.choiceA?.map(x => ({ ...x, uuid: x.uuid, selected: x.uuid === choiceA?.uuid })) ?? [],
|
||||
choiceB: inventory.choiceB?.map(x => ({ ...x, uuid: x.uuid, selected: x.uuid === choiceB?.uuid })) ?? []
|
||||
inventory.choiceA
|
||||
?.filter(x => x)
|
||||
.map(x => ({ ...x, uuid: x.uuid, selected: x.uuid === choiceA?.uuid })) ?? [],
|
||||
choiceB:
|
||||
inventory.choiceB
|
||||
?.filter(x => x)
|
||||
.map(x => ({ ...x, uuid: x.uuid, selected: x.uuid === choiceB?.uuid })) ?? []
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -506,7 +543,10 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
name: this.setup.ancestryName ?? this.setup.primaryAncestry.name,
|
||||
system: {
|
||||
...this.setup.primaryAncestry.system,
|
||||
features: [primaryAncestryFeature.uuid, secondaryAncestryFeature.uuid]
|
||||
features: [
|
||||
{ type: 'primary', item: primaryAncestryFeature.uuid },
|
||||
{ type: 'secondary', item: secondaryAncestryFeature.uuid }
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -535,7 +575,10 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
await this.character.createEmbeddedDocuments('Item', [this.equipment.inventory.choiceA]);
|
||||
if (this.equipment.inventory.choiceB.uuid)
|
||||
await this.character.createEmbeddedDocuments('Item', [this.equipment.inventory.choiceB]);
|
||||
await this.character.createEmbeddedDocuments('Item', this.setup.class.system.inventory.take);
|
||||
await this.character.createEmbeddedDocuments(
|
||||
'Item',
|
||||
this.setup.class.system.inventory.take.filter(x => x)
|
||||
);
|
||||
|
||||
await this.character.update({
|
||||
system: {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
||||
|
||||
export default class ActionSelectionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
constructor(item, event, options={}) {
|
||||
constructor(item, event, options = {}) {
|
||||
super(options);
|
||||
this.#item = item;
|
||||
this.#event = event;
|
||||
|
|
@ -24,7 +24,7 @@ export default class ActionSelectionDialog extends HandlebarsApplicationMixin(Ap
|
|||
|
||||
static PARTS = {
|
||||
actions: {
|
||||
template: "systems/daggerheart/templates/dialogs/actionSelect.hbs"
|
||||
template: 'systems/daggerheart/templates/dialogs/actionSelect.hbs'
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -60,10 +60,10 @@ export default class ActionSelectionDialog extends HandlebarsApplicationMixin(Ap
|
|||
const actions = this.#item.system.actionsList,
|
||||
itemName = this.#item.name;
|
||||
return {
|
||||
...await super._prepareContext(options),
|
||||
...(await super._prepareContext(options)),
|
||||
actions,
|
||||
itemName
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static async #onChooseAction(event, button) {
|
||||
|
|
@ -80,8 +80,8 @@ export default class ActionSelectionDialog extends HandlebarsApplicationMixin(Ap
|
|||
static create(item, event, options) {
|
||||
return new Promise(resolve => {
|
||||
const dialog = new this(item, event, options);
|
||||
dialog.addEventListener("close", () => resolve(dialog.action), { once: true });
|
||||
dialog.addEventListener('close', () => resolve(dialog.action), { once: true });
|
||||
dialog.render({ force: true });
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,10 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
}));
|
||||
|
||||
if (this.config.costs?.length) {
|
||||
const updatedCosts = game.system.api.fields.ActionFields.CostField.calcCosts.call(this.action, this.config.costs);
|
||||
const updatedCosts = game.system.api.fields.ActionFields.CostField.calcCosts.call(
|
||||
this.action,
|
||||
this.config.costs
|
||||
);
|
||||
context.costs = updatedCosts.map(x => ({
|
||||
...x,
|
||||
label: x.keyIsID
|
||||
|
|
@ -80,7 +83,9 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
}
|
||||
if (this.config.uses?.max) {
|
||||
context.uses = game.system.api.fields.ActionFields.UsesField.calcUses.call(this.action, this.config.uses);
|
||||
context.canRoll = context.canRoll && game.system.api.fields.ActionFields.UsesField.hasUses.call(this.action, context.uses);
|
||||
context.canRoll =
|
||||
context.canRoll &&
|
||||
game.system.api.fields.ActionFields.UsesField.hasUses.call(this.action, context.uses);
|
||||
}
|
||||
if (this.roll) {
|
||||
context.roll = this.roll;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import LevelUpBase from './levelup.mjs';
|
||||
import { DhLevelup } from '../../data/levelup.mjs';
|
||||
import { domains } from '../../config/domainConfig.mjs';
|
||||
import { abilities } from '../../config/actorConfig.mjs';
|
||||
import { abilities, subclassFeatureLabels } from '../../config/actorConfig.mjs';
|
||||
|
||||
export default class DhCharacterLevelUp extends LevelUpBase {
|
||||
constructor(actor) {
|
||||
|
|
@ -166,6 +166,7 @@ export default class DhCharacterLevelUp extends LevelUpBase {
|
|||
context.multiclass = {
|
||||
...data,
|
||||
...(multiclass.toObject?.() ?? multiclass),
|
||||
type: 'multiclass',
|
||||
uuid: multiclass.uuid,
|
||||
domains:
|
||||
multiclass?.system?.domains.map(key => {
|
||||
|
|
@ -349,8 +350,8 @@ export default class DhCharacterLevelUp extends LevelUpBase {
|
|||
if (!acc) acc = {};
|
||||
acc[traitKey] = {
|
||||
label: game.i18n.localize(abilities[traitKey].label),
|
||||
old: this.actor.system.traits[traitKey].max,
|
||||
new: this.actor.system.traits[traitKey].max + advancement.trait[traitKey]
|
||||
old: this.actor.system.traits[traitKey].value,
|
||||
new: this.actor.system.traits[traitKey].value + advancement.trait[traitKey]
|
||||
};
|
||||
}
|
||||
return acc;
|
||||
|
|
|
|||
|
|
@ -452,6 +452,12 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
|
|||
return;
|
||||
}
|
||||
|
||||
const secondaryData = Object.keys(
|
||||
foundry.utils.getProperty(this.levelup, `${target.dataset.path}.secondaryData`)
|
||||
).reduce((acc, key) => {
|
||||
acc[`-=${key}`] = null;
|
||||
return acc;
|
||||
}, {});
|
||||
await this.levelup.updateSource({
|
||||
multiclass: {
|
||||
class: item.uuid,
|
||||
|
|
@ -464,7 +470,8 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
|
|||
amount: target.dataset.amount ? Number(target.dataset.amount) : null,
|
||||
value: target.dataset.value,
|
||||
type: target.dataset.type,
|
||||
data: item.uuid
|
||||
data: item.uuid,
|
||||
secondaryData: secondaryData
|
||||
}
|
||||
});
|
||||
this.render();
|
||||
|
|
@ -538,10 +545,21 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
|
|||
static async selectDomain(_, button) {
|
||||
const option = foundry.utils.getProperty(this.levelup, button.dataset.path);
|
||||
const domain = option.secondaryData.domain ? null : button.dataset.domain;
|
||||
const update = { [`${button.dataset.path}.secondaryData.domain`]: domain };
|
||||
|
||||
await this.levelup.updateSource({
|
||||
[`${button.dataset.path}.secondaryData.domain`]: domain
|
||||
const domainCards = this.levelup.levels[this.levelup.currentLevel].achievements.domainCards;
|
||||
const illegalDomainCards = option.secondaryData.domain
|
||||
? Object.keys(domainCards)
|
||||
.map(key => ({ ...domainCards[key], key }))
|
||||
.filter(
|
||||
x => x.uuid && foundry.utils.fromUuidSync(x.uuid).system.domain === option.secondaryData.domain
|
||||
)
|
||||
: [];
|
||||
illegalDomainCards.forEach(card => {
|
||||
update[`levels.${this.levelup.currentLevel}.achievements.domainCards.${card.key}.uuid`] = null;
|
||||
});
|
||||
|
||||
await this.levelup.updateSource(update);
|
||||
this.render();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -107,6 +107,13 @@ export default function DHApplicationMixin(Base) {
|
|||
tagifyConfigs: []
|
||||
};
|
||||
|
||||
/**
|
||||
* Related documents that should cause a rerender of this application when updated.
|
||||
*/
|
||||
get relatedDocs() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**@inheritdoc */
|
||||
|
|
@ -117,9 +124,17 @@ export default function DHApplicationMixin(Base) {
|
|||
/**@inheritdoc */
|
||||
async _onFirstRender(context, options) {
|
||||
await super._onFirstRender(context, options);
|
||||
this.relatedDocs.filter(doc => doc).map(doc => (doc.apps[this.id] = this));
|
||||
|
||||
if (!!this.options.contextMenus.length) this._createContextMenus();
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
_onClose(options) {
|
||||
super._onClose(options);
|
||||
this.relatedDocs.filter(doc => doc).map(doc => delete doc.apps[this.id]);
|
||||
}
|
||||
|
||||
/**@inheritdoc */
|
||||
async _onRender(context, options) {
|
||||
await super._onRender(context, options);
|
||||
|
|
@ -285,7 +300,7 @@ export default function DHApplicationMixin(Base) {
|
|||
icon: 'fa-solid fa-pen-to-square',
|
||||
condition: target => {
|
||||
const doc = getDocFromElement(target);
|
||||
return !doc.hasOwnProperty('systemPath') || doc.inCollection
|
||||
return !doc.hasOwnProperty('systemPath') || doc.inCollection;
|
||||
},
|
||||
callback: target => getDocFromElement(target).sheet.render({ force: true })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,13 +150,15 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
|||
static async #addFeature(_, target) {
|
||||
const { type } = target.dataset;
|
||||
const cls = foundry.documents.Item.implementation;
|
||||
const feature = await cls.create({
|
||||
'type': 'feature',
|
||||
'name': cls.defaultName({ type: 'feature' }),
|
||||
'system.subType': CONFIG.DH.ITEM.featureSubTypes[type]
|
||||
const item = await cls.create({
|
||||
type: 'feature',
|
||||
name: cls.defaultName({ type: 'feature' })
|
||||
});
|
||||
await this.document.update({
|
||||
'system.features': [...this.document.system.features, feature].map(f => f.uuid)
|
||||
'system.features': [...this.document.system.features, { type, item }].map(x => ({
|
||||
...x,
|
||||
item: x.item?.uuid
|
||||
}))
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -164,12 +166,14 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) {
|
|||
* Remove a feature from the item.
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #deleteFeature(_, target) {
|
||||
static async #deleteFeature(_, element) {
|
||||
const target = element.closest('[data-item-uuid]');
|
||||
const feature = getDocFromElement(target);
|
||||
if (!feature) return ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureIsMissing'));
|
||||
await feature.update({ 'system.subType': null });
|
||||
await this.document.update({
|
||||
'system.features': this.document.system.features.map(x => x.uuid).filter(uuid => uuid !== feature.uuid)
|
||||
'system.features': this.document.system.features
|
||||
.filter(x => target.dataset.type !== x.type || x.item.uuid !== feature.uuid)
|
||||
.map(x => ({ ...x, item: x.item.uuid }))
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -242,10 +246,15 @@ 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 current = this.document.system.features.map(x => x.uuid);
|
||||
await this.document.update({ 'system.features': [...current, item.uuid] });
|
||||
await this.document.update({
|
||||
'system.features': [...this.document.system.features, { type: target.dataset.type, item }].map(x => ({
|
||||
...x,
|
||||
item: x.item?.uuid
|
||||
}))
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,12 +3,7 @@ import DHHeritageSheet from '../api/heritage-sheet.mjs';
|
|||
export default class AncestrySheet extends DHHeritageSheet {
|
||||
/**@inheritdoc */
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ['ancestry'],
|
||||
actions: {
|
||||
editFeature: AncestrySheet.#editFeature,
|
||||
removeFeature: AncestrySheet.#removeFeature
|
||||
},
|
||||
dragDrop: [{ dragSelector: null, dropSelector: '.tab.features .drop-section' }]
|
||||
classes: ['ancestry']
|
||||
};
|
||||
|
||||
/**@inheritdoc */
|
||||
|
|
@ -18,38 +13,9 @@ export default class AncestrySheet extends DHHeritageSheet {
|
|||
features: { template: 'systems/daggerheart/templates/sheets/items/ancestry/features.hbs' }
|
||||
};
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Application Clicks Actions */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Edit an existing feature on the item
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #editFeature(_event, button) {
|
||||
const target = button.closest('.feature-item');
|
||||
const feature = this.document.system[`${target.dataset.type}Feature`];
|
||||
if (!feature || Object.keys(feature).length === 0) {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.featureIsMissing'));
|
||||
return;
|
||||
}
|
||||
|
||||
feature.sheet.render(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a feature from the item.
|
||||
* @type {ApplicationClickAction}
|
||||
*/
|
||||
static async #removeFeature(event, button) {
|
||||
event.stopPropagation();
|
||||
const target = button.closest('.feature-item');
|
||||
const feature = this.document.system[`${target.dataset.type}Feature`];
|
||||
|
||||
if (feature) await feature.update({ 'system.subType': null });
|
||||
await this.document.update({
|
||||
'system.features': this.document.system.features.filter(x => x && x.uuid !== feature.uuid).map(x => x.uuid)
|
||||
});
|
||||
/**@inheritdoc */
|
||||
get relatedDocs() {
|
||||
return this.document.system.features.map(x => x.item);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
|
@ -61,22 +27,12 @@ export default class AncestrySheet extends DHHeritageSheet {
|
|||
* @param {DragEvent} event - The drag event
|
||||
*/
|
||||
async _onDrop(event) {
|
||||
event.stopPropagation();
|
||||
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
||||
const target = event.target.closest('fieldset.drop-section');
|
||||
const typeField =
|
||||
this.document.system[target.dataset.type === 'primary' ? 'primaryFeature' : 'secondaryFeature'];
|
||||
|
||||
const item = await fromUuid(data.uuid);
|
||||
if (item?.type === 'feature') {
|
||||
const subType = event.target.closest('.primary-feature') ? 'primary' : 'secondary';
|
||||
if (item.system.subType && item.system.subType !== CONFIG.DH.ITEM.featureSubTypes[subType]) {
|
||||
const error = subType === 'primary' ? 'featureNotPrimary' : 'featureNotSecondary';
|
||||
ui.notifications.warn(game.i18n.localize(`DAGGERHEART.UI.Notifications.${error}`));
|
||||
return;
|
||||
}
|
||||
|
||||
await item.update({ 'system.subType': subType });
|
||||
await this.document.update({
|
||||
'system.features': [...this.document.system.features.map(x => x.uuid), item.uuid]
|
||||
});
|
||||
if (!typeField) {
|
||||
super._onDrop(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,11 @@ export default class BeastformSheet extends DHBaseItemSheet {
|
|||
}
|
||||
};
|
||||
|
||||
/**@inheritdoc */
|
||||
get relatedDocs() {
|
||||
return this.document.system.features;
|
||||
}
|
||||
|
||||
_attachPartListeners(partId, htmlElement, options) {
|
||||
super._attachPartListeners(partId, htmlElement, options);
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,31 @@ export default class ClassSheet extends DHBaseItemSheet {
|
|||
}
|
||||
};
|
||||
|
||||
/**@inheritdoc */
|
||||
get relatedDocs() {
|
||||
return this.document.system.features.map(x => x.item);
|
||||
}
|
||||
|
||||
/**@inheritdoc */
|
||||
async _onFirstRender(context, options) {
|
||||
await super._onFirstRender(context, options);
|
||||
|
||||
const paths = [
|
||||
'subclasses',
|
||||
'characterGuide.suggestedPrimaryWeapon',
|
||||
'characterGuide.suggestedSecondaryWeapon',
|
||||
'characterGuide.suggestedArmor',
|
||||
'inventory.take',
|
||||
'inventory.choiceA',
|
||||
'inventory.choiceB'
|
||||
];
|
||||
|
||||
paths.forEach(path => {
|
||||
const docs = [].concat(foundry.utils.getProperty(this.document, `system.${path}`) ?? []);
|
||||
docs.forEach(doc => (doc.apps[this.id] = this));
|
||||
});
|
||||
}
|
||||
|
||||
/**@inheritdoc */
|
||||
async _prepareContext(_options) {
|
||||
const context = await super._prepareContext(_options);
|
||||
|
|
@ -87,69 +112,45 @@ 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)
|
||||
if (!item.system.secondary)
|
||||
await this.document.update({
|
||||
'system.characterGuide.suggestedPrimaryWeapon': item.uuid
|
||||
});
|
||||
} else if (target.classList.contains('secondary-weapon-section')) {
|
||||
if (!this.document.system.characterGuide.suggestedSecondaryWeapon && item.system.secondary)
|
||||
if (item.system.secondary)
|
||||
await this.document.update({
|
||||
'system.characterGuide.suggestedSecondaryWeapon': item.uuid
|
||||
});
|
||||
}
|
||||
} else if (item.type === 'armor') {
|
||||
if (target.classList.contains('armor-section')) {
|
||||
if (!this.document.system.characterGuide.suggestedArmor)
|
||||
await this.document.update({
|
||||
'system.characterGuide.suggestedArmor': item.uuid
|
||||
});
|
||||
await this.document.update({
|
||||
'system.characterGuide.suggestedArmor': item.uuid
|
||||
});
|
||||
}
|
||||
} else if (target.classList.contains('choice-a-section')) {
|
||||
if (item.type === 'miscellaneous' || item.type === 'consumable') {
|
||||
if (this.document.system.inventory.choiceA.length < 2)
|
||||
const filteredChoiceA = this.document.system.inventory.choiceA;
|
||||
if (filteredChoiceA.length < 2)
|
||||
await this.document.update({
|
||||
'system.inventory.choiceA': [
|
||||
...this.document.system.inventory.choiceA.map(x => x.uuid),
|
||||
item.uuid
|
||||
]
|
||||
'system.inventory.choiceA': [...filteredChoiceA.map(x => x.uuid), item.uuid]
|
||||
});
|
||||
}
|
||||
} else if (item.type === 'miscellaneous') {
|
||||
if (target.classList.contains('take-section')) {
|
||||
if (this.document.system.inventory.take.length < 3)
|
||||
const filteredTake = this.document.system.inventory.take.filter(x => x);
|
||||
if (filteredTake.length < 3)
|
||||
await this.document.update({
|
||||
'system.inventory.take': [...this.document.system.inventory.take.map(x => x.uuid), item.uuid]
|
||||
'system.inventory.take': [...filteredTake.map(x => x.uuid), item.uuid]
|
||||
});
|
||||
} else if (target.classList.contains('choice-b-section')) {
|
||||
if (this.document.system.inventory.choiceB.length < 2)
|
||||
const filteredChoiceB = this.document.system.inventory.choiceB.filter(x => x);
|
||||
if (filteredChoiceB.length < 2)
|
||||
await this.document.update({
|
||||
'system.inventory.choiceB': [
|
||||
...this.document.system.inventory.choiceB.map(x => x.uuid),
|
||||
item.uuid
|
||||
]
|
||||
'system.inventory.choiceB': [...filteredChoiceB.map(x => x.uuid), item.uuid]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -167,7 +168,7 @@ export default class ClassSheet extends DHBaseItemSheet {
|
|||
static async #removeItemFromCollection(_event, element) {
|
||||
const { uuid, target } = element.dataset;
|
||||
const prop = foundry.utils.getProperty(this.document.system, target);
|
||||
await this.document.update({ [`system.${target}`]: prop.filter(i => i.uuid !== uuid) });
|
||||
await this.document.update({ [`system.${target}`]: prop.filter(i => i.uuid !== uuid).map(x => x.uuid) });
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -15,4 +15,9 @@ export default class CommunitySheet extends DHHeritageSheet {
|
|||
scrollable: ['.feature']
|
||||
}
|
||||
};
|
||||
|
||||
/**@inheritdoc */
|
||||
get relatedDocs() {
|
||||
return this.document.system.features;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
@ -37,62 +36,8 @@ export default class SubclassSheet extends DHBaseItemSheet {
|
|||
}
|
||||
};
|
||||
|
||||
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]
|
||||
});
|
||||
}
|
||||
}
|
||||
/**@inheritdoc */
|
||||
get relatedDocs() {
|
||||
return this.document.system.features.map(x => x.item);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
const action = message.system.actions[Number.parseInt(event.currentTarget.dataset.index)];
|
||||
const actor = game.actors.get(message.system.source.actor);
|
||||
await actor.use(action);
|
||||
};
|
||||
}
|
||||
|
||||
async actionUseButton(event, message) {
|
||||
const { moveIndex, actionIndex } = event.currentTarget.dataset;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue