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

Статистика ПДА ​

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

Эта статья описывает реализацию в текущей ветке и общих скриптах gamedata/scripts. Скрипты в gamedata_coc, gamedata_cs и gamedata_soc имеют собственные реализации; изменение общего скрипта само по себе не переносит функциональность в эти игровые наборы.

Подключение ​

pda_statistics.ltx загружается скриптом напрямую. Подключать его через system.ltx не требуется. Файл должен присутствовать в установленной модификации, даже если используются только стандартные изображения.

После перехода на эту реализацию начните новую игру: миграция статистики из прежнего формата сохранений не поддерживается. Для изменения скриптов и LTX перезапустите игру; для исправления зачёта убийств гранатой также нужна обновлённая xrGame.dll используемой конфигурации сборки.

Самый сильный убитый мутант ​

Учитывается мутант, убийство которого засчитано игроку. Сталкеры в этот показатель не входят. Скрипт сохраняет полное имя секции серверного ALife-объекта, например m_controller_normal или bloodsucker_custom.

Приоритет определяется следующим образом:

  1. Если в pda_statistics.ltx у секции есть rank, используется это значение.
  2. В остальных случаях используется rank() серверного объекта.
  3. Первый засчитанный мутант выбирается даже при ранге 0.
  4. Следующий заменяет текущего только при строго большем ранге. При равных значениях остаётся первый.

Это сравнение рангов, а не здоровья, нанесённого урона или количества убийств. Если до контролёра был убит мутант с большим или равным рангом, изображение в ПДА не изменится, хотя общий счётчик убийств увеличится.

Конфигурация ​

Записи находятся в gamedata/configs/misc/pda_statistics.ltx. Имя секции в этом файле должно точно совпадать с секцией мутанта в игровых конфигах.

КлючТипЕсли отсутствует
backСтрока: ID текстуры UI для фонаСтандартное изображение по классу и исходному ALife-рангу, если оно известно
iconСтрока: ID текстуры UI для изображения поверх фонаСтандартное изображение поверх фона, если оно известно
rankЦелое число от 0 до 4294967295Ранг серверного ALife-объекта

Отсутствующий ключ и пустое значение имеют разный смысл. icon = явно скрывает изображение поверх фона; отсутствие icon включает резервное отображение. То же правило действует для back. Известные стандартные профили обычно используют только back.

Неизвестный класс мутанта не вызывает аварийную остановку статистики. Он может стать самым сильным по рангу, но без настроенных текстур и известного резервного профиля его изображение будет пустым.

Настройки берутся из точной секции в pda_statistics.ltx. Наследование игровых секций мутантов в system.ltx не создаёт соответствующее наследование в файле статистики.

Пример нового мутанта ​

Допустим, в конфигурации существ уже есть мутант:

ini
[bloodsucker_custom]:bloodsucker_strong
; Здесь находятся остальные параметры нового мутанта.

Добавьте в pda_statistics.ltx:

ini
[bloodsucker_custom]
back = ui_inGame2_Krovosos_2
icon =
rank = 20

Пример использует существующую текстуру сильного кровососа и задаёт приоритет 20. Если нужен исходный ALife-ранг, удалите строку rank. Задание ранга здесь влияет только на выбор в статистике, а не на параметры мутанта в игре.

Собственная текстура ​

Создайте текстуру gamedata/textures/ui/my_mod_pda_mutants.dds и XML-описание gamedata/configs/ui/textures_descr/my_mod_pda_mutants.xml:

xml
<w>
    <file name="ui\my_mod_pda_mutants">
        <texture id="my_mod_pda_bloodsucker" x="0" y="0" width="393" height="200" />
    </file>
</w>

Размер и координаты должны соответствовать реальному изображению. 393 × 200 — размер стандартного фона мутанта. XML-файлы из ui/textures_descr загружаются при инициализации главного меню.

Затем замените значение в LTX:

ini
[bloodsucker_custom]
back = my_mod_pda_bloodsucker
icon =
rank = 20

В back и icon указывается ID из XML, а не путь к DDS. Используйте уникальный ID для своей модификации.

Любимое оружие ​

Для каждой полной секции создаётся отдельный счётчик. Например, wpn_ak74 и wpn_ak74_custom учитываются независимо, даже если используют один CLSID. Добавлять оружие в отдельный список статистики не нужно.

Любимое оружие выбирается по накопленной сумме положительных значений урона, переданных в set_best_weapon(amount). Это не число выстрелов и не число убийств. Нулевые и отрицательные значения пропускаются. Штатные обработчики смерти также вызывают служебное попадание с величиной 1, поэтому показатель не следует считать точным измерением потери здоровья целей.

Если два оружия набрали одинаковую сумму, остаётся текущее любимое оружие. Пока статистики нет, ПДА возвращает секцию wpn_knife.

Объединение вариантов через parent_section ​

Чтобы вариант с установленным прицелом учитывался вместе с базовым оружием, задайте parent_section в основной игровой секции варианта:

ini
[wpn_ak74_custom_scope]:wpn_ak74_custom
parent_section = wpn_ak74_custom

