Пример #1
0
 def edit_mode(self):
   self.state.game_state = Constants.PAUSE
   self.state.game_map.game_maps[self.state.game_map.game_map_id][self.state.get_target_x()][self.state.get_target_y()].targeted = True
   while not libtcod.console_is_window_closed():
     self.state.turn += 1
     Util.render_all(self.state)
     libtcod.console_flush()
     Input.handle_keys(self.state, False)
     if self.state.game_state == Constants.PLAYING:
       self.play_game()
Пример #2
0
 def connect_stairs(state, previous_player_coords):
   down_stairs_ids = state.stairs[state.dungeon_level - 1][MapConstants.DOWN_STAIRS_OBJECT].keys()
   up_stairs_ids = state.stairs[state.dungeon_level][MapConstants.UP_STAIRS_OBJECT].keys()
   old_down_stair_id = Util.get_padded_coords(previous_player_coords[0], previous_player_coords[1])
   new_up_stair_id = Util.get_padded_coords(state.player.x, state.player.y)
   MapCreation.connect_two_stairs(state, new_up_stair_id, old_down_stair_id)
   down_stairs_ids.remove(old_down_stair_id)
   up_stairs_ids.remove(new_up_stair_id)
   for down_stair_id in down_stairs_ids:
     up_stairs_id = up_stairs_ids.pop()
     MapCreation.connect_two_stairs(state, up_stairs_id, down_stair_id)
Пример #3
0
  def get_monsters_to_place(state):
    max_monsters_table = [[2, 0], [3, 3], [5, 5]]
    max_monsters = Util.from_dungeon_level(state, max_monsters_table)

    # choose random number of monsters
    monster_chances = {
      MonsterConstants.ORC: 80,
      MonsterConstants.TROLL: Util.from_dungeon_level(state, [[15, 3], [30, 5], [60, 7]])
    }
    num_monsters = libtcod.random_get_int(0, 0, max_monsters)
    monsters = [Util.random_choice(monster_chances) for i in range(num_monsters)]
    return monsters
Пример #4
0
 def play_game(self):
   self.state.game_state = Constants.PLAYING
   self.state.game_map.game_maps[self.state.game_map.game_map_id][self.state.get_target_x()][self.state.get_target_y()].targeted = False
   self.state.game_map.game_maps[self.state.game_map.previous_map_id][self.state.get_target_x()][self.state.get_target_y()].targeted = False
   while not libtcod.console_is_window_closed():
     sleep(0.20)
     self.state.turn += 1
     Util.render_all(self.state)
     libtcod.console_flush()
     Input.handle_keys(self.state, True)
     if self.state.game_state == Constants.PAUSE:
       self.edit_mode()
     self.state.game_map.process_map(self.state)
Пример #5
0
 def handle_targeting_keys(key, state):
   if key.vk == libtcod.KEY_CHAR:
     if key.c == ord('k'):
       return Util.player_target(state, 0, -1)
     elif key.c == ord('j'):
       return Util.player_target(state, 0, 1)
     elif key.c == ord('h'):
       return Util.player_target(state, -1, 0)
     elif key.c == ord('l'):
       return Util.player_target(state, 1, 0)
     elif key.c == ord('y'):
       return Util.player_target(state, -1, -1)
     elif key.c == ord('u'):
       return Util.player_target(state, 1, -1)
     elif key.c == ord('b'):
       return Util.player_target(state, -1, 1)
     elif key.c == ord('n'):
       return Util.player_target(state, 1, 1)
     else:
       state.set_player_action(Constants.NOT_VALID_KEY)
   elif key.vk == libtcod.KEY_ESCAPE:
     state.set_game_state(Constants.PLAYING)
   elif key.vk == libtcod.KEY_ENTER:
     state.set_game_state(Constants.FOUND_TARGET)
   else:
     state.set_player_action(Constants.NOT_VALID_KEY)
Пример #6
0
 def inventory_menu(self, header, state):
   # show a menu with each item of the inventory as an option
   if len(self.inventory) == 0:
     options = ['Inventory is empty.']
   else:
     options = []
     for item in state.player_inventory.inventory:
       text = item.name
       if item.equipment and item.equipment.is_equipped:
         text = text + ' (on ' + item.equipment.slot + ')'
       options.append(text)
   index = self.menu.display_menu_return_index(header, options, Constants.INVENTORY_WIDTH, state.con)
   if index is None or len(self.inventory) == 0:
     state.set_player_action(Constants.NOT_VALID_KEY)
     Util.refresh(state)
     return None
   return self.inventory[index].item
