diff --git a/src/data/data.tsx b/src/data/data.tsx index 3c84c9b..404f375 100644 --- a/src/data/data.tsx +++ b/src/data/data.tsx @@ -62,6 +62,12 @@ export interface AutomatorState { powered: boolean; } +export interface InvestmentsState { + portals: string[]; + maxConnections: number; + powered: boolean; +} + export const mineLootTable = { dirt: 120, sand: 60, diff --git a/src/data/nodeTypes.tsx b/src/data/nodeTypes.tsx index 6c4073e..6ba6363 100644 --- a/src/data/nodeTypes.tsx +++ b/src/data/nodeTypes.tsx @@ -34,6 +34,7 @@ import { DowsingState, EmpowererState, InfluenceState, + InvestmentsState, MineState, Passives, PortalGeneratorState, @@ -793,3 +794,52 @@ export const automator = { }), draggable: true } as NodeTypeOptions; + +export const investments = { + shape: Shape.Diamond, + size: 50, + title: "💱", + label: node => { + if (node === main.board.selectedNode.value) { + return { + text: + (node.state as unknown as InvestmentsState).portals.length === 0 + ? "Investments - Drag a portal to me!" + : `Investing (${ + (node.state as unknown as InvestmentsState).portals.length + }/${Decimal.add( + (node.state as unknown as InvestmentsState).maxConnections, + main.computedBonusConnectionsModifier.value + )})` + }; + } + return labelForAcceptingPortal(node, portal => { + return `Auto-buy ${(layers[portal] as GenericPlane).name}'s repeatables and dimensions`; + }); + }, + actionDistance: Math.PI / 4, + actions: [ + { + id: "deselect", + icon: "close", + tooltip: { + text: "Disconnect portals" + }, + onClick(node: BoardNode) { + node.state = { ...(node.state as object), portals: [] }; + main.board.selectedAction.value = null; + main.board.selectedNode.value = null; + }, + visibility: (node: BoardNode) => + (node.state as unknown as InvestmentsState)?.portals.length ?? 0 > 0 + }, + getIncreaseConnectionsAction(x => x.add(3).pow_base(1e8)), + togglePoweredAction + ], + canAccept: canAcceptPortal, + onDrop: onDropPortal, + classes: node => ({ + running: isPowered(node) + }), + draggable: true +} as NodeTypeOptions; diff --git a/src/data/planes.tsx b/src/data/planes.tsx index e1a0595..3dc873d 100644 --- a/src/data/planes.tsx +++ b/src/data/planes.tsx @@ -5,7 +5,7 @@ import { GenericAchievement, createAchievement } from "features/achievements/ach import { createBar } from "features/bars/bar"; import { BoardNode, getUniqueNodeID } from "features/boards/board"; import { GenericClickable, createClickable, setupAutoClick } from "features/clickables/clickable"; -import { createCumulativeConversion } from "features/conversion"; +import { createCumulativeConversion, setupPassiveGeneration } from "features/conversion"; import { CoercableComponent, findFeatures, isVisible, jsx } from "features/feature"; import { GenericRepeatable, RepeatableType, createRepeatable } from "features/repeatable"; import { createReset } from "features/reset"; @@ -47,6 +47,7 @@ import { BoosterState, InfluenceState, Influences, + InvestmentsState, PortalState, ResourceState, Resources, @@ -536,6 +537,16 @@ export function createPlane( {renderRow(clickable)} )); + setupPassiveGeneration(this as GenericLayer, conversion, () => + earnedTreasures.value.length < length && + main.investments.value != null && + isPowered(main.investments.value) && + ( + main.investments.value.state as unknown as InvestmentsState + ).portals.includes(id) + ? 0.01 + : 0 + ); break; case "xp": { const xp = createResource(0); diff --git a/src/data/projEntry.tsx b/src/data/projEntry.tsx index feddc9d..6176dc2 100644 --- a/src/data/projEntry.tsx +++ b/src/data/projEntry.tsx @@ -43,6 +43,7 @@ import { EmpowererState, InfluenceState, Influences, + InvestmentsState, MineState, Passives, PortalGeneratorState, @@ -57,20 +58,21 @@ import { } from "./data"; import "./main.css"; import { + automator, booster, brokenFactory, dowsing, empowerer, factory, influence, + investments, mine, passive, portal, portalGenerator, quarry, resource, - upgrader, - automator + upgrader } from "./nodeTypes"; import { GenericPlane, createPlane } from "./planes"; @@ -90,7 +92,8 @@ const types = { influence, booster, upgrader, - automator + automator, + investments }; /** @@ -117,7 +120,8 @@ export const main = createLayer("main", function (this: BaseLayer) { iron: board.types.portalGenerator.nodes.value[0], gold: board.types.booster.nodes.value[0], platinum: board.types.upgrader.nodes.value[0], - berylium: board.types.automator.nodes.value[0] + berylium: board.types.automator.nodes.value[0], + ultimatum: board.types.investments.nodes.value[0] })); const influenceNodes: ComputedRef> = computed(() => ({ @@ -379,6 +383,18 @@ export const main = createLayer("main", function (this: BaseLayer) { }); }); } + if (investments.value != null) { + (investments.value.state as unknown as InvestmentsState).portals.forEach(portal => { + links.push({ + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + startNode: investments.value!, + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + endNode: portalNodes.value[portal], + stroke: "var(--foreground)", + strokeWidth: 4 + }); + }); + } Object.values(influenceNodes.value).forEach(node => { const state = node.state as unknown as InfluenceState; if (state.type === "increaseResources" || state.type === "decreaseResources") { @@ -409,7 +425,19 @@ export const main = createLayer("main", function (this: BaseLayer) { const booster: ComputedRef = computed(() => toolNodes.value.gold); const upgrader: ComputedRef = computed(() => toolNodes.value.platinum); const automator: ComputedRef = computed(() => toolNodes.value.berylium); - const poweredMachines = [mine, dowsing, quarry, empowerer, booster, upgrader, automator]; + const investments: ComputedRef = computed( + () => toolNodes.value.ultimatum + ); + const poweredMachines = [ + mine, + dowsing, + quarry, + empowerer, + booster, + upgrader, + automator, + investments + ]; function grantResource(type: Resources, amount: DecimalSource) { let node = resourceNodes.value[type]; @@ -820,6 +848,7 @@ export const main = createLayer("main", function (this: BaseLayer) { checkConnections(curr, booster, "portals"); checkConnections(curr, upgrader, "portals"); checkConnections(curr, automator, "portals"); + checkConnections(curr, investments, "portals"); } }); @@ -843,6 +872,7 @@ export const main = createLayer("main", function (this: BaseLayer) { booster, upgrader, automator, + investments, resourceLevels, planarMultis, display: jsx(() => ( diff --git a/src/features/clickables/clickable.ts b/src/features/clickables/clickable.ts index 442ba4d..be6ae0e 100644 --- a/src/features/clickables/clickable.ts +++ b/src/features/clickables/clickable.ts @@ -1,15 +1,21 @@ import ClickableComponent from "features/clickables/Clickable.vue"; import { GenericDecorator } from "features/decorators/common"; -import { +import type { CoercableComponent, GenericComponent, OptionsFunc, Replace, - StyleValue, - findFeatures + StyleValue } from "features/feature"; -import { Component, GatherProps, Visibility, getUniqueID, setDefault } from "features/feature"; -import type { BaseLayer, GenericLayer } from "game/layers"; +import { + Component, + GatherProps, + Visibility, + findFeatures, + getUniqueID, + setDefault +} from "features/feature"; +import type { GenericLayer } from "game/layers"; import type { Unsubscribe } from "nanoevents"; import type { Computable,