Compare commits

..

131 Commits

Author SHA1 Message Date
chexit 217e3ac886 Add feature-gated DLSS SR proof of concept (#124)
Advance to engine ed751714e. Document the optional SDK build, ordered color conversion/submission, native fallback and the remaining MSVC-link and RTX-runtime acceptance.

Co-Authored-By: Kimi Code <noreply@moonshot.ai>
2026-11-14 22:10:32 +03:00
chexit f33b799551 Record previous-frame motion for mod models (#124)
Advance to engine 7a73e8d26: separate previous-position streams and a depth-read-only motion pass for mod models, with matching alpha cutouts and a debug view.

Co-Authored-By: Kimi Code <noreply@moonshot.ai>
2026-11-14 21:06:02 +03:00
chexit d8cb98a964 Keep radar target blips above the player arrow
Draw the player marker before network tracks so a close blip is not hidden. Add a shape-order regression and verify a live raid with truth disabled.

Co-Authored-By: Kimi Code <noreply@moonshot.ai>
2026-11-14 18:25:33 +03:00
chexit e59c49e3bf Blend HD shadow cascade filters at the near boundary
Advance to engine 17382445a and document the six-block near/far transition verified on the forest aerial view.

Co-Authored-By: Kimi Code <noreply@moonshot.ai>
2026-11-14 18:04:24 +03:00
chexit 9664783b17 Add dense motion foundation for temporal upscaling (#124)
Advance to engine c962cd472. Document the render-pixel current-to-previous contract, native TAA/TAAU consumer and the remaining DLSS/object-motion/linear-HDR work.

Co-Authored-By: Kimi Code <noreply@moonshot.ai>
2026-11-14 17:49:23 +03:00
chexit 3db1b73d64 Reuse oversized renderer staging buffers (#130)
Advance the engine to 94b572cd2, backporting upstream f7b77fbc8 with its GPU growth/readback regression. Keep API30 unchanged.

Co-Authored-By: Kimi Code <noreply@moonshot.ai>
2026-11-14 17:27:17 +03:00
chexit 367c7f4ac3 Bound recorded SAM poses under the WASM memory cap (#122)
Thin old SAM keyframes in place, reduce allocation capacity and adapt later sampling when a recording exceeds its fixed pose budget. Preserve recent poses and cover the full ten-minute window in native and real WASM stress tests.

Co-Authored-By: Kimi Code <noreply@moonshot.ai>
2026-11-14 17:21:48 +03:00
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
chexit 5003376e70 Acoustics stage 1: mod plays near sounds when the engine muffles, band-energy check tool (#96, fork patch 39)
build / mod (push) Successful in 3m52s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:09:23 +03:00
chexit 29d43071b5 Track the mod's item and block declarations: the fork's gitignore also matched data/airdef/horizon
build / mod (push) Successful in 3m50s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 19:12:04 +03:00
chexit 318a161a3d HD clouds no longer warp while walking (fork patch 38)
build / mod (push) Successful in 3m50s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 19:07:38 +03:00
chexit 766b292aec Continuous engine sound on drones and missiles, live and in replays, through persistent sound sources (#95, fork patch 37)
build / mod (push) Successful in 3m51s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 16:10:24 +03:00
chexit ab6b61db59 Acoustics porting plan from Sound Physics Remastered 453654e (#96 stage 1)
build / mod (push) Successful in 3m52s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 15:54:01 +03:00
chexit 4d4e1682f5 Windows build: patches and the fork keep LF, packer rebuilt when the fork changes; install notes
build / mod (push) Successful in 3m52s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 15:49:57 +03:00
chexit 545d4777e8 Kill outcomes: falling hull, breakup or air detonation by weapon and target, recorded for replays (#97)
build / mod (push) Successful in 3m54s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 15:47:03 +03:00
chexit f16bc2387f /airdef command tree with typed arguments, live scenario names and generated help (#98, fork patch 36)
build / mod (push) Successful in 3m52s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 15:43:11 +03:00
chexit 9bc94fa8aa Raids launch from real sites: 1, 2 or 4-5 sides, stock and launch queue, land first, then nearer land, then barges on water (#100)
build / mod (push) Successful in 3m50s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 15:36:43 +03:00
chexit 0f5c4136f3 Replays: smoke rebuilt from the recording, recorded objects and searchlights, film cut in true order, export sessions guarded, gun camera above water; export keeps its last frames; hd_bench no longer excuses strong flicker (#76-#84, fork patch 35)
build / mod (push) Successful in 3m49s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 15:19:32 +03:00
chexit 51f9609327 Distinct item icons: a silhouette per item and category instead of one remote (#99)
build / mod (push) Successful in 3m50s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 15:07:54 +03:00
chexit 3265eb63d2 HD: coloured shadows, rain ripples, film motion blur and depth of field (fork patch 34)
build / mod (push) Successful in 3m46s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 15:01:09 +03:00
chexit b43d471706 Combat fixes: exact-ray answers tied to their segment and block (#73), no fuse kill through a wall while waiting (#74), seeker needs confirmed sight and stops reading true velocity (#75), combat RNG and ids independent of graphics (#85), saved layouts validated whole before the scene is touched, refused autosave kept (#86)
build / mod (push) Successful in 3m48s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 14:57:19 +03:00
534 changed files with 227468 additions and 65493 deletions
+1
View File
@@ -4,3 +4,4 @@
*.png binary
*.jpg binary
*.hmod binary
*.patch -text
+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
+124 -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 СБ. Сбитый дрон падает с остатком скорости, и его боевая часть
@@ -221,6 +299,12 @@ API мода `render.set-lights` (до 512, плавно интерполиру
У каждого объекта свой звук и своя дальность слышимости (`attenuation_distance` в `sounds.json`):
- **двигатели:** двухтактный мопед шахеда (220 м), турбина Герани-3, электромотор Ланцета, тяжёлый рёв крылатых ракет (320 м),
ракетный рёв Х-22, Циркона и перехватчиков, нарастающий визг падающей баллистики и её ударная волна (700–900 м);
Двигатели дронов и ракет — **постоянные источники звука** (API 20, `render.sound-sources`, #95): один источник на
объект идёт за его настоящей позицией, зажигается с нарастанием, при сбитии «захлёбывается» (тон падает, громкость
гаснет за секунду) и замолкает вместе с объектом; в повторе и экспорте источники берутся из записанных траекторий и
времени повтора (перемотка и смена плана пересоздают их). Одновременно звучат 24 ближайших и громких, остальные
«виртуальные». Взрывы, пуски и выстрелы остались разовыми, с задержкой по скорости звука. Баллистика (визг при
падении) тоже разовая. Зацикливается устойчивая часть файла (начало и затухание в конце обрезаны), стык — 50 мс.
- **пуски:** хлопок и рвущийся рёв Patriot, свистящий старт Панциря, глухой газовый выброс и затем огромный рёв С-400,
у С-500 ещё ниже и дольше (до 1 км);
- **пушки:** тяжёлые 35-мм очереди Гепарда и частые 30-мм Панциря;
@@ -246,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)
@@ -275,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/barge"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "airdef:block/launch_ramp"
}
}
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "airdef:block/launcher_truck"
}
}
}
@@ -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"
}
}
}
+8
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",
@@ -55,6 +58,9 @@
"block.airdef.radar_truck": "Шасси РЛС",
"block.airdef.depot": "Склад боеприпасов",
"block.airdef.tzm_truck": "Транспортно-заряжающая машина",
"block.airdef.barge": "Баржа",
"block.airdef.launch_ramp": "Рампа запуска дронов",
"block.airdef.launcher_truck": "Пусковая машина ракет",
"block.airdef.ew_truck": "Станция РЭБ",
"block.airdef.searchlight": "Прожектор",
"block.airdef.searchlight_head": "Голова прожектора",
@@ -73,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 (остов)",
+8
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",
@@ -55,6 +58,9 @@
"block.airdef.radar_truck": "Шасси РЛС",
"block.airdef.depot": "Склад боеприпасов",
"block.airdef.tzm_truck": "Транспортно-заряжающая машина",
"block.airdef.barge": "Баржа",
"block.airdef.launch_ramp": "Рампа запуска дронов",
"block.airdef.launcher_truck": "Пусковая машина ракет",
"block.airdef.ew_truck": "Станция РЭБ",
"block.airdef.searchlight": "Прожектор",
"block.airdef.searchlight_head": "Голова прожектора",
@@ -73,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 (остов)",
@@ -0,0 +1,896 @@
{
"ambientocclusion": false,
"textures": {
"dark_metal": "airdef:block/dark_metal",
"metal": "airdef:block/metal",
"ru_khaki_s31": "airdef:block/ru_khaki_s31",
"ru_khaki_s33": "airdef:block/ru_khaki_s33",
"particle": "airdef:block/dark_metal"
},
"elements": [
{
"from": [
-16.0,
0.0,
-16.0
],
"to": [
32.0,
3.0,
32.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,
16,
3.0
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
16,
3.0
],
"texture": "#dark_metal"
},
"up": {
"uv": [
0,
0,
16,
16
],
"texture": "#dark_metal"
},
"down": {
"uv": [
0,
0,
16,
16
],
"texture": "#dark_metal"
}
}
},
{
"from": [
-16.0,
3.0,
-16.0
],
"to": [
32.0,
4.0,
32.0
],
"faces": {
"north": {
"uv": [
0,
0,
16,
1.0
],
"texture": "#metal"
},
"south": {
"uv": [
0,
0,
16,
1.0
],
"texture": "#metal"
},
"east": {
"uv": [
0,
0,
16,
1.0
],
"texture": "#metal"
},
"west": {
"uv": [
0,
0,
16,
1.0
],
"texture": "#metal"
},
"up": {
"uv": [
0,
0,
16,
16
],
"texture": "#metal"
},
"down": {
"uv": [
0,
0,
16,
16
],
"texture": "#metal"
}
}
},
{
"from": [
-15.0,
3.0,
-15.0
],
"to": [
31.0,
4.4,
31.0
],
"faces": {
"north": {
"uv": [
0,
0,
16,
1.4000000000000004
],
"texture": "#ru_khaki_s31"
},
"south": {
"uv": [
0,
0,
16,
1.4000000000000004
],
"texture": "#ru_khaki_s31"
},
"east": {
"uv": [
0,
0,
16,
1.4000000000000004
],
"texture": "#ru_khaki_s31"
},
"west": {
"uv": [
0,
0,
16,
1.4000000000000004
],
"texture": "#ru_khaki_s31"
},
"up": {
"uv": [
0,
0,
16,
16
],
"texture": "#ru_khaki_s33"
},
"down": {
"uv": [
0,
0,
16,
16
],
"texture": "#ru_khaki_s33"
}
}
},
{
"from": [
-16.0,
4.0,
-16.0
],
"to": [
-14.0,
6.0,
32.0
],
"faces": {
"north": {
"uv": [
0,
0,
2.0,
2.0
],
"texture": "#dark_metal"
},
"south": {
"uv": [
0,
0,
2.0,
2.0
],
"texture": "#dark_metal"
},
"east": {
"uv": [
0,
0,
16,
2.0
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
16,
2.0
],
"texture": "#dark_metal"
},
"up": {
"uv": [
0,
0,
2.0,
16
],
"texture": "#dark_metal"
},
"down": {
"uv": [
0,
0,
2.0,
16
],
"texture": "#dark_metal"
}
}
},
{
"from": [
30.0,
4.0,
-16.0
],
"to": [
32.0,
6.0,
32.0
],
"faces": {
"north": {
"uv": [
0,
0,
2.0,
2.0
],
"texture": "#dark_metal"
},
"south": {
"uv": [
0,
0,
2.0,
2.0
],
"texture": "#dark_metal"
},
"east": {
"uv": [
0,
0,
16,
2.0
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
16,
2.0
],
"texture": "#dark_metal"
},
"up": {
"uv": [
0,
0,
2.0,
16
],
"texture": "#dark_metal"
},
"down": {
"uv": [
0,
0,
2.0,
16
],
"texture": "#dark_metal"
}
}
},
{
"from": [
-16.0,
4.0,
30.0
],
"to": [
32.0,
6.0,
32.0
],
"faces": {
"north": {
"uv": [
0,
0,
16,
2.0
],
"texture": "#dark_metal"
},
"south": {
"uv": [
0,
0,
16,
2.0
],
"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": [
-16.0,
4.0,
-16.0
],
"to": [
32.0,
6.0,
-14.0
],
"faces": {
"north": {
"uv": [
0,
0,
16,
2.0
],
"texture": "#dark_metal"
},
"south": {
"uv": [
0,
0,
16,
2.0
],
"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": [
-12.0,
4.4,
-10.0
],
"to": [
-9.0,
6.5,
-7.0
],
"faces": {
"north": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"south": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"east": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"west": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"up": {
"uv": [
0,
0,
3.0,
3.0
],
"texture": "#metal"
},
"down": {
"uv": [
0,
0,
3.0,
3.0
],
"texture": "#metal"
}
}
},
{
"from": [
25.0,
4.4,
-10.0
],
"to": [
28.0,
6.5,
-7.0
],
"faces": {
"north": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"south": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"east": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"west": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"up": {
"uv": [
0,
0,
3.0,
3.0
],
"texture": "#metal"
},
"down": {
"uv": [
0,
0,
3.0,
3.0
],
"texture": "#metal"
}
}
},
{
"from": [
-12.0,
4.4,
8.0
],
"to": [
-9.0,
6.5,
11.0
],
"faces": {
"north": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"south": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"east": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"west": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"up": {
"uv": [
0,
0,
3.0,
3.0
],
"texture": "#metal"
},
"down": {
"uv": [
0,
0,
3.0,
3.0
],
"texture": "#metal"
}
}
},
{
"from": [
25.0,
4.4,
8.0
],
"to": [
28.0,
6.5,
11.0
],
"faces": {
"north": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"south": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"east": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"west": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"up": {
"uv": [
0,
0,
3.0,
3.0
],
"texture": "#metal"
},
"down": {
"uv": [
0,
0,
3.0,
3.0
],
"texture": "#metal"
}
}
},
{
"from": [
-12.0,
4.4,
26.0
],
"to": [
-9.0,
6.5,
29.0
],
"faces": {
"north": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"south": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"east": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"west": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"up": {
"uv": [
0,
0,
3.0,
3.0
],
"texture": "#metal"
},
"down": {
"uv": [
0,
0,
3.0,
3.0
],
"texture": "#metal"
}
}
},
{
"from": [
25.0,
4.4,
26.0
],
"to": [
28.0,
6.5,
29.0
],
"faces": {
"north": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"south": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"east": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"west": {
"uv": [
0,
0,
3.0,
2.0999999999999996
],
"texture": "#metal"
},
"up": {
"uv": [
0,
0,
3.0,
3.0
],
"texture": "#metal"
},
"down": {
"uv": [
0,
0,
3.0,
3.0
],
"texture": "#metal"
}
}
}
]
}
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
@@ -0,0 +1,709 @@
{
"ambientocclusion": false,
"textures": {
"dark_metal": "airdef:block/dark_metal",
"metal": "airdef:block/metal",
"ru_khaki": "airdef:block/ru_khaki",
"particle": "airdef:block/dark_metal"
},
"elements": [
{
"from": [
1.0,
0.0,
-6.0
],
"to": [
15.0,
2.0,
30.0
],
"faces": {
"north": {
"uv": [
0,
0,
14.0,
2.0
],
"texture": "#dark_metal"
},
"south": {
"uv": [
0,
0,
14.0,
2.0
],
"texture": "#dark_metal"
},
"east": {
"uv": [
0,
0,
16,
2.0
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
16,
2.0
],
"texture": "#dark_metal"
},
"up": {
"uv": [
0,
0,
14.0,
16
],
"texture": "#dark_metal"
},
"down": {
"uv": [
0,
0,
14.0,
16
],
"texture": "#dark_metal"
}
}
},
{
"from": [
6.0,
2.0,
0.0
],
"to": [
10.0,
4.0,
26.0
],
"faces": {
"north": {
"uv": [
0,
0,
4.0,
2.0
],
"texture": "#metal"
},
"south": {
"uv": [
0,
0,
4.0,
2.0
],
"texture": "#metal"
},
"east": {
"uv": [
0,
0,
16,
2.0
],
"texture": "#metal"
},
"west": {
"uv": [
0,
0,
16,
2.0
],
"texture": "#metal"
},
"up": {
"uv": [
0,
0,
4.0,
16
],
"texture": "#metal"
},
"down": {
"uv": [
0,
0,
4.0,
16
],
"texture": "#metal"
}
}
},
{
"from": [
3.0,
9.0,
-14.0
],
"to": [
5.0,
11.0,
30.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,
16,
2.0
],
"texture": "#metal"
},
"west": {
"uv": [
0,
0,
16,
2.0
],
"texture": "#metal"
},
"up": {
"uv": [
0,
0,
2.0,
16
],
"texture": "#metal"
},
"down": {
"uv": [
0,
0,
2.0,
16
],
"texture": "#metal"
}
},
"rotation": {
"angle": 22.5,
"axis": "x",
"origin": [
4.0,
10.0,
8.0
]
}
},
{
"from": [
11.0,
9.0,
-14.0
],
"to": [
13.0,
11.0,
30.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,
16,
2.0
],
"texture": "#metal"
},
"west": {
"uv": [
0,
0,
16,
2.0
],
"texture": "#metal"
},
"up": {
"uv": [
0,
0,
2.0,
16
],
"texture": "#metal"
},
"down": {
"uv": [
0,
0,
2.0,
16
],
"texture": "#metal"
}
},
"rotation": {
"angle": 22.5,
"axis": "x",
"origin": [
12.0,
10.0,
8.0
]
}
},
{
"from": [
3.0,
0.0,
-1.0
],
"to": [
5.0,
12.0,
1.0
],
"faces": {
"north": {
"uv": [
0,
0,
2.0,
12.0
],
"texture": "#dark_metal"
},
"south": {
"uv": [
0,
0,
2.0,
12.0
],
"texture": "#dark_metal"
},
"east": {
"uv": [
0,
0,
2.0,
12.0
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
2.0,
12.0
],
"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"
}
}
},
{
"from": [
11.0,
0.0,
-1.0
],
"to": [
13.0,
12.0,
1.0
],
"faces": {
"north": {
"uv": [
0,
0,
2.0,
12.0
],
"texture": "#dark_metal"
},
"south": {
"uv": [
0,
0,
2.0,
12.0
],
"texture": "#dark_metal"
},
"east": {
"uv": [
0,
0,
2.0,
12.0
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
2.0,
12.0
],
"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"
}
}
},
{
"from": [
3.0,
0.0,
17.0
],
"to": [
5.0,
6.0,
19.0
],
"faces": {
"north": {
"uv": [
0,
0,
2.0,
6.0
],
"texture": "#dark_metal"
},
"south": {
"uv": [
0,
0,
2.0,
6.0
],
"texture": "#dark_metal"
},
"east": {
"uv": [
0,
0,
2.0,
6.0
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
2.0,
6.0
],
"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"
}
}
},
{
"from": [
11.0,
0.0,
17.0
],
"to": [
13.0,
6.0,
19.0
],
"faces": {
"north": {
"uv": [
0,
0,
2.0,
6.0
],
"texture": "#dark_metal"
},
"south": {
"uv": [
0,
0,
2.0,
6.0
],
"texture": "#dark_metal"
},
"east": {
"uv": [
0,
0,
2.0,
6.0
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
2.0,
6.0
],
"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"
}
}
},
{
"from": [
4.0,
10.0,
24.0
],
"to": [
12.0,
14.0,
30.0
],
"faces": {
"north": {
"uv": [
0,
0,
8.0,
4.0
],
"texture": "#dark_metal"
},
"south": {
"uv": [
0,
0,
8.0,
4.0
],
"texture": "#dark_metal"
},
"east": {
"uv": [
0,
0,
6.0,
4.0
],
"texture": "#dark_metal"
},
"west": {
"uv": [
0,
0,
6.0,
4.0
],
"texture": "#dark_metal"
},
"up": {
"uv": [
0,
0,
8.0,
6.0
],
"texture": "#dark_metal"
},
"down": {
"uv": [
0,
0,
8.0,
6.0
],
"texture": "#dark_metal"
}
}
},
{
"from": [
1.0,
2.0,
28.0
],
"to": [
15.0,
6.0,
32.0
],
"faces": {
"north": {
"uv": [
0,
0,
14.0,
4.0
],
"texture": "#ru_khaki"
},
"south": {
"uv": [
0,
0,
14.0,
4.0
],
"texture": "#ru_khaki"
},
"east": {
"uv": [
0,
0,
4.0,
4.0
],
"texture": "#ru_khaki"
},
"west": {
"uv": [
0,
0,
4.0,
4.0
],
"texture": "#ru_khaki"
},
"up": {
"uv": [
0,
0,
14.0,
4.0
],
"texture": "#ru_khaki"
},
"down": {
"uv": [
0,
0,
14.0,
4.0
],
"texture": "#ru_khaki"
}
}
}
]
}
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 404 B

After

Width:  |  Height:  |  Size: 265 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 397 B

After

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 400 B

After

Width:  |  Height:  |  Size: 241 B

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