from transcendence.abstract.AbstractRoom import AbstractRoom from transcendence.abstract.AbstractRoomMember import AbstractRoomMember from channels.generic.websocket import WebsocketConsumer from .Ball import Ball from .Player import Player from .Spectator import Spectator from .Wall import Wall import math from .. import config from ..models import GameModel class Game(AbstractRoom): def __init__(self, game_id): super().__init__(None) self.ball: Ball = Ball() game_model: GameModel = GameModel.objects.get(pk = game_id) self.players_id: list[int] = game_model.get_players_id() self.started = False radius: float = min(config.MAP_SIZE_X, config.MAP_SIZE_Y) / 2 - 10 self.nb_sides = len(self.players_id) * 2 self.polygon: list[tuple[float, float]] = [] for i in range(self.nb_sides): angle: float = (i * 2 * math.pi / self.nb_sides) + (math.pi * 3 / 4) x: float = config.MAP_CENTER_X + radius * math.cos(angle) y: float = config.MAP_CENTER_Y + radius * math.sin(angle) self.polygon.append((x, y)) self.players: list[Player] = [] self.spectators: list[Spectator] = [] self.walls: list[Wall] = [] for i in range(1, self.nb_sides, 2): self.walls.append(Wall(*self.polygon[i], *self.polygon[(i + 1) % self.nb_sides])) self.game_id: int = game_id def broadcast(self, detail: str, data: dict = {}, excludeds: list[Spectator | Player] = []): members: list[Player | Spectator] = self.players + self.spectators for excluded in excludeds: members.remove(excluded) for member in members: member.send(detail, data) def get_player_by_user_id(self, user_id: int) -> Player: for player in self.players: player: Player if (player.user_id == user_id): return player return None def _send_game_data(self, member: AbstractRoomMember): member.send("init_game", self.to_dict()) def append(self, member: AbstractRoomMember): super().append(member) member.send("init_game", self.to_dict()) def _player_join(self, user_id: int, socket: WebsocketConsumer): #check if member is a player if (user_id not in self.players_id): return None # check if player is already connected player = self.get_player_by_user_id(user_id) if (player is not None): player.disconnect(1001) index: int = self.players_id.index(user_id) * 2 player = Player(user_id, socket, *self.polygon[index], *self.polygon[(index + 1) % self.nb_sides]) self.players.append(player) player.accept() self.broadcast("player_join", player.to_dict(), [player]) return player def _player_leave(self, player: Player): # TODO send data to all players self.players.remove(player) def _spectator_join(self, user_id: int, socket: WebsocketConsumer): spectator: Spectator = Spectator(user_id, socket) self.spectators.append(spectator) spectator.accept() return spectator def _spectator_leave(self, spectator: Spectator): self.spectators.remove(spectator) def join(self, user_id: int, socket: WebsocketConsumer) -> Spectator | Player: if (user_id in self.players_id): member: Player = self._player_join(user_id, socket) print("yo") else: member: Spectator = self._spectator_join(user_id, socket) self._send_game_data(member) return member def start(self): self.started = True def remove(self, member: AbstractRoomMember): if (isinstance(member, Player)): self._player_leave(member) elif (isinstance(member, Spectator)): self._spectator_leave(member) def to_dict(self): data: dict = {"ball": self.ball.to_dict(), "players": [player.to_dict() for player in self.players], "walls": [wall.to_dict() for wall in self.walls], } print(self.players ) return data