Exemple #1
0
 def recompute_fov(self, fov_recompute):
     if fov_recompute:
         recompute_fov(self.fov_map, self.player.x, self.player.y,
                       self.fov_radius, self.constants['fov_light_walls'],
                       self.constants['fov_algorithm'])
         fov_recompute = False
     return fov_recompute
Exemple #2
0
    def init_game(self):
        libtcodconsole.default_fg = libtcod.white

        if self.fov_recompute:
            recompute_fov(self.fov_map, self.player.x, self.player.y)

        render_all(self.root_console, self.panel, self.entities, self.player,
                   self.game_map, self.fov_map, self.fov_recompute,
                   self.message_log, self.game_state)
        self.fov_recompute = False

        libtcod.console_flush()
Exemple #3
0
    def render_tick(self):
        if 'fov_recompute' in self.regulatory_flags:
            if self.player_location == PlayerLocations.WORLD_MAP:
                recompute_world_fov(self.fov_map, self.entities.player.x, self.entities.player.y)
            elif self.player_location == PlayerLocations.DUNGEON:
                recompute_fov(self.fov_map, self.entities.player.x, self.entities.player.y,
                                self.world_map.current_dungeon.map_creator.fov_radius)

        self.renderer.render_all(self)
        self.regulatory_flags.discard('fov_recompute')

        tcod.console_flush()
        self.renderer.clear_all(self.entities)
Exemple #4
0
    def take_turn(self, game_map, entities):
        results = []

        monster = self.owner

        # recalculate field of vision
        if self.fov_recompute:
            recompute_fov(self.fov_map, monster.x, monster.y, self.fov_radius,
                          fov_light_walls, fov_algorithm)
            self.fov_recompute = False

        # call function based on state
        func = self.statefuncs[self.aistate]
        results.extend(func(game_map, entities))

        return results
Exemple #5
0
def draw_cursor(mouse, cursor_radius, game_state, target_fov_map,
                fov_map_no_walls, screen_width, screen_height):

    #Checks to see that the item we are using has no radius so that we dont waste time computing a target reticule
    if cursor_radius == 1 or cursor_radius == None:
        cursor = libtcod.console_new(1, 1)
        libtcod.console_set_default_foreground(cursor, libtcod.white)
        cursor.draw_rect(0, 0, 1, 1, 0, bg=libtcod.white)
        libtcod.console_blit(cursor, 0, 0, 1, 1, 0, mouse.cx, mouse.cy, 1.0,
                             0.7)

    # If we have a radius greater than one then draw a circle with a radius of cursor_radius. Game state needs to be targetting, this makes it so when we cancel targetting our cursor goes back to normal
    elif game_state == GameStates.TARGETING:
        #I needed to add a buffer to the screen width otherwise the targeting reticule would wrap to the otehr side of the screen when it was on the left side.
        cursor = libtcod.console.Console(screen_width + 20, screen_height)
        libtcod.console_set_default_background(cursor, [245, 245, 245])
        libtcod.console_set_key_color(cursor, [245, 245, 245])
        cursor.draw_rect(0,
                         0,
                         screen_width,
                         screen_height,
                         0,
                         bg=[245, 245, 245])

        #Compute FOV from the cursors perspective. This makes it so walls etc. will block our reticule from showing green
        recompute_fov(target_fov_map,
                      mouse.cx,
                      mouse.cy,
                      cursor_radius,
                      light_walls=False,
                      algorithm=libtcod.FOV_RESTRICTIVE)

        #Check all coords within the target radius from our cursors
        for x in range(mouse.cx - cursor_radius, mouse.cx + cursor_radius + 1):
            for y in range(mouse.cy - cursor_radius,
                           mouse.cy + cursor_radius + 1):
                if math.sqrt((x - mouse.cx)**2 +
                             (y - mouse.cy)**2) <= cursor_radius:
                    #This FOV is computer from the player perspective, but with walls not lighting. This makes it so that if our cursors is on a wall the reticule will be red.
                    if not libtcod.map_is_in_fov(fov_map_no_walls, x, y):
                        cursor.draw_rect(x, y, 1, 1, 0, bg=libtcod.red)
                    #Check FOV of the cursors so that walls will block our reticule. If coordinate is in FOV we color it green.
                    elif libtcod.map_is_in_fov(target_fov_map, x, y):
                        cursor.draw_rect(x, y, 1, 1, 0, bg=libtcod.light_green)
                    else:
                        cursor.draw_rect(x, y, 1, 1, 0, bg=libtcod.red)
        libtcod.console_blit(cursor, 0, 0, 0, 0, 0, 0, 0, 0, 0.4)
Exemple #6
0
    def run_game(self):
        libtcodconsole.default_fg = libtcod.white

        if self.fov_recompute:
            recompute_fov(self.fov_map, self.player.x, self.player.y)

        render_all(self.root_console, self.panel, self.entities, self.player,
                   self.game_map, self.fov_map, self.fov_recompute,
                   self.message_log, self.game_state)
        self.fov_recompute = False

        libtcod.console_flush()
        if self.agent is None:
            action = {'pass': False}
            for event in libtcodevent.get():

                if event.type == "QUIT":
                    return
                if event.type == "KEYDOWN":
                    action = handle_keys(event.sym, self.game_state)
        else:
            if self.player.equipment.head is not None:
                head_name = self.player.equipment.head.name
            else:
                head_name = "Nothing"
            if self.player.equipment.body is not None:
                body_name = self.player.equipment.body.name
            else:
                body_name = "Nothing"
            if self.player.equipment.main_hand is not None:
                main_name = self.player.equipment.main_hand.name
            else:
                main_name = "Nothing"
            if self.player.equipment.off_hand is not None:
                off_name = self.player.equipment.off_hand.name
            else:
                off_name = "Nothing"

            print(
                "Head: {0}   Body: {1}   Main hand: {2}   Off hand: {3}   Coins: {4}"
                .format(head_name, body_name, main_name, off_name,
                        self.player.coin_pouch.get_amount()))
            action = self.agent.get_action()

        self.handle_action(action)
Exemple #7
0
def render_refresh(con, panel, mouse, entities, player, game_map, fov_map,
                   fov_recompute, message_log, constants, game_state,
                   names_list, colors_list):
    if fov_recompute:
        recompute_fov(fov_map, player.x, player.y, constants['fov_radius'],
                      constants['fov_light_walls'], constants['fov_algorithm'])

    render_all(con, panel, entities, player, game_map, fov_map, fov_recompute,
               message_log, constants['screen_width'],
               constants['screen_height'], constants['bar_width'],
               constants['panel_height'], constants['panel_y'], mouse,
               constants['colors'], constants['options_tutorial_enabled'],
               game_state, names_list, colors_list, constants['tick'],
               constants['tick_speed'])

    libtcod.console_flush()

    clear_all(con, entities)
Exemple #8
0
def play_game(player, entities, game_map, message_log, game_state, con, panel, constants):
    fov_recompute = True

    fov_map = initialize_fov(game_map)

    game_state = GameStates.PLAYERS_TURN
    previous_game_state = game_state

    targeting_item = None

    while not libtcod.console_is_window_closed():
        libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse)

        if fov_recompute:
            message_log.add_message(Message('MESSAGE SCROLLING', libtcod.black))  # message log scrolling
            recompute_fov(fov_map, player.x, player.y, constants['fov_radius'], constants['fov_light_walls'],
                          constants['fov_algorithm'])

        dead_check = player.fighter.hp
        if dead_check <= 0:
            message, game_state = kill_player(player)

        render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log,
                   constants['screen_width'], constants['screen_height'], constants['bar_width'],
                   constants['panel_height'], constants['panel_y'], key,mouse, constants['colors'], game_state)

        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities)

        #Consume player actions
        action,entities,fov_map,fov_recompute,game_map,game_state,message_log,mouse_action,player,player_turn_results,previous_game_state,exit_pressed = consume_actions(key,mouse,game_state,player,game_map, entities,fov_recompute,fov_map,message_log,constants,con,targeting_item,previous_game_state)
        if exit_pressed:
            return True

        #Consume action results
        for player_turn_result in player_turn_results:
            available_results,message_log,message,game_state,entities,player,game_state,targeting_item, previous_game_state = consume_results(player_turn_result,message_log,entities,player,game_state,targeting_item, previous_game_state)

        #consume NPC actions
        player,message_log,game_state = handle_npc_turn(game_state,player,entities,fov_map,game_map,message_log)
Exemple #9
0
def cast_fireball(*args, **kwargs):
    entities = kwargs.get('entities')
    fov_map = kwargs.get('fov_map')
    target_fov_map = kwargs.get('target_fov_map')
    damage = kwargs.get('damage')
    radius = kwargs.get('radius')
    target_x = kwargs.get('target_x')
    target_y = kwargs.get('target_y')

    results = []

    if not libtcod.map_is_in_fov(fov_map, target_x, target_y):
        results.append({
            'consumed':
            False,
            'message':
            Message('You cannot target a tile outside of your view.',
                    libtcod.yellow)
        })
        return results

    results.append({
        'consumed':
        True,
        'message':
        Message(
            'The fireball explodes, burning everything within {0} tiles!'.
            format(radius), libtcod.orange)
    })

    for entity in entities:
        if entity.distance(target_x, target_y) <= radius and entity.fighter:
            recompute_fov(target_fov_map, target_x, target_y, radius)
            if libtcod.map_is_in_fov(target_fov_map, entity.x, entity.y):
                results.append({
                    'message':
                    Message(
                        'The {0} gets burned for {1} hit points'.format(
                            entity.name, damage), libtcod.orange)
                })
                results.extend(entity.fighter.take_damage(damage))

    return results
Exemple #10
0
def rendering_proc(player,
                   entities,
                   game_map,
                   message_log,
                   game_state,
                   con,
                   panel,
                   constants,
                   fov_map,
                   mouse,
                   fov_recompute=False):
    if fov_recompute:
        recompute_fov(fov_map, player.x, player.y, constants['fov_radius'],
                      constants['fov_light_walls'], constants['fov_algorithm'])
    render_all(con, panel, entities, player, game_map, fov_map, fov_recompute,
               message_log, constants['screen_width'],
               constants['screen_height'], constants['bar_width'],
               constants['panel_height'], constants['panel_y'],
               constants['colors'], game_state, mouse)
    fov_recompute = False
    libtcod.console_flush()
    clear_all(con, entities)
def main():
    screen_width = 80
    screen_height = 50
    map_width = 80
    map_height = 45

    room_max_size = 10
    room_min_size = 6
    max_rooms = 30

    fov_algorithm = 0
    fov_light_walls = True
    fov_radius = 10

    max_monsters_per_room = 3

    colors = {
        "dark_wall": libtcod.Color(0, 0, 100),
        "dark_ground": libtcod.Color(50, 50, 150),
        "light_wall": libtcod.Color(130, 110, 50),
        "light_ground": libtcod.Color(200, 180, 50),
    }

    player = Entity(0, 0, "@", libtcod.white, "Player", blocks=True)
    entities = [player]

    libtcod.console_set_custom_font(
        "arial10x10.png",
        libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD,
    )

    libtcod.console_init_root(
        screen_width, screen_height, "libtcod tutorial revisited", False
    )

    con = libtcod.console_new(screen_width, screen_height)

    game_map = GameMap(map_width, map_height)
    game_map.make_map(
        max_rooms,
        room_min_size,
        room_max_size,
        map_width,
        map_height,
        player,
        entities,
        max_monsters_per_room,
    )

    fov_recompute = True

    fov_map = initialize_fov(game_map)

    key = libtcod.Key()
    mouse = libtcod.Mouse()

    game_state = GameStates.PLAYERS_TURN

    while not libtcod.console_is_window_closed():
        libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse)

        if fov_recompute:
            recompute_fov(
                fov_map,
                player.x,
                player.y,
                fov_radius,
                fov_light_walls,
                fov_algorithm,
            )

        render_all(
            con,
            entities,
            game_map,
            fov_map,
            fov_recompute,
            screen_width,
            screen_height,
            colors,
        )

        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities)

        action = handle_keys(key)

        move = action.get("move")
        leave = action.get("exit")
        fullscreen = action.get("fullscreen")

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move

            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y
                )

                if target:
                    print(
                        f"you kick the {target.name} in the shins, much to its annoyance!"
                    )
                else:
                    player.move(dx, dy)
                    fov_recompute = True

                game_state = GameStates.ENEMY_TURN

        if leave:
            return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity != player:
                    print(
                        f"The {entity.name} ponders the meaning of its existence"
                    )

            game_state = GameStates.PLAYERS_TURN
def main():
    screen_width = 80
    screen_height = 50
    bar_width = 20
    panel_height = 7
    panel_y = screen_height - panel_height
    message_x = bar_width + 2
    message_width = screen_width - bar_width - 2
    message_height = panel_height - 1
    map_width = 80
    map_height = 43

    room_max_size = 10
    room_min_size = 6
    max_rooms = 30

    fov_algorithm = 0
    fov_light_walls = True
    fov_radius = 10

    max_monsters_per_room = 3
    max_items_per_room = 2

    colors = {
        'dark_wall' : libtcod.Color(0, 0, 100),
        'dark_ground' : libtcod.Color(50, 50, 150),
        'light_wall' : libtcod.Color(130, 110, 50),
        'light_ground' : libtcod.Color(200, 180, 50)
    }

    fighter_component = Fighter(hp=30, defense=2, power=5)
    inventory_component = Inventory(26)

    player = Entity(0, 0, '@', libtcod.white, 'Player', blocks=True, render_order=RenderOrder.ACTOR,
                    fighter=fighter_component, inventory=inventory_component)
    entities = [player]

    libtcod.console_set_custom_font('arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)

    libtcod.console_init_root(screen_width, screen_height, 'libtcod tutorial revised', False)

    con = libtcod.console_new(screen_width, screen_height)
    panel = libtcod.console_new(screen_width, panel_height)

    game_map = GameMap(map_width, map_height)
    game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, max_monsters_per_room, max_items_per_room)

    fov_recompute = True
    fov_map = initialize_fov(game_map)
    message_log = MessageLog(message_x, message_width, message_height)

    key = libtcod.Key()
    mouse = libtcod.Mouse()

    game_state = GameStates.PLAYERS_TURN
    previous_game_state =  game_state

    while not libtcod.console_is_window_closed():
        libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse)
        if fov_recompute:
            recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm)
        render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log, screen_width, screen_height,
                   bar_width, panel_height, panel_y, mouse, colors, game_state)
        fov_recompute = False
        libtcod.console_flush()
        clear_all(con, entities)

        action = handle_keys(key, game_state)

        move = action.get('move')
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        inventory_index = action.get('inventory_index')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')

        player_turn_results = []

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(entities, destination_x, destination_y)

                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)
                    
                    fov_recompute = True
                
                game_state = GameStates.ENEMY_TURN
        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)
                    break
            else:
                message_log.add_message(Message('There is nothing to pickup here.', libtcod.yellow))

        if show_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
            player.inventory.items):
            item = player.inventory.items[inventory_index]

            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(player.inventory.use(item))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(player.inventory.drop_item(item))
        if exit:
            if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY):
                game_state = previous_game_state
            else:
                return True
        
        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            item_consumed = player_turn_result.get('consumed')
            item_dropped = player_turn_result.get('item_dropped')

            if message:
                message_log.add_message(message)

            if dead_entity:
                if dead_entity == player:
                    message, game_state = kill_player(dead_entity)
                else:
                    message = kill_monster(dead_entity)

                message_log.add_message(message)

            if item_added:
                entities.remove(item_added)
                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                game_state = GameStates.ENEMY_TURN

            if item_dropped:
                entities.append(item_dropped)
                game_state = GameStates.ENEMY_TURN

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(player, fov_map, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)
                        
                        if dead_entity:
                            if dead_entity == player:
                                message, game_state = kill_player(dead_entity)
                            else:
                                message = kill_monster(dead_entity)

                            message_log.add_message(message)

                        if game_state == GameStates.PLAYER_DEAD:
                            break
                    
                    if game_state == GameStates.PLAYER_DEAD:
                        break

            else:
                game_state = GameStates.PLAYERS_TURN
