From 1ccdbeeadcbe3ef3e37a7b54ce203201e78b21cf Mon Sep 17 00:00:00 2001 From: ducdat0507 <62660527+ducdat0507@users.noreply.github.com> Date: Wed, 14 Dec 2022 19:55:32 +0700 Subject: [PATCH] (DISABLE AUTOSAVE BEFORE UPDATING) Rough max buy implementation --- src/data/layers/boxes.tsx | 77 +++++++++++++++++++++++++++++++++++- src/data/layers/cloth.tsx | 25 ++++++++++-- src/data/layers/coal.tsx | 83 +++++++++++++++++++++++++++++++++++---- src/data/layers/dyes.tsx | 18 ++++++++- src/data/layers/elves.tsx | 77 +++++++++++++++++++----------------- src/data/layers/metal.tsx | 40 +++++++++++++++++-- src/data/layers/oil.tsx | 58 ++++++++++++++++++++++++--- src/data/layers/paper.tsx | 26 +++++++++++- src/data/layers/trees.tsx | 37 +++++++++++++++-- 9 files changed, 377 insertions(+), 64 deletions(-) diff --git a/src/data/layers/boxes.tsx b/src/data/layers/boxes.tsx index 8a1f27c..34a5884 100644 --- a/src/data/layers/boxes.tsx +++ b/src/data/layers/boxes.tsx @@ -27,6 +27,7 @@ import { WithRequired } from "util/common"; import { render, renderGrid, renderRow } from "util/vue"; import { computed, ComputedRef, ref, unref } from "vue"; import dyes from "./dyes"; +import { ElfBuyable } from "./elves"; import management from "./management"; import paper from "./paper"; import plastic from "./plastic"; @@ -34,7 +35,7 @@ import trees from "./trees"; import workshop from "./workshop"; import wrappingPaper from "./wrapping-paper"; -export type BoxesBuyable = GenericBuyable & { +export type BoxesBuyable = ElfBuyable & { resource: Resource; freeLevels: ComputedRef; totalAmount: ComputedRef; @@ -231,6 +232,19 @@ const layer = createLayer(id, function (this: BaseLayer) { .div(dyes.boosts.orange2.value) .div(wrappingPaper.boosts.ocean1.value); }, + inverseCost(x: DecimalSource) { + let scaling = 3; + if (management.elfTraining.boxElfTraining.milestones[2].earned.value) { + scaling--; + } + + let v = Decimal.mul(x, wrappingPaper.boosts.ocean1.value) + .mul(dyes.boosts.orange2.value) + .div(100).log(scaling); + + v = v.div(Decimal.pow(0.95, paper.books.boxBook.totalAmount.value)); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, visibility: () => showIf(logsUpgrade.bought.value), freeLevels: computed(() => management.elfTraining.boxElfTraining.milestones[0].earned.value @@ -275,6 +289,18 @@ const layer = createLayer(id, function (this: BaseLayer) { } return Decimal.pow(scaling, v).times(1000).div(dyes.boosts.orange2.value); }, + inverseCost(x: DecimalSource) { + let scaling = 5; + if (management.elfTraining.boxElfTraining.milestones[2].earned.value) { + scaling--; + } + + let v = Decimal.mul(x, dyes.boosts.orange2.value) + .div(1000).log(scaling); + + v = v.div(Decimal.pow(0.95, paper.books.boxBook.totalAmount.value)); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, visibility: () => showIf(ashUpgrade.bought.value), freeLevels: computed(() => management.elfTraining.boxElfTraining.milestones[0].earned.value @@ -319,6 +345,18 @@ const layer = createLayer(id, function (this: BaseLayer) { } return Decimal.pow(scaling, v).times(1000).div(dyes.boosts.orange2.value); }, + inverseCost(x: DecimalSource) { + let scaling = 7; + if (management.elfTraining.boxElfTraining.milestones[2].earned.value) { + scaling--; + } + + let v = Decimal.mul(x, dyes.boosts.orange2.value) + .div(1000).log(scaling); + + v = v.div(Decimal.pow(0.95, paper.books.boxBook.totalAmount.value)); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, visibility: () => showIf(coalUpgrade.bought.value), freeLevels: computed(() => management.elfTraining.boxElfTraining.milestones[0].earned.value @@ -367,6 +405,19 @@ const layer = createLayer(id, function (this: BaseLayer) { .div(dyes.boosts.orange2.value) .div(wrappingPaper.boosts.ocean1.value); }, + inverseCost(x: DecimalSource) { + let scaling = 10; + if (management.elfTraining.boxElfTraining.milestones[2].earned.value) { + scaling--; + } + + let v = Decimal.mul(x, wrappingPaper.boosts.ocean1.value) + .mul(dyes.boosts.orange2.value) + .div(1e25).log(scaling); + + v = v.div(Decimal.pow(0.95, paper.books.boxBook.totalAmount.value)); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, visibility: () => showIf(management.elfTraining.boxElfTraining.milestones[3].earned.value), freeLevels: computed(() => management.elfTraining.boxElfTraining.milestones[0].earned.value @@ -411,6 +462,18 @@ const layer = createLayer(id, function (this: BaseLayer) { } return Decimal.pow(scaling, v).times(1e28).div(dyes.boosts.orange2.value); }, + inverseCost(x: DecimalSource) { + let scaling = 15; + if (management.elfTraining.boxElfTraining.milestones[2].earned.value) { + scaling--; + } + + let v = Decimal.mul(x, dyes.boosts.orange2.value) + .div(1e28).log(scaling); + + v = v.div(Decimal.pow(0.95, paper.books.boxBook.totalAmount.value)); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, visibility: () => showIf(management.elfTraining.boxElfTraining.milestones[3].earned.value), freeLevels: computed(() => management.elfTraining.boxElfTraining.milestones[0].earned.value @@ -455,6 +518,18 @@ const layer = createLayer(id, function (this: BaseLayer) { } return Decimal.pow(scaling, v).times(1000).div(dyes.boosts.orange2.value); }, + inverseCost(x: DecimalSource) { + let scaling = 20; + if (management.elfTraining.boxElfTraining.milestones[2].earned.value) { + scaling--; + } + + let v = Decimal.mul(x, dyes.boosts.orange2.value) + .div(1000).log(scaling); + + v = v.div(Decimal.pow(0.95, paper.books.boxBook.totalAmount.value)); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, visibility: () => showIf(management.elfTraining.boxElfTraining.milestones[3].earned.value), freeLevels: computed(() => management.elfTraining.boxElfTraining.milestones[0].earned.value diff --git a/src/data/layers/cloth.tsx b/src/data/layers/cloth.tsx index 6fdbf41..3d910b0 100644 --- a/src/data/layers/cloth.tsx +++ b/src/data/layers/cloth.tsx @@ -30,6 +30,7 @@ import { render, renderCol, renderRow } from "util/vue"; import { computed, ref } from "vue"; import boxes from "./boxes"; import dyes from "./dyes"; +import { ElfBuyable } from "./elves"; import management from "./management"; import metal from "./metal"; import paper from "./paper"; @@ -188,11 +189,17 @@ const layer = createLayer(id, function (this: BaseLayer) { v = Decimal.pow(0.95, paper.books.clothBook.totalAmount.value).times(v); return Decimal.pow(1.5, v).times(1e14); }, + inverseCost(x: DecimalSource) { + let v = Decimal.div(x, 1e14).log(1.5); + v = v.div(Decimal.pow(0.95, paper.books.clothBook.totalAmount.value)); + if (Decimal.gte(v, 100)) v = Decimal.mul(v, 100).root(2); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, display: { title: "Build more pens", description: "Breed +1 sheep at once" } - })) as GenericBuyable & { resource: Resource }; + })) as ElfBuyable & { resource: Resource }; const betterShears = createBuyable(() => ({ resource: metal.metal, @@ -202,11 +209,17 @@ const layer = createLayer(id, function (this: BaseLayer) { v = Decimal.pow(0.95, paper.books.clothBook.totalAmount.value).times(v); return Decimal.pow(1.4, v).times(10000); }, + inverseCost(x: DecimalSource) { + let v = Decimal.div(x, 10000).log(1.4); + v = v.div(Decimal.pow(0.95, paper.books.clothBook.totalAmount.value)); + if (Decimal.gte(v, 100)) v = Decimal.mul(v, 100).root(2); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, display: { title: "Make stronger shears", description: "Shear +1 sheep at once" } - })) as GenericBuyable & { resource: Resource }; + })) as ElfBuyable & { resource: Resource }; const fasterSpinning = createBuyable(() => ({ resource: paper.paper, @@ -216,11 +229,17 @@ const layer = createLayer(id, function (this: BaseLayer) { v = Decimal.pow(0.95, paper.books.clothBook.totalAmount.value).times(v); return Decimal.pow(1.3, v).times(1000000); }, + inverseCost(x: DecimalSource) { + let v = Decimal.div(x, 1000000).log(1.3); + v = v.div(Decimal.pow(0.95, paper.books.clothBook.totalAmount.value)); + if (Decimal.gte(v, 100)) v = Decimal.mul(v, 100).root(2); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, display: { title: "Learn how to spin", description: "Spin +1 wool at once" } - })) as GenericBuyable & { resource: Resource }; + })) as ElfBuyable & { resource: Resource }; const treesUpgrade1 = createUpgrade(() => ({ resource: noPersist(cloth), diff --git a/src/data/layers/coal.tsx b/src/data/layers/coal.tsx index d2a84da..b8ac8ed 100644 --- a/src/data/layers/coal.tsx +++ b/src/data/layers/coal.tsx @@ -33,7 +33,7 @@ import { render, renderGrid, renderRow } from "util/vue"; import { computed, ref, unref } from "vue"; import boxes from "./boxes"; import cloth from "./cloth"; -import elves from "./elves"; +import elves, { ElfBuyable } from "./elves"; import metal from "./metal"; import oil from "./oil"; import paper from "./paper"; @@ -103,6 +103,14 @@ const layer = createLayer(id, function (this: BaseLayer) { v = Decimal.pow(0.95, paper.books.smallFireBook.totalAmount.value).times(v); return v.pow(1.5).times(1e4); }, + inverseCost(x: DecimalSource) { + let v = Decimal.div(x, 1e4).root(1.5); + v = v.div(Decimal.pow(0.95, paper.books.smallFireBook.totalAmount.value)); + if (Decimal.gte(v, 10000)) v = Decimal.mul(v, 10000).root(2); + if (Decimal.gte(v, 100)) v = Decimal.mul(v, 100).root(2); + v = v.sub(Decimal.times(buildBonfire.amount.value, unref(buildBonfire.cost!))); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, display: jsx(() => ( <>

Small Fire

@@ -126,7 +134,7 @@ const layer = createLayer(id, function (this: BaseLayer) { color: colorText, width: "160px" } - })) as GenericBuyable & { resource: Resource }; + })) as ElfBuyable & { resource: Resource }; const { min: minFire, @@ -160,6 +168,9 @@ const layer = createLayer(id, function (this: BaseLayer) { cost() { return Decimal.pow(0.95, paper.books.bonfireBook.totalAmount.value).times(10); }, + inverseCost(x: DecimalSource) { + return Decimal.div(x, Decimal.pow(0.95, paper.books.bonfireBook.totalAmount.value).times(10)).floor(); + }, display: jsx(() => ( <>

Bonfire

@@ -185,7 +196,7 @@ const layer = createLayer(id, function (this: BaseLayer) { width: "160px" }, visibility: () => showIf(unlockBonfire.bought.value) - })) as GenericBuyable & { resource: Resource }; + })) as ElfBuyable & { resource: Resource }; const { min: minBonfire, max: maxBonfire, @@ -220,6 +231,13 @@ const layer = createLayer(id, function (this: BaseLayer) { v = Decimal.pow(0.95, paper.books.kilnBook.totalAmount.value).times(v); return Decimal.pow(1.1, v).times(1e7); }, + inverseCost(x: DecimalSource) { + let v = Decimal.div(x, 1e7).log(1.1); + v = v.div(Decimal.pow(0.95, paper.books.kilnBook.totalAmount.value)); + if (Decimal.gte(v, 10000)) v = Decimal.mul(v, 10000).root(2); + if (Decimal.gte(v, 100)) v = Decimal.mul(v, 100).root(2); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, display: jsx(() => ( <>

Charcoal Kiln

@@ -244,7 +262,7 @@ const layer = createLayer(id, function (this: BaseLayer) { width: "160px" }, visibility: () => showIf(unlockKiln.bought.value) - })) as GenericBuyable & { resource: Resource }; + })) as ElfBuyable & { resource: Resource }; const { min: minKiln, max: maxKiln, @@ -281,6 +299,19 @@ const layer = createLayer(id, function (this: BaseLayer) { } return cost; }, + inverseCost(x: DecimalSource) { + if (management.elfTraining.coalDrillElfTraining.milestones[2].earned.value) { + x = Decimal.div(x, 10); + } + if (management.elfTraining.fertilizerElfTraining.milestones[2].earned.value) { + x = Decimal.div(x, Decimal.add(trees.totalLogs.value, Math.E).ln()); + } + let v = Decimal.div(x, 10).log(1.15); + v = v.div(Decimal.pow(0.95, paper.books.coalDrillBook.totalAmount.value)); + if (Decimal.gte(v, 10000)) v = Decimal.mul(v, 10000).root(2); + if (Decimal.gte(v, 100)) v = Decimal.mul(v, 100).root(2); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, display: jsx(() => ( <>

Coal Drill

@@ -303,7 +334,7 @@ const layer = createLayer(id, function (this: BaseLayer) { width: "160px" }, visibility: () => showIf(metal.coalDrill.bought.value) - })) as GenericBuyable & { resource: Resource }; + })) as ElfBuyable & { resource: Resource }; const { max: maxDrill, min: minDrill, @@ -470,6 +501,18 @@ const layer = createLayer(id, function (this: BaseLayer) { v = v.div(wrappingPaper.boosts.rainbow1.value); return Decimal.add(v, 1).pow(2.5).times(10); }, + inverseCost(x: DecimalSource) { + let v = Decimal.div(x, 10).root(2.5).sub(1); + v = v.mul(wrappingPaper.boosts.rainbow1.value); + if (management.elfTraining.heatedCutterElfTraining.milestones[0].earned.value) { + v = v.div(Decimal.pow(0.95, paper.books.heatedCuttersBook.totalAmount.value)); + } + v = v.div(Decimal.pow(0.95, paper.books.heatedCuttersBook.totalAmount.value)); + if (Decimal.gte(v, 2e6)) v = Decimal.mul(v, 2e6).root(2); + if (Decimal.gte(v, 200)) v = Decimal.mul(v, 200).root(2); + if (Decimal.gte(v, 50)) v = Decimal.mul(v, 50).root(2); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, display: { title: "Heated Cutters", description: "Even warmer cutters cut down trees faster", @@ -479,7 +522,7 @@ const layer = createLayer(id, function (this: BaseLayer) { }, style: { color: colorText }, visibility: () => showIf(warmerCutters.bought.value) - })) as GenericBuyable & { display: { title: string }; resource: Resource }; + })) as ElfBuyable & { display: { title: string }; resource: Resource }; const heatedPlanters = createBuyable(() => ({ resource: noPersist(coal), cost() { @@ -494,6 +537,18 @@ const layer = createLayer(id, function (this: BaseLayer) { v = v.div(wrappingPaper.boosts.rainbow1.value); return Decimal.add(v, 1).pow(2.5).times(10); }, + inverseCost(x: DecimalSource) { + let v = Decimal.div(x, 10).root(2.5).sub(1); + v = v.mul(wrappingPaper.boosts.rainbow1.value); + if (management.elfTraining.heatedPlanterElfTraining.milestones[0].earned.value) { + v = v.div(Decimal.pow(0.95, paper.books.heatedPlantersBook.totalAmount.value)); + } + v = v.div(Decimal.pow(0.95, paper.books.heatedPlantersBook.totalAmount.value)); + if (Decimal.gte(v, 2e6)) v = Decimal.mul(v, 2e6).root(2); + if (Decimal.gte(v, 200)) v = Decimal.mul(v, 200).root(2); + if (Decimal.gte(v, 50)) v = Decimal.mul(v, 50).root(2); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, display: { title: "Heated Planters", description: "Even warmer planters plant trees faster", @@ -503,7 +558,7 @@ const layer = createLayer(id, function (this: BaseLayer) { }, style: { color: colorText }, visibility: () => showIf(warmerPlanters.bought.value) - })) as GenericBuyable & { display: { title: string }; resource: Resource }; + })) as ElfBuyable & { display: { title: string }; resource: Resource }; const moreFertilizer = createBuyable(() => ({ resource: noPersist(ash), cost() { @@ -518,6 +573,18 @@ const layer = createLayer(id, function (this: BaseLayer) { v = v.div(wrappingPaper.boosts.rainbow1.value); return Decimal.add(v, 1).pow(1.5).times(50000); }, + inverseCost(x: DecimalSource) { + let v = Decimal.div(x, 50000).root(1.5).sub(1); + v = v.mul(wrappingPaper.boosts.rainbow1.value); + if (management.elfTraining.fertilizerElfTraining.milestones[0].earned.value) { + v = v.div(Decimal.pow(0.95, paper.books.fertilizerBook.totalAmount.value)); + } + v = v.div(Decimal.pow(0.95, paper.books.fertilizerBook.totalAmount.value)); + if (Decimal.gte(v, 2e6)) v = Decimal.mul(v, 2e6).root(2); + if (Decimal.gte(v, 200)) v = Decimal.mul(v, 200).root(2); + if (Decimal.gte(v, 50)) v = Decimal.mul(v, 50).root(2); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, display: { title: "Fertilized Soil", description: "More fertilizer helps trees grow bigger", @@ -527,7 +594,7 @@ const layer = createLayer(id, function (this: BaseLayer) { }, style: { color: colorText }, visibility: () => showIf(basicFertilizer.bought.value) - })) as GenericBuyable & { display: { title: string }; resource: Resource }; + })) as ElfBuyable & { display: { title: string }; resource: Resource }; const row3buyables = [heatedCutters, heatedPlanters, moreFertilizer]; const heatedCutterEffect = createSequentialModifier(() => [ diff --git a/src/data/layers/dyes.tsx b/src/data/layers/dyes.tsx index 93f461c..4d7a5b6 100644 --- a/src/data/layers/dyes.tsx +++ b/src/data/layers/dyes.tsx @@ -32,12 +32,13 @@ import trees from "./trees"; import wrappingPaper from "./wrapping-paper"; import paper from "./paper"; import boxes from "./boxes"; +import { ElfBuyable } from "./elves"; interface Dye { name: string; amount: Resource & Persistent & { [NonPersistent]: Resource }; - buyable: GenericBuyable; + buyable: ElfBuyable; toGenerate: WithRequired; computedToGenerate: ComputedRef; display: JSXFunction; @@ -184,7 +185,7 @@ const layer = createLayer(id, function (this: BaseLayer) { }) as WithRequired; const computedToGenerate = computed(() => toGenerate.apply(0)); - const buyable: GenericBuyable = createBuyable(() => { + const buyable: ElfBuyable = createBuyable(() => { const costs = convertComputable(options.costs); return { ...options, @@ -243,6 +244,19 @@ const layer = createLayer(id, function (this: BaseLayer) { v = Decimal.mul(v, Decimal.pow(0.95, paper.books.dyeBook.totalAmount.value)); return Decimal.div(v, 10).plus(1); }, + inverseCostPre(x: DecimalSource) { + let v = Decimal.sub(x, 1).mul(10); + v = v.div(Decimal.pow(0.95, paper.books.dyeBook.totalAmount.value)); + if (Decimal.gte(v, 10)) v = Decimal.mul(v, 5).root(2); + if (Decimal.gte(v, 25)) v = Decimal.mul(v, 20).root(2); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, + inverseCost() { + if (unref(buyable.visibility) != Visibility.Visible) return Decimal.dZero; + return unref(costs).reduce((pre, c) => + Decimal.min(this.inverseCostPre(Decimal.div(c.res.value, unref(c.base)).root(unref(c.root ?? 1))), pre) + , Decimal.dInf); + }, canPurchase: computed((cost?: DecimalSource) => { if (unref(buyable.visibility) != Visibility.Visible) return false; const trueCost = cost ?? unref(buyable.cost) ?? Decimal.dInf; diff --git a/src/data/layers/elves.tsx b/src/data/layers/elves.tsx index 24c0c5b..d01ddd2 100644 --- a/src/data/layers/elves.tsx +++ b/src/data/layers/elves.tsx @@ -38,8 +38,14 @@ import workshop from "./workshop"; import wrappingPaper from "./wrapping-paper"; import dyes from "./dyes"; +export interface ElfBuyable extends GenericBuyable { + /** The inverse function of the cost formula, used to calculate the maximum amount that can be bought by elves. */ + inverseCost: (x?: DecimalSource) => DecimalSource +} + const id = "elves"; const day = 4; + const layer = createLayer(id, function (this: BaseLayer) { const name = "Elves"; const colorBright = "red"; @@ -542,13 +548,12 @@ const layer = createLayer(id, function (this: BaseLayer) { name: string; description: string; buyable: - | (GenericBuyable & { resource?: Resource }) - | (GenericBuyable & { resource?: Resource })[]; + | (ElfBuyable & { resource?: Resource }) + | (ElfBuyable & { resource?: Resource })[]; cooldownModifier: Modifier; - customCost?: (amount: DecimalSource) => DecimalSource; hasToggle?: boolean; toggleDesc?: string; - onAutoPurchase?: (buyable: GenericBuyable & { resource?: Resource }) => void; + onAutoPurchase?: (buyable: ElfBuyable & { resource?: Resource }, amount: DecimalSource) => void; onPurchase?: VoidFunction; // Will get overriden by the custom onpurchase, but that's fine canBuy?: Computable; buyMax?: Computable; @@ -566,27 +571,29 @@ const layer = createLayer(id, function (this: BaseLayer) { function update(diff: number) { if (upgrade.bought.value && unref(isActive)) { buyProgress.value = Decimal.add(buyProgress.value, diff); + const cooldown = Decimal.recip(computedAutoBuyCooldown.value); amountOfTimesDone.value += diff / cooldown.toNumber(); + + let maxBuyAmount = Decimal.div(buyProgress.value, cooldown).floor(); + buyProgress.value = Decimal.sub(buyProgress.value, maxBuyAmount.mul(cooldown)); + + if (unref(buyMax)) maxBuyAmount = Decimal.dInf; + (isArray(options.buyable) ? options.buyable : [options.buyable]).forEach( buyable => { - while (buyMax ? true : Decimal.gte(buyProgress.value, cooldown)) { - if ( - options.customCost && buyable.resource - ? Decimal.gte( - buyable.resource.value, - options.customCost(buyable.amount.value) - ) - : unref(buyable.canPurchase) - ) { - buyable.amount.value = Decimal.add(buyable.amount.value, 1); - buyProgress.value = Decimal.sub(buyProgress.value, cooldown); - options.onAutoPurchase?.(buyable); - } else { - buyProgress.value = cooldown; - break; - } - } + const buyAmount = Decimal.min( + Decimal.sub(buyable.inverseCost(buyable.resource?.value), buyable.amount.value), + maxBuyAmount + ); + + if (buyAmount.lte(0)) return; + + buyable.amount.value = Decimal.add(buyable.amount.value, buyAmount); + maxBuyAmount = Decimal.sub(maxBuyAmount, buyAmount); + options.onAutoPurchase?.(buyable, buyAmount); + + if (maxBuyAmount.lte(0)) return; } ); } @@ -723,8 +730,8 @@ const layer = createLayer(id, function (this: BaseLayer) { visibility: () => showIf(boxes.upgrades.ashUpgrade.bought.value), hasToggle: true, toggleDesc: "Activate auto-purchased bonfires", - onAutoPurchase() { - const spent = unref((this.buyable as GenericBuyable).cost!); + onAutoPurchase(buyable, amount) { + const spent = Decimal.mul(unref(buyable.cost ?? 0), amount); 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) { @@ -745,9 +752,9 @@ const layer = createLayer(id, function (this: BaseLayer) { visibility: () => showIf(boxes.upgrades.coalUpgrade.bought.value), hasToggle: true, toggleDesc: "Activate auto-purchased kilns", - onAutoPurchase() { + onAutoPurchase(_, amount) { if (kilnElf.toggle.value) { - coal.activeKilns.value = Decimal.add(coal.activeKilns.value, 1); + coal.activeKilns.value = Decimal.add(coal.activeKilns.value, amount); } }, onPurchase() { @@ -791,9 +798,9 @@ const layer = createLayer(id, function (this: BaseLayer) { showIf(management.elfTraining.expandersElfTraining.milestones[3].earned.value), hasToggle: true, toggleDesc: "Activate auto-purchased coal drills", - onAutoPurchase() { + onAutoPurchase(_, amount) { if (coalDrillElf.toggle.value) { - coal.activeDrills.value = Decimal.add(coal.activeDrills.value, 1); + coal.activeDrills.value = Decimal.add(coal.activeDrills.value, amount); } } }); @@ -807,14 +814,14 @@ const layer = createLayer(id, function (this: BaseLayer) { showIf(management.elfTraining.fertilizerElfTraining.milestones[4].earned.value), hasToggle: true, toggleDesc: "Activate auto-purchased oil drills", - onAutoPurchase(buyable) { + onAutoPurchase(buyable, amount) { if (heavyDrillElf.toggle.value) { if (buyable === oil.buildHeavy) { - oil.activeHeavy.value = Decimal.add(oil.activeHeavy.value, 1); + oil.activeHeavy.value = Decimal.add(oil.activeHeavy.value, amount); } else if (buyable === oil.buildHeavy2) { - oil.activeHeavy2.value = Decimal.add(oil.activeHeavy2.value, 1); + oil.activeHeavy2.value = Decimal.add(oil.activeHeavy2.value, amount); } else if (buyable === oil.buildExtractor) { - oil.activeExtractor.value = Decimal.add(oil.activeExtractor.value, 1); + oil.activeExtractor.value = Decimal.add(oil.activeExtractor.value, amount); } } } @@ -829,14 +836,14 @@ const layer = createLayer(id, function (this: BaseLayer) { showIf(management.elfTraining.heatedCutterElfTraining.milestones[4].earned.value), hasToggle: true, toggleDesc: "Activate auto-purchased oil-using machines", - onAutoPurchase(buyable) { + onAutoPurchase(buyable, amount) { if (heavyDrillElf.toggle.value) { if (buyable === oil.buildPump) { - oil.activePump.value = Decimal.add(oil.activePump.value, 1); + oil.activePump.value = Decimal.add(oil.activePump.value, amount); } else if (buyable === oil.buildBurner) { - oil.activeBurner.value = Decimal.add(oil.activeBurner.value, 1); + oil.activeBurner.value = Decimal.add(oil.activeBurner.value, amount); } else if (buyable === oil.buildSmelter) { - oil.activeSmelter.value = Decimal.add(oil.activeSmelter.value, 1); + oil.activeSmelter.value = Decimal.add(oil.activeSmelter.value, amount); } } } diff --git a/src/data/layers/metal.tsx b/src/data/layers/metal.tsx index 2fa0d73..a08bf55 100644 --- a/src/data/layers/metal.tsx +++ b/src/data/layers/metal.tsx @@ -34,6 +34,7 @@ import dyes from "./dyes"; import management from "./management"; import workshop from "./workshop"; import paper from "./paper"; +import { ElfBuyable } from "./elves"; const id = "metal"; const day = 7; @@ -415,6 +416,17 @@ const layer = createLayer(id, function (this: BaseLayer) { } return cost; }, + inverseCost(x: DecimalSource) { + if (management.elfTraining.metalElfTraining.milestones[3].earned.value) { + x = Decimal.mul(x, 10); + } + if (management.elfTraining.clothElfTraining.milestones[4].earned.value) { + x = Decimal.mul(x, Decimal.add(oil.depth.value, 1).sqrt()); + } + let v = Decimal.div(x, 10).log(1.15); + v = v.div(Decimal.pow(0.95, paper.books.metalBook.totalAmount.value)); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, display: { title: "Metal Drill", description: "An automated machine to help you mine more ore, faster", @@ -433,7 +445,7 @@ const layer = createLayer(id, function (this: BaseLayer) { .gte(10) ), style: { width: "200px" } - })) as GenericBuyable & { resource: Resource }; + })) as ElfBuyable & { resource: Resource }; const industrialCrucible = createBuyable(() => ({ resource: noPersist(metal), cost() { @@ -448,6 +460,17 @@ const layer = createLayer(id, function (this: BaseLayer) { } return cost; }, + inverseCost(x: DecimalSource) { + if (management.elfTraining.metalElfTraining.milestones[3].earned.value) { + x = Decimal.mul(x, 10); + } + if (management.elfTraining.clothElfTraining.milestones[4].earned.value) { + x = Decimal.mul(x, Decimal.add(oil.depth.value, 1).sqrt()); + } + let v = Decimal.div(x, 10).log(1.15).div(10); + v = v.div(Decimal.pow(0.95, paper.books.metalBook.totalAmount.value)); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, display: { title: "Industrial Crucible", description: "A giant automated crucible furnace, letting you smelt ore faster", @@ -465,7 +488,7 @@ const layer = createLayer(id, function (this: BaseLayer) { Decimal.gte(bestOre.value, 50) ), style: { width: "200px" } - })) as GenericBuyable & { resource: Resource }; + })) as ElfBuyable & { resource: Resource }; const autoSmeltEnabled = persistent(true); const hotterForge = createBuyable(() => ({ resource: coal.coal, @@ -481,6 +504,17 @@ const layer = createLayer(id, function (this: BaseLayer) { } return cost; }, + inverseCost(x: DecimalSource) { + if (management.elfTraining.metalElfTraining.milestones[3].earned.value) { + x = Decimal.mul(x, 10); + } + if (management.elfTraining.clothElfTraining.milestones[4].earned.value) { + x = Decimal.mul(x, Decimal.add(oil.depth.value, 1).sqrt()); + } + let v = Decimal.div(x, 1e12).log(10); + v = v.div(Decimal.pow(0.95, paper.books.metalBook.totalAmount.value)); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, display: { title: "Hotter Forges", description: @@ -495,7 +529,7 @@ const layer = createLayer(id, function (this: BaseLayer) { visibility: () => showIf(Decimal.gte(hotterForge.amount.value, 1) || industrialFurnace.bought.value), style: { width: "200px" } - })) as GenericBuyable & { resource: Resource }; + })) as ElfBuyable & { resource: Resource }; const hotterForgeEffect = computed(() => Decimal.times(hotterForge.amount.value, 0.25)); globalBus.on("update", diff => { diff --git a/src/data/layers/oil.tsx b/src/data/layers/oil.tsx index e8d4ffc..5b74056 100644 --- a/src/data/layers/oil.tsx +++ b/src/data/layers/oil.tsx @@ -39,6 +39,7 @@ import dyes from "./dyes"; import management from "./management"; import workshop from "./workshop"; import { WithRequired } from "util/common"; +import { ElfBuyable } from "./elves"; const id = "oil"; const day = 9; @@ -104,6 +105,12 @@ const layer = createLayer(id, function (this: BaseLayer) { v = Decimal.pow(0.95, paper.books.heavyDrillBook.totalAmount.value).times(v); return Decimal.pow(1.3, v).times(2.5e4); }, + inverseCost(x: DecimalSource) { + let v = Decimal.div(x, 2.5e4).log(1.3); + v = v.div(Decimal.pow(0.95, paper.books.heavyDrillBook.totalAmount.value)); + if (Decimal.gte(v, 100)) v = Decimal.mul(v, 100).root(4); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, display: jsx(() => ( <>

Heavy Drill

@@ -134,7 +141,7 @@ const layer = createLayer(id, function (this: BaseLayer) { color: colorText, width: "160px" } - })) as GenericBuyable & { resource: Resource }; + })) as ElfBuyable & { resource: Resource }; const { min: minHeavy, max: maxHeavy, @@ -162,6 +169,12 @@ const layer = createLayer(id, function (this: BaseLayer) { v = Decimal.pow(0.95, paper.books.heavyDrillBook.totalAmount.value).times(v); return Decimal.pow(2, v).times(1e5); }, + inverseCost(x: DecimalSource) { + let v = Decimal.div(x, 1e5).log(2); + v = v.div(Decimal.pow(0.95, paper.books.heavyDrillBook.totalAmount.value)); + if (Decimal.gte(v, 50)) v = Decimal.mul(v, 50).root(4); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, display: jsx(() => ( <>

Heavy Drill Drill

@@ -195,7 +208,7 @@ const layer = createLayer(id, function (this: BaseLayer) { color: colorText, width: "160px" } - })) as GenericBuyable & { resource: Resource }; + })) as ElfBuyable & { resource: Resource }; const { min: minHeavy2, max: maxHeavy2, @@ -218,6 +231,12 @@ const layer = createLayer(id, function (this: BaseLayer) { v = Decimal.pow(0.95, paper.books.heavyDrillBook.totalAmount.value).times(v); return Decimal.pow(8, v).times(2e5); }, + inverseCost(x: DecimalSource) { + let v = Decimal.div(x, 2e5).log(8); + v = v.div(Decimal.pow(0.95, paper.books.heavyDrillBook.totalAmount.value)); + if (Decimal.gte(v, 100)) v = Decimal.mul(v, 100).root(4); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, display: jsx(() => ( <>

Heavy Extractor

@@ -244,7 +263,7 @@ const layer = createLayer(id, function (this: BaseLayer) { color: colorText, width: "160px" } - })) as GenericBuyable & { resource: Resource }; + })) as ElfBuyable & { resource: Resource }; const { min: minExtractor, max: maxExtractor, @@ -288,6 +307,18 @@ const layer = createLayer(id, function (this: BaseLayer) { } return price; }, + inverseCost(x: DecimalSource) { + if (management.elfTraining.heavyDrillElfTraining.milestones[1].earned.value) { + x = Decimal.mul(x, 10); + } + if (row2Upgrades[4].bought.value) { + x = Decimal.mul(x, Decimal.add(totalOil.value, 1).root(6)); + } + let v = Decimal.div(x, 2e6).log(16); + v = v.div(Decimal.pow(0.95, paper.books.heavyDrillBook.totalAmount.value)); + if (Decimal.gte(v, 100)) v = Decimal.mul(v, 100).root(4); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, display: jsx(() => ( <>

Oil Pump

@@ -313,7 +344,7 @@ const layer = createLayer(id, function (this: BaseLayer) { color: colorText, width: "160px" } - })) as GenericBuyable & { resource: Resource }; + })) as ElfBuyable & { resource: Resource }; const { max: maxPump, min: minPump, @@ -343,6 +374,12 @@ const layer = createLayer(id, function (this: BaseLayer) { v = Decimal.pow(0.95, paper.books.oilBook.totalAmount.value).times(v); return Decimal.pow(2, v).times(50); }, + inverseCost(x: DecimalSource) { + let v = Decimal.div(x, 50).log(2); + v = v.div(Decimal.pow(0.95, paper.books.oilBook.totalAmount.value)); + if (Decimal.gte(v, 100)) v = Decimal.mul(v, 100).root(4); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, display: jsx(() => ( <>

Oil Burner

@@ -375,7 +412,7 @@ const layer = createLayer(id, function (this: BaseLayer) { color: colorText, width: "160px" } - })) as GenericBuyable & { resource: Resource }; + })) as ElfBuyable & { resource: Resource }; const { max: maxBurner, min: minBurner, @@ -402,6 +439,15 @@ const layer = createLayer(id, function (this: BaseLayer) { price = price.div(Decimal.add(totalOil.value, 1).root(6)); return price; }, + inverseCost(x: DecimalSource) { + if (row2Upgrades[4].bought.value) { + x = Decimal.mul(x, Decimal.add(totalOil.value, 1).root(6)); + } + let v = Decimal.div(x, 1e7).log(10); + v = v.div(Decimal.pow(0.95, paper.books.oilBook.totalAmount.value)); + if (Decimal.gte(v, 100)) v = Decimal.mul(v, 100).root(4); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, display: jsx(() => ( <>

Oil Smelter

@@ -426,7 +472,7 @@ const layer = createLayer(id, function (this: BaseLayer) { color: colorText, width: "160px" } - })) as GenericBuyable & { resource: Resource }; + })) as ElfBuyable & { resource: Resource }; const { max: maxSmelter, diff --git a/src/data/layers/paper.tsx b/src/data/layers/paper.tsx index b6e8ac7..22e1f40 100644 --- a/src/data/layers/paper.tsx +++ b/src/data/layers/paper.tsx @@ -23,7 +23,7 @@ import { render, renderCol, renderRow } from "util/vue"; import { computed, ComputedRef, ref, unref } from "vue"; import cloth from "./cloth"; import coal from "./coal"; -import elves from "./elves"; +import elves, { ElfBuyable } from "./elves"; import plastic from "./plastic"; import trees from "./trees"; import dyes from "./dyes"; @@ -131,6 +131,28 @@ const layer = createLayer(id, function (this: BaseLayer) { } return cost; }, + inverseCost(x: DecimalSource) { + if (bookUpgrade.bought.value) { + x = Decimal.div(x, 10); + } + if (management.elfTraining.paperElfTraining.milestones[0].earned.value) { + x = Decimal.div(x, sumBooks.value.max(1)); + } + + let scaling = 5; + if (management.elfTraining.paperElfTraining.milestones[0].earned.value) { + scaling--; + } + + let v = Decimal.div(x, 10).log(scaling); + + v = v.div(Decimal.pow(0.95, paperBook.totalAmount.value)); + if (Decimal.gte(v, 10000)) v = Decimal.mul(v, 10000).root(2); + if (Decimal.gte(v, 100)) v = Decimal.mul(v, 100).root(2); + if (options.elfName === "Star" || options.elfName === "Bell") v = Decimal.root(v, 2); + + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, style: "width: 600px", freeLevels: computed(() => management.elfTraining.paperElfTraining.milestones[4].earned.value @@ -138,7 +160,7 @@ const layer = createLayer(id, function (this: BaseLayer) { : 0 ), totalAmount: computed(() => Decimal.add(buyable.amount.value, buyable.freeLevels.value)) - })) as GenericBuyable & { + })) as ElfBuyable & { resource: Resource; freeLevels: ComputedRef; totalAmount: ComputedRef; diff --git a/src/data/layers/trees.tsx b/src/data/layers/trees.tsx index 4c932fd..1dab5fb 100644 --- a/src/data/layers/trees.tsx +++ b/src/data/layers/trees.tsx @@ -32,7 +32,7 @@ import boxes from "./boxes"; import cloth from "./cloth"; import coal from "./coal"; import dyes from "./dyes"; -import elves from "./elves"; +import elves, { ElfBuyable } from "./elves"; import management from "./management"; import paper from "./paper"; import workshop from "./workshop"; @@ -214,12 +214,21 @@ const layer = createLayer(id, function (this: BaseLayer) { v = Decimal.pow(0.95, paper.books.cuttersBook.totalAmount.value).times(v); return Decimal.times(100, v).add(200); }, + inverseCost(x: DecimalSource) { + let v = Decimal.sub(x, 200).div(100); + v = v.div(Decimal.pow(0.95, paper.books.cuttersBook.totalAmount.value)); + if (Decimal.gte(v, 2e30)) v = Decimal.mul(v, Decimal.pow(2e30, 9999)).root(10000); + if (Decimal.gte(v, 2e6)) v = Decimal.mul(v, 2e6).root(2); + if (Decimal.gte(v, 200)) v = Decimal.mul(v, 200).root(2); + if (Decimal.gte(v, 50)) v = Decimal.mul(v, 50).root(2); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, display: { title: "Generic Cutters", description: "Each cutter cuts down 1 tree/s" }, visibility: () => showIf(researchUpgrade2.bought.value) - })) as GenericBuyable & { display: { title: string }; resource: Resource }; + })) as ElfBuyable & { display: { title: string }; resource: Resource }; const autoPlantingBuyable1 = createBuyable(() => ({ resource: noPersist(logs), cost() { @@ -235,12 +244,24 @@ const layer = createLayer(id, function (this: BaseLayer) { } return cost; }, + inverseCost(x: DecimalSource) { + if (management.elfTraining.planterElfTraining.milestones[3].earned.value) { + x = Decimal.mul(x, 10); + } + let v = Decimal.sub(x, 200).div(100); + v = v.div(Decimal.pow(0.95, paper.books.plantersBook.totalAmount.value)); + if (Decimal.gte(v, 2e30)) v = Decimal.mul(v, Decimal.pow(2e30, 9999)).root(10000); + if (Decimal.gte(v, 2e6)) v = Decimal.mul(v, 2e6).root(2); + if (Decimal.gte(v, 200)) v = Decimal.mul(v, 200).root(2); + if (Decimal.gte(v, 50)) v = Decimal.mul(v, 50).root(2); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, display: { title: "Generic Planters", description: "Each planter plants 0.5 trees/s" }, visibility: () => showIf(researchUpgrade2.bought.value) - })) as GenericBuyable & { display: { title: string }; resource: Resource }; + })) as ElfBuyable & { display: { title: string }; resource: Resource }; const expandingForestBuyable = createBuyable(() => ({ resource: noPersist(logs), cost() { @@ -251,12 +272,20 @@ const layer = createLayer(id, function (this: BaseLayer) { v = Decimal.pow(0.95, paper.books.expandersBook.totalAmount.value).times(v); return Decimal.pow(Decimal.add(v, 1), 1.5).times(500); }, + inverseCost(x: DecimalSource) { + let v = Decimal.div(x, 500).root(1.5).sub(1); + v = v.div(Decimal.pow(0.95, paper.books.expandersBook.totalAmount.value)); + if (Decimal.gte(v, 1e15)) v = Decimal.mul(v, 1e135).root(10); + if (Decimal.gte(v, 1e5)) v = Decimal.mul(v, 1e5).root(2); + if (Decimal.gte(v, 100)) v = Decimal.mul(v, 100).root(2); + return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0); + }, display: { title: "Expand Forest", description: "Add 10 trees to the forest" }, visibility: () => showIf(researchUpgrade2.bought.value) - })) as GenericBuyable & { display: { title: string }; resource: Resource }; + })) as ElfBuyable & { display: { title: string }; resource: Resource }; const row1Buyables = [autoCuttingBuyable1, autoPlantingBuyable1, expandingForestBuyable]; const manualCuttingAmount = createSequentialModifier(() => [