Merge branch 'main' into days-15-16

This commit is contained in:
thepaperpilot 2022-12-15 21:07:19 -06:00
parent 44f940d3a1
commit 80a74c13a2
18 changed files with 607 additions and 114 deletions

View file

@ -8,6 +8,7 @@
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"> <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/svg+xml" href="/favicon.svg"> <link rel="icon" type="image/svg+xml" href="/favicon.svg">
<link rel="alternate icon" type="image/png" sizes="48x48" href="/favicon.ico"> <link rel="alternate icon" type="image/png" sizes="48x48" href="/favicon.ico">
<link rel="preload" as="image" href="src/data/adventCalendarGameJamCalandar.png">
<meta name="theme-color" content="#2E3440"> <meta name="theme-color" content="#2E3440">
<title>Advent Incremental</title> <title>Advent Incremental</title>

File diff suppressed because one or more lines are too long

View file

@ -1,7 +1,8 @@
<template> <template>
<div class="layer-container" :style="{ '--layer-color': unref(color) }"> <div class="layer-container" :style="{ '--layer-color': unref(color) }">
<button v-if="showGoBack" class="goBack" @click="goBack"></button> <button v-if="showGoBack" class="goBack" @click="goBack"></button>
<button class="layer-tab minimized" v-if="minimized.value" @click="minimized.value = false">
<button class="layer-tab minimized" v-if="minimized" @click="setMinimized(false)">
<component v-if="minimizedComponent" :is="minimizedComponent" /> <component v-if="minimizedComponent" :is="minimizedComponent" />
<div v-else>{{ unref(name) }}</div> <div v-else>{{ unref(name) }}</div>
</button> </button>
@ -10,7 +11,8 @@
<component :is="component" /> <component :is="component" />
</Context> </Context>
</div> </div>
<button v-if="unref(minimizable)" class="minimize" @click="minimized.value = true">
<button v-if="unref(minimizable)" class="minimize" @click="setMinimized(true)">
</button> </button>
</div> </div>
@ -63,7 +65,7 @@ export default defineComponent({
} }
}, },
setup(props) { setup(props) {
const { display, index, minimized, minWidth, tab, minimizedDisplay } = toRefs(props); const { display, index, minimized, minWidth, tab, minimizedDisplay, name } = toRefs(props);
const component = computeComponent(display); const component = computeComponent(display);
const minimizedComponent = computeOptionalComponent(minimizedDisplay); const minimizedComponent = computeOptionalComponent(minimizedDisplay);
@ -75,23 +77,28 @@ export default defineComponent({
player.tabs.splice(unref(props.index), 1); player.tabs.splice(unref(props.index), 1);
} }
function setMinimized(min: boolean) {
minimized.value = min;
}
nextTick(() => updateTab(minimized.value, unref(minWidth.value))); nextTick(() => updateTab(minimized.value, unref(minWidth.value)));
watch([minimized, wrapRef(minWidth)], ([minimized, minWidth]) => watch([name, minimized, wrapRef(minWidth)], ([name, minimized, minWidth]) => {
updateTab(minimized, minWidth) updateTab(minimized, minWidth);
); });
function updateNodes(nodes: Record<string, FeatureNode | undefined>) { function updateNodes(nodes: Record<string, FeatureNode | undefined>) {
props.nodes.value = nodes; props.nodes.value = nodes;
} }
function updateTab(minimized: boolean, minWidth: number | string) { function updateTab(min: boolean, minWidth: number | string) {
minimized.value = min;
const width = const width =
typeof minWidth === "number" || Number.isNaN(parseInt(minWidth)) typeof minWidth === "number" || Number.isNaN(parseInt(minWidth))
? minWidth + "px" ? minWidth + "px"
: minWidth; : minWidth;
const tabValue = tab.value(); const tabValue = tab.value();
if (tabValue != undefined) { if (tabValue != undefined) {
if (minimized) { if (min) {
tabValue.style.flexGrow = "0"; tabValue.style.flexGrow = "0";
tabValue.style.flexShrink = "0"; tabValue.style.flexShrink = "0";
tabValue.style.width = "60px"; tabValue.style.width = "60px";
@ -107,13 +114,17 @@ export default defineComponent({
} }
} }
return { return {
component, component,
minimizedComponent, minimizedComponent,
showGoBack, showGoBack,
updateNodes, updateNodes,
unref, unref,
goBack goBack,
setMinimized,
minimized,
minWidth,
}; };
} }
}); });
@ -162,6 +173,7 @@ export default defineComponent({
.layer-tab.minimized > * { .layer-tab.minimized > * {
margin: 0; margin: 0;
writing-mode: vertical-rl; writing-mode: vertical-rl;
text-align: left;
padding-left: 10px; padding-left: 10px;
width: 50px; width: 50px;
} }

View file

@ -13,10 +13,15 @@
</template> </template>
<template v-slot:body> <template v-slot:body>
<div v-if="isTab('behaviour')"> <div v-if="isTab('behaviour')">
<div v-if="canAutoSave">
<Toggle :title="autosaveTitle" v-model="autosave" /> <Toggle :title="autosaveTitle" v-model="autosave" />
<FeedbackButton v-if="!autosave" class="button save-button" @click="save()" <FeedbackButton v-if="!autosave" class="button save-button" @click="save()">
>Manually save</FeedbackButton Manually save
> </FeedbackButton>
</div>
<div style="text-align: center" v-else>
Auto-saving is disabled while between days
</div>
<Toggle v-if="projInfo.enablePausing" :title="isPausedTitle" v-model="isPaused" /> <Toggle v-if="projInfo.enablePausing" :title="isPausedTitle" v-model="isPaused" />
</div> </div>
<div v-if="isTab('appearance')"> <div v-if="isTab('appearance')">
@ -45,6 +50,7 @@ import { computed, ref, toRefs } from "vue";
import Select from "./fields/Select.vue"; import Select from "./fields/Select.vue";
import Toggle from "./fields/Toggle.vue"; import Toggle from "./fields/Toggle.vue";
import FeedbackButton from "./fields/FeedbackButton.vue"; import FeedbackButton from "./fields/FeedbackButton.vue";
import { layers } from "game/layers";
const isOpen = ref(false); const isOpen = ref(false);
@ -91,6 +97,10 @@ const isPaused = computed({
} }
}); });
const canAutoSave = computed(
() => (layers as any).main.days[(layers as any).main.day.value - 1].opened.value
);
const autosaveTitle = jsx(() => ( const autosaveTitle = jsx(() => (
<span class="option-title"> <span class="option-title">
Autosave<Tooltip display="Save-specific">*</Tooltip> Autosave<Tooltip display="Save-specific">*</Tooltip>

View file

@ -7,6 +7,12 @@
style="left: 4%; bottom: 3%; width: 40px; height: 40px" style="left: 4%; bottom: 3%; width: 40px; height: 40px"
/> />
<img v-if="day >= 0" :src="tree" class="scene-item" style="left: 10%; bottom: 10%" /> <img v-if="day >= 0" :src="tree" class="scene-item" style="left: 10%; bottom: 10%" />
<img
v-if="day >= 13"
:src="letters"
class="scene-item"
style="left: 26%; bottom: 12%; width: 40px; height: 40px"
/>
<img <img
v-if="day >= 12" v-if="day >= 12"
:src="advManagement" :src="advManagement"
@ -68,6 +74,7 @@ import plastic from "./symbols/plastic.png";
import dyes from "./symbols/dyes.png"; import dyes from "./symbols/dyes.png";
import management from "./symbols/elfManagement.png"; import management from "./symbols/elfManagement.png";
import advManagement from "./symbols/workshopMansion.png"; import advManagement from "./symbols/workshopMansion.png";
import letters from "./symbols/letterbox.png";
defineProps<{ defineProps<{
day: number; day: number;

View file

@ -579,7 +579,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
inverseCost(x: DecimalSource) { inverseCost(x: DecimalSource) {
let v = Decimal.div(x, 50000).root(1.5).sub(1); let v = Decimal.div(x, 50000).root(1.5).sub(1);
v = v.mul(wrappingPaper.boosts.rainbow1.value); v = v.mul(wrappingPaper.boosts.rainbow1.value);
if (management.elfTraining.fertilizerElfTraining.milestones[0].earned.value) { if (management.elfTraining.fertilizerElfTraining.milestones[1].earned.value) {
v = v.div(Decimal.pow(0.95, paper.books.fertilizerBook.totalAmount.value)); v = v.div(Decimal.pow(0.95, paper.books.fertilizerBook.totalAmount.value));
} }
v = v.div(Decimal.pow(0.95, paper.books.fertilizerBook.totalAmount.value)); v = v.div(Decimal.pow(0.95, paper.books.fertilizerBook.totalAmount.value));

View file

@ -92,21 +92,25 @@ const layer = createLayer(id, function (this: BaseLayer) {
description: `${options.name} Chambers` description: `${options.name} Chambers`
})) }))
]; ];
if (options.color === "yellow" && oil.row3Upgrades[0].bought.value){ if (options.color === "yellow" && oil.row3Upgrades[0].bought.value) {
modifiers.push( modifiers.push(
createMultiplicativeModifier(() => ({ createMultiplicativeModifier(() => ({
multiplier(){return Decimal.add(dyes.red.amount.value,1).log10().pow(0.75)}, multiplier() {
return Decimal.add(dyes.red.amount.value, 1).log10().pow(0.75);
},
description: "Dye Synergy I" description: "Dye Synergy I"
})) }))
) );
} }
if (options.color === "red" && oil.row3Upgrades[3].bought.value){ if (options.color === "red" && oil.row3Upgrades[3].bought.value) {
modifiers.push( modifiers.push(
createMultiplicativeModifier(() => ({ createMultiplicativeModifier(() => ({
multiplier(){return Decimal.add(dyes.blue.amount.value,1).log10()}, multiplier() {
return Decimal.add(dyes.blue.amount.value, 1).log10();
},
description: "Dye Synergy II" description: "Dye Synergy II"
})) }))
) );
} }
if (options.color === "red" || options.color === "yellow") { if (options.color === "red" || options.color === "yellow") {
modifiers.push( modifiers.push(
@ -254,9 +258,16 @@ const layer = createLayer(id, function (this: BaseLayer) {
}, },
inverseCost() { inverseCost() {
if (unref(buyable.visibility) != Visibility.Visible) return Decimal.dZero; if (unref(buyable.visibility) != Visibility.Visible) return Decimal.dZero;
return unref(costs).reduce((pre, c) => return unref(costs).reduce(
Decimal.min(this.inverseCostPre(Decimal.div(c.res.value, unref(c.base)).root(unref(c.root ?? 1))), pre) (pre, c) =>
, Decimal.dInf); Decimal.min(
this.inverseCostPre(
Decimal.div(c.res.value, unref(c.base)).root(unref(c.root ?? 1))
),
pre
),
Decimal.dInf
);
}, },
canPurchase: computed((cost?: DecimalSource) => { canPurchase: computed((cost?: DecimalSource) => {
if (unref(buyable.visibility) != Visibility.Visible) return false; if (unref(buyable.visibility) != Visibility.Visible) return false;
@ -533,7 +544,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)
), ),
orange2: computed(() => Decimal.add(dyes.orange.amount.value, 1).log2().plus(1).pow(oil.row3Upgrades[1].bought.value ? 2.5 : 1)), orange2: computed(() =>
Decimal.add(dyes.orange.amount.value, 1)
.log2()
.plus(1)
.pow(oil.row3Upgrades[1].bought.value ? 2.5 : 1)
),
green1: computed(() => green1: computed(() =>
Decimal.pow(2, Decimal.add(dyes.green.amount.value, 1).log2().sqrt()) Decimal.pow(2, Decimal.add(dyes.green.amount.value, 1).log2().sqrt())
.pow(upgrades.coalUpg.bought.value ? 1.2 : 1) .pow(upgrades.coalUpg.bought.value ? 1.2 : 1)
@ -743,6 +759,12 @@ const layer = createLayer(id, function (this: BaseLayer) {
), ),
"Sum of Dyes" "Sum of Dyes"
); );
const secondaryDyeSum = computed(() =>
[dyes.orange, dyes.green, dyes.purple].reduce(
(acc, curr) => acc.add(curr.amount.value),
new Decimal(0)
)
);
const { total: totalDyeSum, trackerDisplay } = setUpDailyProgressTracker({ const { total: totalDyeSum, trackerDisplay } = setUpDailyProgressTracker({
resource: dyeSum, resource: dyeSum,
@ -765,6 +787,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
dyeSum, dyeSum,
boosts, boosts,
totalDyeSum, totalDyeSum,
secondaryDyeSum,
minWidth: 700, minWidth: 700,
generalTabCollapsed, generalTabCollapsed,
upgrades, upgrades,

View file

@ -895,7 +895,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
const metalElf = createElf({ const metalElf = createElf({
name: "Twinkle", name: "Twinkle",
description: description:
"Twinkle will automatically purchase all metal buyables you can afford, without actually spending any resources.", "Twinkle will automatically purchase all metal machines you can afford, without actually spending any resources.",
buyable: [metal.oreDrill, metal.industrialCrucible, metal.hotterForge], buyable: [metal.oreDrill, metal.industrialCrucible, metal.hotterForge],
cooldownModifier: metalCooldown, cooldownModifier: metalCooldown,
visibility: () => visibility: () =>

292
src/data/layers/letters.tsx Normal file
View file

@ -0,0 +1,292 @@
import Spacer from "components/layout/Spacer.vue";
import Modal from "components/Modal.vue";
import MainDisplay from "features/resources/MainDisplay.vue";
import Sqrt from "components/math/Sqrt.vue";
import {
createCollapsibleMilestones,
createCollapsibleModifierSections,
setUpDailyProgressTracker
} from "data/common";
import { createBar } from "features/bars/bar";
import { createClickable } from "features/clickables/clickable";
import { jsx, showIf } from "features/feature";
import { createMilestone } from "features/milestones/milestone";
import { createResource } from "features/resources/resource";
import { BaseLayer, createLayer } from "game/layers";
import { createMultiplicativeModifier, createSequentialModifier } from "game/modifiers";
import { persistent } from "game/persistence";
import Decimal, { DecimalSource, format, formatWhole } from "util/bignum";
import { Direction } from "util/common";
import { render, renderRow } from "util/vue";
import { computed, ref } from "vue";
import { createBuyable, GenericBuyable } from "features/buyable";
import metal from "./metal";
import plastic from "./plastic";
import paper from "./paper";
import SqrtVue from "components/math/Sqrt.vue";
import { globalBus } from "game/events";
import { main } from "data/projEntry";
const id = "letters";
const day = 14;
const layer = createLayer(id, function (this: BaseLayer) {
const name = "Letters";
const color = "antiquewhite";
const letters = createResource<DecimalSource>(0, "letters processed");
const processingProgress = persistent<DecimalSource>(0);
const processingProgressBar = createBar(() => ({
direction: Direction.Right,
width: 100,
height: 10,
style: "margin-top: 8px",
borderStyle: "border-color: black",
baseStyle: "margin-top: 0",
fillStyle: "margin-top: 0; transition-duration: 0s; background: black",
progress: () => Decimal.div(processingProgress.value, computedProcessingCooldown.value)
}));
const process = createClickable(() => ({
display: {
title: "Process Letters",
description: jsx(() => (
<>
Process {format(computedLettersGain.value, 1)} letters
<br />
{render(processingProgressBar)}
</>
))
},
style: {
minHeight: "80px"
},
canClick: () => Decimal.gte(processingProgress.value, computedProcessingCooldown.value),
onClick() {
if (Decimal.lt(processingProgress.value, computedProcessingCooldown.value)) {
return;
}
const amount = Decimal.div(
processingProgress.value,
computedProcessingCooldown.value
).floor();
letters.value = Decimal.times(amount, computedLettersGain.value).add(letters.value);
processingProgress.value = 0;
}
}));
const metalBuyable = createBuyable(() => ({
display: {
title: "Sorting Machine",
description:
"Use a mechanic sorting machine to speed up how quickly you process letters",
effectDisplay: jsx(() => (
<>{format(Decimal.div(metalBuyable.amount.value, 2).add(1))}x</>
))
},
resource: metal.metal,
cost() {
return Decimal.pow(10, metalBuyable.amount.value).times(1e21);
}
})) as GenericBuyable;
const plasticBuyable = createBuyable(() => ({
display: {
title: "Plastic Bins",
description:
"Use various plastic bins to allow you to process larger quantities of letters at once",
effectDisplay: jsx(() => (
<>{format(Decimal.div(plasticBuyable.amount.value, 2).add(1))}x</>
))
},
resource: plastic.plastic,
cost() {
return Decimal.pow(1.5, plasticBuyable.amount.value).times(1e9);
}
})) as GenericBuyable;
const paperBuyable = createBuyable(() => ({
display: {
title: "Printed Labels",
description: "Use printed labels to improve how many letters you can process at once",
effectDisplay: jsx(() => (
<>{format(Decimal.div(paperBuyable.amount.value, 2).add(1))}x</>
))
},
resource: paper.paper,
cost() {
return Decimal.pow(3, paperBuyable.amount.value).times(1e38);
}
})) as GenericBuyable;
const buyables = { metalBuyable, plasticBuyable, paperBuyable };
const autoSmeltingMilestone = createMilestone(() => ({
display: {
requirement: "100 Letters Processed",
effectDisplay: "Double mining speed for every letters processed milestone"
},
shouldEarn: () => Decimal.gte(totalLetters.value, 100)
}));
const miningMilestone = createMilestone(() => ({
display: {
requirement: "1000 Letters Processed",
effectDisplay: jsx(() => (
<>
Mine <SqrtVue>Blue Dye</SqrtVue> additional ore each operation
</>
))
},
shouldEarn: () => Decimal.gte(totalLetters.value, 1000),
visibility: () => showIf(autoSmeltingMilestone.earned.value)
}));
const synergyMilestone = createMilestone(() => ({
display: {
requirement: "10,000 Letters Processed",
effectDisplay:
"Improve how much your experience processing letters allows you to process more letters"
},
shouldEarn: () => Decimal.gte(totalLetters.value, 10000),
visibility: () => showIf(miningMilestone.earned.value)
}));
const industrialCrucibleMilestone = createMilestone(() => ({
display: {
requirement: "100,000 Letters Processed",
effectDisplay: jsx(() => (
<>
"Industrial Crucible" also multiplies the auto smelting multi by{" "}
<Sqrt>amount</Sqrt>
</>
))
},
shouldEarn: () => Decimal.gte(totalLetters.value, 100000),
visibility: () => showIf(synergyMilestone.earned.value)
}));
const milestones = {
autoSmeltingMilestone,
miningMilestone,
synergyMilestone,
industrialCrucibleMilestone
};
const { collapseMilestones, display: milestonesDisplay } =
createCollapsibleMilestones(milestones);
const synergy = computed(() => {
const amount = Decimal.add(totalLetters.value, 1);
if (synergyMilestone.earned.value) {
const preSoftcap = Decimal.log2(10001).add(1);
return preSoftcap.add(amount.sub(9999).sqrt());
} else {
return Decimal.log2(amount).add(1);
}
});
const lettersGain = createSequentialModifier(() => [
createMultiplicativeModifier(() => ({
multiplier: synergy,
description: "Processing Letters Experience"
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.div(plasticBuyable.amount.value, 2).add(1),
description: "Plastic Bins"
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.div(paperBuyable.amount.value, 2).add(1),
description: "Printed Labels"
}))
]);
const computedLettersGain = computed(() => lettersGain.apply(1));
const processingCooldown = createSequentialModifier(() => [
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.div(metalBuyable.amount.value, 2).add(1).recip(),
description: "Sorting Machine"
}))
]);
const computedProcessingCooldown = computed(() => processingCooldown.apply(5));
const [generalTab, generalTabCollapsed] = createCollapsibleModifierSections(() => [
{
title: "Processed Letters Amount",
modifier: lettersGain,
base: 1
},
{
title: "Processed Letters Cooldown",
modifier: processingCooldown,
base: 5
}
]);
const showModifiersModal = ref(false);
const modifiersModal = jsx(() => (
<Modal
modelValue={showModifiersModal.value}
onUpdate:modelValue={(value: boolean) => (showModifiersModal.value = value)}
v-slots={{
header: () => <h2>{name} Modifiers</h2>,
body: generalTab
}}
/>
));
globalBus.on("update", diff => {
if (Decimal.lt(main.day.value, day)) {
return;
}
if (Decimal.gte(processingProgress.value, computedProcessingCooldown.value)) {
processingProgress.value = computedProcessingCooldown.value;
} else {
processingProgress.value = Decimal.add(processingProgress.value, diff);
if (process.isHolding.value) {
process.onClick();
}
}
});
const { total: totalLetters, trackerDisplay } = setUpDailyProgressTracker({
resource: letters,
goal: 1e6,
name,
day,
color,
textColor: "var(--feature-foreground)",
modal: {
show: showModifiersModal,
display: modifiersModal
}
});
return {
name,
day,
color,
letters,
totalLetters,
processingProgress,
buyables,
milestones,
minWidth: 700,
generalTabCollapsed,
collapseMilestones,
display: jsx(() => (
<>
{render(trackerDisplay)}
<Spacer />
<MainDisplay resource={letters} color={color} />
{render(process)}
<div>
The more letters you process, the more you'll improve at processing letters.
</div>
<div>Currently: {format(synergy.value)}x</div>
<Spacer />
{renderRow(...Object.values(buyables))}
<Spacer />
{milestonesDisplay()}
</>
)),
minimizedDisplay: jsx(() => (
<div>
{name} - {format(letters.value)} {letters.displayName}
</div>
))
};
});
export default layer;

View file

@ -426,7 +426,10 @@ const layer = createLayer(id, () => {
effectDisplay: "Unlock an elf that autobuys coal drills." effectDisplay: "Unlock an elf that autobuys coal drills."
}, },
visibility: () => showIf(expanderElfMilestones[2].earned.value && main.day.value >= 13), visibility: () => showIf(expanderElfMilestones[2].earned.value && main.day.value >= 13),
shouldEarn: () => expandersElfTraining.level.value >= 4 shouldEarn: () => expandersElfTraining.level.value >= 4,
onComplete() {
main.days[3].recentlyUpdated.value = true;
}
})), })),
createMilestone(() => ({ createMilestone(() => ({
display: { display: {
@ -481,7 +484,10 @@ const layer = createLayer(id, () => {
}, },
visibility: () => visibility: () =>
showIf(heatedCutterElfMilestones[3].earned.value && main.day.value >= 13), showIf(heatedCutterElfMilestones[3].earned.value && main.day.value >= 13),
shouldEarn: () => heatedCutterElfTraining.level.value >= 5 shouldEarn: () => heatedCutterElfTraining.level.value >= 5,
onComplete() {
main.days[3].recentlyUpdated.value = true;
}
})) }))
] as Array<GenericMilestone>; ] as Array<GenericMilestone>;
const heatedPlanterElfMilestones = [ const heatedPlanterElfMilestones = [
@ -575,11 +581,14 @@ const layer = createLayer(id, () => {
createMilestone(() => ({ createMilestone(() => ({
display: { display: {
requirement: "Noel Level 5", requirement: "Noel Level 5",
effectDisplay: "Unlock an elf that autobuys metal buyables" effectDisplay: "Unlock an elf that autobuys metal machines"
}, },
visibility: () => visibility: () =>
showIf(fertilizerElfMilestones[3].earned.value && main.day.value >= 13), showIf(fertilizerElfMilestones[3].earned.value && main.day.value >= 13),
shouldEarn: () => fertilizerElfTraining.level.value >= 5 shouldEarn: () => fertilizerElfTraining.level.value >= 5,
onComplete() {
main.days[3].recentlyUpdated.value = true;
}
})) }))
] as Array<GenericMilestone>; ] as Array<GenericMilestone>;
const smallfireElfMilestones = [ const smallfireElfMilestones = [
@ -782,7 +791,10 @@ const layer = createLayer(id, () => {
effectDisplay: "Unlock a second row of box buyables" effectDisplay: "Unlock a second row of box buyables"
}, },
visibility: () => showIf(boxElfMilestones[2].earned.value && main.day.value >= 13), visibility: () => showIf(boxElfMilestones[2].earned.value && main.day.value >= 13),
shouldEarn: () => boxElfTraining.level.value >= 4 shouldEarn: () => boxElfTraining.level.value >= 4,
onComplete() {
main.days[5].recentlyUpdated.value = true;
}
})), })),
createMilestone(() => ({ createMilestone(() => ({
display: { display: {
@ -790,7 +802,10 @@ const layer = createLayer(id, () => {
effectDisplay: "Unlock another row of box upgrades" effectDisplay: "Unlock another row of box upgrades"
}, },
visibility: () => showIf(boxElfMilestones[3].earned.value && main.day.value >= 13), visibility: () => showIf(boxElfMilestones[3].earned.value && main.day.value >= 13),
shouldEarn: () => boxElfTraining.level.value >= 5 shouldEarn: () => boxElfTraining.level.value >= 5,
onComplete() {
main.days[5].recentlyUpdated.value = true;
}
})) }))
] as Array<GenericMilestone>; ] as Array<GenericMilestone>;
const clothElfMilestones = [ const clothElfMilestones = [
@ -850,7 +865,10 @@ const layer = createLayer(id, () => {
effectDisplay: "Unlock another row of focus upgrades" effectDisplay: "Unlock another row of focus upgrades"
}, },
visibility: () => showIf(clothElfMilestones[3].earned.value && main.day.value >= 13), visibility: () => showIf(clothElfMilestones[3].earned.value && main.day.value >= 13),
shouldEarn: () => clothElfTraining.level.value >= 5 shouldEarn: () => clothElfTraining.level.value >= 5,
onComplete() {
main.days[12].recentlyUpdated.value = true;
}
})) }))
] as Array<GenericMilestone>; ] as Array<GenericMilestone>;
const coalDrillElfMilestones = [ const coalDrillElfMilestones = [
@ -884,7 +902,10 @@ const layer = createLayer(id, () => {
}, },
visibility: () => visibility: () =>
showIf(coalDrillElfMilestones[2].earned.value && main.day.value >= 13), showIf(coalDrillElfMilestones[2].earned.value && main.day.value >= 13),
shouldEarn: () => coalDrillElfTraining.level.value >= 4 shouldEarn: () => coalDrillElfTraining.level.value >= 4,
onComplete() {
main.days[2].recentlyUpdated.value = true;
}
})), })),
createMilestone(() => ({ createMilestone(() => ({
display: { display: {
@ -979,7 +1000,10 @@ const layer = createLayer(id, () => {
effectDisplay: "Unlock another row of oil upgrades" effectDisplay: "Unlock another row of oil upgrades"
}, },
visibility: () => showIf(oilElfMilestones[3].earned.value && main.day.value >= 13), visibility: () => showIf(oilElfMilestones[3].earned.value && main.day.value >= 13),
shouldEarn: () => oilElfTraining.level.value >= 5 shouldEarn: () => oilElfTraining.level.value >= 5,
onComplete() {
main.days[8].recentlyUpdated.value = true;
}
})) }))
] as Array<GenericMilestone>; ] as Array<GenericMilestone>;
const heavyDrillElfMilestones = [ const heavyDrillElfMilestones = [
@ -1026,7 +1050,10 @@ const layer = createLayer(id, () => {
}, },
visibility: () => visibility: () =>
showIf(heavyDrillElfMilestones[3].earned.value && main.day.value >= 13), showIf(heavyDrillElfMilestones[3].earned.value && main.day.value >= 13),
shouldEarn: () => heavyDrillElfTraining.level.value >= 5 shouldEarn: () => heavyDrillElfTraining.level.value >= 5,
onComplete() {
main.days[4].recentlyUpdated.value = true;
}
})) }))
] as Array<GenericMilestone>; ] as Array<GenericMilestone>;
// ------------------------------------------------------------------------------- Milestone display // ------------------------------------------------------------------------------- Milestone display
@ -1363,7 +1390,7 @@ const layer = createLayer(id, () => {
const focusUpgrade6 = createUpgrade(() => ({ const focusUpgrade6 = createUpgrade(() => ({
display: { display: {
title: "Focus Doubler", title: "Focus Doubler",
description: "Focus now applies to 6 elves." description: "Focus applies to an additional elf."
}, },
resource: trees.logs, resource: trees.logs,
visibility: () => showIf(elfTraining.clothElfTraining.milestones[4].earned.value), visibility: () => showIf(elfTraining.clothElfTraining.milestones[4].earned.value),
@ -1465,9 +1492,7 @@ const layer = createLayer(id, () => {
}); });
const classroomEffect = computed(() => { const classroomEffect = computed(() => {
return Decimal.add(classrooms.amount.value, 1) return Decimal.add(classrooms.amount.value, 1).pow(0.9);
.pow(0.9)
.pow(paper.upgrades2.classroomUpgrade.bought.value ? 1.1 : 1);
}); });
const classrooms = createBuyable(() => ({ const classrooms = createBuyable(() => ({

View file

@ -1,40 +1,40 @@
import Spacer from "components/layout/Spacer.vue";
import MainDisplay from "features/resources/MainDisplay.vue";
import Toggle from "components/fields/Toggle.vue"; import Toggle from "components/fields/Toggle.vue";
import Spacer from "components/layout/Spacer.vue";
import Modal from "components/Modal.vue"; import Modal from "components/Modal.vue";
import { createCollapsibleModifierSections, setUpDailyProgressTracker } from "data/common"; import { createCollapsibleModifierSections, setUpDailyProgressTracker } from "data/common";
import { createBar } from "features/bars/bar";
import { createBuyable } from "features/buyable";
import { createClickable } from "features/clickables/clickable";
import { jsx, showIf } from "features/feature"; import { jsx, showIf } from "features/feature";
import MainDisplay from "features/resources/MainDisplay.vue";
import { createResource, Resource, trackBest } from "features/resources/resource"; import { createResource, Resource, trackBest } from "features/resources/resource";
import { BaseLayer, createLayer } from "game/layers"; import { createUpgrade, GenericUpgrade } from "features/upgrades/upgrade";
import Decimal, { DecimalSource } from "lib/break_eternity";
import { render, renderRow } from "util/vue";
import { persistent } from "game/persistence";
import { globalBus } from "game/events"; import { globalBus } from "game/events";
import { BaseLayer, createLayer } from "game/layers";
import { import {
createAdditiveModifier, createAdditiveModifier,
createExponentialModifier, createExponentialModifier,
createMultiplicativeModifier, createMultiplicativeModifier,
createSequentialModifier createSequentialModifier
} from "game/modifiers"; } from "game/modifiers";
import { computed, ref, unref } from "vue"; import { noPersist, persistent } from "game/persistence";
import { createBar } from "features/bars/bar"; import Decimal, { DecimalSource } from "lib/break_eternity";
import { Direction } from "util/common";
import { format, formatGain, formatLimit, formatWhole } from "util/break_eternity"; import { format, formatGain, formatLimit, formatWhole } from "util/break_eternity";
import { createClickable } from "features/clickables/clickable"; import { Direction } from "util/common";
import coal from "./coal"; import { render, renderRow } from "util/vue";
import { createUpgrade, GenericUpgrade } from "features/upgrades/upgrade"; import { computed, ref, unref } from "vue";
import { noPersist } from "game/persistence";
import { createBuyable, GenericBuyable } from "features/buyable";
import { main } from "../projEntry"; import { main } from "../projEntry";
import oil from "./oil";
import boxes from "./boxes"; import boxes from "./boxes";
import cloth from "./cloth"; import cloth from "./cloth";
import plastic from "./plastic"; import coal from "./coal";
import dyes from "./dyes"; import dyes from "./dyes";
import management from "./management";
import workshop from "./workshop";
import paper from "./paper";
import { ElfBuyable } from "./elves"; import { ElfBuyable } from "./elves";
import letters from "./letters";
import management from "./management";
import oil from "./oil";
import paper from "./paper";
import plastic from "./plastic";
import workshop from "./workshop";
const id = "metal"; const id = "metal";
const day = 7; const day = 7;
@ -188,6 +188,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
multiplier: 3, multiplier: 3,
description: "Twinkle Level 3", description: "Twinkle Level 3",
enabled: () => management.elfTraining.metalElfTraining.milestones[2].earned.value && !main.isMastery.value enabled: () => management.elfTraining.metalElfTraining.milestones[2].earned.value && !main.isMastery.value
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.add(industrialCrucible.amount.value, 1).sqrt(),
description: "100,000 Letters Processed",
enabled: letters.milestones.industrialCrucibleMilestone.earned
})) }))
]); ]);
const computedAutoSmeltMulti = computed(() => autoSmeltMulti.apply(1)); const computedAutoSmeltMulti = computed(() => autoSmeltMulti.apply(1));
@ -258,6 +263,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
multiplier: 2, multiplier: 2,
description: "Carry ore in boxes", description: "Carry ore in boxes",
enabled: boxes.row2Upgrades.oreUpgrade.bought enabled: boxes.row2Upgrades.oreUpgrade.bought
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.add(dyes.dyes.blue.amount.value, 1).sqrt(),
description: "1000 Letters Processed",
enabled: letters.milestones.miningMilestone.earned
})) }))
]); ]);
const computedOreAmount = computed(() => oreAmount.apply(1)); const computedOreAmount = computed(() => oreAmount.apply(1));
@ -286,6 +296,15 @@ const layer = createLayer(id, function (this: BaseLayer) {
multiplier: 2, multiplier: 2,
description: "Oil the Metal Drills", description: "Oil the Metal Drills",
enabled: oil.row2Upgrades[1].bought enabled: oil.row2Upgrades[1].bought
})),
createMultiplicativeModifier(() => ({
multiplier: () =>
Decimal.pow(
2,
Object.values(letters.milestones).filter(m => m.earned.value).length
),
description: "100 Letters Processed",
enabled: letters.milestones.autoSmeltingMilestone.earned
})) }))
]); ]);
const computedOreSpeed = computed(() => oreSpeed.apply(Decimal.recip(maxOreProgress))); const computedOreSpeed = computed(() => oreSpeed.apply(Decimal.recip(maxOreProgress)));

