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

View 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>
);
}

View File

@ -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>

View File

@ -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";
}

View File

@ -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) => {

View File

@ -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>

View File

@ -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,

View 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;
}

View File

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

View File

@ -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;
}