import { requireAuthentication, t } from "./base" import { z } from "zod" import { createGame, getGameByLobbyCode } from "../game" import { SpecialCardId, specialCardIds } from "../../shared/game/cards" const gameProcedure = t.procedure .use(requireAuthentication) .input(z.object({ lobbyCode: z.string() })) .use(t.middleware(async ({ input, ctx, next }) => { const game = getGameByLobbyCode((input as { lobbyCode: string }).lobbyCode) if (game === null) throw new Error("The game does not exist or is not active") return await next({ ctx: { game } }) })) export const gameRouter = t.router({ start: gameProcedure .mutation(async ({ ctx }) => { if (ctx.game.state.players.findIndex(p => p.id === ctx.user.id) !== 0) throw new Error("Only the creator can start the game") ctx.game.start() }), hit: gameProcedure .mutation(async ({ ctx }) => { if (ctx.game.state.activePlayerId !== ctx.user.id) throw new Error("It is not the player’s turn") await ctx.game.hit() }), stay: gameProcedure .mutation(async ({ ctx }) => { if (ctx.game.state.activePlayerId !== ctx.user.id) throw new Error("It is not the player’s turn") await ctx.game.stay() }), useSpecialCard: gameProcedure .input(z.object({ specialCardId: z.string().refine(a => specialCardIds.includes(a as any)).transform(a => a as SpecialCardId) })) .mutation(async ({ ctx, input }) => { if (ctx.game.state.activePlayerId !== ctx.user.id) throw new Error("It is not the player’s turn") await ctx.game.useSpecialCard(input.specialCardId) }), newRound: gameProcedure .mutation(async ({ ctx }) => { if (ctx.game.state.phase !== "end") throw new Error(`Cannot start a new round in this phase: ${ctx.game.state.phase}`) if (ctx.game.state.players.findIndex(p => p.id === ctx.user.id) !== 0) throw new Error("Only the creator can start a new round") const newGame = createGame(ctx.game.lobbyCode) newGame.addPlayer(ctx.user.id, ctx.user.name) ctx.game.announceNewRoundAndDestroy() }) })