View file

@ -450,7 +450,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
} }
let v = Decimal.div(x, 1e7).log(10); let v = Decimal.div(x, 1e7).log(10);
v = v.div(Decimal.pow(0.95, paper.books.oilBook.totalAmount.value)); v = v.div(Decimal.pow(0.95, paper.books.oilBook.totalAmount.value));
if (Decimal.gte(v, 100)) v = Decimal.mul(v, 100).root(4); if (Decimal.gte(v, 1e4)) v = Decimal.mul(v, 1e4).root(2);
if (Decimal.gte(v, 200)) v = Decimal.mul(v, 200).root(2);
if (Decimal.gte(v, 50)) v = Decimal.mul(v, 50).root(2);
return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0);
}, },
display: jsx(() => ( display: jsx(() => (
@ -739,7 +741,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
cost: 1e13, cost: 1e13,
display: { display: {
title: "Dye Synergy I", title: "Dye Synergy I",
description: "Red dye boosts yellow dye gain *(log(x)^0.75)" description: "Red dye boosts yellow dye gain by (log(x)^0.75)"
}, },
visibility: () => visibility: () =>
showIf(management.elfTraining.oilElfTraining.milestones[4].earned.value), showIf(management.elfTraining.oilElfTraining.milestones[4].earned.value),
@ -760,8 +762,13 @@ const layer = createLayer(id, function (this: BaseLayer) {
resource: noPersist(oil), resource: noPersist(oil),
cost: 1e15, cost: 1e15,
display: { display: {
title: "Colorful Focus", title: "Colorful Plastic",
description: "Sum of secondary dyes increases max focus multiplier by cbrt(x)" description: jsx(() => (
<>
Sum of secondary dyes increases plastic gain by <sup>3</sup>
<Sqrt>x</Sqrt>
</>
))
}, },
visibility: () => visibility: () =>
showIf(management.elfTraining.oilElfTraining.milestones[4].earned.value), showIf(management.elfTraining.oilElfTraining.milestones[4].earned.value),
@ -772,7 +779,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
cost: 1e16, cost: 1e16,
display: { display: {
title: "Dye Synergy II", title: "Dye Synergy II",
description: "Blue dye boosts red dye gain *log(x)" description: "Blue dye boosts red dye gain by log(x)"
}, },
visibility: () => visibility: () =>
showIf(management.elfTraining.oilElfTraining.milestones[4].earned.value), showIf(management.elfTraining.oilElfTraining.milestones[4].earned.value),

View file

@ -6,7 +6,7 @@ import Spacer from "components/layout/Spacer.vue";
import Modal from "components/Modal.vue"; import Modal from "components/Modal.vue";
import { createCollapsibleModifierSections, setUpDailyProgressTracker } from "data/common"; import { createCollapsibleModifierSections, setUpDailyProgressTracker } from "data/common";
import { main } from "data/projEntry"; import { main } from "data/projEntry";
import { BuyableOptions, createBuyable, GenericBuyable } from "features/buyable"; import { BuyableOptions, createBuyable } from "features/buyable";
import { createClickable } from "features/clickables/clickable"; import { createClickable } from "features/clickables/clickable";
import { createCumulativeConversion, createPolynomialScaling } from "features/conversion"; import { createCumulativeConversion, createPolynomialScaling } from "features/conversion";
import { jsx, showIf } from "features/feature"; import { jsx, showIf } from "features/feature";
@ -19,15 +19,15 @@ import { createMultiplicativeModifier, createSequentialModifier, Modifier } from
import { noPersist } from "game/persistence"; import { noPersist } from "game/persistence";
import Decimal, { DecimalSource, format, formatSmall, formatWhole } from "util/bignum"; import Decimal, { DecimalSource, format, formatSmall, formatWhole } from "util/bignum";
import { WithRequired } from "util/common"; import { WithRequired } from "util/common";
import { render, renderCol, renderGrid, renderRow } from "util/vue"; import { render, renderCol, renderGrid } from "util/vue";
import { computed, ComputedRef, ref, unref } from "vue"; import { computed, ComputedRef, ref, unref } from "vue";
import cloth from "./cloth"; import cloth from "./cloth";
import coal from "./coal"; import coal from "./coal";
import dyes from "./dyes";
import elves, { ElfBuyable } from "./elves"; import elves, { ElfBuyable } from "./elves";
import management from "./management";
import plastic from "./plastic"; import plastic from "./plastic";
import trees from "./trees"; import trees from "./trees";
import dyes from "./dyes";
import management from "./management";
import workshop from "./workshop"; import workshop from "./workshop";
import wrappingPaper from "./wrapping-paper"; import wrappingPaper from "./wrapping-paper";
@ -244,7 +244,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
const paperBook = createBook({ const paperBook = createBook({
name: "The Book Thief", name: "The Book Thief",
elfName: "Star", elfName: "Star",
buyableName: "Paper Buyables", buyableName: "Books",
visibility: () => showIf(elves.elves.paperElf.bought.value) visibility: () => showIf(elves.elves.paperElf.bought.value)
}); });
const boxBook = createBook({ const boxBook = createBook({
@ -280,13 +280,13 @@ const layer = createLayer(id, function (this: BaseLayer) {
const metalBook = createBook({ const metalBook = createBook({
name: "Physical Metallurgy", name: "Physical Metallurgy",
elfName: "Twinkle", elfName: "Twinkle",
buyableName: "Metal Buyables", buyableName: "Metal Machines",
visibility: () => showIf(elves.elves.metalElf.bought.value) visibility: () => showIf(elves.elves.metalElf.bought.value)
}); });
const dyeBook = createBook({ const dyeBook = createBook({
name: "Arts and Crafts", name: "Arts and Crafts",
elfName: "Carol", elfName: "Carol",
buyableName: "Dye Buyables", buyableName: "Dyes",
visibility: () => showIf(elves.elves.dyeElf.bought.value) visibility: () => showIf(elves.elves.dyeElf.bought.value)
}); });
const books = { const books = {
@ -360,17 +360,17 @@ const layer = createLayer(id, function (this: BaseLayer) {
description: "Books are less expensive" description: "Books are less expensive"
} }
})); }));
const classroomUpgrade = createUpgrade(() => ({ const treeUpgrade = createUpgrade(() => ({
resource: noPersist(paper), resource: noPersist(paper),
cost: 1e40, cost: 1e40,
visibility: () => visibility: () =>
showIf(management.elfTraining.heavyDrillElfTraining.milestones[4].earned.value), showIf(management.elfTraining.heavyDrillElfTraining.milestones[4].earned.value),
display: { display: {
title: "Classroom Supplies", title: "Un-Processing",
description: "Classrooms' effect is raised to the 1.1" description: "Log gain is raised to the ^1.05"
} }
})); }));
const upgrades2 = { ashUpgrade, bookUpgrade, classroomUpgrade }; const upgrades2 = { ashUpgrade, bookUpgrade, treeUpgrade };
const paperGain = createSequentialModifier(() => [ const paperGain = createSequentialModifier(() => [
createMultiplicativeModifier(() => ({ createMultiplicativeModifier(() => ({
multiplier: 2, multiplier: 2,

View file

@ -281,6 +281,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
multiplier: () => Decimal.add(oil.buildExtractor.amount.value, 1).pow(1.25), multiplier: () => Decimal.add(oil.buildExtractor.amount.value, 1).pow(1.25),
description: "Snowball Level 4", description: "Snowball Level 4",
enabled: () => management.elfTraining.kilnElfTraining.milestones[3].earned.value && !main.isMastery.value enabled: () => management.elfTraining.kilnElfTraining.milestones[3].earned.value && !main.isMastery.value
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.add(dyes.secondaryDyeSum.value, 1).cbrt(),
description: "Colorful Plastic",
enabled: oil.row3Upgrades[2].bought
})) }))
]); ]);
const computedPlasticGain = computed(() => plasticGain.apply(0)); const computedPlasticGain = computed(() => plasticGain.apply(0));

View file

@ -538,6 +538,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
exponent: 1.2, exponent: 1.2,
description: "100% Foundation Completed", description: "100% Foundation Completed",
enabled: workshop.milestones.logGainMilestone3.earned enabled: workshop.milestones.logGainMilestone3.earned
})),
createExponentialModifier(() => ({
exponent: 1.05,
description: "Un-Processing",
enabled: paper.upgrades2.treeUpgrade.bought
})) }))
]); ]);

