diff --git a/build.gradle b/build.gradle index 2375c3e69..546f88567 100644 --- a/build.gradle +++ b/build.gradle @@ -119,6 +119,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' @@ -155,6 +171,11 @@ dependencies { jarJar.ranged(it, '[1.0,2.0)') } + compileOnly(annotationProcessor("io.github.llamalad7:mixinextras-common:0.4.1")) + implementation(jarJar("io.github.llamalad7:mixinextras-forge:0.4.1")) { + jarJar.ranged(it, "[0.4.1,)") + } + implementation fg.deobf("com.tterrag.registrate:Registrate:${registrate_version}") compileOnly fg.deobf("dev.engine_room.flywheel:flywheel-forge-api-${flywheel_minecraft_version}:${flywheel_version}") @@ -179,12 +200,20 @@ dependencies { // implementation fg.deobf("curse.maven:ic2-classic-242942:5555152") not updated to 1.20 // implementation fg.deobf("curse.maven:druidcraft-340991:3101903") not updated to 1.20 - // implementation fg.deobf("com.railwayteam.railways:Steam_Rails-forge-1.20.1:1.6.4+forge-mc1.20.1") { transitive = false } - // + // 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:5629578") // runtimeOnly fg.deobf("curse.maven:galosphere-631098:4983871") - runtimeOnly fg.deobf("curse.maven:elementary-ores-332609:4622524") - runtimeOnly fg.deobf("curse.maven:flib-661261:5495793") + // runtimeOnly fg.deobf("curse.maven:elementary-ores-332609:4622524") + // runtimeOnly fg.deobf("curse.maven:flib-661261:5495793") // runtimeOnly fg.deobf("curse.maven:infernal-expansion-395078:4002091") not updated to 1.20 // runtimeOnly fg.deobf("org.violetmoon.zeta:Zeta:1.0-9.44") // runtimeOnly fg.deobf("org.violetmoon.quark:Quark:4.0-461.3475") @@ -214,14 +243,13 @@ dependencies { // runtimeOnly fg.deobf("curse.maven:blueprint-382216:5292242") // runtimeOnly fg.deobf("curse.maven:windsweptmod-636321:4817132") not updated to 1.20 // runtimeOnly fg.deobf("curse.maven:good-ending-690161:5024405") - runtimeOnly fg.deobf("curse.maven:terrablender-563928:5378180") - runtimeOnly fg.deobf("curse.maven:regions-unexplored-659110:5558225") - runtimeOnly fg.deobf("curse.maven:vampirism-become-a-vampire-233029:5526512") - runtimeOnly fg.deobf("curse.maven:applied-energistics-2-223794:5641282") - runtimeOnly fg.deobf("curse.maven:silent-lib-242998:4585754") - runtimeOnly fg.deobf("curse.maven:silents-gems-220311:5193708") - runtimeOnly fg.deobf("curse.maven:project-vibrant-journeys-300297:5676296") - + // runtimeOnly fg.deobf("curse.maven:terrablender-563928:5378180") + // runtimeOnly fg.deobf("curse.maven:regions-unexplored-659110:5558225") + // runtimeOnly fg.deobf("curse.maven:vampirism-become-a-vampire-233029:5526512") + // runtimeOnly fg.deobf("curse.maven:applied-energistics-2-223794:5641282") + // runtimeOnly fg.deobf("curse.maven:silent-lib-242998:4585754") + // runtimeOnly fg.deobf("curse.maven:silents-gems-220311:5193708") + // runtimeOnly fg.deobf("curse.maven:project-vibrant-journeys-300297:5676296") // https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497 // Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings diff --git a/gradle.properties b/gradle.properties index a326ebea1..923699fb4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -23,7 +23,7 @@ use_parchment = true # dependency versions registrate_version = MC1.20-1.3.3 flywheel_minecraft_version = 1.20.1 -flywheel_version = 1.0.0-beta-113 +flywheel_version = 1.0.0-beta-145 jei_minecraft_version = 1.20.1 jei_version = 15.10.0.39 curios_minecraft_version = 1.20.1 diff --git a/src/generated/resources/.cache/12afe0d97856fb2040b8407470e6d13529994eaa b/src/generated/resources/.cache/12afe0d97856fb2040b8407470e6d13529994eaa index 569ceeaba..8aded56d1 100644 --- a/src/generated/resources/.cache/12afe0d97856fb2040b8407470e6d13529994eaa +++ b/src/generated/resources/.cache/12afe0d97856fb2040b8407470e6d13529994eaa @@ -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 diff --git a/src/generated/resources/.cache/2d64935085b86659cb7857bad9701dbf9bab6e4c b/src/generated/resources/.cache/2d64935085b86659cb7857bad9701dbf9bab6e4c index cbba15d14..5777ab3d8 100644 --- a/src/generated/resources/.cache/2d64935085b86659cb7857bad9701dbf9bab6e4c +++ b/src/generated/resources/.cache/2d64935085b86659cb7857bad9701dbf9bab6e4c @@ -1,4 +1,4 @@ -// 1.20.1 2024-09-02T22:36:27.3056283 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-10-11T10:29:49.10689745 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 @@ -68,12 +68,12 @@ b5170d754ce5f07ea2b4646eb07c099c50bae249 assets/create/blockstates/clipboard.jso f7254f20f91e2f1295e36d2e70390d43f3952d07 assets/create/blockstates/copper_door.json 736777de0eb038ff1ef9e8fe9d04c23d80239eda assets/create/blockstates/copper_ladder.json df3103dfc1c3ba7a9573229d009cb0de4925df16 assets/create/blockstates/copper_scaffolding.json -4d3d29e8a74bf103da39e76a1466b03eb5dcf916 assets/create/blockstates/copper_shingles.json 1ea8fdb990f8cda1762ab69ac38ea3161a835227 assets/create/blockstates/copper_shingle_slab.json 7c35bb802099d6bb5d92eafd8cbb7ea146979a2e assets/create/blockstates/copper_shingle_stairs.json -9a9f03140a57a7a8903d3e1b159bdc052566a6ec assets/create/blockstates/copper_tiles.json +4d3d29e8a74bf103da39e76a1466b03eb5dcf916 assets/create/blockstates/copper_shingles.json 7db7a0d81887091ca889f40bb8a508d3098c5164 assets/create/blockstates/copper_tile_slab.json c0b7eca017242913d156e4623147add0d03574f6 assets/create/blockstates/copper_tile_stairs.json +9a9f03140a57a7a8903d3e1b159bdc052566a6ec assets/create/blockstates/copper_tiles.json ef3ccb2d8b03f5a972b053a15bb037f8db6af17c assets/create/blockstates/copper_valve_handle.json 4758bed22fb6fe18213f463bc055775c1909e858 assets/create/blockstates/copycat_bars.json 4789c857508452aede1cb7389187b99ce2d7bf62 assets/create/blockstates/copycat_base.json @@ -90,114 +90,114 @@ c9a2c3a7971c46957d0f07c6d94d76f59da54a0b assets/create/blockstates/crushing_whee 4b0e51a1c10685f7d432467339afc9c2e24793b0 assets/create/blockstates/crushing_wheel_controller.json ba9c3ecfacbd398048440d247decffeaefc714b5 assets/create/blockstates/cuckoo_clock.json 1f6d84cba69062a1989d671c9c97317e2c2455b6 assets/create/blockstates/cut_andesite.json -cc62a6499ce8dcfc5e8695f0e8bb3c3d67f41efc assets/create/blockstates/cut_andesite_bricks.json 50d88f806122818af2ffecbd514d13ebbd21e4c9 assets/create/blockstates/cut_andesite_brick_slab.json 32d801225ea18209792921fa91618ed41794dbd0 assets/create/blockstates/cut_andesite_brick_stairs.json 3bf8204bf8c7c5b7b3c388fbc3478bb2d7c47129 assets/create/blockstates/cut_andesite_brick_wall.json +cc62a6499ce8dcfc5e8695f0e8bb3c3d67f41efc assets/create/blockstates/cut_andesite_bricks.json 34e89a828f14383c6115954a235b19851b74f277 assets/create/blockstates/cut_andesite_slab.json 49d58ae14544d89305ddc707cf7f6a81998200fa assets/create/blockstates/cut_andesite_stairs.json 1cc235cb6c388324793ac40f7bf89df8b048faac assets/create/blockstates/cut_andesite_wall.json 13ea54a4b9b89e576879a6e23a029c6341b7c098 assets/create/blockstates/cut_asurine.json -51c22c0547ab8ed2564890afb8733bbe356899f5 assets/create/blockstates/cut_asurine_bricks.json cf09de38f826fe000c5efe5afe56cf746125691d assets/create/blockstates/cut_asurine_brick_slab.json 1835482d5e9a59f2214336a63b12c7132ad815b4 assets/create/blockstates/cut_asurine_brick_stairs.json c48ab37bf7a2aba676af281d29cb6a2103c72fba assets/create/blockstates/cut_asurine_brick_wall.json +51c22c0547ab8ed2564890afb8733bbe356899f5 assets/create/blockstates/cut_asurine_bricks.json 1523a57124239a99da0b12a6b435c09d3d4276a5 assets/create/blockstates/cut_asurine_slab.json cc1acf5e118f1b1e78c5bb291176008960794d59 assets/create/blockstates/cut_asurine_stairs.json 139640bf41070e8eeb48647319eee54bb6804692 assets/create/blockstates/cut_asurine_wall.json 06b8c5cf98366608c480a37e6944d0d668bc8983 assets/create/blockstates/cut_calcite.json -979c70e35d806f1f63fe3381f27d881a17f9f6be assets/create/blockstates/cut_calcite_bricks.json a8f83cb8e1eae587f4e11e37c4cd3d0a1bbef377 assets/create/blockstates/cut_calcite_brick_slab.json 1eabb2e485aa323d317fa9648be02c12556593b7 assets/create/blockstates/cut_calcite_brick_stairs.json a0a33df71c5d26344a7bb0dd7a4622c30cc7825f assets/create/blockstates/cut_calcite_brick_wall.json +979c70e35d806f1f63fe3381f27d881a17f9f6be assets/create/blockstates/cut_calcite_bricks.json e3ddaae92b52cc3ea230088ff23260b5c5c93017 assets/create/blockstates/cut_calcite_slab.json 80c5249eaf9504c743c427fdd1a2c7bfa0f3d48f assets/create/blockstates/cut_calcite_stairs.json b4bbdb08d8114b6741546a0418cb54d645481c02 assets/create/blockstates/cut_calcite_wall.json 449f5180c72a028393afdac55a34e59862728224 assets/create/blockstates/cut_crimsite.json -25d731077a131d03347296c38c76b547194a6320 assets/create/blockstates/cut_crimsite_bricks.json d2c8a3580d3578c8afe44b94d4448be3680dbdeb assets/create/blockstates/cut_crimsite_brick_slab.json a3d9d2190a23b881dd3a7538ab248e0b0a3efa8e assets/create/blockstates/cut_crimsite_brick_stairs.json 3791c00ed477c0aaf7c5a20803a89dfc0e20f013 assets/create/blockstates/cut_crimsite_brick_wall.json +25d731077a131d03347296c38c76b547194a6320 assets/create/blockstates/cut_crimsite_bricks.json c9f19e7a976a7428b3dd58f45d734700ca1a18cd assets/create/blockstates/cut_crimsite_slab.json 1b8d4ac53dc5823083c2af605165a05b73c9ff79 assets/create/blockstates/cut_crimsite_stairs.json 484f9253ed92e963f398973a99fbeacb67ba1188 assets/create/blockstates/cut_crimsite_wall.json c4e95ceb7914da09ebe42d539bf5d976a3d70972 assets/create/blockstates/cut_deepslate.json -75d4ef863cd85d8f3df78226177966954e02ee2b assets/create/blockstates/cut_deepslate_bricks.json e1dc99a48b9066732fc5c62071c5ead16f34f438 assets/create/blockstates/cut_deepslate_brick_slab.json dbb2eddaf1d4ae3e687beb611552ea4283a1e7d8 assets/create/blockstates/cut_deepslate_brick_stairs.json 91c1f3da848503067c64b966ddda22ab91ff8fd5 assets/create/blockstates/cut_deepslate_brick_wall.json +75d4ef863cd85d8f3df78226177966954e02ee2b assets/create/blockstates/cut_deepslate_bricks.json 593198ffd37eae124a8366ae1d4a40b682788f92 assets/create/blockstates/cut_deepslate_slab.json f8cd1f9002ed8593ab71af9cfb7f962625994108 assets/create/blockstates/cut_deepslate_stairs.json c2d8060a0c830e5b8bbb084457083324b5b6f4c9 assets/create/blockstates/cut_deepslate_wall.json aaa6ac5f4fc399c4b03a7f8de856fa7aae97e049 assets/create/blockstates/cut_diorite.json -08b6289ca8b4193c87324ca23ca081e8773fb223 assets/create/blockstates/cut_diorite_bricks.json 423f809f06fa3fd96643f068ba0d3520269b3844 assets/create/blockstates/cut_diorite_brick_slab.json 9011fb92f57e7695c4484c923dd40ecd749ff307 assets/create/blockstates/cut_diorite_brick_stairs.json 41bad89777a33737bc0365ce2c7ffc20720f9620 assets/create/blockstates/cut_diorite_brick_wall.json +08b6289ca8b4193c87324ca23ca081e8773fb223 assets/create/blockstates/cut_diorite_bricks.json b03e7cf494c53c6f24ba93d0ef531e839026932b assets/create/blockstates/cut_diorite_slab.json 95c8094204979acfb0e59c2826003e0274a02fe5 assets/create/blockstates/cut_diorite_stairs.json e2f163d36dd5d03c0741dd2e87d8f77a0c86ae00 assets/create/blockstates/cut_diorite_wall.json f42ca2ce8e8f657c64376759413ec611f8045531 assets/create/blockstates/cut_dripstone.json -2d696162b2085c3d5723308a8d1ccafb29660f01 assets/create/blockstates/cut_dripstone_bricks.json 9310a800fb091014e7c0a220f5f2511c1de379ad assets/create/blockstates/cut_dripstone_brick_slab.json 3ff2f65dafcb4654b99e0d65b7e851760f9a4075 assets/create/blockstates/cut_dripstone_brick_stairs.json cafc956d8dc2053e5a0e8437c4ccde7fa24fc17e assets/create/blockstates/cut_dripstone_brick_wall.json +2d696162b2085c3d5723308a8d1ccafb29660f01 assets/create/blockstates/cut_dripstone_bricks.json 9cb32af3b952b841e9da94789da17cd274c3cfb9 assets/create/blockstates/cut_dripstone_slab.json da0300f54bdfcc705beb8d84f26406be660de5de assets/create/blockstates/cut_dripstone_stairs.json 83ff3eaeb481202c77e6dbdc442b4dd195ca568c assets/create/blockstates/cut_dripstone_wall.json bf501250fd2226838afe0baf68db08cd832e3c4f assets/create/blockstates/cut_granite.json -5c029d7ec837b3239d17ab91a70f025df1bfb124 assets/create/blockstates/cut_granite_bricks.json 773717bd5c140cf025f463c99c67efb9d27bd696 assets/create/blockstates/cut_granite_brick_slab.json 97d20b21e5b7f329c1b21b436fd0bdcaa8d173d0 assets/create/blockstates/cut_granite_brick_stairs.json 5e4175b6c89039ded48937ad1cd13d3bb2d2992a assets/create/blockstates/cut_granite_brick_wall.json +5c029d7ec837b3239d17ab91a70f025df1bfb124 assets/create/blockstates/cut_granite_bricks.json 42549436ce26ad7b44f2e1cba54357b3f25bcb18 assets/create/blockstates/cut_granite_slab.json e9d8fd028d8092e5fa0fd13cd638516f57a22d53 assets/create/blockstates/cut_granite_stairs.json 2daab523202dd2e31daeaf3b9a04cde2a7da4ca5 assets/create/blockstates/cut_granite_wall.json 0652c8b9c41acc1a8da901bd7b8b6018b3581d5b assets/create/blockstates/cut_limestone.json -508ee569f313b7e804f6268ca86f5a61851563ec assets/create/blockstates/cut_limestone_bricks.json 4efbeb34c96918e9b48dc484a82b1ef4811ed39d assets/create/blockstates/cut_limestone_brick_slab.json 11b99cf9b33d7f8de9d11cc1e405e2681682ba32 assets/create/blockstates/cut_limestone_brick_stairs.json b6c02a9e9e47a8e521a54ef9488259267068f032 assets/create/blockstates/cut_limestone_brick_wall.json +508ee569f313b7e804f6268ca86f5a61851563ec assets/create/blockstates/cut_limestone_bricks.json fb63a2581211fe62344985a06feec9dcec4b1888 assets/create/blockstates/cut_limestone_slab.json ffcca1e66718f3e78e544b5fa9954a852c095e91 assets/create/blockstates/cut_limestone_stairs.json a1a90f84b47f96b4384fc2d60bfc48ddbb5ed179 assets/create/blockstates/cut_limestone_wall.json 1b7a133518780d4f49474a70e7f6263d6e88ff51 assets/create/blockstates/cut_ochrum.json -6f37e5e2dca3b443951131cb82c15a981a4e2005 assets/create/blockstates/cut_ochrum_bricks.json f1e9d54a6f9f41b968f117a7be711011effa71a5 assets/create/blockstates/cut_ochrum_brick_slab.json 8d334e026e94b304a1ff1ee96097f434b50175f2 assets/create/blockstates/cut_ochrum_brick_stairs.json e92c026ee7ab2aa35003ad475bef3d6c0e29818c assets/create/blockstates/cut_ochrum_brick_wall.json +6f37e5e2dca3b443951131cb82c15a981a4e2005 assets/create/blockstates/cut_ochrum_bricks.json 5a61edb7d146e83d951795fae33dc306e71b2cb6 assets/create/blockstates/cut_ochrum_slab.json b31944bf6297685acd37631083dde0889c08ede7 assets/create/blockstates/cut_ochrum_stairs.json df33a8af1dc8cb08ddcfd22a50a305499479a4dd assets/create/blockstates/cut_ochrum_wall.json 1606d7481e56755f07e9331cf85a8d7cc9aace9a assets/create/blockstates/cut_scorchia.json -bc2a0e7f11400b8c2a03071be87dadb5edc097de assets/create/blockstates/cut_scorchia_bricks.json 43db25ebac2f5bcaa7ca9cfb6da8fcb20fad8269 assets/create/blockstates/cut_scorchia_brick_slab.json 7a80620590ba5e61967c5168f5c67ecabf09dc00 assets/create/blockstates/cut_scorchia_brick_stairs.json e4eb79360a41bb1a7ca835d61446ea5166e4cda8 assets/create/blockstates/cut_scorchia_brick_wall.json +bc2a0e7f11400b8c2a03071be87dadb5edc097de assets/create/blockstates/cut_scorchia_bricks.json c0d262f54e3b2fce8bc941a2a6df71db5f0229ea assets/create/blockstates/cut_scorchia_slab.json de2e918058e9dd7eafd085a8dec634f6a2832c21 assets/create/blockstates/cut_scorchia_stairs.json 5d2d06799b82449754f62b1d80b9ee9a24c65bad assets/create/blockstates/cut_scorchia_wall.json 76ea4f3438a3effedfc93d2bbabac0899610cd28 assets/create/blockstates/cut_scoria.json -6d9c79e1b71656a73bb69e2a9b100be59084dd2e assets/create/blockstates/cut_scoria_bricks.json 7c7dcd1fe82f3673910620c2eefebad5d0029cdf assets/create/blockstates/cut_scoria_brick_slab.json d535b387bf0a6f9e124eed8b76d899e13699bca9 assets/create/blockstates/cut_scoria_brick_stairs.json c426e1b5e4c77c25cd0d16d10fba0e0731673dd1 assets/create/blockstates/cut_scoria_brick_wall.json +6d9c79e1b71656a73bb69e2a9b100be59084dd2e assets/create/blockstates/cut_scoria_bricks.json fb692494c88358d4d8e687b216f729d6b6bd7174 assets/create/blockstates/cut_scoria_slab.json 950f43bae8f4e3220103ce0c62f444856129ca12 assets/create/blockstates/cut_scoria_stairs.json 01350030831c5b9edef0dc2c778b92f1ebc2b2fc assets/create/blockstates/cut_scoria_wall.json c0c1c4d44eba5babe9703eca31f0279ebd11ed8e assets/create/blockstates/cut_tuff.json -9bddef4a2b4a338c15f03e2397c4cd4c3ae9e5d9 assets/create/blockstates/cut_tuff_bricks.json 11306e83915e0106d48f890df3212c3a47443a08 assets/create/blockstates/cut_tuff_brick_slab.json e8951d94e0d3228700bcb56819928f1c179c3973 assets/create/blockstates/cut_tuff_brick_stairs.json 619340b7cf014cfb72a4b5440b90881535f16108 assets/create/blockstates/cut_tuff_brick_wall.json +9bddef4a2b4a338c15f03e2397c4cd4c3ae9e5d9 assets/create/blockstates/cut_tuff_bricks.json 3577e3f4933ea8cb7464c28e80867ce84917898d assets/create/blockstates/cut_tuff_slab.json 5673fdb02439d622c56dc0ff47a0dca98dc6d027 assets/create/blockstates/cut_tuff_stairs.json 12a46ee82536665400ec2f3befed3be58325d5c6 assets/create/blockstates/cut_tuff_wall.json beb9e47f8d811c2146f68daf992fb805342a65cb assets/create/blockstates/cut_veridium.json -04d07986eb86ffd66baaaf9b65e02d00022e98e2 assets/create/blockstates/cut_veridium_bricks.json 952543c03e730443d85059ec43642efb089485e7 assets/create/blockstates/cut_veridium_brick_slab.json 6a033e7b5a0b26cce5956c6c7c1eff558f866cb5 assets/create/blockstates/cut_veridium_brick_stairs.json 43689138c8018b3ee9f35a11870887e9df3c8fe5 assets/create/blockstates/cut_veridium_brick_wall.json +04d07986eb86ffd66baaaf9b65e02d00022e98e2 assets/create/blockstates/cut_veridium_bricks.json 212d8ee5dfa78802b9539640cf8b263fd5880b87 assets/create/blockstates/cut_veridium_slab.json c11f09df4a23e951bdf9a345515183f4fac7cde3 assets/create/blockstates/cut_veridium_stairs.json 3aa6f5e613ff73952e3de00408051f92316e7f81 assets/create/blockstates/cut_veridium_wall.json @@ -222,12 +222,12 @@ f7f5df9086c71688cbdb5d05c394dc5acb8fb338 assets/create/blockstates/elevator_cont d47bc65703e9582cc710e6408fb565e16d3514a6 assets/create/blockstates/encased_fan.json 651f9fdb11f56d887d131be8f936f508d0b2fc1d assets/create/blockstates/encased_fluid_pipe.json 489ad4daeaed702d231a3f175f7b66846f5789a6 assets/create/blockstates/experience_block.json -5f6c60a30889b043709066707e80a21081d98155 assets/create/blockstates/exposed_copper_shingles.json 74c8a72db3dd3fa919e29baaa8c5865f13490461 assets/create/blockstates/exposed_copper_shingle_slab.json 4e0b5a9be15f0c2861f5f6bd71bd9c2a4db2a21d assets/create/blockstates/exposed_copper_shingle_stairs.json -5299b4f7b9b3490872e8c26a6b212e14dd05fd9a assets/create/blockstates/exposed_copper_tiles.json +5f6c60a30889b043709066707e80a21081d98155 assets/create/blockstates/exposed_copper_shingles.json 6ee73ff3608d51fdad6e9810feee66ed1773b81c assets/create/blockstates/exposed_copper_tile_slab.json f93e4059876bfc6d70b9fa2bc24d8e3d6943d56f assets/create/blockstates/exposed_copper_tile_stairs.json +5299b4f7b9b3490872e8c26a6b212e14dd05fd9a assets/create/blockstates/exposed_copper_tiles.json f1a03ede031d8c4e33a4d07c529e71936da9dc6d assets/create/blockstates/fake_track.json 21fa4a1bf4ee851e090a21c97c9a38d18cfddf0d assets/create/blockstates/fluid_pipe.json 185e6367c5c5b3632e54148c74987057cbfccaca assets/create/blockstates/fluid_tank.json @@ -292,13 +292,13 @@ fa5fb2be73c7c54b70e927b66adf3f4d64c5cb6b assets/create/blockstates/light_gray_ni 8ec5144da4a49dd5b497af07b0d4b88c9c0b6cc0 assets/create/blockstates/light_gray_seat.json 35b151db396069b146d223fbe46be5b0c3dda8a9 assets/create/blockstates/light_gray_toolbox.json 894827ffd176bc733abecf18d96888e9ed5a3eb4 assets/create/blockstates/light_gray_valve_handle.json -a6f319c803c03e34bbf841ea52d82f0f7ec7a413 assets/create/blockstates/limestone.json -7ff65e1c4c8e48a0b694cd17506a192e6a7e6e44 assets/create/blockstates/limestone_pillar.json 7f20b548dd535942b2d6f41c39de7ad4fafe637e assets/create/blockstates/lime_nixie_tube.json ad1ec304729fd6d336c0d4d0c27c9345af636695 assets/create/blockstates/lime_sail.json b9934a558e1b495403dc2c71ffb43cce7d396013 assets/create/blockstates/lime_seat.json 49a02f7fc16697ba1cf16cee7e45ab6bfd8b06ce assets/create/blockstates/lime_toolbox.json ba181485f219d3ae23509a7edf28e25d9edb10f4 assets/create/blockstates/lime_valve_handle.json +a6f319c803c03e34bbf841ea52d82f0f7ec7a413 assets/create/blockstates/limestone.json +7ff65e1c4c8e48a0b694cd17506a192e6a7e6e44 assets/create/blockstates/limestone_pillar.json 654e845cebed82b7afbcf81380921e0a475b01e9 assets/create/blockstates/linear_chassis.json e195e82e4d0c1fc20474535bc9068cbb77a5e175 assets/create/blockstates/lit_blaze_burner.json 296186b196af94e1ab3f7e8a3254f6d31ae47a5c assets/create/blockstates/magenta_nixie_tube.json @@ -340,12 +340,12 @@ aab812cecf7d10d4e7587f4dead8a98238a15f41 assets/create/blockstates/orange_seat.j 2af63a4768f84fc93c7e7d67fa9a64438433e59f assets/create/blockstates/orange_valve_handle.json 515ed7dae09b052f289419ba09998a23e0d7083d assets/create/blockstates/ornate_iron_window.json 8118444f37536b9104ef4818d374b0c8a7c987bf assets/create/blockstates/ornate_iron_window_pane.json -97cd78453af94f44cef1187988966626574b29d5 assets/create/blockstates/oxidized_copper_shingles.json 2ddc762b8d8558e69a2f81c028702f3a25b5e978 assets/create/blockstates/oxidized_copper_shingle_slab.json ac536ae742c12e97bfd0b2483c87ff29f3935eaf assets/create/blockstates/oxidized_copper_shingle_stairs.json -110a6c19bcc9f044e5e982ac6e4b295b03ec0145 assets/create/blockstates/oxidized_copper_tiles.json +97cd78453af94f44cef1187988966626574b29d5 assets/create/blockstates/oxidized_copper_shingles.json 3f3924f0f0e368edfa04f4fdd6d6c2319276ddfe assets/create/blockstates/oxidized_copper_tile_slab.json 5e634cfb9abb06d8b29f39d751fc56b28ea5a9cd assets/create/blockstates/oxidized_copper_tile_stairs.json +110a6c19bcc9f044e5e982ac6e4b295b03ec0145 assets/create/blockstates/oxidized_copper_tiles.json 36742cc6ce052ead143366d31b11e828a525c1b8 assets/create/blockstates/peculiar_bell.json 53d102e706d53cb2c0dbc0bc11da828084a43519 assets/create/blockstates/pink_nixie_tube.json 213da5c04a33ae8ae7c0a4dec9844bbb6d670e33 assets/create/blockstates/pink_sail.json @@ -426,13 +426,13 @@ f8f9802df9c0b4e39edeefc3b1abb38255d79801 assets/create/blockstates/purple_sail.j 3aca01f2eddb22adb1b25735b98a990bfc7220d2 assets/create/blockstates/radial_chassis.json 72faac9777be540f95f8b662a833856e0e1b8f35 assets/create/blockstates/railway_casing.json 7ce346fa18702f6fe6e2a939efcfa26eda63fe38 assets/create/blockstates/raw_zinc_block.json -ec546afd3ec8036e4393b97d535f05a86f57dbc1 assets/create/blockstates/redstone_contact.json -ff205f032b36486753dddb1f2029ef8d53e9c86f assets/create/blockstates/redstone_link.json e3fd62e466e3e6e7bd6fc8661f764ba972a466fc assets/create/blockstates/red_nixie_tube.json 4c36b562da58ef2af57009da7cf2426059249228 assets/create/blockstates/red_sail.json 145f4e9ffaeff9be180e6c4e4989f2cf44cf0686 assets/create/blockstates/red_seat.json 380f46b7cb72b13c0f16fd4a4287a1a33adeff41 assets/create/blockstates/red_toolbox.json b689d87a27ed0cb2cab190a2ad2b599818bff56c assets/create/blockstates/red_valve_handle.json +ec546afd3ec8036e4393b97d535f05a86f57dbc1 assets/create/blockstates/redstone_contact.json +ff205f032b36486753dddb1f2029ef8d53e9c86f assets/create/blockstates/redstone_link.json 87ab7ca62ecf24d60d7e5c61bd5af97714dad0ad assets/create/blockstates/refined_radiance_casing.json 3807bcc6ccc3dad0dbfcc8fcf260a361aa488659 assets/create/blockstates/rope.json baa7da231c6c45d5eabaf04985d46e206a3346f8 assets/create/blockstates/rope_pulley.json @@ -441,8 +441,8 @@ dd63fd8443a2be507281548df838d878b0c3c8c8 assets/create/blockstates/rose_quartz_l dfe69ee57f832a2e4c576ee01bdde1617c81e46a assets/create/blockstates/rose_quartz_tiles.json b9cbbc7c4e1d9abd312263a9a270315bd5f0106b assets/create/blockstates/rotation_speed_controller.json 5a25ecb95b7978cc487491cb24478e4d6a73e977 assets/create/blockstates/sail_frame.json -bff758cc56bece375b40c32067b903b675065328 assets/create/blockstates/schematicannon.json 505510656c77d93ecd3691e7111615193275f29e assets/create/blockstates/schematic_table.json +bff758cc56bece375b40c32067b903b675065328 assets/create/blockstates/schematicannon.json 82c9ceb19cfc4e247fbb62a9605630ba08423efe assets/create/blockstates/scorchia.json 6fa99d5f1ff05153660f9917286d4b157eaa1b40 assets/create/blockstates/scorchia_pillar.json 8c34743564aa0473745ecec304a19e15e9e87cf2 assets/create/blockstates/scoria.json @@ -451,64 +451,64 @@ e5aff9dc8fa5e98b060232974194afb06d497d09 assets/create/blockstates/scoria_pillar 3343224d6da4e75f0bc7a7634ba010a4ba54ad70 assets/create/blockstates/sequenced_gearshift.json 4c261d54117ee295b307f6ea3e56a09437631f73 assets/create/blockstates/shadow_steel_casing.json 4c67d2a1a1faea5be2a81ebc0722c32d8e2e84d6 assets/create/blockstates/shaft.json -c606f103619088e8a5afe969ba54929af480a3d2 assets/create/blockstates/small_andesite_bricks.json c5469de5957d77fc11febaa658ee2bfb0d11b0bc assets/create/blockstates/small_andesite_brick_slab.json ed0bcfd07959aa208085910bd3780756979c985d assets/create/blockstates/small_andesite_brick_stairs.json 78e30e63adedf1ca95261eb4010a1db45aecfe9e assets/create/blockstates/small_andesite_brick_wall.json -b9fedc13dc8cb53a8bb16ce2257ea65f0ac94a6b assets/create/blockstates/small_asurine_bricks.json +c606f103619088e8a5afe969ba54929af480a3d2 assets/create/blockstates/small_andesite_bricks.json 653fa70f0aa7fc319d50f72692d507ff7c59c0f4 assets/create/blockstates/small_asurine_brick_slab.json e61a0b891729565434d6ab34aa3aeada7d189f9d assets/create/blockstates/small_asurine_brick_stairs.json 02556b916c198c683279eb4392ebaa31fb41e182 assets/create/blockstates/small_asurine_brick_wall.json +b9fedc13dc8cb53a8bb16ce2257ea65f0ac94a6b assets/create/blockstates/small_asurine_bricks.json e986248237013eea755bccd300f745e44d0a183f assets/create/blockstates/small_bogey.json -031d9492dbcc5de77431e8f54b9b04db412b5690 assets/create/blockstates/small_calcite_bricks.json 898bca10ff6e5402c4b8b84e1b9ba9036b32b8bc assets/create/blockstates/small_calcite_brick_slab.json ecc2276bdb2b24f54e31372bf207171a348e55d3 assets/create/blockstates/small_calcite_brick_stairs.json d9dd243b5b754a487755b53609d404ac1b3fde99 assets/create/blockstates/small_calcite_brick_wall.json -3d4e0b54ffda83f7f6e08b6a745db81049d95f3b assets/create/blockstates/small_crimsite_bricks.json +031d9492dbcc5de77431e8f54b9b04db412b5690 assets/create/blockstates/small_calcite_bricks.json 4094bf00cad8dea2dd234866b482c07175802c4c assets/create/blockstates/small_crimsite_brick_slab.json 7f73a2505e2a3a98a7749fa98f4623aa2d216edd assets/create/blockstates/small_crimsite_brick_stairs.json b477c7f1855c9eb2ef1bf672376e972678dc563f assets/create/blockstates/small_crimsite_brick_wall.json -17359d1b87399bb066cfc23002bcf0d8f71d8ccd assets/create/blockstates/small_deepslate_bricks.json +3d4e0b54ffda83f7f6e08b6a745db81049d95f3b assets/create/blockstates/small_crimsite_bricks.json c67f32adc49f0b24b34f098a390a398813365260 assets/create/blockstates/small_deepslate_brick_slab.json d05aed31d45ed12f8f117a9c64312b1abff8bd2f assets/create/blockstates/small_deepslate_brick_stairs.json 6952b02d8c5adf3d0d1a243221b637c50edaa287 assets/create/blockstates/small_deepslate_brick_wall.json -6c0ac59e09feb76afc078a88431442a2a6381c6c assets/create/blockstates/small_diorite_bricks.json +17359d1b87399bb066cfc23002bcf0d8f71d8ccd assets/create/blockstates/small_deepslate_bricks.json ee39994b434a17ec7497b271a6e0a006cf6311cb assets/create/blockstates/small_diorite_brick_slab.json eb335cf0a857299b9cd0c4f60e00bc8e4ca7efe8 assets/create/blockstates/small_diorite_brick_stairs.json b6f7c563c30483c749849899b96d4f0030b71df1 assets/create/blockstates/small_diorite_brick_wall.json -d51095bfb9d5758f8b3972a973fbe282569b0234 assets/create/blockstates/small_dripstone_bricks.json +6c0ac59e09feb76afc078a88431442a2a6381c6c assets/create/blockstates/small_diorite_bricks.json 3d8109d327099c65ca0fafcb5651051059cad1df assets/create/blockstates/small_dripstone_brick_slab.json 3931e24229db79115ffe2a9f3a069202b9b8dcab assets/create/blockstates/small_dripstone_brick_stairs.json 0d16cefcb8e619bc81ef65111d16d331db58d0aa assets/create/blockstates/small_dripstone_brick_wall.json -11dcaf8a6da96d178024b4c3ee76b9c373e5d082 assets/create/blockstates/small_granite_bricks.json +d51095bfb9d5758f8b3972a973fbe282569b0234 assets/create/blockstates/small_dripstone_bricks.json 096b064f28fbe381e1b637d4668550851cbbb2c2 assets/create/blockstates/small_granite_brick_slab.json e99cc3251937fbf9fc858623d5ea525ed5b79704 assets/create/blockstates/small_granite_brick_stairs.json 62f2b570ac6073c8a98369523095d2c18a353eed assets/create/blockstates/small_granite_brick_wall.json -346dbff9a84b988bd9c9af670b486b6af5e18179 assets/create/blockstates/small_limestone_bricks.json +11dcaf8a6da96d178024b4c3ee76b9c373e5d082 assets/create/blockstates/small_granite_bricks.json d640eed81abaa013ed1c53d68a552f639168ae8b assets/create/blockstates/small_limestone_brick_slab.json d470967200aa6ca618421cf375140b352c45cc90 assets/create/blockstates/small_limestone_brick_stairs.json 8d4a1eff66a3f45d595ff8371c0d1ebaa0ba1773 assets/create/blockstates/small_limestone_brick_wall.json -1464b01d4c8bd9ec56460c1250fd4bb07e936e22 assets/create/blockstates/small_ochrum_bricks.json +346dbff9a84b988bd9c9af670b486b6af5e18179 assets/create/blockstates/small_limestone_bricks.json ddee92141e00898e8d70145cf00c0d64f56b4f48 assets/create/blockstates/small_ochrum_brick_slab.json bad9a5820c64c125494c0eba4f6c7ebebe93341c assets/create/blockstates/small_ochrum_brick_stairs.json ed899a18522adc70ae46185c308904c8de5b5834 assets/create/blockstates/small_ochrum_brick_wall.json +1464b01d4c8bd9ec56460c1250fd4bb07e936e22 assets/create/blockstates/small_ochrum_bricks.json c520e9ba54ff6dfb96f7863bb093cdf15cc95ce4 assets/create/blockstates/small_rose_quartz_tiles.json -371ff795eb4e7cb1220d307abf8cb003f455cbec assets/create/blockstates/small_scorchia_bricks.json 384a1331b92b7beba988f729bb7cda42abec0172 assets/create/blockstates/small_scorchia_brick_slab.json 046a84030a23f5a40f4deac13f2e60ced436cadf assets/create/blockstates/small_scorchia_brick_stairs.json 58bc6e3bb10ed72b8cb5813a88cab300d1183b7d assets/create/blockstates/small_scorchia_brick_wall.json -0aa51dbfda8349b878e2f6c9bb3314fcfc1a9c39 assets/create/blockstates/small_scoria_bricks.json +371ff795eb4e7cb1220d307abf8cb003f455cbec assets/create/blockstates/small_scorchia_bricks.json 5b227400e588abae33c1682196f098adc8006d13 assets/create/blockstates/small_scoria_brick_slab.json 51420bb12b757d3888fd1ceb5c21d83b42bd2266 assets/create/blockstates/small_scoria_brick_stairs.json 36e9bd161fa4ffe18f07153b2945cfeae55e7c0b assets/create/blockstates/small_scoria_brick_wall.json -c1f9f986dd0bfdbdee210c6c7d71981b251c27db assets/create/blockstates/small_tuff_bricks.json +0aa51dbfda8349b878e2f6c9bb3314fcfc1a9c39 assets/create/blockstates/small_scoria_bricks.json 8d1af444031291fe58d850ae344aaf7e97b8bd87 assets/create/blockstates/small_tuff_brick_slab.json 26879e6cadf0035c3eed4b54b3a1fdc0c080a485 assets/create/blockstates/small_tuff_brick_stairs.json 5d58ca7b81ae537454c3cdbb5fc8aacca83cff3f assets/create/blockstates/small_tuff_brick_wall.json -ad79aa8ff306695f65386fdeb44c5285547934b6 assets/create/blockstates/small_veridium_bricks.json +c1f9f986dd0bfdbdee210c6c7d71981b251c27db assets/create/blockstates/small_tuff_bricks.json 6226471fdcadbbf0e02704bb0e7de607e99302a8 assets/create/blockstates/small_veridium_brick_slab.json b54200ebe65c4ad2e5661c81ba5bf939039277ca assets/create/blockstates/small_veridium_brick_stairs.json 0237d58443ca9dc2a9186c2387dd6633702a7598 assets/create/blockstates/small_veridium_brick_wall.json +ad79aa8ff306695f65386fdeb44c5285547934b6 assets/create/blockstates/small_veridium_bricks.json 4d987859e5f5a930c20e955919304088fb6fc6d1 assets/create/blockstates/smart_chute.json 57fc35b2e0ae9ab16c011abd95f507910c70a234 assets/create/blockstates/smart_fluid_pipe.json a70c025de5d85180f371ff05bbdc531d8bdfaab1 assets/create/blockstates/speedometer.json @@ -540,36 +540,36 @@ bfb2b7eabba2e7aef4d783328c8a5a1558e7e493 assets/create/blockstates/turntable.jso 116d0a8fb72bcc00bd511db7893ea3e96efda297 assets/create/blockstates/warped_window_pane.json fa3d300520e3bedb926696d9980cbeeb54cfdc68 assets/create/blockstates/water_wheel.json 3dff9e1ec59415779195d2abfa9f07bc17b428a1 assets/create/blockstates/water_wheel_structure.json -2ae175c489b86b78b4646306250ca2dba66b0a5e assets/create/blockstates/waxed_copper_shingles.json 85ed36dcb0a3542e0638601116360202a9670d53 assets/create/blockstates/waxed_copper_shingle_slab.json aaf49f1b6785e2195c5dc2e8792c99c960745f89 assets/create/blockstates/waxed_copper_shingle_stairs.json -835bfe0d2137ad60e5f8322fa4449d5c7a02187f assets/create/blockstates/waxed_copper_tiles.json +2ae175c489b86b78b4646306250ca2dba66b0a5e assets/create/blockstates/waxed_copper_shingles.json b52eda74c9000507a4f34e10fbd1a7846b66c16d assets/create/blockstates/waxed_copper_tile_slab.json 5428969f6f27213d0ec5140d911b3844b5332006 assets/create/blockstates/waxed_copper_tile_stairs.json -306b9cd1efe3abd1fcca11bc464560837fb8fdfa assets/create/blockstates/waxed_exposed_copper_shingles.json +835bfe0d2137ad60e5f8322fa4449d5c7a02187f assets/create/blockstates/waxed_copper_tiles.json bc8f3bb75bdb094c8372d61a68927270d3347437 assets/create/blockstates/waxed_exposed_copper_shingle_slab.json 32382e5f524b50393080fdbd2415a98ddb700c9c assets/create/blockstates/waxed_exposed_copper_shingle_stairs.json -ae92a9051f1603e7ad4f93cb668706ccffc7a85b assets/create/blockstates/waxed_exposed_copper_tiles.json +306b9cd1efe3abd1fcca11bc464560837fb8fdfa assets/create/blockstates/waxed_exposed_copper_shingles.json ca37c3e54d5c78a77fcb4a4aca004a34e271f246 assets/create/blockstates/waxed_exposed_copper_tile_slab.json a864f82ccd6b3e0fa181c800da886ebd3239fb82 assets/create/blockstates/waxed_exposed_copper_tile_stairs.json -729ca65a140b3d7571a2072f7406cc5f4a2e27c5 assets/create/blockstates/waxed_oxidized_copper_shingles.json +ae92a9051f1603e7ad4f93cb668706ccffc7a85b assets/create/blockstates/waxed_exposed_copper_tiles.json ef99e849f9dd6ad53ddf04625c81750f11eaae1c assets/create/blockstates/waxed_oxidized_copper_shingle_slab.json 9386068220f9bb5d2f6d3cc408dc4f78f26b4eeb assets/create/blockstates/waxed_oxidized_copper_shingle_stairs.json -17acf3486e92aabc3efbe99fa1e5d7d664e6ec97 assets/create/blockstates/waxed_oxidized_copper_tiles.json +729ca65a140b3d7571a2072f7406cc5f4a2e27c5 assets/create/blockstates/waxed_oxidized_copper_shingles.json fe79f7eab017d714c0331664a3a2b5579104194e assets/create/blockstates/waxed_oxidized_copper_tile_slab.json 10bbe77a0334b5578b1ec40b398a45cf7d2bb534 assets/create/blockstates/waxed_oxidized_copper_tile_stairs.json -079acbfd6a9375899687b581f95bbe74940afce2 assets/create/blockstates/waxed_weathered_copper_shingles.json +17acf3486e92aabc3efbe99fa1e5d7d664e6ec97 assets/create/blockstates/waxed_oxidized_copper_tiles.json 73572bbe16957e63853ee425d8f34d98e14e4a10 assets/create/blockstates/waxed_weathered_copper_shingle_slab.json ab05925d5bb70e53fec9c149982304f31acd2b1a assets/create/blockstates/waxed_weathered_copper_shingle_stairs.json -202b0f2e6fca9eab949f47eaa1f4ddee249a633a assets/create/blockstates/waxed_weathered_copper_tiles.json +079acbfd6a9375899687b581f95bbe74940afce2 assets/create/blockstates/waxed_weathered_copper_shingles.json fc1b53d3b2b1f0977069abec3c376f3f5c4cd7c8 assets/create/blockstates/waxed_weathered_copper_tile_slab.json 6cd93476a45c3b77f5eda66f68425bae486cfba8 assets/create/blockstates/waxed_weathered_copper_tile_stairs.json -c11562afd9a5f85945e521dcea5f911d1b6d13c6 assets/create/blockstates/weathered_copper_shingles.json +202b0f2e6fca9eab949f47eaa1f4ddee249a633a assets/create/blockstates/waxed_weathered_copper_tiles.json 5a5a1e95988edb7a2b6dc6c6ba5677c2d896a5ae assets/create/blockstates/weathered_copper_shingle_slab.json 07019fc8890cb5e966a42ca636a0ab9cf71cc881 assets/create/blockstates/weathered_copper_shingle_stairs.json -236e072d9056c0dbffdf5d7d973a85a56c2c8de1 assets/create/blockstates/weathered_copper_tiles.json +c11562afd9a5f85945e521dcea5f911d1b6d13c6 assets/create/blockstates/weathered_copper_shingles.json fee668eb9a45dca0d287fee5811219d69f9ec3e2 assets/create/blockstates/weathered_copper_tile_slab.json da110f382368257e15431c77164aef82e014e3f8 assets/create/blockstates/weathered_copper_tile_stairs.json +236e072d9056c0dbffdf5d7d973a85a56c2c8de1 assets/create/blockstates/weathered_copper_tiles.json 25ce64b7af5d244f194da91ccf964a9bf5762327 assets/create/blockstates/weighted_ejector.json 2974b34a8cfb0d4e8e010f8bd085584ea631d541 assets/create/blockstates/white_nixie_tube.json f079469d186087d23f0d91b384040f777b0088b1 assets/create/blockstates/white_sail.json @@ -585,8 +585,8 @@ b0d8f08968763a5f74e5cd5644377a76a9f39753 assets/create/blockstates/yellow_toolbo fe8c497aacc641c2f01cec90bba9f19e59cc2ed2 assets/create/blockstates/yellow_valve_handle.json e819e93fdcbe9fd9c050a052d2718ff3b3539365 assets/create/blockstates/zinc_block.json 64121dcb216381c83b4fe28aa361ea07c24c9ad0 assets/create/blockstates/zinc_ore.json -d3d30a92e4f63e8acb6aa3e3358b6e8340aa8cc1 assets/create/lang/en_ud.json -a50be2f8a02b0fdd2b5a8aae9cf8df1490015707 assets/create/lang/en_us.json +5f729ba3f0557eb1c1923a091e06eee5ddf25c59 assets/create/lang/en_ud.json +bdd95ac05db0717d02e4dc34b6054e73d4eee640 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 @@ -726,20 +726,20 @@ d063df8e9b974c11fc7810ce176b02d7d924e15b assets/create/models/block/copper_post. 2b5aed4a917694beb33d9b0ecbc800dcbc143ee9 assets/create/models/block/copper_post_ends.json bac7566a726b0fe6d537c744aec4afb383dc165c assets/create/models/block/copper_scaffolding.json dbee65c129740f3b99c07e754b3224d3f9f8c242 assets/create/models/block/copper_scaffolding_horizontal.json -32fdb85b5b62d5a0fb41732874c854788cdd2ba1 assets/create/models/block/copper_shingles.json fb7fb6deebd502946ab57f1b8a9f4a6b5dd48da3 assets/create/models/block/copper_shingle_slab.json 660f61112b8e46dec5050cb0ed4ee936965a7c58 assets/create/models/block/copper_shingle_slab_top.json 5d74be967bbe9feba4b630751f13af817a733d1d assets/create/models/block/copper_shingle_stairs.json 35cb89f29ce3f8d8af13602c08ecd7afbb7cf56a assets/create/models/block/copper_shingle_stairs_inner.json fcb9295f4f388e6d439ec9a3906ca326b6d69077 assets/create/models/block/copper_shingle_stairs_outer.json +32fdb85b5b62d5a0fb41732874c854788cdd2ba1 assets/create/models/block/copper_shingles.json cb218a725f82db34ffe58a5208266e1c768cfc05 assets/create/models/block/copper_side.json d9b4652ca8f1e65007f42d946ecfb38acc3f168f assets/create/models/block/copper_side_alt.json -32f06f39d0b34e4431795aa6e64f87e58dc1597b assets/create/models/block/copper_tiles.json 298c6100de02ed9f813397d8ba38c46f35035c69 assets/create/models/block/copper_tile_slab.json d4422c2d96fb329087d1be70d8b983a8cf6c7f01 assets/create/models/block/copper_tile_slab_top.json fca72048f916d3a3e567b385c948cc1b59711ef4 assets/create/models/block/copper_tile_stairs.json 997479b62ed3d81ab633279ecc2fabd9588a3bf3 assets/create/models/block/copper_tile_stairs_inner.json d5c5bbfb9aaa282e11ad6e6309b1880b172ee653 assets/create/models/block/copper_tile_stairs_outer.json +32f06f39d0b34e4431795aa6e64f87e58dc1597b assets/create/models/block/copper_tiles.json fa2fa91e674eb4de440617049dae34064fd6fa39 assets/create/models/block/copper_valve_handle.json 52ae02c17509e483e35a1b6055296c3a663f85d7 assets/create/models/block/crate/creative/bottom.json 689989ecbd4d59d5836deb8adf7af1d473a377c0 assets/create/models/block/crate/creative/left.json @@ -783,15 +783,15 @@ b3f403f77e3b1b44c56450e387136bca12a84a99 assets/create/models/block/crimson_wind 117d14a1f25cc8ac633bb4cc8a81830a1c016096 assets/create/models/block/crimson_window_pane_side.json ee13522aadfca40f856499d5c29bd86d8f4dda57 assets/create/models/block/crimson_window_pane_side_alt.json 40042ce15d51445ec71b73da34477fa735f3fdd4 assets/create/models/block/cut_andesite.json -5be7d431ac56e2ceb9e3d95589d687f757d5257c assets/create/models/block/cut_andesite_bricks.json -c78e2acf9b54d7370f12e34dcca5c71743f47d55 assets/create/models/block/cut_andesite_bricks_wall_post.json -88e3c8eadf97f772fbafe3b71c8dd27c91c0c0e3 assets/create/models/block/cut_andesite_bricks_wall_side.json -bc264e09c506418b01c6032dcab8ca28080cb70b assets/create/models/block/cut_andesite_bricks_wall_side_tall.json fcbe246aca067dcfeef7afb4e6068b8932da8792 assets/create/models/block/cut_andesite_brick_slab.json e384a98b54ed7317b6ad0e86cf87500491eea824 assets/create/models/block/cut_andesite_brick_slab_top.json 91699e60e29e7524271a2f87200951ee8bfeb8ef assets/create/models/block/cut_andesite_brick_stairs.json e314e0837aed319cdf34a1aaa60f0be6ca169636 assets/create/models/block/cut_andesite_brick_stairs_inner.json aba679c4c6a8d5afc2924d2c9c84af5a2208fde3 assets/create/models/block/cut_andesite_brick_stairs_outer.json +5be7d431ac56e2ceb9e3d95589d687f757d5257c assets/create/models/block/cut_andesite_bricks.json +c78e2acf9b54d7370f12e34dcca5c71743f47d55 assets/create/models/block/cut_andesite_bricks_wall_post.json +88e3c8eadf97f772fbafe3b71c8dd27c91c0c0e3 assets/create/models/block/cut_andesite_bricks_wall_side.json +bc264e09c506418b01c6032dcab8ca28080cb70b assets/create/models/block/cut_andesite_bricks_wall_side_tall.json 8c17ba39e50a440497af089f5fd85649f05bdf8c assets/create/models/block/cut_andesite_slab.json b95ab966cf8c177c799e228759d0cd28c1cfa71f assets/create/models/block/cut_andesite_slab_top.json 81a407a5ff4393b66f784ba4ceee971c3c62de7f assets/create/models/block/cut_andesite_stairs.json @@ -801,15 +801,15 @@ f06abcb3ce691fd30db81b40ea0430462fc972cf assets/create/models/block/cut_andesite 81cef9548137aaff5b6e77d417f387796f2608b2 assets/create/models/block/cut_andesite_wall_side.json dbb99ac37333ee12b7d3859207409aa2599f28eb assets/create/models/block/cut_andesite_wall_side_tall.json a48f77e90c1d02d5b4e6540db723f748118788e9 assets/create/models/block/cut_asurine.json -3b0b7bd63870ac19b9444ce9add9930ec9120821 assets/create/models/block/cut_asurine_bricks.json -89142424e1d702a0f2bc27829304520e48ee1eb3 assets/create/models/block/cut_asurine_bricks_wall_post.json -1f1fcf92e91b1f0d15ba389d6d25e1fba3ad8e5b assets/create/models/block/cut_asurine_bricks_wall_side.json -858d15aff53fe938304bafb52ef32e54e3d44a44 assets/create/models/block/cut_asurine_bricks_wall_side_tall.json 4107317f71d07fb1c113e056c832e963f57b41d7 assets/create/models/block/cut_asurine_brick_slab.json fba2e8dc513184eaa9c4449471b32f206dfe425a assets/create/models/block/cut_asurine_brick_slab_top.json 72bb7b2df330f8d5981f4c12b23429d8d874362d assets/create/models/block/cut_asurine_brick_stairs.json e753ba3830c51539565abbd9b49df9a34f97f2ff assets/create/models/block/cut_asurine_brick_stairs_inner.json ec9182d14517ffc71749e3e016e6546db79e6800 assets/create/models/block/cut_asurine_brick_stairs_outer.json +3b0b7bd63870ac19b9444ce9add9930ec9120821 assets/create/models/block/cut_asurine_bricks.json +89142424e1d702a0f2bc27829304520e48ee1eb3 assets/create/models/block/cut_asurine_bricks_wall_post.json +1f1fcf92e91b1f0d15ba389d6d25e1fba3ad8e5b assets/create/models/block/cut_asurine_bricks_wall_side.json +858d15aff53fe938304bafb52ef32e54e3d44a44 assets/create/models/block/cut_asurine_bricks_wall_side_tall.json b4512f7cef7cef0bc5f85cb955c2dec6de2cbb56 assets/create/models/block/cut_asurine_slab.json 7c1befdd97b1556e9658e968e705c9edbf1ed667 assets/create/models/block/cut_asurine_slab_top.json d04b8a8cf9a50aa7e0b068ceb9a5a2970abc81a7 assets/create/models/block/cut_asurine_stairs.json @@ -819,15 +819,15 @@ ac544a8f948119945aa21362ad26ed8b1c922b0d assets/create/models/block/cut_asurine_ a253210cba60f58e720598323bd0d9ed4c209b4d assets/create/models/block/cut_asurine_wall_side.json c0c2cc13288771699a80c5c80e8e35d352cea684 assets/create/models/block/cut_asurine_wall_side_tall.json a6b10dc7984d22cac7aa314d46ac0928a00e667b assets/create/models/block/cut_calcite.json -6230a499321b175fc441bb662e0655662b3597de assets/create/models/block/cut_calcite_bricks.json -be1462847e9001a062091162802fab2fe6737693 assets/create/models/block/cut_calcite_bricks_wall_post.json -6e6b34468a7a0786efe5f4ebd917a4640b4be6ae assets/create/models/block/cut_calcite_bricks_wall_side.json -8b10c0f4f17f3844cee6d514cc22ddc6cb056c8a assets/create/models/block/cut_calcite_bricks_wall_side_tall.json f046be4f44936946bd3cc2ad5549d112b2e60d97 assets/create/models/block/cut_calcite_brick_slab.json 64953ca8a302ecab9311c617f69e5dcf8c138718 assets/create/models/block/cut_calcite_brick_slab_top.json 19e1b342d05d3cd69c410952dc22507c3c988c15 assets/create/models/block/cut_calcite_brick_stairs.json 18317b0a8bab345abd779f5d43f9620b73df0e67 assets/create/models/block/cut_calcite_brick_stairs_inner.json 0631d4e1bdaf724752f2e55401eb7a54af705b56 assets/create/models/block/cut_calcite_brick_stairs_outer.json +6230a499321b175fc441bb662e0655662b3597de assets/create/models/block/cut_calcite_bricks.json +be1462847e9001a062091162802fab2fe6737693 assets/create/models/block/cut_calcite_bricks_wall_post.json +6e6b34468a7a0786efe5f4ebd917a4640b4be6ae assets/create/models/block/cut_calcite_bricks_wall_side.json +8b10c0f4f17f3844cee6d514cc22ddc6cb056c8a assets/create/models/block/cut_calcite_bricks_wall_side_tall.json 6b35e0f9e6a7e247bf38d8d6d911a2bcc53c2517 assets/create/models/block/cut_calcite_slab.json 0eec7692ee8e119c1258bdb7e852204771c2232d assets/create/models/block/cut_calcite_slab_top.json d07ebf8982e4947852da8b2b0052f6b6000d334f assets/create/models/block/cut_calcite_stairs.json @@ -837,15 +837,15 @@ e8b7b983168ad9f4f4fa1642ca20ff56621935db assets/create/models/block/cut_calcite_ 421e128177bb4dd51391e360f11ba83c5d891cd1 assets/create/models/block/cut_calcite_wall_side.json 5add4bde51bbdd7c229b05f4fabd8a769414fb79 assets/create/models/block/cut_calcite_wall_side_tall.json 2e93da554ea72b90a576bbc9230aea373d3aed0f assets/create/models/block/cut_crimsite.json -39d1a3cdd978c761bc0d67baaba82d11953fc2a0 assets/create/models/block/cut_crimsite_bricks.json -8614cb38c52447fea5245fcf295a951a977071c0 assets/create/models/block/cut_crimsite_bricks_wall_post.json -b0b16f4a2f6dd3f77ec4f65f05e9edb70a196316 assets/create/models/block/cut_crimsite_bricks_wall_side.json -ac41e5b092c6ed81d14004f9427b6151b88dc924 assets/create/models/block/cut_crimsite_bricks_wall_side_tall.json c2474a10109d0476a46d2a509fc1cd37cd52822d assets/create/models/block/cut_crimsite_brick_slab.json efeb149835a389409b7f94bc35765b0871ad7342 assets/create/models/block/cut_crimsite_brick_slab_top.json e5096a1bae43341bae5706f02cd6d564b5a82502 assets/create/models/block/cut_crimsite_brick_stairs.json af3c0018e5e12bbe0f118bc0174b6ca513ae58ae assets/create/models/block/cut_crimsite_brick_stairs_inner.json ed30baef426f2ccf158d87111c7b53f3600bc32a assets/create/models/block/cut_crimsite_brick_stairs_outer.json +39d1a3cdd978c761bc0d67baaba82d11953fc2a0 assets/create/models/block/cut_crimsite_bricks.json +8614cb38c52447fea5245fcf295a951a977071c0 assets/create/models/block/cut_crimsite_bricks_wall_post.json +b0b16f4a2f6dd3f77ec4f65f05e9edb70a196316 assets/create/models/block/cut_crimsite_bricks_wall_side.json +ac41e5b092c6ed81d14004f9427b6151b88dc924 assets/create/models/block/cut_crimsite_bricks_wall_side_tall.json a6cdd4b227210b7487b8431b8d76bbe490636b81 assets/create/models/block/cut_crimsite_slab.json 5c585dba4dbfa9ff0a22a84aa726260cffdeebeb assets/create/models/block/cut_crimsite_slab_top.json 91f60b4277ca48dabfb5d3eebb1ed64a2681a083 assets/create/models/block/cut_crimsite_stairs.json @@ -855,15 +855,15 @@ e6b39a0b1dbab462479fc60fab2efc6a9ceb6a55 assets/create/models/block/cut_crimsite 5b3783862e50fde6ffffc92068900afcc066002f assets/create/models/block/cut_crimsite_wall_side.json b59fbbfe9c6738b1f93f03d59a747f5610164c34 assets/create/models/block/cut_crimsite_wall_side_tall.json 144ec3864fb0a7981e74d357200a96033c75a2d6 assets/create/models/block/cut_deepslate.json -0d599ae1b4e9309f2a7b3362e86061e2150ba3ec assets/create/models/block/cut_deepslate_bricks.json -601894e096edbcd3d96ce0160f06e17a4efca819 assets/create/models/block/cut_deepslate_bricks_wall_post.json -42db46cb5c9c02d684c86f3a518feb3348d83fa0 assets/create/models/block/cut_deepslate_bricks_wall_side.json -c046436d59c350c6beb6b395675513c12184ffe2 assets/create/models/block/cut_deepslate_bricks_wall_side_tall.json af8c7c652e75bf904093bbafc1cf805f842a39c9 assets/create/models/block/cut_deepslate_brick_slab.json 2a01dd0244b07f28454c061a565d1028ca7e3066 assets/create/models/block/cut_deepslate_brick_slab_top.json 62d39eec3621204de82377e74936b9cd338e8004 assets/create/models/block/cut_deepslate_brick_stairs.json 5f90dfbb45b57bd894bf03fcc6c347cb525e3a73 assets/create/models/block/cut_deepslate_brick_stairs_inner.json 512d588c77bdf5a7232826e2f4ce4b3cb991d0ce assets/create/models/block/cut_deepslate_brick_stairs_outer.json +0d599ae1b4e9309f2a7b3362e86061e2150ba3ec assets/create/models/block/cut_deepslate_bricks.json +601894e096edbcd3d96ce0160f06e17a4efca819 assets/create/models/block/cut_deepslate_bricks_wall_post.json +42db46cb5c9c02d684c86f3a518feb3348d83fa0 assets/create/models/block/cut_deepslate_bricks_wall_side.json +c046436d59c350c6beb6b395675513c12184ffe2 assets/create/models/block/cut_deepslate_bricks_wall_side_tall.json c79ae6e97e94d36f2586865ea63f3fab43f8ccbc assets/create/models/block/cut_deepslate_slab.json 5978b93805ccf0bdd953938b34a8dd0ffdcf5565 assets/create/models/block/cut_deepslate_slab_top.json 06a508b2395c3f738d2c5651f366792ee9b9c5ec assets/create/models/block/cut_deepslate_stairs.json @@ -873,15 +873,15 @@ c2850e9f223c459ba53d575a1ef8231589c48c0b assets/create/models/block/cut_deepslat e901746d3e50fe7d9b79d268f4d02251d5cf95f4 assets/create/models/block/cut_deepslate_wall_side.json 1ef794aab31a10bf150a0015cd46e5b5f3c70042 assets/create/models/block/cut_deepslate_wall_side_tall.json 4abb502ea3f6764797641f55a2c48f4858be1ba6 assets/create/models/block/cut_diorite.json -e97babf115a4f81f8555994aba435cf76bebf7a3 assets/create/models/block/cut_diorite_bricks.json -4f7cf44e4d6431587266a4fac78c0812e99d780c assets/create/models/block/cut_diorite_bricks_wall_post.json -1f96f9e190d8e28496ce2db5712f33e449215985 assets/create/models/block/cut_diorite_bricks_wall_side.json -45246192d9cd39837b426e425fc5082422642b65 assets/create/models/block/cut_diorite_bricks_wall_side_tall.json ab61b1b94946f315006a29113f594c234d796bee assets/create/models/block/cut_diorite_brick_slab.json 73597772386c6bbd38907cbea8db816f174a9f8f assets/create/models/block/cut_diorite_brick_slab_top.json c9fbd953ef0789a0e9a915d5f283fd09a76784d6 assets/create/models/block/cut_diorite_brick_stairs.json 5d721f1b3f4376a91707b56950a1f9635adbe603 assets/create/models/block/cut_diorite_brick_stairs_inner.json 9a446bf02732e1873fa96d7745fced0fa04d48d6 assets/create/models/block/cut_diorite_brick_stairs_outer.json +e97babf115a4f81f8555994aba435cf76bebf7a3 assets/create/models/block/cut_diorite_bricks.json +4f7cf44e4d6431587266a4fac78c0812e99d780c assets/create/models/block/cut_diorite_bricks_wall_post.json +1f96f9e190d8e28496ce2db5712f33e449215985 assets/create/models/block/cut_diorite_bricks_wall_side.json +45246192d9cd39837b426e425fc5082422642b65 assets/create/models/block/cut_diorite_bricks_wall_side_tall.json 15195975e7e0ffb7010591b957a657f492e6d59d assets/create/models/block/cut_diorite_slab.json 01c320637843dc0d8b74b48b8d6946cd663d51f6 assets/create/models/block/cut_diorite_slab_top.json 7dcbfe4dc2ec62345da660ecc6ca44056fcd64e7 assets/create/models/block/cut_diorite_stairs.json @@ -891,15 +891,15 @@ c9fbd953ef0789a0e9a915d5f283fd09a76784d6 assets/create/models/block/cut_diorite_ 29075eaaba51ba158f030c2a9583ed5ba52379c8 assets/create/models/block/cut_diorite_wall_side.json 1fb50473359147c7147ea85bc1907e6015ce06bc assets/create/models/block/cut_diorite_wall_side_tall.json 59ee053a884bc9731b4d1b01ae22e0e2b5916cfb assets/create/models/block/cut_dripstone.json -6a4b26a117f58d0187b2cc0c5b117ef71d03d4e9 assets/create/models/block/cut_dripstone_bricks.json -0bb1fa8fb9698dae61096483a01b41bf829666b0 assets/create/models/block/cut_dripstone_bricks_wall_post.json -2019fdc38b401bac72e8344d118d85049ec3efb9 assets/create/models/block/cut_dripstone_bricks_wall_side.json -ebb790b2b6f47d40c92c9bba680e82cb8f054fa9 assets/create/models/block/cut_dripstone_bricks_wall_side_tall.json 84d714b29dcb7eb95a82de8d48491413e26d5fa8 assets/create/models/block/cut_dripstone_brick_slab.json 28b0b1a641d11f8ade57c444e4c1bfd9d617f66a assets/create/models/block/cut_dripstone_brick_slab_top.json 05900c156a6341c12b366790c7e8d15e59a873f0 assets/create/models/block/cut_dripstone_brick_stairs.json 35fb2c83dc89b96951c69253f7502f78c903a9b8 assets/create/models/block/cut_dripstone_brick_stairs_inner.json f69244c1706c95aaadd32d45a24c91ce0848509f assets/create/models/block/cut_dripstone_brick_stairs_outer.json +6a4b26a117f58d0187b2cc0c5b117ef71d03d4e9 assets/create/models/block/cut_dripstone_bricks.json +0bb1fa8fb9698dae61096483a01b41bf829666b0 assets/create/models/block/cut_dripstone_bricks_wall_post.json +2019fdc38b401bac72e8344d118d85049ec3efb9 assets/create/models/block/cut_dripstone_bricks_wall_side.json +ebb790b2b6f47d40c92c9bba680e82cb8f054fa9 assets/create/models/block/cut_dripstone_bricks_wall_side_tall.json 9e42cf588f57de5166f2a2ccdae656743c8b9481 assets/create/models/block/cut_dripstone_slab.json 0da2f782d8ad8fecd81b98c72db182b817bf19eb assets/create/models/block/cut_dripstone_slab_top.json b3c903a1edcd1786ea51a2ccdad5734a1d04ea98 assets/create/models/block/cut_dripstone_stairs.json @@ -909,15 +909,15 @@ b3c903a1edcd1786ea51a2ccdad5734a1d04ea98 assets/create/models/block/cut_dripston 7fab5102d7fa4cd824b9393425639d05727b2ad2 assets/create/models/block/cut_dripstone_wall_side.json c41514cda1c9f5d942d222cbc5f6e620e367afc6 assets/create/models/block/cut_dripstone_wall_side_tall.json dff602c8d2fcd1ceca79f90ae15dbdfbd6cb157d assets/create/models/block/cut_granite.json -31c5299a42f82992e50f711e1e33549c373bd034 assets/create/models/block/cut_granite_bricks.json -ef5a851e57cc4b9c0e625176b1256441e1c17c66 assets/create/models/block/cut_granite_bricks_wall_post.json -815e8dc551c3e813b0b2af29df23a28860de0b53 assets/create/models/block/cut_granite_bricks_wall_side.json -ba241f9c82e27dd98ba6f4e4180922388ab5d1a3 assets/create/models/block/cut_granite_bricks_wall_side_tall.json 9e00dc8fcee23548c0cebda6eadbcfc559e4c20b assets/create/models/block/cut_granite_brick_slab.json 5ad061096451f74e773c3030f96d59424aa93314 assets/create/models/block/cut_granite_brick_slab_top.json 94f8ce607aae5c04ccf9e56f177f9d69203ae879 assets/create/models/block/cut_granite_brick_stairs.json 11d511844fec3bfd05cac8b788332f2decd53021 assets/create/models/block/cut_granite_brick_stairs_inner.json 418eb6a2b52e748a26c2d1914c6c1de94106589f assets/create/models/block/cut_granite_brick_stairs_outer.json +31c5299a42f82992e50f711e1e33549c373bd034 assets/create/models/block/cut_granite_bricks.json +ef5a851e57cc4b9c0e625176b1256441e1c17c66 assets/create/models/block/cut_granite_bricks_wall_post.json +815e8dc551c3e813b0b2af29df23a28860de0b53 assets/create/models/block/cut_granite_bricks_wall_side.json +ba241f9c82e27dd98ba6f4e4180922388ab5d1a3 assets/create/models/block/cut_granite_bricks_wall_side_tall.json 81be5e86cbdaec4945d3ccaf6d376f69c49f40d6 assets/create/models/block/cut_granite_slab.json f72a14e7cf3dd7d93b4462a3bee49683353dfb57 assets/create/models/block/cut_granite_slab_top.json 33bf924f01aae3a7720475f4b32b3a637e69ee36 assets/create/models/block/cut_granite_stairs.json @@ -927,15 +927,15 @@ fb4969e562ad2039d3bad2dc57a6845d3243d453 assets/create/models/block/cut_granite_ 2972b40134bcb15950a0118306f0251ff5e377b7 assets/create/models/block/cut_granite_wall_side.json abbe71fd17dbb5f176553db2f6edf2f1f7d8974a assets/create/models/block/cut_granite_wall_side_tall.json 019d3c4ffb39e328b5458aee44fee90e0ecbd829 assets/create/models/block/cut_limestone.json -7eae0f9766506f713933bde9f301d2f7f2bbef13 assets/create/models/block/cut_limestone_bricks.json -817e8cf8956af36c70e4b4e30b5d141086d006dd assets/create/models/block/cut_limestone_bricks_wall_post.json -1291cacff1b0980e58b5702a84c9b87ac5ef835d assets/create/models/block/cut_limestone_bricks_wall_side.json -6c9bc8803fe17ac623bde56f85683dd2ff13c33e assets/create/models/block/cut_limestone_bricks_wall_side_tall.json c93f33ba39c62b10dfb94c6e1c339cd4fbebffae assets/create/models/block/cut_limestone_brick_slab.json b12a340897ba98ed732a91dbd4129db7a7188e68 assets/create/models/block/cut_limestone_brick_slab_top.json 3e90b32d95ad1cf7b8a16dae3c16724510d41490 assets/create/models/block/cut_limestone_brick_stairs.json b2e7311667d14b2aa8c00e207f69f76207226567 assets/create/models/block/cut_limestone_brick_stairs_inner.json aac619ec1fb8aa56f1752ad3f354f9cb128771f8 assets/create/models/block/cut_limestone_brick_stairs_outer.json +7eae0f9766506f713933bde9f301d2f7f2bbef13 assets/create/models/block/cut_limestone_bricks.json +817e8cf8956af36c70e4b4e30b5d141086d006dd assets/create/models/block/cut_limestone_bricks_wall_post.json +1291cacff1b0980e58b5702a84c9b87ac5ef835d assets/create/models/block/cut_limestone_bricks_wall_side.json +6c9bc8803fe17ac623bde56f85683dd2ff13c33e assets/create/models/block/cut_limestone_bricks_wall_side_tall.json adc21af1c07edaf0573cfd2c95ebe38e50f7282c assets/create/models/block/cut_limestone_slab.json 2d1ea8fc5c8ce5549c7f7888371b6612bf0f5301 assets/create/models/block/cut_limestone_slab_top.json c1416808a2178996be75e0a9c1cd45849fcd6646 assets/create/models/block/cut_limestone_stairs.json @@ -945,15 +945,15 @@ c1416808a2178996be75e0a9c1cd45849fcd6646 assets/create/models/block/cut_limeston 2b5e65e662069a5c59e702224778dd407f5d11dd assets/create/models/block/cut_limestone_wall_side.json 052f130fef646242acccbbed2b510add21e18921 assets/create/models/block/cut_limestone_wall_side_tall.json 66cb6054821d45a60ae4d4d1d904dbef0b9f7c0f assets/create/models/block/cut_ochrum.json -0a7e38e3ac32352c5b3ec56a8c26212dbbb637a3 assets/create/models/block/cut_ochrum_bricks.json -47d0c58dd190f1ea894a5ca40ea7efd54a845d3e assets/create/models/block/cut_ochrum_bricks_wall_post.json -b502b5b213996bce0a626d86414045c80921511e assets/create/models/block/cut_ochrum_bricks_wall_side.json -c3f27545b3b7654c3e7a2df6b482d1a9895ccae9 assets/create/models/block/cut_ochrum_bricks_wall_side_tall.json ce16ec490ae8a33671502804e0b45fc42b6f228f assets/create/models/block/cut_ochrum_brick_slab.json fcbee94fdbd96b0b3d4aa245c6c87443abd1de90 assets/create/models/block/cut_ochrum_brick_slab_top.json 827349ed3eb05f5fe700e8f5816bcd82d0347612 assets/create/models/block/cut_ochrum_brick_stairs.json aa81d4135400eb40f891f8c41fcf7fa516ef64f1 assets/create/models/block/cut_ochrum_brick_stairs_inner.json ecd7e1cb9cae717e35eeb58dbe482833e98f5ac0 assets/create/models/block/cut_ochrum_brick_stairs_outer.json +0a7e38e3ac32352c5b3ec56a8c26212dbbb637a3 assets/create/models/block/cut_ochrum_bricks.json +47d0c58dd190f1ea894a5ca40ea7efd54a845d3e assets/create/models/block/cut_ochrum_bricks_wall_post.json +b502b5b213996bce0a626d86414045c80921511e assets/create/models/block/cut_ochrum_bricks_wall_side.json +c3f27545b3b7654c3e7a2df6b482d1a9895ccae9 assets/create/models/block/cut_ochrum_bricks_wall_side_tall.json e23998f88eb77826f5e4d58f3f4bb41a2e09ea97 assets/create/models/block/cut_ochrum_slab.json cd14f1abe3d0c65fbdd052f4a8e0b8fc2a15ad0e assets/create/models/block/cut_ochrum_slab_top.json a751feb4b609df141f971e341b204e76379dcda7 assets/create/models/block/cut_ochrum_stairs.json @@ -963,15 +963,15 @@ bed6843e39e7e771f6de151dfab0586d3ebad58c assets/create/models/block/cut_ochrum_s df267fb690642cac139aaabefa9eab802f13ddc1 assets/create/models/block/cut_ochrum_wall_side.json ed363b80cc61cb4d0b6fad9da855a0543ecaccc9 assets/create/models/block/cut_ochrum_wall_side_tall.json a65a54a08d9cc3b45e2320482dc2d9e317dd4f3d assets/create/models/block/cut_scorchia.json -9c93a554ab680d7c98c648c16472b52cc2646c50 assets/create/models/block/cut_scorchia_bricks.json -615dc444bb677caa774a4e95686ac24ebe4ec6dc assets/create/models/block/cut_scorchia_bricks_wall_post.json -758a2ad6677f857fbe955c26853eadc7150c105a assets/create/models/block/cut_scorchia_bricks_wall_side.json -f918dfa0751589d18a3eb054c290f669b5c61308 assets/create/models/block/cut_scorchia_bricks_wall_side_tall.json a032cf0a77e4f416ed153b1ffa834c065a73b2ae assets/create/models/block/cut_scorchia_brick_slab.json 716fc6ef58c240b3e6b45acf08d6e1472fe38e7c assets/create/models/block/cut_scorchia_brick_slab_top.json b2870e5ba7c5d5053b3639bf0aa1771ee050810b assets/create/models/block/cut_scorchia_brick_stairs.json 3e8a815eabd1991039a8ad18cedc9c57f46cd097 assets/create/models/block/cut_scorchia_brick_stairs_inner.json 0a9dc3149e7219a70642c242cd86dce5ba5cf4cc assets/create/models/block/cut_scorchia_brick_stairs_outer.json +9c93a554ab680d7c98c648c16472b52cc2646c50 assets/create/models/block/cut_scorchia_bricks.json +615dc444bb677caa774a4e95686ac24ebe4ec6dc assets/create/models/block/cut_scorchia_bricks_wall_post.json +758a2ad6677f857fbe955c26853eadc7150c105a assets/create/models/block/cut_scorchia_bricks_wall_side.json +f918dfa0751589d18a3eb054c290f669b5c61308 assets/create/models/block/cut_scorchia_bricks_wall_side_tall.json a85c4d0467c6746a8ef9c6ac0167d3e16f307d4e assets/create/models/block/cut_scorchia_slab.json 23fd6c65ea83f7ca7ef67dd7faf902c4fa662d70 assets/create/models/block/cut_scorchia_slab_top.json e42329f6fa3aeb958d2349a5442856e9473dc6b5 assets/create/models/block/cut_scorchia_stairs.json @@ -981,15 +981,15 @@ b9a911675861fee414f82c745399a7707c258f77 assets/create/models/block/cut_scorchia e61af066960897d50dc7f7bc17f95baa962829bd assets/create/models/block/cut_scorchia_wall_side.json 846f84efddca7d51b58ebe5e3bbed78312fb052d assets/create/models/block/cut_scorchia_wall_side_tall.json ce9dcf5b7fe58a97fab832fb98b4f5b6d3778255 assets/create/models/block/cut_scoria.json -fa3ef2bb65299c985b70f6959421e243a9ebc6d8 assets/create/models/block/cut_scoria_bricks.json -24ea1a30f68a918e6737dc8d9babe4528af5716a assets/create/models/block/cut_scoria_bricks_wall_post.json -ba7ae110d51fe510566ab42f5ead299b4409f2b7 assets/create/models/block/cut_scoria_bricks_wall_side.json -f04d12bc4e0b939bb443abcc6eb808e66c352c66 assets/create/models/block/cut_scoria_bricks_wall_side_tall.json edf04cbfb19b6ce99c1b74a71d40cd40c8120551 assets/create/models/block/cut_scoria_brick_slab.json f05725fd6d2764b277f01985d0e2fcbd3bf4a41e assets/create/models/block/cut_scoria_brick_slab_top.json 4bccbaef9dd9a8322087d3feb973e14d740ff27a assets/create/models/block/cut_scoria_brick_stairs.json 13f3b55dfdd97e68a6d525166618477e5bcb336d assets/create/models/block/cut_scoria_brick_stairs_inner.json 465862fb20542cae723fd72818be73aec05dad60 assets/create/models/block/cut_scoria_brick_stairs_outer.json +fa3ef2bb65299c985b70f6959421e243a9ebc6d8 assets/create/models/block/cut_scoria_bricks.json +24ea1a30f68a918e6737dc8d9babe4528af5716a assets/create/models/block/cut_scoria_bricks_wall_post.json +ba7ae110d51fe510566ab42f5ead299b4409f2b7 assets/create/models/block/cut_scoria_bricks_wall_side.json +f04d12bc4e0b939bb443abcc6eb808e66c352c66 assets/create/models/block/cut_scoria_bricks_wall_side_tall.json aeef239ca6b0eee527f75091d11d4a947740416d assets/create/models/block/cut_scoria_slab.json 5dfda9fa8117d35ebc324a5c9cb026e206e3b936 assets/create/models/block/cut_scoria_slab_top.json dfe8dbdb6deca69d847ee46fedfefe2da98dc329 assets/create/models/block/cut_scoria_stairs.json @@ -999,15 +999,15 @@ e0b2a94ff4b3f1c1e4282c9c8eecf2583bd7c68e assets/create/models/block/cut_scoria_w cf18e3fde94e3ba611f430fe527a9042a57e6936 assets/create/models/block/cut_scoria_wall_side.json 92475d7758b2bf582c585c2aafa6510f330c6f45 assets/create/models/block/cut_scoria_wall_side_tall.json 9f6543d21d9c24a429aae00511e6dbf61caf8030 assets/create/models/block/cut_tuff.json -8b3d9fe37ab7fda79ea4d90f674c525350883ba0 assets/create/models/block/cut_tuff_bricks.json -6b80481e15ff3d6eb40a42128da883c2027e0074 assets/create/models/block/cut_tuff_bricks_wall_post.json -057a34015b49565cb9858a2eea995a446ac0cfd4 assets/create/models/block/cut_tuff_bricks_wall_side.json -9f20bd04ef163076db9a8bf83c20cc802b57ae60 assets/create/models/block/cut_tuff_bricks_wall_side_tall.json 8c16599fda76c38978a2faa14f842a68fbbe4b9c assets/create/models/block/cut_tuff_brick_slab.json 696036e5900bdbb366dd49f5df71a1e701fd8ee3 assets/create/models/block/cut_tuff_brick_slab_top.json 54d4603e36be86e88d9302d61eab81e76cac1bbc assets/create/models/block/cut_tuff_brick_stairs.json 0ebb41a1ce5bf4ca86cbaf95e83cd2edf8f309ea assets/create/models/block/cut_tuff_brick_stairs_inner.json 5d5ed291db4b4bca464717c7fcde682b33d71c3f assets/create/models/block/cut_tuff_brick_stairs_outer.json +8b3d9fe37ab7fda79ea4d90f674c525350883ba0 assets/create/models/block/cut_tuff_bricks.json +6b80481e15ff3d6eb40a42128da883c2027e0074 assets/create/models/block/cut_tuff_bricks_wall_post.json +057a34015b49565cb9858a2eea995a446ac0cfd4 assets/create/models/block/cut_tuff_bricks_wall_side.json +9f20bd04ef163076db9a8bf83c20cc802b57ae60 assets/create/models/block/cut_tuff_bricks_wall_side_tall.json f2a904b7943555e8ec9dcc07513ca1ad9af809c3 assets/create/models/block/cut_tuff_slab.json ea74bb8a69f6acbd520ac8922e147495e5f99f6f assets/create/models/block/cut_tuff_slab_top.json 0262700e59de947907a04fdea9974f9d7e5a22f2 assets/create/models/block/cut_tuff_stairs.json @@ -1017,15 +1017,15 @@ ea74bb8a69f6acbd520ac8922e147495e5f99f6f assets/create/models/block/cut_tuff_sla 8c6492dc9e09359e5bac67ae4d473cffc8f93dbb assets/create/models/block/cut_tuff_wall_side.json f5f24066b6281303f52e25745881d5bca8c49c54 assets/create/models/block/cut_tuff_wall_side_tall.json 167e9a084987bcf7f67f655d0de88ae8ca2fcebb assets/create/models/block/cut_veridium.json -f8ab87c34f211a63525f6d386397face67460f8c assets/create/models/block/cut_veridium_bricks.json -e4e717fa8412032e184aebd1186470f41a2089c0 assets/create/models/block/cut_veridium_bricks_wall_post.json -8c40ccb8f10ef8dcda1bef46ad3490f697d178d2 assets/create/models/block/cut_veridium_bricks_wall_side.json -2c4671c66d904e15883ec3a14681b97ac537135c assets/create/models/block/cut_veridium_bricks_wall_side_tall.json 07c330c501375d5c316677edee80fb040c0fc237 assets/create/models/block/cut_veridium_brick_slab.json 4c8c660afe72e8ce9eaef53a37fdc63eb0c69513 assets/create/models/block/cut_veridium_brick_slab_top.json f802e4ae758e2c37c3129594ce4f5d9ffcfe173d assets/create/models/block/cut_veridium_brick_stairs.json 0d60d5cd0269e05816d28fcbbd2c680fe60cd316 assets/create/models/block/cut_veridium_brick_stairs_inner.json 22656f90b55aeaeeffa448b5f061fb26b5de7b0f assets/create/models/block/cut_veridium_brick_stairs_outer.json +f8ab87c34f211a63525f6d386397face67460f8c assets/create/models/block/cut_veridium_bricks.json +e4e717fa8412032e184aebd1186470f41a2089c0 assets/create/models/block/cut_veridium_bricks_wall_post.json +8c40ccb8f10ef8dcda1bef46ad3490f697d178d2 assets/create/models/block/cut_veridium_bricks_wall_side.json +2c4671c66d904e15883ec3a14681b97ac537135c assets/create/models/block/cut_veridium_bricks_wall_side_tall.json d736230e9b49a9fd40bc8f31df4d5144cdb429c8 assets/create/models/block/cut_veridium_slab.json 750e536c7b71dfb3a005d9b7a128ac435461e57f assets/create/models/block/cut_veridium_slab_top.json 8b05c19560e97ce15a66202717e3d32f6ee153a9 assets/create/models/block/cut_veridium_stairs.json @@ -1052,22 +1052,25 @@ db89bc32d0e466bc5008aa7091c682ba3aeec611 assets/create/models/block/diorite_pill a21387ab955f2b91e402b2189145f5fd6623592d assets/create/models/block/diorite_pillar_horizontal.json 44af455badc2b35a763007bba3537bda7d0ac289 assets/create/models/block/dripstone_pillar.json 1e23e3758e3311d0063c83742abb750a05021075 assets/create/models/block/dripstone_pillar_horizontal.json -19a773f91c58c49301f35965bac02d0c05fb2764 assets/create/models/block/exposed_copper_shingles.json a3420b91fdebec40e508a5eebb145c0201bd80c8 assets/create/models/block/exposed_copper_shingle_slab.json 4178ea5e50ee17b3c15f4a59efd019c4a19bb892 assets/create/models/block/exposed_copper_shingle_slab_top.json dd2d747774abc86e428a883e299db66cded78e11 assets/create/models/block/exposed_copper_shingle_stairs.json b6845da62d96a33cee624bb70360e256b26eda83 assets/create/models/block/exposed_copper_shingle_stairs_inner.json 3d8b758e50e75c5adc26ab6f39f9d73f00866673 assets/create/models/block/exposed_copper_shingle_stairs_outer.json -9cb20c9d41629d8b9426cb65829365d10966338f assets/create/models/block/exposed_copper_tiles.json +19a773f91c58c49301f35965bac02d0c05fb2764 assets/create/models/block/exposed_copper_shingles.json cd21d9d2935b6d0103502e2731c11ea27ff64ecf assets/create/models/block/exposed_copper_tile_slab.json 0ec039ba59fb0028183433e52131ff355ace5bff assets/create/models/block/exposed_copper_tile_slab_top.json c51dbd34996ac4513234800e427ac308067d5e1d assets/create/models/block/exposed_copper_tile_stairs.json 68772d4352dc7ade995dfa57ba41a38ef819e855 assets/create/models/block/exposed_copper_tile_stairs_inner.json d932671822ba93b71a9c8b50e7207803a1c4dbab assets/create/models/block/exposed_copper_tile_stairs_outer.json +9cb20c9d41629d8b9426cb65829365d10966338f assets/create/models/block/exposed_copper_tiles.json 2d1ade82820569936fd3021a877283474ced09d0 assets/create/models/block/fake_track.json 9e41f0b90dd1e71766c9d07bdb75d1e553f3392f assets/create/models/block/fluid_pipe/d_x.json 13507730f6ca6462c4cfeddc46e5b21e93fb1287 assets/create/models/block/fluid_pipe/d_y.json 84c09934d3537343a1226389993dabfa850b745e assets/create/models/block/fluid_pipe/d_z.json +b8fd54e514bd50fb287c6b758647818c6b08ef75 assets/create/models/block/fluid_pipe/l_x.json +e985ff9dbe7324cf69ab38e6e9e85c9b554af56c assets/create/models/block/fluid_pipe/l_y.json +e24957d63bac1e754fcc1647a4a86337a67f6298 assets/create/models/block/fluid_pipe/l_z.json eacc5ee5f164ccc7c13cfbbd37a92b401222debe assets/create/models/block/fluid_pipe/ld_x.json 33fc0ecce85fae051c54d5a538793d7081238894 assets/create/models/block/fluid_pipe/ld_y.json 638f1a259cabed1f8d63c6fdaa6d4d4dff539e7d assets/create/models/block/fluid_pipe/ld_z.json @@ -1077,24 +1080,21 @@ c52521cd566294c797312104284ddd343fad9c2e assets/create/models/block/fluid_pipe/l 99637310d3ca1ccfbe62b03aa9b0d82a0cf6f724 assets/create/models/block/fluid_pipe/lu_x.json 986800d441e95553464d1869d39baf456f5d70dc assets/create/models/block/fluid_pipe/lu_y.json 11dcf7d2dcd0df9b043035cb072deee96ab9e6da assets/create/models/block/fluid_pipe/lu_z.json -b8fd54e514bd50fb287c6b758647818c6b08ef75 assets/create/models/block/fluid_pipe/l_x.json -e985ff9dbe7324cf69ab38e6e9e85c9b554af56c assets/create/models/block/fluid_pipe/l_y.json -e24957d63bac1e754fcc1647a4a86337a67f6298 assets/create/models/block/fluid_pipe/l_z.json +d44ff2aed71039a7d0ff913d0d9e8398e1318f39 assets/create/models/block/fluid_pipe/r_x.json +92d4044b51a90da0b2277b0613c7ca0bb80c66fe assets/create/models/block/fluid_pipe/r_y.json +fb9a23de00ef4edb4f7e24fb60de345cd12e513f assets/create/models/block/fluid_pipe/r_z.json bde9ec36b86113a6ca7a51a4f405994460a2eb56 assets/create/models/block/fluid_pipe/rd_x.json bd325f5b37ff08328ddddeeceac1a41be586d20a assets/create/models/block/fluid_pipe/rd_y.json 28f351fd215af3a991ccd9aa05c57b9cd9e6f58d assets/create/models/block/fluid_pipe/rd_z.json 1ff3ea321aeacca70709eb76370c11c7f13163b6 assets/create/models/block/fluid_pipe/ru_x.json 95bc5342fd3909981430c2e13ef98cdbd8f02709 assets/create/models/block/fluid_pipe/ru_y.json e1fc0d1297a83749ac55f51c9cf33ff2ecc9fdc2 assets/create/models/block/fluid_pipe/ru_z.json -d44ff2aed71039a7d0ff913d0d9e8398e1318f39 assets/create/models/block/fluid_pipe/r_x.json -92d4044b51a90da0b2277b0613c7ca0bb80c66fe assets/create/models/block/fluid_pipe/r_y.json -fb9a23de00ef4edb4f7e24fb60de345cd12e513f assets/create/models/block/fluid_pipe/r_z.json -65a41f4b680af197776e03cae6f1815b6d04def2 assets/create/models/block/fluid_pipe/ud_x.json -26398801d89889ffe17b6513b786d27707f6a480 assets/create/models/block/fluid_pipe/ud_y.json -07747cc2b936e1b326bae7ac32a8a5ba77fdffa9 assets/create/models/block/fluid_pipe/ud_z.json 4e3debb2ba60398a0730866f781e0455f4316610 assets/create/models/block/fluid_pipe/u_x.json 0f98b30ba09706b8a5ee09aeef912b39acea0216 assets/create/models/block/fluid_pipe/u_y.json 83bf9b1af633c319c051055170debff4cc3508c0 assets/create/models/block/fluid_pipe/u_z.json +65a41f4b680af197776e03cae6f1815b6d04def2 assets/create/models/block/fluid_pipe/ud_x.json +26398801d89889ffe17b6513b786d27707f6a480 assets/create/models/block/fluid_pipe/ud_y.json +07747cc2b936e1b326bae7ac32a8a5ba77fdffa9 assets/create/models/block/fluid_pipe/ud_z.json 5f70af15ec2569c68a17d31024c7a37cb5c68c7e assets/create/models/block/framed_glass.json f0100e1d44146b256998fbd2af05da80d147e8d9 assets/create/models/block/framed_glass_pane_noside.json 4a032c6ae3f459e3349c2a2218da186170c31e03 assets/create/models/block/framed_glass_pane_noside_alt.json @@ -1167,14 +1167,14 @@ bcd3d28b8a062649301648ea5e2d0463f93d008d assets/create/models/block/light_blue_v d1813d0f548fcddb361df7cc3b5d97582842b10f assets/create/models/block/light_gray_seat.json 4ec5d701dd8b2d8c3dc44d05f527a3d737002cd4 assets/create/models/block/light_gray_toolbox.json adb8dbed70419e0310e7a20f3656bf325b348434 assets/create/models/block/light_gray_valve_handle.json -8f53caad3899a30be5087a0ba155080834418cc0 assets/create/models/block/limestone.json -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 5a95a72444f523cfba6e8c5adf8eacbb37e2d21e assets/create/models/block/lime_sail.json 09e7bf50cf88c449dbd9e77829cdb5afffb7d88d assets/create/models/block/lime_seat.json b92822a01e4fbed2463b1bdf7dcc736023988e20 assets/create/models/block/lime_toolbox.json 802b47f34b1053b7af980b08b6511f468e7dd7c1 assets/create/models/block/lime_valve_handle.json +8f53caad3899a30be5087a0ba155080834418cc0 assets/create/models/block/limestone.json +2b80f9421c2fe902d55d9bd95183ad4bae46c315 assets/create/models/block/limestone_pillar.json +fb18280a2a708f60b00cc7c675804c219784871a assets/create/models/block/limestone_pillar_horizontal.json 84b9ac6eafdbd037f3ff558c250a8b8952415af1 assets/create/models/block/linear_chassis.json 29ee936c09c1222c6a144e5bb39577b5a9cd28bf assets/create/models/block/linear_chassis_bottom.json a1a3804ddcb1db0a7b5c0693555f8eb326950dd0 assets/create/models/block/linear_chassis_top.json @@ -1214,18 +1214,18 @@ f9010894858512398bddd5d31b922e12594d2e3c assets/create/models/block/ornate_iron_ 92637fbd6bf54891411b32a494064b9a48e59411 assets/create/models/block/ornate_iron_window_pane_post.json 8416d497e7fc8ca4f9f4c608ccc0651036850256 assets/create/models/block/ornate_iron_window_pane_side.json 1cdaa9d4bd23f7b1eb14672dc9322d9dad966502 assets/create/models/block/ornate_iron_window_pane_side_alt.json -561beafce41b9e9c0b07bc6b7176dd4f6918c116 assets/create/models/block/oxidized_copper_shingles.json 7e0bab8109e322c6db5fe1d5999c06536c21c6eb assets/create/models/block/oxidized_copper_shingle_slab.json 42df32c4e2d1ffb2ee62748becfd1717118b440c assets/create/models/block/oxidized_copper_shingle_slab_top.json b55a733e3e68cfbd08d45bb9ac56deef9f728b60 assets/create/models/block/oxidized_copper_shingle_stairs.json 7b8745213af5aa7938fc04a295be6a087c72daa8 assets/create/models/block/oxidized_copper_shingle_stairs_inner.json d89419d48d6ee2f6747e7c93de8699db22ea3f59 assets/create/models/block/oxidized_copper_shingle_stairs_outer.json -5cf92b628ff1f832966138a58ed87d747681274c assets/create/models/block/oxidized_copper_tiles.json +561beafce41b9e9c0b07bc6b7176dd4f6918c116 assets/create/models/block/oxidized_copper_shingles.json ad6134598869711a12e2f95c9b5f25a0f7b8dd93 assets/create/models/block/oxidized_copper_tile_slab.json c17bac0fd6a20540813c6a1c000a553b7c5ac849 assets/create/models/block/oxidized_copper_tile_slab_top.json d5b30340364f5536e46bc67e777ef4fa20a36e04 assets/create/models/block/oxidized_copper_tile_stairs.json b40b315c23cbd3eb4658518bfac836f6091321a5 assets/create/models/block/oxidized_copper_tile_stairs_inner.json f4eaadab29b4f2e915237340e2d6f4aad4ba21d6 assets/create/models/block/oxidized_copper_tile_stairs_outer.json +5cf92b628ff1f832966138a58ed87d747681274c assets/create/models/block/oxidized_copper_tiles.json f8b51eec36c2eddc08a1b60894d863bb58f55625 assets/create/models/block/peculiar_bell_ceiling.json f70f83cfec770879c478eea3760ea187700f2878 assets/create/models/block/peculiar_bell_double_wall.json b9c9d00b844ca2f217ae21cc502cd4d082fed2d5 assets/create/models/block/peculiar_bell_floor.json @@ -1420,133 +1420,133 @@ ff52eb59dadfe675e416440f3115856a501428a6 assets/create/models/block/scoria.json 4d7d36f974d25a310db2f75800e8c7e0377881c6 assets/create/models/block/secondary_linear_chassis_top.json 5ecb821ac06873015d2d7ebcfb7e1f5fe85cf504 assets/create/models/block/secondary_linear_chassis_top_bottom.json e697898a0ec4c308314a4e0b7235fa0a9229da45 assets/create/models/block/shadow_steel_casing.json -73edb947b52c73e85a83422853d0b8a0fb34e82b assets/create/models/block/small_andesite_bricks.json -3bb5c8413b9e81a1adc339f873f37eb656904e06 assets/create/models/block/small_andesite_bricks_wall_post.json -0e70d94fc6ffdc0fd4a50a5910bc1455b401982f assets/create/models/block/small_andesite_bricks_wall_side.json -597fec784e40c1ff3b622824c32773d6d271f3b7 assets/create/models/block/small_andesite_bricks_wall_side_tall.json 593b962350c8de53156901b308617c6a246afa09 assets/create/models/block/small_andesite_brick_slab.json c83de8118653ccdce92a1b7f3501bf7359e0b310 assets/create/models/block/small_andesite_brick_slab_top.json f019380bcc81d52681e2beaf63e2b11836c45922 assets/create/models/block/small_andesite_brick_stairs.json 4fa72fe0115ad9ec83837852a2b2e2d22dde19ca assets/create/models/block/small_andesite_brick_stairs_inner.json f80f485f62dce86e98815b343c89e96b10623e53 assets/create/models/block/small_andesite_brick_stairs_outer.json -4750724972cbac6d7dac31e0689681eab6c37093 assets/create/models/block/small_asurine_bricks.json -407c7bea509bb0e9bf9f04e947ace584103d012d assets/create/models/block/small_asurine_bricks_wall_post.json -60491dfb4f2a6b78effdf18612b9a1cd7d930d8a assets/create/models/block/small_asurine_bricks_wall_side.json -e5d3172c08b65696a6d72220495463636d8b352c assets/create/models/block/small_asurine_bricks_wall_side_tall.json +73edb947b52c73e85a83422853d0b8a0fb34e82b assets/create/models/block/small_andesite_bricks.json +3bb5c8413b9e81a1adc339f873f37eb656904e06 assets/create/models/block/small_andesite_bricks_wall_post.json +0e70d94fc6ffdc0fd4a50a5910bc1455b401982f assets/create/models/block/small_andesite_bricks_wall_side.json +597fec784e40c1ff3b622824c32773d6d271f3b7 assets/create/models/block/small_andesite_bricks_wall_side_tall.json cdd354726eda82d83dc89871fa587b8c07b02a16 assets/create/models/block/small_asurine_brick_slab.json 7bdb6ed1e74437d083bca7d89c0d1b7c81e80b53 assets/create/models/block/small_asurine_brick_slab_top.json 086b9d4284d343967a582fd0a7d194bafd980e13 assets/create/models/block/small_asurine_brick_stairs.json db69f1580ca405b9a99f0e4ea8d9b9950ed6444e assets/create/models/block/small_asurine_brick_stairs_inner.json dd572cbff713b0f4830aef0bf3ba4adb80ee9908 assets/create/models/block/small_asurine_brick_stairs_outer.json -c2c72734ac526c319cb01e982824680bfb5f1186 assets/create/models/block/small_calcite_bricks.json -f17f2ecd5e5a32f92ec0ad0ba9e861a80432c0f2 assets/create/models/block/small_calcite_bricks_wall_post.json -1ad7654125aff67267567c0007cc03b8a15131b0 assets/create/models/block/small_calcite_bricks_wall_side.json -10c339f64c0e78f4fbb7a95c10bf7f9f399c0c6b assets/create/models/block/small_calcite_bricks_wall_side_tall.json +4750724972cbac6d7dac31e0689681eab6c37093 assets/create/models/block/small_asurine_bricks.json +407c7bea509bb0e9bf9f04e947ace584103d012d assets/create/models/block/small_asurine_bricks_wall_post.json +60491dfb4f2a6b78effdf18612b9a1cd7d930d8a assets/create/models/block/small_asurine_bricks_wall_side.json +e5d3172c08b65696a6d72220495463636d8b352c assets/create/models/block/small_asurine_bricks_wall_side_tall.json d07c57748981a54ffcdadc30ec21f728a3557bea assets/create/models/block/small_calcite_brick_slab.json 9a5e6a93328ad35b256b2512c28e683a74e807a9 assets/create/models/block/small_calcite_brick_slab_top.json c3d39e013dd0142f044f8f0a90de849a0d961e84 assets/create/models/block/small_calcite_brick_stairs.json 4e47a4708dafc0ea476e2d5b6567acfdc2c5c148 assets/create/models/block/small_calcite_brick_stairs_inner.json 6a41c44680a958299a787d8c8c8778d52167cd65 assets/create/models/block/small_calcite_brick_stairs_outer.json -485f6c0e37b24124ff23efa3f0caa2cfe85663dd assets/create/models/block/small_crimsite_bricks.json -57b050751e68c9a881d9598cfe8dfb45f19df08c assets/create/models/block/small_crimsite_bricks_wall_post.json -cb01f90c7ac1f56a6f79e1fecb126c349b6d53b0 assets/create/models/block/small_crimsite_bricks_wall_side.json -80932617b1d4b718071c1f8558398ba881743892 assets/create/models/block/small_crimsite_bricks_wall_side_tall.json +c2c72734ac526c319cb01e982824680bfb5f1186 assets/create/models/block/small_calcite_bricks.json +f17f2ecd5e5a32f92ec0ad0ba9e861a80432c0f2 assets/create/models/block/small_calcite_bricks_wall_post.json +1ad7654125aff67267567c0007cc03b8a15131b0 assets/create/models/block/small_calcite_bricks_wall_side.json +10c339f64c0e78f4fbb7a95c10bf7f9f399c0c6b assets/create/models/block/small_calcite_bricks_wall_side_tall.json 827867ddd9b5f6e2daa916c968531c7183ce7fa2 assets/create/models/block/small_crimsite_brick_slab.json dd19ebdbd1a2de827d467b0abd2d1d3ee5822305 assets/create/models/block/small_crimsite_brick_slab_top.json 58048cb41b740b008a98420ea93b567f38e2910f assets/create/models/block/small_crimsite_brick_stairs.json a943586885ea7d48fc27595d9741f97d852446e7 assets/create/models/block/small_crimsite_brick_stairs_inner.json 8dc173b8a9912341ccb9cd8c9a0d2d893571eb85 assets/create/models/block/small_crimsite_brick_stairs_outer.json -cd855b25c38be2c36dcbf6ab0d963a2c76043171 assets/create/models/block/small_deepslate_bricks.json -88a6c43f64c6d53b34719f41707622635108342b assets/create/models/block/small_deepslate_bricks_wall_post.json -dea1773ca9baf9e1a6a7a4288d348127b858c42d assets/create/models/block/small_deepslate_bricks_wall_side.json -673ab543b38a597fd74285cd25b8004c9e2bd706 assets/create/models/block/small_deepslate_bricks_wall_side_tall.json +485f6c0e37b24124ff23efa3f0caa2cfe85663dd assets/create/models/block/small_crimsite_bricks.json +57b050751e68c9a881d9598cfe8dfb45f19df08c assets/create/models/block/small_crimsite_bricks_wall_post.json +cb01f90c7ac1f56a6f79e1fecb126c349b6d53b0 assets/create/models/block/small_crimsite_bricks_wall_side.json +80932617b1d4b718071c1f8558398ba881743892 assets/create/models/block/small_crimsite_bricks_wall_side_tall.json 67c78a3e9250351d0ea18538640b596f05e957a4 assets/create/models/block/small_deepslate_brick_slab.json bc1af783fbcbe73df05e12c93625035db8089d16 assets/create/models/block/small_deepslate_brick_slab_top.json 91e00675337592d17a04032808ca64c4a159c814 assets/create/models/block/small_deepslate_brick_stairs.json 39e78262242637628628a07dc47908fb1593d3f2 assets/create/models/block/small_deepslate_brick_stairs_inner.json d7a61bc4c84070e0fd53e0957a5282078daff7f1 assets/create/models/block/small_deepslate_brick_stairs_outer.json -73e801fb607d76b42e1862323e9d149910a68298 assets/create/models/block/small_diorite_bricks.json -2bdb593d3ae4d856e96cc877f4927da25841af54 assets/create/models/block/small_diorite_bricks_wall_post.json -dd064be7962a2418784a513725fc7b5835e4ab40 assets/create/models/block/small_diorite_bricks_wall_side.json -3753c64785d74f1997b9f8f856fa873302621f39 assets/create/models/block/small_diorite_bricks_wall_side_tall.json +cd855b25c38be2c36dcbf6ab0d963a2c76043171 assets/create/models/block/small_deepslate_bricks.json +88a6c43f64c6d53b34719f41707622635108342b assets/create/models/block/small_deepslate_bricks_wall_post.json +dea1773ca9baf9e1a6a7a4288d348127b858c42d assets/create/models/block/small_deepslate_bricks_wall_side.json +673ab543b38a597fd74285cd25b8004c9e2bd706 assets/create/models/block/small_deepslate_bricks_wall_side_tall.json 59fc1d9dac0b6867779346413953174fc6b55d3c assets/create/models/block/small_diorite_brick_slab.json cbd6fe711e1203aa746d86d12bb85016b7142749 assets/create/models/block/small_diorite_brick_slab_top.json a6c823fa96ba8a06d101ca96a6898fe8a1faf83e assets/create/models/block/small_diorite_brick_stairs.json 7f128501d989122df9d2ab002a497356831caa1c assets/create/models/block/small_diorite_brick_stairs_inner.json 26222975b0efb2acea6473d0bcc99453aa9ed561 assets/create/models/block/small_diorite_brick_stairs_outer.json -7f55f9c8cae6a79a9ab22a4b593a2c5829390573 assets/create/models/block/small_dripstone_bricks.json -fd0880b2e55435c8dc6945fa71c67ba34d7b1e69 assets/create/models/block/small_dripstone_bricks_wall_post.json -c00e9c0bfb108b70975514694f38d3c4cd63e819 assets/create/models/block/small_dripstone_bricks_wall_side.json -26382c01766e04cfe7ea585cabc1baa1c409e0a0 assets/create/models/block/small_dripstone_bricks_wall_side_tall.json +73e801fb607d76b42e1862323e9d149910a68298 assets/create/models/block/small_diorite_bricks.json +2bdb593d3ae4d856e96cc877f4927da25841af54 assets/create/models/block/small_diorite_bricks_wall_post.json +dd064be7962a2418784a513725fc7b5835e4ab40 assets/create/models/block/small_diorite_bricks_wall_side.json +3753c64785d74f1997b9f8f856fa873302621f39 assets/create/models/block/small_diorite_bricks_wall_side_tall.json 7b18bb56d4509f490a73b2812a8e40333f400369 assets/create/models/block/small_dripstone_brick_slab.json 39b7aa7d1494e5328e8774acb8adec8a346e972f assets/create/models/block/small_dripstone_brick_slab_top.json 3d265aed7a723713d525d0fabf3a70600d9d60e4 assets/create/models/block/small_dripstone_brick_stairs.json 2be41e9c1367af7f0eb99856e35900df96974bd4 assets/create/models/block/small_dripstone_brick_stairs_inner.json 4026a9327d47d55218b00b0b4b92464b6448ad91 assets/create/models/block/small_dripstone_brick_stairs_outer.json -ad4cf29e0e67d0d202d5836486531551909c71bf assets/create/models/block/small_granite_bricks.json -d20963cbb5d2321a069bf42d203855a5584f8607 assets/create/models/block/small_granite_bricks_wall_post.json -b860879b66d2d23349fa95ff644d9eba21eb29bd assets/create/models/block/small_granite_bricks_wall_side.json -11593a2a0e307b3e1d847c84d8c61bc78fef2967 assets/create/models/block/small_granite_bricks_wall_side_tall.json +7f55f9c8cae6a79a9ab22a4b593a2c5829390573 assets/create/models/block/small_dripstone_bricks.json +fd0880b2e55435c8dc6945fa71c67ba34d7b1e69 assets/create/models/block/small_dripstone_bricks_wall_post.json +c00e9c0bfb108b70975514694f38d3c4cd63e819 assets/create/models/block/small_dripstone_bricks_wall_side.json +26382c01766e04cfe7ea585cabc1baa1c409e0a0 assets/create/models/block/small_dripstone_bricks_wall_side_tall.json cb0a72cedb6b2b043eaf8c8869648802d74a2eeb assets/create/models/block/small_granite_brick_slab.json d635840492541787d55cc005c7e207532edcdef3 assets/create/models/block/small_granite_brick_slab_top.json ba9bfedf5854fccaba8a5e60c26efb6e34ede3cd assets/create/models/block/small_granite_brick_stairs.json 9bebe59176e74926e28a139dc557c25283285e89 assets/create/models/block/small_granite_brick_stairs_inner.json 15d71900e76c131285447628e63bf1479ce7025a assets/create/models/block/small_granite_brick_stairs_outer.json -6224f2763224d3e746dafdaaf14fae68e2469b93 assets/create/models/block/small_limestone_bricks.json -ca038e240e4157897a6273692db2c952ab5b17d7 assets/create/models/block/small_limestone_bricks_wall_post.json -7920f8cfda77b22d4d29638faa6ae07d89e51ab3 assets/create/models/block/small_limestone_bricks_wall_side.json -6e1fa27744f4592111945e5cafee6d7d67b5299b assets/create/models/block/small_limestone_bricks_wall_side_tall.json +ad4cf29e0e67d0d202d5836486531551909c71bf assets/create/models/block/small_granite_bricks.json +d20963cbb5d2321a069bf42d203855a5584f8607 assets/create/models/block/small_granite_bricks_wall_post.json +b860879b66d2d23349fa95ff644d9eba21eb29bd assets/create/models/block/small_granite_bricks_wall_side.json +11593a2a0e307b3e1d847c84d8c61bc78fef2967 assets/create/models/block/small_granite_bricks_wall_side_tall.json 0e0f551bac87421e6b693aa9ca98fd5da2ee168b assets/create/models/block/small_limestone_brick_slab.json 6669c1e87ed79097f96e7e46eecf3ab6e7c9778c assets/create/models/block/small_limestone_brick_slab_top.json 5aff0145d2fc89549ac541db325dda25b8941583 assets/create/models/block/small_limestone_brick_stairs.json 250aa2c237a9532b19621fa604027433183961c3 assets/create/models/block/small_limestone_brick_stairs_inner.json 92da57d330e9905d017705dd931af1d1d6c1a00d assets/create/models/block/small_limestone_brick_stairs_outer.json -242e4f39f6df26917f21899f0c7d0415a166d4b9 assets/create/models/block/small_ochrum_bricks.json -06cb9faca0062947c08b2a7309a958aac5ab24ac assets/create/models/block/small_ochrum_bricks_wall_post.json -8d9d53206e222839333026c779b66b9fd8cf2cf9 assets/create/models/block/small_ochrum_bricks_wall_side.json -f412fbaa509f7b2d47a27d4bcb13590bfcae74ca assets/create/models/block/small_ochrum_bricks_wall_side_tall.json +6224f2763224d3e746dafdaaf14fae68e2469b93 assets/create/models/block/small_limestone_bricks.json +ca038e240e4157897a6273692db2c952ab5b17d7 assets/create/models/block/small_limestone_bricks_wall_post.json +7920f8cfda77b22d4d29638faa6ae07d89e51ab3 assets/create/models/block/small_limestone_bricks_wall_side.json +6e1fa27744f4592111945e5cafee6d7d67b5299b assets/create/models/block/small_limestone_bricks_wall_side_tall.json 517e3605a9e86a07c673e18d94c2c37109a2aef5 assets/create/models/block/small_ochrum_brick_slab.json 855ad9f6fe03ceb2cc33d9df3536cb4394acfa9b assets/create/models/block/small_ochrum_brick_slab_top.json c5fc35d6b0fe96c11537bc10d34a63ef80f3270c assets/create/models/block/small_ochrum_brick_stairs.json 9a2631d9f6821d2c01bc8b2588a69702d3b083cc assets/create/models/block/small_ochrum_brick_stairs_inner.json 1f0ccdef29dae18535ea304e954e06c91bb0620b assets/create/models/block/small_ochrum_brick_stairs_outer.json +242e4f39f6df26917f21899f0c7d0415a166d4b9 assets/create/models/block/small_ochrum_bricks.json +06cb9faca0062947c08b2a7309a958aac5ab24ac assets/create/models/block/small_ochrum_bricks_wall_post.json +8d9d53206e222839333026c779b66b9fd8cf2cf9 assets/create/models/block/small_ochrum_bricks_wall_side.json +f412fbaa509f7b2d47a27d4bcb13590bfcae74ca assets/create/models/block/small_ochrum_bricks_wall_side_tall.json be96f070be1f838c6fb442c164b5f9b4e5cfcee5 assets/create/models/block/small_rose_quartz_tiles.json -41e56d8e334b81a0d5270bdbe87617981e1f98b4 assets/create/models/block/small_scorchia_bricks.json -56aa81e05019533ce0e0f1ee3ef7bf20fcc400b4 assets/create/models/block/small_scorchia_bricks_wall_post.json -1e1fa90c8b144813770c4d53a3b734ae450895d6 assets/create/models/block/small_scorchia_bricks_wall_side.json -6a46cf73c03a2abea25a81dbb28f4150b355900c assets/create/models/block/small_scorchia_bricks_wall_side_tall.json 6aa3825ace2e73bec454aaa8597e3a892ee29eb7 assets/create/models/block/small_scorchia_brick_slab.json f0378625001171c449a403e372e59623f0fc6569 assets/create/models/block/small_scorchia_brick_slab_top.json 49fa4a3940f84902319df257d39812eb71c8a9e2 assets/create/models/block/small_scorchia_brick_stairs.json 4dee6e6dbe6a98a8eaa04f6812f322343f62fca1 assets/create/models/block/small_scorchia_brick_stairs_inner.json 8a19e7e5c03c155c9ef9332486ae0b069dea0502 assets/create/models/block/small_scorchia_brick_stairs_outer.json -6b435123d852579ba8467c4915cd5d0adaadeca0 assets/create/models/block/small_scoria_bricks.json -86b243074845ca66916ce96ef3774862cf9a39d4 assets/create/models/block/small_scoria_bricks_wall_post.json -57ccb3efbdc4a69cad60c8b90321338ba2e68321 assets/create/models/block/small_scoria_bricks_wall_side.json -d4c5398e10b25d2dc3cb3754a449fc2b60e4074f assets/create/models/block/small_scoria_bricks_wall_side_tall.json +41e56d8e334b81a0d5270bdbe87617981e1f98b4 assets/create/models/block/small_scorchia_bricks.json +56aa81e05019533ce0e0f1ee3ef7bf20fcc400b4 assets/create/models/block/small_scorchia_bricks_wall_post.json +1e1fa90c8b144813770c4d53a3b734ae450895d6 assets/create/models/block/small_scorchia_bricks_wall_side.json +6a46cf73c03a2abea25a81dbb28f4150b355900c assets/create/models/block/small_scorchia_bricks_wall_side_tall.json 918351c1270c26932c0c4783543779a25ca7e986 assets/create/models/block/small_scoria_brick_slab.json 4138e756b4b36f227e178acbcc233edb082ae603 assets/create/models/block/small_scoria_brick_slab_top.json b8e70cd7d9acdcf91be9783cd91d70275a006ea2 assets/create/models/block/small_scoria_brick_stairs.json 625bfbd58440ea4e270d57cc748f2b5f6cece63b assets/create/models/block/small_scoria_brick_stairs_inner.json 602a46fb2736acb8c50b0d04222e6c33e52dee87 assets/create/models/block/small_scoria_brick_stairs_outer.json -a8e8c633dfb6d9f14425b1fd28e88ecf08a88cc6 assets/create/models/block/small_tuff_bricks.json -1c3a22bed504cd7a7e507e83ee21399f8a3fb299 assets/create/models/block/small_tuff_bricks_wall_post.json -1aeb8cac7d0178a18ac1cf98c9a45ca8e67514b0 assets/create/models/block/small_tuff_bricks_wall_side.json -4c6b5c7c60ec4cad314064b171413a3e866e5f99 assets/create/models/block/small_tuff_bricks_wall_side_tall.json +6b435123d852579ba8467c4915cd5d0adaadeca0 assets/create/models/block/small_scoria_bricks.json +86b243074845ca66916ce96ef3774862cf9a39d4 assets/create/models/block/small_scoria_bricks_wall_post.json +57ccb3efbdc4a69cad60c8b90321338ba2e68321 assets/create/models/block/small_scoria_bricks_wall_side.json +d4c5398e10b25d2dc3cb3754a449fc2b60e4074f assets/create/models/block/small_scoria_bricks_wall_side_tall.json 6b2c4d8c8609de0d3d6ce1e30b1dd26ba59cb86d assets/create/models/block/small_tuff_brick_slab.json 1ba07367fcba6a3914f1703115304a7c19979542 assets/create/models/block/small_tuff_brick_slab_top.json 1a5ab239d0f2f041ee04005ceb60111e6848f5de assets/create/models/block/small_tuff_brick_stairs.json be3ee2c36f85a534a71d42a7d63a7816945b3c30 assets/create/models/block/small_tuff_brick_stairs_inner.json aa84e448041d5f74c75565f5e409b1e9b7e5155d assets/create/models/block/small_tuff_brick_stairs_outer.json -e9c75f1b4b663dce09b0a2f8282e574839c19d06 assets/create/models/block/small_veridium_bricks.json -725f6d3dbcfb469cede6fb27a98c1f398f3f3c8c assets/create/models/block/small_veridium_bricks_wall_post.json -b33ee496d43e315a5bed5eaabfd553e361fec1a9 assets/create/models/block/small_veridium_bricks_wall_side.json -80e950f93def51d82a63848b1fb6ac11600ab1bf assets/create/models/block/small_veridium_bricks_wall_side_tall.json +a8e8c633dfb6d9f14425b1fd28e88ecf08a88cc6 assets/create/models/block/small_tuff_bricks.json +1c3a22bed504cd7a7e507e83ee21399f8a3fb299 assets/create/models/block/small_tuff_bricks_wall_post.json +1aeb8cac7d0178a18ac1cf98c9a45ca8e67514b0 assets/create/models/block/small_tuff_bricks_wall_side.json +4c6b5c7c60ec4cad314064b171413a3e866e5f99 assets/create/models/block/small_tuff_bricks_wall_side_tall.json 30b150fe3cf9bdb6ee32cd6b0f51179b44be57d3 assets/create/models/block/small_veridium_brick_slab.json 2158dd9e71f6f60e5132105c68a41ad6e3927438 assets/create/models/block/small_veridium_brick_slab_top.json bbbfc8e3696945ed1f6c3afe73ae0745ff8deda1 assets/create/models/block/small_veridium_brick_stairs.json fc3a996b0ca01c2c09ad84b881c46e92918d084f assets/create/models/block/small_veridium_brick_stairs_inner.json e27a77984e8e28e6032f26bb010efcadfaeb5407 assets/create/models/block/small_veridium_brick_stairs_outer.json +e9c75f1b4b663dce09b0a2f8282e574839c19d06 assets/create/models/block/small_veridium_bricks.json +725f6d3dbcfb469cede6fb27a98c1f398f3f3c8c assets/create/models/block/small_veridium_bricks_wall_post.json +b33ee496d43e315a5bed5eaabfd553e361fec1a9 assets/create/models/block/small_veridium_bricks_wall_side.json +80e950f93def51d82a63848b1fb6ac11600ab1bf assets/create/models/block/small_veridium_bricks_wall_side_tall.json d7c1c2679c8ba543ae7be3b9cf3f4eea3c1a2f68 assets/create/models/block/spruce_window.json f4a4fbb9eea6fb1d0633e349eae6acdaf329e8d5 assets/create/models/block/spruce_window_pane_noside.json 02a25202a42debcd2b4aaa4113e3de4f8f6ee47c assets/create/models/block/spruce_window_pane_noside_alt.json @@ -1595,66 +1595,66 @@ e84875a4eb11e2161a93ec7569aa2ac1c2f60cef assets/create/models/block/warped_windo 378c865ff8213ff56f1f7a4b2d9cf26c71f036e8 assets/create/models/block/warped_window_pane_post.json f320de08cb113a9ad17acd2ebb8dfc57759e4f7d assets/create/models/block/warped_window_pane_side.json 2fc182d9697b5cddd93b01d1236931af27eee8fe assets/create/models/block/warped_window_pane_side_alt.json -32fdb85b5b62d5a0fb41732874c854788cdd2ba1 assets/create/models/block/waxed_copper_shingles.json fb7fb6deebd502946ab57f1b8a9f4a6b5dd48da3 assets/create/models/block/waxed_copper_shingle_slab.json 660f61112b8e46dec5050cb0ed4ee936965a7c58 assets/create/models/block/waxed_copper_shingle_slab_top.json 5d74be967bbe9feba4b630751f13af817a733d1d assets/create/models/block/waxed_copper_shingle_stairs.json 35cb89f29ce3f8d8af13602c08ecd7afbb7cf56a assets/create/models/block/waxed_copper_shingle_stairs_inner.json fcb9295f4f388e6d439ec9a3906ca326b6d69077 assets/create/models/block/waxed_copper_shingle_stairs_outer.json -32f06f39d0b34e4431795aa6e64f87e58dc1597b assets/create/models/block/waxed_copper_tiles.json +32fdb85b5b62d5a0fb41732874c854788cdd2ba1 assets/create/models/block/waxed_copper_shingles.json 298c6100de02ed9f813397d8ba38c46f35035c69 assets/create/models/block/waxed_copper_tile_slab.json d4422c2d96fb329087d1be70d8b983a8cf6c7f01 assets/create/models/block/waxed_copper_tile_slab_top.json fca72048f916d3a3e567b385c948cc1b59711ef4 assets/create/models/block/waxed_copper_tile_stairs.json 997479b62ed3d81ab633279ecc2fabd9588a3bf3 assets/create/models/block/waxed_copper_tile_stairs_inner.json d5c5bbfb9aaa282e11ad6e6309b1880b172ee653 assets/create/models/block/waxed_copper_tile_stairs_outer.json -19a773f91c58c49301f35965bac02d0c05fb2764 assets/create/models/block/waxed_exposed_copper_shingles.json +32f06f39d0b34e4431795aa6e64f87e58dc1597b assets/create/models/block/waxed_copper_tiles.json a3420b91fdebec40e508a5eebb145c0201bd80c8 assets/create/models/block/waxed_exposed_copper_shingle_slab.json 4178ea5e50ee17b3c15f4a59efd019c4a19bb892 assets/create/models/block/waxed_exposed_copper_shingle_slab_top.json dd2d747774abc86e428a883e299db66cded78e11 assets/create/models/block/waxed_exposed_copper_shingle_stairs.json b6845da62d96a33cee624bb70360e256b26eda83 assets/create/models/block/waxed_exposed_copper_shingle_stairs_inner.json 3d8b758e50e75c5adc26ab6f39f9d73f00866673 assets/create/models/block/waxed_exposed_copper_shingle_stairs_outer.json -9cb20c9d41629d8b9426cb65829365d10966338f assets/create/models/block/waxed_exposed_copper_tiles.json +19a773f91c58c49301f35965bac02d0c05fb2764 assets/create/models/block/waxed_exposed_copper_shingles.json cd21d9d2935b6d0103502e2731c11ea27ff64ecf assets/create/models/block/waxed_exposed_copper_tile_slab.json 0ec039ba59fb0028183433e52131ff355ace5bff assets/create/models/block/waxed_exposed_copper_tile_slab_top.json c51dbd34996ac4513234800e427ac308067d5e1d assets/create/models/block/waxed_exposed_copper_tile_stairs.json 68772d4352dc7ade995dfa57ba41a38ef819e855 assets/create/models/block/waxed_exposed_copper_tile_stairs_inner.json d932671822ba93b71a9c8b50e7207803a1c4dbab assets/create/models/block/waxed_exposed_copper_tile_stairs_outer.json -561beafce41b9e9c0b07bc6b7176dd4f6918c116 assets/create/models/block/waxed_oxidized_copper_shingles.json +9cb20c9d41629d8b9426cb65829365d10966338f assets/create/models/block/waxed_exposed_copper_tiles.json 7e0bab8109e322c6db5fe1d5999c06536c21c6eb assets/create/models/block/waxed_oxidized_copper_shingle_slab.json 42df32c4e2d1ffb2ee62748becfd1717118b440c assets/create/models/block/waxed_oxidized_copper_shingle_slab_top.json b55a733e3e68cfbd08d45bb9ac56deef9f728b60 assets/create/models/block/waxed_oxidized_copper_shingle_stairs.json 7b8745213af5aa7938fc04a295be6a087c72daa8 assets/create/models/block/waxed_oxidized_copper_shingle_stairs_inner.json d89419d48d6ee2f6747e7c93de8699db22ea3f59 assets/create/models/block/waxed_oxidized_copper_shingle_stairs_outer.json -5cf92b628ff1f832966138a58ed87d747681274c assets/create/models/block/waxed_oxidized_copper_tiles.json +561beafce41b9e9c0b07bc6b7176dd4f6918c116 assets/create/models/block/waxed_oxidized_copper_shingles.json ad6134598869711a12e2f95c9b5f25a0f7b8dd93 assets/create/models/block/waxed_oxidized_copper_tile_slab.json c17bac0fd6a20540813c6a1c000a553b7c5ac849 assets/create/models/block/waxed_oxidized_copper_tile_slab_top.json d5b30340364f5536e46bc67e777ef4fa20a36e04 assets/create/models/block/waxed_oxidized_copper_tile_stairs.json b40b315c23cbd3eb4658518bfac836f6091321a5 assets/create/models/block/waxed_oxidized_copper_tile_stairs_inner.json f4eaadab29b4f2e915237340e2d6f4aad4ba21d6 assets/create/models/block/waxed_oxidized_copper_tile_stairs_outer.json -9c73020e80c31cd710c218f9699ba9a795758ad0 assets/create/models/block/waxed_weathered_copper_shingles.json +5cf92b628ff1f832966138a58ed87d747681274c assets/create/models/block/waxed_oxidized_copper_tiles.json 897cfc177b073ca1bcb635c74108567f8748b5c4 assets/create/models/block/waxed_weathered_copper_shingle_slab.json efa57ba131c27e0064c0d958e69b10530a26ac41 assets/create/models/block/waxed_weathered_copper_shingle_slab_top.json 4ef11a7e3de630ad46b9179e8a9a34d55202f6c5 assets/create/models/block/waxed_weathered_copper_shingle_stairs.json f32a18c76cfaca2153f6321880a8da1347be37ce assets/create/models/block/waxed_weathered_copper_shingle_stairs_inner.json 9637f78e51ca7ed812e4c64c52e08f6fa0adbfc3 assets/create/models/block/waxed_weathered_copper_shingle_stairs_outer.json -9782a25341dd2ffb146430edbe6916932250c326 assets/create/models/block/waxed_weathered_copper_tiles.json +9c73020e80c31cd710c218f9699ba9a795758ad0 assets/create/models/block/waxed_weathered_copper_shingles.json 0c9669588972d4c2152bd2b043b8386b76a6e1c4 assets/create/models/block/waxed_weathered_copper_tile_slab.json 2d01a583cc948e9e0cb814cad968ed16a07dd46c assets/create/models/block/waxed_weathered_copper_tile_slab_top.json e26dd64495ff8801593e9c22203cbf364075badd assets/create/models/block/waxed_weathered_copper_tile_stairs.json b658c1022587bd670b5acee267607719c1544332 assets/create/models/block/waxed_weathered_copper_tile_stairs_inner.json e7ae89577be9d26a071bf96cbd7ed80293902b63 assets/create/models/block/waxed_weathered_copper_tile_stairs_outer.json -9c73020e80c31cd710c218f9699ba9a795758ad0 assets/create/models/block/weathered_copper_shingles.json +9782a25341dd2ffb146430edbe6916932250c326 assets/create/models/block/waxed_weathered_copper_tiles.json 897cfc177b073ca1bcb635c74108567f8748b5c4 assets/create/models/block/weathered_copper_shingle_slab.json efa57ba131c27e0064c0d958e69b10530a26ac41 assets/create/models/block/weathered_copper_shingle_slab_top.json 4ef11a7e3de630ad46b9179e8a9a34d55202f6c5 assets/create/models/block/weathered_copper_shingle_stairs.json f32a18c76cfaca2153f6321880a8da1347be37ce assets/create/models/block/weathered_copper_shingle_stairs_inner.json 9637f78e51ca7ed812e4c64c52e08f6fa0adbfc3 assets/create/models/block/weathered_copper_shingle_stairs_outer.json -9782a25341dd2ffb146430edbe6916932250c326 assets/create/models/block/weathered_copper_tiles.json +9c73020e80c31cd710c218f9699ba9a795758ad0 assets/create/models/block/weathered_copper_shingles.json 0c9669588972d4c2152bd2b043b8386b76a6e1c4 assets/create/models/block/weathered_copper_tile_slab.json 2d01a583cc948e9e0cb814cad968ed16a07dd46c assets/create/models/block/weathered_copper_tile_slab_top.json e26dd64495ff8801593e9c22203cbf364075badd assets/create/models/block/weathered_copper_tile_stairs.json b658c1022587bd670b5acee267607719c1544332 assets/create/models/block/weathered_copper_tile_stairs_inner.json e7ae89577be9d26a071bf96cbd7ed80293902b63 assets/create/models/block/weathered_copper_tile_stairs_outer.json +9782a25341dd2ffb146430edbe6916932250c326 assets/create/models/block/weathered_copper_tiles.json 2f040681214af58a97e70d3a6e77a0fc2e02c624 assets/create/models/block/white_nixie_tube.json 99f0628623a36ac1700a5876cec010ee6353162f assets/create/models/block/white_seat.json f252f8c68702a0c050797a2dc2a51c586408722d assets/create/models/block/white_toolbox.json @@ -1749,12 +1749,12 @@ de48f4b6fa26928ebc7d5d60e6a0767093430d65 assets/create/models/item/contraption_c ccdf08652511e5737a8489d86ea9422ade4f4ca5 assets/create/models/item/copper_nugget.json 86a770e9b2af1f19bf633f5cfeecd84848f73fbd assets/create/models/item/copper_scaffolding.json a4fd2f4f00e03b2ac5d863e93827d39a984cc2ff assets/create/models/item/copper_sheet.json -13b18ba2938e283d507fbca70518cf52198cdc71 assets/create/models/item/copper_shingles.json 79d9f8667965072f12e51e6601b5c36f8acc125f assets/create/models/item/copper_shingle_slab.json 9fe6f0bdea4595b403ed2d2cbc2023a9abeb79f0 assets/create/models/item/copper_shingle_stairs.json -19642e4ea5deecaf57059827c4c13a19d2e73822 assets/create/models/item/copper_tiles.json +13b18ba2938e283d507fbca70518cf52198cdc71 assets/create/models/item/copper_shingles.json a7147444fc28a4cce21b6cf38e9528537e27c352 assets/create/models/item/copper_tile_slab.json 7330324d6c64f0340d676ecef83a930515d9130e assets/create/models/item/copper_tile_stairs.json +19642e4ea5deecaf57059827c4c13a19d2e73822 assets/create/models/item/copper_tiles.json 08c35e85afe4eb2b106133c5d9c7d7c64ca9a915 assets/create/models/item/copper_valve_handle.json 5cec229a3117ea5987aa42288c070427ac48a5dc assets/create/models/item/copycat_panel.json 1b6707005830ca066a7e997c73391ca88c70bdb0 assets/create/models/item/copycat_step.json @@ -1784,114 +1784,114 @@ b6acd86be9e6cac8b9ed2bc6297d27941ca05f46 assets/create/models/item/crushed_raw_z b67e95801010eab58de02f2b0160bff3f008bd18 assets/create/models/item/crushing_wheel.json af189b0c04482064520d84546d81af8154824292 assets/create/models/item/cuckoo_clock.json 314fb287c7b16a6478fbefde0da80de8828b684e assets/create/models/item/cut_andesite.json -e2840073eac2e6419cd312b3d0177d4c64a5346c assets/create/models/item/cut_andesite_bricks.json 680fe77d50f7c3253ec4997f74761f962b784e15 assets/create/models/item/cut_andesite_brick_slab.json 3c1d56f9686bb2b97c168b0509ddfd06e80be9a0 assets/create/models/item/cut_andesite_brick_stairs.json 4222b965f8a18f78b92838e4642a28fa3e0ad648 assets/create/models/item/cut_andesite_brick_wall.json +e2840073eac2e6419cd312b3d0177d4c64a5346c assets/create/models/item/cut_andesite_bricks.json c100e02ef9b05f4f6df3ddbbfe91db1032d4854b assets/create/models/item/cut_andesite_slab.json f435a67b3d89d12b6e8cb5071a67e35f0918dc79 assets/create/models/item/cut_andesite_stairs.json df9084d532a085220280bc7bee579e1079fbf786 assets/create/models/item/cut_andesite_wall.json 025eedca45b222b91d93b9a3a89fac5ad328b152 assets/create/models/item/cut_asurine.json -1ceb483f428448f00a08541fbcf4f4787aef3f1e assets/create/models/item/cut_asurine_bricks.json 022c56e7aafa7ca4cdd1a88426eb43f9e02c3cc2 assets/create/models/item/cut_asurine_brick_slab.json 3131e09a221c2f0a17cfc7277603f2e3c8164bc7 assets/create/models/item/cut_asurine_brick_stairs.json dc1f5f03acc1165606c48df97953164f6bd7f092 assets/create/models/item/cut_asurine_brick_wall.json +1ceb483f428448f00a08541fbcf4f4787aef3f1e assets/create/models/item/cut_asurine_bricks.json e81d7df1f1b8281c38400713b09cbac59c4d53cc assets/create/models/item/cut_asurine_slab.json cf534603fe71423e0ab80d431ab12394d0a6bb21 assets/create/models/item/cut_asurine_stairs.json 7ca803f5a7798ea034db6385a5f36a48e235c247 assets/create/models/item/cut_asurine_wall.json 707fb799ca44280cad0b817f29a7c75dd0f0ce5e assets/create/models/item/cut_calcite.json -5678b9f76823efac2c6624acc7b2b911402112f4 assets/create/models/item/cut_calcite_bricks.json f794423b242228c43345dc1f40653133fb7f3db6 assets/create/models/item/cut_calcite_brick_slab.json 8e9b46e52758ec7f21c3b84c212e2f6565bf71d9 assets/create/models/item/cut_calcite_brick_stairs.json 1447d21b7fc331528bfd15e5b9d694eb1a31cfb3 assets/create/models/item/cut_calcite_brick_wall.json +5678b9f76823efac2c6624acc7b2b911402112f4 assets/create/models/item/cut_calcite_bricks.json c78c99c78a19097d890414b21270014b52bafd8d assets/create/models/item/cut_calcite_slab.json e6a9144a4bb9e5af3f57d0acdb26d66dc4547217 assets/create/models/item/cut_calcite_stairs.json daf2a2513f6636d140c23b90ba87aad35476c498 assets/create/models/item/cut_calcite_wall.json 29f2bc72aa50cdf34d1d5bfd01a4512d5974dc65 assets/create/models/item/cut_crimsite.json -20bc810ca5b2a35a423e57f287e2f42ad9940b89 assets/create/models/item/cut_crimsite_bricks.json 7c37d3de9674e70595498d1c46c5693d9f39a502 assets/create/models/item/cut_crimsite_brick_slab.json b974c0f2f0e5119d9bac6a36946d4dfdd65b4b5f assets/create/models/item/cut_crimsite_brick_stairs.json c1289ddff572149b2171859689228615802dc825 assets/create/models/item/cut_crimsite_brick_wall.json +20bc810ca5b2a35a423e57f287e2f42ad9940b89 assets/create/models/item/cut_crimsite_bricks.json 8855eb44a68277668c77858715652d6851fa507f assets/create/models/item/cut_crimsite_slab.json 57101d3c2d570bc2c389c1e05e1354d79de70a0a assets/create/models/item/cut_crimsite_stairs.json a10cd65d675a05b9dfbdac67a2d9ca3b4381396a assets/create/models/item/cut_crimsite_wall.json a4ad900cf65136835c259c1e349781538d537a9c assets/create/models/item/cut_deepslate.json -81b10b5d159db4000f4f6569b83fc7e8f702f015 assets/create/models/item/cut_deepslate_bricks.json a63bbe474ca7d8ceafb6bfcb21a88841980fe8e6 assets/create/models/item/cut_deepslate_brick_slab.json 7c1ad49844eafbd87f8c69a077a8c18ccdd4a919 assets/create/models/item/cut_deepslate_brick_stairs.json 6a4ee2e810731e0702c1493237343a567cc736d6 assets/create/models/item/cut_deepslate_brick_wall.json +81b10b5d159db4000f4f6569b83fc7e8f702f015 assets/create/models/item/cut_deepslate_bricks.json ff0d08d1b59de36b016f7952d2bd72d8e1eb1293 assets/create/models/item/cut_deepslate_slab.json 627c806a6eba8b730682821deb31627d75683e88 assets/create/models/item/cut_deepslate_stairs.json 9bdb85a688b09eb34eb8024a6808406118f78133 assets/create/models/item/cut_deepslate_wall.json c33c48d71d98f4b8a84c7f0a4ee88918fed3e798 assets/create/models/item/cut_diorite.json -e8a697df63b0b5fa74dbc70e76b55718a2cc388f assets/create/models/item/cut_diorite_bricks.json 63bc297b782c40c513873b7f8fd8284abce01753 assets/create/models/item/cut_diorite_brick_slab.json f604d088c8c7c6d847795459231d0df8c73d95fb assets/create/models/item/cut_diorite_brick_stairs.json b06be3da6017aa7fbc38b8aecda0d30dae313c13 assets/create/models/item/cut_diorite_brick_wall.json +e8a697df63b0b5fa74dbc70e76b55718a2cc388f assets/create/models/item/cut_diorite_bricks.json 4650f375365caeb237947f6e933d174ebbfbc1e2 assets/create/models/item/cut_diorite_slab.json 933d14f51272b39fc13e94d58f3100469d7cbe06 assets/create/models/item/cut_diorite_stairs.json 0cc44bb9ad0ed3ff11bc6113d0a9e31e99b169b8 assets/create/models/item/cut_diorite_wall.json e2123180fd5312d1e67b3a030fcbc4b6f11aa8bf assets/create/models/item/cut_dripstone.json -4b5d7bbee5741b112e2cb354c5fe49c088fc9b2f assets/create/models/item/cut_dripstone_bricks.json a815b2a927853d6d82d8b69f862be3091c5c8caa assets/create/models/item/cut_dripstone_brick_slab.json b8cb1b04eb869a06ded04c4c3acac6e5a315ee78 assets/create/models/item/cut_dripstone_brick_stairs.json 87fafd603eb4ba41981cd9c9371ac4618909f94d assets/create/models/item/cut_dripstone_brick_wall.json +4b5d7bbee5741b112e2cb354c5fe49c088fc9b2f assets/create/models/item/cut_dripstone_bricks.json 756c801f6bba006fbfd3486e95ba870909ab2902 assets/create/models/item/cut_dripstone_slab.json c59d314e1b5cce1c3745ce164c2a094e17f7a003 assets/create/models/item/cut_dripstone_stairs.json 125b24d28a9957740855467440ad8508d21c24d7 assets/create/models/item/cut_dripstone_wall.json 2fbce0b481f7cf2cf4f0fd03c86ef743b7c30879 assets/create/models/item/cut_granite.json -d8860602cc52fac5a09354c56e78fdfd7d9cb6a9 assets/create/models/item/cut_granite_bricks.json 3584117ed8a69c3842fde1d6accfaaa2c72e44f4 assets/create/models/item/cut_granite_brick_slab.json c68d1c09b9091bc501279115be16f83508b88fed assets/create/models/item/cut_granite_brick_stairs.json 5a37b24319a8708e444902eae3596b68daaffd15 assets/create/models/item/cut_granite_brick_wall.json +d8860602cc52fac5a09354c56e78fdfd7d9cb6a9 assets/create/models/item/cut_granite_bricks.json c2f6603e8cbfc0cdf5e5ef10c6a4baef9c917b6d assets/create/models/item/cut_granite_slab.json 66f8e6d556446441e157427437e9563075e2d6ce assets/create/models/item/cut_granite_stairs.json fe06c8aeab9e4c8a145375af46cbdaed701baad4 assets/create/models/item/cut_granite_wall.json b5c3df9c28a14683a363769cad5d154af56b8da4 assets/create/models/item/cut_limestone.json -7d026353711a464400e69c7e86c9b9c6aa70bf6d assets/create/models/item/cut_limestone_bricks.json 2822ebe1d4211f240e31866759e25add5f0fb56d assets/create/models/item/cut_limestone_brick_slab.json 694dfb73585167011d8123d64f5896697594f4ce assets/create/models/item/cut_limestone_brick_stairs.json db8851d6a1b7604ca1ba7615e1f162f6f5220801 assets/create/models/item/cut_limestone_brick_wall.json +7d026353711a464400e69c7e86c9b9c6aa70bf6d assets/create/models/item/cut_limestone_bricks.json 75584aa5e06168d8866b022fcd72377351b774d9 assets/create/models/item/cut_limestone_slab.json 1df9a186a146e597b48da4c4461f1a98ecf3646a assets/create/models/item/cut_limestone_stairs.json b70ac5462ef4d0363332656aa7cb82919f679893 assets/create/models/item/cut_limestone_wall.json 92bc693db4e0ba6164cd35d4f5fa0982f3b8f796 assets/create/models/item/cut_ochrum.json -3e8e00c602b1fbce888e6fe22d9525f1c025129d assets/create/models/item/cut_ochrum_bricks.json 1edc47c279fadde74322d3fa89ef776bdd6fb354 assets/create/models/item/cut_ochrum_brick_slab.json 4678e2a97c73139b458cea657a55f74659bc36d5 assets/create/models/item/cut_ochrum_brick_stairs.json 85044ec7033cd4c6aa913c4c4bb6c0e3a4386023 assets/create/models/item/cut_ochrum_brick_wall.json +3e8e00c602b1fbce888e6fe22d9525f1c025129d assets/create/models/item/cut_ochrum_bricks.json e0e494fb7fa1767241507347318560335339a2a8 assets/create/models/item/cut_ochrum_slab.json de7c5917bcb14f398d39e3932bfe5e1967ed7a24 assets/create/models/item/cut_ochrum_stairs.json 5a8f8c84e95ee0ab97106a801a456282f5ac207c assets/create/models/item/cut_ochrum_wall.json 1631a807135cf993d9a81068c65e78face2f24e0 assets/create/models/item/cut_scorchia.json -5ecb9692e478e29d64aeb5867e8677671560755d assets/create/models/item/cut_scorchia_bricks.json ac3a29573ce099ac57f59d0a2f1cdc0a453e0621 assets/create/models/item/cut_scorchia_brick_slab.json d3a8a8e0e85aaaadccb18cdce33da54ae0e8a8d7 assets/create/models/item/cut_scorchia_brick_stairs.json 83be13f6cbd9a58e10869e4152066cf3b265f347 assets/create/models/item/cut_scorchia_brick_wall.json +5ecb9692e478e29d64aeb5867e8677671560755d assets/create/models/item/cut_scorchia_bricks.json 0fee2e7f8e80bbd33e4d928c8374e6dae65f0b1f assets/create/models/item/cut_scorchia_slab.json 88a6b3709bab76390ace6f641eac18d43c9d099f assets/create/models/item/cut_scorchia_stairs.json d733d43252bf27b6fb1d7e016dc77556c3d1eb71 assets/create/models/item/cut_scorchia_wall.json ce75fb80c38c94bf6bf631eeb756909decaaaab0 assets/create/models/item/cut_scoria.json -81aa0bd4ec878754043a107466dcd87d49b3697c assets/create/models/item/cut_scoria_bricks.json d78a5126aefdd4cd182f9ec0ddda64df00d0f01c assets/create/models/item/cut_scoria_brick_slab.json 661d49b996f9c97a333e7e39dd13a0476db6b142 assets/create/models/item/cut_scoria_brick_stairs.json 3be69c075b479ac53c6201d7d7224d399f8009b6 assets/create/models/item/cut_scoria_brick_wall.json +81aa0bd4ec878754043a107466dcd87d49b3697c assets/create/models/item/cut_scoria_bricks.json 824bedfbeec53ec8f539fe73c0a3c3d927a21aa4 assets/create/models/item/cut_scoria_slab.json 15560f1251f18d53fe1b71adc6be5060c4d8fb94 assets/create/models/item/cut_scoria_stairs.json e35ebcc4f7f7b94623af85b181d916e48fbbb5ed assets/create/models/item/cut_scoria_wall.json 71284d3d6dba230dbecd01eb015e0e65877b820d assets/create/models/item/cut_tuff.json -4de100799e290db3fd46923781a83e6a12654266 assets/create/models/item/cut_tuff_bricks.json 4c7d5fadb0b0eaecf2055a0cd279f9ec130b93d0 assets/create/models/item/cut_tuff_brick_slab.json 6f32b83c9f82424c0e2a2e0a8813eb44c2ac4527 assets/create/models/item/cut_tuff_brick_stairs.json 9088296b7677bddf16d670858a619d846a134ef6 assets/create/models/item/cut_tuff_brick_wall.json +4de100799e290db3fd46923781a83e6a12654266 assets/create/models/item/cut_tuff_bricks.json e9134027cc917e2e878456edb49bcfee382e73b1 assets/create/models/item/cut_tuff_slab.json 8235a34249197c100645b55ded5ff619a055d8a6 assets/create/models/item/cut_tuff_stairs.json a1626993eafa8d85dc950e17cbf78378ed64c7d2 assets/create/models/item/cut_tuff_wall.json a343c74f1e55426330df18f522e6d2a81276c499 assets/create/models/item/cut_veridium.json -3c3fd197f8e299ff90850e24c6507ea12f373123 assets/create/models/item/cut_veridium_bricks.json c1c5561ce31e237b7ea8f1adfb6a79e661b7f940 assets/create/models/item/cut_veridium_brick_slab.json f633006045ccfcdf486d7a240217229d6eed717e assets/create/models/item/cut_veridium_brick_stairs.json 8182109a002317dd8d2767b3828f8c44166a053f assets/create/models/item/cut_veridium_brick_wall.json +3c3fd197f8e299ff90850e24c6507ea12f373123 assets/create/models/item/cut_veridium_bricks.json 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 @@ -1918,12 +1918,12 @@ badd4326fac0b0a1590a2e9bce7c2cdd4e4562f3 assets/create/models/item/empty_schemat 7ec3ed4aaab72d76f6414447bbb3ad7887adf61f assets/create/models/item/encased_fan.json 3e1fdcc80fd68199b1890bcc830f78c48e7c0e43 assets/create/models/item/experience_block.json 9775e83414c0febb5c5b832437b0580e91bcbff3 assets/create/models/item/experience_nugget.json -87add851ae3271d733c9e6888865c288b6716f3b assets/create/models/item/exposed_copper_shingles.json 721c8ac46bf23abec2bbf4cff6dbfdf96cc569a6 assets/create/models/item/exposed_copper_shingle_slab.json 6e1c7fcd8da84dc2d49adb9802ce4fb431eddae1 assets/create/models/item/exposed_copper_shingle_stairs.json -fa7ffb172a43774cc07a2bb201e7010a2549001d assets/create/models/item/exposed_copper_tiles.json +87add851ae3271d733c9e6888865c288b6716f3b assets/create/models/item/exposed_copper_shingles.json a443633d90ef9ac2a866b69b2ecdfad1841dc3e1 assets/create/models/item/exposed_copper_tile_slab.json 9bb425a14635fc8b36a9a95f3d0c54e0b129b7b4 assets/create/models/item/exposed_copper_tile_stairs.json +fa7ffb172a43774cc07a2bb201e7010a2549001d assets/create/models/item/exposed_copper_tiles.json 8b64a93d9b6e33e3caa66adb7a0cc8c5cd473023 assets/create/models/item/extendo_grip.json dad31483f65baaf187e6553e3cd301c5d69e9db4 assets/create/models/item/filter.json 575047531b8e324df9e58abba79cfe9ee3db8b16 assets/create/models/item/fluid_pipe.json @@ -1948,11 +1948,11 @@ b8d6d2d163e2ab5f654bbc4eda9ad63f8064d27c assets/create/models/item/gray_seat.jso 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 -9e352162c8135773a4eca41871beea8f3ca650ae assets/create/models/item/handheld_worldshaper.json dac0331061c464e6d3e2070b232781c632840191 assets/create/models/item/hand_crank.json +9e352162c8135773a4eca41871beea8f3ca650ae assets/create/models/item/handheld_worldshaper.json 7bb435c53cbf935d80a28746125aebbd6263e45c assets/create/models/item/haunted_bell.json -81d67fb0e59f25762a412990884813c72d399d55 assets/create/models/item/honeyed_apple.json 2e97629313eab1a4ac4b38785dbe7ed45346e625 assets/create/models/item/honey_bucket.json +81d67fb0e59f25762a412990884813c72d399d55 assets/create/models/item/honeyed_apple.json 70185e640169d6253f06fb98f31b240f4807a53e assets/create/models/item/horizontal_framed_glass.json e623c9541adc0fa877c5615e3211f47886383f2d assets/create/models/item/horizontal_framed_glass_pane.json 58b6f4ec2af3a69ae7145fb25d73451b6e8a2834 assets/create/models/item/hose_pulley.json @@ -1986,11 +1986,11 @@ dae914625ff1bc3ebe1463485cad4526a7d7e9f5 assets/create/models/item/light_blue_to 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 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 +8f53caad3899a30be5087a0ba155080834418cc0 assets/create/models/item/limestone.json +fba1e7d1cad39c89976b427db62544d80f47ad5d assets/create/models/item/limestone_pillar.json 1d30f9b525e8e9736b34a92f848e235c71fd6bd8 assets/create/models/item/linear_chassis.json 8f622f5f79446f6060d9e8815205fce919c8c829 assets/create/models/item/linked_controller.json ad6fd371ee989c9c3c21e762273e8a4e903f0af8 assets/create/models/item/magenta_seat.json @@ -2031,12 +2031,12 @@ af50363d603d61340b336569d58c1febde253665 assets/create/models/item/ochrum.json 7e767ca9e0ddb769b38fabd9289648ac63f5413d assets/create/models/item/orange_valve_handle.json 82152bca4310111d91584a2a78f05e158bb4bd90 assets/create/models/item/ornate_iron_window.json f9064c1f199bcd8db321078e2363ed91cb2acc09 assets/create/models/item/ornate_iron_window_pane.json -09b3cd8ff7b29a6dd59f739a95bb708646d23537 assets/create/models/item/oxidized_copper_shingles.json c9c7ccdb68de2e77cd9f7053fab19493dd30a985 assets/create/models/item/oxidized_copper_shingle_slab.json 89c5f7a0a28f238ebed2641e243a47e4be2ad5ab assets/create/models/item/oxidized_copper_shingle_stairs.json -1c3428e2aed32a013631db012642a34d4eaf0785 assets/create/models/item/oxidized_copper_tiles.json +09b3cd8ff7b29a6dd59f739a95bb708646d23537 assets/create/models/item/oxidized_copper_shingles.json f1af7c5f3840efc3ae07940ee6719eb3417a0e1a assets/create/models/item/oxidized_copper_tile_slab.json ef2fe68d407a03bf1ed8f2d2f3e7323777d061bb assets/create/models/item/oxidized_copper_tile_stairs.json +1c3428e2aed32a013631db012642a34d4eaf0785 assets/create/models/item/oxidized_copper_tiles.json 76aeceb41bb7df873dbafe1bd5e26deb24abf93f assets/create/models/item/peculiar_bell.json df13d4281dc45041ecd93504d45daef61d070581 assets/create/models/item/pink_seat.json 842afb2a345dbaba857e90f7dffa724841ef7b2d assets/create/models/item/pink_toolbox.json @@ -2117,12 +2117,12 @@ f91405b9aec1e0142c1b90582e03a1973251da05 assets/create/models/item/radial_chassi 1c984ea9dbaec02e88dba1b81906c9acca7ed672 assets/create/models/item/railway_casing.json 5f8e5283fbebb452f1a1141b33ee73f08879c75d assets/create/models/item/raw_zinc.json 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 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 02473f42ef4b53dc809c7c58ae657c014bfaf652 assets/create/models/item/red_valve_handle.json +9dc6c52e258b00cac6ed23147983045c43218b5d assets/create/models/item/redstone_contact.json +f8f733364bdd32b2ad597e81103bc02344ce63bd assets/create/models/item/redstone_link.json 9926bbe6dad7c4c1a146492116d232e941c80d2b assets/create/models/item/refined_radiance.json bf827486dc7a1b3aeae577844d2dab2a97051db9 assets/create/models/item/refined_radiance_casing.json 69dc8139280bce3a7e08532afbbc5c41e7942be1 assets/create/models/item/rope_pulley.json @@ -2135,9 +2135,9 @@ d45005a89e2c0d29944e0112be274365e0e318a5 assets/create/models/item/rose_quartz_t 670e978a34faf6a3acd7880b2f94c2574178d586 assets/create/models/item/sand_paper.json 6854451e331242ec50c186a545538024b07ec123 assets/create/models/item/schedule.json 0effa517c214ba07dba2f4ed12dfcf4785e42dd8 assets/create/models/item/schematic.json -8b7727844d8c12c3c22828c7f65fc7ac2d273e36 assets/create/models/item/schematicannon.json 2a52f084fa8187dd8da28fe820dde50c47a93b57 assets/create/models/item/schematic_and_quill.json 4c8b34627001e35ee15412a0cd037d0f24ba914e assets/create/models/item/schematic_table.json +8b7727844d8c12c3c22828c7f65fc7ac2d273e36 assets/create/models/item/schematicannon.json 2955563914c2f84ed06474c135062e91189ddf3a assets/create/models/item/scorchia.json 669041e5ad29d2166cc8895f85aa262040671d3e assets/create/models/item/scorchia_pillar.json ff52eb59dadfe675e416440f3115856a501428a6 assets/create/models/item/scoria.json @@ -2147,63 +2147,63 @@ ff36a19e124caf2ee8a03767e39601df6866075b assets/create/models/item/secondary_lin abaa6da82babc26717ffff44fc41327bd015c9a6 assets/create/models/item/shadow_steel.json ffaec38d11b91add4e150e33d0e0e49394f5beca assets/create/models/item/shadow_steel_casing.json b6fcd9722e5a09a9207964cba68752512e3b945a assets/create/models/item/shaft.json -58ca190177e77db90c8195347c29d52c2cd0c556 assets/create/models/item/small_andesite_bricks.json fa92996fada8545fc340fb401bd0568f56809bf0 assets/create/models/item/small_andesite_brick_slab.json 08474bf814a55795c1f94203ceb8a969be2a2132 assets/create/models/item/small_andesite_brick_stairs.json 0e00bc6aa5be242217ed6fe8cbe1ccdf180742fb assets/create/models/item/small_andesite_brick_wall.json -543055fabb706a93037c6a9e47c334508e41b06c assets/create/models/item/small_asurine_bricks.json +58ca190177e77db90c8195347c29d52c2cd0c556 assets/create/models/item/small_andesite_bricks.json b160c3277f00f19687cffb87f9cb3aa32d3633aa assets/create/models/item/small_asurine_brick_slab.json 183fa4919f06e8c3c10f1efeceefd55389a96102 assets/create/models/item/small_asurine_brick_stairs.json d6a5ffdb493fb2c8176a7e6b42e05c2d393a2782 assets/create/models/item/small_asurine_brick_wall.json -26d9361e33e362a772220146724c0927453831e0 assets/create/models/item/small_calcite_bricks.json +543055fabb706a93037c6a9e47c334508e41b06c assets/create/models/item/small_asurine_bricks.json 8c1b5d5d40393636c9ff10afc09038c89bc1b383 assets/create/models/item/small_calcite_brick_slab.json 481ce90fb6abb05c904f01df3fe635f702bbfac0 assets/create/models/item/small_calcite_brick_stairs.json 02adb90bdf06a7c4c57d09dfd3c77cceef9b7fbe assets/create/models/item/small_calcite_brick_wall.json -d5a033d3dedb799c4752b7e68b6881529f38f8e5 assets/create/models/item/small_crimsite_bricks.json +26d9361e33e362a772220146724c0927453831e0 assets/create/models/item/small_calcite_bricks.json 8f382537c99eac3335f72db8dba33ab71f99a919 assets/create/models/item/small_crimsite_brick_slab.json b5d012cf0c5c94b73e6825b6884ab1d3eee7d64e assets/create/models/item/small_crimsite_brick_stairs.json 236457bb16bc7e949c16f3f091ee74dc3f3e6973 assets/create/models/item/small_crimsite_brick_wall.json -6ce2cb7882f41fcbcd641a442c98767bda61f65f assets/create/models/item/small_deepslate_bricks.json +d5a033d3dedb799c4752b7e68b6881529f38f8e5 assets/create/models/item/small_crimsite_bricks.json ce79900b7aa1eff0d42cabcd0a7f80ef20824551 assets/create/models/item/small_deepslate_brick_slab.json a260711af72c749a6b72f72515bbecb2e01e3ed8 assets/create/models/item/small_deepslate_brick_stairs.json 4e474891c6a269166c2eb413fae78699e5657af4 assets/create/models/item/small_deepslate_brick_wall.json -e412eaa393965ef5426c3d8d95d5c9d69e37e054 assets/create/models/item/small_diorite_bricks.json +6ce2cb7882f41fcbcd641a442c98767bda61f65f assets/create/models/item/small_deepslate_bricks.json 55b82c2f30d52acee5c3807ab2ffaed1d773cfa8 assets/create/models/item/small_diorite_brick_slab.json 49a17610b5b05595894ca2683056cecd724c1111 assets/create/models/item/small_diorite_brick_stairs.json dd3630a9c5500e6cf09e95d09e7a3cc99db11899 assets/create/models/item/small_diorite_brick_wall.json -c29d35da520d0fe828bb364db403b8cdf55f0a2e assets/create/models/item/small_dripstone_bricks.json +e412eaa393965ef5426c3d8d95d5c9d69e37e054 assets/create/models/item/small_diorite_bricks.json 21e281ec7a82d48018366a0737c6867f625b4663 assets/create/models/item/small_dripstone_brick_slab.json 6862e72eedf80536f40b6ac42ff78f13f62d012f assets/create/models/item/small_dripstone_brick_stairs.json ca8613bb64ceb562c36dd1d6a3b76b5f15f35be9 assets/create/models/item/small_dripstone_brick_wall.json -81eae95d20a9e99a070dfb8f6e6c22ef29f628d3 assets/create/models/item/small_granite_bricks.json +c29d35da520d0fe828bb364db403b8cdf55f0a2e assets/create/models/item/small_dripstone_bricks.json a19aa13eb3c04a9e0931e22e4170eec80950efab assets/create/models/item/small_granite_brick_slab.json 51bc02587cad5dfcfaf9d040848faa5277a25a5f assets/create/models/item/small_granite_brick_stairs.json 147a6f42be8312fbf050ad53c1625a1458f73cc3 assets/create/models/item/small_granite_brick_wall.json -bfa76583bca68134bbe2793c263cc0b71e1406af assets/create/models/item/small_limestone_bricks.json +81eae95d20a9e99a070dfb8f6e6c22ef29f628d3 assets/create/models/item/small_granite_bricks.json a9599981e872e683dacd01b2f0af511f416dd526 assets/create/models/item/small_limestone_brick_slab.json d8f8eadea13fc90a1c8ee5aca4be71fb22a79fd0 assets/create/models/item/small_limestone_brick_stairs.json 67626afe8b0fc9135456a24ea49c602b83d6970d assets/create/models/item/small_limestone_brick_wall.json -2d4b22d4028c55cbabc7eb405c2c6d485390afab assets/create/models/item/small_ochrum_bricks.json +bfa76583bca68134bbe2793c263cc0b71e1406af assets/create/models/item/small_limestone_bricks.json f7547aacb8bdaf61424cd56565e40d3cd40a1cfa assets/create/models/item/small_ochrum_brick_slab.json 8a320ff9e75e16a182cb7d07784a595fe7876e04 assets/create/models/item/small_ochrum_brick_stairs.json 0eedd4fe5b0a82de16fed148836087ff4ae64a74 assets/create/models/item/small_ochrum_brick_wall.json +2d4b22d4028c55cbabc7eb405c2c6d485390afab assets/create/models/item/small_ochrum_bricks.json 97b8e3eaddac0b93d4b6bc140f573969fcba5823 assets/create/models/item/small_rose_quartz_tiles.json -ac1bf1d2344517c18b945afa198d5d05e2866f6b assets/create/models/item/small_scorchia_bricks.json 63ef9901ba1014027e8c873d8374d86abb73158e assets/create/models/item/small_scorchia_brick_slab.json f52601fe54695c225a595a65e9130665582db856 assets/create/models/item/small_scorchia_brick_stairs.json b4e0db087dc88e0a3a4a82197a0ce347d3c7a7aa assets/create/models/item/small_scorchia_brick_wall.json -25b6bb40701e782ed64414ec8391b304ad5e6b12 assets/create/models/item/small_scoria_bricks.json +ac1bf1d2344517c18b945afa198d5d05e2866f6b assets/create/models/item/small_scorchia_bricks.json a4bdeb066dcc44f8be058e6d9dfc0a3fd34819bf assets/create/models/item/small_scoria_brick_slab.json 5ffb0e7de917013cd82cece2506d72fce2cd5fc6 assets/create/models/item/small_scoria_brick_stairs.json 67dcbc7d52fbbe88f89b36e04f970b27024741e4 assets/create/models/item/small_scoria_brick_wall.json -90943707d8b232d816392bec8ae05e06b6eedd72 assets/create/models/item/small_tuff_bricks.json +25b6bb40701e782ed64414ec8391b304ad5e6b12 assets/create/models/item/small_scoria_bricks.json 91a144100eea8b4e67a0a4f31b35a714693fa001 assets/create/models/item/small_tuff_brick_slab.json b3f89c9f8e46fbdfc58171073d6ad91c588e5853 assets/create/models/item/small_tuff_brick_stairs.json 52c1d4cfb5f1726c9ccbb00db60bdd6f760bf40f assets/create/models/item/small_tuff_brick_wall.json -6935d6d9dbdb99fe7258d9347419d65571711263 assets/create/models/item/small_veridium_bricks.json +90943707d8b232d816392bec8ae05e06b6eedd72 assets/create/models/item/small_tuff_bricks.json 0bb60fc6ab570db83214fd10c83d931f6677e361 assets/create/models/item/small_veridium_brick_slab.json 89918d98b6830477b21ab7fb9e30807d3ca1d379 assets/create/models/item/small_veridium_brick_stairs.json ab4e7695e99548f83a89f3d5ad7690a576bafcc0 assets/create/models/item/small_veridium_brick_wall.json +6935d6d9dbdb99fe7258d9347419d65571711263 assets/create/models/item/small_veridium_bricks.json 6cf508dbd3d015ea730366db92bb17844dc2ca06 assets/create/models/item/smart_chute.json 9201f00edcf2ffa33cb079c28b5c33e39872c824 assets/create/models/item/smart_fluid_pipe.json 67804bdd890f167010f6101a700e85a3245f4cc3 assets/create/models/item/speedometer.json @@ -2240,36 +2240,36 @@ b0f6d37aa695395e28a23d36775092f63ab3f5a5 assets/create/models/item/vertical_gear 9c5087114e35052c5e56bb752252de5d092408c5 assets/create/models/item/warped_window.json 83502f4b8d0134e793611b36a56cca59af097ed5 assets/create/models/item/warped_window_pane.json e5939b47bf7440dc101c667e68ef6bf750a3290f assets/create/models/item/water_wheel.json -be2f058a7ecb015599ee052ec27c4360d636999a assets/create/models/item/waxed_copper_shingles.json adc188e4e48bea80607c6e0c7076c9bdd7236cb0 assets/create/models/item/waxed_copper_shingle_slab.json 7e224aceaa94361256e95e4c44d8814aebaf297c assets/create/models/item/waxed_copper_shingle_stairs.json -eced19a2f721c54b968e5979cde2705f15faf3e1 assets/create/models/item/waxed_copper_tiles.json +be2f058a7ecb015599ee052ec27c4360d636999a assets/create/models/item/waxed_copper_shingles.json 68b3632c34adb9991aa993385f53624632c260f2 assets/create/models/item/waxed_copper_tile_slab.json a7fc0cc2d32dcd49c3274597ce7121f01fca03f8 assets/create/models/item/waxed_copper_tile_stairs.json -5336907eba067492f6d00b4b8514f9663830a1d5 assets/create/models/item/waxed_exposed_copper_shingles.json +eced19a2f721c54b968e5979cde2705f15faf3e1 assets/create/models/item/waxed_copper_tiles.json fd428034c46a240c4bb2a1aee625b8767f41c3ef assets/create/models/item/waxed_exposed_copper_shingle_slab.json 43d714187fe6c0cd1ed7abcddef1ebcd63979ff4 assets/create/models/item/waxed_exposed_copper_shingle_stairs.json -962b24b3611abefc21920d01452944710ab0da3f assets/create/models/item/waxed_exposed_copper_tiles.json +5336907eba067492f6d00b4b8514f9663830a1d5 assets/create/models/item/waxed_exposed_copper_shingles.json 25f5a10fe8e6acbdbf8457d56aeee065835a93ec assets/create/models/item/waxed_exposed_copper_tile_slab.json 22917505d328fb5b489b9f7f9068f1514b784abb assets/create/models/item/waxed_exposed_copper_tile_stairs.json -12c3dd893bddb66b9b387652c67c8f0e24b643ff assets/create/models/item/waxed_oxidized_copper_shingles.json +962b24b3611abefc21920d01452944710ab0da3f assets/create/models/item/waxed_exposed_copper_tiles.json 9b7c82376ea8c1c8ecbc7bbe15283f84b0d50d94 assets/create/models/item/waxed_oxidized_copper_shingle_slab.json fbb6043eb935aa0641a482ee7300c780be257440 assets/create/models/item/waxed_oxidized_copper_shingle_stairs.json -6b8f75d4818db903b22f4626d02671ab76a61023 assets/create/models/item/waxed_oxidized_copper_tiles.json +12c3dd893bddb66b9b387652c67c8f0e24b643ff assets/create/models/item/waxed_oxidized_copper_shingles.json 6e7bc8eb9a87d903dcc590e9918ce8d4411bf190 assets/create/models/item/waxed_oxidized_copper_tile_slab.json 10136759b31e4d957e8374948460d6c984711326 assets/create/models/item/waxed_oxidized_copper_tile_stairs.json -ce2dcfc01205da1dc70f34091a2c24f563e72466 assets/create/models/item/waxed_weathered_copper_shingles.json +6b8f75d4818db903b22f4626d02671ab76a61023 assets/create/models/item/waxed_oxidized_copper_tiles.json 2bf249c677d30a4febf950fa7c6caa87c348c54e assets/create/models/item/waxed_weathered_copper_shingle_slab.json 9fa84f2555d82b5a1550b748a332ceb443a04fae assets/create/models/item/waxed_weathered_copper_shingle_stairs.json -02d2ac048c9bea86d10673254dfc107f3c9c5bb5 assets/create/models/item/waxed_weathered_copper_tiles.json +ce2dcfc01205da1dc70f34091a2c24f563e72466 assets/create/models/item/waxed_weathered_copper_shingles.json ab40b1a5a03cd290d53ef2ea65f90dcfcd2673de assets/create/models/item/waxed_weathered_copper_tile_slab.json dadc7b65a4527e288c21a20df978796a8c444fd2 assets/create/models/item/waxed_weathered_copper_tile_stairs.json -86b8e71fa8b7aeb73eafda89d8d06d83da6a5d25 assets/create/models/item/weathered_copper_shingles.json +02d2ac048c9bea86d10673254dfc107f3c9c5bb5 assets/create/models/item/waxed_weathered_copper_tiles.json 94db30ad2381d2f2c37cdfd0d5ce5c45a2807640 assets/create/models/item/weathered_copper_shingle_slab.json 7262c01df4b5a8cd8c6a5545062f251d5ad9fd06 assets/create/models/item/weathered_copper_shingle_stairs.json -99f17b16b68201aefb78298b3e6c657e3c2235e0 assets/create/models/item/weathered_copper_tiles.json +86b8e71fa8b7aeb73eafda89d8d06d83da6a5d25 assets/create/models/item/weathered_copper_shingles.json 0b1b299d6dfab65b6060305a8b3e51f6e2df09f4 assets/create/models/item/weathered_copper_tile_slab.json 0c3989b44fde934ba8b88b071887e5ede522c417 assets/create/models/item/weathered_copper_tile_stairs.json +99f17b16b68201aefb78298b3e6c657e3c2235e0 assets/create/models/item/weathered_copper_tiles.json 79431edb868e6560f4f6d5b3441c0176c7699f5e assets/create/models/item/weighted_ejector.json 0fd2214cdff8a92e05d9d5ee888329b3235143c0 assets/create/models/item/wheat_flour.json aacced59d21212090d508a9684bb46c9472a8a2f assets/create/models/item/whisk.json @@ -2315,42 +2315,42 @@ fb36a2f400347c3291978a49e59374f3ac459f14 data/create/advancements/recipes/buildi 6df6a6885c3ebf92f98f105be16d8e0c80da19f0 data/create/advancements/recipes/building_blocks/birch_window_pane.json 0d724aefa51b969dbadb59b1193172a44ecf5644 data/create/advancements/recipes/building_blocks/calcite_from_stone_types_calcite_stonecutting.json 537fe5dffa659e5838379587fbd84f2f641551ea data/create/advancements/recipes/building_blocks/calcite_pillar_from_stone_types_calcite_stonecutting.json -09f332cd34e6a92af9e8e4e757418c7ba8b536da data/create/advancements/recipes/building_blocks/copper_shingles_from_ingots_copper_stonecutting.json 55214a0fd27318b17163cace66c7525785127ef8 data/create/advancements/recipes/building_blocks/copper_shingle_slab.json fb4210dbbfb74459e10da94a540f3bfdf91c4a8d data/create/advancements/recipes/building_blocks/copper_shingle_slab_from_copper_shingles_stonecutting.json 31b04ac1b117fb65f5129c5bbb48e42c1c4c1003 data/create/advancements/recipes/building_blocks/copper_shingle_stairs.json bef4a9a4c2e722d4f086d6b4c9d6fa1d0836ec10 data/create/advancements/recipes/building_blocks/copper_shingle_stairs_from_copper_shingles_stonecutting.json -f66a48f01afb4fa1babee4a8c28b032280c3ac9e data/create/advancements/recipes/building_blocks/copper_tiles_from_ingots_copper_stonecutting.json +09f332cd34e6a92af9e8e4e757418c7ba8b536da data/create/advancements/recipes/building_blocks/copper_shingles_from_ingots_copper_stonecutting.json ef79744ebf31453d1c81789afed7b717837b3515 data/create/advancements/recipes/building_blocks/copper_tile_slab.json 8e9997c43b1c06521fe8d38b04ccb3f04c93d537 data/create/advancements/recipes/building_blocks/copper_tile_slab_from_copper_tiles_stonecutting.json a2609aa8b5453f2294f38c81d26e0b8dad71087d data/create/advancements/recipes/building_blocks/copper_tile_stairs.json d47e46c66bf69e8310e6687716858842e8aed7b5 data/create/advancements/recipes/building_blocks/copper_tile_stairs_from_copper_tiles_stonecutting.json +f66a48f01afb4fa1babee4a8c28b032280c3ac9e data/create/advancements/recipes/building_blocks/copper_tiles_from_ingots_copper_stonecutting.json cc14d10c75ab0fdd7c54db1922e5e56667739fef data/create/advancements/recipes/building_blocks/copycat_panel_from_ingots_zinc_stonecutting.json 55d2812be912c857ff666d581174378857d3bce2 data/create/advancements/recipes/building_blocks/copycat_step_from_ingots_zinc_stonecutting.json -8615fc107b1f4df86711081a9dccac8631b02e6b data/create/advancements/recipes/building_blocks/crafting/copper/waxed_copper_shingles_from_honeycomb.json 0e0eba8550768ef69087dff8112814f25233fab7 data/create/advancements/recipes/building_blocks/crafting/copper/waxed_copper_shingle_slab_from_honeycomb.json 2c960d55273df4c0c8c33b2c329175b35b18fc8c data/create/advancements/recipes/building_blocks/crafting/copper/waxed_copper_shingle_stairs_from_honeycomb.json -fa8f3ed9a4c6f0c3cd4c21b0ae4dc8ca4dba8678 data/create/advancements/recipes/building_blocks/crafting/copper/waxed_copper_tiles_from_honeycomb.json +8615fc107b1f4df86711081a9dccac8631b02e6b data/create/advancements/recipes/building_blocks/crafting/copper/waxed_copper_shingles_from_honeycomb.json d6f2aa7fd10c96f71c47bdabb3e53dc4c4e73706 data/create/advancements/recipes/building_blocks/crafting/copper/waxed_copper_tile_slab_from_honeycomb.json eca165eee20adba1557ccc74ef50ee90311b3019 data/create/advancements/recipes/building_blocks/crafting/copper/waxed_copper_tile_stairs_from_honeycomb.json -88a236933e8dfe0d809bda098d16782288c4800c data/create/advancements/recipes/building_blocks/crafting/copper/waxed_exposed_copper_shingles_from_honeycomb.json +fa8f3ed9a4c6f0c3cd4c21b0ae4dc8ca4dba8678 data/create/advancements/recipes/building_blocks/crafting/copper/waxed_copper_tiles_from_honeycomb.json 301149dabc4dce290b4884f4ed3cb2132123adf0 data/create/advancements/recipes/building_blocks/crafting/copper/waxed_exposed_copper_shingle_slab_from_honeycomb.json f360dce7bece72672f2624710c88edbe3e3f8885 data/create/advancements/recipes/building_blocks/crafting/copper/waxed_exposed_copper_shingle_stairs_from_honeycomb.json -bc27959288766492746f41c4810350dcef1b320d data/create/advancements/recipes/building_blocks/crafting/copper/waxed_exposed_copper_tiles_from_honeycomb.json +88a236933e8dfe0d809bda098d16782288c4800c data/create/advancements/recipes/building_blocks/crafting/copper/waxed_exposed_copper_shingles_from_honeycomb.json 7ceb4b74ff84ed404518b6cb5e1432dac5903b5f data/create/advancements/recipes/building_blocks/crafting/copper/waxed_exposed_copper_tile_slab_from_honeycomb.json ec1eec3bc25534484cb264134e62b578525422aa data/create/advancements/recipes/building_blocks/crafting/copper/waxed_exposed_copper_tile_stairs_from_honeycomb.json -2e8f1da032110e8c5ec375ffd425e5eed7f58cae data/create/advancements/recipes/building_blocks/crafting/copper/waxed_oxidized_copper_shingles_from_honeycomb.json +bc27959288766492746f41c4810350dcef1b320d data/create/advancements/recipes/building_blocks/crafting/copper/waxed_exposed_copper_tiles_from_honeycomb.json e34abb4d51c1d00419fc3d3799ca0d9fe7ea1027 data/create/advancements/recipes/building_blocks/crafting/copper/waxed_oxidized_copper_shingle_slab_from_honeycomb.json 9471e190beb603f022fb234f2cf35b5b4b93f0c0 data/create/advancements/recipes/building_blocks/crafting/copper/waxed_oxidized_copper_shingle_stairs_from_honeycomb.json -17fe14b753953a68887cd001fcaa264ef031463f data/create/advancements/recipes/building_blocks/crafting/copper/waxed_oxidized_copper_tiles_from_honeycomb.json +2e8f1da032110e8c5ec375ffd425e5eed7f58cae data/create/advancements/recipes/building_blocks/crafting/copper/waxed_oxidized_copper_shingles_from_honeycomb.json 2577754364f05264fac325f67597230d01fa0c1d data/create/advancements/recipes/building_blocks/crafting/copper/waxed_oxidized_copper_tile_slab_from_honeycomb.json 003e384d9594a4e6ef5678e74f04b56de047dbde data/create/advancements/recipes/building_blocks/crafting/copper/waxed_oxidized_copper_tile_stairs_from_honeycomb.json -5009a82a897a15407fec785005107b0d228fffe7 data/create/advancements/recipes/building_blocks/crafting/copper/waxed_weathered_copper_shingles_from_honeycomb.json +17fe14b753953a68887cd001fcaa264ef031463f data/create/advancements/recipes/building_blocks/crafting/copper/waxed_oxidized_copper_tiles_from_honeycomb.json 70ce32937dcf349dce77fef8022bc0c15863f6a6 data/create/advancements/recipes/building_blocks/crafting/copper/waxed_weathered_copper_shingle_slab_from_honeycomb.json 1fc498238dcc2705152573ba7f74bb50e7e66ca7 data/create/advancements/recipes/building_blocks/crafting/copper/waxed_weathered_copper_shingle_stairs_from_honeycomb.json -d12aa3dd5457327224fd007211878eec21043971 data/create/advancements/recipes/building_blocks/crafting/copper/waxed_weathered_copper_tiles_from_honeycomb.json +5009a82a897a15407fec785005107b0d228fffe7 data/create/advancements/recipes/building_blocks/crafting/copper/waxed_weathered_copper_shingles_from_honeycomb.json 6f461d7036de914c636b7916dc798775ccf25be1 data/create/advancements/recipes/building_blocks/crafting/copper/waxed_weathered_copper_tile_slab_from_honeycomb.json 3bc9efcddecd23fd06c6056a0ee7b937959cecc0 data/create/advancements/recipes/building_blocks/crafting/copper/waxed_weathered_copper_tile_stairs_from_honeycomb.json +d12aa3dd5457327224fd007211878eec21043971 data/create/advancements/recipes/building_blocks/crafting/copper/waxed_weathered_copper_tiles_from_honeycomb.json 3064c52dea808a00c211bfedb96106b563f480da data/create/advancements/recipes/building_blocks/crafting/kinetics/black_seat.json f07a0b21db200ab68a7df02db519869f68953286 data/create/advancements/recipes/building_blocks/crafting/kinetics/black_seat_from_other_seat.json 80ac4db5c53c7efc2666a7abb4e2e876c5f86588 data/create/advancements/recipes/building_blocks/crafting/kinetics/blue_seat.json @@ -2387,7 +2387,6 @@ f3188b24f8108be4219016689a4768f826b4fef3 data/create/advancements/recipes/buildi e88373b83226d860b0c2131213f5d3b09f31ab96 data/create/advancements/recipes/building_blocks/crimsite_pillar_from_stone_types_crimsite_stonecutting.json 09f7122cf360fd56bde2b1659bbed526f9a119c4 data/create/advancements/recipes/building_blocks/crimson_window.json b5234c6050bc0c6fe872a5ddc87d46ba39e07971 data/create/advancements/recipes/building_blocks/crimson_window_pane.json -b32f4345517c3c7299a06489325bd85f987145dc data/create/advancements/recipes/building_blocks/cut_andesite_bricks_from_stone_types_andesite_stonecutting.json 22fe2e61d7e9836d9f71c39bfbba50efc2fa184d data/create/advancements/recipes/building_blocks/cut_andesite_brick_slab.json 6d8d28364f1016dfd1d7cbe4a2637e2b6224e4d8 data/create/advancements/recipes/building_blocks/cut_andesite_brick_slab_from_stone_types_andesite_stonecutting.json 39e904f66d2194de5437b5da2f8db8b6f03d78f4 data/create/advancements/recipes/building_blocks/cut_andesite_brick_slab_recycling.json @@ -2395,6 +2394,7 @@ b32f4345517c3c7299a06489325bd85f987145dc data/create/advancements/recipes/buildi 480c696956b99c96cbaf46e7dad9711c40680ec8 data/create/advancements/recipes/building_blocks/cut_andesite_brick_stairs_from_stone_types_andesite_stonecutting.json 8d504cdb99f5dc59bef5ff35d0b443f2f4ba21d2 data/create/advancements/recipes/building_blocks/cut_andesite_brick_wall.json e1b8e5906d54368c98867b83143dc7acc7b0aa28 data/create/advancements/recipes/building_blocks/cut_andesite_brick_wall_from_stone_types_andesite_stonecutting.json +b32f4345517c3c7299a06489325bd85f987145dc data/create/advancements/recipes/building_blocks/cut_andesite_bricks_from_stone_types_andesite_stonecutting.json d5b44158f9a98d874d941fc4df99de7a2657af21 data/create/advancements/recipes/building_blocks/cut_andesite_from_stone_types_andesite_stonecutting.json c11998f554bbd42efdbdf58cf8efe5bcf69230de data/create/advancements/recipes/building_blocks/cut_andesite_slab.json 1f457c0e816e4dd70e1a960015d2004814d11926 data/create/advancements/recipes/building_blocks/cut_andesite_slab_from_stone_types_andesite_stonecutting.json @@ -2403,7 +2403,6 @@ a4d7adf49472a2069bad72defd39b111b83def3d data/create/advancements/recipes/buildi 6d38bb2b9812761c594ebdf717284ba8d32e88bc data/create/advancements/recipes/building_blocks/cut_andesite_stairs_from_stone_types_andesite_stonecutting.json 2f6b2296b11e0e743d68749e65af5ffa0f374998 data/create/advancements/recipes/building_blocks/cut_andesite_wall.json caf3b1c62d0f8df3ce126535f0566c899577bedb data/create/advancements/recipes/building_blocks/cut_andesite_wall_from_stone_types_andesite_stonecutting.json -54188623046e989d21e6e155933e4084fb2882c4 data/create/advancements/recipes/building_blocks/cut_asurine_bricks_from_stone_types_asurine_stonecutting.json 536a2bed2ed1e7e249886ef376c96a8d5a1facdc data/create/advancements/recipes/building_blocks/cut_asurine_brick_slab.json a4e833cadfbb82222a70d66524e804c83ea13f7b data/create/advancements/recipes/building_blocks/cut_asurine_brick_slab_from_stone_types_asurine_stonecutting.json 610163ac2f4b06121931a81ac4b3df39ece61998 data/create/advancements/recipes/building_blocks/cut_asurine_brick_slab_recycling.json @@ -2411,6 +2410,7 @@ a4e833cadfbb82222a70d66524e804c83ea13f7b data/create/advancements/recipes/buildi f92f31e80cc026160217afb6c757987f75ed0b33 data/create/advancements/recipes/building_blocks/cut_asurine_brick_stairs_from_stone_types_asurine_stonecutting.json fa6dc7eaa32652a00a7217ae25967de0791088b6 data/create/advancements/recipes/building_blocks/cut_asurine_brick_wall.json 33f361369bfd92f53b3e40c837b336edd04a26e9 data/create/advancements/recipes/building_blocks/cut_asurine_brick_wall_from_stone_types_asurine_stonecutting.json +54188623046e989d21e6e155933e4084fb2882c4 data/create/advancements/recipes/building_blocks/cut_asurine_bricks_from_stone_types_asurine_stonecutting.json a6b871faa10badaaaa1a0ebbba94c4f2f627c43f data/create/advancements/recipes/building_blocks/cut_asurine_from_stone_types_asurine_stonecutting.json 719e1d4fea3457f2990be6a5d6cd87915d546217 data/create/advancements/recipes/building_blocks/cut_asurine_slab.json 586918291dda711c79941cf484cb62dbb853a271 data/create/advancements/recipes/building_blocks/cut_asurine_slab_from_stone_types_asurine_stonecutting.json @@ -2419,7 +2419,6 @@ bd2a630d242ae9c89b071b0401285068071a346c data/create/advancements/recipes/buildi 03d7b1609d161043e28661d74f53b06d4408f561 data/create/advancements/recipes/building_blocks/cut_asurine_stairs_from_stone_types_asurine_stonecutting.json cba4a6feaf695e665204cac36f9109ba941b12a6 data/create/advancements/recipes/building_blocks/cut_asurine_wall.json 3327651dd3f2fd778abdcfe70d25137d916f3def data/create/advancements/recipes/building_blocks/cut_asurine_wall_from_stone_types_asurine_stonecutting.json -44873f9d05abde7d52a6eacdf3573d8b69c69452 data/create/advancements/recipes/building_blocks/cut_calcite_bricks_from_stone_types_calcite_stonecutting.json a070ffe63c182b33c4c6faedb391f51a209c0e27 data/create/advancements/recipes/building_blocks/cut_calcite_brick_slab.json 7ba1e7add81422599f798153e4fd069e9fbfdebf data/create/advancements/recipes/building_blocks/cut_calcite_brick_slab_from_stone_types_calcite_stonecutting.json f5e80ec393c306485d666d6f9f91c55d9f1ba592 data/create/advancements/recipes/building_blocks/cut_calcite_brick_slab_recycling.json @@ -2427,6 +2426,7 @@ f5e80ec393c306485d666d6f9f91c55d9f1ba592 data/create/advancements/recipes/buildi 627f85aa63133cf95dd828092e0232b9ec8acfd5 data/create/advancements/recipes/building_blocks/cut_calcite_brick_stairs_from_stone_types_calcite_stonecutting.json d8870e522a68274cc90eab07ea17b7b6cdc5a16c data/create/advancements/recipes/building_blocks/cut_calcite_brick_wall.json cdf5927f3c1b3ef8904f38f66317412799e189fb data/create/advancements/recipes/building_blocks/cut_calcite_brick_wall_from_stone_types_calcite_stonecutting.json +44873f9d05abde7d52a6eacdf3573d8b69c69452 data/create/advancements/recipes/building_blocks/cut_calcite_bricks_from_stone_types_calcite_stonecutting.json 9f8c31b0db2aab8f1c8f42bcef15a74bc36887d4 data/create/advancements/recipes/building_blocks/cut_calcite_from_stone_types_calcite_stonecutting.json 857666ad1c6a5cc886f6896a18f560098afaa67b data/create/advancements/recipes/building_blocks/cut_calcite_slab.json c55074cd091b0e078105abdc940c62afa8984265 data/create/advancements/recipes/building_blocks/cut_calcite_slab_from_stone_types_calcite_stonecutting.json @@ -2435,7 +2435,6 @@ c55074cd091b0e078105abdc940c62afa8984265 data/create/advancements/recipes/buildi ba3378e1d08de2af0b2a725727cf9f68bda60044 data/create/advancements/recipes/building_blocks/cut_calcite_stairs_from_stone_types_calcite_stonecutting.json db5f4e1eee91c2a65d36164c20aba0e9d3a502ae data/create/advancements/recipes/building_blocks/cut_calcite_wall.json 19de370083d2cf1234c9c4e6ff45d85ef34a1ac8 data/create/advancements/recipes/building_blocks/cut_calcite_wall_from_stone_types_calcite_stonecutting.json -b9a2edda241f6e0677a2003300f0be5d3ff8f4b0 data/create/advancements/recipes/building_blocks/cut_crimsite_bricks_from_stone_types_crimsite_stonecutting.json 9fda0e6edde197a9c28a854419a2a07e323b6b53 data/create/advancements/recipes/building_blocks/cut_crimsite_brick_slab.json 2da3f139759be7eea552885b2063a0e2dfc647b1 data/create/advancements/recipes/building_blocks/cut_crimsite_brick_slab_from_stone_types_crimsite_stonecutting.json 62d928c8ab2e09a3f87adacb5adb1a5ddc1d2a7b data/create/advancements/recipes/building_blocks/cut_crimsite_brick_slab_recycling.json @@ -2443,6 +2442,7 @@ b9a2edda241f6e0677a2003300f0be5d3ff8f4b0 data/create/advancements/recipes/buildi 89850244feb8a3293ba96702b7a56a4bea84e1f3 data/create/advancements/recipes/building_blocks/cut_crimsite_brick_stairs_from_stone_types_crimsite_stonecutting.json 267cab789c73d474299542fb0719967501fcf0c9 data/create/advancements/recipes/building_blocks/cut_crimsite_brick_wall.json 27007676b86eb8a3498982d8b5e68495b84d62d5 data/create/advancements/recipes/building_blocks/cut_crimsite_brick_wall_from_stone_types_crimsite_stonecutting.json +b9a2edda241f6e0677a2003300f0be5d3ff8f4b0 data/create/advancements/recipes/building_blocks/cut_crimsite_bricks_from_stone_types_crimsite_stonecutting.json a88d252d4e634ff194daa3ff98fd7e965e3ed09a data/create/advancements/recipes/building_blocks/cut_crimsite_from_stone_types_crimsite_stonecutting.json f703136e1783a42252bc1d89c31e5563cbdff583 data/create/advancements/recipes/building_blocks/cut_crimsite_slab.json 3330d332462da22de48d07b62277c1df8e646a3e data/create/advancements/recipes/building_blocks/cut_crimsite_slab_from_stone_types_crimsite_stonecutting.json @@ -2451,7 +2451,6 @@ c2707e5969f0c554537dda9d3e2a4c13e19863c3 data/create/advancements/recipes/buildi e9ba513178090b020525e72468a0450e225da779 data/create/advancements/recipes/building_blocks/cut_crimsite_stairs_from_stone_types_crimsite_stonecutting.json 7fb5ce65b7b5c2d76b4306d407aaa6eefe07b7e5 data/create/advancements/recipes/building_blocks/cut_crimsite_wall.json a83d5b669f92bd833af2768d2cf5d4797a86b63c data/create/advancements/recipes/building_blocks/cut_crimsite_wall_from_stone_types_crimsite_stonecutting.json -bc9eb21df37df4b69e5d202b3b770698a16f4413 data/create/advancements/recipes/building_blocks/cut_deepslate_bricks_from_stone_types_deepslate_stonecutting.json 2c380e8ddc83cef4213f136ff7a196d861728914 data/create/advancements/recipes/building_blocks/cut_deepslate_brick_slab.json 87b5dfc1e61fabe4e7661bea0d7a56cb75197a81 data/create/advancements/recipes/building_blocks/cut_deepslate_brick_slab_from_stone_types_deepslate_stonecutting.json 09cde6df1120cc5f5f129023885f323b4d1eeae9 data/create/advancements/recipes/building_blocks/cut_deepslate_brick_slab_recycling.json @@ -2459,6 +2458,7 @@ bc9eb21df37df4b69e5d202b3b770698a16f4413 data/create/advancements/recipes/buildi 28e15fe2c377540cb631f6648f49090f234e7704 data/create/advancements/recipes/building_blocks/cut_deepslate_brick_stairs_from_stone_types_deepslate_stonecutting.json d2b34f455ab0053f24a4f9dec7dcce45832ef25b data/create/advancements/recipes/building_blocks/cut_deepslate_brick_wall.json 7b174b65b813b4a9ca507e71fa142931e074f336 data/create/advancements/recipes/building_blocks/cut_deepslate_brick_wall_from_stone_types_deepslate_stonecutting.json +bc9eb21df37df4b69e5d202b3b770698a16f4413 data/create/advancements/recipes/building_blocks/cut_deepslate_bricks_from_stone_types_deepslate_stonecutting.json 83db3f5b46c996481b930974bddba75c82c115af data/create/advancements/recipes/building_blocks/cut_deepslate_from_stone_types_deepslate_stonecutting.json 8e8816aad8212c3557e77cc01df551fe1a0a306d data/create/advancements/recipes/building_blocks/cut_deepslate_slab.json 14ea447072200733dd9551a5ac6a9544593dd9f7 data/create/advancements/recipes/building_blocks/cut_deepslate_slab_from_stone_types_deepslate_stonecutting.json @@ -2467,7 +2467,6 @@ c7870abb459c8b174c380282ae211a87ab252521 data/create/advancements/recipes/buildi 4f157401a3019c96cc6ae5a0036f31351c651fbb data/create/advancements/recipes/building_blocks/cut_deepslate_stairs_from_stone_types_deepslate_stonecutting.json 9ae9635fa129aab54a7ec971b9cc61d300d3d53e data/create/advancements/recipes/building_blocks/cut_deepslate_wall.json 9b5df53000c79a7b20e3a1888e003b704809feda data/create/advancements/recipes/building_blocks/cut_deepslate_wall_from_stone_types_deepslate_stonecutting.json -fdef99789ca74623b00b05be2f975b63831645db data/create/advancements/recipes/building_blocks/cut_diorite_bricks_from_stone_types_diorite_stonecutting.json 30a00465dc9b19d8024146e2c2d6b9f41562da30 data/create/advancements/recipes/building_blocks/cut_diorite_brick_slab.json a55e7daf48a487d74b4a01e30b80968094154d2b data/create/advancements/recipes/building_blocks/cut_diorite_brick_slab_from_stone_types_diorite_stonecutting.json e445a3d8fd00f5e4f2ee56c797d8abf548598447 data/create/advancements/recipes/building_blocks/cut_diorite_brick_slab_recycling.json @@ -2475,6 +2474,7 @@ b421f24513612dd7a5d8977d7bff122fd5cf9522 data/create/advancements/recipes/buildi 3fe00adac35beeda79b7f9d930a1f13b033c0f12 data/create/advancements/recipes/building_blocks/cut_diorite_brick_stairs_from_stone_types_diorite_stonecutting.json 6d2235b8587863107a6d1a0818c81ee3dc217cdf data/create/advancements/recipes/building_blocks/cut_diorite_brick_wall.json 0ec4b69e98adf961f5d4d63700f11ad66a4116b5 data/create/advancements/recipes/building_blocks/cut_diorite_brick_wall_from_stone_types_diorite_stonecutting.json +fdef99789ca74623b00b05be2f975b63831645db data/create/advancements/recipes/building_blocks/cut_diorite_bricks_from_stone_types_diorite_stonecutting.json c9f52e0661fdc266f8429faf1570124fecfa2d6a data/create/advancements/recipes/building_blocks/cut_diorite_from_stone_types_diorite_stonecutting.json c7b73ddec6402e8b5ff5daedbbbc74f882338a8e data/create/advancements/recipes/building_blocks/cut_diorite_slab.json 46c841e5aae99106cbc28026dcfec946976127e5 data/create/advancements/recipes/building_blocks/cut_diorite_slab_from_stone_types_diorite_stonecutting.json @@ -2483,7 +2483,6 @@ ce67a5fae622955ad795e2b3d14c159a4c47b936 data/create/advancements/recipes/buildi 3b7ec28df80ea9cf87980b2c2184858ba6152a3f data/create/advancements/recipes/building_blocks/cut_diorite_stairs_from_stone_types_diorite_stonecutting.json c8fe9ab53eda2cdbff08678ebb577c169ea61a91 data/create/advancements/recipes/building_blocks/cut_diorite_wall.json 050f67b5a662bea3ef972521ef7f81c2ba99015c data/create/advancements/recipes/building_blocks/cut_diorite_wall_from_stone_types_diorite_stonecutting.json -b60683fdd629b201f40a6f9bb6594df7c5ac13f1 data/create/advancements/recipes/building_blocks/cut_dripstone_bricks_from_stone_types_dripstone_stonecutting.json 1e0d39ed56e2ab4eac084f26a1c6de905db29220 data/create/advancements/recipes/building_blocks/cut_dripstone_brick_slab.json 020cbc4c8063d186d3f5c9ece429e4cdff53cf63 data/create/advancements/recipes/building_blocks/cut_dripstone_brick_slab_from_stone_types_dripstone_stonecutting.json b44c9e7f9f62ffffb5566901e0a22010ba76641c data/create/advancements/recipes/building_blocks/cut_dripstone_brick_slab_recycling.json @@ -2491,6 +2490,7 @@ b44c9e7f9f62ffffb5566901e0a22010ba76641c data/create/advancements/recipes/buildi 466fbdf7de8dacd1032fb7af690862bb68707876 data/create/advancements/recipes/building_blocks/cut_dripstone_brick_stairs_from_stone_types_dripstone_stonecutting.json 253b54c191c933e88fa6a9b4e7c94340082c7d60 data/create/advancements/recipes/building_blocks/cut_dripstone_brick_wall.json e176568e3de8b8ca17a788f4cea89002b5ad2d1d data/create/advancements/recipes/building_blocks/cut_dripstone_brick_wall_from_stone_types_dripstone_stonecutting.json +b60683fdd629b201f40a6f9bb6594df7c5ac13f1 data/create/advancements/recipes/building_blocks/cut_dripstone_bricks_from_stone_types_dripstone_stonecutting.json ddc5a16cf0d2790d8133ab6801f4c55317d776e4 data/create/advancements/recipes/building_blocks/cut_dripstone_from_stone_types_dripstone_stonecutting.json 6e40c9af0747a8b3adb805ddd8fbb947aedb408c data/create/advancements/recipes/building_blocks/cut_dripstone_slab.json e7761f71f797d2e62dc0860cbd5153955b9be86c data/create/advancements/recipes/building_blocks/cut_dripstone_slab_from_stone_types_dripstone_stonecutting.json @@ -2499,7 +2499,6 @@ a199a9f78a44f4313a922b317893c68f743dc1a9 data/create/advancements/recipes/buildi b68a95a565ee9a3aec017431aa5b8cc6fffec3ef data/create/advancements/recipes/building_blocks/cut_dripstone_stairs_from_stone_types_dripstone_stonecutting.json a4287f34f95c008bdf7c0a886d05c3960665147b data/create/advancements/recipes/building_blocks/cut_dripstone_wall.json 76f5d4a6a9895064b15ae0c0f27a138bb3d57dbf data/create/advancements/recipes/building_blocks/cut_dripstone_wall_from_stone_types_dripstone_stonecutting.json -24cc01d592faf2bad57fc9b9a1de52c50d225446 data/create/advancements/recipes/building_blocks/cut_granite_bricks_from_stone_types_granite_stonecutting.json 83148f66dc7418740b6f9b6a660b0b9306d87f7c data/create/advancements/recipes/building_blocks/cut_granite_brick_slab.json d982802fc11848c87022f7bf05cecf090953002a data/create/advancements/recipes/building_blocks/cut_granite_brick_slab_from_stone_types_granite_stonecutting.json 6b8fa161725a4e2106226c3591a23def74398f48 data/create/advancements/recipes/building_blocks/cut_granite_brick_slab_recycling.json @@ -2507,6 +2506,7 @@ ce1c81b730b3acef9673f41769339f7d68385348 data/create/advancements/recipes/buildi e9732e3beaefbc6a457e0c4fd61f17f429f1cd8c data/create/advancements/recipes/building_blocks/cut_granite_brick_stairs_from_stone_types_granite_stonecutting.json 4f403aee2aae6aa0fc334b434cf5ade362153329 data/create/advancements/recipes/building_blocks/cut_granite_brick_wall.json 625c8849b5c07835b49dcb4322ec44586628a700 data/create/advancements/recipes/building_blocks/cut_granite_brick_wall_from_stone_types_granite_stonecutting.json +24cc01d592faf2bad57fc9b9a1de52c50d225446 data/create/advancements/recipes/building_blocks/cut_granite_bricks_from_stone_types_granite_stonecutting.json 07e6f3835c3683f007fd25140d671b668706484d data/create/advancements/recipes/building_blocks/cut_granite_from_stone_types_granite_stonecutting.json 2f33b7f82e977eb3fd0e0283313b1066eadadd18 data/create/advancements/recipes/building_blocks/cut_granite_slab.json a1b406ca98c2ba7d5225afea8463d586fc538428 data/create/advancements/recipes/building_blocks/cut_granite_slab_from_stone_types_granite_stonecutting.json @@ -2515,7 +2515,6 @@ af12a2d8f8bb2382f55135df8cfec00692a65fe3 data/create/advancements/recipes/buildi 284087e07acd28aa869d5433375e412f083108e9 data/create/advancements/recipes/building_blocks/cut_granite_stairs_from_stone_types_granite_stonecutting.json dbfb50c3d5048b1f5d8d74f39c389ecec81392d7 data/create/advancements/recipes/building_blocks/cut_granite_wall.json 6b287be7a900dbd715290b069a89ab226d6cec9c data/create/advancements/recipes/building_blocks/cut_granite_wall_from_stone_types_granite_stonecutting.json -4ef0a018dcf0b470061a4b1dbadc27684d8d467f data/create/advancements/recipes/building_blocks/cut_limestone_bricks_from_stone_types_limestone_stonecutting.json b0ade7dab7eb095f07882e4c19884162f18e704c data/create/advancements/recipes/building_blocks/cut_limestone_brick_slab.json 4fc2dc61d62a394cebc91e36745699eeaee650e7 data/create/advancements/recipes/building_blocks/cut_limestone_brick_slab_from_stone_types_limestone_stonecutting.json b8ec42f06ce9eb696643154d16150a223bd5ec65 data/create/advancements/recipes/building_blocks/cut_limestone_brick_slab_recycling.json @@ -2523,6 +2522,7 @@ d0b19c27309cd45d08a6a0cd779f1930bc2e7469 data/create/advancements/recipes/buildi 9f65617405592d587a940ff7513fcb34ca6ab423 data/create/advancements/recipes/building_blocks/cut_limestone_brick_stairs_from_stone_types_limestone_stonecutting.json 281e2ddcb58b603dea8f305ed6c8ddea98d0d030 data/create/advancements/recipes/building_blocks/cut_limestone_brick_wall.json 7b0ab5095a7d2b3e876a8c8b990161851c1c58c2 data/create/advancements/recipes/building_blocks/cut_limestone_brick_wall_from_stone_types_limestone_stonecutting.json +4ef0a018dcf0b470061a4b1dbadc27684d8d467f data/create/advancements/recipes/building_blocks/cut_limestone_bricks_from_stone_types_limestone_stonecutting.json f8663a45d71c52a3982c75bbfb61653c8d2fd668 data/create/advancements/recipes/building_blocks/cut_limestone_from_stone_types_limestone_stonecutting.json 9e22972cd4f2d673cfcf07a597f6a14402c91913 data/create/advancements/recipes/building_blocks/cut_limestone_slab.json 388a57bb88582eda9fef904a530f72b066d24e7d data/create/advancements/recipes/building_blocks/cut_limestone_slab_from_stone_types_limestone_stonecutting.json @@ -2531,7 +2531,6 @@ f8663a45d71c52a3982c75bbfb61653c8d2fd668 data/create/advancements/recipes/buildi b6dc46dca3fc039fd0fe53ab791731cb085c3b62 data/create/advancements/recipes/building_blocks/cut_limestone_stairs_from_stone_types_limestone_stonecutting.json a9382d5f876542bf4fa8aed605352daca4ad2f6f data/create/advancements/recipes/building_blocks/cut_limestone_wall.json 69d9116786c53cb3155bed4580d4b01bfe638243 data/create/advancements/recipes/building_blocks/cut_limestone_wall_from_stone_types_limestone_stonecutting.json -1f8ee1a91937295484d5c2fe0186a617589c1761 data/create/advancements/recipes/building_blocks/cut_ochrum_bricks_from_stone_types_ochrum_stonecutting.json a51d6ebed8e21e8808ccfbe9f9540291504da59a data/create/advancements/recipes/building_blocks/cut_ochrum_brick_slab.json eb08f00651259f83f6eced0f90dd8df0e9d0d508 data/create/advancements/recipes/building_blocks/cut_ochrum_brick_slab_from_stone_types_ochrum_stonecutting.json a189e0549723cefbd19a147274cd79909dca2b70 data/create/advancements/recipes/building_blocks/cut_ochrum_brick_slab_recycling.json @@ -2539,6 +2538,7 @@ a5dc9e74ad0d18d83bad3aab8c5e2768355a2370 data/create/advancements/recipes/buildi 27a5331727199b8b8f2dd6c581e25d17d12fc1ba data/create/advancements/recipes/building_blocks/cut_ochrum_brick_stairs_from_stone_types_ochrum_stonecutting.json 648e532441c664310047c5c9c78833d2eaea5920 data/create/advancements/recipes/building_blocks/cut_ochrum_brick_wall.json 053256b7b154ba5c10d2483d86658f132296e8f5 data/create/advancements/recipes/building_blocks/cut_ochrum_brick_wall_from_stone_types_ochrum_stonecutting.json +1f8ee1a91937295484d5c2fe0186a617589c1761 data/create/advancements/recipes/building_blocks/cut_ochrum_bricks_from_stone_types_ochrum_stonecutting.json 6abb6e36229685ca26ee31b5db3074a07453435e data/create/advancements/recipes/building_blocks/cut_ochrum_from_stone_types_ochrum_stonecutting.json 0c5e92fb20048fe5d9dcd42e10fd0f9b155c385a data/create/advancements/recipes/building_blocks/cut_ochrum_slab.json 941aba0ff7967d7ea56e1f811aa6bc34d4711796 data/create/advancements/recipes/building_blocks/cut_ochrum_slab_from_stone_types_ochrum_stonecutting.json @@ -2547,7 +2547,6 @@ fa14009e4de8cfdacdbb7679473ce359f2cb85be data/create/advancements/recipes/buildi d50accd7f37bfd9384790bdd727401757f6dc7e4 data/create/advancements/recipes/building_blocks/cut_ochrum_stairs_from_stone_types_ochrum_stonecutting.json ed0a72f6393c0d16240b89241f5bbac7dc003516 data/create/advancements/recipes/building_blocks/cut_ochrum_wall.json cda838f95015b0bf02fc5427e1a69ed6302b7e20 data/create/advancements/recipes/building_blocks/cut_ochrum_wall_from_stone_types_ochrum_stonecutting.json -a51cd5a82d9b30c8a68f7cdf8dd7a6b2f883c27c data/create/advancements/recipes/building_blocks/cut_scorchia_bricks_from_stone_types_scorchia_stonecutting.json ce33e5a98a83dae1f37ad4b3d4ea148de5bcacdf data/create/advancements/recipes/building_blocks/cut_scorchia_brick_slab.json 498825e9e5502a7ec8a1f23bfe998b960d7fc9eb data/create/advancements/recipes/building_blocks/cut_scorchia_brick_slab_from_stone_types_scorchia_stonecutting.json 8ffa08b1b4e4ab37dfbf09d2ec4a37f93c9503cb data/create/advancements/recipes/building_blocks/cut_scorchia_brick_slab_recycling.json @@ -2555,6 +2554,7 @@ ce33e5a98a83dae1f37ad4b3d4ea148de5bcacdf data/create/advancements/recipes/buildi 3c4b45560f446534821da63d4e713088928e5f4a data/create/advancements/recipes/building_blocks/cut_scorchia_brick_stairs_from_stone_types_scorchia_stonecutting.json 2aba76185175fff82898a7a905d3ec4ff448deaa data/create/advancements/recipes/building_blocks/cut_scorchia_brick_wall.json ca1f54af4425df994c6707f00e43b8db3ce66280 data/create/advancements/recipes/building_blocks/cut_scorchia_brick_wall_from_stone_types_scorchia_stonecutting.json +a51cd5a82d9b30c8a68f7cdf8dd7a6b2f883c27c data/create/advancements/recipes/building_blocks/cut_scorchia_bricks_from_stone_types_scorchia_stonecutting.json df847f312960866d3d53f48297ea3169c27314eb data/create/advancements/recipes/building_blocks/cut_scorchia_from_stone_types_scorchia_stonecutting.json 8095f7be8aac4f11d618549680d537bed8a921c5 data/create/advancements/recipes/building_blocks/cut_scorchia_slab.json a53831cf7f095fa4d0d92051bd0e21f912c2d9dd data/create/advancements/recipes/building_blocks/cut_scorchia_slab_from_stone_types_scorchia_stonecutting.json @@ -2563,7 +2563,6 @@ a53831cf7f095fa4d0d92051bd0e21f912c2d9dd data/create/advancements/recipes/buildi 30f1efaa46771dd22d7f3aa34f24c69bbdb59bd5 data/create/advancements/recipes/building_blocks/cut_scorchia_stairs_from_stone_types_scorchia_stonecutting.json e02d188d64b270682fa9d335a3423880d8358a0d data/create/advancements/recipes/building_blocks/cut_scorchia_wall.json 834c5a2a8d089822fa81a75b290818db276beab7 data/create/advancements/recipes/building_blocks/cut_scorchia_wall_from_stone_types_scorchia_stonecutting.json -2030ec21c96336bd4c4040857f40ec65d1a75075 data/create/advancements/recipes/building_blocks/cut_scoria_bricks_from_stone_types_scoria_stonecutting.json 705dfcd9f4b6b8a0c360436c097cb371c27cf60d data/create/advancements/recipes/building_blocks/cut_scoria_brick_slab.json 482cf1bbb65a4facc0ebf31ea91bab4d03580635 data/create/advancements/recipes/building_blocks/cut_scoria_brick_slab_from_stone_types_scoria_stonecutting.json 51d070acfc8ad4cd8ca4457ca346458c81eaade4 data/create/advancements/recipes/building_blocks/cut_scoria_brick_slab_recycling.json @@ -2571,6 +2570,7 @@ e02d188d64b270682fa9d335a3423880d8358a0d data/create/advancements/recipes/buildi 99ca117e6a4ad242d92566a2f398c28edb3b7061 data/create/advancements/recipes/building_blocks/cut_scoria_brick_stairs_from_stone_types_scoria_stonecutting.json 01e294976d8ce71b59fb14a47e2686bdce4fab21 data/create/advancements/recipes/building_blocks/cut_scoria_brick_wall.json 0c1d31d37a17d4bd752508022ddd9690bb92a521 data/create/advancements/recipes/building_blocks/cut_scoria_brick_wall_from_stone_types_scoria_stonecutting.json +2030ec21c96336bd4c4040857f40ec65d1a75075 data/create/advancements/recipes/building_blocks/cut_scoria_bricks_from_stone_types_scoria_stonecutting.json 41f420c88dbf61d3cb51966cca9b495d10c604d3 data/create/advancements/recipes/building_blocks/cut_scoria_from_stone_types_scoria_stonecutting.json 26c8447854e29243f0697236f59e258fa96ed369 data/create/advancements/recipes/building_blocks/cut_scoria_slab.json f3e2522664de4ff2ad92a89443e064ac857b7aef data/create/advancements/recipes/building_blocks/cut_scoria_slab_from_stone_types_scoria_stonecutting.json @@ -2579,7 +2579,6 @@ a0635452fd698415e8112e9e0f6d71571901ca34 data/create/advancements/recipes/buildi 1bb047298b71a57e8632607af7b17bab2690aecb data/create/advancements/recipes/building_blocks/cut_scoria_stairs_from_stone_types_scoria_stonecutting.json a33878fe778438a746a28c1fd03ca6d01092ebe4 data/create/advancements/recipes/building_blocks/cut_scoria_wall.json 74a637d0d0f360ad692661c0213c18a06a8ec500 data/create/advancements/recipes/building_blocks/cut_scoria_wall_from_stone_types_scoria_stonecutting.json -f0870d596d9ac9e5b5272fb4e3d2c90c29f3a63d data/create/advancements/recipes/building_blocks/cut_tuff_bricks_from_stone_types_tuff_stonecutting.json b75410afdb8775b2a834ded315913e0ae38e4df8 data/create/advancements/recipes/building_blocks/cut_tuff_brick_slab.json 34c2aead2f2355a8f0f9f9aa7dba58dd5187dbba data/create/advancements/recipes/building_blocks/cut_tuff_brick_slab_from_stone_types_tuff_stonecutting.json c071c43e93cc1735bebbbf320f1b8d2cba4be1e3 data/create/advancements/recipes/building_blocks/cut_tuff_brick_slab_recycling.json @@ -2587,6 +2586,7 @@ c89ec2300425688f9e72e45c64def0b09c0219b0 data/create/advancements/recipes/buildi c882f72f5a31bc92a8186834b105a2e07d864366 data/create/advancements/recipes/building_blocks/cut_tuff_brick_stairs_from_stone_types_tuff_stonecutting.json 70295775a6170a1332f5604aaf75a026630c9e93 data/create/advancements/recipes/building_blocks/cut_tuff_brick_wall.json 1b79d0e71dae77967c1554c203e68eeb51fe8054 data/create/advancements/recipes/building_blocks/cut_tuff_brick_wall_from_stone_types_tuff_stonecutting.json +f0870d596d9ac9e5b5272fb4e3d2c90c29f3a63d data/create/advancements/recipes/building_blocks/cut_tuff_bricks_from_stone_types_tuff_stonecutting.json 549d1f911c009a3cafff4edcb37116c92c2b8e21 data/create/advancements/recipes/building_blocks/cut_tuff_from_stone_types_tuff_stonecutting.json 5bc3e40a8e50a521ebd5fa58efa3ec21064163f7 data/create/advancements/recipes/building_blocks/cut_tuff_slab.json f1ab5be6cb7287517d87b173680ddf833a1dd534 data/create/advancements/recipes/building_blocks/cut_tuff_slab_from_stone_types_tuff_stonecutting.json @@ -2595,7 +2595,6 @@ b7d19085017530f0c2122511c35dbef6a50b337f data/create/advancements/recipes/buildi 3c9541b6e4eb8ff7f7b627a75e8c38ed9eeaf342 data/create/advancements/recipes/building_blocks/cut_tuff_stairs_from_stone_types_tuff_stonecutting.json 51ca798b8bd822ddbbfe8f07073eefb948b97b42 data/create/advancements/recipes/building_blocks/cut_tuff_wall.json 1aa1a0d00c19069f0c55e698b474115d7f437355 data/create/advancements/recipes/building_blocks/cut_tuff_wall_from_stone_types_tuff_stonecutting.json -6a80920618d8e9b7919c83c419e751971440d38a data/create/advancements/recipes/building_blocks/cut_veridium_bricks_from_stone_types_veridium_stonecutting.json e263f555c3a47c83187d29ae9b816edc0c1a763b data/create/advancements/recipes/building_blocks/cut_veridium_brick_slab.json f0e84bde804e52f504cd93bee5058a89f6939dc9 data/create/advancements/recipes/building_blocks/cut_veridium_brick_slab_from_stone_types_veridium_stonecutting.json 949fe819c76fd63edfd93bef5898119c8456fda3 data/create/advancements/recipes/building_blocks/cut_veridium_brick_slab_recycling.json @@ -2603,6 +2602,7 @@ fc87560dedbc951d10d9650a6f27192e7c3a1cc5 data/create/advancements/recipes/buildi 35b09d6300ff8e86f01bc0258fca5cfa80d55c61 data/create/advancements/recipes/building_blocks/cut_veridium_brick_stairs_from_stone_types_veridium_stonecutting.json 599d9ce510531c6006a4964bb4049a850a8457ee data/create/advancements/recipes/building_blocks/cut_veridium_brick_wall.json aaaad7a65a1c05071565ca91a181ff3c375e0141 data/create/advancements/recipes/building_blocks/cut_veridium_brick_wall_from_stone_types_veridium_stonecutting.json +6a80920618d8e9b7919c83c419e751971440d38a data/create/advancements/recipes/building_blocks/cut_veridium_bricks_from_stone_types_veridium_stonecutting.json c76ae7944646e8f13ea460ba6655b95b6c2798ea data/create/advancements/recipes/building_blocks/cut_veridium_from_stone_types_veridium_stonecutting.json 3bafa8873b62cb0333b44af77f2c6e824c5b3e95 data/create/advancements/recipes/building_blocks/cut_veridium_slab.json 143f64b0e5536693262f6a62c2a6fbf85bd4203e data/create/advancements/recipes/building_blocks/cut_veridium_slab_from_stone_types_veridium_stonecutting.json @@ -2786,7 +2786,6 @@ c4c087911453bd979e028d3b3558b273e3cb5926 data/create/advancements/recipes/buildi 780bb3d13fcd8abf6e166b04566b141e023ee11e data/create/advancements/recipes/building_blocks/scorchia_pillar_from_stone_types_scorchia_stonecutting.json 5c5c5080c1136c046caee2d14dd2c3c9f09abad3 data/create/advancements/recipes/building_blocks/scoria_from_stone_types_scoria_stonecutting.json 5a6b12869ffcbd1d9b4fbe1fee444fcde95d2953 data/create/advancements/recipes/building_blocks/scoria_pillar_from_stone_types_scoria_stonecutting.json -a51ca3151c517113338720edeac0e02a46ebb03a data/create/advancements/recipes/building_blocks/small_andesite_bricks_from_stone_types_andesite_stonecutting.json f72093994236a0580c6cafd08fb42f061733de01 data/create/advancements/recipes/building_blocks/small_andesite_brick_slab.json 05092201e6c514d3eae566fb1ce98ad415660112 data/create/advancements/recipes/building_blocks/small_andesite_brick_slab_from_stone_types_andesite_stonecutting.json 0e41d75b613a0ebd0c023669dcfd34f11b14fd0e data/create/advancements/recipes/building_blocks/small_andesite_brick_slab_recycling.json @@ -2794,7 +2793,7 @@ f72093994236a0580c6cafd08fb42f061733de01 data/create/advancements/recipes/buildi 8bbf898cbc47ac7a326c0d082a92a452b6915a7e data/create/advancements/recipes/building_blocks/small_andesite_brick_stairs_from_stone_types_andesite_stonecutting.json 9e0685dd668550c67812d1caccd8c8cae9f2041c data/create/advancements/recipes/building_blocks/small_andesite_brick_wall.json 7a1bfa848f950482f82d7fe7a9cf3cf916f91702 data/create/advancements/recipes/building_blocks/small_andesite_brick_wall_from_stone_types_andesite_stonecutting.json -0bfa788d0038077a88678ff16104a8b82038b3da data/create/advancements/recipes/building_blocks/small_asurine_bricks_from_stone_types_asurine_stonecutting.json +a51ca3151c517113338720edeac0e02a46ebb03a data/create/advancements/recipes/building_blocks/small_andesite_bricks_from_stone_types_andesite_stonecutting.json 3dccee988c08e1988886d9f09f2b5b42332ac083 data/create/advancements/recipes/building_blocks/small_asurine_brick_slab.json 438469fb06dff95a0ab9e0cb183795432d9b78dd data/create/advancements/recipes/building_blocks/small_asurine_brick_slab_from_stone_types_asurine_stonecutting.json 3eb65706d975e6f1e429f43d7384272a58872f10 data/create/advancements/recipes/building_blocks/small_asurine_brick_slab_recycling.json @@ -2802,7 +2801,7 @@ fb8cab1a3ecef97eaf7d744bb0d1d09d46859b60 data/create/advancements/recipes/buildi 525fff52f5dea3178356b7c5f7606d2a369b346e data/create/advancements/recipes/building_blocks/small_asurine_brick_stairs_from_stone_types_asurine_stonecutting.json 39df7ef2b88df45ba4a06bfa9cd7f863f813cb30 data/create/advancements/recipes/building_blocks/small_asurine_brick_wall.json 21aa9dc72b12eb0a33cdc9904ee595de802b55f4 data/create/advancements/recipes/building_blocks/small_asurine_brick_wall_from_stone_types_asurine_stonecutting.json -46666ef8d341971cdd989f14575973777a85cdc6 data/create/advancements/recipes/building_blocks/small_calcite_bricks_from_stone_types_calcite_stonecutting.json +0bfa788d0038077a88678ff16104a8b82038b3da data/create/advancements/recipes/building_blocks/small_asurine_bricks_from_stone_types_asurine_stonecutting.json d61fce64a295a2c3b9433bc27ac50f4f1f6a678d data/create/advancements/recipes/building_blocks/small_calcite_brick_slab.json 7f2e73d01b9bff473c4ecf76ab967b3aa934ff87 data/create/advancements/recipes/building_blocks/small_calcite_brick_slab_from_stone_types_calcite_stonecutting.json 1095487af055116acc2eba87d92dd0918385e9ac data/create/advancements/recipes/building_blocks/small_calcite_brick_slab_recycling.json @@ -2810,7 +2809,7 @@ d61fce64a295a2c3b9433bc27ac50f4f1f6a678d data/create/advancements/recipes/buildi e3bd0900dc92b26fe69c7f4e81db76678505222b data/create/advancements/recipes/building_blocks/small_calcite_brick_stairs_from_stone_types_calcite_stonecutting.json c88fb3af07c32aa127cbe0043075f50fed869839 data/create/advancements/recipes/building_blocks/small_calcite_brick_wall.json ea58b78e177134c73ed5bfb081761f90cc7caa3e data/create/advancements/recipes/building_blocks/small_calcite_brick_wall_from_stone_types_calcite_stonecutting.json -c48216f26cfe93ce99f7f2f0e9f68d1ee2a95e46 data/create/advancements/recipes/building_blocks/small_crimsite_bricks_from_stone_types_crimsite_stonecutting.json +46666ef8d341971cdd989f14575973777a85cdc6 data/create/advancements/recipes/building_blocks/small_calcite_bricks_from_stone_types_calcite_stonecutting.json ed4d6e7779749dd647f744f0486e78b93057aa33 data/create/advancements/recipes/building_blocks/small_crimsite_brick_slab.json 7f3ad6d79eb9d433d5a0e295eb2b099a5f815876 data/create/advancements/recipes/building_blocks/small_crimsite_brick_slab_from_stone_types_crimsite_stonecutting.json b980fcc4b29f9ff897dd867222fc4248d76e808a data/create/advancements/recipes/building_blocks/small_crimsite_brick_slab_recycling.json @@ -2818,7 +2817,7 @@ b980fcc4b29f9ff897dd867222fc4248d76e808a data/create/advancements/recipes/buildi c06600eda4e4bd7c46e4e315a0569fbdfa4bb087 data/create/advancements/recipes/building_blocks/small_crimsite_brick_stairs_from_stone_types_crimsite_stonecutting.json 4021a4a761b06def09f19d6a60bc0722e69ec08d data/create/advancements/recipes/building_blocks/small_crimsite_brick_wall.json 2d8eae517a914e93538307efe23d532582d487e2 data/create/advancements/recipes/building_blocks/small_crimsite_brick_wall_from_stone_types_crimsite_stonecutting.json -ed82f0fac452147faa997af1d45278f501ef165b data/create/advancements/recipes/building_blocks/small_deepslate_bricks_from_stone_types_deepslate_stonecutting.json +c48216f26cfe93ce99f7f2f0e9f68d1ee2a95e46 data/create/advancements/recipes/building_blocks/small_crimsite_bricks_from_stone_types_crimsite_stonecutting.json e4674821cc17adadecacc55d48c028847caf5fea data/create/advancements/recipes/building_blocks/small_deepslate_brick_slab.json 8c0c51d052b110fec3668618be2bdeaf8d0c7cc5 data/create/advancements/recipes/building_blocks/small_deepslate_brick_slab_from_stone_types_deepslate_stonecutting.json f8f7ace802b6c73fabfabbaae1c1383a3c0bcf6b data/create/advancements/recipes/building_blocks/small_deepslate_brick_slab_recycling.json @@ -2826,7 +2825,7 @@ e2e16c3c0e761ef44f9b21ae3bd95300a33459be data/create/advancements/recipes/buildi 37ef4192f1db7dd5c066a47480f86f60687c9894 data/create/advancements/recipes/building_blocks/small_deepslate_brick_stairs_from_stone_types_deepslate_stonecutting.json 6f4d365ce26fb4081a5af0f6e21631209b5b106d data/create/advancements/recipes/building_blocks/small_deepslate_brick_wall.json e0c7377c55dc94b8efd62cb6f57325c94206cbf4 data/create/advancements/recipes/building_blocks/small_deepslate_brick_wall_from_stone_types_deepslate_stonecutting.json -9bb23924495112ba177d12ba2a5adcb872a2b76f data/create/advancements/recipes/building_blocks/small_diorite_bricks_from_stone_types_diorite_stonecutting.json +ed82f0fac452147faa997af1d45278f501ef165b data/create/advancements/recipes/building_blocks/small_deepslate_bricks_from_stone_types_deepslate_stonecutting.json d4b96bcd8902e9bce19603abb99cb7edeb260189 data/create/advancements/recipes/building_blocks/small_diorite_brick_slab.json 2ed3800996491c9a1db23d9cbed04cc5ee963df6 data/create/advancements/recipes/building_blocks/small_diorite_brick_slab_from_stone_types_diorite_stonecutting.json 895d2158ba0783c5fd97b802ef5866d7532df6ba data/create/advancements/recipes/building_blocks/small_diorite_brick_slab_recycling.json @@ -2834,7 +2833,7 @@ d4b96bcd8902e9bce19603abb99cb7edeb260189 data/create/advancements/recipes/buildi 0f4b92965c05ddf71fa24b2b08a0cce358ac8dd1 data/create/advancements/recipes/building_blocks/small_diorite_brick_stairs_from_stone_types_diorite_stonecutting.json 633d921515fb4ad0e3177f3c8f151da80008053b data/create/advancements/recipes/building_blocks/small_diorite_brick_wall.json 3dea60492331bcd3253d90534559cc0bdb0822ae data/create/advancements/recipes/building_blocks/small_diorite_brick_wall_from_stone_types_diorite_stonecutting.json -632ced3760d55b56d1620e447b8b762e0e4a29f3 data/create/advancements/recipes/building_blocks/small_dripstone_bricks_from_stone_types_dripstone_stonecutting.json +9bb23924495112ba177d12ba2a5adcb872a2b76f data/create/advancements/recipes/building_blocks/small_diorite_bricks_from_stone_types_diorite_stonecutting.json 92bb21a400d9720a2f06882049d5b3863a93969d data/create/advancements/recipes/building_blocks/small_dripstone_brick_slab.json 02e2b98eeef9cdc20a8678beec4c7aa8a6cde948 data/create/advancements/recipes/building_blocks/small_dripstone_brick_slab_from_stone_types_dripstone_stonecutting.json 35830242bc48b1355830d6cb17dc4dc547d51bc0 data/create/advancements/recipes/building_blocks/small_dripstone_brick_slab_recycling.json @@ -2842,7 +2841,7 @@ d4b96bcd8902e9bce19603abb99cb7edeb260189 data/create/advancements/recipes/buildi 92523f3058a580743f95e9347fa97e0f5f6483f6 data/create/advancements/recipes/building_blocks/small_dripstone_brick_stairs_from_stone_types_dripstone_stonecutting.json 6e26ab4ad96225b7dd1a4aa06295b0d85e87400b data/create/advancements/recipes/building_blocks/small_dripstone_brick_wall.json e30a5f31d6478dfe7693077727b1abfc40b33f9b data/create/advancements/recipes/building_blocks/small_dripstone_brick_wall_from_stone_types_dripstone_stonecutting.json -1805b7f9db21b4530b173ab6945584e7d852b218 data/create/advancements/recipes/building_blocks/small_granite_bricks_from_stone_types_granite_stonecutting.json +632ced3760d55b56d1620e447b8b762e0e4a29f3 data/create/advancements/recipes/building_blocks/small_dripstone_bricks_from_stone_types_dripstone_stonecutting.json a2929bbd4c81b9601aeca74110936343102b7b5a data/create/advancements/recipes/building_blocks/small_granite_brick_slab.json 0fa83c337d5612e2b8368d5bff34117e0c1cf40a data/create/advancements/recipes/building_blocks/small_granite_brick_slab_from_stone_types_granite_stonecutting.json 0bc47cb22cc70a34879092a57c87551e6fa9f634 data/create/advancements/recipes/building_blocks/small_granite_brick_slab_recycling.json @@ -2850,7 +2849,7 @@ a2929bbd4c81b9601aeca74110936343102b7b5a data/create/advancements/recipes/buildi 44f3e71a4e8b78db74a21a42c3cebfbc15fe0180 data/create/advancements/recipes/building_blocks/small_granite_brick_stairs_from_stone_types_granite_stonecutting.json 3a6edafcb559e767caf421cf1bd6e064940f33e2 data/create/advancements/recipes/building_blocks/small_granite_brick_wall.json cac9914c729c0ecf5e9e1b4fe6498005e7c532f3 data/create/advancements/recipes/building_blocks/small_granite_brick_wall_from_stone_types_granite_stonecutting.json -1ca86b11356749caf7515fc61b8ac5de53d019f6 data/create/advancements/recipes/building_blocks/small_limestone_bricks_from_stone_types_limestone_stonecutting.json +1805b7f9db21b4530b173ab6945584e7d852b218 data/create/advancements/recipes/building_blocks/small_granite_bricks_from_stone_types_granite_stonecutting.json 4f3cc93f422ee9f05587b89d6729a6cc86f572c0 data/create/advancements/recipes/building_blocks/small_limestone_brick_slab.json 02d0c45cd014fd660a9d3eb1c1c6b40ba806b2fb data/create/advancements/recipes/building_blocks/small_limestone_brick_slab_from_stone_types_limestone_stonecutting.json 8fb46bce94f6cca943e4ae427c04d9617ada277d data/create/advancements/recipes/building_blocks/small_limestone_brick_slab_recycling.json @@ -2858,7 +2857,7 @@ cac9914c729c0ecf5e9e1b4fe6498005e7c532f3 data/create/advancements/recipes/buildi 00b61a4d23f8b16a7e4d9bf46fbe52c6b5dd561c data/create/advancements/recipes/building_blocks/small_limestone_brick_stairs_from_stone_types_limestone_stonecutting.json 7c6b80f174687efe10007c0235f2a68db7062b12 data/create/advancements/recipes/building_blocks/small_limestone_brick_wall.json 7f9ade635dcda8d5baae2bbdddc018bcc715f681 data/create/advancements/recipes/building_blocks/small_limestone_brick_wall_from_stone_types_limestone_stonecutting.json -bab018a0adcbc0582ba756158941a87923b20384 data/create/advancements/recipes/building_blocks/small_ochrum_bricks_from_stone_types_ochrum_stonecutting.json +1ca86b11356749caf7515fc61b8ac5de53d019f6 data/create/advancements/recipes/building_blocks/small_limestone_bricks_from_stone_types_limestone_stonecutting.json 9c98b7b56f92f6adc75473f5b0ae4dc69ac8aa9a data/create/advancements/recipes/building_blocks/small_ochrum_brick_slab.json 611fb57772f1446236256f1235751dec6f81cd0e data/create/advancements/recipes/building_blocks/small_ochrum_brick_slab_from_stone_types_ochrum_stonecutting.json 243821a2c3e465f5346ad58e0afda624c09ab946 data/create/advancements/recipes/building_blocks/small_ochrum_brick_slab_recycling.json @@ -2866,8 +2865,8 @@ b9a16792e6158a2923454c9a44d9c176c9607c24 data/create/advancements/recipes/buildi bb91a8ba1ef1c8cb725f18a4d577bb476b9ae68d data/create/advancements/recipes/building_blocks/small_ochrum_brick_stairs_from_stone_types_ochrum_stonecutting.json 5cf5574da0b29895960fa7f0fd63d3f81814f7b3 data/create/advancements/recipes/building_blocks/small_ochrum_brick_wall.json 1b5d14c921a85a3a5cdb9f845d4f0ddf98f87347 data/create/advancements/recipes/building_blocks/small_ochrum_brick_wall_from_stone_types_ochrum_stonecutting.json +bab018a0adcbc0582ba756158941a87923b20384 data/create/advancements/recipes/building_blocks/small_ochrum_bricks_from_stone_types_ochrum_stonecutting.json 8d6ccacf1af917094b1688ed70dc75bf54611e93 data/create/advancements/recipes/building_blocks/small_rose_quartz_tiles_from_polished_rose_quartz_stonecutting.json -7d679c66588f8a717619a7f89861d57ec04f04a1 data/create/advancements/recipes/building_blocks/small_scorchia_bricks_from_stone_types_scorchia_stonecutting.json 2003f1248faaeb4fe6761febda8e29d087f99dc7 data/create/advancements/recipes/building_blocks/small_scorchia_brick_slab.json ff5c50697aefe21c1570230a13255c912744b629 data/create/advancements/recipes/building_blocks/small_scorchia_brick_slab_from_stone_types_scorchia_stonecutting.json 8d1fd41b03940add231fa207d3ddaa1f78cf2b85 data/create/advancements/recipes/building_blocks/small_scorchia_brick_slab_recycling.json @@ -2875,7 +2874,7 @@ ff5c50697aefe21c1570230a13255c912744b629 data/create/advancements/recipes/buildi 8586f387cc9bb74250369373348005f6aa686af2 data/create/advancements/recipes/building_blocks/small_scorchia_brick_stairs_from_stone_types_scorchia_stonecutting.json 94552be031c17f5ef9d97cf5fe33beb15141291f data/create/advancements/recipes/building_blocks/small_scorchia_brick_wall.json 86e866f92095b03b5d77a91425e5e2ef307f4852 data/create/advancements/recipes/building_blocks/small_scorchia_brick_wall_from_stone_types_scorchia_stonecutting.json -e542cd94f84a90530332608b1040e2e6189a51fe data/create/advancements/recipes/building_blocks/small_scoria_bricks_from_stone_types_scoria_stonecutting.json +7d679c66588f8a717619a7f89861d57ec04f04a1 data/create/advancements/recipes/building_blocks/small_scorchia_bricks_from_stone_types_scorchia_stonecutting.json ad4c35afd6c3d55b356e38289c64e8cf6d194d10 data/create/advancements/recipes/building_blocks/small_scoria_brick_slab.json 2f1acca02bb5a40bf174ceeb5272ba1243b8635c data/create/advancements/recipes/building_blocks/small_scoria_brick_slab_from_stone_types_scoria_stonecutting.json dba264e073eab7b2fb1494cb117574b6a6b83919 data/create/advancements/recipes/building_blocks/small_scoria_brick_slab_recycling.json @@ -2883,7 +2882,7 @@ dba264e073eab7b2fb1494cb117574b6a6b83919 data/create/advancements/recipes/buildi 0e64e1dc80a0b84e05260191951ed930a8e578f6 data/create/advancements/recipes/building_blocks/small_scoria_brick_stairs_from_stone_types_scoria_stonecutting.json 95b866fac218affb9aac93272f5436e30dd4678c data/create/advancements/recipes/building_blocks/small_scoria_brick_wall.json 23493359766c969d2fa64575c5af047e6a924373 data/create/advancements/recipes/building_blocks/small_scoria_brick_wall_from_stone_types_scoria_stonecutting.json -b7fc4fbd0d6ce28946b5cbef40d86de3ca37f695 data/create/advancements/recipes/building_blocks/small_tuff_bricks_from_stone_types_tuff_stonecutting.json +e542cd94f84a90530332608b1040e2e6189a51fe data/create/advancements/recipes/building_blocks/small_scoria_bricks_from_stone_types_scoria_stonecutting.json 03acb1becaa3c7f6fc0ced99e6afcf4ac0ec4cb2 data/create/advancements/recipes/building_blocks/small_tuff_brick_slab.json 599693bc47bfd65cc9e3babc0a2f33c0d2bbfd31 data/create/advancements/recipes/building_blocks/small_tuff_brick_slab_from_stone_types_tuff_stonecutting.json aae2cb75ee4b9312e79dfea519c35f5e20ed4da6 data/create/advancements/recipes/building_blocks/small_tuff_brick_slab_recycling.json @@ -2891,7 +2890,7 @@ c72364e32b82f45f17491dd41967373c35d8dfb5 data/create/advancements/recipes/buildi 369763433d6af43d94392e870b3d861f739ba0f9 data/create/advancements/recipes/building_blocks/small_tuff_brick_stairs_from_stone_types_tuff_stonecutting.json 506bbae420bff66d492214c49dabf52e5cbcf6e4 data/create/advancements/recipes/building_blocks/small_tuff_brick_wall.json 6db7e4b981ec28c776988a531c03dbe28fb0a1c2 data/create/advancements/recipes/building_blocks/small_tuff_brick_wall_from_stone_types_tuff_stonecutting.json -9fd6e20a4555b591b17ef225316782de333780fa data/create/advancements/recipes/building_blocks/small_veridium_bricks_from_stone_types_veridium_stonecutting.json +b7fc4fbd0d6ce28946b5cbef40d86de3ca37f695 data/create/advancements/recipes/building_blocks/small_tuff_bricks_from_stone_types_tuff_stonecutting.json b61a773f683c415617a408fa0781e7e7d61cb1af data/create/advancements/recipes/building_blocks/small_veridium_brick_slab.json 526a5323263292bd091c03231a156e18460c34a1 data/create/advancements/recipes/building_blocks/small_veridium_brick_slab_from_stone_types_veridium_stonecutting.json ef040b7189b17cce9dd69c47af61c7abca6f43cd data/create/advancements/recipes/building_blocks/small_veridium_brick_slab_recycling.json @@ -2899,6 +2898,7 @@ ef040b7189b17cce9dd69c47af61c7abca6f43cd data/create/advancements/recipes/buildi 6a12b73815434a544881680cb071f273a75f62a5 data/create/advancements/recipes/building_blocks/small_veridium_brick_stairs_from_stone_types_veridium_stonecutting.json e6dfacd8f2f57d4df42927783750254f7163251a data/create/advancements/recipes/building_blocks/small_veridium_brick_wall.json ee4012cc014539be113ace8f80e51c85d2daead9 data/create/advancements/recipes/building_blocks/small_veridium_brick_wall_from_stone_types_veridium_stonecutting.json +9fd6e20a4555b591b17ef225316782de333780fa data/create/advancements/recipes/building_blocks/small_veridium_bricks_from_stone_types_veridium_stonecutting.json 03a87030672d40b0b2b6ad085103c9a5cef067ce data/create/advancements/recipes/building_blocks/spruce_window.json dfea65f25ebcbe0caf2694dec3d3ea616e2e9291 data/create/advancements/recipes/building_blocks/spruce_window_pane.json 763b3b49296a284f41cbccdc7f1ffb13c89d42db data/create/advancements/recipes/building_blocks/tiled_glass_from_glass_colorless_stonecutting.json @@ -3012,12 +3012,12 @@ fa0856e11351ad0882de2066569807e782071881 data/create/loot_tables/blocks/copper_b 0937b9f634b86dbe41e07eda52c69993fce60fb5 data/create/loot_tables/blocks/copper_door.json 8ed70d812f38adfa147db07a4f2bbe206a69ad20 data/create/loot_tables/blocks/copper_ladder.json ac621731ca23e6fbb1003be59edacdf837dbc37e data/create/loot_tables/blocks/copper_scaffolding.json -9be387731859ccc3aec7701c1804ddc3c5dde216 data/create/loot_tables/blocks/copper_shingles.json be31f0c68bfe80dff88959bd30ef9a9080dd3b3b data/create/loot_tables/blocks/copper_shingle_slab.json 83ae2652a2df217730d6fb34a65c3962e82a961d data/create/loot_tables/blocks/copper_shingle_stairs.json -9cb359c96543d7421250c4ef4e83a5e170974efb data/create/loot_tables/blocks/copper_tiles.json +9be387731859ccc3aec7701c1804ddc3c5dde216 data/create/loot_tables/blocks/copper_shingles.json adbe83d6bf88dd7d2b0b8788bb619cedd37f59d9 data/create/loot_tables/blocks/copper_tile_slab.json 1e06f16b1fa8e78af5cbfc90ba8ff1136de83d2d data/create/loot_tables/blocks/copper_tile_stairs.json +9cb359c96543d7421250c4ef4e83a5e170974efb data/create/loot_tables/blocks/copper_tiles.json 4f75cad20e6b091d1f07cf3db98520d2dc3af5e7 data/create/loot_tables/blocks/copper_valve_handle.json 14a493a7bad6bd399b662da470b71810bd56e812 data/create/loot_tables/blocks/copycat_bars.json 3a2f3ab0834a0c5089ba0a11f5e9784ce59ef6d8 data/create/loot_tables/blocks/copycat_base.json @@ -3033,114 +3033,114 @@ d5d2f565bab2e2b81b0798fc7ce0e21acd362ce5 data/create/loot_tables/blocks/crimson_ b892718d33caf0c260b902c92f46f3bfd827af45 data/create/loot_tables/blocks/crushing_wheel.json ff7853a5d5c0f3bddbcfe07e47efd1ff04b14f0a data/create/loot_tables/blocks/cuckoo_clock.json 9083b026ee254645430434b67c2ba7a842f888bf data/create/loot_tables/blocks/cut_andesite.json -c1aa69f80ba11dd52fb3627fc32377599f5ff887 data/create/loot_tables/blocks/cut_andesite_bricks.json c74a4cac08ab1f66146466ff9fb40c8f210de63c data/create/loot_tables/blocks/cut_andesite_brick_slab.json df3f5dcbf676106800bc1113bb022658eb5e85d6 data/create/loot_tables/blocks/cut_andesite_brick_stairs.json 95c5a4a3327f522d986d7baaa747fce5ead8c032 data/create/loot_tables/blocks/cut_andesite_brick_wall.json +c1aa69f80ba11dd52fb3627fc32377599f5ff887 data/create/loot_tables/blocks/cut_andesite_bricks.json cb6cf8aefaac1e00596bd64a182a329dbba7e659 data/create/loot_tables/blocks/cut_andesite_slab.json 7106a637809dcbeb9d4a02a7ff9dc52f7fd9d7a2 data/create/loot_tables/blocks/cut_andesite_stairs.json e3cfa2ecb0b90ebe07cc98f8e47d22d2c0da67e5 data/create/loot_tables/blocks/cut_andesite_wall.json 75eacbc0656e7a83a20a054755ea7d7d78af983d data/create/loot_tables/blocks/cut_asurine.json -f780d37b956ed734cafcbe42b77f1a8ebfa33350 data/create/loot_tables/blocks/cut_asurine_bricks.json 43ad24bb9da878111f3606a17ef9b45bcc4964ae data/create/loot_tables/blocks/cut_asurine_brick_slab.json 8f4d0af32546b6cc77c68a08dc74494b8be1b7c3 data/create/loot_tables/blocks/cut_asurine_brick_stairs.json bb9ce58aa5b4e38c4d3b29aa8e0d905054023eae data/create/loot_tables/blocks/cut_asurine_brick_wall.json +f780d37b956ed734cafcbe42b77f1a8ebfa33350 data/create/loot_tables/blocks/cut_asurine_bricks.json 972ca04f91a1ce4d35995c14e1b17f773b15b61e data/create/loot_tables/blocks/cut_asurine_slab.json a55778dd8735286c3abc65046186b6b8dff0367e data/create/loot_tables/blocks/cut_asurine_stairs.json 70284c686f16d215ff1a8fb19bbe36fddbd31e18 data/create/loot_tables/blocks/cut_asurine_wall.json 0f450ecf60c5d201f332b2736c552d0b51b159b8 data/create/loot_tables/blocks/cut_calcite.json -aec526af372816f306826eefe4a6318db7964892 data/create/loot_tables/blocks/cut_calcite_bricks.json ec0d2854433ac4f58e53685c69dc19629fee16ca data/create/loot_tables/blocks/cut_calcite_brick_slab.json 584e39fa0b78ba8649f69b53f9f032dd1532d6ac data/create/loot_tables/blocks/cut_calcite_brick_stairs.json cc9cbdb7a50305e47181b2452bfce887f9879437 data/create/loot_tables/blocks/cut_calcite_brick_wall.json +aec526af372816f306826eefe4a6318db7964892 data/create/loot_tables/blocks/cut_calcite_bricks.json b4e5b6d5cb63b7b1a4fe639fd727a381bfd00588 data/create/loot_tables/blocks/cut_calcite_slab.json ca83b89401dba12341e6f26786103c10c90447ca data/create/loot_tables/blocks/cut_calcite_stairs.json 64df1c4a373c28bf9be3630935b01a43abd22e03 data/create/loot_tables/blocks/cut_calcite_wall.json 5df3a2229657d7b616790e922b1d1d558b4a5128 data/create/loot_tables/blocks/cut_crimsite.json -59cb609bc9671ac481832eeaf942533c6861fc0e data/create/loot_tables/blocks/cut_crimsite_bricks.json 6fee8d6425e1c832abed8fd9bccc8e6fae9441fc data/create/loot_tables/blocks/cut_crimsite_brick_slab.json 3123bc9e6123dfeda9bb3cece5c2220ac8485535 data/create/loot_tables/blocks/cut_crimsite_brick_stairs.json 56a8c7b1588f6fa9a1fb438e91b04673e02a0c86 data/create/loot_tables/blocks/cut_crimsite_brick_wall.json +59cb609bc9671ac481832eeaf942533c6861fc0e data/create/loot_tables/blocks/cut_crimsite_bricks.json 90ed82b09f2650ee913956d62803d15fc4c0bdbd data/create/loot_tables/blocks/cut_crimsite_slab.json 0e237e008523ed3e9934c598a708be533aaa0861 data/create/loot_tables/blocks/cut_crimsite_stairs.json 48e1edca75186f160a12fa26ac262c7f86d62c82 data/create/loot_tables/blocks/cut_crimsite_wall.json 7bfe4d183ed26de1d7b241c27880a70d28426502 data/create/loot_tables/blocks/cut_deepslate.json -6e375a42ddf38c99fee86531471573716e27fa44 data/create/loot_tables/blocks/cut_deepslate_bricks.json fa4b940ad8ee432ee0fabf496d2da3d5039c204a data/create/loot_tables/blocks/cut_deepslate_brick_slab.json 1063a94b3e90a52a7492d85b1c086514333f3421 data/create/loot_tables/blocks/cut_deepslate_brick_stairs.json 878d809a038c626e8054f9b71e27be08388d7615 data/create/loot_tables/blocks/cut_deepslate_brick_wall.json +6e375a42ddf38c99fee86531471573716e27fa44 data/create/loot_tables/blocks/cut_deepslate_bricks.json 7b5e46aaf34d71993f50b5b6fa1cd5d7ea64264c data/create/loot_tables/blocks/cut_deepslate_slab.json 7d45e8bb037a1e550132854200d57ce31e073993 data/create/loot_tables/blocks/cut_deepslate_stairs.json cd80fd4f573d59c22f0b9799f1ba7422215d4ff1 data/create/loot_tables/blocks/cut_deepslate_wall.json d79d52657307a30422d9ff2eb1caad78024c24f7 data/create/loot_tables/blocks/cut_diorite.json -9f627b6449ae27a1990b84a60349736129a11e39 data/create/loot_tables/blocks/cut_diorite_bricks.json 1809235166024fa74f65a96b622faa8eddf4ce14 data/create/loot_tables/blocks/cut_diorite_brick_slab.json a6bb9fb4eee3dab9a540b228801ce100c048c2a7 data/create/loot_tables/blocks/cut_diorite_brick_stairs.json 690a938a04543cb60f2952335be26b2df9c75715 data/create/loot_tables/blocks/cut_diorite_brick_wall.json +9f627b6449ae27a1990b84a60349736129a11e39 data/create/loot_tables/blocks/cut_diorite_bricks.json 208999222adb5b1cd4fa47b85000841dbae4ad21 data/create/loot_tables/blocks/cut_diorite_slab.json 12849a868e8dff48ebb688c84fc53d4cee2a4eaa data/create/loot_tables/blocks/cut_diorite_stairs.json 469fffcdd40aea22fedb81b7778cc3c61928f3fd data/create/loot_tables/blocks/cut_diorite_wall.json 302d0bb640f696109fe4edc0c1fa9db332231511 data/create/loot_tables/blocks/cut_dripstone.json -48707f37b94ff1a930ee45bb9e8b6b4b67226945 data/create/loot_tables/blocks/cut_dripstone_bricks.json eb31bc108180e2248d575d5d72325b5585254af0 data/create/loot_tables/blocks/cut_dripstone_brick_slab.json 9b624a456baf55960675d7857e159f69911a281a data/create/loot_tables/blocks/cut_dripstone_brick_stairs.json b4c754d4d5a6c28f537c2d73844e39059b2c1450 data/create/loot_tables/blocks/cut_dripstone_brick_wall.json +48707f37b94ff1a930ee45bb9e8b6b4b67226945 data/create/loot_tables/blocks/cut_dripstone_bricks.json eb9eca9a69f763cbe81dc79375ef76978594b51e data/create/loot_tables/blocks/cut_dripstone_slab.json 47fae3abc8bea3ee802d6759192e631f50329c5f data/create/loot_tables/blocks/cut_dripstone_stairs.json 70b71cc460cba2955694baf0550eadc2187e3a8a data/create/loot_tables/blocks/cut_dripstone_wall.json 26433a16a91414be15b20dc85b81b76d086be889 data/create/loot_tables/blocks/cut_granite.json -65c3936e78a90c53faa0b9f9b3034afc2728e7b9 data/create/loot_tables/blocks/cut_granite_bricks.json c6b8dfa87e9c33a0dd2b3398dcc524347e826d44 data/create/loot_tables/blocks/cut_granite_brick_slab.json 5e00417f06b4d357e7469f0efa6e319dfc587da3 data/create/loot_tables/blocks/cut_granite_brick_stairs.json 8d8779846af8121426f128cc7b5d501037bd1cd4 data/create/loot_tables/blocks/cut_granite_brick_wall.json +65c3936e78a90c53faa0b9f9b3034afc2728e7b9 data/create/loot_tables/blocks/cut_granite_bricks.json 6e7253b2801611b4698e786f495c2ade1088ee0b data/create/loot_tables/blocks/cut_granite_slab.json de8c10fb2c7409a3375f2db5cdce2027c3f419bd data/create/loot_tables/blocks/cut_granite_stairs.json cdf40bb46d9457a66129b300dc4d3f0160cc1de2 data/create/loot_tables/blocks/cut_granite_wall.json ac5f062c7fc270c63d67ccecf19499a9e91fa1c4 data/create/loot_tables/blocks/cut_limestone.json -b60fb652e1f83b1af12a15cb47450bd9a6087f6a data/create/loot_tables/blocks/cut_limestone_bricks.json 3b6d3a9b12cf1c2a20bf337cc0155bb66967f0ee data/create/loot_tables/blocks/cut_limestone_brick_slab.json 701249cc12b7aa6f5cc1691ac4dd17e665aa2180 data/create/loot_tables/blocks/cut_limestone_brick_stairs.json 3b8c5eef9b0e8c35e8573ce91f5fddbac7f76f24 data/create/loot_tables/blocks/cut_limestone_brick_wall.json +b60fb652e1f83b1af12a15cb47450bd9a6087f6a data/create/loot_tables/blocks/cut_limestone_bricks.json ba186786e8677f1c769e8f231fe872c48330e13a data/create/loot_tables/blocks/cut_limestone_slab.json d354966d57804afda39ff27336d8b0f38acf6ea3 data/create/loot_tables/blocks/cut_limestone_stairs.json 28b4eee2c6da259e50c58a51905fa2b79a9b89ef data/create/loot_tables/blocks/cut_limestone_wall.json b3d6d90dd0c3e9d4b47d1f87d5abc354dd8c1447 data/create/loot_tables/blocks/cut_ochrum.json -5856859aae0cc633cbd9d83ea7cf7910ce1a88de data/create/loot_tables/blocks/cut_ochrum_bricks.json 67cadc71d90fb2527b9b2b72a74463d71571e493 data/create/loot_tables/blocks/cut_ochrum_brick_slab.json 487b3e7dc1d9d07183b9b699e33f6371858435aa data/create/loot_tables/blocks/cut_ochrum_brick_stairs.json 289757860f07b63dcce531a74ce7e60b4669c51b data/create/loot_tables/blocks/cut_ochrum_brick_wall.json +5856859aae0cc633cbd9d83ea7cf7910ce1a88de data/create/loot_tables/blocks/cut_ochrum_bricks.json c9deec5e3c7343afa3d013704179e2147b2eb7ec data/create/loot_tables/blocks/cut_ochrum_slab.json e851d829db8ea4398bc1cbe6e743b4fba98d3413 data/create/loot_tables/blocks/cut_ochrum_stairs.json 5dce8524b70baeefaeba13422f5900b1a161a867 data/create/loot_tables/blocks/cut_ochrum_wall.json 293064edf2909db8c9edc26bedd1cc023c647664 data/create/loot_tables/blocks/cut_scorchia.json -767910313f0983ebfb49b80526747d762cbdf782 data/create/loot_tables/blocks/cut_scorchia_bricks.json 895c4b9cc71701a26ae0e765ee67f0c06cc70a9c data/create/loot_tables/blocks/cut_scorchia_brick_slab.json c53d72176cb5dd93977975dd84647391fa563e3a data/create/loot_tables/blocks/cut_scorchia_brick_stairs.json 460232ca38cba2f0adc5316d6db8db94db231953 data/create/loot_tables/blocks/cut_scorchia_brick_wall.json +767910313f0983ebfb49b80526747d762cbdf782 data/create/loot_tables/blocks/cut_scorchia_bricks.json c8201964d877a932fe9a9a2d0360004440f7c380 data/create/loot_tables/blocks/cut_scorchia_slab.json dfd09849dbf48a064269a5ea28d0422caa87e4d4 data/create/loot_tables/blocks/cut_scorchia_stairs.json bd5304e38bb92a445c159e9fe647b906e28b232e data/create/loot_tables/blocks/cut_scorchia_wall.json 6b87a22c39b545d5be92e476751b99ceb4bef740 data/create/loot_tables/blocks/cut_scoria.json -833252d2d63c7502f6f0d7981673a8081046c944 data/create/loot_tables/blocks/cut_scoria_bricks.json 659e86f89499539e435989c2eb29e88e9a0ff9f4 data/create/loot_tables/blocks/cut_scoria_brick_slab.json 8434d461090bc43328eec0b4249d27a9ba383707 data/create/loot_tables/blocks/cut_scoria_brick_stairs.json e3f853395b9b6fb7d5bb103c121a77e04526a9e8 data/create/loot_tables/blocks/cut_scoria_brick_wall.json +833252d2d63c7502f6f0d7981673a8081046c944 data/create/loot_tables/blocks/cut_scoria_bricks.json 8360d736887ae3dc22bcf522791ef981e380456c data/create/loot_tables/blocks/cut_scoria_slab.json c771f03308f45e1e87d92181f94cdfd4e61fa5d8 data/create/loot_tables/blocks/cut_scoria_stairs.json 6fecb7fa2774ea63ac0c66e9c3d0f41d6b8cdff7 data/create/loot_tables/blocks/cut_scoria_wall.json 396074ee7fd5a3ddbac9332c74b7bdc4164919e2 data/create/loot_tables/blocks/cut_tuff.json -81465ef7aa555d36adf249bbc9acfe80abbe308e data/create/loot_tables/blocks/cut_tuff_bricks.json 5148f230c773b83268d52650bdacc660025feb95 data/create/loot_tables/blocks/cut_tuff_brick_slab.json 19719a4a3f63d1ec46a9ca9736a825d2dcc880ff data/create/loot_tables/blocks/cut_tuff_brick_stairs.json e20991b67c07dca62c212b43da5b7e7e98146c0e data/create/loot_tables/blocks/cut_tuff_brick_wall.json +81465ef7aa555d36adf249bbc9acfe80abbe308e data/create/loot_tables/blocks/cut_tuff_bricks.json 6d16bd3860207ff6912afc2bf3f0454b572aabba data/create/loot_tables/blocks/cut_tuff_slab.json c14e52ac9901aa873c33d51988bd26465ce0e095 data/create/loot_tables/blocks/cut_tuff_stairs.json dd70800c79fa2ff56bd4ea032cf069bc27cc9076 data/create/loot_tables/blocks/cut_tuff_wall.json 1957b610d14460cc9ca797fe953bf9831509cdbf data/create/loot_tables/blocks/cut_veridium.json -673d1f0fefa7725ac5bfcabfcea577041adc4eeb data/create/loot_tables/blocks/cut_veridium_bricks.json c1515a908bde249c087be1e73aec37773bc3dc5c data/create/loot_tables/blocks/cut_veridium_brick_slab.json d9552e3e9f4de0e09df8ca9446066e94c6e2c681 data/create/loot_tables/blocks/cut_veridium_brick_stairs.json 584c4bd13d9870f9798155b47cc0d32e5751294d data/create/loot_tables/blocks/cut_veridium_brick_wall.json +673d1f0fefa7725ac5bfcabfcea577041adc4eeb data/create/loot_tables/blocks/cut_veridium_bricks.json 009186ed0efe29a229a28cfd913bc02ddad217d4 data/create/loot_tables/blocks/cut_veridium_slab.json 4845f7127921c7dd93a59118e63c37107d6c2061 data/create/loot_tables/blocks/cut_veridium_stairs.json b56caea031d637321eddfd5d122fc357d2c2e49c data/create/loot_tables/blocks/cut_veridium_wall.json @@ -3165,12 +3165,12 @@ dfe0af3ff61ed2b3082e49c745d8a3e0c5973f4b data/create/loot_tables/blocks/encased_ a2e9a8a10b7fc730c1d7c8db3b529e7a37b683f5 data/create/loot_tables/blocks/encased_fan.json 7ede9f64839f51e6a2eb05b08577d2873f281401 data/create/loot_tables/blocks/encased_fluid_pipe.json 4869211639326efaabd1aba1067bfbb3ab012884 data/create/loot_tables/blocks/experience_block.json -9fa4b0c8ee313b6c9a57d7d5b687cdd01c8259d3 data/create/loot_tables/blocks/exposed_copper_shingles.json 9dbd37ef5ff549f10475101205c1a9d4a44140bc data/create/loot_tables/blocks/exposed_copper_shingle_slab.json d2c9abd9260eb82ea1c2eeae5e2d6abd0b4d3ce8 data/create/loot_tables/blocks/exposed_copper_shingle_stairs.json -f0905ae4c9bdff8fe9e1ab4682a7b1efe2d27d9d data/create/loot_tables/blocks/exposed_copper_tiles.json +9fa4b0c8ee313b6c9a57d7d5b687cdd01c8259d3 data/create/loot_tables/blocks/exposed_copper_shingles.json 6841c02935838f00011d33fc392965326c4dbc5b data/create/loot_tables/blocks/exposed_copper_tile_slab.json 432a047156b93a09b7e027fc34f5680a8f68dc92 data/create/loot_tables/blocks/exposed_copper_tile_stairs.json +f0905ae4c9bdff8fe9e1ab4682a7b1efe2d27d9d data/create/loot_tables/blocks/exposed_copper_tiles.json 3fae2a7a3f133a1d7c76ce91f6c48eab787d6ff6 data/create/loot_tables/blocks/fake_track.json 1d4734d6d9ba039c0dfa2271f08cdb55e35b721f data/create/loot_tables/blocks/fluid_pipe.json 9c112883a3763b2d286d9a5a0980dcea82bcc9e6 data/create/loot_tables/blocks/fluid_tank.json @@ -3234,13 +3234,13 @@ bf4e6c308d82f15689406b5b3e88fe95d49a9a44 data/create/loot_tables/blocks/light_bl 1ae0ff25ac9468e67ab1847b87a37829328d4c84 data/create/loot_tables/blocks/light_gray_seat.json e22dfadefcea50090efe87136a4b92e6ef20d379 data/create/loot_tables/blocks/light_gray_toolbox.json 3e586bc1281f15e25e75475dd726578ff032c6ae data/create/loot_tables/blocks/light_gray_valve_handle.json -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 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 1a3ed7cd5660d7ea014956ea642e0b07d89bc297 data/create/loot_tables/blocks/lime_valve_handle.json +c6bb0877c537dda15469934383dc45c608bfd1a4 data/create/loot_tables/blocks/limestone.json +49058a62e1abd34917f983b6bc13cc4353b613a2 data/create/loot_tables/blocks/limestone_pillar.json 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 @@ -3282,12 +3282,12 @@ d6323d4b30faa87cd4b5b8b815cb16f78296f203 data/create/loot_tables/blocks/orange_s 30aef2df782b6b35cd16b4c205bb15de85bc0664 data/create/loot_tables/blocks/orange_valve_handle.json f4004c6d16754fc8867ed6618dace8e8f6dcc412 data/create/loot_tables/blocks/ornate_iron_window.json 6f14500e07c6d342804f9127e7b66047ffaeef1e data/create/loot_tables/blocks/ornate_iron_window_pane.json -3e54d3c4755a43d837a1d9b2005ea1dee4d02555 data/create/loot_tables/blocks/oxidized_copper_shingles.json 62c43a533e4ffeeec9f7657db5a796569087f806 data/create/loot_tables/blocks/oxidized_copper_shingle_slab.json f47a01824093455030fca66e7b8a39bcfc61d219 data/create/loot_tables/blocks/oxidized_copper_shingle_stairs.json -4d2a2863697664b3b71f02aa703c3504cd5cc826 data/create/loot_tables/blocks/oxidized_copper_tiles.json +3e54d3c4755a43d837a1d9b2005ea1dee4d02555 data/create/loot_tables/blocks/oxidized_copper_shingles.json 4d815b361af81bd0c0e14c853ca54ad3cde66a57 data/create/loot_tables/blocks/oxidized_copper_tile_slab.json d599ef03d1b69e4367ec0dea78f52c1964c99f9b data/create/loot_tables/blocks/oxidized_copper_tile_stairs.json +4d2a2863697664b3b71f02aa703c3504cd5cc826 data/create/loot_tables/blocks/oxidized_copper_tiles.json 58bd9fe9d6706998bfbda3b077cfd0a740972091 data/create/loot_tables/blocks/peculiar_bell.json 4d7724df6fefee4512c4f7886d0e103d1dc39510 data/create/loot_tables/blocks/pink_nixie_tube.json 85811771fbc36f645fdb9f510639715399503c99 data/create/loot_tables/blocks/pink_sail.json @@ -3368,13 +3368,13 @@ c6b7a02db55cf0824a48156adf469c478dfd6a8d data/create/loot_tables/blocks/purple_s 9e5e841d9f9a00d560ed17a7e197dc56bae334b7 data/create/loot_tables/blocks/radial_chassis.json 73a03fa31e299cec2c8a3dc0f31a8aa354b49bcd data/create/loot_tables/blocks/railway_casing.json 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 a50e1c28af16e9f1b4f48aa974461167139768a7 data/create/loot_tables/blocks/red_nixie_tube.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 17d75711f4ef5d76aa931175364642732fb0c60d data/create/loot_tables/blocks/red_valve_handle.json +bbc2d61eeea335f8f011d799ef6a5484ca027640 data/create/loot_tables/blocks/redstone_contact.json +4fa70deeac7e56121e42fb602dfa27ee1727f749 data/create/loot_tables/blocks/redstone_link.json 632067fe6309e31e78637eb0272209b630750242 data/create/loot_tables/blocks/refined_radiance_casing.json 354a3b6c73379b7100b0dd12b3f3b008830c4d2d data/create/loot_tables/blocks/rope.json f74fdd78961619d712891c36e0a0778c25e145dc data/create/loot_tables/blocks/rope_pulley.json @@ -3383,8 +3383,8 @@ f74fdd78961619d712891c36e0a0778c25e145dc data/create/loot_tables/blocks/rope_pul a0575567d5679f2c54e5a25c6ec12338f8cdc939 data/create/loot_tables/blocks/rose_quartz_tiles.json de74765a3bbffafb87d632857dfcfa83f863f814 data/create/loot_tables/blocks/rotation_speed_controller.json 2af8df3e36ace336c43d68f4e53564640a89845f data/create/loot_tables/blocks/sail_frame.json -d499fd59d30da8b907b0f3a0f428700f066eddff data/create/loot_tables/blocks/schematicannon.json 5a54e930243919991d71a1c3296002ff86dd88e1 data/create/loot_tables/blocks/schematic_table.json +d499fd59d30da8b907b0f3a0f428700f066eddff data/create/loot_tables/blocks/schematicannon.json 1d9b0df1330f44681bbd56f8560a30ef9e2175ff data/create/loot_tables/blocks/scorchia.json e39f189bfaebd31aedceb11e25720f1e08eb238d data/create/loot_tables/blocks/scorchia_pillar.json 5e3a37dbb2fcc0d6be042bfd063fd8b1414d6169 data/create/loot_tables/blocks/scoria.json @@ -3393,64 +3393,64 @@ d39afcaedc84d582c0c1f21ec5945cd0a67d389d data/create/loot_tables/blocks/secondar e33a34b47e07cf3262c0dbdbc651b31b9492b18f data/create/loot_tables/blocks/sequenced_gearshift.json 7d61387106e5e7fcc4aa0b05b9560cd5f4ef7df8 data/create/loot_tables/blocks/shadow_steel_casing.json 7e67d04f861e0a680487e27f94022a7850652dfe data/create/loot_tables/blocks/shaft.json -e88ff4ab1341c2db8338de0708b0ca8f40f15a8b data/create/loot_tables/blocks/small_andesite_bricks.json 220febcbcc4a993d475b683ebef7468ebdb7bf26 data/create/loot_tables/blocks/small_andesite_brick_slab.json b4764c5bb538359bcc2a599ff3b7474ade2115ed data/create/loot_tables/blocks/small_andesite_brick_stairs.json a891496ffb91bef56c3b684cb55a57e27a72154a data/create/loot_tables/blocks/small_andesite_brick_wall.json -576d8f6beca755a4082f1c8941e2590c1d18107b data/create/loot_tables/blocks/small_asurine_bricks.json +e88ff4ab1341c2db8338de0708b0ca8f40f15a8b data/create/loot_tables/blocks/small_andesite_bricks.json 1a5d3543ebb7c0064ba8ff01160a22a0f5f29f36 data/create/loot_tables/blocks/small_asurine_brick_slab.json 64f4b44b786eda91d432f20c8b725b0415440b56 data/create/loot_tables/blocks/small_asurine_brick_stairs.json 60a1d505e955047cf933ae55efc2e7c10d0a5a79 data/create/loot_tables/blocks/small_asurine_brick_wall.json +576d8f6beca755a4082f1c8941e2590c1d18107b data/create/loot_tables/blocks/small_asurine_bricks.json 64bcfece2507b8510633ae20c00ab989232664ff data/create/loot_tables/blocks/small_bogey.json -c03bba06f66262c0ced5e85fa7dcbfbfc8c9db71 data/create/loot_tables/blocks/small_calcite_bricks.json b673542c79f4a82f2e80c0931354e994292811f6 data/create/loot_tables/blocks/small_calcite_brick_slab.json e10d286286bba8e172a56e0eeb9af18d06d1a76d data/create/loot_tables/blocks/small_calcite_brick_stairs.json d7214e942b203823fa2fece883e8406a7721369f data/create/loot_tables/blocks/small_calcite_brick_wall.json -f49d32973b0be51229f4e3fdc13958c9852c5c8a data/create/loot_tables/blocks/small_crimsite_bricks.json +c03bba06f66262c0ced5e85fa7dcbfbfc8c9db71 data/create/loot_tables/blocks/small_calcite_bricks.json ef8b0f604b627715542e8216ae5448e88995cc13 data/create/loot_tables/blocks/small_crimsite_brick_slab.json dbec9246ab957a3ed2dbd0707df12c1496258e05 data/create/loot_tables/blocks/small_crimsite_brick_stairs.json d4d5bd8b101655205c4f293f23e83f610e179e91 data/create/loot_tables/blocks/small_crimsite_brick_wall.json -8caba3e7001dd8df4d3e6365b97849570c74c840 data/create/loot_tables/blocks/small_deepslate_bricks.json +f49d32973b0be51229f4e3fdc13958c9852c5c8a data/create/loot_tables/blocks/small_crimsite_bricks.json 44567c10c28ddd221198824766d3fec289fb29d4 data/create/loot_tables/blocks/small_deepslate_brick_slab.json fc141f5cdb1001d344b5ef8fa3ad1fdfeb01d048 data/create/loot_tables/blocks/small_deepslate_brick_stairs.json 3cf68d27362e9bb5dc3255ccf810097fbee511ba data/create/loot_tables/blocks/small_deepslate_brick_wall.json -4f22a84f105c2fabfd08ff0782ec30bbdc59f940 data/create/loot_tables/blocks/small_diorite_bricks.json +8caba3e7001dd8df4d3e6365b97849570c74c840 data/create/loot_tables/blocks/small_deepslate_bricks.json f6565f4bd11b7e95008b0f8fc3f5f2c7af1b77f8 data/create/loot_tables/blocks/small_diorite_brick_slab.json e3cbe41b4b2c38d0d5e625e34b61fc79db16d3bd data/create/loot_tables/blocks/small_diorite_brick_stairs.json 787dfaa16dc30155c90cc360f6927fa067a30ed8 data/create/loot_tables/blocks/small_diorite_brick_wall.json -d9cc7f58c791e040df4abfce225524e01eb01d49 data/create/loot_tables/blocks/small_dripstone_bricks.json +4f22a84f105c2fabfd08ff0782ec30bbdc59f940 data/create/loot_tables/blocks/small_diorite_bricks.json f72338c9252528e41f60cb183cb4ee07cea47bf0 data/create/loot_tables/blocks/small_dripstone_brick_slab.json bedf0fba68e8a8ce4205a968429ebe9c3ddfb528 data/create/loot_tables/blocks/small_dripstone_brick_stairs.json c1168f58f342dfa332bfa7f53f5f03383c55ccf2 data/create/loot_tables/blocks/small_dripstone_brick_wall.json -8437e7e28e45c10562d182c4c07189bcc108cabb data/create/loot_tables/blocks/small_granite_bricks.json +d9cc7f58c791e040df4abfce225524e01eb01d49 data/create/loot_tables/blocks/small_dripstone_bricks.json 4d111f8580ac97cf1b49b667462f7141846f3d3a data/create/loot_tables/blocks/small_granite_brick_slab.json c16e015251126614960d3e6300cb04d3aeaf49b4 data/create/loot_tables/blocks/small_granite_brick_stairs.json e0ff780ddeb5d5c8d2b6cd7736ac05f4556de52c data/create/loot_tables/blocks/small_granite_brick_wall.json -c60def11fbac5010bf749960e084dd5cd0dc4b07 data/create/loot_tables/blocks/small_limestone_bricks.json +8437e7e28e45c10562d182c4c07189bcc108cabb data/create/loot_tables/blocks/small_granite_bricks.json 5222ac5255c9a9ada0ce1da0fd4f4acbeee8ddb7 data/create/loot_tables/blocks/small_limestone_brick_slab.json 97310b6b1cbea869ebaa52861542787c49cee017 data/create/loot_tables/blocks/small_limestone_brick_stairs.json 0855921034db43692baa9fd0bcb767154f96d591 data/create/loot_tables/blocks/small_limestone_brick_wall.json -eb6b2171a6c99a3a28089752f26ddc6ac1f941d1 data/create/loot_tables/blocks/small_ochrum_bricks.json +c60def11fbac5010bf749960e084dd5cd0dc4b07 data/create/loot_tables/blocks/small_limestone_bricks.json 8ced0c24db685dbf4382b7b71124005edde9e0b2 data/create/loot_tables/blocks/small_ochrum_brick_slab.json 090e7154fb2c3dfd20d37aa87f3df4572a27c615 data/create/loot_tables/blocks/small_ochrum_brick_stairs.json 60f2d9970ad8caf8ffe3aa8083dbba671b8d4b8b data/create/loot_tables/blocks/small_ochrum_brick_wall.json +eb6b2171a6c99a3a28089752f26ddc6ac1f941d1 data/create/loot_tables/blocks/small_ochrum_bricks.json a001d069c2b4d15c6dfd0312749765fc4e89571e data/create/loot_tables/blocks/small_rose_quartz_tiles.json -ce71e670948453691d4f09c8110b952afb41afa1 data/create/loot_tables/blocks/small_scorchia_bricks.json d521cf885c737da2e4717d43072840ffd3f4c5d9 data/create/loot_tables/blocks/small_scorchia_brick_slab.json de6b5d583e1adf4d49147e0719616dfd0165726d data/create/loot_tables/blocks/small_scorchia_brick_stairs.json 895603c6920338ffafd8d0d1310e47ac20bdbfda data/create/loot_tables/blocks/small_scorchia_brick_wall.json -8b7e61477c4fdc834d669bda9197b585d60f26a2 data/create/loot_tables/blocks/small_scoria_bricks.json +ce71e670948453691d4f09c8110b952afb41afa1 data/create/loot_tables/blocks/small_scorchia_bricks.json d1954c07a66f40123d8d78602795efad7c92070f data/create/loot_tables/blocks/small_scoria_brick_slab.json 291b5a560f09ed8f09ccc949a1a4da0006f139c7 data/create/loot_tables/blocks/small_scoria_brick_stairs.json ed572e947f78d637e6e1a4166c111121087c41c3 data/create/loot_tables/blocks/small_scoria_brick_wall.json -2c7097ee677f42452212b5dce8959065d2bb0e15 data/create/loot_tables/blocks/small_tuff_bricks.json +8b7e61477c4fdc834d669bda9197b585d60f26a2 data/create/loot_tables/blocks/small_scoria_bricks.json ad8a3571dc3ae0ee1ec7be7f35c9796e544f0682 data/create/loot_tables/blocks/small_tuff_brick_slab.json 17f4a98a81e5920b75c88133d15b63d431f3fb64 data/create/loot_tables/blocks/small_tuff_brick_stairs.json 7defad704f6278e329af634acfb9efd617b2003e data/create/loot_tables/blocks/small_tuff_brick_wall.json -e499c0a8a0f804003612f3a4c9286cb4b033fe4b data/create/loot_tables/blocks/small_veridium_bricks.json +2c7097ee677f42452212b5dce8959065d2bb0e15 data/create/loot_tables/blocks/small_tuff_bricks.json c7771827a715b9eaacd1a7b7e863e274b1dee11f data/create/loot_tables/blocks/small_veridium_brick_slab.json 818b65dd5d868527e7df7658a4f62a93f2795186 data/create/loot_tables/blocks/small_veridium_brick_stairs.json 7733e53a90f2ba9c17cdedaa8720e70df1a8d2de data/create/loot_tables/blocks/small_veridium_brick_wall.json +e499c0a8a0f804003612f3a4c9286cb4b033fe4b data/create/loot_tables/blocks/small_veridium_bricks.json a121d21b81e93c119b6ee32ca21d260d9c33cb2a data/create/loot_tables/blocks/smart_chute.json 4556eb2d607db3631d0a9524d22a50686ce4a5a8 data/create/loot_tables/blocks/smart_fluid_pipe.json 9601e8ba0eb098cc409557f17b01669d8b971461 data/create/loot_tables/blocks/speedometer.json @@ -3482,36 +3482,36 @@ cfc82d2aa8248caeaa17ff0a60db02607046550d data/create/loot_tables/blocks/warped_w 2eeddb89cfc597bc1ce0736b9f4a6f98e0dfa4d2 data/create/loot_tables/blocks/warped_window_pane.json ccab211722d7f06913a549851b0d6e8278edc845 data/create/loot_tables/blocks/water_wheel.json ea5dfcedc928e8dfa1c59cf3917d1577dff87494 data/create/loot_tables/blocks/water_wheel_structure.json -bbc6fc068adccea464909b87f1d1f426324d74cc data/create/loot_tables/blocks/waxed_copper_shingles.json cb31be1e75ca822454bd0a89954f74c4c8726b33 data/create/loot_tables/blocks/waxed_copper_shingle_slab.json c8e440e42141788d1988c57ab91cb1bfcd977407 data/create/loot_tables/blocks/waxed_copper_shingle_stairs.json -a3b8f12d983077477963fd3fc893c5acd36ad552 data/create/loot_tables/blocks/waxed_copper_tiles.json +bbc6fc068adccea464909b87f1d1f426324d74cc data/create/loot_tables/blocks/waxed_copper_shingles.json 807da1d66d6c7d07efc8973de43415fa4b5ddfdc data/create/loot_tables/blocks/waxed_copper_tile_slab.json 92759871a9c84815b98b6dcd22fcf0dd958bc8ab data/create/loot_tables/blocks/waxed_copper_tile_stairs.json -eb9781d081d52c34c041004c774b52169b4a9ca0 data/create/loot_tables/blocks/waxed_exposed_copper_shingles.json +a3b8f12d983077477963fd3fc893c5acd36ad552 data/create/loot_tables/blocks/waxed_copper_tiles.json be5aabc98f4d70028f2b49ae1eaf0bc68a693c53 data/create/loot_tables/blocks/waxed_exposed_copper_shingle_slab.json a99143d290addb98427be53d7fea1cbc702d630c data/create/loot_tables/blocks/waxed_exposed_copper_shingle_stairs.json -e79c0636852b37a463dc122d66cdec27d3aa10c4 data/create/loot_tables/blocks/waxed_exposed_copper_tiles.json +eb9781d081d52c34c041004c774b52169b4a9ca0 data/create/loot_tables/blocks/waxed_exposed_copper_shingles.json 234cbb59a0e00d82c5508c8e9a61e328c22c1c56 data/create/loot_tables/blocks/waxed_exposed_copper_tile_slab.json de628114eb25f393efc4c0934d79c5bdc4365f75 data/create/loot_tables/blocks/waxed_exposed_copper_tile_stairs.json -60fe0594baab9599956d990ba893f8915835db81 data/create/loot_tables/blocks/waxed_oxidized_copper_shingles.json +e79c0636852b37a463dc122d66cdec27d3aa10c4 data/create/loot_tables/blocks/waxed_exposed_copper_tiles.json c8935df7d4634dee2b01c8a0ac5de12397f4d9ed data/create/loot_tables/blocks/waxed_oxidized_copper_shingle_slab.json 2b9370b7fa362ea88f916dd53747da80e4ae3357 data/create/loot_tables/blocks/waxed_oxidized_copper_shingle_stairs.json -f0721c371b08214337f3f4fce3a3705840310bdb data/create/loot_tables/blocks/waxed_oxidized_copper_tiles.json +60fe0594baab9599956d990ba893f8915835db81 data/create/loot_tables/blocks/waxed_oxidized_copper_shingles.json de4d25cac546559173f740752625c82dfd6bae09 data/create/loot_tables/blocks/waxed_oxidized_copper_tile_slab.json 2ed72fc0ea28303f5c6d1039662f55c677cb7bcb data/create/loot_tables/blocks/waxed_oxidized_copper_tile_stairs.json -f309ffd94dfb3591efd2fab337a871a0ceff1084 data/create/loot_tables/blocks/waxed_weathered_copper_shingles.json +f0721c371b08214337f3f4fce3a3705840310bdb data/create/loot_tables/blocks/waxed_oxidized_copper_tiles.json 9a7b265a963e122d510de64012ed1d98ad9017f9 data/create/loot_tables/blocks/waxed_weathered_copper_shingle_slab.json 62f25a1bc013e9c3d487d9a53407e58d89907c5b data/create/loot_tables/blocks/waxed_weathered_copper_shingle_stairs.json -26e6a96f50e7f3384f896bf8a5c3d5ff2b422526 data/create/loot_tables/blocks/waxed_weathered_copper_tiles.json +f309ffd94dfb3591efd2fab337a871a0ceff1084 data/create/loot_tables/blocks/waxed_weathered_copper_shingles.json 3fa20e33ced4aee01775db57629b9580a6b8e200 data/create/loot_tables/blocks/waxed_weathered_copper_tile_slab.json 59b28bd57f461482a394dbce9ea10ee25fc7c294 data/create/loot_tables/blocks/waxed_weathered_copper_tile_stairs.json -3cd15ae684bc0e4e41f02b3ee79eafdbf052620c data/create/loot_tables/blocks/weathered_copper_shingles.json +26e6a96f50e7f3384f896bf8a5c3d5ff2b422526 data/create/loot_tables/blocks/waxed_weathered_copper_tiles.json 278a56aa433ba3647107b3bf0553da5a5f6d40dd data/create/loot_tables/blocks/weathered_copper_shingle_slab.json 198babfd55c3a30c6ac61e81d5e01b0cf8fca80a data/create/loot_tables/blocks/weathered_copper_shingle_stairs.json -771d98a6627d707228719e843bc80636b02dc985 data/create/loot_tables/blocks/weathered_copper_tiles.json +3cd15ae684bc0e4e41f02b3ee79eafdbf052620c data/create/loot_tables/blocks/weathered_copper_shingles.json d6862dc9f7d291df618fbce71eebf613711a5517 data/create/loot_tables/blocks/weathered_copper_tile_slab.json 57d5065d53016e4b1ef0fbad9b84605b1546bcc4 data/create/loot_tables/blocks/weathered_copper_tile_stairs.json +771d98a6627d707228719e843bc80636b02dc985 data/create/loot_tables/blocks/weathered_copper_tiles.json f6ba0623b4bcea2f3796df4c65c494fc072d2c21 data/create/loot_tables/blocks/weighted_ejector.json 978263272f632ed79a61d52a0080de0b7b8102d6 data/create/loot_tables/blocks/white_nixie_tube.json 129c6772c1c12271f9b0d41c77f41ce34fc437b1 data/create/loot_tables/blocks/white_sail.json @@ -3546,42 +3546,42 @@ da3692808565988e21ec5b1d5e976338ccc4a037 data/create/recipes/calcite_pillar_from 1157b2eab2ada187ea80feae298b77ed7ece4bfd data/create/recipes/copper_bars_from_ingots_copper_stonecutting.json b9d4f55128aa03ee6f6ab1831e709629a42c147e data/create/recipes/copper_ladder_from_ingots_copper_stonecutting.json 922c5ac48c8eb8b3a39f5626a381c2252fbac107 data/create/recipes/copper_scaffolding_from_ingots_copper_stonecutting.json -bab9fa969ba95850dc6e3bd0723387a61cbb05cd data/create/recipes/copper_shingles_from_ingots_copper_stonecutting.json bb083ae1d057dc0106946e4c68f9469b81724396 data/create/recipes/copper_shingle_slab.json 3689feaca2bd5355fa2d4226cd2cc519fa9b97c1 data/create/recipes/copper_shingle_slab_from_copper_shingles_stonecutting.json bd4cd7119f8371164b278afc679795a3c2a53406 data/create/recipes/copper_shingle_stairs.json 59f672e8e88d5f4655467e2696616b552debaf46 data/create/recipes/copper_shingle_stairs_from_copper_shingles_stonecutting.json -d463aa891c7ae1b2eb1a758e4100c5a1c16cfffd data/create/recipes/copper_tiles_from_ingots_copper_stonecutting.json +bab9fa969ba95850dc6e3bd0723387a61cbb05cd data/create/recipes/copper_shingles_from_ingots_copper_stonecutting.json f64ba3f3c607b43ea77e5bccb7ec2048e5c6e424 data/create/recipes/copper_tile_slab.json 91b0390e0c772d43eb46b94a0113323f0f6a4387 data/create/recipes/copper_tile_slab_from_copper_tiles_stonecutting.json d31a41f6f7ef0bd20abab06cc31a9d2c56187117 data/create/recipes/copper_tile_stairs.json bf1b0a447169029161fb07feacd22d5aa806b2bf data/create/recipes/copper_tile_stairs_from_copper_tiles_stonecutting.json +d463aa891c7ae1b2eb1a758e4100c5a1c16cfffd data/create/recipes/copper_tiles_from_ingots_copper_stonecutting.json daa54c9ff3612521f06cc1979116beafcda852dd data/create/recipes/copycat_panel_from_ingots_zinc_stonecutting.json 745816d2c3fa29ede2510e39edc76f6fecee963f data/create/recipes/copycat_step_from_ingots_zinc_stonecutting.json -255c32272a704109fccdbb071d4dbf602cb8c1d8 data/create/recipes/crafting/copper/waxed_copper_shingles_from_honeycomb.json 57ae13042e0f96676fa322bf24db4976d75ca6bc data/create/recipes/crafting/copper/waxed_copper_shingle_slab_from_honeycomb.json 790565897535ea2e741d0a0ed7c0b561d594b69a data/create/recipes/crafting/copper/waxed_copper_shingle_stairs_from_honeycomb.json -0c6e14c5884257850c7360cba66bc8cca91c84e7 data/create/recipes/crafting/copper/waxed_copper_tiles_from_honeycomb.json +255c32272a704109fccdbb071d4dbf602cb8c1d8 data/create/recipes/crafting/copper/waxed_copper_shingles_from_honeycomb.json 4693ee65a4a5e1c93fc2acce7bfbc438e573ad9a data/create/recipes/crafting/copper/waxed_copper_tile_slab_from_honeycomb.json f8772b915663e3f70b3a2405a23c5ce87e8b8e49 data/create/recipes/crafting/copper/waxed_copper_tile_stairs_from_honeycomb.json -6d0dacc4db8966d38156fe17645732084379a887 data/create/recipes/crafting/copper/waxed_exposed_copper_shingles_from_honeycomb.json +0c6e14c5884257850c7360cba66bc8cca91c84e7 data/create/recipes/crafting/copper/waxed_copper_tiles_from_honeycomb.json 3bc0b81ea61229e24570e083caa4e5870d517e75 data/create/recipes/crafting/copper/waxed_exposed_copper_shingle_slab_from_honeycomb.json 191f34b27bc8966c2b6ba41403cc0933718748d3 data/create/recipes/crafting/copper/waxed_exposed_copper_shingle_stairs_from_honeycomb.json -cdd66bdfddbcdfacb27c030872d10b6e7f1356fd data/create/recipes/crafting/copper/waxed_exposed_copper_tiles_from_honeycomb.json +6d0dacc4db8966d38156fe17645732084379a887 data/create/recipes/crafting/copper/waxed_exposed_copper_shingles_from_honeycomb.json 2f6d2f8da4d4da2ed48e33d8f6e0b32d37a3ce6d data/create/recipes/crafting/copper/waxed_exposed_copper_tile_slab_from_honeycomb.json 4ed8482ed29fe7c3273db733fa141743c181d460 data/create/recipes/crafting/copper/waxed_exposed_copper_tile_stairs_from_honeycomb.json -0ca4e58d715d5ed4b051a94f2dff42d4d413ef07 data/create/recipes/crafting/copper/waxed_oxidized_copper_shingles_from_honeycomb.json +cdd66bdfddbcdfacb27c030872d10b6e7f1356fd data/create/recipes/crafting/copper/waxed_exposed_copper_tiles_from_honeycomb.json b421f16aea7c47fa8a62e69973f30e4e382f8a2c data/create/recipes/crafting/copper/waxed_oxidized_copper_shingle_slab_from_honeycomb.json 7ab7f673f57e219d3e486d0add1d7e2a8820cc6b data/create/recipes/crafting/copper/waxed_oxidized_copper_shingle_stairs_from_honeycomb.json -b7edffb9b1a936fd34fe23defefc8cb9ea4f6977 data/create/recipes/crafting/copper/waxed_oxidized_copper_tiles_from_honeycomb.json +0ca4e58d715d5ed4b051a94f2dff42d4d413ef07 data/create/recipes/crafting/copper/waxed_oxidized_copper_shingles_from_honeycomb.json 24582e83e8d36a6267df5c028addfb44c1a637e6 data/create/recipes/crafting/copper/waxed_oxidized_copper_tile_slab_from_honeycomb.json 9185ea241bcb5f2fe09d0d5c65832ef379e06c58 data/create/recipes/crafting/copper/waxed_oxidized_copper_tile_stairs_from_honeycomb.json -90bce9f262b87fb821210aceb88d09d815d15e5a data/create/recipes/crafting/copper/waxed_weathered_copper_shingles_from_honeycomb.json +b7edffb9b1a936fd34fe23defefc8cb9ea4f6977 data/create/recipes/crafting/copper/waxed_oxidized_copper_tiles_from_honeycomb.json a2cc99ad9b1234f5327971ee535af9bc25d0154c data/create/recipes/crafting/copper/waxed_weathered_copper_shingle_slab_from_honeycomb.json 0952753a079593d748b38ca84b666f2f886f5c1e data/create/recipes/crafting/copper/waxed_weathered_copper_shingle_stairs_from_honeycomb.json -724802d206db185ebf20bafbcfc35fe0f982f58a data/create/recipes/crafting/copper/waxed_weathered_copper_tiles_from_honeycomb.json +90bce9f262b87fb821210aceb88d09d815d15e5a data/create/recipes/crafting/copper/waxed_weathered_copper_shingles_from_honeycomb.json 98d0b72eb20e1d80cc590800ae2d642a47c3ae5f data/create/recipes/crafting/copper/waxed_weathered_copper_tile_slab_from_honeycomb.json 594b8fd5c30a84df97667b2c6dccc5dedd039d26 data/create/recipes/crafting/copper/waxed_weathered_copper_tile_stairs_from_honeycomb.json +724802d206db185ebf20bafbcfc35fe0f982f58a data/create/recipes/crafting/copper/waxed_weathered_copper_tiles_from_honeycomb.json 97c3e430ef2aecf61c457d0b8c4bbd23e1b01cc3 data/create/recipes/crafting/kinetics/black_seat.json 1129d02609125b48af2efa48f84dd3f90d51a341 data/create/recipes/crafting/kinetics/black_seat_from_other_seat.json 9e5a73e2343054d35e2fbfd20f0c49834d1a87a6 data/create/recipes/crafting/kinetics/black_valve_handle_from_other_valve_handle.json @@ -3634,7 +3634,6 @@ b04c1cebcfbcf44c4ced04252f54dbfeb8f9ff12 data/create/recipes/crafting/kinetics/w c3f4fd2206f3885904913289761f2b8b758e4c95 data/create/recipes/crimsite_pillar_from_stone_types_crimsite_stonecutting.json e1815f97fbc2786d77f5378a2696e36050d8a1fd data/create/recipes/crimson_window.json 96009a12fe3f5ebf677ac069999e2ea2adbc9b7c data/create/recipes/crimson_window_pane.json -82cb9be82ce5109781169bdb47bbd49238b9824b data/create/recipes/cut_andesite_bricks_from_stone_types_andesite_stonecutting.json d6a41fc914a4a41478f115d9503658dba04a4d02 data/create/recipes/cut_andesite_brick_slab.json edf981198463ac58524606f86dc15d2265e8b993 data/create/recipes/cut_andesite_brick_slab_from_stone_types_andesite_stonecutting.json 72486864f3a0d31a92212552441eb659f2541b60 data/create/recipes/cut_andesite_brick_slab_recycling.json @@ -3642,6 +3641,7 @@ edf981198463ac58524606f86dc15d2265e8b993 data/create/recipes/cut_andesite_brick_ 22f463c679249738bf1a340a3b8ff14806303a70 data/create/recipes/cut_andesite_brick_stairs_from_stone_types_andesite_stonecutting.json 42b7105c1d776aed25c1c6bbd9254375079d7438 data/create/recipes/cut_andesite_brick_wall.json 7d25517650c9f66b65f0f8841cf9bcda7ea401ec data/create/recipes/cut_andesite_brick_wall_from_stone_types_andesite_stonecutting.json +82cb9be82ce5109781169bdb47bbd49238b9824b data/create/recipes/cut_andesite_bricks_from_stone_types_andesite_stonecutting.json c3ab483224c3adbd467a4ec0b26a1f6a53fe81c4 data/create/recipes/cut_andesite_from_stone_types_andesite_stonecutting.json 9f316131bb538da9f6b1bde9eaaa0a5bd5972a66 data/create/recipes/cut_andesite_slab.json 50dcff201da369bdc591fdc320aae3547f114284 data/create/recipes/cut_andesite_slab_from_stone_types_andesite_stonecutting.json @@ -3650,7 +3650,6 @@ c3ab483224c3adbd467a4ec0b26a1f6a53fe81c4 data/create/recipes/cut_andesite_from_s c284fc46aabae9c5ab79071eb63ec9b07a9d1002 data/create/recipes/cut_andesite_stairs_from_stone_types_andesite_stonecutting.json 3b6e66e92656ab5b0d1e15444db62ccb1cc01866 data/create/recipes/cut_andesite_wall.json 5df6e8d558f656533aff514aee8cdec7cf8d6fdf data/create/recipes/cut_andesite_wall_from_stone_types_andesite_stonecutting.json -e335b15907be053ab0f2649338b12a86371b78f7 data/create/recipes/cut_asurine_bricks_from_stone_types_asurine_stonecutting.json 41d085d3b8fce5b12d601d86fd0e88df9b482aec data/create/recipes/cut_asurine_brick_slab.json cf61e0806a3988a771675a261a540cbb62352d80 data/create/recipes/cut_asurine_brick_slab_from_stone_types_asurine_stonecutting.json 86606a0717bba33f457707d96461fec6a22d23de data/create/recipes/cut_asurine_brick_slab_recycling.json @@ -3658,6 +3657,7 @@ cf61e0806a3988a771675a261a540cbb62352d80 data/create/recipes/cut_asurine_brick_s 382a7faa460ac286631fe063280541f2f499d895 data/create/recipes/cut_asurine_brick_stairs_from_stone_types_asurine_stonecutting.json 09699c116bb201e742fef1fd3c987e9de4606e6a data/create/recipes/cut_asurine_brick_wall.json 8bb8a9f8e8dd0d6585311c326dcf3f40227149a9 data/create/recipes/cut_asurine_brick_wall_from_stone_types_asurine_stonecutting.json +e335b15907be053ab0f2649338b12a86371b78f7 data/create/recipes/cut_asurine_bricks_from_stone_types_asurine_stonecutting.json 0188d62fbeede94f8596dd5cc73d361a160e8c95 data/create/recipes/cut_asurine_from_stone_types_asurine_stonecutting.json 118e87a2a344238009b1bbbe70e6f314e27842d9 data/create/recipes/cut_asurine_slab.json 37c502094ee96da9e4983142dae5e023c6bcfe14 data/create/recipes/cut_asurine_slab_from_stone_types_asurine_stonecutting.json @@ -3666,7 +3666,6 @@ fe3dd5c7d5bdea71a75003cf3d50439d9d21458d data/create/recipes/cut_asurine_slab_re cade93c9328afcacf4507aa7699c4b09fb4592d4 data/create/recipes/cut_asurine_stairs_from_stone_types_asurine_stonecutting.json 80bec79b5daea4b2b72c0f5e9f189c1044583465 data/create/recipes/cut_asurine_wall.json 45a712e41a74982cfb94a39da199ec6c95eef798 data/create/recipes/cut_asurine_wall_from_stone_types_asurine_stonecutting.json -da11f21280ba1ed06ffe8afe77db3e9e1bbcb1a3 data/create/recipes/cut_calcite_bricks_from_stone_types_calcite_stonecutting.json 98e849c743ed1e4397bf6168215dfa7006a804c4 data/create/recipes/cut_calcite_brick_slab.json 1c21eb6c785729a8ea274513e1313aed952e105e data/create/recipes/cut_calcite_brick_slab_from_stone_types_calcite_stonecutting.json 2a3f078f7f40ba3bc5c17a037db1f8ee415e4e3f data/create/recipes/cut_calcite_brick_slab_recycling.json @@ -3674,6 +3673,7 @@ e4267c62bc6cfc8373df29ee2685f1e1b286b638 data/create/recipes/cut_calcite_brick_s 10fe509e01e3ed1b04bd2f384c0aa3db96b117f1 data/create/recipes/cut_calcite_brick_stairs_from_stone_types_calcite_stonecutting.json 9b55a6c9cf0ce697a242684953daf9aa94d024dc data/create/recipes/cut_calcite_brick_wall.json 1e67376e484923b84bd64b0b22b4e55b581ac419 data/create/recipes/cut_calcite_brick_wall_from_stone_types_calcite_stonecutting.json +da11f21280ba1ed06ffe8afe77db3e9e1bbcb1a3 data/create/recipes/cut_calcite_bricks_from_stone_types_calcite_stonecutting.json 98b014b64c97371f04aaacbdd23e13e274e36e3b data/create/recipes/cut_calcite_from_stone_types_calcite_stonecutting.json fcab91f11fe97a194b2c1b16115206166d3cd634 data/create/recipes/cut_calcite_slab.json 8426a494b776148056cb4525e62744d0be8b28cd data/create/recipes/cut_calcite_slab_from_stone_types_calcite_stonecutting.json @@ -3682,7 +3682,6 @@ fcab91f11fe97a194b2c1b16115206166d3cd634 data/create/recipes/cut_calcite_slab.js a7e7fb425d3c1f21f5ed53da79957363fed824df data/create/recipes/cut_calcite_stairs_from_stone_types_calcite_stonecutting.json 73eaf7bffa38bc874974871f3002cd3ee7f0c36e data/create/recipes/cut_calcite_wall.json 01b4c23362f15ee0e5c207c46383f96032c89d98 data/create/recipes/cut_calcite_wall_from_stone_types_calcite_stonecutting.json -07aff2bb6424de46463b2c965418ed52efd0a790 data/create/recipes/cut_crimsite_bricks_from_stone_types_crimsite_stonecutting.json 8ffb2c1c747f19ea37c0da3fe248b6c58981c9f6 data/create/recipes/cut_crimsite_brick_slab.json 86c3a5c64561052489b3ceb9e08be5a8729198a9 data/create/recipes/cut_crimsite_brick_slab_from_stone_types_crimsite_stonecutting.json e3215d4e651e70402b896ba50975cb2f23d16278 data/create/recipes/cut_crimsite_brick_slab_recycling.json @@ -3690,6 +3689,7 @@ e49f6e319fae9058cbece0e332a11e108234e608 data/create/recipes/cut_crimsite_brick_ c7186fb1a75f59aff929e843f50a162a090b7bb3 data/create/recipes/cut_crimsite_brick_stairs_from_stone_types_crimsite_stonecutting.json 272d8d01730a88eff4fc6923e93962650b992c46 data/create/recipes/cut_crimsite_brick_wall.json 13ac9464098e8c67e820dc898c025ab0382d852a data/create/recipes/cut_crimsite_brick_wall_from_stone_types_crimsite_stonecutting.json +07aff2bb6424de46463b2c965418ed52efd0a790 data/create/recipes/cut_crimsite_bricks_from_stone_types_crimsite_stonecutting.json 18ce9ff32eda2d869bd11f398a86e78b71f6d0fe data/create/recipes/cut_crimsite_from_stone_types_crimsite_stonecutting.json c39166aa6267ec5bc71893d5756955abfb644217 data/create/recipes/cut_crimsite_slab.json 6271d5bc0377814ba06061bfffcb812ca2ef8f03 data/create/recipes/cut_crimsite_slab_from_stone_types_crimsite_stonecutting.json @@ -3698,7 +3698,6 @@ acfe33dbb889c820c213bcbc8593766703bf3a25 data/create/recipes/cut_crimsite_slab_r 90b03cf1e72d3b803e33755832e0722ff264681b data/create/recipes/cut_crimsite_stairs_from_stone_types_crimsite_stonecutting.json 8dfe19522878af232deaa1fc13d83cf785684cba data/create/recipes/cut_crimsite_wall.json 18f9548175baab0173785d7ef308096067712dd2 data/create/recipes/cut_crimsite_wall_from_stone_types_crimsite_stonecutting.json -de1a11b7ed71f1f7aeea2791fe922feef689fd35 data/create/recipes/cut_deepslate_bricks_from_stone_types_deepslate_stonecutting.json 5e5c0e6b1b3e204de3c48fb6a4cd473a150979c2 data/create/recipes/cut_deepslate_brick_slab.json 2c0795b92759dab751f86f50aa80440df2245526 data/create/recipes/cut_deepslate_brick_slab_from_stone_types_deepslate_stonecutting.json dbcc41c48cf28b71dcd9f3b6ecae43c8de681532 data/create/recipes/cut_deepslate_brick_slab_recycling.json @@ -3706,6 +3705,7 @@ e21f8dc33e70ebd43ea79a4afaf3b4e8a449f4bd data/create/recipes/cut_deepslate_brick 7b3489e5b629a995691be117c5a378769c743449 data/create/recipes/cut_deepslate_brick_stairs_from_stone_types_deepslate_stonecutting.json 158bb41bffebb2543e4aa2d5f14cc8af1cdd8671 data/create/recipes/cut_deepslate_brick_wall.json 73a07a5fa665bb20d131f0a0e40806116316928a data/create/recipes/cut_deepslate_brick_wall_from_stone_types_deepslate_stonecutting.json +de1a11b7ed71f1f7aeea2791fe922feef689fd35 data/create/recipes/cut_deepslate_bricks_from_stone_types_deepslate_stonecutting.json 992fdc2eba2afe3ff8aad0ceee5424ecd3f3026d data/create/recipes/cut_deepslate_from_stone_types_deepslate_stonecutting.json 064e2f5edd9209af7742b0f0eb45204453bed46f data/create/recipes/cut_deepslate_slab.json f341d30b7fd427dea09a51d67e1e9532e5184be8 data/create/recipes/cut_deepslate_slab_from_stone_types_deepslate_stonecutting.json @@ -3714,7 +3714,6 @@ c08e12e44344efca550efa8ba14d0cb2f9f6c2c6 data/create/recipes/cut_deepslate_stair e6deec1352fb5c74c470dc488b71e5f8f55bdfbf data/create/recipes/cut_deepslate_stairs_from_stone_types_deepslate_stonecutting.json 2ad7fb3f3a143e58bea8eefe4cd9db3d1c37a3e6 data/create/recipes/cut_deepslate_wall.json e752527479f71f96bb34878008bf8cfb23fd3045 data/create/recipes/cut_deepslate_wall_from_stone_types_deepslate_stonecutting.json -2c23d13f48f3685bda6c564e080053fbfa71ab99 data/create/recipes/cut_diorite_bricks_from_stone_types_diorite_stonecutting.json 90b83c2a2026d70f49c91813305fdee721926db9 data/create/recipes/cut_diorite_brick_slab.json 9d51c690c77321437561a006dc2f9bba975875e6 data/create/recipes/cut_diorite_brick_slab_from_stone_types_diorite_stonecutting.json fa76e64ac9b569f5d5f2f1ecc54e51f9be15aacf data/create/recipes/cut_diorite_brick_slab_recycling.json @@ -3722,6 +3721,7 @@ aa6aea99e9ce2d5dc3d6555ab3d17928bca6195e data/create/recipes/cut_diorite_brick_s 9a26c4097519a9300e591b6578bbaf6c11f909e1 data/create/recipes/cut_diorite_brick_stairs_from_stone_types_diorite_stonecutting.json 78d37df17c7e2be73ce1d226ee552ff3f49b9e4f data/create/recipes/cut_diorite_brick_wall.json f668f2c78a779bc3d0546a82dea02b9f4688e05c data/create/recipes/cut_diorite_brick_wall_from_stone_types_diorite_stonecutting.json +2c23d13f48f3685bda6c564e080053fbfa71ab99 data/create/recipes/cut_diorite_bricks_from_stone_types_diorite_stonecutting.json 1918ecb2ab16ca7dbb30eee4852b67dd963d872e data/create/recipes/cut_diorite_from_stone_types_diorite_stonecutting.json 07fda5c89128648856f948a03ac56a2a2693cf1b data/create/recipes/cut_diorite_slab.json 28765ac7f8b62373b32f014d1dd7f4afb50e1906 data/create/recipes/cut_diorite_slab_from_stone_types_diorite_stonecutting.json @@ -3730,7 +3730,6 @@ dd5f3c59a5d292f7b5c046be35da7f67e8383aa1 data/create/recipes/cut_diorite_slab_re be2c6c01630b90895e7215edce3d02352793dbc4 data/create/recipes/cut_diorite_stairs_from_stone_types_diorite_stonecutting.json 8984b7b7dbc7e65ee04886516501a13278e889e9 data/create/recipes/cut_diorite_wall.json 8ff5d1ecff2202595f7cba5bd65c466c53ac2cc5 data/create/recipes/cut_diorite_wall_from_stone_types_diorite_stonecutting.json -10550b023989113c26d430136daf1dc49f10ce63 data/create/recipes/cut_dripstone_bricks_from_stone_types_dripstone_stonecutting.json 95717a80bb8ae296c2f77478a8f42b88cea88996 data/create/recipes/cut_dripstone_brick_slab.json f04bf1189b53e24974779d9e959e8973d9677162 data/create/recipes/cut_dripstone_brick_slab_from_stone_types_dripstone_stonecutting.json 332534fc2909ca83f5f7f4ab3adf92680bb17f79 data/create/recipes/cut_dripstone_brick_slab_recycling.json @@ -3738,6 +3737,7 @@ f04bf1189b53e24974779d9e959e8973d9677162 data/create/recipes/cut_dripstone_brick 17bf8160eaf16655d454ddfe22b82c9a86462146 data/create/recipes/cut_dripstone_brick_stairs_from_stone_types_dripstone_stonecutting.json 7d638d156326a2e542ed94837273d9cca5cf4fce data/create/recipes/cut_dripstone_brick_wall.json 154931db54115cf4a64147cdd6d1eb7efff48737 data/create/recipes/cut_dripstone_brick_wall_from_stone_types_dripstone_stonecutting.json +10550b023989113c26d430136daf1dc49f10ce63 data/create/recipes/cut_dripstone_bricks_from_stone_types_dripstone_stonecutting.json 7147f9199f174c9864109fe5723528921aaa0c46 data/create/recipes/cut_dripstone_from_stone_types_dripstone_stonecutting.json f2800b467eac75d0099f2f07e09b47115df4e09f data/create/recipes/cut_dripstone_slab.json a4f62a1a30592f82789988f93d8ae35d176eca59 data/create/recipes/cut_dripstone_slab_from_stone_types_dripstone_stonecutting.json @@ -3746,7 +3746,6 @@ a4f62a1a30592f82789988f93d8ae35d176eca59 data/create/recipes/cut_dripstone_slab_ f2df5efedb6fb25ecb877b888007990082d9aca4 data/create/recipes/cut_dripstone_stairs_from_stone_types_dripstone_stonecutting.json a177092d0270f9e07a4f9bef4d0c8fb2ed91d3bc data/create/recipes/cut_dripstone_wall.json a3731ef689d3ac790bc3e3fd507f1134c99a751a data/create/recipes/cut_dripstone_wall_from_stone_types_dripstone_stonecutting.json -9c4c64666b18d3adb11cd3d56667fabf6e88dfe2 data/create/recipes/cut_granite_bricks_from_stone_types_granite_stonecutting.json aa454bebffd7e77cfa5c1bd711bfbac27e3c5a14 data/create/recipes/cut_granite_brick_slab.json d073b9b0b8ca2fbdc5e1ed16f6f195a5f3af4588 data/create/recipes/cut_granite_brick_slab_from_stone_types_granite_stonecutting.json 1dfd539c17a3342a0cd194ce1465a808aacbeda3 data/create/recipes/cut_granite_brick_slab_recycling.json @@ -3754,6 +3753,7 @@ e069aa5c316feb2823ef98e8e6c89bb1bed23d2e data/create/recipes/cut_granite_brick_s f38fc7014aa83d4914d50d87ee3f8f762c078a78 data/create/recipes/cut_granite_brick_stairs_from_stone_types_granite_stonecutting.json 0fd9c3a778c7bdcd7aa06f892a9c260ad664d367 data/create/recipes/cut_granite_brick_wall.json b81db94b6228f512049324dd1436880f1e86e444 data/create/recipes/cut_granite_brick_wall_from_stone_types_granite_stonecutting.json +9c4c64666b18d3adb11cd3d56667fabf6e88dfe2 data/create/recipes/cut_granite_bricks_from_stone_types_granite_stonecutting.json 01970a95f17648a7ef1fb0337ee2e82eb2279e9e data/create/recipes/cut_granite_from_stone_types_granite_stonecutting.json 8fc1c51591e590c8718be0500a4dbcc2b47830ce data/create/recipes/cut_granite_slab.json d239323b7a3b65b2fd7005350a90d578671c2b81 data/create/recipes/cut_granite_slab_from_stone_types_granite_stonecutting.json @@ -3762,7 +3762,6 @@ d239323b7a3b65b2fd7005350a90d578671c2b81 data/create/recipes/cut_granite_slab_fr 3d85d483073d37fea7d9a95831b3b856c0725b98 data/create/recipes/cut_granite_stairs_from_stone_types_granite_stonecutting.json 3d4130fe5fe6e963fd5e10534e729e0448b9f05f data/create/recipes/cut_granite_wall.json d43a876bf89bf3536c80fd5e3ef0ee36c147cd06 data/create/recipes/cut_granite_wall_from_stone_types_granite_stonecutting.json -7cdd3cf302cfe4ef21c0a89dadef4f781e307bb0 data/create/recipes/cut_limestone_bricks_from_stone_types_limestone_stonecutting.json 0e3285206947bcfdf9606d3f8e61ea7d2899f7d2 data/create/recipes/cut_limestone_brick_slab.json c3d3ff37e29c435b2a13d30bd4ded0f6ca9fbfbc data/create/recipes/cut_limestone_brick_slab_from_stone_types_limestone_stonecutting.json 459babb2bd01e9e1ece4c8cd2865690997f01c66 data/create/recipes/cut_limestone_brick_slab_recycling.json @@ -3770,6 +3769,7 @@ d4f8dc640becf1c35416016500424ecd68d7ecee data/create/recipes/cut_limestone_brick 570983b2b27862dabe9f3d1bcd76d2909b8bdb3c data/create/recipes/cut_limestone_brick_stairs_from_stone_types_limestone_stonecutting.json aad4342a726fd65ca2b4c52a4e8857190e50b5be data/create/recipes/cut_limestone_brick_wall.json 5ac226aff9d854efc47ed71241e6c098b170b9b0 data/create/recipes/cut_limestone_brick_wall_from_stone_types_limestone_stonecutting.json +7cdd3cf302cfe4ef21c0a89dadef4f781e307bb0 data/create/recipes/cut_limestone_bricks_from_stone_types_limestone_stonecutting.json 329950373aaaf8e70c54cf5e2467c7a84f372078 data/create/recipes/cut_limestone_from_stone_types_limestone_stonecutting.json cbacfd31703ac908d28e42968bb571dccfa20612 data/create/recipes/cut_limestone_slab.json 628a0a64c2dcd63f17a3ec9ce55ac643b194eacc data/create/recipes/cut_limestone_slab_from_stone_types_limestone_stonecutting.json @@ -3778,7 +3778,6 @@ cbacfd31703ac908d28e42968bb571dccfa20612 data/create/recipes/cut_limestone_slab. ba301da212ee14ff42c38487d0906a2da203e3c3 data/create/recipes/cut_limestone_stairs_from_stone_types_limestone_stonecutting.json d2aac4ac16f9c842af1efd3896dd3250f6d8424e data/create/recipes/cut_limestone_wall.json b14e6972f8586e569a7ab4ecf6ed5d6db1a2bded data/create/recipes/cut_limestone_wall_from_stone_types_limestone_stonecutting.json -a1a2b95283d88e1d990e00da9a095fe928b2aa2f data/create/recipes/cut_ochrum_bricks_from_stone_types_ochrum_stonecutting.json d5a4fa7787d2e56e0b5c8d533567543b93cf694b data/create/recipes/cut_ochrum_brick_slab.json 58514a5f216706e9bb62b27ad03701fe02bac013 data/create/recipes/cut_ochrum_brick_slab_from_stone_types_ochrum_stonecutting.json 6cc3167ebf075d7b302a359d1afdddf5753d0e26 data/create/recipes/cut_ochrum_brick_slab_recycling.json @@ -3786,6 +3785,7 @@ d5a4fa7787d2e56e0b5c8d533567543b93cf694b data/create/recipes/cut_ochrum_brick_sl ec6339d6658b0d32e46c8a4a4e06d94a388a6332 data/create/recipes/cut_ochrum_brick_stairs_from_stone_types_ochrum_stonecutting.json c4139ae7a9742f7111d308fe66bf1d627533550b data/create/recipes/cut_ochrum_brick_wall.json 1b8a4c81680df542a5e6b9e665c96649cf3eb7fa data/create/recipes/cut_ochrum_brick_wall_from_stone_types_ochrum_stonecutting.json +a1a2b95283d88e1d990e00da9a095fe928b2aa2f data/create/recipes/cut_ochrum_bricks_from_stone_types_ochrum_stonecutting.json 2b967f3424196b5da9b396ea58fb969d406af789 data/create/recipes/cut_ochrum_from_stone_types_ochrum_stonecutting.json 5baa701f3cbe8d69e2e6a5554622dd78ef3ac451 data/create/recipes/cut_ochrum_slab.json 9a26cba276cf135a10c71d31f5b960b2ee6ac444 data/create/recipes/cut_ochrum_slab_from_stone_types_ochrum_stonecutting.json @@ -3794,7 +3794,6 @@ c4139ae7a9742f7111d308fe66bf1d627533550b data/create/recipes/cut_ochrum_brick_wa 75a232ccede0ffa7feb3e69da17c6a514a908907 data/create/recipes/cut_ochrum_stairs_from_stone_types_ochrum_stonecutting.json d9c05b7e4ce4ee86d0f6a9e1ee6c1b585ffee58b data/create/recipes/cut_ochrum_wall.json ee0dff8e1317aeffd061688879b97e81a00b7adb data/create/recipes/cut_ochrum_wall_from_stone_types_ochrum_stonecutting.json -087eefb8ffd61fd88f1db6ca25f9ac31e93f2fdf data/create/recipes/cut_scorchia_bricks_from_stone_types_scorchia_stonecutting.json 72ac9293e5791df07914e2d3ed00e5ff59d64b08 data/create/recipes/cut_scorchia_brick_slab.json 2f38c410d5eb93bdb8c8be0f68ac89726e3c765c data/create/recipes/cut_scorchia_brick_slab_from_stone_types_scorchia_stonecutting.json e296e6af6865bf6e4618dab8a96bb88f6999a9a5 data/create/recipes/cut_scorchia_brick_slab_recycling.json @@ -3802,6 +3801,7 @@ bd5984a6b96443319b7fad32db771d8ded0b0591 data/create/recipes/cut_scorchia_brick_ bd5c803c855222a29998dd784e6d12a18dd612d9 data/create/recipes/cut_scorchia_brick_stairs_from_stone_types_scorchia_stonecutting.json adfe0b08b5b72e579d47f36a4f835045e433e7f7 data/create/recipes/cut_scorchia_brick_wall.json 37fc5ae45d0260de9a5c45b0a1b208e4d146a562 data/create/recipes/cut_scorchia_brick_wall_from_stone_types_scorchia_stonecutting.json +087eefb8ffd61fd88f1db6ca25f9ac31e93f2fdf data/create/recipes/cut_scorchia_bricks_from_stone_types_scorchia_stonecutting.json f6dfd648418f24da093b80978c2f6e070f33ff6d data/create/recipes/cut_scorchia_from_stone_types_scorchia_stonecutting.json 7df99605c0c8761aeb9301d5391e1f16d41f89b3 data/create/recipes/cut_scorchia_slab.json fbd9a92d3c3d9e823cac51347320219f1734ec04 data/create/recipes/cut_scorchia_slab_from_stone_types_scorchia_stonecutting.json @@ -3810,7 +3810,6 @@ ad54182c3142ac9d9dd9bb4c5acc18f82e3fc5e5 data/create/recipes/cut_scorchia_stairs 1ddfefce136201ae78dbc53ba472080332fd6366 data/create/recipes/cut_scorchia_stairs_from_stone_types_scorchia_stonecutting.json 0a011b7cee33200fec5546168734c330952124da data/create/recipes/cut_scorchia_wall.json c594d886a303ad6e24d1283004442835ee861fbc data/create/recipes/cut_scorchia_wall_from_stone_types_scorchia_stonecutting.json -8650c0db70a3521b50404252106e0185b4f25a45 data/create/recipes/cut_scoria_bricks_from_stone_types_scoria_stonecutting.json 8baf09b5ff2004d71091b6f95307aa179a21f4df data/create/recipes/cut_scoria_brick_slab.json e7080ca9b6a507bec4a4a3dd52a28c1c33975628 data/create/recipes/cut_scoria_brick_slab_from_stone_types_scoria_stonecutting.json f5b56f6eb9c1ac0f8168b2b0f0b0ab00655ebfdb data/create/recipes/cut_scoria_brick_slab_recycling.json @@ -3818,6 +3817,7 @@ f5b56f6eb9c1ac0f8168b2b0f0b0ab00655ebfdb data/create/recipes/cut_scoria_brick_sl 3fd560355163f0afafefe886e75fd8b2c3cf2b6f data/create/recipes/cut_scoria_brick_stairs_from_stone_types_scoria_stonecutting.json ed803a4cdcf1dd01af03fff52e783f3539f78546 data/create/recipes/cut_scoria_brick_wall.json 553642a4e0dc5f934da8127a427ccdf53d3f51f9 data/create/recipes/cut_scoria_brick_wall_from_stone_types_scoria_stonecutting.json +8650c0db70a3521b50404252106e0185b4f25a45 data/create/recipes/cut_scoria_bricks_from_stone_types_scoria_stonecutting.json 5702063be3d38fa6b3ae5c998337676a0cf91149 data/create/recipes/cut_scoria_from_stone_types_scoria_stonecutting.json 295356022aee8a33272b430879615af638fc5a2c data/create/recipes/cut_scoria_slab.json 1656e822e823fcdf04120b55235aa477845a69a6 data/create/recipes/cut_scoria_slab_from_stone_types_scoria_stonecutting.json @@ -3826,7 +3826,6 @@ d0c88c037004911e377d88cf5a28ff85a413d07e data/create/recipes/cut_scoria_slab_rec 8748df6152c923930452397367562bb6007058cf data/create/recipes/cut_scoria_stairs_from_stone_types_scoria_stonecutting.json 7f9bd9de7bfba21eef449f8e11ffc8cf37de6b88 data/create/recipes/cut_scoria_wall.json 42235c6ded520ecda3321e8cd8910dcfa05cd61e data/create/recipes/cut_scoria_wall_from_stone_types_scoria_stonecutting.json -c02b4daf0050d705c145c0698aaa3094724ba2f1 data/create/recipes/cut_tuff_bricks_from_stone_types_tuff_stonecutting.json 214b6219b86d94ea5705e40f254a4d9a9ac894b7 data/create/recipes/cut_tuff_brick_slab.json 9e0182206fab754daa0596259be0b98a712ba859 data/create/recipes/cut_tuff_brick_slab_from_stone_types_tuff_stonecutting.json 86938ed4ef969e85163c25e2a60181433247b73b data/create/recipes/cut_tuff_brick_slab_recycling.json @@ -3834,6 +3833,7 @@ b4212528d6c8893c1d57c0a5ada60673105e399d data/create/recipes/cut_tuff_brick_stai 90f3241a3eb47d9b0902b639fadee76e41b92a72 data/create/recipes/cut_tuff_brick_stairs_from_stone_types_tuff_stonecutting.json b920d14ac41465f70b1fb8211c1c06d6c41ccadb data/create/recipes/cut_tuff_brick_wall.json aa41f89028dfa995dc11b881894e5a5993e4c4f9 data/create/recipes/cut_tuff_brick_wall_from_stone_types_tuff_stonecutting.json +c02b4daf0050d705c145c0698aaa3094724ba2f1 data/create/recipes/cut_tuff_bricks_from_stone_types_tuff_stonecutting.json 41dc800ae0a8918f4602d610ff0ba9714cdfe8dc data/create/recipes/cut_tuff_from_stone_types_tuff_stonecutting.json 573fff8b4fba92289dc6b113b58c8de25427f62d data/create/recipes/cut_tuff_slab.json 94667fb1e6203bd66bef10acfee7cd990009d26f data/create/recipes/cut_tuff_slab_from_stone_types_tuff_stonecutting.json @@ -3842,7 +3842,6 @@ aa41f89028dfa995dc11b881894e5a5993e4c4f9 data/create/recipes/cut_tuff_brick_wall 3b3ba319bd67a4e7f555cfcb54f9dc1fc22cf015 data/create/recipes/cut_tuff_stairs_from_stone_types_tuff_stonecutting.json 0c241d763e87b23b8799528e132e0d12b0e16141 data/create/recipes/cut_tuff_wall.json 5705b0312c5c70d48662c2ff375f0b2cfe3b4902 data/create/recipes/cut_tuff_wall_from_stone_types_tuff_stonecutting.json -8ab3c640b57421a8c0341ab4ec5bade31376d059 data/create/recipes/cut_veridium_bricks_from_stone_types_veridium_stonecutting.json 822f97726c72d31c4c614767c08140b3535e0640 data/create/recipes/cut_veridium_brick_slab.json 1705fd5fc9ecc9a650812c89f500b5ef9aec2626 data/create/recipes/cut_veridium_brick_slab_from_stone_types_veridium_stonecutting.json 238aeedf55624671809a37246581d28fe6b2c19e data/create/recipes/cut_veridium_brick_slab_recycling.json @@ -3850,6 +3849,7 @@ dfbef691643cead7111b3b1c51aabcda8419bc19 data/create/recipes/cut_veridium_brick_ db2ea87f3ec8924ba9e0b87cd6a6edeb93c0c2d8 data/create/recipes/cut_veridium_brick_stairs_from_stone_types_veridium_stonecutting.json 5e5c9fab7ba7143d206df7d8184742fb1a17c99c data/create/recipes/cut_veridium_brick_wall.json ed752a7f698e3ecbb5e4f848a78f8b3c7c6bf12e data/create/recipes/cut_veridium_brick_wall_from_stone_types_veridium_stonecutting.json +8ab3c640b57421a8c0341ab4ec5bade31376d059 data/create/recipes/cut_veridium_bricks_from_stone_types_veridium_stonecutting.json e0355543105e4ec9d672d2a050e70b5c198ea472 data/create/recipes/cut_veridium_from_stone_types_veridium_stonecutting.json fb3c671f64676538ea3aa96be483ac15b3cdeb3d data/create/recipes/cut_veridium_slab.json 7d7c80ac03ad8623f9a5d7f0ff0bb6f68985efa5 data/create/recipes/cut_veridium_slab_from_stone_types_veridium_stonecutting.json @@ -4033,7 +4033,6 @@ a157a43e7788d285b8d72eade5955369c9b9a1de data/create/recipes/rose_quartz_block_f 1268cc2bdd088d26b84fb4e481db27af61f94bd1 data/create/recipes/scorchia_pillar_from_stone_types_scorchia_stonecutting.json 2e8f4cdb3498547a5e6fe658bb33d4be5ce8f54b data/create/recipes/scoria_from_stone_types_scoria_stonecutting.json 770d3453c75f77b16db661f6e636892d3117690b data/create/recipes/scoria_pillar_from_stone_types_scoria_stonecutting.json -75dc56fcdcd6a10288f2d607bf6dcbbe10b35a64 data/create/recipes/small_andesite_bricks_from_stone_types_andesite_stonecutting.json 2e86fddc76285b4e380b845eb1150580b134d0ac data/create/recipes/small_andesite_brick_slab.json 311727e5c08ddbe0aa26275be74e9b83201ac8ab data/create/recipes/small_andesite_brick_slab_from_stone_types_andesite_stonecutting.json 2767e239c9d704b6bb5325b4f40e0aa0acdcdce1 data/create/recipes/small_andesite_brick_slab_recycling.json @@ -4041,7 +4040,7 @@ a157a43e7788d285b8d72eade5955369c9b9a1de data/create/recipes/rose_quartz_block_f 9e82896e00c1e14e514fac818e11e5b9ef5b10d7 data/create/recipes/small_andesite_brick_stairs_from_stone_types_andesite_stonecutting.json 5287d389b4954d954881d9f0293c52870bba88d0 data/create/recipes/small_andesite_brick_wall.json 1172ca76affd948c50b207124ee03c4f480f4ee8 data/create/recipes/small_andesite_brick_wall_from_stone_types_andesite_stonecutting.json -e3b69122b2cfe64b043384235eeb6d04f346e58b data/create/recipes/small_asurine_bricks_from_stone_types_asurine_stonecutting.json +75dc56fcdcd6a10288f2d607bf6dcbbe10b35a64 data/create/recipes/small_andesite_bricks_from_stone_types_andesite_stonecutting.json 9196a055491052afc14ed01667cccf2a0920e793 data/create/recipes/small_asurine_brick_slab.json f4cc3330837a647c098ccb24fbbbf583c3f960fc data/create/recipes/small_asurine_brick_slab_from_stone_types_asurine_stonecutting.json 063b2f0ad7e93698999922040132eb2b23661a38 data/create/recipes/small_asurine_brick_slab_recycling.json @@ -4049,7 +4048,7 @@ a85d2f957223f87ffa2c3f63cdf6f9f0f84bb921 data/create/recipes/small_asurine_brick c7cb218b0d8a1e358d593fc1fef82fc074289552 data/create/recipes/small_asurine_brick_stairs_from_stone_types_asurine_stonecutting.json 08d10ee57995e67ac1fb5feba04b03aee51dbe16 data/create/recipes/small_asurine_brick_wall.json 4c0aa6203295a36a6d7ffe9d7bf0973277162689 data/create/recipes/small_asurine_brick_wall_from_stone_types_asurine_stonecutting.json -07125218f9025833afa189fa0090f4d6b4660db0 data/create/recipes/small_calcite_bricks_from_stone_types_calcite_stonecutting.json +e3b69122b2cfe64b043384235eeb6d04f346e58b data/create/recipes/small_asurine_bricks_from_stone_types_asurine_stonecutting.json a72719de028ca9e07756dae6031af48525520fc2 data/create/recipes/small_calcite_brick_slab.json d8ebf6f1eb2e2372fb20def956398089adec5d13 data/create/recipes/small_calcite_brick_slab_from_stone_types_calcite_stonecutting.json ab4cfc2b34989d41a434781a3150ecd530c4f15b data/create/recipes/small_calcite_brick_slab_recycling.json @@ -4057,7 +4056,7 @@ c77a7700d978e23db14d947915591061dda8eab3 data/create/recipes/small_calcite_brick 4e066bfc60ea142d54ce939d025b6679ac9634ad data/create/recipes/small_calcite_brick_stairs_from_stone_types_calcite_stonecutting.json 64e53d8090fa26cc4cb62efea7c1615ff7f705c2 data/create/recipes/small_calcite_brick_wall.json 3ba736ae76249fa61692c13f7879af954f9bbd36 data/create/recipes/small_calcite_brick_wall_from_stone_types_calcite_stonecutting.json -a3309c81f84bf4fb78e9db2316fb758f9b2f8429 data/create/recipes/small_crimsite_bricks_from_stone_types_crimsite_stonecutting.json +07125218f9025833afa189fa0090f4d6b4660db0 data/create/recipes/small_calcite_bricks_from_stone_types_calcite_stonecutting.json 92cf7e99229c1e72405bb0875e6f939b3f5aea12 data/create/recipes/small_crimsite_brick_slab.json b993e081103c019b7b9b73b38ef8c408fb4500ac data/create/recipes/small_crimsite_brick_slab_from_stone_types_crimsite_stonecutting.json 7f6fa1fab65d910388f5f2ec4ee7d99cbda8df57 data/create/recipes/small_crimsite_brick_slab_recycling.json @@ -4065,7 +4064,7 @@ b993e081103c019b7b9b73b38ef8c408fb4500ac data/create/recipes/small_crimsite_bric 260da721849d1afd6f431d51538d1587ee3af8d5 data/create/recipes/small_crimsite_brick_stairs_from_stone_types_crimsite_stonecutting.json 093ac919f793111b442029198383a9de5b6df027 data/create/recipes/small_crimsite_brick_wall.json 8b8280a8282fa8718620ee3d69182e241a7852c0 data/create/recipes/small_crimsite_brick_wall_from_stone_types_crimsite_stonecutting.json -e7a3cb889ce6b530cd40f19e23bad943374e61b5 data/create/recipes/small_deepslate_bricks_from_stone_types_deepslate_stonecutting.json +a3309c81f84bf4fb78e9db2316fb758f9b2f8429 data/create/recipes/small_crimsite_bricks_from_stone_types_crimsite_stonecutting.json 022690548a46f5cc63adda3626824a81c6ebf490 data/create/recipes/small_deepslate_brick_slab.json 655be9ddf21dea2255fb2cb2628a5fee39eb10e2 data/create/recipes/small_deepslate_brick_slab_from_stone_types_deepslate_stonecutting.json d6d3db5604279cd402f64dbdeae7c3bee6d7ab78 data/create/recipes/small_deepslate_brick_slab_recycling.json @@ -4073,7 +4072,7 @@ d6d3db5604279cd402f64dbdeae7c3bee6d7ab78 data/create/recipes/small_deepslate_bri 0a458e8248fe395748bd6025d43c002db5a7d343 data/create/recipes/small_deepslate_brick_stairs_from_stone_types_deepslate_stonecutting.json 96e2c36ac2f2899c9681f12f43c8ae232ae09180 data/create/recipes/small_deepslate_brick_wall.json e5644f4227b9cc9b98158ce3ded98bff1ffb97f9 data/create/recipes/small_deepslate_brick_wall_from_stone_types_deepslate_stonecutting.json -38b80603a86df24f6be0df9fd5f7d9b7aa33d2f9 data/create/recipes/small_diorite_bricks_from_stone_types_diorite_stonecutting.json +e7a3cb889ce6b530cd40f19e23bad943374e61b5 data/create/recipes/small_deepslate_bricks_from_stone_types_deepslate_stonecutting.json 6c66b44941c8b97cfec5948b5d8b08355f8d8f67 data/create/recipes/small_diorite_brick_slab.json 801f6cc6e06db56344b37c9b76c69f921c6d9293 data/create/recipes/small_diorite_brick_slab_from_stone_types_diorite_stonecutting.json c1fe4bff306e2d2b5d5595e4b35dd85f7e6bf0ce data/create/recipes/small_diorite_brick_slab_recycling.json @@ -4081,7 +4080,7 @@ af6feedf00bdfa45c1b8f0dd46ddaa80da622fed data/create/recipes/small_diorite_brick 30a6f2bdfec2b3f578572c9f94112906411e7c54 data/create/recipes/small_diorite_brick_stairs_from_stone_types_diorite_stonecutting.json 8728b791808736de2ac31e8dc81aa43638ae0ac8 data/create/recipes/small_diorite_brick_wall.json 7a1fdcef7091d76230fbee410fa5241f584845c4 data/create/recipes/small_diorite_brick_wall_from_stone_types_diorite_stonecutting.json -8840d538648516dd02628fbe3ea4f032ceda78bb data/create/recipes/small_dripstone_bricks_from_stone_types_dripstone_stonecutting.json +38b80603a86df24f6be0df9fd5f7d9b7aa33d2f9 data/create/recipes/small_diorite_bricks_from_stone_types_diorite_stonecutting.json 39a545b60040bd2d922cd3bd5af5036b1b9b23ef data/create/recipes/small_dripstone_brick_slab.json c91e4dc211305456c38e5823def91811ad851202 data/create/recipes/small_dripstone_brick_slab_from_stone_types_dripstone_stonecutting.json 55bb37d07e841bb8eecf2013445c01c8e09ff824 data/create/recipes/small_dripstone_brick_slab_recycling.json @@ -4089,7 +4088,7 @@ c91e4dc211305456c38e5823def91811ad851202 data/create/recipes/small_dripstone_bri 1e23c8df90aef6cd3561369f72c6c3106da883f5 data/create/recipes/small_dripstone_brick_stairs_from_stone_types_dripstone_stonecutting.json fda46cc15c21e7843537df5b5331874fd7511e19 data/create/recipes/small_dripstone_brick_wall.json 336e47b35437ffea4bb86d34f94e6361b2bbcfb0 data/create/recipes/small_dripstone_brick_wall_from_stone_types_dripstone_stonecutting.json -42c74dec6c64d3675e15b2b73cb32fc9d24839e9 data/create/recipes/small_granite_bricks_from_stone_types_granite_stonecutting.json +8840d538648516dd02628fbe3ea4f032ceda78bb data/create/recipes/small_dripstone_bricks_from_stone_types_dripstone_stonecutting.json d1bb4e91d80ca8eb9c2f935cbb66ef08b9ca7059 data/create/recipes/small_granite_brick_slab.json ddb2f4652607b56332a927af939212a5789a34db data/create/recipes/small_granite_brick_slab_from_stone_types_granite_stonecutting.json f1388636bcf98d7d9103c23528053b28c6305b4e data/create/recipes/small_granite_brick_slab_recycling.json @@ -4097,7 +4096,7 @@ f1388636bcf98d7d9103c23528053b28c6305b4e data/create/recipes/small_granite_brick ba935a3d64eedbd9b7017d0abfab351f57589593 data/create/recipes/small_granite_brick_stairs_from_stone_types_granite_stonecutting.json dac22c54e8034587a3fcf3aa0ce19bb4b7607cd7 data/create/recipes/small_granite_brick_wall.json 7a8d9e2291675de9e72363d93410de9039216f32 data/create/recipes/small_granite_brick_wall_from_stone_types_granite_stonecutting.json -714f6a84a5b3d5d57c07364925555e6f545b0b3d data/create/recipes/small_limestone_bricks_from_stone_types_limestone_stonecutting.json +42c74dec6c64d3675e15b2b73cb32fc9d24839e9 data/create/recipes/small_granite_bricks_from_stone_types_granite_stonecutting.json b844632a588cb96397750f4387c7e6517f85092c data/create/recipes/small_limestone_brick_slab.json a1c0bc263cd4659a89213f4fcdd87eba7ae04427 data/create/recipes/small_limestone_brick_slab_from_stone_types_limestone_stonecutting.json ec9154a3791113f57dc1c16dfef4c837533b6fc6 data/create/recipes/small_limestone_brick_slab_recycling.json @@ -4105,7 +4104,7 @@ ec9154a3791113f57dc1c16dfef4c837533b6fc6 data/create/recipes/small_limestone_bri 6943fdc8162e4d53c459f425b2ff5b34e9caa477 data/create/recipes/small_limestone_brick_stairs_from_stone_types_limestone_stonecutting.json 27ff69345efea14b9688fe9b182809995ea8ad4a data/create/recipes/small_limestone_brick_wall.json 98a83f757f0ac9cc2a876ae407bb5765071e700d data/create/recipes/small_limestone_brick_wall_from_stone_types_limestone_stonecutting.json -22c69e391110280e13d50693b9c81355da57a315 data/create/recipes/small_ochrum_bricks_from_stone_types_ochrum_stonecutting.json +714f6a84a5b3d5d57c07364925555e6f545b0b3d data/create/recipes/small_limestone_bricks_from_stone_types_limestone_stonecutting.json abdd280694cb30ce0d2703aadeeb378af9a7f8b2 data/create/recipes/small_ochrum_brick_slab.json e37612fa2523fa3711242cac4ec5e596b3e55698 data/create/recipes/small_ochrum_brick_slab_from_stone_types_ochrum_stonecutting.json 8f3f47cb3e759104cf86a422339345f8795143d3 data/create/recipes/small_ochrum_brick_slab_recycling.json @@ -4113,8 +4112,8 @@ de8d7f8e57645c0b5a6e98eb0cc4e573c5cf96ac data/create/recipes/small_ochrum_brick_ 04ebbdd14f81f4b4dc7986cb5241caa9f48f4ff1 data/create/recipes/small_ochrum_brick_stairs_from_stone_types_ochrum_stonecutting.json 07876725f97ff611f8d1710462224f07cab3ebbd data/create/recipes/small_ochrum_brick_wall.json 2331801569ec95562afc802f7e2ff191d329a5c6 data/create/recipes/small_ochrum_brick_wall_from_stone_types_ochrum_stonecutting.json +22c69e391110280e13d50693b9c81355da57a315 data/create/recipes/small_ochrum_bricks_from_stone_types_ochrum_stonecutting.json 68a9f80b97d9322ed33067d7717180494b904bed data/create/recipes/small_rose_quartz_tiles_from_polished_rose_quartz_stonecutting.json -bf27af2e54ed1b09611d67ee7afa6c7f56d00d09 data/create/recipes/small_scorchia_bricks_from_stone_types_scorchia_stonecutting.json 133057778480e1d2e13fe7b2766ba0891feea3a5 data/create/recipes/small_scorchia_brick_slab.json dad342d215c98f3214752e0ebfaf3015943c5ac7 data/create/recipes/small_scorchia_brick_slab_from_stone_types_scorchia_stonecutting.json 0a57ad5fce22d69cdc1dd880403612ffb47af4ba data/create/recipes/small_scorchia_brick_slab_recycling.json @@ -4122,7 +4121,7 @@ dad342d215c98f3214752e0ebfaf3015943c5ac7 data/create/recipes/small_scorchia_bric 7f89c9c6dcea06a3022c72029a5e547aa1721773 data/create/recipes/small_scorchia_brick_stairs_from_stone_types_scorchia_stonecutting.json 43310b3fa43bd791ef0e2e30971a24e788c20139 data/create/recipes/small_scorchia_brick_wall.json de8edc4fa5eec031ad0a63c7f59141985ae9af9e data/create/recipes/small_scorchia_brick_wall_from_stone_types_scorchia_stonecutting.json -b1a67d052e26c2129c34ee0732cfe533beb3e571 data/create/recipes/small_scoria_bricks_from_stone_types_scoria_stonecutting.json +bf27af2e54ed1b09611d67ee7afa6c7f56d00d09 data/create/recipes/small_scorchia_bricks_from_stone_types_scorchia_stonecutting.json d8a41adcc6ae9b0eb71a83b2dd89ff92a10e0057 data/create/recipes/small_scoria_brick_slab.json 34f4dd094f2949e3fd21f95ac890ae803b81fbea data/create/recipes/small_scoria_brick_slab_from_stone_types_scoria_stonecutting.json f15ad1cb05f5b02b630b982d23bd951178a3650c data/create/recipes/small_scoria_brick_slab_recycling.json @@ -4130,7 +4129,7 @@ df5a1437fb112519d904cc9f1cd28d5d891fb04d data/create/recipes/small_scoria_brick_ d36428daf8bf4e560f649e5eb40a8cd7a27e7a0e data/create/recipes/small_scoria_brick_stairs_from_stone_types_scoria_stonecutting.json cad432398d8886d60b94e96b2c2096ae27fffb50 data/create/recipes/small_scoria_brick_wall.json 9cff8370aaa81ece466fe15642c00a9992bd416c data/create/recipes/small_scoria_brick_wall_from_stone_types_scoria_stonecutting.json -e51ced16059f7c37fe3652a1cf4d938f91e956fc data/create/recipes/small_tuff_bricks_from_stone_types_tuff_stonecutting.json +b1a67d052e26c2129c34ee0732cfe533beb3e571 data/create/recipes/small_scoria_bricks_from_stone_types_scoria_stonecutting.json dd83af4a10a9b0ba6a4efb272d8b6b1611524a39 data/create/recipes/small_tuff_brick_slab.json e3a12b87830e47387e9ac118bb3d12b73558d757 data/create/recipes/small_tuff_brick_slab_from_stone_types_tuff_stonecutting.json 85dff00dc49eaf65f1f149a7f21a9f307b1b9710 data/create/recipes/small_tuff_brick_slab_recycling.json @@ -4138,7 +4137,7 @@ e03a8270b01b9a5cad238db4ce2b8f66ea78e8bf data/create/recipes/small_tuff_brick_st cd50bb5842c90038f6ac74e45971ab2e914d1463 data/create/recipes/small_tuff_brick_stairs_from_stone_types_tuff_stonecutting.json e795fbe5062ec47cc660ee26c8398477509c5f18 data/create/recipes/small_tuff_brick_wall.json 34471a7ebb431b6d1e3be5fa480b800b96556fee data/create/recipes/small_tuff_brick_wall_from_stone_types_tuff_stonecutting.json -82f17edc61a319c74dbdfa730584305899bd7572 data/create/recipes/small_veridium_bricks_from_stone_types_veridium_stonecutting.json +e51ced16059f7c37fe3652a1cf4d938f91e956fc data/create/recipes/small_tuff_bricks_from_stone_types_tuff_stonecutting.json f9a2f4ca078364e05b3446fe890ea207e5a56e87 data/create/recipes/small_veridium_brick_slab.json 234c3baee4c9428caab3e344f396ec87064103e3 data/create/recipes/small_veridium_brick_slab_from_stone_types_veridium_stonecutting.json b0db8335e3c7fd88f074c3895bea952efc0e8df8 data/create/recipes/small_veridium_brick_slab_recycling.json @@ -4146,6 +4145,7 @@ a1e214c230574526ca0a2fec059b4157ddec557d data/create/recipes/small_veridium_bric f63031587a64ed88ddba1df07767dd8d8caa1d2e data/create/recipes/small_veridium_brick_stairs_from_stone_types_veridium_stonecutting.json 9b003fbf2bcd975501ba307ea68c6c4bab397683 data/create/recipes/small_veridium_brick_wall.json 1ba48c5cae05b6f4b1ad223ce80925f1eaaf5dfd data/create/recipes/small_veridium_brick_wall_from_stone_types_veridium_stonecutting.json +82f17edc61a319c74dbdfa730584305899bd7572 data/create/recipes/small_veridium_bricks_from_stone_types_veridium_stonecutting.json 47973044b19b35ce169e7d46abc9d11a2f67a487 data/create/recipes/spruce_window.json 810544f79bf4b002981e614eaa8e49b48a7b5397 data/create/recipes/spruce_window_pane.json e343a80c92dab60f99c9b441d00189aceee477a0 data/create/recipes/tiled_glass_from_glass_colorless_stonecutting.json @@ -4303,8 +4303,8 @@ d794a156fdc9ec9e7c935b3b8962206b7b82eb79 data/minecraft/tags/blocks/mineable/pic 0c13aae0eeb99e89febe8dbe5e002af2ff843a9e data/minecraft/tags/blocks/needs_iron_tool.json 3cb2a92cbdf32ed5978f740dc378d363306c3e84 data/minecraft/tags/blocks/needs_stone_tool.json 5555e9722ecf1d4a3119d118e5aab8a17ef628cb data/minecraft/tags/blocks/rails.json -1ac7c46815461cbec0d4d97f25c085fdc8375dab data/minecraft/tags/blocks/slabs.json -dafa3bdb72fef5e6c0201c05846db3f2b214e587 data/minecraft/tags/blocks/stairs.json +594efc06bed9f38428b62ff3821c30edbc2f1678 data/minecraft/tags/blocks/slabs.json +cd2613a4722ce79366433181095c27463e7c61b8 data/minecraft/tags/blocks/stairs.json 11427a72e181857e22ec37a22462bc652e127cc5 data/minecraft/tags/blocks/trapdoors.json 2bcba05954ff7bc4cf9cc520478083da9973ec76 data/minecraft/tags/blocks/walls.json 71aef080a900d9e86818cf579438c3d826d6567e data/minecraft/tags/blocks/wooden_doors.json diff --git a/src/generated/resources/.cache/455c485c9c8ef171bbc1ce4d435b3110ba1557ba b/src/generated/resources/.cache/455c485c9c8ef171bbc1ce4d435b3110ba1557ba index b84cf1a66..1c010d34b 100644 --- a/src/generated/resources/.cache/455c485c9c8ef171bbc1ce4d435b3110ba1557ba +++ b/src/generated/resources/.cache/455c485c9c8ef171bbc1ce4d435b3110ba1557ba @@ -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 diff --git a/src/generated/resources/.cache/499d9d953ee69b539ff4dd4c95a6cbd849f63f67 b/src/generated/resources/.cache/499d9d953ee69b539ff4dd4c95a6cbd849f63f67 index 65fda67dd..96f56121b 100644 --- a/src/generated/resources/.cache/499d9d953ee69b539ff4dd4c95a6cbd849f63f67 +++ b/src/generated/resources/.cache/499d9d953ee69b539ff4dd4c95a6cbd849f63f67 @@ -1,4 +1,4 @@ -// 1.20.1 2024-09-02T22:36:27.2891201 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 diff --git a/src/generated/resources/.cache/6ec3b5a261c9ae3df674f7595dc66530ce54feb9 b/src/generated/resources/.cache/6ec3b5a261c9ae3df674f7595dc66530ce54feb9 index 3d1fc2731..0a84a5228 100644 --- a/src/generated/resources/.cache/6ec3b5a261c9ae3df674f7595dc66530ce54feb9 +++ b/src/generated/resources/.cache/6ec3b5a261c9ae3df674f7595dc66530ce54feb9 @@ -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 diff --git a/src/generated/resources/.cache/82992cbf8f2794d83ac94034835eac0acd7915b9 b/src/generated/resources/.cache/82992cbf8f2794d83ac94034835eac0acd7915b9 index 2380111ec..52e3dc4f3 100644 --- a/src/generated/resources/.cache/82992cbf8f2794d83ac94034835eac0acd7915b9 +++ b/src/generated/resources/.cache/82992cbf8f2794d83ac94034835eac0acd7915b9 @@ -1,4 +1,4 @@ -// 1.20.1 2024-09-02T22:36:27.358065 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 @@ -217,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 @@ -246,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 @@ -451,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 @@ -463,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 diff --git a/src/generated/resources/.cache/ad9bf59631726a3f24738ebf1a6cd44c7f88ba0f b/src/generated/resources/.cache/ad9bf59631726a3f24738ebf1a6cd44c7f88ba0f index 9fec6ab0a..65eee720e 100644 --- a/src/generated/resources/.cache/ad9bf59631726a3f24738ebf1a6cd44c7f88ba0f +++ b/src/generated/resources/.cache/ad9bf59631726a3f24738ebf1a6cd44c7f88ba0f @@ -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 diff --git a/src/generated/resources/.cache/b256105d8411632b0d585496ea8944a751a08034 b/src/generated/resources/.cache/b256105d8411632b0d585496ea8944a751a08034 index 1dbf300b1..2e647dc3e 100644 --- a/src/generated/resources/.cache/b256105d8411632b0d585496ea8944a751a08034 +++ b/src/generated/resources/.cache/b256105d8411632b0d585496ea8944a751a08034 @@ -842,22 +842,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 @@ -1083,7 +1083,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 diff --git a/src/generated/resources/.cache/c24b4d2b8d15abff51c78bd94f4403d9eae6c139 b/src/generated/resources/.cache/c24b4d2b8d15abff51c78bd94f4403d9eae6c139 index ac707e471..4184c4f4c 100644 --- a/src/generated/resources/.cache/c24b4d2b8d15abff51c78bd94f4403d9eae6c139 +++ b/src/generated/resources/.cache/c24b4d2b8d15abff51c78bd94f4403d9eae6c139 @@ -1,2 +1,2 @@ -// 1.20.1 2024-09-02T22:36:27.3041196 Create's Custom Sounds +// 1.20.1 2024-10-09T12:24:59.2018604 Create's Custom Sounds bcfd9320f8ed54f3282b1757a41da0d1753e1754 assets/create/sounds.json diff --git a/src/generated/resources/.cache/e0a39a97205b7149114f15de91b614248d05fd95 b/src/generated/resources/.cache/e0a39a97205b7149114f15de91b614248d05fd95 index aa52e1351..ba866d79a 100644 --- a/src/generated/resources/.cache/e0a39a97205b7149114f15de91b614248d05fd95 +++ b/src/generated/resources/.cache/e0a39a97205b7149114f15de91b614248d05fd95 @@ -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 diff --git a/src/generated/resources/.cache/eaed56ca9d9781c7626be345dd9f2c9a1fad638e b/src/generated/resources/.cache/eaed56ca9d9781c7626be345dd9f2c9a1fad638e index dedd3119f..5a2a21ad8 100644 --- a/src/generated/resources/.cache/eaed56ca9d9781c7626be345dd9f2c9a1fad638e +++ b/src/generated/resources/.cache/eaed56ca9d9781c7626be345dd9f2c9a1fad638e @@ -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 diff --git a/src/generated/resources/assets/create/lang/en_ud.json b/src/generated/resources/assets/create/lang/en_ud.json index ae7ae5801..3c1a15489 100644 --- a/src/generated/resources/assets/create/lang/en_ud.json +++ b/src/generated/resources/assets/create/lang/en_ud.json @@ -2479,6 +2479,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ɐןᗺ", @@ -2649,6 +2650,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 ɹǝɟǝɹԀ", diff --git a/src/generated/resources/assets/create/lang/en_us.json b/src/generated/resources/assets/create/lang/en_us.json index fa9056942..164323107 100644 --- a/src/generated/resources/assets/create/lang/en_us.json +++ b/src/generated/resources/assets/create/lang/en_us.json @@ -2479,6 +2479,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", @@ -2649,6 +2650,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", diff --git a/src/generated/resources/data/create/advancements/recipes/misc/blasting/ingot_aluminum_compat_ic2.json b/src/generated/resources/data/create/advancements/recipes/misc/blasting/ingot_aluminium_compat_ic2.json similarity index 83% rename from src/generated/resources/data/create/advancements/recipes/misc/blasting/ingot_aluminum_compat_ic2.json rename to src/generated/resources/data/create/advancements/recipes/misc/blasting/ingot_aluminium_compat_ic2.json index cc1c5b704..0baa9feeb 100644 --- a/src/generated/resources/data/create/advancements/recipes/misc/blasting/ingot_aluminum_compat_ic2.json +++ b/src/generated/resources/data/create/advancements/recipes/misc/blasting/ingot_aluminium_compat_ic2.json @@ -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 diff --git a/src/generated/resources/data/create/advancements/recipes/misc/smelting/ingot_aluminum_compat_ic2.json b/src/generated/resources/data/create/advancements/recipes/misc/smelting/ingot_aluminium_compat_ic2.json similarity index 83% rename from src/generated/resources/data/create/advancements/recipes/misc/smelting/ingot_aluminum_compat_ic2.json rename to src/generated/resources/data/create/advancements/recipes/misc/smelting/ingot_aluminium_compat_ic2.json index c7a9b5d7f..532ba3eea 100644 --- a/src/generated/resources/data/create/advancements/recipes/misc/smelting/ingot_aluminum_compat_ic2.json +++ b/src/generated/resources/data/create/advancements/recipes/misc/smelting/ingot_aluminium_compat_ic2.json @@ -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 diff --git a/src/generated/resources/data/create/recipes/blasting/ingot_aluminum_compat_ic2.json b/src/generated/resources/data/create/recipes/blasting/ingot_aluminium_compat_ic2.json similarity index 88% rename from src/generated/resources/data/create/recipes/blasting/ingot_aluminum_compat_ic2.json rename to src/generated/resources/data/create/recipes/blasting/ingot_aluminium_compat_ic2.json index a9a5abda3..8223f16e9 100644 --- a/src/generated/resources/data/create/recipes/blasting/ingot_aluminum_compat_ic2.json +++ b/src/generated/resources/data/create/recipes/blasting/ingot_aluminium_compat_ic2.json @@ -12,5 +12,5 @@ "ingredient": { "item": "create:crushed_raw_aluminum" }, - "result": "ic2:ingot_aluminum" + "result": "ic2:ingot_aluminium" } \ No newline at end of file diff --git a/src/generated/resources/data/create/recipes/crafting/tree_fertilizer.json b/src/generated/resources/data/create/recipes/crafting/tree_fertilizer.json index f705b2e53..56bfafb78 100644 --- a/src/generated/resources/data/create/recipes/crafting/tree_fertilizer.json +++ b/src/generated/resources/data/create/recipes/crafting/tree_fertilizer.json @@ -1,6 +1,12 @@ { "type": "minecraft:crafting_shapeless", "category": "misc", + "conditions": [ + { + "type": "forge:mod_loaded", + "modid": "upgrade_aquatic" + } + ], "ingredients": [ { "tag": "minecraft:small_flowers" diff --git a/src/generated/resources/data/create/recipes/milling/compat/botania/black_petal.json b/src/generated/resources/data/create/recipes/milling/compat/botania/black_petal.json index 66f3fe09d..9e20ea920 100644 --- a/src/generated/resources/data/create/recipes/milling/compat/botania/black_petal.json +++ b/src/generated/resources/data/create/recipes/milling/compat/botania/black_petal.json @@ -1,5 +1,11 @@ { "type": "create:milling", + "conditions": [ + { + "type": "forge:mod_loaded", + "modid": "botania" + } + ], "ingredients": [ { "tag": "botania:petals/black" diff --git a/src/generated/resources/data/create/recipes/milling/compat/botania/blue_petal.json b/src/generated/resources/data/create/recipes/milling/compat/botania/blue_petal.json index d47e82023..54aa19cb0 100644 --- a/src/generated/resources/data/create/recipes/milling/compat/botania/blue_petal.json +++ b/src/generated/resources/data/create/recipes/milling/compat/botania/blue_petal.json @@ -1,5 +1,11 @@ { "type": "create:milling", + "conditions": [ + { + "type": "forge:mod_loaded", + "modid": "botania" + } + ], "ingredients": [ { "tag": "botania:petals/blue" diff --git a/src/generated/resources/data/create/recipes/milling/compat/botania/brown_petal.json b/src/generated/resources/data/create/recipes/milling/compat/botania/brown_petal.json index d1f3eb495..6fa6c006d 100644 --- a/src/generated/resources/data/create/recipes/milling/compat/botania/brown_petal.json +++ b/src/generated/resources/data/create/recipes/milling/compat/botania/brown_petal.json @@ -1,5 +1,11 @@ { "type": "create:milling", + "conditions": [ + { + "type": "forge:mod_loaded", + "modid": "botania" + } + ], "ingredients": [ { "tag": "botania:petals/brown" diff --git a/src/generated/resources/data/create/recipes/milling/compat/botania/cyan_petal.json b/src/generated/resources/data/create/recipes/milling/compat/botania/cyan_petal.json index 05fe7d87b..8657058c8 100644 --- a/src/generated/resources/data/create/recipes/milling/compat/botania/cyan_petal.json +++ b/src/generated/resources/data/create/recipes/milling/compat/botania/cyan_petal.json @@ -1,5 +1,11 @@ { "type": "create:milling", + "conditions": [ + { + "type": "forge:mod_loaded", + "modid": "botania" + } + ], "ingredients": [ { "tag": "botania:petals/cyan" diff --git a/src/generated/resources/data/create/recipes/milling/compat/botania/gray_petal.json b/src/generated/resources/data/create/recipes/milling/compat/botania/gray_petal.json index 9bb0bcd24..33d6c6bd6 100644 --- a/src/generated/resources/data/create/recipes/milling/compat/botania/gray_petal.json +++ b/src/generated/resources/data/create/recipes/milling/compat/botania/gray_petal.json @@ -1,5 +1,11 @@ { "type": "create:milling", + "conditions": [ + { + "type": "forge:mod_loaded", + "modid": "botania" + } + ], "ingredients": [ { "tag": "botania:petals/gray" diff --git a/src/generated/resources/data/create/recipes/milling/compat/botania/green_petal.json b/src/generated/resources/data/create/recipes/milling/compat/botania/green_petal.json index ed4641482..11f11ac3c 100644 --- a/src/generated/resources/data/create/recipes/milling/compat/botania/green_petal.json +++ b/src/generated/resources/data/create/recipes/milling/compat/botania/green_petal.json @@ -1,5 +1,11 @@ { "type": "create:milling", + "conditions": [ + { + "type": "forge:mod_loaded", + "modid": "botania" + } + ], "ingredients": [ { "tag": "botania:petals/green" diff --git a/src/generated/resources/data/create/recipes/milling/compat/botania/light_blue_petal.json b/src/generated/resources/data/create/recipes/milling/compat/botania/light_blue_petal.json index 595e18953..4368eecaf 100644 --- a/src/generated/resources/data/create/recipes/milling/compat/botania/light_blue_petal.json +++ b/src/generated/resources/data/create/recipes/milling/compat/botania/light_blue_petal.json @@ -1,5 +1,11 @@ { "type": "create:milling", + "conditions": [ + { + "type": "forge:mod_loaded", + "modid": "botania" + } + ], "ingredients": [ { "tag": "botania:petals/light_blue" diff --git a/src/generated/resources/data/create/recipes/milling/compat/botania/light_gray_petal.json b/src/generated/resources/data/create/recipes/milling/compat/botania/light_gray_petal.json index 5b9a6bd52..0b6a6d876 100644 --- a/src/generated/resources/data/create/recipes/milling/compat/botania/light_gray_petal.json +++ b/src/generated/resources/data/create/recipes/milling/compat/botania/light_gray_petal.json @@ -1,5 +1,11 @@ { "type": "create:milling", + "conditions": [ + { + "type": "forge:mod_loaded", + "modid": "botania" + } + ], "ingredients": [ { "tag": "botania:petals/light_gray" diff --git a/src/generated/resources/data/create/recipes/milling/compat/botania/lime_petal.json b/src/generated/resources/data/create/recipes/milling/compat/botania/lime_petal.json index 51bac8733..1ae7e3b14 100644 --- a/src/generated/resources/data/create/recipes/milling/compat/botania/lime_petal.json +++ b/src/generated/resources/data/create/recipes/milling/compat/botania/lime_petal.json @@ -1,5 +1,11 @@ { "type": "create:milling", + "conditions": [ + { + "type": "forge:mod_loaded", + "modid": "botania" + } + ], "ingredients": [ { "tag": "botania:petals/lime" diff --git a/src/generated/resources/data/create/recipes/milling/compat/botania/magenta_petal.json b/src/generated/resources/data/create/recipes/milling/compat/botania/magenta_petal.json index 8001d8fd7..e85b7d3f6 100644 --- a/src/generated/resources/data/create/recipes/milling/compat/botania/magenta_petal.json +++ b/src/generated/resources/data/create/recipes/milling/compat/botania/magenta_petal.json @@ -1,5 +1,11 @@ { "type": "create:milling", + "conditions": [ + { + "type": "forge:mod_loaded", + "modid": "botania" + } + ], "ingredients": [ { "tag": "botania:petals/magenta" diff --git a/src/generated/resources/data/create/recipes/milling/compat/botania/orange_petal.json b/src/generated/resources/data/create/recipes/milling/compat/botania/orange_petal.json index b0d9957e1..dd5bd028d 100644 --- a/src/generated/resources/data/create/recipes/milling/compat/botania/orange_petal.json +++ b/src/generated/resources/data/create/recipes/milling/compat/botania/orange_petal.json @@ -1,5 +1,11 @@ { "type": "create:milling", + "conditions": [ + { + "type": "forge:mod_loaded", + "modid": "botania" + } + ], "ingredients": [ { "tag": "botania:petals/orange" diff --git a/src/generated/resources/data/create/recipes/milling/compat/botania/pink_petal.json b/src/generated/resources/data/create/recipes/milling/compat/botania/pink_petal.json index c875d311e..6dd6bae9f 100644 --- a/src/generated/resources/data/create/recipes/milling/compat/botania/pink_petal.json +++ b/src/generated/resources/data/create/recipes/milling/compat/botania/pink_petal.json @@ -1,5 +1,11 @@ { "type": "create:milling", + "conditions": [ + { + "type": "forge:mod_loaded", + "modid": "botania" + } + ], "ingredients": [ { "tag": "botania:petals/pink" diff --git a/src/generated/resources/data/create/recipes/milling/compat/botania/purple_petal.json b/src/generated/resources/data/create/recipes/milling/compat/botania/purple_petal.json index 13ad6984c..815ccae3a 100644 --- a/src/generated/resources/data/create/recipes/milling/compat/botania/purple_petal.json +++ b/src/generated/resources/data/create/recipes/milling/compat/botania/purple_petal.json @@ -1,5 +1,11 @@ { "type": "create:milling", + "conditions": [ + { + "type": "forge:mod_loaded", + "modid": "botania" + } + ], "ingredients": [ { "tag": "botania:petals/purple" diff --git a/src/generated/resources/data/create/recipes/milling/compat/botania/red_petal.json b/src/generated/resources/data/create/recipes/milling/compat/botania/red_petal.json index 0fee03469..fea0a0b68 100644 --- a/src/generated/resources/data/create/recipes/milling/compat/botania/red_petal.json +++ b/src/generated/resources/data/create/recipes/milling/compat/botania/red_petal.json @@ -1,5 +1,11 @@ { "type": "create:milling", + "conditions": [ + { + "type": "forge:mod_loaded", + "modid": "botania" + } + ], "ingredients": [ { "tag": "botania:petals/red" diff --git a/src/generated/resources/data/create/recipes/milling/compat/botania/white_petal.json b/src/generated/resources/data/create/recipes/milling/compat/botania/white_petal.json index 0b8c714a9..de40fc9dc 100644 --- a/src/generated/resources/data/create/recipes/milling/compat/botania/white_petal.json +++ b/src/generated/resources/data/create/recipes/milling/compat/botania/white_petal.json @@ -1,5 +1,11 @@ { "type": "create:milling", + "conditions": [ + { + "type": "forge:mod_loaded", + "modid": "botania" + } + ], "ingredients": [ { "tag": "botania:petals/white" diff --git a/src/generated/resources/data/create/recipes/milling/compat/botania/yellow_petal.json b/src/generated/resources/data/create/recipes/milling/compat/botania/yellow_petal.json index ea71b8e71..704b039ae 100644 --- a/src/generated/resources/data/create/recipes/milling/compat/botania/yellow_petal.json +++ b/src/generated/resources/data/create/recipes/milling/compat/botania/yellow_petal.json @@ -1,5 +1,11 @@ { "type": "create:milling", + "conditions": [ + { + "type": "forge:mod_loaded", + "modid": "botania" + } + ], "ingredients": [ { "tag": "botania:petals/yellow" diff --git a/src/generated/resources/data/create/recipes/smelting/ingot_aluminum_compat_ic2.json b/src/generated/resources/data/create/recipes/smelting/ingot_aluminium_compat_ic2.json similarity index 88% rename from src/generated/resources/data/create/recipes/smelting/ingot_aluminum_compat_ic2.json rename to src/generated/resources/data/create/recipes/smelting/ingot_aluminium_compat_ic2.json index 3a948a09b..2a2de6e48 100644 --- a/src/generated/resources/data/create/recipes/smelting/ingot_aluminum_compat_ic2.json +++ b/src/generated/resources/data/create/recipes/smelting/ingot_aluminium_compat_ic2.json @@ -12,5 +12,5 @@ "ingredient": { "item": "create:crushed_raw_aluminum" }, - "result": "ic2:ingot_aluminum" + "result": "ic2:ingot_aluminium" } \ No newline at end of file diff --git a/src/generated/resources/data/create/recipes/splashing/ic2/crushed_raw_aluminum.json b/src/generated/resources/data/create/recipes/splashing/ic2/crushed_raw_aluminum.json index 738e1d254..945276f36 100644 --- a/src/generated/resources/data/create/recipes/splashing/ic2/crushed_raw_aluminum.json +++ b/src/generated/resources/data/create/recipes/splashing/ic2/crushed_raw_aluminum.json @@ -14,7 +14,7 @@ "results": [ { "count": 9, - "item": "ic2:nugget_aluminum" + "item": "ic2:nugget_aluminium" } ] } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/blocks/slabs.json b/src/generated/resources/data/minecraft/tags/blocks/slabs.json index 84083a313..5832e980e 100644 --- a/src/generated/resources/data/minecraft/tags/blocks/slabs.json +++ b/src/generated/resources/data/minecraft/tags/blocks/slabs.json @@ -1,5 +1,21 @@ { "values": [ + "create:copper_shingle_slab", + "create:exposed_copper_shingle_slab", + "create:weathered_copper_shingle_slab", + "create:oxidized_copper_shingle_slab", + "create:waxed_copper_shingle_slab", + "create:waxed_exposed_copper_shingle_slab", + "create:waxed_weathered_copper_shingle_slab", + "create:waxed_oxidized_copper_shingle_slab", + "create:copper_tile_slab", + "create:exposed_copper_tile_slab", + "create:weathered_copper_tile_slab", + "create:oxidized_copper_tile_slab", + "create:waxed_copper_tile_slab", + "create:waxed_exposed_copper_tile_slab", + "create:waxed_weathered_copper_tile_slab", + "create:waxed_oxidized_copper_tile_slab", "create:cut_granite_slab", "create:polished_cut_granite_slab", "create:cut_granite_brick_slab", diff --git a/src/generated/resources/data/minecraft/tags/blocks/stairs.json b/src/generated/resources/data/minecraft/tags/blocks/stairs.json index f31f0c6ea..5e66f9449 100644 --- a/src/generated/resources/data/minecraft/tags/blocks/stairs.json +++ b/src/generated/resources/data/minecraft/tags/blocks/stairs.json @@ -1,5 +1,21 @@ { "values": [ + "create:copper_shingle_stairs", + "create:exposed_copper_shingle_stairs", + "create:weathered_copper_shingle_stairs", + "create:oxidized_copper_shingle_stairs", + "create:waxed_copper_shingle_stairs", + "create:waxed_exposed_copper_shingle_stairs", + "create:waxed_weathered_copper_shingle_stairs", + "create:waxed_oxidized_copper_shingle_stairs", + "create:copper_tile_stairs", + "create:exposed_copper_tile_stairs", + "create:weathered_copper_tile_stairs", + "create:oxidized_copper_tile_stairs", + "create:waxed_copper_tile_stairs", + "create:waxed_exposed_copper_tile_stairs", + "create:waxed_weathered_copper_tile_stairs", + "create:waxed_oxidized_copper_tile_stairs", "create:cut_granite_stairs", "create:polished_cut_granite_stairs", "create:cut_granite_brick_stairs", diff --git a/src/main/java/com/simibubi/create/AllBlockEntityTypes.java b/src/main/java/com/simibubi/create/AllBlockEntityTypes.java index d0cccbc36..74918805a 100644 --- a/src/main/java/com/simibubi/create/AllBlockEntityTypes.java +++ b/src/main/java/com/simibubi/create/AllBlockEntityTypes.java @@ -199,6 +199,7 @@ import com.simibubi.create.content.schematics.cannon.SchematicannonRenderer; import com.simibubi.create.content.schematics.cannon.SchematicannonVisual; import com.simibubi.create.content.schematics.table.SchematicTableBlockEntity; import com.simibubi.create.content.trains.bogey.BogeyBlockEntityRenderer; +import com.simibubi.create.content.trains.bogey.BogeyBlockEntityVisual; import com.simibubi.create.content.trains.bogey.StandardBogeyBlockEntity; import com.simibubi.create.content.trains.display.FlapDisplayBlockEntity; import com.simibubi.create.content.trains.display.FlapDisplayRenderer; @@ -844,6 +845,7 @@ public class AllBlockEntityTypes { public static final BlockEntityEntry BOGEY = REGISTRATE .blockEntity("bogey", StandardBogeyBlockEntity::new) + .visual(() -> BogeyBlockEntityVisual::new, false) .renderer(() -> BogeyBlockEntityRenderer::new) .validBlocks(AllBlocks.SMALL_BOGEY, AllBlocks.LARGE_BOGEY) .register(); diff --git a/src/main/java/com/simibubi/create/AllBogeyStyles.java b/src/main/java/com/simibubi/create/AllBogeyStyles.java index 96b5c1568..67506bb9d 100644 --- a/src/main/java/com/simibubi/create/AllBogeyStyles.java +++ b/src/main/java/com/simibubi/create/AllBogeyStyles.java @@ -1,132 +1,42 @@ package com.simibubi.create; +import java.util.Collections; import java.util.HashMap; import java.util.Map; -import java.util.Optional; -import java.util.function.Supplier; -import com.google.common.collect.ImmutableMap; -import com.simibubi.create.content.trains.bogey.AbstractBogeyBlock; -import com.simibubi.create.content.trains.bogey.BogeyRenderer; -import com.simibubi.create.content.trains.bogey.BogeyRenderer.CommonRenderer; +import org.jetbrains.annotations.ApiStatus; + import com.simibubi.create.content.trains.bogey.BogeySizes; import com.simibubi.create.content.trains.bogey.BogeyStyle; -import com.simibubi.create.content.trains.bogey.StandardBogeyRenderer.CommonStandardBogeyRenderer; -import com.simibubi.create.content.trains.bogey.StandardBogeyRenderer.LargeStandardBogeyRenderer; -import com.simibubi.create.content.trains.bogey.StandardBogeyRenderer.SmallStandardBogeyRenderer; +import com.simibubi.create.content.trains.bogey.BogeyStyle.SizeRenderer; +import com.simibubi.create.content.trains.bogey.StandardBogeyRenderer; +import com.simibubi.create.content.trains.bogey.StandardBogeyVisual; import com.simibubi.create.foundation.utility.Components; -import com.simibubi.create.foundation.utility.Lang; -import com.tterrag.registrate.util.entry.BlockEntry; -import net.minecraft.core.particles.ParticleOptions; -import net.minecraft.core.particles.ParticleTypes; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.DistExecutor; public class AllBogeyStyles { public static final Map BOGEY_STYLES = new HashMap<>(); public static final Map> CYCLE_GROUPS = new HashMap<>(); - private static final Map EMPTY_GROUP = ImmutableMap.of(); + private static final Map EMPTY_GROUP = Collections.emptyMap(); + + public static final ResourceLocation STANDARD_CYCLE_GROUP = Create.asResource("standard"); + + public static final BogeyStyle STANDARD = + builder("standard", STANDARD_CYCLE_GROUP).displayName(Components.translatable("create.bogey.style.standard")) + .size(BogeySizes.SMALL, AllBlocks.SMALL_BOGEY, () -> new SizeRenderer(new StandardBogeyRenderer.Small(), StandardBogeyVisual.Small::new)) + .size(BogeySizes.LARGE, AllBlocks.LARGE_BOGEY, () -> new SizeRenderer(new StandardBogeyRenderer.Large(), StandardBogeyVisual.Large::new)) + .build(); public static Map getCycleGroup(ResourceLocation cycleGroup) { return CYCLE_GROUPS.getOrDefault(cycleGroup, EMPTY_GROUP); } - public static final String STANDARD_CYCLE_GROUP = "standard"; - - public static final BogeyStyle STANDARD = - create("standard", STANDARD_CYCLE_GROUP).commonRenderer(() -> CommonStandardBogeyRenderer::new) - .displayName(Components.translatable("create.bogey.style.standard")) - .size(BogeySizes.SMALL, () -> SmallStandardBogeyRenderer::new, AllBlocks.SMALL_BOGEY) - .size(BogeySizes.LARGE, () -> LargeStandardBogeyRenderer::new, AllBlocks.LARGE_BOGEY) - .build(); - - private static BogeyStyleBuilder create(String name, String cycleGroup) { - return create(Create.asResource(name), Create.asResource(cycleGroup)); + private static BogeyStyle.Builder builder(String name, ResourceLocation cycleGroup) { + return new BogeyStyle.Builder(Create.asResource(name), cycleGroup); } - public static BogeyStyleBuilder create(ResourceLocation name, ResourceLocation cycleGroup) { - return new BogeyStyleBuilder(name, cycleGroup); - } - - public static void register() {} - - public static class BogeyStyleBuilder { - protected final Map> sizeRenderers = new HashMap<>(); - protected final Map sizes = new HashMap<>(); - protected final ResourceLocation name; - protected final ResourceLocation cycleGroup; - - protected Component displayName = Lang.translateDirect("bogey.style.invalid"); - protected ResourceLocation soundType = AllSoundEvents.TRAIN2.getId(); - protected CompoundTag defaultData = new CompoundTag(); - protected ParticleOptions contactParticle = ParticleTypes.CRIT; - protected ParticleOptions smokeParticle = ParticleTypes.POOF; - protected Optional> commonRenderer = Optional.empty(); - - public BogeyStyleBuilder(ResourceLocation name, ResourceLocation cycleGroup) { - this.name = name; - this.cycleGroup = cycleGroup; - } - - public BogeyStyleBuilder displayName(Component displayName) { - this.displayName = displayName; - return this; - } - - public BogeyStyleBuilder soundType(ResourceLocation soundType) { - this.soundType = soundType; - return this; - } - - public BogeyStyleBuilder defaultData(CompoundTag defaultData) { - this.defaultData = defaultData; - return this; - } - - public BogeyStyleBuilder size(BogeySizes.BogeySize size, Supplier> renderer, - BlockEntry> blockEntry) { - this.size(size, renderer, blockEntry.getId()); - return this; - } - - public BogeyStyleBuilder size(BogeySizes.BogeySize size, Supplier> renderer, - ResourceLocation location) { - this.sizes.put(size, location); - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> { - this.sizeRenderers.put(size, () -> new BogeyStyle.SizeRenderData(renderer.get(), renderer.get() - .get())); - }); - return this; - } - - public BogeyStyleBuilder contactParticle(ParticleOptions contactParticle) { - this.contactParticle = contactParticle; - return this; - } - - public BogeyStyleBuilder smokeParticle(ParticleOptions smokeParticle) { - this.smokeParticle = smokeParticle; - return this; - } - - public BogeyStyleBuilder commonRenderer(Supplier> commonRenderer) { - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> { - this.commonRenderer = Optional.of(commonRenderer.get()); - }); - return this; - } - - public BogeyStyle build() { - BogeyStyle entry = new BogeyStyle(name, cycleGroup, displayName, soundType, contactParticle, smokeParticle, - defaultData, sizes, sizeRenderers, commonRenderer); - BOGEY_STYLES.put(name, entry); - CYCLE_GROUPS.computeIfAbsent(cycleGroup, l -> new HashMap<>()) - .put(name, entry); - return entry; - } + @ApiStatus.Internal + public static void init() { } } diff --git a/src/main/java/com/simibubi/create/AllPackets.java b/src/main/java/com/simibubi/create/AllPackets.java index 3c68ae47e..412375280 100644 --- a/src/main/java/com/simibubi/create/AllPackets.java +++ b/src/main/java/com/simibubi/create/AllPackets.java @@ -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; @@ -164,6 +166,7 @@ public enum AllPackets { CLIPBOARD_EDIT(ClipboardEditPacket.class, ClipboardEditPacket::new, PLAY_TO_SERVER), CONTRAPTION_COLLIDER_LOCK_REQUEST(ContraptionColliderLockPacketRequest.class, ContraptionColliderLockPacketRequest::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), @@ -208,7 +211,8 @@ public enum AllPackets { CONTRAPTION_ACTOR_TOGGLE(ContraptionDisableActorPacket.class, ContraptionDisableActorPacket::new, PLAY_TO_CLIENT), CONTRAPTION_COLLIDER_LOCK(ContraptionColliderLockPacket.class, ContraptionColliderLockPacket::new, PLAY_TO_CLIENT), ATTACHED_COMPUTER(AttachedComputerPacket.class, AttachedComputerPacket::new, PLAY_TO_CLIENT), - SERVER_DEBUG_INFO(ServerDebugInfoPacket.class, ServerDebugInfoPacket::new, PLAY_TO_CLIENT) + SERVER_DEBUG_INFO(ServerDebugInfoPacket.class, ServerDebugInfoPacket::new, PLAY_TO_CLIENT), + TRAIN_MAP_SYNC(TrainMapSyncPacket.class, TrainMapSyncPacket::new, PLAY_TO_CLIENT) ; public static final ResourceLocation CHANNEL_NAME = Create.asResource("main"); diff --git a/src/main/java/com/simibubi/create/Create.java b/src/main/java/com/simibubi/create/Create.java index b98042c45..2ef1094a8 100644 --- a/src/main/java/com/simibubi/create/Create.java +++ b/src/main/java/com/simibubi/create/Create.java @@ -136,7 +136,7 @@ public class Create { AllFanProcessingTypes.register(); BlockSpoutingBehaviour.registerDefaults(); BogeySizes.init(); - AllBogeyStyles.register(); + AllBogeyStyles.init(); // ---- ComputerCraftProxy.register(); diff --git a/src/main/java/com/simibubi/create/compat/Mods.java b/src/main/java/com/simibubi/create/compat/Mods.java index a89dce5ff..df64a92df 100644 --- a/src/main/java/com/simibubi/create/compat/Mods.java +++ b/src/main/java/com/simibubi/create/compat/Mods.java @@ -31,7 +31,10 @@ public enum Mods { TCONSTRUCT, FRAMEDBLOCKS, XLPACKETS, - MODERNUI; + MODERNUI, + FTBCHUNKS, + JOURNEYMAP, + BETTEREND; private final String id; @@ -53,11 +56,11 @@ public enum Mods { public Block getBlock(String id) { return ForgeRegistries.BLOCKS.getValue(rl(id)); } - + public Item getItem(String id) { return ForgeRegistries.ITEMS.getValue(rl(id)); } - + public boolean contains(ItemLike entry) { if (!isLoaded()) return false; diff --git a/src/main/java/com/simibubi/create/compat/betterend/BetterEndPortalCompat.java b/src/main/java/com/simibubi/create/compat/betterend/BetterEndPortalCompat.java new file mode 100644 index 000000000..3387d2e12 --- /dev/null +++ b/src/main/java/com/simibubi/create/compat/betterend/BetterEndPortalCompat.java @@ -0,0 +1,66 @@ +package com.simibubi.create.compat.betterend; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.invoke.VarHandle; + +import com.simibubi.create.Create; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.portal.PortalInfo; + +public class BetterEndPortalCompat { + private static final MethodHandles.Lookup lookup = MethodHandles.lookup(); + + private static MethodHandle constructorHandle; + private static VarHandle portalEntrancePosHandle; + private static MethodHandle findDimensionEntryPointHandle; + + private static boolean hasErrored = false; + + static { + try { + Class travelerStateClass = Class.forName("org.betterx.betterend.portal.TravelerState"); + MethodHandles.Lookup privateLookup = MethodHandles.privateLookupIn(travelerStateClass, lookup); + + MethodType travelerStateConstructorTypes = MethodType.methodType(void.class, Entity.class); + constructorHandle = lookup.findConstructor(travelerStateClass, travelerStateConstructorTypes); + + portalEntrancePosHandle = privateLookup.findVarHandle(travelerStateClass, "portalEntrancePos", BlockPos.class); + + MethodType findDimensionEntryPointTypes = MethodType.methodType(PortalInfo.class, ServerLevel.class); + findDimensionEntryPointHandle = privateLookup.findVirtual(travelerStateClass, "findDimensionEntryPoint", findDimensionEntryPointTypes); + } catch (Exception e) { + Create.LOGGER.error("Create's Better End Portal compat failed to initialize: ", e); + hasErrored = true; + } + } + + /** + * Retrieves the adjusted {@link PortalInfo} for the Better End portal using reflection. + * + * @param targetLevel The target {@link ServerLevel} (dimension). + * @param entity The probe {@link Entity} used for portal traversal calculations. + * @return The adjusted {@link PortalInfo} for the target dimension, or {@code null} if an error occurs. + */ + public static PortalInfo getBetterEndPortalInfo(ServerLevel targetLevel, Entity entity) { + if (!hasErrored) { + try { + Object travelerState = constructorHandle.invoke(entity); + + // Set the private portalEntrancePos field to the entity's block position + // as assumed in TravelerState#findDimensionEntryPoint + portalEntrancePosHandle.set(travelerState, entity.blockPosition().immutable()); + + return (PortalInfo) findDimensionEntryPointHandle.invoke(travelerState, targetLevel); + } catch (Throwable e) { + Create.LOGGER.error("Create's Better End Portal compat failed to initialize: ", e); + } + } + + return null; + } +} diff --git a/src/main/java/com/simibubi/create/compat/computercraft/implementation/peripherals/StationPeripheral.java b/src/main/java/com/simibubi/create/compat/computercraft/implementation/peripherals/StationPeripheral.java index c50891fe3..146742b3b 100644 --- a/src/main/java/com/simibubi/create/compat/computercraft/implementation/peripherals/StationPeripheral.java +++ b/src/main/java/com/simibubi/create/compat/computercraft/implementation/peripherals/StationPeripheral.java @@ -129,7 +129,7 @@ public class StationPeripheral extends SyncedPeripheral { 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 diff --git a/src/main/java/com/simibubi/create/compat/jei/category/ItemDrainCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/ItemDrainCategory.java index 15bb777f6..a1e398c78 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/ItemDrainCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/ItemDrainCategory.java @@ -10,8 +10,10 @@ import com.simibubi.create.content.fluids.potion.PotionFluidHandler; import com.simibubi.create.content.fluids.transfer.EmptyingRecipe; import com.simibubi.create.content.processing.recipe.ProcessingRecipeBuilder; import com.simibubi.create.foundation.gui.AllGuiTextures; +import com.simibubi.create.foundation.item.ItemHelper; import com.simibubi.create.foundation.utility.RegisteredObjects; +import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet; import mezz.jei.api.constants.VanillaTypes; import mezz.jei.api.forge.ForgeTypes; import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; @@ -22,6 +24,7 @@ import mezz.jei.api.runtime.IIngredientManager; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.ItemStackLinkedSet; import net.minecraft.world.item.Items; import net.minecraft.world.item.PotionItem; import net.minecraft.world.item.crafting.Ingredient; @@ -41,6 +44,7 @@ public class ItemDrainCategory extends CreateRecipeCategory { } public static void consumeRecipes(Consumer consumer, IIngredientManager ingredientManager) { + ObjectOpenCustomHashSet emptiedItems = new ObjectOpenCustomHashSet<>(ItemStackLinkedSet.TYPE_AND_TAG); for (ItemStack stack : ingredientManager.getAllIngredients(VanillaTypes.ITEM_STACK)) { if (PotionFluidHandler.isPotionItem(stack)) { FluidStack fluidFromPotionItem = PotionFluidHandler.getFluidFromPotionItem(stack); @@ -68,6 +72,11 @@ public class ItemDrainCategory extends CreateRecipeCategory { if (result.isEmpty()) continue; + // There can be a lot of duplicate empty tanks (e.g. from emptying tanks with different fluids). Merge + // them to reduce memory usage. If the item is exactly the same as the input, just use the input stack + // instead of the copy. + result = ItemHelper.sameItem(stack, result) ? stack : emptiedItems.addOrGet(result); + Ingredient ingredient = Ingredient.of(stack); ResourceLocation itemName = RegisteredObjects.getKeyOrThrow(stack.getItem()); ResourceLocation fluidName = RegisteredObjects.getKeyOrThrow(extracted.getFluid()); diff --git a/src/main/java/com/simibubi/create/compat/jei/category/SpoutCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/SpoutCategory.java index 3fa7d3160..cd810c034 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/SpoutCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/SpoutCategory.java @@ -63,7 +63,16 @@ public class SpoutCategory extends CreateRecipeCategory { if (!capability.isPresent()) continue; + var existingFluidHandler = capability.orElse(null); + int numTanks = existingFluidHandler.getTanks(); + FluidStack existingFluid = numTanks == 1 ? existingFluidHandler.getFluidInTank(0) : FluidStack.EMPTY; + for (FluidStack fluidStack : fluidStacks) { + // Hoist the fluid equality check to avoid the work of copying the stack + populating capabilities + // when most fluids will not match + if (numTanks == 1 && (!existingFluid.isEmpty() && !existingFluid.isFluidEqual(fluidStack))) { + continue; + } ItemStack copy = stack.copy(); copy.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM) .ifPresent(fhi -> { diff --git a/src/main/java/com/simibubi/create/compat/trainmap/FTBChunksTrainMap.java b/src/main/java/com/simibubi/create/compat/trainmap/FTBChunksTrainMap.java new file mode 100644 index 000000000..f60921ae4 --- /dev/null +++ b/src/main/java/com/simibubi/create/compat/trainmap/FTBChunksTrainMap.java @@ -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.Lang; +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 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(Lang.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; + } + +} diff --git a/src/main/java/com/simibubi/create/compat/trainmap/JourneyTrainMap.java b/src/main/java/com/simibubi/create/compat/trainmap/JourneyTrainMap.java new file mode 100644 index 000000000..74beed9a5 --- /dev/null +++ b/src/main/java/com/simibubi/create/compat/trainmap/JourneyTrainMap.java @@ -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.Lang; +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 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(Lang.translate("train_map.toggle") + .component()), mouseX, mouseY + 20, screen.width, screen.height, 256, Minecraft.getInstance().font); + return true; + } + +} diff --git a/src/main/java/com/simibubi/create/compat/trainmap/TrainMapEvents.java b/src/main/java/com/simibubi/create/compat/trainmap/TrainMapEvents.java new file mode 100644 index 000000000..54f2adb19 --- /dev/null +++ b/src/main/java/com/simibubi/create/compat/trainmap/TrainMapEvents.java @@ -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); + } + +} diff --git a/src/main/java/com/simibubi/create/compat/trainmap/TrainMapManager.java b/src/main/java/com/simibubi/create/compat/trainmap/TrainMapManager.java new file mode 100644 index 000000000..f9afac323 --- /dev/null +++ b/src/main/java/com/simibubi/create/compat/trainmap/TrainMapManager.java @@ -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.AnimationTickHolder; +import com.simibubi.create.foundation.utility.Components; +import com.simibubi.create.foundation.utility.Couple; +import com.simibubi.create.foundation.utility.Iterate; +import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.foundation.utility.Pair; +import com.simibubi.create.infrastructure.config.AllConfigs; +import com.simibubi.create.infrastructure.config.CClient; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +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 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.width) + return false; + if (mouseY < y || mouseY >= y + AllGuiTextures.TRAINMAP_TOGGLE_PANEL.height) + return false; + return true; + } + + private static List listTrainDetails(Train train) { + List 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; + + Lang.text(train.name.getString()) + .color(bright) + .addTo(output); + + if (!trainEntry.ownerName.isBlank()) + Lang.translate("train_map.train_owned_by", trainEntry.ownerName) + .color(blue) + .addTo(output); + + switch (state) { + + case CONDUCTOR_MISSING: + Lang.translate("train_map.conductor_missing") + .color(orange) + .addTo(output); + return output; + case DERAILED: + Lang.translate("train_map.derailed") + .color(orange) + .addTo(output); + return output; + case NAVIGATION_FAILED: + Lang.translate("train_map.navigation_failed") + .color(orange) + .addTo(output); + return output; + case SCHEDULE_INTERRUPTED: + Lang.translate("train_map.schedule_interrupted") + .color(orange) + .addTo(output); + return output; + case RUNNING_MANUALLY: + Lang.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) + Lang.translate("train_map.train_at_station", currentStation) + .color(darkBlue) + .addTo(output); + else + Lang.translate("train_map.train_moving_to_station", currentStation, targetStationDistance) + .color(darkBlue) + .addTo(output); + } + + if (signalState != SignalState.NOT_WAITING) { + boolean chainSignal = signalState == SignalState.CHAIN_SIGNAL; + Lang.translate("train_map.waiting_at_signal") + .color(orange) + .addTo(output); + + if (signalState == SignalState.WAITING_FOR_REDSTONE) + Lang.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) { + Lang.translate("train_map.for_other_train", trainWaitingFor.name.getString()) + .color(blue) + .addTo(output); + trainFound = true; + } + } + + if (!trainFound) { + if (chainSignal) + Lang.translate("train_map.cannot_traverse_section") + .color(blue) + .addTo(output); + else + Lang.translate("train_map.section_reserved") + .color(blue) + .addTo(output); + } + } + } + + if (trainEntry.fueled) + Lang.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 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.width / 2.0, sprite.height / 2.0, 0); + pose.mulPose(Axis.ZP.rotationDegrees(90 * (rotation / 2))); + pose.translate(-sprite.width / 2.0, -sprite.height / 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 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 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.width, + sprite.height); + } + + 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> 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> 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 connectionsFrom = graph.getConnectionsFrom(node); + + int hashCode = node.hashCode(); + for (Entry 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, Double> rasterise = turn.rasterise(); + + for (boolean antialias : Iterate.falseAndTrue) { + for (Entry, Double> offset : rasterise.entrySet()) { + Pair 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> collisions, int mainColor, + int darkerColor, int mainColorShadow, int darkerColorShadow) { + for (Couple 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); + } + +} diff --git a/src/main/java/com/simibubi/create/compat/trainmap/TrainMapRenderer.java b/src/main/java/com/simibubi/create/compat/trainmap/TrainMapRenderer.java new file mode 100644 index 000000000..e5335bb4d --- /dev/null +++ b/src/main/java/com/simibubi/create/compat/trainmap/TrainMapRenderer.java @@ -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.foundation.utility.Couple; +import com.simibubi.create.infrastructure.config.CClient; + +import it.unimi.dsi.fastutil.objects.Object2ObjectMap; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +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, TrainMapInstance> maps = new Object2ObjectOpenHashMap<>(); + + public int trackingVersion; + public ResourceKey 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, 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 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> 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 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 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 sectionKey; + + public ResourceLocation location; + + public TrainMapInstance(Couple 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(); + } + + } +} diff --git a/src/main/java/com/simibubi/create/compat/trainmap/TrainMapSync.java b/src/main/java/com/simibubi/create/compat/trainmap/TrainMapSync.java new file mode 100644 index 000000000..0de7783db --- /dev/null +++ b/src/main/java/com/simibubi/create/compat/trainmap/TrainMapSync.java @@ -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 com.simibubi.create.foundation.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> prevDims; + + // Updated every 5 ticks + public float[] positions; + public List> 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 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 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> 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 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 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, 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 leadingDim = + (leading.node1 == null || leading.edge == null || leading.edge.isInterDimensional()) ? null + : leading.node1.getLocation() + .getDimension(); + + ResourceKey trailingDim = + (trailing.node1 == null || trailing.edge == null || trailing.edge.isInterDimensional()) ? null + : trailing.node1.getLocation() + .getDimension(); + + ResourceKey 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; + } + +} diff --git a/src/main/java/com/simibubi/create/compat/trainmap/TrainMapSyncClient.java b/src/main/java/com/simibubi/create/compat/trainmap/TrainMapSyncClient.java new file mode 100644 index 000000000..321b40fc4 --- /dev/null +++ b/src/main/java/com/simibubi/create/compat/trainmap/TrainMapSyncClient.java @@ -0,0 +1,56 @@ +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 com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.utility.Pair; + +public class TrainMapSyncClient { + + public static Map 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 staleEntries = new HashSet<>(); + staleEntries.addAll(currentData.keySet()); + + for (Pair 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); + } + +} diff --git a/src/main/java/com/simibubi/create/compat/trainmap/TrainMapSyncPacket.java b/src/main/java/com/simibubi/create/compat/trainmap/TrainMapSyncPacket.java new file mode 100644 index 000000000..0c3703759 --- /dev/null +++ b/src/main/java/com/simibubi/create/compat/trainmap/TrainMapSyncPacket.java @@ -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 com.simibubi.create.foundation.utility.Pair; + +import net.minecraft.network.FriendlyByteBuf; +import net.minecraftforge.network.NetworkEvent.Context; + +public class TrainMapSyncPacket extends SimplePacketBase { + + public List> 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 pair : entries) + pair.getSecond() + .gatherDimensions(dimensionPalette); + + dimensionPalette.send(buffer); + buffer.writeBoolean(light); + + buffer.writeVarInt(entries.size()); + for (Pair 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; + } + +} diff --git a/src/main/java/com/simibubi/create/compat/trainmap/TrainMapSyncRequestPacket.java b/src/main/java/com/simibubi/create/compat/trainmap/TrainMapSyncRequestPacket.java new file mode 100644 index 000000000..c6138a56d --- /dev/null +++ b/src/main/java/com/simibubi/create/compat/trainmap/TrainMapSyncRequestPacket.java @@ -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; + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/AbstractContraptionEntity.java b/src/main/java/com/simibubi/create/content/contraptions/AbstractContraptionEntity.java index f8e3caf9f..3e254604d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/AbstractContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/AbstractContraptionEntity.java @@ -545,9 +545,12 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit relativeMotion = reverseRotation(relativeMotion, 1); context.relativeMotion = relativeMotion; - return !BlockPos.containing(previousPosition).equals(gridPosition) - || (context.relativeMotion.length() > 0 || context.contraption instanceof CarriageContraption) - && context.firstMovement; + boolean ignoreMotionForFirstMovement = + context.contraption instanceof CarriageContraption || actor instanceof PortableStorageInterfaceMovement; + + return !BlockPos.containing(previousPosition) + .equals(gridPosition) + || (context.relativeMotion.length() > 0 || ignoreMotionForFirstMovement) && context.firstMovement; } public void move(double x, double y, double z) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/Contraption.java index 01545f4bd..8d9b8c334 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/Contraption.java @@ -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 entry : blocks.entrySet()) { @@ -1400,7 +1407,6 @@ public abstract class Contraption { }) .thenAccept(r -> { simplifiedEntityColliders = Optional.of(r); - simplifiedEntityColliderProvider = null; }); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/ContraptionCollider.java b/src/main/java/com/simibubi/create/content/contraptions/ContraptionCollider.java index 5be8ff108..3c542c490 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/ContraptionCollider.java +++ b/src/main/java/com/simibubi/create/content/contraptions/ContraptionCollider.java @@ -14,7 +14,6 @@ import org.apache.commons.lang3.mutable.MutableFloat; import org.apache.commons.lang3.mutable.MutableObject; import org.apache.commons.lang3.tuple.MutablePair; -import com.google.common.base.Predicates; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllMovementBehaviours; import com.simibubi.create.AllPackets; @@ -161,8 +160,7 @@ public class ContraptionCollider { List bbs = new ArrayList<>(); List potentialHits = getPotentiallyCollidedShapes(world, contraption, localBB.expandTowards(motionCopy)); - potentialHits.forEach(shape -> shape.toAabbs() - .forEach(bbs::add)); + potentialHits.forEach(shape -> bbs.addAll(shape.toAabbs())); return bbs; }); @@ -669,19 +667,23 @@ public class ContraptionCollider { BlockPos min = BlockPos.containing(blockScanBB.minX, blockScanBB.minY, blockScanBB.minZ); BlockPos max = BlockPos.containing(blockScanBB.maxX, blockScanBB.maxY, blockScanBB.maxZ); - List potentialHits = BlockPos.betweenClosedStream(min, max) - .filter(contraption.getBlocks()::containsKey) - .filter(Predicates.not(contraption::isHiddenInPortal)) - .map(p -> { - BlockState blockState = contraption.getBlocks() - .get(p).state(); - BlockPos pos = contraption.getBlocks() - .get(p).pos(); - VoxelShape collisionShape = blockState.getCollisionShape(world, p); - return collisionShape.move(pos.getX(), pos.getY(), pos.getZ()); - }) - .filter(Predicates.not(VoxelShape::isEmpty)) - .toList(); + List potentialHits = new ArrayList<>(); + + for (BlockPos p : BlockPos.betweenClosed(min, max)) { + if (contraption.blocks.containsKey(p) && !contraption.isHiddenInPortal(p)) { + StructureBlockInfo info = contraption.getBlocks().get(p); + + BlockState blockState = info.state(); + BlockPos pos = info.pos(); + + VoxelShape collisionShape = blockState.getCollisionShape(world, p) + .move(pos.getX(), pos.getY(), pos.getZ()); + + if (!collisionShape.isEmpty()) { + potentialHits.add(collisionShape); + } + } + } return potentialHits; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/MountedStorage.java b/src/main/java/com/simibubi/create/content/contraptions/MountedStorage.java index 375a2cfad..09fd87072 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/MountedStorage.java +++ b/src/main/java/com/simibubi/create/content/contraptions/MountedStorage.java @@ -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; @@ -177,6 +178,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; @@ -191,6 +194,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"); diff --git a/src/main/java/com/simibubi/create/content/contraptions/actors/contraptionControls/ContraptionControlsBlockEntity.java b/src/main/java/com/simibubi/create/content/contraptions/actors/contraptionControls/ContraptionControlsBlockEntity.java index 6b9c2d0c9..3aa4dfa3c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/actors/contraptionControls/ContraptionControlsBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/actors/contraptionControls/ContraptionControlsBlockEntity.java @@ -107,7 +107,7 @@ public class ContraptionControlsBlockEntity extends SmartBlockEntity { public static void sendStatus(Player player, ItemStack filter, boolean enabled) { MutableComponent state = Lang.translate("contraption.controls.actor_toggle." + (enabled ? "on" : "off")) - .color(DyeHelper.DYE_TABLE.get(enabled ? DyeColor.LIME : DyeColor.ORANGE) + .color(DyeHelper.getDyeColors(enabled ? DyeColor.LIME : DyeColor.ORANGE) .getFirst()) .component(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/actors/contraptionControls/ContraptionControlsRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/actors/contraptionControls/ContraptionControlsRenderer.java index f281b623a..5dfb49ffa 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/actors/contraptionControls/ContraptionControlsRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/actors/contraptionControls/ContraptionControlsRenderer.java @@ -83,7 +83,7 @@ public class ContraptionControlsRenderer extends SmartBlockEntityRenderer couple = DyeHelper.DYE_TABLE.get(efs.targetYEqualsSelection ? DyeColor.WHITE : DyeColor.ORANGE); + Couple couple = DyeHelper.getDyeColors(efs.targetYEqualsSelection ? DyeColor.WHITE : DyeColor.ORANGE); int brightColor = couple.getFirst(); int darkColor = couple.getSecond(); int flickeringBrightColor = Color.mixColors(brightColor, darkColor, flicker / 4); diff --git a/src/main/java/com/simibubi/create/content/contraptions/bearing/BearingVisual.java b/src/main/java/com/simibubi/create/content/contraptions/bearing/BearingVisual.java index 67edcfe3d..e244c49cf 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/bearing/BearingVisual.java +++ b/src/main/java/com/simibubi/create/content/contraptions/bearing/BearingVisual.java @@ -38,7 +38,7 @@ public class BearingVisual e PartialModel top = blockEntity.isWoodenTop() ? AllPartialModels.BEARING_TOP_WOODEN : AllPartialModels.BEARING_TOP; - topInstance = instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(top)) + topInstance = instancerProvider().instancer(InstanceTypes.ORIENTED, Models.partial(top)) .createInstance(); topInstance.position(getVisualPosition()) diff --git a/src/main/java/com/simibubi/create/content/contraptions/chassis/StickerVisual.java b/src/main/java/com/simibubi/create/content/contraptions/chassis/StickerVisual.java index d44a3e95d..e9c84956c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/chassis/StickerVisual.java +++ b/src/main/java/com/simibubi/create/content/contraptions/chassis/StickerVisual.java @@ -29,7 +29,7 @@ public class StickerVisual extends AbstractBlockEntityVisual public StickerVisual(VisualizationContext context, StickerBlockEntity blockEntity, float partialTick) { super(context, blockEntity, partialTick); - head = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.STICKER_HEAD)).createInstance(); + head = instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.STICKER_HEAD)).createInstance(); fakeWorld = blockEntity.getLevel() != Minecraft.getInstance().level; facing = blockState.getValue(StickerBlock.FACING); diff --git a/src/main/java/com/simibubi/create/content/contraptions/gantry/GantryCarriageVisual.java b/src/main/java/com/simibubi/create/content/contraptions/gantry/GantryCarriageVisual.java index 4f1821990..7174a79a4 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/gantry/GantryCarriageVisual.java +++ b/src/main/java/com/simibubi/create/content/contraptions/gantry/GantryCarriageVisual.java @@ -34,7 +34,7 @@ public class GantryCarriageVisual extends ShaftVisual public GantryCarriageVisual(VisualizationContext context, GantryCarriageBlockEntity blockEntity, float partialTick) { super(context, blockEntity, partialTick); - gantryCogs = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.GANTRY_COGS)) + gantryCogs = instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.GANTRY_COGS)) .createInstance(); facing = blockState.getValue(GantryCarriageBlock.FACING); diff --git a/src/main/java/com/simibubi/create/content/contraptions/pulley/AbstractPulleyVisual.java b/src/main/java/com/simibubi/create/content/contraptions/pulley/AbstractPulleyVisual.java index d5dd84a90..df9a1a158 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/pulley/AbstractPulleyVisual.java +++ b/src/main/java/com/simibubi/create/content/contraptions/pulley/AbstractPulleyVisual.java @@ -5,17 +5,16 @@ import java.util.function.Consumer; import com.mojang.math.Axis; import com.simibubi.create.content.kinetics.base.KineticBlockEntity; import com.simibubi.create.content.kinetics.base.ShaftVisual; -import com.simibubi.create.foundation.render.ConditionalInstance; -import com.simibubi.create.foundation.render.GroupInstance; -import com.simibubi.create.foundation.render.SelectInstance; import dev.engine_room.flywheel.api.instance.Instance; import dev.engine_room.flywheel.api.instance.Instancer; import dev.engine_room.flywheel.api.visual.DynamicVisual; import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.lib.instance.OrientedInstance; +import dev.engine_room.flywheel.lib.instance.TransformedInstance; import dev.engine_room.flywheel.lib.math.MoreMath; import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; +import dev.engine_room.flywheel.lib.visual.util.SmartRecycler; import it.unimi.dsi.fastutil.bytes.ByteArrayList; import it.unimi.dsi.fastutil.bytes.ByteList; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; @@ -29,9 +28,8 @@ import net.minecraft.world.level.LightLayer; public abstract class AbstractPulleyVisual extends ShaftVisual implements SimpleDynamicVisual { private final OrientedInstance coil; - private final SelectInstance magnet; - private final GroupInstance rope; - private final ConditionalInstance halfRope; + private final TransformedInstance magnet; + private final SmartRecycler rope; protected final Direction rotatingAbout; protected final Axis rotationAxis; @@ -50,14 +48,12 @@ public abstract class AbstractPulleyVisual extends .position(getVisualPosition()); coil.setChanged(); - magnet = new SelectInstance<>(this::getMagnetModelIndex); - magnet.addModel(getMagnetModel()) - .addModel(getHalfMagnetModel()); + magnet = magnetInstancer().createInstance(); - rope = new GroupInstance<>(getRopeModel()); - halfRope = new ConditionalInstance<>(getHalfRopeModel()).withCondition(this::shouldRenderHalfRope); + rope = new SmartRecycler<>(b -> b ? getHalfRopeModel().createInstance() : getRopeModel().createInstance()); updateOffset(partialTick); + updateLight(partialTick); } @Override @@ -66,67 +62,68 @@ public abstract class AbstractPulleyVisual extends lightCache.updateSections(); } - protected abstract Instancer getRopeModel(); + protected abstract Instancer getRopeModel(); - protected abstract Instancer getMagnetModel(); + protected abstract Instancer getMagnetModel(); - protected abstract Instancer getHalfMagnetModel(); + protected abstract Instancer getHalfMagnetModel(); protected abstract Instancer getCoilModel(); - protected abstract Instancer getHalfRopeModel(); + protected abstract Instancer getHalfRopeModel(); protected abstract float getOffset(float pt); protected abstract boolean isRunning(); + private Instancer magnetInstancer() { + return offset > .25f ? getMagnetModel() : getHalfMagnetModel(); + } + @Override public void beginFrame(DynamicVisual.Context ctx) { updateOffset(ctx.partialTick()); coil.rotation(rotationAxis.rotationDegrees(offset * 180)) .setChanged(); - int neededRopeCount = getNeededRopeCount(); - rope.resize(neededRopeCount); + magnet.setVisible(isRunning() || offset == 0); - magnet.update() - .get() - .ifPresent(data -> { - int i = Math.max(0, Mth.floor(offset)); - int light = lightCache.getPackedLight(i); - data.position(getVisualPosition()) - .translatePosition(0, -offset, 0) - .light(light) - .setChanged(); - }); + magnetInstancer().stealInstance(magnet); - halfRope.update() - .get() - .ifPresent(rope1 -> { - float f = offset % 1; - float halfRopeNudge = f > .75f ? f - 1 : f; + magnet.setIdentityTransform() + .translate(getVisualPosition()) + .translate(0, -offset, 0) + .light(lightCache.getPackedLight(Math.max(0, Mth.floor(offset)))) + .setChanged(); - int light = lightCache.getPackedLight(0); - rope1.position(getVisualPosition()) - .translatePosition(0, -halfRopeNudge, 0) - .light(light) - .setChanged(); - }); + rope.resetCount(); + + if (shouldRenderHalfRope()) { + float f = offset % 1; + float halfRopeNudge = f > .75f ? f - 1 : f; + + rope.get(true).setIdentityTransform() + .translate(getVisualPosition()) + .translate(0, -halfRopeNudge, 0) + .light(lightCache.getPackedLight(0)) + .setChanged(); + } if (isRunning()) { - int size = rope.size(); - for (int i = 0; i < size; i++) { - int light = lightCache.getPackedLight(size - 1 - i); + int neededRopeCount = getNeededRopeCount(); - rope.get(i) - .position(getVisualPosition()) - .translatePosition(0, -offset + i + 1, 0) - .light(light) + for (int i = 0; i < neededRopeCount; i++) { + + rope.get(false) + .setIdentityTransform() + .translate(getVisualPosition()) + .translate(0, -offset + i + 1, 0) + .light(lightCache.getPackedLight(neededRopeCount - 1 - i)) .setChanged(); } - } else { - rope.clear(); } + + rope.discardExtra(); } @Override @@ -151,21 +148,11 @@ public abstract class AbstractPulleyVisual extends return offset > .75f && (f < .25f || f > .75f); } - private int getMagnetModelIndex() { - if (isRunning() || offset == 0) { - return offset > .25f ? 0 : 1; - } else { - return -1; - } - } - @Override public void collectCrumblingInstances(Consumer consumer) { super.collectCrumblingInstances(consumer); consumer.accept(coil); - magnet.forEach(consumer); - rope.forEach(consumer); - halfRope.forEach(consumer); + consumer.accept(magnet); } @Override @@ -173,8 +160,7 @@ public abstract class AbstractPulleyVisual extends super._delete(); coil.delete(); magnet.delete(); - rope.clear(); - halfRope.delete(); + rope.delete(); } private class LightCache { @@ -186,6 +172,7 @@ public abstract class AbstractPulleyVisual extends public void setSize(int size) { if (size != data.size()) { data.size(size); + update(); int sectionCount = MoreMath.ceilingDiv(size + 15 - pos.getY() + pos.getY() / 4 * 4, SectionPos.SECTION_SIZE); if (sectionCount != this.sectionCount) { @@ -215,7 +202,7 @@ public abstract class AbstractPulleyVisual extends for (int i = 0; i < data.size(); i++) { int blockLight = level.getBrightness(LightLayer.BLOCK, mutablePos); int skyLight = level.getBrightness(LightLayer.SKY, mutablePos); - int light = ((skyLight << 4) & 0xF) | (blockLight & 0xF); + int light = ((skyLight & 0xF) << 4) | (blockLight & 0xF); data.set(i, (byte) light); mutablePos.move(Direction.DOWN); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/pulley/HosePulleyVisual.java b/src/main/java/com/simibubi/create/content/contraptions/pulley/HosePulleyVisual.java index 7857e22db..417541ca9 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/pulley/HosePulleyVisual.java +++ b/src/main/java/com/simibubi/create/content/contraptions/pulley/HosePulleyVisual.java @@ -7,6 +7,7 @@ import dev.engine_room.flywheel.api.instance.Instancer; import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.lib.instance.InstanceTypes; import dev.engine_room.flywheel.lib.instance.OrientedInstance; +import dev.engine_room.flywheel.lib.instance.TransformedInstance; import dev.engine_room.flywheel.lib.model.Models; public class HosePulleyVisual extends AbstractPulleyVisual { @@ -15,28 +16,28 @@ public class HosePulleyVisual extends AbstractPulleyVisual getRopeModel() { - return instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.HOSE)); + protected Instancer getRopeModel() { + return instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.HOSE)); } @Override - protected Instancer getMagnetModel() { - return instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.HOSE_MAGNET)); + protected Instancer getMagnetModel() { + return instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.HOSE_MAGNET)); } @Override - protected Instancer getHalfMagnetModel() { - return instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.HOSE_HALF_MAGNET)); + protected Instancer getHalfMagnetModel() { + return instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.HOSE_HALF_MAGNET)); } @Override protected Instancer getCoilModel() { - return instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.HOSE_COIL, rotatingAbout)); + return instancerProvider().instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.HOSE_COIL, rotatingAbout)); } @Override - protected Instancer getHalfRopeModel() { - return instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.HOSE_HALF)); + protected Instancer getHalfRopeModel() { + return instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.HOSE_HALF)); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/pulley/RopePulleyVisual.java b/src/main/java/com/simibubi/create/content/contraptions/pulley/RopePulleyVisual.java index 6b13def27..3930f79e3 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/pulley/RopePulleyVisual.java +++ b/src/main/java/com/simibubi/create/content/contraptions/pulley/RopePulleyVisual.java @@ -9,6 +9,7 @@ import dev.engine_room.flywheel.api.instance.Instancer; import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.lib.instance.InstanceTypes; import dev.engine_room.flywheel.lib.instance.OrientedInstance; +import dev.engine_room.flywheel.lib.instance.TransformedInstance; import dev.engine_room.flywheel.lib.model.Models; public class RopePulleyVisual extends AbstractPulleyVisual { @@ -17,28 +18,28 @@ public class RopePulleyVisual extends AbstractPulleyVisual { } @Override - protected Instancer getRopeModel() { - return instancerProvider.instancer(InstanceTypes.ORIENTED, VirtualRenderHelper.blockModel(AllBlocks.ROPE.getDefaultState())); + protected Instancer getRopeModel() { + return instancerProvider().instancer(InstanceTypes.TRANSFORMED, VirtualRenderHelper.blockModel(AllBlocks.ROPE.getDefaultState())); } @Override - protected Instancer getMagnetModel() { - return instancerProvider.instancer(InstanceTypes.ORIENTED, VirtualRenderHelper.blockModel(AllBlocks.PULLEY_MAGNET.getDefaultState())); + protected Instancer getMagnetModel() { + return instancerProvider().instancer(InstanceTypes.TRANSFORMED, VirtualRenderHelper.blockModel(AllBlocks.PULLEY_MAGNET.getDefaultState())); } @Override - protected Instancer getHalfMagnetModel() { - return instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.ROPE_HALF_MAGNET)); + protected Instancer getHalfMagnetModel() { + return instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ROPE_HALF_MAGNET)); } @Override protected Instancer getCoilModel() { - return instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.ROPE_COIL, rotatingAbout)); + return instancerProvider().instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.ROPE_COIL, rotatingAbout)); } @Override - protected Instancer getHalfRopeModel() { - return instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.ROPE_HALF)); + protected Instancer getHalfRopeModel() { + return instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ROPE_HALF)); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/render/ContraptionVisual.java b/src/main/java/com/simibubi/create/content/contraptions/render/ContraptionVisual.java index 6b3a038c9..b0d03ed6a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/render/ContraptionVisual.java +++ b/src/main/java/com/simibubi/create/content/contraptions/render/ContraptionVisual.java @@ -93,6 +93,8 @@ public class ContraptionVisual extends Abst .instancer(InstanceTypes.TRANSFORMED, model) .createInstance(); + structure.setChanged(); + for (BlockEntity be : contraption.getRenderedBEs()) { setupVisualizer(be, partialTick); } diff --git a/src/main/java/com/simibubi/create/content/decoration/copycat/CopycatPanelBlock.java b/src/main/java/com/simibubi/create/content/decoration/copycat/CopycatPanelBlock.java index a40db2cdb..06106975c 100644 --- a/src/main/java/com/simibubi/create/content/decoration/copycat/CopycatPanelBlock.java +++ b/src/main/java/com/simibubi/create/content/decoration/copycat/CopycatPanelBlock.java @@ -164,6 +164,11 @@ public class CopycatPanelBlock extends WaterloggedCopycatBlock { return false; } + @Override + public boolean skipRendering(BlockState state, BlockState adjacentState, Direction direction) { + return state.equals(adjacentState) && direction.getAxis().isHorizontal(); + } + @Override public boolean supportsExternalFaceHiding(BlockState state) { return true; diff --git a/src/main/java/com/simibubi/create/content/equipment/armor/BacktankBlock.java b/src/main/java/com/simibubi/create/content/equipment/armor/BacktankBlock.java index 967f0a7f6..93e7fc44d 100644 --- a/src/main/java/com/simibubi/create/content/equipment/armor/BacktankBlock.java +++ b/src/main/java/com/simibubi/create/content/equipment/armor/BacktankBlock.java @@ -184,8 +184,10 @@ public class BacktankBlock extends HorizontalKineticBlock implements IBE blockEntityOptional = getBlockEntityOptional(blockGetter, pos); CompoundTag forgeCapsTag = blockEntityOptional.map(BacktankBlockEntity::getForgeCapsTag) + .map(CompoundTag::copy) .orElse(null); CompoundTag vanillaTag = blockEntityOptional.map(BacktankBlockEntity::getVanillaTag) + .map(CompoundTag::copy) .orElse(new CompoundTag()); int air = blockEntityOptional.map(BacktankBlockEntity::getAirLevel) .orElse(0); diff --git a/src/main/java/com/simibubi/create/content/equipment/armor/BacktankBlockEntity.java b/src/main/java/com/simibubi/create/content/equipment/armor/BacktankBlockEntity.java index 181e5b1bb..6b03b0947 100644 --- a/src/main/java/com/simibubi/create/content/equipment/armor/BacktankBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/equipment/armor/BacktankBlockEntity.java @@ -120,10 +120,10 @@ public class BacktankBlockEntity extends KineticBlockEntity implements Nameable compound.putInt("Air", airLevel); compound.putInt("Timer", airLevelTimer); compound.putInt("CapacityEnchantment", capacityEnchantLevel); - + if (this.customName != null) compound.putString("CustomName", Component.Serializer.toJson(this.customName)); - + compound.put("VanillaTag", vanillaTag); if (forgeCapsTag != null) compound.put("ForgeCapsTag", forgeCapsTag); @@ -136,10 +136,10 @@ public class BacktankBlockEntity extends KineticBlockEntity implements Nameable airLevel = compound.getInt("Air"); airLevelTimer = compound.getInt("Timer"); capacityEnchantLevel = compound.getInt("CapacityEnchantment"); - + if (compound.contains("CustomName", 8)) this.customName = Component.Serializer.fromJson(compound.getString("CustomName")); - + vanillaTag = compound.getCompound("VanillaTag"); forgeCapsTag = compound.contains("ForgeCapsTag") ? compound.getCompound("ForgeCapsTag") : null; @@ -181,16 +181,18 @@ public class BacktankBlockEntity extends KineticBlockEntity implements Nameable public void setCapacityEnchantLevel(int capacityEnchantLevel) { this.capacityEnchantLevel = capacityEnchantLevel; } - + public void setTags(CompoundTag vanillaTag, @Nullable CompoundTag forgeCapsTag) { - this.vanillaTag = vanillaTag; - this.forgeCapsTag = forgeCapsTag; + this.vanillaTag = vanillaTag.copy(); + this.forgeCapsTag = forgeCapsTag == null ? null : forgeCapsTag.copy(); + // Prevent nesting of the ctrl+pick block added tag + vanillaTag.remove("BlockEntityTag"); } public CompoundTag getVanillaTag() { return vanillaTag; } - + public CompoundTag getForgeCapsTag() { return forgeCapsTag; } diff --git a/src/main/java/com/simibubi/create/content/equipment/clipboard/ClipboardBlockEntity.java b/src/main/java/com/simibubi/create/content/equipment/clipboard/ClipboardBlockEntity.java index 7d1afe661..2537f6a88 100644 --- a/src/main/java/com/simibubi/create/content/equipment/clipboard/ClipboardBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/equipment/clipboard/ClipboardBlockEntity.java @@ -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)); diff --git a/src/main/java/com/simibubi/create/content/equipment/symmetryWand/SymmetryHandler.java b/src/main/java/com/simibubi/create/content/equipment/symmetryWand/SymmetryHandler.java index 06e1c2e07..116235545 100644 --- a/src/main/java/com/simibubi/create/content/equipment/symmetryWand/SymmetryHandler.java +++ b/src/main/java/com/simibubi/create/content/equipment/symmetryWand/SymmetryHandler.java @@ -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) diff --git a/src/main/java/com/simibubi/create/content/equipment/symmetryWand/SymmetryWandItem.java b/src/main/java/com/simibubi/create/content/equipment/symmetryWand/SymmetryWandItem.java index c74f0aee9..c203e7976 100644 --- a/src/main/java/com/simibubi/create/content/equipment/symmetryWand/SymmetryWandItem.java +++ b/src/main/java/com/simibubi/create/content/equipment/symmetryWand/SymmetryWandItem.java @@ -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 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; + } } diff --git a/src/main/java/com/simibubi/create/content/equipment/toolbox/ToolBoxVisual.java b/src/main/java/com/simibubi/create/content/equipment/toolbox/ToolBoxVisual.java index c3d355740..f7bcd204f 100644 --- a/src/main/java/com/simibubi/create/content/equipment/toolbox/ToolBoxVisual.java +++ b/src/main/java/com/simibubi/create/content/equipment/toolbox/ToolBoxVisual.java @@ -28,10 +28,10 @@ public class ToolBoxVisual extends AbstractBlockEntityVisual facing = blockState.getValue(ToolboxBlock.FACING) .getOpposite(); - Instancer drawerModel = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.TOOLBOX_DRAWER)); + Instancer drawerModel = instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.TOOLBOX_DRAWER)); drawers = new TransformedInstance[]{drawerModel.createInstance(), drawerModel.createInstance()}; - lid = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.TOOLBOX_LIDS.get(blockEntity.getColor()))) + lid = instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.TOOLBOX_LIDS.get(blockEntity.getColor()))) .createInstance(); } diff --git a/src/main/java/com/simibubi/create/content/equipment/toolbox/ToolboxBlock.java b/src/main/java/com/simibubi/create/content/equipment/toolbox/ToolboxBlock.java index 613ae9153..7afa382f6 100644 --- a/src/main/java/com/simibubi/create/content/equipment/toolbox/ToolboxBlock.java +++ b/src/main/java/com/simibubi/create/content/equipment/toolbox/ToolboxBlock.java @@ -8,6 +8,7 @@ import com.simibubi.create.AllBlockEntityTypes; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllShapes; import com.simibubi.create.foundation.block.IBE; +import com.simibubi.create.foundation.item.ItemHelper; import com.simibubi.create.foundation.utility.BlockHelper; import net.minecraft.core.BlockPos; @@ -22,7 +23,6 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; @@ -38,6 +38,7 @@ import net.minecraft.world.level.material.Fluids; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; +import net.minecraftforge.common.capabilities.ForgeCapabilities; import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.network.NetworkHooks; @@ -171,7 +172,7 @@ public class ToolboxBlock extends HorizontalDirectionalBlock implements SimpleWa public Class getBlockEntityClass() { return ToolboxBlockEntity.class; } - + @Override public BlockEntityType getBlockEntityType() { return AllBlockEntityTypes.TOOLBOX.get(); @@ -181,9 +182,14 @@ public class ToolboxBlock extends HorizontalDirectionalBlock implements SimpleWa return color; } - public static Ingredient getMainBox() { - return Ingredient.of(AllBlocks.TOOLBOXES.get(DyeColor.BROWN) - .get()); + @Override + public boolean hasAnalogOutputSignal(BlockState pState) { + return true; + } + + @Override + public int getAnalogOutputSignal(BlockState pState, Level pLevel, BlockPos pPos) { + return ItemHelper.calcRedstoneFromBlockEntity(this, pLevel, pPos); } } diff --git a/src/main/java/com/simibubi/create/content/equipment/toolbox/ToolboxInventory.java b/src/main/java/com/simibubi/create/content/equipment/toolbox/ToolboxInventory.java index a9d69e9ca..bb16f4feb 100644 --- a/src/main/java/com/simibubi/create/content/equipment/toolbox/ToolboxInventory.java +++ b/src/main/java/com/simibubi/create/content/equipment/toolbox/ToolboxInventory.java @@ -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(); + } + } diff --git a/src/main/java/com/simibubi/create/content/fluids/OpenEndedPipe.java b/src/main/java/com/simibubi/create/content/fluids/OpenEndedPipe.java index 75822e28f..f4b633d10 100644 --- a/src/main/java/com/simibubi/create/content/fluids/OpenEndedPipe.java +++ b/src/main/java/com/simibubi/create/content/fluids/OpenEndedPipe.java @@ -192,7 +192,7 @@ public class OpenEndedPipe extends FlowSource { if (!FluidHelper.hasBlockState(fluid.getFluid())) return true; - if (!fluidState.isEmpty() && fluidState.getType() != fluid.getFluid()) { + if (!fluidState.isEmpty() && FluidHelper.convertToStill(fluidState.getType()) != fluid.getFluid()) { FluidReactions.handlePipeSpillCollision(world, outputPos, fluid.getFluid(), fluidState); return false; } diff --git a/src/main/java/com/simibubi/create/content/fluids/drain/ItemDrainItemHandler.java b/src/main/java/com/simibubi/create/content/fluids/drain/ItemDrainItemHandler.java index d69e16c55..44da916ea 100644 --- a/src/main/java/com/simibubi/create/content/fluids/drain/ItemDrainItemHandler.java +++ b/src/main/java/com/simibubi/create/content/fluids/drain/ItemDrainItemHandler.java @@ -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); diff --git a/src/main/java/com/simibubi/create/content/fluids/pipes/valve/FluidValveVisual.java b/src/main/java/com/simibubi/create/content/fluids/pipes/valve/FluidValveVisual.java index 120136561..538b7de3c 100644 --- a/src/main/java/com/simibubi/create/content/fluids/pipes/valve/FluidValveVisual.java +++ b/src/main/java/com/simibubi/create/content/fluids/pipes/valve/FluidValveVisual.java @@ -41,7 +41,7 @@ public class FluidValveVisual extends ShaftVisual impleme pointerRotationOffset = twist ? 90 : 0; settled = false; - pointer = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.FLUID_VALVE_POINTER)).createInstance(); + pointer = instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.FLUID_VALVE_POINTER)).createInstance(); transformPointer(partialTick); } diff --git a/src/main/java/com/simibubi/create/content/fluids/tank/FluidTankBlock.java b/src/main/java/com/simibubi/create/content/fluids/tank/FluidTankBlock.java index b2b29a87f..50a7f7ebf 100644 --- a/src/main/java/com/simibubi/create/content/fluids/tank/FluidTankBlock.java +++ b/src/main/java/com/simibubi/create/content/fluids/tank/FluidTankBlock.java @@ -106,7 +106,7 @@ public class FluidTankBlock extends Block implements IWrenchable, IBE= 10) { onBlockBroken(stateToBreak); @@ -142,7 +142,7 @@ public abstract class BlockBreakingKineticBlockEntity extends KineticBlockEntity return; if (level.restoringBlockSnapshots) return; - + ItemEntity itementity = new ItemEntity(level, vec.x, vec.y, vec.z, stack); itementity.setDefaultPickUpDelay(); itementity.setDeltaMovement(Vec3.ZERO); diff --git a/src/main/java/com/simibubi/create/content/kinetics/base/GeneratingKineticBlockEntity.java b/src/main/java/com/simibubi/create/content/kinetics/base/GeneratingKineticBlockEntity.java index b11625687..724bab243 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/base/GeneratingKineticBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/kinetics/base/GeneratingKineticBlockEntity.java @@ -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); Lang.number(stressTotal) .translate("generic.unit.stress") diff --git a/src/main/java/com/simibubi/create/content/kinetics/base/SingleRotatingVisual.java b/src/main/java/com/simibubi/create/content/kinetics/base/SingleRotatingVisual.java index ba5ec60ec..84cc91d04 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/base/SingleRotatingVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/base/SingleRotatingVisual.java @@ -15,7 +15,7 @@ public class SingleRotatingVisual extends KineticB public SingleRotatingVisual(VisualizationContext context, T blockEntity, float partialTick) { super(context, blockEntity, partialTick); - rotatingModel = instancerProvider.instancer(AllInstanceTypes.ROTATING, model()) + rotatingModel = instancerProvider().instancer(AllInstanceTypes.ROTATING, model()) .createInstance(); setup(rotatingModel); } diff --git a/src/main/java/com/simibubi/create/content/kinetics/belt/BeltBlock.java b/src/main/java/com/simibubi/create/content/kinetics/belt/BeltBlock.java index 50237a1d9..c373d7933 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/belt/BeltBlock.java +++ b/src/main/java/com/simibubi/create/content/kinetics/belt/BeltBlock.java @@ -218,6 +218,8 @@ public class BeltBlock extends HorizontalKineticBlock .copy(), false); if (remainder.isEmpty()) itemEntity.discard(); + else if (remainder.getCount() != itemEntity.getItem().getCount()) + itemEntity.setItem(remainder); }); return; } diff --git a/src/main/java/com/simibubi/create/content/kinetics/belt/BeltRenderer.java b/src/main/java/com/simibubi/create/content/kinetics/belt/BeltRenderer.java index edadb36a3..35f251a08 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/belt/BeltRenderer.java +++ b/src/main/java/com/simibubi/create/content/kinetics/belt/BeltRenderer.java @@ -239,7 +239,7 @@ public class BeltRenderer extends SafeBlockEntityRenderer { be.getBlockPos().getZ()) .add(offsetVec); - if (this.shouldCullItem(itemPos)) { + if (this.shouldCullItem(itemPos, be.getLevel())) { continue; } diff --git a/src/main/java/com/simibubi/create/content/kinetics/belt/BeltVisual.java b/src/main/java/com/simibubi/create/content/kinetics/belt/BeltVisual.java index 625c79092..0a95b470e 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/belt/BeltVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/belt/BeltVisual.java @@ -65,7 +65,7 @@ public class BeltVisual extends KineticBlockEntityVisual { PartialModel beltPartial = BeltRenderer.getBeltPartial(diagonal, start, end, bottom); SpriteShiftEntry spriteShift = BeltRenderer.getSpriteShiftEntry(color, diagonal, bottom); - Instancer beltModel = instancerProvider.instancer(AllInstanceTypes.BELT, Models.partial(beltPartial)); + Instancer beltModel = instancerProvider().instancer(AllInstanceTypes.BELT, Models.partial(beltPartial)); keys.add(setup(beltModel.createInstance(), bottom, spriteShift)); @@ -138,7 +138,7 @@ public class BeltVisual extends KineticBlockEntityVisual { msr.uncenter(); }); - return instancerProvider.instancer(AllInstanceTypes.ROTATING, model); + return instancerProvider().instancer(AllInstanceTypes.ROTATING, model); } private Direction getOrientation() { diff --git a/src/main/java/com/simibubi/create/content/kinetics/belt/transport/ItemHandlerBeltSegment.java b/src/main/java/com/simibubi/create/content/kinetics/belt/transport/ItemHandlerBeltSegment.java index 0a5248c5f..15f20c86d 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/belt/transport/ItemHandlerBeltSegment.java +++ b/src/main/java/com/simibubi/create/content/kinetics/belt/transport/ItemHandlerBeltSegment.java @@ -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; } diff --git a/src/main/java/com/simibubi/create/content/kinetics/crank/HandCrankVisual.java b/src/main/java/com/simibubi/create/content/kinetics/crank/HandCrankVisual.java index 1eebee84b..45f4ae30c 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/crank/HandCrankVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/crank/HandCrankVisual.java @@ -27,13 +27,13 @@ public class HandCrankVisual extends KineticBlockEntityVisual> polishingRecipe = checkRecipe(AllRecipeTypes.SANDPAPER_POLISHING, sandpaperInv, level); + if (polishingRecipe.isPresent()){ + return polishingRecipe.get(); + } } recipeInv.setItem(0, stack); diff --git a/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerItemHandler.java b/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerItemHandler.java index ecabcf2ed..ac106c825 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerItemHandler.java +++ b/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerItemHandler.java @@ -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)) diff --git a/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerVisual.java b/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerVisual.java index 173a08816..82e46cf65 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerVisual.java @@ -52,11 +52,11 @@ public class DeployerVisual extends ShaftVisual implements xRot = facing == Direction.UP ? 270 : facing == Direction.DOWN ? 90 : 0; zRot = rotatePole ? 90 : 0; - pole = instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.DEPLOYER_POLE)).createInstance(); + pole = instancerProvider().instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.DEPLOYER_POLE)).createInstance(); currentHand = this.blockEntity.getHandPose(); - hand = instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(currentHand)).createInstance(); + hand = instancerProvider().instancer(InstanceTypes.ORIENTED, Models.partial(currentHand)).createInstance(); progress = getProgress(partialTick); updateRotation(pole, hand, yRot, xRot, zRot); @@ -69,7 +69,7 @@ public class DeployerVisual extends ShaftVisual implements if (currentHand != handPose) { currentHand = handPose; - instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(currentHand)) + instancerProvider().instancer(InstanceTypes.ORIENTED, Models.partial(currentHand)) .stealInstance(hand); } } diff --git a/src/main/java/com/simibubi/create/content/kinetics/fan/FanVisual.java b/src/main/java/com/simibubi/create/content/kinetics/fan/FanVisual.java index 2a1a030f7..57aa69a52 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/fan/FanVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/fan/FanVisual.java @@ -29,8 +29,8 @@ public class FanVisual extends KineticBlockEntityVisual { direction = blockState.getValue(FACING); opposite = direction.getOpposite(); - shaft = instancerProvider.instancer(AllInstanceTypes.ROTATING, Models.partial(AllPartialModels.SHAFT_HALF, opposite)).createInstance(); - fan = instancerProvider.instancer(AllInstanceTypes.ROTATING, Models.partial(AllPartialModels.ENCASED_FAN_INNER, opposite)) + shaft = instancerProvider().instancer(AllInstanceTypes.ROTATING, Models.partial(AllPartialModels.SHAFT_HALF, opposite)).createInstance(); + fan = instancerProvider().instancer(AllInstanceTypes.ROTATING, Models.partial(AllPartialModels.ENCASED_FAN_INNER, opposite)) .createInstance(); setup(shaft); diff --git a/src/main/java/com/simibubi/create/content/kinetics/flywheel/FlywheelVisual.java b/src/main/java/com/simibubi/create/content/kinetics/flywheel/FlywheelVisual.java index 930f952d1..4512c0908 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/flywheel/FlywheelVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/flywheel/FlywheelVisual.java @@ -27,9 +27,9 @@ public class FlywheelVisual extends KineticBlockEntityVisual implemen GaugeBlock gaugeBlock = (GaugeBlock) blockState.getBlock(); - Instancer dialModel = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.GAUGE_DIAL)); + Instancer dialModel = instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.GAUGE_DIAL)); Instancer headModel = getHeadModel(); var msr = TransformStack.of(ms); @@ -157,7 +157,7 @@ public abstract class GaugeVisual extends ShaftVisual implemen @Override protected Instancer getHeadModel() { - return instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.GAUGE_HEAD_SPEED)); + return instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.GAUGE_HEAD_SPEED)); } } @@ -168,7 +168,7 @@ public abstract class GaugeVisual extends ShaftVisual implemen @Override protected Instancer getHeadModel() { - return instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.GAUGE_HEAD_STRESS)); + return instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.GAUGE_HEAD_STRESS)); } } } diff --git a/src/main/java/com/simibubi/create/content/kinetics/gearbox/GearboxVisual.java b/src/main/java/com/simibubi/create/content/kinetics/gearbox/GearboxVisual.java index eaf39e215..e03c70e01 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/gearbox/GearboxVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/gearbox/GearboxVisual.java @@ -41,7 +41,7 @@ public class GearboxVisual extends KineticBlockEntityVisual if (boxAxis == axis) continue; - RotatingInstance key = instancerProvider.instancer(AllInstanceTypes.ROTATING, Models.partial(AllPartialModels.SHAFT_HALF, direction)) + RotatingInstance key = instancerProvider().instancer(AllInstanceTypes.ROTATING, Models.partial(AllPartialModels.SHAFT_HALF, direction)) .createInstance(); key.setRotationAxis(axis) diff --git a/src/main/java/com/simibubi/create/content/kinetics/mechanicalArm/AllArmInteractionPointTypes.java b/src/main/java/com/simibubi/create/content/kinetics/mechanicalArm/AllArmInteractionPointTypes.java index 8740d5740..d6d7c6c0c 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/mechanicalArm/AllArmInteractionPointTypes.java +++ b/src/main/java/com/simibubi/create/content/kinetics/mechanicalArm/AllArmInteractionPointTypes.java @@ -646,45 +646,30 @@ public class AllArmInteractionPointTypes { @Override public ItemStack insert(ItemStack stack, boolean simulate) { - Item item = stack.getItem(); - if (!(item instanceof RecordItem)) + if (!(stack.getItem() instanceof RecordItem)) return stack; - if (cachedState.getOptionalValue(JukeboxBlock.HAS_RECORD) - .orElse(true)) + if (cachedState.getOptionalValue(JukeboxBlock.HAS_RECORD).orElse(true)) return stack; - BlockEntity blockEntity = level.getBlockEntity(pos); - if (!(blockEntity instanceof JukeboxBlockEntity jukeboxBE)) + if (!(level.getBlockEntity(pos) instanceof JukeboxBlockEntity jukeboxBE)) return stack; - if (!jukeboxBE.getFirstItem() - .isEmpty()) + if (!jukeboxBE.getFirstItem().isEmpty()) return stack; ItemStack remainder = stack.copy(); ItemStack toInsert = remainder.split(1); - if (!simulate) { - jukeboxBE.setFirstItem(toInsert); - level.setBlock(pos, cachedState.setValue(JukeboxBlock.HAS_RECORD, true), 2); - level.levelEvent(null, 1010, pos, Item.getId(item)); - } + if (!simulate) + jukeboxBE.setItem(0, toInsert); return remainder; } @Override public ItemStack extract(int slot, int amount, boolean simulate) { - if (!cachedState.getOptionalValue(JukeboxBlock.HAS_RECORD) - .orElse(false)) + if (!cachedState.getOptionalValue(JukeboxBlock.HAS_RECORD).orElse(false)) return ItemStack.EMPTY; - BlockEntity blockEntity = level.getBlockEntity(pos); - if (!(blockEntity instanceof JukeboxBlockEntity jukeboxBE)) + if (!(level.getBlockEntity(pos) instanceof JukeboxBlockEntity jukeboxBE)) return ItemStack.EMPTY; - ItemStack record = jukeboxBE.getFirstItem(); - if (record.isEmpty()) - return ItemStack.EMPTY; - if (!simulate) { - level.levelEvent(1010, pos, 0); - jukeboxBE.clearContent(); - level.setBlock(pos, cachedState.setValue(JukeboxBlock.HAS_RECORD, false), 2); - } - return record; + if (!simulate) + return jukeboxBE.removeItem(slot, amount); + return jukeboxBE.getFirstItem(); } } diff --git a/src/main/java/com/simibubi/create/content/kinetics/mechanicalArm/ArmVisual.java b/src/main/java/com/simibubi/create/content/kinetics/mechanicalArm/ArmVisual.java index 47e1e40e1..91cb6cb81 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/mechanicalArm/ArmVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/mechanicalArm/ArmVisual.java @@ -49,18 +49,18 @@ public class ArmVisual extends SingleRotatingVisual implements S public ArmVisual(VisualizationContext context, ArmBlockEntity blockEntity, float partialTick) { super(context, blockEntity, partialTick); - base = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ARM_BASE)) + base = instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ARM_BASE)) .createInstance(); - lowerBody = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ARM_LOWER_BODY)) + lowerBody = instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ARM_LOWER_BODY)) .createInstance(); - upperBody = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ARM_UPPER_BODY)) + upperBody = instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ARM_UPPER_BODY)) .createInstance(); - claw = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(blockEntity.goggles ? AllPartialModels.ARM_CLAW_BASE_GOGGLES : AllPartialModels.ARM_CLAW_BASE)) + claw = instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(blockEntity.goggles ? AllPartialModels.ARM_CLAW_BASE_GOGGLES : AllPartialModels.ARM_CLAW_BASE)) .createInstance(); - TransformedInstance clawGrip1 = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ARM_CLAW_GRIP_UPPER)) + TransformedInstance clawGrip1 = instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ARM_CLAW_GRIP_UPPER)) .createInstance(); - TransformedInstance clawGrip2 = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ARM_CLAW_GRIP_LOWER)) + TransformedInstance clawGrip2 = instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ARM_CLAW_GRIP_LOWER)) .createInstance(); clawGrips = Lists.newArrayList(clawGrip1, clawGrip2); @@ -175,7 +175,7 @@ public class ArmVisual extends SingleRotatingVisual implements S super.update(pt); models.remove(claw); claw.delete(); - claw = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(blockEntity.goggles ? AllPartialModels.ARM_CLAW_BASE_GOGGLES : AllPartialModels.ARM_CLAW_BASE)) + claw = instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(blockEntity.goggles ? AllPartialModels.ARM_CLAW_BASE_GOGGLES : AllPartialModels.ARM_CLAW_BASE)) .createInstance(); models.add(claw); updateLight(pt); diff --git a/src/main/java/com/simibubi/create/content/kinetics/mixer/MixerVisual.java b/src/main/java/com/simibubi/create/content/kinetics/mixer/MixerVisual.java index 74aeb1c4e..f229d9d87 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/mixer/MixerVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/mixer/MixerVisual.java @@ -27,12 +27,12 @@ public class MixerVisual extends EncasedCogVisual implements SimpleDynamicVisual super(context, blockEntity, false, partialTick); this.mixer = blockEntity; - mixerHead = instancerProvider.instancer(AllInstanceTypes.ROTATING, Models.partial(AllPartialModels.MECHANICAL_MIXER_HEAD)) + mixerHead = instancerProvider().instancer(AllInstanceTypes.ROTATING, Models.partial(AllPartialModels.MECHANICAL_MIXER_HEAD)) .createInstance(); mixerHead.setRotationAxis(Direction.Axis.Y); - mixerPole = instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.MECHANICAL_MIXER_POLE)) + mixerPole = instancerProvider().instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.MECHANICAL_MIXER_POLE)) .createInstance(); animate(partialTick); diff --git a/src/main/java/com/simibubi/create/content/kinetics/press/PressVisual.java b/src/main/java/com/simibubi/create/content/kinetics/press/PressVisual.java index e73394343..2a5faecc8 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/press/PressVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/press/PressVisual.java @@ -24,7 +24,7 @@ public class PressVisual extends ShaftVisual impleme public PressVisual(VisualizationContext context, MechanicalPressBlockEntity blockEntity, float partialTick) { super(context, blockEntity, partialTick); - pressHead = instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.MECHANICAL_PRESS_HEAD)) + pressHead = instancerProvider().instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.MECHANICAL_PRESS_HEAD)) .createInstance(); Quaternionf q = Axis.YP diff --git a/src/main/java/com/simibubi/create/content/kinetics/simpleRelays/AbstractSimpleShaftBlock.java b/src/main/java/com/simibubi/create/content/kinetics/simpleRelays/AbstractSimpleShaftBlock.java index d4ad89d44..c6eaeb67e 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/simpleRelays/AbstractSimpleShaftBlock.java +++ b/src/main/java/com/simibubi/create/content/kinetics/simpleRelays/AbstractSimpleShaftBlock.java @@ -37,7 +37,10 @@ public abstract class AbstractSimpleShaftBlock extends AbstractShaftBlock implem @Override public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean isMoving) { - if (state != newState && !isMoving) + boolean wasWaterLogged = state.hasProperty(WATERLOGGED) && + newState.hasProperty(WATERLOGGED) && + (state.getValue(WATERLOGGED) != newState.getValue(WATERLOGGED)); + if (state != newState && !isMoving && !wasWaterLogged) removeBracket(world, pos, true).ifPresent(stack -> Block.popResource(world, pos, stack)); super.onRemove(state, world, pos, newState, isMoving); } diff --git a/src/main/java/com/simibubi/create/content/kinetics/simpleRelays/BracketedKineticBlockEntityVisual.java b/src/main/java/com/simibubi/create/content/kinetics/simpleRelays/BracketedKineticBlockEntityVisual.java index 35af391de..0b6b5b7fa 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/simpleRelays/BracketedKineticBlockEntityVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/simpleRelays/BracketedKineticBlockEntityVisual.java @@ -39,7 +39,7 @@ public class BracketedKineticBlockEntityVisual extends SingleRotatingVisual half = instancerProvider.instancer(AllInstanceTypes.ROTATING, model); + Instancer half = instancerProvider().instancer(AllInstanceTypes.ROTATING, model); additionalShaft = setup(half.createInstance(), speed); additionalShaft.setRotationOffset(offset) diff --git a/src/main/java/com/simibubi/create/content/kinetics/simpleRelays/encased/EncasedCogVisual.java b/src/main/java/com/simibubi/create/content/kinetics/simpleRelays/encased/EncasedCogVisual.java index 4f571885d..2fabcafcb 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/simpleRelays/encased/EncasedCogVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/simpleRelays/encased/EncasedCogVisual.java @@ -49,7 +49,7 @@ public class EncasedCogVisual extends KineticBlockEntityVisual extends KineticBlockEntityVisual { - private static final ModelCache MODEL_CACHE = new ModelCache<>(WaterWheelVisual::createModel); + private static final ResourceReloadCache MODEL_CACHE = new ResourceReloadCache<>(WaterWheelVisual::createModel); protected final boolean large; protected BlockState lastMaterial; @@ -42,7 +42,7 @@ public class WaterWheelVisual extends KineticBl private void setupInstance() { lastMaterial = blockEntity.material; - rotatingModel = instancerProvider.instancer(AllInstanceTypes.ROTATING, MODEL_CACHE.get(new WaterWheelModelKey(large, blockState, blockEntity.material))) + rotatingModel = instancerProvider().instancer(AllInstanceTypes.ROTATING, MODEL_CACHE.get(new WaterWheelModelKey(large, blockState, blockEntity.material))) .createInstance(); setup(rotatingModel); } diff --git a/src/main/java/com/simibubi/create/content/logistics/chute/ChuteItemHandler.java b/src/main/java/com/simibubi/create/content/logistics/chute/ChuteItemHandler.java index 72a77ff01..7179a1d26 100644 --- a/src/main/java/com/simibubi/create/content/logistics/chute/ChuteItemHandler.java +++ b/src/main/java/com/simibubi/create/content/logistics/chute/ChuteItemHandler.java @@ -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 diff --git a/src/main/java/com/simibubi/create/content/logistics/depot/EjectorVisual.java b/src/main/java/com/simibubi/create/content/logistics/depot/EjectorVisual.java index c1df29c35..c1bcae3c2 100644 --- a/src/main/java/com/simibubi/create/content/logistics/depot/EjectorVisual.java +++ b/src/main/java/com/simibubi/create/content/logistics/depot/EjectorVisual.java @@ -22,7 +22,7 @@ public class EjectorVisual extends ShaftVisual implements Si public EjectorVisual(VisualizationContext dispatcher, EjectorBlockEntity blockEntity, float partialTick) { super(dispatcher, blockEntity, partialTick); - plate = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.EJECTOR_TOP)).createInstance(); + plate = instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.EJECTOR_TOP)).createInstance(); pivotPlate(getLidProgress(partialTick)); } diff --git a/src/main/java/com/simibubi/create/content/logistics/filter/FilterItemStack.java b/src/main/java/com/simibubi/create/content/logistics/filter/FilterItemStack.java index 8f3c38f87..196825a7c 100644 --- a/src/main/java/com/simibubi/create/content/logistics/filter/FilterItemStack.java +++ b/src/main/java/com/simibubi/create/content/logistics/filter/FilterItemStack.java @@ -23,14 +23,15 @@ public class FilterItemStack { public static FilterItemStack of(ItemStack filter) { if (filter.hasTag()) { - CompoundTag stackTag = filter.getTag(); - stackTag.remove("Enchantments"); - stackTag.remove("AttributeModifiers"); - if (AllItems.FILTER.isIn(filter)) + if (AllItems.FILTER.isIn(filter)){ + trimFilterTag(filter); return new ListFilterItemStack(filter); - if (AllItems.ATTRIBUTE_FILTER.isIn(filter)) + } + if (AllItems.ATTRIBUTE_FILTER.isIn(filter)){ + trimFilterTag(filter); return new AttributeFilterItemStack(filter); + } } return new FilterItemStack(filter); @@ -39,11 +40,17 @@ public class FilterItemStack { public static FilterItemStack of(CompoundTag tag) { return of(ItemStack.of(tag)); } - + public static FilterItemStack empty() { return of(ItemStack.EMPTY); } + private static void trimFilterTag(ItemStack filter){ + CompoundTag stackTag = filter.getTag(); + stackTag.remove("Enchantments"); + stackTag.remove("AttributeModifiers"); + } + public boolean isEmpty() { return filterItemStack.isEmpty(); } @@ -51,16 +58,16 @@ public class FilterItemStack { public CompoundTag serializeNBT() { return filterItemStack.serializeNBT(); } - + public ItemStack item() { return filterItemStack; } - + public FluidStack fluid(Level level) { resolveFluid(level); return filterFluidStack; } - + public boolean isFilterItem() { return filterItemStack.getItem() instanceof FilterItem; } @@ -98,7 +105,7 @@ public class FilterItemStack { } // - + private void resolveFluid(Level world) { if (!fluidExtracted) { fluidExtracted = true; diff --git a/src/main/java/com/simibubi/create/content/logistics/funnel/FunnelBlock.java b/src/main/java/com/simibubi/create/content/logistics/funnel/FunnelBlock.java index d617c9e42..460819ad9 100644 --- a/src/main/java/com/simibubi/create/content/logistics/funnel/FunnelBlock.java +++ b/src/main/java/com/simibubi/create/content/logistics/funnel/FunnelBlock.java @@ -93,7 +93,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; diff --git a/src/main/java/com/simibubi/create/content/logistics/funnel/FunnelVisual.java b/src/main/java/com/simibubi/create/content/logistics/funnel/FunnelVisual.java index 527d2d48b..3dd2bb7f8 100644 --- a/src/main/java/com/simibubi/create/content/logistics/funnel/FunnelVisual.java +++ b/src/main/java/com/simibubi/create/content/logistics/funnel/FunnelVisual.java @@ -34,7 +34,7 @@ public class FunnelVisual extends AbstractBlockEntityVisual i PartialModel flapPartial = (blockState.getBlock() instanceof FunnelBlock ? AllPartialModels.FUNNEL_FLAP : AllPartialModels.BELT_FUNNEL_FLAP); - Instancer model = instancerProvider.instancer(AllInstanceTypes.FLAP, Models.partial(flapPartial)); + Instancer model = instancerProvider().instancer(AllInstanceTypes.FLAP, Models.partial(flapPartial)); int blockLight = level.getBrightness(LightLayer.BLOCK, pos); int skyLight = level.getBrightness(LightLayer.SKY, pos); diff --git a/src/main/java/com/simibubi/create/content/logistics/tunnel/BeltTunnelVisual.java b/src/main/java/com/simibubi/create/content/logistics/tunnel/BeltTunnelVisual.java index 288dbf54d..f4171b9c9 100644 --- a/src/main/java/com/simibubi/create/content/logistics/tunnel/BeltTunnelVisual.java +++ b/src/main/java/com/simibubi/create/content/logistics/tunnel/BeltTunnelVisual.java @@ -34,7 +34,7 @@ public class BeltTunnelVisual extends AbstractBlockEntityVisual model = instancerProvider.instancer(AllInstanceTypes.FLAP, Models.partial(AllPartialModels.BELT_TUNNEL_FLAP)); + Instancer model = instancerProvider().instancer(AllInstanceTypes.FLAP, Models.partial(AllPartialModels.BELT_TUNNEL_FLAP)); int blockLight = level.getBrightness(LightLayer.BLOCK, pos); int skyLight = level.getBrightness(LightLayer.SKY, pos); diff --git a/src/main/java/com/simibubi/create/content/logistics/tunnel/BrassTunnelItemHandler.java b/src/main/java/com/simibubi/create/content/logistics/tunnel/BrassTunnelItemHandler.java index 430755c50..0db27450a 100644 --- a/src/main/java/com/simibubi/create/content/logistics/tunnel/BrassTunnelItemHandler.java +++ b/src/main/java/com/simibubi/create/content/logistics/tunnel/BrassTunnelItemHandler.java @@ -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 diff --git a/src/main/java/com/simibubi/create/content/logistics/vault/ItemVaultBlock.java b/src/main/java/com/simibubi/create/content/logistics/vault/ItemVaultBlock.java index 7d3fd37a1..d874732a1 100644 --- a/src/main/java/com/simibubi/create/content/logistics/vault/ItemVaultBlock.java +++ b/src/main/java/com/simibubi/create/content/logistics/vault/ItemVaultBlock.java @@ -159,11 +159,7 @@ public class ItemVaultBlock extends Block implements IWrenchable, IBE vte.getCapability(ForgeCapabilities.ITEM_HANDLER)) - .map(lo -> lo.map(ItemHelper::calcRedstoneFromInventory) - .orElse(0)) - .orElse(0); + return ItemHelper.calcRedstoneFromBlockEntity(this, pLevel, pPos); } @Override diff --git a/src/main/java/com/simibubi/create/content/logistics/vault/ItemVaultItem.java b/src/main/java/com/simibubi/create/content/logistics/vault/ItemVaultItem.java index 260e86d37..dac93a634 100644 --- a/src/main/java/com/simibubi/create/content/logistics/vault/ItemVaultItem.java +++ b/src/main/java/com/simibubi/create/content/logistics/vault/ItemVaultItem.java @@ -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 com.simibubi.create.foundation.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; diff --git a/src/main/java/com/simibubi/create/content/processing/basin/BasinBlockEntity.java b/src/main/java/com/simibubi/create/content/processing/basin/BasinBlockEntity.java index 1c5c80953..0f7897836 100644 --- a/src/main/java/com/simibubi/create/content/processing/basin/BasinBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/processing/basin/BasinBlockEntity.java @@ -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)); } } diff --git a/src/main/java/com/simibubi/create/content/processing/burner/BlazeBurnerVisual.java b/src/main/java/com/simibubi/create/content/processing/burner/BlazeBurnerVisual.java index 32f6971b9..2542cdd3e 100644 --- a/src/main/java/com/simibubi/create/content/processing/burner/BlazeBurnerVisual.java +++ b/src/main/java/com/simibubi/create/content/processing/burner/BlazeBurnerVisual.java @@ -55,7 +55,7 @@ public class BlazeBurnerVisual extends AbstractBlockEntityVisual 0.125f; @@ -98,7 +104,7 @@ public class BlazeBurnerVisual extends AbstractBlockEntityVisual 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); } diff --git a/src/main/java/com/simibubi/create/content/redstone/displayLink/target/DisplayTarget.java b/src/main/java/com/simibubi/create/content/redstone/displayLink/target/DisplayTarget.java index ee6163d8a..f59159e49 100644 --- a/src/main/java/com/simibubi/create/content/redstone/displayLink/target/DisplayTarget.java +++ b/src/main/java/com/simibubi/create/content/redstone/displayLink/target/DisplayTarget.java @@ -67,5 +67,9 @@ public abstract class DisplayTarget extends DisplayBehaviour { tag.remove("DisplayLink"); return false; } + + public boolean requiresComponentSanitization() { + return false; + } } diff --git a/src/main/java/com/simibubi/create/content/redstone/displayLink/target/LecternDisplayTarget.java b/src/main/java/com/simibubi/create/content/redstone/displayLink/target/LecternDisplayTarget.java index fdc087b4f..15ec2a072 100644 --- a/src/main/java/com/simibubi/create/content/redstone/displayLink/target/LecternDisplayTarget.java +++ b/src/main/java/com/simibubi/create/content/redstone/displayLink/target/LecternDisplayTarget.java @@ -80,5 +80,10 @@ public class LecternDisplayTarget extends DisplayTarget { return written; } + + @Override + public boolean requiresComponentSanitization() { + return true; + } } diff --git a/src/main/java/com/simibubi/create/content/redstone/displayLink/target/SignDisplayTarget.java b/src/main/java/com/simibubi/create/content/redstone/displayLink/target/SignDisplayTarget.java index 12b456197..3c7a4d69d 100644 --- a/src/main/java/com/simibubi/create/content/redstone/displayLink/target/SignDisplayTarget.java +++ b/src/main/java/com/simibubi/create/content/redstone/displayLink/target/SignDisplayTarget.java @@ -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; + } } diff --git a/src/main/java/com/simibubi/create/content/redstone/link/controller/LecternControllerBlockEntity.java b/src/main/java/com/simibubi/create/content/redstone/link/controller/LecternControllerBlockEntity.java index 9760e97fc..9d4915ca9 100644 --- a/src/main/java/com/simibubi/create/content/redstone/link/controller/LecternControllerBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/redstone/link/controller/LecternControllerBlockEntity.java @@ -3,6 +3,7 @@ package com.simibubi.create.content.redstone.link.controller; import java.util.List; import java.util.UUID; +import com.simibubi.create.AllItems; import com.simibubi.create.AllSoundEvents; import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour; @@ -28,7 +29,7 @@ import net.minecraftforge.fml.DistExecutor; public class LecternControllerBlockEntity extends SmartBlockEntity { - private ItemStack controller = ItemStack.EMPTY; + private CompoundTag controllerNbt = new CompoundTag(); private UUID user; private UUID prevUser; // used only on client private boolean deactivatedThisTick; // used only on server @@ -43,7 +44,7 @@ public class LecternControllerBlockEntity extends SmartBlockEntity { @Override protected void write(CompoundTag compound, boolean clientPacket) { super.write(compound, clientPacket); - compound.put("Controller", controller.save(new CompoundTag())); + compound.put("ControllerData", controllerNbt); if (user != null) compound.putUUID("User", user); } @@ -51,18 +52,25 @@ public class LecternControllerBlockEntity extends SmartBlockEntity { @Override public void writeSafe(CompoundTag compound) { super.writeSafe(compound); - compound.put("Controller", controller.save(new CompoundTag())); + compound.put("ControllerData", controllerNbt); } @Override protected void read(CompoundTag compound, boolean clientPacket) { super.read(compound, clientPacket); - controller = ItemStack.of(compound.getCompound("Controller")); + + // Migrate old data if that is found + if (compound.contains("Controller")) { + controllerNbt = ItemStack.of(compound.getCompound("Controller")).getTag(); + } else { + controllerNbt = compound.getCompound("ControllerData"); + } + user = compound.hasUUID("User") ? compound.getUUID("User") : null; } public ItemStack getController() { - return controller; + return getController(); } public boolean hasUser() { return user != null; } @@ -138,8 +146,8 @@ public class LecternControllerBlockEntity extends SmartBlockEntity { } public void setController(ItemStack newController) { - controller = newController; if (newController != null) { + controllerNbt = newController.getTag(); AllSoundEvents.CONTROLLER_PUT.playOnServer(level, worldPosition); } } @@ -148,7 +156,7 @@ public class LecternControllerBlockEntity extends SmartBlockEntity { ItemStack newController = stack.copy(); stack.setCount(0); if (player.getItemInHand(hand).isEmpty()) { - player.setItemInHand(hand, controller); + player.setItemInHand(hand, createLinkedController()); } else { dropController(state); } @@ -164,10 +172,10 @@ public class LecternControllerBlockEntity extends SmartBlockEntity { double x = worldPosition.getX() + 0.5 + 0.25 * dir.getStepX(); double y = worldPosition.getY() + 1; double z = worldPosition.getZ() + 0.5 + 0.25 * dir.getStepZ(); - ItemEntity itementity = new ItemEntity(level, x, y, z, controller.copy()); + ItemEntity itementity = new ItemEntity(level, x, y, z, createLinkedController()); itementity.setDefaultPickUpDelay(); level.addFreshEntity(itementity); - controller = null; + controllerNbt = new CompoundTag(); } public static boolean playerInRange(Player player, Level world, BlockPos pos) { @@ -176,4 +184,10 @@ public class LecternControllerBlockEntity extends SmartBlockEntity { return player.distanceToSqr(Vec3.atCenterOf(pos)) < reach * reach; } + private ItemStack createLinkedController() { + ItemStack stack = AllItems.LINKED_CONTROLLER.asStack(); + stack.setTag(controllerNbt); + return stack; + } + } diff --git a/src/main/java/com/simibubi/create/content/redstone/nixieTube/NixieTubeRenderer.java b/src/main/java/com/simibubi/create/content/redstone/nixieTube/NixieTubeRenderer.java index 19ca595eb..130097e59 100644 --- a/src/main/java/com/simibubi/create/content/redstone/nixieTube/NixieTubeRenderer.java +++ b/src/main/java/com/simibubi/create/content/redstone/nixieTube/NixieTubeRenderer.java @@ -86,7 +86,7 @@ public class NixieTubeRenderer extends SafeBlockEntityRenderer couple = DyeHelper.DYE_TABLE.get(color); + Couple couple = DyeHelper.getDyeColors(color); int brightColor = couple.getFirst(); int darkColor = couple.getSecond(); int flickeringBrightColor = Color.mixColors(brightColor, darkColor, flicker / 4); diff --git a/src/main/java/com/simibubi/create/content/redstone/smartObserver/SmartObserverBlockEntity.java b/src/main/java/com/simibubi/create/content/redstone/smartObserver/SmartObserverBlockEntity.java index e1c202639..d781ef1f7 100644 --- a/src/main/java/com/simibubi/create/content/redstone/smartObserver/SmartObserverBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/redstone/smartObserver/SmartObserverBlockEntity.java @@ -32,10 +32,10 @@ public class SmartObserverBlockEntity extends SmartBlockEntity { private FilteringBehaviour filtering; private InvManipulationBehaviour observedInventory; private TankManipulationBehaviour observedTank; - + private VersionedInventoryTrackerBehaviour invVersionTracker; private boolean sustainSignal; - + public int turnOffTicks = 0; public SmartObserverBlockEntity(BlockEntityType type, BlockPos pos, BlockState state) { @@ -59,10 +59,10 @@ public class SmartObserverBlockEntity extends SmartBlockEntity { @Override public void tick() { super.tick(); - + if (level.isClientSide()) return; - + BlockState state = getBlockState(); if (turnOffTicks > 0) { turnOffTicks--; diff --git a/src/main/java/com/simibubi/create/content/schematics/SchematicWorld.java b/src/main/java/com/simibubi/create/content/schematics/SchematicWorld.java index cc57999cb..7c8fcc4e4 100644 --- a/src/main/java/com/simibubi/create/content/schematics/SchematicWorld.java +++ b/src/main/java/com/simibubi/create/content/schematics/SchematicWorld.java @@ -10,6 +10,8 @@ import java.util.function.Predicate; import java.util.stream.Stream; import com.simibubi.create.Create; +import com.simibubi.create.foundation.blockEntity.IMultiBlockEntityContainer; +import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; import com.simibubi.create.foundation.utility.BBHelper; import com.simibubi.create.foundation.utility.NBTProcessors; import com.simibubi.create.foundation.utility.worldWrappers.WrappedWorld; @@ -251,5 +253,25 @@ public class SchematicWorld extends WrappedWorld implements ServerLevelAccessor } throw new IllegalStateException("Cannot use IServerWorld#getWorld in a client environment"); } + + public void fixControllerBlockEntities() { + for (BlockEntity blockEntity : blockEntities.values()) { + if (!(blockEntity instanceof IMultiBlockEntityContainer multiBlockEntity)) + continue; + BlockPos lastKnown = multiBlockEntity.getLastKnownPos(); + BlockPos current = blockEntity.getBlockPos(); + if (lastKnown == null || current == null) + continue; + if (multiBlockEntity.isController()) + continue; + if (!lastKnown.equals(current)) { + BlockPos newControllerPos = multiBlockEntity.getController() + .offset(current.subtract(lastKnown)); + if (multiBlockEntity instanceof SmartBlockEntity sbe) + sbe.markVirtual(); + multiBlockEntity.setController(newControllerPos); + } + } + } } diff --git a/src/main/java/com/simibubi/create/content/schematics/cannon/SchematicannonVisual.java b/src/main/java/com/simibubi/create/content/schematics/cannon/SchematicannonVisual.java index be84ea7d9..c71cd5151 100644 --- a/src/main/java/com/simibubi/create/content/schematics/cannon/SchematicannonVisual.java +++ b/src/main/java/com/simibubi/create/content/schematics/cannon/SchematicannonVisual.java @@ -24,8 +24,8 @@ public class SchematicannonVisual extends AbstractBlockEntityVisual waitingTrains; private RailwaySavedData savedData; + + public int version; public GlobalRailwayManager() { cleanUp(); diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/AbstractBogeyBlock.java b/src/main/java/com/simibubi/create/content/trains/bogey/AbstractBogeyBlock.java index 5478264bf..81a34571d 100644 --- a/src/main/java/com/simibubi/create/content/trains/bogey/AbstractBogeyBlock.java +++ b/src/main/java/com/simibubi/create/content/trains/bogey/AbstractBogeyBlock.java @@ -4,18 +4,15 @@ import java.util.ArrayList; import java.util.Collection; import java.util.EnumSet; import java.util.List; -import java.util.Optional; import java.util.Set; import javax.annotation.Nullable; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; -import com.mojang.math.Axis; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBogeyStyles; import com.simibubi.create.AllItems; @@ -33,8 +30,6 @@ import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.RegisteredObjects; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.RenderType; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; @@ -57,8 +52,6 @@ import net.minecraft.world.level.block.state.properties.Property; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.registries.ForgeRegistries; public abstract class AbstractBogeyBlock extends Block implements IBE, ProperWaterloggedBlock, ISpecialBlockItemRequirement, IWrenchable { @@ -66,7 +59,6 @@ public abstract class AbstractBogeyBlock ext static final List BOGEYS = new ArrayList<>(); public BogeySizes.BogeySize size; - public AbstractBogeyBlock(Properties pProperties, BogeySizes.BogeySize size) { super(pProperties); registerDefaultState(defaultBlockState().setValue(WATERLOGGED, false)); @@ -91,7 +83,7 @@ public abstract class AbstractBogeyBlock ext /** * Only for internal Create use. If you have your own style set, do not call this method */ - @Deprecated + @ApiStatus.Internal public static void registerStandardBogey(ResourceLocation block) { BOGEYS.add(block); } @@ -147,30 +139,6 @@ public abstract class AbstractBogeyBlock ext return false; } - @OnlyIn(Dist.CLIENT) - public void render(@Nullable BlockState state, float wheelAngle, PoseStack ms, float partialTicks, - MultiBufferSource buffers, int light, int overlay, BogeyStyle style, CompoundTag bogeyData) { - if (style == null) - style = getDefaultStyle(); - - final Optional commonRenderer - = style.getInWorldCommonRenderInstance(); - final BogeyRenderer renderer = style.getInWorldRenderInstance(this.getSize()); - if (state != null) { - ms.translate(.5f, .5f, .5f); - if (state.getValue(AXIS) == Direction.Axis.X) - ms.mulPose(Axis.YP.rotationDegrees(90)); - } - ms.translate(0, -1.5 - 1 / 128f, 0); - VertexConsumer vb = buffers.getBuffer(RenderType.cutoutMipped()); - if (bogeyData == null) - bogeyData = new CompoundTag(); - renderer.render(bogeyData, wheelAngle, ms, light, vb, state == null); - CompoundTag finalBogeyData = bogeyData; - commonRenderer.ifPresent(common -> - common.render(finalBogeyData, wheelAngle, ms, light, vb, state == null)); - } - public BogeySizes.BogeySize getSize() { return this.size; } @@ -216,9 +184,9 @@ public abstract class AbstractBogeyBlock ext Set validSizes = style.validSizes(); - for (int i = 0; i < BogeySizes.count(); i++) { + for (int i = 0; i < BogeySizes.all().size(); i++) { if (validSizes.contains(size)) break; - size = size.increment(); + size = size.nextBySize(); } sbbe.setBogeyStyle(style); @@ -227,7 +195,7 @@ public abstract class AbstractBogeyBlock ext sbbe.setBogeyData(sbbe.getBogeyData().merge(defaultData)); if (size == getSize()) { - if (state.getBlock() != style.getBlockOfSize(size)) { + if (state.getBlock() != style.getBlockForSize(size)) { CompoundTag oldData = sbbe.getBogeyData(); level.setBlock(pos, copyProperties(state, getStateOfSize(sbbe, size)), Block.UPDATE_ALL); if (!(level.getBlockEntity(pos) instanceof AbstractBogeyBlockEntity bogeyBlockEntity)) @@ -328,7 +296,7 @@ public abstract class AbstractBogeyBlock ext public BlockState getStateOfSize(AbstractBogeyBlockEntity sbbe, BogeySizes.BogeySize size) { BogeyStyle style = sbbe.getStyle(); - BlockState state = style.getBlockOfSize(size).defaultBlockState(); + BlockState state = style.getBlockForSize(size).defaultBlockState(); return copyProperties(sbbe.getBlockState(), state); } diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/AbstractBogeyBlockEntity.java b/src/main/java/com/simibubi/create/content/trains/bogey/AbstractBogeyBlockEntity.java index 59985cc7a..146a04e2e 100644 --- a/src/main/java/com/simibubi/create/content/trains/bogey/AbstractBogeyBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/trains/bogey/AbstractBogeyBlockEntity.java @@ -37,14 +37,14 @@ public abstract class AbstractBogeyBlockEntity extends CachedRenderBBBlockEntity public void setBogeyData(@NotNull CompoundTag newData) { if (!newData.contains(BOGEY_STYLE_KEY)) { - ResourceLocation style = getDefaultStyle().name; + ResourceLocation style = getDefaultStyle().id; NBTHelper.writeResourceLocation(newData, BOGEY_STYLE_KEY, style); } this.bogeyData = newData; } public void setBogeyStyle(@NotNull BogeyStyle style) { - ResourceLocation location = style.name; + ResourceLocation location = style.id; CompoundTag data = this.getBogeyData(); NBTHelper.writeResourceLocation(data, BOGEY_STYLE_KEY, location); markUpdated(); @@ -80,7 +80,7 @@ public abstract class AbstractBogeyBlockEntity extends CachedRenderBBBlockEntity private CompoundTag createBogeyData() { CompoundTag nbt = new CompoundTag(); - NBTHelper.writeResourceLocation(nbt, BOGEY_STYLE_KEY, getDefaultStyle().name); + NBTHelper.writeResourceLocation(nbt, BOGEY_STYLE_KEY, getDefaultStyle().id); boolean upsideDown = false; if (getBlockState().getBlock() instanceof AbstractBogeyBlock bogeyBlock) upsideDown = bogeyBlock.isUpsideDown(getBlockState()); @@ -113,6 +113,6 @@ public abstract class AbstractBogeyBlockEntity extends CachedRenderBBBlockEntity setChanged(); Level level = getLevel(); if (level != null) - getLevel().sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3); + level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3); } } diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/BackupBogeyRenderer.java b/src/main/java/com/simibubi/create/content/trains/bogey/BackupBogeyRenderer.java deleted file mode 100644 index ff93126a9..000000000 --- a/src/main/java/com/simibubi/create/content/trains/bogey/BackupBogeyRenderer.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.simibubi.create.content.trains.bogey; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; -import com.simibubi.create.content.trains.entity.CarriageBogey; - -import dev.engine_room.flywheel.api.visualization.VisualizationContext; -import net.minecraft.nbt.CompoundTag; - -public class BackupBogeyRenderer extends BogeyRenderer.CommonRenderer { - public static BackupBogeyRenderer INSTANCE = new BackupBogeyRenderer(); - - @Override - public void render(CompoundTag bogeyData, float wheelAngle, PoseStack ms, int light, VertexConsumer vb, boolean inContraption) { - - } - - @Override - public void initialiseContraptionModelData(VisualizationContext context, CarriageBogey carriageBogey) { - - } -} diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/BogeyBlockEntityRenderer.java b/src/main/java/com/simibubi/create/content/trains/bogey/BogeyBlockEntityRenderer.java index e570fa26b..cbeaf0659 100644 --- a/src/main/java/com/simibubi/create/content/trains/bogey/BogeyBlockEntityRenderer.java +++ b/src/main/java/com/simibubi/create/content/trains/bogey/BogeyBlockEntityRenderer.java @@ -1,26 +1,32 @@ package com.simibubi.create.content.trains.bogey; import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Axis; import com.simibubi.create.foundation.blockEntity.renderer.SafeBlockEntityRenderer; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; -import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.core.Direction; import net.minecraft.world.level.block.state.BlockState; -public class BogeyBlockEntityRenderer extends SafeBlockEntityRenderer { - - public BogeyBlockEntityRenderer(BlockEntityRendererProvider.Context context) {} +public class BogeyBlockEntityRenderer extends SafeBlockEntityRenderer { + public BogeyBlockEntityRenderer(BlockEntityRendererProvider.Context context) { + } @Override protected void renderSafe(T be, float partialTicks, PoseStack ms, MultiBufferSource buffer, int light, int overlay) { BlockState blockState = be.getBlockState(); - if (be instanceof AbstractBogeyBlockEntity sbbe) { - float angle = sbbe.getVirtualAngle(partialTicks); - if (blockState.getBlock() instanceof AbstractBogeyBlock bogey) - bogey.render(blockState, angle, ms, partialTicks, buffer, light, overlay, sbbe.getStyle(), sbbe.getBogeyData()); + if (!(blockState.getBlock() instanceof AbstractBogeyBlock bogey)) { + return; } - } + float angle = be.getVirtualAngle(partialTicks); + ms.pushPose(); + ms.translate(.5f, .5f, .5f); + if (blockState.getValue(AbstractBogeyBlock.AXIS) == Direction.Axis.X) + ms.mulPose(Axis.YP.rotationDegrees(90)); + be.getStyle().render(bogey.getSize(), partialTicks, ms, buffer, light, overlay, angle, be.getBogeyData(), false); + ms.popPose(); + } } diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/BogeyBlockEntityVisual.java b/src/main/java/com/simibubi/create/content/trains/bogey/BogeyBlockEntityVisual.java new file mode 100644 index 000000000..e3bd7191b --- /dev/null +++ b/src/main/java/com/simibubi/create/content/trains/bogey/BogeyBlockEntityVisual.java @@ -0,0 +1,95 @@ +package com.simibubi.create.content.trains.bogey; + +import java.util.function.Consumer; + +import org.jetbrains.annotations.Nullable; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Axis; +import com.simibubi.create.content.trains.bogey.BogeySizes.BogeySize; + +import dev.engine_room.flywheel.api.instance.Instance; +import dev.engine_room.flywheel.api.visualization.VisualizationContext; +import dev.engine_room.flywheel.lib.visual.AbstractBlockEntityVisual; +import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; + +public class BogeyBlockEntityVisual extends AbstractBlockEntityVisual implements SimpleDynamicVisual { + private final PoseStack poseStack = new PoseStack(); + + @Nullable + private final BogeySize bogeySize; + private BogeyStyle lastStyle; + @Nullable + private BogeyVisual bogey; + + public BogeyBlockEntityVisual(VisualizationContext ctx, AbstractBogeyBlockEntity blockEntity, float partialTick) { + super(ctx, blockEntity, partialTick); + + lastStyle = blockEntity.getStyle(); + + if (!(blockState.getBlock() instanceof AbstractBogeyBlock block)) { + bogeySize = null; + return; + } + + bogeySize = block.getSize(); + + BlockPos visualPos = getVisualPosition(); + poseStack.translate(visualPos.getX(), visualPos.getY(), visualPos.getZ()); + poseStack.translate(.5f, .5f, .5f); + if (blockState.getValue(AbstractBogeyBlock.AXIS) == Direction.Axis.X) + poseStack.mulPose(Axis.YP.rotationDegrees(90)); + poseStack.translate(0, -1.5 - 1 / 128f, 0); + + bogey = lastStyle.createVisual(bogeySize, visualizationContext, partialTick, false); + } + + @Override + public void beginFrame(Context context) { + if (bogeySize == null) { + return; + } + + BogeyStyle style = blockEntity.getStyle(); + if (style != lastStyle) { + if (bogey != null) { + bogey.delete(); + bogey = null; + } + lastStyle = style; + bogey = lastStyle.createVisual(bogeySize, visualizationContext, context.partialTick(), false); + } + + if (bogey == null) { + return; + } + + CompoundTag bogeyData = blockEntity.getBogeyData(); + float angle = blockEntity.getVirtualAngle(context.partialTick()); + bogey.update(bogeyData, angle, poseStack); + } + + @Override + public void collectCrumblingInstances(Consumer<@Nullable Instance> consumer) { + if (bogey != null) { + bogey.collectCrumblingInstances(consumer); + } + } + + @Override + public void updateLight(float partialTick) { + if (bogey != null) { + bogey.updateLight(computePackedLight()); + } + } + + @Override + protected void _delete() { + if (bogey != null) { + bogey.delete(); + } + } +} diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/BogeyRenderer.java b/src/main/java/com/simibubi/create/content/trains/bogey/BogeyRenderer.java index 8c01ad8e5..9afce4cb6 100644 --- a/src/main/java/com/simibubi/create/content/trains/bogey/BogeyRenderer.java +++ b/src/main/java/com/simibubi/create/content/trains/bogey/BogeyRenderer.java @@ -1,399 +1,10 @@ package com.simibubi.create.content.trains.bogey; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.stream.IntStream; - -import org.jetbrains.annotations.Nullable; -import org.joml.Matrix3fc; -import org.joml.Matrix4fc; -import org.joml.Quaternionfc; - import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; -import com.simibubi.create.content.trains.entity.CarriageBogey; -import com.simibubi.create.foundation.render.CachedBufferer; -import com.simibubi.create.foundation.render.SuperByteBuffer; -import com.simibubi.create.foundation.render.VirtualRenderHelper; -import dev.engine_room.flywheel.api.visualization.VisualizationContext; -import dev.engine_room.flywheel.lib.instance.InstanceTypes; -import dev.engine_room.flywheel.lib.instance.TransformedInstance; -import dev.engine_room.flywheel.lib.model.Models; -import dev.engine_room.flywheel.lib.model.baked.PartialModel; -import dev.engine_room.flywheel.lib.transform.Transform; +import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.nbt.CompoundTag; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -/** - * This is a port of the bogey api from Extended Bogeys, If you are looking to implement your own bogeys you can find some helpful resources below: - *

- * - Extended Bogeys (Examples) - * - Extended Bogeys (API documentation) - * - Steam n' Rails (Examples) - */ -public abstract class BogeyRenderer { - Map contraptionModelData = new HashMap<>(); - - /** - * A common interface for getting transform data for both in-world and in-contraption model data safely from a - * partial model - * - * @param model The key for the model data to instantiate or retrieve - * @param ms The posestack used for contraption model data - * @param inInstancedContraption The type of model needed - * @param size The amount of models needed - * @return A generic transform which can be used for both in-world and in-contraption models - */ - public BogeyModelData[] getTransform(PartialModel model, PoseStack ms, boolean inInstancedContraption, int size) { - return (inInstancedContraption) ? transformContraptionModelData(keyFromModel(model), ms) : createModelData(model, size); - } - - /** - * A common interface for getting transform data for both in-world and in-contraption model data safely from a - * blockstate - * - * @param state The key for the model data to instantiate or retrieve - * @param ms The posestack used for contraption model data - * @param inContraption The type of model needed - * @param size The amount of models needed - * @return A generic transform which can be used for both in-world and in-contraption models - */ - public BogeyModelData[] getTransform(BlockState state, PoseStack ms, boolean inContraption, int size) { - return inContraption ? transformContraptionModelData(keyFromModel(state), ms) : createModelData(state, size); - } - - /** - * Helper function to collect or create a single model from a partial model used for both in-world and - * in-contraption rendering - * - * @param model The key of the model to be collected or instantiated - * @param ms Posestack to bind the model to if it is within a contraption - * @param inInstancedContraption Type of rendering required - * @return A generic transform which can be used for both in-world and in-contraption models - */ - public BogeyModelData getTransform(PartialModel model, PoseStack ms, boolean inInstancedContraption) { - return inInstancedContraption ? contraptionModelData.get(keyFromModel(model))[0].setTransform(ms) - : BogeyModelData.from(model); - } - - /** - * A common interface for getting transform data for blockstates, for a single model - * - * @param state The state of the model to be collected or instantiated - * @param ms Posestack to bind the model to if it is within a contraption - * @param inContraption Type of model required - * @return A generic transform which can be used for both in-world and in-contraption models - */ - public BogeyModelData getTransform(BlockState state, PoseStack ms, boolean inContraption) { - return (inContraption) ? contraptionModelData.get(keyFromModel(state))[0].setTransform(ms) - : BogeyModelData.from(state); - } - - /** - * Used for calling both in-world and in-contraption rendering - * - * @param bogeyData Custom data stored on the bogey able to be used for rendering - * @param wheelAngle The angle of the wheel - * @param ms The posestack to render to - * @param light (Optional) Light used for in-world rendering - * @param vb (Optional) Vertex Consumer used for in-world rendering - */ - @OnlyIn(Dist.CLIENT) - public abstract void render(CompoundTag bogeyData, float wheelAngle, PoseStack ms, int light, - VertexConsumer vb, boolean inContraption); - - /** - * Used for calling in-contraption rendering ensuring that falsey data is handled correctly - * - * @param bogeyData Custom data stored on the bogey able to be used for rendering - * @param wheelAngle The angle of the wheel - * @param ms The posestack to render to - */ - @OnlyIn(Dist.CLIENT) - public void render(CompoundTag bogeyData, float wheelAngle, PoseStack ms) { - this.render(bogeyData, wheelAngle, ms, 0, null, true); - } - - public abstract BogeySizes.BogeySize getSize(); - - /** - * Used to collect Contraption Model Data for in-contraption rendering, should not be utilised directly when - * rendering to prevent render type mismatch - * - * @param key The key used to access the model - * @param ms Posestack of the contraption to bind the model data to - * @return A generic transform which can be used for both in-world and in-contraption models - */ - private BogeyModelData[] transformContraptionModelData(String key, PoseStack ms) { - BogeyModelData[] modelData = contraptionModelData.get(key); - Arrays.stream(modelData).forEach(modelDataElement -> modelDataElement.setTransform(ms)); - return modelData; - } - - - /** - * Used for in world rendering, creates a set count of model data to be rendered, allowing for a generic response - * when rendering multiple models both in-world and in-contraption for example, with wheels - * - * @param model The partial model of the model data ot be made - * @param size The Amount of models needed - * @return A generic transform which can be used for both in-world and in-contraption models - */ - private BogeyModelData[] createModelData(PartialModel model, int size) { - BogeyModelData[] data = { BogeyModelData.from(model) }; - return expandArrayToLength(data, size); - } - - /** - * Used for in world rendering, creates a set count of model data to be rendered, allowing for a generic response - * when rendering multiple models both in-world and in-contraption for example, with wheels - * - * @param state The state of the model data to be made - * @param size Amount of models needed - * @return A generic transform which can be used for both in-world and in-contraption models - */ - private BogeyModelData[] createModelData(BlockState state, int size) { - BogeyModelData[] data = { BogeyModelData.from(state) }; - return expandArrayToLength(data, size); - } - - /** - * Utility function to clone in-world models to a set size to allow for common handling of rendering with multiple - * instances of the same model for example with wheels - * - * @param data An in-world model to be replicated - * @param size Amount of models needed - * @return A generic transform which can be used for both in-world and in-contraption models - */ - private BogeyModelData[] expandArrayToLength(BogeyModelData[] data, int size) { - return Arrays.stream(Collections.nCopies(size, data).toArray()) - .flatMap(inner -> Arrays.stream((BogeyModelData[]) inner)) - .toArray(BogeyModelData[]::new); - } - - /** - * Provides render implementations a point in setup to instantiate all model data to be needed - * - * @param context The visualization context - * @param carriageBogey The bogey to create data for - */ - @OnlyIn(Dist.CLIENT) - public abstract void initialiseContraptionModelData(VisualizationContext context, CarriageBogey carriageBogey); - - /** - * Creates instances of models for in-world rendering to a set length from a provided partial model - * - * @param context The visualization context - * @param model Partial model to be instanced - * @param count Amount of models neeeded - */ - public void createModelInstance(VisualizationContext context, PartialModel model, int count) { - var instancer = context.instancerProvider() - .instancer(InstanceTypes.TRANSFORMED, Models.partial(model)); - BogeyModelData[] modelData = IntStream.range(0, count) - .mapToObj(i -> instancer.createInstance()) - .map(BogeyModelData::new) - .toArray(BogeyModelData[]::new); - contraptionModelData.put(keyFromModel(model), modelData); - } - - /** - * Creates instances of models for in-contraption rendering to a set length from a provided blockstate - * - * @param context The visualization context - * @param state Blockstate of the model to be created - * @param count Amount of models needed - */ - public void createModelInstance(VisualizationContext context, BlockState state, int count) { - var instancer = context.instancerProvider() - .instancer(InstanceTypes.TRANSFORMED, VirtualRenderHelper.blockModel(state)); - BogeyModelData[] modelData = IntStream.range(0, count) - .mapToObj(i -> instancer.createInstance()) - .map(BogeyModelData::new) - .toArray(BogeyModelData[]::new); - contraptionModelData.put(keyFromModel(state), modelData); - } - - /** - * Creates a single instance of models for in-contraption rendering from a provided blockstate - * - * @param context The visualization context - * @param states Blockstates of the models to be created - */ - public void createModelInstance(VisualizationContext context, BlockState... states) { - for (BlockState state : states) - this.createModelInstance(context, state, 1); - } - - /** - * Helper function to create a single model instance for in-contraption rendering - * - * @param context The visualization context - * @param models The type of model to create instances of - */ - public void createModelInstance(VisualizationContext context, PartialModel... models) { - for (PartialModel model : models) - createModelInstance(context, model, 1); - } - - /** - * This method is deprecated, use BogeyModelData#render instead, left in - * to avoid existing usages from crashing - * - * @param b The model data itself - * @param ms Pose stack to render to - * @param light light level of the scene - * @param vb Vertex Consumber to render to - * @param Generic alias for both contraption and in-world model data - */ - - @Deprecated - public static > void finalize(B b, PoseStack ms, int light, @Nullable VertexConsumer vb) { - b.scale(1 - 1/512f); - if (b instanceof SuperByteBuffer byteBuf && vb != null) - byteBuf.light(light).renderInto(ms, vb); - } - - /** - * Automatic handling for setting empty transforms for all model data - * - */ - - public void emptyTransforms() { - for (BogeyModelData[] data : contraptionModelData.values()) - for (BogeyModelData model : data) - model.setEmptyTransform(); - } - - /** - * Automatic handling for updating all model data's light - * - * @param blockLight the blocklight to be applied - * @param skyLight the skylight to be applied - */ - - public void updateLight(int blockLight, int skyLight) { - for (BogeyModelData[] data : contraptionModelData.values()) - for (BogeyModelData model : data) - model.updateLight(blockLight, skyLight); - } - - /** - * Automatic handling for clearing all model data of a contraption - * - */ - - public void remove() { - for (BogeyModelData[] data : contraptionModelData.values()) - for (BogeyModelData model : data) - model.delete(); - contraptionModelData.clear(); - } - - /** - * Create a model key from a partial model, so it can be easily accessed - * - * @param partialModel the model we want a unique key for - * @return Key of the model - */ - - private String keyFromModel(PartialModel partialModel) { - return partialModel.modelLocation().toString(); - } - - /** - * Create a model key from a blockstate, so it can be easily accessed - * - * @param state Blockstate of the model - * @return Key of the model - */ - - private String keyFromModel(BlockState state) { - return state.toString(); - } - - public static abstract class CommonRenderer extends BogeyRenderer { - @Override - public BogeySizes.BogeySize getSize() { - return null; - } - } - - public record BogeyModelData(Transform transform) implements Transform { - public static BogeyModelData from(PartialModel model) { - BlockState air = Blocks.AIR.defaultBlockState(); - return new BogeyModelData(CachedBufferer.partial(model, air)); - } - public static BogeyModelData from(BlockState model) { - return new BogeyModelData(CachedBufferer.block(model)); - } - public void render(PoseStack ms, int light, @Nullable VertexConsumer vb) { - transform.scale(1 - 1/512f); - if (transform instanceof SuperByteBuffer byteBuf && vb != null) - byteBuf.light(light).renderInto(ms, vb); - } - - public BogeyModelData setTransform(PoseStack ms) { - if (this.transform instanceof TransformedInstance model) - model.setTransform(ms) - .setChanged(); - return this; - } - - public BogeyModelData setEmptyTransform() { - if (this.transform instanceof TransformedInstance model) - model.setZeroTransform() - .setChanged(); - return this; - } - - public BogeyModelData delete() { - if (this.transform instanceof TransformedInstance model) - model.delete(); - return this; - } - - public BogeyModelData updateLight(int blockLight, int skyLight) { - if (this.transform instanceof TransformedInstance model) - model.light(blockLight, skyLight) - .setChanged(); - return this; - } - - @Override - public BogeyModelData mulPose(Matrix4fc pose) { - this.transform.mulPose(pose); - return this; - } - - @Override - public BogeyModelData mulNormal(Matrix3fc normal) { - this.transform.mulNormal(normal); - return this; - } - - @Override - public BogeyModelData rotate(Quaternionfc quaternion) { - this.transform.rotate(quaternion); - return this; - } - - @Override - public BogeyModelData scale(float factorX, float factorY, float factorZ) { - this.transform.scale(factorX, factorY, factorZ); - return this; - } - - @Override - public BogeyModelData translate(float x, float y, float z) { - this.transform.translate(x, y, z); - return this; - } - } +public interface BogeyRenderer { + void render(CompoundTag bogeyData, float wheelAngle, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight, int packedOverlay, boolean inContraption); } diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/BogeySizes.java b/src/main/java/com/simibubi/create/content/trains/bogey/BogeySizes.java index e9bcc2d48..879aec548 100644 --- a/src/main/java/com/simibubi/create/content/trains/bogey/BogeySizes.java +++ b/src/main/java/com/simibubi/create/content/trains/bogey/BogeySizes.java @@ -1,70 +1,78 @@ package com.simibubi.create.content.trains.bogey; -import java.util.Collection; +import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; -import java.util.HashSet; +import java.util.HashMap; import java.util.List; -import java.util.stream.Collectors; +import java.util.Map; + +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.UnmodifiableView; import com.simibubi.create.Create; import net.minecraft.resources.ResourceLocation; -public class BogeySizes { - private static final Collection BOGEY_SIZES = new HashSet<>(); - public static final BogeySize SMALL = new BogeySize(Create.ID, "small", 6.5f / 16f); - public static final BogeySize LARGE = new BogeySize(Create.ID, "large", 12.5f / 16f); +public final class BogeySizes { + private static final Map BOGEY_SIZES = new HashMap<>(); + private static final List SORTED_INCREASING = new ArrayList<>(); + private static final List SORTED_DECREASING = new ArrayList<>(); + @UnmodifiableView + private static final Map BOGEY_SIZES_VIEW = Collections.unmodifiableMap(BOGEY_SIZES); + @UnmodifiableView + private static final List SORTED_INCREASING_VIEW = Collections.unmodifiableList(SORTED_INCREASING); + @UnmodifiableView + private static final List SORTED_DECREASING_VIEW = Collections.unmodifiableList(SORTED_DECREASING); + + public static final BogeySize SMALL = new BogeySize(Create.asResource("small"), 6.5f / 16f); + public static final BogeySize LARGE = new BogeySize(Create.asResource("large"), 12.5f / 16f); static { - BOGEY_SIZES.add(SMALL); - BOGEY_SIZES.add(LARGE); + register(SMALL); + register(LARGE); } - public static BogeySize addSize(String modId, String name, float size) { - ResourceLocation location = new ResourceLocation(modId, name); - return addSize(location, size); + private BogeySizes() { } - public static BogeySize addSize(ResourceLocation location, float size) { - BogeySize customSize = new BogeySize(location, size); - BOGEY_SIZES.add(customSize); - return customSize; - } - - public static List getAllSizesSmallToLarge() { - return BOGEY_SIZES.stream() - .sorted(Comparator.comparing(BogeySize::wheelRadius)) - .collect(Collectors.toList()); - } - - public static List getAllSizesLargeToSmall() { - List sizes = getAllSizesSmallToLarge(); - Collections.reverse(sizes); - return sizes; - } - - public static int count() { - return BOGEY_SIZES.size(); - } - - public record BogeySize(ResourceLocation location, float wheelRadius) { - public BogeySize(String modId, String name, float wheelRadius) { - this(new ResourceLocation(modId, name), wheelRadius); + public static void register(BogeySize size) { + ResourceLocation id = size.id(); + if (BOGEY_SIZES.containsKey(id)) { + throw new IllegalArgumentException(); } + BOGEY_SIZES.put(id, size); - public BogeySize increment() { - List values = getAllSizesSmallToLarge(); + SORTED_INCREASING.add(size); + SORTED_DECREASING.add(size); + SORTED_INCREASING.sort(Comparator.comparing(BogeySize::wheelRadius)); + SORTED_DECREASING.sort(Comparator.comparing(BogeySize::wheelRadius).reversed()); + } + + @UnmodifiableView + public static Map all() { + return BOGEY_SIZES_VIEW; + } + + @UnmodifiableView + public static List allSortedIncreasing() { + return SORTED_INCREASING_VIEW; + } + + @UnmodifiableView + public static List allSortedDecreasing() { + return SORTED_DECREASING_VIEW; + } + + @ApiStatus.Internal + public static void init() { + } + + public record BogeySize(ResourceLocation id, float wheelRadius) { + public BogeySize nextBySize() { + List values = allSortedIncreasing(); int ordinal = values.indexOf(this); return values.get((ordinal + 1) % values.size()); } - - public boolean is(BogeySize size) { - return size.location == this.location; - } - } - - public static void init() { - } } diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/BogeyStyle.java b/src/main/java/com/simibubi/create/content/trains/bogey/BogeyStyle.java index 1d7e355dc..d7ece27df 100644 --- a/src/main/java/com/simibubi/create/content/trains/bogey/BogeyStyle.java +++ b/src/main/java/com/simibubi/create/content/trains/bogey/BogeyStyle.java @@ -2,60 +2,52 @@ package com.simibubi.create.content.trains.bogey; import java.util.HashMap; import java.util.Map; -import java.util.Optional; import java.util.Set; import java.util.function.Supplier; import java.util.stream.Stream; -import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import com.mojang.blaze3d.vertex.PoseStack; import com.simibubi.create.AllBogeyStyles; import com.simibubi.create.AllSoundEvents; -import com.simibubi.create.content.trains.bogey.BogeyRenderer.CommonRenderer; -import com.simibubi.create.content.trains.entity.CarriageBogey; +import com.simibubi.create.content.trains.bogey.BogeySizes.BogeySize; +import com.simibubi.create.foundation.utility.Lang; import dev.engine_room.flywheel.api.visualization.VisualizationContext; +import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvent; -import net.minecraft.world.level.block.Block; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.registries.ForgeRegistries; - public class BogeyStyle { - - public final ResourceLocation name; + public final ResourceLocation id; public final ResourceLocation cycleGroup; public final Component displayName; - public final ResourceLocation soundType; + public final Supplier soundEvent; public final ParticleOptions contactParticle; public final ParticleOptions smokeParticle; public final CompoundTag defaultData; - - private Optional> commonRendererFactory; - private Map sizes; + private final Map>> sizes; @OnlyIn(Dist.CLIENT) - private Map sizeRenderers; + private Map sizeRenderers; - @OnlyIn(Dist.CLIENT) - private Optional commonRenderer; + public BogeyStyle(ResourceLocation id, ResourceLocation cycleGroup, Component displayName, + Supplier soundEvent, ParticleOptions contactParticle, ParticleOptions smokeParticle, + CompoundTag defaultData, Map>> sizes, + Map> sizeRenderers) { - public BogeyStyle(ResourceLocation name, ResourceLocation cycleGroup, Component displayName, - ResourceLocation soundType, ParticleOptions contactParticle, ParticleOptions smokeParticle, - CompoundTag defaultData, Map sizes, - Map> sizeRenderers, - Optional> commonRenderer) { - - this.name = name; + this.id = id; this.cycleGroup = cycleGroup; this.displayName = displayName; - this.soundType = soundType; + this.soundEvent = soundEvent; this.contactParticle = contactParticle; this.smokeParticle = smokeParticle; this.defaultData = defaultData; @@ -64,9 +56,6 @@ public class BogeyStyle { DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> { this.sizeRenderers = new HashMap<>(); sizeRenderers.forEach((k, v) -> this.sizeRenderers.put(k, v.get())); - - this.commonRendererFactory = commonRenderer; - this.commonRenderer = commonRenderer.map(Supplier::get); }); } @@ -74,60 +63,109 @@ public class BogeyStyle { return AllBogeyStyles.getCycleGroup(cycleGroup); } - public Block getNextBlock(BogeySizes.BogeySize currentSize) { - return Stream.iterate(currentSize.increment(), BogeySizes.BogeySize::increment) - .filter(sizes::containsKey) - .findFirst() - .map(this::getBlockOfSize) - .orElse(getBlockOfSize(currentSize)); - } - - public Block getBlockOfSize(BogeySizes.BogeySize size) { - return ForgeRegistries.BLOCKS.getValue(sizes.get(size)); - } - public Set validSizes() { return sizes.keySet(); } - @NotNull - public SoundEvent getSoundType() { - AllSoundEvents.SoundEntry entry = AllSoundEvents.ALL.get(this.soundType); - if (entry == null || entry.getMainEvent() == null) entry = AllSoundEvents.TRAIN2; - return entry.getMainEvent(); + public AbstractBogeyBlock getBlockForSize(BogeySizes.BogeySize size) { + return sizes.get(size).get(); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public AbstractBogeyBlock getNextBlock(BogeySizes.BogeySize currentSize) { + return Stream.iterate(currentSize.nextBySize(), BogeySizes.BogeySize::nextBySize) + .filter(sizes::containsKey) + .findFirst() + .map(this::getBlockForSize) + .orElse((AbstractBogeyBlock) getBlockForSize(currentSize)); } @OnlyIn(Dist.CLIENT) - public BogeyRenderer createRendererInstance(BogeySizes.BogeySize size) { - return this.sizeRenderers.get(size).createRenderInstance(); + public void render(BogeySize size, float partialTick, PoseStack poseStack, MultiBufferSource buffers, int light, int overlay, float wheelAngle, @Nullable CompoundTag bogeyData, boolean inContraption) { + if (bogeyData == null) + bogeyData = new CompoundTag(); + + poseStack.translate(0, -1.5 - 1 / 128f, 0); + + SizeRenderer renderer = sizeRenderers.get(size); + if (renderer != null) { + renderer.renderer.render(bogeyData, wheelAngle, partialTick, poseStack, buffers, light, overlay, inContraption); + } } @OnlyIn(Dist.CLIENT) - public BogeyRenderer getInWorldRenderInstance(BogeySizes.BogeySize size) { - SizeRenderData sizeData = this.sizeRenderers.get(size); - return sizeData != null ? sizeData.getInWorldInstance() : BackupBogeyRenderer.INSTANCE; - } - - public Optional getInWorldCommonRenderInstance() { - return this.commonRenderer; - } - - public Optional getNewCommonRenderInstance() { - return this.commonRendererFactory.map(Supplier::get); - } - - public BogeyVisual createVisual(CarriageBogey bogey, BogeySizes.BogeySize size, VisualizationContext context) { - return new BogeyVisual(bogey, this, size, context); + @Nullable + public BogeyVisual createVisual(BogeySize size, VisualizationContext ctx, float partialTick, boolean inContraption) { + SizeRenderer renderer = sizeRenderers.get(size); + if (renderer != null) { + return renderer.visualizer.createVisual(ctx, partialTick, inContraption); + } + return null; } @OnlyIn(Dist.CLIENT) - public record SizeRenderData(Supplier rendererFactory, BogeyRenderer instance) { - public BogeyRenderer createRenderInstance() { - return rendererFactory.get(); + public record SizeRenderer(BogeyRenderer renderer, BogeyVisualizer visualizer) { + } + + public static class Builder { + protected final ResourceLocation id; + protected final ResourceLocation cycleGroup; + protected final Map>> sizes = new HashMap<>(); + + protected Component displayName = Lang.translateDirect("bogey.style.invalid"); + protected Supplier soundEvent = AllSoundEvents.TRAIN2::getMainEvent; + protected ParticleOptions contactParticle = ParticleTypes.CRIT; + protected ParticleOptions smokeParticle = ParticleTypes.POOF; + protected CompoundTag defaultData = new CompoundTag(); + + protected final Map> sizeRenderers = new HashMap<>(); + + public Builder(ResourceLocation id, ResourceLocation cycleGroup) { + this.id = id; + this.cycleGroup = cycleGroup; } - public BogeyRenderer getInWorldInstance() { - return instance; + public Builder displayName(Component displayName) { + this.displayName = displayName; + return this; + } + + public Builder soundEvent(Supplier soundEvent) { + this.soundEvent = soundEvent; + return this; + } + + public Builder contactParticle(ParticleOptions contactParticle) { + this.contactParticle = contactParticle; + return this; + } + + public Builder smokeParticle(ParticleOptions smokeParticle) { + this.smokeParticle = smokeParticle; + return this; + } + + public Builder defaultData(CompoundTag defaultData) { + this.defaultData = defaultData; + return this; + } + + public Builder size(BogeySizes.BogeySize size, Supplier> block, + Supplier renderer) { + this.sizes.put(size, block); + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> { + this.sizeRenderers.put(size, renderer); + }); + return this; + } + + public BogeyStyle build() { + BogeyStyle entry = new BogeyStyle(id, cycleGroup, displayName, soundEvent, contactParticle, smokeParticle, + defaultData, sizes, sizeRenderers); + AllBogeyStyles.BOGEY_STYLES.put(id, entry); + AllBogeyStyles.CYCLE_GROUPS.computeIfAbsent(cycleGroup, l -> new HashMap<>()) + .put(id, entry); + return entry; } } } diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/BogeyVisual.java b/src/main/java/com/simibubi/create/content/trains/bogey/BogeyVisual.java index 9849caada..a003116cc 100644 --- a/src/main/java/com/simibubi/create/content/trains/bogey/BogeyVisual.java +++ b/src/main/java/com/simibubi/create/content/trains/bogey/BogeyVisual.java @@ -1,65 +1,22 @@ package com.simibubi.create.content.trains.bogey; -import java.util.Optional; +import java.util.function.Consumer; + +import org.jetbrains.annotations.Nullable; import com.mojang.blaze3d.vertex.PoseStack; -import com.simibubi.create.content.trains.entity.CarriageBogey; -import com.simibubi.create.content.trains.entity.CarriageContraptionEntity; -import com.simibubi.create.foundation.utility.AnimationTickHolder; -import dev.engine_room.flywheel.api.visualization.VisualizationContext; -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.LightLayer; -import net.minecraft.world.phys.Vec3; +import dev.engine_room.flywheel.api.instance.Instance; +import net.minecraft.nbt.CompoundTag; -public final class BogeyVisual { - private final BogeySizes.BogeySize size; - private final BogeyStyle style; +public interface BogeyVisual { + void update(CompoundTag bogeyData, float wheelAngle, PoseStack poseStack); - public final CarriageBogey bogey; - public final BogeyRenderer renderer; - public final Optional commonRenderer; + void hide(); - public BogeyVisual(CarriageBogey bogey, BogeyStyle style, BogeySizes.BogeySize size, - VisualizationContext context) { - this.bogey = bogey; - this.size = size; - this.style = style; + void updateLight(int packedLight); - this.renderer = this.style.createRendererInstance(this.size); - this.commonRenderer = this.style.getNewCommonRenderInstance(); + void collectCrumblingInstances(Consumer<@Nullable Instance> consumer); - commonRenderer.ifPresent(bogeyRenderer -> bogeyRenderer.initialiseContraptionModelData(context, bogey)); - renderer.initialiseContraptionModelData(context, bogey); - } - - public void beginFrame(float wheelAngle, PoseStack ms) { - if (ms == null) { - renderer.emptyTransforms(); - return; - } - - commonRenderer.ifPresent(bogeyRenderer -> bogeyRenderer.render(bogey.bogeyData, wheelAngle, ms)); - renderer.render(bogey.bogeyData, wheelAngle, ms); - } - - public void updateLight(BlockAndTintGetter world, CarriageContraptionEntity entity) { - var lightPos = BlockPos.containing(getLightPos(entity)); - commonRenderer - .ifPresent(bogeyRenderer -> bogeyRenderer.updateLight(world.getBrightness(LightLayer.BLOCK, lightPos), - world.getBrightness(LightLayer.SKY, lightPos))); - renderer.updateLight(world.getBrightness(LightLayer.BLOCK, lightPos), - world.getBrightness(LightLayer.SKY, lightPos)); - } - - private Vec3 getLightPos(CarriageContraptionEntity entity) { - return bogey.getAnchorPosition() != null ? bogey.getAnchorPosition() - : entity.getLightProbePosition(AnimationTickHolder.getPartialTicks()); - } - - @FunctionalInterface - interface BogeyVisualFactory { - BogeyVisual create(CarriageBogey bogey, BogeySizes.BogeySize size, VisualizationContext context); - } + void delete(); } diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/BogeyVisualizer.java b/src/main/java/com/simibubi/create/content/trains/bogey/BogeyVisualizer.java new file mode 100644 index 000000000..08570e0a2 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/trains/bogey/BogeyVisualizer.java @@ -0,0 +1,8 @@ +package com.simibubi.create.content.trains.bogey; + +import dev.engine_room.flywheel.api.visualization.VisualizationContext; + +@FunctionalInterface +public interface BogeyVisualizer { + BogeyVisual createVisual(VisualizationContext ctx, float partialTick, boolean inContraption); +} diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/StandardBogeyRenderer.java b/src/main/java/com/simibubi/create/content/trains/bogey/StandardBogeyRenderer.java index d7e3e835d..ec1cabbac 100644 --- a/src/main/java/com/simibubi/create/content/trains/bogey/StandardBogeyRenderer.java +++ b/src/main/java/com/simibubi/create/content/trains/bogey/StandardBogeyRenderer.java @@ -1,134 +1,109 @@ package com.simibubi.create.content.trains.bogey; -import static com.simibubi.create.AllPartialModels.BOGEY_DRIVE; -import static com.simibubi.create.AllPartialModels.BOGEY_FRAME; -import static com.simibubi.create.AllPartialModels.BOGEY_PIN; -import static com.simibubi.create.AllPartialModels.BOGEY_PISTON; -import static com.simibubi.create.AllPartialModels.LARGE_BOGEY_WHEELS; -import static com.simibubi.create.AllPartialModels.SMALL_BOGEY_WHEELS; - import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllPartialModels; import com.simibubi.create.content.kinetics.simpleRelays.ShaftBlock; -import com.simibubi.create.content.trains.entity.CarriageBogey; +import com.simibubi.create.foundation.render.CachedBufferer; +import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.Iterate; -import dev.engine_room.flywheel.api.visualization.VisualizationContext; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.block.Blocks; -public class StandardBogeyRenderer { - public static class CommonStandardBogeyRenderer extends BogeyRenderer.CommonRenderer { - @Override - public void initialiseContraptionModelData(VisualizationContext context, CarriageBogey carriageBogey) { - createModelInstance(context, AllBlocks.SHAFT.getDefaultState() - .setValue(ShaftBlock.AXIS, Direction.Axis.Z), 2); - } +public class StandardBogeyRenderer implements BogeyRenderer { + @Override + public void render(CompoundTag bogeyData, float wheelAngle, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, int light, int overlay, boolean inContraption) { + VertexConsumer buffer = bufferSource.getBuffer(RenderType.cutoutMipped()); - @Override - public void render(CompoundTag bogeyData, float wheelAngle, PoseStack ms, int light, VertexConsumer vb, boolean inContraption) { - boolean inInstancedContraption = vb == null; - BogeyModelData[] shafts = getTransform(AllBlocks.SHAFT.getDefaultState() - .setValue(ShaftBlock.AXIS, Direction.Axis.Z), ms, inInstancedContraption, 2); - for (int i : Iterate.zeroAndOne) { - shafts[i].translate(-.5f, .25f, i * -1) - .center() - .rotateZDegrees(wheelAngle) - .uncenter() - .render(ms, light, vb); - } + SuperByteBuffer shaft = CachedBufferer.block(AllBlocks.SHAFT.getDefaultState() + .setValue(ShaftBlock.AXIS, Direction.Axis.Z)); + for (int i : Iterate.zeroAndOne) { + shaft.translate(-.5f, .25f, i * -1) + .center() + .rotateZDegrees(wheelAngle) + .uncenter() + .light(light) + .overlay(overlay) + .renderInto(poseStack, buffer); } } - - public static class SmallStandardBogeyRenderer extends BogeyRenderer { + public static class Small extends StandardBogeyRenderer { @Override - public void initialiseContraptionModelData(VisualizationContext context, CarriageBogey carriageBogey) { - createModelInstance(context, SMALL_BOGEY_WHEELS, 2); - createModelInstance(context, BOGEY_FRAME); - } + public void render(CompoundTag bogeyData, float wheelAngle, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, int light, int overlay, boolean inContraption) { + super.render(bogeyData, wheelAngle, partialTick, poseStack, bufferSource, light, overlay, inContraption); + VertexConsumer buffer = bufferSource.getBuffer(RenderType.cutoutMipped()); - @Override - public BogeySizes.BogeySize getSize() { - return BogeySizes.SMALL; - } + CachedBufferer.partial(AllPartialModels.BOGEY_FRAME, Blocks.AIR.defaultBlockState()) + .scale(1 - 1 / 512f) + .light(light) + .overlay(overlay) + .renderInto(poseStack, buffer); - @Override - public void render(CompoundTag bogeyData, float wheelAngle, PoseStack ms, int light, VertexConsumer vb, boolean inContraption) { - boolean inInstancedContraption = vb == null; - getTransform(BOGEY_FRAME, ms, inInstancedContraption) - .render(ms, light, vb); - - BogeyModelData[] wheels = getTransform(SMALL_BOGEY_WHEELS, ms, inInstancedContraption, 2); + SuperByteBuffer wheels = CachedBufferer.partial(AllPartialModels.SMALL_BOGEY_WHEELS, Blocks.AIR.defaultBlockState()); for (int side : Iterate.positiveAndNegative) { - if (!inInstancedContraption) - ms.pushPose(); - wheels[(side + 1)/2] - .translate(0, 12 / 16f, side) + wheels.translate(0, 12 / 16f, side) .rotateXDegrees(wheelAngle) - .render(ms, light, vb); - if (!inInstancedContraption) - ms.popPose(); + .light(light) + .overlay(overlay) + .renderInto(poseStack, buffer); } } } - public static class LargeStandardBogeyRenderer extends BogeyRenderer { + public static class Large extends StandardBogeyRenderer { @Override - public void initialiseContraptionModelData(VisualizationContext context, CarriageBogey carriageBogey) { - createModelInstance(context, LARGE_BOGEY_WHEELS, BOGEY_DRIVE, BOGEY_PISTON, BOGEY_PIN); - createModelInstance(context, AllBlocks.SHAFT.getDefaultState() - .setValue(ShaftBlock.AXIS, Direction.Axis.X), 2); - } + public void render(CompoundTag bogeyData, float wheelAngle, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, int light, int overlay, boolean inContraption) { + super.render(bogeyData, wheelAngle, partialTick, poseStack, bufferSource, light, overlay, inContraption); - @Override - public BogeySizes.BogeySize getSize() { - return BogeySizes.LARGE; - } - - @Override - public void render(CompoundTag bogeyData, float wheelAngle, PoseStack ms, int light, VertexConsumer vb, boolean inContraption) { - boolean inInstancedContraption = vb == null; - - BogeyModelData[] secondaryShafts = getTransform(AllBlocks.SHAFT.getDefaultState() - .setValue(ShaftBlock.AXIS, Direction.Axis.X), ms, inInstancedContraption, 2); + VertexConsumer buffer = bufferSource.getBuffer(RenderType.cutoutMipped()); + SuperByteBuffer secondaryShaft = CachedBufferer.block(AllBlocks.SHAFT.getDefaultState() + .setValue(ShaftBlock.AXIS, Direction.Axis.X)); for (int i : Iterate.zeroAndOne) { - secondaryShafts[i] - .translate(-.5f, .25f, .5f + i * -2) + secondaryShaft.translate(-.5f, .25f, .5f + i * -2) .center() .rotateXDegrees(wheelAngle) .uncenter() - .render(ms, light, vb); + .light(light) + .overlay(overlay) + .renderInto(poseStack, buffer); } - getTransform(BOGEY_DRIVE, ms, inInstancedContraption) - .render(ms, light, vb); + CachedBufferer.partial(AllPartialModels.BOGEY_DRIVE, Blocks.AIR.defaultBlockState()) + .scale(1 - 1 / 512f) + .light(light) + .overlay(overlay) + .renderInto(poseStack, buffer); - getTransform(BOGEY_PISTON, ms, inInstancedContraption) + CachedBufferer.partial(AllPartialModels.BOGEY_PISTON, Blocks.AIR.defaultBlockState()) .translate(0, 0, 1 / 4f * Math.sin(AngleHelper.rad(wheelAngle))) - .render(ms, light, vb); + .light(light) + .overlay(overlay) + .renderInto(poseStack, buffer); - if (!inInstancedContraption) - ms.pushPose(); - - getTransform(LARGE_BOGEY_WHEELS, ms, inInstancedContraption) + CachedBufferer.partial(AllPartialModels.LARGE_BOGEY_WHEELS, Blocks.AIR.defaultBlockState()) .translate(0, 1, 0) .rotateXDegrees(wheelAngle) - .render(ms, light, vb); + .light(light) + .overlay(overlay) + .renderInto(poseStack, buffer); - getTransform(BOGEY_PIN, ms, inInstancedContraption) + CachedBufferer.partial(AllPartialModels.BOGEY_PIN, Blocks.AIR.defaultBlockState()) .translate(0, 1, 0) .rotateXDegrees(wheelAngle) .translate(0, 1 / 4f, 0) .rotateXDegrees(-wheelAngle) - .render(ms, light, vb); - - if (!inInstancedContraption) - ms.popPose(); + .light(light) + .overlay(overlay) + .renderInto(poseStack, buffer); } } } diff --git a/src/main/java/com/simibubi/create/content/trains/bogey/StandardBogeyVisual.java b/src/main/java/com/simibubi/create/content/trains/bogey/StandardBogeyVisual.java new file mode 100644 index 000000000..0bb70cd1d --- /dev/null +++ b/src/main/java/com/simibubi/create/content/trains/bogey/StandardBogeyVisual.java @@ -0,0 +1,245 @@ +package com.simibubi.create.content.trains.bogey; + +import java.util.function.Consumer; + +import org.jetbrains.annotations.Nullable; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllPartialModels; +import com.simibubi.create.content.kinetics.simpleRelays.ShaftBlock; +import com.simibubi.create.foundation.render.VirtualRenderHelper; +import com.simibubi.create.foundation.utility.AngleHelper; + +import dev.engine_room.flywheel.api.instance.Instance; +import dev.engine_room.flywheel.api.visualization.VisualizationContext; +import dev.engine_room.flywheel.lib.instance.InstanceTypes; +import dev.engine_room.flywheel.lib.instance.TransformedInstance; +import dev.engine_room.flywheel.lib.model.Models; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; + +public class StandardBogeyVisual implements BogeyVisual { + private final TransformedInstance shaft1; + private final TransformedInstance shaft2; + + public StandardBogeyVisual(VisualizationContext ctx, float partialTick, boolean inContraption) { + var shaftInstancer = ctx.instancerProvider() + .instancer(InstanceTypes.TRANSFORMED, VirtualRenderHelper.blockModel(AllBlocks.SHAFT.getDefaultState() + .setValue(ShaftBlock.AXIS, Direction.Axis.Z))); + shaft1 = shaftInstancer.createInstance(); + shaft2 = shaftInstancer.createInstance(); + } + + @Override + public void update(CompoundTag bogeyData, float wheelAngle, PoseStack poseStack) { + shaft1.setTransform(poseStack) + .translate(-.5f, .25f, 0) + .center() + .rotateZDegrees(wheelAngle) + .uncenter() + .setChanged(); + shaft2.setTransform(poseStack) + .translate(-.5f, .25f, -1) + .center() + .rotateZDegrees(wheelAngle) + .uncenter() + .setChanged(); + } + + @Override + public void hide() { + shaft1.setZeroTransform().setChanged(); + shaft2.setZeroTransform().setChanged(); + } + + @Override + public void updateLight(int packedLight) { + shaft1.light(packedLight).setChanged(); + shaft2.light(packedLight).setChanged(); + } + + @Override + public void collectCrumblingInstances(Consumer<@Nullable Instance> consumer) { + consumer.accept(shaft1); + consumer.accept(shaft2); + } + + @Override + public void delete() { + shaft1.delete(); + shaft2.delete(); + } + + public static class Small extends StandardBogeyVisual { + private final TransformedInstance frame; + private final TransformedInstance wheel1; + private final TransformedInstance wheel2; + + public Small(VisualizationContext ctx, float partialTick, boolean inContraption) { + super(ctx, partialTick, inContraption); + var wheelInstancer = ctx.instancerProvider() + .instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.SMALL_BOGEY_WHEELS)); + frame = ctx.instancerProvider() + .instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.BOGEY_FRAME)) + .createInstance(); + wheel1 = wheelInstancer.createInstance(); + wheel2 = wheelInstancer.createInstance(); + } + + @Override + public void update(CompoundTag bogeyData, float wheelAngle, PoseStack poseStack) { + super.update(bogeyData, wheelAngle, poseStack); + wheel1.setTransform(poseStack) + .translate(0, 12 / 16f, -1) + .rotateXDegrees(wheelAngle) + .setChanged(); + wheel2.setTransform(poseStack) + .translate(0, 12 / 16f, 1) + .rotateXDegrees(wheelAngle) + .setChanged(); + frame.setTransform(poseStack) + .scale(1 - 1 / 512f) + .setChanged(); + } + + @Override + public void hide() { + super.hide(); + frame.setZeroTransform().setChanged(); + wheel1.setZeroTransform().setChanged(); + wheel2.setZeroTransform().setChanged(); + } + + @Override + public void updateLight(int packedLight) { + super.updateLight(packedLight); + frame.light(packedLight).setChanged(); + wheel1.light(packedLight).setChanged(); + wheel2.light(packedLight).setChanged(); + } + + @Override + public void collectCrumblingInstances(Consumer<@Nullable Instance> consumer) { + super.collectCrumblingInstances(consumer); + consumer.accept(frame); + consumer.accept(wheel1); + consumer.accept(wheel2); + } + + @Override + public void delete() { + super.delete(); + frame.delete(); + wheel1.delete(); + wheel2.delete(); + } + } + + public static class Large extends StandardBogeyVisual { + private final TransformedInstance secondaryShaft1; + private final TransformedInstance secondaryShaft2; + private final TransformedInstance drive; + private final TransformedInstance piston; + private final TransformedInstance wheels; + private final TransformedInstance pin; + + public Large(VisualizationContext ctx, float partialTick, boolean inContraption) { + super(ctx, partialTick, inContraption); + var secondaryShaftInstancer = ctx.instancerProvider() + .instancer(InstanceTypes.TRANSFORMED, VirtualRenderHelper.blockModel(AllBlocks.SHAFT.getDefaultState() + .setValue(ShaftBlock.AXIS, Direction.Axis.X))); + secondaryShaft1 = secondaryShaftInstancer.createInstance(); + secondaryShaft2 = secondaryShaftInstancer.createInstance(); + drive = ctx.instancerProvider() + .instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.BOGEY_DRIVE)) + .createInstance(); + piston = ctx.instancerProvider() + .instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.BOGEY_PISTON)) + .createInstance(); + wheels = ctx.instancerProvider() + .instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.LARGE_BOGEY_WHEELS)) + .createInstance(); + pin = ctx.instancerProvider() + .instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.BOGEY_PIN)) + .createInstance(); + } + + @Override + public void update(CompoundTag bogeyData, float wheelAngle, PoseStack poseStack) { + super.update(bogeyData, wheelAngle, poseStack); + secondaryShaft1.setTransform(poseStack) + .translate(-.5f, .25f, .5f) + .center() + .rotateXDegrees(wheelAngle) + .uncenter() + .setChanged(); + secondaryShaft2.setTransform(poseStack) + .translate(-.5f, .25f, -1.5f) + .center() + .rotateXDegrees(wheelAngle) + .uncenter() + .setChanged(); + drive.setTransform(poseStack) + .scale(1 - 1/512f) + .setChanged(); + piston.setTransform(poseStack) + .translate(0, 0, 1 / 4f * Math.sin(AngleHelper.rad(wheelAngle))) + .setChanged(); + wheels.setTransform(poseStack) + .translate(0, 1, 0) + .rotateXDegrees(wheelAngle) + .setChanged(); + pin.setTransform(poseStack) + .translate(0, 1, 0) + .rotateXDegrees(wheelAngle) + .translate(0, 1 / 4f, 0) + .rotateXDegrees(-wheelAngle) + .setChanged(); + } + + @Override + public void hide() { + super.hide(); + secondaryShaft1.setZeroTransform().setChanged(); + secondaryShaft2.setZeroTransform().setChanged(); + wheels.setZeroTransform().setChanged(); + drive.setZeroTransform().setChanged(); + piston.setZeroTransform().setChanged(); + pin.setZeroTransform().setChanged(); + } + + @Override + public void updateLight(int packedLight) { + super.updateLight(packedLight); + secondaryShaft1.light(packedLight).setChanged(); + secondaryShaft2.light(packedLight).setChanged(); + wheels.light(packedLight).setChanged(); + drive.light(packedLight).setChanged(); + piston.light(packedLight).setChanged(); + pin.light(packedLight).setChanged(); + } + + @Override + public void collectCrumblingInstances(Consumer<@Nullable Instance> consumer) { + super.collectCrumblingInstances(consumer); + consumer.accept(secondaryShaft1); + consumer.accept(secondaryShaft2); + consumer.accept(wheels); + consumer.accept(drive); + consumer.accept(piston); + consumer.accept(pin); + } + + @Override + public void delete() { + super.delete(); + secondaryShaft1.delete(); + secondaryShaft2.delete(); + wheels.delete(); + drive.delete(); + piston.delete(); + pin.delete(); + } + } +} diff --git a/src/main/java/com/simibubi/create/content/trains/display/FlapDisplayBlockEntity.java b/src/main/java/com/simibubi/create/content/trains/display/FlapDisplayBlockEntity.java index dc014511c..235cff63c 100644 --- a/src/main/java/com/simibubi/create/content/trains/display/FlapDisplayBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/trains/display/FlapDisplayBlockEntity.java @@ -141,7 +141,7 @@ public class FlapDisplayBlockEntity extends KineticBlockEntity { List lines = getLines(); if (lineIndex >= lines.size()) return; - + FlapDisplayLayout layout = lines.get(lineIndex); if (!layout.isLayout("Default")) layout.loadDefault(getMaxCharCount()); @@ -173,7 +173,7 @@ public class FlapDisplayBlockEntity extends KineticBlockEntity { colour[lineIndex] = color == DyeColor.WHITE ? null : color; notifyUpdate(); } - + public void setGlowing(int lineIndex) { glowingLines[lineIndex] = true; notifyUpdate(); @@ -210,7 +210,7 @@ public class FlapDisplayBlockEntity extends KineticBlockEntity { for (int j = 0; j < manualLines.length; j++) if (manualLines[j]) NBTHelper.putMarker(tag, "CustomLine" + j); - + for (int j = 0; j < glowingLines.length; j++) if (glowingLines[j]) NBTHelper.putMarker(tag, "GlowingLine" + j); @@ -239,7 +239,7 @@ public class FlapDisplayBlockEntity extends KineticBlockEntity { manualLines = new boolean[ySize * 2]; for (int i = 0; i < ySize * 2; i++) manualLines[i] = tag.contains("CustomLine" + i); - + glowingLines = new boolean[ySize * 2]; for (int i = 0; i < ySize * 2; i++) glowingLines[i] = tag.contains("GlowingLine" + i); @@ -323,12 +323,12 @@ public class FlapDisplayBlockEntity extends KineticBlockEntity { public int getLineColor(int line) { DyeColor color = colour[line]; return color == null ? 0xFF_D3C6BA - : DyeHelper.DYE_TABLE.get(color) + : DyeHelper.getDyeColors(color) .getFirst() | 0xFF_000000; } - + public boolean isLineGlowing(int line) { return glowingLines[line]; } - + } diff --git a/src/main/java/com/simibubi/create/content/trains/entity/Carriage.java b/src/main/java/com/simibubi/create/content/trains/entity/Carriage.java index b340e4848..cd11a6a3d 100644 --- a/src/main/java/com/simibubi/create/content/trains/entity/Carriage.java +++ b/src/main/java/com/simibubi/create/content/trains/entity/Carriage.java @@ -29,6 +29,7 @@ import com.simibubi.create.foundation.advancement.AllAdvancements; import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.NBTHelper; +import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.core.BlockPos; @@ -422,6 +423,13 @@ public class Carriage { return null; } + public Pair, DimensionalCarriageEntity> anyAvailableDimensionalCarriage() { + for (Entry, DimensionalCarriageEntity> entry : entities.entrySet()) + if (entry.getValue().entity.get() != null) + return Pair.of(entry.getKey(), entry.getValue()); + return null; + } + public void forEachPresentEntity(Consumer callback) { for (DimensionalCarriageEntity dimensionalCarriageEntity : entities.values()) { CarriageContraptionEntity entity = dimensionalCarriageEntity.entity.get(); @@ -791,6 +799,8 @@ public class Carriage { } private void createEntity(Level level, boolean loadPassengers) { + if (positionAnchor != null) + serialisedEntity.put("Pos", VecHelper.writeNBT(positionAnchor)); Entity entity = EntityType.create(serialisedEntity, level) .orElse(null); diff --git a/src/main/java/com/simibubi/create/content/trains/entity/CarriageBogey.java b/src/main/java/com/simibubi/create/content/trains/entity/CarriageBogey.java index 0f776c3db..937f238e5 100644 --- a/src/main/java/com/simibubi/create/content/trains/entity/CarriageBogey.java +++ b/src/main/java/com/simibubi/create/content/trains/entity/CarriageBogey.java @@ -9,8 +9,8 @@ import com.simibubi.create.AllBogeyStyles; import com.simibubi.create.Create; import com.simibubi.create.content.trains.bogey.AbstractBogeyBlock; import com.simibubi.create.content.trains.bogey.AbstractBogeyBlockEntity; +import com.simibubi.create.content.trains.bogey.BogeySizes.BogeySize; import com.simibubi.create.content.trains.bogey.BogeyStyle; -import com.simibubi.create.content.trains.bogey.BogeyVisual; import com.simibubi.create.content.trains.graph.DimensionPalette; import com.simibubi.create.content.trains.graph.TrackGraph; import com.simibubi.create.foundation.utility.AngleHelper; @@ -21,7 +21,6 @@ import com.simibubi.create.foundation.utility.RegisteredObjects; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.animation.LerpedFloat; -import dev.engine_room.flywheel.api.visualization.VisualizationContext; import net.minecraft.core.Direction.Axis; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; @@ -184,7 +183,7 @@ public class CarriageBogey { tag.put("Points", points.serializeEach(tp -> tp.write(dimensions))); tag.putBoolean("UpsideDown", upsideDown); bogeyData.putBoolean(UPSIDE_DOWN_KEY, upsideDown); - NBTHelper.writeResourceLocation(bogeyData, BOGEY_STYLE_KEY, getStyle().name); + NBTHelper.writeResourceLocation(bogeyData, BOGEY_STYLE_KEY, getStyle().id); tag.put(BOGEY_DATA_KEY, bogeyData); return tag; } @@ -199,20 +198,20 @@ public class CarriageBogey { return new CarriageBogey(type, upsideDown, data, points.getFirst(), points.getSecond()); } - public BogeyVisual createVisual(VisualizationContext context) { - return this.getStyle().createVisual(this, type.getSize(), context); - } - public BogeyStyle getStyle() { ResourceLocation location = NBTHelper.readResourceLocation(this.bogeyData, BOGEY_STYLE_KEY); BogeyStyle style = AllBogeyStyles.BOGEY_STYLES.get(location); return style != null ? style : AllBogeyStyles.STANDARD; // just for safety } + public BogeySize getSize() { + return type.getSize(); + } + private CompoundTag createBogeyData() { BogeyStyle style = type != null ? type.getDefaultStyle() : AllBogeyStyles.STANDARD; CompoundTag nbt = style.defaultData != null ? style.defaultData : new CompoundTag(); - NBTHelper.writeResourceLocation(nbt, BOGEY_STYLE_KEY, style.name); + NBTHelper.writeResourceLocation(nbt, BOGEY_STYLE_KEY, style.id); nbt.putBoolean(UPSIDE_DOWN_KEY, isUpsideDown()); return nbt; } diff --git a/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionEntity.java b/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionEntity.java index abfd3a669..c7c717a44 100644 --- a/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionEntity.java @@ -736,6 +736,7 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity { dimensional.updateRenderedCutoff(); } + // FIXME: entities should not reference their visual in any way @OnlyIn(Dist.CLIENT) private WeakReference instanceHolder; diff --git a/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionEntityRenderer.java b/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionEntityRenderer.java index 7d2d99e7a..0d802900e 100644 --- a/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionEntityRenderer.java +++ b/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionEntityRenderer.java @@ -66,8 +66,8 @@ public class CarriageContraptionEntityRenderer extends ContraptionEntityRenderer int light = getBogeyLightCoords(entity, bogey, partialTicks); - bogey.type.render(null, bogey.wheelAngle.getValue(partialTicks), ms, partialTicks, buffers, light, - overlay, bogey.getStyle(), bogey.bogeyData); + bogey.getStyle().render(bogey.getSize(), partialTicks, ms, buffers, light, + overlay, bogey.wheelAngle.getValue(partialTicks), bogey.bogeyData, true); ms.popPose(); } @@ -75,7 +75,6 @@ public class CarriageContraptionEntityRenderer extends ContraptionEntityRenderer bogey.updateCouplingAnchor(position, viewXRot, viewYRot, bogeySpacing, partialTicks, bogey.isLeading); if (!carriage.isOnTwoBogeys()) bogey.updateCouplingAnchor(position, viewXRot, viewYRot, bogeySpacing, partialTicks, !bogey.isLeading); - }); } @@ -99,7 +98,6 @@ public class CarriageContraptionEntityRenderer extends ContraptionEntityRenderer } public static int getBogeyLightCoords(CarriageContraptionEntity entity, CarriageBogey bogey, float partialTicks) { - var lightPos = BlockPos.containing( Objects.requireNonNullElseGet(bogey.getAnchorPosition(), () -> entity.getLightProbePosition(partialTicks))); diff --git a/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionVisual.java b/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionVisual.java index 376a99969..28ef06cb2 100644 --- a/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionVisual.java +++ b/src/main/java/com/simibubi/create/content/trains/entity/CarriageContraptionVisual.java @@ -1,10 +1,10 @@ package com.simibubi.create.content.trains.entity; +import org.jetbrains.annotations.Nullable; import org.joml.Vector3f; import com.mojang.blaze3d.vertex.PoseStack; import com.simibubi.create.content.contraptions.render.ContraptionVisual; -import com.simibubi.create.content.trains.bogey.BogeyRenderer; import com.simibubi.create.content.trains.bogey.BogeyVisual; import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Iterate; @@ -12,18 +12,19 @@ import com.simibubi.create.foundation.utility.Iterate; import dev.engine_room.flywheel.api.visual.DynamicVisual; import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.lib.transform.TransformStack; +import net.minecraft.nbt.CompoundTag; public class CarriageContraptionVisual extends ContraptionVisual { + private final PoseStack poseStack = new PoseStack(); - private final PoseStack ms = new PoseStack(); - + @Nullable private Carriage carriage; - private Couple bogeys; - private Couple bogeyHidden; + @Nullable + private Couple<@Nullable VisualizedBogey> bogeys; + private Couple bogeyHidden = Couple.create(() -> false); public CarriageContraptionVisual(VisualizationContext context, CarriageContraptionEntity entity, float partialTick) { super(context, entity, partialTick); - bogeyHidden = Couple.create(() -> false); entity.bindInstance(this); } @@ -31,13 +32,12 @@ public class CarriageContraptionVisual extends ContraptionVisual bogey.getStyle() - .createVisual(bogey, bogey.type.getSize(), manager), visualizationContext); - } + if (carriage != null) { + bogeys = carriage.bogeys.mapNotNull(bogey -> VisualizedBogey.of(visualizationContext, bogey, pt)); + } super.init(pt); - } + } public void setBogeyVisibility(boolean first, boolean visible) { bogeyHidden.set(first, !visible); @@ -60,32 +60,37 @@ public class CarriageContraptionVisual extends ContraptionVisual { - if (instance != null) - instance.updateLight(level, entity); + bogeys.forEach(bogey -> { + if (bogey != null) { + int packedLight = CarriageContraptionEntityRenderer.getBogeyLightCoords(entity, bogey.bogey, partialTick); + bogey.visual.updateLight(packedLight); + } }); } @@ -108,11 +115,21 @@ public class CarriageContraptionVisual extends ContraptionVisual { - if (instance != null) { - instance.commonRenderer.ifPresent(BogeyRenderer::remove); - instance.renderer.remove(); + bogeys.forEach(bogey -> { + if (bogey != null) { + bogey.visual.delete(); } }); } + + private record VisualizedBogey(CarriageBogey bogey, BogeyVisual visual) { + @Nullable + static VisualizedBogey of(VisualizationContext ctx, CarriageBogey bogey, float partialTick) { + BogeyVisual visual = bogey.getStyle().createVisual(bogey.getSize(), ctx, partialTick, true); + if (visual == null) { + return null; + } + return new VisualizedBogey(bogey, visual); + } + } } diff --git a/src/main/java/com/simibubi/create/content/trains/entity/CarriageSounds.java b/src/main/java/com/simibubi/create/content/trains/entity/CarriageSounds.java index f327b2cef..de30b39d7 100644 --- a/src/main/java/com/simibubi/create/content/trains/entity/CarriageSounds.java +++ b/src/main/java/com/simibubi/create/content/trains/entity/CarriageSounds.java @@ -42,7 +42,7 @@ public class CarriageSounds { public CarriageSounds(CarriageContraptionEntity entity) { this.entity = entity; bogeySounds = entity.getCarriage().bogeys.map(bogey -> - bogey != null && bogey.getStyle() != null ? bogey.getStyle().getSoundType() + bogey != null && bogey.getStyle() != null ? bogey.getStyle().soundEvent.get() : AllSoundEvents.TRAIN2.getMainEvent()); closestBogeySound = bogeySounds.getFirst(); distanceFactor = LerpedFloat.linear(); @@ -94,7 +94,7 @@ public class CarriageSounds { relevantBogey = bogeys.getFirst(); } if (relevantBogey != null) { - closestBogeySound = relevantBogey.getStyle().getSoundType(); + closestBogeySound = relevantBogey.getStyle().soundEvent.get(); } Vec3 toCarriage = distance1 > distance2 ? toBogey2 : toBogey1; diff --git a/src/main/java/com/simibubi/create/content/trains/entity/Train.java b/src/main/java/com/simibubi/create/content/trains/entity/Train.java index c12913e18..0b0927144 100644 --- a/src/main/java/com/simibubi/create/content/trains/entity/Train.java +++ b/src/main/java/com/simibubi/create/content/trains/entity/Train.java @@ -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; @@ -932,6 +933,8 @@ public class Train { @Nullable public LivingEntity getOwner(Level level) { + if (level.getServer() == null) + return null; try { UUID uuid = owner; return uuid == null ? null @@ -1130,6 +1133,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); @@ -1182,6 +1186,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"); diff --git a/src/main/java/com/simibubi/create/content/trains/entity/TrainPacket.java b/src/main/java/com/simibubi/create/content/trains/entity/TrainPacket.java index 288555ea4..1598c5379 100644 --- a/src/main/java/com/simibubi/create/content/trains/entity/TrainPacket.java +++ b/src/main/java/com/simibubi/create/content/trains/entity/TrainPacket.java @@ -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 diff --git a/src/main/java/com/simibubi/create/content/trains/entity/TrainStatus.java b/src/main/java/com/simibubi/create/content/trains/entity/TrainStatus.java index 1a3e73d84..8a68292a9 100644 --- a/src/main/java/com/simibubi/create/content/trains/entity/TrainStatus.java +++ b/src/main/java/com/simibubi/create/content/trains/entity/TrainStatus.java @@ -16,9 +16,9 @@ public class TrainStatus { Train train; - boolean navigation; - boolean track; - boolean conductor; + public boolean navigation; + public boolean track; + public boolean conductor; List queued = new ArrayList<>(); diff --git a/src/main/java/com/simibubi/create/content/trains/graph/TrackGraphSyncPacket.java b/src/main/java/com/simibubi/create/content/trains/graph/TrackGraphSyncPacket.java index e5cda7b42..f3b04b13f 100644 --- a/src/main/java/com/simibubi/create/content/trains/graph/TrackGraphSyncPacket.java +++ b/src/main/java/com/simibubi/create/content/trains/graph/TrackGraphSyncPacket.java @@ -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; diff --git a/src/main/java/com/simibubi/create/content/trains/station/AssemblyScreen.java b/src/main/java/com/simibubi/create/content/trains/station/AssemblyScreen.java index 8fa4a0ef1..c8246bcf1 100644 --- a/src/main/java/com/simibubi/create/content/trains/station/AssemblyScreen.java +++ b/src/main/java/com/simibubi/create/content/trains/station/AssemblyScreen.java @@ -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(Lang.translateDirect("station.icon_type")); + iconTypeScroll = new ScrollInput(x + 4, y + 17, 162, 14).titled(Lang.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)); } } diff --git a/src/main/java/com/simibubi/create/content/trains/station/StationBlockEntity.java b/src/main/java/com/simibubi/create/content/trains/station/StationBlockEntity.java index a620fc151..1bcd2e0c3 100644 --- a/src/main/java/com/simibubi/create/content/trains/station/StationBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/trains/station/StationBlockEntity.java @@ -466,6 +466,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 updateState) { GlobalStation station = getStation(); diff --git a/src/main/java/com/simibubi/create/content/trains/station/StationScreen.java b/src/main/java/com/simibubi/create/content/trains/station/StationScreen.java index d990ddd12..70cd9e998 100644 --- a/src/main/java/com/simibubi/create/content/trains/station/StationScreen.java +++ b/src/main/java/com/simibubi/create/content/trains/station/StationScreen.java @@ -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; @@ -20,6 +21,7 @@ import com.simibubi.create.foundation.gui.UIRenderHelper; import com.simibubi.create.foundation.gui.widget.IconButton; import com.simibubi.create.foundation.gui.widget.Label; import com.simibubi.create.foundation.gui.widget.ScrollInput; +import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.Components; import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Pair; @@ -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(Lang.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.width - 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.width - 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.width, sprite.height); + } } @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; } diff --git a/src/main/java/com/simibubi/create/content/trains/station/TrainEditPacket.java b/src/main/java/com/simibubi/create/content/trains/station/TrainEditPacket.java index 5ee103bef..d2ba96eab 100644 --- a/src/main/java/com/simibubi/create/content/trains/station/TrainEditPacket.java +++ b/src/main/java/com/simibubi/create/content/trains/station/TrainEditPacket.java @@ -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); } } diff --git a/src/main/java/com/simibubi/create/content/trains/track/AllPortalTracks.java b/src/main/java/com/simibubi/create/content/trains/track/AllPortalTracks.java index f74dece9a..4fb8b200c 100644 --- a/src/main/java/com/simibubi/create/content/trains/track/AllPortalTracks.java +++ b/src/main/java/com/simibubi/create/content/trains/track/AllPortalTracks.java @@ -1,9 +1,12 @@ package com.simibubi.create.content.trains.track; +import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.UnaryOperator; +import com.simibubi.create.Create; import com.simibubi.create.compat.Mods; +import com.simibubi.create.compat.betterend.BetterEndPortalCompat; import com.simibubi.create.content.contraptions.glue.SuperGlueEntity; import com.simibubi.create.foundation.utility.AttachedRegistry; import com.simibubi.create.foundation.utility.BlockFace; @@ -26,30 +29,66 @@ import net.minecraft.world.phys.AABB; import net.minecraftforge.common.util.ITeleporter; import net.minecraftforge.registries.ForgeRegistries; +/** + * Manages portal track integrations for various dimensions and mods within the Create mod. + *

+ * Portals must be entered from the side and must lead to a different dimension than the one entered from. + * This class handles the registration and functionality of portal tracks for standard and modded portals. + *

+ */ public class AllPortalTracks { - - // Portals must be entered from the side and must lead to a different dimension - // than the one entered from - + /** + * Functional interface representing a provider for portal track connections. + * It takes a pair of {@link ServerLevel} and {@link BlockFace} representing the inbound track + * and returns a similar pair for the outbound track. + */ @FunctionalInterface - public interface PortalTrackProvider extends UnaryOperator> { - }; + public interface PortalTrackProvider extends UnaryOperator> {} + /** + * Registry mapping portal blocks to their respective {@link PortalTrackProvider}s. + */ private static final AttachedRegistry PORTAL_BEHAVIOURS = - new AttachedRegistry<>(ForgeRegistries.BLOCKS); + new AttachedRegistry<>(ForgeRegistries.BLOCKS); + /** + * Registers a portal track integration for a given block identified by its {@link ResourceLocation}. + * + * @param block The resource location of the portal block. + * @param provider The portal track provider for the block. + */ public static void registerIntegration(ResourceLocation block, PortalTrackProvider provider) { PORTAL_BEHAVIOURS.register(block, provider); } + /** + * Registers a portal track integration for a given {@link Block}. + * + * @param block The portal block. + * @param provider The portal track provider for the block. + */ public static void registerIntegration(Block block, PortalTrackProvider provider) { PORTAL_BEHAVIOURS.register(block, provider); } + /** + * Checks if a given {@link BlockState} represents a supported portal block. + * + * @param state The block state to check. + * @return {@code true} if the block state represents a supported portal; {@code false} otherwise. + */ public static boolean isSupportedPortal(BlockState state) { return PORTAL_BEHAVIOURS.get(state.getBlock()) != null; } + /** + * Retrieves the corresponding outbound track on the other side of a portal. + * + * @param level The current {@link ServerLevel}. + * @param inboundTrack The inbound track {@link BlockFace}. + * @return A pair containing the target {@link ServerLevel} and outbound {@link BlockFace}, + * or {@code null} if no corresponding portal is found. + */ public static Pair getOtherSide(ServerLevel level, BlockFace inboundTrack) { BlockPos portalPos = inboundTrack.getConnectedPos(); BlockState portalState = level.getBlockState(portalPos); @@ -57,61 +96,132 @@ public class AllPortalTracks { return provider == null ? null : provider.apply(Pair.of(level, inboundTrack)); } - // Builtin handlers + // Built-in handlers + /** + * Registers default portal track integrations for built-in dimensions and mods. + * This includes the Nether and the Aether (if loaded). + */ public static void registerDefaults() { registerIntegration(Blocks.NETHER_PORTAL, AllPortalTracks::nether); if (Mods.AETHER.isLoaded()) - registerIntegration(new ResourceLocation("aether", "aether_portal"), AllPortalTracks::aether); + registerIntegration(Mods.AETHER.rl("aether_portal"), AllPortalTracks::aether); + if (Mods.BETTEREND.isLoaded()) + registerIntegration(Mods.BETTEREND.rl("end_portal_block"), AllPortalTracks::betterend); } + /** + * Portal track provider for the Nether portal. + * + * @param inbound A pair containing the current {@link ServerLevel} and inbound {@link BlockFace}. + * @return A pair with the target {@link ServerLevel} and outbound {@link BlockFace}, or {@code null} if not applicable. + */ private static Pair nether(Pair inbound) { + ServerLevel level = inbound.getFirst(); + MinecraftServer minecraftServer = level.getServer(); + + if (!minecraftServer.isNetherEnabled()) + return null; + return standardPortalProvider(inbound, Level.OVERWORLD, Level.NETHER, ServerLevel::getPortalForcer); } + /** + * Portal track provider for the Aether mod's portal. + * + * @param inbound A pair containing the current {@link ServerLevel} and inbound {@link BlockFace}. + * @return A pair with the target {@link ServerLevel} and outbound {@link BlockFace}, or {@code null} if not applicable. + */ private static Pair aether(Pair inbound) { ResourceKey aetherLevelKey = - ResourceKey.create(Registries.DIMENSION, new ResourceLocation("aether", "the_aether")); + ResourceKey.create(Registries.DIMENSION, Mods.AETHER.rl("the_aether")); return standardPortalProvider(inbound, Level.OVERWORLD, aetherLevelKey, level -> { try { return (ITeleporter) Class.forName("com.aetherteam.aether.block.portal.AetherPortalForcer") - .getDeclaredConstructor(ServerLevel.class, boolean.class) - .newInstance(level, true); + .getDeclaredConstructor(ServerLevel.class, boolean.class) + .newInstance(level, true); } catch (Exception e) { - e.printStackTrace(); + Create.LOGGER.error("Failed to create Aether teleporter: ", e); } return level.getPortalForcer(); }); } - public static Pair standardPortalProvider(Pair inbound, - ResourceKey firstDimension, ResourceKey secondDimension, - Function customPortalForcer) { - ServerLevel level = inbound.getFirst(); - ResourceKey resourcekey = level.dimension() == secondDimension ? firstDimension : secondDimension; - MinecraftServer minecraftserver = level.getServer(); - ServerLevel otherLevel = minecraftserver.getLevel(resourcekey); + /** + * Portal track provider for the Better End mod's portal. + * + * @param inbound A pair containing the current {@link ServerLevel} and inbound {@link BlockFace}. + * @return A pair with the target {@link ServerLevel} and outbound {@link BlockFace}, or {@code null} if not applicable. + */ + private static Pair betterend(Pair inbound) { + return portalProvider(inbound, Level.OVERWORLD, Level.END, BetterEndPortalCompat::getBetterEndPortalInfo); + } - if (otherLevel == null || !minecraftserver.isNetherEnabled()) + /** + * Provides a standard portal track provider that handles portal traversal between two dimensions. + * + * @param inbound A pair containing the current {@link ServerLevel} and inbound {@link BlockFace}. + * @param firstDimension The first dimension (typically the Overworld). + * @param secondDimension The second dimension (e.g., Nether, Aether). + * @param customPortalForcer A function to obtain the {@link ITeleporter} for the target level. + * @return A pair with the target {@link ServerLevel} and outbound {@link BlockFace}, or {@code null} if not applicable. + */ + public static Pair standardPortalProvider( + Pair inbound, + ResourceKey firstDimension, + ResourceKey secondDimension, + Function customPortalForcer + ) { + return portalProvider( + inbound, + firstDimension, + secondDimension, + (otherLevel, probe) -> { + ITeleporter teleporter = customPortalForcer.apply(otherLevel); + return teleporter.getPortalInfo(probe, otherLevel, probe::findDimensionEntryPoint); + } + ); + } + + /** + * Generalized portal provider method that calculates the corresponding outbound track across a portal. + * + * @param inbound A pair containing the current {@link ServerLevel} and inbound {@link BlockFace}. + * @param firstDimension The first dimension. + * @param secondDimension The second dimension. + * @param portalInfoProvider A function that provides the {@link PortalInfo} given the target level and probe entity. + * @return A pair with the target {@link ServerLevel} and outbound {@link BlockFace}, or {@code null} if not applicable. + */ + public static Pair portalProvider( + Pair inbound, + ResourceKey firstDimension, + ResourceKey secondDimension, + BiFunction portalInfoProvider + ) { + ServerLevel level = inbound.getFirst(); + ResourceKey resourceKey = level.dimension() == secondDimension ? firstDimension : secondDimension; + + MinecraftServer minecraftServer = level.getServer(); + ServerLevel otherLevel = minecraftServer.getLevel(resourceKey); + + if (otherLevel == null) return null; BlockFace inboundTrack = inbound.getSecond(); BlockPos portalPos = inboundTrack.getConnectedPos(); BlockState portalState = level.getBlockState(portalPos); - ITeleporter teleporter = customPortalForcer.apply(otherLevel); SuperGlueEntity probe = new SuperGlueEntity(level, new AABB(portalPos)); - probe.setYRot(inboundTrack.getFace() - .toYRot()); + probe.setYRot(inboundTrack.getFace().toYRot()); probe.setPortalEntrancePos(); - PortalInfo portalinfo = teleporter.getPortalInfo(probe, otherLevel, probe::findDimensionEntryPoint); - if (portalinfo == null) + PortalInfo portalInfo = portalInfoProvider.apply(otherLevel, probe); + if (portalInfo == null) return null; - BlockPos otherPortalPos = BlockPos.containing(portalinfo.pos); + BlockPos otherPortalPos = BlockPos.containing(portalInfo.pos); BlockState otherPortalState = otherLevel.getBlockState(otherPortalPos); - if (otherPortalState.getBlock() != portalState.getBlock()) + if (!otherPortalState.is(portalState.getBlock())) return null; Direction targetDirection = inboundTrack.getFace(); @@ -120,5 +230,4 @@ public class AllPortalTracks { BlockPos otherPos = otherPortalPos.relative(targetDirection); return Pair.of(otherLevel, new BlockFace(otherPos, targetDirection.getOpposite())); } - } diff --git a/src/main/java/com/simibubi/create/content/trains/track/BezierConnection.java b/src/main/java/com/simibubi/create/content/trains/track/BezierConnection.java index 51f59191e..5f1885107 100644 --- a/src/main/java/com/simibubi/create/content/trains/track/BezierConnection.java +++ b/src/main/java/com/simibubi/create/content/trains/track/BezierConnection.java @@ -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; @@ -8,6 +10,7 @@ import com.simibubi.create.AllBlocks; import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.NBTHelper; +import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.VecHelper; import dev.engine_room.flywheel.lib.transform.TransformStack; @@ -108,7 +111,8 @@ public class BezierConnection implements Iterable { .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 { } 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 { return bakedGirders; } + public Map, Double> rasterise() { + Map, 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 prev = null; + Pair prev2 = null; + Pair prev3 = null; + + for (int i = 0; i < segCount; i++) { + Vec3 railMiddle = samples[i]; + BlockPos pos = BlockPos.containing(railMiddle); + Pair 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 pFrom, Vec3 to) { + return to.distanceToSqr(pFrom.getFirst() + 0.5, to.y, pFrom.getSecond() + 0.5); + } + + private boolean isLineDoubled(Pair pFrom, Pair pVia, + Pair 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; + } + } diff --git a/src/main/java/com/simibubi/create/content/trains/track/TrackBlockEntity.java b/src/main/java/com/simibubi/create/content/trains/track/TrackBlockEntity.java index 43e8a7d09..ce0fab09d 100644 --- a/src/main/java/com/simibubi/create/content/trains/track/TrackBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/trains/track/TrackBlockEntity.java @@ -20,7 +20,6 @@ import com.simibubi.create.foundation.blockEntity.RemoveBlockEntityPacket; import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour; import com.simibubi.create.foundation.utility.Pair; -import com.simibubi.create.foundation.utility.VecHelper; import dev.engine_room.flywheel.lib.visualization.VisualizationHelper; import net.minecraft.core.BlockPos; @@ -363,54 +362,7 @@ public class TrackBlockEntity extends SmartBlockEntity implements ITransformable } public void manageFakeTracksAlong(BezierConnection bc, boolean remove) { - Map, 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 key = Pair.of(pos.getX(), pos.getZ()); - if (!yLevels.containsKey(key) || yLevels.get(key) > vec.y) - yLevels.put(key, vec.y); - } - } + Map, Double> yLevels = bc.rasterise(); for (Entry, 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); diff --git a/src/main/java/com/simibubi/create/content/trains/track/TrackVisual.java b/src/main/java/com/simibubi/create/content/trains/track/TrackVisual.java index 5a1edb944..ec614f18b 100644 --- a/src/main/java/com/simibubi/create/content/trains/track/TrackVisual.java +++ b/src/main/java/com/simibubi/create/content/trains/track/TrackVisual.java @@ -1,5 +1,6 @@ package com.simibubi.create.content.trains.track; +import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.function.Consumer; @@ -31,16 +32,12 @@ import net.minecraft.world.level.LightLayer; public class TrackVisual extends AbstractBlockEntityVisual { - private final List visuals; + private final List visuals = new ArrayList<>(); public TrackVisual(VisualizationContext context, TrackBlockEntity track, float partialTick) { super(context, track, partialTick); - visuals = blockEntity.connections.values() - .stream() - .map(this::createInstance) - .filter(Objects::nonNull) - .toList(); + collectConnections(); } @Override @@ -49,13 +46,22 @@ public class TrackVisual extends AbstractBlockEntityVisual { return; _delete(); + + collectConnections(); + lightSections.sections(collectLightSections()); } + private void collectConnections() { + blockEntity.connections.values() + .stream() + .map(this::createInstance) + .filter(Objects::nonNull) + .forEach(visuals::add); + } + @Override public void updateLight(float partialTick) { - if (visuals == null) - return; visuals.forEach(BezierTrackVisual::updateLight); } @@ -68,9 +74,8 @@ public class TrackVisual extends AbstractBlockEntityVisual { @Override public void _delete() { - if (visuals == null) - return; visuals.forEach(BezierTrackVisual::delete); + visuals.clear(); } public LongSet collectLightSections() { @@ -102,8 +107,6 @@ public class TrackVisual extends AbstractBlockEntityVisual { @Override public void collectCrumblingInstances(Consumer consumer) { - if (visuals == null) - return; for (BezierTrackVisual instance : visuals) { instance.collectCrumblingInstances(consumer); } @@ -138,11 +141,11 @@ public class TrackVisual extends AbstractBlockEntityVisual { TrackMaterial.TrackModelHolder modelHolder = bc.getMaterial().getModelHolder(); - instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(modelHolder.tie())) + instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(modelHolder.tie())) .createInstances(ties); - instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(modelHolder.leftSegment())) + instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(modelHolder.leftSegment())) .createInstances(left); - instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(modelHolder.rightSegment())) + instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(modelHolder.rightSegment())) .createInstances(right); SegmentAngles[] segments = bc.getBakedSegments(); @@ -151,14 +154,14 @@ public class TrackVisual extends AbstractBlockEntityVisual { var modelIndex = i - 1; ties[modelIndex].setTransform(pose) - .transform(segment.tieTransform) + .mul(segment.tieTransform) .setChanged(); tiesLightPos[modelIndex] = segment.lightPosition.offset(tePosition); for (boolean first : Iterate.trueAndFalse) { Pose transform = segment.railTransforms.get(first); (first ? this.left : this.right)[modelIndex].setTransform(pose) - .transform(transform) + .mul(transform) .setChanged(); (first ? leftLightPos : rightLightPos)[modelIndex] = segment.lightPosition.offset(tePosition); } @@ -218,10 +221,10 @@ public class TrackVisual extends AbstractBlockEntityVisual { beams = Couple.create(() -> new TransformedInstance[segCount]); beamCaps = Couple.create(() -> Couple.create(() -> new TransformedInstance[segCount])); lightPos = new BlockPos[segCount]; - beams.forEach(instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.GIRDER_SEGMENT_MIDDLE))::createInstances); + beams.forEach(instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.GIRDER_SEGMENT_MIDDLE))::createInstances); beamCaps.forEachWithContext((c, top) -> { var partialModel = Models.partial(top ? AllPartialModels.GIRDER_SEGMENT_TOP : AllPartialModels.GIRDER_SEGMENT_BOTTOM); - c.forEach(instancerProvider.instancer(InstanceTypes.TRANSFORMED, partialModel)::createInstances); + c.forEach(instancerProvider().instancer(InstanceTypes.TRANSFORMED, partialModel)::createInstances); }); GirderAngles[] bakedGirders = bc.getBakedGirders(); @@ -233,14 +236,14 @@ public class TrackVisual extends AbstractBlockEntityVisual { for (boolean first : Iterate.trueAndFalse) { Pose beamTransform = segment.beams.get(first); beams.get(first)[modelIndex].setTransform(pose) - .transform(beamTransform) + .mul(beamTransform) .setChanged(); for (boolean top : Iterate.trueAndFalse) { Pose beamCapTransform = segment.beamCaps.get(top) .get(first); beamCaps.get(top) .get(first)[modelIndex].setTransform(pose) - .transform(beamCapTransform) + .mul(beamCapTransform) .setChanged(); } } diff --git a/src/main/java/com/simibubi/create/foundation/block/CopperBlockSet.java b/src/main/java/com/simibubi/create/foundation/block/CopperBlockSet.java index fa662efa3..2aca149ad 100644 --- a/src/main/java/com/simibubi/create/foundation/block/CopperBlockSet.java +++ b/src/main/java/com/simibubi/create/foundation/block/CopperBlockSet.java @@ -7,6 +7,8 @@ import java.util.Map; import java.util.Objects; import java.util.function.Supplier; +import net.minecraft.tags.ItemTags; + import org.apache.commons.lang3.ArrayUtils; import com.simibubi.create.foundation.data.TagGen; @@ -132,7 +134,13 @@ public class CopperBlockSet { .simpleItem(); if (variant == BlockVariant.INSTANCE && state == WeatherState.UNAFFECTED) - builder.recipe((c, p) -> mainBlockRecipe.accept(c, p)); + builder.recipe(mainBlockRecipe::accept); + + if (variant == StairVariant.INSTANCE) + builder.tag(BlockTags.STAIRS); + + if (variant == SlabVariant.INSTANCE) + builder.tag(BlockTags.SLABS); if (waxed) { builder.recipe((ctx, prov) -> { diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/inventory/CapManipulationBehaviourBase.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/inventory/CapManipulationBehaviourBase.java index 9b25a050a..0dcb74dc4 100644 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/inventory/CapManipulationBehaviourBase.java +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/inventory/CapManipulationBehaviourBase.java @@ -7,7 +7,6 @@ import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringBehaviour; import com.simibubi.create.foundation.item.ItemHelper.ExtractionCountMode; import com.simibubi.create.foundation.utility.BlockFace; -import com.simibubi.create.foundation.utility.HashableNonNullConsumer; import net.minecraft.core.BlockPos; import net.minecraft.world.level.Level; @@ -128,8 +127,6 @@ public abstract class CapManipulationBehaviourBase capability = capability(); targetCapability = bypassSided ? invBE.getCapability(capability) : invBE.getCapability(capability, targetBlockFace.getFace()); - if (targetCapability.isPresent()) - targetCapability.addListener(new HashableNonNullConsumer<>(this::onHandlerInvalidated, this)); } @FunctionalInterface diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/renderer/SafeBlockEntityRenderer.java b/src/main/java/com/simibubi/create/foundation/blockEntity/renderer/SafeBlockEntityRenderer.java index f26940d4c..d9b8d4c69 100644 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/renderer/SafeBlockEntityRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/renderer/SafeBlockEntityRenderer.java @@ -2,10 +2,13 @@ package com.simibubi.create.foundation.blockEntity.renderer; import com.mojang.blaze3d.vertex.PoseStack; +import com.simibubi.create.foundation.ponder.PonderWorld; + 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 +31,10 @@ public abstract class SafeBlockEntityRenderer implements .getBlock() == Blocks.AIR; } - public boolean shouldCullItem(Vec3 itemPos) { + public boolean shouldCullItem(Vec3 itemPos, Level level) { + if (level instanceof PonderWorld) + return false; + Frustum frustum = Minecraft.getInstance().levelRenderer.capturedFrustum != null ? Minecraft.getInstance().levelRenderer.capturedFrustum : Minecraft.getInstance().levelRenderer.cullingFrustum; diff --git a/src/main/java/com/simibubi/create/foundation/data/recipe/CompatMetals.java b/src/main/java/com/simibubi/create/foundation/data/recipe/CompatMetals.java index 5a87e23a5..bb1b7ea54 100644 --- a/src/main/java/com/simibubi/create/foundation/data/recipe/CompatMetals.java +++ b/src/main/java/com/simibubi/create/foundation/data/recipe/CompatMetals.java @@ -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. diff --git a/src/main/java/com/simibubi/create/foundation/data/recipe/MillingRecipeGen.java b/src/main/java/com/simibubi/create/foundation/data/recipe/MillingRecipeGen.java index f6a50ac70..6b28a22d5 100644 --- a/src/main/java/com/simibubi/create/foundation/data/recipe/MillingRecipeGen.java +++ b/src/main/java/com/simibubi/create/foundation/data/recipe/MillingRecipeGen.java @@ -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; diff --git a/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java b/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java index 405fe0549..eb0c5ab9e 100644 --- a/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java +++ b/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java @@ -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 { @@ -1178,7 +1180,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)) @@ -1224,8 +1227,8 @@ public class StandardRecipeGen extends CreateRecipeProvider { } GeneratedRecipe blastModdedCrushedMetal(ItemEntry 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) @@ -1375,7 +1378,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")); }); } @@ -1478,10 +1486,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) @@ -1502,19 +1510,39 @@ public class StandardRecipeGen extends CreateRecipeProvider { super(p_i48262_1_); } - private static class ModdedCookingRecipeResult implements FinishedRecipe { + private record ModdedCookingRecipeResult(FinishedRecipe wrapped, ResourceLocation outputOverride, List conditions) implements FinishedRecipe { + @Override + public ResourceLocation getId() { + return wrapped.getId(); + } - private FinishedRecipe wrapped; - private ResourceLocation outputOverride; - private List conditions; + @Override + public RecipeSerializer getType() { + return wrapped.getType(); + } - public ModdedCookingRecipeResult(FinishedRecipe wrapped, ResourceLocation outputOverride, - List 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 conditions) implements FinishedRecipe { @Override public ResourceLocation getId() { return wrapped.getId(); @@ -1536,15 +1564,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); } - } - } diff --git a/src/main/java/com/simibubi/create/foundation/data/recipe/WashingRecipeGen.java b/src/main/java/com/simibubi/create/foundation/data/recipe/WashingRecipeGen.java index a90bd5d74..28b4e2063 100644 --- a/src/main/java/com/simibubi/create/foundation/data/recipe/WashingRecipeGen.java +++ b/src/main/java/com/simibubi/create/foundation/data/recipe/WashingRecipeGen.java @@ -133,8 +133,8 @@ public class WashingRecipeGen extends ProcessingRecipeGen { } public GeneratedRecipe moddedCrushedOre(ItemEntry 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(), diff --git a/src/main/java/com/simibubi/create/foundation/events/CommonEvents.java b/src/main/java/com/simibubi/create/foundation/events/CommonEvents.java index 6967cace0..5ae94185e 100644 --- a/src/main/java/com/simibubi/create/foundation/events/CommonEvents.java +++ b/src/main/java/com/simibubi/create/foundation/events/CommonEvents.java @@ -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 diff --git a/src/main/java/com/simibubi/create/foundation/fluid/FluidHelper.java b/src/main/java/com/simibubi/create/foundation/fluid/FluidHelper.java index e00cbd7d3..7e47daee6 100644 --- a/src/main/java/com/simibubi/create/foundation/fluid/FluidHelper.java +++ b/src/main/java/com/simibubi/create/foundation/fluid/FluidHelper.java @@ -53,11 +53,11 @@ public class FluidHelper { public static boolean isLava(Fluid fluid) { return convertToStill(fluid) == Fluids.LAVA; } - + public static boolean isSame(FluidStack fluidStack, FluidStack fluidStack2) { return fluidStack.getFluid() == fluidStack2.getFluid(); } - + public static boolean isSame(FluidStack fluidStack, Fluid fluid) { return fluidStack.getFluid() == fluid; } @@ -147,6 +147,8 @@ public class FluidHelper { Fluid fluid = ForgeRegistries.FLUIDS.getValue(id); if (fluid == null) throw new JsonSyntaxException("Unknown fluid '" + id + "'"); + if (fluid == Fluids.EMPTY) + throw new JsonSyntaxException("Invalid empty fluid '" + id + "'"); int amount = GsonHelper.getAsInt(json, "amount"); FluidStack stack = new FluidStack(fluid, amount); diff --git a/src/main/java/com/simibubi/create/foundation/fluid/FluidIngredient.java b/src/main/java/com/simibubi/create/foundation/fluid/FluidIngredient.java index ce69e7579..5672f1b83 100644 --- a/src/main/java/com/simibubi/create/foundation/fluid/FluidIngredient.java +++ b/src/main/java/com/simibubi/create/foundation/fluid/FluidIngredient.java @@ -124,7 +124,7 @@ public abstract class FluidIngredient implements Predicate { public static FluidIngredient deserialize(@Nullable JsonElement je) { if (!isFluidIngredient(je)) - throw new JsonSyntaxException("Invalid fluid ingredient: " + Objects.toString(je)); + throw new JsonSyntaxException("Invalid fluid ingredient: " + je); JsonObject json = je.getAsJsonObject(); FluidIngredient ingredient = json.has("fluidTag") ? new FluidTagIngredient() : new FluidStackIngredient(); diff --git a/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java b/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java index 78693e28f..06bf6274f 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java +++ b/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java @@ -189,6 +189,18 @@ public enum AllGuiTextures implements ScreenElement { // 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); diff --git a/src/main/java/com/simibubi/create/foundation/item/ItemHelper.java b/src/main/java/com/simibubi/create/foundation/item/ItemHelper.java index fa812ceb9..d4cdb6151 100644 --- a/src/main/java/com/simibubi/create/foundation/item/ItemHelper.java +++ b/src/main/java/com/simibubi/create/foundation/item/ItemHelper.java @@ -2,11 +2,18 @@ package com.simibubi.create.foundation.item; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.function.Function; import java.util.function.Predicate; import javax.annotation.Nullable; +import com.simibubi.create.foundation.block.IBE; + +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraftforge.common.capabilities.ForgeCapabilities; + import org.apache.commons.lang3.mutable.MutableInt; import com.simibubi.create.foundation.utility.Pair; @@ -26,7 +33,7 @@ public class ItemHelper { public static boolean sameItem(ItemStack stack, ItemStack otherStack) { return !otherStack.isEmpty() && stack.is(otherStack.getItem()); } - + public static Predicate sameItemPredicate(ItemStack stack) { return s -> sameItem(stack, s); } @@ -73,6 +80,13 @@ public class ItemHelper { return true; } + public static > int calcRedstoneFromBlockEntity(T ibe, Level level, BlockPos pos) { + return ibe.getBlockEntityOptional(level, pos) + .map(be -> be.getCapability(ForgeCapabilities.ITEM_HANDLER)) + .map(lo -> lo.map(ItemHelper::calcRedstoneFromInventory).orElse(0)) + .orElse(0); + } + public static int calcRedstoneFromInventory(@Nullable IItemHandler inv) { if (inv == null) return 0; @@ -284,4 +298,16 @@ public class ItemHelper { } return -1; } + + 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; + } + } diff --git a/src/main/java/com/simibubi/create/foundation/mixin/BlockItemMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/BlockItemMixin.java index a9c6d514b..f4031bcb2 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/BlockItemMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/BlockItemMixin.java @@ -9,7 +9,6 @@ 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; import org.spongepowered.asm.mixin.Mixin; @@ -22,7 +21,7 @@ public class BlockItemMixin { @Inject(method = "place", at = @At("HEAD"), cancellable = true) private void create$fixDeployerPlacement(BlockPlaceContext pContext, CallbackInfoReturnable 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); } } diff --git a/src/main/java/com/simibubi/create/foundation/mixin/CreateMixinPlugin.java b/src/main/java/com/simibubi/create/foundation/mixin/CreateMixinPlugin.java new file mode 100644 index 000000000..fb26a4534 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/mixin/CreateMixinPlugin.java @@ -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 myTargets, Set otherTargets) {} + + @Override + public List 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) {} + +} diff --git a/src/main/java/com/simibubi/create/foundation/mixin/SmithingMenuMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/SmithingMenuMixin.java new file mode 100644 index 000000000..23bcbebe4 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/mixin/SmithingMenuMixin.java @@ -0,0 +1,45 @@ +package com.simibubi.create.foundation.mixin; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; + +import com.simibubi.create.AllItems; +import com.simibubi.create.content.equipment.armor.BacktankItem; + +import net.minecraft.world.inventory.SmithingMenu; + +import net.minecraft.world.item.ItemStack; + +import net.minecraft.world.item.enchantment.Enchantment; +import net.minecraft.world.item.enchantment.EnchantmentHelper; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +import java.util.HashMap; +import java.util.Map; + +@Mixin(SmithingMenu.class) +public class SmithingMenuMixin { + // Only add enchantments to the backtank if it supports them + @ModifyExpressionValue( + method = "createResult", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/item/crafting/SmithingRecipe;assemble(Lnet/minecraft/world/Container;Lnet/minecraft/core/RegistryAccess;)Lnet/minecraft/world/item/ItemStack;" + ) + ) + private ItemStack create$preventUnbreakingOnBacktanks(ItemStack original) { + if (AllItems.COPPER_BACKTANK.is(original) || AllItems.NETHERITE_BACKTANK.is(original)) { + Map enchantments = new HashMap<>(); + + EnchantmentHelper.getEnchantments(original).forEach((enchantment, level) -> { + if (enchantment.canEnchant(original)) + enchantments.put(enchantment, level); + }); + + EnchantmentHelper.setEnchantments(enchantments, original); + } + + return original; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/mixin/compat/JourneyFullscreenMapMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/compat/JourneyFullscreenMapMixin.java new file mode 100644 index 000000000..70bb99964 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/mixin/compat/JourneyFullscreenMapMixin.java @@ -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); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/ponder/PonderWorld.java b/src/main/java/com/simibubi/create/foundation/ponder/PonderWorld.java index 794a015f6..85e3956e0 100644 --- a/src/main/java/com/simibubi/create/foundation/ponder/PonderWorld.java +++ b/src/main/java/com/simibubi/create/foundation/ponder/PonderWorld.java @@ -14,7 +14,6 @@ import com.mojang.blaze3d.vertex.PoseStack; import com.simibubi.create.content.kinetics.belt.BeltBlock; import com.simibubi.create.content.kinetics.belt.BeltBlockEntity; import com.simibubi.create.content.schematics.SchematicWorld; -import com.simibubi.create.foundation.blockEntity.IMultiBlockEntityContainer; import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; import com.simibubi.create.foundation.mixin.accessor.ParticleEngineAccessor; import com.simibubi.create.foundation.ponder.element.WorldSectionElement; @@ -259,38 +258,22 @@ public class PonderWorld extends SchematicWorld { smartBlockEntity.markVirtual(); } + @Override public void fixControllerBlockEntities() { + super.fixControllerBlockEntities(); for (BlockEntity blockEntity : blockEntities.values()) { - - if (blockEntity instanceof BeltBlockEntity) { - BeltBlockEntity beltBlockEntity = (BeltBlockEntity) blockEntity; - if (!beltBlockEntity.isController()) + if (!(blockEntity instanceof BeltBlockEntity beltBlockEntity)) + continue; + if (!beltBlockEntity.isController()) + continue; + BlockPos controllerPos = blockEntity.getBlockPos(); + for (BlockPos blockPos : BeltBlock.getBeltChain(this, controllerPos)) { + BlockEntity blockEntity2 = getBlockEntity(blockPos); + if (!(blockEntity2 instanceof BeltBlockEntity)) continue; - BlockPos controllerPos = blockEntity.getBlockPos(); - for (BlockPos blockPos : BeltBlock.getBeltChain(this, controllerPos)) { - BlockEntity blockEntity2 = getBlockEntity(blockPos); - if (!(blockEntity2 instanceof BeltBlockEntity)) - continue; - BeltBlockEntity belt2 = (BeltBlockEntity) blockEntity2; - belt2.setController(controllerPos); - } + BeltBlockEntity belt2 = (BeltBlockEntity) blockEntity2; + belt2.setController(controllerPos); } - - if (blockEntity instanceof IMultiBlockEntityContainer) { - IMultiBlockEntityContainer multiBlockEntity = (IMultiBlockEntityContainer) blockEntity; - BlockPos lastKnown = multiBlockEntity.getLastKnownPos(); - BlockPos current = blockEntity.getBlockPos(); - if (lastKnown == null || current == null) - continue; - if (multiBlockEntity.isController()) - continue; - if (!lastKnown.equals(current)) { - BlockPos newControllerPos = multiBlockEntity.getController() - .offset(current.subtract(lastKnown)); - multiBlockEntity.setController(newControllerPos); - } - } - } } diff --git a/src/main/java/com/simibubi/create/foundation/render/AllInstanceTypes.java b/src/main/java/com/simibubi/create/foundation/render/AllInstanceTypes.java index 7d1b430bb..bda99f70a 100644 --- a/src/main/java/com/simibubi/create/foundation/render/AllInstanceTypes.java +++ b/src/main/java/com/simibubi/create/foundation/render/AllInstanceTypes.java @@ -49,7 +49,7 @@ public class AllInstanceTypes { MemoryUtil.memPutByte(ptr + 33, instance.rotationAxisY); MemoryUtil.memPutByte(ptr + 34, instance.rotationAxisZ); }) - .register(); + .build(); public static final InstanceType BELT = SimpleInstanceType.builder(BeltInstance::new) .cullShader(asResource("instance/cull/belt.glsl")) @@ -87,7 +87,7 @@ public class AllInstanceTypes { MemoryUtil.memPutFloat(ptr + 68, instance.maxV); MemoryUtil.memPutFloat(ptr + 72, instance.scrollMult); }) - .register(); + .build(); // TODO: use this for belts too public static final InstanceType SCROLLING = SimpleInstanceType.builder(ScrollInstance::new) @@ -121,7 +121,7 @@ public class AllInstanceTypes { MemoryUtil.memPutFloat(ptr + 56, instance.scaleU); MemoryUtil.memPutFloat(ptr + 60, instance.scaleV); }) - .register(); + .build(); public static final InstanceType ACTOR = SimpleInstanceType.builder(ActorInstance::new) .cullShader(asResource("instance/cull/actor.glsl")) @@ -151,7 +151,7 @@ public class AllInstanceTypes { MemoryUtil.memPutByte(ptr + 42, instance.rotationCenterZ); MemoryUtil.memPutFloat(ptr + 44, instance.speed); }) - .register(); + .build(); // TODO: remove public static final InstanceType FLAP = SimpleInstanceType.builder(FlapInstance::new) @@ -183,7 +183,7 @@ public class AllInstanceTypes { MemoryUtil.memPutFloat(ptr + 48, instance.flapScale); MemoryUtil.memPutFloat(ptr + 52, instance.flapness); }) - .register(); + .build(); public static void init() { // noop diff --git a/src/main/java/com/simibubi/create/foundation/render/ConditionalInstance.java b/src/main/java/com/simibubi/create/foundation/render/ConditionalInstance.java deleted file mode 100644 index c8c44b4c1..000000000 --- a/src/main/java/com/simibubi/create/foundation/render/ConditionalInstance.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.simibubi.create.foundation.render; - -import java.util.Optional; -import java.util.function.Consumer; - -import javax.annotation.Nullable; - -import dev.engine_room.flywheel.api.instance.Instance; -import dev.engine_room.flywheel.api.instance.Instancer; -import dev.engine_room.flywheel.lib.instance.AbstractInstance; - -public class ConditionalInstance { - - final Instancer model; - ICondition condition; - - Consumer setupFunc; - - @Nullable - private D instance; - - public ConditionalInstance(Instancer model) { - this.model = model; - this.condition = () -> true; - } - - public ConditionalInstance withSetupFunc(Consumer setupFunc) { - this.setupFunc = setupFunc; - return this; - } - - public ConditionalInstance withCondition(ICondition condition) { - this.condition = condition; - return this; - } - - public ConditionalInstance update() { - boolean shouldShow = condition.shouldShow(); - if (shouldShow && instance == null) { - instance = model.createInstance(); - if (setupFunc != null) setupFunc.accept(instance); - } else if (!shouldShow && instance != null) { - instance.delete(); - instance = null; - } - - return this; - } - - public Optional get() { - return Optional.ofNullable(instance); - } - - public void delete() { - if (instance != null) instance.delete(); - } - - public void forEach(Consumer consumer) { - if (instance != null) { - consumer.accept(instance); - } - } - - @FunctionalInterface - public interface ICondition { - boolean shouldShow(); - } -} diff --git a/src/main/java/com/simibubi/create/foundation/render/GroupInstance.java b/src/main/java/com/simibubi/create/foundation/render/GroupInstance.java deleted file mode 100644 index 00255bd77..000000000 --- a/src/main/java/com/simibubi/create/foundation/render/GroupInstance.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.simibubi.create.foundation.render; - -import java.util.AbstractCollection; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import dev.engine_room.flywheel.api.instance.Instancer; -import dev.engine_room.flywheel.lib.instance.AbstractInstance; - -public class GroupInstance extends AbstractCollection { - - final Instancer model; - final List backing; - - public GroupInstance(Instancer model) { - this.model = model; - - this.backing = new ArrayList<>(); - } - - public GroupInstance(Instancer model, int size) { - this.model = model; - - this.backing = new ArrayList<>(size); - - for (int i = 0; i < size; i++) { - addInstance(); - } - } - - /** - * @param count - * @return True if the number of elements changed. - */ - public boolean resize(int count) { - int size = size(); - if (count == size) return false; - - if (count <= 0) { - clear(); - return size > 0; - } - - if (count > size) { - for (int i = size; i < count; i++) { - addInstance(); - } - } else { - List unnecessary = backing.subList(count, size); - unnecessary.forEach(AbstractInstance::delete); - unnecessary.clear(); - } - - return true; - } - - public D addInstance() { - D instance = model.createInstance(); - backing.add(instance); - - return instance; - } - - public D get(int index) { - return backing.get(index); - } - - @Override - public Iterator iterator() { - return backing.iterator(); - } - - @Override - public int size() { - return backing.size(); - } - - @Override - public void clear() { - backing.forEach(AbstractInstance::delete); - backing.clear(); - } -} diff --git a/src/main/java/com/simibubi/create/foundation/render/RenderTypes.java b/src/main/java/com/simibubi/create/foundation/render/RenderTypes.java index d0acb2cc3..0c1f711cf 100644 --- a/src/main/java/com/simibubi/create/foundation/render/RenderTypes.java +++ b/src/main/java/com/simibubi/create/foundation/render/RenderTypes.java @@ -127,6 +127,19 @@ public class RenderTypes extends RenderStateShard { return ADDITIVE; } + public static BiFunction 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; } diff --git a/src/main/java/com/simibubi/create/foundation/render/SelectInstance.java b/src/main/java/com/simibubi/create/foundation/render/SelectInstance.java deleted file mode 100644 index f638146d8..000000000 --- a/src/main/java/com/simibubi/create/foundation/render/SelectInstance.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.simibubi.create.foundation.render; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.function.Consumer; - -import javax.annotation.Nullable; - -import dev.engine_room.flywheel.api.instance.Instance; -import dev.engine_room.flywheel.api.instance.Instancer; - -public class SelectInstance { - - final List> models; - - ModelSelector selector; - - private int last = -1; - @Nullable - private D current; - - public SelectInstance(ModelSelector selector) { - this.models = new ArrayList<>(); - this.selector = selector; - } - - public SelectInstance addModel(Instancer model) { - models.add(model); - return this; - } - - public SelectInstance update() { - int i = selector.modelIndexToShow(); - - if (i < 0 || i >= models.size()) { - if (current != null) { - current.handle().setDeleted(); - current = null; - } - } else if (i != last) { - if (current != null) current.handle().setDeleted(); - - current = models.get(i) - .createInstance(); - } - - last = i; - return this; - } - - public Optional get() { - return Optional.ofNullable(current); - } - - public void delete() { - if (current != null) current.handle().setDeleted(); - } - - public void forEach(Consumer consumer) { - if (current != null) { - consumer.accept(current); - } - } - - public interface ModelSelector { - int modelIndexToShow(); - } -} diff --git a/src/main/java/com/simibubi/create/foundation/render/VirtualRenderHelper.java b/src/main/java/com/simibubi/create/foundation/render/VirtualRenderHelper.java index 7099e537d..3223f503a 100644 --- a/src/main/java/com/simibubi/create/foundation/render/VirtualRenderHelper.java +++ b/src/main/java/com/simibubi/create/foundation/render/VirtualRenderHelper.java @@ -7,10 +7,10 @@ import org.jetbrains.annotations.Nullable; import com.mojang.blaze3d.vertex.PoseStack; import dev.engine_room.flywheel.api.model.Model; -import dev.engine_room.flywheel.lib.model.ModelCache; import dev.engine_room.flywheel.lib.model.ModelUtil; import dev.engine_room.flywheel.lib.model.baked.ForgeBakedModelBuilder; import dev.engine_room.flywheel.lib.model.baked.VirtualEmptyBlockGetter; +import dev.engine_room.flywheel.lib.util.ResourceReloadCache; import net.minecraft.client.renderer.block.BlockRenderDispatcher; import net.minecraft.client.renderer.block.ModelBlockRenderer; import net.minecraft.client.renderer.texture.OverlayTexture; @@ -25,7 +25,7 @@ public class VirtualRenderHelper { public static final ModelProperty VIRTUAL_PROPERTY = new ModelProperty<>(); public static final ModelData VIRTUAL_DATA = ModelData.builder().with(VIRTUAL_PROPERTY, true).build(); - private static final ModelCache VIRTUAL_BLOCKS = new ModelCache<>(state -> new ForgeBakedModelBuilder(ModelUtil.VANILLA_RENDERER.getBlockModel(state)).modelData(VIRTUAL_DATA).build()); + private static final ResourceReloadCache VIRTUAL_BLOCKS = new ResourceReloadCache<>(state -> new ForgeBakedModelBuilder(ModelUtil.VANILLA_RENDERER.getBlockModel(state)).modelData(VIRTUAL_DATA).build()); private static final ThreadLocal THREAD_LOCAL_OBJECTS = ThreadLocal.withInitial(ThreadLocalObjects::new); public static boolean isVirtual(ModelData data) { diff --git a/src/main/java/com/simibubi/create/foundation/utility/BlockHelper.java b/src/main/java/com/simibubi/create/foundation/utility/BlockHelper.java index c8f0c8558..2a3c7969f 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/BlockHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/BlockHelper.java @@ -1,5 +1,6 @@ package com.simibubi.create.foundation.utility; +import java.util.List; import java.util.function.Consumer; import javax.annotation.Nullable; @@ -12,6 +13,7 @@ import com.simibubi.create.content.kinetics.base.KineticBlockEntity; import com.simibubi.create.content.processing.burner.BlazeBurnerBlock; import com.simibubi.create.content.processing.burner.BlazeBurnerBlock.HeatLevel; import com.simibubi.create.foundation.blockEntity.IMergeableBE; +import com.simibubi.create.foundation.blockEntity.IMultiBlockEntityContainer; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -19,6 +21,7 @@ import net.minecraft.core.SectionPos; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; @@ -43,6 +46,8 @@ import net.minecraft.world.level.block.SlimeBlock; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.IntegerProperty; import net.minecraft.world.level.block.state.properties.Property; import net.minecraft.world.level.block.state.properties.SlabType; import net.minecraft.world.level.chunk.LevelChunk; @@ -53,6 +58,24 @@ import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.level.BlockEvent; public class BlockHelper { + private static final List COUNT_STATES = List.of( + BlockStateProperties.EGGS, + BlockStateProperties.PICKLES, + BlockStateProperties.CANDLES + ); + + private static final List VINELIKE_BLOCKS = List.of( + Blocks.VINE, Blocks.GLOW_LICHEN + ); + + private static final List VINELIKE_STATES = List.of( + BlockStateProperties.UP, + BlockStateProperties.NORTH, + BlockStateProperties.EAST, + BlockStateProperties.SOUTH, + BlockStateProperties.WEST, + BlockStateProperties.DOWN + ); public static BlockState setZeroAge(BlockState blockState) { if (blockState.hasProperty(BlockStateProperties.AGE_1)) @@ -94,11 +117,21 @@ public class BlockHelper { if (needsTwo) amount *= 2; - if (block.hasProperty(BlockStateProperties.EGGS)) - amount *= block.getValue(BlockStateProperties.EGGS); + for (IntegerProperty property : COUNT_STATES) + if (block.hasProperty(property)) + amount *= block.getValue(property); - if (block.hasProperty(BlockStateProperties.PICKLES)) - amount *= block.getValue(BlockStateProperties.PICKLES); + if (VINELIKE_BLOCKS.contains(block.getBlock())) { + int vineCount = 0; + + for (BooleanProperty vineState : VINELIKE_STATES) { + if (block.hasProperty(vineState) && block.getValue(vineState)) { + vineCount++; + } + } + + amount += vineCount - 1; + } { // Try held Item first @@ -241,17 +274,17 @@ public class BlockHelper { CompoundTag data = null; if (blockEntity == null) return data; - + if (AllBlockTags.SAFE_NBT.matches(blockState)) { data = blockEntity.saveWithFullMetadata(); - + } else if (blockEntity instanceof IPartialSafeNBT) { data = new CompoundTag(); ((IPartialSafeNBT) blockEntity).writeSafe(data); - + } else if (Mods.FRAMEDBLOCKS.contains(blockState.getBlock())) data = FramedBlocksInSchematics.prepareBlockEntityData(blockState, blockEntity); - + return NBTProcessors.process(blockState, blockEntity, data, true); } @@ -312,8 +345,11 @@ public class BlockHelper { data.putInt("x", target.getX()); data.putInt("y", target.getY()); data.putInt("z", target.getZ()); - if (blockEntity instanceof KineticBlockEntity) - ((KineticBlockEntity) blockEntity).warnOfMovement(); + if (blockEntity instanceof KineticBlockEntity kbe) + kbe.warnOfMovement(); + if (blockEntity instanceof IMultiBlockEntityContainer imbe) + if (!imbe.isController()) + data.put("Controller", NbtUtils.writeBlockPos(imbe.getController())); blockEntity.load(data); } } diff --git a/src/main/java/com/simibubi/create/foundation/utility/Couple.java b/src/main/java/com/simibubi/create/foundation/utility/Couple.java index 608ab696c..4af598c24 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/Couple.java +++ b/src/main/java/com/simibubi/create/foundation/utility/Couple.java @@ -55,6 +55,10 @@ public class Couple extends Pair implements Iterable { return Couple.create(function.apply(first), function.apply(second)); } + public Couple mapNotNull(Function function) { + return Couple.create(first != null ? function.apply(first) : null, second != null ? function.apply(second) : null); + } + public Couple mapWithContext(BiFunction function) { return Couple.create(function.apply(first, true), function.apply(second, false)); } diff --git a/src/main/java/com/simibubi/create/foundation/utility/DyeHelper.java b/src/main/java/com/simibubi/create/foundation/utility/DyeHelper.java index b9d690b98..eb88fac80 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/DyeHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/DyeHelper.java @@ -1,8 +1,8 @@ package com.simibubi.create.foundation.utility; +import java.util.HashMap; import java.util.Map; - -import com.google.common.collect.ImmutableMap; +import java.util.function.Supplier; import net.minecraft.world.item.DyeColor; import net.minecraft.world.level.ItemLike; @@ -11,66 +11,53 @@ import net.minecraft.world.level.block.Blocks; public class DyeHelper { public static ItemLike getWoolOfDye(DyeColor color) { - switch (color) { - case BLACK: - return Blocks.BLACK_WOOL; - case BLUE: - return Blocks.BLUE_WOOL; - case BROWN: - return Blocks.BROWN_WOOL; - case CYAN: - return Blocks.CYAN_WOOL; - case GRAY: - return Blocks.GRAY_WOOL; - case GREEN: - return Blocks.GREEN_WOOL; - case LIGHT_BLUE: - return Blocks.LIGHT_BLUE_WOOL; - case LIGHT_GRAY: - return Blocks.LIGHT_GRAY_WOOL; - case LIME: - return Blocks.LIME_WOOL; - case MAGENTA: - return Blocks.MAGENTA_WOOL; - case ORANGE: - return Blocks.ORANGE_WOOL; - case PINK: - return Blocks.PINK_WOOL; - case PURPLE: - return Blocks.PURPLE_WOOL; - case RED: - return Blocks.RED_WOOL; - case YELLOW: - return Blocks.YELLOW_WOOL; - case WHITE: - default: - return Blocks.WHITE_WOOL; - } + return WOOL_TABLE.getOrDefault(color, () -> Blocks.WHITE_WOOL).get(); } - public static final Map> DYE_TABLE = new ImmutableMap.Builder>() - - // DyeColor, ( Front RGB, Back RGB ) - .put(DyeColor.BLACK, Couple.create(0x45403B, 0x21201F)) - .put(DyeColor.RED, Couple.create(0xB13937, 0x632737)) - .put(DyeColor.GREEN, Couple.create(0x208A46, 0x1D6045)) - .put(DyeColor.BROWN, Couple.create(0xAC855C, 0x68533E)) - - .put(DyeColor.BLUE, Couple.create(0x5391E1, 0x504B90)) - .put(DyeColor.GRAY, Couple.create(0x5D666F, 0x313538)) - .put(DyeColor.LIGHT_GRAY, Couple.create(0x95969B, 0x707070)) - .put(DyeColor.PURPLE, Couple.create(0x9F54AE, 0x63366C)) - - .put(DyeColor.CYAN, Couple.create(0x3EABB4, 0x3C7872)) - .put(DyeColor.PINK, Couple.create(0xD5A8CB, 0xB86B95)) - .put(DyeColor.LIME, Couple.create(0xA3DF55, 0x4FB16F)) - .put(DyeColor.YELLOW, Couple.create(0xE6D756, 0xE9AC29)) - - .put(DyeColor.LIGHT_BLUE, Couple.create(0x69CED2, 0x508AA5)) - .put(DyeColor.ORANGE, Couple.create(0xEE9246, 0xD94927)) - .put(DyeColor.MAGENTA, Couple.create(0xF062B0, 0xC04488)) - .put(DyeColor.WHITE, Couple.create(0xEDEAE5, 0xBBB6B0)) - - .build(); + public static Couple getDyeColors(DyeColor color){ + return DYE_TABLE.getOrDefault(color, DYE_TABLE.get(DyeColor.WHITE)); + } + /** + * Adds a dye color s.t. Create's blocks can use it instead of defaulting to white. + * @param color Dye color to add + * @param brightColor Front (bright) RGB color + * @param darkColor Back (dark) RGB color + * @param wool Supplier of wool item/block corresponding to the color + */ + public static void addDye(DyeColor color, Integer brightColor, Integer darkColor, Supplier wool){ + DYE_TABLE.put(color, Couple.create(brightColor, darkColor)); + WOOL_TABLE.put(color, wool); + } + + private static void addDye(DyeColor color, Integer brightColor, Integer darkColor, ItemLike wool){ + addDye(color, brightColor, darkColor, () -> wool); + } + + private static final Map> WOOL_TABLE = new HashMap<>(); + + private static final Map> DYE_TABLE = new HashMap<>(); + + static { + // DyeColor, ( Front RGB, Back RGB ) + addDye(DyeColor.BLACK, 0x45403B, 0x21201F, Blocks.BLACK_WOOL); + addDye(DyeColor.RED, 0xB13937, 0x632737, Blocks.RED_WOOL); + addDye(DyeColor.GREEN, 0x208A46, 0x1D6045, Blocks.GREEN_WOOL); + addDye(DyeColor.BROWN, 0xAC855C, 0x68533E, Blocks.BROWN_WOOL); + + addDye(DyeColor.BLUE, 0x5391E1, 0x504B90, Blocks.BLUE_WOOL); + addDye(DyeColor.GRAY, 0x5D666F, 0x313538, Blocks.GRAY_WOOL); + addDye(DyeColor.LIGHT_GRAY, 0x95969B, 0x707070, Blocks.LIGHT_GRAY_WOOL); + addDye(DyeColor.PURPLE, 0x9F54AE, 0x63366C, Blocks.PURPLE_WOOL); + + addDye(DyeColor.CYAN, 0x3EABB4, 0x3C7872, Blocks.CYAN_WOOL); + addDye(DyeColor.PINK, 0xD5A8CB, 0xB86B95, Blocks.PINK_WOOL); + addDye(DyeColor.LIME, 0xA3DF55, 0x4FB16F, Blocks.LIME_WOOL); + addDye(DyeColor.YELLOW, 0xE6D756, 0xE9AC29, Blocks.YELLOW_WOOL); + + addDye(DyeColor.LIGHT_BLUE, 0x69CED2, 0x508AA5, Blocks.LIGHT_BLUE_WOOL); + addDye(DyeColor.ORANGE, 0xEE9246, 0xD94927, Blocks.ORANGE_WOOL); + addDye(DyeColor.MAGENTA, 0xF062B0, 0xC04488, Blocks.MAGENTA_WOOL); + addDye(DyeColor.WHITE, 0xEDEAE5, 0xBBB6B0, Blocks.WHITE_WOOL); + } } diff --git a/src/main/java/com/simibubi/create/foundation/utility/NBTProcessors.java b/src/main/java/com/simibubi/create/foundation/utility/NBTProcessors.java index 4496e5a27..d23f57e89 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/NBTProcessors.java +++ b/src/main/java/com/simibubi/create/foundation/utility/NBTProcessors.java @@ -59,8 +59,26 @@ public final class NBTProcessors { }); addProcessor(AllBlockEntityTypes.CREATIVE_CRATE.get(), itemProcessor("Filter")); addProcessor(AllBlockEntityTypes.PLACARD.get(), itemProcessor("Item")); + addProcessor(AllBlockEntityTypes.CLIPBOARD.get(), data -> { + if (!data.contains("Item", Tag.TAG_COMPOUND)) + return data; + CompoundTag book = data.getCompound("Item"); + + if (!book.contains("tag", Tag.TAG_COMPOUND)) + return data; + CompoundTag itemData = book.getCompound("tag"); + + for (List entries : NBTHelper.readCompoundList(itemData.getList("Pages", Tag.TAG_COMPOUND), + pageTag -> NBTHelper.readCompoundList(pageTag.getList("Entries", Tag.TAG_COMPOUND), + tag -> tag.getString("Text")))) { + for (String entry : entries) + if (textComponentHasClickEvent(entry)) + return null; + } + return data; + }); } - + // Triggered by block tag, not BE type private static final UnaryOperator signProcessor = data -> { for (String key : List.of("front_text", "back_text")) { @@ -72,6 +90,8 @@ public final class NBTProcessors { if (textComponentHasClickEvent(stringTag.getAsString())) return null; } + if (data.contains("front_item") || data.contains("back_item")) + return null; // "Amendments" compat: sign data contains itemstacks return data; }; @@ -94,14 +114,22 @@ public final class NBTProcessors { } public static ItemStack withUnsafeNBTDiscarded(ItemStack stack) { - if (stack.getTag() == null) + CompoundTag tag = stack.getTag(); + if (tag == null) return stack; ItemStack copy = stack.copy(); - stack.getTag() - .getAllKeys() + copy.setTag(withUnsafeNBTDiscarded(tag)); + return copy; + } + + public static CompoundTag withUnsafeNBTDiscarded(CompoundTag tag) { + if (tag == null) + return null; + CompoundTag copy = tag.copy(); + tag.getAllKeys() .stream() .filter(NBTProcessors::isUnsafeItemNBTKey) - .forEach(copy::removeTagKey); + .forEach(copy::remove); return copy; } @@ -120,7 +148,13 @@ public final class NBTProcessors { } public static boolean textComponentHasClickEvent(String json) { - Component component = Component.Serializer.fromJson(json.isEmpty() ? "\"\"" : json); + return textComponentHasClickEvent(Component.Serializer.fromJson(json.isEmpty() ? "\"\"" : json)); + } + + public static boolean textComponentHasClickEvent(Component component) { + for (Component sibling : component.getSiblings()) + if (textComponentHasClickEvent(sibling)) + return true; return component != null && component.getStyle() != null && component.getStyle() .getClickEvent() != null; } diff --git a/src/main/java/com/simibubi/create/infrastructure/config/CClient.java b/src/main/java/com/simibubi/create/infrastructure/config/CClient.java index a25381f6b..fcd4af344 100644 --- a/src/main/java/com/simibubi/create/infrastructure/config/CClient.java +++ b/src/main/java/com/simibubi/create/infrastructure/config/CClient.java @@ -88,6 +88,10 @@ public class CClient extends ConfigBase { public final ConfigFloat mountedZoomMultiplier = f(3, 0, "mountedZoomMultiplier", Comments.mountedZoomMultiplier); public final ConfigBool showTrackGraphOnF3 = b(false, "showTrackGraphOnF3", Comments.showTrackGraphOnF3); public final ConfigBool showExtendedTrackGraphOnF3 = b(false, "showExtendedTrackGraphOnF3", Comments.showExtendedTrackGraphOnF3); + public final ConfigBool showTrainMapOverlay = b(true, "showTrainMapOverlay", Comments.showTrainMapOverlay); + public final ConfigBool trainMapOverlay = b(true, "showTrainMapOverlay", Comments.showTrainMapOverlay); + public final ConfigEnum trainMapColorTheme = + e(TrainMapTheme.RED, "trainMapColorTheme", Comments.trainMapColorTheme); @Override public String getName() { @@ -97,6 +101,10 @@ public class CClient extends ConfigBase { public enum PlacementIndicatorSetting { TEXTURE, TRIANGLE, NONE } + + public enum TrainMapTheme { + RED, GREY, WHITE + } private static class Comments { static String client = "Client-only settings - If you're looking for general settings, look inside your worlds serverconfig folder!"; @@ -157,6 +165,8 @@ public class CClient extends ConfigBase { static String ambientVolumeCap = "Maximum volume modifier of Ambient noise"; static String trains = "Railway related settings"; + static String showTrainMapOverlay = "Display Track Networks and Trains on supported map mods"; + static String trainMapColorTheme = "Track Network Color on maps"; static String mountedZoomMultiplier = "How far away the Camera should zoom when seated on a train"; static String showTrackGraphOnF3 = "Display nodes and edges of a Railway Network while f3 debug mode is active"; static String showExtendedTrackGraphOnF3 = "Additionally display materials of a Rail Network while f3 debug mode is active"; diff --git a/src/main/java/com/simibubi/create/infrastructure/debugInfo/ServerDebugInfoPacket.java b/src/main/java/com/simibubi/create/infrastructure/debugInfo/ServerDebugInfoPacket.java index 8b8d0f97b..f038bfd5e 100644 --- a/src/main/java/com/simibubi/create/infrastructure/debugInfo/ServerDebugInfoPacket.java +++ b/src/main/java/com/simibubi/create/infrastructure/debugInfo/ServerDebugInfoPacket.java @@ -84,7 +84,7 @@ public class ServerDebugInfoPacket extends SimplePacketBase { String text = output.toString(); Minecraft.getInstance().keyboardHandler.setClipboard(text); Lang.translate("command.debuginfo.saved_to_clipboard") - .color(DyeHelper.DYE_TABLE.get(DyeColor.LIME) + .color(DyeHelper.getDyeColors(DyeColor.LIME) .getFirst()) .sendChat(player); } diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index b2b5841cf..b84c313c9 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -19,7 +19,7 @@ Technology that empowers the player.''' [[dependencies.create]] modId="forge" mandatory=true - versionRange="[47.0.0,)" + versionRange="[47.1.3,)" ordering="NONE" side="BOTH" diff --git a/src/main/resources/assets/create/lang/default/interface.json b/src/main/resources/assets/create/lang/default/interface.json index 5214ce073..044e4d5f7 100644 --- a/src/main/resources/assets/create/lang/default/interface.json +++ b/src/main/resources/assets/create/lang/default/interface.json @@ -790,6 +790,7 @@ "create.station.cancel": "Cancel Assembly", "create.station.failed": "Assembly Failed", "create.station.icon_type": "Icon Type", + "create.station.train_map_color": "Color on Maps", "create.station.create_train": "Create new Train", "create.station.assemble_train": "Assemble Train", "create.station.disassemble_train": "Disassemble Train", @@ -810,6 +811,22 @@ "create.station.how_to_1": "Remove bogeys by breaking the block on top.", "create.station.how_to_2": "Build carriages attached to one or two bogeys each.", + "create.train_map.toggle": "Train network overlay", + "create.train_map.train_owned_by": "by %1$s", + "create.train_map.conductor_missing": " Conductor Missing", + "create.train_map.derailed": " Derailed", + "create.train_map.navigation_failed": " Navigation Failed", + "create.train_map.schedule_interrupted": " Schedule Interrupted", + "create.train_map.player_controlled": " -> Controlled by Player", + "create.train_map.train_at_station": " >| %1$s", + "create.train_map.train_moving_to_station": " >> %1$s (%2$sm)", + "create.train_map.waiting_at_signal": " Waiting at Signal", + "create.train_map.redstone_powered": " Redstone Powered", + "create.train_map.for_other_train": " for %1$s", + "create.train_map.cannot_traverse_section": " Cannot fully traverse", + "create.train_map.section_reserved": " Section reserved", + "create.train_map.fuel_boosted": " Fuel boosted \u2714", + "create.train_assembly.too_many_bogeys": "Too many Bogeys attached: %1$s", "create.train_assembly.frontmost_bogey_at_station": "Frontmost Bogey must be at Station Marker", "create.train_assembly.no_bogeys": "No Bogeys Found", diff --git a/src/main/resources/assets/create/textures/gui/trainmap_sprite_sheet.png b/src/main/resources/assets/create/textures/gui/trainmap_sprite_sheet.png new file mode 100644 index 000000000..f981e2c68 Binary files /dev/null and b/src/main/resources/assets/create/textures/gui/trainmap_sprite_sheet.png differ diff --git a/src/main/resources/assets/create/textures/gui/widgets.png b/src/main/resources/assets/create/textures/gui/widgets.png index cc8cf5bef..db162967d 100644 Binary files a/src/main/resources/assets/create/textures/gui/widgets.png and b/src/main/resources/assets/create/textures/gui/widgets.png differ diff --git a/src/main/resources/create.mixins.json b/src/main/resources/create.mixins.json index 30f722885..9a6738925 100644 --- a/src/main/resources/create.mixins.json +++ b/src/main/resources/create.mixins.json @@ -5,6 +5,7 @@ "package": "com.simibubi.create.foundation.mixin", "compatibilityLevel": "JAVA_17", "refmap": "create.refmap.json", + "plugin": "com.simibubi.create.foundation.mixin.CreateMixinPlugin", "mixins": [ "BlockItemMixin", "ClientboundMapItemDataPacketMixin", @@ -14,6 +15,7 @@ "LavaSwimmingMixin", "MainMixin", "MapItemSavedDataMixin", + "SmithingMenuMixin", "TestCommandMixin", "WaterWheelFluidSpreadMixin", "accessor.AbstractProjectileDispenseBehaviorAccessor", @@ -45,7 +47,8 @@ "client.LevelRendererMixin", "client.MapRendererMapInstanceMixin", "client.PlayerRendererMixin", - "client.WindowResizeMixin" + "client.WindowResizeMixin", + "compat.JourneyFullscreenMapMixin" ], "injectors": { "defaultRequire": 1