From 4e2095fd517bda844c37f519c9394247a219dbb6 Mon Sep 17 00:00:00 2001 From: thepaperpilot Date: Mon, 11 Apr 2022 22:50:02 -0500 Subject: [PATCH 01/32] Implemented modifiers --- src/features/conversion.ts | 40 +------------------- src/game/modifiers.ts | 76 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 38 deletions(-) create mode 100644 src/game/modifiers.ts diff --git a/src/features/conversion.ts b/src/features/conversion.ts index 55b1547..785a6d1 100644 --- a/src/features/conversion.ts +++ b/src/features/conversion.ts @@ -1,8 +1,8 @@ import { GenericLayer } from "game/layers"; +import { Modifier } from "game/modifiers"; import Decimal, { DecimalSource } from "util/bignum"; import { Computable, - convertComputable, GetComputableTypeWithDefault, processComputable, ProcessedComputable @@ -23,7 +23,7 @@ export interface ConversionOptions { buyMax?: Computable; roundUpCost?: Computable; convert?: VoidFunction; - gainModifier?: GainModifier; + gainModifier?: Modifier; } export interface BaseConversion { @@ -54,11 +54,6 @@ export type GenericConversion = Replace< } >; -export interface GainModifier { - apply: (gain: DecimalSource) => DecimalSource; - revert: (gain: DecimalSource) => DecimalSource; -} - export function createConversion( optionsFunc: OptionsFunc, BaseConversion> ): Conversion { @@ -307,34 +302,3 @@ export function addHardcap( currentGain: conversion => Decimal.min(scaling.currentGain(conversion), unref(cap)) }; } - -export function createAdditiveModifier(addend: Computable): GainModifier { - const processedAddend = convertComputable(addend); - return { - apply: gain => Decimal.add(gain, unref(processedAddend)), - revert: gain => Decimal.sub(gain, unref(processedAddend)) - }; -} - -export function createMultiplicativeModifier(multiplier: Computable): GainModifier { - const processedMultiplier = convertComputable(multiplier); - return { - apply: gain => Decimal.times(gain, unref(processedMultiplier)), - revert: gain => Decimal.div(gain, unref(processedMultiplier)) - }; -} - -export function createExponentialModifier(exponent: Computable): GainModifier { - const processedExponent = convertComputable(exponent); - return { - apply: gain => Decimal.pow(gain, unref(processedExponent)), - revert: gain => Decimal.root(gain, unref(processedExponent)) - }; -} - -export function createSequentialModifier(...modifiers: GainModifier[]): GainModifier { - return { - apply: gain => modifiers.reduce((gain, modifier) => modifier.apply(gain), gain), - revert: gain => modifiers.reduceRight((gain, modifier) => modifier.revert(gain), gain) - }; -} diff --git a/src/game/modifiers.ts b/src/game/modifiers.ts new file mode 100644 index 0000000..1584c7b --- /dev/null +++ b/src/game/modifiers.ts @@ -0,0 +1,76 @@ +import Decimal, { DecimalSource, format } from "util/bignum"; +import { Computable, convertComputable, ProcessedComputable } from "util/computed"; +import { computed, unref } from "vue"; + +export interface Modifier { + apply: (gain: DecimalSource) => DecimalSource; + revert: (gain: DecimalSource) => DecimalSource; + enabled: ProcessedComputable; + description?: ProcessedComputable; +} + +export function createAdditiveModifier( + addend: Computable, + description?: string, + enabled?: Computable +): Modifier { + const processedAddend = convertComputable(addend); + const processedEnabled = convertComputable(enabled == null ? true : enabled); + return { + apply: gain => Decimal.add(gain, unref(processedAddend)), + revert: gain => Decimal.sub(gain, unref(processedAddend)), + enabled: processedEnabled, + description: computed(() => `+${format(unref(processedAddend))} ${description}`) + }; +} + +export function createMultiplicativeModifier( + multiplier: Computable, + description?: string, + enabled?: Computable +): Modifier { + const processedMultiplier = convertComputable(multiplier); + const processedEnabled = convertComputable(enabled == null ? true : enabled); + return { + apply: gain => Decimal.times(gain, unref(processedMultiplier)), + revert: gain => Decimal.div(gain, unref(processedMultiplier)), + enabled: processedEnabled, + description: computed(() => `x${format(unref(processedMultiplier))} ${description}`) + }; +} + +export function createExponentialModifier( + exponent: Computable, + description?: string, + enabled?: Computable +): Modifier { + const processedExponent = convertComputable(exponent); + const processedEnabled = convertComputable(enabled == null ? true : enabled); + return { + apply: gain => Decimal.pow(gain, unref(processedExponent)), + revert: gain => Decimal.root(gain, unref(processedExponent)), + enabled: processedEnabled, + description: computed(() => `^${format(unref(processedExponent))} ${description}`) + }; +} + +export function createSequentialModifier(...modifiers: Modifier[]): Modifier { + return { + apply: gain => + modifiers + .filter(m => unref(m.enabled)) + .reduce((gain, modifier) => modifier.apply(gain), gain), + revert: gain => + modifiers + .filter(m => unref(m.enabled)) + .reduceRight((gain, modifier) => modifier.revert(gain), gain), + enabled: computed(() => modifiers.filter(m => unref(m.enabled)).length > 0), + description: computed(() => { + return modifiers + .filter(m => unref(m.enabled)) + .map(m => unref(m.description)) + .filter(d => d) + .join("\n"); + }) + }; +} From c918f1b54b65256c796b005f7d63b648f4a61a45 Mon Sep 17 00:00:00 2001 From: thepaperpilot Date: Sat, 16 Apr 2022 00:55:35 -0500 Subject: [PATCH 02/32] Add render functions that ensure returned type is always a JSX element --- src/util/vue.tsx | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/util/vue.tsx b/src/util/vue.tsx index 7606e55..14700c4 100644 --- a/src/util/vue.tsx +++ b/src/util/vue.tsx @@ -71,6 +71,30 @@ export function renderCol(...objects: (VueFeature | CoercableComponent)[]): JSX. return {objects.map(render)}; } +export function renderJSX(object: VueFeature | CoercableComponent): JSX.Element { + if (isCoercableComponent(object)) { + if (typeof object === "function") { + return (object as JSXFunction)(); + } + if (typeof object === "string") { + return <>{object}; + } + // TODO why is object typed as never? + const Comp = object as DefineComponent; + return ; + } + const Component = object[ComponentKey]; + return ; +} + +export function renderRowJSX(...objects: (VueFeature | CoercableComponent)[]): JSX.Element { + return {objects.map(renderJSX)}; +} + +export function renderColJSX(...objects: (VueFeature | CoercableComponent)[]): JSX.Element { + return {objects.map(renderJSX)}; +} + export function isCoercableComponent(component: unknown): component is CoercableComponent { if (typeof component === "string") { return true; From 6efd01fc438562ba2d60bf7fe8b5b07d7fff87c8 Mon Sep 17 00:00:00 2001 From: thepaperpilot Date: Sat, 16 Apr 2022 00:56:37 -0500 Subject: [PATCH 03/32] Made modifier descriptions use CoercableComponents --- src/components/common/modifiers.css | 12 +++ src/game/modifiers.ts | 76 ------------------ src/game/modifiers.tsx | 115 ++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+), 76 deletions(-) create mode 100644 src/components/common/modifiers.css delete mode 100644 src/game/modifiers.ts create mode 100644 src/game/modifiers.tsx diff --git a/src/components/common/modifiers.css b/src/components/common/modifiers.css new file mode 100644 index 0000000..646d0c0 --- /dev/null +++ b/src/components/common/modifiers.css @@ -0,0 +1,12 @@ +.modifier-container { + display: flex; +} + +.modifier-amount { + flex-basis: 100px; + flex-shrink: 0; +} + +.modifier-description { + flex-grow: 1; +} diff --git a/src/game/modifiers.ts b/src/game/modifiers.ts deleted file mode 100644 index 1584c7b..0000000 --- a/src/game/modifiers.ts +++ /dev/null @@ -1,76 +0,0 @@ -import Decimal, { DecimalSource, format } from "util/bignum"; -import { Computable, convertComputable, ProcessedComputable } from "util/computed"; -import { computed, unref } from "vue"; - -export interface Modifier { - apply: (gain: DecimalSource) => DecimalSource; - revert: (gain: DecimalSource) => DecimalSource; - enabled: ProcessedComputable; - description?: ProcessedComputable; -} - -export function createAdditiveModifier( - addend: Computable, - description?: string, - enabled?: Computable -): Modifier { - const processedAddend = convertComputable(addend); - const processedEnabled = convertComputable(enabled == null ? true : enabled); - return { - apply: gain => Decimal.add(gain, unref(processedAddend)), - revert: gain => Decimal.sub(gain, unref(processedAddend)), - enabled: processedEnabled, - description: computed(() => `+${format(unref(processedAddend))} ${description}`) - }; -} - -export function createMultiplicativeModifier( - multiplier: Computable, - description?: string, - enabled?: Computable -): Modifier { - const processedMultiplier = convertComputable(multiplier); - const processedEnabled = convertComputable(enabled == null ? true : enabled); - return { - apply: gain => Decimal.times(gain, unref(processedMultiplier)), - revert: gain => Decimal.div(gain, unref(processedMultiplier)), - enabled: processedEnabled, - description: computed(() => `x${format(unref(processedMultiplier))} ${description}`) - }; -} - -export function createExponentialModifier( - exponent: Computable, - description?: string, - enabled?: Computable -): Modifier { - const processedExponent = convertComputable(exponent); - const processedEnabled = convertComputable(enabled == null ? true : enabled); - return { - apply: gain => Decimal.pow(gain, unref(processedExponent)), - revert: gain => Decimal.root(gain, unref(processedExponent)), - enabled: processedEnabled, - description: computed(() => `^${format(unref(processedExponent))} ${description}`) - }; -} - -export function createSequentialModifier(...modifiers: Modifier[]): Modifier { - return { - apply: gain => - modifiers - .filter(m => unref(m.enabled)) - .reduce((gain, modifier) => modifier.apply(gain), gain), - revert: gain => - modifiers - .filter(m => unref(m.enabled)) - .reduceRight((gain, modifier) => modifier.revert(gain), gain), - enabled: computed(() => modifiers.filter(m => unref(m.enabled)).length > 0), - description: computed(() => { - return modifiers - .filter(m => unref(m.enabled)) - .map(m => unref(m.description)) - .filter(d => d) - .join("\n"); - }) - }; -} diff --git a/src/game/modifiers.tsx b/src/game/modifiers.tsx new file mode 100644 index 0000000..532473f --- /dev/null +++ b/src/game/modifiers.tsx @@ -0,0 +1,115 @@ +import { CoercableComponent, jsx } from "features/feature"; +import Decimal, { DecimalSource, format } from "util/bignum"; +import { Computable, convertComputable, ProcessedComputable } from "util/computed"; +import { renderJSX } from "util/vue"; +import { computed, unref } from "vue"; +import "components/common/modifiers.css"; + +export interface Modifier { + apply: (gain: DecimalSource) => DecimalSource; + revert: (gain: DecimalSource) => DecimalSource; + enabled: ProcessedComputable; + description?: ProcessedComputable; +} + +export function createAdditiveModifier( + addend: Computable, + description?: Computable, + enabled?: Computable +): Modifier { + const processedAddend = convertComputable(addend); + const processedDescription = convertComputable(description); + const processedEnabled = convertComputable(enabled == null ? true : enabled); + return { + apply: gain => Decimal.add(gain, unref(processedAddend)), + revert: gain => Decimal.sub(gain, unref(processedAddend)), + enabled: processedEnabled, + description: jsx(() => ( +
+ +{format(unref(processedAddend))} + {unref(processedDescription) ? ( + + {/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */} + {renderJSX(unref(processedDescription)!)} + + ) : null} +
+ )) + }; +} + +export function createMultiplicativeModifier( + multiplier: Computable, + description?: Computable, + enabled?: Computable +): Modifier { + const processedMultiplier = convertComputable(multiplier); + const processedDescription = convertComputable(description); + const processedEnabled = convertComputable(enabled == null ? true : enabled); + return { + apply: gain => Decimal.times(gain, unref(processedMultiplier)), + revert: gain => Decimal.div(gain, unref(processedMultiplier)), + enabled: processedEnabled, + description: jsx(() => ( +
+ x{format(unref(processedMultiplier))} + {unref(processedDescription) ? ( + + {/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */} + {renderJSX(unref(processedDescription)!)} + + ) : null} +
+ )) + }; +} + +export function createExponentialModifier( + exponent: Computable, + description?: Computable, + enabled?: Computable +): Modifier { + const processedExponent = convertComputable(exponent); + const processedDescription = convertComputable(description); + const processedEnabled = convertComputable(enabled == null ? true : enabled); + return { + apply: gain => Decimal.pow(gain, unref(processedExponent)), + revert: gain => Decimal.root(gain, unref(processedExponent)), + enabled: processedEnabled, + description: jsx(() => ( +
+ ^{format(unref(processedExponent))} + {unref(processedDescription) ? ( + + {/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */} + {renderJSX(unref(processedDescription)!)} + + ) : null} +
+ )) + }; +} + +export function createSequentialModifier(...modifiers: Modifier[]): Required { + return { + apply: gain => + modifiers + .filter(m => unref(m.enabled)) + .reduce((gain, modifier) => modifier.apply(gain), gain), + revert: gain => + modifiers + .filter(m => unref(m.enabled)) + .reduceRight((gain, modifier) => modifier.revert(gain), gain), + enabled: computed(() => modifiers.filter(m => unref(m.enabled)).length > 0), + description: jsx(() => ( + <> + {( + modifiers + .filter(m => unref(m.enabled)) + .map(m => unref(m.description)) + .filter(d => d) as CoercableComponent[] + ).map(renderJSX)} + + )) + }; +} From 9c2dcddcbec44c613550f1d0c24339c253e39937 Mon Sep 17 00:00:00 2001 From: thepaperpilot Date: Sat, 16 Apr 2022 18:37:40 -0500 Subject: [PATCH 04/32] Updated some modifiers CSS --- public/index.html | 2 +- src/components/common/modifiers.css | 4 ++++ src/features/tabs/TabFamily.vue | 10 ++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/public/index.html b/public/index.html index 47e896d..364db67 100644 --- a/public/index.html +++ b/public/index.html @@ -9,7 +9,7 @@ - + diff --git a/src/components/common/modifiers.css b/src/components/common/modifiers.css index 646d0c0..fe8071e 100644 --- a/src/components/common/modifiers.css +++ b/src/components/common/modifiers.css @@ -2,6 +2,10 @@ display: flex; } +.modifier-container:nth-child(2n) { + background: var(--raised-background); +} + .modifier-amount { flex-basis: 100px; flex-shrink: 0; diff --git a/src/features/tabs/TabFamily.vue b/src/features/tabs/TabFamily.vue index 5a44cbf..72ccd8b 100644 --- a/src/features/tabs/TabFamily.vue +++ b/src/features/tabs/TabFamily.vue @@ -150,10 +150,20 @@ export default defineComponent({ height: calc(100% + 50px); } +.modal-body > .tab-family-container:first-child { + margin: calc(10px + var(--feature-margin)) 10px 0 10px; + border: none; +} + .tab-family-container > :nth-child(2) { margin-top: 20px; } +.modal-body > .tab-family-container > :nth-child(2) { + /* TODO Why does it need this instead of 20px? */ + margin-top: 50px; +} + .tab-family-container[data-v-f18896fc] > :last-child { margin-bottom: 20px; } From ba7f877581c52dbcf10421f73ae1c139f81eb287 Mon Sep 17 00:00:00 2001 From: thepaperpilot Date: Sat, 16 Apr 2022 18:38:12 -0500 Subject: [PATCH 05/32] Made tab family's options function optional --- src/features/tabs/tabFamily.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/features/tabs/tabFamily.ts b/src/features/tabs/tabFamily.ts index a113f5c..316b131 100644 --- a/src/features/tabs/tabFamily.ts +++ b/src/features/tabs/tabFamily.ts @@ -92,7 +92,7 @@ export type GenericTabFamily = Replace< export function createTabFamily( tabs: Record TabButtonOptions>, - optionsFunc: OptionsFunc, BaseTabFamily> + optionsFunc?: OptionsFunc, BaseTabFamily> ): TabFamily { if (Object.keys(tabs).length === 0) { console.warn("Cannot create tab family with 0 tabs"); @@ -100,7 +100,7 @@ export function createTabFamily( } return createLazyProxy(persistent => { - const tabFamily = Object.assign(persistent, optionsFunc()); + const tabFamily = Object.assign(persistent, optionsFunc?.()); tabFamily.id = getUniqueID("tabFamily-"); tabFamily.type = TabFamilyType; From 89861dfbd5e9277cf149948f10dccfff720b2c7e Mon Sep 17 00:00:00 2001 From: thepaperpilot Date: Sun, 17 Apr 2022 14:01:03 -0500 Subject: [PATCH 06/32] Allowed layer.minWidth to take string values as well --- src/components/Layer.vue | 10 +++++++--- src/game/layers.tsx | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/Layer.vue b/src/components/Layer.vue index c2232a8..30be10d 100644 --- a/src/components/Layer.vue +++ b/src/components/Layer.vue @@ -50,7 +50,7 @@ export default defineComponent({ required: true }, minWidth: { - type: processedPropType(Number), + type: processedPropType(Number, String), required: true }, name: { @@ -93,7 +93,11 @@ export default defineComponent({ } ); - function updateTab(minimized: boolean, minWidth: number) { + function updateTab(minimized: boolean, minWidth: number | string) { + const width = + typeof minWidth === "number" || Number.isNaN(parseInt(minWidth)) + ? minWidth + "px" + : minWidth; const tabValue = tab.value(); if (tabValue != undefined) { if (minimized) { @@ -106,7 +110,7 @@ export default defineComponent({ tabValue.style.flexGrow = ""; tabValue.style.flexShrink = ""; tabValue.style.width = ""; - tabValue.style.minWidth = tabValue.style.flexBasis = `${minWidth}px`; + tabValue.style.minWidth = tabValue.style.flexBasis = `${width}px`; tabValue.style.margin = ""; } } diff --git a/src/game/layers.tsx b/src/game/layers.tsx index 99dd826..85b7a17 100644 --- a/src/game/layers.tsx +++ b/src/game/layers.tsx @@ -66,7 +66,7 @@ export interface LayerOptions { name?: Computable; minimizable?: Computable; forceHideGoBack?: Computable; - minWidth?: Computable; + minWidth?: Computable; } export interface BaseLayer { From f76d5deb6e626b15b747cea78a7116a7d9064103 Mon Sep 17 00:00:00 2001 From: thepaperpilot Date: Sat, 23 Apr 2022 15:23:38 -0500 Subject: [PATCH 07/32] Tooltips overhaul --- src/components/Nav.vue | 28 +++-- src/components/Options.vue | 2 +- src/components/fields/Slider.vue | 2 +- src/features/achievements/Achievement.vue | 4 +- src/features/tooltip.ts | 25 ---- .../tooltips}/Tooltip.vue | 80 +++++++++--- src/features/tooltips/tooltip.ts | 115 ++++++++++++++++++ src/features/trees/Tree.vue | 7 -- src/features/trees/TreeNode.vue | 66 +--------- src/features/trees/tree.ts | 15 --- src/util/proxies.ts | 6 +- src/util/vue.tsx | 8 +- 12 files changed, 212 insertions(+), 146 deletions(-) delete mode 100644 src/features/tooltip.ts rename src/{components => features/tooltips}/Tooltip.vue (59%) create mode 100644 src/features/tooltips/tooltip.ts diff --git a/src/components/Nav.vue b/src/components/Nav.vue index 05ae72a..66453b3 100644 --- a/src/components/Nav.vue +++ b/src/components/Nav.vue @@ -3,7 +3,7 @@
{{ title }}
- v{{ versionNumber }}
@@ -26,51 +26,56 @@
- + info
- + library_books
- + settings
- + v{{ versionNumber }}
- + library_books
- + settings
- + info
- + forum @@ -105,7 +110,8 @@ import { ComponentPublicInstance, ref } from "vue"; import Info from "./Info.vue"; import Options from "./Options.vue"; import SavesManager from "./SavesManager.vue"; -import Tooltip from "./Tooltip.vue"; +import Tooltip from "features/tooltips/Tooltip.vue"; +import { TooltipDirection } from "features/tooltips/tooltip"; const info = ref | null>(null); const savesManager = ref | null>(null); diff --git a/src/components/Options.vue b/src/components/Options.vue index b2281aa..afc9739 100644 --- a/src/components/Options.vue +++ b/src/components/Options.vue @@ -30,7 +30,7 @@ import { coerceComponent, render } from "util/vue"; import { computed, ref, toRefs } from "vue"; import Select from "./fields/Select.vue"; import Toggle from "./fields/Toggle.vue"; -import Tooltip from "./Tooltip.vue"; +import Tooltip from "features/tooltips/Tooltip.vue"; const isOpen = ref(false); diff --git a/src/components/fields/Slider.vue b/src/components/fields/Slider.vue index 7ac610f..a6371e8 100644 --- a/src/components/fields/Slider.vue +++ b/src/components/fields/Slider.vue @@ -9,7 +9,7 @@