Попадания этим вариантом увеличат счётчик wpn_ak74_custom; ПДА также покажет базовую секцию. Без parent_section вариант учитывается отдельно.

Значение используется только если оно непустое и указанная секция существует в system_ini(). При пустом или неизвестном родителе сохраняется собственная секция оружия. Разрешается один уровень перенаправления: цепочка parent_section рекурсивно не обходится.

Унаследованный parent_section также читается из итоговой игровой секции. Если дочерний вариант должен иметь отдельный счётчик, задайте ему пустое значение:

ini
[wpn_ak74_custom_scope]:wpn_ak74_custom
parent_section =

Изображение оружия ​

ПДА получает полную секцию любимого оружия и использует существующие параметры иконки апгрейдов: upgr_icon_x, upgr_icon_y, upgr_icon_width, upgr_icon_height и необязательный upgr_icons_texture. В режиме 3D-иконок используются параметры визуала этой же секции.

Для 2D-отображения нужны все четыре параметра upgr_icon_*. Если используется parent_section, параметры отображения должны быть у выбранной родительской секции. Подробнее об атласах: Индивидуальные атласы иконок.

3D-иконка в статистике ​

В gamedata/configs/ui/pda_ranking.xml и его широкоформатном варианте pda_ranking_16.xml включите атрибут use_3d у существующего элемента:

xml
<favorite_weapon_icon x="775" y="625" width="230" height="80" alignment="c" align="c" use_3d="true"/>

use_3d="true" включает модель только для этого элемента; false оставляет 2D-иконку. Если атрибут отсутствует, используется общий параметр Enable3DIcons из [gameplay] в engine_external.ltx. Если аддон переопределяет XML ПДА, изменять нужно его активную версию разметки.

Модель выбирается из 3d_static_visual_name, а при отсутствии этого ключа — из visual. В выбранной секции оружия также поддерживаются:

ini
3d_static_visual_name = dynamics\weapons\wpn_p90\wpn_p90.ogf
3d_static_rotate = 0, 90, 0
3d_static_scale = 1.0
3d_static_offset = 0.0, 0.0

Пример предполагает, что модель P90 установлена. Поворот задаётся в градусах; масштаб умножает размер модели, автоматически вписанной в элемент UI; смещение задаётся относительно ширины и высоты элемента. Применяются def_hide_bones и def_show_bones; кости wpn_launcher и wpn_silencer скрываются для базового представления оружия. Для отдельной модели иконки задайте 3d_static_visual_name.

3D-отображение не требует координат в атласе апгрейдов. Если модель отсутствует или не подходит для скелетной иконки, используется 2D-иконка при наличии всех upgr_icon_*. Если нет ни модели, ни полного набора параметров 2D-иконки, поле остаётся пустым.

Для проверки типа активного предмета подсчёт использует game_object:is_weapon(): метод возвращает true для оружия и ручных гранат. Он не зависит от заполнения Lua-таблицы weapon_classes старым стартовым callback.

Гранаты: убийство и любимое оружие ​

Для зачёта убийства используется инициатор взрыва. Граната сохраняет ID бросившего; при детонации он передаётся в попадания от взрыва. Убийство мутанта гранатой игрока может увеличить общий счётчик и обновить самого сильного мутанта по обычным правилам сравнения рангов. Граната NPC не должна засчитывать убийство игроку.

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

Сохранения и изменения настроек ​

Сохраняются секция сильнейшего мутанта, выбранный ранг, резервный профиль изображения, секция любимого оружия и счётчики по секциям. Оба пути сериализации поддерживают новый набор данных. Число записей оружия хранится как u16, поэтому список больше не ограничен 255 секциями; предел формата — 65535 записей.

Изменение rank в LTX не пересчитывает уже сохранённый ранг сильнейшего мутанта. Изменение parent_section не объединяет накопленные ранее счётчики. Эти настройки применяются к последующим событиям; для проверки изменённого баланса используйте новую игру.

Проверка и типичные проблемы ​

НаблюдениеЧто проверить
Убитый мутант не заменил изображениеУбийство засчитано игроку; ранг строго больше уже сохранённого
Счётчик убийств растёт, но изображение пустоеТочное имя секции, значения back/icon, наличие XML и DDS; неизвестному классу нужна собственная настройка
Новое оружие отображается как базовоеСобственный или унаследованный parent_section
Оружие учитывается, но иконка не меняетсяВ 2D-режиме — полный набор upgr_icon_*; в 3D — активный XML, модель и её настройки
Граната не засчитывает убийство игрокуОбновлена xrGame.dll, гранату бросил игрок, цель погибла от её попадания
Гранатный урон увеличил счётчик другого оружияАктивный предмет изменился между броском и попаданием; это текущее ограничение
После загрузки сбилась статистикаСохранение создано уже с новым форматом; установлены согласованные скрипты

Для проверки создайте новую игру, нанесите разный суммарный урон базовым и модовым оружием, затем повторите с вариантом, у которого задан parent_section. Убейте мутантов с меньшим, равным и большим приоритетом, проверьте пустые текстуры и убийство гранатой. Сохранитесь и загрузитесь: выбранные секции и счётчики должны сохраниться.

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