extends Navigation2D export (PackedScene) var room : PackedScene export (NodePath) var map_path : NodePath var map var tile_size : int = 3 var num_rooms : int = 50 var min_size : int = 9 var max_size : int = 20 var hspread : float = 400 var cull : float = 0.5 var path : AStar func _ready(): map = get_node(map_path) randomize() make_rooms() func make_rooms(): for i in range(num_rooms): var pos : Vector2 = Vector2(rand_range(-hspread, hspread), 0) var r : Node = room.instance() var w = min_size + randi() % (max_size - min_size) var h = min_size + randi() % (max_size - min_size) r.make_room(pos, Vector2(w, h)* tile_size) $Rooms.add_child(r) r.owner = $Rooms yield(get_tree().create_timer(1.1), 'timeout') #cull rooms var room_positions : Array = [] for room in $Rooms.get_children(): if randf() < cull: room.queue_free() else: room.mode = RigidBody2D.MODE_STATIC room_positions.append(Vector3(room.position.x, room.position.y, 0)) yield(get_tree(), 'idle_frame') #generate MST path = find_mst(room_positions) make_map() func a_draw(): for room in $Rooms.get_children(): draw_rect(Rect2(room.position - room.size, room.size * 2), Color(0, 1, 0), false) if path: for p in path.get_points(): for c in path.get_point_connections(p): var pp = path.get_point_position(p) var cp = path.get_point_position(c) draw_line(Vector2(pp.x, pp.y), Vector2(cp.x, cp.y), Color(1, 1, 0), 15, true) func a_process(delta): update() func a_input(event): if event.is_action_pressed('ui_select'): for n in $Rooms.get_children(): n.queue_free() path = null make_rooms() if event.is_action_pressed('ui_focus_next'): make_map() func find_mst(nodes : Array) -> AStar: #Prim's algorithm var path = AStar.new() path.add_point(path.get_available_point_id(), nodes.pop_front()) while nodes: var min_dist = INF var min_p = null var p = null for p1 in path.get_points(): p1 = path.get_point_position(p1) for p2 in nodes: if p1.distance_to(p2) < min_dist: min_dist = p1.distance_to(p2) min_p = p2 p = p1 var n = path.get_available_point_id() path.add_point(n, min_p) path.connect_points(path.get_closest_point(p), n) nodes.erase(min_p) return path func make_map() -> void: map.clear() #for x in range(0, 200): # for y in range(0, 200): # tile_map.set_cell(x, y, 0) #fill tilemap with walls #var full_rect = Rect2() #carve the rooms var corridors = [] var mob_count = 0 var player_spawned = false for room in $Rooms.get_children(): var top_left = room.position.floor() var bottom_right = (top_left + room.size).floor() for x in range(top_left.x, bottom_right.x): for z in range(top_left.y, bottom_right.y): for y in range(0, 2): map.draw_voxel_data_point(Vector3(x, y, z), 0, randi() % 255) #connection #var p = path.get_closest_point(Vector3(room.position.x, room.position.y, 0)) #for conn in path.get_point_connections(p): # if not conn in corridors: # var start = Vector2(path.get_point_position(p).x, path.get_point_position(p).y).ceil() # var end = Vector2(path.get_point_position(conn).x, path.get_point_position(conn).y).ceil() # carve_path(start, end) #corridors.append(p) var pos : Vector2 = room.position + (room.size / 2).floor() if not player_spawned: #Entities.spawn_player(1, Vector3(pos.x, 2, pos.y)) player_spawned = true else: if mob_count < 20: Entities.spawn_mob(1, randi() % 3, Vector3(pos.x, 2, pos.y)) mob_count += 1 map.build() func carve_path(pos1, pos2): var x_diff = sign(pos2.x - pos1.x) var y_diff = sign(pos2.y - pos1.y) if x_diff == 0: x_diff = pow(-1.0, randi() % 2) if y_diff == 0: y_diff = pow(-1.0, randi() % 2) var x_y = pos1 var y_x = pos2 #if (randi() % 2) > 0: # x_y = pos2 # y_x = pos1 for x in range(pos1.x, pos2.x, x_diff): for n in range(5): var tile = 1 if n == 0 or n == 4: tile = 0 # if tile_map.get_cell(x, x_y.y + (n * y_diff)) != 1: # tile_map.set_cell(x, x_y.y + (n * y_diff), tile) for y in range(pos1.y, pos2.y, y_diff): for n in range(5): var tile = 1 if n == 0 or n == 4: tile = 0 # if tile_map.get_cell(y_x.x + (n * x_diff), y) != 1: # tile_map.set_cell(y_x.x + (n * x_diff), y, tile)