rg-stats
Version:
A library for calculating various rhythm game stats.
51 lines (42 loc) • 1.75 kB
text/typescript
import { ThrowIf } from "../util/throw-if";
/**
* Calculates the jubility of a score. Returns 0 for anything less than 700k.
*
* @param score - The score value. This is between 0 and 1million.
* @param musicRate - The Music Rate of their score -- this is a percentage value.
* This is between 0 and 120, where 100-120 is only achiveable on hard mode.
* @param level - The level for the chart.
*/
export function calculate(score: number, musicRate: number, level: number) {
ThrowIf.negative(score, "Score cannot be negative.", { score });
ThrowIf.negative(level, "Level cannot be negative.", { level });
ThrowIf.negative(musicRate, "MusicRate cannot be negative.", { musicRate });
ThrowIf(score > 1_000_000, "Score cannot be greater than 1million.", { score });
ThrowIf(musicRate > 120, "MusicRate cannot be greater than 120.", { musicRate });
if (score < 700_000) {
return 0;
}
const levelInt = Math.round(level * 10);
const musicRateInt = Math.floor(musicRate * 10);
// Note: These constants are arbitrary. I have no idea why they're like this.
const jub = (levelInt * 125 * musicRateInt) / 99;
// Jubility is *always* floored to one decimal place.
return Math.floor(jub / 100) / 10;
}
/**
* Given a jubility, return the musicRate necessary to get that jubility.
* This assumes that the player has a score >= 700k, as otherwise no inversion
* is possible.
*
* @param jubility - The jubility to inversely calculate.
* @param level - The level for the chart.
*/
export function inverse(jubility: number, level: number) {
const rate = (99 / (12.5 * level)) * jubility;
ThrowIf(
rate > 120,
`A jubility of ${jubility} is not possible on a chart with level ${level}.`,
{ jubility, level }
);
return rate;
}