Mi2dRPGamEng/tests/test_character_health.py

122 lines
4.4 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_human(registry, **kwargs) -> Character:
return Character(
species_id="human",
gender="female",
default_body_parts=registry.new_default_body_parts("human"),
**kwargs,
)
def test_blood_status_thresholds(registry):
species = registry.get_species_def("human")
character = make_human(registry, blood_percentage=100.0)
assert character.blood_status(species) == "normal"
character.blood_percentage = 50.0
assert character.blood_status(species) == "danger"
character.blood_percentage = 10.0
assert character.blood_status(species) == "critical"
def test_bio_defaults_to_zeroed_dnd_skills(registry):
character = make_human(registry)
assert character.bio["stealth"] == 0
assert character.bio["athletics"] == 0
assert set(character.bio.keys()) >= {"perception", "insight", "acrobatics"}
def test_mental_stats_optional_by_default(registry):
character = make_human(registry)
assert character.mental_stats is None
npc = make_human(registry, mental_stats={"insanity": 0.0})
assert npc.mental_stats == {"insanity": 0.0}
def test_skill_penalty_zero_when_all_parts_healthy(registry):
character = make_human(registry)
assert character.skill_penalty("acrobatics", registry) == 0.0
def test_skill_penalty_full_when_relevant_parts_missing(registry):
character = make_human(registry)
character.body_parts = [
BodyPart("left_leg", "human_left_leg", removed=True),
BodyPart("right_leg", "human_right_leg", removed=True),
]
# acrobatics is weighted only on the legs (0.5 each) -> fully lost when both are gone
assert character.skill_penalty("acrobatics", registry) == pytest.approx(1.0)
# athletics also draws from torso/arms, which are untouched -> partial loss
penalty = character.skill_penalty("athletics", registry)
assert 0.0 < penalty < 1.0
def test_skill_penalty_scales_with_integrity_not_just_removal(registry):
character = make_human(registry)
character.body_parts = [BodyPart("head", "human_head", integrity=50.0)]
penalty = character.skill_penalty("perception", registry)
assert penalty == pytest.approx(0.5)
def test_get_body_part_returns_none_when_explicitly_removed(registry):
character = make_human(registry)
character.body_parts = [BodyPart("left_arm", "human_left_arm", removed=True)]
assert character.get_body_part("left_arm") is None
assert character.get_body_part("right_arm") is not None # still falls back to default
def test_get_clothing_falls_back_to_default_like_body_parts(registry):
character = make_human(
registry,
default_clothing=registry.new_default_clothing("player"),
)
assert character.get_clothing("back").item_def_id == "backpack_basic"
def test_get_clothing_override_beats_default_and_removed_returns_none(registry):
character = make_human(
registry,
clothing=[ClothingPiece("torso", "leather_jacket")],
default_clothing=registry.new_default_clothing("player"),
)
assert character.get_clothing("torso").item_def_id == "leather_jacket"
assert character.get_clothing("back").item_def_id == "backpack_basic" # still falls back
character.clothing.append(ClothingPiece("back", "backpack_basic", removed=True))
assert character.get_clothing("back") is None
def test_equipped_backpack_grants_a_lazily_created_inventory(registry):
character = make_human(
registry,
default_clothing=registry.new_default_clothing("player"),
)
assert character.get_clothing("back").inventory is None
inventory = character.get_equipped_inventory("back", registry)
assert (inventory.width, inventory.height) == (4, 4)
# same instance on repeated access, and matches what's stored on the clothing piece
assert character.get_equipped_inventory("back", registry) is inventory
assert character.get_clothing("back").inventory is inventory
def test_equipped_inventory_is_none_for_non_container_clothing(registry):
character = make_human(registry, clothing=[ClothingPiece("torso", "leather_jacket")])
assert character.get_equipped_inventory("torso", registry) is None