Exemple #13
0
def play_game(player, entities, game_map, message_log, game_state, con, panel,
              constants):
    fov_recompute = True

    fov_map = initialize_fov(game_map)

    key = libtcod.Key()
    mouse = libtcod.Mouse()

    game_state = GameStates.PLAYERS_TURN
    previous_game_state = game_state

    targeting_item = None

    while not libtcod.console_is_window_closed():
        libtcod.sys_check_for_event(
            libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse)

        if fov_recompute:
            recompute_fov(fov_map, player.x, player.y, constants['fov_radius'],
                          constants['fov_light_walls'],
                          constants['fov_algorithm'])

        render_all(con, panel, entities, player, game_map, fov_map,
                   fov_recompute, message_log, constants['screen_width'],
                   constants['screen_height'], constants['bar_width'],
                   constants['panel_height'], constants['panel_y'], mouse,
                   constants['colors'], game_state)

        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities)

        action = handle_keys(key, game_state)
        mouse_action = handle_mouse(mouse)

        move = action.get('move')
        wait = action.get('wait')
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        inventory_index = action.get('inventory_index')
        take_stairs = action.get('take_stairs')
        level_up = action.get('level_up')
        show_character_screen = action.get('show_character_screen')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')

        left_click = mouse_action.get('left_click')
        right_click = mouse_action.get('right_click')

        player_turn_results = []

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)

                    fov_recompute = True

                game_state = GameStates.ENEMY_TURN

        elif wait:
            game_state = GameStates.ENEMY_TURN

        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)

                    break
            else:
                message_log.add_message(
                    Message('There is nothing here to pick up.',
                            libtcod.yellow))

        if show_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                player.inventory.items):
            item = player.inventory.items[inventory_index]

            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(
                    player.inventory.use(item,
                                         entities=entities,
                                         fov_map=fov_map))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(player.inventory.drop_item(item))

        if take_stairs and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.stairs and entity.x == player.x and entity.y == player.y:
                    entities = game_map.next_floor(player, message_log,
                                                   constants)
                    fov_map = initialize_fov(game_map)
                    fov_recompute = True
                    libtcod.console_clear(con)

                    break
            else:
                message_log.add_message(
                    Message('There are no stairs here.', libtcod.yellow))

        if level_up:
            if level_up == 'hp':
                player.fighter.base_max_hp += 20
                player.fighter.hp += 20
            elif level_up == 'str':
                player.fighter.base_power += 1
            elif level_up == 'def':
                player.fighter.base_defense += 1

            game_state = previous_game_state

        if show_character_screen:
            previous_game_state = game_state
            game_state = GameStates.CHARACTER_SCREEN

        if game_state == GameStates.TARGETING:
            if left_click:
                target_x, target_y = left_click

                item_use_results = player.inventory.use(targeting_item,
                                                        entities=entities,
                                                        fov_map=fov_map,
                                                        target_x=target_x,
                                                        target_y=target_y)
                player_turn_results.extend(item_use_results)
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})

        if exit:
            if game_state in (GameStates.SHOW_INVENTORY,
                              GameStates.DROP_INVENTORY,
                              GameStates.CHARACTER_SCREEN):
                game_state = previous_game_state
            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
            else:
                save_game(player, entities, game_map, message_log, game_state)

                return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            item_consumed = player_turn_result.get('consumed')
            item_dropped = player_turn_result.get('item_dropped')
            equip = player_turn_result.get('equip')
            targeting = player_turn_result.get('targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')
            xp = player_turn_result.get('xp')

            if message:
                message_log.add_message(message)

            if dead_entity:
                if dead_entity == player:
                    message, game_state = kill_player(dead_entity)
                else:
                    message = kill_monster(dead_entity)

                message_log.add_message(message)

            if item_added:
                entities.remove(item_added)

                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                game_state = GameStates.ENEMY_TURN

            if item_dropped:
                entities.append(item_dropped)

                game_state = GameStates.ENEMY_TURN

            if equip:
                equip_results = player.equipment.toggle_equip(equip)

                for equip_result in equip_results:
                    equipped = equip_result.get('equipped')
                    dequipped = equip_result.get('dequipped')

                    if equipped:
                        message_log.add_message(
                            Message('You equipped the {0}'.format(
                                equipped.name)))

                    if dequipped:
                        message_log.add_message(
                            Message('You dequipped the {0}'.format(
                                dequipped.name)))

                game_state = GameStates.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING

                targeting_item = targeting

                message_log.add_message(targeting_item.item.targeting_message)

            if targeting_cancelled:
                game_state = previous_game_state

                message_log.add_message(Message('Targeting cancelled'))

            if xp:
                leveled_up = player.level.add_xp(xp)
                message_log.add_message(
                    Message('You gain {0} experience points.'.format(xp)))

                if leveled_up:

                    previous_game_state = game_state
                    game_state = GameStates.LEVEL_UP

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(
                        player, fov_map, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

                        if dead_entity:
                            if dead_entity == player:
                                message, game_state = kill_player(dead_entity)
                            else:
                                message = kill_monster(dead_entity)

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break

                    if game_state == GameStates.PLAYER_DEAD:
                        break
            else:
                game_state = GameStates.PLAYERS_TURN
Exemple #14
0
def main():
    """ Main game function """
    fighter_component = Fighter(hp=30, defense=2, power=5)
    player = Entity(0,
                    0,
                    '@',
                    tcod.white,
                    'Player',
                    blocks=True,
                    render_order=RenderOrder.ACTOR,
                    fighter=fighter_component)
    entities = [player]

    # Import font
    tcod.console_set_custom_font(
        FONT, tcod.FONT_TYPE_GREYSCALE | tcod.FONT_LAYOUT_TCOD)

    # Console initialization
    tcod.console_init_root(screen_width,
                           screen_height,
                           'Pilferer %s' % VERSION,
                           False,
                           vsync=False)
    con = tcod.console.Console(screen_width, screen_height)

    # Mapping
    game_map = GameMap(map_width, map_height)
    game_map.make_map(max_rooms, room_min_size, room_max_size, map_width,
                      map_height, player, entities, max_monsters_per_room)

    # FOV
    fov_recompute = True
    fov_map = initialize_fov(game_map)

    # Variables for holding input
    key = tcod.Key()
    mouse = tcod.Mouse()

    # Game state
    game_state = GameStates.PLAYERS_TURN

    # Main game loop
    while not tcod.console_is_window_closed():
        # FOV
        if fov_recompute:
            recompute_fov(fov_map, player.x, player.y, fov_radius,
                          fov_light_walls, fov_algorithm)

        # Draw
        render_all(con, entities, player, game_map, fov_map, fov_recompute,
                   screen_width, screen_height, colors)
        fov_recompute = False
        tcod.console_flush()
        clear_all(con, entities)

        # INDPUT HANDLING
        tcod.sys_check_for_event(tcod.EVENT_KEY_PRESS, key, mouse)
        action = handle_keys(key)

        # Command move
        player_turn_results = []
        move = action.get('move')
        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy
            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entity_at_location(
                    entities, destination_x, destination_y)
                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)
                    fov_recompute = True
                game_state = GameStates.ENEMY_TURN

        # Command exit
        exit = action.get('exit')
        if exit:
            return True

        # Command Fullscreen
        fullscreen = action.get('fullscreen')
        if fullscreen:
            tcod.console_set_fullscreen(not tcod.console_is_fullscreen())

        # Results
        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')

            if message:
                print(message)

            if dead_entity:
                if dead_entity == player:
                    message, game_state = kill_player(dead_entity)
                else:
                    message = kill_monster(dead_entity)

                print(message)

        # Monster turns
        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(
                        player, fov_map, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            print(message)

                        if dead_entity:
                            if dead_entity == player:
                                message, game_state = kill_player(dead_entity)
                            else:
                                message = kill_monster(dead_entity)

                            print(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break

                    if game_state == GameStates.PLAYER_DEAD:
                        break

            else:
                game_state = GameStates.PLAYERS_TURN

            game_state = GameStates.PLAYERS_TURN
def main():
    screen_width = 80
    screen_height = 50
    map_width = 80
    map_height = 45

    room_max_size = 10
    room_min_size = 6
    max_rooms = 30

    fov_algorithm = 0
    fov_light_walls = True
    fov_radius = 10

    colours = {
        'dark_wall': libtcod.Color(0, 0, 100),
        'dark_ground': libtcod.Color(50, 50, 150),
        'light_wall': libtcod.Color(130, 110, 50),
        'light_ground': libtcod.Color(200, 180, 50)
    }

    player = Entity(int(screen_width / 2), int(screen_height / 2), '@',
                    libtcod.white)
    npc = Entity(int(screen_width / 2 - 5), int(screen_height / 2), '@',
                 libtcod.yellow)
    entities = [npc, player]

    libtcod.console_set_custom_font(
        'arial10x10.png',
        libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)

    libtcod.console_init_root(screen_width, screen_height,
                              'libtcod tutorial revised', False)

    con = libtcod.console_new(screen_width, screen_height)

    game_map = GameMap(map_width, map_height)
    game_map.make_map(max_rooms, room_min_size, room_max_size, map_width,
                      map_height, player)

    fov_recompute = True

    fov_map = initialise_fov(game_map)

    key = libtcod.Key()
    mouse = libtcod.Mouse()

    while not libtcod.console_is_window_closed():
        libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse)

        if fov_recompute:
            recompute_fov(fov_map, player.x, player.y, fov_radius)

        render_all(con, entities, game_map, fov_map, fov_recompute,
                   screen_width, screen_height, colours)

        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities)

        action = handle_keys(key)

        move = action.get('move')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')

        if move:
            dx, dy = move
            if not game_map.is_blocked(player.x + dx, player.y + dy):
                player.move(dx, dy)

                fov_recompute = True

        if exit:
            return True

        if fullscreen:
            return True
Exemple #16
0
def main():
    screen_width = 80
    screen_height = 50
    map_width = 80
    map_height = 45
    room_max_size = 10
    room_min_size = 6
    max_rooms = 30
    max_monsters_per_room = 3

    fov_algorithm = 0
    fov_light_walls = True
    fov_radius = 10

    colors = {
        'dark_wall': libtcod.Color(0, 0, 100),
        'dark_ground': libtcod.Color(50, 50, 150),
        'light_wall': libtcod.Color(130, 110, 50),
        'light_ground': libtcod.Color(200, 180, 50)
    }

    player = Entity(0, 0, '@', libtcod.white, 'Player', blocks=True)
    entities = [player]

    libtcod.console_set_custom_font(
        'arial10x10.png',
        libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)
    libtcod.console_init_root(screen_width, screen_height, 'RogueLike', False)

    con = libtcod.console_new(screen_width, screen_height)
    game_map = GameMap(map_width, map_height)
    game_map.make_map(max_rooms, room_min_size, room_max_size, map_width,
                      map_height, player, entities, max_monsters_per_room)

    fov_recompute = True
    fov_map = initialize_fov(game_map)

    key = libtcod.Key()
    mouse = libtcod.Mouse()

    game_state = GameStates.PLAYERS_TURN

    while not libtcod.console_is_window_closed():
        libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse)

        if fov_recompute:
            recompute_fov(fov_map, player.x, player.y, fov_radius,
                          fov_light_walls, fov_algorithm)

        render_all(con, entities, game_map, fov_map, fov_recompute,
                   screen_width, screen_height, colors)

        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities)

        action = handle_keys(key)

        move = action.get('move')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move

            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target:
                    print('You kick the ' + target.name +
                          ' in thr shins, much to its annoyance!')
                else:
                    player.move(dx, dy)
                    fov_recompute = True

                game_state = GameStates.ENEMY_TURN

        if exit:
            return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity != player:
                    print('The ' + entity.name +
                          ' ponders the meaning of its existence')

            game_state = GameStates.PLAYERS_TURN
Exemple #17
0
def play_game(con, player, entities, animator: Animator, turn_count: int,
              game_map: GameMap, message_log, game_state, panel, constants):
    target_x, target_y = player.x, player.y
    targeting_item = None
    target_entity = None

    while True:
        fov_algorithm = 2
        fov_light_walls = True
        fov_radius = 20
        fov_recompute = True
        fov_map = initialize_fov(game_map)

        if fov_recompute:
            recompute_fov(fov_map, player.x, player.y, fov_radius,
                          fov_light_walls, fov_algorithm)

        render_all(con, panel, entities, animator, player, game_map, fov_map,
                   fov_recompute, message_log, constants['screen_width'],
                   constants['screen_height'], constants['bar_width'],
                   constants['panel_height'], constants['panel_y'], game_state,
                   target_x, target_y, target_entity, turn_count)

        tcod.console_flush()

        clear_all(con, entities)

        player_turn_results = []

        animator.advance_frame()

        # Handle Game State
        if game_state == GameStates.ENEMY_TURN:
            turn_count += 1

            # Generate path map with all static tiles (ignore entities for now)
            path_map = generate_path_map(game_map,
                                         entities=None,
                                         player=player)

            for entity in entities:
                if entity.ai and entity.ai != Player:
                    recompute_walkable(fov_map, game_map, entities, entity)
                    entity_turn_results = entity.ai.take_turn(
                        player, fov_map, game_map, entities, path_map)

                    for entity_turn_result in entity_turn_results:
                        message = entity_turn_result.get('message')
                        dead_entity = entity_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

                        if dead_entity:
                            if dead_entity == player:
                                message, game_state = kill_player(player)
                            else:
                                message = kill_entity(dead_entity)

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break

                    if game_state == GameStates.PLAYER_DEAD:
                        break
            else:
                game_state = GameStates.PLAYER_TURN

        # Handle Events
        for event in tcod.event.wait():
            if event.type == "QUIT":
                save_game(player, entities, animator, turn_count, game_map,
                          message_log, game_state)
                raise SystemExit()

            if event.type == "KEYDOWN":
                action: [Action, None] = handle_keys(event.sym, game_state)

                if action is None:
                    continue

                action_type: ActionType = action.action_type

                if action_type == ActionType.EXECUTE:
                    if game_state == GameStates.TARGETING:
                        item_use_results = player.body.use_selected_appendage(
                            entities=entities,
                            fov_map=fov_map,
                            game_map=game_map,
                            target_x=target_x,
                            target_y=target_y)
                        player_turn_results.extend(item_use_results)
                        game_state = GameStates.ENEMY_TURN
                    elif game_state == GameStates.LOOKING:
                        look_results = []

                        looked_at_entities = get_entities_at_location(
                            entities, target_x, target_y)
                        if tcod.map_is_in_fov(fov_map, target_x, target_y):
                            if looked_at_entities:
                                for entity in looked_at_entities:
                                    look_results.extend(
                                        entity.get_description())
                                    target_entity = entity
                            else:
                                if game_map.tiles[target_x][target_y].blocked:
                                    look_results.append({
                                        'message':
                                        Message("You stare at the wall.")
                                    })
                                else:
                                    look_results.append({
                                        'message':
                                        Message("You stare into empty space.")
                                    })
                        else:
                            look_results.append({
                                'message':
                                Message("You can't see that far.")
                            })

                        game_state = GameStates.PLAYER_TURN
                        player_turn_results.extend(look_results)

                if action_type == ActionType.MOVEMENT:
                    dx: int = action.kwargs.get("dx", 0)
                    dy: int = action.kwargs.get("dy", 0)

                    # Player Movement
                    if game_state == GameStates.PLAYER_TURN:
                        destination_x = player.x + dx
                        destination_y = player.y + dy

                        tile_results = game_map.tiles[destination_x][
                            destination_y].overlap_entity(player)
                        player_turn_results.extend(tile_results)

                        if not game_map.is_blocked(destination_x,
                                                   destination_y):
                            target_appendage = get_blocking_entities_at_location(
                                entities, destination_x, destination_y)

                            if target_appendage:
                                if target_appendage.body:
                                    player_fighter = player.body.selected_appendage.fighter

                                    if player_fighter:
                                        target_entity = target_appendage
                                        game_state = GameStates.TARGET_APPENDAGE
                                    else:
                                        player_turn_results.append({
                                            'message':
                                            Message(
                                                "You cannot attack with your {0}."
                                                .format(
                                                    player.body.
                                                    selected_appendage.name),
                                                tcod.yellow)
                                        })
                                elif target_appendage.structure:
                                    structure_interact_results = target_appendage.structure.interact(
                                        player)
                                    player_turn_results.extend(
                                        structure_interact_results)
                            else:
                                player.move(dx, dy)
                        else:
                            player_turn_results.append({
                                'message':
                                Message("You slam yourself into the wall!",
                                        tcod.orange)
                            })

                        if game_state != GameStates.TARGET_APPENDAGE:
                            game_state = GameStates.ENEMY_TURN

                    # Targeting
                    elif game_state in (GameStates.TARGETING,
                                        GameStates.LOOKING):
                        new_x = target_x + dx
                        new_y = target_y + dy
                        if player.distance(new_x, new_y) < targeting_radius:
                            target_x = new_x
                            target_y = new_y

                elif action_type == ActionType.GRAB:
                    for entity in entities:
                        if entity.item and entity.x == player.x and entity.y == player.y:
                            pickup_result = player.body.grab_entity(entity)
                            player_turn_results.extend(pickup_result)
                            break
                    else:
                        player_turn_results.append({
                            'message':
                            Message('You grab at the air', tcod.yellow)
                        })

                    game_state = GameStates.ENEMY_TURN

                elif action_type == ActionType.LOOK:
                    game_state = GameStates.LOOKING
                    target_x, target_y = player.x, player.y
                    targeting_radius = 100

                elif action_type == ActionType.WAIT:
                    player_turn_results.append({
                        'message':
                        Message('You stare blankly into space', tcod.yellow)
                    })
                    game_state = GameStates.ENEMY_TURN

                elif action_type == ActionType.CHOOSE_OPTION:
                    option_index = action.kwargs.get("option_index", None)

                    if game_state == GameStates.SWAP_APPENDAGE:
                        if option_index < len(player.body.appendages):
                            item = player.body.appendages[option_index]
                            swap_results = player.body.select_appendage(item)
                            player_turn_results.extend(swap_results)
                            game_state = GameStates.PLAYER_TURN

                    elif game_state == GameStates.TARGET_APPENDAGE:
                        if option_index < len(target_entity.body.appendages):
                            target_appendage = target_entity.body.appendages[
                                option_index]
                            attack_results = player.body.selected_appendage.fighter.attack_appendage(
                                target_appendage)
                            player_turn_results.extend(attack_results)
                            game_state = GameStates.ENEMY_TURN

                elif action_type == ActionType.INTERACT:
                    for entity in entities:
                        if entity.structure and entity.x == player.x and entity.y == player.y:
                            interact_results = entity.structure.interact(
                                player)
                            player_turn_results.extend(interact_results)
                            break
                    else:
                        if game_state == GameStates.PLAYER_TURN:
                            activate_item_results = player.body.use_selected_appendage(
                                fov_map=fov_map,
                                game_map=game_map,
                                entities=entities)
                            if activate_item_results:
                                player_turn_results.extend(
                                    activate_item_results)
                                game_state = GameStates.ENEMY_TURN

                elif action_type == ActionType.DROP_INVENTORY_ITEM:
                    grabber = player.body.selected_appendage.grabber
                    if grabber:
                        player_turn_results.extend(grabber.drop())
                    # game_state = GameStates.DROP_INVENTORY

                elif action_type == ActionType.SWAP_APPENDAGE:
                    game_state = GameStates.SWAP_APPENDAGE

                elif action_type == ActionType.ESCAPE:
                    if game_state == GameStates.TARGETING:
                        game_state = GameStates.PLAYER_TURN
                    elif game_state == GameStates.PLAYER_TURN:
                        save_game(player, entities, animator, turn_count,
                                  game_map, message_log, game_state)
                        main()
                elif action_type == ActionType.RESTART:
                    main()

        # Process player turn results
        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            item_consumed = player_turn_result.get('consumed')
            item_dropped = player_turn_result.get('item_dropped')
            targeting = player_turn_result.get('targeting')
            next_floor = player_turn_result.get('next_floor')

            if message:
                message_log.add_message(message)

            if dead_entity:
                if dead_entity == player:
                    message, game_state = kill_player(player)
                else:
                    message_log.add_message(kill_entity(dead_entity))

            if item_added:
                entities.remove(item_added)
                game_state = GameStates.ENEMY_TURN

            if item_dropped:
                entities.append(item_dropped)

                game_state = GameStates.ENEMY_TURN

            if targeting:
                game_state = GameStates.TARGETING

                targeting_item = targeting
                targeting_radius = targeting.item.targeting_radius
                target_x = player.x
                target_y = player.y

                message_log.add_message(
                    Message("You begin aiming the {0}.".format(
                        targeting.name)))
                # TODO: Replace occurrences of add_message with player_turn_result approach
                # player_turn_results.append({'message': Message("You begin aiming the {0}.".format(targeting.name))})

            if next_floor:
                entities = game_map.next_floor(player, constants)
                fov_map = initialize_fov(game_map)
                tcod.console_clear(con)
Exemple #18
0
def play_game(player, entities, game_map, message_log, game_state, con, panel,
              constants):
    fov_recompute = True

    fov_map = initialize_fov(game_map)

    key = libtcod.Key()
    mouse = libtcod.Mouse()

    game_state = GameStates.PLAYERS_TURN
    previous_game_state = game_state

    targeting_item = None

    while not libtcod.console_is_window_closed():
        libtcod.sys_check_for_event(
            libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse)

        if fov_recompute:
            recompute_fov(fov_map, player.x, player.y, constants['fov_radius'],
                          constants['fov_light_walls'],
                          constants['fov_algorithm'])

        render_all(con, panel, entities, player, game_map, fov_map,
                   fov_recompute, message_log, constants['screen_width'],
                   constants['screen_height'], constants['bar_width'],
                   constants['panel_height'], constants['panel_y'], mouse,
                   constants['colors'], game_state)

        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities)

        action = handle_keys(key, game_state)
        mouse_action = handle_mouse(mouse)

        move = action.get('move')
        aim_weapon = action.get('aim_weapon')
        wait = action.get('wait')
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        inventory_index = action.get('inventory_index')
        take_stairs = action.get('take_stairs')
        show_character_screen = action.get('show_character_screen')
        exit = action.get('exit')
        level_up = action.get('level_up')
        fullscreen = action.get('fullscreen')
        exit_menu = action.get('exit_menu')

        left_click = mouse_action.get('left_click')
        right_click = mouse_action.get('right_click')

        player_turn_results = []

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if dx == 0 and dy == 0:
                    player.move(dx, dy)

                    fov_recompute = True
                elif target:  # ATTACK!

                    if player.equipment.power_bonus == 4:
                        attack_results = player.fighter.basic_bow_attack(
                            target)
                        player_turn_results.extend(attack_results)

                    else:
                        attack_results = player.fighter.attack(target)
                        player_turn_results.extend(attack_results)

                else:
                    player.move(dx, dy)

                    fov_recompute = True

                game_state = GameStates.ENEMY_TURN

        elif aim_weapon and game_state == GameStates.PLAYERS_TURN:  # ALSO ATTACK! Working on this at the moment
            if player.equipment.power_bonus == 4 and game_state == GameStates.PLAYERS_TURN:
                message_log.add_message(
                    Message(
                        'Left click a tile to fire at it or right click to cancel!',
                        libtcod.yellow))
                game_state = GameStates.AIMING
            else:
                message_log.add_message(
                    Message('You do not have a ranged weapon equipped!',
                            libtcod.yellow))

        elif wait:
            game_state = GameStates.ENEMY_TURN

        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)

                    break
            else:
                message_log.add_message(
                    Message('There is nothing here to pick up.',
                            libtcod.yellow))

        if show_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                player.inventory.items):
            item = player.inventory.items[inventory_index]

            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(
                    player.inventory.use(item,
                                         entities=entities,
                                         fov_map=fov_map))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(player.inventory.drop_item(item))

        if take_stairs and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.stairs and entity.x == player.x and entity.y == player.y:
                    entities = game_map.next_floor(player, message_log,
                                                   constants)
                    fov_map = initialize_fov(game_map)
                    fov_recompute = True
                    libtcod.console_clear(con)

                    break
            else:
                message_log.add_message(
                    Message('There are no stairs here.', libtcod.yellow))

        if level_up:
            if level_up == 'hp':
                player.fighter.base_max_hp += 20
                player.fighter.hp += 20
            elif level_up == 'str':
                player.fighter.base_power += 1
            elif level_up == 'def':
                player.fighter.base_defense += 1

            game_state = previous_game_state

        if show_character_screen:
            previous_game_state = game_state
            game_state = GameStates.CHARACTER_SCREEN

        if game_state == GameStates.TARGETING:
            if left_click:
                target_x, target_y = left_click

                item_use_results = player.inventory.use(targeting_item,
                                                        entities=entities,
                                                        fov_map=fov_map,
                                                        target_x=target_x,
                                                        target_y=target_y)
                player_turn_results.extend(item_use_results)
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})

        if game_state == GameStates.AIMING:
            if left_click:
                target_x, target_y = left_click
                coordinates = target_x, target_y  # OKAY NOW WHAT THE F**K I DONT UNDESTAND WHY THIS WORKS OR HOW THE
                # VARIABLES GET FROM HERE TO THE FUNCTION I NEED THEM I MEAN JESUS CHRIST I JUST WOUND UP WITH THIS
                # ARRANGEMENT BY F*****G AROUND I MEAN IT WORKS BUT SERIOUSLY I DONT UNDERSTAND WHY THIS WORKS
                player_turn_results.append({'fire_weapon': True})
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})

        if exit_menu:
            if game_state in (GameStates.SHOW_INVENTORY,
                              GameStates.DROP_INVENTORY,
                              GameStates.CHARACTER_SCREEN):
                game_state = previous_game_state
            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})

        if exit:
            save_game(player, entities, game_map, message_log, game_state)

            return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            fire_weapon = player_turn_result.get('fire_weapon')
            item_added = player_turn_result.get('item_added')
            item_consumed = player_turn_result.get('consumed')
            item_dropped = player_turn_result.get('item_dropped')
            equip = player_turn_result.get('equip')
            targeting = player_turn_result.get('targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')
            xp = player_turn_result.get('xp')

            if fire_weapon:
                destination_x, destination_y = coordinates
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)
                try:
                    if target == player:
                        message_log.add_message(
                            Message(
                                'No hitting yourself. Targeting cancelled.',
                                libtcod.yellow))
                        game_state = previous_game_state
                    elif target.ai and libtcod.map_is_in_fov(
                            fov_map, target.x, target.y):
                        attack_results = player.fighter.basic_bow_attack(
                            target)
                        player_turn_results.extend(attack_results)
                        game_state = GameStates.ENEMY_TURN
                    elif target.ai and not libtcod.map_is_in_fov(
                            fov_map, target.x, target.y):
                        message_log.add_message(
                            Message(
                                'That cannot be targeted. Targeting cancelled.',
                                libtcod.yellow))
                        game_state = previous_game_state
                except:
                    message_log.add_message(
                        Message(
                            'That cannot be targeted. Targeting cancelled.',
                            libtcod.yellow))
                    game_state = previous_game_state

            if message:
                message_log.add_message(message)

            if dead_entity:
                if dead_entity == player:
                    message, game_state = kill_player(dead_entity)
                else:
                    message = kill_monster(dead_entity)
                message_log.add_message(message)
                if config.win == True:
                    game_state = GameStates.PLAYER_DEAD

            if game_state == GameStates.PLAYER_DEAD:
                break

            if item_added:
                entities.remove(item_added)

                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                game_state = GameStates.ENEMY_TURN

            if item_dropped:
                entities.append(item_dropped)

                game_state = GameStates.ENEMY_TURN

            if equip:
                equip_results = player.equipment.toggle_equip(equip)

                for equip_result in equip_results:
                    equipped = equip_result.get('equipped')
                    dequipped = equip_result.get('dequipped')

                    if equipped:
                        message_log.add_message(
                            Message('You equipped the {0}'.format(
                                equipped.name)))

                    if dequipped:
                        message_log.add_message(
                            Message('You dequipped the {0}'.format(
                                dequipped.name)))

                game_state = GameStates.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING

                targeting_item = targeting

                message_log.add_message(targeting_item.item.targeting_message)

            if targeting_cancelled:
                game_state = previous_game_state

                message_log.add_message(Message('Targeting cancelled'))

            if xp:
                leveled_up = player.level.add_xp(xp)
                message_log.add_message(
                    Message('You gain {0} experience points.'.format(xp)))

                if leveled_up:
                    message_log.add_message(
                        Message(
                            'Your battle skills grow stronger! You reached level {0}'
                            .format(player.level.current_level) + '!',
                            libtcod.yellow))
                    previous_game_state = game_state
                    game_state = GameStates.LEVEL_UP

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(
                        player, fov_map, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

                        if dead_entity:
                            if dead_entity == player:
                                message, game_state = kill_player(dead_entity)
                            else:
                                message = kill_monster(dead_entity)

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break

                    if game_state == GameStates.PLAYER_DEAD:
                        break

            else:
                game_state = GameStates.PLAYERS_TURN
Exemple #19
0
def play_game(player, entities, game_map, message_log, game_state, con, panel, constants):
	fov_recompute = True

	fov_map = initialize_fov(game_map)

	key = libtcod.Key()
	mouse = libtcod.Mouse()

	game_state = GameStates.PLAYERS_TURN
	previous_game_state = game_state

	targeting_item = None

	while not libtcod.console_is_window_closed():
		libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse)

		if fov_recompute:
			recompute_fov(fov_map, player.x, player.y, constants['fov_radius'], constants['fov_light_walls'],
						  constants['fov_algorithm'])

		render_all(con, panel, entities, player, game_map, fov_map, fov_recompute, message_log,
				   constants['screen_width'], constants['screen_height'], constants['bar_width'],
				   constants['panel_height'], constants['panel_y'], mouse, constants['colors'], game_state)

		fov_recompute = False

		libtcod.console_flush()

		clear_all(con, entities)

		action = handle_keys(key, game_state)
		mouse_action = handle_mouse(mouse)

		move = action.get('move')
		wait = action.get('wait')
		pickup = action.get('pickup')
		show_inventory = action.get('show_inventory')
		drop_inventory = action.get('drop_inventory')
		inventory_index = action.get('inventory_index')
		take_stairs = action.get('take_stairs')
		level_up = action.get('level_up')
		show_character_screen = action.get('show_character_screen')
		exit = action.get('exit')
		fullscreen = action.get('fullscreen')

		left_click = mouse_action.get('left_click')
		right_click = mouse_action.get('right_click')

		player_turn_results = []

		if move and game_state == GameStates.PLAYERS_TURN:
			dx, dy = move
			destination_x = player.x + dx
			destination_y = player.y + dy

			if not game_map.is_blocked(destination_x, destination_y):
				target = get_blocking_entities_at_location(entities, destination_x, destination_y)

				if target:
					attack_results = player.fighter.attack(target)
					player_turn_results.extend(attack_results)
				else:
					player.move(dx, dy)

					fov_recompute = True

				game_state = GameStates.ENEMY_TURN

		elif wait:
			game_state = GameStates.ENEMY_TURN

		elif pickup and game_state == GameStates.PLAYERS_TURN:
			for entity in entities:
				if entity.item and entity.x == player.x and entity.y == player.y:
					pickup_results = player.inventory.add_item(entity)
					player_turn_results.extend(pickup_results)

					break
			else:
				message_log.add_message(Message('There is nothing here to pick up.', libtcod.yellow))

		if show_inventory:
			previous_game_state = game_state
			game_state = GameStates.SHOW_INVENTORY

		if drop_inventory:
			previous_game_state = game_state
			game_state = GameStates.DROP_INVENTORY

		if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
				player.inventory.items):
			item = player.inventory.items[inventory_index]

			if game_state == GameStates.SHOW_INVENTORY:
				player_turn_results.extend(player.inventory.use(item, entities=entities, fov_map=fov_map))
			elif game_state == GameStates.DROP_INVENTORY:
				player_turn_results.extend(player.inventory.drop_item(item))

		if take_stairs and game_state == GameStates.PLAYERS_TURN:
			for entity in entities:
				if entity.stairs and entity.x == player.x and entity.y == player.y:
					entities = game_map.next_floor(player, message_log, constants)
					fov_map = initialize_fov(game_map)
					fov_recompute = True
					libtcod.console_clear(con)

					break

				else:
					message_log.add_message(Message('There are no stairs here.', libtcod.yellow))

		if level_up:
			if level_up == 'hp':
				player.fighter.max_hp += 20
				player.fighter.hp += 20
			elif level_up == 'str':
				player.fighter.power += 1
			elif level_up == 'def':
				player.fighter.defense += 1

			game_state = previous_game_state

		if show_character_screen:
			previous_game_state = game_state
			game_state = GameStates.CHARACTER_SCREEN

		if game_state == GameStates.TARGETING:
			if left_click:
				target_x, target_y = left_click

				item_use_results = player.inventory.use(targeting_item, entities=entities, fov_map=fov_map,
														target_x=target_x, target_y=target_y)
				player_turn_results.extend(item_use_results)
			elif right_click:
				player_turn_results.append({'targeting_cancelled': True})

		if exit:
			if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY, GameStates.CHARACTER_SCREEN):
				game_state = previous_game_state
			elif game_state == GameStates.TARGETING:
				player_turn_results.append({'targeting_cancelled': True})
			else:
				save_game(player, entities, game_map, message_log, game_state)

				return True

		if fullscreen:
			libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

		for player_turn_result in player_turn_results:
			message = player_turn_result.get('message')
			dead_entity = player_turn_result.get('dead')
			item_added = player_turn_result.get('item_added')
			item_consumed = player_turn_result.get('consumed')
			item_dropped = player_turn_result.get('item_dropped')
			targeting = player_turn_result.get('targeting')
			targeting_cancelled = player_turn_result.get('targeting_cancelled')
			xp = player_turn_result.get('xp')

			if message:
				message_log.add_message(message)

			if dead_entity:
				if dead_entity == player:
					message, game_state = kill_player(dead_entity)
				else:
					message = kill_monster(dead_entity)

				message_log.add_message(message)

			if item_added:
				entities.remove(item_added)

				game_state = GameStates.ENEMY_TURN

			if item_consumed:
				game_state = GameStates.ENEMY_TURN

			if item_dropped:
				entities.append(item_dropped)

				game_state = GameStates.ENEMY_TURN

			if targeting:
				previous_game_state = GameStates.PLAYERS_TURN
				game_state = GameStates.TARGETING

				targeting_item = targeting

				message_log.add_message(targeting_item.item.targeting_message)

			if targeting_cancelled:
				game_state = previous_game_state

				message_log.add_message(Message('Targeting cancelled'))

			if xp:
				leveled_up = player.level.add_xp(xp)
				message_log.add_message(Message('You gain {0} experience points.'.format(xp)))

				if leveled_up:
					message_log.add_message(Message(
						'Your battle skills grow stronger! You reached level {0}'.format(
							player.level.current_level) + '!', libtcod.yellow))
					previous_game_state = game_state
					game_state = GameStates.LEVEL_UP


		if game_state == GameStates.ENEMY_TURN:
			for entity in entities:
				if entity.ai:
					enemy_turn_results = entity.ai.take_turn(player, fov_map, game_map, entities)

					for enemy_turn_result in enemy_turn_results:
						message = enemy_turn_result.get('message')
						dead_entity = enemy_turn_result.get('dead')

						if message:
							message_log.add_message(message)

						if dead_entity:
							if dead_entity == player:
								message, game_state = kill_player(dead_entity)
							else:
								message = kill_monster(dead_entity)

							message_log.add_message(message)

							if game_state == GameStates.PLAYER_DEAD:
								break

					if game_state == GameStates.PLAYER_DEAD:
						break
			else:
				game_state = GameStates.PLAYERS_TURN
