feat(script): evaluate additive FML expressions during Init
Docs Deploy / Build and Deploy MkDocs (push) Successful in 37s
Docs Deploy / Build and Deploy MkDocs (push) Successful in 37s
This commit is contained in:
5 files changed
+856
-104
No files matched your search
@@ -133,7 +133,7 @@ control word процесса.
|
||||
Лицензированный AutoDemo по-прежнему загружается с raw TMA anchor-ами
|
||||
`[(500.2857, 751.8217), (728.0, 449.0)]` и записями `[(500, 752, 0),
|
||||
(728, 449, 1)]`. Rust теперь также читает optional `.fml` sibling для каждого
|
||||
script base и поддерживает numeric literal assignments в первом `Init`.
|
||||
script base и поддерживает узкий набор атомарных формул в первом `Init`.
|
||||
Отсутствующий `.fml` не мешает пакету с одними `Handler(19)`; другие ошибки
|
||||
чтения распространяются как VFS errors.
|
||||
|
||||
@@ -144,9 +144,11 @@ script base и поддерживает numeric literal assignments в перв
|
||||
два доказанных действия: `Handler(19)` и formula assignment selector `-1` при
|
||||
source `-1`, нулевой глубине условий и корректных индексах. У `Handler(19)`
|
||||
control находится в `header_words[3]`, а `header_words[1]` — result-save
|
||||
reference; оба равны `0xffffffff` в поддержанной форме. У formula assignment
|
||||
`header_words[1]` — индекс целевой varset ячейки, `header_words[2]` — source,
|
||||
а индекс formula row занимает `header_words[6]`. Маппинг подтверждён
|
||||
reference; оба равны `0xffffffff` в поддержанной форме. В дисковом заголовке
|
||||
formula assignment `header_words[1]` — индекс целевой varset ячейки,
|
||||
`header_words[2]` — source, а индекс formula row занимает `header_words[6]`;
|
||||
индексы цели и формулы в native record находятся по смещениям `+0x08` и `+0x1c`
|
||||
соответственно. Маппинг подтверждён
|
||||
`ai.dll!FUN_10011b20` (RVA `0x11b20`) и исполнителем `FUN_10012020` (RVA
|
||||
`0x12020`), SHA-256 `c19cd6cd31cd2896f8c4ba0f0e700dd3408aec8182daaf4863d98a7d233a2abc`.
|
||||
`Handler(19)` (`FUN_1000aa38`, RVA `0xaa38`) использует references `0..2`;
|
||||
@@ -154,23 +156,58 @@ reference; оба равны `0xffffffff` в поддержанной форме
|
||||
|
||||
Formula table загружается из `<bundle-base>.fml`; native `FUN_100123b0`
|
||||
(RVA `0x123b0`) проверяет ordinal, compiler `FUN_100152a0` (RVA `0x152a0`)
|
||||
строит numeric literal node, а evaluator `FUN_10015b30` (RVA `0x15b30`)
|
||||
возвращает его raw `f32`. Target type `3` сохраняет эти bits; type `5` проходит
|
||||
через `FUN_10012c00` (RVA `0x12c00`) и `__ftol` (RVA `0x1df70`) к raw DWORD
|
||||
с усечением к нулю. Изолированный x86 oracle на оригинальном `ai.dll` и
|
||||
настоящих ресурсах подтвердил таблицы `tut1_pl2`/`scr_pl_1`/`scream` с
|
||||
строит числовые, переменные и операторные узлы, а evaluator `FUN_10015b30`
|
||||
(RVA `0x15b30`) в проверенных путях `+` и `-` считывает значения переменных и
|
||||
сохраняет результаты как `f32` при x87 control word `0x007f`. В GOG-сборке
|
||||
`ai.dll` с SHA-256
|
||||
`c19cd6cd31cd2896f8c4ba0f0e700dd3408aec8182daaf4863d98a7d233a2abc` поиск
|
||||
переменной через varset vtable slot `+0x10` ведёт на RVA `0x16ad0`: сравнение
|
||||
байтов точное, регистр учитывается, при повторах берётся первое объявление.
|
||||
Getter `FUN_10013190` (RVA `0x13190`) читает type `3` как `f32`, type `5` как
|
||||
беззнаковый `DWORD` и возвращает число через x87. Затем evaluator сохраняет
|
||||
его как `f32` до операции. Оператор `+`
|
||||
считает right+left, `-` — left-right; результат также сохраняется как `f32`.
|
||||
Target type `3` сохраняет эти bits; type `5` проходит через `FUN_10012c00`
|
||||
(RVA `0x12c00`) и `__ftol` (RVA `0x1df70`) к raw DWORD с усечением к нулю.
|
||||
Изолированный x86 oracle на оригинальном `ai.dll` и настоящих ресурсах
|
||||
подтвердил таблицы `tut1_pl2`/`scr_pl_1`/`scream` с
|
||||
26/5/149 строками и 15 присваиваний: кампанийные `df0..df3` и `Single.01`
|
||||
`dT8/dT9` получают `0`; `scream` задаёт `fDifficulty = 0.8f` и остальные
|
||||
проверенные DWORD `0, 0, 1, 10, 0, 100, 400, 2`.
|
||||
|
||||
Граница Rust остаётся узкой: ссылка должна вести на один digit-starting numeric
|
||||
token и типизированную `float`/`DWORD` ячейку. Неизвестные expression nodes,
|
||||
переменные, unary operators, составные выражения и source-copy ветвь
|
||||
`source != 0xffffffff` остаются явными ошибками; native source-copy переносит
|
||||
всю varset record, не только числовое значение. В preview package сохраняется,
|
||||
но `Unsupported` не применяет частичные writes; полная загрузка отклоняет весь
|
||||
новый мир и сохраняет предыдущие world/RNG. Это политика Rust, не правило
|
||||
оригинального dispatcher-а.
|
||||
Граница Rust остаётся узкой: один числовой токен либо ASCII-имя переменной,
|
||||
или два таких атома с одним бинарным `+`/`-`. Имя проверяется раньше числового
|
||||
преобразования, сравнивается с учётом регистра и выбирает первое совпадение;
|
||||
публичный `FormulaTable::evaluate_numeric_literal` принимает только числовые
|
||||
литералы. Временная копия значений начинается со значений по умолчанию и
|
||||
обновляется после каждого успешного действия `Init`, поэтому следующая формула
|
||||
видит предыдущие записи. Нет
|
||||
поддержки неизвестных операторов, унарных форм, третьего атома, отсутствующих
|
||||
или не-ASCII имён и source-copy ветви `source != 0xffffffff`; native source-copy
|
||||
переносит всю запись varset. Preview сохраняет package, но не применяет частичные
|
||||
writes; полный load отклоняет новый мир и сохраняет прежние world/RNG. Это
|
||||
политика ограниченного Rust resolver-а, а не правило оригинального dispatcher-а.
|
||||
|
||||
Ресурсные строки с переменными найдены в поздних событиях: `c1m3e.fml` row 19
|
||||
(`0.8 + fT`) вызывается из `Fort_Captured`, row 22
|
||||
(`dBuildingProtectHits - dT2`) — из `PBM_BUILDING_PROTECT_Start`, а `c1m4e.fml`
|
||||
row 0 (`fTemp + 0.00001`) — из `PBM_BUILDING_INF_CAPTURE_Start`. Декодирование
|
||||
этих `.scr` не показывает эти формулы в первом `Init`. Игнорируемая проверка
|
||||
читает настоящие `.fml` и `varset.var`, но вставляет строки в синтетический
|
||||
`Init`; она проверяет resolver, а не оригинальное исполнение. Одноразовый x86
|
||||
oracle на исходной GOG `ai.dll` с SHA-256
|
||||
`c19cd6cd31cd2896f8c4ba0f0e700dd3408aec8182daaf4863d98a7d233a2abc` проверил
|
||||
13 отдельных присваиваний: 9 контролируемых выражений и 4 вызова с настоящими
|
||||
строками `.fml` (`c1m3e` rows 19/22, `c1m4e` row 0 дважды подряд). В каждом векторе
|
||||
native harness записывал вычисленный `f32`, типизированное raw-слово и getter;
|
||||
scratch-проход через публичный Rust parser/resolver совпал со всеми 13
|
||||
векторами по `f32`-результату и raw-записи. Для native вызовов control word
|
||||
временно принудительно устанавливался в `0x007f`: 87 наблюдений сохранили
|
||||
`0x027f` на входе и после восстановления,
|
||||
а canary-проверки прошли. Менялись только varset-копии в памяти. Это
|
||||
подтверждает компиляцию формулы, локальное вычисление и typed writes для этих
|
||||
входов, но не запуск исходного поиска и обхода события `Init`, исполнение поздних
|
||||
событий или поведение живой миссии.
|
||||
|
||||
Лицензированный test загружает одну первую кампанийную миссию
|
||||
`CAMPAIGN/CAMPAIGN.00/Mission.01/data.tma` после literal writes; это не проход
|
||||
|
||||
Reference in new issue
Block a user