feat(runtime): initialize mission ore properties
Docs Deploy / Build and Deploy MkDocs (push) Successful in 1m9s
Docs Deploy / Build and Deploy MkDocs (push) Successful in 1m9s
This commit is contained in:
5 files changed
+379
-4
No files matched your search
@@ -169,6 +169,42 @@ Behavior (`Behavior.dll`, RVA `0x3600`) вызывает `World3D!stdGetGameMode
|
||||
с реальными интерфейсами ArealMap, нужными `FUN_10019e80`; полный Behavior tick
|
||||
flow и общий dispatcher событий также остаются открытыми.
|
||||
|
||||
Начальные свойства `CurrentOre`/`MaximumOre` восстановлены отдельно от
|
||||
регулярного обмена. В проверенных `Behavior.dll` (SHA-256
|
||||
`ddfbdbde07832358fe6e35e01c8dba9b58e7313789498b6049ed51d4ed9baf99`) RVA
|
||||
`0x8790` выбирает начальные значения по class word, `0xb110` регистрирует
|
||||
дескрипторы кодов 4/5, `0xb470` пишет только код 5, а `0xb5b0` читает код 4
|
||||
как дополнительное слово и код 5 как основное. `MisLoad.dll` (SHA-256
|
||||
`c607762bb67db14ca530927c8e1347339b62b0a163ac90c708ee83142292e2bf`) RVA
|
||||
`0x40b0` выбирает первое свойство TMA с точным именем `CurrentOre` и передаёт
|
||||
его `raw_value[1]`; setter сохраняет биты напрямую. В AutoDemo snapshot на этих
|
||||
входах было восемь объектов Unit DAT, у всех raw `CurrentOre` равен нулю;
|
||||
четыре объекта класса `0x01008000` не вошли в distributor, но остались среди
|
||||
инициализированных Rust-состояний. Поэтому путь нулевого значения наблюдался
|
||||
наживую, но ненулевое TMA-значение в живой миссии пока не проверено.
|
||||
|
||||
Синтетический x86 oracle вызвал `Behavior.dll!FUN_10008790` напрямую для классов
|
||||
`0x80000004`, `0x80000008`, `0x01002000`, `0x01004000` и `0x01008000`; перед
|
||||
вызовом в записи были значения `CurrentOre=123` и `MaximumOre=-1`, так что
|
||||
проверено их перезаписывание. Тест выставляет `a64=1`, чтобы отключить отложенный
|
||||
side effect обёртки setter-а. Это подтверждает ветви initializer-а, но не весь
|
||||
путь его запуска и связи с остальными фазами объекта. Другой изолированный x86
|
||||
oracle проверяет ненулевое raw-слово `CurrentOre`, только чтение `MaximumOre` и
|
||||
перестановку строк дескрипторов на синтетических записях свойств.
|
||||
|
||||
Не проверен селектор 4 для внешнего config-like ресурса: в наблюдавшемся
|
||||
AutoDemo его вызова нет, а установленный `Behavior.ini` не содержит
|
||||
`Mine_MaxOre`, `Storage_MaxOre` или `Transport_MaxOre`. Поэтому Rust пока
|
||||
воспроизводит доказанные class defaults (500, 4000 и 2000) и не заявляет
|
||||
поддержку конфигурационного переопределения. Отдельно не доказано, что каждый
|
||||
Unit DAT создаёт тот же Behavior-компонент во всех host factory paths. Rust
|
||||
ограничивает новую запись полными TMA-объектами с Unit DAT; preview, прямые
|
||||
prototype roots без Unit DAT и отложенные spawn после исходной загрузки вне
|
||||
этой модели. Путь в `ArealMap.dll` (SHA-256
|
||||
`a25f9254ebb339d70e2e07c8121950191e9584ca0858d8e9c2e2b6c671edf6ea`) к
|
||||
`CreateObject` по RVA `0x14fd0`/`0x15290` показывает выбор World3D class 3 или 4
|
||||
по старшему биту, но не всю цепочку их Behavior attachment.
|
||||
|
||||
Для `Handler(30)` отдельно подтверждены обратный вызов `iron3d.dll` RVA
|
||||
`0x611d0` (SHA-256 `d1dc4ea8535e2069b0a05c9e8be2724dd438ba44cca7a83007d8b2e50f9e35fa`),
|
||||
начальные поля IGame и проверки режима/состояния. Обработчик выбора миссии
|
||||
|
||||
@@ -92,3 +92,15 @@ slot `+0x40` в путь выбора AI в Behavior. Поэтому Rust сох
|
||||
|
||||
`Property` состоит из четырёх raw `u32` и имени. Typed views разрешены только
|
||||
для доказанных property names и consumers.
|
||||
|
||||
Для свойств объекта `MisLoad.dll!FUN_10003ab0` (RVA `0x3ab0`) переставляет
|
||||
дисковые слова в runtime-запись, а `FUN_100040b0` (RVA `0x40b0`) проходит её
|
||||
таблицу в порядке runtime-дескрипторов. Поиск имени учитывает длину и байты с
|
||||
точным регистром и использует первое совпадение. В подтверждённом пути
|
||||
дисковое `raw_value[1]` становится первым DWORD аргумента setter-а, поэтому
|
||||
значение передаётся как биты, без промежуточного float-преобразования.
|
||||
Например, Behavior регистрирует `CurrentOre` под кодом `5`; его setter кладёт
|
||||
полученные биты в основное слово свойства `0x02000100`. `MaximumOre` с кодом
|
||||
`4` читает дополнительное слово той же записи, а setter этого дескриптора
|
||||
ничего не меняет. Подтверждение классов и native getter/setter находится в
|
||||
[главе о Behavior](../tomes/06-behavior.md#начальные-свойства-запасов-руды).
|
||||
@@ -255,6 +255,56 @@ Rust хранит этот небольшой начальный список с
|
||||
опирается на уже созданный `ObjectHandle`. Регулярный обмен ресурсами пока
|
||||
остаётся отдельным этапом, потому что для него нужны интерфейсы игровых объектов.
|
||||
|
||||
### Начальные свойства запасов руды
|
||||
|
||||
Behavior хранит `CurrentOre` и `MaximumOre` в одной записи свойства с ключом
|
||||
`0x02000100`: текущее количество лежит в основном float-слове, предел — в
|
||||
дополнительном DWORD. В TMA это не означает, что оба значения свободно задаются
|
||||
файлом. При загрузке `MisLoad.dll` ищет первое свойство с точным, чувствительным
|
||||
к регистру совпадением имени и передаёт его второе raw-слово в setter. В
|
||||
Behavior дескриптор `CurrentOre` записывает это слово в основное значение;
|
||||
дескриптор `MaximumOre` читает дополнительное слово, но его setter ничего не
|
||||
меняет.
|
||||
|
||||
Оба дескриптора регистрируются как коды `4` и `5`. Это коды обработчика, а не
|
||||
позиции в таблице дескрипторов: исходная DLL корректно работает и после
|
||||
перестановки строк, потому что callback выбирает обработчик по коду строки.
|
||||
Поэтому начальное состояние можно описать так, сохраняя биты без пересчёта
|
||||
через `float`:
|
||||
|
||||
```text
|
||||
current = first_exact("CurrentOre").raw_value[1] ?? class_default_current
|
||||
maximum = class_default_maximum
|
||||
```
|
||||
|
||||
Класс задаёт значения по умолчанию в Behavior RVA `0x8790`:
|
||||
|
||||
| Слово класса | `CurrentOre` | `MaximumOre` |
|
||||
| --- | ---: | ---: |
|
||||
| `0x80000004` | 0 | 500 |
|
||||
| `0x80000008` | 0 | 4000 |
|
||||
| `0x01002000` | 0 | 2000 |
|
||||
| `0x01004000` | 2000 | 2000 |
|
||||
| прочие слова в этой ветви | 0 | 0 |
|
||||
|
||||
Вызов RVA `0x8790` на синтетической структуре подтвердил эти значения для
|
||||
классов таблицы, включая `0x01008000`; он проверяет тело native initializer-а,
|
||||
но не его полный жизненный цикл в игре.
|
||||
|
||||
В полной загрузке Rust сохраняет эти два raw-значения рядом с исходным TMA ID
|
||||
и `ObjectHandle` каждого объекта с Unit DAT; список участников распределителя
|
||||
для этого не требуется. Это важно для объектов, у которых есть компонент
|
||||
Behavior, но нет членства в ресурсном distributor. Preview намеренно не создаёт
|
||||
начальное состояние. Лицензированная AutoDemo показывает восемь объектов с
|
||||
Unit DAT, включая объекты класса `0x01008000` вне списков distributor; в этом
|
||||
снимке TMA `CurrentOre` равен нулю у всех восьми. Нативный x86 oracle отдельно
|
||||
проверяет ненулевое raw-слово, чтение предела, отсутствие записи в `MaximumOre`
|
||||
и переставленные строки дескрипторов.
|
||||
|
||||
Эта модель покрывает именно начальную загрузку полных TMA-объектов. Она не
|
||||
утверждает, что уже восстановлены все пути создания Behavior, отложенное
|
||||
создание объектов или внешняя подмена class defaults конфигурацией.
|
||||
|
||||
### Регулярная передача ресурсов
|
||||
|
||||
Resource Distributor работает со списком зарегистрированных объектов. За один
|
||||
|
||||
Reference in new issue
Block a user