Now the level generator won't load planets from a folder, instead they are directly set from the editor, ands tarted porting the dungeon generator from the roguelike project. Also updated the world generator module to get the property type changes, this fixes some of the crashes.

This commit is contained in:
Relintai 2020-07-18 12:50:17 +02:00
parent c6429124fb
commit ec8e8d0406
12 changed files with 404 additions and 52 deletions

2
HEADS
View File

@ -1 +1 @@
{"engine": {"3.2": "07b24de868457c0a190c88771e99ff09e5451c3b", "master": "8c73e813134001e575b6f59e3b0100471c007410"}, "world_generator": {"master": "b70154cbddde9178e1d159a7acb7f738f7c8f487"}, "entity_spell_system": {"master": "af1bd74fbf38d0ac42d3cf203feb3c7212d01849"}, "ui_extensions": {"master": "6fe4f69fea8d71043b08d959b8085404c9c4fe47"}, "voxelman": {"master": "dee38b1588ef3224cf8022eaf227e1dcaead6277"}, "texture_packer": {"master": "2993ed34f34cfa6a5e61b7913380231e9c55eda6"}, "fastnoise": {"master": "d0e3f1c759332cf0d9a5d7e0e71d0b0278310651"}, "mesh_data_resource": {"master": "85417ebee9198be3cd7cc643e0e0e934db64a620"}, "procedural_animations": {"master": "9226d21781ea05828570e592874aa319df0dc53d"}, "ess_data": {"master": "3bd637fdd3304b64a18287a49a6b7387acf2f5de"}, "props": {"master": "544654f49b13af2d25ac14152c8a5014474e6333"}, "mesh_utils": {"master": "4f69ec67b861ce4475cfd17946dfaa586c888d94"}, "broken_seals_module": {"master": "0e5c54a70f8e90f95cbf11419b959a5f67562d48"}, "thread_pool": {"master": "93320fe864128d706bcc47fc7ed0731e6e9bcf69"}}
{"engine": {"3.2": "07b24de868457c0a190c88771e99ff09e5451c3b", "master": "8c73e813134001e575b6f59e3b0100471c007410"}, "world_generator": {"master": "873a5f3e4a88bbebdc317c2bd82d1ec0d045c9b5"}, "entity_spell_system": {"master": "af1bd74fbf38d0ac42d3cf203feb3c7212d01849"}, "ui_extensions": {"master": "6fe4f69fea8d71043b08d959b8085404c9c4fe47"}, "voxelman": {"master": "dee38b1588ef3224cf8022eaf227e1dcaead6277"}, "texture_packer": {"master": "2993ed34f34cfa6a5e61b7913380231e9c55eda6"}, "fastnoise": {"master": "d0e3f1c759332cf0d9a5d7e0e71d0b0278310651"}, "mesh_data_resource": {"master": "85417ebee9198be3cd7cc643e0e0e934db64a620"}, "procedural_animations": {"master": "9226d21781ea05828570e592874aa319df0dc53d"}, "ess_data": {"master": "3bd637fdd3304b64a18287a49a6b7387acf2f5de"}, "props": {"master": "544654f49b13af2d25ac14152c8a5014474e6333"}, "mesh_utils": {"master": "4f69ec67b861ce4475cfd17946dfaa586c888d94"}, "broken_seals_module": {"master": "0e5c54a70f8e90f95cbf11419b959a5f67562d48"}, "thread_pool": {"master": "93320fe864128d706bcc47fc7ed0731e6e9bcf69"}}

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=24 format=2]
[gd_scene load_steps=25 format=2]
[ext_resource path="res://ui/theme/ui_theme.tres" type="Theme" id=1]
[ext_resource path="res://ui/menu/CharacterEntry.tscn" type="PackedScene" id=2]
@ -20,12 +20,14 @@
[ext_resource path="res://scripts/world_generators/MainPlanetGenerator.gd" type="Script" id=18]
[ext_resource path="res://scripts/settings/DirectionalLightSettings.gd" type="Script" id=19]
[ext_resource path="res://ui/about/About.tscn" type="PackedScene" id=20]
[ext_resource path="res://modules/planets/test_planet/DungeonPlanetData.tres" type="PlanetData" id=21]
[sub_resource type="VoxelmanLevelGenerator" id=1]
script = ExtResource( 18 )
_force_planet = -1
_level_seed = 0
_spawn_mobs = false
planet = ExtResource( 21 )
[sub_resource type="ProceduralSky" id=2]
sky_top_color = Color( 0.447059, 0.780392, 0.854902, 1 )

View File

@ -1,9 +1,9 @@
[gd_resource type="PlanetData" load_steps=3 format=2]
[ext_resource path="res://modules/planets/test_planet/biomes/2_tdungb.tres" type="BiomeData" id=1]
[ext_resource path="res://modules/planets/test_planet/planets/simple_planet.tres" type="Planet" id=2]
[ext_resource path="res://modules/planets/test_planet/planets/simple_planet.tres" type="Planet" id=1]
[ext_resource path="res://modules/planets/test_planet/biomes/2_tdungb.tres" type="BiomeData" id=2]
[resource]
id = 1
planet = ExtResource( 2 )
biome_datas = [ ExtResource( 1 ) ]
planet = ExtResource( 1 )
biome_datas = [ ExtResource( 2 ) ]

View File

@ -0,0 +1,9 @@
[gd_resource type="PlanetData" load_steps=3 format=2]
[ext_resource path="res://modules/planets/test_planet/planets/simple_planet.tres" type="Planet" id=1]
[ext_resource path="res://modules/planets/test_planet/biomes/2_tdungb.tres" type="BiomeData" id=2]
[resource]
id = 1
planet = ExtResource( 1 )
biome_datas = [ ExtResource( 2 ) ]

View File

@ -6,4 +6,3 @@
[resource]
biome = ExtResource( 2 )
dungeon_datas = [ ExtResource( 1 ) ]
voxel_surfaces = [ null, null, null, null ]

View File

@ -20,11 +20,30 @@ extends BiomeBase
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
func _setup():
if !data:
return
for i in range(data.get_dungeon_data_count()):
var dd : DungeonData = data.get_dungeon_data(i)
if !dd:
continue
var d : Dungeon = dd.instance()
d.posx = 0
d.posz = 0
d.posy = -20
d.current_seed = current_seed
d.setup()
add_dungeon(d)
return
func _generate_chunk(chunk: VoxelChunk, spawn_mobs: bool) -> void:
# var chunk : VoxelChunk = chunk.get_chunk()
# generate_terrarin(chunk, spawn_mobs)
generate_simple_terrarin(chunk, spawn_mobs)
if not Engine.editor_hint and chunk.position_y == 0 and spawn_mobs and randi() % 4 == 0:

View File