Exemple #20
0
def main():
    # Presets
    libtcod.sys_set_fps(120)
    screen_width = 80
    screen_height = 50

    map_width = 80
    map_height = 45

    room_max_size = 10
    room_min_size = 6
    max_rooms = 30
    max_monsters = 20

    fov_algorithm = 0
    fov_light_walls = True
    fov_radius = 6

    # Dictionary to hold colors we'll be using
    colors = {
        'dark_wall': libtcod.Color(48, 98, 48),
        'dark_ground': libtcod.Color(100, 140, 15),
        'light_wall': libtcod.Color(110, 110, 48),
        'light_ground': libtcod.Color(155, 188, 15),
        'unexplored': libtcod.Color(15, 56, 15)
    }
    # We declare an npc
    npc = Entity(int(screen_width / 2 + 2), int(screen_height / 2 - 5), '@',
                 libtcod.grey)
    # We declare the player
    player = Entity(int(screen_width / 2), int(screen_height / 2), '@',
                    libtcod.white)
    # We get all entities in a list so we can iterate them
    entities = [player, npc]
    # Define the font and the screen...
    libtcod.console_set_custom_font(
        'arial12x12.png',
        libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)

    libtcod.console_init_root(screen_width, screen_height, 'Roguelike',
                              False)  # False because we dont want fullscreen
    # Main console
    con = libtcod.console_new(screen_width, screen_height)
    # We create a map randomly from the available options
    map_type = randint(0, 1)
    if map_type == 0:
        game_map = GameMap(map_width, map_height)
        game_map.make_map(80, map_width, map_height, player, max_monsters,
                          entities)
    else:
        room_num = randint(10, max_rooms)
        game_map = roomGameMap(map_width, map_height)
        game_map.make_map(room_num, room_min_size, room_max_size, map_width,
                          map_height, player, entities, 3)
    # Fov doesn't need to be computed every turn, only if we move. We use
    # the boolean fov_recompute to handle this
    fov_recompute = True

    fov_map = initialize_fov(game_map)
    # Key for holding key presses and mouse variable
    key = libtcod.Key()
    mouse = libtcod.Mouse()

    # Game Loop
    while not libtcod.console_is_window_closed():
        # Check for keypress
        libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse)

        # Calculate fov
        if fov_recompute:
            recompute_fov(fov_map, player.x, player.y, fov_radius,
                          fov_light_walls, fov_algorithm)

        render_all(con, entities, game_map, fov_map, fov_recompute,
                   screen_width, screen_height, colors, player)

        fov_recompute = False
        libtcod.console_flush()

        # We overwrite the character before getting the new coordinates, so next time we draw
        # it will not leave a trace
        '''
        Key handling
        We look for dictionary entries in action. If any of these is present it
        will be True.
        '''
        action = handle_keys(key)

        move = action.get('move')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')

        if move:
            dx, dy = move
            # We check if we can actually move to the tile
            if not game_map.is_blocked(player.x + dx, player.y + dy):
                player.move(dx, dy)
                fov_recompute = True
        if exit:
            return True
        if fullscreen:
            libtcod.console_set_fullscreen(
                not libtcod.console_is_fullscreen())  # On and off
Exemple #21
0
def play_game(player, entities, game_map, message_log, game_state, con, panel,
              constants):
    fov_recompute = True

    fov_map = initialize_fov(game_map)

    key = libtcod.Key()
    mouse = libtcod.Mouse()

    game_state = GameStates.PLAYERS_TURN
    previous_game_state = game_state

    targeting_item = None

    # game loop
    while not libtcod.console_is_window_closed():
        # captures user input - will update the key and mouse variables with what the user inputs
        libtcod.sys_check_for_event(
            libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse)

        if fov_recompute:
            recompute_fov(fov_map, player.x, player.y, constants['fov_radius'],
                          constants['fov_light_walls'],
                          constants['fov_algorithm'])

        # draw the entities and blit the changes to the screen - only render the item inventory when the game state is in the inventory state
        render_all(con, panel, entities, player, game_map, fov_map,
                   fov_recompute, message_log, constants['screen_width'],
                   constants['screen_height'], constants['bar_width'],
                   constants['panel_height'], constants['panel_y'], mouse,
                   constants['colors'], game_state)

        fov_recompute = False

        # present everything on the screen
        libtcod.console_flush()

        # clear entities after drawing to screen - this makes it so that when entities move, they do not leave a trail behind
        clear_all(con, entities)

        # gives a way to gracefully exit program by hitting the ESC key
        # gets any keyboard input to the program and stores in the key variable
        action = handle_keys(key, game_state)
        mouse_action = handle_mouse(mouse)

        move = action.get('move')
        wait = action.get('wait')
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        inventory_index = action.get('inventory_index')
        take_stairs = action.get('take_stairs')
        level_up = action.get('level_up')
        show_character_screen = action.get('show_character_screen')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')

        left_click = mouse_action.get('left_click')
        right_click = mouse_action.get('right_click')

        player_turn_results = []

        # move the player only on the players turn
        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            # check if there is something at the destination that would block the player - if not, move the player there
            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)
                    fov_recompute = True

                # change to enemy's turn after player's move
                game_state = GameStates.ENEMY_TURN

        elif wait:
            game_state = GameStates.ENEMY_TURN

        # if the player did not move and performed the pickup action by pressing the key 'g'...
        elif pickup and game_state == GameStates.PLAYERS_TURN:
            # loop through each entity on the map, check if it is an item and occupies the same space as the player
            for entity in entities:
                # if the entity is an item and in the same position as the player
                if entity.item and entity.x == player.x and entity.y == player.y:
                    # add the item to the inventory and append the results to player_turn_results
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)

                    break  # makes it so the player only picks up one item at a time
            else:
                message_log.add_message(
                    Message('There is nothing here to pick up.',
                            libtcod.yellow))

        if show_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        # take the index selected, use the item selected
        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                player.inventory.items):
            item = player.inventory.items[inventory_index]

            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(
                    player.inventory.use(item,
                                         entities=entities,
                                         fov_map=fov_map))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(player.inventory.drop_item(item))

        if take_stairs and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.stairs and entity.x == player.x and entity.y == player.y:
                    entities = game_map.next_floor(player, message_log,
                                                   constants)
                    fov_map = initialize_fov(game_map)
                    fov_recompute = True
                    libtcod.console_clear(con)

                    break
            else:
                message_log.add_message(
                    Message('There are no stairs here.', libtcod.yellow))

        if level_up:
            if level_up == 'hp':
                player.fighter.max_hp += 20
                player.fighter.hp += 20
            elif level_up == 'str':
                player.fighter.power += 1
            elif level_up == 'def':
                player.fighter.defense += 1

            game_state = previous_game_state

        if show_character_screen:
            previous_game_state = game_state
            game_state = GameStates.CHARACTER_SCREEN

        if game_state == GameStates.TARGETING:
            if left_click:
                target_x, target_y = left_click

                item_use_results = player.inventory.use(targeting_item,
                                                        entities=entities,
                                                        fov_map=fov_map,
                                                        target_x=target_x,
                                                        target_y=target_y)
                player_turn_results.extend(item_use_results)
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})

        # checks if the key pressed was the Esc key - if it was, then exit the loop
        if exit:
            if game_state in (GameStates.SHOW_INVENTORY,
                              GameStates.DROP_INVENTORY,
                              GameStates.CHARACTER_SCREEN):
                game_state = previous_game_state
            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
            else:
                save_game(player, entities, game_map, message_log, game_state)
                return True

        if fullscreen:
            libtcod.console_set_fullscreen(
                (not libtcod.console_is_fullscreen()))

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            item_consumed = player_turn_result.get('consumed')
            item_dropped = player_turn_result.get('item_dropped')
            targeting = player_turn_result.get('targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')
            xp = player_turn_result.get('xp')

            if message:
                message_log.add_message(message)

            if dead_entity:
                if dead_entity == player:
                    message, game_state = kill_player(dead_entity)
                else:
                    message = kill_monster(dead_entity)

                message_log.add_message(message)

            if item_added:
                entities.remove(item_added)

                game_state = GameStates.ENEMY_TURN

            if item_dropped:
                entities.append(item_dropped)

                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                game_state = GameStates.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING

                targeting_item = targeting

                message_log.add_message(targeting_item.item.targeting_message)

            if targeting_cancelled:
                game_state = previous_game_state

                message_log.add_message(Message('Targeting cancelled'))

            if xp:
                leveled_up = player.level.add_xp(xp)
                message_log.add_message(
                    Message('You gain {0} experience points.'.format(xp)))

                if leveled_up:
                    message_log.add_message(
                        Message(
                            'Your battle skills grow stronger! You reached level {0}'
                            .format(player.level.current_level) + '!',
                            libtcod.yellow))
                    previous_game_state = game_state
                    game_state = GameStates.LEVEL_UP

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(
                        player, fov_map, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

                        if dead_entity:
                            if dead_entity == player:
                                message, game_state = kill_player(dead_entity)
                            else:
                                message = kill_monster(dead_entity)

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break

                    if game_state == GameStates.PLAYER_DEAD:
                        break
            # note that this is a for-else statement; without a break statement, this else will always happen
            else:
                game_state = GameStates.PLAYERS_TURN
Exemple #22
0
def main():
	screen_width = 80
	screen_height = 50
	map_width = 80
	map_height = 45

	room_max_size = 10
	room_min_size = 6
	max_rooms = 30

	fov_algorithm = 0
	fov_light_walls = True
	fov_radius = 10

	max_monsters_per_room = 3

	colors = {
		'dark_wall': libtcod.Color(0, 0, 100),
		'dark_ground': libtcod.Color(50, 50, 150),
		'light_wall': libtcod.Color(130, 110, 50),
		'light_ground': libtcod.Color(200, 180, 50)
	}

	fighter_component = Fighter(hp=30, defense=2, power=5)
	player = Entity(0, 0, '@', libtcod.white, "Player", blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component)
	entities = [player]

	libtcod.console_set_custom_font('arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)

	libtcod.console_init_root(screen_width, screen_height, 'libtcod tutorial revised', False)

	con = libtcod.console_new(screen_width, screen_height)

	game_map = GameMap(map_width, map_height)
	game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, max_monsters_per_room)

	fov_recompute = True

	fov_map = initialize_fov(game_map)

	key = libtcod.Key()
	mouse = libtcod.Mouse()

	game_state = GameStates.PLAYERS_TURN

	while not libtcod.console_is_window_closed():
		libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse)

		if fov_recompute:
			recompute_fov(fov_map, player.x, player.y, fov_radius, fov_light_walls, fov_algorithm)

		render_all(con, entities, player, game_map, fov_map, fov_recompute, screen_width, screen_height, colors)

		libtcod.console_flush()

		clear_all(con, entities)

		action = handle_keys(key)

		move = action.get('move')
		exit = action.get('exit')
		fullscreen = action.get('fullscreen')

		player_turn_results = []

		if move and game_state == GameStates.PLAYERS_TURN:
			dx, dy = move
			destination_x = player.x + dx
			destination_y = player.y + dy

			if not game_map.is_blocked(destination_x, destination_y):
				target = get_blocking_entities_at_location(entities, destination_x, destination_y)

				if target:
					attack_results = player.fighter.attack(target)
					player_turn_results.extend(attack_results)
				else:
					player.move(dx, dy)

					fov_recompute = True

				game_state = GameStates.ENEMY_TURN

		if exit:
			return True

		if fullscreen:
			libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

		for player_turn_result in player_turn_results:
			message = player_turn_result.get('message')
			dead_entity = player_turn_result.get('dead')

			if message:
				print(message)

			if dead_entity:
				if dead_entity == player:
					message, game_state = kill_player(dead_entity)
				else:
					message = kill_monster(dead_entity)

				print(message)

		if game_state == GameStates.ENEMY_TURN:
			for entity in entities:
				if entity.ai:
					enemy_turn_results = entity.ai.take_turn(player, fov_map, game_map, entities)

					for enemy_turn_result in enemy_turn_results:
						message = enemy_turn_result.get('message')
						dead_entity = enemy_turn_result.get('dead')

						if message:
							print(message)

						if dead_entity:
							if dead_entity == player:
								message, game_state = kill_player(dead_entity)
							else:
								message = kill_monster(dead_entity)

							print(message)

							if game_state == GameStates.PLAYER_DEAD:
								break

					if game_state == GameStates.PLAYER_DEAD:
						break

			else:
				game_state = GameStates.PLAYERS_TURN
Exemple #23
0
def play_game(player, entities, game_map, message_log, game_state, con, panel,
              constants, root_con):
    tcod.console_set_custom_font(
        "arial10x10.png", tcod.FONT_LAYOUT_TCOD | tcod.FONT_TYPE_GREYSCALE)
    fov_recompute = True
    fov_map = initialize_fov(game_map)
    previous_game_state = game_state
    targeting_item = None
    while True:
        if fov_recompute:
            recompute_fov(fov_map, player.x, player.y, constants['fov_radius'],
                          constants['fov_light_walls'],
                          constants['fov_algorithm'])
        render_all(con, panel, entities, player, game_map, fov_map,
                   fov_recompute, message_log, constants["screen_width"],
                   constants["screen_height"], constants["bar_width"],
                   constants["panel_y"], constants["colors"], root_con,
                   game_state)
        tcod.console_flush()
        clear_all(con, entities)
        for event in tcod.event.get():
            move = None
            pickup = None
            look_enemy = None
            left_click = None
            right_click = None
            show_inventory = None
            drop_inventory = None
            inventory_index = None
            take_stairs = None
            leave = None
            fullscreen = None
            show_character_screen = None
            player_turn_results = []
            if isinstance(event, tcod.event.KeyDown):
                action = handle_keys(event, game_state)
                move = action.get("move")
                pickup = action.get("pickup")
                look_enemy = action.get("look_enemy")
                show_inventory = action.get("show_inventory")
                drop_inventory = action.get("drop_inventory")
                inventory_index = action.get("inventory_index")
                take_stairs = action.get('take_stairs')
                leave = action.get("leave")
                fullscreen = action.get("fullscreen")
                show_character_screen = action.get('show_character_screen')
            if isinstance(event, tcod.event.MouseButtonDown):
                mouse_action = handle_mouse(event)
                left_click = mouse_action.get("left_click")
                right_click = mouse_action.get("right_click")
            if look_enemy and game_state == GameStates.PLAYER_TURN:
                game_state = GameStates.LOOK_ENEMY
                player_turn_results.extend([{
                    'message':
                    Message('You are in the looking mode', tcod.green)
                }])
            elif look_enemy and game_state == GameStates.LOOK_ENEMY:
                game_state = GameStates.PLAYER_TURN
                player_turn_results.extend([{
                    'message':
                    Message('You left the looking mode', tcod.green)
                }])
            elif left_click and game_state == GameStates.LOOK_ENEMY:
                entities_at_location = check_entity_at_location(
                    entities, left_click[0], left_click[1])
                player_turn_results.extend(entities_at_location)
            elif pickup and game_state == GameStates.PLAYER_TURN:
                for entity in entities:
                    if entity.item and entity.x == player.x and entity.y == player.y:
                        pickup_results = player.inventory.add_item(entity)
                        player_turn_results.extend(pickup_results)
                        break
                else:
                    message_log.add_message(
                        Message('There is nothing here to pick up.',
                                tcod.yellow))
            elif show_inventory:
                previous_game_state = game_state
                game_state = GameStates.SHOW_INVENTORY
                MenuState.menu_state = 0
            elif drop_inventory:
                previous_game_state = game_state
                game_state = GameStates.DROP_INVENTORY
            elif inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                    player.inventory.items):
                item = player.inventory.items[inventory_index]
                if game_state == GameStates.SHOW_INVENTORY:
                    player_turn_results.extend(
                        player.inventory.use(item,
                                             entities=entities,
                                             fov_map=fov_map))
                elif game_state == GameStates.DROP_INVENTORY:
                    player_turn_results.extend(
                        player.inventory.drop_item(item))
            elif game_state == GameStates.TARGETING:
                if left_click and targeting_item:
                    target_x, target_y = left_click
                    item_use_results = player.inventory.use(targeting_item,
                                                            entities=entities,
                                                            fov_map=fov_map,
                                                            target_x=target_x,
                                                            target_y=target_y)
                    player_turn_results.extend(item_use_results)
                elif right_click:
                    player_turn_results.append({'targeting_cancelled': True})
            elif move and game_state == GameStates.PLAYER_TURN:
                dx, dy = move
                destination_x = player.x + dx
                destination_y = player.y + dy
                if not game_map.is_blocked(destination_x, destination_y):
                    target = get_blocking_entities_at_location(
                        entities, destination_x, destination_y)
                    if target:
                        attack_results = player.fighter.melee_attack(target)
                        player_turn_results.extend(attack_results)
                    else:
                        player.move(dx, dy)

                        fov_recompute = True
                    game_state = GameStates.ENEMY_TURN
            elif take_stairs and game_state == GameStates.PLAYER_TURN:
                for entity in entities:
                    if entity.stairs and entity.x == player.x and entity.y == player.y:
                        entities = game_map.next_floor(player, message_log,
                                                       constants)
                        fov_map = initialize_fov(game_map)
                        fov_recompute = True
                        con.clear(fg=(63, 127, 63))

                        break
                else:
                    message_log.add_message(
                        Message('There are no stairs here.', tcod.yellow))
            elif game_state == GameStates.LEVEL_UP:
                player.fighter.max_hp += DiceRoll("1d8").roll_dice()
                game_state = previous_game_state
            elif show_character_screen:
                previous_game_state = game_state
                game_state = GameStates.CHARACTER_SCREEN
            if leave:
                if game_state in (GameStates.SHOW_INVENTORY,
                                  GameStates.DROP_INVENTORY,
                                  GameStates.CHARACTER_SCREEN):
                    game_state = previous_game_state
                elif game_state == GameStates.TARGETING:
                    player_turn_results.append({'targeting_cancelled': True})
                else:
                    save_game(player, entities, game_map, message_log,
                              game_state)
                    return True

            if fullscreen:
                tcod.console_set_fullscreen(not tcod.console_is_fullscreen())

            for player_turn_result in player_turn_results:
                message = player_turn_result.get('message')
                dead_entity = player_turn_result.get('dead')
                entity_identified = player_turn_result.get("entity_identified")
                item_added = player_turn_result.get('item_added')
                item_consumed = player_turn_result.get('consumed')
                item_dropped = player_turn_result.get('item_dropped')
                targeting = player_turn_result.get('targeting')
                targeting_cancelled = player_turn_result.get(
                    'targeting_cancelled')
                xp = player_turn_result.get('xp')
                if message:
                    message_log.add_message(message)

                if dead_entity:
                    if dead_entity == player:
                        message, game_state = kill_player(dead_entity)
                    else:
                        message = kill_monster(dead_entity)

                    message_log.add_message(message)

                if item_added:
                    entities.remove(item_added)
                    game_state = GameStates.ENEMY_TURN

                if item_consumed:
                    game_state = GameStates.ENEMY_TURN

                if item_dropped:
                    entities.append(item_dropped)
                    game_state = GameStates.ENEMY_TURN

                if entity_identified:
                    game_state = GameStates.PLAYER_TURN

                if targeting:
                    previous_game_state = GameStates.PLAYER_TURN
                    game_state = GameStates.TARGETING
                    targeting_item = targeting
                    message_log.add_message(
                        targeting_item.item.targeting_message)

                if targeting_cancelled:
                    game_state = previous_game_state
                    message_log.add_message(Message('Targeting cancelled'))

                if xp:
                    leveled_up = player.level.add_xp(xp)
                    message_log.add_message(
                        Message('You gain {0} experience points.'.format(xp)))

                    if leveled_up:
                        message_log.add_message(
                            Message(
                                'Your battle skills grow stronger! You reached level {0}'
                                .format(player.level.current_level) + '!',
                                tcod.yellow))
                        player.fighter.cr = str(player.level.current_level / 4)
                        previous_game_state = game_state
                        game_state = GameStates.LEVEL_UP

            if game_state == GameStates.ENEMY_TURN:
                for entity in entities:
                    if entity.ai:
                        enemy_turn_results = entity.ai.take_turn(
                            player, fov_map, game_map, entities)

                        for enemy_turn_result in enemy_turn_results:
                            message = enemy_turn_result.get('message')
                            dead_entity = enemy_turn_result.get('dead')

                            if message:
                                message_log.add_message(message)

                            if dead_entity:
                                if dead_entity == player:
                                    message, game_state = kill_player(
                                        dead_entity)
                                else:
                                    message = kill_monster(dead_entity)

                                message_log.add_message(message)

                                if game_state == GameStates.PLAYER_DEAD:
                                    break

                        if game_state == GameStates.PLAYER_DEAD:
                            break
                else:
                    game_state = GameStates.PLAYER_TURN
