Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# - none of the decay applied to the room may block off any of its
# interesting features
# TODO it would be nice if i could really write all this without ever
# having to hardcode a specific direction, so the logic could always be
# rotated freely
side = random.choice([Direction.left, Direction.right])
# TODO assert region is big enough
room_size = Size(
random_normal_range(9, int(self.region.width * 0.4)),
random_normal_range(9, int(self.region.height * 0.4)),
)
room_position = self.region.center() - room_size // 2
room_position += Point(
random_normal_int(0, self.region.width * 0.1),
random_normal_int(0, self.region.height * 0.1),
)
room_rect = Rectangle(room_position, room_size)
self.room_region = room_rect
room = Room(room_rect)
cave_area = (
Blob.from_rectangle(self.region)
- Blob.from_rectangle(room_rect)
)
self.cave_region = cave_area
walls = [point for (point, _) in self.region.iter_border()]
floors = []
def iter_points(self):
"""Iterate over all tiles within this rectangle as points."""
for x in range(self.left, self.right + 1):
for y in range(self.top, self.bottom + 1):
yield Point(x, y)
min_y = mid_y - 1
max_y = mid_y + 1
else:
min_y = mid_y - 2
max_y = mid_y + 1
for y in range(min_y, max_y + 1):
self.map_canvas.set_architecture(Point(x, y), KadathGate)
# Beat up the border of the room near the gate
y = random.choice(
tuple(range(room_rect.top, min_y))
+ tuple(range(max_y + 1, room_rect.bottom))
)
for dx in range(-2, 3):
for dy in range(-2, 3):
point = Point(x + dx, y + dy)
# TODO i think what i may want is to have the cave be a
# "Feature", where i can check whether it has already claimed a
# tile, or draw it later, or whatever.
if self.map_canvas._arch_grid[point] is not CaveWall:
distance = abs(dx) + abs(dy)
ruination = random_normal_range(0, 0.2) + distance * 0.2
self.map_canvas.set_architecture(
point, e.Rubble(Breakable(ruination)))
# And apply some light ruination to the inside of the room
border = list(room_rect.iter_border())
# TODO don't do this infinitely; give up after x tries
while True:
point, edge = random.choice(border)
if self.map_canvas._arch_grid[point + edge] is CaveWall:
break
end = y
new_block = False
else:
end = y
else:
if not new_block:
blocks.append((start, end))
new_block = True
if not new_block:
blocks.append((start, end))
for start, end in blocks:
y = random_normal_range(start, end)
span = river_blob.spans[y][0]
local_minima.add(Point(span.start - 1, y))
local_minima.add(Point(span.end + 1, y))
for x in span:
self.map_canvas.set_architecture(Point(x, y), e.Bridge)
# Consider all local minima along the edges, as well.
for x in self.region.range_width():
for y in (self.region.top, self.region.bottom):
point = Point(x, y)
n = noise[point]
if (n < noise.get(Point(x - 1, y), 1) and
n < noise.get(Point(x + 1, y), 1)):
local_minima.add(point)
for y in self.region.range_height():
for x in (self.region.left, self.region.right):
point = Point(x, y)
n = noise[point]
if (n < noise.get(Point(x, y - 1), 1) and
local_minima.add(Point(span.start - 1, y))
local_minima.add(Point(span.end + 1, y))
for x in span:
self.map_canvas.set_architecture(Point(x, y), e.Bridge)
# Consider all local minima along the edges, as well.
for x in self.region.range_width():
for y in (self.region.top, self.region.bottom):
point = Point(x, y)
n = noise[point]
if (n < noise.get(Point(x - 1, y), 1) and
n < noise.get(Point(x + 1, y), 1)):
local_minima.add(point)
for y in self.region.range_height():
for x in (self.region.left, self.region.right):
point = Point(x, y)
n = noise[point]
if (n < noise.get(Point(x, y - 1), 1) and
n < noise.get(Point(x, y + 1), 1)):
local_minima.add(point)
for point in local_minima:
if point not in river_blob:
self.map_canvas.set_architecture(point, e.Dirt)
for blob in (left_bank, right_bank):
paths = self.flood_valleys(blob, local_minima, noise)
for path_point in paths:
self.map_canvas.set_architecture(path_point, e.Dirt)
# Whoops time for another step: generating a surrounding cave wall.
else:
end = y
else:
if not new_block:
blocks.append((start, end))
new_block = True
if not new_block:
blocks.append((start, end))
for start, end in blocks:
y = random_normal_range(start, end)
span = river_blob.spans[y][0]
local_minima.add(Point(span.start - 1, y))
local_minima.add(Point(span.end + 1, y))
for x in span:
self.map_canvas.set_architecture(Point(x, y), e.Bridge)
# Consider all local minima along the edges, as well.
for x in self.region.range_width():
for y in (self.region.top, self.region.bottom):
point = Point(x, y)
n = noise[point]
if (n < noise.get(Point(x - 1, y), 1) and
n < noise.get(Point(x + 1, y), 1)):
local_minima.add(point)
for y in self.region.range_height():
for x in (self.region.left, self.region.right):
point = Point(x, y)
n = noise[point]
if (n < noise.get(Point(x, y - 1), 1) and
n < noise.get(Point(x, y + 1), 1)):
local_minima.add(point)
def iter_border(self):
for x in range(self.left + 1, self.right):
yield Point(x, self.top), Direction.up
yield Point(x, self.bottom), Direction.down
for y in range(self.top + 1, self.bottom):
yield Point(self.left, y), Direction.left
yield Point(self.right, y), Direction.right
yield Point(self.left, self.top), Direction.up_left
yield Point(self.right, self.top), Direction.up_right
yield Point(self.left, self.bottom), Direction.down_left
yield Point(self.right, self.bottom), Direction.down_right
def iter_border(self):
for x in range(self.left + 1, self.right):
yield Point(x, self.top), Direction.up
yield Point(x, self.bottom), Direction.down
for y in range(self.top + 1, self.bottom):
yield Point(self.left, y), Direction.left
yield Point(self.right, y), Direction.right
yield Point(self.left, self.top), Direction.up_left
yield Point(self.right, self.top), Direction.up_right
yield Point(self.left, self.bottom), Direction.down_left
yield Point(self.right, self.bottom), Direction.down_right
self.map_canvas.set_architecture(Point(x, y), e.Bridge)
# Consider all local minima along the edges, as well.
for x in self.region.range_width():
for y in (self.region.top, self.region.bottom):
point = Point(x, y)
n = noise[point]
if (n < noise.get(Point(x - 1, y), 1) and
n < noise.get(Point(x + 1, y), 1)):
local_minima.add(point)
for y in self.region.range_height():
for x in (self.region.left, self.region.right):
point = Point(x, y)
n = noise[point]
if (n < noise.get(Point(x, y - 1), 1) and
n < noise.get(Point(x, y + 1), 1)):
local_minima.add(point)
for point in local_minima:
if point not in river_blob:
self.map_canvas.set_architecture(point, e.Dirt)
for blob in (left_bank, right_bank):
paths = self.flood_valleys(blob, local_minima, noise)
for path_point in paths:
self.map_canvas.set_architecture(path_point, e.Dirt)
# Whoops time for another step: generating a surrounding cave wall.
for edge in Direction.orthogonal:
width = self.region.edge_length(edge)
wall_noise = discrete_perlin_noise_factory(width, resolution=6)