Profectus-Demo/src/features/resources/resource.ts

110 lines
3.4 KiB
TypeScript
Raw Normal View History

2022-01-13 22:25:47 -06:00
import Decimal, { DecimalSource, format, formatWhole } from "@/util/bignum";
import { computed, ComputedRef, ref, Ref, watch } from "vue";
2022-01-13 22:25:47 -06:00
import { globalBus } from "@/game/events";
import { State, persistent } from "@/game/persistence";
2022-01-13 22:25:47 -06:00
export interface Resource<T = DecimalSource> extends Ref<T> {
2022-01-13 22:25:47 -06:00
displayName: string;
precision: number;
small: boolean;
}
2022-01-13 22:25:47 -06:00
export function createResource<T extends State>(
defaultValue: T | Ref<T>,
displayName = "points",
precision = 0,
small = false
): Resource<T> {
const resource: Partial<Resource<T>> = persistent(defaultValue);
resource.displayName = displayName;
resource.precision = precision;
resource.small = small;
return resource as Resource<T>;
}
export function trackBest(resource: Resource): Ref<DecimalSource> {
const best = persistent(resource.value);
watch(resource, amount => {
if (Decimal.gt(amount, best.value)) {
best.value = amount;
}
});
return best;
}
export function trackTotal(resource: Resource): Ref<DecimalSource> {
const total = persistent(resource.value);
watch(resource, (amount, prevAmount) => {
if (Decimal.gt(amount, prevAmount)) {
total.value = Decimal.add(total.value, Decimal.sub(amount, prevAmount));
}
});
return total;
}
export function trackOOMPS(
resource: Resource,
pointGain?: ComputedRef<DecimalSource>
): Ref<string> {
const oomps = ref<DecimalSource>(0);
const oompsMag = ref(0);
const lastPoints = ref<DecimalSource>(0);
2022-01-13 22:25:47 -06:00
globalBus.on("update", diff => {
oompsMag.value = 0;
2022-01-13 22:25:47 -06:00
if (Decimal.lte(resource.value, 1e100)) {
lastPoints.value = resource.value;
2022-01-13 22:25:47 -06:00
return;
}
let curr = resource.value;
let prev = lastPoints.value;
lastPoints.value = curr;
2022-01-13 22:25:47 -06:00
if (Decimal.gt(curr, prev)) {
if (Decimal.gte(curr, "10^^8")) {
curr = Decimal.slog(curr, 1e10);
prev = Decimal.slog(prev, 1e10);
oomps.value = curr.sub(prev).div(diff);
oompsMag.value = -1;
2022-01-13 22:25:47 -06:00
} else {
while (
2022-01-24 22:23:30 -06:00
Decimal.div(curr, prev).log(10).div(diff).gte("100") &&
oompsMag.value <= 5 &&
2022-01-13 22:25:47 -06:00
Decimal.gt(prev, 0)
) {
curr = Decimal.log10(curr);
prev = Decimal.log10(prev);
oomps.value = curr.sub(prev).div(diff);
oompsMag.value++;
2022-01-13 22:25:47 -06:00
}
}
}
});
const oompsString = computed(() => {
if (oompsMag.value === 0) {
return pointGain
? format(pointGain.value, resource.precision, resource.small) +
" " +
resource.displayName +
"/s"
: "";
}
return (
format(oomps.value) +
2022-01-13 22:25:47 -06:00
" OOM" +
(oompsMag.value < 0 ? "^OOM" : "^" + oompsMag.value) +
"s/sec"
);
});
return oompsString;
2022-01-13 22:25:47 -06:00
}
export function displayResource(resource: Resource, overrideAmount?: DecimalSource): string {
const amount = overrideAmount ?? resource.value;
2022-01-13 22:25:47 -06:00
if (Decimal.eq(resource.precision, 0)) {
return formatWhole(amount);
}
return format(amount, resource.precision, resource.small);
}