diff --git a/content/zones/tavern.toml b/content/zones/tavern.toml index e0d34e9..22b7f9d 100644 --- a/content/zones/tavern.toml +++ b/content/zones/tavern.toml @@ -3,6 +3,8 @@ description = "a cozy tavern with a crackling fireplace" width = 8 height = 6 toroidal = false +spawn_x = 1 +spawn_y = 1 [terrain] # rows as strings, one per line diff --git a/src/mudlib/zone.py b/src/mudlib/zone.py index 0b49bd8..3bc875f 100644 --- a/src/mudlib/zone.py +++ b/src/mudlib/zone.py @@ -21,6 +21,8 @@ class Zone(Object): toroidal: bool = True terrain: list[list[str]] = field(default_factory=list) impassable: set[str] = field(default_factory=lambda: {"^", "~"}) + spawn_x: int = 0 + spawn_y: int = 0 def can_accept(self, obj: Object) -> bool: """Zones accept everything.""" diff --git a/src/mudlib/zones.py b/src/mudlib/zones.py index 13488de..de417b7 100644 --- a/src/mudlib/zones.py +++ b/src/mudlib/zones.py @@ -53,6 +53,8 @@ def load_zone(path: Path) -> Zone: width = data["width"] height = data["height"] toroidal = data.get("toroidal", True) + spawn_x = data.get("spawn_x", 0) + spawn_y = data.get("spawn_y", 0) # Parse terrain rows into 2D list terrain_rows = data.get("terrain", {}).get("rows", []) @@ -71,6 +73,8 @@ def load_zone(path: Path) -> Zone: toroidal=toroidal, terrain=terrain, impassable=impassable, + spawn_x=spawn_x, + spawn_y=spawn_y, ) return zone diff --git a/tests/test_zone.py b/tests/test_zone.py index e3413d1..9c902e2 100644 --- a/tests/test_zone.py +++ b/tests/test_zone.py @@ -32,6 +32,20 @@ def test_zone_default_impassable(): assert "~" in zone.impassable +def test_zone_default_spawn_point(): + """Zone has spawn_x=0, spawn_y=0 by default.""" + zone = Zone(name="test") + assert zone.spawn_x == 0 + assert zone.spawn_y == 0 + + +def test_zone_custom_spawn_point(): + """Zone can be created with custom spawn point.""" + zone = Zone(name="test", spawn_x=3, spawn_y=4) + assert zone.spawn_x == 3 + assert zone.spawn_y == 4 + + # --- can_accept --- diff --git a/tests/test_zone_loading.py b/tests/test_zone_loading.py index 9a58698..f031a22 100644 --- a/tests/test_zone_loading.py +++ b/tests/test_zone_loading.py @@ -134,6 +134,8 @@ def test_load_tavern_zone(): assert zone.width == 8 assert zone.height == 6 assert zone.toroidal is False + assert zone.spawn_x == 1 + assert zone.spawn_y == 1 assert len(zone.terrain) == 6 assert zone.terrain[0] == ["#", "#", "#", "#", "#", "#", "#", "#"] assert zone.terrain[5] == ["#", "#", "#", "#", ".", "#", "#", "#"] @@ -144,3 +146,68 @@ def test_load_tavern_zone(): # Check that walls are impassable assert not zone.is_passable(0, 0) assert not zone.is_passable(7, 0) + + +def test_load_zone_with_spawn_point(): + """Load a zone with spawn_x and spawn_y defined.""" + with tempfile.NamedTemporaryFile(mode="w", suffix=".toml", delete=False) as f: + f.write(""" +name = "spawn_zone" +description = "a zone with spawn point" +width = 10 +height = 10 +spawn_x = 5 +spawn_y = 7 + +[terrain] +rows = [ + "..........", + "..........", + "..........", + "..........", + "..........", + "..........", + "..........", + "..........", + "..........", + "..........", +] +""") + temp_path = pathlib.Path(f.name) + + try: + zone = load_zone(temp_path) + + assert zone.spawn_x == 5 + assert zone.spawn_y == 7 + finally: + temp_path.unlink() + + +def test_load_zone_default_spawn_point(): + """Load a zone without spawn point defined defaults to (0, 0).""" + with tempfile.NamedTemporaryFile(mode="w", suffix=".toml", delete=False) as f: + f.write(""" +name = "default_spawn" +description = "a zone without spawn point" +width = 5 +height = 5 + +[terrain] +rows = [ + ".....", + ".....", + ".....", + ".....", + ".....", +] +""") + temp_path = pathlib.Path(f.name) + + try: + zone = load_zone(temp_path) + + assert zone.spawn_x == 0 + assert zone.spawn_y == 0 + finally: + temp_path.unlink()