Exemple #24
0
def main():
    constants = get_constants()

    libtcod.console_set_custom_font(
        'arial10x10.png',
        libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)
    libtcod.console_init_root(constants['screen_width'],
                              constants['screen_height'], 'rogue', False)

    con = libtcod.console_new(constants['screen_width'],
                              constants['screen_height'])
    panel = libtcod.console_new(constants['screen_width'],
                                constants['panel_height'])

    player, entities, game_map, message_log, game_state = get_game_variables(
        constants)

    fov_recompute = True

    fov_map = initialize_fov(game_map)

    key = libtcod.Key()
    mouse = libtcod.Mouse()

    previous_game_state = game_state

    while not libtcod.console_is_window_closed():
        libtcod.sys_check_for_event(
            libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse)

        if fov_recompute:
            recompute_fov(fov_map, player.x, player.y, constants['fov_radius'],
                          constants['fov_light_walls'],
                          constants['fov_algorithm'])

        render_all(con, panel, entities, player, game_map, fov_map,
                   fov_recompute, message_log, constants['screen_width'],
                   constants['screen_height'], constants['bar_width'],
                   constants['panel_height'], constants['panel_y'],
                   constants['mouse'], constants['colors'], game_state)
        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities)

        action = handle_keys(key, game_state)
        mouse_action = handle_mouse(mouse)

        move = action.get('move')
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        inventory_index = action.get('inventory_index')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')

        left_click = mouse_action.get('left_click')
        right_click = mouse_action.get('right_click')

        player_turn_results = []

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(player.x + dx, player.y + dy):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target:
                    player.fighter.attack(target)
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)
                    fov_recompute = True
                game_state = GameStates.ENEMY_TURN

        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)

                    break
                else:
                    message_log.add_message(
                        Message('There is nothing here to pick up.',
                                libtcod.yellow))

        if show_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                player.inventory.items):
            item = player.inventory.items[inventory_index]
            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(
                    player.inventory.use(item,
                                         entities=entities,
                                         fov_map=fov_map))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(player.inventory.drop_item(item))

        if game_state == GameStates.TARGETING:
            if left_click:
                target_x, target_y = left_click

                item_use_results = player.inventory.use(targeting_item,
                                                        entities=entities,
                                                        fov_map=fov_map,
                                                        target_x=target_x,
                                                        target_y=target_y)
                player_turn_results.append(item_use_results)
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})

        if exit:
            if game_state in (game_state.SHOW_INVENTORY,
                              game_state.DROP_INVENTORY):
                game_state = previous_game_state
            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
            else:
                return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            item_consumed = player_turn_result.get('consumed')
            item_dropped = player_turn_result.get('item_dropped')
            targeting = player_turn_result.get('targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')

            if message:
                message_log.add_message(message)

            if targeting_cancelled:
                game_state = previous_game_state
                message_log.add_message(Message('Targeting cancelled'))

            if dead_entity:
                if dead_entity == player:
                    message, game_state = kill_player(dead_entity)
                else:
                    message = kill_monster(dead_entity)

                message_log.add_message(message)

            if item_added:
                entities.remove(item_added)

                game_state = game_state.ENEMY_TURN

            if item_consumed:
                game_state.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING

                targeting_item = targeting

                message_log.add_message(targeting_item.item.targeting_message)

            if item_dropped:
                entities.append(item_dropped)
                game_state = GameStates.ENEMY_TURN

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(
                        player, fov_map, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

                        if dead_entity:
                            if dead_entity == player:
                                message, game_state = kill_player(dead_entity)
                            else:
                                message = kill_monster(dead_entity)

                        message_log.add_message(message)

                        if game_state == GameStates.PLAYER_DEAD:
                            break

                    if game_state == GameStates.PLAYER_DEAD:
                        break

            else:
                game_state = GameStates.PLAYERS_TURN
Exemple #25
0
def play_game(player, entities, game_map, message_log, game_state, con, panel, constants):
	# Intialize FOV map.
	fov_recompute = True # Recompute FOV after the player moves
	fov_map = initialize_fov(game_map)
	target_fov_map = initialize_fov(game_map)
	fov_map_no_walls = initialize_fov(game_map)


	# Capture keyboard and mouse input
	key = libtcod.Key()
	mouse = libtcod.Mouse()
	game_state = GameStates.PLAYERS_TURN
	previous_game_state = game_state

	# Store the item that the player used to enter targeting mode (ie lightning scroll). This is so that we know what item we need to remove from inventory etc.
	targeting_item = None
	cursor_radius = 1

	# For showing object descriptions
	description_recompute = True
	description_list = []
	description_index = 0	
	prev_mouse_y = None
	prev_mouse_x = None

	# Start music
	mixer.init()
	mixer.music.load(os.path.join(definitions.ROOT_DIR, 'data', 'music', 'bgm2.mp3'))
	#mixer.music.play(loops=-1)

	#Our main loop
	while not libtcod.console_is_window_closed():
		# Check for input
		libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse)
		for animator in Animator.animators:
			animator.update()
		if Animator.blocking > 0:
			if not game_state == GameStates.BLOCKING_ANIMATION:
				previous_game_state = game_state
			game_state = GameStates.BLOCKING_ANIMATION

		if Animator.blocking == 0 and game_state == GameStates.BLOCKING_ANIMATION:
				game_state = previous_game_state

		# Recompute FOV
		if fov_recompute:
			recompute_fov(fov_map, player.x, player.y, constants['fov_radius'], constants['fov_light_walls'], constants['fov_algorithm'])
			recompute_fov(fov_map_no_walls, player.x, player.y, constants['fov_radius'], light_walls=False, algorithm=constants['fov_algorithm'])
		
	
		# Show object descriptions
		if description_recompute == True:

			for entity in entities:

				if (prev_mouse_x != mouse.cx) or (prev_mouse_y != mouse.cy):
					description_list = []
					description_index = 0
				if entity.x == mouse.cx and entity.y == mouse.cy:
					description_list.append(entity)
					prev_mouse_x = mouse.cx
					prev_mouse_y = mouse.cy

			
		if len(description_list) > 0:
			description_recompute = False
			# We need to check to see if the mouse position changed and then clear our description list if it did, otherwise it will keep growing
			if (prev_mouse_x != mouse.cx) or (prev_mouse_y != mouse.cy):
				description_list = []
				description_index = 0
				description_recompute = True
			if mouse.lbutton_pressed:
				description_index += 1
			if description_index > (len(description_list) - 1):
				description_index = 0


		
		# Draw our scene
		render_all(con, panel, mouse, entities, player, game_map, fov_map, fov_recompute, message_log, constants['screen_width'], constants['screen_height'], constants['bar_width'], constants['panel_height'], constants['panel_y'], constants['colors'], game_state, description_list, description_index, cursor_radius, target_fov_map, fov_map_no_walls)
		fov_recompute = False
		libtcod.console_flush()

		# Clear our 'drawing consoles' so we dont leave a trail on the main console screen
		clear_all(con, entities)


		# Store input results
		action = handle_keys(key, game_state)
		mouse_action = handle_mouse(mouse)
		key = libtcod.Key()
		mouse = libtcod.Mouse()
		move = action.get('move')
		pickup = action.get('pickup')
		show_inventory = action.get('show_inventory')
		drop_inventory = action.get('drop_inventory')
		inventory_index = action.get('inventory_index')
		take_stairs = action.get('take_stairs')
		level_up = action.get('level_up')
		show_character_screen = action.get('show_character_screen')
		ability_1 = action.get('ability_1')
		exit = action.get('exit')
		fullscreen = action.get('fullscreen')
		left_click = mouse_action.get('left_click')
		right_click = mouse_action.get('right_click')
		


		#Instatiate our message queue for the players turn
		player_turn_results = []

		# Player Actions
		# Move
		if move and game_state == GameStates.PLAYERS_TURN:
			if not move == 'wait':
				dx, dy = move
				destination_x = player.x + dx
				destination_y = player.y + dy

				# Check to see if the location we want to move to is blocked by a wall or inhabited by a creature
				if not game_map.is_blocked(destination_x, destination_y):
					target = get_blocking_entities_at_location(entities, destination_x, destination_y)

					# If blocked by a creature, attack
					if target:
						attack_results = player.fighter.attack(target)
						player_turn_results.extend(attack_results)
					# Otherwise, move.
					else:
						player.move(dx, dy)
						fov_recompute = True
					game_state = GameStates.ENEMY_TURN
			else:
				game_state = GameStates.ENEMY_TURN

		elif pickup and game_state == GameStates.PLAYERS_TURN:
			for entity in entities:
				if entity.item and entity.x == player.x and entity.y == player.y:
					pickup_results = player.inventory.add_item(entity)
					player_turn_results.extend(pickup_results)

					break
			else:
				message_log.add_message(Message('There is nothing here to pick up.', libtcod.yellow))
		#Ability complete checks:
		for ability in player.abilities:
			if player.animator.caller == ability and player.animator.complete:
				player_turn_results.extend(ability.use(complete=True))
				player.animator.caller = None
				player.animator.complete = None

		if ability_1:
			player_turn_results.extend(player.abilities[0].use())


		if show_inventory:
			if game_state != GameStates.SHOW_INVENTORY:
				previous_game_state = game_state
			player.inventory.sort_items()
			game_state = GameStates.SHOW_INVENTORY

		if drop_inventory:
			if game_state != GameStates.DROP_INVENTORY:
				previous_game_state = game_state
			game_state = GameStates.DROP_INVENTORY

		#Use or drop item in inventory
		if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(player.inventory.items):
			item = player.inventory.items[inventory_index]
			if game_state == GameStates.SHOW_INVENTORY:
				player_turn_results.extend(player.inventory.use(item, entities=entities, fov_map=fov_map))

			elif game_state == GameStates.DROP_INVENTORY:
				player_turn_results.extend(player.inventory.drop_item(item))

		if take_stairs and game_state == GameStates.PLAYERS_TURN:
			for entity in entities:
				if entity.stairs and entity.x == player.x and entity.y == player.y: 
					entities = game_map.next_floor(player, message_log, constants)
					fov_map = initialize_fov(game_map)
					target_fov_map = initialize_fov(game_map)
					fov_map_no_walls = initialize_fov(game_map)
					fov_recompute = True
					libtcod.console_clear(con)

					break
			else:
				message_log.add_message(Message('There are no stairs here.', libtcod.yellow))

		if level_up:
			if level_up == 'hp':
				player.fighter.con += 1
				message_log.add_message(Message('Your Constitution has increased by 1!', libtcod.yellow))
			elif level_up == 'str':
				player.fighter.base_power += 1
				message_log.add_message(Message('Your Strength has increased by 1!', libtcod.yellow))
			elif level_up == 'def':
				player.fighter.base_defense += 1
				message_log.add_message(Message('Your Defense has increased by 1!', libtcod.yellow))

			hp_increase = randint(player.fighter.hitdie[0], player.fighter.hitdie[1]) + int((player.fighter.con - 10) / 2)
			player.fighter.base_max_hp += hp_increase
			player.fighter.hp += hp_increase
			message_log.add_message(Message('Your HP has increased by {0}'.format(hp_increase) + '!', libtcod.yellow))
			game_state = previous_game_state

		if show_character_screen:
			if not game_state == GameStates.CHARACTER_SCREEN:
				previous_game_state = game_state
			game_state = GameStates.CHARACTER_SCREEN

		if game_state == GameStates.TARGETING:

			if hasattr(targeting_item, 'item'):
				cursor_radius = targeting_item.item.function_kwargs.get('radius')
			else:
				cursor_radius = targeting_item.function_kwargs.get('radius')
			if left_click:
				target_x, target_y = left_click
				if hasattr(targeting_item, 'item'):
					item_use_results = player.inventory.use(targeting_item, entities=entities, fov_map=fov_map, target_fov_map=target_fov_map,target_x=target_x, target_y=target_y)
				else:
					item_use_results = targeting_item.use(entities=entities, fov_map=fov_map, target_fov_map=target_fov_map,target_x=target_x, target_y=target_y)
				player_turn_results.extend(item_use_results)
				cursor_radius = 1
			
			elif right_click:
				player_turn_results.append({'targeting_cancelled': True})
				cursor_radius = 1		
						
		if exit:
			if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY, GameStates.CHARACTER_SCREEN):
				game_state = previous_game_state
			elif game_state == GameStates.TARGETING:
				player_turn_results.append({'targeting_cancelled': True})
				cursor_radius = 1
			else:
				save_game(player, entities, game_map, message_log, game_state)
				return True


		if fullscreen:
			libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

		# Check player message queue and react accordingly
		for player_turn_result in player_turn_results:
			message = player_turn_result.get('message')
			dead_entity = player_turn_result.get('dead')
			item_added = player_turn_result.get('item_added')
			item_consumed = player_turn_result.get('consumed')
			item_dropped = player_turn_result.get('item_dropped')
			equip = player_turn_result.get('equip')
			targeting = player_turn_result.get('targeting')
			targeting_cancelled = player_turn_result.get('targeting_cancelled')
			ability_used = player_turn_result.get("ability_used")
			xp = player_turn_result.get('xp')

			if message:
				message_log.add_message(message)

			if targeting_cancelled:
				game_state = previous_game_state

				message_log.add_message(Message('Targeting cancelled'))

			if dead_entity:
				if dead_entity == player:
					message, game_state = kill_player(dead_entity)
				else:
					message = kill_monster(dead_entity)

				message_log.add_message(message)

			if item_added:
				entities.remove(item_added)

				game_state = GameStates.ENEMY_TURN

			if item_consumed:
				game_state = GameStates.ENEMY_TURN
			
			if targeting:
				previous_game_state = GameStates.PLAYERS_TURN
				game_state = GameStates.TARGETING

				targeting_item = targeting
				if hasattr(targeting_item, 'item'):
					message_log.add_message(targeting_item.item.targeting_message)
				else:
					message_log.add_message(targeting_item.targeting_message)

			if ability_used:
				if Animator.blocking == 0:
					game_state = GameStates.ENEMY_TURN

			if item_dropped:
				entities.append(item_dropped)
				game_state = GameStates.ENEMY_TURN

			if equip:
				equip_results = player.equipment.toggle_equip(equip)

				for equip_result in equip_results:
					equipped = equip_result.get('equipped')
					dequipped = equip_result.get('dequipped')

					if equipped:
						message_log.add_message(Message('You equipped the {0}'.format(equipped.name)))

					if dequipped:
						message_log.add_message(Message('You removed the {0}'.format(dequipped.name)))

				game_state = GameStates.ENEMY_TURN

			if xp:
				leveled_up = player.level.add_xp(xp)
				message_log.add_message(Message('You gain {0} experience points.'.format(xp)))

				if leveled_up:
					message_log.add_message(Message('Your battle skills grow stronger! You reached level {0}'.format(
													player.level.current_level) + '!', libtcod.yellow))
					if (player.level.current_level % 2) == 0:
						previous_game_state = game_state
						game_state = GameStates.LEVEL_UP
					else:
						hp_increase = randint(player.fighter.hitdie[0], player.fighter.hitdie[1]) + int((player.fighter.con - 10) / 2)
						player.fighter.base_max_hp += hp_increase
						player.fighter.hp += hp_increase
						message_log.add_message(Message('Your HP has increased by {0}'.format(hp_increase) + '!', libtcod.yellow))


		# Enemy Turn
		if game_state == GameStates.ENEMY_TURN:
			for entity in entities:
				if entity.ai:
					enemy_turn_results = entity.ai.take_turn(player, fov_map, game_map, entities)

					# Capture enemy turn message queue, analyze and react accordingly.
					for enemy_turn_result in enemy_turn_results:
						message = enemy_turn_result.get('message')
						dead_entity = enemy_turn_result.get('dead')

						if message:
							message_log.add_message(message)

						if dead_entity:
							if dead_entity == player:
								message, game_state = kill_player(dead_entity)
							else:
								message = kill_monster(dead_entity)

							message_log.add_message(message)

							if game_state == GameStates.PLAYER_DEAD:
								break
					if game_state == GameStates.PLAYER_DEAD:
						break

				
			else:            

				game_state = GameStates.PLAYERS_TURN
