"|" means go

- Added Signals
- Nixie tubes no longer have a base plate
- Nixie tubes can now mount to walls
- Nixie tubes display signal info when mounted to a signal box
- Train speeds are now configurable
- More Jank patrol
- Track debug now on 'H' & 'J'
This commit is contained in:
simibubi 2022-02-16 03:14:31 +01:00
parent 033e7e1a0d
commit 34bc21658a
112 changed files with 4770 additions and 489 deletions

View file

@ -16,13 +16,13 @@ e555e3c2b2d3f01440e48db4ba88f7e00fd99b6f assets/create/blockstates/basin.json
f25693a9429f6337149ff24f27900dc4eb82a7c2 assets/create/blockstates/belt.json
cf9045eb16e5299a1d917c4cb536289f49411276 assets/create/blockstates/birch_window.json
94a1a91403eb4b035fec48071e7fcae57a8a6abd assets/create/blockstates/birch_window_pane.json
8d257089491a1f6e87544242c9fe9af0127b4f88 assets/create/blockstates/black_nixie_tube.json
95bada2b3bf55536f85e82bc6f9d16501b6e1a95 assets/create/blockstates/black_nixie_tube.json
e0f1e44c9bce4a7478592cf3a8ee7b91d9083d65 assets/create/blockstates/black_sail.json
58b07d2af6030342f0354f6d3fd0ee128d2d74b4 assets/create/blockstates/black_seat.json
73db8bd55bd5bd21f939ee9eb4b4b02209d9c5ed assets/create/blockstates/black_toolbox.json
a71ddf3291bd13d7877f2fe32c42f50407f99afb assets/create/blockstates/black_valve_handle.json
923aeb2a556f67bc0526f237dd97af2d37b4c9f1 assets/create/blockstates/blaze_burner.json
b619f127c38e9ffdb4e45bb32e5cea35863622f3 assets/create/blockstates/blue_nixie_tube.json
ea1a792572af1ee4c9831cd55825514d6568952d assets/create/blockstates/blue_nixie_tube.json
ec2ab87734acc209e6be3bc4898b1199f819bfd3 assets/create/blockstates/blue_sail.json
4854d1ef52130a7887aecc60bcaffbd66f0871a8 assets/create/blockstates/blue_seat.json
dea175335c5db0abe758cd208dc984c22506a176 assets/create/blockstates/blue_toolbox.json
@ -35,7 +35,7 @@ e69a71fdeb5855b2a59a31598f25eaea589c1748 assets/create/blockstates/brass_encased
288bad07593a8a2c8efaf44bba0ffb0011d36cd3 assets/create/blockstates/brass_encased_shaft.json
adfbd6cc5e44a0f431180aedbe65a19428299d8e assets/create/blockstates/brass_funnel.json
672eedcd3520c6d39603449165a23be9c612c620 assets/create/blockstates/brass_tunnel.json
9526a0758dcfda9fbbf75c01548e96bb5887a52f assets/create/blockstates/brown_nixie_tube.json
ffe31d5ad0486949b049cf2060d1f34ef7ceaa82 assets/create/blockstates/brown_nixie_tube.json
11ebdd9bd0815833e62ec1bea03a4cdd86ce00f3 assets/create/blockstates/brown_sail.json
e81608346d43406ee72cae0f78b8bcfb37ba2d75 assets/create/blockstates/brown_seat.json
bd73bfdbe88c58883cc15fe31a9dac7860482ca3 assets/create/blockstates/brown_toolbox.json
@ -181,7 +181,7 @@ ba66cf941ebb42b9b5426560f63215526de2996e assets/create/blockstates/cut_tuff_bric
d6a8c385c9ebc5bae603c908b6f8eccd6f5ad94b assets/create/blockstates/cut_veridium_slab.json
3f3ab7e6792c6ecbc0201b728a3dba091f56334f assets/create/blockstates/cut_veridium_stairs.json
62b181dcbb1f8de809be2625e8735ff3d7169a7d assets/create/blockstates/cut_veridium_wall.json
d986774dc41e5f01c6f3ffd10765df94f196922d assets/create/blockstates/cyan_nixie_tube.json
34adbe403ba4f36ca005e82997cc3b6b6fa17e36 assets/create/blockstates/cyan_nixie_tube.json
b496452f2f7dbbba385e1fc10b560ec266e4b5e7 assets/create/blockstates/cyan_sail.json
4de72f65bff4e5d9c8153fa3adeee6b61d6f912b assets/create/blockstates/cyan_seat.json
8e14112e948e492da8151b773c1fa40bf1467490 assets/create/blockstates/cyan_toolbox.json
@ -216,12 +216,12 @@ eca1f0e56efdadb241f42dc6ebb036f1d52213a9 assets/create/blockstates/gearbox.json
f34814b17cde3231a1dfb271f3dabf8d6de4fbf6 assets/create/blockstates/gearshift.json
93f8bdc22d9a5e04268964e35e4285c8cbf2b89d assets/create/blockstates/glass_fluid_pipe.json
f5928e309add6e414cf69e675cef9287750a427c assets/create/blockstates/granite_pillar.json
4478ee1b4c7a17deea77ee0d1234a19725889671 assets/create/blockstates/gray_nixie_tube.json
e506b85ed71dc4567295be3989f3302e57777ad9 assets/create/blockstates/gray_nixie_tube.json
5c40c4a27e1dec747a467dd251700c72a6ceb07d assets/create/blockstates/gray_sail.json
a5ec5401ba9f3e102a2e1b35837f643847afbca4 assets/create/blockstates/gray_seat.json
191d2cc56af51349688ccb2dea75801a9bc9de85 assets/create/blockstates/gray_toolbox.json
5f17a5868616b33eb157965a661046cab7a1427f assets/create/blockstates/gray_valve_handle.json
747579dd8e635533c15208cec25afe445ff4774a assets/create/blockstates/green_nixie_tube.json
497dd226b6520a6d754413508c74b98e50563e2f assets/create/blockstates/green_nixie_tube.json
52b849faef96b8ab9d9d64a1518c8f299af057b8 assets/create/blockstates/green_sail.json
13059309684db0cc7a0f1f4fce2407cf06cce80a assets/create/blockstates/green_seat.json
e91dcebe132d5b745df0f6c5b1c90d5fc4e8af52 assets/create/blockstates/green_toolbox.json
@ -253,17 +253,17 @@ aed03a18238b6635de06f351d872076248e94476 assets/create/blockstates/layered_scorc
b743ef11048fc284ba5622e1fbae3082f0616382 assets/create/blockstates/layered_tuff.json
21233210f6e68a47bb66207613c08df6cd97e796 assets/create/blockstates/layered_veridium.json
6a3c81d62c7c5a5fa2f4a1e239319d83875bbe55 assets/create/blockstates/lectern_controller.json
e0c8fc35bfa28f025bdc14085b01b179e36c9f96 assets/create/blockstates/light_blue_nixie_tube.json
2d1f10ee52f74a20021b9222781a772b19cc29a3 assets/create/blockstates/light_blue_nixie_tube.json
029904f21970947a4423a6e0c8c65c4e02f2e8e6 assets/create/blockstates/light_blue_sail.json
2a0a8b1715700bf1e284ee57ef9f7f163c12f3ee assets/create/blockstates/light_blue_seat.json
527f32e0d2b5b975cfeb515542098bb2d5224755 assets/create/blockstates/light_blue_toolbox.json
9bee040558a6b24e21f837fc808e17fae1883e71 assets/create/blockstates/light_blue_valve_handle.json
745b940c71575afbfac1786ffe1a23dcb62d5e70 assets/create/blockstates/light_gray_nixie_tube.json
bda5c5e9e42b31fdbb819484c74d457ba11fc9a0 assets/create/blockstates/light_gray_nixie_tube.json
93537c4e2ab86218a777e7b000c3fcd55a80b1cd assets/create/blockstates/light_gray_sail.json
d9a2551e001bb315d071bb9f1f013323a66a5d09 assets/create/blockstates/light_gray_seat.json
0c40d13637f00a533175d29ba67559461101ead5 assets/create/blockstates/light_gray_toolbox.json
8bea8c86de8c218c8932eef140f0ed439e173156 assets/create/blockstates/light_gray_valve_handle.json
3bee155fee49a9f85403f018a51e60c0e536d51c assets/create/blockstates/lime_nixie_tube.json
d023ef67d23da0b3e7b221b1b4ddf7f1f0c09ea7 assets/create/blockstates/lime_nixie_tube.json
ba2c4e3ddafa3c89a72cc243b14e8518fab369aa assets/create/blockstates/lime_sail.json
1de3a88c003df03f5006e1bbaa0236589aba08ad assets/create/blockstates/lime_seat.json
db46a5b6d0b595293a672236d0a64548b0816cab assets/create/blockstates/lime_toolbox.json
@ -272,7 +272,7 @@ e7cb0b25e511610b46dfd219e0cc5ea60a79d56b assets/create/blockstates/limestone.jso
bff90a8d674a839b13fd9cd1f78bf3d0ad9fad4f assets/create/blockstates/limestone_pillar.json
69790737767e06f000c7824749c46664a123160e assets/create/blockstates/linear_chassis.json
56b111c8a345627e9f37deac141138064271c2f1 assets/create/blockstates/lit_blaze_burner.json
e99e9c5cf03334a48d9d071e1590bc8f286d3cf6 assets/create/blockstates/magenta_nixie_tube.json
0210042f2801d262b011e48bfdceed0ac0cd09e2 assets/create/blockstates/magenta_nixie_tube.json
85a58ac539775f90903d9ce66374f3f2ffd4fecf assets/create/blockstates/magenta_sail.json
84c494d24cc58af274fdd054896c680e8095d2d0 assets/create/blockstates/magenta_seat.json
2334006c152d6773040ca03ef3b3d26a58f0dfa0 assets/create/blockstates/magenta_toolbox.json
@ -295,7 +295,7 @@ e20699a753e7b12abd4a881de473d494a4ffeaa9 assets/create/blockstates/metal_girder_
4e48ad0936647065c2322390e7c0fe115c853a98 assets/create/blockstates/millstone.json
468202df0802e17c75fcad0993daf1bc5300ca91 assets/create/blockstates/minecart_anchor.json
b1126c191877cff86b4e2de83e1fcbd151451cb7 assets/create/blockstates/mysterious_cuckoo_clock.json
f090a023bebb8590ed609d0c624277703b4699a4 assets/create/blockstates/nixie_tube.json
304e5e7b2927f3e8e8b8c6932c35c5c6892d2eb5 assets/create/blockstates/nixie_tube.json
36e46e65003a8d0b8555fe5e8f8dc980d6559bc5 assets/create/blockstates/nozzle.json
cf60989f63f02067fc4e4ad25033ac83167cdeb0 assets/create/blockstates/oak_window.json
4a796509c3953171f04f957351282205840b3760 assets/create/blockstates/oak_window_pane.json
@ -314,7 +314,7 @@ ed1a1d7a8b47027a1fcac2014e80f4e061d0f983 assets/create/blockstates/oxidized_copp
94761f4295416261080bc6a1b21a5790ac7104dc assets/create/blockstates/oxidized_copper_tile_stairs.json
9257b8d0d1edd9c707d1fc6c9819eca569d954e0 assets/create/blockstates/oxidized_copper_tiles.json
005cc195712aca252326ae8239ed0caf9a69a314 assets/create/blockstates/peculiar_bell.json
06ad2ce2f1730488d51daf12b4a985c86d43bbb4 assets/create/blockstates/pink_nixie_tube.json
1286ad485c73b70714094bb9d5ad411021856399 assets/create/blockstates/pink_nixie_tube.json
30971f2f76fe56f144178c33ad6bde5fc9fb61c3 assets/create/blockstates/pink_sail.json
919a79e4a4a5fab0aac3ef48e1c786017d6aa001 assets/create/blockstates/pink_seat.json
588ebcdb4c1d8d4c75225e92f26d6cf80cac2f15 assets/create/blockstates/pink_toolbox.json
@ -383,14 +383,14 @@ e8b0a401c10d1ba67ed71ba31bd5f9bc28571b65 assets/create/blockstates/powered_toggl
3a739f9d4276828d83f2d2750bf3227c87bcd438 assets/create/blockstates/pulley_magnet.json
dee3cdef860bb92d439ecaaec4300b42208b025c assets/create/blockstates/pulse_extender.json
638eb675fe3c464a0ab265c37f7d37fdf6440323 assets/create/blockstates/pulse_repeater.json
83ad917bb7f528e68d64f3859b3bf1236080d454 assets/create/blockstates/purple_nixie_tube.json
ea8200550190eb65d8631c7842e06d99274b3c79 assets/create/blockstates/purple_nixie_tube.json
d06cd9a1101b18d306a786320aab12018b1325d6 assets/create/blockstates/purple_sail.json
92957119abd5fbcca36a113b2a80255fd70fc303 assets/create/blockstates/purple_seat.json
b78c6057ef94b03f541a17e625b3778ca526a6ad assets/create/blockstates/purple_toolbox.json
61035f8afe75ff7bbd291da5d8690bcbebe679eb assets/create/blockstates/purple_valve_handle.json
4439fc83a8c7370ab44b211a3fd48abde20a4728 assets/create/blockstates/radial_chassis.json
c9ccf6fe4c80357ba2e4d053f5a1b35df4f377a8 assets/create/blockstates/raw_zinc_block.json
3735f396cf8e8bab0793ce2bfa281b29af73919e assets/create/blockstates/red_nixie_tube.json
9315e0004ad46eb4c855f452c7447db86ad23fe1 assets/create/blockstates/red_nixie_tube.json
45877c4d90a7185c2f304edbd67379d800920439 assets/create/blockstates/red_sail.json
da1b08387af7afa0855ee8d040f620c01f20660a assets/create/blockstates/red_seat.json
27fad7876f5a2de16f13dfde16d4a05dfe093989 assets/create/blockstates/red_toolbox.json
@ -482,6 +482,7 @@ e815bfd854c2653f10828bb11950f7fb991d7efc assets/create/blockstates/stressometer.
8b0c2c7ac72529565b3339aa8df7565858100afa assets/create/blockstates/tiled_glass.json
a2454400b1cf9889f70aebdc89c52a1be25f543c assets/create/blockstates/tiled_glass_pane.json
85b57776edf426c2f8df6698b2482ea925914a5c assets/create/blockstates/track.json
5a61450b6f6aac63f75580f8dcbc3d3fabfd54d8 assets/create/blockstates/track_signal.json
aa08785f906d41933e0dd1086ea7b08f5b93aa24 assets/create/blockstates/track_station.json
29af21c8d82891139d48d69f0393f612f2b6f8f1 assets/create/blockstates/tuff_pillar.json
a8094531617e27a545c4815ab2062bf0ffca3633 assets/create/blockstates/turntable.json
@ -523,36 +524,36 @@ f2a261f2f2daeab2a6ac403497c469364d2bfaaa assets/create/blockstates/weathered_cop
d7588ea4a82633c38c7a33f17d4c1c2876d7f6a9 assets/create/blockstates/weathered_copper_tile_stairs.json
3d4fec3f32782c7158b10baf768ce85b3232d8fe assets/create/blockstates/weathered_copper_tiles.json
c838c0792511ca2e14493b40032bb1370fac588a assets/create/blockstates/weighted_ejector.json
aef042718ae54973cbafdb4507c32944d722e99d assets/create/blockstates/white_nixie_tube.json
1ed177e00c30ab8ca44ad4041cd95084a86b810c assets/create/blockstates/white_nixie_tube.json
512bf17c9ea309b1f7da54440f923530d25e467c assets/create/blockstates/white_sail.json
4647010162eb4c350fad236d860317eaa1884c77 assets/create/blockstates/white_seat.json
3695510f11231c8a5c1a0be94a92703e4b5a0f9c assets/create/blockstates/white_toolbox.json
89000903d0ab8139e919abea7aa0361b34c24e55 assets/create/blockstates/white_valve_handle.json
c4cd1131113667da0180898b5db3ebad609db8ba assets/create/blockstates/windmill_bearing.json
d4f804f2818376950ef28fc8d6250419f4e12218 assets/create/blockstates/wooden_bracket.json
de1557d79eebf1cd469d098639cd6b5518b52b61 assets/create/blockstates/yellow_nixie_tube.json
21cbde8ab2ab1bebe8bd36b23d1b480091fa9d57 assets/create/blockstates/yellow_nixie_tube.json
e03c48512967845fce09d84b955d3bc7b480fedc assets/create/blockstates/yellow_sail.json
a3a11524cd3515fc01d905767b4b7ea782adaf03 assets/create/blockstates/yellow_seat.json
bf2b0310500213ff853c748c236eb5d01f61658e assets/create/blockstates/yellow_toolbox.json
6801fa1f466f172700e573e5b8ee8ee5f9ca4583 assets/create/blockstates/yellow_valve_handle.json
7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json
b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json
99fe404c85879934693a6afca6c0088e04c50657 assets/create/lang/en_ud.json
a66727961d19361e9f6fc2a81a93053f11155141 assets/create/lang/en_us.json
40e345f3514d00a6de7ee6ccd07af0991155042f assets/create/lang/unfinished/de_de.json
7e9c89a7b70fab85346c30258d9db728bcdd0a11 assets/create/lang/unfinished/es_cl.json
e0cd89e2e67a7a6e1b744a7f44bea4dbc6861011 assets/create/lang/unfinished/es_es.json
76401cc86ef9545a382094dd128779f1af05f489 assets/create/lang/unfinished/fr_fr.json
763380d38ee082a85fa28a74db3d1fa3a6f8e931 assets/create/lang/unfinished/it_it.json
4afbee011c0877633241ea3655f1c97b5431f608 assets/create/lang/unfinished/ja_jp.json
b3fc6f2fcb5dfb357fb066d9665e4adc487515df assets/create/lang/unfinished/ko_kr.json
62db40a1b598ebab022156ba3849cfe9ceb8e1a9 assets/create/lang/unfinished/nl_nl.json
075f756c2b25f8abf8684a9f967c8dba706540c8 assets/create/lang/unfinished/pl_pl.json
bb7a09bac75414ea509f960abb0ef902c939f00b assets/create/lang/unfinished/pt_br.json
ec9eca6a8e36457857f8f6dd03c8f16d8a583d3a assets/create/lang/unfinished/pt_pt.json
47a78bac16ed55a4a14c04273e9e6226668699ca assets/create/lang/unfinished/ru_ru.json
6c11045cd143c80bfe8fbf84e58403dda58cb6e5 assets/create/lang/unfinished/zh_cn.json
8d4484b00acdad79717093384fcc3db0d96ba67b assets/create/lang/unfinished/zh_tw.json
8d5cb91338bccfa4f3acfd048b28e08acc9a82b7 assets/create/lang/en_ud.json
4a5c5a6f4677bf4f6fe40acfe93bda03ea5568e0 assets/create/lang/en_us.json
645c1f48d82161f920bda0cff4bfe9e46aba6416 assets/create/lang/unfinished/de_de.json
9aeeaff96624e945cf0018b36b7a817169001ef2 assets/create/lang/unfinished/es_cl.json
34dbc3806e178e33ea35fdad0f018ff5b8dfccd0 assets/create/lang/unfinished/es_es.json
8e054f9fc4c1b937f9b35c87c0d13aac09e175df assets/create/lang/unfinished/fr_fr.json
35492c408d1abdf11ef9f82fd4eb4444e467575e assets/create/lang/unfinished/it_it.json
e1176e97d402311c798f1e5bdd0fc86b2fe230f2 assets/create/lang/unfinished/ja_jp.json
dbf8fee3b62bfac529cd15ce324b52ce62d79a3e assets/create/lang/unfinished/ko_kr.json
4a7baacd9fa0112b5a2c82670e46ce27e4ebfaa9 assets/create/lang/unfinished/nl_nl.json
68bb201f1e6b5d549dd0da5eecf5bd93279fc51b assets/create/lang/unfinished/pl_pl.json
23717bc699dbb33f3b1b7c1ea256eaa3d2351f17 assets/create/lang/unfinished/pt_br.json
b6477a01032733848b11b3f669b44bf7a67f6512 assets/create/lang/unfinished/pt_pt.json
58a008a6683a807b3e52afaa536821fee82e7700 assets/create/lang/unfinished/ru_ru.json
7123ac611ea8c2ce7a100c09a2f7213bead8bb35 assets/create/lang/unfinished/zh_cn.json
42a371f8007daa1101b8664c96ace6ba9eb2188f assets/create/lang/unfinished/zh_tw.json
487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json
b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.json
3066db1bf03cffa1a9c7fbacf47ae586632f4eb3 assets/create/models/block/acacia_window_pane_noside_alt.json
@ -2077,6 +2078,7 @@ bab8f78c319b2a79ed55c5d2a94b521ddaa44996 assets/create/models/item/stressometer.
b1d3d00ff05908feacad06a86800da96cc9bc65d assets/create/models/item/tiled_glass.json
a7d0b746637897209bd86b1a6501ecbfb46d8270 assets/create/models/item/tiled_glass_pane.json
6b5569f25fa2d905729a3f18deb56b6c67c5dfa4 assets/create/models/item/track.json
c317adb86ee47765dd7716539c65f31f329deb85 assets/create/models/item/track_signal.json
d6364e9d11915e53dafd8761f016e4b23c7703c8 assets/create/models/item/track_station.json
f8a4fa1ccecb16a3941cc46db7481ed8e8429a5e assets/create/models/item/tree_fertilizer.json
3f6810da54724de551591b46cd5b47a98a4737ef assets/create/models/item/tuff_pillar.json
@ -3766,6 +3768,7 @@ da3ceb80799d349b91781b0dd43a02e548045c66 data/create/loot_tables/blocks/stressom
811674fd816503cd78fc4df267dc23f760940e8f data/create/loot_tables/blocks/tiled_glass.json
313344ef4ee67ffd0f7fd44adcb3ad08de571c92 data/create/loot_tables/blocks/tiled_glass_pane.json
e2846b8823918bce402eb361f703ecdc14251ccc data/create/loot_tables/blocks/track.json
f589afc404f98c42d2d9b0b03bcac87f7f6444cc data/create/loot_tables/blocks/track_signal.json
4617a11e220dcd0094c29d204fe90c01495c4e9b data/create/loot_tables/blocks/track_station.json
8fbe59bc77b029b802c43fb8a930778dede440ea data/create/loot_tables/blocks/tuff_pillar.json
2419d50b6086e92ab05624fdf38ef2b55c0b0944 data/create/loot_tables/blocks/turntable.json
@ -5279,7 +5282,7 @@ ff1900963bc4cd8ceffa78d58ef1952ceacb2fb7 data/forge/tags/items/storage_blocks/br
69f596fcb065e26b02ce246760432b5174191b76 data/minecraft/tags/blocks/impermeable.json
2db7759fe036160c14c6ed19a68604ca16f4de60 data/minecraft/tags/blocks/lush_ground_replaceable.json
02f7a9df2f9e154749266e7ac59c37aa076a3390 data/minecraft/tags/blocks/mineable/axe.json
8609b989da9a0a1a2394c157483e89df83eff240 data/minecraft/tags/blocks/mineable/pickaxe.json
99f0f8d72017ec54567b75f10975b2794a33a424 data/minecraft/tags/blocks/mineable/pickaxe.json
2db7759fe036160c14c6ed19a68604ca16f4de60 data/minecraft/tags/blocks/moss_replaceable.json
e157c1d3af30e409e34bbefbe15a037e6e1c8daa data/minecraft/tags/blocks/needs_iron_tool.json
a08f67865337f62601c5e333b4011382d10020e4 data/minecraft/tags/blocks/needs_stone_tool.json

View file

