Mi2dRPGamEng/tests/test_steering.py

110 lines
4.1 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.map_loader import MapLoader
from engine.tile import TileLayerInstance
from engine.world import World
from resources.logic.steering import at_helm, try_steer_ship, try_turn_ship
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 build_demo_world(registry) -> World:
loader = MapLoader(DEFS_DIR / "maps")
demo_world = loader.load("demo_world.json")
ship = demo_world.embeddings[0].child_map
world = World(registry=registry)
world.add_map(demo_world)
world.add_map(ship)
return world
def test_at_helm_true_when_standing_on_the_helm_tile(registry):
world = build_demo_world(registry)
sailor = make_human(registry, position=EntityPosition("ship_small", 2, 1, 0))
embedding = at_helm(sailor, world)
assert embedding is not None
assert embedding.child_map.map_id == "ship_small"
def test_at_helm_none_elsewhere_on_the_ship(registry):
world = build_demo_world(registry)
sailor = make_human(registry, position=EntityPosition("ship_small", 1, 1, 0))
assert at_helm(sailor, world) is None
def test_at_helm_none_when_not_aboard_an_embedded_map(registry):
world = build_demo_world(registry)
person = make_human(registry, position=EntityPosition("demo_world", 1, 1, 0))
assert at_helm(person, world) is None
def test_steering_moves_the_ship_and_leaves_aboard_entities_local_position_untouched(registry):
world = build_demo_world(registry)
ship = world.maps["ship_small"]
embedding = ship.parent_embedding
original_anchor = embedding.anchor
helmsman = make_human(registry, position=EntityPosition("ship_small", 2, 1, 0))
passenger = make_human(registry, position=EntityPosition("ship_small", 1, 1, 0))
assert try_steer_ship(helmsman, world, 0, 1, 0) is True
assert embedding.anchor == (original_anchor[0], original_anchor[1] + 1, original_anchor[2])
# nobody aboard needed to move - their local coordinates are exactly as before
assert (helmsman.position.x, helmsman.position.y) == (2, 1)
assert (passenger.position.x, passenger.position.y) == (1, 1)
def test_steering_fails_if_destination_runs_into_something_unwalkable(registry):
world = build_demo_world(registry)
parent = world.maps["demo_world"]
# ship's footprint is x:6-9, y:6-8; moving west by 1 would occupy x:5-8, y:6-8 -
# put a wall right in that path
parent.get_tile(5, 7, 0).room = TileLayerInstance("wood_wall")
helmsman = make_human(registry, position=EntityPosition("ship_small", 2, 1, 0))
embedding = world.maps["ship_small"].parent_embedding
before = embedding.anchor
assert try_steer_ship(helmsman, world, -1, 0, 0) is False
assert embedding.anchor == before
def test_steering_fails_off_the_parent_map_edge(registry):
world = build_demo_world(registry)
embedding = world.maps["ship_small"].parent_embedding
embedding.move_to((0, 0, 0)) # right at the parent's edge
helmsman = make_human(registry, position=EntityPosition("ship_small", 2, 1, 0))
assert try_steer_ship(helmsman, world, -1, 0, 0) is False
def test_turning_the_ship_rotates_the_embedding(registry):
world = build_demo_world(registry)
embedding = world.maps["ship_small"].parent_embedding
helmsman = make_human(registry, position=EntityPosition("ship_small", 2, 1, 0))
assert try_turn_ship(helmsman, world, 1) is True
assert embedding.rotation == 1
def test_non_helmsman_cannot_steer(registry):
world = build_demo_world(registry)
embedding = world.maps["ship_small"].parent_embedding
before = embedding.anchor
bystander = make_human(registry, position=EntityPosition("ship_small", 1, 1, 0))
assert try_steer_ship(bystander, world, 1, 0, 0) is False
assert embedding.anchor == before