Exemple #26
0
def play_game(player, entities, game_map, message_log, game_state, con, panel,
              constants):
    # bool to store whether we update fov or not
    fov_recompute = True
    fov_map = initialize_fov(game_map)

    # key and mouse to capture input
    key = libtcod.Key()
    mouse = libtcod.Mouse()
    mouse_pos = 0

    # set game state
    game_state = GameStates.PLAYERS_TURN
    previous_game_state = game_state

    # make sure set to none
    targeting_item = None

    #-------GAME LOOP-------
    while not libtcod.console_is_window_closed():
        libtcod.sys_check_for_event(
            libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse)

        # This is will update the mouse when it is moved.
        if mouse.x != mouse_pos:
            fov_recompute = True
            mouse_pos = mouse.x

        #if player doesn't move fov won't update.
        if fov_recompute:
            recompute_fov(fov_map, player.x, player.y, constants['fov_radius'],
                          constants['fov_light_walls'],
                          constants['fov_algorithm'])

        #update everything
        render_all(con, panel, entities, player, game_map, fov_map,
                   fov_recompute, message_log, constants['screen_width'],
                   constants['screen_height'], constants['bar_width'],
                   constants['panel_height'], constants['panel_y'], mouse,
                   constants['colors'], game_state)
        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities)

        action = handle_keys(key, game_state)

        mouse_action = handle_mouse(mouse)

        #----ACTIONS-----
        move = action.get('move')
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        inventory_index = action.get('inventory_index')
        drop_inventory = action.get('drop_inventory')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')

        left_click = mouse_action.get('left_click')
        right_click = mouse_action.get('right_click')

        player_turn_results = []

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            fov_recompute = True
            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)
                    fov_recompute = True
                #after player's turn set to enemy turn
                game_state = GameStates.ENEMY_TURN
        elif pickup and game_state == GameStates.PLAYERS_TURN:
            fov_recompute = True
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)

                    break
            else:
                message_log.add_message(
                    Message('There is nothing here to pick up.',
                            libtcod.yellow))

        if show_inventory:
            fov_recompute = True
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if drop_inventory:
            fov_recompute = True
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                player.inventory.items):
            fov_recompute = True
            item = player.inventory.items[inventory_index]
            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(
                    player.inventory.use(item,
                                         entities=entities,
                                         fov_map=fov_map))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(player.inventory.drop_item(item))

        if game_state == GameStates.TARGETING:
            if left_click:
                target_x, target_y = left_click

                item_use_results = player.inventory.use(targeting_item,
                                                        entities=entities,
                                                        fov_map=fov_map,
                                                        target_x=target_x,
                                                        target_y=target_y)
                player_turn_results.extend(item_use_results)
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})

        if exit:
            if game_state in (GameStates.SHOW_INVENTORY,
                              GameStates.DROP_INVENTORY):
                game_state = previous_game_state
                fov_recompute = True
            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_canclled': True})
            else:
                # save when the game is exited
                save_game(player, entities, game_map, message_log, game_state)

                return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        ##-----PLAYER TURN RESULTS
        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            item_consumed = player_turn_result.get('consumed')
            item_dropped = player_turn_result.get('item_dropped')
            targeting = player_turn_result.get('targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')

            if message:
                message_log.add_message(message)

            if dead_entity:
                if dead_entity == player:
                    message, game_state = kill_player(dead_entity)
                else:
                    message = kill_monster(dead_entity)

                message_log.add_message(message)

            if item_added:
                entities.remove(item_added)
                fov_recompute = True
                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                game_state = GameStates.ENEMY_TURN

            if item_dropped:
                entities.append(item_dropped)
                game_state = GameStates.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING

                targeting_item = targeting

                message_log.add_message(targeting_item.item.targeting_message)

            if targeting_cancelled:
                game_state = previous_game_state
                message_log.add_message(Message('Targeting cancelled'))

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.ai:  #if an entity object has an ai, it gets a turn.
                    enemy_turn_results = entity.ai.take_turn(
                        player, fov_map, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

                        if dead_entity:
                            if dead_entity == player:
                                message, game_state = kill_player(dead_entity)
                            else:
                                message = kill_monster(dead_entity)

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break
                    if game_state == GameStates.PLAYER_DEAD:
                        break
            else:
                #after all the enemies move, players turn
                game_state = GameStates.PLAYERS_TURN
Exemple #27
0
def main():
	screen_width = 80 # /4 = 20
	screen_height = 50 # /4 ~= 12

	# Map panel parameters
	map_width = 45
	map_height = 40

	fov_algorithm = libtcod.FOV_SHADOW
	fov_light_walls = True
	fov_radius = 9

	# Health/Stats panel parameters
	bar_x = 4
	bar_width = 24
	panel_height = screen_height - map_height - 1
	panel_y = screen_height - panel_height

	# Message panel parameters
	message_x = bar_width + bar_x + 2
	message_width = screen_width - bar_width - bar_x - 2
	message_height = panel_height - 2

	message_log = MessageLog(message_x, message_width, message_height)

	# set up player entity and active entity list
	# TODO: Allow player to assign stats when starting to play
	fighter_component = Fighter(
		hp=30, 
		defense=5, spdefense=5, 
		attack=5, spattack=5, 
		speed=5)
	player = Entity(int(screen_width / 2), int(screen_height / 2), 
		'@', libtcod.white, 'Player', 
		render_order=RenderOrder.ACTOR, blocks=True, fighter=fighter_component)
	entities = []

	# set up console
	libtcod.console_set_custom_font('arial10x10.png', 
		libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)
	libtcod.console_init_root(screen_width, screen_height, 
		'libtcod tutorial revised', False, 
		libtcod.RENDERER_SDL2, vsync=True)

	# set up all panels
	con = libtcod.console.Console(screen_width, screen_height)
	panel = libtcod.console.Console(screen_width, panel_height)

	# load map, entities and player
	game_world = GameWorld(map_width, map_height)
	game_world.loadfirstfloor(player, entities)

	# player field of vision variables
	fov_recompute = True
	fov_map = initialize_fov(game_world.currmap)

	# input variables
	key = libtcod.Key()
	mouse = libtcod.Mouse()

	# state variables
	game_state = GameState.PLAYERS_TURN

	while not libtcod.console_is_window_closed():
		# poll input
		libtcod.sys_check_for_event(
			libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, 
			key, mouse)

		# compute field of vision
		if fov_recompute:
			if game_world.currmap.islair:
				current_fov_radius = 20
			else:
				current_fov_radius = fov_radius
			recompute_fov(fov_map, player.x, player.y, current_fov_radius, 
				fov_light_walls, fov_algorithm)

		# draw screen
		render_all(con, panel, entities, player, game_world.currmap, 
			message_log, fov_map, fov_recompute, 
			screen_width, screen_height, 
			bar_x, bar_width, panel_height, panel_y, mouse)
		fov_recompute = False
		libtcod.console_flush()

		# erase previous player position
		clear_all(con, entities)

		# parse input
		action = handle_keys(key)

		move = action.get('move')
		exit = action.get('exit')
		fullscreen = action.get('fullscreen')
		confirm = action.get('confirm')
		cancel = action.get('cancel')
		wait = action.get('wait')

		player_turn_results = []

		# update
		if move and game_state == GameState.PLAYERS_TURN:
			dx, dy = move # saves dx and dy outside of the while loop too
			dest_x = player.x + dx
			dest_y = player.y + dy

			if not game_world.currmap.tileblocked(dest_x, dest_y):
				target = get_blocking_entities_at_location(
					entities, dest_x, dest_y)

				if target:
					if target.door:
						game_world.movetonextroom(player, entities, 
							target.door.direction)
						fov_map = initialize_fov(game_world.currmap)
						fov_recompute = True
						con.clear(fg=(0, 0, 0))
					elif target.stairs:
						game_world.movetonextfloor(player, entities)
						fov_map = initialize_fov(game_world.currmap)
						fov_recompute = True
						con.clear(fg=(0, 0, 0))
					elif target.fighter:
						attack_results = player.fighter.attacktarget(
							target, player.fighter.attacks[0])
						player_turn_results.extend(attack_results)
				else:
					player.move(dx, dy)
					fov_recompute = True

				if (game_state == GameState.PLAYERS_TURN):
					game_state = GameState.ENEMY_TURN

		if wait and game_state == GameState.PLAYERS_TURN:
			game_state = GameState.ENEMY_TURN

		if exit:
			return True

		if fullscreen:
			libtcod.console_set_fullscreen(
				not libtcod.console_is_fullscreen())

		for player_turn_result in player_turn_results:
			message = player_turn_result.get('message')
			dead_entity = player_turn_result.get('dead')

			if message:
				message_log.add_message(message)

			if dead_entity:
				if dead_entity == player:
					message, game_state = kill_player(dead_entity)
				else:
					if (dead_entity.char == '@'):
						# dead boss, spawn stairs, update world
						game_world.bosses_cleared[game_world.current_floor] = True
						entities.extend(
							game_world.currmap.spawnstairsdown())
					message = kill_monster(dead_entity)

				message_log.add_message(message)

		if game_state == GameState.ENEMY_TURN:
			for entity in entities:
				if entity.ai:
					enemy_turn_results = entity.ai.take_turn(
						game_world.currmap, entities)

					for enemy_turn_result in enemy_turn_results:
						message = enemy_turn_result.get('message')
						dead_entity = enemy_turn_result.get('dead')

						if message:
							message_log.add_message(message)

						if dead_entity:
							if dead_entity == player:
								message, game_state = kill_player(dead_entity)
							else:
								if (dead_entity.char == '@'):
									# dead boss, spawn stairs, update world
									game_world.bosses_cleared[game_world.current_floor] = True
									entities.extend(
										game_world.currmap.spawnstairsdown())
								message = kill_monster(dead_entity)

							message_log.add_message(message)

							if game_state == GameState.PLAYER_DEAD:
								break

					if game_state == GameState.PLAYER_DEAD:
						break
			else:
				game_state = GameState.PLAYERS_TURN
def play_game(player, entities, game_map, message_log, game_state, con, panel,
              constants):
    fov_recompute = True

    fov_map = initialize_fov(game_map)

    key = libtcod.Key()
    mouse = libtcod.Mouse()

    if not game_state == GameStates.PLAYER_DEAD:
        game_state = GameStates.PLAYERS_TURN

    begin_player_turn = True

    previous_game_state = game_state

    targeting_item = None

    if not game_state == GameStates.PLAYER_DEAD:
        PLAYERDEADSTATE = False
    else:
        PLAYERDEADSTATE = True

    while not libtcod.console_is_window_closed():
        libtcod.sys_check_for_event(
            libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse)

        if fov_recompute:
            recompute_fov(fov_map, player.x, player.y, constants['fov_radius'],
                          constants['fov_light_walls'],
                          constants['fov_algorithm'])

        render_all(con, panel, entities, player, game_map, fov_map,
                   fov_recompute, message_log, constants['screen_width'],
                   constants['screen_height'], constants['bar_width'],
                   constants['panel_height'], constants['panel_y'], mouse,
                   constants['colors'], constants['kill_count'], game_state,
                   constants['wall_tile'], constants['floor_tile'])

        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities)

        action = handle_keys(key, game_state)
        mouse_action = handle_mouse(mouse)

        move = action.get('move')
        wait = action.get('wait')
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        drop_equipment = action.get('drop_equipment')
        show_equipment_inventory = action.get('show_equipment_inventory')
        show_bag = action.get('show_bag')
        inventory_index = action.get('inventory_index')
        equipment_inventory_index = action.get('equipment_inventory_index')
        take_stairs = action.get('take_stairs')
        level_up = action.get('level_up')
        show_character_screen = action.get('show_character_screen')
        show_help_menu = action.get('show_help_menu')
        exit = action.get('exit')
        exit_quit_menu = action.get('exit_quit_menu')
        fullscreen = action.get('fullscreen')
        cast_magic_wand = action.get('cast_magic_wand')
        shoot_bow = action.get('shoot_bow')
        drop_menu = action.get('drop_menu')
        sell_menu = action.get('sell_menu')
        sell_equipment_menu = action.get('sell_equipment_menu')
        buy_menu = action.get('buy_menu')
        buy_equipment_menu = action.get('buy_equipment_menu')
        shop_menu = action.get('shop_menu')
        shop_menu_index = action.get('shop_menu_index')
        shop_equipment_menu_index = action.get('shop_equipment_menu_index')

        left_click = mouse_action.get('left_click')
        right_click = mouse_action.get('right_click')

        player_turn_results = []

        if begin_player_turn and game_state == GameStates.PLAYERS_TURN:
            begin_player_turn = False

            if player.fighter.status:
                player_turn_results.extend(player.fighter.status.update())

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target:
                    attack_results = player.fighter.attack(target,
                                                           constants,
                                                           entities=entities)
                    #playsound('sounds/attack.m4a', block=False)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)

                    fov_recompute = True

                game_state = GameStates.ENEMY_TURN

        elif wait:
            game_state = GameStates.ENEMY_TURN

        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.item and (
                        not entity.equippable
                ) and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)

                    break

                elif entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.equipment_inventory.add_item(
                        entity)
                    player_turn_results.extend(pickup_results)

                    break
            else:
                message_log.add_message(
                    Message("There is nothing here to pick up...",
                            libtcod.yellow))

        if show_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if show_equipment_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_EQUIPMENT_INVENTORY

        if drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if drop_equipment:
            previous_game_state = game_state
            game_state = GameStates.DROP_EQUIPMENT

        if show_bag:
            previous_game_state = game_state
            game_state = GameStates.SHOW_BAG

        if drop_menu:
            previous_game_state = game_state
            game_state = GameStates.DROP_MENU

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                player.inventory.items):
            item = player.inventory.items[inventory_index]

            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(
                    player.inventory.use(item,
                                         entities=entities,
                                         fov_map=fov_map))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(player.inventory.drop_item(item))
            elif game_state == GameStates.SELL_MENU:
                player_turn_results.extend(
                    player.inventory.sell(item, game_state))

        if equipment_inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and equipment_inventory_index < len(
                player.equipment_inventory.items):
            equip_item = player.equipment_inventory.items[
                equipment_inventory_index]

            if game_state == GameStates.SHOW_EQUIPMENT_INVENTORY:
                player_turn_results.extend(
                    player.equipment_inventory.use(equip_item))
            elif game_state == GameStates.DROP_EQUIPMENT:
                player_turn_results.extend(
                    player.equipment_inventory.drop_item(equip_item))
            elif game_state == GameStates.SELL_EQUIPMENT_MENU:
                player_turn_results.extend(
                    player.equipment_inventory.sell(equip_item, game_state))

        if shop_menu_index is not None and previous_game_state != GameStates.PLAYER_DEAD:
            item = game_map.shop_items[shop_menu_index]

            if game_state == GameStates.BUY_MENU:
                player_turn_results.extend(
                    player.inventory.buy(item, game_state))

        if shop_equipment_menu_index is not None and previous_game_state != GameStates.PLAYER_DEAD:
            item = game_map.shop_equipment_items[shop_equipment_menu_index]

            if game_state == GameStates.BUY_EQUIPMENT_MENU:
                player_turn_results.extend(
                    player.equipment_inventory.buy(item, game_state))

        if take_stairs and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.stairs and entity.x == player.x and entity.y == player.y:
                    entities = game_map.next_floor(player, message_log,
                                                   constants)
                    fov_map = initialize_fov(game_map)
                    fov_recompute = True
                    libtcod.console_clear(con)

                    break
            else:
                message_log.add_message(
                    Message("There are no stairs here...", libtcod.yellow))

        if cast_magic_wand and game_state == GameStates.PLAYERS_TURN:
            wand = player.inventory.search("Magic Wand")
            staff = player.inventory.search("Wizard Staff")
            if wand is None and staff is None:
                message_log.add_message(
                    Message("You cannot cast magic without a magic item!",
                            libtcod.orange))
            else:
                player_turn_results.extend(
                    player.inventory.use(wand,
                                         entities=entities,
                                         fov_map=fov_map))

                game_state = GameStates.ENEMY_TURN

        if shoot_bow and game_state == GameStates.PLAYERS_TURN:
            bow = player.inventory.search("Long Bow")
            arrow = player.inventory.search("Arrow")
            if bow is None and arrow is None:
                message_log.add_message(
                    Message(
                        "You don't have anything to shoot with at this time!",
                        libtcod.orange))
            elif bow is None and arrow is not None:
                message_log.add_message(
                    Message("You cannot shoot an arrow without a bow!",
                            libtcod.orange))
            elif bow is not None and arrow is None:
                message_log.add_message(
                    Message("You need arrows to use your bow", libtcod.orange))
            else:
                player_turn_results.extend(
                    player.inventory.use(bow,
                                         entities=entities,
                                         fov_map=fov_map))

                game_state = GameStates.ENEMY_TURN

        if level_up:
            if level_up == 'hp':
                player.fighter.base_max_hp += 20
                player.fighter.hp += 20
                message_log.add_message(
                    Message("You leveled up your HP!", libtcod.light_cyan))
            elif level_up == 'str':
                player.fighter.base_power += 1
                message_log.add_message(
                    Message("You leveled up your ATTACK!", libtcod.light_cyan))
            elif level_up == 'def':
                player.fighter.base_defense += 1
                message_log.add_message(
                    Message("You leveled up your DEFENSE!",
                            libtcod.light_cyan))
            elif level_up == 'mgk':
                player.fighter.base_magic += 1
                message_log.add_message(
                    Message("You leveled up your MAGIC!", libtcod.light_cyan))
            elif level_up == 'mgk_def':
                player.fighter.base_magic_defense += 1
                message_log.add_message(
                    Message("You leveled up your MAGIC RESISTANCE!",
                            libtcod.light_cyan))

            game_state = previous_game_state

        if show_character_screen:
            previous_game_state = game_state
            game_state = GameStates.CHARACTER_SCREEN

        if show_help_menu:
            previous_game_state = game_state
            game_state = GameStates.HELP_MENU

        if sell_menu:
            previous_game_state = game_state
            game_state = GameStates.SELL_MENU

        if sell_equipment_menu:
            previous_game_state = game_state
            game_state = GameStates.SELL_EQUIPMENT_MENU

        if buy_menu:
            previous_game_state = game_state
            game_state = GameStates.BUY_MENU

        if buy_equipment_menu:
            previous_game_state = game_state
            game_state = GameStates.BUY_EQUIPMENT_MENU

        if shop_menu:
            previous_game_state = game_state
            game_state = GameStates.SHOP_MENU

        if game_state == GameStates.TARGETING:
            if left_click:
                target_x, target_y = left_click

                item_use_results = player.inventory.use(targeting_item,
                                                        entities=entities,
                                                        fov_map=fov_map,
                                                        target_x=target_x,
                                                        target_y=target_y)
                player_turn_results.extend(item_use_results)
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})

        if exit:
            if game_state in (GameStates.SHOW_INVENTORY,
                              GameStates.DROP_INVENTORY,
                              GameStates.DROP_EQUIPMENT,
                              GameStates.CHARACTER_SCREEN,
                              GameStates.HELP_MENU,
                              GameStates.SHOW_EQUIPMENT_INVENTORY,
                              GameStates.SELL_MENU, GameStates.BUY_MENU,
                              GameStates.SELL_EQUIPMENT_MENU,
                              GameStates.BUY_EQUIPMENT_MENU):
                game_state = previous_game_state
            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
            elif game_state == GameStates.SHOW_BAG:
                if PLAYERDEADSTATE == True:
                    game_state = GameStates.PLAYER_DEAD
                else:
                    game_state = GameStates.PLAYERS_TURN
            elif game_state == GameStates.SHOP_MENU:
                if PLAYERDEADSTATE == True:
                    game_state = GameStates.PLAYER_DEAD
                else:
                    game_state = GameStates.PLAYERS_TURN
            elif game_state == GameStates.PLAYERS_TURN:
                game_state = GameStates.QUIT_MENU
            elif game_state == GameStates.DROP_MENU:
                game_state = GameStates.PLAYERS_TURN
            else:
                save_game(player, entities, game_map, message_log, game_state)

                return True

        if exit_quit_menu:
            if game_state == GameStates.QUIT_MENU:
                game_state = previous_game_state

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            equipment_item_added = player_turn_result.get(
                'equipment_item_added')
            item_consumed = player_turn_result.get('consumed')
            equipment_consumed = player_turn_result.get('equipment_consumed')
            item_dropped = player_turn_result.get('item_dropped')
            loot_dropped = player_turn_result.get('loot_dropped')
            staff_used = player_turn_result.get('staff_used')
            equip = player_turn_result.get('equip')
            targeting = player_turn_result.get('targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')
            xp = player_turn_result.get('xp')
            item_bought = player_turn_result.get('item_bought')
            equipment_bought = player_turn_result.get('equipment_bought')
            end_turn = player_turn_result.get('end_turn')

            if message:
                message_log.add_message(message)

            if targeting_cancelled:
                game_state = previous_game_state

                message_log.add_message(Message('Targeting cancelled'))

            if xp:
                leveled_up = player.level.add_xp(xp)
                message_log.add_message(
                    Message("You gain {0} experience points.".format(xp)))

                if leveled_up:
                    message_log.add_message(
                        Message(
                            "Your battle prowess grows stronger! You reached level {0}!"
                            .format(player.level.current_level),
                            libtcod.yellow))
                    previous_game_state = game_state
                    game_state = GameStates.LEVEL_UP

            if dead_entity:
                if dead_entity == player:
                    PLAYERDEADSTATE = True
                    message, game_state = kill_player(dead_entity, constants)
                    message_log.add_message(message)
                else:
                    monster_name = ''
                    monster_name = dead_entity.name
                    message = kill_monster(dead_entity, player, constants)
                    constants['kill_count'] += 1
                    message_log.add_message(message)

                    while dead_entity.equipment_inventory.items:
                        item = dead_entity.equipment_inventory.items[0]
                        dead_entity.equipment_inventory.loot_item(item)
                        entities.append(item)
                        message_log.add_message(
                            Message(
                                "The {0} dropped the {1}.".format(
                                    monster_name, item.name), libtcod.yellow))

                    while dead_entity.inventory.items:
                        item = dead_entity.inventory.items[0]
                        dead_entity.inventory.loot_item(item)
                        entities.append(item)
                        message_log.add_message(
                            Message(
                                "The {0} dropped the {1}.".format(
                                    monster_name, item.name), libtcod.yellow))

            if item_added:
                entities.remove(item_added)

                game_state = GameStates.ENEMY_TURN

            if equipment_item_added:
                entities.remove(equipment_item_added)

                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                game_state = GameStates.ENEMY_TURN

            if item_bought:
                game_map.shop_items.remove(item_bought)

                game_state = GameStates.ENEMY_TURN

            if equipment_bought:
                game_map.shop_equipment_items.remove(equipment_bought)

                game_state = GameStates.ENEMY_TURN

            if equipment_consumed:
                game_state = GameStates.ENEMY_TURN

            if staff_used:
                game_state = GameStates.ENEMY_TURN

            if end_turn:
                game_state = GameStates.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING

                targeting_item = targeting

                message_log.add_message(targeting_item.item.targeting_message)

            if item_dropped:
                entities.append(item_dropped)

                game_state = GameStates.ENEMY_TURN

            if loot_dropped:
                entities.append(loot_dropped)

                game_state = GameStates.ENEMY_TURN

            if equip:
                equip_results = player.equipment.toggle_equip(equip)

                for equip_result in equip_results:
                    equipped = equip_result.get('equipped')
                    dequipped = equip_result.get('dequipped')

                    if equipped:
                        message_log.add_message(
                            Message("You equipped the {0}".format(
                                equipped.name)))

                    if dequipped:
                        message_log.add_message(
                            Message("You dequipped the {0}".format(
                                dequipped.name)))

                game_state = GameStates.ENEMY_TURN

        if game_state == GameStates.ENEMY_TURN:
            fov_recompute = True
            for entity in entities:
                if entity.ai:
                    if entity.fighter.status:
                        entity.fighter.status.update()

                    enemy_turn_results = entity.ai.take_turn(
                        player, fov_map, game_map, entities, constants)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

                        if dead_entity:
                            if dead_entity == player:
                                PLAYERDEADSTATE = True
                                message, game_state = kill_player(
                                    dead_entity, constants)
                                message_log.add_message(message)
                            else:
                                monster_name = ''
                                monster_name = dead_entity.name
                                message = kill_monster(dead_entity, player,
                                                       constants)
                                constants['kill_count'] += 1
                                message_log.add_message(message)

                                while dead_entity.equipment_inventory.items:
                                    item = dead_entity.equipment_inventory.items[
                                        0]
                                    dead_entity.equipment_inventory.loot_item(
                                        item)
                                    entities.append(item)
                                    message_log.add_message(
                                        Message(
                                            "The {0} dropped the {1}.".format(
                                                monster_name, item.name),
                                            libtcod.yellow))

                                while dead_entity.inventory.items:
                                    item = dead_entity.inventory.items[0]
                                    dead_entity.inventory.loot_item(item)
                                    entities.append(item)
                                    message_log.add_message(
                                        Message(
                                            "The {0} dropped the {1}.".format(
                                                monster_name, item.name),
                                            libtcod.yellow))

                            if game_state == GameStates.PLAYER_DEAD:
                                break
                    if game_state == GameStates.PLAYER_DEAD:
                        break
            else:
                game_state = GameStates.PLAYERS_TURN
                begin_player_turn = True
