Merge branch 'doors' into 'map_generation'

Doors

See merge request ynerant/squirrel-battle!75
This commit is contained in:
ynerant 2021-01-10 23:54:13 +01:00
commit b72e41d14d
9 changed files with 65 additions and 39 deletions

View File

@ -2,17 +2,17 @@
####### #############
#.H...# #...........#
#.....# #####...........#
#.....# #............H..#
#.....# #...&........H..#
#.##### #.###...........#
#.# #.# #...........#
#.# #.# #############
#.# #.#
#.#### #.#
#....# #.#
####.###################.#
####&###################&#
#.....................# #################
#.....................# #...............#
#.....................#######...............#
#...........................................#
#.....................&.....&...............#
#.....................#######...............#
####################### #################

View File

@ -82,6 +82,7 @@ TexturePack.ASCII_PACK = TexturePack(
BOW=')',
CHEST='',
CHESTPLATE='(',
DOOR='&',
EAGLE='µ',
EMPTY=' ',
EXPLOSION='%',
@ -124,6 +125,8 @@ TexturePack.SQUIRREL_PACK = TexturePack(
BOW='🏹',
CHEST='🧰',
CHESTPLATE='🦺',
DOOR=('🚪', curses.COLOR_WHITE, (1000, 1000, 1000),
curses.COLOR_WHITE, (1000, 1000, 1000)),
EAGLE='🦅',
EMPTY=' ',
EXPLOSION='💥',

View File

@ -6,7 +6,7 @@ from random import randint
from typing import Dict, Optional, Tuple
from .items import Item
from ..interfaces import FightingEntity, InventoryHolder
from ..interfaces import FightingEntity, InventoryHolder, Tile
from ..translations import gettext as _
@ -152,6 +152,12 @@ class Player(InventoryHolder, FightingEntity):
return True
elif entity.is_item():
entity.hold(self)
tile = self.map.tiles[y][x]
if tile == Tile.DOOR and move_if_possible:
# Open door
self.map.tiles[y][x] = Tile.FLOOR
self.map.compute_visibility(y, x, self.vision)
return super().check_move(y, x, move_if_possible)
return super().check_move(y, x, move_if_possible)
def save_state(self) -> dict:

View File

@ -199,7 +199,9 @@ class Game:
self.map_index = 0
return
while self.map_index >= len(self.maps):
self.maps.append(broguelike.Generator().run())
m = broguelike.Generator().run()
m.logs = self.logs
self.maps.append(m)
new_map = self.map
new_map.floor = self.map_index
old_map.remove_entity(self.player)
@ -417,6 +419,7 @@ class Game:
self.maps = [Map().load_state(map_dict) for map_dict in d["maps"]]
for i, m in enumerate(self.maps):
m.floor = i
m.logs = self.logs
except KeyError as error:
self.message = _("Some keys are missing in your save file.\n"
"Your save seems to be corrupt. It got deleted.")\

View File

@ -390,6 +390,7 @@ class Tile(Enum):
WALL = auto()
FLOOR = auto()
LADDER = auto()
DOOR = auto()
@staticmethod
def from_ascii_char(ch: str) -> "Tile":
@ -430,7 +431,7 @@ class Tile(Enum):
"""
Is this Tile a wall?
"""
return self == Tile.WALL
return self == Tile.WALL or self == Tile.DOOR
def is_ladder(self) -> bool:
"""

View File

@ -26,9 +26,11 @@ DEFAULT_PARAMS = {
"spawn_per_region": [1, 2],
}
def dist(level, y1, x1, y2, x2):
def dist(level: List[List[Tile]], y1: int, x1: int, y2: int, x2: int) -> int:
"""
Compute the minimum walking distance between points (y1, x1) and (y2, x2) on a Tile grid
Compute the minimum walking distance between points (y1, x1) and (y2, x2)
on a Tile grid
"""
# simple breadth first search
copy = [[t for t in row] for row in level]
@ -97,8 +99,7 @@ class Generator:
making (door_y, door_x) in the room correspond with (y, x) in the level
"""
rh, rw = len(room), len(room[0])
# maybe place Tile.DOOR here instead ?
level[y][x] = Tile.FLOOR
level[y][x] = Tile.DOOR
for ry in range(rh):
for rx in range(rw):
if room[ry][rx] == Tile.FLOOR:
@ -248,8 +249,8 @@ class Generator:
if room[y][x] == Tile.EMPTY and \
Generator.build_door(room, y, x, dy, dx, length):
break
else:
return None, None
else: # pragma: no cover
return None, None, None, None
return y + length * dy, x + length * dx, dy, dx
@ -324,8 +325,8 @@ class Generator:
top left corner of the room on the level, then log them as a
spawnable region
"""
if self.queued_area != None:
translated_area = [[y+ry, x+rx] for ry, rx in self.queued_area]
if self.queued_area is not None:
translated_area = [[y + ry, x + rx] for ry, rx in self.queued_area]
self.spawn_areas.append(translated_area)
self.queued_area = None
@ -334,11 +335,6 @@ class Generator:
Populate every spawnable area with some randomly chosen, randomly
placed entity
"""
if self.queued_area is not None:
translated_area = [[y + ry, x + rx] for ry, rx in self.queued_area]
self.spawn_areas.append(translated_area)
self.queued_area = None
min_c, max_c = self.params["spawn_per_region"]
for region in self.spawn_areas:
entity_count = randint(min_c, max_c)

View File

@ -134,13 +134,13 @@ class TestEntities(unittest.TestCase):
self.map.remove_entity(entity2)
# Test following the player and finding the player as target
self.player.move(5, 5)
fam.move(4, 5)
self.player.move(6, 5)
fam.move(5, 5)
fam.target = None
self.player.move_down()
self.map.tick(self.player)
self.assertTrue(fam.target == self.player)
self.assertEqual(fam.y, 5)
self.assertEqual(fam.y, 6)
self.assertEqual(fam.x, 5)
# Test random move

View File

@ -728,6 +728,7 @@ class TestGame(unittest.TestCase):
self.game.player.inventory.clear()
ring = RingCritical()
ring.hold(self.game.player)
self.game.display_actions(DisplayActions.REFRESH)
old_critical = self.game.player.critical
self.game.handle_key_pressed(KeyValues.EQUIP)
self.assertEqual(self.game.player.critical,
@ -951,3 +952,18 @@ class TestGame(unittest.TestCase):
# Exit the menu
self.game.handle_key_pressed(KeyValues.SPACE)
self.assertEqual(self.game.state, GameMode.PLAY)
def test_doors(self) -> None:
"""
Check that the user can open doors.
"""
self.game.state = GameMode.PLAY
self.game.player.move(9, 8)
self.assertEqual(self.game.map.tiles[10][8], Tile.DOOR)
# Open door
self.game.handle_key_pressed(KeyValues.DOWN)
self.assertEqual(self.game.map.tiles[10][8], Tile.FLOOR)
self.assertEqual(self.game.player.y, 10)
self.assertEqual(self.game.player.x, 8)
self.game.display_actions(DisplayActions.REFRESH)

View File

@ -26,16 +26,17 @@ class TestBroguelike(unittest.TestCase):
def is_connex(self, grid: List[List[Tile]]) -> bool:
h, w = len(grid), len(grid[0])
y, x = randint(0, h - 1), randint(0, w - 1)
while not (grid[y][x].can_walk()):
y, x = -1, -1
while not grid[y][x].can_walk():
y, x = randint(0, h - 1), randint(0, w - 1)
queue = Map.neighbourhood(grid, y, x)
while queue:
y, x = queue.pop()
if grid[y][x].can_walk():
if grid[y][x].can_walk() or grid[y][x] == Tile.DOOR:
grid[y][x] = Tile.WALL
queue += Map.neighbourhood(grid, y, x)
return not any([t.can_walk() for row in grid for t in row])
return not any([t.can_walk() or t == Tile.DOOR
for row in grid for t in row])
def test_build_doors(self) -> None:
m = self.stom(". .\n. .\n. .\n")