1
0
Fork 0
mirror of https://github.com/thepaperpilot/Advent-Incremental.git synced 2025-03-28 11:48:01 +00:00

basic management layer

This commit is contained in:
circle-gon 2022-12-10 22:38:42 +00:00
commit c24255acc3
22 changed files with 1587 additions and 156 deletions

4
package-lock.json generated
View file

@ -49,7 +49,7 @@
"vue-tsc": "^0.38.1"
},
"engines": {
"node": "16.x"
"node": ">=16"
}
},
"node_modules/@ampproject/remapping": {
@ -6749,7 +6749,6 @@
"node_modules/vue-panzoom": {
"version": "1.1.6",
"resolved": "git+ssh://git@github.com/thepaperpilot/vue-panzoom.git#fa3cc91f6842cdfbd1bfb433c75cac01f177fe2d",
"integrity": "sha512-d4URo4PVl2jCFG1WNY+5lDQ8nloOVLf2gFLqE+TLNmF43+F/STgld0A58uf9aq2xbaupVJdZAp/prGtve9ESRQ==",
"license": "MIT",
"dependencies": {
"panzoom": "^9.4.1"
@ -11902,7 +11901,6 @@
},
"vue-panzoom": {
"version": "git+ssh://git@github.com/thepaperpilot/vue-panzoom.git#fa3cc91f6842cdfbd1bfb433c75cac01f177fe2d",
"integrity": "sha512-d4URo4PVl2jCFG1WNY+5lDQ8nloOVLf2gFLqE+TLNmF43+F/STgld0A58uf9aq2xbaupVJdZAp/prGtve9ESRQ==",
"from": "vue-panzoom@https://github.com/thepaperpilot/vue-panzoom.git",
"requires": {
"panzoom": "^9.4.1"

View file

@ -55,6 +55,6 @@
"vue-tsc": "^0.38.1"
},
"engines": {
"node": "16.x"
"node": ">=16"
}
}

View file

@ -56,6 +56,43 @@
border-radius: var(--border-radius);
}
.row-grid.mergeAdjacent > .feature:not(.dontMerge),
.row-grid.mergeAdjacent > .tooltip-container > .feature:not(.dontMerge) {
margin-left: 0;
margin-right: 0;
margin-bottom: 0;
margin-top: 0;
border-radius: 0;
}
.row-grid.mergeAdjacent > .feature:not(.dontMerge):last-child,
.row-grid.mergeAdjacent > .tooltip-container:last-child > .feature:not(.dontMerge) {
border-radius: 0 0 0 0;
}
.row-grid.mergeAdjacent > .feature:not(.dontMerge):first-child,
.row-grid.mergeAdjacent > .tooltip-container:first-child > .feature:not(.dontMerge) {
border-radius: 0 0 0 0;
}
.table-grid > .row-grid.mergeAdjacent:last-child > .feature:not(.dontMerge):first-child {
border-radius: 0 0 0 var(--border-radius);
}
.table-grid > .row-grid.mergeAdjacent:first-child > .feature:not(.dontMerge):last-child {
border-radius: 0 var(--border-radius) 0 0;
}
.table-grid > .row-grid.mergeAdjacent:first-child > .feature:not(.dontMerge):first-child {
border-radius: var(--border-radius) 0 0 0;
}
.table-grid > .row-grid.mergeAdjacent:last-child > .feature:not(.dontMerge):last-child {
border-radius: 0 0 var(--border-radius) 0;
}
/*
TODO how to implement mergeAdjacent for grids?
.row.mergeAdjacent + .row.mergeAdjacent > .feature:not(.dontMerge) {

View file

@ -20,16 +20,13 @@
class="scene-item"
style="left: 72%; bottom: 8%; width: 40px; height: 40px"
/>
<img
v-if="(day >= 8)"
:src="oil"
class="scene-item"
style="left: 80%; bottom: 6%"
/>
<img v-if="day >= 8" :src="oil" class="scene-item" style="left: 80%; bottom: 6%" />
<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" />
<img v-if="day >= 9" :src="plastic" class="scene-item" />
<img v-if="day >= 10" :src="dyes" class="scene-item" />
</div>
</div>
</template>
@ -44,6 +41,8 @@ import boxes from "./symbols/cardboardBox.png";
import metal from "./symbols/metal.png";
import cloth from "./symbols/cloth.png";
import oil from "./symbols/oil.png";
import plastic from "./symbols/plastic.png";
import dyes from "./symbols/dyes.png";
defineProps<{
day: number;

View file

@ -417,8 +417,9 @@ export function setUpDailyProgressTracker(options: {
display: VueFeature | CoercableComponent;
};
usingLog?: Ref<boolean>;
ignoreTotal?: boolean
}) {
const total = trackTotal(options.resource);
const total = options.ignoreTotal ? options.resource : trackTotal(options.resource);
const progressFunc = () => {
if (main.day.value !== options.day) return 1;
let progress = Decimal.add(total.value, 1);
@ -452,7 +453,7 @@ export function setUpDailyProgressTracker(options: {
<div>
{main.day.value === options.day ? (
<>
Reach {formatWhole(options.goal)} total {options.resource.displayName} to
Reach {formatWhole(options.goal)} {options.ignoreTotal ? "" : ("total ")}{options.resource.displayName} to
complete the day
</>
) : (

View file

@ -10,14 +10,18 @@ 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 } from "features/resources/resource";
import { createResource, displayResource, Resource } from "features/resources/resource";
import { createUpgrade } from "features/upgrades/upgrade";
import { globalBus } from "game/events";
import { BaseLayer, createLayer } from "game/layers";
import { noPersist } from "game/persistence";
import Decimal, { DecimalSource, format, formatWhole } from "util/bignum";
import { render, renderRow } from "util/vue";
import { unref } from "vue";
import paper from "./paper";
import plastic from "./plastic";
import trees from "./trees";
import dyes from "./dyes";
const id = "boxes";
const day = 6;
@ -100,6 +104,35 @@ const layer = createLayer(id, function (this: BaseLayer) {
}));
const upgrades = { logsUpgrade, ashUpgrade, coalUpgrade };
const oreUpgrade = createUpgrade(() => ({
resource: noPersist(boxes),
cost: 1e8,
visibility: () => showIf(plastic.upgrades.boxTools.bought.value),
display: {
title: "Carry ore in boxes",
description: "Double ore per mining op"
}
}));
const metalUpgrade = createUpgrade(() => ({
resource: noPersist(boxes),
cost: 1e9,
visibility: () => showIf(plastic.upgrades.boxTools.bought.value),
display: {
title: "Carry metal in boxes",
description: "Double ore purity"
}
}));
const plasticUpgrade = createUpgrade(() => ({
resource: noPersist(boxes),
cost: 1e10,
visibility: () => showIf(plastic.upgrades.boxTools.bought.value),
display: {
title: "Carry plastic in boxes",
description: "Double plastic gain"
}
}));
const row2Upgrades = { oreUpgrade, metalUpgrade, plasticUpgrade };
const logBoxesBuyable = createBuyable(() => ({
display: {
title: "Carry more logs",
@ -110,10 +143,12 @@ const layer = createLayer(id, function (this: BaseLayer) {
},
resource: noPersist(boxes),
cost() {
return Decimal.pow(3, logBoxesBuyable.amount.value).times(100);
let v = this.amount.value;
v = Decimal.pow(0.95, paper.books.boxBook.amount.value).times(v);
return Decimal.pow(3, v).times(100).div(dyes.boosts.orange2.value);
},
visibility: () => showIf(logsUpgrade.bought.value)
})) as GenericBuyable;
})) as GenericBuyable & { resource: Resource };
const ashBoxesBuyable = createBuyable(() => ({
display: {
title: "Carry more ash",
@ -124,10 +159,12 @@ const layer = createLayer(id, function (this: BaseLayer) {
},
resource: noPersist(boxes),
cost() {
return Decimal.pow(5, ashBoxesBuyable.amount.value).times(1000);
let v = this.amount.value;
v = Decimal.pow(0.95, paper.books.boxBook.amount.value).times(v);
return Decimal.pow(5, v).times(1000).div(dyes.boosts.orange2.value);;
},
visibility: () => showIf(ashUpgrade.bought.value)
})) as GenericBuyable;
})) as GenericBuyable & { resource: Resource };
const coalBoxesBuyable = createBuyable(() => ({
display: {
title: "Carry more coal",
@ -138,12 +175,25 @@ const layer = createLayer(id, function (this: BaseLayer) {
},
resource: noPersist(boxes),
cost() {
return Decimal.pow(7, coalBoxesBuyable.amount.value).times(1000);
let v = this.amount.value;
v = Decimal.pow(0.95, paper.books.boxBook.amount.value).times(v);
return Decimal.pow(7, v).times(1000).div(dyes.boosts.orange2.value);
},
visibility: () => showIf(coalUpgrade.bought.value)
})) as GenericBuyable;
})) as GenericBuyable & { resource: Resource };
const buyables = { logBoxesBuyable, ashBoxesBuyable, coalBoxesBuyable };
globalBus.on("update", diff => {
if (Decimal.lt(main.day.value, day)) {
return;
}
boxes.value = Decimal.times(diff, plastic.buyables.passiveBoxes.amount.value)
.times(boxesConversion.currentGain.value)
.div(100)
.add(boxes.value);
});
const { total: totalBoxes, trackerDisplay } = setUpDailyProgressTracker({
resource: boxes,
goal: 5e4,
@ -160,6 +210,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
totalBoxes,
boxesConversion,
upgrades,
row2Upgrades,
buyables,
minWidth: 700,
display: jsx(() => (
@ -171,6 +222,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
{render(makeBoxes)}
<Spacer />
{renderRow(...Object.values(upgrades))}
{renderRow(...Object.values(row2Upgrades))}
{renderRow(...Object.values(buyables))}
</>
))

View file

@ -8,16 +8,20 @@ import Modal from "components/Modal.vue";
import { createCollapsibleModifierSections, setUpDailyProgressTracker } from "data/common";
import { main } from "data/projEntry";
import { createBar } from "features/bars/bar";
import { createBuyable } from "features/buyable";
import { createBuyable, GenericBuyable } from "features/buyable";
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 } from "features/resources/resource";
import { createResource, Resource } from "features/resources/resource";
import { createUpgrade } from "features/upgrades/upgrade";
import { globalBus } from "game/events";
import { BaseLayer, createLayer } from "game/layers";
import { createAdditiveModifier, createSequentialModifier } from "game/modifiers";
import {
createAdditiveModifier,
createMultiplicativeModifier,
createSequentialModifier
} from "game/modifiers";
import { noPersist, persistent } from "game/persistence";
import Decimal, { DecimalSource } from "util/bignum";
import { formatWhole } from "util/break_eternity";
@ -26,6 +30,7 @@ import { render, renderCol, renderRow } from "util/vue";
import { computed, ref } from "vue";
import metal from "./metal";
import paper from "./paper";
import plastic from "./plastic";
import trees from "./trees";
const id = "cloth";
@ -176,39 +181,42 @@ const layer = createLayer(id, function (this: BaseLayer) {
cost() {
let v = this.amount.value;
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 2).div(100);
v = Decimal.pow(0.95, paper.books.clothBook.amount.value).times(v);
return Decimal.pow(1.5, v).times(1e14);
},
display: {
title: "Build more pens",
description: "Breed +1 sheep at once"
}
}));
})) as GenericBuyable & { resource: Resource };
const betterShears = createBuyable(() => ({
resource: metal.metal,
cost() {
let v = this.amount.value;
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 2).div(100);
v = Decimal.pow(0.95, paper.books.clothBook.amount.value).times(v);
return Decimal.pow(1.4, v).times(10000);
},
display: {
title: "Make stronger shears",
description: "Shear +1 sheep at once"
}
}));
})) as GenericBuyable & { resource: Resource };
const fasterSpinning = createBuyable(() => ({
resource: paper.paper,
cost() {
let v = this.amount.value;
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 2).div(100);
v = Decimal.pow(0.95, paper.books.clothBook.amount.value).times(v);
return Decimal.pow(1.3, v).times(1000000);
},
display: {
title: "Learn how to spin",
description: "Spin +1 wool at once"
}
}));
})) as GenericBuyable & { resource: Resource };
const treesUpgrade1 = createUpgrade(() => ({
resource: noPersist(cloth),
@ -236,7 +244,16 @@ const layer = createLayer(id, function (this: BaseLayer) {
description: "Quadruple trees planted"
}
}));
const treesUpgrades = { treesUpgrade3, treesUpgrade2, treesUpgrade1 };
const treesUpgrade4 = createUpgrade(() => ({
resource: noPersist(cloth),
cost: 1e3,
visibility: () => showIf(plastic.upgrades.clothTools.bought.value),
display: {
title: "Felt-Gripped Axe",
description: "10x log gain"
}
}));
const treesUpgrades = { treesUpgrade4, treesUpgrade3, treesUpgrade2, treesUpgrade1 };
const metalUpgrade1 = createUpgrade(() => ({
resource: noPersist(cloth),
@ -264,7 +281,16 @@ const layer = createLayer(id, function (this: BaseLayer) {
description: "Triple coal gain"
}
}));
const metalUpgrades = { metalUpgrade3, metalUpgrade2, metalUpgrade1 };
const metalUpgrade4 = createUpgrade(() => ({
resource: noPersist(cloth),
cost: 2e3,
visibility: () => showIf(plastic.upgrades.clothTools.bought.value),
display: {
title: "Felt-Gripped Pick",
description: "Quadruple coal gain"
}
}));
const metalUpgrades = { metalUpgrade4, metalUpgrade3, metalUpgrade2, metalUpgrade1 };
const paperUpgrade1 = createUpgrade(() => ({
resource: noPersist(cloth),
@ -292,12 +318,31 @@ const layer = createLayer(id, function (this: BaseLayer) {
description: "Double paper gain"
}
}));
const paperUpgrades = { paperUpgrade3, paperUpgrade2, paperUpgrade1 };
const paperUpgrade4 = createUpgrade(() => ({
resource: noPersist(cloth),
cost: 4e3,
visibility: () => showIf(plastic.upgrades.clothTools.bought.value),
display: {
title: "Felt Elbow Pads",
description: "10x paper gain"
}
}));
const paperUpgrades = { paperUpgrade4, paperUpgrade3, paperUpgrade2, paperUpgrade1 };
const sheepGain = createSequentialModifier(() => [
createAdditiveModifier(() => ({
addend: buildPens.amount,
description: "Build more pens"
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.div(plastic.buyables.clothGains.amount.value, 10).add(1),
description: "Plastic Shepherd",
enabled: () => Decimal.gte(plastic.buyables.clothGains.amount.value, 1)
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "Shepherding for Dummies",
enabled: paper.upgrades.clothUpgrade.bought
}))
]);
const computedSheepGain = computed(() => sheepGain.apply(1));
@ -308,6 +353,16 @@ const layer = createLayer(id, function (this: BaseLayer) {
createAdditiveModifier(() => ({
addend: betterShears.amount,
description: "Make stronger shears"
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.div(plastic.buyables.clothGains.amount.value, 10).add(1),
description: "Plastic Shepherd",
enabled: () => Decimal.gte(plastic.buyables.clothGains.amount.value, 1)
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "Shepherding for Dummies",
enabled: paper.upgrades.clothUpgrade.bought
}))
]);
const computedShearingAmount = computed(() => shearingAmount.apply(1));
@ -318,6 +373,16 @@ const layer = createLayer(id, function (this: BaseLayer) {
createAdditiveModifier(() => ({
addend: fasterSpinning.amount,
description: "Learn how to spin"
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.div(plastic.buyables.clothGains.amount.value, 10).add(1),
description: "Plastic Shepherd",
enabled: () => Decimal.gte(plastic.buyables.clothGains.amount.value, 1)
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "Shepherding for Dummies",
enabled: paper.upgrades.clothUpgrade.bought
}))
]);
const computedSpinningAmount = computed(() => spinningAmount.apply(1));

View file

@ -2,42 +2,42 @@
* @module
* @hidden
*/
import Column from "components/layout/Column.vue";
import Row from "components/layout/Row.vue";
import Spacer from "components/layout/Spacer.vue";
import Modal from "components/Modal.vue";
import MainDisplay from "features/resources/MainDisplay.vue";
import Row from "components/layout/Row.vue";
import Column from "components/layout/Column.vue";
import {
createCollapsibleModifierSections,
setUpDailyProgressTracker,
changeActiveBuyables
changeActiveBuyables, createCollapsibleModifierSections,
setUpDailyProgressTracker
} from "data/common";
import { main } from "data/projEntry";
import { createBuyable, GenericBuyable } from "features/buyable";
import { jsx, JSXFunction, showIf, StyleValue, Visibility } from "features/feature";
import MainDisplay from "features/resources/MainDisplay.vue";
import { createResource, Resource } from "features/resources/resource";
import { createUpgrade, Upgrade } from "features/upgrades/upgrade";
import { globalBus } from "game/events";
import { BaseLayer, createLayer } from "game/layers";
import {
createAdditiveModifier,
createExponentialModifier,
createMultiplicativeModifier,
createSequentialModifier,
Modifier
} from "game/modifiers";
import { noPersist, persistent } from "game/persistence";
import Decimal, { DecimalSource, format, formatWhole } from "util/bignum";
import { WithRequired } from "util/common";
import { render, renderRow } from "util/vue";
import { computed, ref, unref } from "vue";
import trees from "./trees";
import {
createAdditiveModifier,
createExponentialModifier,
createMultiplicativeModifier,
createSequentialModifier,
Modifier
} from "game/modifiers";
import { createUpgrade, Upgrade } from "features/upgrades/upgrade";
import elves from "./elves";
import paper from "./paper";
import boxes from "./boxes";
import metal from "./metal";
import cloth from "./cloth";
import { WithRequired } from "util/common";
import elves from "./elves";
import metal from "./metal";
import oil from "./oil";
import paper from "./paper";
import trees from "./trees";
import dyes from "./dyes";
interface BetterFertilizerUpgOptions {
canAfford: () => boolean;
@ -552,7 +552,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
enabled: elves.elves.bonfireElf.bought
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.div(buildKiln.amount.value, 100).add(1),
multiplier: () => Decimal.div(buildKiln.amount.value, 100).times(dyes.boosts.green2.value).add(1),
description: "Kiln Synergy",
enabled: elves.elves.kilnElf.bought
})),
@ -566,6 +566,16 @@ const layer = createLayer(id, function (this: BaseLayer) {
description: "Mining helmet",
enabled: cloth.metalUpgrades.metalUpgrade3.bought
})),
createMultiplicativeModifier(() => ({
multiplier: 4,
description: "Felt-Gripped Pick",
enabled: cloth.metalUpgrades.metalUpgrade4.bought
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "12 Elves Trained",
enabled: elves.milestones[11].earned
})),
createExponentialModifier(() => ({
exponent: 1.25,
description: "3 Elves Trained",
@ -634,7 +644,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
enabled: elves.elves.bonfireElf.bought
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.div(buildKiln.amount.value, 100).add(1),
multiplier: () => Decimal.div(buildKiln.amount.value, 100).times(dyes.boosts.green2.value).add(1),
description: "Kiln Synergy",
enabled: elves.elves.kilnElf.bought
})),

