From d226ca52a1c41dfa3e457a7883524dd18dc7e2c5 Mon Sep 17 00:00:00 2001 From: aMediocreDad Date: Sun, 21 Jul 2024 09:16:17 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Adventure=20Site=20creati?= =?UTF-8?q?on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lang/en.json | 4 + src/forbidden-lands.scss | 2 +- src/forbidden-lands.ts | 3 - .../adventure-site-generator.js | 54 +++++++++ .../adventure-sites/adventure-site-sheet.js | 37 ------ .../styles/_adventure-sites.scss | 19 ++-- src/journal/journal-document.js | 80 ------------- src/journal/styles/_journal.scss | 13 +-- src/legacy-styles/system/_main.scss | 60 +++++++--- src/legacy-styles/system/_root.scss | 5 +- src/system/core/hooks.js | 51 +++++++++ src/system/core/sheets.js | 2 - src/system/core/styles/variables.scss | 5 +- .../adventure-sites/adventure-site-sheet.hbs | 106 ------------------ 14 files changed, 175 insertions(+), 266 deletions(-) delete mode 100644 src/journal/adventure-sites/adventure-site-sheet.js delete mode 100644 src/journal/journal-document.js delete mode 100644 templates/journal/adventure-sites/adventure-site-sheet.hbs diff --git a/lang/en.json b/lang/en.json index 3e7a111b..ee4b49a8 100644 --- a/lang/en.json +++ b/lang/en.json @@ -17,6 +17,10 @@ "ACTOR.TypeMonster": "Monster", "ACTOR.TypeParty": "Party", "ACTOR.TypeStronghold": "Stronghold", + "ADVENTURE_SITE.ADD_ROOM": "Add Room", + "ADVENTURE_SITE.CREATE_TITLE": "Create a new Adventure Site", + "ADVENTURE_SITE.CREATE_DESCRIPTION": "Choose what type of site you want to create.", + "ADVENTURE_SITE.LABEL": "Adventure Site", "ARMOR.BODY": "Body", "ARMOR.HELMET": "Helmet", "ARMOR.OTHER": "Other", diff --git a/src/forbidden-lands.scss b/src/forbidden-lands.scss index 1afe5600..a6dce5c3 100644 --- a/src/forbidden-lands.scss +++ b/src/forbidden-lands.scss @@ -5,4 +5,4 @@ @import "system"; @import "changelog"; -@import "journal"; +@import "journal"; \ No newline at end of file diff --git a/src/forbidden-lands.ts b/src/forbidden-lands.ts index e46ef8c8..dd617eee 100644 --- a/src/forbidden-lands.ts +++ b/src/forbidden-lands.ts @@ -11,7 +11,6 @@ import { init, utilities, } from "@journal/adventure-sites/adventure-site-generator.js"; -import { ForbiddenLandsJournalEntry } from "@journal/journal-document.js"; import FBL, { modifyConfig } from "@system/core/config.js"; import { initializeEditorEnrichers } from "@system/core/editor.js"; import { registerFonts } from "@system/core/fonts.js"; @@ -47,8 +46,6 @@ Hooks.once("init", () => { CONFIG.Actor.documentClass = ForbiddenLandsActor; CONFIG.Item.documentClass = ForbiddenLandsItem; - // @ts-expect-error - PF2 types Internal Type Error - CONFIG.JournalEntry.documentClass = ForbiddenLandsJournalEntry; CONFIG.statusEffects = [ ...CONFIG.statusEffects.filter( (effect) => !["sleep", "frozen", "curse"].includes(effect.id), diff --git a/src/journal/adventure-sites/adventure-site-generator.js b/src/journal/adventure-sites/adventure-site-generator.js index 573db634..51802426 100644 --- a/src/journal/adventure-sites/adventure-site-generator.js +++ b/src/journal/adventure-sites/adventure-site-generator.js @@ -1,3 +1,5 @@ +import t from "$utils/localize-string"; + let ALL_TABLES = {}; // Utilities @@ -185,6 +187,58 @@ const moldData = (data, type) => { return typeFn(data, ALL_TABLES); }; +export const adventureSiteCreateDialog = async () => { + const titleCase = (string) => + string.replace(/_/g, " ").replace(/\b\w/g, (char) => char.toUpperCase()); + + const types = Object.entries(CONFIG.fbl.adventureSites.types); + + const type = await Dialog.wait({ + title: t("ADVENTURE_SITE.CREATE_TITLE"), + content: `
+

${t("ADVENTURE_SITE.CREATE_DESCRIPTION")}

+
+
+ + +
+
+
`, + buttons: { + ok: { + icon: '', + label: `${t("Create")}`, + callback: (jqhtml) => jqhtml.find("form")[0].type.value, + }, + }, + }); + + const [path, adventureSite] = type.split(":"); + + const content = await CONFIG.fbl.adventureSites.generate(path, adventureSite); + + const entry = await JournalEntry.create({ + name: `${t("ADVENTURE_SITE.LABEL")}: ${titleCase(adventureSite)}`, + pages: [ + { + name: titleCase(adventureSite), + text: { content: `
${content}
` }, + title: { show: false }, + }, + ], + flags: { + "forbidden-lands": { + adventureSiteType: adventureSite, + }, + }, + }); + entry.sheet.render(true); +}; + // Initialize random generation export const init = async (path, adventureSite) => { const registeredSites = Object.keys(CONFIG.fbl.adventureSites.types); diff --git a/src/journal/adventure-sites/adventure-site-sheet.js b/src/journal/adventure-sites/adventure-site-sheet.js deleted file mode 100644 index 4a65934a..00000000 --- a/src/journal/adventure-sites/adventure-site-sheet.js +++ /dev/null @@ -1,37 +0,0 @@ -export class AdventureSitesSheet extends JournalSheet { - get template() { - return "systems/forbidden-lands/templates/journal/adventure-sites/adventure-site-sheet.hbs"; - } - - getData(options) { - const data = super.getData(options); - data.type = this.object.type; - return data; - } - - activateListeners(html) { - super.activateListeners(html); - - html.find('[data-action="add-room"]').on("click", async () => { - const type = this.object.type; - const path = CONFIG.fbl.adventureSites.types[type]; - const room = await CONFIG.fbl.adventureSites?.generate( - path, - `${type}_rooms`, - ); - const pageName = $(room) - .find("h4, strong") - ?.first() - .text() - .replace(/[^\p{L}]+/u, " ") - .trim(); - await this.object.createEmbeddedDocuments("JournalEntryPage", [ - { - name: pageName, - title: { level: 2, show: false }, - text: { content: room }, - }, - ]); - }); - } -} diff --git a/src/journal/adventure-sites/styles/_adventure-sites.scss b/src/journal/adventure-sites/styles/_adventure-sites.scss index 0c062c84..27456d67 100644 --- a/src/journal/adventure-sites/styles/_adventure-sites.scss +++ b/src/journal/adventure-sites/styles/_adventure-sites.scss @@ -1,13 +1,11 @@ /* - Journal Sheet Styles - */ +.app .journal-sheet-container { -.app .journal-sheet-container.adventure-site { // Form content - .journal-entry-page.text { - & > * { + .journal-entry-page.text .adventure-site { + &>* { margin-inline: auto; } @@ -35,7 +33,7 @@ font-weight: 600; } - p + p { + p+p { text-indent: 0; } @@ -61,7 +59,7 @@ background-color: #f0f0f0; } - & > .index-tip { + &>.index-tip { font-family: Branding, Ubuntu, sans-serif; position: absolute; top: 0; @@ -77,6 +75,7 @@ } } } + .editable-tools { position: absolute; left: 50%; @@ -89,7 +88,7 @@ gap: 4rem; // Buttons - & > * { + &>* { display: block; margin: 0; min-width: 14rem; @@ -105,7 +104,7 @@ } &:hover { - & > * { + &>* { opacity: 1; &:hover { @@ -115,4 +114,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/journal/journal-document.js b/src/journal/journal-document.js deleted file mode 100644 index 862f3027..00000000 --- a/src/journal/journal-document.js +++ /dev/null @@ -1,80 +0,0 @@ -export class ForbiddenLandsJournalEntry extends JournalEntry { - static async create(data, options) { - if (!data.type || data.type === "base") return super.create(data, options); - data.flags = { - "forbidden-lands": { type: data.type }, - }; - const path = CONFIG.fbl.adventureSites?.types[data.type]; - const content = await CONFIG.fbl.adventureSites?.generate(path, data.type); - data.pages = [ - { name: "Overview", title: { show: false }, text: { content } }, - ]; - return super.create(data, options); - } - - get type() { - const type = this.getFlag("forbidden-lands", "type"); - if (type) return type; - return CONST.BASE_DOCUMENT_TYPE; - } - - // Lifted straight out of Foundry because in V11 it removes the base type from the list of types - static async createDialog( - data = {}, - { parentFolder = null, pack = null, ...options } = {}, - ) { - // Collect data - const documentName = this.metadata.name; - const types = game.documentTypes[documentName]; - let folders = []; - if (!parentFolder) { - if (pack) folders = game.packs.get(pack).folders.contents; - else - folders = game.folders.filter( - (f) => f.type === documentName && f.displayed, - ); - } - const label = game.i18n.localize(this.metadata.label); - const title = game.i18n.format("DOCUMENT.Create", { type: label }); - - // Render the document creation form - const html = await renderTemplate( - "templates/sidebar/document-create.html", - { - folders, - name: data.name || game.i18n.format("DOCUMENT.New", { type: label }), - folder: data.folder, - hasFolders: folders.length >= 1, - type: data.type || CONFIG[documentName]?.defaultType || types[0], - types: types.reduce((obj, t) => { - const typeLabel = CONFIG[documentName]?.typeLabels?.[t] ?? t; - obj[t] = game.i18n.has(typeLabel) ? game.i18n.localize(typeLabel) : t; - return obj; - }, {}), - hasTypes: types.length > 1, - }, - ); - - // Render the confirmation dialog window - return Dialog.prompt({ - title: title, - content: html, - label: title, - callback: (JQhtml) => { - const form = JQhtml[0].querySelector("form"); - const fd = new FormDataExtended(form); - foundry.utils.mergeObject(data, fd.object, { inplace: true }); - if (!data.folder) data.folder = undefined; - if (types.length === 1) data.type = types[0]; - if (!data.name?.trim()) data.name = this.defaultName(); - return this.create(data, { - parent: parentFolder, - pack, - renderSheet: true, - }); - }, - rejectClose: false, - options, - }); - } -} diff --git a/src/journal/styles/_journal.scss b/src/journal/styles/_journal.scss index d3394679..2ddae82c 100644 --- a/src/journal/styles/_journal.scss +++ b/src/journal/styles/_journal.scss @@ -20,14 +20,6 @@ background-color: #eeed; } } - - .pages-list .directory-item.active { - background-color: var(--color-theme-constrast); - - .page-heading { - font-weight: 600; - } - } } // Force proper height @@ -121,6 +113,7 @@ // Page header .journal-page-header { + h1, h2, h3 { @@ -144,7 +137,7 @@ } // Page Content -:where(.journal-page-content,.editor-content) { +:where(.journal-page-content, .editor-content) { font-family: var(--font-editor); line-height: 1.75; font-size: var(--font-size-16); @@ -191,4 +184,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/legacy-styles/system/_main.scss b/src/legacy-styles/system/_main.scss index 2c698963..f1b4edf5 100644 --- a/src/legacy-styles/system/_main.scss +++ b/src/legacy-styles/system/_main.scss @@ -1,7 +1,7 @@ @use "../utils"; .forbidden-lands { - &.window-app .window-content > * { + &.window-app .window-content>* { height: 100%; } @@ -40,7 +40,7 @@ font-weight: 600; - & ~ * { + &~* { display: none; } @@ -171,6 +171,7 @@ } } } + button:focus, button:hover { background: var(--color-highlight); @@ -190,6 +191,7 @@ height: auto; width: 100%; } + input:disabled, select:disabled, textarea:disabled { @@ -208,11 +210,13 @@ appearance: textfield; text-align: center; } + input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } + input[type="number"]:focus, input[type="text"]:focus, select:focus, @@ -299,8 +303,11 @@ } /* Scrollbars */ -.app { +.app, +.application { background: #292929f0; + + &.dialog, &.window-app { color: var(--color-theme-text); border: 2px solid transparent; @@ -309,20 +316,36 @@ padding: 0 4px 4px; margin: 0; background-color: var(--color-theme-background); + + h1 { + color: var(--color-theme-text) + } + + .window-header { + background: none; + + button.header-control { + color: var(--color-theme-text) + } + } + .journal-sheet { min-width: 500px; min-height: 300px; } + &.sheet { &.journal-sheet { min-height: 260px; min-width: 560px; } + &.forbidden-lands { &.actor { ::-webkit-scrollbar { width: 6px; } + ::-webkit-scrollbar-thumb { background: var(--color-theme-gray-200); border: 0 none; @@ -331,12 +354,11 @@ .bio { padding: 4px 8px; + .avatar { - background: radial-gradient( - closest-side, - var(--color-highlight) 0%, - var(--color-background) 100% - ); + background: radial-gradient(closest-side, + var(--color-highlight) 0%, + var(--color-background) 100%); flex: 0 0 auto; height: 95px; width: 95px; @@ -344,10 +366,11 @@ &:hover { cursor: pointer; - & > img { + &>img { filter: drop-shadow(0 0 5px #a00404); } } + img { place-self: center; border: none; @@ -362,6 +385,7 @@ } } } + &.sidebar-popout { .window-content { width: 96%; @@ -369,30 +393,36 @@ color: #222; margin-bottom: 10px; } + .subdirectory { border-color: #555; + li { &.folder { - & > .folder-header { + &>.folder-header { background: rgba(0, 0, 0, 0.2); color: #222; } } } } + li { &.folder { - & > .folder-header { + &>.folder-header { background: rgba(255, 255, 255, 0.9); color: #222; + h3 { color: #222; } + .create-entity { color: #444; } } } + &.directory-item { &.entity { background: rgba(0, 0, 0, 0.5); @@ -400,8 +430,9 @@ } } } + .folder { - & > .folder-header { + &>.folder-header { .create-folder { color: #444; } @@ -432,6 +463,7 @@ cursor: pointer; text-shadow: 0 0 8px #a00404; } + .tab-item { position: relative; flex: 0; @@ -447,6 +479,7 @@ &:hover { text-shadow: 0 0 6px #fff; } + &.active { filter: drop-shadow(0 0 2px #999); color: #fff; @@ -474,6 +507,7 @@ .broken .far.fa-check-circle { color: #a00404; } + .broken .change-willpower .far.fa-circle { color: #333; } @@ -530,4 +564,4 @@ text-align: left; padding-left: 8px; } -} +} \ No newline at end of file diff --git a/src/legacy-styles/system/_root.scss b/src/legacy-styles/system/_root.scss index 68803f25..793cc7e1 100644 --- a/src/legacy-styles/system/_root.scss +++ b/src/legacy-styles/system/_root.scss @@ -6,14 +6,15 @@ --color-border: #939598; --color-shadow-primary: #005d67; --color-shadow-highlight: #36b5a7; - --color-border-highlight: #36b5a7; + --color-border-highlight: #005d67; --color-border-highlight-alt: #005d67; --color-border-light-tertiary: #ffb994; --color-border-dark-tertiary: #433a3f; + --color-light-1: var(--color-background); --font-editor: "IM Fell Great Primer", serif; --font-special: "IM Fell DW Pica", serif; --font-subheader: "IM Fell DW Pica SC", serif; --font-input: Branding, Author, MavenPro, Ubuntu, sans-serif; --font-primary: Branding, Author, MavenPro, Ubuntu, sans-serif; --font-table: Branding, Author, MavenPro, Ubuntu, sans-serif; -} +} \ No newline at end of file diff --git a/src/system/core/hooks.js b/src/system/core/hooks.js index 0fcab2b5..40755f66 100644 --- a/src/system/core/hooks.js +++ b/src/system/core/hooks.js @@ -1,7 +1,9 @@ import { Changelog } from "$changelog/changelog.js"; import { handleHotbarDrop } from "@components/macros/macros.js"; import { FBLRollHandler } from "@components/roll-engine/engine.js"; +import { adventureSiteCreateDialog } from "@journal/adventure-sites/adventure-site-generator.js"; import { registerDiceSoNice } from "../../external-api/dice-so-nice.js"; +import t from "$utils/localize-string.js"; /** * Registers all hooks that are not 'init' or 'ready' @@ -254,4 +256,53 @@ export default function registerHooks() { new Changelog().render(true); }); }); + + Hooks.on("changeSidebarTab", (app) => { + if ( + app.tabName !== "journal" || + !Object.keys(CONFIG.fbl.adventureSites.types).length + ) + return; + const adventureSiteButton = $( + ``, + ); + adventureSiteButton.on("click", () => { + adventureSiteCreateDialog(); + }); + + app.element.find(".header-actions").append(adventureSiteButton); + }); } + +Hooks.on("renderJournalSheet", (app, html) => { + const type = app.object.getFlag("forbidden-lands", "adventureSiteType"); + const isDungeon = ["dungeon", "ice_cave", "elven_ruin"].includes(type); + if (!isDungeon) return; + + const button = $( + ``, + ); + + button.on("click", async () => { + const path = CONFIG.fbl.adventureSites.types[type]; + const room = await CONFIG.fbl.adventureSites?.generate( + path, + `${type}_rooms`, + ); + const pageName = $(room) + .find("h4, strong") + ?.first() + .text() + .replace(/[^\p{L}]+/u, " ") + .trim(); + await app.object.createEmbeddedDocuments("JournalEntryPage", [ + { + name: pageName, + title: { level: 2, show: false }, + text: { content: `
${room}
` }, + }, + ]); + }); + + html.find('[data-action="createPage"]').after(button); +}); diff --git a/src/system/core/sheets.js b/src/system/core/sheets.js index 3a69592f..ae707ab1 100644 --- a/src/system/core/sheets.js +++ b/src/system/core/sheets.js @@ -12,7 +12,6 @@ import { ForbiddenLandsCriticalInjurySheet } from "@item/critical-injury/critica import { ForbiddenLandsMonsterAttackSheet } from "@item/monster-attack/monster-attack-sheet.js"; import { ForbiddenLandsBuildingSheet } from "@item/building/building-sheet.js"; import { ForbiddenLandsHirelingSheet } from "@item/hireling/hireling-sheet.js"; -import { AdventureSitesSheet } from "@journal/adventure-sites/adventure-site-sheet.js"; export function registerSheets() { Actors.unregisterSheet("core", ActorSheet); @@ -73,5 +72,4 @@ export function registerSheets() { types: ["hireling"], makeDefault: true, }); - CONFIG.fbl.adventureSites.sheetClass = AdventureSitesSheet; } diff --git a/src/system/core/styles/variables.scss b/src/system/core/styles/variables.scss index 71679995..68392a6a 100644 --- a/src/system/core/styles/variables.scss +++ b/src/system/core/styles/variables.scss @@ -1,4 +1,4 @@ -:root { +body { // Theme Colors --color-theme-text: #222020; --color-theme-background: #fff; @@ -24,6 +24,7 @@ --color-text-dark-header: #23221d; --color-text-dark-inactive: #7a7971; --color-text-hyperlink: var(--color-theme-accent); + --color-light-1: var(--color-theme-background); --color-text-light-0: #fff; --color-text-light-1: #eee; --color-text-light-2: #ddd; @@ -59,7 +60,7 @@ --color-border-dark-primary: var(--color-theme-text); --color-border-dark-secondary: #23221d; --color-border-dark-tertiary: #4b4a44; - --color-border-highlight: var(--color-theme-alt-600); + --color-border-highlight: var(--color-theme-alt-800); --color-border-highlight-alt: var(--color-theme-alt-600); --color-bg-btn-minor-inactive: #c9c7b8; --color-bg-btn-minor-active: #b5b3a4; diff --git a/templates/journal/adventure-sites/adventure-site-sheet.hbs b/templates/journal/adventure-sites/adventure-site-sheet.hbs deleted file mode 100644 index 882aa410..00000000 --- a/templates/journal/adventure-sites/adventure-site-sheet.hbs +++ /dev/null @@ -1,106 +0,0 @@ -
- - {{! Sidebar Container }} - - - {{! Main Content }} -
-
- -
- -
-
- {{#each pages as |page|}} -
- {{#if page.editable}} -
- -
- {{/if}} -
- {{/each}} -
-
-
-