"""Tests for mob home region system.""" import pathlib import tempfile import pytest from mudlib.entity import Mob from mudlib.mobs import MobTemplate, mobs, spawn_mob from mudlib.zone import SpawnRule, Zone from mudlib.zones import load_zone @pytest.fixture(autouse=True) def clear_mobs(): mobs.clear() yield mobs.clear() @pytest.fixture def zone(): terrain = [["." for _ in range(20)] for _ in range(20)] return Zone( name="forest", width=20, height=20, terrain=terrain, toroidal=False, ) @pytest.fixture def template(): return MobTemplate( name="squirrel", description="a bushy-tailed squirrel", pl=10, stamina=20, max_stamina=20, moves=[], ) # --- SpawnRule --- def test_spawn_rule_default_no_home_region(): """SpawnRule has no home_region by default.""" rule = SpawnRule(mob="goblin") assert rule.home_region is None def test_spawn_rule_with_home_region(): """SpawnRule can have a home_region.""" rule = SpawnRule( mob="goblin", home_region={"x": [5, 15], "y": [3, 10]}, ) assert rule.home_region == {"x": [5, 15], "y": [3, 10]} # --- Mob fields --- def test_mob_home_region_defaults(): """Mob has no home region by default.""" mob = Mob(name="rat", x=0, y=0) assert mob.home_x_min is None assert mob.home_x_max is None assert mob.home_y_min is None assert mob.home_y_max is None def test_mob_home_region_set(): """Mob can have home region bounds.""" mob = Mob( name="rat", x=5, y=5, home_x_min=3, home_x_max=10, home_y_min=2, home_y_max=8, ) assert mob.home_x_min == 3 assert mob.home_x_max == 10 assert mob.home_y_min == 2 assert mob.home_y_max == 8 def test_mob_in_home_region(): """Mob at position within home region.""" mob = Mob( name="rat", x=5, y=5, home_x_min=3, home_x_max=10, home_y_min=2, home_y_max=8, ) assert mob.home_x_min is not None assert mob.home_x_max is not None assert mob.home_y_min is not None assert mob.home_y_max is not None assert mob.home_x_min <= mob.x <= mob.home_x_max assert mob.home_y_min <= mob.y <= mob.home_y_max # --- spawn_mob with home region --- def test_spawn_mob_with_home_region(zone, template): """spawn_mob sets home region from SpawnRule.""" rule = SpawnRule( mob="squirrel", home_region={"x": [5, 15], "y": [3, 10]}, ) mob = spawn_mob(template, 10, 7, zone, home_region=rule.home_region) assert mob.home_x_min == 5 assert mob.home_x_max == 15 assert mob.home_y_min == 3 assert mob.home_y_max == 10 def test_spawn_mob_without_home_region(zone, template): """spawn_mob without home_region leaves bounds as None.""" mob = spawn_mob(template, 10, 7, zone) assert mob.home_x_min is None assert mob.home_x_max is None # --- TOML loading --- def test_load_zone_spawn_with_home_region(): """Zone TOML with home_region on spawn rule.""" with tempfile.NamedTemporaryFile(mode="w", suffix=".toml", delete=False) as f: f.write( """ name = "test_zone" width = 20 height = 20 [terrain] rows = [ "....................", "....................", "....................", "....................", "....................", "....................", "....................", "....................", "....................", "....................", "....................", "....................", "....................", "....................", "....................", "....................", "....................", "....................", "....................", "....................", ] [[spawns]] mob = "squirrel" max_count = 2 respawn_seconds = 180 home_region = { x = [5, 15], y = [3, 10] } """ ) temp_path = pathlib.Path(f.name) try: zone = load_zone(temp_path) assert len(zone.spawn_rules) == 1 rule = zone.spawn_rules[0] assert rule.home_region == {"x": [5, 15], "y": [3, 10]} finally: temp_path.unlink() def test_load_zone_spawn_without_home_region(): """Zone TOML without home_region on spawn rule.""" with tempfile.NamedTemporaryFile(mode="w", suffix=".toml", delete=False) as f: f.write( """ name = "test_zone" width = 5 height = 5 [terrain] rows = [ ".....", ".....", ".....", ".....", ".....", ] [[spawns]] mob = "goblin" max_count = 1 """ ) temp_path = pathlib.Path(f.name) try: zone = load_zone(temp_path) assert len(zone.spawn_rules) == 1 rule = zone.spawn_rules[0] assert rule.home_region is None finally: temp_path.unlink()