import { type Card, create_card, type CardNetcode } from "./Card"; import { type Effect, create_effect, type EffectNetcode, EffectType, CardEffects, } from "./Effect"; import { type Game, create_game, type GameNetcode } from "./Game"; import type { GameObjectNetcode } from "./GameObject"; import { type Player, create_player, type PlayerNetcode } from "./Player"; import { type Team, create_team, type TeamNetcode } from "./Team"; import { type Turn, create_turn } from "./Turn"; import { type Lobby, create_lobby, type LobbyNetcode } from "./Lobby"; import { type Ref } from "vue"; let socket: WebSocket; export class GameObjectRegister { readonly effects: Map; readonly cards: Map; readonly teams: Map; readonly players: Map; readonly turns: Map; readonly games: Map; context: "lobby" | "login" | "pregame" | "game" | "rules" = "login"; private readonly objects: Map; current_game: Ref; lobby: Ref; self: Ref; zoomKeyPressed: Ref hoveredCard: Ref clientMouseX: Ref clientMouseY: Ref discordId: Ref constructor() { this.effects = reactive(new Map()); this.cards = reactive(new Map()); this.teams = reactive(new Map()); this.players = reactive(new Map()); this.turns = reactive(new Map()); this.games = reactive(new Map()); this.objects = reactive(new Map()); this.current_game = ref(null); this.lobby = ref(null); this.self = ref(null); this.zoomKeyPressed = ref(false); this.hoveredCard = ref() this.clientMouseX = ref(0) this.clientMouseY = ref(0) this.discordId = ref("") } update_object(obj: GameObjectNetcode) { // console.log(obj); // console.log(obj.uuid); // console.log(this.objects.get(obj.uuid)); Object.assign(this.objects.get(obj.uuid) as GameNetcode, obj); if (unref(this.current_game)?.uuid === obj.uuid) { triggerRef(this.current_game); } else if (unref(this.lobby)?.uuid === obj.uuid) { triggerRef(this.lobby); } else if (unref(this.self)?.uuid === obj.uuid) { triggerRef(this.self); } else if (unref(this.self)?.turn?.uuid === obj.uuid) { triggerRef(this.self); } } createObject = { effect: (data: EffectNetcode) => { const effect = create_effect(data, this); this.effects.set(data.uuid, effect); this.objects.set(data.uuid, data); }, card: (data: CardNetcode) => { const card = create_card(data, this); this.cards.set(data.uuid, card); this.objects.set(data.uuid, card); }, player: (data: PlayerNetcode) => { const player = create_player(data, this); this.players.set(data.uuid, player); this.objects.set(data.uuid, player); }, team: (data: TeamNetcode) => { const team = create_team(data, this); this.teams.set(data.uuid, team); this.objects.set(data.uuid, team); }, game: (data: GameNetcode) => { const game = create_game(data, this); this.games.set(data.uuid, game); this.objects.set(data.uuid, game); }, turn: (data: any) => { const turn = create_turn(data, this); this.turns.set(data.uuid, turn); this.objects.set(data.uuid, turn); }, lobby: (data: LobbyNetcode) => { this.lobby.value = create_lobby(data, this); this.objects.set(data.uuid, this.lobby.value); }, } as { [id: string]: (data: any) => any }; setSelf = (uuid: string) => { this.self.value = this.players.get(uuid) ?? null; }; setDiscordId = (username: string) => { this.discordId.value = username } setCurrentGame = (uuid: string) => { this.current_game.value = this.games.get(uuid) ?? null; }; } const goStore = reactive(new GameObjectRegister()); export const setup_websocket = () => new Promise((resolve, reject) => { if (socket) { return resolve(); } const config = useRuntimeConfig(); const heron_session = useCookie("heron_session"); socket = new WebSocket(config.public.websocketEndpoint); socket.onopen = function (e) { if (socket.readyState == 1) { resolve(); } console.log("[open] Connection established"); }; socket.onclose = function (event) { if (event.wasClean) { console.warn( `[close] Connection closed cleanly, code=${event.code} reason=${event.reason}` ); } else { // e.g. server process killed or network down // event.code is usually 1006 in this case console.error("[close] Connection died"); } }; socket.onerror = function (error) { console.error(error); }; socket.onmessage = function (event) { const data = JSON.parse(event.data); if (data.type == "create" && data.data_type == "object") { if (!(data.data.object_type in goStore.createObject)) { throw new Error( `Object ${data.data.object_type} couldn't be created` ); } goStore.createObject[data.data.object_type](data.data); } else if (data.type == "update" && data.data_type == "object") { goStore.update_object(data.data); } else if (data.type === "context") { goStore.context = data.data; // console.log(data.data); } else if (data.type === "set") { if (data.data_type == "self") { goStore.setSelf(data.data); } else if (data.data_type == "current_game") { goStore.setCurrentGame(data.data); } else if (data.data_type == "session_cookie") { heron_session.value = data.data; } else if (data.data_type == "self_discord_id") { goStore.setDiscordId(data.data) } } else { // console.log(data.type, data.data_type, data.data); } }; }); export async function heron_cookie_login(cookie: string) { await setup_websocket(); socket.send( JSON.stringify({ type: "cookie_login", data_type: "cookie", data: cookie, }) ); } export async function oauth2_register_discord(code: string) { await setup_websocket(); socket.send( JSON.stringify({ type: "discord_login", data_type: "code", data: code, }) ); } export async function register(username: string) { await setup_websocket(); socket.send( JSON.stringify({ type: "register", data_type: "username", data: username, }) ); } export async function login(username: string) { await setup_websocket(); socket.send( JSON.stringify({ type: "login", data_type: "username", data: username, }) ); } export async function setReady(value: boolean) { await setup_websocket(); socket.send( JSON.stringify({ type: "ready", data_type: "ready_state", data: value, }) ); } export async function buy(card: Card) { await setup_websocket(); socket.send( JSON.stringify({ type: "action", data_type: "buy", data: card.uuid, }) ); } export async function endTurn() { await setup_websocket(); socket.send( JSON.stringify({ type: "action", data_type: "end_turn", data: true, }) ); } export function playAllCards(cards: Card[]) { cards.forEach((c: any) => { playCard(c); }); } export async function playCard(card: Card) { // console.log(card.uuid); await setup_websocket(); socket.send( JSON.stringify({ type: "action", data_type: "play_card", data: card.uuid, }) ); } export async function lockCard(card: Card) { await setup_websocket(); socket.send( JSON.stringify({ type: "action", data_type: "lock_card", data: card.uuid, }) ); } export async function useEffect( effect: Effect, target?: Effect | Card | Player | Team ) { await setup_websocket(); socket.send( JSON.stringify({ type: "action", data_type: "use_effect", data: { effect_id: effect.uuid, target: target?.uuid }, }) ); } export async function discard(card: Card) { await setup_websocket(); socket.send( JSON.stringify({ type: "action", data_type: "discard", data: card.uuid, }) ); } h; export async function heal() { await setup_websocket(); socket.send( JSON.stringify({ type: "action", data_type: "heal", data: 1, }) ); } export async function damage_team(target: Team) { await setup_websocket(); socket.send( JSON.stringify({ type: "action", data_type: "damage_team", data: target.uuid, }) ); } export async function damage_champion(target: Card) { await setup_websocket(); socket.send( JSON.stringify({ type: "action", data_type: "damage_champion", data: target.uuid, }) ); } export async function netcode_create_game() { await setup_websocket(); socket.send( JSON.stringify({ type: "create", data_type: "game", data: "bite", }) ); } export async function join_game(game_uuid: string) { await setup_websocket(); socket.send( JSON.stringify({ type: "join", data_type: "game", data: game_uuid, }) ); } export default goStore;