Пример #7
0
 def previous_level(self):
   up_stairs_id = Util.get_padded_coords(self.state.player.x, self.state.player.y)
   down_stairs_id = self.follow_stairs(MapConstants.UP_STAIRS_OBJECT, up_stairs_id, self.state.dungeon_level)
   self.state.dijkstra_map_update = True
   self.state.player.x, self.state.player.y = Util.get_coords_from_padded_coords(down_stairs_id)
   if self.state.dungeon_level == 0:
     self.state.set_player_action(Constants.EXIT)
     return
   else:
     self.state.dungeon_level -= 1
   self.state.objects = self.state.objects_map[self.state.dungeon_level]
   self.state.game_map.set_game_map(self.state.dungeon_level)
   # TODO Make fov_map container class
   self.state.fov_map = self.state.fov_map_map[self.state.dungeon_level]
   self.initialize_fov(self.state.dungeon_level)
   self.state.set_player_action(None)
   self.state.fov_recompute = True
Пример #8
0
 def create_stairs_of_type(state, stairs_coords, type):
   for stair_coords in stairs_coords:
     stairs = Object(stair_coords[0], stair_coords[1], type, MapConstants.STAIRS_NAME, MapConstants.STAIRS_COLOR,
                     always_visible=True)
     state.objects_map[state.dungeon_level].append(stairs)
     stairs.send_to_back(state.objects_map[state.dungeon_level])
     stairs_id = Util.get_padded_coords(stairs.x, stairs.y)
     state.stairs[state.dungeon_level][type][stairs_id] = None
Пример #9
0
 def cast_lightning(state):
   monster = Util.closest_monster(state, Constants.LIGHTNING_RANGE)
   if monster is None:
     state.status_panel.message('No enemy is close enough to strike with lightning', libtcod.red)
     return Constants.CANCELLED
   state.status_panel.message('A lightning bolt strikes the ' + monster.name + ' with a ZAP! The damage done is '
                              + str(Constants.LIGHTNING_DAMAGE) + ' hp.', libtcod.light_blue)
   monster.fighter.take_damage(Constants.LIGHTNING_DAMAGE, state)
Пример #10
0
 def cast_fireball(state):
   # TODO: Add range check
   x, y = Util.target_tile(state)
   state.game_map.get_map()[x][y].set_targeted(False)
   for object in state.objects:
     if object.distance(x, y) <= Constants.FIREBALL_RADIUS and object.fighter:
       state.status_panel.message('You sling a fireball at: ' + object.name + ' with a BAMboosh! The damage done is '
                                  + str(Constants.FIREBALL_DAMAGE) + ' hp.', libtcod.light_blue)
       object.fighter.take_damage(Constants.FIREBALL_DAMAGE, state)
Пример #11
0
  def target_tile(state, start_x=None, start_y=None):
    state.set_game_state(Constants.TARGETING)
    if start_x is None or start_y is None:
      state.set_target(state.player.x, state.player.y)
    else:
      state.set_target(start_x, start_y)
    while state.get_game_state() == Constants.TARGETING:
      Input.handle_keys(state)
      Util.refresh(state)

    if state.get_game_state() == Constants.FOUND_TARGET:
      x, y = state.get_target_coords()
      state.set_game_state(Constants.PLAYING)
    # TODO: Make target class? how to save/where to save targeting coords?
    # while
    if state.get_target_x() is None or state.get_target_y() is None:
      return Constants.CANCELLED
    state.game_map.get_map()[state.get_target_x()][state.get_target_y()].set_targeted(False)
    return state.get_target_x(), state.get_target_y()
Пример #12
0
 def next_level(self):
   self.state.dijkstra_map_update = True
   self.state.dungeon_level += 1
   self.state.status_panel.message('You take a moment to rest and recover 50% health', libtcod.violet)
   self.state.player.fighter.heal(self.state.player.fighter.max_hp(self.state) / 2, self.state)
   self.state.status_panel.message('and now you descend into the depths of the dungeon', libtcod.red)
   if self.state.dungeon_level in self.state.game_map.complete_game_map:
     self.state.game_map.set_game_map(self.state.dungeon_level)
     down_stairs_id = Util.get_padded_coords(self.state.player.x, self.state.player.y)
     up_stairs_id = self.follow_stairs(MapConstants.DOWN_STAIRS_OBJECT, down_stairs_id, self.state.dungeon_level - 1)
     self.state.player.x, self.state.player.y = Util.get_coords_from_padded_coords(up_stairs_id)
   else:
     self.state.objects_map[self.state.dungeon_level] = [self.state.player]
     self.state.game_map.generate_map(self.state, self.state.dungeon_level)
     self.state.score += self.state.dungeon_level * 10
   self.state.objects = self.state.objects_map[self.state.dungeon_level]
   self.initialize_fov(self.state.dungeon_level)
   self.state.set_player_action(None)
   self.state.fov_recompute = True
   Util.render_all(self.state)
