Change where score info is displayed
This commit is contained in:
parent
5ecd18e30a
commit
adc76f501f
38
src/components/CutStats.js
Normal file
38
src/components/CutStats.js
Normal file
@ -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 { useSongDataStore } from "../store/songDataStore";
|
||||
import styles from "../styles/scoreStats.module.css";
|
||||
|
||||
export default function ScoreStats() {
|
||||
const [showScoreInfo] = useSettingsStore((store) => [store.showScoreInfo]);
|
||||
const [percentage, currentScore, currentPP, saberA, saberB, isLoading] =
|
||||
const [percentage, currentScore, currentPP, combo, isLoading] =
|
||||
useSongDataStore((store) => [
|
||||
store.percentage,
|
||||
store.currentScore,
|
||||
store.currentPP,
|
||||
store.saberA,
|
||||
store.saberB,
|
||||
store.combo,
|
||||
store.isLoading,
|
||||
]);
|
||||
|
||||
@ -24,27 +24,30 @@ export default function ScoreStats() {
|
||||
|
||||
return (
|
||||
<div className={styles.scoreStats}>
|
||||
<p
|
||||
style={{
|
||||
fontSize: "45px",
|
||||
}}
|
||||
>
|
||||
{currentScore.toLocaleString("en-us", {
|
||||
maximumFractionDigits: 0,
|
||||
minimumFractionDigits: 0,
|
||||
})}
|
||||
</p>
|
||||
<div className={styles.scoreStatsInfo}>
|
||||
<p>{percentage}</p>
|
||||
<p>
|
||||
{currentScore.toLocaleString("en-us", {
|
||||
maximumFractionDigits: 2,
|
||||
minimumFractionDigits: 2,
|
||||
})}
|
||||
</p>
|
||||
{currentPP !== undefined ? <p>{currentPP.toFixed(0)}pp</p> : null}
|
||||
</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>
|
||||
<p>Combo: {combo}</p>
|
||||
<p>
|
||||
<span
|
||||
style={{
|
||||
marginRight: "6px",
|
||||
}}
|
||||
>
|
||||
{getFormattedScorePercent(percentage)}
|
||||
</span>
|
||||
{percentage}%
|
||||
</p>
|
||||
{currentPP !== undefined ? <p>{currentPP.toFixed(0)}pp</p> : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,3 +1,31 @@
|
||||
export function getMapHashFromLevelId(levelId: string): string {
|
||||
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 { usePlayerDataStore } from "../store/playerDataStore";
|
||||
import { useSongDataStore } from "../store/songDataStore";
|
||||
import Utils from "../utils/utils";
|
||||
import { getMapHashFromLevelId } from "./map/mapHelpers";
|
||||
|
||||
const ip = useSettingsStore.getState().socketAddr;
|
||||
@ -29,7 +28,9 @@ export function connectClient(attempt: number = 1) {
|
||||
};
|
||||
client.onclose = () => {
|
||||
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(() => {
|
||||
@ -71,15 +72,8 @@ const handlers: any = {
|
||||
} = data.status.beatmap;
|
||||
state.reset();
|
||||
state.setInSong(true);
|
||||
state.setCombo(data.status.performance.combo);
|
||||
useDataStore.setState({ loadedDuringSong: true });
|
||||
state.updateMapData(
|
||||
getMapHashFromLevelId(levelId),
|
||||
difficultyEnum,
|
||||
characteristic,
|
||||
songName,
|
||||
songSubName || levelAuthorName,
|
||||
length
|
||||
);
|
||||
|
||||
const { score, relativeScore } = data.status.performance;
|
||||
let finalScore = score;
|
||||
@ -89,7 +83,17 @@ const handlers: any = {
|
||||
const percent = relativeScore * 100;
|
||||
|
||||
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;
|
||||
|
||||
state.setCurrentScore(finalScore);
|
||||
state.setPercent(percent.toFixed(2) + "%");
|
||||
|
||||
const leaderboardType = useSettingsStore.getState().leaderboardType;
|
||||
let currentPP = Utils.calculatePP(
|
||||
state.mapStarCount,
|
||||
percent,
|
||||
leaderboardType
|
||||
);
|
||||
if (currentPP === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
state.setPp(currentPP);
|
||||
state.setPercent(percent.toFixed(2));
|
||||
state.setCombo(data.status.performance.combo);
|
||||
state.setPp(percent);
|
||||
},
|
||||
|
||||
noteFullyCut: (data: any) => {
|
||||
|
@ -1,6 +1,7 @@
|
||||
import axios from "axios";
|
||||
import { NextSeo } from "next-seo";
|
||||
import { useEffect } from "react";
|
||||
import CutStats from "../components/CutStats";
|
||||
import PlayerStats from "../components/PlayerStats";
|
||||
import ScoreStats from "../components/ScoreStats";
|
||||
import SongInfo from "../components/SongInfo";
|
||||
@ -59,6 +60,7 @@ export default function Overlay(props) {
|
||||
<div className={styles.main}>
|
||||
<NextSeo title="Overlay"></NextSeo>
|
||||
<PlayerStats />
|
||||
<CutStats />
|
||||
<ScoreStats />
|
||||
<SongInfo />
|
||||
</div>
|
||||
|
@ -21,6 +21,7 @@ interface SongDataState {
|
||||
currentSongTime: number;
|
||||
currentScore: number;
|
||||
percentage: string;
|
||||
combo: number;
|
||||
currentPP: number | undefined;
|
||||
saberA: {
|
||||
cutDistanceScore: number;
|
||||
@ -45,7 +46,8 @@ interface SongDataState {
|
||||
setPaused: (paused: boolean) => void;
|
||||
setCurrentScore: (score: number) => void;
|
||||
setPercent: (percent: string) => void;
|
||||
setPp: (pp: number) => void;
|
||||
setCombo: (combo: number) => void;
|
||||
setPp: (percent: number) => void;
|
||||
setInSong: (isInSong: boolean) => void;
|
||||
setSaberData: (saberType: string, cutData: any) => void;
|
||||
}
|
||||
@ -67,6 +69,7 @@ export const useSongDataStore = create<SongDataState>()((set) => ({
|
||||
currentSongTime: 0,
|
||||
currentScore: 0,
|
||||
percentage: "100%",
|
||||
combo: 0,
|
||||
currentPP: undefined,
|
||||
saberA: {
|
||||
cutDistanceScore: 0.0,
|
||||
@ -133,6 +136,10 @@ export const useSongDataStore = create<SongDataState>()((set) => ({
|
||||
set({ percentage: percent });
|
||||
},
|
||||
|
||||
setCombo: (combo: number) => {
|
||||
set({ combo: combo });
|
||||
},
|
||||
|
||||
setSaberData: (saberType: string, saberData: any) => {
|
||||
if (saberType === "saberA") {
|
||||
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 });
|
||||
},
|
||||
|
||||
@ -165,6 +179,7 @@ export const useSongDataStore = create<SongDataState>()((set) => ({
|
||||
currentSongTime: 0,
|
||||
currentScore: 0,
|
||||
percentage: "100%",
|
||||
combo: 0,
|
||||
currentPP: undefined,
|
||||
saberA: {
|
||||
cutDistanceScore: 0.0,
|
||||
|
44
src/styles/cutStats.module.css
Normal file
44
src/styles/cutStats.module.css
Normal file
@ -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;
|
||||
font-size: xx-large;
|
||||
line-height: 1.4em !important;
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
.main p {
|
||||
|
@ -1,50 +1,19 @@
|
||||
.scoreStats {
|
||||
text-align: center;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
margin-top: 5px;
|
||||
margin-right: 5px;
|
||||
margin-top: -5px;
|
||||
margin-left: 10px;
|
||||
min-width: 135px;
|
||||
|
||||
display: flex;
|
||||
justify-content: right;
|
||||
flex-direction: column;
|
||||
align-items: right;
|
||||
}
|
||||
|
||||
.scoreStats p {
|
||||
font-size: 38px;
|
||||
line-height: 1.2em;
|
||||
}
|
||||
|
||||
.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;
|
||||
line-height: 1.1em;
|
||||
font-size: 35px;
|
||||
}
|
||||
|
||||
.scoreStatsInfo {
|
||||
margin-right: 10px;
|
||||
text-align: right;
|
||||
}
|
||||
|
Reference in New Issue
Block a user