@ -21,26 +21,41 @@ extends Dungeon
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
func _setup():
if data.get_dungeon_start_room_data_count() == 0:
return
var drd : DungeonRoomData = data.get_dungeon_start_room_data(0)
var dung : DungeonRoom
if drd.dungeon_room != null:
dung = drd.dungeon_room.duplicate()
else:
dung = DungeonRoom.new()
dung.posx = posx
dung.posy = posy
dung.posz = posz
dung.current_seed = current_seed
dung.data = drd
dung.setup()
export(int) var level_room_count : int = 9
export(int) var min_room_dimension : int = 5
export(int) var max_room_dimension : int = 8
export(int) var enemy_count : int = 14
add_dungeon_start_room(dung)
var map : Array = []
var rooms : Array = []
var enemies : Array = []
#var nav_graph : AStar2D
var entrance_position : Transform = Transform()
enum Tile { None, Floor, Wall, Door }
func _setup():
if sizex == 0 || sizey == 0 || sizez == 0:
print("Dungeon size is 0!")
return
# if data.get_dungeon_start_room_data_count() == 0:
# return
#
# var drd : DungeonRoomData = data.get_dungeon_start_room_data(0)
#
# var dung : DungeonRoom = drd.instance()
#
# dung.posx = posx
# dung.posy = posy
# dung.posz = posz
# dung.current_seed = current_seed
# dung.data = drd
# dung.setup()
#
# add_dungeon_start_room(dung)
# build()
pass
func _setup_library(library):
._setup_library(library)
@ -51,3 +66,293 @@ func _setup_library(library):
func _generate_chunk(chunk, spawn_mobs):
for i in range(get_dungeon_start_room_count()):
get_dungeon_start_room(i).generate_chunk(chunk, spawn_mobs)
func build():
# randomize()
build_level()
#Place player
# var start_room = rooms.front()
# var player_x = start_room.position.x + 1 + randi() % int(start_room.size.x - 2)
# var player_y = start_room.position.y + 1 + randi() % int(start_room.size.y - 2)
# entrance_position.origin = Vector2(player_x * tile_size + tile_size / 2, player_y * tile_size + tile_size / 2)
# _player = ESS.entity_spawner.load_player(_player_file_name, pos, 1) as Entity
#Server.sset_seed(_player.sseed)
#Place enemies
# for i in range(enemy_count):
# var room = rooms[1 + randi() % (rooms.size() - 1)]
# var x = room.position.x + 1 + randi() % int (room.size.x - 2)
# var y = room.position.y + 1 + randi() % int (room.size.y - 2)
#
# var blocked = false
# for enemy in enemies:
# var body = enemy.get_body()
# var bp = body.get_tile_position()
# if bp.x == x && bp.y == y:
# blocked = true
# break
#
# if !blocked:
# var t = tile_to_pixel_center(x, y)
# var enemy = ESS.entity_spawner.spawn_mob(1, 1, Vector3(t.x, t.y, 0), get_path())
#
# enemies.append(enemy)
#
# tile_map.update_dirty_quadrants()
#
# generated = true
func build_level():
rooms.clear()
map.clear()
for e in enemies:
e.queue_free()
enemies.clear()
# nav_graph = AStar2D.new()
for x in range(sizex):
map.append([])
for y in range(sizez):
map[x].append(Tile.Wall)
var free_regions = [Rect2(Vector2(2, 2), Vector2(sizex, sizez) - Vector2(4, 4))]
for i in range(level_room_count):
add_room(free_regions)
if free_regions.empty():
break
connect_rooms()
func connect_rooms():
var stone_graph : AStar2D = AStar2D.new()
var point_id : int = 0
for x in range(sizex):
for y in range(sizez):
if map[x][y] == Tile.Wall:
stone_graph.add_point(point_id, Vector2(x, y))
#connect to left if also stone
if x > 0 && map[x - 1][y] == Tile.Wall:
var left_point = stone_graph.get_closest_point(Vector2(x - 1, y))
stone_graph.connect_points(point_id, left_point)
#connect to above if also stone
if y > 0 && map[x][y - 1] == Tile.Wall:
var above_point = stone_graph.get_closest_point(Vector2(x, y - 1))
stone_graph.connect_points(point_id, above_point)
point_id += 1
#Build an AStar graph of room connections
var room_graph : AStar2D = AStar2D.new()
point_id = 0
for room in rooms:
var room_center = room.position + room.size / 2
room_graph.add_point(point_id, Vector2(room_center.x, room_center.y))
point_id += 1
#Add random connections until everything is connected
while !is_everything_connected(room_graph):
add_random_connection(stone_graph, room_graph)
func is_everything_connected(graph : AStar2D):
var points = graph.get_points()
var start = points.pop_back()
for point in points:
var path = graph.get_point_path(start, point)
if !path:
return false
return true
func add_random_connection(stone_graph : AStar2D, room_graph : AStar2D):
#Pick rooms to connect
var start_room_id = get_least_connected_point(room_graph)
var end_room_id = get_nearest_unconnected_point(room_graph, start_room_id)
#Pick door locations
var start_position = pick_random_door_location(rooms[start_room_id])
var end_position = pick_random_door_location(rooms[end_room_id])
#Find a path to connect the doors to each other
var closest_start_point = stone_graph.get_closest_point(start_position)
var closest_end_point = stone_graph.get_closest_point(end_position)
var path = stone_graph.get_point_path(closest_start_point, closest_end_point)
assert(path)
#Add path to the map
set_tile(start_position.x, start_position.y, Tile.Door)
set_tile(end_position.x, end_position.y, Tile.Door)
for position in path:
set_tile(position.x, position.y, Tile.Floor)
room_graph.connect_points(start_room_id, end_room_id)
func get_least_connected_point(graph : AStar2D):
var point_ids = graph.get_points()
var least
var tied_for_least = []
for point in point_ids:
var count = graph.get_point_connections(point).size()
if !least || count < least:
least = count
tied_for_least = [point]
elif count == least:
tied_for_least.append(point)
return tied_for_least[randi() % tied_for_least.size()]
func get_nearest_unconnected_point(graph : AStar2D, target_point):
var target_position = graph.get_point_position(target_point)
var point_ids = graph.get_points()
var nearest
var tied_for_nearest = []
for point in point_ids:
if point == target_point:
continue
var path = graph.get_point_path(point, target_point)
if path:
continue
var dist = (graph.get_point_position(point) - target_position).length()
if !nearest || dist < nearest:
nearest = dist
tied_for_nearest = [point]
elif dist == nearest:
tied_for_nearest.append(point)
return tied_for_nearest[randi() % tied_for_nearest.size()]
func pick_random_door_location(room):
var options = []
#Top and bottom walls
for x in range(room.position.x + 1, room.end.x - 2):
options.append(Vector2(x, room.position.y))
options.append(Vector2(x, room.end.y))
#Left and right walls
for y in range(room.position.y + 1, room.end.y - 2):
options.append(Vector2(room.position.x, y))
options.append(Vector2(room.end.x, y))
return options[randi() % options.size()]
func add_room(free_regions):
var region = free_regions[randi() % free_regions.size()]
var size_x = min_room_dimension
if region.size.x > min_room_dimension:
size_x += randi() % int(region.size.x - min_room_dimension)
var size_y = min_room_dimension
if region.size.y > min_room_dimension:
size_y += randi() % int(region.size.y - min_room_dimension)
size_x = min(size_x, min_room_dimension)
size_y = min(size_y, min_room_dimension)
var start_x = region.position.x
if region.size.x > size_x:
start_x += randi() % int(region.size.x - size_x)
var start_y = region.position.y
if region.size.y > size_y:
start_y += randi() % int(region.size.y - size_y)
var room = Rect2(start_x, start_y, size_x, size_y)
rooms.append(room)
for x in range(start_x, start_x + size_x):
set_tile(x, start_y, Tile.Wall)
set_tile(x, start_y + size_y - 1, Tile.Wall)
for y in range(start_y, start_y + size_y):
set_tile(start_x, y, Tile.Wall)
set_tile(start_x + size_x - 1, y, Tile.Wall)
for x in range(start_x + 1, start_x + size_x - 1):
set_tile(x, y, Tile.Floor)
cut_regions(free_regions, room)
func cut_regions(free_regions, region_to_remove):
var removal_queue = []
var addition_queue = []
for region in free_regions:
if region.intersects(region_to_remove):
removal_queue.append(region)
var leftover_left = region_to_remove.position.x - region.position.x - 1
var leftover_right = region_to_remove.end.x - region_to_remove.end.x - 1
var leftover_above = region_to_remove.position.y - region.position.y - 1
var leftover_below = region.end.y - region_to_remove.end.y - 1
if leftover_left >= min_room_dimension:
addition_queue.append(Rect2(region.position, Vector2(leftover_left, region.size.y)))
if leftover_right >= min_room_dimension:
addition_queue.append(Rect2(Vector2(region_to_remove.end.x + 1, region.position.y), Vector2(leftover_right, region.size.y)))
if leftover_above >= min_room_dimension:
addition_queue.append(Rect2(region.position, Vector2(region.size.x, leftover_above)))
if leftover_below >= min_room_dimension:
addition_queue.append(Rect2(Vector2(region.position.x, region_to_remove.end.y + 1), Vector2(region.size.x, leftover_below)))
for region in removal_queue:
free_regions.erase(region)
for region in addition_queue:
free_regions.append(region)
#
#func clear_path(tile):
# var new_point = nav_graph.get_available_point_id()
# nav_graph.add_point(new_point, Vector2(tile.x, tile.y))
#
# var points_to_conect = []
#
# if tile.x > 0 && map[tile.x - 1][tile.y] == Tile.Floor:
# points_to_conect.append(nav_graph.get_closest_point(Vector2(tile.x - 1, tile.y)))
#
# if tile.y > 0 && map[tile.x][tile.y - 1] == Tile.Floor:
# points_to_conect.append(nav_graph.get_closest_point(Vector2(tile.x, tile.y - 1)))
#
# if tile.x < 0 && map[tile.x + 1][tile.y] == Tile.Floor:
# points_to_conect.append(nav_graph.get_closest_point(Vector2(tile.x + 1, tile.y)))
#
# if tile.y < 0 && map[tile.x][tile.y + 1] == Tile.Floor:
# points_to_conect.append(nav_graph.get_closest_point(Vector2(tile.x, tile.y + 1)))
#
# for point in points_to_conect:
# nav_graph.connect_points(point, new_point)
func set_tile(x, y, type):
map[x][y] = type
# if type == Tile.Floor:
# clear_path(Vector2(x, y))

View File

@ -3,4 +3,11 @@
[ext_resource path="res://modules/planets/test_planet/dungeons/dungeon.gd" type="Script" id=1]
[resource]
sizex = 40
sizey = 3
sizez = 40
script = ExtResource( 1 )
level_room_count = 9
min_room_dimension = 5
max_room_dimension = 8
enemy_count = 14

View File

@ -36,20 +36,20 @@ func _setup():
b.setup()
add_biome(b)
if bdata.get_dungeon_data_count() == 0:
return
var dd : DungeonData = bdata.get_dungeon_data(0)
var dung : Dungeon = dd.instance()
dung.posx = 0
dung.posy = -4
dung.posz = 0
dung.current_seed = current_seed
dung.setup()
add_dungeon(dung)
# if bdata.get_dungeon_data_count() == 0:
# return
#
# var dd : DungeonData = bdata.get_dungeon_data(0)
#
# var dung : Dungeon = dd.instance()
#
# dung.posx = 0
# dung.posy = -4
# dung.posz = 0
# dung.current_seed = current_seed
# dung.setup()
#
# add_dungeon(dung)
func _setup_library(library):
._setup_library(library)

View File

@ -1,9 +1,10 @@
[gd_scene load_steps=9 format=2]
[gd_scene load_steps=10 format=2]
[ext_resource path="res://scripts/world_generators/MainPlanetGenerator.gd" type="Script" id=1]
[ext_resource path="res://modules/planets/test_planet/voxel_library/1_main_lib_merger_empty.tres" type="VoxelmanLibraryMerger" id=2]
[ext_resource path="res://scripts/settings/DirectionalLightSettings.gd" type="Script" id=3]
[ext_resource path="res://test_props/MeshDataInstance.tres" type="PropData" id=4]
[ext_resource path="res://modules/planets/test_planet/DungeonPlanetData.tres" type="PlanetData" id=5]
[ext_resource path="res://voxelman/world/TVVoxelWorld.gd" type="Script" id=8]
[sub_resource type="VoxelmanLevelGenerator" id=1]
@ -11,6 +12,7 @@ script = ExtResource( 1 )
_force_planet = -1
_level_seed = 0
_spawn_mobs = false
planet = ExtResource( 5 )
[sub_resource type="ProceduralSky" id=2]
sky_top_color = Color( 0.34902, 0.643137, 0.705882, 1 )

