aboutsummaryrefslogtreecommitdiff
path: root/docs/tomes/06-behavior.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/tomes/06-behavior.md')
-rw-r--r--docs/tomes/06-behavior.md82
1 files changed, 66 insertions, 16 deletions
diff --git a/docs/tomes/06-behavior.md b/docs/tomes/06-behavior.md
index 7dc6d66..bcb7320 100644
--- a/docs/tomes/06-behavior.md
+++ b/docs/tomes/06-behavior.md
@@ -755,27 +755,77 @@ NDP, а `FUN_1000a100` (RVA `0xa100`) добавляет их в общую та
`FUN_100198e0` (RVA `0x198e0`) суммирует успешные запросы IID `0x204` с selector
`0xe00`. В парной `Control.dll` выше `FUN_1002bb40` (RVA `0x2bb40`) для типа
`0x1a` вызывает selector `0x300`, описанный в этом разделе. Затем Behavior query
-`0x1002` (RVA `0xa490`) умножает полученную сумму на текущее значение block
-`+0x820`, поле `+0x58` `Transfer_Ore_OffBoard` (имя — RVA `0x22e20`, default
-5.0 — RVA `0x22d90`; config selector 2 загружает блок через RVA `0x0a1a0`).
-Отдельный query `0x1005` (RVA `0xa490`) возвращает поле `+0x60`
-`Transfer_Power_Out` (имя — RVA `0x22e20`, default 100.0 — RVA `0x22d90`;
-setter — RVA `0xaa40`). В полной загрузке FParkan начальные provider-строки
-хранятся вместе с таблицей Control конкретного `ObjectHandle`. Запрос
-`0xe00` проходит по ключу устройства в этот снимок и пока поддержан только для
-текущего descriptor tag `26` с factory tag `26`; для него результат равен
+`0x1002` (RVA `0xa490`) умножает полученную сумму на поле `+0x58`
+`Transfer_Ore_OffBoard` блока `+0x820`; отдельный selector `0x1005` возвращает
+`+0x60` `Transfer_Power_Out`. Имена регистрируются в RVA `0x22e20`, а конструктор
+RVA `0x22d90` задаёт начальные значения 5.0 и 100.0. Восемнадцать точных class
+codes выбирают записи `.var` из `behpsp.res`: например, `0x80000004` выбирает
+`prof_mine.var`, `0x80000002` — `prof_generator.var`, а три кода bunker-класса
+выбирают `prof_bunker.var`. Таблицу этих соответствий задаёт mapper
+`FUN_10008a80` (RVA `0x8a80`) в Behavior.dll SHA-256
+`ddfbdbde07832358fe6e35e01c8dba9b58e7313789498b6049ed51d4ed9baf99`.
+
+Установленные соответствия mapper-а:
+
+| Class flags | Запись `behpsp.res` |
+| --- | --- |
+| `0x80000004` | `prof_mine.var` |
+| `0x80000008` | `prof_storage.var` |
+| `0x80000002` | `prof_generator.var` |
+| `0x80000010` | `prof_plant.var` |
+| `0x80000040` | `prof_angar.var` |
+| `0x80000200` | `prof_mtp.var` |
+| `0x80000400` | `prof_institute.var` |
+| `0x80010000`, `0x80020000`, `0x80040000` | `prof_bunker.var` |
+| `0x80100000`, `0x80200000` | `prof_tower.var` |
+| `0x01002000` | `prof_trn.var` |
+| `0x01004000` | `prof_bld.var` |
+| `0x01008000` | `prof_war.var` |
+| `0x01010000` | `prof_hq.var` |
+| `0x01020000` | `prof_hero.var` |
+| `0x20000000` | `prof_animal.var` |
+
+У бинарной строки `.var` есть имя, индекс типа, размер и две области данных.
+Native parser RVA `0x49fa0` читает запись, binder RVA `0x49090` связывает её с
+зарегистрированным полем, а apply-loop RVA `0x49170` копирует в поле именно
+вторую область. В профиле используются точные C-string имена
+`Transfer_Ore_OffBoard` и `Transfer_Power_Out`; регистр учитывается, первый
+совпавший ряд побеждает. Rust ограничивает чтение исходной записи NRes её
+границами и сохраняет значения как исходные 32-битные слова у соответствующего
+`ObjectHandle`. Разбор профиля для полной миссии завершается до создания нового
+мира: отсутствие или повреждение профиля известного класса прерывает загрузку,
+не подменяя предыдущую миссию. Если mapper не знает class code, остаются
+конструкторские значения 5.0 и 100.0; это не догадка о неизвестном профиле.
+Preview не загружает профили.
+
+При вычислении `0x1002` native `FUN_100186b0` (RVA `0x186b0`) добавляет в список
+только текущие Control descriptor-и tag `26`, после чего
+`FUN_100198e0` (RVA `0x198e0`) суммирует их успешные `0xe00` запросы. FParkan
+делает то же для загруженной таблицы в её исходном порядке и затем умножает
+сумму на профильный `Transfer_Ore_OffBoard`. Записи tag `5`, `10` и `21` в общей
+таблице в этот список не попадают. Запрос `0xe00` проходит по ключу устройства
+в исходную provider-таблицу и пока поддержан только для текущего descriptor
+tag `26` с factory tag `26`; для него результат равен
`provider * fixed_words[11] * multiplier`. Лицензированный тест загружает
-оригинальные CTL/NDP и подтверждает, что tag-26 запись с ключом `2` читает
-начальное значение строки `1.0`. Это проверка начального состояния после
-конструкторов, не результат живого игрового тика.
+оригинальные CTL/NDP и полную миссию с этим Unit DAT. В установленном
+`min_l_n1.dat` class word равен `0x80000004`, поэтому исходный прогон выбирает
+`prof_mine.var`. Для проверки другого отображения второй прогон оставляет тот же
+TMA и компоненты, но во временном VFS заменяет слово класса заголовка DAT на
+`0x80000002`; это тестовая подмена, а не содержимое лицензированного файла.
+Профиль mine даёт `Transfer_Power_Out` 0.0 и `Transfer_Ore_OffBoard` 1.0;
+оригинальный профиль генератора — 10.0 и 0.0 соответственно. Для исходного
+tag-26 ряда получается `1.0` provider × `1.0` coefficient × `1.0` multiplier;
+профиль mine умножает эту сумму на `1.0`, поэтому selector `0x1002` возвращает
+`1.0`. Эти запросы используют начальные provider-значения после конструкторов,
+а не результаты живого игрового тика.
Поведение provider-строк меняется и после загрузки: например,
`Control.dll!FUN_10010f30` (RVA `0x10f30`) обновляет и ограничивает текущее
значение, а соседние процедуры распространяют его между связанными строками.
-Эти изменения пока не отражены в Rust-снимке. Поэтому `0xe00` не является
-исполнением всего Control tick-а, а Behavior query `0x1002` не подключён к
-этому API; его множитель `Transfer_Ore_OffBoard` требует отдельного источника
-текущей конфигурации.
+Эти изменения пока не отражены в Rust-снимке. Поэтому запрос Control `0xe00` и
+Behavior selector `0x1002`, который его суммирует, используют исходное состояние
+полной загрузки. Selector `0x1005` прямо возвращает загруженную ставку профиля.
+Ни один из них пока не исполняет Control tick или последующие изменения профиля.
На x87 control word `0x007f` каждое умножение округляет мантиссу до 24 бит,
но промежуточная степень может выйти за диапазон `f32` и вернуться в него при