Обыск больше не превращает труп в мешок. Труп получает сумку со списком добычи zPackVictim
и открывается игровым путём (LockRequestLocal -> LootBagOpened -> окно добычи с игровым
таймером обыска). Запрет открывать мёртвых у EntityAlive снят префиксами только для таких
трупов. Открытый и не опустошённый труп лежит час, опустошённый убирается сразу.
После загрузки труп узнаётся по сохранённой сумке (баффы зомби в сейв не пишутся).
LockRequestLocal вызывается из TEPersistence (перегрузка с ReadOnlySpan не компилируется
в основном проекте). Класс EntityLootContainerVictim оставлен ради старых сейвов.
Описание ножа исправлено на всех языках, README - текущее описание.
Проверено в игре на 3.3: открытие, таймер, уборка опустошённых, восстановление после загрузки.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Указание: «зомби после упокоения оставляет свой труп. Можем ли мы подменять
этот труп точно таким же, но с другой текстурой и с функцией мешка жертвы?»
ПОДМЕНЯТЬ НЕ ПРИШЛОСЬ НИЧЕГО. Труп - не отдельная модель, а та же скелетная
модель зомби в позе смерти, так что «такой же, но другой текстуры» делается
перекраской уже лежащего трупа. Ни нового префаба, ни новой сущности.
Три части, каждая на своём ванильном механизме:
НЕ ИСЧЕЗАЕТ. EntityAlive.timeStayAfterDeath - обычное публичное поле в тиках,
у зомби 30 секунд, у ванильного мешка 3600. Пишем второе.
ОБЫСКИВАЕТСЯ. У сущностей своя система команд, отдельная от блочной:
InitLocalActivationCommands / AllowActivationCommand / OnEntityActivated.
Объявляем ту же команду "search", что и ванильный мешок (EntityItem), поэтому
подпись достаётся готовой и локализованной. Список команд кешируется при
первом обращении - пока зомби жив, - поэтому на смерти он обнуляется.
ВНУТРИ ЛУТ. Обход сознательный: хранилище живёт внутри EntityLootContainer
вместе со своим сейвом и сетевой синхронизацией, и приделывать это трупу
значит трогать сейвы. Поэтому обыск ПРЕВРАЩАЕТ труп в мешок «Жертва».
ПЕРЕКРАСКА ЧЕРЕЗ ТЕКСТУРУ, А НЕ ЧЕРЕЗ _Color. Первая версия не работала вовсе:
у шейдеров Game/Character и Game/Animal/Fur свойства цвета НЕТ (видно в пробе,
которую печатает GhostTraderPatch: "tint property: <none>"). Красится сама
текстура - прогоном через RenderTexture, как обесцвечиваются торговцы, только
вместо сведения к яркости умножение на цвет. Результат кешируется по исходной
текстуре. Если модель на кадре смерти не собрана, труп встаёт в очередь и
докрашивается односекундным тиком.
ПОДСКАЗКА ПРИ НАВЕДЕНИИ - отдельный механизм, и сначала я настроил не тот.
Иконка EntityActivationCommand рисуется в РАДИАЛЬНОМ меню, то есть на зажатии.
А то, что видно при простом наведении, приходит из Entity.GetActivationText(),
и у EntityAlive он для существа возвращает пустую строку. Теперь возвращает то
же, что ванильный лутаемый объект: строку lootTooltipNew со значком клавиши из
разметки [action:...]. Имя берётся у зомби, так что читается «обыскать Арлин».
ОБЫСК НЕ МГНОВЕННЫЙ: три секунды с круговым индикатором (XUiC_Timer, тот же,
что при снятии верстака). Поле activateTime у команды не подошло - по нему игра
дёргает игровое событие из entity_class, а не наш код.
Обычный мешок это не отменяет: бросок вероятности остался как был, и теперь он
печатается в лог целиком (шанс против броска) - чтобы «не повезло» отличалось
от «сломано» без гадания. У ванильного зомби шанс 4%, то есть ноль мешков на
два десятка убийств - исход с вероятностью около 40%.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Мод для 7 Days to Die 3.2: навык «Некромантия», растущий от счётчика убитых
зомби, тёмное оружие с шестью собственными модами, призывная нежить, пирамида
духов и сюжетный финал через Чёрный портал. Локализация на 13 языках.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MaNro5hAGTzcQ7rJNN2tCX