Merge branch 'main' into day-24-packing

This commit is contained in:
ducdat0507 2022-12-24 20:07:11 +07:00
commit 0345022622
11 changed files with 620 additions and 174 deletions

View file

@ -33,11 +33,13 @@ import { computed, ref, unref } from "vue";
import boxes from "./boxes"; import boxes from "./boxes";
import dyes from "./dyes"; import dyes from "./dyes";
import { ElfBuyable } from "./elves"; import { ElfBuyable } from "./elves";
import factory from "./factory";
import management from "./management"; import management from "./management";
import metal from "./metal"; import metal from "./metal";
import paper from "./paper"; import paper from "./paper";
import plastic from "./plastic"; import plastic from "./plastic";
import reindeer from "./reindeer"; import reindeer from "./reindeer";
import routing from "./routing";
import trees from "./trees"; import trees from "./trees";
import workshop from "./workshop"; import workshop from "./workshop";
import packing from "./packing" import packing from "./packing"
@ -550,7 +552,16 @@ const layer = createLayer(id, function (this: BaseLayer) {
description: "Yellow Dye", description: "Yellow Dye",
enabled: dyes.masteryEffectActive enabled: dyes.masteryEffectActive
})), })),
reindeer.reindeer.cupid.modifier reindeer.reindeer.cupid.modifier,
createMultiplicativeModifier(() => ({
multiplier: () =>
Object.values(factory.components).reduce(
(x, y) => y + (x.type == "cloth" ? 1 : 0),
1
) as number,
description: "300,000 Cities Solved",
enabled: routing.metaMilestones[4].earned
}))
]) as WithRequired<Modifier, "description" | "revert">; ]) as WithRequired<Modifier, "description" | "revert">;
const computedSpinningAmount = computed(() => spinningAmount.apply(1)); const computedSpinningAmount = computed(() => spinningAmount.apply(1));
const spinningCooldown = createSequentialModifier(() => []); const spinningCooldown = createSequentialModifier(() => []);

View file

