Mi2dRPGamEng/tests/test_interaction.py

113 lines
4.4 KiB
Python

from pathlib import Path
import pytest
from engine.character import Character
from engine.defs import DefRegistry
from engine.entity import EntityPosition
from engine.inventory import Inventory
from engine.item import ItemInstance
from engine.map import Map
from engine.tile import Tile, TileLayerInstance
from engine.world import World
from resources.logic.construction import interact_with_tile, wielded_tool
DEFS_DIR = Path(__file__).resolve().parent.parent / "resources" / "defs"
@pytest.fixture()
def registry():
return DefRegistry.load(DEFS_DIR)
def make_human(registry, **kwargs) -> Character:
return Character(species_id="human", default_body_parts=registry.new_default_body_parts("human"), **kwargs)
def make_world(registry):
field = Map("field", 5, 5, 1)
for x in range(5):
for y in range(5):
field.set_tile(x, y, 0, Tile(subfloor=TileLayerInstance("dirt"), room=TileLayerInstance("wood_wall")))
world = World(registry=registry)
world.add_map(field)
return world, field
def test_wielded_tool_finds_a_held_tool_kind_item(registry):
character = make_human(registry)
assert wielded_tool(character, registry) is None
character.wield_item("right_hand", "multi_deconstructor", registry)
tool = wielded_tool(character, registry)
assert tool is not None
assert tool.id == "multi_deconstructor"
def test_interact_without_a_wielded_tool_is_a_no_op(registry):
world, field = make_world(registry)
character = make_human(registry, position=EntityPosition("field", 2, 2, 0))
result = interact_with_tile(character, world, "field", 2, 2, 0, "room", "left")
assert result is None
assert field.get_tile(2, 2, 0).room is not None # untouched
def test_deconstructor_left_click_destroys_with_no_item(registry):
world, field = make_world(registry)
character = make_human(registry, position=EntityPosition("field", 2, 2, 0))
character.wield_item("right_hand", "multi_deconstructor", registry)
result = interact_with_tile(character, world, "field", 2, 2, 0, "room", "left")
assert result is True
assert field.get_tile(2, 2, 0).room is None
def test_deconstructor_right_click_yields_item_into_inventory(registry):
world, field = make_world(registry)
character = make_human(registry, position=EntityPosition("field", 2, 2, 0))
character.wield_item("right_hand", "multi_deconstructor", registry)
character.inventory = Inventory(4, 4)
result = interact_with_tile(character, world, "field", 2, 2, 0, "room", "right")
assert result is not None
assert result.def_id == "wood_planks"
assert field.get_tile(2, 2, 0).room is None
assert {p.item.def_id for p in character.inventory.items()} == {"wood_planks"}
def test_deconstructor_right_click_without_room_in_inventory_still_clears_layer(registry):
world, field = make_world(registry)
character = make_human(registry, position=EntityPosition("field", 2, 2, 0))
character.wield_item("right_hand", "multi_deconstructor", registry)
character.inventory = None # no inventory to receive the item
result = interact_with_tile(character, world, "field", 2, 2, 0, "room", "right")
assert result is not None
assert field.get_tile(2, 2, 0).room is None
def test_constructor_consumes_matching_material_and_builds_layer(registry):
world, field = make_world(registry)
field.get_tile(2, 2, 0).room = None # bare slot to build on
character = make_human(registry, position=EntityPosition("field", 2, 2, 0))
character.wield_item("right_hand", "constructor_tool", registry)
character.inventory = Inventory(4, 4)
planks_def = registry.get_item_def("wood_planks")
character.inventory.place(ItemInstance("planks-1", "wood_planks"), planks_def, 0, 0)
result = interact_with_tile(character, world, "field", 2, 2, 0, "room", "left")
assert result is True
assert field.get_tile(2, 2, 0).room.def_id == "wood_wall"
assert character.inventory.items() == []
def test_constructor_fails_without_matching_material(registry):
world, field = make_world(registry)
field.get_tile(2, 2, 0).room = None
character = make_human(registry, position=EntityPosition("field", 2, 2, 0))
character.wield_item("right_hand", "constructor_tool", registry)
character.inventory = Inventory(4, 4)
result = interact_with_tile(character, world, "field", 2, 2, 0, "room", "left")
assert result is False
assert field.get_tile(2, 2, 0).room is None