Building generation complete, city goes next

This commit is contained in:
Segey Lapin
2020-04-20 23:11:34 +03:00
parent 72452dcb4c
commit 9d6f2fc79b
4 changed files with 1531 additions and 22 deletions

View File

@@ -10,15 +10,14 @@ var window = preload("res://scenes/maps/window.tscn")
var door = preload("res://scenes/maps/door.tscn") var door = preload("res://scenes/maps/door.tscn")
var entry = preload("res://scenes/maps/door-outside.tscn") var entry = preload("res://scenes/maps/door-outside.tscn")
var fl = preload("res://scenes/maps/floor.escn") var fl = preload("res://scenes/maps/floor.escn")
var stairs = preload("res://scenes/maps/stairs-small.escn")
# Called when the node enters the scene tree for the first time. # Called when the node enters the scene tree for the first time.
var rnd: RandomNumberGenerator var rnd: RandomNumberGenerator
var contour = [ var contour = [
Vector2(-20, -20), Vector2(-8, -20), Vector2(-8, -8), Vector2(-6, -8), Vector2(-6, -20), Vector2(-10, -10), Vector2(10, -10),
Vector2(20, -20), Vector2(20, -8), Vector2(8, -8), Vector2(8, -6), Vector2(20, -6), Vector2(10, 10), Vector2(-10, 10)
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 = [ var spaces = [
@@ -48,6 +47,7 @@ class Floor extends Reference:
const FLAG_DOOR_UP = (1 << 14) const FLAG_DOOR_UP = (1 << 14)
const FLAG_DOOR_RIGHT = (1 << 15) const FLAG_DOOR_RIGHT = (1 << 15)
const FLAG_DOOR_DOWN = (1 << 16) const FLAG_DOOR_DOWN = (1 << 16)
const FLAG_STAIRS = (1 << 17)
const FLAG_WALL_MASK = (FLAG_WALL_LEFT | FLAG_WALL_UP | FLAG_WALL_RIGHT | FLAG_WALL_DOWN) const FLAG_WALL_MASK = (FLAG_WALL_LEFT | FLAG_WALL_UP | FLAG_WALL_RIGHT | FLAG_WALL_DOWN)
const FLAG_ENTRY_MASK = (FLAG_ENTRY_LEFT | FLAG_ENTRY_UP | FLAG_ENTRY_RIGHT | FLAG_ENTRY_DOWN) const FLAG_ENTRY_MASK = (FLAG_ENTRY_LEFT | FLAG_ENTRY_UP | FLAG_ENTRY_RIGHT | FLAG_ENTRY_DOWN)
const FLAG_WINDOW_MASK = (FLAG_WINDOW_LEFT | FLAG_WINDOW_UP | FLAG_WINDOW_RIGHT | FLAG_WINDOW_DOWN) const FLAG_WINDOW_MASK = (FLAG_WINDOW_LEFT | FLAG_WINDOW_UP | FLAG_WINDOW_RIGHT | FLAG_WINDOW_DOWN)
@@ -66,6 +66,29 @@ class Floor extends Reference:
var windows = [] var windows = []
var walls_tiles = [] var walls_tiles = []
var enterance var enterance
var enterance_tile = -1
var stairs_pos: Vector2
var stairs_tile: int
const big_stairs_w = 10
const big_stairs_h = 8
const small_stairs_w = 4
const small_stairs_h = 4
func copy():
var ret = Floor.new()
ret.wall_length = wall_length
ret.grid_areas = grid_areas.duplicate()
ret.grid_walls = grid_walls.duplicate()
ret.grid_rect = grid_rect
ret.grid_size = grid_size
ret.size_x = size_x
ret.size_y = size_y
ret.windows = windows.duplicate()
ret.walls_tiles = walls_tiles.duplicate()
ret.enterance = enterance
ret.enterance_tile = enterance_tile
ret.stairs_pos = stairs_pos
ret.stairs_tile = stairs_tile
return ret
func init_grid(contour): func init_grid(contour):
for k in range(contour.size()): for k in range(contour.size()):
var p1 = contour[k] var p1 = contour[k]
@@ -250,10 +273,10 @@ class Floor extends Reference:
var tile = walls_tiles[rnd.randi() % walls_tiles.size()] var tile = walls_tiles[rnd.randi() % walls_tiles.size()]
var point_flags = grid_walls[tile] var point_flags = grid_walls[tile]
var flags = [ var flags = [
[1, 32], [FLAG_WALL_LEFT, FLAG_ENTRY_LEFT],
[2, 64], [FLAG_WALL_UP, FLAG_ENTRY_UP],
[4, 128], [FLAG_WALL_RIGHT, FLAG_ENTRY_RIGHT],
[8, 256] [FLAG_WALL_DOWN, FLAG_ENTRY_DOWN]
] ]
var rflags = [] var rflags = []
for p in flags: for p in flags:
@@ -263,6 +286,74 @@ class Floor extends Reference:
point_flags &= ~f[0] point_flags &= ~f[0]
point_flags |= f[1] point_flags |= f[1]
grid_walls[tile] = point_flags grid_walls[tile] = point_flags
enterance_tile = tile
func allocate_stairs(area_code: int):
var stairs_w = small_stairs_w
var stairs_h = small_stairs_h
var stairs_grid_w = int((stairs_w + grid_size * 0.5) / grid_size)
var stairs_grid_h = int((stairs_h + grid_size * 0.5) / grid_size)
print("size_x ", size_x)
print("size_y ", size_y)
print("stairs grid size: ", stairs_grid_w, " ", stairs_grid_h)
var candidates = []
var candidates_tile = []
for i in range(size_y - stairs_grid_h):
for j in range(size_x - stairs_grid_w):
var ok = true
for ii in range(stairs_grid_h):
for jj in range(stairs_grid_w):
if grid_walls[(i + ii) * size_x + j + jj] != FLAG_FLOOR:
ok = false
break
if grid_areas[(i + ii) * size_x + j + jj] != 0:
ok = false
break
if ok:
candidates_tile.push_back(i * size_x + j)
var pos = grid2pos(j, i) + Vector2(stairs_w, stairs_h) * 0.5
print("stairs tile: ", i * size_x +j, " pos: ", pos)
candidates.push_back(pos)
assert(candidates_tile.size() > 0)
var pos = 0
for xpos in range(1, candidates_tile.size(), 1):
if abs(enterance_tile - candidates_tile[xpos]) < abs(enterance_tile - candidates_tile[pos]):
pos = xpos
stairs_tile = candidates_tile[pos]
stairs_pos = candidates[pos]
print("result: tile: ", stairs_tile, " pos: ", stairs_pos)
for i in range(stairs_grid_h):
for j in range(stairs_grid_w):
grid_areas[stairs_tile + i * size_x + j] = area_code
grid_walls[stairs_tile + i * size_x + j] |= FLAG_STAIRS
func remove_stairs_floor():
var stairs_w = small_stairs_w
var stairs_h = small_stairs_h
var stairs_grid_w = int((stairs_w + grid_size * 0.5) / grid_size)
var stairs_grid_h = int((stairs_h + grid_size * 0.5) / grid_size)
for i in range(stairs_grid_h):
for j in range(stairs_grid_w):
grid_walls[stairs_tile + i * size_x + j] &= ~FLAG_FLOOR
func clear_entry_door():
if enterance_tile < 0:
return
var point_flags = grid_walls[enterance_tile]
var flags = [
[FLAG_ENTRY_LEFT, FLAG_WALL_LEFT, FLAG_WINDOW_LEFT],
[FLAG_ENTRY_UP, FLAG_WALL_UP, FLAG_WINDOW_UP],
[FLAG_ENTRY_RIGHT, FLAG_WALL_RIGHT, FLAG_WINDOW_RIGHT],
[FLAG_ENTRY_DOWN, FLAG_WALL_DOWN, FLAG_WINDOW_DOWN]
]
var rflags = []
for p in flags:
if point_flags & p[0] != 0:
rflags.push_back(p)
for f in rflags:
point_flags &= ~f[0]
point_flags |= f[1]
grid_walls[enterance_tile] = point_flags
enterance_tile = -1
func create_windows(rnd, pwindow: float): func create_windows(rnd, pwindow: float):
for tile in walls_tiles: for tile in walls_tiles:
var point_flags = grid_walls[tile] var point_flags = grid_walls[tile]
@@ -288,19 +379,22 @@ class Floor extends Reference:
var cur_y = int(tile2 / size_x) var cur_y = int(tile2 / size_x)
var dst = Vector2(cur_x - last_x, cur_y - last_y).length() var dst = Vector2(cur_x - last_x, cur_y - last_y).length()
return int(dst) return int(dst)
func create_areas(min_d: int = 4): func init_areas():
var created_roots = []
for t in range(grid_walls.size()): for t in range(grid_walls.size()):
if grid_walls[t] & FLAG_FLOOR: if grid_walls[t] & FLAG_FLOOR:
grid_areas[t] = 0x0 grid_areas[t] = 0x0
else: else:
grid_areas[t] = 0xffff grid_areas[t] = 0xffff
var area_code: int = 1 func create_areas(min_d: int = 4, start_code: int = 1) -> int:
var created_roots = []
var area_code: int = start_code
for t in [FLAG_ENTRY_MASK, FLAG_WINDOW_MASK]: for t in [FLAG_ENTRY_MASK, FLAG_WINDOW_MASK]:
var p = walls_tiles.duplicate() var p = walls_tiles.duplicate()
while p.size() > 0: while p.size() > 0:
var tile = p.pop_front() var tile = p.pop_front()
var point_flags = grid_walls[tile] var point_flags = grid_walls[tile]
if point_flags & FLAG_STAIRS != 0:
continue
if (point_flags & t != 0): if (point_flags & t != 0):
if t == FLAG_ENTRY_MASK: if t == FLAG_ENTRY_MASK:
print("entry") print("entry")
@@ -324,6 +418,7 @@ class Floor extends Reference:
area_code += 1 area_code += 1
created_roots.push_back(tile) created_roots.push_back(tile)
assert(enterance != null) assert(enterance != null)
return area_code
func grow_areas_left(): func grow_areas_left():
var count = 0 var count = 0
for tile in range(grid_areas.size()): for tile in range(grid_areas.size()):
@@ -613,6 +708,14 @@ class Floor extends Reference:
var p = p0 var p = p0
xform.origin = Vector3(p.x, 0, p.y) xform.origin = Vector3(p.x, 0, p.y)
fd.transform = xform fd.transform = xform
assert(stairs_pos != null)
if stairs_pos:
var fd = objdata.stairs.instance()
base.add_child(fd)
var xform = Transform()
var p = stairs_pos
xform.origin = Vector3(p.x, 0, p.y)
fd.transform = xform
func debug_contour(): func debug_contour():
$debug.begin(Mesh.PRIMITIVE_LINES) $debug.begin(Mesh.PRIMITIVE_LINES)
for k in range(contour.size()): for k in range(contour.size()):
@@ -655,11 +758,13 @@ var objd = {
"window": window, "window": window,
"door": door, "door": door,
"floor": fl, "floor": fl,
"entry": entry "entry": entry,
"stairs": stairs
} }
var floors = [] var floors = []
var nfloors = 3 var nfloors = 40
var floor_bases = [] var floor_bases = []
var area_code = 1
func _process(delta): func _process(delta):
match(state): match(state):
0: 0:
@@ -674,17 +779,39 @@ func _process(delta):
floors[0].convert_walls() floors[0].convert_walls()
floors[0].create_entry_door(rnd) floors[0].create_entry_door(rnd)
floors[0].create_windows(rnd, 0.6) floors[0].create_windows(rnd, 0.6)
floors[0].create_areas(4) floors[0].init_areas()
floors[0].allocate_stairs(area_code)
area_code += 1
for k in range(0, nfloors, 1):
if k > 0:
floors[k] = floors[0].copy()
floors[k].clear_entry_door()
area_code = floors[k].create_areas(4, area_code)
state = 1 state = 1
1: 1:
var b1 = floors[0].grow_areas_left() var b1 = false
var b2 = floors[0].grow_areas_up() var b2 = false
var b3 = floors[0].grow_areas_right() var b3 = false
var b4 = floors[0].grow_areas_down() var b4 = false
for k in range(nfloors):
var tb1 = floors[k].grow_areas_left()
if tb1:
b1 = true
var tb2 = floors[k].grow_areas_up()
if tb2:
b2 = true
var tb3 = floors[k].grow_areas_right()
if tb3:
b3 = true
var tb4 = floors[k].grow_areas_down()
if tb4:
b4 = true
if !b1 && !b2 && !b3 && !b4: if !b1 && !b2 && !b3 && !b4:
state = 2 state = 2
2: 2:
floors[0].build_doors() for k in range(nfloors):
floors[0].build_area_walls() floors[k].build_doors()
floors[0].display_walls(floor_bases[0], objd) floors[k].build_area_walls()
floors[k].remove_stairs_floor()
floors[k].display_walls(floor_bases[k], objd)
state = 3 state = 3

View File

@@ -133,7 +133,7 @@ surfaces/0 = {
[node type="Spatial" name="Scene"] [node type="Spatial" name="Scene"]
[node name="floor" type="MeshInstance" parent="."] [node name="floor-col" type="MeshInstance" parent="."]
mesh = SubResource(3) mesh = SubResource(3)
visible = true visible = true

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff