Exemple #1
0
def create_mainhand_item(name, material):
    _bonus = material_dict[material][0]
    _color = material_dict[material][1]
    _name = material.capitalize() + ' ' + name.capitalize()

    _base, _equip, _skill = None, None, None

    if name == 'sword':
        _base = Base(name=_name,
                     char=u'\u2193',
                     color=_color,
                     render_order=RenderOrder.ITEM)

        _profile = {}
        _profile = example_profile()
        _profile['ATK']['ATK'] = 1.8 + _bonus

        _equip = Equippable(slot=Bodyparts.MainHand.name, profile=_profile)

        _profile = {}
        _profile = example_profile()
        _profile['ATK']['ATK'] = 1.6 + _bonus
        _profile['ATK']['MAG'] = 0.2 + _bonus

        _skill = Skill(cooldown=12,
                       name='pierce',
                       nature='direct',
                       profile=_profile)

    if name == 'spear':
        _base = Base(name=_name,
                     char=u'\u2191',
                     color=_color,
                     render_order=RenderOrder.ITEM)

        _profile = {}
        _profile = example_profile()
        _profile['ATK']['ATK'] = 1.2 + _bonus

        _equip = Equippable(slot=Bodyparts.MainHand.name, profile=_profile)

        _profile = {}
        _profile = example_profile()
        _profile['ATK']['ATK'] = 1.6 + _bonus
        _profile['ATK']['SPD'] = 0.2 + _bonus

        _skill = Skill(cooldown=5,
                       name='pierce',
                       nature='direct',
                       profile=_profile)

    return _base, _equip, _skill
class Charm(Skill):
    skill_component = Skill(use_function=cast_charm, hunger_cost=10, skill_targeting=True,
                            targeting_message=Message(
                                'Left-click a target tile to charm them, or right-click to cancel.',
                                libtcod.light_cyan))
    charm = SkillEntity(' ', libtcod.red, 'Charm Enemy', skill=skill_component)

    def use(self, skill_entity, **kwargs):
        results = []

        skill_component = Skill(use_function=cast_charm)

        if skill_component.use_function is None:
            results.append({'message': Message('You cannot use that skill.'.format(skill_entity.name), libtcod.yellow)})
        else:
            if skill_component.skill_targeting and not (kwargs.get('target_x') or kwargs.get('target_y')):
                results.append({'skill_targeting': Skill})
            else:
                kwargs = {**skill_entity.function_kwargs, **kwargs}
                skill_use_results = skill_component.use_function(self.owner, **kwargs)

                for skill_use_result in skill_use_results:
                    if skill_use_result.get('used'):
                       self.remove_skill()

                    results.extend(skill_use_results)

        return results
    def use(self, skill_entity, **kwargs):
        results = []

        skill_component = Skill(use_function=cast_charm)

        if skill_component.use_function is None:
            results.append({'message': Message('You cannot use that skill.'.format(skill_entity.name), libtcod.yellow)})
        else:
            if skill_component.skill_targeting and not (kwargs.get('target_x') or kwargs.get('target_y')):
                results.append({'skill_targeting': Skill})
            else:
                kwargs = {**skill_entity.function_kwargs, **kwargs}
                skill_use_results = skill_component.use_function(self.owner, **kwargs)

                for skill_use_result in skill_use_results:
                    if skill_use_result.get('used'):
                       self.remove_skill()

                    results.extend(skill_use_results)

        return results
Exemple #4
0
def create_offhand_item(name, material):
    _bonus = material_dict[material][0]
    _color = material_dict[material][1]
    _base, _equip, _skill = None, None, None
    _name = material.capitalize() + ' ' + name.capitalize()

    if name == 'buckler':
        _base = Base(name=_name,
                     char=u'\u03C3',
                     color=_color,
                     render_order=RenderOrder.ITEM)
        _equip = Equippable(slot=Bodyparts.OffHand.name)
        _skill = Skill(cooldown=5, name='bash', nature='direct')
        _skill.knockback_force = 2

    if name == 'shield':
        _base = Base(name=_name,
                     char=u'\u0398',
                     color=_color,
                     render_order=RenderOrder.ITEM)
        _equip = Equippable(slot=Bodyparts.OffHand.name)
        _skill = Skill(cooldown=5, name='bash', nature='direct')
        _skill.knockback_force = 4

    return _base, _equip, _skill
