Skip to content

Части тела

Особенности нейминга

Здесь и далее парты (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 частям тела. Но если это специально не указывать, то никакого влияния не будет.

В остальном временные конечности никак не отличаются от постоянных, кроме этого скромного таймера самоуничтожения.