Пример #1
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))
Пример #2
0
 def _handle_dialog_change_option(self, npc_type: NpcType,
                                  previous_index: int, new_index: int):
     play_sound(SoundId.DIALOG)
     blur_npc_action(npc_type, previous_index, self.game_state,
                     self.ui_view)
     hover_npc_action(npc_type, new_index, self.game_state, self.ui_view)