From 0c0de62a831e7e6dfbe77dc458e57a82583e64db Mon Sep 17 00:00:00 2001 From: thepaperpilot Date: Tue, 20 Dec 2022 21:26:25 -0600 Subject: [PATCH] Add eslint rule for strict boolean expressions and fix linting issues --- .eslintrc.js | 12 ++++++++-- src/App.vue | 2 +- src/components/Info.vue | 2 +- src/components/Layer.vue | 9 +++----- src/components/Modal.vue | 4 ++-- src/components/NaNScreen.vue | 8 +++---- src/components/Options.vue | 2 +- src/components/Save.vue | 6 ++--- src/components/SavesManager.vue | 2 +- src/components/fields/Slider.vue | 2 +- src/components/fields/Text.vue | 2 +- src/components/fields/Toggle.vue | 2 +- src/components/math/Fraction.vue | 2 +- src/components/math/Sqrt.vue | 6 +++-- src/data/common.tsx | 20 ++++++++-------- src/data/projEntry.tsx | 4 ++-- src/features/achievements/achievement.tsx | 2 +- src/features/bars/bar.ts | 8 ++++++- src/features/boards/Board.vue | 2 +- src/features/boards/BoardNode.vue | 8 +++---- src/features/buyable.tsx | 28 ++++++++++++++--------- src/features/challenges/Challenge.vue | 8 +++---- src/features/challenges/challenge.tsx | 16 +++++++++---- src/features/clickables/Clickable.vue | 2 +- src/features/clickables/clickable.ts | 15 ++++++++---- src/features/conversion.ts | 17 ++++++++------ src/features/feature.ts | 4 ++-- src/features/milestones/Milestone.vue | 4 ++-- src/features/milestones/milestone.tsx | 15 +++++++++--- src/features/reset.ts | 2 +- src/features/trees/tree.ts | 4 ++-- src/features/upgrades/Upgrade.vue | 4 ++-- src/features/upgrades/upgrade.ts | 7 ++++-- src/game/modifiers.tsx | 6 ++--- src/game/persistence.ts | 6 ++--- src/game/player.ts | 2 +- src/game/settings.ts | 8 +++---- src/util/bignum.ts | 4 ++-- src/util/break_eternity.ts | 6 ++++- src/util/proxies.ts | 2 +- src/util/save.ts | 9 ++++++-- src/util/vue.tsx | 5 +++- 42 files changed, 168 insertions(+), 111 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 2a1d0bc..a881f38 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -11,7 +11,8 @@ module.exports = { "@vue/eslint-config-prettier" ], parserOptions: { - ecmaVersion: 2020 + ecmaVersion: 2020, + project: "tsconfig.json" }, ignorePatterns: ["src/lib"], rules: { @@ -19,7 +20,14 @@ module.exports = { "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off", "vue/script-setup-uses-vars": "warn", "vue/no-mutating-props": "off", - "vue/multi-word-component-names": "off" + "vue/multi-word-component-names": "off", + "@typescript-eslint/strict-boolean-expressions": [ + "error", + { + allowNullableObject: true, + allowNullableBoolean: true + } + ] }, globals: { defineProps: "readonly", diff --git a/src/App.vue b/src/App.vue index 560ce53..b661703 100644 --- a/src/App.vue +++ b/src/App.vue @@ -32,7 +32,7 @@ const theme = computed(() => themes[settings.theme].variables as CSSProperties); const showTPS = toRef(settings, "showTPS"); const gameComponent = computed(() => { - return coerceComponent(jsx(() => <>{gameComponents.map(render)})); + return coerceComponent(jsx(() => (<>{gameComponents.map(render)}))); }); diff --git a/src/components/Info.vue b/src/components/Info.vue index 1d7cef9..939dd4e 100644 --- a/src/components/Info.vue +++ b/src/components/Info.vue @@ -80,7 +80,7 @@ const isOpen = ref(false); const timePlayed = computed(() => formatTime(player.timePlayed)); const infoComponent = computed(() => { - return coerceComponent(jsx(() => <>{infoComponents.map(render)})); + return coerceComponent(jsx(() => (<>{infoComponents.map(render)}))); }); defineExpose({ diff --git a/src/components/Layer.vue b/src/components/Layer.vue index 8c055bd..e6300f8 100644 --- a/src/components/Layer.vue +++ b/src/components/Layer.vue @@ -12,9 +12,7 @@ - + @@ -114,7 +112,6 @@ export default defineComponent({ } } - return { component, minimizedComponent, @@ -124,7 +121,7 @@ export default defineComponent({ goBack, setMinimized, minimized, - minWidth, + minWidth }; } }); @@ -237,7 +234,7 @@ export default defineComponent({ text-shadow: 0 0 7px var(--foreground); } - \ No newline at end of file + diff --git a/src/components/math/Sqrt.vue b/src/components/math/Sqrt.vue index 6dce0de..461846f 100644 --- a/src/components/math/Sqrt.vue +++ b/src/components/math/Sqrt.vue @@ -1,6 +1,8 @@ diff --git a/src/data/common.tsx b/src/data/common.tsx index 5074730..869414b 100644 --- a/src/data/common.tsx +++ b/src/data/common.tsx @@ -1,4 +1,5 @@ import Collapsible from "components/layout/Collapsible.vue"; +import "data/layers/styles/day-gradients.css"; import { createBar } from "features/bars/bar"; import { GenericBuyable } from "features/buyable"; import type { Clickable, ClickableOptions, GenericClickable } from "features/clickables/clickable"; @@ -16,14 +17,12 @@ import { GenericMilestone } from "features/milestones/milestone"; import { displayResource, Resource, trackTotal } from "features/resources/resource"; import type { GenericTree, GenericTreeNode, TreeNode, TreeNodeOptions } from "features/trees/tree"; import { createTreeNode } from "features/trees/tree"; -import { BaseLayer, Layer } from "game/layers"; import type { Modifier } from "game/modifiers"; import type { Persistent } from "game/persistence"; import { DefaultValue, persistent } from "game/persistence"; import player from "game/player"; import settings from "game/settings"; -import { DecimalSource, formatSmall } from "util/bignum"; -import Decimal, { format } from "util/bignum"; +import Decimal, { DecimalSource, format, formatSmall } from "util/bignum"; import { formatWhole } from "util/break_eternity"; import { Direction, WithRequired } from "util/common"; import type { @@ -34,10 +33,8 @@ import type { } from "util/computed"; import { convertComputable, processComputable } from "util/computed"; import { getFirstFeature, render, renderColJSX, renderJSX, VueFeature } from "util/vue"; -import { Ref, watchEffect } from "vue"; -import { computed, unref } from "vue"; +import { computed, Ref, unref, watchEffect } from "vue"; import "./common.css"; -import "data/layers/styles/day-gradients.css"; import { main } from "./projEntry"; /** An object that configures a {@link ResetButton} */ @@ -138,7 +135,7 @@ export function createResetButton{" "} {resetButton.conversion.gainResource.displayName} - {unref(resetButton.showNextAt) ? ( + {unref(resetButton.showNextAt) != null ? (

{unref(resetButton.conversion.buyMax) ? "Next:" : "Req:"}{" "} @@ -167,7 +164,7 @@ export function createResetButton {s.title} - {s.subtitle ? ({s.subtitle}) : null} + {s.subtitle != null ? ({s.subtitle}) : null} ); @@ -338,7 +335,8 @@ export function createCollapsibleModifierSections( {hasPreviousSection ?
: null}
{header} @@ -455,7 +453,7 @@ export function setUpDailyProgressTracker(options: { animation: options.background.duration + " " + options.background.gradient + " linear infinite", }, /* eslint-enable prettier/prettier */ - textStyle: options.textColor ? { color: options.textColor } : undefined, + textStyle: options.textColor != null ? { color: options.textColor } : undefined, progress: progressFunc, display: jsx(() => main.day.value === options.day || diff --git a/src/data/projEntry.tsx b/src/data/projEntry.tsx index 7b2ac9e..efe1bb0 100644 --- a/src/data/projEntry.tsx +++ b/src/data/projEntry.tsx @@ -539,10 +539,10 @@ export const main = createLayer("main", function (this: BaseLayer) { display: jsx(() => ( <> {player.devSpeed === 0 ?
Game Paused
: null} - {player.devSpeed && player.devSpeed !== 1 ? ( + {player.devSpeed != null && player.devSpeed !== 1 ? (
Dev Speed: {format(player.devSpeed)}x
) : null} - {player.offlineTime ? ( + {player.offlineTime != null && player.offlineTime !== 0 ? (
Offline Time: {formatTime(player.offlineTime)}
) : null} diff --git a/src/features/achievements/achievement.tsx b/src/features/achievements/achievement.tsx index 8bebb55..92e9e88 100644 --- a/src/features/achievements/achievement.tsx +++ b/src/features/achievements/achievement.tsx @@ -109,7 +109,7 @@ export function createAchievement( ) { genericAchievement.earned.value = true; genericAchievement.onComplete?.(); - if (genericAchievement.display) { + if (genericAchievement.display != null) { const Display = coerceComponent(unref(genericAchievement.display)); toast.info(
diff --git a/src/features/bars/bar.ts b/src/features/bars/bar.ts index 1eca337..a77fcb8 100644 --- a/src/features/bars/bar.ts +++ b/src/features/bars/bar.ts @@ -1,5 +1,11 @@ import BarComponent from "features/bars/Bar.vue"; -import type { CoercableComponent, GenericComponent, OptionsFunc, Replace, StyleValue } from "features/feature"; +import type { + CoercableComponent, + GenericComponent, + OptionsFunc, + Replace, + StyleValue +} from "features/feature"; import { Component, GatherProps, getUniqueID, setDefault, Visibility } from "features/feature"; import type { DecimalSource } from "util/bignum"; import { Direction } from "util/common"; diff --git a/src/features/boards/Board.vue b/src/features/boards/Board.vue index c7e7d9d..221ed4a 100644 --- a/src/features/boards/Board.vue +++ b/src/features/boards/Board.vue @@ -210,7 +210,7 @@ function drag(e: MouseEvent | TouchEvent) { hasDragged.value = true; } - if (dragging.value) { + if (dragging.value != null) { e.preventDefault(); e.stopPropagation(); } diff --git a/src/features/boards/BoardNode.vue b/src/features/boards/BoardNode.vue index e46fb32..a153afd 100644 --- a/src/features/boards/BoardNode.vue +++ b/src/features/boards/BoardNode.vue @@ -234,17 +234,17 @@ const title = computed(() => getNodeProperty(props.nodeType.value.title, unref(p const label = computed(() => getNodeProperty(props.nodeType.value.label, unref(props.node))); const size = computed(() => getNodeProperty(props.nodeType.value.size, unref(props.node))); const progress = computed( - () => getNodeProperty(props.nodeType.value.progress, unref(props.node)) || 0 + () => getNodeProperty(props.nodeType.value.progress, unref(props.node)) ?? 0 ); const backgroundColor = computed(() => themes[settings.theme].variables["--background"]); const outlineColor = computed( () => - getNodeProperty(props.nodeType.value.outlineColor, unref(props.node)) || + getNodeProperty(props.nodeType.value.outlineColor, unref(props.node)) ?? themes[settings.theme].variables["--outline"] ); const fillColor = computed( () => - getNodeProperty(props.nodeType.value.fillColor, unref(props.node)) || + getNodeProperty(props.nodeType.value.fillColor, unref(props.node)) ?? themes[settings.theme].variables["--raised-background"] ); const progressColor = computed(() => @@ -252,7 +252,7 @@ const progressColor = computed(() => ); const titleColor = computed( () => - getNodeProperty(props.nodeType.value.titleColor, unref(props.node)) || + getNodeProperty(props.nodeType.value.titleColor, unref(props.node)) ?? themes[settings.theme].variables["--foreground"] ); const progressDisplay = computed(() => diff --git a/src/features/buyable.tsx b/src/features/buyable.tsx index b3d3737..c426274 100644 --- a/src/features/buyable.tsx +++ b/src/features/buyable.tsx @@ -1,5 +1,11 @@ import ClickableComponent from "features/clickables/Clickable.vue"; -import type { CoercableComponent, GenericComponent, OptionsFunc, Replace, StyleValue } from "features/feature"; +import type { + CoercableComponent, + GenericComponent, + OptionsFunc, + Replace, + StyleValue +} from "features/feature"; import { Component, GatherProps, getUniqueID, jsx, setDefault, Visibility } from "features/feature"; import type { Resource } from "features/resources/resource"; import { DefaultValue, Persistent } from "game/persistence"; @@ -170,18 +176,18 @@ export function createBuyable( } if (currDisplay != null && buyable.cost != null && buyable.resource != null) { const genericBuyable = buyable as GenericBuyable; - const Title = coerceComponent(currDisplay.title || "", "h3"); - const Description = coerceComponent(currDisplay.description || ""); - const EffectDisplay = coerceComponent(currDisplay.effectDisplay || ""); + const Title = coerceComponent(currDisplay.title ?? "", "h3"); + const Description = coerceComponent(currDisplay.description ?? ""); + const EffectDisplay = coerceComponent(currDisplay.effectDisplay ?? ""); return ( - {currDisplay.title ? ( + {currDisplay.title == null ? null : (
</div> - ) : null} - {currDisplay.description ? <Description /> : null} + )} + {currDisplay.description == null ? null : <Description />} {currDisplay.showAmount === false ? null : ( <div> <br /> @@ -195,15 +201,15 @@ export function createBuyable<T extends BuyableOptions>( )} </div> )} - {currDisplay.effectDisplay ? ( + {currDisplay.effectDisplay == null ? null : ( <div> <br /> Currently: <EffectDisplay /> </div> - ) : null} - {genericBuyable.cost && !genericBuyable.maxed.value ? ( + )} + {genericBuyable.cost != null && !genericBuyable.maxed.value ? ( <div> - Cost: {format(unref(genericBuyable.cost) || 0)}{" "} + Cost: {format(unref(genericBuyable.cost))}{" "} {buyable.resource.displayName} </div> ) : null} diff --git a/src/features/challenges/Challenge.vue b/src/features/challenges/Challenge.vue index e387c18..f68d9cf 100644 --- a/src/features/challenges/Challenge.vue +++ b/src/features/challenges/Challenge.vue @@ -134,25 +134,25 @@ export default defineComponent({ comp.value = coerceComponent( jsx(() => ( <span> - {currDisplay.title ? ( + {currDisplay.title != null ? ( <div> <Title /> </div> ) : null} <Description /> - {currDisplay.goal ? ( + {currDisplay.goal != null ? ( <div> <br /> Goal: <Goal /> </div> ) : null} - {currDisplay.reward ? ( + {currDisplay.reward != null ? ( <div> <br /> Reward: <Reward /> </div> ) : null} - {currDisplay.effectDisplay ? ( + {currDisplay.effectDisplay != null ? ( <div> Currently: <EffectDisplay /> </div> diff --git a/src/features/challenges/challenge.tsx b/src/features/challenges/challenge.tsx index 8128ab2..be3d90b 100644 --- a/src/features/challenges/challenge.tsx +++ b/src/features/challenges/challenge.tsx @@ -126,7 +126,10 @@ export function createChallenge<T extends ChallengeOptions>( challenge.toggle = function () { const genericChallenge = challenge as GenericChallenge; if (genericChallenge.active.value) { - if (unref(genericChallenge.canComplete) && !genericChallenge.maxed.value) { + if ( + unref(genericChallenge.canComplete) !== false && + !genericChallenge.maxed.value + ) { let completions: boolean | DecimalSource = unref(genericChallenge.canComplete); if (typeof completions === "boolean") { completions = 1; @@ -264,11 +267,14 @@ export function setupAutoComplete( exitOnComplete = true ): WatchStopHandle { const isActive = typeof autoActive === "function" ? computed(autoActive) : autoActive; - return watch([challenge.canComplete, isActive], ([canComplete, isActive]) => { - if (canComplete && isActive) { - challenge.complete(!exitOnComplete); + return watch( + [challenge.canComplete as Ref<boolean>, isActive as Ref<boolean>], + ([canComplete, isActive]) => { + if (canComplete && isActive) { + challenge.complete(!exitOnComplete); + } } - }); + ); } export function createActiveChallenge( diff --git a/src/features/clickables/Clickable.vue b/src/features/clickables/Clickable.vue index acbc804..c51c510 100644 --- a/src/features/clickables/Clickable.vue +++ b/src/features/clickables/Clickable.vue @@ -98,7 +98,7 @@ export default defineComponent({ comp.value = coerceComponent( jsx(() => ( <span> - {currDisplay.title ? ( + {currDisplay.title != null ? ( <div> <Title /> </div> diff --git a/src/features/clickables/clickable.ts b/src/features/clickables/clickable.ts index 7222982..68035c4 100644 --- a/src/features/clickables/clickable.ts +++ b/src/features/clickables/clickable.ts @@ -1,5 +1,11 @@ import ClickableComponent from "features/clickables/Clickable.vue"; -import type { CoercableComponent, GenericComponent, OptionsFunc, Replace, StyleValue } from "features/feature"; +import type { + CoercableComponent, + GenericComponent, + OptionsFunc, + Replace, + StyleValue +} from "features/feature"; import { Component, GatherProps, getUniqueID, setDefault, Visibility } from "features/feature"; import type { BaseLayer } from "game/layers"; import type { Unsubscribe } from "nanoevents"; @@ -84,7 +90,7 @@ export function createClickable<T extends ClickableOptions>( if (clickable.onClick) { const onClick = clickable.onClick.bind(clickable); clickable.onClick = function (e) { - if (unref(clickable.canClick)) { + if (unref(clickable.canClick) !== false) { onClick(e); } }; @@ -92,7 +98,7 @@ export function createClickable<T extends ClickableOptions>( if (clickable.onHold) { const onHold = clickable.onHold.bind(clickable); clickable.onHold = function () { - if (unref(clickable.canClick)) { + if (unref(clickable.canClick) !== false) { onHold(); } }; @@ -136,7 +142,8 @@ export function setupAutoClick( clickable: GenericClickable, autoActive: Computable<boolean> = true ): Unsubscribe { - const isActive = typeof autoActive === "function" ? computed(autoActive) : autoActive; + const isActive: ProcessedComputable<boolean> = + typeof autoActive === "function" ? computed(autoActive) : autoActive; return layer.on("update", () => { if (unref(isActive) && unref(clickable.canClick)) { clickable.onClick?.(); diff --git a/src/features/conversion.ts b/src/features/conversion.ts index 6c95c1e..a7f18d0 100644 --- a/src/features/conversion.ts +++ b/src/features/conversion.ts @@ -151,7 +151,7 @@ export function createConversion<T extends ConversionOptions>( : conversion.scaling.currentGain(conversion as GenericConversion); gain = Decimal.floor(gain).max(0); - if (!unref(conversion.buyMax)) { + if (unref(conversion.buyMax) === false) { gain = gain.min(1); } return gain; @@ -163,14 +163,15 @@ export function createConversion<T extends ConversionOptions>( if (conversion.currentAt == null) { conversion.currentAt = computed(() => { let current = conversion.scaling.currentAt(conversion as GenericConversion); - if (conversion.roundUpCost) current = Decimal.ceil(current); + if (unref((conversion as GenericConversion).roundUpCost)) + current = Decimal.ceil(current); return current; }); } if (conversion.nextAt == null) { conversion.nextAt = computed(() => { let next = conversion.scaling.nextAt(conversion as GenericConversion); - if (conversion.roundUpCost) next = Decimal.ceil(next); + if (unref((conversion as GenericConversion).roundUpCost)) next = Decimal.ceil(next); return next; }); } @@ -405,7 +406,7 @@ export function createIndependentConversion<S extends ConversionOptions>( : conversion.scaling.currentGain(conversion as GenericConversion); gain = Decimal.floor(gain).max(conversion.gainResource.value); - if (!unref(conversion.buyMax)) { + if (unref(conversion.buyMax) === false) { gain = gain.min(Decimal.add(conversion.gainResource.value, 1)); } return gain; @@ -418,7 +419,7 @@ export function createIndependentConversion<S extends ConversionOptions>( conversion.gainResource.value ).max(0); - if (!unref(conversion.buyMax)) { + if (unref(conversion.buyMax) === false) { gain = gain.min(1); } return gain; @@ -511,8 +512,10 @@ export function addSoftcap( ): ScalingFunction { return { ...scaling, - currentAt: conversion => softcap(scaling.currentAt(conversion), unref(cap), Decimal.recip(unref(power))), - nextAt: conversion => softcap(scaling.nextAt(conversion), unref(cap), Decimal.recip(unref(power))), + currentAt: conversion => + softcap(scaling.currentAt(conversion), unref(cap), Decimal.recip(unref(power))), + nextAt: conversion => + softcap(scaling.nextAt(conversion), unref(cap), Decimal.recip(unref(power))), currentGain: conversion => softcap(scaling.currentGain(conversion), unref(cap), unref(power)) }; diff --git a/src/features/feature.ts b/src/features/feature.ts index ae14e29..afa251f 100644 --- a/src/features/feature.ts +++ b/src/features/feature.ts @@ -102,7 +102,7 @@ export function findFeatures(obj: Record<string, unknown>, ...types: symbol[]): const handleObject = (obj: Record<string, unknown>) => { Object.keys(obj).forEach(key => { const value = obj[key]; - if (value && typeof value === "object") { + if (value != null && typeof value === "object") { // eslint-disable-next-line @typescript-eslint/no-explicit-any if (types.includes((value as Record<string, any>).type)) { objects.push(value); @@ -127,7 +127,7 @@ export function excludeFeatures(obj: Record<string, unknown>, ...types: symbol[] const handleObject = (obj: Record<string, unknown>) => { Object.keys(obj).forEach(key => { const value = obj[key]; - if (value && typeof value === "object") { + if (value != null && typeof value === "object") { if ( // eslint-disable-next-line @typescript-eslint/no-explicit-any typeof (value as Record<string, any>).type == "symbol" && diff --git a/src/features/milestones/Milestone.vue b/src/features/milestones/Milestone.vue index 92a90d6..8cc4331 100644 --- a/src/features/milestones/Milestone.vue +++ b/src/features/milestones/Milestone.vue @@ -74,12 +74,12 @@ export default defineComponent({ jsx(() => ( <span> <Requirement /> - {currDisplay.effectDisplay ? ( + {currDisplay.effectDisplay != null ? ( <div> <EffectDisplay /> </div> ) : null} - {currDisplay.optionsDisplay ? ( + {currDisplay.optionsDisplay != null ? ( <div class="equal-spaced"> <OptionsDisplay /> </div> diff --git a/src/features/milestones/milestone.tsx b/src/features/milestones/milestone.tsx index e016e64..cb3e7c4 100644 --- a/src/features/milestones/milestone.tsx +++ b/src/features/milestones/milestone.tsx @@ -1,5 +1,11 @@ import Select from "components/fields/Select.vue"; -import type { CoercableComponent, GenericComponent, OptionsFunc, Replace, StyleValue } from "features/feature"; +import type { + CoercableComponent, + GenericComponent, + OptionsFunc, + Replace, + StyleValue +} from "features/feature"; import { Component, GatherProps, getUniqueID, jsx, setDefault, Visibility } from "features/feature"; import MilestoneComponent from "features/milestones/Milestone.vue"; import { globalBus } from "game/events"; @@ -92,7 +98,7 @@ export function createMilestone<T extends MilestoneOptions>( const genericMilestone = milestone as GenericMilestone; earned.value = true; genericMilestone.onComplete?.(); - if (genericMilestone.display && unref(genericMilestone.showPopups) === true) { + if (genericMilestone.display != null && unref(genericMilestone.showPopups) === true) { const display = unref(genericMilestone.display); const Display = coerceComponent( isCoercableComponent(display) ? display : display.requirement @@ -162,7 +168,10 @@ export function createMilestone<T extends MilestoneOptions>( ) { genericMilestone.earned.value = true; genericMilestone.onComplete?.(); - if (genericMilestone.display && unref(genericMilestone.showPopups) === true) { + if ( + genericMilestone.display != null && + unref(genericMilestone.showPopups) === true + ) { const display = unref(genericMilestone.display); const Display = coerceComponent( isCoercableComponent(display) ? display : display.requirement diff --git a/src/features/reset.ts b/src/features/reset.ts index 92cb506..487238c 100644 --- a/src/features/reset.ts +++ b/src/features/reset.ts @@ -43,7 +43,7 @@ export function createReset<T extends ResetOptions>( reset.reset = function () { const handleObject = (obj: unknown) => { - if (obj && typeof obj === "object") { + if (obj != null && typeof obj === "object") { if (DefaultValue in obj) { const persistent = obj as NonPersistent; persistent.value = persistent[DefaultValue]; diff --git a/src/features/trees/tree.ts b/src/features/trees/tree.ts index 3fbf935..0b36f74 100644 --- a/src/features/trees/tree.ts +++ b/src/features/trees/tree.ts @@ -88,7 +88,7 @@ export function createTreeNode<T extends TreeNodeOptions>( if (treeNode.onClick) { const onClick = treeNode.onClick.bind(treeNode); treeNode.onClick = function () { - if (unref(treeNode.canClick)) { + if (unref(treeNode.canClick) !== false) { onClick(); } }; @@ -96,7 +96,7 @@ export function createTreeNode<T extends TreeNodeOptions>( if (treeNode.onHold) { const onHold = treeNode.onHold.bind(treeNode); treeNode.onHold = function () { - if (unref(treeNode.canClick)) { + if (unref(treeNode.canClick) !== false) { onHold(); } }; diff --git a/src/features/upgrades/Upgrade.vue b/src/features/upgrades/Upgrade.vue index dce37be..9723f44 100644 --- a/src/features/upgrades/Upgrade.vue +++ b/src/features/upgrades/Upgrade.vue @@ -96,13 +96,13 @@ export default defineComponent({ component.value = coerceComponent( jsx(() => ( <span> - {currDisplay.title ? ( + {currDisplay.title != null ? ( <div> <Title /> </div> ) : null} <Description /> - {currDisplay.effectDisplay ? ( + {currDisplay.effectDisplay != null ? ( <div> Currently: <EffectDisplay /> </div> diff --git a/src/features/upgrades/upgrade.ts b/src/features/upgrades/upgrade.ts index d60d9ea..1eb1d56 100644 --- a/src/features/upgrades/upgrade.ts +++ b/src/features/upgrades/upgrade.ts @@ -187,8 +187,11 @@ export function setupAutoPurchase( autoActive: Computable<boolean>, upgrades: GenericUpgrade[] = [] ): void { - upgrades = upgrades || findFeatures(layer, UpgradeType); - const isAutoActive = isFunction(autoActive) ? computed(autoActive) : autoActive; + upgrades = + upgrades.length === 0 ? (findFeatures(layer, UpgradeType) as GenericUpgrade[]) : upgrades; + const isAutoActive: ProcessedComputable<boolean> = isFunction(autoActive) + ? computed(autoActive) + : autoActive; layer.on("update", () => { if (unref(isAutoActive)) { upgrades.forEach(upgrade => upgrade.purchase()); diff --git a/src/game/modifiers.tsx b/src/game/modifiers.tsx index a5cd416..4606671 100644 --- a/src/game/modifiers.tsx +++ b/src/game/modifiers.tsx @@ -78,7 +78,7 @@ export function createAdditiveModifier<T extends AdditiveModifierOptions>( ? undefined : jsx(() => ( <div class="modifier-container"> - {unref(processedDescription) ? ( + {unref(processedDescription) != null ? ( <span class="modifier-description"> {/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */} {renderJSX(unref(processedDescription)!)} @@ -126,7 +126,7 @@ export function createMultiplicativeModifier<T extends MultiplicativeModifierOpt ? undefined : jsx(() => ( <div class="modifier-container"> - {unref(processedDescription) ? ( + {unref(processedDescription) != null ? ( <span class="modifier-description"> {/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */} {renderJSX(unref(processedDescription)!)} @@ -195,7 +195,7 @@ export function createExponentialModifier<T extends ExponentialModifierOptions>( ? undefined : jsx(() => ( <div class="modifier-container"> - {unref(processedDescription) ? ( + {unref(processedDescription) != null ? ( <span class="modifier-description"> {/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */} {renderJSX(unref(processedDescription)!)} diff --git a/src/game/persistence.ts b/src/game/persistence.ts index 03f5dad..893d435 100644 --- a/src/game/persistence.ts +++ b/src/game/persistence.ts @@ -85,7 +85,7 @@ function getStackTrace() { ?.split("\n") .slice(3, 5) .map(line => line.trim()) - .join("\n") || "" + .join("\n") ?? "" ); } @@ -134,7 +134,7 @@ export function persistent<T extends State>(defaultValue: T | Ref<T>): Persisten */ // eslint-disable-next-line @typescript-eslint/no-explicit-any export function isPersistent(value: any): value is Persistent { - return value && typeof value === "object" && PersistentState in value; + return value != null && typeof value === "object" && PersistentState in value; } /** @@ -168,7 +168,7 @@ globalBus.on("addLayer", (layer: GenericLayer, saveData: Record<string, unknown> let foundPersistent = false; Object.keys(obj).forEach(key => { let value = obj[key]; - if (value && typeof value === "object") { + if (value != null && typeof value === "object") { if (ProxyState in value) { // eslint-disable-next-line @typescript-eslint/no-explicit-any value = (value as any)[ProxyState] as object; diff --git a/src/game/player.ts b/src/game/player.ts index e641904..3280caf 100644 --- a/src/game/player.ts +++ b/src/game/player.ts @@ -70,7 +70,7 @@ const state = reactive<PlayerData>({ modVersion: "", layers: {}, - autoPause: true, + autoPause: true }); /** Convert a player save data object into a JSON string. Unwraps refs. */ diff --git a/src/game/settings.ts b/src/game/settings.ts index a82c8a5..9595343 100644 --- a/src/game/settings.ts +++ b/src/game/settings.ts @@ -33,9 +33,9 @@ const state = reactive<Partial<Settings>>({ showTPS: true, theme: Themes.Nordic, unthrottled: false, - + usingLog: false, - alignUnits: false, + alignUnits: false }); watch( @@ -68,9 +68,9 @@ export const hardResetSettings = (window.hardResetSettings = () => { saves: [], showTPS: true, theme: Themes.Nordic, - + usingLog: false, - alignUnits: false, + alignUnits: false }; globalBus.emit("loadSettings", settings); Object.assign(state, settings); diff --git a/src/util/bignum.ts b/src/util/bignum.ts index 3c368d9..64bbeb2 100644 --- a/src/util/bignum.ts +++ b/src/util/bignum.ts @@ -33,7 +33,7 @@ declare global { formatSmall: (x: DecimalSource, precision?: number) => string; formatLimit: (list: [DecimalSource, string][], unit: string) => string; invertOOM: (x: DecimalSource) => Decimal; - formatGain: (x: DecimalSource) => string + formatGain: (x: DecimalSource) => string; } } window.Decimal = Decimal; @@ -47,6 +47,6 @@ window.toPlaces = toPlaces; window.formatSmall = formatSmall; window.formatLimit = formatLimit; window.invertOOM = invertOOM; -window.formatGain = formatGain +window.formatGain = formatGain; export default Decimal; diff --git a/src/util/break_eternity.ts b/src/util/break_eternity.ts index a794464..a3fc5aa 100644 --- a/src/util/break_eternity.ts +++ b/src/util/break_eternity.ts @@ -196,7 +196,11 @@ export function invertOOM(x: DecimalSource): Decimal { return x; } -export function formatLimit(list: [DecimalSource, string][], unit: string, gainMultiplier: DecimalSource = Decimal.dOne): string { +export function formatLimit( + list: [DecimalSource, string][], + unit: string, + gainMultiplier: DecimalSource = Decimal.dOne +): string { let num = list[0][0]; let str = list[0][1]; for (let i = 1; i < list.length; i++) { diff --git a/src/util/proxies.ts b/src/util/proxies.ts index a855dee..9dad138 100644 --- a/src/util/proxies.ts +++ b/src/util/proxies.ts @@ -39,7 +39,7 @@ export function createLazyProxy<T extends object, S extends T>( } // eslint-disable-next-line @typescript-eslint/no-explicit-any const val = (calculateObj() as any)[key]; - if (val && typeof val === "object" && NonPersistent in val) { + if (val != null && typeof val === "object" && NonPersistent in val) { return val[NonPersistent]; } return val; diff --git a/src/util/save.ts b/src/util/save.ts index 8ddddad..31fb837 100644 --- a/src/util/save.ts +++ b/src/util/save.ts @@ -86,7 +86,7 @@ export function getUniqueID(): string { i = 0; do { id = `${projInfo.id}-${i++}`; - } while (localStorage.getItem(id)); + } while (localStorage.getItem(id) != null); return id; } @@ -107,7 +107,12 @@ export async function loadSave(playerObj: Partial<PlayerData>): Promise<void> { getInitialLayers(playerObj).forEach(layer => addLayer(layer, playerObj)); playerObj = setupInitialStore(playerObj); - if (playerObj.offlineProd && playerObj.time && playerObj.devSpeed !== 0) { + if ( + playerObj.offlineProd && + playerObj.time != null && + playerObj.time && + playerObj.devSpeed !== 0 + ) { if (playerObj.offlineTime == undefined) playerObj.offlineTime = 0; playerObj.offlineTime += Math.min( playerObj.offlineTime + (Date.now() - playerObj.time) / 1000, diff --git a/src/util/vue.tsx b/src/util/vue.tsx index 750672f..089b465 100644 --- a/src/util/vue.tsx +++ b/src/util/vue.tsx @@ -229,7 +229,10 @@ export function computeOptionalComponent( const comp = shallowRef<Component | "" | null>(null); watchEffect(() => { const currComponent = unwrapRef(component); - comp.value = !currComponent ? null : coerceComponent(currComponent, defaultWrapper); + comp.value = + currComponent == "" || currComponent == null + ? null + : coerceComponent(currComponent, defaultWrapper); }); return comp; }