diff --git a/discworld.mjs b/discworld.mjs index 4a41f59..65bbddc 100644 --- a/discworld.mjs +++ b/discworld.mjs @@ -14,6 +14,7 @@ import * as Rolls from "./modules/rolls/index.mjs"; import DiscworldCharacter from "./modules/documents/character.mjs"; +import DiscworldSheetMixin from "./modules/applications/sheets/base-document-sheet.mjs"; import TraitSheet from "./modules/applications/sheets/trait-sheet.mjs"; import DiscworldJournalEntrySheet from "./modules/applications/sheets/journal-entry-sheet.mjs"; @@ -29,6 +30,7 @@ globalThis.discworld = { TraitDataModel, }, sheets: { + DiscworldSheetMixin, DiscworldActorSheet, CharacterSheet, TraitSheet, diff --git a/lang/en.json b/lang/en.json index d1b7252..5d3edd4 100644 --- a/lang/en.json +++ b/lang/en.json @@ -75,13 +75,19 @@ "background": "Background", "consequences": "Consequences", "core": "Core", + "features": "Features", + "mannerism": "Mannerism", "niche": "Niche", "organization": "Organization", + "other": "Other", "quirks": "Quirks", - "other": "Other" + "species": "Species" }, "FIELDS": { + "actorType": { + "label": "Actor Type" + }, "notes": { "label": "Notes" }, diff --git a/modules/applications/sheets/actors/base-actor-sheet.mjs b/modules/applications/sheets/actors/base-actor-sheet.mjs index 5f4f86b..7407a75 100644 --- a/modules/applications/sheets/actors/base-actor-sheet.mjs +++ b/modules/applications/sheets/actors/base-actor-sheet.mjs @@ -61,6 +61,17 @@ export default class DiscworldActorSheet extends DiscworldSheetMixin(ActorSheetV return this.actor.helpMode.enabled; } + /* ------------------------------------------------- */ + + /** + * Helper to get the base actor type, e.g., removing any prefixes from modules. + * @example "character" -> "character"; "discworld-core.npc" -> "npc" + * @type {string} + */ + get actorBaseType() { + return this.actor.type.replace(/.*\./, ""); + } + /* -------------------------------------------------- */ /** @inheritdoc */ @@ -76,11 +87,12 @@ export default class DiscworldActorSheet extends DiscworldSheetMixin(ActorSheetV { rollData: this.document.getRollData(), relativeTo: this.document }, ); + const traitActorGroup = DISCWORLD.traitTypes[this.actorBaseType]; // Get just the base actor type. // Construct arrays of traits, filtered by category. - context.traitGroups = this._getTraitGroups(); + context.traitGroups = this._getTraitGroups(traitActorGroup); // Translation of trait types. - context.traitTypeTranslationMap = DISCWORLD.traitTypes; + context.traitTypeTranslationMap = traitActorGroup; return context; } @@ -116,10 +128,10 @@ export default class DiscworldActorSheet extends DiscworldSheetMixin(ActorSheetV /** * Get trait groups by type. - * @param {Object} traitTypes - * @returns {Record} + * @param {Object} traitTypes Trait types for a particular sheet. + * @returns {Record} */ - _getTraitGroups(traitTypes = DISCWORLD.traitTypes) { + _getTraitGroups(traitTypes) { const items = Object.groupBy(this.actor.items, item => item.system.type); return Object.keys(traitTypes).reduce((acc, traitType) => { acc[traitType] = items[traitType] ?? []; @@ -150,7 +162,7 @@ export default class DiscworldActorSheet extends DiscworldSheetMixin(ActorSheetV const { traitType } = event.target.closest(".trait-category").dataset; if (!traitType) return; - this.constructor._addTrait.call(this, traitType); + DiscworldActorSheet.#addTrait.call(this, traitType); }); // Make each description direct child element rollable. @@ -227,7 +239,7 @@ export default class DiscworldActorSheet extends DiscworldSheetMixin(ActorSheetV switch (actionType) { case "add": { const { traitType } = target.closest(".trait-category").dataset; - this.constructor._addTrait.call(this, traitType); + DiscworldActorSheet.#addTrait.call(this, traitType); break; } case "edit": @@ -248,14 +260,13 @@ export default class DiscworldActorSheet extends DiscworldSheetMixin(ActorSheetV * Add a new trait of the given type to the character. * @this DiscworldActorSheet * @param {string} traitType The type of trait to add. Must be one of the {@link DISCWORLD.traitTypes} constants. - * @param {object} extraData Additional creation data that a module may provide. E.g., for new datapoints. */ - static async _addTrait(traitType, extraData = {}) { + static async #addTrait(traitType, extraData = {}) { const createData = foundry.utils.mergeObject( { name: _loc("DOCUMENT.New", { type: _loc(`DISCWORLD.trait.type.${traitType}`) }), type: "trait", - system: { type: traitType }, + system: { type: traitType, actorType: this.actorBaseType }, }, extraData, ); diff --git a/modules/applications/sheets/trait-sheet.mjs b/modules/applications/sheets/trait-sheet.mjs index 2ec0016..af58f4c 100644 --- a/modules/applications/sheets/trait-sheet.mjs +++ b/modules/applications/sheets/trait-sheet.mjs @@ -31,34 +31,43 @@ export default class TraitSheet extends DiscworldSheetMixin(ItemSheetV2) { /** @inheritdoc */ async _prepareContext(options) { const context = await super._prepareContext(options); + const { document } = this; + const { system } = this.document; context.fields = { name: { - field: this.document.schema.getField("name"), + field: document.schema.getField("name"), value: this.isEditMode - ? this.document._source.name - : this.document.name, + ? document._source.name + : document.name, + }, + actorType: { + field: system.schema.getField("actorType"), + value: this.isEditMode + ? system._source.actorType + : system.actorType, }, type: { - field: this.document.system.schema.getField("type"), + field: system.schema.getField("type"), value: this.isEditMode - ? this.document.system._source.type - : this.document.system.type, + ? system._source.type + : system.type, }, severity: { - field: this.document.system.schema.getField("severity"), + field: system.schema.getField("severity"), value: this.isEditMode - ? this.document.system._source.severity - : this.document.system.severity, + ? system._source.severity + : system.severity, }, notes: { - field: this.document.system.schema.getField("notes"), + field: system.schema.getField("notes"), value: this.isEditMode - ? this.document.system._source.notes - : this.document.system.notes, + ? system._source.notes + : system.notes, }, }; + context.fields.actorType.show = !document.isOwned && (Object.keys(DISCWORLD.actorTypes).length > 1); context.fields.severity.show = context.fields.type.value === "consequences"; context.fields.notes.enriched = await CONFIG.ux.TextEditor.enrichHTML( context.fields.notes.value, @@ -70,6 +79,30 @@ export default class TraitSheet extends DiscworldSheetMixin(ItemSheetV2) { /* -------------------------------------------------- */ + /** @inheritdoc */ + async _onRender(context, options) { + await super._onRender(context, options); + + const { system } = this.document; + + // Sort and filter