Ejemplo n.º 1
0
 def _confirm_option(self) -> Optional[SceneTransition]:
     if self._selected_option_index < len(self._saved_characters):
         self.flags.saved_player_state = self._saved_characters[
             self._selected_option_index]
         self.flags.character_file = self._files[
             self._selected_option_index]
         return SceneTransition(self.creating_world_scene(self.flags))
     else:
         return SceneTransition(self.picking_hero_scene(self.flags))
Ejemplo n.º 2
0
 def handle_event(self, event: EngineEvent) -> Optional[SceneTransition]:
     if event == EngineEvent.PLAYER_DIED:
         return SceneTransition(self.picking_hero_scene(self.init_flags))
     elif event == EngineEvent.ENEMY_DIED:
         num_enemies = len([npc for npc in self.game_state.non_player_characters if npc.is_enemy])
         if num_enemies == 0:
             return SceneTransition(self.challenge_complete_scene(self.total_time_played))
         self.info_message.set_message(str(num_enemies) + " enemies remaining")
     return None
Ejemplo n.º 3
0
    def run_one_frame(self, _time_passed: Millis) -> Optional[SceneTransition]:

        map_file_name = self.cmd_flags.map_file_name or "map1.json"
        map_file_path = "resources/maps/" + map_file_name

        start_immediately_and_skip_hero_selection = (
            self.cmd_flags.chosen_hero_id is not None
            or self.cmd_flags.hero_start_level is not None
            or self.cmd_flags.start_money is not None
            or self.cmd_flags.save_file_name is not None)
        if start_immediately_and_skip_hero_selection:

            if self.cmd_flags.save_file_name:
                saved_player_state = self.save_file_handler.load_player_state_from_json_file(
                    self.cmd_flags.save_file_name)
                flags = InitFlags(map_file_path=map_file_path,
                                  picked_hero=None,
                                  saved_player_state=saved_player_state,
                                  hero_start_level=None,
                                  start_money=None,
                                  character_file=None)
                return SceneTransition(
                    self.scene_factory.creating_world_scene(flags))

            if self.cmd_flags.chosen_hero_id:
                picked_hero = HeroId[self.cmd_flags.chosen_hero_id]
            else:
                picked_hero = HeroId.MAGE
            hero_start_level = int(self.cmd_flags.hero_start_level
                                   ) if self.cmd_flags.hero_start_level else 1
            start_money = int(self.cmd_flags.start_money
                              ) if self.cmd_flags.start_money else 0

            flags = InitFlags(map_file_path=map_file_path,
                              picked_hero=picked_hero,
                              saved_player_state=None,
                              hero_start_level=hero_start_level,
                              start_money=start_money,
                              character_file=None)
            return SceneTransition(
                self.scene_factory.creating_world_scene(flags))

        else:
            flags = InitFlags(map_file_path=map_file_path,
                              picked_hero=None,
                              saved_player_state=None,
                              hero_start_level=1,
                              start_money=0,
                              character_file=None)
            return SceneTransition(self.scene_factory.main_menu_scene(flags))
