def draw(self, screen): x_offset1 = 0 if self.orientation == "vertical" else 25 y_offset1 = 0 if self.orientation == "horizontal" else 25 x_offset2 = 0 if self.orientation == "vertical" else 50 y_offset2 = 0 if self.orientation == "horizontal" else 50 if self.damaged: marker = RectLabel(self.button.rect.x + x_offset1, self.button.rect.y + y_offset1, 28, 28, "media/Threat_Markers/damageMarker.png") marker.draw(screen) elif self.destroyed: marker = RectLabel(self.button.rect.x + x_offset2, self.button.rect.y + y_offset2, 28, 28, "media/Threat_Markers/damageMarker.png") marker.draw(screen) marker = RectLabel(self.button.rect.x + x_offset1, self.button.rect.y + y_offset1, 28, 28, "media/Threat_Markers/damageMarker.png") marker.draw(screen)
class DoorSprite(pygame.sprite.Sprite, DoorObserver): def __init__(self, door_model: DoorModel, orientation: str, tile_sprite: TileSprite, tile_model: TileModel, id: Tuple[int, int, str]): super().__init__() self.orientation = orientation self._game: GameStateModel = GameStateModel.instance() self._current_player = self._game.players_turn self._button = None self.tile_model = tile_model self.id = id self.door_model = door_model self.door_model.add_observer(self) self.open = self.door_model.door_status == DoorStatusEnum.OPEN self.closed = self.door_model.door_status == DoorStatusEnum.CLOSED self.destroyed = self.door_model.door_status == DoorStatusEnum.DESTROYED self.marker = None self.tile_sprite = tile_sprite self._prev_x = self.tile_sprite.rect.x self._prev_y = self.tile_sprite.rect.y self.button_input = RectButton( self.tile_sprite.rect.x + 100, self.tile_sprite.rect.y + 100, 100, 25, Color.WOOD, 0, Text(pygame.font.SysFont('Agency FB', 15), "Interact", Color.GREEN2)) pygame.draw.rect(self.button_input.image, Color.YELLOW, [0, 0, 100, 25], 3) self.button_input.disable() self.menu_shown = False @property def direction(self) -> str: return self.id[2] @property def player(self) -> PlayerModel: return self._current_player @property def button(self): return self._button @button.setter def button(self, button): self._button = button def update(self, event_queue): diff_x = self.tile_sprite.rect.x - self._prev_x diff_y = self.tile_sprite.rect.y - self._prev_y self._button.rect.move_ip((diff_x, diff_y)) self._prev_x = self.tile_sprite.rect.x self._prev_y = self.tile_sprite.rect.y self.button_input.rect.x = self.tile_sprite.rect.x + 100 self.button_input.rect.y = self.tile_sprite.rect.y + 100 for event in event_queue: if event.type == pygame.MOUSEBUTTONUP: if not ((self.button_input.rect.x <= pygame.mouse.get_pos()[0] <= self.button_input.rect.x + 100) and (self.button_input.rect.y <= pygame.mouse.get_pos()[1] <= self.button_input.rect.y + 25)): self.button_input.disable() self._button.update(event_queue) self.button_input.update(event_queue) def door_status_changed(self, status: DoorStatusEnum): if status == DoorStatusEnum.DESTROYED: self.destroyed = True self.open = False self.closed = False elif status == DoorStatusEnum.CLOSED: self.closed = True self.open = False self.destroyed = False elif status == DoorStatusEnum.OPEN: self.open = True self.closed = False self.destroyed = False else: raise Exception("Door status ERROR") def draw(self, screen): self.button.draw(screen) x_offset1 = 0 y_offset1 = 0 if self.menu_shown: if self.button_input.enabled: screen.blit(self.button_input.image, self.button_input.rect) if self.orientation == "vertical": x_offset1 = -22 y_offset1 = 40 if self.orientation == "horizontal": x_offset1 = 34 y_offset1 = -18 if self.destroyed: self.marker = RectLabel(self.button.rect.x + x_offset1, self.button.rect.y + y_offset1, 50, 50, "media/Threat_Markers/damageMarker.png") self.marker.draw(screen) if self.open: self.marker = RectLabel(self.button.rect.x + x_offset1, self.button.rect.y + y_offset1, 50, 50, "media/Door_Markers/Open_Door.png") self.marker.draw(screen) if self.closed: self.marker = RectLabel(self.button.rect.x + x_offset1, self.button.rect.y + y_offset1, 50, 50, "media/Door_Markers/Closed_Door.png") self.marker.draw(screen)
class PlayerBox(PlayerObserver): def __init__(self, text_position, background_position, username: str, player: PlayerModel, color: Color): super().__init__() self._game: GameStateModel = GameStateModel.instance() self._assoc_player = player self._assoc_player.add_observer(self) self.player_username = username self.txt_pos = text_position self.background_position = background_position self.text_box = self._init_text_box(color) self.background = RectLabel( self.background_position[0], self.background_position[1], self.background_position[2], self.background_position[3], ) self.background.change_bg_image(MEDIA_CONSTS.WOOD) self.background.add_frame( self.get_path_from_character_enum(self._assoc_player.role)) self.background.add_frame(MEDIA_CONSTS.FRAME) def delete_class(self): self._assoc_player.remove_observer(self) def _init_text_box(self, color: Color): box_size = (self.txt_pos[2], self.txt_pos[3]) user_box = RectLabel( self.txt_pos[0], self.txt_pos[1], box_size[0], box_size[1], color, 0, Text(pygame.font.SysFont('Agency FB', 27), self.player_username, color)) user_box.change_bg_image(MEDIA_CONSTS.WOOD) user_box.add_frame(MEDIA_CONSTS.FRAME) return user_box def get_path_from_character_enum(self, enum: PlayerRoleEnum): if enum == PlayerRoleEnum.CAFS: return MEDIA_CONSTS.CAFS_FIREFIGHTER elif enum == PlayerRoleEnum.CAPTAIN: return MEDIA_CONSTS.FIRE_CAPTAIN elif enum == PlayerRoleEnum.GENERALIST: return MEDIA_CONSTS.GENERALIST elif enum == PlayerRoleEnum.DRIVER: return MEDIA_CONSTS.DRIVER_OPERATOR elif enum == PlayerRoleEnum.HAZMAT: return MEDIA_CONSTS.HAZMAT_TECHNICIAN elif enum == PlayerRoleEnum.IMAGING: return MEDIA_CONSTS.IMAGING_TECHNICIAN elif enum == PlayerRoleEnum.PARAMEDIC: return MEDIA_CONSTS.PARAMEDIC elif enum == PlayerRoleEnum.RESCUE: return MEDIA_CONSTS.RESCUE_SPECIALIST elif enum == PlayerRoleEnum.FAMILY: return MEDIA_CONSTS.FAMILY elif enum == PlayerRoleEnum.DOGE: return MEDIA_CONSTS.DOGE elif enum == PlayerRoleEnum.VETERAN: return MEDIA_CONSTS.VETERAN def draw(self, screen): self.text_box.draw(screen) if self.background: self.background.draw(screen) self.background.change_bg_image(MEDIA_CONSTS.WOOD) self.background.add_frame( self.get_path_from_character_enum(self._assoc_player.role)) self.background.add_frame(MEDIA_CONSTS.FRAME) def player_status_changed(self, status: PlayerStatusEnum): pass def player_ap_changed(self, updated_ap: int): pass def player_special_ap_changed(self, updated_ap: int): pass def player_position_changed(self, row: int, column: int): pass def player_wins_changed(self, wins: int): pass def player_losses_changed(self, losses: int): pass def player_carry_changed(self, carry): pass def player_leading_victim_changed(self, leading_victim): pass def player_role_changed(self, role: PlayerRoleEnum): if self._game.state == GameStateEnum.READY_TO_JOIN: logger.info(f"new role: {role}") role_path = self.get_path_from_character_enum(role) logger.info(f"Role Path is: {role_path}") self.background = (RectLabel(self.background_position[0], self.background_position[1], self.background_position[2], self.background_position[3], role_path))
class DodgePrompt(object): """Prompt for the player deciding whether to dodge or not.""" def __init__(self): self.bg = pygame.image.load(WOOD) self.frame = pygame.image.load(FRAME) self.frame = pygame.transform.scale(self.frame, (400, 100)) self.accept_button = RectButton( 550 - 75, 310, 75, 50, Color.ORANGE, 0, Text(pygame.font.SysFont('Agency FB', 25), "Accept", Color.GREEN2)) self.accept_button.change_bg_image(WOOD) self.accept_button.add_frame(FRAME) self.deny_button = RectButton( 550 + 200, 310, 75, 50, Color.ORANGE, 0, Text(pygame.font.SysFont('Agency FB', 25), "Deny", Color.GREEN2)) self.deny_button.change_bg_image(WOOD) self.deny_button.add_frame(FRAME) self.accept_button.on_click(self._accept_on_click) self.deny_button.on_click(self._deny_on_click) self.background = RectLabel( 550, 300, 200, 75, Color.GREY, 0, Text(pygame.font.SysFont('Agency FB', 25), "Dodge?", Color.GREEN2)) self.background.change_bg_image(WOOD) self.background.add_frame(FRAME) self.enabled = False self.disable() def enable(self): self.deny_button.enable() self.accept_button.enable() self.accept_button.on_click(self._accept_on_click) self.deny_button.on_click(self._deny_on_click) self.enabled = True def disable(self): self.deny_button.disable() self.accept_button.disable() self.accept_button.on_click(None) self.deny_button.on_click(None) self.enabled = False def _send_reply_event(self, reply: bool): if Networking.get_instance().is_host: Networking.get_instance().send_to_all_client( DodgeReplyEvent(reply)) else: Networking.get_instance().send_to_server(DodgeReplyEvent(reply)) def _deny_on_click(self): self.disable() self._send_reply_event(False) def _accept_on_click(self): self.disable() self._send_reply_event(True) def update(self, event_queue: EventQueue): self.background.update(event_queue) self.accept_button.update(event_queue) self.deny_button.update(event_queue) def draw(self, screen): if self.enabled: self.background.draw(screen) self.accept_button.draw(screen) self.deny_button.draw(screen)
class CommandNotification(object): """Displays the command status to the targeted players (source and target)""" def __init__(self): self._source = None self._target = None self._notification = RectLabel( 500, 0, 350, 75, Color.GREY, 0, Text(pygame.font.SysFont('Agency FB', 30), f"Commanding: None", Color.GREEN2)) self._notification.change_bg_image(WOOD) self._notification.add_frame(FRAME) self._wait_command = RectLabel( 500, 400, 300, 50, Color.GREY, 0, Text(pygame.font.SysFont('Agency FB', 30), f"Commanded by: None", Color.GREEN2)) self._wait_command.change_bg_image(WOOD) self._wait_command.add_frame(FRAME) self._init_end_command_btn() self._is_source = False self._is_target = False def _init_end_command_btn(self): # End command button self._end_command_btn = RectButton( 1080, 450, 200, 50, background=Color.ORANGE, txt_obj=Text(pygame.font.SysFont('Agency FB', 23), "END COMMAND", Color.GREEN2)) self._end_command_btn.change_bg_image(WOOD) self._end_command_btn.add_frame(FRAME) self._end_command_btn.on_click(self.end_command) def end_command(self): event = StopCommandEvent(self._source) if Networking.get_instance().is_host: Networking.get_instance().send_to_all_client(event) else: Networking.get_instance().send_to_server(event) @property def command(self) -> Tuple[PlayerModel, PlayerModel]: return self._source, self._target @command.setter def command(self, command: Tuple[PlayerModel, PlayerModel]): (self._source, self._target) = command source_msg = "Commanding: None" target_msg = "Commanded by: None" if self._target: source_msg = f"Commanding: {self._target.nickname}" if self._source: target_msg = f"Commanded by: {self._source.nickname}" self._notification.change_text( Text(pygame.font.SysFont('Agency FB', 30), source_msg, Color.ORANGE)) self._notification.change_bg_image(WOOD) self._notification.add_frame(FRAME) self._wait_command.change_text( Text(pygame.font.SysFont('Agency FB', 30), target_msg, Color.ORANGE)) self._wait_command.change_bg_image(WOOD) self._wait_command.add_frame(FRAME) @property def is_source(self) -> bool: return self._is_source @is_source.setter def is_source(self, source: bool): self._is_source = source @property def is_target(self) -> bool: return self._is_target @is_target.setter def is_target(self, target: bool): self._is_target = target def update(self, event_queue: EventQueue): if self.is_source: self._notification.update(event_queue) self._end_command_btn.update(event_queue) elif self.is_target: self._wait_command.update(event_queue) def draw(self, screen): if self.is_source: self._notification.draw(screen) self._end_command_btn.draw(screen) elif self.is_target: self._wait_command.draw(screen)
class PermissionPrompt(object): """Prompt for the player deciding whether to allow to be commanded or not.""" def __init__(self): self.accept_button = RectButton( 500 - 75, 310, 75, 50, Color.ORANGE, 0, Text(pygame.font.SysFont('Agency FB', 20), "Accept", Color.GREEN2)) self.accept_button.change_bg_image(WOOD) self.accept_button.add_frame(FRAME) self.deny_button = RectButton( 500 + 300, 310, 75, 50, Color.ORANGE, 0, Text(pygame.font.SysFont('Agency FB', 20), "Deny", Color.GREEN2)) self.deny_button.change_bg_image(WOOD) self.deny_button.add_frame(FRAME) self.accept_button.on_click(self._accept_on_click) self.deny_button.on_click(self._deny_on_click) self._source = None self._target = None self.background = RectLabel( 500, 300, 300, 75, Color.GREY, 0, Text(pygame.font.SysFont('Agency FB', 20), "Permission?", Color.GREEN2)) self.background.change_bg_image(WOOD) self.background.add_frame(FRAME) self._enabled = False def _send_reply_event(self, reply: bool): if Networking.get_instance().is_host: Networking.get_instance().send_to_all_client( PermissionReplyEvent(reply, self._source, self._target)) else: Networking.get_instance().send_to_server( PermissionReplyEvent(reply, self._source, self._target)) def _deny_on_click(self): self.enabled = False self._send_reply_event(False) def _accept_on_click(self): self.enabled = False self._send_reply_event(True) def update(self, event_queue: EventQueue): if self._enabled: self.background.update(event_queue) self.accept_button.update(event_queue) self.deny_button.update(event_queue) def draw(self, screen): if self._enabled: self.background.draw(screen) self.accept_button.draw(screen) self.deny_button.draw(screen) @property def enabled(self) -> bool: return self._enabled @enabled.setter def enabled(self, enable: bool): self._enabled = enable @property def command(self) -> Tuple[PlayerModel, PlayerModel]: return self._source, self._target @command.setter def command(self, command: Tuple[PlayerModel, PlayerModel]): self._source = command[0] self._target = command[1] self.background.change_text( Text(pygame.font.SysFont('Agency FB', 20), f"{self._source.nickname} wants to command you", Color.GREEN2)) self.background.change_bg_image(WOOD) self.background.add_frame(FRAME)