# Оригинальные кнопки и приказы юнитов

Дата реализации: 2026-10-28. Изменения подготовлены для общей схемы 30; публикацию и полный браузерный прогон выполняет интегратор.

## Панель

Визуально просмотрены оба пользовательских эталона из `uploads/images/2026-10-28_03-47-17-211_MSK/Буфер-1.png` и `uploads/images/2026-10-28_03-51-54-708_MSK/Буфер-1.png`. Их первые семь золотых значков совпадают с первой строкой `Civ3PTW/Art/interface/NormButtons.PCX`: Пропустить ход (Space), Ждать (W), Укрепиться (F), Распустить (D), Проложить маршрут (G), Разведывать (E), Охранять / ждать противника (Y). Неподписанный восьмой значок скриншота не добавлен: явный список пользователя содержит семь действий.

Прежняя панель использовала `Art/interface/NormButtons.pcx` базовой игры высотой 160 px и координаты из разных вариантов атласа. У PTW атлас высотой 320 px: Explore находится в ячейке (5,0), Sentry — (6,0), Build City — (0,2). Все семь стандартных кнопок теперь имеют фиксированный порядок, размер 32×32 и оригинальные состояния Normal/RollOver/Highlighted. Для B отдельно экспортирована показанная на эталоне тёплая красно-оранжевая ячейка (0,2) из оригинального RollOverButtons. Пиксели не перерисованы, оттенки не перекрашены. Прозрачность получена штатной маской ButtonAlpha.

Поселенец получает отдельную B над стандартным рядом. Присоединение к городу, рабочие задания и модернизация показываются своим дополнительным рядом только для подходящего юнита; базовый воин без доступного улучшения имеет ровно семь кнопок. Без выбора панель скрывается. Режим G, маршруты, снятие выбора на пустой клетке/Escape, Hold, FIFO Wait, клавиши в русской раскладке и завершение готового хода Space сохранены.

Экспортёр `scripts/prepare-native-orders.py` требует явного `--assets-dir`; общий manifest изменяется только при передаче `--manifest`. Это позволяет готовить и проверять изображения в `/tmp` без изменения общего dist во время чужого браузера.

## Общие правила D и Y

Обе команды проходят стандартные проверки стороны, владельца, фазы, незавершённых решений и завершённой партии. Доступность читается из родных Standard Actions: Disband = 0x08, Sentry = 0x40 первого байта `action_flags_hex`. Рабочий с заданием защищён от обоих приказов по записанному пользователем требованию.

`DISBAND {unitId}` удаляет юнит. UI сначала показывает подтверждение; строки «Распустить отряд?», «Вы уверены?» и варианты ответа взяты из оригинального `Conquests/Text/Script.txt`, секции DISBAND/DISBAND_NONCOM. До подтверждения/при отмене состояние не меняется. Общая команда остаётся применимой для ИИ без UI.

В своём городе щиты равны `min(floor(productionCost(unit)/4), max(0, productionCost(target)-city.shields))`. Используется общий расчёт реальной стоимости: поле PRTO.shield_cost_raw уже выражено в щитах (Воин=10, Рабочий=10, Племя=30); учитываются существующие параметры стоимости ИИ и ускоренного производства. Невольник с нулевой стоимостью не создаёт щитов. Обычное здание и юнит принимают вклад; Дворец, великие/малые чудеса, Богатство и части корабля — нет. Вклад помечается `restrictedShields`; продукция завершается в обычной экономической фазе. За пределами своего города юнит удаляется без щитов. Роспуск допускается при нулевом остатке движения, если юнит не занят работой.

`SENTRY {unitId}` сохраняет единственный авторитетный приказ `unit.orders={type:'sentry'}`. Отдельного boolean и новых обязательных полей у старых юнитов нет; `UNIT_CONTROL_MODEL` остаётся v1. Приказ требует оставшегося движения, сохраняет его и не даёт бонуса укрепления. Юнит исключается из активной очереди и счётчика незаданных приказов, поэтому не мешает завершить ход. Приказ переживает конец раунда, экспорт и загрузку. Ручной выбор/ACTIVATE_UNIT снимает ожидание, в том числе при нулевом движении.

