Merge branch 'mc1.20.1/feature-dev' into mc1.20.1/high-logistics

This commit is contained in:
simibubi 2024-10-09 21:19:47 +02:00
commit f243c6432a
107 changed files with 2619 additions and 287 deletions

View file

@ -177,6 +177,22 @@ repositories {
name = "squiddev"
url = "https://squiddev.cc/maven/"
}
maven {
name = "ftb"
url = "https://maven.saps.dev/releases"
}
maven {
name = "architectury"
url = "https://maven.architectury.dev/"
}
maven {
url = "https://jm.gserv.me/repository/maven-public/"
content {
includeGroup "info.journeymap"
includeGroup "mysticdrew"
}
}
maven {
url = 'https://www.cursemaven.com'
@ -266,6 +282,14 @@ dependencies {
// implementation fg.deobf("curse.maven:ic2-classic-242942:5555152")
// implementation fg.deobf("curse.maven:druidcraft-340991:3101903")
// implementation fg.deobf("com.railwayteam.railways:railways-1.19.2-1.6.4:all") { transitive = false }
implementation fg.deobf("dev.architectury:architectury-forge:9.1.12")
implementation fg.deobf("dev.ftb.mods:ftb-chunks-forge:2001.3.1")
implementation fg.deobf("dev.ftb.mods:ftb-teams-forge:2001.3.0")
implementation fg.deobf("dev.ftb.mods:ftb-library-forge:2001.2.4")
implementation fg.deobf("curse.maven:journeymap-32274:5457831")
// implementation fg.deobf("ignored:journeymap-1.20.1-5.10.1-forge")
// runtimeOnly fg.deobf("curse.maven:framedblocks-441647:5399211")
// runtimeOnly fg.deobf("curse.maven:galosphere-631098:4574834")

View file

@ -28,7 +28,7 @@ jei_minecraft_version = 1.20.1
jei_version = 15.10.0.39
curios_minecraft_version = 1.20.1
curios_version = 5.3.1
catnip_version = 0.8.14
catnip_version = 0.8.15
ponder_version = 0.8.10
cc_tweaked_enable = true

View file

@ -1,4 +1,4 @@
// 1.20.1 2024-09-02T22:36:27.3560692 Create's Sequenced Assembly Recipes
// 1.20.1 2024-10-09T12:24:59.2666858 Create's Sequenced Assembly Recipes
dbaca5a5aa312f3bc7b826e51e665d32e798a5d7 data/create/recipes/sequenced_assembly/precision_mechanism.json
dacafdb106304d183b00e21fb01517ac45eca800 data/create/recipes/sequenced_assembly/sturdy_sheet.json
1274315b5c570722d6f5b2ed7f5e53fe01b6288a data/create/recipes/sequenced_assembly/track.json

View file

@ -1,4 +1,4 @@
// 1.20.1 2024-10-05T13:53:09.0252048 Registrate Provider for create [Recipes, Advancements, Loot Tables, Tags (blocks), Tags (items), Tags (fluids), Tags (entity_types), Blockstates, Item models, Lang (en_us/en_ud)]
// 1.20.1 2024-09-03T11:32:11.6637155 Registrate Provider for create [Recipes, Advancements, Loot Tables, Tags (blocks), Tags (items), Tags (fluids), Tags (entity_types), Blockstates, Item models, Lang (en_us/en_ud)]
60bbdf92d2ac9824ea6144955c74043a6005f79d assets/create/blockstates/acacia_window.json
6a67703c2697d81b7dc83e9d72a66f9c9ff08383 assets/create/blockstates/acacia_window_pane.json
c3ae87b62e81d8e9476eccd793bb1548d74c66a1 assets/create/blockstates/adjustable_chain_gearshift.json
@ -23,14 +23,12 @@ a97910c7516e7cedec9e34eca51f1183f1e3e681 assets/create/blockstates/belt.json
0ea03133af234921a3313f52521d8cfd02bf5d81 assets/create/blockstates/birch_window.json
2003c43151b731bf19cae58290c63bcb3785848a assets/create/blockstates/birch_window_pane.json
c8b65faf51122eb411f5895e718869da9b260c2e assets/create/blockstates/black_nixie_tube.json
edcdce7ec6afbaa00952131df4b3f2c93c2c6919 assets/create/blockstates/black_postbox.json
980ae9ba3f6d4e0faea8f3878985f9a9dadc0796 assets/create/blockstates/black_sail.json
da3ad0225984a0dcbfb4ed800e307e45aff5aaa1 assets/create/blockstates/black_seat.json
0083f6aa3fda2c7ebb2e5f2a032e740cf3ae3846 assets/create/blockstates/black_toolbox.json
28f2fb355e80171403e540afd2aed44e9c19659a assets/create/blockstates/black_valve_handle.json
06ecd28cd97f4e8200dc396858695cad57b871c8 assets/create/blockstates/blaze_burner.json
37caf031254b5171a1fbfe9906f4bc65e8dbc909 assets/create/blockstates/blue_nixie_tube.json
54f6aae1d573b27979689301ef1c2ad4a3bf6e93 assets/create/blockstates/blue_postbox.json
d540f0f23e0d7c03f8e147cf3eebbaf7caec9f93 assets/create/blockstates/blue_sail.json
d2fdb432bb037de781260c789e905b223fab408c assets/create/blockstates/blue_seat.json
f91092da79b69fece9583ccc15350612f439ee1b assets/create/blockstates/blue_toolbox.json
@ -48,14 +46,12 @@ a408005aae4c1caa7aaae5a0ddf9d1ad73cd0254 assets/create/blockstates/brass_funnel.
6d210298b9d80ae69aa03b09aa73b92e14b9ab1b assets/create/blockstates/brass_scaffolding.json
8ee948f9e87b82bb27aaecc522127fa1297b3d9d assets/create/blockstates/brass_tunnel.json
debf33346bf410216f21082e1e8d07aa6250b84c assets/create/blockstates/brown_nixie_tube.json
c23d7f691bf532d6b27317c0063289a8bd747de2 assets/create/blockstates/brown_postbox.json
1334fc9e71d9f2a6117f448817263467a9c695de assets/create/blockstates/brown_sail.json
19524b2c0672632e63372f405a87dbea35f1d160 assets/create/blockstates/brown_seat.json
1ffc38bf682e84aad4cb300c573375eb0cdcc434 assets/create/blockstates/brown_toolbox.json
440b29e1dffa4374ddc1aed444bff18a485bc1cb assets/create/blockstates/brown_valve_handle.json
2064534de4791b339fdcd4ef3a8129a2e233ec50 assets/create/blockstates/calcite_pillar.json
060c957b28afed9f4e0954cbef7e80cbf4b99f58 assets/create/blockstates/cart_assembler.json
fab98b93ad9b78312742daca83c2575db40fce98 assets/create/blockstates/chain_conveyor.json
c7eca70054241944171b1d4ffcba0376b071ec62 assets/create/blockstates/chocolate.json
9eb989b0a0545af9efd052d1f127b2ec28a972d1 assets/create/blockstates/chute.json
b5170d754ce5f07ea2b4646eb07c099c50bae249 assets/create/blockstates/clipboard.json
@ -206,7 +202,6 @@ beb9e47f8d811c2146f68daf992fb805342a65cb assets/create/blockstates/cut_veridium.
c11f09df4a23e951bdf9a345515183f4fac7cde3 assets/create/blockstates/cut_veridium_stairs.json
3aa6f5e613ff73952e3de00408051f92316e7f81 assets/create/blockstates/cut_veridium_wall.json
bb627b2e78dba6833cf2d357033f253fc89aa1b8 assets/create/blockstates/cyan_nixie_tube.json
3406ab8baa7d9e9892c059c27b5ace92aadc2a80 assets/create/blockstates/cyan_postbox.json
f1061b8f9757374d6608fda07e301a2623e79f72 assets/create/blockstates/cyan_sail.json
538c6d95da5cc460e99c91647dac61726a91479f assets/create/blockstates/cyan_seat.json
c4d84b719762aca46cdb8decddfeb97dcc50676c assets/create/blockstates/cyan_toolbox.json
@ -249,13 +244,11 @@ ff9f56912d8ac4069df90505232820f9c45f5e06 assets/create/blockstates/gantry_carria
5a193991f33a1af8659192f3693e4d8d3ed0082b assets/create/blockstates/glass_fluid_pipe.json
e3f2a093c436cb65c5a7ac049a14cc4dadb22526 assets/create/blockstates/granite_pillar.json
921cf220c44a67195c90a30c4c296e65311738da assets/create/blockstates/gray_nixie_tube.json
f3153de05bb7658cd2d27ed6becea1b2ea687ae3 assets/create/blockstates/gray_postbox.json
30ba031a6b5a327d2a4caa12169676da573c2133 assets/create/blockstates/gray_sail.json
f35a502c4a5e2703e7c6811b3d2ba16a9c47d4c8 assets/create/blockstates/gray_seat.json
87457e0eddae80225dbb3145f2d120296ea1bfcd assets/create/blockstates/gray_toolbox.json
f18b87db39836eef20154b239d488eebb64b3455 assets/create/blockstates/gray_valve_handle.json
0f0fe2bf83f763e04cd2d7a979beb547feac3191 assets/create/blockstates/green_nixie_tube.json
4446fdbf784366888215251fb082ff9b52c2ea6d assets/create/blockstates/green_postbox.json
0a2a5fbf2cf084e1be0426a224c291dc22a826fd assets/create/blockstates/green_sail.json
b4aede1847d204ecdb7847559066d9d2ffb66903 assets/create/blockstates/green_seat.json
6f080890b3b30c46ba9ceb382c1171940bf4966f assets/create/blockstates/green_toolbox.json
@ -268,7 +261,6 @@ bffc2169f5fc3a8e22f8952a90767e0bb8d726b5 assets/create/blockstates/horizontal_fr
8ae52808eba950c36b75d62113e9cea9441a1a54 assets/create/blockstates/hose_pulley.json
87fa830c5d3541d096fab32d430c54516c197583 assets/create/blockstates/industrial_iron_block.json
2788ad2d29996076f7f18ab8d47e40c1ad10b348 assets/create/blockstates/item_drain.json
e840d746532f350ee2977c00036163f73c3f4147 assets/create/blockstates/item_hatch.json
3e99569e978c0fe17ec18b97881434a9da1a8421 assets/create/blockstates/item_vault.json
8680e9d2a94231f4bbad87b26ab2efdb714903d3 assets/create/blockstates/jungle_window.json
ddcf1010e43c5d4a8c93aad37cc97a94343fd9f5 assets/create/blockstates/jungle_window_pane.json
@ -291,13 +283,11 @@ ca124508c59130d21f23d7b1ef354d78bdd24dd4 assets/create/blockstates/layered_tuff.
2ff5466f9ea3b1292c24a8ddb31666d74635c592 assets/create/blockstates/layered_veridium.json
fcf02725651ab5973fab1cfc09fdd68cb4b93579 assets/create/blockstates/lectern_controller.json
5d7e1b08b1ec7c7c11b70db11df09311fcd7cf45 assets/create/blockstates/light_blue_nixie_tube.json
f77864045801c12e9308f9ae75fa7c78de15bb7e assets/create/blockstates/light_blue_postbox.json
f2354e8cb6086473ac97a5228b99706858dcad8a assets/create/blockstates/light_blue_sail.json
6b7045eaf9efe3a90f2d9a6785be6a5fd534b8e7 assets/create/blockstates/light_blue_seat.json
b7065e7871c3c7f1a0656c2f92f82544e606f2fb assets/create/blockstates/light_blue_toolbox.json
549882a0f4de60906ca870a6197330f81d4e1afe assets/create/blockstates/light_blue_valve_handle.json
fa5fb2be73c7c54b70e927b66adf3f4d64c5cb6b assets/create/blockstates/light_gray_nixie_tube.json
63aa0bfbba64796ec0096972585d15d5cbed7508 assets/create/blockstates/light_gray_postbox.json
3d95c9c4442d1bdd660bae382c72c68134db86dd assets/create/blockstates/light_gray_sail.json
8ec5144da4a49dd5b497af07b0d4b88c9c0b6cc0 assets/create/blockstates/light_gray_seat.json
35b151db396069b146d223fbe46be5b0c3dda8a9 assets/create/blockstates/light_gray_toolbox.json
@ -305,7 +295,6 @@ fa5fb2be73c7c54b70e927b66adf3f4d64c5cb6b assets/create/blockstates/light_gray_ni
a6f319c803c03e34bbf841ea52d82f0f7ec7a413 assets/create/blockstates/limestone.json
7ff65e1c4c8e48a0b694cd17506a192e6a7e6e44 assets/create/blockstates/limestone_pillar.json
7f20b548dd535942b2d6f41c39de7ad4fafe637e assets/create/blockstates/lime_nixie_tube.json
b1b07cbe36064d2755d0f2a4af036ec0506e6995 assets/create/blockstates/lime_postbox.json
ad1ec304729fd6d336c0d4d0c27c9345af636695 assets/create/blockstates/lime_sail.json
b9934a558e1b495403dc2c71ffb43cce7d396013 assets/create/blockstates/lime_seat.json
49a02f7fc16697ba1cf16cee7e45ab6bfd8b06ce assets/create/blockstates/lime_toolbox.json
@ -313,7 +302,6 @@ ba181485f219d3ae23509a7edf28e25d9edb10f4 assets/create/blockstates/lime_valve_ha
654e845cebed82b7afbcf81380921e0a475b01e9 assets/create/blockstates/linear_chassis.json
e195e82e4d0c1fc20474535bc9068cbb77a5e175 assets/create/blockstates/lit_blaze_burner.json
296186b196af94e1ab3f7e8a3254f6d31ae47a5c assets/create/blockstates/magenta_nixie_tube.json
32cf7fc7e7b36b6ef873658946a40cf7c32d5da8 assets/create/blockstates/magenta_postbox.json
f150922cbed1c05fb3892d4ac91eb471234252e2 assets/create/blockstates/magenta_sail.json
bb1ab5c70647933400b3a99ef9d166ba5e3d4709 assets/create/blockstates/magenta_seat.json
fcd226c7863262d98765c701538bf9e44d2b177e assets/create/blockstates/magenta_toolbox.json
@ -346,7 +334,6 @@ ba9c3ecfacbd398048440d247decffeaefc714b5 assets/create/blockstates/mysterious_cu
7f2c5728e24d60ed2f7a095e3a954d7ca4e410e9 assets/create/blockstates/oak_window_pane.json
df91d0ca68934c1afd9858a8d1591dd4cb88df65 assets/create/blockstates/ochrum.json
09c9bee3d26edc4b87cb7a5042f125c439ee5956 assets/create/blockstates/ochrum_pillar.json
42799faa0c59e6ed410c1ef42eceef25c323090f assets/create/blockstates/orange_postbox.json
af4c2c4861d1410e1b7371a5bf3fe09ed3ab0077 assets/create/blockstates/orange_sail.json
aab812cecf7d10d4e7587f4dead8a98238a15f41 assets/create/blockstates/orange_seat.json
2bc30ed9907230271b4e2d0786f106f3e1e25029 assets/create/blockstates/orange_toolbox.json
@ -359,12 +346,8 @@ ac536ae742c12e97bfd0b2483c87ff29f3935eaf assets/create/blockstates/oxidized_copp
110a6c19bcc9f044e5e982ac6e4b295b03ec0145 assets/create/blockstates/oxidized_copper_tiles.json
3f3924f0f0e368edfa04f4fdd6d6c2319276ddfe assets/create/blockstates/oxidized_copper_tile_slab.json
5e634cfb9abb06d8b29f39d751fc56b28ea5a9cd assets/create/blockstates/oxidized_copper_tile_stairs.json
ef3af446b56c69e71a156d5998d9dc8e6d9ea4f5 assets/create/blockstates/packager.json
0f204afc6712a08d2db84bb07a0a49927f3127a6 assets/create/blockstates/packager_link.json
887565a0f89f089d6be888c87394dde4878afda7 assets/create/blockstates/package_frogport.json
36742cc6ce052ead143366d31b11e828a525c1b8 assets/create/blockstates/peculiar_bell.json
53d102e706d53cb2c0dbc0bc11da828084a43519 assets/create/blockstates/pink_nixie_tube.json
8889da0684a2fd247a769cadbf94fd45e1c218f2 assets/create/blockstates/pink_postbox.json
213da5c04a33ae8ae7c0a4dec9844bbb6d670e33 assets/create/blockstates/pink_sail.json
8d5c80d5dc561240dfe8d7f212ffc33ac4e0fcd8 assets/create/blockstates/pink_seat.json
90bd26c7c6933f5ebbe17b0fe58f840e2924a0f5 assets/create/blockstates/pink_toolbox.json
@ -435,9 +418,7 @@ b1f5ad596067cb4c84eb53b2c7b359be76f1cfbe assets/create/blockstates/powered_shaft
df7af1e49c53ae99ac3f0b2fca5d948b8ea91938 assets/create/blockstates/pulley_magnet.json
89d763258c53aa12a1e0c0e586ab701f3de5a1b5 assets/create/blockstates/pulse_extender.json
81281435b8d1eeb4f1e318c6d14d49fa1fd86820 assets/create/blockstates/pulse_repeater.json
65bfd8283749117663f7199204691758fd286e38 assets/create/blockstates/pulse_timer.json
b658654aa97e8dd2c897f432a601835a3f8aca10 assets/create/blockstates/purple_nixie_tube.json
af5db46f49be3c13eeb9bcae1803cc6fb47a1c76 assets/create/blockstates/purple_postbox.json
f8f9802df9c0b4e39edeefc3b1abb38255d79801 assets/create/blockstates/purple_sail.json
91b5ab66d7ec5235d278ee2bed6ddd88f39ce81d assets/create/blockstates/purple_seat.json
6aa467b3588359fdf5d7201f844193d5b70f20f7 assets/create/blockstates/purple_toolbox.json
@ -447,9 +428,7 @@ f8f9802df9c0b4e39edeefc3b1abb38255d79801 assets/create/blockstates/purple_sail.j
7ce346fa18702f6fe6e2a939efcfa26eda63fe38 assets/create/blockstates/raw_zinc_block.json
ec546afd3ec8036e4393b97d535f05a86f57dbc1 assets/create/blockstates/redstone_contact.json
ff205f032b36486753dddb1f2029ef8d53e9c86f assets/create/blockstates/redstone_link.json
e3e0ea8069b354c29103948d0b5e79094587ef85 assets/create/blockstates/redstone_requester.json
e3fd62e466e3e6e7bd6fc8661f764ba972a466fc assets/create/blockstates/red_nixie_tube.json
d7535074a636f30247e7bd2f1a21685d3231d321 assets/create/blockstates/red_postbox.json
4c36b562da58ef2af57009da7cf2426059249228 assets/create/blockstates/red_sail.json
145f4e9ffaeff9be180e6c4e4989f2cf44cf0686 assets/create/blockstates/red_seat.json
380f46b7cb72b13c0f16fd4a4287a1a33adeff41 assets/create/blockstates/red_toolbox.json
@ -542,7 +521,6 @@ a60c9c8241e40c2e28f5760c0ca6e80cfe9d59f3 assets/create/blockstates/steam_whistle
8865500bcd2e4d467e74edb3509850fa92a5809f assets/create/blockstates/sticker.json
bed0534e618105184bc877b104230403ca85bb58 assets/create/blockstates/sticky_mechanical_piston.json
bab242ab794e6d439645c2d5a0242ae7c81942ff assets/create/blockstates/stockpile_switch.json
9989bda294fbffc5f659d2e608e01dea424c7694 assets/create/blockstates/stock_ticker.json
a70c025de5d85180f371ff05bbdc531d8bdfaab1 assets/create/blockstates/stressometer.json
8086f80c532fad42b37fcdc590b890ed7e8c3fe9 assets/create/blockstates/tiled_glass.json
1143ab7223c655764a81ed72ac385ea179664072 assets/create/blockstates/tiled_glass_pane.json
@ -594,7 +572,6 @@ fee668eb9a45dca0d287fee5811219d69f9ec3e2 assets/create/blockstates/weathered_cop
da110f382368257e15431c77164aef82e014e3f8 assets/create/blockstates/weathered_copper_tile_stairs.json
25ce64b7af5d244f194da91ccf964a9bf5762327 assets/create/blockstates/weighted_ejector.json
2974b34a8cfb0d4e8e010f8bd085584ea631d541 assets/create/blockstates/white_nixie_tube.json
debbed52643d90ab054171f76622e54192be60ad assets/create/blockstates/white_postbox.json
f079469d186087d23f0d91b384040f777b0088b1 assets/create/blockstates/white_sail.json
317a6463db64b66d215d25b65ab52fe7f26ba9f8 assets/create/blockstates/white_seat.json
6cb8c82a429b54d6a87d02eec5cfd1fcd5365f1e assets/create/blockstates/white_toolbox.json
@ -602,15 +579,14 @@ c0bfe8416173868f9916c4a54dd9f983887c5bac assets/create/blockstates/white_valve_h
ec2720e3f1bc84304d0c81cd23ff1e155b0c2f2c assets/create/blockstates/windmill_bearing.json
d688e80dfbd5b17970814887c3698fc721981caa assets/create/blockstates/wooden_bracket.json
157942a838aa02909fb2238ad9ce77edc82f6142 assets/create/blockstates/yellow_nixie_tube.json
f99bf11ac6b2d8d2a315f354d7704a938241d95e assets/create/blockstates/yellow_postbox.json
68b6e267e93b96dbc0596ea4a1cd26636aa0e04a assets/create/blockstates/yellow_sail.json
4face2dd50a30bda0b21742319e701e666d51f8c assets/create/blockstates/yellow_seat.json
b0d8f08968763a5f74e5cd5644377a76a9f39753 assets/create/blockstates/yellow_toolbox.json
fe8c497aacc641c2f01cec90bba9f19e59cc2ed2 assets/create/blockstates/yellow_valve_handle.json
e819e93fdcbe9fd9c050a052d2718ff3b3539365 assets/create/blockstates/zinc_block.json
64121dcb216381c83b4fe28aa361ea07c24c9ad0 assets/create/blockstates/zinc_ore.json
2670fb1fc306cbe16e88a0b1be45b4047074b2ce assets/create/lang/en_ud.json
25dcc2800d5f15625490b7dcb736e42448929066 assets/create/lang/en_us.json
1195fdc4fb51659c921e2bbe744a35107f787aa2 assets/create/lang/en_ud.json
632d1aac7255fc0f4804f4df138ce9926134d2f9 assets/create/lang/en_us.json
a97e1060e00ae701a02e39cd4ef8054cf345fac4 assets/create/models/block/acacia_window.json
103e032c0b1a0a6a27c67da8c91179a564bd281c assets/create/models/block/acacia_window_pane_noside.json
fb00b627abda76ad4fea867ca57dbfadd24fffa3 assets/create/models/block/acacia_window_pane_noside_alt.json
@ -677,13 +653,11 @@ ee71b0992edc2496025c22806e8de3a3243882aa assets/create/models/block/birch_window
3088aa5e46cf9caa912c80a4e7791904e64e9def assets/create/models/block/birch_window_pane_side.json
cb9d3a0dbac6a884d5ce0dc82085322f8c666707 assets/create/models/block/birch_window_pane_side_alt.json
2f040681214af58a97e70d3a6e77a0fc2e02c624 assets/create/models/block/black_nixie_tube.json
1fe4a9cbcae773f32c07f7cef42f52588ec1c1aa assets/create/models/block/black_postbox.json
62c92a681b5a86a5415cc7a70263ffdc794cdd59 assets/create/models/block/black_sail.json
443ed49b053fdd7356cd56f0495e18f2570d57d9 assets/create/models/block/black_seat.json
f48989d377de8e5067e807adf7e38da781e37ed9 assets/create/models/block/black_toolbox.json
8715787d72c3ef47c5651abcd819539bad6a96f7 assets/create/models/block/black_valve_handle.json
2f040681214af58a97e70d3a6e77a0fc2e02c624 assets/create/models/block/blue_nixie_tube.json
e9e9487a3440b3a6c1ac515f63385ee59e8fb773 assets/create/models/block/blue_postbox.json
ddc740084aa5f387bee062bd4141ad8fadb56355 assets/create/models/block/blue_sail.json
96431b1f3a531ce89f876c9286b81838aec9b6d3 assets/create/models/block/blue_seat.json
89932aab163b14a21fffd4fab4b8b88a94163089 assets/create/models/block/blue_toolbox.json
@ -736,7 +710,6 @@ b2a95218042586aae38dff9278f3ee3f159bc73e assets/create/models/block/brass_post_e
ec81e9c237ec98b30a3de22e12cb9720922478eb assets/create/models/block/brass_side.json
c697cace1f4097468ff34254c4ff6450d9d52f91 assets/create/models/block/brass_side_alt.json
2f040681214af58a97e70d3a6e77a0fc2e02c624 assets/create/models/block/brown_nixie_tube.json
b04c80852527a07e01c27686be678cbaf568e821 assets/create/models/block/brown_postbox.json
50a054d1e0660d16e86cf7a520b9bf36e38401b6 assets/create/models/block/brown_sail.json
0616de192825246e6036d1f69911170438a83b81 assets/create/models/block/brown_seat.json
4226a7c5f1bfb0a75457fb4dfd22448503110e5c assets/create/models/block/brown_toolbox.json
@ -1062,7 +1035,6 @@ d6423c0fd0af4fbd929d26d6097a1722567acc9d assets/create/models/block/cut_veridium
b2e847cee8c01791c15fcdd35787af33ebe46f0a assets/create/models/block/cut_veridium_wall_side.json
5ab4db4245b852edf985fe72595f678eb7372801 assets/create/models/block/cut_veridium_wall_side_tall.json
2f040681214af58a97e70d3a6e77a0fc2e02c624 assets/create/models/block/cyan_nixie_tube.json
0cbd0c6c909effa2f71e198655d51f2e483454aa assets/create/models/block/cyan_postbox.json
27c9aff76b32e4de18d581e133fc23a8239ca412 assets/create/models/block/cyan_sail.json
01a324a92552076589e2aaaeca9d4da2d1e3b39d assets/create/models/block/cyan_seat.json
663f431fe8a02e057980cf9bcfc566eb5adc876f assets/create/models/block/cyan_toolbox.json
@ -1144,13 +1116,11 @@ d0fa41de17f65693188f1868ace5fc2ac518739b assets/create/models/block/gantry_shaft
3356069e112cde817da0c99ceb40cd8f207de822 assets/create/models/block/granite_pillar.json
ee860a8bd95fda14a859d6632652ee2a95f06c19 assets/create/models/block/granite_pillar_horizontal.json
2f040681214af58a97e70d3a6e77a0fc2e02c624 assets/create/models/block/gray_nixie_tube.json
f2bbb067bc4e91a71303cc92939c4f4707cdc1ab assets/create/models/block/gray_postbox.json
97f382e9b435c81d1d8e0ed487a7fc16e6945958 assets/create/models/block/gray_sail.json
58b51da5c80e4f43582452d97453c93145a516ad assets/create/models/block/gray_seat.json
cd3cff8e38d559dcb78df014556a78d5a538af43 assets/create/models/block/gray_toolbox.json
3ee19f46bdeb0ac7489dcd4d51f90ab01ad863c9 assets/create/models/block/gray_valve_handle.json
2f040681214af58a97e70d3a6e77a0fc2e02c624 assets/create/models/block/green_nixie_tube.json
21fbacdc856fb1003f58bf2842fe418124f6b01d assets/create/models/block/green_postbox.json
26577589688ec1f39cae9f42704cb36cbc1c48ae assets/create/models/block/green_sail.json
ae51eaa500dd036fa27474a7392f381afb677dfd assets/create/models/block/green_seat.json
801d277b241332d5f4b49bdb00b911dcd01a7db2 assets/create/models/block/green_toolbox.json
@ -1188,13 +1158,11 @@ b843a6e27c4f90e31108f9f3c1573e70fb3d0927 assets/create/models/block/layered_scor
5fb53db0c6623dc16e486ac0bd094b5a90e2e080 assets/create/models/block/layered_tuff.json
336d1646294e018ea3de60b30a621a10ca7aa6d7 assets/create/models/block/layered_veridium.json
2f040681214af58a97e70d3a6e77a0fc2e02c624 assets/create/models/block/light_blue_nixie_tube.json
cf487c0be9444b7ac124d2ae33e6c545803e14b6 assets/create/models/block/light_blue_postbox.json
2e83d3aaa92640d6b3da2a2644f6a160f97b08e4 assets/create/models/block/light_blue_sail.json
ba917560f40a4e46ef190649f18adad9962c5c02 assets/create/models/block/light_blue_seat.json
c20616aa90feab3003cecb4a5be5466c0fc83072 assets/create/models/block/light_blue_toolbox.json
bcd3d28b8a062649301648ea5e2d0463f93d008d assets/create/models/block/light_blue_valve_handle.json
2f040681214af58a97e70d3a6e77a0fc2e02c624 assets/create/models/block/light_gray_nixie_tube.json
1efabd28f0dc3db1c0e6bea2be62cac883fefd66 assets/create/models/block/light_gray_postbox.json
09f284574b38ab57579e939bbb088b8d36e0b8f5 assets/create/models/block/light_gray_sail.json
d1813d0f548fcddb361df7cc3b5d97582842b10f assets/create/models/block/light_gray_seat.json
4ec5d701dd8b2d8c3dc44d05f527a3d737002cd4 assets/create/models/block/light_gray_toolbox.json
@ -1203,7 +1171,6 @@ adb8dbed70419e0310e7a20f3656bf325b348434 assets/create/models/block/light_gray_v
2b80f9421c2fe902d55d9bd95183ad4bae46c315 assets/create/models/block/limestone_pillar.json
fb18280a2a708f60b00cc7c675804c219784871a assets/create/models/block/limestone_pillar_horizontal.json
2f040681214af58a97e70d3a6e77a0fc2e02c624 assets/create/models/block/lime_nixie_tube.json
952d292d4dc2158e6106c5079cfa1ddb81c7777e assets/create/models/block/lime_postbox.json
5a95a72444f523cfba6e8c5adf8eacbb37e2d21e assets/create/models/block/lime_sail.json
09e7bf50cf88c449dbd9e77829cdb5afffb7d88d assets/create/models/block/lime_seat.json
b92822a01e4fbed2463b1bdf7dcc736023988e20 assets/create/models/block/lime_toolbox.json
@ -1213,7 +1180,6 @@ b92822a01e4fbed2463b1bdf7dcc736023988e20 assets/create/models/block/lime_toolbox
a1a3804ddcb1db0a7b5c0693555f8eb326950dd0 assets/create/models/block/linear_chassis_top.json
f885acc0ba705cfa9c65b62626ab4007f3b6e329 assets/create/models/block/linear_chassis_top_bottom.json
2f040681214af58a97e70d3a6e77a0fc2e02c624 assets/create/models/block/magenta_nixie_tube.json
bfea3fd456f92391afc9f948ade90b16275e63de assets/create/models/block/magenta_postbox.json
81122f26a12b7ab40fed6d31c97376f4dfffa111 assets/create/models/block/magenta_sail.json
b5cd13b021400b3c37499ec4ef22e560c721ac54 assets/create/models/block/magenta_seat.json
d7b2b16ba2d6a0b2441aeaf7faa76f61fbdc35e7 assets/create/models/block/magenta_toolbox.json
@ -1238,7 +1204,6 @@ af50363d603d61340b336569d58c1febde253665 assets/create/models/block/ochrum_natur
d69effa0a811cb93fead8257bcaad4bbf0094002 assets/create/models/block/ochrum_natural_3.json
24669a4e93925940477fcfc0aca10ab9d87368e0 assets/create/models/block/ochrum_pillar.json
c8dd33a0b71dce37712788a61729de89574b117f assets/create/models/block/ochrum_pillar_horizontal.json
dbd0cbfa1c6cfaddd7ac954379b4b1f3056730f2 assets/create/models/block/orange_postbox.json
cb4cd4e4bfb0d105a09c56454abf4795b155d12b assets/create/models/block/orange_sail.json
6c4addc75fb03911fca3083f891b22f55209b8db assets/create/models/block/orange_seat.json
f68eeb8cd828a0659fe8665373daf093ea65f0fc assets/create/models/block/orange_toolbox.json
@ -1266,7 +1231,6 @@ f70f83cfec770879c478eea3760ea187700f2878 assets/create/models/block/peculiar_bel
b9c9d00b844ca2f217ae21cc502cd4d082fed2d5 assets/create/models/block/peculiar_bell_floor.json
f7b09c243cfeda8bb38a29a917b9fbdafe47eece assets/create/models/block/peculiar_bell_single_wall.json
2f040681214af58a97e70d3a6e77a0fc2e02c624 assets/create/models/block/pink_nixie_tube.json
084266ced8975953fa158fd9e7261d8f10b94db7 assets/create/models/block/pink_postbox.json
90113a1f53f0f8d9ce11ff14128eb860063f5ddc assets/create/models/block/pink_sail.json
888dba067e751a55205dbd919db8e92ef2be604d assets/create/models/block/pink_seat.json
3cb69299c7787f88fb41c6397362aa7b607c0960 assets/create/models/block/pink_toolbox.json
@ -1421,11 +1385,7 @@ b21ec7cde56398b65f44922ddb026d9adb7b6072 assets/create/models/block/polished_cut
66374fdc4d3d55f99b03e406f3b594f8b1bab94d assets/create/models/block/pulse_repeater_powered.json
6bd0d85ca18b468bee279e7bc398bc8395e33a8b assets/create/models/block/pulse_repeater_powered_powering.json
de0cc956e7ff1510d0947ca8fd2b6e642944f0ee assets/create/models/block/pulse_repeater_powering.json
addbe93af945ff7ca2680a27225db804d3ac9b46 assets/create/models/block/pulse_timer_powered.json
ab3d7e10abcb53b835d6f5c406b7a777a942d6f7 assets/create/models/block/pulse_timer_powered_powering.json
7b425d9db8d914b52b7faad2f792c020b678f84d assets/create/models/block/pulse_timer_powering.json
2f040681214af58a97e70d3a6e77a0fc2e02c624 assets/create/models/block/purple_nixie_tube.json
afdd265ee175c47ea6e4e44fb08d212e4cef5ee5 assets/create/models/block/purple_postbox.json
356378a5839b0b400aa5e0a67740634113c09a38 assets/create/models/block/purple_sail.json
bc8e473a5662b6180b00b85e5006241a283c9baa assets/create/models/block/purple_seat.json
5e85ec98c165a0b5bfe25d391e96df9164372a3a assets/create/models/block/purple_toolbox.json
@ -1439,7 +1399,6 @@ ff65b89683fbb9326f625b9a68f954def5ed000d assets/create/models/block/radial_chass
9d234d1294f927d1e70a5c9b1e6de73ef65e7014 assets/create/models/block/railway_casing.json
be8042806b08990786ced1cf140c4942d7a6788b assets/create/models/block/raw_zinc_block.json
2f040681214af58a97e70d3a6e77a0fc2e02c624 assets/create/models/block/red_nixie_tube.json
844614001c30ef34d3136a350c12018c5e9ab341 assets/create/models/block/red_postbox.json
b692deeb65f338212fb1073b725a122b7b1359d5 assets/create/models/block/red_sail.json
bf3f4ba33e1a61254073ecee3e753958f8debb35 assets/create/models/block/red_seat.json
2a13766aebac1a392ae7bf934bd81d9210c87a24 assets/create/models/block/red_toolbox.json
@ -1697,13 +1656,11 @@ e26dd64495ff8801593e9c22203cbf364075badd assets/create/models/block/weathered_co
b658c1022587bd670b5acee267607719c1544332 assets/create/models/block/weathered_copper_tile_stairs_inner.json
e7ae89577be9d26a071bf96cbd7ed80293902b63 assets/create/models/block/weathered_copper_tile_stairs_outer.json
2f040681214af58a97e70d3a6e77a0fc2e02c624 assets/create/models/block/white_nixie_tube.json
998d838964c6c5bc2a1903b5098491abf5d819bc assets/create/models/block/white_postbox.json
99f0628623a36ac1700a5876cec010ee6353162f assets/create/models/block/white_seat.json
f252f8c68702a0c050797a2dc2a51c586408722d assets/create/models/block/white_toolbox.json
c9e344a06ee8bca1bfddd70481198135cabafbce assets/create/models/block/white_valve_handle.json
68d8eddfb724c73938862fb1a213a99c95814fdb assets/create/models/block/windmill_bearing.json
2f040681214af58a97e70d3a6e77a0fc2e02c624 assets/create/models/block/yellow_nixie_tube.json
9abbd0af47396b1cb18362b423f497ddb40eede4 assets/create/models/block/yellow_postbox.json
cf8477d6c7558ceba38416fae755567086a856a6 assets/create/models/block/yellow_sail.json
07b68f0e4c617dfe3e935a1b9e8e020ab3131c0b assets/create/models/block/yellow_seat.json
21bb6e0b43984214c496e531e16dd60aeb619a42 assets/create/models/block/yellow_toolbox.json
@ -1735,14 +1692,12 @@ def88cd2c79a1f0ed40bbf5a0332187dd1d6006e assets/create/models/item/basin.json
35a1e2cb2645a8386dfee2697b47547b3f9a1dd2 assets/create/models/item/belt_connector.json
f5dcb9096a52d5d2eab1e4204fbd1222e0d5094d assets/create/models/item/birch_window.json
eccafeec52e4195fbe211c602b4fc71a260d8a64 assets/create/models/item/birch_window_pane.json
641b85751f91c0b4931307548c12034fc56286bc assets/create/models/item/black_postbox.json
7ca635d45fef81e6681a492be6c7bb71fd0f4574 assets/create/models/item/black_seat.json
e2dc1a8db84d84d592bfd91a26464343b8706bc0 assets/create/models/item/black_toolbox.json
20fbeb136e85d146c0e041f7f1570b1d1fd34585 assets/create/models/item/black_valve_handle.json
c31038397821b6abe296d2799aa81edf3c12d095 assets/create/models/item/blaze_burner.json
9d28754112688323a6b55ecb6742e918eabfd6a3 assets/create/models/item/blaze_cake.json
01637416bb932d861e9c9b10b256b2fdf4c96d44 assets/create/models/item/blaze_cake_base.json
ef453775edb9342dc68e0e4ed7aa2e845b819fa6 assets/create/models/item/blue_postbox.json
de8beb7ef521822eb9b2826806baf1fa3344a45d assets/create/models/item/blue_seat.json
a82bc56a503cd15d2354c86a49fc6d1d4ed22767 assets/create/models/item/blue_toolbox.json
2f90f781cd9b5d144a6cfd4748ae3a87c9f12ba8 assets/create/models/item/blue_valve_handle.json
@ -1761,18 +1716,12 @@ a51a28424e75dbd11c845f455c778d4c578b9da4 assets/create/models/item/brass_ladder.
af97ba84be90381e2cc9434e31e2199c2e7e3aa6 assets/create/models/item/brass_scaffolding.json
b78e9274156f5027a9a3b6fb7725c57a7aecc8bb assets/create/models/item/brass_sheet.json
28e104d5041c1f4676704c0f6b4e2e80aac43106 assets/create/models/item/brass_tunnel.json
35c8539a0b2f927e65a43c3a2c3cb82db429c2eb assets/create/models/item/brown_postbox.json
fce64539b36fc8a5ffa39d7a3f73765818437cbf assets/create/models/item/brown_seat.json
90c1ec317beed0b5735c8731e3115a695b7060f7 assets/create/models/item/brown_toolbox.json
9477ab491586f1314bebf4d58387425ae56d0bad assets/create/models/item/brown_valve_handle.json
1db479848369140bb913ba09f3f1d994e4ac864c assets/create/models/item/builders_tea.json
f5ff4e2ed2ea2e43b6d02f6a95ba02b2e4b611dc assets/create/models/item/calcite_pillar.json
45d7fa87d102a0373a06a13592f58baafa4e5a33 assets/create/models/item/cardboard_package_10x12.json
f998f36d9a6f469bbd3822a17b2b45f81e6810c6 assets/create/models/item/cardboard_package_10x8.json
b7a24a7dd21a464815b2fd8cd6037e854be3f485 assets/create/models/item/cardboard_package_12x10.json
d5396690e7813c67ee3600555d7e47d0097b1f56 assets/create/models/item/cardboard_package_12x12.json
1cdb2b8801551c1540bb9b2a9cc3d725a2b433e7 assets/create/models/item/cart_assembler.json
390a06d81c8c2a0ff83196bd0154dd292206e3b6 assets/create/models/item/chain_conveyor.json
a197d08618f4035182c91a6b16031eb681ab8a7c assets/create/models/item/chest_minecart_contraption.json
293cfa8b1073f8641a2c623b73a90907576c36ed assets/create/models/item/chocolate_bucket.json
77654cbd16cdfa95181ea3f85fcfa3cd352b69fd assets/create/models/item/chocolate_glazed_berries.json
@ -1946,7 +1895,6 @@ f633006045ccfcdf486d7a240217229d6eed717e assets/create/models/item/cut_veridium_
410b949304faa5856028f7c42ab762b7498ffd95 assets/create/models/item/cut_veridium_slab.json
62697c0922b11537914d2f4f84faa0b909ee518d assets/create/models/item/cut_veridium_stairs.json
3921d61a26d48d999cbb2f6645611e53ea71978b assets/create/models/item/cut_veridium_wall.json
73c2eed9b6a906a519e27361211ae05bc6ed2d87 assets/create/models/item/cyan_postbox.json
eef3be2fa3b6424436a553e3c1bfee3979015962 assets/create/models/item/cyan_seat.json
265d5d6de4238442bb9b161dba0a2fc2f063df0b assets/create/models/item/cyan_toolbox.json
8beb6459822efe59d0f60749143d73c5390e39f2 assets/create/models/item/cyan_valve_handle.json
@ -1994,11 +1942,9 @@ b17d9fd1a92db0965f2e5da6215956b0451af29e assets/create/models/item/furnace_minec
7c850a41a754e46bb9c9f257ed621e37a1b9506a assets/create/models/item/goggles.json
b1ae37998326c8ca054e57b0cbff0b51cad98625 assets/create/models/item/golden_sheet.json
85c301898775d5720d4d11c1c555b331a5c2e93b assets/create/models/item/granite_pillar.json
44173ca711aa497d08ca3b8a9613290378072870 assets/create/models/item/gray_postbox.json
b8d6d2d163e2ab5f654bbc4eda9ad63f8064d27c assets/create/models/item/gray_seat.json
6492f86b693f924d0222d0ca1d16fbe33d797b1a assets/create/models/item/gray_toolbox.json
2a9500f9630b1da44615c7c9ca145b56324c46bb assets/create/models/item/gray_valve_handle.json
1a97f63df2977ac2f2e3363c61a7e36bf60d3ce3 assets/create/models/item/green_postbox.json
2843370b0e693e1ba1777c26416914edbd87c4f9 assets/create/models/item/green_seat.json
561e0579101bf602b252c0b9a5eec468c89d0e40 assets/create/models/item/green_toolbox.json
7d3ddad087b4d2c6a32f97092533cbfb5de0cb3b assets/create/models/item/green_valve_handle.json
@ -2015,7 +1961,6 @@ ae5c5925ecf775a4f5c3dc3c79d9766d7dd34ab6 assets/create/models/item/incomplete_tr
43173d18384817288a9ba687da77a4fab31b1957 assets/create/models/item/industrial_iron_block.json
c6e3e4ca8b3dfdaaa943faa3dc89c0b2e6f2b5c4 assets/create/models/item/iron_sheet.json
d1fbf1be53208c3ab5384dfd6be4d980c858941c assets/create/models/item/item_drain.json
5adda29ca25d00eb41884d0b7ad4a471e250ae10 assets/create/models/item/item_hatch.json
908dd0a4eafd868d280e25cfb7721f20b649560f assets/create/models/item/item_vault.json
5fba1fa33e360c2744ec74d7ccb63f9baa295546 assets/create/models/item/jungle_window.json
b3a0c9664465f49a2f53e4ded6c29710a357e6ca assets/create/models/item/jungle_window_pane.json
@ -2035,23 +1980,19 @@ a22638fd361a8185175e107a8ee092a9ac030b7b assets/create/models/item/layered_grani
14494272713544a1595d654fd397a986b2da0951 assets/create/models/item/layered_scoria.json
b1174d783c62dda84aafd4259c622197f4664421 assets/create/models/item/layered_tuff.json
952b07dbf9ecc1883deabaa1344667f13936f7f2 assets/create/models/item/layered_veridium.json
623c937db944651cf1075b3875afe002db527ed6 assets/create/models/item/light_blue_postbox.json
b44a9f1bd9079f3533d7f708d76eb19a864e5ebb assets/create/models/item/light_blue_seat.json
dae914625ff1bc3ebe1463485cad4526a7d7e9f5 assets/create/models/item/light_blue_toolbox.json
1d94314f185151eb9dcabcef950abf6f86c3c836 assets/create/models/item/light_blue_valve_handle.json
b56a28924b0b1b2530ebac7834e011700b09b966 assets/create/models/item/light_gray_postbox.json
1747bcdea3b1d3f5dfb786102069e07198d36dfe assets/create/models/item/light_gray_seat.json
c8513eb1c89652783e26d7dcfcf64afa97619bc8 assets/create/models/item/light_gray_toolbox.json
3774d23e76b5712e7004e333e0a770f2230c2998 assets/create/models/item/light_gray_valve_handle.json
8f53caad3899a30be5087a0ba155080834418cc0 assets/create/models/item/limestone.json
fba1e7d1cad39c89976b427db62544d80f47ad5d assets/create/models/item/limestone_pillar.json
26b8e1daf9cc4b206fb5f62904c7f1701ba93e67 assets/create/models/item/lime_postbox.json
32cd55a1c97a31a13ad106a457ec9925aa91f6d3 assets/create/models/item/lime_seat.json
931d187c11cb95a0eeae8f256187ef551b42007e assets/create/models/item/lime_toolbox.json
d0f4148bdb0a905e68f54b5dfd829fd47e528fea assets/create/models/item/lime_valve_handle.json
1d30f9b525e8e9736b34a92f848e235c71fd6bd8 assets/create/models/item/linear_chassis.json
8f622f5f79446f6060d9e8815205fce919c8c829 assets/create/models/item/linked_controller.json
538e28af9013a43c258a659cbe67671991f3eee7 assets/create/models/item/magenta_postbox.json
ad6fd371ee989c9c3c21e762273e8a4e903f0af8 assets/create/models/item/magenta_seat.json
7c0e3f91e5ab029473736deffb2b2aab9d4763c7 assets/create/models/item/magenta_toolbox.json
6d82582e5afea919927606b20a74cbda5223956f assets/create/models/item/magenta_valve_handle.json
@ -2085,7 +2026,6 @@ f80358eba19bc8d1741e4e25753866799631a118 assets/create/models/item/nixie_tube.js
061587faf0e53e4fac0c8f2f3bd6b22020b2a3ee assets/create/models/item/oak_window_pane.json
af50363d603d61340b336569d58c1febde253665 assets/create/models/item/ochrum.json
62ec1afee14f9de3f5b02ee930d002a240a3c337 assets/create/models/item/ochrum_pillar.json
226f99c241b1d8b03d8fc57db32c1bee0721b64f assets/create/models/item/orange_postbox.json
56e7d28824d3fc566b5f551babbe423a550ef08c assets/create/models/item/orange_seat.json
96cc543d5afed90a022ece7b8671cd47a9b6fb68 assets/create/models/item/orange_toolbox.json
7e767ca9e0ddb769b38fabd9289648ac63f5413d assets/create/models/item/orange_valve_handle.json
@ -2097,12 +2037,7 @@ c9c7ccdb68de2e77cd9f7053fab19493dd30a985 assets/create/models/item/oxidized_copp
1c3428e2aed32a013631db012642a34d4eaf0785 assets/create/models/item/oxidized_copper_tiles.json
f1af7c5f3840efc3ae07940ee6719eb3417a0e1a assets/create/models/item/oxidized_copper_tile_slab.json
ef2fe68d407a03bf1ed8f2d2f3e7323777d061bb assets/create/models/item/oxidized_copper_tile_stairs.json
b21a1f3ee7de3e17f69d27fd13ae6b23b62aa22c assets/create/models/item/packager.json
a8538df19e47fe37401c9fbedbb867b5d612a51b assets/create/models/item/packager_link.json
5b974e55caffdbfc2156eb8b59dd99db12243bd3 assets/create/models/item/package_filter.json
7fd76e7d2e6c6d94352f1fa08d096b63616ad01e assets/create/models/item/package_frogport.json
76aeceb41bb7df873dbafe1bd5e26deb24abf93f assets/create/models/item/peculiar_bell.json
ab6c05a0468f3f4295a07adb362fa2d36cf6e3e8 assets/create/models/item/pink_postbox.json
df13d4281dc45041ecd93504d45daef61d070581 assets/create/models/item/pink_seat.json
842afb2a345dbaba857e90f7dffa724841ef7b2d assets/create/models/item/pink_toolbox.json
6b85a0da81b2d18fb54eb05e187a2ce8cd7b09eb assets/create/models/item/pink_valve_handle.json
@ -2175,8 +2110,6 @@ bd70b798ca9f73f4e5aabc30e286487f5363122e assets/create/models/item/precision_mec
d9a736e7a6fc70e0848de3e318c739d58b1e563f assets/create/models/item/propeller.json
9b41eec5759887be9bae3d27654bf478a7eff676 assets/create/models/item/pulse_extender.json
ea76bd3bd9e5bea4d64d91347d473b538e926b02 assets/create/models/item/pulse_repeater.json
6ff9ce0cc633ea39b779b2e873a1d0fd7cfe7119 assets/create/models/item/pulse_timer.json
8496f6c5449a70eef12e9c68ba46eee2f365fb77 assets/create/models/item/purple_postbox.json
7e165f83266edf34bb03fa3e8d2a83d44829c10a assets/create/models/item/purple_seat.json
d75c4969334f2ee1ae4a3d8ac28b001735c76b97 assets/create/models/item/purple_toolbox.json
ebffb05119f499fcec051a4337aadc47654baed2 assets/create/models/item/purple_valve_handle.json
@ -2186,8 +2119,6 @@ f91405b9aec1e0142c1b90582e03a1973251da05 assets/create/models/item/radial_chassi
4631d67976cef148c346a7016baaa6703e4f243e assets/create/models/item/raw_zinc_block.json
9dc6c52e258b00cac6ed23147983045c43218b5d assets/create/models/item/redstone_contact.json
f8f733364bdd32b2ad597e81103bc02344ce63bd assets/create/models/item/redstone_link.json
f526dee8bc213b3d87cbc79350eb37b61b0eee79 assets/create/models/item/redstone_requester.json
4b73ee9cc2651a3d1a97476d100f9c4d7e2b2efe assets/create/models/item/red_postbox.json
8d00eb1a10055a802556eab10e13f522d12acd1c assets/create/models/item/red_sand_paper.json
b64a054c92cbd2e055502d470f3921d1077e63a1 assets/create/models/item/red_seat.json
ac4695cc465d094b4adba1a4e9efec42c916f37d assets/create/models/item/red_toolbox.json
@ -2284,7 +2215,6 @@ b82ab0c69df330f6f938ed1beee7b4add67d2e50 assets/create/models/item/steam_engine.
54f200be903e056e5cf9e2186f0a0a51f8f0f84e assets/create/models/item/sticker.json
0f88de164439640cc175ceef2017f7416b5a7018 assets/create/models/item/sticky_mechanical_piston.json
4b640b66765b206f8c2884b7c1a1ef860b81d841 assets/create/models/item/stockpile_switch.json
67c98c6c7f2122850acfbee34688572934fdd226 assets/create/models/item/stock_ticker.json
6ee792277b9fd980c40e18e841afa63fc500ed0b assets/create/models/item/stressometer.json
8d4ce1ccf180016506292f63188c10d0dabe0ee3 assets/create/models/item/sturdy_sheet.json
a10bb4d6d1a4483a806e3aaa086d48c0e20aaefe assets/create/models/item/super_glue.json
@ -2343,7 +2273,6 @@ dadc7b65a4527e288c21a20df978796a8c444fd2 assets/create/models/item/waxed_weather
79431edb868e6560f4f6d5b3441c0176c7699f5e assets/create/models/item/weighted_ejector.json
0fd2214cdff8a92e05d9d5ee888329b3235143c0 assets/create/models/item/wheat_flour.json
aacced59d21212090d508a9684bb46c9472a8a2f assets/create/models/item/whisk.json
bcf3104e463ec212dc239281033e4e80d78e1d74 assets/create/models/item/white_postbox.json
4e112e82185e2c1a5c57f5a94fa11c59c92cef0d assets/create/models/item/white_sail.json
17ed8ac7d745117f622190a46c5e1b42892afc29 assets/create/models/item/white_seat.json
432040f39177ab3df6003df24e818c73e28cf754 assets/create/models/item/white_toolbox.json
@ -2351,7 +2280,6 @@ bcf3104e463ec212dc239281033e4e80d78e1d74 assets/create/models/item/white_postbox
bccccbdfa5d376936e123defa44f2907dc317617 assets/create/models/item/windmill_bearing.json
47c6ad1c146366156a0ec4bc1cbf74282784698f assets/create/models/item/wooden_bracket.json
6c08d2fa59e56e4848063ab6f3e45894b89f1744 assets/create/models/item/wrench.json
3a899db3044ee39ac5d6385c16630733e00f77ca assets/create/models/item/yellow_postbox.json
ac59f141cd3c3f7e57a794e542d6e22bf8ebb8f9 assets/create/models/item/yellow_seat.json
532a429d58a177f61b4d67180db7676fa7536052 assets/create/models/item/yellow_toolbox.json
2c87ef8a26a01a17b2f3799d62cb27cf1107d061 assets/create/models/item/yellow_valve_handle.json
@ -3040,14 +2968,12 @@ d964b7a8f6a4ce28ce640d31a01e77eafcc181e5 data/create/loot_tables/blocks/belt.jso
a268eb02c10015a901a6543595b2b815a8026d78 data/create/loot_tables/blocks/birch_window.json
43d16eae230de501c528f4e9af666f72a081ed29 data/create/loot_tables/blocks/birch_window_pane.json
4aec2374e76dfa5535fe22b1fc02b4b2d453217d data/create/loot_tables/blocks/black_nixie_tube.json
6ed685605e24af5c6ff5d797dde8492069427b76 data/create/loot_tables/blocks/black_postbox.json
7ce6dd2c0d02eb1b56ec441044dfc608ea6bcb41 data/create/loot_tables/blocks/black_sail.json
2449b8c173fbbc2a96e0b8d1996d72fb60527e64 data/create/loot_tables/blocks/black_seat.json
2d33e25b2741f634bbd6cd77b31c17dd94511d94 data/create/loot_tables/blocks/black_toolbox.json
f911ac185cd48afa2393d24f28a688936a9fa147 data/create/loot_tables/blocks/black_valve_handle.json
eee41c02c8cfcdb56f31e74fc266783b785bea9d data/create/loot_tables/blocks/blaze_burner.json
247d12823eed3b9248003aca8e3ead87972ac61e data/create/loot_tables/blocks/blue_nixie_tube.json
76217732c9bddf77b7de735b4380d9f92adca9b3 data/create/loot_tables/blocks/blue_postbox.json
bb9d906a97810ed1461ed321ef8e4bee1dd104fb data/create/loot_tables/blocks/blue_sail.json
833fe6bc3020055dd0d6f46b324cbe27b248708d data/create/loot_tables/blocks/blue_seat.json
9d22716d9d846dc9587e327dfcdf18dd5955f826 data/create/loot_tables/blocks/blue_toolbox.json
@ -3065,14 +2991,12 @@ e466a397f84957616f7e83954db2050355f052c9 data/create/loot_tables/blocks/brass_en
429d524c9848b44d19028126f0efd678e0c4b680 data/create/loot_tables/blocks/brass_scaffolding.json
af90102bfe0e3a14bf1330cddec553f27b8fba89 data/create/loot_tables/blocks/brass_tunnel.json
d391cff5b741fd6ddf5b6fa64e05526eb3a9f0d9 data/create/loot_tables/blocks/brown_nixie_tube.json
bfa0365507a888134c20b36af4bd7944263687f0 data/create/loot_tables/blocks/brown_postbox.json
862bd3ceed05ea45c03911bb8403817b73c4bc38 data/create/loot_tables/blocks/brown_sail.json
6ddbdd489120be56f50272c86ecdb886afa3a8e4 data/create/loot_tables/blocks/brown_seat.json
588ae3d0da73eed3bc30cb28c583e7f8312d15bd data/create/loot_tables/blocks/brown_toolbox.json
7c7cf4c30786f6e0a699e2b3f9120343e53107f4 data/create/loot_tables/blocks/brown_valve_handle.json
06d1c478e4236210aa12b5911691868fef33bb5f data/create/loot_tables/blocks/calcite_pillar.json
515c839deea520b07b03f7ba65c4a7b22fdf5ba3 data/create/loot_tables/blocks/cart_assembler.json
aadd8aa7f8433896bd4fea56f43e496cbc5be25a data/create/loot_tables/blocks/chain_conveyor.json
fb4877d45df15be1a74378ab28f23fbf9d0657ef data/create/loot_tables/blocks/chute.json
ace9255cbdd1af5e5068916d2a6bed2f861f81f1 data/create/loot_tables/blocks/clipboard.json
bfd871acdde6c239098ead188a5aad7636d11bc0 data/create/loot_tables/blocks/clockwork_bearing.json
@ -3221,7 +3145,6 @@ d9552e3e9f4de0e09df8ca9446066e94c6e2c681 data/create/loot_tables/blocks/cut_veri
4845f7127921c7dd93a59118e63c37107d6c2061 data/create/loot_tables/blocks/cut_veridium_stairs.json
b56caea031d637321eddfd5d122fc357d2c2e49c data/create/loot_tables/blocks/cut_veridium_wall.json
ffb440a03f5e513b8d20c2725a95dc5c9b84c73b data/create/loot_tables/blocks/cyan_nixie_tube.json
914146303ae7e73c4f9283ea61cd5443f49f5cde data/create/loot_tables/blocks/cyan_postbox.json
8858b4e1b4e51889b2006005585a17e4978ed8e9 data/create/loot_tables/blocks/cyan_sail.json
8dccecb2c87d7421efdfb3fb97ae62b79f0b4411 data/create/loot_tables/blocks/cyan_seat.json
66ea2f2cc32d49bb434f83cbd07736d6fbacacf3 data/create/loot_tables/blocks/cyan_toolbox.json
@ -3264,13 +3187,11 @@ a4c86e5456bbbcc417d736151ac6a15c944d555b data/create/loot_tables/blocks/gearshif
ffa2776989447e44fa10673986961ab395ebd592 data/create/loot_tables/blocks/glass_fluid_pipe.json
07d8265c285ebb69b9160d516905ae1f17acc87d data/create/loot_tables/blocks/granite_pillar.json
41feb0f235495384ebca5b6f70d01b6f0c0c8878 data/create/loot_tables/blocks/gray_nixie_tube.json
6f123d5e6612274223ddb695e582abd952d3521c data/create/loot_tables/blocks/gray_postbox.json
bd526fc4f0acea571c37b2ecbb7267fee6be29f0 data/create/loot_tables/blocks/gray_sail.json
5e23e2032f92737eaa6e6cfb4c62232566f06e77 data/create/loot_tables/blocks/gray_seat.json
6ff8b3e59ea98697b87e71eb64d1e6f7e4631f36 data/create/loot_tables/blocks/gray_toolbox.json
aa0d47422e0adc3fb18e5c0eefd25c417ddbf9ae data/create/loot_tables/blocks/gray_valve_handle.json
4cfbe1bdc89916f78f891b9dbaed461cd838584b data/create/loot_tables/blocks/green_nixie_tube.json
e99e3895a19faa928e40fa17fbfbda6d3566b1ed data/create/loot_tables/blocks/green_postbox.json
6c22cf8de05828af7979dc32d9e151297d551fe5 data/create/loot_tables/blocks/green_sail.json
fbd61c331d4fda692f0e7174aed5aed3652d3553 data/create/loot_tables/blocks/green_seat.json
703a285a5d47fcc13e6775040d45620db2ef5480 data/create/loot_tables/blocks/green_toolbox.json
@ -3282,7 +3203,6 @@ a206598562bcbc9e3bc10dbe12fb22974ee58fcc data/create/loot_tables/blocks/horizont
e65fae1b9b72cf2208696463fa20a82a4d64fb62 data/create/loot_tables/blocks/hose_pulley.json
34c239150baa92e03ca89430148560e1b7a1f02d data/create/loot_tables/blocks/industrial_iron_block.json
c22dea1941471be65c811cdc2ce7b77d2247e9e1 data/create/loot_tables/blocks/item_drain.json
528078b0cf042236d2cb0701fb55f41f54aa932b data/create/loot_tables/blocks/item_hatch.json
72b5a7288f7f54694df5f456e4ab4433bd38dfff data/create/loot_tables/blocks/item_vault.json
13bd1033991eb65354a9b9406fe638c357fea409 data/create/loot_tables/blocks/jungle_window.json
fe9c2629eb30393d2ae5a1f252b9732506ef9bef data/create/loot_tables/blocks/jungle_window_pane.json
@ -3305,13 +3225,11 @@ b4882fe056a8d03bddf7a8c4fa70ee06548e1743 data/create/loot_tables/blocks/layered_
7f9ea6bfcf8344018866013e12d23edf21f034e9 data/create/loot_tables/blocks/layered_veridium.json
54a876a52655d5c9c33325a7d07c7978d33adca6 data/create/loot_tables/blocks/lectern_controller.json
8a6153a0b5857c77cdac0cffcb22e30ae6181f3a data/create/loot_tables/blocks/light_blue_nixie_tube.json
27bbda185ab99cff4974e6bfc40b72265896ef42 data/create/loot_tables/blocks/light_blue_postbox.json
304072298d4078eca7e0fb8c58ea3144afe246a8 data/create/loot_tables/blocks/light_blue_sail.json
a1396be526ef27c6d0f97cdd0f0e61f810e7353b data/create/loot_tables/blocks/light_blue_seat.json
0cd56baf9f3c9edb97e4ce892d374e21a099374f data/create/loot_tables/blocks/light_blue_toolbox.json
bf4e6c308d82f15689406b5b3e88fe95d49a9a44 data/create/loot_tables/blocks/light_blue_valve_handle.json
6928acbfcafdfead9750be6760da163b86532054 data/create/loot_tables/blocks/light_gray_nixie_tube.json
eb95d1e0abb93d5efecb0809e3901f37021c4dfc data/create/loot_tables/blocks/light_gray_postbox.json
886ef98e4bd60d8860b56441da6928e24f262d70 data/create/loot_tables/blocks/light_gray_sail.json
1ae0ff25ac9468e67ab1847b87a37829328d4c84 data/create/loot_tables/blocks/light_gray_seat.json
e22dfadefcea50090efe87136a4b92e6ef20d379 data/create/loot_tables/blocks/light_gray_toolbox.json
@ -3319,7 +3237,6 @@ e22dfadefcea50090efe87136a4b92e6ef20d379 data/create/loot_tables/blocks/light_gr
c6bb0877c537dda15469934383dc45c608bfd1a4 data/create/loot_tables/blocks/limestone.json
49058a62e1abd34917f983b6bc13cc4353b613a2 data/create/loot_tables/blocks/limestone_pillar.json
582bb26f6df37d0c2dbe12983ad05fc74f5fb5c0 data/create/loot_tables/blocks/lime_nixie_tube.json
ec9d973d218b26d51b82f265603feab31170c619 data/create/loot_tables/blocks/lime_postbox.json
623ac65211a9920325308b55285f78e3b7275751 data/create/loot_tables/blocks/lime_sail.json
7efe69664a781b292f491d5ff89e27dd5991f3cf data/create/loot_tables/blocks/lime_seat.json
0f6a465501a445925e9aff7a4c84b3c8e2caa93e data/create/loot_tables/blocks/lime_toolbox.json
@ -3327,7 +3244,6 @@ ec9d973d218b26d51b82f265603feab31170c619 data/create/loot_tables/blocks/lime_pos
baf70f9eb579f20b232a2af4e6b00a54f84844e6 data/create/loot_tables/blocks/linear_chassis.json
e4c0f8ca822cf7555bd011825b430c3c735160d4 data/create/loot_tables/blocks/lit_blaze_burner.json
6bd8b044cc9c69a5268372e5436f556da2c1bf21 data/create/loot_tables/blocks/magenta_nixie_tube.json
601bc43286b9f6b978ae8681281bf8e195f8211d data/create/loot_tables/blocks/magenta_postbox.json
b4d06c9ce7fbec0f23bb6dbc446b77d070f06775 data/create/loot_tables/blocks/magenta_sail.json
300e480d8e43e3a4ca19a92ae1360c02f7c5accd data/create/loot_tables/blocks/magenta_seat.json
40d2ba0a52eaa2c61900731f0cee2657c5e77c20 data/create/loot_tables/blocks/magenta_toolbox.json
@ -3360,7 +3276,6 @@ fe79cb4cbea87efc84d61d3d31f073bf3c64c73d data/create/loot_tables/blocks/netherit
5dcb11160a51ce17fb06f5fecc14e87d92b1a641 data/create/loot_tables/blocks/oak_window_pane.json
461e9818f41aab34905757a423455cdcee780e67 data/create/loot_tables/blocks/ochrum.json
1259a439286385d5b7c48bff89d0839f1f2e02c2 data/create/loot_tables/blocks/ochrum_pillar.json
3f6940f13ca705bad7cdb9a9b80a3ae84f70f80c data/create/loot_tables/blocks/orange_postbox.json
d6323d4b30faa87cd4b5b8b815cb16f78296f203 data/create/loot_tables/blocks/orange_sail.json
119fc4c3055c09c7958ac405925a6b7be2081c6b data/create/loot_tables/blocks/orange_seat.json
54ac8c8166c23f24a8a0870c981ef8ffa64c0b89 data/create/loot_tables/blocks/orange_toolbox.json
@ -3373,12 +3288,8 @@ f47a01824093455030fca66e7b8a39bcfc61d219 data/create/loot_tables/blocks/oxidized
4d2a2863697664b3b71f02aa703c3504cd5cc826 data/create/loot_tables/blocks/oxidized_copper_tiles.json
4d815b361af81bd0c0e14c853ca54ad3cde66a57 data/create/loot_tables/blocks/oxidized_copper_tile_slab.json
d599ef03d1b69e4367ec0dea78f52c1964c99f9b data/create/loot_tables/blocks/oxidized_copper_tile_stairs.json
ab8cee7abd7dd92428bf7d8f0f5edd35082401a4 data/create/loot_tables/blocks/packager.json
e5df1b8ead9e575ed06f2040a7c9cc72c7a71b49 data/create/loot_tables/blocks/packager_link.json
54aa9700df601640b705d912abe773d5b6ee2b1f data/create/loot_tables/blocks/package_frogport.json
58bd9fe9d6706998bfbda3b077cfd0a740972091 data/create/loot_tables/blocks/peculiar_bell.json
4d7724df6fefee4512c4f7886d0e103d1dc39510 data/create/loot_tables/blocks/pink_nixie_tube.json
df7b12349c64d035eb563535b03cb70d780c5a71 data/create/loot_tables/blocks/pink_postbox.json
85811771fbc36f645fdb9f510639715399503c99 data/create/loot_tables/blocks/pink_sail.json
9a5652002131d14c585a6e434a4457ef36d2f60d data/create/loot_tables/blocks/pink_seat.json
23e28971460b2a3b8b39412a4778672d7ced4af7 data/create/loot_tables/blocks/pink_toolbox.json
@ -3449,9 +3360,7 @@ afe84b9468fba532acc447236a9a0cbdd02c4560 data/create/loot_tables/blocks/powered_
fbc433a7e8518860bc828a52b56dba92e4dff66c data/create/loot_tables/blocks/pulley_magnet.json
e654e6cedc0373e97caea947e7e605bc4095da88 data/create/loot_tables/blocks/pulse_extender.json
422385f062dd63edaf246c42fb0e617e92e6cc44 data/create/loot_tables/blocks/pulse_repeater.json
93f0c41aedaa2b9baceda78b93a4b3198962e3f9 data/create/loot_tables/blocks/pulse_timer.json
6f453ea136098a5872aeb4e2ad1e5b78d2fd571f data/create/loot_tables/blocks/purple_nixie_tube.json
53e964048baa1b98877a559e8fda6c8f367d5cd6 data/create/loot_tables/blocks/purple_postbox.json
c6b7a02db55cf0824a48156adf469c478dfd6a8d data/create/loot_tables/blocks/purple_sail.json
73cd7cc36fafb491666d2bccf1b4f24624b3c8f2 data/create/loot_tables/blocks/purple_seat.json
147086b9db173aed1b25d9460d0135708dcebcf9 data/create/loot_tables/blocks/purple_toolbox.json
@ -3461,9 +3370,7 @@ c6b7a02db55cf0824a48156adf469c478dfd6a8d data/create/loot_tables/blocks/purple_s
f76e5a157d2aeab5708f464b1f3c8e47b3855f18 data/create/loot_tables/blocks/raw_zinc_block.json
bbc2d61eeea335f8f011d799ef6a5484ca027640 data/create/loot_tables/blocks/redstone_contact.json
4fa70deeac7e56121e42fb602dfa27ee1727f749 data/create/loot_tables/blocks/redstone_link.json
efc3a5595e4daf67fa43f84c9869dfc76fd6fca4 data/create/loot_tables/blocks/redstone_requester.json
a50e1c28af16e9f1b4f48aa974461167139768a7 data/create/loot_tables/blocks/red_nixie_tube.json
f36f1e69e4fb8723238f81aadbac892f54b5ac62 data/create/loot_tables/blocks/red_postbox.json
977d724cddf8eba053a3310ad0d30af15199bbed data/create/loot_tables/blocks/red_sail.json
9aedede893e2127a1cdd17695699397d8d5c6ce5 data/create/loot_tables/blocks/red_seat.json
9713071cab536e8c1550a6309dc4563fecc2c4e0 data/create/loot_tables/blocks/red_toolbox.json
@ -3556,7 +3463,6 @@ cae1bd9100b62841e260880faa80e2442f44a141 data/create/loot_tables/blocks/steam_wh
0bc3fdde351129e3a261a2420aff9d3f063c235e data/create/loot_tables/blocks/sticker.json
074f526902cb5fcff2129614428aba1ea05a6649 data/create/loot_tables/blocks/sticky_mechanical_piston.json
a7332324e63f7d28621ddfbd54eb3d091461d890 data/create/loot_tables/blocks/stockpile_switch.json
f4fa9bb255348dc79dcc0468b3beb9ad075eb036 data/create/loot_tables/blocks/stock_ticker.json
b13496b1b4bc0be30605832e23894fb374dd796e data/create/loot_tables/blocks/stressometer.json
6a7df4d2730d57ae6e404b4bc8e01367e5ddbf07 data/create/loot_tables/blocks/tiled_glass.json
0ad584e41780dc0183af1fa1e49e126730dfdbab data/create/loot_tables/blocks/tiled_glass_pane.json
@ -3608,7 +3514,6 @@ d6862dc9f7d291df618fbce71eebf613711a5517 data/create/loot_tables/blocks/weathere
57d5065d53016e4b1ef0fbad9b84605b1546bcc4 data/create/loot_tables/blocks/weathered_copper_tile_stairs.json
f6ba0623b4bcea2f3796df4c65c494fc072d2c21 data/create/loot_tables/blocks/weighted_ejector.json
978263272f632ed79a61d52a0080de0b7b8102d6 data/create/loot_tables/blocks/white_nixie_tube.json
3d8a4d4a9634d49b20f65ebcdddaef2d0f21b36b data/create/loot_tables/blocks/white_postbox.json
129c6772c1c12271f9b0d41c77f41ce34fc437b1 data/create/loot_tables/blocks/white_sail.json
84c79bc47b4a74021e91745356bb24fe02402209 data/create/loot_tables/blocks/white_seat.json
3c63263c9fb642e34a0a67af4cab2d4348d661c0 data/create/loot_tables/blocks/white_toolbox.json
@ -3616,7 +3521,6 @@ f6ba0623b4bcea2f3796df4c65c494fc072d2c21 data/create/loot_tables/blocks/weighted
bf0ea5c6957a43b6c4b1914df70e0b8f6585e638 data/create/loot_tables/blocks/windmill_bearing.json
ed989d41a4b640dc1ffb15c9c0712ee3172d408f data/create/loot_tables/blocks/wooden_bracket.json
d9f853e662b004b6ffdbb82af99ad7e774698178 data/create/loot_tables/blocks/yellow_nixie_tube.json
a536699cab16540eb906e0b63a2c5064244c7b6c data/create/loot_tables/blocks/yellow_postbox.json
0ead61521fec15522633d6cfdeb77150bb30d075 data/create/loot_tables/blocks/yellow_sail.json
3ae6d4e380237face57b9187ab8570967226b3b1 data/create/loot_tables/blocks/yellow_seat.json
11b10beba7a6842ce3d01ea4210bff7d3aa6ab94 data/create/loot_tables/blocks/yellow_toolbox.json
@ -4278,9 +4182,8 @@ f675c20350ed60da4878b5d6301f02c8c05624bd data/create/tags/blocks/fan_processing_
4970078b49ddac1b1d500ed0469cedf42bdc3d35 data/create/tags/blocks/non_movable.json
06e13efbb7b0d09ff7ecd1a7dc45a0760b91ad67 data/create/tags/blocks/ore_override_stone.json
a5874f73c7dc0a3ae12999e6ae8abf45bc7fb9be data/create/tags/blocks/passive_boiler_heaters.json
f400870b8dbcd14238be3ec99c419093073ba3a6 data/create/tags/blocks/postboxes.json
9bc8c13fd80bdbe7f767b91ee1a1042e9aff02b0 data/create/tags/blocks/roots.json
55dccb895bbdacfbd6ee9005486cd3fe9df01249 data/create/tags/blocks/safe_nbt.json
79ed9149ee2ce143114db4ccafda8a2b6a293aac data/create/tags/blocks/safe_nbt.json
79418bd729cef417b322cef9b491e7ae83317d61 data/create/tags/blocks/seats.json
5def5088f7fd31b80e6f28c1c4ea146aa9d7d15b data/create/tags/blocks/toolboxes.json
2589b135c0e96ad29076569e144528fe32ea5b39 data/create/tags/blocks/tracks.json
@ -4305,7 +4208,6 @@ d371dfd35e49a7bef19f59c03e7f4ae20992f03d data/create/tags/items/create_ingots.js
0fa526e7e742573b603ad26b09526cf724efa1dc data/create/tags/items/deployable_drink.json
1cebeb92bd514b75d54ac6d5708047801f0501c5 data/create/tags/items/modded_stripped_logs.json
586f8fc5a8b8559c9dc0017e13c78ad918688fae data/create/tags/items/modded_stripped_wood.json
f400870b8dbcd14238be3ec99c419093073ba3a6 data/create/tags/items/postboxes.json
695d75b352fd190b303c724d1aaee9bb786a903b data/create/tags/items/pressurized_air_sources.json
2cd3adffd8b151354df137a990dcb97996a665bb data/create/tags/items/sandpaper.json
79418bd729cef417b322cef9b491e7ae83317d61 data/create/tags/items/seats.json
@ -4341,7 +4243,7 @@ de1fc89be6a52473d526d3efe0204b9b8489058c data/forge/tags/blocks/glass_panes.json
81b107ada9c6ac5679a21f8c6a006bf230f69c39 data/forge/tags/blocks/ores/zinc.json
e475ad1c52bffedfc544e5331a87c1f5c45149fd data/forge/tags/blocks/ores_in_ground/deepslate.json
2f6068972e364599b6849dc46fcb0724d4219d53 data/forge/tags/blocks/ores_in_ground/stone.json
8a5988e68f3a41341b486784c29d00e16d5272f7 data/forge/tags/blocks/relocation_not_supported.json
2589b135c0e96ad29076569e144528fe32ea5b39 data/forge/tags/blocks/relocation_not_supported.json
b3af02a6fa3dc41bc3f4db933485f22b202deea3 data/forge/tags/blocks/storage_blocks.json
7d10cdf9e46a79753d4437c7bb958e3ab8bf0c89 data/forge/tags/blocks/storage_blocks/andesite_alloy.json
70bba470740dc7a77f51b4cb1747a105b62d4bde data/forge/tags/blocks/storage_blocks/brass.json
@ -4395,8 +4297,8 @@ c741ba83b562ae3459d7c4f2db69537f549ea411 data/forge/tags/items/tools/wrench.json
515a1c773e617dd7e38aa1b893acc7db2dd30e08 data/minecraft/tags/blocks/dripstone_replaceable_blocks.json
e3321ff14704c031a2c16953b7e391f4f24dd70b data/minecraft/tags/blocks/impermeable.json
515a1c773e617dd7e38aa1b893acc7db2dd30e08 data/minecraft/tags/blocks/lush_ground_replaceable.json
5bfa11627f37364de2098753c85a589721cfa2af data/minecraft/tags/blocks/mineable/axe.json
1f8802b85d179bbd7f74ec37c6ffceb59eb4856c data/minecraft/tags/blocks/mineable/pickaxe.json
5a030817b2322e363edc8f5376f7c9de73df8b48 data/minecraft/tags/blocks/mineable/axe.json
d794a156fdc9ec9e7c935b3b8962206b7b82eb79 data/minecraft/tags/blocks/mineable/pickaxe.json
515a1c773e617dd7e38aa1b893acc7db2dd30e08 data/minecraft/tags/blocks/moss_replaceable.json
0c13aae0eeb99e89febe8dbe5e002af2ff843a9e data/minecraft/tags/blocks/needs_iron_tool.json
3cb2a92cbdf32ed5978f740dc378d363306c3e84 data/minecraft/tags/blocks/needs_stone_tool.json

View file

@ -1,4 +1,4 @@
// 1.20.1 2024-09-02T22:36:27.2861383 Create's Advancements
// 1.20.1 2024-10-09T12:24:59.1794112 Create's Advancements
2661a689fdcf729494f46e3c719f71c62e31582e data/create/advancements/andesite_alloy.json
fa16c4afe0496edc3f157858a6e0ff177a1622ff data/create/advancements/andesite_casing.json
5a694002d0a663bc869b09d15924a10c43dc522f data/create/advancements/anvil_plough.json

View file

@ -1,4 +1,4 @@
// 1.20.1 2024-09-24T12:18:51.3002838 Create Train Hat Information
// 1.20.1 2024-10-09T12:24:59.1824022 Create Train Hat Information
be16d47aa64e673b1107a36ce06475016e316fca assets/minecraft/train_hat_info/axolotl.json
b8ae6d9c8014439f4049622e0d6e79b9d6716260 assets/minecraft/train_hat_info/bat.json
5053a6c9fb412dfac1bf17eb0f57f9fd314198e4 assets/minecraft/train_hat_info/bee.json
@ -47,6 +47,6 @@ e524c61954660d3cb605f01395edb25572b59a1c assets/minecraft/train_hat_info/skeleto
b8ae6d9c8014439f4049622e0d6e79b9d6716260 assets/minecraft/train_hat_info/turtle.json
78950a0bb66d28d1939049400a8cfd194f92f906 assets/minecraft/train_hat_info/warden.json
5ed6eccda89a6721f1b70eca7e7869cfc30aa612 assets/minecraft/train_hat_info/wither.json
0e92893e2b9d3e6586610e4e13c678e11beb1e64 assets/minecraft/train_hat_info/wolf.json
0ac114bc3a5d0a0ab3153cae258a30fe970d4264 assets/minecraft/train_hat_info/wolf.json
daac75dcadb6e00db5cf1a5b30a450f137da54ae assets/minecraft/train_hat_info/zoglin.json
e524c61954660d3cb605f01395edb25572b59a1c assets/minecraft/train_hat_info/zombie_horse.json

View file

@ -1,4 +1,4 @@
// 1.20.1 2024-09-02T22:36:27.3630513 Create's Mechanical Crafting Recipes
// 1.20.1 2024-10-09T12:24:59.2726698 Create's Mechanical Crafting Recipes
f076d64d9f30709bed34775136c9241097b28aa9 data/create/recipes/mechanical_crafting/crushing_wheel.json
694dca9dcff246bb7f560b3304fcc244c53217d5 data/create/recipes/mechanical_crafting/extendo_grip.json
c03bc27f537e2d6531438bf58a17d977a7e16c7b data/create/recipes/mechanical_crafting/potato_cannon.json

View file

@ -1,4 +1,4 @@
// 1.20.1 2024-10-02T12:38:33.1742888 Create's Standard Recipes
// 1.20.1 2024-10-09T12:24:59.2686824 Create's Standard Recipes
a8cc4af26f6c7c45a9eef12e92af1452fe042454 data/create/advancements/recipes/combat/crafting/appliances/netherite_backtank.json
2c2639c7b307ee7c7a4e97e5efebf496788998ad data/create/advancements/recipes/combat/crafting/appliances/netherite_backtank_from_netherite.json
81dcf0cb1aa99e39bc7d1a386e07cad4cee7d8b9 data/create/advancements/recipes/combat/crafting/appliances/netherite_diving_boots.json
@ -7,7 +7,7 @@ a8cc4af26f6c7c45a9eef12e92af1452fe042454 data/create/advancements/recipes/combat
c1f2e6d1d955fb2d6d7ccc7a6d45d051bbcab315 data/create/advancements/recipes/combat/crafting/appliances/netherite_diving_helmet_from_netherite.json
6418408e9fe53c03eae1e2b17b2229a548abc226 data/create/advancements/recipes/misc/blasting/copper_ingot_from_crushed.json
d88c5c8b6751f389d9eea30acbd566c120e77705 data/create/advancements/recipes/misc/blasting/gold_ingot_from_crushed.json
c5eabab1b28eaf8d83007b303480f12d8c319c4d data/create/advancements/recipes/misc/blasting/ingot_aluminum_compat_ic2.json
ea97407030aed9f2da5720fe7f68dd0c87f68944 data/create/advancements/recipes/misc/blasting/ingot_aluminium_compat_ic2.json
2532dd0af4124639c26525b6c4bbaf8059132903 data/create/advancements/recipes/misc/blasting/ingot_aluminum_compat_immersiveengineering.json
6b62cf9551e30b3560349e8d905cd10b446a98fd data/create/advancements/recipes/misc/blasting/ingot_lead_compat_immersiveengineering.json
4568168d851832c9eefd177c64a2de9c40e9954b data/create/advancements/recipes/misc/blasting/ingot_lead_compat_mekanism.json
@ -40,7 +40,6 @@ b90af96817d6c38ec446f7464642a473a55c2027 data/create/advancements/recipes/misc/b
029e463d5eea7ae590577fdfab52664036727985 data/create/advancements/recipes/misc/crafting/appliances/copper_diving_boots.json
5d5b4c49e81090a48c23314c49815f61ac170518 data/create/advancements/recipes/misc/crafting/appliances/copper_diving_helmet.json
0746cb63e224d7620e781e1494b9a8b9d56b186b data/create/advancements/recipes/misc/crafting/appliances/crafting_blueprint.json
4bd1ab25286d5a9dce7cafd1f814113f21a6969d data/create/advancements/recipes/misc/crafting/appliances/display_cloth_clear.json
c4d0901541855ea2fda0cef7f0270edfa16d70e2 data/create/advancements/recipes/misc/crafting/appliances/dough.json
79b6501f8cb069dc55b78871a5fecf40a5b3dbd5 data/create/advancements/recipes/misc/crafting/appliances/filter_clear.json
3271ad36fbab51d87d0baad8c69cb7b2add506b8 data/create/advancements/recipes/misc/crafting/appliances/linked_controller.json
@ -170,16 +169,13 @@ f3e387ae41a55cdb5ff745f40e2ddb5e2595e9b8 data/create/advancements/recipes/misc/c
dc61a327753684a0d8a7bcc408d656b53ac633b1 data/create/advancements/recipes/misc/crafting/logistics/brass_tunnel.json
03c367840951af268047c407b15aad52f0b094b4 data/create/advancements/recipes/misc/crafting/logistics/content_observer.json
09454f1d4db813c89a0a2f3af966298fc5f7da7b data/create/advancements/recipes/misc/crafting/logistics/display_link.json
995aa09f4672405984988e445a1d97301c5c4389 data/create/advancements/recipes/misc/crafting/logistics/packager_link_clear.json
95b357cbac39acfbc68ac04d0d4681a4d91746ee data/create/advancements/recipes/misc/crafting/logistics/powered_latch.json
ef84b382bd4f6ba9558574f2c8e63030813594e9 data/create/advancements/recipes/misc/crafting/logistics/powered_toggle_latch.json
c443707391ce79dc1ec8cfacee74757b0c00bd3e data/create/advancements/recipes/misc/crafting/logistics/pulse_extender.json
77c3df89a06fc10cd8bd1cc35f0353441860ec11 data/create/advancements/recipes/misc/crafting/logistics/pulse_repeater.json
96b4998626e624fb79c79fb754c28b21ddc27254 data/create/advancements/recipes/misc/crafting/logistics/redstone_contact.json
1b50ed47c37e48d1112c76059574eed71ecea4e5 data/create/advancements/recipes/misc/crafting/logistics/redstone_link.json
cea78bc9b093a8a6a85ef1df53ddf11d9c37a114 data/create/advancements/recipes/misc/crafting/logistics/redstone_requester_clear.json
831588b3f29411d5c4b358006051152eb2b23e6b data/create/advancements/recipes/misc/crafting/logistics/stockpile_switch.json
1e0fc9f4971286a69d9706006bd8358931382c9c data/create/advancements/recipes/misc/crafting/logistics/stock_ticker_clear.json
cb416511a219d2bc5806c6880c01820a8b563b80 data/create/advancements/recipes/misc/crafting/materials/andesite_alloy.json
3b65a04da4e16442bfa8accfe209b7c5342b1db9 data/create/advancements/recipes/misc/crafting/materials/andesite_alloy_block.json
2715b888b6d96ee4c7208af21bb4dfb1a1bd544c data/create/advancements/recipes/misc/crafting/materials/andesite_alloy_from_block.json
@ -221,7 +217,7 @@ bb87cb8787644e20b3418d6f57726f2ca70b0aae data/create/advancements/recipes/misc/s
70342b3f5c5482caa82e0afcd559c7b200d9f247 data/create/advancements/recipes/misc/smelting/glass_pane_from_tiled_glass_pane.json
8635e2becb91b0e4e754fd79d231300492b8afce data/create/advancements/recipes/misc/smelting/glass_pane_from_vertical_framed_glass_pane.json
d76d08c3efcf9174ee2980796aa04c67fe9443eb data/create/advancements/recipes/misc/smelting/gold_ingot_from_crushed.json
6a53b4a956a5560dfa7a6ed3d3279fe502a45574 data/create/advancements/recipes/misc/smelting/ingot_aluminum_compat_ic2.json
5e222928aadd0a91f9996b0a104ec4b80646058c data/create/advancements/recipes/misc/smelting/ingot_aluminium_compat_ic2.json
1e88edf27ed1f83031f9d71cad8f3f4388f57b85 data/create/advancements/recipes/misc/smelting/ingot_aluminum_compat_immersiveengineering.json
2b6b739a2f0ad1f33db8090aa0e77c8149d67dbf data/create/advancements/recipes/misc/smelting/ingot_lead_compat_immersiveengineering.json
7392d585e5409438f70ddb43ebba58b35609265b data/create/advancements/recipes/misc/smelting/ingot_lead_compat_mekanism.json
@ -250,7 +246,7 @@ b8d5ef1eba4521441658d4c051861ecf9cc96102 data/create/advancements/recipes/misc/s
42f1375bf3004cfd891a5fbb05352f578636dd75 data/create/advancements/recipes/misc/smoking/bread.json
3c9dcf347eef42d0cca69ae5bc4a61fe90fb27c8 data/create/recipes/blasting/copper_ingot_from_crushed.json
cbd86c583643e65a0d9b7950dcf593cdf6d43d77 data/create/recipes/blasting/gold_ingot_from_crushed.json
053d94339f3b64e02b0eae56fe714b6f4a05986f data/create/recipes/blasting/ingot_aluminum_compat_ic2.json
4dccb0aaf5316c75f4dd03b497fb43bf20f7e279 data/create/recipes/blasting/ingot_aluminium_compat_ic2.json
5b1b7981636b211a956e37356423c2ba65c8042c data/create/recipes/blasting/ingot_aluminum_compat_immersiveengineering.json
f794d2eab3922ea7765866d473eb61c74a2678c5 data/create/recipes/blasting/ingot_lead_compat_immersiveengineering.json
7acb7c5bc88b238e914abc07f979c33f8d33123e data/create/recipes/blasting/ingot_lead_compat_mekanism.json
@ -283,7 +279,6 @@ b3c4585dc6ed9c4a38d7923ae399b88ab8912df9 data/create/recipes/blasting/zinc_ingot
c500139f545fea4568575b93b1ab9e56f004f137 data/create/recipes/crafting/appliances/copper_diving_boots.json
77b28e10fcbe223f8235b193e899046b382382c9 data/create/recipes/crafting/appliances/copper_diving_helmet.json
3e3f71d579ec7453e453d5b65aaee3c43169b679 data/create/recipes/crafting/appliances/crafting_blueprint.json
4516e2c533f753f9d3802ae3c9c1400866ad3a31 data/create/recipes/crafting/appliances/display_cloth_clear.json
b7c8f3c5e80749c6c38d5c0153dc68a79c32535f data/create/recipes/crafting/appliances/dough.json
409b5d70ee1ef9164c327d79472e6d66ce55dec6 data/create/recipes/crafting/appliances/filter_clear.json
265ead7993ae9e9b617dbfae749a77fed6b7b1ba data/create/recipes/crafting/appliances/linked_controller.json
@ -420,16 +415,13 @@ a24f11d979f40994b9f881b0f49fff5d93185296 data/create/recipes/crafting/logistics/
d994ef262b16357984d3ed62f6563d2f37266193 data/create/recipes/crafting/logistics/brass_tunnel.json
0b18d9964f2d580eb465cc72208f7a7fdba7b63e data/create/recipes/crafting/logistics/content_observer.json
cc837e8b014c121ed9d959baddea134ebf669350 data/create/recipes/crafting/logistics/display_link.json
5db046b432f184c6590c8e6adaf95adac6f0dc9d data/create/recipes/crafting/logistics/packager_link_clear.json
dd28b63ceb46a1e9071549c4f8ff32f520c667f6 data/create/recipes/crafting/logistics/powered_latch.json
9ee6e19644928dc78e6f8a5e59f30cd42ac3e454 data/create/recipes/crafting/logistics/powered_toggle_latch.json
aa8a704ad643ff5f06db34f4047f7f740a556236 data/create/recipes/crafting/logistics/pulse_extender.json
8b0b342baa18cc47c7a60a3c9812fece28210cf6 data/create/recipes/crafting/logistics/pulse_repeater.json
c81f852f1d1514184ff235e790a6ca907f7b6ad4 data/create/recipes/crafting/logistics/redstone_contact.json
00877e6b56f28d8691080ef18b654f0a141835ce data/create/recipes/crafting/logistics/redstone_link.json
8446b3ca07575ea978ddde4121900207d54be8b3 data/create/recipes/crafting/logistics/redstone_requester_clear.json
eff0d37e98e8badd8d2c3c9de17ee5560b110dbd data/create/recipes/crafting/logistics/stockpile_switch.json
38aa7b9b3c4724ec8b8d94f00a98d684110ad5ca data/create/recipes/crafting/logistics/stock_ticker_clear.json
ac524c110f66a7433208a888c5f3bb69e5e95743 data/create/recipes/crafting/materials/andesite_alloy.json
e6bb68a1d2ed5a629c83f5a0eefb843bb890736d data/create/recipes/crafting/materials/andesite_alloy_block.json
eebacb477bcce876622173289b06e1ad21424686 data/create/recipes/crafting/materials/andesite_alloy_from_block.json
@ -459,7 +451,7 @@ d849fafedd10c68e6bc6dc1e5a85be82aae1b139 data/create/recipes/crafting/palettes/s
9a687ee9dab44c439ab669aa596117064fb13457 data/create/recipes/crafting/schematics/schematicannon.json
4a20356c9ce01ebfbcacbdc5d3c31094a5599a17 data/create/recipes/crafting/schematics/schematic_and_quill.json
4a297162a630b48407dbc8ff8ca713387dcd3206 data/create/recipes/crafting/schematics/schematic_table.json
dd2b5bfb7ebd836e8b5639894736c226f2cac8c0 data/create/recipes/crafting/tree_fertilizer.json
2cf06129b47d1a2b733619514dc9e8cf1d8967f2 data/create/recipes/crafting/tree_fertilizer.json
78526658ca5ccaa3729c967b5283069945d183b7 data/create/recipes/smelting/bread.json
04bb0c80f3b5a6fe86fc4a8ed5293fc74c2d9aba data/create/recipes/smelting/copper_ingot_from_crushed.json
d5b29fa27977691c3c50eb36c28bfe33b8462d09 data/create/recipes/smelting/glass_from_framed_glass.json
@ -471,7 +463,7 @@ ab1a181eb787f501ae7b8a8c6da2d3adb35a8f2b data/create/recipes/smelting/glass_pane
ad412d18c2084dc74fff8a079a2e7ffb20f9a0c6 data/create/recipes/smelting/glass_pane_from_tiled_glass_pane.json
67c1143c7aac88a9cc91b98dbca60770cb1422a5 data/create/recipes/smelting/glass_pane_from_vertical_framed_glass_pane.json
461e4dede50a4a318281ae9c086c8094470e21a1 data/create/recipes/smelting/gold_ingot_from_crushed.json
ae05209f9f639c7709bb25d0ff5f09f1af6cffcf data/create/recipes/smelting/ingot_aluminum_compat_ic2.json
0ceeee303ca8993c394fc597cdd7c5ef44d84ad0 data/create/recipes/smelting/ingot_aluminium_compat_ic2.json
fa0d3d6f50d344aa83ddf4ac8abf4a80deb9fb32 data/create/recipes/smelting/ingot_aluminum_compat_immersiveengineering.json
4e8cf8775719219849b1a0e95903a3605b665015 data/create/recipes/smelting/ingot_lead_compat_immersiveengineering.json
cfa90e7ba56d1ec6caa11bd019244bddd51da841 data/create/recipes/smelting/ingot_lead_compat_mekanism.json

View file

@ -1,4 +1,4 @@
// 1.20.1 2024-09-02T22:36:27.3560692 Create's Damage Type Tags
// 1.20.1 2024-10-09T12:24:59.2656887 Create's Damage Type Tags
7884716b2f4bb1330ff215366bb4bab06e4728c2 data/minecraft/tags/damage_type/bypasses_armor.json
1fcad1f89265fba8bdb05b03a1dfcc88d7b7a550 data/minecraft/tags/damage_type/is_explosion.json
08324c61115b72bb8a6370d7f34d84d9a31afd16 data/minecraft/tags/damage_type/is_fire.json

View file

@ -1,4 +1,4 @@
// 1.20.1 2024-09-20T10:47:27.5889856 Create's Processing Recipes
// 1.20.1 2024-10-09T12:24:59.1833995 Create's Processing Recipes
3c94326fb730f68c1e44fe1e2ef09c9db6ffd92b data/create/recipes/compacting/andesite_from_flint.json
8d3d5b31f3601b9f681ff710e0545a483a1494c6 data/create/recipes/compacting/blaze_cake.json
8bd7f4e3a686ab520b2d55594d2018d0e9a50c91 data/create/recipes/compacting/chocolate.json
@ -792,22 +792,22 @@ e383106ff8f877b5995e20c03af5e41e3db541d9 data/create/recipes/milling/compat/biom
213e079f32baa2879702b72bdf08f146877a0bb9 data/create/recipes/milling/compat/biomesoplenty/violet.json
b3f041e005491582f055da15871891357908d998 data/create/recipes/milling/compat/biomesoplenty/wildflower.json
d08c4fcebb79e2e02ac9cb4623124332a05ed661 data/create/recipes/milling/compat/biomesoplenty/wilted_lily.json
ca03746c39143de7867aeab2fb450fe0a67b69e3 data/create/recipes/milling/compat/botania/black_petal.json
3192777eeb363a55174a0eb58197ee686b2e02c7 data/create/recipes/milling/compat/botania/blue_petal.json
ee99c9bdcc4da8d160fc762ce7b394848d6a86d1 data/create/recipes/milling/compat/botania/brown_petal.json
1d8dab24913945268f819c24e132d8bb74f792c2 data/create/recipes/milling/compat/botania/cyan_petal.json
010a111f9810f142315bc94dfb1be03ee02508c4 data/create/recipes/milling/compat/botania/gray_petal.json
dee8b4c26d6b78aceeb8e5a264693dad4e81dbcb data/create/recipes/milling/compat/botania/green_petal.json
285a24e440d6a8cf34f2925a3eed7fa1d16e102b data/create/recipes/milling/compat/botania/light_blue_petal.json
3cc232966240394aaf5a3a5d16a3ceebd41597a0 data/create/recipes/milling/compat/botania/light_gray_petal.json
1225119a7dc1f69dfaf2cec32a0267b1d47ef72d data/create/recipes/milling/compat/botania/lime_petal.json
09e114685483329a78c3cecf8b312f16d26cd981 data/create/recipes/milling/compat/botania/magenta_petal.json
ae3e7eb55dda1846b8fd849ea1c8f1cbd37b9fca data/create/recipes/milling/compat/botania/orange_petal.json
bf13e9807a96efc1ef684f0129cc21110e44cc4c data/create/recipes/milling/compat/botania/pink_petal.json
7e0a167201b9c915579ede71ee7128bccdeee9c2 data/create/recipes/milling/compat/botania/purple_petal.json
4e7c1ae95f10bb3466dd542a2e04c726c599ecd9 data/create/recipes/milling/compat/botania/red_petal.json
28cbeb278022b2ac62cae2f3deaa65cb375c6456 data/create/recipes/milling/compat/botania/white_petal.json
dd1e35234c419b1576410a2590fd33d88c8bb9bd data/create/recipes/milling/compat/botania/yellow_petal.json
4994095300eabfe98a86036e7fbba6c12cddb078 data/create/recipes/milling/compat/botania/black_petal.json
3516555e62ce7d6f0b5a57375339e69b4de41f83 data/create/recipes/milling/compat/botania/blue_petal.json
deb37dcb4b323590fbb76f21732e5b9016028f7d data/create/recipes/milling/compat/botania/brown_petal.json
d831337c28b89ce25a2be50e06719ab3be9400b6 data/create/recipes/milling/compat/botania/cyan_petal.json
1ec99d5ee65becc6c921827956e26f286398b1ba data/create/recipes/milling/compat/botania/gray_petal.json
7bcbd91fae49452fe30966b350c6830ad5bb588c data/create/recipes/milling/compat/botania/green_petal.json
5819b1ff0c54851d4bf7c60228ce2e31b8d8ffee data/create/recipes/milling/compat/botania/light_blue_petal.json
94b6cb826923907527c57e079d08fb410720b008 data/create/recipes/milling/compat/botania/light_gray_petal.json
4fe3b309902b0d59971d351d6e4a8066908df195 data/create/recipes/milling/compat/botania/lime_petal.json
b8f8ea5d52ae9cbdd59d60aabbac660859190855 data/create/recipes/milling/compat/botania/magenta_petal.json
eab4d51ba92d5a2f172de76bca72cf2746359b68 data/create/recipes/milling/compat/botania/orange_petal.json
c8cf3978e3bf0ffeccd18c1b16ea26c5e1c18634 data/create/recipes/milling/compat/botania/pink_petal.json
9ee958eb5fb176902255aa606517a362670f3d60 data/create/recipes/milling/compat/botania/purple_petal.json
3239b0a1ef91f61ab32f42ac3935ee99316089c5 data/create/recipes/milling/compat/botania/red_petal.json
15afbebf247ea66e0b023ea84aa5c5dad8ac8466 data/create/recipes/milling/compat/botania/white_petal.json
9c500a9d6cadb4f673ca63de38c1d3713dab061c data/create/recipes/milling/compat/botania/yellow_petal.json
c7d2b07396448628123b81e1f34a8b131aa99c83 data/create/recipes/milling/compat/buzzier_bees/buttercup.json
0c4a3c7da1e151868740db2037504e35a02af3d0 data/create/recipes/milling/compat/buzzier_bees/pink_clover.json
355e89a3e003ae65ff06a9277c05699220eec569 data/create/recipes/milling/compat/buzzier_bees/white_clover.json
@ -1033,7 +1033,7 @@ e3f12ec5d449caa54ebe1c453a89373492b8f48a data/create/recipes/splashing/endergeti
64535aaa3a5d4b98791337b1a8ce50ad3d39a8ac data/create/recipes/splashing/gravel.json
dd9508767f68cc8b5cc2f642690961e0c22c9985 data/create/recipes/splashing/gray_concrete_powder.json
8908b452e6bc1290ebb8cfefc2c066460de93bff data/create/recipes/splashing/green_concrete_powder.json
869a639fd7069495693fd2106165b57ce674201b data/create/recipes/splashing/ic2/crushed_raw_aluminum.json
9764857ea6ee8d31ec37e6022f89dbe662e88591 data/create/recipes/splashing/ic2/crushed_raw_aluminum.json
6fd01478f838507f9e0daf7eb0a19e8315e03cb8 data/create/recipes/splashing/ic2/crushed_raw_silver.json
b5a0a0fc79bf310965aa16e78044b3f6a8a9998f data/create/recipes/splashing/ic2/crushed_raw_tin.json
00b8d0c2577cc36da1c862234b61fb7d1cfe3e65 data/create/recipes/splashing/ic2/crushed_raw_uranium.json

View file

@ -1,2 +1,2 @@
// 1.20.1 2024-09-24T21:07:12.9288376 Create's Custom Sounds
c8f92cda61fef77efb6ce0b61770368e8c074444 assets/create/sounds.json
// 1.20.1 2024-10-09T12:24:59.2018604 Create's Custom Sounds
bcfd9320f8ed54f3282b1757a41da0d1753e1754 assets/create/sounds.json

View file

@ -1,2 +1,2 @@
// 1.20.1 2024-09-02T22:36:27.3550723 Create's Recipe Serializer Tags
// 1.20.1 2024-10-09T12:24:59.2646915 Create's Recipe Serializer Tags
0d8718f7383761bc5d7bc45306ed266ebf25dc1d data/create/tags/recipe_serializer/automation_ignore.json

View file

@ -1,4 +1,4 @@
// 1.20.1 2024-09-02T22:36:27.3570669 Create's Generated Registry Entries
// 1.20.1 2024-10-09T12:24:59.2666858 Create's Generated Registry Entries
030ede1044384c4117ac1e491bf5c78bbd2842f5 data/create/damage_type/crush.json
92b0416950ffeb3ba68811e587177c2f8811c2c5 data/create/damage_type/cuckoo_surprise.json
d2a4fdb64f4ba817e13a7b20c73fd1ca34b825fc data/create/damage_type/fan_fire.json

View file

@ -2537,6 +2537,7 @@
"create.station.remove_auto_schedule": ןnpǝɥɔS-oʇnⱯ pɹɐɔsıᗡ",
"create.station.remove_schedule": ןnpǝɥɔS ǝʌǝıɹʇǝᴚ",
"create.station.retry": "ʎɹʇǝɹ puɐ sıɥʇ ǝʌןosǝᴚ",
"create.station.train_map_color": "sdɐW uo ɹoןoƆ",
"create.station.train_not_aligned": "'ǝןqɯǝssɐsıp ʇouuɐƆ",
"create.station.train_not_aligned_1": "pǝubıןɐ sǝbɐıɹɹɐɔ ןןɐ ʇou",
"create.subtitle.blaze_munch": "sǝɥɔunɯ ɹǝuɹnᗺ ǝzɐןᗺ",
@ -2709,6 +2710,21 @@
"create.train_assembly.sideways_controls": "sʎɐʍǝpıs ǝɔɐɟ ʇouuɐɔ sןoɹʇuoƆ uıɐɹ⟘",
"create.train_assembly.single_bogey_carriage": "uʍo sʇı uo ǝbɐıɹɹɐɔ ɐ ʇɹoddns ʇouuɐɔ ǝdʎʇ ʎǝboᗺ sıɥ⟘",
"create.train_assembly.too_many_bogeys": "%1$s :pǝɥɔɐʇʇɐ sʎǝboᗺ ʎuɐɯ oo⟘",
"create.train_map.cannot_traverse_section": "ǝsɹǝʌɐɹʇ ʎןןnɟ ʇouuɐƆ ",
"create.train_map.conductor_missing": "buıssıW ɹoʇɔnpuoƆ >¡< ",
"create.train_map.derailed": "pǝןıɐɹǝᗡ >¡< ",
"create.train_map.for_other_train": "%1$s ɹoɟ ",
"create.train_map.fuel_boosted": "✔ pǝʇsooq ןǝnℲ ",
"create.train_map.navigation_failed": "pǝןıɐℲ uoıʇɐbıʌɐN >¡< ",
"create.train_map.player_controlled": "ɹǝʎɐןԀ ʎq pǝןןoɹʇuoƆ >- ",
"create.train_map.redstone_powered": "pǝɹǝʍoԀ ǝuoʇspǝᴚ ",
"create.train_map.schedule_interrupted": "pǝʇdnɹɹǝʇuI ǝןnpǝɥɔS >¡< ",
"create.train_map.section_reserved": "pǝʌɹǝsǝɹ uoıʇɔǝS ",
"create.train_map.toggle": "ʎɐןɹǝʌo ʞɹoʍʇǝu uıɐɹ⟘",
"create.train_map.train_at_station": "%1$s |> ",
"create.train_map.train_moving_to_station": ")ɯ%2$s( %1$s >> ",
"create.train_map.train_owned_by": "%1$s ʎq",
"create.train_map.waiting_at_signal": "ןɐubıS ʇɐ buıʇıɐM ",
"create.tunnel.selection_mode.forced_round_robin": "uıqoᴚ punoᴚ pǝɔɹoℲ",
"create.tunnel.selection_mode.forced_split": ıןdS pǝɔɹoℲ",
"create.tunnel.selection_mode.prefer_nearest": "ʇsǝɹɐǝN ɹǝɟǝɹԀ",

View file

@ -2537,6 +2537,7 @@
"create.station.remove_auto_schedule": "Discard Auto-Schedule",
"create.station.remove_schedule": "Retrieve Schedule",
"create.station.retry": "Resolve this and retry",
"create.station.train_map_color": "Color on Maps",
"create.station.train_not_aligned": "Cannot disassemble,",
"create.station.train_not_aligned_1": "not all carriages aligned",
"create.subtitle.blaze_munch": "Blaze Burner munches",
@ -2709,6 +2710,21 @@
"create.train_assembly.sideways_controls": "Train Controls cannot face sideways",
"create.train_assembly.single_bogey_carriage": "This Bogey type cannot support a carriage on its own",
"create.train_assembly.too_many_bogeys": "Too many Bogeys attached: %1$s",
"create.train_map.cannot_traverse_section": " Cannot fully traverse",
"create.train_map.conductor_missing": " <!> Conductor Missing",
"create.train_map.derailed": " <!> Derailed",
"create.train_map.for_other_train": " for %1$s",
"create.train_map.fuel_boosted": " Fuel boosted ✔",
"create.train_map.navigation_failed": " <!> Navigation Failed",
"create.train_map.player_controlled": " -> Controlled by Player",
"create.train_map.redstone_powered": " Redstone Powered",
"create.train_map.schedule_interrupted": " <!> Schedule Interrupted",
"create.train_map.section_reserved": " Section reserved",
"create.train_map.toggle": "Train network overlay",
"create.train_map.train_at_station": " >| %1$s",
"create.train_map.train_moving_to_station": " >> %1$s (%2$sm)",
"create.train_map.train_owned_by": "by %1$s",
"create.train_map.waiting_at_signal": " Waiting at Signal",
"create.tunnel.selection_mode.forced_round_robin": "Forced Round Robin",
"create.tunnel.selection_mode.forced_split": "Forced Split",
"create.tunnel.selection_mode.prefer_nearest": "Prefer Nearest",

View file

@ -15,7 +15,7 @@
},
"has_the_recipe": {
"conditions": {
"recipe": "create:blasting/ingot_aluminum_compat_ic2"
"recipe": "create:blasting/ingot_aluminium_compat_ic2"
},
"trigger": "minecraft:recipe_unlocked"
}
@ -28,7 +28,7 @@
],
"rewards": {
"recipes": [
"create:blasting/ingot_aluminum_compat_ic2"
"create:blasting/ingot_aluminium_compat_ic2"
]
},
"sends_telemetry_event": false

View file

@ -15,7 +15,7 @@
},
"has_the_recipe": {
"conditions": {
"recipe": "create:smelting/ingot_aluminum_compat_ic2"
"recipe": "create:smelting/ingot_aluminium_compat_ic2"
},
"trigger": "minecraft:recipe_unlocked"
}
@ -28,7 +28,7 @@
],
"rewards": {
"recipes": [
"create:smelting/ingot_aluminum_compat_ic2"
"create:smelting/ingot_aluminium_compat_ic2"
]
},
"sends_telemetry_event": false

View file

@ -12,5 +12,5 @@
"ingredient": {
"item": "create:crushed_raw_aluminum"
},
"result": "ic2:ingot_aluminum"
"result": "ic2:ingot_aluminium"
}

View file

@ -1,6 +1,12 @@
{
"type": "minecraft:crafting_shapeless",
"category": "misc",
"conditions": [
{
"type": "forge:mod_loaded",
"modid": "upgrade_aquatic"
}
],
"ingredients": [
{
"tag": "minecraft:small_flowers"

View file

@ -1,5 +1,11 @@
{
"type": "create:milling",
"conditions": [
{
"type": "forge:mod_loaded",
"modid": "botania"
}
],
"ingredients": [
{
"tag": "botania:petals/black"

View file

@ -1,5 +1,11 @@
{
"type": "create:milling",
"conditions": [
{
"type": "forge:mod_loaded",
"modid": "botania"
}
],
"ingredients": [
{
"tag": "botania:petals/blue"

View file

@ -1,5 +1,11 @@
{
"type": "create:milling",
"conditions": [
{
"type": "forge:mod_loaded",
"modid": "botania"
}
],
"ingredients": [
{
"tag": "botania:petals/brown"

View file

@ -1,5 +1,11 @@
{
"type": "create:milling",
"conditions": [
{
"type": "forge:mod_loaded",
"modid": "botania"
}
],
"ingredients": [
{
"tag": "botania:petals/cyan"

View file

@ -1,5 +1,11 @@
{
"type": "create:milling",
"conditions": [
{
"type": "forge:mod_loaded",
"modid": "botania"
}
],
"ingredients": [
{
"tag": "botania:petals/gray"

View file

@ -1,5 +1,11 @@
{
"type": "create:milling",
"conditions": [
{
"type": "forge:mod_loaded",
"modid": "botania"
}
],
"ingredients": [
{
"tag": "botania:petals/green"

View file

@ -1,5 +1,11 @@
{
"type": "create:milling",
"conditions": [
{
"type": "forge:mod_loaded",
"modid": "botania"
}
],
"ingredients": [
{
"tag": "botania:petals/light_blue"

View file

@ -1,5 +1,11 @@
{
"type": "create:milling",
"conditions": [
{
"type": "forge:mod_loaded",
"modid": "botania"
}
],
"ingredients": [
{
"tag": "botania:petals/light_gray"

View file

@ -1,5 +1,11 @@
{
"type": "create:milling",
"conditions": [
{
"type": "forge:mod_loaded",
"modid": "botania"
}
],
"ingredients": [
{
"tag": "botania:petals/lime"

View file

@ -1,5 +1,11 @@
{
"type": "create:milling",
"conditions": [
{
"type": "forge:mod_loaded",
"modid": "botania"
}
],
"ingredients": [
{
"tag": "botania:petals/magenta"

View file

@ -1,5 +1,11 @@
{
"type": "create:milling",
"conditions": [
{
"type": "forge:mod_loaded",
"modid": "botania"
}
],
"ingredients": [
{
"tag": "botania:petals/orange"

View file

@ -1,5 +1,11 @@
{
"type": "create:milling",
"conditions": [
{
"type": "forge:mod_loaded",
"modid": "botania"
}
],
"ingredients": [
{
"tag": "botania:petals/pink"

View file

@ -1,5 +1,11 @@
{
"type": "create:milling",
"conditions": [
{
"type": "forge:mod_loaded",
"modid": "botania"
}
],
"ingredients": [
{
"tag": "botania:petals/purple"

View file

@ -1,5 +1,11 @@
{
"type": "create:milling",
"conditions": [
{
"type": "forge:mod_loaded",
"modid": "botania"
}
],
"ingredients": [
{
"tag": "botania:petals/red"

View file

@ -1,5 +1,11 @@
{
"type": "create:milling",
"conditions": [
{
"type": "forge:mod_loaded",
"modid": "botania"
}
],
"ingredients": [
{
"tag": "botania:petals/white"

View file

@ -1,5 +1,11 @@
{
"type": "create:milling",
"conditions": [
{
"type": "forge:mod_loaded",
"modid": "botania"
}
],
"ingredients": [
{
"tag": "botania:petals/yellow"

View file

@ -12,5 +12,5 @@
"ingredient": {
"item": "create:crushed_raw_aluminum"
},
"result": "ic2:ingot_aluminum"
"result": "ic2:ingot_aluminium"
}

View file

@ -14,7 +14,7 @@
"results": [
{
"count": 9,
"item": "ic2:nugget_aluminum"
"item": "ic2:nugget_aluminium"
}
]
}

View file

@ -8,6 +8,8 @@ import java.util.function.Function;
import java.util.function.Supplier;
import com.simibubi.create.compat.computercraft.AttachedComputerPacket;
import com.simibubi.create.compat.trainmap.TrainMapSyncPacket;
import com.simibubi.create.compat.trainmap.TrainMapSyncRequestPacket;
import com.simibubi.create.content.contraptions.ContraptionBlockChangedPacket;
import com.simibubi.create.content.contraptions.ContraptionColliderLockPacket;
import com.simibubi.create.content.contraptions.ContraptionColliderLockPacket.ContraptionColliderLockPacketRequest;
@ -187,6 +189,7 @@ public enum AllPackets {
STOCK_TICKER_CONFIGURATION(StockTickerConfigurationPacket.class, StockTickerConfigurationPacket::new, PLAY_TO_SERVER),
DISPLAY_CLOTH_SERVERBOUND(DisplayClothPacketToServer.class, DisplayClothPacketToServer::new, PLAY_TO_SERVER),
PACKAGE_PORT_CONFIGURATION(PackagePortConfigurationPacket.class, PackagePortConfigurationPacket::new, PLAY_TO_SERVER),
TRAIN_MAP_REQUEST(TrainMapSyncRequestPacket.class, TrainMapSyncRequestPacket::new, PLAY_TO_SERVER),
// Server to Client
SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_TO_CLIENT),
@ -235,7 +238,8 @@ public enum AllPackets {
SERVER_DEBUG_INFO(ServerDebugInfoPacket.class, ServerDebugInfoPacket::new, PLAY_TO_CLIENT),
PACKAGE_DESTROYED(PackageDestroyPacket.class, PackageDestroyPacket::new, PLAY_TO_CLIENT),
LOGISTICS_STOCK_RESPONSE(LogisticalStockResponsePacket.class, LogisticalStockResponsePacket::new, PLAY_TO_CLIENT),
DISPLAY_CLOTH_CLIENTBOUND(DisplayClothPacketToClient.class, DisplayClothPacketToClient::new, PLAY_TO_CLIENT);
DISPLAY_CLOTH_CLIENTBOUND(DisplayClothPacketToClient.class, DisplayClothPacketToClient::new, PLAY_TO_CLIENT),
TRAIN_MAP_SYNC(TrainMapSyncPacket.class, TrainMapSyncPacket::new, PLAY_TO_CLIENT);
static {
ClientboundSimpleActionPacket.addAction("rainbowDebug", () -> SimpleCreateActions::rainbowDebug);

View file

@ -30,7 +30,9 @@ public enum Mods {
TCONSTRUCT,
FRAMEDBLOCKS,
XLPACKETS,
MODERNUI;
MODERNUI,
FTBCHUNKS,
JOURNEYMAP;
private final String id;

View file

@ -129,7 +129,7 @@ public class StationPeripheral extends SyncedPeripheral<StationBlockEntity> {
public final void setTrainName(String name) throws LuaException {
Train train = getTrainOrThrow();
train.name = Components.literal(name);
AllPackets.getChannel().send(PacketDistributor.ALL.noArg(), new TrainEditPacket.TrainEditReturnPacket(train.id, name, train.icon.getId()));
AllPackets.getChannel().send(PacketDistributor.ALL.noArg(), new TrainEditPacket.TrainEditReturnPacket(train.id, name, train.icon.getId(), train.mapColorIndex));
}
@LuaFunction

View file

@ -0,0 +1,158 @@
package com.simibubi.create.compat.trainmap;
import java.util.List;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.foundation.gui.RemovedGuiUtils;
import com.simibubi.create.foundation.utility.CreateLang;
import com.simibubi.create.infrastructure.config.AllConfigs;
import dev.ftb.mods.ftbchunks.client.gui.LargeMapScreen;
import dev.ftb.mods.ftbchunks.client.gui.RegionMapPanel;
import dev.ftb.mods.ftblibrary.ui.ScreenWrapper;
import dev.ftb.mods.ftblibrary.ui.Widget;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.renderer.Rect2i;
import net.minecraft.network.chat.FormattedText;
import net.minecraft.util.Mth;
import net.minecraftforge.client.event.InputEvent;
import net.minecraftforge.client.event.RenderTooltipEvent;
import net.minecraftforge.client.event.ScreenEvent;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
public class FTBChunksTrainMap {
private static int cancelTooltips = 0;
private static boolean renderingTooltip = false;
private static boolean requesting;
public static void tick() {
if (cancelTooltips > 0)
cancelTooltips--;
if (!AllConfigs.client().showTrainMapOverlay.get()
|| getAsLargeMapScreen(Minecraft.getInstance().screen) == null) {
if (requesting)
TrainMapSyncClient.stopRequesting();
requesting = false;
return;
}
TrainMapManager.tick();
requesting = true;
TrainMapSyncClient.requestData();
}
public static void cancelTooltips(RenderTooltipEvent.Pre event) {
if (getAsLargeMapScreen(Minecraft.getInstance().screen) == null)
return;
if (renderingTooltip || cancelTooltips == 0)
return;
event.setCanceled(true);
}
public static void mouseClick(InputEvent.MouseButton.Pre event) {
LargeMapScreen screen = getAsLargeMapScreen(Minecraft.getInstance().screen);
if (screen == null)
return;
if (TrainMapManager.handleToggleWidgetClick(screen.getMouseX(), screen.getMouseY(), 20, 2))
event.setCanceled(true);
}
public static void renderGui(ScreenEvent.Render.Post event) {
LargeMapScreen largeMapScreen = getAsLargeMapScreen(event.getScreen());
if (largeMapScreen == null)
return;
Object panel = ObfuscationReflectionHelper.getPrivateValue(LargeMapScreen.class, largeMapScreen, "regionPanel");
if (!(panel instanceof RegionMapPanel regionMapPanel))
return;
GuiGraphics graphics = event.getGuiGraphics();
if (!AllConfigs.client().showTrainMapOverlay.get()) {
renderToggleWidgetAndTooltip(event, largeMapScreen, graphics);
return;
}
int blocksPerRegion = 16 * 32;
int minX = Mth.floor(regionMapPanel.getScrollX());
int minY = Mth.floor(regionMapPanel.getScrollY());
float regionTileSize = largeMapScreen.getRegionTileSize() / (float) blocksPerRegion;
int regionMinX =
ObfuscationReflectionHelper.getPrivateValue(RegionMapPanel.class, regionMapPanel, "regionMinX");
int regionMinZ =
ObfuscationReflectionHelper.getPrivateValue(RegionMapPanel.class, regionMapPanel, "regionMinZ");
float mouseX = event.getMouseX();
float mouseY = event.getMouseY();
boolean linearFiltering = largeMapScreen.getRegionTileSize() * Minecraft.getInstance()
.getWindow()
.getGuiScale() < 512D;
PoseStack pose = graphics.pose();
pose.pushPose();
pose.translate(-minX, -minY, 0);
pose.scale(regionTileSize, regionTileSize, 1);
pose.translate(-regionMinX * blocksPerRegion, -regionMinZ * blocksPerRegion, 0);
mouseX += minX;
mouseY += minY;
mouseX /= regionTileSize;
mouseY /= regionTileSize;
mouseX += regionMinX * blocksPerRegion;
mouseY += regionMinZ * blocksPerRegion;
Rect2i bounds = new Rect2i(Mth.floor(minX / regionTileSize + regionMinX * blocksPerRegion),
Mth.floor(minY / regionTileSize + regionMinZ * blocksPerRegion),
Mth.floor(largeMapScreen.width / regionTileSize), Mth.floor(largeMapScreen.height / regionTileSize));
List<FormattedText> tooltip = TrainMapManager.renderAndPick(graphics, Mth.floor(mouseX), Mth.floor(mouseY),
event.getPartialTick(), linearFiltering, bounds);
pose.popPose();
if (!renderToggleWidgetAndTooltip(event, largeMapScreen, graphics) && tooltip != null) {
renderingTooltip = true;
RemovedGuiUtils.drawHoveringText(graphics, tooltip, event.getMouseX(), event.getMouseY(),
largeMapScreen.width, largeMapScreen.height, 256, Minecraft.getInstance().font);
renderingTooltip = false;
cancelTooltips = 5;
}
pose.pushPose();
pose.translate(0, 0, 300);
for (Widget widget : largeMapScreen.getWidgets()) {
if (!widget.isEnabled())
continue;
if (widget == panel)
continue;
widget.draw(graphics, largeMapScreen.getTheme(), widget.getPosX(), widget.getPosY(), widget.getWidth(),
widget.getHeight());
}
pose.popPose();
}
private static boolean renderToggleWidgetAndTooltip(ScreenEvent.Render.Post event, LargeMapScreen largeMapScreen,
GuiGraphics graphics) {
TrainMapManager.renderToggleWidget(graphics, 20, 2);
if (!TrainMapManager.isToggleWidgetHovered(event.getMouseX(), event.getMouseY(), 20, 2))
return false;
renderingTooltip = true;
RemovedGuiUtils.drawHoveringText(graphics, List.of(CreateLang.translate("train_map.toggle")
.component()), event.getMouseX(), event.getMouseY() + 20, largeMapScreen.width, largeMapScreen.height, 256,
Minecraft.getInstance().font);
renderingTooltip = false;
cancelTooltips = 5;
return true;
}
private static LargeMapScreen getAsLargeMapScreen(Screen screen) {
if (!(screen instanceof ScreenWrapper screenWrapper))
return null;
Object wrapped = ObfuscationReflectionHelper.getPrivateValue(ScreenWrapper.class, screenWrapper, "wrappedGui");
if (!(wrapped instanceof LargeMapScreen largeMapScreen))
return null;
return largeMapScreen;
}
}

View file

@ -0,0 +1,108 @@
package com.simibubi.create.compat.trainmap;
import java.util.List;
import com.mojang.blaze3d.platform.Window;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.foundation.gui.RemovedGuiUtils;
import com.simibubi.create.foundation.utility.CreateLang;
import com.simibubi.create.infrastructure.config.AllConfigs;
import journeymap.client.api.display.Context.UI;
import journeymap.client.api.util.UIState;
import journeymap.client.ui.fullscreen.Fullscreen;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.Rect2i;
import net.minecraft.network.chat.FormattedText;
import net.minecraft.util.Mth;
import net.minecraftforge.client.event.InputEvent;
public class JourneyTrainMap {
private static boolean requesting;
public static void tick() {
if (!AllConfigs.client().showTrainMapOverlay.get() || !(Minecraft.getInstance().screen instanceof Fullscreen)) {
if (requesting)
TrainMapSyncClient.stopRequesting();
requesting = false;
return;
}
TrainMapManager.tick();
requesting = true;
TrainMapSyncClient.requestData();
}
public static void mouseClick(InputEvent.MouseButton.Pre event) {
Minecraft mc = Minecraft.getInstance();
if (!(mc.screen instanceof Fullscreen screen))
return;
Window window = mc.getWindow();
double mX = mc.mouseHandler.xpos() * window.getGuiScaledWidth() / window.getScreenWidth();
double mY = mc.mouseHandler.ypos() * window.getGuiScaledHeight() / window.getScreenHeight();
if (TrainMapManager.handleToggleWidgetClick(Mth.floor(mX), Mth.floor(mY), 3, 30))
event.setCanceled(true);
}
// Called by JourneyFullscreenMapMixin
public static void onRender(GuiGraphics graphics, Fullscreen screen, double x, double z, int mX, int mY, float pt) {
UIState state = screen.getUiState();
if (state == null)
return;
if (state.ui != UI.Fullscreen)
return;
if (!state.active)
return;
if (!AllConfigs.client().showTrainMapOverlay.get()) {
renderToggleWidgetAndTooltip(graphics, screen, mX, mY);
return;
}
Minecraft mc = Minecraft.getInstance();
Window window = mc.getWindow();
double guiScale = (double) window.getScreenWidth() / window.getGuiScaledWidth();
double scale = state.blockSize / guiScale;
PoseStack pose = graphics.pose();
pose.pushPose();
pose.translate(screen.width / 2.0f, screen.height / 2.0f, 0);
pose.scale((float) scale, (float) scale, 1);
pose.translate(-x, -z, 0);
float mouseX = mX - screen.width / 2.0f;
float mouseY = mY - screen.height / 2.0f;
mouseX /= scale;
mouseY /= scale;
mouseX += x;
mouseY += z;
Rect2i bounds =
new Rect2i(Mth.floor(-screen.width / 2.0f / scale + x), Mth.floor(-screen.height / 2.0f / scale + z),
Mth.floor(screen.width / scale), Mth.floor(screen.height / scale));
List<FormattedText> tooltip =
TrainMapManager.renderAndPick(graphics, Mth.floor(mouseX), Mth.floor(mouseY), pt, false, bounds);
pose.popPose();
if (!renderToggleWidgetAndTooltip(graphics, screen, mX, mY) && tooltip != null)
RemovedGuiUtils.drawHoveringText(graphics, tooltip, mX, mY, screen.width, screen.height, 256, mc.font);
}
private static boolean renderToggleWidgetAndTooltip(GuiGraphics graphics, Fullscreen screen, int mouseX,
int mouseY) {
TrainMapManager.renderToggleWidget(graphics, 3, 30);
if (!TrainMapManager.isToggleWidgetHovered(mouseX, mouseY, 3, 30))
return false;
RemovedGuiUtils.drawHoveringText(graphics, List.of(CreateLang.translate("train_map.toggle")
.component()), mouseX, mouseY + 20, screen.width, screen.height, 256, Minecraft.getInstance().font);
return true;
}
}

View file

@ -0,0 +1,56 @@
package com.simibubi.create.compat.trainmap;
import com.mojang.blaze3d.platform.InputConstants;
import com.simibubi.create.compat.Mods;
import net.minecraft.client.Minecraft;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.InputEvent;
import net.minecraftforge.client.event.RenderTooltipEvent;
import net.minecraftforge.client.event.ScreenEvent;
import net.minecraftforge.event.TickEvent.ClientTickEvent;
import net.minecraftforge.event.TickEvent.Phase;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@EventBusSubscriber(value = Dist.CLIENT)
public class TrainMapEvents {
@SubscribeEvent
public static void tick(ClientTickEvent event) {
if (event.phase == Phase.START)
return;
Minecraft mc = Minecraft.getInstance();
if (mc.level == null)
return;
if (Mods.FTBCHUNKS.isLoaded())
FTBChunksTrainMap.tick();
if (Mods.JOURNEYMAP.isLoaded())
JourneyTrainMap.tick();
}
@SubscribeEvent
public static void mouseClick(InputEvent.MouseButton.Pre event) {
if (event.getAction() != InputConstants.PRESS)
return;
if (Mods.FTBCHUNKS.isLoaded())
FTBChunksTrainMap.mouseClick(event);
if (Mods.JOURNEYMAP.isLoaded())
JourneyTrainMap.mouseClick(event);
}
@SubscribeEvent
public static void cancelTooltips(RenderTooltipEvent.Pre event) {
if (Mods.FTBCHUNKS.isLoaded())
FTBChunksTrainMap.cancelTooltips(event);
}
@SubscribeEvent
public static void renderGui(ScreenEvent.Render.Post event) {
if (Mods.FTBCHUNKS.isLoaded())
FTBChunksTrainMap.renderGui(event);
}
}

View file

@ -0,0 +1,730 @@
package com.simibubi.create.compat.trainmap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Axis;
import com.simibubi.create.CreateClient;
import com.simibubi.create.compat.trainmap.TrainMapSync.SignalState;
import com.simibubi.create.compat.trainmap.TrainMapSync.TrainMapSyncEntry;
import com.simibubi.create.compat.trainmap.TrainMapSync.TrainState;
import com.simibubi.create.content.trains.entity.Carriage;
import com.simibubi.create.content.trains.entity.Train;
import com.simibubi.create.content.trains.graph.EdgePointType;
import com.simibubi.create.content.trains.graph.TrackEdge;
import com.simibubi.create.content.trains.graph.TrackGraph;
import com.simibubi.create.content.trains.graph.TrackNode;
import com.simibubi.create.content.trains.graph.TrackNodeLocation;
import com.simibubi.create.content.trains.station.GlobalStation;
import com.simibubi.create.content.trains.track.BezierConnection;
import com.simibubi.create.foundation.gui.AllGuiTextures;
import com.simibubi.create.foundation.utility.CreateLang;
import com.simibubi.create.infrastructure.config.AllConfigs;
import com.simibubi.create.infrastructure.config.CClient;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.createmod.catnip.utility.AnimationTickHolder;
import net.createmod.catnip.utility.Couple;
import net.createmod.catnip.utility.Iterate;
import net.createmod.catnip.utility.Pair;
import net.createmod.catnip.utility.lang.Components;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.Rect2i;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.FormattedText;
import net.minecraft.resources.ResourceKey;
import net.minecraft.util.FastColor;
import net.minecraft.util.Mth;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
public class TrainMapManager {
public static void tick() {
TrainMapRenderer map = TrainMapRenderer.INSTANCE;
if (map.trackingVersion != CreateClient.RAILWAYS.version
|| map.trackingDim != Minecraft.getInstance().level.dimension()
|| map.trackingTheme != AllConfigs.client().trainMapColorTheme.get()) {
redrawAll();
}
}
public static List<FormattedText> renderAndPick(GuiGraphics graphics, int mouseX, int mouseY, float pt,
boolean linearFiltering, Rect2i bounds) {
Object hoveredElement = null;
int offScreenMargin = 32;
bounds.setX(bounds.getX() - offScreenMargin);
bounds.setY(bounds.getY() - offScreenMargin);
bounds.setWidth(bounds.getWidth() + 2 * offScreenMargin);
bounds.setHeight(bounds.getHeight() + 2 * offScreenMargin);
TrainMapRenderer.INSTANCE.render(graphics, mouseX, mouseY, pt, linearFiltering, bounds);
hoveredElement = drawTrains(graphics, mouseX, mouseY, pt, hoveredElement, bounds);
hoveredElement = drawPoints(graphics, mouseX, mouseY, pt, hoveredElement, bounds);
graphics.bufferSource()
.endBatch();
if (hoveredElement instanceof GlobalStation station)
return List.of(Components.literal(station.name));
if (hoveredElement instanceof Train train)
return listTrainDetails(train);
return null;
}
public static void renderToggleWidget(GuiGraphics graphics, int x, int y) {
boolean enabled = AllConfigs.client().showTrainMapOverlay.get();
if (CreateClient.RAILWAYS.trackNetworks.isEmpty())
return;
RenderSystem.enableBlend();
PoseStack pose = graphics.pose();
pose.pushPose();
pose.translate(0, 0, 300);
AllGuiTextures.TRAINMAP_TOGGLE_PANEL.render(graphics, x, y);
(enabled ? AllGuiTextures.TRAINMAP_TOGGLE_ON : AllGuiTextures.TRAINMAP_TOGGLE_OFF).render(graphics, x + 18,
y + 3);
pose.popPose();
}
public static boolean handleToggleWidgetClick(int mouseX, int mouseY, int x, int y) {
if (!isToggleWidgetHovered(mouseX, mouseY, x, y))
return false;
CClient config = AllConfigs.client();
config.showTrainMapOverlay.set(!config.showTrainMapOverlay.get());
return true;
}
public static boolean isToggleWidgetHovered(int mouseX, int mouseY, int x, int y) {
if (CreateClient.RAILWAYS.trackNetworks.isEmpty())
return false;
if (mouseX < x || mouseX >= x + AllGuiTextures.TRAINMAP_TOGGLE_PANEL.getWidth())
return false;
if (mouseY < y || mouseY >= y + AllGuiTextures.TRAINMAP_TOGGLE_PANEL.getHeight())
return false;
return true;
}
private static List<FormattedText> listTrainDetails(Train train) {
List<FormattedText> output = new ArrayList<>();
int blue = 0xD3DEDC;
int darkBlue = 0x92A9BD;
int bright = 0xFFEFEF;
int orange = 0xFFAD60;
TrainMapSyncEntry trainEntry = TrainMapSyncClient.currentData.get(train.id);
if (trainEntry == null)
return Collections.emptyList();
TrainState state = trainEntry.state;
SignalState signalState = trainEntry.signalState;
CreateLang.text(train.name.getString())
.color(bright)
.addTo(output);
if (!trainEntry.ownerName.isBlank())
CreateLang.translate("train_map.train_owned_by", trainEntry.ownerName)
.color(blue)
.addTo(output);
switch (state) {
case CONDUCTOR_MISSING:
CreateLang.translate("train_map.conductor_missing")
.color(orange)
.addTo(output);
return output;
case DERAILED:
CreateLang.translate("train_map.derailed")
.color(orange)
.addTo(output);
return output;
case NAVIGATION_FAILED:
CreateLang.translate("train_map.navigation_failed")
.color(orange)
.addTo(output);
return output;
case SCHEDULE_INTERRUPTED:
CreateLang.translate("train_map.schedule_interrupted")
.color(orange)
.addTo(output);
return output;
case RUNNING_MANUALLY:
CreateLang.translate("train_map.player_controlled")
.color(blue)
.addTo(output);
break;
case RUNNING:
default:
break;
}
String currentStation = trainEntry.targetStationName;
int targetStationDistance = trainEntry.targetStationDistance;
if (!currentStation.isBlank()) {
if (targetStationDistance == 0)
CreateLang.translate("train_map.train_at_station", currentStation)
.color(darkBlue)
.addTo(output);
else
CreateLang.translate("train_map.train_moving_to_station", currentStation, targetStationDistance)
.color(darkBlue)
.addTo(output);
}
if (signalState != SignalState.NOT_WAITING) {
boolean chainSignal = signalState == SignalState.CHAIN_SIGNAL;
CreateLang.translate("train_map.waiting_at_signal")
.color(orange)
.addTo(output);
if (signalState == SignalState.WAITING_FOR_REDSTONE)
CreateLang.translate("train_map.redstone_powered")
.color(blue)
.addTo(output);
else {
UUID waitingFor = trainEntry.waitingForTrain;
boolean trainFound = false;
if (waitingFor != null) {
Train trainWaitingFor = CreateClient.RAILWAYS.trains.get(waitingFor);
if (trainWaitingFor != null) {
CreateLang.translate("train_map.for_other_train", trainWaitingFor.name.getString())
.color(blue)
.addTo(output);
trainFound = true;
}
}
if (!trainFound) {
if (chainSignal)
CreateLang.translate("train_map.cannot_traverse_section")
.color(blue)
.addTo(output);
else
CreateLang.translate("train_map.section_reserved")
.color(blue)
.addTo(output);
}
}
}
if (trainEntry.fueled)
CreateLang.translate("train_map.fuel_boosted")
.color(darkBlue)
.addTo(output);
return output;
}
private static Object drawPoints(GuiGraphics graphics, int mouseX, int mouseY, float pt, Object hoveredElement,
Rect2i bounds) {
PoseStack pose = graphics.pose();
RenderSystem.enableDepthTest();
for (TrackGraph graph : CreateClient.RAILWAYS.trackNetworks.values()) {
for (GlobalStation station : graph.getPoints(EdgePointType.STATION)) {
Couple<TrackNodeLocation> edgeLocation = station.edgeLocation;
TrackNode node = graph.locateNode(edgeLocation.getFirst());
TrackNode other = graph.locateNode(edgeLocation.getSecond());
if (node == null || other == null)
continue;
if (node.getLocation().dimension != TrainMapRenderer.INSTANCE.trackingDim)
continue;
TrackEdge edge = graph.getConnection(Couple.create(node, other));
if (edge == null)
continue;
double tLength = station.getLocationOn(edge);
double t = tLength / edge.getLength();
Vec3 position = edge.getPosition(graph, t);
int x = Mth.floor(position.x());
int y = Mth.floor(position.z());
if (!bounds.contains(x, y))
continue;
Vec3 diff = edge.getDirectionAt(tLength)
.normalize();
int rotation = Mth.positiveModulo(Mth.floor(0.5
+ (Math.atan2(diff.z, diff.x) * Mth.RAD_TO_DEG + 90 + (station.isPrimary(node) ? 180 : 0)) / 45),
8);
AllGuiTextures sprite = AllGuiTextures.TRAINMAP_STATION_ORTHO;
AllGuiTextures highlightSprite = AllGuiTextures.TRAINMAP_STATION_ORTHO_HIGHLIGHT;
if (rotation % 2 != 0) {
sprite = AllGuiTextures.TRAINMAP_STATION_DIAGO;
highlightSprite = AllGuiTextures.TRAINMAP_STATION_DIAGO_HIGHLIGHT;
}
boolean highlight = hoveredElement == null && Math.max(Math.abs(mouseX - x), Math.abs(mouseY - y)) < 3;
pose.pushPose();
pose.translate(x - 2, y - 2, 5);
pose.translate(sprite.getWidth() / 2.0, sprite.getHeight() / 2.0, 0);
pose.mulPose(Axis.ZP.rotationDegrees(90 * (rotation / 2)));
pose.translate(-sprite.getWidth() / 2.0, -sprite.getHeight() / 2.0, 0);
sprite.render(graphics, 0, 0);
sprite.render(graphics, 0, 0);
if (highlight) {
pose.translate(0, 0, 5);
highlightSprite.render(graphics, -1, -1);
hoveredElement = station;
}
pose.popPose();
}
}
return hoveredElement;
}
private static Object drawTrains(GuiGraphics graphics, int mouseX, int mouseY, float pt, Object hoveredElement,
Rect2i bounds) {
PoseStack pose = graphics.pose();
RenderSystem.enableDepthTest();
RenderSystem.enableBlend();
int spriteYOffset = -3;
double time = AnimationTickHolder.getTicks();
time += AnimationTickHolder.getPartialTicks();
time -= TrainMapSyncClient.lastPacket;
time /= TrainMapSync.lightPacketInterval;
time = Mth.clamp(time, 0, 1);
int[] sliceXShiftByRotationIndex = new int[] { 0, 1, 2, 2, 3, -2, -2, -1 };
int[] sliceYShiftByRotationIndex = new int[] { 3, 2, 2, 1, 0, 1, 2, 2 };
for (Train train : CreateClient.RAILWAYS.trains.values()) {
TrainMapSyncEntry trainEntry = TrainMapSyncClient.currentData.get(train.id);
if (trainEntry == null)
continue;
Vec3 frontPos = Vec3.ZERO;
List<Carriage> carriages = train.carriages;
boolean otherDim = true;
double avgY = 0;
for (int i = 0; i < carriages.size(); i++) {
for (boolean firstBogey : Iterate.trueAndFalse)
avgY += trainEntry.getPosition(i, firstBogey, time)
.y();
}
avgY /= carriages.size() * 2;
for (int i = 0; i < carriages.size(); i++) {
Carriage carriage = carriages.get(i);
Vec3 pos1 = trainEntry.getPosition(i, true, time);
Vec3 pos2 = trainEntry.getPosition(i, false, time);
ResourceKey<Level> dim = trainEntry.dimensions.get(i);
if (dim == null || dim != TrainMapRenderer.INSTANCE.trackingDim)
continue;
if (!bounds.contains(Mth.floor(pos1.x()), Mth.floor(pos1.z()))
&& !bounds.contains(Mth.floor(pos2.x()), Mth.floor(pos2.z())))
continue;
otherDim = false;
if (!trainEntry.backwards && i == 0)
frontPos = pos1;
if (trainEntry.backwards && i == train.carriages.size() - 1)
frontPos = pos2;
Vec3 diff = pos2.subtract(pos1);
int size = carriage.bogeySpacing + 1;
Vec3 center = pos1.add(pos2)
.scale(0.5);
double pX = center.x;
double pY = center.z;
int rotation =
Mth.positiveModulo(Mth.floor(0.5 + (Math.atan2(diff.x, diff.z) * Mth.RAD_TO_DEG) / 22.5), 8);
if (trainEntry.state == TrainState.DERAILED)
rotation =
Mth.positiveModulo((AnimationTickHolder.getTicks() / 8 + i * 3) * (i % 2 == 0 ? 1 : -1), 8);
AllGuiTextures sprite = AllGuiTextures.TRAINMAP_SPRITES;
int slices = 2;
if (rotation == 0 || rotation == 4) {
// Orthogonal, slices add 3 pixels
slices += Mth.floor((size - 2) / (3.0) + 0.5);
}
else if (rotation == 2 || rotation == 6) {
// Diagonal, slices add 2*sqrt(2) pixels
slices += Mth.floor((size - (5 - 2 * Mth.SQRT_OF_TWO)) / (2 * Mth.SQRT_OF_TWO) + 0.5);
}
else {
// Slanty, slices add sqrt(5) pixels
slices += Mth.floor((size - (5 - Mth.sqrt(5))) / (Mth.sqrt(5)) + 0.5);
}
slices = Math.max(2, slices);
sprite.bind();
pose.pushPose();
float pivotX = 7.5f + (slices - 3) * sliceXShiftByRotationIndex[rotation] / 2.0f;
float pivotY = 6.5f + (slices - 3) * sliceYShiftByRotationIndex[rotation] / 2.0f;
// Ysort at home
pose.translate(pX - pivotX, pY - pivotY, 10 + (avgY / 512.0) + (1024.0 + center.z() % 8192.0) / 1024.0);
int trainColorIndex = train.mapColorIndex;
int colorRow = trainColorIndex / 4;
int colorCol = trainColorIndex % 4;
for (int slice = 0; slice < slices; slice++) {
int row = slice == 0 ? 1 : slice == slices - 1 ? 2 : 3;
int sliceShifts = slice == 0 ? 0 : slice == slices - 1 ? slice - 2 : slice - 1;
int col = rotation;
int positionX = sliceShifts * sliceXShiftByRotationIndex[rotation];
int positionY = sliceShifts * sliceYShiftByRotationIndex[rotation] + spriteYOffset;
int sheetX = col * 16 + colorCol * 128;
int sheetY = row * 16 + colorRow * 64;
graphics.blit(sprite.location, positionX, positionY, sheetX, sheetY, 16, 16, sprite.getWidth(),
sprite.getHeight());
}
pose.popPose();
int margin = 1;
int sizeX = 8 + (slices - 3) * sliceXShiftByRotationIndex[rotation];
int sizeY = 12 + (slices - 3) * sliceYShiftByRotationIndex[rotation];
double pXm = pX - sizeX / 2;
double pYm = pY - sizeY / 2 + spriteYOffset;
if (hoveredElement == null && mouseX < pXm + margin + sizeX && mouseX > pXm - margin
&& mouseY < pYm + margin + sizeY && mouseY > pYm - margin)
hoveredElement = train;
}
if (otherDim)
continue;
if (trainEntry.signalState != SignalState.NOT_WAITING) {
pose.pushPose();
pose.translate(frontPos.x - 0.5, frontPos.z - 0.5, 20 + (1024.0 + frontPos.z() % 8192.0) / 1024.0);
AllGuiTextures.TRAINMAP_SIGNAL.render(graphics, 0, -3);
pose.popPose();
}
}
return hoveredElement;
}
// Background first so we can mindlessly paint over it
static final int PHASE_BACKGROUND = 0;
// Straights before curves so that curves anti-alias properly at the transition
static final int PHASE_STRAIGHTS = 1;
static final int PHASE_CURVES = 2;
public static void redrawAll() {
TrainMapRenderer map = TrainMapRenderer.INSTANCE;
map.trackingVersion = CreateClient.RAILWAYS.version;
map.trackingDim = Minecraft.getInstance().level.dimension();
map.trackingTheme = AllConfigs.client().trainMapColorTheme.get();
map.startDrawing();
int mainColor = 0xFF_7C57D4;
int darkerColor = 0xFF_70437D;
int darkerColorShadow = 0xFF_4A2754;
switch (map.trackingTheme) {
case GREY:
mainColor = 0xFF_A8B5B5;
darkerColor = 0xFF_776E6C;
darkerColorShadow = 0xFF_56504E;
break;
case WHITE:
mainColor = 0xFF_E8F9F9;
darkerColor = 0xFF_889595;
darkerColorShadow = 0xFF_56504E;
break;
default:
break;
}
List<Couple<Integer>> collisions = new ObjectArrayList<>();
for (int phase = 0; phase <= 2; phase++)
renderPhase(map, collisions, mainColor, darkerColor, phase);
highlightYDifferences(map, collisions, mainColor, darkerColor, darkerColor, darkerColorShadow);
map.finishDrawing();
}
private static void renderPhase(TrainMapRenderer map, List<Couple<Integer>> collisions, int mainColor,
int darkerColor, int phase) {
int outlineColor = 0xFF_000000;
int portalFrameColor = 0xFF_4C2D5B;
int portalColor = 0xFF_FF7FD6;
for (TrackGraph graph : CreateClient.RAILWAYS.trackNetworks.values()) {
for (TrackNodeLocation nodeLocation : graph.getNodes()) {
if (nodeLocation.dimension != map.trackingDim)
continue;
TrackNode node = graph.locateNode(nodeLocation);
Map<TrackNode, TrackEdge> connectionsFrom = graph.getConnectionsFrom(node);
int hashCode = node.hashCode();
for (Entry<TrackNode, TrackEdge> entry : connectionsFrom.entrySet()) {
TrackNode other = entry.getKey();
TrackNodeLocation otherLocation = other.getLocation();
TrackEdge edge = entry.getValue();
BezierConnection turn = edge.getTurn();
// Portal track
if (edge.isInterDimensional()) {
Vec3 vec = node.getLocation()
.getLocation();
int x = Mth.floor(vec.x);
int z = Mth.floor(vec.z);
if (phase == PHASE_CURVES)
continue;
if (phase == PHASE_BACKGROUND) {
map.setPixels(x - 3, z - 2, x + 3, z + 2, outlineColor);
map.setPixels(x - 2, z - 3, x + 2, z + 3, outlineColor);
continue;
}
int a = mapYtoAlpha(Mth.floor(vec.y()));
for (int xi = x - 2; xi <= x + 2; xi++) {
for (int zi = z - 2; zi <= z + 2; zi++) {
int alphaAt = map.alphaAt(xi, zi);
if (alphaAt > 0 && alphaAt != a)
collisions.add(Couple.create(xi, zi));
int c = (xi - x) * (xi - x) + (zi - z) * (zi - z) > 2 ? portalFrameColor : portalColor;
if (alphaAt <= a) {
map.setPixel(xi, zi, markY(c, vec.y()));
}
}
}
continue;
}
if (other.hashCode() > hashCode)
continue;
if (turn == null) {
if (phase == PHASE_CURVES)
continue;
float x1 = nodeLocation.getX();
float z1 = nodeLocation.getZ();
float x2 = otherLocation.getX();
float z2 = otherLocation.getZ();
double y1 = nodeLocation.getLocation()
.y();
double y2 = otherLocation.getLocation()
.y();
float xDiffSign = Math.signum(x2 - x1);
float zDiffSign = Math.signum(z2 - z1);
boolean diagonal = xDiffSign != 0 && zDiffSign != 0;
if (xDiffSign != 0) {
x2 -= xDiffSign * .25;
x1 += xDiffSign * .25;
}
if (zDiffSign != 0) {
z2 -= zDiffSign * .25;
z1 += zDiffSign * .25;
}
x1 /= 2;
x2 /= 2;
z1 /= 2;
z2 /= 2;
int y = Mth.floor(y1);
int a = mapYtoAlpha(y);
// Diagonal
if (diagonal) {
int z = Mth.floor(z1);
int x = Mth.floor(x1);
for (int s = 0; s <= Math.abs(x1 - x2); s++) {
if (phase == PHASE_BACKGROUND) {
map.setPixels(x - 1, z, x + 1, z + 1, outlineColor);
map.setPixels(x, z - 1, x, z + 2, outlineColor);
x += xDiffSign;
z += zDiffSign;
continue;
}
int alphaAt = map.alphaAt(x, z);
if (alphaAt > 0 && alphaAt != a)
collisions.add(Couple.create(x, z));
if (alphaAt <= a) {
map.setPixel(x, z, markY(mainColor, y));
}
if (map.alphaAt(x, z + 1) < a) {
map.setPixel(x, z + 1, markY(darkerColor, y));
}
x += xDiffSign;
z += zDiffSign;
}
continue;
}
// Straight
if (phase == PHASE_BACKGROUND) {
int x1i = Mth.floor(Math.min(x1, x2));
int z1i = Mth.floor(Math.min(z1, z2));
int x2i = Mth.floor(Math.max(x1, x2));
int z2i = Mth.floor(Math.max(z1, z2));
map.setPixels(x1i - 1, z1i, x2i + 1, z2i, outlineColor);
map.setPixels(x1i, z1i - 1, x2i, z2i + 1, outlineColor);
continue;
}
int z = Mth.floor(z1);
int x = Mth.floor(x1);
float diff = Math.max(Math.abs(x1 - x2), Math.abs(z1 - z2));
double yStep = (y2 - y1) / diff;
for (int s = 0; s <= diff; s++) {
int alphaAt = map.alphaAt(x, z);
if (alphaAt > 0 && alphaAt != a)
collisions.add(Couple.create(x, z));
if (alphaAt <= a) {
map.setPixel(x, z, markY(mainColor, y));
}
x += xDiffSign;
y += yStep;
z += zDiffSign;
}
continue;
}
if (phase == PHASE_STRAIGHTS)
continue;
BlockPos origin = turn.bePositions.getFirst();
Map<Pair<Integer, Integer>, Double> rasterise = turn.rasterise();
for (boolean antialias : Iterate.falseAndTrue) {
for (Entry<Pair<Integer, Integer>, Double> offset : rasterise.entrySet()) {
Pair<Integer, Integer> xz = offset.getKey();
int x = origin.getX() + xz.getFirst();
int y = Mth.floor(origin.getY() + offset.getValue() + 0.5);
int z = origin.getZ() + xz.getSecond();
if (phase == PHASE_BACKGROUND) {
map.setPixels(x - 1, z, x + 1, z, outlineColor);
map.setPixels(x, z - 1, x, z + 1, outlineColor);
continue;
}
int a = mapYtoAlpha(y);
if (!antialias) {
int alphaAt = map.alphaAt(x, z);
if (alphaAt > 0 && alphaAt != a)
collisions.add(Couple.create(x, z));
if (alphaAt > a)
continue;
map.setPixel(x, z, markY(mainColor, y));
continue;
}
boolean mainColorBelowLeft =
map.is(x + 1, z + 1, mainColor) && Math.abs(map.alphaAt(x + 1, z + 1) - a) <= 1;
boolean mainColorBelowRight =
map.is(x - 1, z + 1, mainColor) && Math.abs(map.alphaAt(x - 1, z + 1) - a) <= 1;
if (mainColorBelowLeft || mainColorBelowRight) {
int alphaAt = map.alphaAt(x, z + 1);
if (alphaAt > 0 && alphaAt != a)
collisions.add(Couple.create(x, z));
if (alphaAt >= a)
continue;
map.setPixel(x, z + 1, markY(darkerColor, y));
// Adjust background
if (map.isEmpty(x + 1, z + 1))
map.setPixel(x + 1, z + 1, outlineColor);
if (map.isEmpty(x - 1, z + 1))
map.setPixel(x - 1, z + 1, outlineColor);
if (map.isEmpty(x, z + 2))
map.setPixel(x, z + 2, outlineColor);
}
}
if (phase == PHASE_BACKGROUND)
break;
}
}
}
}
}
private static void highlightYDifferences(TrainMapRenderer map, List<Couple<Integer>> collisions, int mainColor,
int darkerColor, int mainColorShadow, int darkerColorShadow) {
for (Couple<Integer> couple : collisions) {
int x = couple.getFirst();
int z = couple.getSecond();
int a = map.alphaAt(x, z);
if (a == 0)
continue;
for (int xi = x - 2; xi <= x + 2; xi++) {
for (int zi = z - 2; zi <= z + 2; zi++) {
if (map.alphaAt(xi, zi) >= a)
continue;
if (map.is(xi, zi, mainColor))
map.setPixel(xi, zi, FastColor.ABGR32.color(a, mainColorShadow));
else if (map.is(xi, zi, darkerColor))
map.setPixel(xi, zi, FastColor.ABGR32.color(a, darkerColorShadow));
}
}
}
}
private static int mapYtoAlpha(double y) {
int minY = Minecraft.getInstance().level.getMinBuildHeight();
return Mth.clamp(32 + Mth.floor((y - minY) / 4.0), 0, 255);
}
private static int markY(int color, double y) {
return FastColor.ABGR32.color(mapYtoAlpha(y), color);
}
}

View file

@ -0,0 +1,259 @@
package com.simibubi.create.compat.trainmap;
import java.util.HashSet;
import java.util.Set;
import org.joml.Matrix4f;
import com.mojang.blaze3d.platform.NativeImage;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.simibubi.create.foundation.render.RenderTypes;
import com.simibubi.create.infrastructure.config.CClient;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.createmod.catnip.utility.Couple;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.MultiBufferSource.BufferSource;
import net.minecraft.client.renderer.Rect2i;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.FastColor;
import net.minecraft.util.Mth;
import net.minecraft.world.level.Level;
public class TrainMapRenderer implements AutoCloseable {
public static final TrainMapRenderer INSTANCE = new TrainMapRenderer();
public static final int WIDTH = 128, HEIGHT = 128;
private Object2ObjectMap<Couple<Integer>, TrainMapInstance> maps = new Object2ObjectOpenHashMap<>();
public int trackingVersion;
public ResourceKey<Level> trackingDim;
public CClient.TrainMapTheme trackingTheme;
//
private TrainMapInstance previouslyAccessed;
public void startDrawing() {
previouslyAccessed = null;
maps.values()
.forEach(tmi -> {
tmi.getImage()
.fillRect(0, 0, WIDTH, HEIGHT, 0);
tmi.untouched = true;
});
}
public Object2ObjectMap<Couple<Integer>, TrainMapInstance> getMaps() {
return maps;
}
public void setPixel(int xCoord, int zCoord, int color) {
TrainMapInstance instance = getOrCreateAt(xCoord, zCoord);
xCoord = Mth.positiveModulo(xCoord, WIDTH);
zCoord = Mth.positiveModulo(zCoord, HEIGHT);
instance.getImage()
.setPixelRGBA(xCoord, zCoord, color);
}
public int getPixel(int xCoord, int zCoord) {
Couple<Integer> sectionKey = toSectionKey(xCoord, zCoord);
if (!maps.containsKey(sectionKey))
return 0;
TrainMapInstance instance = getOrCreateAt(xCoord, zCoord);
xCoord = Mth.positiveModulo(xCoord, WIDTH);
zCoord = Mth.positiveModulo(zCoord, HEIGHT);
return instance.getImage()
.getPixelRGBA(xCoord, zCoord);
}
public void setPixels(int xCoordFrom, int zCoordFrom, int xCoordTo, int zCoordTo, int color) {
for (int x = Math.min(xCoordFrom, xCoordTo); x <= Math.max(xCoordFrom, xCoordTo); x++)
for (int z = Math.min(zCoordFrom, zCoordTo); z <= Math.max(zCoordFrom, zCoordTo); z++)
setPixel(x, z, color);
}
public void blendPixel(int xCoord, int zCoord, int color, int alpha) {
TrainMapInstance instance = getOrCreateAt(xCoord, zCoord);
xCoord = Mth.positiveModulo(xCoord, WIDTH);
zCoord = Mth.positiveModulo(zCoord, HEIGHT);
instance.getImage()
.blendPixel(xCoord, zCoord, FastColor.ABGR32.color(alpha, color));
}
public void blendPixels(int xCoordFrom, int zCoordFrom, int xCoordTo, int zCoordTo, int color, int alpha) {
for (int x = Math.min(xCoordFrom, xCoordTo); x <= Math.max(xCoordFrom, xCoordTo); x++)
for (int z = Math.min(zCoordFrom, zCoordTo); z <= Math.max(zCoordFrom, zCoordTo); z++)
blendPixel(x, z, color, alpha);
}
public void finishDrawing() {
previouslyAccessed = null;
Set<Couple<Integer>> stale = new HashSet<>();
maps.forEach((key, tmi) -> {
if (!tmi.untouched)
return;
tmi.close();
stale.add(key);
});
stale.forEach(key -> {
TrainMapInstance tmi = maps.remove(key);
if (tmi != null)
tmi.close();
});
}
public boolean is(int x, int z, int color) {
return (getPixel(x, z) & 0xFFFFFF) == (color & 0xFFFFFF);
}
public boolean isEmpty(int x, int z) {
return getPixel(x, z) == 0;
}
public int alphaAt(int x, int z) {
int pixel = getPixel(x, z);
return ((pixel & 0xFFFFFF) != 0) ? ((pixel >>> 24) & 0xFF) : 0;
}
//
public void render(GuiGraphics graphics, int mouseX, int mouseY, float pt, boolean linearFiltering, Rect2i bounds) {
BufferSource bufferSource = graphics.bufferSource();
PoseStack pose = graphics.pose();
maps.forEach((key, tmi) -> {
if (tmi.canBeSkipped(bounds))
return;
int x = key.getFirst();
int y = key.getSecond();
pose.pushPose();
pose.translate(x * WIDTH, y * HEIGHT, 0);
tmi.draw(pose, bufferSource, linearFiltering);
pose.popPose();
});
}
public TrainMapInstance getOrCreateAt(int xCoord, int zCoord) {
Couple<Integer> sectionKey = toSectionKey(xCoord, zCoord);
if (previouslyAccessed != null && previouslyAccessed.sectionKey.equals(sectionKey))
return previouslyAccessed;
return maps.compute(sectionKey, (key, instance) -> instance == null ? new TrainMapInstance(key) : instance);
}
public Couple<Integer> toSectionKey(int xCoord, int zCoord) {
return Couple.create(Mth.floor(xCoord / (float) WIDTH), Mth.floor(zCoord / (float) HEIGHT));
}
public void resetData() {
for (TrainMapInstance instance : maps.values())
instance.close();
maps.clear();
}
public void close() {
this.resetData();
}
public class TrainMapInstance implements AutoCloseable {
private DynamicTexture texture;
private RenderType renderType;
private boolean requiresUpload;
private boolean linearFiltering;
private Rect2i bounds;
private boolean untouched;
private Couple<Integer> sectionKey;
public ResourceLocation location;
public TrainMapInstance(Couple<Integer> sectionKey) {
TextureManager textureManager = Minecraft.getInstance()
.getTextureManager();
this.sectionKey = sectionKey;
untouched = false;
requiresUpload = true;
texture = new DynamicTexture(128, 128, true);
linearFiltering = false;
location = textureManager
.register("create_trainmap/" + sectionKey.getFirst() + "_" + sectionKey.getSecond(), texture);
renderType = RenderTypes.TRAIN_MAP.apply(location, linearFiltering);
bounds = new Rect2i(sectionKey.getFirst() * WIDTH, sectionKey.getSecond() * HEIGHT, WIDTH, HEIGHT);
}
public boolean canBeSkipped(Rect2i bounds) {
return bounds.getX() + bounds.getWidth() < this.bounds.getX()
|| this.bounds.getX() + this.bounds.getWidth() < bounds.getX()
|| bounds.getY() + bounds.getHeight() < this.bounds.getY()
|| this.bounds.getY() + this.bounds.getHeight() < bounds.getY();
}
public NativeImage getImage() {
untouched = false;
requiresUpload = true;
return texture.getPixels();
}
public void draw(PoseStack pPoseStack, MultiBufferSource pBufferSource, boolean linearFiltering) {
if (texture.getPixels() == null)
return;
if (requiresUpload) {
texture.upload();
requiresUpload = false;
}
if (pPoseStack == null)
return;
if (linearFiltering != this.linearFiltering) {
this.linearFiltering = linearFiltering;
renderType = RenderTypes.TRAIN_MAP.apply(location, linearFiltering);
}
int pPackedLight = LightTexture.FULL_BRIGHT;
Matrix4f matrix4f = pPoseStack.last()
.pose();
VertexConsumer vertexconsumer = pBufferSource.getBuffer(renderType);
vertexconsumer.vertex(matrix4f, 0.0F, HEIGHT, 0)
.color(255, 255, 255, 255)
.uv(0.0F, 1.0F)
.uv2(pPackedLight)
.endVertex();
vertexconsumer.vertex(matrix4f, WIDTH, HEIGHT, 0)
.color(255, 255, 255, 255)
.uv(1.0F, 1.0F)
.uv2(pPackedLight)
.endVertex();
vertexconsumer.vertex(matrix4f, WIDTH, 0.0F, 0)
.color(255, 255, 255, 255)
.uv(1.0F, 0.0F)
.uv2(pPackedLight)
.endVertex();
vertexconsumer.vertex(matrix4f, 0.0F, 0.0F, 0)
.color(255, 255, 255, 255)
.uv(0.0F, 0.0F)
.uv2(pPackedLight)
.endVertex();
}
public void close() {
texture.close();
}
}
}

View file

@ -0,0 +1,353 @@
package com.simibubi.create.compat.trainmap;
import java.lang.ref.WeakReference;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.simibubi.create.AllPackets;
import com.simibubi.create.Create;
import com.simibubi.create.content.trains.entity.Carriage;
import com.simibubi.create.content.trains.entity.Carriage.DimensionalCarriageEntity;
import com.simibubi.create.content.trains.entity.Train;
import com.simibubi.create.content.trains.entity.TravellingPoint;
import com.simibubi.create.content.trains.graph.DimensionPalette;
import com.simibubi.create.content.trains.graph.EdgePointType;
import com.simibubi.create.content.trains.schedule.ScheduleRuntime;
import com.simibubi.create.content.trains.signal.SignalBlock.SignalType;
import com.simibubi.create.content.trains.signal.SignalBoundary;
import com.simibubi.create.content.trains.signal.SignalEdgeGroup;
import com.simibubi.create.content.trains.station.GlobalStation;
import net.createmod.catnip.utility.Pair;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Mth;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.event.TickEvent.ServerTickEvent;
import net.minecraftforge.network.PacketDistributor;
public class TrainMapSync {
public static final int lightPacketInterval = 5;
public static final int fullPacketInterval = 10;
public static int ticks;
public enum TrainState {
RUNNING, RUNNING_MANUALLY, DERAILED, SCHEDULE_INTERRUPTED, CONDUCTOR_MISSING, NAVIGATION_FAILED
}
public enum SignalState {
NOT_WAITING, WAITING_FOR_REDSTONE, BLOCK_SIGNAL, CHAIN_SIGNAL
}
public static class TrainMapSyncEntry {
// Clientside
public float[] prevPositions;
public List<ResourceKey<Level>> prevDims;
// Updated every 5 ticks
public float[] positions;
public List<ResourceKey<Level>> dimensions;
public TrainState state = TrainState.RUNNING;
public SignalState signalState = SignalState.NOT_WAITING;
public boolean fueled = false;
public boolean backwards = false;
public int targetStationDistance = 0;
// Updated every 10 ticks
public String ownerName = "";
public String targetStationName = "";
public UUID waitingForTrain = null;
public void gatherDimensions(DimensionPalette dimensionPalette) {
for (ResourceKey<Level> resourceKey : dimensions)
if (resourceKey != null)
dimensionPalette.encode(resourceKey);
}
public void send(FriendlyByteBuf buffer, DimensionPalette dimensionPalette, boolean light) {
buffer.writeVarInt(positions.length);
for (float f : positions)
buffer.writeFloat(f);
buffer.writeVarInt(dimensions.size());
for (ResourceKey<Level> resourceKey : dimensions)
buffer.writeVarInt(resourceKey == null ? -1 : dimensionPalette.encode(resourceKey));
buffer.writeVarInt(state.ordinal());
buffer.writeVarInt(signalState.ordinal());
buffer.writeBoolean(fueled);
buffer.writeBoolean(backwards);
buffer.writeVarInt(targetStationDistance);
if (light)
return;
buffer.writeUtf(ownerName);
buffer.writeUtf(targetStationName);
buffer.writeBoolean(waitingForTrain != null);
if (waitingForTrain != null)
buffer.writeUUID(waitingForTrain);
}
public void receive(FriendlyByteBuf buffer, DimensionPalette dimensionPalette, boolean light) {
positions = new float[buffer.readVarInt()];
for (int i = 0; i < positions.length; i++)
positions[i] = buffer.readFloat();
dimensions = new ArrayList<>();
int dimensionsSize = buffer.readVarInt();
for (int i = 0; i < dimensionsSize; i++) {
int index = buffer.readVarInt();
dimensions.add(index == -1 ? null : dimensionPalette.decode(index));
}
state = TrainState.values()[buffer.readVarInt()];
signalState = SignalState.values()[buffer.readVarInt()];
fueled = buffer.readBoolean();
backwards = buffer.readBoolean();
targetStationDistance = buffer.readVarInt();
if (light)
return;
ownerName = buffer.readUtf();
targetStationName = buffer.readUtf();
waitingForTrain = null;
if (buffer.readBoolean())
waitingForTrain = buffer.readUUID();
}
public void updateFrom(TrainMapSyncEntry other, boolean light) {
prevPositions = positions;
prevDims = dimensions;
positions = other.positions;
dimensions = other.dimensions;
state = other.state;
signalState = other.signalState;
fueled = other.fueled;
backwards = other.backwards;
targetStationDistance = other.targetStationDistance;
if (prevDims != null)
for (int i = 0; i < Math.min(prevDims.size(), dimensions.size()); i++)
if (prevDims.get(i) != dimensions.get(i))
for (int j = 0; j < 6; j++)
prevPositions[i * 6 + j] = positions[i * 6 + j];
if (light)
return;
ownerName = other.ownerName;
targetStationName = other.targetStationName;
waitingForTrain = other.waitingForTrain;
}
public Vec3 getPosition(int carriageIndex, boolean firstBogey, double time) {
int startIndex = carriageIndex * 6 + (firstBogey ? 0 : 3);
if (positions == null || positions.length <= startIndex + 2)
return Vec3.ZERO;
Vec3 position = new Vec3(positions[startIndex], positions[startIndex + 1], positions[startIndex + 2]);
if (prevPositions == null || prevPositions.length <= startIndex + 2)
return position;
Vec3 prevPosition =
new Vec3(prevPositions[startIndex], prevPositions[startIndex + 1], prevPositions[startIndex + 2]);
return prevPosition.lerp(position, time);
}
}
public static Cache<UUID, WeakReference<ServerPlayer>> requestingPlayers = CacheBuilder.newBuilder()
.expireAfterWrite(Duration.ofSeconds(1))
.build();
public static void requestReceived(ServerPlayer sender) {
boolean sendImmediately = requestingPlayers.getIfPresent(sender.getUUID()) == null;
requestingPlayers.put(sender.getUUID(), new WeakReference<>(sender));
if (sendImmediately)
send(sender.server, false);
}
public static void serverTick(ServerTickEvent event) {
ticks++;
if (ticks % fullPacketInterval == 0)
send(event.getServer(), false);
else if (ticks % lightPacketInterval == 0)
send(event.getServer(), true);
}
public static void send(MinecraftServer minecraftServer, boolean light) {
if (requestingPlayers.size() == 0)
return;
TrainMapSyncPacket packet = new TrainMapSyncPacket(light);
for (Train train : Create.RAILWAYS.trains.values())
packet.add(train.id, createEntry(minecraftServer, train));
for (WeakReference<ServerPlayer> weakReference : requestingPlayers.asMap()
.values()) {
ServerPlayer player = weakReference.get();
if (player == null)
continue;
AllPackets.getChannel()
.send(PacketDistributor.PLAYER.with(() -> player), packet);
}
}
private static TrainMapSyncEntry createEntry(MinecraftServer minecraftServer, Train train) {
TrainMapSyncEntry entry = new TrainMapSyncEntry();
boolean stopped = Math.abs(train.speed) < 0.05;
entry.positions = new float[train.carriages.size() * 6];
entry.dimensions = new ArrayList<>();
List<Carriage> carriages = train.carriages;
for (int i = 0; i < carriages.size(); i++) {
Carriage carriage = carriages.get(i);
Vec3 leadingPos;
Vec3 trailingPos;
if (train.graph == null) {
// Train is derailed
Pair<ResourceKey<Level>, DimensionalCarriageEntity> dimCarriage =
carriage.anyAvailableDimensionalCarriage();
if (dimCarriage == null || carriage.presentInMultipleDimensions()) {
entry.dimensions.add(null);
continue;
}
leadingPos = dimCarriage.getSecond().rotationAnchors.getFirst();
trailingPos = dimCarriage.getSecond().rotationAnchors.getSecond();
if (leadingPos == null || trailingPos == null) {
entry.dimensions.add(null);
continue;
}
entry.dimensions.add(dimCarriage.getFirst());
} else {
// Train is on Track
TravellingPoint leading = carriage.getLeadingPoint();
TravellingPoint trailing = carriage.getTrailingPoint();
if (leading == null || trailing == null || leading.edge == null || trailing.edge == null) {
entry.dimensions.add(null);
continue;
}
ResourceKey<Level> leadingDim =
(leading.node1 == null || leading.edge == null || leading.edge.isInterDimensional()) ? null
: leading.node1.getLocation()
.getDimension();
ResourceKey<Level> trailingDim =
(trailing.node1 == null || trailing.edge == null || trailing.edge.isInterDimensional()) ? null
: trailing.node1.getLocation()
.getDimension();
ResourceKey<Level> carriageDim = (leadingDim == null || leadingDim != trailingDim) ? null : leadingDim;
entry.dimensions.add(carriageDim);
leadingPos = leading.getPosition(train.graph);
trailingPos = trailing.getPosition(train.graph);
}
entry.positions[i * 6] = (float) leadingPos.x();
entry.positions[i * 6 + 1] = (float) leadingPos.y();
entry.positions[i * 6 + 2] = (float) leadingPos.z();
entry.positions[i * 6 + 3] = (float) trailingPos.x();
entry.positions[i * 6 + 4] = (float) trailingPos.y();
entry.positions[i * 6 + 5] = (float) trailingPos.z();
}
entry.backwards = train.currentlyBackwards;
if (train.owner != null) {
ServerPlayer owner = minecraftServer.getPlayerList()
.getPlayer(train.owner);
if (owner != null)
entry.ownerName = owner.getName()
.getString();
}
if (train.derailed) {
entry.state = TrainState.DERAILED;
return entry;
}
ScheduleRuntime runtime = train.runtime;
if (runtime.getSchedule() != null && stopped) {
if (runtime.paused) {
entry.state = TrainState.SCHEDULE_INTERRUPTED;
return entry;
}
if (train.status.conductor) {
entry.state = TrainState.CONDUCTOR_MISSING;
return entry;
}
if (train.status.navigation) {
entry.state = TrainState.NAVIGATION_FAILED;
return entry;
}
}
if ((runtime.getSchedule() == null || runtime.paused) && train.speed != 0)
entry.state = TrainState.RUNNING_MANUALLY;
GlobalStation currentStation = train.getCurrentStation();
if (currentStation != null) {
entry.targetStationName = currentStation.name;
entry.targetStationDistance = 0;
} else if (train.navigation.destination != null && !runtime.paused) {
entry.targetStationName = train.navigation.destination.name;
entry.targetStationDistance = Math.max(0, Mth.floor(train.navigation.distanceToDestination));
}
if (stopped && train.navigation.waitingForSignal != null) {
UUID signalId = train.navigation.waitingForSignal.getFirst();
boolean side = train.navigation.waitingForSignal.getSecond();
SignalBoundary signal = train.graph.getPoint(EdgePointType.SIGNAL, signalId);
if (signal != null) {
boolean chainSignal = signal.types.get(side) == SignalType.CROSS_SIGNAL;
entry.signalState = chainSignal ? SignalState.CHAIN_SIGNAL : SignalState.BLOCK_SIGNAL;
if (signal.isForcedRed(side))
entry.signalState = SignalState.WAITING_FOR_REDSTONE;
else {
SignalEdgeGroup group = Create.RAILWAYS.signalEdgeGroups.get(signal.groups.get(side));
if (group != null) {
for (Train other : group.trains) {
if (other == train)
continue;
entry.waitingForTrain = other.id;
break;
}
}
}
}
}
if (train.fuelTicks > 0 && !stopped)
entry.fueled = true;
return entry;
}
}

View file

@ -0,0 +1,57 @@
package com.simibubi.create.compat.trainmap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import com.simibubi.create.AllPackets;
import com.simibubi.create.compat.trainmap.TrainMapSync.TrainMapSyncEntry;
import net.createmod.catnip.utility.AnimationTickHolder;
import net.createmod.catnip.utility.Pair;
public class TrainMapSyncClient {
public static Map<UUID, TrainMapSyncEntry> currentData = new HashMap<>();
public static double lastPacket;
private static int ticks;
public static void requestData() {
ticks++;
if (ticks % 5 == 0)
AllPackets.getChannel()
.sendToServer(new TrainMapSyncRequestPacket());
}
public static void stopRequesting() {
ticks = 0;
currentData.clear();
}
public static void receive(TrainMapSyncPacket packet) {
if (ticks == 0)
return;
lastPacket = AnimationTickHolder.getTicks();
lastPacket += AnimationTickHolder.getPartialTicks();
Set<UUID> staleEntries = new HashSet<>();
staleEntries.addAll(currentData.keySet());
for (Pair<UUID, TrainMapSyncEntry> pair : packet.entries) {
UUID id = pair.getFirst();
TrainMapSyncEntry entry = pair.getSecond();
staleEntries.remove(id);
currentData.computeIfAbsent(id, $ -> entry)
.updateFrom(entry, packet.light);
}
for (UUID uuid : staleEntries)
currentData.remove(uuid);
}
}

View file

@ -0,0 +1,65 @@
package com.simibubi.create.compat.trainmap;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import com.simibubi.create.compat.trainmap.TrainMapSync.TrainMapSyncEntry;
import com.simibubi.create.content.trains.graph.DimensionPalette;
import com.simibubi.create.foundation.networking.SimplePacketBase;
import net.createmod.catnip.utility.Pair;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.network.NetworkEvent.Context;
public class TrainMapSyncPacket extends SimplePacketBase {
public List<Pair<UUID, TrainMapSyncEntry>> entries = new ArrayList<>();
public boolean light;
public TrainMapSyncPacket(boolean light) {
this.light = light;
}
public void add(UUID trainId, TrainMapSyncEntry data) {
entries.add(Pair.of(trainId, data));
}
public TrainMapSyncPacket(FriendlyByteBuf buffer) {
DimensionPalette dimensionPalette = DimensionPalette.receive(buffer);
light = buffer.readBoolean();
int size = buffer.readVarInt();
for (int i = 0; i < size; i++) {
UUID id = buffer.readUUID();
TrainMapSyncEntry entry = new TrainMapSyncEntry();
entry.receive(buffer, dimensionPalette, light);
entries.add(Pair.of(id, entry));
}
}
@Override
public void write(FriendlyByteBuf buffer) {
DimensionPalette dimensionPalette = new DimensionPalette();
for (Pair<UUID, TrainMapSyncEntry> pair : entries)
pair.getSecond()
.gatherDimensions(dimensionPalette);
dimensionPalette.send(buffer);
buffer.writeBoolean(light);
buffer.writeVarInt(entries.size());
for (Pair<UUID, TrainMapSyncEntry> pair : entries) {
buffer.writeUUID(pair.getFirst());
pair.getSecond()
.send(buffer, dimensionPalette, light);
}
}
@Override
public boolean handle(Context context) {
context.enqueueWork(() -> TrainMapSyncClient.receive(this));
return true;
}
}

View file

@ -0,0 +1,23 @@
package com.simibubi.create.compat.trainmap;
import com.simibubi.create.foundation.networking.SimplePacketBase;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.network.NetworkEvent.Context;
public class TrainMapSyncRequestPacket extends SimplePacketBase {
public TrainMapSyncRequestPacket() {}
public TrainMapSyncRequestPacket(FriendlyByteBuf buffer) {}
@Override
public void write(FriendlyByteBuf buffer) {}
@Override
public boolean handle(Context context) {
context.enqueueWork(() -> TrainMapSync.requestReceived(context.getSender()));
return true;
}
}

View file

@ -1143,6 +1143,7 @@ public abstract class Contraption {
if (blockEntity instanceof IMultiBlockEntityContainer) {
if (tag.contains("LastKnownPos") || capturedMultiblocks.isEmpty()) {
tag.put("LastKnownPos", NbtUtils.writeBlockPos(BlockPos.ZERO.below(Integer.MAX_VALUE - 1)));
tag.remove("Controller");
}
}
@ -1199,6 +1200,9 @@ public abstract class Contraption {
// swap nbt data to the new controller position
StructureBlockInfo prevControllerInfo = blocks.get(controllerPos);
StructureBlockInfo newControllerInfo = blocks.get(otherPos);
if (prevControllerInfo == null || newControllerInfo == null)
return;
blocks.put(otherPos, new StructureBlockInfo(newControllerInfo.pos(), newControllerInfo.state(), prevControllerInfo.nbt()));
blocks.put(controllerPos, new StructureBlockInfo(prevControllerInfo.pos(), prevControllerInfo.state(), newControllerInfo.nbt()));
});
@ -1384,6 +1388,9 @@ public abstract class Contraption {
private void gatherBBsOffThread() {
getContraptionWorld();
if (simplifiedEntityColliderProvider != null) {
simplifiedEntityColliderProvider.cancel(false);
}
simplifiedEntityColliderProvider = CompletableFuture.supplyAsync(() -> {
VoxelShape combinedShape = Shapes.empty();
for (Entry<BlockPos, StructureBlockInfo> entry : blocks.entrySet()) {
@ -1400,7 +1407,6 @@ public abstract class Contraption {
})
.thenAccept(r -> {
simplifiedEntityColliders = Optional.of(r);
simplifiedEntityColliderProvider = null;
});
}

View file

@ -2,6 +2,7 @@ package com.simibubi.create.content.contraptions;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllTags.AllBlockTags;
import com.simibubi.create.content.equipment.toolbox.ToolboxInventory;
import com.simibubi.create.content.kinetics.crafter.MechanicalCrafterBlockEntity;
import com.simibubi.create.content.logistics.crate.BottomlessItemHandler;
import com.simibubi.create.content.logistics.vault.ItemVaultBlockEntity;
@ -176,6 +177,8 @@ public class MountedStorage {
CompoundTag tag = handler.serializeNBT();
if (noFuel)
NBTHelper.putMarker(tag, "NoFuel");
if (handler instanceof ToolboxInventory)
NBTHelper.putMarker(tag, "Toolbox");
if (!(handler instanceof BottomlessItemHandler))
return tag;
@ -190,6 +193,9 @@ public class MountedStorage {
storage.handler = new ItemStackHandler();
if (nbt == null)
return storage;
if (nbt.contains("Toolbox"))
storage.handler = new ToolboxInventory(null);
storage.valid = true;
storage.noFuel = nbt.contains("NoFuel");

View file

@ -68,6 +68,8 @@ public class ClipboardBlockEntity extends SmartBlockEntity {
protected void read(CompoundTag tag, boolean clientPacket) {
super.read(tag, clientPacket);
dataContainer = ItemStack.of(tag.getCompound("Item"));
if (!AllBlocks.CLIPBOARD.isIn(dataContainer))
dataContainer = AllBlocks.CLIPBOARD.asStack();
if (clientPacket)
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> readClientSide(tag));

View file

@ -52,19 +52,13 @@ public class SymmetryHandler {
if (event.getLevel()
.isClientSide())
return;
if (!(event.getEntity() instanceof Player))
if (!(event.getEntity() instanceof Player player))
return;
Player player = (Player) event.getEntity();
Inventory inv = player.getInventory();
for (int i = 0; i < Inventory.getSelectionSize(); i++) {
if (!inv.getItem(i)
.isEmpty()
&& inv.getItem(i)
.getItem() == AllItems.WAND_OF_SYMMETRY.get()) {
for (int i = 0; i < Inventory.getSelectionSize(); i++)
if (AllItems.WAND_OF_SYMMETRY.isIn(inv.getItem(i)))
SymmetryWandItem.apply(player.level(), inv.getItem(i), player, event.getPos(), event.getPlacedBlock());
}
}
}
@SubscribeEvent(priority = EventPriority.LOWEST)
@ -75,12 +69,9 @@ public class SymmetryHandler {
Player player = event.getPlayer();
Inventory inv = player.getInventory();
for (int i = 0; i < Inventory.getSelectionSize(); i++) {
if (!inv.getItem(i)
.isEmpty() && AllItems.WAND_OF_SYMMETRY.isIn(inv.getItem(i))) {
for (int i = 0; i < Inventory.getSelectionSize(); i++)
if (AllItems.WAND_OF_SYMMETRY.isIn(inv.getItem(i)))
SymmetryWandItem.remove(player.level(), inv.getItem(i), player, event.getPos());
}
}
}
@OnlyIn(Dist.CLIENT)

View file

@ -9,6 +9,7 @@ import java.util.function.Consumer;
import javax.annotation.Nonnull;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems;
import com.simibubi.create.AllPackets;
import com.simibubi.create.content.contraptions.mounted.CartAssemblerBlock;
import com.simibubi.create.content.equipment.symmetryWand.mirror.CrossPlaneMirror;
@ -27,6 +28,7 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.Item;
@ -328,5 +330,13 @@ public class SymmetryWandItem extends Item {
public void initializeClient(Consumer<IClientItemExtensions> consumer) {
consumer.accept(SimpleCustomRenderer.create(this, new SymmetryWandItemRenderer()));
}
public static boolean presentInHotbar(Player player) {
Inventory inv = player.getInventory();
for (int i = 0; i < Inventory.getSelectionSize(); i++)
if (AllItems.WAND_OF_SYMMETRY.isIn(inv.getItem(i)))
return true;
return false;
}
}

View file

@ -83,7 +83,7 @@ public class ToolboxInventory extends ItemStackHandler {
}
}
settling = false;
blockEntity.sendData();
notifyUpdate();
}
@Override
@ -109,7 +109,7 @@ public class ToolboxInventory extends ItemStackHandler {
if (!stack.isEmpty() && filters.get(compartment)
.isEmpty()) {
filters.set(compartment, ItemHandlerHelper.copyStackWithSize(stack, 1));
blockEntity.sendData();
notifyUpdate();
}
}
@ -121,7 +121,7 @@ public class ToolboxInventory extends ItemStackHandler {
if (!stack.isEmpty() && filters.get(compartment)
.isEmpty()) {
filters.set(compartment, ItemHandlerHelper.copyStackWithSize(stack, 1));
blockEntity.sendData();
notifyUpdate();
}
}
return insertItem;
@ -136,10 +136,9 @@ public class ToolboxInventory extends ItemStackHandler {
@Override
protected void onContentsChanged(int slot) {
if (!settling && !blockEntity.getLevel().isClientSide)
if (!settling && (blockEntity == null || !blockEntity.getLevel().isClientSide))
settle(slot / STACKS_PER_COMPARTMENT);
blockEntity.sendData();
blockEntity.setChanged();
notifyUpdate();
super.onContentsChanged(slot);
}
@ -208,4 +207,9 @@ public class ToolboxInventory extends ItemStackHandler {
return ItemHandlerHelper.canItemStacksStack(stack1, stack2);
}
private void notifyUpdate() {
if (blockEntity != null)
blockEntity.notifyUpdate();
}
}

View file

@ -2,6 +2,7 @@ package com.simibubi.create.content.fluids.drain;
import com.simibubi.create.content.fluids.transfer.GenericItemEmptying;
import com.simibubi.create.content.kinetics.belt.transport.TransportedItemStack;
import com.simibubi.create.foundation.item.ItemHelper;
import net.minecraft.core.Direction;
import net.minecraft.world.item.ItemStack;
@ -38,7 +39,8 @@ public class ItemDrainItemHandler implements IItemHandler {
if (stack.getCount() > 1 && GenericItemEmptying.canItemBeEmptied(blockEntity.getLevel(), stack)) {
returned = ItemHandlerHelper.copyStackWithSize(stack, stack.getCount() - 1);
stack = ItemHandlerHelper.copyStackWithSize(stack, 1);
}
} else
returned = ItemHelper.limitCountToMaxStackSize(stack, simulate);
if (!simulate) {
TransportedItemStack heldItem = new TransportedItemStack(stack);

View file

@ -3,6 +3,7 @@ package com.simibubi.create.content.fluids.tank;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.api.connectivity.ConnectivityHandler;
import com.simibubi.create.content.equipment.symmetryWand.SymmetryWandItem;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@ -75,6 +76,8 @@ public class FluidTankItem extends BlockItem {
if (!FluidTankBlock.isTank(placedOnState))
return;
if (SymmetryWandItem.presentInHotbar(player))
return;
boolean creative = getBlock().equals(AllBlocks.CREATIVE_FLUID_TANK.get());
FluidTankBlockEntity tankAt = ConnectivityHandler.partAt(
creative ? AllBlockEntityTypes.CREATIVE_FLUID_TANK.get() : AllBlockEntityTypes.FLUID_TANK.get(), world, placedOnPos

View file

@ -73,9 +73,8 @@ public abstract class GeneratingKineticBlockEntity extends KineticBlockEntity {
float speed = getTheoreticalSpeed();
if (speed != getGeneratedSpeed() && speed != 0)
stressBase *= getGeneratedSpeed() / speed;
speed = Math.abs(speed);
float stressTotal = stressBase * speed;
float stressTotal = Math.abs(stressBase * speed);
CreateLang.number(stressTotal)
.translate("generic.unit.stress")

View file

@ -51,6 +51,7 @@ import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.ItemStack;
@ -223,6 +224,8 @@ public class BeltBlock extends HorizontalKineticBlock
ItemStack remainder = handler.insertItem(0, asItem, false);
if (remainder.isEmpty())
entityIn.discard();
else if (entityIn instanceof ItemEntity itemEntity && remainder.getCount() != itemEntity.getItem().getCount())
itemEntity.setItem(remainder);
});
return;
}

View file

@ -259,7 +259,7 @@ public class BeltRenderer extends SafeBlockEntityRenderer<BeltBlockEntity> {
be.getBlockPos().getZ())
.add(offsetVec);
if (this.shouldCullItem(itemPos)) {
if (this.shouldCullItem(itemPos, be.getLevel())) {
return;
}

View file

@ -1,5 +1,7 @@
package com.simibubi.create.content.kinetics.belt.transport;
import com.simibubi.create.foundation.item.ItemHelper;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
@ -29,6 +31,7 @@ public class ItemHandlerBeltSegment implements IItemHandler {
@Override
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
if (this.beltInventory.canInsertAt(offset)) {
ItemStack remainder = ItemHelper.limitCountToMaxStackSize(stack, simulate);
if (!simulate) {
TransportedItemStack newStack = new TransportedItemStack(stack);
newStack.insertedAt = offset;
@ -38,7 +41,7 @@ public class ItemHandlerBeltSegment implements IItemHandler {
this.beltInventory.belt.setChanged();
this.beltInventory.belt.sendData();
}
return ItemStack.EMPTY;
return remainder;
}
return stack;
}

View file

@ -120,6 +120,12 @@ public class MechanicalCrafterBlockEntity extends KineticBlockEntity {
registerAwardables(behaviours, AllAdvancements.CRAFTER, AllAdvancements.CRAFTER_LAZY);
}
@Override
public void invalidateCaps() {
inserting.removeListener();
super.invalidateCaps();
}
@Override
public void onSpeedChanged(float previousSpeed) {
super.onSpeedChanged(previousSpeed);
@ -132,6 +138,7 @@ public class MechanicalCrafterBlockEntity extends KineticBlockEntity {
public void blockChanged() {
removeBehaviour(InvManipulationBehaviour.TYPE);
inserting.removeListener();
inserting = new InvManipulationBehaviour(this, this::getTargetFace);
attachBehaviourLate(inserting);
}

View file

@ -1,6 +1,7 @@
package com.simibubi.create.content.kinetics.deployer;
import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringBehaviour;
import com.simibubi.create.foundation.item.ItemHelper;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.item.ItemStack;
@ -52,9 +53,10 @@ public class DeployerItemHandler implements IItemHandlerModifiable {
ItemStack held = getHeld();
if (held.isEmpty()) {
ItemStack remainder = ItemHelper.limitCountToMaxStackSize(stack, simulate);
if (!simulate)
set(stack);
return ItemStack.EMPTY;
return remainder;
}
if (!ItemHandlerHelper.canItemStacksStack(held, stack))

View file

@ -1,5 +1,7 @@
package com.simibubi.create.content.logistics.chute;
import com.simibubi.create.foundation.item.ItemHelper;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
@ -25,9 +27,10 @@ public class ChuteItemHandler implements IItemHandler {
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
if (!blockEntity.canAcceptItem(stack))
return stack;
ItemStack remainder = ItemHelper.limitCountToMaxStackSize(stack, simulate);
if (!simulate)
blockEntity.setItem(stack);
return ItemStack.EMPTY;
return remainder;
}
@Override

View file

@ -95,7 +95,7 @@ public abstract class FunnelBlock extends AbstractDirectionalFunnelBlock {
withBlockEntityDo(worldIn, pos, be -> {
ItemStack toInsert = heldItem.copy();
ItemStack remainder = tryInsert(worldIn, pos, toInsert, false);
if (!ItemStack.matches(remainder, toInsert))
if (!ItemStack.matches(remainder, toInsert) || remainder.getCount() != heldItem.getCount())
player.setItemInHand(handIn, remainder);
});
return InteractionResult.SUCCESS;

View file

@ -276,6 +276,12 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering
registerAwardables(behaviours, AllAdvancements.FUNNEL);
}
@Override
public void invalidateCaps() {
invManipulation.removeListener();
super.invalidateCaps();
}
private boolean supportsAmountOnFilter() {
BlockState blockState = getBlockState();
boolean beltFunnelsupportsAmount = false;

View file

@ -1,5 +1,7 @@
package com.simibubi.create.content.logistics.tunnel;
import com.simibubi.create.foundation.item.ItemHelper;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.IItemHandler;
@ -33,9 +35,11 @@ public class BrassTunnelItemHandler implements IItemHandler {
if (!blockEntity.canTakeItems())
return stack;
ItemStack remainder = ItemHelper.limitCountToMaxStackSize(stack, simulate);
if (!simulate)
blockEntity.setStackToDistribute(stack, null);
return ItemStack.EMPTY;
return remainder;
}
@Override

View file

@ -2,6 +2,7 @@ package com.simibubi.create.content.logistics.vault;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.api.connectivity.ConnectivityHandler;
import com.simibubi.create.content.equipment.symmetryWand.SymmetryWandItem;
import net.createmod.catnip.utility.VecHelper;
import net.minecraft.core.BlockPos;
@ -65,6 +66,8 @@ public class ItemVaultItem extends BlockItem {
if (!ItemVaultBlock.isVault(placedOnState))
return;
if (SymmetryWandItem.presentInHotbar(player))
return;
ItemVaultBlockEntity tankAt = ConnectivityHandler.partAt(AllBlockEntityTypes.ITEM_VAULT.get(), world, placedOnPos);
if (tankAt == null)
return;

View file

@ -411,7 +411,8 @@ public class BasinBlockEntity extends SmartBlockEntity implements IHaveGoggleInf
if (filter != null && !filter.test(itemStack))
continue;
visualizedOutputItems.add(IntAttached.withZero(itemStack));
if (visualizedOutputItems.size() < 3)
visualizedOutputItems.add(IntAttached.withZero(itemStack));
update = true;
remainder = ItemHandlerHelper.insertItemStacked(targetInv, itemStack.copy(), false);
@ -445,7 +446,8 @@ public class BasinBlockEntity extends SmartBlockEntity implements IHaveGoggleInf
update = true;
iterator.remove();
visualizedOutputFluids.add(IntAttached.withZero(fluidStack));
if (visualizedOutputFluids.size() < 3)
visualizedOutputFluids.add(IntAttached.withZero(fluidStack));
}
}

View file

@ -13,6 +13,7 @@ import com.simibubi.create.content.trains.display.FlapDisplayBlockEntity;
import com.simibubi.create.content.trains.display.FlapDisplayLayout;
import com.simibubi.create.foundation.gui.ModularGuiLineBuilder;
import net.createmod.catnip.utility.NBTProcessors;
import net.createmod.catnip.utility.lang.Components;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
@ -38,6 +39,12 @@ public abstract class DisplaySource extends DisplayBehaviour {
List<MutableComponent> text = provideText(context, stats);
if (text.isEmpty())
text = EMPTY;
if (activeTarget.requiresComponentSanitization())
for (MutableComponent component : text)
if (NBTProcessors.textComponentHasClickEvent(component))
return; // Naughty
activeTarget.acceptText(line, text, context);
}

View file

@ -67,5 +67,9 @@ public abstract class DisplayTarget extends DisplayBehaviour {
tag.remove("DisplayLink");
return false;
}
public boolean requiresComponentSanitization() {
return false;
}
}

View file

@ -80,5 +80,10 @@ public class LecternDisplayTarget extends DisplayTarget {
return written;
}
@Override
public boolean requiresComponentSanitization() {
return true;
}
}

View file

@ -41,5 +41,10 @@ public class SignDisplayTarget extends DisplayTarget {
public DisplayTargetStats provideStats(DisplayLinkContext context) {
return new DisplayTargetStats(4, 15, this);
}
@Override
public boolean requiresComponentSanitization() {
return true;
}
}

View file

@ -56,6 +56,13 @@ public class SmartObserverBlockEntity extends SmartBlockEntity {
behaviours.add(observedTank = new TankManipulationBehaviour(this, towardBlockFacing).bypassSidedness());
}
@Override
public void invalidateCaps() {
observedInventory.removeListener();
observedTank.removeListener();
super.invalidateCaps();
}
@Override
public void tick() {
super.tick();

View file

@ -319,6 +319,17 @@ public class ThresholdSwitchBlockEntity extends SmartBlockEntity {
behaviours.add(observedTank = new TankManipulationBehaviour(this, towardBlockFacing).bypassSidedness());
}
@Override
public void invalidateCaps() {
observedInventory.removeListener();
observedTank.removeListener();
super.invalidateCaps();
}
public float getLevelForDisplay() {
return currentLevel == -1 ? 0 : currentLevel;
}
public boolean getState() {
return redstoneState;
}

View file

@ -48,6 +48,8 @@ public class GlobalRailwayManager {
private List<Train> waitingTrains;
private RailwaySavedData savedData;
public int version;
public GlobalRailwayManager() {
cleanUp();

View file

@ -31,6 +31,7 @@ import com.simibubi.create.foundation.advancement.AllAdvancements;
import net.createmod.catnip.utility.Couple;
import net.createmod.catnip.utility.Iterate;
import net.createmod.catnip.utility.NBTHelper;
import net.createmod.catnip.utility.Pair;
import net.createmod.catnip.utility.VecHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
@ -431,6 +432,13 @@ public class Carriage {
return null;
}
public Pair<ResourceKey<Level>, DimensionalCarriageEntity> anyAvailableDimensionalCarriage() {
for (Entry<ResourceKey<Level>, DimensionalCarriageEntity> entry : entities.entrySet())
if (entry.getValue().entity.get() != null)
return Pair.of(entry.getKey(), entry.getValue());
return null;
}
public void forEachPresentEntity(Consumer<CarriageContraptionEntity> callback) {
for (DimensionalCarriageEntity dimensionalCarriageEntity : entities.values()) {
CarriageContraptionEntity entity = dimensionalCarriageEntity.entity.get();

View file

@ -95,6 +95,7 @@ public class Train {
public Navigation navigation;
public ScheduleRuntime runtime;
public TrainIconType icon;
public int mapColorIndex;
public Component name;
public TrainStatus status;
@ -933,6 +934,8 @@ public class Train {
@Nullable
public LivingEntity getOwner(Level level) {
if (level.getServer() == null)
return null;
try {
UUID uuid = owner;
return uuid == null ? null
@ -1131,6 +1134,7 @@ public class Train {
tag.putInt("Fuel", fuelTicks);
tag.putDouble("TargetSpeed", targetSpeed);
tag.putString("IconType", icon.id.toString());
tag.putInt("MapColorIndex", mapColorIndex);
tag.putString("Name", Component.Serializer.toJson(name));
if (currentStation != null)
tag.putUUID("Station", currentStation);
@ -1183,6 +1187,7 @@ public class Train {
train.speedBeforeStall = tag.getDouble("SpeedBeforeStall");
train.targetSpeed = tag.getDouble("TargetSpeed");
train.icon = TrainIconType.byId(new ResourceLocation(tag.getString("IconType")));
train.mapColorIndex = tag.getInt("MapColorIndex");
train.name = Component.Serializer.fromJson(tag.getString("Name"));
train.currentStation = tag.contains("Station") ? tag.getUUID("Station") : null;
train.currentlyBackwards = tag.getBoolean("Backwards");

View file

@ -68,6 +68,7 @@ public class TrainPacket extends SimplePacketBase {
train.name = Component.Serializer.fromJson(buffer.readUtf());
train.icon = TrainIconType.byId(buffer.readResourceLocation());
train.mapColorIndex = buffer.readVarInt();
}
@Override
@ -105,6 +106,7 @@ public class TrainPacket extends SimplePacketBase {
buffer.writeBoolean(train.doubleEnded);
buffer.writeUtf(Component.Serializer.toJson(train.name));
buffer.writeResourceLocation(train.icon.id);
buffer.writeVarInt(train.mapColorIndex);
}
@Override

View file

@ -21,9 +21,9 @@ public class TrainStatus {
Train train;
boolean navigation;
boolean track;
boolean conductor;
public boolean navigation;
public boolean track;
public boolean conductor;
List<StatusMessage> queued = new ArrayList<>();

View file

@ -171,6 +171,8 @@ public class TrackGraphSyncPacket extends TrackGraphPacket {
@Override
protected void handle(GlobalRailwayManager manager, TrackGraph graph) {
manager.version++;
if (packetDeletesGraph) {
manager.removeGraph(graph);
return;

View file

@ -49,7 +49,7 @@ public class AssemblyScreen extends AbstractStationScreen {
iconTypes = TrainIconType.REGISTRY.keySet()
.stream()
.toList();
iconTypeScroll = new ScrollInput(x + 4, y + 17, 184, 14).titled(CreateLang.translateDirect("station.icon_type"));
iconTypeScroll = new ScrollInput(x + 4, y + 17, 162, 14).titled(CreateLang.translateDirect("station.icon_type"));
iconTypeScroll.withRange(0, iconTypes.size());
iconTypeScroll.withStepFunction(ctx -> -iconTypeScroll.standardStep()
.apply(ctx));
@ -164,7 +164,7 @@ public class AssemblyScreen extends AbstractStationScreen {
ResourceLocation iconId = iconTypes.get(iconTypeScroll.getState());
train.icon = TrainIconType.byId(iconId);
AllPackets.getChannel()
.sendToServer(new TrainEditPacket(train.id, "", iconId));
.sendToServer(new TrainEditPacket(train.id, "", iconId, train.mapColorIndex));
}
}

View file

@ -476,6 +476,18 @@ public class StationBlockEntity extends SmartBlockEntity implements ITransformab
itemEntity.setDeltaMovement(Vec3.ZERO);
getLevel().addFreshEntity(itemEntity);
}
public void updateMapColor(int color) {
GlobalStation station = getStation();
if (station == null)
return;
Train train = station.getPresentTrain();
if (train == null)
return;
train.mapColorIndex = color;
}
private boolean updateStationState(Consumer<GlobalStation> updateState) {
GlobalStation station = getStation();

View file

@ -10,6 +10,7 @@ import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllPackets;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.compat.Mods;
import com.simibubi.create.content.decoration.slidingDoor.DoorControl;
import com.simibubi.create.content.trains.entity.Carriage;
import com.simibubi.create.content.trains.entity.Train;
@ -23,6 +24,7 @@ import com.simibubi.create.foundation.utility.CreateLang;
import dev.engine_room.flywheel.lib.model.baked.PartialModel;
import net.createmod.catnip.gui.UIRenderHelper;
import net.createmod.catnip.utility.AnimationTickHolder;
import net.createmod.catnip.utility.Pair;
import net.createmod.catnip.utility.animation.LerpedFloat;
import net.createmod.catnip.utility.lang.Components;
@ -44,6 +46,9 @@ public class StationScreen extends AbstractStationScreen {
private int leavingAnimation;
private LerpedFloat trainPosition;
private DoorControl doorControl;
private ScrollInput colorTypeScroll;
private int messedWithColors;
private boolean switchingToAssemblyMode;
@ -99,6 +104,20 @@ public class StationScreen extends AbstractStationScreen {
dropScheduleButton.withCallback(() -> AllPackets.getChannel()
.sendToServer(StationEditPacket.dropSchedule(blockEntity.getBlockPos())));
addRenderableWidget(dropScheduleButton);
colorTypeScroll = new ScrollInput(x + 166, y + 17, 22, 14).titled(CreateLang.translateDirect("station.train_map_color"));
colorTypeScroll.withRange(0, 16);
colorTypeScroll.withStepFunction(ctx -> -colorTypeScroll.standardStep()
.apply(ctx));
colorTypeScroll.calling(s -> {
Train train = displayedTrain.get();
if (train != null) {
train.mapColorIndex = s;
messedWithColors = 10;
}
});
colorTypeScroll.active = colorTypeScroll.visible = false;
addRenderableWidget(colorTypeScroll);
onTextChanged = s -> trainNameBox.setX(nameBoxX(s, trainNameBox));
trainNameBox = new EditBox(font, x + 23, y + 47, background.getWidth() - 75, 10, Components.immutableEmpty());
@ -131,6 +150,12 @@ public class StationScreen extends AbstractStationScreen {
.length());
trainNameBox.setHighlightPos(trainNameBox.getCursorPosition());
}
if (messedWithColors > 0) {
messedWithColors--;
if (messedWithColors == 0)
syncTrainNameAndColor();
}
super.tick();
@ -151,6 +176,8 @@ public class StationScreen extends AbstractStationScreen {
leavingAnimation = 0;
newTrainButton.active = blockEntity.edgePoint.isOrthogonal();
newTrainButton.visible = true;
colorTypeScroll.visible = false;
colorTypeScroll.active = false;
Train imminentTrain = getImminent();
if (imminentTrain != null) {
@ -161,7 +188,9 @@ public class StationScreen extends AbstractStationScreen {
disassembleTrainButton.visible = true;
dropScheduleButton.active = blockEntity.trainHasSchedule;
dropScheduleButton.visible = true;
colorTypeScroll.setState(imminentTrain.mapColorIndex);
colorTypeScroll.visible = true;
colorTypeScroll.active = true;
trainNameBox.active = true;
trainNameBox.setValue(imminentTrain.name.getString());
trainNameBox.setX(nameBoxX(trainNameBox.getValue(), trainNameBox));
@ -185,6 +214,8 @@ public class StationScreen extends AbstractStationScreen {
targetPos -= trainIconWidth - 130;
if (leavingAnimation > 0) {
colorTypeScroll.visible = false;
colorTypeScroll.active = false;
disassembleTrainButton.active = false;
float f = 1 - (leavingAnimation / 80f);
trainPosition.setValue(targetPos + f * f * f * (background.getWidth() - targetPos + 5));
@ -301,6 +332,27 @@ public class StationScreen extends AbstractStationScreen {
if (font.width(text) > trainNameBox.getWidth())
graphics.drawString(font, "...", guiLeft + 26, guiTop + 47, 0xa6a6a6);
}
if (!Mods.FTBCHUNKS.isLoaded())
return;
AllGuiTextures sprite = AllGuiTextures.TRAINMAP_SPRITES;
sprite.bind();
int trainColorIndex = colorTypeScroll.getState();
int colorRow = trainColorIndex / 4;
int colorCol = trainColorIndex % 4;
int rotation = (AnimationTickHolder.getTicks() / 5) % 8;
for (int slice = 0; slice < 3; slice++) {
int row = slice == 0 ? 1 : slice == 2 ? 2 : 3;
int col = rotation;
int positionX = colorTypeScroll.getX() + 4;
int positionY = colorTypeScroll.getY() - 1;
int sheetX = col * 16 + colorCol * 128;
int sheetY = row * 16 + colorRow * 64;
graphics.blit(sprite.location, positionX, positionY, sheetX, sheetY, 16, 16, sprite.getWidth(), sprite.getHeight());
}
}
@Override
@ -335,19 +387,19 @@ public class StationScreen extends AbstractStationScreen {
if (hitEnter && trainNameBox.isFocused()) {
trainNameBox.setFocused(false);
syncTrainName();
syncTrainNameAndColor();
return true;
}
return super.keyPressed(pKeyCode, pScanCode, pModifiers);
}
private void syncTrainName() {
private void syncTrainNameAndColor() {
Train train = displayedTrain.get();
if (train != null && !trainNameBox.getValue()
.equals(train.name.getString()))
AllPackets.getChannel()
.sendToServer(new TrainEditPacket(train.id, trainNameBox.getValue(), train.icon.getId()));
.sendToServer(new TrainEditPacket(train.id, trainNameBox.getValue(), train.icon.getId(), train.mapColorIndex));
}
private void syncStationName() {
@ -371,7 +423,8 @@ public class StationScreen extends AbstractStationScreen {
return;
if (!switchingToAssemblyMode)
AllPackets.getChannel()
.sendToServer(new TrainEditPacket(train.id, trainNameBox.getValue(), train.icon.getId()));
.sendToServer(
new TrainEditPacket(train.id, trainNameBox.getValue(), train.icon.getId(), train.mapColorIndex));
else
blockEntity.imminentTrain = null;
}

View file

@ -21,17 +21,20 @@ public class TrainEditPacket extends SimplePacketBase {
private String name;
private UUID id;
private ResourceLocation iconType;
private int mapColor;
public TrainEditPacket(UUID id, String name, ResourceLocation iconType) {
public TrainEditPacket(UUID id, String name, ResourceLocation iconType, int mapColor) {
this.name = name;
this.id = id;
this.iconType = iconType;
this.mapColor = mapColor;
}
public TrainEditPacket(FriendlyByteBuf buffer) {
id = buffer.readUUID();
name = buffer.readUtf(256);
iconType = buffer.readResourceLocation();
mapColor = buffer.readVarInt();
}
@Override
@ -39,6 +42,7 @@ public class TrainEditPacket extends SimplePacketBase {
buffer.writeUUID(id);
buffer.writeUtf(name);
buffer.writeResourceLocation(iconType);
buffer.writeVarInt(mapColor);
}
@Override
@ -52,8 +56,9 @@ public class TrainEditPacket extends SimplePacketBase {
if (!name.isBlank())
train.name = Components.literal(name);
train.icon = TrainIconType.byId(iconType);
train.mapColorIndex = mapColor;
if (sender != null)
AllPackets.getChannel().send(PacketDistributor.ALL.noArg(), new TrainEditReturnPacket(id, name, iconType));
AllPackets.getChannel().send(PacketDistributor.ALL.noArg(), new TrainEditReturnPacket(id, name, iconType, mapColor));
});
return true;
}
@ -64,8 +69,8 @@ public class TrainEditPacket extends SimplePacketBase {
super(buffer);
}
public TrainEditReturnPacket(UUID id, String name, ResourceLocation iconType) {
super(id, name, iconType);
public TrainEditReturnPacket(UUID id, String name, ResourceLocation iconType, int mapColor) {
super(id, name, iconType, mapColor);
}
}

View file

@ -1,6 +1,8 @@
package com.simibubi.create.content.trains.track;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.PoseStack.Pose;
@ -10,6 +12,7 @@ import dev.engine_room.flywheel.lib.transform.TransformStack;
import net.createmod.catnip.utility.Couple;
import net.createmod.catnip.utility.Iterate;
import net.createmod.catnip.utility.NBTHelper;
import net.createmod.catnip.utility.Pair;
import net.createmod.catnip.utility.VecHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction.Axis;
@ -108,7 +111,8 @@ public class BezierConnection implements Iterable<BezierConnection.Segment> {
.map(v -> v.add(Vec3.atLowerCornerOf(localTo))),
Couple.deserializeEach(compound.getList("Axes", Tag.TAG_COMPOUND), VecHelper::readNBTCompound),
Couple.deserializeEach(compound.getList("Normals", Tag.TAG_COMPOUND), VecHelper::readNBTCompound),
compound.getBoolean("Primary"), compound.getBoolean("Girder"), TrackMaterial.deserialize(compound.getString("Material")));
compound.getBoolean("Primary"), compound.getBoolean("Girder"),
TrackMaterial.deserialize(compound.getString("Material")));
if (compound.contains("Smoothing"))
smoothing =
@ -398,7 +402,8 @@ public class BezierConnection implements Iterable<BezierConnection.Segment> {
}
public void spawnDestroyParticles(Level level) {
BlockParticleOption data = new BlockParticleOption(ParticleTypes.BLOCK, getMaterial().getBlock().defaultBlockState());
BlockParticleOption data = new BlockParticleOption(ParticleTypes.BLOCK, getMaterial().getBlock()
.defaultBlockState());
BlockParticleOption girderData =
new BlockParticleOption(ParticleTypes.BLOCK, AllBlocks.METAL_GIRDER.getDefaultState());
if (!(level instanceof ServerLevel slevel))
@ -673,4 +678,104 @@ public class BezierConnection implements Iterable<BezierConnection.Segment> {
return bakedGirders;
}
public Map<Pair<Integer, Integer>, Double> rasterise() {
Map<Pair<Integer, Integer>, Double> yLevels = new HashMap<>();
BlockPos tePosition = bePositions.getFirst();
Vec3 end1 = starts.getFirst()
.subtract(Vec3.atLowerCornerOf(tePosition))
.add(0, 3 / 16f, 0);
Vec3 end2 = starts.getSecond()
.subtract(Vec3.atLowerCornerOf(tePosition))
.add(0, 3 / 16f, 0);
Vec3 axis1 = axes.getFirst();
Vec3 axis2 = axes.getSecond();
double handleLength = getHandleLength();
Vec3 finish1 = axis1.scale(handleLength)
.add(end1);
Vec3 finish2 = axis2.scale(handleLength)
.add(end2);
Vec3 faceNormal1 = normals.getFirst();
Vec3 faceNormal2 = normals.getSecond();
int segCount = getSegmentCount();
float[] lut = getStepLUT();
Vec3[] samples = new Vec3[segCount];
for (int i = 0; i < segCount; i++) {
float t = Mth.clamp((i + 0.5f) * lut[i] / segCount, 0, 1);
Vec3 result = VecHelper.bezier(end1, end2, finish1, finish2, t);
Vec3 derivative = VecHelper.bezierDerivative(end1, end2, finish1, finish2, t)
.normalize();
Vec3 faceNormal =
faceNormal1.equals(faceNormal2) ? faceNormal1 : VecHelper.slerp(t, faceNormal1, faceNormal2);
Vec3 normal = faceNormal.cross(derivative)
.normalize();
Vec3 below = result.add(faceNormal.scale(-.25f));
Vec3 rail1 = below.add(normal.scale(.05f));
Vec3 rail2 = below.subtract(normal.scale(.05f));
Vec3 railMiddle = rail1.add(rail2)
.scale(.5);
samples[i] = railMiddle;
}
Vec3 center = end1.add(end2)
.scale(0.5);
Pair<Integer, Integer> prev = null;
Pair<Integer, Integer> prev2 = null;
Pair<Integer, Integer> prev3 = null;
for (int i = 0; i < segCount; i++) {
Vec3 railMiddle = samples[i];
BlockPos pos = BlockPos.containing(railMiddle);
Pair<Integer, Integer> key = Pair.of(pos.getX(), pos.getZ());
boolean alreadyPresent = yLevels.containsKey(key);
if (alreadyPresent && yLevels.get(key) <= railMiddle.y)
continue;
yLevels.put(key, railMiddle.y);
if (alreadyPresent)
continue;
if (prev3 != null) { // Remove obsolete pixels
boolean doubledViaPrev = isLineDoubled(prev2, prev, key);
boolean doubledViaPrev2 = isLineDoubled(prev3, prev2, prev);
boolean prevCloser = diff(prev, center) > diff(prev2, center);
if (doubledViaPrev2 && (!doubledViaPrev || !prevCloser)) {
yLevels.remove(prev2);
prev2 = prev;
prev = key;
continue;
} else if (doubledViaPrev && doubledViaPrev2 && prevCloser) {
yLevels.remove(prev);
prev = key;
continue;
}
}
prev3 = prev2;
prev2 = prev;
prev = key;
}
return yLevels;
}
private double diff(Pair<Integer, Integer> pFrom, Vec3 to) {
return to.distanceToSqr(pFrom.getFirst() + 0.5, to.y, pFrom.getSecond() + 0.5);
}
private boolean isLineDoubled(Pair<Integer, Integer> pFrom, Pair<Integer, Integer> pVia,
Pair<Integer, Integer> pTo) {
int diff1x = pVia.getFirst() - pFrom.getFirst();
int diff1z = pVia.getSecond() - pFrom.getSecond();
int diff2x = pTo.getFirst() - pVia.getFirst();
int diff2z = pTo.getSecond() - pVia.getSecond();
return Math.abs(diff1x) + Math.abs(diff1z) == 1 && Math.abs(diff2x) + Math.abs(diff2z) == 1 && diff1x != diff2x
&& diff1z != diff2z;
}
}

View file

@ -22,7 +22,6 @@ import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour
import dev.engine_room.flywheel.lib.visualization.VisualizationHelper;
import net.createmod.catnip.utility.Pair;
import net.createmod.catnip.utility.VecHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction.Axis;
import net.minecraft.core.registries.Registries;
@ -363,54 +362,7 @@ public class TrackBlockEntity extends SmartBlockEntity implements ITransformable
}
public void manageFakeTracksAlong(BezierConnection bc, boolean remove) {
Map<Pair<Integer, Integer>, Double> yLevels = new HashMap<>();
BlockPos tePosition = bc.bePositions.getFirst();
Vec3 end1 = bc.starts.getFirst()
.subtract(Vec3.atLowerCornerOf(tePosition))
.add(0, 3 / 16f, 0);
Vec3 end2 = bc.starts.getSecond()
.subtract(Vec3.atLowerCornerOf(tePosition))
.add(0, 3 / 16f, 0);
Vec3 axis1 = bc.axes.getFirst();
Vec3 axis2 = bc.axes.getSecond();
double handleLength = bc.getHandleLength();
Vec3 finish1 = axis1.scale(handleLength)
.add(end1);
Vec3 finish2 = axis2.scale(handleLength)
.add(end2);
Vec3 faceNormal1 = bc.normals.getFirst();
Vec3 faceNormal2 = bc.normals.getSecond();
int segCount = bc.getSegmentCount();
float[] lut = bc.getStepLUT();
for (int i = 0; i < segCount; i++) {
float t = i == segCount ? 1 : i * lut[i] / segCount;
t += 0.5f / segCount;
Vec3 result = VecHelper.bezier(end1, end2, finish1, finish2, t);
Vec3 derivative = VecHelper.bezierDerivative(end1, end2, finish1, finish2, t)
.normalize();
Vec3 faceNormal =
faceNormal1.equals(faceNormal2) ? faceNormal1 : VecHelper.slerp(t, faceNormal1, faceNormal2);
Vec3 normal = faceNormal.cross(derivative)
.normalize();
Vec3 below = result.add(faceNormal.scale(-.25f));
Vec3 rail1 = below.add(normal.scale(.05f));
Vec3 rail2 = below.subtract(normal.scale(.05f));
Vec3 railMiddle = rail1.add(rail2)
.scale(.5);
for (Vec3 vec : new Vec3[] { railMiddle }) {
BlockPos pos = BlockPos.containing(vec);
Pair<Integer, Integer> key = Pair.of(pos.getX(), pos.getZ());
if (!yLevels.containsKey(key) || yLevels.get(key) > vec.y)
yLevels.put(key, vec.y);
}
}
Map<Pair<Integer, Integer>, Double> yLevels = bc.rasterise();
for (Entry<Pair<Integer, Integer>, Double> entry : yLevels.entrySet()) {
double yValue = entry.getValue();
@ -419,7 +371,7 @@ public class TrackBlockEntity extends SmartBlockEntity implements ITransformable
.getFirst(), floor,
entry.getKey()
.getSecond());
targetPos = targetPos.offset(tePosition)
targetPos = targetPos.offset(bc.bePositions.getFirst())
.above(1);
BlockState stateAtPos = level.getBlockState(targetPos);

View file

@ -80,6 +80,10 @@ public abstract class CapManipulationBehaviourBase<T, S extends CapManipulationB
targetCapability = LazyOptional.empty();
}
public void removeListener() {
targetCapability.removeListener(new HashableNonNullConsumer<>(this::onHandlerInvalidated, this));
}
@Override
public void lazyTick() {
super.lazyTick();

View file

@ -2,10 +2,12 @@ package com.simibubi.create.foundation.blockEntity.renderer;
import com.mojang.blaze3d.vertex.PoseStack;
import net.createmod.ponder.api.level.PonderLevel;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.client.renderer.culling.Frustum;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.phys.AABB;
@ -28,7 +30,10 @@ public abstract class SafeBlockEntityRenderer<T extends BlockEntity> implements
.getBlock() == Blocks.AIR;
}
public boolean shouldCullItem(Vec3 itemPos) {
public boolean shouldCullItem(Vec3 itemPos, Level level) {
if (level instanceof PonderLevel)
return false;
Frustum frustum = Minecraft.getInstance().levelRenderer.capturedFrustum != null ?
Minecraft.getInstance().levelRenderer.capturedFrustum :
Minecraft.getInstance().levelRenderer.cullingFrustum;

View file

@ -32,6 +32,12 @@ public enum CompatMetals {
public String getName() {
return name;
}
public String getName(Mods mod) {
if (this == ALUMINUM && mod == IC2) // include in mods.builder if this happens again
return "aluminium";
return name;
}
/**
* These mods must provide an ingot and nugget variant of the corresponding metal.

View file

@ -817,7 +817,8 @@ public class MillingRecipeGen extends ProcessingRecipeGen {
create(Mods.BTN.recipeId(color + "_petal"), b -> b.duration(50)
.require(AllTags.optionalTag(ForgeRegistries.ITEMS,
new ResourceLocation(Mods.BTN.getId(), "petals/" + color)))
.output(Mods.MC, color + "_dye"));
.output(Mods.MC, color + "_dye")
.whenModLoaded(Mods.BTN.getId()));
}
return null;
}
@ -850,7 +851,7 @@ public class MillingRecipeGen extends ProcessingRecipeGen {
public MillingRecipeGen(PackOutput output) {
super(output);
}
@Override
protected AllRecipeTypes getRecipeType() {
return AllRecipeTypes.MILLING;

View file

@ -59,6 +59,8 @@ import net.minecraftforge.common.crafting.conditions.ICondition;
import net.minecraftforge.common.crafting.conditions.ModLoadedCondition;
import net.minecraftforge.common.crafting.conditions.NotCondition;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings("unused")
public class StandardRecipeGen extends CreateRecipeProvider {
@ -1183,7 +1185,8 @@ public class StandardRecipeGen extends CreateRecipeProvider {
.inBlastFurnace(),
UA_TREE_FERTILIZER = create(AllItems.TREE_FERTILIZER::get).returns(2)
.whenModLoaded(Mods.UA.getId()).unlockedBy(() -> Items.BONE_MEAL)
.unlockedBy(() -> Items.BONE_MEAL)
.whenModLoaded(Mods.UA.getId())
.viaShapeless(b -> b.requires(Ingredient.of(ItemTags.SMALL_FLOWERS), 2)
.requires(AllItemTags.UA_CORAL.tag).requires(Items.BONE_MEAL))
@ -1229,8 +1232,8 @@ public class StandardRecipeGen extends CreateRecipeProvider {
}
GeneratedRecipe blastModdedCrushedMetal(ItemEntry<? extends Item> ingredient, CompatMetals metal) {
String metalName = metal.getName();
for (Mods mod : metal.getMods()) {
String metalName = metal.getName(mod);
ResourceLocation ingot = mod.ingotOf(metalName);
String modId = mod.getId();
create(ingot).withSuffix("_compat_" + modId)
@ -1380,7 +1383,12 @@ public class StandardRecipeGen extends CreateRecipeProvider {
ShapelessRecipeBuilder b = builder.apply(ShapelessRecipeBuilder.shapeless(RecipeCategory.MISC, result.get(), amount));
if (unlockedBy != null)
b.unlockedBy("has_item", inventoryTrigger(unlockedBy.get()));
b.save(consumer, createLocation("crafting"));
b.save(result -> {
consumer.accept(
!recipeConditions.isEmpty() ? new ConditionSupportingShapelessRecipeResult(result, recipeConditions)
: result);
}, createLocation("crafting"));
});
}
@ -1483,10 +1491,10 @@ public class StandardRecipeGen extends CreateRecipeProvider {
SimpleCookingRecipeBuilder b = builder.apply(SimpleCookingRecipeBuilder.generic(ingredient.get(),
RecipeCategory.MISC, isOtherMod ? Items.DIRT : result.get(), exp,
(int) (cookingTime * cookingTimeModifier), serializer));
if (unlockedBy != null)
b.unlockedBy("has_item", inventoryTrigger(unlockedBy.get()));
b.save(result -> {
consumer.accept(
isOtherMod ? new ModdedCookingRecipeResult(result, compatDatagenOutput, recipeConditions)
@ -1507,19 +1515,39 @@ public class StandardRecipeGen extends CreateRecipeProvider {
super(p_i48262_1_);
}
private static class ModdedCookingRecipeResult implements FinishedRecipe {
private record ModdedCookingRecipeResult(FinishedRecipe wrapped, ResourceLocation outputOverride, List<ICondition> conditions) implements FinishedRecipe {
@Override
public ResourceLocation getId() {
return wrapped.getId();
}
private FinishedRecipe wrapped;
private ResourceLocation outputOverride;
private List<ICondition> conditions;
@Override
public RecipeSerializer<?> getType() {
return wrapped.getType();
}
public ModdedCookingRecipeResult(FinishedRecipe wrapped, ResourceLocation outputOverride,
List<ICondition> conditions) {
this.wrapped = wrapped;
this.outputOverride = outputOverride;
this.conditions = conditions;
@Override
public JsonObject serializeAdvancement() {
return wrapped.serializeAdvancement();
}
@Override
public ResourceLocation getAdvancementId() {
return wrapped.getAdvancementId();
}
@Override
public void serializeRecipeData(JsonObject object) {
wrapped.serializeRecipeData(object);
object.addProperty("result", outputOverride.toString());
JsonArray conds = new JsonArray();
conditions.forEach(c -> conds.add(CraftingHelper.serialize(c)));
object.add("conditions", conds);
}
}
private record ConditionSupportingShapelessRecipeResult(FinishedRecipe wrapped, List<ICondition> conditions) implements FinishedRecipe {
@Override
public ResourceLocation getId() {
return wrapped.getId();
@ -1541,15 +1569,12 @@ public class StandardRecipeGen extends CreateRecipeProvider {
}
@Override
public void serializeRecipeData(JsonObject object) {
wrapped.serializeRecipeData(object);
object.addProperty("result", outputOverride.toString());
public void serializeRecipeData(@NotNull JsonObject pJson) {
wrapped.serializeRecipeData(pJson);
JsonArray conds = new JsonArray();
conditions.forEach(c -> conds.add(CraftingHelper.serialize(c)));
object.add("conditions", conds);
pJson.add("conditions", conds);
}
}
}

View file

@ -133,8 +133,8 @@ public class WashingRecipeGen extends ProcessingRecipeGen {
}
public GeneratedRecipe moddedCrushedOre(ItemEntry<? extends Item> crushed, CompatMetals metal) {
String metalName = metal.getName();
for (Mods mod : metal.getMods()) {
String metalName = metal.getName(mod);
ResourceLocation nugget = mod.nuggetOf(metalName);
create(mod.getId() + "/" + crushed.getId()
.getPath(),

View file

@ -1,6 +1,7 @@
package com.simibubi.create.foundation.events;
import com.simibubi.create.Create;
import com.simibubi.create.compat.trainmap.TrainMapSync;
import com.simibubi.create.content.contraptions.ContraptionHandler;
import com.simibubi.create.content.contraptions.actors.trainControls.ControlsServerHandler;
import com.simibubi.create.content.contraptions.minecart.CouplingPhysics;
@ -67,6 +68,7 @@ public class CommonEvents {
Create.LAGGER.tick();
ServerSpeedProvider.serverTick();
Create.RAILWAYS.sync.serverTick();
TrainMapSync.serverTick(event);
}
@SubscribeEvent

View file

@ -195,6 +195,21 @@ public enum AllGuiTextures implements ScreenElement, TextureSheetSegment {
TRADE_OVERLAY("widgets", 136, 97, 98, 48),
// PlacementIndicator
PLACEMENT_INDICATOR_SHEET("placement_indicator", 0, 0, 16, 256),
// Train Map
TRAINMAP_SPRITES("trainmap_sprite_sheet", 0, 0, 512, 256),
TRAINMAP_SIGNAL("widgets", 81, 156, 5, 10),
TRAINMAP_STATION_ORTHO("widgets", 49, 156, 5, 5),
TRAINMAP_STATION_DIAGO("widgets", 56, 156, 5, 5),
TRAINMAP_STATION_ORTHO_HIGHLIGHT("widgets", 63, 156, 7, 7),
TRAINMAP_STATION_DIAGO_HIGHLIGHT("widgets", 72, 156, 7, 7),
TRAINMAP_TOGGLE_PANEL("widgets", 166, 74, 33, 14),
TRAINMAP_TOGGLE_ON("widgets", 166, 89, 12, 7),
TRAINMAP_TOGGLE_OFF("widgets", 166, 97, 12, 7),
// ComputerCraft
COMPUTER("computer", 200, 102);

View file

@ -297,5 +297,16 @@ public class ItemHelper {
}
return entityIn instanceof ItemEntity ? ((ItemEntity) entityIn).getItem() : ItemStack.EMPTY;
}
public static ItemStack limitCountToMaxStackSize(ItemStack stack, boolean simulate) {
int count = stack.getCount();
int max = stack.getMaxStackSize();
if (count <= max)
return ItemStack.EMPTY;
ItemStack remainder = ItemHandlerHelper.copyStackWithSize(stack, count - max);
if (!simulate)
stack.setCount(max);
return remainder;
}
}

View file

@ -11,7 +11,6 @@ import com.simibubi.create.foundation.mixin.accessor.UseOnContextAccessor;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
@Mixin(BlockItem.class)
@ -19,7 +18,7 @@ public class BlockItemMixin {
@Inject(method = "place", at = @At("HEAD"), cancellable = true)
private void create$fixDeployerPlacement(BlockPlaceContext pContext, CallbackInfoReturnable<InteractionResult> cir) {
BlockState state = pContext.getLevel().getBlockState(((UseOnContextAccessor) pContext).create$getHitResult().getBlockPos());
if (state != Blocks.AIR.defaultBlockState() && pContext.getPlayer() instanceof DeployerFakePlayer) {
if (!state.canBeReplaced() && pContext.getPlayer() instanceof DeployerFakePlayer) {
cir.setReturnValue(InteractionResult.PASS);
}
}

View file

@ -0,0 +1,43 @@
package com.simibubi.create.foundation.mixin;
import java.util.List;
import java.util.Set;
import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
import com.simibubi.create.compat.Mods;
public class CreateMixinPlugin implements IMixinConfigPlugin {
@Override
public void onLoad(String mixinPackage) {}
@Override
public String getRefMapperConfig() {
return null;
}
@Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
if (targetClassName.equals("journeymap/client/ui/fullscreen/Fullscreen") && !Mods.JOURNEYMAP.isLoaded())
return false;
return true;
}
@Override
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {}
@Override
public List<String> getMixins() {
return null;
}
@Override
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {}
@Override
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {}
}

View file

@ -0,0 +1,40 @@
package com.simibubi.create.foundation.mixin.compat;
import java.awt.geom.Point2D;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.At.Shift;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.simibubi.create.compat.trainmap.JourneyTrainMap;
import journeymap.client.render.map.GridRenderer;
import journeymap.client.ui.fullscreen.Fullscreen;
import net.minecraft.client.gui.GuiGraphics;
@Mixin(Fullscreen.class)
public abstract class JourneyFullscreenMapMixin {
@Shadow
private static GridRenderer gridRenderer;
@Shadow
private Boolean isScrolling;
@Shadow
public abstract Point2D.Double getMouseDrag();
@Inject(method = "Ljourneymap/client/ui/fullscreen/Fullscreen;render(Lnet/minecraft/client/gui/GuiGraphics;IIF)V", at = @At(target = "Ljourneymap/client/ui/fullscreen/Fullscreen;drawMap(Lnet/minecraft/client/gui/GuiGraphics;II)V", value = "INVOKE", shift = Shift.AFTER))
public void create$journeyMapFullscreenRender(GuiGraphics graphics, int mouseX, int mouseY, float pt,
CallbackInfo ci) {
boolean dragging = isScrolling;
Point2D.Double mouseDrag = getMouseDrag();
double x = gridRenderer.getCenterBlockX() - (dragging ? mouseDrag.x : 0);
double z = gridRenderer.getCenterBlockZ() - (dragging ? mouseDrag.y : 0);
JourneyTrainMap.onRender(graphics, (Fullscreen) (Object) this, x, z, mouseX, mouseY, pt);
}
}

View file

@ -1,6 +1,7 @@
package com.simibubi.create.foundation.render;
import java.io.IOException;
import java.util.function.BiFunction;
import java.util.function.Function;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
@ -116,6 +117,19 @@ public class RenderTypes extends RenderStateShard {
return ADDITIVE;
}
public static BiFunction<ResourceLocation, Boolean, RenderType> TRAIN_MAP = Util.memoize(RenderTypes::getTrainMap);
private static RenderType getTrainMap(ResourceLocation locationIn, boolean linearFiltering) {
RenderType.CompositeState rendertype$state = RenderType.CompositeState.builder()
.setShaderState(RENDERTYPE_TEXT_SHADER)
.setTextureState(new RenderStateShard.TextureStateShard(locationIn, linearFiltering, false))
.setTransparencyState(NO_TRANSPARENCY)
.setLightmapState(LIGHTMAP)
.createCompositeState(false);
return RenderType.create("create_train_map", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP,
VertexFormat.Mode.QUADS, 256, false, true, rendertype$state);
}
public static RenderType fluid() {
return FLUID;
}

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