Change where score info is displayed

This commit is contained in:
Liam 2022-10-29 13:17:24 +01:00
parent 5ecd18e30a
commit adc76f501f
9 changed files with 178 additions and 84 deletions

@ -0,0 +1,38 @@
import { useSettingsStore } from "../store/overlaySettingsStore";
import { useSongDataStore } from "../store/songDataStore";
import styles from "../styles/cutStats.module.css";
export default function CutStats() {
const [showScoreInfo] = useSettingsStore((store) => [store.showScoreInfo]);
const [saberA, saberB, isLoading] = useSongDataStore((store) => [
store.saberA,
store.saberB,
store.isLoading,
]);
if (isLoading) {
return null;
}
if (!showScoreInfo) {
return null;
}
return (
<div className={styles.cutStats}>
<p className={styles.cutStatsAverageCut}>Average Cut</p>
<div className={styles.cutStatsHands}>
<div className={styles.cutStatsLeft}>
<p>{saberA.averagePreSwing.toFixed(2)}</p>
<p>{saberA.averagePostSwing.toFixed(2)}</p>
<p>{saberA.cutDistanceScore.toFixed(2)}</p>
</div>
<div className={styles.cutStatsRight}>
<p>{saberB.averagePreSwing.toFixed(2)}</p>
<p>{saberB.averagePostSwing.toFixed(2)}</p>
<p>{saberB.cutDistanceScore.toFixed(2)}</p>
</div>
</div>
</div>
);
}

