From 97774bc319ee71be50c27226d10d1c4cd845cace Mon Sep 17 00:00:00 2001 From: ducdat0507 <62660527+ducdat0507@users.noreply.github.com> Date: Sat, 24 Dec 2022 13:13:23 +0700 Subject: [PATCH 01/28] Fix factory not working at full spped at high tick rate --- src/data/layers/factory.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/data/layers/factory.tsx b/src/data/layers/factory.tsx index 39d2e7d..d9d5a51 100644 --- a/src/data/layers/factory.tsx +++ b/src/data/layers/factory.tsx @@ -101,9 +101,6 @@ const toyGoal = 750; const advancedToyGoal = 1500; const presentsGoal = 8e9; -// 20x20 block size -// TODO: unhardcode stuff - function roundDownTo(num: number, multiple: number) { return Math.floor((num + multiple / 2) / multiple) * multiple; } @@ -1641,6 +1638,7 @@ const factory = createLayer(id, () => { const compData = _compData as FactoryInternalProcessor; // factory part // PRODUCTION + data.ticksDone += factoryTicks; if (data.ticksDone >= factoryData.tick) { if (compData.canProduce.value) { const cyclesDone = Math.floor(data.ticksDone / factoryData.tick); @@ -1678,8 +1676,6 @@ const factory = createLayer(id, () => { if (compData.lastProdTimes.length > 10) compData.lastProdTimes.shift(); compData.lastFactoryProd = now; } - } else { - data.ticksDone += factoryTicks; } // now look at each component direction and see if it accepts items coming in // components are 1x1 so simple math for now From a72d8c720b9ed16574d1a282d3d07f3614e378d5 Mon Sep 17 00:00:00 2001 From: thepaperpilot Date: Sat, 24 Dec 2022 00:18:58 -0600 Subject: [PATCH 02/28] Make Christmas open automatically --- src/data/Day.vue | 6 +- src/data/projEntry.tsx | 245 ++++++++++++++++++++++------------------- 2 files changed, 138 insertions(+), 113 deletions(-) diff --git a/src/data/Day.vue b/src/data/Day.vue index a63ccc3..e47cb60 100644 --- a/src/data/Day.vue +++ b/src/data/Day.vue @@ -6,7 +6,7 @@ masteryLock, wallpaper: day < 8 }" - v-if="opened.value" + v-if="opened.value && visibility !== Visibility.None" >
@@ -26,7 +26,7 @@
import Notif from "components/Notif.vue"; +import { Visibility } from "features/feature"; import Tooltip from "features/tooltips/Tooltip.vue"; import { layers } from "game/layers"; import Decimal from "util/bignum"; @@ -66,6 +67,7 @@ const props = defineProps<{ recentlyUpdated: Ref; shouldNotify: ProcessedComputable; mastered: Ref; + visibility?: Visibility; }>(); const emit = defineEmits<{ diff --git a/src/data/projEntry.tsx b/src/data/projEntry.tsx index 6cd4fdd..0a79fac 100644 --- a/src/data/projEntry.tsx +++ b/src/data/projEntry.tsx @@ -4,7 +4,8 @@ import { Component, GatherProps, GenericComponent, - jsx + jsx, + Visibility } from "features/feature"; import { BaseLayer, createLayer, GenericLayer, layers } from "game/layers"; import { isPersistent, Persistent, persistent } from "game/persistence"; @@ -15,7 +16,7 @@ import { Computable, convertComputable, ProcessedComputable } from "util/compute import { createLazyProxy } from "util/proxies"; import { save } from "util/save"; import { render, renderRow, VueFeature } from "util/vue"; -import type { Ref } from "vue"; +import { Ref, watchEffect } from "vue"; import { computed, ref, unref } from "vue"; import "./advent.css"; import Day from "./Day.vue"; @@ -60,7 +61,7 @@ import toysSymbol from "./symbols/truck.png"; import advManagementSymbol from "./symbols/workshopMansion.png"; import wrappingPaperSymbol from "./symbols/wrappingPaper.png"; import snowflakeSymbol from "./symbols/snowflake.svg"; -import presentSymbol from "./layers/factory-components/present.svg" +import presentSymbol from "./layers/factory-components/present.svg"; import { createParticles } from "features/particles/particles"; import { credits } from "./credits"; @@ -74,6 +75,7 @@ export interface Day extends VueFeature { opened: Persistent; recentlyUpdated: Ref; // Has the tab recieved an update since the player last opened it? shouldNotify: ProcessedComputable; + visibility?: Visibility; } export const main = createLayer("main", function (this: BaseLayer) { @@ -96,112 +98,113 @@ export const main = createLayer("main", function (this: BaseLayer) { this.boundingRect.value = boundingRect; }, style: "z-index: -1" - })) + })); - particles.addEmitter({ - lifetime: {min: 5, max: 5}, - pos: {x: 0, y: 0}, - frequency: 0.05, - behaviors: [ - { - type: 'alpha', - config: { - alpha: { - list: [ - { - value: 1, - time: 0 - }, - { - value: 1, - time: 1 - } - ], - }, - } - }, - { - type: 'scale', - config: { - scale: { - list: [ - { - value: 1, - time: 0 - }, - { - value: 1, - time: 1 - } - ], - }, - } - }, - { - type: 'color', - config: { - color: { - list: [ - { - value: "fb1010", - time: 0 - }, - { - value: "f5b830", - time: 1 - } - ], - }, - } - }, - { - type: 'moveSpeed', - config: { - speed: { - list: [ - { - value: 200, - time: 0 - }, - { - value: 100, - time: 1 - } - ], - isStepped: false - }, - } - }, - { - type: 'rotationStatic', - config: { - min: 70, - max: 110 - } - }, - { - type: 'spawnShape', - config: { - type: 'rect', - data: { - x: 0, - y: 0, - width: 800, - height: 10 + particles + .addEmitter({ + lifetime: { min: 5, max: 5 }, + pos: { x: 0, y: 0 }, + frequency: 0.05, + behaviors: [ + { + type: "alpha", + config: { + alpha: { + list: [ + { + value: 1, + time: 0 + }, + { + value: 1, + time: 1 + } + ] + } + } + }, + { + type: "scale", + config: { + scale: { + list: [ + { + value: 1, + time: 0 + }, + { + value: 1, + time: 1 + } + ] + } + } + }, + { + type: "color", + config: { + color: { + list: [ + { + value: "fb1010", + time: 0 + }, + { + value: "f5b830", + time: 1 + } + ] + } + } + }, + { + type: "moveSpeed", + config: { + speed: { + list: [ + { + value: 200, + time: 0 + }, + { + value: 100, + time: 1 + } + ], + isStepped: false + } + } + }, + { + type: "rotationStatic", + config: { + min: 70, + max: 110 + } + }, + { + type: "spawnShape", + config: { + type: "rect", + data: { + x: 0, + y: 0, + width: 800, + height: 10 + } + } + }, + { + type: "textureSingle", + config: { + texture: snowflakeSymbol } } - }, - { - type: 'textureSingle', - config: { - texture: snowflakeSymbol - } - } - ] - }).then(e => { - e.autoUpdate = true; - }) - + ] + }) + .then(e => { + e.autoUpdate = true; + }); const currentlyMastering = computed(() => isMastery.value @@ -285,6 +288,7 @@ export const main = createLayer("main", function (this: BaseLayer) { story: string; completedStory: string; masteredStory: string; + visibility?: Visibility; } ): Day { const opened = persistent(false); @@ -314,7 +318,8 @@ export const main = createLayer("main", function (this: BaseLayer) { story, completedStory, masteredStory, - recentlyUpdated + recentlyUpdated, + visibility } = this; const mastered: Ref = @@ -327,6 +332,7 @@ export const main = createLayer("main", function (this: BaseLayer) { recentlyUpdated, shouldNotify, mastered, + visibility, onOpenLore() { const completed = main.day.value > day; loreScene.value = completed ? day - 1 : -1; @@ -370,7 +376,10 @@ export const main = createLayer("main", function (this: BaseLayer) { opened.value = true; setTimeout(() => { loreScene.value = -1; - loreTitle.value = day == 25 ? "The End!" : unref(layers[layer ?? "trees"]?.name ?? ""); + loreTitle.value = + day == 25 + ? "The End!" + : unref(layers[layer ?? "trees"]?.name ?? ""); loreBody.value = story; if (player.autoPause) player.devSpeed = null; showLoreModal.value = true; @@ -638,9 +647,10 @@ export const main = createLayer("main", function (this: BaseLayer) { shouldNotify: false, layer: null, // credits symbol: snowflakeSymbol, - story: `It's Christmas. Thanks to your efforts, Santa has delivered all the presents to people all over the world. That is, all but one...


Open your present
`, + story: `It's Christmas. Thanks to your efforts, Santa has delivered all the presents to people all over the world. That is, all but one...


Open your present

`, completedStory: "", - masteredStory: "" + masteredStory: "", + visibility: Visibility.None })) ]; @@ -673,6 +683,15 @@ export const main = createLayer("main", function (this: BaseLayer) { } } + watchEffect(() => { + if (day.value === 25 && showLoreModal.value === false) { + loreScene.value = -1; + loreTitle.value = "Merry Christmas!"; + loreBody.value = days[day.value - 1].story; + showLoreModal.value = true; + } + }); + return { name: "Calendar", days, @@ -724,7 +743,11 @@ export const main = createLayer("main", function (this: BaseLayer) { ) .map((days: Day[]) => renderRow(...days))}
- {render(particles) /*creditsOpen.value || day.value == 25 ? render(particles) : null*/} + { + render( + particles + ) /*creditsOpen.value || day.value == 25 ? render(particles) : null*/ + } )) }; From 11d3e05e03d797242ee80f873cf63e859386458e Mon Sep 17 00:00:00 2001 From: ducdat0507 <62660527+ducdat0507@users.noreply.github.com> Date: Sat, 24 Dec 2022 13:26:31 +0700 Subject: [PATCH 03/28] Batter efficiency colors --- src/data/layers/factory.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/data/layers/factory.tsx b/src/data/layers/factory.tsx index 2e67e78..3cbda96 100644 --- a/src/data/layers/factory.tsx +++ b/src/data/layers/factory.tsx @@ -2243,12 +2243,12 @@ const factory = createLayer(id, () => { style={{ color: (compInternalHovered.value as FactoryInternalProcessor) - .average.value! > 1 - ? "purple" + .average.value! >= 0.995 + ? "fuchsia" : ( compInternalHovered.value as FactoryInternalProcessor ).average.value! >= 0.9 - ? "green" + ? "lime" : ( compInternalHovered.value as FactoryInternalProcessor ).average.value! >= 0.5 From aa7fbccb348b0a14f5c9d48d539587e91e2cb5be Mon Sep 17 00:00:00 2001 From: thepaperpilot Date: Sat, 24 Dec 2022 00:26:50 -0600 Subject: [PATCH 04/28] After opening the present, win the game --- src/data/projEntry.tsx | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/data/projEntry.tsx b/src/data/projEntry.tsx index 0a79fac..f4d75f3 100644 --- a/src/data/projEntry.tsx +++ b/src/data/projEntry.tsx @@ -16,7 +16,7 @@ import { Computable, convertComputable, ProcessedComputable } from "util/compute import { createLazyProxy } from "util/proxies"; import { save } from "util/save"; import { render, renderRow, VueFeature } from "util/vue"; -import { Ref, watchEffect } from "vue"; +import { Ref, watch, watchEffect } from "vue"; import { computed, ref, unref } from "vue"; import "./advent.css"; import Day from "./Day.vue"; @@ -80,6 +80,8 @@ export interface Day extends VueFeature { export const main = createLayer("main", function (this: BaseLayer) { const day = persistent(1); + const hasWon = persistent(false); + const timeUntilNewDay = computed( () => (+new Date(new Date().getFullYear(), 11, day.value) - player.time) / 1000 ); @@ -684,11 +686,12 @@ export const main = createLayer("main", function (this: BaseLayer) { } watchEffect(() => { - if (day.value === 25 && showLoreModal.value === false) { + if (day.value === 25 && showLoreModal.value === false && !hasWon.value) { loreScene.value = -1; loreTitle.value = "Merry Christmas!"; loreBody.value = days[day.value - 1].story; showLoreModal.value = true; + hasWon.value = true; } }); @@ -713,6 +716,7 @@ export const main = createLayer("main", function (this: BaseLayer) { masteredDays, creditsOpen, credits, + hasWon, display: jsx(() => ( <> {player.devSpeed === 0 ?
Game Paused
: null} @@ -743,6 +747,18 @@ export const main = createLayer("main", function (this: BaseLayer) { ) .map((days: Day[]) => renderRow(...days))} + {hasWon.value ? ( + <> + + + + ) : null} { render( particles From dc6bf2714dd94953e7665a921cfe28bdb983c772 Mon Sep 17 00:00:00 2001 From: ducdat0507 <62660527+ducdat0507@users.noreply.github.com> Date: Sat, 24 Dec 2022 13:27:46 +0700 Subject: [PATCH 05/28] Fix sawmill visibility --- src/data/layers/factory.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/data/layers/factory.tsx b/src/data/layers/factory.tsx index 3cbda96..80f7a32 100644 --- a/src/data/layers/factory.tsx +++ b/src/data/layers/factory.tsx @@ -505,8 +505,7 @@ const factory = createLayer(id, () => { plank: { amount: computed(() => (upgrades[0][0].bought.value ? 2 : 1)) } - }, - visible: main.days[presentsDay - 1].opened + } } as FactoryComponentDeclaration, thread: { imageSrc: _threadMaker, From db075b9f16dd65c14bb4867c73ac4a1bd808df85 Mon Sep 17 00:00:00 2001 From: ducdat0507 <62660527+ducdat0507@users.noreply.github.com> Date: Sat, 24 Dec 2022 13:32:42 +0700 Subject: [PATCH 06/28] Fix box maker visibility --- src/data/layers/factory.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/data/layers/factory.tsx b/src/data/layers/factory.tsx index 80f7a32..b6e8db7 100644 --- a/src/data/layers/factory.tsx +++ b/src/data/layers/factory.tsx @@ -667,7 +667,8 @@ const factory = createLayer(id, () => { box: { amount: 2 } - } + }, + visible: main.days[presentsDay - 1].opened } as FactoryComponentDeclaration, blocks: { imageSrc: _blockMaker, From 9fc5ab090daef87cb5649d5d82a88919e37542a4 Mon Sep 17 00:00:00 2001 From: unsoftcapped3 <75136164+unsoftcapped3@users.noreply.github.com> Date: Sat, 24 Dec 2022 05:51:34 +0000 Subject: [PATCH 07/28] importing --- src/data/layers/metal.tsx | 1 + src/data/layers/plastic.tsx | 1 + src/data/layers/trees.tsx | 1 + 3 files changed, 3 insertions(+) diff --git a/src/data/layers/metal.tsx b/src/data/layers/metal.tsx index c6d338f..bf80c30 100644 --- a/src/data/layers/metal.tsx +++ b/src/data/layers/metal.tsx @@ -38,6 +38,7 @@ import workshop from "./workshop"; import wrappingPaper from "./wrapping-paper"; import toys from "./toys"; import reindeer from "./reindeer"; +import sleigh from "./sleigh"; const id = "metal"; const day = 7; diff --git a/src/data/layers/plastic.tsx b/src/data/layers/plastic.tsx index 4061179..3915031 100644 --- a/src/data/layers/plastic.tsx +++ b/src/data/layers/plastic.tsx @@ -38,6 +38,7 @@ import paper from "./paper"; import workshop from "./workshop"; import toys from "./toys"; import reindeer from "./reindeer"; +import sleigh from "./sleigh"; const id = "plastic"; const day = 10; diff --git a/src/data/layers/trees.tsx b/src/data/layers/trees.tsx index ef68f14..d121bcd 100644 --- a/src/data/layers/trees.tsx +++ b/src/data/layers/trees.tsx @@ -41,6 +41,7 @@ import wrappingPaper from "./wrapping-paper"; import toys from "./toys"; import factory from "./factory"; import reindeer from "./reindeer"; +import sleigh from "./sleigh"; const id = "trees"; const day = 1; From b51e8dac9dae7645d87ced9fe557d7c23d4ca68d Mon Sep 17 00:00:00 2001 From: unsoftcapped3 <75136164+unsoftcapped3@users.noreply.github.com> Date: Sat, 24 Dec 2022 06:15:29 +0000 Subject: [PATCH 08/28] finish balancing --- src/data/layers/metal.tsx | 15 +++++++++++++++ src/data/layers/plastic.tsx | 18 ++++++++++++++++++ src/data/layers/sleigh.tsx | 12 ++++++------ src/data/layers/trees.tsx | 10 ++++++++++ 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/data/layers/metal.tsx b/src/data/layers/metal.tsx index bf80c30..e74aeb1 100644 --- a/src/data/layers/metal.tsx +++ b/src/data/layers/metal.tsx @@ -112,6 +112,11 @@ const layer = createLayer(id, function (this: BaseLayer) { exponent: 1.1, description: "Mary Level 2", enabled: management.elfTraining.heatedPlanterElfTraining.milestones[1].earned + })), + createExponentialModifier(() => ({ + exponent: 1.2, + description: "100% Sleigh Fixed", + enabled: sleigh.milestones.milestone8.earned })) ]); const computedOrePurity = computed(() => orePurity.apply(0.1)); @@ -183,6 +188,11 @@ const layer = createLayer(id, function (this: BaseLayer) { description: "Jazzy Wrapping Paper", enabled: computed(() => Decimal.gt(wrappingPaper.boosts.jazzy1.value, 1)) })), + createMultiplicativeModifier(() => ({ + multiplier: 2, + description: "30% Sleigh Fixed", + enabled: sleigh.milestones.milestone4.earned + })), createAdditiveModifier(() => ({ addend: () => Decimal.sub(lastOreGained.value, lastOreSmelted.value).max(0), description: "Metal Decoration", @@ -292,6 +302,11 @@ const layer = createLayer(id, function (this: BaseLayer) { description: "1000 Letters Processed", enabled: letters.milestones.miningMilestone.earned })), + createMultiplicativeModifier(() => ({ + multiplier: 2, + description: "30% Sleigh Fixed", + enabled: sleigh.milestones.milestone4.earned + })), createMultiplicativeModifier(() => ({ multiplier: () => Decimal.add(toys.clothes.value, 1), description: "Give elves clothes to wear", diff --git a/src/data/layers/plastic.tsx b/src/data/layers/plastic.tsx index 3915031..6023a10 100644 --- a/src/data/layers/plastic.tsx +++ b/src/data/layers/plastic.tsx @@ -321,6 +321,14 @@ const layer = createLayer(id, function (this: BaseLayer) { description: "Oil Refinery", enabled: () => Decimal.gt(activeRefinery.value, 0) })), + createAdditiveModifier(() => ({ + addend: () => + management.elfTraining.oilElfTraining.milestones[3].earned.value + ? Decimal.times(Decimal.div(sleigh.sleighProgress.value.value,2).floor(), 200) + : Decimal.times(activeRefinery.value, 40), + description: "75% Sleigh Fixed", + enabled: sleigh.milestones.milestone7.earned + })), createMultiplicativeModifier(() => ({ multiplier: 2, description: "Paper Elf Recruitment", @@ -386,6 +394,16 @@ const layer = createLayer(id, function (this: BaseLayer) { multiplier: () => dyes.boosts.white1.value, description: "White Dye Boost" })), + createMultiplicativeModifier(() => ({ + multiplier: () => Decimal.div(sleigh.sleighProgress.value.value, 5).floor().mul(0.05).add(1), + description: "20% Sleigh Fixed", + enabled: sleigh.milestones.milestone3.earned + })), + createMultiplicativeModifier(() => ({ + multiplier: 4, + description: "40% Sleigh Fixed", + enabled: sleigh.milestones.milestone5.earned + })), reindeer.reindeer.blitzen.modifier ]); const computedPlasticGain = computed(() => plasticGain.apply(0)); diff --git a/src/data/layers/sleigh.tsx b/src/data/layers/sleigh.tsx index 93247e9..35bfc71 100644 --- a/src/data/layers/sleigh.tsx +++ b/src/data/layers/sleigh.tsx @@ -43,9 +43,9 @@ const layer = createLayer(id, function (this: BaseLayer) { const sleighCost = computed(() => { let v = sleighProgress.value.value; return { - wood: Decimal.mul(1e60, Decimal.pow(1.2, v)), - metal: Decimal.mul(1e40, Decimal.pow(1.1, v)), - plastic: Decimal.mul(1e10, Decimal.pow(1.05, v)) + wood: Decimal.mul(1e97, Decimal.pow(1.2, v)), + metal: Decimal.mul(1e67, Decimal.pow(1.1, v)), + plastic: Decimal.mul(1e22, Decimal.pow(1.05, v)) }; }); const sleigh = createBuyable(() => ({ @@ -55,7 +55,7 @@ const layer = createLayer(id, function (this: BaseLayer) {

- Cost: {displayCost(trees.logs, sleighCost.value.wood, "logs")}, + Requires: {displayCost(trees.logs, sleighCost.value.wood, "logs")}, {displayCost(metal.metal, sleighCost.value.metal, "metal")}, {displayCost(plastic.plastic, sleighCost.value.plastic, "plastic")} @@ -111,7 +111,7 @@ const layer = createLayer(id, function (this: BaseLayer) { const milestone5 = createMilestone(() => ({ display: { requirement: "40% Sleigh Fixed", - effectDisplay: "Plastic gain is doubled" + effectDisplay: "Plastic gain is quadrupled" }, shouldEarn: () => Decimal.gte(sleighProgress.value.value, 40), showPopups: shouldShowPopups @@ -127,7 +127,7 @@ const layer = createLayer(id, function (this: BaseLayer) { const milestone7 = createMilestone(() => ({ display: { requirement: "75% Sleigh Fixed", - effectDisplay: "Gain 10 extra refineries for every 2% of sleigh fixed" + effectDisplay: "Gain 40 extra refineries for every 2% of sleigh fixed" }, shouldEarn: () => Decimal.gte(sleighProgress.value.value, 75), showPopups: shouldShowPopups diff --git a/src/data/layers/trees.tsx b/src/data/layers/trees.tsx index d121bcd..a0cdfed 100644 --- a/src/data/layers/trees.tsx +++ b/src/data/layers/trees.tsx @@ -559,6 +559,16 @@ const layer = createLayer(id, function (this: BaseLayer) { description: "Haul wood in trucks", enabled: factory.upgrades[0][2].bought })), + createMultiplicativeModifier(() => ({ + multiplier: () => Decimal.div(sleigh.sleighProgress.value.value, 5).floor().mul(0.05).add(1), + description: "10% Sleigh Fixed", + enabled: sleigh.milestones.milestone2.earned + })), + createMultiplicativeModifier(() => ({ + multiplier: 10, + description: "50% Sleigh Fixed", + enabled: sleigh.milestones.milestone6.earned + })), reindeer.reindeer.dasher.modifier, createExponentialModifier(() => ({ exponent: 1.2, From 332fadc7ee7db507f6fefbd8419e44e792ca8ab0 Mon Sep 17 00:00:00 2001 From: thepaperpilot Date: Sat, 24 Dec 2022 00:34:18 -0600 Subject: [PATCH 09/28] Add art and lore --- src/data/Scene.vue | 7 +++++++ src/data/layers/reindeer.tsx | 4 ++-- src/data/projEntry.tsx | 10 ++++++---- src/data/symbols/sleigh.png | Bin 0 -> 68911 bytes 4 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 src/data/symbols/sleigh.png diff --git a/src/data/Scene.vue b/src/data/Scene.vue index 8dc001f..28ed3ec 100644 --- a/src/data/Scene.vue +++ b/src/data/Scene.vue @@ -19,6 +19,12 @@ class="scene-item" style="left: 26%; bottom: 12%; width: 40px; height: 40px" /> + 10); function focus() { + currCooldown.value = Decimal.fromValue(computedMaxCooldown.value).toNumber(); let targetsSelected = 0; currTargets.value = {}; timeSinceFocus.value = 0; @@ -141,7 +142,6 @@ const layer = createLayer(id, function (this: BaseLayer) { }, canClick: () => Decimal.eq(currCooldown.value, 0), onClick() { - currCooldown.value = Decimal.fromValue(computedMaxCooldown.value).toNumber(); focus(); } })); @@ -488,7 +488,7 @@ const layer = createLayer(id, function (this: BaseLayer) { let auto = false; if (upgrade7.bought.value) { timeSinceFocus.value += diff; - if (timeSinceFocus.value > 10) { + if (timeSinceFocus.value > 20) { auto = true; } } diff --git a/src/data/projEntry.tsx b/src/data/projEntry.tsx index 25fcfaf..dd3fd88 100644 --- a/src/data/projEntry.tsx +++ b/src/data/projEntry.tsx @@ -59,6 +59,7 @@ import treeSymbol from "./symbols/tree.png"; import toysSymbol from "./symbols/truck.png"; import advManagementSymbol from "./symbols/workshopMansion.png"; import wrappingPaperSymbol from "./symbols/wrappingPaper.png"; +import sleighSymbol from "./symbols/sleigh.png"; export interface Day extends VueFeature { day: number; @@ -488,10 +489,11 @@ export const main = createLayer("main", function (this: BaseLayer) { createDay(() => ({ day: 22, shouldNotify: false, - layer: "sleigh", // "sleigh" - symbol: "", - story: "default body", - completedStory: "", + layer: "sleigh", + symbol: sleighSymbol, + story: "You realize you haven't noticed a very important object since you've started working here. Where's the sleigh? You bring it up to Santa and he immediately becomes visibly stressed, mentioning it's been in disrepair and he completely forgot! You promise you'll get it back in shape in no time!", + completedStory: + "Crisis averted! The sleigh has been returned to it's full splendor. Santa is incredibly appreciative. Good Job!", masteredStory: "" })), createDay(() => ({ diff --git a/src/data/symbols/sleigh.png b/src/data/symbols/sleigh.png new file mode 100644 index 0000000000000000000000000000000000000000..644cf63861d7cda22f8ab6b59451f5f4b84644f9 GIT binary patch literal 68911 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�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 literal 0 HcmV?d00001 From f5d29ed117c4a80a983b1d0c9cb822302e7a719e Mon Sep 17 00:00:00 2001 From: thepaperpilot Date: Fri, 23 Dec 2022 09:06:21 -0600 Subject: [PATCH 10/28] Add layer stuff --- src/data/layers/routing.tsx | 589 ++++++++++++++++++++++++++++++++++++ src/data/projEntry.tsx | 11 +- 2 files changed, 596 insertions(+), 4 deletions(-) create mode 100644 src/data/layers/routing.tsx diff --git a/src/data/layers/routing.tsx b/src/data/layers/routing.tsx new file mode 100644 index 0000000..73d220b --- /dev/null +++ b/src/data/layers/routing.tsx @@ -0,0 +1,589 @@ +/** + * @module + * @hidden + */ +import HotkeyVue from "components/Hotkey.vue"; +import Spacer from "components/layout/Spacer.vue"; +import Modal from "components/Modal.vue"; +import { createCollapsibleModifierSections } from "data/common"; +import { main } from "data/projEntry"; +import { createBar, GenericBar } from "features/bars/bar"; +import { createClickable } from "features/clickables/clickable"; +import { jsx } from "features/feature"; +import { createHotkey, GenericHotkey } from "features/hotkey"; +import { createUpgrade } from "features/upgrades/upgrade"; +import { globalBus } from "game/events"; +import { BaseLayer, createLayer } from "game/layers"; +import { + createAdditiveModifier, + createMultiplicativeModifier, + createSequentialModifier +} from "game/modifiers"; +import { persistent } from "game/persistence"; +import Decimal, { DecimalSource, format, formatTime, formatWhole } from "util/bignum"; +import { Direction } from "util/common"; +import { render, renderGrid } from "util/vue"; +import { computed, ref, unref, watchEffect } from "vue"; +import boxes from "./boxes"; +import cloth from "./cloth"; +import coal from "./coal"; +import dyes from "./dyes"; +import metal from "./metal"; +import oil from "./oil"; +import paper from "./paper"; +import plastic from "./plastic"; +import "./styles/reindeer.css"; +import trees from "./trees"; + +const id = "routing"; +const day = 23; +const layer = createLayer(id, function (this: BaseLayer) { + const name = "Routing"; + const color = "navajowhite"; + + const feedGoal = 2.5e3; + + const timeSinceFocus = persistent(0); + + const currMultiplier = persistent(1); + const currTargets = persistent>({}); + const currCooldown = persistent(0); + const crit = persistent(0); + + const maxMultiplier = createSequentialModifier(() => [ + createMultiplicativeModifier(() => ({ + multiplier: 2, + description: "Carry food in boxes", + enabled: upgrade4.bought + })) + ]); + const computedMaxMultiplier = computed(() => maxMultiplier.apply(2)); + const targetsCount = createSequentialModifier(() => [ + createAdditiveModifier(() => ({ + addend: 1, + description: "Guide to Reindeer Handling", + enabled: upgrade3.bought + })), + createAdditiveModifier(() => ({ + addend: crit, + description: "Metal clapper", + enabled: upgrade5.bought + })) + ]); + const computedTargetsCount = computed(() => targetsCount.apply(1)); + const computedMaxCooldown = computed(() => 10); + + function focus() { + let targetsSelected = 0; + currTargets.value = {}; + timeSinceFocus.value = 0; + while (Decimal.gt(computedTargetsCount.value, targetsSelected)) { + const selectedReindeer = + Object.values(reindeer)[Math.floor(Math.random() * Object.values(reindeer).length)]; + const roll = selectedReindeer?.name ?? ""; + if (!currTargets.value[roll]) { + currTargets.value[roll] = true; + targetsSelected++; + } + } + } + + const focusMeter = createBar(() => ({ + direction: Direction.Right, + width: 476, + height: 50, + style: `border-radius: 0`, + borderStyle: `border-radius: 0`, + fillStyle: () => ({ + background: currCooldown.value > 0 ? color : "#7f7f00", + animation: currCooldown.value > 0 ? "1s focused-eating-bar linear infinite" : "", + opacity: currCooldown.value > 0 ? currCooldown.value / 10 : 1, + transition: "none" + }), + progress: () => + Decimal.sub(currMultiplier.value, 1) + .div(Decimal.sub(computedMaxMultiplier.value, 1)) + .toNumber(), + display: jsx(() => ( + <> + {format(currMultiplier.value)}x + {currCooldown.value > 0 ? ( + <> + {" "} + to {Object.keys(currTargets.value).join(", ")} for{" "} + {formatTime(currCooldown.value)} + + ) : ( + "" + )} + + )) + })) as GenericBar; + + const focusButton = createClickable(() => ({ + display: { + title: "Focus", + description: jsx(() => ( + <> + Motivate reindeer to eat, multiplying {formatWhole(computedTargetsCount.value)}{" "} + random reindeer's eating rate by up to {format(computedMaxMultiplier.value)}x + for {formatTime(computedMaxCooldown.value)}, equal to the focus bar's effect. + + )) + }, + style: { + width: "480px", + minHeight: "80px", + zIndex: 4 + }, + canClick: () => Decimal.eq(currCooldown.value, 0), + onClick() { + currCooldown.value = Decimal.fromValue(computedMaxCooldown.value).toNumber(); + focus(); + } + })); + + const cooldown = createSequentialModifier(() => [ + createMultiplicativeModifier(() => ({ + multiplier: 0.5, + description: "Pile of coal", + enabled: upgrade2.bought + })) + ]); + const computedCooldown = computed(() => cooldown.apply(10)); + + function createReindeer(options: { + name: string; + key: string; + boostDescription: string; + boostAmount: DecimalSource; + }) { + const timesFed = persistent(0); + const progress = persistent(0); + + const hotkey = createHotkey(() => ({ + key: "Numpad " + options.key, + description: "Feed " + options.name, + enabled: main.days[day - 1].opened, + onPress: clickable.onClick + })) as GenericHotkey; + + const clickable = createClickable(() => { + const progressBar = createBar(() => ({ + direction: Direction.Right, + width: 140, + height: 10, + style: "margin-top: 8px", + borderStyle: "border-color: black", + baseStyle: "margin-top: -1px", + fillStyle: () => ({ + marginTop: "-1px", + transitionDuration: "0s", + background: "black", + animation: + currTargets.value[options.name] && currCooldown.value > 0 + ? ".5s focused-eating-bar linear infinite" + : "" + }), + progress: () => Decimal.div(progress.value, computedCooldown.value) + })); + + const modifier = createMultiplicativeModifier(() => ({ + multiplier: effect, + description: options.name, + enabled: () => Decimal.gt(timesFed.value, 0) + })); + + const effect = computed(() => + Decimal.times(options.boostAmount, timesFed.value) + .add(1) + .pow(upgrade9.bought.value ? 1.1 : 1) + ); + + return { + ...options, + hotkey, + timesFed, + progress, + effect, + modifier, + display: { + title: jsx(() => ( +

+ Feed {options.name} +

+ )), + description: jsx(() => ( + <> +
+ Each time you feed {options.name} will increase your{" "} + {options.boostDescription} by +{format(options.boostAmount)}x + + Currently {format(effect.value)}x +
+ {render(progressBar)} + + )) + }, + style: { + width: "160px", + height: "160px" + }, + canClick() { + return Decimal.gte(progress.value, computedCooldown.value); + }, + onClick() { + if (!unref(clickable.canClick)) { + return; + } + let amount = Decimal.div(progress.value, computedCooldown.value); + if (upgrade1.bought.value) { + amount = Decimal.times(amount, 2); + } + timesFed.value = Decimal.add(timesFed.value, amount); + progress.value = 0; + }, + update(diff: number) { + if (Decimal.gte(progress.value, computedCooldown.value)) { + progress.value = computedCooldown.value; + } else { + let amount: DecimalSource = diff; + const isFocused = currTargets.value[options.name] && currCooldown.value > 0; + if (isFocused) { + amount = Decimal.times(amount, currMultiplier.value); + } + progress.value = Decimal.add(progress.value, amount); + if (clickable.isHolding.value || (upgrade8.bought.value && isFocused)) { + clickable.onClick(); + } + } + } + }; + }); + return clickable; + } + const dasher = createReindeer({ + name: "Dasher", + key: "7", + boostDescription: "log gain", + boostAmount: 1 + }); + const dancer = createReindeer({ + name: "Dancer", + key: "8", + boostDescription: "coal gain", + boostAmount: 0.1 + }); + const prancer = createReindeer({ + name: "Prancer", + key: "9", + boostDescription: "paper gain", + boostAmount: 0.1 + }); + const vixen = createReindeer({ + name: "Vixen", + key: "4", + boostDescription: "boxes gain", + boostAmount: 0.1 + }); + const comet = createReindeer({ + name: "Comet", + key: "5", + boostDescription: "metal gain", + boostAmount: 0.1 + }); + const cupid = createReindeer({ + name: "Cupid", + key: "6", + boostDescription: "cloth actions", + boostAmount: 0.1 + }); + const donner = createReindeer({ + name: "Donner", + key: "1", + boostDescription: "oil gain", + boostAmount: 0.01 + }); + const blitzen = createReindeer({ + name: "Blitzen", + key: "2", + boostDescription: "plastic gain", + boostAmount: 0.1 + }); + const rudolph = createReindeer({ + name: "Rudolph", + key: "3", + boostDescription: "dye gain", + boostAmount: 0.01 + }); + // order is designed so hotkeys appear 1-9, even though they're displayed in numpad order in the layer itself + const reindeer = { donner, blitzen, rudolph, vixen, comet, cupid, dasher, dancer, prancer }; + + const sumTimesFed = computed(() => + Object.values(reindeer) + .map(r => r.timesFed.value) + .reduce(Decimal.add, Decimal.dZero) + ); + + const upgrade1 = createUpgrade(() => ({ + resource: trees.logs, + cost: 0, + style: { + width: "160px" + }, + display: { + title: "Sawdust?", + description: + "Adding some sawdust to the feed allows you to make more of it. Each feed action counts twice" + } + })); + const upgrade2 = createUpgrade(() => ({ + resource: coal.coal, + cost: 0, + style: { + width: "160px" + }, + display: { + title: "Pile of coal", + description: + "Building a threatening pile of coal encourages the reindeer to behave. Each reindeer eats twice as fast" + } + })); + const upgrade3 = createUpgrade(() => ({ + resource: paper.paper, + cost: 0, + style: { + width: "160px" + }, + display: { + title: "Guide to Reindeer Handling", + description: + "Written reindeer handling instructions allow you to help more focus at once. Increase focus targets by one" + } + })); + const upgrade4 = createUpgrade(() => ({ + resource: boxes.boxes, + cost: 0, + style: { + width: "160px" + }, + display: { + title: "Carry food in boxes", + description: + "Carrying reindeer food in boxes allows you to distribute it faster. Double the maximum focus multiplier" + } + })); + const upgrade5 = createUpgrade(() => ({ + resource: metal.metal, + cost: 0, + style: { + width: "160px" + }, + display: { + title: "Metal clapper", + description: + 'Striking two rods of metal can help get more reindeer\'s attention when done right. "Critical" focuses now affect up to two additional reindeer' + } + })); + const upgrade6 = createUpgrade(() => ({ + resource: cloth.cloth, + cost: 0, + style: { + width: "160px" + }, + display: { + title: "Focus bar padding", + description: + "Adding padding to the focus bar lets you slow it down when it's closer to the max value" + } + })); + const upgrade7 = createUpgrade(() => ({ + resource: oil.oil, + cost: 0, + style: { + width: "160px" + }, + display: { + title: "Oil can do that?", + description: + "Using a lot of oil somehow let's reindeers focus themselves with a random value when left un-focused for 10s" + } + })); + const upgrade8 = createUpgrade(() => ({ + resource: plastic.plastic, + cost: 0, + style: { + width: "160px" + }, + display: { + title: "Autoamted feeder", + description: "An automated feeder let's focused reindeer eat automatically" + } + })); + const upgrade9 = createUpgrade(() => ({ + resource: dyes.dyes.white.amount, + cost: 0, + style: { + width: "160px" + }, + display: { + title: "Colorful food", + description: + "Adding some non-toxic dyes to the food makes them more powerful. Raise each reindeer's effect to the ^1.1" + } + })); + const upgrades = { + upgrade1, + upgrade2, + upgrade3, + upgrade4, + upgrade5, + upgrade6, + upgrade7, + upgrade8, + upgrade9 + }; + + const [generalTab, generalTabCollapsed] = createCollapsibleModifierSections(() => [ + { + title: "Max Focus Multiplier", + modifier: maxMultiplier, + base: 2 + }, + { + title: "Focus Targets", + modifier: targetsCount, + base: 1 + }, + { + title: "Eating duration", + modifier: cooldown, + base: 10 + } + ]); + const showModifiersModal = ref(false); + const modifiersModal = jsx(() => ( + (showModifiersModal.value = value)} + v-slots={{ + header: () =>

{name} Modifiers

, + body: generalTab + }} + /> + )); + + globalBus.on("update", diff => { + if (Decimal.lt(main.day.value, day)) { + return; + } + + Object.values(reindeer).forEach(reindeer => reindeer.update(diff)); + + currCooldown.value = Math.max(currCooldown.value - diff, 0); + + let auto = false; + if (upgrade7.bought.value) { + timeSinceFocus.value += diff; + if (timeSinceFocus.value > 10) { + auto = true; + } + } + + if (Decimal.eq(currCooldown.value, 0)) { + let speed = 1000; + if (auto) { + speed = Math.random() * 1000; + } + let stoppedAt = 1 - Math.abs(Math.sin((Date.now() / speed) * 2)); + if (upgrade6.bought.value) { + stoppedAt = 1 - (1 - stoppedAt) ** 2; + } + crit.value = stoppedAt > 0.975 ? 2 : stoppedAt > 0.9 ? 1 : 0; + currMultiplier.value = Decimal.pow(computedMaxMultiplier.value, stoppedAt); + if (auto) { + focus(); + } + } + }); + + const dayProgress = createBar(() => ({ + direction: Direction.Right, + width: 600, + height: 25, + fillStyle: `backgroundColor: ${color}`, + progress: () => (main.day.value === day ? Decimal.div(sumTimesFed.value, feedGoal) : 1), + display: jsx(() => + main.day.value === day ? ( + <> + {formatWhole(sumTimesFed.value)}/{formatWhole(feedGoal)} + + ) : ( + "" + ) + ) + })) as GenericBar; + + watchEffect(() => { + if (main.day.value === day && Decimal.gte(sumTimesFed.value, feedGoal)) { + main.completeDay(); + } + }); + + return { + name, + day, + color, + reindeer, + generalTabCollapsed, + timeSinceFocus, + currMultiplier, + currTargets, + currCooldown, + upgrades, + crit, + minWidth: 700, + display: jsx(() => ( + <> +
+ {main.day.value === day + ? `Feed reindeer ${formatWhole(feedGoal)} times to complete the day` + : `${name} Complete!`}{" "} + -{" "} + +
+ {render(dayProgress)} + {render(modifiersModal)} + +
You have fed reindeer {formatWhole(sumTimesFed.value)} times
+ + {renderGrid( + [focusButton], + [focusMeter], + [dasher, dancer, prancer], + [vixen, comet, cupid], + [donner, blitzen, rudolph] + )} + + {renderGrid( + [upgrade1, upgrade2, upgrade3], + [upgrade4, upgrade5, upgrade6], + [upgrade7, upgrade8, upgrade9] + )} + + )), + minimizedDisplay: jsx(() => ( +
+ {name} {format(sumTimesFed.value)} times fed +
+ )) + }; +}); + +export default layer; diff --git a/src/data/projEntry.tsx b/src/data/projEntry.tsx index dd3fd88..60c526f 100644 --- a/src/data/projEntry.tsx +++ b/src/data/projEntry.tsx @@ -33,6 +33,7 @@ import paper from "./layers/paper"; import plastic from "./layers/plastic"; import reindeer from "./layers/reindeer"; import ribbon from "./layers/ribbon"; +import routing from "./layers/routing"; import toys from "./layers/toys"; import trees from "./layers/trees"; import workshop from "./layers/workshop"; @@ -499,10 +500,11 @@ export const main = createLayer("main", function (this: BaseLayer) { createDay(() => ({ day: 23, shouldNotify: false, - layer: null, // "distribution route planning" + layer: "routing", symbol: "", - story: "", - completedStory: "", + story: "You're almost ready for the big day! The next step is to find an optimal route to ensure you can get all the presents delivered before kids start waking up! This is like the travelling salesman problem on steroids. Good Luck!", + completedStory: + "Take that, math majors! Optimal route planned with time to spare. Good Job!", masteredStory: "" })), createDay(() => ({ @@ -625,7 +627,8 @@ export const getInitialLayers = ( toys, factory, reindeer, - sleigh + sleigh, + routing ]; /** From 4db49e3e410b225ebe68f2a0e927f8f352d1c420 Mon Sep 17 00:00:00 2001 From: thepaperpilot Date: Fri, 23 Dec 2022 11:27:35 -0600 Subject: [PATCH 11/28] Make boards take state and link overrides --- src/features/boards/board.ts | 78 +++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 27 deletions(-) diff --git a/src/features/boards/board.ts b/src/features/boards/board.ts index 4763993..689659d 100644 --- a/src/features/boards/board.ts +++ b/src/features/boards/board.ts @@ -9,7 +9,7 @@ import { Visibility } from "features/feature"; import { globalBus } from "game/events"; -import type { Persistent, State } from "game/persistence"; +import { DefaultValue, deletePersistent, Persistent, State } from "game/persistence"; import { persistent } from "game/persistence"; import type { Unsubscribe } from "nanoevents"; import { isFunction } from "util/common"; @@ -167,12 +167,12 @@ export interface BoardOptions { style?: Computable; startNodes: () => Omit[]; types: Record; + state?: Computable; + links?: Computable; } export interface BaseBoard { id: string; - state: Persistent; - links: Ref; nodes: Ref; selectedNode: Ref; selectedAction: Ref; @@ -191,6 +191,8 @@ export type Board = Replace< width: GetComputableType; classes: GetComputableType; style: GetComputableType; + state: GetComputableTypeWithDefault>; + links: GetComputableTypeWithDefault>; } >; @@ -198,31 +200,46 @@ export type GenericBoard = Replace< Board, { visibility: ProcessedComputable; + state: ProcessedComputable; + links: ProcessedComputable; } >; export function createBoard( optionsFunc: OptionsFunc ): Board { + const state = persistent({ + nodes: [], + selectedNode: null, + selectedAction: null + }); + return createLazyProxy(() => { const board = optionsFunc(); board.id = getUniqueID("board-"); board.type = BoardType; board[Component] = BoardComponent; - board.state = persistent({ - nodes: board.startNodes().map((n, i) => { - (n as BoardNode).id = i; - return n as BoardNode; - }), - selectedNode: null, - selectedAction: null - }); - board.nodes = computed(() => processedBoard.state.value.nodes); + if (board.state) { + deletePersistent(state); + processComputable(board as T, "state"); + } else { + state[DefaultValue] = { + nodes: board.startNodes().map((n, i) => { + (n as BoardNode).id = i; + return n as BoardNode; + }), + selectedNode: null, + selectedAction: null + }; + board.state = state; + } + + board.nodes = computed(() => unref(processedBoard.state).nodes); board.selectedNode = computed( () => processedBoard.nodes.value.find( - node => node.id === processedBoard.state.value.selectedNode + node => node.id === unref(processedBoard.state).selectedNode ) || null ); board.selectedAction = computed(() => { @@ -236,23 +253,30 @@ export function createBoard( } return ( type.actions.find( - action => action.id === processedBoard.state.value.selectedAction + action => action.id === unref(processedBoard.state).selectedAction ) || null ); }); board.mousePosition = ref(null); - board.links = computed(() => { - if (processedBoard.selectedAction.value == null) { - return null; - } - if (processedBoard.selectedAction.value.links && processedBoard.selectedNode.value) { - return getNodeProperty( - processedBoard.selectedAction.value.links, + if (board.links) { + processComputable(board as T, "links"); + } else { + board.links = computed(() => { + if (processedBoard.selectedAction.value == null) { + return null; + } + if ( + processedBoard.selectedAction.value.links && processedBoard.selectedNode.value - ); - } - return null; - }); + ) { + return getNodeProperty( + processedBoard.selectedAction.value.links, + processedBoard.selectedNode.value + ); + } + return null; + }); + } processComputable(board as T, "visibility"); setDefault(board, "visibility", Visibility.Visible); processComputable(board as T, "width"); @@ -286,10 +310,10 @@ export function createBoard( processComputable(nodeType as NodeTypeOptions, "actionDistance"); setDefault(nodeType, "actionDistance", Math.PI / 6); nodeType.nodes = computed(() => - processedBoard.state.value.nodes.filter(node => node.type === type) + unref(processedBoard.state).nodes.filter(node => node.type === type) ); setDefault(nodeType, "onClick", function (node: BoardNode) { - processedBoard.state.value.selectedNode = node.id; + unref(processedBoard.state).selectedNode = node.id; }); if (nodeType.actions) { From 3de5dc567fc53751cc2c01398eff2084d2be0e7d Mon Sep 17 00:00:00 2001 From: thepaperpilot Date: Fri, 23 Dec 2022 11:45:50 -0600 Subject: [PATCH 12/28] Don't yell about deleted persistent refs --- src/game/persistence.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/game/persistence.ts b/src/game/persistence.ts index efb43c0..1fa6d91 100644 --- a/src/game/persistence.ts +++ b/src/game/persistence.ts @@ -268,6 +268,9 @@ globalBus.on("addLayer", (layer: GenericLayer, saveData: Record // eslint-disable-next-line @typescript-eslint/no-explicit-any handleObject((layer as any)[ProxyState]); persistentRefs[layer.id].forEach(persistent => { + if (persistent[Deleted]) { + return; + } console.error( `Created persistent ref in ${layer.id} without registering it to the layer! Make sure to include everything persistent in the returned object`, persistent, From e27cef29a790b9189543cab7ea019b92a6799672 Mon Sep 17 00:00:00 2001 From: thepaperpilot Date: Fri, 23 Dec 2022 14:59:16 -0600 Subject: [PATCH 13/28] Routing implemented --- src/data/layers/routing.tsx | 915 +++++++++++++++--------------- src/features/boards/BoardLink.vue | 9 +- 2 files changed, 473 insertions(+), 451 deletions(-) diff --git a/src/data/layers/routing.tsx b/src/data/layers/routing.tsx index 73d220b..52dc1b6 100644 --- a/src/data/layers/routing.tsx +++ b/src/data/layers/routing.tsx @@ -2,38 +2,55 @@ * @module * @hidden */ -import HotkeyVue from "components/Hotkey.vue"; import Spacer from "components/layout/Spacer.vue"; import Modal from "components/Modal.vue"; import { createCollapsibleModifierSections } from "data/common"; import { main } from "data/projEntry"; import { createBar, GenericBar } from "features/bars/bar"; -import { createClickable } from "features/clickables/clickable"; +import { BoardNode, BoardNodeLink, createBoard, Shape } from "features/boards/board"; +import { createClickable, GenericClickable } from "features/clickables/clickable"; import { jsx } from "features/feature"; -import { createHotkey, GenericHotkey } from "features/hotkey"; -import { createUpgrade } from "features/upgrades/upgrade"; +import MainDisplay from "features/resources/MainDisplay.vue"; +import { createResource } from "features/resources/resource"; import { globalBus } from "game/events"; import { BaseLayer, createLayer } from "game/layers"; -import { - createAdditiveModifier, - createMultiplicativeModifier, - createSequentialModifier -} from "game/modifiers"; +import { createAdditiveModifier, createSequentialModifier } from "game/modifiers"; import { persistent } from "game/persistence"; -import Decimal, { DecimalSource, format, formatTime, formatWhole } from "util/bignum"; +import Decimal, { DecimalSource, format, formatWhole } from "util/bignum"; import { Direction } from "util/common"; -import { render, renderGrid } from "util/vue"; +import { render, renderRow } from "util/vue"; import { computed, ref, unref, watchEffect } from "vue"; -import boxes from "./boxes"; -import cloth from "./cloth"; -import coal from "./coal"; -import dyes from "./dyes"; -import metal from "./metal"; -import oil from "./oil"; -import paper from "./paper"; -import plastic from "./plastic"; +import { resourceLimits } from "worker_threads"; import "./styles/reindeer.css"; -import trees from "./trees"; + +const alpha = [ + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z" +]; const id = "routing"; const day = 23; @@ -41,424 +58,426 @@ const layer = createLayer(id, function (this: BaseLayer) { const name = "Routing"; const color = "navajowhite"; - const feedGoal = 2.5e3; + const citiesGoal = 100; - const timeSinceFocus = persistent(0); + const citiesCompleted = createResource(0, "cities solved"); + const currentCity = persistent([]); + const currentRoute = persistent([]); + const checkRouteProgress = persistent(0); - const currMultiplier = persistent(1); - const currTargets = persistent>({}); - const currCooldown = persistent(0); - const crit = persistent(0); - - const maxMultiplier = createSequentialModifier(() => [ - createMultiplicativeModifier(() => ({ - multiplier: 2, - description: "Carry food in boxes", - enabled: upgrade4.bought - })) - ]); - const computedMaxMultiplier = computed(() => maxMultiplier.apply(2)); - const targetsCount = createSequentialModifier(() => [ - createAdditiveModifier(() => ({ - addend: 1, - description: "Guide to Reindeer Handling", - enabled: upgrade3.bought - })), - createAdditiveModifier(() => ({ - addend: crit, - description: "Metal clapper", - enabled: upgrade5.bought - })) - ]); - const computedTargetsCount = computed(() => targetsCount.apply(1)); - const computedMaxCooldown = computed(() => 10); - - function focus() { - let targetsSelected = 0; - currTargets.value = {}; - timeSinceFocus.value = 0; - while (Decimal.gt(computedTargetsCount.value, targetsSelected)) { - const selectedReindeer = - Object.values(reindeer)[Math.floor(Math.random() * Object.values(reindeer).length)]; - const roll = selectedReindeer?.name ?? ""; - if (!currTargets.value[roll]) { - currTargets.value[roll] = true; - targetsSelected++; - } + const currentRouteDuration = computed(() => { + const route = currentRoute.value; + let duration = 0; + for (let i = 0; i < route.length - 1; i++) { + duration += currentCity.value[route[i]][route[i + 1]]; } + return duration; + }); + + globalBus.on("onLoad", () => { + if (currentCity.value.length === 0) { + generateCity(); + } + }); + + function stringifyRoute(route: number[]) { + route + .map(h => (city.types.house.title as (node: BoardNode) => string)(city.nodes.value[h])) + .join("->"); } - const focusMeter = createBar(() => ({ - direction: Direction.Right, - width: 476, - height: 50, - style: `border-radius: 0`, - borderStyle: `border-radius: 0`, - fillStyle: () => ({ - background: currCooldown.value > 0 ? color : "#7f7f00", - animation: currCooldown.value > 0 ? "1s focused-eating-bar linear infinite" : "", - opacity: currCooldown.value > 0 ? currCooldown.value / 10 : 1, - transition: "none" - }), - progress: () => - Decimal.sub(currMultiplier.value, 1) - .div(Decimal.sub(computedMaxMultiplier.value, 1)) - .toNumber(), - display: jsx(() => ( - <> - {format(currMultiplier.value)}x - {currCooldown.value > 0 ? ( - <> - {" "} - to {Object.keys(currTargets.value).join(", ")} for{" "} - {formatTime(currCooldown.value)} - - ) : ( - "" - )} - - )) - })) as GenericBar; + function generateCity() { + const numHouses = new Decimal(computedHouses.value).clampMin(3).toNumber(); + const min = computedMinWeight.value; + const max = computedMaxWeight.value; + const diff = Decimal.sub(max, min); + const city: number[][] = []; + for (let i = 0; i < numHouses; i++) { + const house: number[] = []; + for (let j = 0; j < numHouses; j++) { + if (i === j) { + house.push(0); + } else if (j < i) { + house.push(city[j][i]); + } else { + house.push(Decimal.times(diff, Math.random()).add(min).floor().toNumber()); + } + } + city.push(house); + } + currentCity.value = city; + routesChecked.value = 0; + getNextRoute(); + } - const focusButton = createClickable(() => ({ + const routesChecked = ref(0); + function getNextRoute() { + if (routesChecked.value === 0) { + const numHouses = new Decimal(computedHouses.value).clampMin(3).toNumber(); + currentRoute.value = new Array(numHouses).fill(0).map((_, i) => i); + } else { + const route = currentRoute.value.slice(); + // Loop through each location as if they were digits, from right to left + // Try to increment a digit. + // If that makes it equal to the location to its left, then it has performed a full cycle: + // In this case, we mark that location as needing to be re-calculated and move to the next digit to the left + // If that digit was the starting location, then we've completed this city entirely + // If incrementing a digit doesn't make it equal to its left neighbor, but it _does_ appear elsewhere to its left, then try incrementing the digit again + // Once we find a digit that can be incremented successfully without completing a full cycle, save that new value and exit this loop + // If we marked a location as needing to be re-calculated, then set it to one above its left neighbor, skipping over any values present in other digits to its left, and repeat this process for every digit to the right of the marked one + let recalculateFrom = route.length; + outer: for (let i = route.length - 1; i >= 0; i--) { + let newHouse = route[i] + 1; + while (true) { + if (newHouse >= route.length) { + if (i === 0) { + // Overflowing on starting location means we're done! + citiesCompleted.value = Decimal.add(citiesCompleted.value, 1); + generateCity(); + return; + } + newHouse = 0; + } + if (i > 0 && newHouse === route[i - 1]) { + // This location is completed, so we'll increment the next location + // (going right to left) + recalculateFrom = i; + route[i] = -1; + break; + } + if (route.includes(newHouse)) { + // Skip over locations that appear to the left in the route + newHouse++; + } else { + // The route is fully valid + route[i] = newHouse; + break outer; + } + } + } + if (recalculateFrom <= 0) { + console.error("thepaperpilot's logic failed :skull:"); + } else { + for (let i = recalculateFrom; i < route.length; i++) { + let j = route[i - 1] + 1; + while (true) { + if (j >= route.length) { + j = 0; + } else if (route.includes(j)) { + j++; + } else { + break; + } + } + route[i] = j; + } + currentRoute.value = route; + } + } + checkRouteProgress.value = 0; + } + + const newCityProgress = persistent(0); + const newCityProgressBar = createBar(() => ({ + direction: Direction.Right, + width: 100, + height: 10, + style: "margin-top: 8px", + borderStyle: "border-color: black", + baseStyle: "margin-top: -1px", + fillStyle: "margin-top: -1px; transition-duration: 0s; background: black", + progress: () => Decimal.div(newCityProgress.value, 10) + })); + const getNewCity = createClickable(() => ({ display: { - title: "Focus", description: jsx(() => ( <> - Motivate reindeer to eat, multiplying {formatWhole(computedTargetsCount.value)}{" "} - random reindeer's eating rate by up to {format(computedMaxMultiplier.value)}x - for {formatTime(computedMaxCooldown.value)}, equal to the focus bar's effect. + Generate New City +
+ {render(newCityProgressBar)} )) }, style: { - width: "480px", - minHeight: "80px", - zIndex: 4 + minHeight: "40px", + "--layer-color": "var(--danger)" }, - canClick: () => Decimal.eq(currCooldown.value, 0), + canClick: () => Decimal.gte(newCityProgress.value, 10), onClick() { - currCooldown.value = Decimal.fromValue(computedMaxCooldown.value).toNumber(); - focus(); + if (!unref(getNewCity.canClick)) { + return; + } + generateCity(); + newCityProgress.value = 0; } })); - const cooldown = createSequentialModifier(() => [ - createMultiplicativeModifier(() => ({ - multiplier: 0.5, - description: "Pile of coal", - enabled: upgrade2.bought - })) - ]); - const computedCooldown = computed(() => cooldown.apply(10)); + const boostProgress = persistent(0); + const boostProgressBar = createBar(() => ({ + direction: Direction.Right, + width: 100, + height: 10, + style: "margin-top: 8px", + borderStyle: "border-color: black", + baseStyle: "margin-top: -1px", + fillStyle: "margin-top: -1px; transition-duration: 0s; background: black", + progress: () => Decimal.div(boostProgress.value, computedManualCooldown.value) + })); + const boost = createClickable(() => ({ + display: { + description: jsx(() => ( + <> + Perform {formatWhole(computedManualBoost.value)} units of work +
+ {render(boostProgressBar)} + + )) + }, + style: { + minHeight: "40px" + }, + canClick: () => Decimal.gte(boostProgress.value, computedManualCooldown.value), + onClick() { + if (!unref(boost.canClick)) { + return; + } + checkRouteProgress.value = Decimal.add( + checkRouteProgress.value, + computedManualBoost.value + ).toNumber(); + boostProgress.value = 0; + } + })); - function createReindeer(options: { - name: string; - key: string; - boostDescription: string; - boostAmount: DecimalSource; - }) { - const timesFed = persistent(0); - const progress = persistent(0); + const redundantProgress = persistent(0); + const redundantProgressBar = createBar(() => ({ + direction: Direction.Right, + width: 100, + height: 10, + style: "margin-top: 8px", + borderStyle: "border-color: black", + baseStyle: "margin-top: -1px", + fillStyle: "margin-top: -1px; transition-duration: 0s; background: black", + progress: () => Decimal.div(redundantProgress.value, computedRedundantCooldown.value) + })); + const removeRedundantRoute = createClickable(() => ({ + display: { + description: jsx(() => ( + <> + Remove a redundant route from the list to check +
+ {render(redundantProgressBar)} + + )) + }, + style: { + minHeight: "40px" + }, + canClick: () => Decimal.gte(redundantProgress.value, computedRedundantCooldown.value), + onClick() { + if (!unref(removeRedundantRoute.canClick)) { + return; + } + // TODO remove redundant route + redundantProgress.value = 0; + } + })); - const hotkey = createHotkey(() => ({ - key: "Numpad " + options.key, - description: "Feed " + options.name, - enabled: main.days[day - 1].opened, - onPress: clickable.onClick - })) as GenericHotkey; - - const clickable = createClickable(() => { - const progressBar = createBar(() => ({ - direction: Direction.Right, - width: 140, - height: 10, - style: "margin-top: 8px", - borderStyle: "border-color: black", - baseStyle: "margin-top: -1px", - fillStyle: () => ({ - marginTop: "-1px", - transitionDuration: "0s", - background: "black", - animation: - currTargets.value[options.name] && currCooldown.value > 0 - ? ".5s focused-eating-bar linear infinite" - : "" - }), - progress: () => Decimal.div(progress.value, computedCooldown.value) - })); - - const modifier = createMultiplicativeModifier(() => ({ - multiplier: effect, - description: options.name, - enabled: () => Decimal.gt(timesFed.value, 0) - })); - - const effect = computed(() => - Decimal.times(options.boostAmount, timesFed.value) - .add(1) - .pow(upgrade9.bought.value ? 1.1 : 1) - ); + const city = createBoard(() => ({ + startNodes: () => [], + types: { + house: { + shape: Shape.Circle, + fillColor: "var(--highlighted)", + outlineColor(node) { + return currentRoute.value.includes(node.state as number) + ? "var(--accent1)" + : "var(--outline)"; + }, + size: 20, + title(node) { + let letter = node.state as number; + let name = ""; + while (true) { + if (letter < 26) { + name += alpha[letter]; + break; + } + let thisLetter = letter; + let iterations = 0; + while (Math.floor(thisLetter / 26) - 1 >= 0) { + thisLetter = Math.floor(thisLetter / 26) - 1; + iterations++; + } + name += alpha[thisLetter]; + let amountToDecrement = thisLetter + 1; + for (let i = 0; i < iterations; i++) { + amountToDecrement *= 26; + } + letter -= amountToDecrement; + } + return name; + } + } + }, + width: "600px", + height: "600px", + style: { + background: "var(--raised-background)", + borderRadius: "var(--border-radius) var(--border-radius) 0 0", + boxShadow: "0 2px 10px rgb(0 0 0 / 50%)" + }, + state: computed(() => { + const nodes: BoardNode[] = []; + const city = currentCity.value; + const rows = Math.ceil(Math.sqrt(city.length)); + const cols = Math.ceil(city.length / rows); + for (let i = 0; i < city.length; i++) { + const row = Math.floor(i / rows); + const col = Math.floor(i % rows); + nodes.push({ + id: i, + position: { + x: 80 * (-(cols - 1) / 2 + col), + y: 80 * (-(rows - 1) / 2 + row) + }, + type: "house", + state: i + }); + } return { - ...options, - hotkey, - timesFed, - progress, - effect, - modifier, - display: { - title: jsx(() => ( -

- Feed {options.name} -

- )), - description: jsx(() => ( - <> -
- Each time you feed {options.name} will increase your{" "} - {options.boostDescription} by +{format(options.boostAmount)}x - - Currently {format(effect.value)}x -
- {render(progressBar)} - - )) - }, - style: { - width: "160px", - height: "160px" - }, - canClick() { - return Decimal.gte(progress.value, computedCooldown.value); - }, - onClick() { - if (!unref(clickable.canClick)) { - return; - } - let amount = Decimal.div(progress.value, computedCooldown.value); - if (upgrade1.bought.value) { - amount = Decimal.times(amount, 2); - } - timesFed.value = Decimal.add(timesFed.value, amount); - progress.value = 0; - }, - update(diff: number) { - if (Decimal.gte(progress.value, computedCooldown.value)) { - progress.value = computedCooldown.value; - } else { - let amount: DecimalSource = diff; - const isFocused = currTargets.value[options.name] && currCooldown.value > 0; - if (isFocused) { - amount = Decimal.times(amount, currMultiplier.value); - } - progress.value = Decimal.add(progress.value, amount); - if (clickable.isHolding.value || (upgrade8.bought.value && isFocused)) { - clickable.onClick(); + nodes, + selectedNode: null, + selectedAction: null + }; + }), + links() { + const links: BoardNodeLink[] = []; + const citySize = currentCity.value.length; + for (let i = 0; i < citySize; i++) { + for (let j = 0; j < citySize; j++) { + if (i !== j) { + // Bloody O(n^2) performance Batman! + let isActive = false; + const endPoints = [ + currentRoute.value[0], + currentRoute.value[currentRoute.value.length - 1] + ]; + if ( + (!endPoints.includes(i) || !endPoints.includes(j)) && + currentRoute.value.includes(i) && + currentRoute.value.includes(j) + ) { + isActive = true; } + links.push({ + startNode: city.nodes.value[i], + endNode: city.nodes.value[j], + stroke: isActive ? "red" : "white", + "stroke-width": isActive ? 4 : 2, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + weight: i < j ? null : currentCity.value[i][j] + }); } } - }; - }); - return clickable; - } - const dasher = createReindeer({ - name: "Dasher", - key: "7", - boostDescription: "log gain", - boostAmount: 1 - }); - const dancer = createReindeer({ - name: "Dancer", - key: "8", - boostDescription: "coal gain", - boostAmount: 0.1 - }); - const prancer = createReindeer({ - name: "Prancer", - key: "9", - boostDescription: "paper gain", - boostAmount: 0.1 - }); - const vixen = createReindeer({ - name: "Vixen", - key: "4", - boostDescription: "boxes gain", - boostAmount: 0.1 - }); - const comet = createReindeer({ - name: "Comet", - key: "5", - boostDescription: "metal gain", - boostAmount: 0.1 - }); - const cupid = createReindeer({ - name: "Cupid", - key: "6", - boostDescription: "cloth actions", - boostAmount: 0.1 - }); - const donner = createReindeer({ - name: "Donner", - key: "1", - boostDescription: "oil gain", - boostAmount: 0.01 - }); - const blitzen = createReindeer({ - name: "Blitzen", - key: "2", - boostDescription: "plastic gain", - boostAmount: 0.1 - }); - const rudolph = createReindeer({ - name: "Rudolph", - key: "3", - boostDescription: "dye gain", - boostAmount: 0.01 - }); - // order is designed so hotkeys appear 1-9, even though they're displayed in numpad order in the layer itself - const reindeer = { donner, blitzen, rudolph, vixen, comet, cupid, dasher, dancer, prancer }; + } + return links; + } + })); - const sumTimesFed = computed(() => - Object.values(reindeer) - .map(r => r.timesFed.value) - .reduce(Decimal.add, Decimal.dZero) - ); + const checkRouteProgressBar = createBar(() => ({ + direction: Direction.Right, + width: 597, + height: 24, + style: { + borderRadius: "0 0 var(--border-radius) var(--border-radius)", + background: "var(--raised-background)", + marginTop: "-24px" + }, + borderStyle: { + borderRadius: "0 0 var(--border-radius) var(--border-radius)", + borderColor: "var(--outline)", + marginTop: "unset" + }, + fillStyle: { + background: "black", + marginTop: "unset" + }, + progress() { + return Decimal.div(checkRouteProgress.value, currentRouteDuration.value); + }, + display: jsx(() => ( + <> + {Math.floor(checkRouteProgress.value)}/{currentRouteDuration.value} + + )) + })); - const upgrade1 = createUpgrade(() => ({ - resource: trees.logs, - cost: 0, - style: { - width: "160px" - }, - display: { - title: "Sawdust?", - description: - "Adding some sawdust to the feed allows you to make more of it. Each feed action counts twice" - } - })); - const upgrade2 = createUpgrade(() => ({ - resource: coal.coal, - cost: 0, - style: { - width: "160px" - }, - display: { - title: "Pile of coal", - description: - "Building a threatening pile of coal encourages the reindeer to behave. Each reindeer eats twice as fast" - } - })); - const upgrade3 = createUpgrade(() => ({ - resource: paper.paper, - cost: 0, - style: { - width: "160px" - }, - display: { - title: "Guide to Reindeer Handling", - description: - "Written reindeer handling instructions allow you to help more focus at once. Increase focus targets by one" - } - })); - const upgrade4 = createUpgrade(() => ({ - resource: boxes.boxes, - cost: 0, - style: { - width: "160px" - }, - display: { - title: "Carry food in boxes", - description: - "Carrying reindeer food in boxes allows you to distribute it faster. Double the maximum focus multiplier" - } - })); - const upgrade5 = createUpgrade(() => ({ - resource: metal.metal, - cost: 0, - style: { - width: "160px" - }, - display: { - title: "Metal clapper", - description: - 'Striking two rods of metal can help get more reindeer\'s attention when done right. "Critical" focuses now affect up to two additional reindeer' - } - })); - const upgrade6 = createUpgrade(() => ({ - resource: cloth.cloth, - cost: 0, - style: { - width: "160px" - }, - display: { - title: "Focus bar padding", - description: - "Adding padding to the focus bar lets you slow it down when it's closer to the max value" - } - })); - const upgrade7 = createUpgrade(() => ({ - resource: oil.oil, - cost: 0, - style: { - width: "160px" - }, - display: { - title: "Oil can do that?", - description: - "Using a lot of oil somehow let's reindeers focus themselves with a random value when left un-focused for 10s" - } - })); - const upgrade8 = createUpgrade(() => ({ - resource: plastic.plastic, - cost: 0, - style: { - width: "160px" - }, - display: { - title: "Autoamted feeder", - description: "An automated feeder let's focused reindeer eat automatically" - } - })); - const upgrade9 = createUpgrade(() => ({ - resource: dyes.dyes.white.amount, - cost: 0, - style: { - width: "160px" - }, - display: { - title: "Colorful food", - description: - "Adding some non-toxic dyes to the food makes them more powerful. Raise each reindeer's effect to the ^1.1" - } - })); - const upgrades = { - upgrade1, - upgrade2, - upgrade3, - upgrade4, - upgrade5, - upgrade6, - upgrade7, - upgrade8, - upgrade9 - }; + const houses = createSequentialModifier(() => [ + createAdditiveModifier(() => ({ + addend: citiesCompleted, + description: "Cities Completed" + })) + ]); + const computedHouses = computed(() => houses.apply(3)); + const maxWeight = createSequentialModifier(() => [ + createAdditiveModifier(() => ({ + addend: () => Decimal.pow(citiesCompleted.value, 1.1), + description: "Cities Completed" + })) + ]); + const computedMaxWeight = computed(() => maxWeight.apply(10)); + const minWeight = createSequentialModifier(() => [ + createAdditiveModifier(() => ({ + addend: citiesCompleted, + description: "Cities Completed" + })) + ]); + const computedMinWeight = computed(() => minWeight.apply(2)); + const manualBoost = createSequentialModifier(() => []); + const computedManualBoost = computed(() => manualBoost.apply(1)); + const manualCooldown = createSequentialModifier(() => []); + const computedManualCooldown = computed(() => manualCooldown.apply(1)); + const redundantCooldown = createSequentialModifier(() => []); + const computedRedundantCooldown = computed(() => redundantCooldown.apply(10)); + const autoProcessing = createSequentialModifier(() => []); + const computedAutoProcessing = computed(() => autoProcessing.apply(1)); const [generalTab, generalTabCollapsed] = createCollapsibleModifierSections(() => [ { - title: "Max Focus Multiplier", - modifier: maxMultiplier, + title: "Houses/city", + modifier: houses, + base: 3 + }, + { + title: "Minimum Weight", + modifier: minWeight, base: 2 }, { - title: "Focus Targets", - modifier: targetsCount, + title: "Manual Processing Amount", + modifier: manualBoost, base: 1 }, { - title: "Eating duration", - modifier: cooldown, - base: 10 + title: "Manual Processing Cooldown", + modifier: manualCooldown, + base: 1, + unit: "s" + }, + { + title: "Remove Redundant Route Cooldown", + modifier: redundantCooldown, + base: 10, + unit: "s" + }, + { + title: "Auto Processing Speed", + modifier: autoProcessing, + base: 1, + unit: "/s" } ]); const showModifiersModal = ref(false); @@ -478,33 +497,40 @@ const layer = createLayer(id, function (this: BaseLayer) { return; } - Object.values(reindeer).forEach(reindeer => reindeer.update(diff)); - - currCooldown.value = Math.max(currCooldown.value - diff, 0); - - let auto = false; - if (upgrade7.bought.value) { - timeSinceFocus.value += diff; - if (timeSinceFocus.value > 10) { - auto = true; + if (Decimal.gte(newCityProgress.value, 10)) { + newCityProgress.value = 10; + } else { + newCityProgress.value = Decimal.add(newCityProgress.value, diff); + if (getNewCity.isHolding.value) { + getNewCity.onClick(); } } - if (Decimal.eq(currCooldown.value, 0)) { - let speed = 1000; - if (auto) { - speed = Math.random() * 1000; + if (Decimal.gte(boostProgress.value, computedManualCooldown.value)) { + boostProgress.value = computedManualCooldown.value; + } else { + boostProgress.value = Decimal.add(boostProgress.value, diff); + if (boost.isHolding.value) { + boost.onClick(); } - let stoppedAt = 1 - Math.abs(Math.sin((Date.now() / speed) * 2)); - if (upgrade6.bought.value) { - stoppedAt = 1 - (1 - stoppedAt) ** 2; - } - crit.value = stoppedAt > 0.975 ? 2 : stoppedAt > 0.9 ? 1 : 0; - currMultiplier.value = Decimal.pow(computedMaxMultiplier.value, stoppedAt); - if (auto) { - focus(); + } + + if (Decimal.gte(redundantProgress.value, computedRedundantCooldown.value)) { + redundantProgress.value = computedRedundantCooldown.value; + } else { + redundantProgress.value = Decimal.add(redundantProgress.value, diff); + if (removeRedundantRoute.isHolding.value) { + removeRedundantRoute.onClick(); } } + + checkRouteProgress.value = Decimal.times(diff, computedAutoProcessing.value) + .add(checkRouteProgress.value) + .toNumber(); + if (checkRouteProgress.value > currentRouteDuration.value) { + routesChecked.value++; + getNextRoute(); + } }); const dayProgress = createBar(() => ({ @@ -512,11 +538,12 @@ const layer = createLayer(id, function (this: BaseLayer) { width: 600, height: 25, fillStyle: `backgroundColor: ${color}`, - progress: () => (main.day.value === day ? Decimal.div(sumTimesFed.value, feedGoal) : 1), + progress: () => + main.day.value === day ? Decimal.div(citiesCompleted.value, citiesGoal) : 1, display: jsx(() => main.day.value === day ? ( <> - {formatWhole(sumTimesFed.value)}/{formatWhole(feedGoal)} + {formatWhole(citiesCompleted.value)}/{formatWhole(citiesGoal)} ) : ( "" @@ -525,7 +552,7 @@ const layer = createLayer(id, function (this: BaseLayer) { })) as GenericBar; watchEffect(() => { - if (main.day.value === day && Decimal.gte(sumTimesFed.value, feedGoal)) { + if (main.day.value === day && Decimal.gte(citiesCompleted.value, citiesGoal)) { main.completeDay(); } }); @@ -534,20 +561,19 @@ const layer = createLayer(id, function (this: BaseLayer) { name, day, color, - reindeer, + citiesCompleted, + currentCity, + currentRoute, + checkRouteProgress, + newCityProgress, generalTabCollapsed, - timeSinceFocus, - currMultiplier, - currTargets, - currCooldown, - upgrades, - crit, + city, minWidth: 700, display: jsx(() => ( <>
{main.day.value === day - ? `Feed reindeer ${formatWhole(feedGoal)} times to complete the day` + ? `Solve ${formatWhole(citiesGoal)} cities to complete the day` : `${name} Complete!`}{" "} -{" "}