Пример #13
0
 def pick_up(self, state):
   if len(state.player_inventory.inventory) >= 26:
     state.inventory.status_panel.message('Your inventory is full, cannot pick up ' + self.owner.name + '.',
                                          libtcod.red)
   else:
     state.player_inventory.inventory.append(self.owner)
     state.objects.remove(self.owner)
     state.status_panel.message('You picked up a ' + self.owner.name + '!', libtcod.green)
     equipment = self.owner.equipment
     if equipment and Util.get_equipped_in_slot(state, equipment.slot) is None:
       equipment.equip(state)
Пример #14
0
 def cast_confuse(state):
   # monster = Constants.closest_monster(util, Constants.CONFUSE_RANGE)
   monster = Util.target_monster(state, Constants.CONFUSE_RANGE)
   if monster is None:
     state.status_panel.message('No enemy is close enough to confuse', libtcod.red)
     return Constants.CANCELLED
   old_ai = monster.ai
   monster.ai = ConfusedMonster(old_ai, state)
   monster.clear(state.con)
   monster.ai.owner = monster
   state.status_panel.message('The eyes of the ' + monster.name + ' look vacant, as he starts to stumble around!',
                              libtcod.light_green)
Пример #15
0
  def spell_menu(self, header, state):
    # show a menu with each item of the inventory as an option
    if len(self.spells) == 0:
      options = ['You have no spells.']
    else:
      options = []
      for spell_name in state.player.caster.spells:
        spell = state.magic.spells[spell_name]
        text = spell_name + ' : ' + spell.description + ', mp cost: ' + str(spell.mp_cost) + ', spell range: ' + str(
          spell.range) + \
               ', spell power: ' + str(spell.power)
        options.append(text)

    index = self.menu.display_menu_return_index(header, options, Constants.INVENTORY_WIDTH, state.con)
    if index is not None:
      spell_name = options[index].split(' : ')[0]

    if index is None or len(self.spells) == 0:
      state.set_player_action(Constants.NOT_VALID_KEY)
      Util.refresh(state)
      return None
    return state.magic.spells[spell_name]
Пример #16
0
 def process_map(self, state):
   self.update_game_map_id()
   for column in self.game_maps[self.previous_map_id]:
     for tile in column:
       num_adjacent_alive = Util.get_count_of_adjacent_tile(self.game_maps[self.previous_map_id], tile.x, tile.y)
       if tile.alive:
         if num_adjacent_alive < 2 or num_adjacent_alive > 3:
           self.game_maps[self.game_map_id][tile.x][tile.y].alive = False
         else:
           self.game_maps[self.game_map_id][tile.x][tile.y].alive = True
       else:
         if num_adjacent_alive == 3:
           self.game_maps[self.game_map_id][tile.x][tile.y].alive = True
         else:
           self.game_maps[self.game_map_id][tile.x][tile.y].alive = False
   self.game_map = self.game_maps[self.game_map_id]
Пример #17
0
 def dijkstra_on_map(state, source_x, source_y):
     unvisited_tiles = queue.PriorityQueue()
     if state.dijkstra_map_update:
         state.dijkstra_map = [[sys.maxint for col in range(len(state.game_map.game_map[0]))] for row in range(len(state.game_map.game_map))]
         state.dijkstra_map_update = False
     for row in state.game_map.game_map:
         for tile in row:
             if tile.x == source_x and tile.y == source_y:
                 state.dijkstra_map[source_x][source_y] = 0
                 unvisited_tiles.put((0, (tile.x, tile.y)))
             elif tile.blocked:
                 continue
             else:
                 unvisited_tiles.put((sys.maxint, (tile.x, tile.y)))
     while not unvisited_tiles.empty():
         closest_dist, closest_tile = unvisited_tiles.get()
         closest_neighbors = Util.get_adjacent_tiles(state, closest_tile[0], closest_tile[1])
         for neighbor in closest_neighbors:
             if not neighbor.blocked:
                 temp_dist = closest_dist + 1
                 if temp_dist < state.dijkstra_map[neighbor.x][neighbor.y]:
                     state.dijkstra_map[neighbor.x][neighbor.y] = temp_dist
                     unvisited_tiles.put((temp_dist, (neighbor.x, neighbor.y)))
                     neighbor.dist_from_player = temp_dist
Пример #18
0
  def get_items_to_place(state):
    max_items_table = [[3, 0], [5, 3]]
    max_items = Util.from_dungeon_level(state, max_items_table)
    item_chances = {
        ItemConstants.HEALTH_POTION: 35,
        ItemConstants.SCROLL_OF_LIGHTNING_BOLT: Util.from_dungeon_level(state, [[25, 1]]),
        ItemConstants.SCROLL_OF_FIREBALL: Util.from_dungeon_level(state, [[25, 1]]),
        ItemConstants.SCROLL_OF_CONFUSE: Util.from_dungeon_level(state, [[10, 1]]),
    }
    equipment_chances = {
        EquipmentConstants.SWORD: 50,  # Util.from_dungeon_level(state, [[5, 4]]),
        EquipmentConstants.SHIELD: 50  # Util.from_dungeon_level(state, [[15, 8]]),
    }
    num_total_items = libtcod.random_get_int(0, 0, max_items)
    num_items = libtcod.random_get_int(0, 0, num_total_items)
    num_equipments = num_total_items - num_items

    items = [Util.random_choice(item_chances) for i in range(num_items)]
    equipments = [Util.random_choice(equipment_chances) for i in range(num_equipments)]
    return items, equipments
Пример #19
0
  def play_game(self):
    self.state.set_game_state(Constants.PLAYING)
    self.state.set_player_action(None)
    self.state.fov_recompute = True

    while not libtcod.console_is_window_closed():
      self.state.turn += 1
      Util.render_all(self.state)
      libtcod.console_flush()
      Util.check_level_up(self.state)
      for object in self.state.objects:
        object.clear(self.state.con)
      self.state.set_player_action(Constants.DID_NOT_TAKE_TURN)
      while self.state.get_player_action() == Constants.DID_NOT_TAKE_TURN:
        Input.handle_keys(self.state)

      player_action = self.state.get_player_action()
      if player_action == Constants.EXIT or self.state.player.color == libtcod.dark_red:
        self.save_game()
        break

      if self.state.get_game_state() == Constants.PLAYING and self.state.get_player_action() != Constants.DID_NOT_TAKE_TURN:
        AiUtils.dijkstra_on_map(self.state, self.state.player.x, self.state.player.y)
        monsters_still_alive = False
        for object in self.state.objects:
          if object.ai:
            monsters_still_alive = True
            object.ai.take_turn(self.state)
        if not monsters_still_alive and self.state.game_type == Constants.BATTLE:
          old_player_coords = self.state.player.x, self.state.player.y
          self.state.game_map.generate_battle_map(self.state)
          self.state.player.x, self.state.player.y = old_player_coords
      if player_action == Constants.NEXT_LEVEL:
        self.next_level()
      elif player_action == Constants.PREVIOUS_LEVEL:
        self.previous_level()
      elif player_action == Constants.EXIT or self.state.player.color == libtcod.dark_red:
        Util.render_all(self.state)
        self.save_game()
        break
      self.state.status_panel.message('###### Turn ' + str(self.state.turn) + ' has ended')
Пример #20
0
 def defense(self, state):
   bonus = sum(equipment.defense_bonus for equipment in Util.get_all_equiped(state, self.owner))
   return self.base_defense + bonus
Пример #21
0
 def equip(self, state):
   old_equipment = Util.get_equipped_in_slot(state, self.slot)
   if old_equipment is not None:
     old_equipment.equipment.dequip(state)
   self.is_equipped = True
   state.status_panel.message('Equiped ' + self.owner.name + ' on ' + self.slot + '.', libtcod.light_green)
Пример #22
0
 def power(self, state):
   bonus = sum(equipment.power_bonus for equipment in Util.get_all_equiped(state, self.owner))
   return self.base_power + bonus
