diff --git a/dnd5e.mjs b/dnd5e.mjs index b51d0f999e..5d24495b3a 100644 --- a/dnd5e.mjs +++ b/dnd5e.mjs @@ -114,10 +114,19 @@ Hooks.once("init", function() { makeDefault: true, label: "DND5E.SheetClassItem" }); + + DocumentSheetConfig.unregisterSheet(JournalEntry, "core", JournalSheet); + DocumentSheetConfig.registerSheet(JournalEntry, "dnd5e", applications.journal.JournalSheet5e, { + label: "DND5E.SheetClassJournalEntry" + }); DocumentSheetConfig.registerSheet(JournalEntryPage, "dnd5e", applications.journal.JournalClassPageSheet, { label: "DND5E.SheetClassClassSummary", types: ["class"] }); + DocumentSheetConfig.registerSheet(JournalEntryPage, "dnd5e", applications.journal.JournalMapLocationPageSheet, { + label: "DND5E.SheetClassMapLocation", + types: ["map"] + }); // Preload Handlebars helpers & partials utils.registerHandlebarsHelpers(); diff --git a/lang/en.json b/lang/en.json index 0bf27e2696..001f5f45fb 100644 --- a/lang/en.json +++ b/lang/en.json @@ -989,10 +989,12 @@ "DND5E.SenseSpecial": "Special Senses", "DND5E.SheetClassCharacter": "Default 5e Character Sheet", "DND5E.SheetClassClassSummary": "Default 5e Class Summary Sheet", +"DND5E.SheetClassMapLocation": "Default 5e Map Location Sheet", "DND5E.SheetClassNPC": "Default 5e NPC Sheet", "DND5E.SheetClassVehicle": "Default 5e Vehicle Sheet", "DND5E.SheetClassGroup": "Default 5e Group Sheet", "DND5E.SheetClassItem": "Default 5e Item Sheet", +"DND5E.SheetClassJournalEntry": "Default 5e Journal Entry Sheet", "DND5E.SavingThrow": "Saving Throw", "DND5E.SaveDC": "DC {dc} {ability}", "DND5E.SavePromptTitle": "{ability} Saving Throw", @@ -1317,6 +1319,7 @@ "JOURNALENTRYPAGE.TypeClass": "Class Summary", "TYPES.JournalEntryPage.class": "Class Summary", +"TYPES.JournalEntryPage.map": "Map Location", "JOURNALENTRYPAGE.DND5E.Class.AdditionalEquipment": "Equipment", "JOURNALENTRYPAGE.DND5E.Class.AdditionalEquipmentHint": "List of equipment granted by this class if taken at first level.", "JOURNALENTRYPAGE.DND5E.Class.AdditionalHitPoints": "Additional Hit Points Description", diff --git a/less/journal.less b/less/journal.less index 87055bf9f2..7426d9ec31 100644 --- a/less/journal.less +++ b/less/journal.less @@ -148,3 +148,24 @@ } } } + +.journal-entry-page.map { + .journal-header { + gap: 1rem; + + [name="system.code"] { + block-size: 100%; + inline-size: 3em; + background: rgb(0 0 0 / 0.1); + font-size: var(--font-size-24); + text-align: center; + } + + .page-level { + margin-inline-start: 0; + } + } + [data-map-location-code]::before { + content: attr(data-map-location-code) ': '; + } +} diff --git a/module/applications/journal/_module.mjs b/module/applications/journal/_module.mjs index 0919ca0d64..045cc59090 100644 --- a/module/applications/journal/_module.mjs +++ b/module/applications/journal/_module.mjs @@ -1,3 +1,5 @@ -export {default as JournalClassPageSheet} from "./class-sheet.mjs"; +export {default as JournalClassPageSheet} from "./class-page-sheet.mjs"; export {default as JournalEditor} from "./journal-editor.mjs"; +export {default as JournalMapLocationPageSheet} from "./map-page-sheet.mjs"; +export {default as JournalSheet5e} from "./journal-sheet.mjs"; export {default as SRDCompendium} from "./srd-compendium.mjs"; diff --git a/module/applications/journal/class-sheet.mjs b/module/applications/journal/class-page-sheet.mjs similarity index 100% rename from module/applications/journal/class-sheet.mjs rename to module/applications/journal/class-page-sheet.mjs diff --git a/module/applications/journal/journal-sheet.mjs b/module/applications/journal/journal-sheet.mjs new file mode 100644 index 0000000000..7b9c63e8b8 --- /dev/null +++ b/module/applications/journal/journal-sheet.mjs @@ -0,0 +1,24 @@ +/** + * Variant of the standard journal sheet to handle custom TOC numbering. + */ +export default class JournalSheet5e extends JournalSheet { + /** @inheritdoc */ + _getPageData() { + const pageData = super._getPageData(); + + let adjustment = 0; + for ( const page of pageData ) { + const pageDocument = this.document.pages.get(page._id); + let needsAdjustment = true; + const numbering = pageDocument.system.adjustTOCNumbering?.(page.number); + if ( numbering ) { + page.number = numbering.number; + adjustment += numbering.adjustment ?? 0; + needsAdjustment = false; + } + if ( needsAdjustment ) page.number += adjustment; + } + + return pageData; + } +} diff --git a/module/applications/journal/map-page-sheet.mjs b/module/applications/journal/map-page-sheet.mjs new file mode 100644 index 0000000000..ae79dcb3ea --- /dev/null +++ b/module/applications/journal/map-page-sheet.mjs @@ -0,0 +1,42 @@ +/** + * Journal entry page that displays a controls for editing map markers. + */ +export default class JournalMapLocationPageSheet extends JournalTextPageSheet { + + /** @inheritdoc */ + static get defaultOptions() { + const options = super.defaultOptions; + options.classes.push("map"); + return options; + } + + /* -------------------------------------------- */ + + /** @inheritdoc */ + get template() { + return `templates/journal/page-text-${this.isEditable ? "edit" : "view"}.html`; + } + + /* -------------------------------------------- */ + + /** @inheritdoc */ + async _renderInner(...args) { + const jQuery = await super._renderInner(...args); + const editingHeader = jQuery[0].querySelector(".journal-header"); + const viewingHeader = jQuery[0].querySelector(":is(h1, h2, h3)"); + + if ( editingHeader ) { + const input = document.createElement("input"); + input.name = "system.code"; + input.type = "text"; + input.value = this.document.system.code ?? ""; + editingHeader.insertAdjacentElement("afterbegin", input); + } + + else if ( viewingHeader && this.document.system.code ) { + viewingHeader.dataset.mapLocationCode = this.document.system.code; + } + + return jQuery; + } +} diff --git a/module/data/journal/_module.mjs b/module/data/journal/_module.mjs index e94373caa6..9f592db9fb 100644 --- a/module/data/journal/_module.mjs +++ b/module/data/journal/_module.mjs @@ -1,9 +1,12 @@ import ClassJournalPageData from "./class.mjs"; +import MapLocationJournalPageData from "./map.mjs"; export { - ClassJournalPageData + ClassJournalPageData, + MapLocationJournalPageData }; export const config = { - class: ClassJournalPageData + class: ClassJournalPageData, + map: MapLocationJournalPageData }; diff --git a/module/data/journal/map.mjs b/module/data/journal/map.mjs new file mode 100644 index 0000000000..eb122b37bd --- /dev/null +++ b/module/data/journal/map.mjs @@ -0,0 +1,24 @@ +/** + * Data definition for Map Location journal entry pages. + * + * @property {string} code Code for the location marker on the map. + */ +export default class MapLocationJournalPageData extends foundry.abstract.DataModel { + static defineSchema() { + return { + code: new foundry.data.fields.StringField() + }; + } + + /* -------------------------------------------- */ + + /** + * Adjust the number of this entry in the table of contents. + * @param {number} number Current position number. + * @returns {{ number: string, adjustment: number }|void} + */ + adjustTOCNumbering(number) { + if ( !this.code ) return; + return { number: this.code, adjustment: -1 }; + } +} diff --git a/template.json b/template.json index 0d4ffd9f21..6826d861e1 100644 --- a/template.json +++ b/template.json @@ -716,7 +716,7 @@ } }, "JournalEntryPage": { - "types": ["class"], + "types": ["class", "map"], "htmlFields": ["description.value", "description.additionalHitPoints", "description.additionalTraits", "description.additionalEquipment", "description.subclass"], "class": { "item": "",