Указание: «зомби после упокоения оставляет свой труп. Можем ли мы подменять этот труп точно таким же, но с другой текстурой и с функцией мешка жертвы?» ПОДМЕНЯТЬ НЕ ПРИШЛОСЬ НИЧЕГО. Труп - не отдельная модель, а та же скелетная модель зомби в позе смерти, так что «такой же, но другой текстуры» делается перекраской уже лежащего трупа. Ни нового префаба, ни новой сущности. Три части, каждая на своём ванильном механизме: НЕ ИСЧЕЗАЕТ. 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>
113 KiB
113 KiB