После пересчёта текущей видимости каждой принятой команды `wakeSentries` проверяет соседние клетки штатной геометрии, включая обёртку. Пробуждение вызывается только наблюдаемым чужим юнитом рядом. Как в оригинальном Y, мирный чужой юнит тоже считается причиной: руководство отличает Y от Shift-Y (только вражеские). Исторические сведения, невидимые клетки и далёкие чужие юниты не используются. Сохранение отвергает sentry с работой, укреплением, неразрешённым флагом действия или дополнительными координатами маршрута. ИИ сохраняет выданный sentry и использует те же проверки и применение.

## Первичные свидетельства

* [Официальное руководство Civilization III Complete на Steam](https://cdn.akamai.steamstatic.com/steam/apps/3910/manuals/manual.pdf), печатные страницы 204–207: необратимость D, вклад в производство, Y при соседнем чужом/варварском юните, FIFO Wait и G. Руководство подтверждает поведение, но не задаёт точную долю щитов.
* Локальный `Conquests/Civ3Conquests.exe` проверен как PCG-вариант адресов из `civ_prog_objects.csv`, а не GOG-вариант. `Unit_disband=0x5BC010`: вызов City_can_take_outside_shields, затем Leader_get_unit_cost и деление на четыре (`0x5BC091..0x5BC099`), установка restricted-флага и ограничение запасов стоимостью текущего заказа (`0x5BC0A4..0x5BC0C8`).
* `City_can_take_outside_shields=0x4B50E0` для зданий делегирует в `0x569B60`: исключены centerOfEmpire, great/small wonder, wealth и `SpaceshipPart != -1`. `Leader_get_unit_cost=0x56A1C0` использует родную стоимость стороны и ускорение.
* `/tmp/civ3-worker-rate-reference/Civ3Conquests.h`: `UCV_Disband=8`, `UCV_Explore=32`, `UCV_Sentry=64`; источник именования — [Antal1987 C3CPatchFramework](https://github.com/Antal1987/C3CPatchFramework/blob/master/Info/Civ3Conquests.h). Имена функций и полей сверены с действительными инструкциями поставленного EXE.

## Проверка и границы

`tests/native-unit-orders.test.mjs` — 13 проверок общих правил, стоимости/целей, фаз, флагов, неизменности PRNG, сохранений, Wait/Hold и пробуждения без скрытой информации. `tests/native-unit-order-ui.test.mjs` — 7 проверок подтверждения/отмены D, отправки Y, физической русской раскладки, повторов клавиш, блокировки модальными окнами, Space и ручной активации. Все 20 прошли на актуальном src после интеграции.

`tests/test_native_order_assets.py` сравнивает каждый экспортированный RGBA-пиксель с оригинальным PCX и маской, точность B-crop, хеши, сохранность сторонних записей manifest и повторяемость экспорта. Проверка прошла. Синтаксис нового helper, UI и драйвера проверен. `tests/browser-native-orders.cjs` подготовлен для общего реального браузерного прогона интегратора; до появления отчёта `data/browser-native-orders-verification.json` его нельзя считать выполненным.

Не заявляется проверка точных внутренних Windows-таймингов Y, невидимых подразделений и влияния перевозок: эти механики не были воспроизведены в исходном приложении. Проверка видимости использует текущую поддерживаемую модель карты. Приказ Y рядом с уже наблюдаемым чужим юнитом пробуждается при штатной проверке наблюдений. Базовая функция стоимости ИИ/ускорения используется общая с производством; её отдельное соответствие всем сочетаниям оригинальных округлений не расширялось этой задачей.


## Итог интеграционной проверки v0.9.0

Опубликовано28.10.2026 в04:32 МСК, код `bd5314f4a3a8d843`. Соответствующий реальный Chromium-сценарий прошёл локально и на основном HTTPS-сайте. Проверяется выполнение действий и состояние, а не только наличие DOM-элементов. [Текущий публичный отчёт](data/browser-native-orders-verification.json). [Сверка138 опубликованных файлов](data/published-090-byte-audit.json) не нашла расхождений; восемь статических файлов независимых сервисов сохранены. Совпадение поведения Windows-оригинала за пределами явно перечисленных свидетельств не заявляется.
