Пример #1
0
def use_ray_gun(*args, **kwargs):
    caster = args[0]
    entities = kwargs.get('entities')
    fov_map = kwargs.get('fov_map')
    damage = kwargs.get('damage')
    maximum_range = kwargs.get('maximum_range')

    results = []

    target = None
    closest_distance = maximum_range + 1

    for entity in entities:
        if entity.fighter and entity != caster and libtcod.map_is_in_fov(
                fov_map, entity.x, entity.y):
            distance = caster.distance_to(entity)

            if distance < closest_distance:
                target = entity
                closest_distance = distance

    if target:
        if randint(0, 100) >= 30:
            results.append({
                'consumed':
                False,
                'target':
                target,
                'message':
                Message(
                    'Pew! Pew! You hit the {0} with a searing ray blast! It takes {1} damage!'
                    .format(target.name, damage), libtcod.orange)
            })
            results.extend(target.fighter.take_damage(damage))
        else:
            results.append({
                'consumed':
                False,
                'target':
                target,
                'message':
                Message(
                    'Pew! Pew! Pew! Pew! You miss the {0}!'.format(
                        target.name), libtcod.dark_red)
            })
    else:
        results.append({
            'consumed':
            False,
            'target':
            None,
            'message':
            Message('No enemy is close enough to shoot.', libtcod.red)
        })

    return results
Пример #2
0
    def use(self, item_entity, **kwargs):
        results = []

        item_component = item_entity.item

        if item_component.use_function is None:
            equippable_component = item_entity.equippable

            if equippable_component:
                results.append({'equip': item_entity})
            else:
                results.append({
                    'message':
                    Message('The {0} cannot be used'.format(item_entity.name),
                            libtcod.yellow)
                })
        else:
            if item_component.targeting and not (kwargs.get('target_x')
                                                 or kwargs.get('target_y')):
                results.append({'targeting': item_entity})
            else:
                kwargs = {**item_component.function_kwargs, **kwargs}
                item_use_results = item_component.use_function(
                    self.owner, **kwargs)

                for item_use_result in item_use_results:
                    if item_use_result.get('consumed'):
                        self.remove_item(item_entity)

                results.extend(item_use_results)

        return results
Пример #3
0
def use_stun_grenade(*args, **kwargs):
    entities = kwargs.get('entities')
    fov_map = kwargs.get('fov_map')
    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 field of view!',
                    libtcod.yellow)
        })
        return results

    for entity in entities:
        if entity.x == target_x and entity.y == target_y and entity.ai:
            stunned_ai = StunnedMonster(entity.ai, 10)

            stunned_ai.owner = entity
            entity.ai = stunned_ai

            results.append({
                'consumed':
                True,
                'message':
                Message(
                    'The stun grenade explodes near the {0}! It reels and begins to stumble around as it tries to regain its bearings.'
                    .format(entity.name), libtcod.light_green)
            })

            break
    else:
        results.append({
            'consumed':
            False,
            'message':
            Message('There is no targetable enemy at that location!',
                    libtcod.yellow)
        })

    return results
Пример #4
0
def use_shock_charge(*args, **kwargs):
    caster = args[0]
    entities = kwargs.get('entities')
    fov_map = kwargs.get('fov_map')
    damage = kwargs.get('damage')
    maximum_range = kwargs.get('maximum_range')

    results = []

    target = None
    closest_distance = maximum_range + 1

    for entity in entities:
        if entity.fighter and entity != caster and libtcod.map_is_in_fov(
                fov_map, entity.x, entity.y):
            distance = caster.distance_to(entity)

            if distance < closest_distance:
                target = entity
                closest_distance = distance

    if target:
        results.append({
            'consumed':
            True,
            'target':
            target,
            'message':
            Message(
                'A lightning bolt strikes the {0} with a loud thunder! It deals {1} damage.'
                .format(target.name, damage), libtcod.orange)
        })
        results.extend(target.fighter.take_damage(damage))
    else:
        results.append({
            'consumed':
            False,
            'target':
            None,
            'message':
            Message('No enemy is close enough to strike.', libtcod.red)
        })

    return results
