Advertisement
jamesonBradfield

dun_gen.gd

Mar 1st, 2024 (edited)
276
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. @tool
  2. extends Node3D
  3. # bool to start the generation
  4. @export var start : bool = false : set = set_start
  5. # grid map var
  6. @onready var grid_map : GridMap = $GridMap
  7. @onready var dun_mesh = $DunMesh
  8.  
  9. func set_start(val:bool)->void:
  10.     generate()
  11. # number of rooms to spawn
  12. @export var room_number : int = 4
  13. # space between rooms and border
  14. @export var room_margin : int = 1
  15. @export var room_recursion : int = 15
  16. @export var min_room_size : int = 2
  17. @export var max_room_size : int = 4
  18. @export_multiline var custom_seed :String = "" : set = set_seed
  19. func set_seed(val:String)->void:
  20.     custom_seed = val
  21.     seed(val.hash())
  22.  
  23. var room_tiles : Array[PackedVector3Array] = []
  24. var room_positions : PackedVector3Array = []
  25.  
  26. @export_range(0,1) var survival_chance : float = .25
  27. @export var border_size : int = 20 : set = set_border_size
  28.  
  29. func _ready():
  30.     generate()
  31.     await get_tree().create_timer(5).timeout
  32.     dun_mesh.create_dungeon()
  33. func set_border_size(val:int)->void:
  34.     border_size = val
  35.     if Engine.is_editor_hint():
  36.         visualize_border()
  37. # generate the red border to visualize the border_size
  38. func visualize_border():
  39.     grid_map.clear()
  40.     # grid map id 3 is visualize_border
  41.     for i in range(-1,border_size+1):
  42.         grid_map.set_cell_item( Vector3i(i,0,-1),3)
  43.         grid_map.set_cell_item( Vector3i(i,0,border_size),3)
  44.         grid_map.set_cell_item( Vector3i(border_size,0,i),3)
  45.         grid_map.set_cell_item( Vector3i(-1,0,i),3)
  46.  
  47. func generate():
  48.     room_tiles.clear()
  49.     room_positions.clear()
  50.     if custom_seed : set_seed(custom_seed)
  51.     visualize_border()
  52.     for i in room_number:
  53.         make_room(room_recursion,i)
  54.     var room_positions_vector2 : PackedVector2Array = []
  55.     var delaunay_graph : AStar2D = AStar2D.new()
  56.     var minimum_spanning_tree_graph : AStar2D = AStar2D.new()
  57.  
  58.  
  59.     for p in room_positions:
  60.         room_positions_vector2.append(Vector2(p.x,p.z))
  61.         delaunay_graph.add_point(delaunay_graph.get_available_point_id(),Vector2(p.x,p.z))
  62.         minimum_spanning_tree_graph.add_point(minimum_spanning_tree_graph.get_available_point_id(),Vector2(p.x,p.z))
  63.     # this function takes the vector2 of our rooms and returns a array of vector2s that corresponds to the triangles made by connecting all points.
  64.     var delaunay : Array = Array(Geometry2D.triangulate_delaunay(room_positions_vector2))
  65.     # we go through them here and connect each point making the triangle.
  66.     for i in delaunay.size()/3:
  67.         var p1 : int = delaunay.pop_front()
  68.         var p2 : int = delaunay.pop_front()
  69.         var p3 : int = delaunay.pop_front()
  70.         delaunay_graph.connect_points(p1,p2)
  71.         delaunay_graph.connect_points(p2,p3)
  72.         delaunay_graph.connect_points(p1,p3)
  73.     # this is where MST code starts
  74.     var visited_points : PackedInt32Array = []
  75.     visited_points.append(randi() % room_positions.size())
  76.     while visited_points.size() != minimum_spanning_tree_graph.get_point_count():
  77.         var possible_connections : Array[PackedInt32Array] = []
  78.         for vp in visited_points:
  79.             for c in delaunay_graph.get_point_connections(vp):
  80.                 if !visited_points.has(c):
  81.                     var con : PackedInt32Array = [vp,c]
  82.                     possible_connections.append(con)
  83.         var connection : PackedInt32Array = possible_connections.pick_random()
  84.         for pc in possible_connections:
  85.             if room_positions_vector2[pc[0]].distance_squared_to(room_positions_vector2[1]) <\
  86.                 room_positions_vector2[connection[0]].distance_squared_to(room_positions_vector2[connection[1]]):
  87.                     connection = pc
  88.        
  89.             visited_points.append(connection[1])
  90.             minimum_spanning_tree_graph.connect_points(connection[0],connection[1])
  91.             delaunay_graph.disconnect_points(connection[0],connection[1])
  92.                
  93.         var hallway_graph : AStar2D = minimum_spanning_tree_graph
  94.        
  95.         for p in delaunay_graph.get_point_ids():
  96.             for c in delaunay_graph.get_point_connections(p):
  97.                 if c>p:
  98.                     var kill : float = randf()
  99.                     if survival_chance > kill :
  100.                         hallway_graph.connect_points(p,c)
  101.         create_hallways(hallway_graph) 
  102.  
  103. func make_room(rec:int,RoomID:int):
  104.     if !rec>0:
  105.         return
  106.  
  107.     var width : int = (randi() % (max_room_size - min_room_size)) + min_room_size
  108.     var height : int = (randi() % (max_room_size - min_room_size)) + min_room_size
  109.  
  110.     var start_pos : Vector3i
  111.     start_pos.x = randi() % (border_size - width + 1)
  112.     start_pos.z = randi() % (border_size - height + 1)
  113.    
  114.  
  115.     for r in range(-room_margin,height + room_margin):
  116.         for c in range(-room_margin,width + room_margin):
  117.             var pos : Vector3i = start_pos + Vector3i(c,0,r)
  118.             if grid_map.get_cell_item(pos) == 0:
  119.                 make_room(rec-1,RoomID)
  120.                 return
  121.  
  122.     var room : PackedVector3Array = []
  123.     for r in height:
  124.         for c in width:
  125.             var pos : Vector3i = start_pos + Vector3i(c,0,r)
  126.             # rooms have an id of 0
  127.             grid_map.set_cell_item(pos, 0)
  128.             room.append(pos)
  129.     room_tiles.append(room)
  130.     var avg_x : float = start_pos.x + (float(width)/2)
  131.     var avg_z : float = start_pos.z + (float(height)/2)
  132.     var pos : Vector3 = Vector3(avg_x,0,avg_z)
  133.     room_positions.append(pos)
  134.  
  135.  
  136. func create_hallways(hallway_graph:AStar2D):
  137.     var hallways : Array[PackedVector3Array] = []
  138.     for p in hallway_graph.get_point_ids():
  139.         for c in hallway_graph.get_point_connections(p):
  140.             if c>p:
  141.                 var room_from : PackedVector3Array = room_tiles[p]
  142.                 var room_to : PackedVector3Array = room_tiles[c]
  143.                 var tile_from : Vector3 = room_from[0]
  144.                 var tile_to : Vector3 = room_to[0]
  145.                 for t in room_from:
  146.                     if t.distance_squared_to(room_positions[c])<\
  147.                     tile_from.distance_squared_to(room_positions[c]):
  148.                         tile_from = t
  149.                    
  150.                 for t in room_to:
  151.                     if t.distance_squared_to(room_positions[p])<\
  152.                     tile_to.distance_squared_to(room_positions[p]):
  153.                         tile_to = t
  154.                
  155.                 var hallway :PackedVector3Array = [tile_from,tile_to]
  156.                 hallways.append(hallway)
  157.                 grid_map.set_cell_item(tile_from,2)
  158.                 grid_map.set_cell_item(tile_to,2)
  159.  
  160.     var astar : AStarGrid2D = AStarGrid2D.new()
  161.     astar.size = Vector2i.ONE * border_size
  162.     astar.update()
  163.     astar.diagonal_mode = AStarGrid2D.DIAGONAL_MODE_NEVER
  164.     astar.default_estimate_heuristic = AStarGrid2D.HEURISTIC_MANHATTAN
  165.    
  166.  
  167.     for t in grid_map.get_used_cells_by_item(0):
  168.         astar.set_point_solid(Vector2i(t.x,t.z))
  169.  
  170.     for h in hallways:
  171.         var pos_from : Vector2i = Vector2i(h[0].x,h[0].z)
  172.         var pos_to : Vector2i = Vector2i(h[1].x,h[1].z)
  173.         var hall : PackedVector2Array = astar.get_point_path(pos_from,pos_to)
  174.        
  175.         for t in hall:
  176.             var pos : Vector3i = Vector3i(t.x,0,t.y)
  177.             if grid_map.get_cell_item(pos) < 0:
  178.                 grid_map.set_cell_item(pos,1)
  179.  
  180.     # func choose_spawnpoint(val:PackedVector3Array):
  181.     #   for r in val:
  182.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement