import { Clickable, ClickableOptions, createClickable, GenericClickable } from "features/clickables/clickable"; import { GenericConversion } from "features/conversion"; import { CoercableComponent, jsx, Replace, setDefault } from "features/feature"; import { displayResource } from "features/resources/resource"; import { createTreeNode, GenericTree, GenericTreeNode, TreeNode, TreeNodeOptions } from "features/trees/tree"; import player from "game/player"; import Decimal from "util/bignum"; import { Computable, GetComputableType, GetComputableTypeWithDefault, processComputable, ProcessedComputable } from "util/computed"; import { computed, Ref, unref } from "vue"; export interface ResetButtonOptions extends ClickableOptions { conversion: GenericConversion; tree: GenericTree; treeNode: GenericTreeNode; resetDescription?: Computable; showNextAt?: Computable; display?: Computable; canClick?: Computable; } export type ResetButton = Replace< Clickable, { resetDescription: GetComputableTypeWithDefault>; showNextAt: GetComputableTypeWithDefault; display: GetComputableTypeWithDefault>; canClick: GetComputableTypeWithDefault>; onClick: VoidFunction; } >; export type GenericResetButton = Replace< GenericClickable & ResetButton, { resetDescription: ProcessedComputable; showNextAt: ProcessedComputable; display: ProcessedComputable; canClick: ProcessedComputable; } >; export function createResetButton( optionsFunc: () => T ): ResetButton { return createClickable(() => { const resetButton = optionsFunc(); processComputable(resetButton as T, "showNextAt"); setDefault(resetButton, "showNextAt", true); if (resetButton.resetDescription == null) { resetButton.resetDescription = computed(() => Decimal.lt(resetButton.conversion.gainResource.value, 1e3) ? "Reset for " : "" ); } else { processComputable(resetButton as T, "resetDescription"); } if (resetButton.display == null) { resetButton.display = jsx(() => ( {unref(resetButton.resetDescription as ProcessedComputable)} {displayResource( resetButton.conversion.gainResource, unref(resetButton.conversion.actualGain) )} {" "} {resetButton.conversion.gainResource.displayName}

Next:{" "} {displayResource( resetButton.conversion.baseResource, unref(resetButton.conversion.nextAt) )}{" "} {resetButton.conversion.baseResource.displayName}
)); } if (resetButton.canClick == null) { resetButton.canClick = computed(() => Decimal.gt(unref(resetButton.conversion.actualGain), 0) ); } const onClick = resetButton.onClick; resetButton.onClick = function () { if (!unref(resetButton.canClick)) { return; } resetButton.conversion.convert(); resetButton.tree.reset(resetButton.treeNode); onClick?.(); }; return resetButton; }) as unknown as ResetButton; } export interface LayerTreeNodeOptions extends TreeNodeOptions { layerID: string; color: Computable; // marking as required display?: Computable; append?: Computable; } export type LayerTreeNode = Replace< TreeNode, { display: GetComputableTypeWithDefault; append: GetComputableType; } >; export type GenericLayerTreeNode = Replace< LayerTreeNode, { display: ProcessedComputable; append?: ProcessedComputable; } >; export function createLayerTreeNode( optionsFunc: () => T ): LayerTreeNode { return createTreeNode(() => { const options = optionsFunc(); processComputable(options as T, "display"); setDefault(options, "display", options.layerID); processComputable(options as T, "append"); return { ...options, display: options.layerID, onClick: unref((options as unknown as GenericLayerTreeNode).append) ? function () { if (player.tabs.includes(options.layerID)) { const index = player.tabs.lastIndexOf(options.layerID); player.tabs.splice(index, 1); } else { player.tabs.push(options.layerID); } } : function () { player.tabs.splice(1, 1, options.layerID); } }; }) as unknown as LayerTreeNode; }