def clear_cell(self, row, column): """Clear cell (row, column) This method clears a cell, meaning it position a void_cell BoardItemVoid at these coordinates. :param row: The row of the item to remove :type row: int :param column: The column of the item to remove :type column: int Example:: myboard.clear_cell(3,4) .. WARNING:: This method does not check the content before, it *will* overwrite the content. """ if self._matrix[row][column] in self._movables: index = self._movables.index(self._matrix[row][column]) del (self._movables[index]) elif self._matrix[row][column] in self._immovables: index = self._immovables.index(self._matrix[row][column]) del (self._immovables[index]) self.place_item( BoardItemVoid(model=self.ui_board_void_cell, name='void_cell'), row, column)
def init_board(self): """ Initialize the board with BoardItemVoid that uses ui_board_void_cell as model. Example:: myboard.init_board() """ self._matrix = [ [ BoardItemVoid(model=self.ui_board_void_cell) for i in range(0,self.size[0],1) ] for j in range(0,self.size[1],1) ]
def init_cell(self,row,column): """ Initialize a specific cell of the board with BoardItemVoid that uses ui_board_void_cell as model. :param row: the row coordinate. :type row: int :param column: the column coordinate. :type column: int Example:: myboard.init_cell(2,3) """ self._matrix[row][column] = BoardItemVoid(model=self.ui_board_void_cell)
def reset_drawn_path(): global g for i in g.current_board().get_immovables(type='path_marker'): g.current_board().place_item(BoardItemVoid(), i.pos[0], i.pos[1])
def create_wizard(): global game key = '' while True: game.clear_screen() print(Utils.green_bright("\t\tObject creation wizard")) print('What do you want to create: a NPC or a structure?') print('1 - NPC (Non Playable Character)') print('2 - Structure (Wall, Door, Treasure, Portal, Trees, etc.)') key = Utils.get_key() if key == '1' or key == '2': break if key == '1': game.clear_screen() print( Utils.green_bright("\t\tObject creation wizard: ") + Utils.cyan_bright("NPC")) new_object = NPC() print("First give a name to your NPC. Default value: " + new_object.name) r = str(input('(Enter name)> ')) if len(r) > 0: new_object.name = r print( "Then give it a type. A type is important as it allows grouping.\nType is a string. Default value: " + new_object.type) r = str(input('(Enter type)> ')) if len(r) > 0: new_object.type = r print("Now we need a model. Default value: " + new_object.model) input('Hit "Enter" when you are ready to choose a model.') new_object.model = model_picker() game.clear_screen() print( Utils.green_bright("\t\tObject creation wizard: ") + Utils.cyan_bright("NPC") + f' - {new_object.model}') print( 'We now needs to go through some basic statistics. You can decide to go with default by simply hitting the "Enter" key.' ) r = input_digit( f'Number of cell crossed in one turn. Default: {new_object.step}(type: int) > ' ) if len(r) > 0: new_object.step = int(r) else: # If it's 0 it means it's going to be a static NPC so to prevent python to pass some random pre-initialized default, we explicitly set the Actuator to a static one new_object.actuator = SimpleActuators.RandomActuator(moveset=[]) r = input_digit( f'Max HP (Health Points). Default: {new_object.max_hp}(type: int) > ' ) if len(r) > 0: new_object.max_hp = int(r) new_object.hp = new_object.max_hp r = input_digit( f'Max MP (Mana Points). Default: {new_object.max_mp}(type: int) > ' ) if len(r) > 0: new_object.max_mp = int(r) new_object.mp = new_object.max_mp r = input_digit( f'Remaining lives (it is advised to set that to 1 for a standard NPC). Default: {new_object.remaining_lives}(type: int) > ' ) if len(r) > 0: new_object.remaining_lives = int(r) r = input_digit( f'AP (Attack Power). Default: {new_object.attack_power}(type: int) > ' ) if len(r) > 0: new_object.attack_power = int(r) r = input_digit( f'DP (Defense Power). Default: {new_object.defense_power}(type: int) > ' ) if len(r) > 0: new_object.defense_power = int(r) r = input_digit( f'Strength. Default: {new_object.strength}(type: int) > ') if len(r) > 0: new_object.strength = int(r) r = input_digit( f'Intelligence. Default: {new_object.intelligence}(type: int) > ') if len(r) > 0: new_object.intelligence = int(r) r = input_digit( f'Agility. Default: {new_object.agility}(type: int) > ') if len(r) > 0: new_object.agility = int(r) game.clear_screen() print( "We now need to give some life to that NPC. What kind of movement should it have:" ) print("1 - Randomly chosen from a preset of directions") print("2 - Following a predetermined path") r = Utils.get_key() if r == '1': new_object.actuator = SimpleActuators.RandomActuator(moveset=[]) print( 'Random it is! Now choose from which preset of movements should we give it:' ) print('1 - UP,DOWN,LEFT, RIGHT') print('2 - UP,DOWN') print('3 - LEFT, RIGHT') print('4 - UP,DOWN,LEFT, RIGHT + all DIAGONALES') print( '5 - DIAGONALES (DIAG UP LEFT, DIAG UP RIGHT, etc.) but NO straight UP, DOWN, LEFT and RIGHT' ) print('6 - No movement') r = Utils.get_key() if r == '1': new_object.actuator.moveset = [ Constants.UP, Constants.DOWN, Constants.LEFT, Constants.RIGHT ] elif r == '2': new_object.actuator.moveset = [Constants.UP, Constants.DOWN] elif r == '3': new_object.actuator.moveset = [Constants.RIGHT, Constants.LEFT] elif r == '4': new_object.actuator.moveset = [ Constants.UP, Constants.DOWN, Constants.LEFT, Constants.RIGHT, Constants.DLDOWN, Constants.DLUP, Constants.DRDOWN, Constants.DRUP ] elif r == '5': new_object.actuator.moveset = [ Constants.DLDOWN, Constants.DLUP, Constants.DRDOWN, Constants.DRUP ] elif r == '6': new_object.actuator.moveset = [] else: Utils.warn( f'"{r}" is not a valid choice. Movement set is now empty.') new_object.actuator.moveset = [] elif r == '2': new_object.actuator = SimpleActuators.PathActuator(path=[]) print("Great, so what path this NPC should take:") print('1 - UP/DOWN patrol') print('2 - DOWN/UP patrol') print('3 - LEFT/RIGHT patrol') print('4 - RIGHT/LEFT patrol') print('5 - Circle patrol: LEFT, DOWN, RIGHT, UP') print('6 - Circle patrol: LEFT, UP, RIGHT, DOWN') print('7 - Circle patrol: RIGHT, DOWN, LEFT, UP') print('8 - Circle patrol: RIGHT, UP, LEFT, DOWN') print('9 - Write your own path') r = Utils.get_key() if r == '1': print( "How many steps should the NPC go in one direction before turning back ?" ) r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.UP for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.DOWN for i in range(0, r, 1) ] elif r == '2': print( "How many steps should the NPC go in one direction before turning back ?" ) r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.DOWN for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.UP for i in range(0, r, 1) ] elif r == '3': print( "How many steps should the NPC go in one direction before turning back ?" ) r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.LEFT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.RIGHT for i in range(0, r, 1) ] elif r == '3': print( "How many steps should the NPC go in one direction before turning back ?" ) r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.RIGHT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.LEFT for i in range(0, r, 1) ] elif r == '4': print( "How many steps should the NPC go in one direction before turning back ?" ) r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.DOWN for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.UP for i in range(0, r, 1) ] elif r == '5': print( "How many steps should the NPC go in EACH direction before changing ?" ) r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.LEFT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.DOWN for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.RIGHT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.UP for i in range(0, r, 1) ] elif r == '6': print( "How many steps should the NPC go in EACH direction before changing ?" ) r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.LEFT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.UP for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.RIGHT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.DOWN for i in range(0, r, 1) ] elif r == '7': print( "How many steps should the NPC go in EACH direction before changing ?" ) r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.RIGHT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.DOWN for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.LEFT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.UP for i in range(0, r, 1) ] elif r == '8': print( "How many steps should the NPC go in EACH direction before changing ?" ) r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.RIGHT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.UP for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.LEFT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.DOWN for i in range(0, r, 1) ] elif r == '9': print( "Write your own path using only words from this list: UP, DOWN, LEFT, RIGHT, DLDOWN, DLUP, DRDOWN, DRUP." ) print('Each direction has to be separated by a coma.') r = str(input('Write your path: ')).upper() new_object.actuator.path = r.split(',') else: Utils.warn(f'"{r}" is not a valid choice. Path is now empty.') new_object.actuator.path = [] return new_object elif key == '2': while True: game.clear_screen() print( Utils.green_bright("\t\tObject creation wizard: ") + Utils.magenta_bright("Structure")) print("What kind of structure do you want to create:") print( '1 - A wall like structure (an object that cannot be picked-up and is not overlappable). Ex: walls, trees, non moving elephant (try to go through an elephant or to pick it up in your backpack...)' ) print('2 - A door (player and/or NPC can go through)') print( '3 - A treasure (can be picked up, take space in the inventory, give points to the player)' ) print( '4 - A generic object (you can set the properties to make it pickable or overlappable)' ) print( '5 - A generic actionable object (to make portals, heart to replenish life, etc.)' ) key = Utils.get_key() new_object = None if key == '1': new_object = Structures.Wall() new_object.name = str(uuid.uuid1()) new_object.model = model_picker() break elif key == '2': new_object = Structures.Door() new_object.name = str(uuid.uuid1()) new_object.model = model_picker() break elif key == '3': new_object = Structures.Treasure() print("First give a name to your Treasure. Default value: " + new_object.name) r = str(input('(Enter name)> ')) if len(r) > 0: new_object.name = r print( "Then give it a type. A type is important as it allows grouping (in this case probably in the inventory).\nType is a string. Default value: " + new_object.type) r = str(input('(Enter type)> ')) if len(r) > 0: new_object.type = r print("Now we need a model. Default value: " + new_object.model) input('Hit "Enter" when you are ready to choose a model.') new_object.model = model_picker() break elif key == '4' or key == '5': if key == '4': new_object = Structures.GenericStructure() else: new_object = Structures.GenericActionableStructure() new_object.set_overlappable(False) new_object.set_pickable(False) print("First give a name to your structure. Default value: " + new_object.name) r = str(input('(Enter name)> ')) if len(r) > 0: new_object.name = r print( "Then give it a type. \nType is a string. Default value: " + new_object.type) r = str(input('(Enter type)> ')) if len(r) > 0: new_object.type = r print("Now we need a model. Default value: " + new_object.model) input('Hit "Enter" when you are ready to choose a model.') new_object.model = model_picker() print( 'Is this object pickable? (can it be picked up by the player)?' ) print('0 - No') print('1 - Yes') r = Utils.get_key() if r == '1': new_object.set_pickable(True) print( 'Is this object overlappable? (can it be walked over by player?' ) print('0 - No') print('1 - Yes') r = Utils.get_key() if r == '1': new_object.set_overlappable(True) break return new_object #Placeholder return BoardItemVoid()
height = int(input_digit('Height (in number of cells): ')) game.add_board( 1, Board(name=name, size=[width, height], ui_borders=Utils.WHITE_SQUARE, ui_board_void_cell=Utils.BLACK_SQUARE)) is_modified = True # Main program game = Game() current_file = '' game.player = Player(model='[]') key = 'None' current_object = BoardItemVoid(model='None') object_history = [] current_menu = 'main' while True: game.clear_screen() print( Utils.cyan_bright("HAC-GAME-LIB - EDITOR v" + Constants.HAC_GAME_LIB_VERSION)) print('Looking for existing maps in selected directories...', end='') with open('directories.json') as paths: directories = json.load(paths) hmaps = [] try: for directory in directories: files = [f'{directory}/{f}' for f in os.listdir(directory)]
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
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
def move(self, item, direction, step): """ Move an item in the specified direction for a number of steps. Example:: board.move(player,Constants.UP,1) :param item: an item to move (it has to be a subclass of Movable) :type item: gamelib.Movable.Movable :param direction: a direction from :ref:`constants-module` :type direction: gamelib.Constants :param step: the number of steps to move the item. :type step: int If the number of steps is greater than the Board, the item will be move to the maximum possible position. If the item is not a subclass of Movable, an HacObjectIsNotMovableException exception (see :class:`gamelib.HacExceptions.HacObjectIsNotMovableException`). .. Important:: if the move is successfull, an empty BoardItemVoid (see :class:`gamelib.BoardItem.BoardItemVoid`) will be put at the departure position (unless the movable item is over an overlappable item). If the movable item is over an overlappable item, the overlapped item is restored. .. note:: It could be interesting here, instead of relying on storing the overlapping item in a property of a Movable (:class:`gamelib.Movable.Movable`) object, to have another dimension on the board matrix to push and pop objects on a cell. Only the first item would be rendered and it would avoid the complicated and error prone logic in this method. If anyone feel up to the challenge, `PR are welcome ;-) <https://github.com/arnauddupuis/hac-game-lib/pulls>`_. .. todo:: check all types! """ if isinstance(item, Movable) and item.can_move(): # if direction not in dir(Constants): # raise HacInvalidTypeException('In Board.move(item, direction, # step), direction must be a direction contant from the # gamelib.Constants module') new_x = None new_y = None if direction == Constants.UP: new_x = item.pos[0] - step new_y = item.pos[1] elif direction == Constants.DOWN: new_x = item.pos[0] + step new_y = item.pos[1] elif direction == Constants.LEFT: new_x = item.pos[0] new_y = item.pos[1] - step elif direction == Constants.RIGHT: new_x = item.pos[0] new_y = item.pos[1] + step elif direction == Constants.DRUP: new_x = item.pos[0] - step new_y = item.pos[1] + step elif direction == Constants.DRDOWN: new_x = item.pos[0] + step new_y = item.pos[1] + step elif direction == Constants.DLUP: new_x = item.pos[0] - step new_y = item.pos[1] - step elif direction == Constants.DLDOWN: new_x = item.pos[0] + step new_y = item.pos[1] - step if (new_x is not None and new_y is not None and new_x >= 0 and new_y >= 0 and new_x < self.size[1] and new_y < self.size[0] and self._matrix[new_x][new_y].overlappable()): # If we are here, it means the cell we are going to already # has an overlappable item, so let's save it for # later restoration if (not isinstance(self._matrix[new_x][new_y], BoardItemVoid) and isinstance(self._matrix[new_x][new_y], Immovable) and self._matrix[new_x][new_y].restorable()): if item._overlapping is None: item._overlapping = self._matrix[new_x][new_y] else: item._overlapping_buffer = self._matrix[new_x][new_y] if isinstance(self._matrix[new_x][new_y], Actionable): if ((isinstance(item, Player) and ((self._matrix[new_x][new_y].perm == Constants.PLAYER_AUTHORIZED) or (self._matrix[new_x][new_y].perm == Constants.ALL_PLAYABLE_AUTHORIZED))) or (isinstance(item, NPC) and ((self._matrix[new_x][new_y].perm == Constants.NPC_AUTHORIZED) or (self._matrix[new_x][new_y].perm == Constants.ALL_PLAYABLE_AUTHORIZED)))): self._matrix[new_x][new_y].activate() # Here instead of just placing a BoardItemVoid on # the departure position we first make sure there # is no _overlapping object to restore. if (item._overlapping is not None and isinstance(item._overlapping, Immovable) and item._overlapping.restorable() and (item._overlapping.pos[0] != new_x or item._overlapping.pos[1] != new_y)): self.place_item(item._overlapping, item._overlapping.pos[0], item._overlapping.pos[1]) if item._overlapping_buffer is not None: item._overlapping = item._overlapping_buffer item._overlapping_buffer = None else: item._overlapping = None else: self.place_item( BoardItemVoid(model=self.ui_board_void_cell), item.pos[0], item.pos[1]) self.place_item(item, new_x, new_y) else: # if there is an overlapped item, restore it. # Else just move if (item._overlapping is not None and isinstance(item._overlapping, Immovable) and item._overlapping.restorable() and (item._overlapping.pos[0] != new_x or item._overlapping.pos[1] != new_y)): self.place_item(item._overlapping, item._overlapping.pos[0], item._overlapping.pos[1]) if item._overlapping_buffer is not None: item._overlapping = item._overlapping_buffer item._overlapping_buffer = None else: item._overlapping = None else: self.place_item( BoardItemVoid(model=self.ui_board_void_cell), item.pos[0], item.pos[1]) self.place_item(item, new_x, new_y) elif (new_x is not None and new_y is not None and new_x >= 0 and new_y >= 0 and new_x < self.size[1] and new_y < self.size[0] and self._matrix[new_x][new_y].pickable()): if isinstance(item, Movable) and item.has_inventory(): item.inventory.add_item(self._matrix[new_x][new_y]) # Here instead of just placing a BoardItemVoid on the # departure position we first make sure there is no # _overlapping object to restore. if (item._overlapping is not None and isinstance(item._overlapping, Immovable) and item._overlapping.restorable() and (item._overlapping.pos[0] != new_x or item._overlapping.pos[1] != new_y)): self.place_item(item._overlapping, item._overlapping.pos[0], item._overlapping.pos[1]) item._overlapping = None else: self.place_item( BoardItemVoid(model=self.ui_board_void_cell), item.pos[0], item.pos[1]) self.place_item(item, new_x, new_y) elif (new_x is not None and new_y is not None and new_x >= 0 and new_y >= 0 and new_x < self.size[1] and new_y < self.size[0] and isinstance(self._matrix[new_x][new_y], Actionable)): if ((isinstance(item, Player) and ((self._matrix[new_x][new_y].perm == Constants.PLAYER_AUTHORIZED) or (self._matrix[new_x][new_y].perm == Constants.ALL_PLAYABLE_AUTHORIZED))) or (isinstance(item, NPC) and ((self._matrix[new_x][new_y].perm == Constants.NPC_AUTHORIZED) or (self._matrix[new_x][new_y].perm == Constants.ALL_PLAYABLE_AUTHORIZED)))): self._matrix[new_x][new_y].activate() else: raise HacObjectIsNotMovableException( (f"Item '{item.name}' at position [{item.pos[0]}, " "{item.pos[1]}] is not a subclass of Movable, " "therefor it cannot be moved."))
global game global is_modified game.clear_screen() print( Utils.blue_bright("\t\tNew board") ) print("First we need some information on your new board:") name = str( input('Name: ') ) width = int( input_digit('Width (in number of cells): ') ) height = int( input_digit('Height (in number of cells): ') ) game.add_board(1, Board(name=name,size=[width,height], ui_borders=Utils.WHITE_SQUARE,ui_board_void_cell=Utils.BLACK_SQUARE) ) is_modified=True # Main program game = Game() game.player = Player(model='[]') key = 'None' current_object = BoardItemVoid(model='None') object_history = [] current_menu = 'main' while True: game.clear_screen() print( Utils.cyan_bright("HAC-GAME-LIB - EDITOR v"+Constants.HAC_GAME_LIB_VERSION) ) print('Looking for existing maps in hac-maps/ directory...',end='') hmaps = [] try: hmaps = os.listdir('hac-maps/') print(Utils.green('OK')) except FileNotFoundError as e: print(Utils.red('KO')) if len(hmaps) > 0:
def create_wizard(): global game key = "" while True: game.clear_screen() print(Utils.green_bright("\t\tObject creation wizard")) print("What do you want to create: a NPC or a structure?") print("1 - NPC (Non Playable Character)") print("2 - Structure (Wall, Door, Treasure, Portal, Trees, etc.)") key = Utils.get_key() if key == "1" or key == "2": break if key == "1": game.clear_screen() print( Utils.green_bright("\t\tObject creation wizard: ") + Utils.cyan_bright("NPC")) new_object = NPC() print("First give a name to your NPC. Default value: " + new_object.name) r = str(input("(Enter name)> ")) if len(r) > 0: new_object.name = r print( "Then give it a type. A type is important as it allows grouping.\n" "Type is a string. Default value: " + new_object.type) r = str(input("(Enter type)> ")) if len(r) > 0: new_object.type = r print("Now we need a model. Default value: " + new_object.model) input('Hit "Enter" when you are ready to choose a model.') new_object.model = model_picker() game.clear_screen() print( Utils.green_bright("\t\tObject creation wizard: ") + Utils.cyan_bright("NPC") + f" - {new_object.model}") print("We now needs to go through some basic statistics. " "You can decide to go with default by simply hitting " 'the "Enter" key.') r = input_digit(f"Number of cell crossed in one turn. " f"Default: {new_object.step}(type: int) > ") if len(r) > 0: new_object.step = int(r) else: # If it's 0 it means it's going to be a static NPC so to prevent # python to pass some random pre-initialized default, we explicitly # set the Actuator to a static one new_object.actuator = SimpleActuators.RandomActuator(moveset=[]) r = input_digit(f"Max HP (Health Points). " f"Default: {new_object.max_hp}(type: int) > ") if len(r) > 0: new_object.max_hp = int(r) new_object.hp = new_object.max_hp r = input_digit(f"Max MP (Mana Points). " f"Default: {new_object.max_mp}(type: int) > ") if len(r) > 0: new_object.max_mp = int(r) new_object.mp = new_object.max_mp r = input_digit( f"Remaining lives (it is advised to set that to 1 for a " f"standard NPC). " f"Default: {new_object.remaining_lives}(type: int) > ") if len(r) > 0: new_object.remaining_lives = int(r) r = input_digit(f"AP (Attack Power). " f"Default: {new_object.attack_power}(type: int) > ") if len(r) > 0: new_object.attack_power = int(r) r = input_digit(f"DP (Defense Power). " f"Default: {new_object.defense_power}(type: int) > ") if len(r) > 0: new_object.defense_power = int(r) r = input_digit( f"Strength. Default: {new_object.strength}(type: int) > ") if len(r) > 0: new_object.strength = int(r) r = input_digit( f"Intelligence. Default: {new_object.intelligence}(type: int) > ") if len(r) > 0: new_object.intelligence = int(r) r = input_digit( f"Agility. Default: {new_object.agility}(type: int) > ") if len(r) > 0: new_object.agility = int(r) game.clear_screen() print("We now need to give some life to that NPC. " "What kind of movement should it have:") print("1 - Randomly chosen from a preset of directions") print("2 - Following a predetermined path") print("3 - Following a predetermined path back and forth") print( "4 - Automatically finding it's way from one point to another (no" " pre-determined path, you will set the points on the map).") r = Utils.get_key() if r == "1": new_object.actuator = SimpleActuators.RandomActuator(moveset=[]) print("Random it is! Now choose from which preset " "of movements should we give it:") print("1 - UP,DOWN,LEFT, RIGHT") print("2 - UP,DOWN") print("3 - LEFT, RIGHT") print("4 - UP,DOWN,LEFT, RIGHT + all DIAGONALES") print("5 - DIAGONALES (DIAG UP LEFT, DIAG UP RIGHT, etc.) " "but NO straight UP, DOWN, LEFT and RIGHT") print("6 - No movement") r = Utils.get_key() if r == "1": new_object.actuator.moveset = [ Constants.UP, Constants.DOWN, Constants.LEFT, Constants.RIGHT, ] elif r == "2": new_object.actuator.moveset = [Constants.UP, Constants.DOWN] elif r == "3": new_object.actuator.moveset = [Constants.RIGHT, Constants.LEFT] elif r == "4": new_object.actuator.moveset = [ Constants.UP, Constants.DOWN, Constants.LEFT, Constants.RIGHT, Constants.DLDOWN, Constants.DLUP, Constants.DRDOWN, Constants.DRUP, ] elif r == "5": new_object.actuator.moveset = [ Constants.DLDOWN, Constants.DLUP, Constants.DRDOWN, Constants.DRUP, ] elif r == "6": new_object.actuator.moveset = [] else: Utils.warn( f'"{r}" is not a valid choice. Movement set is now empty.') new_object.actuator.moveset = [] elif r == "2" or r == "3": if r == "2": new_object.actuator = SimpleActuators.PathActuator(path=[]) elif r == "3": new_object.actuator = SimpleActuators.PatrolActuator(path=[]) print("Great, so what path this NPC should take:") print("1 - UP/DOWN patrol") print("2 - DOWN/UP patrol") print("3 - LEFT/RIGHT patrol") print("4 - RIGHT/LEFT patrol") print("5 - Circle patrol: LEFT, DOWN, RIGHT, UP") print("6 - Circle patrol: LEFT, UP, RIGHT, DOWN") print("7 - Circle patrol: RIGHT, DOWN, LEFT, UP") print("8 - Circle patrol: RIGHT, UP, LEFT, DOWN") print("9 - Write your own path") r = Utils.get_key() if r == "1": print("How many steps should the NPC go in one direction " "before turning back ?") r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += ([ Constants.UP for i in range(0, r, 1) ], ) new_object.actuator.path += [ Constants.DOWN for i in range(0, r, 1) ] elif r == "2": print("How many steps should the NPC go in one " "direction before turning back ?") r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.DOWN for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.UP for i in range(0, r, 1) ] elif r == "3": print("How many steps should the NPC go in one " "direction before turning back ?") r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.LEFT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.RIGHT for i in range(0, r, 1) ] elif r == "3": print("How many steps should the NPC go in one direction " "before turning back ?") r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.RIGHT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.LEFT for i in range(0, r, 1) ] elif r == "4": print("How many steps should the NPC go in one " "direction before turning back ?") r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.DOWN for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.UP for i in range(0, r, 1) ] elif r == "5": print("How many steps should the NPC go in EACH " "direction before changing ?") r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.LEFT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.DOWN for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.RIGHT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.UP for i in range(0, r, 1) ] elif r == "6": print("How many steps should the NPC go in EACH " "direction before changing ?") r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.LEFT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.UP for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.RIGHT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.DOWN for i in range(0, r, 1) ] elif r == "7": print("How many steps should the NPC go in EACH " "direction before changing ?") r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.RIGHT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.DOWN for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.LEFT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.UP for i in range(0, r, 1) ] elif r == "8": print("How many steps should the NPC go in EACH direction " "before changing ?") r = int(input_digit("(please enter an integer)> ")) new_object.actuator.path += [ Constants.RIGHT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.UP for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.LEFT for i in range(0, r, 1) ] new_object.actuator.path += [ Constants.DOWN for i in range(0, r, 1) ] elif r == "9": print("Write your own path using only words from this list: " "UP, DOWN, LEFT, RIGHT, DLDOWN, DLUP, DRDOWN, DRUP.") print("Each direction has to be separated by a coma.") r = str(input("Write your path: ")).upper() new_object.actuator.path = r.split(",") else: Utils.warn(f'"{r}" is not a valid choice. Path is now empty.') new_object.actuator.path = [] elif r == "4": new_object.actuator = AdvancedActuators.PathFinder( parent=new_object, circle_waypoints=True) print( "Do you want the NPC to go through your way points once and stop or" " to cycle through all of them infinitely ?") print("1 - Cycle once") print("2 - Cycle infinitely (default value)") r = Utils.get_key() if r == "1": new_object.actuator.circle_waypoints = False return new_object elif key == "2": while True: game.clear_screen() print( Utils.green_bright("\t\tObject creation wizard: ") + Utils.magenta_bright("Structure")) print("What kind of structure do you want to create:") print( "1 - A wall like structure (an object that cannot be picked-up " "and is not overlappable). Ex: walls, trees, non moving " "elephant (try to go through an elephant or to pick it up " "in your backpack...)") print("2 - A door (player and/or NPC can go through)") print("3 - A treasure (can be picked up, take space in the " "inventory, give points to the player)") print("4 - A generic object (you can set the properties to " "make it pickable or overlappable)") print("5 - A generic actionable object (to make portals, heart " "to replenish life, etc.)") key = Utils.get_key() new_object = None if key == "1": new_object = Structures.Wall() new_object.name = str(uuid.uuid1()) new_object.model = model_picker() break elif key == "2": new_object = Structures.Door() new_object.name = str(uuid.uuid1()) new_object.model = model_picker() break elif key == "3": new_object = Structures.Treasure() print("First give a name to your Treasure. Default value: " + new_object.name) r = str(input("(Enter name)> ")) if len(r) > 0: new_object.name = r print("Then give it a type. A type is important as it allows " "grouping (in this case probably in the inventory).\n" "Type is a string. Default value: " + new_object.type) r = str(input("(Enter type)> ")) if len(r) > 0: new_object.type = r print("Now we need a model. Default value: " + new_object.model) input('Hit "Enter" when you are ready to choose a model.') new_object.model = model_picker() break elif key == "4" or key == "5": if key == "4": new_object = Structures.GenericStructure() else: new_object = Structures.GenericActionableStructure() new_object.set_overlappable(False) new_object.set_pickable(False) print("First give a name to your structure. Default value: " + new_object.name) r = str(input("(Enter name)> ")) if len(r) > 0: new_object.name = r print( "Then give it a type. \nType is a string. Default value: " + new_object.type) r = str(input("(Enter type)> ")) if len(r) > 0: new_object.type = r print("Now we need a model. Default value: " + new_object.model) input('Hit "Enter" when you are ready to choose a model.') new_object.model = model_picker() print("Is this object pickable? (can it be picked up " "by the player)?") print("0 - No") print("1 - Yes") r = Utils.get_key() if r == "1": new_object.set_pickable(True) print("Is this object overlappable? (can it be walked " "over by player?") print("0 - No") print("1 - Yes") r = Utils.get_key() if r == "1": new_object.set_overlappable(True) break return new_object # Placeholder return BoardItemVoid()
game.config("settings")["partial_display_viewport"] = [10, 30] game.config("settings")["menu_mode"] = "full" game.config("settings")["last_used_board_parameters"] = { "name": None, "width": None, "height": None, } game.config("settings")["object_library"] = [] # Main program game = Game() current_file = "" game.player = Player(model="[]") key = "None" current_object = BoardItemVoid(model="None") current_object_instance = BoardItemVoid(model="None") object_history = [] viewport_board = Board( name="Viewport testing board", size=[viewport_width * 2, viewport_height * 2], ui_borders=Utils.GREEN_SQUARE, ui_board_void_cell=Utils.RED_SQUARE, ) game.add_board(2, viewport_board) current_menu = "main" while True: game.clear_screen() print( Utils.cyan_bright("HAC-GAME-LIB - EDITOR v" + Constants.HAC_GAME_LIB_VERSION))