Files
healer-man/src/game/arenaPractice.ts
T
2026-09-05 21:27:30 -04:00

75 lines
2.5 KiB
TypeScript

import type { CharacterProfile } from "../app/types";
import { ArenaSimulation } from "../../server/arena-simulation.mjs";
import type { ArenaAuthoritativeSnapshot, ArenaCombatIntent, ArenaResult, ArenaRole, ArenaStageManifest } from "./arenaTypes";
interface PracticeOptions {
character: CharacterProfile;
role: ArenaRole;
bracket: "2v2" | "3v3";
ruleset: "wow" | "coa" | "rom";
stage: ArenaStageManifest;
difficulty: number;
onSnapshot: (snapshot: ArenaAuthoritativeSnapshot) => void;
onResult: (result: ArenaResult) => void;
}
function teamRoles(teamSize: number, playerRole?: ArenaRole): ArenaRole[] {
const roles: ArenaRole[] = playerRole ? [playerRole] : [];
if (!roles.includes("healer")) roles.push("healer");
while (roles.length < teamSize) roles.push("damage");
return roles;
}
export function createArenaPractice(options: PracticeOptions) {
const id = `practice-${Date.now().toString(36)}`;
const teamSize = options.bracket === "2v2" ? 2 : 3;
const participants = [
...teamRoles(teamSize, options.role).map((role, index) => ({
actorId: index === 0 ? "practice-player" : `practice-ally-${index}`,
accountId: null,
characterId: index === 0 ? options.character.id : null,
name: index === 0 ? options.character.name : role === "healer" ? "Training Medic" : `Training Ally ${index}`,
team: 0 as const,
role,
isBot: index !== 0,
rating: options.difficulty,
})),
...teamRoles(teamSize).map((role, index) => ({
actorId: `practice-enemy-${index}`,
accountId: null,
characterId: null,
name: role === "healer" ? "Opponent Medic" : `Opponent ${index + 1}`,
team: 1 as const,
role,
isBot: true,
rating: options.difficulty,
})),
];
const simulation = new ArenaSimulation({
id,
stage: options.stage,
bracket: options.bracket,
mode: "practice",
ruleset: options.ruleset,
participants,
onSnapshot: (snapshot) => options.onSnapshot({ ...snapshot, controlledActorId: "practice-player" }),
onResult: (result) => options.onResult({ ...result, ratingUpdates: [] }),
});
options.onSnapshot({ ...simulation.snapshot(), controlledActorId: "practice-player" });
let started = false;
return {
start() {
if (started) return;
started = true;
simulation.resetPreparationClock();
simulation.start();
},
intent(intent: ArenaCombatIntent) {
return simulation.receiveIntent("practice-player", intent);
},
stop() {
simulation.stop();
},
};
}