Compare commits

...

111 Commits

Author SHA1 Message Date
chexit e7934a1ebb Give the enemy a structured intent and a durable route queue (#127)
build / mod (push) Failing after 22s
release / windows (push) Failing after 2s
Stage 2 of #127. A smart drone now carries why it is aimed where it is
(Intent: plan, sead, react, replace) apart from the aim bookkeeping
(unit, since, switches, confidence). Assignments are throttled per
adaptive tick and per contact, a fresh disclosure replaces an aim only
after a hold, within a switch cap and when the change is worth a new
route, and a killed aim is replaced as a separate, lower-priority
decision. The queue is bounded and taken by priority (plan > sead >
react > replace); unknown land is no longer free in a replanned route.

The autosave now carries the air state: the drones in flight, the launch
queue, every pending job with its id, aim, unit, version, priority,
intent and relief version, the contacts the jobs were chosen from and
the relief snapshots they plan over. The format is a versioned `air 1`
section; older saves read as before, scenarios do not carry the sky,
stale, ghost and duplicate jobs are cancelled on load, and the section is
bounded (512 drones, 512 route points, 4096 contacts, 8 reliefs, 900 KB).
A periodic save waits while a raid is only being planned.

enemy_picture() now explains targets and pending jobs (aims, aimed_by,
pending_jobs, reason, work_per_tick) in English, and intel_bench records
the queue and intent evidence next to completion, losses and failures.
2026-11-06 18:36:20 +03:00
chexit 8fc10c07a1 Give the enemy a last-observation picture and observed-capability pricing (#127) 2026-11-06 18:00:08 +03:00
chexit 0b645d77e9 Normalize #129 measurements and pair the cold-launch capture
build / mod (push) Failing after 22s
Write both measurement CSVs with LF instead of CRLF so the range no longer
fails `git diff --check` on trailing whitespace; the parsed data is unchanged.

Add a matched before/after capture: one copied world, scenario and seed, the
same client/director and the same export command. The baseline hmod is built
from dc36d67 and the final one from the #129 code. Both launch shots start at
frame 94; the first centre illumination is frame 101 (0.233 s) before and
frame 121 (0.900 s) after, against the 0.25/1.00 s cold rules. Raw probe,
hashes and the measurement method are in issue-129-pair.json. The two MP4s
in docs are CRF26 storage copies; the CRF16 originals stay in the scratch
homes.

These are replay exports, not live footage. The capturing agent still has no
image input, so composition is left for human review; the frames before the
launch are not pixel-identical because these are two live sessions.

Co-Authored-By: Kimi Code <noreply@kimi.com>
2026-11-06 13:35:35 +03:00
chexit 56093b3a55 Record the #129 balance and the cold-launch capture
The stage contract and profiles are in 4b013fb. This commit adds the
measured balance (the #120 grid on identical seeds and the 12-seed raid),
the replay/export video with four stills, and updates the user and handoff
documentation. The visual files are provided for human review; the agent
that captured them has no image input and checked only the encoded
parameters, shot boundaries and the first large plume.

Co-Authored-By: Kimi Code <noreply@kimi.com>
2026-11-06 13:35:35 +03:00
chexit 1261c30724 Stage the cold launch and spool every interceptor's motor (#129)
The interceptor's launch is one sequence: the cap opens, the round is
thrown out unlit and slows under linear gas drag (`cold` ticks), the motor
lights where it has reached, it turns with a growing rate while thrust
spools up (`boost` ticks), and full guidance starts only at `cold + boost`.
A rail launch lights at once but spools over the same `boost` ticks; the
electric P1-SUN has no rocket spool or plume.

S-400/500 now hold the unlit ejection for 20/24 ticks (1.00/1.20 s at
20 Hz); IRIS-T/Tor keep shorter 8-tick throws. Ignition, its sound, flame
and recorded MotorIgnition event all use the missile's current position.
The RM48U strike follows the same 20-tick choreography, counts the throw
in its flight time and starts its recorded smoke at ignition.

Maximum speed, turn, accel, pk and every collision rule are unchanged.

Co-Authored-By: Kimi Code <noreply@kimi.com>
2026-11-06 13:35:35 +03:00
chexit a592ece6e3 fixup! Keep unfinished retarget routes in a bounded job queue (#127)
build / mod (push) Failing after 22s
The planner caches were keyed by (kind, relief Arc pointer, start, aim): two jobs with the same relief but different known-units snapshots could reuse each other's price grid and route. Key relief sampling by its Arc pointer but key prices and routes by the whole knowledge version: adaptive tick plus the known-units and relief Arc pointers. Regression creates two same-start, same-aim jobs on one relief with different known snapshots and checks their routes differ, while a third job of one version still reuses the route cache. Core release, adapter and WASM contract pass.
2026-11-06 12:57:36 +03:00
chexit a47812aadd fixup! Keep unfinished retarget routes in a bounded job queue (#127)
The relief snapshot was still global: a smart plan finishing while a retarget job waited could replace Sim::known_relief, so the pending route was planned on the newer map. RouteJob now carries Arc<KnownRelief> for its knowledge version; Sim::known_relief keeps the same Arc only to seed new jobs. retarget_relief reads the job's snapshot, and relief sampling, price grids and route caches are keyed by that version. The new regression makes a job wait, swaps the global relief for another grid with a wall, and checks the pending route and sample stay those of the original version; outside its grid is Unknown. Core release, adapter and WASM contract pass.
2026-11-06 12:57:36 +03:00
chexit 6f7b041c8b Keep unfinished retarget routes in a bounded job queue (#127)
A mass retarget used to clear every selected drone's route before the planner's per-tick work ran out: the rest flew straight for ever. Route jobs now carry the drone id, new aim, target unit, knowledge version and the intel snapshot, stay in a FIFO across ticks and are drained under the same WORK_PER_TICK. An old safe route is kept until its replacement is ready; a cancelled job falls back to a straight run. Jobs are replaced in place per drone, cancelled when the drone or unit is gone, and retarget routes reuse the original plan's known relief. An in-flight drone no longer turns to a unit behind its turning circle. Core release tests, adapter tests and the real WASM contract pass.
2026-11-06 12:57:36 +03:00
chexit dc36d67eb7 Unblock supply trucks from an impossible RM48U return (#128)
build / mod (push) Failing after 21s
step_supply sent every free truck into the return branch whenever any
S-400 had a pending ground_return, even when that return could not
proceed (the system moving, damaged, reloading or preparing, its round
already claimed by another truck, the route marked unreachable, or no
depot with room). The branch then found no target, cleared the job and
stopped the truck, so independent typed supply requests starved.

The return now keeps its priority only while it is executable: a
carrier holding a reserved round looks for a depot with room in reach,
an empty one for a system ready to hand a round over. Otherwise the
claim stays untouched and only real RM48U demand (a requesting system
with depot stock, or ground rounds aboard for one) pulls the truck
into the typed supply branch; without such demand it holds its watch
exactly as before. Redirecting a reserved round to a waiting request
clears return_cargo once the last one leaves the truck, and a stale
return_cargo with an empty hold no longer sends the truck to a depot
handover it cannot complete.

Regressions: three sim tests (moving claimant, pickup claimed by
another truck with damaged/save-restore phases, unreachable route) and
one full-drive lib test with a mid-flight state round trip; the rounds
are conserved in every phase and the actual return completes once the
claimant is back. All three sim tests fail on the old code.

Checks: core release 200 passed/8 ignored + 8 scenarios; adapter
67 unit + 1 boundary + 5 scenarios; real WASM test-wasm 30 steps.
2026-11-06 11:11:59 +03:00
chexit d45629ae29 Fix the UI-event fuel trap on a second large raid order
build / mod (push) Failing after 22s
The Windows log for #122 showed the mod stopping in the UI event
(fuel budget 1e9, remaining 0) with known_units <- order_raid <-
launch_wave <- ui_select: order_raid recomputed the planner snapshot
known_units() for every drone, and the snapshot itself rescanned the
whole force and the dedup list per intel entry. A second big Smart
order cost drones x intel-log x force-size inside one event.

Reproduced in actual WASM with measured per-callback fuel through the
exact ui_select(BTN_LAUNCH) handler (diagnostic guest, trigger.patch):
before, a 111-drone second order at revealed=13172/known=144 exhausted
exactly 1e9 and stopped the mod (an 11-drone order at the same state:
247805865); after, the same scenario passes with max command fuel
32946177/1e9, failures=0, and /stats at tick 2602 byte-identical.
A stacked single-point layout dies to one warhead (known=0, cheap
order), so the scenario deploys spread clusters with a moved player.

Fix: one known_units snapshot per order_raid passed to radar_strikes
and choose_target; known_units is a single O(log + force) set pass;
price_grid_on reuses its snapshot. Emitter/network targeting and
carrier choice semantics are unchanged (native equivalence test
against the former predicate; WASM checkpoint counters equal).
Limits unchanged; HD/recording untouched; wave size unrestricted.

Committed regressions: native snapshot-equivalence and
second-smart-order tests; the heavy WASM fixture now orders two Smart
raids through the wave screen's launch function (airdef preset +
airdef raid) with EW and a combat intel log, four accepted orders
asserted; the light contract covers preset and the empty-wave refusal.

Core release 195 + 8 scenarios; adapter 65 + 1 boundary + 5 scenarios;
light WASM 30 steps; heavy WASM 283 steps (tick max 182413686/300M,
command max 6939810/1e9, failures 0). Windows GUI acceptance remains
external and is not claimed.

Co-Authored-By: Kimi Code (Moonshot AI) <noreply@moonshot.cn>
2026-11-06 10:29:36 +03:00
chexit 61aaa0bf35 Record the Metal/offscreen camera picture acceptance
build / mod (push) Failing after 22s
The final engine 6a53a626c with the API30 AirDef build was run in the
real game (macOS, Apple M5, Metal, --offscreen, a clean HORIZON_HOME and
copied test worlds), not only in the sandbox: the monitor and the film's
main view report ready with the picture actually drawn (screenshots show
the panel and picture area, not a registered target), an empty set-views
drops the request, a world change bumps the generation and clears it, and
AirDef's next submission prepares the camera again in the new world.

Fixes nothing: no defect showed. It also records what the run does not
prove (a human visual check, Windows/other GPUs, two runs with the same
local id on the GPU, a mod reload on the GPU), the per-tick
set-views/set-main-view ordering that can honestly read awaiting-frame
between tick and note (not flicker), and that a title trip back into the
same world keeps the request because the generation is per world.

Co-Authored-By: Kimi Code <noreply@moonshot.cn>
2026-11-04 21:10:34 +03:00
chexit 9217f9a5cc Report camera readiness in /airdef capabilities
Pin the engine at 6a53a626c (API 30) and show render.camera-status: the
calling run's set-views cameras, whether the last noted frame was a world
frame, the request's world generation, each camera's reason and the run's
own main-view selection. As the other lines, this is a host milestone:
availability, request, preparation and why, not a GPU frame or a visible
picture. A unit test pins the line: readiness stays per camera and apart
from the run's main-view selection.

docs/ENGINE.md, the 4 November continuation and the status table now say
what prepared means (a picture encoded into the camera's target, or a
world frame drawn from it as this run's screen view, only for the run
whose selection the screen used), the per-run/per-world resets, and what
remains: GPU acceptance.

Verified: python3 tools/airdef.py check (gitlink, packer, mod needs 30,
fork 30, game 30); test-wasm 27 steps; airdef-mod 65 unit, 1 boundary and
5 scenarios; python3 -m unittest discover -s tools 28 tests.

Co-Authored-By: Kimi Code <noreply@moonshot.cn>
2026-11-04 21:08:23 +03:00
chexit 46d2274c8d Measure the #120 balance grid across batteries, ranges and target classes
Wider same-seed sampling of the finite-burn/coast change: baseline 2689d93
(pre-#120) against the current tree, 6 variants x 8 seeds of a 46-drone raid
(batt10/20/50, near200, far1500, hills20). Harness-only: Result carries the
tally's fuse/expired/orphaned/energy_lost counts and a new ignored
sim::balance::issue_120_grid test; no simulation parameters changed.

Findings: kills are equal or up and leaks equal or down in every variant;
fuse misses drop (far1500 70 -> 38 over 8 seeds); hills terrain losses fall
(scrubbed 6 -> 2). MotorEnergyLost never fires in the 48 scenarios and
expired stays <= 1: coast ends before drag reaches the 25% guidance
threshold. Leaks stay concentrated in the ballistic/fast classes
(Iskander/Kinzhal/Kh22/Zircon). No confirmed defect, so no tuning.

Full airdef-core suite: 193 + 8 passed, 0 failed (baseline side 169 + 4).

Co-Authored-By: Kimi Code <noreply@moonshot.cn>
2026-11-04 21:03:01 +03:00
chexit 325119b726 refactor: validate specs without a per-kind name list
The armed/support check in load_specs named the ten armed kinds, so a new
unit type would still have required a code edit and repeated the coupling
#91 is removing. Drop it: optional missile/gun rows are still validated
generically, and the existing kind-coverage check against content.json
already ties specs to the catalog.

validate_specs now takes the document, content identities and sound
events, and a test shows a hypothetical unit kind is accepted from a
specs row plus its content entry alone. No data or balance changes.

Verified: gen_catalog --check fresh, test_gen_assets 10 tests, core
release 195 passed + 8 scenarios (7 ignored), adapter 64 unit +
1 boundary + 5 scenarios, WASM contract 27 steps.
2026-11-04 21:00:35 +03:00
chexit 0937ac9e05 fix: keep the P1-SUN motor voice at its played 1.6 pitch
The old engine_voice returned early for flame == 0 with
(DRONE_LANCET, 0.8, 1.6), so the later `P1sun => 1.7` match arm was
unreachable. The catalog migration mistook that arm for the played value
and stored 1.7, which changed the interceptor drone's flight sound.
specs.json is back to 1.6 and specs_generated.rs is regenerated.

Adds missile_engine_voices_keep_their_played_values, pinning P1-SUN to
(DRONE_LANCET, 0.8, 1.6) and M48N6 to (MISSILE_FLIGHT, 1.0, 0.88).

The continuation and handoff text now describe the early return instead
of the dead arm, and tools/airdef_assets/catalog.py gets its final
newline back.

Verified: gen_catalog --check and test_gen_assets, core release
195 passed + 8 scenarios (7 ignored), adapter 64 unit + 1 boundary +
5 scenarios, WASM contract 27 steps.
2026-11-04 21:00:35 +03:00
chexit ead87343d2 feat: generate simulation numeric profiles from catalog/specs.json
catalog/specs.json is now the single copy of the numeric rows for
DroneSpec, MissileSpec and SamSpec: speed, guidance, warheads, models'
parts, RCS, seekers, launch and motor sounds, mount drives, gravity,
the Oreshnik split height and logistics limits, plus the named part
sets. tools/gen_catalog.py generates airdef-mod/src/sim/specs_generated.rs
(included by mod.rs, so the mod and airdef-core compile the same rows)
and unit_specs_generated.rs (included by units.rs). The hand-written
spec matches are gone; DroneKind::spec, MissileKind::spec and
SamKind::spec read the generated constants.

load_specs validates the schema, sound references, kind coverage against
content.json, named-part references and unused rows. gen_catalog.py
--check already runs in the CI generated-assets step, so a JSON/Rust
drift fails the build.

Every value was compared with the literals at 632061d field by field.
The only mismatch was the P1-SUN motor voice pitch in JSON (1.6 instead
of the actual 1.7, the flame == 0 branch in voices.rs); the JSON was
corrected and behaviour is unchanged. Save keys, raid order, RNG and
gameplay traces are untouched.

Verified: core release 194 passed + 8 scenarios (7 ignored), adapter
64 unit + 1 boundary + 5 scenarios, WASM contract 27 steps, catalog and
model generators fresh, asset/sound/model-bound/report tests pass.
2026-11-04 21:00:35 +03:00
chexit abf3d76fdb docs: record the real MP4 acoustics check (#96)
Pairs of the same replay exported with acoustics on and off on the
scratch world (no HORIZON_NO_AUDIO): acoustics and capture ownership
both ready. The open field has no reverb send by design, so it shows
occlusion/air absorption only; the stone court's on-track is quieter
and darker, and its residual after a gain fit is low-passed and
stereo-decorrelated, i.e. the wet path. A clean reverb tail/RT60 in a
real MP4, echoes alone and listening remain open. No code changes.

Co-Authored-By: Kimi Code <noreply@moonshot.ai>
2026-11-04 20:52:11 +03:00
chexit e6a7000440 docs: record the engine cleanup for failed film takes
Engine 60cc7b11d removes a failed or cancelled take's video, raw sound
and log, carries the log's last lines in the error, and only creates
<name>.mp4 after a successful finish. A real failing encoder on the
scratch world left no temporaries and kept the earlier film byte for
byte; successful audio and no-audio control films still verified.

Co-Authored-By: Kimi Code <noreply@moonshot.ai>
2026-11-04 20:19:51 +03:00
chexit cec7257ea1 Pin the engine that frees a failed film take's files
horizon 60cc7b11d (on top of 57f8b2853, API 29) removes a failed or
cancelled take's video, raw sound and log, carries the log's last lines
in the error, and only creates <name>.mp4 after a successful finish.

Co-Authored-By: Kimi Code <noreply@moonshot.ai>
2026-11-04 20:17:52 +03:00
chexit 503e6e29af Fix dynamic model lighting and document GPU comparison (#123)
Co-Authored-By: Kimi Code <noreply@moonshot.ai>
2026-11-04 17:53:10 +03:00
chexit 675967ce42 End the show when its world closes and verify the MP4 lifecycle (#89)
A frame hook ends an active film or export when the world is gone. The game
stops ticking at the title screen but keeps rendering, so an export used to
keep recording the title with its playback clock frozen (a sec=10 request
produced 3898 frames) and went on after re-entering the world. Session
cleanup runs once with WorldChange and cancels the capture.

Real short exports on a scratch home and world (pin 57f8b2853, API 29,
Metal): h264+AAC both 2.07 s with non-silent audio, reported frames equal
ffprobe nb_frames; cancel, SDK refusal, encoder failure and restart all
leave no capture running; 1920x1080 works. The engine still leaves
*.audio.raw and *.ffmpeg.log behind on an encoder error (game/film.rs).

Co-Authored-By: Kimi Code <noreply@moonshot.ai>
2026-11-04 17:44:28 +03:00
chexit 632061d2ad docs: archive clean API29 WASM fuel acceptance
build / mod (push) Failing after 20s
Co-Authored-By: Codex <noreply@openai.com>
2026-11-04 16:23:22 +03:00
chexit 56339b076e docs: hand off catalog, model, API29 and acoustics continuation
build / mod (push) Failing after 20s
Co-Authored-By: Codex <noreply@openai.com>
2026-11-04 16:21:29 +03:00
chexit c1a595b773 feat: expose light and sound processing diagnostics with isolated cameras
build / mod (push) Failing after 21s
Co-Authored-By: Codex <noreply@openai.com>
2026-11-04 16:19:06 +03:00
chexit 914f723d1f Verify aircraft models as lit mod instances
build / mod (push) Failing after 20s
Co-Authored-By: Codex <noreply@openai.com>
2026-11-04 16:16:47 +03:00
chexit d45d59df9f build: pin source-manager processing handshake
Co-Authored-By: Codex <noreply@openai.com>
2026-11-04 16:12:53 +03:00
chexit cfae0c1253 Refine cruise silhouette and document model comparisons
build / mod (push) Failing after 19s
Co-Authored-By: Codex <noreply@openai.com>
2026-11-04 16:09:14 +03:00
chexit 53669887dd Refine Lancet silhouette with swept X wings
Co-Authored-By: Codex <noreply@openai.com>
2026-11-04 16:09:14 +03:00
chexit 4c7c887917 build: pin point-light handshake and mass acoustics fixture
Co-Authored-By: Codex <noreply@openai.com>
2026-11-04 16:09:14 +03:00
chexit daa9ed7cbc Use catalog sound identifiers throughout runtime
build / mod (push) Failing after 19s
Co-Authored-By: Codex <noreply@openai.com>
2026-11-04 16:01:19 +03:00
chexit 1553976484 Share sound identifiers and metadata with resource generation
build / mod (push) Failing after 18s
Co-Authored-By: Codex <noreply@openai.com>
2026-11-04 15:59:18 +03:00
chexit 0c870c10d5 Represent damage diagnostics as typed reasons
Co-Authored-By: Codex <noreply@openai.com>
2026-11-04 15:59:18 +03:00
chexit eea1b3692e Share aircraft and item catalog with asset generation
build / mod (push) Failing after 20s
Co-Authored-By: Codex <noreply@openai.com>
2026-11-04 15:55:45 +03:00
chexit cb73cb7ccc Move world cache report to presentation adapter
Co-Authored-By: Codex <noreply@openai.com>
2026-11-04 15:55:45 +03:00
chexit 375fdf2d80 Separate battery status from player-facing text
Co-Authored-By: Codex <noreply@openai.com>
2026-11-04 15:55:45 +03:00
chexit 63aefc7621 test: record measured callback fuel in budget reports
Co-Authored-By: Codex <noreply@openai.com>
2026-11-04 15:55:45 +03:00
chexit d410e2c92d docs: archive the reproduced fuel failure and bounded cache fix
build / mod (push) Failing after 18s
Preserve the diagnostic trigger, scenario, before/after logs and scope of equivalent counters. Update ground strike guidance, Windows acceptance status and profiler semantics.

Co-authored-by: Codex <codex@openai.com>
2026-11-03 11:39:23 +03:00
chexit ab737e7390 test: verify empty nearby depot feedback in WASM
build / mod (push) Failing after 18s
Co-authored-by: Codex <codex@openai.com>
2026-11-03 11:34:02 +03:00
chexit 3b470ddc8a build: pin optional per-callback WASM fuel profiling
The opt-in test CLI reports measured guest fuel separately from host and GPU costs; runtime limits remain unchanged.

Co-authored-by: Codex <codex@openai.com>
2026-11-03 11:34:02 +03:00
chexit cbd6067e8f fix: explain empty strike stock and ground attack prerequisites
build / mod (push) Failing after 19s
Show typed depot cargo separately, identify an empty nearby depot, and document loading, reconnaissance, two ID namespaces and reverse pickup.

Co-authored-by: Codex <codex@openai.com>
2026-11-03 11:26:52 +03:00
chexit cc48302b36 Exercise two maximum menu raids with terrain replies
Co-authored-by: Codex <codex@openai.com>
2026-11-03 11:26:52 +03:00
chexit 1f28f8361f Bound height cache invalidation per explosion
Co-authored-by: Codex <codex@openai.com>
2026-11-03 11:23:47 +03:00
chexit 10f24b5df8 docs: record verified overlap stress and unresolved Windows report
build / mod (push) Failing after 19s
Keep the corrected historical coverage claim, archive the real flat-world WASM run, explain trap diagnostics and the small HD trail density change.

Co-authored-by: Codex <codex@openai.com>
2026-11-03 10:54:57 +03:00
chexit 293236490b test: freeze the exact budget fixture used by the runtime
build / mod (push) Failing after 17s
Derive synthetic terrain metadata from the fixture and copy the same bytes that were hashed before building.

Co-authored-by: Codex <codex@openai.com>
2026-11-03 10:49:21 +03:00
chexit bf8551e1a8 Run flat terrain scenario in budget report
Co-authored-by: Codex <codex@openai.com>
2026-11-03 10:43:01 +03:00
chexit 3afebae6bd Cover HD grid during overlapping raids
Co-authored-by: Codex <codex@openai.com>
2026-11-03 10:43:01 +03:00
chexit 326817db9a Add overlapping raids budget scenario with flat terrain
Co-authored-by: Codex <codex@openai.com>
2026-11-03 10:43:01 +03:00
chexit 8f5603847e test: pin real render-query fixtures and correct raid coverage claims
build / mod (push) Failing after 18s
Archive the original budget report as insufficient proof of overlapping raids. Pin callback/fuel diagnostics and an opt-in flat render world that services actual guest queries.

Co-authored-by: Codex <codex@openai.com>
2026-11-03 10:36:45 +03:00
chexit bd091e60df Exercise overlapping Oreshnik splits and recording
Co-authored-by: Codex <codex@openai.com>
2026-11-03 10:36:42 +03:00
chexit 296a64ffaa Exercise overlapping menu raids on answered terrain
Co-authored-by: Codex <codex@openai.com>
2026-11-03 10:34:31 +03:00
chexit a41a4d17cf Verify sequential raid requests in budget scenario 2026-11-03 10:32:31 +03:00
chexit 692ae77af7 Slightly densify missile smoke trails
build / mod (push) Failing after 18s
Co-authored-by: Codex <codex@openai.com>
2026-11-03 10:25:56 +03:00
chexit 19c53fda4c docs: record API27 readiness and reverse logistics verification
build / mod (push) Failing after 19s
Document capability milestones, budget limits versus measurements, real-game no-audio observations, reverse pickup reservation and the Windows stale-URL fix.

Co-authored-by: Codex <codex@openai.com>
2026-11-03 10:22:53 +03:00
chexit aab3e784b8 build: reuse the pinned engine target cache for its packer
build / mod (push) Failing after 18s
Co-authored-by: Codex <codex@openai.com>
2026-11-03 00:27:02 +03:00
chexit 8d5d0d1dd7 Test WASM budget report failure paths
Co-authored-by: Codex <codex@openai.com>
2026-11-03 00:25:28 +03:00
chexit 910f02ca92 feat: consume scoped engine capabilities and preserve safe fallbacks
build / mod (push) Failing after 19s
Pin API27, diagnose prepared states, gate capture ownership and keep far-sound fallback until acoustics is prepared. Retain engine changes in build provenance and cancel invalid return reservations after cell loss.

Co-authored-by: Codex <codex@openai.com>
2026-11-03 00:24:46 +03:00
chexit 4dddea2e8c Add opt-in heavy WASM budget tier
Co-authored-by: Codex <codex@openai.com>
2026-11-03 00:23:25 +03:00
chexit b0085cb3e8 Test interrupted return pickup
Co-authored-by: Codex <codex@openai.com>
2026-11-03 00:18:44 +03:00
chexit e9fbaba1d6 Preserve pending delivery and command completion behavior
Co-authored-by: Codex <codex@openai.com>
2026-11-03 00:18:44 +03:00
chexit bb931ab95c Return loaded RM48U to depot by truck
Co-authored-by: Codex <codex@openai.com>
2026-11-03 00:18:44 +03:00
chexit d3378b37a2 fix: synchronize the engine submodule URL before updating
build / mod (push) Failing after 18s
Reproduce stale upstream configuration with real local Git repositories, including the already-matching pin fast path.

Co-authored-by: Codex <codex@openai.com>
2026-11-03 00:18:41 +03:00
chexit e70d7a667b docs: describe implemented realism mechanics and verified handoff
build / mod (push) Failing after 18s
Record actual save field positions, motor phases, finite typed delivery, last-known radar contacts and blast-cover policy. Include per-seed baseline measurements and distinguish native/WASM checks from pending GUI acceptance.

Co-authored-by: Codex <codex@openai.com>
2026-11-03 00:07:31 +03:00
chexit 6e2d661b39 test: exercise radar silence through the real WASM boundary
build / mod (push) Failing after 18s
Co-authored-by: Codex <codex@openai.com>
2026-11-03 00:02:52 +03:00
chexit a7b8cb980a Apply coast drag after interceptor burnout
Co-authored-by: Codex <codex@openai.com>
2026-11-03 00:02:50 +03:00
chexit ce76f20074 Target SEAD strikes at observed radar contacts
Co-authored-by: Codex <codex@openai.com>
2026-11-02 23:59:11 +03:00
chexit e38ca0d9ab Match impact speed to swept segment
Co-authored-by: Codex <codex@openai.com>
2026-11-02 23:59:11 +03:00
chexit e3ca3fbd8c Release interceptor engine source at burnout
Co-authored-by: Codex <codex@openai.com>
2026-11-02 23:59:11 +03:00
chexit 44a023006d Use interceptor energy for residual fuse chance
Co-authored-by: Codex <codex@openai.com>
2026-11-02 23:59:11 +03:00
chexit f3985d5363 Record energy loss and exercise meeting geometry
Co-authored-by: Codex <codex@openai.com>
2026-11-02 23:59:11 +03:00
chexit 6b6293f353 Cover lead for crossing target
Co-authored-by: Codex <codex@openai.com>
2026-11-02 23:59:11 +03:00
chexit 932a8b7761 Use swept meeting point for interceptor impact
Co-authored-by: Codex <codex@openai.com>
2026-11-02 23:59:11 +03:00
chexit 143d9b2858 Prototype finite interceptor motor and coast
Co-authored-by: Codex <codex@openai.com>
2026-11-02 23:58:54 +03:00
chexit b377a5d8d2 test: preserve delivery requests alongside radar emission saves
Co-authored-by: Codex <codex@openai.com>
2026-11-02 23:58:15 +03:00
chexit 9e1e0f5543 Update network risk fixture for observed radar
Co-authored-by: Codex <codex@openai.com>
2026-11-02 23:56:52 +03:00
chexit 88f940546b Test radar silence and replay seeking
Co-authored-by: Codex <codex@openai.com>
2026-11-02 23:56:52 +03:00
chexit 0df225a2de Observe emitting radars and expose emission control
Co-authored-by: Codex <codex@openai.com>
2026-11-02 23:56:52 +03:00
chexit 26b258f00f Add persisted radar emission switch
Co-authored-by: Codex <codex@openai.com>
2026-11-02 23:56:52 +03:00
chexit 952a10f360 Exercise strike delivery across movement and save restore
build / mod (push) Failing after 18s
Co-authored-by: Codex <codex@openai.com>
2026-11-02 23:55:56 +03:00
chexit c775f31544 Deliver typed strike rounds by transport loader
Co-authored-by: Codex <codex@openai.com>
2026-11-02 23:55:56 +03:00
chexit c96676f3e5 feat: attenuate indirect blast damage behind known cover
build / mod (push) Failing after 18s
Use a bounded read-only pre-destruction occupancy sample; preserve conservative damage for unresolved geometry and do not defer or repeat damage on replies.

Co-authored-by: Codex <codex@openai.com>
2026-11-02 23:55:38 +03:00
chexit a7d400ea7e docs: establish current project status and engineering handoff
build / mod (push) Failing after 18s
Co-authored-by: Codex <codex@openai.com>
2026-11-02 23:50:19 +03:00
chexit 2689d933e7 docs: document cold launch visual checks and battery validation
build / mod (push) Failing after 19s
Co-authored-by: Codex <codex@openai.com>
2026-11-02 23:42:19 +03:00
chexit 966b52f9fc feat: add shared radar batteries and animated cold launch
build / mod (push) Failing after 18s
Separate search and engagement roles, support launcher-only SAMs, animate individual tube lids and delay ground strike spending until ejection. Preserve battery configuration and launch poses in saves and replay.

Co-authored-by: Codex <codex@openai.com>
2026-11-02 23:40:40 +03:00
chexit d4adbb1e47 Launch typed ground strikes from carriers and isolate presentation state (#118 #88 #89)
build / mod (push) Failing after 18s
Share read-only scene data for smoke and displayed blasts; preserve cold ejection and flight-relative recording samples. Keep finite typed depot inventory, expose per-world smoke readiness through the pinned API26 engine, and invalidate presentation resources on world changes.

Validation: core suite 156 unit tests plus 4 scenarios and the new targeted recording regression; adapter 50 unit tests, boundary check and 4 scenarios; real WASM contract 16 steps; asset pipeline and bounds checks; macOS Metal client build and HD frame.

Co-Authored-By: Codex <noreply@openai.com>
2026-11-02 22:23:09 +03:00
chexit e84a5e9fa7 Refine ground vehicle silhouettes and publish in-game model checks (#115)
Preserve launcher grids and authored materials; fix the Buk radar intersection and regenerate geometry bounds. Register the separate RM48U game visual for the upcoming carrier path.

Co-Authored-By: Codex <noreply@openai.com>
2026-11-02 22:22:54 +03:00
chexit c4b72da3ff Clarify gun burst counters and record the verified realism follow-up (#91)
Co-Authored-By: Codex <noreply@openai.com>
2026-11-02 21:48:47 +03:00
chexit ac866d64a0 Record acoustic fixture results and ship source notices with game bundles (#96 #102)
build / mod (push) Failing after 18s
Co-Authored-By: Codex <noreply@openai.com>
2026-11-02 21:33:59 +03:00
chexit 5620347ffe Add three art pilots and derive chassis envelopes from final models (#115 #114)
Keep authored JSON separate from generated output. Export rotated model bounds for SDK-free navigation and check grazing voxel corners. Include unretouched in-game before/after captures and explicit art/performance limits; pilots are an intermediate pass, not completion of the full asset set.

Co-Authored-By: Codex <noreply@openai.com>
2026-11-02 21:33:59 +03:00
chexit 4a3500fdc0 Install the pinned raster generator dependency in CI (#92)
Co-Authored-By: Codex <noreply@openai.com>
2026-11-02 21:06:00 +03:00
chexit dedb0213c7 Validate the actual hmod in the pinned host sandbox (#102)
build / mod (push) Failing after 19s
Keep runtime compilation in an opt-in CI tier; run asset consistency on regular builds. Sandbox checks do not substitute for GPU, capture or maximum-scenario budgets.

Co-Authored-By: Codex <noreply@openai.com>
2026-11-02 21:01:07 +03:00
chexit ad96018c0a Explain unavailable coordinate-strike loadouts in map and documentation (#118)
Co-Authored-By: Codex <noreply@openai.com>
2026-11-02 21:01:07 +03:00
chexit efb2f20e58 Apply route node limit before waiting for geometry (#114)
Co-Authored-By: Codex <noreply@openai.com>
2026-11-02 21:00:22 +03:00
chexit 29b047abaf Remove seed-only defenders and reject unsupported player-launched strikes (#118)
No compatible coordinate-strike loadout is implemented yet. Preserve flight and collision mechanics through explicit test fixtures without allowing generic stock or player position to create a production missile. Physical carriers, typed ammunition and logistics remain to implement.

Co-Authored-By: Codex <noreply@openai.com>
2026-11-02 21:00:22 +03:00
chexit 814f8c7e83 Make export own its playback and centralize session exits (#89)
Co-Authored-By: Codex <noreply@openai.com>
2026-11-02 21:00:22 +03:00
chexit f28e68db62 Record measured scene transitions and isolate combat effects from recorder (#88)
Capture actual missile launch/ignition, track transitions, fire state, SAM health and components. Keep legacy fallback and bound scene transitions to 65536. Renderers still use incremental adapters; shared SceneTimeline remains follow-up work.

Co-Authored-By: Codex <noreply@openai.com>
2026-11-02 21:00:22 +03:00
chexit 63972995a1 Use the standalone Horizon fork merged with v0.2.97 (#72)
Client library: 1227 passed, 42 ignored. SDK/packer/runtime: 59 passed. Built macOS arm64 client with mods and packaged actual AirDef WASM. Native HDR and Windows/Linux runtime smoke remain unverified.

Co-Authored-By: Codex <noreply@openai.com>
2026-11-02 21:00:10 +03:00
chexit 5ad6ea8ad9 Share stable content IDs across raids, inventory and item dispatch (#91)
Co-Authored-By: Codex <noreply@openai.com>
2026-11-02 20:59:56 +03:00
chexit 657d8f16c6 Separate authored assets and install generated output transactionally (#92)
Co-Authored-By: Codex <noreply@openai.com>
2026-11-02 01:19:51 +03:00
chexit e7c00267b1 Check chassis footprint and bound pending route exploration (#114)
Reject narrow corridors, recheck motion clearance, and wait for footprint data before flooding the shared query budget.

Co-Authored-By: Codex GPT-6 Luna <noreply@openai.com>
2026-11-02 01:17:03 +03:00
chexit 5f07027faa Build canonical simulation without Horizon SDK and remove hidden launch fixes (#87 #107)
Preserve the adapter facade and move adapter-only checks out of domain tests. Late tracks do not reveal an unseen launch origin or its timestamp.

Co-Authored-By: Codex GPT-6.1 Terra <noreply@openai.com>
2026-11-02 01:17:03 +03:00
chexit 4761ae7d70 Pin the standalone Horizon fork as a submodule (#104)
Replace patch-stack reconstruction with safe pinned initialization and legacy checkout migration; use an engine-local packer and write artifact identities.

Co-Authored-By: Codex <noreply@openai.com>
2026-11-02 01:09:21 +03:00
chexit afe320786d Match counter-strike launch audio and live smoke to replay (#109)
build / mod (push) Successful in 8m46s
2026-11-02 00:45:14 +03:00
chexit 733dc07863 Keep radar-controlled gun accuracy independent of darkness 2026-11-02 00:45:14 +03:00
chexit 5860c5009f Bound counter-strike steps and check terminal collisions (#106 #117) 2026-11-02 00:45:14 +03:00
chexit cd3c4ed76d Separate live and replay worlds, refresh acoustic lifecycle (#105 #110 #111 #112)
build / mod (push) Successful in 8m39s
Co-Authored-By: Kimi <noreply@moonshot.ai>
2026-11-01 02:34:39 +03:00
chexit 31d967b036 Counter-strikes collide, persist and record their flights (#106 #108 #109 #113)
Co-Authored-By: Kimi <noreply@moonshot.ai>
2026-11-01 02:34:39 +03:00
chexit 1a693763fd The player's picture and the enemy's intel apart from the truth (#93); world answers carry their context, worlds told apart by seed, a drone that can't reach its aim gives up (#90)
build / mod (push) Successful in 8m25s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 03:20:07 +03:00
chexit 557346548a Interceptors blow up only before blocks a probe confirms, not on a tree-top height; low flights hold height over unknown land
build / mod (push) Successful in 8m54s
release / windows (push) Successful in 22m27s
In a clean real game with 15 systems: interceptors scrubbed at relief 58 to 2, kills 33 to 46 of 82. Smart raids from 2500 blocks: crashes 10 to 3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 03:03:31 +03:00
chexit 38e515dea9 Flights over unknown land hold a safe height, air starts wait for the land, systems and aims settle on the surface; map labels, filters, coverage by terrain and scenes
build / mod (push) Successful in 8m34s
Far raids over mountains with a 300-block known disc: crashes from 19 to 2 of 368 (mixed), 22 to about 9 (smart). Balance tests gain hilly land.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 02:19:31 +03:00
chexit 57a5426e65 Strikes on launch sites, command map and placement editor, fire doctrines, ground routes, acoustics switch and reverb
build / mod (push) Successful in 4m13s
#101: radars locate sites from launches, /airdef sites, /airdef strike; sites launch slower (15/25/50 ticks) so a strike can come in time. #48: M opens the map on the network's picture, with an editor. #47: guard, sector, reserve and salvo per system. #94: vehicles route round slopes and water and say when they cannot get through. #96: reverb, and a menu switch for the acoustics. #92: generated files are validated before the swap, repo map.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 00:59:03 +03:00
chexit ccc3e20902 Playtest fixes: smoke by engine, searchlights, far launch sites that load their chunks, air defence balance, last chance and radar-cued shots, radars in smart raids, echo, Windows release build from a tag
build / mod (push) Successful in 4m4s
release / windows (push) Successful in 23m13s
Smoke: one rule by engine, no heat on trails, no trail on P1-SUN. Searchlights: two lamps a target, off with an empty sky. Halos fade before their reach and their sum is limited. Launch sites load chunks through the server thread, go off-map as a last resort, and reach 4000 blocks. Air defence: ranges x1.5, shots grow with urgency, claims released, /airdef lastchance, long shots on a big radar's tracks. Build: rust-toolchain.toml, airdef.py check, generator manifest and --check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 23:44:14 +03:00
368 changed files with 218305 additions and 72914 deletions
+22 -5
View File
@@ -1,7 +1,7 @@
# На каждый пуш: только мод (.hmod, один для всех ОС) и релиз build-<номер> с ним.
# Раннер живёт на одной машине с Gitea и другими сервисами (2 ядра, 4 ГБ): сборка мода лёгкая —
# один поток компиляции, низший приоритет, без системных пакетов и без кэша target.
# Игра-форк собирается отдельно и только вручную: game.yml (Linux) и desktop.yml (macOS/Windows).
# Игра-форк здесь не собирается: только по тегу версии (release.yml, Windows) и вручную (game.yml Linux, desktop.yml macOS).
name: build
on:
@@ -20,6 +20,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Rust
run: |
curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --target wasm32-unknown-unknown
@@ -28,8 +30,20 @@ jobs:
# падало по таймауту, а сохранение вешало «Complete job» на пару минут. Инструмент собирается заново.
- name: Форк Horizon
run: nice -n 19 python3 tools/airdef.py fork
# Чистая симуляция тестируется нативно (хост-таргет раннера, без WASM): регрессии из sim/regress.rs
# и сценарии tests/scenarios.rs (NaN, налёт кончается, ТЗМ не зависают). Нужен форк: SDK подключён путём.
- name: Проверка закреплённого checkout
run: python3 -m unittest discover -s tools -p test_engine_checkout.py
- name: Проверка generated assets
run: |
python3 -m pip install --user -r tools/requirements.txt
python3 tools/gen_catalog.py --check
python3 -m unittest discover -s tools -p test_sound_catalog.py
python3 tools/gen_models.py --check
python3 -m unittest discover -s tools -p test_model_bounds.py
- name: Тесты ядра без SDK
working-directory: airdef-core
run: |
HOST=$(rustc -vV | sed -n 's/^host: //p')
nice -n 19 cargo test --target "$HOST"
- name: Тесты мода
working-directory: airdef-mod
run: |
@@ -46,8 +60,10 @@ jobs:
SHA: ${{ github.sha }}
run: |
set -e
mkdir -p out && cp airdef-mod/target/horizon-mod/airdef.hmod out/airdef.hmod
BODY=$(printf 'Сборка %s (%s).\n\n- airdef.hmod — мод, для всех ОС.\n\nИгра-форк Horizon (нужна для мода): собрать у себя — python3 tools/airdef.py all, или запустить вручную workflow game (Linux) / desktop (macOS, Windows) с этим тегом.\nКак запускать: docs/INSTALL.md.' "$TAG" "$SHA")
mkdir -p out
cp airdef-mod/target/horizon-mod/airdef.hmod out/airdef.hmod
cp airdef-mod/target/horizon-mod/build-identity.json out/build-identity.json
BODY=$(printf 'Сборка %s (%s).\n\n- airdef.hmod — мод, для всех ОС.\n\nИгра-форк Horizon (нужна для мода): собрать у себя — python3 tools/airdef.py all, или скачать из большого релиза v* (Windows), или запустить вручную workflow game (Linux) / desktop (macOS) с этим тегом.\nКак запускать: docs/INSTALL.md.' "$TAG" "$SHA")
DATA=$(BODY="$BODY" python3 -c 'import json,os;print(json.dumps({"tag_name":os.environ["TAG"],"target_commitish":os.environ["SHA"],"name":os.environ["TAG"],"body":os.environ["BODY"]}))')
if [ -z "$TOKEN" ]; then echo "::error::нет токена: добавь секрет RELEASE_TOKEN"; exit 1; fi
CODE=$(curl -sS -o release.json -w '%{http_code}' -X POST -H "Authorization: token $TOKEN" -H "Content-Type: application/json" "$API/releases" -d "$DATA")
@@ -57,3 +73,4 @@ jobs:
fi
ID=$(python3 -c 'import json;print(json.load(open("release.json"))["id"])')
curl -sf -X POST -H "Authorization: token $TOKEN" -F "attachment=@out/airdef.hmod" "$API/releases/$ID/assets?name=airdef.hmod" > /dev/null
curl -sf -X POST -H "Authorization: token $TOKEN" -F "attachment=@out/build-identity.json" "$API/releases/$ID/assets?name=build-identity.json" > /dev/null
+8 -75
View File
@@ -1,6 +1,6 @@
# Сборки игры-форка для macOS и Windows: запускаются вручную (Actions → desktop → Run workflow)
# с тегом готового релиза (build-N) и дописывают свои архивы в него. Нужны раннеры с метками
# macos-latest / windows-latest (например, act_runner в режиме host на своём Маке или ПК).
# Сборка игры-форка для macOS: запускается вручную (Actions → desktop → Run workflow) с тегом готового
# релиза (build-N) и дописывает свой архив в него. Нужен раннер с меткой macos-latest (например, act_runner
# в режиме host на своём Маке). Windows собирается на сервере по тегу версии: release.yml.
name: desktop
on:
@@ -9,17 +9,12 @@ on:
tag:
description: Тег релиза, например build-3
required: true
os:
description: macos, windows или both
required: true
default: both
env:
CARGO_TERM_COLOR: never
jobs:
game-macos:
if: inputs.os == 'macos' || inputs.os == 'both'
runs-on: macos-latest
steps:
- name: Проверка релиза
@@ -46,6 +41,7 @@ jobs:
PY
- uses: actions/checkout@v4
with:
submodules: recursive
ref: refs/tags/${{ inputs.tag }}
- name: Проверка коммита
env:
@@ -74,6 +70,10 @@ jobs:
D=airdef-macos-arm64
mkdir -p "$D"
cp horizon/target/fast/horizon-client horizon/target/fast/horizon-ctl out/airdef.hmod dist/play.sh docs/INSTALL.md "$D/"
cp airdef-mod/target/horizon-mod/build-identity.json "$D/"
cp -R docs/licenses "$D/"
cp horizon/THIRD_PARTY_NOTICES.md "$D/licenses/HORIZON-THIRD-PARTY-NOTICES.md"
cp horizon/crates/horizon-client/src/acoustics/THIRD_PARTY_SPR.md "$D/licenses/THIRD_PARTY_SPR.md"
tar czf "out/$D.tar.gz" "$D"
- name: В релиз
env:
@@ -83,70 +83,3 @@ jobs:
set -e
# 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'
runs-on: windows-latest
defaults:
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)) {
Invoke-WebRequest https://win.rustup.rs/x86_64 -OutFile rustup-init.exe
.\rustup-init.exe -y --profile minimal
}
"$env:USERPROFILE\.cargo\bin" | Out-File -Append -Encoding utf8 $env:GITHUB_PATH
- name: Форк Horizon
run: python tools/airdef.py fork
- name: Игра
run: python tools/airdef.py game
- name: Мод
run: |
rustup target add wasm32-unknown-unknown
python tools/airdef.py mod
New-Item -ItemType Directory -Force out | Out-Null
Copy-Item airdef-mod\target\horizon-mod\airdef.hmod out\
- name: Архив
run: |
$D = "airdef-windows-x86_64"
New-Item -ItemType Directory -Force $D | Out-Null
Copy-Item horizon\target\fast\horizon-client.exe, horizon\target\fast\horizon-ctl.exe, out\airdef.hmod, dist\play.bat, docs\INSTALL.md $D
Compress-Archive -Path $D -DestinationPath "out\$D.zip" -Force
- name: В релиз
env:
TOKEN: ${{ secrets.RELEASE_TOKEN || gitea.token }}
API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
run: |
# 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"
+5
View File
@@ -49,6 +49,7 @@ jobs:
PY
- uses: actions/checkout@v4
with:
submodules: recursive
ref: refs/tags/${{ inputs.tag }}
- name: Проверка коммита
env:
@@ -82,6 +83,10 @@ jobs:
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/"
cp airdef-mod/target/horizon-mod/build-identity.json "$D/"
cp -R docs/licenses "$D/"
cp horizon/THIRD_PARTY_NOTICES.md "$D/licenses/HORIZON-THIRD-PARTY-NOTICES.md"
cp horizon/crates/horizon-client/src/acoustics/THIRD_PARTY_SPR.md "$D/licenses/THIRD_PARTY_SPR.md"
tar czf "out/$D.tar.gz" "$D"
# 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
+101
View File
@@ -0,0 +1,101 @@
# Большой релиз: только по тегу vX.Y.Z (git tag v0.3.0 && git push origin v0.3.0) или вручную с готовым тегом.
# Игра-форк для Windows собирается на Linux-сервере кросс-компиляцией (x86_64-pc-windows-gnu), без Windows-раннера.
# Сервер общий (2 ядра, 4 ГБ, Gitea и боты), поэтому контейнер ограничен: при нехватке памяти убивается сборка, а не
# сервисы. Замер 2026-10-30: 20,5 минуты, 2 ГБ памяти постоянно в потолке, у сервера не меньше 726 МБ свободно.
# Обычные коммиты сюда не попадают: build.yml собирает только мод.
name: release
on:
push:
tags: ['v*']
workflow_dispatch:
inputs:
tag:
description: Существующий тег, например v0.3.0
required: true
env:
CARGO_TERM_COLOR: never
CARGO_BUILD_JOBS: "1"
CARGO_INCREMENTAL: "0"
CARGO_PROFILE_FAST_INCREMENTAL: "false"
CARGO_PROFILE_FAST_DEBUG: "false"
CARGO_PROFILE_FAST_STRIP: "true"
TAG: ${{ inputs.tag || github.ref_name }}
jobs:
windows:
runs-on: ubuntu-latest
container:
image: catthehacker/ubuntu:act-latest
options: --memory=2g --memory-swap=4500m --cpus=1.5 --cpu-shares=128 --blkio-weight=100 --oom-score-adj=800
steps:
- name: Место на диске
run: |
FREE=$(df --output=avail -BG / | tail -1 | tr -dc 0-9)
echo "свободно: ${FREE} ГБ"
if [ "$FREE" -lt 12 ]; then echo "::error::на сервере свободно ${FREE} ГБ, нужно хотя бы 12"; exit 1; fi
- uses: actions/checkout@v4
with:
submodules: recursive
ref: refs/tags/${{ inputs.tag || github.ref_name }}
- name: Инструменты
run: |
SUDO=$(command -v sudo || true)
$SUDO apt-get update -qq
$SUDO apt-get install -y -qq --no-install-recommends gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 zip
curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain none
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
# Версия Rust берётся из rust-toolchain.toml.
- name: Цели Rust
run: rustup target add x86_64-pc-windows-gnu wasm32-unknown-unknown
- name: Форк Horizon
run: nice -n 19 python3 tools/airdef.py fork
- name: Мод
run: nice -n 19 python3 tools/airdef.py mod
- name: Игра для Windows
working-directory: horizon
run: |
# Сторож: сервер важнее сборки. Память контейнера ограничена, это на случай, если её съело что-то ещё.
( while sleep 10; do
AVAIL=$(awk '/MemAvailable/{print int($2/1024)}' /proc/meminfo)
DISK=$(df --output=avail -BG / | tail -1 | tr -dc 0-9)
if [ "$AVAIL" -lt 250 ] || [ "$DISK" -lt 6 ]; then
echo "::error::сборка остановлена: свободно ${AVAIL} МБ памяти и ${DISK} ГБ диска"
pkill -9 cargo; pkill -9 rustc; exit 1
fi
done ) &
WATCH=$!
nice -n 19 ionice -c3 cargo build --profile fast -p horizon-client --features mods --target x86_64-pc-windows-gnu
kill "$WATCH"
- name: Архив
run: |
set -e
D=airdef-windows-x86_64
T=horizon/target/x86_64-pc-windows-gnu/fast
mkdir -p "$D" out
cp "$T/horizon-client.exe" "$T/horizon-ctl.exe" airdef-mod/target/horizon-mod/airdef.hmod dist/play.bat docs/INSTALL.md "$D/"
cp airdef-mod/target/horizon-mod/build-identity.json "$D/"
cp -R docs/licenses "$D/"
cp horizon/THIRD_PARTY_NOTICES.md "$D/licenses/HORIZON-THIRD-PARTY-NOTICES.md"
cp horizon/crates/horizon-client/src/acoustics/THIRD_PARTY_SPR.md "$D/licenses/THIRD_PARTY_SPR.md"
zip -qr "out/$D.zip" "$D"
cp airdef-mod/target/horizon-mod/airdef.hmod out/
- name: Релиз
env:
TOKEN: ${{ secrets.RELEASE_TOKEN || gitea.token }}
API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
run: |
set -e
if [ -z "$TOKEN" ]; then echo "::error::нет токена: добавь секрет RELEASE_TOKEN"; exit 1; fi
# Тег с дефисом (v0.3.0-rc1) выходит как предварительный релиз; уже созданный релиз тега дополняется.
DATA=$(python3 -c 'import json,os;t=os.environ["TAG"];print(json.dumps({"tag_name":t,"name":t,"prerelease":"-" in t,"body":"Windows: распакуй airdef-windows-x86_64.zip и запусти play.bat. Нужен Minecraft Java 26.3 и лаунчер Horizon, запущенный один раз. Подробнее: docs/INSTALL.md.\n\nmacOS: сборка из исходников, python3 tools/airdef.py all."}))')
CODE=$(curl -sS -o release.json -w '%{http_code}' -H "Authorization: token $TOKEN" "$API/releases/tags/$TAG")
if [ "$CODE" != "200" ]; then
CODE=$(curl -sS -o release.json -w '%{http_code}' -X POST -H "Authorization: token $TOKEN" -H "Content-Type: application/json" "$API/releases" -d "$DATA")
if [ "$CODE" != "201" ]; then echo "::error::Gitea не создала релиз (HTTP $CODE): $(cat release.json)"; exit 1; fi
fi
ID=$(python3 -c 'import json;print(json.load(open("release.json"))["id"])')
for F in airdef-windows-x86_64.zip airdef.hmod; do
curl -sf -X POST -H "Authorization: token $TOKEN" -F "attachment=@out/$F" "$API/releases/$ID/assets?name=$F" > /dev/null
done
+27
View File
@@ -0,0 +1,27 @@
# Opt-in heavy sandbox runtime tier; separate from the routine WASM contract.
name: wasm-budget
on:
workflow_dispatch:
env:
CARGO_BUILD_JOBS: "1"
CARGO_INCREMENTAL: "0"
jobs:
budget:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Rust
run: |
curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --target wasm32-unknown-unknown
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: Actual WASM budget scenario
run: nice -n 19 python3 tools/airdef.py test-budgets
- name: Preserve machine-readable provenance
if: always()
uses: actions/upload-artifact@v4
with:
name: wasm-budget-provenance
path: .horizon-cache/wasm-budget-report.json
if-no-files-found: warn
+20
View File
@@ -0,0 +1,20 @@
# Heavy sandbox runtime is opt-in on the shared 2-core runner.
name: wasm-contract
on:
workflow_dispatch:
env:
CARGO_BUILD_JOBS: "1"
CARGO_INCREMENTAL: "0"
jobs:
contract:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Rust
run: |
curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --target wasm32-unknown-unknown
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: Actual WASM contract
run: nice -n 19 python3 tools/airdef.py test-wasm
+1 -1
View File
@@ -1,7 +1,7 @@
/horizon/
run-home/
.horizon-cache/
airdef-mod/target/
airdef-core/target/
__pycache__/
/out/
.DS_Store
+3
View File
@@ -0,0 +1,3 @@
[submodule "horizon"]
path = horizon
url = https://gitea.maoniao.team/chexit/horizon-airdef.git
-1
View File
@@ -1 +0,0 @@
b6c936f82b08798057161bdfa577e3aac53fb91e
+118 -32
View File
@@ -1,11 +1,18 @@
# AirDef — дальнобойные дроны и ПВО для Horizon
Мод для Horizon (Minecraft 26.3 на Rust): Шахед-136, Герань-3, Patriot и Гепард с 3D-моделями,
наведением ракет, слежением башен, падением сбитых дронов и эффектами взрывов.
Клиентский sandbox-мод для Horizon (Minecraft 26.3 на Rust): налёты дронов и ракет,
эшелонированная ПВО, раздельные батареи, наземная логистика, разведка, РЭБ, повреждения,
повторы и экспорт видео. Характеристики и временные масштабы игровые; это не тренажёр реальных комплексов.
Работает на **своём форке Horizon** (`horizon/`, ветка `airdef`): в нём добавлен API отрисовки
Работает на **[своём форке Horizon](https://gitea.maoniao.team/chexit/horizon-airdef)**
(`horizon/` — сабмодуль, закреплённый SHA): в нём добавлен API отрисовки
3D-моделей, которого нет в основном Horizon.
Рабочая ветка — **`kimi-work`**. Подробный проверенный объём и оставшаяся приёмка:
[состояние задач](docs/IMPLEMENTATION-STATUS.md). Для передачи разработки:
[технический журнал и handoff](docs/CODEX-HANDOFF.md). Открытый issue не означает отсутствие
реализации: по просьбе владельца агенты оставляют комментарии, но не закрывают задачи.
![Перехваты](screenshots/intercepts.jpg)
## Запуск
@@ -16,10 +23,21 @@
Коротко, из исходников:
```bash
python3 tools/airdef.py all # скачать Horizon, наложить патчи форка, собрать игру и мод, установить мод
git switch kimi-work
git pull --ff-only
git submodule update --init --recursive # также выполняется командой all
python3 tools/airdef.py all # получить закреплённый движок, собрать игру и мод, установить мод
python3 tools/airdef.py play # запустить (аргументы игры — после: --world "Имя мира")
```
`all` синхронизирует URL сабмодуля из `.gitmodules`, включая обновление со старого upstream.
Продолжение 4 ноября: [модели, границы ядра, общий каталог, API29 и массовая акустика](docs/CONTINUATION-2026-11-04.md).
Диагностика в игре: `/airdef capabilities` показывает доступность API, принятие запроса и
подготовку дыма, акустики и захвата именно этого мода. Подготовка не означает готовый GPU-кадр или MP4.
Для разработчика: `python3 tools/airdef.py test-wasm` — лёгкий ABI-тест;
`python3 tools/airdef.py test-budgets` — отдельный тяжёлый сценарий с JSON-отчётом.
Для разработки: `./install.sh` перегенерирует модели (`tools/gen_models.py`, нужен Pillow) и звуки
(`tools/gen_sounds.py`, нужны numpy и ffmpeg), собирает и ставит мод. Сгенерированные файлы лежат в репозитории,
так что для обычной сборки нужен только Rust.
@@ -52,10 +70,11 @@ CI: `.gitea/workflows/build.yml` на каждый пуш собирает то
волнами по типам), дальность старта, цели и **ПУСК**. Цели:
- *только объекты* — всё летит по отмеченным объектам (или по игроку, если их нет);
- *объекты и ПВО* — треть ударных средств бьёт по случайным комплексам;
- *умный противник* — планировщик знает, где стоят комплексы и что видят их РЛС: ведёт дроны и крылатые ракеты
- *умный противник* — планировщик использует наблюдённые контакты и последние известные позиции комплексов: ведёт дроны и крылатые ракеты
маршрутами в обход зон поражения, низко, за рельефом и через мёртвые зоны; «Герберы» прилетают на 15 с раньше,
чтобы оттянуть ракеты; «Ланцеты» идут по Гепардам и Панцирям, Х-22/Циркон и часть баллистики — по дальнобойным
комплексам; всё остальное стартует со сдвигом так, чтобы прилететь одновременно.
комплексам; на наблюдённые РЛС дальнего обнаружения выделяются 2–3 быстрых ударника (Х-22, Циркон, Искандер, Кинжал, затем Х-101,
Герань-3, Ланцет, Шахед; не больше четверти налёта); всё остальное стартует со сдвигом так, чтобы прилететь одновременно.
После налёта приходит отчёт: сколько сбито и прорвалось, ракет ПВО потрачено, комплексов потеряно, урон объектам.
@@ -71,16 +90,39 @@ CI: `.gitea/workflows/build.yml` на каждый пуш собирает то
**Сохранение.** Комплексы, объекты, их повреждения и настройки сохраняются отдельно для каждого мира (и для каждого
сервера); уничтоженный комплекс остаётся остовом и после перезахода, пока его не отремонтируют.
Налёт в воздухе тоже сохраняется: дроны, очередь их запуска и незавершённые задания на маршрут
восстанавливаются, и перезаход не обрывает перенацеливание. Ракеты-перехватчики в воздухе и площадки
запуска не сохраняются; сценарий — стартовое состояние и налёт не несёт.
**Сеть ПВО.** Каждая единица делится целями со всеми в радиусе 1,5 км (линия связи): РЛС дальнего обнаружения
даёт раннее предупреждение всем, пусковая без своей РЛС (P1-SUN) стреляет по чужим данным. Пушкам (Гепард,
**Сеть ПВО.** Единицы обмениваются измеренными треками в пределах игровой связи; повреждение связи
сокращает её дальность. Можно поставить несколько С-400/С-500 без собственной РЛС и общие радары
поиска, сопровождения и мачтового обзора: N → «Разместить элементы батареи…».
Поисковый радар даёт подсказку; огневой должен сам измерить цель, прежде чем разрешить пуск.
Старая сборная конфигурация сохранена. [Команды, источники и ограничения](docs/BATTERIES-AND-COLD-LAUNCH.md).
P1-SUN также использует чужие данные. Пушкам (Гепард,
пушки Панциря) нужна своя цель: они стреляют только по тому, что видят сами. Уничтоженная РЛС — дыра в сети.
**Радиомолчание.** `/airdef radar <номер> off|on` или кнопка в карточке техники на карте
выключает/включает собственный радар. Приём разрешённых внешних треков сохраняется; чужой трек
не заменяет обязательное собственное сопровождение. Выключение не стирает старые сведения противника:
он продолжает использовать последнюю наблюдённую позицию, а пуски и РЭБ могут снова раскрыть технику.
**Логистика.** Пока нет ни одного склада, магазины пополняются сами, как раньше. Как только поставлен склад,
боекомплект считается: комплекс без ракет пишет «ЖДЁТ БК»; в 60 м от склада он перезаряжается прямо с него, а
дальние обслуживают **ТЗМ**: заправляются на складе (2 перезарядки), сами едут к ждущим комплексам, ближайшим
первым, и возвращаются. Запас склада — 30 перезарядок, он виден в сводке. Склад и ТЗМ детонируют всем грузом.
Ударная **RM48U у С-400** — отдельный условный игровой боеприпас, который делит четыре ячейки
с ракетами ПВО. `/airdef ground-stock <склад> <количество>` задаёт конечный начальный запас
sandbox-сценария, `/airdef ground-load <С-400>` загружает одну ракету рядом со складом либо
создаёт заявку на доставку ТЗМ. Груз едет физически; снятая ракета ПВО возвращается на склад.
Заявка и груз сохраняются в пути. `/airdef ground-unload <С-400>` выгружает ракету у склада,
а вдали создаёт заявку на обратный вывоз ТЗМ. Одна ракета резервируется от пуска до забора;
`/airdef ground-cancel <С-400>` отменяет ещё ожидающую доставку или вывоз.
После забора ракета находится в машине и едет на склад. Отмена заявки не возвращает уже вывезенный груз в ПУ.
Без склада этот ударный боеприпас сам не появляется. Бук и остальные комплексы такого профиля пока не имеют.
Порядок подготовки, разведка и номера двух списков: [как ударить по ПУ](docs/GROUND-STRIKES.md).
**Перемещение.** **Пульт перемещения**: навестись на технику (выбрать), затем на точку на земле — она
сворачивается (С-400 и другие с вертикальным пуском дольше, Гепард и Панцирь быстро), едет по рельефу и
разворачивается; всё это время не стреляет и не светит РЛС. Или `/airdef move <номер>` — к тому месту, где ты стоишь.
@@ -94,9 +136,12 @@ CI: `.gitea/workflows/build.yml` на каждый пуш собирает то
**Умный противник учится.** Он запоминает, откуда его налёты сбивали, а откуда они прорывались, и следующий
налёт ведёт с лучшего направления; помнит комплексы, выдавшие себя пуском, и станции РЭБ, и во время налёта
перенацеливает ещё не взлетевшие Ланцеты и Шахеды на них; если цель-комплекс уничтожен, дроны идут к
следующему известному. Дроны под обстрелом прижимаются к земле.
следующему известному. Маршруты к новым целям достраиваются по бюджету планировщика в следующих тиках:
необработанное задание не теряется, старый безопасный участок остаётся до готовности нового, а дрон без
маршрута летит прямо только до ближайшего бюджета. Дроны под обстрелом прижимаются к земле.
**Ночь.** Ночью пушки попадают втрое хуже, если цель не освещена. Освещают **прожекторы** (луч ведёт ближайшую
**Ночь.** Исправные пушки с собственным свежим радарным сопровождением не теряют точность из-за темноты.
Цели освещают **прожекторы** (луч ведёт ближайшую
цель из сети, приоритет — цели пушек) и **осветительные ракеты**: пушечные комплексы пускают их сами (раз в
25 с на цель в темноте), игрок — **осветительным пистолетом** или `/airdef flare`. Ракета висит ~30 с и
освещает всё вокруг на ~60–90 м.
@@ -109,6 +154,10 @@ CI: `.gitea/workflows/build.yml` на каждый пуш собирает то
тонмаппинг (ванильный диапазон не трогается, сжимается только то, что ярче). Источники передаются движку новым
API мода `render.set-lights` (до 512, плавно интерполируются), режим — `render.set-lighting`.
В HD дымовые следы ракет немного уплотнены; число сегментов и время появления/выгорания сохранены.
Это относится к ракетам ПВО, RM48U, крылатым, сверхзвуковым и баллистическим средствам;
дым пожаров и слабая дымка винтовых дронов остались прежними.
**Сетка J** после сбития ещё 3,5 с держит камеру на сбитой цели, и комплекс в это время не пропадает из сетки.
**Повреждения.** Взрыв рядом с комплексом повреждает его: он хуже поворачивается, хуже видит и попадает,
@@ -117,6 +166,11 @@ API мода `render.set-lights` (до 512, плавно интерполиру
пострадать. Объекты (Целеуказатель или `/airdef target here`) имеют прочность, она видна в сводке. Ремонт —
кнопкой в меню или `/airdef repair`.
Известные стены и рельеф ослабляют **непрямой** урон корпусу, узлам и объектам; проёмы дают
частичное воздействие. Используется геометрия, известная перед разрушением. При неизвестной или
устаревшей геометрии сохраняется прежний урон без защиты; поздний ответ его повторно не наносит.
Прямое вооружённое попадание этим ослаблением не отменяется.
**Монитор комплекса:** клавиша **K** листает комплексы по очереди, после последнего монитор скрывается. Слева вверху показано:
- состояние комплекса (поиск, сопровождение, доворот, захват, пуск, огонь, перезарядка, огонь запрещён);
- его РЛС: цели, по которым он работает, красным, остальные серым, текущая цель жёлтым;
@@ -149,13 +203,19 @@ API мода `render.set-lights` (до 512, плавно интерполиру
Клавиши N, K, J, R и U можно переназначить в «Настройки → Моды».
Команды:
- `/airdef wave <тип> [кол-во] [дальность]` — налёт на ближайшую цель. Типы: `shahed`, `geran3`, `lancet`, `gerbera`, `kh101`, `kalibr`, `kh22`, `zircon`, `iskander`, `kinzhal`, `oreshnik` и `mix` (комбинированный удар двумя секторами: «Герберы», шахеды, Герани-3, Х-101, «Калибры», Х-22, Циркон, «Искандер», «Кинжал», при 30+ — «Орешник»);
- `/airdef wave <тип> [кол-во] [дальность]` — налёт на ближайшую цель. Дальность старта — от 60 до 4000 блоков (в меню: 200–4000); землю для площадок, которой нет в загруженных чанках, игра подгружает сама (API 22, `render.load-chunks`, пока идёт поиск), а где подгрузить нельзя (сервер) или нет пригодного места, дроны всё равно стартуют: «за картой», с высоты полёта на заказанной дальности, без площадки. Типы: `shahed`, `geran3`, `lancet`, `gerbera`, `kh101`, `kalibr`, `kh22`, `zircon`, `iskander`, `kinzhal`, `oreshnik` и `mix` (комбинированный удар двумя секторами: «Герберы», шахеды, Герани-3, Х-101, «Калибры», Х-22, Циркон, «Искандер», «Кинжал», при 30+ — «Орешник»);
- `/airdef replay [map|full|reel|stop]` — повтор последнего налёта;
- `/airdef replay film [best|all|N]` — фильм режиссёра: для каждого перехвата/прилёта несколько планов (комплекс, пуск, погоня за ракетой, взгляд с цели, замедленный крупный план поражения, общий план после), склейки, плавные движения камеры, камера не уходит под землю; играется в максимальном качестве (HD, мир в полном разрешении, больше шагов облаков и тумана; настройки возвращаются после);
- `/airdef replay export [имя] [best|all|N] [fps=60] [size=1920x1080] [crf=14] [sec=N] [noaudio]` — тот же фильм кадр за кадром с фиксированным шагом (скорость компьютера не важна) в MP4 с звуком: `<HORIZON_HOME>/airdef-films/<имя>.mp4` (нужен `ffmpeg` в PATH или `HORIZON_FFMPEG`; без него — PNG-последовательность и готовая команда ffmpeg). Прогресс в чате, отмена — `/airdef replay stop`. Окно игры держите в фокусе (пауза останавливает съёмку); чат попадает в кадр.
- `/airdef import` — перенести в текущий мир комплексы и цели из старой версии мода (до 0.2.x они были общими для всех миров);
- `/airdef raid` — налёт, настроенный в меню; `/airdef target here` — отметить объект под ногами; `/airdef repair` — ремонт;
- `/airdef lastchance <on|off>` — «последний шанс»: комплекс стреляет и по классу вне ролей, если цель вот-вот попадёт (по умолчанию вкл; сохраняется);
- `/airdef sites` — известные пусковые площадки (ПУ). РЛС с прямой видимостью может заметить сам пуск и получить неточную позицию; несколько наблюдённых пусков уточняют её. Обнаруженный позже дрон даёт только слабое предположение об обратном курсе: скрытые координаты площадки и время невидимого старта не используются. Повторные треки одного полёта не создают ложную точность.
- `/airdef strike <номер ПУ>` — ручной удар по разведанной площадке из готового физического С-400 с отдельно загруженной RM48U (игровой профиль, #118). Четыре ячейки делятся с боезапасом ПВО; приказ резервирует носитель и ячейку, открывает крышку и списывает одну ударную ракету при выбросе. Выбирается готовый комплекс с наибольшим остатком RM48U, затем ближайший к цели. Есть открытие ТПК, выброс, отложенное включение двигателя и разгон, ограниченная игровая траектория, столкновения и запись пуска. Несуществующее «ПВО площадки» не перехватывает ракету по броску вероятности.
- `/airdef ground-stock <номер склада> <количество>` — задать остаток RM48U для sandbox-сценария (по умолчанию 0). `/airdef ground-load <номер С-400>` загружает одну ракету у склада либо заказывает ТЗМ; `ground-unload` возвращает её у склада либо заказывает вывоз; `ground-cancel` отменяет ожидающую заявку. Доставка и обратный вывоз через ТЗМ реализованы, запас и груз сохраняются. [Пошаговый пример](docs/GROUND-STRIKES.md). Совместимость профиля основана на [публикации ГУР](https://gur.gov.ua/content/warsanctions-hur-mo-rozkryvaie-budovu-komponentnu-bazu-ta-pidpryiemstva-kooperatsii-z-vyrobnytstva-udarnykh-raket-rm48u.html); это сообщение ведомства, не независимая сертификация. Дальность, форма полёта и оформление условны для Minecraft.
- `/airdef deploy s400_launcher` и `s500_launcher` — отдельные пусковые без своей РЛС; `radar_search`, `radar_track`, `radar_height` — обзорная, сопровождающая и мачтовая игровые РЛС. Они также доступны через меню N → «Разместить элементы батареи…». `/airdef battery` показывает состав и связь; `/airdef battery <номер> integrated|launcher` меняет конфигурацию, `/airdef radar <номер> multi|search|engagement|height` — роль отдельной РЛС. Обзорная РЛС передаёт подсказки; станция сопровождения должна сама получить свежее измерение, чтобы разрешить пуск. Старые С-400/С-500 сохраняют упрощённую сборную конфигурацию. [Устройство игровой батареи и пуска](docs/BATTERIES-AND-COLD-LAUNCH.md).
- `/airdef roles` — показать, по каким классам целей работает каждый комплекс; `/airdef roles <patriot|gepard|pantsir|s400|s500|all> <классы|default>` — задать (классы через запятую: `drone`, `jet`, `cruise`, `supersonic`, `ballistic` или `all`), например `/airdef roles s400 cruise,ballistic`;
- `/airdef doctrine` — доктрины комплексов (#47; в меню N: «Доктрины…»): `/airdef doctrine <номер|all> reserve <K>` — держать K ракет для срочных целей (баллистика или до удара меньше 12 с); `salvo eco|normal|heavy` — сколько перехватчиков на цель (только базовые / как обычно / на один больше); `sector <центр°> <полуширина°>` или `sector off` — сектор ответственности (0° — север); `guard <объект№>[,<№>]` или `guard off` — стрелять только по тому, что идёт на охраняемые объекты (отметка: `/airdef target here`). По умолчанию ограничений нет; последний шанс сильнее доктрины; `/airdef why <номер>` называет, какая настройка остановила или разрешила пуск; сохраняется с миром и сценариями. Карта охраны и пробелов в ней — вместе с картой (#48).
- `/airdef deploy <patriot|gepard|pantsir|s400|s500>` — поставить комплекс в 8 блоках перед собой;
- `/airdef hold on|off` — запретить или разрешить ПВО огонь, удобно для съёмки ударов;
- `/airdef damage on|off` — разрушать ли ландшафт взрывами (через TNT, нужны читы);
@@ -192,24 +252,42 @@ API мода `render.set-lights` (до 512, плавно интерполиру
| ПВО | Вооружение | Дальность |
|---|---|---|
| Patriot | 4 × PAC-3, пусковая разворачивается на цель | 10–300 |
| Гепард | 2 × 35 мм, башня и стволы со слежением и упреждением, 160 очередей | 90 (слежение с 130) |
| Панцирь-С1 | 12 × 57Э6 и 2 × 30 мм; модуль поворачивается, пакеты и стволы поднимаются | ракеты 25–150, пушки 60 |
| С-400 | 4 × 48Н6, вертикальный холодный старт, РЛС обзора на прицепе | 30–480 |
| С-500 | 4 × 77Н6, холодный старт, самые быстрые ракеты | 40–700 |
| 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 |
| Patriot | 4 × PAC-3, пусковая разворачивается на цель | 10–450 |
| Гепард | 2 × 35 мм, башня и стволы со слежением и упреждением, 160 очередей | 135 (слежение с 195) |
| Панцирь-С1 | 12 × 57Э6 и 2 × 30 мм; модуль поворачивается, пакеты и стволы поднимаются | ракеты 25–225, пушки 90 |
| С-400 | 4 × 48Н6, вертикальный холодный старт, РЛС обзора на прицепе | 30–720 |
| С-500 | 2 × 77Н6, холодный старт, самые быстрые ракеты | 40–1050 |
| IRIS-T SLM | 8 ракет, вертикальный пуск, быстрые и манёвренные | 15–600 |
| NASAMS | 6 × AMRAAM, наводимая пусковая на прицепе | 10–450 |
| Бук-М2 | 4 × 9М317 на направляющих, башня с РЛС подсвета | 20–675 |
| Тор-М2 | 8 × 9М338 вертикально из башни, быстрая реакция против дронов | 8–240 |
| P1-SUN | 8 дронов-перехватчиков против Шахедов и Герань; своей РЛС нет — стреляет по данным сети | 5–675 |
Обслуживающая техника (тоже пультами или `/airdef deploy <ключ>`): **РЛС дальнего обнаружения** (`radar`,
видит на 1,7 км с высокой мачты, хуже прячутся за рельефом), **склад боеприпасов** (`depot`), **ТЗМ** (`tzm`),
видит на 2,5 км с высокой мачты, хуже прячутся за рельефом), **склад боеприпасов** (`depot`), **ТЗМ** (`tzm`),
**станция РЭБ** (`ew`), **прожектор** (`light`). Новые комплексы: `irist`, `nasams`, `buk`, `tor`, `p1sun`.
**Согласование огня.** Комплексы делят цели между собой: на обычную цель идёт одна ракета, на баллистическую две,
пушки расходятся по разным целям. Первыми бьют по самым опасным (быстрым и тяжёлым) целям, при этом ложные
«Герберы» выглядят для них как настоящие. Шанс поражения падает, если цель быстрее перехватчика.
**Согласование огня.** Комплексы делят цели между собой: на обычную цель идёт одна ракета, на баллистическую две; чем ближе цель к своей точке попадания,
тем больше перехватчиков разрешено на неё сразу (за ~12 с до удара ещё один, за ~5 с — ещё один). Комплекс, у которого кончились ракеты
или идёт перезарядка, цель не держит; тот, кто не смог навестись за ~2 с, отпускает её другим. Пушки расходятся по разным целям. Первыми бьют по самым опасным (быстрым и тяжёлым) целям, при этом ложные
«Герберы» выглядят для них как настоящие. Геометрия встречи проверяется по движению обоих объектов
за тик, а остаточный шанс учитывает фактическую скорость перехватчика.
**Энергетика перехватчика.** Сначала ракета выходит из ТПК без двигателя: у С-400 это 1,0 с,
у С-500 — 1,2 с; только потом в её текущей точке зажигается факел, и тяга плавно нарастает.
После выброса ракета разгоняется, но двигатель работает конечное игровое время. После выгорания
ракета летит по инерции, теряет скорость и манёвренность; при недостаточной скорости сопровождение
срывается. Факел, звук двигателя и новый дым прекращаются при выгорании и в live, и в повторе;
уже созданный дым продолжает рассеиваться. У ракет с горячим (рельсовым) пуском тяга тоже
нарастает плавно, но холодного выброса нет; электрический P1-SUN не получает ракетную струю.
**Последний шанс** (`/airdef lastchance on|off`, по умолчанию вкл). Комплекс стреляет и по классу целей вне своих ролей
(С-400, С-500 и Patriot по умолчанию не бьют дроны), если цель долетит до своей точки меньше чем за 10 с и на ней ещё нет
ничьего перехватчика. Комплексу с пустыми ролями (огонь запрещён) это не касается. `/airdef why` пишет «последний шанс».
**Дальний пуск по РЛС.** С-400, С-500 и Patriot могут стрелять дальше своей дальности (до 1,6×) по цели, которую держит
свежим треком РЛС дальнего обнаружения в радиусе связи: не чаще раза в 15 с, при не менее чем половине боезапаса, только по
своим ролям и только пока в обычной дальности нет цели; шанс поражения на краю вдвое ниже. `/airdef why`: «дальний пуск по РЛС».
**Роли по умолчанию** (в сводке в квадратных скобках: Д — дроны, Г — реактивные, К — крылатые, С — сверхзвуковые,
Б — баллистика): Гепард ДГК, Панцирь ДГКС, Patriot ГКСБ, С-400 ГКСБ, С-500 СБ. Сбитый дрон падает с остатком скорости, и его боевая часть
@@ -252,16 +330,18 @@ API мода `render.set-lights` (до 512, плавно интерполиру
## Устройство
```
HORIZON_COMMIT коммит апстрима Horizon, на который накладываются патчи
horizon-patches/ изменения форка (git format-patch); tools/airdef.py fork собирает из них horizon/
horizon/ форк (не в репозитории; ветка airdef). Что в нём меняется:
.gitmodules URL отдельного репозитория движка
horizon/ git submodule: точный SHA форка Horizon. Что в нём меняется:
crates/horizon-mod-sdk/wit/horizon.wit render.set-models, spawn-particles, play-sound,
query-ground / ground
crates/horizon-mods/src/runtime.rs хост этих функций
crates/horizon-client/src/game/mod_models.rs интерполяция и отрисовка моделей, частицы
crates/horizon-client/src/gfx/mod_post.rs пост-проход мода: render.set-post / set-params
airdef-mod/ сам мод: Rust → WebAssembly
src/sim.rs симуляция: дроны, ракеты, ПВО, эффекты (20 тиков/с)
airdef-core/ SDK-free сборка общего ядра; использует те же исходники sim, без копии
airdef-mod/ адаптер: Rust → WebAssembly
src/sim/mod.rs симуляция: дроны, ракеты, ПВО, эффекты (20 тиков/с)
src/sim/battery.rs конфигурации пусковых и роли общей РЛС
src/sim/launch.rs резервирование ячеек и анимация крышек ТПК
src/lib.rs предметы, команды, сохранение, передача в движок
src/panel.rs сводка, src/radar.rs — радар, src/monitor.rs — монитор комплекса
assets/airdef/sounds звуки (генерирует tools/gen_sounds.py)
@@ -281,11 +361,17 @@ run-home/ тестовая игровая папка (для пров
Модели — обычные блочные JSON-модели, по одной на часть: корпус, винт, башня, стволы. Их генерирует
`tools/gen_models.py`. Координаты элементов должны быть в пределах −16..32, иначе Horizon отбросит модель.
Рельеф мод узнаёт через `render.query-ground`: присылает колонки, а движок отвечает высотой по карте
высот на следующем тике.
Рельеф и коллизии приходят асинхронно через ground/ray/section queries. Высотной карты недостаточно
для точного попадания: известные блоки и формы проверяются отдельно; ожидание/Unknown не считается
доказанным свободным путём. Историческое отображение повтора отделено от live-геометрии симуляции.
## Известные ограничения
- Для [#122](https://gitea.maoniao.team/chexit/airdef/issues/122) воспроизведено и исправлено исчерпание fuel при массовых взрывах:
каждый взрыв больше не обходит всю карту высот. Проверка на конкретном Windows-компьютере ещё нужна;
прирост FPS этим исправлением не обещается.
- Мод клиентский: дроны и ПВО видит только тот, у кого он стоит. Мультиплеер не поддерживается.
- Окно Horizon на macOS не рисует кадры, пока оно перекрыто другими окнами (это поведение движка).
- Шейдер работает, только если не включён шейдер-пак Horizon (они взаимоисключающие).
Разработка и обновление закреплённого движка: [docs/ENGINE.md](docs/ENGINE.md).
+16
View File
@@ -0,0 +1,16 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "airdef-core"
version = "0.2.0"
dependencies = [
"glam",
]
[[package]]
name = "glam"
version = "0.30.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19fc433e8437a212d1b6f1e68c7824af3aed907da60afa994e7f542d18d12aa9"
+13
View File
@@ -0,0 +1,13 @@
[package]
name = "airdef-core"
version = "0.2.0"
edition = "2024"
publish = false
[dependencies]
glam = "0.30"
[features]
test-fixtures = []
[workspace]
+13
View File
@@ -0,0 +1,13 @@
# AirDef headless simulation
This package compiles the same `airdef-mod/src/sim` source as the game adapter, with `glam` as its only dependency. A checkout does not need the Horizon submodule to build or run it:
```sh
cargo test --manifest-path airdef-core/Cargo.toml
cargo run --manifest-path airdef-core/Cargo.toml --release --example sim_run -- --list
cargo run --manifest-path airdef-core/Cargo.toml --release --example sim_run -- --scenario big-smart
```
The shared scenario harness runs for both packages. Adapter integration tests for layout and smoke stay in `airdef-mod`; `core_boundary` verifies the public type facade and deterministic combat trace.
This is an incremental boundary: the simulation still produces rendering and audio declarations and formats some UI text. Moving those outputs and diagnostics to adapters, remain follow-up work. The mod re-exports `airdef_core::sim` as its existing public facade.
+8
View File
@@ -0,0 +1,8 @@
//! The enemy-picture bench (#127) without building the Horizon SDK.
extern crate airdef_core as airdef;
#[path = "../../airdef-mod/examples/intel_bench.rs"]
mod bench;
fn main() {
bench::main();
}
+8
View File
@@ -0,0 +1,8 @@
//! Run the same native scenario CLI without building the Horizon SDK.
extern crate airdef_core as airdef;
#[path = "../../airdef-mod/examples/sim_run/main.rs"]
mod runner;
fn main() {
runner::main();
}
+6
View File
@@ -0,0 +1,6 @@
//! SDK-independent build of the same simulation used by the AirDef adapter.
//!
//! The source remains shared while the domain/presentation boundary is extracted;
//! no generated copy can drift from the mod's simulation.
#[path = "../../airdef-mod/src/sim/mod.rs"]
pub mod sim;
+166
View File
@@ -0,0 +1,166 @@
//! The mod's headless scenarios run against the SDK-independent package too.
extern crate airdef_core as airdef;
#[path = "../../airdef-mod/examples/sim_run/harness.rs"]
mod harness;
fn check(sc: harness::Scenario) -> harness::Report {
let r = harness::run(&sc);
let problems = r.problems();
assert!(problems.is_empty(), "scenario {} failed: {problems:?}\n{}", r.name, r.text());
assert!(r.launched > 0);
r
}
#[test]
fn big_smart_raid_on_61_systems() {
let r = check(harness::big_smart());
assert_eq!(r.units, 61);
assert!(r.fired > 0 && r.ground_queries > 0);
}
#[test]
fn logistics_trucks_depot_and_raid() {
let r = check(harness::logistics());
assert!(r.truck_busy_ticks > 0 && r.fired > 0);
}
#[test]
fn ew_and_adaptive_enemy_over_three_raids() {
assert_eq!(check(harness::ew_adaptive()).raids_ended, 3);
}
#[test]
fn same_seed_same_result() {
let a = harness::run(&harness::logistics());
let b = harness::run(&harness::logistics());
assert_eq!((a.ticks_run, a.launched, a.kills, a.hits, a.fired, a.ground_queries), (b.ticks_run, b.launched, b.kills, b.hits, b.fired, b.ground_queries));
}
#[test]
fn overlapping_mass_strikes_on_flat_world() {
use airdef::sim::{Aim, Approach, DroneKind as D, Ground, Out, RaidOrder, Sam, Sim};
use glam::DVec3;
let sc = harness::big_smart();
let terrain = harness::Terrain::Flat(70);
let mut sim = Sim::new(sc.seed);
sim.damage = false;
for unit in &sc.units {
let id = sim.id();
sim.sams.push(Sam::new(id, unit.kind, DVec3::new(unit.pos.x, 70.0, unit.pos.z), unit.heading));
}
sim.targets = vec![DVec3::new(0.0, 70.0, 0.0)];
sim.target_health = vec![100.0];
// Exact composition of the menu's "Массированный удар" preset.
let order = RaidOrder { kinds: vec![(D::Gerbera, 8), (D::Shahed, 12), (D::Geran3, 4), (D::Kh101, 4), (D::Kalibr, 4), (D::Kh22, 2), (D::Iskander, 2)], approach: Approach::AllSides, aim: Aim::Smart, dist: 4000.0 };
let mut ground = Ground::default();
let mut pending = Vec::new();
let mut out = Out::default();
let targets = sim.targets.clone();
assert_eq!(sim.order_raid(&order, &targets, &mut out), 36);
let mut second = false;
let mut peak = 0;
for now in 1..=12000 {
if !second && !sim.planning() {
assert_eq!(sim.order_raid(&order, &targets, &mut out), 36);
second = true;
}
ground.answer(std::mem::take(&mut pending), now);
out = Out::default();
sim.step(&mut ground, None, &mut out);
let wanted = ground.take_wanted();
pending = wanted.into_iter().map(|(x, z)| (x, z, 70)).collect();
let sections = ground.world.take_wanted(now);
ground.world.serve(&terrain, sections, now);
peak = peak.max(sim.drones.iter().filter(|d| d.alive()).count());
assert!(sim.drones.iter().all(|d| d.pos.is_finite() && d.vel.is_finite()));
if sim.launched >= 72 && peak > 36 { break; }
}
eprintln!("overlapping mass strikes: launched {}, peak airborne {peak}", sim.launched);
assert!(second && sim.launched >= 72, "second raid failed to launch; launched {}", sim.launched);
assert!(peak > 36, "raids never overlapped; peak {peak}");
}
#[test]
fn overlapping_oreshnik_splits_are_recorded() {
use airdef::sim::{Aim, Approach, DroneKind, Ground, Out, RaidOrder, Sim};
use glam::DVec3;
let mut sim = Sim::new(1);
sim.damage = false;
let targets = vec![DVec3::new(0.0, 70.0, 0.0)];
sim.targets = targets.clone();
sim.target_health = vec![100.0];
let order = RaidOrder { kinds: vec![(DroneKind::Oreshnik, 40)], approach: Approach::Sector, aim: Aim::Objects, dist: 2600.0 };
let terrain = harness::Terrain::Flat(70);
let mut ground = Ground::default();
let mut pending = Vec::new();
let mut out = Out::default();
assert_eq!(sim.order_raid(&order, &targets, &mut out), 40);
let mut second = false;
let mut peak = 0;
let mut peak_subs = 0;
for now in 1..=10000 {
if !second && !sim.planning() {
assert_eq!(sim.order_raid(&order, &targets, &mut out), 40);
second = true;
}
ground.answer(std::mem::take(&mut pending), now);
out = Out::default();
sim.step(&mut ground, None, &mut out);
pending = ground.take_wanted().into_iter().map(|(x, z)| (x, z, 70)).collect();
let sections = ground.world.take_wanted(now);
ground.world.serve(&terrain, sections, now);
peak = peak.max(sim.drones.iter().filter(|d| d.alive()).count());
peak_subs = peak_subs.max(sim.drones.iter().filter(|d| d.alive() && d.kind == DroneKind::OreshnikSub).count());
assert!(sim.drones.iter().all(|d| d.pos.is_finite() && d.vel.is_finite()));
if second && sim.launched >= 80 && !sim.replays.is_empty() { break; }
}
eprintln!("overlapping oreshnik: launched {}, peak airborne {peak}, peak submunitions {peak_subs}, replays {}", sim.launched, sim.replays.len());
assert_eq!(sim.launched, 2880);
assert!(peak_subs > 36, "expected many simultaneous submunitions");
assert!(!sim.replays.is_empty(), "recording did not finish");
}
#[test]
fn two_maximum_menu_raids_with_answered_flat_terrain() {
use airdef::sim::{Aim, Approach, Ground, Out, RaidOrder, Sam, Sim, catalog::RAID_KINDS};
use glam::DVec3;
let sc = harness::big_smart();
let terrain = harness::Terrain::Flat(70);
let mut sim = Sim::new(sc.seed);
for unit in &sc.units {
let id = sim.id();
sim.sams.push(Sam::new(id, unit.kind, DVec3::new(unit.pos.x, 70.0, unit.pos.z), unit.heading));
}
let targets = vec![DVec3::new(0.0, 70.0, 0.0)];
sim.targets = targets.clone();
sim.target_health = vec![100.0];
// The maximum selectable by the menu: 40 for each raid kind.
let order = RaidOrder { kinds: RAID_KINDS.iter().copied().map(|kind| (kind, 40)).collect(), approach: Approach::AllSides, aim: Aim::Smart, dist: 300.0 };
let expected = RAID_KINDS.len() as u32 * 40;
let mut ground = Ground::default();
let mut pending = Vec::new();
let mut out = Out::default();
assert_eq!(sim.order_raid(&order, &targets, &mut out), expected);
let mut second = false;
let mut overlap = false;
let mut peak = 0;
for now in 1..=5000 {
if !second && !sim.planning() {
overlap = !sim.queue.is_empty() || sim.drones.iter().any(|d| d.alive());
assert_eq!(sim.order_raid(&order, &targets, &mut out), expected);
second = true;
}
ground.answer(std::mem::take(&mut pending), now);
out = Out::default();
sim.step(&mut ground, None, &mut out);
pending = ground.take_wanted().into_iter().map(|(x, z)| (x, z, 70)).collect();
let sections = ground.world.take_wanted(now);
ground.world.serve(&terrain, sections, now);
peak = peak.max(sim.drones.iter().filter(|d| d.alive()).count());
assert!(sim.drones.iter().all(|d| d.pos.is_finite() && d.vel.is_finite()));
if second && sim.launched >= expected * 2 && !sim.replays.is_empty() { break; }
}
eprintln!("max menu raids: requested {}, launched {}, peak {peak}, replays {}", expected * 2, sim.launched, sim.replays.len());
assert!(second && overlap && sim.launched >= expected * 2 && peak > 40);
assert!(!sim.replays.is_empty(), "raid recording did not finish");
}
+8
View File
@@ -6,10 +6,18 @@ version = 4
name = "airdef"
version = "0.2.0"
dependencies = [
"airdef-core",
"glam",
"horizon-mod-sdk",
]
[[package]]
name = "airdef-core"
version = "0.2.0"
dependencies = [
"glam",
]
[[package]]
name = "anyhow"
version = "1.0.104"
+4
View File
@@ -9,9 +9,13 @@ description = "AirDef: long-range drones and air defence for the AirDef fork of
crate-type = ["cdylib", "rlib"]
[dependencies]
airdef-core = { path = "../airdef-core" }
horizon-mod-sdk = { path = "../horizon/crates/horizon-mod-sdk" }
glam = "0.30"
[dev-dependencies]
airdef-core = { path = "../airdef-core", features = ["test-fixtures"] }
[profile.release]
opt-level = "s"
lto = true
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "airdef:block/radar_mast"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "airdef:block/radar_mast_burnt"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "airdef:block/rm48u"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "airdef:block/tpk_cap"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "airdef:block/tpk_cap_burnt"
}
}
}
+5
View File
@@ -30,10 +30,13 @@
"block.airdef.s400_tubes": "ТПК 48Н6",
"block.airdef.s500_chassis": "Шасси С-500",
"block.airdef.s500_tubes": "ТПК 77Н6",
"block.airdef.tpk_cap": "Крышка ТПК (анимация)",
"block.airdef.radar_mast": "Радиомачта (секция высоты)",
"block.airdef.radar_trailer": "Прицеп РЛС",
"block.airdef.radar_panel": "РЛС обзора",
"block.airdef.m57e6": "57Э6",
"block.airdef.m48n6": "48Н6",
"block.airdef.rm48u": "RM48U (игровой профиль)",
"block.airdef.m77n6": "77Н6",
"block.airdef.kalibr": "Калибр",
"block.airdef.kh22": "Х-22",
@@ -76,6 +79,8 @@
"block.airdef.s400_tubes_burnt": "ТПК 48Н6 (остов)",
"block.airdef.s500_chassis_burnt": "Шасси С-500 (остов)",
"block.airdef.s500_tubes_burnt": "ТПК 77Н6 (остов)",
"block.airdef.tpk_cap_burnt": "Крышка ТПК (анимация) (остов)",
"block.airdef.radar_mast_burnt": "Радиомачта (секция высоты) (остов)",
"block.airdef.irist_chassis_burnt": "Шасси IRIS-T SLM (остов)",
"block.airdef.irist_tubes_burnt": "Пакет IRIS-T (остов)",
"block.airdef.nasams_trailer_burnt": "Прицеп NASAMS (остов)",
+5
View File
@@ -30,10 +30,13 @@
"block.airdef.s400_tubes": "ТПК 48Н6",
"block.airdef.s500_chassis": "Шасси С-500",
"block.airdef.s500_tubes": "ТПК 77Н6",
"block.airdef.tpk_cap": "Крышка ТПК (анимация)",
"block.airdef.radar_mast": "Радиомачта (секция высоты)",
"block.airdef.radar_trailer": "Прицеп РЛС",
"block.airdef.radar_panel": "РЛС обзора",
"block.airdef.m57e6": "57Э6",
"block.airdef.m48n6": "48Н6",
"block.airdef.rm48u": "RM48U (игровой профиль)",
"block.airdef.m77n6": "77Н6",
"block.airdef.kalibr": "Калибр",
"block.airdef.kh22": "Х-22",
@@ -76,6 +79,8 @@
"block.airdef.s400_tubes_burnt": "ТПК 48Н6 (остов)",
"block.airdef.s500_chassis_burnt": "Шасси С-500 (остов)",
"block.airdef.s500_tubes_burnt": "ТПК 77Н6 (остов)",
"block.airdef.tpk_cap_burnt": "Крышка ТПК (анимация) (остов)",
"block.airdef.radar_mast_burnt": "Радиомачта (секция высоты) (остов)",
"block.airdef.irist_chassis_burnt": "Шасси IRIS-T SLM (остов)",
"block.airdef.irist_tubes_burnt": "Пакет IRIS-T (остов)",
"block.airdef.nasams_trailer_burnt": "Прицеп NASAMS (остов)",
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -4,8 +4,7 @@
"missile_ru": "airdef:block/missile_ru",
"booster": "airdef:block/booster",
"dark_metal": "airdef:block/dark_metal",
"ru_green_s31": "airdef:block/ru_green_s31",
"ru_green": "airdef:block/ru_green",
"pilot_olive": "airdef:block/pilot_olive",
"particle": "airdef:block/missile_ru"
},
"elements": [
@@ -844,7 +843,7 @@
16,
2.0
],
"texture": "#ru_green_s31"
"texture": "#pilot_olive"
},
"south": {
"uv": [
@@ -853,7 +852,7 @@
16,
2.0
],
"texture": "#ru_green_s31"
"texture": "#pilot_olive"
},
"east": {
"uv": [
@@ -862,7 +861,7 @@
16,
2.0
],
"texture": "#ru_green"
"texture": "#pilot_olive"
},
"west": {
"uv": [
@@ -871,7 +870,7 @@
16,
2.0
],
"texture": "#ru_green"
"texture": "#pilot_olive"
},
"up": {
"uv": [
@@ -880,7 +879,7 @@
16,
16
],
"texture": "#ru_green_s31"
"texture": "#pilot_olive"
},
"down": {
"uv": [
@@ -889,9 +888,9 @@
16,
16
],
"texture": "#ru_green_s31"
"texture": "#pilot_olive"
}
}
}
]
}
}
@@ -4,8 +4,7 @@
"missile_ru_b": "airdef:block/missile_ru_b",
"booster_b": "airdef:block/booster_b",
"dark_metal_b": "airdef:block/dark_metal_b",
"ru_green_s31_b": "airdef:block/ru_green_s31_b",
"ru_green_b": "airdef:block/ru_green_b",
"pilot_olive_b": "airdef:block/pilot_olive_b",
"particle": "airdef:block/missile_ru_b"
},
"elements": [
@@ -844,7 +843,7 @@
16,
2.0
],
"texture": "#ru_green_s31_b"
"texture": "#pilot_olive_b"
},
"south": {
"uv": [
@@ -853,7 +852,7 @@
16,
2.0
],
"texture": "#ru_green_s31_b"
"texture": "#pilot_olive_b"
},
"east": {
"uv": [
@@ -862,7 +861,7 @@
16,
2.0
],
"texture": "#ru_green_b"
"texture": "#pilot_olive_b"
},
"west": {
"uv": [
@@ -871,7 +870,7 @@
16,
2.0
],
"texture": "#ru_green_b"
"texture": "#pilot_olive_b"
},
"up": {
"uv": [
@@ -880,7 +879,7 @@
16,
16
],
"texture": "#ru_green_s31_b"
"texture": "#pilot_olive_b"
},
"down": {
"uv": [
@@ -889,9 +888,9 @@
16,
16
],
"texture": "#ru_green_s31_b"
"texture": "#pilot_olive_b"
}
}
}
]
}
}
@@ -1,11 +1,11 @@
{
"ambientocclusion": false,
"textures": {
"ru_green_s21": "airdef:block/ru_green_s21",
"ru_green_s22": "airdef:block/ru_green_s22",
"pilot_olive": "airdef:block/pilot_olive",
"radar_face": "airdef:block/radar_face",
"ru_green": "airdef:block/ru_green",
"particle": "airdef:block/ru_green_s21"
"dark_metal": "airdef:block/dark_metal",
"metal": "airdef:block/metal",
"particle": "airdef:block/pilot_olive"
},
"elements": [
{
@@ -16,7 +16,7 @@
],
"to": [
20.0,
9.0,
7.0,
20.0
],
"faces": {
@@ -25,36 +25,36 @@
0,
0,
16,
9.0
7.0
],
"texture": "#ru_green_s21"
"texture": "#pilot_olive"
},
"south": {
"uv": [
0,
0,
16,
9.0
7.0
],
"texture": "#ru_green_s21"
"texture": "#pilot_olive"
},
"east": {
"uv": [
0,
0,
16,
9.0
7.0
],
"texture": "#ru_green_s21"
"texture": "#pilot_olive"
},
"west": {
"uv": [
0,
0,
16,
9.0
7.0
],
"texture": "#ru_green_s21"
"texture": "#pilot_olive"
},
"up": {
"uv": [
@@ -63,7 +63,7 @@
16,
16
],
"texture": "#ru_green_s22"
"texture": "#pilot_olive"
},
"down": {
"uv": [
@@ -72,7 +72,75 @@
16,
16
],
"texture": "#ru_green_s22"
"texture": "#pilot_olive"
}
}
},
{
"from": [
-2.0,
7.0,
2.0
],
"to": [
18.0,
10.0,
18.0
],
"faces": {
"north": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#pilot_olive"
},
"south": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#pilot_olive"
},
"east": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#pilot_olive"
},
"west": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#pilot_olive"
},
"up": {
"uv": [
0,
0,
16,
16
],
"texture": "#pilot_olive"
},
"down": {
"uv": [
0,
0,
16,
16
],
"texture": "#pilot_olive"
}
}
},
@@ -83,7 +151,7 @@
-10.0
],
"to": [
15.0,
11.0,
14.0,
-4.0
],
@@ -92,7 +160,7 @@
"uv": [
0,
0,
14.0,
10.0,
12.0
],
"texture": "#radar_face"
@@ -101,7 +169,7 @@
"uv": [
0,
0,
14.0,
10.0,
12.0
],
"texture": "#radar_face"
@@ -128,7 +196,7 @@
"uv": [
0,
0,
14.0,
10.0,
6.0
],
"texture": "#radar_face"
@@ -137,7 +205,7 @@
"uv": [
0,
0,
14.0,
10.0,
6.0
],
"texture": "#radar_face"
@@ -146,14 +214,14 @@
},
{
"from": [
-2.0,
9.0,
6.0
0.0,
1.0,
-5.0
],
"to": [
18.0,
11.0,
18.0
16.0,
3.0,
-3.0
],
"faces": {
"north": {
@@ -163,7 +231,7 @@
16,
2.0
],
"texture": "#ru_green"
"texture": "#dark_metal"
},
"south": {
"uv": [
@@ -172,7 +240,75 @@
16,
2.0
],
"texture": "#ru_green"
"texture": "#dark_metal"
},
"east": {
"uv": [
0,
0,
2.0,
2.0
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
2.0,
2.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": [
-4.0,
7.0,
4.0
],
"to": [
-2.0,
9.0,
16.0
],
"faces": {
"north": {
"uv": [
0,
0,
2.0,
2.0
],
"texture": "#metal"
},
"south": {
"uv": [
0,
0,
2.0,
2.0
],
"texture": "#metal"
},
"east": {
"uv": [
@@ -181,7 +317,7 @@
12.0,
2.0
],
"texture": "#ru_green"
"texture": "#metal"
},
"west": {
"uv": [
@@ -190,27 +326,95 @@
12.0,
2.0
],
"texture": "#ru_green"
"texture": "#metal"
},
"up": {
"uv": [
0,
0,
16,
2.0,
12.0
],
"texture": "#ru_green"
"texture": "#metal"
},
"down": {
"uv": [
0,
0,
16,
2.0,
12.0
],
"texture": "#ru_green"
"texture": "#metal"
}
}
},
{
"from": [
18.0,
7.0,
4.0
],
"to": [
20.0,
9.0,
16.0
],
"faces": {
"north": {
"uv": [
0,
0,
2.0,
2.0
],
"texture": "#metal"
},
"south": {
"uv": [
0,
0,
2.0,
2.0
],
"texture": "#metal"
},
"east": {
"uv": [
0,
0,
12.0,
2.0
],
"texture": "#metal"
},
"west": {
"uv": [
0,
0,
12.0,
2.0
],
"texture": "#metal"
},
"up": {
"uv": [
0,
0,
2.0,
12.0
],
"texture": "#metal"
},
"down": {
"uv": [
0,
0,
2.0,
12.0
],
"texture": "#metal"
}
}
}
]
}
}
@@ -1,11 +1,11 @@
{
"ambientocclusion": false,
"textures": {
"ru_green_s21_b": "airdef:block/ru_green_s21_b",
"ru_green_s22_b": "airdef:block/ru_green_s22_b",
"pilot_olive_b": "airdef:block/pilot_olive_b",
"radar_face_b": "airdef:block/radar_face_b",
"ru_green_b": "airdef:block/ru_green_b",
"particle": "airdef:block/ru_green_s21_b"
"dark_metal_b": "airdef:block/dark_metal_b",
"metal_b": "airdef:block/metal_b",
"particle": "airdef:block/pilot_olive_b"
},
"elements": [
{
@@ -16,7 +16,7 @@
],
"to": [
20.0,
9.0,
7.0,
20.0
],
"faces": {
@@ -25,36 +25,36 @@
0,
0,
16,
9.0
7.0
],
"texture": "#ru_green_s21_b"
"texture": "#pilot_olive_b"
},
"south": {
"uv": [
0,
0,
16,
9.0
7.0
],
"texture": "#ru_green_s21_b"
"texture": "#pilot_olive_b"
},
"east": {
"uv": [
0,
0,
16,
9.0
7.0
],
"texture": "#ru_green_s21_b"
"texture": "#pilot_olive_b"
},
"west": {
"uv": [
0,
0,
16,
9.0
7.0
],
"texture": "#ru_green_s21_b"
"texture": "#pilot_olive_b"
},
"up": {
"uv": [
@@ -63,7 +63,7 @@
16,
16
],
"texture": "#ru_green_s22_b"
"texture": "#pilot_olive_b"
},
"down": {
"uv": [
@@ -72,7 +72,75 @@
16,
16
],
"texture": "#ru_green_s22_b"
"texture": "#pilot_olive_b"
}
}
},
{
"from": [
-2.0,
7.0,
2.0
],
"to": [
18.0,
10.0,
18.0
],
"faces": {
"north": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#pilot_olive_b"
},
"south": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#pilot_olive_b"
},
"east": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#pilot_olive_b"
},
"west": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#pilot_olive_b"
},
"up": {
"uv": [
0,
0,
16,
16
],
"texture": "#pilot_olive_b"
},
"down": {
"uv": [
0,
0,
16,
16
],
"texture": "#pilot_olive_b"
}
}
},
@@ -83,7 +151,7 @@
-10.0
],
"to": [
15.0,
11.0,
14.0,
-4.0
],
@@ -92,7 +160,7 @@
"uv": [
0,
0,
14.0,
10.0,
12.0
],
"texture": "#radar_face_b"
@@ -101,7 +169,7 @@
"uv": [
0,
0,
14.0,
10.0,
12.0
],
"texture": "#radar_face_b"
@@ -128,7 +196,7 @@
"uv": [
0,
0,
14.0,
10.0,
6.0
],
"texture": "#radar_face_b"
@@ -137,7 +205,7 @@
"uv": [
0,
0,
14.0,
10.0,
6.0
],
"texture": "#radar_face_b"
@@ -146,14 +214,14 @@
},
{
"from": [
-2.0,
9.0,
6.0
0.0,
1.0,
-5.0
],
"to": [
18.0,
11.0,
18.0
16.0,
3.0,
-3.0
],
"faces": {
"north": {
@@ -163,7 +231,7 @@
16,
2.0
],
"texture": "#ru_green_b"
"texture": "#dark_metal_b"
},
"south": {
"uv": [
@@ -172,7 +240,75 @@
16,
2.0
],
"texture": "#ru_green_b"
"texture": "#dark_metal_b"
},
"east": {
"uv": [
0,
0,
2.0,
2.0
],
"texture": "#dark_metal_b"
},
"west": {
"uv": [
0,
0,
2.0,
2.0
],
"texture": "#dark_metal_b"
},
"up": {
"uv": [
0,
0,
16,
2.0
],
"texture": "#dark_metal_b"
},
"down": {
"uv": [
0,
0,
16,
2.0
],
"texture": "#dark_metal_b"
}
}
},
{
"from": [
-4.0,
7.0,
4.0
],
"to": [
-2.0,
9.0,
16.0
],
"faces": {
"north": {
"uv": [
0,
0,
2.0,
2.0
],
"texture": "#metal_b"
},
"south": {
"uv": [
0,
0,
2.0,
2.0
],
"texture": "#metal_b"
},
"east": {
"uv": [
@@ -181,7 +317,7 @@
12.0,
2.0
],
"texture": "#ru_green_b"
"texture": "#metal_b"
},
"west": {
"uv": [
@@ -190,27 +326,95 @@
12.0,
2.0
],
"texture": "#ru_green_b"
"texture": "#metal_b"
},
"up": {
"uv": [
0,
0,
16,
2.0,
12.0
],
"texture": "#ru_green_b"
"texture": "#metal_b"
},
"down": {
"uv": [
0,
0,
16,
2.0,
12.0
],
"texture": "#ru_green_b"
"texture": "#metal_b"
}
}
},
{
"from": [
18.0,
7.0,
4.0
],
"to": [
20.0,
9.0,
16.0
],
"faces": {
"north": {
"uv": [
0,
0,
2.0,
2.0
],
"texture": "#metal_b"
},
"south": {
"uv": [
0,
0,
2.0,
2.0
],
"texture": "#metal_b"
},
"east": {
"uv": [
0,
0,
12.0,
2.0
],
"texture": "#metal_b"
},
"west": {
"uv": [
0,
0,
12.0,
2.0
],
"texture": "#metal_b"
},
"up": {
"uv": [
0,
0,
2.0,
12.0
],
"texture": "#metal_b"
},
"down": {
"uv": [
0,
0,
2.0,
12.0
],
"texture": "#metal_b"
}
}
}
]
}
}
+179 -42
View File
@@ -3,6 +3,7 @@
"textures": {
"concrete": "airdef:block/concrete",
"crate": "airdef:block/crate",
"dark_metal": "airdef:block/dark_metal",
"tube_cap": "airdef:block/tube_cap",
"tube": "airdef:block/tube",
"particle": "airdef:block/concrete"
@@ -78,22 +79,22 @@
},
{
"from": [
-12.0,
-13.0,
2.0,
-12.0
-13.0
],
"to": [
0.0,
10.0,
0.0
1.0,
12.0,
1.0
],
"faces": {
"north": {
"uv": [
0,
0,
12.0,
8.0
14.0,
10.0
],
"texture": "#crate"
},
@@ -101,8 +102,8 @@
"uv": [
0,
0,
12.0,
8.0
14.0,
10.0
],
"texture": "#crate"
},
@@ -110,8 +111,8 @@
"uv": [
0,
0,
12.0,
8.0
14.0,
10.0
],
"texture": "#crate"
},
@@ -119,8 +120,8 @@
"uv": [
0,
0,
12.0,
8.0
14.0,
10.0
],
"texture": "#crate"
},
@@ -128,8 +129,8 @@
"uv": [
0,
0,
12.0,
12.0
14.0,
14.0
],
"texture": "#crate"
},
@@ -137,8 +138,8 @@
"uv": [
0,
0,
12.0,
12.0
14.0,
14.0
],
"texture": "#crate"
}
@@ -146,21 +147,21 @@
},
{
"from": [
-12.0,
-13.0,
2.0,
4.0
3.0
],
"to": [
0.0,
1.0,
10.0,
16.0
17.0
],
"faces": {
"north": {
"uv": [
0,
0,
12.0,
14.0,
8.0
],
"texture": "#crate"
@@ -169,7 +170,7 @@
"uv": [
0,
0,
12.0,
14.0,
8.0
],
"texture": "#crate"
@@ -178,7 +179,7 @@
"uv": [
0,
0,
12.0,
14.0,
8.0
],
"texture": "#crate"
@@ -187,7 +188,7 @@
"uv": [
0,
0,
12.0,
14.0,
8.0
],
"texture": "#crate"
@@ -196,8 +197,8 @@
"uv": [
0,
0,
12.0,
12.0
14.0,
14.0
],
"texture": "#crate"
},
@@ -205,8 +206,8 @@
"uv": [
0,
0,
12.0,
12.0
14.0,
14.0
],
"texture": "#crate"
}
@@ -214,21 +215,21 @@
},
{
"from": [
4.0,
3.0,
2.0,
-12.0
-13.0
],
"to": [
16.0,
17.0,
10.0,
0.0
1.0
],
"faces": {
"north": {
"uv": [
0,
0,
12.0,
14.0,
8.0
],
"texture": "#crate"
@@ -237,7 +238,7 @@
"uv": [
0,
0,
12.0,
14.0,
8.0
],
"texture": "#crate"
@@ -246,7 +247,7 @@
"uv": [
0,
0,
12.0,
14.0,
8.0
],
"texture": "#crate"
@@ -255,7 +256,7 @@
"uv": [
0,
0,
12.0,
14.0,
8.0
],
"texture": "#crate"
@@ -264,8 +265,8 @@
"uv": [
0,
0,
12.0,
12.0
14.0,
14.0
],
"texture": "#crate"
},
@@ -273,13 +274,149 @@
"uv": [
0,
0,
12.0,
12.0
14.0,
14.0
],
"texture": "#crate"
}
}
},
{
"from": [
-14.0,
2.0,
27.0
],
"to": [
30.0,
5.0,
29.0
],
"faces": {
"north": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#dark_metal"
},
"south": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#dark_metal"
},
"east": {
"uv": [
0,
0,
2.0,
3.0
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
2.0,
3.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": [
-14.0,
2.0,
-14.0
],
"to": [
-12.0,
5.0,
28.0
],
"faces": {
"north": {
"uv": [
0,
0,
2.0,
3.0
],
"texture": "#dark_metal"
},
"south": {
"uv": [
0,
0,
2.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,
2.0,
16
],
"texture": "#dark_metal"
},
"down": {
"uv": [
0,
0,
2.0,
16
],
"texture": "#dark_metal"
}
}
},
{
"from": [
6.0,
@@ -485,4 +622,4 @@
}
}
]
}
}
@@ -3,6 +3,7 @@
"textures": {
"concrete_b": "airdef:block/concrete_b",
"crate_b": "airdef:block/crate_b",
"dark_metal_b": "airdef:block/dark_metal_b",
"tube_cap_b": "airdef:block/tube_cap_b",
"tube_b": "airdef:block/tube_b",
"particle": "airdef:block/concrete_b"
@@ -78,22 +79,22 @@
},
{
"from": [
-12.0,
-13.0,
2.0,
-12.0
-13.0
],
"to": [
0.0,
10.0,
0.0
1.0,
12.0,
1.0
],
"faces": {
"north": {
"uv": [
0,
0,
12.0,
8.0
14.0,
10.0
],
"texture": "#crate_b"
},
@@ -101,8 +102,8 @@
"uv": [
0,
0,
12.0,
8.0
14.0,
10.0
],
"texture": "#crate_b"
},
@@ -110,8 +111,8 @@
"uv": [
0,
0,
12.0,
8.0
14.0,
10.0
],
"texture": "#crate_b"
},
@@ -119,8 +120,8 @@
"uv": [
0,
0,
12.0,
8.0
14.0,
10.0
],
"texture": "#crate_b"
},
@@ -128,8 +129,8 @@
"uv": [
0,
0,
12.0,
12.0
14.0,
14.0
],
"texture": "#crate_b"
},
@@ -137,8 +138,8 @@
"uv": [
0,
0,
12.0,
12.0
14.0,
14.0
],
"texture": "#crate_b"
}
@@ -146,21 +147,21 @@
},
{
"from": [
-12.0,
-13.0,
2.0,
4.0
3.0
],
"to": [
0.0,
1.0,
10.0,
16.0
17.0
],
"faces": {
"north": {
"uv": [
0,
0,
12.0,
14.0,
8.0
],
"texture": "#crate_b"
@@ -169,7 +170,7 @@
"uv": [
0,
0,
12.0,
14.0,
8.0
],
"texture": "#crate_b"
@@ -178,7 +179,7 @@
"uv": [
0,
0,
12.0,
14.0,
8.0
],
"texture": "#crate_b"
@@ -187,7 +188,7 @@
"uv": [
0,
0,
12.0,
14.0,
8.0
],
"texture": "#crate_b"
@@ -196,8 +197,8 @@
"uv": [
0,
0,
12.0,
12.0
14.0,
14.0
],
"texture": "#crate_b"
},
@@ -205,8 +206,8 @@
"uv": [
0,
0,
12.0,
12.0
14.0,
14.0
],
"texture": "#crate_b"
}
@@ -214,21 +215,21 @@
},
{
"from": [
4.0,
3.0,
2.0,
-12.0
-13.0
],
"to": [
16.0,
17.0,
10.0,
0.0
1.0
],
"faces": {
"north": {
"uv": [
0,
0,
12.0,
14.0,
8.0
],
"texture": "#crate_b"
@@ -237,7 +238,7 @@
"uv": [
0,
0,
12.0,
14.0,
8.0
],
"texture": "#crate_b"
@@ -246,7 +247,7 @@
"uv": [
0,
0,
12.0,
14.0,
8.0
],
"texture": "#crate_b"
@@ -255,7 +256,7 @@
"uv": [
0,
0,
12.0,
14.0,
8.0
],
"texture": "#crate_b"
@@ -264,8 +265,8 @@
"uv": [
0,
0,
12.0,
12.0
14.0,
14.0
],
"texture": "#crate_b"
},
@@ -273,13 +274,149 @@
"uv": [
0,
0,
12.0,
12.0
14.0,
14.0
],
"texture": "#crate_b"
}
}
},
{
"from": [
-14.0,
2.0,
27.0
],
"to": [
30.0,
5.0,
29.0
],
"faces": {
"north": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#dark_metal_b"
},
"south": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#dark_metal_b"
},
"east": {
"uv": [
0,
0,
2.0,
3.0
],
"texture": "#dark_metal_b"
},
"west": {
"uv": [
0,
0,
2.0,
3.0
],
"texture": "#dark_metal_b"
},
"up": {
"uv": [
0,
0,
16,
2.0
],
"texture": "#dark_metal_b"
},
"down": {
"uv": [
0,
0,
16,
2.0
],
"texture": "#dark_metal_b"
}
}
},
{
"from": [
-14.0,
2.0,
-14.0
],
"to": [
-12.0,
5.0,
28.0
],
"faces": {
"north": {
"uv": [
0,
0,
2.0,
3.0
],
"texture": "#dark_metal_b"
},
"south": {
"uv": [
0,
0,
2.0,
3.0
],
"texture": "#dark_metal_b"
},
"east": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#dark_metal_b"
},
"west": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#dark_metal_b"
},
"up": {
"uv": [
0,
0,
2.0,
16
],
"texture": "#dark_metal_b"
},
"down": {
"uv": [
0,
0,
2.0,
16
],
"texture": "#dark_metal_b"
}
}
},
{
"from": [
6.0,
@@ -485,4 +622,4 @@
}
}
]
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -2,7 +2,7 @@
"ambientocclusion": false,
"textures": {
"bare_barrel": "airdef:block/bare_barrel",
"flecktarn": "airdef:block/flecktarn",
"pilot_nato": "airdef:block/pilot_nato",
"dark_metal": "airdef:block/dark_metal",
"particle": "airdef:block/bare_barrel"
},
@@ -162,7 +162,7 @@
5.0,
5.5
],
"texture": "#flecktarn"
"texture": "#pilot_nato"
},
"south": {
"uv": [
@@ -171,7 +171,7 @@
5.0,
5.5
],
"texture": "#flecktarn"
"texture": "#pilot_nato"
},
"east": {
"uv": [
@@ -180,7 +180,7 @@
12.0,
5.5
],
"texture": "#flecktarn"
"texture": "#pilot_nato"
},
"west": {
"uv": [
@@ -189,7 +189,7 @@
12.0,
5.5
],
"texture": "#flecktarn"
"texture": "#pilot_nato"
},
"up": {
"uv": [
@@ -198,7 +198,7 @@
5.0,
12.0
],
"texture": "#flecktarn"
"texture": "#pilot_nato"
},
"down": {
"uv": [
@@ -207,7 +207,7 @@
5.0,
12.0
],
"texture": "#flecktarn"
"texture": "#pilot_nato"
}
}
},
@@ -230,7 +230,7 @@
5.0,
5.5
],
"texture": "#flecktarn"
"texture": "#pilot_nato"
},
"south": {
"uv": [
@@ -239,7 +239,7 @@
5.0,
5.5
],
"texture": "#flecktarn"
"texture": "#pilot_nato"
},
"east": {
"uv": [
@@ -248,7 +248,7 @@
12.0,
5.5
],
"texture": "#flecktarn"
"texture": "#pilot_nato"
},
"west": {
"uv": [
@@ -257,7 +257,7 @@
12.0,
5.5
],
"texture": "#flecktarn"
"texture": "#pilot_nato"
},
"up": {
"uv": [
@@ -266,7 +266,7 @@
5.0,
12.0
],
"texture": "#flecktarn"
"texture": "#pilot_nato"
},
"down": {
"uv": [
@@ -275,7 +275,7 @@
5.0,
12.0
],
"texture": "#flecktarn"
"texture": "#pilot_nato"
}
}
},
@@ -416,4 +416,4 @@
}
}
]
}
}
@@ -2,7 +2,7 @@
"ambientocclusion": false,
"textures": {
"bare_barrel_b": "airdef:block/bare_barrel_b",
"flecktarn_b": "airdef:block/flecktarn_b",
"pilot_nato_b": "airdef:block/pilot_nato_b",
"dark_metal_b": "airdef:block/dark_metal_b",
"particle": "airdef:block/bare_barrel_b"
},
@@ -162,7 +162,7 @@
5.0,
5.5
],
"texture": "#flecktarn_b"
"texture": "#pilot_nato_b"
},
"south": {
"uv": [
@@ -171,7 +171,7 @@
5.0,
5.5
],
"texture": "#flecktarn_b"
"texture": "#pilot_nato_b"
},
"east": {
"uv": [
@@ -180,7 +180,7 @@
12.0,
5.5
],
"texture": "#flecktarn_b"
"texture": "#pilot_nato_b"
},
"west": {
"uv": [
@@ -189,7 +189,7 @@
12.0,
5.5
],
"texture": "#flecktarn_b"
"texture": "#pilot_nato_b"
},
"up": {
"uv": [
@@ -198,7 +198,7 @@
5.0,
12.0
],
"texture": "#flecktarn_b"
"texture": "#pilot_nato_b"
},
"down": {
"uv": [
@@ -207,7 +207,7 @@
5.0,
12.0
],
"texture": "#flecktarn_b"
"texture": "#pilot_nato_b"
}
}
},
@@ -230,7 +230,7 @@
5.0,
5.5
],
"texture": "#flecktarn_b"
"texture": "#pilot_nato_b"
},
"south": {
"uv": [
@@ -239,7 +239,7 @@
5.0,
5.5
],
"texture": "#flecktarn_b"
"texture": "#pilot_nato_b"
},
"east": {
"uv": [
@@ -248,7 +248,7 @@
12.0,
5.5
],
"texture": "#flecktarn_b"
"texture": "#pilot_nato_b"
},
"west": {
"uv": [
@@ -257,7 +257,7 @@
12.0,
5.5
],
"texture": "#flecktarn_b"
"texture": "#pilot_nato_b"
},
"up": {
"uv": [
@@ -266,7 +266,7 @@
5.0,
12.0
],
"texture": "#flecktarn_b"
"texture": "#pilot_nato_b"
},
"down": {
"uv": [
@@ -275,7 +275,7 @@
5.0,
12.0
],
"texture": "#flecktarn_b"
"texture": "#pilot_nato_b"
}
}
},
@@ -348,4 +348,4 @@
}
}
]
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,25 +1,23 @@
{
"ambientocclusion": false,
"textures": {
"flecktarn_s21": "airdef:block/flecktarn_s21",
"flecktarn": "airdef:block/flecktarn",
"pilot_nato": "airdef:block/pilot_nato",
"radar_face": "airdef:block/radar_face",
"metal": "airdef:block/metal",
"mk_de": "airdef:block/mk_de",
"bare_antenna": "airdef:block/bare_antenna",
"dark_metal": "airdef:block/dark_metal",
"particle": "airdef:block/flecktarn_s21"
"mk_de": "airdef:block/mk_de",
"particle": "airdef:block/pilot_nato"
},
"elements": [
{
"from": [
-4.0,
0.0,
-6.0
-5.0
],
"to": [
20.0,
12.0,
5.0,
16.0
],
"faces": {
@@ -28,36 +26,36 @@
0,
0,
16,
12.0
5.0
],
"texture": "#flecktarn_s21"
"texture": "#pilot_nato"
},
"south": {
"uv": [
0,
0,
16,
12.0
5.0
],
"texture": "#flecktarn_s21"
"texture": "#pilot_nato"
},
"east": {
"uv": [
0,
0,
16,
12.0
5.0
],
"texture": "#flecktarn"
"texture": "#pilot_nato"
},
"west": {
"uv": [
0,
0,
16,
12.0
5.0
],
"texture": "#flecktarn"
"texture": "#pilot_nato"
},
"up": {
"uv": [
@@ -66,7 +64,7 @@
16,
16
],
"texture": "#flecktarn_s21"
"texture": "#pilot_nato"
},
"down": {
"uv": [
@@ -75,7 +73,75 @@
16,
16
],
"texture": "#flecktarn_s21"
"texture": "#pilot_nato"
}
}
},
{
"from": [
-2.5,
5.0,
-5.0
],
"to": [
18.5,
12.0,
15.0
],
"faces": {
"north": {
"uv": [
0,
0,
16,
7.0
],
"texture": "#pilot_nato"
},
"south": {
"uv": [
0,
0,
16,
7.0
],
"texture": "#pilot_nato"
},
"east": {
"uv": [
0,
0,
16,
7.0
],
"texture": "#pilot_nato"
},
"west": {
"uv": [
0,
0,
16,
7.0
],
"texture": "#pilot_nato"
},
"up": {
"uv": [
0,
0,
16,
16
],
"texture": "#pilot_nato"
},
"down": {
"uv": [
0,
0,
16,
16
],
"texture": "#pilot_nato"
}
}
},
@@ -87,7 +153,7 @@
],
"to": [
18.0,
14.0,
13.0,
14.0
],
"faces": {
@@ -96,36 +162,36 @@
0,
0,
16,
2.0
1.0
],
"texture": "#flecktarn"
"texture": "#pilot_nato"
},
"south": {
"uv": [
0,
0,
16,
2.0
1.0
],
"texture": "#flecktarn"
"texture": "#pilot_nato"
},
"east": {
"uv": [
0,
0,
16,
2.0
1.0
],
"texture": "#flecktarn"
"texture": "#pilot_nato"
},
"west": {
"uv": [
0,
0,
16,
2.0
1.0
],
"texture": "#flecktarn"
"texture": "#pilot_nato"
},
"up": {
"uv": [
@@ -134,7 +200,7 @@
16,
16
],
"texture": "#flecktarn"
"texture": "#pilot_nato"
},
"down": {
"uv": [
@@ -143,7 +209,7 @@
16,
16
],
"texture": "#flecktarn"
"texture": "#pilot_nato"
}
}
},
@@ -218,7 +284,7 @@
{
"from": [
7.0,
14.0,
13.0,
10.0
],
"to": [
@@ -232,7 +298,7 @@
0,
0,
2.0,
4.0
5.0
],
"texture": "#metal"
},
@@ -241,7 +307,7 @@
0,
0,
2.0,
4.0
5.0
],
"texture": "#metal"
},
@@ -250,7 +316,7 @@
0,
0,
2.0,
4.0
5.0
],
"texture": "#metal"
},
@@ -259,7 +325,7 @@
0,
0,
2.0,
4.0
5.0
],
"texture": "#metal"
},
@@ -285,150 +351,168 @@
},
{
"from": [
20.0,
3.0,
-5.5
-4.7,
4.8,
-4.0
],
"to": [
20.119999999999997,
6.5,
1.5
-2.5,
10.7,
14.0
],
"faces": {
"north": {
"uv": [
0,
0,
0.25,
3.5
2.2,
5.8999999999999995
],
"texture": "#mk_de"
"texture": "#pilot_nato"
},
"south": {
"uv": [
0,
0,
0.25,
3.5
2.2,
5.8999999999999995
],
"texture": "#mk_de"
"texture": "#pilot_nato"
},
"east": {
"uv": [
0,
0,
7.0,
3.5
16,
5.8999999999999995
],
"texture": "#mk_de"
"texture": "#pilot_nato"
},
"west": {
"uv": [
0,
0,
7.0,
3.5
16,
5.8999999999999995
],
"texture": "#mk_de"
"texture": "#pilot_nato"
},
"up": {
"uv": [
0,
0,
0.25,
7.0
2.2,
16
],
"texture": "#mk_de"
"texture": "#pilot_nato"
},
"down": {
"uv": [
0,
0,
0.25,
7.0
2.2,
16
],
"texture": "#mk_de"
"texture": "#pilot_nato"
}
},
"rotation": {
"angle": 22.5,
"axis": "z",
"origin": [
-3.6,
7.75,
5.0
]
}
},
{
"from": [
-4.119999999999997,
3.0,
-5.5
18.5,
4.8,
-4.0
],
"to": [
-4.0,
6.5,
1.5
20.7,
10.7,
14.0
],
"faces": {
"north": {
"uv": [
0,
0,
0.25,
3.5
2.1999999999999993,
5.8999999999999995
],
"texture": "#mk_de"
"texture": "#pilot_nato"
},
"south": {
"uv": [
0,
0,
0.25,
3.5
2.1999999999999993,
5.8999999999999995
],
"texture": "#mk_de"
"texture": "#pilot_nato"
},
"east": {
"uv": [
0,
0,
7.0,
3.5
16,
5.8999999999999995
],
"texture": "#mk_de"
"texture": "#pilot_nato"
},
"west": {
"uv": [
0,
0,
7.0,
3.5
16,
5.8999999999999995
],
"texture": "#mk_de"
"texture": "#pilot_nato"
},
"up": {
"uv": [
0,
0,
0.25,
7.0
2.1999999999999993,
16
],
"texture": "#mk_de"
"texture": "#pilot_nato"
},
"down": {
"uv": [
0,
0,
0.25,
7.0
2.1999999999999993,
16
],
"texture": "#mk_de"
"texture": "#pilot_nato"
}
},
"rotation": {
"angle": -22.5,
"axis": "z",
"origin": [
19.6,
7.75,
5.0
]
}
},
{
"from": [
5.5,
14.0,
0.0,
13.05,
2.0
],
"to": [
10.5,
14.8,
7.0
5.0,
13.7,
8.0
],
"faces": {
"north": {
@@ -436,143 +520,75 @@
0,
0,
5.0,
0.8000000000000007
0.6499999999999986
],
"texture": "#metal"
"texture": "#dark_metal"
},
"south": {
"uv": [
0,
0,
5.0,
0.8000000000000007
0.6499999999999986
],
"texture": "#metal"
"texture": "#dark_metal"
},
"east": {
"uv": [
0,
0,
5.0,
0.8000000000000007
6.0,
0.6499999999999986
],
"texture": "#metal"
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
5.0,
0.8000000000000007
6.0,
0.6499999999999986
],
"texture": "#metal"
"texture": "#dark_metal"
},
"up": {
"uv": [
0,
0,
5.0,
5.0
6.0
],
"texture": "#metal"
"texture": "#dark_metal"
},
"down": {
"uv": [
0,
0,
5.0,
5.0
6.0
],
"texture": "#metal"
"texture": "#dark_metal"
}
}
},
{
"from": [
2.0,
14.0,
5.0
],
"to": [
3.0,
16.0,
6.0
],
"faces": {
"north": {
"uv": [
0,
0,
1.0,
2.0
],
"texture": "#bare_antenna"
},
"south": {
"uv": [
0,
0,
1.0,
2.0
],
"texture": "#bare_antenna"
},
"east": {
"uv": [
0,
0,
1.0,
2.0
],
"texture": "#bare_antenna"
},
"west": {
"uv": [
0,
0,
1.0,
2.0
],
"texture": "#bare_antenna"
},
"up": {
"uv": [
0,
0,
1.0,
1.0
],
"texture": "#bare_antenna"
},
"down": {
"uv": [
0,
0,
1.0,
1.0
],
"texture": "#bare_antenna"
}
}
},
{
"from": [
-4.800000000000001,
7.0,
-5.0
],
"to": [
-4.0,
10.0,
-2.0
13.05,
2.0
],
"to": [
15.0,
13.7,
8.0
],
"faces": {
"north": {
"uv": [
0,
0,
0.8000000000000007,
3.0
5.0,
0.6499999999999986
],
"texture": "#dark_metal"
},
@@ -580,8 +596,8 @@
"uv": [
0,
0,
0.8000000000000007,
3.0
5.0,
0.6499999999999986
],
"texture": "#dark_metal"
},
@@ -589,8 +605,8 @@
"uv": [
0,
0,
3.0,
3.0
6.0,
0.6499999999999986
],
"texture": "#dark_metal"
},
@@ -598,8 +614,8 @@
"uv": [
0,
0,
3.0,
3.0
6.0,
0.6499999999999986
],
"texture": "#dark_metal"
},
@@ -607,8 +623,8 @@
"uv": [
0,
0,
0.8000000000000007,
3.0
5.0,
6.0
],
"texture": "#dark_metal"
},
@@ -616,8 +632,8 @@
"uv": [
0,
0,
0.8000000000000007,
3.0
5.0,
6.0
],
"texture": "#dark_metal"
}
@@ -625,207 +641,139 @@
},
{
"from": [
20.0,
7.0,
-5.0
18.5,
6.0,
-4.0
],
"to": [
20.8,
10.0,
-2.0
18.619999999999997,
9.0,
2.0
],
"faces": {
"north": {
"uv": [
0,
0,
0.8000000000000007,
0.25,
3.0
],
"texture": "#dark_metal"
"texture": "#mk_de"
},
"south": {
"uv": [
0,
0,
0.8000000000000007,
0.25,
3.0
],
"texture": "#dark_metal"
"texture": "#mk_de"
},
"east": {
"uv": [
0,
0,
3.0,
6.0,
3.0
],
"texture": "#dark_metal"
"texture": "#mk_de"
},
"west": {
"uv": [
0,
0,
3.0,
6.0,
3.0
],
"texture": "#dark_metal"
"texture": "#mk_de"
},
"up": {
"uv": [
0,
0,
0.8000000000000007,
3.0
0.25,
6.0
],
"texture": "#dark_metal"
"texture": "#mk_de"
},
"down": {
"uv": [
0,
0,
0.8000000000000007,
3.0
0.25,
6.0
],
"texture": "#dark_metal"
"texture": "#mk_de"
}
}
},
{
"from": [
-4.800000000000001,
7.0,
-1.5
-2.6199999999999974,
6.0,
-4.0
],
"to": [
-4.0,
10.0,
0.5
-2.5,
9.0,
2.0
],
"faces": {
"north": {
"uv": [
0,
0,
0.8000000000000007,
0.25,
3.0
],
"texture": "#dark_metal"
"texture": "#mk_de"
},
"south": {
"uv": [
0,
0,
0.8000000000000007,
0.25,
3.0
],
"texture": "#dark_metal"
"texture": "#mk_de"
},
"east": {
"uv": [
0,
0,
2.0,
6.0,
3.0
],
"texture": "#dark_metal"
"texture": "#mk_de"
},
"west": {
"uv": [
0,
0,
2.0,
6.0,
3.0
],
"texture": "#dark_metal"
"texture": "#mk_de"
},
"up": {
"uv": [
0,
0,
0.8000000000000007,
2.0
0.25,
6.0
],
"texture": "#dark_metal"
"texture": "#mk_de"
},
"down": {
"uv": [
0,
0,
0.8000000000000007,
2.0
0.25,
6.0
],
"texture": "#dark_metal"
}
}
},
{
"from": [
20.0,
7.0,
-1.5
],
"to": [
20.8,
10.0,
0.5
],
"faces": {
"north": {
"uv": [
0,
0,
0.8000000000000007,
3.0
],
"texture": "#dark_metal"
},
"south": {
"uv": [
0,
0,
0.8000000000000007,
3.0
],
"texture": "#dark_metal"
},
"east": {
"uv": [
0,
0,
2.0,
3.0
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
2.0,
3.0
],
"texture": "#dark_metal"
},
"up": {
"uv": [
0,
0,
0.8000000000000007,
2.0
],
"texture": "#dark_metal"
},
"down": {
"uv": [
0,
0,
0.8000000000000007,
2.0
],
"texture": "#dark_metal"
"texture": "#mk_de"
}
}
}
]
}
}
@@ -1,25 +1,23 @@
{
"ambientocclusion": false,
"textures": {
"flecktarn_s21_b": "airdef:block/flecktarn_s21_b",
"flecktarn_b": "airdef:block/flecktarn_b",
"pilot_nato_b": "airdef:block/pilot_nato_b",
"radar_face_b": "airdef:block/radar_face_b",
"metal_b": "airdef:block/metal_b",
"mk_de_b": "airdef:block/mk_de_b",
"bare_antenna_b": "airdef:block/bare_antenna_b",
"dark_metal_b": "airdef:block/dark_metal_b",
"particle": "airdef:block/flecktarn_s21_b"
"mk_de_b": "airdef:block/mk_de_b",
"particle": "airdef:block/pilot_nato_b"
},
"elements": [
{
"from": [
-4.0,
0.0,
-6.0
-5.0
],
"to": [
20.0,
12.0,
5.0,
16.0
],
"faces": {
@@ -28,36 +26,36 @@
0,
0,
16,
12.0
5.0
],
"texture": "#flecktarn_s21_b"
"texture": "#pilot_nato_b"
},
"south": {
"uv": [
0,
0,
16,
12.0
5.0
],
"texture": "#flecktarn_s21_b"
"texture": "#pilot_nato_b"
},
"east": {
"uv": [
0,
0,
16,
12.0
5.0
],
"texture": "#flecktarn_b"
"texture": "#pilot_nato_b"
},
"west": {
"uv": [
0,
0,
16,
12.0
5.0
],
"texture": "#flecktarn_b"
"texture": "#pilot_nato_b"
},
"up": {
"uv": [
@@ -66,7 +64,7 @@
16,
16
],
"texture": "#flecktarn_s21_b"
"texture": "#pilot_nato_b"
},
"down": {
"uv": [
@@ -75,7 +73,75 @@
16,
16
],
"texture": "#flecktarn_s21_b"
"texture": "#pilot_nato_b"
}
}
},
{
"from": [
-2.5,
5.0,
-5.0
],
"to": [
18.5,
12.0,
15.0
],
"faces": {
"north": {
"uv": [
0,
0,
16,
7.0
],
"texture": "#pilot_nato_b"
},
"south": {
"uv": [
0,
0,
16,
7.0
],
"texture": "#pilot_nato_b"
},
"east": {
"uv": [
0,
0,
16,
7.0
],
"texture": "#pilot_nato_b"
},
"west": {
"uv": [
0,
0,
16,
7.0
],
"texture": "#pilot_nato_b"
},
"up": {
"uv": [
0,
0,
16,
16
],
"texture": "#pilot_nato_b"
},
"down": {
"uv": [
0,
0,
16,
16
],
"texture": "#pilot_nato_b"
}
}
},
@@ -87,7 +153,7 @@
],
"to": [
18.0,
14.0,
13.0,
14.0
],
"faces": {
@@ -96,36 +162,36 @@
0,
0,
16,
2.0
1.0
],
"texture": "#flecktarn_b"
"texture": "#pilot_nato_b"
},
"south": {
"uv": [
0,
0,
16,
2.0
1.0
],
"texture": "#flecktarn_b"
"texture": "#pilot_nato_b"
},
"east": {
"uv": [
0,
0,
16,
2.0
1.0
],
"texture": "#flecktarn_b"
"texture": "#pilot_nato_b"
},
"west": {
"uv": [
0,
0,
16,
2.0
1.0
],
"texture": "#flecktarn_b"
"texture": "#pilot_nato_b"
},
"up": {
"uv": [
@@ -134,7 +200,7 @@
16,
16
],
"texture": "#flecktarn_b"
"texture": "#pilot_nato_b"
},
"down": {
"uv": [
@@ -143,7 +209,7 @@
16,
16
],
"texture": "#flecktarn_b"
"texture": "#pilot_nato_b"
}
}
},
@@ -218,7 +284,7 @@
{
"from": [
7.0,
14.0,
13.0,
10.0
],
"to": [
@@ -232,7 +298,7 @@
0,
0,
2.0,
4.0
5.0
],
"texture": "#metal_b"
},
@@ -241,7 +307,7 @@
0,
0,
2.0,
4.0
5.0
],
"texture": "#metal_b"
},
@@ -250,7 +316,7 @@
0,
0,
2.0,
4.0
5.0
],
"texture": "#metal_b"
},
@@ -259,7 +325,7 @@
0,
0,
2.0,
4.0
5.0
],
"texture": "#metal_b"
},
@@ -285,226 +351,244 @@
},
{
"from": [
20.0,
3.0,
-5.5
-4.7,
4.8,
-4.0
],
"to": [
20.119999999999997,
6.5,
1.5
-2.5,
10.7,
14.0
],
"faces": {
"north": {
"uv": [
0,
0,
0.25,
3.5
2.2,
5.8999999999999995
],
"texture": "#mk_de_b"
"texture": "#pilot_nato_b"
},
"south": {
"uv": [
0,
0,
0.25,
3.5
2.2,
5.8999999999999995
],
"texture": "#mk_de_b"
"texture": "#pilot_nato_b"
},
"east": {
"uv": [
0,
0,
7.0,
3.5
16,
5.8999999999999995
],
"texture": "#mk_de_b"
"texture": "#pilot_nato_b"
},
"west": {
"uv": [
0,
0,
7.0,
3.5
16,
5.8999999999999995
],
"texture": "#mk_de_b"
"texture": "#pilot_nato_b"
},
"up": {
"uv": [
0,
0,
0.25,
7.0
2.2,
16
],
"texture": "#mk_de_b"
"texture": "#pilot_nato_b"
},
"down": {
"uv": [
0,
0,
0.25,
7.0
2.2,
16
],
"texture": "#mk_de_b"
"texture": "#pilot_nato_b"
}
},
"rotation": {
"angle": 22.5,
"axis": "z",
"origin": [
-3.6,
7.75,
5.0
]
}
},
{
"from": [
-4.119999999999997,
3.0,
-5.5
18.5,
4.8,
-4.0
],
"to": [
-4.0,
6.5,
1.5
20.7,
10.7,
14.0
],
"faces": {
"north": {
"uv": [
0,
0,
0.25,
3.5
2.1999999999999993,
5.8999999999999995
],
"texture": "#mk_de_b"
"texture": "#pilot_nato_b"
},
"south": {
"uv": [
0,
0,
0.25,
3.5
2.1999999999999993,
5.8999999999999995
],
"texture": "#mk_de_b"
"texture": "#pilot_nato_b"
},
"east": {
"uv": [
0,
0,
7.0,
3.5
16,
5.8999999999999995
],
"texture": "#mk_de_b"
"texture": "#pilot_nato_b"
},
"west": {
"uv": [
0,
0,
7.0,
3.5
16,
5.8999999999999995
],
"texture": "#mk_de_b"
"texture": "#pilot_nato_b"
},
"up": {
"uv": [
0,
0,
0.25,
7.0
2.1999999999999993,
16
],
"texture": "#mk_de_b"
"texture": "#pilot_nato_b"
},
"down": {
"uv": [
0,
0,
0.25,
7.0
2.1999999999999993,
16
],
"texture": "#mk_de_b"
"texture": "#pilot_nato_b"
}
},
"rotation": {
"angle": -22.5,
"axis": "z",
"origin": [
19.6,
7.75,
5.0
]
}
},
{
"from": [
2.0,
14.0,
5.0
0.0,
13.05,
2.0
],
"to": [
3.0,
16.0,
6.0
5.0,
13.7,
8.0
],
"faces": {
"north": {
"uv": [
0,
0,
1.0,
2.0
5.0,
0.6499999999999986
],
"texture": "#bare_antenna_b"
"texture": "#dark_metal_b"
},
"south": {
"uv": [
0,
0,
1.0,
2.0
5.0,
0.6499999999999986
],
"texture": "#bare_antenna_b"
"texture": "#dark_metal_b"
},
"east": {
"uv": [
0,
0,
1.0,
2.0
6.0,
0.6499999999999986
],
"texture": "#bare_antenna_b"
"texture": "#dark_metal_b"
},
"west": {
"uv": [
0,
0,
1.0,
2.0
6.0,
0.6499999999999986
],
"texture": "#bare_antenna_b"
"texture": "#dark_metal_b"
},
"up": {
"uv": [
0,
0,
1.0,
1.0
5.0,
6.0
],
"texture": "#bare_antenna_b"
"texture": "#dark_metal_b"
},
"down": {
"uv": [
0,
0,
1.0,
1.0
5.0,
6.0
],
"texture": "#bare_antenna_b"
"texture": "#dark_metal_b"
}
}
},
{
"from": [
-4.800000000000001,
7.0,
-5.0
],
"to": [
-4.0,
10.0,
-2.0
13.05,
2.0
],
"to": [
15.0,
13.7,
8.0
],
"faces": {
"north": {
"uv": [
0,
0,
0.8000000000000007,
3.0
5.0,
0.6499999999999986
],
"texture": "#dark_metal_b"
},
@@ -512,8 +596,8 @@
"uv": [
0,
0,
0.8000000000000007,
3.0
5.0,
0.6499999999999986
],
"texture": "#dark_metal_b"
},
@@ -521,8 +605,8 @@
"uv": [
0,
0,
3.0,
3.0
6.0,
0.6499999999999986
],
"texture": "#dark_metal_b"
},
@@ -530,8 +614,8 @@
"uv": [
0,
0,
3.0,
3.0
6.0,
0.6499999999999986
],
"texture": "#dark_metal_b"
},
@@ -539,8 +623,8 @@
"uv": [
0,
0,
0.8000000000000007,
3.0
5.0,
6.0
],
"texture": "#dark_metal_b"
},
@@ -548,8 +632,8 @@
"uv": [
0,
0,
0.8000000000000007,
3.0
5.0,
6.0
],
"texture": "#dark_metal_b"
}
@@ -557,139 +641,71 @@
},
{
"from": [
20.0,
7.0,
-5.0
-2.6199999999999974,
6.0,
-4.0
],
"to": [
20.8,
10.0,
-2.0
-2.5,
9.0,
2.0
],
"faces": {
"north": {
"uv": [
0,
0,
0.8000000000000007,
0.25,
3.0
],
"texture": "#dark_metal_b"
"texture": "#mk_de_b"
},
"south": {
"uv": [
0,
0,
0.8000000000000007,
0.25,
3.0
],
"texture": "#dark_metal_b"
"texture": "#mk_de_b"
},
"east": {
"uv": [
0,
0,
3.0,
6.0,
3.0
],
"texture": "#dark_metal_b"
"texture": "#mk_de_b"
},
"west": {
"uv": [
0,
0,
3.0,
6.0,
3.0
],
"texture": "#dark_metal_b"
"texture": "#mk_de_b"
},
"up": {
"uv": [
0,
0,
0.8000000000000007,
3.0
0.25,
6.0
],
"texture": "#dark_metal_b"
"texture": "#mk_de_b"
},
"down": {
"uv": [
0,
0,
0.8000000000000007,
3.0
0.25,
6.0
],
"texture": "#dark_metal_b"
}
}
},
{
"from": [
-4.800000000000001,
7.0,
-1.5
],
"to": [
-4.0,
10.0,
0.5
],
"faces": {
"north": {
"uv": [
0,
0,
0.8000000000000007,
3.0
],
"texture": "#dark_metal_b"
},
"south": {
"uv": [
0,
0,
0.8000000000000007,
3.0
],
"texture": "#dark_metal_b"
},
"east": {
"uv": [
0,
0,
2.0,
3.0
],
"texture": "#dark_metal_b"
},
"west": {
"uv": [
0,
0,
2.0,
3.0
],
"texture": "#dark_metal_b"
},
"up": {
"uv": [
0,
0,
0.8000000000000007,
2.0
],
"texture": "#dark_metal_b"
},
"down": {
"uv": [
0,
0,
0.8000000000000007,
2.0
],
"texture": "#dark_metal_b"
"texture": "#mk_de_b"
}
}
}
]
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -686,6 +686,142 @@
"texture": "#dark_metal"
}
}
},
{
"from": [
-1.9,
0.0,
-2.0
],
"to": [
17.9,
9.0,
-1.5
],
"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,
0.5,
9.0
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
0.5,
9.0
],
"texture": "#dark_metal"
},
"up": {
"uv": [
0,
0,
16,
0.5
],
"texture": "#dark_metal"
},
"down": {
"uv": [
0,
0,
16,
0.5
],
"texture": "#dark_metal"
}
}
},
{
"from": [
-1.9,
0.0,
22.0
],
"to": [
17.9,
9.0,
22.5
],
"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,
0.5,
9.0
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
0.5,
9.0
],
"texture": "#dark_metal"
},
"up": {
"uv": [
0,
0,
16,
0.5
],
"texture": "#dark_metal"
},
"down": {
"uv": [
0,
0,
16,
0.5
],
"texture": "#dark_metal"
}
}
}
]
}
}
@@ -686,6 +686,142 @@
"texture": "#dark_metal_b"
}
}
},
{
"from": [
-1.9,
0.0,
-2.0
],
"to": [
17.9,
9.0,
-1.5
],
"faces": {
"north": {
"uv": [
0,
0,
16,
9.0
],
"texture": "#dark_metal_b"
},
"south": {
"uv": [
0,
0,
16,
9.0
],
"texture": "#dark_metal_b"
},
"east": {
"uv": [
0,
0,
0.5,
9.0
],
"texture": "#dark_metal_b"
},
"west": {
"uv": [
0,
0,
0.5,
9.0
],
"texture": "#dark_metal_b"
},
"up": {
"uv": [
0,
0,
16,
0.5
],
"texture": "#dark_metal_b"
},
"down": {
"uv": [
0,
0,
16,
0.5
],
"texture": "#dark_metal_b"
}
}
},
{
"from": [
-1.9,
0.0,
22.0
],
"to": [
17.9,
9.0,
22.5
],
"faces": {
"north": {
"uv": [
0,
0,
16,
9.0
],
"texture": "#dark_metal_b"
},
"south": {
"uv": [
0,
0,
16,
9.0
],
"texture": "#dark_metal_b"
},
"east": {
"uv": [
0,
0,
0.5,
9.0
],
"texture": "#dark_metal_b"
},
"west": {
"uv": [
0,
0,
0.5,
9.0
],
"texture": "#dark_metal_b"
},
"up": {
"uv": [
0,
0,
16,
0.5
],
"texture": "#dark_metal_b"
},
"down": {
"uv": [
0,
0,
16,
0.5
],
"texture": "#dark_metal_b"
}
}
}
]
}
}
+598 -54
View File
@@ -741,8 +741,8 @@
2.0
],
"to": [
22.0,
7.6,
13.55,
7.5,
11.0
],
"faces": {
@@ -750,8 +750,8 @@
"uv": [
0,
0,
11.5,
0.6999999999999993
3.0500000000000007,
0.5999999999999996
],
"texture": "#kh101"
},
@@ -759,8 +759,8 @@
"uv": [
0,
0,
11.5,
0.6999999999999993
3.0500000000000007,
0.5999999999999996
],
"texture": "#kh101"
},
@@ -769,7 +769,7 @@
0,
0,
9.0,
0.6999999999999993
0.5999999999999996
],
"texture": "#kh101"
},
@@ -778,7 +778,7 @@
0,
0,
9.0,
0.6999999999999993
0.5999999999999996
],
"texture": "#kh101"
},
@@ -786,7 +786,7 @@
"uv": [
0,
0,
11.5,
3.0500000000000007,
9.0
],
"texture": "#kh101"
@@ -795,7 +795,7 @@
"uv": [
0,
0,
11.5,
3.0500000000000007,
9.0
],
"texture": "#kh101_belly"
@@ -804,13 +804,13 @@
},
{
"from": [
-6.0,
2.4499999999999993,
6.9,
2.0
],
"to": [
5.5,
7.6,
7.5,
11.0
],
"faces": {
@@ -818,8 +818,8 @@
"uv": [
0,
0,
11.5,
0.6999999999999993
3.0500000000000007,
0.5999999999999996
],
"texture": "#kh101"
},
@@ -827,8 +827,8 @@
"uv": [
0,
0,
11.5,
0.6999999999999993
3.0500000000000007,
0.5999999999999996
],
"texture": "#kh101"
},
@@ -837,7 +837,7 @@
0,
0,
9.0,
0.6999999999999993
0.5999999999999996
],
"texture": "#kh101"
},
@@ -846,7 +846,7 @@
0,
0,
9.0,
0.6999999999999993
0.5999999999999996
],
"texture": "#kh101"
},
@@ -854,7 +854,7 @@
"uv": [
0,
0,
11.5,
3.0500000000000007,
9.0
],
"texture": "#kh101"
@@ -863,7 +863,7 @@
"uv": [
0,
0,
11.5,
3.0500000000000007,
9.0
],
"texture": "#kh101_belly"
@@ -872,22 +872,22 @@
},
{
"from": [
22.0,
13.5,
6.9,
5.0
2.65
],
"to": [
28.5,
7.4,
11.0
16.55,
7.5,
10.88
],
"faces": {
"north": {
"uv": [
0,
0,
6.5,
0.5
3.0500000000000007,
0.5999999999999996
],
"texture": "#kh101"
},
@@ -895,8 +895,8 @@
"uv": [
0,
0,
6.5,
0.5
3.0500000000000007,
0.5999999999999996
],
"texture": "#kh101"
},
@@ -904,8 +904,8 @@
"uv": [
0,
0,
6.0,
0.5
8.23,
0.5999999999999996
],
"texture": "#kh101"
},
@@ -913,8 +913,8 @@
"uv": [
0,
0,
6.0,
0.5
8.23,
0.5999999999999996
],
"texture": "#kh101"
},
@@ -922,8 +922,8 @@
"uv": [
0,
0,
6.5,
6.0
3.0500000000000007,
8.23
],
"texture": "#kh101"
},
@@ -931,8 +931,552 @@
"uv": [
0,
0,
6.5,
6.0
3.0500000000000007,
8.23
],
"texture": "#kh101_belly"
}
}
},
{
"from": [
-0.5500000000000007,
6.9,
2.65
],
"to": [
2.5,
7.5,
10.88
],
"faces": {
"north": {
"uv": [
0,
0,
3.0500000000000007,
0.5999999999999996
],
"texture": "#kh101"
},
"south": {
"uv": [
0,
0,
3.0500000000000007,
0.5999999999999996
],
"texture": "#kh101"
},
"east": {
"uv": [
0,
0,
8.23,
0.5999999999999996
],
"texture": "#kh101"
},
"west": {
"uv": [
0,
0,
8.23,
0.5999999999999996
],
"texture": "#kh101"
},
"up": {
"uv": [
0,
0,
3.0500000000000007,
8.23
],
"texture": "#kh101"
},
"down": {
"uv": [
0,
0,
3.0500000000000007,
8.23
],
"texture": "#kh101_belly"
}
}
},
{
"from": [
16.5,
6.9,
3.3
],
"to": [
19.55,
7.5,
10.76
],
"faces": {
"north": {
"uv": [
0,
0,
3.0500000000000007,
0.5999999999999996
],
"texture": "#kh101"
},
"south": {
"uv": [
0,
0,
3.0500000000000007,
0.5999999999999996
],
"texture": "#kh101"
},
"east": {
"uv": [
0,
0,
7.46,
0.5999999999999996
],
"texture": "#kh101"
},
"west": {
"uv": [
0,
0,
7.46,
0.5999999999999996
],
"texture": "#kh101"
},
"up": {
"uv": [
0,
0,
3.0500000000000007,
7.46
],
"texture": "#kh101"
},
"down": {
"uv": [
0,
0,
3.0500000000000007,
7.46
],
"texture": "#kh101_belly"
}
}
},
{
"from": [
-3.5500000000000007,
6.9,
3.3
],
"to": [
-0.5,
7.5,
10.76
],
"faces": {
"north": {
"uv": [
0,
0,
3.0500000000000007,
0.5999999999999996
],
"texture": "#kh101"
},
"south": {
"uv": [
0,
0,
3.0500000000000007,
0.5999999999999996
],
"texture": "#kh101"
},
"east": {
"uv": [
0,
0,
7.46,
0.5999999999999996
],
"texture": "#kh101"
},
"west": {
"uv": [
0,
0,
7.46,
0.5999999999999996
],
"texture": "#kh101"
},
"up": {
"uv": [
0,
0,
3.0500000000000007,
7.46
],
"texture": "#kh101"
},
"down": {
"uv": [
0,
0,
3.0500000000000007,
7.46
],
"texture": "#kh101_belly"
}
}
},
{
"from": [
19.5,
6.9,
3.95
],
"to": [
22.55,
7.5,
10.64
],
"faces": {
"north": {
"uv": [
0,
0,
3.0500000000000007,
0.5999999999999996
],
"texture": "#kh101"
},
"south": {
"uv": [
0,
0,
3.0500000000000007,
0.5999999999999996
],
"texture": "#kh101"
},
"east": {
"uv": [
0,
0,
6.69,
0.5999999999999996
],
"texture": "#kh101"
},
"west": {
"uv": [
0,
0,
6.69,
0.5999999999999996
],
"texture": "#kh101"
},
"up": {
"uv": [
0,
0,
3.0500000000000007,
6.69
],
"texture": "#kh101"
},
"down": {
"uv": [
0,
0,
3.0500000000000007,
6.69
],
"texture": "#kh101_belly"
}
}
},
{
"from": [
-6.550000000000001,
6.9,
3.95
],
"to": [
-3.5,
7.5,
10.64
],
"faces": {
"north": {
"uv": [
0,
0,
3.0500000000000007,
0.5999999999999996
],
"texture": "#kh101"
},
"south": {
"uv": [
0,
0,
3.0500000000000007,
0.5999999999999996
],
"texture": "#kh101"
},
"east": {
"uv": [
0,
0,
6.69,
0.5999999999999996
],
"texture": "#kh101"
},
"west": {
"uv": [
0,
0,
6.69,
0.5999999999999996
],
"texture": "#kh101"
},
"up": {
"uv": [
0,
0,
3.0500000000000007,
6.69
],
"texture": "#kh101"
},
"down": {
"uv": [
0,
0,
3.0500000000000007,
6.69
],
"texture": "#kh101_belly"
}
}
},
{
"from": [
22.5,
6.9,
4.6
],
"to": [
25.55,
7.5,
10.52
],
"faces": {
"north": {
"uv": [
0,
0,
3.0500000000000007,
0.5999999999999996
],
"texture": "#kh101"
},
"south": {
"uv": [
0,
0,
3.0500000000000007,
0.5999999999999996
],
"texture": "#kh101"
},
"east": {
"uv": [
0,
0,
5.92,
0.5999999999999996
],
"texture": "#kh101"
},
"west": {
"uv": [
0,
0,
5.92,
0.5999999999999996
],
"texture": "#kh101"
},
"up": {
"uv": [
0,
0,
3.0500000000000007,
5.92
],
"texture": "#kh101"
},
"down": {
"uv": [
0,
0,
3.0500000000000007,
5.92
],
"texture": "#kh101_belly"
}
}
},
{
"from": [
-9.55,
6.9,
4.6
],
"to": [
-6.5,
7.5,
10.52
],
"faces": {
"north": {
"uv": [
0,
0,
3.0500000000000007,
0.5999999999999996
],
"texture": "#kh101"
},
"south": {
"uv": [
0,
0,
3.0500000000000007,
0.5999999999999996
],
"texture": "#kh101"
},
"east": {
"uv": [
0,
0,
5.92,
0.5999999999999996
],
"texture": "#kh101"
},
"west": {
"uv": [
0,
0,
5.92,
0.5999999999999996
],
"texture": "#kh101"
},
"up": {
"uv": [
0,
0,
3.0500000000000007,
5.92
],
"texture": "#kh101"
},
"down": {
"uv": [
0,
0,
3.0500000000000007,
5.92
],
"texture": "#kh101_belly"
}
}
},
{
"from": [
25.5,
6.9,
5.25
],
"to": [
28.5,
7.5,
10.4
],
"faces": {
"north": {
"uv": [
0,
0,
3.0,
0.5999999999999996
],
"texture": "#kh101"
},
"south": {
"uv": [
0,
0,
3.0,
0.5999999999999996
],
"texture": "#kh101"
},
"east": {
"uv": [
0,
0,
5.15,
0.5999999999999996
],
"texture": "#kh101"
},
"west": {
"uv": [
0,
0,
5.15,
0.5999999999999996
],
"texture": "#kh101"
},
"up": {
"uv": [
0,
0,
3.0,
5.15
],
"texture": "#kh101"
},
"down": {
"uv": [
0,
0,
3.0,
5.15
],
"texture": "#kh101_belly"
}
@@ -942,20 +1486,20 @@
"from": [
-12.5,
6.9,
5.0
5.25
],
"to": [
-6.0,
7.4,
11.0
-9.5,
7.5,
10.4
],
"faces": {
"north": {
"uv": [
0,
0,
6.5,
0.5
3.0,
0.5999999999999996
],
"texture": "#kh101"
},
@@ -963,8 +1507,8 @@
"uv": [
0,
0,
6.5,
0.5
3.0,
0.5999999999999996
],
"texture": "#kh101"
},
@@ -972,8 +1516,8 @@
"uv": [
0,
0,
6.0,
0.5
5.15,
0.5999999999999996
],
"texture": "#kh101"
},
@@ -981,8 +1525,8 @@
"uv": [
0,
0,
6.0,
0.5
5.15,
0.5999999999999996
],
"texture": "#kh101"
},
@@ -990,8 +1534,8 @@
"uv": [
0,
0,
6.5,
6.0
3.0,
5.15
],
"texture": "#kh101"
},
@@ -999,8 +1543,8 @@
"uv": [
0,
0,
6.5,
6.0
3.0,
5.15
],
"texture": "#kh101_belly"
}
@@ -1551,4 +2095,4 @@
}
}
]
}
}
File diff suppressed because it is too large Load Diff
@@ -550,6 +550,142 @@
"texture": "#dark_metal"
}
}
},
{
"from": [
0.6,
0.0,
-2.0
],
"to": [
15.4,
9.0,
-1.5
],
"faces": {
"north": {
"uv": [
0,
0,
14.8,
9.0
],
"texture": "#dark_metal"
},
"south": {
"uv": [
0,
0,
14.8,
9.0
],
"texture": "#dark_metal"
},
"east": {
"uv": [
0,
0,
0.5,
9.0
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
0.5,
9.0
],
"texture": "#dark_metal"
},
"up": {
"uv": [
0,
0,
14.8,
0.5
],
"texture": "#dark_metal"
},
"down": {
"uv": [
0,
0,
14.8,
0.5
],
"texture": "#dark_metal"
}
}
},
{
"from": [
0.6,
0.0,
22.0
],
"to": [
15.4,
9.0,
22.5
],
"faces": {
"north": {
"uv": [
0,
0,
14.8,
9.0
],
"texture": "#dark_metal"
},
"south": {
"uv": [
0,
0,
14.8,
9.0
],
"texture": "#dark_metal"
},
"east": {
"uv": [
0,
0,
0.5,
9.0
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
0.5,
9.0
],
"texture": "#dark_metal"
},
"up": {
"uv": [
0,
0,
14.8,
0.5
],
"texture": "#dark_metal"
},
"down": {
"uv": [
0,
0,
14.8,
0.5
],
"texture": "#dark_metal"
}
}
}
]
}
}
@@ -550,6 +550,142 @@
"texture": "#dark_metal_b"
}
}
},
{
"from": [
0.6,
0.0,
-2.0
],
"to": [
15.4,
9.0,
-1.5
],
"faces": {
"north": {
"uv": [
0,
0,
14.8,
9.0
],
"texture": "#dark_metal_b"
},
"south": {
"uv": [
0,
0,
14.8,
9.0
],
"texture": "#dark_metal_b"
},
"east": {
"uv": [
0,
0,
0.5,
9.0
],
"texture": "#dark_metal_b"
},
"west": {
"uv": [
0,
0,
0.5,
9.0
],
"texture": "#dark_metal_b"
},
"up": {
"uv": [
0,
0,
14.8,
0.5
],
"texture": "#dark_metal_b"
},
"down": {
"uv": [
0,
0,
14.8,
0.5
],
"texture": "#dark_metal_b"
}
}
},
{
"from": [
0.6,
0.0,
22.0
],
"to": [
15.4,
9.0,
22.5
],
"faces": {
"north": {
"uv": [
0,
0,
14.8,
9.0
],
"texture": "#dark_metal_b"
},
"south": {
"uv": [
0,
0,
14.8,
9.0
],
"texture": "#dark_metal_b"
},
"east": {
"uv": [
0,
0,
0.5,
9.0
],
"texture": "#dark_metal_b"
},
"west": {
"uv": [
0,
0,
0.5,
9.0
],
"texture": "#dark_metal_b"
},
"up": {
"uv": [
0,
0,
14.8,
0.5
],
"texture": "#dark_metal_b"
},
"down": {
"uv": [
0,
0,
14.8,
0.5
],
"texture": "#dark_metal_b"
}
}
}
]
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -2,9 +2,7 @@
"ambientocclusion": false,
"textures": {
"tubes6": "airdef:block/tubes6",
"ru_green": "airdef:block/ru_green",
"ru_green_s21": "airdef:block/ru_green_s21",
"ru_green_s12": "airdef:block/ru_green_s12",
"pilot_olive": "airdef:block/pilot_olive",
"bare_barrel": "airdef:block/bare_barrel",
"dark_metal": "airdef:block/dark_metal",
"particle": "airdef:block/tubes6"
@@ -38,7 +36,7 @@
8.0,
10.0
],
"texture": "#ru_green"
"texture": "#pilot_olive"
},
"east": {
"uv": [
@@ -47,7 +45,7 @@
16,
10.0
],
"texture": "#ru_green_s21"
"texture": "#pilot_olive"
},
"west": {
"uv": [
@@ -56,7 +54,7 @@
16,
10.0
],
"texture": "#ru_green_s21"
"texture": "#pilot_olive"
},
"up": {
"uv": [
@@ -65,7 +63,7 @@
8.0,
16
],
"texture": "#ru_green_s12"
"texture": "#pilot_olive"
},
"down": {
"uv": [
@@ -74,7 +72,7 @@
8.0,
16
],
"texture": "#ru_green_s12"
"texture": "#pilot_olive"
}
}
},
@@ -106,7 +104,7 @@
8.0,
10.0
],
"texture": "#ru_green"
"texture": "#pilot_olive"
},
"east": {
"uv": [
@@ -115,7 +113,7 @@
16,
10.0
],
"texture": "#ru_green_s21"
"texture": "#pilot_olive"
},
"west": {
"uv": [
@@ -124,7 +122,7 @@
16,
10.0
],
"texture": "#ru_green_s21"
"texture": "#pilot_olive"
},
"up": {
"uv": [
@@ -133,7 +131,7 @@
8.0,
16
],
"texture": "#ru_green_s12"
"texture": "#pilot_olive"
},
"down": {
"uv": [
@@ -142,7 +140,7 @@
8.0,
16
],
"texture": "#ru_green_s12"
"texture": "#pilot_olive"
}
}
},
@@ -555,4 +553,4 @@
}
}
]
}
}
@@ -2,9 +2,7 @@
"ambientocclusion": false,
"textures": {
"tubes6_b": "airdef:block/tubes6_b",
"ru_green_b": "airdef:block/ru_green_b",
"ru_green_s21_b": "airdef:block/ru_green_s21_b",
"ru_green_s12_b": "airdef:block/ru_green_s12_b",
"pilot_olive_b": "airdef:block/pilot_olive_b",
"bare_barrel_b": "airdef:block/bare_barrel_b",
"dark_metal_b": "airdef:block/dark_metal_b",
"particle": "airdef:block/tubes6_b"
@@ -38,7 +36,7 @@
8.0,
10.0
],
"texture": "#ru_green_b"
"texture": "#pilot_olive_b"
},
"east": {
"uv": [
@@ -47,7 +45,7 @@
16,
10.0
],
"texture": "#ru_green_s21_b"
"texture": "#pilot_olive_b"
},
"west": {
"uv": [
@@ -56,7 +54,7 @@
16,
10.0
],
"texture": "#ru_green_s21_b"
"texture": "#pilot_olive_b"
},
"up": {
"uv": [
@@ -65,7 +63,7 @@
8.0,
16
],
"texture": "#ru_green_s12_b"
"texture": "#pilot_olive_b"
},
"down": {
"uv": [
@@ -74,7 +72,7 @@
8.0,
16
],
"texture": "#ru_green_s12_b"
"texture": "#pilot_olive_b"
}
}
},
@@ -106,7 +104,7 @@
8.0,
10.0
],
"texture": "#ru_green_b"
"texture": "#pilot_olive_b"
},
"east": {
"uv": [
@@ -115,7 +113,7 @@
16,
10.0
],
"texture": "#ru_green_s21_b"
"texture": "#pilot_olive_b"
},
"west": {
"uv": [
@@ -124,7 +122,7 @@
16,
10.0
],
"texture": "#ru_green_s21_b"
"texture": "#pilot_olive_b"
},
"up": {
"uv": [
@@ -133,7 +131,7 @@
8.0,
16
],
"texture": "#ru_green_s12_b"
"texture": "#pilot_olive_b"
},
"down": {
"uv": [
@@ -142,7 +140,7 @@
8.0,
16
],
"texture": "#ru_green_s12_b"
"texture": "#pilot_olive_b"
}
}
},
@@ -555,4 +553,4 @@
}
}
]
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,24 +1,23 @@
{
"ambientocclusion": false,
"textures": {
"ru_green": "airdef:block/ru_green",
"pilot_olive": "airdef:block/pilot_olive",
"radar_face": "airdef:block/radar_face",
"metal": "airdef:block/metal",
"dark_metal": "airdef:block/dark_metal",
"metal": "airdef:block/metal",
"bare_lamp": "airdef:block/bare_lamp",
"mk_ru": "airdef:block/mk_ru",
"particle": "airdef:block/ru_green"
"particle": "airdef:block/pilot_olive"
},
"elements": [
{
"from": [
-2.0,
0.0,
-6.0
-5.0
],
"to": [
18.0,
10.0,
7.0,
16.0
],
"faces": {
@@ -27,36 +26,36 @@
0,
0,
16,
10.0
7.0
],
"texture": "#ru_green"
"texture": "#pilot_olive"
},
"south": {
"uv": [
0,
0,
16,
10.0
7.0
],
"texture": "#ru_green"
"texture": "#pilot_olive"
},
"east": {
"uv": [
0,
0,
16,
10.0
7.0
],
"texture": "#ru_green"
"texture": "#pilot_olive"
},
"west": {
"uv": [
0,
0,
16,
10.0
7.0
],
"texture": "#ru_green"
"texture": "#pilot_olive"
},
"up": {
"uv": [
@@ -65,7 +64,7 @@
16,
16
],
"texture": "#ru_green"
"texture": "#pilot_olive"
},
"down": {
"uv": [
@@ -74,7 +73,75 @@
16,
16
],
"texture": "#ru_green"
"texture": "#pilot_olive"
}
}
},
{
"from": [
0.0,
7.0,
-4.0
],
"to": [
16.0,
10.0,
14.0
],
"faces": {
"north": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#pilot_olive"
},
"south": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#pilot_olive"
},
"east": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#pilot_olive"
},
"west": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#pilot_olive"
},
"up": {
"uv": [
0,
0,
16,
16
],
"texture": "#pilot_olive"
},
"down": {
"uv": [
0,
0,
16,
16
],
"texture": "#pilot_olive"
}
}
},
@@ -146,6 +213,74 @@
}
}
},
{
"from": [
2.0,
1.0,
-6.0
],
"to": [
14.0,
11.0,
-5.0
],
"faces": {
"north": {
"uv": [
0,
0,
12.0,
10.0
],
"texture": "#dark_metal"
},
"south": {
"uv": [
0,
0,
12.0,
10.0
],
"texture": "#dark_metal"
},
"east": {
"uv": [
0,
0,
1.0,
10.0
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
1.0,
10.0
],
"texture": "#dark_metal"
},
"up": {
"uv": [
0,
0,
12.0,
1.0
],
"texture": "#dark_metal"
},
"down": {
"uv": [
0,
0,
12.0,
1.0
],
"texture": "#dark_metal"
}
}
},
{
"from": [
7.0,
@@ -216,12 +351,12 @@
},
{
"from": [
0.0,
1.0,
10.0,
8.0
],
"to": [
16.0,
15.0,
12.0,
16.0
],
@@ -230,19 +365,19 @@
"uv": [
0,
0,
16,
14.0,
2.0
],
"texture": "#ru_green"
"texture": "#pilot_olive"
},
"south": {
"uv": [
0,
0,
16,
14.0,
2.0
],
"texture": "#ru_green"
"texture": "#pilot_olive"
},
"east": {
"uv": [
@@ -251,7 +386,7 @@
8.0,
2.0
],
"texture": "#ru_green"
"texture": "#pilot_olive"
},
"west": {
"uv": [
@@ -260,25 +395,25 @@
8.0,
2.0
],
"texture": "#ru_green"
"texture": "#pilot_olive"
},
"up": {
"uv": [
0,
0,
16,
14.0,
8.0
],
"texture": "#ru_green"
"texture": "#pilot_olive"
},
"down": {
"uv": [
0,
0,
16,
14.0,
8.0
],
"texture": "#ru_green"
"texture": "#pilot_olive"
}
}
},
@@ -417,210 +552,6 @@
"texture": "#bare_lamp"
}
}
},
{
"from": [
1.0,
12.0,
10.0
],
"to": [
15.0,
12.6,
15.0
],
"faces": {
"north": {
"uv": [
0,
0,
14.0,
0.5999999999999996
],
"texture": "#metal"
},
"south": {
"uv": [
0,
0,
14.0,
0.5999999999999996
],
"texture": "#metal"
},
"east": {
"uv": [
0,
0,
5.0,
0.5999999999999996
],
"texture": "#metal"
},
"west": {
"uv": [
0,
0,
5.0,
0.5999999999999996
],
"texture": "#metal"
},
"up": {
"uv": [
0,
0,
14.0,
5.0
],
"texture": "#metal"
},
"down": {
"uv": [
0,
0,
14.0,
5.0
],
"texture": "#metal"
}
}
},
{
"from": [
18.0,
3.0,
-4.0
],
"to": [
18.119999999999997,
6.5,
3.0
],
"faces": {
"north": {
"uv": [
0,
0,
0.25,
3.5
],
"texture": "#mk_ru"
},
"south": {
"uv": [
0,
0,
0.25,
3.5
],
"texture": "#mk_ru"
},
"east": {
"uv": [
0,
0,
7.0,
3.5
],
"texture": "#mk_ru"
},
"west": {
"uv": [
0,
0,
7.0,
3.5
],
"texture": "#mk_ru"
},
"up": {
"uv": [
0,
0,
0.25,
7.0
],
"texture": "#mk_ru"
},
"down": {
"uv": [
0,
0,
0.25,
7.0
],
"texture": "#mk_ru"
}
}
},
{
"from": [
-2.1199999999999974,
3.0,
-4.0
],
"to": [
-2.0,
6.5,
3.0
],
"faces": {
"north": {
"uv": [
0,
0,
0.25,
3.5
],
"texture": "#mk_ru"
},
"south": {
"uv": [
0,
0,
0.25,
3.5
],
"texture": "#mk_ru"
},
"east": {
"uv": [
0,
0,
7.0,
3.5
],
"texture": "#mk_ru"
},
"west": {
"uv": [
0,
0,
7.0,
3.5
],
"texture": "#mk_ru"
},
"up": {
"uv": [
0,
0,
0.25,
7.0
],
"texture": "#mk_ru"
},
"down": {
"uv": [
0,
0,
0.25,
7.0
],
"texture": "#mk_ru"
}
}
}
]
}
}
@@ -1,24 +1,22 @@
{
"ambientocclusion": false,
"textures": {
"ru_green_b": "airdef:block/ru_green_b",
"pilot_olive_b": "airdef:block/pilot_olive_b",
"radar_face_b": "airdef:block/radar_face_b",
"metal_b": "airdef:block/metal_b",
"dark_metal_b": "airdef:block/dark_metal_b",
"bare_lamp_b": "airdef:block/bare_lamp_b",
"mk_ru_b": "airdef:block/mk_ru_b",
"particle": "airdef:block/ru_green_b"
"metal_b": "airdef:block/metal_b",
"particle": "airdef:block/pilot_olive_b"
},
"elements": [
{
"from": [
-2.0,
0.0,
-6.0
-5.0
],
"to": [
18.0,
10.0,
7.0,
16.0
],
"faces": {
@@ -27,36 +25,36 @@
0,
0,
16,
10.0
7.0
],
"texture": "#ru_green_b"
"texture": "#pilot_olive_b"
},
"south": {
"uv": [
0,
0,
16,
10.0
7.0
],
"texture": "#ru_green_b"
"texture": "#pilot_olive_b"
},
"east": {
"uv": [
0,
0,
16,
10.0
7.0
],
"texture": "#ru_green_b"
"texture": "#pilot_olive_b"
},
"west": {
"uv": [
0,
0,
16,
10.0
7.0
],
"texture": "#ru_green_b"
"texture": "#pilot_olive_b"
},
"up": {
"uv": [
@@ -65,7 +63,7 @@
16,
16
],
"texture": "#ru_green_b"
"texture": "#pilot_olive_b"
},
"down": {
"uv": [
@@ -74,7 +72,75 @@
16,
16
],
"texture": "#ru_green_b"
"texture": "#pilot_olive_b"
}
}
},
{
"from": [
0.0,
7.0,
-4.0
],
"to": [
16.0,
10.0,
14.0
],
"faces": {
"north": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#pilot_olive_b"
},
"south": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#pilot_olive_b"
},
"east": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#pilot_olive_b"
},
"west": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#pilot_olive_b"
},
"up": {
"uv": [
0,
0,
16,
16
],
"texture": "#pilot_olive_b"
},
"down": {
"uv": [
0,
0,
16,
16
],
"texture": "#pilot_olive_b"
}
}
},
@@ -146,6 +212,74 @@
}
}
},
{
"from": [
2.0,
1.0,
-6.0
],
"to": [
14.0,
11.0,
-5.0
],
"faces": {
"north": {
"uv": [
0,
0,
12.0,
10.0
],
"texture": "#dark_metal_b"
},
"south": {
"uv": [
0,
0,
12.0,
10.0
],
"texture": "#dark_metal_b"
},
"east": {
"uv": [
0,
0,
1.0,
10.0
],
"texture": "#dark_metal_b"
},
"west": {
"uv": [
0,
0,
1.0,
10.0
],
"texture": "#dark_metal_b"
},
"up": {
"uv": [
0,
0,
12.0,
1.0
],
"texture": "#dark_metal_b"
},
"down": {
"uv": [
0,
0,
12.0,
1.0
],
"texture": "#dark_metal_b"
}
}
},
{
"from": [
7.0,
@@ -216,12 +350,12 @@
},
{
"from": [
0.0,
1.0,
10.0,
8.0
],
"to": [
16.0,
15.0,
12.0,
16.0
],
@@ -230,19 +364,19 @@
"uv": [
0,
0,
16,
14.0,
2.0
],
"texture": "#ru_green_b"
"texture": "#pilot_olive_b"
},
"south": {
"uv": [
0,
0,
16,
14.0,
2.0
],
"texture": "#ru_green_b"
"texture": "#pilot_olive_b"
},
"east": {
"uv": [
@@ -251,7 +385,7 @@
8.0,
2.0
],
"texture": "#ru_green_b"
"texture": "#pilot_olive_b"
},
"west": {
"uv": [
@@ -260,25 +394,25 @@
8.0,
2.0
],
"texture": "#ru_green_b"
"texture": "#pilot_olive_b"
},
"up": {
"uv": [
0,
0,
16,
14.0,
8.0
],
"texture": "#ru_green_b"
"texture": "#pilot_olive_b"
},
"down": {
"uv": [
0,
0,
16,
14.0,
8.0
],
"texture": "#ru_green_b"
"texture": "#pilot_olive_b"
}
}
},
@@ -349,210 +483,6 @@
"texture": "#dark_metal_b"
}
}
},
{
"from": [
6.0,
10.5,
-4.4
],
"to": [
10.0,
12.5,
-4.0
],
"faces": {
"north": {
"uv": [
0,
0,
4.0,
2.0
],
"texture": "#bare_lamp_b"
},
"south": {
"uv": [
0,
0,
4.0,
2.0
],
"texture": "#bare_lamp_b"
},
"east": {
"uv": [
0,
0,
0.40000000000000036,
2.0
],
"texture": "#bare_lamp_b"
},
"west": {
"uv": [
0,
0,
0.40000000000000036,
2.0
],
"texture": "#bare_lamp_b"
},
"up": {
"uv": [
0,
0,
4.0,
0.40000000000000036
],
"texture": "#bare_lamp_b"
},
"down": {
"uv": [
0,
0,
4.0,
0.40000000000000036
],
"texture": "#bare_lamp_b"
}
}
},
{
"from": [
1.0,
12.0,
10.0
],
"to": [
15.0,
12.6,
15.0
],
"faces": {
"north": {
"uv": [
0,
0,
14.0,
0.5999999999999996
],
"texture": "#metal_b"
},
"south": {
"uv": [
0,
0,
14.0,
0.5999999999999996
],
"texture": "#metal_b"
},
"east": {
"uv": [
0,
0,
5.0,
0.5999999999999996
],
"texture": "#metal_b"
},
"west": {
"uv": [
0,
0,
5.0,
0.5999999999999996
],
"texture": "#metal_b"
},
"up": {
"uv": [
0,
0,
14.0,
5.0
],
"texture": "#metal_b"
},
"down": {
"uv": [
0,
0,
14.0,
5.0
],
"texture": "#metal_b"
}
}
},
{
"from": [
-2.1199999999999974,
3.0,
-4.0
],
"to": [
-2.0,
6.5,
3.0
],
"faces": {
"north": {
"uv": [
0,
0,
0.25,
3.5
],
"texture": "#mk_ru_b"
},
"south": {
"uv": [
0,
0,
0.25,
3.5
],
"texture": "#mk_ru_b"
},
"east": {
"uv": [
0,
0,
7.0,
3.5
],
"texture": "#mk_ru_b"
},
"west": {
"uv": [
0,
0,
7.0,
3.5
],
"texture": "#mk_ru_b"
},
"up": {
"uv": [
0,
0,
0.25,
7.0
],
"texture": "#mk_ru_b"
},
"down": {
"uv": [
0,
0,
0.25,
7.0
],
"texture": "#mk_ru_b"
}
}
}
]
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,418 @@
{
"ambientocclusion": false,
"textures": {
"dark_metal": "airdef:block/dark_metal",
"metal": "airdef:block/metal",
"particle": "airdef:block/dark_metal"
},
"elements": [
{
"from": [
4.0,
0.0,
4.0
],
"to": [
12.0,
3.0,
12.0
],
"faces": {
"north": {
"uv": [
0,
0,
8.0,
3.0
],
"texture": "#dark_metal"
},
"south": {
"uv": [
0,
0,
8.0,
3.0
],
"texture": "#dark_metal"
},
"east": {
"uv": [
0,
0,
8.0,
3.0
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
8.0,
3.0
],
"texture": "#dark_metal"
},
"up": {
"uv": [
0,
0,
8.0,
8.0
],
"texture": "#dark_metal"
},
"down": {
"uv": [
0,
0,
8.0,
8.0
],
"texture": "#dark_metal"
}
}
},
{
"from": [
5.5,
3.0,
5.5
],
"to": [
10.5,
18.0,
10.5
],
"faces": {
"north": {
"uv": [
0,
0,
5.0,
15.0
],
"texture": "#metal"
},
"south": {
"uv": [
0,
0,
5.0,
15.0
],
"texture": "#metal"
},
"east": {
"uv": [
0,
0,
5.0,
15.0
],
"texture": "#metal"
},
"west": {
"uv": [
0,
0,
5.0,
15.0
],
"texture": "#metal"
},
"up": {
"uv": [
0,
0,
5.0,
5.0
],
"texture": "#metal"
},
"down": {
"uv": [
0,
0,
5.0,
5.0
],
"texture": "#metal"
}
}
},
{
"from": [
4.5,
18.0,
4.5
],
"to": [
11.5,
21.0,
11.5
],
"faces": {
"north": {
"uv": [
0,
0,
7.0,
3.0
],
"texture": "#dark_metal"
},
"south": {
"uv": [
0,
0,
7.0,
3.0
],
"texture": "#dark_metal"
},
"east": {
"uv": [
0,
0,
7.0,
3.0
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
7.0,
3.0
],
"texture": "#dark_metal"
},
"up": {
"uv": [
0,
0,
7.0,
7.0
],
"texture": "#dark_metal"
},
"down": {
"uv": [
0,
0,
7.0,
7.0
],
"texture": "#dark_metal"
}
}
},
{
"from": [
6.5,
21.0,
6.5
],
"to": [
9.5,
30.0,
9.5
],
"faces": {
"north": {
"uv": [
0,
0,
3.0,
9.0
],
"texture": "#dark_metal"
},
"south": {
"uv": [
0,
0,
3.0,
9.0
],
"texture": "#dark_metal"
},
"east": {
"uv": [
0,
0,
3.0,
9.0
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
3.0,
9.0
],
"texture": "#dark_metal"
},
"up": {
"uv": [
0,
0,
3.0,
3.0
],
"texture": "#dark_metal"
},
"down": {
"uv": [
0,
0,
3.0,
3.0
],
"texture": "#dark_metal"
}
}
},
{
"from": [
5.5,
30.0,
5.5
],
"to": [
10.5,
32.0,
10.5
],
"faces": {
"north": {
"uv": [
0,
0,
5.0,
2.0
],
"texture": "#metal"
},
"south": {
"uv": [
0,
0,
5.0,
2.0
],
"texture": "#metal"
},
"east": {
"uv": [
0,
0,
5.0,
2.0
],
"texture": "#metal"
},
"west": {
"uv": [
0,
0,
5.0,
2.0
],
"texture": "#metal"
},
"up": {
"uv": [
0,
0,
5.0,
5.0
],
"texture": "#metal"
},
"down": {
"uv": [
0,
0,
5.0,
5.0
],
"texture": "#metal"
}
}
},
{
"from": [
7.0,
31.5,
7.0
],
"to": [
9.0,
32.0,
9.0
],
"faces": {
"north": {
"uv": [
0,
0,
2.0,
0.5
],
"texture": "#dark_metal"
},
"south": {
"uv": [
0,
0,
2.0,
0.5
],
"texture": "#dark_metal"
},
"east": {
"uv": [
0,
0,
2.0,
0.5
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
2.0,
0.5
],
"texture": "#dark_metal"
},
"up": {
"uv": [
0,
0,
2.0,
2.0
],
"texture": "#dark_metal"
},
"down": {
"uv": [
0,
0,
2.0,
2.0
],
"texture": "#dark_metal"
}
}
}
]
}
@@ -0,0 +1,418 @@
{
"ambientocclusion": false,
"textures": {
"dark_metal_b": "airdef:block/dark_metal_b",
"metal_b": "airdef:block/metal_b",
"particle": "airdef:block/dark_metal_b"
},
"elements": [
{
"from": [
4.0,
0.0,
4.0
],
"to": [
12.0,
3.0,
12.0
],
"faces": {
"north": {
"uv": [
0,
0,
8.0,
3.0
],
"texture": "#dark_metal_b"
},
"south": {
"uv": [
0,
0,
8.0,
3.0
],
"texture": "#dark_metal_b"
},
"east": {
"uv": [
0,
0,
8.0,
3.0
],
"texture": "#dark_metal_b"
},
"west": {
"uv": [
0,
0,
8.0,
3.0
],
"texture": "#dark_metal_b"
},
"up": {
"uv": [
0,
0,
8.0,
8.0
],
"texture": "#dark_metal_b"
},
"down": {
"uv": [
0,
0,
8.0,
8.0
],
"texture": "#dark_metal_b"
}
}
},
{
"from": [
5.5,
3.0,
5.5
],
"to": [
10.5,
18.0,
10.5
],
"faces": {
"north": {
"uv": [
0,
0,
5.0,
15.0
],
"texture": "#metal_b"
},
"south": {
"uv": [
0,
0,
5.0,
15.0
],
"texture": "#metal_b"
},
"east": {
"uv": [
0,
0,
5.0,
15.0
],
"texture": "#metal_b"
},
"west": {
"uv": [
0,
0,
5.0,
15.0
],
"texture": "#metal_b"
},
"up": {
"uv": [
0,
0,
5.0,
5.0
],
"texture": "#metal_b"
},
"down": {
"uv": [
0,
0,
5.0,
5.0
],
"texture": "#metal_b"
}
}
},
{
"from": [
4.5,
18.0,
4.5
],
"to": [
11.5,
21.0,
11.5
],
"faces": {
"north": {
"uv": [
0,
0,
7.0,
3.0
],
"texture": "#dark_metal_b"
},
"south": {
"uv": [
0,
0,
7.0,
3.0
],
"texture": "#dark_metal_b"
},
"east": {
"uv": [
0,
0,
7.0,
3.0
],
"texture": "#dark_metal_b"
},
"west": {
"uv": [
0,
0,
7.0,
3.0
],
"texture": "#dark_metal_b"
},
"up": {
"uv": [
0,
0,
7.0,
7.0
],
"texture": "#dark_metal_b"
},
"down": {
"uv": [
0,
0,
7.0,
7.0
],
"texture": "#dark_metal_b"
}
}
},
{
"from": [
6.5,
21.0,
6.5
],
"to": [
9.5,
30.0,
9.5
],
"faces": {
"north": {
"uv": [
0,
0,
3.0,
9.0
],
"texture": "#dark_metal_b"
},
"south": {
"uv": [
0,
0,
3.0,
9.0
],
"texture": "#dark_metal_b"
},
"east": {
"uv": [
0,
0,
3.0,
9.0
],
"texture": "#dark_metal_b"
},
"west": {
"uv": [
0,
0,
3.0,
9.0
],
"texture": "#dark_metal_b"
},
"up": {
"uv": [
0,
0,
3.0,
3.0
],
"texture": "#dark_metal_b"
},
"down": {
"uv": [
0,
0,
3.0,
3.0
],
"texture": "#dark_metal_b"
}
}
},
{
"from": [
5.5,
30.0,
5.5
],
"to": [
10.5,
32.0,
10.5
],
"faces": {
"north": {
"uv": [
0,
0,
5.0,
2.0
],
"texture": "#metal_b"
},
"south": {
"uv": [
0,
0,
5.0,
2.0
],
"texture": "#metal_b"
},
"east": {
"uv": [
0,
0,
5.0,
2.0
],
"texture": "#metal_b"
},
"west": {
"uv": [
0,
0,
5.0,
2.0
],
"texture": "#metal_b"
},
"up": {
"uv": [
0,
0,
5.0,
5.0
],
"texture": "#metal_b"
},
"down": {
"uv": [
0,
0,
5.0,
5.0
],
"texture": "#metal_b"
}
}
},
{
"from": [
7.0,
31.5,
7.0
],
"to": [
9.0,
32.0,
9.0
],
"faces": {
"north": {
"uv": [
0,
0,
2.0,
0.5
],
"texture": "#dark_metal_b"
},
"south": {
"uv": [
0,
0,
2.0,
0.5
],
"texture": "#dark_metal_b"
},
"east": {
"uv": [
0,
0,
2.0,
0.5
],
"texture": "#dark_metal_b"
},
"west": {
"uv": [
0,
0,
2.0,
0.5
],
"texture": "#dark_metal_b"
},
"up": {
"uv": [
0,
0,
2.0,
2.0
],
"texture": "#dark_metal_b"
},
"down": {
"uv": [
0,
0,
2.0,
2.0
],
"texture": "#dark_metal_b"
}
}
}
]
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -19,15 +19,6 @@
32.0
],
"faces": {
"north": {
"uv": [
0,
0,
9.5,
9.5
],
"texture": "#tube_cap"
},
"south": {
"uv": [
0,
@@ -87,15 +78,6 @@
32.0
],
"faces": {
"north": {
"uv": [
0,
0,
9.5,
9.5
],
"texture": "#tube_cap"
},
"south": {
"uv": [
0,
@@ -19,15 +19,6 @@
32.0
],
"faces": {
"north": {
"uv": [
0,
0,
9.5,
9.5
],
"texture": "#tube_cap_b"
},
"south": {
"uv": [
0,
@@ -87,15 +78,6 @@
32.0
],
"faces": {
"north": {
"uv": [
0,
0,
9.5,
9.5
],
"texture": "#tube_cap_b"
},
"south": {
"uv": [
0,
@@ -2,27 +2,28 @@
"ambientocclusion": false,
"textures": {
"dark_metal": "airdef:block/dark_metal",
"metal": "airdef:block/metal",
"particle": "airdef:block/dark_metal"
},
"elements": [
{
"from": [
2.0,
1.0,
0.0,
2.0
1.0
],
"to": [
14.0,
3.0,
14.0
15.0,
2.0,
15.0
],
"faces": {
"north": {
"uv": [
0,
0,
12.0,
3.0
14.0,
2.0
],
"texture": "#dark_metal"
},
@@ -30,8 +31,8 @@
"uv": [
0,
0,
12.0,
3.0
14.0,
2.0
],
"texture": "#dark_metal"
},
@@ -39,8 +40,8 @@
"uv": [
0,
0,
12.0,
3.0
14.0,
2.0
],
"texture": "#dark_metal"
},
@@ -48,8 +49,8 @@
"uv": [
0,
0,
12.0,
3.0
14.0,
2.0
],
"texture": "#dark_metal"
},
@@ -57,8 +58,8 @@
"uv": [
0,
0,
12.0,
12.0
14.0,
14.0
],
"texture": "#dark_metal"
},
@@ -66,8 +67,8 @@
"uv": [
0,
0,
12.0,
12.0
14.0,
14.0
],
"texture": "#dark_metal"
}
@@ -75,8 +76,76 @@
},
{
"from": [
6.0,
3.0,
2.0,
3.0
],
"to": [
13.0,
4.0,
13.0
],
"faces": {
"north": {
"uv": [
0,
0,
10.0,
2.0
],
"texture": "#metal"
},
"south": {
"uv": [
0,
0,
10.0,
2.0
],
"texture": "#metal"
},
"east": {
"uv": [
0,
0,
10.0,
2.0
],
"texture": "#metal"
},
"west": {
"uv": [
0,
0,
10.0,
2.0
],
"texture": "#metal"
},
"up": {
"uv": [
0,
0,
10.0,
10.0
],
"texture": "#metal"
},
"down": {
"uv": [
0,
0,
10.0,
10.0
],
"texture": "#metal"
}
}
},
{
"from": [
6.0,
4.0,
6.0
],
"to": [
@@ -90,7 +159,7 @@
0,
0,
4.0,
9.0
8.0
],
"texture": "#dark_metal"
},
@@ -99,7 +168,7 @@
0,
0,
4.0,
9.0
8.0
],
"texture": "#dark_metal"
},
@@ -108,7 +177,7 @@
0,
0,
4.0,
9.0
8.0
],
"texture": "#dark_metal"
},
@@ -117,7 +186,7 @@
0,
0,
4.0,
9.0
8.0
],
"texture": "#dark_metal"
},
@@ -140,6 +209,142 @@
"texture": "#dark_metal"
}
}
},
{
"from": [
2.0,
8.0,
7.0
],
"to": [
3.0,
14.0,
9.0
],
"faces": {
"north": {
"uv": [
0,
0,
1.0,
6.0
],
"texture": "#metal"
},
"south": {
"uv": [
0,
0,
1.0,
6.0
],
"texture": "#metal"
},
"east": {
"uv": [
0,
0,
2.0,
6.0
],
"texture": "#metal"
},
"west": {
"uv": [
0,
0,
2.0,
6.0
],
"texture": "#metal"
},
"up": {
"uv": [
0,
0,
1.0,
2.0
],
"texture": "#metal"
},
"down": {
"uv": [
0,
0,
1.0,
2.0
],
"texture": "#metal"
}
}
},
{
"from": [
13.0,
8.0,
7.0
],
"to": [
14.0,
14.0,
9.0
],
"faces": {
"north": {
"uv": [
0,
0,
1.0,
6.0
],
"texture": "#metal"
},
"south": {
"uv": [
0,
0,
1.0,
6.0
],
"texture": "#metal"
},
"east": {
"uv": [
0,
0,
2.0,
6.0
],
"texture": "#metal"
},
"west": {
"uv": [
0,
0,
2.0,
6.0
],
"texture": "#metal"
},
"up": {
"uv": [
0,
0,
1.0,
2.0
],
"texture": "#metal"
},
"down": {
"uv": [
0,
0,
1.0,
2.0
],
"texture": "#metal"
}
}
}
]
}
}
@@ -2,27 +2,28 @@
"ambientocclusion": false,
"textures": {
"dark_metal_b": "airdef:block/dark_metal_b",
"metal_b": "airdef:block/metal_b",
"particle": "airdef:block/dark_metal_b"
},
"elements": [
{
"from": [
2.0,
1.0,
0.0,
2.0
1.0
],
"to": [
14.0,
3.0,
14.0
15.0,
2.0,
15.0
],
"faces": {
"north": {
"uv": [
0,
0,
12.0,
3.0
14.0,
2.0
],
"texture": "#dark_metal_b"
},
@@ -30,8 +31,8 @@
"uv": [
0,
0,
12.0,
3.0
14.0,
2.0
],
"texture": "#dark_metal_b"
},
@@ -39,8 +40,8 @@
"uv": [
0,
0,
12.0,
3.0
14.0,
2.0
],
"texture": "#dark_metal_b"
},
@@ -48,8 +49,8 @@
"uv": [
0,
0,
12.0,
3.0
14.0,
2.0
],
"texture": "#dark_metal_b"
},
@@ -57,8 +58,8 @@
"uv": [
0,
0,
12.0,
12.0
14.0,
14.0
],
"texture": "#dark_metal_b"
},
@@ -66,8 +67,8 @@
"uv": [
0,
0,
12.0,
12.0
14.0,
14.0
],
"texture": "#dark_metal_b"
}
@@ -75,8 +76,76 @@
},
{
"from": [
6.0,
3.0,
2.0,
3.0
],
"to": [
13.0,
4.0,
13.0
],
"faces": {
"north": {
"uv": [
0,
0,
10.0,
2.0
],
"texture": "#metal_b"
},
"south": {
"uv": [
0,
0,
10.0,
2.0
],
"texture": "#metal_b"
},
"east": {
"uv": [
0,
0,
10.0,
2.0
],
"texture": "#metal_b"
},
"west": {
"uv": [
0,
0,
10.0,
2.0
],
"texture": "#metal_b"
},
"up": {
"uv": [
0,
0,
10.0,
10.0
],
"texture": "#metal_b"
},
"down": {
"uv": [
0,
0,
10.0,
10.0
],
"texture": "#metal_b"
}
}
},
{
"from": [
6.0,
4.0,
6.0
],
"to": [
@@ -90,7 +159,7 @@
0,
0,
4.0,
9.0
8.0
],
"texture": "#dark_metal_b"
},
@@ -99,7 +168,7 @@
0,
0,
4.0,
9.0
8.0
],
"texture": "#dark_metal_b"
},
@@ -108,7 +177,7 @@
0,
0,
4.0,
9.0
8.0
],
"texture": "#dark_metal_b"
},
@@ -117,7 +186,7 @@
0,
0,
4.0,
9.0
8.0
],
"texture": "#dark_metal_b"
},
@@ -140,6 +209,74 @@
"texture": "#dark_metal_b"
}
}
},
{
"from": [
2.0,
8.0,
7.0
],
"to": [
3.0,
14.0,
9.0
],
"faces": {
"north": {
"uv": [
0,
0,
1.0,
6.0
],
"texture": "#metal_b"
},
"south": {
"uv": [
0,
0,
1.0,
6.0
],
"texture": "#metal_b"
},
"east": {
"uv": [
0,
0,
2.0,
6.0
],
"texture": "#metal_b"
},
"west": {
"uv": [
0,
0,
2.0,
6.0
],
"texture": "#metal_b"
},
"up": {
"uv": [
0,
0,
1.0,
2.0
],
"texture": "#metal_b"
},
"down": {
"uv": [
0,
0,
1.0,
2.0
],
"texture": "#metal_b"
}
}
}
]
}
}
@@ -3,6 +3,7 @@
"textures": {
"dark_metal": "airdef:block/dark_metal",
"lamp": "airdef:block/lamp",
"metal": "airdef:block/metal",
"particle": "airdef:block/dark_metal"
},
"elements": [
@@ -74,6 +75,74 @@
}
}
},
{
"from": [
4.0,
2.0,
0.0
],
"to": [
12.0,
14.0,
12.0
],
"faces": {
"north": {
"uv": [
0,
0,
8.0,
12.0
],
"texture": "#dark_metal"
},
"south": {
"uv": [
0,
0,
8.0,
12.0
],
"texture": "#dark_metal"
},
"east": {
"uv": [
0,
0,
12.0,
12.0
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
12.0,
12.0
],
"texture": "#dark_metal"
},
"up": {
"uv": [
0,
0,
8.0,
12.0
],
"texture": "#dark_metal"
},
"down": {
"uv": [
0,
0,
8.0,
12.0
],
"texture": "#dark_metal"
}
}
},
{
"from": [
3.5,
@@ -141,6 +210,74 @@
"texture": "#lamp"
}
}
},
{
"from": [
5.0,
5.0,
14.0
],
"to": [
11.0,
11.0,
15.0
],
"faces": {
"north": {
"uv": [
0,
0,
6.0,
6.0
],
"texture": "#metal"
},
"south": {
"uv": [
0,
0,
6.0,
6.0
],
"texture": "#metal"
},
"east": {
"uv": [
0,
0,
1.0,
6.0
],
"texture": "#metal"
},
"west": {
"uv": [
0,
0,
1.0,
6.0
],
"texture": "#metal"
},
"up": {
"uv": [
0,
0,
6.0,
1.0
],
"texture": "#metal"
},
"down": {
"uv": [
0,
0,
6.0,
1.0
],
"texture": "#metal"
}
}
}
]
}
}
@@ -74,6 +74,74 @@
}
}
},
{
"from": [
4.0,
2.0,
0.0
],
"to": [
12.0,
14.0,
12.0
],
"faces": {
"north": {
"uv": [
0,
0,
8.0,
12.0
],
"texture": "#dark_metal_b"
},
"south": {
"uv": [
0,
0,
8.0,
12.0
],
"texture": "#dark_metal_b"
},
"east": {
"uv": [
0,
0,
12.0,
12.0
],
"texture": "#dark_metal_b"
},
"west": {
"uv": [
0,
0,
12.0,
12.0
],
"texture": "#dark_metal_b"
},
"up": {
"uv": [
0,
0,
8.0,
12.0
],
"texture": "#dark_metal_b"
},
"down": {
"uv": [
0,
0,
8.0,
12.0
],
"texture": "#dark_metal_b"
}
}
},
{
"from": [
3.5,
@@ -143,4 +211,4 @@
}
}
]
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,12 +1,11 @@
{
"ambientocclusion": false,
"textures": {
"ru_khaki_s21": "airdef:block/ru_khaki_s21",
"ru_khaki_s22": "airdef:block/ru_khaki_s22",
"pilot_olive": "airdef:block/pilot_olive",
"radar_face": "airdef:block/radar_face",
"dark_metal": "airdef:block/dark_metal",
"tube_cap": "airdef:block/tube_cap",
"particle": "airdef:block/ru_khaki_s21"
"particle": "airdef:block/pilot_olive"
},
"elements": [
{
@@ -17,7 +16,7 @@
],
"to": [
20.0,
16.0,
12.0,
22.0
],
"faces": {
@@ -26,36 +25,36 @@
0,
0,
16,
16
12.0
],
"texture": "#ru_khaki_s21"
"texture": "#pilot_olive"
},
"south": {
"uv": [
0,
0,
16,
16
12.0
],
"texture": "#ru_khaki_s21"
"texture": "#pilot_olive"
},
"east": {
"uv": [
0,
0,
16,
16
12.0
],
"texture": "#ru_khaki_s21"
"texture": "#pilot_olive"
},
"west": {
"uv": [
0,
0,
16,
16
12.0
],
"texture": "#ru_khaki_s21"
"texture": "#pilot_olive"
},
"up": {
"uv": [
@@ -64,7 +63,7 @@
16,
16
],
"texture": "#ru_khaki_s22"
"texture": "#pilot_olive"
},
"down": {
"uv": [
@@ -73,7 +72,75 @@
16,
16
],
"texture": "#ru_khaki_s22"
"texture": "#pilot_olive"
}
}
},
{
"from": [
-3.0,
12.0,
-3.0
],
"to": [
19.0,
16.0,
21.0
],
"faces": {
"north": {
"uv": [
0,
0,
16,
4.0
],
"texture": "#pilot_olive"
},
"south": {
"uv": [
0,
0,
16,
4.0
],
"texture": "#pilot_olive"
},
"east": {
"uv": [
0,
0,
16,
4.0
],
"texture": "#pilot_olive"
},
"west": {
"uv": [
0,
0,
16,
4.0
],
"texture": "#pilot_olive"
},
"up": {
"uv": [
0,
0,
16,
16
],
"texture": "#pilot_olive"
},
"down": {
"uv": [
0,
0,
16,
16
],
"texture": "#pilot_olive"
}
}
},
@@ -758,4 +825,4 @@
}
}
]
}
}
@@ -1,12 +1,11 @@
{
"ambientocclusion": false,
"textures": {
"ru_khaki_s21_b": "airdef:block/ru_khaki_s21_b",
"ru_khaki_s22_b": "airdef:block/ru_khaki_s22_b",
"pilot_olive_b": "airdef:block/pilot_olive_b",
"radar_face_b": "airdef:block/radar_face_b",
"dark_metal_b": "airdef:block/dark_metal_b",
"tube_cap_b": "airdef:block/tube_cap_b",
"particle": "airdef:block/ru_khaki_s21_b"
"particle": "airdef:block/pilot_olive_b"
},
"elements": [
{
@@ -17,7 +16,7 @@
],
"to": [
20.0,
16.0,
12.0,
22.0
],
"faces": {
@@ -26,36 +25,36 @@
0,
0,
16,
16
12.0
],
"texture": "#ru_khaki_s21_b"
"texture": "#pilot_olive_b"
},
"south": {
"uv": [
0,
0,
16,
16
12.0
],
"texture": "#ru_khaki_s21_b"
"texture": "#pilot_olive_b"
},
"east": {
"uv": [
0,
0,
16,
16
12.0
],
"texture": "#ru_khaki_s21_b"
"texture": "#pilot_olive_b"
},
"west": {
"uv": [
0,
0,
16,
16
12.0
],
"texture": "#ru_khaki_s21_b"
"texture": "#pilot_olive_b"
},
"up": {
"uv": [
@@ -64,7 +63,7 @@
16,
16
],
"texture": "#ru_khaki_s22_b"
"texture": "#pilot_olive_b"
},
"down": {
"uv": [
@@ -73,7 +72,75 @@
16,
16
],
"texture": "#ru_khaki_s22_b"
"texture": "#pilot_olive_b"
}
}
},
{
"from": [
-3.0,
12.0,
-3.0
],
"to": [
19.0,
16.0,
21.0
],
"faces": {
"north": {
"uv": [
0,
0,
16,
4.0
],
"texture": "#pilot_olive_b"
},
"south": {
"uv": [
0,
0,
16,
4.0
],
"texture": "#pilot_olive_b"
},
"east": {
"uv": [
0,
0,
16,
4.0
],
"texture": "#pilot_olive_b"
},
"west": {
"uv": [
0,
0,
16,
4.0
],
"texture": "#pilot_olive_b"
},
"up": {
"uv": [
0,
0,
16,
16
],
"texture": "#pilot_olive_b"
},
"down": {
"uv": [
0,
0,
16,
16
],
"texture": "#pilot_olive_b"
}
}
},
@@ -622,4 +689,4 @@
}
}
]
}
}
@@ -0,0 +1,282 @@
{
"ambientocclusion": false,
"textures": {
"tube_cap": "airdef:block/tube_cap",
"dark_metal": "airdef:block/dark_metal",
"particle": "airdef:block/tube_cap"
},
"elements": [
{
"from": [
2.5,
0.0,
7.7
],
"to": [
13.5,
16.0,
8.25
],
"faces": {
"north": {
"uv": [
0,
0,
11.0,
16
],
"texture": "#tube_cap"
},
"south": {
"uv": [
0,
0,
11.0,
16
],
"texture": "#tube_cap"
},
"east": {
"uv": [
0,
0,
0.5499999999999998,
16
],
"texture": "#tube_cap"
},
"west": {
"uv": [
0,
0,
0.5499999999999998,
16
],
"texture": "#tube_cap"
},
"up": {
"uv": [
0,
0,
11.0,
0.5499999999999998
],
"texture": "#tube_cap"
},
"down": {
"uv": [
0,
0,
11.0,
0.5499999999999998
],
"texture": "#tube_cap"
}
}
},
{
"from": [
0.0,
2.5,
7.7
],
"to": [
2.5,
13.5,
8.25
],
"faces": {
"north": {
"uv": [
0,
0,
2.5,
11.0
],
"texture": "#tube_cap"
},
"south": {
"uv": [
0,
0,
2.5,
11.0
],
"texture": "#tube_cap"
},
"east": {
"uv": [
0,
0,
0.5499999999999998,
11.0
],
"texture": "#tube_cap"
},
"west": {
"uv": [
0,
0,
0.5499999999999998,
11.0
],
"texture": "#tube_cap"
},
"up": {
"uv": [
0,
0,
2.5,
0.5499999999999998
],
"texture": "#tube_cap"
},
"down": {
"uv": [
0,
0,
2.5,
0.5499999999999998
],
"texture": "#tube_cap"
}
}
},
{
"from": [
13.5,
2.5,
7.7
],
"to": [
16.0,
13.5,
8.25
],
"faces": {
"north": {
"uv": [
0,
0,
2.5,
11.0
],
"texture": "#tube_cap"
},
"south": {
"uv": [
0,
0,
2.5,
11.0
],
"texture": "#tube_cap"
},
"east": {
"uv": [
0,
0,
0.5499999999999998,
11.0
],
"texture": "#tube_cap"
},
"west": {
"uv": [
0,
0,
0.5499999999999998,
11.0
],
"texture": "#tube_cap"
},
"up": {
"uv": [
0,
0,
2.5,
0.5499999999999998
],
"texture": "#tube_cap"
},
"down": {
"uv": [
0,
0,
2.5,
0.5499999999999998
],
"texture": "#tube_cap"
}
}
},
{
"from": [
5.0,
5.0,
8.25
],
"to": [
11.0,
11.0,
8.3
],
"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,
0.25,
6.0
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
0.25,
6.0
],
"texture": "#dark_metal"
},
"up": {
"uv": [
0,
0,
6.0,
0.25
],
"texture": "#dark_metal"
},
"down": {
"uv": [
0,
0,
6.0,
0.25
],
"texture": "#dark_metal"
}
}
}
]
}
@@ -0,0 +1,282 @@
{
"ambientocclusion": false,
"textures": {
"tube_cap_b": "airdef:block/tube_cap_b",
"dark_metal_b": "airdef:block/dark_metal_b",
"particle": "airdef:block/tube_cap_b"
},
"elements": [
{
"from": [
2.5,
0.0,
7.7
],
"to": [
13.5,
16.0,
8.25
],
"faces": {
"north": {
"uv": [
0,
0,
11.0,
16
],
"texture": "#tube_cap_b"
},
"south": {
"uv": [
0,
0,
11.0,
16
],
"texture": "#tube_cap_b"
},
"east": {
"uv": [
0,
0,
0.5499999999999998,
16
],
"texture": "#tube_cap_b"
},
"west": {
"uv": [
0,
0,
0.5499999999999998,
16
],
"texture": "#tube_cap_b"
},
"up": {
"uv": [
0,
0,
11.0,
0.5499999999999998
],
"texture": "#tube_cap_b"
},
"down": {
"uv": [
0,
0,
11.0,
0.5499999999999998
],
"texture": "#tube_cap_b"
}
}
},
{
"from": [
0.0,
2.5,
7.7
],
"to": [
2.5,
13.5,
8.25
],
"faces": {
"north": {
"uv": [
0,
0,
2.5,
11.0
],
"texture": "#tube_cap_b"
},
"south": {
"uv": [
0,
0,
2.5,
11.0
],
"texture": "#tube_cap_b"
},
"east": {
"uv": [
0,
0,
0.5499999999999998,
11.0
],
"texture": "#tube_cap_b"
},
"west": {
"uv": [
0,
0,
0.5499999999999998,
11.0
],
"texture": "#tube_cap_b"
},
"up": {
"uv": [
0,
0,
2.5,
0.5499999999999998
],
"texture": "#tube_cap_b"
},
"down": {
"uv": [
0,
0,
2.5,
0.5499999999999998
],
"texture": "#tube_cap_b"
}
}
},
{
"from": [
13.5,
2.5,
7.7
],
"to": [
16.0,
13.5,
8.25
],
"faces": {
"north": {
"uv": [
0,
0,
2.5,
11.0
],
"texture": "#tube_cap_b"
},
"south": {
"uv": [
0,
0,
2.5,
11.0
],
"texture": "#tube_cap_b"
},
"east": {
"uv": [
0,
0,
0.5499999999999998,
11.0
],
"texture": "#tube_cap_b"
},
"west": {
"uv": [
0,
0,
0.5499999999999998,
11.0
],
"texture": "#tube_cap_b"
},
"up": {
"uv": [
0,
0,
2.5,
0.5499999999999998
],
"texture": "#tube_cap_b"
},
"down": {
"uv": [
0,
0,
2.5,
0.5499999999999998
],
"texture": "#tube_cap_b"
}
}
},
{
"from": [
5.0,
5.0,
8.25
],
"to": [
11.0,
11.0,
8.3
],
"faces": {
"north": {
"uv": [
0,
0,
6.0,
6.0
],
"texture": "#dark_metal_b"
},
"south": {
"uv": [
0,
0,
6.0,
6.0
],
"texture": "#dark_metal_b"
},
"east": {
"uv": [
0,
0,
0.25,
6.0
],
"texture": "#dark_metal_b"
},
"west": {
"uv": [
0,
0,
0.25,
6.0
],
"texture": "#dark_metal_b"
},
"up": {
"uv": [
0,
0,
6.0,
0.25
],
"texture": "#dark_metal_b"
},
"down": {
"uv": [
0,
0,
6.0,
0.25
],
"texture": "#dark_metal_b"
}
}
}
]
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 B

@@ -0,0 +1,4 @@
{
"template": "minecraft:stone",
"item": false
}
@@ -0,0 +1,4 @@
{
"template": "minecraft:stone",
"item": false
}
@@ -0,0 +1,4 @@
{
"template": "minecraft:stone",
"item": false
}
@@ -0,0 +1,4 @@
{
"template": "minecraft:stone",
"item": false
}
@@ -0,0 +1,4 @@
{
"template": "minecraft:stone",
"item": false
}
+57
View File
@@ -0,0 +1,57 @@
//! Enemy-picture outcomes on fixed seeds (#127): what changed for the raids, measured.
//!
//! Runs the standard scenarios over a fixed seed set and prints one JSON object with the
//! completion, losses and failure reasons of every run — the before/after comparison of the
//! honest EnemyPicture is judged on these, not on "it got smarter".
//!
//! cargo run --release --example intel_bench
#[path = "sim_run/harness.rs"]
mod harness;
use harness::{big_smart, ew_adaptive, logistics, Scenario};
fn esc(s: &str) -> String {
s.chars().flat_map(|c| match c {
'"' => "\\\"".chars().collect::<Vec<_>>(),
'\\' => "\\\\".chars().collect::<Vec<_>>(),
c => vec![c],
}).collect()
}
fn run(sc: &Scenario) -> String {
let r = harness::run(sc);
format!(
"{{\"scenario\":\"{}\",\"seed\":{},\"ticks_run\":{},\"raids_ordered\":{},\"raids_ended\":{},\"all_ended\":{},\"launched\":{},\"kills\":{},\"hits\":{},\"crashes\":{},\"sams_lost\":{},\"fired\":{},\"retargets_max\":{},\"air_bytes\":{},\"switches_max\":{},\"intents\":\"{}\",\"failures\":\"{}\"}}",
esc(&r.name),
r.seed,
r.ticks_run,
r.raids_ordered,
r.raids_ended,
r.all_ended,
r.launched,
r.kills,
r.hits,
r.crashes,
r.sams_lost,
r.fired,
r.retargets_max,
r.air_bytes,
r.switches_max,
esc(&r.intents),
esc(&r.failures),
)
}
pub fn main() {
let scenarios: Vec<fn() -> Scenario> = vec![big_smart, logistics, ew_adaptive];
let seeds = [1u64, 7, 42];
let mut rows = Vec::new();
for make in &scenarios {
for &seed in &seeds {
let mut sc = make();
sc.seed = seed;
rows.push(run(&sc));
}
}
println!("[{}]", rows.join(",\n"));
}
+38 -1
View File
@@ -5,6 +5,8 @@
//! Native timings say nothing about the WASM build or the GPU; use them to compare runs of the
//! same machine.
#![allow(dead_code)]
#[path = "../../src/world_view.rs"]
mod world_view;
use airdef::sim::{Aim, Approach, DroneKind, Ground, Out, RaidOrder, Sam, SamKind, Sim};
use glam::DVec3;
use std::collections::HashMap;
@@ -126,6 +128,25 @@ pub struct Report {
pub raids_ordered: usize,
pub raids_ended: usize,
pub all_ended: bool,
/// Systems the defence lost (destroyed units at the end).
pub sams_lost: u32,
/// The most retarget route jobs waiting at once (#127).
pub retargets_max: usize,
/// The largest air section a save would have taken, in bytes (#127).
pub air_bytes: usize,
/// The aims every drone ended with, by intent: "plan:1,sead:2,react:3,replace:0".
pub intents: String,
/// The most aim switches one drone went through.
pub switches_max: u16,
}
/// The last intent every smart drone of the run was seen carrying, as `name:count`.
fn intent_counts(seen: &HashMap<u32, &'static str>) -> String {
let mut counts = std::collections::BTreeMap::new();
for name in seen.values() {
*counts.entry(*name).or_insert(0usize) += 1;
}
["plan", "sead", "react", "replace"].iter().map(|k| format!("{k}:{}", counts.get(*k).copied().unwrap_or(0))).collect::<Vec<_>>().join(",")
}
fn finite(v: DVec3) -> bool {
@@ -160,6 +181,8 @@ pub fn run(sc: &Scenario) -> Report {
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();
// drone id -> the last structured intent it carried (#127).
let mut intents_seen: HashMap<u32, &'static str> = 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.
@@ -192,6 +215,18 @@ pub fn run(sc: &Scenario) -> Report {
pending = wanted.into_iter().map(|(x, z)| (x, z, sc.terrain.height(x, z))).collect();
}
r.ticks_run = now;
r.retargets_max = r.retargets_max.max(sim.retargets_len());
r.switches_max = sim.drones.iter().chain(sim.queue.iter().map(|(_, d)| d)).map(|d| d.aim_switches()).max().unwrap_or(0).max(r.switches_max);
for d in sim.drones.iter().chain(sim.queue.iter().map(|(_, d)| d)) {
if d.alive() && d.smart() {
intents_seen.insert(d.id, d.intent().name());
}
}
// The air section a save would take, sampled when the sky is fullest (writing it every tick
// would distort the timings the bench measures).
if sim.drones.len() > r.air_bytes {
r.air_bytes = sim.air_text().map_or(0, |t| t.len());
}
// 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()
@@ -225,15 +260,17 @@ pub fn run(sc: &Scenario) -> Report {
}
}
r.launched = sim.launched;
r.sams_lost = sim.sams.iter().filter(|s| !s.alive()).count() as u32;
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.world = world_view::text(&ground.world);
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.intents = intent_counts(&intents_seen);
r.tick_total = times.iter().sum();
times.sort();
if !times.is_empty() {
+1 -1
View File
@@ -97,7 +97,7 @@ fn parse_layout(path: &str) -> Vec<Unit> {
units
}
fn main() {
pub fn main() {
let args: Vec<String> = std::env::args().skip(1).collect();
let mut name = "big-smart".to_string();
let mut i = 0;
+592
View File
@@ -0,0 +1,592 @@
61d8c0b90973a3f1398d4db914b1fc9c39ff5ac4316085d7cc05d070ea62d15f assets/airdef/blockstates/amraam_missile.json
7f8fe0d11f6c8929e48c136b2f34d1c653f060511957a32fe4988377fc61d62c assets/airdef/blockstates/barge.json
dc5d543e28c50474df938163495a70fb81becd0814dc59d516493adb7c087110 assets/airdef/blockstates/beam.json
b2cc12fe02e4ccba502f47085046defe6a51e22be3fd739c4678677ed977c312 assets/airdef/blockstates/buk_chassis.json
8e2fe3bce22d718a9384a3805034691ee0ea068aad81d10aededa20da20afb9a assets/airdef/blockstates/buk_chassis_burnt.json
035b3898bfee5c0dfeed946e64e9365ad111c6e017ce0222e6455ee860f8d8cf assets/airdef/blockstates/buk_rails.json
b8ff32da42179af8d3762b5bddd3f33df7172fbef5352fbf51ddd1a8d5899c21 assets/airdef/blockstates/buk_rails_burnt.json
a4b1563f2c4578014b48778177d1e7032cc3f23afa99a715d4c9b08a67397b9e assets/airdef/blockstates/buk_turret.json
413edabb0c8db5b5f39f10f91ace49ee658036a00ba53db7d4ffc20615f70814 assets/airdef/blockstates/buk_turret_burnt.json
3b3145ddb3dad08986aeebacee5a389aea74e6ae7f2c778da52201fd8f24f2f4 assets/airdef/blockstates/debris.json
254aaebdf2c9c63d0c3bd95093368ebd6466cbb768d31ede32f07fc4fef5e808 assets/airdef/blockstates/depot.json
4062e069929859ea7fb18487b42953ac43cb9bd6e90d349e3ae49afbd29426c6 assets/airdef/blockstates/depot_burnt.json
d02848bd8df8af516fd12c3412636457e4f62577e221082a8627f041b714609c assets/airdef/blockstates/ew_truck.json
6921ae900410d3415aa5357d008c9ef122891082f1f71d11dfda01b145e2127e assets/airdef/blockstates/ew_truck_burnt.json
3cd4de622d0c8e43caf42f22547df388dbb78ff55ac868d9cfad37a23d37800f assets/airdef/blockstates/fireball.json
7355433bd94843c5c0d7848f1a5afb810ef08221b3f0389c0061e50970b5d92f assets/airdef/blockstates/flame.json
840655b48624534badc6367d88cc1472d748c989ff8c7082ecacaf79f54cc2e5 assets/airdef/blockstates/flare.json
0654962121ca92b60cf95beced4b062fb377cb2776ad1ff08f44d92624d59a08 assets/airdef/blockstates/flash.json
2453542113245c015b7c54971fd57184b80beb970eaefb420e7adab3618da005 assets/airdef/blockstates/gepard_dish.json
0a3fe2f20da19c69744f304cf769e3ce3ef236a6d251afee380477e2b5276292 assets/airdef/blockstates/gepard_guns.json
4645e4959fa2b126dc913e710dd15babbb30c139f8450d86cdb3676ec590ea0f assets/airdef/blockstates/gepard_guns_burnt.json
477ce5eb4b76da642c6b758098715c20d0fbb7c114177fceb705f3bbe97b5c59 assets/airdef/blockstates/gepard_hull.json
7b18a4ba743d64e554529efa25c881ab3ea7a500aa3390fca4a98c5691724380 assets/airdef/blockstates/gepard_hull_burnt.json
ca3e0e913af91bfffc6d9910a557b3acb1e01cfa497e3452ad37e935be491697 assets/airdef/blockstates/gepard_turret.json
80c3bfd8b7fc2252110ccd54b3ae8118ddf3100d7b983ce326aa6b1fcc6e6d97 assets/airdef/blockstates/gepard_turret_burnt.json
41108d18eda14c14e6259e3c68d3894d86aee8ac10cccec33fe271e0345e9202 assets/airdef/blockstates/geran3.json
4f0737d7739bee31106845b4062dc65336ae49bde0f310a3bbccc74c17f31ad5 assets/airdef/blockstates/geran3_flame.json
b6fe8c5937cf30957d0ad01f7313146760beb3958d8f25a8586021b5a8ed3c8f assets/airdef/blockstates/gerbera.json
2c270b14b4130c4831eda0ea9acc378e4f720e42f4adab5babea25662d7500ef assets/airdef/blockstates/irist_chassis.json
22f2e998245f414f789ca3929d43d73d66b03bf95334ad41c2c5ce768e6b23b4 assets/airdef/blockstates/irist_chassis_burnt.json
16a21bd9b4051a1087b64e9c606541d098ee3074e492aedb6142e6f16eac4c58 assets/airdef/blockstates/irist_missile.json
e6e1cb2e1aa92837a187016cc1d6238f962fb1a256c168395aeb15fc2dbb8efc assets/airdef/blockstates/irist_tubes.json
204d6cb12a261672f190d8b7958837fe9eb5efd960b891accb68fc61b46a110b assets/airdef/blockstates/irist_tubes_burnt.json
1d1fdd506878e5ad8fdbb64bb1608179c4dc247f7369b8e0ffd85835d05a8685 assets/airdef/blockstates/iskander.json
c62e1d8ffaeaf14e3b57ecf1e161cec6bcb13a9aee36dca3e88442584f1dd155 assets/airdef/blockstates/kalibr.json
c09ae784b9bc87e969a845975294f0d4880b9a90692f57c79e2de04c5a650146 assets/airdef/blockstates/kh101.json
0d30bb49f1227ac4c78a9f05babfcf6856b17d8ba059e00669a4d27a558ff519 assets/airdef/blockstates/kh22.json
f37a2c415049fe1579bc71cb8caa14b05c6e96c17e6a2f9760bc83a97b93c4a4 assets/airdef/blockstates/kinzhal.json
88b47dffffe1d95cf2c5981ef67837e597f6be06d417177d4967451bb55b3b8c assets/airdef/blockstates/lancet.json
83f736f00a673c90c0c1dcf726dd8a7350ab1d1efa37dcd85eacd8dfe94383f8 assets/airdef/blockstates/launch_ramp.json
de0bc51183c7a8379dddab26952f063a4a4a4b51b8dd862bc061989ec89681d7 assets/airdef/blockstates/launcher_truck.json
5352e83f412ea524aba1519367f0f9a921958a5d4caefe17d509a5b7e04a1cbe assets/airdef/blockstates/m48n6.json
64bc9d9193ca5f20a2bbb189bf6216211c167e051cc63c297a72655d711cfe67 assets/airdef/blockstates/m57e6.json
dc55ec1579702d9d48c01e5268dfae7097d0ece87d85b1a469222134f962f4b1 assets/airdef/blockstates/m77n6.json
2331d3c3c614e38d39d67d8d85c4b16030ed7ecab37bfaa9da938379534f57cd assets/airdef/blockstates/nasams_launcher.json
f05bb84135b39bc469fadbc4f144e0f69d203b1887396a0b20adac59e549c1ed assets/airdef/blockstates/nasams_launcher_burnt.json
9fa63fdb0fe84521f00326dad6955af6adb3dea1093f42404e6e07770cd9bcf5 assets/airdef/blockstates/nasams_trailer.json
640b83fc5b43f6fce1d13106016e9b14c0150603035a6d9b19ad6f0598511959 assets/airdef/blockstates/nasams_trailer_burnt.json
446bd55fb9bacd7828c6a7028595de64e26cc5cbe3ef4280713c3d9f1cdf850e assets/airdef/blockstates/p1sun.json
9e2e00e75afb10c38684b1994688ea11bcc2faace46ff551967e1e05ae08ec85 assets/airdef/blockstates/p1sun_launcher.json
02f9474f5f459e33096931887b71b515d957b7a1be14ccb81a0bba36af551ec9 assets/airdef/blockstates/p1sun_launcher_burnt.json
da5130347d961fe0ca0df11d31b250dc1fa268cacfeed184662fe22901b6ebd7 assets/airdef/blockstates/pac3.json
f5674075063a8dbd897394de194b980a426e08faf7803ec10b8117070a579a78 assets/airdef/blockstates/pantsir_dish.json
365f6ca767ad9dd9cc724ea859f41ea6879f0d0ba88d6aaaab2ae7d5fe34acd8 assets/airdef/blockstates/pantsir_pack.json
53af2cf24abb2df609f02d41e711ba49e38be4b6a9a0a6e1d8cf395dde3b58a5 assets/airdef/blockstates/pantsir_pack_burnt.json
6a93f7b1eee7b8ff02567c38c05196f8326d66b319cc5d69c942902986bed946 assets/airdef/blockstates/pantsir_truck.json
81804b614abfd0776e1513c9f759d1cc22952346cbbc980b006fd367b68792a2 assets/airdef/blockstates/pantsir_truck_burnt.json
c274aaf1c5e81683c540c784bf0eb7de15ac8522a5e4d7397cd7b181367c7e83 assets/airdef/blockstates/pantsir_turret.json
05c3dd4f66c8cd7332654e19aeb60115f00e246c8f57f4eef2c300f1ddb97a2a assets/airdef/blockstates/pantsir_turret_burnt.json
c96640ff19099af66c2da0a9a7561b847d6355ab2de8bbfbe03f2daf38b89ff3 assets/airdef/blockstates/patriot_launcher.json
c3b0b6f1d9b7da434c95f2794b97b9e2c05c62ccbce9f0884df071e4ec28a468 assets/airdef/blockstates/patriot_launcher_burnt.json
83058657f466b769c9140f5d6c4a5079f9567f9cb13ece7a453da191aee5b89d assets/airdef/blockstates/patriot_radar.json
3ecae997dc4fe1939848fc60347979c02075396a164b31dec3995a2e907a8447 assets/airdef/blockstates/patriot_trailer.json
31fecc6476129990a7d368f6d7cdb954b13e777b28d1396a68168770024112ce assets/airdef/blockstates/patriot_trailer_burnt.json
183d0b2ae9c24c94c3d83f2819e1167b5e2d134cc7889e0e3bda12aa784c7baa assets/airdef/blockstates/patriot_truck.json
421b5be0a4c80e892850f4a77d5ebb386e04153201be63241c7edc11659d03de assets/airdef/blockstates/radar_mast.json
fcc6bbe526baf5551923e2a69cdf09f506cdfd96669e1fffbea643401dd2a1de assets/airdef/blockstates/radar_mast_burnt.json
37714e19e555cc50a9f195e1a8845a28c9985c27ed38b577c0813f4629b66fcb assets/airdef/blockstates/radar_panel.json
95fe14b9d3e30597f5505aa93f31c3357cebea6117596bd9f5a5bc840ab22415 assets/airdef/blockstates/radar_trailer.json
a95a1b8731d6bedda7d8b352ff3c448ea8be691b0ead01f14acab39234590c45 assets/airdef/blockstates/radar_truck.json
332e6f39c40063ca690064e13a1a256ef215fc2bb96985b842d9dda58abee2eb assets/airdef/blockstates/radar_truck_burnt.json
67b93302bea867248b6fa0109a4b5af2065e5c857d4a5c7e088bc9849fe624de assets/airdef/blockstates/reentry.json
ac9ff6b121adfc64ff60110a4e49bd5ec8e6b5ad57d45ee348b4ef1af7361264 assets/airdef/blockstates/rm48u.json
7f3e952f5de83880549012945827f8469883355b0a3dd966e7f03c44aee532ab assets/airdef/blockstates/s400_chassis.json
411d0a0ac102b21016bf48d30482e073a7e8054c2775d8fd5a7c91364a2cb1f7 assets/airdef/blockstates/s400_chassis_burnt.json
3ffc2edef1362f318d6c087a20cd730feda6f35f7381942cfc8012f06f4dc174 assets/airdef/blockstates/s400_tubes.json
e570e68b27a7554e3aa8b63b30108a2f4e2c3bec6e91cd3cff7509e3d7eb3400 assets/airdef/blockstates/s400_tubes_burnt.json
eb8061c3cb198600ad8f587738e8a676d9ef114ed171764bc905f4730eb3a0ba assets/airdef/blockstates/s500_chassis.json
f0cf8bafdf7053ae757e5b0baee92accb984a24bfbc18d65e1e824384e09180c assets/airdef/blockstates/s500_chassis_burnt.json
2b7bd3099ec300184a185e2beb48dd748004af869696f4a26793032bf9675439 assets/airdef/blockstates/s500_tubes.json
3d6fc384684a24218888e871ba0efc72d15ce29de84cf45e3adffc5f7f98a45c assets/airdef/blockstates/s500_tubes_burnt.json
3af7b3f01780265cbff35e20aa149691bceb8de10a6991129b32046c753c6f8b assets/airdef/blockstates/searchlight.json
8e530da837dba9ec426651efa136c3389c4f9f9e8baf453b9055b4d260b5900f assets/airdef/blockstates/searchlight_burnt.json
48b14bddcb967c4a4933a827568c0b66d9e6c9e2d3a62c63b6ca55ddab8764dd assets/airdef/blockstates/searchlight_head.json
bc57f94b431786c60a6b204ea54126c9d2b363427673c39a45ce0a53336ee7c8 assets/airdef/blockstates/searchlight_head_burnt.json
9c25df8f750763b5e3011557a6aa59289e9a41efa1811c18c30522747473dde6 assets/airdef/blockstates/shahed.json
ab6d7a96cda417cf70fa31aca6f6c7bcdaaf4f8d413b079386f97ecef6d33709 assets/airdef/blockstates/shahed_prop.json
137dc0f2bc5723534dc2e4f44f1706d589c0dd85318d17c207f2f6772d98d989 assets/airdef/blockstates/target.json
e766e18158d00f0480f6dfe32dfe142890b8d452bc493b7474fda0984cc2dd4c assets/airdef/blockstates/tor_chassis.json
ff125150e206ada5a7fb47394e809039d338c22a843207a32352e9ee59e278a3 assets/airdef/blockstates/tor_chassis_burnt.json
04a5fb931f419086995791c1defd9486b36b3c725581bf5a10191a2c71c69984 assets/airdef/blockstates/tor_turret.json
fdcbe36a0f4968005e8c6588f2fa5d8196c55da3183cf89760ea221a5c4cb431 assets/airdef/blockstates/tor_turret_burnt.json
923340f2233c363a880fffeb40dba04038f26ff42b072f28418e0a6ab757aac5 assets/airdef/blockstates/tpk_cap.json
f3e430750f5cb60f44c2a97687d7cc1ac58232b27274a82758c23861d704662a assets/airdef/blockstates/tpk_cap_burnt.json
cf7c26abeb1d8f7d84106bd83b84bf541a3d11369b7745a77802b7e51dcdf447 assets/airdef/blockstates/tracer.json
8b547ccbc890fa53b613cdb2cf55ceaa5833348479b0863651c6df01a9f778b3 assets/airdef/blockstates/tzm_truck.json
11fca31a88e658c819954fbb86b53d7709b66b971af8747a5edda24be34e5dbb assets/airdef/blockstates/tzm_truck_burnt.json
4a74928eae32adeaf6e0e5d964ccbda97be0a2208961772848f109c59a9c6c1f assets/airdef/blockstates/zircon.json
48aeeb65e6be762ef975540826b2b3303a2df5378c3181e5e99826206df370e4 assets/airdef/items/cam_geran3.json
e6d0a3b45670cda451ebe4689323b269de22afb7d99b341510a711a22db75c85 assets/airdef/items/cam_gerbera.json
e22e53fbfadaa018ec8091213406b57eee49b39341e029daf96d7915f500e50a assets/airdef/items/cam_iskander.json
a3174ebb0b1720b803316c3bdce3abf09146d2c1a2b78bb6c091aa4a363716ec assets/airdef/items/cam_kalibr.json
f357a1510ead55131a7f93bfe43d46c3e0c229deb25cfe82bfecfa84caba543e assets/airdef/items/cam_kh101.json
65625082b0ca6b0835b9a7bb04657b83b76103a25f263d85254835e0d29f6725 assets/airdef/items/cam_kh22.json
16fe2fa4cfa528878261fde9c3a9923989608ffc2ebbdc770cdda2b9098b0287 assets/airdef/items/cam_kinzhal.json
f4d13fcb599d8fed03ab4fa5a95900df6a0c766d29b3095d32fe9dc2f06d3554 assets/airdef/items/cam_lancet.json
ed5405e2cd20da02053d8b614a630ef5c32f476c08dabccbbeaaf0b261823956 assets/airdef/items/cam_reentry.json
7654d42382b9f072ea8a0f348c30e78c147921f5bf95723fe08bfe23b1b28c1a assets/airdef/items/cam_shahed.json
adb65d10541f62f8e0a4c0b9da63a9e7bf4581f44672d2542d11bb16f89e75fc assets/airdef/items/cam_zircon.json
0c5fd99e7447602834eae3296026031fc7419ba6126b507132503925b01af1e4 assets/airdef/items/deploy_buk.json
b5c9bbceb576dcf3e4ddc3d01f6e3743d67f087ab98a24966c506585aaa67b2b assets/airdef/items/deploy_depot.json
b50fe5804cbbe10df992ebbc7e095a32ce8b73fc35159fa19889640681e408e9 assets/airdef/items/deploy_ew.json
728e5e8bfb4c351f11db6be872834e4a07a9b04fb6be63d9bb1ad42495bb57d3 assets/airdef/items/deploy_gepard.json
0c9c5ee3fc87e2dc6d716bdb0bb5f30d3b265268bfd5083462b4861a8da65f0f assets/airdef/items/deploy_irist.json
09e46a6c4b59f66c24060ac627e6a287bf6797c7b1e32a9ec6c9d9662fdc3de3 assets/airdef/items/deploy_light.json
6983561b3558aee16662aa83d2d9af760fb6236cc7dbe79ba20802f8a2ff15b9 assets/airdef/items/deploy_nasams.json
d8ac6a9258e2fc2e0791bbce18a3a07a72e471fbc72b6be7b5ca545c53f8d633 assets/airdef/items/deploy_p1sun.json
e2353c70f6e5053864ab2fdf51df886d72c03e5c34db84fef8f3fff9c84a7ae4 assets/airdef/items/deploy_pantsir.json
68dd9b1382b2dd6ad23d0f507a8cfcdcfa18ef5c4203e69c61f6ade9cfbf238e assets/airdef/items/deploy_patriot.json
d93b6bf77de4aed1f1955e76353661729f06445788ad7a6654ed6af1a67fc48d assets/airdef/items/deploy_radar.json
0b9445f3b54a9e958da0b9bd4243a41d85fc8f12b5c4e56bbc070edb8f1bf618 assets/airdef/items/deploy_s400.json
dd7478f447d87dcad42e1a7e6dcb5fae555c832e933a3722022d0e10e2de011e assets/airdef/items/deploy_s500.json
14e9a20dcddee5a6262ef624783900576dac2bd16e5079e731cf6115f13c76ec assets/airdef/items/deploy_tor.json
d4ff57f630ca92bf52ba228d8c6fd5292928b685d6bb5a9c9b9dc0c3d586fc2e assets/airdef/items/deploy_tzm.json
044fc626ad99ff8be6db0800f96dc743fc80606d813bd59abad531396bf9d8ce assets/airdef/items/designator.json
5a07f4adb780e52b920d1c8ca5296e43e84f44897b0f6afe258a8c2c7712f83c assets/airdef/items/flare_gun.json
25fc0a8ac7b5e01c6de19c86584e5bfc2dd9cbfa8e7ffb0468db82cb89f5585a assets/airdef/items/launch_geran3.json
5dd3ca665c44c43bef0c4c25361b9a4d45d0b2a7b01d2c8e66cefbf62ee38180 assets/airdef/items/launch_iskander.json
106695745868cf5ed80534ca35d81944a9fc40a74d30d4d4fdf43d716dc5b28b assets/airdef/items/launch_kalibr.json
5c45ad03265b1331ee73b8085cfc33a8538339c9fd1c9916c3f5471bb2ed0bfb assets/airdef/items/launch_kh101.json
ed9356cb86466025eab00d4283a72adfd1cf6aa9549f051c5e6088c72078263c assets/airdef/items/launch_kh22.json
8af907c3597963f6332c2cd677d5236e41dc9584d816fdbbd820ddb99217fdf1 assets/airdef/items/launch_kinzhal.json
54045e7d6cb53e92700accb04f6caf68e229d71cba6038669c425e9c109b904d assets/airdef/items/launch_lancet.json
4a007ad0f768a53c605236476667178e981e47980baf04a973fefde2bd4b20c3 assets/airdef/items/launch_oreshnik.json
b4d98a938486d49db28c6c7a608ca3b6ab0c9c3eac266ecf12c7dd931cc28f93 assets/airdef/items/launch_shahed.json
489799dcb5b441e9d4be8bfb3d73a6ebd5fdf2b5ee614b62f38b85bb2fbfad75 assets/airdef/items/launch_zircon.json
6b6da5887aa8d9bc987b2c181c243bc2afdd5846a869818f699b59204e559929 assets/airdef/items/mover.json
177f7535e4c52ed975d6f737c2b2acb7741b7a928955c8899aced85211443bbf assets/airdef/items/remover.json
cede33ba58f61891a8afe42e1f4311cb293ca93f4d7eb3a57636caff17317a4d assets/airdef/lang/en_us.json
cede33ba58f61891a8afe42e1f4311cb293ca93f4d7eb3a57636caff17317a4d assets/airdef/lang/ru_ru.json
b9b5b5bec33a77e944552c225ee2f526ab9820fa8fca4b3ccf311f2a325925ee assets/airdef/models/block/amraam_missile.json
c54e6b24ab69e9d9a2dbbbc63fe2ac60fa37735bf644500ddd5c3de0b91908cf assets/airdef/models/block/barge.json
a4198ff647de5866919f9b82a3d53e6486fc56cc9f175f7907951d063a6f4526 assets/airdef/models/block/beam.json
87c5b37677b74fc0eb83db9d946f63a4b05651734e5a6c00f49c2bd30acaade2 assets/airdef/models/block/buk_chassis.json
e06845ed1a8c3b6bc737ae0415c8170c24fbbf30ee6c03d92e69558047647018 assets/airdef/models/block/buk_chassis_burnt.json
e51314abb51660f2e06d896084802ae913c3a233a05f5531b9d2fb83f1066f7c assets/airdef/models/block/buk_rails.json
b305b7fe737f9a303bd60dacff4e71468835e63b09fc6af5e63ecb248e390572 assets/airdef/models/block/buk_rails_burnt.json
3a0f03c100dd8811349798e3baa5cdab53be12381dd1faabbe5375cfdb1fe332 assets/airdef/models/block/buk_turret.json
d64884c030716bc212bbfa04b2308714f8f0a116a14e0249847859a0cc96fa3d assets/airdef/models/block/buk_turret_burnt.json
684edfac71d15f328b92aee2f2cc508532f6654d5a664ac78c13b6868c3307ba assets/airdef/models/block/debris.json
de1e494d4b9543ffb72f6b351830d2821ba3e344baaf0f7d365f771fa9d5ba24 assets/airdef/models/block/depot.json
b0f94e748ecc44fffa6711b1affa8e2a4ccf95e6fb101c8577e0f118f31133c2 assets/airdef/models/block/depot_burnt.json
6e99fc5296a9251bbe04379da7122faee34df156d77f4888daa27b9f9d54c6e4 assets/airdef/models/block/ew_truck.json
4e270f0092d3c10acaaec5f3824f43c0e16c1191b837187af10aa3b0b5791a9f assets/airdef/models/block/ew_truck_burnt.json
c00df220e46a265c5a33e68df1cf407dc1fd25bb70978b6b8d850d7826044f3c assets/airdef/models/block/fireball.json
fd5ca8c85d054580e6f95cb88bfed6216c9b41ddab9efec2eb4a642ad408c17c assets/airdef/models/block/flame.json
3962ad6a9bfd88ed4638dd72d27ddbd0933583e7f0d40b808ddabfd6e3a35399 assets/airdef/models/block/flare.json
6bf4a388b9a38a5359053be38cf09f1c86d0ea47d61e5de0016b2b1c7f7dbb4a assets/airdef/models/block/flash.json
9fa54aaabfc0dd1b6af4fdd1fd4ac9a4248c4837801a7d74e441627f565a18fa assets/airdef/models/block/gepard_dish.json
c8146e2999b4b94633abd1fbafdb39fca8896e9df92aa37c78544ee594337218 assets/airdef/models/block/gepard_guns.json
e8a9c326e2630d7484e1a11ce8a30d2a0005dc4c847c62b5e425904d6ac4fcf1 assets/airdef/models/block/gepard_guns_burnt.json
48a3496b78b37dda0a6eff1ed610458824949dd11c56626dffaf6158f8c1c7ae assets/airdef/models/block/gepard_hull.json
eec91700830aaea1c7d80a4af3ca44b99756bba18ca634e0107004f4ed59ae06 assets/airdef/models/block/gepard_hull_burnt.json
e666f027e7cd54c6c9596d896931db7c51a5b74564e7038f9bceb6824c6c29dc assets/airdef/models/block/gepard_turret.json
da2509d47a048c59c81430a83fa71ac0a0d312a2ec617ed1d3175b5ceb75ccd1 assets/airdef/models/block/gepard_turret_burnt.json
d43f9cda780b1821a6e778555a1be5bd112a1d9655ff96d35acebec61cf11e0b assets/airdef/models/block/geran3.json
83cf0a42e59f6aee1039925f849398960334f2545558409e7ccd7173ac841d73 assets/airdef/models/block/geran3_flame.json
ac93e872743844465f0688162dddd7433352e8710612dd391a1e92b7f36e6b0d assets/airdef/models/block/gerbera.json
3ed12c12f9c1490ef08585cd4a55632cd94528e9bbde1e993310f1e9ca57c534 assets/airdef/models/block/irist_chassis.json
122e7dbb3cba0b8e249c8a06251d3ef83dcbe1880d540b0d4c2430910314f34d assets/airdef/models/block/irist_chassis_burnt.json
db7b914b2d027b8ebde485b940951244e4bc4cb614eb2eefc49ccf0b26c98bdd assets/airdef/models/block/irist_missile.json
e6cb3f578b875d3683d2a027f1ac34226b56c4db410fecc6479e2683485b8c3e assets/airdef/models/block/irist_tubes.json
449284669a58d71ae2de7e68cd7cf18ae21fec70ceb3124cd24fb4a09fc49909 assets/airdef/models/block/irist_tubes_burnt.json
be87037b84cd45b2c53d7fde6653f51769e782eea1b8586383afcfababf19ab6 assets/airdef/models/block/iskander.json
98d488ca797fb3d0193957b8a93a82f48376a89f8e091032e6365d1845016a90 assets/airdef/models/block/kalibr.json
20deb68dbba6eb64b7c51685497110ef7d1d3bf0aa7e7167c558e0a8e842e759 assets/airdef/models/block/kh101.json
ea7c9af888f1285502b2ca51114f226573311be6fb90b8d449b9f75cfbb6b885 assets/airdef/models/block/kh22.json
7b73015e33d85d4cef31660ef874ba8dcd6e07ae3a95416d0ead1d325bd0cb6c assets/airdef/models/block/kinzhal.json
69135e90a1a7fb21d9f47b1854c5a3648e296136c2375acd9db5a48b0ad40887 assets/airdef/models/block/lancet.json
15c9884ce51311cf4b9b9d106e142e33d72c5ba18dc9236c5b51da01232f8e44 assets/airdef/models/block/launch_ramp.json
159fa5e3b6a096a1872dec2a550bfa30575d57519654a860607e20dab8f35f53 assets/airdef/models/block/launcher_truck.json
2069198ba24a932816f504fb52f53dc4bc740cacaf45637698a17d9175da851c assets/airdef/models/block/m48n6.json
61968f4d63adb6dfebd5770ce5225f4cf5610a7d7ef863c4665875e82abb4f25 assets/airdef/models/block/m57e6.json
238ed59a5dfa261272c0a4dabbda3ee62d2c1c7b9829cced644bf8b2322d4bfc assets/airdef/models/block/m77n6.json
266565d9ed8dc836c46028c8b8bdc83c9725db587552bf8848cd9059f3917ed4 assets/airdef/models/block/nasams_launcher.json
94c8beaf3226c86d5ad018a31846286b451eaa96073e07be4465c9de3583ef61 assets/airdef/models/block/nasams_launcher_burnt.json
99d3a530ca47536443db0e2c8a8f9236d68f67b6c78a5313c44dd80fb6edbde0 assets/airdef/models/block/nasams_trailer.json
ab0d875ad069ccd241f3c75fd32ecbe3507cfe740aa072a3a75955c489629ec6 assets/airdef/models/block/nasams_trailer_burnt.json
ce9f0dc61bd07cfcb3be5cadf12df0d2ef1b3167aa2260bc4b42414dc3825b58 assets/airdef/models/block/p1sun.json
b5346ab109ffb8c259592574b091a47bd396de34b0fe96e684b672316cee6b86 assets/airdef/models/block/p1sun_launcher.json
4457a527977ad5c7d381991ca1c9d304cac0b7074f632a04328e836bfd83f784 assets/airdef/models/block/p1sun_launcher_burnt.json
2e11e64942baaf057ccc60f42dc629f7519eb3892198c1906c22fcfa95584e7b assets/airdef/models/block/pac3.json
ba90d89595c3c5d6d5a30f1041540f50504676bc64df5cf34038f8682307bd3e assets/airdef/models/block/pantsir_dish.json
9a461291c90e18c50f3a82afe7f17bc8a0a299b9f2b925c244580087fc3b5fa5 assets/airdef/models/block/pantsir_pack.json
79af2971ac88a93bbc42c0e193f61e585f6ae5330153f4b40b7720c5ce8e4cd0 assets/airdef/models/block/pantsir_pack_burnt.json
ef73f453ea0abcd97121c845207efcf2438d47991d49bac1cae66acc9a416419 assets/airdef/models/block/pantsir_truck.json
1d3a00601801268636165e8fea79f9c9d141e1434f0268e2f65ef67ecddd4447 assets/airdef/models/block/pantsir_truck_burnt.json
d01efdcfafa92243e745aea7870269c07a0224c9010010e2dbed720ced1662c5 assets/airdef/models/block/pantsir_turret.json
0036037578cf2df9f565acd8ac3553af9038ebafb5b9a4e6d8fd0d225b39149c assets/airdef/models/block/pantsir_turret_burnt.json
33884253bc3ab463d15a7fe952187b1f9fb3b78632e825e1fabc85ca5335b543 assets/airdef/models/block/patriot_launcher.json
3fed073655020b72dd515dca7eb362f642af50251b473012429a5ca946426f8d assets/airdef/models/block/patriot_launcher_burnt.json
2a8ca10c933e236270810ce9de40c83dfd8016b0f0d32413433e3a5f8622329f assets/airdef/models/block/patriot_radar.json
548bc63e46d96e5110598e39269851c48f750164981a433f75971b0229c268df assets/airdef/models/block/patriot_trailer.json
190726b64bef4baadb0bc2a00147069685ef148100c8935402e09c3bef66e65b assets/airdef/models/block/patriot_trailer_burnt.json
6f027b020e4066f673c376e289cc627846a084e5733d62744fe78ab23013fb08 assets/airdef/models/block/patriot_truck.json
8070d24b511ac733d73f5961762e6f5995379814f33f54c56c1a45d1dd7ff28a assets/airdef/models/block/radar_mast.json
7343f6085138f974d581706cc135e582040a46069c215e95ba14ad31dc1a8d63 assets/airdef/models/block/radar_mast_burnt.json
e5733ece9b976998c9c6a6c968b17cada868b62d9e2a7bc67e1272e333e35399 assets/airdef/models/block/radar_panel.json
b0ae344fbad3b982e7821cd1b26f9922e2a5713b38107521ddc5a5b2abd9e39c assets/airdef/models/block/radar_trailer.json
5545094620c27fae6b3d97a71f3d68ee8e0b49804a1dcd61b79ca847277e3b61 assets/airdef/models/block/radar_truck.json
5c756abfb412b31076cd84d8735ad4e41ca26c8d5896e3795aaddb976aefbd1c assets/airdef/models/block/radar_truck_burnt.json
f102765390762d45954b26405b6acdde845df7f0a319bac53d25508e768957b5 assets/airdef/models/block/reentry.json
971c11e58eafa17ad798f6d27d91a9ee0531f33692eb657d31f2d83e8cee7e39 assets/airdef/models/block/rm48u.json
a6bb637011c176edae474ae7b5d6e3b5af0d2a448845e3f95b026f789e21560f assets/airdef/models/block/s400_chassis.json
192076b361a57ee26a1dd449717f30f50b612ee6c88d4dc1fb9dc6aef3f3b829 assets/airdef/models/block/s400_chassis_burnt.json
44bf27184842d0e3c86bed035a7090add0a79f6b5bdea7a37e6ddaaae728d39a assets/airdef/models/block/s400_tubes.json
973e02b2058c0b3d59c156f2ac94fbba4ac90a97736e8a4cc9be177b5e0f19a9 assets/airdef/models/block/s400_tubes_burnt.json
088f42bb17f4d6099c16adf6cc0426b6d04ff9a43abdf125476a3571e924fcbd assets/airdef/models/block/s500_chassis.json
3e35ed19ea22c8309ac7c0ccc9c12e31b2387de97c6b72ba519bae34f681c58c assets/airdef/models/block/s500_chassis_burnt.json
8c6bc46647f3df32febd96fccdba894e4c986b717b006e3c3e5607a73f0f252f assets/airdef/models/block/s500_tubes.json
135d34c4059ea7aca794cce201ef27c3c17cdb21ea27205634cea95bc8d16515 assets/airdef/models/block/s500_tubes_burnt.json
3d61559d5bde298d6dc8987122c68edc3b02bd0d1afed1d9458bd7c3315fb0fe assets/airdef/models/block/searchlight.json
6391c155f45656f63ac579bd1ff0d3512c54830a03561b8dd04e5e63ed751cf4 assets/airdef/models/block/searchlight_burnt.json
357165a1a1ad382257e68768bf1b4158294e0e080eab9a9570ed6bd824e7f3aa assets/airdef/models/block/searchlight_head.json
1ca6eff892a0101bcd950323d2f9c68cc81d6c714086a44555ee49441797fbc3 assets/airdef/models/block/searchlight_head_burnt.json
60c44090d52fd08f230b3f37b58e888824e680b5411dd4c3c6220da6ff3d15d8 assets/airdef/models/block/shahed.json
d5b9ed76b1744d0c93a809b6a4c16bc3dfa7ff4784e3cb9968aa36b12fc30484 assets/airdef/models/block/shahed_prop.json
465e6aa2a8ac3c563b1e546fc844a0520fc89f3ce528d49f193aa6c21e19308f assets/airdef/models/block/target.json
8f4d29f5cff68b74880d2120a0f183a35018d36576330bb33de3789cf769683a assets/airdef/models/block/tor_chassis.json
cacaa7265489f1083f7de351515a7d08eac5d2b072cf58b32ee51840473ab44e assets/airdef/models/block/tor_chassis_burnt.json
d130179a7717f1bff9f045a3e0b93788eff17737c7c1c9c3b5b287d811eb6fad assets/airdef/models/block/tor_turret.json
a98d2a545b4bdea5cff1c5826d55dc8c3fd341ecebeb8b00ee2e1e1b0739b2cc assets/airdef/models/block/tor_turret_burnt.json
a6785198c98f5b2f20acc26ddeca3b5432e6b521b68541ea65ca2592c3cae4a1 assets/airdef/models/block/tpk_cap.json
0391ce9eeac9aa0cfcc05b31b0bd5594e10a5df2dc46c355b0b95a8ea8234ff5 assets/airdef/models/block/tpk_cap_burnt.json
b2380510f56dc60e914919cb6e20b82e3613a9d62b08a1c81740f960569c3425 assets/airdef/models/block/tracer.json
753c46e821b4fce9fd9240de2ec627a27688740a4c31c9eff24593034ffa33e7 assets/airdef/models/block/tzm_truck.json
fa29c0224a5a7ad2e3252cde099b17c6c8241ede7cf0e52766734672843a6432 assets/airdef/models/block/tzm_truck_burnt.json
b85d09a73a1c251bbc76945aa8f99b5e7e606ed41e1d120f811a435f441b1e96 assets/airdef/models/block/zircon.json
8360c341dbe0aac6c485bf0d2c9ace49378173f1749f5b52793a79b98697685b assets/airdef/models/item/cam_geran3.json
5b35d42715fa9c4afe8d0bccf5060380a8b5216edc9509ba0d859e8e953232d7 assets/airdef/models/item/cam_gerbera.json
f06af8a128e76975bdf3178e7db1453d01a888f06b2b5e9f997fbc43e0b1266a assets/airdef/models/item/cam_iskander.json
300ef4f62f89aff9b59567da8ea32749abec2966c77041846835953b2dca0d0e assets/airdef/models/item/cam_kalibr.json
8e7b91623d1d3e72dab4e701b506eb1de6c87ab774d3f6e6ed9ab76a4d82270b assets/airdef/models/item/cam_kh101.json
5ea688448ece076431da2d4539806211825c2a63b816d00416f946351b92f509 assets/airdef/models/item/cam_kh22.json
c6977e576991ba245796d82caa87a0ae87105bae7067ae2bf33d933779bfcaa5 assets/airdef/models/item/cam_kinzhal.json
56400ae5307d0f02273ebf919f12f7263e5fe410a3e1833b83a5f19d32ddb9d5 assets/airdef/models/item/cam_lancet.json
ee660fe4736f801646f944d54144f72a777048c269d828d1b71239c8732b0730 assets/airdef/models/item/cam_reentry.json
99637f9ce3aa4ba3517b682890bbf7e35835145df666a9f74f53302684ecd1ba assets/airdef/models/item/cam_shahed.json
182acfb9fb1d8f42741378a0bf17484c89a757118ffd7bd3bdd9bda2941906b9 assets/airdef/models/item/cam_zircon.json
c6cba2497f834e0a0e0dbc7604afeb1f1106e0c64e2a1b497a66e932db0ce073 assets/airdef/models/item/deploy_buk.json
43ad086ad7cff44263c30b2404bb6266834f36310ed044e661537bf665f12150 assets/airdef/models/item/deploy_depot.json
5047028c52687c2c789be9d339f97d520619e595ea7a33b589ea6ef45d41f067 assets/airdef/models/item/deploy_ew.json
a5d0450da8d6757b9b45f86e6b36977894dd9e3e1278c3668b99a8acab36f399 assets/airdef/models/item/deploy_gepard.json
e80ee81085241b9712e024bbef73ef744ef5493eebb88770f4912d8aae138fe6 assets/airdef/models/item/deploy_irist.json
637b9bfe426ee50045f8fcbfd4f25dfbc1d819ce36dedbd60abdac63c274f088 assets/airdef/models/item/deploy_light.json
3398844e90203f97ee73e35619684c775d1856c8ca3399b5ed682786170d9327 assets/airdef/models/item/deploy_nasams.json
76019c05d070cf1141cdf95b744b3d6198ab99469dba1f88a6903de1de303bde assets/airdef/models/item/deploy_p1sun.json
8b1af688bc83be5a8065673bca7054deee86ca425f0bfd1fb4ffb491844e90bf assets/airdef/models/item/deploy_pantsir.json
d0091d809816350c648e532a90ae59a3c5c9b94f837b2a46b5695e7f985a00f9 assets/airdef/models/item/deploy_patriot.json
332f9de8c88658a562748fc7a6de7ec37847273ac0cd0733e23c0dff4b44418c assets/airdef/models/item/deploy_radar.json
9ee1dfa7d2c2587c85a8f73554962a02a06f1969a9a56c56110162dd93db7301 assets/airdef/models/item/deploy_s400.json
55f1dae5cd7f0126533825c9da3ed3ee316e74d4be8f9bb217a3ebc6f827d24d assets/airdef/models/item/deploy_s500.json
aca5ea765ca0d84ed12444bf433c024b57d6ea9b9b7cf06449dfbd6892a66ae6 assets/airdef/models/item/deploy_tor.json
67912cc711c2f1514e6e2f8f17aa340fa9a99534fbbaeb2b8e319aa6ef80f38d assets/airdef/models/item/deploy_tzm.json
d0976d990130c6398f4adf5d3086e9cf50e5a2adbec081e4682e810af368c332 assets/airdef/models/item/designator.json
b20ec2241060123a208ef66e86183261a7514611206b1b4389d2ababf40b6ca8 assets/airdef/models/item/flare_gun.json
4fc1487d0ea8634bd164c01b54833d243933fd4dd8e40029d3c662f6c0afe9d8 assets/airdef/models/item/launch_geran3.json
a5685a17b3169165faa53b27357933388fcc46ce55ae73049360ca0deee58c64 assets/airdef/models/item/launch_iskander.json
ea86f852034e540430bd7c624fec49072eb775fee4263e48f22e722387393fd3 assets/airdef/models/item/launch_kalibr.json
8954e2d7de8f39b2702e5aec20b10f39cfc4911acb4f7bb438fee76948040487 assets/airdef/models/item/launch_kh101.json
6a27d903c35b802c6a755e4fb24af5bd38421b0dab9f6e39425cc7b5236a3d2b assets/airdef/models/item/launch_kh22.json
148e92840c1884c4915cb14316f6018fbc96ad4cd701f3871407753e5bc4ecd9 assets/airdef/models/item/launch_kinzhal.json
8a2a008a9b58913120acb044a72403679e57c1daa55e9e115676576e7f7ad217 assets/airdef/models/item/launch_lancet.json
dc99bbddf69f5666530f35bd5d92b0e01999afaa69e007f00f03c06bcad8065f assets/airdef/models/item/launch_oreshnik.json
f2fae6baddbb09d9c1889657a58bf9b31d012e357118108c3f8ff45120e31a2a assets/airdef/models/item/launch_shahed.json
45f5442bc6b47c15955f2c080c28db7cccd7485c9fa70fc4f3e9ed976b74ff95 assets/airdef/models/item/launch_zircon.json
0528d0a362eb44e43ef26771e2527ba14eb6f59bc7e71a6b7dd40a908e469b0c assets/airdef/models/item/mover.json
0be54b1273d2a3ab75fd4c643004a753643a423db0ad099b80f4bff66a6b9b4c assets/airdef/models/item/remover.json
b68f4a6564e4a76d66502c9f765d967d80b66f0f8672309dddee5b7928d2ebeb assets/airdef/textures/block/antenna.png
8123e74fd56c6fa211b7490373625756e8792b3d17bb050d0a8ed81689bb2ad3 assets/airdef/textures/block/bare_antenna.png
09a2dd50acbaa8bcd08c9063730898e9601c74661446279c3c2cc10a373a1f1c assets/airdef/textures/block/bare_antenna_b.png
048e8d01ddffd59665e07c1954a6e2d725089dd9ac84933ecf85f093d048751d assets/airdef/textures/block/bare_barrel.png
0decb34bef6baf602616899053ead3378dbe798282ab2f6c931f20c98aa67820 assets/airdef/textures/block/bare_barrel_b.png
dcf8d38a0275fd73c1c1592384962fbe0f0327103414fc8a00c41e8758af113f assets/airdef/textures/block/bare_dish.png
3b5cc50eaf6d3eaf6f6fcc7d7f28935980420fa2a5f8ad680a4790d09f58313f assets/airdef/textures/block/bare_lamp.png
fcb6a151da7c25d755c012629ad5f8b55e2de951ce745c2d7b3b2f0d191babb1 assets/airdef/textures/block/bare_lamp_b.png
de9acb4f73b59d80a4bcc6d0569dfb286d627991c40c1643d7c3c4535a02ac56 assets/airdef/textures/block/bare_nozzle.png
b83bf9da366623e9060981ad77909398ecec55c2f0a7a0aefc941070db961c5b assets/airdef/textures/block/bare_nozzle_b.png
070ce486efc729c756072e19e0f469763e1401289889c302800e45c68d1fb92a assets/airdef/textures/block/barrel.png
b3dfaf452ffe4569477fa270e73d57e16eaed0e7639276336a0ffa4050b53507 assets/airdef/textures/block/beam.png
510a01548a0dce9d3caf767f1a9f172045b253be4f3b3e98e367a281f550ec55 assets/airdef/textures/block/booster.png
7de5699fd66a82395d03e389d2ba0b2aed87d7a52c4f7bcfbcf9a6fdb34ca301 assets/airdef/textures/block/booster_b.png
2d9d72a90bee81630131ecf60f84b74691f6f16e8a7427fef62e2fa7923e5334 assets/airdef/textures/block/canister.png
909b3acf5ac784c4917acba2e1e5c290d412c71fae5457e3916a770c9b20809a assets/airdef/textures/block/canister_b.png
082e2d3fd7df0d548c294c410a6a7643b54d482d76643e0737bae1dcc54736fe assets/airdef/textures/block/canister_front.png
53adaaade4d845d87ec3535adddfba8c0fc84ce373e9722650508ddc0fec7420 assets/airdef/textures/block/canister_front_b.png
2248649b97f906d44208c5d83be7482867e1439d7bdab3e974b0b63af5224249 assets/airdef/textures/block/concrete.png
e43d62b61bb7a5cf7973be9bbe197218c63924c87274852a46c1deb7713c5f30 assets/airdef/textures/block/concrete_b.png
68a21931d31f90f74f1101047ba307b9587ef2cd13139b03fb13cd1119f5d551 assets/airdef/textures/block/crate.png
5fbef49d433c12ff76842d66d8b6bcc9aaeab0e7d47305523f97d12842b2ff0c assets/airdef/textures/block/crate_b.png
331cacfccc1c61b16a986b33e422d751e57cd8d07cb064a012f762105bfca93d assets/airdef/textures/block/dark_metal.png
d262dfab6a1e4bde719f85493246c2ccecdd367a5240d8e7a25cf0eaef2bda7a assets/airdef/textures/block/dark_metal_b.png
deee51e051cb1fdf7495a8dc1fa05bf9a166df9cb5e7e446bf3d29cea856efb3 assets/airdef/textures/block/dish.png
698c9095df8f6b48c260759655797e67df35b390791ceba3e7ce2eb3cce3f8ab assets/airdef/textures/block/fire.png
8532e81c8d5056db50100d963c84522205b6ee698081081a1888f1ee48b7bf08 assets/airdef/textures/block/flame.png
b5b75b2380ed2a12a7ae1b0618efe17358e3a9ebcb9af5de46adf5195dbba271 assets/airdef/textures/block/flecktarn.png
6be4508463644978a41aa426cf9fb547ba2c313e22140b6cb898dd1f54e7446e assets/airdef/textures/block/flecktarn_b.png
b9d5beda0383b16f3f52bafad020768929f0910d0cfd5555b58d176c2bcbf3a7 assets/airdef/textures/block/flecktarn_s13.png
52ca49f3c196de9b7216a1a40b359942a2da3204a39aa0716b085a67dfc073cf assets/airdef/textures/block/flecktarn_s13_b.png
e6b307c552e008962695052a7136cc9037ca8c524a697d8450eb591cd7518e78 assets/airdef/textures/block/flecktarn_s21.png
979c60d195732ac97352408a7e42aa645de153dbf1c55bbb3d72ccf65f8fe695 assets/airdef/textures/block/flecktarn_s21_b.png
1aa7201611114554ce054a9d46a60da566f9c571f2a4ff4ebd4133258c0bbcfb assets/airdef/textures/block/flecktarn_s23.png
7439316183817ce23322367cbd51c80602f0e1537977c78b410671dbbab166bd assets/airdef/textures/block/flecktarn_s23_b.png
5517a43554b08fbbf5cccec8e537ecb23965e1472323e5ae4ad1420a12fcdd4a assets/airdef/textures/block/flecktarn_s31.png
5c44f0f17d55077549982690bab313711543fd706ee944207759262c76e00cb8 assets/airdef/textures/block/flecktarn_s31_b.png
007b3b806bc431be1c84dfca31f2f81fb4c2f9d5a522e40ce0d03f5d3716b106 assets/airdef/textures/block/foam.png
7f8f88fff7d9f4b872ab7bbdc3e976e782730d91355941c7837ef2f7685730f4 assets/airdef/textures/block/geran.png
014374b3428ffe8c438c0df2806c3edd9215c707ec3fd4e18edefd304b9d49cb assets/airdef/textures/block/geran_engine.png
d44f6059ac51c7d707dcb8152036f87fe83af63cdece0c06f88370b5db56a5e0 assets/airdef/textures/block/glass.png
5f733a261a5e8c8eb6a7837ab1e6e28d058410d7cca16e124d7b315f032c3ebc assets/airdef/textures/block/glass_cab.png
b1a6096232481d08c710ff4133547badd1e0061676d6fc4f8e110e691c5e2e0e assets/airdef/textures/block/glass_cab_b.png
3c836747774bc6c5f037eb5f6f581e9b9913c365747251f702164690ec3241e7 assets/airdef/textures/block/glow_ember.png
8f2a9c7485d8b56c7bcf26ee3823f9efdea7ffdb5e3d770f991228cf883eab30 assets/airdef/textures/block/hub.png
0b9e2514e1ff4832ade4ce231e4f1fda0ad50c16ebe7ae726ad749e454e07e1c assets/airdef/textures/block/hub_b.png
216ec5f36c0ff06a55fef95691190eedb0d3ca7af5c42b97c7b901eed91fd1e8 assets/airdef/textures/block/intake.png
d76e4cecd7bedde37dd5d7f84fa2ff6c2b690bcc6e3d9fe905589e24849c045a assets/airdef/textures/block/kh101.png
3413594a1f8ef3e91fd85660114f81c36f3db54a03dc645d030b545d1ba16e4e assets/airdef/textures/block/kh101_belly.png
b52ffbc21c7d5f7cb4d48b5b379e09e92656c5677b8aa66116483521fb3cb7e1 assets/airdef/textures/block/lamp.png
d6f46d3018b98fd8d5f36df9ca11c07f77e5983e05db24bbc59e10916dd6efcd assets/airdef/textures/block/lamp_b.png
e25bd88852f4a50609487eea13bbf58f397c54926f0bc9d02e9d596b17e058e1 assets/airdef/textures/block/lancet.png
d76ebbd51a689233c256776b2c55893268f40567b2c059c9805e3cfc323307ec assets/airdef/textures/block/metal.png
b8f411252cbce0a9e08cccfb4788aad721f6d7aa76c05a40a1c25757c27404d8 assets/airdef/textures/block/metal_b.png
ca2f6efebc39b27cc2a3f974b3ea6b4d9f64929a8355ce4ec1d96ce44fa3dca2 assets/airdef/textures/block/missile.png
898c77bf0dca8c5242468969ad9ae96d13a36d0cfe2c12798f9f51804244a840 assets/airdef/textures/block/missile_grey.png
bf63b80d2b4e9c2f229fccf4e1162dafe738e5522c4784d5262f89afb3eab2cb assets/airdef/textures/block/missile_ru.png
b3c7d5fd6518311f7d22f5b98c9edf230814716f5ec33e5ef84747f49cc7a639 assets/airdef/textures/block/missile_ru_b.png
22730d3a16bf4793e7a2b0cedde24fa015312f6cd91d00d6cd7767faf82f6a06 assets/airdef/textures/block/mk_de.png
9089911e06b239c2f782268c4d637a96e75e0a1eb48a1228f09201245ccc7c9c assets/airdef/textures/block/mk_de_b.png
b8c28ed48383b17725d1d4229e52db9a153bbbcce114e6cfabe6ac86dca86f18 assets/airdef/textures/block/mk_ru.png
7cc8d37e381e965b44cbb53e82626a2d52692a3085ea142c0ec9faa77cf99690 assets/airdef/textures/block/mk_ru2.png
812fee3fc8c346e8eeed2ad30e1caab80c0f6bcb5e94a33ee6d47a6732cb4ddb assets/airdef/textures/block/mk_ru2_b.png
e6a89c73305fc2429df0a7a3fab1b6e6c2d1eb2de48251f1d556dc9a8476a14f assets/airdef/textures/block/mk_ru_b.png
a9de0c4e228fd2adaa996d0ca6123b6d8195fc5c1719201ae741c4979882f1d5 assets/airdef/textures/block/mk_star.png
0b2017578093f28b49994c7d120fa19ec4fa07d137f5b8d30c58326aad00164c assets/airdef/textures/block/mk_star_b.png
8526c1439d9723d1592c3c7c06da8bb8ac2f44cbd5310aaa689019e583a1cc19 assets/airdef/textures/block/mk_us.png
65c308e09a0ba82cdffb87d334ff5bb517a27c2d60d6244cfd53cd9bff1c5080 assets/airdef/textures/block/nato_green.png
5bf07917f3ac31f74ccffd1ae381e8d62f58fd4748bce7b16bfb135850c9bd74 assets/airdef/textures/block/nato_green_b.png
66eb485456876d3aea75cd5e3afb676998d3315056041ee04220b7708ced7856 assets/airdef/textures/block/nato_green_s21.png
76174f752b5e96040e0edb0454b4fcd354182d95786033e396e2bab29e57f2e1 assets/airdef/textures/block/nato_green_s21_b.png
09af19d2003a7ef61c83cb4d4ce4ad544ca760d98c2cb60a881ee9039cf39d65 assets/airdef/textures/block/nato_green_s22.png
6559a12b24829a933b05b21a4bb673878e53bdfa5d7f87a8810c6e9e27ea3d00 assets/airdef/textures/block/nato_green_s22_b.png
28737c6592a187f4b542c18084dfa26ef5e2a5ef0424b94fa5fc1db06825f0e8 assets/airdef/textures/block/nato_green_s23.png
d5aa425480264085dd0a5654e97be78620a28b0adb2e17ad952d6faadcf5a168 assets/airdef/textures/block/nato_green_s23_b.png
491f3e54e771764a9a3a345a577838bb5c2d4bdf80a827d05ff6e8d98f229551 assets/airdef/textures/block/nato_green_s31.png
dd8c9056df254fe788a6848c96af4e56c5951f08717b25ebaa8815d1fb823751 assets/airdef/textures/block/nato_green_s31_b.png
311932fa43f0b513342e8f3746208bd845b936f883f6f5c8d453fd4ef6d315dc assets/airdef/textures/block/nato_tan.png
6a1289cfba0b17732cedfadceb6522b0b9f847f754dd56975716b3e2e21e777a assets/airdef/textures/block/nose_dark.png
a8c0d707e86dedb7591b7e89f07ffd2df85ab0763e903a4c4c9ea17c97c4baee assets/airdef/textures/block/nozzle.png
85c25585f0701d719a4750f77c1eb1d63fcb469741caa27aeb5b7a04fdff7279 assets/airdef/textures/block/pilot_nato.png
e2a967933fe524abf37135e61b1aede6443a8a44d7cbe0438a0c4b4e49d6721f assets/airdef/textures/block/pilot_nato_b.png
c912a25df82af9bdfb864e7e7a018accdd048fd729a672fa4b088c663555beaf assets/airdef/textures/block/pilot_olive.png
e2a967933fe524abf37135e61b1aede6443a8a44d7cbe0438a0c4b4e49d6721f assets/airdef/textures/block/pilot_olive_b.png
3f908df37b1456884d840e346f2da60ccce5b61bd226317de9ca24430bd59a8c assets/airdef/textures/block/prop.png
98442b32c81dd7523c8d38bc6ae9810d8e0295474c814533b7fbde33f4910e3b assets/airdef/textures/block/radar_big.png
5dff7780ae2f934bc05bb58742f1965b7cf06ad28459d6dd63b574a0a327f949 assets/airdef/textures/block/radar_face.png
83a012f282bf709a4628530632fac3e0e3227325e931d7774747d7b95401d3d3 assets/airdef/textures/block/radar_face_b.png
144ce90863430c724243ba27bfb212ab1e4e5ff58650d0ec884b14d47232ddeb assets/airdef/textures/block/rm_dark.png
46a86ef31a44a7672c9f5d4e8c0605b78964ccbe1131127dd94d9c4bb307695e assets/airdef/textures/block/rm_dark_t.png
5e37e431975e5816388bf8906cd8d32e41b6ee44760f355983ca9c26cc004932 assets/airdef/textures/block/rm_grey.png
a0d4a601d1d29b1988e73b74c1198c9b6fde7cbfccceb3057465b22124959fd2 assets/airdef/textures/block/rm_grey_t.png
0d21b93c78581892e08f31ca8e4f01c9edf7793f61bca78c8ee72cb0bfa2e40f assets/airdef/textures/block/rm_khaki.png
e832c1bbff632eac6c9b62be8d68981a62a7837499437c0b85f9fb51a4506550 assets/airdef/textures/block/rm_khaki_t.png
4a8e048b9219e04b143da3ae9214f12fa96c68b4e33201b9ec248d65c9eb7f7f assets/airdef/textures/block/rm_pac3.png
08c9ad4315458bc7c59632aba8bc65de051639b2039dc9d252b79917dce15f7a assets/airdef/textures/block/rm_pac3_t.png
a4280a067f3c3068b3ba47dcf4881e091e70a269685e192e19dd025bf7532843 assets/airdef/textures/block/rm_ru.png
7992de763ec57589788eedb01bfb656cec49e73d3dbc15b13aab8a65506c6f5b assets/airdef/textures/block/rm_ru_t.png
c9abfcb99b86708b009270d96a563036c4a539c7f7cfa734c94a97c05b3f36ac assets/airdef/textures/block/rm_white.png
f336ac70e704bbb2977ef36ce6c6ce853ad57e3970cc44ee16eabb9554485707 assets/airdef/textures/block/rm_white_t.png
b92c1817d1b25d626b03998762d8ae29900f6ef41d883be35191877edd4bfd93 assets/airdef/textures/block/ru_green.png
4c932c1c226af577ed1b77c6846d1f1ce95e5da053bda1723e7ddb3442d78959 assets/airdef/textures/block/ru_green_b.png
c3cea9d7709650d88515a7fbfaeec719eb3395687d10cfd92ce374c8b1687e4d assets/airdef/textures/block/ru_green_s12.png
b8cdde5132e534c46c7521a3612b490656221e7549045990edf881f9c2e5e388 assets/airdef/textures/block/ru_green_s12_b.png
bc82211cc1a25e52672452dcd5cd533e818821c79b06a705402d2aff36d48286 assets/airdef/textures/block/ru_green_s13.png
4ca0d50c73cbb661c6c86da9dc2add011da52de185f844dd7dfb515c26b9db72 assets/airdef/textures/block/ru_green_s13_b.png
58729c9509463a4858dddd7fa0964de696e265f6c409a77fae732a73a177542b assets/airdef/textures/block/ru_green_s21.png
167683d721a45aa4a104edeafdf231b0eecfc70442b59e190460009bee3b2e89 assets/airdef/textures/block/ru_green_s21_b.png
7795c2ef19789d465b9b1420ca3aacf1201b0904414b7e39610172c84049c0c1 assets/airdef/textures/block/ru_green_s22.png
5d92c96f896314e390711b66c07922c832a443c3c56e1daec2890195960de47a assets/airdef/textures/block/ru_green_s22_b.png
1c53b3d9cecaa5ed932bf1d58a864e77481e515729c7a72c4032a734897e0b34 assets/airdef/textures/block/ru_green_s23.png
c1424132a342f0245430fa165a1b2d18b6660580cf4ae100fcc19dd3feb2e20d assets/airdef/textures/block/ru_green_s23_b.png
ba4511238d904460c91a55af88781560eac6272de937ed57d54714590f0a3907 assets/airdef/textures/block/ru_green_s31.png
c7425dcb7916bb5ec48bfa57def2a8d6a44a88600fc2651392e9fae8b2fe4888 assets/airdef/textures/block/ru_green_s31_b.png
934ea2bc2623e42310adc0dd67e01916cd21dd32dd691ed759bd681cac958525 assets/airdef/textures/block/ru_khaki.png
abab312510b9d18ca5561c8424aa0ad33feab2575b8d5dfe42b0a6bf31430bd3 assets/airdef/textures/block/ru_khaki_b.png
055fdbc8ed3b808e263a13f694cce5444c4fada440994cd443103d308d54fd20 assets/airdef/textures/block/ru_khaki_s13.png
a53ae1e5fd32671e28d74a090ab3828e2dc34ef223b4c71a1b6f535c0e999a9e assets/airdef/textures/block/ru_khaki_s13_b.png
8df45cca0a57f01efeb85da2c76544c2b103fc474387aa76215d093e998242d9 assets/airdef/textures/block/ru_khaki_s21.png
06dc7f90bdf077097534322435be402f08e5ee9bc34135e410809a8892b940e8 assets/airdef/textures/block/ru_khaki_s21_b.png
194d9a3bca192f65b4f2e808b21c28346dc85d96e923e4bebe2138bc5a0b4927 assets/airdef/textures/block/ru_khaki_s22.png
5f8a6dfed6add932e9b4d0cee17adc4c811cba85433877fcbf0f7dfd9773cb1b assets/airdef/textures/block/ru_khaki_s22_b.png
6d0aa0dcc1702486c764120f49fc3e2ae6f17c953b8c06f53b395a645463a666 assets/airdef/textures/block/ru_khaki_s23.png
cea69d4094324363c2088e1f186927f8dabab4e7eb34a97add85587ea144fda4 assets/airdef/textures/block/ru_khaki_s23_b.png
898405a1bb59a934a499409431003f3dc44a5f3f1874f41e28750f2c4331befc assets/airdef/textures/block/ru_khaki_s31.png
dddcaf43fdf7f5d4e2433c72e5267548e3cb7d65c745082be0a60b14367810b0 assets/airdef/textures/block/ru_khaki_s31_b.png
76b33dc7f36d1a67cb07f9e65b5dbda1e07ddbc41fbc75ad974654aa1ebacb57 assets/airdef/textures/block/ru_khaki_s33.png
3e81c65d26070613c59fc6e363f0e0772c376bea5ab86c37b6cb19431a816535 assets/airdef/textures/block/shahed.png
36e55b26a48838c8c25ec6d1660cfcdfcb1fc7e430dda0ac8908709c0c05f9b4 assets/airdef/textures/block/shahed_nose.png
29a415d359ee6eb0b4b85a18edb38b77e852b5f6a441abbeb9485d1068726e35 assets/airdef/textures/block/target.png
c047457ac99436c8a69bfc7fa755fa55e842ae3261890965df09a2011b8e6201 assets/airdef/textures/block/tire.png
97bd7e7731bd1ad8e4eb582e9acd44981ac4fc47a51a1a5ec4e39d9873a42079 assets/airdef/textures/block/tire_b.png
4edb1f39d7ffeb69257098023b6c3e4709014e5d54cd306ef0930e54257ee93a assets/airdef/textures/block/tracer.png
564d4e443a0270a09cc2e7202ca73e40ffb00422c68a9842b19c10d4c2c184b9 assets/airdef/textures/block/tracer_hot.png
e1da001ded920abd57814b7301d0388a04db72b0eeac51f73d67b6287d56ef43 assets/airdef/textures/block/track.png
337e60bf5be059e10649e78da7fc98f1f12cc47ae8dddeb85f733535d3fa0c48 assets/airdef/textures/block/track_b.png
68b9407648c541ea0a167e731340358b4ef45862be13ee5a582f7e088818cfaf assets/airdef/textures/block/track_side.png
fa2848684a76002a17932aae6a0eead4af19ac594be39e1f7f995d2a239d6c6c assets/airdef/textures/block/track_side_s31.png
02fa231c4ba6ba4d42c254fe815d1e0d74308a7f8fc1735cec5f955b494c9970 assets/airdef/textures/block/track_side_s31_b.png
7a83f09a9c4feca1eb1dbde5abefa770b3623d5e491666d6835d2272d70d3709 assets/airdef/textures/block/tube.png
137d90569624d7b164c16bf5d8dec2e9c4aed8096e3ec0d96f9e3661df90ee63 assets/airdef/textures/block/tube_b.png
03570f9d5963c5fd61472d10cb68d56c26a7fd5806ccc86b86c5095476966b58 assets/airdef/textures/block/tube_cap.png
e622dfd1caabbfde83081c89447fe49c13301f4edb92efe149402e110cbcb64e assets/airdef/textures/block/tube_cap_b.png
bfd57114127057959dc3d46c60b1234e27dcdb35387a5e2b4f045ceb676ca09f assets/airdef/textures/block/tubes6.png
4a229d23538c8f22c812633362f70ee4d887e515ef1d798fcd8a26c28f715696 assets/airdef/textures/block/tubes6_b.png
92c449cdceb109949b31d49ff5627173cc0a33daf2c610748aef709623dcef23 assets/airdef/textures/block/white.png
fb41e5b003f0c16308bc819fd632828d21fe1855ad9cd32283e02de3defb67fe assets/airdef/textures/item/deploy_buk.png
0c06c682684abbf03e01d5ce7d8d2a4ece2ddc96e96bf87d7597bb0247ce3806 assets/airdef/textures/item/deploy_depot.png
d0a6911668824195a4630a60f2b618958a134dada220a269a1c1c8faf2b77922 assets/airdef/textures/item/deploy_ew.png
303c3352b21762b59eb23f2402dcb59f77983e5d2db08711414be99624695364 assets/airdef/textures/item/deploy_gepard.png
a3dd2f7ad102f84be1df0182e22f2c2189bb872a8dcf3ddb7136ac05434c6abc assets/airdef/textures/item/deploy_irist.png
805e883f86175f4f16ac8e43488f0db469f8c7d4bf0545c80439440517ea4685 assets/airdef/textures/item/deploy_light.png
e7e303005314c70ec142e69ca6511d7dd1d6daba909563ecf6e3cbd6d146a9a8 assets/airdef/textures/item/deploy_nasams.png
cfe4373e86a9e2f268e0623279da6498b4327afbbeec3b7cef0b1775f6007c73 assets/airdef/textures/item/deploy_p1sun.png
e7522f1c583dae4cdf313a0ddbf22aae837dc34e5ec36a46daa5d7cb459d59fb assets/airdef/textures/item/deploy_pantsir.png
2cffed28123c0e4eb828eb314e7ea65ced2576bb158913e0a837b96f0fb67730 assets/airdef/textures/item/deploy_patriot.png
8b015f6480fbd7d9c1078efc73f3097fe32832fb5bbd6b8fe45307cd545a3026 assets/airdef/textures/item/deploy_radar.png
37ad7777de7034487d3c53f5224eca34b5dac6de41aeb2080fdbd112ec7eae0e assets/airdef/textures/item/deploy_s400.png
4cfb6250543f00b37fdb9e09e63c3107f7d88beeeaf72838150f9f301284cdd8 assets/airdef/textures/item/deploy_s500.png
c473b97913fe7afab44d84768c80e11b752645b8bf9de9ffe5a026d3eb4d8e9c assets/airdef/textures/item/deploy_tor.png
483c40bf24d5dae5ffad872c1b1df719cebcfb1f36c1153c2a5790981588d493 assets/airdef/textures/item/deploy_tzm.png
3be70aa7d5210da09a910701605dcf8b2b4dbc5c43ef2d2c77ce36a7f2029012 assets/airdef/textures/item/designator.png
f336d25be27818f3b0f4b2fc7c6f7b3e8be9050c9f9231f5703056a4bd8c1685 assets/airdef/textures/item/flare_gun.png
51d28156b180efa780ad91dc7b5d0b5d89880ae3a35a5f228d3dc8ca1ec80938 assets/airdef/textures/item/launch_geran3.png
f6165a2f251c61a6b89711e493da86ec0facb422f6b1e0364a8b7e707d641bf5 assets/airdef/textures/item/launch_iskander.png
748f050d5229d70414e81ef204f66f075f659e78117c40818bc51cb728d73180 assets/airdef/textures/item/launch_kalibr.png
925224a3deffa75f32207bd4324f8c06a6e1c08739126a96ab83b327902e55bf assets/airdef/textures/item/launch_kh101.png
dc6e92e3386badb8b3b8fc17dffe93f19ae9a406e4e2275141d6313743d8ed4c assets/airdef/textures/item/launch_kh22.png
0e81d738ddf1d7eb1db828f27e88e45066c413fd2ade293561d9c08965232908 assets/airdef/textures/item/launch_kinzhal.png
41586acc732102fbc07a5183d91dd614a622aaecf3fed6de795e34e59af41fe6 assets/airdef/textures/item/launch_lancet.png
f446b6d8b37f5be99390bd77e4e36752547085f004b98520359b3f3e80edfdea assets/airdef/textures/item/launch_oreshnik.png
7e0643346b7ad04caa4f234c793dd671abdbb9dbc5138a3836d867aebec95a48 assets/airdef/textures/item/launch_shahed.png
a1439f23a2d368f3d3ebd1b7d26d44af27c05797c3aad76a30878a79e225cce9 assets/airdef/textures/item/launch_zircon.png
60332733e12c2c0d346db2f3b8108d0083167cfc75e8b1e0c76a52c495b95924 assets/airdef/textures/item/mover.png
e43175307463d0946562f21d44ec5393c2605537820708dae3687065d3284aa1 assets/airdef/textures/item/remover.png
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/amraam_missile.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/barge.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/beam.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/buk_chassis.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/buk_chassis_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/buk_rails.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/buk_rails_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/buk_turret.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/buk_turret_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/debris.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/depot.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/depot_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/ew_truck.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/ew_truck_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/fireball.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/flame.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/flare.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/flash.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/gepard_dish.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/gepard_guns.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/gepard_guns_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/gepard_hull.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/gepard_hull_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/gepard_turret.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/gepard_turret_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/geran3.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/geran3_flame.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/gerbera.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/irist_chassis.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/irist_chassis_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/irist_missile.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/irist_tubes.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/irist_tubes_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/iskander.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/kalibr.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/kh101.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/kh22.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/kinzhal.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/lancet.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/launch_ramp.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/launcher_truck.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/m48n6.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/m57e6.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/m77n6.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/nasams_launcher.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/nasams_launcher_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/nasams_trailer.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/nasams_trailer_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/p1sun.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/p1sun_launcher.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/p1sun_launcher_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/pac3.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/pantsir_dish.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/pantsir_pack.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/pantsir_pack_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/pantsir_truck.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/pantsir_truck_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/pantsir_turret.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/pantsir_turret_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/patriot_launcher.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/patriot_launcher_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/patriot_radar.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/patriot_trailer.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/patriot_trailer_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/patriot_truck.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/radar_mast.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/radar_mast_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/radar_panel.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/radar_trailer.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/radar_truck.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/radar_truck_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/reentry.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/rm48u.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/s400_chassis.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/s400_chassis_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/s400_tubes.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/s400_tubes_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/s500_chassis.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/s500_chassis_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/s500_tubes.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/s500_tubes_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/searchlight.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/searchlight_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/searchlight_head.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/searchlight_head_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/shahed.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/shahed_prop.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/target.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/tor_chassis.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/tor_chassis_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/tor_turret.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/tor_turret_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/tpk_cap.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/tpk_cap_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/tracer.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/tzm_truck.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/tzm_truck_burnt.json
cc0877f40434365b45b03429222926aa0cf135e504017311be53263fd27c5f8f data/airdef/horizon/block/zircon.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/cam_geran3.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/cam_gerbera.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/cam_iskander.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/cam_kalibr.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/cam_kh101.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/cam_kh22.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/cam_kinzhal.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/cam_lancet.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/cam_reentry.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/cam_shahed.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/cam_zircon.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/deploy_buk.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/deploy_depot.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/deploy_ew.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/deploy_gepard.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/deploy_irist.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/deploy_light.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/deploy_nasams.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/deploy_p1sun.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/deploy_pantsir.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/deploy_patriot.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/deploy_radar.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/deploy_s400.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/deploy_s500.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/deploy_tor.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/deploy_tzm.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/designator.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/flare_gun.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/launch_geran3.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/launch_iskander.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/launch_kalibr.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/launch_kh101.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/launch_kh22.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/launch_kinzhal.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/launch_lancet.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/launch_oreshnik.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/launch_shahed.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/launch_zircon.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/mover.json
2a3912a7c9d5bb8025b1ac16a1a1d6b5eff0360bb3184e810d319e498255bf97 data/airdef/horizon/item/remover.json
5e0c0090b5aaded5b86b245cb30bcd0cbaa82f632a362d490d79bcf2794e25fd src/sim/generated_bounds.rs
+15
View File
@@ -0,0 +1,15 @@
# Authored source assets
Place artist-authored overrides under `assets/airdef/` in this directory, preserving the runtime-relative path.
For example, an authored icon at `source-assets/assets/airdef/textures/item/deploy_gepard.png` replaces the
procedural icon at the generated runtime path while the source copy remains untouched. The asset generator
copies this tree into its temporary staging tree, validates the merged runtime assets, then installs them using
the generated manifest. Do not edit generated files under `airdef-mod/assets/` directly; an untracked or
hand-edited output is treated as a conflict and left untouched.
This directory is intentionally kept separate from runtime and generated output. The initial art pilots are
S-400 chassis/canisters, Gepard hull/turret and Shahed, including burnt variants for the ground vehicles.
The JSON is editable directly. `python tools/pilot_models.py` is an optional authoring helper that overwrites
only those named pilot JSONs; the normal regeneration never invokes it. After editing, run
`python tools/gen_models.py` to validate and install the authored models. `generated_bounds.rs` is derived
from the final staged geometry, including overrides and element rotation, for chassis navigation.
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More