Ejemplo n.º 4
0
 def handle_user_input(self,
                       events: List[Any]) -> Optional[SceneTransition]:
     for event in events:
         if event.type == pygame.KEYDOWN:
             if event.key == pygame.K_LEFT or event.key == pygame.K_UP:
                 self._change_hero(-1)
             elif event.key == pygame.K_RIGHT or event.key == pygame.K_DOWN:
                 self._change_hero(1)
             elif event.key == pygame.K_RETURN or event.key == pygame.K_SPACE:
                 self.flags.picked_hero = HEROES[self.selected_hero_index]
                 return SceneTransition(
                     self.creating_world_scene(self.flags))
    def run_one_frame(self, _time_passed: Millis) -> Optional[SceneTransition]:
        # movement speed affects the hero entity in the game state (in contrast to other stats)
        player_speed_multiplier = self.previous_game_engine.game_state.game_world.player_entity.get_speed_multiplier(
        )

        # NPC's share a "global path finder" that needs to be initialized before we start creating NPCs.
        # TODO This is very messy
        path_finder = init_global_path_finder()
        new_game_engine, new_world_behavior = self.create_new_game_engine_and_behavior(
            self.previous_game_engine)
        new_game_state = new_game_engine.game_state
        path_finder.set_grid(new_game_state.pathfinder_wall_grid)

        # Must center camera before notifying player position as it affects which walls are shown on the minimap
        new_game_state.center_camera_on_player()
        self.ui_view.on_world_area_updated(
            new_game_state.game_world.entire_world_area)

        # We set up observers for gameEngine and gameState, since they are newly created in this scene. The player
        # state's observers (ui view) have already been setup in an earlier scene however.
        register_game_engine_observers(new_game_engine, self.ui_view)
        register_game_state_observers(new_game_state,
                                      self.ui_view,
                                      include_player_state=False)

        new_game_state.game_world.set_hero_movement_speed(
            player_speed_multiplier)

        # Clear any messages to give space for any messages generated by the new world behavior
        self.ui_view.info_message.clear_messages()

        # If we don't clear the minimap, there will be remains from the previous game state
        self.ui_view.minimap.clear_exploration()

        playing_scene = self.scene_factory.playing_scene(
            game_state=new_game_state,
            game_engine=new_game_engine,
            world_behavior=new_world_behavior,
            ui_view=self.ui_view,
            new_hero_was_created=False,
            character_file=self.character_file,
            total_time_played_on_character=self.total_time_played_on_character)
        return SceneTransition(playing_scene)
Ejemplo n.º 6
0
 def control(self, time_passed: Millis) -> Optional[SceneTransition]:
     if self.game_state.player_state.has_completed_quest(
             QuestId.MAIN_RETRIEVE_KEY):
         return SceneTransition(self.victory_screen_scene())
Ejemplo n.º 7
0
 def control(self, time_passed: Millis) -> Optional[SceneTransition]:
     if self.game_state.player_state.has_finished_main_quest:
         return SceneTransition(self.victory_screen_scene())
