diff --git a/src/components/CutStats.js b/src/components/CutStats.js
new file mode 100644
index 0000000..3ec301c
--- /dev/null
+++ b/src/components/CutStats.js
@@ -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 (
+
+
+ {currentScore.toLocaleString("en-us", {
+ maximumFractionDigits: 0,
+ minimumFractionDigits: 0,
+ })}
+
-
{percentage}
-
- {currentScore.toLocaleString("en-us", {
- maximumFractionDigits: 2,
- minimumFractionDigits: 2,
- })}
-
- {currentPP !== undefined ?
{currentPP.toFixed(0)}pp
: null}
-
-
Average Cut
-
-
-
{saberA.averagePreSwing.toFixed(2)}
-
{saberA.averagePostSwing.toFixed(2)}
-
{saberA.cutDistanceScore.toFixed(2)}
-
-
-
{saberB.averagePreSwing.toFixed(2)}
-
{saberB.averagePostSwing.toFixed(2)}
-
{saberB.cutDistanceScore.toFixed(2)}
+
+
Combo: {combo}
+
+
+ {getFormattedScorePercent(percentage)}
+
+ {percentage}%
+
+ {currentPP !== undefined ?
{currentPP.toFixed(0)}pp
: null}
diff --git a/src/helpers/map/mapHelpers.ts b/src/helpers/map/mapHelpers.ts
index 2951dd0..678daa5 100644
--- a/src/helpers/map/mapHelpers.ts
+++ b/src/helpers/map/mapHelpers.ts
@@ -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";
+}
diff --git a/src/helpers/websocketClient.ts b/src/helpers/websocketClient.ts
index 497175c..1b4b492 100644
--- a/src/helpers/websocketClient.ts
+++ b/src/helpers/websocketClient.ts
@@ -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) => {
diff --git a/src/pages/overlay.js b/src/pages/overlay.js
index ee82f07..5049329 100644
--- a/src/pages/overlay.js
+++ b/src/pages/overlay.js
@@ -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) {
diff --git a/src/store/songDataStore.ts b/src/store/songDataStore.ts
index ac602f2..2146746 100644
--- a/src/store/songDataStore.ts
+++ b/src/store/songDataStore.ts
@@ -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
()((set) => ({
currentSongTime: 0,
currentScore: 0,
percentage: "100%",
+ combo: 0,
currentPP: undefined,
saberA: {
cutDistanceScore: 0.0,
@@ -133,6 +136,10 @@ export const useSongDataStore = create()((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()((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()((set) => ({
currentSongTime: 0,
currentScore: 0,
percentage: "100%",
+ combo: 0,
currentPP: undefined,
saberA: {
cutDistanceScore: 0.0,
diff --git a/src/styles/cutStats.module.css b/src/styles/cutStats.module.css
new file mode 100644
index 0000000..e3f98fc
--- /dev/null
+++ b/src/styles/cutStats.module.css
@@ -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;
+}
diff --git a/src/styles/overlay.module.css b/src/styles/overlay.module.css
index 40a964e..0f08423 100644
--- a/src/styles/overlay.module.css
+++ b/src/styles/overlay.module.css
@@ -3,6 +3,7 @@
color: white;
font-size: xx-large;
line-height: 1.4em !important;
+ height: fit-content;
}
.main p {
diff --git a/src/styles/scoreStats.module.css b/src/styles/scoreStats.module.css
index a5f6764..249a05a 100644
--- a/src/styles/scoreStats.module.css
+++ b/src/styles/scoreStats.module.css
@@ -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;
}