View file

@ -8,6 +8,7 @@ import { main } from "data/projEntry";
import { createBar } from "features/bars/bar"; import { createBar } from "features/bars/bar";
import { createClickable } from "features/clickables/clickable"; import { createClickable } from "features/clickables/clickable";
import { import {
addHardcap,
addSoftcap, addSoftcap,
createIndependentConversion, createIndependentConversion,
createPolynomialScaling createPolynomialScaling
@ -51,19 +52,30 @@ const layer = createLayer(id, function (this: BaseLayer) {
createExponentialModifier(() => ({ createExponentialModifier(() => ({
exponent: 0.99, exponent: 0.99,
description: "Holly Level 5", description: "Holly Level 5",
enabled: () => management.elfTraining.cutterElfTraining.milestones[4].earned.value && !main.isMastery.value enabled: () =>
management.elfTraining.cutterElfTraining.milestones[4].earned.value &&
!main.isMastery.value
})) }))
]) ]);
const addScaling = (value: DecimalSource) => computed(() => costDecrease.apply(value)); const addScaling = (value: DecimalSource) => computed(() => costDecrease.apply(value));
const foundationConversion = createIndependentConversion(() => ({ const foundationConversion = createIndependentConversion(() => ({
scaling: addSoftcap( // note: 5423 is a magic number. Don't touch this or it'll self-destruct.
addSoftcap(createPolynomialScaling( scaling: addHardcap(
addScaling(250), 1.5), addScaling(5423), 1 / 1e10), addSoftcap(
addSoftcap(
createPolynomialScaling(addScaling(250), 1.5),
addScaling(5423),
1 / 1e10
),
addScaling(1e20), addScaling(1e20),
3e8 3e8
), ),
computed(() =>
management.elfTraining.expandersElfTraining.milestones[2].earned.value ? 1000 : 100
)
),
baseResource: trees.logs, baseResource: trees.logs,
gainResource: noPersist(foundationProgress), gainResource: noPersist(foundationProgress),
roundUpCost: true, roundUpCost: true,
@ -77,7 +89,12 @@ const layer = createLayer(id, function (this: BaseLayer) {
display: jsx(() => ( display: jsx(() => (
<> <>
<b style="font-size: x-large"> <b style="font-size: x-large">
Build {formatWhole((main.isMastery.value ? mastery.foundationConversion : foundationConversion).actualGain.value)}% of the foundation Build{" "}
{formatWhole(
(main.isMastery.value ? mastery.foundationConversion : foundationConversion)
.actualGain.value
)}
% of the foundation
</b> </b>
<br /> <br />
<br /> <br />
@ -85,9 +102,21 @@ const layer = createLayer(id, function (this: BaseLayer) {
{main.isMastery.value || mastered ? "Requirement" : "Cost"}:{" "} {main.isMastery.value || mastered ? "Requirement" : "Cost"}:{" "}
{displayResource( {displayResource(
main.isMastery.value ? trees.mastery.logs : trees.logs, main.isMastery.value ? trees.mastery.logs : trees.logs,
Decimal.gte((main.isMastery.value ? mastery.foundationConversion : foundationConversion).actualGain.value, 1) Decimal.gte(
? (main.isMastery.value ? mastery.foundationConversion : foundationConversion).currentAt.value (main.isMastery.value
: (main.isMastery.value ? mastery.foundationConversion : foundationConversion).nextAt.value ? mastery.foundationConversion
: foundationConversion
).actualGain.value,
1
)
? (main.isMastery.value
? mastery.foundationConversion
: foundationConversion
).currentAt.value
: (main.isMastery.value
? mastery.foundationConversion
: foundationConversion
).nextAt.value
)}{" "} )}{" "}
{trees.logs.displayName} {trees.logs.displayName}
</span> </span>
@ -95,13 +124,42 @@ const layer = createLayer(id, function (this: BaseLayer) {
)), )),
visibility: () => visibility: () =>
showIf( showIf(
Decimal.lt(main.isMastery.value ? mastery.foundationProgress.value : foundationProgress.value, 100) || main.isMastery.value
? Decimal.lt(mastery.foundationProgress.value, 100)
: Decimal.lt(
foundationProgress.value,
management.elfTraining.expandersElfTraining.milestones[2].earned.value management.elfTraining.expandersElfTraining.milestones[2].earned.value
? 1000
: 100
)
), ),
canClick: () => canClick: () => {
Decimal.gte((main.isMastery.value ? trees.mastery.logs.value : trees.logs.value), (main.isMastery.value ? mastery.foundationConversion : foundationConversion).nextAt.value) && if (main.isMastery.value) {
(Decimal.lt(foundationProgress.value, 100) || if (
management.elfTraining.expandersElfTraining.milestones[2].earned.value), Decimal.lt(trees.mastery.logs.value, mastery.foundationConversion.nextAt.value)
) {
return false;
}
if (Decimal.gte(foundationProgress.value, 100)) {
return false;
}
} else {
if (Decimal.lt(trees.logs.value, foundationConversion.nextAt.value)) {
return false;
}
if (
Decimal.gte(
foundationProgress.value,
management.elfTraining.expandersElfTraining.milestones[2].earned.value
? 1000
: 100
)
) {
return false;
}
}
return true;
},
onClick() { onClick() {
if (!unref(this.canClick)) { if (!unref(this.canClick)) {
return; return;
@ -286,7 +344,6 @@ const layer = createLayer(id, function (this: BaseLayer) {
) )
})); }));
watchEffect(() => { watchEffect(() => {
if (main.day.value === day && Decimal.gte(foundationProgress.value, 100)) { if (main.day.value === day && Decimal.gte(foundationProgress.value, 100)) {
main.completeDay(); main.completeDay();
@ -297,8 +354,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
const foundationProgress = createResource<DecimalSource>(0, "foundation progress"); const foundationProgress = createResource<DecimalSource>(0, "foundation progress");
const foundationConversion = createIndependentConversion(() => ({ const foundationConversion = createIndependentConversion(() => ({
scaling: addSoftcap( scaling: addSoftcap(
addSoftcap(createPolynomialScaling( addSoftcap(
addScaling(250), 1.5), addScaling(5423), 1 / 1e10), createPolynomialScaling(addScaling(250), 1.5),
addScaling(5423),
1 / 1e10
),
addScaling(1e20), addScaling(1e20),
3e8 3e8
), ),
@ -319,7 +379,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
const autoCutMilestone1 = createMilestone(() => ({ const autoCutMilestone1 = createMilestone(() => ({
display: { display: {
requirement: "10% Foundation Completed", requirement: "10% Foundation Completed",
effectDisplay: "Cut an additional tree per second for each 5% of foundation completed" effectDisplay:
"Cut an additional tree per second for each 5% of foundation completed"
}, },
shouldEarn: () => Decimal.gte(foundationProgress.value, 10), shouldEarn: () => Decimal.gte(foundationProgress.value, 10),
visibility: () => showIf(logGainMilestone1.earned.value), visibility: () => showIf(logGainMilestone1.earned.value),
@ -481,8 +542,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
extraExpansionMilestone3, extraExpansionMilestone3,
extraExpansionMilestone4, extraExpansionMilestone4,
extraExpansionMilestone5 extraExpansionMilestone5
} };
})() })();
return { return {
name, name,
@ -508,7 +569,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
<div> <div>
<span>The foundation is </span> <span>The foundation is </span>
<h2 style={`color: ${color}; text-shadow: 0 0 10px ${color}`}> <h2 style={`color: ${color}; text-shadow: 0 0 10px ${color}`}>
{formatWhole(main.isMastery.value ? mastery.foundationProgress.value : foundationProgress.value)} {formatWhole(
main.isMastery.value
? mastery.foundationProgress.value
: foundationProgress.value
)}
</h2> </h2>
% completed % completed
</div> </div>
@ -523,7 +588,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
)), )),
minimizedDisplay: jsx(() => ( minimizedDisplay: jsx(() => (
<div> <div>
{name} - {format(foundationProgress.value)} {foundationProgress.displayName} {name} - {format(foundationProgress.value)}% {foundationProgress.displayName}
</div> </div>
)) ))
}; };

View file

@ -8,11 +8,12 @@ import {
} from "features/feature"; } from "features/feature";
import { BaseLayer, createLayer, GenericLayer, layers } from "game/layers"; import { BaseLayer, createLayer, GenericLayer, layers } from "game/layers";
import { persistent } from "game/persistence"; import { persistent } from "game/persistence";
import type { PlayerData } from "game/player"; import type { LayerData, PlayerData } from "game/player";
import player from "game/player"; import player from "game/player";
import { format, formatTime } from "util/bignum"; import Decimal, { format, formatTime } from "util/bignum";
import { Computable, convertComputable, ProcessedComputable } from "util/computed"; import { Computable, convertComputable, ProcessedComputable } from "util/computed";
import { createLazyProxy } from "util/proxies"; import { createLazyProxy } from "util/proxies";
import { save } from "util/save";
import { renderRow, VueFeature } from "util/vue"; import { renderRow, VueFeature } from "util/vue";
import type { Ref } from "vue"; import type { Ref } from "vue";
import { computed, ref, unref } from "vue"; import { computed, ref, unref } from "vue";
@ -24,6 +25,7 @@ import coalSymbol from "./symbols/coal.png";
import dyesSymbol from "./symbols/dyes.png"; import dyesSymbol from "./symbols/dyes.png";
import elfSymbol from "./symbols/elf.png"; import elfSymbol from "./symbols/elf.png";
import managementSymbol from "./symbols/elfManagement.png"; import managementSymbol from "./symbols/elfManagement.png";
import lettersSymbol from "./symbols/letterbox.png";
import metalSymbol from "./symbols/metal.png"; import metalSymbol from "./symbols/metal.png";
import oilSymbol from "./symbols/oil.png"; import oilSymbol from "./symbols/oil.png";
import paperSymbol from "./symbols/paperStacks.png"; import paperSymbol from "./symbols/paperStacks.png";
@ -43,6 +45,7 @@ import cloth from "./layers/cloth";
import oil from "./layers/oil"; import oil from "./layers/oil";
import plastic from "./layers/plastic"; import plastic from "./layers/plastic";
import dyes from "./layers/dyes"; import dyes from "./layers/dyes";
import letters from "./layers/letters";
import management from "./layers/management"; import management from "./layers/management";
import wrappingPaper from "./layers/wrapping-paper"; import wrappingPaper from "./layers/wrapping-paper";
import { createReset } from "features/reset"; import { createReset } from "features/reset";
@ -279,7 +282,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
symbol: dyesSymbol, symbol: dyesSymbol,
story: "To make toys, we're going to need some color to make them look nice and enticing! We can't just give kids clear toys after all! To add some color to our toys, we'll need some dyes!", story: "To make toys, we're going to need some color to make them look nice and enticing! We can't just give kids clear toys after all! To add some color to our toys, we'll need some dyes!",
completedStory: completedStory:
"After all that effort, you finally have a rainbow of dyes to choose from! Now the children won't be able to resist the toys you have to offer, once you get them made of course..." "After all that effort, you finally have a rainbow of dyes to choose from! Now the children won't be able to resist the toys you have to offer, once you get them made of course... Good Job!"
})), })),
createDay(() => ({ createDay(() => ({
day: 12, day: 12,
@ -302,10 +305,11 @@ export const main = createLayer("main", function (this: BaseLayer) {
createDay(() => ({ createDay(() => ({
day: 14, day: 14,
shouldNotify: false, shouldNotify: false,
layer: null, // "letters to santa" layer: "letters",
symbol: "", symbol: lettersSymbol,
story: "", story: "Fully prepared to start working on presents, you realize you don't actually know what to make! You ask Santa and he points at a massive pile of letters hiding just off-camera. Those are all the letters to Santa that need to be processed, sorted, and categorized appropriately so every kid gets what they need!",
completedStory: "" completedStory:
"The letters are sorted! You have a slight feeling you may have rushed a little, and suddenly understand why sometimes you don't get everything you asked Santa for every year, or even the occasional bad gift. You sympathetically pat Santa on the back as you head to bed for the day. Good Job!"
})), })),
createDay(() => ({ createDay(() => ({
day: 15, day: 15,
@ -398,6 +402,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
day.value++; day.value++;
main.minimized.value = false; main.minimized.value = false;
if (player.autoPause) player.devSpeed = 0; if (player.autoPause) player.devSpeed = 0;
save();
} }
return { return {
@ -463,7 +468,8 @@ export const getInitialLayers = (
plastic, plastic,
dyes, dyes,
wrappingPaper, wrappingPaper,
management management,
letters
]; ];
/** /**
@ -487,6 +493,14 @@ export function fixOldSave(
if (!["0.0", "0.1", "0.2", "0.3", "0.4"].includes(oldVersion ?? "")) { if (!["0.0", "0.1", "0.2", "0.3", "0.4"].includes(oldVersion ?? "")) {
return; return;
} }
if ((player.layers?.workshop as LayerData<typeof workshop> | undefined)?.foundationProgress) {
(player.layers?.workshop as LayerData<typeof workshop> | undefined)!.foundationProgress =
Decimal.min(
(player.layers!.workshop as LayerData<typeof workshop> | undefined)!
.foundationProgress!,
1000
);
}
/*player.offlineProd = false; /*player.offlineProd = false;
delete player.layers?.management; delete player.layers?.management;
if ((player.layers?.main as LayerData<typeof main> | undefined)?.days?.[11]) { if ((player.layers?.main as LayerData<typeof main> | undefined)?.days?.[11]) {

View file

@ -1,5 +1,6 @@
import projInfo from "data/projInfo.json"; import projInfo from "data/projInfo.json";
import { globalBus } from "game/events"; import { globalBus } from "game/events";
import { layers } from "game/layers";
import type { Player, PlayerData } from "game/player"; import type { Player, PlayerData } from "game/player";
import player, { stringifySave } from "game/player"; import player, { stringifySave } from "game/player";
import settings, { loadSettings } from "game/settings"; import settings, { loadSettings } from "game/settings";
@ -126,12 +127,18 @@ export async function loadSave(playerObj: Partial<PlayerData>): Promise<void> {
} }
setInterval(() => { setInterval(() => {
if (player.autosave) { if (
player.autosave &&
(layers as any).main.days[(layers as any).main.day.value - 1].opened.value
) {
save(); save();
} }
}, 1000); }, 1000);
window.onbeforeunload = () => { window.onbeforeunload = () => {
if (player.autosave) { if (
player.autosave &&
(layers as any).main.days[(layers as any).main.day.value - 1].opened.value
) {
save(); save();
} }
}; };