示例#1
0
 def __init__(self, args):
   self.state = State()
   self.state.init_stuff()
   self.state.debug = bool(args.debug)
   self.state.god_mode = bool(args.god_mode)
   self.menu = Menu()
   self.state.high_scores = HighScores()
示例#2
0
class SpellInventory:
  def __init__(self, state):
    self.status_panel = state.status_panel
    self.menu = Menu()
    self.player = state.player
    self.spells = state.player.caster.spells

  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]
示例#3
0
class Inventory:
  def __init__(self, state):
    self.status_panel = state.status_panel
    self.inventory = []
    self.objects = state.objects
    self.menu = Menu()
    self.player = state.player

  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
示例#4
0
class CreateCharacter:
  def __init__(self, state):
    self.state = state
    self.menu = Menu()
    self.player_class = None
    self.player_race = None
    self.caster_component = None
    self.fighter_component = None
    self.choose_race()
    self.choose_class()
    self.get_caster_component()
    self.get_fighter_component()
    self.state.player = Object(0, 0, '@', Constants.PLAYER, libtcod.white, blocks=True, fighter=self.fighter_component,
                               caster=self.caster_component)
    self.state.player.level = 1
    self.state.player_inventory = Inventory(self.state)
    self.state.player_spell_inventory = SpellInventory(self.state)
    self.get_starting_equipment()

  def choose_class(self):
    while (self.player_class == None):
      self.player_class = self.menu.display_menu_return_item('Choose a class:',
                                                             [Constants.WARRIOR, Constants.MAGE, Constants.ARCHER], 30,
                                                             self.state.con,
                                                             override_height=MapConstants.MENU_HEIGHT_ADDITION)
    self.state.player_class = self.player_class

  def choose_race(self):
    while (self.player_race == None):
      self.player_race = self.menu.display_menu_return_item('Choose a race:',
                                                            [Constants.ELF, Constants.HUMAN, Constants.DWARF], 30,
                                                            self.state.con,
                                                            override_height=MapConstants.MENU_HEIGHT_ADDITION)
    self.state.player_race = self.player_race

  def get_caster_component(self):
    self.caster_component = getattr(eval(self.player_class), 'get_caster_component')()

  def get_fighter_component(self):
    self.fighter_component = getattr(eval(self.player_race), 'get_fighter_component')()

  # TODO Make this fit the class / race better
  def get_starting_equipment(self):
    equipment_component = self.state.equipment.get_data_object(EquipmentConstants.DAGGER)
    item = equipment_component.create_at_location(0, 0)
    self.state.player_inventory.inventory.append(item)
    equipment_component.equip(self.state)
示例#5
0
 def __init__(self, args):
   self.state = State()
   self.state.init_stuff()
   self.state.debug = bool(args.debug)
   self.state.god_mode = bool(args.god_mode)
   self.menu = Menu()
   self.state.magic = DatafileLoader(data_file=Constants.SPELL_FILE, data_class=Spell, map_name="spells")
   self.state.items = DatafileLoader(data_file=Constants.ITEM_FILE, data_class=Item, map_name="items")
   self.state.monsters = DatafileLoader(data_file=Constants.MONSTER_FILE, data_class=Monster, map_name="monsters")
   self.state.equipment = DatafileLoader(data_file=Constants.EQUIPMENT_FILE, data_class=Equipment, map_name="equipments")
   self.state.high_scores = HighScores()
示例#6
0
 def __init__(self, state):
   self.state = state
   self.menu = Menu()
   self.player_class = None
   self.player_race = None
   self.caster_component = None
   self.fighter_component = None
   self.choose_race()
   self.choose_class()
   self.get_caster_component()
   self.get_fighter_component()
   self.state.player = Object(0, 0, '@', Constants.PLAYER, libtcod.white, blocks=True, fighter=self.fighter_component,
                              caster=self.caster_component)
   self.state.player.level = 1
   self.state.player_inventory = Inventory(self.state)
   self.state.player_spell_inventory = SpellInventory(self.state)
   self.get_starting_equipment()
示例#7
0
class MainMenu:

  def __init__(self, args):
    self.state = State()
    self.state.init_stuff()
    self.state.debug = bool(args.debug)
    self.state.god_mode = bool(args.god_mode)
    self.menu = Menu()
    self.state.high_scores = HighScores()

  def main_menu(self):
    while not libtcod.console_is_window_closed():
      choice = self.menu.display_menu_return_index('', ['Play a new game', 'Continue last game',
                                                        'Custom Map Mode', 'High Scores', 'Quit'], 30, self.state.con)
      if choice == 0:
        self.new_game()
        self.play_game()
      elif choice == 1:
        try:
          self.load_game()
        except:
          self.message_box('No saved game to load', 24)
          continue
        self.play_game()
      elif choice == 2:
        self.make_custom_map()
        self.edit_mode()
      elif choice == 3:
        self.show_high_scores()
      elif choice == 4:
        break

  def show_high_scores(self):
    self.state.high_scores.show_high_scores(self.state, self.menu)

  def message_box(self, message, size=50):
    self.menu.display_menu_return_index(message, [], size, self.state.con)

  def make_custom_map(self):
    self.setup_game()
    self.state.game_map = Map()
    self.state.game_map.generate_map(self.state, Map.create_blank_map)
    self.initialize_fov(self.state.dungeon_level)
    self.state.set_player_action(None)

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

  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)

  def new_game(self):
    self.setup_game()
    self.state.game_map = Map()
    self.state.game_map.generate_map(self.state, Map.create_random_map)
    self.initialize_fov(self.state.dungeon_level)
    self.state.game_state = Constants.PLAYING

  def initialize_fov(self, dungeon_level):
    self.state.fov_map_map[dungeon_level] = libtcod.map_new(MapConstants.MAP_WIDTH, MapConstants.MAP_HEIGHT)
    libtcod.console_clear(self.state.con)
    for y in range(MapConstants.MAP_HEIGHT):
      for x in range(MapConstants.MAP_WIDTH):
        libtcod.map_set_properties(self.state.fov_map_map[dungeon_level], x, y, True, True)
    self.state.fov_map = self.state.fov_map_map[dungeon_level]

  # def save_game(self):
  #   file = shelve.open(Constants.SAVE_FILE, 'n')
  #   file['game_map'] = self.state.game_map.game_map
  #   file.close()
  #
  # def load_game(self):
  #   self.state.game_map = Map(self.state)
  #   file = shelve.open(Constants.SAVE_FILE, 'r')
  #   self.state.game_map.game_map = file['game_map']
  #   file.close()
  #   self.initialize_fov(self.state.dungeon_level)

  def setup_game(self):
    self.state.status_panel.game_messages = []
    self.state.status_panel.message('Starting the game of life', libtcod.red)
    self.state.turn = 0
    self.state.score = 0
示例#8
0
 def __init__(self, state):
   self.status_panel = state.status_panel
   self.menu = Menu()
   self.player = state.player
   self.spells = state.player.caster.spells
示例#9
0
class MainMenu:

  def __init__(self, args):
    self.state = State()
    self.state.init_stuff()
    self.state.debug = bool(args.debug)
    self.state.god_mode = bool(args.god_mode)
    self.menu = Menu()
    self.state.magic = DatafileLoader(data_file=Constants.SPELL_FILE, data_class=Spell, map_name="spells")
    self.state.items = DatafileLoader(data_file=Constants.ITEM_FILE, data_class=Item, map_name="items")
    self.state.monsters = DatafileLoader(data_file=Constants.MONSTER_FILE, data_class=Monster, map_name="monsters")
    self.state.equipment = DatafileLoader(data_file=Constants.EQUIPMENT_FILE, data_class=Equipment, map_name="equipments")
    self.state.high_scores = HighScores()

  def main_menu(self):
    # img = libtcod.image_load('rl_image.png')
    # show the background image, at twice the regular console resolution
    while not libtcod.console_is_window_closed():
      # libtcod.image_blit_2x(img, 0, 0, 0)
      choice = self.menu.display_menu_return_index('', ['Play a new game', 'Continue last game',
                                                        'Battle (work in progress)', 'High Scores', 'Quit'], 30,
                                                   self.state.con)
      if choice == 0:
        self.new_game()
        self.play_game()
      elif choice == 1:
        try:
          self.load_game()
        except:
          self.message_box('No saved game to load', 24)
          continue
        self.play_game()
      elif choice == 2:
        self.battle()
        self.play_game()
      elif choice == 3:
        self.show_high_scores()
      elif choice == 4:
        break

  def show_high_scores(self):
    self.state.high_scores.show_high_scores(self.state, self.menu)

  def message_box(self, message, size=50):
    self.menu.display_menu_return_index(message, [], size, self.state.con)

  def setup_game(self):
    self.state.status_panel.game_messages = []
    self.state.status_panel.message('Welcome stranger! Prepare to perish in the Tombs of the Ancient Kings.',
                                    libtcod.red)
    self.state.dungeon_level = 0
    self.state.turn = 0
    self.state.score = 0
    self.choose_class(self.state)
    self.state.objects_map[self.state.dungeon_level] = [self.state.player]
    self.state.objects = self.state.objects_map[self.state.dungeon_level]


  def battle(self):
    self.setup_game()
    self.state.game_type = Constants.BATTLE
    self.state.game_map = Map()
    self.state.game_map.generate_battle_map(self.state)
    self.state.game_map.set_game_map(self.state.dungeon_level)
    self.initialize_battle_fov(self.state.dungeon_level)
    # self.initialize_fov(self.state.dungeon_level)
    self.state.set_player_action(None)

  def choose_class(self, state):
    CreateCharacter(state)

  def new_game(self):
    self.setup_game()
    self.state.game_type = Constants.CRAWL
    self.state.game_map = Map()
    self.state.game_map.generate_map(self.state, self.state.dungeon_level)
    self.state.game_map.set_game_map(self.state.dungeon_level)
    self.initialize_fov(self.state.dungeon_level)
    self.state.set_player_action(None)

  def initialize_fov(self, dungeon_level):
    self.state.fov_map_map[dungeon_level] = libtcod.map_new(MapConstants.MAP_WIDTH, MapConstants.MAP_HEIGHT)
    libtcod.console_clear(self.state.con)
    for y in range(MapConstants.MAP_HEIGHT):
      for x in range(MapConstants.MAP_WIDTH):
        libtcod.map_set_properties(self.state.fov_map_map[dungeon_level], x, y,
                                   not self.state.game_map.is_blocked_sight(self.state.objects, x, y),
                                   not self.state.game_map.is_blocked_sight(self.state.objects, x, y))
    self.state.fov_map = self.state.fov_map_map[dungeon_level]

  def initialize_battle_fov(self, dungeon_level):
    self.state.fov_map_map[dungeon_level] = libtcod.map_new(MapConstants.MAP_WIDTH, MapConstants.MAP_HEIGHT)
    libtcod.console_clear(self.state.con)
    for y in range(MapConstants.MAP_HEIGHT):
      for x in range(MapConstants.MAP_WIDTH):
        libtcod.map_set_properties(self.state.fov_map_map[dungeon_level], x, y,
                                   True, True)
    self.state.fov_map = self.state.fov_map_map[dungeon_level]

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

  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

  def follow_stairs(self, type_entered, stairs_id_entered, stairs_entered_dungeon_level):
    other_stairs_id = self.state.stairs[stairs_entered_dungeon_level][type_entered][stairs_id_entered]
    return other_stairs_id

  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)

  def save_game(self):
    file = shelve.open(Constants.SAVE_FILE, 'n')
    file['game_map'] = self.state.game_map.game_map
    file['inventory'] = self.state.player_inventory.inventory
    file['game_messages'] = self.state.status_panel.game_messages
    file['objects'] = self.state.objects
    file['player_index'] = self.state.objects.index(self.state.player)
    file['stairs'] = self.state.stairs
    file['dungeon_level'] = self.state.dungeon_level
    file['turn'] = self.state.turn
    file['score'] = self.state.score
    file.close()

  def load_game(self):
    self.state.game_map = Map(self.state)
    self.state.player_inventory = Inventory(self.state)
    file = shelve.open(Constants.SAVE_FILE, 'r')
    self.state.game_map.game_map = file['game_map']
    self.state.player_inventory.inventory = file['inventory']
    self.state.status_panel.game_messages = file['game_messages']
    self.state.objects = file['objects']
    self.state.player = self.state.objects[file['player_index']]
    self.state.stairs = file['stairs']
    self.state.dungeon_level = file['dungeon_level']
    self.state.turn = file['turn']
    self.state.score = file['score']
    file.close()
    self.state.player_spell_inventory = SpellInventory(self.state)
    self.initialize_fov(self.state.dungeon_level)
示例#10
0
 def __init__(self, state):
   self.status_panel = state.status_panel
   self.inventory = []
   self.objects = state.objects
   self.menu = Menu()
   self.player = state.player