Части тела
Особенности нейминга
Здесь и далее парты (parts), бодипарты (bodyparts) и части тела (chasty_tela) это одно и то же. По неведомой причине местами в коде они называются и бодипартами и партами. Так или иначе, это одно и то же.
Часть тела - это основная составляющая персонажа. Персонаж без частей тела это грустно, даже если у вас персонажи плавающие слизняки, то им все равно нужна хотя бы одна часть тела.
Бодипарт (Part)
Поля класса Part
uid: str- Айдишник. Так же является primary_key, т.е. обязан быть уникальным уже на стороне БД.
display_name: str- Отображаемое имя, строка. Обязательно.
hp: int- Максимальное (базовое) хп. Интегер, обязательно.
resists: ResistTable- Врожденные резисты части тела. Подробнее про резисты тут
accuracy_coefficient: float- Вероятность попадания по конечности, по умолчанию 1.
inability_percentage: float- Доля, с которой конечность считается не-рабочей. Единица это 100%, по умолчанию 0.2, то есть нужно снести 80% ХП и больше, чтобы конечность перестала быть рабочей.
deadly: bool- Буль, является ли травма конечности смертельной (учтите, что смертельность с точки зрения боевки не равна смерти в игре, это просто нокаут). По умолчанию False.
status_on_damaging: Status- Один статус, накладываемый конечностью на себя при ранении. Только один, да.
status_on_losing: list[Status]- Список статусов, накладываемый на энтити при потере конечности.
abilities: AbilitiesTable- Список абилок, которые дает конечность. Если
curr_hp < base_hp * inability_percentage, то абилка так же не дается. tags: list[Tag]- Список тэгов части тела.
tags_type: TagType- Для части тела всегда будет равно TagType.BODYPART_TAG
summoned: bool- Особая штука, связана она с временными частями тела. Работает так же, как и призванные предметы; подробности ниже.
time_to_live: int- О временных частях тела ниже.
events: dict- Об ивентах подробнее на их страничке.
Контейнер части тела (PartContainer)
Как и многие другие штуки с динамичными данными, сам по себе Part хранится в особом PartContainer, созданном специально для каждой части тела.
Поля класса PartContainer
- bodypart: Part
- Референс на часть тела.
- curr_hp: float
- Текущее хп части тела.
- disabled: bool
- "Неспособность" части тела. В случае, если конечность disabled, то ее абилки не могут быть использованы, а так же накладывается status_on_damaging.
- upgrades: list[PartUpgrade]
- Список апгрейдов части тела. Подробнее про апгрейды на их страничке.
- armor_element: WearableContainer
- Элемент брони на части тела. Формально, даже если там нет брони, там все равно находится WearableContainer, но он пустой (в item ничего нет).
- time_left: int = IntField(default=0)
- Нужно для временных частей тела, подробнее об этом ниже.
У контейнера так же есть методы. В большинстве случаев они нужны для того, чтобы сразу получать суммарные значения и для контейнера, и для части тела.
Поля класса PartContainer
take_hp(amount: float | int, damage_type: str = None, damage_trauma_division: int = 5, traumatic: bool = True) -> None- Основной метод для нанесения урона. Если указан только amount, то он просто снимает это количество урона, убеждаясь, что он не уйдет в минус. Если же указан damage_type, то он автоматически может наложить травму. Подробнее о травмах тут.
restore_hp(amount: float)- Лучше всего восстанавливать хп через этот метод, так как он не даст поднять хп выше, чем максимальное.
get_max_hp() -> float- Возвращает максимальное хп, с учетом апгрейдов.
get_full_resist(resist_name: str)- Узнать полный резист, с учетом резиста части тела и апгрейдов, но, естественно, без учета статусов, тринкетов и прочих приколов самой энтити. Подробнее про резисты тут
get_ablitities(containers: bool = False) -> list- Узнать все абилки, с учетом апгрейдов.
get_def_abilities(containers: bool = False) -> list- Узнать все защитные абилки, с учетом апгрейдов.
get_accuracy_coefficient() -> float- Узнать совокупный коэффициент точности, с учетом апгрейдов.
get_inability_percentage() -> float- Узнать совокупный процент, с которого часть тела считается нерабочей; с учетом апгрейдов.
get_persistent_tags() -> list[Tags]- Получить совокупные тэги самой части тела и апгрейдов.
evaluate_own_disability() -> bool- Посчитать собственную работоспособность. Возвращает true, если часть тела стала неспособной, false, если была неспособной, но стала способной, и None, если ничего не поменялось.
get_total_psychosis(self) -> Psychosis- Получить инстанс класса Psychosis с значениями психоза от всех имплантов на части тела. В основном чисто техническая штука.
Особенности хранения частей тела в энтити
Контейнеры хранятся в entity, но в особом виде. Если обычно все хранится списками, то части тела хранятся как словарь (dict), где ключ это строка, а значение это и есть часть тела; например "left_leg": leg, где leg это инстанс класса Part. Это нужно для того, чтобы проще было понимать, о чем речь, потому что айдишник самого парта может быть human_head или elf_head, а энтити это будет просто head. Так гораздо проще для восприятия. Тем более, одна и та же human_arm может встречаться два раза в рамках одной энтити - тогда гораздо проще будет, если записать их как left_arm и right_arm и так далее.
Временные части тела
Я же обещал, что про них ниже. Так вот, ниже настало.
Сама по себе часть тела может иметь time_to_live, тогда, при добавлении этой части тела энтити, в контейнере будет заполнено time_left. Оно уменьшается каждый ход, части тела с time_left автоматически уничтожаются при перерасчете.
В принципе, если сама часть тела не имеет time_to_live, но вам очень хочется добавить часть тела временно, у метода add_bodypart в entity есть для этого специальный атрибут. Таким образом, можно добавить абсолютно любую часть тела временно.
Буль summoned нужен для разного рода абилок и указывается только в самой части тела. Например, может быть абилка, наносящая удвоенный урон по summoned частям тела. Но если это специально не указывать, то никакого влияния не будет.
В остальном временные конечности никак не отличаются от постоянных, кроме этого скромного таймера самоуничтожения.