@ -38,7 +38,8 @@ import trees from "./trees";
import toys from "./toys"; import toys from "./toys";
import factory from "./factory"; import factory from "./factory";
import reindeer from "./reindeer"; import reindeer from "./reindeer";
import packing from "./packing" import routing from "./routing";
import packing from "./packing";
interface Dye { interface Dye {
name: string; name: string;
@ -59,7 +60,15 @@ type DyeUpg =
| "blueDyeUpg2" | "blueDyeUpg2"
| "coalUpg"; | "coalUpg";
export type enumColor = "red" | "green" | "blue" | "yellow" | "purple" | "orange" | "black" | "white"; export type enumColor =
| "red"
| "green"
| "blue"
| "yellow"
| "purple"
| "orange"
| "black"
| "white";
const id = "dyes"; const id = "dyes";
const day = 11; const day = 11;
@ -205,6 +214,17 @@ const layer = createLayer(id, function (this: BaseLayer) {
})) }))
); );
modifiers.push(reindeer.reindeer.rudolph.modifier); modifiers.push(reindeer.reindeer.rudolph.modifier);
modifiers.push(
createMultiplicativeModifier(() => ({
multiplier: () =>
Object.values(factory.components).reduce(
(x, y) => y + (x.type == "dye" ? 1 : 0),
1
) as number,
description: "300,000 Cities Solved",
enabled: routing.metaMilestones[4].earned
}))
);
return modifiers; return modifiers;
}) as WithRequired<Modifier, "description" | "revert">; }) as WithRequired<Modifier, "description" | "revert">;
const computedToGenerate = computed(() => toGenerate.apply(0)); const computedToGenerate = computed(() => toGenerate.apply(0));
@ -730,7 +750,12 @@ const layer = createLayer(id, function (this: BaseLayer) {
.pow(upgrades.coalUpg.bought.value ? 1.2 : 1) .pow(upgrades.coalUpg.bought.value ? 1.2 : 1)
.pow(management.elfTraining.clothElfTraining.milestones[3].earned.value ? 1.1 : 1) .pow(management.elfTraining.clothElfTraining.milestones[3].earned.value ? 1.1 : 1)
), ),
purple2: computed(() => Decimal.add(dyes.purple.amount.value, 1).log2().plus(1).mul(packing.packingMilestones.secondaryDyeBoost.earned.value ? 2 : 1)), purple2: computed(() =>
Decimal.add(dyes.purple.amount.value, 1)
.log2()
.plus(1)
.mul(packing.packingMilestones.secondaryDyeBoost.earned.value ? 2 : 1)
),
black1: computed(() => black1: computed(() =>
Decimal.pow(2, Decimal.add(dyes.black.amount.value, 1).log2().sqrt()) Decimal.pow(2, Decimal.add(dyes.black.amount.value, 1).log2().sqrt())
.pow(upgrades.coalUpg.bought.value ? 1.2 : 1) .pow(upgrades.coalUpg.bought.value ? 1.2 : 1)

View file

@ -90,6 +90,7 @@ import toys from "./toys";
import trees from "./trees"; import trees from "./trees";
import workshop from "./workshop"; import workshop from "./workshop";
import ribbon from "./ribbon"; import ribbon from "./ribbon";
import routing from "./routing";
const id = "factory"; const id = "factory";
@ -235,6 +236,11 @@ const factory = createLayer(id, () => {
multiplier: 1.5, multiplier: 1.5,
description: "Carry ticks in boxes", description: "Carry ticks in boxes",
enabled: () => upgrades[2][3].bought.value enabled: () => upgrades[2][3].bought.value
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.max(routing.citiesCompleted.value, 1).log10().sub(3).max(1),
description: "25,000 Cities Solved",
enabled: routing.metaMilestones[2].earned
})) }))
]); ]);
const computedTickRate = computed(() => tickRate.apply(1)); const computedTickRate = computed(() => tickRate.apply(1));
@ -301,6 +307,15 @@ const factory = createLayer(id, () => {
)} )}
</div> </div>
<div> <div>
{routing.metaMilestones[5].earned.value ? (
<Tooltip display="Polyfill" direction={Direction.Down}>
<button class="control-btn material-icons" onClick={polyfill}>
format_color_fill
</button>
</Tooltip>
) : (
""
)}
<Tooltip display="Clear Tracks" direction={Direction.Down}> <Tooltip display="Clear Tracks" direction={Direction.Down}>
<button class="control-btn material-icons" onClick={setTracks}> <button class="control-btn material-icons" onClick={setTracks}>
clear clear
@ -417,7 +432,7 @@ const factory = createLayer(id, () => {
imageSrc: _shed, imageSrc: _shed,
extraImage: _wood, extraImage: _wood,
key: "1", key: "1",
name: "Wood Machine", name: "Wood Warehouse",
type: "processor", type: "processor",
description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.wood)), description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.wood)),
energyCost: 10, energyCost: 10,
@ -432,7 +447,7 @@ const factory = createLayer(id, () => {
imageSrc: _shed, imageSrc: _shed,
extraImage: _cloth, extraImage: _cloth,
key: "2", key: "2",
name: "Cloth Machine", name: "Cloth Warehouse",
type: "processor", type: "processor",
description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.cloth)), description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.cloth)),
energyCost: 10, energyCost: 10,
@ -447,7 +462,7 @@ const factory = createLayer(id, () => {
imageSrc: _shed, imageSrc: _shed,
extraImage: _dye, extraImage: _dye,
key: "3", key: "3",
name: "Dye Machine", name: "Dye Warehouse",
type: "processor", type: "processor",
description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.dye)), description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.dye)),
energyCost: 10, energyCost: 10,
@ -462,7 +477,7 @@ const factory = createLayer(id, () => {
imageSrc: _shed, imageSrc: _shed,
extraImage: _metal, extraImage: _metal,
key: "4", key: "4",
name: "Metal Machine", name: "Metal Warehouse",
type: "processor", type: "processor",
description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.metal)), description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.metal)),
energyCost: 10, energyCost: 10,
@ -477,7 +492,7 @@ const factory = createLayer(id, () => {
imageSrc: _shed, imageSrc: _shed,
extraImage: _plastic, extraImage: _plastic,
key: "5", key: "5",
name: "Plastic Machine", name: "Plastic Warehouse",
type: "processor", type: "processor",
description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.plastic)), description: computed(() => generateComponentDescription(FACTORY_COMPONENTS.plastic)),
energyCost: 10, energyCost: 10,
@ -816,7 +831,11 @@ const factory = createLayer(id, () => {
}, },
outputs: { outputs: {
console: { console: {
amount: computed(() => (upgrades[1][3].bought.value ? 3 : 1)), amount: computed(
() =>
(upgrades[1][3].bought.value ? 3 : 1) *
(routing.metaMilestones[3].earned.value ? 6 : 1)
),
resource: noPersist(consoles) resource: noPersist(consoles)
} }
}, },
@ -1238,6 +1257,7 @@ const factory = createLayer(id, () => {
)), )),
showAmount: false showAmount: false
}, },
purchaseLimit: 12,
style: "width: 200px", style: "width: 200px",
visibility: () => showIf(main.days[advancedDay - 1].opened.value) visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})) as GenericBuyable; })) as GenericBuyable;
@ -2074,6 +2094,24 @@ const factory = createLayer(id, () => {
} }
} }
function polyfill() {
for (
let x = Math.floor(-computedFactorySize.value / 2);
x < computedFactorySize.value / 2;
x++
) {
for (
let y = Math.floor(-computedFactorySize.value / 2);
y < computedFactorySize.value / 2;
y++
) {
const t = ["wood", "cloth", "dye", "metal", "plastic"][(((x + y) % 5) + 5) % 5];
if (components.value[x + "x" + y] == undefined) {
addFactoryComp(x, y, { type: t });
}
}
}
}
function clearFactory() { function clearFactory() {
for (const key of Object.keys(compInternalData)) { for (const key of Object.keys(compInternalData)) {
const [x, y] = key.split("x").map(i => +i); const [x, y] = key.split("x").map(i => +i);
@ -2526,6 +2564,7 @@ const factory = createLayer(id, () => {
generalTabCollapsed, generalTabCollapsed,
hotkeys, hotkeys,
upgrades, upgrades,
computedTickRate,
display: jsx(() => ( display: jsx(() => (
<> <>
{render(modifiersModal)} {render(modifiersModal)}

View file

@ -36,6 +36,7 @@ import "./styles/management.css";
import { Resource } from "features/resources/resource"; import { Resource } from "features/resources/resource";
import { isArray } from "@vue/shared"; import { isArray } from "@vue/shared";
import { createTab } from "features/tabs/tab"; import { createTab } from "features/tabs/tab";
import routing from "./routing";
import packing from "./packing"; import packing from "./packing";
import elves from "./elves"; import elves from "./elves";
@ -203,7 +204,7 @@ const layer = createLayer(id, () => {
const expRequiredForNextLevel = computed(() => Decimal.pow(5, level.value).mul(costBase)); const expRequiredForNextLevel = computed(() => Decimal.pow(5, level.value).mul(costBase));
const level = computed(() => const level = computed(() =>
Decimal.affordGeometricSeries(exp.value, costBase, 5, 0) Decimal.affordGeometricSeries(exp.value, costBase, 5, 0)
.min(schools.amount.value) .min(routing.metaMilestones[1].earned.value ? Infinity : schools.amount.value)
.toNumber() .toNumber()
); );
const expToNextLevel = computed(() => const expToNextLevel = computed(() =>
@ -231,9 +232,13 @@ const layer = createLayer(id, () => {
animation: focusTargets.value[elf.name] ? ".5s focused-xp-bar linear infinite" : "" animation: focusTargets.value[elf.name] ? ".5s focused-xp-bar linear infinite" : ""
}), }),
borderStyle: () => borderStyle: () =>
Decimal.gte(level.value, schools.amount.value) ? "border-color: red" : "", !routing.metaMilestones[1].earned.value &&
Decimal.gte(level.value, schools.amount.value)
? "border-color: red"
: "",
progress: () => Decimal.div(expToNextLevel.value, expRequiredForNextLevel.value), progress: () => Decimal.div(expToNextLevel.value, expRequiredForNextLevel.value),
display: jsx(() => display: jsx(() =>
!routing.metaMilestones[1].earned.value &&
Decimal.gte(level.value, schools.amount.value) ? ( Decimal.gte(level.value, schools.amount.value) ? (
<>Limit reached</> <>Limit reached</>
) : ( ) : (
@ -270,7 +275,8 @@ const layer = createLayer(id, () => {
<> <>
{elf.name} can buy buyables {formatWhole(elf.computedAutoBuyCooldown.value)}{" "} {elf.name} can buy buyables {formatWhole(elf.computedAutoBuyCooldown.value)}{" "}
times per second, gaining{" "} times per second, gaining{" "}
{Decimal.gte(level.value, schools.amount.value) {!routing.metaMilestones[1].earned.value &&
Decimal.gte(level.value, schools.amount.value)
? 0 ? 0
: format( : format(
Decimal.mul( Decimal.mul(
@ -1157,8 +1163,13 @@ const layer = createLayer(id, () => {
requirement: "Jingle Level 2", requirement: "Jingle Level 2",
effectDisplay: jsx(() => ( effectDisplay: jsx(() => (
<> <>
Each elf assistant increases packing speed by 10%<br /> Each elf assistant increases packing speed by 10%
Currently: +{formatWhole(Decimal.times(packing.helpers.elf.amount.value, 0.1).times(100))}% <br />
Currently: +
{formatWhole(
Decimal.times(packing.helpers.elf.amount.value, 0.1).times(100)
)}
%
</> </>
)) ))
}, },
@ -1170,8 +1181,15 @@ const layer = createLayer(id, () => {
requirement: "Jingle Level 3", requirement: "Jingle Level 3",
effectDisplay: jsx(() => ( effectDisplay: jsx(() => (
<> <>
Multiply packing speed by the number of completed packing milestones<br /> Multiply packing speed by the number of completed packing milestones
Currently: {formatWhole(Object.values(packing.packingMilestones).filter(milestone => milestone.earned.value).length+1)}x <br />
Currently:{" "}
{formatWhole(
Object.values(packing.packingMilestones).filter(
milestone => milestone.earned.value
).length + 1
)}
x
</> </>
)) ))
}, },
@ -1278,7 +1296,7 @@ const layer = createLayer(id, () => {
const packingElfTraining = createElfTraining(elves.elves.packingElf, packingElfMilestones); const packingElfTraining = createElfTraining(elves.elves.packingElf, packingElfMilestones);
const row5Elves = [coalDrillElfTraining, heavyDrillElfTraining, oilElfTraining]; const row5Elves = [coalDrillElfTraining, heavyDrillElfTraining, oilElfTraining];
const row6Elves = [metalElfTraining, dyeElfTraining, plasticElfTraining]; const row6Elves = [metalElfTraining, dyeElfTraining, plasticElfTraining];
const row7Elves = [packingElfTraining] const row7Elves = [packingElfTraining];
const elfTraining = { const elfTraining = {
cutterElfTraining, cutterElfTraining,
planterElfTraining, planterElfTraining,
@ -1342,7 +1360,10 @@ const layer = createLayer(id, () => {
const times = Math.floor(elf.amountOfTimesDone.value); const times = Math.floor(elf.amountOfTimesDone.value);
if (times >= 1) { if (times >= 1) {
elf.amountOfTimesDone.value -= times; elf.amountOfTimesDone.value -= times;
if (Decimal.lt(elf.level.value, schools.amount.value)) if (
routing.metaMilestones[1].earned.value ||
Decimal.lt(elf.level.value, schools.amount.value)
)
elf.exp.value = Decimal.mul(elf.elfXPGainComputed.value, times).add( elf.exp.value = Decimal.mul(elf.elfXPGainComputed.value, times).add(
elf.exp.value elf.exp.value
); );

View file

@ -39,7 +39,9 @@ import wrappingPaper from "./wrapping-paper";
import toys from "./toys"; import toys from "./toys";
import reindeer from "./reindeer"; import reindeer from "./reindeer";
import sleigh from "./sleigh"; import sleigh from "./sleigh";
import packing from "./packing" import factory from "./factory";
import routing from "./routing";
import packing from "./packing";
const id = "metal"; const id = "metal";
const day = 7; const day = 7;
@ -109,6 +111,15 @@ const layer = createLayer(id, function (this: BaseLayer) {
enabled: management.elfTraining.metalElfTraining.milestones[0].earned enabled: management.elfTraining.metalElfTraining.milestones[0].earned
})), })),
reindeer.reindeer.comet.modifier, reindeer.reindeer.comet.modifier,
createMultiplicativeModifier(() => ({
multiplier: () =>
Object.values(factory.components).reduce(
(x, y) => y + (x.type == "metal" ? 1 : 0),
1
) as number,
description: "300,000 Cities Solved",
enabled: routing.metaMilestones[4].earned
})),
createExponentialModifier(() => ({ createExponentialModifier(() => ({
exponent: 1.1, exponent: 1.1,
description: "Mary Level 2", description: "Mary Level 2",

View file

@ -39,6 +39,8 @@ import workshop from "./workshop";
import toys from "./toys"; import toys from "./toys";
import reindeer from "./reindeer"; import reindeer from "./reindeer";
import sleigh from "./sleigh"; import sleigh from "./sleigh";
import factory from "./factory";
import routing from "./routing";
const id = "plastic"; const id = "plastic";
const day = 10; const day = 10;
@ -323,9 +325,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
})), })),
createAdditiveModifier(() => ({ createAdditiveModifier(() => ({
addend: () => addend: () =>
management.elfTraining.oilElfTraining.milestones[3].earned.value management.elfTraining.oilElfTraining.milestones[3].earned.value
? Decimal.times(Decimal.div(sleigh.sleighProgress.value.value,2).floor(), 200) ? Decimal.times(Decimal.div(sleigh.sleighProgress.value.value, 2).floor(), 200)
: Decimal.times(activeRefinery.value, 40), : Decimal.times(activeRefinery.value, 40),
description: "75% Sleigh Fixed", description: "75% Sleigh Fixed",
enabled: sleigh.milestones.milestone7.earned enabled: sleigh.milestones.milestone7.earned
})), })),
@ -395,7 +397,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
description: "White Dye Boost" description: "White Dye Boost"
})), })),
createMultiplicativeModifier(() => ({ createMultiplicativeModifier(() => ({
multiplier: () => Decimal.div(sleigh.sleighProgress.value.value, 5).floor().mul(0.05).add(1), multiplier: () =>
Decimal.div(sleigh.sleighProgress.value.value, 5).floor().mul(0.05).add(1),
description: "20% Sleigh Fixed", description: "20% Sleigh Fixed",
enabled: sleigh.milestones.milestone3.earned enabled: sleigh.milestones.milestone3.earned
})), })),
@ -404,7 +407,16 @@ const layer = createLayer(id, function (this: BaseLayer) {
description: "40% Sleigh Fixed", description: "40% Sleigh Fixed",
enabled: sleigh.milestones.milestone5.earned enabled: sleigh.milestones.milestone5.earned
})), })),
reindeer.reindeer.blitzen.modifier reindeer.reindeer.blitzen.modifier,
createMultiplicativeModifier(() => ({
multiplier: () =>
Object.values(factory.components).reduce(
(x, y) => y + (x.type == "plastic" ? 1 : 0),
1
) as number,
description: "300,000 Cities Solved",
enabled: routing.metaMilestones[4].earned
}))
]); ]);
const computedPlasticGain = computed(() => plasticGain.apply(0)); const computedPlasticGain = computed(() => plasticGain.apply(0));

View file

@ -8,9 +8,10 @@ import { createCollapsibleMilestones, createCollapsibleModifierSections } from "
import { main } from "data/projEntry"; import { main } from "data/projEntry";
import { createBar, GenericBar } from "features/bars/bar"; import { createBar, GenericBar } from "features/bars/bar";
import { BoardNode, BoardNodeLink, createBoard, Shape } from "features/boards/board"; import { BoardNode, BoardNodeLink, createBoard, Shape } from "features/boards/board";
import { createBuyable, GenericBuyable } from "features/buyable";
import { createClickable } from "features/clickables/clickable"; import { createClickable } from "features/clickables/clickable";
import { jsx, showIf } from "features/feature"; import { jsx, showIf } from "features/feature";
import { createMilestone } from "features/milestones/milestone"; import { createMilestone, GenericMilestone } from "features/milestones/milestone";
import MainDisplay from "features/resources/MainDisplay.vue"; import MainDisplay from "features/resources/MainDisplay.vue";
import { createResource } from "features/resources/resource"; import { createResource } from "features/resources/resource";
import { globalBus } from "game/events"; import { globalBus } from "game/events";
@ -19,14 +20,19 @@ import {
createAdditiveModifier, createAdditiveModifier,
createExponentialModifier, createExponentialModifier,
createMultiplicativeModifier, createMultiplicativeModifier,
createSequentialModifier createSequentialModifier,
Modifier
} from "game/modifiers"; } from "game/modifiers";
import { persistent } from "game/persistence"; import { DefaultValue, persistent } from "game/persistence";
import Decimal, { DecimalSource, format, formatWhole } from "util/bignum"; import Decimal, { DecimalSource, format, formatWhole } from "util/bignum";
import { Direction } from "util/common"; import { Direction, WithRequired } from "util/common";
import { render, renderRow } from "util/vue"; import { render, renderRow } from "util/vue";
import { computed, ComputedRef, ref, unref, watchEffect } from "vue"; import { computed, ComputedRef, ref, unref, watchEffect } from "vue";
import factory from "./factory";
import management from "./management";
import metal from "./metal";
import "./styles/routing.css"; import "./styles/routing.css";
import Fraction from "components/math/Fraction.vue";
const alpha = [ const alpha = [
"A", "A",
@ -63,9 +69,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
const name = "Routing"; const name = "Routing";
const color = "navajowhite"; const color = "navajowhite";
const citiesGoal = 10; const citiesGoal = 5000000;
const citiesCompleted = createResource<DecimalSource>(0, "countries solved"); const citiesCompleted = createResource<DecimalSource>(0, "cities solved");
const currentCity = persistent<number[][]>([]); const currentCity = persistent<number[][]>([]);
const routeIndex = persistent<number>(0); const routeIndex = persistent<number>(0);
const checkRouteProgress = persistent<number>(0); const checkRouteProgress = persistent<number>(0);
@ -143,35 +149,37 @@ const layer = createLayer(id, function (this: BaseLayer) {
function stringifyRoute(route: number[]) { function stringifyRoute(route: number[]) {
return route return route
.map(h => (city.types.house.title as (node: BoardNode) => string)(city.nodes.value[h])) .map(h => (city.types.house.title as (node: BoardNode) => string)(city.nodes.value[h]))
.join("->"); .join(" > ");
} }
function generateCity() { function generateCity() {
const numHouses = new Decimal(computedHouses.value).clampMin(3).toNumber(); if (Decimal.lte(citiesCompleted.value, 50)) {
const min = computedMinWeight.value; const numHouses = new Decimal(computedHouses.value).clampMin(3).toNumber();
const max = milestone6.earned.value ? min : computedMaxWeight.value; const min = computedMinWeight.value;
const diff = Decimal.sub(max, min); const max = milestone6.earned.value ? min : computedMaxWeight.value;
const city: number[][] = []; const diff = Decimal.sub(max, min);
for (let i = 0; i < numHouses; i++) { const city: number[][] = [];
const house: number[] = []; for (let i = 0; i < numHouses; i++) {
for (let j = 0; j < numHouses; j++) { const house: number[] = [];
if (i === j) { for (let j = 0; j < numHouses; j++) {
house.push(0); if (i === j) {
} else if (j < i) { house.push(0);
house.push(city[j][i]); } else if (j < i) {
} else { house.push(city[j][i]);
house.push(Decimal.times(diff, Math.random()).add(min).floor().toNumber()); } else {
house.push(Decimal.times(diff, Math.random()).add(min).floor().toNumber());
}
} }
city.push(house);
} }
city.push(house); currentCity.value = city;
routeIndex.value = 0;
redundanciesRemoved.value = Decimal.gte(citiesCompleted.value, 7)
? Decimal.factorial(currentCity.value.length).div(2).toNumber()
: 0;
routesToSkip.value = [];
getNextRoute();
} }
currentCity.value = city;
routeIndex.value = 0;
redundanciesRemoved.value = Decimal.gte(citiesCompleted.value, 7)
? Decimal.factorial(currentCity.value.length).div(2).toNumber()
: 0;
routesToSkip.value = [];
getNextRoute();
} }
function getNextRoute() { function getNextRoute() {
@ -208,7 +216,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
display: { display: {
description: jsx(() => ( description: jsx(() => (
<> <>
Generate New Country Generate New City
<br /> <br />
{render(newCityProgressBar)} {render(newCityProgressBar)}
</> </>
@ -342,12 +350,13 @@ const layer = createLayer(id, function (this: BaseLayer) {
}, },
width: "600px", width: "600px",
height: "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(() => { state: computed(() => {
if (Decimal.gte(citiesCompleted.value, 50))
return {
nodes: [],
selectedNode: null,
selectedAction: null
};
const nodes: BoardNode[] = []; const nodes: BoardNode[] = [];
const city = currentCity.value; const city = currentCity.value;
const rows = Math.ceil(Math.sqrt(city.length)); const rows = Math.ceil(Math.sqrt(city.length));
@ -373,6 +382,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
}; };
}), }),
links() { links() {
if (Decimal.gte(citiesCompleted.value, 15)) return [];
const links: BoardNodeLink[] = []; const links: BoardNodeLink[] = [];
const route = currentRoute.value; const route = currentRoute.value;
if (route == null) { if (route == null) {
@ -432,6 +442,44 @@ const layer = createLayer(id, function (this: BaseLayer) {
} }
})); }));
const checkCityProgressBar = createBar(() => ({
direction: Direction.Right,
width: 597,
height: 24,
style: {
borderRadius: "var(--border-radius) var(--border-radius) 0 0",
background: "var(--raised-background)",
marginBottom: "-24px"
},
borderStyle: {
borderRadius: "var(--border-radius) var(--border-radius) 0 0",
borderColor: "transparent",
marginBottom: "unset"
},
fillStyle: {
background: "black",
marginBottom: "unset"
},
progress() {
return Decimal.div(
routeIndex.value,
typeof currentRoutes.value == "number"
? Math.floor(currentRoutes.value)
: currentRoutes.value.length
);
},
display: jsx(() => (
<>
{formatWhole(Math.floor(routeIndex.value))} /{" "}
{formatWhole(
typeof currentRoutes.value == "number"
? Math.floor(currentRoutes.value)
: currentRoutes.value.length
)}
</>
))
}));
const checkRouteProgressBar = createBar(() => ({ const checkRouteProgressBar = createBar(() => ({
direction: Direction.Right, direction: Direction.Right,
width: 597, width: 597,
@ -443,7 +491,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
}, },
borderStyle: { borderStyle: {
borderRadius: "0 0 var(--border-radius) var(--border-radius)", borderRadius: "0 0 var(--border-radius) var(--border-radius)",
borderColor: "var(--outline)", borderColor: "transparent",
marginTop: "unset" marginTop: "unset"
}, },
fillStyle: { fillStyle: {
@ -455,15 +503,16 @@ const layer = createLayer(id, function (this: BaseLayer) {
}, },
display: jsx(() => ( display: jsx(() => (
<> <>
{Math.floor(checkRouteProgress.value)}/{currentRouteDuration.value} {formatWhole(Math.floor(checkRouteProgress.value))} /{" "}
{formatWhole(currentRouteDuration.value)}
</> </>
)) ))
})); }));
const milestone1 = createMilestone(() => ({ const milestone1 = createMilestone(() => ({
display: { display: {
requirement: "1 Country Solved", requirement: "1 City Solved",
effectDisplay: "Each country solved doubles manual and auto processing speed" effectDisplay: "Each city solved doubles manual and auto processing speed"
}, },
shouldEarn() { shouldEarn() {
return Decimal.gte(citiesCompleted.value, 1); return Decimal.gte(citiesCompleted.value, 1);
@ -471,9 +520,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
})); }));
const milestone2 = createMilestone(() => ({ const milestone2 = createMilestone(() => ({
display: { display: {
requirement: "2 Countries Solved", requirement: "2 Cities Solved",
effectDisplay: effectDisplay:
"Manually checking routes does additional work based on number of routes checked in this country" "Manually checking routes does additional work based on number of routes checked in this city"
}, },
shouldEarn() { shouldEarn() {
return Decimal.gte(citiesCompleted.value, 2); return Decimal.gte(citiesCompleted.value, 2);
@ -482,9 +531,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
})); }));
const milestone3 = createMilestone(() => ({ const milestone3 = createMilestone(() => ({
display: { display: {
requirement: "3 Countries Solved", requirement: "3 Cities Solved",
effectDisplay: effectDisplay:
"Each country solved makes the cooldown for removing a redundant route 25% shorter" "Each city solved makes the cooldown for removing a redundant route 25% shorter"
}, },
shouldEarn() { shouldEarn() {
return Decimal.gte(citiesCompleted.value, 3); return Decimal.gte(citiesCompleted.value, 3);
@ -493,9 +542,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
})); }));
const milestone4 = createMilestone(() => ({ const milestone4 = createMilestone(() => ({
display: { display: {
requirement: "4 Countries Solved", requirement: "4 Cities Solved",
effectDisplay: effectDisplay:
"Automatic processing speed is multiplied by the amount of redundant routes removed from this country" "Automatic processing speed is multiplied by the amount of redundant routes removed from this city"
}, },
shouldEarn() { shouldEarn() {
return Decimal.gte(citiesCompleted.value, 4); return Decimal.gte(citiesCompleted.value, 4);
@ -504,8 +553,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
})); }));
const milestone5 = createMilestone(() => ({ const milestone5 = createMilestone(() => ({
display: { display: {
requirement: "5 Countries Solved", requirement: "5 Cities Solved",
effectDisplay: "Remove 1 city" effectDisplay: "Remove 1 city from the map"
}, },
shouldEarn() { shouldEarn() {
return Decimal.gte(citiesCompleted.value, 5); return Decimal.gte(citiesCompleted.value, 5);
@ -517,7 +566,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
})); }));
const milestone6 = createMilestone(() => ({ const milestone6 = createMilestone(() => ({
display: { display: {
requirement: "6 Countries Solved", requirement: "6 Cities Solved",
effectDisplay: effectDisplay:
"Lower max weight to the min weight, and uncap amount of routes that can be checked per tick" "Lower max weight to the min weight, and uncap amount of routes that can be checked per tick"
}, },
@ -528,7 +577,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
})); }));
const milestone7 = createMilestone(() => ({ const milestone7 = createMilestone(() => ({
display: { display: {
requirement: "7 Countries Solved", requirement: "7 Cities Solved",
effectDisplay: "All redundancies are removed" effectDisplay: "All redundancies are removed"
}, },
shouldEarn() { shouldEarn() {
@ -548,14 +597,206 @@ const layer = createLayer(id, function (this: BaseLayer) {
const { collapseMilestones, display: milestonesDisplay } = const { collapseMilestones, display: milestonesDisplay } =
createCollapsibleMilestones(milestones); createCollapsibleMilestones(milestones);
// ---------------------------------------------------- Meta stuff
const metaBuyables = {
metal: createBuyable(() => ({
resName: "Metal",
resource: metal.metal,
cost() {
const amount = Decimal.mul(this.amount.value, 1.05);
return Decimal.pow(5, amount).mul(1e83).div(Decimal.max(citiesCompleted.value, 1));
},
display: jsx(() => (
<>
Upgrade computer
<br />
for {formatWhole(unref(metaBuyables.metal.cost ?? 0))} metal
<br />
Currently +{formatWhole(Decimal.mul(metaBuyables.metal.amount.value, 10))}%
</>
)),
style: "width: 150px; min-height: 60px"
})),
console: createBuyable(() => ({
resName: "Game Console",
resource: factory.consoles,
cost() {
const amount = Decimal.mul(this.amount.value, 1.15);
return Decimal.pow(1.2, amount)
.mul(1e11)
.div(Decimal.max(citiesCompleted.value, 1));
},
display: jsx(() => (
<>
Upgrade computer
<br />
for {formatWhole(unref(metaBuyables.console.cost ?? 0))} game consoles
<br />
Currently +{formatWhole(Decimal.mul(metaBuyables.console.amount.value, 10))}%
</>
)),
style: "width: 150px; min-height: 60px"
})),
classroom: createBuyable(() => ({
resName: "Classroom",
cost() {
const amount = Decimal.mul(this.amount.value, 1.25);
return Decimal.pow(1.2, amount)
.mul(1e6)
.div(Decimal.max(citiesCompleted.value, 1).pow(0.5));
},
canPurchase() {
return Decimal.gte(
management.classrooms.amount.value,
unref(metaBuyables.classroom.cost ?? 0)
);
},
onPurchase() {
management.classrooms.amount.value = Decimal.sub(
management.classrooms.amount.value,
unref(metaBuyables.classroom.cost ?? 0)
);
this.amount.value = Decimal.add(this.amount.value, 1);
},
display: jsx(() => (
<>
Upgrade computer
<br />
for {formatWhole(unref(metaBuyables.classroom.cost ?? 0))} classrooms
<br />
Currently +{formatWhole(Decimal.mul(metaBuyables.classroom.amount.value, 10))}%
</>
)),
style: "width: 150px; min-height: 60px"
})),
tick: createBuyable(() => ({
resName: "Factory Tick Rate",
cost() {
const amount = Decimal.mul(this.amount.value, 1.15);
return Decimal.pow(1.5, amount)
.mul(5e6)
.div(Decimal.max(citiesCompleted.value, 1).pow(0.5));
},
canPurchase() {
return Decimal.gte(
factory.computedTickRate.value,
unref(metaBuyables.tick.cost ?? 0)
);
},
onPurchase() {
this.amount.value = Decimal.add(this.amount.value, 1);
},
display: jsx(() => (
<>
Upgrade computer
<br />
for {formatWhole(unref(metaBuyables.tick.cost ?? 0))} factory tick rate
<br />
Currently +{formatWhole(Decimal.mul(metaBuyables.tick.amount.value, 10))}%
</>
)),
style: "width: 150px; min-height: 60px"
}))
} as Record<string, GenericBuyable & { resName: string }>;
const metaMilestones = {
0: createMilestone(() => ({
display: {
requirement: "1000 Cities Solved",
effectDisplay: "Each city generates 1 classroom per minute"
},
shouldEarn() {
return Decimal.gte(citiesCompleted.value, 1000);
}
})),
1: createMilestone(() => ({
display: {
requirement: "5000 Cities Solved",
effectDisplay:
"Elves can learn past level 5 and gain 0.1 base city solved per second for each level elves learnt"
},
shouldEarn() {
return Decimal.gte(citiesCompleted.value, 5000);
},
visibility: () => showIf(metaMilestones[0].earned.value)
})),
2: createMilestone(() => ({
display: {
requirement: "25,000 Cities Solved",
effectDisplay: jsx(() => (
<>
Multiply factory tick rate by log<sub>10</sub>(cities solved) - 3
</>
))
},
shouldEarn() {
return Decimal.gte(citiesCompleted.value, 25000);
},
visibility: () => showIf(metaMilestones[1].earned.value)
})),
3: createMilestone(() => ({
display: {
requirement: "80,000 Cities Solved",
effectDisplay: "Multiply game console production by 6"
},
shouldEarn() {
return Decimal.gte(citiesCompleted.value, 80000);
},
visibility: () => showIf(metaMilestones[2].earned.value)
})),
4: createMilestone(() => ({
display: {
requirement: "300,000 Cities Solved",
effectDisplay:
"Multiply the amount of factory input resources by the amount of their corresponding warehouses appeared in the factory, plus 1"
},
shouldEarn() {
return Decimal.gte(citiesCompleted.value, 300000);
},
visibility: () => showIf(metaMilestones[3].earned.value)
})),
5: createMilestone(() => ({
display: {
requirement: "600,000 Cities Solved",
effectDisplay:
"Unlocks a button to let you fill the remaining empty spaces in the factory with warehouses, useful for the previous milestone"
},
shouldEarn() {
return Decimal.gte(citiesCompleted.value, 600000);
},
visibility: () => showIf(metaMilestones[4].earned.value)
})),
6: createMilestone(() => ({
display: {
requirement: "1,000,000 Cities Solved",
effectDisplay: jsx(() => (
<>
Increases base city solving speed by{" "}
<Fraction>
<div>factory tick rate</div>
<div>1000</div>
</Fraction>
</>
))
},
shouldEarn() {
return Decimal.gte(citiesCompleted.value, 1000000);
},
visibility: () => showIf(metaMilestones[5].earned.value)
}))
} as Record<number, GenericMilestone>;
const { collapseMilestones: collapseMetaMilestones, display: metaMilestonesDisplay } =
createCollapsibleMilestones(metaMilestones);
const houses = createSequentialModifier(() => [ const houses = createSequentialModifier(() => [
createAdditiveModifier(() => ({ createAdditiveModifier(() => ({
addend: citiesCompleted, addend: citiesCompleted,
description: "Countries Completed" description: "Cities Completed"
})), })),
createAdditiveModifier(() => ({ createAdditiveModifier(() => ({
addend: -1, addend: -1,
description: "5 Countries Completed", description: "5 Cities Completed",
enabled: milestone5.earned enabled: milestone5.earned
})) }))
]); ]);
@ -563,18 +804,18 @@ const layer = createLayer(id, function (this: BaseLayer) {
const maxWeight = createSequentialModifier(() => [ const maxWeight = createSequentialModifier(() => [
createAdditiveModifier(() => ({ createAdditiveModifier(() => ({
addend: () => Decimal.pow(citiesCompleted.value, 1.1), addend: () => Decimal.pow(citiesCompleted.value, 1.1),
description: "Countries Completed" description: "Cities Completed"
})) }))
]); ]);
const computedMaxWeight = computed(() => maxWeight.apply(10)); const computedMaxWeight = computed(() => maxWeight.apply(10));
const minWeight = createSequentialModifier(() => [ const minWeight = createSequentialModifier(() => [
createAdditiveModifier(() => ({ createAdditiveModifier(() => ({
addend: citiesCompleted, addend: citiesCompleted,
description: "Countries Completed" description: "Cities Completed"
})), })),
createExponentialModifier(() => ({ createExponentialModifier(() => ({
exponent: 3, exponent: 3,
description: "Countries Completed", description: "Cities Completed",
enabled: milestone7.earned enabled: milestone7.earned
})) }))
]); ]);
@ -582,7 +823,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
const manualBoost = createSequentialModifier(() => [ const manualBoost = createSequentialModifier(() => [
createAdditiveModifier(() => ({ createAdditiveModifier(() => ({
addend: () => Decimal.add(routeIndex.value, 1).sqrt(), addend: () => Decimal.add(routeIndex.value, 1).sqrt(),
description: "2 Countries Solved", description: "2 Cities Solved",
enabled: milestone2.earned enabled: milestone2.earned
})) }))
]); ]);
@ -590,7 +831,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
const manualCooldown = createSequentialModifier(() => [ const manualCooldown = createSequentialModifier(() => [
createMultiplicativeModifier(() => ({ createMultiplicativeModifier(() => ({
multiplier: () => Decimal.pow(0.5, citiesCompleted.value), multiplier: () => Decimal.pow(0.5, citiesCompleted.value),
description: "1 Country Solved", description: "1 City Solved",
enabled: milestone1.earned enabled: milestone1.earned
})) }))
]); ]);
@ -598,7 +839,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
const redundantCooldown = createSequentialModifier(() => [ const redundantCooldown = createSequentialModifier(() => [
createMultiplicativeModifier(() => ({ createMultiplicativeModifier(() => ({
multiplier: () => Decimal.pow(0.75, citiesCompleted.value), multiplier: () => Decimal.pow(0.75, citiesCompleted.value),
description: "3 Countries Solved", description: "3 Cities Solved",
enabled: milestone3.earned enabled: milestone3.earned
})) }))
]); ]);
@ -606,56 +847,89 @@ const layer = createLayer(id, function (this: BaseLayer) {
const autoProcessing = createSequentialModifier(() => [ const autoProcessing = createSequentialModifier(() => [
createMultiplicativeModifier(() => ({ createMultiplicativeModifier(() => ({
multiplier: () => Decimal.pow(2, citiesCompleted.value), multiplier: () => Decimal.pow(2, citiesCompleted.value),
description: "1 Country Solved", description: "1 City Solved",
enabled: milestone1.earned enabled: milestone1.earned
})), })),
createMultiplicativeModifier(() => ({ createMultiplicativeModifier(() => ({
multiplier: () => Decimal.add(redundanciesRemoved.value, 1), multiplier: () => Decimal.add(redundanciesRemoved.value, 1),
description: "4 Countries Solved", description: "4 Cities Solved",
enabled: milestone4.earned enabled: milestone4.earned
})) }))
]); ]);
const computedAutoProcessing = computed(() => autoProcessing.apply(1)); const computedAutoProcessing = computed(() => autoProcessing.apply(1));
const metaSolvingSpeed = createSequentialModifier(() => [
createAdditiveModifier(() => ({
addend: () => Decimal.div(management.totalElfLevels.value, 10),
description: "5000 Cities Solved",
enabled: metaMilestones[1].earned
})),
createAdditiveModifier(() => ({
addend: () => Decimal.div(factory.computedTickRate.value, 1000),
description: "1,000,000 Cities Solved",
enabled: metaMilestones[1].earned
})),
...Object.values(metaBuyables).map(x =>
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.div(x.amount.value, 10).add(1),
description: x.resName + " Upgrade",
enabled: () => Decimal.gte(x.amount.value, 1)
}))
)
]) as WithRequired<Modifier, "description">;
const computedMetaSolvingSpeed = computed(() => metaSolvingSpeed.apply(20));
const [generalTab, generalTabCollapsed] = createCollapsibleModifierSections(() => [ const [generalTab, generalTabCollapsed] = createCollapsibleModifierSections(() => [
{ {
title: "Cities/country", title: "Houses per City",
modifier: houses, modifier: houses,
base: 3 base: 3,
visible: () => Decimal.lte(citiesCompleted.value, 50)
}, },
{ {
title: () => (milestone6.earned.value ? "Weight" : "Minimum Weight"), title: () => (milestone6.earned.value ? "Weight" : "Minimum Weight"),
modifier: minWeight, modifier: minWeight,
base: 2 base: 2,
visible: () => Decimal.lte(citiesCompleted.value, 50)
}, },
{ {
title: "Maximum Weight", title: "Maximum Weight",
modifier: maxWeight, modifier: maxWeight,
base: 10, base: 10,
visible: () => !milestone6.earned.value visible: () => !milestone6.earned.value && Decimal.lte(citiesCompleted.value, 50)
}, },
{ {
title: "Manual Processing Amount", title: "Manual Processing Amount",
modifier: manualBoost, modifier: manualBoost,
base: 1 base: 1,
visible: () => Decimal.lte(citiesCompleted.value, 50)
}, },
{ {
title: "Manual Processing Cooldown", title: "Manual Processing Cooldown",
modifier: manualCooldown, modifier: manualCooldown,
base: 1, base: 1,
unit: "s" unit: "s",
visible: () => Decimal.lte(citiesCompleted.value, 50)
}, },
{ {
title: "Remove Redundant Route Cooldown", title: "Remove Redundant Route Cooldown",
modifier: redundantCooldown, modifier: redundantCooldown,
base: 10, base: 10,
unit: "s" unit: "s",
visible: () => Decimal.lte(citiesCompleted.value, 50)
}, },
{ {
title: "Auto Processing Speed", title: "Auto Processing Speed",
modifier: autoProcessing, modifier: autoProcessing,
base: 1, base: 1,
unit: "/s" unit: "/s",
visible: () => Decimal.lte(citiesCompleted.value, 50)
},
{
title: "Post-Inflation Solving Speed",
modifier: metaSolvingSpeed,
base: 20,
unit: "/s",
visible: () => Decimal.gt(citiesCompleted.value, 50)
} }
]); ]);
const showModifiersModal = ref(false); const showModifiersModal = ref(false);
@ -674,56 +948,68 @@ const layer = createLayer(id, function (this: BaseLayer) {
if (Decimal.lt(main.day.value, day)) { if (Decimal.lt(main.day.value, day)) {
return; return;
} }
if (citiesCompleted.value >= 100) return; if (Decimal.lte(citiesCompleted.value, 50)) {
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.gte(newCityProgress.value, 10)) { if (Decimal.gte(boostProgress.value, computedManualCooldown.value)) {
newCityProgress.value = 10; boostProgress.value = computedManualCooldown.value;
} else {
boostProgress.value = Decimal.add(boostProgress.value, diff);
if (boost.isHolding.value) {
boost.onClick();
}
}
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) {
const overflow = checkRouteProgress.value - currentRouteDuration.value;
routeIndex.value++;
if (milestone6.earned.value && currentRoute.value != null) {
const length =
typeof currentRoute.value === "number"
? currentRoute.value
: currentRoute.value.length;
const extraRoutes = Decimal.div(
overflow,
Decimal.times(length, computedMinWeight.value)
)
.floor()
.toNumber();
routeIndex.value += extraRoutes;
}
getNextRoute();
}
} else { } else {
newCityProgress.value = Decimal.add(newCityProgress.value, diff); citiesCompleted.value = Decimal.add(
if (getNewCity.isHolding.value) { citiesCompleted.value,
getNewCity.onClick(); Decimal.times(computedMetaSolvingSpeed.value, diff)
} ).min(5000000);
}
if (Decimal.gte(boostProgress.value, computedManualCooldown.value)) { if (metaMilestones[0].earned.value) {
boostProgress.value = computedManualCooldown.value; management.classrooms.amount.value = Decimal.add(
} else { management.classrooms.amount.value,
boostProgress.value = Decimal.add(boostProgress.value, diff); Decimal.times(citiesCompleted.value, diff).div(60)
if (boost.isHolding.value) { );
boost.onClick();
} }
} }
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) {
const overflow = checkRouteProgress.value - currentRouteDuration.value;
routeIndex.value++;
if (milestone6.earned.value && currentRoute.value != null) {
const length =
typeof currentRoute.value === "number"
? currentRoute.value
: currentRoute.value.length;
const extraRoutes = Decimal.div(
overflow,
Decimal.times(length, computedMinWeight.value)
)
.floor()
.toNumber();
routeIndex.value += extraRoutes;
}
getNextRoute();
}
}); });
const dayProgress = createBar(() => ({ const dayProgress = createBar(() => ({
@ -758,16 +1044,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
return ""; return "";
} }
if (typeof currentRoutes.value === "number") { if (typeof currentRoutes.value === "number") {
return ( return <div class="routes-list">&nbsp;</div>;
<div class="routes-list">
{routeIndex.value > 0 ? (
<div class="checked">{formatWhole(routeIndex.value)} already checked</div>
) : null}
<div>
{formatWhole(currentRoutes.value - routeIndex.value)} routes left to check
</div>
</div>
);
} }
if (typeof currentRoutes.value === "number") { if (typeof currentRoutes.value === "number") {
console.error("Something went horribly wrong"); console.error("Something went horribly wrong");
@ -775,22 +1052,17 @@ const layer = createLayer(id, function (this: BaseLayer) {
} }
const routes = currentRoutes.value.slice(); const routes = currentRoutes.value.slice();
let showPrevious = false; let showPrevious = false;
let showNext = 0; if (routes.length > 25) {
if (routes.length > 6) { routes.splice(0, Math.max(routeIndex.value - 12, 0));
routes.splice(0, routeIndex.value);
showPrevious = true; showPrevious = true;
if (routes.length > 6) { if (routes.length > 25) {
showNext = routes.length - 5; routes.splice(25);
routes.splice(5);
} }
} }
return ( return (
<div class="routes-list"> <div class="routes-list">
{showPrevious && routeIndex.value > 0 ? (
<div class="checked">{formatWhole(routeIndex.value)} already checked</div>
) : null}
{routes.map((route, i) => { {routes.map((route, i) => {
const index = i + (showPrevious ? routeIndex.value : 0); const index = i + (showPrevious ? Math.max(routeIndex.value - 12, 0) : 0);
return ( return (
<div <div
class={{ class={{
@ -800,13 +1072,14 @@ const layer = createLayer(id, function (this: BaseLayer) {
skipped: skipped:
routeIndex.value < index && routesToSkip.value.includes(index) routeIndex.value < index && routesToSkip.value.includes(index)
}} }}
style={{
"--opacity": 1 - Math.abs(index - routeIndex.value) / 13
}}
> >
{stringifyRoute(route)} {stringifyRoute(route)}
</div> </div>
); );
})} })}
{showNext > 0 ? <div>+ {formatWhole(showNext)} more</div> : null}
</div> </div>
); );
} }
@ -828,14 +1101,17 @@ const layer = createLayer(id, function (this: BaseLayer) {
routesToSkip, routesToSkip,
redundanciesRemoved, redundanciesRemoved,
city, city,
metaBuyables,
milestones, milestones,
collapseMilestones, collapseMilestones,
metaMilestones,
collapseMetaMilestones,
minWidth: 700, minWidth: 700,
display: jsx(() => ( display: jsx(() => (
<> <>
<div> <div>
{main.day.value === day {main.day.value === day
? `Solve ${formatWhole(citiesGoal)} countries to complete the day` ? `Solve ${formatWhole(citiesGoal)} cities to complete the day`
: `${name} Complete!`}{" "} : `${name} Complete!`}{" "}
-{" "} -{" "}
<button <button
@ -850,19 +1126,31 @@ const layer = createLayer(id, function (this: BaseLayer) {
{render(modifiersModal)} {render(modifiersModal)}
<Spacer /> <Spacer />
<MainDisplay resource={citiesCompleted} color={color} /> <MainDisplay resource={citiesCompleted} color={color} />
{renderRow(boost, removeRedundantRoute)} {Decimal.lte(citiesCompleted.value, 50) ? (
{render(city)} <>
{render(checkRouteProgressBar)} {renderRow(boost, removeRedundantRoute)}
<Spacer /> {render(checkCityProgressBar)}
<h3>Checking Routes...</h3> {displayRoutes()}
{displayRoutes()} {render(city)}
<Spacer /> {render(checkRouteProgressBar)}
{milestonesDisplay()} <Spacer />
{milestonesDisplay()}
</>
) : (
<>
You're solving {formatWhole(computedMetaSolvingSpeed.value)} cities per
second
<Spacer />
{renderRow(...Object.values(metaBuyables))}
<Spacer />
{metaMilestonesDisplay()}
</>
)}
</> </>
)), )),
minimizedDisplay: jsx(() => ( minimizedDisplay: jsx(() => (
<div> <div>
{name} <span class="desc">{format(citiesCompleted.value)} countries solved</span> {name} <span class="desc">{formatWhole(citiesCompleted.value)} cities solved</span>
</div> </div>
)) ))
}; };

View file

@ -1,3 +1,15 @@
.routes-list {
width: 600px;
height: 573px;
margin-bottom: -604px;
margin-top: -4px;
padding-top: 35px;
pointer-events: none;
border-radius: var(--border-radius);
background: var(--raised-background);
box-shadow: 0 2px 10px rgb(0 0 0 / 50%);
}
.routes-list .checked { .routes-list .checked {
color: var(--bought); color: var(--bought);
} }
@ -7,7 +19,7 @@
} }
.routes-list .redundant:not(.checked):not(.processing) { .routes-list .redundant:not(.checked):not(.processing) {
opacity: 0.5; color: var(--accent1);
} }
.routes-list .skipped { .routes-list .skipped {
@ -16,5 +28,12 @@
} }
.routes-list > * { .routes-list > * {
position: relative;
--opacity: 1;
flex: 1 1 33%; flex: 1 1 33%;
opacity: var(--opacity);
transition: all 0s;
}
.routes-list + div {
position: relative;
} }

View file

@ -42,6 +42,7 @@ import toys from "./toys";
import factory from "./factory"; import factory from "./factory";
import reindeer from "./reindeer"; import reindeer from "./reindeer";
import sleigh from "./sleigh"; import sleigh from "./sleigh";
import routing from "./routing";
import packing from "./packing"; import packing from "./packing";
const id = "trees"; const id = "trees";
const day = 1; const day = 1;
@ -561,7 +562,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
enabled: factory.upgrades[0][2].bought enabled: factory.upgrades[0][2].bought
})), })),
createMultiplicativeModifier(() => ({ createMultiplicativeModifier(() => ({
multiplier: () => Decimal.div(sleigh.sleighProgress.value.value, 5).floor().mul(0.05).add(1), multiplier: () =>
Decimal.div(sleigh.sleighProgress.value.value, 5).floor().mul(0.05).add(1),
description: "10% Sleigh Fixed", description: "10% Sleigh Fixed",
enabled: sleigh.milestones.milestone2.earned enabled: sleigh.milestones.milestone2.earned
})), })),
@ -570,6 +572,15 @@ const layer = createLayer(id, function (this: BaseLayer) {
description: "50% Sleigh Fixed", description: "50% Sleigh Fixed",
enabled: sleigh.milestones.milestone6.earned enabled: sleigh.milestones.milestone6.earned
})), })),
createMultiplicativeModifier(() => ({
multiplier: () =>
Object.values(factory.components).reduce(
(x, y) => y + (x.type == "wood" ? 1 : 0),
1
) as number,
description: "300,000 Cities Solved",
enabled: routing.metaMilestones[4].earned
})),
reindeer.reindeer.dasher.modifier, reindeer.reindeer.dasher.modifier,
createExponentialModifier(() => ({ createExponentialModifier(() => ({
exponent: 1.2, exponent: 1.2,

View file

@ -787,5 +787,14 @@ export function fixOldSave(
oldVersion: string | undefined, oldVersion: string | undefined,
player: Partial<PlayerData> player: Partial<PlayerData>
// eslint-disable-next-line @typescript-eslint/no-empty-function // eslint-disable-next-line @typescript-eslint/no-empty-function
): void {} ): void {
if (oldVersion !== undefined && oldVersion < "0.6") {
if ((player.layers?.main as typeof main)?.day !== undefined) {
(player.layers?.main as typeof main).day.value = Math.min(
(player.layers?.main as typeof main).day.value,
23
);
}
}
}
/* eslint-enable @typescript-eslint/no-unused-vars */ /* eslint-enable @typescript-eslint/no-unused-vars */

View file

@ -8,7 +8,7 @@
"discordName": "", "discordName": "",
"discordLink": "", "discordLink": "",
"versionNumber": "0.5", "versionNumber": "0.6",
"versionTitle": "Initial Commit", "versionTitle": "Initial Commit",
"allowGoBack": true, "allowGoBack": true,