Ejemplo n.º 8
0
 def run_one_frame(self, _time_passed: Millis) -> Optional[SceneTransition]:
     if not self._saved_characters:
         return SceneTransition(
             self.scene_factory.picking_hero_scene(self.flags))
    def run_one_frame(self, _time_passed: Millis) -> Optional[SceneTransition]:

        saved_player_state = self.flags.saved_player_state
        hero_start_level = self.flags.hero_start_level
        start_money = self.flags.start_money
        picked_hero = self.flags.picked_hero
        map_file_path = self.flags.map_file_path
        character_file = self.flags.character_file

        if saved_player_state:
            hero_from_saved_state = HeroId[saved_player_state.hero_id]
            if picked_hero is not None and picked_hero != hero_from_saved_state:
                raise Exception("Mismatch! Hero from saved state: " +
                                str(hero_from_saved_state) +
                                ", but picked hero: " + str(picked_hero))
            picked_hero = hero_from_saved_state

        total_time_played_on_character = saved_player_state.total_time_played_on_character if saved_player_state else 0

        # NPC's share a "global path finder" that needs to be initialized before we start creating NPCs.
        # TODO This is very messy
        path_finder = GlobalPathFinder()
        set_global_path_finder(path_finder)

        map_data = load_map_from_json_file(self.camera_size, map_file_path,
                                           picked_hero)

        path_finder.set_grid(map_data.game_state.pathfinder_wall_grid)

        game_state = map_data.game_state
        game_engine = GameEngine(game_state, self.ui_view.info_message)
        game_state.player_state.exp_was_updated.register_observer(
            self.ui_view.on_player_exp_updated)
        game_state.player_state.talents_were_updated.register_observer(
            self.ui_view.on_talents_updated)
        game_state.player_state.notify_talent_observers(
        )  # Must notify the initial state
        game_state.player_movement_speed_was_updated.register_observer(
            self.ui_view.on_player_movement_speed_updated)
        game_state.notify_movement_speed_observers(
        )  # Must notify the initial state
        game_state.player_state.stats_were_updated.register_observer(
            self.ui_view.on_player_stats_updated)
        game_state.player_state.notify_stats_observers(
        )  # Must notify the initial state
        game_engine.talent_was_unlocked.register_observer(
            self.ui_view.on_talent_was_unlocked)
        game_engine.ability_was_clicked.register_observer(
            self.ui_view.on_ability_was_clicked)
        game_engine.consumable_was_clicked.register_observer(
            self.ui_view.on_consumable_was_clicked)
        game_state.player_state.money_was_updated.register_observer(
            self.ui_view.on_money_updated)
        game_state.player_state.notify_money_observers(
        )  # Must notify the initial state
        game_state.player_state.abilities_were_updated.register_observer(
            self.ui_view.on_abilities_updated)
        game_state.player_state.notify_ability_observers(
        )  # Must notify the initial state
        game_state.player_state.cooldowns_were_updated.register_observer(
            self.ui_view.on_cooldowns_updated)
        game_state.player_state.health_resource.value_was_updated.register_observer(
            self.ui_view.on_health_updated)
        game_state.player_state.mana_resource.value_was_updated.register_observer(
            self.ui_view.on_mana_updated)
        game_state.player_state.buffs_were_updated.register_observer(
            self.ui_view.on_buffs_updated)
        game_state.player_state.quests_were_updated.register_observer(
            self.ui_view.on_player_quests_updated)
        game_state.player_entity.movement_changed = Observable()
        game_state.player_entity.movement_changed.register_observer(
            play_or_stop_footstep_sounds)
        game_state.player_entity.position_changed = Observable()
        game_state.player_entity.position_changed.register_observer(
            self.ui_view.on_player_position_updated)
        game_state.player_entity.position_changed.register_observer(
            lambda _: self.ui_view.on_walls_seen([
                w.get_position()
                for w in game_state.get_walls_in_sight_of_player()
            ]))
        self.ui_view.on_world_area_updated(game_state.entire_world_area)
        # Must center camera before notifying player position as it affects which walls are shown on the minimap
        game_state.center_camera_on_player()
        game_state.player_entity.notify_position_observers(
        )  # Must notify the initial state

        if map_file_path == 'resources/maps/challenge.json':
            world_behavior = ChallengeBehavior(self.picking_hero_scene,
                                               self.challenge_complete_scene,
                                               game_state,
                                               self.ui_view.info_message,
                                               game_engine, self.flags)
        else:
            world_behavior = StoryBehavior(self.victory_screen_scene,
                                           game_state,
                                           self.ui_view.info_message)

        if saved_player_state:
            game_engine.gain_levels(saved_player_state.level - 1)
            game_state.player_state.gain_exp(saved_player_state.exp)
            game_engine.set_item_inventory([
                ItemType[item] if item else None
                for item in saved_player_state.items
            ])
            game_state.player_state.consumable_inventory = ConsumableInventory(
                {
                    int(slot_number): [ConsumableType[c] for c in consumables]
                    for (slot_number, consumables
                         ) in saved_player_state.consumables_in_slots.items()
                })
            game_state.player_state.modify_money(saved_player_state.money)
            for portal in game_state.portals:
                if portal.portal_id.name in saved_player_state.enabled_portals:
                    sprite = saved_player_state.enabled_portals[
                        portal.portal_id.name]
                    portal.activate(Sprite[sprite])
            for tier_index, option_index in enumerate(
                    saved_player_state.talent_tier_choices):
                if option_index is not None:
                    pick_talent(game_state, tier_index, option_index)
            for completed_quest in saved_player_state.completed_quests:
                quest = get_quest(QuestId[completed_quest])
                game_state.player_state.start_quest(quest)
                game_state.player_state.complete_quest(quest)
            for active_quest in saved_player_state.active_quests:
                quest = get_quest(QuestId[active_quest])
                game_state.player_state.start_quest(quest)
        else:
            if hero_start_level > 1:
                game_engine.gain_levels(hero_start_level - 1)
            if start_money > 0:
                game_state.player_state.modify_money(start_money)

        game_state.player_state.item_inventory.was_updated.register_observer(
            self.ui_view.on_inventory_updated)
        game_state.player_state.item_inventory.notify_observers(
        )  # Must notify the initial state
        game_state.player_state.consumable_inventory.was_updated.register_observer(
            self.ui_view.on_consumables_updated)
        game_state.player_state.consumable_inventory.notify_observers(
        )  # Must notify the initial state
        self.ui_view.update_hero(game_state.player_state.hero_id)

        # When loading from a savefile a bunch of messages are generated (levelup, learning talents, etc), but they
        # are irrelevant, since we're loading an exiting character
        self.ui_view.info_message.clear_messages()

        # Talent toggle is highlighted when new talents are unlocked, but we don't want it to be highlighted on startup
        # when loading from a savefile
        self.ui_view.remove_highlight_from_talent_toggle()

        allocate_input_keys_for_abilities(game_state.player_state.abilities)

        new_hero_was_created = saved_player_state is None
        playing_scene = self.playing_scene(game_state, game_engine,
                                           world_behavior, self.ui_view,
                                           new_hero_was_created,
                                           character_file,
                                           total_time_played_on_character)
        return SceneTransition(playing_scene)
