2022-01-14 04:25:47 +00:00
|
|
|
import {
|
|
|
|
Clickable,
|
|
|
|
ClickableOptions,
|
|
|
|
createClickable,
|
|
|
|
GenericClickable
|
2022-02-27 22:04:56 +00:00
|
|
|
} from "@/features/clickables/clickable";
|
2022-01-14 04:25:47 +00:00
|
|
|
import { GenericConversion } from "@/features/conversion";
|
2022-02-27 19:49:34 +00:00
|
|
|
import { CoercableComponent, jsx, Replace, setDefault } from "@/features/feature";
|
2022-02-27 22:04:56 +00:00
|
|
|
import { displayResource } from "@/features/resources/resource";
|
2022-01-14 04:25:47 +00:00
|
|
|
import {
|
|
|
|
createTreeNode,
|
|
|
|
GenericTree,
|
|
|
|
GenericTreeNode,
|
|
|
|
TreeNode,
|
|
|
|
TreeNodeOptions
|
2022-02-27 22:04:56 +00:00
|
|
|
} from "@/features/trees/tree";
|
2022-01-14 04:25:47 +00:00
|
|
|
import player from "@/game/player";
|
|
|
|
import Decimal from "@/util/bignum";
|
|
|
|
import {
|
|
|
|
Computable,
|
|
|
|
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<string>;
|
|
|
|
showNextAt?: Computable<boolean>;
|
|
|
|
display?: Computable<CoercableComponent>;
|
|
|
|
canClick?: Computable<boolean>;
|
|
|
|
}
|
|
|
|
|
|
|
|
type ResetButton<T extends ResetButtonOptions> = Replace<
|
|
|
|
Clickable<T>,
|
|
|
|
{
|
|
|
|
resetDescription: GetComputableTypeWithDefault<T["resetDescription"], Ref<string>>;
|
|
|
|
showNextAt: GetComputableTypeWithDefault<T["showNextAt"], true>;
|
|
|
|
display: GetComputableTypeWithDefault<T["display"], Ref<JSX.Element>>;
|
|
|
|
canClick: GetComputableTypeWithDefault<T["canClick"], Ref<boolean>>;
|
|
|
|
onClick: VoidFunction;
|
|
|
|
}
|
|
|
|
>;
|
|
|
|
|
|
|
|
export type GenericResetButton = Replace<
|
|
|
|
GenericClickable & ResetButton<ResetButtonOptions>,
|
|
|
|
{
|
|
|
|
resetDescription: ProcessedComputable<string>;
|
|
|
|
showNextAt: ProcessedComputable<boolean>;
|
|
|
|
display: ProcessedComputable<CoercableComponent>;
|
|
|
|
canClick: ProcessedComputable<boolean>;
|
|
|
|
}
|
|
|
|
>;
|
|
|
|
|
|
|
|
export function createResetButton<T extends ClickableOptions & ResetButtonOptions>(
|
2022-02-27 19:49:34 +00:00
|
|
|
optionsFunc: () => T
|
2022-01-14 04:25:47 +00:00
|
|
|
): ResetButton<T> {
|
2022-02-27 19:49:34 +00:00
|
|
|
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 " : ""
|
2022-01-14 04:25:47 +00:00
|
|
|
);
|
2022-02-27 19:49:34 +00:00
|
|
|
} else {
|
|
|
|
processComputable(resetButton as T, "resetDescription");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (resetButton.display == null) {
|
|
|
|
resetButton.display = jsx(() => (
|
2022-01-14 04:25:47 +00:00
|
|
|
<span>
|
2022-02-27 19:49:34 +00:00
|
|
|
{unref(resetButton.resetDescription as ProcessedComputable<string>)}
|
2022-01-14 04:25:47 +00:00
|
|
|
<b>
|
|
|
|
{displayResource(
|
2022-02-27 19:49:34 +00:00
|
|
|
resetButton.conversion.gainResource,
|
|
|
|
unref(resetButton.conversion.currentGain)
|
2022-01-14 04:25:47 +00:00
|
|
|
)}
|
2022-02-27 19:49:34 +00:00
|
|
|
</b>{" "}
|
|
|
|
{resetButton.conversion.gainResource.displayName}
|
|
|
|
<div v-show={unref(resetButton.showNextAt)}>
|
|
|
|
<br />
|
|
|
|
Next:{" "}
|
|
|
|
{displayResource(
|
|
|
|
resetButton.conversion.baseResource,
|
|
|
|
unref(resetButton.conversion.nextAt)
|
|
|
|
)}{" "}
|
|
|
|
{resetButton.conversion.baseResource.displayName}
|
|
|
|
</div>
|
2022-01-14 04:25:47 +00:00
|
|
|
</span>
|
2022-02-27 19:49:34 +00:00
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (resetButton.canClick == null) {
|
|
|
|
resetButton.canClick = computed(() =>
|
|
|
|
Decimal.gt(unref(resetButton.conversion.currentGain), 0)
|
2022-01-14 04:25:47 +00:00
|
|
|
);
|
2022-02-27 19:49:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const onClick = resetButton.onClick;
|
|
|
|
resetButton.onClick = function () {
|
|
|
|
resetButton.conversion.convert();
|
|
|
|
resetButton.tree.reset(resetButton.treeNode);
|
|
|
|
onClick?.();
|
|
|
|
};
|
2022-01-14 04:25:47 +00:00
|
|
|
|
2022-02-27 19:49:34 +00:00
|
|
|
return resetButton;
|
|
|
|
}) as unknown as ResetButton<T>;
|
2022-01-14 04:25:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export interface LayerTreeNodeOptions extends TreeNodeOptions {
|
|
|
|
layerID: string;
|
|
|
|
color: string;
|
|
|
|
append?: boolean;
|
|
|
|
}
|
|
|
|
export type LayerTreeNode<T extends LayerTreeNodeOptions> = Replace<
|
|
|
|
TreeNode<T>,
|
|
|
|
{
|
|
|
|
append: ProcessedComputable<boolean>;
|
|
|
|
}
|
|
|
|
>;
|
2022-01-28 04:47:26 +00:00
|
|
|
export type GenericLayerTreeNode = LayerTreeNode<LayerTreeNodeOptions>;
|
2022-01-14 04:25:47 +00:00
|
|
|
|
2022-02-27 19:49:34 +00:00
|
|
|
export function createLayerTreeNode<T extends LayerTreeNodeOptions>(
|
|
|
|
optionsFunc: () => T
|
|
|
|
): LayerTreeNode<T> {
|
|
|
|
return createTreeNode(() => {
|
|
|
|
const options = optionsFunc();
|
|
|
|
processComputable(options as T, "append");
|
|
|
|
return {
|
|
|
|
...options,
|
|
|
|
display: options.layerID,
|
|
|
|
onClick:
|
|
|
|
options.append != null && options.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);
|
2022-01-14 04:25:47 +00:00
|
|
|
}
|
2022-02-27 19:49:34 +00:00
|
|
|
};
|
2022-01-25 04:23:30 +00:00
|
|
|
}) as unknown as LayerTreeNode<T>;
|
2022-01-14 04:25:47 +00:00
|
|
|
}
|