Exemple #29
0
def main():
    screen_width = 80
    screen_height = 50
    map_width = 80
    map_height = 45
    room_max_size = 10
    room_min_size = 6
    max_rooms = 30

    fov_algorithm = 0
    fov_light_walls = True
    fov_radius = 10

    max_monsters_per_room = 3

    colors = {
        'light_wall': libtcod.Color(82, 53, 52),
        'light_ground': libtcod.Color(82, 81, 52),
        'dark_wall': libtcod.Color(39, 40, 57),
        'dark_ground': libtcod.Color(50, 54, 87)
    }

    fighter_component = Fighter(hp=30, defense=2, power=5)
    player = Entity(0,
                    0,
                    '@',
                    libtcod.white,
                    'Player',
                    blocks=True,
                    fighter=fighter_component)
    entities = [player]

    libtcod.console_set_custom_font(
        'resources/arial10x10.png',
        libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)

    libtcod.console_init_root(screen_width,
                              screen_height,
                              'pyrogue',
                              False,
                              libtcod.RENDERER_SDL2,
                              vsync=True)

    con = libtcod.console.Console(screen_width, screen_height)

    game_map = GameMap(map_width, map_height)
    game_map.make_map(max_rooms, room_min_size, room_max_size, map_width,
                      map_height, player, entities, max_monsters_per_room)

    fov_recompute = True
    fov_map = initialize_fov(game_map)

    game_state = GameStates.PLAYERS_TURN

    while True:

        if fov_recompute:
            recompute_fov(fov_map, player.x, player.y, fov_radius,
                          fov_light_walls, fov_algorithm)

        render_all(con, entities, game_map, fov_map, fov_recompute,
                   screen_width, screen_height, colors)
        fov_recompute = False
        libtcod.console_flush()
        clear_all(con, entities, fov_map)

        for event in tcod.event.wait():
            if event.type == "QUIT":
                raise SystemExit()
            elif event.type == "KEYDOWN":
                action = handle_keys(event)

                move = action.get('move')
                exit = action.get('exit')
                fullscreen = action.get('fullscreen')

                if move and game_state == GameStates.PLAYERS_TURN:
                    dx, dy = move
                    destination_x = player.x + dx
                    destination_y = player.y + dy
                    if not game_map.is_blocked(destination_x, destination_y):
                        target = get_blocking_entities_at_location(
                            entities, destination_x, destination_y)

                        if target:
                            print('You kick the ' + target.name +
                                  ' in the shins, much to its annoyance!')
                        else:
                            player.move(dx, dy)
                            fov_recompute = True

                        game_state = GameStates.ENEMY_TURN

                if exit:
                    return True

                if fullscreen:
                    libtcod.console_set_fullscreen(
                        not libtcod.console_is_fullscreen())

                if game_state == GameStates.ENEMY_TURN:
                    for entity in entities:
                        if entity.ai:
                            entity.ai.take_turn()

                    game_state = GameStates.PLAYERS_TURN
