From 2b2d175a66e9bf6f15b0c089f46f2cc791e0a5c6 Mon Sep 17 00:00:00 2001 From: Relintai Date: Tue, 24 Aug 2021 21:08:34 +0200 Subject: [PATCH] Initial Building implementation. The room transforms are still broken, will figure them out later. --- game/scripts/dungeons/dungeon.gd | 172 ++++++++++++++++++++++++++++--- game/test_dungeon/Dungtest.tscn | 12 ++- 2 files changed, 168 insertions(+), 16 deletions(-) diff --git a/game/scripts/dungeons/dungeon.gd b/game/scripts/dungeons/dungeon.gd index d67ba6fe..153bbc03 100644 --- a/game/scripts/dungeons/dungeon.gd +++ b/game/scripts/dungeons/dungeon.gd @@ -6,40 +6,186 @@ export(PropData) var start_room : PropData export(Array, PropData) var rooms : Array export(bool) var generate : bool setget set_generate, get_generate +#todo calc aabbs and store in PropData during prop conversion +var room_aabbs : Dictionary var portal_map : Dictionary +var portals : Array + +var current_aabbs : Array var debug : bool = true -func _enter_tree(): +func _enter_tree() -> void: if not Engine.editor_hint && generate_on_ready: call_deferred("generate") -func set_up_room_data(): +func set_up_room_data() -> void: clear_room_data() + + process_prop(start_room) + + for r in rooms: + process_prop(r) + + process_portals() + +func process_prop(room : PropData) -> void: + if !room: + return + + if !room.is_room: + return + + if room in room_aabbs: + return + + var ps : PoolVector3Array = room.room_bounds + + var aabb : AABB = AABB() + + for p in ps: + aabb.expand(p) + + room_aabbs[room] = aabb + + for i in range(room.props.size()): + var pe : PropDataEntry = room.props[i] + + if pe is PropDataPortal: + portals.append([pe, room, i]) + + +func process_portals() -> void: + for i in range(portals.size()): + var pe = portals[i] + + var portal : PropDataPortal = pe[0] + var room : PropData = pe[1] + + var portal_points : PoolVector2Array = portal.points + + if portal in portal_map: + continue + + var map_data : Array = Array() + + for j in range(portals.size()): + if i == j: + continue + + var pp : Array = portals[j] + var cportal : PropDataPortal = pp[0] + + var cportal_points : PoolVector2Array = cportal.points + + if (cportal_points.size() != portal_points.size()): + continue + + var eq : bool = true + + for k in range(portal_points.size()): + var p1 : Vector2 = portal_points[k] + var p2 : Vector2 = cportal_points[k] + + if !p1.is_equal_approx(p2): + eq = false + break + + if !eq: + continue + + var croom : PropData = pp[1] + var cj : int = pp[2] -func clear_room_data(): + map_data.append([ croom, cportal, cj ]) + + portal_map[portal] = map_data + + #print(portal_map) + +func clear_room_data() -> void: portal_map.clear() + portals.clear() + room_aabbs.clear() + current_aabbs.clear() -func generate(): +func generate() -> void: clear() set_up_room_data() + spawn_room(Transform(), start_room) + -func clear(): - if not debug: - for c in get_children(): - if c.owner == self: - #don't destroy the user's nodes +func spawn_room(tf : Transform, room : PropData, level : int = 0, current_portal : PropDataPortal = null) -> void: + if level > 2: + return + + var sr : PropInstanceMerger = PropInstanceMerger.new() + sr.prop_data = start_room + add_child(sr) + sr.transform = tf + + if Engine.editor_hint and debug: + sr.owner = get_tree().edited_scene_root + + var caabb : AABB = room_aabbs[room] + caabb.position = tf.xform(Vector3()) + current_aabbs.push_back(caabb) + + for pe in room.props: + if pe is PropDataPortal: + if pe == current_portal: + continue + + var ntf : Transform = pe.transform * tf + + var d : Array = portal_map[pe] + + if d.size() == 0: continue - c.queue_delete() + randomize() + + var new_room_data = d[randi() % d.size()] + + #[ croom, cportal, cj ] + var new_room : PropData = new_room_data[0] + var new_room_portal : PropDataPortal = new_room_data[1] + + #todo figure out the transforms + var poffset : Vector3 = new_room_portal.transform.xform(Vector3()) + poffset.x += 1 + + var offsert_ntf : Transform = ntf + offsert_ntf = offsert_ntf.translated(-poffset) + + var ab : AABB = room_aabbs[new_room] + ab.position = offsert_ntf.xform(Vector3()) + + + var can_spawn : bool = true + for saab in current_aabbs: + if ab.intersects(saab): + #todo implement plugs + can_spawn = false + break + + if can_spawn: + spawn_room(offsert_ntf, new_room, level + 1, new_room_portal) + +func clear() -> void: + if Engine.editor_hint and debug: + #don't destroy the user's nodes + for c in get_children(): + if c.owner == get_tree().edited_scene_root: + c.queue_free() else: for c in get_children(): - c.queue_delete() + c.queue_free() -func set_generate(on): +func set_generate(on) -> void: if on: generate() -func get_generate(): +func get_generate() -> bool: return false diff --git a/game/test_dungeon/Dungtest.tscn b/game/test_dungeon/Dungtest.tscn index 12b70af0..524dc655 100644 --- a/game/test_dungeon/Dungtest.tscn +++ b/game/test_dungeon/Dungtest.tscn @@ -1,15 +1,21 @@ -[gd_scene load_steps=7 format=2] +[gd_scene load_steps=6 format=2] [ext_resource path="res://scripts/dungeons/dungeon.gd" type="Script" id=1] [ext_resource path="res://test_rooms/Room1.tres" type="PropData" id=2] -[ext_resource path="res://test_rooms/Room2.tres" type="PropData" id=3] [ext_resource path="res://test_rooms/Room3.tres" type="PropData" id=4] [ext_resource path="res://test_rooms/Room5.tres" type="PropData" id=5] [ext_resource path="res://test_rooms/Room4.tres" type="PropData" id=6] [node name="Dungtest" type="Spatial"] +[node name="DirectionalLight" type="DirectionalLight" parent="."] +transform = Transform( 1, 0, 0, 0, 0.618285, 0.785954, 0, -0.785954, 0.618285, 0, 7.04604, 18.7882 ) + +[node name="Camera" type="Camera" parent="."] +transform = Transform( 1, 0, 0, 0, 0.937221, 0.348736, 0, -0.348736, 0.937221, 0, 3.89185, 8.51114 ) +current = true + [node name="Dungeon" type="Spatial" parent="."] script = ExtResource( 1 ) start_room = ExtResource( 2 ) -rooms = [ ExtResource( 2 ), ExtResource( 3 ), ExtResource( 4 ), ExtResource( 6 ), ExtResource( 5 ) ] +rooms = [ ExtResource( 4 ), ExtResource( 6 ), ExtResource( 5 ) ]