Merge pull request #604 from TNG-dev/zkldi/issue-598

This commit is contained in:
zkldi
2021-12-21 09:15:20 +00:00
committed by GitHub
13 changed files with 191 additions and 8 deletions
+1
View File
@@ -46,6 +46,7 @@
"bms",
"chunithm",
"usc",
"wacca",
],
IMPORT_TYPES: [
"file/eamusement-iidx-csv",
+1 -1
View File
@@ -83,7 +83,7 @@
"rimraf": "3.0.2",
"safe-json-stringify": "1.2.0",
"seq-logging": "^1.1.1",
"tachi-common": "0.3.24",
"tachi-common": "0.4.1",
"ts-node": "10.0.0",
"typescript": "4.3.4",
"winston": "3.3.3",
+4 -4
View File
@@ -63,7 +63,7 @@ specifiers:
safe-json-stringify: 1.2.0
seq-logging: ^1.1.1
supertest: 6.1.3
tachi-common: 0.3.24
tachi-common: 0.4.1
tap: 15.0.9
ts-node: 10.0.0
tsconfig-paths: 3.10.1
@@ -107,7 +107,7 @@ dependencies:
rimraf: 3.0.2
safe-json-stringify: 1.2.0
seq-logging: 1.1.1
tachi-common: 0.3.24
tachi-common: 0.4.1
ts-node: 10.0.0_83f53b0a0c5616d3fa00ed4e30b9ce1b
typescript: 4.3.4
winston: 3.3.3
@@ -5387,8 +5387,8 @@ packages:
strip-ansi: 6.0.0
dev: true
/tachi-common/0.3.24:
resolution: {integrity: sha512-nTfVZeRXqOyVF5viHACawbbrERzwyY88wBxNuhpZVvSL4jTjFy7dSRf/7LnJVDC1XizhUBKfYMlOBXOUXTIzzg==}
/tachi-common/0.4.1:
resolution: {integrity: sha512-AREsya2jvgpBq036I17XUeR/jF+lKKJ+CeKCtzKLGE1j8GgyHH6HAy6zP5Vzw6eXRXknubCgr/xFbq+LDqWPmw==}
dependencies:
monk: 7.3.4
transitivePeerDependencies:
+2
View File
@@ -122,6 +122,7 @@ const songs = {
popn: monkDB.get<SongDocument>(`songs-popn`),
sdvx: monkDB.get<SongDocument>(`songs-sdvx`),
usc: monkDB.get<SongDocument>(`songs-usc`),
wacca: monkDB.get<SongDocument>(`songs-wacca`),
};
const charts = {
@@ -136,6 +137,7 @@ const charts = {
popn: monkDB.get<ChartDocument>(`charts-popn`),
sdvx: monkDB.get<ChartDocument>(`charts-sdvx`),
usc: monkDB.get<ChartDocument>(`charts-usc`),
wacca: monkDB.get<ChartDocument>(`charts-wacca`),
};
const db = {
+11
View File
@@ -767,6 +767,12 @@ export const DatabaseSchemas: Record<Databases, ValidatorFunction> = {
displayVersion: "string",
})
),
"songs-wacca": prSchemaify(
PR_SongDocument({
genre: "string",
displayVersion: "?string",
})
),
"charts-iidx": (self) => {
const playtype = getPlaytype("iidx", self);
@@ -849,6 +855,11 @@ export const DatabaseSchemas: Record<Databases, ValidatorFunction> = {
})
)(self);
},
"charts-wacca": prSchemaify(
PR_ChartDocument("wacca", "Single", {
releaseVersion: p.isIn("wacca", "s", "lily", "lily-r", "reverse"),
})
),
goals: prSchemaify({
game: p.isIn(games),
playtype: isValidPlaytype,
+12
View File
@@ -172,3 +172,15 @@ export enum CHUNITHM_COLOURS {
PLATINUM,
RAINBOW,
}
export enum WACCA_COLOURS {
ASH,
NAVY,
YELLOW,
RED,
PURPLE,
BLUE,
SILVER,
GOLD,
RAINBOW,
}
@@ -3,13 +3,13 @@ import { KtLogger } from "lib/logger/logger";
import {
ChartDocument,
Game,
GetGamePTConfig,
Grades,
IDStrings,
IIDX_LAMPS,
Lamps,
Playtypes,
ScoreDocument,
GetGamePTConfig,
IIDX_LAMPS,
} from "tachi-common";
import { HasOwnProperty } from "utils/misc";
import { DryScore } from "../common/types";
@@ -93,6 +93,9 @@ const CalculatedDataFunctions: CalculatedDataFunctions = {
Controller: CalculateDataSDVXorUSC,
Keyboard: CalculateDataSDVXorUSC,
},
wacca: {
Single: CalculateDataWACCA,
},
};
// Creates Game-Specific calculatedData for the provided game & playtype.
@@ -323,3 +326,37 @@ export function CalculateDataBMS7K(
// jubility: 0, // @todo #163 Jubeat Jubility
// };
// }
function CalculateDataWACCA(
dryScore: DryScore,
chart: ChartDocument,
logger: KtLogger
): CalculatedData<"wacca:Single"> {
let scoreCoef = 1;
// See https://github.com/TNG-dev/tachi-server/issues/598.
// This is genuinely how the game works.
if (scoreCoef >= 990_000) {
scoreCoef = 4;
} else if (scoreCoef >= 980_000) {
scoreCoef = 3.75;
} else if (scoreCoef >= 970_000) {
scoreCoef = 3.5;
} else if (scoreCoef >= 960_000) {
scoreCoef = 3.25;
} else if (scoreCoef >= 950_000) {
scoreCoef = 3;
} else if (scoreCoef >= 940_000) {
scoreCoef = 2.75;
} else if (scoreCoef >= 920_000) {
scoreCoef = 2.5;
} else if (scoreCoef >= 900_000) {
scoreCoef = 2;
} else if (scoreCoef >= 850_000) {
scoreCoef = 1.5;
}
// That's... it??
// How discrete. How boring!
return { rate: scoreCoef * chart.levelNum };
}
@@ -127,6 +127,11 @@ const CalculatedDataFunctions: CalculatedDataFunctions = {
};
},
},
wacca: {
Single: (scd) => ({
naiveRate: AvgBest10Map(scd, "rate"),
}),
},
};
export function CreateSessionCalcData(
@@ -1,4 +1,9 @@
import { CHUNITHM_COLOURS, GitadoraColours, SDVXVFClasses } from "lib/constants/classes";
import {
CHUNITHM_COLOURS,
GitadoraColours,
SDVXVFClasses,
WACCA_COLOURS,
} from "lib/constants/classes";
import { KtLogger } from "lib/logger/logger";
import { Game, integer, Playtypes, ScoreCalculatedDataLookup } from "tachi-common";
import { GameClasses } from "tachi-common/js/game-classes";
@@ -94,6 +99,39 @@ export function GitadoraSkillToColour(sk: number) {
return GitadoraColours.WHITE;
}
export function CalculateWACCAColour(
game: Game,
playtype: Playtypes[Game],
userID: integer,
ratings: Record<string, number>
) {
const colour = WACCARateToColour(ratings.naiveRate);
return { colour };
}
function WACCARateToColour(rate: number) {
if (rate >= 2500) {
return WACCA_COLOURS.RAINBOW;
} else if (rate >= 2200) {
return WACCA_COLOURS.GOLD;
} else if (rate >= 1900) {
return WACCA_COLOURS.SILVER;
} else if (rate >= 1600) {
return WACCA_COLOURS.BLUE;
} else if (rate >= 1300) {
return WACCA_COLOURS.PURPLE;
} else if (rate >= 1000) {
return WACCA_COLOURS.RED;
} else if (rate >= 600) {
return WACCA_COLOURS.YELLOW;
} else if (rate >= 300) {
return WACCA_COLOURS.NAVY;
}
return WACCA_COLOURS.ASH;
}
export function CalculateChunithmColour(
game: Game,
playtype: Playtypes[Game],
@@ -9,6 +9,7 @@ import {
CalculateChunithmColour,
CalculateGitadoraColour,
CalculateSDVXClass,
CalculateWACCAColour,
} from "./builtin-class-handlers";
import { ClassHandler, ScoreClasses } from "./types";
@@ -50,6 +51,9 @@ const STATIC_CLASS_HANDLERS: ClassHandlerMap = {
Single: CalculateSDVXClass,
},
usc: null,
wacca: {
Single: CalculateWACCAColour,
},
};
/**
@@ -132,6 +132,12 @@ const RatingFunctions: RatingFunctions = {
ktRating: await LazyMeanN("ktRating", 20)(g, p, u),
}),
},
wacca: {
Single: async (g, p, u, l) => ({
naiveRate: await LazySumN("rate", 50)(g, p, u),
rate: await CalculateWACCARate(g, p, u, l),
}),
},
// jubeat: {
// Single: async (g, p, u, l) => ({
// jubility: await CalculateJubility(g, p, u, l),
@@ -149,6 +155,71 @@ export function CalculateRatings(
return RatingFunctions[game][playtype](game, playtype, userID, logger);
}
// Wacca has a funny algorithm for rate involving gitadora-style latest chart bonuses,
async function CalculateWACCARate(
game: Game,
playtype: Playtypes[Game],
userID: integer,
logger: KtLogger
) {
const hotChartIDs = (
await db.charts.wacca.find(
{ "data.releaseVersion": "reverse" },
{ projection: { chartID: 1 } }
)
).map((e) => e.chartID);
const coldChartIDs = (
await db.charts.wacca.find(
{ "data.releaseVersion": { $ne: "reverse" } },
{ projection: { chartID: 1 } }
)
).map((e) => e.chartID);
const best15Hot = await db["personal-bests"].find(
{
game,
playtype,
userID,
chartID: { $in: hotChartIDs },
"calculatedData.rate": { $type: "number" },
},
{
sort: {
"calculatedData.rate": -1,
},
limit: 15,
projection: {
"calculatedData.rate": 1,
},
}
);
const best35Cold = await db["personal-bests"].find(
{
game,
playtype,
userID,
chartID: { $in: coldChartIDs },
"calculatedData.rate": { $type: "number" },
},
{
sort: {
"calculatedData.rate": -1,
},
limit: 35,
projection: {
"calculatedData.rate": 1,
},
}
);
return (
best15Hot.reduce((a, r) => a + r.calculatedData.rate!, 0) +
best35Cold.reduce((a, r) => a + r.calculatedData.rate!, 0)
);
}
async function CalculateGitadoraSkill(
game: Game,
playtype: Playtypes[Game],
@@ -0,0 +1 @@
[]
@@ -0,0 +1 @@
[]