Apply requirement system to advent incremental

This commit is contained in:
thepaperpilot 2023-01-01 18:24:24 -06:00
parent 6efda5ddce
commit 652d720b5f
19 changed files with 1732 additions and 1556 deletions

View file

@ -37,6 +37,7 @@ import trees from "./trees";
import workshop from "./workshop";
import wrappingPaper from "./wrapping-paper";
import packing from "./packing";
import { createCostRequirement } from "game/requirements";
export type BoxesBuyable = ElfBuyable & {
resource: Resource;
@ -68,8 +69,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
exponent: 1.1,
description: "Bell Level 2",
enabled: management.elfTraining.boxElfTraining.milestones[1].earned
})),
}))
]) as WithRequired<Modifier, "description" | "revert">;
const boxesConversion = createCumulativeConversion(() => ({
@ -123,8 +123,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
main.days[3].recentlyUpdated.value = true;
},
resource: noPersist(boxes),
cost: 100
requirements: createCostRequirement(() => ({
resource: noPersist(boxes),
cost: 100
}))
}));
const ashUpgrade = createUpgrade(() => ({
display: {
@ -137,8 +139,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
main.days[3].recentlyUpdated.value = true;
},
resource: noPersist(boxes),
cost: 1000
requirements: createCostRequirement(() => ({
resource: noPersist(boxes),
cost: 1000
}))
}));
const coalUpgrade = createUpgrade(() => ({
display: {
@ -151,14 +155,18 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
main.days[3].recentlyUpdated.value = true;
},
resource: noPersist(boxes),
cost: 4000
requirements: createCostRequirement(() => ({
resource: noPersist(boxes),
cost: 4000
}))
}));
const upgrades = { logsUpgrade, ashUpgrade, coalUpgrade };
const oreUpgrade = createUpgrade(() => ({
resource: noPersist(boxes),
cost: 1e8,
requirements: createCostRequirement(() => ({
resource: noPersist(boxes),
cost: 1e8
})),
visibility: () => showIf(plastic.upgrades.boxTools.bought.value),
display: {
title: "Carry ore in boxes",
@ -166,8 +174,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const metalUpgrade = createUpgrade(() => ({
resource: noPersist(boxes),
cost: 1e9,
requirements: createCostRequirement(() => ({
resource: noPersist(boxes),
cost: 1e9
})),
visibility: () => showIf(plastic.upgrades.boxTools.bought.value),
display: {
title: "Carry metal in boxes",
@ -175,8 +185,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const plasticUpgrade = createUpgrade(() => ({
resource: noPersist(boxes),
cost: 1e10,
requirements: createCostRequirement(() => ({
resource: noPersist(boxes),
cost: 1e10
})),
visibility: () => showIf(plastic.upgrades.boxTools.bought.value),
display: {
title: "Carry plastic in boxes",
@ -185,8 +197,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}));
const row2Upgrades = { oreUpgrade, metalUpgrade, plasticUpgrade };
const clothUpgrade = createUpgrade(() => ({
resource: noPersist(boxes),
cost: 1e28,
requirements: createCostRequirement(() => ({
resource: noPersist(boxes),
cost: 1e28
})),
visibility: () => showIf(management.elfTraining.boxElfTraining.milestones[4].earned.value),
display: {
title: "Carry cloth in boxes",
@ -194,8 +208,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
})) as GenericUpgrade;
const dyeUpgrade = createUpgrade(() => ({
resource: noPersist(boxes),
cost: 1e29,
requirements: createCostRequirement(() => ({
resource: noPersist(boxes),
cost: 1e29
})),
visibility: () => showIf(management.elfTraining.boxElfTraining.milestones[4].earned.value),
display: {
title: "Carry dye in boxes",
@ -203,8 +219,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
})) as GenericUpgrade;
const xpUpgrade = createUpgrade(() => ({
resource: noPersist(boxes),
cost: 1e30,
requirements: createCostRequirement(() => ({
resource: noPersist(boxes),
cost: 1e30
})),
visibility: () => showIf(management.elfTraining.boxElfTraining.milestones[4].earned.value),
display: {
title: "Carry experience in boxes???",
@ -233,19 +251,21 @@ const layer = createLayer(id, function (this: BaseLayer) {
)),
showAmount: false
},
resource: noPersist(boxes),
cost() {
let v = this.amount.value;
v = Decimal.pow(0.95, paper.books.boxBook.totalAmount.value).times(v);
let scaling = 3;
if (management.elfTraining.boxElfTraining.milestones[2].earned.value) {
scaling--;
requirements: createCostRequirement(() => ({
resource: noPersist(boxes),
cost() {
let v = logBoxesBuyable.amount.value;
v = Decimal.pow(0.95, paper.books.boxBook.totalAmount.value).times(v);
let scaling = 3;
if (management.elfTraining.boxElfTraining.milestones[2].earned.value) {
scaling--;
}
return Decimal.pow(scaling, v)
.times(100)
.div(dyes.boosts.orange2.value)
.div(wrappingPaper.boosts.ocean1.value);
}
return Decimal.pow(scaling, v)
.times(100)
.div(dyes.boosts.orange2.value)
.div(wrappingPaper.boosts.ocean1.value);
},
})),
inverseCost(x: DecimalSource) {
let scaling = 3;
if (management.elfTraining.boxElfTraining.milestones[2].earned.value) {
@ -301,16 +321,18 @@ const layer = createLayer(id, function (this: BaseLayer) {
)),
showAmount: false
},
resource: noPersist(boxes),
cost() {
let v = this.amount.value;
v = Decimal.pow(0.95, paper.books.boxBook.totalAmount.value).times(v);
let scaling = 5;
if (management.elfTraining.boxElfTraining.milestones[2].earned.value) {
scaling--;
requirements: createCostRequirement(() => ({
resource: noPersist(boxes),
cost() {
let v = ashBoxesBuyable.amount.value;
v = Decimal.pow(0.95, paper.books.boxBook.totalAmount.value).times(v);
let scaling = 5;
if (management.elfTraining.boxElfTraining.milestones[2].earned.value) {
scaling--;
}
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) {
@ -363,16 +385,18 @@ const layer = createLayer(id, function (this: BaseLayer) {
)),
showAmount: false
},
resource: noPersist(boxes),
cost() {
let v = this.amount.value;
v = Decimal.pow(0.95, paper.books.boxBook.totalAmount.value).times(v);
let scaling = 7;
if (management.elfTraining.boxElfTraining.milestones[2].earned.value) {
scaling--;
requirements: createCostRequirement(() => ({
resource: noPersist(boxes),
cost() {
let v = coalBoxesBuyable.amount.value;
v = Decimal.pow(0.95, paper.books.boxBook.totalAmount.value).times(v);
let scaling = 7;
if (management.elfTraining.boxElfTraining.milestones[2].earned.value) {
scaling--;
}
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) {
@ -426,19 +450,21 @@ const layer = createLayer(id, function (this: BaseLayer) {
)),
showAmount: false
},
resource: noPersist(boxes),
cost() {
let v = this.amount.value;
v = Decimal.pow(0.95, paper.books.boxBook.totalAmount.value).times(v);
let scaling = 10;
if (management.elfTraining.boxElfTraining.milestones[2].earned.value) {
scaling--;
requirements: createCostRequirement(() => ({
resource: noPersist(boxes),
cost() {
let v = oreBoxesBuyable.amount.value;
v = Decimal.pow(0.95, paper.books.boxBook.totalAmount.value).times(v);
let scaling = 10;
if (management.elfTraining.boxElfTraining.milestones[2].earned.value) {
scaling--;
}
return Decimal.pow(scaling, v)
.times(1e25)
.div(dyes.boosts.orange2.value)
.div(wrappingPaper.boosts.ocean1.value);
}
return Decimal.pow(scaling, v)
.times(1e25)
.div(dyes.boosts.orange2.value)
.div(wrappingPaper.boosts.ocean1.value);
},
})),
inverseCost(x: DecimalSource) {
let scaling = 10;
if (management.elfTraining.boxElfTraining.milestones[2].earned.value) {
@ -494,16 +520,18 @@ const layer = createLayer(id, function (this: BaseLayer) {
)),
showAmount: false
},
resource: noPersist(boxes),
cost() {
let v = this.amount.value;
v = Decimal.pow(0.95, paper.books.boxBook.totalAmount.value).times(v);
let scaling = 15;
if (management.elfTraining.boxElfTraining.milestones[2].earned.value) {
scaling--;
requirements: createCostRequirement(() => ({
resource: noPersist(boxes),
cost() {
let v = metalBoxesBuyable.amount.value;
v = Decimal.pow(0.95, paper.books.boxBook.totalAmount.value).times(v);
let scaling = 15;
if (management.elfTraining.boxElfTraining.milestones[2].earned.value) {
scaling--;
}
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) {
@ -556,16 +584,18 @@ const layer = createLayer(id, function (this: BaseLayer) {
)),
showAmount: false
},
resource: noPersist(boxes),
cost() {
let v = this.amount.value;
v = Decimal.pow(0.95, paper.books.boxBook.totalAmount.value).times(v);
let scaling = 20;
if (management.elfTraining.boxElfTraining.milestones[2].earned.value) {
scaling--;
requirements: createCostRequirement(() => ({
resource: noPersist(boxes),
cost() {
let v = plasticBoxesBuyable.amount.value;
v = Decimal.pow(0.95, paper.books.boxBook.totalAmount.value).times(v);
let scaling = 20;
if (management.elfTraining.boxElfTraining.milestones[2].earned.value) {
scaling--;
}
return Decimal.pow(scaling, v).times(1e31).div(dyes.boosts.orange2.value);
}
return Decimal.pow(scaling, v).times(1e31).div(dyes.boosts.orange2.value);
},
})),
inverseCost(x: DecimalSource) {
let scaling = 20;
if (management.elfTraining.boxElfTraining.milestones[2].earned.value) {
@ -613,10 +643,12 @@ const layer = createLayer(id, function (this: BaseLayer) {
)),
showAmount: false
},
resource: noPersist(boxes),
cost() {
return Decimal.pow(2, presentBuyable.amount.value).mul(1e87);
},
requirements: createCostRequirement(() => ({
resource: noPersist(boxes),
cost() {
return Decimal.pow(2, presentBuyable.amount.value).mul(1e87);
}
})),
inverseCost(x: DecimalSource) {
const amt = Decimal.div(x, 1e87).log2();
return Decimal.isNaN(amt) ? Decimal.dZero : amt.floor().max(0);

View file

@ -42,7 +42,8 @@ import reindeer from "./reindeer";
import routing from "./routing";
import trees from "./trees";
import workshop from "./workshop";
import packing from "./packing"
import packing from "./packing";
import { createCostRequirement } from "game/requirements";
const id = "cloth";
const day = 8;
@ -240,13 +241,16 @@ const layer = createLayer(id, function (this: BaseLayer) {
}));
const buildPens = createBuyable(() => ({
requirements: createCostRequirement(() => ({
resource: trees.logs,
cost() {
let v = buildPens.amount.value;
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 2).div(100);
v = Decimal.pow(0.95, paper.books.clothBook.totalAmount.value).times(v);
return Decimal.pow(1.5, v).times(1e14);
}
})),
resource: trees.logs,
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.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));
@ -257,16 +261,19 @@ const layer = createLayer(id, function (this: BaseLayer) {
title: "Build more pens",
description: "Breed +1 sheep at once"
}
})) as ElfBuyable & { resource: Resource };
})) as ElfBuyable;
const betterShears = createBuyable(() => ({
requirements: createCostRequirement(() => ({
resource: metal.metal,
cost() {
let v = betterShears.amount.value;
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 2).div(100);
v = Decimal.pow(0.95, paper.books.clothBook.totalAmount.value).times(v);
return Decimal.pow(1.4, v).times(10000);
}
})),
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.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));
@ -277,16 +284,19 @@ const layer = createLayer(id, function (this: BaseLayer) {
title: "Make stronger shears",
description: "Shear +1 sheep at once"
}
})) as ElfBuyable & { resource: Resource };
})) as ElfBuyable;
const fasterSpinning = createBuyable(() => ({
requirements: createCostRequirement(() => ({
resource: paper.paper,
cost() {
let v = fasterSpinning.amount.value;
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 2).div(100);
v = Decimal.pow(0.95, paper.books.clothBook.totalAmount.value).times(v);
return Decimal.pow(1.3, v).times(1000000);
}
})),
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.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));
@ -297,19 +307,23 @@ const layer = createLayer(id, function (this: BaseLayer) {
title: "Learn how to spin",
description: "Spin +1 wool at once"
}
})) as ElfBuyable & { resource: Resource };
})) as ElfBuyable;
const treesUpgrade1 = createUpgrade(() => ({
resource: noPersist(cloth),
cost: 100,
requirements: createCostRequirement(() => ({
resource: noPersist(cloth),
cost: 100
})),
display: {
title: "Lumberjack Boots",
description: "Quadruple log gain"
}
}));
const treesUpgrade2 = createUpgrade(() => ({
resource: noPersist(wool),
cost: 150,
requirements: createCostRequirement(() => ({
resource: noPersist(wool),
cost: 150
})),
visibility: () => showIf(treesUpgrade1.bought.value),
display: {
title: "Lumberjack Jeans",
@ -317,8 +331,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const treesUpgrade3 = createUpgrade(() => ({
resource: noPersist(sheep),
cost: 200,
requirements: createCostRequirement(() => ({
resource: noPersist(sheep),
cost: 200
})),
visibility: () => showIf(treesUpgrade2.bought.value),
display: {
title: "Lumberjack Plaid",
@ -326,8 +342,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const treesUpgrade4 = createUpgrade(() => ({
resource: noPersist(cloth),
cost: 1e3,
requirements: createCostRequirement(() => ({
resource: noPersist(cloth),
cost: 1e3
})),
visibility: () => showIf(plastic.upgrades.clothTools.bought.value),
display: {
title: "Felt-Gripped Axe",
@ -337,16 +355,20 @@ const layer = createLayer(id, function (this: BaseLayer) {
const treesUpgrades = { treesUpgrade4, treesUpgrade3, treesUpgrade2, treesUpgrade1 };
const metalUpgrade1 = createUpgrade(() => ({
resource: noPersist(cloth),
cost: 150,
requirements: createCostRequirement(() => ({
resource: noPersist(cloth),
cost: 150
})),
display: {
title: "Mining boots",
description: "Quadruple ash gain"
}
}));
const metalUpgrade2 = createUpgrade(() => ({
resource: noPersist(wool),
cost: 225,
requirements: createCostRequirement(() => ({
resource: noPersist(wool),
cost: 225
})),
visibility: () => showIf(metalUpgrade1.bought.value),
display: {
title: "Mining overalls",
@ -354,8 +376,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const metalUpgrade3 = createUpgrade(() => ({
resource: noPersist(sheep),
cost: 300,
requirements: createCostRequirement(() => ({
resource: noPersist(sheep),
cost: 300
})),
visibility: () => showIf(metalUpgrade2.bought.value),
display: {
title: "Mining helmet",
@ -363,8 +387,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const metalUpgrade4 = createUpgrade(() => ({
resource: noPersist(cloth),
cost: 2e3,
requirements: createCostRequirement(() => ({
resource: noPersist(cloth),
cost: 2e3
})),
visibility: () => showIf(plastic.upgrades.clothTools.bought.value),
display: {
title: "Felt-Gripped Pick",
@ -374,16 +400,20 @@ const layer = createLayer(id, function (this: BaseLayer) {
const metalUpgrades = { metalUpgrade4, metalUpgrade3, metalUpgrade2, metalUpgrade1 };
const paperUpgrade1 = createUpgrade(() => ({
resource: noPersist(cloth),
cost: 200,
requirements: createCostRequirement(() => ({
resource: noPersist(cloth),
cost: 200
})),
display: {
title: "Scholar's shoes",
description: "Double paper gain"
}
}));
const paperUpgrade2 = createUpgrade(() => ({
resource: noPersist(wool),
cost: 200,
requirements: createCostRequirement(() => ({
resource: noPersist(wool),
cost: 200
})),
visibility: () => showIf(paperUpgrade1.bought.value),
display: {
title: "Scholar's slacks",
@ -391,8 +421,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const paperUpgrade3 = createUpgrade(() => ({
resource: noPersist(sheep),
cost: 400,
requirements: createCostRequirement(() => ({
resource: noPersist(sheep),
cost: 400
})),
visibility: () => showIf(paperUpgrade2.bought.value),
display: {
title: "Scholar's jacket",
@ -400,8 +432,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const paperUpgrade4 = createUpgrade(() => ({
resource: noPersist(cloth),
cost: 4e3,
requirements: createCostRequirement(() => ({
resource: noPersist(cloth),
cost: 4e3
})),
visibility: () => showIf(plastic.upgrades.clothTools.bought.value),
display: {
title: "Felt Elbow Pads",

View file

@ -13,10 +13,10 @@ import {
} from "data/common";
import { main } from "data/projEntry";
import { createBuyable } from "features/buyable";
import { jsx, JSXFunction, showIf, StyleValue, Visibility } from "features/feature";
import { jsx, showIf } 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 { createUpgrade } from "features/upgrades/upgrade";
import { globalBus } from "game/events";
import { BaseLayer, createLayer } from "game/layers";
import {
@ -27,9 +27,9 @@ import {
Modifier
} from "game/modifiers";
import { noPersist, persistent } from "game/persistence";
import { createCostRequirement } from "game/requirements";
import Decimal, { DecimalSource, format, formatWhole } from "util/bignum";
import { WithRequired } from "util/common";
import { Computable } from "util/computed";
import { render, renderGrid, renderRow } from "util/vue";
import { computed, ref, unref } from "vue";
import boxes from "./boxes";
@ -39,40 +39,12 @@ import elves, { ElfBuyable } from "./elves";
import management from "./management";
import metal from "./metal";
import oil from "./oil";
import packing from "./packing";
import paper from "./paper";
import plastic from "./plastic";
import reindeer from "./reindeer";
import trees from "./trees";
import wrappingPaper from "./wrapping-paper";
import packing from "./packing";
interface BetterFertilizerUpgOptions {
canAfford: () => boolean;
onPurchase: VoidFunction;
display: JSXFunction;
style: Computable<StyleValue>;
visibility: () => Visibility;
}
interface UnlockKilnUpgOptions {
resource: Resource;
cost: DecimalSource;
display: {
title: string;
description: string;
};
style: Computable<StyleValue>;
visibility: () => Visibility;
}
interface EfficientSmeltherUpgOptions {
resource: Resource;
cost: DecimalSource;
display: {
title: string;
description: string;
};
style: Computable<StyleValue>;
visibility: () => Visibility;
}
const id = "coal";
const day = 3;
@ -95,41 +67,42 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
return gain;
});
const fireCost = computed(() => {
const bonfireCost = Decimal.pow(0.95, paper.books.bonfireBook.totalAmount.value).times(10);
let v = Decimal.times(buildBonfire.amount.value, bonfireCost).plus(buildFire.amount.value);
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 2).div(100);
if (Decimal.gte(v, 10000)) v = Decimal.pow(v, 2).div(10000);
v = Decimal.pow(0.95, paper.books.smallFireBook.totalAmount.value).times(v);
return v.pow(masteryEffectActive.value ? 1.1 : 1.5).times(1e4);
});
const buildFire = createBuyable(() => ({
requirements: createCostRequirement(() => ({
resource: trees.logs,
cost: fireCost
})),
resource: trees.logs,
cost() {
let v = Decimal.times(buildBonfire.amount.value, unref(buildBonfire.cost!)).plus(
this.amount.value
);
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 2).div(100);
if (Decimal.gte(v, 10000)) v = Decimal.pow(v, 2).div(10000);
v = Decimal.pow(0.95, paper.books.smallFireBook.totalAmount.value).times(v);
return v.pow(masteryEffectActive.value ? 1.1 : 1.5).times(1e4);
},
inverseCost(x: DecimalSource) {
let v = Decimal.div(x, 1e4).root(masteryEffectActive.value ? 1.1 : 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!)));
const bonfireCost = Decimal.pow(0.95, paper.books.bonfireBook.totalAmount.value).times(
10
);
v = v.sub(Decimal.times(buildBonfire.amount.value, bonfireCost));
return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0);
},
display: jsx(() => (
<>
<h3>Small Fire</h3>
<br />
Burn 1000 logs for 0.1 coal and 50 ash
<br />
<br />
Currently:
<br />-{format(fireLogs.value)} logs/sec
<br />+{format(fireCoal.value)} coal/sec
<br />+{format(fireAsh.value)} ash/sec
<br />
<br />
Cost: {formatWhole(unref(buildFire.cost!))} {buildFire.resource!.displayName}
</>
)),
display: {
title: "Small Fire",
description: "Burn 1000 logs for 0.1 coal and 50 ash",
effectDisplay: jsx(() => (
<>
<br />-{format(fireLogs.value)} logs/sec
<br />+{format(fireCoal.value)} coal/sec
<br />+{format(fireAsh.value)} ash/sec
</>
))
},
onPurchase() {
activeFires.value = Decimal.add(activeFires.value, 1);
},
@ -139,7 +112,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
flexGrow: 1
},
visibility: () => showIf(!main.isMastery.value || masteryEffectActive.value)
})) as ElfBuyable & { resource: Resource };
})) as ElfBuyable;
const {
min: minFire,
@ -169,34 +142,36 @@ const layer = createLayer(id, function (this: BaseLayer) {
return gain;
});
const buildBonfire = createBuyable(() => ({
requirements: createCostRequirement(() => ({
resource: fireResource,
cost() {
return Decimal.pow(0.95, paper.books.bonfireBook.totalAmount.value).times(10);
}
})),
resource: fireResource,
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(() => (
<>
<h3>Bonfire</h3>
<br />
Burn 10,000 logs for 10 coal and 1000 ash
<br />
<br />
Currently:
<br />-{format(bonfireLogs.value)} logs/sec
<br />+{format(bonfireCoal.value)} coal/sec
<br />+{format(bonfireAsh.value)} ash/sec
<br />
<br />
Cost: {formatWhole(unref(buildBonfire.cost!))} {buildBonfire.resource!.displayName}
</>
)),
onPurchase(cost) {
activeFires.value = Decimal.sub(activeFires.value, cost!).max(0);
display: {
title: "Bonfire",
description: "Burn 10,000 logs for 10 coal and 1000 ash",
effectDisplay: jsx(() => (
<>
<br />-{format(bonfireLogs.value)} logs/sec
<br />+{format(bonfireCoal.value)} coal/sec
<br />+{format(bonfireAsh.value)} ash/sec
</>
))
},
onPurchase() {
const cost = Decimal.pow(
0.95,
Decimal.sub(paper.books.bonfireBook.totalAmount.value, 1)
).times(10);
activeFires.value = Decimal.sub(activeFires.value, cost).max(0);
activeBonfires.value = Decimal.add(activeBonfires.value, 1);
},
style: {
@ -205,7 +180,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
flexGrow: 1
},
visibility: () => showIf(unlockBonfire.bought.value)
})) as ElfBuyable & { resource: Resource };
})) as ElfBuyable;
const {
min: minBonfire,
max: maxBonfire,
@ -231,38 +206,41 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
return gain;
});
const kilnCost = computed(() => {
let v = buildKiln.amount.value;
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 2).div(100);
if (Decimal.gte(v, 10000)) v = Decimal.pow(v, 2).div(10000);
v = Decimal.pow(0.95, paper.books.kilnBook.totalAmount.value).times(v);
return Decimal.pow(packing.packingMilestones.coalBoost.earned.value ? 1.05 : 1.1, v).times(
1e7
);
});
const buildKiln = createBuyable(() => ({
requirements: createCostRequirement(() => ({
resource: trees.logs,
cost: kilnCost
})),
resource: trees.logs,
cost() {
let v = this.amount.value;
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 2).div(100);
if (Decimal.gte(v, 10000)) v = Decimal.pow(v, 2).div(10000);
v = Decimal.pow(0.95, paper.books.kilnBook.totalAmount.value).times(v);
return Decimal.pow(packing.packingMilestones.coalBoost.earned.value ? 1.05 : 1.1, v).times(1e7);
},
inverseCost(x: DecimalSource) {
let v = Decimal.div(x, 1e7).log(packing.packingMilestones.coalBoost.earned.value ? 1.05 : 1.1);
let v = Decimal.div(x, 1e7).log(
packing.packingMilestones.coalBoost.earned.value ? 1.05 : 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(() => (
<>
<h3>Charcoal Kiln</h3>
<br />
Burn 1,000,000 logs for 10,000 coal and 10,000 ash
<br />
<br />
Currently:
<br />-{format(kilnLogs.value)} logs/sec
<br />+{format(kilnCoal.value)} coal/sec
<br />+{format(kilnAsh.value)} ash/sec
<br />
<br />
Cost: {formatWhole(unref(buildKiln.cost!))} {buildKiln.resource!.displayName}
</>
)),
display: {
title: "Charcoal Kiln",
description: "Burn 1,000,000 logs for 10,000 coal and 10,000 ash",
effectDisplay: jsx(() => (
<>
<br />-{format(kilnLogs.value)} logs/sec
<br />+{format(kilnCoal.value)} coal/sec
<br />+{format(kilnAsh.value)} ash/sec
</>
))
},
onPurchase() {
activeKilns.value = Decimal.add(activeKilns.value, 1);
},
@ -272,7 +250,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
flexGrow: 1
},
visibility: () => showIf(unlockKiln.bought.value)
})) as ElfBuyable & { resource: Resource };
})) as ElfBuyable;
const {
min: minKiln,
max: maxKiln,
@ -293,22 +271,29 @@ const layer = createLayer(id, function (this: BaseLayer) {
.times(management.elfTraining.bonfireElfTraining.milestones[2].earned.value ? 2 : 1)
.times(management.elfTraining.kilnElfTraining.milestones[2].earned.value ? 2 : 1)
);
const drillCost = computed(() => {
let v = buildDrill.amount.value;
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 2).div(100);
if (Decimal.gte(v, 10000)) v = Decimal.pow(v, 2).div(10000);
v = Decimal.pow(0.95, paper.books.coalDrillBook.totalAmount.value).times(v);
let cost = Decimal.pow(
packing.packingMilestones.coalBoost.earned.value ? 1.075 : 1.15,
v
).times(10);
if (management.elfTraining.fertilizerElfTraining.milestones[2].earned.value) {
cost = cost.div(Decimal.add(trees.totalLogs.value, Math.E).ln());
}
if (management.elfTraining.coalDrillElfTraining.milestones[2].earned.value) {
cost = cost.div(10);
}
return cost;
});
const buildDrill = createBuyable(() => ({
requirements: createCostRequirement(() => ({
resource: metal.metal,
cost: drillCost
})),
resource: metal.metal,
cost() {
let v = this.amount.value;
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 2).div(100);
if (Decimal.gte(v, 10000)) v = Decimal.pow(v, 2).div(10000);
v = Decimal.pow(0.95, paper.books.coalDrillBook.totalAmount.value).times(v);
let cost = Decimal.pow(packing.packingMilestones.coalBoost.earned.value ? 1.075 : 1.15, v).times(10);
if (management.elfTraining.fertilizerElfTraining.milestones[2].earned.value) {
cost = cost.div(Decimal.add(trees.totalLogs.value, Math.E).ln());
}
if (management.elfTraining.coalDrillElfTraining.milestones[2].earned.value) {
cost = cost.div(10);
}
return cost;
},
inverseCost(x: DecimalSource) {
if (management.elfTraining.coalDrillElfTraining.milestones[2].earned.value) {
x = Decimal.mul(x, 10);
@ -316,26 +301,23 @@ const layer = createLayer(id, function (this: BaseLayer) {
if (management.elfTraining.fertilizerElfTraining.milestones[2].earned.value) {
x = Decimal.mul(x, Decimal.add(trees.totalLogs.value, Math.E).ln());
}
let v = Decimal.div(x, 10).log(packing.packingMilestones.coalBoost.earned.value ? 1.075 : 1.15);
let v = Decimal.div(x, 10).log(
packing.packingMilestones.coalBoost.earned.value ? 1.075 : 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(() => (
<>
<h3>Coal Drill</h3>
<br />
Dig through the ground to find 50,000,000 coal
<br />
<br />
Currently:
<br />+{format(drillCoal.value)} coal/sec
<br />
<br />
Cost: {formatWhole(unref(buildDrill.cost!))} {buildDrill.resource.displayName}
</>
)),
display: {
title: "Coal Drill",
description: "Dig through the ground to find 50,000,000 coal",
effectDisplay: jsx(() => (
<>
<br />+{format(drillCoal.value)} coal/sec
</>
))
},
onPurchase() {
activeDrills.value = Decimal.add(activeDrills.value, 1);
},
@ -345,7 +327,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
flexGrow: 1
},
visibility: () => showIf(metal.coalDrill.bought.value)
})) as ElfBuyable & { resource: Resource };
})) as ElfBuyable;
const {
max: maxDrill,
min: minDrill,
@ -357,8 +339,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
});
const warmerCutters = createUpgrade(() => ({
resource: noPersist(coal),
cost: 5,
requirements: createCostRequirement(() => ({
resource: noPersist(coal),
cost: 5
})),
display: {
title: "Warmer Cutters",
description: "Cut down twice as many trees/s"
@ -368,8 +352,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const warmerPlanters = createUpgrade(() => ({
resource: noPersist(coal),
cost: 5,
requirements: createCostRequirement(() => ({
resource: noPersist(coal),
cost: 5
})),
display: {
title: "Warmer Planters",
description: "Plant twice as many trees/s"
@ -379,8 +365,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const basicFertilizer = createUpgrade(() => ({
resource: noPersist(ash),
cost: 5000,
requirements: createCostRequirement(() => ({
resource: noPersist(ash),
cost: 5000
})),
display: {
title: "Ashy Soil",
description: "Trees give 25% more logs"
@ -390,14 +378,16 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const unlockBonfire = createUpgrade(() => ({
resource: fireResource,
cost: 10,
requirements: createCostRequirement(() => ({
resource: fireResource,
cost: 10
})),
display: {
title: "Bigger Fires",
description: "Put all those fires together into a larger blaze"
},
onPurchase() {
fireResource.value = Decimal.add(fireResource.value, this.cost as number);
fireResource.value = Decimal.add(fireResource.value, 10);
},
style() {
return this.bought.value ? "" : { color: colorText };
@ -406,8 +396,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
const row1upgrades = [warmerCutters, warmerPlanters, basicFertilizer, unlockBonfire];
const dedicatedCutters = createUpgrade(() => ({
resource: noPersist(coal),
cost: 250,
requirements: createCostRequirement(() => ({
resource: noPersist(coal),
cost: 250
})),
display: {
title: "Dedicated Cutter Heaters",
description: "Double the bonus from Heated Cutters"
@ -418,8 +410,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
visibility: () => showIf(unlockBonfire.bought.value)
}));
const dedicatedPlanters = createUpgrade(() => ({
resource: noPersist(coal),
cost: 250,
requirements: createCostRequirement(() => ({
resource: noPersist(coal),
cost: 250
})),
display: {
title: "Dedicated Planter Heaters",
description: "Double the bonus from Heated Planters"
@ -429,35 +423,32 @@ const layer = createLayer(id, function (this: BaseLayer) {
},
visibility: () => showIf(unlockBonfire.bought.value)
}));
const betterFertilizer: Upgrade<BetterFertilizerUpgOptions> = createUpgrade(() => ({
canAfford() {
return Decimal.gte(trees.logs.value, 1e5) && Decimal.gte(ash.value, 1e5);
const betterFertilizer = createUpgrade(() => ({
requirements: [
createCostRequirement(() => ({
resource: trees.logs,
cost: 1e5
})),
createCostRequirement(() => ({
resource: noPersist(ash),
cost: 1e5
}))
],
display: {
title: "Mulched Soil",
description: "Double the bonus from Fertilized Soil"
},
onPurchase() {
trees.logs.value = Decimal.sub(trees.logs.value, 1e5);
ash.value = Decimal.sub(ash.value, 1e5);
},
display: jsx(() => (
<>
<h3>Mulched Soil</h3>
<br />
Double the bonus from Fertilized Soil
<br />
<br />
Cost: {formatWhole(1e5)} {trees.logs.displayName}
<br />
{formatWhole(1e5)} {ash.displayName}
</>
)),
style() {
return this.bought.value ? "" : { color: colorText };
},
visibility: () => showIf(unlockBonfire.bought.value)
}));
const unlockKiln: Upgrade<UnlockKilnUpgOptions> = createUpgrade(() => ({
resource: trees.logs,
cost: 1e7,
const unlockKiln = createUpgrade(() => ({
requirements: createCostRequirement(() => ({
resource: trees.logs,
cost: 1e7
})),
display: {
title: "Efficient Fires",
description: "Move the fires underground to keep the coal from turning to ash"
@ -469,9 +460,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
}));
const row2upgrades = [dedicatedCutters, dedicatedPlanters, betterFertilizer, unlockKiln];
const efficientSmelther: Upgrade<EfficientSmeltherUpgOptions> = createUpgrade(() => ({
resource: noPersist(coal),
cost: 1e19,
const efficientSmelther = createUpgrade(() => ({
requirements: createCostRequirement(() => ({
resource: noPersist(coal),
cost: 1e19
})),
display: {
title: "Efficient Crucibles",
description: "Double auto smelting speed and triple metal gain from auto smelting"
@ -482,8 +475,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
visibility: () => showIf(oil.depthMilestones[4].earned.value)
}));
const arsonistAssistance = createUpgrade(() => ({
resource: noPersist(coal),
cost: 1e45,
requirements: createCostRequirement(() => ({
resource: noPersist(coal),
cost: 1e45
})),
display: {
title: "Arsonist Assistance",
description: "Every elf at or above level 5 doubles ash gain"
@ -495,8 +490,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
showIf(management.elfTraining.coalDrillElfTraining.milestones[3].earned.value)
}));
const refinedCoal = createUpgrade(() => ({
resource: noPersist(coal),
cost: 1e50,
requirements: createCostRequirement(() => ({
resource: noPersist(coal),
cost: 1e50
})),
display: {
title: "Refined Coal",
description: "Refineries boost coal gain"
@ -508,8 +505,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
showIf(management.elfTraining.coalDrillElfTraining.milestones[3].earned.value)
}));
const coloredFire = createUpgrade(() => ({
resource: noPersist(coal),
cost: 1e55,
requirements: createCostRequirement(() => ({
resource: noPersist(coal),
cost: 1e55
})),
display: {
title: "Colored Fire",
description: "Green dye also affects small fire synergy"
@ -523,19 +522,21 @@ const layer = createLayer(id, function (this: BaseLayer) {
const row3upgrades = [efficientSmelther, arsonistAssistance, refinedCoal, coloredFire];
const heatedCutters = createBuyable(() => ({
resource: noPersist(coal),
cost() {
let v = this.amount.value;
if (Decimal.gte(v, 50)) v = Decimal.pow(v, 2).div(50);
if (Decimal.gte(v, 200)) v = Decimal.pow(v, 2).div(200);
if (Decimal.gte(v, 2e6)) v = Decimal.pow(v, 2).div(2e6);
v = Decimal.pow(0.95, paper.books.heatedCuttersBook.totalAmount.value).times(v);
if (management.elfTraining.heatedCutterElfTraining.milestones[0].earned.value) {
requirements: createCostRequirement(() => ({
resource: noPersist(coal),
cost() {
let v = heatedCutters.amount.value;
if (Decimal.gte(v, 50)) v = Decimal.pow(v, 2).div(50);
if (Decimal.gte(v, 200)) v = Decimal.pow(v, 2).div(200);
if (Decimal.gte(v, 2e6)) v = Decimal.pow(v, 2).div(2e6);
v = Decimal.pow(0.95, paper.books.heatedCuttersBook.totalAmount.value).times(v);
if (management.elfTraining.heatedCutterElfTraining.milestones[0].earned.value) {
v = Decimal.pow(0.95, paper.books.heatedCuttersBook.totalAmount.value).times(v);
}
v = v.div(wrappingPaper.boosts.rainbow1.value);
return Decimal.add(v, 1).pow(2.5).times(10);
}
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);
@ -559,19 +560,23 @@ const layer = createLayer(id, function (this: BaseLayer) {
visibility: () => showIf(warmerCutters.bought.value)
})) as ElfBuyable & { display: { title: string }; resource: Resource };
const heatedPlanters = createBuyable(() => ({
resource: noPersist(coal),
cost() {
let v = this.amount.value;
if (Decimal.gte(v, 50)) v = Decimal.pow(v, 2).div(50);
if (Decimal.gte(v, 200)) v = Decimal.pow(v, 2).div(200);
if (Decimal.gte(v, 2e6)) v = Decimal.pow(v, 2).div(2e6);
v = Decimal.pow(0.95, paper.books.heatedPlantersBook.totalAmount.value).times(v);
if (management.elfTraining.heatedPlanterElfTraining.milestones[0].earned.value) {
requirements: createCostRequirement(() => ({
resource: noPersist(coal),
cost() {
let v = heatedPlanters.amount.value;
if (Decimal.gte(v, 50)) v = Decimal.pow(v, 2).div(50);
if (Decimal.gte(v, 200)) v = Decimal.pow(v, 2).div(200);
if (Decimal.gte(v, 2e6)) v = Decimal.pow(v, 2).div(2e6);
v = Decimal.pow(0.95, paper.books.heatedPlantersBook.totalAmount.value).times(v);
if (management.elfTraining.heatedPlanterElfTraining.milestones[0].earned.value) {
v = Decimal.pow(0.95, paper.books.heatedPlantersBook.totalAmount.value).times(
v
);
}
v = v.div(wrappingPaper.boosts.rainbow1.value);
return Decimal.add(v, 1).pow(2.5).times(10);
}
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);
@ -595,19 +600,21 @@ const layer = createLayer(id, function (this: BaseLayer) {
visibility: () => showIf(warmerPlanters.bought.value)
})) as ElfBuyable & { display: { title: string }; resource: Resource };
const moreFertilizer = createBuyable(() => ({
resource: noPersist(ash),
cost() {
let v = this.amount.value;
if (Decimal.gte(v, 50)) v = Decimal.pow(v, 2).div(50);
if (Decimal.gte(v, 200)) v = Decimal.pow(v, 2).div(200);
if (Decimal.gte(v, 2e6)) v = Decimal.pow(v, 2).div(2e6);
v = Decimal.pow(0.95, paper.books.fertilizerBook.totalAmount.value).times(v);
if (management.elfTraining.fertilizerElfTraining.milestones[1].earned.value) {
requirements: createCostRequirement(() => ({
resource: noPersist(ash),
cost() {
let v = moreFertilizer.amount.value;
if (Decimal.gte(v, 50)) v = Decimal.pow(v, 2).div(50);
if (Decimal.gte(v, 200)) v = Decimal.pow(v, 2).div(200);
if (Decimal.gte(v, 2e6)) v = Decimal.pow(v, 2).div(2e6);
v = Decimal.pow(0.95, paper.books.fertilizerBook.totalAmount.value).times(v);
if (management.elfTraining.fertilizerElfTraining.milestones[1].earned.value) {
v = Decimal.pow(0.95, paper.books.fertilizerBook.totalAmount.value).times(v);
}
v = v.div(wrappingPaper.boosts.rainbow1.value);
return Decimal.add(v, 1).pow(1.5).times(50000);
}
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);

View file

@ -40,6 +40,11 @@ import factory from "./factory";
import reindeer from "./reindeer";
import routing from "./routing";
import packing from "./packing";
import {
createBooleanRequirement,
createCostRequirement,
requirementsMet
} from "game/requirements";
interface Dye {
name: string;
@ -80,19 +85,24 @@ const layer = createLayer(id, function (this: BaseLayer) {
() => mastered.value || main.currentlyMastering.value?.name === name
);
const primaryDyes = createResource(
computed(() =>
Decimal.min(dyes.red.amount.value, dyes.yellow.amount.value).min(dyes.blue.amount.value)
),
"red, yellow, and blue dye"
);
function createDye(
options: {
name: string;
color: string;
shadowColor?: string;
key: string;
costs: Computable<
{
base: Ref<DecimalSource> | DecimalSource;
root?: Ref<DecimalSource> | DecimalSource;
res: Resource<DecimalSource>;
}[]
>;
costs: () => {
base: Ref<DecimalSource> | DecimalSource;
root?: Ref<DecimalSource> | DecimalSource;
res: Resource<DecimalSource>;
}[];
listedBoosts: {
visible: Ref<boolean> | boolean;
desc: Ref<string>;
@ -250,81 +260,61 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
const buyable: ElfBuyable = createBuyable(() => {
const costs = convertComputable(options.costs);
const costs = options.costs();
return {
...options,
style: () => ({
backgroundColor: unref(buyable.canPurchase) ? color : "#545454",
backgroundColor: requirementsMet(buyable.requirements) ? color : "#545454",
minWidth: "200px"
}),
display: jsx(() => {
return (
<span>
<h3>
{options.name} Chambers <HotkeyVue hotkey={hotkey} />
</h3>
<br />
display: {
title: jsx(() => (
<h3>
{options.name} Chambers <HotkeyVue hotkey={hotkey} />
</h3>
)),
description: jsx(() => (
<>
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:{" "}
{unref(costs).map(c =>
render(
jsx(() => (
<div
class={
Decimal.lt(
c.res.value,
unref(
Decimal.pow(
unref(buyable.cost) ?? Decimal.dInf,
unref(c.root ?? 1)
).times(unref(c.base))
)
)
? "unaffordable"
: ""
}
>
{format(
unref(
Decimal.pow(
unref(buyable.cost) ?? Decimal.dInf,
unref(c.root ?? 1)
).times(unref(c.base))
)
)}{" "}
{c.res.displayName}
<br />
</div>
))
)
)}
</div>
</>
)),
effectDisplay: jsx(() => (
<span class="white-space: pre-wrap">
Currently:{" "}
{options.listedBoosts
.filter(b => unref(b.visible))
.map(b => render(jsx(() => <div>{unref(b.desc)}</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
if (Decimal.gte(v, 3125)) v = Decimal.pow(v, 2).div(3125);
v = Decimal.mul(v, Decimal.pow(0.95, dyeBook.totalAmount.value));
return Decimal.div(v, 10).plus(1);
))
},
// Doesn't actually get used due to custom inverseCost function
resource: amount,
requirements: [
...costs.map(c =>
createCostRequirement(() => ({
resource: createResource(
computed(() =>
Decimal.div(c.res.value, unref(c.base)).root(unref(c.root ?? 1))
),
c.res.displayName
),
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
if (Decimal.gte(v, 3125)) v = Decimal.pow(v, 2).div(3125);
v = Decimal.mul(v, Decimal.pow(0.95, dyeBook.totalAmount.value));
return Decimal.div(v, 10).plus(1);
}
}))
),
createBooleanRequirement(() => !main.isMastery.value)
],
inverseCostPre(x: DecimalSource) {
let v = Decimal.sub(x, 1).mul(10);
v = v.div(Decimal.pow(0.95, dyeBook.totalAmount.value));
@ -346,21 +336,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
Decimal.dInf
);
},
canPurchase: computed((cost?: DecimalSource) => {
if (unref(buyable.visibility) != Visibility.Visible) {
return false;
}
if (main.isMastery.value && !masteryEffectActive.value) {
return false;
}
const trueCost = cost ?? unref(buyable.cost) ?? Decimal.dInf;
return unref(costs).every(c =>
Decimal.div(c.res.value, unref(c.base))
.root(unref(c.root ?? 1))
.gte(trueCost)
);
}),
onPurchase(cost?: DecimalSource) {
onPurchase() {
buyable.amount.value = Decimal.add(buyable.amount.value, -1);
let buyMax = false;
switch (options.color) {
@ -828,8 +804,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
</>
))
},
cost: 1000,
resource: dyes.blue.amount,
requirements: createCostRequirement(() => ({
cost: 1000,
resource: dyes.blue.amount
})),
onPurchase() {
dyes.blue.buyable.amount.value = 0;
}
@ -849,8 +827,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
</>
))
},
cost: 1500,
resource: dyes.red.amount,
requirements: createCostRequirement(() => ({
cost: 1500,
resource: dyes.red.amount
})),
onPurchase() {
dyes.red.buyable.amount.value = 0;
}
@ -866,8 +846,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
title: "Wetter Dyes",
description: "Double Red, Yellow, and Blue Dye gain."
},
cost: 2000,
resource: dyes.yellow.amount
requirements: createCostRequirement(() => ({
cost: 2000,
resource: dyes.yellow.amount
}))
})),
yellowDyeUpg2: createUpgrade(() => ({
visibility: () => showIf(upgrades.yellowDyeUpg.bought.value),
@ -875,8 +857,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
title: "Golden Wash",
description: "Halve the Oil cost of Red, Yellow, and Blue Dyes."
},
cost: 5000,
resource: dyes.yellow.amount,
requirements: createCostRequirement(() => ({
cost: 5000,
resource: dyes.yellow.amount
})),
onPurchase() {
dyes.yellow.buyable.amount.value = 0;
}
@ -891,8 +875,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
</>
))
},
cost: 6000,
resource: dyes.red.amount,
requirements: createCostRequirement(() => ({
cost: 6000,
resource: dyes.red.amount
})),
onPurchase() {
dyes.red.buyable.amount.value = 0;
}
@ -903,8 +889,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
title: "Hydrophobia",
description: "Raise Red Dye's effect ^1.5."
},
cost: 7500,
resource: dyes.blue.amount,
requirements: createCostRequirement(() => ({
cost: 7500,
resource: dyes.blue.amount
})),
onPurchase() {
dyes.blue.buyable.amount.value = 0;
}
@ -921,8 +909,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
description:
"Orange, Green, and Purple Dyes' first effect is raised ^1.2, and Green Dye's second effect is squared."
},
cost: "5e30",
resource: coal.coal
requirements: createCostRequirement(() => ({
cost: "5e30",
resource: coal.coal
}))
}))
};
@ -1006,6 +996,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
dyeSum,
boosts,
totalDyeSum,
primaryDyes,
secondaryDyeSum,
minWidth: 700,
generalTabCollapsed,

View file

@ -20,7 +20,7 @@ import { globalBus } from "game/events";
import { BaseLayer, createLayer } from "game/layers";
import { createMultiplicativeModifier, createSequentialModifier, Modifier } from "game/modifiers";
import { persistent } from "game/persistence";
import Decimal, { DecimalSource, formatWhole } from "util/bignum";
import Decimal, { DecimalSource, format, formatWhole } from "util/bignum";
import { Direction } from "util/common";
import { Computable, convertComputable } from "util/computed";
import { render, renderGrid } from "util/vue";
@ -40,10 +40,12 @@ import dyes, { enumColor } from "./dyes";
import ribbon from "./ribbon";
import letters from "./letters";
import packing from "./packing";
import { createBooleanRequirement, createCostRequirement } from "game/requirements";
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;
resource: Resource;
}
const id = "elves";
@ -730,20 +732,20 @@ const layer = createLayer(id, function (this: BaseLayer) {
toggle,
buyProgress,
update,
resource: coal.coal,
cost: trainingCost,
requirements: [
createCostRequirement(() => ({
resource: coal.coal,
cost: trainingCost
})),
createBooleanRequirement(() => !main.isMastery.value)
],
computedAutoBuyCooldown,
amountOfTimesDone,
name: options.name,
canAfford() {
return (
Decimal.gte(coal.coal.value, unref(trainingCost)) && !main.isMastery.value
);
},
display: () => ({
title: options.name,
description: jsx(() => (
<>
<div>
{options.description}
{upgrade.bought.value || elvesThatReset.includes(options.name) ? (
<>
@ -761,9 +763,8 @@ const layer = createLayer(id, function (this: BaseLayer) {
/>
</>
) : null}
</>
)),
showCost: !upgrade.bought.value
</div>
))
}),
style: "width: 190px",
onPurchase() {
@ -864,7 +865,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
hasToggle: true,
toggleDesc: "Activate auto-purchased bonfires",
onAutoPurchase(buyable, amount) {
const spent = Decimal.mul(unref(buyable.cost ?? 0), amount);
const spent = Decimal.mul(
Decimal.pow(0.95, paper.books.bonfireBook.totalAmount.value).times(10),
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) {
@ -1022,7 +1026,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
description:
"Carol will automatically purchase all primary dyes you can afford, without actually spending any resources.",
buyable: Object.values(dyes.dyes).map(dye => dye.buyable),
cooldownModifier: dyeCooldown, // Note: Buy max will be unlocked at this point
cooldownModifier: dyeCooldown,
visibility: () =>
showIf(wrappingPaper.unlockDyeElfMilestone.earned.value && !main.isMastery.value),
buyMax: () => management.elfTraining.dyeElfTraining.milestones[2].earned.value,

View file

@ -91,6 +91,7 @@ import trees from "./trees";
import workshop from "./workshop";
import ribbon from "./ribbon";
import routing from "./routing";
import { createCostRequirement } from "game/requirements";
const id = "factory";
@ -1153,86 +1154,98 @@ const factory = createLayer(id, () => {
const computedCostCheapeners = computed(() => costCheapener.apply(1));
const clothesBuyable = createBuyable(() => ({
resource: toys.clothes,
cost() {
return Decimal.pow(2, Decimal.add(this.amount.value, 5)).div(
computedCostCheapeners.value
);
},
requirements: createCostRequirement(() => ({
resource: toys.clothes,
cost() {
return Decimal.pow(2, Decimal.add(clothesBuyable.amount.value, 5)).div(
computedCostCheapeners.value
);
}
})),
display: {
title: "Train elves to make clothes",
description: "Use your finished toys to train an elf on factory work"
},
style: "width: 110px"
}));
})) as GenericBuyable;
const blocksBuyable = createBuyable(() => ({
resource: toys.woodenBlocks,
cost() {
return Decimal.pow(2, Decimal.add(this.amount.value, 5)).div(
computedCostCheapeners.value
);
},
requirements: createCostRequirement(() => ({
resource: toys.woodenBlocks,
cost() {
return Decimal.pow(2, Decimal.add(blocksBuyable.amount.value, 5)).div(
computedCostCheapeners.value
);
}
})),
display: {
title: "Train elves to make wooden blocks",
description: "Use your finished toys to train an elf on factory work"
},
style: "width: 110px"
}));
})) as GenericBuyable;
const trucksBuyable = createBuyable(() => ({
resource: toys.trucks,
cost() {
return Decimal.pow(2, Decimal.add(this.amount.value, 5)).div(
computedCostCheapeners.value
);
},
requirements: createCostRequirement(() => ({
resource: toys.trucks,
cost() {
return Decimal.pow(2, Decimal.add(trucksBuyable.amount.value, 5)).div(
computedCostCheapeners.value
);
}
})),
display: {
title: "Train elves to make toy trucks",
description: "Use your finished toys to train an elf on factory work"
},
style: "width: 110px"
}));
})) as GenericBuyable;
const bearsBuyable = createBuyable(() => ({
resource: noPersist(bears),
cost() {
return Decimal.pow(2, Decimal.add(this.amount.value, 5)).div(
computedCostCheapeners.value
);
},
requirements: createCostRequirement(() => ({
resource: noPersist(bears),
cost() {
return Decimal.pow(2, Decimal.add(bearsBuyable.amount.value, 5)).div(
computedCostCheapeners.value
);
}
})),
display: {
title: "Train elves to make bears",
description: "Use your finished toys to train an elf on factory work"
},
style: "width: 110px",
visible: () => showIf(main.days[advancedDay - 1].opened.value)
}));
})) as GenericBuyable;
const bucketBuyable = createBuyable(() => ({
resource: noPersist(bucketAndShovels),
cost() {
return Decimal.pow(2, Decimal.add(this.amount.value, 5)).div(
computedCostCheapeners.value
);
},
requirements: createCostRequirement(() => ({
resource: noPersist(bucketAndShovels),
cost() {
return Decimal.pow(2, Decimal.add(bucketBuyable.amount.value, 5)).div(
computedCostCheapeners.value
);
}
})),
display: {
title: "Train elves to make shovel and pails",
description: "Use your finished toys to train an elf on factory work"
},
style: "width: 110px",
visible: () => showIf(main.days[advancedDay - 1].opened.value)
}));
})) as GenericBuyable;
const consolesBuyable = createBuyable(() => ({
resource: noPersist(consoles),
cost() {
return Decimal.pow(2, Decimal.add(this.amount.value, 5)).div(
computedCostCheapeners.value
);
},
requirements: createCostRequirement(() => ({
resource: noPersist(consoles),
cost() {
return Decimal.pow(2, Decimal.add(consolesBuyable.amount.value, 5)).div(
computedCostCheapeners.value
);
}
})),
display: {
title: "Train elves to make consoles",
description: "Use your finished toys to train an elf on factory work"
},
style: "width: 110px",
visible: () => showIf(main.days[advancedDay - 1].opened.value)
}));
})) as GenericBuyable;
const elfBuyables = {
clothesBuyable,
blocksBuyable,
@ -1251,10 +1264,12 @@ const factory = createLayer(id, () => {
const elvesEffect = computed(() => Decimal.pow(1.05, trainedElves.value));
const expandFactory = createBuyable(() => ({
resource: trees.logs,
cost() {
return Decimal.pow(1e4, this.amount.value).times(1e72);
},
requirements: createCostRequirement(() => ({
resource: trees.logs,
cost() {
return Decimal.pow(1e4, expandFactory.amount.value).times(1e72);
}
})),
display: {
title: "Expand Factory",
description:
@ -1269,10 +1284,12 @@ const factory = createLayer(id, () => {
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})) as GenericBuyable;
const oilFuel = createBuyable(() => ({
resource: oil.oil,
cost() {
return Decimal.pow(10, this.amount.value).times(1e23);
},
requirements: createCostRequirement(() => ({
resource: oil.oil,
cost() {
return Decimal.pow(10, oilFuel.amount.value).times(1e23);
}
})),
display: {
title: "Oil Fuel",
description: "Use some surplus oil to generate more electricity",
@ -1283,10 +1300,12 @@ const factory = createLayer(id, () => {
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})) as GenericBuyable;
const carryToys = createBuyable(() => ({
resource: boxes.boxes,
cost() {
return Decimal.pow(100, this.amount.value).times(1e80);
},
requirements: createCostRequirement(() => ({
resource: boxes.boxes,
cost() {
return Decimal.pow(100, carryToys.amount.value).times(1e80);
}
})),
display: {
title: "Carry toys in boxes",
description: "Use some surplus boxes to speed up the whole factory",
@ -1300,8 +1319,10 @@ const factory = createLayer(id, () => {
})) as GenericBuyable;
const betterFactory = createUpgrade(() => ({
resource: noPersist(presents),
cost: 100,
requirements: createCostRequirement(() => ({
resource: noPersist(presents),
cost: 100
})),
display: {
title: "Factory eXPerience",
description: "Factory size is increased by 5."
@ -1309,8 +1330,10 @@ const factory = createLayer(id, () => {
visibility: () => showIf(main.days[presentsDay - 1].opened.value)
}));
const betterLighting = createUpgrade(() => ({
resource: noPersist(presents),
cost: 300,
requirements: createCostRequirement(() => ({
resource: noPersist(presents),
cost: 300
})),
display: {
title: "Burn some logs",
description: "More energy needed? Let's burn some logs! Logs boosts maximum energy.",
@ -1321,8 +1344,10 @@ const factory = createLayer(id, () => {
visibility: () => showIf(betterFactory.bought.value)
}));
const excitmentUpgrade = createUpgrade(() => ({
resource: noPersist(presents),
cost: 1000,
requirements: createCostRequirement(() => ({
resource: noPersist(presents),
cost: 1000
})),
display: {
title: "Faster Elf Training",
description:
@ -1332,8 +1357,10 @@ const factory = createLayer(id, () => {
visibility: () => showIf(betterLighting.bought.value)
}));
const carryPresents = createUpgrade(() => ({
resource: noPersist(presents),
cost: 5000,
requirements: createCostRequirement(() => ({
resource: noPersist(presents),
cost: 5000
})),
display: {
title: "Carrying more stuff in boxes",
description:
@ -1342,13 +1369,15 @@ const factory = createLayer(id, () => {
visibility: () => showIf(excitmentUpgrade.bought.value)
}));
const carryBoxes = createBuyable(() => ({
resource: noPersist(presents),
cost() {
return Decimal.add(carryBoxes.amount.value, 1)
.pow(1.5)
.mul(Decimal.pow(2, carryBoxes.amount.value))
.mul(1000);
},
requirements: createCostRequirement(() => ({
resource: noPersist(presents),
cost() {
return Decimal.add(carryBoxes.amount.value, 1)
.pow(1.5)
.mul(Decimal.pow(2, carryBoxes.amount.value))
.mul(1000);
}
})),
style: "width: 400px",
display: {
title: "Carry boxes in... presents?",
@ -1359,8 +1388,10 @@ const factory = createLayer(id, () => {
visibility: () => showIf(carryPresents.bought.value)
})) as GenericBuyable;
const catalysts = createUpgrade(() => ({
resource: noPersist(presents),
cost: 10000,
requirements: createCostRequirement(() => ({
resource: noPersist(presents),
cost: 10000
})),
display: {
title: "Better Presents",
description:
@ -1369,8 +1400,10 @@ const factory = createLayer(id, () => {
visibility: () => showIf(carryPresents.bought.value)
}));
const bowUpgrade = createUpgrade(() => ({
resource: noPersist(presents),
cost: 1e7,
requirements: createCostRequirement(() => ({
resource: noPersist(presents),
cost: 1e7
})),
display: {
title: "With a bow",
description:
@ -1383,8 +1416,10 @@ const factory = createLayer(id, () => {
const upgrades = [
[
createUpgrade(() => ({
resource: trees.logs,
cost: () => Decimal.pow(5, upgradeAmount.value).mul(1e75),
requirements: createCostRequirement(() => ({
resource: trees.logs,
cost: () => Decimal.pow(5, upgradeAmount.value).mul(1e75)
})),
display: {
title: "Sawmill Efficiency",
description:
@ -1393,8 +1428,10 @@ const factory = createLayer(id, () => {
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})),
createUpgrade(() => ({
resource: paper.paper,
cost: () => Decimal.pow(5, upgradeAmount.value).mul(1e90),
requirements: createCostRequirement(() => ({
resource: paper.paper,
cost: () => Decimal.pow(5, upgradeAmount.value).mul(1e90)
})),
display: {
title: "News Ticker",
description: "Paper boosts tick speed"
@ -1402,8 +1439,10 @@ const factory = createLayer(id, () => {
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})),
createUpgrade(() => ({
resource: toys.trucks,
cost: () => Decimal.pow(1.2, upgradeAmount.value).mul(1000),
requirements: createCostRequirement(() => ({
resource: toys.trucks,
cost: () => Decimal.pow(1.2, upgradeAmount.value).mul(1000)
})),
display: {
title: "Haul wood in trucks",
description: "Trucks multiply wood gain"
@ -1411,8 +1450,10 @@ const factory = createLayer(id, () => {
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})),
createUpgrade(() => ({
resource: metal.metal,
cost: () => Decimal.pow(3, upgradeAmount.value).mul(1e53),
requirements: createCostRequirement(() => ({
resource: metal.metal,
cost: () => Decimal.pow(3, upgradeAmount.value).mul(1e53)
})),
display: {
title: "Diamond-tipped drills",
description: "Drill power ^1.2"
@ -1422,8 +1463,10 @@ const factory = createLayer(id, () => {
],
[
createUpgrade(() => ({
resource: toys.woodenBlocks,
cost: () => Decimal.pow(1.2, upgradeAmount.value).mul(2000),
requirements: createCostRequirement(() => ({
resource: toys.woodenBlocks,
cost: () => Decimal.pow(1.2, upgradeAmount.value).mul(2000)
})),
display: {
title: "Larger wood pieces",
description: "Wooden block producers produce 3x as much"
@ -1431,8 +1474,10 @@ const factory = createLayer(id, () => {
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})),
createUpgrade(() => ({
resource: dyes.dyes.red.amount,
cost: () => Decimal.pow(1.5, upgradeAmount.value).mul(4e16),
requirements: createCostRequirement(() => ({
resource: dyes.dyes.red.amount,
cost: () => Decimal.pow(1.5, upgradeAmount.value).mul(4e16)
})),
display: {
title: "Colorful clothes",
description: "Dye producers produce 4x as much"
@ -1440,8 +1485,10 @@ const factory = createLayer(id, () => {
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})),
createUpgrade(() => ({
resource: plastic.plastic,
cost: () => Decimal.pow(2, upgradeAmount.value).mul(1e17),
requirements: createCostRequirement(() => ({
resource: plastic.plastic,
cost: () => Decimal.pow(2, upgradeAmount.value).mul(1e17)
})),
display: {
title: "Improved plastic producers",
description: "Plastic producers produce 4x as much"
@ -1449,8 +1496,10 @@ const factory = createLayer(id, () => {
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})),
createUpgrade(() => ({
resource: oil.oil,
cost: () => Decimal.pow(1.5, upgradeAmount.value).mul(1e22),
requirements: createCostRequirement(() => ({
resource: oil.oil,
cost: () => Decimal.pow(1.5, upgradeAmount.value).mul(1e22)
})),
display: {
title: "Capitalism",
description: "Console production is tripled"
@ -1460,8 +1509,10 @@ const factory = createLayer(id, () => {
],
[
createUpgrade(() => ({
resource: coal.coal,
cost: () => Decimal.pow(5, upgradeAmount.value).mul(1e130),
requirements: createCostRequirement(() => ({
resource: coal.coal,
cost: () => Decimal.pow(5, upgradeAmount.value).mul(1e130)
})),
display: {
title: "Brighter work rooms",
description: "Unused electricity makes ticks faster"
@ -1469,8 +1520,10 @@ const factory = createLayer(id, () => {
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})),
createUpgrade(() => ({
resource: dyes.dyes.blue.amount,
cost: () => Decimal.pow(1.4, upgradeAmount.value).mul(1e15),
requirements: createCostRequirement(() => ({
resource: dyes.dyes.blue.amount,
cost: () => Decimal.pow(1.4, upgradeAmount.value).mul(1e15)
})),
display: {
title: "Colorful teddy bears",
description: "Teddy bears produce 2x as much"
@ -1478,8 +1531,10 @@ const factory = createLayer(id, () => {
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})),
createUpgrade(() => ({
resource: dyes.dyes.black.amount,
cost: () => Decimal.pow(1.5, upgradeAmount.value).mul(1e6),
requirements: createCostRequirement(() => ({
resource: dyes.dyes.black.amount,
cost: () => Decimal.pow(1.5, upgradeAmount.value).mul(1e6)
})),
display: {
title: "New Colors",
description: "Unlock white dye"
@ -1487,8 +1542,10 @@ const factory = createLayer(id, () => {
visibility: () => showIf(main.days[advancedDay - 1].opened.value)
})),
createUpgrade(() => ({
resource: boxes.boxes,
cost: () => Decimal.pow(3, upgradeAmount.value).mul(1e80),
requirements: createCostRequirement(() => ({
resource: boxes.boxes,
cost: () => Decimal.pow(3, upgradeAmount.value).mul(1e80)
})),
display: {
title: "Carry ticks in boxes",
description: "Tick speed x1.5"
@ -1502,7 +1559,11 @@ const factory = createLayer(id, () => {
// pixi
const upgradeAmount = computed(
() => upgrades.slice(0,3).flat().filter(u => u.bought.value).length
() =>
upgrades
.slice(0, 3)
.flat()
.filter(u => u.bought.value).length
) as ComputedRef<number>;
// load every sprite here so pixi doesn't complain about loading multiple times
const assetsLoading = Promise.all([

View file

@ -30,6 +30,7 @@ import { globalBus } from "game/events";
import { main } from "data/projEntry";
import { createHotkey } from "features/hotkey";
import HotkeyVue from "components/Hotkey.vue";
import { createCostRequirement } from "game/requirements";
const id = "letters";
const day = 14;
@ -104,10 +105,12 @@ const layer = createLayer(id, function (this: BaseLayer) {
<>{format(Decimal.div(metalBuyable.amount.value, 2).add(1))}x</>
))
},
resource: metal.metal,
cost() {
return Decimal.pow(10, metalBuyable.amount.value).times(1e21);
},
requirements: createCostRequirement(() => ({
resource: metal.metal,
cost() {
return Decimal.pow(10, metalBuyable.amount.value).times(1e21);
}
})),
visibility: () => showIf(!main.isMastery.value || masteryEffectActive.value)
})) as GenericBuyable;
const plasticBuyable = createBuyable(() => ({
@ -119,10 +122,12 @@ const layer = createLayer(id, function (this: BaseLayer) {
<>{format(Decimal.div(plasticBuyable.amount.value, 2).add(1))}x</>
))
},
resource: plastic.plastic,
cost() {
return Decimal.pow(1.5, plasticBuyable.amount.value).times(1e9);
},
requirements: createCostRequirement(() => ({
resource: plastic.plastic,
cost() {
return Decimal.pow(1.5, plasticBuyable.amount.value).times(1e9);
}
})),
visibility: () => showIf(!main.isMastery.value || masteryEffectActive.value)
})) as GenericBuyable;
const paperBuyable = createBuyable(() => ({
@ -133,10 +138,12 @@ const layer = createLayer(id, function (this: BaseLayer) {
<>{format(Decimal.div(paperBuyable.amount.value, 2).add(1))}x</>
))
},
resource: paper.paper,
cost() {
return Decimal.pow(3, paperBuyable.amount.value).times(1e38);
},
requirements: createCostRequirement(() => ({
resource: paper.paper,
cost() {
return Decimal.pow(3, paperBuyable.amount.value).times(1e38);
}
})),
visibility: () => showIf(!main.isMastery.value || masteryEffectActive.value)
})) as GenericBuyable;
const buyables = { metalBuyable, plasticBuyable, paperBuyable };

View file

@ -33,12 +33,12 @@ import plastic from "./plastic";
import trees from "./trees";
import "./styles/management.css";
import { Resource } from "features/resources/resource";
import { createResource, Resource } from "features/resources/resource";
import { isArray } from "@vue/shared";
import { createTab } from "features/tabs/tab";
import routing from "./routing";
import packing from "./packing";
import elves from "./elves";
import { createCostRequirement } from "game/requirements";
const id = "management";
const day = 12;
@ -103,8 +103,10 @@ const layer = createLayer(id, () => {
description:
"The Elves probably need to be taught if they're to do better. Maybe you'll build a school so you can teach them?"
},
resource: trees.logs,
cost: 1e21,
requirements: createCostRequirement(() => ({
resource: trees.logs,
cost: 1e21
})),
visibility: () => showIf(!main.isMastery.value)
}));
@ -115,9 +117,11 @@ const layer = createLayer(id, () => {
"Yay, you have a school. Too bad it has pretty much nothing in it. Maybe you could add some classrooms to make it less boring and more enticing to the Elves?"
},
visibility: () => showIf(teaching.bought.value),
resource: boxes.boxes,
style: "width: 150px",
cost: 1e13
requirements: createCostRequirement(() => ({
resource: boxes.boxes,
cost: 1e13
}))
}));
const advancedUpgrade = createUpgrade(() => ({
display: {
@ -131,9 +135,11 @@ const layer = createLayer(id, () => {
main.day.value >= advancedDay &&
main.days[advancedDay - 1].opened.value
),
resource: boxes.boxes,
style: "width: 150px",
cost: 1e25
requirements: createCostRequirement(() => ({
resource: boxes.boxes,
cost: 1e25
}))
}));
const globalXPModifier = createSequentialModifier(() => [
createMultiplicativeModifier(() => ({
@ -1523,24 +1529,30 @@ const layer = createLayer(id, () => {
title: "Focus Booster",
description: "Multiplies the maximum experience multiplier from focus by 2"
},
resource: trees.logs,
cost: 1e25
requirements: createCostRequirement(() => ({
resource: trees.logs,
cost: 1e25
}))
}));
const focusUpgrade2 = createUpgrade(() => ({
display: {
title: "Focus Buffer",
description: "Increase elves affected by focus by 1"
},
resource: trees.logs,
cost: 1e28
requirements: createCostRequirement(() => ({
resource: trees.logs,
cost: 1e28
}))
}));
const focusUpgrade3 = createUpgrade(() => ({
display: {
title: "Focus Upgrader",
description: "Focus can now be rerolled every 10 seconds"
},
resource: trees.logs,
cost: 1e31
requirements: createCostRequirement(() => ({
resource: trees.logs,
cost: 1e31
}))
}));
const upgrades = [focusUpgrade1, focusUpgrade2, focusUpgrade3];
const focusUpgrade4 = createUpgrade(() => ({
@ -1549,122 +1561,116 @@ const layer = createLayer(id, () => {
description:
"The bar moves slower when it's closer to the right and faster when it's closer to the left"
},
resource: trees.logs,
visibility: () => showIf(elfTraining.clothElfTraining.milestones[4].earned.value),
cost: 1e34
requirements: createCostRequirement(() => ({
resource: trees.logs,
cost: 1e34
}))
}));
const focusUpgrade5 = createUpgrade(() => ({
display: {
title: "Focus Focuser",
description: "The bar moves 2x slower"
},
resource: trees.logs,
visibility: () => showIf(elfTraining.clothElfTraining.milestones[4].earned.value),
cost: 1e35
requirements: createCostRequirement(() => ({
resource: trees.logs,
cost: 1e35
}))
}));
const focusUpgrade6 = createUpgrade(() => ({
display: {
title: "Focus Doubler",
description: "Focus applies to an additional elf."
},
resource: trees.logs,
visibility: () => showIf(elfTraining.clothElfTraining.milestones[4].earned.value),
cost: 1e36
requirements: createCostRequirement(() => ({
resource: trees.logs,
cost: 1e36
}))
}));
const upgrades2 = [focusUpgrade4, focusUpgrade5, focusUpgrade6];
// ------------------------------------------------------------------------------- Schools
const schoolCost = computed(() => {
const schoolFactor = Decimal.pow(10, schools.amount.value);
const nerfedSchoolFactor = Decimal.pow(4, schools.amount.value);
let woodFactor = Decimal.pow(2e4, Decimal.pow(schools.amount.value, 0.75));
if (Decimal.gte(schools.amount.value, 4)) {
woodFactor = woodFactor.div(1e3);
}
const coalFactor = Decimal.pow(2000, schools.amount.value);
return {
wood: woodFactor.mul(1e21),
coal: coalFactor.mul(1e32),
paper: coalFactor.mul(1e18),
boxes: woodFactor.mul(1e13),
metalIngots: nerfedSchoolFactor.mul(1e12),
cloth: schoolFactor.mul(1e4),
plastic: nerfedSchoolFactor.mul(1e6),
dye: Decimal.add(schools.amount.value, 1).mul(10000)
};
});
function displayCost(
res: Resource<DecimalSource> | Resource<DecimalSource>[],
cost: DecimalSource,
label: string
) {
const affordable = (isArray(res) ? res : [res]).every(res => Decimal.gte(res.value, cost));
return (
<span class={affordable ? "" : "unaffordable"}>
{format(cost)} {label}
</span>
);
}
const schools = createBuyable(() => ({
display: jsx(() => (
<>
<h3>Build a School</h3>
<div>
You gotta start somewhere, right? Each school increases the maximum level for
elves by 1, maximum of {main.days[advancedDay - 1].opened.value ? 5 : 3}{" "}
schools.
</div>
<div>
You have {formatWhole(schools.amount.value)} schools, which are currently
letting elves learn up to level {formatWhole(schools.amount.value)}.
</div>
{Decimal.lt(schools.amount.value, unref(schools.purchaseLimit)) ? (
requirements: [
createCostRequirement(() => ({
resource: trees.logs,
cost() {
let woodFactor = Decimal.pow(2e4, Decimal.pow(schools.amount.value, 0.75));
if (Decimal.gte(schools.amount.value, 4)) {
woodFactor = woodFactor.div(1e3);
}
return woodFactor.mul(1e21);
}
})),
createCostRequirement(() => ({
resource: coal.coal,
cost() {
const coalFactor = Decimal.pow(2000, schools.amount.value);
return coalFactor.mul(1e32);
}
})),
createCostRequirement(() => ({
resource: paper.paper,
cost() {
const coalFactor = Decimal.pow(2000, schools.amount.value);
return coalFactor.mul(1e18);
}
})),
createCostRequirement(() => ({
resource: boxes.boxes,
cost() {
let woodFactor = Decimal.pow(2e4, Decimal.pow(schools.amount.value, 0.75));
if (Decimal.gte(schools.amount.value, 4)) {
woodFactor = woodFactor.div(1e3);
}
return woodFactor.mul(1e13);
}
})),
createCostRequirement(() => ({
resource: metal.metal,
cost() {
const nerfedSchoolFactor = Decimal.pow(4, schools.amount.value);
return nerfedSchoolFactor.mul(1e12);
}
})),
createCostRequirement(() => ({
resource: cloth.cloth,
cost() {
const schoolFactor = Decimal.pow(10, schools.amount.value);
return schoolFactor.mul(1e4);
}
})),
createCostRequirement(() => ({
resource: plastic.plastic,
cost() {
const nerfedSchoolFactor = Decimal.pow(4, schools.amount.value);
return nerfedSchoolFactor.mul(1e6);
}
})),
createCostRequirement(() => ({
resource: dyes.primaryDyes,
cost() {
return Decimal.add(schools.amount.value, 1).mul(10000);
}
}))
],
display: {
title: "Build a School",
description: jsx(() => (
<>
<div>
Costs {displayCost(trees.logs, schoolCost.value.wood, "logs")},{" "}
{displayCost(coal.coal, schoolCost.value.coal, "coal")},{" "}
{displayCost(paper.paper, schoolCost.value.paper, "paper")},{" "}
{displayCost(boxes.boxes, schoolCost.value.boxes, "boxes")},{" "}
{displayCost(metal.metal, schoolCost.value.metalIngots, "metal ingots")},{" "}
{displayCost(cloth.cloth, schoolCost.value.cloth, "cloth")},{" "}
{displayCost(plastic.plastic, schoolCost.value.plastic, "plastic")}, and
requires{" "}
{displayCost(
[dyes.dyes.red.amount, dyes.dyes.yellow.amount, dyes.dyes.blue.amount],
schoolCost.value.dye,
"red, yellow, and blue dye"
)}
You gotta start somewhere, right? Each school increases the maximum level
for elves by 1, maximum of {main.days[advancedDay - 1].opened.value ? 5 : 3}{" "}
schools.
</div>
) : null}
</>
)),
canPurchase(): boolean {
return (
schoolCost.value.wood.lte(trees.logs.value) &&
schoolCost.value.coal.lte(coal.coal.value) &&
schoolCost.value.paper.lte(paper.paper.value) &&
schoolCost.value.boxes.lte(boxes.boxes.value) &&
schoolCost.value.metalIngots.lte(metal.metal.value) &&
schoolCost.value.cloth.lte(cloth.cloth.value) &&
schoolCost.value.plastic.lte(plastic.plastic.value) &&
schoolCost.value.dye.lte(dyes.dyes.blue.amount.value) &&
schoolCost.value.dye.lte(dyes.dyes.red.amount.value) &&
schoolCost.value.dye.lte(dyes.dyes.yellow.amount.value) &&
Decimal.lt(schools.amount.value, unref(schools.purchaseLimit))
);
},
onPurchase() {
// Lower amount first so costs are accurate, then re-add the purchase after
this.amount.value = Decimal.add(this.amount.value, -1);
trees.logs.value = Decimal.sub(trees.logs.value, schoolCost.value.wood);
coal.coal.value = Decimal.sub(coal.coal.value, schoolCost.value.coal);
paper.paper.value = Decimal.sub(paper.paper.value, schoolCost.value.paper);
boxes.boxes.value = Decimal.sub(boxes.boxes.value, schoolCost.value.boxes);
metal.metal.value = Decimal.sub(metal.metal.value, schoolCost.value.metalIngots);
cloth.cloth.value = Decimal.sub(cloth.cloth.value, schoolCost.value.cloth);
plastic.plastic.value = Decimal.sub(plastic.plastic.value, schoolCost.value.plastic);
this.amount.value = Decimal.add(this.amount.value, 1);
<div>
You have {formatWhole(schools.amount.value)} schools, which are currently
letting elves learn up to level {formatWhole(schools.amount.value)}.
</div>
</>
))
},
purchaseLimit() {
if (main.days[advancedDay - 1].opened.value) return 5;
@ -1674,17 +1680,11 @@ const layer = createLayer(id, () => {
style: "width: 600px"
})) as GenericBuyable;
const classroomCost = computed(() => {
const classroomFactor = computed(() => {
let v = classrooms.amount.value;
if (Decimal.gte(v, 50)) v = Decimal.pow(v, 2).div(50);
if (Decimal.gte(v, 200)) v = Decimal.pow(v, 2).div(200);
const classroomFactor = Decimal.add(v, 1).pow(1.5);
return {
wood: classroomFactor.mul(1e21),
paper: classroomFactor.mul(1e18),
boxes: classroomFactor.mul(1e13),
metalIngots: classroomFactor.mul(1e12)
};
return Decimal.add(v, 1).pow(1.5);
});
const classroomEffect = computed(() => {
@ -1692,45 +1692,42 @@ const layer = createLayer(id, () => {
});
const classrooms = createBuyable(() => ({
display: jsx(() => (
<>
<h3>Build a Classroom</h3>
<div>
Hopefully it makes the school a bit less boring. Multiplies elves' XP gain by{" "}
(Classrooms + 1)<sup>0.9</sup>.
</div>
<div>
You have {formatWhole(classrooms.amount.value)} classrooms, which are currently
multiplying elves' XP gain by {format(classroomEffect.value)}
</div>
<div>
Costs {displayCost(trees.logs, classroomCost.value.wood, "logs")},
{displayCost(paper.paper, classroomCost.value.paper, "paper")},{" "}
{displayCost(boxes.boxes, classroomCost.value.boxes, "boxes")},{" "}
{displayCost(metal.metal, classroomCost.value.metalIngots, "metal ingots")}
</div>
</>
)),
canPurchase(): boolean {
return (
classroomCost.value.wood.lte(trees.logs.value) &&
classroomCost.value.paper.lte(paper.paper.value) &&
classroomCost.value.boxes.lte(boxes.boxes.value) &&
classroomCost.value.metalIngots.lte(metal.metal.value)
);
},
onPurchase() {
// Lower amount first so costs are accurate, then re-add the purchase after
this.amount.value = Decimal.add(this.amount.value, -1);
trees.logs.value = Decimal.sub(trees.logs.value, classroomCost.value.wood);
paper.paper.value = Decimal.sub(paper.paper.value, classroomCost.value.paper);
boxes.boxes.value = Decimal.sub(boxes.boxes.value, classroomCost.value.boxes);
metal.metal.value = Decimal.sub(metal.metal.value, classroomCost.value.metalIngots);
this.amount.value = Decimal.add(this.amount.value, 1);
requirements: [
createCostRequirement(() => ({
resource: trees.logs,
cost: () => classroomFactor.value.mul(1e21)
})),
createCostRequirement(() => ({
resource: paper.paper,
cost: () => classroomFactor.value.mul(1e18)
})),
createCostRequirement(() => ({
resource: boxes.boxes,
cost: () => classroomFactor.value.mul(1e13)
})),
createCostRequirement(() => ({
resource: metal.metal,
cost: () => classroomFactor.value.mul(1e12)
}))
],
display: {
title: "Build a Classroom",
description: jsx(() => (
<>
<div>
Hopefully it makes the school a bit less boring. Multiplies elves' XP gain
by (Classrooms + 1)<sup>0.9</sup>.
</div>
<div>
You have {formatWhole(classrooms.amount.value)} classrooms, which are
currently multiplying elves' XP gain by {format(classroomEffect.value)}
</div>
</>
))
},
visibility: computed(() => showIf(classroomUpgrade.bought.value)),
style: "width: 600px"
}));
})) as GenericBuyable;
// ------------------------------------------------------------------------------- Modifiers

View file

@ -42,6 +42,7 @@ import sleigh from "./sleigh";
import factory from "./factory";
import routing from "./routing";
import packing from "./packing";
import { createCostRequirement } from "game/requirements";
const id = "metal";
const day = 7;
@ -412,8 +413,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
const computedNetOreGain = computed(() => netOreGain.apply(0));
const simplePickaxe = createUpgrade(() => ({
resource: noPersist(metal),
cost: 0.1,
requirements: createCostRequirement(() => ({
resource: noPersist(metal),
cost: 0.1
})),
display: {
title: "A Simple Pickaxe",
description:
@ -421,8 +424,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const doublePickaxe = createUpgrade(() => ({
resource: noPersist(metal),
cost: 0.1,
requirements: createCostRequirement(() => ({
resource: noPersist(metal),
cost: 0.1
})),
display: {
title: "Double Pickaxe",
description:
@ -431,8 +436,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
visibility: () => showIf(doublePickaxe.bought.value)
})) as GenericUpgrade;
const crucible = createUpgrade(() => ({
resource: noPersist(metal),
cost: 1,
requirements: createCostRequirement(() => ({
resource: noPersist(metal),
cost: 1
})),
display: {
title: "Crucible",
description:
@ -445,8 +452,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
)
})) as GenericUpgrade;
const coalDrill = createUpgrade(() => ({
resource: noPersist(metal),
cost: 0,
requirements: createCostRequirement(() => ({
resource: noPersist(metal),
cost: 0
})),
display: {
title: "Coal Drilling",
description:
@ -469,24 +478,26 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
})) as GenericUpgrade;
const industrialFurnace = createUpgrade(() => ({
canAfford() {
return Decimal.gte(metal.value, 50) && Decimal.gte(coal.coal.value, 1e11);
},
onPurchase() {
metal.value = Decimal.sub(metal.value, 50);
coal.coal.value = Decimal.sub(coal.coal.value, 1e11);
},
requirements: [
createCostRequirement(() => ({
resource: noPersist(metal),
cost: 50
})),
createCostRequirement(() => ({
resource: coal.coal,
cost: 1e11
}))
],
display: {
title: "Industrial Furnace",
description: `Moving smelting out of the open air and into a dedicated furnace should make efficiency even better. Double metal gained per ore
<br/>
<br/>
Cost: 50 ${metal.displayName}<br/>${format(1e11)} ${coal.coal.displayName}`
description: `Moving smelting out of the open air and into a dedicated furnace should make efficiency even better. Double metal gained per ore`
}
}));
const efficientDrill = createUpgrade(() => ({
resource: noPersist(metal),
cost: 100000,
requirements: createCostRequirement(() => ({
resource: noPersist(metal),
cost: 100000
})),
display: {
title: "Efficient Drills",
description: `Use metal and a bunch of R&D to make drilling stuff faster. Double coal and ore mining speed.`
@ -495,19 +506,22 @@ const layer = createLayer(id, function (this: BaseLayer) {
}));
const oreDrill = createBuyable(() => ({
requirements: createCostRequirement(() => ({
resource: noPersist(metal),
cost() {
let v = new Decimal(oreDrill.amount.value);
v = Decimal.pow(0.95, paper.books.metalBook.totalAmount.value).times(v);
let cost = Decimal.pow(1.15, v).times(10);
if (management.elfTraining.metalElfTraining.milestones[4].earned.value) {
cost = Decimal.div(cost, Decimal.add(oil.depth.value, 1).sqrt());
}
if (management.elfTraining.metalElfTraining.milestones[3].earned.value) {
cost = Decimal.div(cost, 10);
}
return cost;
}
})),
resource: noPersist(metal),
cost() {
let v = new Decimal(this.amount.value);
v = Decimal.pow(0.95, paper.books.metalBook.totalAmount.value).times(v);
let cost = Decimal.pow(1.15, v).times(10);
if (management.elfTraining.metalElfTraining.milestones[4].earned.value) {
cost = Decimal.div(cost, Decimal.add(oil.depth.value, 1).sqrt());
}
if (management.elfTraining.metalElfTraining.milestones[3].earned.value) {
cost = Decimal.div(cost, 10);
}
return cost;
},
inverseCost(x: DecimalSource) {
if (management.elfTraining.metalElfTraining.milestones[3].earned.value) {
x = Decimal.mul(x, 10);
@ -537,21 +551,24 @@ const layer = createLayer(id, function (this: BaseLayer) {
.gte(10)
),
style: { width: "200px" }
})) as ElfBuyable & { resource: Resource };
})) as ElfBuyable;
const industrialCrucible = createBuyable(() => ({
requirements: createCostRequirement(() => ({
resource: noPersist(metal),
cost() {
let v = new Decimal(industrialCrucible.amount.value);
v = Decimal.pow(0.95, paper.books.metalBook.totalAmount.value).times(v);
let cost = Decimal.pow(1.15, Decimal.times(v, 10)).times(10);
if (management.elfTraining.metalElfTraining.milestones[4].earned.value) {
cost = Decimal.div(cost, Decimal.add(oil.depth.value, 1).sqrt());
}
if (management.elfTraining.metalElfTraining.milestones[3].earned.value) {
cost = Decimal.div(cost, 10);
}
return cost;
}
})),
resource: noPersist(metal),
cost() {
let v = new Decimal(this.amount.value);
v = Decimal.pow(0.95, paper.books.metalBook.totalAmount.value).times(v);
let cost = Decimal.pow(1.15, Decimal.times(v, 10)).times(10);
if (management.elfTraining.metalElfTraining.milestones[4].earned.value) {
cost = Decimal.div(cost, Decimal.add(oil.depth.value, 1).sqrt());
}
if (management.elfTraining.metalElfTraining.milestones[3].earned.value) {
cost = Decimal.div(cost, 10);
}
return cost;
},
inverseCost(x: DecimalSource) {
if (management.elfTraining.metalElfTraining.milestones[3].earned.value) {
x = Decimal.mul(x, 10);
@ -580,22 +597,25 @@ const layer = createLayer(id, function (this: BaseLayer) {
Decimal.gte(bestOre.value, 50)
),
style: { width: "200px" }
})) as ElfBuyable & { resource: Resource };
})) as ElfBuyable;
const autoSmeltEnabled = persistent<boolean>(true);
const hotterForge = createBuyable(() => ({
requirements: createCostRequirement(() => ({
resource: coal.coal,
cost() {
let v = new Decimal(hotterForge.amount.value);
v = Decimal.pow(0.95, paper.books.metalBook.totalAmount.value).times(v);
let cost = Decimal.pow(10, v).times(1e12);
if (management.elfTraining.metalElfTraining.milestones[4].earned.value) {
cost = Decimal.div(cost, Decimal.add(oil.depth.value, 1).sqrt());
}
if (management.elfTraining.metalElfTraining.milestones[3].earned.value) {
cost = Decimal.div(cost, 10);
}
return cost;
}
})),
resource: coal.coal,
cost() {
let v = new Decimal(this.amount.value);
v = Decimal.pow(0.95, paper.books.metalBook.totalAmount.value).times(v);
let cost = Decimal.pow(10, v).times(1e12);
if (management.elfTraining.metalElfTraining.milestones[4].earned.value) {
cost = Decimal.div(cost, Decimal.add(oil.depth.value, 1).sqrt());
}
if (management.elfTraining.metalElfTraining.milestones[3].earned.value) {
cost = Decimal.div(cost, 10);
}
return cost;
},
inverseCost(x: DecimalSource) {
if (management.elfTraining.metalElfTraining.milestones[3].earned.value) {
x = Decimal.mul(x, 10);
@ -621,7 +641,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
visibility: () =>
showIf(Decimal.gte(hotterForge.amount.value, 1) || industrialFurnace.bought.value),
style: { width: "200px" }
})) as ElfBuyable & { resource: Resource };
})) as ElfBuyable;
const hotterForgeEffect = computed(() => Decimal.times(hotterForge.amount.value, 0.25));
globalBus.on("update", diff => {

View file

@ -45,7 +45,8 @@ import toys from "./toys";
import factory from "./factory";
import reindeer from "./reindeer";
import routing from "./routing";
import packing from "./packing"
import packing from "./packing";
import { createCostRequirement } from "game/requirements";
const id = "oil";
const day = 9;
@ -107,43 +108,48 @@ const layer = createLayer(id, function (this: BaseLayer) {
const heavyPower = computed(() =>
Decimal.times(Decimal.pow(activeHeavy.value, heavy2Power.value), 1)
);
const heavyCost = computed(() => {
let v = new Decimal(buildHeavy.amount.value);
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 4).div(100 ** 3);
v = Decimal.pow(0.95, paper.books.heavyDrillBook.totalAmount.value).times(v);
return Decimal.pow(1.3, v).times(2.5e4);
});
const buildHeavy = createBuyable(() => ({
requirements: createCostRequirement(() => ({
resource: metal.metal,
cost: heavyCost
})),
resource: metal.metal,
cost() {
let v = new Decimal(this.amount.value);
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 4).div(100 ** 3);
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 ** 3).root(4);
return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0);
},
display: jsx(() => (
<>
<h3>Heavy Drill</h3>
<br />
A large drill specialized at deep mining.
<br />
Consumes 1e14*(Heavy Drills amount)
<sup>
{management.elfTraining.coalDrillElfTraining.milestones[0].earned.value
? 2.5
: 2}
</sup>{" "}
coal/sec for (Heavy Drills amount) drill power.
<br />
<br />
Currently:
<br />-{format(heavyCoal.value)} coal/sec
<br />+{format(heavyPower.value)} drill power
<br />
<br />
Cost: {formatWhole(unref(buildHeavy.cost!))} {buildHeavy.resource!.displayName}
</>
)),
display: {
title: "Heavy Drill",
description: jsx(() => (
<>
<div>A large drill specialized at deep mining.</div>
<br />
<div>
Consumes 1e14*(Heavy Drills amount)
<sup>
{management.elfTraining.coalDrillElfTraining.milestones[0].earned.value
? 2.5
: 2}
</sup>{" "}
coal/sec for (Heavy Drills amount) drill power.
</div>
</>
)),
effectDisplay: jsx(() => (
<>
<br />-{format(heavyCoal.value)} coal/sec
<br />+{format(heavyPower.value)} drill power
</>
))
},
onPurchase() {
activeHeavy.value = Decimal.add(activeHeavy.value, 1);
},
@ -153,7 +159,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
flexGrow: 1
},
visibility: () => showIf(!main.isMastery.value || masteryEffectActive.value)
})) as ElfBuyable & { resource: Resource };
})) as ElfBuyable;
const {
min: minHeavy,
max: maxHeavy,
@ -173,46 +179,49 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
return power;
});
const heavy2Cost = computed(() => {
let v = new Decimal(buildHeavy2.amount.value);
if (Decimal.gte(v, 50)) v = Decimal.pow(v, 4).div(50 ** 3);
v = Decimal.pow(0.95, paper.books.heavyDrillBook.totalAmount.value).times(v);
return Decimal.pow(2, v).times(1e5);
});
const buildHeavy2 = createBuyable(() => ({
requirements: createCostRequirement(() => ({
resource: metal.metal,
cost: heavy2Cost
})),
resource: metal.metal,
cost() {
let v = new Decimal(this.amount.value);
if (Decimal.gte(v, 50)) v = Decimal.pow(v, 4).div(50 ** 3);
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 ** 3).root(4);
return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0);
},
display: jsx(() => (
<>
<h3>Heavy Drill Drill</h3>
<br />
Attach extra drills to Heavy Drills to make them faster
<br />
Raise amount of effective Heavy Drills by ^
{management.elfTraining.heavyDrillElfTraining.milestones[3].earned.value ? (
<>
log<sub>2.5</sub>
</>
) : (
<>ln</>
)}
(Heavy Drill Drill amount + e).
<br />
(also affects coal consumption).
<br />
<br />
Currently:
<br />^{format(heavy2Power.value)} Heavy Drill amount
<br />
<br />
Cost: {formatWhole(unref(buildHeavy2.cost!))} {buildHeavy2.resource!.displayName}
</>
)),
display: {
title: "Heavy Drill Drill",
description: jsx(() => (
<div>
Attach extra drills to Heavy Drills to make them faster
<br />
Raise amount of effective Heavy Drills by ^
{management.elfTraining.heavyDrillElfTraining.milestones[3].earned.value ? (
<>
log<sub>2.5</sub>
</>
) : (
<>ln</>
)}
(Heavy Drill Drill amount + e).
<br />
(also affects coal consumption).
</div>
)),
effectDisplay: jsx(() => (
<>
<br />^{format(heavy2Power.value)} Heavy Drill amount
</>
))
},
onPurchase() {
activeHeavy2.value = Decimal.add(activeHeavy2.value, 1);
},
@ -221,7 +230,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
width: "160px",
flexGrow: 1
}
})) as ElfBuyable & { resource: Resource };
})) as ElfBuyable;
const {
min: minHeavy2,
max: maxHeavy2,
@ -238,39 +247,41 @@ const layer = createLayer(id, function (this: BaseLayer) {
);
const extractorCoal = computed(() => Decimal.pow(2, activeExtractor.value));
const extractorOre = computed(() => Decimal.pow(1.2, activeExtractor.value));
const extractorCost = computed(() => {
let v = new Decimal(buildExtractor.amount.value);
if (Decimal.gte(v, 10)) v = Decimal.pow(v, 4).div(10 ** 3);
v = Decimal.pow(0.95, paper.books.heavyDrillBook.totalAmount.value).times(v);
return Decimal.pow(8, v).times(2e5);
});
const buildExtractor = createBuyable(() => ({
requirements: createCostRequirement(() => ({
resource: metal.metal,
cost: extractorCost
})),
resource: metal.metal,
cost() {
let v = new Decimal(this.amount.value);
if (Decimal.gte(v, 10)) v = Decimal.pow(v, 4).div(10 ** 3);
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, 10)) v = Decimal.mul(v, 10 ** 3).root(4);
return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0);
},
display: jsx(() => (
<>
<h3>Heavy Extractor</h3>
<br />
Attach extractors to the drill to mine coal and ore, but with a price.
<br />
Divides drill power by 3 to multiply coal gain by 2 and ore gain by 1.2.
<br />
<br />
Currently:
<br />×{formatSmall(extractorPower.value)} drill power
<br />×{format(extractorCoal.value)} coal/sec
<br />×{format(extractorOre.value)} ore/sec
<br />
<br />
Cost: {formatWhole(unref(buildExtractor.cost!))}{" "}
{buildExtractor.resource!.displayName}
</>
)),
display: {
title: "Heavy Extractor",
description: jsx(() => (
<div>
Attach extractors to the drill to mine coal and ore, but with a price.
<br />
Divides drill power by 3 to multiply coal gain by 2 and ore gain by 1.2.
</div>
)),
effectDisplay: jsx(() => (
<>
<br />×{formatSmall(extractorPower.value)} drill power
<br />×{format(extractorCoal.value)} coal/sec
<br />×{format(extractorOre.value)} ore/sec
</>
))
},
onPurchase() {
activeExtractor.value = Decimal.add(activeExtractor.value, 1);
},
@ -279,7 +290,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
width: "160px",
flexGrow: 1
}
})) as ElfBuyable & { resource: Resource };
})) as ElfBuyable;
const {
min: minExtractor,
max: maxExtractor,
@ -310,21 +321,25 @@ const layer = createLayer(id, function (this: BaseLayer) {
)
.div(1e5)
);
const pumpCost = computed(() => {
let v = new Decimal(buildPump.amount.value);
if (Decimal.gte(v, 10)) v = Decimal.pow(v, 4).div(10 ** 3);
v = Decimal.pow(0.95, paper.books.oilBook.totalAmount.value).times(v);
let price = Decimal.pow(16, v).times(2e6);
if (row2Upgrades[4].bought.value) {
price = price.div(Decimal.add(totalOil.value, 1).root(6));
}
if (management.elfTraining.heavyDrillElfTraining.milestones[1].earned.value) {
price = price.div(10);
}
return price;
});
const buildPump = createBuyable(() => ({
requirements: createCostRequirement(() => ({
resource: metal.metal,
cost: pumpCost
})),
resource: metal.metal,
cost() {
let v = new Decimal(this.amount.value);
if (Decimal.gte(v, 10)) v = Decimal.pow(v, 4).div(10 ** 3);
v = Decimal.pow(0.95, paper.books.oilBook.totalAmount.value).times(v);
let price = Decimal.pow(16, v).times(2e6);
if (row2Upgrades[4].bought.value) {
price = price.div(Decimal.add(totalOil.value, 1).root(6));
}
if (management.elfTraining.heavyDrillElfTraining.milestones[1].earned.value) {
price = price.div(10);
}
return price;
},
inverseCost(x: DecimalSource) {
if (management.elfTraining.heavyDrillElfTraining.milestones[1].earned.value) {
x = Decimal.mul(x, 10);
@ -337,24 +352,23 @@ const layer = createLayer(id, function (this: BaseLayer) {
if (Decimal.gte(v, 10)) v = Decimal.mul(v, 10 ** 3).root(4);
return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0);
},
display: jsx(() => (
<>
<h3>Oil Pump</h3>
<br />
Pump that oil from the ground.
<br />
Gain oil based on the number of Heavy buildings active and well depth, but coal
usage is multiplied by {row2Upgrades[3].bought.value ? 4 : 5}×.
<br />
<br />
Currently:
<br />×{format(pumpCoal.value)} coal usage
<br />+{format(pumpOil.value)} oil/sec
<br />
<br />
Cost: {formatWhole(unref(buildPump.cost!))} {buildPump.resource!.displayName}
</>
)),
display: {
title: "Oil Pump",
description: jsx(() => (
<div>
Pump that oil from the ground.
<br />
Gain oil based on the number of Heavy buildings active and well depth, but coal
usage is multiplied by {row2Upgrades[3].bought.value ? 4 : 5}×.
</div>
)),
effectDisplay: jsx(() => (
<>
<br />×{format(pumpCoal.value)} coal usage
<br />+{format(pumpOil.value)} oil/sec
</>
))
},
onPurchase() {
activePump.value = Decimal.add(activePump.value, 1);
},
@ -363,7 +377,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
width: "160px",
flexGrow: 1
}
})) as ElfBuyable & { resource: Resource };
})) as ElfBuyable;
const {
max: maxPump,
min: minPump,
@ -387,45 +401,48 @@ const layer = createLayer(id, function (this: BaseLayer) {
);
const burnerCoal = computed(() => Decimal.pow(effectiveBurners.value, 3).mul(1e19));
const burnerMetal = computed(() => Decimal.add(effectiveBurners.value, 1));
const burnerCost = computed(() => {
let v = new Decimal(buildBurner.amount.value);
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 4).div(100 ** 3);
v = Decimal.pow(0.95, paper.books.oilBook.totalAmount.value).times(v);
return Decimal.pow(2, v).times(50);
});
const buildBurner = createBuyable(() => ({
requirements: createCostRequirement(() => ({
resource: noPersist(oil),
cost: burnerCost
})),
resource: noPersist(oil),
cost() {
let v = new Decimal(this.amount.value);
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 4).div(100 ** 3);
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 ** 3).root(4);
return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0);
},
display: jsx(() => (
<>
<h3>Oil Burner</h3>
<br />
Burn oil as fuel.
<br />
(Oil Burner Amount)<sup>2</sup> unit of oil can give 1e19*(Oil Burner Amount)
<sup>3</sup> units of coal.
<br />
<br />
Currently:
<br />-{format(burnerOil.value)} oil/sec
<br />-{format(burnerCoal.value)} coal consumption
{row2Upgrades[2].bought.value ? (
<>
<br />×{format(burnerMetal.value)} to auto smelting multi
</>
) : (
""
)}
<br />
<br />
Cost: {formatWhole(unref(buildBurner.cost!))} {buildBurner.resource!.displayName}
</>
)),
display: {
title: "Oil Burner",
description: jsx(() => (
<div>
Burn oil as fuel.
<br />
(Oil Burner Amount)<sup>2</sup> unit of oil can give 1e19*(Oil Burner Amount)
<sup>3</sup> units of coal.
</div>
)),
effectDisplay: jsx(() => (
<>
<br />-{format(burnerOil.value)} oil/sec
<br />-{format(burnerCoal.value)} coal consumption
{row2Upgrades[2].bought.value ? (
<>
<br />×{format(burnerMetal.value)} to auto smelting multi
</>
) : (
""
)}
</>
))
},
onPurchase() {
activeBurner.value = Decimal.add(activeBurner.value, 1);
},
@ -434,7 +451,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
width: "160px",
flexGrow: 1
}
})) as ElfBuyable & { resource: Resource };
})) as ElfBuyable;
const {
max: maxBurner,
min: minBurner,
@ -450,19 +467,22 @@ const layer = createLayer(id, function (this: BaseLayer) {
masteryEffectActive.value ? 0 : Decimal.pow(activeSmelter.value, 2).mul(100)
);
const smelterMetal = computed(() => Decimal.add(activeSmelter.value, 1));
const smelterCost = computed(() => {
let v = new Decimal(buildSmelter.amount.value);
if (Decimal.gte(v, 50)) v = Decimal.pow(v, 2).div(50);
if (Decimal.gte(v, 200)) v = Decimal.pow(v, 2).div(200);
if (Decimal.gte(v, 1e4)) v = Decimal.pow(v, 2).div(1e4);
v = Decimal.pow(0.95, paper.books.oilBook.totalAmount.value).times(v);
let price = Decimal.pow(10, v).times(1e7);
if (row2Upgrades[4].bought.value) price = price.div(Decimal.add(totalOil.value, 1).root(6));
return price;
});
const buildSmelter = createBuyable(() => ({
requirements: createCostRequirement(() => ({
resource: metal.metal,
cost: smelterCost
})),
resource: metal.metal,
cost() {
let v = new Decimal(this.amount.value);
if (Decimal.gte(v, 50)) v = Decimal.pow(v, 2).div(50);
if (Decimal.gte(v, 200)) v = Decimal.pow(v, 2).div(200);
if (Decimal.gte(v, 1e4)) v = Decimal.pow(v, 2).div(1e4);
v = Decimal.pow(0.95, paper.books.oilBook.totalAmount.value).times(v);
let price = Decimal.pow(10, v).times(1e7);
if (row2Upgrades[4].bought.value)
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));
@ -474,23 +494,22 @@ const layer = createLayer(id, function (this: BaseLayer) {
if (Decimal.gte(v, 50)) v = Decimal.mul(v, 50).root(2);
return Decimal.isNaN(v) ? Decimal.dZero : v.floor().max(0);
},
display: jsx(() => (
<>
<h3>Oil Smelter</h3>
<br />
Use oil as a crucible fuel.
<br />
Burn 100*(Oil Smelter amount)<sup>2</sup> oil to smelt +100% faster.
<br />
<br />
Currently:
<br />-{format(smelterOil.value)} oil/sec
<br />×{format(smelterMetal.value)} smelting speed
<br />
<br />
Cost: {formatWhole(unref(buildSmelter.cost!))} {buildSmelter.resource!.displayName}
</>
)),
display: {
title: "Oil Smelter",
description: jsx(() => (
<div>
Use oil as a crucible fuel.
<br />
Burn 100*(Oil Smelter amount)<sup>2</sup> oil to smelt +100% faster.
</div>
)),
effectDisplay: jsx(() => (
<>
<br />-{format(smelterOil.value)} oil/sec
<br />×{format(smelterMetal.value)} smelting speed
</>
))
},
onPurchase() {
activeSmelter.value = Decimal.add(activeSmelter.value, 1);
},
@ -499,7 +518,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
width: "160px",
flexGrow: 1
}
})) as ElfBuyable & { resource: Resource };
})) as ElfBuyable;
const {
max: maxSmelter,
@ -621,8 +640,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
const row1Upgrades: GenericUpgrade[] = [
createUpgrade(() => ({
resource: coal.coal,
cost: 1e18,
requirements: createCostRequirement(() => ({
resource: coal.coal,
cost: 1e18
})),
display: {
title: "Coal Drill Synergy",
description: "Increase drill power by +4% per Coal Drill owned.",
@ -633,8 +654,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
})),
createUpgrade(() => ({
resource: metal.metal,
cost: 150000,
requirements: createCostRequirement(() => ({
resource: metal.metal,
cost: 150000
})),
display: {
title: "Metal Drill Synergy",
description: "Increase drill power by +4% per Metal Drill owned.",
@ -645,8 +668,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
})),
createUpgrade(() => ({
resource: coal.coal,
cost: 1e20,
requirements: createCostRequirement(() => ({
resource: coal.coal,
cost: 1e20
})),
display: {
title: "Coal Drill Upgrade",
description: "Increase drill power by +6% per OoM of coal owned.",
@ -657,8 +682,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
})),
createUpgrade(() => ({
resource: metal.metal,
cost: 1500000,
requirements: createCostRequirement(() => ({
resource: metal.metal,
cost: 1500000
})),
display: {
title: "Metal Drill Upgrade",
description: "Increase drill power by +10% per OoM of metal ingot owned.",
@ -669,8 +696,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
})),
createUpgrade(() => ({
resource: noPersist(oil),
cost: 100,
requirements: createCostRequirement(() => ({
resource: noPersist(oil),
cost: 100
})),
display: {
title: "Drill Oil",
description: "Increase previous upgrades' effect by +0.1% per Heavy Drill owned.",
@ -713,8 +742,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
const row2Upgrades = [
createUpgrade(() => ({
resource: noPersist(oil),
cost: 100,
requirements: createCostRequirement(() => ({
resource: noPersist(oil),
cost: 100
})),
display: {
title: "Oil the Oil Pump",
description: "Double oil gain."
@ -724,8 +755,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
})),
createUpgrade(() => ({
resource: noPersist(oil),
cost: 500,
requirements: createCostRequirement(() => ({
resource: noPersist(oil),
cost: 500
})),
display: {
title: "Oil the Metal Drills",
description:
@ -736,8 +769,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
})),
createUpgrade(() => ({
resource: noPersist(oil),
cost: 1500,
requirements: createCostRequirement(() => ({
resource: noPersist(oil),
cost: 1500
})),
display: {
title: "Blaster Burner",
description: "The Oil Burner can now increase your auto smelting multi."
@ -747,8 +782,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
})),
createUpgrade(() => ({
resource: noPersist(oil),
cost: 25000,
requirements: createCostRequirement(() => ({
resource: noPersist(oil),
cost: 25000
})),
display: {
title: "Oil Integration",
description: "Reduce Oil Pump's coal consumption multipler from 5 to 4"
@ -758,8 +795,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
})),
createUpgrade(() => ({
resource: noPersist(oil),
cost: 50000,
requirements: createCostRequirement(() => ({
resource: noPersist(oil),
cost: 50000
})),
display: {
title: "Be One with the Oil",
description: jsx(() => (
@ -776,8 +815,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
];
const row3Upgrades = [
createUpgrade(() => ({
resource: noPersist(oil),
cost: 1e13,
requirements: createCostRequirement(() => ({
resource: noPersist(oil),
cost: 1e13
})),
display: {
title: "Dye Synergy I",
description: "Red dye boosts yellow dye gain by (log(x)^0.75)"
@ -789,8 +830,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
})),
createUpgrade(() => ({
resource: noPersist(oil),
cost: 1e14,
requirements: createCostRequirement(() => ({
resource: noPersist(oil),
cost: 1e14
})),
display: {
title: "Orange-colored boxes",
description: "Orange dye's 2nd effect is raised to the 2.5"
@ -802,8 +845,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
})),
createUpgrade(() => ({
resource: noPersist(oil),
cost: 1e15,
requirements: createCostRequirement(() => ({
resource: noPersist(oil),
cost: 1e15
})),
display: {
title: "Colorful Plastic",
description: jsx(() => (
@ -820,8 +865,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
})),
createUpgrade(() => ({
resource: noPersist(oil),
cost: 1e16,
requirements: createCostRequirement(() => ({
resource: noPersist(oil),
cost: 1e16
})),
display: {
title: "Dye Synergy II",
description: "Blue dye boosts red dye gain by log(x)"
@ -833,8 +880,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
})),
createUpgrade(() => ({
resource: noPersist(oil),
cost: 1e17,
requirements: createCostRequirement(() => ({
resource: noPersist(oil),
cost: 1e17
})),
display: {
title: "The Ultimate Metal Dye",
description: "Sum of primary dyes boosts auto smelt speed"

View file

@ -32,6 +32,7 @@ import ModalVue from "components/Modal.vue";
import ribbon from "./ribbon";
import { createReset } from "features/reset";
import ResourceVue from "features/resources/Resource.vue";
import { createCostRequirement } from "game/requirements";
const id = "packing";
const day = 24;
@ -198,105 +199,67 @@ const layer = createLayer(id, function (this: BaseLayer) {
const computedLoaderPackingSpeed = computed(() => loaderPackingSpeed.apply(1000));
const elf = createBuyable(() => ({
visibility: () => showIf(Decimal.gte(totalPresents.value, 10)),
cost() {
let v = this.amount.value;
v = Decimal.pow(0.98, paper.books.packingBook.totalAmount.value).times(v);
return Decimal.pow(1.2, v).times(10).floor();
},
requirements: createCostRequirement(() => ({
resource: totalPresentsResource,
cost() {
let v = elf.amount.value;
v = Decimal.pow(0.98, paper.books.packingBook.totalAmount.value).times(v);
return Decimal.pow(1.2, v).times(10).floor();
},
requiresPay: false
})),
resource: totalPresentsResource,
inverseCost(cost: DecimalSource) {
let amount = Decimal.div(cost, 10).log(1.2);
amount = amount.div(Decimal.pow(0.98, paper.books.packingBook.totalAmount.value));
return Decimal.isNaN(amount) ? Decimal.dZero : amount.floor().max(0);
},
resource: totalPresentsResource,
display: jsx(() => (
<>
<div>
<h3>Hire an elf assistant</h3>
</div>
Packs {format(computedElfPackingSpeed.value)} presents per second
<div>
<br />
Amount: {formatWhole(helpers.elf.amount.value)}
</div>
<div>
<br />
Currently packing{" "}
{format(
Decimal.times(helpers.elf.amount.value, computedElfPackingSpeed.value)
)}{" "}
presents per second
</div>
<div>
Requires: {formatWhole(unref(helpers.elf.cost!))}{" "}
{helpers.elf.resource!.displayName}
</div>
</>
)),
display: {
title: "Hire an elf assistant",
description: jsx(() => <>Packs {format(computedElfPackingSpeed.value)} presents/s</>),
effectDisplay: jsx(() => (
<>
{format(Decimal.times(helpers.elf.amount.value, computedElfPackingSpeed.value))}{" "}
presents/s
</>
))
},
style: {
width: "200px"
}
})) as ElfBuyable;
const loader = createBuyable(() => ({
visibility: () => showIf(upgrades.loaderUnlock.bought.value),
metalCost: computed(() => Decimal.pow(1.2, helpers.loader.amount.value).times(1e70)),
oilCost: computed(() => Decimal.pow(1.2, helpers.loader.amount.value).times(1e25)),
canPurchase(
this: GenericBuyable & {
metalCost: ComputedRef<DecimalSource>;
oilCost: ComputedRef<DecimalSource>;
}
) {
return (
Decimal.gte(metal.metal.value, this.metalCost.value) &&
Decimal.gte(oil.oil.value, this.oilCost.value)
);
},
onPurchase() {
const metalCost = Decimal.pow(1.2, Decimal.sub(helpers.loader.amount.value, 1)).times(
1e70
);
const oilCost = Decimal.pow(1.2, Decimal.sub(helpers.loader.amount.value, 1)).times(
1e25
);
metal.metal.value = Decimal.sub(metal.metal.value, metalCost);
oil.oil.value = Decimal.sub(oil.oil.value, oilCost);
},
requirements: [
createCostRequirement(() => ({
resource: metal.metal,
cost: () => Decimal.pow(1.2, helpers.loader.amount.value).times(1e70)
})),
createCostRequirement(() => ({
resource: oil.oil,
cost: () => Decimal.pow(1.2, helpers.loader.amount.value).times(1e25)
}))
],
inverseCost() {
const metalAmount = Decimal.div(metal.metal.value, 1e70).log(1.2);
const oilAmount = Decimal.div(oil.oil.value, 1e25).log(1.2);
if (Decimal.isNaN(metalAmount) || Decimal.isNaN(oilAmount)) return Decimal.dZero;
return Decimal.min(metalAmount, oilAmount).floor().max(0);
},
display: jsx(() => (
<>
<div>
<h3>Build a loader</h3>
</div>
Loads {format(computedLoaderPackingSpeed.value)} presents per second
<div>
<br />
Amount: {formatWhole(helpers.loader.amount.value)}
</div>
<div>
<br />
Currently packing{" "}
display: {
title: "Build a loader",
description: jsx(() => (
<>Loads {format(computedLoaderPackingSpeed.value)} presents/s</>
)),
effectDisplay: jsx(() => (
<>
{format(
Decimal.times(helpers.loader.amount.value, computedLoaderPackingSpeed.value)
)}{" "}
persents per second
</div>
<div>
Cost:{" "}
{displayCost(
metal.metal,
helpers.loader.metalCost.value,
metal.metal.displayName
)}
,{displayCost(oil.oil, helpers.loader.oilCost.value, oil.oil.displayName)}
</div>
</>
)),
persents/s
</>
))
},
style: {
width: "200px"
}
@ -312,8 +275,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
title: "An Elf's Elf",
description: "Train an Elf to help you hire more Elves."
},
cost: 1000,
resource: totalPresentsResource,
requirements: createCostRequirement(() => ({
cost: 1000,
resource: totalPresentsResource,
requiresPay: false
})),
style: {
width: "200px"
},
@ -331,8 +297,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
description:
"Those construction vehicles you have from building the workshop should be useful for loading presents too."
},
cost: 1000000,
resource: totalPresentsResource,
requirements: createCostRequirement(() => ({
cost: 1000000,
resource: totalPresentsResource,
requiresPay: false
})),
style: {
width: "200px"
},
@ -345,8 +314,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
title: "Communal Assistance",
description: "Each elf level increases elf packing speed by 5%"
},
cost: 100000000,
resource: totalPresentsResource,
requirements: createCostRequirement(() => ({
cost: 100000000,
resource: totalPresentsResource,
requiresPay: false
})),
style: {
width: "200px"
},
@ -361,8 +333,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
title: "Spare Bows",
description: "Each ribbon multiplies elf packing speed by 1.02x"
},
cost: 2e9,
resource: totalPresentsResource,
requirements: createCostRequirement(() => ({
cost: 2e9,
resource: totalPresentsResource,
requiresPay: false
})),
style: {
width: "200px"
},
@ -376,8 +351,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
description:
"Each elf assistant increases how much the loader can load per second by 5"
},
cost: 5e9,
resource: totalPresentsResource,
requirements: createCostRequirement(() => ({
cost: 5e9,
resource: totalPresentsResource,
requiresPay: false
})),
style: {
width: "200px"
},
@ -391,8 +369,11 @@ const layer = createLayer(id, function (this: BaseLayer) {
description:
"Each present manually packed gives 2 seconds of automatic present packing production"
},
cost: 1e10,
resource: totalPresentsResource,
requirements: createCostRequirement(() => ({
cost: 1e10,
resource: totalPresentsResource,
requiresPay: false
})),
style: {
width: "200px"
},

View file

@ -17,6 +17,7 @@ import { globalBus } from "game/events";
import { BaseLayer, createLayer } from "game/layers";
import { createMultiplicativeModifier, createSequentialModifier, Modifier } from "game/modifiers";
import { noPersist, persistent } from "game/persistence";
import { createCostRequirement } from "game/requirements";
import Decimal, { DecimalSource, format, formatSmall, formatWhole } from "util/bignum";
import { WithRequired } from "util/common";
import { render, renderCol, renderGrid } from "util/vue";
@ -115,34 +116,38 @@ const layer = createLayer(id, function (this: BaseLayer) {
)),
showAmount: false
},
requirements: createCostRequirement(() => ({
resource: noPersist(paper),
cost() {
let v = buyable.amount.value;
if (options.elfName === "Star" && Decimal.gte(v, 10))
v = Decimal.pow(10, Decimal.div(v, 10));
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.totalAmount.value).times(v);
let scaling = 5;
if (management.elfTraining.paperElfTraining.milestones[2].earned.value) {
scaling--;
}
let cost = Decimal.pow(scaling, v).times(10);
if (["Peppermint", "Twinkle", "Cocoa", "Frosty"].includes(options.elfName)) {
cost = cost.mul(1e31);
}
if (["Jingle"].includes(options.elfName)) {
cost = cost.mul(1e123);
}
if (management.elfTraining.paperElfTraining.milestones[0].earned.value) {
cost = Decimal.div(cost, sumBooks.value.max(1));
}
if (bookUpgrade.bought.value) {
cost = cost.div(10);
}
return cost;
}
})),
resource: noPersist(paper),
cost() {
let v = buyable.amount.value;
if (options.elfName === "Star" && Decimal.gte(v, 10))
v = Decimal.pow(10, Decimal.div(v, 10));
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.totalAmount.value).times(v);
let scaling = 5;
if (management.elfTraining.paperElfTraining.milestones[2].earned.value) {
scaling--;
}
let cost = Decimal.pow(scaling, v).times(10);
if (["Peppermint", "Twinkle", "Cocoa", "Frosty"].includes(options.elfName)) {
cost = cost.mul(1e31);
}
if (["Jingle"].includes(options.elfName)) {
cost = cost.mul(1e123);
}
if (management.elfTraining.paperElfTraining.milestones[0].earned.value) {
cost = Decimal.div(cost, sumBooks.value.max(1));
}
if (bookUpgrade.bought.value) {
cost = cost.div(10);
}
return cost;
},
inverseCost(x: DecimalSource) {
if (bookUpgrade.bought.value) {
x = Decimal.mul(x, 10);
@ -196,7 +201,6 @@ const layer = createLayer(id, function (this: BaseLayer) {
),
totalAmount: computed(() => Decimal.add(buyable.amount.value, buyable.freeLevels.value))
})) as ElfBuyable & {
resource: Resource;
freeLevels: ComputedRef<DecimalSource>;
totalAmount: ComputedRef<DecimalSource>;
};
@ -317,7 +321,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
elfName: "Jingle",
buyableName: "Elf Assistants",
visibility: () => showIf(packing.upgrades.packingElf.bought.value)
})
});
const books = {
cuttersBook,
plantersBook,
@ -345,8 +349,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
);
const clothUpgrade = createUpgrade(() => ({
resource: noPersist(paper),
cost: 1e8,
requirements: createCostRequirement(() => ({
resource: noPersist(paper),
cost: 1e8
})),
visibility: () => showIf(plastic.upgrades.paperTools.bought.value),
display: {
title: "Shepherding for Dummies",
@ -354,8 +360,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const drillingUpgrade = createUpgrade(() => ({
resource: noPersist(paper),
cost: 1e9,
requirements: createCostRequirement(() => ({
resource: noPersist(paper),
cost: 1e9
})),
visibility: () => showIf(plastic.upgrades.paperTools.bought.value),
display: {
title: "Guide to drilling",
@ -363,8 +371,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const oilUpgrade = createUpgrade(() => ({
resource: noPersist(paper),
cost: 1e10,
requirements: createCostRequirement(() => ({
resource: noPersist(paper),
cost: 1e10
})),
visibility: () => showIf(plastic.upgrades.paperTools.bought.value),
display: {
title: "Oil and where to find it",
@ -373,8 +383,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}));
const upgrades = { clothUpgrade, drillingUpgrade, oilUpgrade };
const ashUpgrade = createUpgrade(() => ({
resource: noPersist(paper),
cost: 1e36,
requirements: createCostRequirement(() => ({
resource: noPersist(paper),
cost: 1e36
})),
visibility: () =>
showIf(management.elfTraining.heavyDrillElfTraining.milestones[4].earned.value),
display: {
@ -383,8 +395,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
})) as GenericUpgrade;
const bookUpgrade = createUpgrade(() => ({
resource: noPersist(paper),
cost: 1e38,
requirements: createCostRequirement(() => ({
resource: noPersist(paper),
cost: 1e38
})),
visibility: () =>
showIf(management.elfTraining.heavyDrillElfTraining.milestones[4].earned.value),
display: {
@ -393,8 +407,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const treeUpgrade = createUpgrade(() => ({
resource: noPersist(paper),
cost: 1e40,
requirements: createCostRequirement(() => ({
resource: noPersist(paper),
cost: 1e40
})),
visibility: () =>
showIf(management.elfTraining.heavyDrillElfTraining.milestones[4].earned.value),
display: {

View file

@ -41,6 +41,7 @@ import reindeer from "./reindeer";
import sleigh from "./sleigh";
import factory from "./factory";
import routing from "./routing";
import { createCostRequirement } from "game/requirements";
const id = "plastic";
const day = 10;
@ -77,34 +78,37 @@ const layer = createLayer(id, function (this: BaseLayer) {
management.elfTraining.oilElfTraining.milestones[3].earned.value ? 5 : 1
)
) as ComputedRef<DecimalSource>;
const refineryCost = computed(() => {
const v = new Decimal(buildRefinery.amount.value);
let cost = Decimal.pow(1.2, v).times(1e7);
if (management.elfTraining.fertilizerElfTraining.milestones[3].earned.value) {
cost = Decimal.sub(cost, Decimal.pow(plastic.value, 2)).max(0);
}
return cost;
});
const buildRefinery = createBuyable(() => ({
requirements: createCostRequirement(() => ({
resource: metal.metal,
cost: refineryCost
})),
resource: metal.metal,
cost() {
const v = new Decimal(this.amount.value);
let cost = Decimal.pow(1.2, v).times(1e7);
if (management.elfTraining.fertilizerElfTraining.milestones[3].earned.value) {
cost = Decimal.sub(cost, Decimal.pow(plastic.value, 2)).max(0);
}
return cost;
display: {
title: "Refinery",
description: jsx(() => (
<div>
Refines oil into plastic pellets
<br />
Consumes 100 oil/s to create 1 plastic/s
</div>
)),
effectDisplay: jsx(() => (
<>
<br />-{format(oilCost.value)} oil/sec
<br />+{format(activeRefinery.value)} plastic/sec
</>
)),
showAmount: false
},
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);
},
@ -136,8 +140,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
)
);
const paperTools = createUpgrade(() => ({
resource: noPersist(plastic),
cost: upgradeCost,
requirements: createCostRequirement(() => ({
resource: noPersist(plastic),
cost: upgradeCost
})),
display: () => ({
title: "Plastic Scissors",
description: "Unlock paper upgrades",
@ -145,8 +151,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
})
})) as GenericUpgrade;
const boxTools = createUpgrade(() => ({
resource: noPersist(plastic),
cost: upgradeCost,
requirements: createCostRequirement(() => ({
resource: noPersist(plastic),
cost: upgradeCost
})),
display: () => ({
title: "Plastic Level",
description: "Unlock box upgrades",
@ -154,8 +162,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
})
})) as GenericUpgrade;
const clothTools = createUpgrade(() => ({
resource: noPersist(plastic),
cost: upgradeCost,
requirements: createCostRequirement(() => ({
resource: noPersist(plastic),
cost: upgradeCost
})),
display: () => ({
title: "Plastic Cane",
description: "Unlock cloth upgrades",
@ -165,8 +175,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
const upgrades = { paperTools, boxTools, clothTools };
const paperElf = createUpgrade(() => ({
resource: noPersist(plastic),
cost: upgradeCost,
requirements: createCostRequirement(() => ({
resource: noPersist(plastic),
cost: upgradeCost
})),
visibility: () => showIf(paperTools.bought.value),
display: () => ({
title: "Paper Elf Recruitment",
@ -180,8 +192,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
})) as GenericUpgrade;
const boxElf = createUpgrade(() => ({
resource: noPersist(plastic),
cost: upgradeCost,
requirements: createCostRequirement(() => ({
resource: noPersist(plastic),
cost: upgradeCost
})),
visibility: () => showIf(boxTools.bought.value),
display: () => ({
title: "Box Elf Recruitment",
@ -195,8 +209,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
})) as GenericUpgrade;
const clothElf = createUpgrade(() => ({
resource: noPersist(plastic),
cost: upgradeCost,
requirements: createCostRequirement(() => ({
resource: noPersist(plastic),
cost: upgradeCost
})),
visibility: () => showIf(clothTools.bought.value),
display: () => ({
title: "Cloth Elf Recruitment",
@ -212,12 +228,15 @@ const layer = createLayer(id, function (this: BaseLayer) {
const elfUpgrades = { paperElf, boxElf, clothElf };
const passivePaper = createBuyable(() => ({
requirements: createCostRequirement(() => ({
resource: noPersist(plastic),
cost() {
let v = passivePaper.amount.value;
v = Decimal.pow(0.95, paper.books.plasticBook.totalAmount.value).times(v);
return Decimal.pow(1.3, v).times(100).div(dyes.boosts.blue2.value);
}
})),
resource: noPersist(plastic),
cost() {
let v = passivePaper.amount.value;
v = Decimal.pow(0.95, paper.books.plasticBook.totalAmount.value).times(v);
return Decimal.pow(1.3, v).times(100).div(dyes.boosts.blue2.value);
},
inverseCost(x: DecimalSource) {
let v = Decimal.times(x, dyes.boosts.blue2.value).div(100).log(1.3);
v = v.div(Decimal.pow(0.95, paper.books.plasticBook.totalAmount.value));
@ -245,12 +264,15 @@ const layer = createLayer(id, function (this: BaseLayer) {
)
})) as BoxesBuyable;
const passiveBoxes = createBuyable(() => ({
requirements: createCostRequirement(() => ({
resource: noPersist(plastic),
cost() {
let v = passiveBoxes.amount.value;
v = Decimal.pow(0.95, paper.books.plasticBook.totalAmount.value).times(v);
return Decimal.pow(1.3, v).times(100).div(dyes.boosts.blue2.value);
}
})),
resource: noPersist(plastic),
cost() {
let v = passiveBoxes.amount.value;
v = Decimal.pow(0.95, paper.books.plasticBook.totalAmount.value).times(v);
return Decimal.pow(1.3, v).times(100).div(dyes.boosts.blue2.value);
},
inverseCost(x: DecimalSource) {
let v = Decimal.times(x, dyes.boosts.blue2.value).div(100).log(1.3);
v = v.div(Decimal.pow(0.95, paper.books.plasticBook.totalAmount.value));
@ -278,12 +300,15 @@ const layer = createLayer(id, function (this: BaseLayer) {
)
})) as BoxesBuyable;
const clothGains = createBuyable(() => ({
requirements: createCostRequirement(() => ({
resource: noPersist(plastic),
cost() {
let v = clothGains.amount.value;
v = Decimal.pow(0.95, paper.books.plasticBook.totalAmount.value).times(v);
return Decimal.pow(1.3, v).times(100).div(dyes.boosts.blue2.value);
}
})),
resource: noPersist(plastic),
cost() {
let v = clothGains.amount.value;
v = Decimal.pow(0.95, paper.books.plasticBook.totalAmount.value).times(v);
return Decimal.pow(1.3, v).times(100).div(dyes.boosts.blue2.value);
},
inverseCost(x: DecimalSource) {
let v = Decimal.times(x, dyes.boosts.blue2.value).div(100).log(1.3);
v = v.div(Decimal.pow(0.95, paper.books.plasticBook.totalAmount.value));

View file

@ -20,6 +20,7 @@ import {
createSequentialModifier
} from "game/modifiers";
import { persistent } from "game/persistence";
import { createCostRequirement } from "game/requirements";
import Decimal, { DecimalSource, format, formatTime, formatWhole } from "util/bignum";
import { Direction } from "util/common";
import { render, renderGrid } from "util/vue";
@ -327,8 +328,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
);
const upgrade1 = createUpgrade(() => ({
resource: trees.logs,
cost: 1e97,
requirements: createCostRequirement(() => ({
resource: trees.logs,
cost: 1e97
})),
style: {
width: "160px"
},
@ -339,8 +342,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const upgrade2 = createUpgrade(() => ({
resource: coal.coal,
cost: 1e167,
requirements: createCostRequirement(() => ({
resource: coal.coal,
cost: 1e167
})),
style: {
width: "160px"
},
@ -351,8 +356,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const upgrade3 = createUpgrade(() => ({
resource: paper.paper,
cost: 1e117,
requirements: createCostRequirement(() => ({
resource: paper.paper,
cost: 1e117
})),
style: {
width: "160px"
},
@ -363,8 +370,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const upgrade4 = createUpgrade(() => ({
resource: boxes.boxes,
cost: 1e102,
requirements: createCostRequirement(() => ({
resource: boxes.boxes,
cost: 1e102
})),
style: {
width: "160px"
},
@ -375,8 +384,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const upgrade5 = createUpgrade(() => ({
resource: metal.metal,
cost: 1e67,
requirements: createCostRequirement(() => ({
resource: metal.metal,
cost: 1e67
})),
style: {
width: "160px"
},
@ -387,8 +398,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const upgrade6 = createUpgrade(() => ({
resource: cloth.cloth,
cost: 1e20,
requirements: createCostRequirement(() => ({
resource: cloth.cloth,
cost: 1e20
})),
style: {
width: "160px"
},
@ -399,8 +412,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const upgrade7 = createUpgrade(() => ({
resource: oil.oil,
cost: 4e25,
requirements: createCostRequirement(() => ({
resource: oil.oil,
cost: 4e25
})),
style: {
width: "160px"
},
@ -411,8 +426,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const upgrade8 = createUpgrade(() => ({
resource: plastic.plastic,
cost: 1e22,
requirements: createCostRequirement(() => ({
resource: plastic.plastic,
cost: 1e22
})),
style: {
width: "160px"
},
@ -422,8 +439,13 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const upgrade9 = createUpgrade(() => ({
resource: dyes.dyes.white.amount,
cost: 7.5e7,
requirements: createCostRequirement(() => ({
resource: dyes.dyes.white.amount,
cost: 7.5e7,
pay() {
dyes.dyes.white.buyable.amount.value = 0;
}
})),
style: {
width: "160px"
},

View file

@ -33,6 +33,7 @@ import management from "./management";
import metal from "./metal";
import "./styles/routing.css";
import Fraction from "components/math/Fraction.vue";
import { createCostRequirement } from "game/requirements";
const alpha = [
"A",
@ -600,102 +601,81 @@ const layer = createLayer(id, function (this: BaseLayer) {
// ---------------------------------------------------- Meta stuff
const metalCost = computed(() => {
const amount = Decimal.mul(metaBuyables.metal.amount.value, 1.05);
return Decimal.pow(5, amount).mul(1e83).div(Decimal.max(citiesCompleted.value, 1));
});
const consolesCost = computed(() => {
const amount = Decimal.mul(metaBuyables.console.amount.value, 1.15);
return Decimal.pow(1.2, amount).mul(1e11).div(Decimal.max(citiesCompleted.value, 1));
});
const metaBuyables = {
metal: createBuyable(() => ({
resName: "Metal",
resource: metal.metal,
cost() {
const amount = Decimal.mul(this.amount.value, 1.05);
return Decimal.pow(5, amount).mul(1e83).div(Decimal.max(citiesCompleted.value, 1));
requirements: createCostRequirement(() => ({
resource: metal.metal,
cost: metalCost
})),
display: {
description: "Upgrade computer",
effectDisplay: jsx(() => (
<>+{formatWhole(Decimal.mul(metaBuyables.metal.amount.value, 10))}%</>
))
},
display: jsx(() => (
<>
Upgrade computer
<br />
for {formatWhole(unref(metaBuyables.metal.cost ?? 0))} metal
<br />
Currently +{formatWhole(Decimal.mul(metaBuyables.metal.amount.value, 10))}%
</>
)),
style: "width: 150px; min-height: 60px"
})),
console: createBuyable(() => ({
resName: "Game Console",
resource: factory.consoles,
cost() {
const amount = Decimal.mul(this.amount.value, 1.15);
return Decimal.pow(1.2, amount)
.mul(1e11)
.div(Decimal.max(citiesCompleted.value, 1));
requirements: createCostRequirement(() => ({
resource: factory.consoles,
cost: consolesCost
})),
display: {
description: "Upgrade computer",
effectDisplay: jsx(() => (
<>+{formatWhole(Decimal.mul(metaBuyables.console.amount.value, 10))}%</>
))
},
display: jsx(() => (
<>
Upgrade computer
<br />
for {formatWhole(unref(metaBuyables.console.cost ?? 0))} game consoles
<br />
Currently +{formatWhole(Decimal.mul(metaBuyables.console.amount.value, 10))}%
</>
)),
style: "width: 150px; min-height: 60px"
})),
classroom: createBuyable(() => ({
resName: "Classroom",
cost() {
const amount = Decimal.mul(this.amount.value, 1.25);
return Decimal.pow(1.2, amount)
.mul(1e6)
.div(Decimal.max(citiesCompleted.value, 1).pow(0.5));
requirements: createCostRequirement(() => ({
resource: createResource(management.classrooms.amount, "classrooms"),
cost() {
const amount = Decimal.mul(metaBuyables.classroom.amount.value, 1.25);
return Decimal.pow(1.2, amount)
.mul(1e6)
.div(Decimal.max(citiesCompleted.value, 1).pow(0.5));
}
})),
display: {
description: "Upgrade computer",
effectDisplay: jsx(() => (
<>+{formatWhole(Decimal.mul(metaBuyables.classroom.amount.value, 10))}%</>
))
},
canPurchase() {
return Decimal.gte(
management.classrooms.amount.value,
unref(metaBuyables.classroom.cost ?? 0)
);
},
onPurchase() {
// Lower amount first so costs are accurate, then re-add the purchase after
this.amount.value = Decimal.add(this.amount.value, -1);
management.classrooms.amount.value = Decimal.sub(
management.classrooms.amount.value,
unref(metaBuyables.classroom.cost ?? 0)
);
this.amount.value = Decimal.add(this.amount.value, 1);
},
display: jsx(() => (
<>
Upgrade computer
<br />
for {formatWhole(unref(metaBuyables.classroom.cost ?? 0))} classrooms
<br />
Currently +{formatWhole(Decimal.mul(metaBuyables.classroom.amount.value, 10))}%
</>
)),
style: "width: 150px; min-height: 60px"
})),
tick: createBuyable(() => ({
resName: "Factory Tick Rate",
cost() {
const amount = Decimal.mul(this.amount.value, 1.15);
return Decimal.pow(1.5, amount)
.mul(5e6)
.div(Decimal.max(citiesCompleted.value, 1).pow(0.5));
requirements: createCostRequirement(() => ({
resource: createResource(factory.computedTickRate, "factory tick rate"),
cost() {
const amount = Decimal.mul(metaBuyables.tick.amount.value, 1.15);
return Decimal.pow(1.5, amount)
.mul(5e6)
.div(Decimal.max(citiesCompleted.value, 1).pow(0.5));
},
requiresPay: false
})),
display: {
description: "Upgrade computer",
effectDisplay: jsx(() => (
<>+{formatWhole(Decimal.mul(metaBuyables.tick.amount.value, 10))}%</>
))
},
canPurchase() {
return Decimal.gte(
factory.computedTickRate.value,
unref(metaBuyables.tick.cost ?? 0)
);
},
display: jsx(() => (
<>
Upgrade computer
<br />
for {formatWhole(unref(metaBuyables.tick.cost ?? 0))} factory tick rate
<br />
Currently +{formatWhole(Decimal.mul(metaBuyables.tick.amount.value, 10))}%
</>
)),
style: "width: 150px; min-height: 60px"
}))
} as Record<string, GenericBuyable & { resName: string }>;

View file

@ -2,24 +2,25 @@
* @module
* @hidden
*/
import { isArray } from "@vue/shared";
import Spacer from "components/layout/Spacer.vue";
import { createCollapsibleMilestones } from "data/common";
import { main } from "data/projEntry";
import { createBar } from "features/bars/bar";
import { createBuyable, GenericBuyable } from "features/buyable";
import { jsx, showIf } from "features/feature";
import { createMilestone } from "features/milestones/milestone";
import { Resource } from "features/resources/resource";
import { BaseLayer, createLayer } from "game/layers";
import { createCostRequirement } from "game/requirements";
import Decimal, { DecimalSource, format, formatWhole } from "util/bignum";
import { Direction } from "util/common";
import { render } from "util/vue";
import { computed, watchEffect } from "vue";
import management from "./management";
import trees from "./trees";
import metal from "./metal";
import plastic from "./plastic";
import { createBuyable, GenericBuyable } from "features/buyable";
import { Resource } from "features/resources/resource";
import { isArray } from "@vue/shared";
import trees from "./trees";
const id = "sleigh";
const day = 22;
@ -40,36 +41,27 @@ const layer = createLayer(id, function (this: BaseLayer) {
);
}
const sleighProgress = computed(() => sleigh.amount);
const sleighCost = computed(() => {
const v = sleighProgress.value.value;
return {
wood: Decimal.mul(1e97, Decimal.pow(1.2, v)),
metal: Decimal.mul(1e67, Decimal.pow(1.1, v)),
plastic: Decimal.mul(1e22, Decimal.pow(1.05, v))
};
});
const sleigh = createBuyable(() => ({
display: jsx(() => (
<>
<b style="font-size: x-large">Fix 1% of the sleigh</b>
<br />
<br />
<span style="font-size: large">
Requires: {displayCost(trees.logs, sleighCost.value.wood, "logs")},
{displayCost(metal.metal, sleighCost.value.metal, "metal")},
{displayCost(plastic.plastic, sleighCost.value.plastic, "plastic")}
</span>
</>
)),
canPurchase(): boolean {
return (
sleighCost.value.wood.lte(trees.logs.value) &&
sleighCost.value.metal.lte(metal.metal.value) &&
sleighCost.value.plastic.lte(plastic.plastic.value)
);
},
onPurchase() {
this.amount.value = Decimal.add(this.amount.value, 1);
requirements: [
createCostRequirement(() => ({
resource: trees.logs,
cost: () => Decimal.mul(1e97, Decimal.pow(1.2, sleighProgress.value.value)),
requiresPay: false
})),
createCostRequirement(() => ({
resource: metal.metal,
cost: () => Decimal.mul(1e67, Decimal.pow(1.1, sleighProgress.value.value)),
requiresPay: false
})),
createCostRequirement(() => ({
resource: plastic.plastic,
cost: () => Decimal.mul(1e22, Decimal.pow(1.05, sleighProgress.value.value)),
requiresPay: false
}))
],
display: {
description: "<b style='font-size: x-large'>Fix 1% of the sleigh</b>",
showAmount: false
},
visibility: () => showIf(Decimal.lt(sleighProgress.value.value, 100)),
style: "width: 600px"

View file

@ -16,11 +16,11 @@ import { createMilestone, GenericMilestone } from "features/milestones/milestone
import MainDisplay from "features/resources/MainDisplay.vue";
import { createResource } from "features/resources/resource";
import { createUpgrade } from "features/upgrades/upgrade";
import { globalBus } from "game/events";
import { BaseLayer, createLayer } from "game/layers";
import { createSequentialModifier } from "game/modifiers";
import { noPersist } from "game/persistence";
import Decimal, { DecimalSource, format, formatWhole } from "util/bignum";
import { createCostRequirement } from "game/requirements";
import Decimal, { DecimalSource, formatWhole } from "util/bignum";
import { render, renderGrid, renderRow } from "util/vue";
import { computed, ref } from "vue";
import cloth from "./cloth";
@ -47,177 +47,129 @@ const layer = createLayer(id, function (this: BaseLayer) {
"toys"
);
const clothesCost = computed(() => {
let clothFactor = Decimal.add(1, clothesBuyable.amount.value);
if (milestones.milestone1.earned.value) {
clothFactor = clothFactor.div(
Decimal.div(workshop.foundationProgress.value, 100).floor()
);
}
return {
cloth: clothFactor.mul(1e13),
dye: clothFactor.mul(2e14)
};
});
const clothesBuyable = createBuyable(() => ({
display: jsx(() => (
<>
<h3>Make Clothes</h3>
<div>Click this buyable to make some clothes!</div>
<div>You have {formatWhole(clothes.value)} clothes.</div>
<div>
Costs{" "}
<span
class={
Decimal.lt(cloth.cloth.value, clothesCost.value.cloth)
? "unaffordable"
: ""
}
>
{format(clothesCost.value.cloth)} cloth
</span>{" "}
and requires{" "}
<span
class={
[dyes.dyes.red, dyes.dyes.yellow, dyes.dyes.blue].some(d =>
Decimal.lt(d.amount.value, clothesCost.value.dye)
)
? "unaffordable"
: ""
}
>
{format(clothesCost.value.dye)} of red, yellow, and blue dye
</span>
</div>
</>
)),
canPurchase(): boolean {
return (
clothesCost.value.cloth.lte(cloth.cloth.value) &&
clothesCost.value.dye.lte(dyes.dyes.blue.amount.value) &&
clothesCost.value.dye.lte(dyes.dyes.red.amount.value) &&
clothesCost.value.dye.lte(dyes.dyes.yellow.amount.value)
);
requirements: [
createCostRequirement(() => ({
resource: cloth.cloth,
cost() {
let clothFactor = Decimal.add(1, clothesBuyable.amount.value);
if (milestones.milestone1.earned.value) {
clothFactor = clothFactor.div(
Decimal.div(workshop.foundationProgress.value, 100).floor()
);
}
return clothFactor.mul(1e13);
}
})),
createCostRequirement(() => ({
resource: dyes.primaryDyes,
cost() {
let clothFactor = Decimal.add(1, clothesBuyable.amount.value);
if (milestones.milestone1.earned.value) {
clothFactor = clothFactor.div(
Decimal.div(workshop.foundationProgress.value, 100).floor()
);
}
return clothFactor.mul(2e14);
},
requiresPay: false
}))
],
display: {
title: "Make Clothes",
description: jsx(() => (
<>
<div>Click this buyable to make some clothes!</div>
<div>You have {formatWhole(clothes.value)} clothes.</div>
</>
))
},
onPurchase() {
// Lower amount first so costs are accurate, then re-add the purchase after
this.amount.value = Decimal.add(this.amount.value, -1);
cloth.cloth.value = Decimal.sub(cloth.cloth.value, clothesCost.value.cloth);
this.amount.value = Decimal.add(this.amount.value, 1);
clothes.value = Decimal.add(clothes.value, 1);
}
})) as GenericBuyable;
const woodenBlocksCost = computed(() => {
let woodFactor = Decimal.add(1, woodenBlocksBuyable.amount.value).pow(5);
if (milestones.milestone1.earned.value) {
woodFactor = woodFactor.div(
Decimal.div(workshop.foundationProgress.value, 100).floor()
);
}
return {
wood: woodFactor.mul(1e63)
};
});
const woodenBlocksBuyable = createBuyable(() => ({
display: jsx(() => (
<>
<h3>Make Wooden Blocks</h3>
<div>Click this buyable to make some wooden blocks!</div>
<div>You have {formatWhole(woodenBlocks.value)} wooden blocks.</div>
<div>Costs {format(woodenBlocksCost.value.wood)} logs</div>
</>
)),
canPurchase(): boolean {
return woodenBlocksCost.value.wood.lte(trees.logs.value);
requirements: createCostRequirement(() => ({
resource: trees.logs,
cost() {
let woodFactor = Decimal.add(1, woodenBlocksBuyable.amount.value).pow(5);
if (milestones.milestone1.earned.value) {
woodFactor = woodFactor.div(
Decimal.div(workshop.foundationProgress.value, 100).floor()
);
}
return woodFactor.mul(1e63);
}
})),
display: {
title: "Make Wooden Blocks",
description: jsx(() => (
<>
<div>Click this buyable to make some wooden blocks!</div>
<div>You have {formatWhole(woodenBlocks.value)} wooden blocks.</div>
</>
))
},
onPurchase() {
// Lower amount first so costs are accurate, then re-add the purchase after
this.amount.value = Decimal.add(this.amount.value, -1);
trees.logs.value = Decimal.sub(trees.logs.value, woodenBlocksCost.value.wood);
this.amount.value = Decimal.add(this.amount.value, 1);
woodenBlocks.value = Decimal.add(woodenBlocks.value, 1);
}
})) as GenericBuyable;
const trucksCost = computed(() => {
let factor = Decimal.add(1, trucksBuyable.amount.value).pow(3);
let plasticFactor = Decimal.add(1, trucksBuyable.amount.value);
if (milestones.milestone1.earned.value) {
factor = factor.div(Decimal.div(workshop.foundationProgress.value, 100).floor());
plasticFactor = plasticFactor.div(
Decimal.div(workshop.foundationProgress.value, 100).floor()
);
}
return {
metal: factor.mul(1e43),
plastic: plasticFactor.mul(1e14)
};
});
const trucksBuyable = createBuyable(() => ({
display: jsx(() => (
<>
<h3>Make Trucks</h3>
<div>Click this buyable to make some trucks!</div>
<div>You have {formatWhole(trucks.value)} trucks.</div>
<div>
Costs{" "}
<span
class={
Decimal.lt(metal.metal.value, trucksCost.value.metal)
? "unaffordable"
: ""
}
>
{format(trucksCost.value.metal)} metal
</span>{" "}
and{" "}
<span
class={
Decimal.lt(plastic.plastic.value, trucksCost.value.plastic)
? "unaffordable"
: ""
}
>
{format(trucksCost.value.plastic)} plastic
</span>
</div>
</>
)),
canPurchase(): boolean {
return (
trucksCost.value.metal.lte(metal.metal.value) &&
trucksCost.value.plastic.lte(plastic.plastic.value)
);
requirements: [
createCostRequirement(() => ({
resource: metal.metal,
cost() {
let factor = Decimal.add(1, trucksBuyable.amount.value).pow(3);
if (milestones.milestone1.earned.value) {
factor = factor.div(
Decimal.div(workshop.foundationProgress.value, 100).floor()
);
}
return factor.mul(1e43);
}
})),
createCostRequirement(() => ({
resource: plastic.plastic,
cost() {
let plasticFactor = Decimal.add(1, trucksBuyable.amount.value);
if (milestones.milestone1.earned.value) {
plasticFactor = plasticFactor.div(
Decimal.div(workshop.foundationProgress.value, 100).floor()
);
}
return plasticFactor.mul(1e14);
}
}))
],
display: {
title: "Make Trucks",
description: jsx(() => (
<>
<div>Click this buyable to make some trucks!</div>
<div>You have {formatWhole(trucks.value)} trucks.</div>
</>
))
},
onPurchase() {
// Lower amount first so costs are accurate, then re-add the purchase after
this.amount.value = Decimal.add(this.amount.value, -1);
metal.metal.value = Decimal.sub(metal.metal.value, trucksCost.value.metal);
plastic.plastic.value = Decimal.sub(plastic.plastic.value, trucksCost.value.plastic);
this.amount.value = Decimal.add(this.amount.value, 1);
trucks.value = Decimal.add(trucks.value, 1);
}
})) as GenericBuyable;
const buyables = [clothesBuyable, woodenBlocksBuyable, trucksBuyable];
const trucksUpgrade1 = createUpgrade(() => ({
resource: noPersist(trucks),
cost: 10,
requirements: createCostRequirement(() => ({
resource: noPersist(trucks),
cost: 10
})),
display: {
title: "Load logs onto trucks",
description: "Log gain is doubled."
}
}));
const clothesUpgrade1 = createUpgrade(() => ({
resource: noPersist(clothes),
cost: 30,
requirements: createCostRequirement(() => ({
resource: noPersist(clothes),
cost: 30
})),
display: {
title: "Give elves clothes to wear",
description:
@ -226,8 +178,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}));
const woodenBlocksUpgrade1 = createUpgrade(() => ({
resource: noPersist(woodenBlocks),
cost: 15,
requirements: createCostRequirement(() => ({
resource: noPersist(woodenBlocks),
cost: 15
})),
display: {
title: "Build wooden towers",
description: "You can now build 2 extra tall workshops!"

View file

@ -44,6 +44,7 @@ import reindeer from "./reindeer";
import sleigh from "./sleigh";
import routing from "./routing";
import packing from "./packing";
import { createCostRequirement } from "game/requirements";
const id = "trees";
const day = 1;
@ -114,40 +115,50 @@ const layer = createLayer(id, function (this: BaseLayer) {
const computedTotalTrees = computed(() => totalTrees.apply(10));
const manualCutUpgrade1 = createUpgrade(() => ({
resource: noPersist(logs),
cost: 10,
requirements: createCostRequirement(() => ({
resource: noPersist(logs),
cost: 10
})),
display: {
title: "Wooden Fingers",
description: "Cut down an additional tree per click"
}
}));
const manualPlantUpgrade1 = createUpgrade(() => ({
resource: noPersist(logs),
cost: 10,
requirements: createCostRequirement(() => ({
resource: noPersist(logs),
cost: 10
})),
display: {
title: "Leafy Fingers",
description: "Plant an additional tree per click"
}
}));
const autoCutUpgrade1 = createUpgrade(() => ({
resource: noPersist(logs),
cost: 25,
requirements: createCostRequirement(() => ({
resource: noPersist(logs),
cost: 25
})),
display: {
title: "Automated Knives",
description: "Cut down a tree every second"
}
}));
const autoPlantUpgrade1 = createUpgrade(() => ({
resource: noPersist(logs),
cost: 25,
requirements: createCostRequirement(() => ({
resource: noPersist(logs),
cost: 25
})),
display: {
title: "Automated Spade",
description: "Plant a tree every second"
}
}));
const researchUpgrade1 = createUpgrade(() => ({
resource: noPersist(logs),
cost: 40,
requirements: createCostRequirement(() => ({
resource: noPersist(logs),
cost: 40
})),
display: {
title: "Research I",
description: "Trees give 25% more logs, and unlock more upgrades"
@ -162,8 +173,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
];
const manualCutUpgrade2 = createUpgrade(() => ({
resource: noPersist(logs),
cost: 50,
requirements: createCostRequirement(() => ({
resource: noPersist(logs),
cost: 50
})),
visibility: () => showIf(researchUpgrade1.bought.value),
display: {
title: "Sharper Fingers",
@ -171,8 +184,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const manualPlantUpgrade2 = createUpgrade(() => ({
resource: noPersist(logs),
cost: 50,
requirements: createCostRequirement(() => ({
resource: noPersist(logs),
cost: 50
})),
visibility: () => showIf(researchUpgrade1.bought.value),
display: {
title: "Greener Fingers",
@ -180,8 +195,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const manualCutUpgrade3 = createUpgrade(() => ({
resource: noPersist(logs),
cost: 150,
requirements: createCostRequirement(() => ({
resource: noPersist(logs),
cost: 150
})),
visibility: () => showIf(researchUpgrade1.bought.value),
display: {
title: "Smart Knives",
@ -190,8 +207,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const manualPlantUpgrade3 = createUpgrade(() => ({
resource: noPersist(logs),
cost: 150,
requirements: createCostRequirement(() => ({
resource: noPersist(logs),
cost: 150
})),
visibility: () => showIf(researchUpgrade1.bought.value),
display: {
title: "Smart Spades",
@ -200,8 +219,10 @@ const layer = createLayer(id, function (this: BaseLayer) {
}
}));
const researchUpgrade2 = createUpgrade(() => ({
resource: noPersist(logs),
cost: 300,
requirements: createCostRequirement(() => ({
resource: noPersist(logs),
cost: 300
})),
visibility: () => showIf(researchUpgrade1.bought.value),
display: {
title: "Research II",
@ -217,16 +238,19 @@ const layer = createLayer(id, function (this: BaseLayer) {
];
const autoCuttingBuyable1 = createBuyable(() => ({
requirements: createCostRequirement(() => ({
resource: noPersist(logs),
cost() {
let v = autoCuttingBuyable1.amount.value;
if (Decimal.gte(v, 50)) v = Decimal.pow(v, 2).div(50);
if (Decimal.gte(v, 200)) v = Decimal.pow(v, 2).div(200);
if (Decimal.gte(v, 2e6)) v = Decimal.pow(v, 2).div(2e6);
if (Decimal.gte(v, 2e30)) v = Decimal.pow(v, 10).div(Decimal.pow(2e30, 9));
v = Decimal.pow(0.95, paper.books.cuttersBook.totalAmount.value).times(v);
return Decimal.times(100, v).add(200);
}
})),
resource: noPersist(logs),
cost() {
let v = this.amount.value;
if (Decimal.gte(v, 50)) v = Decimal.pow(v, 2).div(50);
if (Decimal.gte(v, 200)) v = Decimal.pow(v, 2).div(200);
if (Decimal.gte(v, 2e6)) v = Decimal.pow(v, 2).div(2e6);
if (Decimal.gte(v, 2e30)) v = Decimal.pow(v, 10).div(Decimal.pow(2e30, 9));
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));
@ -241,22 +265,25 @@ const layer = createLayer(id, function (this: BaseLayer) {
description: "Each cutter cuts down 1 tree/s"
},
visibility: () => showIf(researchUpgrade2.bought.value)
})) as ElfBuyable & { display: { title: string }; resource: Resource };
})) as ElfBuyable;
const autoPlantingBuyable1 = createBuyable(() => ({
resource: noPersist(logs),
cost() {
let v = this.amount.value;
if (Decimal.gte(v, 50)) v = Decimal.pow(v, 2).div(50);
if (Decimal.gte(v, 200)) v = Decimal.pow(v, 2).div(200);
if (Decimal.gte(v, 2e6)) v = Decimal.pow(v, 2).div(2e6);
if (Decimal.gte(v, 2e30)) v = Decimal.pow(v, 10).div(Decimal.pow(2e30, 9));
v = Decimal.pow(0.95, paper.books.plantersBook.totalAmount.value).times(v);
let cost = Decimal.times(100, v).add(200);
if (management.elfTraining.planterElfTraining.milestones[3].earned.value) {
cost = Decimal.div(cost, 10);
requirements: createCostRequirement(() => ({
resource: noPersist(logs),
cost() {
let v = autoPlantingBuyable1.amount.value;
if (Decimal.gte(v, 50)) v = Decimal.pow(v, 2).div(50);
if (Decimal.gte(v, 200)) v = Decimal.pow(v, 2).div(200);
if (Decimal.gte(v, 2e6)) v = Decimal.pow(v, 2).div(2e6);
if (Decimal.gte(v, 2e30)) v = Decimal.pow(v, 10).div(Decimal.pow(2e30, 9));
v = Decimal.pow(0.95, paper.books.plantersBook.totalAmount.value).times(v);
let cost = Decimal.times(100, v).add(200);
if (management.elfTraining.planterElfTraining.milestones[3].earned.value) {
cost = Decimal.div(cost, 10);
}
return cost;
}
return cost;
},
})),
resource: noPersist(logs),
inverseCost(x: DecimalSource) {
if (management.elfTraining.planterElfTraining.milestones[3].earned.value) {
x = Decimal.mul(x, 10);
@ -274,17 +301,20 @@ const layer = createLayer(id, function (this: BaseLayer) {
description: "Each planter plants 0.5 trees/s"
},
visibility: () => showIf(researchUpgrade2.bought.value)
})) as ElfBuyable & { display: { title: string }; resource: Resource };
})) as ElfBuyable;
const expandingForestBuyable = createBuyable(() => ({
requirements: createCostRequirement(() => ({
resource: noPersist(logs),
cost() {
let v = expandingForestBuyable.amount.value;
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 2).div(100);
if (Decimal.gte(v, 1e5)) v = Decimal.pow(v, 2).div(1e5);
if (Decimal.gte(v, 1e15)) v = Decimal.pow(v, 10).div(1e135);
v = Decimal.pow(0.95, paper.books.expandersBook.totalAmount.value).times(v);
return Decimal.pow(Decimal.add(v, 1), 1.5).times(500);
}
})),
resource: noPersist(logs),
cost() {
let v = this.amount.value;
if (Decimal.gte(v, 100)) v = Decimal.pow(v, 2).div(100);
if (Decimal.gte(v, 1e5)) v = Decimal.pow(v, 2).div(1e5);
if (Decimal.gte(v, 1e15)) v = Decimal.pow(v, 10).div(1e135);
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));
@ -298,7 +328,7 @@ const layer = createLayer(id, function (this: BaseLayer) {
description: "Add 10 trees to the forest"
},
visibility: () => showIf(researchUpgrade2.bought.value)
})) as ElfBuyable & { display: { title: string }; resource: Resource };
})) as ElfBuyable;
const row1Buyables = [autoCuttingBuyable1, autoPlantingBuyable1, expandingForestBuyable];
const manualCuttingAmount = createSequentialModifier(() => [

View file

@ -5,19 +5,19 @@ import { createClickable } from "features/clickables/clickable";
import { jsx, JSXFunction, showIf } from "features/feature";
import { createMilestone } from "features/milestones/milestone";
import MainDisplay from "features/resources/MainDisplay.vue";
import { createResource, Resource } from "features/resources/resource";
import { createResource } from "features/resources/resource";
import { createLayer, layers } from "game/layers";
import player from "game/player";
import { createCostRequirement, displayRequirements, requirementsMet } from "game/requirements";
import Decimal, { DecimalSource, format, formatWhole } from "util/bignum";
import { Direction } from "util/common";
import { Computable } from "util/computed";
import { render, renderRow } from "util/vue";
import { computed, Ref, unref, watchEffect } from "vue";
import { main } from "../projEntry";
import { default as dyes, type enumColor } from "./dyes";
import elves from "./elves";
import toys from "./toys";
import packing from "./packing";
import toys from "./toys";
const id = "wrappingPaper";
const day = 15;
@ -55,66 +55,40 @@ const layer = createLayer(id, () => {
const color = "gold";
const createWrappingPaper = (options: WrappingPaperOptions & Partial<BuyableOptions>) => {
const getCost: Computable<
{
resource: Resource;
cost: DecimalSource;
}[]
> = computed(() => {
const dyeCosts = [];
for (const [color, ratio] of Object.entries(options.ratio)) {
dyeCosts.push({
resource: dyes.dyes[color as enumColor].amount,
cost: Decimal.mul(ratio.base, Decimal.pow(ratio.exponent, buyable.amount.value))
});
}
return dyeCosts;
});
const buyable: GenericBuyable = createBuyable(() => {
return {
requirements: (Object.entries(options.ratio) as [enumColor, Scaling][]).map(
([color, ratio]) => {
return createCostRequirement(() => ({
resource: dyes.dyes[color as enumColor].amount,
cost: () =>
Decimal.mul(
ratio.base,
Decimal.pow(ratio.exponent, buyable.amount.value)
),
requiresPay: false
}));
}
),
style: () => ({
background: unref(buyable.canPurchase) ? options.background : "#545454",
background: requirementsMet(buyable.requirements)
? options.background
: "#545454",
minWidth: "200px",
boxShadow:
"0 3px 0 #00000022 inset, 3px 0 0 #00000022 inset, 0 0 3px #00000022 inset, 0 0 0 3px #00000022 inset",
border: "none"
}),
display: jsx(() => {
return (
<span>
<h3>{options.name}</h3>
<br />
Create {options.name}.
<br />
Requirement:{" "}
{getCost.value.map(({ resource, cost }) => {
return render(
jsx(() => (
<div
class={
Decimal.lt(resource.value, cost)
? "unaffordable"
: ""
}
>
{format(cost)} {resource.displayName} <br />
</div>
))
);
})}
<br />
Currently:{" "}
display: {
title: options.name,
description: `Create ${options.name}`,
effectDisplay: jsx(() => (
<>
{options.listedBoosts.map(({ desc }) => {
return render(jsx(() => <div>{unref(desc)}</div>));
})}
</span>
);
}),
canPurchase() {
for (const { resource, cost } of getCost.value) {
if (Decimal.lt(resource.value, cost)) return false;
}
return true;
</>
))
}
};
});