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 { 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,
|
||||||
|
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;
|
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;
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user