mirror of
https://github.com/thepaperpilot/Planar-Pioneers.git
synced 2024-11-24 17:31:47 +00:00
Rebalance resource levels and implement portal costs
This commit is contained in:
parent
5d26995a72
commit
653e674484
4 changed files with 95 additions and 54 deletions
|
@ -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))
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue