Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8a12225ba1 | |||
| 4bab572293 | |||
| f43fa5ee66 | |||
| 336ae9f7cc | |||
| 5f8bff31b9 | |||
| 3ced60e84f | |||
| 6f3fc644bc | |||
| 9075717872 | |||
| e3148bf458 | |||
| d0b9498aaf | |||
| 8065f2225c | |||
| a8551b5c28 | |||
| f443f0a94a | |||
| e33daac636 | |||
| 661c852bbf | |||
| 428713d4bc | |||
| 5839da129a | |||
| ab4a7899af | |||
| 65dd84646a | |||
| ed2db8523b | |||
| 67a2a523b4 | |||
| a806635681 | |||
| 0092ec64a9 | |||
| e08fc65ac8 | |||
| 90379f6e17 | |||
| bb35975642 | |||
| f2838a8f08 | |||
| c42d97af08 | |||
| 6efec3e546 | |||
| d3359f4b39 | |||
| a2f31c831c |
@@ -5,7 +5,9 @@
|
||||
name: build
|
||||
|
||||
on:
|
||||
# Branches only: the release's own tag (build-N) mustn't start another build.
|
||||
push:
|
||||
branches: ['**']
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
@@ -22,14 +24,17 @@ jobs:
|
||||
run: |
|
||||
curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --target wasm32-unknown-unknown
|
||||
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
||||
# Инструмент упаковки (cargo-horizon-mod без пробного запуска) — единственное, что стоит кэшировать.
|
||||
- uses: actions/cache@v3
|
||||
continue-on-error: true
|
||||
with:
|
||||
path: ~/.cargo/bin/cargo-horizon-mod
|
||||
key: tool-${{ hashFiles('HORIZON_COMMIT', 'horizon-patches/*') }}
|
||||
# Без actions/cache: кэш-сервер раннера из контейнеров задач недоступен — восстановление
|
||||
# падало по таймауту, а сохранение вешало «Complete job» на пару минут. Инструмент собирается заново.
|
||||
- name: Форк Horizon
|
||||
run: nice -n 19 python3 tools/airdef.py fork
|
||||
# Чистая симуляция тестируется нативно (хост-таргет раннера, без WASM): регрессии из sim/regress.rs
|
||||
# и сценарии tests/scenarios.rs (NaN, налёт кончается, ТЗМ не зависают). Нужен форк: SDK подключён путём.
|
||||
- name: Тесты мода
|
||||
working-directory: airdef-mod
|
||||
run: |
|
||||
HOST=$(rustc -vV | sed -n 's/^host: //p')
|
||||
nice -n 19 cargo test --target "$HOST"
|
||||
- name: Мод
|
||||
run: nice -n 19 python3 tools/airdef.py mod
|
||||
- name: Релиз
|
||||
|
||||
@@ -22,7 +22,39 @@ jobs:
|
||||
if: inputs.os == 'macos' || inputs.os == 'both'
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Проверка релиза
|
||||
env:
|
||||
TOKEN: ${{ secrets.RELEASE_TOKEN || gitea.token }}
|
||||
API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
|
||||
TAG: ${{ inputs.tag }}
|
||||
run: |
|
||||
set -e
|
||||
if ! [[ "$TAG" =~ ^build-[0-9]+$ ]]; then echo "::error::тег '$TAG' не похож на build-N"; exit 1; fi
|
||||
REL_JSON=$(mktemp)
|
||||
CODE=$(curl -s -o "$REL_JSON" -w '%{http_code}' -H "Authorization: token $TOKEN" "$API/releases/tags/$TAG")
|
||||
if [ "$CODE" != "200" ]; then echo "::error::релиза с тегом $TAG нет (HTTP $CODE): сначала дождись сборки build.yml на main"; exit 1; fi
|
||||
python3 - "$TAG" "$REL_JSON" <<'PY'
|
||||
import json, os, sys
|
||||
tag, path = sys.argv[1], sys.argv[2]
|
||||
r = json.load(open(path))
|
||||
assets = [a.get('name') for a in (r.get('assets') or [])]
|
||||
if r.get('tag_name') != tag or r.get('name') != tag or 'airdef.hmod' not in assets:
|
||||
print('::error::релиз %s не создан build.yml (нужны имя = тег и вложение airdef.hmod): чужой релиз не трогаем' % tag)
|
||||
sys.exit(1)
|
||||
with open(os.environ['GITHUB_ENV'], 'a') as f:
|
||||
f.write('RELEASE_ID=%s\nRELEASE_SHA=%s\n' % (r['id'], r.get('target_commitish', '')))
|
||||
PY
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: refs/tags/${{ inputs.tag }}
|
||||
- name: Проверка коммита
|
||||
env:
|
||||
TAG: ${{ inputs.tag }}
|
||||
run: |
|
||||
set -e
|
||||
HEAD_SHA=$(git rev-parse HEAD)
|
||||
if [[ "$RELEASE_SHA" =~ ^[0-9a-f]{40}$ ]] && [ "$HEAD_SHA" != "$RELEASE_SHA" ]; then echo "::error::тег $TAG указывает на $HEAD_SHA, а релиз создан из $RELEASE_SHA"; exit 1; fi
|
||||
echo "собираю $TAG = $HEAD_SHA"
|
||||
- name: Rust
|
||||
run: |
|
||||
command -v cargo || curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal
|
||||
@@ -47,11 +79,10 @@ jobs:
|
||||
env:
|
||||
TOKEN: ${{ secrets.RELEASE_TOKEN || gitea.token }}
|
||||
API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
|
||||
TAG: ${{ inputs.tag }}
|
||||
run: |
|
||||
set -e
|
||||
ID=$(curl -sf -H "Authorization: token $TOKEN" "$API/releases/tags/$TAG" | python3 -c 'import json,sys;print(json.load(sys.stdin)["id"])')
|
||||
curl -sf -X POST -H "Authorization: token $TOKEN" -F "attachment=@out/airdef-macos-arm64.tar.gz" "$API/releases/$ID/assets?name=airdef-macos-arm64.tar.gz" > /dev/null
|
||||
# RELEASE_ID взят в шаге «Проверка релиза» (релиз build-N, созданный build.yml)
|
||||
curl -sf -X POST -H "Authorization: token $TOKEN" -F "attachment=@out/airdef-macos-arm64.tar.gz" "$API/releases/$RELEASE_ID/assets?name=airdef-macos-arm64.tar.gz" > /dev/null
|
||||
|
||||
game-windows:
|
||||
if: inputs.os == 'windows' || inputs.os == 'both'
|
||||
@@ -60,7 +91,34 @@ jobs:
|
||||
run:
|
||||
shell: pwsh
|
||||
steps:
|
||||
- name: Проверка релиза
|
||||
env:
|
||||
TOKEN: ${{ secrets.RELEASE_TOKEN || gitea.token }}
|
||||
API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
|
||||
TAG: ${{ inputs.tag }}
|
||||
run: |
|
||||
$ErrorActionPreference = 'Stop'
|
||||
if ($env:TAG -notmatch '^build-\d+$') { Write-Output "::error::тег '$env:TAG' не похож на build-N"; exit 1 }
|
||||
$h = @{ Authorization = "token $env:TOKEN" }
|
||||
try { $r = Invoke-RestMethod -Headers $h "$env:API/releases/tags/$env:TAG" }
|
||||
catch { Write-Output "::error::релиза с тегом $env:TAG нет: сначала дождись сборки build.yml на main"; exit 1 }
|
||||
$assets = @($r.assets | ForEach-Object { $_.name })
|
||||
if ($r.tag_name -ne $env:TAG -or $r.name -ne $env:TAG -or ($assets -notcontains 'airdef.hmod')) {
|
||||
Write-Output "::error::релиз $env:TAG не создан build.yml (нужны имя = тег и вложение airdef.hmod): чужой релиз не трогаем"; exit 1
|
||||
}
|
||||
"RELEASE_ID=$($r.id)" | Out-File -Append -Encoding utf8 $env:GITHUB_ENV
|
||||
"RELEASE_SHA=$($r.target_commitish)" | Out-File -Append -Encoding utf8 $env:GITHUB_ENV
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: refs/tags/${{ inputs.tag }}
|
||||
- name: Проверка коммита
|
||||
env:
|
||||
TAG: ${{ inputs.tag }}
|
||||
run: |
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$head = git rev-parse HEAD
|
||||
if ($env:RELEASE_SHA -match '^[0-9a-f]{40}$' -and $head -ne $env:RELEASE_SHA) { Write-Output "::error::тег $env:TAG указывает на $head, а релиз создан из $env:RELEASE_SHA"; exit 1 }
|
||||
Write-Output "собираю $env:TAG = $head"
|
||||
- name: Rust
|
||||
run: |
|
||||
if (-not (Get-Command cargo -ErrorAction SilentlyContinue)) {
|
||||
@@ -88,9 +146,7 @@ jobs:
|
||||
env:
|
||||
TOKEN: ${{ secrets.RELEASE_TOKEN || gitea.token }}
|
||||
API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
|
||||
TAG: ${{ inputs.tag }}
|
||||
run: |
|
||||
$h = @{ Authorization = "token $env:TOKEN" }
|
||||
$id = (Invoke-RestMethod -Headers $h "$env:API/releases/tags/$env:TAG").id
|
||||
curl.exe -sf -X POST -H "Authorization: token $env:TOKEN" -F "attachment=@out\airdef-windows-x86_64.zip" "$env:API/releases/$id/assets?name=airdef-windows-x86_64.zip"
|
||||
# RELEASE_ID взят в шаге «Проверка релиза» (релиз build-N, созданный build.yml)
|
||||
curl.exe -sf -X POST -H "Authorization: token $env:TOKEN" -F "attachment=@out\airdef-windows-x86_64.zip" "$env:API/releases/$env:RELEASE_ID/assets?name=airdef-windows-x86_64.zip"
|
||||
|
||||
|
||||
@@ -25,7 +25,39 @@ jobs:
|
||||
FREE=$(df --output=avail -BG / | tail -1 | tr -dc 0-9)
|
||||
echo "свободно: ${FREE} ГБ"
|
||||
if [ "$FREE" -lt 15 ]; then echo "::error::на сервере свободно ${FREE} ГБ, нужно хотя бы 15: сборка игры забьёт диск и уронит Gitea"; exit 1; fi
|
||||
- name: Проверка релиза
|
||||
env:
|
||||
TOKEN: ${{ secrets.RELEASE_TOKEN || gitea.token }}
|
||||
API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
|
||||
TAG: ${{ inputs.tag }}
|
||||
run: |
|
||||
set -e
|
||||
if ! [[ "$TAG" =~ ^build-[0-9]+$ ]]; then echo "::error::тег '$TAG' не похож на build-N"; exit 1; fi
|
||||
REL_JSON=$(mktemp)
|
||||
CODE=$(curl -s -o "$REL_JSON" -w '%{http_code}' -H "Authorization: token $TOKEN" "$API/releases/tags/$TAG")
|
||||
if [ "$CODE" != "200" ]; then echo "::error::релиза с тегом $TAG нет (HTTP $CODE): сначала дождись сборки build.yml на main"; exit 1; fi
|
||||
python3 - "$TAG" "$REL_JSON" <<'PY'
|
||||
import json, os, sys
|
||||
tag, path = sys.argv[1], sys.argv[2]
|
||||
r = json.load(open(path))
|
||||
assets = [a.get('name') for a in (r.get('assets') or [])]
|
||||
if r.get('tag_name') != tag or r.get('name') != tag or 'airdef.hmod' not in assets:
|
||||
print('::error::релиз %s не создан build.yml (нужны имя = тег и вложение airdef.hmod): чужой релиз не трогаем' % tag)
|
||||
sys.exit(1)
|
||||
with open(os.environ['GITHUB_ENV'], 'a') as f:
|
||||
f.write('RELEASE_ID=%s\nRELEASE_SHA=%s\n' % (r['id'], r.get('target_commitish', '')))
|
||||
PY
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
ref: refs/tags/${{ inputs.tag }}
|
||||
- name: Проверка коммита
|
||||
env:
|
||||
TAG: ${{ inputs.tag }}
|
||||
run: |
|
||||
set -e
|
||||
HEAD_SHA=$(git rev-parse HEAD)
|
||||
if [[ "$RELEASE_SHA" =~ ^[0-9a-f]{40}$ ]] && [ "$HEAD_SHA" != "$RELEASE_SHA" ]; then echo "::error::тег $TAG указывает на $HEAD_SHA, а релиз создан из $RELEASE_SHA"; exit 1; fi
|
||||
echo "собираю $TAG = $HEAD_SHA"
|
||||
- name: Системные библиотеки
|
||||
run: |
|
||||
SUDO=$(command -v sudo || true)
|
||||
@@ -45,12 +77,11 @@ jobs:
|
||||
env:
|
||||
TOKEN: ${{ secrets.RELEASE_TOKEN || gitea.token }}
|
||||
API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
|
||||
TAG: ${{ inputs.tag }}
|
||||
run: |
|
||||
set -e
|
||||
D=airdef-linux-x86_64
|
||||
mkdir -p "$D" out
|
||||
cp horizon/target/fast/horizon-client horizon/target/fast/horizon-ctl airdef-mod/target/horizon-mod/airdef.hmod dist/play.sh docs/INSTALL.md "$D/"
|
||||
tar czf "out/$D.tar.gz" "$D"
|
||||
ID=$(curl -sf -H "Authorization: token $TOKEN" "$API/releases/tags/$TAG" | python3 -c 'import json,sys;print(json.load(sys.stdin)["id"])')
|
||||
curl -sf -X POST -H "Authorization: token $TOKEN" -F "attachment=@out/$D.tar.gz" "$API/releases/$ID/assets?name=$D.tar.gz" > /dev/null
|
||||
# RELEASE_ID взят в шаге «Проверка релиза» (релиз build-N, созданный build.yml)
|
||||
curl -sf -X POST -H "Authorization: token $TOKEN" -F "attachment=@out/$D.tar.gz" "$API/releases/$RELEASE_ID/assets?name=$D.tar.gz" > /dev/null
|
||||
|
||||
@@ -5,3 +5,5 @@ airdef-mod/target/
|
||||
__pycache__/
|
||||
/out/
|
||||
.DS_Store
|
||||
run-home-bench/
|
||||
run-home-smoke/
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
## Запуск
|
||||
|
||||
Пошаговый гайд для Windows и macOS (готовая сборка из релиза или сборка из исходников): [docs/INSTALL.md](docs/INSTALL.md).
|
||||
Устройство HD-рендера, его статус и план доработки: [docs/HD-RENDERER.md](docs/HD-RENDERER.md).
|
||||
|
||||
Коротко, из исходников:
|
||||
|
||||
@@ -23,9 +24,12 @@ python3 tools/airdef.py play # запустить (аргументы игр
|
||||
(`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` и дописывает архивы в релиз.
|
||||
CI: `.gitea/workflows/build.yml` на каждый пуш собирает только мод (`airdef.hmod`), а пуш в `main` публикует его
|
||||
релизом `build-N`. Игру-форк собирают вручную: `.gitea/workflows/game.yml` (Linux) и `.gitea/workflows/desktop.yml`
|
||||
(macOS и Windows, на раннерах с метками `macos-latest` / `windows-latest`); оба запускаются из Actions с тегом
|
||||
готового релиза `build-N`. Перед сборкой workflow проверяет, что такой релиз создан `build.yml` (имя релиза = тег,
|
||||
есть `airdef.hmod`), иначе падает с ошибкой; затем выкачивает ровно коммит этого тега (а не ветку, с которой запущен),
|
||||
сверяет его с коммитом релиза и дописывает архивы только в этот релиз.
|
||||
|
||||
## Как играть
|
||||
|
||||
@@ -68,6 +72,45 @@ CI: `.gitea/workflows/build.yml` на каждый пуш собирает мо
|
||||
**Сохранение.** Комплексы, объекты, их повреждения и настройки сохраняются отдельно для каждого мира (и для каждого
|
||||
сервера); уничтоженный комплекс остаётся остовом и после перезахода, пока его не отремонтируют.
|
||||
|
||||
**Сеть ПВО.** Каждая единица делится целями со всеми в радиусе 1,5 км (линия связи): РЛС дальнего обнаружения
|
||||
даёт раннее предупреждение всем, пусковая без своей РЛС (P1-SUN) стреляет по чужим данным. Пушкам (Гепард,
|
||||
пушки Панциря) нужна своя цель: они стреляют только по тому, что видят сами. Уничтоженная РЛС — дыра в сети.
|
||||
|
||||
**Логистика.** Пока нет ни одного склада, магазины пополняются сами, как раньше. Как только поставлен склад,
|
||||
боекомплект считается: комплекс без ракет пишет «ЖДЁТ БК»; в 60 м от склада он перезаряжается прямо с него, а
|
||||
дальние обслуживают **ТЗМ**: заправляются на складе (2 перезарядки), сами едут к ждущим комплексам, ближайшим
|
||||
первым, и возвращаются. Запас склада — 30 перезарядок, он виден в сводке. Склад и ТЗМ детонируют всем грузом.
|
||||
|
||||
**Перемещение.** **Пульт перемещения**: навестись на технику (выбрать), затем на точку на земле — она
|
||||
сворачивается (С-400 и другие с вертикальным пуском дольше, Гепард и Панцирь быстро), едет по рельефу и
|
||||
разворачивается; всё это время не стреляет и не светит РЛС. Или `/airdef move <номер>` — к тому месту, где ты стоишь.
|
||||
|
||||
**РЭБ.** Клавиша **U** (или `/airdef ew on|off`) включает все станции. Станция в радиусе 350 м сбивает
|
||||
спутниковую навигацию у Шахедов, Герань, Гербер, Х-101 и Калибров: они теряют маршрут и уводятся с цели
|
||||
(баллистике и Ланцетам с оптикой всё равно). Передатчик работает до 20 с и перегревается; остывает ~35 с,
|
||||
пока не остынет — не включить. Включённая станция себя выдаёт: умный противник запоминает её и шлёт на неё
|
||||
Ланцеты и Х-22, а маршруты спутниковых дронов прокладывает в обход.
|
||||
|
||||
**Умный противник учится.** Он запоминает, откуда его налёты сбивали, а откуда они прорывались, и следующий
|
||||
налёт ведёт с лучшего направления; помнит комплексы, выдавшие себя пуском, и станции РЭБ, и во время налёта
|
||||
перенацеливает ещё не взлетевшие Ланцеты и Шахеды на них; если цель-комплекс уничтожен, дроны идут к
|
||||
следующему известному. Дроны под обстрелом прижимаются к земле.
|
||||
|
||||
**Ночь.** Ночью пушки попадают втрое хуже, если цель не освещена. Освещают **прожекторы** (луч ведёт ближайшую
|
||||
цель из сети, приоритет — цели пушек) и **осветительные ракеты**: пушечные комплексы пускают их сами (раз в
|
||||
25 с на цель в темноте), игрок — **осветительным пистолетом** или `/airdef flare`. Ракета висит ~30 с и
|
||||
освещает всё вокруг на ~60–90 м.
|
||||
|
||||
**Графика: три пресета** (меню N → «Огонь, ремонт, эффекты…» → «Эффекты», или `/airdef shader off|on|hd`):
|
||||
выкл — ванильная картинка; обычные — шейдерные огненные шары, ударная волна и подсветка; **HD** — свой рендер
|
||||
освещения в форке: мир дополнительно рисуется в G-буфер (цвет без света и нормали), и все источники света мода
|
||||
освещают его попиксельно в HDR — факелы ракет и двигатели, раскалённые боевые блоки, осветительные ракеты, вспышки
|
||||
выстрелов, трассеры, взрывы (вспышка и догорающий шар), горящие остовы, пятна прожекторов, — затем bloom и мягкий
|
||||
тонмаппинг (ванильный диапазон не трогается, сжимается только то, что ярче). Источники передаются движку новым
|
||||
API мода `render.set-lights` (до 512, плавно интерполируются), режим — `render.set-lighting`.
|
||||
|
||||
**Сетка J** после сбития ещё 3,5 с держит камеру на сбитой цели, и комплекс в это время не пропадает из сетки.
|
||||
|
||||
**Повреждения.** Взрыв рядом с комплексом повреждает его: он хуже поворачивается, хуже видит и попадает,
|
||||
дымит, ниже 35% горит. Уничтоженный остаётся горящим остовом, его боекомплект детонирует: чем больше ракет
|
||||
оставалось, тем мощнее взрыв и дольше вторичные (у Гепарда рвутся снаряды); соседние комплексы тоже могут
|
||||
@@ -91,7 +134,7 @@ CI: `.gitea/workflows/build.yml` на каждый пуш собирает мо
|
||||
перехватчиков (жёлтые), сбития (x), прилёты, шкала времени с событиями; время идёт само, колесо мыши перематывает;
|
||||
- **повтор момента** — клик по событию в списке: «призраки» дронов и ракет снова летят в мире, камера идёт за
|
||||
целью, потом за перехватчиком (или смотрит из пушки, со стороны на прилёт), в момент сбития время замедляется;
|
||||
- **полный повтор** — весь налёт, камера-режиссёр сама выбирает, за чем следить; колесо — скорость (×0.5–×16);
|
||||
- **полный повтор** — весь налёт, камера-режиссёр сама выбирает, за чем следить; колесо — перемотка, стрелки — скорость;
|
||||
- **лучшие моменты** — нарезка до 8 самых интересных событий (перехват баллистики и гиперзвука, поражения
|
||||
объектов, потерянные комплексы, разделение «Орешника») с титрами и замедлением; колесо листает моменты.
|
||||
|
||||
@@ -103,7 +146,7 @@ CI: `.gitea/workflows/build.yml` на каждый пуш собирает мо
|
||||
Чтобы в повторах и камерах комплексов была видна земля далеко от игрока, мод включает дальний ландшафт
|
||||
(48 чанков, упрощённый); выключается в меню N → «Огонь, ремонт, эффекты…» → «Дальний ландшафт».
|
||||
|
||||
Клавиши N, K, J и R можно переназначить в «Настройки → Моды».
|
||||
Клавиши N, K, J, R и U можно переназначить в «Настройки → Моды».
|
||||
|
||||
Команды:
|
||||
- `/airdef wave <тип> [кол-во] [дальность]` — налёт на ближайшую цель. Типы: `shahed`, `geran3`, `lancet`, `gerbera`, `kh101`, `kalibr`, `kh22`, `zircon`, `iskander`, `kinzhal`, `oreshnik` и `mix` (комбинированный удар двумя секторами: «Герберы», шахеды, Герани-3, Х-101, «Калибры», Х-22, Циркон, «Искандер», «Кинжал», при 30+ — «Орешник»);
|
||||
@@ -152,6 +195,15 @@ CI: `.gitea/workflows/build.yml` на каждый пуш собирает мо
|
||||
| Панцирь-С1 | 12 × 57Э6 и 2 × 30 мм; модуль поворачивается, пакеты и стволы поднимаются | ракеты 25–150, пушки 60 |
|
||||
| С-400 | 4 × 48Н6, вертикальный холодный старт, РЛС обзора на прицепе | 30–480 |
|
||||
| С-500 | 4 × 77Н6, холодный старт, самые быстрые ракеты | 40–700 |
|
||||
| IRIS-T SLM | 8 ракет, вертикальный пуск, быстрые и манёвренные | 15–400 |
|
||||
| NASAMS | 6 × AMRAAM, наводимая пусковая на прицепе | 10–300 |
|
||||
| Бук-М2 | 4 × 9М317 на направляющих, башня с РЛС подсвета | 20–450 |
|
||||
| Тор-М2 | 8 × 9М338 вертикально из башни, быстрая реакция против дронов | 8–160 |
|
||||
| P1-SUN | 8 дронов-перехватчиков против Шахедов и Герань; своей РЛС нет — стреляет по данным сети | 5–450 |
|
||||
|
||||
Обслуживающая техника (тоже пультами или `/airdef deploy <ключ>`): **РЛС дальнего обнаружения** (`radar`,
|
||||
видит на 1,7 км с высокой мачты, хуже прячутся за рельефом), **склад боеприпасов** (`depot`), **ТЗМ** (`tzm`),
|
||||
**станция РЭБ** (`ew`), **прожектор** (`light`). Новые комплексы: `irist`, `nasams`, `buk`, `tor`, `p1sun`.
|
||||
|
||||
**Согласование огня.** Комплексы делят цели между собой: на обычную цель идёт одна ракета, на баллистическую две,
|
||||
пушки расходятся по разным целям. Первыми бьют по самым опасным (быстрым и тяжёлым) целям, при этом ложные
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
Status of terrain-aware flight (not committed):
|
||||
- Done: sim/terrain.rs (look-ahead terrain following, dive only down a clear line, interceptor steer/loft/self-destruct, launch predicate), planner relief pricing + spawn above land (raid.rs), SAM launch check + why line (mod.rs, why.rs), Tally.scrubbed, world.probe, harness terrain fixes, 6 new tests in regress.rs. Build has no warnings; cargo test passes (43 + 4).
|
||||
- Numbers (6 seeds, sim_run big-smart): hills:70:100:140 crashes 13 -> 3, hills:70:150:120 29 -> 2, default hills 2 -> 2 (all terminal-dive near-target by Kh101/Kalibr).
|
||||
- Half-done / known: terminal dive of slow-turning cruise missiles still sometimes hits ground 7-20 blocks short of target; hills:70:150:120 tick max 38 ms / p95 2 ms (planner terrain phase + ground queries) not profiled; not tested in game.
|
||||
- Next: tune dive geometry for Kh101/Kalibr, profile the planner's 1024-columns-per-tick height requests, optional in-game check.
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "airdef:block/amraam_missile"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "airdef:block/beam"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "airdef:block/buk_chassis"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "airdef:block/buk_rails"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "airdef:block/buk_turret"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "airdef:block/depot"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "airdef:block/ew_truck"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "airdef:block/flare"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "airdef:block/irist_chassis"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "airdef:block/irist_missile"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "airdef:block/irist_tubes"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "airdef:block/nasams_launcher"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "airdef:block/nasams_trailer"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "airdef:block/p1sun"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "airdef:block/p1sun_launcher"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "airdef:block/radar_truck"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "airdef:block/searchlight"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "airdef:block/searchlight_head"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "airdef:block/tor_chassis"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "airdef:block/tor_turret"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "airdef:block/tzm_truck"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "airdef:item/deploy_buk"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "airdef:item/deploy_depot"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "airdef:item/deploy_ew"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "airdef:item/deploy_irist"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "airdef:item/deploy_light"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "airdef:item/deploy_nasams"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "airdef:item/deploy_p1sun"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "airdef:item/deploy_radar"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "airdef:item/deploy_tor"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "airdef:item/deploy_tzm"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "airdef:item/flare_gun"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "airdef:item/mover"
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,8 @@
|
||||
"block.airdef.geran3": "Герань-3",
|
||||
"block.airdef.geran3_flame": "Факел",
|
||||
"block.airdef.pac3": "PAC-3 MSE",
|
||||
"block.airdef.irist_missile": "IRIS-T SLM",
|
||||
"block.airdef.amraam_missile": "AMRAAM",
|
||||
"block.airdef.flame": "Факел",
|
||||
"block.airdef.patriot_launcher": "ПУ M903",
|
||||
"block.airdef.patriot_truck": "Тягач",
|
||||
@@ -39,6 +41,25 @@
|
||||
"block.airdef.iskander": "Искандер-М",
|
||||
"block.airdef.kinzhal": "Кинжал",
|
||||
"block.airdef.tracer": "Трассер",
|
||||
"block.airdef.irist_chassis": "Шасси IRIS-T SLM",
|
||||
"block.airdef.irist_tubes": "Пакет IRIS-T",
|
||||
"block.airdef.nasams_trailer": "Прицеп NASAMS",
|
||||
"block.airdef.nasams_launcher": "Пусковая NASAMS",
|
||||
"block.airdef.buk_chassis": "Шасси Бука",
|
||||
"block.airdef.buk_turret": "Башня Бука",
|
||||
"block.airdef.buk_rails": "Ракеты Бука",
|
||||
"block.airdef.tor_chassis": "Шасси Тора",
|
||||
"block.airdef.tor_turret": "Башня Тора",
|
||||
"block.airdef.p1sun_launcher": "Пусковая P1-SUN",
|
||||
"block.airdef.p1sun": "Дрон-перехватчик P1-SUN",
|
||||
"block.airdef.radar_truck": "Шасси РЛС",
|
||||
"block.airdef.depot": "Склад боеприпасов",
|
||||
"block.airdef.tzm_truck": "Транспортно-заряжающая машина",
|
||||
"block.airdef.ew_truck": "Станция РЭБ",
|
||||
"block.airdef.searchlight": "Прожектор",
|
||||
"block.airdef.searchlight_head": "Голова прожектора",
|
||||
"block.airdef.beam": "Луч прожектора",
|
||||
"block.airdef.flare": "Осветительная ракета",
|
||||
"block.airdef.reentry": "Боевой блок",
|
||||
"item.airdef.designator": "Целеуказатель",
|
||||
"item.airdef.launch_shahed": "Пуск: Шахед-136",
|
||||
@@ -56,6 +77,18 @@
|
||||
"item.airdef.launch_iskander": "Пуск: Искандер-М",
|
||||
"item.airdef.launch_kinzhal": "Пуск: Кинжал",
|
||||
"item.airdef.launch_oreshnik": "Пуск: Орешник",
|
||||
"item.airdef.deploy_irist": "Развернуть IRIS-T SLM",
|
||||
"item.airdef.deploy_nasams": "Развернуть NASAMS",
|
||||
"item.airdef.deploy_buk": "Развернуть Бук-М2",
|
||||
"item.airdef.deploy_tor": "Развернуть Тор-М2",
|
||||
"item.airdef.deploy_p1sun": "Развернуть P1-SUN",
|
||||
"item.airdef.deploy_radar": "Развернуть РЛС дальнего обнаружения",
|
||||
"item.airdef.deploy_depot": "Развернуть склад боеприпасов",
|
||||
"item.airdef.deploy_tzm": "Развернуть ТЗМ",
|
||||
"item.airdef.deploy_ew": "Развернуть станцию РЭБ",
|
||||
"item.airdef.deploy_light": "Развернуть прожектор",
|
||||
"item.airdef.mover": "Пульт перемещения",
|
||||
"item.airdef.flare_gun": "Осветительная ракета",
|
||||
"item.airdef.remover": "Свернуть ПВО",
|
||||
"item.airdef.cam_shahed": "Шахед-136",
|
||||
"item.airdef.cam_geran3": "Герань-3",
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
"block.airdef.geran3": "Герань-3",
|
||||
"block.airdef.geran3_flame": "Факел",
|
||||
"block.airdef.pac3": "PAC-3 MSE",
|
||||
"block.airdef.irist_missile": "IRIS-T SLM",
|
||||
"block.airdef.amraam_missile": "AMRAAM",
|
||||
"block.airdef.flame": "Факел",
|
||||
"block.airdef.patriot_launcher": "ПУ M903",
|
||||
"block.airdef.patriot_truck": "Тягач",
|
||||
@@ -39,6 +41,25 @@
|
||||
"block.airdef.iskander": "Искандер-М",
|
||||
"block.airdef.kinzhal": "Кинжал",
|
||||
"block.airdef.tracer": "Трассер",
|
||||
"block.airdef.irist_chassis": "Шасси IRIS-T SLM",
|
||||
"block.airdef.irist_tubes": "Пакет IRIS-T",
|
||||
"block.airdef.nasams_trailer": "Прицеп NASAMS",
|
||||
"block.airdef.nasams_launcher": "Пусковая NASAMS",
|
||||
"block.airdef.buk_chassis": "Шасси Бука",
|
||||
"block.airdef.buk_turret": "Башня Бука",
|
||||
"block.airdef.buk_rails": "Ракеты Бука",
|
||||
"block.airdef.tor_chassis": "Шасси Тора",
|
||||
"block.airdef.tor_turret": "Башня Тора",
|
||||
"block.airdef.p1sun_launcher": "Пусковая P1-SUN",
|
||||
"block.airdef.p1sun": "Дрон-перехватчик P1-SUN",
|
||||
"block.airdef.radar_truck": "Шасси РЛС",
|
||||
"block.airdef.depot": "Склад боеприпасов",
|
||||
"block.airdef.tzm_truck": "Транспортно-заряжающая машина",
|
||||
"block.airdef.ew_truck": "Станция РЭБ",
|
||||
"block.airdef.searchlight": "Прожектор",
|
||||
"block.airdef.searchlight_head": "Голова прожектора",
|
||||
"block.airdef.beam": "Луч прожектора",
|
||||
"block.airdef.flare": "Осветительная ракета",
|
||||
"block.airdef.reentry": "Боевой блок",
|
||||
"item.airdef.designator": "Целеуказатель",
|
||||
"item.airdef.launch_shahed": "Пуск: Шахед-136",
|
||||
@@ -56,6 +77,18 @@
|
||||
"item.airdef.launch_iskander": "Пуск: Искандер-М",
|
||||
"item.airdef.launch_kinzhal": "Пуск: Кинжал",
|
||||
"item.airdef.launch_oreshnik": "Пуск: Орешник",
|
||||
"item.airdef.deploy_irist": "Развернуть IRIS-T SLM",
|
||||
"item.airdef.deploy_nasams": "Развернуть NASAMS",
|
||||
"item.airdef.deploy_buk": "Развернуть Бук-М2",
|
||||
"item.airdef.deploy_tor": "Развернуть Тор-М2",
|
||||
"item.airdef.deploy_p1sun": "Развернуть P1-SUN",
|
||||
"item.airdef.deploy_radar": "Развернуть РЛС дальнего обнаружения",
|
||||
"item.airdef.deploy_depot": "Развернуть склад боеприпасов",
|
||||
"item.airdef.deploy_tzm": "Развернуть ТЗМ",
|
||||
"item.airdef.deploy_ew": "Развернуть станцию РЭБ",
|
||||
"item.airdef.deploy_light": "Развернуть прожектор",
|
||||
"item.airdef.mover": "Пульт перемещения",
|
||||
"item.airdef.flare_gun": "Осветительная ракета",
|
||||
"item.airdef.remover": "Свернуть ПВО",
|
||||
"item.airdef.cam_shahed": "Шахед-136",
|
||||
"item.airdef.cam_geran3": "Герань-3",
|
||||
|
||||
@@ -0,0 +1,895 @@
|
||||
{
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"nose_dark": "airdef:block/nose_dark",
|
||||
"white": "airdef:block/white",
|
||||
"nozzle": "airdef:block/nozzle",
|
||||
"particle": "airdef:block/nose_dark"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [
|
||||
7.333333333333333,
|
||||
7.333333333333333,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
8.666666666666666,
|
||||
8.666666666666666,
|
||||
-13.666666666666666
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.333333333333333,
|
||||
1.333333333333333
|
||||
],
|
||||
"texture": "#nose_dark"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.333333333333333,
|
||||
1.333333333333333
|
||||
],
|
||||
"texture": "#nose_dark"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.333333333333334,
|
||||
1.333333333333333
|
||||
],
|
||||
"texture": "#nose_dark"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.333333333333334,
|
||||
1.333333333333333
|
||||
],
|
||||
"texture": "#nose_dark"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.333333333333333,
|
||||
2.333333333333334
|
||||
],
|
||||
"texture": "#nose_dark"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.333333333333333,
|
||||
2.333333333333334
|
||||
],
|
||||
"texture": "#nose_dark"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
7.0,
|
||||
7.0,
|
||||
-13.666666666666666
|
||||
],
|
||||
"to": [
|
||||
9.0,
|
||||
9.0,
|
||||
-11.333333333333332
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#nose_dark"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#nose_dark"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.333333333333334,
|
||||
2.0
|
||||
],
|
||||
"texture": "#nose_dark"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.333333333333334,
|
||||
2.0
|
||||
],
|
||||
"texture": "#nose_dark"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.333333333333334
|
||||
],
|
||||
"texture": "#nose_dark"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.333333333333334
|
||||
],
|
||||
"texture": "#nose_dark"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
6.666666666666666,
|
||||
6.666666666666666,
|
||||
-11.333333333333332
|
||||
],
|
||||
"to": [
|
||||
9.333333333333334,
|
||||
9.333333333333334,
|
||||
-9.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.666666666666668,
|
||||
2.666666666666668
|
||||
],
|
||||
"texture": "#nose_dark"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.666666666666668,
|
||||
2.666666666666668
|
||||
],
|
||||
"texture": "#nose_dark"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.333333333333332,
|
||||
2.666666666666668
|
||||
],
|
||||
"texture": "#nose_dark"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.333333333333332,
|
||||
2.666666666666668
|
||||
],
|
||||
"texture": "#nose_dark"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.666666666666668,
|
||||
2.333333333333332
|
||||
],
|
||||
"texture": "#nose_dark"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.666666666666668,
|
||||
2.333333333333332
|
||||
],
|
||||
"texture": "#nose_dark"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
6.5,
|
||||
6.5,
|
||||
-9.0
|
||||
],
|
||||
"to": [
|
||||
9.5,
|
||||
9.5,
|
||||
26.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#white"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
1.0,
|
||||
7.6,
|
||||
2.0
|
||||
],
|
||||
"to": [
|
||||
6.5,
|
||||
8.4,
|
||||
9.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.5,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.5,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.5,
|
||||
7.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.5,
|
||||
7.0
|
||||
],
|
||||
"texture": "#white"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
9.5,
|
||||
7.6,
|
||||
2.0
|
||||
],
|
||||
"to": [
|
||||
15.0,
|
||||
8.4,
|
||||
9.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.5,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.5,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.5,
|
||||
7.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.5,
|
||||
7.0
|
||||
],
|
||||
"texture": "#white"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
7.6,
|
||||
1.0,
|
||||
2.0
|
||||
],
|
||||
"to": [
|
||||
8.4,
|
||||
6.5,
|
||||
9.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
5.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
5.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
5.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
5.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
7.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
7.0
|
||||
],
|
||||
"texture": "#white"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
7.6,
|
||||
9.5,
|
||||
2.0
|
||||
],
|
||||
"to": [
|
||||
8.4,
|
||||
15.0,
|
||||
9.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
5.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
5.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
5.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
5.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
7.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
7.0
|
||||
],
|
||||
"texture": "#white"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
4.0,
|
||||
7.6,
|
||||
19.0
|
||||
],
|
||||
"to": [
|
||||
6.5,
|
||||
8.4,
|
||||
25.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.5,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.5,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.5,
|
||||
6.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.5,
|
||||
6.0
|
||||
],
|
||||
"texture": "#white"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
9.5,
|
||||
7.6,
|
||||
19.0
|
||||
],
|
||||
"to": [
|
||||
12.0,
|
||||
8.4,
|
||||
25.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.5,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.5,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.5,
|
||||
6.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.5,
|
||||
6.0
|
||||
],
|
||||
"texture": "#white"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
7.6,
|
||||
4.0,
|
||||
19.0
|
||||
],
|
||||
"to": [
|
||||
8.4,
|
||||
6.5,
|
||||
25.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
2.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
2.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
2.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
2.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
6.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
6.0
|
||||
],
|
||||
"texture": "#white"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
7.6,
|
||||
9.5,
|
||||
19.0
|
||||
],
|
||||
"to": [
|
||||
8.4,
|
||||
12.0,
|
||||
25.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
2.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
2.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
2.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
2.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
6.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
6.0
|
||||
],
|
||||
"texture": "#white"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
7.0,
|
||||
7.0,
|
||||
26.0
|
||||
],
|
||||
"to": [
|
||||
9.0,
|
||||
9.0,
|
||||
28.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#nozzle"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#nozzle"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#nozzle"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#nozzle"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#nozzle"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#nozzle"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"beam": "airdef:block/beam",
|
||||
"particle": "airdef:block/beam"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [
|
||||
6.5,
|
||||
6.5,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
9.5,
|
||||
9.5,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#beam"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#beam"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#beam"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#beam"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#beam"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#beam"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,487 @@
|
||||
{
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"ru_green": "airdef:block/ru_green",
|
||||
"dark_metal": "airdef:block/dark_metal",
|
||||
"track": "airdef:block/track",
|
||||
"particle": "airdef:block/ru_green"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [
|
||||
-10.0,
|
||||
4.0,
|
||||
-14.0
|
||||
],
|
||||
"to": [
|
||||
26.0,
|
||||
15.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
11.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
11.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
11.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
11.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-10.0,
|
||||
4.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
26.0,
|
||||
10.0,
|
||||
-14.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
6.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
6.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-8.0,
|
||||
15.0,
|
||||
22.0
|
||||
],
|
||||
"to": [
|
||||
24.0,
|
||||
16.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
10.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
10.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
10.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
10.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-14.0,
|
||||
0.0,
|
||||
-15.0
|
||||
],
|
||||
"to": [
|
||||
-10.0,
|
||||
9.0,
|
||||
31.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#track"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#track"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
9.0
|
||||
],
|
||||
"texture": "#track"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
9.0
|
||||
],
|
||||
"texture": "#track"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#track"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#track"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
26.0,
|
||||
0.0,
|
||||
-15.0
|
||||
],
|
||||
"to": [
|
||||
30.0,
|
||||
9.0,
|
||||
31.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#track"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#track"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
9.0
|
||||
],
|
||||
"texture": "#track"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
9.0
|
||||
],
|
||||
"texture": "#track"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#track"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#track"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-14.5,
|
||||
5.0,
|
||||
-15.0
|
||||
],
|
||||
"to": [
|
||||
-10.0,
|
||||
10.0,
|
||||
31.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
5.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
5.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
16
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
16
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
26.0,
|
||||
5.0,
|
||||
-15.0
|
||||
],
|
||||
"to": [
|
||||
30.5,
|
||||
10.0,
|
||||
31.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
5.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
5.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
16
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
16
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,896 @@
|
||||
{
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"missile_ru": "airdef:block/missile_ru",
|
||||
"booster": "airdef:block/booster",
|
||||
"dark_metal": "airdef:block/dark_metal",
|
||||
"ru_green": "airdef:block/ru_green",
|
||||
"particle": "airdef:block/missile_ru"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [
|
||||
-10.5,
|
||||
4.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
-7.5,
|
||||
7.0,
|
||||
26.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-10.8,
|
||||
3.5,
|
||||
20.0
|
||||
],
|
||||
"to": [
|
||||
-7.2,
|
||||
7.5,
|
||||
27.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.6000000000000005,
|
||||
4.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.6000000000000005,
|
||||
4.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.6000000000000005,
|
||||
7.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.6000000000000005,
|
||||
7.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-9.5,
|
||||
2.0,
|
||||
-6.0
|
||||
],
|
||||
"to": [
|
||||
-8.5,
|
||||
4.0,
|
||||
16.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-4.5,
|
||||
4.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
-1.5,
|
||||
7.0,
|
||||
26.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-4.8,
|
||||
3.5,
|
||||
20.0
|
||||
],
|
||||
"to": [
|
||||
-1.2,
|
||||
7.5,
|
||||
27.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5999999999999996,
|
||||
4.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5999999999999996,
|
||||
4.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5999999999999996,
|
||||
7.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5999999999999996,
|
||||
7.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-3.5,
|
||||
2.0,
|
||||
-6.0
|
||||
],
|
||||
"to": [
|
||||
-2.5,
|
||||
4.0,
|
||||
16.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
11.5,
|
||||
4.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
14.5,
|
||||
7.0,
|
||||
26.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
11.2,
|
||||
3.5,
|
||||
20.0
|
||||
],
|
||||
"to": [
|
||||
14.8,
|
||||
7.5,
|
||||
27.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.6000000000000014,
|
||||
4.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.6000000000000014,
|
||||
4.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.6000000000000014,
|
||||
7.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.6000000000000014,
|
||||
7.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
12.5,
|
||||
2.0,
|
||||
-6.0
|
||||
],
|
||||
"to": [
|
||||
13.5,
|
||||
4.0,
|
||||
16.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
17.5,
|
||||
4.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
20.5,
|
||||
7.0,
|
||||
26.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#missile_ru"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
17.2,
|
||||
3.5,
|
||||
20.0
|
||||
],
|
||||
"to": [
|
||||
20.8,
|
||||
7.5,
|
||||
27.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.6000000000000014,
|
||||
4.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.6000000000000014,
|
||||
4.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.6000000000000014,
|
||||
7.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.6000000000000014,
|
||||
7.0
|
||||
],
|
||||
"texture": "#booster"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
18.5,
|
||||
2.0,
|
||||
-6.0
|
||||
],
|
||||
"to": [
|
||||
19.5,
|
||||
4.0,
|
||||
16.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-12.0,
|
||||
0.0,
|
||||
-2.0
|
||||
],
|
||||
"to": [
|
||||
28.0,
|
||||
2.0,
|
||||
14.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
{
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"ru_green": "airdef:block/ru_green",
|
||||
"radar_face": "airdef:block/radar_face",
|
||||
"particle": "airdef:block/ru_green"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [
|
||||
-4.0,
|
||||
0.0,
|
||||
-4.0
|
||||
],
|
||||
"to": [
|
||||
20.0,
|
||||
9.0,
|
||||
20.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
9.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
9.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
9.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
9.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
1.0,
|
||||
2.0,
|
||||
-10.0
|
||||
],
|
||||
"to": [
|
||||
15.0,
|
||||
14.0,
|
||||
-4.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
14.0,
|
||||
12.0
|
||||
],
|
||||
"texture": "#radar_face"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
14.0,
|
||||
12.0
|
||||
],
|
||||
"texture": "#radar_face"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
12.0
|
||||
],
|
||||
"texture": "#radar_face"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
12.0
|
||||
],
|
||||
"texture": "#radar_face"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
14.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#radar_face"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
14.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#radar_face"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-2.0,
|
||||
9.0,
|
||||
6.0
|
||||
],
|
||||
"to": [
|
||||
18.0,
|
||||
11.0,
|
||||
18.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
12.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
12.0
|
||||
],
|
||||
"texture": "#ru_green"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,488 @@
|
||||
{
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"concrete": "airdef:block/concrete",
|
||||
"crate": "airdef:block/crate",
|
||||
"tube": "airdef:block/tube",
|
||||
"tube_cap": "airdef:block/tube_cap",
|
||||
"particle": "airdef:block/concrete"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [
|
||||
-14.0,
|
||||
0.0,
|
||||
-14.0
|
||||
],
|
||||
"to": [
|
||||
30.0,
|
||||
2.0,
|
||||
30.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#concrete"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#concrete"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#concrete"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#concrete"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#concrete"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#concrete"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-12.0,
|
||||
2.0,
|
||||
-12.0
|
||||
],
|
||||
"to": [
|
||||
0.0,
|
||||
10.0,
|
||||
0.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
8.0
|
||||
],
|
||||
"texture": "#crate"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
8.0
|
||||
],
|
||||
"texture": "#crate"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
8.0
|
||||
],
|
||||
"texture": "#crate"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
8.0
|
||||
],
|
||||
"texture": "#crate"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
12.0
|
||||
],
|
||||
"texture": "#crate"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
12.0
|
||||
],
|
||||
"texture": "#crate"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-12.0,
|
||||
2.0,
|
||||
4.0
|
||||
],
|
||||
"to": [
|
||||
0.0,
|
||||
10.0,
|
||||
16.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
8.0
|
||||
],
|
||||
"texture": "#crate"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
8.0
|
||||
],
|
||||
"texture": "#crate"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
8.0
|
||||
],
|
||||
"texture": "#crate"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
8.0
|
||||
],
|
||||
"texture": "#crate"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
12.0
|
||||
],
|
||||
"texture": "#crate"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
12.0
|
||||
],
|
||||
"texture": "#crate"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
4.0,
|
||||
2.0,
|
||||
-12.0
|
||||
],
|
||||
"to": [
|
||||
16.0,
|
||||
10.0,
|
||||
0.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
8.0
|
||||
],
|
||||
"texture": "#crate"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
8.0
|
||||
],
|
||||
"texture": "#crate"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
8.0
|
||||
],
|
||||
"texture": "#crate"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
8.0
|
||||
],
|
||||
"texture": "#crate"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
12.0
|
||||
],
|
||||
"texture": "#crate"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
12.0
|
||||
],
|
||||
"texture": "#crate"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
6.0,
|
||||
2.0,
|
||||
6.0
|
||||
],
|
||||
"to": [
|
||||
28.0,
|
||||
7.0,
|
||||
10.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
5.0
|
||||
],
|
||||
"texture": "#tube"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
5.0
|
||||
],
|
||||
"texture": "#tube"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
6.0,
|
||||
7.0,
|
||||
6.0
|
||||
],
|
||||
"to": [
|
||||
28.0,
|
||||
12.0,
|
||||
10.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
5.0
|
||||
],
|
||||
"texture": "#tube"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
5.0
|
||||
],
|
||||
"texture": "#tube"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
6.0,
|
||||
12.0,
|
||||
6.0
|
||||
],
|
||||
"to": [
|
||||
28.0,
|
||||
17.0,
|
||||
10.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
5.0
|
||||
],
|
||||
"texture": "#tube"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
5.0
|
||||
],
|
||||
"texture": "#tube"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"lamp": "airdef:block/lamp",
|
||||
"antenna": "airdef:block/antenna",
|
||||
"particle": "airdef:block/lamp"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [
|
||||
6.5,
|
||||
6.5,
|
||||
6.5
|
||||
],
|
||||
"to": [
|
||||
9.5,
|
||||
9.5,
|
||||
9.5
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#lamp"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#lamp"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#lamp"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#lamp"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#lamp"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#lamp"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
7.6,
|
||||
9.5,
|
||||
7.6
|
||||
],
|
||||
"to": [
|
||||
8.4,
|
||||
16.0,
|
||||
8.4
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
6.5
|
||||
],
|
||||
"texture": "#antenna"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
6.5
|
||||
],
|
||||
"texture": "#antenna"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
6.5
|
||||
],
|
||||
"texture": "#antenna"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
6.5
|
||||
],
|
||||
"texture": "#antenna"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#antenna"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#antenna"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,895 @@
|
||||
{
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"white": "airdef:block/white",
|
||||
"missile_grey": "airdef:block/missile_grey",
|
||||
"nozzle": "airdef:block/nozzle",
|
||||
"particle": "airdef:block/white"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [
|
||||
7.333333333333333,
|
||||
7.333333333333333,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
8.666666666666666,
|
||||
8.666666666666666,
|
||||
-14.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.333333333333333,
|
||||
1.333333333333333
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.333333333333333,
|
||||
1.333333333333333
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
1.333333333333333
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
1.333333333333333
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.333333333333333,
|
||||
2.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.333333333333333,
|
||||
2.0
|
||||
],
|
||||
"texture": "#white"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
7.0,
|
||||
7.0,
|
||||
-14.0
|
||||
],
|
||||
"to": [
|
||||
9.0,
|
||||
9.0,
|
||||
-12.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#white"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
6.666666666666666,
|
||||
6.666666666666666,
|
||||
-12.0
|
||||
],
|
||||
"to": [
|
||||
9.333333333333334,
|
||||
9.333333333333334,
|
||||
-10.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.666666666666668,
|
||||
2.666666666666668
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.666666666666668,
|
||||
2.666666666666668
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.666666666666668
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.666666666666668
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.666666666666668,
|
||||
2.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.666666666666668,
|
||||
2.0
|
||||
],
|
||||
"texture": "#white"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
6.5,
|
||||
6.5,
|
||||
-10.0
|
||||
],
|
||||
"to": [
|
||||
9.5,
|
||||
9.5,
|
||||
24.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#white"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
3.0,
|
||||
7.6,
|
||||
-9.0
|
||||
],
|
||||
"to": [
|
||||
6.5,
|
||||
8.4,
|
||||
-5.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
4.0
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
4.0
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
9.5,
|
||||
7.6,
|
||||
-9.0
|
||||
],
|
||||
"to": [
|
||||
13.0,
|
||||
8.4,
|
||||
-5.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
4.0
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
4.0
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
7.6,
|
||||
3.0,
|
||||
-9.0
|
||||
],
|
||||
"to": [
|
||||
8.4,
|
||||
6.5,
|
||||
-5.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
3.5
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
3.5
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
3.5
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
3.5
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
4.0
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
4.0
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
7.6,
|
||||
9.5,
|
||||
-9.0
|
||||
],
|
||||
"to": [
|
||||
8.4,
|
||||
13.0,
|
||||
-5.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
3.5
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
3.5
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
3.5
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
3.5
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
4.0
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
4.0
|
||||
],
|
||||
"texture": "#missile_grey"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
2.0,
|
||||
7.6,
|
||||
18.0
|
||||
],
|
||||
"to": [
|
||||
6.5,
|
||||
8.4,
|
||||
26.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
8.0,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
8.0,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
8.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
8.0
|
||||
],
|
||||
"texture": "#white"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
9.5,
|
||||
7.6,
|
||||
18.0
|
||||
],
|
||||
"to": [
|
||||
14.0,
|
||||
8.4,
|
||||
26.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
8.0,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
8.0,
|
||||
0.8000000000000007
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
8.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
8.0
|
||||
],
|
||||
"texture": "#white"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
7.6,
|
||||
2.0,
|
||||
18.0
|
||||
],
|
||||
"to": [
|
||||
8.4,
|
||||
6.5,
|
||||
26.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
4.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
4.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
8.0,
|
||||
4.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
8.0,
|
||||
4.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
8.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
8.0
|
||||
],
|
||||
"texture": "#white"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
7.6,
|
||||
9.5,
|
||||
18.0
|
||||
],
|
||||
"to": [
|
||||
8.4,
|
||||
14.0,
|
||||
26.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
4.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
4.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
8.0,
|
||||
4.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
8.0,
|
||||
4.5
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
8.0
|
||||
],
|
||||
"texture": "#white"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.8000000000000007,
|
||||
8.0
|
||||
],
|
||||
"texture": "#white"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
7.0,
|
||||
7.0,
|
||||
24.0
|
||||
],
|
||||
"to": [
|
||||
9.0,
|
||||
9.0,
|
||||
28.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#nozzle"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#nozzle"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#nozzle"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#nozzle"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#nozzle"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#nozzle"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,691 @@
|
||||
{
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"canister": "airdef:block/canister",
|
||||
"tube_cap": "airdef:block/tube_cap",
|
||||
"dark_metal": "airdef:block/dark_metal",
|
||||
"particle": "airdef:block/canister"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [
|
||||
-1.5,
|
||||
0.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
2.5,
|
||||
4.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-1.5,
|
||||
5.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
2.5,
|
||||
9.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
3.5,
|
||||
0.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
7.5,
|
||||
4.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
3.5,
|
||||
5.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
7.5,
|
||||
9.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
8.5,
|
||||
0.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
12.5,
|
||||
4.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
8.5,
|
||||
5.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
12.5,
|
||||
9.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
13.5,
|
||||
0.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
17.5,
|
||||
4.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
13.5,
|
||||
5.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
17.5,
|
||||
9.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-2.5,
|
||||
0.0,
|
||||
26.0
|
||||
],
|
||||
"to": [
|
||||
18.5,
|
||||
9.0,
|
||||
28.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
9.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
9.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-2.5,
|
||||
0.0,
|
||||
-2.0
|
||||
],
|
||||
"to": [
|
||||
18.5,
|
||||
9.0,
|
||||
0.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
9.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
9.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,555 @@
|
||||
{
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"canister": "airdef:block/canister",
|
||||
"tube_cap": "airdef:block/tube_cap",
|
||||
"dark_metal": "airdef:block/dark_metal",
|
||||
"particle": "airdef:block/canister"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [
|
||||
1.0,
|
||||
0.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
5.0,
|
||||
4.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
1.0,
|
||||
5.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
5.0,
|
||||
9.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
6.0,
|
||||
0.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
10.0,
|
||||
4.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
6.0,
|
||||
5.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
10.0,
|
||||
9.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
11.0,
|
||||
0.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
15.0,
|
||||
4.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
11.0,
|
||||
5.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
15.0,
|
||||
9.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#canister"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
0.0,
|
||||
0.0,
|
||||
26.0
|
||||
],
|
||||
"to": [
|
||||
16.0,
|
||||
9.0,
|
||||
28.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
9.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
9.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
0.0,
|
||||
0.0,
|
||||
-2.0
|
||||
],
|
||||
"to": [
|
||||
16.0,
|
||||
9.0,
|
||||
0.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
9.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
9.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,488 @@
|
||||
{
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"nato_green": "airdef:block/nato_green",
|
||||
"dark_metal": "airdef:block/dark_metal",
|
||||
"metal": "airdef:block/metal",
|
||||
"tire": "airdef:block/tire",
|
||||
"particle": "airdef:block/nato_green"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [
|
||||
-6.0,
|
||||
5.0,
|
||||
-10.0
|
||||
],
|
||||
"to": [
|
||||
22.0,
|
||||
9.0,
|
||||
26.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#nato_green"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#nato_green"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#nato_green"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#nato_green"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#nato_green"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#nato_green"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-4.0,
|
||||
9.0,
|
||||
10.0
|
||||
],
|
||||
"to": [
|
||||
20.0,
|
||||
13.0,
|
||||
24.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
4.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
14.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
14.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
14.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
14.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
6.0,
|
||||
3.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
10.0,
|
||||
6.0,
|
||||
-10.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-9.0,
|
||||
0.0,
|
||||
4.0
|
||||
],
|
||||
"to": [
|
||||
-5.5,
|
||||
9.0,
|
||||
11.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
9.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
9.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
7.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
7.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
21.5,
|
||||
0.0,
|
||||
4.0
|
||||
],
|
||||
"to": [
|
||||
25.0,
|
||||
9.0,
|
||||
11.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
9.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
9.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
7.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
7.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-9.0,
|
||||
0.0,
|
||||
14.0
|
||||
],
|
||||
"to": [
|
||||
-5.5,
|
||||
9.0,
|
||||
21.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
9.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
9.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
7.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
7.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
21.5,
|
||||
0.0,
|
||||
14.0
|
||||
],
|
||||
"to": [
|
||||
25.0,
|
||||
9.0,
|
||||
21.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
9.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
9.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
7.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
7.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.5,
|
||||
7.0
|
||||
],
|
||||
"texture": "#tire"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,691 @@
|
||||
{
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"dark_metal": "airdef:block/dark_metal",
|
||||
"missile": "airdef:block/missile",
|
||||
"prop": "airdef:block/prop",
|
||||
"particle": "airdef:block/dark_metal"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [
|
||||
6.5,
|
||||
6.5,
|
||||
-10.0
|
||||
],
|
||||
"to": [
|
||||
9.5,
|
||||
9.5,
|
||||
10.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
7.0,
|
||||
7.0,
|
||||
-14.0
|
||||
],
|
||||
"to": [
|
||||
9.0,
|
||||
9.0,
|
||||
-10.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#missile"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#missile"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#missile"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
2.0
|
||||
],
|
||||
"texture": "#missile"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#missile"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#missile"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
2.0,
|
||||
2.0,
|
||||
0.0
|
||||
],
|
||||
"to": [
|
||||
8.0,
|
||||
8.0,
|
||||
1.5
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.5,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.5,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.5
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.5
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-0.5,
|
||||
-0.5,
|
||||
0.0
|
||||
],
|
||||
"to": [
|
||||
4.5,
|
||||
4.5,
|
||||
0.6
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
5.0
|
||||
],
|
||||
"texture": "#prop"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
5.0
|
||||
],
|
||||
"texture": "#prop"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.6,
|
||||
5.0
|
||||
],
|
||||
"texture": "#prop"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.6,
|
||||
5.0
|
||||
],
|
||||
"texture": "#prop"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
0.6
|
||||
],
|
||||
"texture": "#prop"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
0.6
|
||||
],
|
||||
"texture": "#prop"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
2.0,
|
||||
8.0,
|
||||
0.0
|
||||
],
|
||||
"to": [
|
||||
8.0,
|
||||
14.0,
|
||||
1.5
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.5,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.5,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.5
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.5
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-0.5,
|
||||
11.5,
|
||||
0.0
|
||||
],
|
||||
"to": [
|
||||
4.5,
|
||||
16.5,
|
||||
0.6
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
5.0
|
||||
],
|
||||
"texture": "#prop"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
5.0
|
||||
],
|
||||
"texture": "#prop"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.6,
|
||||
5.0
|
||||
],
|
||||
"texture": "#prop"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.6,
|
||||
5.0
|
||||
],
|
||||
"texture": "#prop"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
0.6
|
||||
],
|
||||
"texture": "#prop"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
0.6
|
||||
],
|
||||
"texture": "#prop"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
8.0,
|
||||
2.0,
|
||||
0.0
|
||||
],
|
||||
"to": [
|
||||
14.0,
|
||||
8.0,
|
||||
1.5
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.5,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.5,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.5
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.5
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
11.5,
|
||||
-0.5,
|
||||
0.0
|
||||
],
|
||||
"to": [
|
||||
16.5,
|
||||
4.5,
|
||||
0.6
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
5.0
|
||||
],
|
||||
"texture": "#prop"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
5.0
|
||||
],
|
||||
"texture": "#prop"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.6,
|
||||
5.0
|
||||
],
|
||||
"texture": "#prop"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.6,
|
||||
5.0
|
||||
],
|
||||
"texture": "#prop"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
0.6
|
||||
],
|
||||
"texture": "#prop"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
0.6
|
||||
],
|
||||
"texture": "#prop"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
8.0,
|
||||
8.0,
|
||||
0.0
|
||||
],
|
||||
"to": [
|
||||
14.0,
|
||||
14.0,
|
||||
1.5
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.5,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
1.5,
|
||||
6.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.5
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.5
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
11.5,
|
||||
11.5,
|
||||
0.0
|
||||
],
|
||||
"to": [
|
||||
16.5,
|
||||
16.5,
|
||||
0.6
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
5.0
|
||||
],
|
||||
"texture": "#prop"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
5.0
|
||||
],
|
||||
"texture": "#prop"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.6,
|
||||
5.0
|
||||
],
|
||||
"texture": "#prop"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.6,
|
||||
5.0
|
||||
],
|
||||
"texture": "#prop"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
0.6
|
||||
],
|
||||
"texture": "#prop"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
0.6
|
||||
],
|
||||
"texture": "#prop"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,690 @@
|
||||
{
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"dark_metal": "airdef:block/dark_metal",
|
||||
"tube_cap": "airdef:block/tube_cap",
|
||||
"particle": "airdef:block/dark_metal"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [
|
||||
0.5,
|
||||
0.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
3.5,
|
||||
3.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
0.5,
|
||||
4.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
3.5,
|
||||
7.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
4.5,
|
||||
0.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
7.5,
|
||||
3.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
4.5,
|
||||
4.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
7.5,
|
||||
7.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
8.5,
|
||||
0.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
11.5,
|
||||
3.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
8.5,
|
||||
4.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
11.5,
|
||||
7.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
12.5,
|
||||
0.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
15.5,
|
||||
3.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
12.5,
|
||||
4.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
15.5,
|
||||
7.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
3.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-0.5,
|
||||
0.0,
|
||||
26.0
|
||||
],
|
||||
"to": [
|
||||
16.5,
|
||||
7.0,
|
||||
28.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
7.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
7.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
7.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
7.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-0.5,
|
||||
0.0,
|
||||
-2.0
|
||||
],
|
||||
"to": [
|
||||
16.5,
|
||||
7.0,
|
||||
0.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
7.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
7.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
7.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
7.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
{
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"dark_metal": "airdef:block/dark_metal",
|
||||
"particle": "airdef:block/dark_metal"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [
|
||||
2.0,
|
||||
0.0,
|
||||
2.0
|
||||
],
|
||||
"to": [
|
||||
14.0,
|
||||
3.0,
|
||||
14.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
3.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
12.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
12.0,
|
||||
12.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
6.0,
|
||||
3.0,
|
||||
6.0
|
||||
],
|
||||
"to": [
|
||||
10.0,
|
||||
12.0,
|
||||
10.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
4.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
{
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"dark_metal": "airdef:block/dark_metal",
|
||||
"lamp": "airdef:block/lamp",
|
||||
"particle": "airdef:block/dark_metal"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [
|
||||
3.0,
|
||||
3.0,
|
||||
-2.0
|
||||
],
|
||||
"to": [
|
||||
13.0,
|
||||
13.0,
|
||||
14.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
10.0,
|
||||
10.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
10.0,
|
||||
10.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
10.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
10.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
10.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
10.0,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
3.5,
|
||||
3.5,
|
||||
-2.5
|
||||
],
|
||||
"to": [
|
||||
12.5,
|
||||
12.5,
|
||||
-2.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
9.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#lamp"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
9.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#lamp"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.5,
|
||||
9.0
|
||||
],
|
||||
"texture": "#lamp"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
0.5,
|
||||
9.0
|
||||
],
|
||||
"texture": "#lamp"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
9.0,
|
||||
0.5
|
||||
],
|
||||
"texture": "#lamp"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
9.0,
|
||||
0.5
|
||||
],
|
||||
"texture": "#lamp"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,487 @@
|
||||
{
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"ru_khaki": "airdef:block/ru_khaki",
|
||||
"dark_metal": "airdef:block/dark_metal",
|
||||
"track": "airdef:block/track",
|
||||
"particle": "airdef:block/ru_khaki"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [
|
||||
-10.0,
|
||||
4.0,
|
||||
-14.0
|
||||
],
|
||||
"to": [
|
||||
26.0,
|
||||
15.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
11.0
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
11.0
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
11.0
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
11.0
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-10.0,
|
||||
4.0,
|
||||
-16.0
|
||||
],
|
||||
"to": [
|
||||
26.0,
|
||||
10.0,
|
||||
-14.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
6.0
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
6.0
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
2.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
2.0
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-8.0,
|
||||
15.0,
|
||||
22.0
|
||||
],
|
||||
"to": [
|
||||
24.0,
|
||||
16.0,
|
||||
32.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
10.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
10.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
10.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
10.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-14.0,
|
||||
0.0,
|
||||
-15.0
|
||||
],
|
||||
"to": [
|
||||
-10.0,
|
||||
9.0,
|
||||
31.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#track"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#track"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
9.0
|
||||
],
|
||||
"texture": "#track"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
9.0
|
||||
],
|
||||
"texture": "#track"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#track"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#track"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
26.0,
|
||||
0.0,
|
||||
-15.0
|
||||
],
|
||||
"to": [
|
||||
30.0,
|
||||
9.0,
|
||||
31.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#track"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
9.0
|
||||
],
|
||||
"texture": "#track"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
9.0
|
||||
],
|
||||
"texture": "#track"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
9.0
|
||||
],
|
||||
"texture": "#track"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#track"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
16
|
||||
],
|
||||
"texture": "#track"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-14.5,
|
||||
5.0,
|
||||
-15.0
|
||||
],
|
||||
"to": [
|
||||
-10.0,
|
||||
10.0,
|
||||
31.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
5.0
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
5.0
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
16
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
16
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
26.0,
|
||||
5.0,
|
||||
-15.0
|
||||
],
|
||||
"to": [
|
||||
30.5,
|
||||
10.0,
|
||||
31.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
5.0
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
5.0
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
16
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.5,
|
||||
16
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,760 @@
|
||||
{
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"ru_khaki": "airdef:block/ru_khaki",
|
||||
"radar_face": "airdef:block/radar_face",
|
||||
"dark_metal": "airdef:block/dark_metal",
|
||||
"tube_cap": "airdef:block/tube_cap",
|
||||
"particle": "airdef:block/ru_khaki"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [
|
||||
-4.0,
|
||||
0.0,
|
||||
-6.0
|
||||
],
|
||||
"to": [
|
||||
20.0,
|
||||
16.0,
|
||||
22.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#ru_khaki"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-2.0,
|
||||
2.0,
|
||||
-11.0
|
||||
],
|
||||
"to": [
|
||||
18.0,
|
||||
15.0,
|
||||
-6.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
13.0
|
||||
],
|
||||
"texture": "#radar_face"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
13.0
|
||||
],
|
||||
"texture": "#radar_face"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
13.0
|
||||
],
|
||||
"texture": "#radar_face"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
5.0,
|
||||
13.0
|
||||
],
|
||||
"texture": "#radar_face"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#radar_face"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
5.0
|
||||
],
|
||||
"texture": "#radar_face"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-3.0,
|
||||
16.0,
|
||||
2.0
|
||||
],
|
||||
"to": [
|
||||
19.0,
|
||||
17.0,
|
||||
20.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
1.0
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
16,
|
||||
16
|
||||
],
|
||||
"texture": "#dark_metal"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-1.0,
|
||||
16.5,
|
||||
4.0
|
||||
],
|
||||
"to": [
|
||||
3.0,
|
||||
17.5,
|
||||
10.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
-1.0,
|
||||
16.5,
|
||||
12.0
|
||||
],
|
||||
"to": [
|
||||
3.0,
|
||||
17.5,
|
||||
18.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
4.0,
|
||||
16.5,
|
||||
4.0
|
||||
],
|
||||
"to": [
|
||||
8.0,
|
||||
17.5,
|
||||
10.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
4.0,
|
||||
16.5,
|
||||
12.0
|
||||
],
|
||||
"to": [
|
||||
8.0,
|
||||
17.5,
|
||||
18.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
9.0,
|
||||
16.5,
|
||||
4.0
|
||||
],
|
||||
"to": [
|
||||
13.0,
|
||||
17.5,
|
||||
10.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
9.0,
|
||||
16.5,
|
||||
12.0
|
||||
],
|
||||
"to": [
|
||||
13.0,
|
||||
17.5,
|
||||
18.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
14.0,
|
||||
16.5,
|
||||
4.0
|
||||
],
|
||||
"to": [
|
||||
18.0,
|
||||
17.5,
|
||||
10.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
14.0,
|
||||
16.5,
|
||||
12.0
|
||||
],
|
||||
"to": [
|
||||
18.0,
|
||||
17.5,
|
||||
18.0
|
||||
],
|
||||
"faces": {
|
||||
"north": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"south": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"east": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"west": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
6.0,
|
||||
1.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"up": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
},
|
||||
"down": {
|
||||
"uv": [
|
||||
0,
|
||||
0,
|
||||
4.0,
|
||||
6.0
|
||||
],
|
||||
"texture": "#tube_cap"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "airdef:item/deploy_buk"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "airdef:item/deploy_depot"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "airdef:item/deploy_ew"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "airdef:item/deploy_irist"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "airdef:item/deploy_light"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "airdef:item/deploy_nasams"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "airdef:item/deploy_p1sun"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "airdef:item/deploy_radar"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "airdef:item/deploy_tor"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "airdef:item/deploy_tzm"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "airdef:item/flare_gun"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "airdef:item/mover"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 342 B |
|
After Width: | Height: | Size: 97 B |
|
After Width: | Height: | Size: 374 B |
|
After Width: | Height: | Size: 328 B |
|
After Width: | Height: | Size: 97 B |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 346 B |
|
After Width: | Height: | Size: 404 B |
|
After Width: | Height: | Size: 397 B |
|
After Width: | Height: | Size: 400 B |
|
After Width: | Height: | Size: 400 B |
|
After Width: | Height: | Size: 388 B |
|
After Width: | Height: | Size: 395 B |
|
After Width: | Height: | Size: 386 B |
|
After Width: | Height: | Size: 403 B |
|
After Width: | Height: | Size: 401 B |
|
After Width: | Height: | Size: 400 B |
|
After Width: | Height: | Size: 386 B |
|
After Width: | Height: | Size: 404 B |
|
Before Width: | Height: | Size: 407 B After Width: | Height: | Size: 411 B |
@@ -0,0 +1,59 @@
|
||||
//! Rough cost of handing 2000 model instances to the game each tick: allocations and bytes the mod
|
||||
//! builds (counting allocator) and the bytes the canonical ABI then copies across (wasm32 layout:
|
||||
//! `model-instance` 64 bytes + its name, `model-instance-id` 56 bytes).
|
||||
//! Run: `cargo run --release --example emit_cost`.
|
||||
use horizon_mod_sdk::render::{ModelInstance, ModelInstanceId};
|
||||
use std::alloc::{GlobalAlloc, Layout, System};
|
||||
use std::sync::atomic::{AtomicUsize, Ordering::Relaxed};
|
||||
|
||||
static COUNT: AtomicUsize = AtomicUsize::new(0);
|
||||
static BYTES: AtomicUsize = AtomicUsize::new(0);
|
||||
struct Counting;
|
||||
unsafe impl GlobalAlloc for Counting {
|
||||
unsafe fn alloc(&self, l: Layout) -> *mut u8 {
|
||||
COUNT.fetch_add(1, Relaxed);
|
||||
BYTES.fetch_add(l.size(), Relaxed);
|
||||
unsafe { System.alloc(l) }
|
||||
}
|
||||
unsafe fn dealloc(&self, p: *mut u8, l: Layout) {
|
||||
unsafe { System.dealloc(p, l) }
|
||||
}
|
||||
}
|
||||
#[global_allocator]
|
||||
static A: Counting = Counting;
|
||||
|
||||
const NAMES: [&str; 4] = ["airdef:shahed", "airdef:geran_2", "airdef:iris_t", "airdef:explosion_core"];
|
||||
|
||||
fn measure(f: impl FnOnce()) -> (usize, usize) {
|
||||
let (c, b) = (COUNT.load(Relaxed), BYTES.load(Relaxed));
|
||||
f();
|
||||
(COUNT.load(Relaxed) - c, BYTES.load(Relaxed) - b)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
const N: usize = 2000;
|
||||
let (mut old, mut by_id): (Vec<ModelInstance>, Vec<ModelInstanceId>) = (Vec::new(), Vec::new());
|
||||
by_id.reserve(N);
|
||||
let inst = |i: usize| (i as u32, NAMES[i % 4], i as f64);
|
||||
let wire_old: usize = (0..N).map(|i| 64 + NAMES[i % 4].len()).sum();
|
||||
let (c, b) = measure(|| {
|
||||
old = (0..N)
|
||||
.map(|i| {
|
||||
let (id, n, x) = inst(i);
|
||||
ModelInstance { id, model: n.to_string(), x, y: x, z: x, rotation: (0., 0., 0., 1.), scale: 1., glow: false }
|
||||
})
|
||||
.collect();
|
||||
});
|
||||
println!("old : {c} allocations, {b} bytes built per tick; {wire_old} bytes across, {N} strings lowered");
|
||||
drop(old);
|
||||
for tick in 0..2 {
|
||||
let (c, b) = measure(|| {
|
||||
by_id.clear();
|
||||
for i in 0..N {
|
||||
let (id, _, x) = inst(i);
|
||||
by_id.push(ModelInstanceId { id, model: (i % 4) as u32, x, y: x, z: x, rotation: (0., 0., 0., 1.), scale: 1., glow: false });
|
||||
}
|
||||
});
|
||||
println!("new : tick {tick}: {c} allocations, {b} bytes built; {} bytes across, no strings", N * 56);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,438 @@
|
||||
//! Headless driver for the pure simulation (`airdef::sim`): builds a scenario, steps the
|
||||
//! simulation like the mod's tick does (answering ground queries from a height function),
|
||||
//! and measures. Shared by the `sim_run` example and `tests/scenarios.rs`.
|
||||
//!
|
||||
//! Native timings say nothing about the WASM build or the GPU; use them to compare runs of the
|
||||
//! same machine.
|
||||
#![allow(dead_code)]
|
||||
use airdef::sim::{Aim, Approach, DroneKind, Ground, Out, RaidOrder, Sam, SamKind, Sim};
|
||||
use glam::DVec3;
|
||||
use std::collections::HashMap;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
/// Height of the land under a column (what `render.ground` would answer).
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum Terrain {
|
||||
Flat(i32),
|
||||
/// Smooth hills: `base + amp * (sin(x/period) + cos(z/period)) / 2`.
|
||||
Hills { base: i32, amp: f64, period: f64 },
|
||||
}
|
||||
|
||||
/// The land as blocks: solid at and below the column's height (what the game would answer `render.sections` with).
|
||||
impl airdef::sim::world::WorldSource for Terrain {
|
||||
fn solid(&self, x: i32, y: i32, z: i32) -> Option<bool> {
|
||||
Some(y < self.height(x, z))
|
||||
}
|
||||
}
|
||||
|
||||
impl Terrain {
|
||||
pub fn height(self, x: i32, z: i32) -> i32 {
|
||||
match self {
|
||||
Terrain::Flat(h) => h,
|
||||
Terrain::Hills { base, amp, period } => {
|
||||
base + (amp * ((f64::from(x) / period).sin() + (f64::from(z) / period).cos()) / 2.0).round() as i32
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RaidSpec {
|
||||
pub kinds: Vec<(DroneKind, u32)>,
|
||||
pub approach: Approach,
|
||||
pub aim: Aim,
|
||||
pub dist: f64,
|
||||
/// The tick the raid is ordered at (a raid waits for the previous one to be sent).
|
||||
pub at: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Unit {
|
||||
pub kind: SamKind,
|
||||
pub pos: DVec3,
|
||||
pub heading: f64,
|
||||
/// Starts with an empty magazine, waiting for a reload (logistics).
|
||||
pub empty: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Scenario {
|
||||
pub name: String,
|
||||
pub seed: u64,
|
||||
pub units: Vec<Unit>,
|
||||
pub objects: Vec<DVec3>,
|
||||
pub raids: Vec<RaidSpec>,
|
||||
pub terrain: Terrain,
|
||||
/// Hard limit of ticks (20 a second).
|
||||
pub ticks: u64,
|
||||
/// Stop as soon as every raid has ended.
|
||||
pub stop_at_end: bool,
|
||||
pub ew: bool,
|
||||
/// Ticks a truck on a job may stand still before it counts as stuck.
|
||||
pub stuck_after: u64,
|
||||
}
|
||||
|
||||
impl Scenario {
|
||||
pub fn new(name: &str) -> Self {
|
||||
Scenario {
|
||||
name: name.into(),
|
||||
seed: 1,
|
||||
units: Vec::new(),
|
||||
objects: vec![DVec3::new(0.0, 70.0, 0.0)],
|
||||
raids: Vec::new(),
|
||||
terrain: Terrain::Flat(70),
|
||||
ticks: 20 * 60 * 10,
|
||||
stop_at_end: true,
|
||||
ew: false,
|
||||
stuck_after: 600,
|
||||
}
|
||||
}
|
||||
pub fn unit(&mut self, kind: SamKind, x: f64, z: f64) -> &mut Unit {
|
||||
self.units.push(Unit { kind, pos: DVec3::new(x, 70.0, z), heading: 0.0, empty: false });
|
||||
self.units.last_mut().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct Report {
|
||||
pub name: String,
|
||||
pub seed: u64,
|
||||
pub ticks_run: u64,
|
||||
pub units: usize,
|
||||
pub launched: u32,
|
||||
pub kills: u32,
|
||||
pub hits: u32,
|
||||
/// Missiles fired by air defence (sum of the systems' `fired`).
|
||||
pub fired: u32,
|
||||
pub ground_queries: u64,
|
||||
/// The block cache's counters (issue #43) and the drones that struck the land (issue #42).
|
||||
pub world: String,
|
||||
pub crashes: u32,
|
||||
/// What went wrong for the air defence, as the raid report words it.
|
||||
pub failures: String,
|
||||
pub ground_batches: u64,
|
||||
pub tick_p50: Duration,
|
||||
pub tick_p95: Duration,
|
||||
pub tick_max: Duration,
|
||||
pub tick_total: Duration,
|
||||
/// Time spent in ticks that began with a raid being planned.
|
||||
pub planning: Duration,
|
||||
pub planning_ticks: u64,
|
||||
pub nan_positions: u64,
|
||||
/// Ids of trucks that stood on a job without progress for too long.
|
||||
pub stuck_trucks: Vec<u32>,
|
||||
/// Truck-ticks spent on a job or driving (shows the logistics actually ran).
|
||||
pub truck_busy_ticks: u64,
|
||||
pub raids_ordered: usize,
|
||||
pub raids_ended: usize,
|
||||
pub all_ended: bool,
|
||||
}
|
||||
|
||||
fn finite(v: DVec3) -> bool {
|
||||
v.x.is_finite() && v.y.is_finite() && v.z.is_finite()
|
||||
}
|
||||
|
||||
pub fn run(sc: &Scenario) -> Report {
|
||||
let mut sim = Sim::new(sc.seed);
|
||||
sim.damage = false; // explosions would change the land the height function describes
|
||||
for u in &sc.units {
|
||||
let id = sim.id();
|
||||
// Systems stand on the land, whatever the layout says.
|
||||
let pos = DVec3::new(u.pos.x, f64::from(sc.terrain.height(u.pos.x.floor() as i32, u.pos.z.floor() as i32)), u.pos.z);
|
||||
let mut s = Sam::new(id, u.kind, pos, u.heading);
|
||||
if u.empty {
|
||||
s.empty = true;
|
||||
s.missiles = 0;
|
||||
}
|
||||
sim.sams.push(s);
|
||||
}
|
||||
sim.targets = sc.objects.iter().map(|o| DVec3::new(o.x, f64::from(sc.terrain.height(o.x.floor() as i32, o.z.floor() as i32)), o.z)).collect();
|
||||
sim.target_health = vec![100.0; sc.objects.len()];
|
||||
if sc.ew {
|
||||
sim.set_ew(true);
|
||||
}
|
||||
let mut ground = Ground::default();
|
||||
let mut pending: Vec<(i32, i32, i32)> = Vec::new();
|
||||
let mut r = Report { name: sc.name.clone(), seed: sc.seed, units: sc.units.len(), ..Default::default() };
|
||||
let mut times: Vec<Duration> = Vec::with_capacity(sc.ticks as usize);
|
||||
let mut ordered = vec![false; sc.raids.len()];
|
||||
let mut launched_before = vec![0u32; sc.raids.len()];
|
||||
let mut ended = vec![false; sc.raids.len()];
|
||||
// truck id -> (last position, ticks standing while busy)
|
||||
let mut standing: HashMap<u32, (DVec3, u64)> = HashMap::new();
|
||||
let mut out = Out::default();
|
||||
for now in 1..=sc.ticks {
|
||||
// Raids come in order: one is ordered once the previous one has been sent.
|
||||
for (i, spec) in sc.raids.iter().enumerate() {
|
||||
if !ordered[i] && now >= spec.at && !sim.planning() && (i == 0 || ended[i - 1]) {
|
||||
let order = RaidOrder { kinds: spec.kinds.clone(), approach: spec.approach, dist: spec.dist, aim: spec.aim };
|
||||
launched_before[i] = sim.launched;
|
||||
let objects = sim.targets.clone();
|
||||
sim.order_raid(&order, &objects, &mut out);
|
||||
ordered[i] = true;
|
||||
}
|
||||
}
|
||||
ground.answer(std::mem::take(&mut pending), now);
|
||||
let planning = sim.planning();
|
||||
out = Out::default();
|
||||
let t = Instant::now();
|
||||
sim.step(&mut ground, None, &mut out);
|
||||
let wanted = ground.take_wanted();
|
||||
let sections = ground.world.take_wanted(now);
|
||||
ground.world.serve(&sc.terrain, sections, now);
|
||||
let dt = t.elapsed();
|
||||
times.push(dt);
|
||||
if planning {
|
||||
r.planning += dt;
|
||||
r.planning_ticks += 1;
|
||||
}
|
||||
if !wanted.is_empty() {
|
||||
r.ground_batches += 1;
|
||||
r.ground_queries += wanted.len() as u64;
|
||||
pending = wanted.into_iter().map(|(x, z)| (x, z, sc.terrain.height(x, z))).collect();
|
||||
}
|
||||
r.ticks_run = now;
|
||||
// NaN check on everything with a position.
|
||||
let bad = sim.drones.iter().filter(|d| !finite(d.pos) || !finite(d.vel)).count()
|
||||
+ sim.missiles.iter().filter(|m| !finite(m.pos)).count()
|
||||
+ sim.sams.iter().filter(|s| !finite(s.pos)).count()
|
||||
+ sim.blasts.iter().filter(|b| !finite(b.at)).count()
|
||||
+ out.models.iter().filter(|m| !finite(m.at)).count();
|
||||
r.nan_positions += bad as u64;
|
||||
// Trucks with a job or on the move, standing still.
|
||||
for s in sim.sams.iter().filter(|s| s.kind == SamKind::Tzm && s.alive()) {
|
||||
let busy = s.moving() || s.job().is_some();
|
||||
r.truck_busy_ticks += u64::from(busy);
|
||||
let e = standing.entry(s.id).or_insert((s.pos, 0));
|
||||
if !busy || e.0.distance(s.pos) > 0.05 {
|
||||
*e = (s.pos, 0);
|
||||
} else {
|
||||
e.1 += 1;
|
||||
if e.1 == sc.stuck_after && !r.stuck_trucks.contains(&s.id) {
|
||||
r.stuck_trucks.push(s.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
// A raid has ended when it was ordered, planned, flown and nothing is left in the air.
|
||||
let quiet = !sim.planning() && sim.queue.is_empty() && !sim.drones.iter().any(|d| d.alive()) && sim.missiles.is_empty();
|
||||
for i in 0..sc.raids.len() {
|
||||
if ordered[i] && !ended[i] && quiet && sim.launched > launched_before[i] {
|
||||
ended[i] = true;
|
||||
}
|
||||
}
|
||||
if sc.stop_at_end && ended.iter().all(|e| *e) && !sc.raids.is_empty() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
r.launched = sim.launched;
|
||||
r.kills = sim.kills;
|
||||
r.hits = sim.hits;
|
||||
r.fired = sim.sams.iter().map(|s| s.fired).sum();
|
||||
r.raids_ordered = ordered.iter().filter(|o| **o).count();
|
||||
r.world = ground.world.text();
|
||||
r.crashes = sim.crashes;
|
||||
r.failures = sim.tally.text();
|
||||
r.raids_ended = ended.iter().filter(|o| **o).count();
|
||||
r.all_ended = r.raids_ended == sc.raids.len();
|
||||
r.tick_total = times.iter().sum();
|
||||
times.sort();
|
||||
if !times.is_empty() {
|
||||
let at = |q: f64| times[((times.len() - 1) as f64 * q).round() as usize];
|
||||
r.tick_p50 = at(0.5);
|
||||
r.tick_p95 = at(0.95);
|
||||
r.tick_max = *times.last().unwrap();
|
||||
}
|
||||
r
|
||||
}
|
||||
|
||||
fn ms(d: Duration) -> f64 {
|
||||
d.as_secs_f64() * 1000.0
|
||||
}
|
||||
|
||||
impl Report {
|
||||
/// Problems that fail a scenario: empty when it is healthy.
|
||||
pub fn problems(&self) -> Vec<String> {
|
||||
let mut p = Vec::new();
|
||||
if self.nan_positions > 0 {
|
||||
p.push(format!("{} non-finite positions", self.nan_positions));
|
||||
}
|
||||
if !self.stuck_trucks.is_empty() {
|
||||
p.push(format!("stuck trucks: {:?}", self.stuck_trucks));
|
||||
}
|
||||
if !self.all_ended {
|
||||
p.push(format!("{} of {} raids ended in {} ticks", self.raids_ended, self.raids_ended.max(self.raids_ordered), self.ticks_run));
|
||||
}
|
||||
p
|
||||
}
|
||||
pub fn text(&self) -> String {
|
||||
format!(
|
||||
"scenario {name} (seed {seed}): {units} units, {ticks} ticks ({secs:.0} s of game time)\n\
|
||||
raids: {ro} ordered, {re} ended\n\
|
||||
launched {l}, shot down {k}, got through {h}, air-defence missiles fired {f}\n\
|
||||
tick time ms: p50 {p50:.3} p95 {p95:.3} max {max:.3} total {tot:.0}\n\
|
||||
planning: {pl:.1} ms over {pt} ticks\n\
|
||||
ground queries: {gq} in {gb} batches\n\
|
||||
non-finite positions: {nan}\n\
|
||||
stuck trucks: {stuck:?} (busy truck-ticks {busy})\n\
|
||||
crashes into the land: {crashes}; {world}\n\
|
||||
air-defence failures: {failures}\n",
|
||||
name = self.name,
|
||||
seed = self.seed,
|
||||
units = self.units,
|
||||
ticks = self.ticks_run,
|
||||
secs = self.ticks_run as f64 / 20.0,
|
||||
ro = self.raids_ordered,
|
||||
re = self.raids_ended,
|
||||
l = self.launched,
|
||||
k = self.kills,
|
||||
h = self.hits,
|
||||
f = self.fired,
|
||||
p50 = ms(self.tick_p50),
|
||||
p95 = ms(self.tick_p95),
|
||||
max = ms(self.tick_max),
|
||||
tot = ms(self.tick_total),
|
||||
pl = ms(self.planning),
|
||||
pt = self.planning_ticks,
|
||||
gq = self.ground_queries,
|
||||
gb = self.ground_batches,
|
||||
nan = self.nan_positions,
|
||||
stuck = self.stuck_trucks,
|
||||
busy = self.truck_busy_ticks,
|
||||
crashes = self.crashes,
|
||||
world = self.world,
|
||||
failures = if self.failures.is_empty() { "none" } else { &self.failures },
|
||||
)
|
||||
}
|
||||
pub fn json(&self) -> String {
|
||||
format!(
|
||||
"{{\"scenario\":{:?},\"seed\":{},\"units\":{},\"ticks\":{},\"raids_ordered\":{},\"raids_ended\":{},\
|
||||
\"launched\":{},\"kills\":{},\"hits\":{},\"fired\":{},\
|
||||
\"tick_ms\":{{\"p50\":{:.4},\"p95\":{:.4},\"max\":{:.4},\"total\":{:.2}}},\
|
||||
\"planning_ms\":{:.2},\"planning_ticks\":{},\"ground_queries\":{},\"ground_batches\":{},\
|
||||
\"nan_positions\":{},\"stuck_trucks\":{:?},\"truck_busy_ticks\":{}}}",
|
||||
self.name,
|
||||
self.seed,
|
||||
self.units,
|
||||
self.ticks_run,
|
||||
self.raids_ordered,
|
||||
self.raids_ended,
|
||||
self.launched,
|
||||
self.kills,
|
||||
self.hits,
|
||||
self.fired,
|
||||
ms(self.tick_p50),
|
||||
ms(self.tick_p95),
|
||||
ms(self.tick_max),
|
||||
ms(self.tick_total),
|
||||
ms(self.planning),
|
||||
self.planning_ticks,
|
||||
self.ground_queries,
|
||||
self.ground_batches,
|
||||
self.nan_positions,
|
||||
self.stuck_trucks,
|
||||
self.truck_busy_ticks,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------ ready-made scenarios
|
||||
|
||||
fn ring(sc: &mut Scenario, kinds: &[SamKind], count: usize, r0: f64, r1: f64) {
|
||||
for i in 0..count {
|
||||
let a = i as f64 * 2.399_963; // golden angle: an even spread without randomness
|
||||
let r = r0 + (r1 - r0) * (i as f64 / count.max(1) as f64);
|
||||
let kind = kinds[i % kinds.len()];
|
||||
sc.unit(kind, a.sin() * r, a.cos() * r).heading = a;
|
||||
}
|
||||
}
|
||||
|
||||
/// A big smart raid on 61 systems.
|
||||
pub fn big_smart() -> Scenario {
|
||||
let mut sc = Scenario::new("big-smart");
|
||||
sc.terrain = Terrain::Hills { base: 70, amp: 14.0, period: 90.0 };
|
||||
for (x, z) in [(0.0, 0.0), (120.0, 80.0), (-150.0, -60.0)] {
|
||||
sc.objects.push(DVec3::new(x, 70.0, z));
|
||||
}
|
||||
ring(&mut sc, &[SamKind::Radar], 6, 150.0, 500.0);
|
||||
ring(&mut sc, &[SamKind::Ew], 2, 100.0, 300.0);
|
||||
ring(&mut sc, &SamKind::ARMED, 53, 60.0, 450.0);
|
||||
assert_eq!(sc.units.len(), 61);
|
||||
sc.raids.push(RaidSpec {
|
||||
kinds: vec![
|
||||
(DroneKind::Gerbera, 8),
|
||||
(DroneKind::Shahed, 12),
|
||||
(DroneKind::Geran3, 4),
|
||||
(DroneKind::Lancet, 4),
|
||||
(DroneKind::Kh101, 4),
|
||||
(DroneKind::Kalibr, 4),
|
||||
(DroneKind::Iskander, 2),
|
||||
],
|
||||
approach: Approach::AllSides,
|
||||
aim: Aim::Smart,
|
||||
dist: 500.0,
|
||||
at: 1,
|
||||
});
|
||||
sc.ticks = 20 * 60 * 8;
|
||||
sc
|
||||
}
|
||||
|
||||
/// Trucks and a depot supplying systems that start with empty magazines, under a raid.
|
||||
pub fn logistics() -> Scenario {
|
||||
let mut sc = Scenario::new("logistics");
|
||||
sc.unit(SamKind::Radar, 0.0, -40.0);
|
||||
sc.unit(SamKind::Depot, 300.0, 300.0);
|
||||
for (x, z) in [(310.0, 320.0), (290.0, 330.0)] {
|
||||
sc.unit(SamKind::Tzm, x, z);
|
||||
}
|
||||
sc.unit(SamKind::Tzm, 280.0, 280.0);
|
||||
for (i, kind) in [SamKind::Patriot, SamKind::Tor, SamKind::Buk, SamKind::Nasams, SamKind::Pantsir, SamKind::S400].into_iter().enumerate() {
|
||||
let a = i as f64 * 1.05;
|
||||
let u = sc.unit(kind, a.sin() * 120.0, a.cos() * 120.0);
|
||||
// Every other system starts out of missiles: the trucks have work from the first second.
|
||||
u.empty = i % 2 == 0;
|
||||
}
|
||||
sc.raids.push(RaidSpec {
|
||||
kinds: vec![(DroneKind::Shahed, 16), (DroneKind::Gerbera, 8), (DroneKind::Kh101, 3)],
|
||||
approach: Approach::TwoSectors,
|
||||
aim: Aim::Objects,
|
||||
dist: 400.0,
|
||||
at: 1,
|
||||
});
|
||||
sc.ticks = 20 * 60 * 6;
|
||||
sc
|
||||
}
|
||||
|
||||
/// EW stations on and a smart enemy that adapts over three raids.
|
||||
pub fn ew_adaptive() -> Scenario {
|
||||
let mut sc = Scenario::new("ew-adaptive");
|
||||
sc.ew = true;
|
||||
sc.unit(SamKind::Radar, 0.0, 0.0);
|
||||
sc.unit(SamKind::Radar, 200.0, -200.0);
|
||||
sc.unit(SamKind::Ew, 80.0, 0.0);
|
||||
sc.unit(SamKind::Ew, -80.0, 60.0);
|
||||
for (i, kind) in [SamKind::Pantsir, SamKind::Gepard, SamKind::Tor, SamKind::Patriot, SamKind::Buk, SamKind::Gepard].into_iter().enumerate() {
|
||||
let a = i as f64 * 1.05;
|
||||
sc.unit(kind, a.sin() * 150.0, a.cos() * 150.0);
|
||||
}
|
||||
for at in [1, 1, 1] {
|
||||
sc.raids.push(RaidSpec {
|
||||
kinds: vec![(DroneKind::Gerbera, 6), (DroneKind::Shahed, 10), (DroneKind::Kh101, 4), (DroneKind::Kalibr, 3)],
|
||||
approach: Approach::AllSides,
|
||||
aim: Aim::Smart,
|
||||
dist: 450.0,
|
||||
at,
|
||||
});
|
||||
}
|
||||
sc.ticks = 20 * 60 * 12;
|
||||
sc
|
||||
}
|
||||
|
||||
pub fn preset(name: &str) -> Option<Scenario> {
|
||||
match name {
|
||||
"big-smart" => Some(big_smart()),
|
||||
"logistics" => Some(logistics()),
|
||||
"ew-adaptive" => Some(ew_adaptive()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
pub const PRESETS: [&str; 3] = ["big-smart", "logistics", "ew-adaptive"];
|
||||
@@ -0,0 +1,156 @@
|
||||
//! Native headless runner for the simulation.
|
||||
//!
|
||||
//! cargo run --release --example sim_run -- [options]
|
||||
//!
|
||||
//! Options (all optional; a preset gives the defaults, the others override it):
|
||||
//! --scenario NAME big-smart | logistics | ew-adaptive (default big-smart)
|
||||
//! --seed N random seed
|
||||
//! --layout FILE systems from a text file, replacing the preset's; one per line:
|
||||
//! `KIND X Z [HEADING_RAD] [empty]` (`#` starts a comment)
|
||||
//! KIND is a system key (patriot, tor, radar, depot, tzm, ew, ...)
|
||||
//! --raid SPEC replaces the preset's raids; repeatable. SPEC is
|
||||
//! `kind=count,kind=count[;dist=500][;aim=smart|objects|sams][;approach=sector|two|all|waves][;at=TICK]`
|
||||
//! --terrain T flat[:HEIGHT] | hills[:BASE:AMP:PERIOD]
|
||||
//! --ticks N tick limit (20 a second)
|
||||
//! --run-on do not stop when the raids have ended
|
||||
//! --ew / --no-ew EW stations on or off
|
||||
//! --json one JSON object instead of text
|
||||
//! --list list scenarios, system and drone kinds
|
||||
//! Exit code 1 when the run has problems (NaN positions, stuck trucks, a raid that never ended).
|
||||
//! Native timings are for comparing runs on one machine, not an estimate of WASM/GPU cost.
|
||||
mod harness;
|
||||
use airdef::sim::{Aim, Approach, DroneKind, SamKind};
|
||||
use glam::DVec3;
|
||||
use harness::*;
|
||||
|
||||
fn die(msg: &str) -> ! {
|
||||
eprintln!("sim_run: {msg}");
|
||||
std::process::exit(2);
|
||||
}
|
||||
|
||||
fn parse_raid(spec: &str) -> RaidSpec {
|
||||
let mut r = RaidSpec { kinds: Vec::new(), approach: Approach::Sector, aim: Aim::Smart, dist: 400.0, at: 1 };
|
||||
for (i, part) in spec.split(';').enumerate() {
|
||||
if i == 0 {
|
||||
for kc in part.split(',').filter(|s| !s.is_empty()) {
|
||||
let (k, c) = kc.split_once('=').unwrap_or_else(|| die(&format!("raid kind `{kc}` needs =count")));
|
||||
let kind = DroneKind::from_key(k).unwrap_or_else(|| die(&format!("unknown drone kind `{k}` (see --list)")));
|
||||
r.kinds.push((kind, c.parse().unwrap_or_else(|_| die(&format!("bad count `{c}`")))));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
let (k, v) = part.split_once('=').unwrap_or_else(|| die(&format!("bad raid option `{part}`")));
|
||||
match k {
|
||||
"dist" => r.dist = v.parse().unwrap_or_else(|_| die("bad dist")),
|
||||
"at" => r.at = v.parse().unwrap_or_else(|_| die("bad at")),
|
||||
"aim" => {
|
||||
r.aim = match v {
|
||||
"smart" => Aim::Smart,
|
||||
"objects" => Aim::Objects,
|
||||
"sams" => Aim::ObjectsAndSams,
|
||||
_ => die("aim: smart | objects | sams"),
|
||||
}
|
||||
}
|
||||
"approach" => {
|
||||
r.approach = match v {
|
||||
"sector" => Approach::Sector,
|
||||
"two" => Approach::TwoSectors,
|
||||
"all" => Approach::AllSides,
|
||||
"waves" => Approach::Waves,
|
||||
_ => die("approach: sector | two | all | waves"),
|
||||
}
|
||||
}
|
||||
_ => die(&format!("unknown raid option `{k}`")),
|
||||
}
|
||||
}
|
||||
r
|
||||
}
|
||||
|
||||
fn parse_terrain(t: &str) -> Terrain {
|
||||
let n: Vec<&str> = t.split(':').collect();
|
||||
let num = |i: usize, d: f64| n.get(i).map_or(d, |s| s.parse().unwrap_or_else(|_| die("bad terrain number")));
|
||||
match n[0] {
|
||||
"flat" => Terrain::Flat(num(1, 70.0) as i32),
|
||||
"hills" => Terrain::Hills { base: num(1, 70.0) as i32, amp: num(2, 14.0), period: num(3, 90.0) },
|
||||
_ => die("terrain: flat[:H] | hills[:BASE:AMP:PERIOD]"),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_layout(path: &str) -> Vec<Unit> {
|
||||
let text = std::fs::read_to_string(path).unwrap_or_else(|e| die(&format!("{path}: {e}")));
|
||||
let mut units = Vec::new();
|
||||
for (n, line) in text.lines().enumerate() {
|
||||
let line = line.split('#').next().unwrap_or("").trim();
|
||||
if line.is_empty() {
|
||||
continue;
|
||||
}
|
||||
let w: Vec<&str> = line.split_whitespace().collect();
|
||||
let bad = || die(&format!("{path}:{}: expected `KIND X Z [HEADING] [empty]`", n + 1));
|
||||
if w.len() < 3 {
|
||||
bad();
|
||||
}
|
||||
let kind = SamKind::from_key(w[0]).unwrap_or_else(|| die(&format!("{path}:{}: unknown system `{}`", n + 1, w[0])));
|
||||
let f = |s: &str| s.parse::<f64>().unwrap_or_else(|_| bad());
|
||||
let heading = w.get(3).filter(|s| **s != "empty").map_or(0.0, |s| f(s));
|
||||
units.push(Unit { kind, pos: DVec3::new(f(w[1]), 70.0, f(w[2])), heading, empty: w.contains(&"empty") });
|
||||
}
|
||||
units
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = std::env::args().skip(1).collect();
|
||||
let mut name = "big-smart".to_string();
|
||||
let mut i = 0;
|
||||
// The scenario first, so the other options override it whatever their order.
|
||||
while i < args.len() {
|
||||
if args[i] == "--scenario" {
|
||||
name = args.get(i + 1).cloned().unwrap_or_else(|| die("--scenario needs a name"));
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
let mut sc = preset(&name).unwrap_or_else(|| die(&format!("unknown scenario `{name}`; one of {PRESETS:?}")));
|
||||
let (mut json, mut raids) = (false, Vec::new());
|
||||
let mut it = args.iter();
|
||||
while let Some(arg) = it.next() {
|
||||
let mut value = || it.next().cloned().unwrap_or_else(|| die(&format!("{arg} needs a value")));
|
||||
match arg.as_str() {
|
||||
"--scenario" => {
|
||||
value();
|
||||
}
|
||||
"--seed" => sc.seed = value().parse().unwrap_or_else(|_| die("bad seed")),
|
||||
"--ticks" => sc.ticks = value().parse().unwrap_or_else(|_| die("bad ticks")),
|
||||
"--layout" => sc.units = parse_layout(&value()),
|
||||
"--raid" => raids.push(parse_raid(&value())),
|
||||
"--terrain" => sc.terrain = parse_terrain(&value()),
|
||||
"--run-on" => sc.stop_at_end = false,
|
||||
"--ew" => sc.ew = true,
|
||||
"--no-ew" => sc.ew = false,
|
||||
"--json" => json = true,
|
||||
"--list" => {
|
||||
println!("scenarios: {PRESETS:?}");
|
||||
println!("systems: {:?}", SamKind::ALL.iter().map(|k| k.key()).collect::<Vec<_>>());
|
||||
println!("drones: {:?}", DroneKind::ALL.iter().map(|k| k.spec().key).collect::<Vec<_>>());
|
||||
return;
|
||||
}
|
||||
"-h" | "--help" => {
|
||||
println!("{}", include_str!("main.rs").lines().take_while(|l| l.starts_with("//")).map(|l| l.trim_start_matches("//!").trim_start_matches("//").to_string() + "\n").collect::<String>());
|
||||
return;
|
||||
}
|
||||
other => die(&format!("unknown option `{other}` (try --help)")),
|
||||
}
|
||||
}
|
||||
if !raids.is_empty() {
|
||||
sc.raids = raids;
|
||||
}
|
||||
let r = run(&sc);
|
||||
if json {
|
||||
println!("{}", r.json());
|
||||
} else {
|
||||
print!("{}", r.text());
|
||||
}
|
||||
let problems = r.problems();
|
||||
if !problems.is_empty() {
|
||||
eprintln!("PROBLEMS: {}", problems.join("; "));
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
// [0] now (mod ticks), blasts, lights, -
|
||||
// [1 + 2i], [2 + 2i] blast i: x, y, z, size | start tick, life ticks, kind, -
|
||||
// [97 + 2j], [98 + 2j] light j: x, y, z, radius | r, g, b, intensity
|
||||
// [255].x hold: 0 live; a replay's share of the frame's partial tick it does not advance with
|
||||
|
||||
const BLAST_BASE: i32 = 1;
|
||||
const LIGHT_BASE: i32 = 97;
|
||||
@@ -59,8 +60,28 @@ fn screen_radius(world: vec3<f32>, radius: f32) -> f32 {
|
||||
return length((b.xy - a.xy) * frame.resolution.xy);
|
||||
}
|
||||
|
||||
// The clip-space position of a world point (what `project` starts from).
|
||||
fn clip_of(world: vec3<f32>) -> vec4<f32> {
|
||||
return frame.view_proj * vec4<f32>(world - frame.camera.xyz, 1.0);
|
||||
}
|
||||
|
||||
// A clip position on the screen in uv.
|
||||
fn clip_uv(c: vec4<f32>) -> vec2<f32> {
|
||||
let ndc = c.xy / max(abs(c.w), 1e-5);
|
||||
return vec2<f32>(ndc.x * 0.5 + 0.5, 0.5 - ndc.y * 0.5);
|
||||
}
|
||||
|
||||
// `screen_radius` for a point whose clip position is known (the projection is linear,
|
||||
// so the offset to the right is added in clip space): saves two projections and a matrix
|
||||
// product for every effect at every pixel.
|
||||
fn screen_radius_clip(c0: vec4<f32>, radius: f32) -> f32 {
|
||||
let right = frame.view_inverse[0].xyz;
|
||||
let cb = c0 + frame.view_proj * vec4<f32>(right * radius, 0.0);
|
||||
return length((clip_uv(cb) - clip_uv(c0)) * frame.resolution.xy);
|
||||
}
|
||||
|
||||
fn now() -> f32 {
|
||||
return frame.params[0].x + frame.time.y;
|
||||
return frame.params[0].x + frame.time.y * (1.0 - frame.params[255].x);
|
||||
}
|
||||
|
||||
// Fire's colour from its heat (0 cold soot .. 1 white-hot).
|
||||
@@ -86,22 +107,27 @@ fn post(uv: vec2<f32>, pixel: vec2<f32>) -> vec4<f32> {
|
||||
let b = frame.params[BLAST_BASE + 2 * i + 1];
|
||||
let age = t_now - b.x;
|
||||
if age < 0.0 { continue; }
|
||||
// Past both windows (the ring's second, the haze over a hot ball) it bends nothing.
|
||||
let heat = 1.0 - smoothstep(0.0, 0.5, age / b.y);
|
||||
if age >= 24.0 && heat <= 0.0 { continue; }
|
||||
let centre = a.xyz;
|
||||
let p = project(centre);
|
||||
if p.z <= 0.5 { continue; }
|
||||
let to = px - p.xy * frame.resolution.xy;
|
||||
let c0 = clip_of(centre);
|
||||
if c0.w <= 0.5 { continue; }
|
||||
let to = px - clip_uv(c0) * frame.resolution.xy;
|
||||
let dist = length(to);
|
||||
// The shock: a ring racing out, fading in a second.
|
||||
if age < 24.0 {
|
||||
let ring = screen_radius(centre, age * 3.2 * (0.6 + a.w * 0.1));
|
||||
let ring = screen_radius_clip(c0, age * 3.2 * (0.6 + a.w * 0.1));
|
||||
let width = 6.0 + ring * 0.08;
|
||||
let x = (dist - ring) / width;
|
||||
let strength = (1.0 - age / 24.0) * min(a.w / 4.0, 2.0) * 10.0;
|
||||
offset += normalize(to + vec2<f32>(1e-4)) * exp(-x * x) * x * strength * frame.resolution.zw;
|
||||
// exp(-x * x) * x is below 1e-8 past six widths.
|
||||
if abs(x) < 6.0 {
|
||||
let strength = (1.0 - age / 24.0) * min(a.w / 4.0, 2.0) * 10.0;
|
||||
offset += normalize(to + vec2<f32>(1e-4)) * exp(-x * x) * x * strength * frame.resolution.zw;
|
||||
}
|
||||
}
|
||||
// Heat haze over a hot fireball.
|
||||
let heat = 1.0 - smoothstep(0.0, 0.5, age / b.y);
|
||||
let r = screen_radius(centre, a.w * 2.0);
|
||||
let r = screen_radius_clip(c0, a.w * 2.0);
|
||||
if heat > 0.0 && dist < r {
|
||||
let n = noise3(vec3<f32>(px * 0.04, t_now * 0.35)) - 0.5;
|
||||
offset += vec2<f32>(n, -abs(n)) * heat * (1.0 - dist / r) * 6.0 * frame.resolution.zw;
|
||||
@@ -115,7 +141,8 @@ fn post(uv: vec2<f32>, pixel: vec2<f32>) -> vec4<f32> {
|
||||
// the pixel sees, much stronger at night.
|
||||
let night = clamp(0.35 - frame.time.z * 1.8, 0.0, 1.0);
|
||||
let strength = mix(0.35, 2.2, night);
|
||||
if wall < 1.0e5 {
|
||||
// Under the HD lighting (params[0].w) the engine lights the world from the same lights.
|
||||
if wall < 1.0e5 && frame.params[0].w < 0.5 {
|
||||
let p = dir * wall;
|
||||
var light = vec3<f32>(0.0);
|
||||
for (var i = 0; i < blasts; i++) {
|
||||
@@ -148,8 +175,23 @@ fn post(uv: vec2<f32>, pixel: vec2<f32>) -> vec4<f32> {
|
||||
let age = t_now - b.x;
|
||||
if age < 0.0 { continue; }
|
||||
let life = b.y;
|
||||
// Burnt out: no density and no fire light.
|
||||
if age >= life { continue; }
|
||||
let k = clamp(age / life, 0.0, 1.0);
|
||||
let size = a.w;
|
||||
// The ball and its smoke stay inside 4.5 sizes of the blast (radius 2.28 sizes, risen
|
||||
// 2.2 sizes): rays that miss that sphere cannot reach the volume. Only the
|
||||
// pixels' own direction is needed, no volume maths.
|
||||
let rel = a.xyz - frame.camera.xyz;
|
||||
let reach = size * 4.5 + 0.1;
|
||||
let cc = dot(rel, rel);
|
||||
let along = dot(rel, dir);
|
||||
if cc > reach * reach && (along < 0.0 || cc - along * along > reach * reach) {
|
||||
// Out of reach of the volume; the fire's glow still counts.
|
||||
let h0 = 1.0 - smoothstep(0.05, 0.55, k);
|
||||
glow += vec3<f32>(1.0, 0.5, 0.15) * h0 * h0 * size * 0.05 / (1.0 + length(rel + vec3<f32>(0.0, k * k * size * 2.2, 0.0)) * 0.03);
|
||||
continue;
|
||||
}
|
||||
let seed = vec3<f32>(a.x * 0.37, a.y * 0.11, a.z * 0.53);
|
||||
// The ball swells fast, then rises and spreads as smoke.
|
||||
let radius = size * (0.3 + 0.9 * (1.0 - exp(-age / 3.0))) * (1.0 + k * 0.9);
|
||||
@@ -160,7 +202,9 @@ fn post(uv: vec2<f32>, pixel: vec2<f32>) -> vec4<f32> {
|
||||
let t1 = min(span.y, wall);
|
||||
if t1 <= t0 { continue; }
|
||||
let heat = 1.0 - smoothstep(0.05, 0.55, k);
|
||||
let fade = 1.0 - smoothstep(0.65, 1.0, k);
|
||||
// With the HD renderer's volumetric smoke (params[0].w = 2) only the fireball is drawn here.
|
||||
var fade = 1.0 - smoothstep(0.65, 1.0, k);
|
||||
if frame.params[0].w > 1.5 { fade = 1.0 - smoothstep(0.08, 0.28, k); }
|
||||
// Fewer steps for a fireball that is small on screen.
|
||||
let on_screen = radius / max(length(centre), 1.0);
|
||||
let steps = i32(clamp(on_screen * 40.0, 6.0, 14.0));
|
||||
@@ -188,31 +232,67 @@ fn post(uv: vec2<f32>, pixel: vec2<f32>) -> vec4<f32> {
|
||||
}
|
||||
color = color * trans + lit;
|
||||
|
||||
// 3. Flashes: a bright bloom at the blast and the whole view lit up for a moment.
|
||||
// 3. Flashes (#51): a huge bright bloom at the blast, a wide halo that lifts the sky and the
|
||||
// clouds, a white shock ring racing out, and the view lit up for a moment. The sum is
|
||||
// squashed, so a crowded sky never whites the screen out for long.
|
||||
var flare = vec3<f32>(0.0);
|
||||
for (var i = 0; i < blasts; i++) {
|
||||
let a = frame.params[BLAST_BASE + 2 * i];
|
||||
let b = frame.params[BLAST_BASE + 2 * i + 1];
|
||||
let age = t_now - b.x;
|
||||
if age < 0.0 || age > 10.0 { continue; }
|
||||
let p = project(a.xyz);
|
||||
if p.z <= 0.5 { continue; }
|
||||
let visible = select(0.25, 1.0, scene_distance(p.xy) > p.z - a.w);
|
||||
let f = exp(-age * 0.7) * min(a.w / 4.0, 2.5) * visible;
|
||||
let r = screen_radius(a.xyz, a.w * 2.5) + 20.0;
|
||||
let dd = length(px - p.xy * frame.resolution.xy) / r;
|
||||
color += vec3<f32>(1.0, 0.85, 0.6) * f * (exp(-dd * dd * 3.0) * 2.5 + exp(-dd * 0.8) * 0.25);
|
||||
color += vec3<f32>(1.0, 0.8, 0.55) * f * 0.12 / (1.0 + p.z * 0.01);
|
||||
if age < 0.0 || age > 24.0 { continue; }
|
||||
let c0 = clip_of(a.xyz);
|
||||
if c0.w <= 0.5 { continue; }
|
||||
let p = vec3<f32>(clip_uv(c0), c0.w);
|
||||
// Ray distance on both sides: `p.z` is the depth along the view axis, which is shorter
|
||||
// than the distance along the ray towards the screen edge.
|
||||
let dist = length(a.xyz - frame.camera.xyz);
|
||||
let visible = select(0.25, 1.0, scene_distance(p.xy) > dist - a.w);
|
||||
let mass = min(a.w / 4.0, 2.5);
|
||||
// How close it is, in its own sizes: a burst overhead is felt, a far one only seen.
|
||||
let near = clamp(1.0 - dist / (a.w * 40.0), 0.0, 1.0);
|
||||
let centre = p.xy * frame.resolution.xy;
|
||||
if age <= 10.0 {
|
||||
let f = exp(-age * 0.7) * mass * visible;
|
||||
let r = screen_radius_clip(c0, a.w * 2.5) + 20.0;
|
||||
let dd = length(px - centre) / r;
|
||||
// The bloom's tail is below 5e-4 (under 8 bits) past nine radii.
|
||||
if dd < 9.0 {
|
||||
flare += vec3<f32>(1.0, 0.85, 0.6) * f * (exp(-dd * dd * 3.0) * 3.2 + exp(-dd * 0.8) * 0.3);
|
||||
}
|
||||
// The halo: a third of the screen wide for a close blast, lifting the sky and clouds most.
|
||||
let wide = (0.12 + 0.3 * near) * frame.resolution.y;
|
||||
let dw = length(px - centre) / wide;
|
||||
if dw < 4.0 {
|
||||
let sky = select(1.0, 1.7, wall > 1.0e5);
|
||||
flare += vec3<f32>(1.0, 0.82, 0.58) * f * near * sky * exp(-dw * dw) * 0.55;
|
||||
}
|
||||
flare += vec3<f32>(1.0, 0.8, 0.55) * f * (0.12 + 0.2 * near) / (1.0 + p.z * 0.01);
|
||||
}
|
||||
// The shock ring: the same radius as the wave that bends the picture.
|
||||
let ring = screen_radius_clip(c0, age * 3.2 * (0.6 + a.w * 0.1));
|
||||
let width = 3.0 + ring * 0.025;
|
||||
let x = (length(px - centre) - ring) / width;
|
||||
if abs(x) < 4.0 {
|
||||
let fade = 1.0 - age / 24.0;
|
||||
flare += vec3<f32>(1.0, 0.9, 0.72) * exp(-x * x) * fade * fade * mass * (0.25 + 0.5 * near) * visible;
|
||||
}
|
||||
}
|
||||
color += flare / (1.0 + flare * 0.2);
|
||||
|
||||
// 4. Glows: engine flames and muzzle flashes.
|
||||
for (var j = 0; j < lights; j++) {
|
||||
let a = frame.params[LIGHT_BASE + 2 * j];
|
||||
let b = frame.params[LIGHT_BASE + 2 * j + 1];
|
||||
let p = project(a.xyz);
|
||||
if p.z <= 0.3 { continue; }
|
||||
if scene_distance(p.xy) < p.z - a.w * 1.5 { continue; }
|
||||
let r = screen_radius(a.xyz, a.w) + 3.0;
|
||||
let dd = length(px - p.xy * frame.resolution.xy) / r;
|
||||
let c0 = clip_of(a.xyz);
|
||||
if c0.w <= 0.3 { continue; }
|
||||
let p = clip_uv(c0);
|
||||
let r = screen_radius_clip(c0, a.w) + 3.0;
|
||||
let dd = length(px - p * frame.resolution.xy) / r;
|
||||
// Far from the glow (intensity at most 2): its tail is below 5e-4, under 8 bits.
|
||||
// This is checked before the depth lookup, which most pixels then never make.
|
||||
if dd > 6.0 { continue; }
|
||||
if scene_distance(p) < length(a.xyz - frame.camera.xyz) - a.w * 1.5 { continue; }
|
||||
let flicker = 0.85 + 0.15 * noise3(vec3<f32>(a.xyz * 0.7 + vec3<f32>(t_now * 1.3)));
|
||||
color += b.rgb * b.w * flicker * (exp(-dd * dd * 4.0) * 1.2 + exp(-dd * 1.2) * 0.18);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
//! The cinematic look of a blast (#51): a layered sound (a close crack, a low thump, a rolling
|
||||
//! tail; from afar the muffled report and a late boom), and the camera's reaction (a brief
|
||||
//! exposure and bloom punch). Everything is a function of the blast, its distance and its age, so
|
||||
//! a replay hears and sees the same as the live raid did, from the replay's camera.
|
||||
|
||||
/// The power (0 air burst .. 4 ballistic) of a blast sound event, if it is one.
|
||||
pub fn blast_power(event: &str) -> Option<usize> {
|
||||
Some(match event {
|
||||
"airdef:blast.air" => 0,
|
||||
"airdef:blast.medium" => 1,
|
||||
"airdef:blast.big" => 2,
|
||||
"airdef:blast.heavy" => 3,
|
||||
"airdef:blast.huge" => 4,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
/// One voice of a blast: the sound event (with `_far` where the listener is far), its loudness
|
||||
/// and pitch, and the ticks it follows the first after the sound has travelled.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Layer {
|
||||
pub name: String,
|
||||
pub volume: f32,
|
||||
pub pitch: f32,
|
||||
pub delay: u64,
|
||||
}
|
||||
|
||||
/// Blasts of one tick that get all their layers, the nearest first: the rest of a mass raid
|
||||
/// plays its one voice, so the key events are not buried and the mix does not clip.
|
||||
pub const FULL: usize = 3;
|
||||
|
||||
/// The voices of a blast of `power`, `dist` blocks from the listener (`far`: where the muffled
|
||||
/// variants take over), `gain` its loudness (1 normal; bigger warheads more), the `rank`-th
|
||||
/// nearest of its tick.
|
||||
pub fn layers(power: usize, dist: f64, far: f64, gain: f32, pitch: f32, rank: usize) -> Vec<Layer> {
|
||||
let g = gain.clamp(0.3, 2.0);
|
||||
let own = ["airdef:blast.air", "airdef:blast.medium", "airdef:blast.big", "airdef:blast.heavy", "airdef:blast.huge"][power.min(4)];
|
||||
let layer = |name: &str, volume: f32, pitch: f32, delay: u64| Layer { name: name.to_string(), volume, pitch, delay };
|
||||
let far_away = dist > far;
|
||||
let suffix = if far_away { "_far" } else { "" };
|
||||
if rank >= FULL {
|
||||
return vec![layer(&format!("{own}{suffix}"), g, pitch, 0)];
|
||||
}
|
||||
if far_away {
|
||||
// The muffled report, then a deep boom that arrives late.
|
||||
return vec![
|
||||
layer(&format!("{own}_far"), g, pitch, 0),
|
||||
layer("airdef:blast.big_far", 0.7 * g, pitch * 0.6, 10 + 2 * power as u64),
|
||||
];
|
||||
}
|
||||
let tail = (0.45 + 0.08 * power as f32) * g;
|
||||
if power == 0 {
|
||||
// An air burst has no body of its own: the crack, the thump, the roll.
|
||||
vec![
|
||||
layer("airdef:blast.air", g, pitch * 1.12, 0),
|
||||
layer("airdef:blast.big", 0.85 * g, pitch * 0.66, 2),
|
||||
layer("airdef:blast.huge", tail, pitch * 0.5, 7),
|
||||
]
|
||||
} else {
|
||||
vec![
|
||||
layer(own, g, pitch, 0),
|
||||
layer("airdef:blast.air", 0.7 * g, pitch * 1.15, 0),
|
||||
layer("airdef:blast.huge", tail, pitch * 0.5, 7),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
/// How hard the picture is punched now (0 to 1) by a blast of fireball radius `size` that went
|
||||
/// off `age` ticks ago `dist` blocks from the camera: bright and brief, near and big blasts most.
|
||||
pub fn punch(size: f32, age: f32, dist: f64) -> f32 {
|
||||
if age < 0.0 {
|
||||
return 0.0;
|
||||
}
|
||||
let reach = (size as f64 * 45.0).max(30.0);
|
||||
let near = (1.0 - dist / reach).clamp(0.0, 1.0) as f32;
|
||||
let big = (size / 8.0).clamp(0.35, 1.0);
|
||||
// A rise over a tick, then gone in about half a second.
|
||||
(near * big * (-age / 3.0).exp() * (age / 0.8).min(1.0)).clamp(0.0, 1.0)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn a_near_intercept_is_layered_and_a_mass_raid_is_bounded() {
|
||||
let l = layers(0, 40.0, 140.0, 1.2, 1.0, 0);
|
||||
assert_eq!(l.len(), 3);
|
||||
assert!(l.iter().all(|v| !v.name.ends_with("_far")));
|
||||
assert!(l[0].delay == 0 && l[2].delay > l[1].delay, "crack, then thump, then the roll");
|
||||
// A far one is the muffled report and a late boom.
|
||||
let f = layers(0, 400.0, 140.0, 1.0, 1.0, 0);
|
||||
assert!(f.iter().all(|v| v.name.ends_with("_far")) && f[1].delay > 0);
|
||||
// The rest of a tick's blasts play one voice, and the whole mix stays bounded.
|
||||
let total: f32 = (0..12).flat_map(|r| layers(2, 60.0, 140.0, 1.0, 1.0, r)).map(|v| v.volume).sum();
|
||||
let voices: usize = (0..12).map(|r| layers(2, 60.0, 140.0, 1.0, 1.0, r).len()).sum();
|
||||
assert_eq!(voices, FULL * 3 + (12 - FULL));
|
||||
assert!(total < 18.0, "{total}");
|
||||
assert_eq!(blast_power("airdef:blast.huge"), Some(4));
|
||||
assert_eq!(blast_power("airdef:boom.sonic"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_punch_is_brief_near_and_bounded() {
|
||||
assert_eq!(punch(5.0, -1.0, 10.0), 0.0);
|
||||
assert!(punch(5.0, 1.5, 20.0) > punch(5.0, 1.5, 150.0));
|
||||
assert!(punch(5.0, 1.5, 20.0) > punch(2.0, 1.5, 20.0));
|
||||
assert!(punch(13.0, 1.0, 0.0) <= 1.0);
|
||||
assert!(punch(5.0, 30.0, 20.0) < 0.01, "gone in a second and a half");
|
||||
}
|
||||
}
|
||||