def build_meta_map(self, build_data): if not build_data.rooms: print( f'Room based spawning only work after rooms have been created.' ) raise ProcessLookupError else: rooms = deepcopy(build_data.rooms) connected = dict() corridors = list() for i, room in enumerate(rooms): room_distance = list() room_x, room_y = room.center() for j, other_room in enumerate(rooms): if i != j and not connected.get(j): other_x, other_y = other_room.center() distance = distance_to(room_x, room_y, other_x, other_y) room_distance.append((j, distance)) if room_distance: room_distance = sorted( room_distance, key=lambda room_to_sort: room_to_sort[1]) dest_center_x, dest_center_y = rooms[room_distance[0] [0]].center() corridor = draw_corridor(build_data.map, room_x, room_y, dest_center_x, dest_center_y) connected[i] = True build_data.take_snapshot() corridors.append(corridor) build_data.corridors = corridors
def build(self, build_data, start_x, start_y): if start_x == StartX.LEFT: x = 1 elif start_x == StartX.CENTER: x = build_data.map.width // 2 elif start_x == StartX.RIGHT: x = build_data.map.width - 2 else: print('AreaStartingPosition : wrong type of Start X') raise NotImplementedError if start_y == StartY.TOP: y = 1 elif start_y == StartY.CENTER: y = build_data.map.height // 2 elif start_y == StartY.BOTTOM: y = build_data.map.height - 2 else: print('AreaStartingPosition : wrong type of Start Y') raise NotImplementedError available_floors = list() for idx, tile in enumerate(build_data.map.tiles): if tile == TileType.FLOOR: closest_x, closest_y = build_data.map.index_to_point2d(idx) available_floors.append( (idx, distance_to(x, y, closest_x, closest_y))) available_floors = sorted(available_floors, key=lambda floor: floor[1]) new_x, new_y = build_data.map.index_to_point2d(available_floors[0][0]) build_data.starting_position = new_x, new_y
def build_meta_map(self, build_data): if not build_data.rooms: print( f'Room based spawning only work after rooms have been created.' ) raise ProcessLookupError else: rooms = deepcopy(build_data.rooms) connected = dict() corridors = list() for i, room in enumerate(rooms): room_distance = list() room_x, room_y = room.center() for j, other_room in enumerate(rooms): if i != j and not connected.get(j): other_x, other_y = other_room.center() distance = distance_to(room_x, room_y, other_x, other_y) room_distance.append((j, distance)) if room_distance: room_distance = sorted( room_distance, key=lambda room_to_sort: room_to_sort[1]) dest_center_x, dest_center_y = rooms[room_distance[0] [0]].center() lines = tcod.line_where(room_x, room_y, dest_center_x, dest_center_y) cell_x = lines[0] cell_y = lines[1] last_x = cell_x[0] last_y = cell_y[0] corridor = list() for cell in range(0, len(cell_y) - 1): if last_x != cell_x[cell] and last_y != cell_y[cell]: if randint(1, 2) == 1: idx = build_data.map.xy_idx( cell_x[cell], last_y) build_data.map.tiles[idx] = TileType.FLOOR else: idx = build_data.map.xy_idx( last_x, cell_y[cell]) build_data.map.tiles[idx] = TileType.FLOOR idx = int( build_data.map.xy_idx(cell_x[cell], cell_y[cell])) build_data.map.tiles[idx] = TileType.FLOOR last_x = cell_x[cell] last_y = cell_y[cell] corridor.append(idx) corridors.append(corridor) connected[i] = True build_data.take_snapshot() build_data.corridors = corridors
def update(self, *args, **kwargs): subjects = World.get_components(NameComponent, MonsterComponent, ViewshedComponent, PositionComponent, MyTurn) player = World.fetch('player') player_position = World.get_entity_component(player, PositionComponent) x, y = player_position.x, player_position.y for entity, (name, monster, viewshed, position_component, _myturn, *args) in subjects: can_act = True is_confused = World.get_entity_component(entity, ConfusionComponent) if is_confused: is_confused.turns -= 1 if is_confused.turns < 1: World.remove_component(ConfusionComponent, entity) can_act = False ParticuleBuilder.request(position_component.x, position_component.y, 'magenta', '?', 'particules/confusion.png') if can_act: print( f'monster ai: player position is {player_position.x, player_position.y} - checking {x, y}' ) if viewshed.visible_tiles[y][x]: print(f'me, monster {entity}, I see player position') if distance_to(position_component.x, position_component.y, player_position.x, player_position.y) <= 1.5: want_to_melee = WantsToMeleeComponent(player) World.add_component(want_to_melee, entity) else: move_astar = self.move_astar(entity, viewshed, position_component, player_position.x, player_position.y) current_map = World.fetch('current_map') if move_astar: x, y = move_astar move_to(x, y, entity, current_map) else: print(f'astar didnt work. Move towards instead.') self.move_towards(entity, position_component, player_position.x, player_position.y, current_map) else: print( f'me, monster {entity}, I dont see player and wait. Im at {position_component.x, position_component.y}' ) # do nothing, pass its turn. action_wait(entity)
def draw_circle(self, gmap, room): radius = min(room.x2 - room.x1, room.y2 - room.y1) / 2.0 center_x, center_y = room.center() ''' for y in range(room.y1, room.y2): for x in range(room.x1, room.x2): idx = gmap.xy_idx(x, y) distance = distance_to(x, y, center_x, center_y) if 0 < idx < (gmap.width * gmap.height) - 1 and distance < radius: gmap.tiles[idx] = TileType.FLOOR ''' for x, y in it_product(range(room.x1, room.x2), range(room.y1, room.y2)): idx = gmap.xy_idx(x, y) distance = distance_to(x, y, center_x, center_y) if 0 < idx < (gmap.width * gmap.height) - 1 and distance < radius: gmap.tiles[idx] = TileType.FLOOR
def show_targeting(): player = World.fetch('player') player_pos = World.get_entity_component(player, PositionComponent) min_x, max_x, min_y, max_y = get_screen_bounds() current_map = World.fetch('current_map') viewshed = World.get_entity_component(player, ViewshedComponent) targeter = World.get_entity_component(player, TargetingComponent) available_cells = list() x = 0 y = 0 for row in viewshed.visible_tiles: for tile in row: if tile and distance_to(player_pos.x, player_pos.y, x, y) < targeter.range: screen_x = x - min_x screen_y = y - min_y if 1 < screen_x < (max_x - min_x) - 1 and 1 < screen_y < (max_y - min_y): if Interface.mode == GraphicalModes.TILES: draw_tile(screen_x * Interface.zoom, screen_y * Interface.zoom, ' ', 'particules/grid.png', 'light blue', Layers.INTERFACE) elif Interface.mode == GraphicalModes.ASCII: draw_tile(screen_x * Interface.zoom, screen_y * Interface.zoom, ' ', 'system/grid.png', 'light blue', Layers.BACKGROUND, 'light blue') else: print(f'Targeting system: {Interface.mode} not supported') raise NotImplementedError available_cells.append(current_map.xy_idx(x, y)) print(f'target: x,y : {x, y}. Mscreen : {screen_x, screen_y}, screenZoom: {screen_x * Interface.zoom, screen_y * Interface.zoom}') x += 1 y += 1 x = 0 mouse_pos_x = (terminal.state(terminal.TK_MOUSE_X) // Interface.zoom) + min_x mouse_pos_y = (terminal.state(terminal.TK_MOUSE_Y) // Interface.zoom) + min_y print(f'mouse : {mouse_pos_x, mouse_pos_y}') valid_target = False for idx in available_cells: cell_x, cell_y = current_map.index_to_point2d(idx) if mouse_pos_x == cell_x and mouse_pos_y == cell_y: valid_target = True render_entities_camera() terminal.refresh() return targeting_input(targeter.item, (mouse_pos_x, mouse_pos_y), valid_target)
def update(self, *args, **kwargs): run_state = World.fetch('state') if run_state.current_state != States.TICKING: return print(f'initiative : run state is : {run_state.current_state}') # on s'assure qu'i n'y a plus de "My Turn". World.remove_component_for_all_entities(MyTurn) player = World.fetch('player') player_pos = World.get_entity_component(player, PositionComponent) subjects = World.get_components(InitiativeComponent, PositionComponent) # subjects = sorted(subjects, key=lambda entry: entry[1][0].current) for entity, (initiative, position) in subjects: print(f'INITIATIVE: {entity} initiative is : {initiative.current}') # on ajoute les penalités d'initiative. initiative_cost = World.get_entity_component( entity, InitiativeCostComponent) if initiative_cost: initiative.current += initiative_cost.cost World.remove_component(InitiativeCostComponent, entity) else: if entity != player and distance_to( player_pos.x, player_pos.y, position.x, position.y) > config.MIN_DISTANCE_TO_BE_ACTIVE: print( f'INITIATIVE: {entity} is not active. Initiative is : {initiative.current}' ) continue print( f'INITIATIVE: {entity} is active, with : {initiative.current}' ) initiative.current -= config.DEFAULT_INITIATIVE_TICK if initiative.current < 1: # Cas 2: I dont have an InitiativeCost. I must do something. World.add_component(MyTurn(), entity) if entity == World.fetch('player'): run_state.change_state(States.AWAITING_INPUT)