Fix some styling & layout things and use events instead of imports
- No component should import SharkGame except App.svelte, except *as a type* - use props instead - Add events for Log - Make tab not use name but the actual tab instead
This commit is contained in:
parent
1ff92d152d
commit
416585e0da
13 changed files with 170 additions and 86 deletions
|
@ -7,6 +7,6 @@
|
||||||
SharkGame.init();
|
SharkGame.init();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Header />
|
<Header title={SharkGame.title} />
|
||||||
<Wrapper />
|
<Wrapper game={SharkGame} />
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|
|
@ -7,13 +7,8 @@
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
footer {
|
footer {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
pointer-events: none;
|
|
||||||
font-size: 80%;
|
font-size: 80%;
|
||||||
color: var(--color-lighter);
|
color: var(--color-lighter);
|
||||||
filter: brightness(130%);
|
filter: brightness(130%);
|
||||||
|
|
||||||
> a {
|
|
||||||
pointer-events: initial;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
<script lang="ts">
|
|
||||||
import { SharkGame } from "../shark/SharkGame";
|
|
||||||
import type { Tabs } from "../shark/Tabs";
|
|
||||||
|
|
||||||
export let currentTab: typeof Tabs.currentTab;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<svelte:component this={SharkGame.Tabs.Tabs[currentTab]} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
div {
|
|
||||||
height: calc(100% - 2em);
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { SharkGame } from "../shark/SharkGame";
|
export let title: string;
|
||||||
|
|
||||||
const discordLink = "https://discord.gg/eYqApFkFPY";
|
const discordLink = "https://discord.gg/eYqApFkFPY";
|
||||||
|
|
||||||
|
@ -38,16 +38,16 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
<title>{SharkGame.title}</title>
|
<title>{title}</title>
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<header>
|
<header id="header">
|
||||||
<ul id="main-header-buttons">
|
<ul id="main-header-buttons">
|
||||||
{#each Object.entries(mainHeaderButtons) as [name, onClick]}
|
{#each Object.entries(mainHeaderButtons) as [name, onClick]}
|
||||||
<li><a on:click={onClick} href={"javascript:;"}>{name}</a></li>
|
<li><a on:click={onClick} href={"javascript:;"}>{name}</a></li>
|
||||||
{/each}
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
<span>{SharkGame.title}</span>
|
<span>{title}</span>
|
||||||
<ul id="other-header-buttons">
|
<ul id="other-header-buttons">
|
||||||
{#each Object.entries(otherHeaderButtons) as [name, onClick]}
|
{#each Object.entries(otherHeaderButtons) as [name, onClick]}
|
||||||
<li>
|
<li>
|
||||||
|
@ -78,11 +78,6 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
|
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
|
||||||
> span {
|
> span {
|
||||||
|
@ -104,15 +99,6 @@
|
||||||
&:not(:first-child):before {
|
&:not(:first-child):before {
|
||||||
content: " | ";
|
content: " | ";
|
||||||
}
|
}
|
||||||
|
|
||||||
> a:link,
|
|
||||||
> a:visited {
|
|
||||||
color: var(--color-lighter);
|
|
||||||
filter: none;
|
|
||||||
}
|
|
||||||
> a:hover {
|
|
||||||
filter: brightness(130%);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&#main-header-buttons {
|
&#main-header-buttons {
|
||||||
|
|
|
@ -1,21 +1,34 @@
|
||||||
<svelte:options immutable />
|
<svelte:options immutable />
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { createEventDispatcher } from "svelte";
|
||||||
import { expoOut } from "svelte/easing";
|
import { expoOut } from "svelte/easing";
|
||||||
import type { Writable } from "svelte/store";
|
import type { Writable } from "svelte/store";
|
||||||
import { slide } from "svelte/transition";
|
import { slide } from "svelte/transition";
|
||||||
|
|
||||||
import { Message, MessageType } from "../shark/Message";
|
import type {
|
||||||
import { SharkGame } from "../shark/SharkGame";
|
AddMessageEvent,
|
||||||
|
ResetMessagesEvent,
|
||||||
|
Message,
|
||||||
|
} from "../shark/Message";
|
||||||
|
import { MessageType } from "../shark/Message";
|
||||||
|
|
||||||
export let messages: Writable<Message[]>;
|
export let messages: Writable<Message[]>;
|
||||||
|
export let logLength: number;
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher<{
|
||||||
|
addMessage: AddMessageEvent;
|
||||||
|
resetLog: ResetMessagesEvent;
|
||||||
|
}>();
|
||||||
|
|
||||||
// Shorthand
|
// Shorthand
|
||||||
function addMessage(message: string, messageType?: MessageType) {
|
function addMessage(message: string, messageType?: MessageType) {
|
||||||
SharkGame.Log.addMessage(message, messageType);
|
dispatch("addMessage", { message, messageType });
|
||||||
|
}
|
||||||
|
function resetMessages() {
|
||||||
|
dispatch("resetLog", { reset: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
$: logLength = SharkGame.Settings.logLength.current;
|
|
||||||
$: displayMessages = $messages.slice(-logLength).reverse();
|
$: displayMessages = $messages.slice(-logLength).reverse();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -45,11 +58,7 @@
|
||||||
addMessage("error" + $messages.length, MessageType.error);
|
addMessage("error" + $messages.length, MessageType.error);
|
||||||
}}>Add Error</button
|
}}>Add Error</button
|
||||||
>
|
>
|
||||||
<button
|
<button on:click={resetMessages}>Clear log</button>
|
||||||
on:click={() => {
|
|
||||||
SharkGame.Log.reset();
|
|
||||||
}}>Clear log</button
|
|
||||||
>
|
|
||||||
<ol>
|
<ol>
|
||||||
{#each displayMessages as message, i (message)}
|
{#each displayMessages as message, i (message)}
|
||||||
{#if i < logLength}
|
{#if i < logLength}
|
||||||
|
@ -81,6 +90,7 @@
|
||||||
> li {
|
> li {
|
||||||
padding: 1em 0.4em;
|
padding: 1em 0.4em;
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
|
overflow-anchor: none;
|
||||||
|
|
||||||
&.odd {
|
&.odd {
|
||||||
background-color: var(--color-med);
|
background-color: var(--color-med);
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Tabs } from "../shark/Tabs";
|
import type { Tabs } from "../shark/Tabs";
|
||||||
|
|
||||||
export let tabs: typeof Tabs.Tabs;
|
export let tabs: typeof Tabs.AllTabs;
|
||||||
export let selectedTab: typeof Tabs.currentTab;
|
export let selectedTab: typeof Tabs.currentTab;
|
||||||
$: tabNames = Object.keys(tabs) as typeof selectedTab[];
|
$: tabEntries = Object.entries(tabs);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<ul>
|
<ul>
|
||||||
{#each tabNames as tab}
|
{#each tabEntries as [tabName, tab]}
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
selectedTab = tab;
|
selectedTab = tab;
|
||||||
}}
|
}}
|
||||||
disabled={tab === selectedTab}
|
disabled={tab === selectedTab}
|
||||||
href={"javascript:;"}>{tab}</a
|
href={"javascript:;"}>{tabName}</a
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
{/each}
|
{/each}
|
||||||
|
@ -55,16 +55,11 @@
|
||||||
content: " | ";
|
content: " | ";
|
||||||
}
|
}
|
||||||
|
|
||||||
> a {
|
> a[disabled="false"] {
|
||||||
color: var(--color-lighter);
|
text-decoration: none;
|
||||||
}
|
|
||||||
> a:not([disabled="true"]):hover {
|
|
||||||
filter: brightness(130%);
|
|
||||||
}
|
}
|
||||||
> a[disabled="true"] {
|
> a[disabled="true"] {
|
||||||
pointer-events: none;
|
text-decoration: underline;
|
||||||
text-decoration: none;
|
|
||||||
color: var(--color-light);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,16 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { createEventDispatcher } from "svelte";
|
||||||
|
|
||||||
import type { HomeAction } from "../../shark/data/HomeActions";
|
import type { HomeAction } from "../../shark/data/HomeActions";
|
||||||
import { HomeActions } from "../../shark/data/HomeActions";
|
import { HomeActions } from "../../shark/data/HomeActions";
|
||||||
import { SharkGame } from "../../shark/SharkGame";
|
import { Resources } from "../../shark/data/Resources";
|
||||||
|
import type { AddMessageEvent } from "../../shark/Message";
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher<{ addMessage: AddMessageEvent }>();
|
||||||
|
|
||||||
function homeActionClick(homeAction: HomeAction) {
|
function homeActionClick(homeAction: HomeAction) {
|
||||||
if (homeAction.effect.resource) {
|
if (homeAction.effect.resource) {
|
||||||
const resources = SharkGame.Resources.getResources(
|
const resources = Resources.getResources(
|
||||||
Object.keys(homeAction.effect.resource)
|
Object.keys(homeAction.effect.resource)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -17,11 +22,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (homeAction.outcomes) {
|
if (homeAction.outcomes) {
|
||||||
SharkGame.Log.addMessage(
|
dispatch("addMessage", {
|
||||||
|
message:
|
||||||
homeAction.outcomes[
|
homeAction.outcomes[
|
||||||
Math.floor(Math.random() * homeAction.outcomes.length)
|
Math.floor(Math.random() * homeAction.outcomes.length)
|
||||||
]
|
],
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -37,5 +43,6 @@
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
div {
|
div {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1 +1,56 @@
|
||||||
Haha, Laboratory go <em>BRRRRRRRRRRRRRRR!</em>
|
Haha, Laboratory go <em>BRRRRRRRRRRRRRRR!</em>
|
||||||
|
|
||||||
|
A bunch of empty lines:<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
This is because I wanted to test the scrollability of the content wrapper.
|
||||||
|
<br />
|
||||||
|
More lines:<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
Egg
|
||||||
|
|
|
@ -1,22 +1,43 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { SharkGame } from "../shark/SharkGame";
|
import type { AddMessageEvent } from "../shark/Message";
|
||||||
import Game from "./Game.svelte";
|
|
||||||
|
import type { SharkGame } from "../shark/SharkGame";
|
||||||
import Log from "./Log.svelte";
|
import Log from "./Log.svelte";
|
||||||
import ResourceTable from "./ResourceTable/ResourceTable.svelte";
|
import ResourceTable from "./ResourceTable/ResourceTable.svelte";
|
||||||
import TabSelector from "./TabSelector.svelte";
|
import TabSelector from "./TabSelector.svelte";
|
||||||
|
|
||||||
|
export let game: typeof SharkGame;
|
||||||
|
$: Game = game;
|
||||||
|
|
||||||
|
function handleAddMessage(event: CustomEvent<AddMessageEvent>) {
|
||||||
|
Game.Log.addMessage(event.detail.message, event.detail.messageType);
|
||||||
|
}
|
||||||
|
function handleResetLog() {
|
||||||
|
Game.Log.reset();
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<div id="left-column">
|
<div id="left-column">
|
||||||
<ResourceTable bind:resources={SharkGame.Resources.Resources} />
|
<ResourceTable bind:resources={Game.Resources.Resources} />
|
||||||
<Log bind:messages={SharkGame.Log.messages} />
|
<Log
|
||||||
|
bind:logLength={Game.Settings.logLength.current}
|
||||||
|
bind:messages={Game.Log.messages}
|
||||||
|
on:addMessage={handleAddMessage}
|
||||||
|
on:resetLog={handleResetLog}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div id="right-column">
|
<div id="right-column">
|
||||||
<TabSelector
|
<TabSelector
|
||||||
bind:tabs={SharkGame.Tabs.Tabs}
|
bind:tabs={Game.Tabs.AllTabs}
|
||||||
bind:selectedTab={SharkGame.Tabs.currentTab}
|
bind:selectedTab={Game.Tabs.currentTab}
|
||||||
/>
|
/>
|
||||||
<Game bind:currentTab={SharkGame.Tabs.currentTab} />
|
<div id="tab-content">
|
||||||
|
<svelte:component
|
||||||
|
this={Game.Tabs.currentTab}
|
||||||
|
on:addMessage={handleAddMessage}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
@ -26,12 +47,12 @@
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
||||||
background-color: var(--color-dark);
|
background-color: var(--color-dark);
|
||||||
margin: 2em 0 0 0;
|
|
||||||
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
height: 100%;
|
// Subtract footer and header size
|
||||||
|
height: calc(100% - 2em - 3em);
|
||||||
|
|
||||||
overflow-y: scroll;
|
overflow-y: hidden;
|
||||||
|
|
||||||
> #left-column {
|
> #left-column {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -41,8 +62,18 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
> #right-column {
|
> #right-column {
|
||||||
|
height: 100%;
|
||||||
|
max-height: 100%;
|
||||||
width: 80%;
|
width: 80%;
|
||||||
max-width: 80%;
|
max-width: 80%;
|
||||||
|
|
||||||
|
> #tab-content {
|
||||||
|
width: 100%;
|
||||||
|
// Subtract the height of the TabSelector
|
||||||
|
height: calc(100% - 2em);
|
||||||
|
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
export type AddMessageEvent = { message: string; messageType?: MessageType };
|
||||||
|
export type ResetMessagesEvent = { reset: true };
|
||||||
|
|
||||||
export enum MessageType {
|
export enum MessageType {
|
||||||
message = "message",
|
message = "message",
|
||||||
warning = "warning",
|
warning = "warning",
|
||||||
|
|
|
@ -3,9 +3,10 @@ import Lab from "../components/Tabs/Lab.svelte";
|
||||||
import { StaticClass } from "./StaticClass";
|
import { StaticClass } from "./StaticClass";
|
||||||
|
|
||||||
export class Tabs extends StaticClass {
|
export class Tabs extends StaticClass {
|
||||||
static readonly Tabs = {
|
static readonly AllTabs = {
|
||||||
Home,
|
Home,
|
||||||
Lab,
|
Lab,
|
||||||
} as const;
|
} as const;
|
||||||
static currentTab: keyof typeof Tabs.Tabs = "Home";
|
static currentTab: typeof Tabs.AllTabs[keyof typeof Tabs.AllTabs] =
|
||||||
|
Tabs.AllTabs.Home;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ export type HomeAction = {
|
||||||
};
|
};
|
||||||
outcomes: string[];
|
outcomes: string[];
|
||||||
multiOutcomes?: string[];
|
multiOutcomes?: string[];
|
||||||
helpText: string;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export class HomeActions extends StaticClass {
|
export class HomeActions extends StaticClass {
|
||||||
|
@ -23,8 +22,6 @@ export class HomeActions extends StaticClass {
|
||||||
fish: 1,
|
fish: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
cost: {},
|
|
||||||
prereq: {},
|
|
||||||
outcomes: [
|
outcomes: [
|
||||||
"Dropped the bass.",
|
"Dropped the bass.",
|
||||||
"Ate a kipper. Wait. Hang on.",
|
"Ate a kipper. Wait. Hang on.",
|
||||||
|
@ -67,7 +64,21 @@ export class HomeActions extends StaticClass {
|
||||||
"Ate a swedish fish.",
|
"Ate a swedish fish.",
|
||||||
"Ate a goldfish.",
|
"Ate a goldfish.",
|
||||||
],
|
],
|
||||||
helpText: "Use your natural shark prowess to find and catch a fish.",
|
},
|
||||||
|
catchShark: {
|
||||||
|
name: "Catch shark",
|
||||||
|
effect: {
|
||||||
|
resource: {
|
||||||
|
shark: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
outcomes: [
|
||||||
|
"S h a r k",
|
||||||
|
"s.h.a.r.k.",
|
||||||
|
"shark",
|
||||||
|
"sharg",
|
||||||
|
"that was probably a shark",
|
||||||
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
@use "./themes.scss";
|
@use "./themes.scss";
|
||||||
|
|
||||||
html {
|
html {
|
||||||
height: calc(100vh - 2em - 3em);
|
// Subtract height of header and footer
|
||||||
|
height: calc(100vh);
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -20,6 +21,9 @@ a {
|
||||||
&:active {
|
&:active {
|
||||||
filter: brightness(135%);
|
filter: brightness(135%);
|
||||||
}
|
}
|
||||||
|
&[disabled="true"] {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
|
@ -29,6 +33,8 @@ button {
|
||||||
text-shadow: 0 0 2px black;
|
text-shadow: 0 0 2px black;
|
||||||
color: white;
|
color: white;
|
||||||
|
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
box-shadow: 0 0 2px 2px var(--color-lighter);
|
box-shadow: 0 0 2px 2px var(--color-lighter);
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue