46 lines
2.4 KiB
Python
46 lines
2.4 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
|
|
from engine.character import BodyPart
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class AbilityDef:
|
|
"""An ability a species can perform, gated on the body parts it needs to work."""
|
|
|
|
id: str
|
|
name: str
|
|
required_slots: tuple[str, ...] = ()
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class SpeciesDef:
|
|
"""A species/preset a Character is based off: default anatomy + blood-loss thresholds."""
|
|
|
|
id: str
|
|
name: str
|
|
genders: list[str] = field(default_factory=list) # open marker: species defines its own valid gender values
|
|
default_body_parts: list[BodyPart] = field(default_factory=list)
|
|
default_organs: list[str] = field(default_factory=list) # organ_def ids; placed by each organ's own host_slot
|
|
body_type: str = "biped" # coarse anatomical shape (e.g. "biped", "quadruped") - gates which
|
|
# clothing fits at all, regardless of arm count; see ItemDef.compatible_body_types
|
|
body_type_options: list[str] = field(default_factory=list) # cosmetic build/archetype choices
|
|
# for character creation (e.g. "average"/"thin"/"fat"/"hulk") - NOT the same as body_type
|
|
# above, which is a fixed anatomical trait, not a player choice
|
|
hair_colors: list[str] = field(default_factory=list) # valid hair color choices for character
|
|
# creation; empty for species with no hair (e.g. reptilian, hydraulibot, motorbot)
|
|
is_synthetic: bool = False # mechanical/electronic organs (currently hydraulibot/motorbot) -
|
|
# lets game logic gate effects like a lightning-induced short circuit without hardcoding
|
|
# species ids
|
|
abilities: list[AbilityDef] = field(default_factory=list)
|
|
blood_danger_threshold: float = 50.0 # % blood remaining
|
|
blood_critical_threshold: float = 25.0
|
|
blood_label: str = "Blood" # display term for blood_percentage - e.g. hydraulibot calls it
|
|
# "Synthmuscle-Fluid" (see Character.blood_label); purely cosmetic, no mechanical difference
|
|
health_item_compatibility: list[str] = field(default_factory=list) # placeholder for future health-item tagging
|
|
innate_check_penalties: dict[str, float] = field(default_factory=dict) # permanent, always-on
|
|
# fraction lost for a named check regardless of damage state - e.g. motorbot's clumsy
|
|
# manipulators (sleight_of_hand) - applied in Character.total_check_penalty alongside
|
|
# skill/organ/ailment penalties, the one source that isn't tied to any damage/ailment
|