Перейти к содержимому

Стекло маски и капли дождя ​

IX-Ray поддерживает два типа стекла, повреждения от состояния предмета, два варианта капель дождя и протирание анимациями от первого лица. Стекло принадлежит надетому шлему или костюму. Здоровье главного героя не определяет его внешний вид.

Страница описывает реализацию в текущей ветке. Она относится к пакетам gamedata, gamedata_soc, gamedata_cs и gamedata_coc; доступные предметы и ресурсы анимаций зависят от игры и мода.

Быстрое подключение ​

Для существующего шлема или костюма добавьте параметры в секцию предмета, а не в его HUD-секцию:

ini
glass_present = true
hud_gas_mask_avaliable = true
hud_rain_drops_avaliable = true
hud_gas_mask_type = flat
use_condition = true

Включите эффекты в консоли:

text
r4_use_gasmask true
r2_use_rain_drops true
r2_rain_drops_mode procedural

Выберите R4, наденьте предмет и перейдите к виду от первого лица. Трещины зависят от состояния предмета. Капли накапливаются, когда дождь достигает камеры. Для протирания дополнительно нужна анимация, настроенная по инструкции ниже.

Рендеры и пользовательские настройки ​

КомандаЗначенияНачальное значение в движкеДействие
r4_use_gasmasktrue, falsefalseВключает постпроцесс стекла и повреждения от состояния предмета на R4.
r2_use_rain_dropstrue, falsefalseВключает капли на стекле на R2 и R4.
r2_rain_drops_modetexture, proceduraltextureВыбирает реализацию капель.

Профили пользователя и пресеты могут переопределять начальные значения. Эти настройки также доступны в расширенных настройках графики/постпроцессов и применяются без перезапуска рендера. Используйте точные имена выше: исторические r_use_gasmask и r_use_rain_drops не являются командами этой реализации.

РендерСтекло flatСтекло curvedТекстурные каплиПроцедурные капли
R4 / D3D11ДаДаДаДа
R2 / D3D9НетНетДаДа
R1НетНетНетНет

Стекло и капли включаются независимо. При выключенном стекле подходящая экипировка может отображать капли. При выключенных каплях стекло и трещины продолжают работать. На R2 тип стекла не влияет на изображение, но надетый предмет со стеклом всё равно необходим для капель.

r2_use_weapon_raindrops управляет отдельным эффектом на оружии. Протирание стекла не очищает капли оружия и не меняет влажность мира.

Настройка экипировки ​

Параметры читает CArmorBase — общая база шлемов и костюмов:

ПараметрЗначение при отсутствииНазначение
glass_presentfalseУ предмета есть стекло; он может предоставлять эффекты маски.
hud_gas_mask_avaliabletrueРазрешает постпроцесс стекла для этого предмета.
hud_rain_drops_avaliabletrueРазрешает капли дождя для этого предмета.
hud_gas_mask_typeflatВыбирает стекло flat или curved.
use_conditiontrueВключает существующий флаг использования состояния предмета; отдельное HP стекла не создаётся.

Сохраняйте написание avaliable в обоих параметрах доступности. available не является синонимом. Типы стекла задаются точными строчными значениями flat и curved. Неизвестное значение вызывает предупреждение в логе и выбор flat.

Одних флагов доступности недостаточно: нужен glass_present = true. Значения, унаследованные от родительской секции, также учитываются. Флаги разрешают эффекты в дополнение к глобальным настройкам игрока, а не переопределяют эти настройки.

Как выбирается предмет со стеклом ​

Эффекты предоставляет текущий актор, пока он жив и использует вид от первого лица:

  1. Надетый шлем с glass_present = true имеет приоритет.
  2. Иначе используется надетый костюм с glass_present = true.
  3. Если ни один предмет не подходит, эффекты стекла отключены.

Шлем без стекла не мешает использовать стекло костюма. Тип, флаги доступности и состояние берутся из одного выбранного предмета; состояния шлема и костюма не суммируются. Если выбранный шлем запрещает один из эффектов, для этого эффекта перехода к костюму нет. Предметы в рюкзаке не предоставляют эффекты стекла.

Плоское и полусферическое стекло ​

ТипВнешний видСтупени поврежденияВозможное применение
flatОбычное стекло с преломлением, отражениями и трещинами от состояния предмета.Десять карт нормалей.Плоские щитки и стёкла костюмов.
curvedИсходное полусферическое стекло с усиленными искажениями по краям, отражениями и конденсатом.Четыре исходных состояния текстуры.Защитные шлемы с округлым щитком.

Оба типа на R4 поддерживают оба режима капель. Названия типов описывают форму стекла. Отсутствие параметра выбирает flat; для полусферического стекла мод должен явно указать curved.

Например, DLTX-патч для CoP/CoC в файле наподобие configs/mod_system_visors.ltx может назначить защитному шлему исходное стекло, а научному костюму — плоское:

ini
![helm_protective]
glass_present = true
hud_gas_mask_avaliable = true
hud_rain_drops_avaliable = true
hud_gas_mask_type = curved
use_condition = true

![scientific_outfit]
glass_present = true
hud_gas_mask_avaliable = true
hud_rain_drops_avaliable = true
hud_gas_mask_type = flat
use_condition = true

Изменяйте только секции, существующие в целевой игре. В обычном LTX поместите те же строки параметров в существующую секцию предмета или наследника вместо синтаксиса DLTX ![section].

Состояние предмета и трещины ​

Рендер читает существующее значение GetCondition() выбранного предмета. Значение 1 означает полностью исправную экипировку, 0 — полностью повреждённую. Это состояние/HP предмета, а не HP актора, ресурс фильтра или новый отдельный счётчик здоровья стекла. Значение меняют существующие механики повреждения и ремонта экипировки.

Рендер читает сохранённое состояние независимо от use_condition. Этот флаг не включает и не выключает трещины, не заменяет glass_present и при изменении не ремонтирует повреждённое стекло.

Плоское стекло ограничивает состояние диапазоном [0, 1] и выбирает текстуру по формуле:

text
DamagePhase = min(floor((1 - Condition) * 10) + 1, 10)
Texture = mask_nm_<DamagePhase>.dds

Полусферическое стекло выбирает одно из четырёх исходных состояний по формуле min(floor(4 - 4 * Condition), 3) для обычного состояния в диапазоне [0, 1].

Состояние предметаТекстура плоского стеклаТекстура полусферического стекла
1.00 / 100%mask_nm_1.ddsGood.dds
0.75 / 75%mask_nm_3.ddsMedium.dds
0.50 / 50%mask_nm_6.ddsBad.dds
0.25 / 25%mask_nm_8.ddsBroken.dds
0.00 / 0%mask_nm_10.ddsBroken.dds

Ступени повреждения переключаются дискретно. Ремонт выбранного предмета меняет видимую степень повреждения. Дождь и протирание не повреждают и не ремонтируют предмет. Протирание не убирает трещины и конденсат шейдера curved.

Режимы капель и накопление ​

texture использует существующую статическую карту нормалей капель shaders/fx_hud_droplets.dds. Сила искажения изображения зависит от накопленного количества. procedural генерирует в шейдере анимированные слои, включая движущиеся капли и следы. Он использует то же накопленное количество, поэтому протирание и укрытия работают в обоих режимах.

Накоплением управляет движок, а не только время в шейдере:

СитуацияРезультат
Дождь под открытым небомКоличество растёт на 0.05 в секунду.
Дождь под укрытием сверхуКоличество уменьшается на 0.05 в секунду.
Плотность дождя в погодеКоличество ограничено плотностью в диапазоне [0, 1].
Дождь прекращается или эффект дождя отключёнКоличество сразу обнуляется.
Callback протиранияКоличество сразу обнуляется; под дождём стекло затем намокает снова.
ПаузаНакопление и высыхание останавливаются; проверки прекращения дождя и отключения эффекта сохраняются.

При плотности 1 сухое стекло достигает полного количества примерно за 20 секунд, а полностью мокрое высыхает в укрытии примерно за 20 секунд, пока дождь продолжается. При плотности 0.5 максимум равен 0.5 и достигается примерно за 10 секунд. При снижении плотности во время обычного обновления количество ограничивается новым значением.

Укрытие определяется лучом длиной 50 метров строго вверх от камеры. Проверяется статическая и динамическая геометрия с коллизией; объект, от которого ведётся наблюдение, исключён. Первая проверка выполняется сразу, следующие — не чаще раза в секунду. Поэтому вход в укрытие и выход из него могут отразиться на накоплении с задержкой примерно до секунды. Видимая крыша должна иметь коллизию, чтобы считаться укрытием.

Состояние обновляется один раз за кадр рендера с использованием времени кадра, ограниченного одной секундой на обновление. Обычные изменения FPS не меняют скорость накопления; длительная остановка не отыгрывает всё прошедшее время сразу.

Сохранение количества и сбросы ​

Количество общее для двух режимов капель. Переключение texture → procedural и обратно сохраняет его. Отключение только постпроцесса стекла также сохраняет количество, если капли остаются включёнными.

Снятие или замена выбранного предмета со стеклом обнуляет количество, в том числе замена другим экземпляром той же секции. Смерть, переход к виду от третьего лица, смена объекта наблюдения, отключение капель глобально или для выбранного предмета и отключение от уровня также сбрасывают состояние. После повторного включения или надевания стекло начинает сухим.

Отдельной сохранённой влажности у каждого предмета в инвентаре нет. Накопление относится к текущему виду и не сериализуется вместе с экипировкой. Прекращение дождя очищает стекло сразу; остаточное высыхание после дождя не моделируется.

Анимации протирания ​

Действие актора называется clear_gasmask. Назначьте его в меню управления или через консоль; например, эта команда назначает клавишу H:

text
bind clear_gasmask kH

Это пример назначения, а не указание стандартной клавиши. Действие требует надетый шлем или костюм со стеклом. Оно может использовать anm_gasmask HUD-предмета/устройства либо отдельно настроенный HUD animator. Сам шейдер стекла не предоставляет анимации рук.

HUD-предметы и устройства: anm_gasmask ​

Добавьте базовый псевдоним в нужную HUD-секцию, указав анимацию протирания, существующую в загруженной модели рук/OMF:

ini
anm_gasmask = visor_wipe

visor_wipe — пример имени анимации: замените его реальным движением из мода. Базовый псевдоним anm_gasmask нужен для проверки доступности, даже если дополнительно используются варианты для разных состояний. Необязательный звук snd_gasmask задаётся в игровой секции предмета/state animator, а не вместо псевдонима движения.

Добавьте в анимацию рук motion mark с именем Left, точно сохранив регистр, в момент, когда стекло должно стать чистым. Это метка в данных анимации, а не имя кости или произвольный Anim Notify. См. HUD Animator: добавление меток анимации.

Во время состояния протирания eDeviceSwitch достижение Left вызывает CActor::ClearMaskCB(). Callback обнуляет количество капель для актора, от которого сейчас ведётся наблюдение. Сброс происходит мгновенно на метке; пространственного прохода очистки по экрану нет. Путь HUD-предмета не очищает стекло автоматически только потому, что anm_gasmask завершилась: нужна метка Left.

Сначала актор рассматривает текущий state animator, затем подходящие сочетания активного HUD-предмета и устройства, затем отдельные анимации предмета/устройства. Стрельба, прицеливание, незавершённые действия предмета и активация устройства могут блокировать протирание. Текущий state animator без возможности протирания также блокирует последующие пути; резервный вариант не прерывает принудительно любую занятую анимацию.

Резервный вариант: отдельный HUD animator ​

Когда путь предмета/устройства не выбран и item animator свободен, актор может использовать секцию, указанную в configs/game_global.ltx:

ini
[glass_mask]
clearmask_animator = clear_gasmask_animator

Указанная секция должна существовать в настройках, загружаемых через system.ltx. Одной поставляемой ссылки недостаточно: добавьте в мод секцию и необходимые движения. Пример только с руками:

ini
[clear_gasmask_animator]
hands_position = 0, 0, 0
hands_position_16x9 = 0, 0, 0
hands_orientation = 0, 0, 0
hands_orientation_16x9 = 0, 0, 0
anm_show = visor_wipe
can_sprint = false

Замените visor_wipe движением, доступным на текущих HUD-руках, подберите смещения под модель и подключите LTX-файл секции в system.ltx. Этот путь воспроизводит anm_show, в отличие от anm_gasmask у предмета/устройства. Фиктивный предмет в инвентаре не нужен. Звуки, необязательные модели и остальные параметры описаны в HUD Animator.

Движок присоединяет callback протирания к Left. Добавьте метку, чтобы очистка совпала с движением руки. Если метка Left не достигнута, этот отдельный item animator вызывает оставшийся callback при естественном завершении анимации. Callback расходуется один раз, поэтому завершение после метки не очищает стекло повторно. Остановка animator до обоих событий удаляет callback и не очищает стекло.

Ручной запуск animator из Lua сам по себе не присоединяет callback протирания актора. Используйте действие очистки маски, когда анимация должна сбрасывать накопленные капли.

Шейдеры и текстуры ​

Все пути ниже указаны относительно выбранного игрового пакета:

РесурсНазначение
shaders/d3d11/flat_gasmask.ps.hlslПлоское стекло, повреждения/отражения и выбранные капли в объединённом проходе.
shaders/d3d11/effector_gasmask.ps.hlslСохранённый шейдер полусферического стекла.
shaders/{d3d11,r2}/raindrops.ps.hlslОтдельный проход текстурных капель.
shaders/{d3d11,r2}/procedural_raindrops.ps.hlslОтдельный проход процедурных капель.
shaders/{d3d11,r2}/shared/VisorDrops.hlsliОбщий алгоритм процедурных капель для каждого шейдерного бэкенда.
textures/shaders/gasmasks/mask_nm_1.dds … mask_nm_10.ddsДесять карт повреждений плоского стекла.
textures/shaders/gasmask/{Good,Medium,Bad,Broken}.ddsИсходные карты повреждений полусферического стекла.
textures/shaders/gasmask/Condensation.ddsКонденсат полусферического стекла.
textures/shaders/fx_hud_droplets.ddsСуществующая карта нормалей текстурных капель.

Фигурные скобки обозначают варианты путей, а не буквальные имена каталогов. Сохраняйте различие между gasmasks для плоских карт и gasmask для полусферических. Плоское стекло загружает индексы 1–10; mask_nm_0.dds не требуется. Шейдерные вспомогательные файлы должны находиться рядом с шейдерами соответствующего бэкенда.

На R4 при включённом постпроцессе плоского стекла капли входят в его проход, а отдельный проход капель пропускается. Полусферическое стекло и выключенный постпроцесс стекла используют отдельный проход капель. Так капли не рисуются дважды. D3D11 сохраняет исходный расчёт процедурных нормалей конечными разностями; R2 использует экранные производные, чтобы уложиться в ограничения числа инструкций шейдера.

Диагностика ​

СимптомЧто проверить
Нет стеклаR4, r4_use_gasmask true, живой актор от первого лица, надетый предмет с glass_present = true и hud_gas_mask_avaliable = true.
Настройки костюма не применяютсяШлем со стеклом имеет приоритет, включая тип, состояние и оба флага доступности.
Нет капельr2_use_rain_drops true, R2/R4, подходящая экипировка и hud_rain_drops_avaliable = true; активный дождь, его плотность и коллизия укрытия сверху. Дайте каплям время накопиться.
Неожиданная форма стеклаЗадайте curved или flat выбранному предмету. Неизвестные значения, верхний регистр и опечатки выбирают flat с предупреждением в логе.
Трещины не соответствуют HP актораОни зависят от состояния выбранной экипировки. Проверьте повреждение/ремонт и use_condition в конфиге предмета.
anm_gasmask проигрывается, капли остаютсяДобавьте motion mark Left в реальное движение рук для состояния протирания. Проверьте, что callback относится к актору текущего вида.
Нет резервной анимацииОпределите секцию из [glass_mask], подключите её в system.ltx, добавьте anm_show и ресурс движения; проверьте занятость animator/предметов.
Протирание убирает капли, но оставляет трещиныЭто ожидаемо: оно очищает только накопление дождя, не ремонтирует экипировку и не убирает конденсат.
Капли исчезают при прекращении дождяЭто ожидаемо: остаточная влажность после дождя не моделируется.

Чек-лист проверки мода ​

  1. На R4 наденьте плоское стекло и включите оба эффекта. Проверьте полное, половинное и почти нулевое состояние предмета, затем ремонт и обратные переходы.
  2. При постоянном дожде плотности 1 подождите примерно 20 секунд снаружи. Войдите под укрытие с коллизией, проверьте постепенное высыхание, выйдите и проверьте накопление.
  3. Вызовите clear_gasmask, проверьте сброс на Left и последующее накопление. Проверьте анимацию предмета/устройства и отдельный резервный animator, включая прерывание до события очистки.
  4. На мокром стекле переключите texture и procedural: количество должно сохраниться. Выключите только стекло и проверьте, что капли работают.
  5. Наденьте стекло curved, проверьте исходные искажения, четыре ступени повреждения и оба режима капель. Наденьте шлем со стеклом поверх костюма со стеклом и проверьте приоритет.
  6. Снимите/замените выбранный предмет, перейдите к третьему лицу и обратно или выключите/включите капли: стекло должно начинать сухим. Остановите дождь и проверьте мгновенную очистку.
  7. Если мод поддерживает R2, проверьте оба режима капель на нём; стекло/трещины поддерживаются только на R4.

Точки входа в реализацию ​

src/xrGame/ArmorBase.cpp загружает параметры предмета; Actor.cpp выбирает экипировку и передаёт состояние/тип в ShaderParams. ActorInput.cpp, HudItem.cpp и HudAnimatorManager.cpp связывают действие протирания и метки с CActor::ClearMaskCB().

src/xrEngine/VisorRainDrops.cpp реализует накопление, проверку укрытий, очистку и сброс; владельцем состояния является IGame_Persistent::VisorRain. src/Include/xrRender/VisorGlassType.h определяет Flat и Curved, не создавая зависимости рендера от игровой реализации.

Проходы R4 находятся в src/Layers/xrRenderPC_R4/r4_rendertarget_phase_screen_postprocess.cpp, привязка стекла и выбор текстур — в BlenderGasMask.cpp. Консольные команды регистрируются в src/Layers/xrRender/xrRender_console.cpp. Константа шейдера visor_rain.x передаёт накопленное количество, а mask_control плоского шейдера — ступень повреждения и режим капель.

Опубликовано под лицензией MIT.