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, { Image } 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 { return new Promise((res) => { p.loadImage(image, (img) => { res(img); }); }); } 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; }