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
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
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
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
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
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
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
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
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
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
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
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
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
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)
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