mirror of
https://github.com/zkldi/Tachi.git
synced 2026-10-10 00:08:22 +03:00
Jubeat support.
This commit is contained in:
+1
-1
@@ -83,7 +83,7 @@
|
||||
"resolve": "1.12.0",
|
||||
"resolve-url-loader": "3.1.0",
|
||||
"socicon": "3.0.5",
|
||||
"tachi-common": "0.4.12"
|
||||
"tachi-common": "0.4.21"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/humanize-duration": "3.25.1",
|
||||
|
||||
Generated
+4
-4
@@ -85,7 +85,7 @@ specifiers:
|
||||
serve: 11.2.0
|
||||
socicon: 3.0.5
|
||||
style-loader: 1.0.0
|
||||
tachi-common: 0.4.12
|
||||
tachi-common: 0.4.21
|
||||
terser-webpack-plugin: 1.4.1
|
||||
ts-pnp: 1.1.4
|
||||
typescript: 4.3.5
|
||||
@@ -158,7 +158,7 @@ dependencies:
|
||||
resolve: 1.12.0
|
||||
resolve-url-loader: 3.1.0
|
||||
socicon: 3.0.5
|
||||
tachi-common: 0.4.12
|
||||
tachi-common: 0.4.21
|
||||
|
||||
devDependencies:
|
||||
'@types/humanize-duration': 3.25.1
|
||||
@@ -11277,8 +11277,8 @@ packages:
|
||||
strip-ansi: 6.0.0
|
||||
dev: true
|
||||
|
||||
/tachi-common/0.4.12:
|
||||
resolution: {integrity: sha512-PsmVP5oJNnCvx3Omc6s6TVSheHmmiG/MJJAtUtcdeG8fwx38ulevVBiB2lSLTUldAh+HMtRvg5m0Qf/ts1QlwQ==}
|
||||
/tachi-common/0.4.21:
|
||||
resolution: {integrity: sha512-Rlworn5QevIuTbZD2qWrsAFSE2dUhcrJQ2iQfo5PtH8WZ95YbsBeOo0D1WfLUBH9YqASQuS3O7lZcwZ0Tz3wvg==}
|
||||
dependencies:
|
||||
monk: 7.3.4
|
||||
transitivePeerDependencies:
|
||||
|
||||
@@ -59,99 +59,99 @@ export default function FolderScoreDistributionChart({
|
||||
);
|
||||
}
|
||||
|
||||
function ScoreDistributionChart({ game, folderDataset, playtype, view }: Props) {
|
||||
if (view === "grade") {
|
||||
return <ScoreBarChart game={game} playtype={playtype} folderDataset={folderDataset} />;
|
||||
}
|
||||
// function ScoreDistributionChart({ game, folderDataset, playtype, view }: Props) {
|
||||
// if (view === "grade") {
|
||||
// return <ScoreBarChart game={game} playtype={playtype} folderDataset={folderDataset} />;
|
||||
// }
|
||||
|
||||
return <>LAMP TODO</>;
|
||||
}
|
||||
// return <>LAMP TODO</>;
|
||||
// }
|
||||
|
||||
function ScoreBarChart({ game, playtype, folderDataset }: Omit<Props, "view">) {
|
||||
const dataMap = CreateChartIDMap(folderDataset);
|
||||
const gptConfig = GetGamePTConfig(game, playtype);
|
||||
// function ScoreBarChart({ game, playtype, folderDataset }: Omit<Props, "view">) {
|
||||
// const dataMap = CreateChartIDMap(folderDataset);
|
||||
// const gptConfig = GetGamePTConfig(game, playtype);
|
||||
|
||||
const expScale = GetGradeChartExpScale(game);
|
||||
const expFn = ComposeExpFn(expScale);
|
||||
const invExpFn = ComposeInverseExpFn(expScale);
|
||||
// const expScale = GetGradeChartExpScale(game);
|
||||
// const expFn = ComposeExpFn(expScale);
|
||||
// const invExpFn = ComposeInverseExpFn(expScale);
|
||||
|
||||
const dataset = [];
|
||||
// const dataset = [];
|
||||
|
||||
for (const data of folderDataset) {
|
||||
const value = data.__related.pb ? expFn(data.__related.pb.scoreData.percent) : 0;
|
||||
dataset.push({
|
||||
chartID: data.chartID,
|
||||
expValue: expFn(value),
|
||||
value,
|
||||
grade: data.__related.pb?.scoreData.grade,
|
||||
});
|
||||
}
|
||||
// for (const data of folderDataset) {
|
||||
// const value = data.__related.pb ? expFn(data.__related.pb.scoreData.percent) : 0;
|
||||
// dataset.push({
|
||||
// chartID: data.chartID,
|
||||
// expValue: expFn(value),
|
||||
// value,
|
||||
// grade: data.__related.pb?.scoreData.grade,
|
||||
// });
|
||||
// }
|
||||
|
||||
dataset.sort(NumericSOV(x => x.expValue));
|
||||
// dataset.sort(NumericSOV(x => x.expValue));
|
||||
|
||||
return (
|
||||
<div style={{ height: 400 }}>
|
||||
<ResponsiveBar
|
||||
indexBy="chartID"
|
||||
tooltip={d => (
|
||||
<BarChartTooltip
|
||||
point={d}
|
||||
renderFn={d => {
|
||||
const data = dataMap.get(d.indexValue as string)!;
|
||||
// return (
|
||||
// <div style={{ height: 400 }}>
|
||||
// <ResponsiveBar
|
||||
// indexBy="chartID"
|
||||
// tooltip={d => (
|
||||
// <BarChartTooltip
|
||||
// point={d}
|
||||
// renderFn={d => {
|
||||
// const data = dataMap.get(d.indexValue as string)!;
|
||||
|
||||
return (
|
||||
<div className="w-100 text-center">
|
||||
{data.__related.song.title}
|
||||
<br />
|
||||
{data.__related.pb?.scoreData.percent.toFixed(2)}%
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
key={"value"}
|
||||
colors={k => {
|
||||
if (!k.data.grade) {
|
||||
return "black";
|
||||
}
|
||||
// @ts-expect-error temp
|
||||
return ChangeOpacity(gptConfig.gradeColours[k.data.grade], 0.5);
|
||||
}}
|
||||
// @ts-expect-error temp
|
||||
borderColor={k => gptConfig.gradeColours[k.data.grade]}
|
||||
borderWidth={1}
|
||||
padding={0.2}
|
||||
// @ts-expect-error temp
|
||||
data={dataset}
|
||||
minValue={0}
|
||||
maxValue={expFn(100)}
|
||||
margin={{ left: 50, top: 20, bottom: 20 }}
|
||||
valueFormat={e => `${invExpFn(e).toFixed(2)}%`}
|
||||
axisLeft={{
|
||||
tickValues: gptConfig.gradeBoundaries.map(e => (e === 0 ? 0 : expFn(e))),
|
||||
format: x => {
|
||||
let nearest;
|
||||
// return (
|
||||
// <div className="w-100 text-center">
|
||||
// {data.__related.song.title}
|
||||
// <br />
|
||||
// {data.__related.pb?.scoreData.percent.toFixed(2)}%
|
||||
// </div>
|
||||
// );
|
||||
// }}
|
||||
// />
|
||||
// )}
|
||||
// key={"value"}
|
||||
// colors={k => {
|
||||
// if (!k.data.grade) {
|
||||
// return "black";
|
||||
// }
|
||||
// // @ts-expect-error temp
|
||||
// return ChangeOpacity(gptConfig.gradeColours[k.data.grade], 0.5);
|
||||
// }}
|
||||
// // @ts-expect-error temp
|
||||
// borderColor={k => gptConfig.gradeColours[k.data.grade]}
|
||||
// borderWidth={1}
|
||||
// padding={0.2}
|
||||
// // @ts-expect-error temp
|
||||
// data={dataset}
|
||||
// minValue={0}
|
||||
// maxValue={expFn(100)}
|
||||
// margin={{ left: 50, top: 20, bottom: 20 }}
|
||||
// valueFormat={e => `${invExpFn(e).toFixed(2)}%`}
|
||||
// axisLeft={{
|
||||
// tickValues: gptConfig.gradeBoundaries.map(e => (e === 0 ? 0 : expFn(e))),
|
||||
// format: x => {
|
||||
// let nearest;
|
||||
|
||||
const lgv = invExpFn(x);
|
||||
// const lgv = invExpFn(x);
|
||||
|
||||
for (const [i, gradeBnd] of gptConfig.gradeBoundaries.entries()) {
|
||||
if (Math.abs(gradeBnd - lgv) < 0.00005) {
|
||||
nearest = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// for (const [i, gradeBnd] of gptConfig.gradeBoundaries.entries()) {
|
||||
// if (Math.abs(gradeBnd - lgv) < 0.00005) {
|
||||
// nearest = i;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (nearest === undefined) {
|
||||
return null;
|
||||
}
|
||||
// if (nearest === undefined) {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
return gptConfig.grades[nearest];
|
||||
},
|
||||
}}
|
||||
axisBottom={null}
|
||||
{...DEFAULT_BAR_PROPS}
|
||||
labelSkipWidth={40}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
// return gptConfig.grades[nearest];
|
||||
// },
|
||||
// }}
|
||||
// axisBottom={null}
|
||||
// {...DEFAULT_BAR_PROPS}
|
||||
// labelSkipWidth={40}
|
||||
// />
|
||||
// </div>
|
||||
// );
|
||||
// }
|
||||
|
||||
@@ -45,7 +45,7 @@ export default function DifficultyCell({
|
||||
<span className={!alwaysShort ? "d-lg-none" : ""}>
|
||||
{FormatDifficultyShort(chart, game)}
|
||||
</span>
|
||||
{chart.levelNum.toString() !== chart.level && (
|
||||
{chart.levelNum.toString() !== chart.level && !chart.level.endsWith(".0") && (
|
||||
<Muted>{chart.levelNum.toFixed(2)}</Muted>
|
||||
)}
|
||||
{"isHot" in chart.data && chart.data.isHot && (
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import React from "react";
|
||||
import { COLOUR_SET, PBScoreDocument, ScoreDocument } from "tachi-common";
|
||||
import { IsNullish } from "util/misc";
|
||||
|
||||
export default function JubeatJudgementCell({
|
||||
score,
|
||||
}: {
|
||||
score: ScoreDocument<"jubeat:Single"> | PBScoreDocument<"jubeat:Single">;
|
||||
}) {
|
||||
// even if we dont have judgement data, we know what they got.
|
||||
if (score.scoreData.lamp === "EXCELLENT") {
|
||||
return (
|
||||
<td>
|
||||
<strong>
|
||||
<span style={{ color: COLOUR_SET.gold }}>0</span>-
|
||||
<span style={{ color: COLOUR_SET.blue }}>0</span>-
|
||||
<span style={{ color: COLOUR_SET.purple }}>0</span>-
|
||||
<span style={{ color: COLOUR_SET.red }}>0</span>
|
||||
</strong>
|
||||
</td>
|
||||
);
|
||||
}
|
||||
|
||||
// safety
|
||||
if (score.scoreData.lamp === "FULL COMBO") {
|
||||
score.scoreData.judgements.miss = 0;
|
||||
}
|
||||
|
||||
const judgements = score.scoreData.judgements;
|
||||
|
||||
if (
|
||||
IsNullish(judgements.miss) ||
|
||||
IsNullish(judgements.great) ||
|
||||
IsNullish(judgements.good) ||
|
||||
IsNullish(judgements.poor)
|
||||
) {
|
||||
return <td>No Data.</td>;
|
||||
}
|
||||
|
||||
return (
|
||||
<td>
|
||||
<strong>
|
||||
<span style={{ color: COLOUR_SET.gold }}>{judgements.great}</span>-
|
||||
<span style={{ color: COLOUR_SET.blue }}>{judgements.good}</span>-
|
||||
<span style={{ color: COLOUR_SET.purple }}>{judgements.poor}</span>-
|
||||
<span style={{ color: COLOUR_SET.red }}>{judgements.miss}</span>
|
||||
</strong>
|
||||
</td>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import React from "react";
|
||||
import { PBScoreDocument, ScoreDocument } from "tachi-common";
|
||||
import { IsNullish } from "util/misc";
|
||||
import LampCell from "../cells/LampCell";
|
||||
import MillionsScoreCell from "../cells/MillionsScoreCell";
|
||||
import JubeatJudgementCell from "../cells/JubeatJudgementCell";
|
||||
|
||||
export default function JubeatCoreCells({
|
||||
sc,
|
||||
}: {
|
||||
sc: ScoreDocument<"jubeat:Single"> | PBScoreDocument<"jubeat:Single">;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<MillionsScoreCell score={sc} />
|
||||
<JubeatJudgementCell score={sc} />
|
||||
<LampCell score={sc} />
|
||||
<td>
|
||||
{!IsNullish(sc.calculatedData.jubility)
|
||||
? sc.calculatedData.jubility!.toFixed(2)
|
||||
: "N/A"}
|
||||
</td>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
import React from "react";
|
||||
import { PBDataset } from "types/tables";
|
||||
import { NumericSOV } from "util/sorts";
|
||||
import { CreateDefaultPBSearchParams } from "util/tables/create-search";
|
||||
import { GetPBLeadingHeaders } from "util/tables/get-pb-leaders";
|
||||
import IndexCell from "../cells/IndexCell";
|
||||
import RankingCell from "../cells/RankingCell";
|
||||
import TimestampCell from "../cells/TimestampCell";
|
||||
import DropdownRow from "../components/DropdownRow";
|
||||
import TachiTable, { Header } from "../components/TachiTable";
|
||||
import { usePBState } from "../components/UseScoreState";
|
||||
import GenericPBDropdown from "../dropdowns/GenericPBDropdown";
|
||||
import JubeatCoreCells from "../game-core-cells/JubeatCoreCells";
|
||||
import PBLeadingRows from "./PBLeadingRows";
|
||||
|
||||
export default function JubeatPBTable({
|
||||
dataset,
|
||||
indexCol = true,
|
||||
showPlaycount = false,
|
||||
showUser = false,
|
||||
showChart = true,
|
||||
playtype,
|
||||
}: {
|
||||
dataset: PBDataset<"jubeat:Single">;
|
||||
indexCol?: boolean;
|
||||
showPlaycount?: boolean;
|
||||
showUser?: boolean;
|
||||
showChart?: boolean;
|
||||
playtype: "Single";
|
||||
}) {
|
||||
const headers: Header<PBDataset<"jubeat:Single">[0]>[] = [
|
||||
...GetPBLeadingHeaders(showUser, showChart, [
|
||||
"Chart",
|
||||
"Chart",
|
||||
NumericSOV(x => x.__related.chart.levelNum),
|
||||
]),
|
||||
["Score", "Score", NumericSOV(x => x.scoreData.percent)],
|
||||
["Judgements", "Judgements", NumericSOV(x => x.scoreData.percent)],
|
||||
["Lamp", "Lamp", NumericSOV(x => x.scoreData.lampIndex)],
|
||||
["Jubility", "Jub.", NumericSOV(x => x.calculatedData.jubility ?? 0)],
|
||||
["Site Ranking", "Site Rank", NumericSOV(x => x.rankingData.rank)],
|
||||
["Last Raised", "Last Raised", NumericSOV(x => x.timeAchieved ?? 0)],
|
||||
];
|
||||
|
||||
if (showPlaycount) {
|
||||
headers.push(["Playcount", "Plays", NumericSOV(x => x.__playcount ?? 0)]);
|
||||
}
|
||||
|
||||
if (indexCol) {
|
||||
headers.unshift(["#", "#", NumericSOV(x => x.__related.index)]);
|
||||
}
|
||||
|
||||
return (
|
||||
<TachiTable
|
||||
dataset={dataset}
|
||||
headers={headers}
|
||||
entryName="PBs"
|
||||
searchFunctions={CreateDefaultPBSearchParams("jubeat", playtype)}
|
||||
defaultSortMode={indexCol ? "#" : undefined}
|
||||
rowFunction={pb => (
|
||||
<Row
|
||||
pb={pb}
|
||||
key={`${pb.chartID}:${pb.userID}`}
|
||||
indexCol={indexCol}
|
||||
showPlaycount={showPlaycount}
|
||||
showChart={showChart}
|
||||
showUser={showUser}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function Row({
|
||||
pb,
|
||||
indexCol,
|
||||
showPlaycount,
|
||||
showChart,
|
||||
showUser,
|
||||
}: {
|
||||
pb: PBDataset<"jubeat:Single">[0];
|
||||
indexCol: boolean;
|
||||
showPlaycount: boolean;
|
||||
showChart: boolean;
|
||||
showUser: boolean;
|
||||
}) {
|
||||
const scoreState = usePBState(pb);
|
||||
|
||||
return (
|
||||
<DropdownRow
|
||||
dropdown={
|
||||
<GenericPBDropdown
|
||||
chart={pb.__related.chart}
|
||||
userID={pb.userID}
|
||||
game={pb.game}
|
||||
playtype={pb.playtype}
|
||||
scoreState={scoreState}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{indexCol && <IndexCell index={pb.__related.index} />}
|
||||
<PBLeadingRows {...{ showUser, showChart, pb, scoreState }} />
|
||||
<JubeatCoreCells sc={pb} />
|
||||
<RankingCell rankingData={pb.rankingData} />
|
||||
<TimestampCell time={pb.timeAchieved} />
|
||||
{showPlaycount && <td>{pb.__playcount ?? 0}</td>}
|
||||
</DropdownRow>
|
||||
);
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { PBDataset } from "types/tables";
|
||||
import BMSPBTable from "./BMSPBTable";
|
||||
import GenericPBTable from "./GenericPBTable";
|
||||
import IIDXPBTable from "./IIDXPBTable";
|
||||
import JubeatPBTable from "./JubeatPBTable";
|
||||
import MusecaPBTable from "./MusecaPBTable";
|
||||
import PopnPBTable from "./PopnPBTable";
|
||||
import SDVXLikePBTable from "./SDVXLikePBTable";
|
||||
@@ -56,6 +57,8 @@ export default function PBTable({
|
||||
return <WACCAPBTable {...props} />;
|
||||
} else if (game === "popn") {
|
||||
return <PopnPBTable {...props} />;
|
||||
} else if (game === "jubeat") {
|
||||
return <JubeatPBTable {...props} />;
|
||||
}
|
||||
|
||||
return <GenericPBTable {...props} game={game} playtype={playtype} />;
|
||||
|
||||
@@ -26,7 +26,7 @@ export default function WACCAPBTable({
|
||||
showPlaycount?: boolean;
|
||||
showUser?: boolean;
|
||||
showChart?: boolean;
|
||||
playtype: "9B";
|
||||
playtype: "Single";
|
||||
}) {
|
||||
const headers: Header<PBDataset<"wacca:Single">[0]>[] = [
|
||||
...GetPBLeadingHeaders(showUser, showChart, [
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
import React from "react";
|
||||
import { integer, Playtypes, PublicUserDocument } from "tachi-common";
|
||||
import { ScoreDataset } from "types/tables";
|
||||
import { NumericSOV, StrSOV } from "util/sorts";
|
||||
import { CreateDefaultScoreSearchParams } from "util/tables/create-search";
|
||||
import DifficultyCell from "../cells/DifficultyCell";
|
||||
import IndicatorsCell from "../cells/IndicatorsCell";
|
||||
import TimestampCell from "../cells/TimestampCell";
|
||||
import TitleCell from "../cells/TitleCell";
|
||||
import UserCell from "../cells/UserCell";
|
||||
import DropdownRow from "../components/DropdownRow";
|
||||
import TachiTable, { Header } from "../components/TachiTable";
|
||||
import { useScoreState } from "../components/UseScoreState";
|
||||
import GenericScoreDropdown from "../dropdowns/GenericScoreDropdown";
|
||||
import JubeatCoreCells from "../game-core-cells/JubeatCoreCells";
|
||||
import WACCACoreCells from "../game-core-cells/WACCACoreCells";
|
||||
import IndicatorHeader from "../headers/IndicatorHeader";
|
||||
|
||||
export default function JubeatScoreTable({
|
||||
reqUser,
|
||||
dataset,
|
||||
pageLen,
|
||||
userCol = false,
|
||||
}: {
|
||||
reqUser: PublicUserDocument;
|
||||
dataset: ScoreDataset<"jubeat:Single">;
|
||||
pageLen?: integer;
|
||||
playtype: Playtypes["jubeat"];
|
||||
userCol: boolean;
|
||||
}) {
|
||||
const headers: Header<ScoreDataset<"jubeat:Single">[0]>[] = [
|
||||
["Chart", "Chart", NumericSOV(x => x.__related.chart.levelNum)],
|
||||
IndicatorHeader,
|
||||
["Song", "Song", StrSOV(x => x.__related.song.title)],
|
||||
["Score", "Score", NumericSOV(x => x.scoreData.percent)],
|
||||
["Judgements", "Judgements", NumericSOV(x => x.scoreData.percent)],
|
||||
["Lamp", "Lamp", NumericSOV(x => x.scoreData.lampIndex)],
|
||||
["Jubility", "Jub.", NumericSOV(x => x.calculatedData.jubility ?? 0)],
|
||||
|
||||
["Timestamp", "Timestamp", NumericSOV(x => x.timeAchieved ?? 0)],
|
||||
];
|
||||
|
||||
if (userCol) {
|
||||
headers.unshift(["User", "User", StrSOV(x => x.__related.user.username)]);
|
||||
}
|
||||
|
||||
return (
|
||||
<TachiTable
|
||||
dataset={dataset}
|
||||
pageLen={pageLen}
|
||||
headers={headers}
|
||||
entryName="Scores"
|
||||
searchFunctions={CreateDefaultScoreSearchParams("jubeat", "Single")}
|
||||
rowFunction={sc => <Row key={sc.scoreID} sc={sc} reqUser={reqUser} userCol={userCol} />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function Row({
|
||||
sc,
|
||||
userCol,
|
||||
}: {
|
||||
sc: ScoreDataset<"jubeat:Single">[0];
|
||||
reqUser: PublicUserDocument;
|
||||
userCol: boolean;
|
||||
}) {
|
||||
const scoreState = useScoreState(sc);
|
||||
|
||||
return (
|
||||
<DropdownRow
|
||||
dropdown={
|
||||
<GenericScoreDropdown
|
||||
chart={sc.__related.chart}
|
||||
user={sc.__related.user}
|
||||
game={sc.game}
|
||||
thisScore={sc}
|
||||
playtype={sc.playtype}
|
||||
scoreState={scoreState}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{userCol && <UserCell game={sc.game} playtype={sc.playtype} user={sc.__related.user} />}
|
||||
<DifficultyCell chart={sc.__related.chart} game="jubeat" />
|
||||
<IndicatorsCell highlight={scoreState.highlight} />
|
||||
<TitleCell
|
||||
song={sc.__related.song}
|
||||
comment={sc.comment}
|
||||
chart={sc.__related.chart}
|
||||
game="jubeat"
|
||||
/>
|
||||
<JubeatCoreCells sc={sc} />
|
||||
<TimestampCell time={sc.timeAchieved} service={sc.service} />
|
||||
</DropdownRow>
|
||||
);
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { ScoreDataset } from "types/tables";
|
||||
import BMSScoreTable from "./BMSScoreTable";
|
||||
import GenericScoreTable from "./GenericScoreTable";
|
||||
import IIDXScoreTable from "./IIDXScoreTable";
|
||||
import JubeatScoreTable from "./JubeatScoreTable";
|
||||
import MusecaScoreTable from "./MusecaScoreTable";
|
||||
import SDVXLikeScoreTable from "./SDVXLikeScoreTable";
|
||||
|
||||
@@ -36,6 +37,8 @@ export default function ScoreTable({
|
||||
return <GenericScoreTable {...props} game={game} playtype={playtype} showScore={false} />;
|
||||
} else if (game === "museca") {
|
||||
return <MusecaScoreTable {...props} />;
|
||||
} else if (game === "jubeat") {
|
||||
return <JubeatScoreTable {...props} />;
|
||||
}
|
||||
|
||||
return <GenericScoreTable {...props} game={game} playtype={playtype} />;
|
||||
|
||||
@@ -21,7 +21,7 @@ if (mode === "ktchi") {
|
||||
type: "ktchi",
|
||||
// TODO: #78 This should inherit in some way from the server config. Can we reflect
|
||||
// this out somehow?
|
||||
supportedGames: ["iidx", "chunithm", "museca", "sdvx", "wacca", "popn"],
|
||||
supportedGames: ["iidx", "chunithm", "museca", "sdvx", "wacca", "popn", "jubeat"],
|
||||
importTypes: [
|
||||
"api/arc-iidx",
|
||||
"api/arc-sdvx",
|
||||
|
||||
@@ -9,6 +9,10 @@ export function AbsoluteGradeDelta<I extends IDStrings = IDStrings>(
|
||||
) {
|
||||
const gptConfig = GetGamePTConfig(game, playtype);
|
||||
|
||||
if (!gptConfig.gradeBoundaries) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const maxScore = Math.round(score * (100 / percent));
|
||||
|
||||
const gradeIndex =
|
||||
|
||||
@@ -52,8 +52,12 @@ export function FormatGPTRating(
|
||||
game: Game,
|
||||
playtype: Playtype,
|
||||
key: ScoreCalculatedDataLookup[IDStrings],
|
||||
value: number
|
||||
value: number | null
|
||||
) {
|
||||
if (value === null) {
|
||||
return "No Data.";
|
||||
}
|
||||
|
||||
const gptConfig = GetGamePTConfig(game, playtype);
|
||||
|
||||
if (gptConfig.scoreRatingAlgFormatters[key]) {
|
||||
|
||||
@@ -12,6 +12,7 @@ const scales: Record<Game, number> = {
|
||||
usc: 5,
|
||||
wacca: 5,
|
||||
popn: 4,
|
||||
jubeat: 5,
|
||||
};
|
||||
|
||||
export function GetGradeChartExpScale(game: Game) {
|
||||
|
||||
@@ -36,6 +36,7 @@ const ScaleNameAchievedFns: ScaleAchievedFns = {
|
||||
"usc:Keyboard": {},
|
||||
"wacca:Single": {},
|
||||
"popn:9B": {},
|
||||
"jubeat:Single": {},
|
||||
};
|
||||
|
||||
export function GetScaleAchievedFn(
|
||||
|
||||
Reference in New Issue
Block a user