Пример #23
0
 def handle_playing_keys(key, state):
   if key.vk == libtcod.KEY_CHAR:
     if key.c == ord('k'):
       Util.player_move_or_attack(state, 0, -1)
     elif key.c == ord('j'):
       Util.player_move_or_attack(state, 0, 1)
     elif key.c == ord('h'):
       Util.player_move_or_attack(state, -1, 0)
     elif key.c == ord('l'):
       Util.player_move_or_attack(state, 1, 0)
     elif key.c == ord('y'):
       Util.player_move_or_attack(state, -1, -1)
     elif key.c == ord('u'):
       Util.player_move_or_attack(state, 1, -1)
     elif key.c == ord('b'):
       Util.player_move_or_attack(state, -1, 1)
     elif key.c == ord('n'):
       Util.player_move_or_attack(state, 1, 1)
     elif key.c == ord('.'):
       pass
     elif key.c == ord('v'):
       Input.look(state)
       state.set_player_action(Constants.NOT_VALID_KEY)
     elif key.c == ord('i'):
       chosen_item = state.player_inventory.inventory_menu(
         'Press the key next to an item to use it, or any other to cancel.\n', state)
       if chosen_item is not None:
         chosen_item.use(state)
         # else:
         #     state.set_player_action(Constants.NOT_VALID_KEY)
     elif key.c == ord('I'):
       chosen_spell = state.player_spell_inventory.spell_menu(
         'Press the key next to a spell to use it, or any other to cancel.\n', state)
       if chosen_spell is not None:
         chosen_spell.cast(state, state.player)
     elif key.c == ord('d'):
       chosen_item = state.player_inventory.inventory_menu(
         'Press the key next to an item to drop it, or any other to cancel.\n', state)
       if chosen_item is not None:
         chosen_item.drop(state)
     elif key.c == ord('g'):
       # pick up an item
       for object in state.objects:  # look for an item in the player's tile
         if object.x == state.player.x and object.y == state.player.y and object.item:
           object.item.pick_up(state)
           break
     elif key.c == ord('>'):
       padded_player_coords = Util.get_padded_coords(state.player.x, state.player.y)
       if padded_player_coords in state.stairs[state.dungeon_level][MapConstants.DOWN_STAIRS_OBJECT].keys():
         state.set_player_action(Constants.NEXT_LEVEL)
     elif key.c == ord('<'):
       padded_player_coords = Util.get_padded_coords(state.player.x, state.player.y)
       if padded_player_coords in state.stairs[state.dungeon_level][MapConstants.UP_STAIRS_OBJECT].keys():
         state.set_player_action(Constants.PREVIOUS_LEVEL)
     elif key.c == ord('c'):
       # show character information
       level_up_xp = Constants.LEVEL_UP_BASE + state.player.level * Constants.LEVEL_UP_FACTOR
       Util.show_character_screen(state, level_up_xp)
       Util.refresh(state)
     else:
       state.set_player_action(Constants.NOT_VALID_KEY)
Пример #24
0
 def max_hp(self, state):
   bonus = sum(equipment.hp_bonus for equipment in Util.get_all_equiped(state, self.owner))
   return self.base_max_hp + bonus
Пример #25
0
 def handle_targeting_keys(key, state):
     if key.vk == libtcod.KEY_CHAR:
         if key.c == ord("k"):
             return Util.player_target(state, 0, -1)
         elif key.c == ord("j"):
             return Util.player_target(state, 0, 1)
         elif key.c == ord("h"):
             return Util.player_target(state, -1, 0)
         elif key.c == ord("l"):
             return Util.player_target(state, 1, 0)
         elif key.c == ord("y"):
             return Util.player_target(state, -1, -1)
         elif key.c == ord("u"):
             return Util.player_target(state, 1, -1)
         elif key.c == ord("b"):
             return Util.player_target(state, -1, 1)
         elif key.c == ord("n"):
             return Util.player_target(state, 1, 1)
         elif key.c == ord("x"):
             state.status_panel.message(
                 "toggleing x: " + str(state.get_target_x()) + ", y: " + str(state.get_target_y())
             )
             return Util.toggle_alive(state)
         elif key.c == ord("p"):
             if state.game_state == Constants.PAUSE:
                 state.status_panel.message("handle_targeting_keys: going from paused to playing")
                 state.game_state = Constants.PLAYING
                 return
             elif state.game_state == Constants.PLAYING:
                 state.status_panel.message("handle_targeting_keys: going from playing to paused")
                 state.game_state = Constants.PAUSE
                 return
             else:
                 state.status_panel.message("game state is: " + str(state.game_state))
         elif key.c == ord("s"):
             Util.save_map(state)
         else:
             state.set_player_action(Constants.NOT_VALID_KEY)