mirror of
https://github.com/zkldi/Tachi.git
synced 2026-10-06 22:07:58 +03:00
feat: add minimumRelevantValue and minimumScores to classes (#1348)
* fix(bot): don't spam ongeki classes * feat(bot): fix discord spam for good * fix: missed a few values * fix: update wacca * fix: update ddr * fix: remove bms, pms, iidx * fix: add maimaidx
This commit is contained in:
@@ -5,7 +5,7 @@ import { CreateEmbed } from "../utils/embeds";
|
||||
import { PrependTachiUrl } from "../utils/fetchTachi";
|
||||
import logger from "../utils/logger";
|
||||
import { FormatClass, GetGameChannel } from "../utils/misc";
|
||||
import { FormatGame } from "tachi-common";
|
||||
import { FormatGame, GetGamePTConfig } from "tachi-common";
|
||||
import type {
|
||||
Classes,
|
||||
GPTString,
|
||||
@@ -32,15 +32,14 @@ export async function HandleClassUpdateV1(
|
||||
}
|
||||
|
||||
if (!ShouldRenderUpdate(game, playtype, event.set, event.new)) {
|
||||
logger.info(
|
||||
`Not rendering class update ${event.set}: ${event.old} -> ${event.new} (not relevant).`
|
||||
);
|
||||
return 204;
|
||||
}
|
||||
|
||||
const userDoc = await GetUserInfo(event.userID);
|
||||
|
||||
// We don't want to render classes if the user is blitzing through them
|
||||
// because they haven't played enough charts to "average out".
|
||||
// For example, a new player playing their first 50 charts will blitz through
|
||||
// atleast 10 of the volforce ranks, which will just result in channel spam.
|
||||
const minimumNecessaryScores = GetMinimumScores(game, playtype, event.set);
|
||||
|
||||
if (minimumNecessaryScores !== null) {
|
||||
@@ -48,7 +47,9 @@ export async function HandleClassUpdateV1(
|
||||
|
||||
// Do not render if the user hasn't hit the score cap.
|
||||
if (totalScores < minimumNecessaryScores) {
|
||||
logger.info(`Not rendering class update ${event.set}: ${event.old} -> ${event.new}.`);
|
||||
logger.info(
|
||||
`Not rendering class update ${event.set}: ${event.old} -> ${event.new} (not enough scores).`
|
||||
);
|
||||
return 204;
|
||||
}
|
||||
}
|
||||
@@ -82,16 +83,34 @@ function ShouldRenderUpdate(
|
||||
classSet: Classes[GPTString],
|
||||
classValue: string
|
||||
) {
|
||||
if (game === "sdvx" && classSet === "vfClass") {
|
||||
return ["IMPERIAL_I", "IMPERIAL_II", "IMPERIAL_III", "IMPERIAL_IV"].includes(classValue);
|
||||
} else if (game === "popn" && classSet === "class") {
|
||||
return [
|
||||
// All of the other classes in pop'n can be trivially blitzed through.
|
||||
"GOD",
|
||||
].includes(classValue);
|
||||
const config = GetGamePTConfig(game, playtype);
|
||||
const classSpec = config.classes[classSet];
|
||||
|
||||
if (classSpec === undefined) {
|
||||
logger.error(`Invalid class ${classSet} for ${game} ${playtype}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
if (classSpec.minimumRelevantValue === undefined) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const ids = classSpec.values.map((c) => c.id);
|
||||
|
||||
const currentId = ids.indexOf(classValue);
|
||||
const minimumId = ids.indexOf(classSpec.minimumRelevantValue);
|
||||
|
||||
if (currentId < 0) {
|
||||
logger.error(`Invalid classValue ${classValue} for ${game} ${playtype}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (minimumId < 0) {
|
||||
logger.error(`Invalid minimum classValue ${classValue} for ${game} ${playtype}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
return currentId >= minimumId;
|
||||
}
|
||||
|
||||
function GetMinimumScores(
|
||||
@@ -99,29 +118,13 @@ function GetMinimumScores(
|
||||
playtype: Playtype,
|
||||
classSet: Classes[GPTString]
|
||||
): integer | null {
|
||||
if (game === "chunithm" && classSet === "colour") {
|
||||
return 50;
|
||||
} else if (game === "sdvx" && classSet === "vfClass") {
|
||||
return 50;
|
||||
} else if (game === "gitadora") {
|
||||
return 50;
|
||||
} else if (game === "jubeat") {
|
||||
return 60;
|
||||
} else if (game === "wacca") {
|
||||
return 50;
|
||||
} else if (game === "bms") {
|
||||
return 20;
|
||||
} else if (game === "iidx") {
|
||||
return 20;
|
||||
} else if (game === "pms") {
|
||||
return 20;
|
||||
} else if (game === "ddr") {
|
||||
return 90;
|
||||
} else if (game === "maimai" && classSet === "colour") {
|
||||
return 30;
|
||||
} else if (game === "maimaidx" && classSet === "colour") {
|
||||
return 50;
|
||||
const config = GetGamePTConfig(game, playtype);
|
||||
const classSpec = config.classes[classSet];
|
||||
|
||||
if (classSpec === undefined) {
|
||||
logger.error(`Invalid class ${classSet} for ${game} ${playtype}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
return classSpec.minimumScores ?? null;
|
||||
}
|
||||
|
||||
@@ -151,6 +151,7 @@ export const CHUNITHM_SINGLE_CONF = {
|
||||
colour: {
|
||||
type: "DERIVED",
|
||||
values: CHUNITHMColours,
|
||||
minimumScores: 50,
|
||||
},
|
||||
|
||||
dan: {
|
||||
|
||||
@@ -186,6 +186,7 @@ export const DDR_SP_CONF = {
|
||||
flare: {
|
||||
type: "DERIVED",
|
||||
values: DDRFlare,
|
||||
minimumRelevantValue: "URANUS",
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ export const GITADORA_GITA_CONF = {
|
||||
},
|
||||
|
||||
classes: {
|
||||
colour: { type: "DERIVED", values: GitadoraColours },
|
||||
colour: { type: "DERIVED", values: GitadoraColours, minimumScores: 50 },
|
||||
},
|
||||
|
||||
orderedJudgements: ["perfect", "great", "good", "ok", "miss"],
|
||||
|
||||
@@ -107,7 +107,7 @@ export const JUBEAT_SINGLE_CONF = {
|
||||
},
|
||||
|
||||
classes: {
|
||||
colour: { type: "DERIVED", values: JubeatColours },
|
||||
colour: { type: "DERIVED", values: JubeatColours, minimumScores: 60 },
|
||||
},
|
||||
|
||||
orderedJudgements: ["perfect", "great", "good", "poor", "miss"],
|
||||
|
||||
@@ -204,6 +204,7 @@ export const MAIMAI_DX_SINGLE_CONF = {
|
||||
colour: {
|
||||
type: "DERIVED",
|
||||
values: MaimaiDXColours,
|
||||
minimumRelevantValue: "BRONZE",
|
||||
},
|
||||
dan: {
|
||||
type: "PROVIDED",
|
||||
|
||||
@@ -143,6 +143,7 @@ export const MAIMAI_SINGLE_CONF = {
|
||||
colour: {
|
||||
type: "DERIVED",
|
||||
values: MaimaiColours,
|
||||
minimumScores: 30,
|
||||
},
|
||||
dan: {
|
||||
type: "PROVIDED",
|
||||
|
||||
@@ -195,6 +195,7 @@ export const ONGEKI_SINGLE_CONF = {
|
||||
colour: {
|
||||
type: "DERIVED",
|
||||
values: OngekiColours,
|
||||
minimumRelevantValue: "RAINBOW",
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -129,6 +129,7 @@ export const POPN_9B_CONF = {
|
||||
class: {
|
||||
type: "DERIVED",
|
||||
values: PopnClasses,
|
||||
minimumRelevantValue: "GOD",
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -168,6 +168,7 @@ export const SDVX_SINGLE_CONF = {
|
||||
vfClass: {
|
||||
type: "DERIVED",
|
||||
values: SDVXVFClasses,
|
||||
minimumRelevantValue: "IMPERIAL_I",
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ export const USC_CONTROLLER_CONF = {
|
||||
vfClass: {
|
||||
type: "DERIVED",
|
||||
values: SDVXVFClasses,
|
||||
minimumRelevantValue: "IMPERIAL_I",
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -128,6 +128,7 @@ export const WACCA_SINGLE_CONF = {
|
||||
colour: {
|
||||
type: "DERIVED",
|
||||
values: WaccaColours,
|
||||
minimumRelevantValue: "RAINBOW",
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -33,9 +33,24 @@ interface BaseClassConfig<V extends string> {
|
||||
/**
|
||||
* What are the possible values for this class field?
|
||||
*
|
||||
* @note This should be in ascending order.
|
||||
* @note This must be in ascending order.
|
||||
*/
|
||||
values: Array<ClassInfo<V>>;
|
||||
|
||||
/**
|
||||
* The ID of the lowest class value that should trigger a discord message.
|
||||
* Lower values will be ignored to reduce channel spam.
|
||||
*/
|
||||
minimumRelevantValue?: V;
|
||||
|
||||
/**
|
||||
* What number of scores is needed to "fill" this class?
|
||||
* If the number of scores is lower, new class values will not
|
||||
* trigger discord messages (useful if minimumRelevantValue is undesired)
|
||||
* For example, a new SDVX player playing their first 50 charts will blitz through
|
||||
* at least 10 of the volforce ranks, which would just result in channel spam.
|
||||
*/
|
||||
minimumScores?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user