Exemple #5
0
    def __init__(self):
        create_wall_comp = Skill(use_function=create_wall,
                                 targeting_skill=True,
                                 targeting_type='single',
                                 targeting_message=Message(
                                     'Select tile to make wall', tcod.cyan))
        create_wall_fact = Fact('Create Wall',
                                'Self explanatory',
                                skill=create_wall_comp)

        break_wall_comp = Skill(use_function=break_wall,
                                targeting_skill=True,
                                targeting_type='single',
                                targeting_message=Message(
                                    'Select tile to destoy wall', tcod.cyan))
        break_wall_fact = Fact('Break Wall',
                               'Self explanatory',
                               skill=break_wall_comp)

        move_wall_comp = Skill(use_function=move_wall,
                               targeting_skill=True,
                               targeting_type='multi',
                               targeting_message=Message(
                                   'Select tile to move wall', tcod.cyan))
        move_wall_fact = Fact('Move Wall',
                              'Self explanatory',
                              skill=move_wall_comp)

        teleport_comp = Skill(use_function=teleport,
                              targeting_skill=True,
                              targeting_type='single',
                              targeting_message=Message(
                                  'Select tile to teleport', tcod.cyan))
        teleport_fact = Fact('Teleport',
                             'Self explanatory',
                             skill=teleport_comp)

        self.skills = [
            create_wall_fact, break_wall_fact, move_wall_fact, teleport_fact
        ]
Exemple #6
0
def create_torso_item(name, material):
    _bonus = material_dict[material][0]
    _color = material_dict[material][1]
    _name = material.capitalize() + ' ' + name.capitalize()

    _base, _equip, _skill = None, None, None

    if name == 'chain mail':
        _base = Base(name=_name,
                     char=u'\u2593',
                     color=_color,
                     render_order=RenderOrder.ITEM)

        _profile = {}
        _profile = example_profile()
        _profile['DEF']['DEF'] = 1.2 + _bonus
        _profile['MAG']['MAG'] = 1.0 + _bonus

        _equip = Equippable(slot=Bodyparts.Torso.name, profile=_profile)

        _skill = Skill()

    if name == 'plate mail':
        _base = Base(name=_name,
                     char=u'\u2588',
                     color=_color,
                     render_order=RenderOrder.ITEM)

        _profile = {}
        _profile = example_profile()
        _profile['DEF']['DEF'] = 1.9 + _bonus
        _profile['MAG']['MAG'] = 0.7 + _bonus

        _equip = Equippable(slot=Bodyparts.Torso.name, profile=_profile)

        _skill = Skill()

    return _base, _equip, _skill
Exemple #7
0
def create_head_item(name, material):
    _bonus = material_dict[material][0]
    _color = material_dict[material][1]
    _name = material.capitalize() + ' ' + name.capitalize()
    _base, _equip, _skill = None, None, None

    if name == 'helm':
        _base = Base(name=_name,
                     char=u'\u00A3',
                     color=_color,
                     render_order=RenderOrder.ITEM)
        _equip = Equippable(slot=Bodyparts.Head.name)
        _skill = Skill()

    if name == 'cap':
        _base = Base(name=_name,
                     char=u'\u207F',
                     color=_color,
                     render_order=RenderOrder.ITEM)
        _equip = Equippable(slot=Bodyparts.Head.name)
        _skill = Skill(cooldown=10, name='healing buff', nature='direct')

    return _base, _equip, _skill
