def endgame(self): if self._state == GameStateEnum.LOST: for player in self.players: with open(PROFILES, mode='r+', encoding='utf-8') as file: temp = json.load(file) file.seek(0) file.truncate() for user in temp: if user['_nickname'] == player.nickname: losses = user['_losses'] user['_losses'] = losses + 1 json.dump(temp, file) player.status = PlayerStatusEnum.NOT_READY EventQueue.block() EventQueue.post(CustomEvent(ChangeSceneEnum.LOSESCENE)) else: for player in self.players: with open(PROFILES, mode='r+', encoding='utf-8') as file: temp = json.load(file) file.seek(0) file.truncate() for user in temp: if user['_nickname'] == player.nickname: wins = user['_wins'] user['_wins'] = wins + 1 json.dump(temp, file) player.status = PlayerStatusEnum.NOT_READY EventQueue.block() EventQueue.post(CustomEvent(ChangeSceneEnum.WINSCENE))
def __init__(self, screen: pygame.Surface, current_player: PlayerModel): Scene.__init__(self, screen) self._current_player = current_player self._init_background() self._init_btn_host(575, 481, "Host", Color.STANDARDBTN, Color.GREEN2) self._init_btn_join(575, 371, "Join", Color.STANDARDBTN, Color.GREEN2) self._init_btn_back(20, 20, "Back", Color.STANDARDBTN, Color.GREEN2) self.buttonJoin.on_click(EventQueue.post, CustomEvent(ChangeSceneEnum.JOINSCENE)) self.buttonBack.on_click(EventQueue.post, CustomEvent(ChangeSceneEnum.STARTSCENE)) self.buttonHost.on_click(EventQueue.post, CustomEvent(ChangeSceneEnum.HOSTMENUSCENE))
def go_back(): if Networking.get_instance().is_host: next_scene = ChangeSceneEnum.SETMAXPLAYERSCENE else: next_scene = ChangeSceneEnum.JOINSCENE Networking.get_instance().disconnect() EventQueue.post(CustomEvent(next_scene))
def __init__(self, screen, current_player: PlayerModel): super().__init__() self._current_player = current_player self._game = GameStateModel.instance() self.player_boxes = [] if Networking.get_instance().is_host: self._current_player.color = Color.BLUE self._game.host.color = Color.BLUE self._current_player.status = PlayerStatusEnum.READY self._player_count = len(self._game.players) self.isReady = False self.resolution = (1280, 700) self.sprite_grp = pygame.sprite.Group() self.players_not_ready_prompt = None self._init_all() if self._game.rules == GameKindEnum.EXPERIENCED: self.buttonSelChar.on_click( EventQueue.post, CustomEvent(ChangeSceneEnum.CHARACTERSCENE)) if Networking.get_instance().is_host: self._current_player.status = PlayerStatusEnum.READY self.isReady = True self.start_button.on_click(self.start_game) self.start_button.disable() if self._game.rules == GameKindEnum.EXPERIENCED and self._current_player.role == PlayerRoleEnum.FAMILY: self._current_player.status = PlayerStatusEnum.NOT_READY else: self._current_player.status = PlayerStatusEnum.NOT_READY self.buttonReady.on_click(self.set_ready) self.buttonBack.on_click(self.go_back)
def _init_btn_back(self, x_pos: int, y_pos: int, text: str, color: Color, color_text: Color): box_size = (130, 48) self.buttonBack = RectButton(x_pos, y_pos, box_size[0], box_size[1], color, 0, Text(pygame.font.SysFont('Agency FB', 25), text, color_text)) self.buttonBack.on_click(EventQueue.post, CustomEvent(ChangeSceneEnum.CHOOSEBOARDSCENE)) self.buttonBack.change_bg_image(WOOD) self.buttonBack.add_frame(FRAME) self.sprite_grp.add(self.buttonBack)
def execute(self): logger.info( f"Player {self._source.nickname} is asking you for command permission" ) EventQueue.post( CustomEvent(CustomEventEnum.PERMISSION_PROMPT, source=self._source, target=self._target))
def __init__(self, screen: pygame.Surface, host_player: PlayerModel): Scene.__init__(self, screen) self._host = host_player self._init_background() self._init_btn_new_game(575, 481, "New Game", Color.STANDARDBTN, Color.GREEN2) self._init_btn_login(575, 371, "Load Game", Color.STANDARDBTN, Color.GREEN2) self._init_btn_back(20, 20, "Back", Color.STANDARDBTN, Color.GREEN2) self.buttonNewGame.on_click( EventQueue.post, CustomEvent(ChangeSceneEnum.CREATEGAMEMENU)) self.buttonLogin.on_click(EventQueue.post, CustomEvent(ChangeSceneEnum.LOADGAME)) self.buttonBack.on_click( EventQueue.post, CustomEvent(ChangeSceneEnum.HOSTJOINSCENE, player=self._host))
def callback_disconnect(): """ Define callback here when client's connection to host is interrupted. :return: """ # if Networking.get_instance().is_host: logger.warning("It seems that client is not connected...") Networking.get_instance().disconnect() EventQueue.post(CustomEvent(ChangeSceneEnum.DISCONNECT))
def __init__(self, screen, current_player: PlayerModel): self._current_player = current_player self.resolution = (1280, 700) self.sprite_grp = pygame.sprite.Group() self._init_background() self._init_text_box(342, 350, "Enter IP:", Color.STANDARDBTN, Color.GREEN2) self._init_text_bar(500, 350, 400, 32) self._init_btn(625, 536, "Connect", Color.STANDARDBTN, Color.GREEN2) self._init_btn_back(20, 20, "Back", Color.STANDARDBTN, Color.GREEN2) self._text_bar = self._init_text_bar(500, 350, 400, 32) self.error_msg = "" self.buttonBack.on_click(EventQueue.post, CustomEvent(ChangeSceneEnum.HOSTJOINSCENE, player=self._current_player)) self.buttonConnect.on_click(self.join)
def load_game(self, save): """Instantiate a new family game and move to the lobby scene.""" data = save # Restore game metadata game: GameStateModel = JSONSerializer.deserialize(data) game.host = self._current_player game.players = [self._current_player] game._players_turn_index = 0 # Restore GameBoard GameStateModel.set_game(game) game.game_board.is_loaded = True Networking.get_instance().create_host() EventQueue.post(CustomEvent(ChangeSceneEnum.LOBBYSCENE))
def confirm(self): if self.character_enum: accept = True # This is a boolean flag if any([player.role == self.character_enum for player in self._game.players]): accept = False if accept: # means no one took this character EventQueue.post(CustomEvent(ChangeSceneEnum.LOBBYSCENE)) event = ChooseCharacterEvent(self.character_enum, self._game.players.index(self._current_player)) if Networking.get_instance().is_host: Networking.get_instance().send_to_all_client(event) else: Networking.get_instance().send_to_server(event)
def __init__(self, screen, current_player: PlayerModel): self.label_grp = pygame.sprite.Group() self._current_player = current_player Scene.__init__(self, screen) self._init_background() self._game = GameStateModel.instance() self.create_label(0, 0, 100, 150, 1) self.create_butn_img(150, 150, 99, 150, MEDIA_CONSTS.CAFS_FIREFIGHTER, 1) self.create_butn_img(350, 150, 100, 150, MEDIA_CONSTS.DRIVER_OPERATOR, 2) self.create_butn_img(550, 150, 100, 150, MEDIA_CONSTS.FIRE_CAPTAIN, 3) self.create_butn_img(750, 150, 99, 150, MEDIA_CONSTS.GENERALIST, 4) self.create_butn_img(150, 450, 100, 150, MEDIA_CONSTS.HAZMAT_TECHNICIAN, 5) self.create_butn_img(350, 450, 99, 150, MEDIA_CONSTS.IMAGING_TECHNICIAN, 6) self.create_butn_img(550, 450, 99, 150, MEDIA_CONSTS.PARAMEDIC, 7) self.create_butn_img(750, 450, 98, 150, MEDIA_CONSTS.RESCUE_SPECIALIST, 8) self.create_butn_img(950, 150, 98, 150, MEDIA_CONSTS.DOGE, 9) self.create_butn_img(950, 450, 99, 150, MEDIA_CONSTS.VETERAN, 10) self._init_btn_back(20, 20, "Back", Color.STANDARDBTN, Color.BLACK) self._init_btn_confirm(1100, 575, "Confirm", Color.STANDARDBTN, Color.BLACK) self._init_title_text() self.character_enum: PlayerRoleEnum = None self.buttonBack.on_click(EventQueue.post, CustomEvent(ChangeSceneEnum.LOBBYSCENE)) self.buttonConfirm.on_click(self.confirm)
def update_profiles(self): if not os.path.exists(self.profiles): with open(self.profiles, mode="w+", encoding='utf-8') as myFile: myFile.write("[]") with open(self.profiles, mode='r', encoding='utf-8') as myFile: temp = json.load(myFile) for i, user in enumerate(temp): player: PlayerModel = JSONSerializer.deserialize(user) player.ip = Networking.get_instance().get_ip() player.set_pos(-1, -1) player.ap = 0 player.special_ap = 0 player.carrying_victim = NullModel() self.profile.set_profile( i, player.nickname, player.wins, player.losses, EventQueue.post, CustomEvent(ChangeSceneEnum.HOSTJOINSCENE, player=player) ) self.profile.remove_profile_callback(i, self.remove_profile, player.nickname)
def join(self): """ Start the join host process in Networking :param ip_addr: ip address to connect :param next_scene: next scene to be called after the process completes :param args: extra arguments for the next scene :return: """ ip_addr = self.text_bar_msg try: self._current_player.status = PlayerStatusEnum.NOT_READY Networking.get_instance().join_host(ip_addr, player=self._current_player) reply = Networking.wait_for_reply() # Connection error will be raised if no reply if reply: reply = JSONSerializer.deserialize(reply) if isinstance(reply, TooManyPlayersEvent): raise TooManyPlayersException(self._current_player) # GameStateModel.set_game(JSONSerializer.deserialize(reply)) EventQueue.post(CustomEvent(ChangeSceneEnum.LOBBYSCENE)) except TimeoutError: msg = "Host not found." print(msg) self.init_error_message(msg) except TooManyPlayersException: msg = "Lobby is full. Cannot join the game." print(msg) self.init_error_message(msg) # Disconnect client that's trying to connect if not Networking.get_instance().is_host: Networking.get_instance().client.disconnect() except Networking.Client.SocketError: msg = "Failed to establish connection." print(msg) self.init_error_message(msg) except OSError: msg = "Invalid IP address" print(msg) self.init_error_message(msg)
def dodge(self, player: PlayerModel) -> bool: """ Determines whether the player can dodge (out of turn) to avoid being knocked down and performs dodge. Returns False otherwise. :param player: player that is attempting to dodge :return: True if the player is able to dodge, False otherwise """ logger.info("Attempting to dodge...") # Doge cannot dodge if player.role == PlayerRoleEnum.DOGE: self._log_player_dodge(1, player) return False if not self._valid_to_dodge(player): self._log_player_dodge(1, player) return False player_tile = self.game_state.game_board.get_tile_at( player.row, player.column) possible_dodge_target = NullModel() for dirn, nb_tile in player_tile.adjacent_tiles.items(): if isinstance(nb_tile, TileModel): has_obstacle = player_tile.has_obstacle_in_direction(dirn) obstacle = player_tile.get_obstacle_in_direction(dirn) is_open_door = isinstance( obstacle, DoorModel) and obstacle.door_status == DoorStatusEnum.OPEN if not has_obstacle or is_open_door: if nb_tile.space_status != SpaceStatusEnum.FIRE: possible_dodge_target = nb_tile break # If we couldn't find a potential space # to dodge, the player cannot avoid being # knocked down. if isinstance(possible_dodge_target, NullModel): self._log_player_dodge(1, player) return False # Pause the current event and ask player to dodge: EventQueue.post(CustomEvent(CustomEventEnum.DODGE_PROMPT, player)) logger.info( f"Thread {threading.current_thread().getName()} going to sleep") # Go to sleep switch.pause_event.clear() switch.pause_event.wait() logger.info(f"Thread {threading.current_thread().getName()} woke up") if not GameStateModel.instance().dodge_reply: logger.info("Reply was no, knocking player down") return False logger.info("Reply was yes, attempting to dodge...") GameStateModel.instance().dodge_reply = False # Disassociate the victim/hazmat that the player # may be carrying since they cannot dodge with them player_victim = player.carrying_victim player_hazmat = player.carrying_hazmat is_carrying_victim = isinstance(player_victim, VictimModel) is_carrying_hazmat = isinstance(player_hazmat, HazmatModel) if is_carrying_victim: self._log_player_dodge(2, player, player_victim, player_tile) player_tile.add_associated_model(player_victim) player.carrying_victim = NullModel() if is_carrying_hazmat: self._log_player_dodge(2, player, player_hazmat, player_tile) player_tile.add_associated_model(player_hazmat) player.carrying_hazmat = NullModel() self._log_player_dodge(3, player) player.set_pos(possible_dodge_target.row, possible_dodge_target.column) # Costs 1 AP for Veteran to dodge # and 2 AP for the rest of the roles if player.role == PlayerRoleEnum.VETERAN: player.ap = player.ap - 1 else: player.ap = player.ap - 2 return True
def _continue(self): Networking.get_instance().disconnect() EventQueue.post(CustomEvent(ChangeSceneEnum.STARTSCENE))
def create_new_game(self, game_kind: GameKindEnum, difficulty_level: DifficultyLevelEnum = None): """Instantiate a new family game and move to the lobby scene.""" GameStateModel(self._current_player, 6, game_kind, GameBoardTypeEnum.ORIGINAL, difficulty_level) EventQueue.post(CustomEvent(ChangeSceneEnum.CHOOSEBOARDSCENE))
def _disconnect_and_back(): Networking.get_instance().disconnect() EventQueue.post(CustomEvent(ChangeSceneEnum.HOSTMENUSCENE))
def set_and_continue(desired_players: int): GameStateModel.instance().max_players = desired_players Networking.get_instance().create_host() EventQueue.post(CustomEvent(ChangeSceneEnum.LOBBYSCENE))
def set_and_continue(board_type: GameBoardTypeEnum): GameStateModel.instance().board_type = board_type EventQueue.post(CustomEvent(ChangeSceneEnum.SETMAXPLAYERSCENE))
def execute(self): logging.info("Executing StartGameEvent.") GameStateModel.instance().state = GameStateEnum.PLACING_PLAYERS EventQueue.block() EventQueue.post(CustomEvent(ChangeSceneEnum.GAMEBOARDSCENE))
def countdown(self): EventQueue.post(CustomEvent(CustomEventEnum.ENABLE_KNOCKDOWN_PROMPT, self.player.nickname)) time.sleep(5) EventQueue.post(CustomEvent(CustomEventEnum.DISABLE_KNOCKDOWN_PROMPT))
def countdown(self): EventQueue.post(CustomEvent( CustomEventEnum.ENABLE_VICTIM_SAVED_PROMPT)) time.sleep(5) EventQueue.post( CustomEvent(CustomEventEnum.DISABLE_VICTIM_SAVED_PROMPT))
def execute(self, *args, **kwargs): logger.info(f"Host has disconnected") EventQueue.post(CustomEvent(ChangeSceneEnum.DISCONNECT))