Пример #5
0
def kill_player(player):
    # Delete savegame file upon death to force player to start over
    if not os.path.isfile('savegame.dat'):
        pass
    else:
        os.remove('savegame.dat')
    player.char = 180
    player.color = libtcod.dark_red

    return Message('You died!', libtcod.red), GameStates.PLAYER_DEAD
Пример #6
0
def use_plasma_grenade(*args, **kwargs):
    entities = kwargs.get('entities')
    fov_map = kwargs.get('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 field of view!',
                    libtcod.yellow)
        })
        return results

    results.append({
        'consumed':
        True,
        'message':
        Message(
            'The plasma grenade 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:
            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
Пример #7
0
def kill_monster(monster):
    death_message = Message('{0} is dead!'.format(monster.name.capitalize()),
                            libtcod.orange)

    monster.char = 180
    monster.color = libtcod.dark_red
    monster.blocks = False
    monster.fighter = None
    monster.ai = None
    monster.name = 'remains of ' + monster.name
    monster.render_order = RenderOrder.CORPSE

    return death_message
Пример #8
0
    def add_item(self, item):
        results = []

        if len(self.items) >= self.capacity:
            results.append({
                'item_added':
                None,
                'message':
                Message('You cannot carry any more, your inventory is full',
                        libtcod.yellow)
            })
        else:
            results.append({
                'item_added':
                item,
                'message':
                Message('You pick up the {0}!'.format(item.name), libtcod.blue)
            })

            self.items.append(item)

        return results
Пример #9
0
def morphine_pack(*args, **kwargs):
    entity = args[0]
    amount = kwargs.get('amount')

    results = []

    if entity.fighter.hp == entity.fighter.max_hp:
        results.append({
            'consumed':
            False,
            'message':
            Message('You are already at full health', libtcod.yellow)
        })
    else:
        entity.fighter.heal(amount)
        results.append({
            'consumed':
            True,
            'message':
            Message('Your wounds start to feel much better!', libtcod.green)
        })

    return results
Пример #10
0
    def attack(self, target):
        results = []

        damage = self.power - target.fighter.defense

        if damage > 0:
            results.append({
                'message':
                Message(
                    '{0} attacks {1} for {2} hit points.'.format(
                        self.owner.name.capitalize(), target.name,
                        str(damage)), libtcod.white)
            })
            results.extend(target.fighter.take_damage(damage))
        else:
            results.append({
                'message':
                Message(
                    '{0} attacks {1} but does no damage.'.format(
                        self.owner.name.capitalize(), target.name),
                    libtcod.white)
            })

        return results
Пример #11
0
    def next_floor(self, player, message_log, constants):
        self.dungeon_level += 1
        entities = [player]

        self.tiles = self.initialize_tiles()
        self.make_map(constants['max_rooms'], constants['room_min_size'],
                      constants['room_max_size'], constants['map_width'],
                      constants['map_height'], player, entities)

        player.fighter.heal(player.fighter.max_hp // 2)

        message_log.add_message(
            Message('You take a moment to rest, and recover your strenth.',
                    libtcod.light_violet))

        return entities
Пример #12
0
	def take_turn(self, target, fov_map, game_map, entities):
		results = []
		
		if self.number_of_turns > 0:
			random_x = self.owner.x + randint(0, 2) - 1
			random_y = self.owner.y + randint(0, 2) - 1
			
			if random_x != self.owner.x and random_y != self.owner.y:
				self.owner.move_towards(random_x, random_y, game_map, entities)
				
			self.number_of_turns -= 1
		else:
			self.owner.ai = self.previous_ai
			results.append({'message': Message('The {0} is no longer stunned!'.format(self.owner.name), libtcod.violet)})
			
		return results
Пример #13
0
    def drop_item(self, item):
        results = []

        if self.owner.equipment.top_right_tentacle == item or self.owner.equipment.top_left_tentacle == item or self.owner.equipment.bottom_right_tentacle == item or self.owner.equipment.bottom_left_tentacle == item or self.owner.equipment.chest_plate == item or self.owner.equipment.helmet == item or self.owner.equipment.neck == item:
            self.owner.equipment.toggle_equip(item)

        item.x = self.owner.x
        item.y = self.owner.y

        self.remove_item(item)
        results.append({
            'item_dropped':
            item,
            'message':
            Message('You dropped the {0}'.format(item.name), libtcod.yellow)
        })

        return results
Пример #14
0
    def place_entities(self, room, entities):
        max_monsters_per_room = from_dungeon_level(
            [[2, 1], [3, 4], [5, 6], [7, 10]], self.dungeon_level)
        min_monsters_per_room = from_dungeon_level(
            [[0, 1], [1, 4], [2, 6], [6, 10], [3, 11]], self.dungeon_level)
        max_items_per_room = from_dungeon_level([[1, 1], [2, 4], [3, 7]],
                                                self.dungeon_level)

        # Get a random number of monsters
        number_of_monsters = randint(min_monsters_per_room,
                                     max_monsters_per_room)
        number_of_items = randint(0, max_items_per_room)

        monster_chances = {
            'kanga':
            from_dungeon_level([[25, 3], [70, 6], [5, 10], [70, 11], [30, 16]],
                               self.dungeon_level),
            'dingo':
            from_dungeon_level([[60, 1], [45, 4], [20, 7], [5, 10], [20, 11]],
                               self.dungeon_level),
            'joey':
            from_dungeon_level([[20, 1], [15, 2], [10, 3], [0, 10], [10, 11]],
                               self.dungeon_level),
            'goanna':
            from_dungeon_level(
                [[20, 6], [70, 9], [10, 10], [70, 11], [55, 16]],
                self.dungeon_level),
            'killer_bees':
            from_dungeon_level([[5, 1], [100, 10], [5, 11]],
                               self.dungeon_level),
            'dropbear':
            from_dungeon_level(
                [[15, 9], [5, 10], [35, 11], [55, 14], [70, 16]],
                self.dungeon_level)
        }
        item_chances = {
            'lesser_med_kit':
            from_dungeon_level([[25, 1], [20, 5], [1, 7]], self.dungeon_level),
            'morphine_pack':
            from_dungeon_level([[5, 5], [20, 7], [5, 9]], self.dungeon_level),
            'tentacruels':
            from_dungeon_level([[5, 3]], self.dungeon_level),
            'energy_shield':
            from_dungeon_level([[15, 6]], self.dungeon_level),
            'plasma_grenade':
            from_dungeon_level([[10, 3], [12, 5]], self.dungeon_level),
            'stun_grenade':
            from_dungeon_level([[10, 2], [15, 4]], self.dungeon_level),
            'ray_gun':
            from_dungeon_level([[3, 6], [5, 8]], self.dungeon_level),
            'shock_charge':
            from_dungeon_level([[5, 1], [13, 3]], self.dungeon_level),
            'med_kit':
            from_dungeon_level([[5, 7], [25, 9]], self.dungeon_level),
            'whippy_willow_twig':
            from_dungeon_level([[15, 1]], self.dungeon_level),
            'goanna_skin_hat':
            from_dungeon_level([[5, 1], [15, 3]], self.dungeon_level),
            'aluminite_neck_brace':
            from_dungeon_level([[5, 2], [10, 4]], self.dungeon_level),
            'dropbear_fur_vest':
            from_dungeon_level([[5, 3], [7, 6]], self.dungeon_level)
        }

        for i in range(number_of_monsters):
            # Choose a random location in the room
            x = randint(room.x1 + 1, room.x2 - 1)
            y = randint(room.y1 + 1, room.y2 - 1)

            if not any([
                    entity
                    for entity in entities if entity.x == x and entity.y == y
            ]):
                monster_choice = random_choice_from_dict(monster_chances)
                if monster_choice == 'kanga':
                    statbase = randint(30, 45) + self.dungeon_level
                    rand_hp = statbase * 15
                    rand_def = statbase
                    rand_power = round(statbase * 2.5)
                    rand_xp = statbase * 3
                    fighter_component = Fighter(hp=rand_hp,
                                                defense=rand_def,
                                                power=rand_power,
                                                xp=rand_xp)
                    ai_component = BasicMonster()
                    monster = Entity(x,
                                     y,
                                     196,
                                     libtcod.Color(218, 42, 32),
                                     'Kanga',
                                     blocks=True,
                                     render_order=RenderOrder.ACTOR,
                                     fighter=fighter_component,
                                     ai=ai_component)
                elif monster_choice == 'dingo':
                    statbase = randint(15, 20) + self.dungeon_level
                    rand_hp = statbase * 15
                    rand_def = statbase
                    rand_power = round(statbase * 3.5)
                    rand_xp = statbase * 3
                    fighter_component = Fighter(hp=rand_hp,
                                                defense=rand_def,
                                                power=rand_power,
                                                xp=rand_xp)
                    ai_component = BasicMonster()
                    monster = Entity(x,
                                     y,
                                     191,
                                     libtcod.Color(165, 42, 42),
                                     'Dingo',
                                     blocks=True,
                                     render_order=RenderOrder.ACTOR,
                                     fighter=fighter_component,
                                     ai=ai_component)
                elif monster_choice == 'goanna':
                    statbase = randint(45, 55) + self.dungeon_level
                    rand_hp = statbase * 15
                    rand_def = statbase
                    rand_power = statbase * 3
                    rand_xp = statbase * 3
                    fighter_component = Fighter(hp=rand_hp,
                                                defense=rand_def,
                                                power=rand_power,
                                                xp=rand_xp)
                    ai_component = BasicMonster()
                    monster = Entity(x,
                                     y,
                                     186,
                                     libtcod.Color(25, 42, 0),
                                     'Goanna',
                                     blocks=True,
                                     render_order=RenderOrder.ACTOR,
                                     fighter=fighter_component,
                                     ai=ai_component)
                elif monster_choice == 'dropbear':
                    statbase = randint(60, 65) + self.dungeon_level
                    rand_hp = statbase * 10
                    rand_def = statbase + self.dungeon_level
                    rand_power = statbase * 4
                    rand_xp = statbase * 4
                    fighter_component = Fighter(hp=rand_hp,
                                                defense=rand_def,
                                                power=rand_power,
                                                xp=rand_xp)
                    ai_component = BasicMonster()
                    monster = Entity(x,
                                     y,
                                     191,
                                     libtcod.Color(33, 33, 33),
                                     'Dropbear',
                                     blocks=True,
                                     render_order=RenderOrder.ACTOR,
                                     fighter=fighter_component,
                                     ai=ai_component)
                elif monster_choice == 'killer_bees':
                    statbase = randint(8, 10) + self.dungeon_level
                    rand_hp = statbase * 7
                    rand_def = statbase
                    rand_power = round(statbase * 12)
                    rand_xp = round(statbase * 2.5)
                    fighter_component = Fighter(hp=rand_hp,
                                                defense=rand_def,
                                                power=rand_power,
                                                xp=rand_xp)
                    ai_component = BasicMonster()
                    monster = Entity(x,
                                     y,
                                     201,
                                     libtcod.yellow,
                                     'Killer Bee',
                                     blocks=True,
                                     render_order=RenderOrder.ACTOR,
                                     fighter=fighter_component,
                                     ai=ai_component)
                else:
                    statbase = randint(9, 20) + self.dungeon_level
                    rand_hp = statbase * 15
                    rand_def = statbase
                    rand_power = round(statbase * 2.5)
                    rand_xp = statbase * 3
                    fighter_component = Fighter(hp=rand_hp,
                                                defense=rand_def,
                                                power=rand_power,
                                                xp=rand_xp)
                    ai_component = BasicMonster()
                    monster = Entity(x,
                                     y,
                                     179,
                                     libtcod.Color(218, 42, 32),
                                     'Joey',
                                     blocks=True,
                                     render_order=RenderOrder.ACTOR,
                                     fighter=fighter_component,
                                     ai=ai_component)

                entities.append(monster)
        for i in range(number_of_items):
            x = randint(room.x1 + 1, room.x2 - 1)
            y = randint(room.y1 + 1, room.y2 - 1)

            if not any([
                    entity
                    for entity in entities if entity.x == x and entity.y == y
            ]):
                item_choice = random_choice_from_dict(item_chances)

                if item_choice == 'lesser_med_kit':
                    item_component = Item(use_function=heal, amount=200)
                    item = Entity(x,
                                  y,
                                  195,
                                  libtcod.violet,
                                  'Lesser Med Kit',
                                  render_order=RenderOrder.ITEM,
                                  item=item_component)
                elif item_choice == 'morphine_pack':
                    item_component = Item(use_function=morphine_pack,
                                          amount=350)
                    item = Entity(x,
                                  y,
                                  195,
                                  libtcod.Color(40, 30, 0),
                                  'Morphine Pack',
                                  render_order=RenderOrder.ITEM,
                                  item=item_component)
                elif item_choice == 'med_kit':
                    item_component = Item(use_function=morphine_pack,
                                          amount=500)
                    item = Entity(x,
                                  y,
                                  195,
                                  libtcod.Color(255, 30, 0),
                                  'Med Kit',
                                  render_order=RenderOrder.ITEM,
                                  item=item_component)
                elif item_choice == 'tentacruels':
                    equippable_component = Equippable(EquipmentSlots.TENTACLE,
                                                      power_bonus=40)
                    item = Entity(x,
                                  y,
                                  218,
                                  libtcod.purple,
                                  'Tentacruel',
                                  equippable=equippable_component)
                elif item_choice == 'energy_shield':
                    equippable_component = Equippable(EquipmentSlots.TENTACLE,
                                                      defense_bonus=50,
                                                      max_hp_bonus=250)
                    item = Entity(x,
                                  y,
                                  217,
                                  libtcod.cyan,
                                  'Energy Shield',
                                  equippable=equippable_component)
                elif item_choice == 'whippy_willow_twig':
                    equippable_component = Equippable(EquipmentSlots.TENTACLE,
                                                      power_bonus=15)
                    item = Entity(x,
                                  y,
                                  188,
                                  libtcod.Color(53, 38, 0),
                                  'Whippy Willow Twig',
                                  equippable=equippable_component)
                elif item_choice == 'goanna_skin_hat':
                    equippable_component = Equippable(EquipmentSlots.HELMET,
                                                      power_bonus=5,
                                                      defense_bonus=10)
                    item = Entity(x,
                                  y,
                                  200,
                                  libtcod.Color(20, 38, 0),
                                  'Goanna Skin Hat',
                                  equippable=equippable_component)
                elif item_choice == 'aluminite_neck_brace':
                    equippable_component = Equippable(EquipmentSlots.NECK,
                                                      defense_bonus=5)
                    item = Entity(x,
                                  y,
                                  204,
                                  libtcod.silver,
                                  'Aluminite Neck Brace',
                                  equippable=equippable_component)
                elif item_choice == 'dropbear_fur_vest':
                    equippable_component = Equippable(
                        EquipmentSlots.CHEST_PLATE,
                        max_hp_bonus=100,
                        defense_bonus=25)
                    item = Entity(x,
                                  y,
                                  185,
                                  libtcod.Color(30, 30, 30),
                                  'Dropbear Fur Vest',
                                  equippable=equippable_component)
                elif item_choice == 'plasma_grenade':
                    item_component = Item(
                        use_function=use_plasma_grenade,
                        targeting=True,
                        targeting_message=Message(
                            'Left-click an enemy to lob the Plasma Grenade at it, or right-click to cancel.',
                            libtcod.light_cyan),
                        damage=250,
                        radius=3)
                    item = Entity(x,
                                  y,
                                  193,
                                  libtcod.cyan,
                                  'Plasma Grenade',
                                  render_order=RenderOrder.ITEM,
                                  item=item_component)
                elif item_choice == 'ray_gun':
                    item_component = Item(use_function=use_ray_gun,
                                          damage=80,
                                          maximum_range=11)
                    item = Entity(x,
                                  y,
                                  187,
                                  libtcod.Color(180, 180, 180),
                                  'Ray Gun',
                                  render_order=RenderOrder.ITEM,
                                  item=item_component)
                elif item_choice == 'stun_grenade':
                    item_component = Item(
                        use_function=use_stun_grenade,
                        targeting=True,
                        targeting_message=Message(
                            'Left-click an enemy to lob the Stun Grenade at it, or right-click to cancel.',
                            libtcod.light_cyan))
                    item = Entity(x,
                                  y,
                                  193,
                                  libtcod.Color(0, 40, 0),
                                  'Stun Grenade',
                                  render_order=RenderOrder.ITEM,
                                  item=item_component)
                else:
                    item_component = Item(use_function=use_shock_charge,
                                          damage=350,
                                          maximum_range=5)
                    item = Entity(x,
                                  y,
                                  194,
                                  libtcod.yellow,
                                  'Shock Charge',
                                  render_order=RenderOrder.ITEM,
                                  item=item_component)

                entities.append(item)
Пример #15
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

    wait_timer = 0

    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_trail = action.get('take_trail')
        level_up = action.get('level_up')
        show_character_screen = action.get('show_character_screen')
        checkpoint = action.get('checkpoint')
        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 player.fighter.max_hp < player.fighter.hp:
            player.fighter.hp = player.fighter.max_hp

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

            if wait_timer > 0:
                if randint(0, 7) == 7:
                    wait_timer = wait_timer - 5

            passive_regen = randint(0, 20)
            if passive_regen == 20 and player.fighter.hp < player.fighter.max_hp:
                if player.fighter.hp >= player.fighter.max_hp - round(
                    (player.fighter.max_hp / 150)):
                    player.fighter.hp = player.fighter.max_hp
                    message_log.add_message(
                        Message('Your wounds are completely healed!',
                                libtcod.green))
                else:
                    player.fighter.hp = player.fighter.hp + round(
                        (player.fighter.max_hp / 150))

            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:
            if wait_timer <= 55:
                wait_timer = wait_timer + 5
                if player.fighter.hp < player.fighter.max_hp:
                    if player.fighter.hp >= player.fighter.max_hp - round(
                        (player.fighter.max_hp / 50)):
                        player.fighter.hp = player.fighter.max_hp
                        message_log.add_message(
                            Message(
                                'You rest for a moment. Your wounds are completely healed!',
                                libtcod.green))
                        game_state = GameStates.ENEMY_TURN
                    else:
                        player.fighter.hp = player.fighter.hp + round(
                            (player.fighter.max_hp / 50))
                        message_log.add_message(
                            Message(
                                'You rest for a moment. Your wounds are beginning to feel slightly better.',
                                libtcod.green))
                        game_state = GameStates.ENEMY_TURN
                else:
                    message_log.add_message(
                        Message('You rest for a moment.', libtcod.yellow))
                    game_state = GameStates.ENEMY_TURN
            elif wait_timer >= 56:
                if player.fighter.hp >= 501:
                    player.fighter.hp = player.fighter.hp - 500
                    message_log.add_message(
                        Message(
                            'You begin to rest, but the Dropbear drops down on your back and begins feasting on your flesh!',
                            libtcod.dark_red))
                    game_state = GameStates.ENEMY_TURN
                elif player.fighter.hp <= 500:
                    player.fighter.hp = player.fighter.hp - 500
                    message_log.add_message(
                        Message(
                            'You begin to rest, but the Dropbear drops down on your back and feasts on your flesh!',
                            libtcod.dark_red))
                    player.char = 180
                    player.color = libtcod.dark_red
                    if not os.path.isfile('savegame.dat'):
                        pass
                    else:
                        os.remove('savegame.dat')
                    message_log.add_message(Message('You died!', libtcod.red))
                    game_state = GameStates.PLAYER_DEAD

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

        if take_trail and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.trail 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()

                    break

            else:
                message_log.add_message(
                    Message('There is no trail here.', libtcod.yellow))

        if level_up:
            if player.fighter.hp <= player.fighter.max_hp - round(
                (player.fighter.max_hp / 7)):
                player.fighter.hp = player.fighter.hp + round(
                    (player.fighter.max_hp / 7))
            else:
                player.fighter.hp = player.fighter.max_hp
            if level_up == 'hp':
                player.fighter.base_max_hp += 250
                player.fighter.hp += 250
            elif level_up == 'str':
                player.fighter.base_power += 12
            elif level_up == 'def':
                player.fighter.base_defense += 12

            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 checkpoint:
            save_game(player, entities, game_map, message_log, game_state)
            message_log.add_message(
                Message('Your game has been saved.', libtcod.green))

        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, gamestate = 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 unequipped 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! Welcome to 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