diff --git a/lang/en.json b/lang/en.json index 28e2829c..09cbef70 100755 --- a/lang/en.json +++ b/lang/en.json @@ -2442,7 +2442,6 @@ "single": "Miss", "plural": "Miss" }, - "missingX": "Missing {x}", "maxWithThing": "Max {thing}", "missingDragDropThing": "Drop {thing} here", "multiclass": "Multiclass", @@ -3165,6 +3164,7 @@ "noSelectionsLeft": "Nothing more to select!", "alreadySelectedClass": "You already have that class!", "classAlreadySelected": "The character already has a class", + "classMissingIdentifier": "The class hasn't set up an identifier", "subclassAlreadySelected": "The character already has a subclass for that class.", "noClassSelected": "Your character has no class selected!", "lacksDomain": "Your character doesn't have the domain of the card!", diff --git a/module/applications/sheets/items/class.mjs b/module/applications/sheets/items/class.mjs index 25c631fe..0e253ddd 100644 --- a/module/applications/sheets/items/class.mjs +++ b/module/applications/sheets/items/class.mjs @@ -9,7 +9,8 @@ export default class ClassSheet extends DHBaseItemSheet { position: { width: 700 }, actions: { removeItemFromCollection: ClassSheet.#removeItemFromCollection, - removeSuggestedItem: ClassSheet.#removeSuggestedItem + removeSuggestedItem: ClassSheet.#removeSuggestedItem, + resetIdentifier: ClassSheet.#resetIdentifier }, tagifyConfigs: [ { @@ -104,10 +105,10 @@ export default class ClassSheet extends DHBaseItemSheet { } /**@inheritdoc */ - async _prepareContext(options) { - const context = await super._prepareContext(options); + async _prepareContext(_options) { + const context = await super._prepareContext(_options); context.domains = this.document.system.domains; - context.subclasses = await this.document.system.fetchSubclasses(); + context.subclasses = await this.document.system.getSubclasses(); return context; } @@ -189,6 +190,12 @@ 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); + + if (target === 'subclasses') { + const subclass = await foundry.utils.fromUuid(uuid); + await subclass?.update({ 'system.linkedClass': null }); + } + await this.document.update({ [`system.${target}`]: prop.filter(i => i && i.uuid !== uuid).map(x => x.uuid) }); } @@ -201,4 +208,10 @@ export default class ClassSheet extends DHBaseItemSheet { const { target } = element.dataset; await this.document.update({ [`system.characterGuide.${target}`]: null }); } + + static async #resetIdentifier() { + const document = this.document; + const initial = document.system.schema.fields.identifier.getInitialValue(document._source); + document.update({ 'system.identifier': initial }); + } } diff --git a/module/applications/sheets/items/subclass.mjs b/module/applications/sheets/items/subclass.mjs index 254ab7cc..db01bfae 100644 --- a/module/applications/sheets/items/subclass.mjs +++ b/module/applications/sheets/items/subclass.mjs @@ -41,27 +41,22 @@ export default class SubclassSheet extends DHBaseItemSheet { return this.document.system.features.map(x => x.item); } - async _prepareContext(options) { - const context = await super._prepareContext(options); - if (this.document.system.linkedClass) { - context.class = (await fromUuid(this.document.system.linkedClass)) ?? { - name: _loc('DAGGERHEART.GENERAL.missingX', { x: _loc('TYPES.Item.class') }), - img: 'systems/daggerheart/assets/icons/documents/items/laurel-crown.svg', - missing: true - }; - } - return context; - } - async _onDrop(event) { event.stopPropagation(); const data = TextEditor.getDragEventData(event); const item = await fromUuid(data.uuid); const itemType = data.type === 'ActiveEffect' ? data.type : item.type; if (itemType === 'class') { - const uuid = item._stats.compendiumSource ?? item.uuid; - if (this.document.system.linkedClass !== uuid) { - await this.document.update({ 'system.linkedClass': uuid }); + const identifier = item.system.identifier; + if (!identifier) { + return ui.notifications.error( + game.i18n.localize('DAGGERHEART.UI.Notifications.classMissingIdentifier') + ); + } + + if (this.document.system.classLink.identifier !== identifier) { + const { img, name } = item; + await this.document.update({ 'system.classLink': { identifier, img, name } }); } return; } diff --git a/module/data/item/class.mjs b/module/data/item/class.mjs index 7014e011..49195b5a 100644 --- a/module/data/item/class.mjs +++ b/module/data/item/class.mjs @@ -2,7 +2,7 @@ import BaseDataItem from './base.mjs'; import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs'; import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs'; import ItemLinkFields from '../fields/itemLinkFields.mjs'; -import { addLinkedItemsDiff, getFeaturesHTMLData, updateLinkedItemApps } from '../../helpers/utils.mjs'; +import { addLinkedItemsDiff, camelize, getFeaturesHTMLData, updateLinkedItemApps } from '../../helpers/utils.mjs'; export default class DHClass extends BaseDataItem { /** @inheritDoc */ @@ -50,7 +50,10 @@ export default class DHClass extends BaseDataItem { }), backgroundQuestions: new fields.ArrayField(new fields.StringField(), { initial: ['', '', ''] }), connections: new fields.ArrayField(new fields.StringField(), { initial: ['', '', ''] }), - isMulticlass: new fields.BooleanField({ initial: false }) + isMulticlass: new fields.BooleanField({ initial: false }), + identifier: new fields.StringField({ blank: false, initial: obj => camelize(obj?.name ?? '') }), + /* Subclasses is legacy. If we can safetely migrate it away at some point we could remove it*/ + subclasses: new ForeignDocumentUUIDArrayField({ type: 'Item', required: false }) }; } @@ -69,14 +72,18 @@ export default class DHClass extends BaseDataItem { return this.features.filter(x => x.type === CONFIG.DH.ITEM.featureSubTypes.class).map(x => x.item); } - async fetchSubclasses() { - const uuids = [this.parent.uuid, this.parent._stats?.compendiumSource].filter(u => !!u); - const subclasses = game.items.filter(x => x.type === 'subclass' && uuids.includes(x.system.linkedClass)); + async getSubclasses() { + const oldLinkedSubclasses = this.subclasses; + if (oldLinkedSubclasses.length) return oldLinkedSubclasses; + + const subclasses = game.items.filter( + x => x.type === 'subclass' && x.system.classLink.identifier === this.identifier + ); for (const pack of game.packs) { - const indexes = await pack.getIndex({ fields: ['system.linkedClass'] }); + const indexes = await pack.getIndex({ fields: ['system.classLink.identifier'] }); for (const index of indexes) { if (index.type !== 'subclass') continue; - if (!uuids.includes(index.system?.linkedClass)) continue; + if (index.system?.classLink?.identifier !== this.identifier) continue; if (subclasses.find(x => x.uuid === index.uuid)) continue; const subclass = await foundry.utils.fromUuid(index.uuid); diff --git a/module/data/item/subclass.mjs b/module/data/item/subclass.mjs index 865ac085..96c9f5de 100644 --- a/module/data/item/subclass.mjs +++ b/module/data/item/subclass.mjs @@ -28,7 +28,13 @@ export default class DHSubclass extends BaseDataItem { features: new ItemLinkFields(), featureState: new fields.NumberField({ required: true, initial: 1, min: 1 }), isMulticlass: new fields.BooleanField({ initial: false }), - linkedClass: new fields.DocumentUUIDField({ type: 'Item', nullable: true, initial: null }) + classLink: new fields.SchemaField({ + identifier: new fields.StringField({ nullable: true, initial: null }), + name: new fields.StringField(), + img: new fields.StringField() + }), + /* Linked class is legacy. If we can safetely migrate it away at some point we could remove it */ + linkedClass: new ForeignDocumentUUIDField({ type: 'Item', nullable: true, initial: null }) }; } diff --git a/templates/sheets/items/class/features.hbs b/templates/sheets/items/class/features.hbs index 279ff52c..5da6e368 100644 --- a/templates/sheets/items/class/features.hbs +++ b/templates/sheets/items/class/features.hbs @@ -41,8 +41,19 @@ data-item-uuid={{subclass.uuid}} data-tooltip='{{localize "DAGGERHEART.UI.Tooltip.openItemWorld"}}' > - + + {{#if document.system.subclasses}} + + + + {{/if}} diff --git a/templates/sheets/items/class/settings.hbs b/templates/sheets/items/class/settings.hbs index b224ec1f..d44b12dd 100644 --- a/templates/sheets/items/class/settings.hbs +++ b/templates/sheets/items/class/settings.hbs @@ -3,6 +3,15 @@ data-tab='{{tabs.settings.id}}' data-group='{{tabs.settings.group}}' > +
+