Exemple #30
0
def play_game(player, entities, game_map, message_log, game_state, con,
              message_panel, char_info_panel, area_info_panel,
              under_mouse_panel, constants, floor_index, original_entity_index,
              entity_index, fov_index):
    fov_recompute = True
    fov_map = initialize_fov(game_map)
    key = libtcod.Key()
    mouse = libtcod.Mouse()

    game_state = GameStates.PLAYERS_TURN
    previous_game_state = game_state

    mouse_x = mouse.cx
    old_mouse_x = mouse_x

    mouse_y = mouse.cy
    old_mouse_y = mouse_y

    #attack_animation_x = 0
    #attack_animation_y = 0

    clean_map = False

    #attacked = False

    #animation_time = 200
    #animation_distance = 0

    targeting_item = None

    equipment_choice = 0

    npc = None

    item = None

    while not libtcod.console_is_window_closed():
        libtcod.sys_check_for_event(
            libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse)
        """
		if animation_time == 0:
			if attacked:
				animation_distance += 1
			animation_time = 200

		if animation_distance == 5:
			animation_distance = 0
			attacked = False
		"""

        if clean_map == True:
            fov_recompute = True
            clean_map = False

        if fov_recompute:
            recompute_fov(fov_map, player.x, player.y, constants['fov_radius'],
                          constants['fov_light_walls'],
                          constants['fov_algorithm'])

        render_all(con, message_panel, char_info_panel, area_info_panel,
                   under_mouse_panel, entities, player, game_map, fov_map,
                   fov_recompute, message_log, constants['screen_width'],
                   constants['screen_height'], constants['bar_width'],
                   constants['panel_height'], constants['panel_y'], mouse,
                   constants['tiles'], constants['colors'], game_state, npc,
                   targeting_item, item, equipment_choice)

        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities, fov_map, game_map)

        action = handle_keys(key, game_state)
        mouse_action = handle_mouse(mouse)

        ############################################
        if game_state == GameStates.EQUIPMENT_SCREEN and not action.get(
                'exit'):
            for equipment in action:
                if equipment:
                    equipment_choice = equipment
                    break

        ############################################

        move = action.get('move')
        ranged_attack = action.get('ranged_attack')
        interact = action.get('interact')
        inspect_item = action.get('inspect_item')
        wait = action.get('wait')
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        inventory_index = action.get('inventory_index')
        take_stairs = action.get('take_stairs')
        level_up = action.get('level_up')
        show_character_screen = action.get('show_character_screen')
        show_equipment_screen = action.get('show_equipment_screen')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')

        left_click = mouse_action.get('left_click')
        right_click = mouse_action.get('right_click')

        player_turn_results = []

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target and not target.invulnerable:
                    attack_results = player.combat_class.attack(target)
                    player_turn_results.extend(attack_results)

                    clean_map = True

                elif not target:
                    player.move(dx, dy)

                    if player.combat_class.turns_until_rest == 0:
                        pass
                    else:
                        player.combat_class.turns_until_rest -= 1

                    fov_recompute = True

                game_state = GameStates.ENEMY_TURN

        elif move and game_state == GameStates.INTERACT:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destination_x, destination_y):
                blocking_target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)
                non_blocking_target = get_non_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if blocking_target:
                    try:
                        if blocking_target.dialogue.dialogue:
                            npc = blocking_target
                    except (AttributeError):
                        pass
                    if blocking_target.bonfire is not None:
                        message_log.add_message(
                            Message(
                                'You see a mysterious bonfire. You cannot resist touching it',
                                libtcod.light_violet))
                        entity_index = blocking_target.bonfire.reset_entities(
                            game_map, original_entity_index, entity_index)
                        game_state = GameStates.PLAYERS_TURN
                    else:
                        message_log.add_message(
                            Message('You see {0}'.format(blocking_target.name),
                                    libtcod.white))

                elif non_blocking_target:
                    message_log.add_message(
                        Message('You see {0}'.format(non_blocking_target.name),
                                libtcod.white))

                else:
                    message_log.add_message(
                        Message('There is nothing to inspect here.',
                                libtcod.white))

        elif wait:
            if player.combat_class.turns_until_rest == 0:
                pass
            else:
                player.combat_class.turns_until_rest -= 1

            message = player.combat_class.rest()
            message_log.add_message(Message(message, libtcod.green))
            game_state = GameStates.ENEMY_TURN

        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)

                    break
            else:
                message_log.add_message(
                    Message('There is nothing here to pick up.',
                            libtcod.white))

        if show_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if interact:
            previous_game_state = GameStates.PLAYERS_TURN
            game_state = GameStates.INTERACT
            message_log.add_message(Message('You begin to look around.'))

        if ranged_attack:
            if player.equipment.main_hand.equippable.ranged:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING
                message_log.add_message(Message('Choose a target to attack.'))
            else:
                message_log.add_message(
                    Message('This weapon cannot attack at range.'))

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and \
         inventory_index < len(player.inventory.items):
            item = player.inventory.items[inventory_index]

            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(
                    player.inventory.use(item,
                                         entities=entities,
                                         fov_map=fov_map))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(player.inventory.drop_item(item))

            elif game_state == GameStates.CHOOSE_ITEM_TO_INSPECT:
                previous_game_state = GameStates.CHOOSE_ITEM_TO_INSPECT
                game_state = GameStates.INSPECT_ITEM
                message_log.add_message(
                    Message('You inspect the {0}.'.format(item.name)))

        if take_stairs and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.stairs and entity.x == player.x and entity.y == player.y:
                    if entity.name == 'Stairs Down':
                        if len(floor_index) == game_map.dungeon_level:
                            entities = game_map.new_floor(
                                player, message_log, constants)
                            fov_map = initialize_fov(game_map)
                            floor_index.append(game_map.tiles)
                            entity_index.append(entities)
                            original_entity_index.append(entities)
                            fov_index.append(fov_map)
                            fov_recompute = True
                            libtcod.console_clear(con)
                            break

                        elif len(floor_index) > game_map.dungeon_level:
                            # Update the entity index with the floors NEW entity list
                            entity_index[game_map.dungeon_level - 1] = entities
                            entities, player, fov_map = game_map.next_floor(
                                player, entity_index, floor_index, fov_index,
                                message_log, constants)
                            fov_recompute = True
                            libtcod.console_clear(con)
                            break

                    elif entity.name == 'Stairs Up':
                        entity_index[game_map.dungeon_level - 1] = entities
                        entities, player, fov_map = game_map.previous_floor(
                            player, entity_index, floor_index, fov_index,
                            message_log, constants)
                        fov_recompute = True
                        libtcod.console_clear(con)
                        break

            else:
                message_log.add_message(
                    Message('There are no stairs here.', libtcod.yellow))

        if level_up:
            if level_up == 'str':
                player.combat_class.base_strength += 1
            elif level_up == 'dex':
                player.combat_class.base_dexterity += 1
            elif level_up == 'sta':
                player.combat_class.base_stamina += 1
            elif level_up == 'int':
                player.combat_class.base_intelligence += 1

            game_state = previous_game_state

        if show_character_screen:
            previous_game_state = game_state
            game_state = GameStates.CHARACTER_SCREEN

        if show_equipment_screen:
            previous_game_state = game_state
            game_state = GameStates.EQUIPMENT_SCREEN

        if game_state == GameStates.TARGETING:
            mouse_x = mouse.cx
            mouse_y = mouse.cy

            if (old_mouse_y != mouse_y
                    or old_mouse_x != mouse_x) and libtcod.map_is_in_fov(
                        fov_map, mouse_x, mouse_y):
                fov_recompute = True
            elif libtcod.map_is_in_fov(
                    fov_map, old_mouse_x,
                    old_mouse_y) and not libtcod.map_is_in_fov(
                        fov_map, mouse_x, mouse_y):
                clean_map = True

            old_mouse_x = mouse_x
            old_mouse_y = mouse_y
            if left_click and targeting_item != None:
                target_x, target_y = left_click

                item_use_results = player.inventory.use(targeting_item,
                                                        entities=entities,
                                                        fov_map=fov_map,
                                                        target_x=target_x,
                                                        target_y=target_y)
                player_turn_results.extend(item_use_results)
                fov_recompute = True

            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})
                fov_recompute = True

            elif left_click and targeting_item == None:
                target_x, target_y = left_click
                if not game_map.tiles[target_x][target_y].blocked:
                    target = get_blocking_entities_at_location(
                        entities, target_x, target_y)
                else:
                    message_log.add_message(
                        Message('You can\'t attack that.', libtcod.yellow))

                if target and not target.invulnerable:
                    attack_results = player.combat_class.attack(target)
                    player_turn_results.extend(attack_results)
                    fov_recompute = True
                    game_state = GameStates.ENEMY_TURN

        if game_state == GameStates.SHOW_INVENTORY:
            if inspect_item:
                previous_game_state = game_state
                game_state = GameStates.CHOOSE_ITEM_TO_INSPECT
                message_log.add_message(
                    Message('Choose an item to inspect.', libtcod.yellow))

        if game_state == GameStates.EQUIPMENT_SCREEN:
            if equipment_choice:
                previous_game_state = game_state
                game_state = GameStates.EQUIPMENT_DETAILS

        if exit:
            if game_state in (GameStates.SHOW_INVENTORY,
                              GameStates.DROP_INVENTORY,
                              GameStates.CHARACTER_SCREEN,
                              GameStates.INTERACT):
                if game_state == (GameStates.INTERACT):
                    player_turn_results.append({'interacting_cancelled': True})
                    game_state = previous_game_state
                    npc = None
                else:
                    game_state = previous_game_state

            elif game_state == GameStates.CHOOSE_ITEM_TO_INSPECT:
                game_state = GameStates.SHOW_INVENTORY
                previous_game_state = GameStates.PLAYERS_TURN
                message_log.add_message(
                    Message('Item inspection cancelled.', libtcod.yellow))

            elif game_state == GameStates.INSPECT_ITEM:
                game_state = previous_game_state

            elif game_state == GameStates.EQUIPMENT_SCREEN:
                game_state = GameStates.PLAYERS_TURN

            elif game_state == GameStates.EQUIPMENT_DETAILS:
                game_state = previous_game_state
                equipment_choice = False

            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
                game_state = previous_game_state
                fov_recompute = True

            else:
                libtcod.console_clear(0)
                save_game(player, entities, game_map, message_log, game_state,
                          floor_index, original_entity_index, entity_index,
                          fov_index)

                return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            item_consumed = player_turn_result.get('consumed')
            item_dropped = player_turn_result.get('item_dropped')
            equip = player_turn_result.get('equip')
            targeting = player_turn_result.get('targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')
            xp = player_turn_result.get('xp')
            interacting_cancelled = player_turn_result.get(
                'interacting_cancelled')

            if message:
                message_log.add_message(message)

            if dead_entity:
                if dead_entity == player:
                    message, game_state = kill_player(dead_entity)
                else:
                    dead_entity.alive = False
                    message = kill_monster(dead_entity)

                message_log.add_message(message)

            if item_added:
                entities.remove(item_added)
                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                game_state = GameStates.ENEMY_TURN

            if equip:
                equip_results = player.equipment.toggle_equip(equip)

                for equip_result in equip_results:
                    equipped = equip_result.get('equipped')
                    unequipped = equip_result.get('unequipped')

                    if equipped:
                        message_log.add_message(
                            Message('You equipped the {0}.'.format(
                                equipped.name)))

                    if unequipped:
                        message_log.add_message(
                            Message('You unequipped the {0}.'.format(
                                unequipped.name)))

                game_state = GameStates.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING

                targeting_item = targeting

                message_log.add_message(targeting_item.item.targeting_message)

            if targeting_cancelled:
                game_state = previous_game_state
                message_log.add_message(Message('Targeting cancelled.'))

            if interacting_cancelled:
                game_state = previous_game_state
                message_log.add_message(Message('You stop looking around.'))

            if xp:
                leveled_up = player.level.add_xp(xp)
                message_log.add_message(
                    Message('You gain {0} experience points.'.format(xp),
                            libtcod.lighter_yellow))

                if leveled_up:
                    message_log.add_message(
                        Message(
                            'Your skills grow more honed. You reach level {0}'.
                            format(player.level.current_level) + "!",
                            libtcod.yellow))
                    previous_game_state = game_state
                    game_state = GameStates.LEVEL_UP

            if item_dropped:
                entities.append(item_dropped)
                game_state = GameStates.ENEMY_TURN

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.ai:
                    if wait:
                        enemy_turn_results = entity.ai.approach_player_on_wait(
                            player, fov_map, game_map, entities)
                    else:
                        enemy_turn_results = entity.ai.take_turn(
                            player, fov_map, game_map, entities)

                        for enemy_turn_result in enemy_turn_results:
                            message = enemy_turn_result.get('message')
                            dead_entity = enemy_turn_result.get('dead')

                            if message:
                                message_log.add_message(message)

                            if dead_entity:
                                if dead_entity == player:
                                    message, game_state = kill_player(
                                        dead_entity)
                                else:
                                    message = kill_monster(dead_entity)

                                message_log.add_message(message)

                                if game_state == GameStates.PLAYER_DEAD:
                                    break

                    if game_state == GameStates.PLAYER_DEAD:
                        break
            else:
                game_state = GameStates.PLAYERS_TURN
Exemple #31
0
def main():
    #initialize constants, game variables, fov, message log, and font
    const = get_constants()
    player, entities, game_map, fov_recompute, fov_map, message_log, hp_regen_tick, mp_regen_tick = get_game_variables(
        const)

    # font from: http://rogueliketutorials.com/tutorials/tcod/part-0/
    tcod.console_set_custom_font(
        'arial10x10.png', tcod.FONT_TYPE_GREYSCALE | tcod.FONT_LAYOUT_TCOD)

    #sets game state to be players turn to begin with
    game_state = GameStates.PLAYERS_TURN

    # main game loop. Root console being created in context with 'with' so that it closes nicely instead of freezing and crashing
    with tcod.console_init_root(const['screen_width'],
                                const['screen_height'],
                                const['window_title'],
                                fullscreen=False,
                                order='F',
                                vsync=True) as root_console:
        # initializes main console and console for UI elements
        con = tcod.console.Console(const['screen_width'],
                                   const['screen_height'],
                                   order='F')
        panel = tcod.console.Console(const['screen_width'],
                                     const['panel_height'],
                                     order='F')

        # main game loop
        while True:
            # gets user input and sends input events to a handler that returns a dictionary of actions
            for event in tcod.event.wait():
                action = event_dispatcher(event)

            # recomputes fov when necessary
            if (fov_recompute == True):
                recompute_fov(fov_map, player.x, player.y, player.fov_range,
                              const['fov_light_walls'], const['fov_algorithm'])

            # renders whole map on console
            render_all(con, panel, message_log, entities, player, game_map,
                       fov_map, fov_recompute, const['screen_width'],
                       const['screen_height'], const['bar_width'],
                       const['panel_height'], const['panel_y'])
            tcod.console_flush()

            # resets fov_recompute to prevent wasteful computation
            fov_recompute = False

            # clears console to avoid trails when moving
            clear_all(con, entities)

            # gets actions inputted by player from dictionary
            move = action.get('move')
            exit_game = action.get('exit_game')
            fullscreen = action.get('fullscreen')
            restart = action.get('restart')
            take_stairs = action.get('take_stairs')
            toggle_lights = action.get('toggle_lights')
            spell = action.get('spell')

            # player's turn taken only if player gives input
            if (move != None) and (game_state == GameStates.PLAYERS_TURN) and (
                    player.is_dead == False):
                dx, dy = move
                # only move player if the cell is unblocked and moving within the map
                if ((player.x + dx < game_map.width - 1)
                        and (player.y + dy < game_map.height - 1) and
                    (not game_map.is_blocked(player.x + dx, player.y + dy))):
                    # checks for entities that block movement in destination being moved to
                    target = get_blocking_entities_at_location(
                        entities, player.x + dx, player.y + dy)

                    # space is empty so player moves. if player is waiting in place it is treated as a normal move to prevent them from atacking themselves
                    if (target == None) or (dx == 0 and dy == 0):
                        player.move(dx, dy)
                        # only recomputes fov when player moves to avoid unnecessary computation
                        fov_recompute = True
                    # attack target
                    else:
                        player.attack(target, message_log)

                # increments tick by one if the player is below full health/mp. Player must always wait for the full delay after losing hp/mp at max
                if (player.hp < player.max_hp):
                    hp_regen_tick += 1
                if (player.mp < player.max_mp):
                    mp_regen_tick += 1

                # player statically regenerates hp and mp periodically
                if (hp_regen_tick == const['hp_regen_delay']):
                    player.heal(1)
                    hp_regen_tick = 0  # resets tick
                if (mp_regen_tick == const['mp_regen_delay']):
                    player.restore_mp(1)
                    mp_regen_tick = 0  # resets tick

                # resets players fov range in case they have casted flash
                player.fov_range = const['default_fov_radius']

                # passes turn to enemies. this happens even if player walks into a wall
                game_state = GameStates.ENEMY_TURN

            # handles spells
            if (spell != None) and (game_state == GameStates.PLAYERS_TURN
                                    ) and (player.is_dead == False):
                # f key casts a fireball spell that does damage in a radius around the player
                if (spell == 'fireball'):
                    player.cast_fireball(entities, message_log)
                # h key casts cure which heals for a portion of players max hp
                elif (spell == 'cure'):
                    player.cast_cure(message_log)
                # v key casts clairvoyance which reveals position of stairs
                elif (spell == 'clairvoyance'):
                    player.cast_clairvoyance(game_map, message_log)
                # g key casts flash which increases the distance the player can see for a turn
                elif (spell == 'flash'):
                    player.cast_flash(message_log)
                # arrow keys cast in appropriate direction
                elif (spell == 'tunnel_up'):
                    player.cast_tunnel(game_map, fov_map, message_log, 0, -1)
                elif (spell == 'tunnel_down'):
                    player.cast_tunnel(game_map, fov_map, message_log, 0, 1)
                elif (spell == 'tunnel_left'):
                    player.cast_tunnel(game_map, fov_map, message_log, -1, 0)
                elif (spell == 'tunnel_right'):
                    player.cast_tunnel(game_map, fov_map, message_log, 1, 0)

                # increments tick by one if the player is below full health.
                if (player.hp < player.max_hp):
                    hp_regen_tick += 1
                # resets mp regen tick so a player must wait full delay after casting a spell to start mp regen
                mp_regen_tick = 0

                # hp regen unaffected by casting a spell
                if (hp_regen_tick == const['hp_regen_delay']):
                    player.heal(1)
                    hp_regen_tick = 0  # resets tick

                # resets player's fov range unless they cast flash. this makes flash only last one turn
                if (spell != 'flash'):
                    player.fov_range = const['default_fov_radius']

                # recomputes fov since some spells affect the map/fov
                fov_recompute = True

                game_state = GameStates.ENEMY_TURN

            # enemy's turn
            if (game_state == GameStates.ENEMY_TURN):
                # loops through all enemies
                for entity in entities:
                    if (isinstance(entity, Enemy)):
                        # enemy gets a real turn if they are within the players fov, or if they have seen the player
                        if ((fov_map.fov[entity.y, entity.x])
                                or (entity.knows_player_location == True)):
                            # attacks player if they are adjacent or moves towards player using bfs pathfinding algorithm
                            entity.take_turn(player, game_map, entities,
                                             message_log)

                            # enemy will continue to follow the player after being seen for the first time, regardless of fov
                            if entity.knows_player_location == False:
                                entity.knows_player_location = True

                        # enemies outside of fov just move around at random
                        else:
                            entity.random_move(game_map, entities)

                # checks to see if the player died
                if (player.is_dead == True):
                    game_state = GameStates.PLAYER_DEATH
                else:
                    # passes turn back to player even if the enemies didn't do anything
                    game_state = GameStates.PLAYERS_TURN

            # handles death of player
            if (game_state == GameStates.PLAYER_DEATH):
                message_log.add_message(Message('You Lose', tcod.darker_red))

            # takes player to new floor
            if (take_stairs == True) and (player.x == game_map.stairs.x) and (
                    player.y == game_map.stairs.y):
                # makes new floor and resets entities list
                entities = game_map.stairs.take_stairs(player, game_map,
                                                       entities, message_log)

                # resets fov
                fov_map = initialize_fov(game_map)
                fov_recompute = True

                # clears the console to remove the last floor from the screen
                clear_console(con, const['screen_width'],
                              const['screen_height'])

                # player wins if they make it to the 4th floor
                if (game_map.depth == const['winning_floor']):
                    game_state = GameStates.PLAYER_WINS

            # player wins after getting to a set floor
            if game_state == GameStates.PLAYER_WINS:
                message_log.add_message(Message('You Win!', tcod.yellow))

            # restarts game
            if (restart == True):
                # resets everything to beginning state
                const = get_constants()
                player, entities, game_map, fov_recompute, fov_map, message_log, hp_regen_tick, mp_regen_tick = get_game_variables(
                    const)

                # clears the console to remove the last floor from the screen
                clear_console(con, const['screen_width'],
                              const['screen_height'])

                # new game starts with players turn
                game_state = GameStates.PLAYERS_TURN

            # toggles lights to see the whole map for deomonstration
            if (toggle_lights == True):
                game_map.lights_on = not game_map.lights_on
                if game_map.lights_on == False:
                    clear_console(con, const['screen_width'],
                                  const['screen_height'])
                fov_recompute = True

            # breaks loop if player exits
            if (exit_game == True):
                raise SystemExit()

            # toggles fullscreen
            if (fullscreen == True):
                tcod.console_set_fullscreen(not tcod.console_is_fullscreen())