nise/nise-replay-viewer/src/utils.ts

87 lines
2.0 KiB
TypeScript

import { BeatmapDecoder } from "osu-parsers";
import { ScoreDecoder } from "../osu-parsers";
import { StandardRuleset, StandardBeatmap } from "osu-standard-stable";
import { IMod, Score } from "osu-classes";
import p5 from "p5";
import { create } from "zustand";
const ruleset = new StandardRuleset();
const scoreDecoder = new ScoreDecoder();
const beatmapDecoder = new BeatmapDecoder();
export async function getReplay(buffer: ArrayBuffer) {
const repl = await scoreDecoder.decodeFromBuffer(buffer);
repl.info.ruleset = ruleset;
return repl;
}
export async function getBeatmap(mapText: string, scoreBase: Score) {
const map = beatmapDecoder.decodeFromString(mapText);
const score = scoreBase.info;
score.accuracy =
(score.count300 + score.count100 / 3 + score.count50 / 6) /
(score.count300 + score.count100 + score.count50 + score.countMiss);
return ruleset.applyToBeatmap(map);
}
export async function loadImageAsync(image: string): Promise<p5.Image> {
return new Promise((resolve, reject) => {
p.loadImage(
image,
(img) => {
resolve(img);
},
(err) => {
reject(err);
}
);
});
}
export function clamp(num: number, min: number, max: number) {
if (num > max) return max;
if (num < min) return min;
return num
}
export const state = create<{
beatmap: StandardBeatmap | null;
replay: Score | null;
metadataEditorDialog: boolean;
openDialog: boolean;
saveDialog: boolean;
dataAnalysisDialog: boolean;
achivementsDialog: boolean;
aboutDialog: boolean;
grda: any;
tool: "cursor" | "brush" | "advanced" | "smoother";
mods: IMod[] | null;
playing: boolean;
time: number;
speed: number;
}>(() => ({
metadataEditorDialog: false,
openDialog: false,
saveDialog: false,
aboutDialog: false,
achivementsDialog: false,
dataAnalysisDialog: false,
beatmap: null,
replay: null,
grda: null,
tool: "cursor",
mods: null,
playing: false,
time: 0,
speed: 1
}));
export let p: p5;
export function setEnv(_p: p5) {
p = _p;
}