Extend routing

This commit is contained in:
ducdat0507 2022-12-24 19:58:36 +07:00
parent 825ea2f2ed
commit 5f08ae7412
10 changed files with 407 additions and 56 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";
@ -544,7 +546,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,6 +38,7 @@ 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 routing from "./routing";
interface Dye { interface Dye {
name: string; name: string;
@ -58,7 +59,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;
@ -203,6 +212,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));

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

@ -37,6 +37,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";
const id = "management"; const id = "management";
const day = 12; const day = 12;
@ -198,7 +199,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(() =>
@ -226,9 +227,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</>
) : ( ) : (
@ -265,7 +270,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(
@ -1283,7 +1289,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,6 +39,8 @@ 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 factory from "./factory";
import routing from "./routing";
const id = "metal"; const id = "metal";
const day = 7; const day = 7;
@ -108,6 +110,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 { DefaultValue, 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,7 +69,7 @@ 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, "cities solved"); const citiesCompleted = createResource<DecimalSource>(0, "cities solved");
const currentCity = persistent<number[][]>([]); const currentCity = persistent<number[][]>([]);
@ -210,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)}
</> </>
@ -345,7 +351,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
width: "600px", width: "600px",
height: "600px", height: "600px",
state: computed(() => { state: computed(() => {
if (Decimal.gte(citiesCompleted.value, 20)) if (Decimal.gte(citiesCompleted.value, 50))
return { return {
nodes: [], nodes: [],
selectedNode: null, selectedNode: null,
@ -376,7 +382,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
}; };
}), }),
links() { links() {
if (Decimal.gte(citiesCompleted.value, 20)) return []; 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) {
@ -505,8 +511,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
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);
@ -514,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);
@ -525,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);
@ -536,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);
@ -547,7 +553,7 @@ 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 from the map" effectDisplay: "Remove 1 city from the map"
}, },
shouldEarn() { shouldEarn() {
@ -560,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"
}, },
@ -571,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() {
@ -591,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
})) }))
]); ]);
@ -606,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
})) }))
]); ]);
@ -625,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
})) }))
]); ]);
@ -633,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
})) }))
]); ]);
@ -641,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
})) }))
]); ]);
@ -649,22 +847,40 @@ 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(() => []); 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 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) visible: () => Decimal.lte(citiesCompleted.value, 50)
@ -732,7 +948,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
if (Decimal.lt(main.day.value, day)) { if (Decimal.lt(main.day.value, day)) {
return; return;
} }
if (Decimal.lte(citiesCompleted[DefaultValue], 50)) { if (Decimal.lte(citiesCompleted.value, 50)) {
if (Decimal.gte(newCityProgress.value, 10)) { if (Decimal.gte(newCityProgress.value, 10)) {
newCityProgress.value = 10; newCityProgress.value = 10;
} else { } else {
@ -784,8 +1000,15 @@ const layer = createLayer(id, function (this: BaseLayer) {
} else { } else {
citiesCompleted.value = Decimal.add( citiesCompleted.value = Decimal.add(
citiesCompleted.value, citiesCompleted.value,
computedMetaSolvingSpeed.value Decimal.times(computedMetaSolvingSpeed.value, diff)
); ).min(5000000);
if (metaMilestones[0].earned.value) {
management.classrooms.amount.value = Decimal.add(
management.classrooms.amount.value,
Decimal.times(citiesCompleted.value, diff).div(60)
);
}
} }
}); });
@ -878,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
@ -914,14 +1140,17 @@ const layer = createLayer(id, function (this: BaseLayer) {
<> <>
You're solving {formatWhole(computedMetaSolvingSpeed.value)} cities per You're solving {formatWhole(computedMetaSolvingSpeed.value)} cities per
second second
<Spacer />
{renderRow(...Object.values(metaBuyables))}
<Spacer />
{metaMilestonesDisplay()}
</> </>
)} )}
</> </>
)), )),
minimizedDisplay: jsx(() => ( minimizedDisplay: jsx(() => (
<div> <div>
{name}{" "} {name} <span class="desc">{formatWhole(citiesCompleted.value)} cities solved</span>
<span class="desc">{formatWhole(citiesCompleted.value)} countries solved</span>
</div> </div>
)) ))
}; };

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";
const id = "trees"; const id = "trees";
const day = 1; const day = 1;
@ -560,7 +561,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
})), })),
@ -569,6 +571,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

@ -649,5 +649,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,