Proper door layout; started multiple floors

This commit is contained in:
Segey Lapin
2020-04-20 01:31:57 +03:00
parent 585a9bdae1
commit 72452dcb4c

View File

@@ -11,6 +11,26 @@ var door = preload("res://scenes/maps/door.tscn")
var entry = preload("res://scenes/maps/door-outside.tscn")
var fl = preload("res://scenes/maps/floor.escn")
# Called when the node enters the scene tree for the first time.
var rnd: RandomNumberGenerator
var contour = [
Vector2(-20, -20), Vector2(-8, -20), Vector2(-8, -8), Vector2(-6, -8), Vector2(-6, -20),
Vector2(20, -20), Vector2(20, -8), Vector2(8, -8), Vector2(8, -6), Vector2(20, -6),
Vector2(20, 20), Vector2(8, 20), Vector2(8, 8), Vector2(6, 8), Vector2(6, 20),
Vector2(-20, 20), Vector2(-20, 8), Vector2(-8, 8), Vector2(-8, 6), Vector2(-20, 6), Vector2(-25, 2),
]
var spaces = [
"entry",
"window",
"corridoor"
]
#var adj = {
# "entry": ["hall"],
# "hall": ["hall1", "kitchen", "toilet1", "bathroom1", "hall2"],
#}
class Floor extends Reference:
const FLAG_WALL_LEFT = (1 << 0)
const FLAG_WALL_UP = (1 << 1)
const FLAG_WALL_RIGHT = (1 << 2)
@@ -36,15 +56,6 @@ const FLAG_LEFT_MASK = (FLAG_WALL_LEFT | FLAG_ENTRY_LEFT | FLAG_WINDOW_LEFT | FL
const FLAG_UP_MASK = (FLAG_WALL_UP | FLAG_ENTRY_UP | FLAG_WINDOW_UP | FLAG_DOOR_UP)
const FLAG_RIGHT_MASK = (FLAG_WALL_RIGHT | FLAG_ENTRY_RIGHT | FLAG_WINDOW_RIGHT | FLAG_DOOR_RIGHT)
const FLAG_DOWN_MASK = (FLAG_WALL_DOWN | FLAG_ENTRY_DOWN | FLAG_WINDOW_DOWN | FLAG_DOOR_DOWN)
# Called when the node enters the scene tree for the first time.
var rnd: RandomNumberGenerator
var contour = [
Vector2(-20, -20), Vector2(-8, -20), Vector2(-8, -8), Vector2(-6, -8), Vector2(-6, -20),
Vector2(20, -20), Vector2(20, -8), Vector2(8, -8), Vector2(8, -6), Vector2(20, -6),
Vector2(20, 20), Vector2(8, 20), Vector2(8, 8), Vector2(6, 8), Vector2(6, 20),
Vector2(-20, 20), Vector2(-20, 8), Vector2(-8, 8), Vector2(-8, 6), Vector2(-20, 6), Vector2(-25, 2),
]
var wall_length = 2.0
var grid_areas = []
var grid_walls = []
@@ -53,26 +64,12 @@ var grid_size = 2.0
var size_x:int = 0
var size_y:int = 0
var windows = []
var enterance
var spaces = [
"entry",
"window",
"corridoor"
]
var walls_tiles = []
#var adj = {
# "entry": ["hall"],
# "hall": ["hall1", "kitchen", "toilet1", "bathroom1", "hall2"],
#}
func init_grid():
$debug.begin(Mesh.PRIMITIVE_LINES)
var enterance
func init_grid(contour):
for k in range(contour.size()):
var p1 = contour[k]
var p2 = contour[(k + 1) % contour.size()]
$debug.add_vertex(Vector3(p1.x, 3.0, p1.y))
$debug.add_vertex(Vector3(p2.x, 3.0, p2.y))
$debug.end()
for x in contour:
grid_rect = grid_rect.expand(x)
size_x = grid_rect.size.x / grid_size + 2
@@ -82,12 +79,7 @@ func init_grid():
for t in range(size_x * size_y):
grid_areas[t] = 0
grid_walls[t] = 0
# for e in adj.keys():
# if !e in spaces:
# spaces.push_back(e)
var cur_pos: = Vector2()
func init_walls():
func init_walls(contour):
for y in range(size_y):
for x in range(size_x):
var point_flags = 0
@@ -125,8 +117,11 @@ func init_walls():
else:
grid_areas[y * size_x + x] = 0
grid_walls[y * size_x + x] = point_flags
func grid2pos(x: int, y: int):
var px = float(x) * grid_size + grid_rect.position.x - grid_size
var py = float(y) * grid_size + grid_rect.position.y - grid_size
return Vector2(px, py)
func convert_walls():
$debug.begin(Mesh.PRIMITIVE_LINES)
for y in range(size_y):
for x in range(size_x):
var left = false
@@ -141,14 +136,6 @@ func convert_walls():
var p1 = Vector2(px + grid_size, py)
var p2 = Vector2(px + grid_size, py + grid_size)
var p3 = Vector2(px, py + grid_size)
$debug.add_vertex(Vector3(p0.x, 0.1, p0.y))
$debug.add_vertex(Vector3(p1.x, 0.1, p1.y))
$debug.add_vertex(Vector3(p1.x, 0.1, p1.y))
$debug.add_vertex(Vector3(p2.x, 0.1, p2.y))
$debug.add_vertex(Vector3(p2.x, 0.1, p2.y))
$debug.add_vertex(Vector3(p3.x, 0.1, p3.y))
$debug.add_vertex(Vector3(p3.x, 0.1, p3.y))
$debug.add_vertex(Vector3(p0.x, 0.1, p0.y))
match(point_flags):
0x1ff:
f = true
@@ -259,8 +246,7 @@ func convert_walls():
grid_walls[y * size_x + x] = point_flags
if point_flags & 0xf != 0:
walls_tiles.push_back(y * size_x + x)
$debug.end()
func create_entry_door():
func create_entry_door(rnd):
var tile = walls_tiles[rnd.randi() % walls_tiles.size()]
var point_flags = grid_walls[tile]
var flags = [
@@ -277,7 +263,7 @@ func create_entry_door():
point_flags &= ~f[0]
point_flags |= f[1]
grid_walls[tile] = point_flags
func create_windows(pwindow: float):
func create_windows(rnd, pwindow: float):
for tile in walls_tiles:
var point_flags = grid_walls[tile]
var flags = [
@@ -302,7 +288,6 @@ func tile_distance(tile1: int, tile2: int):
var cur_y = int(tile2 / size_x)
var dst = Vector2(cur_x - last_x, cur_y - last_y).length()
return int(dst)
func create_areas(min_d: int = 4):
var created_roots = []
for t in range(grid_walls.size()):
@@ -450,7 +435,6 @@ func build_area_adj():
add_adj(adj, code, code_down, tile, tile + size_x, FLAG_DOOR_DOWN)
assert(!adj.empty())
return adj
func build_area_walls():
for tile in range(grid_areas.size()):
var code = grid_areas[tile]
@@ -493,9 +477,72 @@ func build_area_walls():
# if old_point_flags != point_flags:
# print("point flags %04x" % (old_point_flags), " after %04x" % (point_flags))
grid_walls[tile] = point_flags
func build_doors():
func make_door_graph():
var adj = build_area_adj()
print("adj: ", adj)
var unreached = []
var reached = []
var pairs = {}
var spanning_tree = {}
for k in adj.keys():
for l in adj[k].keys():
if pairs.has(k):
if !l in pairs[k]:
pairs[k].push_back(l)
else:
pairs[k] = [l]
if !k in unreached:
unreached.push_back(k)
if !l in unreached:
unreached.push_back(l)
var vstart = enterance
reached.push_back(vstart)
unreached.erase(vstart)
while unreached.size() > 0:
var record = 100000
var rindex = -1
var uindex = -1
for ri in range(reached.size()):
for ui in range(unreached.size()):
var rval = reached[ri]
var dist = 1 if unreached[ui] in pairs[rval] else 10000
if dist < record:
record = dist
rindex = ri
uindex = ui
if uindex >= 0:
var rvalue = reached[rindex]
var uvalue = unreached[uindex]
if spanning_tree.has(rvalue):
if !uvalue in spanning_tree[rvalue]:
spanning_tree[rvalue].push_back(uvalue)
else:
spanning_tree[rvalue] = [uvalue]
reached.push_back(unreached[uindex])
unreached.remove(uindex)
else:
assert(false)
pairs = {}
for k in spanning_tree.keys():
for l in spanning_tree[k]:
if pairs.has(k):
pairs[k].push_back(l)
else:
pairs[k] = [l]
if pairs.has(l):
pairs[l].push_back(k)
else:
pairs[l] = [k]
var new_adj = {}
for k in adj.keys():
for l in adj[k].keys():
if pairs.has(k) && l in pairs[k]:
if !new_adj.has(k):
new_adj[k] = {}
new_adj[k][l] = adj[k][l]
print("new adj: ", new_adj)
return new_adj
func build_doors():
var adj = make_door_graph()
var queue = [enterance]
var seen = []
while queue.size() > 0:
@@ -522,15 +569,15 @@ func build_doors():
if !e in seen:
queue.push_back(e)
func instance_wall(what, p0, p1):
func instance_wall(base: Spatial, what, p0, p1):
var obj = what.instance()
add_child(obj)
base.add_child(obj)
var v = p1 - p0
var xform = Transform().rotated(Vector3(0, 1, 0), -v.angle())
var p = p0 + v * 0.5
xform.origin = Vector3(p.x, 0, p.y)
obj.transform = xform
func display_walls():
func display_walls(base: Spatial, objdata: Dictionary):
for y in range(size_y):
for x in range(size_x):
var point_flags = grid_walls[y * size_x + x]
@@ -542,63 +589,102 @@ func display_walls():
var p3 = Vector2(px, py + grid_size)
var obje
var objects = {
FLAG_WALL_MASK: wall,
FLAG_ENTRY_MASK: entry,
FLAG_WINDOW_MASK: window,
FLAG_DOOR_MASK: door
FLAG_WALL_MASK: objdata.wall,
FLAG_ENTRY_MASK: objdata.entry,
FLAG_WINDOW_MASK: objdata.window,
FLAG_DOOR_MASK: objdata.door
}
for k in objects.keys():
if point_flags & k != 0:
obje = objects[k]
if point_flags & (k & FLAG_LEFT_MASK) != 0:
instance_wall(obje, p3, p0)
instance_wall(base, obje, p3, p0)
if point_flags & (k & FLAG_UP_MASK) != 0:
instance_wall(obje, p0, p1)
instance_wall(base, obje, p0, p1)
if point_flags & (k & FLAG_RIGHT_MASK) != 0:
instance_wall(obje, p1, p2)
instance_wall(base, obje, p1, p2)
if point_flags & (k & FLAG_DOWN_MASK) != 0:
instance_wall(obje, p2, p3)
instance_wall(base, obje, p2, p3)
if point_flags & FLAG_FLOOR != 0:
var fd = fl.instance()
add_child(fd)
var fd = objdata.floor.instance()
base.add_child(fd)
var xform = Transform()
var p = p0
xform.origin = Vector3(p.x, 0, p.y)
fd.transform = xform
func debug_contour():
$debug.begin(Mesh.PRIMITIVE_LINES)
for k in range(contour.size()):
var p1 = contour[k]
var p2 = contour[(k + 1) % contour.size()]
$debug.add_vertex(Vector3(p1.x, 3.0, p1.y))
$debug.add_vertex(Vector3(p2.x, 3.0, p2.y))
$debug.end()
#onready var building_floor = Floor.new()
var cur_pos: = Vector2()
func debug_walls(fl):
$debug.begin(Mesh.PRIMITIVE_LINES)
for y in range(fl.size_y):
for x in range(fl.size_x):
var gpos = fl.grid2pos(x, y)
var px = gpos.x
var py = gpos.y
var p0 = Vector2(px, py)
var p1 = Vector2(px + fl.grid_size, py)
var p2 = Vector2(px + fl.grid_size, py + fl.grid_size)
var p3 = Vector2(px, py + fl.grid_size)
$debug.add_vertex(Vector3(p0.x, 0.1, p0.y))
$debug.add_vertex(Vector3(p1.x, 0.1, p1.y))
$debug.add_vertex(Vector3(p1.x, 0.1, p1.y))
$debug.add_vertex(Vector3(p2.x, 0.1, p2.y))
$debug.add_vertex(Vector3(p2.x, 0.1, p2.y))
$debug.add_vertex(Vector3(p3.x, 0.1, p3.y))
$debug.add_vertex(Vector3(p3.x, 0.1, p3.y))
$debug.add_vertex(Vector3(p0.x, 0.1, p0.y))
$debug.end()
func _ready():
rnd = RandomNumberGenerator.new()
rnd.seed = OS.get_unix_time()
var state = 0
var objd = {
"wall": wall,
"window": window,
"door": door,
"floor": fl,
"entry": entry
}
var floors = []
var nfloors = 3
var floor_bases = []
func _process(delta):
match(state):
0:
init_grid()
init_walls()
convert_walls()
create_entry_door()
create_windows(0.6)
create_areas(4)
for k in range(nfloors):
floors.push_back(Floor.new())
var b = Spatial.new()
add_child(b)
b.translation.y = 3.0 * float(k)
floor_bases.push_back(b)
floors[0].init_grid(contour)
floors[0].init_walls(contour)
floors[0].convert_walls()
floors[0].create_entry_door(rnd)
floors[0].create_windows(rnd, 0.6)
floors[0].create_areas(4)
state = 1
1:
var b1 = grow_areas_left()
var b2 = grow_areas_up()
var b3 = grow_areas_right()
var b4 = grow_areas_down()
var b1 = floors[0].grow_areas_left()
var b2 = floors[0].grow_areas_up()
var b3 = floors[0].grow_areas_right()
var b4 = floors[0].grow_areas_down()
if !b1 && !b2 && !b3 && !b4:
state = 2
2:
build_doors()
build_area_walls()
display_walls()
# place_flats()
# grow_flats()
# draw_grid()
# draw_walls()
# print(grid)
# for k in range(150):
# build_corridor()
floors[0].build_doors()
floors[0].build_area_walls()
floors[0].display_walls(floor_bases[0], objd)
state = 3