"|" 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 f25693a9429f6337149ff24f27900dc4eb82a7c2 assets/create/blockstates/belt.json
cf9045eb16e5299a1d917c4cb536289f49411276 assets/create/blockstates/birch_window.json cf9045eb16e5299a1d917c4cb536289f49411276 assets/create/blockstates/birch_window.json
94a1a91403eb4b035fec48071e7fcae57a8a6abd assets/create/blockstates/birch_window_pane.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 e0f1e44c9bce4a7478592cf3a8ee7b91d9083d65 assets/create/blockstates/black_sail.json
58b07d2af6030342f0354f6d3fd0ee128d2d74b4 assets/create/blockstates/black_seat.json 58b07d2af6030342f0354f6d3fd0ee128d2d74b4 assets/create/blockstates/black_seat.json
73db8bd55bd5bd21f939ee9eb4b4b02209d9c5ed assets/create/blockstates/black_toolbox.json 73db8bd55bd5bd21f939ee9eb4b4b02209d9c5ed assets/create/blockstates/black_toolbox.json
a71ddf3291bd13d7877f2fe32c42f50407f99afb assets/create/blockstates/black_valve_handle.json a71ddf3291bd13d7877f2fe32c42f50407f99afb assets/create/blockstates/black_valve_handle.json
923aeb2a556f67bc0526f237dd97af2d37b4c9f1 assets/create/blockstates/blaze_burner.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 ec2ab87734acc209e6be3bc4898b1199f819bfd3 assets/create/blockstates/blue_sail.json
4854d1ef52130a7887aecc60bcaffbd66f0871a8 assets/create/blockstates/blue_seat.json 4854d1ef52130a7887aecc60bcaffbd66f0871a8 assets/create/blockstates/blue_seat.json
dea175335c5db0abe758cd208dc984c22506a176 assets/create/blockstates/blue_toolbox.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 288bad07593a8a2c8efaf44bba0ffb0011d36cd3 assets/create/blockstates/brass_encased_shaft.json
adfbd6cc5e44a0f431180aedbe65a19428299d8e assets/create/blockstates/brass_funnel.json adfbd6cc5e44a0f431180aedbe65a19428299d8e assets/create/blockstates/brass_funnel.json
672eedcd3520c6d39603449165a23be9c612c620 assets/create/blockstates/brass_tunnel.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 11ebdd9bd0815833e62ec1bea03a4cdd86ce00f3 assets/create/blockstates/brown_sail.json
e81608346d43406ee72cae0f78b8bcfb37ba2d75 assets/create/blockstates/brown_seat.json e81608346d43406ee72cae0f78b8bcfb37ba2d75 assets/create/blockstates/brown_seat.json
bd73bfdbe88c58883cc15fe31a9dac7860482ca3 assets/create/blockstates/brown_toolbox.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 d6a8c385c9ebc5bae603c908b6f8eccd6f5ad94b assets/create/blockstates/cut_veridium_slab.json
3f3ab7e6792c6ecbc0201b728a3dba091f56334f assets/create/blockstates/cut_veridium_stairs.json 3f3ab7e6792c6ecbc0201b728a3dba091f56334f assets/create/blockstates/cut_veridium_stairs.json
62b181dcbb1f8de809be2625e8735ff3d7169a7d assets/create/blockstates/cut_veridium_wall.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 b496452f2f7dbbba385e1fc10b560ec266e4b5e7 assets/create/blockstates/cyan_sail.json
4de72f65bff4e5d9c8153fa3adeee6b61d6f912b assets/create/blockstates/cyan_seat.json 4de72f65bff4e5d9c8153fa3adeee6b61d6f912b assets/create/blockstates/cyan_seat.json
8e14112e948e492da8151b773c1fa40bf1467490 assets/create/blockstates/cyan_toolbox.json 8e14112e948e492da8151b773c1fa40bf1467490 assets/create/blockstates/cyan_toolbox.json
@ -216,12 +216,12 @@ eca1f0e56efdadb241f42dc6ebb036f1d52213a9 assets/create/blockstates/gearbox.json
f34814b17cde3231a1dfb271f3dabf8d6de4fbf6 assets/create/blockstates/gearshift.json f34814b17cde3231a1dfb271f3dabf8d6de4fbf6 assets/create/blockstates/gearshift.json
93f8bdc22d9a5e04268964e35e4285c8cbf2b89d assets/create/blockstates/glass_fluid_pipe.json 93f8bdc22d9a5e04268964e35e4285c8cbf2b89d assets/create/blockstates/glass_fluid_pipe.json
f5928e309add6e414cf69e675cef9287750a427c assets/create/blockstates/granite_pillar.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 5c40c4a27e1dec747a467dd251700c72a6ceb07d assets/create/blockstates/gray_sail.json
a5ec5401ba9f3e102a2e1b35837f643847afbca4 assets/create/blockstates/gray_seat.json a5ec5401ba9f3e102a2e1b35837f643847afbca4 assets/create/blockstates/gray_seat.json
191d2cc56af51349688ccb2dea75801a9bc9de85 assets/create/blockstates/gray_toolbox.json 191d2cc56af51349688ccb2dea75801a9bc9de85 assets/create/blockstates/gray_toolbox.json
5f17a5868616b33eb157965a661046cab7a1427f assets/create/blockstates/gray_valve_handle.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 52b849faef96b8ab9d9d64a1518c8f299af057b8 assets/create/blockstates/green_sail.json
13059309684db0cc7a0f1f4fce2407cf06cce80a assets/create/blockstates/green_seat.json 13059309684db0cc7a0f1f4fce2407cf06cce80a assets/create/blockstates/green_seat.json
e91dcebe132d5b745df0f6c5b1c90d5fc4e8af52 assets/create/blockstates/green_toolbox.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 b743ef11048fc284ba5622e1fbae3082f0616382 assets/create/blockstates/layered_tuff.json
21233210f6e68a47bb66207613c08df6cd97e796 assets/create/blockstates/layered_veridium.json 21233210f6e68a47bb66207613c08df6cd97e796 assets/create/blockstates/layered_veridium.json
6a3c81d62c7c5a5fa2f4a1e239319d83875bbe55 assets/create/blockstates/lectern_controller.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 029904f21970947a4423a6e0c8c65c4e02f2e8e6 assets/create/blockstates/light_blue_sail.json
2a0a8b1715700bf1e284ee57ef9f7f163c12f3ee assets/create/blockstates/light_blue_seat.json 2a0a8b1715700bf1e284ee57ef9f7f163c12f3ee assets/create/blockstates/light_blue_seat.json
527f32e0d2b5b975cfeb515542098bb2d5224755 assets/create/blockstates/light_blue_toolbox.json 527f32e0d2b5b975cfeb515542098bb2d5224755 assets/create/blockstates/light_blue_toolbox.json
9bee040558a6b24e21f837fc808e17fae1883e71 assets/create/blockstates/light_blue_valve_handle.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 93537c4e2ab86218a777e7b000c3fcd55a80b1cd assets/create/blockstates/light_gray_sail.json
d9a2551e001bb315d071bb9f1f013323a66a5d09 assets/create/blockstates/light_gray_seat.json d9a2551e001bb315d071bb9f1f013323a66a5d09 assets/create/blockstates/light_gray_seat.json
0c40d13637f00a533175d29ba67559461101ead5 assets/create/blockstates/light_gray_toolbox.json 0c40d13637f00a533175d29ba67559461101ead5 assets/create/blockstates/light_gray_toolbox.json
8bea8c86de8c218c8932eef140f0ed439e173156 assets/create/blockstates/light_gray_valve_handle.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 ba2c4e3ddafa3c89a72cc243b14e8518fab369aa assets/create/blockstates/lime_sail.json
1de3a88c003df03f5006e1bbaa0236589aba08ad assets/create/blockstates/lime_seat.json 1de3a88c003df03f5006e1bbaa0236589aba08ad assets/create/blockstates/lime_seat.json
db46a5b6d0b595293a672236d0a64548b0816cab assets/create/blockstates/lime_toolbox.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 bff90a8d674a839b13fd9cd1f78bf3d0ad9fad4f assets/create/blockstates/limestone_pillar.json
69790737767e06f000c7824749c46664a123160e assets/create/blockstates/linear_chassis.json 69790737767e06f000c7824749c46664a123160e assets/create/blockstates/linear_chassis.json
56b111c8a345627e9f37deac141138064271c2f1 assets/create/blockstates/lit_blaze_burner.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 85a58ac539775f90903d9ce66374f3f2ffd4fecf assets/create/blockstates/magenta_sail.json
84c494d24cc58af274fdd054896c680e8095d2d0 assets/create/blockstates/magenta_seat.json 84c494d24cc58af274fdd054896c680e8095d2d0 assets/create/blockstates/magenta_seat.json
2334006c152d6773040ca03ef3b3d26a58f0dfa0 assets/create/blockstates/magenta_toolbox.json 2334006c152d6773040ca03ef3b3d26a58f0dfa0 assets/create/blockstates/magenta_toolbox.json
@ -295,7 +295,7 @@ e20699a753e7b12abd4a881de473d494a4ffeaa9 assets/create/blockstates/metal_girder_
4e48ad0936647065c2322390e7c0fe115c853a98 assets/create/blockstates/millstone.json 4e48ad0936647065c2322390e7c0fe115c853a98 assets/create/blockstates/millstone.json
468202df0802e17c75fcad0993daf1bc5300ca91 assets/create/blockstates/minecart_anchor.json 468202df0802e17c75fcad0993daf1bc5300ca91 assets/create/blockstates/minecart_anchor.json
b1126c191877cff86b4e2de83e1fcbd151451cb7 assets/create/blockstates/mysterious_cuckoo_clock.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 36e46e65003a8d0b8555fe5e8f8dc980d6559bc5 assets/create/blockstates/nozzle.json
cf60989f63f02067fc4e4ad25033ac83167cdeb0 assets/create/blockstates/oak_window.json cf60989f63f02067fc4e4ad25033ac83167cdeb0 assets/create/blockstates/oak_window.json
4a796509c3953171f04f957351282205840b3760 assets/create/blockstates/oak_window_pane.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 94761f4295416261080bc6a1b21a5790ac7104dc assets/create/blockstates/oxidized_copper_tile_stairs.json
9257b8d0d1edd9c707d1fc6c9819eca569d954e0 assets/create/blockstates/oxidized_copper_tiles.json 9257b8d0d1edd9c707d1fc6c9819eca569d954e0 assets/create/blockstates/oxidized_copper_tiles.json
005cc195712aca252326ae8239ed0caf9a69a314 assets/create/blockstates/peculiar_bell.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 30971f2f76fe56f144178c33ad6bde5fc9fb61c3 assets/create/blockstates/pink_sail.json
919a79e4a4a5fab0aac3ef48e1c786017d6aa001 assets/create/blockstates/pink_seat.json 919a79e4a4a5fab0aac3ef48e1c786017d6aa001 assets/create/blockstates/pink_seat.json
588ebcdb4c1d8d4c75225e92f26d6cf80cac2f15 assets/create/blockstates/pink_toolbox.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 3a739f9d4276828d83f2d2750bf3227c87bcd438 assets/create/blockstates/pulley_magnet.json
dee3cdef860bb92d439ecaaec4300b42208b025c assets/create/blockstates/pulse_extender.json dee3cdef860bb92d439ecaaec4300b42208b025c assets/create/blockstates/pulse_extender.json
638eb675fe3c464a0ab265c37f7d37fdf6440323 assets/create/blockstates/pulse_repeater.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 d06cd9a1101b18d306a786320aab12018b1325d6 assets/create/blockstates/purple_sail.json
92957119abd5fbcca36a113b2a80255fd70fc303 assets/create/blockstates/purple_seat.json 92957119abd5fbcca36a113b2a80255fd70fc303 assets/create/blockstates/purple_seat.json
b78c6057ef94b03f541a17e625b3778ca526a6ad assets/create/blockstates/purple_toolbox.json b78c6057ef94b03f541a17e625b3778ca526a6ad assets/create/blockstates/purple_toolbox.json
61035f8afe75ff7bbd291da5d8690bcbebe679eb assets/create/blockstates/purple_valve_handle.json 61035f8afe75ff7bbd291da5d8690bcbebe679eb assets/create/blockstates/purple_valve_handle.json
4439fc83a8c7370ab44b211a3fd48abde20a4728 assets/create/blockstates/radial_chassis.json 4439fc83a8c7370ab44b211a3fd48abde20a4728 assets/create/blockstates/radial_chassis.json
c9ccf6fe4c80357ba2e4d053f5a1b35df4f377a8 assets/create/blockstates/raw_zinc_block.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 45877c4d90a7185c2f304edbd67379d800920439 assets/create/blockstates/red_sail.json
da1b08387af7afa0855ee8d040f620c01f20660a assets/create/blockstates/red_seat.json da1b08387af7afa0855ee8d040f620c01f20660a assets/create/blockstates/red_seat.json
27fad7876f5a2de16f13dfde16d4a05dfe093989 assets/create/blockstates/red_toolbox.json 27fad7876f5a2de16f13dfde16d4a05dfe093989 assets/create/blockstates/red_toolbox.json
@ -482,6 +482,7 @@ e815bfd854c2653f10828bb11950f7fb991d7efc assets/create/blockstates/stressometer.
8b0c2c7ac72529565b3339aa8df7565858100afa assets/create/blockstates/tiled_glass.json 8b0c2c7ac72529565b3339aa8df7565858100afa assets/create/blockstates/tiled_glass.json
a2454400b1cf9889f70aebdc89c52a1be25f543c assets/create/blockstates/tiled_glass_pane.json a2454400b1cf9889f70aebdc89c52a1be25f543c assets/create/blockstates/tiled_glass_pane.json
85b57776edf426c2f8df6698b2482ea925914a5c assets/create/blockstates/track.json 85b57776edf426c2f8df6698b2482ea925914a5c assets/create/blockstates/track.json
5a61450b6f6aac63f75580f8dcbc3d3fabfd54d8 assets/create/blockstates/track_signal.json
aa08785f906d41933e0dd1086ea7b08f5b93aa24 assets/create/blockstates/track_station.json aa08785f906d41933e0dd1086ea7b08f5b93aa24 assets/create/blockstates/track_station.json
29af21c8d82891139d48d69f0393f612f2b6f8f1 assets/create/blockstates/tuff_pillar.json 29af21c8d82891139d48d69f0393f612f2b6f8f1 assets/create/blockstates/tuff_pillar.json
a8094531617e27a545c4815ab2062bf0ffca3633 assets/create/blockstates/turntable.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 d7588ea4a82633c38c7a33f17d4c1c2876d7f6a9 assets/create/blockstates/weathered_copper_tile_stairs.json
3d4fec3f32782c7158b10baf768ce85b3232d8fe assets/create/blockstates/weathered_copper_tiles.json 3d4fec3f32782c7158b10baf768ce85b3232d8fe assets/create/blockstates/weathered_copper_tiles.json
c838c0792511ca2e14493b40032bb1370fac588a assets/create/blockstates/weighted_ejector.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 512bf17c9ea309b1f7da54440f923530d25e467c assets/create/blockstates/white_sail.json
4647010162eb4c350fad236d860317eaa1884c77 assets/create/blockstates/white_seat.json 4647010162eb4c350fad236d860317eaa1884c77 assets/create/blockstates/white_seat.json
3695510f11231c8a5c1a0be94a92703e4b5a0f9c assets/create/blockstates/white_toolbox.json 3695510f11231c8a5c1a0be94a92703e4b5a0f9c assets/create/blockstates/white_toolbox.json
89000903d0ab8139e919abea7aa0361b34c24e55 assets/create/blockstates/white_valve_handle.json 89000903d0ab8139e919abea7aa0361b34c24e55 assets/create/blockstates/white_valve_handle.json
c4cd1131113667da0180898b5db3ebad609db8ba assets/create/blockstates/windmill_bearing.json c4cd1131113667da0180898b5db3ebad609db8ba assets/create/blockstates/windmill_bearing.json
d4f804f2818376950ef28fc8d6250419f4e12218 assets/create/blockstates/wooden_bracket.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 e03c48512967845fce09d84b955d3bc7b480fedc assets/create/blockstates/yellow_sail.json
a3a11524cd3515fc01d905767b4b7ea782adaf03 assets/create/blockstates/yellow_seat.json a3a11524cd3515fc01d905767b4b7ea782adaf03 assets/create/blockstates/yellow_seat.json
bf2b0310500213ff853c748c236eb5d01f61658e assets/create/blockstates/yellow_toolbox.json bf2b0310500213ff853c748c236eb5d01f61658e assets/create/blockstates/yellow_toolbox.json
6801fa1f466f172700e573e5b8ee8ee5f9ca4583 assets/create/blockstates/yellow_valve_handle.json 6801fa1f466f172700e573e5b8ee8ee5f9ca4583 assets/create/blockstates/yellow_valve_handle.json
7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json 7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json
b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json
99fe404c85879934693a6afca6c0088e04c50657 assets/create/lang/en_ud.json 8d5cb91338bccfa4f3acfd048b28e08acc9a82b7 assets/create/lang/en_ud.json
a66727961d19361e9f6fc2a81a93053f11155141 assets/create/lang/en_us.json 4a5c5a6f4677bf4f6fe40acfe93bda03ea5568e0 assets/create/lang/en_us.json
40e345f3514d00a6de7ee6ccd07af0991155042f assets/create/lang/unfinished/de_de.json 645c1f48d82161f920bda0cff4bfe9e46aba6416 assets/create/lang/unfinished/de_de.json
7e9c89a7b70fab85346c30258d9db728bcdd0a11 assets/create/lang/unfinished/es_cl.json 9aeeaff96624e945cf0018b36b7a817169001ef2 assets/create/lang/unfinished/es_cl.json
e0cd89e2e67a7a6e1b744a7f44bea4dbc6861011 assets/create/lang/unfinished/es_es.json 34dbc3806e178e33ea35fdad0f018ff5b8dfccd0 assets/create/lang/unfinished/es_es.json
76401cc86ef9545a382094dd128779f1af05f489 assets/create/lang/unfinished/fr_fr.json 8e054f9fc4c1b937f9b35c87c0d13aac09e175df assets/create/lang/unfinished/fr_fr.json
763380d38ee082a85fa28a74db3d1fa3a6f8e931 assets/create/lang/unfinished/it_it.json 35492c408d1abdf11ef9f82fd4eb4444e467575e assets/create/lang/unfinished/it_it.json
4afbee011c0877633241ea3655f1c97b5431f608 assets/create/lang/unfinished/ja_jp.json e1176e97d402311c798f1e5bdd0fc86b2fe230f2 assets/create/lang/unfinished/ja_jp.json
b3fc6f2fcb5dfb357fb066d9665e4adc487515df assets/create/lang/unfinished/ko_kr.json dbf8fee3b62bfac529cd15ce324b52ce62d79a3e assets/create/lang/unfinished/ko_kr.json
62db40a1b598ebab022156ba3849cfe9ceb8e1a9 assets/create/lang/unfinished/nl_nl.json 4a7baacd9fa0112b5a2c82670e46ce27e4ebfaa9 assets/create/lang/unfinished/nl_nl.json
075f756c2b25f8abf8684a9f967c8dba706540c8 assets/create/lang/unfinished/pl_pl.json 68bb201f1e6b5d549dd0da5eecf5bd93279fc51b assets/create/lang/unfinished/pl_pl.json
bb7a09bac75414ea509f960abb0ef902c939f00b assets/create/lang/unfinished/pt_br.json 23717bc699dbb33f3b1b7c1ea256eaa3d2351f17 assets/create/lang/unfinished/pt_br.json
ec9eca6a8e36457857f8f6dd03c8f16d8a583d3a assets/create/lang/unfinished/pt_pt.json b6477a01032733848b11b3f669b44bf7a67f6512 assets/create/lang/unfinished/pt_pt.json
47a78bac16ed55a4a14c04273e9e6226668699ca assets/create/lang/unfinished/ru_ru.json 58a008a6683a807b3e52afaa536821fee82e7700 assets/create/lang/unfinished/ru_ru.json
6c11045cd143c80bfe8fbf84e58403dda58cb6e5 assets/create/lang/unfinished/zh_cn.json 7123ac611ea8c2ce7a100c09a2f7213bead8bb35 assets/create/lang/unfinished/zh_cn.json
8d4484b00acdad79717093384fcc3db0d96ba67b assets/create/lang/unfinished/zh_tw.json 42a371f8007daa1101b8664c96ace6ba9eb2188f assets/create/lang/unfinished/zh_tw.json
487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json 487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json
b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.json b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.json
3066db1bf03cffa1a9c7fbacf47ae586632f4eb3 assets/create/models/block/acacia_window_pane_noside_alt.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 b1d3d00ff05908feacad06a86800da96cc9bc65d assets/create/models/item/tiled_glass.json
a7d0b746637897209bd86b1a6501ecbfb46d8270 assets/create/models/item/tiled_glass_pane.json a7d0b746637897209bd86b1a6501ecbfb46d8270 assets/create/models/item/tiled_glass_pane.json
6b5569f25fa2d905729a3f18deb56b6c67c5dfa4 assets/create/models/item/track.json 6b5569f25fa2d905729a3f18deb56b6c67c5dfa4 assets/create/models/item/track.json
c317adb86ee47765dd7716539c65f31f329deb85 assets/create/models/item/track_signal.json
d6364e9d11915e53dafd8761f016e4b23c7703c8 assets/create/models/item/track_station.json d6364e9d11915e53dafd8761f016e4b23c7703c8 assets/create/models/item/track_station.json
f8a4fa1ccecb16a3941cc46db7481ed8e8429a5e assets/create/models/item/tree_fertilizer.json f8a4fa1ccecb16a3941cc46db7481ed8e8429a5e assets/create/models/item/tree_fertilizer.json
3f6810da54724de551591b46cd5b47a98a4737ef assets/create/models/item/tuff_pillar.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 811674fd816503cd78fc4df267dc23f760940e8f data/create/loot_tables/blocks/tiled_glass.json
313344ef4ee67ffd0f7fd44adcb3ad08de571c92 data/create/loot_tables/blocks/tiled_glass_pane.json 313344ef4ee67ffd0f7fd44adcb3ad08de571c92 data/create/loot_tables/blocks/tiled_glass_pane.json
e2846b8823918bce402eb361f703ecdc14251ccc data/create/loot_tables/blocks/track.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 4617a11e220dcd0094c29d204fe90c01495c4e9b data/create/loot_tables/blocks/track_station.json
8fbe59bc77b029b802c43fb8a930778dede440ea data/create/loot_tables/blocks/tuff_pillar.json 8fbe59bc77b029b802c43fb8a930778dede440ea data/create/loot_tables/blocks/tuff_pillar.json
2419d50b6086e92ab05624fdf38ef2b55c0b0944 data/create/loot_tables/blocks/turntable.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 69f596fcb065e26b02ce246760432b5174191b76 data/minecraft/tags/blocks/impermeable.json
2db7759fe036160c14c6ed19a68604ca16f4de60 data/minecraft/tags/blocks/lush_ground_replaceable.json 2db7759fe036160c14c6ed19a68604ca16f4de60 data/minecraft/tags/blocks/lush_ground_replaceable.json
02f7a9df2f9e154749266e7ac59c37aa076a3390 data/minecraft/tags/blocks/mineable/axe.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 2db7759fe036160c14c6ed19a68604ca16f4de60 data/minecraft/tags/blocks/moss_replaceable.json
e157c1d3af30e409e34bbefbe15a037e6e1c8daa data/minecraft/tags/blocks/needs_iron_tool.json e157c1d3af30e409e34bbefbe15a037e6e1c8daa data/minecraft/tags/blocks/needs_iron_tool.json
a08f67865337f62601c5e333b4011382d10020e4 data/minecraft/tags/blocks/needs_stone_tool.json a08f67865337f62601c5e333b4011382d10020e4 data/minecraft/tags/blocks/needs_stone_tool.json

