152 lines
5.8 KiB
Python
152 lines
5.8 KiB
Python
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from engine.character import BodyPart, Character, ClothingPiece
|
|
from engine.defs import DefRegistry
|
|
|
|
DEFS_DIR = Path(__file__).resolve().parent.parent / "resources" / "defs"
|
|
|
|
|
|
@pytest.fixture()
|
|
def registry():
|
|
return DefRegistry.load(DEFS_DIR)
|
|
|
|
|
|
def make_character(registry, species_id: str, **kwargs) -> Character:
|
|
return Character(species_id=species_id, default_body_parts=registry.new_default_body_parts(species_id), **kwargs)
|
|
|
|
|
|
# --- arm_slot_count -----------------------------------------------------------------------
|
|
|
|
|
|
def test_arm_slot_count_for_two_armed_species(registry):
|
|
human = make_character(registry, "human")
|
|
assert human.arm_slot_count() == 2
|
|
|
|
|
|
def test_arm_slot_count_for_four_armed_species(registry):
|
|
reptilian = make_character(registry, "reptilian_quad")
|
|
assert reptilian.arm_slot_count() == 4
|
|
|
|
|
|
def test_arm_slot_count_for_armless_species(registry):
|
|
dog = make_character(registry, "dog")
|
|
assert dog.arm_slot_count() == 0
|
|
|
|
|
|
def test_arm_slot_count_ignores_a_missing_arm(registry):
|
|
human = make_character(registry, "human")
|
|
human.body_parts.append(BodyPart("left_arm", "human_left_arm", removed=True))
|
|
assert human.arm_slot_count() == 1
|
|
|
|
|
|
# --- wear_item: bigger (more sleeves) fits smaller, not vice versa --------------------------
|
|
|
|
|
|
def test_two_armed_species_can_wear_a_four_armed_jacket(registry):
|
|
human = make_character(registry, "human")
|
|
assert human.wear_item("torso", "reptilian_jacket", registry) is True
|
|
assert human.get_clothing("torso").item_def_id == "reptilian_jacket"
|
|
|
|
|
|
def test_four_armed_species_cannot_wear_a_two_armed_jacket(registry):
|
|
reptilian = make_character(registry, "reptilian_quad")
|
|
assert reptilian.wear_item("torso", "leather_jacket", registry) is False
|
|
assert reptilian.get_clothing("torso") is None
|
|
|
|
|
|
def test_four_armed_species_can_wear_a_four_armed_jacket(registry):
|
|
reptilian = make_character(registry, "reptilian_quad")
|
|
assert reptilian.wear_item("torso", "reptilian_jacket", registry) is True
|
|
|
|
|
|
def test_two_armed_species_can_wear_a_two_armed_jacket(registry):
|
|
human = make_character(registry, "human")
|
|
assert human.wear_item("torso", "leather_jacket", registry) is True
|
|
|
|
|
|
def test_non_sleeved_item_ignores_arm_count_entirely(registry):
|
|
# dog_saddlebag has no arm_slots_required set (0 = unconstrained) - arm count is
|
|
# irrelevant for a non-sleeved item, regardless of body type
|
|
dog = make_character(registry, "dog")
|
|
assert dog.wear_item("back", "dog_saddlebag", registry) is True
|
|
|
|
|
|
# --- wear_item: body_type gate (a dog can't wear human clothes, full stop) -------------------
|
|
|
|
|
|
def test_dog_cannot_wear_a_human_jacket(registry):
|
|
dog = make_character(registry, "dog")
|
|
assert dog.wear_item("torso", "leather_jacket", registry) is False
|
|
assert dog.get_clothing("torso") is None
|
|
|
|
|
|
def test_dog_cannot_wear_a_four_armed_jacket_either(registry):
|
|
# arm count would technically fit (0 <= 4) but body_type ("quadruped" vs "biped") rejects
|
|
# it outright - a completely different anatomy, not just a sleeve-count mismatch
|
|
dog = make_character(registry, "dog")
|
|
assert dog.wear_item("torso", "reptilian_jacket", registry) is False
|
|
|
|
|
|
def test_dog_cannot_wear_a_human_backpack(registry):
|
|
dog = make_character(registry, "dog")
|
|
assert dog.wear_item("back", "backpack_basic", registry) is False
|
|
|
|
|
|
def test_dog_can_wear_dog_equipment(registry):
|
|
dog = make_character(registry, "dog")
|
|
assert dog.wear_item("torso", "dog_harness", registry) is True
|
|
assert dog.wear_item("back", "dog_saddlebag", registry) is True
|
|
|
|
|
|
def test_biped_species_cannot_wear_dog_equipment(registry):
|
|
human = make_character(registry, "human")
|
|
reptilian = make_character(registry, "reptilian_quad")
|
|
assert human.wear_item("torso", "dog_harness", registry) is False
|
|
assert reptilian.wear_item("back", "dog_saddlebag", registry) is False
|
|
|
|
|
|
def test_reptilian_and_zenari_share_biped_body_type_and_can_wear_each_others_jackets(registry):
|
|
zenari = make_character(registry, "alien_tri")
|
|
assert zenari.wear_item("torso", "reptilian_jacket", registry) is True # both bipeds, fits (2 <= 4)
|
|
|
|
|
|
# --- wear_item: slot / replacement semantics -------------------------------------------------
|
|
|
|
|
|
def test_wear_item_rejects_item_meant_for_a_different_slot(registry):
|
|
human = make_character(registry, "human")
|
|
assert human.wear_item("back", "leather_jacket", registry) is False # leather_jacket is "torso"
|
|
assert human.get_clothing("back") is None
|
|
|
|
|
|
def test_wear_item_replaces_whatever_was_in_that_slot(registry):
|
|
human = make_character(registry, "human")
|
|
human.wear_item("torso", "leather_jacket", registry)
|
|
human.wear_item("torso", "reptilian_jacket", registry)
|
|
assert human.get_clothing("torso").item_def_id == "reptilian_jacket"
|
|
assert len([c for c in human.clothing if c.slot == "torso"]) == 1
|
|
|
|
|
|
def test_wear_item_does_not_replace_on_failed_fit_check(registry):
|
|
reptilian = make_character(registry, "reptilian_quad")
|
|
reptilian.wear_item("torso", "reptilian_jacket", registry)
|
|
assert reptilian.wear_item("torso", "leather_jacket", registry) is False
|
|
assert reptilian.get_clothing("torso").item_def_id == "reptilian_jacket" # unchanged
|
|
|
|
|
|
def test_take_off_clears_a_slot(registry):
|
|
human = make_character(registry, "human")
|
|
human.wear_item("torso", "leather_jacket", registry)
|
|
human.take_off("torso")
|
|
assert human.get_clothing("torso") is None
|
|
|
|
|
|
def test_take_off_reveals_a_default_garment_underneath(registry):
|
|
human = make_character(registry, "human", default_clothing=[ClothingPiece("torso", "leather_jacket")])
|
|
human.wear_item("torso", "reptilian_jacket", registry)
|
|
assert human.get_clothing("torso").item_def_id == "reptilian_jacket"
|
|
human.take_off("torso")
|
|
assert human.get_clothing("torso").item_def_id == "leather_jacket" # fell back to the default
|