Implemented boxes day

This commit is contained in:
thepaperpilot 2022-12-04 16:50:39 -06:00
parent 3ba15fd969
commit f670ffa6aa
7 changed files with 522 additions and 37 deletions

View file

@ -11,6 +11,7 @@
<img v-if="day >= 3" :src="elves" class="scene-item" style="left: 52%; bottom: 12%" />
<div v-if="day >= 4" class="scene-bubble" style="left: 50%; bottom: 38%">
<img v-if="day >= 4" :src="paper" class="scene-item" />
<img v-if="day >= 5" :src="boxes" class="scene-item" />
</div>
</div>
</template>
@ -21,6 +22,7 @@ import workshop from "./symbols/sws.png";
import coal from "./symbols/coal.png";
import elves from "./symbols/elf.png";
import paper from "./symbols/paperStacks.png";
import boxes from "./symbols/cardboardBox.png";
defineProps<{
day: number;

204
src/data/layers/boxes.tsx Normal file
View file

@ -0,0 +1,204 @@
/**
* @module
* @hidden
*/
import Spacer from "components/layout/Spacer.vue";
import { main } from "data/projEntry";
import { createBar } from "features/bars/bar";
import { createBuyable, GenericBuyable } from "features/buyable";
import { createClickable } from "features/clickables/clickable";
import { createCumulativeConversion, createPolynomialScaling } from "features/conversion";
import { jsx, showIf } from "features/feature";
import MainDisplay from "features/resources/MainDisplay.vue";
import { createResource, displayResource, trackTotal } from "features/resources/resource";
import { createUpgrade } from "features/upgrades/upgrade";
import { BaseLayer, createLayer } from "game/layers";
import Decimal, { DecimalSource, format, formatWhole } from "util/bignum";
import { Direction } from "util/common";
import { render, renderRow } from "util/vue";
import { unref, watchEffect } from "vue";
import trees from "./trees";
const id = "boxes";
const day = 6;
const layer = createLayer(id, function (this: BaseLayer) {
const name = "Boxes";
const color = "#964B00";
const colorDark = "#964B00";
const totalBoxesGoal = 5e4;
const boxes = createResource<DecimalSource>(0, "boxes");
const totalBoxes = trackTotal(boxes);
const boxesConversion = createCumulativeConversion(() => ({
scaling: createPolynomialScaling(1e10, 1),
baseResource: trees.logs,
gainResource: boxes,
roundUpCost: true
}));
const makeBoxes = createClickable(() => ({
display: jsx(() => {
return (
<>
<span style="font-size: large">
Create {formatWhole(boxesConversion.currentGain.value)} {boxes.displayName}
</span>
<br />
<span style="font-size: large">
Cost:{" "}
{displayResource(
trees.logs,
Decimal.gte(boxesConversion.actualGain.value, 1)
? boxesConversion.currentAt.value
: boxesConversion.nextAt.value
)}{" "}
{trees.logs.displayName}
</span>
</>
);
}),
canClick: () => Decimal.gte(boxesConversion.actualGain.value, 1),
onClick() {
if (!unref(this.canClick)) {
return;
}
boxesConversion.convert();
},
style: "width: 600px; min-height: unset"
}));
const logsUpgrade = createUpgrade(() => ({
display: {
title: "Carry logs in boxes",
description: "Double log gain and unlock a new elf for training"
},
resource: boxes,
cost: 100
}));
const ashUpgrade = createUpgrade(() => ({
display: {
title: "Carry ash in boxes",
description: "Double ash gain and unlock a new elf for training"
},
resource: boxes,
cost: 1000
}));
const coalUpgrade = createUpgrade(() => ({
display: {
title: "Carry coal in boxes",
description: "Double coal gain and unlock a new elf for training"
},
resource: boxes,
cost: 4000
}));
const upgrades = { logsUpgrade, ashUpgrade, coalUpgrade };
const logBoxesBuyable = createBuyable(() => ({
display: {
title: "Carry more logs",
description: "Use boxes to carry even more logs, boosting their gain",
effectDisplay: jsx(() => (
<>{format(Decimal.div(logBoxesBuyable.amount.value, 2).add(1))}x</>
))
},
resource: boxes,
cost() {
return Decimal.pow(3, logBoxesBuyable.amount.value).times(100);
},
visibility: () => showIf(logsUpgrade.bought.value)
})) as GenericBuyable;
const ashBoxesBuyable = createBuyable(() => ({
display: {
title: "Carry more ash",
description: "Use boxes to carry even more ash, boosting their gain",
effectDisplay: jsx(() => (
<>{format(Decimal.div(ashBoxesBuyable.amount.value, 2).add(1))}x</>
))
},
resource: boxes,
cost() {
return Decimal.pow(5, ashBoxesBuyable.amount.value).times(1000);
},
visibility: () => showIf(ashUpgrade.bought.value)
})) as GenericBuyable;
const coalBoxesBuyable = createBuyable(() => ({
display: {
title: "Carry more coal",
description: "Use boxes to carry even more coal, boosting their gain",
effectDisplay: jsx(() => (
<>{format(Decimal.div(coalBoxesBuyable.amount.value, 2).add(1))}x</>
))
},
resource: boxes,
cost() {
return Decimal.pow(7, coalBoxesBuyable.amount.value).times(1000);
},
visibility: () => showIf(coalUpgrade.bought.value)
})) as GenericBuyable;
const buyables = { logBoxesBuyable, ashBoxesBuyable, coalBoxesBuyable };
const dayProgress = createBar(() => ({
direction: Direction.Right,
width: 600,
height: 25,
fillStyle: `backgroundColor: ${colorDark}`,
textStyle: "color: var(--feature-foreground)",
progress: () =>
main.day.value === day
? Decimal.div(
Decimal.log10(Decimal.add(totalBoxes.value, 1)),
Decimal.log10(totalBoxesGoal)
)
: 1,
display: jsx(() =>
main.day.value === day ? (
<>
{formatWhole(totalBoxes.value)}/{formatWhole(totalBoxesGoal)}
</>
) : (
""
)
)
}));
watchEffect(() => {
if (main.day.value === day && Decimal.gte(totalBoxes.value, totalBoxesGoal)) {
main.completeDay();
}
});
return {
name,
day,
color,
boxes,
totalBoxes,
boxesConversion,
upgrades,
buyables,
minWidth: 700,
display: jsx(() => (
<>
<div>
{main.day.value === day
? `Reach ${formatWhole(totalBoxesGoal)} total ${
boxes.displayName
} to complete the day`
: `${name} Complete!`}
</div>
{render(dayProgress)}
<Spacer />
<MainDisplay resource={boxes} color={color} style="margin-bottom: 0" />
<Spacer />
{render(makeBoxes)}
<Spacer />
{renderRow(...Object.values(upgrades))}
{renderRow(...Object.values(buyables))}
</>
))
};
});
export default layer;

View file

@ -31,6 +31,7 @@ import {
import { createUpgrade, Upgrade } from "features/upgrades/upgrade";
import elves from "./elves";
import paper from "./paper";
import boxes from "./boxes";
interface BetterFertilizerUpgOptions {
canAfford: () => boolean;
@ -91,10 +92,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
const buildFire = createBuyable(() => ({
resource: trees.logs,
cost() {
return Decimal.times(buildBonfire.amount.value, 10)
.plus(this.amount.value)
.pow(1.5)
.times(1e4);
let v = this.amount.value;
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 2).div(100);
if (Decimal.gte(v, 10000)) v = Decimal.pow(v, 2).div(10000);
v = Decimal.pow(0.95, paper.books.smallFireBook.amount.value).times(v);
return Decimal.times(v, 10).plus(v).pow(1.5).times(1e4);
},
display: jsx(() => (
<>
@ -119,7 +121,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
color: colorText,
width: "160px"
}
})) as GenericBuyable;
})) as GenericBuyable & { resource: Resource };
const minFire = createClickable(() => ({
display: "0",
style: { minHeight: "20px", width: "40px", color: colorText },
@ -168,7 +170,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
const bonfireAsh = computed(() => Decimal.times(activeBonfires.value, 1000));
const buildBonfire = createBuyable(() => ({
resource: fireResource,
cost: 10,
cost() {
return Decimal.times(10, Decimal.pow(0.95, paper.books.bonfireBook.amount.value));
},
display: jsx(() => (
<>
<h3>Bonfire</h3>
@ -193,7 +197,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
color: colorText,
width: "160px"
}
})) as GenericBuyable;
})) as GenericBuyable & { resource: Resource };
const minBonfire = createClickable(() => ({
display: "0",
style: { minHeight: "20px", width: "40px", color: colorText },
@ -242,7 +246,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
const buildKiln = createBuyable(() => ({
resource: trees.logs,
cost() {
return Decimal.pow(1.1, this.amount.value).times(1e7);
let v = this.amount.value;
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 2).div(100);
if (Decimal.gte(v, 10000)) v = Decimal.pow(v, 2).div(10000);
v = Decimal.pow(0.95, paper.books.kilnBook.amount.value).times(v);
return Decimal.pow(1.1, v).times(1e7);
},
display: jsx(() => (
<>
@ -267,7 +275,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
color: colorText,
width: "160px"
}
})) as GenericBuyable;
})) as GenericBuyable & { resource: Resource };
const minKiln = createClickable(() => ({
display: "0",
style: { minHeight: "20px", width: "40px", color: colorText },
@ -425,7 +433,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
},
style: { color: colorText },
visibility: () => showIf(warmerCutters.bought.value)
})) as GenericBuyable & { display: { title: string } };
})) as GenericBuyable & { display: { title: string }; resource: Resource };
const heatedPlanters = createBuyable(() => ({
resource: coal,
cost() {
@ -445,7 +453,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
},
style: { color: colorText },
visibility: () => showIf(warmerPlanters.bought.value)
})) as GenericBuyable & { display: { title: string } };
})) as GenericBuyable & { display: { title: string }; resource: Resource };
const moreFertilizer = createBuyable(() => ({
resource: ash,
cost() {
@ -465,7 +473,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
},
style: { color: colorText },
visibility: () => showIf(basicFertilizer.bought.value)
})) as GenericBuyable & { display: { title: string } };
})) as GenericBuyable & { display: { title: string }; resource: Resource };
const row3buyables = [heatedCutters, heatedPlanters, moreFertilizer];
const heatedCutterEffect = createSequentialModifier(() => [
@ -550,6 +558,31 @@ const layer = createLayer(id, function (this: BaseLayer) {
return Decimal.gt(activeKilns.value, 0);
}
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "Carry coal in boxes",
enabled: boxes.upgrades.coalUpgrade.bought
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.div(boxes.buyables.coalBoxesBuyable.amount.value, 2).add(1),
description: "Carry more coal",
enabled: boxes.upgrades.coalUpgrade.bought
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.div(buildFire.amount.value, 10000).add(1),
description: "Small Fires Synergy",
enabled: elves.elves.smallFireElf.bought
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.div(buildBonfire.amount.value, 1000).add(1),
description: "Bonfires Synergy",
enabled: elves.elves.bonfireElf.bought
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.div(buildKiln.amount.value, 100).add(1),
description: "Kiln Synergy",
enabled: elves.elves.kilnElf.bought
})),
createExponentialModifier(() => ({
exponent: 1.25,
description: "3 Elves Trained",
@ -585,6 +618,31 @@ const layer = createLayer(id, function (this: BaseLayer) {
enabled() {
return Decimal.gt(activeKilns.value, 0);
}
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "Carry ash in boxes",
enabled: boxes.upgrades.ashUpgrade.bought
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.div(boxes.buyables.ashBoxesBuyable.amount.value, 2).add(1),
description: "Carry more ash",
enabled: boxes.upgrades.ashUpgrade.bought
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.div(buildFire.amount.value, 10000).add(1),
description: "Small Fires Synergy",
enabled: elves.elves.smallFireElf.bought
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.div(buildBonfire.amount.value, 1000).add(1),
description: "Bonfires Synergy",
enabled: elves.elves.bonfireElf.bought
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.div(buildKiln.amount.value, 100).add(1),
description: "Kiln Synergy",
enabled: elves.elves.kilnElf.bought
}))
]);
const computedAshGain = computed(() => ashGain.apply(0));

