(DISABLE AUTOSAVE BEFORE UPDATING) Rough max buy implementation

This commit is contained in:
ducdat0507 2022-12-14 19:55:32 +07:00
parent 8eac9490ee
commit 1ccdbeeadc
9 changed files with 377 additions and 64 deletions

View file

@ -27,6 +27,7 @@ import { WithRequired } from "util/common";
import { render, renderGrid, renderRow } from "util/vue"; import { render, renderGrid, renderRow } from "util/vue";
import { computed, ComputedRef, ref, unref } from "vue"; import { computed, ComputedRef, ref, unref } from "vue";
import dyes from "./dyes"; import dyes from "./dyes";
import { ElfBuyable } from "./elves";
import management from "./management"; import management from "./management";
import paper from "./paper"; import paper from "./paper";
import plastic from "./plastic"; import plastic from "./plastic";
@ -34,7 +35,7 @@ import trees from "./trees";
import workshop from "./workshop"; import workshop from "./workshop";
import wrappingPaper from "./wrapping-paper"; import wrappingPaper from "./wrapping-paper";
export type BoxesBuyable = GenericBuyable & { export type BoxesBuyable = ElfBuyable & {
resource: Resource; resource: Resource;
freeLevels: ComputedRef<DecimalSource>; freeLevels: ComputedRef<DecimalSource>;
totalAmount: ComputedRef<Decimal>; totalAmount: ComputedRef<Decimal>;
@ -231,6 +232,19 @@ const layer = createLayer(id, function (this: BaseLayer) {
.div(dyes.boosts.orange2.value) .div(dyes.boosts.orange2.value)
.div(wrappingPaper.boosts.ocean1.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), visibility: () => showIf(logsUpgrade.bought.value),
freeLevels: computed(() => freeLevels: computed(() =>
management.elfTraining.boxElfTraining.milestones[0].earned.value 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); 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), visibility: () => showIf(ashUpgrade.bought.value),
freeLevels: computed(() => freeLevels: computed(() =>
management.elfTraining.boxElfTraining.milestones[0].earned.value 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); 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), visibility: () => showIf(coalUpgrade.bought.value),
freeLevels: computed(() => freeLevels: computed(() =>
management.elfTraining.boxElfTraining.milestones[0].earned.value management.elfTraining.boxElfTraining.milestones[0].earned.value
@ -367,6 +405,19 @@ const layer = createLayer(id, function (this: BaseLayer) {
.div(dyes.boosts.orange2.value) .div(dyes.boosts.orange2.value)
.div(wrappingPaper.boosts.ocean1.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), visibility: () => showIf(management.elfTraining.boxElfTraining.milestones[3].earned.value),
freeLevels: computed(() => freeLevels: computed(() =>
management.elfTraining.boxElfTraining.milestones[0].earned.value 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); 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), visibility: () => showIf(management.elfTraining.boxElfTraining.milestones[3].earned.value),
freeLevels: computed(() => freeLevels: computed(() =>
management.elfTraining.boxElfTraining.milestones[0].earned.value 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); 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), visibility: () => showIf(management.elfTraining.boxElfTraining.milestones[3].earned.value),
freeLevels: computed(() => freeLevels: computed(() =>
management.elfTraining.boxElfTraining.milestones[0].earned.value management.elfTraining.boxElfTraining.milestones[0].earned.value

View file

@ -30,6 +30,7 @@ import { render, renderCol, renderRow } from "util/vue";
import { computed, ref } from "vue"; import { computed, ref } from "vue";
import boxes from "./boxes"; import boxes from "./boxes";
import dyes from "./dyes"; import dyes from "./dyes";
import { ElfBuyable } from "./elves";
import management from "./management"; import management from "./management";
import metal from "./metal"; import metal from "./metal";
import paper from "./paper"; 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); v = Decimal.pow(0.95, paper.books.clothBook.totalAmount.value).times(v);
return Decimal.pow(1.5, v).times(1e14); 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: { display: {
title: "Build more pens", title: "Build more pens",
description: "Breed +1 sheep at once" description: "Breed +1 sheep at once"
} }
})) as GenericBuyable & { resource: Resource }; })) as ElfBuyable & { resource: Resource };
const betterShears = createBuyable(() => ({ const betterShears = createBuyable(() => ({
resource: metal.metal, 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); v = Decimal.pow(0.95, paper.books.clothBook.totalAmount.value).times(v);
return Decimal.pow(1.4, v).times(10000); 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: { display: {
title: "Make stronger shears", title: "Make stronger shears",
description: "Shear +1 sheep at once" description: "Shear +1 sheep at once"
} }
})) as GenericBuyable & { resource: Resource }; })) as ElfBuyable & { resource: Resource };
const fasterSpinning = createBuyable(() => ({ const fasterSpinning = createBuyable(() => ({
resource: paper.paper, 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); v = Decimal.pow(0.95, paper.books.clothBook.totalAmount.value).times(v);
return Decimal.pow(1.3, v).times(1000000); 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: { display: {
title: "Learn how to spin", title: "Learn how to spin",
description: "Spin +1 wool at once" description: "Spin +1 wool at once"
} }
})) as GenericBuyable & { resource: Resource }; })) as ElfBuyable & { resource: Resource };
const treesUpgrade1 = createUpgrade(() => ({ const treesUpgrade1 = createUpgrade(() => ({
resource: noPersist(cloth), resource: noPersist(cloth),

View file

@ -33,7 +33,7 @@ import { render, renderGrid, renderRow } from "util/vue";
import { computed, ref, unref } from "vue"; import { computed, ref, unref } from "vue";
import boxes from "./boxes"; import boxes from "./boxes";
import cloth from "./cloth"; import cloth from "./cloth";
import elves from "./elves"; import elves, { ElfBuyable } from "./elves";
import metal from "./metal"; import metal from "./metal";
import oil from "./oil"; import oil from "./oil";
import paper from "./paper"; 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); v = Decimal.pow(0.95, paper.books.smallFireBook.totalAmount.value).times(v);
return v.pow(1.5).times(1e4); 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(() => ( display: jsx(() => (
<> <>
<h3>Small Fire</h3> <h3>Small Fire</h3>
@ -126,7 +134,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
color: colorText, color: colorText,
width: "160px" width: "160px"
} }
})) as GenericBuyable & { resource: Resource }; })) as ElfBuyable & { resource: Resource };
const { const {
min: minFire, min: minFire,
@ -160,6 +168,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
cost() { cost() {
return Decimal.pow(0.95, paper.books.bonfireBook.totalAmount.value).times(10); 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(() => ( display: jsx(() => (
<> <>
<h3>Bonfire</h3> <h3>Bonfire</h3>
@ -185,7 +196,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
width: "160px" width: "160px"
}, },
visibility: () => showIf(unlockBonfire.bought.value) visibility: () => showIf(unlockBonfire.bought.value)
})) as GenericBuyable & { resource: Resource }; })) as ElfBuyable & { resource: Resource };
const { const {
min: minBonfire, min: minBonfire,
max: maxBonfire, 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); v = Decimal.pow(0.95, paper.books.kilnBook.totalAmount.value).times(v);
return Decimal.pow(1.1, v).times(1e7); 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(() => ( display: jsx(() => (
<> <>
<h3>Charcoal Kiln</h3> <h3>Charcoal Kiln</h3>
@ -244,7 +262,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
width: "160px" width: "160px"
}, },
visibility: () => showIf(unlockKiln.bought.value) visibility: () => showIf(unlockKiln.bought.value)
})) as GenericBuyable & { resource: Resource }; })) as ElfBuyable & { resource: Resource };
const { const {
min: minKiln, min: minKiln,
max: maxKiln, max: maxKiln,
@ -281,6 +299,19 @@ const layer = createLayer(id, function (this: BaseLayer) {
} }
return cost; 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(() => ( display: jsx(() => (
<> <>
<h3>Coal Drill</h3> <h3>Coal Drill</h3>
@ -303,7 +334,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
width: "160px" width: "160px"
}, },
visibility: () => showIf(metal.coalDrill.bought.value) visibility: () => showIf(metal.coalDrill.bought.value)
})) as GenericBuyable & { resource: Resource }; })) as ElfBuyable & { resource: Resource };
const { const {
max: maxDrill, max: maxDrill,
min: minDrill, min: minDrill,
@ -470,6 +501,18 @@ const layer = createLayer(id, function (this: BaseLayer) {
v = v.div(wrappingPaper.boosts.rainbow1.value); v = v.div(wrappingPaper.boosts.rainbow1.value);
return Decimal.add(v, 1).pow(2.5).times(10); 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: { display: {
title: "Heated Cutters", title: "Heated Cutters",
description: "Even warmer cutters cut down trees faster", description: "Even warmer cutters cut down trees faster",
@ -479,7 +522,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
}, },
style: { color: colorText }, style: { color: colorText },
visibility: () => showIf(warmerCutters.bought.value) visibility: () => showIf(warmerCutters.bought.value)
})) as GenericBuyable & { display: { title: string }; resource: Resource }; })) as ElfBuyable & { display: { title: string }; resource: Resource };
const heatedPlanters = createBuyable(() => ({ const heatedPlanters = createBuyable(() => ({
resource: noPersist(coal), resource: noPersist(coal),
cost() { cost() {
@ -494,6 +537,18 @@ const layer = createLayer(id, function (this: BaseLayer) {
v = v.div(wrappingPaper.boosts.rainbow1.value); v = v.div(wrappingPaper.boosts.rainbow1.value);
return Decimal.add(v, 1).pow(2.5).times(10); 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: { display: {
title: "Heated Planters", title: "Heated Planters",
description: "Even warmer planters plant trees faster", description: "Even warmer planters plant trees faster",
@ -503,7 +558,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
}, },
style: { color: colorText }, style: { color: colorText },
visibility: () => showIf(warmerPlanters.bought.value) visibility: () => showIf(warmerPlanters.bought.value)
})) as GenericBuyable & { display: { title: string }; resource: Resource }; })) as ElfBuyable & { display: { title: string }; resource: Resource };
const moreFertilizer = createBuyable(() => ({ const moreFertilizer = createBuyable(() => ({
resource: noPersist(ash), resource: noPersist(ash),
cost() { cost() {
@ -518,6 +573,18 @@ const layer = createLayer(id, function (this: BaseLayer) {
v = v.div(wrappingPaper.boosts.rainbow1.value); v = v.div(wrappingPaper.boosts.rainbow1.value);
return Decimal.add(v, 1).pow(1.5).times(50000); 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: { display: {
title: "Fertilized Soil", title: "Fertilized Soil",
description: "More fertilizer helps trees grow bigger", description: "More fertilizer helps trees grow bigger",
@ -527,7 +594,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
}, },
style: { color: colorText }, style: { color: colorText },
visibility: () => showIf(basicFertilizer.bought.value) 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 row3buyables = [heatedCutters, heatedPlanters, moreFertilizer];
const heatedCutterEffect = createSequentialModifier(() => [ const heatedCutterEffect = createSequentialModifier(() => [

View file

@ -32,12 +32,13 @@ import trees from "./trees";
import wrappingPaper from "./wrapping-paper"; import wrappingPaper from "./wrapping-paper";
import paper from "./paper"; import paper from "./paper";
import boxes from "./boxes"; import boxes from "./boxes";
import { ElfBuyable } from "./elves";
interface Dye { interface Dye {
name: string; name: string;
amount: Resource<DecimalSource> & amount: Resource<DecimalSource> &
Persistent<DecimalSource> & { [NonPersistent]: Resource<DecimalSource> }; Persistent<DecimalSource> & { [NonPersistent]: Resource<DecimalSource> };
buyable: GenericBuyable; buyable: ElfBuyable;
toGenerate: WithRequired<Modifier, "description" | "revert">; toGenerate: WithRequired<Modifier, "description" | "revert">;
computedToGenerate: ComputedRef<DecimalSource>; computedToGenerate: ComputedRef<DecimalSource>;
display: JSXFunction; display: JSXFunction;
@ -184,7 +185,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
}) as WithRequired<Modifier, "description" | "revert">; }) as WithRequired<Modifier, "description" | "revert">;
const computedToGenerate = computed(() => toGenerate.apply(0)); const computedToGenerate = computed(() => toGenerate.apply(0));
const buyable: GenericBuyable = createBuyable(() => { const buyable: ElfBuyable = createBuyable(() => {
const costs = convertComputable(options.costs); const costs = convertComputable(options.costs);
return { return {
...options, ...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)); v = Decimal.mul(v, Decimal.pow(0.95, paper.books.dyeBook.totalAmount.value));
return Decimal.div(v, 10).plus(1); 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) => { canPurchase: computed((cost?: DecimalSource) => {
if (unref(buyable.visibility) != Visibility.Visible) return false; if (unref(buyable.visibility) != Visibility.Visible) return false;
const trueCost = cost ?? unref(buyable.cost) ?? Decimal.dInf; const trueCost = cost ?? unref(buyable.cost) ?? Decimal.dInf;

View file

@ -38,8 +38,14 @@ import workshop from "./workshop";
import wrappingPaper from "./wrapping-paper"; import wrappingPaper from "./wrapping-paper";
import dyes from "./dyes"; 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 id = "elves";
const day = 4; const day = 4;
const layer = createLayer(id, function (this: BaseLayer) { const layer = createLayer(id, function (this: BaseLayer) {
const name = "Elves"; const name = "Elves";
const colorBright = "red"; const colorBright = "red";
@ -542,13 +548,12 @@ const layer = createLayer(id, function (this: BaseLayer) {
name: string; name: string;
description: string; description: string;
buyable: buyable:
| (GenericBuyable & { resource?: Resource }) | (ElfBuyable & { resource?: Resource })
| (GenericBuyable & { resource?: Resource })[]; | (ElfBuyable & { resource?: Resource })[];
cooldownModifier: Modifier; cooldownModifier: Modifier;
customCost?: (amount: DecimalSource) => DecimalSource;
hasToggle?: boolean; hasToggle?: boolean;
toggleDesc?: string; 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 onPurchase?: VoidFunction; // Will get overriden by the custom onpurchase, but that's fine
canBuy?: Computable<boolean>; canBuy?: Computable<boolean>;
buyMax?: Computable<boolean>; buyMax?: Computable<boolean>;
@ -566,27 +571,29 @@ const layer = createLayer(id, function (this: BaseLayer) {
function update(diff: number) { function update(diff: number) {
if (upgrade.bought.value && unref(isActive)) { if (upgrade.bought.value && unref(isActive)) {
buyProgress.value = Decimal.add(buyProgress.value, diff); buyProgress.value = Decimal.add(buyProgress.value, diff);
const cooldown = Decimal.recip(computedAutoBuyCooldown.value); const cooldown = Decimal.recip(computedAutoBuyCooldown.value);
amountOfTimesDone.value += diff / cooldown.toNumber(); 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( (isArray(options.buyable) ? options.buyable : [options.buyable]).forEach(
buyable => { buyable => {
while (buyMax ? true : Decimal.gte(buyProgress.value, cooldown)) { const buyAmount = Decimal.min(
if ( Decimal.sub(buyable.inverseCost(buyable.resource?.value), buyable.amount.value),
options.customCost && buyable.resource maxBuyAmount
? Decimal.gte( );
buyable.resource.value,
options.customCost(buyable.amount.value) if (buyAmount.lte(0)) return;
)
: unref(buyable.canPurchase) buyable.amount.value = Decimal.add(buyable.amount.value, buyAmount);
) { maxBuyAmount = Decimal.sub(maxBuyAmount, buyAmount);
buyable.amount.value = Decimal.add(buyable.amount.value, 1); options.onAutoPurchase?.(buyable, buyAmount);
buyProgress.value = Decimal.sub(buyProgress.value, cooldown);
options.onAutoPurchase?.(buyable); if (maxBuyAmount.lte(0)) return;
} else {
buyProgress.value = cooldown;
break;
}
}
} }
); );
} }
@ -723,8 +730,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
visibility: () => showIf(boxes.upgrades.ashUpgrade.bought.value), visibility: () => showIf(boxes.upgrades.ashUpgrade.bought.value),
hasToggle: true, hasToggle: true,
toggleDesc: "Activate auto-purchased bonfires", toggleDesc: "Activate auto-purchased bonfires",
onAutoPurchase() { onAutoPurchase(buyable, amount) {
const spent = unref((this.buyable as GenericBuyable).cost!); const spent = Decimal.mul(unref(buyable.cost ?? 0), amount);
coal.activeFires.value = Decimal.sub(coal.activeFires.value, spent).max(0); coal.activeFires.value = Decimal.sub(coal.activeFires.value, spent).max(0);
coal.buildFire.amount.value = Decimal.sub(coal.buildFire.amount.value, spent).max(0); coal.buildFire.amount.value = Decimal.sub(coal.buildFire.amount.value, spent).max(0);
if (bonfireElf.toggle.value) { if (bonfireElf.toggle.value) {
@ -745,9 +752,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
visibility: () => showIf(boxes.upgrades.coalUpgrade.bought.value), visibility: () => showIf(boxes.upgrades.coalUpgrade.bought.value),
hasToggle: true, hasToggle: true,
toggleDesc: "Activate auto-purchased kilns", toggleDesc: "Activate auto-purchased kilns",
onAutoPurchase() { onAutoPurchase(_, amount) {
if (kilnElf.toggle.value) { if (kilnElf.toggle.value) {
coal.activeKilns.value = Decimal.add(coal.activeKilns.value, 1); coal.activeKilns.value = Decimal.add(coal.activeKilns.value, amount);
} }
}, },
onPurchase() { onPurchase() {
@ -791,9 +798,9 @@ const layer = createLayer(id, function (this: BaseLayer) {
showIf(management.elfTraining.expandersElfTraining.milestones[3].earned.value), showIf(management.elfTraining.expandersElfTraining.milestones[3].earned.value),
hasToggle: true, hasToggle: true,
toggleDesc: "Activate auto-purchased coal drills", toggleDesc: "Activate auto-purchased coal drills",
onAutoPurchase() { onAutoPurchase(_, amount) {
if (coalDrillElf.toggle.value) { 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), showIf(management.elfTraining.fertilizerElfTraining.milestones[4].earned.value),
hasToggle: true, hasToggle: true,
toggleDesc: "Activate auto-purchased oil drills", toggleDesc: "Activate auto-purchased oil drills",
onAutoPurchase(buyable) { onAutoPurchase(buyable, amount) {
if (heavyDrillElf.toggle.value) { if (heavyDrillElf.toggle.value) {
if (buyable === oil.buildHeavy) { 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) { } 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) { } 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), showIf(management.elfTraining.heatedCutterElfTraining.milestones[4].earned.value),
hasToggle: true, hasToggle: true,
toggleDesc: "Activate auto-purchased oil-using machines", toggleDesc: "Activate auto-purchased oil-using machines",
onAutoPurchase(buyable) { onAutoPurchase(buyable, amount) {
if (heavyDrillElf.toggle.value) { if (heavyDrillElf.toggle.value) {
if (buyable === oil.buildPump) { 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) { } 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) { } else if (buyable === oil.buildSmelter) {
oil.activeSmelter.value = Decimal.add(oil.activeSmelter.value, 1); oil.activeSmelter.value = Decimal.add(oil.activeSmelter.value, amount);
} }
} }
} }

View file

@ -34,6 +34,7 @@ import dyes from "./dyes";
import management from "./management"; import management from "./management";
import workshop from "./workshop"; import workshop from "./workshop";
import paper from "./paper"; import paper from "./paper";
import { ElfBuyable } from "./elves";
const id = "metal"; const id = "metal";
const day = 7; const day = 7;
@ -415,6 +416,17 @@ const layer = createLayer(id, function (this: BaseLayer) {
} }
return cost; 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: { display: {
title: "Metal Drill", title: "Metal Drill",
description: "An automated machine to help you mine more ore, faster", description: "An automated machine to help you mine more ore, faster",
@ -433,7 +445,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
.gte(10) .gte(10)
), ),
style: { width: "200px" } style: { width: "200px" }
})) as GenericBuyable & { resource: Resource }; })) as ElfBuyable & { resource: Resource };
const industrialCrucible = createBuyable(() => ({ const industrialCrucible = createBuyable(() => ({
resource: noPersist(metal), resource: noPersist(metal),
cost() { cost() {
@ -448,6 +460,17 @@ const layer = createLayer(id, function (this: BaseLayer) {
} }
return cost; 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: { display: {
title: "Industrial Crucible", title: "Industrial Crucible",
description: "A giant automated crucible furnace, letting you smelt ore faster", 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) Decimal.gte(bestOre.value, 50)
), ),
style: { width: "200px" } style: { width: "200px" }
})) as GenericBuyable & { resource: Resource }; })) as ElfBuyable & { resource: Resource };
const autoSmeltEnabled = persistent<boolean>(true); const autoSmeltEnabled = persistent<boolean>(true);
const hotterForge = createBuyable(() => ({ const hotterForge = createBuyable(() => ({
resource: coal.coal, resource: coal.coal,
@ -481,6 +504,17 @@ const layer = createLayer(id, function (this: BaseLayer) {
} }
return cost; 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: { display: {
title: "Hotter Forges", title: "Hotter Forges",
description: description:
@ -495,7 +529,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
visibility: () => visibility: () =>
showIf(Decimal.gte(hotterForge.amount.value, 1) || industrialFurnace.bought.value), showIf(Decimal.gte(hotterForge.amount.value, 1) || industrialFurnace.bought.value),
style: { width: "200px" } style: { width: "200px" }
})) as GenericBuyable & { resource: Resource }; })) as ElfBuyable & { resource: Resource };
const hotterForgeEffect = computed(() => Decimal.times(hotterForge.amount.value, 0.25)); const hotterForgeEffect = computed(() => Decimal.times(hotterForge.amount.value, 0.25));
globalBus.on("update", diff => { globalBus.on("update", diff => {

View file

@ -39,6 +39,7 @@ import dyes from "./dyes";
import management from "./management"; import management from "./management";
import workshop from "./workshop"; import workshop from "./workshop";
import { WithRequired } from "util/common"; import { WithRequired } from "util/common";
import { ElfBuyable } from "./elves";
const id = "oil"; const id = "oil";
const day = 9; 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); v = Decimal.pow(0.95, paper.books.heavyDrillBook.totalAmount.value).times(v);
return Decimal.pow(1.3, v).times(2.5e4); 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(() => ( display: jsx(() => (
<> <>
<h3>Heavy Drill</h3> <h3>Heavy Drill</h3>
@ -134,7 +141,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
color: colorText, color: colorText,
width: "160px" width: "160px"
} }
})) as GenericBuyable & { resource: Resource }; })) as ElfBuyable & { resource: Resource };
const { const {
min: minHeavy, min: minHeavy,
max: maxHeavy, 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); v = Decimal.pow(0.95, paper.books.heavyDrillBook.totalAmount.value).times(v);
return Decimal.pow(2, v).times(1e5); 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(() => ( display: jsx(() => (
<> <>
<h3>Heavy Drill Drill</h3> <h3>Heavy Drill Drill</h3>
@ -195,7 +208,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
color: colorText, color: colorText,
width: "160px" width: "160px"
} }
})) as GenericBuyable & { resource: Resource }; })) as ElfBuyable & { resource: Resource };
const { const {
min: minHeavy2, min: minHeavy2,
max: maxHeavy2, 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); v = Decimal.pow(0.95, paper.books.heavyDrillBook.totalAmount.value).times(v);
return Decimal.pow(8, v).times(2e5); 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(() => ( display: jsx(() => (
<> <>
<h3>Heavy Extractor</h3> <h3>Heavy Extractor</h3>
@ -244,7 +263,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
color: colorText, color: colorText,
width: "160px" width: "160px"
} }
})) as GenericBuyable & { resource: Resource }; })) as ElfBuyable & { resource: Resource };
const { const {
min: minExtractor, min: minExtractor,
max: maxExtractor, max: maxExtractor,
@ -288,6 +307,18 @@ const layer = createLayer(id, function (this: BaseLayer) {
} }
return price; 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(() => ( display: jsx(() => (
<> <>
<h3>Oil Pump</h3> <h3>Oil Pump</h3>
@ -313,7 +344,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
color: colorText, color: colorText,
width: "160px" width: "160px"
} }
})) as GenericBuyable & { resource: Resource }; })) as ElfBuyable & { resource: Resource };
const { const {
max: maxPump, max: maxPump,
min: minPump, 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); v = Decimal.pow(0.95, paper.books.oilBook.totalAmount.value).times(v);
return Decimal.pow(2, v).times(50); 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(() => ( display: jsx(() => (
<> <>
<h3>Oil Burner</h3> <h3>Oil Burner</h3>
@ -375,7 +412,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
color: colorText, color: colorText,
width: "160px" width: "160px"
} }
})) as GenericBuyable & { resource: Resource }; })) as ElfBuyable & { resource: Resource };
const { const {
max: maxBurner, max: maxBurner,
min: minBurner, min: minBurner,
@ -402,6 +439,15 @@ const layer = createLayer(id, function (this: BaseLayer) {
price = price.div(Decimal.add(totalOil.value, 1).root(6)); price = price.div(Decimal.add(totalOil.value, 1).root(6));
return price; 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(() => ( display: jsx(() => (
<> <>
<h3>Oil Smelter</h3> <h3>Oil Smelter</h3>
@ -426,7 +472,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
color: colorText, color: colorText,
width: "160px" width: "160px"
} }
})) as GenericBuyable & { resource: Resource }; })) as ElfBuyable & { resource: Resource };
const { const {
max: maxSmelter, max: maxSmelter,

View file

@ -23,7 +23,7 @@ import { render, renderCol, renderRow } from "util/vue";
import { computed, ComputedRef, ref, unref } from "vue"; import { computed, ComputedRef, ref, unref } from "vue";
import cloth from "./cloth"; import cloth from "./cloth";
import coal from "./coal"; import coal from "./coal";
import elves from "./elves"; import elves, { ElfBuyable } from "./elves";
import plastic from "./plastic"; import plastic from "./plastic";
import trees from "./trees"; import trees from "./trees";
import dyes from "./dyes"; import dyes from "./dyes";
@ -131,6 +131,28 @@ const layer = createLayer(id, function (this: BaseLayer) {
} }
return cost; 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", style: "width: 600px",
freeLevels: computed(() => freeLevels: computed(() =>
management.elfTraining.paperElfTraining.milestones[4].earned.value management.elfTraining.paperElfTraining.milestones[4].earned.value
@ -138,7 +160,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
: 0 : 0
), ),
totalAmount: computed(() => Decimal.add(buyable.amount.value, buyable.freeLevels.value)) totalAmount: computed(() => Decimal.add(buyable.amount.value, buyable.freeLevels.value))
})) as GenericBuyable & { })) as ElfBuyable & {
resource: Resource; resource: Resource;
freeLevels: ComputedRef<DecimalSource>; freeLevels: ComputedRef<DecimalSource>;
totalAmount: ComputedRef<DecimalSource>; totalAmount: ComputedRef<DecimalSource>;

View file

@ -32,7 +32,7 @@ import boxes from "./boxes";
import cloth from "./cloth"; import cloth from "./cloth";
import coal from "./coal"; import coal from "./coal";
import dyes from "./dyes"; import dyes from "./dyes";
import elves from "./elves"; import elves, { ElfBuyable } from "./elves";
import management from "./management"; import management from "./management";
import paper from "./paper"; import paper from "./paper";
import workshop from "./workshop"; 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); v = Decimal.pow(0.95, paper.books.cuttersBook.totalAmount.value).times(v);
return Decimal.times(100, v).add(200); 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: { display: {
title: "Generic Cutters", title: "Generic Cutters",
description: "Each cutter cuts down 1 tree/s" description: "Each cutter cuts down 1 tree/s"
}, },
visibility: () => showIf(researchUpgrade2.bought.value) visibility: () => showIf(researchUpgrade2.bought.value)
})) as GenericBuyable & { display: { title: string }; resource: Resource }; })) as ElfBuyable & { display: { title: string }; resource: Resource };
const autoPlantingBuyable1 = createBuyable(() => ({ const autoPlantingBuyable1 = createBuyable(() => ({
resource: noPersist(logs), resource: noPersist(logs),
cost() { cost() {
@ -235,12 +244,24 @@ const layer = createLayer(id, function (this: BaseLayer) {
} }
return cost; 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: { display: {
title: "Generic Planters", title: "Generic Planters",
description: "Each planter plants 0.5 trees/s" description: "Each planter plants 0.5 trees/s"
}, },
visibility: () => showIf(researchUpgrade2.bought.value) visibility: () => showIf(researchUpgrade2.bought.value)
})) as GenericBuyable & { display: { title: string }; resource: Resource }; })) as ElfBuyable & { display: { title: string }; resource: Resource };
const expandingForestBuyable = createBuyable(() => ({ const expandingForestBuyable = createBuyable(() => ({
resource: noPersist(logs), resource: noPersist(logs),
cost() { cost() {
@ -251,12 +272,20 @@ const layer = createLayer(id, function (this: BaseLayer) {
v = Decimal.pow(0.95, paper.books.expandersBook.totalAmount.value).times(v); v = Decimal.pow(0.95, paper.books.expandersBook.totalAmount.value).times(v);
return Decimal.pow(Decimal.add(v, 1), 1.5).times(500); 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: { display: {
title: "Expand Forest", title: "Expand Forest",
description: "Add 10 trees to the forest" description: "Add 10 trees to the forest"
}, },
visibility: () => showIf(researchUpgrade2.bought.value) 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 row1Buyables = [autoCuttingBuyable1, autoPlantingBuyable1, expandingForestBuyable];
const manualCuttingAmount = createSequentialModifier(() => [ const manualCuttingAmount = createSequentialModifier(() => [