def move_path(self) -> None: if self.path: dest_x, dest_y = self.path[0] try: # Check if there is any actor blocking. # If there is one, check if that actor is this ai's potential target. If so, proceeds(BumpAction). If not, consider the path blocked. bump_actor = self.parent.gamemap.get_actor_at_location( dest_x, dest_y) if bump_actor: if self.check_if_enemy(bump_actor): BumpAction( self.parent, dest_x - self.parent.x, dest_y - self.parent.y, ).perform() else: raise None else: BumpAction( self.parent, dest_x - self.parent.x, dest_y - self.parent.y, ).perform() # If it moved the coordinate is popped from the path. # If not, it remains. if self.parent.x == dest_x and self.parent.y == dest_y: self.path.pop(0) return None except: if self.target: # if the AI was chasing the target pass # keep chasing regardless of valid path existing it since new path will be generated next turn else: # if the AI was wandering self.wander() # Select new destination to wander
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[Action]: action: Optional[Action] = None key = event.sym player = self.engine.player if key == tcod.event.K_k: action = BumpAction(player, dx=0, dy=-1) elif key == tcod.event.K_j: action = BumpAction(player, dx=0, dy=1) elif key == tcod.event.K_h: action = BumpAction(player, dx=-1, dy=0) elif key == tcod.event.K_l: action = BumpAction(player, dx=1, dy=0) elif key == tcod.event.K_u: action = BumpAction(player, dx=1, dy=-1) elif key == tcod.event.K_y: action = BumpAction(player, dx=-1, dy=-1) elif key == tcod.event.K_b: action = BumpAction(player, dx=-1, dy=1) elif key == tcod.event.K_n: action = BumpAction(player, dx=1, dy=1) elif key == tcod.event.K_ESCAPE: action = EscapeAction(player) return action
def perform(self) -> None: """Revert the AI back to the original state if the effect has run its course""" if self.turns_remaining <= 0: self.engine.message_log.add_message( f"The {self.entity.name} is no longer confused.") self.entity.ai = self.previous_ai else: #Pick a random direction direction_x, direction_y = random.choice([ (-1, -1), #NorthWest (0, -1), #North (1, -1), #NorthEast (-1, 0), #West (1, 0), #East (-1, 1), #SouthWest (0, 1), #South (1, 1), #SouthEast ]) self.turns_remaining -= 1 return BumpAction( self.entity, direction_x, direction_y, ).perform()
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[ActionOrHandler]: action: Optional[Action] = None key = event.sym player = self.engine.player if key in MOVE_KEYS: dx, dy = MOVE_KEYS[key] action = BumpAction(player, dx, dy) elif key in WAIT_KEYS: action = WaitAction(player) elif key == tcod.event.K_ESCAPE: raise SystemExit() elif key == tcod.event.K_v: return HistoryViewer(self.engine) elif key == tcod.event.K_g: action = PickupAction(player) elif key == tcod.event.K_i: return InventoryActivateHandler(self.engine) elif key == tcod.event.K_d: return InventoryDropHandler(self.engine) elif key == tcod.event.K_c: return CharacterScreenEventHandler(self.engine) elif key == tcod.event.K_l: return LookHandler(self.engine) elif key == tcod.event.K_y: return actions.TakeStairsAction(player) # No valid key was pressed return action
def perform(self) -> None: # Revert AI back to original state once effect expires. if self.turns_remaining <= 0: self.engine.message_log.add_message( f"The {self.entity.name} is no longer confused.") self.entity.ai = self.previous_ai else: self.turns_remaining -= 1 # pick a random direction direction_x, direction_y = random.choice([ (-1, -1), # NW (0, -1), # N (1, -1), # NE (-1, 0), # W (1, 0), # E (-1, 1), # SW (0, 1), # S (1, 1), # SE ]) # Chance to not hit allies. target_x = self.entity.x + direction_x, target_y = self.entity.y + direction_y target_entity = self.engine.game_map.get_blocking_entity_at_location( target_x, target_y) if not (target_entity is self.engine.player): # 50% chance of not hitting allies # TODO: Tie into allegiances, intelligence. r = random.random() if r <= 0.5: return WaitAction(self.entity) return BumpAction( self.entity, direction_x, direction_y, ).perform()
def perform(self) -> None: # Revert the AI back to the original state if the effect has run its course. if self.turns_remaining <= 0: self.engine.message_log.add_message( f"The {self.entity.name} is no longer confused.") self.entity.ai = self.previous_ai else: # Pick a random direction direction_x, direction_y = random.choice([ (-1, -1), # Northwest (0, -1), # North (1, -1), # Northeast (-1, 0), # West (1, 0), # East (-1, 1), # Southwest (0, 1), # South (1, 1), # Southeast ]) self.turns_remaining -= 1 # The actor will either try to move or attack in the chosen random direction. # Its possible the actor will just bump into the wall, wasting a turn. return BumpAction( self.entity, direction_x, direction_y, ).perform()
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[ActionOrHandler]: action: Optional[Action] = None key = event.sym modifier = event.mod player = self.engine.player if key == tcod.event.K_PERIOD and modifier & (tcod.event.KMOD_LSHIFT | tcod.event.KMOD_RSHIFT): return actions.TakeStairsAction(player) if key in MOVE_KEYS: dx, dy = MOVE_KEYS[key] action = BumpAction(player, dx, dy) elif key in WAIT_KEYS: action = WaitAction(player) elif key == tcod.event.K_ESCAPE: raise SystemExit() elif key == tcod.event.K_v: return HistoryViewer(self.engine) elif key == tcod.event.K_g: action = PickupAction(player) elif key == tcod.event.K_i: return InventoryActivateHandler(self.engine) elif key == tcod.event.K_d: return InventoryDropHandler(self.engine) elif key == tcod.event.K_c: return CharacterScreenEventHandler(self.engine) elif key == tcod.event.K_SLASH: return LookHandler(self.engine) return action
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[Action]: action: Optional[Action] = None key = event.sym player = self.engine.player if key in MOVE_KEYS: dx, dy = MOVE_KEYS[key] action = BumpAction(player, dx, dy) elif key in WAIT_KEYS: action = WaitAction(player) elif key == tcod.event.K_ESCAPE: raise SystemExit() elif key == tcod.event.K_v: self.engine.event_handler = HistoryViewer(self.engine) elif key == tcod.event.K_g: action = PickupAction(player) elif key == tcod.event.K_o: self.engine.event_handler = InventoryActivateHandler(self.engine) elif key == tcod.event.K_d: self.engine.event_handler = InventoryDropHandler(self.engine) elif key == tcod.event.K_SLASH: self.engine.event_handler = LookHandler(self.engine) return action
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[ActionOrHandler]: action: Optional[Action] = None key = event.sym modifier = event.mod player = self.engine.player if key == tcod.event.K_SPACE: return actions.TakeStairsAction(player) if key in MOVE_KEYS: dx, dy = MOVE_KEYS[key] action = BumpAction(player, dx, dy) elif key in WAIT_KEYS: action = WaitAction(player) elif key == tcod.event.K_ESCAPE: raise SystemExit() elif key == tcod.event.K_m: return HistoryViewer(self.engine) elif key == tcod.event.K_g: action = PickupAction(player) elif key == tcod.event.K_i: return InventoryActivateHandler(self.engine) elif key == tcod.event.K_SLASH: return LookHandler(self.engine) elif key == tcod.event.K_TAB: return ControlsEventHandler(self.engine) # Был нажат невалидный ключ. return action
def ev_keydown (self, event: tcod.event.KeyDown) -> Optional[Action]: action: Optional[Action] = None key = event.sym if key == tcod.event.K_UP: action = BumpAction(dx = 0, dy = -1) elif key == tcod.event.K_DOWN: action = BumpAction(dx = 0, dy = 1) elif key == tcod.event.K_LEFT: action = BumpAction(dx = -1, dy = 0) elif key == tcod.event.K_RIGHT: action = BumpAction(dx = 1, dy = 0) elif key == tcod.event.K_ESCAPE: action = EscapeAction() return action
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[Action]: action: Optional[Action] = None key = event.sym player = self.engine.player if key == tcod.event.K_UP: action = BumpAction(player, dx=0, dy=-1) elif key == tcod.event.K_DOWN: action = BumpAction(player, dx=0, dy=1) elif key == tcod.event.K_LEFT: action = BumpAction(player, dx=-1, dy=0) elif key == tcod.event.K_RIGHT: action = BumpAction(player, dx=1, dy=0) elif key == tcod.event.K_ESCAPE: action = EscapeAction(player) # No valid key was pressed return action
def perform(self) -> None: if self.turns_remaining <= 0: self.engine.message_log.add_message( f"The {self.entity.name} is no longer confused.") self.entity.ai = self.previous_ai else: direction_x, direction_y = random.choice([(-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1)]) self.turns_remaining -= 1 return BumpAction(self.entity, direction_x, direction_y).perform()
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[Action]: # 'action' holds whatever subclass we end up assigning it to action: Optional[Action] = None # 'key' holds the key pressed. # Doesn't include modifiers i.e. shift, alt, ctrl key = event.sym # directional keys modify dx and dy if key == tcod.event.K_UP: action = BumpAction(dx=0, dy=-1) elif key == tcod.event.K_DOWN: action = BumpAction(dx=0, dy=1) elif key == tcod.event.K_LEFT: action = BumpAction(dx=-1, dy=0) elif key == tcod.event.K_RIGHT: action = BumpAction(dx=1, dy=0) elif key == tcod.event.K_ESCAPE: action = EscapeAction() return action
def perform(self) -> None: """Revert the AI back to its original AI if the effect ends""" if self.turns_remaining <= 0: self.engine.message_log.add_message( f"The {self.entity.name} is no longer confused.") self.entity.ai = self.previous_ai else: # Pick random direction direction_x, direction_y = random.choice([(-1, -1), (0, -1), (1, -1), (-1, 0), (-1, 1), (0, 1), (1, 1)]) self.turns_remaining -= 1 return BumpAction(self.entity, direction_x, direction_y).perform()
def perform(self) -> None: if self.turns_remaining <= 0: self.engine.message_log.add_message( f"The {self.entity.name} is no longer confused") self.entity.ai = self.previous_ai else: direction_x, direction_y = random.choice([(-1, -1), (-1, 1), (1, -1), (1, 1), (-1, 0), (1, 0), (0, -1), (0, 1)]) self.turns_remaining -= 1 # try to move or attack in the chosen random direction # if the actor bumps into a wall it will waste its turn return BumpAction(self.entity, direction_x, direction_y).perform()
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[ActionOrHandler]: super().ev_keydown(event) action: Optional[Action] = None key = event.sym modifier = event.mod player = self.engine.player if key == tcod.event.K_PERIOD and modifier & (tcod.event.KMOD_LSHIFT | tcod.event.KMOD_RSHIFT): return actions.TakeStairsAction(player) # If fullscreen was toggled, keep input handler active if event.sym == tcod.event.K_RETURN and event.mod & tcod.event.KMOD_ALT: self.engine.toggle_fullscreen() return None if key in MOVE_KEYS: dx, dy = MOVE_KEYS[key] action = BumpAction(player, dx, dy) elif key in WAIT_KEYS: action = WaitAction(player) elif key == tcod.event.K_ESCAPE: raise SystemExit() elif key == tcod.event.K_v: return HistoryViewer(self.engine) elif key == tcod.event.K_g: action = PickupAction(player) elif key == tcod.event.K_i: return InventoryActivateHandler(self.engine) elif key == tcod.event.K_d: return InventoryDropHandler(self.engine) elif key == tcod.event.K_c: return CharacterScreenEventHandler(self.engine) elif key == tcod.event.K_m: return LookHandler(self.engine) return action
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[Action]: action: Optional[Action] = None key = event.sym player = self.engine.player if key in MOVE_KEYS: dx, dy = MOVE_KEYS[key] action = BumpAction(player, dx, dy) elif key in WAIT_KEYS: action = WaitAction(player) elif key in ESCAPE_KEYS: action = EscapeAction(player) return action
def ev_keydown(self, event: str) -> Optional[ActionOrHandler]: action: Optional[Action] = None key = event modifier = event player = self.engine.player # if key == tcod.event.K_PERIOD and modifier & ( # tcod.event.KMOD_LSHIFT | tcod.event.KMOD_RSHIFT # ): if key == "spacebar": return actions.TakeStairsAction(player) if key == "numpad0": return actions.KillAllAction(player) if key == "numpadenter": return actions.SwitchViewMode(player) if key == "numpadadd": return actions.CheatTakeStairsAction(player) if key in MOVE_KEYS: dx, dy = MOVE_KEYS[key] action = BumpAction(player, dx, dy) elif key in WAIT_KEYS: action = WaitAction(player) elif key == "escape": raise SystemExit() elif key == "v": return HistoryViewer(self.engine) elif key == "g": action = PickupAction(player) elif key == "i": return InventoryActivateHandler(self.engine) elif key == "d": return InventoryDropHandler(self.engine) elif key == "c": return CharacterScreenEventHandler(self.engine) elif key == "/": return LookHandler(self.engine) # No valid key was pressed return action
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[Action]: action: Optional[Action] = None key = event.sym # Common arguments for player actions. context = (self.engine, self.engine.player) if key in (tcod.event.K_UP, tcod.event.K_k): action = BumpAction(*context, dx=0, dy=-1) elif key in (tcod.event.K_DOWN, tcod.event.K_j): action = BumpAction(*context, dx=0, dy=1) elif key in (tcod.event.K_LEFT, tcod.event.K_h): action = BumpAction(*context, dx=-1, dy=0) elif key in (tcod.event.K_RIGHT, tcod.event.K_l): action = BumpAction(*context, dx=1, dy=0) elif key == tcod.event.K_y: action = BumpAction(*context, dx=-1, dy=-1) elif key == tcod.event.K_u: action = BumpAction(*context, dx=1, dy=-1) elif key == tcod.event.K_b: action = BumpAction(*context, dx=-1, dy=1) elif key == tcod.event.K_n: action = BumpAction(*context, dx=1, dy=1) elif key == tcod.event.K_PERIOD: action = WaitAction(*context) elif key == tcod.event.K_ESCAPE: action = EscapeAction(*context) elif key == tcod.event.K_g: action = PickupAction(*context) elif key == tcod.event.K_i: action = ShowInventoryAction(*context) elif key == tcod.event.K_d: action = ShowInventoryAction(*context, dropping=True) # No valid key was pressed return action
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[Action]: # action variable will hold whatever subclass of Action we assign it to, if no input it will store None action: Optional[Action] = None key = event.sym player = self.engine.player if key in MOVE_KEYS: dx, dy = MOVE_KEYS[key] action = BumpAction(player, dx, dy) elif key in WAIT_KEYS: action = WaitAction(player) elif key == tcod.event.K_ESCAPE: action = EscapeAction(player) return action
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[Action]: action: Optional[Action] = None key = event.sym player = self.engine.player if key in MOVE_KEYS: dx, dy = MOVE_KEYS[key] action = BumpAction(player, dx, dy) elif key in WAIT_KEYS: action = WaitAction(player) elif key == tcod.event.K_ESCAPE: action = EscapeAction(player) elif key == tcod.event.K_v: self.engine.event_handler = HistoryViewer(self.engine) # No valid key was pressed return action
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[ActionOrHandler]: """ Registering af key presses. Returnerer type `None` hvis invalid key press. """ action: Optional[Action] = None key = event.sym modifier = event.mod player = self.engine.player if key == tcod.event.K_PERIOD and modifier & (tcod.event.KMOD_LSHIFT | tcod.event.KMOD_RSHIFT): return actions.TakeStairsAction(player) if key in MOVE_KEYS: dir_x, dir_y = MOVE_KEYS[key] action = BumpAction(player, dir_x, dir_y) elif key in WAIT_KEYS: action = WaitAction(player) # Exit the game elif key == tcod.event.K_ESCAPE: raise SystemExit(0) # Message Log elif key == tcod.event.K_v: return HistoryViewer(self.engine) # Pick up item elif key == tcod.event.K_g: action = PickUpAction(player) elif key == tcod.event.K_i: return InventoryActiveHandler(self.engine) elif key == tcod.event.K_d: return InventoryDropHandler(self.engine) elif key == tcod.event.K_c: return CharacterScreenEventHandler(self.engine) elif key == tcod.event.K_MINUS: return LookHandler(self.engine) # Hvis en ikke valid tast blev trykket return action
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[ActionOrHandler]: #action holds whatever subclass of Action we end up assigning it to. Defaults to none. action: Optional[Action] = None #key holds the actual key that we pressed key = event.sym modifier = event.mod player = self.engine.player if key == tcod.event.K_PERIOD and modifier & (tcod.event.KMOD_LSHIFT | tcod.event.KMOD_RSHIFT): return actions.TakeStairsAction(player) #create a MovementAction for the up, down, left and right keys if any of them are pressed if key in MOVE_KEYS: dx, dy = MOVE_KEYS[key] action = BumpAction(player, dx, dy) elif key in WAIT_KEYS: action = WaitAction(player) #if the user presses the escape key, return EscapeAction, which will exit the game. This will exit menus in the future elif key == tcod.event.K_ESCAPE: raise SystemExit() elif key == tcod.event.K_v: return HistoryViewer(self.engine) elif key == tcod.event.K_e: action = PickupAction(player) elif key == tcod.event.K_i: return InventoryActivateHandler(self.engine) elif key == tcod.event.K_d: return InventoryDropHandler(self.engine) elif key == tcod.event.K_SLASH: return LookHandler(self.engine) elif key == tcod.event.K_c: return CharacterScreenEventHandler(self.engine) #Whether a valid key is pressed or not, we return the value of action, which is none by default. return action
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[Action]: # Set the default action to 'none' (returned when no key/invalid key is pressed) action: Optional[Action] = None # Capture the key pressed and grab the 'player' instance from the engine object key = event.sym player = self.engine.player # Check if keypress matches a valid keypress in the pre-defined Dict objects if key in MOVE_KEYS: dx, dy = MOVE_KEYS[key] action = BumpAction(player, dx, dy) elif key in WAIT_KEYS: action = WaitAction(player) # The 'ESC' key returns an 'escape' action elif key == tcod.event.K_ESCAPE: action = EscapeAction(player) # Returns the resulting action type (defualt = 'none') return action
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[ActionOrHandler]: action: Optional[Action] = None key = event.sym modifier = event.mod player = self.engine.player if key == tcod.event.K_PERIOD and modifier & (tcod.event.KMOD_LSHIFT | tcod.event.KMOD_RSHIFT): if self.engine.game_world.current_floor == 8: return WinEventHandler(self.engine) else: return actions.TakeStairsAction(player) if key in MOVE_KEYS: dx, dy = MOVE_KEYS[key] action = BumpAction(player, dx, dy) elif key in WAIT_KEYS: action = WaitAction(player) elif key == tcod.event.K_ESCAPE: raise SystemExit() elif key == tcod.event.K_v: return HistoryViewer(self.engine) elif key == tcod.event.K_g: action = PickupAction(player) elif key == tcod.event.K_i: return InventoryActivateHandler(self.engine) elif key == tcod.event.K_d: return InventoryDropHandler(self.engine) elif key == tcod.event.K_c: return CharacterScreenEventHandler(self.engine) elif key == tcod.event.K_q: return ControlsScreenEventHandler(self.engine) # No valid key was pressed return action
def perform(self) -> None: if self.engine.game_map.visible[self.entity.x, self.entity.y]: direction_x, direction_y = random.choice([ (-1, -1), # Northwest (0, -1), # North (1, -1), # Northeast (-1, 0), # West (1, 0), # East (-1, 1), # Southwest (0, 1), # South (1, 1), # Southeast ]) self.engine.message_log.add_message( f"The {self.entity.name} wanders aimlessly") # The actor will either try to move or attack in the chosen random direction. # Its possible the actor will just bump into the wall, wasting a turn. if self.engine.game_map.visible[self.entity.x, self.entity.y]: return BumpAction( self.entity, direction_x, direction_y, ).perform()
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[Action]: action: Optional[Action] = None key = event.sym modifier = event.mod player = self.engine.player #take stairs if key == tcod.event.K_PERIOD and modifier & (tcod.event.KMOD_LSHIFT | tcod.event.KMOD_RSHIFT): return TakeStairsAction(player) #movement if key in MOVE_KEYS: dx, dy = MOVE_KEYS[key] action = BumpAction(player, dx, dy) elif key in WAIT_KEYS: action = WaitAction(player) #game mode elif key == tcod.event.K_s: # print("switch game mode") action = GameModeAction(player) #full message log history elif key == tcod.event.K_v: self.engine.event_handler = HistoryViewer(self.engine) #quit game, see score without exit app elif key == tcod.event.K_q: self.engine.event_handler = GameOverEventHandler(self.engine) #exit game elif key == tcod.event.K_ESCAPE: action = EscapeAction(player) # No valid key was pressed return action
def do_player_queue_actions(self) -> None: """ The game will automatically do an action for the player based on the player_path, player_dir information. """ ### A. If player path exist (=if the player clicked a tile that is at least 2 tiles away) if self.player_path: # Check if there is any new actor spotted in sight if self.prev_actors_in_sight != self.actors_in_sight: # If so, stop the movement. # TODO: Add an option to not stop? # TODO: Add a feature to stop ONLY if the actor is hostile to player? self.update_entity_in_sight( ) # update actors only when it's necessary self.player_path = deque([]) return False dest_xy = self.player_path[-1] dx = dest_xy[0] - self.player.x dy = dest_xy[1] - self.player.y # Check for semiactors collided_semiactor = self.game_map.get_semiactor_at_location( dest_xy[0], dest_xy[1]) if collided_semiactor: if collided_semiactor.entity_id == "closed_door": # We do not pop from the path, because the player has to first open the door and then move to the tile. BumpAction(self.player, dx, dy).perform() return True if self.game_map.get_actor_at_location(dest_xy[0], dest_xy[1]): # If the monster is in the way, the game automatically attacks it. # After the attack the game will delete the player's path. BumpAction(self.player, dx, dy).perform() self.player_path = deque([]) return True else: # If something unexpectedly blocks the way, perform BumpAction and delete all paths. #NOTE: This part of the code is meant to prevent unexpected circumstances crashing the game. # So be aware that issues can be ignored here. try: BumpAction(self.player, dx, dy).perform() self.player_path.pop() return True except Exception as e: print(f"DEBUG::{e}") self.player_path = deque([]) return False ### B. If the player clicked one of nearby tiles (including the tile player is at) elif self.player_dir: # B-1. Clicked the tile that player is currently at if self.player_dir == (0, 0): # Check for descending stairs if self.game_map.tiles[ self.player.x, self.player.y]["tile_id"] == "descending_stair": try: DescendAction(entity=self.player).perform() self.player_dir = None return True except exceptions.Impossible as exc: self.message_log.add_message(exc.args[0], color.impossible) self.player_dir = None return False except: traceback.print_exc() self.message_log.add_message(traceback.format_exc(), color.error) self.player_dir = None return False # Check for ascending stairs elif self.game_map.tiles[ self.player.x, self.player.y]["tile_id"] == "ascending_stair": try: AscendAction(entity=self.player).perform() self.player_dir = None return True except exceptions.Impossible as exc: self.message_log.add_message(exc.args[0], color.impossible) self.player_dir = None return False except: traceback.print_exc() self.message_log.add_message(traceback.format_exc(), color.error) self.player_dir = None return False # If there is no stair, check for items. # TODO: What if the item is dropped on the stair tile? else: try: PickupAction(entity=self.player).perform() self.player_dir = None return True except exceptions.Impossible as exc: self.message_log.add_message(exc.args[0], color.impossible) self.player_dir = None return False except: traceback.print_exc() self.message_log.add_message(traceback.format_exc(), color.error) self.player_dir = None return False # B-2. Clicked one of the nearby tile else: try: BumpAction(self.player, self.player_dir[0], self.player_dir[1]).perform() self.player_dir = None return True except exceptions.Impossible as exc: self.message_log.add_message(exc.args[0], color.impossible) self.player_dir = None return False except: traceback.print_exc() self.message_log.add_message(traceback.format_exc(), color.error) self.player_dir = None return False return True # Turn passes after every actions like normal