@ -1,35 +1,145 @@
{
"variants": {
"ceiling=false,facing=north": {
"double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/black_nixie_tube",
"y": 180
},
"ceiling=true,facing=north": {
"double_face=wall,facing=north,waterlogged=false": {
"model": "create:block/black_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=false": {
"model": "create:block/black_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=false": {
"model": "create:block/black_nixie_tube",
"x": 180,
"y": 180
},
"ceiling=false,facing=south": {
"double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/black_nixie_tube"
},
"ceiling=true,facing=south": {
"double_face=wall,facing=south,waterlogged=false": {
"model": "create:block/black_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=false": {
"model": "create:block/black_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=false": {
"model": "create:block/black_nixie_tube",
"x": 180
},
"ceiling=false,facing=west": {
"double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/black_nixie_tube",
"y": 90
},
"ceiling=true,facing=west": {
"double_face=wall,facing=west,waterlogged=false": {
"model": "create:block/black_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=false": {
"model": "create:block/black_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=false": {
"model": "create:block/black_nixie_tube",
"x": 180,
"y": 90
},
"ceiling=false,facing=east": {
"double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/black_nixie_tube",
"y": 270
},
"ceiling=true,facing=east": {
"double_face=wall,facing=east,waterlogged=false": {
"model": "create:block/black_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=false": {
"model": "create:block/black_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=false": {
"model": "create:block/black_nixie_tube",
"x": 180,
"y": 270
},
"double_face=floor,facing=north,waterlogged=true": {
"model": "create:block/black_nixie_tube",
"y": 180
},
"double_face=wall,facing=north,waterlogged=true": {
"model": "create:block/black_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=true": {
"model": "create:block/black_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=true": {
"model": "create:block/black_nixie_tube",
"x": 180,
"y": 180
},
"double_face=floor,facing=south,waterlogged=true": {
"model": "create:block/black_nixie_tube"
},
"double_face=wall,facing=south,waterlogged=true": {
"model": "create:block/black_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=true": {
"model": "create:block/black_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=true": {
"model": "create:block/black_nixie_tube",
"x": 180
},
"double_face=floor,facing=west,waterlogged=true": {
"model": "create:block/black_nixie_tube",
"y": 90
},
"double_face=wall,facing=west,waterlogged=true": {
"model": "create:block/black_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=true": {
"model": "create:block/black_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=true": {
"model": "create:block/black_nixie_tube",
"x": 180,
"y": 90
},
"double_face=floor,facing=east,waterlogged=true": {
"model": "create:block/black_nixie_tube",
"y": 270
},
"double_face=wall,facing=east,waterlogged=true": {
"model": "create:block/black_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=true": {
"model": "create:block/black_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=true": {
"model": "create:block/black_nixie_tube",
"x": 180,
"y": 270

View file

@ -1,35 +1,145 @@
{
"variants": {
"ceiling=false,facing=north": {
"double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/blue_nixie_tube",
"y": 180
},
"ceiling=true,facing=north": {
"double_face=wall,facing=north,waterlogged=false": {
"model": "create:block/blue_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=false": {
"model": "create:block/blue_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=false": {
"model": "create:block/blue_nixie_tube",
"x": 180,
"y": 180
},
"ceiling=false,facing=south": {
"double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/blue_nixie_tube"
},
"ceiling=true,facing=south": {
"double_face=wall,facing=south,waterlogged=false": {
"model": "create:block/blue_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=false": {
"model": "create:block/blue_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=false": {
"model": "create:block/blue_nixie_tube",
"x": 180
},
"ceiling=false,facing=west": {
"double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/blue_nixie_tube",
"y": 90
},
"ceiling=true,facing=west": {
"double_face=wall,facing=west,waterlogged=false": {
"model": "create:block/blue_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=false": {
"model": "create:block/blue_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=false": {
"model": "create:block/blue_nixie_tube",
"x": 180,
"y": 90
},
"ceiling=false,facing=east": {
"double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/blue_nixie_tube",
"y": 270
},
"ceiling=true,facing=east": {
"double_face=wall,facing=east,waterlogged=false": {
"model": "create:block/blue_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=false": {
"model": "create:block/blue_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=false": {
"model": "create:block/blue_nixie_tube",
"x": 180,
"y": 270
},
"double_face=floor,facing=north,waterlogged=true": {
"model": "create:block/blue_nixie_tube",
"y": 180
},
"double_face=wall,facing=north,waterlogged=true": {
"model": "create:block/blue_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=true": {
"model": "create:block/blue_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=true": {
"model": "create:block/blue_nixie_tube",
"x": 180,
"y": 180
},
"double_face=floor,facing=south,waterlogged=true": {
"model": "create:block/blue_nixie_tube"
},
"double_face=wall,facing=south,waterlogged=true": {
"model": "create:block/blue_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=true": {
"model": "create:block/blue_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=true": {
"model": "create:block/blue_nixie_tube",
"x": 180
},
"double_face=floor,facing=west,waterlogged=true": {
"model": "create:block/blue_nixie_tube",
"y": 90
},
"double_face=wall,facing=west,waterlogged=true": {
"model": "create:block/blue_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=true": {
"model": "create:block/blue_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=true": {
"model": "create:block/blue_nixie_tube",
"x": 180,
"y": 90
},
"double_face=floor,facing=east,waterlogged=true": {
"model": "create:block/blue_nixie_tube",
"y": 270
},
"double_face=wall,facing=east,waterlogged=true": {
"model": "create:block/blue_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=true": {
"model": "create:block/blue_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=true": {
"model": "create:block/blue_nixie_tube",
"x": 180,
"y": 270

View file

@ -1,35 +1,145 @@
{
"variants": {
"ceiling=false,facing=north": {
"double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/brown_nixie_tube",
"y": 180
},
"ceiling=true,facing=north": {
"double_face=wall,facing=north,waterlogged=false": {
"model": "create:block/brown_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=false": {
"model": "create:block/brown_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=false": {
"model": "create:block/brown_nixie_tube",
"x": 180,
"y": 180
},
"ceiling=false,facing=south": {
"double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/brown_nixie_tube"
},
"ceiling=true,facing=south": {
"double_face=wall,facing=south,waterlogged=false": {
"model": "create:block/brown_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=false": {
"model": "create:block/brown_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=false": {
"model": "create:block/brown_nixie_tube",
"x": 180
},
"ceiling=false,facing=west": {
"double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/brown_nixie_tube",
"y": 90
},
"ceiling=true,facing=west": {
"double_face=wall,facing=west,waterlogged=false": {
"model": "create:block/brown_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=false": {
"model": "create:block/brown_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=false": {
"model": "create:block/brown_nixie_tube",
"x": 180,
"y": 90
},
"ceiling=false,facing=east": {
"double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/brown_nixie_tube",
"y": 270
},
"ceiling=true,facing=east": {
"double_face=wall,facing=east,waterlogged=false": {
"model": "create:block/brown_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=false": {
"model": "create:block/brown_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=false": {
"model": "create:block/brown_nixie_tube",
"x": 180,
"y": 270
},
"double_face=floor,facing=north,waterlogged=true": {
"model": "create:block/brown_nixie_tube",
"y": 180
},
"double_face=wall,facing=north,waterlogged=true": {
"model": "create:block/brown_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=true": {
"model": "create:block/brown_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=true": {
"model": "create:block/brown_nixie_tube",
"x": 180,
"y": 180
},
"double_face=floor,facing=south,waterlogged=true": {
"model": "create:block/brown_nixie_tube"
},
"double_face=wall,facing=south,waterlogged=true": {
"model": "create:block/brown_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=true": {
"model": "create:block/brown_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=true": {
"model": "create:block/brown_nixie_tube",
"x": 180
},
"double_face=floor,facing=west,waterlogged=true": {
"model": "create:block/brown_nixie_tube",
"y": 90
},
"double_face=wall,facing=west,waterlogged=true": {
"model": "create:block/brown_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=true": {
"model": "create:block/brown_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=true": {
"model": "create:block/brown_nixie_tube",
"x": 180,
"y": 90
},
"double_face=floor,facing=east,waterlogged=true": {
"model": "create:block/brown_nixie_tube",
"y": 270
},
"double_face=wall,facing=east,waterlogged=true": {
"model": "create:block/brown_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=true": {
"model": "create:block/brown_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=true": {
"model": "create:block/brown_nixie_tube",
"x": 180,
"y": 270

View file

@ -1,35 +1,145 @@
{
"variants": {
"ceiling=false,facing=north": {
"double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/cyan_nixie_tube",
"y": 180
},
"ceiling=true,facing=north": {
"double_face=wall,facing=north,waterlogged=false": {
"model": "create:block/cyan_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=false": {
"model": "create:block/cyan_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=false": {
"model": "create:block/cyan_nixie_tube",
"x": 180,
"y": 180
},
"ceiling=false,facing=south": {
"double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/cyan_nixie_tube"
},
"ceiling=true,facing=south": {
"double_face=wall,facing=south,waterlogged=false": {
"model": "create:block/cyan_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=false": {
"model": "create:block/cyan_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=false": {
"model": "create:block/cyan_nixie_tube",
"x": 180
},
"ceiling=false,facing=west": {
"double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/cyan_nixie_tube",
"y": 90
},
"ceiling=true,facing=west": {
"double_face=wall,facing=west,waterlogged=false": {
"model": "create:block/cyan_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=false": {
"model": "create:block/cyan_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=false": {
"model": "create:block/cyan_nixie_tube",
"x": 180,
"y": 90
},
"ceiling=false,facing=east": {
"double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/cyan_nixie_tube",
"y": 270
},
"ceiling=true,facing=east": {
"double_face=wall,facing=east,waterlogged=false": {
"model": "create:block/cyan_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=false": {
"model": "create:block/cyan_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=false": {
"model": "create:block/cyan_nixie_tube",
"x": 180,
"y": 270
},
"double_face=floor,facing=north,waterlogged=true": {
"model": "create:block/cyan_nixie_tube",
"y": 180
},
"double_face=wall,facing=north,waterlogged=true": {
"model": "create:block/cyan_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=true": {
"model": "create:block/cyan_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=true": {
"model": "create:block/cyan_nixie_tube",
"x": 180,
"y": 180
},
"double_face=floor,facing=south,waterlogged=true": {
"model": "create:block/cyan_nixie_tube"
},
"double_face=wall,facing=south,waterlogged=true": {
"model": "create:block/cyan_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=true": {
"model": "create:block/cyan_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=true": {
"model": "create:block/cyan_nixie_tube",
"x": 180
},
"double_face=floor,facing=west,waterlogged=true": {
"model": "create:block/cyan_nixie_tube",
"y": 90
},
"double_face=wall,facing=west,waterlogged=true": {
"model": "create:block/cyan_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=true": {
"model": "create:block/cyan_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=true": {
"model": "create:block/cyan_nixie_tube",
"x": 180,
"y": 90
},
"double_face=floor,facing=east,waterlogged=true": {
"model": "create:block/cyan_nixie_tube",
"y": 270
},
"double_face=wall,facing=east,waterlogged=true": {
"model": "create:block/cyan_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=true": {
"model": "create:block/cyan_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=true": {
"model": "create:block/cyan_nixie_tube",
"x": 180,
"y": 270

View file

@ -1,35 +1,145 @@
{
"variants": {
"ceiling=false,facing=north": {
"double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/gray_nixie_tube",
"y": 180
},
"ceiling=true,facing=north": {
"double_face=wall,facing=north,waterlogged=false": {
"model": "create:block/gray_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=false": {
"model": "create:block/gray_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=false": {
"model": "create:block/gray_nixie_tube",
"x": 180,
"y": 180
},
"ceiling=false,facing=south": {
"double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/gray_nixie_tube"
},
"ceiling=true,facing=south": {
"double_face=wall,facing=south,waterlogged=false": {
"model": "create:block/gray_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=false": {
"model": "create:block/gray_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=false": {
"model": "create:block/gray_nixie_tube",
"x": 180
},
"ceiling=false,facing=west": {
"double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/gray_nixie_tube",
"y": 90
},
"ceiling=true,facing=west": {
"double_face=wall,facing=west,waterlogged=false": {
"model": "create:block/gray_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=false": {
"model": "create:block/gray_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=false": {
"model": "create:block/gray_nixie_tube",
"x": 180,
"y": 90
},
"ceiling=false,facing=east": {
"double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/gray_nixie_tube",
"y": 270
},
"ceiling=true,facing=east": {
"double_face=wall,facing=east,waterlogged=false": {
"model": "create:block/gray_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=false": {
"model": "create:block/gray_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=false": {
"model": "create:block/gray_nixie_tube",
"x": 180,
"y": 270
},
"double_face=floor,facing=north,waterlogged=true": {
"model": "create:block/gray_nixie_tube",
"y": 180
},
"double_face=wall,facing=north,waterlogged=true": {
"model": "create:block/gray_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=true": {
"model": "create:block/gray_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=true": {
"model": "create:block/gray_nixie_tube",
"x": 180,
"y": 180
},
"double_face=floor,facing=south,waterlogged=true": {
"model": "create:block/gray_nixie_tube"
},
"double_face=wall,facing=south,waterlogged=true": {
"model": "create:block/gray_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=true": {
"model": "create:block/gray_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=true": {
"model": "create:block/gray_nixie_tube",
"x": 180
},
"double_face=floor,facing=west,waterlogged=true": {
"model": "create:block/gray_nixie_tube",
"y": 90
},
"double_face=wall,facing=west,waterlogged=true": {
"model": "create:block/gray_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=true": {
"model": "create:block/gray_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=true": {
"model": "create:block/gray_nixie_tube",
"x": 180,
"y": 90
},
"double_face=floor,facing=east,waterlogged=true": {
"model": "create:block/gray_nixie_tube",
"y": 270
},
"double_face=wall,facing=east,waterlogged=true": {
"model": "create:block/gray_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=true": {
"model": "create:block/gray_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=true": {
"model": "create:block/gray_nixie_tube",
"x": 180,
"y": 270

View file

@ -1,35 +1,145 @@
{
"variants": {
"ceiling=false,facing=north": {
"double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/green_nixie_tube",
"y": 180
},
"ceiling=true,facing=north": {
"double_face=wall,facing=north,waterlogged=false": {
"model": "create:block/green_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=false": {
"model": "create:block/green_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=false": {
"model": "create:block/green_nixie_tube",
"x": 180,
"y": 180
},
"ceiling=false,facing=south": {
"double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/green_nixie_tube"
},
"ceiling=true,facing=south": {
"double_face=wall,facing=south,waterlogged=false": {
"model": "create:block/green_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=false": {
"model": "create:block/green_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=false": {
"model": "create:block/green_nixie_tube",
"x": 180
},
"ceiling=false,facing=west": {
"double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/green_nixie_tube",
"y": 90
},
"ceiling=true,facing=west": {
"double_face=wall,facing=west,waterlogged=false": {
"model": "create:block/green_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=false": {
"model": "create:block/green_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=false": {
"model": "create:block/green_nixie_tube",
"x": 180,
"y": 90
},
"ceiling=false,facing=east": {
"double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/green_nixie_tube",
"y": 270
},
"ceiling=true,facing=east": {
"double_face=wall,facing=east,waterlogged=false": {
"model": "create:block/green_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=false": {
"model": "create:block/green_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=false": {
"model": "create:block/green_nixie_tube",
"x": 180,
"y": 270
},
"double_face=floor,facing=north,waterlogged=true": {
"model": "create:block/green_nixie_tube",
"y": 180
},
"double_face=wall,facing=north,waterlogged=true": {
"model": "create:block/green_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=true": {
"model": "create:block/green_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=true": {
"model": "create:block/green_nixie_tube",
"x": 180,
"y": 180
},
"double_face=floor,facing=south,waterlogged=true": {
"model": "create:block/green_nixie_tube"
},
"double_face=wall,facing=south,waterlogged=true": {
"model": "create:block/green_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=true": {
"model": "create:block/green_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=true": {
"model": "create:block/green_nixie_tube",
"x": 180
},
"double_face=floor,facing=west,waterlogged=true": {
"model": "create:block/green_nixie_tube",
"y": 90
},
"double_face=wall,facing=west,waterlogged=true": {
"model": "create:block/green_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=true": {
"model": "create:block/green_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=true": {
"model": "create:block/green_nixie_tube",
"x": 180,
"y": 90
},
"double_face=floor,facing=east,waterlogged=true": {
"model": "create:block/green_nixie_tube",
"y": 270
},
"double_face=wall,facing=east,waterlogged=true": {
"model": "create:block/green_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=true": {
"model": "create:block/green_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=true": {
"model": "create:block/green_nixie_tube",
"x": 180,
"y": 270

View file

@ -1,35 +1,145 @@
{
"variants": {
"ceiling=false,facing=north": {
"double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/light_blue_nixie_tube",
"y": 180
},
"ceiling=true,facing=north": {
"double_face=wall,facing=north,waterlogged=false": {
"model": "create:block/light_blue_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=false": {
"model": "create:block/light_blue_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=false": {
"model": "create:block/light_blue_nixie_tube",
"x": 180,
"y": 180
},
"ceiling=false,facing=south": {
"double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/light_blue_nixie_tube"
},
"ceiling=true,facing=south": {
"double_face=wall,facing=south,waterlogged=false": {
"model": "create:block/light_blue_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=false": {
"model": "create:block/light_blue_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=false": {
"model": "create:block/light_blue_nixie_tube",
"x": 180
},
"ceiling=false,facing=west": {
"double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/light_blue_nixie_tube",
"y": 90
},
"ceiling=true,facing=west": {
"double_face=wall,facing=west,waterlogged=false": {
"model": "create:block/light_blue_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=false": {
"model": "create:block/light_blue_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=false": {
"model": "create:block/light_blue_nixie_tube",
"x": 180,
"y": 90
},
"ceiling=false,facing=east": {
"double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/light_blue_nixie_tube",
"y": 270
},
"ceiling=true,facing=east": {
"double_face=wall,facing=east,waterlogged=false": {
"model": "create:block/light_blue_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=false": {
"model": "create:block/light_blue_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=false": {
"model": "create:block/light_blue_nixie_tube",
"x": 180,
"y": 270
},
"double_face=floor,facing=north,waterlogged=true": {
"model": "create:block/light_blue_nixie_tube",
"y": 180
},
"double_face=wall,facing=north,waterlogged=true": {
"model": "create:block/light_blue_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=true": {
"model": "create:block/light_blue_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=true": {
"model": "create:block/light_blue_nixie_tube",
"x": 180,
"y": 180
},
"double_face=floor,facing=south,waterlogged=true": {
"model": "create:block/light_blue_nixie_tube"
},
"double_face=wall,facing=south,waterlogged=true": {
"model": "create:block/light_blue_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=true": {
"model": "create:block/light_blue_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=true": {
"model": "create:block/light_blue_nixie_tube",
"x": 180
},
"double_face=floor,facing=west,waterlogged=true": {
"model": "create:block/light_blue_nixie_tube",
"y": 90
},
"double_face=wall,facing=west,waterlogged=true": {
"model": "create:block/light_blue_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=true": {
"model": "create:block/light_blue_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=true": {
"model": "create:block/light_blue_nixie_tube",
"x": 180,
"y": 90
},
"double_face=floor,facing=east,waterlogged=true": {
"model": "create:block/light_blue_nixie_tube",
"y": 270
},
"double_face=wall,facing=east,waterlogged=true": {
"model": "create:block/light_blue_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=true": {
"model": "create:block/light_blue_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=true": {
"model": "create:block/light_blue_nixie_tube",
"x": 180,
"y": 270

View file

@ -1,35 +1,145 @@
{
"variants": {
"ceiling=false,facing=north": {
"double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/light_gray_nixie_tube",
"y": 180
},
"ceiling=true,facing=north": {
"double_face=wall,facing=north,waterlogged=false": {
"model": "create:block/light_gray_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=false": {
"model": "create:block/light_gray_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=false": {
"model": "create:block/light_gray_nixie_tube",
"x": 180,
"y": 180
},
"ceiling=false,facing=south": {
"double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/light_gray_nixie_tube"
},
"ceiling=true,facing=south": {
"double_face=wall,facing=south,waterlogged=false": {
"model": "create:block/light_gray_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=false": {
"model": "create:block/light_gray_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=false": {
"model": "create:block/light_gray_nixie_tube",
"x": 180
},
"ceiling=false,facing=west": {
"double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/light_gray_nixie_tube",
"y": 90
},
"ceiling=true,facing=west": {
"double_face=wall,facing=west,waterlogged=false": {
"model": "create:block/light_gray_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=false": {
"model": "create:block/light_gray_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=false": {
"model": "create:block/light_gray_nixie_tube",
"x": 180,
"y": 90
},
"ceiling=false,facing=east": {
"double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/light_gray_nixie_tube",
"y": 270
},
"ceiling=true,facing=east": {
"double_face=wall,facing=east,waterlogged=false": {
"model": "create:block/light_gray_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=false": {
"model": "create:block/light_gray_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=false": {
"model": "create:block/light_gray_nixie_tube",
"x": 180,
"y": 270
},
"double_face=floor,facing=north,waterlogged=true": {
"model": "create:block/light_gray_nixie_tube",
"y": 180
},
"double_face=wall,facing=north,waterlogged=true": {
"model": "create:block/light_gray_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=true": {
"model": "create:block/light_gray_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=true": {
"model": "create:block/light_gray_nixie_tube",
"x": 180,
"y": 180
},
"double_face=floor,facing=south,waterlogged=true": {
"model": "create:block/light_gray_nixie_tube"
},
"double_face=wall,facing=south,waterlogged=true": {
"model": "create:block/light_gray_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=true": {
"model": "create:block/light_gray_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=true": {
"model": "create:block/light_gray_nixie_tube",
"x": 180
},
"double_face=floor,facing=west,waterlogged=true": {
"model": "create:block/light_gray_nixie_tube",
"y": 90
},
"double_face=wall,facing=west,waterlogged=true": {
"model": "create:block/light_gray_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=true": {
"model": "create:block/light_gray_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=true": {
"model": "create:block/light_gray_nixie_tube",
"x": 180,
"y": 90
},
"double_face=floor,facing=east,waterlogged=true": {
"model": "create:block/light_gray_nixie_tube",
"y": 270
},
"double_face=wall,facing=east,waterlogged=true": {
"model": "create:block/light_gray_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=true": {
"model": "create:block/light_gray_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=true": {
"model": "create:block/light_gray_nixie_tube",
"x": 180,
"y": 270

View file

@ -1,35 +1,145 @@
{
"variants": {
"ceiling=false,facing=north": {
"double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/lime_nixie_tube",
"y": 180
},
"ceiling=true,facing=north": {
"double_face=wall,facing=north,waterlogged=false": {
"model": "create:block/lime_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=false": {
"model": "create:block/lime_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=false": {
"model": "create:block/lime_nixie_tube",
"x": 180,
"y": 180
},
"ceiling=false,facing=south": {
"double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/lime_nixie_tube"
},
"ceiling=true,facing=south": {
"double_face=wall,facing=south,waterlogged=false": {
"model": "create:block/lime_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=false": {
"model": "create:block/lime_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=false": {
"model": "create:block/lime_nixie_tube",
"x": 180
},
"ceiling=false,facing=west": {
"double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/lime_nixie_tube",
"y": 90
},
"ceiling=true,facing=west": {
"double_face=wall,facing=west,waterlogged=false": {
"model": "create:block/lime_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=false": {
"model": "create:block/lime_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=false": {
"model": "create:block/lime_nixie_tube",
"x": 180,
"y": 90
},
"ceiling=false,facing=east": {
"double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/lime_nixie_tube",
"y": 270
},
"ceiling=true,facing=east": {
"double_face=wall,facing=east,waterlogged=false": {
"model": "create:block/lime_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=false": {
"model": "create:block/lime_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=false": {
"model": "create:block/lime_nixie_tube",
"x": 180,
"y": 270
},
"double_face=floor,facing=north,waterlogged=true": {
"model": "create:block/lime_nixie_tube",
"y": 180
},
"double_face=wall,facing=north,waterlogged=true": {
"model": "create:block/lime_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=true": {
"model": "create:block/lime_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=true": {
"model": "create:block/lime_nixie_tube",
"x": 180,
"y": 180
},
"double_face=floor,facing=south,waterlogged=true": {
"model": "create:block/lime_nixie_tube"
},
"double_face=wall,facing=south,waterlogged=true": {
"model": "create:block/lime_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=true": {
"model": "create:block/lime_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=true": {
"model": "create:block/lime_nixie_tube",
"x": 180
},
"double_face=floor,facing=west,waterlogged=true": {
"model": "create:block/lime_nixie_tube",
"y": 90
},
"double_face=wall,facing=west,waterlogged=true": {
"model": "create:block/lime_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=true": {
"model": "create:block/lime_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=true": {
"model": "create:block/lime_nixie_tube",
"x": 180,
"y": 90
},
"double_face=floor,facing=east,waterlogged=true": {
"model": "create:block/lime_nixie_tube",
"y": 270
},
"double_face=wall,facing=east,waterlogged=true": {
"model": "create:block/lime_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=true": {
"model": "create:block/lime_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=true": {
"model": "create:block/lime_nixie_tube",
"x": 180,
"y": 270

View file

@ -1,35 +1,145 @@
{
"variants": {
"ceiling=false,facing=north": {
"double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/magenta_nixie_tube",
"y": 180
},
"ceiling=true,facing=north": {
"double_face=wall,facing=north,waterlogged=false": {
"model": "create:block/magenta_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=false": {
"model": "create:block/magenta_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=false": {
"model": "create:block/magenta_nixie_tube",
"x": 180,
"y": 180
},
"ceiling=false,facing=south": {
"double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/magenta_nixie_tube"
},
"ceiling=true,facing=south": {
"double_face=wall,facing=south,waterlogged=false": {
"model": "create:block/magenta_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=false": {
"model": "create:block/magenta_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=false": {
"model": "create:block/magenta_nixie_tube",
"x": 180
},
"ceiling=false,facing=west": {
"double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/magenta_nixie_tube",
"y": 90
},
"ceiling=true,facing=west": {
"double_face=wall,facing=west,waterlogged=false": {
"model": "create:block/magenta_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=false": {
"model": "create:block/magenta_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=false": {
"model": "create:block/magenta_nixie_tube",
"x": 180,
"y": 90
},
"ceiling=false,facing=east": {
"double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/magenta_nixie_tube",
"y": 270
},
"ceiling=true,facing=east": {
"double_face=wall,facing=east,waterlogged=false": {
"model": "create:block/magenta_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=false": {
"model": "create:block/magenta_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=false": {
"model": "create:block/magenta_nixie_tube",
"x": 180,
"y": 270
},
"double_face=floor,facing=north,waterlogged=true": {
"model": "create:block/magenta_nixie_tube",
"y": 180
},
"double_face=wall,facing=north,waterlogged=true": {
"model": "create:block/magenta_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=true": {
"model": "create:block/magenta_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=true": {
"model": "create:block/magenta_nixie_tube",
"x": 180,
"y": 180
},
"double_face=floor,facing=south,waterlogged=true": {
"model": "create:block/magenta_nixie_tube"
},
"double_face=wall,facing=south,waterlogged=true": {
"model": "create:block/magenta_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=true": {
"model": "create:block/magenta_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=true": {
"model": "create:block/magenta_nixie_tube",
"x": 180
},
"double_face=floor,facing=west,waterlogged=true": {
"model": "create:block/magenta_nixie_tube",
"y": 90
},
"double_face=wall,facing=west,waterlogged=true": {
"model": "create:block/magenta_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=true": {
"model": "create:block/magenta_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=true": {
"model": "create:block/magenta_nixie_tube",
"x": 180,
"y": 90
},
"double_face=floor,facing=east,waterlogged=true": {
"model": "create:block/magenta_nixie_tube",
"y": 270
},
"double_face=wall,facing=east,waterlogged=true": {
"model": "create:block/magenta_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=true": {
"model": "create:block/magenta_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=true": {
"model": "create:block/magenta_nixie_tube",
"x": 180,
"y": 270

View file

@ -1,35 +1,145 @@
{
"variants": {
"ceiling=false,facing=north": {
"double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/nixie_tube",
"y": 180
},
"ceiling=true,facing=north": {
"double_face=wall,facing=north,waterlogged=false": {
"model": "create:block/nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=false": {
"model": "create:block/nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=false": {
"model": "create:block/nixie_tube",
"x": 180,
"y": 180
},
"ceiling=false,facing=south": {
"double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/nixie_tube"
},
"ceiling=true,facing=south": {
"double_face=wall,facing=south,waterlogged=false": {
"model": "create:block/nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=false": {
"model": "create:block/nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=false": {
"model": "create:block/nixie_tube",
"x": 180
},
"ceiling=false,facing=west": {
"double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/nixie_tube",
"y": 90
},
"ceiling=true,facing=west": {
"double_face=wall,facing=west,waterlogged=false": {
"model": "create:block/nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=false": {
"model": "create:block/nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=false": {
"model": "create:block/nixie_tube",
"x": 180,
"y": 90
},
"ceiling=false,facing=east": {
"double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/nixie_tube",
"y": 270
},
"ceiling=true,facing=east": {
"double_face=wall,facing=east,waterlogged=false": {
"model": "create:block/nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=false": {
"model": "create:block/nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=false": {
"model": "create:block/nixie_tube",
"x": 180,
"y": 270
},
"double_face=floor,facing=north,waterlogged=true": {
"model": "create:block/nixie_tube",
"y": 180
},
"double_face=wall,facing=north,waterlogged=true": {
"model": "create:block/nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=true": {
"model": "create:block/nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=true": {
"model": "create:block/nixie_tube",
"x": 180,
"y": 180
},
"double_face=floor,facing=south,waterlogged=true": {
"model": "create:block/nixie_tube"
},
"double_face=wall,facing=south,waterlogged=true": {
"model": "create:block/nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=true": {
"model": "create:block/nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=true": {
"model": "create:block/nixie_tube",
"x": 180
},
"double_face=floor,facing=west,waterlogged=true": {
"model": "create:block/nixie_tube",
"y": 90
},
"double_face=wall,facing=west,waterlogged=true": {
"model": "create:block/nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=true": {
"model": "create:block/nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=true": {
"model": "create:block/nixie_tube",
"x": 180,
"y": 90
},
"double_face=floor,facing=east,waterlogged=true": {
"model": "create:block/nixie_tube",
"y": 270
},
"double_face=wall,facing=east,waterlogged=true": {
"model": "create:block/nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=true": {
"model": "create:block/nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=true": {
"model": "create:block/nixie_tube",
"x": 180,
"y": 270

View file

@ -1,35 +1,145 @@
{
"variants": {
"ceiling=false,facing=north": {
"double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/pink_nixie_tube",
"y": 180
},
"ceiling=true,facing=north": {
"double_face=wall,facing=north,waterlogged=false": {
"model": "create:block/pink_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=false": {
"model": "create:block/pink_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=false": {
"model": "create:block/pink_nixie_tube",
"x": 180,
"y": 180
},
"ceiling=false,facing=south": {
"double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/pink_nixie_tube"
},
"ceiling=true,facing=south": {
"double_face=wall,facing=south,waterlogged=false": {
"model": "create:block/pink_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=false": {
"model": "create:block/pink_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=false": {
"model": "create:block/pink_nixie_tube",
"x": 180
},
"ceiling=false,facing=west": {
"double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/pink_nixie_tube",
"y": 90
},
"ceiling=true,facing=west": {
"double_face=wall,facing=west,waterlogged=false": {
"model": "create:block/pink_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=false": {
"model": "create:block/pink_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=false": {
"model": "create:block/pink_nixie_tube",
"x": 180,
"y": 90
},
"ceiling=false,facing=east": {
"double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/pink_nixie_tube",
"y": 270
},
"ceiling=true,facing=east": {
"double_face=wall,facing=east,waterlogged=false": {
"model": "create:block/pink_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=false": {
"model": "create:block/pink_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=false": {
"model": "create:block/pink_nixie_tube",
"x": 180,
"y": 270
},
"double_face=floor,facing=north,waterlogged=true": {
"model": "create:block/pink_nixie_tube",
"y": 180
},
"double_face=wall,facing=north,waterlogged=true": {
"model": "create:block/pink_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=true": {
"model": "create:block/pink_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=true": {
"model": "create:block/pink_nixie_tube",
"x": 180,
"y": 180
},
"double_face=floor,facing=south,waterlogged=true": {
"model": "create:block/pink_nixie_tube"
},
"double_face=wall,facing=south,waterlogged=true": {
"model": "create:block/pink_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=true": {
"model": "create:block/pink_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=true": {
"model": "create:block/pink_nixie_tube",
"x": 180
},
"double_face=floor,facing=west,waterlogged=true": {
"model": "create:block/pink_nixie_tube",
"y": 90
},
"double_face=wall,facing=west,waterlogged=true": {
"model": "create:block/pink_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=true": {
"model": "create:block/pink_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=true": {
"model": "create:block/pink_nixie_tube",
"x": 180,
"y": 90
},
"double_face=floor,facing=east,waterlogged=true": {
"model": "create:block/pink_nixie_tube",
"y": 270
},
"double_face=wall,facing=east,waterlogged=true": {
"model": "create:block/pink_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=true": {
"model": "create:block/pink_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=true": {
"model": "create:block/pink_nixie_tube",
"x": 180,
"y": 270

View file

@ -1,35 +1,145 @@
{
"variants": {
"ceiling=false,facing=north": {
"double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/purple_nixie_tube",
"y": 180
},
"ceiling=true,facing=north": {
"double_face=wall,facing=north,waterlogged=false": {
"model": "create:block/purple_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=false": {
"model": "create:block/purple_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=false": {
"model": "create:block/purple_nixie_tube",
"x": 180,
"y": 180
},
"ceiling=false,facing=south": {
"double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/purple_nixie_tube"
},
"ceiling=true,facing=south": {
"double_face=wall,facing=south,waterlogged=false": {
"model": "create:block/purple_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=false": {
"model": "create:block/purple_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=false": {
"model": "create:block/purple_nixie_tube",
"x": 180
},
"ceiling=false,facing=west": {
"double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/purple_nixie_tube",
"y": 90
},
"ceiling=true,facing=west": {
"double_face=wall,facing=west,waterlogged=false": {
"model": "create:block/purple_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=false": {
"model": "create:block/purple_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=false": {
"model": "create:block/purple_nixie_tube",
"x": 180,
"y": 90
},
"ceiling=false,facing=east": {
"double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/purple_nixie_tube",
"y": 270
},
"ceiling=true,facing=east": {
"double_face=wall,facing=east,waterlogged=false": {
"model": "create:block/purple_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=false": {
"model": "create:block/purple_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=false": {
"model": "create:block/purple_nixie_tube",
"x": 180,
"y": 270
},
"double_face=floor,facing=north,waterlogged=true": {
"model": "create:block/purple_nixie_tube",
"y": 180
},
"double_face=wall,facing=north,waterlogged=true": {
"model": "create:block/purple_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=true": {
"model": "create:block/purple_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=true": {
"model": "create:block/purple_nixie_tube",
"x": 180,
"y": 180
},
"double_face=floor,facing=south,waterlogged=true": {
"model": "create:block/purple_nixie_tube"
},
"double_face=wall,facing=south,waterlogged=true": {
"model": "create:block/purple_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=true": {
"model": "create:block/purple_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=true": {
"model": "create:block/purple_nixie_tube",
"x": 180
},
"double_face=floor,facing=west,waterlogged=true": {
"model": "create:block/purple_nixie_tube",
"y": 90
},
"double_face=wall,facing=west,waterlogged=true": {
"model": "create:block/purple_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=true": {
"model": "create:block/purple_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=true": {
"model": "create:block/purple_nixie_tube",
"x": 180,
"y": 90
},
"double_face=floor,facing=east,waterlogged=true": {
"model": "create:block/purple_nixie_tube",
"y": 270
},
"double_face=wall,facing=east,waterlogged=true": {
"model": "create:block/purple_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=true": {
"model": "create:block/purple_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=true": {
"model": "create:block/purple_nixie_tube",
"x": 180,
"y": 270

View file

@ -1,35 +1,145 @@
{
"variants": {
"ceiling=false,facing=north": {
"double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/red_nixie_tube",
"y": 180
},
"ceiling=true,facing=north": {
"double_face=wall,facing=north,waterlogged=false": {
"model": "create:block/red_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=false": {
"model": "create:block/red_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=false": {
"model": "create:block/red_nixie_tube",
"x": 180,
"y": 180
},
"ceiling=false,facing=south": {
"double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/red_nixie_tube"
},
"ceiling=true,facing=south": {
"double_face=wall,facing=south,waterlogged=false": {
"model": "create:block/red_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=false": {
"model": "create:block/red_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=false": {
"model": "create:block/red_nixie_tube",
"x": 180
},
"ceiling=false,facing=west": {
"double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/red_nixie_tube",
"y": 90
},
"ceiling=true,facing=west": {
"double_face=wall,facing=west,waterlogged=false": {
"model": "create:block/red_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=false": {
"model": "create:block/red_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=false": {
"model": "create:block/red_nixie_tube",
"x": 180,
"y": 90
},
"ceiling=false,facing=east": {
"double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/red_nixie_tube",
"y": 270
},
"ceiling=true,facing=east": {
"double_face=wall,facing=east,waterlogged=false": {
"model": "create:block/red_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=false": {
"model": "create:block/red_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=false": {
"model": "create:block/red_nixie_tube",
"x": 180,
"y": 270
},
"double_face=floor,facing=north,waterlogged=true": {
"model": "create:block/red_nixie_tube",
"y": 180
},
"double_face=wall,facing=north,waterlogged=true": {
"model": "create:block/red_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=true": {
"model": "create:block/red_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=true": {
"model": "create:block/red_nixie_tube",
"x": 180,
"y": 180
},
"double_face=floor,facing=south,waterlogged=true": {
"model": "create:block/red_nixie_tube"
},
"double_face=wall,facing=south,waterlogged=true": {
"model": "create:block/red_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=true": {
"model": "create:block/red_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=true": {
"model": "create:block/red_nixie_tube",
"x": 180
},
"double_face=floor,facing=west,waterlogged=true": {
"model": "create:block/red_nixie_tube",
"y": 90
},
"double_face=wall,facing=west,waterlogged=true": {
"model": "create:block/red_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=true": {
"model": "create:block/red_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=true": {
"model": "create:block/red_nixie_tube",
"x": 180,
"y": 90
},
"double_face=floor,facing=east,waterlogged=true": {
"model": "create:block/red_nixie_tube",
"y": 270
},
"double_face=wall,facing=east,waterlogged=true": {
"model": "create:block/red_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=true": {
"model": "create:block/red_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=true": {
"model": "create:block/red_nixie_tube",
"x": 180,
"y": 270

View file

@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "create:block/track_signal/block"
}
}
}

View file

@ -1,35 +1,145 @@
{
"variants": {
"ceiling=false,facing=north": {
"double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/white_nixie_tube",
"y": 180
},
"ceiling=true,facing=north": {
"double_face=wall,facing=north,waterlogged=false": {
"model": "create:block/white_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=false": {
"model": "create:block/white_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=false": {
"model": "create:block/white_nixie_tube",
"x": 180,
"y": 180
},
"ceiling=false,facing=south": {
"double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/white_nixie_tube"
},
"ceiling=true,facing=south": {
"double_face=wall,facing=south,waterlogged=false": {
"model": "create:block/white_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=false": {
"model": "create:block/white_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=false": {
"model": "create:block/white_nixie_tube",
"x": 180
},
"ceiling=false,facing=west": {
"double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/white_nixie_tube",
"y": 90
},
"ceiling=true,facing=west": {
"double_face=wall,facing=west,waterlogged=false": {
"model": "create:block/white_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=false": {
"model": "create:block/white_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=false": {
"model": "create:block/white_nixie_tube",
"x": 180,
"y": 90
},
"ceiling=false,facing=east": {
"double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/white_nixie_tube",
"y": 270
},
"ceiling=true,facing=east": {
"double_face=wall,facing=east,waterlogged=false": {
"model": "create:block/white_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=false": {
"model": "create:block/white_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=false": {
"model": "create:block/white_nixie_tube",
"x": 180,
"y": 270
},
"double_face=floor,facing=north,waterlogged=true": {
"model": "create:block/white_nixie_tube",
"y": 180
},
"double_face=wall,facing=north,waterlogged=true": {
"model": "create:block/white_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=true": {
"model": "create:block/white_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=true": {
"model": "create:block/white_nixie_tube",
"x": 180,
"y": 180
},
"double_face=floor,facing=south,waterlogged=true": {
"model": "create:block/white_nixie_tube"
},
"double_face=wall,facing=south,waterlogged=true": {
"model": "create:block/white_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=true": {
"model": "create:block/white_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=true": {
"model": "create:block/white_nixie_tube",
"x": 180
},
"double_face=floor,facing=west,waterlogged=true": {
"model": "create:block/white_nixie_tube",
"y": 90
},
"double_face=wall,facing=west,waterlogged=true": {
"model": "create:block/white_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=true": {
"model": "create:block/white_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=true": {
"model": "create:block/white_nixie_tube",
"x": 180,
"y": 90
},
"double_face=floor,facing=east,waterlogged=true": {
"model": "create:block/white_nixie_tube",
"y": 270
},
"double_face=wall,facing=east,waterlogged=true": {
"model": "create:block/white_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=true": {
"model": "create:block/white_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=true": {
"model": "create:block/white_nixie_tube",
"x": 180,
"y": 270

View file

@ -1,35 +1,145 @@
{
"variants": {
"ceiling=false,facing=north": {
"double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/yellow_nixie_tube",
"y": 180
},
"ceiling=true,facing=north": {
"double_face=wall,facing=north,waterlogged=false": {
"model": "create:block/yellow_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=false": {
"model": "create:block/yellow_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=false": {
"model": "create:block/yellow_nixie_tube",
"x": 180,
"y": 180
},
"ceiling=false,facing=south": {
"double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/yellow_nixie_tube"
},
"ceiling=true,facing=south": {
"double_face=wall,facing=south,waterlogged=false": {
"model": "create:block/yellow_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=false": {
"model": "create:block/yellow_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=false": {
"model": "create:block/yellow_nixie_tube",
"x": 180
},
"ceiling=false,facing=west": {
"double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/yellow_nixie_tube",
"y": 90
},
"ceiling=true,facing=west": {
"double_face=wall,facing=west,waterlogged=false": {
"model": "create:block/yellow_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=false": {
"model": "create:block/yellow_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=false": {
"model": "create:block/yellow_nixie_tube",
"x": 180,
"y": 90
},
"ceiling=false,facing=east": {
"double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/yellow_nixie_tube",
"y": 270
},
"ceiling=true,facing=east": {
"double_face=wall,facing=east,waterlogged=false": {
"model": "create:block/yellow_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=false": {
"model": "create:block/yellow_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=false": {
"model": "create:block/yellow_nixie_tube",
"x": 180,
"y": 270
},
"double_face=floor,facing=north,waterlogged=true": {
"model": "create:block/yellow_nixie_tube",
"y": 180
},
"double_face=wall,facing=north,waterlogged=true": {
"model": "create:block/yellow_nixie_tube",
"x": 90
},
"double_face=wall_reversed,facing=north,waterlogged=true": {
"model": "create:block/yellow_nixie_tube",
"x": 90
},
"double_face=ceiling,facing=north,waterlogged=true": {
"model": "create:block/yellow_nixie_tube",
"x": 180,
"y": 180
},
"double_face=floor,facing=south,waterlogged=true": {
"model": "create:block/yellow_nixie_tube"
},
"double_face=wall,facing=south,waterlogged=true": {
"model": "create:block/yellow_nixie_tube",
"x": 90,
"y": 180
},
"double_face=wall_reversed,facing=south,waterlogged=true": {
"model": "create:block/yellow_nixie_tube",
"x": 90,
"y": 180
},
"double_face=ceiling,facing=south,waterlogged=true": {
"model": "create:block/yellow_nixie_tube",
"x": 180
},
"double_face=floor,facing=west,waterlogged=true": {
"model": "create:block/yellow_nixie_tube",
"y": 90
},
"double_face=wall,facing=west,waterlogged=true": {
"model": "create:block/yellow_nixie_tube",
"x": 90,
"y": 270
},
"double_face=wall_reversed,facing=west,waterlogged=true": {
"model": "create:block/yellow_nixie_tube",
"x": 90,
"y": 270
},
"double_face=ceiling,facing=west,waterlogged=true": {
"model": "create:block/yellow_nixie_tube",
"x": 180,
"y": 90
},
"double_face=floor,facing=east,waterlogged=true": {
"model": "create:block/yellow_nixie_tube",
"y": 270
},
"double_face=wall,facing=east,waterlogged=true": {
"model": "create:block/yellow_nixie_tube",
"x": 90,
"y": 90
},
"double_face=wall_reversed,facing=east,waterlogged=true": {
"model": "create:block/yellow_nixie_tube",
"x": 90,
"y": 90
},
"double_face=ceiling,facing=east,waterlogged=true": {
"model": "create:block/yellow_nixie_tube",
"x": 180,
"y": 270

View file

@ -483,6 +483,7 @@
"block.create.tiled_glass": "ss\u0250\u05DF\u2141 p\u01DD\u05DF\u0131\u27D8",
"block.create.tiled_glass_pane": "\u01DDu\u0250\u0500 ss\u0250\u05DF\u2141 p\u01DD\u05DF\u0131\u27D8",
"block.create.track": "\u029E\u0254\u0250\u0279\u27D8 u\u0131\u0250\u0279\u27D8",
"block.create.track_signal": "\u05DF\u0250ub\u0131S u\u0131\u0250\u0279\u27D8",
"block.create.track_station": "uo\u0131\u0287\u0250\u0287S u\u0131\u0250\u0279\u27D8",
"block.create.tuff_pillar": "\u0279\u0250\u05DF\u05DF\u0131\u0500 \u025F\u025Fn\u27D8",
"block.create.turntable": "\u01DD\u05DFq\u0250\u0287u\u0279n\u27D8",

View file

@ -486,6 +486,7 @@
"block.create.tiled_glass": "Tiled Glass",
"block.create.tiled_glass_pane": "Tiled Glass Pane",
"block.create.track": "Train Track",
"block.create.track_signal": "Train Signal",
"block.create.track_station": "Train Station",
"block.create.tuff_pillar": "Tuff Pillar",
"block.create.turntable": "Turntable",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 1432",
"_": "Missing Localizations: 1433",
"_": "->------------------------] Game Elements [------------------------<-",
@ -487,6 +487,7 @@
"block.create.tiled_glass": "Glasfliesen",
"block.create.tiled_glass_pane": "Glasfliesenscheibe",
"block.create.track": "UNLOCALIZED: Train Track",
"block.create.track_signal": "UNLOCALIZED: Train Signal",
"block.create.track_station": "UNLOCALIZED: Train Station",
"block.create.tuff_pillar": "UNLOCALIZED: Tuff Pillar",
"block.create.turntable": "Drehtisch",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 443",
"_": "Missing Localizations: 444",
"_": "->------------------------] Game Elements [------------------------<-",
@ -487,6 +487,7 @@
"block.create.tiled_glass": "Vidrio Baldosa",
"block.create.tiled_glass_pane": "Panel de Vidrio Baldosa",
"block.create.track": "UNLOCALIZED: Train Track",
"block.create.track_signal": "UNLOCALIZED: Train Signal",
"block.create.track_station": "UNLOCALIZED: Train Station",
"block.create.tuff_pillar": "UNLOCALIZED: Tuff Pillar",
"block.create.turntable": "Plato Giratorio",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 443",
"_": "Missing Localizations: 444",
"_": "->------------------------] Game Elements [------------------------<-",
@ -487,6 +487,7 @@
"block.create.tiled_glass": "Vidrio esmaltado",
"block.create.tiled_glass_pane": "Panel de vidrio esmaltado",
"block.create.track": "UNLOCALIZED: Train Track",
"block.create.track_signal": "UNLOCALIZED: Train Signal",
"block.create.track_station": "UNLOCALIZED: Train Station",
"block.create.tuff_pillar": "UNLOCALIZED: Tuff Pillar",
"block.create.turntable": "Plataforma giratoria mecánica",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 1694",
"_": "Missing Localizations: 1695",
"_": "->------------------------] Game Elements [------------------------<-",
@ -487,6 +487,7 @@
"block.create.tiled_glass": "Verre carrelé",
"block.create.tiled_glass_pane": "Vitre carrelé",
"block.create.track": "UNLOCALIZED: Train Track",
"block.create.track_signal": "UNLOCALIZED: Train Signal",
"block.create.track_station": "UNLOCALIZED: Train Station",
"block.create.tuff_pillar": "UNLOCALIZED: Tuff Pillar",
"block.create.turntable": "Plaque tournante",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 1383",
"_": "Missing Localizations: 1384",
"_": "->------------------------] Game Elements [------------------------<-",
@ -487,6 +487,7 @@
"block.create.tiled_glass": "Vetro piastrellato",
"block.create.tiled_glass_pane": "Pannello di vetro piastrellato",
"block.create.track": "UNLOCALIZED: Train Track",
"block.create.track_signal": "UNLOCALIZED: Train Signal",
"block.create.track_station": "UNLOCALIZED: Train Station",
"block.create.tuff_pillar": "UNLOCALIZED: Tuff Pillar",
"block.create.turntable": "Piatto",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 113",
"_": "Missing Localizations: 114",
"_": "->------------------------] Game Elements [------------------------<-",
@ -487,6 +487,7 @@
"block.create.tiled_glass": "タイルガラス",
"block.create.tiled_glass_pane": "タイル板ガラス",
"block.create.track": "UNLOCALIZED: Train Track",
"block.create.track_signal": "UNLOCALIZED: Train Signal",
"block.create.track_station": "UNLOCALIZED: Train Station",
"block.create.tuff_pillar": "凝灰岩の柱",
"block.create.turntable": "ターンテーブル",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 115",
"_": "Missing Localizations: 116",
"_": "->------------------------] Game Elements [------------------------<-",
@ -487,6 +487,7 @@
"block.create.tiled_glass": "타일 유리",
"block.create.tiled_glass_pane": "타일 유리판",
"block.create.track": "UNLOCALIZED: Train Track",
"block.create.track_signal": "UNLOCALIZED: Train Signal",
"block.create.track_station": "UNLOCALIZED: Train Station",
"block.create.tuff_pillar": "응회암 기둥",
"block.create.turntable": "돌림판",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 2047",
"_": "Missing Localizations: 2048",
"_": "->------------------------] Game Elements [------------------------<-",
@ -487,6 +487,7 @@
"block.create.tiled_glass": "Getegeld Glas",
"block.create.tiled_glass_pane": "Getegeld Glazen Paneel",
"block.create.track": "UNLOCALIZED: Train Track",
"block.create.track_signal": "UNLOCALIZED: Train Signal",
"block.create.track_station": "UNLOCALIZED: Train Station",
"block.create.tuff_pillar": "UNLOCALIZED: Tuff Pillar",
"block.create.turntable": "Draaischijf",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 482",
"_": "Missing Localizations: 483",
"_": "->------------------------] Game Elements [------------------------<-",
@ -487,6 +487,7 @@
"block.create.tiled_glass": "Kafelkowane szkło",
"block.create.tiled_glass_pane": "Kafelkowana szyba",
"block.create.track": "UNLOCALIZED: Train Track",
"block.create.track_signal": "UNLOCALIZED: Train Signal",
"block.create.track_station": "UNLOCALIZED: Train Station",
"block.create.tuff_pillar": "UNLOCALIZED: Tuff Pillar",
"block.create.turntable": "Talerz obrotowy",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 1666",
"_": "Missing Localizations: 1667",
"_": "->------------------------] Game Elements [------------------------<-",
@ -487,6 +487,7 @@
"block.create.tiled_glass": "Vidro Entalhado",
"block.create.tiled_glass_pane": "Vidraça Entalhada",
"block.create.track": "UNLOCALIZED: Train Track",
"block.create.track_signal": "UNLOCALIZED: Train Signal",
"block.create.track_station": "UNLOCALIZED: Train Station",
"block.create.tuff_pillar": "UNLOCALIZED: Tuff Pillar",
"block.create.turntable": "Mesa giratória",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 1666",
"_": "Missing Localizations: 1667",
"_": "->------------------------] Game Elements [------------------------<-",
@ -487,6 +487,7 @@
"block.create.tiled_glass": "Vidro Entalhado",
"block.create.tiled_glass_pane": "Vidraça Entalhada",
"block.create.track": "UNLOCALIZED: Train Track",
"block.create.track_signal": "UNLOCALIZED: Train Signal",
"block.create.track_station": "UNLOCALIZED: Train Station",
"block.create.tuff_pillar": "UNLOCALIZED: Tuff Pillar",
"block.create.turntable": "Mesa giratória",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 487",
"_": "Missing Localizations: 488",
"_": "->------------------------] Game Elements [------------------------<-",
@ -487,6 +487,7 @@
"block.create.tiled_glass": "Плиточное стекло",
"block.create.tiled_glass_pane": "Плиточная стеклянная панель",
"block.create.track": "UNLOCALIZED: Train Track",
"block.create.track_signal": "UNLOCALIZED: Train Signal",
"block.create.track_station": "UNLOCALIZED: Train Station",
"block.create.tuff_pillar": "UNLOCALIZED: Tuff Pillar",
"block.create.turntable": "Поворотный стол",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 113",
"_": "Missing Localizations: 114",
"_": "->------------------------] Game Elements [------------------------<-",
@ -487,6 +487,7 @@
"block.create.tiled_glass": "十字玻璃窗",
"block.create.tiled_glass_pane": "十字玻璃窗户板",
"block.create.track": "UNLOCALIZED: Train Track",
"block.create.track_signal": "UNLOCALIZED: Train Signal",
"block.create.track_station": "UNLOCALIZED: Train Station",
"block.create.tuff_pillar": "凝灰岩柱",
"block.create.turntable": "转盘",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 501",
"_": "Missing Localizations: 502",
"_": "->------------------------] Game Elements [------------------------<-",
@ -487,6 +487,7 @@
"block.create.tiled_glass": "十字玻璃窗",
"block.create.tiled_glass_pane": "十字玻璃窗戶片",
"block.create.track": "UNLOCALIZED: Train Track",
"block.create.track_signal": "UNLOCALIZED: Train Signal",
"block.create.track_station": "UNLOCALIZED: Train Station",
"block.create.tuff_pillar": "UNLOCALIZED: Tuff Pillar",
"block.create.turntable": "轉盤",

View file

@ -0,0 +1,3 @@
{
"parent": "create:block/track_signal/item"
}

View file

@ -0,0 +1,20 @@
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1.0,
"bonus_rolls": 0.0,
"entries": [
{
"type": "minecraft:item",
"name": "create:track_signal"
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
}
]
}

View file

@ -108,6 +108,7 @@
"create:mechanical_arm",
"create:track",
"create:track_station",
"create:track_signal",
"create:item_vault",
"create:andesite_funnel",
"create:andesite_belt_funnel",

View file

@ -118,10 +118,10 @@ public class AllBlockPartials {
GIRDER_SEGMENT_MIDDLE = block("metal_girder/segment_middle"),
GIRDER_SEGMENT_BOTTOM = block("metal_girder/segment_bottom"),
TRACK_STATION_OVERLAY = block("track/station_overlay"),
TRACK_STATION_OVERLAY_DIAGONAL = block("track/station_overlay_diagonal"),
TRACK_STATION_OVERLAY_ASCENDING = block("track/station_overlay_ascending"),
TRACK_ASSEMBLY_OVERLAY = block("track/assembly_overlay"),
TRACK_STATION_OVERLAY = block("track_overlay/station"),
TRACK_SIGNAL_OVERLAY = block("track_overlay/signal"),
TRACK_ASSEMBLING_OVERLAY = block("track_overlay/assembling"),
TRACK_SIGNAL_DUAL_OVERLAY = block("track_overlay/signal_dual"),
BOGEY_FRAME = block("track/bogey/bogey_frame"),
SMALL_BOGEY_WHEELS = block("track/bogey/bogey_wheel"),
@ -135,6 +135,17 @@ public class AllBlockPartials {
TRAIN_CONTROLS_COVER = block("controls/train/cover"),
TRAIN_CONTROLS_LEVER = block("controls/train/lever"),
SIGNAL_ON = block("track_signal/indicator_on"),
SIGNAL_OFF = block("track_signal/indicator_off"),
SIGNAL_PANEL = block("track_signal/panel"),
SIGNAL_WHITE_CUBE = block("track_signal/white_cube"),
SIGNAL_WHITE_GLOW = block("track_signal/white_glow"),
SIGNAL_WHITE = block("track_signal/white_tube"),
SIGNAL_RED_CUBE = block("track_signal/red_cube"),
SIGNAL_RED_GLOW = block("track_signal/red_glow"),
SIGNAL_RED = block("track_signal/red_tube"),
CRAFTING_BLUEPRINT_1x1 = entity("crafting_blueprint_small"),
CRAFTING_BLUEPRINT_2x2 = entity("crafting_blueprint_medium"),

View file

@ -174,6 +174,7 @@ import com.simibubi.create.content.logistics.block.vault.ItemVaultItem;
import com.simibubi.create.content.logistics.item.LecternControllerBlock;
import com.simibubi.create.content.logistics.trains.management.StationBlock;
import com.simibubi.create.content.logistics.trains.management.TrackTargetingBlockItem;
import com.simibubi.create.content.logistics.trains.management.signal.SignalBlock;
import com.simibubi.create.content.logistics.trains.track.StandardBogeyBlock;
import com.simibubi.create.content.logistics.trains.track.TrackBlock;
import com.simibubi.create.content.logistics.trains.track.TrackBlockItem;
@ -1310,6 +1311,16 @@ public class AllBlocks {
.item(TrackTargetingBlockItem::new)
.transform(customItemModel("_", "block"))
.register();
public static final BlockEntry<SignalBlock> TRACK_SIGNAL = REGISTRATE.block("track_signal", SignalBlock::new)
.initialProperties(SharedProperties::softMetal)
.properties(p -> p.sound(SoundType.NETHERITE_BLOCK))
.transform(pickaxeOnly())
.blockstate((c, p) -> p.simpleBlock(c.get(), AssetLookup.partialBaseModel(c, p)))
.lang("Train Signal")
.item(TrackTargetingBlockItem::new)
.transform(customItemModel())
.register();
public static final BlockEntry<StandardBogeyBlock> SMALL_BOGEY =
REGISTRATE.block("small_bogey", p -> new StandardBogeyBlock(p, false))

View file

@ -58,12 +58,6 @@ public class AllShapes {
.add(0, 14, 0, 16, 16, 16)
.add(3, 3, -2, 13, 13, 2)
.forHorizontal(NORTH),
NIXIE_TUBE = shape(0, 0, 0, 16, 4, 16).add(9, 0, 5, 15, 15, 11)
.add(1, 0, 5, 7, 15, 11)
.forHorizontalAxis(),
NIXIE_TUBE_CEILING = shape(0, 12, 0, 16, 16, 16).add(9, 1, 5, 15, 16, 11)
.add(1, 1, 5, 7, 16, 11)
.forHorizontalAxis(),
FUNNEL_COLLISION = shape(0, 0, 0, 16, 4, 16).forDirectional(UP),
BELT_FUNNEL_RETRACTED = shape(2, -2, 14, 14, 14, 18).add(0, -5, 8, 16, 16, 14)
.forHorizontal(NORTH),
@ -127,7 +121,14 @@ public class AllShapes {
STATION = shape(0, 0, 0, 16, 5, 16).add(2, 4, 0, 14, 16, 4)
.forHorizontal(NORTH),
CONTROLS = shape(0, 0, 4, 16, 4, 16).add(0, 0, 6, 16, 14, 16)
.forHorizontal(NORTH)
.forHorizontal(NORTH),
NIXIE_TUBE = shape(9, 0, 5, 15, 12, 11).add(1, 0, 5, 7, 12, 11)
.forHorizontalAxis(),
NIXIE_TUBE_CEILING = shape(9, 4, 5, 15, 16, 11).add(1, 4, 5, 7, 16, 11)
.forHorizontalAxis(),
NIXIE_TUBE_WALL = shape(5, 9, 0, 11, 15, 12).add(5, 1, 0, 11, 7, 12)
.forHorizontal(Direction.SOUTH)
;

View file

@ -170,6 +170,8 @@ import com.simibubi.create.content.logistics.item.LecternControllerTileEntity;
import com.simibubi.create.content.logistics.trains.IBogeyTileEntityRenderer;
import com.simibubi.create.content.logistics.trains.management.StationRenderer;
import com.simibubi.create.content.logistics.trains.management.StationTileEntity;
import com.simibubi.create.content.logistics.trains.management.signal.SignalRenderer;
import com.simibubi.create.content.logistics.trains.management.signal.SignalTileEntity;
import com.simibubi.create.content.logistics.trains.track.StandardBogeyTileEntity;
import com.simibubi.create.content.logistics.trains.track.TrackInstance;
import com.simibubi.create.content.logistics.trains.track.TrackRenderer;
@ -748,6 +750,12 @@ public class AllTileEntities {
.renderer(() -> StationRenderer::new)
.validBlocks(AllBlocks.TRACK_STATION)
.register();
public static final BlockEntityEntry<SignalTileEntity> TRACK_SIGNAL = Create.registrate()
.tileEntity("track_signal", SignalTileEntity::new)
.renderer(() -> SignalRenderer::new)
.validBlocks(AllBlocks.TRACK_SIGNAL)
.register();
public static void register() {}
}

View file

@ -14,7 +14,7 @@ public class SeatInteractionBehaviour extends MovingInteractionBehaviour {
@Override
public boolean handlePlayerInteraction(Player player, InteractionHand activeHand, BlockPos localPos,
AbstractContraptionEntity contraptionEntity) {
return true;
return false;
}
@Override

View file

@ -14,6 +14,7 @@ import org.apache.commons.lang3.tuple.MutablePair;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllItems;
import com.simibubi.create.AllMovementBehaviours;
import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.Create;
@ -191,7 +192,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
InteractionHand interactionHand) {
int indexOfSeat = contraption.getSeats()
.indexOf(localPos);
if (indexOfSeat == -1)
if (indexOfSeat == -1 || AllItems.WRENCH.isIn(player.getItemInHand(interactionHand)))
return contraption.interactors.containsKey(localPos) && contraption.interactors.get(localPos)
.handlePlayerInteraction(player, interactionHand, localPos, this);
if (player.isPassenger())

View file

@ -1,5 +1,6 @@
package com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls;
import com.simibubi.create.AllItems;
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.MovingInteractionBehaviour;
@ -12,6 +13,8 @@ public class ControlsInteractionBehaviour extends MovingInteractionBehaviour {
@Override
public boolean handlePlayerInteraction(Player player, InteractionHand activeHand, BlockPos localPos,
AbstractContraptionEntity contraptionEntity) {
if (AllItems.WRENCH.isIn(player.getItemInHand(activeHand)))
return false;
if (player.level.isClientSide)
ControlsHandler.controllerClicked(contraptionEntity, localPos, player);
return true;

View file

@ -11,6 +11,7 @@ import com.simibubi.create.content.contraptions.fluids.pipes.BracketBlock;
import com.simibubi.create.content.contraptions.relays.elementary.BracketedTileEntityBehaviour;
import com.simibubi.create.content.contraptions.wrench.IWrenchable;
import com.simibubi.create.content.logistics.block.chute.AbstractChuteBlock;
import com.simibubi.create.content.logistics.block.redstone.NixieTubeBlock;
import com.simibubi.create.content.logistics.trains.track.TrackBlock;
import com.simibubi.create.content.logistics.trains.track.TrackShape;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
@ -159,6 +160,8 @@ public class GirderBlock extends Block implements SimpleWaterloggedBlock, IWrenc
state = state.setValue(updateProperty, true);
if (sideState.getBlock() == state.getBlock() && sideState.getValue(updateProperty))
state = state.setValue(updateProperty, true);
if (sideState.getBlock() instanceof NixieTubeBlock && NixieTubeBlock.getFacing(sideState) == d)
state = state.setValue(updateProperty, true);
for (Direction d2 : Iterate.directionsInAxis(axis == Axis.X ? Axis.Z : Axis.X)) {
BlockState above = level.getBlockState(pos.above()
@ -177,8 +180,13 @@ public class GirderBlock extends Block implements SimpleWaterloggedBlock, IWrenc
Property<Boolean> updateProperty, BlockState sideState, Direction d) {
if (sideState.getBlock() == state.getBlock() && sideState.getValue(X) == sideState.getValue(Z))
state = state.setValue(updateProperty, true);
else if (sideState.getBlock() == state.getBlock() && sideState.getValue(X) != state.getValue(X)
&& sideState.getValue(Z) != state.getValue(Z))
state = state.setValue(updateProperty, true);
else if (sideState.hasProperty(WallBlock.UP) && sideState.getValue(WallBlock.UP))
state = state.setValue(updateProperty, true);
else if (sideState.getBlock() instanceof NixieTubeBlock && NixieTubeBlock.getFacing(sideState) == d)
state = state.setValue(updateProperty, true);
else if (sideState.hasBlockEntity()) {
BlockEntity blockEntity = level.getBlockEntity(pos.relative(d));
if (!(blockEntity instanceof SmartTileEntity ste))
@ -219,6 +227,8 @@ public class GirderBlock extends Block implements SimpleWaterloggedBlock, IWrenc
BlockState blockState = world.getBlockState(relative);
if (blockState.isAir())
return false;
if (blockState.getBlock() instanceof NixieTubeBlock && NixieTubeBlock.getFacing(blockState) == side)
return true;
VoxelShape shape = blockState.getShape(world, relative);
if (shape.isEmpty())
return false;

View file

@ -0,0 +1,82 @@
package com.simibubi.create.content.logistics.block.redstone;
import javax.annotation.Nullable;
import net.minecraft.core.Direction;
import net.minecraft.util.StringRepresentable;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.block.HorizontalDirectionalBlock;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.EnumProperty;
import net.minecraft.world.phys.Vec3;
public class DoubleFaceAttachedBlock extends HorizontalDirectionalBlock {
public enum DoubleAttachFace implements StringRepresentable {
FLOOR("floor"), WALL("wall"), WALL_REVERSED("wall_reversed"), CEILING("ceiling");
private final String name;
private DoubleAttachFace(String p_61311_) {
this.name = p_61311_;
}
public String getSerializedName() {
return this.name;
}
public int xRot() {
return this == FLOOR ? 0 : this == CEILING ? 180 : 90;
}
}
public static final EnumProperty<DoubleAttachFace> FACE =
EnumProperty.create("double_face", DoubleAttachFace.class);
public DoubleFaceAttachedBlock(BlockBehaviour.Properties p_53182_) {
super(p_53182_);
}
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext pContext) {
for (Direction direction : pContext.getNearestLookingDirections()) {
BlockState blockstate;
if (direction.getAxis() == Direction.Axis.Y) {
blockstate = this.defaultBlockState()
.setValue(FACE, direction == Direction.UP ? DoubleAttachFace.CEILING : DoubleAttachFace.FLOOR)
.setValue(FACING, pContext.getHorizontalDirection());
} else {
Vec3 n = Vec3.atLowerCornerOf(direction.getClockWise()
.getNormal());
DoubleAttachFace face = DoubleAttachFace.WALL;
if (pContext.getPlayer() != null) {
Vec3 lookAngle = pContext.getPlayer()
.getLookAngle();
if (lookAngle.dot(n) < 0)
face = DoubleAttachFace.WALL_REVERSED;
}
blockstate = this.defaultBlockState()
.setValue(FACE, face) // TODO wall reversed
.setValue(FACING, direction.getOpposite());
}
if (blockstate.canSurvive(pContext.getLevel(), pContext.getClickedPos())) {
return blockstate;
}
}
return null;
}
protected static Direction getConnectedDirection(BlockState pState) {
switch ((DoubleAttachFace) pState.getValue(FACE)) {
case CEILING:
return Direction.DOWN;
case FLOOR:
return Direction.UP;
default:
return pState.getValue(FACING);
}
}
}

View file

@ -1,5 +1,7 @@
package com.simibubi.create.content.logistics.block.redstone;
import static net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED;
import java.util.Random;
import com.simibubi.create.AllBlocks;
@ -24,31 +26,30 @@ import net.minecraft.world.item.Items;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.HorizontalDirectionalBlock;
import net.minecraft.world.level.block.SimpleWaterloggedBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition.Builder;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.level.pathfinder.PathComputationType;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
public class NixieTubeBlock extends HorizontalDirectionalBlock
implements ITE<NixieTubeTileEntity>, IWrenchable, ISpecialBlockItemRequirement {
public static final BooleanProperty CEILING = BooleanProperty.create("ceiling");
public class NixieTubeBlock extends DoubleFaceAttachedBlock
implements ITE<NixieTubeTileEntity>, IWrenchable, SimpleWaterloggedBlock, ISpecialBlockItemRequirement {
protected final DyeColor color;
public NixieTubeBlock(Properties properties, DyeColor color) {
super(properties);
this.color = color;
registerDefaultState(defaultBlockState().setValue(CEILING, false));
registerDefaultState(defaultBlockState().setValue(FACE, DoubleAttachFace.FLOOR));
}
@Override
@ -78,7 +79,13 @@ public class NixieTubeBlock extends HorizontalDirectionalBlock
return InteractionResult.PASS;
Direction left = state.getValue(FACING)
.getClockWise();
.getOpposite();
if (state.getValue(FACE) == DoubleAttachFace.WALL)
left = Direction.UP;
if (state.getValue(FACE) == DoubleAttachFace.WALL_REVERSED)
left = Direction.DOWN;
Direction right = left.getOpposite();
if (world.isClientSide)
@ -114,7 +121,7 @@ public class NixieTubeBlock extends HorizontalDirectionalBlock
@Override
protected void createBlockStateDefinition(Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder.add(CEILING, FACING));
super.createBlockStateDefinition(builder.add(FACE, FACING, WATERLOGGED));
}
@Override
@ -128,7 +135,7 @@ public class NixieTubeBlock extends HorizontalDirectionalBlock
public ItemStack getCloneItemStack(BlockGetter p_185473_1_, BlockPos p_185473_2_, BlockState p_185473_3_) {
return AllBlocks.ORANGE_NIXIE_TUBE.asStack();
}
@Override
public ItemRequirement getRequiredItems(BlockState state, BlockEntity te) {
return new ItemRequirement(ItemUseType.CONSUME, AllBlocks.ORANGE_NIXIE_TUBE.get()
@ -136,11 +143,18 @@ public class NixieTubeBlock extends HorizontalDirectionalBlock
}
@Override
public VoxelShape getShape(BlockState state, BlockGetter p_220053_2_, BlockPos p_220053_3_,
CollisionContext p_220053_4_) {
return (state.getValue(CEILING) ? AllShapes.NIXIE_TUBE_CEILING : AllShapes.NIXIE_TUBE)
.get(state.getValue(FACING)
public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) {
Direction facing = pState.getValue(FACING);
switch (pState.getValue(FACE)) {
case CEILING:
return AllShapes.NIXIE_TUBE_CEILING.get(facing.getClockWise()
.getAxis());
case FLOOR:
return AllShapes.NIXIE_TUBE.get(facing.getClockWise()
.getAxis());
default:
return AllShapes.NIXIE_TUBE_WALL.get(facing);
}
}
@Override
@ -152,16 +166,30 @@ public class NixieTubeBlock extends HorizontalDirectionalBlock
return super.getCloneItemStack(state, target, world, pos, player);
}
@Override
public FluidState getFluidState(BlockState state) {
return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : Fluids.EMPTY.defaultFluidState();
}
@Override
public BlockState updateShape(BlockState state, Direction direction, BlockState neighbourState, LevelAccessor world,
BlockPos pos, BlockPos neighbourPos) {
if (state.getValue(WATERLOGGED))
world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world));
return state;
}
@Override
public BlockState getStateForPlacement(BlockPlaceContext context) {
BlockPos pos = context.getClickedPos();
boolean ceiling = context.getClickedFace() == Direction.DOWN;
Vec3 hitVec = context.getClickLocation();
if (hitVec != null)
ceiling = hitVec.y - pos.getY() > .5f;
return defaultBlockState().setValue(FACING, context.getHorizontalDirection()
.getOpposite())
.setValue(CEILING, ceiling);
BlockState state = super.getStateForPlacement(context);
if (state == null)
return null;
if (state.getValue(FACE) != DoubleAttachFace.WALL && state.getValue(FACE) != DoubleAttachFace.WALL_REVERSED)
state = state.setValue(FACING, state.getValue(FACING)
.getClockWise());
return state.setValue(WATERLOGGED, Boolean.valueOf(context.getLevel()
.getFluidState(context.getClickedPos())
.getType() == Fluids.WATER));
}
@Override
@ -229,7 +257,7 @@ public class NixieTubeBlock extends HorizontalDirectionalBlock
public BlockEntityType<? extends NixieTubeTileEntity> getTileEntityType() {
return AllTileEntities.NIXIE_TUBE.get();
}
public DyeColor getColor() {
return color;
}
@ -246,7 +274,8 @@ public class NixieTubeBlock extends HorizontalDirectionalBlock
return (color == DyeColor.ORANGE ? AllBlocks.ORANGE_NIXIE_TUBE : AllBlocks.NIXIE_TUBES.get(color))
.getDefaultState()
.setValue(FACING, state.getValue(FACING))
.setValue(CEILING, state.getValue(CEILING));
.setValue(WATERLOGGED, state.getValue(WATERLOGGED))
.setValue(FACE, state.getValue(FACE));
}
public static DyeColor colorOf(BlockState blockState) {
@ -254,4 +283,8 @@ public class NixieTubeBlock extends HorizontalDirectionalBlock
: DyeColor.ORANGE;
}
public static Direction getFacing(BlockState sideState) {
return getConnectedDirection(sideState);
}
}

View file

@ -1,5 +1,6 @@
package com.simibubi.create.content.logistics.block.redstone;
import com.simibubi.create.content.logistics.block.redstone.DoubleFaceAttachedBlock.DoubleAttachFace;
import com.simibubi.create.foundation.data.SpecialBlockStateGen;
import com.tterrag.registrate.providers.DataGenContext;
import com.tterrag.registrate.providers.RegistrateBlockstateProvider;
@ -12,12 +13,15 @@ public class NixieTubeGenerator extends SpecialBlockStateGen {
@Override
protected int getXRotation(BlockState state) {
return state.getValue(NixieTubeBlock.CEILING) ? 180 : 0;
return state.getValue(NixieTubeBlock.FACE)
.xRot();
}
@Override
protected int getYRotation(BlockState state) {
return horizontalAngle(state.getValue(NixieTubeBlock.FACING));
DoubleAttachFace face = state.getValue(NixieTubeBlock.FACE);
return horizontalAngle(state.getValue(NixieTubeBlock.FACING))
+ (face == DoubleAttachFace.WALL || face == DoubleAttachFace.WALL_REVERSED ? 180 : 0);
}
@Override

View file

@ -6,10 +6,16 @@ import java.util.Random;
import com.google.common.collect.ImmutableMap;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.logistics.block.redstone.DoubleFaceAttachedBlock.DoubleAttachFace;
import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.RenderTypes;
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.Color;
import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
@ -17,10 +23,13 @@ import net.minecraft.client.gui.font.glyphs.BakedGlyph;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.MultiBufferSource.BufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.core.Direction;
import net.minecraft.network.chat.Style;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
public class NixieTubeRenderer extends SafeTileEntityRenderer<NixieTubeTileEntity> {
@ -58,11 +67,26 @@ public class NixieTubeRenderer extends SafeTileEntityRenderer<NixieTubeTileEntit
int light, int overlay) {
ms.pushPose();
BlockState blockState = te.getBlockState();
TransformStack.cast(ms)
.centre()
.rotateY(AngleHelper.horizontalAngle(blockState.getValue(NixieTubeBlock.FACING)));
DoubleAttachFace face = blockState.getValue(NixieTubeBlock.FACE);
float yRot = AngleHelper.horizontalAngle(blockState.getValue(NixieTubeBlock.FACING)) - 90
+ (face == DoubleAttachFace.WALL_REVERSED ? 180 : 0);
float xRot = face == DoubleAttachFace.WALL ? -90 : face == DoubleAttachFace.WALL_REVERSED ? 90 : 0;
float height = blockState.getValue(NixieTubeBlock.CEILING) ? 2 : 6;
TransformStack msr = TransformStack.cast(ms);
msr.centre()
.rotateY(yRot)
.rotateZ(xRot)
.unCentre();
if (te.signalState != null) {
renderAsSignal(te, partialTicks, ms, buffer, light, overlay);
ms.popPose();
return;
}
msr.centre();
float height = face == DoubleAttachFace.CEILING ? 5 : 3;
float scale = 1 / 20f;
Couple<String> s = te.getDisplayedStrings();
@ -124,4 +148,71 @@ public class NixieTubeRenderer extends SafeTileEntityRenderer<NixieTubeTileEntit
}
}
private void renderAsSignal(NixieTubeTileEntity te, float partialTicks, PoseStack ms, MultiBufferSource buffer,
int light, int overlay) {
BlockState blockState = te.getBlockState();
Direction facing = NixieTubeBlock.getFacing(blockState);
Vec3 observerVec = Minecraft.getInstance().cameraEntity.getEyePosition(partialTicks);
TransformStack msr = TransformStack.cast(ms);
if (facing == Direction.DOWN)
msr.centre()
.rotateZ(180)
.unCentre();
boolean invertTubes =
facing == Direction.DOWN || blockState.getValue(NixieTubeBlock.FACE) == DoubleAttachFace.WALL_REVERSED;
CachedBufferer.partial(AllBlockPartials.SIGNAL_PANEL, blockState)
.light(light)
.renderInto(ms, buffer.getBuffer(RenderType.solid()));
ms.pushPose();
ms.translate(1 / 2f, 7.5f / 16f, 1 / 2f);
float renderTime = AnimationTickHolder.getRenderTime(te.getLevel());
for (boolean first : Iterate.trueAndFalse) {
Vec3 lampVec = Vec3.atCenterOf(te.getBlockPos());
Vec3 diff = lampVec.subtract(observerVec);
if (first && !te.signalState.isRedLight(renderTime))
continue;
if (!first && !te.signalState.isGreenLight(renderTime))
continue;
boolean flip = first == invertTubes;
ms.pushPose();
ms.translate(flip ? 4 / 16f : -4 / 16f, 0, 0);
if (diff.lengthSqr() < 36 * 36) {
boolean vert = first ^ facing.getAxis()
.isHorizontal();
CachedBufferer.partial(AllBlockPartials.SIGNAL_WHITE_CUBE, blockState)
.light(0xf000f0)
.disableDiffuseMult()
.scale(vert ? 4 : 1, vert ? 1 : 4, 1)
.renderInto(ms, buffer.getBuffer(RenderType.translucent()));
CachedBufferer
.partial(first ? AllBlockPartials.SIGNAL_RED_GLOW : AllBlockPartials.SIGNAL_WHITE_GLOW, blockState)
.light(0xf000f0)
.disableDiffuseMult()
.scale(vert ? 5.125f : 2, vert ? 2 : 5.125f, 2)
.renderInto(ms, buffer.getBuffer(RenderTypes.getAdditive()));
}
CachedBufferer.partial(first ? AllBlockPartials.SIGNAL_RED : AllBlockPartials.SIGNAL_WHITE, blockState)
.light(0xF000F0)
.disableDiffuseMult()
.scale(1 + 1 / 16f)
.renderInto(ms, buffer.getBuffer(RenderTypes.getAdditive()));
ms.popPose();
}
ms.popPose();
}
}

View file

@ -1,5 +1,6 @@
package com.simibubi.create.content.logistics.block.redstone;
import java.lang.ref.WeakReference;
import java.util.List;
import javax.annotation.Nullable;
@ -8,6 +9,8 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.simibubi.create.content.logistics.trains.management.signal.SignalTileEntity;
import com.simibubi.create.content.logistics.trains.management.signal.SignalTileEntity.SignalState;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.utility.Couple;
@ -15,6 +18,7 @@ import com.simibubi.create.foundation.utility.Couple;
import net.minecraft.commands.CommandSource;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component;
@ -23,6 +27,7 @@ import net.minecraft.network.chat.TextComponent;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec2;
@ -39,10 +44,14 @@ public class NixieTubeTileEntity extends SmartTileEntity {
private Component parsedCustomText;
private Couple<String> displayedStrings;
private WeakReference<SignalTileEntity> cachedSignalTE;
public SignalState signalState;
public NixieTubeTileEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
hasCustomText = false;
redstoneStrength = 0;
cachedSignalTE = new WeakReference<>(null);
}
@Override
@ -57,6 +66,23 @@ public class NixieTubeTileEntity extends SmartTileEntity {
if (currentStrings == null || !currentStrings.equals(displayedStrings))
sendData();
}
if (level.isClientSide) {
signalState = null;
SignalTileEntity signalTileEntity = cachedSignalTE.get();
if (signalTileEntity == null || signalTileEntity.isRemoved()) {
Direction facing = NixieTubeBlock.getFacing(getBlockState());
BlockEntity blockEntity = level.getBlockEntity(worldPosition.relative(facing.getOpposite()));
if (blockEntity instanceof SignalTileEntity signal) {
signalState = signal.getState();
cachedSignalTE = new WeakReference<>(signal);
}
return;
}
signalState = signalTileEntity.getState();
}
}
@Override
@ -95,6 +121,8 @@ public class NixieTubeTileEntity extends SmartTileEntity {
}
public void updateDisplayedStrings() {
if (signalState != null)
return;
if (!hasCustomText) {
displayedStrings = Couple.create(redstoneStrength < 10 ? "0" : "1", String.valueOf(redstoneStrength % 10));
} else {
@ -195,9 +223,13 @@ public class NixieTubeTileEntity extends SmartTileEntity {
// From SignTileEntity
public CommandSourceStack getCommandSource(@Nullable ServerPlayer p_195539_1_) {
String s = p_195539_1_ == null ? "Nixie Tube" : p_195539_1_.getName().getString();
Component itextcomponent = (Component)(p_195539_1_ == null ? new TextComponent("Nixie Tube") : p_195539_1_.getDisplayName());
return new CommandSourceStack(CommandSource.NULL, Vec3.atCenterOf(this.worldPosition), Vec2.ZERO, (ServerLevel)this.level, 2, s, itextcomponent, this.level.getServer(), p_195539_1_);
String s = p_195539_1_ == null ? "Nixie Tube"
: p_195539_1_.getName()
.getString();
Component itextcomponent =
(Component) (p_195539_1_ == null ? new TextComponent("Nixie Tube") : p_195539_1_.getDisplayName());
return new CommandSourceStack(CommandSource.NULL, Vec3.atCenterOf(this.worldPosition), Vec2.ZERO,
(ServerLevel) this.level, 2, s, itextcomponent, this.level.getServer(), p_195539_1_);
}
@Override

View file

@ -7,9 +7,12 @@ import java.util.UUID;
import javax.annotation.Nullable;
import com.simibubi.create.content.contraptions.KineticDebugger;
import org.lwjgl.glfw.GLFW;
import com.simibubi.create.AllKeys;
import com.simibubi.create.content.logistics.trains.entity.Carriage;
import com.simibubi.create.content.logistics.trains.entity.Train;
import com.simibubi.create.content.logistics.trains.management.signal.SignalEdgeGroup;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
@ -22,11 +25,11 @@ import net.minecraft.world.level.dimension.DimensionType;
public class GlobalRailwayManager {
public Map<UUID, TrackGraph> trackNetworks;
private TrackSavedData trackData;
public Map<UUID, SignalEdgeGroup> signalEdgeGroups;
public Map<UUID, Train> trains;
public Map<Integer, Carriage> carriageById;
private TrackSavedData trackData;
public TrackGraphSync sync;
//
@ -57,6 +60,7 @@ public class GlobalRailwayManager {
return;
trackData = TrackSavedData.load(server);
trackNetworks = trackData.getTrackNetworks();
signalEdgeGroups = trackData.getSignalBlocks();
}
public void levelUnloaded(LevelAccessor level) {
@ -68,6 +72,7 @@ public class GlobalRailwayManager {
public void cleanUp() {
trackNetworks = new HashMap<>();
signalEdgeGroups = new HashMap<>();
trains = new HashMap<>();
carriageById = new HashMap<>();
sync = new TrackGraphSync();
@ -77,7 +82,7 @@ public class GlobalRailwayManager {
if (trackData != null)
trackData.setDirty();
}
//
public TrackGraph getOrCreateGraph(UUID graphID) {
@ -120,16 +125,30 @@ public class GlobalRailwayManager {
if (!location.equals(location2))
return;
for (SignalEdgeGroup group : signalEdgeGroups.values()) {
group.trains.clear();
group.reserved = null;
}
for (TrackGraph graph : trackNetworks.values())
graph.getSignals()
.forEach(sb -> sb.tick(graph));
for (Train train : trains.values())
train.earlyTick(level);
for (Train train : trains.values())
train.tick(level);
if (AllKeys.isKeyDown(GLFW.GLFW_KEY_H)) {
trackNetworks.values()
.forEach(TrackGraph::debugViewSignalData);
}
}
public void clientTick() {
if (KineticDebugger.isActive()) {
if (AllKeys.isKeyDown(GLFW.GLFW_KEY_J)) {
trackNetworks.values()
.forEach(TrackGraph::debugViewNodes);
.forEach(TrackGraph::debugViewNodes);
}
}

View file

@ -11,6 +11,7 @@ import javax.annotation.Nullable;
import com.jozufozu.flywheel.core.PartialModel;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation.DiscoveredLocation;
import com.simibubi.create.content.logistics.trains.management.TrackTargetingBehaviour.RenderedTrackOverlayType;
import com.simibubi.create.content.logistics.trains.track.TrackBlock;
import com.simibubi.create.content.logistics.trains.track.TrackShape;
import com.simibubi.create.foundation.utility.Iterate;
@ -103,8 +104,8 @@ public interface ITrackBlock {
}
@OnlyIn(Dist.CLIENT)
public PartialModel prepareStationOverlay(BlockGetter world, BlockPos pos, BlockState state,
AxisDirection direction, PoseStack transform);
public PartialModel prepareTrackOverlay(BlockGetter world, BlockPos pos, BlockState state,
AxisDirection direction, PoseStack transform, RenderedTrackOverlayType type);
@OnlyIn(Dist.CLIENT)
public PartialModel prepareAssemblyOverlay(BlockGetter world, BlockPos pos, BlockState state, Direction direction,

View file

@ -1,5 +1,6 @@
package com.simibubi.create.content.logistics.trains;
import com.simibubi.create.content.logistics.trains.management.signal.EdgeData;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.core.BlockPos;
@ -11,15 +12,21 @@ import net.minecraft.world.phys.Vec3;
public class TrackEdge {
BezierConnection turn;
EdgeData edgeData;
public TrackEdge(BezierConnection turn) {
this.turn = turn;
this.edgeData = new EdgeData();
}
public boolean isTurn() {
return turn != null;
}
public EdgeData getEdgeData() {
return edgeData;
}
public BezierConnection getTurn() {
return turn;
}
@ -61,11 +68,16 @@ public class TrackEdge {
}
public CompoundTag write() {
return isTurn() ? turn.write(BlockPos.ZERO) : new CompoundTag();
CompoundTag baseCompound = isTurn() ? turn.write(BlockPos.ZERO) : new CompoundTag();
baseCompound.put("Signals", edgeData.write());
return baseCompound;
}
public static TrackEdge read(CompoundTag tag) {
return new TrackEdge(tag.contains("Positions") ? new BezierConnection(tag, BlockPos.ZERO) : null);
public static TrackEdge read(CompoundTag tag, TrackGraph graph) {
TrackEdge trackEdge =
new TrackEdge(tag.contains("Positions") ? new BezierConnection(tag, BlockPos.ZERO) : null);
trackEdge.edgeData = EdgeData.read(tag.getCompound("Signals"), graph);
return trackEdge;
}
}

View file

@ -16,14 +16,22 @@ import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nullable;
import org.lwjgl.glfw.GLFW;
import com.simibubi.create.AllKeys;
import com.simibubi.create.Create;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation.DiscoveredLocation;
import com.simibubi.create.content.logistics.trains.entity.Train;
import com.simibubi.create.content.logistics.trains.management.GlobalStation;
import com.simibubi.create.content.logistics.trains.management.signal.EdgeData;
import com.simibubi.create.content.logistics.trains.management.signal.SignalBoundary;
import com.simibubi.create.content.logistics.trains.management.signal.SignalEdgeGroup;
import com.simibubi.create.content.logistics.trains.management.signal.SignalPropagator;
import com.simibubi.create.foundation.utility.Color;
import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.NBTHelper;
import com.simibubi.create.foundation.utility.Pair;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.client.Minecraft;
@ -47,7 +55,8 @@ public class TrackGraph {
Map<Integer, TrackNode> nodesById;
Map<TrackNode, Map<TrackNode, TrackEdge>> connectionsByNode;
Map<UUID, GlobalStation> stations;
private Map<UUID, GlobalStation> stations;
private Map<UUID, SignalBoundary> signals;
public TrackGraph() {
this(UUID.randomUUID());
@ -60,6 +69,7 @@ public class TrackGraph {
connectionsByNode = new IdentityHashMap<>();
color = Color.rainbowColor(new Random(graphID.getLeastSignificantBits()).nextInt());
stations = new HashMap<>();
signals = new HashMap<>();
}
//
@ -69,17 +79,41 @@ public class TrackGraph {
return stations.get(id);
}
@Nullable
public SignalBoundary getSignal(UUID id) {
return signals.get(id);
}
public Collection<GlobalStation> getStations() {
return stations.values();
}
public Collection<SignalBoundary> getSignals() {
return signals.values();
}
public void addStation(GlobalStation station) {
stations.put(station.id, station);
SignalPropagator.onEdgePointAdded(this, station, GlobalStation.class);
markDirty();
}
public void addSignal(SignalBoundary signal) {
signals.put(signal.id, signal);
SignalPropagator.onEdgePointAdded(this, signal, SignalBoundary.class);
markDirty();
}
public void removeStation(UUID id) {
stations.remove(id);
markDirty();
}
public void addStation(GlobalStation station) {
stations.put(station.id, station);
public void removeSignal(UUID id) {
SignalBoundary signal = signals.remove(id);
if (signal == null)
return;
SignalPropagator.onSignalRemoved(this, signal);
markDirty();
}
@ -104,7 +138,8 @@ public class TrackGraph {
public boolean createNode(DiscoveredLocation location) {
if (!createSpecificNode(location, nextNodeId(), location.normal))
return false;
Create.RAILWAYS.sync.nodeAdded(this, nodes.get(location));
TrackNode newNode = nodes.get(location);
Create.RAILWAYS.sync.nodeAdded(this, newNode);
markDirty();
return true;
}
@ -157,6 +192,10 @@ public class TrackGraph {
return true;
Map<TrackNode, TrackEdge> connections = connectionsByNode.remove(removed);
for (TrackEdge trackEdge : connections.values())
for (SignalBoundary boundary : trackEdge.getEdgeData()
.getBoundaries())
signals.remove(boundary.id);
for (TrackNode railNode : connections.keySet())
if (connectionsByNode.containsKey(railNode))
connectionsByNode.get(railNode)
@ -352,7 +391,8 @@ public class TrackGraph {
});
tag.put("Nodes", nodesList);
tag.put("Stations", NBTHelper.writeCompoundList(stations.values(), GlobalStation::write));
tag.put("Stations", NBTHelper.writeCompoundList(getStations(), GlobalStation::write));
tag.put("Signals", NBTHelper.writeCompoundList(getSignals(), SignalBoundary::write));
return tag;
}
@ -360,6 +400,11 @@ public class TrackGraph {
TrackGraph graph = new TrackGraph(tag.getUUID("Id"));
graph.color = new Color(tag.getInt("Color"));
NBTHelper.readCompoundList(tag.getList("Signals", Tag.TAG_COMPOUND), SignalBoundary::new)
.forEach(s -> graph.signals.put(s.id, s));
NBTHelper.readCompoundList(tag.getList("Stations", Tag.TAG_COMPOUND), GlobalStation::new)
.forEach(s -> graph.stations.put(s.id, s));
Map<Integer, TrackNode> indexTracker = new HashMap<>();
ListTag nodesList = tag.getList("Nodes", Tag.TAG_COMPOUND);
@ -384,16 +429,112 @@ public class TrackGraph {
continue;
NBTHelper.iterateCompoundList(nodeTag.getList("Connections", Tag.TAG_COMPOUND), c -> {
TrackNode node2 = indexTracker.get(c.getInt("To"));
TrackEdge edge = TrackEdge.read(c.getCompound("EdgeData"));
TrackEdge edge = TrackEdge.read(c.getCompound("EdgeData"), graph);
edge.edgeData.updateDelegates(node1, node2, edge);
graph.putConnection(node1, node2, edge);
});
}
NBTHelper.readCompoundList(tag.getList("Stations", Tag.TAG_COMPOUND), GlobalStation::new)
.forEach(s -> graph.stations.put(s.id, s));
return graph;
}
public void debugViewSignalData() {
Entity cameraEntity = Minecraft.getInstance().cameraEntity;
if (cameraEntity == null)
return;
Vec3 camera = cameraEntity.getEyePosition();
for (Entry<TrackNodeLocation, TrackNode> nodeEntry : nodes.entrySet()) {
TrackNodeLocation nodeLocation = nodeEntry.getKey();
TrackNode node = nodeEntry.getValue();
if (nodeLocation == null)
continue;
Vec3 location = nodeLocation.getLocation();
if (location.distanceTo(camera) > 50)
continue;
Map<TrackNode, TrackEdge> map = connectionsByNode.get(node);
if (map == null)
continue;
int hashCode = node.hashCode();
for (Entry<TrackNode, TrackEdge> entry : map.entrySet()) {
TrackNode other = entry.getKey();
if (other.hashCode() > hashCode && !AllKeys.isKeyDown(GLFW.GLFW_KEY_LEFT_CONTROL))
continue;
Vec3 yOffset = new Vec3(0, (other.hashCode() > hashCode ? 6 : 4) / 16f, 0);
TrackEdge edge = entry.getValue();
EdgeData signalData = edge.getEdgeData();
UUID singleGroup = signalData.singleSignalGroup;
SignalEdgeGroup signalEdgeGroup =
singleGroup == null ? null : Create.RAILWAYS.signalEdgeGroups.get(singleGroup);
if (!edge.isTurn()) {
Vec3 p1 = edge.getPosition(node, other, 0);
Vec3 p2 = edge.getPosition(node, other, 1);
if (signalData.hasBoundaries()) {
SignalBoundary boundary = signalData.nextBoundary(node, other, edge, 0);
SignalBoundary prevBoundaryNonNull = boundary;
double prev = 0;
double length = edge.getLength(node, other);
SignalEdgeGroup group = Create.RAILWAYS.signalEdgeGroups.get(boundary.getGroup(node));
while (boundary != null) {
if (group != null)
CreateClient.OUTLINER
.showLine(Pair.of(boundary, edge),
edge.getPosition(node, other, prev + (prev == 0 ? 0 : 1 / 16f / length))
.add(yOffset),
edge.getPosition(node, other,
(prev = boundary.getLocationOn(node, other, edge) / length)
- 1 / 16f / length)
.add(yOffset))
.colored(group.color.getRGB())
.lineWidth(1 / 16f);
boundary =
signalData.nextBoundary(node, other, edge, boundary.getLocationOn(node, other, edge));
if (boundary != null) {
group = Create.RAILWAYS.signalEdgeGroups.get(boundary.getGroup(node));
prevBoundaryNonNull = boundary;
}
}
group = Create.RAILWAYS.signalEdgeGroups.get(prevBoundaryNonNull.getGroup(other));
if (group != null)
CreateClient.OUTLINER.showLine(edge, edge.getPosition(node, other, prev + 1 / 16f / length)
.add(yOffset), p2.add(yOffset))
.colored(group.color.getRGB())
.lineWidth(1 / 16f);
continue;
}
if (signalEdgeGroup == null)
continue;
CreateClient.OUTLINER.showLine(edge, p1.add(yOffset), p2.add(yOffset))
.colored(signalEdgeGroup.color.getRGB())
.lineWidth(1 / 16f);
continue;
}
if (signalEdgeGroup == null)
continue;
Vec3 previous = null;
BezierConnection turn = edge.getTurn();
for (int i = 0; i <= turn.getSegmentCount(); i++) {
Vec3 current = edge.getPosition(node, other, i * 1f / turn.getSegmentCount());
if (previous != null)
CreateClient.OUTLINER
.showLine(Pair.of(edge, previous), previous.add(yOffset), current.add(yOffset))
.colored(signalEdgeGroup.color.getRGB())
.lineWidth(1 / 16f);
previous = current;
}
}
}
}
public void debugViewNodes() {
Entity cameraEntity = Minecraft.getInstance().cameraEntity;
if (cameraEntity == null)
@ -411,10 +552,10 @@ public class TrackGraph {
Vec3 yOffset = new Vec3(0, 3 / 16f, 0);
Vec3 v1 = location.add(yOffset);
Vec3 v2 = v1.add(node.normal.scale(0.125f));
Vec3 v2 = v1.add(node.normal.scale(3 / 16f));
CreateClient.OUTLINER.showLine(Integer.valueOf(node.netId), v1, v2)
.colored(Color.mixColors(Color.WHITE, color, 1))
.lineWidth(1 / 4f);
.lineWidth(1 / 8f);
Map<TrackNode, TrackEdge> map = connectionsByNode.get(node);
if (map == null)
@ -424,8 +565,9 @@ public class TrackGraph {
for (Entry<TrackNode, TrackEdge> entry : map.entrySet()) {
TrackNode other = entry.getKey();
if (other.hashCode() > hashCode)
if (other.hashCode() > hashCode && !AllKeys.isKeyDown(GLFW.GLFW_KEY_LEFT_CONTROL))
continue;
yOffset = new Vec3(0, (other.hashCode() > hashCode ? 6 : 4) / 16f, 0);
TrackEdge edge = entry.getValue();
if (!edge.isTurn()) {
@ -443,7 +585,8 @@ public class TrackGraph {
for (int i = 0; i <= turn.getSegmentCount(); i++) {
Vec3 current = edge.getPosition(node, other, i * 1f / turn.getSegmentCount());
if (previous != null)
CreateClient.OUTLINER.showLine(previous, previous.add(yOffset), current.add(yOffset))
CreateClient.OUTLINER
.showLine(Pair.of(edge, previous), previous.add(yOffset), current.add(yOffset))
.colored(color)
.lineWidth(1 / 16f);
previous = current;

View file

@ -106,7 +106,7 @@ public class TrackGraphHelper {
frontNode = node;
if (backwards) {
backNode = node;
position = distance + .5;
position = distance + axis.length() / 2;
}
break;
}

View file

@ -9,6 +9,7 @@ import java.util.Set;
import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation.DiscoveredLocation;
import com.simibubi.create.content.logistics.trains.management.signal.SignalPropagator;
import net.minecraft.core.BlockPos;
import net.minecraft.util.Mth;
@ -40,7 +41,7 @@ public class TrackPropagator {
TrackGraph foundGraph = null;
// 1. Remove any nodes this rail was part of
for (DiscoveredLocation removedLocation : ends) {
if (foundGraph == null)
foundGraph = manager.getGraph(reader, removedLocation);
@ -63,7 +64,7 @@ public class TrackPropagator {
positionsToUpdate.addAll(removedEnd.allAdjacent());
// 2. Re-run railAdded for any track that was disconnected from this track
Set<TrackGraph> toUpdate = new HashSet<>();
for (BlockPos blockPos : positionsToUpdate)
if (!blockPos.equals(pos)) {
@ -71,7 +72,7 @@ public class TrackPropagator {
if (onRailAdded != null)
toUpdate.add(onRailAdded);
}
// 3. Ensure any affected graph gets checked for segmentation
for (TrackGraph railGraph : toUpdate)
@ -171,8 +172,11 @@ public class TrackPropagator {
}
frontier.clear();
if (graph.createNode(startNode))
sync.nodeAdded(graph, graph.locateNode(startNode));
Set<TrackNode> addedNodes = new HashSet<>();
if (graph.createNode(startNode)) {
TrackNode node = graph.locateNode(startNode);
sync.nodeAdded(graph, node);
}
frontier.add(new FrontierEntry(startNode, null, startNode));
@ -192,9 +196,12 @@ public class TrackPropagator {
if (isValidGraphNodeLocation(entry.currentNode, ends, first) && entry.currentNode != startNode) {
boolean nodeIsNew = graph.createNode(entry.currentNode);
if (nodeIsNew)
sync.nodeAdded(graph, graph.locateNode(entry.currentNode));
if (nodeIsNew) {
TrackNode node = graph.locateNode(entry.currentNode);
sync.nodeAdded(graph, node);
}
graph.connectNodes(parentNode, entry.currentNode, new TrackEdge(entry.currentNode.getTurn()));
addedNodes.add(graph.locateNode(entry.currentNode));
parentNode = entry.currentNode;
if (!nodeIsNew)
continue;
@ -204,6 +211,8 @@ public class TrackPropagator {
}
manager.markTracksDirty();
for (TrackNode trackNode : addedNodes)
SignalPropagator.notifySignalsOfNewNode(graph, trackNode);
return graph;
}

View file

@ -5,6 +5,7 @@ import java.util.Map;
import java.util.UUID;
import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.management.signal.SignalEdgeGroup;
import com.simibubi.create.foundation.utility.NBTHelper;
import net.minecraft.nbt.CompoundTag;
@ -15,26 +16,38 @@ import net.minecraft.world.level.saveddata.SavedData;
public class TrackSavedData extends SavedData {
private Map<UUID, TrackGraph> trackNetworks = new HashMap<>();
private Map<UUID, SignalEdgeGroup> signalEdgeGroups = new HashMap<>();
@Override
public CompoundTag save(CompoundTag nbt) {
nbt.put("RailGraphs", NBTHelper.writeCompoundList(Create.RAILWAYS.trackNetworks.values(), TrackGraph::write));
nbt.put("SignalBlocks",
NBTHelper.writeCompoundList(Create.RAILWAYS.signalEdgeGroups.values(), SignalEdgeGroup::write));
return nbt;
}
private static TrackSavedData load(CompoundTag nbt) {
TrackSavedData sd = new TrackSavedData();
sd.trackNetworks = new HashMap<>();
sd.signalEdgeGroups = new HashMap<>();
NBTHelper.iterateCompoundList(nbt.getList("RailGraphs", Tag.TAG_COMPOUND), c -> {
TrackGraph graph = TrackGraph.read(c);
sd.trackNetworks.put(graph.id, graph);
});
NBTHelper.iterateCompoundList(nbt.getList("SignalBlocks", Tag.TAG_COMPOUND), c -> {
SignalEdgeGroup group = SignalEdgeGroup.read(c);
sd.signalEdgeGroups.put(group.id, group);
});
return sd;
}
public Map<UUID, TrackGraph> getTrackNetworks() {
return trackNetworks;
}
public Map<UUID, SignalEdgeGroup> getSignalBlocks() {
return signalEdgeGroups;
}
private TrackSavedData() {}

View file

@ -11,6 +11,7 @@ import org.apache.commons.lang3.mutable.MutableDouble;
import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.IBogeyBlock;
import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ISignalBoundaryListener;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ITrackSelector;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.Couple;
@ -41,6 +42,8 @@ public class Carriage {
WeakReference<CarriageContraptionEntity> entity;
Couple<CarriageBogey> bogeys;
static final int FIRST = 0, MIDDLE = 1, LAST = 2, BOTH = 3;
public Carriage(CarriageBogey bogey1, @Nullable CarriageBogey bogey2, int bogeySpacing) {
this.bogeySpacing = bogeySpacing;
this.bogeys = Couple.create(bogey1, bogey2);
@ -63,7 +66,7 @@ public class Carriage {
public double travel(Level level, TrackGraph graph, double distance,
Function<TravellingPoint, ITrackSelector> forwardControl,
Function<TravellingPoint, ITrackSelector> backwardControl) {
Function<TravellingPoint, ITrackSelector> backwardControl, int type) {
Vec3 leadingAnchor = leadingBogey().anchorPosition;
Vec3 trailingAnchor = trailingBogey().anchorPosition;
boolean onTwoBogeys = isOnTwoBogeys();
@ -98,9 +101,18 @@ public class Carriage {
ITrackSelector backTrackSelector =
nextPoint == null ? backwardControl.apply(point) : point.follow(nextPoint);
double moved = point.travel(graph, toMove, toMove > 0 ? frontTrackSelector : backTrackSelector);
double stressCorrection = correction + bogeyCorrection;
point.travel(graph, stressCorrection, stressCorrection > 0 ? frontTrackSelector : backTrackSelector);
boolean atFront = (type == FIRST || type == BOTH) && actuallyFirstWheel && actuallyFirstBogey;
boolean atBack =
(type == LAST || type == BOTH) && !actuallyFirstWheel && (!actuallyFirstBogey || !onTwoBogeys);
ISignalBoundaryListener frontListener = train.frontSignalListener();
ISignalBoundaryListener backListener = train.backSignalListener();
ISignalBoundaryListener passiveListener = point.ignoreSignals();
toMove += correction + bogeyCorrection;
double moved = point.travel(graph, toMove, toMove > 0 ? frontTrackSelector : backTrackSelector,
toMove > 0 ? atFront ? frontListener : atBack ? backListener : passiveListener
: atFront ? backListener : atBack ? frontListener : passiveListener);
blocked |= point.blocked;
distanceMoved.setValue(moved);

View file

@ -12,6 +12,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Ori
import com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls.ControlsBlock;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.SteerDirection;
import com.simibubi.create.content.logistics.trains.management.GlobalStation;
import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.utility.Color;
import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Lang;
@ -197,7 +198,8 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
carriage.train.manualSteer =
targetSteer < 0 ? SteerDirection.RIGHT : targetSteer > 0 ? SteerDirection.LEFT : SteerDirection.NONE;
carriage.train.targetSpeed = Train.topSpeed * targetSpeed;
double topSpeed = AllConfigs.SERVER.trains.getTopSpeedMPT();
carriage.train.targetSpeed = topSpeed * targetSpeed;
if (slow)
carriage.train.targetSpeed /= 8;
boolean counteringAcceleration = Math.abs(Math.signum(targetSpeed) - Math.signum(carriage.train.speed)) > 1.5f;

View file

@ -8,16 +8,22 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.PriorityQueue;
import java.util.Set;
import java.util.UUID;
import java.util.function.BiPredicate;
import org.apache.commons.lang3.mutable.MutableObject;
import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.TrackEdge;
import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ITrackSelector;
import com.simibubi.create.content.logistics.trains.management.GlobalStation;
import com.simibubi.create.content.logistics.trains.management.signal.EdgeData;
import com.simibubi.create.content.logistics.trains.management.signal.SignalBoundary;
import com.simibubi.create.content.logistics.trains.management.signal.SignalEdgeGroup;
import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.Pair;
@ -33,9 +39,14 @@ public class Navigation {
public boolean destinationBehindTrain;
List<TrackEdge> currentPath;
public Navigation(Train train, TrackGraph graph) {
private TravellingPoint signalScout;
public Pair<UUID, Boolean> waitingForSignal;
public double distanceToSignal;
public Navigation(Train train) {
this.train = train;
currentPath = new ArrayList<>();
signalScout = new TravellingPoint();
}
public void tick(Level level) {
@ -65,36 +76,105 @@ public class Navigation {
destination.reserveFor(train);
if (distanceToDestination < 1 / 32f) {
distanceToDestination = 0;
double acceleration = AllConfigs.SERVER.trains.getAccelerationMPTT();
double brakingDistance = (train.speed * train.speed) / (2 * acceleration);
double speedMod = destinationBehindTrain ? -1 : 1;
// Signals
if (train.graph != null) {
if (waitingForSignal != null && checkBlockingSignal())
waitingForSignal = null;
TravellingPoint leadingPoint = train.speed > 0 ? train.carriages.get(0)
.getLeadingPoint()
: train.carriages.get(train.carriages.size() - 1)
.getTrailingPoint();
if (waitingForSignal == null)
distanceToSignal = Double.MAX_VALUE;
if (distanceToSignal > 1 / 16f) {
signalScout.node1 = leadingPoint.node1;
signalScout.node2 = leadingPoint.node2;
signalScout.edge = leadingPoint.edge;
signalScout.position = leadingPoint.position;
double brakingDistanceNoFlicker = brakingDistance + 3 - (brakingDistance % 3);
double scanDistance = Math.min(distanceToDestination - .5f, brakingDistanceNoFlicker);
signalScout.travel(train.graph, scanDistance * speedMod, controlSignalScout(), (distance, couple) -> {
UUID entering = couple.getSecond()
.getSecond();
SignalEdgeGroup signalEdgeGroup = Create.RAILWAYS.signalEdgeGroups.get(entering);
if (signalEdgeGroup == null)
return;
SignalBoundary boundary = couple.getFirst();
if (signalEdgeGroup.isOccupiedUnless(train)) {
distanceToSignal = Math.min(distance, distanceToSignal);
waitingForSignal = Pair.of(boundary.id, entering.equals(boundary.groups.getFirst()));
return;
}
signalEdgeGroup.reserved = boundary;
});
}
}
double targetDistance = waitingForSignal != null ? distanceToSignal : distanceToDestination;
if (targetDistance < 1 / 32f) {
train.speed = 0;
if (waitingForSignal != null) {
distanceToSignal = 0;
return;
}
distanceToDestination = 0;
currentPath.clear();
train.arriveAt(destination);
destination = null;
return;
}
float speedMod = destinationBehindTrain ? -1 : 1;
train.currentlyBackwards = destinationBehindTrain;
if (distanceToDestination - Math.abs(train.speed) < 1 / 32f) {
train.speed = distanceToDestination * speedMod;
if (targetDistance - Math.abs(train.speed) < 1 / 32f) {
train.speed = targetDistance * speedMod;
return;
}
if (distanceToDestination < 10) {
double target = Train.topSpeed * ((distanceToDestination) / 10);
double topSpeed = AllConfigs.SERVER.trains.getTopSpeedMPT();
if (targetDistance < 10) {
double target = topSpeed * ((targetDistance) / 10);
if (target < Math.abs(train.speed)) {
train.speed += (target - Math.abs(train.speed)) * .5f * speedMod;
return;
}
}
double brakingDistance = (train.speed * train.speed) / (2 * Train.acceleration);
train.targetSpeed = distanceToDestination > brakingDistance ? Train.topSpeed * speedMod : 0;
train.targetSpeed = targetDistance > brakingDistance ? topSpeed * speedMod : 0;
train.approachTargetSpeed(1);
}
private boolean checkBlockingSignal() {
if (distanceToDestination < .5f)
return true;
SignalBoundary signal = train.graph.getSignal(waitingForSignal.getFirst());
if (signal == null)
return true;
UUID groupId = signal.groups.get(waitingForSignal.getSecond());
if (groupId == null)
return true;
SignalEdgeGroup signalEdgeGroup = Create.RAILWAYS.signalEdgeGroups.get(groupId);
if (signalEdgeGroup == null)
return true;
if (!signalEdgeGroup.isOccupiedUnless(train)) {
if (train.currentStation != null)
train.leaveStation();
return true;
}
return false;
}
public boolean isActive() {
return destination != null;
}
@ -103,20 +183,40 @@ public class Navigation {
if (destination == null)
return mp.steer(train.manualSteer, new Vec3(0, 1, 0));
return (graph, pair) -> {
if (!currentPath.isEmpty()) {
TrackEdge target = currentPath.get(0);
for (Entry<TrackNode, TrackEdge> entry : pair.getSecond()) {
if (entry.getValue() == target) {
currentPath.remove(0);
return entry;
}
}
List<Entry<TrackNode, TrackEdge>> options = pair.getSecond();
if (currentPath.isEmpty())
return options.get(0);
TrackEdge target = currentPath.get(0);
for (Entry<TrackNode, TrackEdge> entry : options) {
if (entry.getValue() != target)
continue;
currentPath.remove(0);
return entry;
}
return pair.getSecond()
.get(0);
return options.get(0);
};
}
public ITrackSelector controlSignalScout() {
if (destination == null)
return signalScout.steer(train.manualSteer, new Vec3(0, 1, 0));
List<TrackEdge> pathCopy = new ArrayList<>(currentPath);
return (graph, pair) -> {
List<Entry<TrackNode, TrackEdge>> options = pair.getSecond();
if (pathCopy.isEmpty())
return options.get(0);
TrackEdge target = pathCopy.get(0);
for (Entry<TrackNode, TrackEdge> entry : options) {
if (entry.getValue() != target)
continue;
pathCopy.remove(0);
return entry;
}
return options.get(0);
};
}
public void cancelNavigation() {
distanceToDestination = 0;
currentPath.clear();
@ -137,7 +237,6 @@ public class Navigation {
distanceToDestination = distance;
currentPath = pathTo.getSecond();
destinationBehindTrain = pathTo.getFirst() < 0;
if (noneFound) {
distanceToDestination = 0;
@ -146,9 +245,11 @@ public class Navigation {
return -1;
}
destinationBehindTrain = pathTo.getFirst() < 0;
if (this.destination == destination)
return 0;
if (!train.runtime.paused) {
boolean frontDriver = train.hasForwardConductor();
boolean backDriver = train.hasBackwardConductor();
@ -171,7 +272,20 @@ public class Navigation {
train.status.foundConductor();
}
train.leaveStation();
GlobalStation currentStation = train.getCurrentStation();
if (currentStation != null) {
SignalBoundary boundary = currentStation.boundary;
if (boundary != null) {
TrackNode node1 = train.graph.locateNode(currentStation.edgeLocation.getFirst());
UUID group = boundary.getGroup(node1);
if (group != null) {
waitingForSignal = Pair.of(boundary.id, !boundary.isPrimary(node1));
distanceToSignal = 0;
}
} else
train.leaveStation();
}
this.destination = destination;
return distanceToDestination;
}
@ -265,8 +379,9 @@ public class Navigation {
return null;
MutableObject<GlobalStation> result = new MutableObject<>(null);
double minDistance = .75f * (train.speed * train.speed) / (2 * Train.acceleration);
double maxDistance = Math.max(32, 1.5f * (train.speed * train.speed) / (2 * Train.acceleration));
double acceleration = AllConfigs.SERVER.trains.getAccelerationMPTT();
double minDistance = .75f * (train.speed * train.speed) / (2 * acceleration);
double maxDistance = Math.max(32, 1.5f * (train.speed * train.speed) / (2 * acceleration));
search(maxDistance, forward, (reachedVia, poll) -> {
double distance = poll.getFirst();
@ -280,7 +395,8 @@ public class Navigation {
TrackNode node2 = currentEntry.getFirst()
.getSecond();
for (GlobalStation globalStation : graph.getStations()) {
for (GlobalStation globalStation : edge.getEdgeData()
.getStations()) {
Couple<TrackNodeLocation> target = globalStation.edgeLocation;
TrackNodeLocation loc1 = node1.getLocation();
TrackNodeLocation loc2 = node2.getLocation();
@ -340,16 +456,23 @@ public class Navigation {
return;
List<Entry<TrackNode, TrackEdge>> validTargets = new ArrayList<>();
for (Entry<TrackNode, TrackEdge> entry : graph.getConnectionsFrom(node2)
EdgeWalk: for (Entry<TrackNode, TrackEdge> entry : graph.getConnectionsFrom(node2)
.entrySet()) {
TrackNode newNode = entry.getKey();
TrackEdge newEdge = entry.getValue();
Vec3 currentDirection = edge.getDirection(node1, node2, false);
Vec3 newDirection = newEdge.getDirection(node2, newNode, true);
if (currentDirection.dot(newDirection) < 0)
if (currentDirection.dot(newDirection) < 3 / 4f)
continue;
if (!visited.add(entry.getValue()))
continue;
EdgeData signalData = newEdge.getEdgeData();
if (signalData.hasBoundaries())
for (SignalBoundary boundary : signalData.getBoundaries())
if (!boundary.canNavigateVia(node2))
continue EdgeWalk;
validTargets.add(entry);
}

View file

@ -9,23 +9,32 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import javax.annotation.Nullable;
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.apache.commons.lang3.mutable.MutableObject;
import com.simibubi.create.Create;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.logistics.trains.TrackEdge;
import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.entity.Carriage.CarriageBogey;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ISignalBoundaryListener;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ITrackSelector;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.SteerDirection;
import com.simibubi.create.content.logistics.trains.management.GlobalStation;
import com.simibubi.create.content.logistics.trains.management.GraphLocation;
import com.simibubi.create.content.logistics.trains.management.ScheduleRuntime;
import com.simibubi.create.content.logistics.trains.management.ScheduleRuntime.State;
import com.simibubi.create.content.logistics.trains.management.signal.EdgeData;
import com.simibubi.create.content.logistics.trains.management.signal.SignalBoundary;
import com.simibubi.create.content.logistics.trains.management.signal.SignalEdgeGroup;
import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.VecHelper;
@ -42,9 +51,6 @@ import net.minecraft.world.phys.Vec3;
public class Train {
public static final double acceleration = 0.005f;
public static final double topSpeed = 1.2f;
public double speed = 0;
public double targetSpeed = 0;
@ -68,6 +74,9 @@ public class Train {
public List<Carriage> carriages;
public List<Integer> carriageSpacing;
public boolean updateSignalBlocks;
public List<UUID> occupiedSignalBlocks;
List<TrainMigration> migratingPoints;
public int migrationCooldown;
public boolean derailed;
@ -92,22 +101,40 @@ public class Train {
doubleEnded = carriages.stream()
.anyMatch(c -> c.contraption.hasBackwardControls());
navigation = new Navigation(this, graph);
navigation = new Navigation(this);
runtime = new ScheduleRuntime(this);
heldForAssembly = true;
migratingPoints = new ArrayList<>();
currentStation = null;
manualSteer = SteerDirection.NONE;
occupiedSignalBlocks = new ArrayList<>();
}
public void earlyTick(Level level) {
status.tick(level);
if (graph == null && !migratingPoints.isEmpty())
reattachToTracks(level);
if (graph == null)
return;
if (updateSignalBlocks) {
updateSignalBlocks = false;
collectInitiallyOccupiedSignalBlocks();
}
for (Iterator<UUID> iterator = occupiedSignalBlocks.iterator(); iterator.hasNext();) {
SignalEdgeGroup signalEdgeGroup = Create.RAILWAYS.signalEdgeGroups.get(iterator.next());
if (signalEdgeGroup == null) {
iterator.remove();
continue;
}
signalEdgeGroup.trains.add(this);
}
}
public void tick(Level level) {
status.tick(level);
if (graph == null) {
if (!migratingPoints.isEmpty())
reattachToTracks(level);
if (graph == null)
return;
}
updateConductors();
runtime.tick(level);
@ -119,8 +146,9 @@ public class Train {
double distance = speed;
Carriage previousCarriage = null;
int carriageCount = carriages.size();
for (int i = 0; i < carriages.size(); i++) {
for (int i = 0; i < carriageCount; i++) {
Carriage carriage = carriages.get(i);
if (previousCarriage != null) {
int target = carriageSpacing.get(i - 1);
@ -142,8 +170,8 @@ public class Train {
boolean blocked = false;
boolean iterateFromBack = speed < 0;
for (int index = 0; index < carriages.size(); index++) {
int i = iterateFromBack ? carriages.size() - 1 - index : index;
for (int index = 0; index < carriageCount; index++) {
int i = iterateFromBack ? carriageCount - 1 - index : index;
double leadingStress = i == 0 ? 0 : stress[i - 1] * -(iterateFromBack ? trailingModifier : leadingModifier);
double trailingStress =
i == stress.length ? 0 : stress[i] * (iterateFromBack ? leadingModifier : trailingModifier);
@ -154,7 +182,7 @@ public class Train {
: carriages.get(i - 1)
.getTrailingPoint();
TravellingPoint toFollowBackward = i == carriages.size() - 1 ? null
TravellingPoint toFollowBackward = i == carriageCount - 1 ? null
: carriages.get(i + 1)
.getLeadingPoint();
@ -164,8 +192,11 @@ public class Train {
toFollowBackward == null ? navigation::control : mp -> mp.follow(toFollowBackward);
double totalStress = leadingStress + trailingStress;
boolean first = i == 0;
boolean last = i == carriageCount - 1;
int carriageType = first ? last ? Carriage.BOTH : Carriage.FIRST : last ? Carriage.LAST : Carriage.MIDDLE;
double actualDistance =
carriage.travel(level, graph, distance + totalStress, forwardControl, backwardControl);
carriage.travel(level, graph, distance + totalStress, forwardControl, backwardControl, carriageType);
blocked |= carriage.blocked;
if (index == 0) {
@ -185,14 +216,44 @@ public class Train {
updateNavigationTarget(distance);
}
public ISignalBoundaryListener frontSignalListener() {
return (distance, couple) -> {
UUID groupId = couple.getSecond()
.getSecond();
SignalEdgeGroup signalEdgeGroup = Create.RAILWAYS.signalEdgeGroups.get(groupId);
SignalBoundary boundary = couple.getFirst();
if (signalEdgeGroup != null) {
signalEdgeGroup.reserved = boundary;
occupiedSignalBlocks.add(groupId);
}
};
}
public ISignalBoundaryListener backSignalListener() {
return (distance, couple) -> {
occupiedSignalBlocks.remove(couple.getSecond()
.getFirst());
};
}
private void updateNavigationTarget(double distance) {
if (navigation.destination != null) {
boolean recalculate = navigation.distanceToDestination % 100 > 20;
boolean imminentRecalculate = navigation.distanceToDestination > 5;
navigation.distanceToDestination -= Math.abs(distance);
if (recalculate && navigation.distanceToDestination % 100 <= 20
|| imminentRecalculate && navigation.distanceToDestination <= 5)
boolean signalMode = navigation.waitingForSignal != null;
if (signalMode) {
navigation.distanceToSignal -= Math.abs(distance);
recalculate = navigation.distanceToSignal % 100 > 20;
}
if (recalculate && (signalMode ? navigation.distanceToSignal : navigation.distanceToDestination) % 100 <= 20
|| imminentRecalculate && navigation.distanceToDestination <= 5) {
if (signalMode) {
navigation.waitingForSignal = null;
return;
}
navigation.startNavigation(navigation.destination, false);
}
}
}
@ -204,9 +265,10 @@ public class Train {
private void tickPassiveSlowdown() {
if (!manualTick && navigation.destination == null && speed != 0) {
if (speed > 0)
double acceleration = AllConfigs.SERVER.trains.getAccelerationMPTT();
if (speed > 0) {
speed = Math.max(speed - acceleration, 0);
else
} else
speed = Math.min(speed + acceleration, 0);
}
manualTick = false;
@ -375,6 +437,39 @@ public class Train {
}
}
public void forEachTravellingPointBackwards(BiConsumer<TravellingPoint, Double> callback) {
double lastWheelOffset = 0;
for (int i = 0; i < carriages.size(); i++) {
int index = carriages.size() - i - 1;
Carriage carriage = carriages.get(index);
CarriageBogey trailingBogey = carriage.trailingBogey();
double trailSpacing = trailingBogey.type.getWheelPointSpacing();
// trailing point
callback.accept(trailingBogey.trailing(),
i == 0 ? 0 : carriageSpacing.get(index) - lastWheelOffset - trailSpacing / 2);
// inside 1st bogey
callback.accept(trailingBogey.leading(), trailSpacing);
lastWheelOffset = trailSpacing / 2;
if (!carriage.isOnTwoBogeys())
continue;
CarriageBogey leadingBogey = carriage.leadingBogey();
double leadSpacing = carriage.leadingBogey().type.getWheelPointSpacing();
// between bogeys
callback.accept(leadingBogey.trailing(), carriage.bogeySpacing - lastWheelOffset - leadSpacing / 2);
// inside 2nd bogey
callback.accept(trailingBogey.leading(), leadSpacing);
lastWheelOffset = leadSpacing / 2;
}
}
public void reattachToTracks(Level level) {
if (migrationCooldown > 0) {
migrationCooldown--;
@ -418,6 +513,7 @@ public class Train {
GlobalStation currentStation = getCurrentStation();
if (currentStation != null)
currentStation.reserveFor(this);
updateSignalBlocks = true;
return;
}
}
@ -478,10 +574,72 @@ public class Train {
return;
if (manualTick)
leaveStation();
double acceleration = AllConfigs.SERVER.trains.getAccelerationMPTT();
if (speed < targetSpeed)
speed = Math.min(speed + Train.acceleration * accelerationMod, targetSpeed);
speed = Math.min(speed + acceleration * accelerationMod, targetSpeed);
else if (speed > targetSpeed)
speed = Math.max(speed - Train.acceleration * accelerationMod, targetSpeed);
speed = Math.max(speed - acceleration * accelerationMod, targetSpeed);
}
public void collectInitiallyOccupiedSignalBlocks() {
TravellingPoint trailingPoint = carriages.get(carriages.size() - 1)
.getTrailingPoint();
TrackNode node1 = trailingPoint.node1;
TrackNode node2 = trailingPoint.node2;
TrackEdge edge = trailingPoint.edge;
double position = trailingPoint.position;
EdgeData signalData = edge.getEdgeData();
occupiedSignalBlocks.clear();
TravellingPoint signalScout = new TravellingPoint(node1, node2, edge, position);
Map<UUID, SignalEdgeGroup> allGroups = Create.RAILWAYS.signalEdgeGroups;
MutableObject<UUID> prevGroup = new MutableObject<>(null);
if (signalData.hasBoundaries()) {
SignalBoundary nextBoundary = signalData.nextBoundary(node1, node2, edge, position);
if (nextBoundary == null) {
double d = 0;
SignalBoundary prev = null;
SignalBoundary current = signalData.nextBoundary(node1, node2, edge, 0);
while (current != null) {
prev = current;
d = current.getLocationOn(node1, node2, edge);
current = signalData.nextBoundary(node1, node2, edge, d);
}
if (prev != null) {
UUID group = prev.getGroup(node2);
if (Create.RAILWAYS.signalEdgeGroups.containsKey(group)) {
occupiedSignalBlocks.add(group);
prevGroup.setValue(group);
}
}
} else {
UUID group = nextBoundary.getGroup(node1);
if (Create.RAILWAYS.signalEdgeGroups.containsKey(group)) {
occupiedSignalBlocks.add(group);
prevGroup.setValue(group);
}
}
} else if (signalData.singleSignalGroup != null && allGroups.containsKey(signalData.singleSignalGroup)) {
occupiedSignalBlocks.add(signalData.singleSignalGroup);
prevGroup.setValue(signalData.singleSignalGroup);
}
forEachTravellingPointBackwards((tp, d) -> {
signalScout.travel(graph, d, signalScout.follow(tp), (distance, couple) -> couple.getSecond()
.forEach(id -> {
if (!Create.RAILWAYS.signalEdgeGroups.containsKey(id))
return;
if (id.equals(prevGroup.getValue()))
return;
occupiedSignalBlocks.add(id);
prevGroup.setValue(id);
}));
});
}
}

View file

@ -8,6 +8,8 @@ import java.util.function.Consumer;
import javax.annotation.Nullable;
import org.apache.commons.lang3.mutable.MutableBoolean;
import com.simibubi.create.AllItems;
import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionHandlerClient;
@ -16,6 +18,7 @@ import com.simibubi.create.content.logistics.trains.TrackEdge;
import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackGraphHelper;
import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ISignalBoundaryListener;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ITrackSelector;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.SteerDirection;
import com.simibubi.create.content.logistics.trains.management.GraphLocation;
@ -125,58 +128,40 @@ public class TrainRelocator {
return false;
TravellingPoint probe = new TravellingPoint(node1, node2, edge, graphLocation.position);
ISignalBoundaryListener ignoreSignals = probe.ignoreSignals();
List<Pair<Couple<TrackNode>, Double>> recordedLocations = new ArrayList<>();
Consumer<TravellingPoint> recorder =
tp -> recordedLocations.add(Pair.of(Couple.create(tp.node1, tp.node2), tp.position));
recorder.accept(probe);
double lastWheelOffset = 0;
ITrackSelector steer = probe.steer(SteerDirection.NONE, track.getUpNormal(level, pos, blockState));
for (int i = 0; i < train.carriages.size(); i++) {
int index = train.carriages.size() - i - 1;
Carriage carriage = train.carriages.get(index);
double trailSpacing = carriage.trailingBogey().type.getWheelPointSpacing();
if (i > 0) {
probe.travel(graph, train.carriageSpacing.get(index) - lastWheelOffset - trailSpacing / 2, steer);
if (probe.blocked)
return false;
recorder.accept(probe);
MutableBoolean blocked = new MutableBoolean(false);
train.forEachTravellingPointBackwards((tp, d) -> {
if (blocked.booleanValue())
return;
probe.travel(graph, d, steer, ignoreSignals);
if (probe.blocked) {
blocked.setTrue();
return;
}
// inside 1st bogey
probe.travel(graph, trailSpacing, steer);
if (probe.blocked)
return false;
recorder.accept(probe);
lastWheelOffset = trailSpacing / 2;
if (!carriage.isOnTwoBogeys())
continue;
double leadSpacing = carriage.leadingBogey().type.getWheelPointSpacing();
// between bogeys
probe.travel(graph, carriage.bogeySpacing - lastWheelOffset - leadSpacing / 2, steer);
if (probe.blocked)
return false;
recorder.accept(probe);
// inside 2nd bogey
probe.travel(graph, leadSpacing, steer);
if (probe.blocked)
return false;
recorder.accept(probe);
lastWheelOffset = leadSpacing / 2;
}
});
if (blocked.booleanValue())
return false;
if (simulate)
return true;
train.leaveStation();
train.derailed = false;
train.navigation.waitingForSignal = null;
train.occupiedSignalBlocks.clear();
train.graph = graph;
train.migratingPoints.clear();
train.speed = 0;
if (train.navigation.destination != null)
train.navigation.cancelNavigation();
train.forEachTravellingPoint(tp -> {
Pair<Couple<TrackNode>, Double> last = recordedLocations.remove(recordedLocations.size() - 1);
tp.node1 = last.getFirst()
@ -189,7 +174,7 @@ public class TrainRelocator {
});
train.status.successfulMigration();
train.leaveStation();
train.collectInitiallyOccupiedSignalBlocks();
return true;
}

View file

@ -5,7 +5,9 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.Vector;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import com.simibubi.create.Create;
@ -13,16 +15,19 @@ import com.simibubi.create.content.logistics.trains.TrackEdge;
import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.management.GraphLocation;
import com.simibubi.create.content.logistics.trains.management.signal.SignalBoundary;
import com.simibubi.create.content.logistics.trains.management.signal.EdgeData;
import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Pair;
import net.minecraft.world.phys.Vec3;
public class TravellingPoint {
TrackNode node1, node2;
TrackEdge edge;
double position;
boolean blocked;
public TrackNode node1, node2;
public TrackEdge edge;
public double position;
public boolean blocked;
public static enum SteerDirection {
NONE(0), LEFT(-1), RIGHT(1);
@ -38,6 +43,11 @@ public class TravellingPoint {
extends BiFunction<TrackGraph, Pair<Boolean, List<Entry<TrackNode, TrackEdge>>>, Entry<TrackNode, TrackEdge>> {
};
public static interface ISignalBoundaryListener extends BiConsumer<Double, Pair<SignalBoundary, Couple<UUID>>> {
};
public TravellingPoint() {}
public TravellingPoint(TrackNode node1, TrackNode node2, TrackEdge edge, double position) {
this.node1 = node1;
this.node2 = node2;
@ -45,6 +55,11 @@ public class TravellingPoint {
this.position = position;
}
public ISignalBoundaryListener ignoreSignals() {
return (d, c) -> {
};
}
public ITrackSelector random() {
return (graph, pair) -> pair.getSecond()
.get(Create.RANDOM.nextInt(pair.getSecond()
@ -133,19 +148,25 @@ public class TravellingPoint {
};
}
public double travel(TrackGraph graph, double distance, ITrackSelector trackSelector) {
public double travel(TrackGraph graph, double distance, ITrackSelector trackSelector,
ISignalBoundaryListener signalListener) {
blocked = false;
double edgeLength = edge.getLength(node1, node2);
if (distance == 0)
return 0;
double prevPos = position;
double traveled = distance;
double currentT = position / edgeLength;
double incrementT = edge.incrementT(node1, node2, currentT, distance);
position = incrementT * edgeLength;
List<Entry<TrackNode, TrackEdge>> validTargets = new ArrayList<>();
if (distance > 0) {
boolean forward = distance > 0;
double collectedDistance = forward ? -prevPos : -edgeLength + prevPos;
edgeTraversedFrom(graph, forward, signalListener, prevPos, collectedDistance);
if (forward) {
// Moving forward
while (position > edgeLength) {
validTargets.clear();
@ -179,6 +200,11 @@ public class TravellingPoint {
node2 = entry.getKey();
edge = entry.getValue();
position -= edgeLength;
collectedDistance += edgeLength;
edgeTraversedFrom(graph, forward, signalListener, 0, collectedDistance);
prevPos = 0;
edgeLength = edge.getLength(node1, node2);
}
@ -217,8 +243,11 @@ public class TravellingPoint {
node1 = entry.getKey();
edge = graph.getConnectionsFrom(node1)
.get(node2);
collectedDistance += edgeLength;
edgeLength = edge.getLength(node1, node2);
position += edgeLength;
edgeTraversedFrom(graph, forward, signalListener, edgeLength, collectedDistance);
}
}
@ -226,6 +255,41 @@ public class TravellingPoint {
return traveled;
}
private void edgeTraversedFrom(TrackGraph graph, boolean forward, ISignalBoundaryListener signalListener,
double prevPos, double totalDistance) {
EdgeData signalsOnEdge = edge.getEdgeData();
if (!signalsOnEdge.hasBoundaries())
return;
double from = forward ? prevPos : position;
double to = forward ? position : prevPos;
SignalBoundary nextBoundary = signalsOnEdge.nextBoundary(node1, node2, edge, from);
List<SignalBoundary> discoveredBoundaries = null;
while (nextBoundary != null) {
double d = nextBoundary.getLocationOn(node1, node2, edge);
if (d > to)
break;
if (discoveredBoundaries == null)
discoveredBoundaries = new ArrayList<>();
discoveredBoundaries.add(nextBoundary);
nextBoundary = signalsOnEdge.nextBoundary(node1, node2, edge, d);
}
if (discoveredBoundaries == null)
return;
for (int i = 0; i < discoveredBoundaries.size(); i++) {
int index = forward ? i : discoveredBoundaries.size() - i - 1;
nextBoundary = discoveredBoundaries.get(index);
double d = nextBoundary.getLocationOn(node1, node2, edge);
if (!forward)
d = edge.getLength(node1, node2) - d;
Couple<UUID> nodes = Couple.create(nextBoundary.getGroup(node1), nextBoundary.getGroup(node2));
signalListener.accept(totalDistance + d, Pair.of(nextBoundary, forward ? nodes : nodes.swap()));
}
}
public void reverse(TrackGraph graph) {
TrackNode n = node1;
node1 = node2;

View file

@ -7,40 +7,38 @@ import javax.annotation.Nullable;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation;
import com.simibubi.create.content.logistics.trains.entity.Train;
import com.simibubi.create.content.logistics.trains.management.signal.SignalBoundary;
import com.simibubi.create.content.logistics.trains.management.signal.TrackEdgePoint;
import com.simibubi.create.foundation.utility.Couple;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.nbt.Tag;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.entity.BlockEntity;
public class GlobalStation {
public class GlobalStation extends TrackEdgePoint {
public UUID id;
public Couple<TrackNodeLocation> edgeLocation;
public double position;
public String name;
public BlockPos stationPos;
public WeakReference<Train> nearestTrain;
@Nullable
public SignalBoundary boundary;
public GlobalStation(UUID id, BlockPos stationPos) {
this.id = id;
super(id);
this.stationPos = stationPos;
name = "Track Station";
nearestTrain = new WeakReference<Train>(null);
}
public GlobalStation(CompoundTag nbt) {
id = nbt.getUUID("Id");
super(nbt);
name = nbt.getString("Name");
position = nbt.getDouble("Position");
stationPos = NbtUtils.readBlockPos(nbt.getCompound("StationPos"));
nearestTrain = new WeakReference<Train>(null);
edgeLocation = Couple.deserializeEach(nbt.getList("Edge", Tag.TAG_COMPOUND),
tag -> TrackNodeLocation.fromPackedPos(NbtUtils.readBlockPos(tag)));
}
public void migrate(LevelAccessor level) {

View file

@ -4,6 +4,7 @@ import com.jozufozu.flywheel.core.PartialModel;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.simibubi.create.content.logistics.trains.ITrackBlock;
import com.simibubi.create.content.logistics.trains.management.TrackTargetingBehaviour.RenderedTrackOverlayType;
import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
@ -36,7 +37,7 @@ public class StationRenderer extends SafeTileEntityRenderer<StationTileEntity> {
Block block = trackState.getBlock();
if (!(block instanceof ITrackBlock))
return;
GlobalStation station = te.getOrCreateGlobalStation();
if (!te.getBlockState()
@ -44,7 +45,7 @@ public class StationRenderer extends SafeTileEntityRenderer<StationTileEntity> {
ms.pushPose();
ms.translate(-pos.getX(), -pos.getY(), -pos.getZ());
TrackTargetingBehaviour.render(level, targetPosition, target.getTargetDirection(), 0xCC993B, ms, buffer,
light, overlay);
light, overlay, RenderedTrackOverlayType.STATION);
ms.popPose();
return;
}
@ -62,8 +63,8 @@ public class StationRenderer extends SafeTileEntityRenderer<StationTileEntity> {
MutableBlockPos currentPos = targetPosition.mutable();
PartialModel assemblyOverlay = track.prepareAssemblyOverlay(level, targetPosition, trackState, direction, ms);
int colorWhenValid = 0x7092F2;
int colorWhenCarriage = 0x70EF70;
int colorWhenValid = 0x96B5FF;
int colorWhenCarriage = 0xCAFF96;
VertexConsumer vb = buffer.getBuffer(RenderType.cutoutMipped());
currentPos.move(direction, 1);

View file

@ -488,6 +488,7 @@ public class StationTileEntity extends SmartTileEntity {
GlobalStation station = getOrCreateGlobalStation();
train.setCurrentStation(station);
station.reserveFor(train);
train.collectInitiallyOccupiedSignalBlocks();
Create.RAILWAYS.trains.put(train.id, train);
clearException();

View file

@ -84,9 +84,13 @@ public class TrackTargetingBehaviour extends TileEntityBehaviour {
.get(0));
}
public static enum RenderedTrackOverlayType {
STATION, SIGNAL, DUAL_SIGNAL;
}
@OnlyIn(Dist.CLIENT)
public static void render(LevelAccessor level, BlockPos pos, AxisDirection direction, int tintColor, PoseStack ms,
MultiBufferSource buffer, int light, int overlay) {
MultiBufferSource buffer, int light, int overlay, RenderedTrackOverlayType type) {
BlockState trackState = level.getBlockState(pos);
Block block = trackState.getBlock();
if (!(block instanceof ITrackBlock))
@ -97,8 +101,7 @@ public class TrackTargetingBehaviour extends TileEntityBehaviour {
ITrackBlock track = (ITrackBlock) block;
SuperByteBuffer sbb =
CachedBufferer.partial(track.prepareStationOverlay(level, pos, trackState, direction, ms), trackState);
sbb.color(tintColor);
CachedBufferer.partial(track.prepareTrackOverlay(level, pos, trackState, direction, ms, type), trackState);
sbb.light(LevelRenderer.getLightColor(level, pos));
sbb.renderInto(ms, buffer.getBuffer(RenderType.cutoutMipped()));

View file

@ -19,7 +19,7 @@ public class ScheduledDelay extends TimedWaitCondition {
@Override
public boolean tickCompletion(Level level, Train train, CompoundTag context) {
int time = context.getInt("Time");
int time = context.getInt("Time") + 1900;
if (time >= value * timeUnit.ticksPer)
return true;
context.putInt("Time", time + 1);

View file

@ -0,0 +1,154 @@
package com.simibubi.create.content.logistics.trains.management.signal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.function.Function;
import javax.annotation.Nullable;
import com.simibubi.create.content.logistics.trains.TrackEdge;
import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.management.GlobalStation;
import com.simibubi.create.foundation.utility.NBTHelper;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.util.Mth;
public class EdgeData {
public UUID singleSignalGroup;
private List<SignalBoundary> boundaries;
private List<GlobalStation> stations;
public EdgeData() {
boundaries = new ArrayList<>();
stations = new ArrayList<>();
singleSignalGroup = null;
}
public boolean hasBoundaries() {
return !boundaries.isEmpty();
}
public boolean hasStations() {
return !stations.isEmpty();
}
public List<SignalBoundary> getBoundaries() {
return boundaries;
}
public List<GlobalStation> getStations() {
return stations;
}
public void removePoint(TrackNode node1, TrackNode node2, TrackEdge edge, TrackEdgePoint point) {
if (point instanceof GlobalStation gs)
stations.remove(gs);
if (point instanceof SignalBoundary sb)
boundaries.remove(sb);
updateDelegates(node1, node2, edge);
}
public <T extends TrackEdgePoint> void addPoint(TrackNode node1, TrackNode node2, TrackEdge edge, T boundary,
Class<T> type) {
T next = next(type, node1, node2, edge, boundary.getLocationOn(node1, node2, edge));
if (boundary instanceof GlobalStation gs)
stations.add(next == null ? stations.size() : stations.indexOf(next), gs);
if (boundary instanceof SignalBoundary sb)
boundaries.add(next == null ? boundaries.size() : boundaries.indexOf(next), sb);
updateDelegates(node1, node2, edge);
}
public void updateDelegates(TrackNode node1, TrackNode node2, TrackEdge edge) {
for (GlobalStation globalStation : stations)
globalStation.boundary = getBoundary(node1, node2, edge, globalStation.getLocationOn(node1, node2, edge));
for (SignalBoundary boundary : boundaries)
boundary.station = getStation(node1, node2, edge, boundary.getLocationOn(node1, node2, edge));
}
@Nullable
public SignalBoundary nextBoundary(TrackNode node1, TrackNode node2, TrackEdge edge, double minPosition) {
return next(SignalBoundary.class, node1, node2, edge, minPosition);
}
@Nullable
public GlobalStation nextStation(TrackNode node1, TrackNode node2, TrackEdge edge, double minPosition) {
return next(GlobalStation.class, node1, node2, edge, minPosition);
}
@Nullable
public SignalBoundary getBoundary(TrackNode node1, TrackNode node2, TrackEdge edge, double exactPosition) {
return get(SignalBoundary.class, node1, node2, edge, exactPosition);
}
@Nullable
public GlobalStation getStation(TrackNode node1, TrackNode node2, TrackEdge edge, double exactPosition) {
return get(GlobalStation.class, node1, node2, edge, exactPosition);
}
@Nullable
@SuppressWarnings("unchecked")
private <T extends TrackEdgePoint> T next(Class<T> type, TrackNode node1, TrackNode node2, TrackEdge edge,
double minPosition) {
for (TrackEdgePoint point : type == GlobalStation.class ? stations : boundaries)
if (point.getLocationOn(node1, node2, edge) > minPosition)
return (T) point;
return null;
}
@Nullable
private <T extends TrackEdgePoint> T get(Class<T> type, TrackNode node1, TrackNode node2, TrackEdge edge,
double exactPosition) {
T next = next(type, node1, node2, edge, exactPosition - .5f);
if (next != null && Mth.equal(next.getLocationOn(node1, node2, edge), exactPosition))
return next;
return null;
}
public CompoundTag write() {
CompoundTag signalCompound = new CompoundTag();
if (hasBoundaries()) {
signalCompound.put("Boundaries", NBTHelper.writeCompoundList(boundaries, this::writePoint));
} else if (singleSignalGroup != null)
signalCompound.putUUID("Group", singleSignalGroup);
if (hasStations())
signalCompound.put("Stations", NBTHelper.writeCompoundList(stations, this::writePoint));
return signalCompound;
}
public static EdgeData read(CompoundTag tag, TrackGraph graph) {
EdgeData signalEdgeData = new EdgeData();
if (tag.contains("Group"))
signalEdgeData.singleSignalGroup = tag.getUUID("Group");
if (tag.contains("Boundaries"))
NBTHelper.iterateCompoundList(tag.getList("Boundaries", Tag.TAG_COMPOUND),
readPoint(graph::getSignal, signalEdgeData.boundaries));
if (tag.contains("Stations"))
NBTHelper.iterateCompoundList(tag.getList("Stations", Tag.TAG_COMPOUND),
readPoint(graph::getStation, signalEdgeData.stations));
return signalEdgeData;
}
private <T extends TrackEdgePoint> CompoundTag writePoint(T point) {
CompoundTag compoundTag = new CompoundTag();
compoundTag.putUUID("Id", point.id);
return compoundTag;
}
private static <T extends TrackEdgePoint> Consumer<CompoundTag> readPoint(Function<UUID, T> lookup,
Collection<T> target) {
return tag -> {
UUID id = tag.getUUID("Id");
T signal = lookup.apply(id);
if (signal != null)
target.add(signal);
};
}
}

View file

@ -0,0 +1,55 @@
package com.simibubi.create.content.logistics.trains.management.signal;
import java.util.Random;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.foundation.block.ITE;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.SimpleWaterloggedBlock;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
public class SignalBlock extends Block implements SimpleWaterloggedBlock, ITE<SignalTileEntity> {
public SignalBlock(Properties p_53182_) {
super(p_53182_);
}
@Override
public Class<SignalTileEntity> getTileEntityClass() {
return SignalTileEntity.class;
}
@Override
public BlockEntityType<? extends SignalTileEntity> getTileEntityType() {
return AllTileEntities.TRACK_SIGNAL.get();
}
@Override
public boolean canConnectRedstone(BlockState state, BlockGetter world, BlockPos pos, Direction side) {
return side != null;
}
@Override
public boolean isSignalSource(BlockState state) {
return true;
}
@Override
public void tick(BlockState blockState, ServerLevel world, BlockPos pos, Random random) {
getTileEntityOptional(world, pos).ifPresent(SignalTileEntity::updatePowerAfterDelay);
}
@Override
public int getSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) {
return getTileEntityOptional(blockAccess, pos).filter(SignalTileEntity::isPowered)
.map($ -> 15)
.orElse(0);
}
}

View file

@ -0,0 +1,143 @@
package com.simibubi.create.content.logistics.trains.management.signal;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.management.GlobalStation;
import com.simibubi.create.content.logistics.trains.management.signal.SignalTileEntity.OverlayState;
import com.simibubi.create.content.logistics.trains.management.signal.SignalTileEntity.SignalState;
import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.NBTHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.nbt.Tag;
public class SignalBoundary extends TrackEdgePoint {
public Couple<Set<BlockPos>> signals;
public Couple<UUID> groups;
public Couple<Boolean> sidesToUpdate;
@Nullable
public GlobalStation station;
public SignalBoundary(UUID id, BlockPos tilePosition, boolean front) {
super(id);
signals = Couple.create(HashSet::new);
groups = Couple.create(null, null);
sidesToUpdate = Couple.create(true, true);
this.signals.get(front)
.add(tilePosition);
}
public void setGroup(TrackNode side, UUID groupId) {
boolean primary = isPrimary(side);
groups.set(primary, groupId);
sidesToUpdate.set(primary, false);
}
public void queueUpdate(TrackNode side) {
sidesToUpdate.set(isPrimary(side), true);
}
public UUID getGroup(TrackNode side) {
return groups.get(isPrimary(side));
}
public boolean canNavigateVia(TrackNode side) {
return !signals.get(!isPrimary(side))
.isEmpty();
}
public OverlayState getOverlayFor(BlockPos tile) {
if (station != null)
return OverlayState.SKIP;
for (boolean first : Iterate.trueAndFalse) {
Set<BlockPos> set = signals.get(first);
for (BlockPos blockPos : set) {
if (blockPos.equals(tile))
return signals.get(!first)
.isEmpty() ? OverlayState.RENDER : OverlayState.DUAL;
return OverlayState.SKIP;
}
}
return OverlayState.SKIP;
}
public SignalState getStateFor(BlockPos tile) {
for (boolean first : Iterate.trueAndFalse) {
Set<BlockPos> set = signals.get(first);
if (!set.contains(tile))
continue;
UUID group = groups.get(first);
if (Objects.equal(group, groups.get(!first)))
return SignalState.INVALID;
Map<UUID, SignalEdgeGroup> signalEdgeGroups = Create.RAILWAYS.signalEdgeGroups;
SignalEdgeGroup signalEdgeGroup = signalEdgeGroups.get(group);
if (signalEdgeGroup == null)
return SignalState.INVALID;
return signalEdgeGroup.isOccupiedUnless(this) ? SignalState.RED : SignalState.GREEN;
}
return SignalState.INVALID;
}
public void tick(TrackGraph graph) {
for (boolean front : Iterate.trueAndFalse) {
if (!sidesToUpdate.get(front))
continue;
sidesToUpdate.set(front, false);
SignalPropagator.propagateSignalGroup(graph, this, front);
}
}
public SignalBoundary(CompoundTag nbt) {
super(nbt);
signals = Couple.create(HashSet::new);
groups = Couple.create(null, null);
sidesToUpdate = Couple.create(true, true);
for (int i = 1; i <= 2; i++)
if (nbt.contains("Tiles" + i)) {
boolean first = i == 1;
NBTHelper.iterateCompoundList(nbt.getList("Tiles" + i, Tag.TAG_COMPOUND), c -> signals.get(first)
.add(NbtUtils.readBlockPos(c)));
}
for (int i = 1; i <= 2; i++)
if (nbt.contains("Group" + i))
groups.set(i == 1, nbt.getUUID("Group" + i));
for (int i = 1; i <= 2; i++)
sidesToUpdate.set(i == 1, nbt.contains("Update" + i));
}
public CompoundTag write() {
CompoundTag nbt = new CompoundTag();
nbt.putUUID("Id", id);
nbt.putDouble("Position", position);
nbt.put("Edge", edgeLocation.serializeEach(loc -> NbtUtils.writeBlockPos(new BlockPos(loc))));
for (int i = 1; i <= 2; i++)
if (!signals.get(i == 1)
.isEmpty())
nbt.put("Tiles" + i, NBTHelper.writeCompoundList(signals.get(i == 1), NbtUtils::writeBlockPos));
for (int i = 1; i <= 2; i++)
if (groups.get(i == 1) != null)
nbt.putUUID("Group" + i, groups.get(i == 1));
for (int i = 1; i <= 2; i++)
if (sidesToUpdate.get(i == 1))
nbt.putBoolean("Update" + i, true);
return nbt;
}
}

View file

@ -0,0 +1,52 @@
package com.simibubi.create.content.logistics.trains.management.signal;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.entity.Train;
import com.simibubi.create.foundation.utility.Color;
import net.minecraft.nbt.CompoundTag;
public class SignalEdgeGroup {
public UUID id;
public Color color;
public Set<Train> trains;
public SignalBoundary reserved;
public SignalEdgeGroup(UUID id) {
this.id = id;
color = Color.rainbowColor(Create.RANDOM.nextInt());
trains = new HashSet<>();
}
public boolean isOccupiedUnless(Train train) {
return reserved != null || trains.size() > 1 || !trains.contains(train) && !trains.isEmpty();
}
public boolean isOccupiedUnless(SignalBoundary boundary) {
return !trains.isEmpty() || reserved != null && reserved != boundary;
}
public boolean isOccupied() {
return !trains.isEmpty() || reserved != null;
}
public static SignalEdgeGroup read(CompoundTag tag) {
SignalEdgeGroup group = new SignalEdgeGroup(tag.getUUID("Id"));
group.color = new Color(tag.getInt("Color"));
return group;
}
public CompoundTag write() {
CompoundTag tag = new CompoundTag();
tag.putUUID("Id", id);
tag.putInt("Color", color.getRGB());
return tag;
}
}

View file

@ -0,0 +1,196 @@
package com.simibubi.create.content.logistics.trains.management.signal;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.function.Predicate;
import com.google.common.base.Predicates;
import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.TrackEdge;
import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation;
import com.simibubi.create.content.logistics.trains.entity.Train;
import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.Pair;
public class SignalPropagator {
public static <T extends TrackEdgePoint> void onEdgePointAdded(TrackGraph graph, T point, Class<T> type) {
Couple<TrackNodeLocation> edgeLocation = point.edgeLocation;
Couple<TrackNode> startNodes = edgeLocation.map(graph::locateNode);
Couple<TrackEdge> startEdges = startNodes.mapWithParams((l1, l2) -> graph.getConnectionsFrom(l1)
.get(l2), startNodes.swap());
for (boolean front : Iterate.trueAndFalse) {
TrackNode node1 = startNodes.get(front);
TrackNode node2 = startNodes.get(!front);
TrackEdge startEdge = startEdges.get(front);
startEdge.getEdgeData()
.addPoint(node1, node2, startEdge, point, type);
}
}
public static <T extends TrackEdgePoint> void onEdgePointRemoved(TrackGraph graph, T point, Class<T> type) {
Couple<TrackNodeLocation> edgeLocation = point.edgeLocation;
Couple<TrackNode> startNodes = edgeLocation.map(graph::locateNode);
startNodes.forEachWithParams((l1, l2) -> {
TrackEdge trackEdge = graph.getConnectionsFrom(l1)
.get(l2);
trackEdge.getEdgeData()
.removePoint(l1, l2, trackEdge, point);
}, startNodes.swap());
}
public static void onSignalRemoved(TrackGraph graph, SignalBoundary signal) {
signal.sidesToUpdate.map($ -> false);
for (boolean front : Iterate.trueAndFalse) {
if (signal.sidesToUpdate.get(front))
continue;
Create.RAILWAYS.signalEdgeGroups.remove(signal.groups.get(front));
walkSignals(graph, signal, front, pair -> {
TrackNode node1 = pair.getFirst();
SignalBoundary boundary = pair.getSecond();
boundary.queueUpdate(node1);
return false;
}, Predicates.alwaysFalse());
}
onEdgePointRemoved(graph, signal, SignalBoundary.class);
}
public static void notifySignalsOfNewNode(TrackGraph graph, TrackNode node) {
List<Couple<TrackNode>> frontier = new ArrayList<>();
frontier.add(Couple.create(node, null));
walkSignals(graph, frontier, pair -> {
TrackNode node1 = pair.getFirst();
SignalBoundary boundary = pair.getSecond();
boundary.queueUpdate(node1);
return false;
}, Predicates.alwaysFalse());
}
public static void propagateSignalGroup(TrackGraph graph, SignalBoundary signal, boolean front) {
Map<UUID, SignalEdgeGroup> globalGroups = Create.RAILWAYS.signalEdgeGroups;
SignalEdgeGroup group = new SignalEdgeGroup(UUID.randomUUID());
UUID groupId = group.id;
globalGroups.put(groupId, group);
signal.groups.set(front, groupId);
walkSignals(graph, signal, front, pair -> {
TrackNode node1 = pair.getFirst();
SignalBoundary boundary = pair.getSecond();
UUID currentGroup = boundary.getGroup(node1);
if (currentGroup != null)
globalGroups.remove(currentGroup);
boundary.setGroup(node1, groupId);
return true;
}, signalData -> {
if (signalData.singleSignalGroup != null)
globalGroups.remove(signalData.singleSignalGroup);
signalData.singleSignalGroup = groupId;
return true;
});
}
public static void walkSignals(TrackGraph graph, SignalBoundary signal, boolean front,
Predicate<Pair<TrackNode, SignalBoundary>> boundaryCallback, Predicate<EdgeData> nonBoundaryCallback) {
Couple<TrackNodeLocation> edgeLocation = signal.edgeLocation;
Couple<TrackNode> startNodes = edgeLocation.map(graph::locateNode);
Couple<TrackEdge> startEdges = startNodes.mapWithParams((l1, l2) -> graph.getConnectionsFrom(l1)
.get(l2), startNodes.swap());
TrackNode node1 = startNodes.get(front);
TrackNode node2 = startNodes.get(!front);
TrackEdge startEdge = startEdges.get(front);
if (startEdge == null)
return;
// Check for signal on the same edge
SignalBoundary immediateBoundary = startEdge.getEdgeData()
.nextBoundary(node1, node2, startEdge, signal.getLocationOn(node1, node2, startEdge));
if (immediateBoundary != null) {
if (boundaryCallback.test(Pair.of(node1, immediateBoundary)))
notifyTrains(graph, startEdge, startEdges.get(!front));
return;
}
// Search for any connected signals
List<Couple<TrackNode>> frontier = new ArrayList<>();
frontier.add(Couple.create(node2, node1));
walkSignals(graph, frontier, boundaryCallback, nonBoundaryCallback);
}
private static void walkSignals(TrackGraph graph, List<Couple<TrackNode>> frontier,
Predicate<Pair<TrackNode, SignalBoundary>> boundaryCallback, Predicate<EdgeData> nonBoundaryCallback) {
Set<TrackEdge> visited = new HashSet<>();
while (!frontier.isEmpty()) {
Couple<TrackNode> couple = frontier.remove(0);
TrackNode currentNode = couple.getFirst();
TrackNode prevNode = couple.getSecond();
EdgeWalk: for (Entry<TrackNode, TrackEdge> entry : graph.getConnectionsFrom(currentNode)
.entrySet()) {
TrackNode nextNode = entry.getKey();
TrackEdge edge = entry.getValue();
if (nextNode == prevNode)
continue;
// already checked this edge
if (!visited.add(edge))
continue;
TrackEdge oppositeEdge = graph.getConnectionsFrom(nextNode)
.get(currentNode);
visited.add(oppositeEdge);
for (boolean flip : Iterate.falseAndTrue) {
TrackEdge currentEdge = flip ? oppositeEdge : edge;
EdgeData signalData = currentEdge.getEdgeData();
// no boundary- update group of edge
if (!signalData.hasBoundaries()) {
if (nonBoundaryCallback.test(signalData))
notifyTrains(graph, currentEdge);
continue;
}
// other/own boundary found
SignalBoundary nextBoundary = signalData.nextBoundary(currentNode, nextNode, currentEdge, 0);
if (boundaryCallback.test(Pair.of(currentNode, nextBoundary)))
notifyTrains(graph, edge, oppositeEdge);
continue EdgeWalk;
}
frontier.add(Couple.create(nextNode, currentNode));
}
}
}
public static void notifyTrains(TrackGraph graph, TrackEdge... edges) {
for (TrackEdge trackEdge : edges) {
for (Train train : Create.RAILWAYS.trains.values()) {
if (train.graph != graph)
continue;
if (train.updateSignalBlocks)
continue;
train.forEachTravellingPoint(tp -> {
if (tp.edge == trackEdge)
train.updateSignalBlocks = true;
});
}
}
}
}

View file

@ -0,0 +1,62 @@
package com.simibubi.create.content.logistics.trains.management.signal;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.logistics.trains.ITrackBlock;
import com.simibubi.create.content.logistics.trains.management.TrackTargetingBehaviour;
import com.simibubi.create.content.logistics.trains.management.TrackTargetingBehaviour.RenderedTrackOverlayType;
import com.simibubi.create.content.logistics.trains.management.signal.SignalTileEntity.OverlayState;
import com.simibubi.create.content.logistics.trains.management.signal.SignalTileEntity.SignalState;
import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
public class SignalRenderer extends SafeTileEntityRenderer<SignalTileEntity> {
public SignalRenderer(BlockEntityRendererProvider.Context context) {}
@Override
protected void renderSafe(SignalTileEntity te, float partialTicks, PoseStack ms, MultiBufferSource buffer,
int light, int overlay) {
BlockState blockState = te.getBlockState();
SignalState signalState = te.getState();
OverlayState overlayState = te.getOverlay();
float renderTime = AnimationTickHolder.getRenderTime(te.getLevel());
if (signalState.isRedLight(renderTime))
CachedBufferer.partial(AllBlockPartials.SIGNAL_ON, blockState)
.renderInto(ms, buffer.getBuffer(RenderType.solid()));
else if (signalState.isGreenLight(renderTime))
CachedBufferer.partial(AllBlockPartials.SIGNAL_OFF, blockState)
.renderInto(ms, buffer.getBuffer(RenderType.solid()));
BlockPos pos = te.getBlockPos();
TrackTargetingBehaviour target = te.getTarget();
BlockPos targetPosition = target.getGlobalPosition();
Level level = te.getLevel();
BlockState trackState = level.getBlockState(targetPosition);
Block block = trackState.getBlock();
if (!(block instanceof ITrackBlock))
return;
if (overlayState == OverlayState.SKIP)
return;
ms.pushPose();
ms.translate(-pos.getX(), -pos.getY(), -pos.getZ());
TrackTargetingBehaviour.render(level, targetPosition, target.getTargetDirection(), 0xd0cccc, ms, buffer, light,
overlay,
overlayState == OverlayState.DUAL ? RenderedTrackOverlayType.DUAL_SIGNAL : RenderedTrackOverlayType.SIGNAL);
ms.popPose();
}
}

View file

@ -0,0 +1,224 @@
package com.simibubi.create.content.logistics.trains.management.signal;
import java.util.List;
import java.util.UUID;
import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.TrackEdge;
import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.management.GraphLocation;
import com.simibubi.create.content.logistics.trains.management.TrackTargetingBehaviour;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.NBTHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction.AxisDirection;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.Mth;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.ticks.TickPriority;
public class SignalTileEntity extends SmartTileEntity {
public static enum OverlayState {
RENDER, SKIP, DUAL
}
public static enum SignalState {
RED, GREEN, INVALID, TRAIN_ENTERING;
public boolean isRedLight(float renderTime) {
return this == RED || this == INVALID && renderTime % 40 < 3;
}
public boolean isGreenLight(float renderTime) {
return this == GREEN || this == TRAIN_ENTERING;
}
}
public UUID id;
private SignalState state;
private OverlayState overlay;
private int switchToRedAfterTrainEntered;
public SignalTileEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
id = UUID.randomUUID();
this.state = SignalState.INVALID;
this.overlay = OverlayState.SKIP;
}
@Override
protected void write(CompoundTag tag, boolean clientPacket) {
super.write(tag, clientPacket);
tag.putUUID("Id", id);
NBTHelper.writeEnum(tag, "State", state);
NBTHelper.writeEnum(tag, "Overlay", overlay);
}
@Override
protected void read(CompoundTag tag, boolean clientPacket) {
super.read(tag, clientPacket);
id = tag.getUUID("Id");
state = NBTHelper.readEnum(tag, "State", SignalState.class);
overlay = NBTHelper.readEnum(tag, "Overlay", OverlayState.class);
}
public boolean isPowered() {
return state == SignalState.RED;
}
protected void scheduleBlockTick() {
Block block = getBlockState().getBlock();
if (!level.getBlockTicks()
.willTickThisTick(worldPosition, block))
level.scheduleTick(worldPosition, block, 2, TickPriority.NORMAL);
}
public void updatePowerAfterDelay() {
level.blockUpdated(worldPosition, getBlockState().getBlock());
}
@Override
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
behaviours.add(new TrackTargetingBehaviour(this));
}
@Override
public void tick() {
super.tick();
if (level.isClientSide)
return;
SignalBoundary boundary = getOrCreateSignalBoundary();
if (boundary == null) {
enterState(SignalState.INVALID);
setOverlay(OverlayState.RENDER);
return;
}
enterState(boundary.getStateFor(worldPosition));
setOverlay(boundary.getOverlayFor(worldPosition));
}
@Override
protected void setRemovedNotDueToChunkUnload() {
if (!getTarget().hasValidTrack() || level.isClientSide) {
super.setRemovedNotDueToChunkUnload();
return;
}
for (TrackGraph trackGraph : Create.RAILWAYS.trackNetworks.values()) {
SignalBoundary signal = trackGraph.getSignal(id);
if (signal == null)
continue;
for (boolean front : Iterate.trueAndFalse)
signal.signals.get(front)
.remove(worldPosition);
if (signal.signals.getFirst()
.isEmpty()
&& signal.signals.getSecond()
.isEmpty())
trackGraph.removeSignal(id);
}
super.setRemovedNotDueToChunkUnload();
}
public SignalBoundary getOrCreateSignalBoundary() {
for (TrackGraph trackGraph : Create.RAILWAYS.trackNetworks.values()) {
SignalBoundary signal = trackGraph.getSignal(id);
if (signal == null)
continue;
return signal;
}
if (level.isClientSide)
return null;
TrackTargetingBehaviour target = getTarget();
if (!target.hasValidTrack())
return null;
GraphLocation loc = target.determineGraphLocation();
if (loc == null)
return null;
TrackGraph graph = loc.graph;
TrackNode node1 = graph.locateNode(loc.edge.getFirst());
TrackNode node2 = graph.locateNode(loc.edge.getSecond());
TrackEdge edge = graph.getConnectionsFrom(node1)
.get(node2);
boolean positive = target.getTargetDirection() == AxisDirection.POSITIVE;
if (edge == null)
return null;
EdgeData signalData = edge.getEdgeData();
if (signalData.hasBoundaries()) {
SignalBoundary nextBoundary = signalData.nextBoundary(node1, node2, edge, loc.position - .25f);
if (nextBoundary != null && Mth.equal(nextBoundary.getLocationOn(node1, node2, edge), loc.position)) {
nextBoundary.signals.get(positive)
.add(worldPosition);
id = nextBoundary.id;
setChanged();
return nextBoundary;
}
}
SignalBoundary signal = new SignalBoundary(id, worldPosition, positive);
signal.setLocation(positive ? loc.edge : loc.edge.swap(),
positive ? loc.position : edge.getLength(node1, node2) - loc.position);
graph.addSignal(signal);
setChanged();
return signal;
}
public TrackTargetingBehaviour getTarget() {
return getBehaviour(TrackTargetingBehaviour.TYPE);
}
public SignalState getState() {
return state;
}
public OverlayState getOverlay() {
return overlay;
}
public void setOverlay(OverlayState state) {
if (this.overlay == state)
return;
this.overlay = state;
notifyUpdate();
}
public void enterState(SignalState state) {
if (switchToRedAfterTrainEntered > 0)
switchToRedAfterTrainEntered--;
if (this.state == state)
return;
if (state == SignalState.RED && switchToRedAfterTrainEntered > 0)
return;
this.state = state;
switchToRedAfterTrainEntered = state == SignalState.GREEN ? 15 : 0;
notifyUpdate();
scheduleBlockTick();
}
// Render
private AABB renderBounds = null;
@Override
public AABB getRenderBoundingBox() {
if (renderBounds == null)
renderBounds = new AABB(worldPosition, getTarget().getGlobalPosition()).inflate(2);
return renderBounds;
}
}

View file

@ -0,0 +1,45 @@
package com.simibubi.create.content.logistics.trains.management.signal;
import java.util.UUID;
import com.simibubi.create.content.logistics.trains.TrackEdge;
import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation;
import com.simibubi.create.foundation.utility.Couple;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.nbt.Tag;
public class TrackEdgePoint {
public UUID id;
public Couple<TrackNodeLocation> edgeLocation;
public double position;
public TrackEdgePoint(UUID id) {
this.id = id;
}
public TrackEdgePoint(CompoundTag nbt) {
id = nbt.getUUID("Id");
position = nbt.getDouble("Position");
edgeLocation = Couple.deserializeEach(nbt.getList("Edge", Tag.TAG_COMPOUND),
tag -> TrackNodeLocation.fromPackedPos(NbtUtils.readBlockPos(tag)));
}
public void setLocation(Couple<TrackNodeLocation> nodes, double position) {
this.edgeLocation = nodes;
this.position = position;
}
public double getLocationOn(TrackNode node1, TrackNode node2, TrackEdge edge) {
return isPrimary(node1) ? edge.getLength(node1, node2) - position : position;
}
public boolean isPrimary(TrackNode node1) {
return edgeLocation.getSecond()
.equals(node1.getLocation());
}
}

View file

@ -24,6 +24,7 @@ import com.simibubi.create.content.logistics.trains.TrackNodeLocation;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation.DiscoveredLocation;
import com.simibubi.create.content.logistics.trains.TrackPropagator;
import com.simibubi.create.content.logistics.trains.management.StationTileEntity;
import com.simibubi.create.content.logistics.trains.management.TrackTargetingBehaviour.RenderedTrackOverlayType;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.VecHelper;
@ -214,6 +215,8 @@ public class TrackBlock extends Block implements EntityBlock, IWrenchable, ITrac
if (Blocks.SPONGE.asItem() == itemInHand.getItem()) {
Create.RAILWAYS.trackNetworks.clear();
CreateClient.RAILWAYS.trackNetworks.clear();
Create.RAILWAYS.signalEdgeGroups.clear();
CreateClient.RAILWAYS.signalEdgeGroups.clear();
return InteractionResult.SUCCESS;
}
@ -347,13 +350,13 @@ public class TrackBlock extends Block implements EntityBlock, IWrenchable, ITrac
PoseStack ms) {
new MatrixTransformStack(ms).rotateCentered(Direction.UP,
AngleHelper.rad(AngleHelper.horizontalAngle(direction)));
return AllBlockPartials.TRACK_ASSEMBLY_OVERLAY;
return AllBlockPartials.TRACK_ASSEMBLING_OVERLAY;
}
@Override
@OnlyIn(Dist.CLIENT)
public PartialModel prepareStationOverlay(BlockGetter world, BlockPos pos, BlockState state,
AxisDirection direction, PoseStack ms) {
public PartialModel prepareTrackOverlay(BlockGetter world, BlockPos pos, BlockState state, AxisDirection direction,
PoseStack ms, RenderedTrackOverlayType type) {
Vec3 axis = state.getValue(SHAPE)
.getAxes()
.get(0);
@ -361,13 +364,16 @@ public class TrackBlock extends Block implements EntityBlock, IWrenchable, ITrac
.normalize();
Vec3 normal = getUpNormal(world, pos, state);
Vec3 angles = TrackRenderer.getModelAngles(normal, directionVec);
new MatrixTransformStack(ms).centre()
.rotateYRadians(angles.y + Math.PI)
.rotateXRadians(-angles.x)
.unCentre();
return axis.lengthSqr() > 1 ? axis.y != 0 ? AllBlockPartials.TRACK_STATION_OVERLAY_ASCENDING
: AllBlockPartials.TRACK_STATION_OVERLAY_DIAGONAL : AllBlockPartials.TRACK_STATION_OVERLAY;
new MatrixTransformStack(ms).centre()
.rotateYRadians(angles.y)
.rotateXRadians(angles.x)
.unCentre()
.translate(0, axis.y != 0 ? 7 / 16f : 0, axis.y != 0 ? direction.getStep() * 2.5f / 16f : 0);
return type == RenderedTrackOverlayType.STATION ? AllBlockPartials.TRACK_STATION_OVERLAY
: type == RenderedTrackOverlayType.SIGNAL ? AllBlockPartials.TRACK_SIGNAL_OVERLAY
: AllBlockPartials.TRACK_SIGNAL_DUAL_OVERLAY;
}
@Override

View file

@ -1,5 +1,6 @@
package com.simibubi.create.foundation.command;
import java.util.Collection;
import java.util.Map.Entry;
import java.util.UUID;
import java.util.function.BiConsumer;
@ -12,6 +13,7 @@ import com.simibubi.create.content.logistics.trains.entity.Train;
import com.simibubi.create.content.logistics.trains.management.GlobalStation;
import com.simibubi.create.content.logistics.trains.management.ScheduleRuntime;
import com.simibubi.create.content.logistics.trains.management.ScheduleRuntime.State;
import com.simibubi.create.content.logistics.trains.management.signal.SignalBoundary;
import net.minecraft.ChatFormatting;
import net.minecraft.commands.CommandSourceStack;
@ -48,6 +50,7 @@ public class DumpRailwaysCommand {
chat.accept("", white);
chat.accept("-+------<< Railways Summary: >>------+-", white);
chat.accept("Track Networks: " + railways.trackNetworks.size(), blue);
chat.accept("Signal Groups: " + railways.signalEdgeGroups.size(), blue);
chat.accept("Trains: " + railways.trains.size(), blue);
chat.accept("", white);
@ -59,6 +62,9 @@ public class DumpRailwaysCommand {
+ graph.getNodes()
.size()
+ " Nodes", graph.color.getRGB());
Collection<SignalBoundary> signals = graph.getSignals();
if (!signals.isEmpty())
chat.accept(" -> " + signals.size() + " registered Signals", blue);
for (GlobalStation globalStation : graph.getStations()) {
BlockPos pos = globalStation.stationPos;
chat.accept(" -> " + globalStation.name + " (" + globalStation.id.toString()

View file

@ -12,6 +12,7 @@ public class CServer extends ConfigBase {
public final CLogistics logistics = nested(0, CLogistics::new, Comments.logistics);
public final CSchematics schematics = nested(0, CSchematics::new, Comments.schematics);
public final CCuriosities curiosities = nested(0, CCuriosities::new, Comments.curiosities);
public final CTrains trains = nested(0, CTrains::new, Comments.trains);
@Override
public String getName() {
@ -25,6 +26,7 @@ public class CServer extends ConfigBase {
static String fluids = "Create's liquid manipulation tools";
static String logistics = "Tweaks for logistical components";
static String curiosities = "Gadgets and other Shenanigans added by Create";
static String trains = "Create's builtin Railway systems";
static String infrastructure = "The Backbone of Create";
static String tickrateSyncTimer =
"The amount of time a server waits before sending out tickrate synchronization packets.";

View file

@ -0,0 +1,29 @@
package com.simibubi.create.foundation.config;
public class CTrains extends ConfigBase {
public final ConfigFloat trainTopSpeed = f(40, 0, "trainTopSpeed", Comments.mps, Comments.trainTopSpeed);
public final ConfigFloat trainAcceleration =
f(6, 0, "trainAcceleration", Comments.acc, Comments.trainAcceleration);
@Override
public String getName() {
return "trains";
}
public double getTopSpeedMPT() {
return trainTopSpeed.getF() / 20;
}
public double getAccelerationMPTT() {
return trainAcceleration.getF() / 400;
}
private static class Comments {
static String mps = "[in Blocks/Second]";
static String acc = "[in Blocks/Second²]";
static String trainTopSpeed = "The top speed of any assembled Train.";
static String trainAcceleration = "The acceleration of any assembled Train.";
}
}

View file

@ -67,6 +67,20 @@ public class RenderTypes extends RenderStateShard {
.createCompositeState(true));
}
private static final RenderType ADDITIVE = RenderType.create(createLayerName("additive"), DefaultVertexFormat.BLOCK,
VertexFormat.Mode.QUADS, 256, true, true, RenderType.CompositeState.builder()
.setShaderState(BLOCK_SHADER)
.setTextureState(new RenderStateShard.TextureStateShard(InventoryMenu.BLOCK_ATLAS, false, false))
.setTransparencyState(ADDITIVE_TRANSPARENCY)
.setCullState(NO_CULL)
.setLightmapState(LIGHTMAP)
.setOverlayState(OVERLAY)
.createCompositeState(true));
public static RenderType getAdditive() {
return ADDITIVE;
}
private static final RenderType GLOWING_TRANSLUCENT_DEFAULT = getGlowingTranslucent(InventoryMenu.BLOCK_ATLAS);
public static RenderType getGlowingTranslucent() {

View file

@ -11,6 +11,7 @@
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [6.5, 9, 5, 16], "texture": "#0"},
"east": {"uv": [8, 8, 15, 13], "rotation": 90, "texture": "#0"},
"south": {"uv": [5, 9, 6.5, 16], "texture": "#0"},
"west": {"uv": [0, 9, 5, 16], "texture": "#0"},
"up": {"uv": [6.5, 11, 8, 16], "texture": "#0"},

View file

@ -10,6 +10,7 @@
"to": [13.05, 15.05, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [8, 8, 15, 13], "rotation": 90, "texture": "#0"},
"east": {"uv": [5, 9, 6.5, 16], "texture": "#0"},
"south": {"uv": [0, 9, 5, 16], "texture": "#0"},
"west": {"uv": [6.5, 9, 5, 16], "texture": "#0"},

View file

@ -12,6 +12,7 @@
"faces": {
"north": {"uv": [0, 9, 5, 16], "texture": "#0"},
"east": {"uv": [6.5, 9, 5, 16], "texture": "#0"},
"south": {"uv": [8, 8, 15, 13], "rotation": 90, "texture": "#0"},
"west": {"uv": [5, 9, 6.5, 16], "texture": "#0"},
"up": {"uv": [6.5, 11, 8, 16], "rotation": 90, "texture": "#0"},
"down": {"uv": [6.5, 11, 8, 16], "rotation": 270, "texture": "#0"}

View file

@ -13,6 +13,7 @@
"north": {"uv": [5, 9, 6.5, 16], "texture": "#0"},
"east": {"uv": [0, 9, 5, 16], "texture": "#0"},
"south": {"uv": [6.5, 9, 5, 16], "texture": "#0"},
"west": {"uv": [8, 8, 15, 13], "rotation": 90, "texture": "#0"},
"up": {"uv": [6.5, 11, 8, 16], "rotation": 180, "texture": "#0"},
"down": {"uv": [6.5, 11, 8, 16], "rotation": 180, "texture": "#0"}
}

View file

@ -3,81 +3,83 @@
"parent": "block/block",
"textures": {
"0": "create:block/nixie_tube",
"1": "create:block/brass_casing",
"particle": "create:block/nixie_tube"
},
"elements": [
{
"name": "base",
"from": [0, 0, 0],
"to": [16, 4, 16],
"name": "connector4",
"from": [5, 0, 9],
"to": [11, 3, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [8, 0, 16, 2], "texture": "#0"},
"east": {"uv": [8, 0, 16, 2], "texture": "#0"},
"south": {"uv": [8, 0, 16, 2], "texture": "#0"},
"west": {"uv": [8, 0, 16, 2], "texture": "#0"},
"up": {"uv": [0, 0, 8, 8], "texture": "#0"},
"down": {"uv": [0, 0, 16, 16], "texture": "#1"}
"north": {"uv": [0, 10, 6, 13], "texture": "#0"},
"east": {"uv": [0, 10, 6, 13], "texture": "#0"},
"south": {"uv": [0, 10, 6, 13], "texture": "#0"},
"west": {"uv": [0, 10, 6, 13], "texture": "#0"},
"up": {"uv": [6, 6, 12, 12], "rotation": 270, "texture": "#0"},
"down": {"uv": [6, 6, 12, 12], "rotation": 90, "texture": "#0"}
}
},
{
"name": "connector1",
"from": [1, 4, 5],
"to": [7, 6, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [9, 12, 13]},
"name": "connector5",
"from": [5, 0, 1],
"to": [11, 3, 7],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [8, 7, 11, 8], "texture": "#0"},
"east": {"uv": [8, 7, 11, 8], "texture": "#0"},
"south": {"uv": [8, 7, 11, 8], "texture": "#0"},
"west": {"uv": [8, 7, 11, 8], "texture": "#0"},
"up": {"uv": [11, 5, 14, 8], "texture": "#0"}
"north": {"uv": [0, 10, 6, 13], "texture": "#0"},
"east": {"uv": [0, 10, 6, 13], "texture": "#0"},
"south": {"uv": [0, 10, 6, 13], "texture": "#0"},
"west": {"uv": [0, 10, 6, 13], "texture": "#0"},
"up": {"uv": [6, 6, 12, 12], "rotation": 270, "texture": "#0"},
"down": {"uv": [6, 6, 12, 12], "rotation": 90, "texture": "#0"}
}
},
{
"name": "connector2",
"from": [9, 4, 5],
"to": [15, 6, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [17, 12, 13]},
"name": "tube5",
"from": [5, 3, 9],
"to": [11, 12, 15],
"rotation": {"angle": 0, "axis": "z", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [8, 7, 11, 8], "texture": "#0"},
"east": {"uv": [8, 7, 11, 8], "texture": "#0"},
"south": {"uv": [8, 7, 11, 8], "texture": "#0"},
"west": {"uv": [8, 7, 11, 8], "texture": "#0"},
"up": {"uv": [11, 5, 14, 8], "texture": "#0"}
"north": {"uv": [0, 1, 6, 10], "texture": "#0"},
"east": {"uv": [0, 1, 6, 10], "texture": "#0"},
"south": {"uv": [0, 1, 6, 10], "texture": "#0"},
"west": {"uv": [0, 1, 6, 10], "texture": "#0"},
"up": {"uv": [6, 0, 12, 6], "rotation": 180, "texture": "#0"}
}
},
{
"name": "tube1",
"from": [1, 6, 5],
"to": [7, 15, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [9, 14, 13]},
"name": "tube6",
"from": [5, 3, 1],
"to": [11, 12, 7],
"rotation": {"angle": 0, "axis": "z", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [8, 2.5, 11, 7], "texture": "#0"},
"east": {"uv": [8, 2.5, 11, 7], "texture": "#0"},
"south": {"uv": [8, 2.5, 11, 7], "texture": "#0"},
"west": {"uv": [8, 2.5, 11, 7], "texture": "#0"},
"up": {"uv": [11, 2, 14, 5], "texture": "#0"}
}
},
{
"name": "tube2",
"from": [9, 6, 5],
"to": [15, 15, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [17, 14, 13]},
"faces": {
"north": {"uv": [8, 2.5, 11, 7], "texture": "#0"},
"east": {"uv": [8, 2.5, 11, 7], "texture": "#0"},
"south": {"uv": [8, 2.5, 11, 7], "texture": "#0"},
"west": {"uv": [8, 2.5, 11, 7], "texture": "#0"},
"up": {"uv": [11, 2, 14, 5], "texture": "#0"}
"north": {"uv": [0, 1, 6, 10], "texture": "#0"},
"east": {"uv": [0, 1, 6, 10], "texture": "#0"},
"south": {"uv": [0, 1, 6, 10], "texture": "#0"},
"west": {"uv": [0, 1, 6, 10], "texture": "#0"},
"up": {"uv": [6, 0, 12, 6], "rotation": 180, "texture": "#0"}
}
}
],
"groups": [
{
"name": "nixie",
"name": "block",
"origin": [8, 8, 8],
"children": [0, 1, 2, 3, 4]
"color": 0,
"children": [
{
"name": "group",
"origin": [17, 14, 13],
"color": 0,
"children": []
},
{
"name": "group",
"origin": [17, 14, 13],
"color": 0,
"children": [0, 1, 2, 3]
}
]
}
]
}

View file

@ -3,81 +3,83 @@
"parent": "block/block",
"textures": {
"0": "create:block/nixie_tube",
"1": "create:block/brass_casing",
"particle": "create:block/nixie_tube"
},
"elements": [
{
"name": "base",
"from": [0, 0, 0],
"to": [16, 4, 16],
"name": "connector4",
"from": [9, 0, 5],
"to": [15, 3, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [8, 0, 16, 2], "texture": "#0"},
"east": {"uv": [8, 0, 16, 2], "texture": "#0"},
"south": {"uv": [8, 0, 16, 2], "texture": "#0"},
"west": {"uv": [8, 0, 16, 2], "texture": "#0"},
"up": {"uv": [0, 0, 8, 8], "texture": "#0"},
"down": {"uv": [0, 0, 16, 16], "texture": "#1"}
"north": {"uv": [0, 10, 6, 13], "texture": "#0"},
"east": {"uv": [0, 10, 6, 13], "texture": "#0"},
"south": {"uv": [0, 10, 6, 13], "texture": "#0"},
"west": {"uv": [0, 10, 6, 13], "texture": "#0"},
"up": {"uv": [6, 6, 12, 12], "rotation": 180, "texture": "#0"},
"down": {"uv": [6, 6, 12, 12], "rotation": 180, "texture": "#0"}
}
},
{
"name": "connector1",
"from": [1, 4, 5],
"to": [7, 6, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [9, 12, 13]},
"name": "connector5",
"from": [1, 0, 5],
"to": [7, 3, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [8, 7, 11, 8], "texture": "#0"},
"east": {"uv": [8, 7, 11, 8], "texture": "#0"},
"south": {"uv": [8, 7, 11, 8], "texture": "#0"},
"west": {"uv": [8, 7, 11, 8], "texture": "#0"},
"up": {"uv": [11, 5, 14, 8], "texture": "#0"}
"north": {"uv": [0, 10, 6, 13], "texture": "#0"},
"east": {"uv": [0, 10, 6, 13], "texture": "#0"},
"south": {"uv": [0, 10, 6, 13], "texture": "#0"},
"west": {"uv": [0, 10, 6, 13], "texture": "#0"},
"up": {"uv": [6, 6, 12, 12], "rotation": 180, "texture": "#0"},
"down": {"uv": [6, 6, 12, 12], "rotation": 180, "texture": "#0"}
}
},
{
"name": "connector2",
"from": [9, 4, 5],
"to": [15, 6, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [17, 12, 13]},
"name": "tube5",
"from": [9, 3, 5],
"to": [15, 12, 11],
"rotation": {"angle": 0, "axis": "z", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [8, 7, 11, 8], "texture": "#0"},
"east": {"uv": [8, 7, 11, 8], "texture": "#0"},
"south": {"uv": [8, 7, 11, 8], "texture": "#0"},
"west": {"uv": [8, 7, 11, 8], "texture": "#0"},
"up": {"uv": [11, 5, 14, 8], "texture": "#0"}
"north": {"uv": [0, 1, 6, 10], "texture": "#0"},
"east": {"uv": [0, 1, 6, 10], "texture": "#0"},
"south": {"uv": [0, 1, 6, 10], "texture": "#0"},
"west": {"uv": [0, 1, 6, 10], "texture": "#0"},
"up": {"uv": [6, 0, 12, 6], "rotation": 90, "texture": "#0"}
}
},
{
"name": "tube1",
"from": [1, 6, 5],
"to": [7, 15, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [9, 14, 13]},
"name": "tube6",
"from": [1, 3, 5],
"to": [7, 12, 11],
"rotation": {"angle": 0, "axis": "z", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [8, 2.5, 11, 7], "texture": "#0"},
"east": {"uv": [8, 2.5, 11, 7], "texture": "#0"},
"south": {"uv": [8, 2.5, 11, 7], "texture": "#0"},
"west": {"uv": [8, 2.5, 11, 7], "texture": "#0"},
"up": {"uv": [11, 2, 14, 5], "texture": "#0"}
}
},
{
"name": "tube2",
"from": [9, 6, 5],
"to": [15, 15, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [17, 14, 13]},
"faces": {
"north": {"uv": [8, 2.5, 11, 7], "texture": "#0"},
"east": {"uv": [8, 2.5, 11, 7], "texture": "#0"},
"south": {"uv": [8, 2.5, 11, 7], "texture": "#0"},
"west": {"uv": [8, 2.5, 11, 7], "texture": "#0"},
"up": {"uv": [11, 2, 14, 5], "texture": "#0"}
"north": {"uv": [0, 1, 6, 10], "texture": "#0"},
"east": {"uv": [0, 1, 6, 10], "texture": "#0"},
"south": {"uv": [0, 1, 6, 10], "texture": "#0"},
"west": {"uv": [0, 1, 6, 10], "texture": "#0"},
"up": {"uv": [6, 0, 12, 6], "rotation": 90, "texture": "#0"}
}
}
],
"groups": [
{
"name": "nixie",
"name": "block",
"origin": [8, 8, 8],
"children": [0, 1, 2, 3, 4, 5, 6]
"color": 0,
"children": [
{
"name": "group",
"origin": [17, 14, 13],
"color": 0,
"children": []
},
{
"name": "group",
"origin": [17, 14, 13],
"color": 0,
"children": [0, 1, 2, 3]
}
]
}
]
}

View file

@ -0,0 +1,57 @@
{
"credit": "Made with Blockbench",
"ambientocclusion": false,
"textures": {
"3": "create:block/track_assembly_overlay"
},
"elements": [
{
"name": "cube5",
"from": [-2.95, -2.05625, 1.9],
"to": [8, 2.24375, 6.1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 0, 8]},
"faces": {
"north": {"uv": [0, 5, 11, 9], "texture": "#3"},
"south": {"uv": [11, 5, 0, 9], "texture": "#3"},
"up": {"uv": [11, 0, 0, 4], "texture": "#3"},
"down": {"uv": [11, 10, 0, 14], "texture": "#3"}
}
},
{
"name": "cube6",
"from": [-2.95, -2.05625, 9.9],
"to": [8, 2.24375, 14.1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 0, 8]},
"faces": {
"north": {"uv": [0, 5, 11, 9], "texture": "#3"},
"south": {"uv": [11, 5, 0, 9], "texture": "#3"},
"up": {"uv": [11, 0, 0, 4], "texture": "#3"},
"down": {"uv": [11, 10, 0, 14], "texture": "#3"}
}
},
{
"name": "cube7",
"from": [8, -2.05625, 1.9],
"to": [18.95, 2.24375, 6.1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 0, 8]},
"faces": {
"north": {"uv": [11, 5, 0, 9], "texture": "#3"},
"south": {"uv": [0, 5, 11, 9], "texture": "#3"},
"up": {"uv": [11, 0, 0, 4], "rotation": 180, "texture": "#3"},
"down": {"uv": [11, 10, 0, 14], "rotation": 180, "texture": "#3"}
}
},
{
"name": "cube6",
"from": [8, -2.05625, 9.9],
"to": [18.95, 2.24375, 14.1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 0, 8]},
"faces": {
"north": {"uv": [11, 5, 0, 9], "texture": "#3"},
"south": {"uv": [0, 5, 11, 9], "texture": "#3"},
"up": {"uv": [11, 0, 0, 4], "rotation": 180, "texture": "#3"},
"down": {"uv": [11, 10, 0, 14], "rotation": 180, "texture": "#3"}
}
}
]
}

View file

@ -0,0 +1,7 @@
{
"credit": "Made with Blockbench",
"parent": "create:block/track_overlay/station",
"textures": {
"1": "create:block/track_signal_indicator"
}
}

View file

@ -0,0 +1,7 @@
{
"credit": "Made with Blockbench",
"parent": "create:block/track_overlay/station",
"textures": {
"1": "create:block/track_signal_dual_indicator"
}
}

View file

@ -0,0 +1,34 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"ambientocclusion": false,
"texture_size": [32, 32],
"textures": {
"1": "create:block/track_station_indicator",
"1_2": "create:block/depot_top",
"particle": "create:block/track_station_indicator"
},
"elements": [
{
"from": [1, 1, 1],
"to": [15, 3, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [9, -2, 9]},
"faces": {
"north": {"uv": [1, 14, 15, 16], "texture": "#1_2"},
"east": {"uv": [1, 14, 15, 16], "texture": "#1_2"},
"south": {"uv": [1, 14, 15, 16], "texture": "#1_2"},
"west": {"uv": [1, 14, 15, 16], "texture": "#1_2"},
"up": {"uv": [1, 1, 15, 15], "texture": "#1"},
"down": {"uv": [1, 0, 15, 14], "texture": "#1_2"}
}
}
],
"groups": [
{
"name": "block",
"origin": [8, 8, 8],
"color": 0,
"children": [0]
}
]
}

View file

@ -0,0 +1,85 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "create:block/signal_box",
"1": "create:block/signal_box_top",
"particle": "create:block/signal_box"
},
"elements": [
{
"from": [0, 14, 0],
"to": [16, 16, 16],
"faces": {
"north": {"uv": [0, 0, 16, 2], "texture": "#0"},
"east": {"uv": [0, 0, 16, 2], "texture": "#0"},
"south": {"uv": [0, 0, 16, 2], "texture": "#0"},
"west": {"uv": [0, 0, 16, 2], "texture": "#0"},
"up": {"uv": [0, 0, 16, 16], "texture": "#1"},
"down": {"uv": [0, 0, 16, 16], "texture": "#1"}
}
},
{
"from": [0, 0, 0],
"to": [16, 2, 16],
"faces": {
"north": {"uv": [0, 14, 16, 16], "texture": "#0"},
"east": {"uv": [0, 14, 16, 16], "texture": "#0"},
"south": {"uv": [0, 14, 16, 16], "texture": "#0"},
"west": {"uv": [0, 14, 16, 16], "texture": "#0"},
"up": {"uv": [0, 0, 16, 16], "texture": "#1"},
"down": {"uv": [0, 0, 16, 16], "texture": "#1"}
}
},
{
"from": [1, 2, 1],
"to": [15, 14, 15],
"faces": {
"north": {"uv": [1, 2, 15, 14], "texture": "#0"},
"east": {"uv": [1, 2, 15, 14], "texture": "#0"},
"south": {"uv": [1, 2, 15, 14], "texture": "#0"},
"west": {"uv": [1, 2, 15, 14], "texture": "#0"}
}
},
{
"from": [13, 2, 13],
"to": [16, 14, 16],
"faces": {
"north": {"uv": [13, 2, 16, 14], "texture": "#0"},
"east": {"uv": [0, 2, 3, 14], "texture": "#0"},
"south": {"uv": [13, 2, 16, 14], "texture": "#0"},
"west": {"uv": [0, 2, 3, 14], "texture": "#0"}
}
},
{
"from": [0, 2, 0],
"to": [3, 14, 3],
"faces": {
"north": {"uv": [13, 2, 16, 14], "texture": "#0"},
"east": {"uv": [0, 2, 3, 14], "texture": "#0"},
"south": {"uv": [13, 2, 16, 14], "texture": "#0"},
"west": {"uv": [0, 2, 3, 14], "texture": "#0"}
}
},
{
"from": [13, 2, 0],
"to": [16, 14, 3],
"faces": {
"north": {"uv": [0, 2, 3, 14], "texture": "#0"},
"east": {"uv": [13, 2, 16, 14], "texture": "#0"},
"south": {"uv": [0, 2, 3, 14], "texture": "#0"},
"west": {"uv": [13, 2, 16, 14], "texture": "#0"}
}
},
{
"from": [0, 2, 13],
"to": [3, 14, 16],
"faces": {
"north": {"uv": [0, 2, 3, 14], "texture": "#0"},
"east": {"uv": [13, 2, 16, 14], "texture": "#0"},
"south": {"uv": [0, 2, 3, 14], "texture": "#0"},
"west": {"uv": [13, 2, 16, 14], "texture": "#0"}
}
}
]
}

View file

@ -0,0 +1,35 @@
{
"credit": "Made with Blockbench",
"textures": {
"2": "create:block/indicator/0",
"particle": "create:block/signal_box"
},
"elements": [
{
"from": [0, 9, 7],
"to": [16, 11, 9],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [2, 6, 4, 8], "texture": "#2"},
"east": {"uv": [0, 3, 2, 5], "texture": "#2"},
"south": {"uv": [2, 4, 4, 6], "texture": "#2"},
"west": {"uv": [2, 3, 4, 5], "texture": "#2"},
"up": {"uv": [0, 2, 2, 4], "rotation": 270, "texture": "#2"},
"down": {"uv": [0, 6, 2, 8], "rotation": 90, "texture": "#2"}
}
},
{
"from": [7, 9, 0],
"to": [9, 11, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [2, 3, 4, 5], "texture": "#2"},
"east": {"uv": [2, 6, 4, 8], "texture": "#2"},
"south": {"uv": [0, 3, 2, 5], "texture": "#2"},
"west": {"uv": [2, 4, 4, 6], "texture": "#2"},
"up": {"uv": [0, 2, 2, 4], "texture": "#2"},
"down": {"uv": [0, 6, 2, 8], "texture": "#2"}
}
}
]
}

View file

@ -0,0 +1,35 @@
{
"credit": "Made with Blockbench",
"textures": {
"2": "create:block/indicator/6",
"particle": "create:block/signal_box"
},
"elements": [
{
"from": [0, 9, 7],
"to": [16, 11, 9],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [2, 6, 4, 8], "texture": "#2"},
"east": {"uv": [0, 3, 2, 5], "texture": "#2"},
"south": {"uv": [2, 4, 4, 6], "texture": "#2"},
"west": {"uv": [2, 3, 4, 5], "texture": "#2"},
"up": {"uv": [0, 2, 2, 4], "rotation": 270, "texture": "#2"},
"down": {"uv": [0, 6, 2, 8], "rotation": 90, "texture": "#2"}
}
},
{
"from": [7, 9, 0],
"to": [9, 11, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [2, 3, 4, 5], "texture": "#2"},
"east": {"uv": [2, 6, 4, 8], "texture": "#2"},
"south": {"uv": [0, 3, 2, 5], "texture": "#2"},
"west": {"uv": [2, 4, 4, 6], "texture": "#2"},
"up": {"uv": [0, 2, 2, 4], "texture": "#2"},
"down": {"uv": [0, 6, 2, 8], "texture": "#2"}
}
}
]
}

View file

@ -0,0 +1,112 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "create:block/signal_box",
"1": "create:block/signal_box_top",
"2": "create:block/indicator/0",
"particle": "create:block/signal_box"
},
"elements": [
{
"from": [0, 14, 0],
"to": [16, 16, 16],
"faces": {
"north": {"uv": [0, 0, 16, 2], "texture": "#0"},
"east": {"uv": [0, 0, 16, 2], "texture": "#0"},
"south": {"uv": [0, 0, 16, 2], "texture": "#0"},
"west": {"uv": [0, 0, 16, 2], "texture": "#0"},
"up": {"uv": [0, 0, 16, 16], "texture": "#1"},
"down": {"uv": [0, 0, 16, 16], "texture": "#1"}
}
},
{
"from": [0, 0, 0],
"to": [16, 2, 16],
"faces": {
"north": {"uv": [0, 14, 16, 16], "texture": "#0"},
"east": {"uv": [0, 14, 16, 16], "texture": "#0"},
"south": {"uv": [0, 14, 16, 16], "texture": "#0"},
"west": {"uv": [0, 14, 16, 16], "texture": "#0"},
"up": {"uv": [0, 0, 16, 16], "texture": "#1"},
"down": {"uv": [0, 0, 16, 16], "texture": "#1"}
}
},
{
"from": [1, 2, 1],
"to": [15, 14, 15],
"faces": {
"north": {"uv": [1, 2, 15, 14], "texture": "#0"},
"east": {"uv": [1, 2, 15, 14], "texture": "#0"},
"south": {"uv": [1, 2, 15, 14], "texture": "#0"},
"west": {"uv": [1, 2, 15, 14], "texture": "#0"}
}
},
{
"from": [13, 2, 13],
"to": [16, 14, 16],
"faces": {
"north": {"uv": [13, 2, 16, 14], "texture": "#0"},
"east": {"uv": [0, 2, 3, 14], "texture": "#0"},
"south": {"uv": [13, 2, 16, 14], "texture": "#0"},
"west": {"uv": [0, 2, 3, 14], "texture": "#0"}
}
},
{
"from": [0, 2, 0],
"to": [3, 14, 3],
"faces": {
"north": {"uv": [13, 2, 16, 14], "texture": "#0"},
"east": {"uv": [0, 2, 3, 14], "texture": "#0"},
"south": {"uv": [13, 2, 16, 14], "texture": "#0"},
"west": {"uv": [0, 2, 3, 14], "texture": "#0"}
}
},
{
"from": [13, 2, 0],
"to": [16, 14, 3],
"faces": {
"north": {"uv": [0, 2, 3, 14], "texture": "#0"},
"east": {"uv": [13, 2, 16, 14], "texture": "#0"},
"south": {"uv": [0, 2, 3, 14], "texture": "#0"},
"west": {"uv": [13, 2, 16, 14], "texture": "#0"}
}
},
{
"from": [0, 2, 13],
"to": [3, 14, 16],
"faces": {
"north": {"uv": [0, 2, 3, 14], "texture": "#0"},
"east": {"uv": [13, 2, 16, 14], "texture": "#0"},
"south": {"uv": [0, 2, 3, 14], "texture": "#0"},
"west": {"uv": [13, 2, 16, 14], "texture": "#0"}
}
},
{
"from": [0, 9, 7],
"to": [16, 11, 9],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [2, 6, 4, 8], "texture": "#2"},
"east": {"uv": [0, 3, 2, 5], "texture": "#2"},
"south": {"uv": [2, 4, 4, 6], "texture": "#2"},
"west": {"uv": [2, 3, 4, 5], "texture": "#2"},
"up": {"uv": [0, 2, 2, 4], "rotation": 270, "texture": "#2"},
"down": {"uv": [0, 6, 2, 8], "rotation": 90, "texture": "#2"}
}
},
{
"from": [7, 9, 0],
"to": [9, 11, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [2, 3, 4, 5], "texture": "#2"},
"east": {"uv": [2, 6, 4, 8], "texture": "#2"},
"south": {"uv": [0, 3, 2, 5], "texture": "#2"},
"west": {"uv": [2, 4, 4, 6], "texture": "#2"},
"up": {"uv": [0, 2, 2, 4], "texture": "#2"},
"down": {"uv": [0, 6, 2, 8], "texture": "#2"}
}
}
]
}

View file

@ -0,0 +1,79 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"2": "create:block/signal",
"3": "create:block/nixie_tube",
"particle": "create:block/signal"
},
"elements": [
{
"name": "connector3",
"from": [5, 0, 9],
"to": [11, 3, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [1, 12, 7, 15], "texture": "#2"},
"east": {"uv": [1, 12, 7, 15], "texture": "#2"},
"south": {"uv": [1, 12, 7, 15], "texture": "#2"},
"west": {"uv": [1, 12, 7, 15], "texture": "#2"},
"up": {"uv": [9, 9, 15, 15], "rotation": 90, "texture": "#2"},
"down": {"uv": [9, 9, 15, 15], "rotation": 270, "texture": "#2"}
}
},
{
"name": "connector4",
"from": [5, 0, 1],
"to": [11, 3, 7],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [1, 12, 7, 15], "texture": "#2"},
"east": {"uv": [1, 12, 7, 15], "texture": "#2"},
"south": {"uv": [1, 12, 7, 15], "texture": "#2"},
"west": {"uv": [1, 12, 7, 15], "texture": "#2"},
"up": {"uv": [9, 9, 15, 15], "rotation": 90, "texture": "#2"},
"down": {"uv": [9, 9, 15, 15], "rotation": 270, "texture": "#2"}
}
},
{
"name": "tube4",
"from": [5, 3, 9],
"to": [11, 12, 15],
"rotation": {"angle": 0, "axis": "z", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [8, 2.5, 11, 7], "texture": "#3"},
"east": {"uv": [8, 2.5, 11, 7], "texture": "#3"},
"south": {"uv": [8, 2.5, 11, 7], "texture": "#3"},
"west": {"uv": [8, 2.5, 11, 7], "texture": "#3"},
"up": {"uv": [11, 2, 14, 5], "texture": "#3"}
}
},
{
"name": "tube5",
"from": [5, 3, 1],
"to": [11, 12, 7],
"rotation": {"angle": 0, "axis": "z", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [8, 2.5, 11, 7], "texture": "#3"},
"east": {"uv": [8, 2.5, 11, 7], "texture": "#3"},
"south": {"uv": [8, 2.5, 11, 7], "texture": "#3"},
"west": {"uv": [8, 2.5, 11, 7], "texture": "#3"},
"up": {"uv": [11, 2, 14, 5], "texture": "#3"}
}
}
],
"groups": [
{
"name": "group",
"origin": [17, 14, 13],
"color": 0,
"children": []
},
{
"name": "group",
"origin": [17, 14, 13],
"color": 0,
"children": [0, 1, 2, 3]
}
]
}

View file

@ -0,0 +1,31 @@
{
"credit": "Made with Blockbench",
"texture_size": [32, 32],
"textures": {
"1": "create:block/nixie_tube"
},
"elements": [
{
"from": [1.5, 3, 6.5],
"to": [6.5, 11, 7.5],
"faces": {
"north": {"uv": [7.5, 13.25, 11.5, 15.75], "rotation": 90, "texture": "#1"},
"east": {"uv": [7.5, 13.25, 11.5, 15.75], "rotation": 90, "texture": "#1"},
"south": {"uv": [7.5, 13.25, 11.5, 15.75], "rotation": 90, "texture": "#1"},
"west": {"uv": [7.5, 13.25, 11.5, 15.75], "rotation": 90, "texture": "#1"},
"up": {"uv": [7.5, 13.25, 7.25, 15.75], "rotation": 90, "texture": "#1"}
}
},
{
"from": [9.5, 3, 6.5],
"to": [14.5, 11, 7.5],
"faces": {
"north": {"uv": [7.5, 13.25, 11.5, 15.75], "rotation": 90, "texture": "#1"},
"east": {"uv": [7.5, 13.25, 11.5, 15.75], "rotation": 90, "texture": "#1"},
"south": {"uv": [7.5, 13.25, 11.5, 15.75], "rotation": 90, "texture": "#1"},
"west": {"uv": [7.5, 13.25, 11.5, 15.75], "rotation": 90, "texture": "#1"},
"up": {"uv": [7.5, 13.25, 7.25, 15.75], "rotation": 90, "texture": "#1"}
}
}
]
}

View file

@ -0,0 +1,21 @@
{
"credit": "Made with Blockbench",
"textures": {
"0": "create:block/signal_glow",
"particle": "create:block/signal_glow"
},
"elements": [
{
"from": [-0.5, -0.5, -0.5],
"to": [0.5, 0.5, 0.5],
"faces": {
"north": {"uv": [1, 1, 2, 2], "texture": "#0"},
"east": {"uv": [1, 1, 2, 2], "texture": "#0"},
"south": {"uv": [1, 1, 2, 2], "texture": "#0"},
"west": {"uv": [1, 1, 2, 2], "texture": "#0"},
"up": {"uv": [1, 1, 2, 2], "texture": "#0"},
"down": {"uv": [1, 1, 2, 2], "texture": "#0"}
}
}
]
}

View file

@ -0,0 +1,21 @@
{
"credit": "Made with Blockbench",
"textures": {
"0": "create:block/signal_glow",
"particle": "create:block/signal_glow"
},
"elements": [
{
"from": [-0.5, -0.5, -0.5],
"to": [0.5, 0.5, 0.5],
"faces": {
"north": {"uv": [1, 0, 2, 1], "texture": "#0"},
"east": {"uv": [1, 0, 2, 1], "texture": "#0"},
"south": {"uv": [1, 0, 2, 1], "texture": "#0"},
"west": {"uv": [1, 0, 2, 1], "texture": "#0"},
"up": {"uv": [1, 0, 2, 1], "texture": "#0"},
"down": {"uv": [1, 0, 2, 1], "texture": "#0"}
}
}
]
}

View file

@ -0,0 +1,39 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"ambientocclusion": false,
"textures": {
"2": "create:block/signal_glow",
"particle": "create:block/signal_glow"
},
"elements": [
{
"name": "tube3",
"from": [-3, -4.5, -3],
"to": [3, 4.5, 3],
"rotation": {"angle": 0, "axis": "z", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [10, 7, 16, 16], "texture": "#2"},
"east": {"uv": [10, 7, 16, 16], "texture": "#2"},
"south": {"uv": [10, 7, 16, 16], "texture": "#2"},
"west": {"uv": [10, 7, 16, 16], "texture": "#2"},
"up": {"uv": [10, 0, 16, 6], "rotation": 90, "texture": "#2"},
"down": {"uv": [10, 0, 16, 6], "rotation": 90, "texture": "#2"}
}
}
],
"groups": [
{
"name": "group",
"origin": [17, 14, 13],
"color": 0,
"children": []
},
{
"name": "group",
"origin": [17, 14, 13],
"color": 0,
"children": [0]
}
]
}

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