Ejemplo n.º 10
0
 def handle_user_input(self,
                       events: List[Any]) -> Optional[SceneTransition]:
     for event in events:
         if event.type == pygame.KEYDOWN:
             if event.key == pygame.K_RETURN:
                 return SceneTransition(self.playing_scene)
Ejemplo n.º 11
0
 def _transition_out_of_dungeon(self):
     scene = self.scene_factory.switching_game_world(
         self.game_engine, self.character_file,
         self.total_time_played_on_character,
         self._recreate_main_world_engine_and_behavior)
     return SceneTransition(scene)
    def run_one_frame(self, _time_passed: Millis) -> Optional[SceneTransition]:

        saved_player_state = self.flags.saved_player_state
        hero_start_level = self.flags.hero_start_level
        start_money = self.flags.start_money
        picked_hero = self.flags.picked_hero
        map_file_path = self.flags.map_file_path
        character_file = self.flags.character_file

        if saved_player_state:
            hero_from_saved_state = HeroId[saved_player_state.hero_id]
            if picked_hero is not None and picked_hero != hero_from_saved_state:
                raise Exception("Mismatch! Hero from saved state: " +
                                str(hero_from_saved_state) +
                                ", but picked hero: " + str(picked_hero))
            picked_hero = hero_from_saved_state

        total_time_played_on_character = saved_player_state.total_time_played_on_character if saved_player_state else 0

        ui_state = GameUiState()
        game_state = create_game_state_from_json_file(self.camera_size,
                                                      map_file_path,
                                                      picked_hero)
        game_engine = GameEngine(game_state, ui_state)
        game_state.player_state.exp_was_updated.register_observer(
            self.ui_view.on_player_exp_updated)
        game_state.player_state.talents_were_updated.register_observer(
            self.ui_view.on_talents_updated)
        game_state.player_state.notify_talent_observers(
        )  # Must notify the initial state
        game_state.player_movement_speed_was_updated.register_observer(
            self.ui_view.on_player_movement_speed_updated)
        game_state.notify_movement_speed_observers(
        )  # Must notify the initial state
        game_state.player_state.stats_were_updated.register_observer(
            self.ui_view.on_player_stats_updated)
        game_state.player_state.notify_stats_observers(
        )  # Must notify the initial state
        game_engine.talent_was_unlocked.register_observer(
            self.ui_view.on_talent_was_unlocked)
        game_state.player_state.money_was_updated.register_observer(
            self.ui_view.on_money_updated)
        game_state.player_state.notify_money_observers(
        )  # Must notify the initial state
        game_state.player_state.abilities_were_updated.register_observer(
            self.ui_view.on_abilities_updated)
        game_state.player_state.notify_ability_observers(
        )  # Must notify the initial state
        game_state.player_state.cooldowns_were_updated.register_observer(
            self.ui_view.on_cooldowns_updated)
        game_state.player_state.health_resource.value_was_updated.register_observer(
            self.ui_view.on_health_updated)
        game_state.player_state.mana_resource.value_was_updated.register_observer(
            self.ui_view.on_mana_updated)
        game_state.player_state.buffs_were_updated.register_observer(
            self.ui_view.on_buffs_updated)
        game_state.player_entity.movement_changed = Observable()
        game_state.player_entity.movement_changed.register_observer(
            play_or_stop_footstep_sounds)

        if map_file_path == 'resources/maps/challenge.json':
            world_behavior = ChallengeBehavior(self.picking_hero_scene,
                                               self.challenge_complete_scene,
                                               game_state, ui_state,
                                               game_engine, self.flags)
        else:
            world_behavior = StoryBehavior(self.victory_screen_scene,
                                           game_state, ui_state)

        if saved_player_state:
            game_engine.gain_levels(saved_player_state.level - 1)
            game_state.player_state.gain_exp(saved_player_state.exp)
            game_engine.set_item_inventory([
                ItemType[item] if item else None
                for item in saved_player_state.items
            ])
            game_state.player_state.consumable_inventory = ConsumableInventory(
                {
                    int(slot_number): [ConsumableType[c] for c in consumables]
                    for (slot_number, consumables
                         ) in saved_player_state.consumables_in_slots.items()
                })
            game_state.player_state.modify_money(saved_player_state.money)
            for portal in game_state.portals:
                if portal.portal_id.name in saved_player_state.enabled_portals:
                    sprite = saved_player_state.enabled_portals[
                        portal.portal_id.name]
                    portal.activate(Sprite[sprite])
            for tier_index, option_index in enumerate(
                    saved_player_state.talent_tier_choices):
                if option_index is not None:
                    pick_talent(game_state, tier_index, option_index)
        else:
            if hero_start_level > 1:
                game_engine.gain_levels(hero_start_level - 1)
            if start_money > 0:
                game_state.player_state.modify_money(start_money)

        game_state.player_state.item_inventory.was_updated.register_observer(
            self.ui_view.on_inventory_updated)
        game_state.player_state.item_inventory.notify_observers(
        )  # Must notify the initial state
        game_state.player_state.consumable_inventory.was_updated.register_observer(
            self.ui_view.on_consumables_updated)
        game_state.player_state.consumable_inventory.notify_observers(
        )  # Must notify the initial state
        self.ui_view.update_hero(game_state.player_state.hero_id)

        # When loading from a savefile a bunch of messages are generated (levelup, learning talents, etc), but they
        # are irrelevant, since we're loading an exiting character
        ui_state.clear_messages()

        # Talent toggle is highlighted when new talents are unlocked, but we don't want it to be highlighted on startup
        # when loading from a savefile
        self.ui_view.remove_highlight_from_talent_toggle()

        allocate_input_keys_for_abilities(game_state.player_state.abilities)

        new_hero_was_created = saved_player_state is None
        playing_scene = self.playing_scene(game_state, game_engine,
                                           world_behavior, ui_state,
                                           self.ui_view, new_hero_was_created,
                                           character_file,
                                           total_time_played_on_character)
        return SceneTransition(playing_scene)
Ejemplo n.º 13
0
    def handle_user_input(self,
                          events: List[Any]) -> Optional[SceneTransition]:

        transition_to_pause = False

        events_triggered_from_ui: List[EventTriggeredFromUi] = []

        # TODO handle dialog/no dialog more explicitly as states, and delegate more things to them (?)

        if self.ui_view.has_open_dialog():
            self.game_state.game_world.player_entity.set_not_moving()
            user_actions = get_dialog_actions(events)
            for action in user_actions:
                if isinstance(action, ActionChangeDialogOption):
                    npc_type, previous_index, new_index = self.ui_view.change_dialog_option(
                        action.index_delta)
                    self._handle_dialog_change_option(npc_type, previous_index,
                                                      new_index)
                if isinstance(action, ActionPressSpaceKey):
                    result = self.ui_view.handle_space_click()
                    if result:
                        npc_in_dialog, option_index = result
                        npc_type = npc_in_dialog.npc_type
                        blur_npc_action(npc_type, option_index,
                                        self.game_state, self.ui_view)
                        message = select_npc_action(npc_type, option_index,
                                                    self.game_engine)
                        if message:
                            self.ui_view.info_message.set_message(message)
                        npc_in_dialog.stun_status.remove_one()

                        # User may have been holding down a key when starting dialog, and then releasing it while in
                        # dialog. It's safer then to treat all keys as released when we exit the dialog.
                        self.user_input_handler.forget_held_down_keys()
                if isinstance(action, ActionMouseMovement):
                    self.ui_view.handle_mouse_movement_in_dialog(
                        action.mouse_screen_position)
                    # we handle "normal UI" mouse movement here primarily so that you can hover your equipment
                    # while in a dialog. (especially important when buying from an NPC)
                    self.ui_view.handle_mouse_movement(
                        action.mouse_screen_position)
                if isinstance(action, ActionMouseClicked):
                    result = self.ui_view.handle_mouse_click_in_dialog()
                    if result:
                        npc_type, previous_index, new_index = result
                        self._handle_dialog_change_option(
                            npc_type, previous_index, new_index)

        else:
            user_actions = self.user_input_handler.get_actions(events)
            for action in user_actions:
                if isinstance(action, ActionToggleRenderDebugging):
                    self.render_hit_and_collision_boxes = not self.render_hit_and_collision_boxes
                    # TODO: Handle this better than accessing a global variable from here
                    pythongame.core.pathfinding.npc_pathfinding.DEBUG_RENDER_PATHFINDING = \
                        not pythongame.core.pathfinding.npc_pathfinding.DEBUG_RENDER_PATHFINDING
                elif isinstance(action, ActionTryUseAbility):
                    self.game_engine.try_use_ability(action.ability_type)
                elif isinstance(action, ActionTryUsePotion):
                    self.game_engine.try_use_consumable(action.slot_number)
                elif isinstance(action, ActionMoveInDirection):
                    self.game_engine.move_in_direction(action.direction)
                elif isinstance(action, ActionStopMoving):
                    self.game_engine.stop_moving()
                elif isinstance(action, ActionPauseGame):
                    transition_to_pause = True
                elif isinstance(action, ActionMouseMovement):
                    self.ui_view.handle_mouse_movement(
                        action.mouse_screen_position)
                elif isinstance(action, ActionMouseClicked):
                    events_triggered_from_ui += self.ui_view.handle_mouse_click(
                    )
                elif isinstance(action, ActionMouseReleased):
                    events_triggered_from_ui += self.ui_view.handle_mouse_release(
                    )
                elif isinstance(action, ActionRightMouseClicked):
                    events_triggered_from_ui += self.ui_view.handle_mouse_right_click(
                    )
                elif isinstance(action, ActionPressSpaceKey):
                    ready_entity = self.player_interactions_state.get_entity_to_interact_with(
                    )
                    if ready_entity is not None:
                        if isinstance(ready_entity, NonPlayerCharacter):
                            ready_entity.world_entity.direction = get_directions_to_position(
                                ready_entity.world_entity,
                                self.game_state.game_world.player_entity.
                                get_center_position())[0]
                            ready_entity.world_entity.set_not_moving()
                            ready_entity.stun_status.add_one()
                            npc_type = ready_entity.npc_type
                            dialog_data = get_dialog_data(
                                npc_type, self.game_state)
                            option_index = self.ui_view.start_dialog_with_npc(
                                ready_entity, dialog_data)
                            play_sound(SoundId.DIALOG)
                            hover_npc_action(npc_type, option_index,
                                             self.game_state, self.ui_view)
                        elif isinstance(ready_entity, LootableOnGround):
                            self.game_engine.try_pick_up_loot_from_ground(
                                ready_entity)
                        elif isinstance(ready_entity, Portal):
                            self.game_engine.interact_with_portal(ready_entity)
                        elif isinstance(ready_entity, WarpPoint):
                            self.game_engine.use_warp_point(ready_entity)
                        elif isinstance(ready_entity, Chest):
                            self.game_engine.open_chest(ready_entity)
                        elif isinstance(ready_entity, Shrine):
                            self.game_engine.interact_with_shrine(ready_entity)
                        elif isinstance(ready_entity, DungeonEntrance):
                            has_key = self.game_state.player_state.item_inventory.has_item_in_inventory(
                                plain_item_id(ItemType.PORTAL_KEY))
                            if has_key:
                                entering_dungeon_scene = self.scene_factory.switching_game_world(
                                    self.game_engine, self.character_file,
                                    self.total_time_played_on_character,
                                    self._create_dungeon_engine_and_behavior)
                                return SceneTransition(entering_dungeon_scene)
                            else:
                                self.ui_view.info_message.set_message(
                                    "There is a keyhole on the side!")
                        else:
                            raise Exception("Unhandled entity: " +
                                            str(ready_entity))
                elif isinstance(action, ActionPressKey):
                    events_triggered_from_ui += self.ui_view.handle_key_press(
                        action.key)

        # TODO Much noise below around playing sounds. Perhaps game_engine should play the sounds in these cases?
        for event in events_triggered_from_ui:
            if isinstance(event, StartDraggingItemOrConsumable):
                play_sound(SoundId.UI_START_DRAGGING_ITEM)
            elif isinstance(event, DragItemBetweenInventorySlots):
                did_switch_succeed = self.game_engine.drag_item_between_inventory_slots(
                    event.from_slot, event.to_slot)
                if did_switch_succeed:
                    play_sound(SoundId.UI_ITEM_WAS_MOVED)
                else:
                    play_sound(SoundId.INVALID_ACTION)
            elif isinstance(event, DropItemOnGround):
                world_position = _get_mouse_world_pos(self.game_state,
                                                      event.screen_position)
                self.game_engine.drop_inventory_item_on_ground(
                    event.from_slot, world_position)
                play_sound(SoundId.UI_ITEM_WAS_DROPPED_ON_GROUND)
            elif isinstance(event, DragConsumableBetweenInventorySlots):
                self.game_engine.drag_consumable_between_inventory_slots(
                    event.from_slot, event.to_slot)
                play_sound(SoundId.UI_ITEM_WAS_MOVED)
            elif isinstance(event, DropConsumableOnGround):
                world_position = _get_mouse_world_pos(self.game_state,
                                                      event.screen_position)
                self.game_engine.drop_consumable_on_ground(
                    event.from_slot, world_position)
                play_sound(SoundId.UI_ITEM_WAS_DROPPED_ON_GROUND)
            elif isinstance(event, PickTalent):
                name_of_picked = pick_talent(self.game_state, event.tier_index,
                                             event.option_index)
                if not self.game_state.player_state.has_unpicked_talents():
                    self.ui_view.close_talent_window()
                self.ui_view.info_message.set_message("Talent picked: " +
                                                      name_of_picked)
                play_sound(SoundId.EVENT_PICKED_TALENT)
            elif isinstance(event, TrySwitchItemInInventory):
                did_switch_succeed = self.game_engine.try_switch_item_at_slot(
                    event.slot)
                if did_switch_succeed:
                    play_sound(SoundId.UI_ITEM_WAS_MOVED)
                else:
                    play_sound(SoundId.INVALID_ACTION)
            elif isinstance(event, ToggleSound):
                toggle_muted()
            elif isinstance(event, SaveGame):
                self._save_game()
            elif isinstance(event, ToggleFullscreen):
                self.toggle_fullscreen_callback()
            elif isinstance(event, ToggleWindow):
                play_sound(SoundId.UI_TOGGLE)
            else:
                raise Exception("Unhandled event: " + str(event))

        if transition_to_pause:
            return SceneTransition(
                PausedScene(self, self.world_view, self.ui_view,
                            self.game_state))