View File

@ -27,6 +27,7 @@ const planet_folder : String = "res://modules/planets"
export(int) var _force_planet : int = -1
export(int) var _level_seed : int
export(bool) var _spawn_mobs : bool
export(PlanetData) var planet : PlanetData = null
var _world : VoxelWorld
var _planet : Planet
@ -38,7 +39,13 @@ func setup(world : VoxelWorld, level_seed : int, spawn_mobs : bool, library: Vox
_spawn_mobs = spawn_mobs
_library = library
create_planet()
if planet:
_planet = planet.instance()
_planet.current_seed = _level_seed
_planet.setup()
_planet.setup_library(_library)
# create_planet()
func _generate_chunk(chunk : VoxelChunk) -> void:
if _planet == null:
@ -66,11 +73,8 @@ func create_planet():
return
print("planet loaded: " + planet_data.resource_path)
if planet_data.planet != null:
_planet = planet_data.planet.duplicate()
else:
_planet = Planet.new()
_planet = planet_data.instance()
_planet.current_seed = _level_seed
_planet.data = planet_data

View File

@ -45,13 +45,18 @@ const VIS_UPDATE_INTERVAL = 5
var vis_update : float = 0
var _max_frame_chunk_build_temp : int
var rc : int = 0
func _enter_tree():
if generate_on_ready and not Engine.is_editor_hint():
# call_deferred("generate")
generate()
func generate():
if level_generator != null:
level_generator.setup(self, 80, false, library)
if level_generator != null:
level_generator.setup(self, 80, false, library)
spawn()
spawn()
func _process(delta):
if initial_generation: