Exemple #1
0
    def load_board(self, filename, lvl_number=0):
        """Load a saved board

        Load a Board saved on the disk as a JSON file. This method creates a new Board object, populate it with all the elements (except a Player) and then return it.

        If the filename argument is not an existing file, the open function is going to raise an exception.

        This method, load the board from the JSON file, populate it with all BoardItem included, check for sanity, init the board with BoardItemVoid and then associate the freshly created board to a lvl_number.
        It then create the NPCs and add them to the board.

        :param filename: The file to load
        :type filename: str
        :param lvl_number: The level number to associate the board to. Default is 0.
        :type lvl_number: int
        :returns: a newly created board (see :class:`gamelib.Board.Board`)
        
        Example::

            mynewboard = game.load_board( 'awesome_level.json', 1 )
            game.change_level( 1 )
        """
        with open(filename, 'r') as f:
            data = json.load(f)
        local_board = Board()
        data_keys = data.keys()
        if "name" in data_keys:
            local_board.name = data["name"]
        if 'size' in data_keys:
            local_board.size = data['size']
        if 'player_starting_position' in data_keys:
            local_board.player_starting_position = data[
                'player_starting_position']
        if 'ui_border_top' in data_keys:
            local_board.ui_border_top = data['ui_border_top']
        if 'ui_border_bottom' in data_keys:
            local_board.ui_border_bottom = data['ui_border_bottom']
        if 'ui_border_left' in data_keys:
            local_board.ui_border_left = data['ui_border_left']
        if 'ui_border_right' in data_keys:
            local_board.ui_border_right = data['ui_border_right']
        if 'ui_board_void_cell' in data_keys:
            local_board.ui_board_void_cell = data['ui_board_void_cell']
        # Now we need to recheck for board sanity
        local_board.check_sanity()
        # and re-initialize the board (mainly to attribute a new model to the void cells as it's not dynamic).
        local_board.init_board()
        # Then add board to the game
        self.add_board(lvl_number, local_board)

        # Define an internal function to transform directions string into constants
        def _string_to_constant(s):
            if type(s) is int:
                return s
            elif s == "UP":
                return Constants.UP
            elif s == "DOWN":
                return Constants.DOWN
            elif s == "RIGHT":
                return Constants.RIGHT
            elif s == "LEFT":
                return Constants.LEFT
            elif s == "DRUP":
                return Constants.DRUP
            elif s == "DRDOWN":
                return Constants.DRDOWN
            elif s == "DLDOWN":
                return Constants.DLDOWN
            elif s == "DLUP":
                return Constants.DLUP

        def _ref2obj(ref):
            obj_keys = ref.keys()
            local_object = BoardItemVoid()
            if 'Wall' in ref['object']:
                local_object = Structures.Wall()
            elif 'Treasure' in ref['object']:
                local_object = Structures.Treasure()
                if 'value' in obj_keys:
                    local_object.value = ref['value']
                if 'size' in obj_keys:
                    local_object._size = ref['size']
            elif 'GenericStructure' in ref['object']:
                local_object = Structures.GenericStructure()
                if 'value' in obj_keys:
                    local_object.value = ref['value']
                if 'size' in obj_keys:
                    local_object._size = ref['size']
                if 'pickable' in obj_keys:
                    local_object.set_pickable(ref['pickable'])
                if 'overlappable' in obj_keys:
                    local_object.set_overlappable(ref['overlappable'])
            elif 'Door' in ref['object']:
                local_object = Structures.Door()
                if 'value' in obj_keys:
                    local_object.value = ref['value']
                if 'size' in obj_keys:
                    local_object._size = ref['size']
                if 'pickable' in obj_keys:
                    local_object.set_pickable(ref['pickable'])
                if 'overlappable' in obj_keys:
                    local_object.set_overlappable(ref['overlappable'])
                if 'restorable' in obj_keys:
                    local_object.set_restorable(ref['restorable'])
            elif 'GenericActionableStructure' in ref['object']:
                local_object = Structures.GenericActionableStructure()
                if 'value' in obj_keys:
                    local_object.value = ref['value']
                if 'size' in obj_keys:
                    local_object._size = ref['size']
                if 'pickable' in obj_keys:
                    local_object.set_pickable(ref['pickable'])
                if 'overlappable' in obj_keys:
                    local_object.set_overlappable(ref['overlappable'])
            elif 'NPC' in ref['object']:
                local_object = NPC()
                if 'value' in obj_keys:
                    local_object.value = ref['value']
                if 'size' in obj_keys:
                    local_object._size = ref['size']
                if 'hp' in obj_keys:
                    local_object.hp = ref['hp']
                if 'max_hp' in obj_keys:
                    local_object.max_hp = ref['max_hp']
                if 'step' in obj_keys:
                    local_object.step = ref['step']
                if 'remaining_lives' in obj_keys:
                    local_object.remaining_lives = ref['remaining_lives']
                if 'attack_power' in obj_keys:
                    local_object.attack_power = ref['attack_power']
                if 'actuator' in obj_keys:
                    if 'RandomActuator' in ref['actuator']['type']:
                        local_object.actuator = RandomActuator(moveset=[])
                        if 'moveset' in ref['actuator'].keys():
                            for m in ref['actuator']['moveset']:
                                local_object.actuator.moveset.append(
                                    _string_to_constant(m))
                    elif 'PathActuator' in ref['actuator']['type']:
                        local_object.actuator = PathActuator(path=[])
                        if 'path' in ref['actuator'].keys():
                            for m in ref['actuator']['path']:
                                local_object.actuator.path.append(
                                    _string_to_constant(m))
            # Now what remains is what is common to all BoardItem
            if not isinstance(local_object, BoardItemVoid):
                if 'name' in obj_keys:
                    local_object.name = ref['name']
                if 'model' in obj_keys:
                    local_object.model = ref['model']
                if 'type' in obj_keys:
                    local_object.type = ref['type']
            return local_object

        # Now load the library if any
        if 'library' in data_keys:
            self.object_library = []
            for e in data['library']:
                self.object_library.append(_ref2obj(e))
        # Now let's place the good stuff on the board
        if 'map_data' in data_keys:
            for pos_x in data['map_data'].keys():
                x = int(pos_x)
                for pos_y in data['map_data'][pos_x].keys():
                    y = int(pos_y)
                    ref = data['map_data'][pos_x][pos_y]
                    obj_keys = ref.keys()
                    if 'object' in obj_keys:
                        o = _ref2obj(ref)
                        if not isinstance(o, NPC) and not isinstance(
                                o, BoardItemVoid):
                            local_board.place_item(o, x, y)
                        elif isinstance(o, NPC):
                            self.add_npc(lvl_number, o, x, y)

                    else:
                        Utils.warn(
                            f'while loading the board in {filename}, at coordinates [{pos_x},{pos_y}] there is an entry without "object" attribute. NOT LOADED.'
                        )
        return local_board
     Utils.cyan_bright("HAC-GAME-LIB - EDITOR v" +
                       Constants.HAC_GAME_LIB_VERSION))
 # Create config_dir if not exist and populate it with a directories.json file.
 if (not os.path.exists(config_dir) or not os.path.isdir(config_dir)
         or not os.path.exists(base_config_dir)
         or not os.path.isdir(base_config_dir)
         or not os.path.isdir(editor_config_dir) or not os.path.exists(
             os.path.join(editor_config_dir, "settings.json"))):
     first_use()
 else:
     game.load_config(os.path.join(editor_config_dir, "settings.json"),
                      "settings")
     viewport_height = game.config(
         "settings")["partial_display_viewport"][0]
     viewport_width = game.config("settings")["partial_display_viewport"][1]
     viewport_board.size = [viewport_width * 2, viewport_height * 2]
     viewport_board.init_board()
     # The objects library is stored as a list of references. We need to convert that
     # before using the objects.
     objlib = []
     for ref in game.config("settings")["object_library"]:
         objlib.append(Game._ref2obj(ref))
     game.config("settings")["object_library"] = objlib
 print("Looking for existing maps in selected directories...", end="")
 default_map_dir = None
 hmaps = []
 for directory in game.config("settings")["directories"]:
     # files = [f'{directory}/{f}' for f in os.listdir(directory)]
     # hmaps += files
     test_dir = os.path.join(base_config_dir, directory)
     if os.path.exists(test_dir):