View file

@ -1,35 +1,145 @@
{ {
"variants": { "variants": {
"ceiling=false,facing=north": { "double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/black_nixie_tube", "model": "create:block/black_nixie_tube",
"y": 180 "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", "model": "create:block/black_nixie_tube",
"x": 180, "x": 180,
"y": 180 "y": 180
}, },
"ceiling=false,facing=south": { "double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/black_nixie_tube" "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", "model": "create:block/black_nixie_tube",
"x": 180 "x": 180
}, },
"ceiling=false,facing=west": { "double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/black_nixie_tube", "model": "create:block/black_nixie_tube",
"y": 90 "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", "model": "create:block/black_nixie_tube",
"x": 180, "x": 180,
"y": 90 "y": 90
}, },
"ceiling=false,facing=east": { "double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/black_nixie_tube", "model": "create:block/black_nixie_tube",
"y": 270 "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", "model": "create:block/black_nixie_tube",
"x": 180, "x": 180,
"y": 270 "y": 270

View file

@ -1,35 +1,145 @@
{ {
"variants": { "variants": {
"ceiling=false,facing=north": { "double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/blue_nixie_tube", "model": "create:block/blue_nixie_tube",
"y": 180 "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", "model": "create:block/blue_nixie_tube",
"x": 180, "x": 180,
"y": 180 "y": 180
}, },
"ceiling=false,facing=south": { "double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/blue_nixie_tube" "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", "model": "create:block/blue_nixie_tube",
"x": 180 "x": 180
}, },
"ceiling=false,facing=west": { "double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/blue_nixie_tube", "model": "create:block/blue_nixie_tube",
"y": 90 "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", "model": "create:block/blue_nixie_tube",
"x": 180, "x": 180,
"y": 90 "y": 90
}, },
"ceiling=false,facing=east": { "double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/blue_nixie_tube", "model": "create:block/blue_nixie_tube",
"y": 270 "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", "model": "create:block/blue_nixie_tube",
"x": 180, "x": 180,
"y": 270 "y": 270

View file

@ -1,35 +1,145 @@
{ {
"variants": { "variants": {
"ceiling=false,facing=north": { "double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/brown_nixie_tube", "model": "create:block/brown_nixie_tube",
"y": 180 "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", "model": "create:block/brown_nixie_tube",
"x": 180, "x": 180,
"y": 180 "y": 180
}, },
"ceiling=false,facing=south": { "double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/brown_nixie_tube" "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", "model": "create:block/brown_nixie_tube",
"x": 180 "x": 180
}, },
"ceiling=false,facing=west": { "double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/brown_nixie_tube", "model": "create:block/brown_nixie_tube",
"y": 90 "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", "model": "create:block/brown_nixie_tube",
"x": 180, "x": 180,
"y": 90 "y": 90
}, },
"ceiling=false,facing=east": { "double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/brown_nixie_tube", "model": "create:block/brown_nixie_tube",
"y": 270 "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", "model": "create:block/brown_nixie_tube",
"x": 180, "x": 180,
"y": 270 "y": 270

View file

@ -1,35 +1,145 @@
{ {
"variants": { "variants": {
"ceiling=false,facing=north": { "double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/cyan_nixie_tube", "model": "create:block/cyan_nixie_tube",
"y": 180 "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", "model": "create:block/cyan_nixie_tube",
"x": 180, "x": 180,
"y": 180 "y": 180
}, },
"ceiling=false,facing=south": { "double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/cyan_nixie_tube" "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", "model": "create:block/cyan_nixie_tube",
"x": 180 "x": 180
}, },
"ceiling=false,facing=west": { "double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/cyan_nixie_tube", "model": "create:block/cyan_nixie_tube",
"y": 90 "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", "model": "create:block/cyan_nixie_tube",
"x": 180, "x": 180,
"y": 90 "y": 90
}, },
"ceiling=false,facing=east": { "double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/cyan_nixie_tube", "model": "create:block/cyan_nixie_tube",
"y": 270 "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", "model": "create:block/cyan_nixie_tube",
"x": 180, "x": 180,
"y": 270 "y": 270

View file

@ -1,35 +1,145 @@
{ {
"variants": { "variants": {
"ceiling=false,facing=north": { "double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/gray_nixie_tube", "model": "create:block/gray_nixie_tube",
"y": 180 "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", "model": "create:block/gray_nixie_tube",
"x": 180, "x": 180,
"y": 180 "y": 180
}, },
"ceiling=false,facing=south": { "double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/gray_nixie_tube" "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", "model": "create:block/gray_nixie_tube",
"x": 180 "x": 180
}, },
"ceiling=false,facing=west": { "double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/gray_nixie_tube", "model": "create:block/gray_nixie_tube",
"y": 90 "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", "model": "create:block/gray_nixie_tube",
"x": 180, "x": 180,
"y": 90 "y": 90
}, },
"ceiling=false,facing=east": { "double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/gray_nixie_tube", "model": "create:block/gray_nixie_tube",
"y": 270 "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", "model": "create:block/gray_nixie_tube",
"x": 180, "x": 180,
"y": 270 "y": 270

View file

@ -1,35 +1,145 @@
{ {
"variants": { "variants": {
"ceiling=false,facing=north": { "double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/green_nixie_tube", "model": "create:block/green_nixie_tube",
"y": 180 "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", "model": "create:block/green_nixie_tube",
"x": 180, "x": 180,
"y": 180 "y": 180
}, },
"ceiling=false,facing=south": { "double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/green_nixie_tube" "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", "model": "create:block/green_nixie_tube",
"x": 180 "x": 180
}, },
"ceiling=false,facing=west": { "double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/green_nixie_tube", "model": "create:block/green_nixie_tube",
"y": 90 "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", "model": "create:block/green_nixie_tube",
"x": 180, "x": 180,
"y": 90 "y": 90
}, },
"ceiling=false,facing=east": { "double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/green_nixie_tube", "model": "create:block/green_nixie_tube",
"y": 270 "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", "model": "create:block/green_nixie_tube",
"x": 180, "x": 180,
"y": 270 "y": 270

View file

@ -1,35 +1,145 @@
{ {
"variants": { "variants": {
"ceiling=false,facing=north": { "double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/light_blue_nixie_tube", "model": "create:block/light_blue_nixie_tube",
"y": 180 "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", "model": "create:block/light_blue_nixie_tube",
"x": 180, "x": 180,
"y": 180 "y": 180
}, },
"ceiling=false,facing=south": { "double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/light_blue_nixie_tube" "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", "model": "create:block/light_blue_nixie_tube",
"x": 180 "x": 180
}, },
"ceiling=false,facing=west": { "double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/light_blue_nixie_tube", "model": "create:block/light_blue_nixie_tube",
"y": 90 "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", "model": "create:block/light_blue_nixie_tube",
"x": 180, "x": 180,
"y": 90 "y": 90
}, },
"ceiling=false,facing=east": { "double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/light_blue_nixie_tube", "model": "create:block/light_blue_nixie_tube",
"y": 270 "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", "model": "create:block/light_blue_nixie_tube",
"x": 180, "x": 180,
"y": 270 "y": 270

View file

@ -1,35 +1,145 @@
{ {
"variants": { "variants": {
"ceiling=false,facing=north": { "double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/light_gray_nixie_tube", "model": "create:block/light_gray_nixie_tube",
"y": 180 "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", "model": "create:block/light_gray_nixie_tube",
"x": 180, "x": 180,
"y": 180 "y": 180
}, },
"ceiling=false,facing=south": { "double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/light_gray_nixie_tube" "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", "model": "create:block/light_gray_nixie_tube",
"x": 180 "x": 180
}, },
"ceiling=false,facing=west": { "double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/light_gray_nixie_tube", "model": "create:block/light_gray_nixie_tube",
"y": 90 "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", "model": "create:block/light_gray_nixie_tube",
"x": 180, "x": 180,
"y": 90 "y": 90
}, },
"ceiling=false,facing=east": { "double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/light_gray_nixie_tube", "model": "create:block/light_gray_nixie_tube",
"y": 270 "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", "model": "create:block/light_gray_nixie_tube",
"x": 180, "x": 180,
"y": 270 "y": 270

View file

@ -1,35 +1,145 @@
{ {
"variants": { "variants": {
"ceiling=false,facing=north": { "double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/lime_nixie_tube", "model": "create:block/lime_nixie_tube",
"y": 180 "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", "model": "create:block/lime_nixie_tube",
"x": 180, "x": 180,
"y": 180 "y": 180
}, },
"ceiling=false,facing=south": { "double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/lime_nixie_tube" "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", "model": "create:block/lime_nixie_tube",
"x": 180 "x": 180
}, },
"ceiling=false,facing=west": { "double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/lime_nixie_tube", "model": "create:block/lime_nixie_tube",
"y": 90 "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", "model": "create:block/lime_nixie_tube",
"x": 180, "x": 180,
"y": 90 "y": 90
}, },
"ceiling=false,facing=east": { "double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/lime_nixie_tube", "model": "create:block/lime_nixie_tube",
"y": 270 "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", "model": "create:block/lime_nixie_tube",
"x": 180, "x": 180,
"y": 270 "y": 270

View file

@ -1,35 +1,145 @@
{ {
"variants": { "variants": {
"ceiling=false,facing=north": { "double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/magenta_nixie_tube", "model": "create:block/magenta_nixie_tube",
"y": 180 "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", "model": "create:block/magenta_nixie_tube",
"x": 180, "x": 180,
"y": 180 "y": 180
}, },
"ceiling=false,facing=south": { "double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/magenta_nixie_tube" "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", "model": "create:block/magenta_nixie_tube",
"x": 180 "x": 180
}, },
"ceiling=false,facing=west": { "double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/magenta_nixie_tube", "model": "create:block/magenta_nixie_tube",
"y": 90 "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", "model": "create:block/magenta_nixie_tube",
"x": 180, "x": 180,
"y": 90 "y": 90
}, },
"ceiling=false,facing=east": { "double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/magenta_nixie_tube", "model": "create:block/magenta_nixie_tube",
"y": 270 "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", "model": "create:block/magenta_nixie_tube",
"x": 180, "x": 180,
"y": 270 "y": 270

View file

@ -1,35 +1,145 @@
{ {
"variants": { "variants": {
"ceiling=false,facing=north": { "double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/nixie_tube", "model": "create:block/nixie_tube",
"y": 180 "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", "model": "create:block/nixie_tube",
"x": 180, "x": 180,
"y": 180 "y": 180
}, },
"ceiling=false,facing=south": { "double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/nixie_tube" "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", "model": "create:block/nixie_tube",
"x": 180 "x": 180
}, },
"ceiling=false,facing=west": { "double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/nixie_tube", "model": "create:block/nixie_tube",
"y": 90 "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", "model": "create:block/nixie_tube",
"x": 180, "x": 180,
"y": 90 "y": 90
}, },
"ceiling=false,facing=east": { "double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/nixie_tube", "model": "create:block/nixie_tube",
"y": 270 "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", "model": "create:block/nixie_tube",
"x": 180, "x": 180,
"y": 270 "y": 270

View file

@ -1,35 +1,145 @@
{ {
"variants": { "variants": {
"ceiling=false,facing=north": { "double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/pink_nixie_tube", "model": "create:block/pink_nixie_tube",
"y": 180 "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", "model": "create:block/pink_nixie_tube",
"x": 180, "x": 180,
"y": 180 "y": 180
}, },
"ceiling=false,facing=south": { "double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/pink_nixie_tube" "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", "model": "create:block/pink_nixie_tube",
"x": 180 "x": 180
}, },
"ceiling=false,facing=west": { "double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/pink_nixie_tube", "model": "create:block/pink_nixie_tube",
"y": 90 "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", "model": "create:block/pink_nixie_tube",
"x": 180, "x": 180,
"y": 90 "y": 90
}, },
"ceiling=false,facing=east": { "double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/pink_nixie_tube", "model": "create:block/pink_nixie_tube",
"y": 270 "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", "model": "create:block/pink_nixie_tube",
"x": 180, "x": 180,
"y": 270 "y": 270

View file

@ -1,35 +1,145 @@
{ {
"variants": { "variants": {
"ceiling=false,facing=north": { "double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/purple_nixie_tube", "model": "create:block/purple_nixie_tube",
"y": 180 "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", "model": "create:block/purple_nixie_tube",
"x": 180, "x": 180,
"y": 180 "y": 180
}, },
"ceiling=false,facing=south": { "double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/purple_nixie_tube" "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", "model": "create:block/purple_nixie_tube",
"x": 180 "x": 180
}, },
"ceiling=false,facing=west": { "double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/purple_nixie_tube", "model": "create:block/purple_nixie_tube",
"y": 90 "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", "model": "create:block/purple_nixie_tube",
"x": 180, "x": 180,
"y": 90 "y": 90
}, },
"ceiling=false,facing=east": { "double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/purple_nixie_tube", "model": "create:block/purple_nixie_tube",
"y": 270 "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", "model": "create:block/purple_nixie_tube",
"x": 180, "x": 180,
"y": 270 "y": 270

View file

@ -1,35 +1,145 @@
{ {
"variants": { "variants": {
"ceiling=false,facing=north": { "double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/red_nixie_tube", "model": "create:block/red_nixie_tube",
"y": 180 "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", "model": "create:block/red_nixie_tube",
"x": 180, "x": 180,
"y": 180 "y": 180
}, },
"ceiling=false,facing=south": { "double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/red_nixie_tube" "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", "model": "create:block/red_nixie_tube",
"x": 180 "x": 180
}, },
"ceiling=false,facing=west": { "double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/red_nixie_tube", "model": "create:block/red_nixie_tube",
"y": 90 "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", "model": "create:block/red_nixie_tube",
"x": 180, "x": 180,
"y": 90 "y": 90
}, },
"ceiling=false,facing=east": { "double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/red_nixie_tube", "model": "create:block/red_nixie_tube",
"y": 270 "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", "model": "create:block/red_nixie_tube",
"x": 180, "x": 180,
"y": 270 "y": 270

View file

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

View file

@ -1,35 +1,145 @@
{ {
"variants": { "variants": {
"ceiling=false,facing=north": { "double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/white_nixie_tube", "model": "create:block/white_nixie_tube",
"y": 180 "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", "model": "create:block/white_nixie_tube",
"x": 180, "x": 180,
"y": 180 "y": 180
}, },
"ceiling=false,facing=south": { "double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/white_nixie_tube" "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", "model": "create:block/white_nixie_tube",
"x": 180 "x": 180
}, },
"ceiling=false,facing=west": { "double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/white_nixie_tube", "model": "create:block/white_nixie_tube",
"y": 90 "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", "model": "create:block/white_nixie_tube",
"x": 180, "x": 180,
"y": 90 "y": 90
}, },
"ceiling=false,facing=east": { "double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/white_nixie_tube", "model": "create:block/white_nixie_tube",
"y": 270 "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", "model": "create:block/white_nixie_tube",
"x": 180, "x": 180,
"y": 270 "y": 270

View file

@ -1,35 +1,145 @@
{ {
"variants": { "variants": {
"ceiling=false,facing=north": { "double_face=floor,facing=north,waterlogged=false": {
"model": "create:block/yellow_nixie_tube", "model": "create:block/yellow_nixie_tube",
"y": 180 "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", "model": "create:block/yellow_nixie_tube",
"x": 180, "x": 180,
"y": 180 "y": 180
}, },
"ceiling=false,facing=south": { "double_face=floor,facing=south,waterlogged=false": {
"model": "create:block/yellow_nixie_tube" "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", "model": "create:block/yellow_nixie_tube",
"x": 180 "x": 180
}, },
"ceiling=false,facing=west": { "double_face=floor,facing=west,waterlogged=false": {
"model": "create:block/yellow_nixie_tube", "model": "create:block/yellow_nixie_tube",
"y": 90 "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", "model": "create:block/yellow_nixie_tube",
"x": 180, "x": 180,
"y": 90 "y": 90
}, },
"ceiling=false,facing=east": { "double_face=floor,facing=east,waterlogged=false": {
"model": "create:block/yellow_nixie_tube", "model": "create:block/yellow_nixie_tube",
"y": 270 "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", "model": "create:block/yellow_nixie_tube",
"x": 180, "x": 180,
"y": 270 "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": "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.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": "\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.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.tuff_pillar": "\u0279\u0250\u05DF\u05DF\u0131\u0500 \u025F\u025Fn\u27D8",
"block.create.turntable": "\u01DD\u05DFq\u0250\u0287u\u0279n\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": "Tiled Glass",
"block.create.tiled_glass_pane": "Tiled Glass Pane", "block.create.tiled_glass_pane": "Tiled Glass Pane",
"block.create.track": "Train Track", "block.create.track": "Train Track",
"block.create.track_signal": "Train Signal",
"block.create.track_station": "Train Station", "block.create.track_station": "Train Station",
"block.create.tuff_pillar": "Tuff Pillar", "block.create.tuff_pillar": "Tuff Pillar",
"block.create.turntable": "Turntable", "block.create.turntable": "Turntable",

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -118,10 +118,10 @@ public class AllBlockPartials {
GIRDER_SEGMENT_MIDDLE = block("metal_girder/segment_middle"), GIRDER_SEGMENT_MIDDLE = block("metal_girder/segment_middle"),
GIRDER_SEGMENT_BOTTOM = block("metal_girder/segment_bottom"), GIRDER_SEGMENT_BOTTOM = block("metal_girder/segment_bottom"),
TRACK_STATION_OVERLAY = block("track/station_overlay"), TRACK_STATION_OVERLAY = block("track_overlay/station"),
TRACK_STATION_OVERLAY_DIAGONAL = block("track/station_overlay_diagonal"), TRACK_SIGNAL_OVERLAY = block("track_overlay/signal"),
TRACK_STATION_OVERLAY_ASCENDING = block("track/station_overlay_ascending"), TRACK_ASSEMBLING_OVERLAY = block("track_overlay/assembling"),
TRACK_ASSEMBLY_OVERLAY = block("track/assembly_overlay"), TRACK_SIGNAL_DUAL_OVERLAY = block("track_overlay/signal_dual"),
BOGEY_FRAME = block("track/bogey/bogey_frame"), BOGEY_FRAME = block("track/bogey/bogey_frame"),
SMALL_BOGEY_WHEELS = block("track/bogey/bogey_wheel"), SMALL_BOGEY_WHEELS = block("track/bogey/bogey_wheel"),
@ -136,6 +136,17 @@ public class AllBlockPartials {
TRAIN_CONTROLS_COVER = block("controls/train/cover"), TRAIN_CONTROLS_COVER = block("controls/train/cover"),
TRAIN_CONTROLS_LEVER = block("controls/train/lever"), 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_1x1 = entity("crafting_blueprint_small"),
CRAFTING_BLUEPRINT_2x2 = entity("crafting_blueprint_medium"), CRAFTING_BLUEPRINT_2x2 = entity("crafting_blueprint_medium"),
CRAFTING_BLUEPRINT_3x3 = entity("crafting_blueprint_large"), CRAFTING_BLUEPRINT_3x3 = entity("crafting_blueprint_large"),

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.item.LecternControllerBlock;
import com.simibubi.create.content.logistics.trains.management.StationBlock; 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.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.StandardBogeyBlock;
import com.simibubi.create.content.logistics.trains.track.TrackBlock; import com.simibubi.create.content.logistics.trains.track.TrackBlock;
import com.simibubi.create.content.logistics.trains.track.TrackBlockItem; import com.simibubi.create.content.logistics.trains.track.TrackBlockItem;
@ -1311,6 +1312,16 @@ public class AllBlocks {
.transform(customItemModel("_", "block")) .transform(customItemModel("_", "block"))
.register(); .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 = public static final BlockEntry<StandardBogeyBlock> SMALL_BOGEY =
REGISTRATE.block("small_bogey", p -> new StandardBogeyBlock(p, false)) REGISTRATE.block("small_bogey", p -> new StandardBogeyBlock(p, false))
.transform(BuilderTransformers.bogey()) .transform(BuilderTransformers.bogey())

View file

@ -58,12 +58,6 @@ public class AllShapes {
.add(0, 14, 0, 16, 16, 16) .add(0, 14, 0, 16, 16, 16)
.add(3, 3, -2, 13, 13, 2) .add(3, 3, -2, 13, 13, 2)
.forHorizontal(NORTH), .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), 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) BELT_FUNNEL_RETRACTED = shape(2, -2, 14, 14, 14, 18).add(0, -5, 8, 16, 16, 14)
.forHorizontal(NORTH), .forHorizontal(NORTH),
@ -127,7 +121,14 @@ public class AllShapes {
STATION = shape(0, 0, 0, 16, 5, 16).add(2, 4, 0, 14, 16, 4) STATION = shape(0, 0, 0, 16, 5, 16).add(2, 4, 0, 14, 16, 4)
.forHorizontal(NORTH), .forHorizontal(NORTH),
CONTROLS = shape(0, 0, 4, 16, 4, 16).add(0, 0, 6, 16, 14, 16) 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.IBogeyTileEntityRenderer;
import com.simibubi.create.content.logistics.trains.management.StationRenderer; 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.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.StandardBogeyTileEntity;
import com.simibubi.create.content.logistics.trains.track.TrackInstance; import com.simibubi.create.content.logistics.trains.track.TrackInstance;
import com.simibubi.create.content.logistics.trains.track.TrackRenderer; import com.simibubi.create.content.logistics.trains.track.TrackRenderer;
@ -749,5 +751,11 @@ public class AllTileEntities {
.validBlocks(AllBlocks.TRACK_STATION) .validBlocks(AllBlocks.TRACK_STATION)
.register(); .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() {} public static void register() {}
} }

View file

@ -14,7 +14,7 @@ public class SeatInteractionBehaviour extends MovingInteractionBehaviour {
@Override @Override
public boolean handlePlayerInteraction(Player player, InteractionHand activeHand, BlockPos localPos, public boolean handlePlayerInteraction(Player player, InteractionHand activeHand, BlockPos localPos,
AbstractContraptionEntity contraptionEntity) { AbstractContraptionEntity contraptionEntity) {
return true; return false;
} }
@Override @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.ByteArrayDataOutput;
import com.google.common.io.ByteStreams; import com.google.common.io.ByteStreams;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllItems;
import com.simibubi.create.AllMovementBehaviours; import com.simibubi.create.AllMovementBehaviours;
import com.simibubi.create.AllSoundEvents; import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.Create; import com.simibubi.create.Create;
@ -191,7 +192,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
InteractionHand interactionHand) { InteractionHand interactionHand) {
int indexOfSeat = contraption.getSeats() int indexOfSeat = contraption.getSeats()
.indexOf(localPos); .indexOf(localPos);
if (indexOfSeat == -1) if (indexOfSeat == -1 || AllItems.WRENCH.isIn(player.getItemInHand(interactionHand)))
return contraption.interactors.containsKey(localPos) && contraption.interactors.get(localPos) return contraption.interactors.containsKey(localPos) && contraption.interactors.get(localPos)
.handlePlayerInteraction(player, interactionHand, localPos, this); .handlePlayerInteraction(player, interactionHand, localPos, this);
if (player.isPassenger()) if (player.isPassenger())

View file

@ -1,5 +1,6 @@
package com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls; 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.AbstractContraptionEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.MovingInteractionBehaviour; import com.simibubi.create.content.contraptions.components.structureMovement.MovingInteractionBehaviour;
@ -12,6 +13,8 @@ public class ControlsInteractionBehaviour extends MovingInteractionBehaviour {
@Override @Override
public boolean handlePlayerInteraction(Player player, InteractionHand activeHand, BlockPos localPos, public boolean handlePlayerInteraction(Player player, InteractionHand activeHand, BlockPos localPos,
AbstractContraptionEntity contraptionEntity) { AbstractContraptionEntity contraptionEntity) {
if (AllItems.WRENCH.isIn(player.getItemInHand(activeHand)))
return false;
if (player.level.isClientSide) if (player.level.isClientSide)
ControlsHandler.controllerClicked(contraptionEntity, localPos, player); ControlsHandler.controllerClicked(contraptionEntity, localPos, player);
return true; 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.relays.elementary.BracketedTileEntityBehaviour;
import com.simibubi.create.content.contraptions.wrench.IWrenchable; import com.simibubi.create.content.contraptions.wrench.IWrenchable;
import com.simibubi.create.content.logistics.block.chute.AbstractChuteBlock; 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.TrackBlock;
import com.simibubi.create.content.logistics.trains.track.TrackShape; import com.simibubi.create.content.logistics.trains.track.TrackShape;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
@ -159,6 +160,8 @@ public class GirderBlock extends Block implements SimpleWaterloggedBlock, IWrenc
state = state.setValue(updateProperty, true); state = state.setValue(updateProperty, true);
if (sideState.getBlock() == state.getBlock() && sideState.getValue(updateProperty)) if (sideState.getBlock() == state.getBlock() && sideState.getValue(updateProperty))
state = state.setValue(updateProperty, true); 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)) { for (Direction d2 : Iterate.directionsInAxis(axis == Axis.X ? Axis.Z : Axis.X)) {
BlockState above = level.getBlockState(pos.above() 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) { Property<Boolean> updateProperty, BlockState sideState, Direction d) {
if (sideState.getBlock() == state.getBlock() && sideState.getValue(X) == sideState.getValue(Z)) if (sideState.getBlock() == state.getBlock() && sideState.getValue(X) == sideState.getValue(Z))
state = state.setValue(updateProperty, true); 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)) else if (sideState.hasProperty(WallBlock.UP) && sideState.getValue(WallBlock.UP))
state = state.setValue(updateProperty, true); state = state.setValue(updateProperty, true);
else if (sideState.getBlock() instanceof NixieTubeBlock && NixieTubeBlock.getFacing(sideState) == d)
state = state.setValue(updateProperty, true);
else if (sideState.hasBlockEntity()) { else if (sideState.hasBlockEntity()) {
BlockEntity blockEntity = level.getBlockEntity(pos.relative(d)); BlockEntity blockEntity = level.getBlockEntity(pos.relative(d));
if (!(blockEntity instanceof SmartTileEntity ste)) if (!(blockEntity instanceof SmartTileEntity ste))
@ -219,6 +227,8 @@ public class GirderBlock extends Block implements SimpleWaterloggedBlock, IWrenc
BlockState blockState = world.getBlockState(relative); BlockState blockState = world.getBlockState(relative);
if (blockState.isAir()) if (blockState.isAir())
return false; return false;
if (blockState.getBlock() instanceof NixieTubeBlock && NixieTubeBlock.getFacing(blockState) == side)
return true;
VoxelShape shape = blockState.getShape(world, relative); VoxelShape shape = blockState.getShape(world, relative);
if (shape.isEmpty()) if (shape.isEmpty())
return false; 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; package com.simibubi.create.content.logistics.block.redstone;
import static net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED;
import java.util.Random; import java.util.Random;
import com.simibubi.create.AllBlocks; 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.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level; 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.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.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition.Builder; 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.level.pathfinder.PathComputationType;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult; 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.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.VoxelShape;
public class NixieTubeBlock extends HorizontalDirectionalBlock public class NixieTubeBlock extends DoubleFaceAttachedBlock
implements ITE<NixieTubeTileEntity>, IWrenchable, ISpecialBlockItemRequirement { implements ITE<NixieTubeTileEntity>, IWrenchable, SimpleWaterloggedBlock, ISpecialBlockItemRequirement {
public static final BooleanProperty CEILING = BooleanProperty.create("ceiling");
protected final DyeColor color; protected final DyeColor color;
public NixieTubeBlock(Properties properties, DyeColor color) { public NixieTubeBlock(Properties properties, DyeColor color) {
super(properties); super(properties);
this.color = color; this.color = color;
registerDefaultState(defaultBlockState().setValue(CEILING, false)); registerDefaultState(defaultBlockState().setValue(FACE, DoubleAttachFace.FLOOR));
} }
@Override @Override
@ -78,7 +79,13 @@ public class NixieTubeBlock extends HorizontalDirectionalBlock
return InteractionResult.PASS; return InteractionResult.PASS;
Direction left = state.getValue(FACING) 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(); Direction right = left.getOpposite();
if (world.isClientSide) if (world.isClientSide)
@ -114,7 +121,7 @@ public class NixieTubeBlock extends HorizontalDirectionalBlock
@Override @Override
protected void createBlockStateDefinition(Builder<Block, BlockState> builder) { protected void createBlockStateDefinition(Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder.add(CEILING, FACING)); super.createBlockStateDefinition(builder.add(FACE, FACING, WATERLOGGED));
} }
@Override @Override
@ -136,11 +143,18 @@ public class NixieTubeBlock extends HorizontalDirectionalBlock
} }
@Override @Override
public VoxelShape getShape(BlockState state, BlockGetter p_220053_2_, BlockPos p_220053_3_, public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) {
CollisionContext p_220053_4_) { Direction facing = pState.getValue(FACING);
return (state.getValue(CEILING) ? AllShapes.NIXIE_TUBE_CEILING : AllShapes.NIXIE_TUBE) switch (pState.getValue(FACE)) {
.get(state.getValue(FACING) case CEILING:
return AllShapes.NIXIE_TUBE_CEILING.get(facing.getClockWise()
.getAxis()); .getAxis());
case FLOOR:
return AllShapes.NIXIE_TUBE.get(facing.getClockWise()
.getAxis());
default:
return AllShapes.NIXIE_TUBE_WALL.get(facing);
}
} }
@Override @Override
@ -152,16 +166,30 @@ public class NixieTubeBlock extends HorizontalDirectionalBlock
return super.getCloneItemStack(state, target, world, pos, player); 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 @Override
public BlockState getStateForPlacement(BlockPlaceContext context) { public BlockState getStateForPlacement(BlockPlaceContext context) {
BlockPos pos = context.getClickedPos(); BlockState state = super.getStateForPlacement(context);
boolean ceiling = context.getClickedFace() == Direction.DOWN; if (state == null)
Vec3 hitVec = context.getClickLocation(); return null;
if (hitVec != null) if (state.getValue(FACE) != DoubleAttachFace.WALL && state.getValue(FACE) != DoubleAttachFace.WALL_REVERSED)
ceiling = hitVec.y - pos.getY() > .5f; state = state.setValue(FACING, state.getValue(FACING)
return defaultBlockState().setValue(FACING, context.getHorizontalDirection() .getClockWise());
.getOpposite()) return state.setValue(WATERLOGGED, Boolean.valueOf(context.getLevel()
.setValue(CEILING, ceiling); .getFluidState(context.getClickedPos())
.getType() == Fluids.WATER));
} }
@Override @Override
@ -246,7 +274,8 @@ public class NixieTubeBlock extends HorizontalDirectionalBlock
return (color == DyeColor.ORANGE ? AllBlocks.ORANGE_NIXIE_TUBE : AllBlocks.NIXIE_TUBES.get(color)) return (color == DyeColor.ORANGE ? AllBlocks.ORANGE_NIXIE_TUBE : AllBlocks.NIXIE_TUBES.get(color))
.getDefaultState() .getDefaultState()
.setValue(FACING, state.getValue(FACING)) .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) { public static DyeColor colorOf(BlockState blockState) {
@ -254,4 +283,8 @@ public class NixieTubeBlock extends HorizontalDirectionalBlock
: DyeColor.ORANGE; : 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; 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.simibubi.create.foundation.data.SpecialBlockStateGen;
import com.tterrag.registrate.providers.DataGenContext; import com.tterrag.registrate.providers.DataGenContext;
import com.tterrag.registrate.providers.RegistrateBlockstateProvider; import com.tterrag.registrate.providers.RegistrateBlockstateProvider;
@ -12,12 +13,15 @@ public class NixieTubeGenerator extends SpecialBlockStateGen {
@Override @Override
protected int getXRotation(BlockState state) { protected int getXRotation(BlockState state) {
return state.getValue(NixieTubeBlock.CEILING) ? 180 : 0; return state.getValue(NixieTubeBlock.FACE)
.xRot();
} }
@Override @Override
protected int getYRotation(BlockState state) { 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 @Override

View file

@ -6,10 +6,16 @@ import java.util.Random;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.jozufozu.flywheel.util.transform.TransformStack; import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack; 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.tileEntity.renderer.SafeTileEntityRenderer;
import com.simibubi.create.foundation.utility.AngleHelper; 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.Color;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font; 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.LightTexture;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.MultiBufferSource.BufferSource; import net.minecraft.client.renderer.MultiBufferSource.BufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.core.Direction;
import net.minecraft.network.chat.Style; import net.minecraft.network.chat.Style;
import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.DyeColor;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
public class NixieTubeRenderer extends SafeTileEntityRenderer<NixieTubeTileEntity> { public class NixieTubeRenderer extends SafeTileEntityRenderer<NixieTubeTileEntity> {
@ -58,11 +67,26 @@ public class NixieTubeRenderer extends SafeTileEntityRenderer<NixieTubeTileEntit
int light, int overlay) { int light, int overlay) {
ms.pushPose(); ms.pushPose();
BlockState blockState = te.getBlockState(); BlockState blockState = te.getBlockState();
TransformStack.cast(ms) DoubleAttachFace face = blockState.getValue(NixieTubeBlock.FACE);
.centre() float yRot = AngleHelper.horizontalAngle(blockState.getValue(NixieTubeBlock.FACING)) - 90
.rotateY(AngleHelper.horizontalAngle(blockState.getValue(NixieTubeBlock.FACING))); + (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; float scale = 1 / 20f;
Couple<String> s = te.getDisplayedStrings(); 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; package com.simibubi.create.content.logistics.block.redstone;
import java.lang.ref.WeakReference;
import java.util.List; import java.util.List;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -8,6 +9,8 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import com.mojang.brigadier.exceptions.CommandSyntaxException; 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.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.utility.Couple; 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.CommandSource;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component; 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.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.ItemStack; 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.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec2;
@ -39,10 +44,14 @@ public class NixieTubeTileEntity extends SmartTileEntity {
private Component parsedCustomText; private Component parsedCustomText;
private Couple<String> displayedStrings; private Couple<String> displayedStrings;
private WeakReference<SignalTileEntity> cachedSignalTE;
public SignalState signalState;
public NixieTubeTileEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) { public NixieTubeTileEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state); super(type, pos, state);
hasCustomText = false; hasCustomText = false;
redstoneStrength = 0; redstoneStrength = 0;
cachedSignalTE = new WeakReference<>(null);
} }
@Override @Override
@ -57,6 +66,23 @@ public class NixieTubeTileEntity extends SmartTileEntity {
if (currentStrings == null || !currentStrings.equals(displayedStrings)) if (currentStrings == null || !currentStrings.equals(displayedStrings))
sendData(); 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 @Override
@ -95,6 +121,8 @@ public class NixieTubeTileEntity extends SmartTileEntity {
} }
public void updateDisplayedStrings() { public void updateDisplayedStrings() {
if (signalState != null)
return;
if (!hasCustomText) { if (!hasCustomText) {
displayedStrings = Couple.create(redstoneStrength < 10 ? "0" : "1", String.valueOf(redstoneStrength % 10)); displayedStrings = Couple.create(redstoneStrength < 10 ? "0" : "1", String.valueOf(redstoneStrength % 10));
} else { } else {
@ -195,9 +223,13 @@ public class NixieTubeTileEntity extends SmartTileEntity {
// From SignTileEntity // From SignTileEntity
public CommandSourceStack getCommandSource(@Nullable ServerPlayer p_195539_1_) { public CommandSourceStack getCommandSource(@Nullable ServerPlayer p_195539_1_) {
String s = p_195539_1_ == null ? "Nixie Tube" : p_195539_1_.getName().getString(); String s = p_195539_1_ == null ? "Nixie Tube"
Component itextcomponent = (Component)(p_195539_1_ == null ? new TextComponent("Nixie Tube") : p_195539_1_.getDisplayName()); : p_195539_1_.getName()
return new CommandSourceStack(CommandSource.NULL, Vec3.atCenterOf(this.worldPosition), Vec2.ZERO, (ServerLevel)this.level, 2, s, itextcomponent, this.level.getServer(), p_195539_1_); .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 @Override

View file

@ -7,9 +7,12 @@ import java.util.UUID;
import javax.annotation.Nullable; 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.Carriage;
import com.simibubi.create.content.logistics.trains.entity.Train; 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.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
@ -22,11 +25,11 @@ import net.minecraft.world.level.dimension.DimensionType;
public class GlobalRailwayManager { public class GlobalRailwayManager {
public Map<UUID, TrackGraph> trackNetworks; public Map<UUID, TrackGraph> trackNetworks;
private TrackSavedData trackData; public Map<UUID, SignalEdgeGroup> signalEdgeGroups;
public Map<UUID, Train> trains; public Map<UUID, Train> trains;
public Map<Integer, Carriage> carriageById; public Map<Integer, Carriage> carriageById;
private TrackSavedData trackData;
public TrackGraphSync sync; public TrackGraphSync sync;
// //
@ -57,6 +60,7 @@ public class GlobalRailwayManager {
return; return;
trackData = TrackSavedData.load(server); trackData = TrackSavedData.load(server);
trackNetworks = trackData.getTrackNetworks(); trackNetworks = trackData.getTrackNetworks();
signalEdgeGroups = trackData.getSignalBlocks();
} }
public void levelUnloaded(LevelAccessor level) { public void levelUnloaded(LevelAccessor level) {
@ -68,6 +72,7 @@ public class GlobalRailwayManager {
public void cleanUp() { public void cleanUp() {
trackNetworks = new HashMap<>(); trackNetworks = new HashMap<>();
signalEdgeGroups = new HashMap<>();
trains = new HashMap<>(); trains = new HashMap<>();
carriageById = new HashMap<>(); carriageById = new HashMap<>();
sync = new TrackGraphSync(); sync = new TrackGraphSync();
@ -120,14 +125,28 @@ public class GlobalRailwayManager {
if (!location.equals(location2)) if (!location.equals(location2))
return; 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()) for (Train train : trains.values())
train.tick(level); train.tick(level);
if (AllKeys.isKeyDown(GLFW.GLFW_KEY_H)) {
trackNetworks.values()
.forEach(TrackGraph::debugViewSignalData);
}
} }
public void clientTick() { public void clientTick() {
if (KineticDebugger.isActive()) { if (AllKeys.isKeyDown(GLFW.GLFW_KEY_J)) {
trackNetworks.values() 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.jozufozu.flywheel.core.PartialModel;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation.DiscoveredLocation; 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.TrackBlock;
import com.simibubi.create.content.logistics.trains.track.TrackShape; import com.simibubi.create.content.logistics.trains.track.TrackShape;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
@ -103,8 +104,8 @@ public interface ITrackBlock {
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public PartialModel prepareStationOverlay(BlockGetter world, BlockPos pos, BlockState state, public PartialModel prepareTrackOverlay(BlockGetter world, BlockPos pos, BlockState state,
AxisDirection direction, PoseStack transform); AxisDirection direction, PoseStack transform, RenderedTrackOverlayType type);
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public PartialModel prepareAssemblyOverlay(BlockGetter world, BlockPos pos, BlockState state, Direction direction, public PartialModel prepareAssemblyOverlay(BlockGetter world, BlockPos pos, BlockState state, Direction direction,

View file

@ -1,5 +1,6 @@
package com.simibubi.create.content.logistics.trains; 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 com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
@ -11,15 +12,21 @@ import net.minecraft.world.phys.Vec3;
public class TrackEdge { public class TrackEdge {
BezierConnection turn; BezierConnection turn;
EdgeData edgeData;
public TrackEdge(BezierConnection turn) { public TrackEdge(BezierConnection turn) {
this.turn = turn; this.turn = turn;
this.edgeData = new EdgeData();
} }
public boolean isTurn() { public boolean isTurn() {
return turn != null; return turn != null;
} }
public EdgeData getEdgeData() {
return edgeData;
}
public BezierConnection getTurn() { public BezierConnection getTurn() {
return turn; return turn;
} }
@ -61,11 +68,16 @@ public class TrackEdge {
} }
public CompoundTag write() { 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) { public static TrackEdge read(CompoundTag tag, TrackGraph graph) {
return new TrackEdge(tag.contains("Positions") ? new BezierConnection(tag, BlockPos.ZERO) : null); 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 javax.annotation.Nullable;
import org.lwjgl.glfw.GLFW;
import com.simibubi.create.AllKeys;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.CreateClient; import com.simibubi.create.CreateClient;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation.DiscoveredLocation; 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.entity.Train;
import com.simibubi.create.content.logistics.trains.management.GlobalStation; 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.Color;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.NBTHelper;
import com.simibubi.create.foundation.utility.Pair;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
@ -47,7 +55,8 @@ public class TrackGraph {
Map<Integer, TrackNode> nodesById; Map<Integer, TrackNode> nodesById;
Map<TrackNode, Map<TrackNode, TrackEdge>> connectionsByNode; Map<TrackNode, Map<TrackNode, TrackEdge>> connectionsByNode;
Map<UUID, GlobalStation> stations; private Map<UUID, GlobalStation> stations;
private Map<UUID, SignalBoundary> signals;
public TrackGraph() { public TrackGraph() {
this(UUID.randomUUID()); this(UUID.randomUUID());
@ -60,6 +69,7 @@ public class TrackGraph {
connectionsByNode = new IdentityHashMap<>(); connectionsByNode = new IdentityHashMap<>();
color = Color.rainbowColor(new Random(graphID.getLeastSignificantBits()).nextInt()); color = Color.rainbowColor(new Random(graphID.getLeastSignificantBits()).nextInt());
stations = new HashMap<>(); stations = new HashMap<>();
signals = new HashMap<>();
} }
// //
@ -69,17 +79,41 @@ public class TrackGraph {
return stations.get(id); return stations.get(id);
} }
@Nullable
public SignalBoundary getSignal(UUID id) {
return signals.get(id);
}
public Collection<GlobalStation> getStations() { public Collection<GlobalStation> getStations() {
return stations.values(); 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) { public void removeStation(UUID id) {
stations.remove(id); stations.remove(id);
markDirty(); markDirty();
} }
public void addStation(GlobalStation station) { public void removeSignal(UUID id) {
stations.put(station.id, station); SignalBoundary signal = signals.remove(id);
if (signal == null)
return;
SignalPropagator.onSignalRemoved(this, signal);
markDirty(); markDirty();
} }
@ -104,7 +138,8 @@ public class TrackGraph {
public boolean createNode(DiscoveredLocation location) { public boolean createNode(DiscoveredLocation location) {
if (!createSpecificNode(location, nextNodeId(), location.normal)) if (!createSpecificNode(location, nextNodeId(), location.normal))
return false; return false;
Create.RAILWAYS.sync.nodeAdded(this, nodes.get(location)); TrackNode newNode = nodes.get(location);
Create.RAILWAYS.sync.nodeAdded(this, newNode);
markDirty(); markDirty();
return true; return true;
} }
@ -157,6 +192,10 @@ public class TrackGraph {
return true; return true;
Map<TrackNode, TrackEdge> connections = connectionsByNode.remove(removed); 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()) for (TrackNode railNode : connections.keySet())
if (connectionsByNode.containsKey(railNode)) if (connectionsByNode.containsKey(railNode))
connectionsByNode.get(railNode) connectionsByNode.get(railNode)
@ -352,7 +391,8 @@ public class TrackGraph {
}); });
tag.put("Nodes", nodesList); 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; return tag;
} }
@ -360,6 +400,11 @@ public class TrackGraph {
TrackGraph graph = new TrackGraph(tag.getUUID("Id")); TrackGraph graph = new TrackGraph(tag.getUUID("Id"));
graph.color = new Color(tag.getInt("Color")); 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<>(); Map<Integer, TrackNode> indexTracker = new HashMap<>();
ListTag nodesList = tag.getList("Nodes", Tag.TAG_COMPOUND); ListTag nodesList = tag.getList("Nodes", Tag.TAG_COMPOUND);
@ -384,16 +429,112 @@ public class TrackGraph {
continue; continue;
NBTHelper.iterateCompoundList(nodeTag.getList("Connections", Tag.TAG_COMPOUND), c -> { NBTHelper.iterateCompoundList(nodeTag.getList("Connections", Tag.TAG_COMPOUND), c -> {
TrackNode node2 = indexTracker.get(c.getInt("To")); 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); 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; 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() { public void debugViewNodes() {
Entity cameraEntity = Minecraft.getInstance().cameraEntity; Entity cameraEntity = Minecraft.getInstance().cameraEntity;
if (cameraEntity == null) if (cameraEntity == null)
@ -411,10 +552,10 @@ public class TrackGraph {
Vec3 yOffset = new Vec3(0, 3 / 16f, 0); Vec3 yOffset = new Vec3(0, 3 / 16f, 0);
Vec3 v1 = location.add(yOffset); 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) CreateClient.OUTLINER.showLine(Integer.valueOf(node.netId), v1, v2)
.colored(Color.mixColors(Color.WHITE, color, 1)) .colored(Color.mixColors(Color.WHITE, color, 1))
.lineWidth(1 / 4f); .lineWidth(1 / 8f);
Map<TrackNode, TrackEdge> map = connectionsByNode.get(node); Map<TrackNode, TrackEdge> map = connectionsByNode.get(node);
if (map == null) if (map == null)
@ -424,8 +565,9 @@ public class TrackGraph {
for (Entry<TrackNode, TrackEdge> entry : map.entrySet()) { for (Entry<TrackNode, TrackEdge> entry : map.entrySet()) {
TrackNode other = entry.getKey(); TrackNode other = entry.getKey();
if (other.hashCode() > hashCode) if (other.hashCode() > hashCode && !AllKeys.isKeyDown(GLFW.GLFW_KEY_LEFT_CONTROL))
continue; continue;
yOffset = new Vec3(0, (other.hashCode() > hashCode ? 6 : 4) / 16f, 0);
TrackEdge edge = entry.getValue(); TrackEdge edge = entry.getValue();
if (!edge.isTurn()) { if (!edge.isTurn()) {
@ -443,7 +585,8 @@ public class TrackGraph {
for (int i = 0; i <= turn.getSegmentCount(); i++) { for (int i = 0; i <= turn.getSegmentCount(); i++) {
Vec3 current = edge.getPosition(node, other, i * 1f / turn.getSegmentCount()); Vec3 current = edge.getPosition(node, other, i * 1f / turn.getSegmentCount());
if (previous != null) 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) .colored(color)
.lineWidth(1 / 16f); .lineWidth(1 / 16f);
previous = current; previous = current;

View file

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

View file

@ -9,6 +9,7 @@ import java.util.Set;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation.DiscoveredLocation; 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.core.BlockPos;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
@ -171,8 +172,11 @@ public class TrackPropagator {
} }
frontier.clear(); frontier.clear();
if (graph.createNode(startNode)) Set<TrackNode> addedNodes = new HashSet<>();
sync.nodeAdded(graph, graph.locateNode(startNode)); if (graph.createNode(startNode)) {
TrackNode node = graph.locateNode(startNode);
sync.nodeAdded(graph, node);
}
frontier.add(new FrontierEntry(startNode, null, startNode)); frontier.add(new FrontierEntry(startNode, null, startNode));
@ -192,9 +196,12 @@ public class TrackPropagator {
if (isValidGraphNodeLocation(entry.currentNode, ends, first) && entry.currentNode != startNode) { if (isValidGraphNodeLocation(entry.currentNode, ends, first) && entry.currentNode != startNode) {
boolean nodeIsNew = graph.createNode(entry.currentNode); boolean nodeIsNew = graph.createNode(entry.currentNode);
if (nodeIsNew) if (nodeIsNew) {
sync.nodeAdded(graph, graph.locateNode(entry.currentNode)); TrackNode node = graph.locateNode(entry.currentNode);
sync.nodeAdded(graph, node);
}
graph.connectNodes(parentNode, entry.currentNode, new TrackEdge(entry.currentNode.getTurn())); graph.connectNodes(parentNode, entry.currentNode, new TrackEdge(entry.currentNode.getTurn()));
addedNodes.add(graph.locateNode(entry.currentNode));
parentNode = entry.currentNode; parentNode = entry.currentNode;
if (!nodeIsNew) if (!nodeIsNew)
continue; continue;
@ -204,6 +211,8 @@ public class TrackPropagator {
} }
manager.markTracksDirty(); manager.markTracksDirty();
for (TrackNode trackNode : addedNodes)
SignalPropagator.notifySignalsOfNewNode(graph, trackNode);
return graph; return graph;
} }

View file

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

View file

@ -11,6 +11,7 @@ import org.apache.commons.lang3.mutable.MutableDouble;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.IBogeyBlock; import com.simibubi.create.content.logistics.trains.IBogeyBlock;
import com.simibubi.create.content.logistics.trains.TrackGraph; 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.content.logistics.trains.entity.TravellingPoint.ITrackSelector;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
@ -41,6 +42,8 @@ public class Carriage {
WeakReference<CarriageContraptionEntity> entity; WeakReference<CarriageContraptionEntity> entity;
Couple<CarriageBogey> bogeys; Couple<CarriageBogey> bogeys;
static final int FIRST = 0, MIDDLE = 1, LAST = 2, BOTH = 3;
public Carriage(CarriageBogey bogey1, @Nullable CarriageBogey bogey2, int bogeySpacing) { public Carriage(CarriageBogey bogey1, @Nullable CarriageBogey bogey2, int bogeySpacing) {
this.bogeySpacing = bogeySpacing; this.bogeySpacing = bogeySpacing;
this.bogeys = Couple.create(bogey1, bogey2); this.bogeys = Couple.create(bogey1, bogey2);
@ -63,7 +66,7 @@ public class Carriage {
public double travel(Level level, TrackGraph graph, double distance, public double travel(Level level, TrackGraph graph, double distance,
Function<TravellingPoint, ITrackSelector> forwardControl, Function<TravellingPoint, ITrackSelector> forwardControl,
Function<TravellingPoint, ITrackSelector> backwardControl) { Function<TravellingPoint, ITrackSelector> backwardControl, int type) {
Vec3 leadingAnchor = leadingBogey().anchorPosition; Vec3 leadingAnchor = leadingBogey().anchorPosition;
Vec3 trailingAnchor = trailingBogey().anchorPosition; Vec3 trailingAnchor = trailingBogey().anchorPosition;
boolean onTwoBogeys = isOnTwoBogeys(); boolean onTwoBogeys = isOnTwoBogeys();
@ -98,9 +101,18 @@ public class Carriage {
ITrackSelector backTrackSelector = ITrackSelector backTrackSelector =
nextPoint == null ? backwardControl.apply(point) : point.follow(nextPoint); nextPoint == null ? backwardControl.apply(point) : point.follow(nextPoint);
double moved = point.travel(graph, toMove, toMove > 0 ? frontTrackSelector : backTrackSelector); boolean atFront = (type == FIRST || type == BOTH) && actuallyFirstWheel && actuallyFirstBogey;
double stressCorrection = correction + bogeyCorrection; boolean atBack =
point.travel(graph, stressCorrection, stressCorrection > 0 ? frontTrackSelector : backTrackSelector); (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; blocked |= point.blocked;
distanceMoved.setValue(moved); 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.contraptions.components.structureMovement.interaction.controls.ControlsBlock;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.SteerDirection; 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.GlobalStation;
import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.utility.Color; import com.simibubi.create.foundation.utility.Color;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
@ -197,7 +198,8 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
carriage.train.manualSteer = carriage.train.manualSteer =
targetSteer < 0 ? SteerDirection.RIGHT : targetSteer > 0 ? SteerDirection.LEFT : SteerDirection.NONE; 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) if (slow)
carriage.train.targetSpeed /= 8; carriage.train.targetSpeed /= 8;
boolean counteringAcceleration = Math.abs(Math.signum(targetSpeed) - Math.signum(carriage.train.speed)) > 1.5f; 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.Map.Entry;
import java.util.PriorityQueue; import java.util.PriorityQueue;
import java.util.Set; import java.util.Set;
import java.util.UUID;
import java.util.function.BiPredicate; import java.util.function.BiPredicate;
import org.apache.commons.lang3.mutable.MutableObject; 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.TrackEdge;
import com.simibubi.create.content.logistics.trains.TrackGraph; import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackNode; import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation; 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.entity.TravellingPoint.ITrackSelector;
import com.simibubi.create.content.logistics.trains.management.GlobalStation; 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.Couple;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.Pair;
@ -33,9 +39,14 @@ public class Navigation {
public boolean destinationBehindTrain; public boolean destinationBehindTrain;
List<TrackEdge> currentPath; 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; this.train = train;
currentPath = new ArrayList<>(); currentPath = new ArrayList<>();
signalScout = new TravellingPoint();
} }
public void tick(Level level) { public void tick(Level level) {
@ -65,36 +76,105 @@ public class Navigation {
destination.reserveFor(train); destination.reserveFor(train);
if (distanceToDestination < 1 / 32f) { double acceleration = AllConfigs.SERVER.trains.getAccelerationMPTT();
distanceToDestination = 0; 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; train.speed = 0;
if (waitingForSignal != null) {
distanceToSignal = 0;
return;
}
distanceToDestination = 0;
currentPath.clear(); currentPath.clear();
train.arriveAt(destination); train.arriveAt(destination);
destination = null; destination = null;
return; return;
} }
float speedMod = destinationBehindTrain ? -1 : 1;
train.currentlyBackwards = destinationBehindTrain; train.currentlyBackwards = destinationBehindTrain;
if (distanceToDestination - Math.abs(train.speed) < 1 / 32f) { if (targetDistance - Math.abs(train.speed) < 1 / 32f) {
train.speed = distanceToDestination * speedMod; train.speed = targetDistance * speedMod;
return; return;
} }
if (distanceToDestination < 10) { double topSpeed = AllConfigs.SERVER.trains.getTopSpeedMPT();
double target = Train.topSpeed * ((distanceToDestination) / 10); if (targetDistance < 10) {
double target = topSpeed * ((targetDistance) / 10);
if (target < Math.abs(train.speed)) { if (target < Math.abs(train.speed)) {
train.speed += (target - Math.abs(train.speed)) * .5f * speedMod; train.speed += (target - Math.abs(train.speed)) * .5f * speedMod;
return; return;
} }
} }
double brakingDistance = (train.speed * train.speed) / (2 * Train.acceleration); train.targetSpeed = targetDistance > brakingDistance ? topSpeed * speedMod : 0;
train.targetSpeed = distanceToDestination > brakingDistance ? Train.topSpeed * speedMod : 0;
train.approachTargetSpeed(1); 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() { public boolean isActive() {
return destination != null; return destination != null;
} }
@ -103,20 +183,40 @@ public class Navigation {
if (destination == null) if (destination == null)
return mp.steer(train.manualSteer, new Vec3(0, 1, 0)); return mp.steer(train.manualSteer, new Vec3(0, 1, 0));
return (graph, pair) -> { return (graph, pair) -> {
if (!currentPath.isEmpty()) { List<Entry<TrackNode, TrackEdge>> options = pair.getSecond();
if (currentPath.isEmpty())
return options.get(0);
TrackEdge target = currentPath.get(0); TrackEdge target = currentPath.get(0);
for (Entry<TrackNode, TrackEdge> entry : pair.getSecond()) { for (Entry<TrackNode, TrackEdge> entry : options) {
if (entry.getValue() == target) { if (entry.getValue() != target)
continue;
currentPath.remove(0); currentPath.remove(0);
return entry; return entry;
} }
} return options.get(0);
}
return pair.getSecond()
.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() { public void cancelNavigation() {
distanceToDestination = 0; distanceToDestination = 0;
currentPath.clear(); currentPath.clear();
@ -137,7 +237,6 @@ public class Navigation {
distanceToDestination = distance; distanceToDestination = distance;
currentPath = pathTo.getSecond(); currentPath = pathTo.getSecond();
destinationBehindTrain = pathTo.getFirst() < 0;
if (noneFound) { if (noneFound) {
distanceToDestination = 0; distanceToDestination = 0;
@ -146,6 +245,8 @@ public class Navigation {
return -1; return -1;
} }
destinationBehindTrain = pathTo.getFirst() < 0;
if (this.destination == destination) if (this.destination == destination)
return 0; return 0;
@ -171,7 +272,20 @@ public class Navigation {
train.status.foundConductor(); train.status.foundConductor();
} }
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(); train.leaveStation();
}
this.destination = destination; this.destination = destination;
return distanceToDestination; return distanceToDestination;
} }
@ -265,8 +379,9 @@ public class Navigation {
return null; return null;
MutableObject<GlobalStation> result = new MutableObject<>(null); MutableObject<GlobalStation> result = new MutableObject<>(null);
double minDistance = .75f * (train.speed * train.speed) / (2 * Train.acceleration); double acceleration = AllConfigs.SERVER.trains.getAccelerationMPTT();
double maxDistance = Math.max(32, 1.5f * (train.speed * train.speed) / (2 * Train.acceleration)); 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) -> { search(maxDistance, forward, (reachedVia, poll) -> {
double distance = poll.getFirst(); double distance = poll.getFirst();
@ -280,7 +395,8 @@ public class Navigation {
TrackNode node2 = currentEntry.getFirst() TrackNode node2 = currentEntry.getFirst()
.getSecond(); .getSecond();
for (GlobalStation globalStation : graph.getStations()) { for (GlobalStation globalStation : edge.getEdgeData()
.getStations()) {
Couple<TrackNodeLocation> target = globalStation.edgeLocation; Couple<TrackNodeLocation> target = globalStation.edgeLocation;
TrackNodeLocation loc1 = node1.getLocation(); TrackNodeLocation loc1 = node1.getLocation();
TrackNodeLocation loc2 = node2.getLocation(); TrackNodeLocation loc2 = node2.getLocation();
@ -340,16 +456,23 @@ public class Navigation {
return; return;
List<Entry<TrackNode, TrackEdge>> validTargets = new ArrayList<>(); 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()) { .entrySet()) {
TrackNode newNode = entry.getKey(); TrackNode newNode = entry.getKey();
TrackEdge newEdge = entry.getValue(); TrackEdge newEdge = entry.getValue();
Vec3 currentDirection = edge.getDirection(node1, node2, false); Vec3 currentDirection = edge.getDirection(node1, node2, false);
Vec3 newDirection = newEdge.getDirection(node2, newNode, true); Vec3 newDirection = newEdge.getDirection(node2, newNode, true);
if (currentDirection.dot(newDirection) < 0) if (currentDirection.dot(newDirection) < 3 / 4f)
continue; continue;
if (!visited.add(entry.getValue())) if (!visited.add(entry.getValue()))
continue; continue;
EdgeData signalData = newEdge.getEdgeData();
if (signalData.hasBoundaries())
for (SignalBoundary boundary : signalData.getBoundaries())
if (!boundary.canNavigateVia(node2))
continue EdgeWalk;
validTargets.add(entry); validTargets.add(entry);
} }

View file

@ -9,23 +9,32 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.apache.commons.lang3.mutable.MutableBoolean; import org.apache.commons.lang3.mutable.MutableBoolean;
import org.apache.commons.lang3.mutable.MutableObject;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.CreateClient; 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.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackNode; 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.ITrackSelector;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.SteerDirection; 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.GlobalStation;
import com.simibubi.create.content.logistics.trains.management.GraphLocation; 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;
import com.simibubi.create.content.logistics.trains.management.ScheduleRuntime.State; 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.Iterate;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
@ -42,9 +51,6 @@ import net.minecraft.world.phys.Vec3;
public class Train { public class Train {
public static final double acceleration = 0.005f;
public static final double topSpeed = 1.2f;
public double speed = 0; public double speed = 0;
public double targetSpeed = 0; public double targetSpeed = 0;
@ -68,6 +74,9 @@ public class Train {
public List<Carriage> carriages; public List<Carriage> carriages;
public List<Integer> carriageSpacing; public List<Integer> carriageSpacing;
public boolean updateSignalBlocks;
public List<UUID> occupiedSignalBlocks;
List<TrainMigration> migratingPoints; List<TrainMigration> migratingPoints;
public int migrationCooldown; public int migrationCooldown;
public boolean derailed; public boolean derailed;
@ -92,22 +101,40 @@ public class Train {
doubleEnded = carriages.stream() doubleEnded = carriages.stream()
.anyMatch(c -> c.contraption.hasBackwardControls()); .anyMatch(c -> c.contraption.hasBackwardControls());
navigation = new Navigation(this, graph); navigation = new Navigation(this);
runtime = new ScheduleRuntime(this); runtime = new ScheduleRuntime(this);
heldForAssembly = true; heldForAssembly = true;
migratingPoints = new ArrayList<>(); migratingPoints = new ArrayList<>();
currentStation = null; currentStation = null;
manualSteer = SteerDirection.NONE; 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) { public void tick(Level level) {
status.tick(level); if (graph == null)
if (graph == null) {
if (!migratingPoints.isEmpty())
reattachToTracks(level);
return; return;
}
updateConductors(); updateConductors();
runtime.tick(level); runtime.tick(level);
@ -119,8 +146,9 @@ public class Train {
double distance = speed; double distance = speed;
Carriage previousCarriage = null; 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); Carriage carriage = carriages.get(i);
if (previousCarriage != null) { if (previousCarriage != null) {
int target = carriageSpacing.get(i - 1); int target = carriageSpacing.get(i - 1);
@ -142,8 +170,8 @@ public class Train {
boolean blocked = false; boolean blocked = false;
boolean iterateFromBack = speed < 0; boolean iterateFromBack = speed < 0;
for (int index = 0; index < carriages.size(); index++) { for (int index = 0; index < carriageCount; index++) {
int i = iterateFromBack ? carriages.size() - 1 - index : index; int i = iterateFromBack ? carriageCount - 1 - index : index;
double leadingStress = i == 0 ? 0 : stress[i - 1] * -(iterateFromBack ? trailingModifier : leadingModifier); double leadingStress = i == 0 ? 0 : stress[i - 1] * -(iterateFromBack ? trailingModifier : leadingModifier);
double trailingStress = double trailingStress =
i == stress.length ? 0 : stress[i] * (iterateFromBack ? leadingModifier : trailingModifier); i == stress.length ? 0 : stress[i] * (iterateFromBack ? leadingModifier : trailingModifier);
@ -154,7 +182,7 @@ public class Train {
: carriages.get(i - 1) : carriages.get(i - 1)
.getTrailingPoint(); .getTrailingPoint();
TravellingPoint toFollowBackward = i == carriages.size() - 1 ? null TravellingPoint toFollowBackward = i == carriageCount - 1 ? null
: carriages.get(i + 1) : carriages.get(i + 1)
.getLeadingPoint(); .getLeadingPoint();
@ -164,8 +192,11 @@ public class Train {
toFollowBackward == null ? navigation::control : mp -> mp.follow(toFollowBackward); toFollowBackward == null ? navigation::control : mp -> mp.follow(toFollowBackward);
double totalStress = leadingStress + trailingStress; 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 = double actualDistance =
carriage.travel(level, graph, distance + totalStress, forwardControl, backwardControl); carriage.travel(level, graph, distance + totalStress, forwardControl, backwardControl, carriageType);
blocked |= carriage.blocked; blocked |= carriage.blocked;
if (index == 0) { if (index == 0) {
@ -185,16 +216,46 @@ public class Train {
updateNavigationTarget(distance); 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) { private void updateNavigationTarget(double distance) {
if (navigation.destination != null) { if (navigation.destination != null) {
boolean recalculate = navigation.distanceToDestination % 100 > 20; boolean recalculate = navigation.distanceToDestination % 100 > 20;
boolean imminentRecalculate = navigation.distanceToDestination > 5; boolean imminentRecalculate = navigation.distanceToDestination > 5;
navigation.distanceToDestination -= Math.abs(distance); navigation.distanceToDestination -= Math.abs(distance);
if (recalculate && navigation.distanceToDestination % 100 <= 20 boolean signalMode = navigation.waitingForSignal != null;
|| imminentRecalculate && navigation.distanceToDestination <= 5) 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); navigation.startNavigation(navigation.destination, false);
} }
} }
}
private void tickDerailedSlowdown() { private void tickDerailedSlowdown() {
speed /= 3f; speed /= 3f;
@ -204,9 +265,10 @@ public class Train {
private void tickPassiveSlowdown() { private void tickPassiveSlowdown() {
if (!manualTick && navigation.destination == null && speed != 0) { 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); speed = Math.max(speed - acceleration, 0);
else } else
speed = Math.min(speed + acceleration, 0); speed = Math.min(speed + acceleration, 0);
} }
manualTick = false; 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) { public void reattachToTracks(Level level) {
if (migrationCooldown > 0) { if (migrationCooldown > 0) {
migrationCooldown--; migrationCooldown--;
@ -418,6 +513,7 @@ public class Train {
GlobalStation currentStation = getCurrentStation(); GlobalStation currentStation = getCurrentStation();
if (currentStation != null) if (currentStation != null)
currentStation.reserveFor(this); currentStation.reserveFor(this);
updateSignalBlocks = true;
return; return;
} }
} }
@ -478,10 +574,72 @@ public class Train {
return; return;
if (manualTick) if (manualTick)
leaveStation(); leaveStation();
double acceleration = AllConfigs.SERVER.trains.getAccelerationMPTT();
if (speed < targetSpeed) if (speed < targetSpeed)
speed = Math.min(speed + Train.acceleration * accelerationMod, targetSpeed); speed = Math.min(speed + acceleration * accelerationMod, targetSpeed);
else if (speed > 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 javax.annotation.Nullable;
import org.apache.commons.lang3.mutable.MutableBoolean;
import com.simibubi.create.AllItems; import com.simibubi.create.AllItems;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionHandlerClient; 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.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackGraphHelper; import com.simibubi.create.content.logistics.trains.TrackGraphHelper;
import com.simibubi.create.content.logistics.trains.TrackNode; 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.ITrackSelector;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.SteerDirection; import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.SteerDirection;
import com.simibubi.create.content.logistics.trains.management.GraphLocation; import com.simibubi.create.content.logistics.trains.management.GraphLocation;
@ -125,58 +128,40 @@ public class TrainRelocator {
return false; return false;
TravellingPoint probe = new TravellingPoint(node1, node2, edge, graphLocation.position); TravellingPoint probe = new TravellingPoint(node1, node2, edge, graphLocation.position);
ISignalBoundaryListener ignoreSignals = probe.ignoreSignals();
List<Pair<Couple<TrackNode>, Double>> recordedLocations = new ArrayList<>(); List<Pair<Couple<TrackNode>, Double>> recordedLocations = new ArrayList<>();
Consumer<TravellingPoint> recorder = Consumer<TravellingPoint> recorder =
tp -> recordedLocations.add(Pair.of(Couple.create(tp.node1, tp.node2), tp.position)); 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)); ITrackSelector steer = probe.steer(SteerDirection.NONE, track.getUpNormal(level, pos, blockState));
for (int i = 0; i < train.carriages.size(); i++) { MutableBoolean blocked = new MutableBoolean(false);
int index = train.carriages.size() - i - 1;
Carriage carriage = train.carriages.get(index); train.forEachTravellingPointBackwards((tp, d) -> {
double trailSpacing = carriage.trailingBogey().type.getWheelPointSpacing(); if (blocked.booleanValue())
if (i > 0) { return;
probe.travel(graph, train.carriageSpacing.get(index) - lastWheelOffset - trailSpacing / 2, steer); probe.travel(graph, d, steer, ignoreSignals);
if (probe.blocked) if (probe.blocked) {
return false; blocked.setTrue();
recorder.accept(probe); return;
} }
// inside 1st bogey
probe.travel(graph, trailSpacing, steer);
if (probe.blocked)
return false;
recorder.accept(probe); recorder.accept(probe);
});
lastWheelOffset = trailSpacing / 2; if (blocked.booleanValue())
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; 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 (simulate) if (simulate)
return true; return true;
train.leaveStation();
train.derailed = false; train.derailed = false;
train.navigation.waitingForSignal = null;
train.occupiedSignalBlocks.clear();
train.graph = graph; train.graph = graph;
train.migratingPoints.clear(); train.speed = 0;
if (train.navigation.destination != null)
train.navigation.cancelNavigation();
train.forEachTravellingPoint(tp -> { train.forEachTravellingPoint(tp -> {
Pair<Couple<TrackNode>, Double> last = recordedLocations.remove(recordedLocations.size() - 1); Pair<Couple<TrackNode>, Double> last = recordedLocations.remove(recordedLocations.size() - 1);
tp.node1 = last.getFirst() tp.node1 = last.getFirst()
@ -189,7 +174,7 @@ public class TrainRelocator {
}); });
train.status.successfulMigration(); train.status.successfulMigration();
train.leaveStation(); train.collectInitiallyOccupiedSignalBlocks();
return true; return true;
} }

View file

@ -5,7 +5,9 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.UUID;
import java.util.Vector; import java.util.Vector;
import java.util.function.BiConsumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import com.simibubi.create.Create; 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.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackNode; 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.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 com.simibubi.create.foundation.utility.Pair;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
public class TravellingPoint { public class TravellingPoint {
TrackNode node1, node2; public TrackNode node1, node2;
TrackEdge edge; public TrackEdge edge;
double position; public double position;
boolean blocked; public boolean blocked;
public static enum SteerDirection { public static enum SteerDirection {
NONE(0), LEFT(-1), RIGHT(1); 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>> { 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) { public TravellingPoint(TrackNode node1, TrackNode node2, TrackEdge edge, double position) {
this.node1 = node1; this.node1 = node1;
this.node2 = node2; this.node2 = node2;
@ -45,6 +55,11 @@ public class TravellingPoint {
this.position = position; this.position = position;
} }
public ISignalBoundaryListener ignoreSignals() {
return (d, c) -> {
};
}
public ITrackSelector random() { public ITrackSelector random() {
return (graph, pair) -> pair.getSecond() return (graph, pair) -> pair.getSecond()
.get(Create.RANDOM.nextInt(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; blocked = false;
double edgeLength = edge.getLength(node1, node2); double edgeLength = edge.getLength(node1, node2);
if (distance == 0) if (distance == 0)
return 0; return 0;
double prevPos = position;
double traveled = distance; double traveled = distance;
double currentT = position / edgeLength; double currentT = position / edgeLength;
double incrementT = edge.incrementT(node1, node2, currentT, distance); double incrementT = edge.incrementT(node1, node2, currentT, distance);
position = incrementT * edgeLength; position = incrementT * edgeLength;
List<Entry<TrackNode, TrackEdge>> validTargets = new ArrayList<>(); 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 // Moving forward
while (position > edgeLength) { while (position > edgeLength) {
validTargets.clear(); validTargets.clear();
@ -179,6 +200,11 @@ public class TravellingPoint {
node2 = entry.getKey(); node2 = entry.getKey();
edge = entry.getValue(); edge = entry.getValue();
position -= edgeLength; position -= edgeLength;
collectedDistance += edgeLength;
edgeTraversedFrom(graph, forward, signalListener, 0, collectedDistance);
prevPos = 0;
edgeLength = edge.getLength(node1, node2); edgeLength = edge.getLength(node1, node2);
} }
@ -217,8 +243,11 @@ public class TravellingPoint {
node1 = entry.getKey(); node1 = entry.getKey();
edge = graph.getConnectionsFrom(node1) edge = graph.getConnectionsFrom(node1)
.get(node2); .get(node2);
collectedDistance += edgeLength;
edgeLength = edge.getLength(node1, node2); edgeLength = edge.getLength(node1, node2);
position += edgeLength; position += edgeLength;
edgeTraversedFrom(graph, forward, signalListener, edgeLength, collectedDistance);
} }
} }
@ -226,6 +255,41 @@ public class TravellingPoint {
return traveled; 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) { public void reverse(TrackGraph graph) {
TrackNode n = node1; TrackNode n = node1;
node1 = node2; 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.TrackNodeLocation;
import com.simibubi.create.content.logistics.trains.entity.Train; 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 com.simibubi.create.foundation.utility.Couple;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.NbtUtils;
import net.minecraft.nbt.Tag;
import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.entity.BlockEntity; 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 String name;
public BlockPos stationPos; public BlockPos stationPos;
public WeakReference<Train> nearestTrain; public WeakReference<Train> nearestTrain;
@Nullable
public SignalBoundary boundary;
public GlobalStation(UUID id, BlockPos stationPos) { public GlobalStation(UUID id, BlockPos stationPos) {
this.id = id; super(id);
this.stationPos = stationPos; this.stationPos = stationPos;
name = "Track Station"; name = "Track Station";
nearestTrain = new WeakReference<Train>(null); nearestTrain = new WeakReference<Train>(null);
} }
public GlobalStation(CompoundTag nbt) { public GlobalStation(CompoundTag nbt) {
id = nbt.getUUID("Id"); super(nbt);
name = nbt.getString("Name"); name = nbt.getString("Name");
position = nbt.getDouble("Position");
stationPos = NbtUtils.readBlockPos(nbt.getCompound("StationPos")); stationPos = NbtUtils.readBlockPos(nbt.getCompound("StationPos"));
nearestTrain = new WeakReference<Train>(null); 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) { 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.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.blaze3d.vertex.VertexConsumer;
import com.simibubi.create.content.logistics.trains.ITrackBlock; 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.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
@ -44,7 +45,7 @@ public class StationRenderer extends SafeTileEntityRenderer<StationTileEntity> {
ms.pushPose(); ms.pushPose();
ms.translate(-pos.getX(), -pos.getY(), -pos.getZ()); ms.translate(-pos.getX(), -pos.getY(), -pos.getZ());
TrackTargetingBehaviour.render(level, targetPosition, target.getTargetDirection(), 0xCC993B, ms, buffer, TrackTargetingBehaviour.render(level, targetPosition, target.getTargetDirection(), 0xCC993B, ms, buffer,
light, overlay); light, overlay, RenderedTrackOverlayType.STATION);
ms.popPose(); ms.popPose();
return; return;
} }
@ -62,8 +63,8 @@ public class StationRenderer extends SafeTileEntityRenderer<StationTileEntity> {
MutableBlockPos currentPos = targetPosition.mutable(); MutableBlockPos currentPos = targetPosition.mutable();
PartialModel assemblyOverlay = track.prepareAssemblyOverlay(level, targetPosition, trackState, direction, ms); PartialModel assemblyOverlay = track.prepareAssemblyOverlay(level, targetPosition, trackState, direction, ms);
int colorWhenValid = 0x7092F2; int colorWhenValid = 0x96B5FF;
int colorWhenCarriage = 0x70EF70; int colorWhenCarriage = 0xCAFF96;
VertexConsumer vb = buffer.getBuffer(RenderType.cutoutMipped()); VertexConsumer vb = buffer.getBuffer(RenderType.cutoutMipped());
currentPos.move(direction, 1); currentPos.move(direction, 1);

View file

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

View file

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

View file

@ -19,7 +19,7 @@ public class ScheduledDelay extends TimedWaitCondition {
@Override @Override
public boolean tickCompletion(Level level, Train train, CompoundTag context) { 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) if (time >= value * timeUnit.ticksPer)
return true; return true;
context.putInt("Time", time + 1); 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.TrackNodeLocation.DiscoveredLocation;
import com.simibubi.create.content.logistics.trains.TrackPropagator; 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.StationTileEntity;
import com.simibubi.create.content.logistics.trains.management.TrackTargetingBehaviour.RenderedTrackOverlayType;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.VecHelper; 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()) { if (Blocks.SPONGE.asItem() == itemInHand.getItem()) {
Create.RAILWAYS.trackNetworks.clear(); Create.RAILWAYS.trackNetworks.clear();
CreateClient.RAILWAYS.trackNetworks.clear(); CreateClient.RAILWAYS.trackNetworks.clear();
Create.RAILWAYS.signalEdgeGroups.clear();
CreateClient.RAILWAYS.signalEdgeGroups.clear();
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;
} }
@ -347,13 +350,13 @@ public class TrackBlock extends Block implements EntityBlock, IWrenchable, ITrac
PoseStack ms) { PoseStack ms) {
new MatrixTransformStack(ms).rotateCentered(Direction.UP, new MatrixTransformStack(ms).rotateCentered(Direction.UP,
AngleHelper.rad(AngleHelper.horizontalAngle(direction))); AngleHelper.rad(AngleHelper.horizontalAngle(direction)));
return AllBlockPartials.TRACK_ASSEMBLY_OVERLAY; return AllBlockPartials.TRACK_ASSEMBLING_OVERLAY;
} }
@Override @Override
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public PartialModel prepareStationOverlay(BlockGetter world, BlockPos pos, BlockState state, public PartialModel prepareTrackOverlay(BlockGetter world, BlockPos pos, BlockState state, AxisDirection direction,
AxisDirection direction, PoseStack ms) { PoseStack ms, RenderedTrackOverlayType type) {
Vec3 axis = state.getValue(SHAPE) Vec3 axis = state.getValue(SHAPE)
.getAxes() .getAxes()
.get(0); .get(0);
@ -361,13 +364,16 @@ public class TrackBlock extends Block implements EntityBlock, IWrenchable, ITrac
.normalize(); .normalize();
Vec3 normal = getUpNormal(world, pos, state); Vec3 normal = getUpNormal(world, pos, state);
Vec3 angles = TrackRenderer.getModelAngles(normal, directionVec); 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 new MatrixTransformStack(ms).centre()
: AllBlockPartials.TRACK_STATION_OVERLAY_DIAGONAL : AllBlockPartials.TRACK_STATION_OVERLAY; .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 @Override

View file

@ -1,5 +1,6 @@
package com.simibubi.create.foundation.command; package com.simibubi.create.foundation.command;
import java.util.Collection;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.UUID; import java.util.UUID;
import java.util.function.BiConsumer; 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.GlobalStation;
import com.simibubi.create.content.logistics.trains.management.ScheduleRuntime; 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.ScheduleRuntime.State;
import com.simibubi.create.content.logistics.trains.management.signal.SignalBoundary;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
@ -48,6 +50,7 @@ public class DumpRailwaysCommand {
chat.accept("", white); chat.accept("", white);
chat.accept("-+------<< Railways Summary: >>------+-", white); chat.accept("-+------<< Railways Summary: >>------+-", white);
chat.accept("Track Networks: " + railways.trackNetworks.size(), blue); 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("Trains: " + railways.trains.size(), blue);
chat.accept("", white); chat.accept("", white);
@ -59,6 +62,9 @@ public class DumpRailwaysCommand {
+ graph.getNodes() + graph.getNodes()
.size() .size()
+ " Nodes", graph.color.getRGB()); + " Nodes", graph.color.getRGB());
Collection<SignalBoundary> signals = graph.getSignals();
if (!signals.isEmpty())
chat.accept(" -> " + signals.size() + " registered Signals", blue);
for (GlobalStation globalStation : graph.getStations()) { for (GlobalStation globalStation : graph.getStations()) {
BlockPos pos = globalStation.stationPos; BlockPos pos = globalStation.stationPos;
chat.accept(" -> " + globalStation.name + " (" + globalStation.id.toString() 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 CLogistics logistics = nested(0, CLogistics::new, Comments.logistics);
public final CSchematics schematics = nested(0, CSchematics::new, Comments.schematics); public final CSchematics schematics = nested(0, CSchematics::new, Comments.schematics);
public final CCuriosities curiosities = nested(0, CCuriosities::new, Comments.curiosities); public final CCuriosities curiosities = nested(0, CCuriosities::new, Comments.curiosities);
public final CTrains trains = nested(0, CTrains::new, Comments.trains);
@Override @Override
public String getName() { public String getName() {
@ -25,6 +26,7 @@ public class CServer extends ConfigBase {
static String fluids = "Create's liquid manipulation tools"; static String fluids = "Create's liquid manipulation tools";
static String logistics = "Tweaks for logistical components"; static String logistics = "Tweaks for logistical components";
static String curiosities = "Gadgets and other Shenanigans added by Create"; 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 infrastructure = "The Backbone of Create";
static String tickrateSyncTimer = static String tickrateSyncTimer =
"The amount of time a server waits before sending out tickrate synchronization packets."; "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)); .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); private static final RenderType GLOWING_TRANSLUCENT_DEFAULT = getGlowingTranslucent(InventoryMenu.BLOCK_ATLAS);
public static RenderType getGlowingTranslucent() { public static RenderType getGlowingTranslucent() {

View file

@ -11,6 +11,7 @@
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]},
"faces": { "faces": {
"north": {"uv": [6.5, 9, 5, 16], "texture": "#0"}, "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"}, "south": {"uv": [5, 9, 6.5, 16], "texture": "#0"},
"west": {"uv": [0, 9, 5, 16], "texture": "#0"}, "west": {"uv": [0, 9, 5, 16], "texture": "#0"},
"up": {"uv": [6.5, 11, 8, 16], "texture": "#0"}, "up": {"uv": [6.5, 11, 8, 16], "texture": "#0"},

View file

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

View file

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