diff --git a/apps/discord-bot/src/commands/arcade/modes/overall-arcade.tsx b/apps/discord-bot/src/commands/arcade/modes/overall-arcade.tsx
index f074cae81..81b78a339 100644
--- a/apps/discord-bot/src/commands/arcade/modes/overall-arcade.tsx
+++ b/apps/discord-bot/src/commands/arcade/modes/overall-arcade.tsx
@@ -9,6 +9,7 @@
import { Arcade } from "@statsify/schemas";
import { LocalizeFunction } from "@statsify/discord";
import { Table } from "#components";
+import { arcadeWins } from "../wins.js";
import { arrayGroup } from "@statsify/util";
interface OverallArcadeTableProps {
@@ -19,30 +20,7 @@ interface OverallArcadeTableProps {
export const OverallArcadeTable = ({ stats, t }: OverallArcadeTableProps) => {
const rowSize = 3;
- const games: [string, number][] = [
- ["Blocking Dead", stats.blockingDead.wins],
- ["Bounty Hunters", stats.bountyHunters.wins],
- ["Dragon Wars", stats.dragonWars.wins],
- ["Dropper", stats.dropper.wins],
- ["Ender Spleef", stats.enderSpleef.wins],
- ["Farm Hunt", stats.farmHunt.wins],
- ["Football", stats.football.wins],
- ["Galaxy Wars", stats.galaxyWars.wins],
- ["Hide And Seek", stats.hideAndSeek.overall.wins],
- ["Hole In The Wall", stats.holeInTheWall.wins],
- ["Hypixel Says", stats.hypixelSays.wins],
- ["Mini Walls", stats.miniWalls.wins],
- ["Party Games", stats.partyGames.wins],
- ["Pixel Painters", stats.pixelPainters.wins],
- ["Pixel Party", stats.pixelParty.overall.wins],
- ["Seasonal", stats.seasonal.totalWins],
- ["Throw Out", stats.throwOut.wins],
- ["Zombies", stats.zombies.overall.wins],
- ];
-
- games.sort((a, b) => b[1] - a[1]);
-
- const rows = arrayGroup(games, rowSize);
+ const rows = arrayGroup(arcadeWins(stats), rowSize);
const colors = ["§d", "§b", "§a", "§e", "§6", "§c"];
diff --git a/apps/discord-bot/src/commands/arcade/wins.ts b/apps/discord-bot/src/commands/arcade/wins.ts
new file mode 100644
index 000000000..c14b3b0d2
--- /dev/null
+++ b/apps/discord-bot/src/commands/arcade/wins.ts
@@ -0,0 +1,36 @@
+/**
+ * Copyright (c) Statsify
+ *
+ * This source code is licensed under the GNU GPL v3 license found in the
+ * LICENSE file in the root directory of this source tree.
+ * https://github.com/Statsify/statsify/blob/main/LICENSE
+ */
+
+import { Arcade } from "@statsify/schemas";
+
+export function arcadeWins(stats: Arcade): [string, number][] {
+ const games: [string, number][] = [
+ ["Blocking Dead", stats.blockingDead.wins],
+ ["Bounty Hunters", stats.bountyHunters.wins],
+ ["Dragon Wars", stats.dragonWars.wins],
+ ["Dropper", stats.dropper.wins],
+ ["Ender Spleef", stats.enderSpleef.wins],
+ ["Farm Hunt", stats.farmHunt.wins],
+ ["Football", stats.football.wins],
+ ["Galaxy Wars", stats.galaxyWars.wins],
+ ["Hide And Seek", stats.hideAndSeek.overall.wins],
+ ["Hole In The Wall", stats.holeInTheWall.wins],
+ ["Hypixel Says", stats.hypixelSays.wins],
+ ["Mini Walls", stats.miniWalls.wins],
+ ["Party Games", stats.partyGames.wins],
+ ["Pixel Painters", stats.pixelPainters.wins],
+ ["Pixel Party", stats.pixelParty.overall.wins],
+ ["Seasonal", stats.seasonal.totalWins],
+ ["Throw Out", stats.throwOut.wins],
+ ["Zombies", stats.zombies.overall.wins],
+ ];
+
+ games.sort((a, b) => b[1] - a[1]);
+
+ return games;
+}
diff --git a/apps/discord-bot/src/commands/general/general.profile.tsx b/apps/discord-bot/src/commands/general/general.profile.tsx
index 60361afd2..71cb9e31a 100644
--- a/apps/discord-bot/src/commands/general/general.profile.tsx
+++ b/apps/discord-bot/src/commands/general/general.profile.tsx
@@ -8,8 +8,9 @@
import { Container, Footer, Header, If, Table } from "#components";
import { DateTime } from "luxon";
-import { FormattedGame, Guild, PlayerStatus } from "@statsify/schemas";
+import { FormattedGame, Guild, PlayerStats, PlayerStatus } from "@statsify/schemas";
import { LocalizeFunction } from "@statsify/discord";
+import { arcadeWins } from "#commands/arcade/wins";
import type { BaseProfileProps } from "#commands/base.hypixel-command";
interface GeneralProfileHeaderBodyProps {
@@ -79,6 +80,8 @@ export const GeneralProfile = ({
const { status } = player;
const member = guild?.members.find((m) => m.uuid === player.uuid);
+ const mostPlayedGame = findMostPlayedGame(player.stats);
+
return (
-
+
+
+
+
+
{(member) => (
-
-
-
-
-
+
+
+
+
+
+
+
)}
@@ -156,3 +161,654 @@ export const GeneralProfile = ({
);
};
+
+function findMostPlayedGame(stats: PlayerStats): PlayableGame {
+ const keys = Object.keys(stats) as Array;
+ const games = keys.filter((game) => game !== "parkour" && game !== "general" && game !== "quests" && game !== "challenges");
+ const weights = games.map((game) => gameWeight(stats, game));
+
+ let max = weights[0];
+ let index = 0;
+
+ for (const [i, weight] of weights.entries()) {
+ if (weight > max) {
+ index = i;
+ max = weight;
+ }
+ }
+
+ return games[index];
+}
+
+type PlayableGame = Exclude;
+
+function gameWeight(stats: PlayerStats, game: PlayableGame) {
+ const [mean, stdev] = GameNormal[game];
+
+ let score: number;
+
+ switch (game) {
+ case "arcade":
+ score = stats.arcade.wins;
+ break;
+
+ case "arenabrawl":
+ score = stats.arenabrawl.overall.wins;
+ break;
+
+ case "bedwars":
+ score = stats.bedwars.overall.wins;
+ break;
+
+ case "blitzsg":
+ score = stats.blitzsg.overall.wins;
+ break;
+
+ case "buildbattle":
+ score = stats.buildbattle.overall.wins;
+ break;
+
+ case "copsandcrims":
+ score = stats.copsandcrims.overall.wins;
+ break;
+
+ case "duels":
+ score = stats.duels.overall.wins;
+ break;
+
+ case "megawalls":
+ score = stats.megawalls.overall.wins;
+ break;
+
+ case "murdermystery":
+ score = stats.murdermystery.overall.wins;
+ break;
+
+ case "paintball":
+ score = stats.paintball.wins;
+ break;
+
+ case "pit":
+ score = stats.pit.trueLevel;
+ break;
+
+ case "quake":
+ score = stats.quake.overall.wins;
+ break;
+
+ case "skywars":
+ score = stats.skywars.overall.wins;
+ break;
+
+ case "smashheroes":
+ score = stats.smashheroes.overall.wins;
+ break;
+
+ case "speeduhc":
+ score = stats.speeduhc.overall.wins;
+ break;
+
+ case "tntgames":
+ score = stats.tntgames.wins;
+ break;
+
+ case "turbokartracers":
+ score = stats.turbokartracers.gold + stats.turbokartracers.silver + stats.turbokartracers.bronze;
+ break;
+
+ case "uhc":
+ score = stats.uhc.overall.wins;
+ break;
+
+ case "vampirez":
+ score = stats.vampirez.wins;
+ break;
+
+ case "walls":
+ score = stats.walls.wins;
+ break;
+
+ case "warlords":
+ score = stats.warlords.wins;
+ break;
+
+ case "woolgames":
+ score = stats.woolgames.wins;
+ break;
+ }
+
+ return (score - mean) / stdev;
+}
+
+interface GamePreviewTableProps {
+ game: PlayableGame;
+ stats: PlayerStats;
+ t: LocalizeFunction;
+}
+
+function GamePreviewTable({ game, stats, t }: GamePreviewTableProps) {
+ switch (game) {
+ case "arcade":{
+ const [first, second, third] = arcadeWins(stats[game]);
+
+ return (
+ <>
+
+
+
+
+ >
+ );
+ }
+ case "arenabrawl":
+ return (
+ <>
+
+
+
+ >
+ );
+ case "bedwars":
+ return (
+ <>
+
+
+
+
+ >
+ );
+ case "blitzsg":
+ return (
+ <>
+
+
+
+ >
+ );
+ case "buildbattle":
+ return (
+ <>
+
+
+
+ >
+ );
+ case "copsandcrims":
+ return (
+ <>
+
+
+
+ >
+ );
+ case "duels":
+ return (
+ <>
+
+
+
+
+ >
+ );
+ case "megawalls":
+ return (
+ <>
+
+
+
+ >
+ );
+ case "murdermystery":
+ return (
+ <>
+
+
+
+ >
+ );
+ case "paintball":
+ return (
+ <>
+
+
+
+ >
+ );
+ case "pit":
+ return (
+ <>
+
+
+
+
+ >
+ );
+ case "quake":
+ return (
+ <>
+
+
+
+ >
+ );
+ case "skywars":
+ return (
+ <>
+
+
+
+
+ >
+ );
+ case "smashheroes":
+ return (
+ <>
+
+
+
+
+ >
+ );
+ case "speeduhc":
+ return (
+ <>
+
+
+
+
+ >
+ );
+ case "tntgames":
+ // [TODO]: Add TNT Games stats
+ return [t("stats.wins"), t(stats[game].wins)];
+ case "turbokartracers":
+ return (
+ <>
+
+
+
+ >
+ );
+ case "uhc":
+ return (
+ <>
+
+
+
+ >
+ );
+ case "vampirez":
+ return (
+ <>
+
+
+
+ >
+ );
+ case "walls":
+ return (
+ <>
+
+
+
+ >
+ );
+ case "warlords":
+ return (
+ <>
+
+
+
+ >
+ );
+ case "woolgames":
+ return (
+ <>
+
+
+
+
+ >
+ );
+ }
+}
+
+const FormattedPlayableGame: Record = {
+ arcade: FormattedGame.ARCADE,
+ arenabrawl: FormattedGame.ARENA_BRAWL,
+ bedwars: FormattedGame.BEDWARS,
+ blitzsg: FormattedGame.BLITZSG,
+ buildbattle: FormattedGame.BUILD_BATTLE,
+ copsandcrims: FormattedGame.COPS_AND_CRIMS,
+ duels: FormattedGame.DUELS,
+ megawalls: FormattedGame.MEGAWALLS,
+ murdermystery: FormattedGame.MURDER_MYSTERY,
+ paintball: FormattedGame.PAINTBALL,
+ pit: FormattedGame.PIT,
+ quake: FormattedGame.QUAKE,
+ skywars: FormattedGame.SKYWARS,
+ smashheroes: FormattedGame.SMASH_HEROES,
+ speeduhc: FormattedGame.SPEED_UHC,
+ tntgames: FormattedGame.TNT_GAMES,
+ turbokartracers: FormattedGame.TURBO_KART_RACERS,
+ uhc: FormattedGame.UHC,
+ vampirez: FormattedGame.VAMPIREZ,
+ walls: FormattedGame.WALLS,
+ warlords: FormattedGame.WARLORDS,
+ woolgames: FormattedGame.WOOLGAMES,
+};
+
+/* eslint-disable unicorn/numeric-separators-style */
+const GameNormal: Record = {
+ arcade: [47.943456623159285, 345.45462984480355],
+ arenabrawl: [54.54271059484758, 456.7449242807322],
+ bedwars: [258.74934632116793, 748.0327413158763],
+ blitzsg: [66.62482760173609, 462.74593393363017],
+ buildbattle: [14.501026965691436, 96.75410919555686],
+ challenges: [703.3189660164868, 1121.0524615976233],
+ copsandcrims: [24.66711634640695, 209.2012305609239],
+ duels: [498.4884596072068, 2105.437063866322],
+ general: [2093.1178095654386, 1720.0900266142357],
+ megawalls: [24.53680465485529, 131.15816805113383],
+ murdermystery: [150.76623514552855, 915.9276449171637],
+ paintball: [23.34181091905699, 117.86448713259242],
+ parkour: [0, 0],
+ pit: [102.56580072764409, 277.06822675957835],
+ quake: [26.814050527274105, 430.61202349308223],
+ quests: [413.50770716841487, 981.7769202969056],
+ skywars: [228.95944991807306, 987.3697381192043],
+ smashheroes: [52.99487443574538, 495.9379499033822],
+ speeduhc: [9.100884466556108, 68.29294762132967],
+ tntgames: [30.684695073419277, 369.0345100173687],
+ turbokartracers: [71.54076539101497, 427.8901349133345],
+ uhc: [26.139986346957933, 84.59519407156014],
+ vampirez: [20.305040582036874, 231.25314292785842],
+ walls: [8.220307526093416, 79.08187919057073],
+ warlords: [27.839182249700166, 217.31182795352672],
+ woolgames: [21.583678620368413, 285.09386895294614],
+};
+
diff --git a/apps/discord-bot/src/commands/vampirez/vampirez.profile.tsx b/apps/discord-bot/src/commands/vampirez/vampirez.profile.tsx
index a22e8d699..5bfd4c4f2 100644
--- a/apps/discord-bot/src/commands/vampirez/vampirez.profile.tsx
+++ b/apps/discord-bot/src/commands/vampirez/vampirez.profile.tsx
@@ -38,7 +38,7 @@ export const VampireZProfile = ({
const sidebar: SidebarItem[] = [
[t("stats.coins"), t(vampirez.coins), "§6"],
[t("stats.tokens"), t(vampirez.tokens), "§e"],
- [t("stats.overallWins"), t(vampirez.overallWins), "§a"],
+ [t("stats.overallWins"), t(vampirez.wins), "§a"],
[t("stats.zombieKills"), t(vampirez.zombieKills), "§2"],
];
diff --git a/apps/discord-bot/src/components/Table/TableData.tsx b/apps/discord-bot/src/components/Table/TableData.tsx
index 5a38b1574..6b7ccbe82 100644
--- a/apps/discord-bot/src/components/Table/TableData.tsx
+++ b/apps/discord-bot/src/components/Table/TableData.tsx
@@ -52,7 +52,8 @@ export const TableData = ({ title, value, color, size = "regular" }: TableDataPr
{`${color}${title}`}
{`§^4^${color}${value}`}
+ size={4}
+ >{`${color}${value}`}
);
diff --git a/packages/schemas/src/player/gamemodes/vampirez/index.ts b/packages/schemas/src/player/gamemodes/vampirez/index.ts
index 2c2485f13..afc9757a0 100644
--- a/packages/schemas/src/player/gamemodes/vampirez/index.ts
+++ b/packages/schemas/src/player/gamemodes/vampirez/index.ts
@@ -23,7 +23,7 @@ export class VampireZ {
public tokens: number;
@Field()
- public overallWins: number;
+ public wins: number;
@Field({ historical: { enabled: false } })
public mostVampireKills: number;
@@ -57,7 +57,7 @@ export class VampireZ {
this.human = new VampireZHuman(data, "human");
this.vampire = new VampireZVampire(data, "vampire");
- this.overallWins = add(this.human.wins, this.vampire.wins);
+ this.wins = add(this.human.wins, this.vampire.wins);
}
}