Exemple #8
0
def create_ring_finger_item(name, material):
    _bonus = material_dict[material][0]
    _color = material_dict[material][1]
    _name = material.capitalize() + ' ' + name.capitalize()
    _base, _equip, _skill = None, None, None

    if name == 'ring':
        _base = Base(name=_name,
                     char=u'\u00F6',
                     color=_color,
                     render_order=RenderOrder.ITEM)
        _equip = Equippable(slot=Bodyparts.Head.name)
        _skill = Skill()

    return _base, _equip, _skill
Exemple #9
0
def create_feet_item(name, material):
    _bonus = material_dict[material][0]
    _color = material_dict[material][1]
    _name = material.capitalize() + ' ' + name.capitalize()
    _base, _equip, _skill = None, None, None

    if name == 'boots':
        _base = Base(name=_name,
                     char=u'\u221F',
                     color=_color,
                     render_order=RenderOrder.ITEM)
        _equip = Equippable(slot=Bodyparts.Feet.name)
        _skill = Skill(cooldown=5, name='leap', nature='direct')

    return _base, _equip, _skill
Exemple #10
0
def play_game(player, entities, game_map, message_log, game_state, con, panel,
              constants):
    fov_recompute = True

    fov_map = initialize_fov(game_map)

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

    game_state = GameStates.RACE_SELECTION
    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')
        see_skills = action.get('see_skills')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        inventory_index = action.get('inventory_index')
        skills_index = action.get('skill_index')
        take_stairs = action.get('take_stairs')
        level_up = action.get('level_up')
        job = action.get('job')
        show_character_screen = action.get('show_character_screen')
        race = action.get('race')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')
        job_menu = action.get('job_menu')

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

        player_turn_results = []

        print(game_state)

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

            if player.fighter.status_effects.grace == True:
                player.fighter.nutrition -= 50
            else:
                player.fighter.nutrition -= 1

            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 job_menu:
            game_state = GameStates.JOB_MENU

        if see_skills:
            previous_game_state = game_state
            game_state = GameStates.SKILL_SELECTION

        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 skills_index is not None and previous_game_state != GameStates.PLAYER_DEAD and skills_index < len(
                player.skills.skills):
            item = player.skills.skills[skills_index]

            if game_state == GameStates.SKILL_SELECTION:
                player_turn_results.extend(
                    player.skills.use(item, entities=entities,
                                      fov_map=fov_map))

        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
                elif entity.upstairs and entity.x == player.x and entity.y == player.y:
                    entities = game_map.previous_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 = GameStates.CLASS_SELECTION

        if show_character_screen:
            previous_game_state = game_state
            game_state = GameStates.CHARACTER_SCREEN

        if job:
            if job == 'cleric':
                player.fighter.job.cleric_level += 1
            elif job == 'fighter':
                player.fighter.job.fighter_level += 1
            elif job == 'thief':
                player.fighter.job.thief_level += 1
            elif job == 'wizard':
                player.fighter.job.wizard_level += 1

            game_state = previous_game_state
        if game_state == GameStates.TARGETING:
            if left_click:
                target_x, target_y = left_click
                if targeting_item.skill:
                    item_use_results = player.skills.use(targeting_item,
                                                         entities=entities,
                                                         fov_map=fov_map,
                                                         target_x=target_x,
                                                         target_y=target_y)
                else:
                    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 == GameStates.JOB_MENU:
                game_state = GameStates.CHARACTER_SCREEN
            elif game_state in (GameStates.SHOW_INVENTORY,
                                GameStates.DROP_INVENTORY,
                                GameStates.CHARACTER_SCREEN,
                                GameStates.SKILL_SELECTION):
                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')
            skill_targeting = player_turn_result.get('skill_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 skill_targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING

                targeting_item = skill_targeting

                message_log.add_message(targeting_item.skill.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 race:
            if race == 'mern':
                player.fighter.race = 'Human'
                player.fighter.levels_quickly = True
            elif race == 'elf':
                player.fighter.race = 'Elf'
                player.fighter.base_defense += 2
                player.fighter.base_constitution -= 2
            elif race == 'dwarf':
                player.fighter.race = 'Dwarf'
                player.fighter.base_defense -= 2
                player.fighter.base_constitution += 2
            elif race == 'halfling':
                player.fighter.race = 'Halfling'
                player.fighter.base_defense += 4
                player.fighter.base_power -= 3
                player.fighter.base_constitution -= 1
            elif race == 'gnome':
                player.fighter.race = 'Gnome'
                player.fighter.base_constitution += 2
                player.fighter.base_willpower += 2
                player.fighter.base_power -= 4
            elif race == 'draconian':
                player.fighter.race = 'Draconian'
                player.fighter.large = True
                player.fighter.base_constitution += 3
                player.fighter.base_defense -= 4
                player.fighter.base_power += 3
            elif race == 'orc':
                player.fighter.race = 'Orc'
                player.fighter.base_constitution += 1
                player.fighter.base_defense -= 3
                player.fighter.base_power += 2
            elif race == 'goblin':
                player.fighter.race = 'Goblin'
                player.fighter.base_constitution += 1
                player.fighter.base_defense -= 3
                player.fighter.base_power += 2
            elif race == 'fairy':
                player.fighter.race = 'Fairy'
                player.fighter.base_constitution -= 6
                player.fighter.base_defense += 6
                player.fighter.base_power -= 6
                skill_component = Skill(use_function=become_accurate)
                skill = Skill_Entity('Faerie Dance', skill=skill_component)
                player.skills.add_skill(skill)
            elif race == 'turtle':
                player.fighter.race = 'Giant Turtle'
                player.fighter.base_constitution += 8
                player.fighter.base_defense -= 12
                player.fighter.base_power += 3
                player.fighter.large = True
                player.fighter.cant_wear_armour = True
            elif race == 'lizard':
                player.fighter.race = 'Lizardperson'
                skill_component = Skill(
                    use_function=acid_spit,
                    targeting=True,
                    targeting_message=Message(
                        'Left-click a target tile for the spit, or right-click to cancel.',
                        libtcod.light_cyan),
                    damage=25)
                skill = Skill_Entity('Acid Spit', skill=skill_component)
                player.skills.add_skill(skill)
                player.fighter.base_defense -= 2
                player.fighter.base_power += 3
            elif race == 'frog':
                player.fighter.race = 'Frogperson'
                player.fighter.base_defense += 3
                player.fighter.base_power -= 2
                skill_component = Skill(use_function=become_graceful)
                skill = Skill_Entity('Slimy Skin', skill=skill_component)
                player.skills.add_skill(skill)
            elif race == 'giant':
                player.fighter.race = 'Giant'
                player.fighter.base_defense -= 7
                player.fighter.base_power += 5
                player.fighter.base_constitution += 5
                player.fighter.large = True
            elif race == 'troll':
                player.fighter.race = 'Troll'
                player.fighter.base_defense -= 7
                player.fighter.base_power += 4
                player.fighter.base_constitution += 2
                player.fighter.large = True
                player.fighter.carnivore = True
                player.fighter.sharp_claws = True
            elif race == 'skeleton':
                player.fighter.race = 'Skeleton'
                player.fighter.base_power += 1
                player.fighter.base_constitution += 1
                player.fighter.base_defense -= 4
            elif race == 'biter':
                player.fighter.race = 'Biter'
                player.fighter.base_constitution -= 2
                player.fighter.base_defense += 4
                player.player.fighter.sharp_claws = True
            elif race == 'kobold':
                player.fighter.race = 'Kobold'
                player.fighter.base_power -= 3
                player.fighter.base_defense += 3
                player.fighter.large = True
            elif race == 'chaosling':
                player.fighter.race = 'chaosling'
                player.fighter.base_power += 2
                player.fighter.base_defense += 2
                player.fighter.base_constitution += 2
                player.fighter.base_willpower -= 6
                player.fighter.hates_law = True
            elif race == 'reaper':
                player.fighter.race = 'Reaper'
                player.fighter.base_power += 4
                player.fighter.base_constitution += 2
                player.fighter.base_willpower -= 10
                player.fighter.bloodthirsty = True
            elif race == 'nymph':
                player.fighter.race = 'Nymph'
                player.fighter.base_power -= 5
                player.fighter.base_defense += 5
            elif race == 'octopode':
                player.fighter.race = 'Octopode'
                player.fighter.base_defense += 3
                player.fighter.eight_arms = True
                player.fighter.cant_wear_armour = True
            elif race == 'cat':
                player.fighter.race = 'Housecat'
                player.fighter.base_defense += 6
                player.fighter.base_constitution -= 3
            elif race == 'merfolk':
                player.fighter.race = 'Merfolk'
                player.fighter.swimmer = True
                player.fighter.base_defense += 3
                player.fighter.base_constitution += 3
                player.fighter.base_power -= 4
            elif race == 'mud':
                player.fighter.race = 'Mud Man'
                skill_component = Skill(
                    use_function=throw_mudball,
                    targeting=True,
                    targeting_message=Message(
                        'Left-click a target tile for the ball, or right-click to cancel.',
                        libtcod.light_cyan),
                    damage=25)
                skill = Skill_Entity('Throw Mudball', skill=skill_component)
                player.skills.add_skill(skill)
                player.fighter.base_defense += 3
                player.fighter.base_constitution -= 3
            elif race == 'dryad':
                player.fighter.race = 'Dryad'
                player.fighter.one_with_nature = True
                player.fighter.base_power += 4
                player.fighter.base_defence -= 4
            elif race == 'naga':
                player.fighter.race = 'Naga'
                skill_component = Skill(
                    use_function=poison_bite,
                    targeting=True,
                    targeting_message=Message(
                        'Left-click a target tile for the bite, or right-click to cancel.',
                        libtcod.light_cyan),
                    damage=25)
                skill = Skill_Entity('Naga Bite', skill=skill_component)
                player.skills.add_skill(skill)
                player.fighter.base_defense += 4
                player.fighter.base_power -= 4
                player.fighter.no_legs = True
            elif race == 'golem':
                player.fighter.race = 'Rogue Golem'
                player.fighter.golem = True
                player.fighter.base_defense += 10
                player.fighter.base_power += 10
                player.fighter.base_willpower += 13
            elif race == 'tengu':
                player.fighter.race = 'Tengu'
                player.fighter.base_defense += 4
                player.fighter.base_power -= 2
                player.fighter.base_constitution -= 3
            libtcod.console_flush()
            game_state = GameStates.PLAYERS_TURN

        if game_state == GameStates.ENEMY_TURN:
            if player.fighter.nutrition < 1:
                game_state = GameStates.PLAYER_DEAD
                kill_player(player)

            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 #11
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.CHARACTER_CREATION
    previous_game_state = game_state

    targeting_item = None
    targeting_skill = None
    ggender = Gender.male

    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(player, key, game_state)
        mouse_action = handle_mouse(mouse)

        move = action.get('move')
        wait = action.get('wait')
        pickup = action.get('pickup')
        use_skills = action.get('use_skills')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        inventory_index = action.get('inventory_index')
        skill_index = action.get('skill_index')
        take_stairs = action.get('take_stairs')
        take_upstairs = action.get('take_upstairs')
        level_up = action.get('level_up')
        show_character_screen = action.get('show_character_screen')
        character_creation = action.get('character_creation')
        job = action.get('job')
        gender = action.get('gender')
        skill_selection = action.get('skill_selection')
        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:
            #The starvation variable increases or decreases as the player gets more psyche and gets hungrier.
            libtcod.console_flush()
            starvation_variable = 1
            player.fighter.nutrition -= 1
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if player.fighter.nutrition <= 0:
                kill_player(player)
                game_state = GameStates.PLAYER_DEAD
                message_log.add_message(
                    Message('You have starved to death.', libtcod.red))

            if player.fighter.starvation_bonus >= 20 and player.fighter.psyche <= 5 or player.fighter.psyche == 5:
                starvation_variable = 0
            elif player.fighter.starvation_bonus >= 40 and player.fighter.psyche <= 10 or player.fighter.psyche == 10:
                starvation_variable = 0

            if player.fighter.nutrition <= 100:
                player.fighter.starvation_bonus += starvation_variable

            elif player.fighter.nutrition >= 100:
                player.fighter.starvation_bonus += 0

            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 gender == Gender.male:
            player.fighter.gender = 1

        elif gender == Gender.female:
            player.fighter.gender = 2

        elif gender == Gender.agender:
            player.fighter.gender = 3

        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if (entity.item or 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
            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 use_skills:
            previous_game_state = game_state
            game_state = GameStates.SHOW_SKILL_MENU

        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))
                libtcod.console_flush()
                libtcod.console_clear(con)
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(player.inventory.drop_item(item))
                libtcod.console_flush()
                libtcod.console_clear(con)

        if skill_index is not None and previous_game_state != GameStates.PLAYER_DEAD and skill_index < len(
                player.skills.skill_list):
            skill = player.skills.skill_list[skill_index]

            if game_state == GameStates.SHOW_SKILL_MENU:
                player_turn_results.extend(
                    player.skills.use(skill,
                                      entities=entities,
                                      fov_map=fov_map))
                libtcod.console_flush()
                libtcod.console_clear(con)

        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 take_upstairs 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.previous_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 += 10
                player.fighter.hp += 10
            elif level_up == 'str':
                player.fighter.base_power += 1
            elif level_up == 'def':
                player.fighter.base_defense += 1
            libtcod.console_flush()
            libtcod.console_clear(con)
            game_state = GameStates.JOB_SELECTION


#For some reason the skil menu is linked here. I wonder why?
        if job:
            if job == 'pri':
                player.fighter.base_max_hp += 20
                player.fighter.hp += 20
                player.fighter.job += 1
                player.fighter.priest_level += 1
                skill_component = Skill(use_function=prayer,
                                        amount=40,
                                        mana_cost=5)
                bandage = Entity(0,
                                 0,
                                 '?',
                                 libtcod.yellow,
                                 'Cure Light Wounds',
                                 skill=skill_component)
                player.skills.add_skill(bandage)
            elif job == 'fig':
                player.fighter.base_power += 2
                player.fighter.base_defense += 1
                player.fighter.job += 2
                player.fighter.fighter_level += 1
            elif job == 'thi':
                skill_component = Skill(use_function=hide)
                tornado = Entity(0,
                                 0,
                                 '?',
                                 libtcod.yellow,
                                 'Hide',
                                 skill=skill_component)
                player.fighter.base_defense += 2
                player.fighter.base_power += 1
                player.fighter.base_agility += 0.5
                player.fighter.job += 3
                player.fighter.thief_level += 1
                player.skills.add_skill(tornado)
            elif job == 'wiz':
                skill_component = Skill(
                    use_function=cast_spell_fireball,
                    mana_cost=10,
                    skill_targeting=True,
                    targeting_message=Message(
                        'Left-click a target tile for the fireball, or right-click to cancel.',
                        libtcod.light_cyan),
                    damage=25,
                    radius=3)
                x = entity.x
                y = entity.y
                fireball = Entity(x,
                                  y,
                                  '?',
                                  libtcod.red,
                                  'Fireball',
                                  skill=skill_component)
                player.skills.add_skill(fireball)
            elif job == 'psy':
                skill_component = Charm()
                charm = SkillEntity(' ',
                                    libtcod.yellow,
                                    'Charm',
                                    skill=skill_component)
                player.fighter.base_psyche += 3
                player.fighter.job = 5
                skill_component = Skill(use_function=cast_mind_lightning,
                                        maximum_range=5,
                                        hunger_cost=40 +
                                        player.fighter.psyche / 2)
                psybolt = Entity(0,
                                 0,
                                 ' ',
                                 libtcod.yellow,
                                 'PsyBolt',
                                 skill=skill_component)
                player.skills.add_skill(psybolt)
                player.skills.add_skill(charm)

            libtcod.console_flush()
            libtcod.console_clear(con)
            game_state = GameStates.PLAYERS_TURN

        if character_creation:
            if character_creation == 'mern':
                player.fighter.base_max_hp += 20
                player.fighter.hp += 20
                player.fighter.race += 1
            elif character_creation == 'avis':
                player.fighter.base_power += 1
                player.fighter.race += 2
            elif character_creation == 'lepra':
                player.fighter.base_defense += 1
                player.fighter.race += 3
            elif character_creation == 'giant':
                player.fighter.base_agility -= 5
                player.fighter.base_power += 6
                player.fighter.hp += 60
                player.fighter.base_max_hp += 60
                player.fighter.race += 4
            elif character_creation == 'change':
                player.fighter.base_agility += 2
                player.fighter.race += 5
            elif character_creation == 'fae':
                player.fighter.base_agility += 10
                player.fighter.hp -= 75
                player.fighter.base_max_hp -= 75
                player.fighter.race += 6
            libtcod.console_flush()
            libtcod.console_clear(con)
            game_state = GameStates.GENDER_SELECTION
        # damn son thats a lot of menus
        # like a lot

        if gender:
            if gender == 'm':
                player.fighter.base_max_hp += 10
                player.fighter.hp += 10
                player.fighter.gender += 1
            elif gender == 'f':
                player.fighter.base_power += 5
                player.fighter.base_max_hp -= 20
                player.fighter.hp -= 20
                player.fighter.gender += 2
            elif gender == 'a':
                player.fighter.gender += 3
            libtcod.console_flush()
            libtcod.console_clear(con)
            game_state = GameStates.PLAYERS_TURN

        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)
                libtcod.console_flush()
                libtcod.console_clear(con)
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})
                libtcod.console_flush()
                libtcod.console_clear(con)

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

                skill_use_results = player.skills.use(targeting_skill,
                                                      entities=entities,
                                                      fov_map=fov_map,
                                                      target_x=target_x,
                                                      target_y=target_y)
                player_turn_results.extend(skill_use_results)
                libtcod.console_flush()
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})
                libtcod.console_flush()
                libtcod.console_clear(con)

        if exit:
            if game_state in (GameStates.SHOW_INVENTORY,
                              GameStates.DROP_INVENTORY,
                              GameStates.CHARACTER_SCREEN):
                game_state = previous_game_state
            elif game_state == GameStates.SHOW_SKILL_MENU:
                game_state = GameStates.PLAYERS_TURN
            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
            elif game_state == GameStates.SKILL_TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
            else:
                save_game(player, entities, game_map, message_log, game_state)
                libtcod.console_flush()
                libtcod.console_clear(panel)
                libtcod.console_clear(con)

                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')
            skill_added = player_turn_result.get('skill_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')
            skill_targeting = player_turn_result.get('skill_targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')
            xp = player_turn_result.get('xp')
            skill_used = player_turn_result.get('used')

            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 skill_added:
                game_state = GameStates.ENEMY_TURN

            if skill_used:
                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 skill_targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.SKILL_TARGETING

                targeting_skill = skill_targeting

                message_log.add_message(
                    targeting_skill.skill.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:

            if player.fighter.nutrition <= 0:
                kill_player(player)
                game_state = GameStates.PLAYER_DEAD
                message_log.add_message(
                    Message('You have starved to death.', libtcod.red))

            if player.fighter.nutrition <= 100 and player.fighter.stealthed == 1:
                player.fighter.stealthed = 0

            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