from pathlib import Path import pytest from engine.character import Character from engine.defs import DefRegistry from engine.entity import EntityPosition from engine.item import ItemInstance from engine.map import Map from engine.tile import Tile, TileLayerInstance from engine.world import World from resources.logic.companion import open_companion_inventory DEFS_DIR = Path(__file__).resolve().parent.parent / "resources" / "defs" @pytest.fixture() def registry(): return DefRegistry.load(DEFS_DIR) def make_world(registry): field = Map("field", 10, 10, 1) for x in range(10): for y in range(10): field.set_tile(x, y, 0, Tile(flooring=TileLayerInstance("grass"))) world = World(registry=registry) world.add_map(field) return world def spawn_companion(registry, entity_def_id, position) -> Character: entity_def = registry.get_entity_def(entity_def_id) dog = Character( name=entity_def.name, def_id=entity_def.id, position=position, species_id=entity_def.species_id, gender="male", default_body_parts=registry.new_default_body_parts(entity_def.species_id), default_clothing=registry.new_default_clothing(entity_def.id), ) return dog def test_companion_dog_entity_wears_harness_and_saddlebag(registry): dog = spawn_companion(registry, "companion_dog", EntityPosition("field", 5, 5, 0)) assert dog.get_clothing("torso").item_def_id == "dog_harness" assert dog.get_clothing("back").item_def_id == "dog_saddlebag" def test_open_companion_inventory_returns_the_saddlebag(registry): world = make_world(registry) player = Character(species_id="human", default_body_parts=registry.new_default_body_parts("human"), position=EntityPosition("field", 5, 5, 0)) dog = spawn_companion(registry, "companion_dog", EntityPosition("field", 6, 5, 0)) world.add_entity(player) world.add_entity(dog) inventory = open_companion_inventory(player, world, registry, (1, 0, 0), "back") assert inventory is not None assert (inventory.width, inventory.height) == (3, 3) def test_items_placed_in_the_opened_inventory_persist_on_the_dog(registry): world = make_world(registry) player = Character(species_id="human", default_body_parts=registry.new_default_body_parts("human"), position=EntityPosition("field", 5, 5, 0)) dog = spawn_companion(registry, "companion_dog", EntityPosition("field", 6, 5, 0)) world.add_entity(player) world.add_entity(dog) inventory = open_companion_inventory(player, world, registry, (1, 0, 0), "back") inventory.place(ItemInstance("rope-1", "sandwich"), registry.get_item_def("sandwich"), 0, 0) # re-fetching via the dog's own gear (not the helper) sees the same items - same object assert dog.get_equipped_inventory("back", registry) is inventory assert {p.item.item_id for p in dog.get_equipped_inventory("back", registry).items()} == {"rope-1"} def test_open_companion_inventory_none_when_not_adjacent(registry): world = make_world(registry) player = Character(species_id="human", default_body_parts=registry.new_default_body_parts("human"), position=EntityPosition("field", 5, 5, 0)) dog = spawn_companion(registry, "companion_dog", EntityPosition("field", 8, 8, 0)) # far away world.add_entity(player) world.add_entity(dog) assert open_companion_inventory(player, world, registry, (1, 0, 0), "back") is None def test_open_companion_inventory_none_for_empty_tile(registry): world = make_world(registry) player = Character(species_id="human", default_body_parts=registry.new_default_body_parts("human"), position=EntityPosition("field", 5, 5, 0)) world.add_entity(player) assert open_companion_inventory(player, world, registry, (1, 0, 0), "back") is None def test_open_companion_inventory_none_targeting_self(registry): world = make_world(registry) player = Character(species_id="human", default_body_parts=registry.new_default_body_parts("human"), position=EntityPosition("field", 5, 5, 0)) world.add_entity(player) # aim_direction (0,0,0) means "ahead" is the actor's own tile - entity_at finds the actor # themself there, which the target-is-actor check must reject assert open_companion_inventory(player, world, registry, (0, 0, 0), "back") is None def test_open_companion_inventory_none_for_slot_with_nothing_worn(registry): world = make_world(registry) player = Character(species_id="human", default_body_parts=registry.new_default_body_parts("human"), position=EntityPosition("field", 5, 5, 0)) dog = spawn_companion(registry, "companion_dog", EntityPosition("field", 6, 5, 0)) world.add_entity(player) world.add_entity(dog) assert open_companion_inventory(player, world, registry, (1, 0, 0), "head") is None