560
src/data/layers/dyes.tsx Normal file
View file

@ -0,0 +1,560 @@
/**
* @module
* @hidden
*/
import Modal from "components/Modal.vue";
import MainDisplay from "features/resources/MainDisplay.vue";
import Row from "components/layout/Row.vue";
import Spacer from "components/layout/Spacer.vue";
import Sqrt from "components/math/Sqrt.vue";
import { BuyableOptions, GenericBuyable, createBuyable } from "features/buyable";
import { jsx, JSXFunction, showIf, Visibility } from "features/feature";
import { createResource, Resource } from "features/resources/resource";
import { globalBus } from "game/events";
import { BaseLayer, createLayer } from "game/layers";
import { noPersist, persistent } from "game/persistence";
import Decimal, { DecimalSource, format, formatWhole } from "util/bignum";
import { computed, ComputedRef, ref, Ref, unref } from "vue";
import trees from "./trees";
import oil from "./oil";
import { coerceComponent, render, renderCol, renderRow } from "util/vue";
import { setUpDailyProgressTracker, createCollapsibleModifierSections } from "data/common";
import { createAdditiveModifier, createMultiplicativeModifier, createSequentialModifier, Modifier } from "game/modifiers";
import { WithRequired } from "util/common";
import { createUpgrade, GenericUpgrade } from "features/upgrades/upgrade";
import { createLazyProxy } from "util/proxies";
import coal from "./coal";
interface Dye {
name: string,
amount: Resource<DecimalSource>,
buyable: GenericBuyable,
toGenerate: WithRequired<Modifier, "description" | "revert">,
computedToGenerate: ComputedRef<DecimalSource>,
display: JSXFunction
}
type DyeUpg = "blueDyeUpg" | "redDyeUpg" | "yellowDyeUpg" | "yellowDyeUpg2" | "redDyeUpg2" | "blueDyeUpg2" | "coalUpg"
const id = "dyes";
const day = 11;
const layer = createLayer(id, function (this: BaseLayer) {
const name = "Dyes";
const color = "#D4D4F4";
function createDye(
optionsFunc: () => {
name: string;
color: string;
costs: {
base: Ref<DecimalSource> | DecimalSource;
root?: Ref<DecimalSource> | DecimalSource,
res: Resource<DecimalSource>
}[];
listedBoosts: {
visible: Ref<boolean> | boolean,
desc: Ref<string>
}[];
dyesToReset: {
name: string,
reset: VoidFunction
}[]
} & Partial<BuyableOptions>
): Dye {
return createLazyProxy(() => {
const options = optionsFunc();
const amount = createResource<DecimalSource>(0, optionsFunc().name);
const toGenerate = createSequentialModifier(() => [
createAdditiveModifier(() => ({
addend: () => Decimal.add(buyable.amount.value, 1),
description: `${options.name} Chambers`
})),
createMultiplicativeModifier(() => ({
multiplier: boosts.orange1,
description: "Orange Dye Boost 1",
enabled: options.color == "red" || options.color == "yellow"
})),
createMultiplicativeModifier(() => ({
multiplier: boosts.green1,
description: "Green Dye Boost 1",
enabled: options.color == "yellow" || options.color == "blue"
})),
createMultiplicativeModifier(() => ({
multiplier: boosts.purple1,
description: "Purple Dye Boost 1",
enabled: options.color == "red" || options.color == "blue"
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "Wetter Dyes",
enabled: () => upgrades.yellowDyeUpg.bought.value && options.color == "red" || options.color == "yellow" || options.color == "blue"
}))
]) as WithRequired<Modifier, "description" | "revert">;
const computedToGenerate = computed(() => toGenerate.apply(0));
const buyable: GenericBuyable = createBuyable(() => ({
...options,
style: () => ({ backgroundColor: unref(buyable.canPurchase) ? color : "#545454", minWidth: "200px" }),
display: jsx(() => {
return (
<span>
<h3>{options.name} Chambers</h3>
<br/>
Create {format(computedToGenerate.value)} {options.name}{options.dyesToReset.length > 0 ? ", but reset " + options.dyesToReset.map(dye => dye.name).join(", ") : ""}.
<br/>
<br/>
<span class="white-space: pre-wrap">
Currently: {options.listedBoosts.filter(b => unref(b.visible)).map(b => render(jsx(() => <div>{unref(b.desc)}</div>)))}
</span>
<br/>
<div>
Cost: {options.costs.map(c => render(jsx(() =>
<div>
{format(unref(Decimal.pow(unref(buyable.cost) ?? Decimal.dInf, unref(c.root ?? 1)).times(unref(c.base))))}
{" "}{c.res.displayName}<br/>
</div>)))}
</div>
</span>
);
}),
cost() {
let v = buyable.amount.value;
if (Decimal.gte(v, 25)) v = Decimal.pow(v, 2).div(20) // intentional price jump #2
if (Decimal.gte(v, 10)) v = Decimal.pow(v, 2).div(5); // intentional price jump
return Decimal.div(v, 10).plus(1);
},
canPurchase: computed((cost?: DecimalSource) => {
if (unref(buyable.visibility) != Visibility.Visible) return false;
const trueCost = cost ?? unref(buyable.cost) ?? Decimal.dInf;
return options.costs.every(c => Decimal.div(c.res.value, unref(c.base)).root(unref(c.root ?? 1)).gte(trueCost));
}),
onPurchase(cost?: DecimalSource) {
const trueCost = cost ?? unref(buyable.cost) ?? Decimal.dInf;
options.costs.forEach(c => {
c.res.value = Decimal.sub(c.res.value, Decimal.pow(trueCost, unref(c.root ?? 1)).times(unref(c.base)));
});
amount.value = Decimal.add(amount.value, computedToGenerate.value);
buyable.amount.value = Decimal.add(buyable.amount.value, 1);
options.dyesToReset.forEach(dye => dye.reset());
}
}));
return {
name: options.name,
amount,
buyable,
toGenerate,
computedToGenerate,
display: jsx(() => (
<div class="col" style="max-width: 200px">
<MainDisplay resource={amount} color={options.color} style="margin-bottom: 0" />
<Spacer />
{render(buyable)}
</div>
))
}
})
}
const dyes: Record<"red" | "yellow" | "blue" | "orange" | "green" | "purple", Dye> = {
red: createDye(() => ({
name: "Red Dye",
color: "red",
costs: [
{
base: '2e18',
root: 5,
res: trees.logs
},
{
base: computed(() => upgrades.yellowDyeUpg2.bought.value ? '2.5e5' : '5e5'),
root: 2,
res: oil.oil
}
],
listedBoosts: [
{
visible: true,
desc: computed(() => `+${format(boosts.red1.value)} effective Oil Pumps (does not impact coal consumption)`)
}
],
dyesToReset: [],
})),
yellow: createDye(() => ({
name: "Yellow Dye",
color: "yellow",
costs: [
{
base: '1e18',
root: 5,
res: trees.logs
},
{
base: computed(() => upgrades.yellowDyeUpg2.bought.value ? '5e5' : '1e6'),
root: 2,
res: oil.oil
}
],
listedBoosts: [
{
visible: true,
desc: computed(() => `x${format(boosts.yellow1.value)} Paper \& Plastic gain`)
}
],
dyesToReset: [],
})),
blue: createDye(() => ({
name: "Blue Dye",
color: "blue",
costs: [
{
base: '5e17',
root: 5,
res: trees.logs
},
{
base: computed(() => upgrades.yellowDyeUpg2.bought.value ? '1e6' : '2e6'),
root: 2,
res: oil.oil
}
],
listedBoosts: [
{
visible: true,
desc: computed(() => `+${formatWhole(boosts.blue1.value)} forest size (after all other modifiers).`)
}
],
dyesToReset: [],
})),
orange: createDye(() => ({
name: "Orange Dye",
color: "orange",
costs: [
{
base: 15,
root: 2,
res: dyes.red.amount
},
{
base: 10,
root: 2,
res: dyes.yellow.amount
}
],
listedBoosts: [
{
visible: true,
desc: computed(() => `x${format(boosts.orange1.value)} Red and Yellow Dye gain`)
},
{
visible: true,
desc: computed(() => `/${format(boosts.orange2.value)} Box buyable costs.`)
}
],
dyesToReset: [{
name: "Red Dye",
reset() {
dyes.red.amount.value = 0;
dyes.red.buyable.amount.value = 0;
}
}, {
name: "Yellow Dye",
reset() {
dyes.yellow.amount.value = 0;
dyes.yellow.buyable.amount.value = 0;
}
}],
})),
green: createDye(() => ({
name: "Green Dye",
color: "green",
costs: [
{
base: 15,
root: 2,
res: dyes.yellow.amount
},
{
base: 10,
root: 2,
res: dyes.blue.amount
}
],
listedBoosts: [
{
visible: true,
desc: computed(() => `x${format(boosts.green1.value)} Yellow and Blue Dye gain`)
},
{
visible: true,
desc: computed(() => `x${formatWhole(Decimal.sub(boosts.green2.value, 1).times(100))}% Kiln synergy effect.`)
}
],
dyesToReset: [{
name: "Yellow Dye",
reset() {
dyes.yellow.amount.value = 0;
dyes.yellow.buyable.amount.value = 0;
}
},{
name: "Blue Dye",
reset() {
dyes.blue.amount.value = 0;
dyes.blue.buyable.amount.value = 0;
}
}],
})),
purple: createDye(() => ({
name: "Purple Dye",
color: "purple",
costs: [
{
base: 15,
root: 2,
res: dyes.blue.amount
},
{
base: 10,
root: 2,
res: dyes.red.amount
}
],
listedBoosts: [
{
visible: true,
desc: computed(() => `x${format(boosts.purple1.value)} Red and Blue Dye gain`)
},
{
visible: true,
desc: computed(() => `x${format(boosts.purple2.value)} Smelting Speed and Ore Purity`)
}
],
dyesToReset: [{
name: "Blue Dye",
reset() {
dyes.blue.amount.value = 0;
dyes.blue.buyable.amount.value = 0;
}
}, {
name: "Red Dye",
reset() {
dyes.red.amount.value = 0;
dyes.red.buyable.amount.value = 0;
}
}],
}))
};
const boosts = {
red1: computed(() => Decimal.pow(Decimal.add(dyes.red.amount.value, 1).log2().plus(1).log2().div(2), upgrades.blueDyeUpg2.bought.value ? 1.5 : 1)),
yellow1: computed(() => Decimal.add(dyes.yellow.amount.value, 1).log2().plus(1)),
blue1: computed(() => Decimal.add(dyes.blue.amount.value, 1).log2().sqrt().times(5e6)),
orange1: computed(() => Decimal.pow(2, Decimal.add(dyes.orange.amount.value, 1).log2().sqrt()).pow(upgrades.coalUpg.bought.value ? 1.2 : 1)),
orange2: computed(() => Decimal.add(dyes.orange.amount.value, 1).log2().plus(1)),
green1: computed(() => Decimal.pow(2, Decimal.add(dyes.green.amount.value, 1).log2().sqrt()).pow(upgrades.coalUpg.bought.value ? 1.2 : 1)),
green2: computed(() => Decimal.add(dyes.green.amount.value, 1).log2().plus(1).pow(upgrades.coalUpg.bought.value ? 2 : 1)),
purple1: computed(() => Decimal.pow(2, Decimal.add(dyes.purple.amount.value, 1).log2().sqrt()).pow(upgrades.coalUpg.bought.value ? 1.2 : 1)),
purple2: computed(() => Decimal.add(dyes.purple.amount.value, 1).log2().plus(1)),
}
const [generalTab, generalTabCollapsed] = createCollapsibleModifierSections(() => [
{
title: "Red Dye Creation",
modifier: dyes.red.toGenerate,
base: 0
},
{
title: "Yellow Dye Creation",
modifier: dyes.yellow.toGenerate,
base: 0
},
{
title: "Blue Dye Creation",
modifier: dyes.blue.toGenerate,
base: 0
},
{
title: "Orange Dye Creation",
modifier: dyes.orange.toGenerate,
base: 0
},
{
title: "Green Dye Creation",
modifier: dyes.green.toGenerate,
base: 0
},
{
title: "Purple Dye Creation",
modifier: dyes.purple.toGenerate,
base: 0
}
]);
const upgrades: Record<DyeUpg, GenericUpgrade> = {
blueDyeUpg: createUpgrade(() => ({
visibility: () => showIf(Decimal.add(dyes.orange.amount.value, dyes.green.amount.value).add(dyes.purple.amount.value).gte(1) || upgrades.blueDyeUpg.bought.value),
display: {
title: "Is Blue Dye just Water?",
description: jsx(() => <>Multiply Log gain by log<sub>10</sub>(Auto Cutting Amount)+1.</>)
},
cost: 1000,
resource: dyes.blue.amount,
onPurchase() {
dyes.blue.amount.value = 0;
dyes.blue.buyable.amount.value = 0;
}
})),
redDyeUpg: createUpgrade(() => ({
visibility: () => showIf(Decimal.add(dyes.orange.amount.value, dyes.green.amount.value).add(dyes.purple.amount.value).gte(10) || upgrades.redDyeUpg.bought.value),
display: {
title: "Glistening Paint",
description: jsx(() => <>Multiply Ore Purity by log<sub>10</sub>(Cloth)+1.</>)
},
cost: 1500,
resource: dyes.red.amount,
onPurchase() {
dyes.red.amount.value = 0;
dyes.red.buyable.amount.value = 0;
}
})),
yellowDyeUpg: createUpgrade(() => ({
visibility: () => showIf(Decimal.add(dyes.orange.amount.value, dyes.green.amount.value).add(dyes.purple.amount.value).gte(100) || upgrades.yellowDyeUpg.bought.value),
display: {
title: "Wetter Dyes",
description: "Double Red, Yellow, and Blue Dye gain, but reset their amounts."
},
cost: 2000,
resource: dyes.yellow.amount,
onPurchase() {
dyes.red.amount.value = 0;
dyes.red.buyable.amount.value = 0;
dyes.yellow.amount.value = 0;
dyes.yellow.buyable.amount.value = 0;
dyes.blue.amount.value = 0;
dyes.blue.buyable.amount.value = 0;
}
})),
yellowDyeUpg2: createUpgrade(() => ({
visibility: () => showIf(upgrades.yellowDyeUpg.bought.value),
display: {
title: "Golden Wash",
description: "Halve the Oil cost of Red, Yellow, and Blue Dyes."
},
cost: 5000,
resource: dyes.yellow.amount,
onPurchase() {
dyes.yellow.amount.value = 0;
dyes.yellow.buyable.amount.value = 0;
}
})),
redDyeUpg2: createUpgrade(() => ({
visibility: () => showIf(upgrades.redDyeUpg.bought.value),
display: {
title: "De Louvre",
description: jsx(() => <>Multiply Smelting Speed by <Sqrt>Refineries+1</Sqrt>.</>)
},
cost: 6000,
resource: dyes.red.amount,
onPurchase() {
dyes.red.amount.value = 0;
dyes.red.buyable.amount.value = 0;
}
})),
blueDyeUpg2: createUpgrade(() => ({
visibility: () => showIf(upgrades.blueDyeUpg.bought.value),
display: {
title: "Hydrophobia",
description: "Raise Red Dye's effect ^1.5."
},
cost: 7500,
resource: dyes.blue.amount,
onPurchase() {
dyes.blue.amount.value = 0;
dyes.blue.buyable.amount.value = 0;
}
})),
coalUpg: createUpgrade(() => ({
visibility: () => showIf(upgrades.blueDyeUpg2.bought.value && upgrades.redDyeUpg2.bought.value && upgrades.yellowDyeUpg2.bought.value),
display: {
title: "Denser Spectrum",
description: "Orange, Green, and Purple Dyes' first effect is raised ^1.2, and Green Dye's second effect is squared. Buying this resets Red, Yellow, and Blue Dyes.",
},
cost: "5e30",
resource: coal.coal,
onPurchase() {
dyes.red.amount.value = 0;
dyes.red.buyable.amount.value = 0;
dyes.yellow.amount.value = 0;
dyes.yellow.buyable.amount.value = 0;
dyes.blue.amount.value = 0;
dyes.blue.buyable.amount.value = 0;
}
}))
}
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
}}
/>
));
const dyeSum = createResource<DecimalSource>(computed(() => Object.values(dyes).reduce<DecimalSource>((a,c) => Decimal.add(a, c.amount.value), 0)), "Sum of Dyes");
const { total: totalDyeSum, trackerDisplay } = setUpDailyProgressTracker({
resource: dyeSum,
goal: 6e4,
name,
day,
color,
textColor: "var(--feature-foreground)",
modal: {
show: showModifiersModal,
display: modifiersModal
},
ignoreTotal: true
});
return {
name,
color,
dyes,
dyeSum,
boosts,
totalDyeSum,
minWidth: 700,
generalTabCollapsed,
upgrades,
display: jsx(() => (
<>
{render(trackerDisplay)}
<Spacer />
{renderRow(dyes.red.display, dyes.yellow.display, dyes.blue.display)}
<Spacer />
{renderRow(dyes.orange.display, dyes.green.display, dyes.purple.display)}
<Spacer />
<div class="row" style="vertical-align: top">
{renderCol(upgrades.redDyeUpg, upgrades.redDyeUpg2)}
{renderCol(upgrades.yellowDyeUpg, upgrades.yellowDyeUpg2)}
{renderCol(upgrades.blueDyeUpg, upgrades.blueDyeUpg2)}
</div>
{render(upgrades.coalUpg)}
</>
))
}
});
export default layer;

View file

@ -2,6 +2,7 @@
* @module
* @hidden
*/
import { isArray } from "@vue/shared";
import Toggle from "components/fields/Toggle.vue";
import Spacer from "components/layout/Spacer.vue";
import Modal from "components/Modal.vue";
@ -25,8 +26,10 @@ import { Computable, convertComputable } from "util/computed";
import { render, renderRow } from "util/vue";
import { computed, ref, Ref, unref, watchEffect } from "vue";
import boxes from "./boxes";
import cloth from "./cloth";
import coal from "./coal";
import paper from "./paper";
import plastic from "./plastic";
import trees from "./trees";
import workshop from "./workshop";
@ -86,6 +89,17 @@ const layer = createLayer(id, function (this: BaseLayer) {
if (foundationMilestone.earned.value) {
workshop.foundationProgress.value = 100;
}
if (coalUpgradesMilestone.earned.value) {
coal.warmerCutters.bought.value = true;
coal.warmerPlanters.bought.value = true;
coal.basicFertilizer.bought.value = true;
coal.unlockBonfire.bought.value = true;
coal.dedicatedCutters.bought.value = true;
coal.dedicatedPlanters.bought.value = true;
coal.betterFertilizer.bought.value = true;
coal.unlockKiln.bought.value = true;
coal.efficientSmelther.bought.value = true;
}
});
}
}));
@ -100,6 +114,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
multiplier: () => Decimal.times(paper.books.cuttersBook.amount.value, 0.1).add(1),
description: "Now You're Logging!",
enabled: () => Decimal.gt(paper.books.cuttersBook.amount.value, 0)
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "10 Elves Trained",
enabled: elvesMilestone2.earned
}))
]);
const planterCooldown = createSequentialModifier(() => [
@ -112,6 +131,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
multiplier: () => Decimal.times(paper.books.plantersBook.amount.value, 0.1).add(1),
description: "The Man Who Planted Trees",
enabled: () => Decimal.gt(paper.books.plantersBook.amount.value, 0)
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "10 Elves Trained",
enabled: elvesMilestone2.earned
}))
]);
const expanderCooldown = createSequentialModifier(() => [
@ -124,6 +148,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
multiplier: () => Decimal.times(paper.books.expandersBook.amount.value, 0.1).add(1),
description: "Logjam",
enabled: () => Decimal.gt(paper.books.expandersBook.amount.value, 0)
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "10 Elves Trained",
enabled: elvesMilestone2.earned
}))
]);
const heatedCutterCooldown = createSequentialModifier(() => [
@ -136,6 +165,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
multiplier: () => Decimal.times(paper.books.heatedCuttersBook.amount.value, 0.1).add(1),
description: "Fahrenheit 451",
enabled: () => Decimal.gt(paper.books.heatedCuttersBook.amount.value, 0)
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "10 Elves Trained",
enabled: elvesMilestone2.earned
}))
]);
const heatedPlanterCooldown = createSequentialModifier(() => [
@ -149,6 +183,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
Decimal.times(paper.books.heatedPlantersBook.amount.value, 0.1).add(1),
description: "Tillamook Burn Country",
enabled: () => Decimal.gt(paper.books.heatedPlantersBook.amount.value, 0)
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "10 Elves Trained",
enabled: elvesMilestone2.earned
}))
]);
const fertilizerCooldown = createSequentialModifier(() => [
@ -161,6 +200,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
multiplier: () => Decimal.times(paper.books.fertilizerBook.amount.value, 0.1).add(1),
description: "The Garden Tree's Handbook",
enabled: () => Decimal.gt(paper.books.fertilizerBook.amount.value, 0)
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "10 Elves Trained",
enabled: elvesMilestone2.earned
}))
]);
const smallFireCooldown = createSequentialModifier(() => [
@ -173,6 +217,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
multiplier: () => Decimal.times(paper.books.smallFireBook.amount.value, 0.1).add(1),
description: "Firestarter",
enabled: () => Decimal.gt(paper.books.smallFireBook.amount.value, 0)
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "10 Elves Trained",
enabled: elvesMilestone2.earned
}))
]);
const bonfireCooldown = createSequentialModifier(() => [
@ -185,6 +234,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
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)
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "10 Elves Trained",
enabled: elvesMilestone2.earned
}))
]);
const kilnCooldown = createSequentialModifier(() => [
@ -197,6 +251,62 @@ const layer = createLayer(id, function (this: BaseLayer) {
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)
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "10 Elves Trained",
enabled: elvesMilestone2.earned
}))
]);
const paperCooldown = createSequentialModifier(() => [
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "6 Elves Trained",
enabled: elvesMilestone.earned
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.times(paper.books.paperBook.amount.value, 0.1).add(1),
description: "The Book Thief",
enabled: () => Decimal.gt(paper.books.paperBook.amount.value, 0)
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "10 Elves Trained",
enabled: elvesMilestone2.earned
}))
]);
const boxCooldown = createSequentialModifier(() => [
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "6 Elves Trained",
enabled: elvesMilestone.earned
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.times(paper.books.boxBook.amount.value, 0.1).add(1),
description: "Not a box",
enabled: () => Decimal.gt(paper.books.boxBook.amount.value, 0)
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "10 Elves Trained",
enabled: elvesMilestone2.earned
}))
]);
const clothCooldown = createSequentialModifier(() => [
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "6 Elves Trained",
enabled: elvesMilestone.earned
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.times(paper.books.clothBook.amount.value, 0.1).add(1),
description: "Fuzzy Bee and Friends",
enabled: () => Decimal.gt(paper.books.clothBook.amount.value, 0)
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "10 Elves Trained",
enabled: elvesMilestone2.earned
}))
]);
@ -263,6 +373,27 @@ const layer = createLayer(id, function (this: BaseLayer) {
base: 10,
unit: "/s",
visible: elves.kilnElf.bought
},
{
title: "Star Auto-Buy Frequency",
modifier: paperCooldown,
base: 10,
unit: "/s",
visible: elves.paperElf.bought
},
{
title: "Bell Auto-Buy Frequency",
modifier: boxCooldown,
base: 10,
unit: "/s",
visible: elves.boxElf.bought
},
{
title: "Gingersnap Auto-Buy Frequency",
modifier: clothCooldown,
base: 10,
unit: "/s",
visible: elves.clothElf.bought
}
]);
const showModifiersModal = ref(false);
@ -277,11 +408,21 @@ const layer = createLayer(id, function (this: BaseLayer) {
/>
));
const trainingCost = computed(() => {
let cost = Decimal.pow(4, totalElves.value).times(1e6);
if (Decimal.gte(totalElves.value, 9)) {
cost = Decimal.times(cost, 1e15);
}
return cost;
});
function createElf(
options: {
name: string;
description: string;
buyable: GenericBuyable & { resource: Resource };
buyable:
| (GenericBuyable & { resource: Resource })
| (GenericBuyable & { resource: Resource })[];
cooldownModifier: Modifier;
customCost?: (amount: DecimalSource) => DecimalSource;
hasToggle?: boolean;
@ -291,7 +432,6 @@ const layer = createLayer(id, function (this: BaseLayer) {
canBuy?: Computable<boolean>;
} & 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);
@ -303,23 +443,27 @@ const layer = createLayer(id, function (this: BaseLayer) {
if (upgrade.bought.value && unref(isActive)) {
buyProgress.value = Decimal.add(buyProgress.value, diff);
const cooldown = Decimal.recip(computedAutoBuyCooldown.value);
while (Decimal.gte(buyProgress.value, cooldown)) {
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;
(isArray(options.buyable) ? options.buyable : [options.buyable]).forEach(
buyable => {
while (Decimal.gte(buyProgress.value, cooldown)) {
if (
options.customCost == undefined
? unref(buyable.canPurchase)
: Decimal.gte(
buyable.resource.value,
options.customCost(buyable.amount.value)
)
) {
buyable.amount.value = Decimal.add(buyable.amount.value, 1);
buyProgress.value = Decimal.sub(buyProgress.value, cooldown);
options.onAutoPurchase?.();
} else {
buyProgress.value = cooldown;
break;
}
}
}
}
);
}
}
@ -447,7 +591,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
hasToggle: true,
toggleDesc: "Activate auto-purchased bonfires",
onAutoPurchase() {
const spent = unref(this.buyable.cost!);
const spent = unref((this.buyable as GenericBuyable).cost!);
coal.activeFires.value = Decimal.sub(coal.activeFires.value, spent).max(0);
coal.buildFire.amount.value = Decimal.sub(coal.buildFire.amount.value, spent).max(0);
if (bonfireElf.toggle.value) {
@ -479,6 +623,31 @@ const layer = createLayer(id, function (this: BaseLayer) {
canBuy: coal.unlockKiln.bought
});
const fireElves = [smallFireElf, bonfireElf, kilnElf];
const paperElf = createElf({
name: "Star",
description:
"Star will automatically purchase all books you can afford, without actually spending any paper.",
buyable: Object.values(paper.books),
cooldownModifier: paperCooldown,
visibility: () => showIf(plastic.elfUpgrades.paperElf.bought.value)
});
const boxElf = createElf({
name: "Bell",
description:
"Bell will automatically purchase all box buyables you can afford, without actually spending any boxes.",
buyable: Object.values(boxes.buyables),
cooldownModifier: boxCooldown,
visibility: () => showIf(plastic.elfUpgrades.boxElf.bought.value)
});
const clothElf = createElf({
name: "Gingersnap",
description:
"Gingersnap will automatically purchase all cloth buyables you can afford, without actually spending any resources.",
buyable: [cloth.buildPens, cloth.betterShears, cloth.fasterSpinning],
cooldownModifier: clothCooldown,
visibility: () => showIf(plastic.elfUpgrades.clothElf.bought.value)
});
const plasticElves = [paperElf, boxElf, clothElf];
const elves = {
cuttersElf,
plantersElf,
@ -488,7 +657,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
fertilizerElf,
smallFireElf,
bonfireElf,
kilnElf
kilnElf,
paperElf,
boxElf,
clothElf
};
const totalElves = computed(() => Object.values(elves).filter(elf => elf.bought.value).length);
@ -564,6 +736,30 @@ const layer = createLayer(id, function (this: BaseLayer) {
shouldEarn: () => Decimal.gte(totalElves.value, 9),
visibility: () => showIf(forestMilestone2.earned.value)
}));
const elvesMilestone2 = createMilestone(() => ({
display: {
requirement: "10 Elves Trained",
effectDisplay: "Elves work twice as fast (again)"
},
shouldEarn: () => Decimal.gte(totalElves.value, 10),
visibility: () => showIf(main.day.value >= 10)
}));
const coalUpgradesMilestone = createMilestone(() => ({
display: {
requirement: "11 Elves Trained",
effectDisplay: "Coal upgrades aren't reset after training"
},
shouldEarn: () => Decimal.gte(totalElves.value, 11),
visibility: () => showIf(elvesMilestone2.earned.value)
}));
const coalGainMilestone2 = createMilestone(() => ({
display: {
requirement: "12 Elves Trained",
effectDisplay: "Double coal gain"
},
shouldEarn: () => Decimal.gte(totalElves.value, 12),
visibility: () => showIf(coalUpgradesMilestone.earned.value)
}));
// Gosh why did I make these as an array at first
const milestones = [
manualMilestone,
@ -574,7 +770,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
elvesMilestone,
foundationMilestone,
forestMilestone2,
treeUpgradesMilestone
treeUpgradesMilestone,
elvesMilestone2,
coalUpgradesMilestone,
coalGainMilestone2
];
const milestonesDict = {
manualMilestone,
@ -585,7 +784,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
elvesMilestone,
foundationMilestone,
forestMilestone2,
treeUpgradesMilestone
treeUpgradesMilestone,
elvesMilestone2,
coalUpgradesMilestone,
coalGainMilestone2
};
const { collapseMilestones, display: milestonesDisplay } =
createCollapsibleMilestones(milestonesDict);
@ -641,6 +843,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
{renderRow(...treesElves)}
{renderRow(...coalElves)}
{renderRow(...fireElves)}
{renderRow(...plasticElves)}
</div>
{milestonesDisplay()}
</>

View file

@ -26,6 +26,10 @@ import { noPersist } from "game/persistence";
import { createBuyable, GenericBuyable } from "features/buyable";
import { main } from "../projEntry";
import oil from "./oil";
import boxes from "./boxes";
import cloth from "./cloth";
import plastic from "./plastic";
import dyes from "./dyes";
const id = "metal";
const day = 7;
@ -59,6 +63,21 @@ const layer = createLayer(id, function (this: BaseLayer) {
multiplier: () => Decimal.add(hotterForgeEffect.value, 1),
description: "Hotter Forges",
enabled: () => Decimal.gte(hotterForge.amount.value, 1)
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "Carry metal in boxes",
enabled: boxes.row2Upgrades.metalUpgrade.bought
})),
createMultiplicativeModifier(() => ({
multiplier: dyes.boosts.purple2,
description: "Purple Dye Boost 2",
enabled: () => Decimal.gte(dyes.dyes.purple.amount.value, 1)
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.add(cloth.cloth.value, 1).log10().plus(1),
description: "Glistening Paint",
enabled: dyes.upgrades.redDyeUpg.bought
}))
]);
const computedOrePurity = computed(() => orePurity.apply(0.1));
@ -75,10 +94,21 @@ const layer = createLayer(id, function (this: BaseLayer) {
enabled: coal.efficientSmelther.bought
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.mul(oil.activeSmelter.value, oil.oilEffectiveness.value).add(1),
multiplier: () =>
Decimal.mul(oil.activeSmelter.value, oil.oilEffectiveness.value).add(1),
description: "Oil Smelter",
enabled: () => Decimal.gt(oil.activeSmelter.value, 0)
})),
createMultiplicativeModifier(() => ({
multiplier: dyes.boosts.purple2,
description: "Purple Dye Boost 2",
enabled: () => Decimal.gte(dyes.dyes.purple.amount.value, 1)
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.add(plastic.activeRefinery.value, 1).sqrt(),
description: "De Louvre",
enabled: dyes.upgrades.redDyeUpg2.bought
}))
]);
const computedAutoSmeltSpeed = computed(() => autoSmeltSpeed.apply(0));
const autoSmeltMulti = createSequentialModifier(() => [
@ -88,10 +118,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
enabled: coal.efficientSmelther.bought
})),
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.add(oil.activeBurner.value, 1).mul(oil.oilEffectiveness.value),
multiplier: () =>
Decimal.add(oil.activeBurner.value, 1).mul(oil.oilEffectiveness.value),
description: "Blaster Burner",
enabled: oil.row2Upgrades[2].bought
})),
}))
]);
const computedAutoSmeltMulti = computed(() => autoSmeltMulti.apply(1));
@ -150,13 +181,18 @@ const layer = createLayer(id, function (this: BaseLayer) {
createMultiplicativeModifier(() => ({
multiplier: () => Decimal.mul(oil.depth.value, 0.05).add(1),
description: "25m Well Depth",
enabled: oil.depthMilestones[2].earned,
enabled: oil.depthMilestones[2].earned
})),
createMultiplicativeModifier(() => ({
multiplier: oil.extractorOre,
description: "Heavy Extractor",
enabled: () => Decimal.gt(oil.activeExtractor.value, 0)
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "Carry ore in boxes",
enabled: boxes.row2Upgrades.oreUpgrade.bought
}))
]);
const computedOreAmount = computed(() => oreAmount.apply(1));
const oreSpeed = createSequentialModifier(() => [
@ -203,7 +239,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
})),
createMultiplicativeModifier(() => ({
multiplier: computedOreSpeed
})),
}))
]);
const computedOreGain = computed(() => oreGain.apply(0));
const netOreGain = createSequentialModifier(() => [
@ -216,7 +252,6 @@ const layer = createLayer(id, function (this: BaseLayer) {
}))
]);
const computedNetOreGain = computed(() => netOreGain.apply(0));
const simplePickaxe = createUpgrade(() => ({
resource: noPersist(metal),
@ -248,7 +283,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
visibility: () =>
showIf(
crucible.bought.value ||
Decimal.div(bestOre.value, computedOrePurity.value).plus(bestMetal.value).gte(1)
Decimal.div(bestOre.value, computedOrePurity.value).plus(bestMetal.value).gte(1)
)
})) as GenericUpgrade;
const coalDrill = createUpgrade(() => ({
@ -262,12 +297,14 @@ const layer = createLayer(id, function (this: BaseLayer) {
visibility: () =>
showIf(
Decimal.gte(oreDrill.amount.value, 1) &&
(coalDrill.bought.value ||
Decimal.lt(
coal.computedCoalGain.value,
Decimal.times(computedOreAmount.value, computedOreSpeed.value)
.times(coalCost)
))
(coalDrill.bought.value ||
main.days[7].opened.value ||
Decimal.lt(
coal.computedCoalGain.value,
Decimal.times(computedOreAmount.value, computedOreSpeed.value).times(
coalCost
)
))
),
onPurchase() {
main.days[2].recentlyUpdated.value = true;
@ -299,7 +336,6 @@ const layer = createLayer(id, function (this: BaseLayer) {
visibility: () => showIf(oil.depthMilestones[4].earned.value)
}));
const oreDrill = createBuyable(() => ({
resource: noPersist(metal),
cost() {
@ -318,9 +354,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
visibility: () =>
showIf(
Decimal.gte(oreDrill.amount.value, 1) ||
Decimal.div(bestOre.value, computedOrePurity.value)
.plus(bestMetal.value)
.gte(10)
Decimal.div(bestOre.value, computedOrePurity.value)
.plus(bestMetal.value)
.gte(10)
),
style: { width: "200px" }
})) as GenericBuyable;
@ -342,8 +378,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
visibility: () =>
showIf(
Decimal.gte(industrialCrucible.amount.value, 1) ||
Decimal.gte(oreDrill.amount.value, 4) ||
Decimal.gte(bestOre.value, 50)
Decimal.gte(oreDrill.amount.value, 4) ||
Decimal.gte(bestOre.value, 50)
),
style: { width: "200px" }
})) as GenericBuyable;
@ -378,10 +414,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
if (autoSmeltEnabled.value) {
smeltOre(
Decimal.min(
smeltableOre.value,
Decimal.times(computedAutoSmeltSpeed.value, diff)
), computedAutoSmeltMulti.value
Decimal.min(smeltableOre.value, Decimal.times(computedAutoSmeltSpeed.value, diff)),
computedAutoSmeltMulti.value
);
}
});
@ -418,7 +452,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
title: "Mining Speed",
modifier: oreSpeed,
base: 0.1,
unit: "/s",
unit: "/s"
}
]);
const showModifiersModal = ref(false);
@ -478,16 +512,23 @@ const layer = createLayer(id, function (this: BaseLayer) {
sticky={false}
productionDisplay={jsx(() => (
<>
{autoSmeltEnabled.value && Decimal.gte(industrialCrucible.amount.value, 1)
{autoSmeltEnabled.value &&
Decimal.gte(industrialCrucible.amount.value, 1)
? `+${formatLimit(
[
[computedAutoSmeltSpeed.value, "smelting speed"],
[computedOreGain.value, "ore gain"],
[Decimal.div(coal.computedCoalGain.value, coalCost), "coal gain"]
],
"/s",
Decimal.mul(computedOrePurity.value, computedAutoSmeltMulti.value)
)}`
[
[computedAutoSmeltSpeed.value, "smelting speed"],
[computedOreGain.value, "ore gain"],
[
Decimal.div(coal.computedCoalGain.value, coalCost),
"coal gain"
]
],
"/s",
Decimal.mul(
computedOrePurity.value,
computedAutoSmeltMulti.value
)
)}`
: undefined}
</>
))}
@ -499,7 +540,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
<Toggle
title="Auto Smelt"
modelValue={autoSmeltEnabled.value}
onUpdate:modelValue={(value: boolean) => (autoSmeltEnabled.value = value)}
onUpdate:modelValue={(value: boolean) =>
(autoSmeltEnabled.value = value)
}
/>
</div>
) : undefined}
@ -520,7 +563,14 @@ const layer = createLayer(id, function (this: BaseLayer) {
</div>
{render(oreBar)}
<Spacer />
{renderRow(simplePickaxe, doublePickaxe, crucible, coalDrill, industrialFurnace, efficientDrill)}
{renderRow(
simplePickaxe,
doublePickaxe,
crucible,
coalDrill,
industrialFurnace,
efficientDrill
)}
{renderRow(oreDrill, industrialCrucible, hotterForge)}
</>
))

View file

@ -32,6 +32,9 @@ import coal from "./coal";
import { createUpgrade, GenericUpgrade } from "features/upgrades/upgrade";
import { createMilestone, GenericMilestone } from "features/milestones/milestone";
import { formatGain } from "util/bignum";
import plastic from "./plastic";
import paper from "./paper";
import dyes from "./dyes";
const id = "oil";
const day = 9;
@ -221,7 +224,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
Decimal.pow(row2Upgrades[3].bought.value ? 4 : 5, activePump.value)
);
const pumpOil = computed(() =>
Decimal.pow(activePump.value, 2)
Decimal.add(activePump.value, computedExtraOilPumps.value)
.pow(2)
.mul(activeHeavy.value)
.mul(Decimal.add(activeHeavy2.value, 1))
.mul(activeExtractor.value)
@ -413,7 +417,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
display: {
requirement: "150m Well Depth",
effectDisplay:
"It appears that coal and metal appear a lot more when you go this deep! Unlock more coal and metal upgrades!"
"It appears that coal and metal appear a lot more when you go this deep! Unlock an upgrade apiece for coal and metal!"
},
shouldEarn: () => Decimal.gte(depth.value, 150),
visibility: () => showIf(depthMilestones[3].earned.value)
@ -598,7 +602,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
cost: 25000,
display: {
title: "Oil Integration",
description: "Reduce Oil Well's coal consumption multipler from 5 to 4"
description: "Reduce Oil Pump's coal consumption multipler from 5 to 4"
},
style: { color: colorText }
})),
@ -667,6 +671,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
description: "Metal Drill Upgrade",
enabled: row1Upgrades[3].bought
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "Guide to drilling",
enabled: paper.upgrades.drillingUpgrade.bought
})),
createMultiplicativeModifier(() => ({
multiplier: () => coalEffectiveness.value,
description: "Effectiveness",
@ -700,6 +709,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
description: "3000m Well Depth",
enabled: depthMilestones[7].earned
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "Oil and where to find it",
enabled: paper.upgrades.oilUpgrade.bought
})),
createMultiplicativeModifier(() => ({
multiplier: () => coalEffectiveness.value,
description: "Effectiveness",
@ -718,6 +732,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
addend: () => Decimal.negate(smelterOil.value),
description: "Oil Smelter",
enabled: () => Decimal.gt(activeSmelter.value, 0)
})),
createAdditiveModifier(() => ({
addend: () => Decimal.negate(plastic.oilCost.value),
description: "Oil Refinery",
enabled: () => Decimal.gt(plastic.activeRefinery.value, 0)
}))
]);
const computedOilConsumption = computed(() => oilConsumption.apply(0));
@ -736,6 +755,15 @@ const layer = createLayer(id, function (this: BaseLayer) {
]);
const computedOilSubstitution = computed(() => oilSubstitution.apply(0));
const extraOilPumps = createSequentialModifier(() => [
createAdditiveModifier(() => ({
addend: dyes.boosts.red1,
description: "Red Dye Boost 1",
enabled: () => Decimal.gte(dyes.dyes.red.amount.value, 1)
}))
])
const computedExtraOilPumps = computed(() => extraOilPumps.apply(0));
const [generalTab, generalTabCollapsed] = createCollapsibleModifierSections(() => [
{
title: "Coal Consumption",
@ -782,6 +810,14 @@ const layer = createLayer(id, function (this: BaseLayer) {
visible() {
return Decimal.gt(computedOilSubstitution.value, 0);
}
},
{
title: "Extra Oil Pumps",
modifier: extraOilPumps,
base: 0,
visible() {
return Decimal.gt(computedExtraOilPumps.value, 0)
}
}
]);
const showModifiersModal = ref(false);
@ -826,7 +862,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
oil.value = Decimal.sub(
oil.value,
Decimal.mul(oilCost, oilEffectiveness.value).mul(diff)
);
).max(0);
} else {
oilEffectiveness.value = Decimal.dOne;
}
@ -889,12 +925,12 @@ const layer = createLayer(id, function (this: BaseLayer) {
<>
{render(trackerDisplay)}
<Spacer />
{Decimal.lt(coalEffectiveness.value, 1)
? "Coal efficiency: " + format(Decimal.mul(coalEffectiveness.value, 100)) + "%"
: null}
{Decimal.lt(oilEffectiveness.value, 1)
? "Oil efficiency: " + format(Decimal.mul(oilEffectiveness.value, 100)) + "%"
: null}
{Decimal.lt(coalEffectiveness.value, 1) ? (
<div>Coal efficiency: {format(Decimal.mul(coalEffectiveness.value, 100))}%</div>
) : null}
{Decimal.lt(oilEffectiveness.value, 1) ? (
<div>Oil efficiency: {format(Decimal.mul(oilEffectiveness.value, 100))}%</div>
) : null}
<MainDisplay
resource={oil}
color={color}

View file

@ -5,23 +5,28 @@
import Spacer from "components/layout/Spacer.vue";
import Modal from "components/Modal.vue";
import { createCollapsibleModifierSections, setUpDailyProgressTracker } from "data/common";
import { main } from "data/projEntry";
import { BuyableOptions, 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 } from "features/resources/resource";
import { createResource, displayResource, Resource } from "features/resources/resource";
import { createUpgrade } from "features/upgrades/upgrade";
import { globalBus } from "game/events";
import { BaseLayer, createLayer } from "game/layers";
import { createMultiplicativeModifier, createSequentialModifier, Modifier } from "game/modifiers";
import { noPersist } from "game/persistence";
import Decimal, { DecimalSource, format, formatWhole } from "util/bignum";
import { WithRequired } from "util/common";
import { render, renderCol } from "util/vue";
import { render, renderCol, renderRow } from "util/vue";
import { computed, ref, unref } from "vue";
import cloth from "./cloth";
import coal from "./coal";
import elves from "./elves";
import plastic from "./plastic";
import trees from "./trees";
import dyes from "./dyes";
const id = "paper";
const day = 5;
@ -96,9 +101,16 @@ const layer = createLayer(id, function (this: BaseLayer) {
showAmount: false
},
resource: noPersist(paper),
cost: () => Decimal.pow(5, buyable.amount.value).times(10),
cost() {
let v = this.amount.value;
if (options.elfName === "Star" || options.elfName === "Bell") v = Decimal.pow(v, 2);
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, paperBook.amount.value).times(v);
return Decimal.pow(5, v).times(10);
},
style: "width: 600px"
})) as GenericBuyable;
})) as GenericBuyable & { resource: Resource };
return buyable;
}
@ -150,6 +162,24 @@ const layer = createLayer(id, function (this: BaseLayer) {
buyableName: "Kiln",
visibility: () => showIf(elves.elves.kilnElf.bought.value)
});
const paperBook = createBook({
name: "The Book Thief",
elfName: "Star",
buyableName: "Paper Buyables",
visibility: () => showIf(elves.elves.paperElf.bought.value)
});
const boxBook = createBook({
name: "Not a box",
elfName: "Bell",
buyableName: "Box Buyables",
visibility: () => showIf(elves.elves.boxElf.bought.value)
});
const clothBook = createBook({
name: "Fuzzy Bee and Friends",
elfName: "Gingersnap",
buyableName: "Cloth Buyables",
visibility: () => showIf(elves.elves.clothElf.bought.value)
});
const books = {
cuttersBook,
plantersBook,
@ -159,9 +189,41 @@ const layer = createLayer(id, function (this: BaseLayer) {
fertilizerBook,
smallFireBook,
bonfireBook,
kilnBook
kilnBook,
paperBook,
boxBook,
clothBook
};
const clothUpgrade = createUpgrade(() => ({
resource: noPersist(paper),
cost: 1e8,
visibility: () => showIf(plastic.upgrades.paperTools.bought.value),
display: {
title: "Shepherding for Dummies",
description: "Double effectiveness of all cloth actions"
}
}));
const drillingUpgrade = createUpgrade(() => ({
resource: noPersist(paper),
cost: 1e9,
visibility: () => showIf(plastic.upgrades.paperTools.bought.value),
display: {
title: "Guide to drilling",
description: "Double drilling power"
}
}));
const oilUpgrade = createUpgrade(() => ({
resource: noPersist(paper),
cost: 1e10,
visibility: () => showIf(plastic.upgrades.paperTools.bought.value),
display: {
title: "Oil and where to find it",
description: "Double oil gain"
}
}));
const upgrades = { clothUpgrade, drillingUpgrade, oilUpgrade };
const paperGain = createSequentialModifier(() => [
createMultiplicativeModifier(() => ({
multiplier: 2,
@ -177,6 +239,16 @@ const layer = createLayer(id, function (this: BaseLayer) {
multiplier: 2,
description: "Scholar's jacket",
enabled: cloth.paperUpgrades.paperUpgrade3.bought
})),
createMultiplicativeModifier(() => ({
multiplier: 10,
description: "Felt Elbow Pads",
enabled: cloth.paperUpgrades.paperUpgrade4.bought
})),
createMultiplicativeModifier(() => ({
multiplier: dyes.boosts.yellow1,
description: "Yellow Dye Boost 1",
enabled: () => Decimal.gte(dyes.dyes.yellow.amount.value, 1)
}))
]) as WithRequired<Modifier, "description" | "revert">;
@ -199,6 +271,17 @@ const layer = createLayer(id, function (this: BaseLayer) {
/>
));
globalBus.on("update", diff => {
if (Decimal.lt(main.day.value, day)) {
return;
}
paper.value = Decimal.times(diff, plastic.buyables.passivePaper.amount.value)
.times(paperConversion.currentGain.value)
.div(100)
.add(paper.value);
});
const { total: totalPaper, trackerDisplay } = setUpDailyProgressTracker({
resource: paper,
goal: 5e3,
@ -220,6 +303,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
totalPaper,
paperConversion,
books,
upgrades,
generalTabCollapsed,
minWidth: 700,
display: jsx(() => (
@ -230,6 +314,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
<Spacer />
{render(makePaper)}
<Spacer />
{renderRow(...Object.values(upgrades))}
<Spacer />
{renderCol(...Object.values(books))}
</>
))

326
src/data/layers/plastic.tsx Normal file
View file

@ -0,0 +1,326 @@
/**
* @module
* @hidden
*/
import Column from "components/layout/Column.vue";
import Row from "components/layout/Row.vue";
import Spacer from "components/layout/Spacer.vue";
import Modal from "components/Modal.vue";
import {
changeActiveBuyables,
createCollapsibleModifierSections,
setUpDailyProgressTracker
} from "data/common";
import { main } from "data/projEntry";
import { createBuyable, GenericBuyable } from "features/buyable";
import { jsx, showIf } from "features/feature";
import MainDisplay from "features/resources/MainDisplay.vue";
import { createResource, Resource } from "features/resources/resource";
import { createUpgrade, GenericUpgrade } from "features/upgrades/upgrade";
import { globalBus } from "game/events";
import { BaseLayer, createLayer } from "game/layers";
import {
createAdditiveModifier,
createMultiplicativeModifier,
createSequentialModifier
} from "game/modifiers";
import { noPersist, persistent } from "game/persistence";
import Decimal, { DecimalSource, format, formatWhole } from "util/bignum";
import { render, renderCol, renderRow } from "util/vue";
import { computed, ref, unref } from "vue";
import boxes from "./boxes";
import metal from "./metal";
import oil from "./oil";
import dyes from "./dyes";
const id = "plastic";
const day = 10;
const layer = createLayer(id, function (this: BaseLayer) {
const name = "Plastic";
const color = "#DCD9CD";
const plastic = createResource<DecimalSource>(0, "plastic");
const [generalTab, generalTabCollapsed] = createCollapsibleModifierSections(() => [
{
title: "Plastic Gain",
modifier: plasticGain,
base: 0
}
]);
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
}}
/>
));
const activeRefinery = persistent<DecimalSource>(0);
const oilCost = computed(() => Decimal.times(activeRefinery.value, 100));
const buildRefinery = createBuyable(() => ({
resource: metal.metal,
cost() {
const v = new Decimal(this.amount.value);
return Decimal.pow(1.2, v).times(1e7);
},
display: jsx(() => (
<>
<h3>Refinery</h3>
<br />
Refines oil into plastic pellets
<br />
Consumes 100 oil/s to create 1 plastic/s
<br />
<br />
Currently:
<br />-{format(oilCost.value)} oil/sec
<br />+{format(activeRefinery.value)} plastic/sec
<br />
<br />
Cost: {formatWhole(unref(buildRefinery.cost!))}{" "}
{buildRefinery.resource!.displayName}
</>
)),
onPurchase() {
activeRefinery.value = Decimal.add(activeRefinery.value, 1);
},
style: {
width: "300px"
}
})) as GenericBuyable & { resource: Resource };
const {
min: minRefinery,
max: maxRefinery,
add: addRefinery,
remove: removeRefinery
} = changeActiveBuyables({
buyable: buildRefinery,
active: activeRefinery,
style: { minHeight: "20px", width: "40px", color: "var(--feature-foreground)" }
});
const upgradeCost = computed(() =>
Decimal.pow(
5,
Decimal.add(
[...Object.values(upgrades), ...Object.values(elfUpgrades)].filter(
upg => upg.bought.value
).length,
2
)
)
);
const paperTools = createUpgrade(() => ({
resource: noPersist(plastic),
cost: upgradeCost,
display: () => ({
title: "Plastic Scissors",
description: "Unlock paper upgrades",
showCost: !paperTools.bought.value
})
})) as GenericUpgrade;
const boxTools = createUpgrade(() => ({
resource: noPersist(plastic),
cost: upgradeCost,
display: () => ({
title: "Plastic Level",
description: "Unlock box upgrades",
showCost: !boxTools.bought.value
})
})) as GenericUpgrade;
const clothTools = createUpgrade(() => ({
resource: noPersist(plastic),
cost: upgradeCost,
display: () => ({
title: "Plastic Cane",
description: "Unlock cloth upgrades",
showCost: !clothTools.bought.value
})
})) as GenericUpgrade;
const upgrades = { paperTools, boxTools, clothTools };
const paperElf = createUpgrade(() => ({
resource: noPersist(plastic),
cost: upgradeCost,
visibility: () => showIf(paperTools.bought.value),
display: () => ({
title: "Paper Elf Recruitment",
description: "Double plastic gain and unlock a new elf for training",
showCost: !paperElf.bought.value
})
})) as GenericUpgrade;
const boxElf = createUpgrade(() => ({
resource: noPersist(plastic),
cost: upgradeCost,
visibility: () => showIf(boxTools.bought.value),
display: () => ({
title: "Box Elf Recruitment",
description: "Double plastic gain and unlock a new elf for training",
showCost: !boxElf.bought.value
})
})) as GenericUpgrade;
const clothElf = createUpgrade(() => ({
resource: noPersist(plastic),
cost: upgradeCost,
visibility: () => showIf(clothTools.bought.value),
display: () => ({
title: "Cloth Elf Recruitment",
description: "Double plastic gain and unlock a new elf for training",
showCost: !clothElf.bought.value
})
})) as GenericUpgrade;
const elfUpgrades = { paperElf, boxElf, clothElf };
const passivePaper = createBuyable(() => ({
resource: noPersist(plastic),
cost() {
const amount = this.amount.value;
return Decimal.pow(1.3, amount).times(100);
},
visibility: () => showIf(paperElf.bought.value),
display: {
title: "Plastic Printing Press",
description: "Gain +1% of your paper gain per second",
effectDisplay: jsx(() => <>{formatWhole(passivePaper.amount.value)}%</>),
showAmount: false
}
})) as GenericBuyable;
const passiveBoxes = createBuyable(() => ({
resource: noPersist(plastic),
cost() {
const amount = this.amount.value;
return Decimal.pow(1.3, amount).times(100);
},
visibility: () => showIf(boxElf.bought.value),
display: {
title: "Plastic Box Folder",
description: "Gain +1% of your box gain per second",
effectDisplay: jsx(() => <>{formatWhole(passiveBoxes.amount.value)}%</>),
showAmount: false
}
})) as GenericBuyable;
const clothGains = createBuyable(() => ({
resource: noPersist(plastic),
cost() {
const amount = this.amount.value;
return Decimal.pow(1.3, amount).times(100);
},
visibility: () => showIf(clothElf.bought.value),
display: {
title: "Plastic Shepherd",
description: "All cloth actions are +10% more efficient",
effectDisplay: jsx(() => (
<>{formatWhole(Decimal.times(clothGains.amount.value, 10))}%</>
)),
showAmount: false
}
})) as GenericBuyable;
const buyables = { passivePaper, passiveBoxes, clothGains };
const plasticGain = createSequentialModifier(() => [
createAdditiveModifier(() => ({
addend: activeRefinery,
description: "Oil Refinery",
enabled: () => Decimal.gt(activeRefinery.value, 0)
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "Paper Elf Recruitment",
enabled: paperElf.bought
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "Box Elf Recruitment",
enabled: boxElf.bought
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "Cloth Elf Recruitment",
enabled: clothElf.bought
})),
createMultiplicativeModifier(() => ({
multiplier: 2,
description: "Carry plastic in boxes",
enabled: boxes.row2Upgrades.plasticUpgrade.bought
})),
createMultiplicativeModifier(() => ({
multiplier: () => oil.oilEffectiveness.value,
description: "Effectiveness",
enabled: () => Decimal.lt(oil.oilEffectiveness.value, 1)
})),
createMultiplicativeModifier(() => ({
multiplier: dyes.boosts.yellow1,
description: "Yellow Dye Boost 1",
enabled: () => Decimal.gte(dyes.dyes.yellow.amount.value, 1)
}))
]);
const computedPlasticGain = computed(() => plasticGain.apply(0));
globalBus.on("update", diff => {
if (Decimal.lt(main.day.value, day)) {
return;
}
plastic.value = Decimal.times(diff, computedPlasticGain.value).add(plastic.value);
});
const { total: totalPlastic, trackerDisplay } = setUpDailyProgressTracker({
resource: plastic,
goal: 2.5e5,
name,
day,
color,
textColor: "var(--feature-foreground)",
modal: {
show: showModifiersModal,
display: modifiersModal
}
});
return {
name,
color,
plastic,
totalPlastic,
buildRefinery,
activeRefinery,
oilCost,
upgrades,
elfUpgrades,
buyables,
generalTabCollapsed,
minWidth: 700,
display: jsx(() => (
<>
{render(trackerDisplay)}
<Spacer />
<MainDisplay resource={plastic} color={color} style="margin-bottom: 0" effectDisplay={
Decimal.gt(computedPlasticGain.value, 0)
? `+${format(computedPlasticGain.value)}/s`
: undefined
} />
<Spacer />
<Column>
{render(buildRefinery)}
<div>
{formatWhole(Decimal.floor(activeRefinery.value))}/
{formatWhole(Decimal.floor(buildRefinery.amount.value))}
</div>
{renderRow(minRefinery, removeRefinery, addRefinery, maxRefinery)}
</Column>
<Row>
{renderCol(paperTools, paperElf, passivePaper)}
{renderCol(boxTools, boxElf, passiveBoxes)}
{renderCol(clothTools, clothElf, clothGains)}
</Row>
</>
))
};
});
export default layer;

View file

@ -34,6 +34,7 @@ import coal from "./coal";
import elves from "./elves";
import paper from "./paper";
import workshop from "./workshop";
import dyes from "./dyes";
const id = "trees";
const day = 1;
@ -76,6 +77,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
multiplier: 4,
description: "Lumberjack Boots",
enabled: cloth.treesUpgrades.treesUpgrade1.bought
})),
createAdditiveModifier(() => ({
addend: dyes.boosts.blue1,
description: "Blue Dye Boost 1",
enabled: () => Decimal.gte(dyes.dyes.blue.amount.value, 1)
}))
]) as WithRequired<Modifier, "description" | "revert">;
const trees = createResource(
@ -414,6 +420,16 @@ const layer = createLayer(id, function (this: BaseLayer) {
description: "Carry more logs",
enabled: boxes.upgrades.logsUpgrade.bought
})),
createMultiplicativeModifier(() => ({
multiplier: 10,
description: "Felt-Gripped Axe",
enabled: cloth.treesUpgrades.treesUpgrade4.bought
})),
createMultiplicativeModifier(() => ({
multiplier: computed(() => Decimal.add(computedAutoCuttingAmount.value, 1).log10().plus(1)),
description: "Is Blue Dye just Water?",
enabled: dyes.upgrades.blueDyeUpg.bought
})),
createExponentialModifier(() => ({
exponent: 1.2,
description: "100% Foundation Completed",

View file

@ -29,6 +29,8 @@ import boxesSymbol from "./symbols/cardboardBox.png";
import metalSymbol from "./symbols/metal.png";
import clothSymbol from "./symbols/cloth.png";
import oilSymbol from "./symbols/oil.png";
import plasticSymbol from "./symbols/plastic.png";
import dyesSymbol from "./symbols/dyes.png";
import managementSymbol from "./symbols/elfManagement.png"
import coal from "./layers/coal";
import elves from "./layers/elves";
@ -37,7 +39,6 @@ import boxes from "./layers/boxes";
import metal from "./layers/metal";
import cloth from "./layers/cloth";
import oil from "./layers/oil";
import management from "./layers/management";
export interface Day extends VueFeature {
day: number;
@ -238,18 +239,20 @@ export const main = createLayer("main", function (this: BaseLayer) {
createDay(() => ({
day: 10,
shouldNotify: false,
layer: null, // "plastic"
symbol: "",
story: "",
completedStory: ""
layer: "plastic",
symbol: plasticSymbol,
story: "Now that plenty of oil has been prepared, it's time to start refining it into plastic! This should be incredibly useful not only for toys, but making tools and other items!",
completedStory:
"You've started refining massive amounts of oil into slightly less massive amounts of plastic. You have a slight pang of regret thinking of the environmental impact, but ultimately decide Christmas is worth it. Good Job!"
})),
createDay(() => ({
day: 11,
shouldNotify: false,
layer: null, // "dyes"
symbol: "",
story: "",
completedStory: ""
layer: "dyes",
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!",
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..."
})),
createDay(() => ({
day: 12,
@ -414,19 +417,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,
boxes,
metal,
cloth,
oil,
management
];
): Array<GenericLayer> => [main, trees, workshop, coal, elves, paper, boxes, metal, cloth, oil];
/**
* A computed ref whose value is true whenever the game is over.

BIN
src/data/symbols/dyes.png Normal file

Binary file not shown.

After

(image error) Size: 2.1 KiB

Binary file not shown.

After

(image error) Size: 7.6 KiB

View file

@ -109,21 +109,21 @@ export default defineComponent({
};
switch (unref(direction)) {
case Direction.Up:
barStyle.clipPath = `inset(${normalizedProgress.value}% 0% 0% 0%)`;
barStyle.width = unwrapRef(width) + 1 + "px";
barStyle.clipPath = `inset(${normalizedProgress.value}% -2px -2px -2px)`;
barStyle.width = unwrapRef(width) + 2 + "px";
break;
case Direction.Down:
barStyle.clipPath = `inset(0% 0% ${normalizedProgress.value}% 0%)`;
barStyle.width = unwrapRef(width) + 1 + "px";
barStyle.clipPath = `inset(-2px -2px ${normalizedProgress.value}% -2px)`;
barStyle.width = unwrapRef(width) + 2 + "px";
break;
case Direction.Right:
barStyle.clipPath = `inset(0% ${normalizedProgress.value}% 0% 0%)`;
barStyle.clipPath = `inset(-2px ${normalizedProgress.value}% -2px -2px)`;
break;
case Direction.Left:
barStyle.clipPath = `inset(0% 0% 0% ${normalizedProgress.value} + '%)`;
barStyle.clipPath = `inset(-2px -2px -2px ${normalizedProgress.value} + '%)`;
break;
case Direction.Default:
barStyle.clipPath = "inset(0% 50% 0% 0%)";
barStyle.clipPath = "inset(-2px 50% -2px -2px)";
break;
}
return barStyle;
@ -146,6 +146,8 @@ export default defineComponent({
.bar {
position: relative;
display: table;
overflow: hidden;
border-radius: 10px;
}
.overlayTextContainer {
@ -166,7 +168,6 @@ export default defineComponent({
border-radius: 10px;
border-color: var(--foreground);
overflow: hidden;
mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
margin: 0;
}

View file

@ -4,9 +4,9 @@
:style="{
visibility: unref(visibility) === Visibility.Hidden ? 'hidden' : undefined
}"
class="table"
class="table-grid"
>
<div v-for="row in unref(rows)" class="row" :class="{ mergeAdjacent }" :key="row">
<div v-for="row in unref(rows)" class="row-grid" :class="{ mergeAdjacent }" :key="row">
<GridCell
v-for="col in unref(cols)"
:key="col"

View file

@ -3,7 +3,7 @@
<div
class="main-display-container"
:class="classes ?? {}"
:style="[{ height: `${(effectRef?.$el.clientHeight ?? 0) + 50}px` }, style ?? {}]"
:style="[{ 'min-height': `${(effectRef?.$el.clientHeight ?? 0) + 50}px` }, style ?? {}]"
>
<div class="main-display">
<span v-if="showPrefix">You have </span>
@ -23,7 +23,7 @@
<div v-else
class="main-display-container"
:class="classes ?? {}"
:style="[{ height: '50px' }, style ?? {}]"
:style="[{ 'min-height': '50px' }, style ?? {}]"
>
<div class="main-display">
<span v-if="showPrefix">You have </span>

View file

@ -49,7 +49,7 @@ requestAnimationFrame(async () => {
const toast = useToast();
const { updateServiceWorker } = useRegisterSW({
onNeedRefresh() {
toast.info("New content available, click or reload to update.", {
toast.info("New content available, click here to update.", {
timeout: false,
closeOnClick: false,
draggable: false,