diff --git a/src/data/boardUtils.tsx b/src/data/boardUtils.tsx index aedd7b2..bb2e576 100644 --- a/src/data/boardUtils.tsx +++ b/src/data/boardUtils.tsx @@ -1,5 +1,5 @@ import { BoardNode, GenericBoard, GenericBoardNodeAction, NodeLabel } from "features/boards/board"; -import Formula, { calculateCost } from "game/formulas/formulas"; +import Formula from "game/formulas/formulas"; import { GenericFormula, InvertibleIntegralFormula } from "game/formulas/types"; import Decimal, { formatWhole } from "util/bignum"; import { @@ -16,7 +16,11 @@ import { main } from "./projEntry"; import { DecimalSource } from "lib/break_eternity"; import { ComputedRef } from "vue"; -export const resourceLevelFormula = Formula.variable(0).add(1); +export const resourceLevelFormula = Formula.variable(0) + .step(100, x => x.pow(1.5)) + .step(Decimal.pow(900, 1.5).add(100), x => x.pow(1.5)) + .pow(1.5); +console.log(resourceLevelFormula); export const deselectAllAction = { id: "deselect", @@ -324,12 +328,8 @@ export function getResourceLevelProgress(resource: Resources): number { (main.resourceNodes.value[resource]?.state as unknown as ResourceState | undefined) ?.amount ?? 0; const currentLevel = main.resourceLevels.value[resource]; - const requiredForCurrentLevel = calculateCost(resourceLevelFormula, currentLevel, true); - const requiredForNextLevel = calculateCost( - resourceLevelFormula, - Decimal.add(currentLevel, 1), - true - ); + const requiredForCurrentLevel = resourceLevelFormula.evaluate(currentLevel); + const requiredForNextLevel = resourceLevelFormula.evaluate(Decimal.add(currentLevel, 1)); return Decimal.sub(amount, requiredForCurrentLevel) .max(0) .div(Decimal.sub(requiredForNextLevel, requiredForCurrentLevel)) diff --git a/src/data/nodeTypes.tsx b/src/data/nodeTypes.tsx index 6ba6363..e592d44 100644 --- a/src/data/nodeTypes.tsx +++ b/src/data/nodeTypes.tsx @@ -119,9 +119,7 @@ export const factory = { ).type; const text = node.state === resource ? "Disconnect" : tools[resource].name; const color = - node.state === resource || - (Decimal.gte(main.energy.value, tools[resource].cost) && - main.toolNodes.value[resource] == null) + node.state === resource || main.toolNodes.value[resource] == null ? "var(--accent2)" : "var(--danger)"; return { @@ -189,7 +187,10 @@ export const factory = { progress: node => node.state == null || main.toolNodes.value[node.state as Resources] != null ? 0 - : Decimal.div(main.energy.value, tools[node.state as Resources].cost) + : Decimal.div( + Decimal.sqrt(main.energy.value), + Decimal.sqrt(tools[node.state as Resources].cost) + ) .clampMax(1) .toNumber(), progressDisplay: ProgressDisplay.Fill, @@ -449,13 +450,24 @@ export const portalGenerator = { id: "makePortal", icon: "done", tooltip: node => ({ - text: `Spawn ${(node.state as unknown as PortalGeneratorState).tier}-tier portal` + text: `Spawn ${ + (node.state as unknown as PortalGeneratorState).tier + }-tier portal - ${formatWhole(main.computedPortalCost.value)} energy` }), + fillColor: () => + Decimal.gte(main.energy.value, main.computedPortalCost.value) + ? "var(--accent2)" + : "var(--danger)", + confirmationLabel: () => + Decimal.gte(main.energy.value, main.computedPortalCost.value) + ? { text: "Tap again to confirm" } + : { text: "Cannot afford", color: "var(--danger)" }, onClick(node) { let id = 0; while (`portal-${id}` in layers) { id++; } + main.energy.value = Decimal.sub(main.energy.value, main.computedPortalCost.value); const { tier, influences } = node.state as unknown as PortalGeneratorState; addLayer( createPlane( diff --git a/src/data/projEntry.tsx b/src/data/projEntry.tsx index 6176dc2..635852c 100644 --- a/src/data/projEntry.tsx +++ b/src/data/projEntry.tsx @@ -23,7 +23,7 @@ import { State } from "game/persistence"; import type { LayerData, Player } from "game/player"; import player from "game/player"; import settings from "game/settings"; -import Decimal, { DecimalSource, format, formatWhole } from "util/bignum"; +import Decimal, { DecimalSource, format, formatSmall, formatWhole } from "util/bignum"; import { WithRequired, camelToTitle } from "util/common"; import { render } from "util/vue"; import { ComputedRef, computed, nextTick, reactive, ref, watch } from "vue"; @@ -52,6 +52,7 @@ import { ResourceState, Resources, UpgraderState, + influences, mineLootTable, resourceNames, tools @@ -143,21 +144,7 @@ export const main = createLayer("main", function (this: BaseLayer) { const amount = (resourceNodes.value[curr]?.state as unknown as ResourceState | undefined) ?.amount ?? 0; - // Sub 10 and then manually sum until we go over amount - let currentLevel = Decimal.floor(resourceLevelFormula.invertIntegral(amount)) - .sub(10) - .clampMin(0); - let summedCost = calculateCost(resourceLevelFormula, currentLevel, true, 0); - while (true) { - const nextCost = resourceLevelFormula.evaluate(currentLevel); - if (Decimal.add(summedCost, nextCost).lte(amount)) { - currentLevel = currentLevel.add(1); - summedCost = Decimal.add(summedCost, nextCost); - } else { - break; - } - } - acc[curr] = currentLevel; + acc[curr] = Decimal.floor(resourceLevelFormula.invert(amount)); return acc; }, {} as Record) ); @@ -185,7 +172,6 @@ export const main = createLayer("main", function (this: BaseLayer) { )}`} ! -
Energy gain is now 1.01x higher.
); } @@ -488,27 +474,30 @@ export const main = createLayer("main", function (this: BaseLayer) { return multis; }); - const energyModifier = createSequentialModifier(() => [ - ...resourceNames.map(resource => - createMultiplicativeModifier(() => ({ - description: () => - `${camelToTitle(resource)} (Lv. ${formatWhole( - resourceLevels.value[resource] - )}) (${format(computedmaterialLevelEffectModifier.value)}x per level)`, - multiplier: () => - Decimal.pow( - computedmaterialLevelEffectModifier.value, - resourceLevels.value[resource] - ), - enabled: () => - resource in resourceNodes.value && - Decimal.gt( - (resourceNodes.value[resource].state as ResourceState | undefined) - ?.amount ?? 0, - 0 - ) + const totalResourceLevels = createSequentialModifier(() => + resourceNames.map(resource => + createAdditiveModifier(() => ({ + description: () => camelToTitle(resource), + addend: () => resourceLevels.value[resource], + enabled: () => Decimal.gt(resourceLevels.value[resource], 0) })) - ), + ) + ); + const computedTotalResourceLevels = computed(() => totalResourceLevels.apply(0)); + const energyModifier = createSequentialModifier(() => [ + createAdditiveModifier(() => ({ + addend: computedTotalResourceLevels, + description: "Resource Levels" + })), + createMultiplicativeModifier(() => ({ + multiplier: () => + Decimal.pow( + computedmaterialLevelEffectModifier.value, + computedTotalResourceLevels.value + ), + description: () => + `${formatSmall(computedmaterialLevelEffectModifier.value)}x per Resource Level` + })), createMultiplicativeModifier(() => ({ multiplier: () => (isEmpowered("stone") ? 4 : 2), description: () => (isEmpowered("stone") ? "Empowered " : "") + tools.stone.name, @@ -525,7 +514,7 @@ export const main = createLayer("main", function (this: BaseLayer) { enabled: () => Decimal.gt(numPoweredMachines.value, 0) })) ]); - const computedEnergyModifier = computed(() => energyModifier.apply(1)); + const computedEnergyModifier = computed(() => energyModifier.apply(0)); const bonusConnectionsModifier = createSequentialModifier(() => [ createAdditiveModifier(() => ({ @@ -604,17 +593,56 @@ export const main = createLayer("main", function (this: BaseLayer) { return acc; }, {} as Record; computedModifier: ComputedRef; section: Section }>); + const basePortalCost = computed(() => { + const n = resourceNames.indexOf( + (portalGenerator.value?.state as unknown as PortalGeneratorState | undefined)?.tier ?? + "dirt" + ); + return Decimal.add(n, 1).times(n).div(2).add(9).pow10(); + }); + const portalCostModifier = createSequentialModifier(() => + (Object.keys(influences) as Influences[]).map(influence => + createMultiplicativeModifier(() => ({ + multiplier: influences[influence].cost, + description: influences[influence].display, + enabled: () => + ( + portalGenerator.value?.state as unknown as PortalGeneratorState | undefined + )?.influences.includes(influence) ?? false + })) + ) + ); + const computedPortalCost = computed(() => portalCostModifier.apply(basePortalCost.value)); + const [energyTab, energyTabCollapsed] = createCollapsibleModifierSections(() => [ + { + title: "Resource Levels", + modifier: totalResourceLevels, + base: 0 + }, { title: "Energy Gain", modifier: energyModifier, - base: 1, + base: 0, unit: "/s" }, + { + title: "Portal Cost", + modifier: portalCostModifier, + base: basePortalCost, + unit: " energy", + baseText: () => + `${camelToTitle( + (portalGenerator.value?.state as unknown as PortalGeneratorState | undefined) + ?.tier ?? "dirt" + )}-tier Base Cost`, + visible: () => portalGenerator.value != null + }, { title: "Bonus Connections", modifier: bonusConnectionsModifier, - base: 0 + base: 0, + visible: () => Decimal.gt(computedBonusConnectionsModifier.value, 0) } ]); const [miningTab, miningTabCollapsed] = createCollapsibleModifierSections(() => [ @@ -875,6 +903,7 @@ export const main = createLayer("main", function (this: BaseLayer) { investments, resourceLevels, planarMultis, + computedPortalCost, display: jsx(() => ( <> diff --git a/src/game/formulas/operations.ts b/src/game/formulas/operations.ts index 0e39d58..61f16bc 100644 --- a/src/game/formulas/operations.ts +++ b/src/game/formulas/operations.ts @@ -399,7 +399,7 @@ export function integratePow10(stack: SubstitutionStack, lhs: FormulaSource) { export function invertPowBase(value: DecimalSource, lhs: FormulaSource, rhs: FormulaSource) { if (hasVariable(lhs)) { - return lhs.invert(Decimal.ln(value).div(unrefFormulaSource(rhs))); + return lhs.invert(Decimal.ln(value).div(Decimal.ln(unrefFormulaSource(rhs)))); } else if (hasVariable(rhs)) { return rhs.invert(Decimal.root(unrefFormulaSource(lhs), value)); }