Rebalance resource levels and implement portal costs

This commit is contained in:
thepaperpilot 2023-05-11 21:09:15 -05:00
parent 5d26995a72
commit 653e674484
4 changed files with 95 additions and 54 deletions

View file

@ -1,5 +1,5 @@
import { BoardNode, GenericBoard, GenericBoardNodeAction, NodeLabel } from "features/boards/board"; 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 { GenericFormula, InvertibleIntegralFormula } from "game/formulas/types";
import Decimal, { formatWhole } from "util/bignum"; import Decimal, { formatWhole } from "util/bignum";
import { import {
@ -16,7 +16,11 @@ import { main } from "./projEntry";
import { DecimalSource } from "lib/break_eternity"; import { DecimalSource } from "lib/break_eternity";
import { ComputedRef } from "vue"; 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 = { export const deselectAllAction = {
id: "deselect", id: "deselect",
@ -324,12 +328,8 @@ export function getResourceLevelProgress(resource: Resources): number {
(main.resourceNodes.value[resource]?.state as unknown as ResourceState | undefined) (main.resourceNodes.value[resource]?.state as unknown as ResourceState | undefined)
?.amount ?? 0; ?.amount ?? 0;
const currentLevel = main.resourceLevels.value[resource]; const currentLevel = main.resourceLevels.value[resource];
const requiredForCurrentLevel = calculateCost(resourceLevelFormula, currentLevel, true); const requiredForCurrentLevel = resourceLevelFormula.evaluate(currentLevel);
const requiredForNextLevel = calculateCost( const requiredForNextLevel = resourceLevelFormula.evaluate(Decimal.add(currentLevel, 1));
resourceLevelFormula,
Decimal.add(currentLevel, 1),
true
);
return Decimal.sub(amount, requiredForCurrentLevel) return Decimal.sub(amount, requiredForCurrentLevel)
.max(0) .max(0)
.div(Decimal.sub(requiredForNextLevel, requiredForCurrentLevel)) .div(Decimal.sub(requiredForNextLevel, requiredForCurrentLevel))

View file

@ -119,9 +119,7 @@ export const factory = {
).type; ).type;
const text = node.state === resource ? "Disconnect" : tools[resource].name; const text = node.state === resource ? "Disconnect" : tools[resource].name;
const color = const color =
node.state === resource || node.state === resource || main.toolNodes.value[resource] == null
(Decimal.gte(main.energy.value, tools[resource].cost) &&
main.toolNodes.value[resource] == null)
? "var(--accent2)" ? "var(--accent2)"
: "var(--danger)"; : "var(--danger)";
return { return {
@ -189,7 +187,10 @@ export const factory = {
progress: node => progress: node =>
node.state == null || main.toolNodes.value[node.state as Resources] != null node.state == null || main.toolNodes.value[node.state as Resources] != null
? 0 ? 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) .clampMax(1)
.toNumber(), .toNumber(),
progressDisplay: ProgressDisplay.Fill, progressDisplay: ProgressDisplay.Fill,
@ -449,13 +450,24 @@ export const portalGenerator = {
id: "makePortal", id: "makePortal",
icon: "done", icon: "done",
tooltip: node => ({ 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) { onClick(node) {
let id = 0; let id = 0;
while (`portal-${id}` in layers) { while (`portal-${id}` in layers) {
id++; id++;
} }
main.energy.value = Decimal.sub(main.energy.value, main.computedPortalCost.value);
const { tier, influences } = node.state as unknown as PortalGeneratorState; const { tier, influences } = node.state as unknown as PortalGeneratorState;
addLayer( addLayer(
createPlane( createPlane(

View file

@ -23,7 +23,7 @@ import { State } from "game/persistence";
import type { LayerData, Player } from "game/player"; import type { LayerData, Player } from "game/player";
import player from "game/player"; import player from "game/player";
import settings from "game/settings"; 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 { WithRequired, camelToTitle } from "util/common";
import { render } from "util/vue"; import { render } from "util/vue";
import { ComputedRef, computed, nextTick, reactive, ref, watch } from "vue"; import { ComputedRef, computed, nextTick, reactive, ref, watch } from "vue";
@ -52,6 +52,7 @@ import {
ResourceState, ResourceState,
Resources, Resources,
UpgraderState, UpgraderState,
influences,
mineLootTable, mineLootTable,
resourceNames, resourceNames,
tools tools
@ -143,21 +144,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
const amount = const amount =
(resourceNodes.value[curr]?.state as unknown as ResourceState | undefined) (resourceNodes.value[curr]?.state as unknown as ResourceState | undefined)
?.amount ?? 0; ?.amount ?? 0;
// Sub 10 and then manually sum until we go over amount acc[curr] = Decimal.floor(resourceLevelFormula.invert(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;
return acc; return acc;
}, {} as Record<Resources, DecimalSource>) }, {} as Record<Resources, DecimalSource>)
); );
@ -185,7 +172,6 @@ export const main = createLayer("main", function (this: BaseLayer) {
)}`} )}`}
! !
</h3> </h3>
<div>Energy gain is now 1.01x higher.</div>
</div> </div>
); );
} }
@ -488,27 +474,30 @@ export const main = createLayer("main", function (this: BaseLayer) {
return multis; return multis;
}); });
const energyModifier = createSequentialModifier(() => [ const totalResourceLevels = createSequentialModifier(() =>
...resourceNames.map(resource => resourceNames.map(resource =>
createMultiplicativeModifier(() => ({ createAdditiveModifier(() => ({
description: () => description: () => camelToTitle(resource),
`${camelToTitle(resource)} (Lv. ${formatWhole( addend: () => resourceLevels.value[resource],
resourceLevels.value[resource] enabled: () => Decimal.gt(resourceLevels.value[resource], 0)
)}) (${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 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(() => ({ createMultiplicativeModifier(() => ({
multiplier: () => (isEmpowered("stone") ? 4 : 2), multiplier: () => (isEmpowered("stone") ? 4 : 2),
description: () => (isEmpowered("stone") ? "Empowered " : "") + tools.stone.name, 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) enabled: () => Decimal.gt(numPoweredMachines.value, 0)
})) }))
]); ]);
const computedEnergyModifier = computed(() => energyModifier.apply(1)); const computedEnergyModifier = computed(() => energyModifier.apply(0));
const bonusConnectionsModifier = createSequentialModifier(() => [ const bonusConnectionsModifier = createSequentialModifier(() => [
createAdditiveModifier(() => ({ createAdditiveModifier(() => ({
@ -604,17 +593,56 @@ export const main = createLayer("main", function (this: BaseLayer) {
return acc; return acc;
}, {} as Record<Resources, { modifier: WithRequired<Modifier, "invert" | "description">; computedModifier: ComputedRef<DecimalSource>; section: Section }>); }, {} as Record<Resources, { modifier: WithRequired<Modifier, "invert" | "description">; computedModifier: ComputedRef<DecimalSource>; 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(() => [ const [energyTab, energyTabCollapsed] = createCollapsibleModifierSections(() => [
{
title: "Resource Levels",
modifier: totalResourceLevels,
base: 0
},
{ {
title: "Energy Gain", title: "Energy Gain",
modifier: energyModifier, modifier: energyModifier,
base: 1, base: 0,
unit: "/s" 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", title: "Bonus Connections",
modifier: bonusConnectionsModifier, modifier: bonusConnectionsModifier,
base: 0 base: 0,
visible: () => Decimal.gt(computedBonusConnectionsModifier.value, 0)
} }
]); ]);
const [miningTab, miningTabCollapsed] = createCollapsibleModifierSections(() => [ const [miningTab, miningTabCollapsed] = createCollapsibleModifierSections(() => [
@ -875,6 +903,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
investments, investments,
resourceLevels, resourceLevels,
planarMultis, planarMultis,
computedPortalCost,
display: jsx(() => ( display: jsx(() => (
<> <>
<StickyVue class="nav-container"> <StickyVue class="nav-container">

View file

@ -399,7 +399,7 @@ export function integratePow10(stack: SubstitutionStack, lhs: FormulaSource) {
export function invertPowBase(value: DecimalSource, lhs: FormulaSource, rhs: FormulaSource) { export function invertPowBase(value: DecimalSource, lhs: FormulaSource, rhs: FormulaSource) {
if (hasVariable(lhs)) { 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)) { } else if (hasVariable(rhs)) {
return rhs.invert(Decimal.root(unrefFormulaSource(lhs), value)); return rhs.invert(Decimal.root(unrefFormulaSource(lhs), value));
} }