diff --git a/.changeset/clean-peas-exercise.md b/.changeset/clean-peas-exercise.md
new file mode 100644
index 00000000..079e09b9
--- /dev/null
+++ b/.changeset/clean-peas-exercise.md
@@ -0,0 +1,5 @@
+---
+"forbidden-lands": patch
+---
+
+Fixes the Adventure Site creation mechanisms. Adventure Sites can now be created by using a button in the Journal Sidebar Tab
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: `
`,
+ 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 }}
-
-