Dynamic max roster size

This commit is contained in:
Kalle
2023-11-25 13:36:57 +02:00
parent ff2fdad03d
commit 0ba2b4c789
5 changed files with 33 additions and 10 deletions

View File

@@ -81,6 +81,7 @@ import {
} from "~/features/mmr";
import { queryTeamPlayerRatingAverage } from "~/features/mmr/mmr-utils.server";
import * as TournamentRepository from "~/features/tournament/TournamentRepository.server";
import { HACKY_maxRosterSizeBeforeStart } from "~/features/tournament/tournament-utils";
export const links: LinksFunction = () => {
return [
@@ -122,8 +123,7 @@ export const action: ActionFunction = async ({ params, request }) => {
} else {
// in the normal check in process this is handled
teams = teams.filter(
(team) =>
team.members.length > TOURNAMENT.TEAM_MAX_MEMBERS_BEFORE_START,
(team) => team.members.length >= TOURNAMENT.TEAM_MIN_MEMBERS_FOR_FULL,
);
}
@@ -623,7 +623,9 @@ function AddSubsPopOver({
const [, copyToClipboard] = useCopyToClipboard();
const subsAvailableToAdd =
TOURNAMENT.TEAM_MAX_MEMBERS_BEFORE_START + 1 - members.length;
HACKY_maxRosterSizeBeforeStart(parentRouteData.tournament) +
1 -
members.length;
const inviteLink = `${SENDOU_INK_BASE_URL}${tournamentJoinPage({
eventId: parentRouteData.tournament.id,

View File

@@ -24,6 +24,7 @@ import {
tournamentTeamMaxSize,
} from "../tournament-utils";
import { useTranslation } from "~/hooks/useTranslation";
import { findByIdentifier } from "../queries/findByIdentifier.server";
export const action: ActionFunction = async ({ request, params }) => {
const tournamentId = tournamentIdFromParams(params);
@@ -41,6 +42,7 @@ export const action: ActionFunction = async ({ request, params }) => {
team.members.some((member) => member.userId === user.id),
);
const tournament = notFoundIfFalsy(findByIdentifier(tournamentId));
const tournamentHasStarted = hasTournamentStarted(tournamentId);
if (tournamentHasStarted) {
@@ -56,6 +58,7 @@ export const action: ActionFunction = async ({ request, params }) => {
teamToJoin,
userId: user.id,
tournamentHasStarted,
tournament,
}) === "VALID",
"Cannot join this team or invite code is invalid",
);
@@ -118,6 +121,7 @@ export default function JoinTeamPage() {
);
const captain = teamToJoin?.members.find((member) => member.isOwner);
const validationStatus = validateCanJoin({
tournament: parentRouteData.tournament,
inviteCode: data.inviteCode,
teamToJoin,
userId: user?.id,
@@ -174,11 +178,13 @@ function validateCanJoin({
teamToJoin,
userId,
tournamentHasStarted,
tournament,
}: {
inviteCode?: string | null;
teamToJoin?: TournamentLoaderTeam;
userId?: number;
tournamentHasStarted: boolean;
tournament: { name: string };
}) {
if (typeof inviteCode !== "string") {
return "MISSING_CODE";
@@ -193,7 +199,8 @@ function validateCanJoin({
return "NO_TEAM_MATCHING_CODE";
}
if (
teamToJoin.members.length >= tournamentTeamMaxSize(tournamentHasStarted)
teamToJoin.members.length >=
tournamentTeamMaxSize({ tournament, tournamentHasStarted })
) {
return "TEAM_FULL";
}

View File

@@ -75,6 +75,7 @@ import { useSelectCounterpickMapPoolState } from "../tournament-hooks";
import { registerSchema } from "../tournament-schemas.server";
import {
HACKY_isInviteOnlyEvent,
HACKY_maxRosterSizeBeforeStart,
HACKY_resolveCheckInTime,
HACKY_resolvePicture,
HACKY_subsFeatureEnabled,
@@ -677,7 +678,7 @@ function FillRoster({
);
const optionalMembers = Math.max(
TOURNAMENT.TEAM_MAX_MEMBERS_BEFORE_START -
HACKY_maxRosterSizeBeforeStart(parentRouteData.tournament) -
ownTeamMembers.length -
missingMembers,
0,
@@ -697,7 +698,8 @@ function FillRoster({
})();
const teamIsFull =
ownTeamMembers.length >= TOURNAMENT.TEAM_MAX_MEMBERS_BEFORE_START;
ownTeamMembers.length >=
HACKY_maxRosterSizeBeforeStart(parentRouteData.tournament);
return (
<div>
@@ -765,7 +767,7 @@ function FillRoster({
<div className="tournament__section__warning">
{t("tournament:pre.roster.footer", {
atLeastCount: TOURNAMENT.TEAM_MIN_MEMBERS_FOR_FULL,
maxCount: TOURNAMENT.TEAM_MAX_MEMBERS_BEFORE_START,
maxCount: HACKY_maxRosterSizeBeforeStart(parentRouteData.tournament),
})}
</div>
</div>

View File

@@ -4,7 +4,7 @@ export const TOURNAMENT = {
COUNTERPICK_MAX_STAGE_REPEAT: 2,
COUNTERPICK_ONE_MODE_TOURNAMENT_MAPS_PER_MODE: 6,
TEAM_MIN_MEMBERS_FOR_FULL: 4,
TEAM_MAX_MEMBERS_BEFORE_START: 6,
DEFAULT_TEAM_MAX_MEMBERS_BEFORE_START: 6,
AVAILABLE_BEST_OF: [3, 5, 7] as const,
ENOUGH_TEAMS_TO_START: 2,
} as const;

View File

@@ -112,6 +112,12 @@ export function HACKY_subsFeatureEnabled(
return true;
}
export function HACKY_maxRosterSizeBeforeStart(event: { name: string }) {
if (HACKY_isSendouQSeasonFinale(event)) return 5;
return TOURNAMENT.DEFAULT_TEAM_MAX_MEMBERS_BEFORE_START;
}
export function mapPickCountPerMode(event: TournamentLoaderData["tournament"]) {
return isOneModeTournamentOf(event)
? TOURNAMENT.COUNTERPICK_ONE_MODE_TOURNAMENT_MAPS_PER_MODE
@@ -159,9 +165,15 @@ export function tournamentRoundI18nKey(round: PlayedSet["round"]) {
return `bracket.${round.type}` as const;
}
export function tournamentTeamMaxSize(tournamentHasStarted: boolean) {
export function tournamentTeamMaxSize({
tournament,
tournamentHasStarted,
}: {
tournament: { name: string };
tournamentHasStarted: boolean;
}) {
// ensuring every team can add at least one sub while the tournament is ongoing
return (
TOURNAMENT.TEAM_MAX_MEMBERS_BEFORE_START + Number(tournamentHasStarted)
HACKY_maxRosterSizeBeforeStart(tournament) + Number(tournamentHasStarted)
);
}