From 023f93e1fb565b8b720ff6df6573c21f57c803b3 Mon Sep 17 00:00:00 2001 From: Gyoo Date: Sat, 24 Aug 2024 09:31:36 +0000 Subject: [PATCH 1/4] feat: support exScore, fast, slow, maxCombo as optional metrics for DDR --- common/src/config/game-support/ddr.ts | 22 +++++++++++++++++ server/src/game-implementations/games/ddr.ts | 26 ++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/common/src/config/game-support/ddr.ts b/common/src/config/game-support/ddr.ts index f46436d4d..bebdc6b1b 100644 --- a/common/src/config/game-support/ddr.ts +++ b/common/src/config/game-support/ddr.ts @@ -4,6 +4,7 @@ import { ClassValue, zodNonNegativeInt } from "../config-utils"; import { p } from "prudence"; import { z } from "zod"; import type { INTERNAL_GAME_CONFIG, INTERNAL_GAME_PT_CONFIG } from "../../types/internals"; +import {FAST_SLOW_MAXCOMBO} from "./_common"; export const DDR_FLARE_CATEGORIES = z.enum(["CLASSIC", "WHITE", "GOLD", "NONE"]); @@ -122,6 +123,19 @@ export const DDR_SP_CONF = { minimumRelevantValue: "0", description: "The Flare rank. If no Flare is provided, Flare 0 is chosen by default.", }, + exScore: { + type: "INTEGER", + formatter: FmtNum, + validate: p.isPositiveInteger, + + // We want to track the best EXScore a user gets, but it is an optional + // metric. + partOfScoreID: true, + + description: + "The EXScore value. Marvelous and O.K. judgements are worth 3 points, Perfect judgements are worth 2 points, Great judgements are worth 1 point, and Good and lower judgements are not worth any points.", + }, + ...FAST_SLOW_MAXCOMBO }, defaultMetric: "score", @@ -132,6 +146,10 @@ export const DDR_SP_CONF = { description: "Flare Skill as it's implemented in DDR World.", formatter: FmtScoreNoCommas, }, + exScore: { + description: "The EXScore.", + formatter: FmtScoreNoCommas, + }, }, sessionRatingAlgs: { @@ -139,6 +157,10 @@ export const DDR_SP_CONF = { description: "Average of your 10 best Flare Points this session", formatter: FmtScoreNoCommas, }, + exScore: { + description: "Average of your 10 best EXScores this session", + formatter: FmtScoreNoCommas, + }, }, profileRatingAlgs: { diff --git a/server/src/game-implementations/games/ddr.ts b/server/src/game-implementations/games/ddr.ts index 96b0e3634..c304c8898 100644 --- a/server/src/game-implementations/games/ddr.ts +++ b/server/src/game-implementations/games/ddr.ts @@ -141,6 +141,25 @@ export const DDR_SCORE_VALIDATORS: Array> = default: } }, + (s) => { + const { MARVELOUS, PERFECT, GREAT, OK } = s.scoreData.judgements; + + if ( + IsNullish(MARVELOUS) || + IsNullish(PERFECT) || + IsNullish(GREAT) || + IsNullish(OK) || + IsNullish(s.scoreData.optional.exScore) + ) { + return; + } + + const calculatedExScore = MARVELOUS * 3 + OK * 3 + PERFECT * 2 + GREAT; + + if (calculatedExScore !== s.scoreData.optional.exScore) { + return `EXScore expected to be ${calculatedExScore} instead of ${s.scoreData.optional.exScore}`; + } + }, ]; export const DDR_IMPL: GPTServerImplementation<"ddr:DP" | "ddr:SP"> = { @@ -260,6 +279,9 @@ export const DDR_IMPL: GPTServerImplementation<"ddr:DP" | "ddr:SP"> = { base.scoreData.score = score.scoreData.score; base.scoreData.grade = score.scoreData.grade; }), + CreatePBMergeFor("largest", "optional.exScore", "Best EX Score", (base, score) => { + base.scoreData.optional.exScore = score.scoreData.optional.exScore; + }), ], profileCalcs: { flareSkill: async (game: Game, playtype: Playtype, userID: integer) => { @@ -336,9 +358,13 @@ export const DDR_IMPL: GPTServerImplementation<"ddr:DP" | "ddr:SP"> = { return DDRFlare.calculate(chart.levelNum, flareLevel); }, + exScore: (scoreData) => { + return scoreData.optional.exScore ?? 0; + }, }, scoreValidators: DDR_SCORE_VALIDATORS, sessionCalcs: { flareSkill: SessionAvgBest10For("flareSkill"), + exScore: SessionAvgBest10For("exScore"), }, }; From 02071f058d1b108c623a4876f44125543c0f4004 Mon Sep 17 00:00:00 2001 From: Gyoo Date: Sat, 24 Aug 2024 09:45:00 +0000 Subject: [PATCH 2/4] chore: lint-fix in common --- common/src/config/game-support/ddr.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/src/config/game-support/ddr.ts b/common/src/config/game-support/ddr.ts index bebdc6b1b..ea4fd73a1 100644 --- a/common/src/config/game-support/ddr.ts +++ b/common/src/config/game-support/ddr.ts @@ -1,10 +1,10 @@ +import { FAST_SLOW_MAXCOMBO } from "./_common"; import { IIDXDans } from "./iidx"; import { FmtNum, FmtPercent, FmtScoreNoCommas } from "../../utils/util"; import { ClassValue, zodNonNegativeInt } from "../config-utils"; import { p } from "prudence"; import { z } from "zod"; import type { INTERNAL_GAME_CONFIG, INTERNAL_GAME_PT_CONFIG } from "../../types/internals"; -import {FAST_SLOW_MAXCOMBO} from "./_common"; export const DDR_FLARE_CATEGORIES = z.enum(["CLASSIC", "WHITE", "GOLD", "NONE"]); @@ -135,7 +135,7 @@ export const DDR_SP_CONF = { description: "The EXScore value. Marvelous and O.K. judgements are worth 3 points, Perfect judgements are worth 2 points, Great judgements are worth 1 point, and Good and lower judgements are not worth any points.", }, - ...FAST_SLOW_MAXCOMBO + ...FAST_SLOW_MAXCOMBO, }, defaultMetric: "score", From 6281abffac75be6cd68666d23c894487c05bf6c5 Mon Sep 17 00:00:00 2001 From: Gyoo Date: Tue, 27 Aug 2024 09:34:56 +0000 Subject: [PATCH 3/4] fix: remove exScore from calculated metrics for DDR --- client/src/components/tables/cells/DDRScoreCell.tsx | 8 ++++++++ common/src/config/game-support/ddr.ts | 11 +---------- server/src/game-implementations/games/ddr.ts | 4 ---- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/client/src/components/tables/cells/DDRScoreCell.tsx b/client/src/components/tables/cells/DDRScoreCell.tsx index 39d4a931f..a1ca96301 100644 --- a/client/src/components/tables/cells/DDRScoreCell.tsx +++ b/client/src/components/tables/cells/DDRScoreCell.tsx @@ -6,12 +6,14 @@ export default function DDRScoreCell({ score, colour, grade, + exScore, scoreRenderFn, }: { score?: integer; grade: string; colour: string; showScore?: boolean; + exScore?: integer; scoreRenderFn?: (s: number) => string; }) { return ( @@ -23,6 +25,12 @@ export default function DDRScoreCell({ {grade}
{score !== undefined && <>{scoreRenderFn ? scoreRenderFn(score) : score}} + {(!!exScore || exScore === 0) && ( + <> +
+ [EX: {exScore}] + + )} ); } diff --git a/common/src/config/game-support/ddr.ts b/common/src/config/game-support/ddr.ts index ea4fd73a1..c773c0d8b 100644 --- a/common/src/config/game-support/ddr.ts +++ b/common/src/config/game-support/ddr.ts @@ -1,6 +1,5 @@ import { FAST_SLOW_MAXCOMBO } from "./_common"; -import { IIDXDans } from "./iidx"; -import { FmtNum, FmtPercent, FmtScoreNoCommas } from "../../utils/util"; +import { FmtNum, FmtScoreNoCommas } from "../../utils/util"; import { ClassValue, zodNonNegativeInt } from "../config-utils"; import { p } from "prudence"; import { z } from "zod"; @@ -146,10 +145,6 @@ export const DDR_SP_CONF = { description: "Flare Skill as it's implemented in DDR World.", formatter: FmtScoreNoCommas, }, - exScore: { - description: "The EXScore.", - formatter: FmtScoreNoCommas, - }, }, sessionRatingAlgs: { @@ -157,10 +152,6 @@ export const DDR_SP_CONF = { description: "Average of your 10 best Flare Points this session", formatter: FmtScoreNoCommas, }, - exScore: { - description: "Average of your 10 best EXScores this session", - formatter: FmtScoreNoCommas, - }, }, profileRatingAlgs: { diff --git a/server/src/game-implementations/games/ddr.ts b/server/src/game-implementations/games/ddr.ts index c304c8898..5a89c557e 100644 --- a/server/src/game-implementations/games/ddr.ts +++ b/server/src/game-implementations/games/ddr.ts @@ -358,13 +358,9 @@ export const DDR_IMPL: GPTServerImplementation<"ddr:DP" | "ddr:SP"> = { return DDRFlare.calculate(chart.levelNum, flareLevel); }, - exScore: (scoreData) => { - return scoreData.optional.exScore ?? 0; - }, }, scoreValidators: DDR_SCORE_VALIDATORS, sessionCalcs: { flareSkill: SessionAvgBest10For("flareSkill"), - exScore: SessionAvgBest10For("exScore"), }, }; From b5314dbfacb7020cb12524f9b0e742b789799037 Mon Sep 17 00:00:00 2001 From: zkldi <20380519+zkldi@users.noreply.github.com> Date: Mon, 23 Sep 2024 13:24:20 +0000 Subject: [PATCH 4/4] fix: use clearer logic for number|null --- client/src/components/tables/cells/DDRScoreCell.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/components/tables/cells/DDRScoreCell.tsx b/client/src/components/tables/cells/DDRScoreCell.tsx index a1ca96301..59954a748 100644 --- a/client/src/components/tables/cells/DDRScoreCell.tsx +++ b/client/src/components/tables/cells/DDRScoreCell.tsx @@ -25,7 +25,7 @@ export default function DDRScoreCell({ {grade}
{score !== undefined && <>{scoreRenderFn ? scoreRenderFn(score) : score}} - {(!!exScore || exScore === 0) && ( + {typeof exScore === "number" && ( <>
[EX: {exScore}]