View file

@ -2,15 +2,18 @@
* @module
* @hidden
*/
import Toggle from "components/fields/Toggle.vue";
import Spacer from "components/layout/Spacer.vue";
import Modal from "components/Modal.vue";
import { createCollapsibleModifierSections } from "data/common";
import { main } from "data/projEntry";
import { createBar, GenericBar } from "features/bars/bar";
import { GenericBuyable } from "features/buyable";
import { ClickableOptions } from "features/clickables/clickable";
import { jsx, showIf } from "features/feature";
import { createMilestone } from "features/milestones/milestone";
import { createReset } from "features/reset";
import { Resource } from "features/resources/resource";
import { createUpgrade, GenericUpgrade } from "features/upgrades/upgrade";
import { globalBus } from "game/events";
import { BaseLayer, createLayer } from "game/layers";
@ -20,6 +23,7 @@ import Decimal, { DecimalSource, formatWhole } from "util/bignum";
import { Direction } from "util/common";
import { render, renderCol, renderRow } from "util/vue";
import { computed, ref, Ref, unref, watchEffect } from "vue";
import boxes from "./boxes";
import coal from "./coal";
import paper from "./paper";
import trees from "./trees";
@ -71,10 +75,16 @@ const layer = createLayer(id, function (this: BaseLayer) {
thingsToReset: [trees, workshop, coal],
onReset() {
setTimeout(() => {
if (researchMilestone.earned.value) {
if (treeUpgradesMilestone.earned.value) {
trees.row1Upgrades.forEach(upg => (upg.bought.value = true));
trees.row2Upgrades.forEach(upg => (upg.bought.value = true));
} else if (researchMilestone.earned.value) {
trees.row1Upgrades[4].bought.value = true;
trees.row2Upgrades[4].bought.value = true;
}
if (foundationMilestone.earned.value) {
workshop.foundationProgress.value = 100;
}
});
}
}));
@ -152,6 +162,42 @@ const layer = createLayer(id, function (this: BaseLayer) {
enabled: () => Decimal.gt(paper.books.fertilizerBook.amount.value, 0)
}))
]);
const smallFireCooldown = createSequentialModifier(() => [
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "6 Elves Trained",
enabled: elvesMilestone.earned
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.times(paper.books.smallFireBook.amount.value, 0.1).add(1),
description: "Firestarter",
enabled: () => Decimal.gt(paper.books.smallFireBook.amount.value, 0)
}))
]);
const bonfireCooldown = createSequentialModifier(() => [
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "6 Elves Trained",
enabled: elvesMilestone.earned
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.times(paper.books.bonfireBook.amount.value, 0.1).add(1),
description: "An Arsonist's Guide to Writer's Homes in New England",
enabled: () => Decimal.gt(paper.books.bonfireBook.amount.value, 0)
}))
]);
const kilnCooldown = createSequentialModifier(() => [
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "6 Elves Trained",
enabled: elvesMilestone.earned
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.times(paper.books.kilnBook.amount.value, 0.1).add(1),
description: "Little Fires Everywhere",
enabled: () => Decimal.gt(paper.books.kilnBook.amount.value, 0)
}))
]);
const [generalTab, generalTabCollapsed] = createCollapsibleModifierSections(() => [
{
@ -195,6 +241,27 @@ const layer = createLayer(id, function (this: BaseLayer) {
base: 10,
unit: "/s",
visible: elves.fertilizerElf.bought
},
{
title: "Joy Auto-Buy Frequency",
modifier: smallFireCooldown,
base: 10,
unit: "/s",
visible: elves.smallFireElf.bought
},
{
title: "Faith Auto-Buy Frequency",
modifier: bonfireCooldown,
base: 10,
unit: "/s",
visible: elves.bonfireElf.bought
},
{
title: "Snowball Auto-Buy Frequency",
modifier: kilnCooldown,
base: 10,
unit: "/s",
visible: elves.kilnElf.bought
}
]);
const showModifiersModal = ref(false);
@ -209,14 +276,21 @@ const layer = createLayer(id, function (this: BaseLayer) {
/>
));
function createElf(options: {
name: string;
description: string;
buyable: GenericBuyable;
cooldownModifier: Modifier;
}) {
function createElf(
options: {
name: string;
description: string;
buyable: GenericBuyable & { resource: Resource };
cooldownModifier: Modifier;
customCost?: (amount: DecimalSource) => DecimalSource;
hasToggle?: boolean;
toggleDesc?: string;
onAutoPurchase?: VoidFunction;
} & Partial<ClickableOptions>
) {
const trainingCost = computed(() => Decimal.pow(4, totalElves.value).times(1e6));
const buyProgress = persistent<DecimalSource>(0);
const toggle = options.hasToggle ? persistent<boolean>(false) : ref(true);
const computedAutoBuyCooldown = computed(() => options.cooldownModifier.apply(10));
@ -225,9 +299,17 @@ const layer = createLayer(id, function (this: BaseLayer) {
buyProgress.value = Decimal.add(buyProgress.value, diff);
const cooldown = Decimal.recip(computedAutoBuyCooldown.value);
while (Decimal.gte(buyProgress.value, cooldown)) {
if (unref(options.buyable.canPurchase)) {
if (
options.customCost == undefined
? unref(options.buyable.canPurchase)
: Decimal.gte(
options.buyable.resource.value,
options.customCost(options.buyable.amount.value)
)
) {
options.buyable.amount.value = Decimal.add(options.buyable.amount.value, 1);
buyProgress.value = Decimal.sub(buyProgress.value, cooldown);
options.onAutoPurchase?.();
} else {
buyProgress.value = cooldown;
break;
@ -239,6 +321,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
const upgrade = createUpgrade(() => {
return {
...options,
toggle,
buyProgress,
update,
resource: coal.coal,
@ -256,6 +339,15 @@ const layer = createLayer(id, function (this: BaseLayer) {
days 1-3.
</>
)}
{upgrade.bought.value && options.hasToggle === true ? (
<>
<Toggle
title={options.toggleDesc}
onUpdate:modelValue={value => (toggle.value = value)}
modelValue={toggle.value}
/>
</>
) : null}
</>
)),
showCost: !upgrade.bought.value
@ -263,7 +355,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
style: "width: 190px",
onPurchase: elfReset.reset
};
}) as GenericUpgrade & { buyProgress: Ref<number>; update: (diff: number) => void };
}) as GenericUpgrade & {
buyProgress: Ref<number>;
update: (diff: number) => void;
toggle: Ref<boolean>;
};
return upgrade;
}
@ -311,13 +407,66 @@ const layer = createLayer(id, function (this: BaseLayer) {
cooldownModifier: fertilizerCooldown
});
const coalElves = [heatedCuttersElf, heatedPlantersElf, fertilizerElf];
const smallFireElf = createElf({
name: "Joy",
description:
"Joy will automatically purchase small fires you can afford, without actually spending any logs. You can toggle whether or not to enable the purchased small fires automatically. Small fires will start giving a boost to ash and coal gain.",
buyable: coal.buildFire,
cooldownModifier: smallFireCooldown,
visibility: () => showIf(boxes.upgrades.logsUpgrade.bought.value),
hasToggle: true,
toggleDesc: "Activate auto-purchased small fires",
onAutoPurchase() {
if (smallFireElf.toggle.value) {
coal.activeFires.value = Decimal.add(coal.activeFires.value, 1);
}
}
});
const bonfireElf = createElf({
name: "Faith",
description:
"Faith will automatically purchase bonfires you can afford, without actually spending any small fires. You can toggle whether or not to enable the purchased bonfires automatically. Bonfires will start giving a boost to ash and coal gain.",
buyable: coal.buildBonfire,
cooldownModifier: bonfireCooldown,
visibility: () => showIf(boxes.upgrades.ashUpgrade.bought.value),
customCost: amount =>
Decimal.times(amount, 10)
.plus(10)
.times(Decimal.pow(0.95, paper.books.bonfireBook.amount.value)),
hasToggle: true,
toggleDesc: "Activate auto-purchased bonfires",
onAutoPurchase() {
if (bonfireElf.toggle.value) {
coal.activeBonfires.value = Decimal.add(coal.activeBonfires.value, 1);
}
}
});
const kilnElf = createElf({
name: "Snowball",
description:
"Snowball will automatically purchase kilns you can afford, without actually spending any logs. You can toggle whether or not to enable the purchased kilns automatically. Kilns will start giving a boost to ash and coal gain.",
buyable: coal.buildKiln,
cooldownModifier: kilnCooldown,
visibility: () => showIf(boxes.upgrades.coalUpgrade.bought.value),
hasToggle: true,
toggleDesc: "Activate auto-purchased kilns",
onAutoPurchase() {
if (kilnElf.toggle.value) {
coal.activeKilns.value = Decimal.add(coal.activeKilns.value, 1);
}
}
});
const fireElves = [smallFireElf, bonfireElf, kilnElf];
const elves = {
cuttersElf,
plantersElf,
expandersElf,
heatedCuttersElf,
heatedPlantersElf,
fertilizerElf
fertilizerElf,
smallFireElf,
bonfireElf,
kilnElf
};
const totalElves = computed(() => Object.values(elves).filter(elf => elf.bought.value).length);
@ -332,7 +481,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
const researchMilestone = createMilestone(() => ({
display: {
requirement: "2 Elves Trained",
effectDisplay: "Research I & II are't reset after training"
effectDisplay: "Research I & II aren't reset after training"
},
shouldEarn: () => Decimal.gte(totalElves.value, 2),
visibility: () => showIf(manualMilestone.earned.value)
@ -369,13 +518,40 @@ const layer = createLayer(id, function (this: BaseLayer) {
shouldEarn: () => Decimal.gte(totalElves.value, 6),
visibility: () => showIf(forestMilestone.earned.value)
}));
const foundationMilestone = createMilestone(() => ({
display: {
requirement: "7 Elves Trained",
effectDisplay: "Workshop Foundation starts at 100% complete after training"
},
shouldEarn: () => Decimal.gte(totalElves.value, 7),
visibility: () => showIf(elvesMilestone.earned.value && main.day.value > 5)
}));
const forestMilestone2 = createMilestone(() => ({
display: {
requirement: "8 Elves Trained",
effectDisplay: "Forest is twice as large (again)"
},
shouldEarn: () => Decimal.gte(totalElves.value, 8),
visibility: () => showIf(foundationMilestone.earned.value)
}));
const treeUpgradesMilestone = createMilestone(() => ({
display: {
requirement: "9 Elves Trained",
effectDisplay: "Trees upgrades aren't reset after training"
},
shouldEarn: () => Decimal.gte(totalElves.value, 9),
visibility: () => showIf(forestMilestone2.earned.value)
}));
const milestones = [
manualMilestone,
researchMilestone,
coalGainMilestone,
logGainMilestone,
forestMilestone,
elvesMilestone
elvesMilestone,
foundationMilestone,
forestMilestone2,
treeUpgradesMilestone
];
globalBus.on("update", diff => {
@ -427,6 +603,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
<div style="width: 600px">
{renderRow(...treesElves)}
{renderRow(...coalElves)}
{renderRow(...fireElves)}
</div>
{renderCol(...milestones)}
</>

View file

@ -5,10 +5,10 @@
import Spacer from "components/layout/Spacer.vue";
import { main } from "data/projEntry";
import { createBar } from "features/bars/bar";
import { createBuyable, GenericBuyable } from "features/buyable";
import { BuyableOptions, createBuyable, GenericBuyable } from "features/buyable";
import { createClickable } from "features/clickables/clickable";
import { createCumulativeConversion, createPolynomialScaling } from "features/conversion";
import { jsx } from "features/feature";
import { jsx, showIf } from "features/feature";
import MainDisplay from "features/resources/MainDisplay.vue";
import { createResource, displayResource, trackTotal } from "features/resources/resource";
import { BaseLayer, createLayer } from "game/layers";
@ -17,6 +17,7 @@ import { Direction } from "util/common";
import { render, renderCol } from "util/vue";
import { computed, unref, watchEffect } from "vue";
import coal from "./coal";
import elves from "./elves";
import trees from "./trees";
const id = "paper";
@ -78,8 +79,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
style: "width: 600px; min-height: unset"
}));
function createBook(options: { name: string; elfName: string; buyableName: string }) {
function createBook(
options: { name: string; elfName: string; buyableName: string } & Partial<BuyableOptions>
) {
const buyable = createBuyable(() => ({
...options,
display: {
title: options.name,
description: `Print a copy of "${options.name}", which ${options.elfName} will use to improve their skills! Each copy printed will reduce the "${options.buyableName}" price scaling by 0.95x and make ${options.elfName} purchase +10% faster!`,
@ -128,13 +132,34 @@ const layer = createLayer(id, function (this: BaseLayer) {
elfName: "Noel",
buyableName: "Fertilized Soil"
});
const smallFireBook = createBook({
name: "Firestarter",
elfName: "Joy",
buyableName: "Small Fire",
visibility: () => showIf(elves.elves.smallFireElf.bought.value)
});
const bonfireBook = createBook({
name: "An Arsonist's Guide to Writer's Homes in New England",
elfName: "Faith",
buyableName: "Bonfire",
visibility: () => showIf(elves.elves.bonfireElf.bought.value)
});
const kilnBook = createBook({
name: "Little Fires Everywhere",
elfName: "Snowball",
buyableName: "Kiln",
visibility: () => showIf(elves.elves.kilnElf.bought.value)
});
const books = {
cuttersBook,
plantersBook,
expandersBook,
heatedCuttersBook,
heatedPlantersBook,
fertilizerBook
fertilizerBook,
smallFireBook,
bonfireBook,
kilnBook
};
const dayProgress = createBar(() => ({

View file

@ -12,7 +12,7 @@ import { createClickable } from "features/clickables/clickable";
import { jsx, showIf } from "features/feature";
import { createHotkey } from "features/hotkey";
import MainDisplay from "features/resources/MainDisplay.vue";
import { createResource, trackTotal } from "features/resources/resource";
import { createResource, Resource, trackTotal } from "features/resources/resource";
import { createUpgrade } from "features/upgrades/upgrade";
import { globalBus } from "game/events";
import { BaseLayer, createLayer } from "game/layers";
@ -28,6 +28,7 @@ import Decimal, { DecimalSource, format, formatWhole } from "util/bignum";
import { Direction, WithRequired } from "util/common";
import { render, renderRow } from "util/vue";
import { computed, ref, watchEffect } from "vue";
import boxes from "./boxes";
import coal from "./coal";
import elves from "./elves";
import paper from "./paper";
@ -67,6 +68,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
multiplier: 2,
description: "5 Elves Trained",
enabled: elves.milestones[4].earned
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "8 Elves Trained",
enabled: elves.milestones[7].earned
}))
]) as WithRequired<Modifier, "description" | "revert">;
const trees = createResource(
@ -192,7 +198,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
description: "Each cutter cuts down 1 tree/s"
},
visibility: () => showIf(researchUpgrade2.bought.value)
})) as GenericBuyable & { display: { title: string } };
})) as GenericBuyable & { display: { title: string }; resource: Resource };
const autoPlantingBuyable1 = createBuyable(() => ({
resource: logs,
cost() {
@ -208,7 +214,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
description: "Each planter plants 0.5 trees/s"
},
visibility: () => showIf(researchUpgrade2.bought.value)
})) as GenericBuyable & { display: { title: string } };
})) as GenericBuyable & { display: { title: string }; resource: Resource };
const expandingForestBuyable = createBuyable(() => ({
resource: logs,
cost() {
@ -223,7 +229,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
description: "Add 10 trees to the forest"
},
visibility: () => showIf(researchUpgrade2.bought.value)
})) as GenericBuyable & { display: { title: string } };
})) as GenericBuyable & { display: { title: string }; resource: Resource };
const row1Buyables = [autoCuttingBuyable1, autoPlantingBuyable1, expandingForestBuyable];
const dayProgress = createBar(() => ({
@ -404,6 +410,16 @@ const layer = createLayer(id, function (this: BaseLayer) {
description: "4 Elves Trained",
enabled: elves.milestones[3].earned
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "Carry logs in boxes",
enabled: boxes.upgrades.logsUpgrade.bought
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.div(boxes.buyables.logBoxesBuyable.amount.value, 2).add(1),
description: "Carry more logs",
enabled: boxes.upgrades.logsUpgrade.bought
})),
createExponentialModifier(() => ({
exponent: 1.1,
description: "100% Foundation Completed",

View file

@ -25,9 +25,11 @@ import workshopSymbol from "./symbols/sws.png";
import coalSymbol from "./symbols/coal.png";
import elfSymbol from "./symbols/elf.png";
import paperSymbol from "./symbols/paperStacks.png";
import boxesSymbol from "./symbols/cardboardBox.png";
import coal from "./layers/coal";
import elves from "./layers/elves";
import paper from "./layers/paper";
import boxes from "./layers/boxes";
export interface Day extends VueFeature {
day: number;
@ -169,10 +171,11 @@ export const main = createLayer("main", function (this: BaseLayer) {
createDay(() => ({
day: 6,
shouldNotify: false,
layer: null,
symbol: "",
story: "",
completedStory: ""
layer: "boxes",
symbol: boxesSymbol,
story: "You watch all these elves carrying incredibly large loads just in their open elf-sized hands, and realize there's probably a better way. You need to put the toys in boxes anyways, so why don't we get started working on those so the workers can take advantage as well?",
completedStory:
"Wow, those boxes are really convenient! The workshop feels more and more proper with every day. You tick another requirement of your list and start looking towards tomorrow. Good Job!"
})),
createDay(() => ({
day: 7,
@ -376,7 +379,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
export const getInitialLayers = (
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
player: Partial<PlayerData>
): Array<GenericLayer> => [main, trees, workshop, coal, elves, paper];
): Array<GenericLayer> => [main, trees, workshop, coal, elves, paper, boxes];
/**
* A computed ref whose value is true whenever the game is over.