mirror of
https://github.com/thepaperpilot/Planar-Pioneers.git
synced 2024-11-22 00:21:31 +00:00
Implement most treasures
Implemented resource caches, resource generation, resource multis, and energy multis. Remaining: influences and relics.
This commit is contained in:
parent
da393b7f5a
commit
fd7df64e0e
2 changed files with 183 additions and 26 deletions
|
@ -20,7 +20,7 @@ import { Direction, WithRequired, camelToTitle } from "util/common";
|
||||||
import { VueFeature, render, renderRow, trackHover } from "util/vue";
|
import { VueFeature, render, renderRow, trackHover } from "util/vue";
|
||||||
import { ComputedRef, Ref, computed, ref } from "vue";
|
import { ComputedRef, Ref, computed, ref } from "vue";
|
||||||
import { createCollapsibleModifierSections, createFormulaPreview, estimateTime } from "./common";
|
import { createCollapsibleModifierSections, createFormulaPreview, estimateTime } from "./common";
|
||||||
import { main, Resources, resourceNames } from "./projEntry";
|
import { main, Resources, resourceNames, mineLootTable, ResourceState } from "./projEntry";
|
||||||
import { getColor, getName, sfc32 } from "./utils";
|
import { getColor, getName, sfc32 } from "./utils";
|
||||||
import ModalVue from "components/Modal.vue";
|
import ModalVue from "components/Modal.vue";
|
||||||
import { addTooltip } from "features/tooltips/tooltip";
|
import { addTooltip } from "features/tooltips/tooltip";
|
||||||
|
@ -185,7 +185,10 @@ export function createPlane(id: string, tier: Resources, seed: number) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const treasureWeights = {
|
const treasureWeights = {
|
||||||
dirtGeneration: 16
|
cache: 100,
|
||||||
|
generation: 10,
|
||||||
|
resourceMulti: 5,
|
||||||
|
energyMulti: 5
|
||||||
};
|
};
|
||||||
const sumTreasureWeights = Object.values(treasureWeights).reduce((a, b) => a + b);
|
const sumTreasureWeights = Object.values(treasureWeights).reduce((a, b) => a + b);
|
||||||
const treasureWeightsKeys = Object.keys(
|
const treasureWeightsKeys = Object.keys(
|
||||||
|
@ -209,11 +212,43 @@ export function createPlane(id: string, tier: Resources, seed: number) {
|
||||||
let update: (diff: number) => void;
|
let update: (diff: number) => void;
|
||||||
let onComplete: VoidFunction;
|
let onComplete: VoidFunction;
|
||||||
let link: ComputedRef<BoardNode>;
|
let link: ComputedRef<BoardNode>;
|
||||||
|
let randomResource: Resources;
|
||||||
|
let effectedResource: Resources | "energy";
|
||||||
|
let resourceMulti: DecimalSource;
|
||||||
switch (treasureType) {
|
switch (treasureType) {
|
||||||
case "dirtGeneration":
|
case "cache":
|
||||||
description = `Gain ${format(difficulty)} dirt/s while plane is active`;
|
randomResource = getRandomResource(random);
|
||||||
update = diff => main.grantResource("dirt", Decimal.times(diff, difficulty));
|
description = `Gain ${format(difficulty)}x your current ${randomResource}.`;
|
||||||
link = computed(() => main.resourceNodes.value["dirt"]);
|
onComplete = () =>
|
||||||
|
main.grantResource(
|
||||||
|
randomResource,
|
||||||
|
Decimal.times(
|
||||||
|
(
|
||||||
|
main.resourceNodes.value[randomResource]
|
||||||
|
?.state as unknown as ResourceState | null
|
||||||
|
)?.amount ?? 0,
|
||||||
|
difficulty
|
||||||
|
)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case "generation":
|
||||||
|
randomResource = getRandomResource(random);
|
||||||
|
const gain = Decimal.div(difficulty, 120).times(mineLootTable[randomResource]);
|
||||||
|
description = `Gain ${format(gain)} ${randomResource}/s while plane is active.`;
|
||||||
|
update = diff => main.grantResource(randomResource, Decimal.times(diff, gain));
|
||||||
|
link = computed(() => main.resourceNodes.value[randomResource]);
|
||||||
|
break;
|
||||||
|
case "resourceMulti":
|
||||||
|
effectedResource = randomResource = getRandomResource(random);
|
||||||
|
resourceMulti = Decimal.div(difficulty, 17).pow_base(2);
|
||||||
|
description = `Gain ${format(
|
||||||
|
resourceMulti
|
||||||
|
)}x ${randomResource} while plane is active.`;
|
||||||
|
break;
|
||||||
|
case "energyMulti":
|
||||||
|
effectedResource = "energy";
|
||||||
|
resourceMulti = Decimal.div(difficulty, 17);
|
||||||
|
description = `Gain ${format(resourceMulti)}x energy while plane is active.`;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const cost = Decimal.times(difficulty, random() + 0.5)
|
const cost = Decimal.times(difficulty, random() + 0.5)
|
||||||
|
@ -237,7 +272,9 @@ export function createPlane(id: string, tier: Resources, seed: number) {
|
||||||
},
|
},
|
||||||
update,
|
update,
|
||||||
onComplete,
|
onComplete,
|
||||||
link
|
link,
|
||||||
|
effectedResource,
|
||||||
|
resourceMulti
|
||||||
})) as GenericAchievement;
|
})) as GenericAchievement;
|
||||||
features.push([milestone]);
|
features.push([milestone]);
|
||||||
visibility = milestone.earned;
|
visibility = milestone.earned;
|
||||||
|
@ -317,6 +354,32 @@ export function createPlane(id: string, tier: Resources, seed: number) {
|
||||||
return links;
|
return links;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const resourceMultis = computed(() => {
|
||||||
|
const multis: Partial<Record<Resources | "energy", DecimalSource>> = {};
|
||||||
|
for (let i = 1; i < features.length; i += 2) {
|
||||||
|
const treasure = features[i][0] as GenericAchievement & {
|
||||||
|
effectedResource?: Resources | "energy";
|
||||||
|
resourceMulti: DecimalSource;
|
||||||
|
};
|
||||||
|
if (
|
||||||
|
treasure.earned.value &&
|
||||||
|
treasure.effectedResource != null &&
|
||||||
|
treasure.resourceMulti != null
|
||||||
|
) {
|
||||||
|
if (multis[treasure.effectedResource] != null) {
|
||||||
|
multis[treasure.effectedResource] = Decimal.times(
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
|
multis[treasure.effectedResource]!,
|
||||||
|
treasure.resourceMulti
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
multis[treasure.effectedResource] = treasure.resourceMulti;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return multis;
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
tier: persistent(tier),
|
tier: persistent(tier),
|
||||||
seed: persistent(seed),
|
seed: persistent(seed),
|
||||||
|
@ -331,6 +394,7 @@ export function createPlane(id: string, tier: Resources, seed: number) {
|
||||||
features,
|
features,
|
||||||
resourceTabCollapsed,
|
resourceTabCollapsed,
|
||||||
links,
|
links,
|
||||||
|
resourceMultis,
|
||||||
display: jsx(() => (
|
display: jsx(() => (
|
||||||
<>
|
<>
|
||||||
<StickyVue class="nav-container">
|
<StickyVue class="nav-container">
|
||||||
|
@ -375,4 +439,23 @@ export function createPlane(id: string, tier: Resources, seed: number) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Using separate method from what's used in mining, because planes are influenced by influences and not things like dowsing
|
||||||
|
function getRandomResource(random: () => number) {
|
||||||
|
const sumResourceWeights = (Object.values(mineLootTable) as number[]).reduce((a, b) => a + b);
|
||||||
|
const resourceWeightsKeys = Object.keys(mineLootTable) as Resources[];
|
||||||
|
const r = Math.floor(random() * sumResourceWeights);
|
||||||
|
let weight = 0;
|
||||||
|
let resource: Resources;
|
||||||
|
for (let i = 0; i < resourceWeightsKeys.length; i++) {
|
||||||
|
const type = resourceWeightsKeys[i];
|
||||||
|
weight += mineLootTable[type];
|
||||||
|
if (r < weight) {
|
||||||
|
resource = type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
|
return resource!;
|
||||||
|
}
|
||||||
|
|
||||||
export type GenericPlane = ReturnType<typeof createPlane>;
|
export type GenericPlane = ReturnType<typeof createPlane>;
|
||||||
|
|
|
@ -74,7 +74,7 @@ export interface PortalState {
|
||||||
powered: boolean;
|
powered: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const mineLootTable = {
|
export const mineLootTable = {
|
||||||
dirt: 120,
|
dirt: 120,
|
||||||
sand: 60,
|
sand: 60,
|
||||||
gravel: 40,
|
gravel: 40,
|
||||||
|
@ -202,7 +202,7 @@ const passives = {
|
||||||
},
|
},
|
||||||
gravel: {
|
gravel: {
|
||||||
description: (empowered: boolean) =>
|
description: (empowered: boolean) =>
|
||||||
empowered ? "Quadruples material drops" : "Doubles material drops"
|
empowered ? "Quadruples mine ore drops" : "Doubles mine ore drops"
|
||||||
},
|
},
|
||||||
stone: {
|
stone: {
|
||||||
description: (empowered: boolean) =>
|
description: (empowered: boolean) =>
|
||||||
|
@ -715,10 +715,14 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
||||||
progressColor: "var(--accent3)",
|
progressColor: "var(--accent3)",
|
||||||
classes: node => ({
|
classes: node => ({
|
||||||
"affected-node":
|
"affected-node":
|
||||||
dowsing.value != null &&
|
(dowsing.value != null &&
|
||||||
isPowered(dowsing.value) &&
|
isPowered(dowsing.value) &&
|
||||||
(dowsing.value.state as unknown as DowsingState).resources.includes(
|
(dowsing.value.state as unknown as DowsingState).resources.includes(
|
||||||
(node.state as unknown as ResourceState).type
|
(node.state as unknown as ResourceState).type
|
||||||
|
)) ||
|
||||||
|
Decimal.neq(
|
||||||
|
planarMultis.value[(node.state as unknown as ResourceState).type] ?? 1,
|
||||||
|
1
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
draggable: true
|
draggable: true
|
||||||
|
@ -1107,20 +1111,34 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
||||||
});
|
});
|
||||||
// TODO link to influences
|
// TODO link to influences
|
||||||
}
|
}
|
||||||
links.push(
|
(board as GenericBoard).types.portal.nodes.value.forEach(node => {
|
||||||
...activePortals.value
|
const plane = layers[(node.state as unknown as PortalState).id] as GenericPlane;
|
||||||
.map(node =>
|
plane.links.value.forEach(n => {
|
||||||
(
|
if (n.value != null) {
|
||||||
layers[(node.state as unknown as PortalState).id] as GenericPlane
|
links.push({
|
||||||
).links.value.map(n => ({
|
|
||||||
startNode: node,
|
startNode: node,
|
||||||
endNode: n.value,
|
endNode: n.value,
|
||||||
stroke: "var(--accent3)",
|
stroke: isPowered(node) ? "var(--accent3)" : "var(--foreground)",
|
||||||
strokeWidth: 4
|
strokeWidth: 4
|
||||||
}))
|
});
|
||||||
)
|
}
|
||||||
.reduce((a, b) => [...a, ...b], [])
|
});
|
||||||
);
|
(Object.keys(plane.resourceMultis.value) as (Resources | "energy")[]).forEach(
|
||||||
|
type => {
|
||||||
|
if (type !== "energy" && type in resourceNodes.value) {
|
||||||
|
links.push({
|
||||||
|
startNode: node,
|
||||||
|
endNode: resourceNodes.value[type],
|
||||||
|
stroke: isPowered(node)
|
||||||
|
? "var(--accent1)"
|
||||||
|
: "var(--foreground)",
|
||||||
|
strokeWidth: 4
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return links;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return links;
|
return links;
|
||||||
}
|
}
|
||||||
|
@ -1143,6 +1161,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
||||||
|
|
||||||
function grantResource(type: Resources, amount: DecimalSource) {
|
function grantResource(type: Resources, amount: DecimalSource) {
|
||||||
let node = resourceNodes.value[type];
|
let node = resourceNodes.value[type];
|
||||||
|
amount = Decimal.times(amount, resourceGain[type].computedModifier.value);
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
node = {
|
node = {
|
||||||
id: getUniqueNodeID(board),
|
id: getUniqueNodeID(board),
|
||||||
|
@ -1169,6 +1188,26 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const planarMultis = computed(() => {
|
||||||
|
const multis: Partial<Record<Resources | "energy", DecimalSource>> = {};
|
||||||
|
board.types.portal.nodes.value.forEach(n => {
|
||||||
|
if (!isPowered(n)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const plane = layers[(n.state as unknown as PortalState).id] as GenericPlane;
|
||||||
|
const planeMultis = plane.resourceMultis.value;
|
||||||
|
(Object.keys(planeMultis) as (Resources | "energy")[]).forEach(type => {
|
||||||
|
if (multis[type] != null) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
|
multis[type] = Decimal.times(multis[type]!, planeMultis[type]!);
|
||||||
|
} else {
|
||||||
|
multis[type] = planeMultis[type];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return multis;
|
||||||
|
});
|
||||||
|
|
||||||
const energyModifier = createSequentialModifier(() => [
|
const energyModifier = createSequentialModifier(() => [
|
||||||
...resourceNames.map(resource =>
|
...resourceNames.map(resource =>
|
||||||
createMultiplicativeModifier(() => ({
|
createMultiplicativeModifier(() => ({
|
||||||
|
@ -1205,6 +1244,11 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
||||||
: "") + tools.stone.name,
|
: "") + tools.stone.name,
|
||||||
enabled: () => toolNodes.value["stone"] != null
|
enabled: () => toolNodes.value["stone"] != null
|
||||||
})),
|
})),
|
||||||
|
createMultiplicativeModifier(() => ({
|
||||||
|
multiplier: () => planarMultis.value.energy ?? 1,
|
||||||
|
description: "Planar Treasures",
|
||||||
|
enabled: () => Decimal.neq(planarMultis.value.energy ?? 1, 1)
|
||||||
|
})),
|
||||||
createAdditiveModifier(() => ({
|
createAdditiveModifier(() => ({
|
||||||
addend: () => Decimal.pow(100, poweredMachines.value).div(10).neg(),
|
addend: () => Decimal.pow(100, poweredMachines.value).div(10).neg(),
|
||||||
description: "Powered Machines (100^n/10 energy/s)",
|
description: "Powered Machines (100^n/10 energy/s)",
|
||||||
|
@ -1293,6 +1337,23 @@ 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 resourceGain = (Object.keys(mineLootTable) as Resources[]).reduce((acc, resource) => {
|
||||||
|
const modifier = createSequentialModifier(() => [
|
||||||
|
createMultiplicativeModifier(() => ({
|
||||||
|
multiplier: () => planarMultis.value[resource] ?? 1,
|
||||||
|
description: "Planar Treasures",
|
||||||
|
enabled: () => Decimal.neq(planarMultis.value[resource] ?? 1, 1)
|
||||||
|
}))
|
||||||
|
]);
|
||||||
|
const computedModifier = computed(() => modifier.apply(1));
|
||||||
|
const section = {
|
||||||
|
title: `${camelToTitle(resource)} Gain`,
|
||||||
|
modifier
|
||||||
|
};
|
||||||
|
acc[resource] = { modifier, computedModifier, section };
|
||||||
|
return acc;
|
||||||
|
}, {} as Record<Resources, { modifier: WithRequired<Modifier, "invert" | "description">; computedModifier: ComputedRef<DecimalSource>; section: Section }>);
|
||||||
|
|
||||||
const [energyTab, energyTabCollapsed] = createCollapsibleModifierSections(() => [
|
const [energyTab, energyTabCollapsed] = createCollapsibleModifierSections(() => [
|
||||||
{
|
{
|
||||||
title: "Energy Gain",
|
title: "Energy Gain",
|
||||||
|
@ -1325,6 +1386,9 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
||||||
const [resourcesTab, resourcesCollapsed] = createCollapsibleModifierSections(() =>
|
const [resourcesTab, resourcesCollapsed] = createCollapsibleModifierSections(() =>
|
||||||
Object.values(dropRates).map(d => d.section)
|
Object.values(dropRates).map(d => d.section)
|
||||||
);
|
);
|
||||||
|
const [resourceGainTab, resourceGainCollapsed] = createCollapsibleModifierSections(() =>
|
||||||
|
Object.values(resourceGain).map(d => d.section)
|
||||||
|
);
|
||||||
const modifierTabs = createTabFamily({
|
const modifierTabs = createTabFamily({
|
||||||
general: () => ({
|
general: () => ({
|
||||||
display: "Energy",
|
display: "Energy",
|
||||||
|
@ -1335,7 +1399,7 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
||||||
energyTabCollapsed
|
energyTabCollapsed
|
||||||
}),
|
}),
|
||||||
mining: () => ({
|
mining: () => ({
|
||||||
display: "Mining",
|
display: "Mine",
|
||||||
glowColor(): string {
|
glowColor(): string {
|
||||||
return modifierTabs.activeTab.value === this.tab ? "white" : "";
|
return modifierTabs.activeTab.value === this.tab ? "white" : "";
|
||||||
},
|
},
|
||||||
|
@ -1344,13 +1408,23 @@ export const main = createLayer("main", function (this: BaseLayer) {
|
||||||
miningTabCollapsed
|
miningTabCollapsed
|
||||||
}),
|
}),
|
||||||
resources: () => ({
|
resources: () => ({
|
||||||
display: "Resources",
|
display: "Mine Rates",
|
||||||
glowColor(): string {
|
glowColor(): string {
|
||||||
return modifierTabs.activeTab.value === this.tab ? "white" : "";
|
return modifierTabs.activeTab.value === this.tab ? "white" : "";
|
||||||
},
|
},
|
||||||
visibility: () => dowsing.value != null,
|
visibility: () => dowsing.value != null,
|
||||||
tab: resourcesTab,
|
tab: resourcesTab,
|
||||||
resourcesCollapsed
|
resourcesCollapsed
|
||||||
|
}),
|
||||||
|
resourcesGain: () => ({
|
||||||
|
display: "Resource Gain",
|
||||||
|
glowColor(): string {
|
||||||
|
return modifierTabs.activeTab.value === this.tab ? "white" : "";
|
||||||
|
},
|
||||||
|
visibility: () =>
|
||||||
|
Object.values(resourceGain).some(r => Decimal.neq(r.computedModifier.value, 1)),
|
||||||
|
tab: resourceGainTab,
|
||||||
|
resourceGainCollapsed
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
const showModifiersModal = ref(false);
|
const showModifiersModal = ref(false);
|
||||||
|
|
Loading…
Reference in a new issue