Exemple #1
0
def start_game(config):
    # Loads game data, setups first map of the game then runs the main game loop.

    # Load all game data.
    tiles_data, generation_data, actor_data, item_data, animation_data = load_data(
    )

    # Initialize map then generate a new map.
    current_map = Map(100, 100)
    start_x, start_y = generate_cave_map(current_map, generation_data,
                                         tiles_data, actor_data, item_data)

    # Initialize camera.
    camera = Camera(0, 0, config['camera_width'], config['camera_height'], 0,
                    0)

    # Spawn player.
    player_stats = {
        "hp": 100,
        "mp": 100,
        "starting_ap": 2,
        "max_ap": 10,
        "ap_recovery": 2,
        "base_damage": "1d4",
        "ac": 10,
        "hit": 4
    }
    player = Actor(start_x, start_y, 'Player', '@', [255, 255, 255, 255])
    player_inventory = Inventory(player)
    player.alive = Alive(player, player_stats, inventory=player_inventory)

    # Initialize FOV.
    fov = FOV(player, 5, current_map)

    under_mouse = None
    debug = False
    game_state = GameState.players_turn
    previous_state = None

    # Setup presets/containers for the game loop.
    actor_queue = PriorityQueue()
    actor_turns_left = False
    animations = []
    no_block_animations = []
    widgets = []
    targeting_action = None

    terminal.refresh()

    while True:
        terminal.clear()
        if not debug:
            if current_map.tiles[player.x][player.y].is_stairs:
                player.x, player.y = generate_cave_map(current_map,
                                                       generation_data,
                                                       tiles_data, actor_data,
                                                       item_data)
                current_map.depth += 1

            render_all(player, current_map, fov, camera, under_mouse,
                       animations, no_block_animations, widgets,
                       targeting_action, game_state, config, animation_data)

            # Parse player input.
            action = handle_input(player, current_map, camera, fov,
                                  under_mouse, widgets, targeting_action,
                                  animations, no_block_animations,
                                  animation_data, game_state)
            under_mouse = get_under_mouse(player, current_map.tiles,
                                          current_map.actors,
                                          current_map.items, widgets, camera,
                                          game_state)

            # If an action was returned, complete that action.
            if isinstance(action, str):
                if action == 'restart':
                    start_game(config)
                elif action == 'end-turn':
                    if player.alive.check_in_combat(current_map.actors, fov):
                        game_state = GameState.actors_turn
                elif action == 'toggle-inventory':
                    if game_state == GameState.show_inventory:
                        game_state = previous_state
                        widgets = []
                    else:
                        previous_state = game_state
                        game_state = GameState.show_inventory
                        fill_widgets(player, widgets, config, game_state)
                elif action == 'toggle-targeting':
                    game_state = previous_state
                    targeting_action = None
                elif action == 'toggle-map':
                    if game_state == GameState.show_full_map:
                        game_state = previous_state
                    else:
                        previous_state = game_state
                        game_state = GameState.show_full_map

            elif action:
                if len(animations) == 0:
                    if game_state == GameState.show_inventory:
                        game_state = previous_state
                        widgets = []
                        if action.item.targeting:
                            previous_state = game_state
                            game_state = GameState.targeting
                            targeting_action = action
                    elif game_state == GameState.targeting:
                        game_state = previous_state
                        targeting_action = None

                    if game_state == GameState.players_turn:
                        action.perform(animations, no_block_animations,
                                       animation_data)

            # Check if camera was moved, if it was, recalculate FOV.
            camera_moved = camera.move_camera(player.x, player.y, current_map)
            if camera_moved:
                fov.fov_recompute()

            # If player is in combat and out of ap, end the players turn.
            if player.alive.check_in_combat(current_map.actors, fov):
                if player.alive.get_ap(False) <= 0:
                    game_state = GameState.actors_turn

            # Only continue if all animations have finished.
            if len(animations) == 0:
                # Go through all actors and let them take turns until
                # they are out of ap or decide not to take any actions.
                if game_state == GameState.actors_turn:

                    # Fill the queue with actors that still need to take turns.
                    if actor_queue.empty():
                        for actor in current_map.actors:
                            if actor.alive and not actor.alive.turn_over and fov.in_fov(
                                    actor):
                                actor_queue.put(actor,
                                                actor.alive.get_ap(False))
                    else:
                        actor = actor_queue.get()
                        if actor.alive:
                            action = actor.alive.get_action(
                                player, current_map, fov)
                            if action:
                                action.perform(animations, no_block_animations,
                                               animation_data)
                                actor_turns_left = True
                            else:
                                actor.alive.turn_over = True

                    # Player recovers ap at the end of the actors turn.
                    if actor_queue.empty():
                        if not actor_turns_left:
                            player.alive.recover_ap()
                            game_state = GameState.players_turn
                            for actor in current_map.actors:
                                if actor.alive:
                                    actor.alive.turn_over = False
                        actor_turns_left = False
        else:
            debug_render(player, current_map)

            # Parse player input.
            action = handle_input(player, current_map, camera)
            if action == 'restart':
                start_game(config)
            if action == 'debug':
                debug = not debug
                terminal.set("window: size='40x20', cellsize='24x24'")

        terminal.refresh()