bf966a4dbe
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
222 lines
23 KiB
Markdown
222 lines
23 KiB
Markdown
# AirDef — дальнобойные дроны и ПВО для Horizon
|
||
|
||
Мод для Horizon (Minecraft 26.3 на Rust): Шахед-136, Герань-3, Patriot и Гепард с 3D-моделями,
|
||
наведением ракет, слежением башен, падением сбитых дронов и эффектами взрывов.
|
||
|
||
Работает на **своём форке Horizon** (`horizon/`, ветка `airdef`): в нём добавлен API отрисовки
|
||
3D-моделей, которого нет в основном Horizon.
|
||
|
||

|
||
|
||
## Запуск
|
||
|
||
Пошаговый гайд для Windows и macOS (готовая сборка из релиза или сборка из исходников): [docs/INSTALL.md](docs/INSTALL.md).
|
||
|
||
Коротко, из исходников:
|
||
|
||
```bash
|
||
python3 tools/airdef.py all # скачать Horizon, наложить патчи форка, собрать игру и мод, установить мод
|
||
python3 tools/airdef.py play # запустить (аргументы игры — после: --world "Имя мира")
|
||
```
|
||
|
||
Для разработки: `./install.sh` перегенерирует модели (`tools/gen_models.py`, нужен Pillow) и звуки
|
||
(`tools/gen_sounds.py`, нужны numpy и ffmpeg), собирает и ставит мод. Сгенерированные файлы лежат в репозитории,
|
||
так что для обычной сборки нужен только Rust.
|
||
|
||
CI: `.gitea/workflows/build.yml` на каждый пуш собирает мод и игру для Linux, а пуш в `main` публикует релиз
|
||
`build-N`; `.gitea/workflows/desktop.yml` (запуск вручную с тегом релиза) собирает игру для macOS и Windows на
|
||
раннерах с метками `macos-latest` / `windows-latest` и дописывает архивы в релиз.
|
||
|
||
## Как играть
|
||
|
||
`/airdef give` выдаёт пульты. Все срабатывают на **ПКМ**.
|
||
|
||
| Предмет | Что делает |
|
||
|---|---|
|
||
| Целеуказатель | ставит или снимает цель на блоке под прицелом (до 512 блоков) |
|
||
| Пуск: Шахед-136 / Герань-3 / Ланцет-3 / Х-101 / Калибр / Х-22 / Циркон / Искандер-М / Кинжал | запускает дрон или ракету в точку под прицелом |
|
||
| Развернуть Patriot / Гепард / Панцирь-С1 / С-400 / С-500 | ставит комплекс на блок под прицелом, носом по взгляду |
|
||
| Свернуть ПВО | убирает ближайший комплекс у точки под прицелом |
|
||
|
||
**Командный пункт:** клавиша **N** или `/airdef menu`. В нём список комплексов: выбери комплекс и включай или выключай классы целей
|
||
(дроны, реактивные дроны, крылатые, сверхзвуковые, баллистика), есть сброс по умолчанию. Там же кнопки «Командный
|
||
пункт» (сетка), «Налёт…» и «Огонь, ремонт, эффекты…» (огонь ПВО, ремонт всех, эффекты, разрушения).
|
||
|
||
**Налёт (меню N → «Налёт: состав и запуск…»):** на первой странице состав — клик по типу листает число
|
||
(0, 1, 2, 3, 4, 6, 8, 10, 15, 20, 30, 40); на второй — готовый вариант («Рой Шахедов», «Массированный удар»,
|
||
«Баллистика», «Гиперзвук», «Орешник с прикрытием», «Подавление ПВО»), откуда (один сектор, два, со всех сторон,
|
||
волнами по типам), дальность старта, цели и **ПУСК**. Цели:
|
||
- *только объекты* — всё летит по отмеченным объектам (или по игроку, если их нет);
|
||
- *объекты и ПВО* — треть ударных средств бьёт по случайным комплексам;
|
||
- *умный противник* — планировщик знает, где стоят комплексы и что видят их РЛС: ведёт дроны и крылатые ракеты
|
||
маршрутами в обход зон поражения, низко, за рельефом и через мёртвые зоны; «Герберы» прилетают на 15 с раньше,
|
||
чтобы оттянуть ракеты; «Ланцеты» идут по Гепардам и Панцирям, Х-22/Циркон и часть баллистики — по дальнобойным
|
||
комплексам; всё остальное стартует со сдвигом так, чтобы прилететь одновременно.
|
||
|
||
После налёта приходит отчёт: сколько сбито и прорвалось, ракет ПВО потрачено, комплексов потеряно, урон объектам.
|
||
|
||
**Обнаружение.** РЛС видит цель не дальше, чем позволяют:
|
||
- её размер: дальность растёт как корень четвёртой степени из ЭПР — Х-101 и Ланцет видно примерно вдвое ближе, чем Х-22;
|
||
- радиогоризонт: низколетящую цель видно поздно (Шахед на 25 м — с ~250 м, баллистику — издалека);
|
||
- рельеф и лес: за холмом цель не видна (каждый комплекс строит свой горизонт по 48 лучам; рельеф известен в
|
||
прогруженных чанках);
|
||
- вблизи (24 м) видно всё.
|
||
|
||
Радар игрока и мониторы показывают только то, что держат РЛС; в сводке видно «Вне видимости РЛС: N».
|
||
Мёртвые зоны — ближе минимальной дальности ракет (Patriot 10 м, Панцирь 25, С-400 30, С-500 40).
|
||
|
||
**Повреждения.** Взрыв рядом с комплексом повреждает его: он хуже поворачивается, хуже видит и попадает,
|
||
дымит, ниже 35% горит. Уничтоженный остаётся горящим остовом, его боекомплект детонирует: чем больше ракет
|
||
оставалось, тем мощнее взрыв и дольше вторичные (у Гепарда рвутся снаряды); соседние комплексы тоже могут
|
||
пострадать. Объекты (Целеуказатель или `/airdef target here`) имеют прочность, она видна в сводке. Ремонт —
|
||
кнопкой в меню или `/airdef repair`.
|
||
|
||
**Монитор комплекса:** клавиша **K** листает комплексы по очереди, после последнего монитор скрывается. Слева вверху показано:
|
||
- состояние комплекса (поиск, сопровождение, доворот, захват, пуск, огонь, перезарядка, огонь запрещён);
|
||
- его РЛС: цели, по которым он работает, красным, остальные серым, текущая цель жёлтым;
|
||
- камера комплекса: настоящий вид мира из точки комплекса (второй рендер форка), с зумом на цель — тепловизор
|
||
при сопровождении, в поиске днём цвет, ночью ПНВ; рамка захвата, дальность, высота, скорость и пеленг.
|
||
|
||
**Командный пункт ПВО (сетка):** клавиша **J** (или `/airdef grid`, или кнопка в меню N) — на весь экран сетка
|
||
до 8 комплексов: у каждого состояние, РЛС, живая камера, прочность и боекомплект. Если комплексов больше, показываются
|
||
самые занятые (стреляют, держат захват, сопровождают, горят), раз в 2 секунды; комплекс с монитора K — всегда.
|
||
Повторное J закрывает.
|
||
|
||
**Повторы.** Каждый налёт записывается сам: с первой цели в небе до момента, когда небо 5 с чисто
|
||
(хранятся 3 последних). Меню N → «Повторы…» или клавиша **R**:
|
||
- **карта налёта** — вид сверху: комплексы и их зоны, объекты, треки целей (красные), ложных целей (серые) и
|
||
перехватчиков (жёлтые), сбития (x), прилёты, шкала времени с событиями; время идёт само, колесо мыши перематывает;
|
||
- **повтор момента** — клик по событию в списке: «призраки» дронов и ракет снова летят в мире, камера идёт за
|
||
целью, потом за перехватчиком (или смотрит из пушки, со стороны на прилёт), в момент сбития время замедляется;
|
||
- **полный повтор** — весь налёт, камера-режиссёр сама выбирает, за чем следить; колесо — скорость (×0.5–×16);
|
||
- **лучшие моменты** — нарезка до 8 самых интересных событий (перехват баллистики и гиперзвука, поражения
|
||
объектов, потерянные комплексы, разделение «Орешника») с титрами и замедлением; колесо листает моменты.
|
||
|
||
Повтор идёт на весь экран с леттербоксом; звук слышен так, как его слышала бы камера. R — выход.
|
||
|
||
Клавиши N, K, J и R можно переназначить в «Настройки → Моды».
|
||
|
||
Команды:
|
||
- `/airdef wave <тип> [кол-во] [дальность]` — налёт на ближайшую цель. Типы: `shahed`, `geran3`, `lancet`, `gerbera`, `kh101`, `kalibr`, `kh22`, `zircon`, `iskander`, `kinzhal`, `oreshnik` и `mix` (комбинированный удар двумя секторами: «Герберы», шахеды, Герани-3, Х-101, «Калибры», Х-22, Циркон, «Искандер», «Кинжал», при 30+ — «Орешник»);
|
||
- `/airdef replay [map|full|reel|stop]` — повтор последнего налёта;
|
||
- `/airdef raid` — налёт, настроенный в меню; `/airdef target here` — отметить объект под ногами; `/airdef repair` — ремонт;
|
||
- `/airdef roles` — показать, по каким классам целей работает каждый комплекс; `/airdef roles <patriot|gepard|pantsir|s400|s500|all> <классы|default>` — задать (классы через запятую: `drone`, `jet`, `cruise`, `supersonic`, `ballistic` или `all`), например `/airdef roles s400 cruise,ballistic`;
|
||
- `/airdef deploy <patriot|gepard|pantsir|s400|s500>` — поставить комплекс в 8 блоках перед собой;
|
||
- `/airdef hold on|off` — запретить или разрешить ПВО огонь, удобно для съёмки ударов;
|
||
- `/airdef damage on|off` — разрушать ли ландшафт взрывами (через TNT, нужны читы);
|
||
- `/airdef shader on|off` — шейдерные эффекты;
|
||
- `/airdef clear` — убрать дроны и ракеты;
|
||
- `/airdef targets clear` — снять все цели;
|
||
- `/airdef stats` — сводка.
|
||
|
||
Интерфейс:
|
||
- **сверху справа — сводка:** тревога, цели по типам, ближайшая угроза (дальность, высота, скорость), перехватчики в воздухе, по каждому комплексу боезапас или перезарядка, его текущая цель и число сбитых, итоговый счёт;
|
||
- **снизу справа — радар на 500 м** со сканирующим лучом. Отметки гаснут после прохода луча. Красное — цели (с хвостом по курсу), жёлтое — ракеты, синее — ПВО с кругами дальности, крест — цели удара.
|
||
|
||
Комплексы ПВО и цели сохраняются между сессиями.
|
||
|
||
## Техника
|
||
|
||
| Дрон / ракета | Поведение |
|
||
|---|---|
|
||
| Шахед-136 | 43 км/ч в игре, 45 м над целью, 18 м над рельефом, крен в поворотах, пикирует, винт крутится |
|
||
| Герань-3 | реактивный, 115 км/ч, факел из сопла |
|
||
| Ланцет-3 | Х-образные крылья, низко (25 м), манёвренный, его труднее сбить |
|
||
| Гербера | ложная цель из пенопласта, без боевой части: отвлекает ракеты ПВО |
|
||
| Х-101 | крылатая ракета, 170 км/ч, огибает рельеф на 12 м, мощная боевая часть |
|
||
| Калибр | крылатая ракета, 150 км/ч, огибает рельеф на 15 м |
|
||
| Х-22 | сверхзвуковая, 290 км/ч, идёт на 140 м и круто пикирует издалека |
|
||
| Циркон | гиперзвуковая, 400 км/ч, её трудно сбить |
|
||
| Искандер-М | баллистическая: стартует за 1 км, дуга с апогеем ~250 м, на конечном участке доворачивает на цель |
|
||
| Кинжал | аэробаллистическая, 540 км/ч, стартует за 1,5 км; реально сбивает только С-500 |
|
||
| Орешник | баллистическая средней дальности: стартует за 2,6 км, над целью разделяется на 6 блоков, каждый — на 6 светящихся суббоеприпасов («огненный дождь», ~5 с); С-500 успевает сбить лишь несколько |
|
||
|
||
Сила взрыва зависит от боевой части: ложные цели — хлопок, дроны — средний взрыв, Шахед — сильный, Х-101/Х-22/Калибр —
|
||
тяжёлый (двойной удар, столб земли, тряска до 160 м), Искандер/Кинжал — самый мощный (огненный шар 13 м, тряска до 240 м);
|
||
у каждого уровня свой звук.
|
||
|
||
| ПВО | Вооружение | Дальность |
|
||
|---|---|---|
|
||
| Patriot | 4 × PAC-3, пусковая разворачивается на цель | 10–300 |
|
||
| Гепард | 2 × 35 мм, башня и стволы со слежением и упреждением, 160 очередей | 90 (слежение с 130) |
|
||
| Панцирь-С1 | 12 × 57Э6 и 2 × 30 мм; модуль поворачивается, пакеты и стволы поднимаются | ракеты 25–150, пушки 60 |
|
||
| С-400 | 4 × 48Н6, вертикальный холодный старт, РЛС обзора на прицепе | 30–480 |
|
||
| С-500 | 4 × 77Н6, холодный старт, самые быстрые ракеты | 40–700 |
|
||
|
||
**Согласование огня.** Комплексы делят цели между собой: на обычную цель идёт одна ракета, на баллистическую две,
|
||
пушки расходятся по разным целям. Первыми бьют по самым опасным (быстрым и тяжёлым) целям, при этом ложные
|
||
«Герберы» выглядят для них как настоящие. Шанс поражения падает, если цель быстрее перехватчика.
|
||
|
||
**Роли по умолчанию** (в сводке в квадратных скобках: Д — дроны, Г — реактивные, К — крылатые, С — сверхзвуковые,
|
||
Б — баллистика): Гепард ДГК, Панцирь ДГКС, Patriot ГКСБ, С-400 ГКСБ, С-500 СБ. Сбитый дрон падает с остатком скорости, и его боевая часть
|
||
может сдетонировать на земле.
|
||
|
||
## Звук
|
||
|
||
Все звуки синтезированы (`tools/gen_sounds.py`: шум, тоны, фильтры и эхо на numpy, кодирует ffmpeg), сэмплов нет.
|
||
У каждого объекта свой звук и своя дальность слышимости (`attenuation_distance` в `sounds.json`):
|
||
- **двигатели:** двухтактный мопед шахеда (220 м), турбина Герани-3, электромотор Ланцета, тяжёлый рёв крылатых ракет (320 м),
|
||
ракетный рёв Х-22, Циркона и перехватчиков, нарастающий визг падающей баллистики и её ударная волна (700–900 м);
|
||
- **пуски:** хлопок и рвущийся рёв Patriot, свистящий старт Панциря, глухой газовый выброс и затем огромный рёв С-400,
|
||
у С-500 ещё ниже и дольше (до 1 км);
|
||
- **пушки:** тяжёлые 35-мм очереди Гепарда и частые 30-мм Панциря;
|
||
- **взрывы:** хлопок, суббас, рокот и треск обломков с длинным эхом, у разных калибров по-разному (до 900 м).
|
||
|
||
## Эффекты
|
||
|
||
Мод передаёт движку шейдер пост-обработки (`airdef-mod/shaders/effects.wgsl`):
|
||
- **объёмный огненный шар:** шум, «прошитый» лучом камеры, с переходом раскалённое ядро → пламя → чёрный дым, который поднимается и рассеивается;
|
||
- **вспышка** с ореолом и засветкой всего кадра;
|
||
- **ударная волна**, искажающая картинку за собой;
|
||
- **тепловое марево** над огнём;
|
||
- **свечение** факелов ракет, дульных вспышек, красных трассеров и маркеров цели;
|
||
- **освещение от огня:** взрывы, факелы и трассеры подсвечивают землю и технику, ночью намного сильнее.
|
||
|
||
У Гепарда и Панциря каждый снаряд — летящий красный трассер.
|
||
|
||
Всё размещено в мире и скрывается за тем, что стоит перед ним (по глубине сцены). Выключить: `/airdef shader off`.
|
||
|
||

|
||

|
||
|
||
## Устройство
|
||
|
||
```
|
||
HORIZON_COMMIT коммит апстрима Horizon, на который накладываются патчи
|
||
horizon-patches/ изменения форка (git format-patch); tools/airdef.py fork собирает из них horizon/
|
||
horizon/ форк (не в репозитории; ветка airdef). Что в нём меняется:
|
||
crates/horizon-mod-sdk/wit/horizon.wit render.set-models, spawn-particles, play-sound,
|
||
query-ground / ground
|
||
crates/horizon-mods/src/runtime.rs хост этих функций
|
||
crates/horizon-client/src/game/mod_models.rs интерполяция и отрисовка моделей, частицы
|
||
crates/horizon-client/src/gfx/mod_post.rs пост-проход мода: render.set-post / set-params
|
||
airdef-mod/ сам мод: Rust → WebAssembly
|
||
src/sim.rs симуляция: дроны, ракеты, ПВО, эффекты (20 тиков/с)
|
||
src/lib.rs предметы, команды, сохранение, передача в движок
|
||
src/panel.rs сводка, src/radar.rs — радар, src/monitor.rs — монитор комплекса
|
||
assets/airdef/sounds звуки (генерирует tools/gen_sounds.py)
|
||
shaders/effects.wgsl шейдер взрывов и свечения
|
||
assets/, data/ модели, текстуры, предметы (генерирует tools/gen_models.py)
|
||
tools/gen_models.py генератор моделей и текстур
|
||
legacy/ первая версия: датапак на командах и контент-мод
|
||
run-home/ тестовая игровая папка (для проверок через horizon-ctl)
|
||
```
|
||
|
||
Как рисуются модели. Мод раз в тик отдаёт список объектов: блок-модель, позиция, кватернион и масштаб.
|
||
Движок держит для каждого id две последние позы и в каждом кадре рисует объект между ними:
|
||
- позиция интерполируется линейно, поворот — через slerp;
|
||
- освещение учитывает поворот модели;
|
||
- `glow` даёт полную яркость (пламя, вспышки).
|
||
|
||
Модели — обычные блочные JSON-модели, по одной на часть: корпус, винт, башня, стволы. Их генерирует
|
||
`tools/gen_models.py`. Координаты элементов должны быть в пределах −16..32, иначе Horizon отбросит модель.
|
||
|
||
Рельеф мод узнаёт через `render.query-ground`: присылает колонки, а движок отвечает высотой по карте
|
||
высот на следующем тике.
|
||
|
||
## Известные ограничения
|
||
|
||
- Мод клиентский: дроны и ПВО видит только тот, у кого он стоит. Мультиплеер не поддерживается.
|
||
- Окно Horizon на macOS не рисует кадры, пока оно перекрыто другими окнами (это поведение движка).
|
||
- Шейдер работает, только если не включён шейдер-пак Horizon (они взаимоисключающие).
|