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

125 lines
3.9 KiB
TypeScript
Raw Normal View History

2022-03-03 21:39:48 -06:00
import { globalBus } from "game/events";
2022-06-26 19:17:22 -05:00
import type { State } from "game/persistence";
import { persistent } from "game/persistence";
import type { DecimalSource } from "util/bignum";
import Decimal, { format, formatWhole } from "util/bignum";
import type { ProcessedComputable } from "util/computed";
2022-06-26 19:17:22 -05:00
import type { ComputedRef, Ref } from "vue";
import { computed, isRef, ref, unref, watch } from "vue";
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 = undefined
2022-01-13 22:25:47 -06:00
): Resource<T> {
const resource: Partial<Resource<T>> = isRef(defaultValue)
? defaultValue
: persistent(defaultValue);
2022-01-13 22:25:47 -06:00
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;
}
2022-03-11 09:59:45 -06:00
const tetra8 = new Decimal("10^^8");
const e100 = new Decimal("1e100");
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-03-11 09:59:45 -06:00
if (Decimal.lte(resource.value, e100)) {
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)) {
2022-03-11 09:59:45 -06:00
if (Decimal.gte(curr, tetra8)) {
2022-01-13 22:25:47 -06:00
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)) {
2022-12-01 15:29:13 -08:00
return formatWhole(resource.small ? amount : Decimal.floor(amount));
2022-01-13 22:25:47 -06:00
}
return format(amount, resource.precision, resource.small);
}
export function unwrapResource(resource: ProcessedComputable<Resource>): Resource {
if ("displayName" in resource) {
return resource;
}
return unref(resource);
}