diff --git a/src/data/planes.tsx b/src/data/planes.tsx index ca62ab1..d961637 100644 --- a/src/data/planes.tsx +++ b/src/data/planes.tsx @@ -3,9 +3,9 @@ import SpacerVue from "components/layout/Spacer.vue"; import StickyVue from "components/layout/Sticky.vue"; import { GenericAchievement, createAchievement } from "features/achievements/achievement"; import { BoardNode, getUniqueNodeID } from "features/boards/board"; -import { findFeatures, jsx } from "features/feature"; +import { CoercableComponent, findFeatures, isVisible, jsx } from "features/feature"; import { GenericRepeatable, RepeatableType, createRepeatable } from "features/repeatable"; -import { createResource } from "features/resources/resource"; +import { createResource, displayResource } from "features/resources/resource"; import { addTooltip } from "features/tooltips/tooltip"; import { GenericUpgrade, UpgradeType, createUpgrade } from "features/upgrades/upgrade"; import Formula, { unrefFormulaSource } from "game/formulas/formulas"; @@ -42,6 +42,9 @@ import type { ResourceState, Resources, PortalState } from "./projEntry"; import { getColor, getName, sfc32 } from "./utils"; import { useToast } from "vue-toastification"; import TooltipVue from "features/tooltips/Tooltip.vue"; +import { createConversion, createCumulativeConversion } from "features/conversion"; +import { createClickable } from "features/clickables/clickable"; +import ResourceVue from "features/resources/Resource.vue"; const toast = useToast(); @@ -123,6 +126,7 @@ export function createPlane( modifier: Modifier; cost: FormulaSource; }[] = []; + const displays: Record = {}; function prepareFeature({ feature, @@ -130,14 +134,16 @@ export function createPlane( modifier, cost, previewModifier, - showETA + showETA, + previewCost }: { feature: VueFeature; canClick: Computable; modifier: WithRequired; cost: FormulaSource; - previewModifier?: WithRequired; + previewModifier: WithRequired; showETA?: Computable; + previewCost?: FormulaSource; }) { canClick = convertComputable(canClick); showETA = convertComputable(showETA); @@ -147,20 +153,28 @@ export function createPlane( shouldShowPreview: computed( () => unref(canClick as ProcessedComputable) && isHovering.value ), - modifier: previewModifier ?? modifier, - cost + modifier: createSequentialModifier(() => { + const modifiers = resourceModifiers.slice() as WithRequired< + Modifier, + "invert" + >[]; + modifiers.splice(modifiers.indexOf(modifier), 1, previewModifier); + return modifiers; + }), + cost: previewCost ?? cost }); resourceModifiers.push(modifier); const eta = estimateTime(resource, computedResourceGain, () => unrefFormulaSource(cost) ); - addTooltip(feature, { + const tooltip = addTooltip(feature, { display: showETA == null ? eta : () => (unref(showETA as ProcessedComputable) ? eta.value : ""), direction: Direction.Down }); + return { isHovering, eta, tooltip }; } const features: VueFeature[][] = []; @@ -179,8 +193,8 @@ export function createPlane( for (let i = 0; i < length; i++) { const featureWeights = { upgrades: 32, - repeatables: i <= 1 ? 0 : 16 - // conversion: i <= 3 ? 0 : 8, + repeatables: i <= 1 ? 0 : 16, + conversion: i <= 3 ? 0 : 8 // xp: i <= 5 ? 0 : 4, // dimensions: i <= 7 ? 0 : 2, // prestige: i <= 7 && i < length - 1 ? 0 : 1 @@ -200,6 +214,8 @@ export function createPlane( const title = getRandomUpgrade(random); let description = ""; let modifier: WithRequired; + let previewModifier: WithRequired; + const currentN = n.value; switch (upgradeType) { case "add": { const addend = Decimal.add(cost, 10).pow(random() / 4 + 0.875); @@ -210,6 +226,7 @@ export function createPlane( description: title, enabled: upgrade.bought })); + previewModifier = createAdditiveModifier(() => ({ addend })); break; } case "mult": { @@ -218,13 +235,16 @@ export function createPlane( resource.displayName } gain by x${format(multiplier)}.`; costFormula = costFormula.add( - Decimal.sub(multiplier, 1).times(cachedGain[n.value - 1]) + Decimal.sub(multiplier, 1).times(cachedGain[currentN - 1]) ); modifier = createMultiplicativeModifier(() => ({ multiplier, description: title, enabled: upgrade.bought })); + previewModifier = createMultiplicativeModifier(() => ({ + multiplier + })); break; } case "pow": { @@ -233,13 +253,14 @@ export function createPlane( resource.displayName } gain to the ^${format(exponent)}`; costFormula = costFormula - .add(Decimal.pow(cachedGain[n.value - 1], exponent)) - .sub(cachedGain[n.value - 1]); + .add(Decimal.pow(cachedGain[currentN - 1], exponent)) + .sub(cachedGain[currentN - 1]); modifier = createExponentialModifier(() => ({ exponent, description: title, enabled: upgrade.bought })); + previewModifier = createExponentialModifier(() => ({ exponent })); } } cachedGain[n.value] = costFormula.evaluate(); @@ -261,7 +282,8 @@ export function createPlane( canClick: () => upgrade.canPurchase.value, modifier, cost, - showETA: () => !upgrade.bought.value + showETA: () => !upgrade.bought.value, + previewModifier }); upgrades.push(upgrade); } @@ -309,11 +331,14 @@ export function createPlane( description: title, enabled: () => Decimal.gt(repeatable.amount.value, 0) })); - previewModifier = createAdditiveModifier(() => ({ addend })); + previewModifier = createAdditiveModifier(() => ({ + addend: () => + Decimal.add(repeatable.amount.value, 1).times(addend) + })); break; } case "mult": { - const multiplier = random() + 1; + const multiplier = random() * 0.75 + 1.25; description = `Multiply previous ${ resource.displayName } gain by x${format(multiplier)}.`; @@ -325,7 +350,7 @@ export function createPlane( .times(5) .pow_base(multiplier) .sub(1) - .times(cachedGain[currentN]) + .times(cachedGain[currentN - 1]) ) ); effect = computed( @@ -340,7 +365,8 @@ export function createPlane( enabled: () => Decimal.gt(repeatable.amount.value, 0) })); previewModifier = createMultiplicativeModifier(() => ({ - multiplier + multiplier: () => + Decimal.add(repeatable.amount.value, 1).pow_base(multiplier) })); break; } @@ -371,6 +397,125 @@ export function createPlane( } features.push(repeatables); break; + case "conversion": + const prestigeResource = createResource(0, getName(random)); + const prestigeColor = getColor([0.64, 0.75, 0.55], random); + const cost = nextCost.value; + const costExponent = random() / 2 + 0.25; // Random from 0.25 - 0.75 + const effectExponent = random() / 2 + 0.25; // ditto + const currentN = n.value; + costFormula = costFormula.add( + computed(() => + Decimal.sub(n.value, currentN) + .add(1) + .pow_base(5) + .pow(effectExponent) + .times(cachedGain[currentN - 1]) + ) + ); + const conversion = createCumulativeConversion(() => ({ + baseResource: noPersist(resource), + gainResource: prestigeResource, + formula: x => x.div(cost).pow(costExponent), + spend() { + resource.value = 0; + } + })); + cachedGain[n.value] = costFormula.evaluate(); + n.value += 2; + const clickableVisibility = visibility; + const title = getRandomUpgrade(random); + const formula = Formula.variable(prestigeResource).pow(effectExponent).add(1); + const modifier = createMultiplicativeModifier(() => ({ + multiplier: () => formula.evaluate(), + description: title, + enabled: () => Decimal.gt(prestigeResource.value, 0) + })); + const previewModifier = createMultiplicativeModifier(() => ({ + multiplier: () => + formula.evaluate( + Decimal.add(prestigeResource.value, conversion.actualGain.value) + ) + })); + const clickable = createClickable(() => ({ + display: { + title, + description: jsx(() => ( + + Reset {resource.displayName} for{" "} + {displayResource( + prestigeResource, + Decimal.clampMin(conversion.actualGain.value, 1) + )}{" "} + {prestigeResource.displayName} +
+
+ Next:{" "} + {displayResource( + resource, + Decimal.lt(conversion.actualGain.value, 1) + ? conversion.currentAt.value + : conversion.nextAt.value + )}{" "} + {resource.displayName} +
+
+ )) + }, + style: { + width: "200px", + minHeight: "100px" + }, + canClick: () => Decimal.gte(conversion.actualGain.value, 1), + prestigeResource, + onClick: conversion.convert, + visibility: clickableVisibility + })); + const { isHovering } = prepareFeature({ + feature: clickable, + canClick: () => unref(clickable.canClick), + modifier, + cost, + previewCost: resource, + previewModifier + }); + const showPreview = computed( + () => isHovering.value && clickable.canClick.value + ); + features.push([clickable]); + const resourcePreview = createFormulaPreview( + Formula.variable(prestigeResource), + showPreview, + conversion.actualGain + ); + const effectReview = createFormulaPreview( + formula, + showPreview, + conversion.actualGain + ); + displays[i * 2] = jsx(() => ( + <> + {isVisible(clickable.visibility) ? ( +
+ You have{" "} +

+ {resourcePreview()} +

{" "} + {prestigeResource.displayName}, +
+ providing a {effectReview()}x multiplier to previous{" "} + {resource.displayName} gain +
+ ) : null} + {renderRow(clickable)} + + )); + break; } const treasureWeights = { cache: "increaseCaches" in influenceState ? 10 : 1, @@ -603,10 +748,7 @@ export function createPlane( const resourceProductionChange = computed(() => { const preview = previews.find(p => p.shouldShowPreview.value); if (preview) { - return Decimal.sub( - preview.modifier.apply(computedResourceGain.value), - computedResourceGain.value - ); + return Decimal.sub(preview.modifier.apply(0), computedResourceGain.value); } return 0; }); @@ -769,7 +911,9 @@ export function createPlane( - {features.map(row => renderRow(...row))} + {features.map((row, i) => + i in displays ? render(displays[i]) : renderRow(...row) + )} {render(modifiersModal)} )),