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";
|
2022-07-25 21:35:37 -05:00
|
|
|
import type { ProcessedComputable } from "util/computed";
|
2022-06-26 19:17:22 -05:00
|
|
|
import type { ComputedRef, Ref } from "vue";
|
2022-07-25 21:35:37 -05:00
|
|
|
import { computed, isRef, ref, unref, watch } from "vue";
|
2022-01-13 22:25:47 -06:00
|
|
|
|
2022-02-27 13:49:34 -06:00
|
|
|
export interface Resource<T = DecimalSource> extends Ref<T> {
|
2022-01-13 22:25:47 -06:00
|
|
|
displayName: string;
|
|
|
|
precision: number;
|
2022-03-02 20:28:11 -06:00
|
|
|
small?: boolean;
|
2022-02-27 13:49:34 -06:00
|
|
|
}
|
2022-01-13 22:25:47 -06:00
|
|
|
|
|
|
|
export function createResource<T extends State>(
|
|
|
|
defaultValue: T | Ref<T>,
|
|
|
|
displayName = "points",
|
|
|
|
precision = 0,
|
2022-03-02 20:28:11 -06:00
|
|
|
small = undefined
|
2022-01-13 22:25:47 -06:00
|
|
|
): Resource<T> {
|
2022-03-12 15:00:11 -06:00
|
|
|
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");
|
2022-02-27 13:49:34 -06:00
|
|
|
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 => {
|
2022-02-27 13:49:34 -06:00
|
|
|
oompsMag.value = 0;
|
2022-03-11 09:59:45 -06:00
|
|
|
if (Decimal.lte(resource.value, e100)) {
|
2022-02-27 13:49:34 -06:00
|
|
|
lastPoints.value = resource.value;
|
2022-01-13 22:25:47 -06:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let curr = resource.value;
|
2022-02-27 13:49:34 -06:00
|
|
|
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);
|
2022-02-27 13:49:34 -06:00
|
|
|
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") &&
|
2022-02-27 13:49:34 -06:00
|
|
|
oompsMag.value <= 5 &&
|
2022-01-13 22:25:47 -06:00
|
|
|
Decimal.gt(prev, 0)
|
|
|
|
) {
|
|
|
|
curr = Decimal.log10(curr);
|
|
|
|
prev = Decimal.log10(prev);
|
2022-02-27 13:49:34 -06:00
|
|
|
oomps.value = curr.sub(prev).div(diff);
|
|
|
|
oompsMag.value++;
|
2022-01-13 22:25:47 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2022-02-27 13:49:34 -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" +
|
2022-02-27 13:49:34 -06:00
|
|
|
(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 {
|
2022-02-27 13:49:34 -06:00
|
|
|
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);
|
|
|
|
}
|
2022-07-25 21:35:37 -05:00
|
|
|
|
|
|
|
export function unwrapResource(resource: ProcessedComputable<Resource>): Resource {
|
|
|
|
if ("displayName" in resource) {
|
|
|
|
return resource;
|
|
|
|
}
|
|
|
|
return unref(resource);
|
|
|
|
}
|