110 lines
4.1 KiB
Python
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
|