@ -1,16 +1,16 @@
import { getFormattedScorePercent } from "../helpers/map/mapHelpers";
import { useSettingsStore } from "../store/overlaySettingsStore"; import { useSettingsStore } from "../store/overlaySettingsStore";
import { useSongDataStore } from "../store/songDataStore"; import { useSongDataStore } from "../store/songDataStore";
import styles from "../styles/scoreStats.module.css"; import styles from "../styles/scoreStats.module.css";
export default function ScoreStats() { export default function ScoreStats() {
const [showScoreInfo] = useSettingsStore((store) => [store.showScoreInfo]); const [showScoreInfo] = useSettingsStore((store) => [store.showScoreInfo]);
const [percentage, currentScore, currentPP, saberA, saberB, isLoading] = const [percentage, currentScore, currentPP, combo, isLoading] =
useSongDataStore((store) => [ useSongDataStore((store) => [
store.percentage, store.percentage,
store.currentScore, store.currentScore,
store.currentPP, store.currentPP,
store.saberA, store.combo,
store.saberB,
store.isLoading, store.isLoading,
]); ]);
@ -24,28 +24,31 @@ export default function ScoreStats() {
return ( return (
<div className={styles.scoreStats}> <div className={styles.scoreStats}>
<div className={styles.scoreStatsInfo}> <p
<p>{percentage}</p> style={{
<p> fontSize: "45px",
}}
>
{currentScore.toLocaleString("en-us", { {currentScore.toLocaleString("en-us", {
maximumFractionDigits: 2, maximumFractionDigits: 0,
minimumFractionDigits: 2, minimumFractionDigits: 0,
})} })}
</p> </p>
<div className={styles.scoreStatsInfo}>
<div>
<p>Combo: {combo}</p>
<p>
<span
style={{
marginRight: "6px",
}}
>
{getFormattedScorePercent(percentage)}
</span>
{percentage}%
</p>
{currentPP !== undefined ? <p>{currentPP.toFixed(0)}pp</p> : null} {currentPP !== undefined ? <p>{currentPP.toFixed(0)}pp</p> : null}
</div> </div>
<p className={styles.scoreStatsAverageCut}>Average Cut</p>
<div className={styles.scoreStatsHands}>
<div className={styles.scoreStatsLeft}>
<p>{saberA.averagePreSwing.toFixed(2)}</p>
<p>{saberA.averagePostSwing.toFixed(2)}</p>
<p>{saberA.cutDistanceScore.toFixed(2)}</p>
</div>
<div className={styles.scoreStatsRight}>
<p>{saberB.averagePreSwing.toFixed(2)}</p>
<p>{saberB.averagePostSwing.toFixed(2)}</p>
<p>{saberB.cutDistanceScore.toFixed(2)}</p>
</div>
</div> </div>
</div> </div>
); );

@ -1,3 +1,31 @@
export function getMapHashFromLevelId(levelId: string): string { export function getMapHashFromLevelId(levelId: string): string {
return levelId.replace("custom_level_", ""); return levelId.replace("custom_level_", "");
} }
/**
* Formats the score.
* eg: 91% = SS
*
* @param percent The percentage of the current score
*/
export function getFormattedScorePercent(percent: number): string {
if (percent >= 90) {
return "SS";
}
if (percent >= 80) {
return "S";
}
if (percent >= 65) {
return "A";
}
if (percent >= 50) {
return "B";
}
if (percent >= 35) {
return "C";
}
if (percent >= 20) {
return "D";
}
return "E";
}

@ -3,7 +3,6 @@ import { useDataStore } from "../store/overlayDataStore";
import { useSettingsStore } from "../store/overlaySettingsStore"; import { useSettingsStore } from "../store/overlaySettingsStore";
import { usePlayerDataStore } from "../store/playerDataStore"; import { usePlayerDataStore } from "../store/playerDataStore";
import { useSongDataStore } from "../store/songDataStore"; import { useSongDataStore } from "../store/songDataStore";
import Utils from "../utils/utils";
import { getMapHashFromLevelId } from "./map/mapHelpers"; import { getMapHashFromLevelId } from "./map/mapHelpers";
const ip = useSettingsStore.getState().socketAddr; const ip = useSettingsStore.getState().socketAddr;
@ -29,7 +28,9 @@ export function connectClient(attempt: number = 1) {
}; };
client.onclose = () => { client.onclose = () => {
console.log( console.log(
`Unable to connect to HTTPSiraStatus, retrying in ${retryTime} seconds. (Attempt: ${attempt})` `Unable to connect to HTTPSiraStatus, retrying in ${
retryTime / 1000
} seconds. (Attempt: ${attempt})`
); );
setTimeout(() => { setTimeout(() => {
@ -71,15 +72,8 @@ const handlers: any = {
} = data.status.beatmap; } = data.status.beatmap;
state.reset(); state.reset();
state.setInSong(true); state.setInSong(true);
state.setCombo(data.status.performance.combo);
useDataStore.setState({ loadedDuringSong: true }); useDataStore.setState({ loadedDuringSong: true });
state.updateMapData(
getMapHashFromLevelId(levelId),
difficultyEnum,
characteristic,
songName,
songSubName || levelAuthorName,
length
);
const { score, relativeScore } = data.status.performance; const { score, relativeScore } = data.status.performance;
let finalScore = score; let finalScore = score;
@ -89,7 +83,17 @@ const handlers: any = {
const percent = relativeScore * 100; const percent = relativeScore * 100;
state.setCurrentScore(finalScore); state.setCurrentScore(finalScore);
state.setPercent(percent.toFixed(2) + "%"); state.setPercent(percent.toFixed(2));
state.setPp(percent);
state.updateMapData(
getMapHashFromLevelId(levelId),
difficultyEnum,
characteristic,
songName,
songSubName || levelAuthorName,
length
);
} }
}, },
@ -128,19 +132,9 @@ const handlers: any = {
const percent = relativeScore * 100; const percent = relativeScore * 100;
state.setCurrentScore(finalScore); state.setCurrentScore(finalScore);
state.setPercent(percent.toFixed(2) + "%"); state.setPercent(percent.toFixed(2));
state.setCombo(data.status.performance.combo);
const leaderboardType = useSettingsStore.getState().leaderboardType; state.setPp(percent);
let currentPP = Utils.calculatePP(
state.mapStarCount,
percent,
leaderboardType
);
if (currentPP === undefined) {
return;
}
state.setPp(currentPP);
}, },
noteFullyCut: (data: any) => { noteFullyCut: (data: any) => {

@ -1,6 +1,7 @@
import axios from "axios"; import axios from "axios";
import { NextSeo } from "next-seo"; import { NextSeo } from "next-seo";
import { useEffect } from "react"; import { useEffect } from "react";
import CutStats from "../components/CutStats";
import PlayerStats from "../components/PlayerStats"; import PlayerStats from "../components/PlayerStats";
import ScoreStats from "../components/ScoreStats"; import ScoreStats from "../components/ScoreStats";
import SongInfo from "../components/SongInfo"; import SongInfo from "../components/SongInfo";
@ -59,6 +60,7 @@ export default function Overlay(props) {
<div className={styles.main}> <div className={styles.main}>
<NextSeo title="Overlay"></NextSeo> <NextSeo title="Overlay"></NextSeo>
<PlayerStats /> <PlayerStats />
<CutStats />
<ScoreStats /> <ScoreStats />
<SongInfo /> <SongInfo />
</div> </div>

@ -21,6 +21,7 @@ interface SongDataState {
currentSongTime: number; currentSongTime: number;
currentScore: number; currentScore: number;
percentage: string; percentage: string;
combo: number;
currentPP: number | undefined; currentPP: number | undefined;
saberA: { saberA: {
cutDistanceScore: number; cutDistanceScore: number;
@ -45,7 +46,8 @@ interface SongDataState {
setPaused: (paused: boolean) => void; setPaused: (paused: boolean) => void;
setCurrentScore: (score: number) => void; setCurrentScore: (score: number) => void;
setPercent: (percent: string) => void; setPercent: (percent: string) => void;
setPp: (pp: number) => void; setCombo: (combo: number) => void;
setPp: (percent: number) => void;
setInSong: (isInSong: boolean) => void; setInSong: (isInSong: boolean) => void;
setSaberData: (saberType: string, cutData: any) => void; setSaberData: (saberType: string, cutData: any) => void;
} }
@ -67,6 +69,7 @@ export const useSongDataStore = create<SongDataState>()((set) => ({
currentSongTime: 0, currentSongTime: 0,
currentScore: 0, currentScore: 0,
percentage: "100%", percentage: "100%",
combo: 0,
currentPP: undefined, currentPP: undefined,
saberA: { saberA: {
cutDistanceScore: 0.0, cutDistanceScore: 0.0,
@ -133,6 +136,10 @@ export const useSongDataStore = create<SongDataState>()((set) => ({
set({ percentage: percent }); set({ percentage: percent });
}, },
setCombo: (combo: number) => {
set({ combo: combo });
},
setSaberData: (saberType: string, saberData: any) => { setSaberData: (saberType: string, saberData: any) => {
if (saberType === "saberA") { if (saberType === "saberA") {
set({ saberA: saberData }); set({ saberA: saberData });
@ -141,7 +148,14 @@ export const useSongDataStore = create<SongDataState>()((set) => ({
} }
}, },
setPp: (pp: number) => { setPp: (percent: number) => {
const leaderboardType = useSettingsStore.getState().leaderboardType;
const mapStarCount = useSongDataStore.getState().mapStarCount;
let pp = Utils.calculatePP(mapStarCount, percent, leaderboardType);
if (pp === undefined) {
return;
}
set({ currentPP: pp }); set({ currentPP: pp });
}, },
@ -165,6 +179,7 @@ export const useSongDataStore = create<SongDataState>()((set) => ({
currentSongTime: 0, currentSongTime: 0,
currentScore: 0, currentScore: 0,
percentage: "100%", percentage: "100%",
combo: 0,
currentPP: undefined, currentPP: undefined,
saberA: { saberA: {
cutDistanceScore: 0.0, cutDistanceScore: 0.0,

@ -0,0 +1,44 @@
.cutStats {
text-align: center;
position: fixed;
top: 0;
right: 0;
margin-top: 5px;
margin-right: 5px;
min-width: 135px;
display: flex;
justify-content: right;
flex-direction: column;
}
.cutStats p {
font-size: 38px;
line-height: 1.2em;
}
.cutStatsLeft {
text-align: right;
margin-right: 3px;
}
.cutStatsRight {
text-align: left;
}
.cutStatsAverageCut {
font-weight: bold;
}
.cutStatsHands {
display: flex;
justify-content: center;
}
.cutStatsHands p {
min-width: 68px;
}
.cutStatsHands div {
padding-left: 10px;
}

@ -3,6 +3,7 @@
color: white; color: white;
font-size: xx-large; font-size: xx-large;
line-height: 1.4em !important; line-height: 1.4em !important;
height: fit-content;
} }
.main p { .main p {

@ -1,50 +1,19 @@
.scoreStats { .scoreStats {
text-align: center;
position: fixed; position: fixed;
top: 0; margin-top: -5px;
right: 0; margin-left: 10px;
margin-top: 5px;
margin-right: 5px;
min-width: 135px; min-width: 135px;
display: flex; display: flex;
justify-content: right;
flex-direction: column; flex-direction: column;
align-items: right;
} }
.scoreStats p { .scoreStats p {
font-size: 38px; font-size: 38px;
line-height: 1.2em; line-height: 1.1em;
} font-size: 35px;
.scoreStatsLeft {
text-align: right;
margin-right: 3px;
}
.scoreStatsRight {
text-align: left;
}
.scoreStatsAverageCut {
font-weight: bold;
}
.scoreStatsHands {
display: flex;
justify-content: center;
}
.scoreStatsHands p {
min-width: 68px;
}
.scoreStatsHands div {
padding-left: 10px;
} }
.scoreStatsInfo { .scoreStatsInfo {
margin-right: 10px; margin-right: 10px;
text-align: right;
} }