From cf308cdc7f9c783ea9af6ba04b1aceeedfd28d6d Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Tue, 22 Feb 2022 19:41:30 +0100 Subject: [PATCH] Steamy - Fluid tanks become boilers when engines are attached - Added the steam engine - Some tweaks and fixes to girder connectivity --- src/generated/resources/.cache/cache | 43 +-- .../create/blockstates/powered_shaft.json | 17 + .../create/blockstates/steam_engine.json | 110 +++++++ .../resources/assets/create/lang/en_ud.json | 2 + .../resources/assets/create/lang/en_us.json | 2 + .../assets/create/lang/unfinished/de_de.json | 4 +- .../assets/create/lang/unfinished/es_cl.json | 4 +- .../assets/create/lang/unfinished/es_es.json | 4 +- .../assets/create/lang/unfinished/fr_fr.json | 4 +- .../assets/create/lang/unfinished/it_it.json | 4 +- .../assets/create/lang/unfinished/ja_jp.json | 4 +- .../assets/create/lang/unfinished/ko_kr.json | 4 +- .../assets/create/lang/unfinished/nl_nl.json | 4 +- .../assets/create/lang/unfinished/pl_pl.json | 4 +- .../assets/create/lang/unfinished/pt_br.json | 4 +- .../assets/create/lang/unfinished/pt_pt.json | 4 +- .../assets/create/lang/unfinished/ru_ru.json | 4 +- .../assets/create/lang/unfinished/zh_cn.json | 4 +- .../assets/create/lang/unfinished/zh_tw.json | 4 +- .../create/models/item/steam_engine.json | 3 + .../data/create/advancements/aesthetics.json | 4 +- .../loot_tables/blocks/powered_shaft.json | 20 ++ .../loot_tables/blocks/steam_engine.json | 20 ++ .../tags/blocks/active_boiler_heaters.json | 8 + .../tags/blocks/passive_boiler_heaters.json | 6 + .../tags/blocks/mineable/pickaxe.json | 2 + .../com/simibubi/create/AllBlockPartials.java | 5 + .../java/com/simibubi/create/AllBlocks.java | 22 +- .../com/simibubi/create/AllParticleTypes.java | 2 + .../java/com/simibubi/create/AllShapes.java | 10 + .../java/com/simibubi/create/AllTags.java | 15 +- .../com/simibubi/create/AllTileEntities.java | 16 + .../contraptions/base/KineticTileEntity.java | 4 + .../base/KineticTileEntityRenderer.java | 4 +- .../base/KineticTileInstance.java | 2 +- .../components/steam/PoweredShaftBlock.java | 80 +++++ .../steam/PoweredShaftTileEntity.java | 77 +++++ .../components/steam/SteamEngineBlock.java | 153 +++++++++ .../components/steam/SteamEngineRenderer.java | 81 +++++ .../steam/SteamEngineTileEntity.java | 196 +++++++++++ .../components/steam/SteamJetParticle.java | 117 +++++++ .../steam/SteamJetParticleData.java | 82 +++++ .../structureMovement/Contraption.java | 2 +- .../MountedFluidStorage.java | 13 +- .../fluids/pipes/BracketBlock.java | 4 +- .../contraptions/fluids/tank/BoilerData.java | 306 ++++++++++++++++++ .../fluids/tank/BoilerHeaters.java | 39 +++ .../fluids/tank/FluidTankBlock.java | 23 +- .../tank/FluidTankConnectivityHandler.java | 11 +- .../fluids/tank/FluidTankRenderer.java | 58 +++- .../fluids/tank/FluidTankTileEntity.java | 83 +++-- .../relays/belt/item/BeltConnectorItem.java | 6 +- .../relays/elementary/AbstractShaftBlock.java | 62 +--- .../elementary/AbstractSimpleShaftBlock.java | 63 ++++ .../BracketedKineticTileEntity.java | 2 +- .../relays/elementary/CogWheelBlock.java | 2 +- .../relays/elementary/ShaftBlock.java | 16 +- .../curiosities/girder/GirderBlock.java | 63 ++-- .../schematics/block/LaunchedItem.java | 4 +- .../block/SchematicannonTileEntity.java | 4 +- .../behaviour/ValueBoxRenderer.java | 4 +- .../utility/animation/LerpedFloat.java | 4 + .../create/models/block/powered_shaft.json | 42 +++ .../block/steam_engine/Steam Piston.bbmodel | 1 + .../models/block/steam_engine/block.json | 63 ++++ .../models/block/steam_engine/gauge.json | 37 +++ .../models/block/steam_engine/item.json | 157 +++++++++ .../models/block/steam_engine/linkage.json | 51 +++ .../models/block/steam_engine/piston.json | 28 ++ .../block/steam_engine/shaft_connector.json | 68 ++++ .../assets/create/particles/steam_jet.json | 27 ++ .../create/textures/block/boiler_gauge.png | Bin 0 -> 360 bytes .../create/textures/block/cam_linkage.png | Bin 0 -> 1454 bytes .../assets/create/textures/block/engine.png | Bin 0 -> 9791 bytes .../create/textures/particle/steam_jet_0.png | Bin 0 -> 126 bytes .../create/textures/particle/steam_jet_1.png | Bin 0 -> 131 bytes .../create/textures/particle/steam_jet_10.png | Bin 0 -> 208 bytes .../create/textures/particle/steam_jet_11.png | Bin 0 -> 202 bytes .../create/textures/particle/steam_jet_12.png | Bin 0 -> 177 bytes .../create/textures/particle/steam_jet_13.png | Bin 0 -> 190 bytes .../create/textures/particle/steam_jet_14.png | Bin 0 -> 201 bytes .../create/textures/particle/steam_jet_15.png | Bin 0 -> 202 bytes .../create/textures/particle/steam_jet_16.png | Bin 0 -> 205 bytes .../create/textures/particle/steam_jet_17.png | Bin 0 -> 204 bytes .../create/textures/particle/steam_jet_18.png | Bin 0 -> 200 bytes .../create/textures/particle/steam_jet_19.png | Bin 0 -> 192 bytes .../create/textures/particle/steam_jet_2.png | Bin 0 -> 140 bytes .../create/textures/particle/steam_jet_20.png | Bin 0 -> 178 bytes .../create/textures/particle/steam_jet_21.png | Bin 0 -> 159 bytes .../create/textures/particle/steam_jet_22.png | Bin 0 -> 139 bytes .../create/textures/particle/steam_jet_3.png | Bin 0 -> 156 bytes .../create/textures/particle/steam_jet_4.png | Bin 0 -> 164 bytes .../create/textures/particle/steam_jet_5.png | Bin 0 -> 179 bytes .../create/textures/particle/steam_jet_6.png | Bin 0 -> 193 bytes .../create/textures/particle/steam_jet_7.png | Bin 0 -> 195 bytes .../create/textures/particle/steam_jet_8.png | Bin 0 -> 200 bytes .../create/textures/particle/steam_jet_9.png | Bin 0 -> 203 bytes 97 files changed, 2221 insertions(+), 181 deletions(-) create mode 100644 src/generated/resources/assets/create/blockstates/powered_shaft.json create mode 100644 src/generated/resources/assets/create/blockstates/steam_engine.json create mode 100644 src/generated/resources/assets/create/models/item/steam_engine.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/powered_shaft.json create mode 100644 src/generated/resources/data/create/loot_tables/blocks/steam_engine.json create mode 100644 src/generated/resources/data/create/tags/blocks/active_boiler_heaters.json create mode 100644 src/generated/resources/data/create/tags/blocks/passive_boiler_heaters.json create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/steam/PoweredShaftBlock.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/steam/PoweredShaftTileEntity.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamEngineBlock.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamEngineRenderer.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamEngineTileEntity.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamJetParticle.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamJetParticleData.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/fluids/tank/BoilerData.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/fluids/tank/BoilerHeaters.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/relays/elementary/AbstractSimpleShaftBlock.java create mode 100644 src/main/resources/assets/create/models/block/powered_shaft.json create mode 100644 src/main/resources/assets/create/models/block/steam_engine/Steam Piston.bbmodel create mode 100644 src/main/resources/assets/create/models/block/steam_engine/block.json create mode 100644 src/main/resources/assets/create/models/block/steam_engine/gauge.json create mode 100644 src/main/resources/assets/create/models/block/steam_engine/item.json create mode 100644 src/main/resources/assets/create/models/block/steam_engine/linkage.json create mode 100644 src/main/resources/assets/create/models/block/steam_engine/piston.json create mode 100644 src/main/resources/assets/create/models/block/steam_engine/shaft_connector.json create mode 100644 src/main/resources/assets/create/particles/steam_jet.json create mode 100644 src/main/resources/assets/create/textures/block/boiler_gauge.png create mode 100644 src/main/resources/assets/create/textures/block/cam_linkage.png create mode 100644 src/main/resources/assets/create/textures/block/engine.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_0.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_1.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_10.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_11.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_12.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_13.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_14.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_15.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_16.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_17.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_18.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_19.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_2.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_20.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_21.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_22.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_3.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_4.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_5.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_6.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_7.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_8.png create mode 100644 src/main/resources/assets/create/textures/particle/steam_jet_9.png diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index c5d5a2641..1df7bdd36 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -379,6 +379,7 @@ bc91f1cbdf0c2f9867edb36652bda43aa614e414 assets/create/blockstates/polished_cut_ 3bb571d0a2597907bf3a30686b4bfa0841ac990a assets/create/blockstates/portable_fluid_interface.json 1b70b4e5792dccd2110b84e209016ac258005e28 assets/create/blockstates/portable_storage_interface.json 8296d43d5f1c2113012d127038fb319af83aaee4 assets/create/blockstates/powered_latch.json +c650bece9b333daba3174f944e6ebd41a010c850 assets/create/blockstates/powered_shaft.json e8b0a401c10d1ba67ed71ba31bd5f9bc28571b65 assets/create/blockstates/powered_toggle_latch.json 3a739f9d4276828d83f2d2750bf3227c87bcd438 assets/create/blockstates/pulley_magnet.json dee3cdef860bb92d439ecaaec4300b42208b025c assets/create/blockstates/pulse_extender.json @@ -475,6 +476,7 @@ e815bfd854c2653f10828bb11950f7fb991d7efc assets/create/blockstates/speedometer.j 1cb7cdbefa0ff199263782809287854b9d85074c assets/create/blockstates/spout.json d62b7908119fa4f51715a186d0882b388bb25cab assets/create/blockstates/spruce_window.json 8d7dfa60630a8b4bae4e8eca5c66e1cfa34dda1f assets/create/blockstates/spruce_window_pane.json +0378b27d9ad698b37d72cd958e15112f9ca418d3 assets/create/blockstates/steam_engine.json 5d7385d28a23dcfc95a221d36d82337908582726 assets/create/blockstates/sticker.json 3d93eabbb327aecc526beae9c62283f1d43eb710 assets/create/blockstates/sticky_mechanical_piston.json f385988cb6fa9c48b5d59a6942ec50ed2b60c8bf assets/create/blockstates/stockpile_switch.json @@ -538,22 +540,22 @@ bf2b0310500213ff853c748c236eb5d01f61658e assets/create/blockstates/yellow_toolbo 6801fa1f466f172700e573e5b8ee8ee5f9ca4583 assets/create/blockstates/yellow_valve_handle.json 7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json -8d5cb91338bccfa4f3acfd048b28e08acc9a82b7 assets/create/lang/en_ud.json -4a5c5a6f4677bf4f6fe40acfe93bda03ea5568e0 assets/create/lang/en_us.json -645c1f48d82161f920bda0cff4bfe9e46aba6416 assets/create/lang/unfinished/de_de.json -9aeeaff96624e945cf0018b36b7a817169001ef2 assets/create/lang/unfinished/es_cl.json -34dbc3806e178e33ea35fdad0f018ff5b8dfccd0 assets/create/lang/unfinished/es_es.json -8e054f9fc4c1b937f9b35c87c0d13aac09e175df assets/create/lang/unfinished/fr_fr.json -35492c408d1abdf11ef9f82fd4eb4444e467575e assets/create/lang/unfinished/it_it.json -e1176e97d402311c798f1e5bdd0fc86b2fe230f2 assets/create/lang/unfinished/ja_jp.json -dbf8fee3b62bfac529cd15ce324b52ce62d79a3e assets/create/lang/unfinished/ko_kr.json -4a7baacd9fa0112b5a2c82670e46ce27e4ebfaa9 assets/create/lang/unfinished/nl_nl.json -68bb201f1e6b5d549dd0da5eecf5bd93279fc51b assets/create/lang/unfinished/pl_pl.json -23717bc699dbb33f3b1b7c1ea256eaa3d2351f17 assets/create/lang/unfinished/pt_br.json -b6477a01032733848b11b3f669b44bf7a67f6512 assets/create/lang/unfinished/pt_pt.json -58a008a6683a807b3e52afaa536821fee82e7700 assets/create/lang/unfinished/ru_ru.json -7123ac611ea8c2ce7a100c09a2f7213bead8bb35 assets/create/lang/unfinished/zh_cn.json -42a371f8007daa1101b8664c96ace6ba9eb2188f assets/create/lang/unfinished/zh_tw.json +255e47ab7894ba35851a2f34c82be3dc9c9e8784 assets/create/lang/en_ud.json +3610238d5807c0d4f04a7632a871487ba8cc2c1f assets/create/lang/en_us.json +6a67c98238de2e57b5f2b36b3e988e70616c2ab0 assets/create/lang/unfinished/de_de.json +f9cb3ca070daff2503223de083c95e7e176b10fd assets/create/lang/unfinished/es_cl.json +35bb65eb644b10adbf55bc03913db056bc88f32c assets/create/lang/unfinished/es_es.json +9e7c2ea229f44ff57fc7ba2bc6f94638d2a68af0 assets/create/lang/unfinished/fr_fr.json +0e4bc37cd97dd28107593eb11d936101a2a3ebb6 assets/create/lang/unfinished/it_it.json +11034cb1b7e049c403f4a1e4774c2e1611af5b10 assets/create/lang/unfinished/ja_jp.json +626ef47b3ee504f922b6fa7cde416ae284f22236 assets/create/lang/unfinished/ko_kr.json +1025d8531ada9f4a521aba15a153de59a3bfd596 assets/create/lang/unfinished/nl_nl.json +4113a74ef44f7c30285b578eea239fee70646702 assets/create/lang/unfinished/pl_pl.json +ecb8680bae4a7ce8c6e7f1ae45f74992a6f152a6 assets/create/lang/unfinished/pt_br.json +db520fa1663bbecea9e39a1acfa6514740e74445 assets/create/lang/unfinished/pt_pt.json +718e9841f70866b4fbbe397f8fdd1600e2c044a8 assets/create/lang/unfinished/ru_ru.json +c8094e8ebf65b51fe1156955e2968709543c0592 assets/create/lang/unfinished/zh_cn.json +949a8d2f792ff994dbe2339dda5d08543d62fd55 assets/create/lang/unfinished/zh_tw.json 487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.json 3066db1bf03cffa1a9c7fbacf47ae586632f4eb3 assets/create/models/block/acacia_window_pane_noside_alt.json @@ -2069,6 +2071,7 @@ d6fb0d38b1b5bcc199b52ac8889eaecd167f6725 assets/create/models/item/speedometer.j b9abe1331d49871838231f3a8e5d2973634e9325 assets/create/models/item/spout.json b305e81f1dc5272634745b6e822af40955a2ef28 assets/create/models/item/spruce_window.json f3ec8df2ee1690353ae1ec687b822d0fd962160e assets/create/models/item/spruce_window_pane.json +6c0693011f4104999c03328ba5e3bb25ffcf6359 assets/create/models/item/steam_engine.json bb546e5342c6d1a6b4040cf7ccdd2f10c6f79965 assets/create/models/item/sticker.json 891abc24593d53d282773eca5534065056d89b4c assets/create/models/item/sticky_mechanical_piston.json bbb5773adc23128c70174bfc531af936e6e063e3 assets/create/models/item/stockpile_switch.json @@ -2140,7 +2143,7 @@ d080b1b25e5bc8baf5aee68691b08c7f12ece3b0 assets/create/models/item/windmill_bear a80fb25a0b655e76be986b5b49fcb0f03461a1ab assets/create/models/item/zinc_nugget.json b1689617190c05ef34bd18456b0c7ae09bb3210f assets/create/models/item/zinc_ore.json 5049f72c327a88f175f6f9425909e098fc711100 assets/create/sounds.json -5d0cc4c0255dc241e61c173b31ddca70c88d08e4 data/create/advancements/aesthetics.json +0f1b4b980afba9bf2caf583b88e261bba8b10313 data/create/advancements/aesthetics.json 613e64b44bed959da899fdd54c1cacb227fb33f2 data/create/advancements/andesite_alloy.json 81885c6bfb85792c88aaa7c9b70f58832945d31f data/create/advancements/andesite_casing.json 83c046bd200623933545c9e4326f782fb02c87fa data/create/advancements/arm_blaze_burner.json @@ -3665,6 +3668,7 @@ f35d81d75c48479b8b5f117dcb885c84f42a1595 data/create/loot_tables/blocks/polished ea720d675f34385735dd43dd249d2d0262864adc data/create/loot_tables/blocks/portable_fluid_interface.json 450920992b5eae0db50aab90dcc822a74986fe6d data/create/loot_tables/blocks/portable_storage_interface.json b7979db39c2c055cb59154bc8a6ab875a52f222b data/create/loot_tables/blocks/powered_latch.json +09907573ad2602251401bc53db0e389a45d6833c data/create/loot_tables/blocks/powered_shaft.json 46a097e6c8d14e36144083f6f4ba824a542c3878 data/create/loot_tables/blocks/powered_toggle_latch.json 5c1df8443043b3fe3b665dba348e2ff188bcbe31 data/create/loot_tables/blocks/pulley_magnet.json 9957bf7cc65b94530d5cf4f337d7ce7c6c1b1ca1 data/create/loot_tables/blocks/pulse_extender.json @@ -3761,6 +3765,7 @@ e257576e224e673ecf3aadc32d145e489c86349e data/create/loot_tables/blocks/small_ve 2ef9d90b2f03d86a758e3a2fb626ecc1d6709a51 data/create/loot_tables/blocks/spout.json 8f52215e5954a5a14b14db0304cb8471ad26f9fd data/create/loot_tables/blocks/spruce_window.json ad771358ecd71e2f0c4b71f7244947fc2dc2a1c9 data/create/loot_tables/blocks/spruce_window_pane.json +e3f024bb8366efe8a8b4335a769a93595adcdb18 data/create/loot_tables/blocks/steam_engine.json 1ab6f4764b93da0e78494dd2deb3a4fff0ed9553 data/create/loot_tables/blocks/sticker.json 94f516dd7e6fd4bd4ee26fad2d2d84b79f40de0b data/create/loot_tables/blocks/sticky_mechanical_piston.json 69cc8ce9ff7b905b62f52d9ac4819e79f3235f58 data/create/loot_tables/blocks/stockpile_switch.json @@ -5204,10 +5209,12 @@ d79c82bc6cf59b073b2f51f5fea9c98e81d14b68 data/create/recipes/weathered_copper_ti 452d480dd50b97fce72e0c89429cf68db534c6b2 data/create/recipes/weathered_copper_tile_slab_from_weathered_copper_tiles_stonecutting.json ac265a674626e0e832330086fd18fe0be37fc327 data/create/recipes/weathered_copper_tile_stairs.json 5942a571f79c40524bbf408775cf91de4715f2b6 data/create/recipes/weathered_copper_tile_stairs_from_weathered_copper_tiles_stonecutting.json +0003d197585d40fda7dac6c08eac0985e4a23f5c data/create/tags/blocks/active_boiler_heaters.json 6558ef43f28c92cc558fbfc572f38496f1ed479e data/create/tags/blocks/brittle.json 330bfb3850ba3964b10b1bccbc3cbb9b012cae54 data/create/tags/blocks/fan_heaters.json 57b942386a15c874d1ca9cd6a8032c11a5599fc2 data/create/tags/blocks/fan_transparent.json 10781e8cfcbb3486327aace3aa00e437fb44b331 data/create/tags/blocks/ore_override_stone.json +197ed7ee3b284045c005011d28c38ac5b2e44d8c data/create/tags/blocks/passive_boiler_heaters.json 557a29a61145b0f266760ef06256188a296739a7 data/create/tags/blocks/safe_nbt.json c9ac7e3e5ec18554e7184168d65e9b8e44ef5610 data/create/tags/blocks/sails.json 6cdeeac1689f7b5bfd9bc40b462143d8eaf3ad0b data/create/tags/blocks/seats.json @@ -5282,7 +5289,7 @@ ff1900963bc4cd8ceffa78d58ef1952ceacb2fb7 data/forge/tags/items/storage_blocks/br 69f596fcb065e26b02ce246760432b5174191b76 data/minecraft/tags/blocks/impermeable.json 2db7759fe036160c14c6ed19a68604ca16f4de60 data/minecraft/tags/blocks/lush_ground_replaceable.json 02f7a9df2f9e154749266e7ac59c37aa076a3390 data/minecraft/tags/blocks/mineable/axe.json -99f0f8d72017ec54567b75f10975b2794a33a424 data/minecraft/tags/blocks/mineable/pickaxe.json +a462e6c5caf03b7d11e61ef775724472fdd53570 data/minecraft/tags/blocks/mineable/pickaxe.json 2db7759fe036160c14c6ed19a68604ca16f4de60 data/minecraft/tags/blocks/moss_replaceable.json e157c1d3af30e409e34bbefbe15a037e6e1c8daa data/minecraft/tags/blocks/needs_iron_tool.json a08f67865337f62601c5e333b4011382d10020e4 data/minecraft/tags/blocks/needs_stone_tool.json diff --git a/src/generated/resources/assets/create/blockstates/powered_shaft.json b/src/generated/resources/assets/create/blockstates/powered_shaft.json new file mode 100644 index 000000000..c95246c45 --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/powered_shaft.json @@ -0,0 +1,17 @@ +{ + "variants": { + "axis=x": { + "model": "create:block/powered_shaft", + "x": 90, + "y": 90 + }, + "axis=y": { + "model": "create:block/powered_shaft" + }, + "axis=z": { + "model": "create:block/powered_shaft", + "x": 90, + "y": 180 + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/blockstates/steam_engine.json b/src/generated/resources/assets/create/blockstates/steam_engine.json new file mode 100644 index 000000000..bad677f65 --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/steam_engine.json @@ -0,0 +1,110 @@ +{ + "variants": { + "face=floor,facing=north,waterlogged=false": { + "model": "create:block/steam_engine/block" + }, + "face=wall,facing=north,waterlogged=false": { + "model": "create:block/steam_engine/block", + "x": 90 + }, + "face=ceiling,facing=north,waterlogged=false": { + "model": "create:block/steam_engine/block", + "x": 180, + "y": 180 + }, + "face=floor,facing=south,waterlogged=false": { + "model": "create:block/steam_engine/block", + "y": 180 + }, + "face=wall,facing=south,waterlogged=false": { + "model": "create:block/steam_engine/block", + "x": 90, + "y": 180 + }, + "face=ceiling,facing=south,waterlogged=false": { + "model": "create:block/steam_engine/block", + "x": 180 + }, + "face=floor,facing=west,waterlogged=false": { + "model": "create:block/steam_engine/block", + "y": 270 + }, + "face=wall,facing=west,waterlogged=false": { + "model": "create:block/steam_engine/block", + "x": 90, + "y": 270 + }, + "face=ceiling,facing=west,waterlogged=false": { + "model": "create:block/steam_engine/block", + "x": 180, + "y": 90 + }, + "face=floor,facing=east,waterlogged=false": { + "model": "create:block/steam_engine/block", + "y": 90 + }, + "face=wall,facing=east,waterlogged=false": { + "model": "create:block/steam_engine/block", + "x": 90, + "y": 90 + }, + "face=ceiling,facing=east,waterlogged=false": { + "model": "create:block/steam_engine/block", + "x": 180, + "y": 270 + }, + "face=floor,facing=north,waterlogged=true": { + "model": "create:block/steam_engine/block" + }, + "face=wall,facing=north,waterlogged=true": { + "model": "create:block/steam_engine/block", + "x": 90 + }, + "face=ceiling,facing=north,waterlogged=true": { + "model": "create:block/steam_engine/block", + "x": 180, + "y": 180 + }, + "face=floor,facing=south,waterlogged=true": { + "model": "create:block/steam_engine/block", + "y": 180 + }, + "face=wall,facing=south,waterlogged=true": { + "model": "create:block/steam_engine/block", + "x": 90, + "y": 180 + }, + "face=ceiling,facing=south,waterlogged=true": { + "model": "create:block/steam_engine/block", + "x": 180 + }, + "face=floor,facing=west,waterlogged=true": { + "model": "create:block/steam_engine/block", + "y": 270 + }, + "face=wall,facing=west,waterlogged=true": { + "model": "create:block/steam_engine/block", + "x": 90, + "y": 270 + }, + "face=ceiling,facing=west,waterlogged=true": { + "model": "create:block/steam_engine/block", + "x": 180, + "y": 90 + }, + "face=floor,facing=east,waterlogged=true": { + "model": "create:block/steam_engine/block", + "y": 90 + }, + "face=wall,facing=east,waterlogged=true": { + "model": "create:block/steam_engine/block", + "x": 90, + "y": 90 + }, + "face=ceiling,facing=east,waterlogged=true": { + "model": "create:block/steam_engine/block", + "x": 180, + "y": 270 + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/lang/en_ud.json b/src/generated/resources/assets/create/lang/en_ud.json index 8b5e6f713..8fe912523 100644 --- a/src/generated/resources/assets/create/lang/en_ud.json +++ b/src/generated/resources/assets/create/lang/en_ud.json @@ -380,6 +380,7 @@ "block.create.portable_fluid_interface": "\u01DD\u0254\u0250\u025F\u0279\u01DD\u0287uI p\u0131n\u05DF\u2132 \u01DD\u05DFq\u0250\u0287\u0279o\u0500", "block.create.portable_storage_interface": "\u01DD\u0254\u0250\u025F\u0279\u01DD\u0287uI \u01DDb\u0250\u0279o\u0287S \u01DD\u05DFq\u0250\u0287\u0279o\u0500", "block.create.powered_latch": "\u0265\u0254\u0287\u0250\uA780 p\u01DD\u0279\u01DD\u028Do\u0500", + "block.create.powered_shaft": "\u0287\u025F\u0250\u0265S p\u01DD\u0279\u01DD\u028Do\u0500", "block.create.powered_toggle_latch": "\u0265\u0254\u0287\u0250\uA780 \u01DD\u05DFbbo\u27D8 p\u01DD\u0279\u01DD\u028Do\u0500", "block.create.pulley_magnet": "\u0287\u01DDub\u0250W \u028E\u01DD\u05DF\u05DFn\u0500", "block.create.pulse_extender": "\u0279\u01DDpu\u01DD\u0287x\u018E \u01DDs\u05DFn\u0500", @@ -476,6 +477,7 @@ "block.create.spout": "\u0287nodS", "block.create.spruce_window": "\u028Dopu\u0131M \u01DD\u0254n\u0279dS", "block.create.spruce_window_pane": "\u01DDu\u0250\u0500 \u028Dopu\u0131M \u01DD\u0254n\u0279dS", + "block.create.steam_engine": "\u01DDu\u0131bu\u018E \u026F\u0250\u01DD\u0287S", "block.create.sticker": "\u0279\u01DD\u029E\u0254\u0131\u0287S", "block.create.sticky_mechanical_piston": "uo\u0287s\u0131\u0500 \u05DF\u0250\u0254\u0131u\u0250\u0265\u0254\u01DDW \u028E\u029E\u0254\u0131\u0287S", "block.create.stockpile_switch": "\u0265\u0254\u0287\u0131\u028DS \u01DD\u05DF\u0131d\u029E\u0254o\u0287S", diff --git a/src/generated/resources/assets/create/lang/en_us.json b/src/generated/resources/assets/create/lang/en_us.json index 56a52c676..a4644f44d 100644 --- a/src/generated/resources/assets/create/lang/en_us.json +++ b/src/generated/resources/assets/create/lang/en_us.json @@ -383,6 +383,7 @@ "block.create.portable_fluid_interface": "Portable Fluid Interface", "block.create.portable_storage_interface": "Portable Storage Interface", "block.create.powered_latch": "Powered Latch", + "block.create.powered_shaft": "Powered Shaft", "block.create.powered_toggle_latch": "Powered Toggle Latch", "block.create.pulley_magnet": "Pulley Magnet", "block.create.pulse_extender": "Pulse Extender", @@ -479,6 +480,7 @@ "block.create.spout": "Spout", "block.create.spruce_window": "Spruce Window", "block.create.spruce_window_pane": "Spruce Window Pane", + "block.create.steam_engine": "Steam Engine", "block.create.sticker": "Sticker", "block.create.sticky_mechanical_piston": "Sticky Mechanical Piston", "block.create.stockpile_switch": "Stockpile Switch", diff --git a/src/generated/resources/assets/create/lang/unfinished/de_de.json b/src/generated/resources/assets/create/lang/unfinished/de_de.json index aebd67d78..bac784a48 100644 --- a/src/generated/resources/assets/create/lang/unfinished/de_de.json +++ b/src/generated/resources/assets/create/lang/unfinished/de_de.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1433", + "_": "Missing Localizations: 1435", "_": "->------------------------] Game Elements [------------------------<-", @@ -384,6 +384,7 @@ "block.create.portable_fluid_interface": "Portable Flüssigkeitsschnittstelle", "block.create.portable_storage_interface": "Portable Lagerschnittstelle", "block.create.powered_latch": "RS-Flipflop", + "block.create.powered_shaft": "UNLOCALIZED: Powered Shaft", "block.create.powered_toggle_latch": "T-Flipflop", "block.create.pulley_magnet": "Rollenmagnet", "block.create.pulse_extender": "UNLOCALIZED: Pulse Extender", @@ -480,6 +481,7 @@ "block.create.spout": "Ausguss", "block.create.spruce_window": "Fichtenfenster", "block.create.spruce_window_pane": "Fichtenfensterscheibe", + "block.create.steam_engine": "UNLOCALIZED: Steam Engine", "block.create.sticker": "Ankleber", "block.create.sticky_mechanical_piston": "Klebriger Mechanischer Kolben", "block.create.stockpile_switch": "Vorratssensor", diff --git a/src/generated/resources/assets/create/lang/unfinished/es_cl.json b/src/generated/resources/assets/create/lang/unfinished/es_cl.json index 4478a76d7..5083ad46d 100644 --- a/src/generated/resources/assets/create/lang/unfinished/es_cl.json +++ b/src/generated/resources/assets/create/lang/unfinished/es_cl.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 444", + "_": "Missing Localizations: 446", "_": "->------------------------] Game Elements [------------------------<-", @@ -384,6 +384,7 @@ "block.create.portable_fluid_interface": "Interfaz de Fluidos Portable", "block.create.portable_storage_interface": "Interfaz de Almacenamientos Portable", "block.create.powered_latch": "Cerrojo de Redstone", + "block.create.powered_shaft": "UNLOCALIZED: Powered Shaft", "block.create.powered_toggle_latch": "Cerrojo Palanca de Redstone", "block.create.pulley_magnet": "Imán de la Polea", "block.create.pulse_extender": "UNLOCALIZED: Pulse Extender", @@ -480,6 +481,7 @@ "block.create.spout": "Surtidor", "block.create.spruce_window": "Ventana de Abeto", "block.create.spruce_window_pane": "Panel de Ventana de Abeto", + "block.create.steam_engine": "UNLOCALIZED: Steam Engine", "block.create.sticker": "Pegador", "block.create.sticky_mechanical_piston": "Pistón Mecánico Pegajoso", "block.create.stockpile_switch": "Interruptor de Reservas", diff --git a/src/generated/resources/assets/create/lang/unfinished/es_es.json b/src/generated/resources/assets/create/lang/unfinished/es_es.json index ef57cc2d6..feca7b44c 100644 --- a/src/generated/resources/assets/create/lang/unfinished/es_es.json +++ b/src/generated/resources/assets/create/lang/unfinished/es_es.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 444", + "_": "Missing Localizations: 446", "_": "->------------------------] Game Elements [------------------------<-", @@ -384,6 +384,7 @@ "block.create.portable_fluid_interface": "Interfaz de fluidos portátil", "block.create.portable_storage_interface": "Interfaz de almacenamiento portátil", "block.create.powered_latch": "Palanca motorizada", + "block.create.powered_shaft": "UNLOCALIZED: Powered Shaft", "block.create.powered_toggle_latch": "Palanca de cierre motorizada", "block.create.pulley_magnet": "Imán de la polea", "block.create.pulse_extender": "UNLOCALIZED: Pulse Extender", @@ -480,6 +481,7 @@ "block.create.spout": "Surtidor", "block.create.spruce_window": "Ventana de abeto", "block.create.spruce_window_pane": "Panel de ventana de abeto", + "block.create.steam_engine": "UNLOCALIZED: Steam Engine", "block.create.sticker": "Sticker", "block.create.sticky_mechanical_piston": "Pistón mecánico pegajoso", "block.create.stockpile_switch": "Interruptor de acopio", diff --git a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json index 62a6959d7..67f88d1fc 100644 --- a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json +++ b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1695", + "_": "Missing Localizations: 1697", "_": "->------------------------] Game Elements [------------------------<-", @@ -384,6 +384,7 @@ "block.create.portable_fluid_interface": "UNLOCALIZED: Portable Fluid Interface", "block.create.portable_storage_interface": "Interface de stockage portable", "block.create.powered_latch": "Verrou alimenté", + "block.create.powered_shaft": "UNLOCALIZED: Powered Shaft", "block.create.powered_toggle_latch": "Verrou alimenté à bascule", "block.create.pulley_magnet": "Aimant de poulie", "block.create.pulse_extender": "UNLOCALIZED: Pulse Extender", @@ -480,6 +481,7 @@ "block.create.spout": "UNLOCALIZED: Spout", "block.create.spruce_window": "UNLOCALIZED: Spruce Window", "block.create.spruce_window_pane": "UNLOCALIZED: Spruce Window Pane", + "block.create.steam_engine": "UNLOCALIZED: Steam Engine", "block.create.sticker": "UNLOCALIZED: Sticker", "block.create.sticky_mechanical_piston": "Piston mécanique collant", "block.create.stockpile_switch": "Détecteur de stockage", diff --git a/src/generated/resources/assets/create/lang/unfinished/it_it.json b/src/generated/resources/assets/create/lang/unfinished/it_it.json index 71d777c7a..6f4babfd3 100644 --- a/src/generated/resources/assets/create/lang/unfinished/it_it.json +++ b/src/generated/resources/assets/create/lang/unfinished/it_it.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1384", + "_": "Missing Localizations: 1386", "_": "->------------------------] Game Elements [------------------------<-", @@ -384,6 +384,7 @@ "block.create.portable_fluid_interface": "Interfaccia per fluidi portatile", "block.create.portable_storage_interface": "Interfaccia di archiviazione portatile", "block.create.powered_latch": "Leva alimentata", + "block.create.powered_shaft": "UNLOCALIZED: Powered Shaft", "block.create.powered_toggle_latch": "Leva alimentata alterata", "block.create.pulley_magnet": "Magnete della carrucola", "block.create.pulse_extender": "UNLOCALIZED: Pulse Extender", @@ -480,6 +481,7 @@ "block.create.spout": "Spruzzo", "block.create.spruce_window": "Finestra di abete", "block.create.spruce_window_pane": "Pannello di finestra di abete", + "block.create.steam_engine": "UNLOCALIZED: Steam Engine", "block.create.sticker": "UNLOCALIZED: Sticker", "block.create.sticky_mechanical_piston": "Pistone meccanico appiccicoso", "block.create.stockpile_switch": "Interruttore accumulatore", diff --git a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json index 6bb741447..8bdd1dce1 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json +++ b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 114", + "_": "Missing Localizations: 116", "_": "->------------------------] Game Elements [------------------------<-", @@ -384,6 +384,7 @@ "block.create.portable_fluid_interface": "ポータブル液体インターフェース", "block.create.portable_storage_interface": "ポータブルストーレジインターフェース", "block.create.powered_latch": "パワードラッチ", + "block.create.powered_shaft": "UNLOCALIZED: Powered Shaft", "block.create.powered_toggle_latch": "パワードトグルラッチ", "block.create.pulley_magnet": "プーリーマグネット", "block.create.pulse_extender": "パルスエクステンダー", @@ -480,6 +481,7 @@ "block.create.spout": "アイテム注液口", "block.create.spruce_window": "マツの窓", "block.create.spruce_window_pane": "マツの板窓", + "block.create.steam_engine": "UNLOCALIZED: Steam Engine", "block.create.sticker": "スティッカー", "block.create.sticky_mechanical_piston": "メカニカル粘着ピストン", "block.create.stockpile_switch": "在庫スイッチ", diff --git a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json index f337baac0..577e97648 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json +++ b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 116", + "_": "Missing Localizations: 118", "_": "->------------------------] Game Elements [------------------------<-", @@ -384,6 +384,7 @@ "block.create.portable_fluid_interface": "액체 인터페이스", "block.create.portable_storage_interface": "아이템 인터페이스", "block.create.powered_latch": "레드스톤 걸쇠", + "block.create.powered_shaft": "UNLOCALIZED: Powered Shaft", "block.create.powered_toggle_latch": "레드스톤 토글 걸쇠", "block.create.pulley_magnet": "도르래 자석", "block.create.pulse_extender": "펄스 연장기", @@ -480,6 +481,7 @@ "block.create.spout": "주입기", "block.create.spruce_window": "가문비나무 유리창", "block.create.spruce_window_pane": "가문비나무 유리판", + "block.create.steam_engine": "UNLOCALIZED: Steam Engine", "block.create.sticker": "부착기", "block.create.sticky_mechanical_piston": "기계식 끈끈이 피스톤", "block.create.stockpile_switch": "수량 스위치", diff --git a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json index c0fadd146..52f139bb3 100644 --- a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json +++ b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 2048", + "_": "Missing Localizations: 2050", "_": "->------------------------] Game Elements [------------------------<-", @@ -384,6 +384,7 @@ "block.create.portable_fluid_interface": "UNLOCALIZED: Portable Fluid Interface", "block.create.portable_storage_interface": "UNLOCALIZED: Portable Storage Interface", "block.create.powered_latch": "UNLOCALIZED: Powered Latch", + "block.create.powered_shaft": "UNLOCALIZED: Powered Shaft", "block.create.powered_toggle_latch": "UNLOCALIZED: Powered Toggle Latch", "block.create.pulley_magnet": "UNLOCALIZED: Pulley Magnet", "block.create.pulse_extender": "UNLOCALIZED: Pulse Extender", @@ -480,6 +481,7 @@ "block.create.spout": "UNLOCALIZED: Spout", "block.create.spruce_window": "UNLOCALIZED: Spruce Window", "block.create.spruce_window_pane": "UNLOCALIZED: Spruce Window Pane", + "block.create.steam_engine": "UNLOCALIZED: Steam Engine", "block.create.sticker": "UNLOCALIZED: Sticker", "block.create.sticky_mechanical_piston": "Mechanische Zuiger", "block.create.stockpile_switch": "Voorraad Schakelaar", diff --git a/src/generated/resources/assets/create/lang/unfinished/pl_pl.json b/src/generated/resources/assets/create/lang/unfinished/pl_pl.json index 5e8dfacf5..0da1ea64a 100644 --- a/src/generated/resources/assets/create/lang/unfinished/pl_pl.json +++ b/src/generated/resources/assets/create/lang/unfinished/pl_pl.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 483", + "_": "Missing Localizations: 485", "_": "->------------------------] Game Elements [------------------------<-", @@ -384,6 +384,7 @@ "block.create.portable_fluid_interface": "Przenośny interfejs płynów", "block.create.portable_storage_interface": "Przenośny interfejs magazynu", "block.create.powered_latch": "Zaawansowany zasilany przełącznik", + "block.create.powered_shaft": "UNLOCALIZED: Powered Shaft", "block.create.powered_toggle_latch": "Zasilany przełącznik", "block.create.pulley_magnet": "Krążek z magnesem", "block.create.pulse_extender": "UNLOCALIZED: Pulse Extender", @@ -480,6 +481,7 @@ "block.create.spout": "Napełniacz", "block.create.spruce_window": "Świerkowe okno", "block.create.spruce_window_pane": "Świerkowa szyba okienna", + "block.create.steam_engine": "UNLOCALIZED: Steam Engine", "block.create.sticker": "Przyklejacz", "block.create.sticky_mechanical_piston": "Lepki mechaniczny tłok", "block.create.stockpile_switch": "Przełącznik zawartościowy", diff --git a/src/generated/resources/assets/create/lang/unfinished/pt_br.json b/src/generated/resources/assets/create/lang/unfinished/pt_br.json index 08cd0aded..155551c1d 100644 --- a/src/generated/resources/assets/create/lang/unfinished/pt_br.json +++ b/src/generated/resources/assets/create/lang/unfinished/pt_br.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1667", + "_": "Missing Localizations: 1669", "_": "->------------------------] Game Elements [------------------------<-", @@ -384,6 +384,7 @@ "block.create.portable_fluid_interface": "Interface de fluidos portátil", "block.create.portable_storage_interface": "Interface de armazenamento portátil", "block.create.powered_latch": "UNLOCALIZED: Powered Latch", + "block.create.powered_shaft": "UNLOCALIZED: Powered Shaft", "block.create.powered_toggle_latch": "UNLOCALIZED: Powered Toggle Latch", "block.create.pulley_magnet": "Imã da Polia", "block.create.pulse_extender": "Extensor de pulso", @@ -480,6 +481,7 @@ "block.create.spout": "Bica", "block.create.spruce_window": "UNLOCALIZED: Spruce Window", "block.create.spruce_window_pane": "UNLOCALIZED: Spruce Window Pane", + "block.create.steam_engine": "UNLOCALIZED: Steam Engine", "block.create.sticker": "Adesivo", "block.create.sticky_mechanical_piston": "Pistão Mecânico Grudento", "block.create.stockpile_switch": "Disjuntor de Armazenamento", diff --git a/src/generated/resources/assets/create/lang/unfinished/pt_pt.json b/src/generated/resources/assets/create/lang/unfinished/pt_pt.json index 6c96c8de0..d0e4c8f6a 100644 --- a/src/generated/resources/assets/create/lang/unfinished/pt_pt.json +++ b/src/generated/resources/assets/create/lang/unfinished/pt_pt.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1667", + "_": "Missing Localizations: 1669", "_": "->------------------------] Game Elements [------------------------<-", @@ -384,6 +384,7 @@ "block.create.portable_fluid_interface": "Interface de fluidos portátil", "block.create.portable_storage_interface": "Interface de armazenamento portátil", "block.create.powered_latch": "UNLOCALIZED: Powered Latch", + "block.create.powered_shaft": "UNLOCALIZED: Powered Shaft", "block.create.powered_toggle_latch": "UNLOCALIZED: Powered Toggle Latch", "block.create.pulley_magnet": "Imã da Polia", "block.create.pulse_extender": "Extensor de pulso", @@ -480,6 +481,7 @@ "block.create.spout": "Bica", "block.create.spruce_window": "UNLOCALIZED: Spruce Window", "block.create.spruce_window_pane": "UNLOCALIZED: Spruce Window Pane", + "block.create.steam_engine": "UNLOCALIZED: Steam Engine", "block.create.sticker": "Adesivo", "block.create.sticky_mechanical_piston": "Pistão Mecânico Grudento", "block.create.stockpile_switch": "Disjuntor de Armazenamento", diff --git a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json index f5afceb15..2bf7fbe08 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json +++ b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 488", + "_": "Missing Localizations: 490", "_": "->------------------------] Game Elements [------------------------<-", @@ -384,6 +384,7 @@ "block.create.portable_fluid_interface": "Портативный жидкостный интерфейс", "block.create.portable_storage_interface": "Портативный интерфейс хранения", "block.create.powered_latch": "Питаемый рычаг", + "block.create.powered_shaft": "UNLOCALIZED: Powered Shaft", "block.create.powered_toggle_latch": "Питаемый рычаг-переключатель", "block.create.pulley_magnet": "Магнитный шкив", "block.create.pulse_extender": "UNLOCALIZED: Pulse Extender", @@ -480,6 +481,7 @@ "block.create.spout": "Дозатор", "block.create.spruce_window": "Еловое окно", "block.create.spruce_window_pane": "Панель из елового окна", + "block.create.steam_engine": "UNLOCALIZED: Steam Engine", "block.create.sticker": "Блок-липучка", "block.create.sticky_mechanical_piston": "Липкий механический поршень", "block.create.stockpile_switch": "Настраиваемый компаратор", diff --git a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json index 8e08a2409..01b31a53f 100644 --- a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json +++ b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 114", + "_": "Missing Localizations: 116", "_": "->------------------------] Game Elements [------------------------<-", @@ -384,6 +384,7 @@ "block.create.portable_fluid_interface": "移动式流体接口", "block.create.portable_storage_interface": "移动式存储接口", "block.create.powered_latch": "锁存器", + "block.create.powered_shaft": "UNLOCALIZED: Powered Shaft", "block.create.powered_toggle_latch": "转换锁存器", "block.create.pulley_magnet": "滑轮磁铁", "block.create.pulse_extender": "脉冲延长器", @@ -480,6 +481,7 @@ "block.create.spout": "注液器", "block.create.spruce_window": "云杉木窗户", "block.create.spruce_window_pane": "云杉木窗户板", + "block.create.steam_engine": "UNLOCALIZED: Steam Engine", "block.create.sticker": "黏着器", "block.create.sticky_mechanical_piston": "黏性动力活塞", "block.create.stockpile_switch": "存量转换器", diff --git a/src/generated/resources/assets/create/lang/unfinished/zh_tw.json b/src/generated/resources/assets/create/lang/unfinished/zh_tw.json index bcdb7d9fb..451be04d9 100644 --- a/src/generated/resources/assets/create/lang/unfinished/zh_tw.json +++ b/src/generated/resources/assets/create/lang/unfinished/zh_tw.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 502", + "_": "Missing Localizations: 504", "_": "->------------------------] Game Elements [------------------------<-", @@ -384,6 +384,7 @@ "block.create.portable_fluid_interface": "移動式液體口", "block.create.portable_storage_interface": "移動式物品口", "block.create.powered_latch": "閂鎖器", + "block.create.powered_shaft": "UNLOCALIZED: Powered Shaft", "block.create.powered_toggle_latch": "T型正反器", "block.create.pulley_magnet": "滑輪磁鐵", "block.create.pulse_extender": "UNLOCALIZED: Pulse Extender", @@ -480,6 +481,7 @@ "block.create.spout": "液體灌注器", "block.create.spruce_window": "雲杉木窗戶", "block.create.spruce_window_pane": "雲杉木窗戶片", + "block.create.steam_engine": "UNLOCALIZED: Steam Engine", "block.create.sticker": "方塊黏著器", "block.create.sticky_mechanical_piston": "黏性機械活塞", "block.create.stockpile_switch": "存量偵測器", diff --git a/src/generated/resources/assets/create/models/item/steam_engine.json b/src/generated/resources/assets/create/models/item/steam_engine.json new file mode 100644 index 000000000..6f76b9fde --- /dev/null +++ b/src/generated/resources/assets/create/models/item/steam_engine.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/steam_engine/item" +} \ No newline at end of file diff --git a/src/generated/resources/data/create/advancements/aesthetics.json b/src/generated/resources/data/create/advancements/aesthetics.json index 59a86f429..d723cbe38 100644 --- a/src/generated/resources/data/create/advancements/aesthetics.json +++ b/src/generated/resources/data/create/advancements/aesthetics.json @@ -28,8 +28,8 @@ "trigger": "create:bracket_apply", "conditions": { "accepted_entries": [ - "create:large_cogwheel", - "create:cogwheel" + "create:cogwheel", + "create:large_cogwheel" ] } }, diff --git a/src/generated/resources/data/create/loot_tables/blocks/powered_shaft.json b/src/generated/resources/data/create/loot_tables/blocks/powered_shaft.json new file mode 100644 index 000000000..647a8e0da --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/powered_shaft.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1.0, + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "create:shaft" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/steam_engine.json b/src/generated/resources/data/create/loot_tables/blocks/steam_engine.json new file mode 100644 index 000000000..a7dead3cb --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/steam_engine.json @@ -0,0 +1,20 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1.0, + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "create:steam_engine" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/tags/blocks/active_boiler_heaters.json b/src/generated/resources/data/create/tags/blocks/active_boiler_heaters.json new file mode 100644 index 000000000..e9e85ee8d --- /dev/null +++ b/src/generated/resources/data/create/tags/blocks/active_boiler_heaters.json @@ -0,0 +1,8 @@ +{ + "replace": false, + "values": [ + "minecraft:furnace", + "minecraft:blast_furnace", + "minecraft:smoker" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/tags/blocks/passive_boiler_heaters.json b/src/generated/resources/data/create/tags/blocks/passive_boiler_heaters.json new file mode 100644 index 000000000..509d23e72 --- /dev/null +++ b/src/generated/resources/data/create/tags/blocks/passive_boiler_heaters.json @@ -0,0 +1,6 @@ +{ + "replace": false, + "values": [ + "#create:fan_heaters" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json b/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json index 23c18d08c..d96280c7e 100644 --- a/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json +++ b/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json @@ -72,6 +72,8 @@ "create:item_drain", "create:spout", "create:portable_fluid_interface", + "create:steam_engine", + "create:powered_shaft", "create:mechanical_piston", "create:sticky_mechanical_piston", "create:piston_extension_pole", diff --git a/src/main/java/com/simibubi/create/AllBlockPartials.java b/src/main/java/com/simibubi/create/AllBlockPartials.java index 61d546121..11aa86b3b 100644 --- a/src/main/java/com/simibubi/create/AllBlockPartials.java +++ b/src/main/java/com/simibubi/create/AllBlockPartials.java @@ -136,6 +136,11 @@ public class AllBlockPartials { TRAIN_CONTROLS_COVER = block("controls/train/cover"), TRAIN_CONTROLS_LEVER = block("controls/train/lever"), + ENGINE_PISTON = block("steam_engine/piston"), + ENGINE_LINKAGE = block("steam_engine/linkage"), + ENGINE_CONNECTOR = block("steam_engine/shaft_connector"), + BOILER_GAUGE = block("steam_engine/gauge"), + SIGNAL_ON = block("track_signal/indicator_on"), SIGNAL_OFF = block("track_signal/indicator_off"), diff --git a/src/main/java/com/simibubi/create/AllBlocks.java b/src/main/java/com/simibubi/create/AllBlocks.java index 130c26f7e..33cf76bf9 100644 --- a/src/main/java/com/simibubi/create/AllBlocks.java +++ b/src/main/java/com/simibubi/create/AllBlocks.java @@ -51,6 +51,8 @@ import com.simibubi.create.content.contraptions.components.motor.CreativeMotorGe import com.simibubi.create.content.contraptions.components.press.MechanicalPressBlock; import com.simibubi.create.content.contraptions.components.saw.SawBlock; import com.simibubi.create.content.contraptions.components.saw.SawGenerator; +import com.simibubi.create.content.contraptions.components.steam.PoweredShaftBlock; +import com.simibubi.create.content.contraptions.components.steam.SteamEngineBlock; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.ClockworkBearingBlock; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.MechanicalBearingBlock; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.SailBlock; @@ -843,6 +845,24 @@ public class AllBlocks { .transform(customItemModel()) .register(); + public static final BlockEntry STEAM_ENGINE = + REGISTRATE.block("steam_engine", SteamEngineBlock::new) + .initialProperties(SharedProperties::copperMetal) + .transform(pickaxeOnly()) + .blockstate((c, p) -> p.horizontalFaceBlock(c.get(), AssetLookup.partialBaseModel(c, p))) + .item() + .transform(customItemModel()) + .register(); + + public static final BlockEntry POWERED_SHAFT = + REGISTRATE.block("powered_shaft", PoweredShaftBlock::new) + .initialProperties(SharedProperties::stone) + .transform(pickaxeOnly()) + .transform(BlockStressDefaults.setCapacity(64.0)) + .blockstate(BlockStateGen.axisBlockProvider(false)) + .loot((lt, block) -> lt.dropOther(block, AllBlocks.SHAFT.get())) + .register(); + // Contraptions public static final BlockEntry MECHANICAL_PISTON = @@ -1311,7 +1331,7 @@ public class AllBlocks { .item(TrackTargetingBlockItem::new) .transform(customItemModel("_", "block")) .register(); - + public static final BlockEntry TRACK_SIGNAL = REGISTRATE.block("track_signal", SignalBlock::new) .initialProperties(SharedProperties::softMetal) .properties(p -> p.sound(SoundType.NETHERITE_BLOCK)) diff --git a/src/main/java/com/simibubi/create/AllParticleTypes.java b/src/main/java/com/simibubi/create/AllParticleTypes.java index 21c6ea9c0..722f1b5d2 100644 --- a/src/main/java/com/simibubi/create/AllParticleTypes.java +++ b/src/main/java/com/simibubi/create/AllParticleTypes.java @@ -2,6 +2,7 @@ package com.simibubi.create; import java.util.function.Supplier; +import com.simibubi.create.content.contraptions.components.steam.SteamJetParticleData; import com.simibubi.create.content.contraptions.fluids.particle.FluidParticleData; import com.simibubi.create.content.contraptions.particle.AirFlowParticleData; import com.simibubi.create.content.contraptions.particle.AirParticleData; @@ -29,6 +30,7 @@ public enum AllParticleTypes { ROTATION_INDICATOR(RotationIndicatorParticleData::new), AIR_FLOW(AirFlowParticleData::new), AIR(AirParticleData::new), + STEAM_JET(SteamJetParticleData::new), HEATER_PARTICLE(HeaterParticleData::new), CUBE(CubeParticleData::new), FLUID_PARTICLE(FluidParticleData::new), diff --git a/src/main/java/com/simibubi/create/AllShapes.java b/src/main/java/com/simibubi/create/AllShapes.java index d7776fdf2..f67677bc6 100644 --- a/src/main/java/com/simibubi/create/AllShapes.java +++ b/src/main/java/com/simibubi/create/AllShapes.java @@ -128,6 +128,16 @@ public class AllShapes { NIXIE_TUBE_CEILING = shape(9, 4, 5, 15, 16, 11).add(1, 4, 5, 7, 16, 11) .forHorizontalAxis(), NIXIE_TUBE_WALL = shape(5, 9, 0, 11, 15, 12).add(5, 1, 0, 11, 7, 12) + .forHorizontal(Direction.SOUTH), + + STEAM_ENGINE = shape(1, 0, 1, 15, 3, 15).add(3, 0, 3, 13, 15, 13) + .add(1, 5, 4, 15, 13, 12) + .forHorizontalAxis(), + STEAM_ENGINE_CEILING = shape(1, 13, 1, 15, 16, 15).add(3, 1, 3, 13, 16, 13) + .add(1, 3, 4, 15, 11, 12) + .forHorizontalAxis(), + STEAM_ENGINE_WALL = shape(1, 1, 0, 15, 15, 3).add(3, 3, 0, 13, 13, 15) + .add(1, 4, 5, 15, 12, 13) .forHorizontal(Direction.SOUTH) ; diff --git a/src/main/java/com/simibubi/create/AllTags.java b/src/main/java/com/simibubi/create/AllTags.java index c7922a7f9..0731d199a 100644 --- a/src/main/java/com/simibubi/create/AllTags.java +++ b/src/main/java/com/simibubi/create/AllTags.java @@ -70,10 +70,10 @@ public class AllTags { public static NonNullFunction, ItemBuilder>> tagBlockAndItem( String... path) { return b -> { - for (String p : path) + for (String p : path) b.tag(forgeBlockTag(p)); - ItemBuilder> item = b.item(); - for (String p : path) + ItemBuilder> item = b.item(); + for (String p : path) item.tag(forgeItemTag(p)); return item; }; @@ -114,7 +114,10 @@ public class AllTags { WINDMILL_SAILS, WINDOWABLE, WRENCH_PICKUP, - + + PASSIVE_BOILER_HEATERS, + ACTIVE_BOILER_HEATERS, + ORE_OVERRIDE_STONE, WG_STONE(FORGE), @@ -337,6 +340,8 @@ public class AllTags { AllBlockTags.FAN_HEATERS.add(Blocks.MAGMA_BLOCK, Blocks.CAMPFIRE, Blocks.LAVA, Blocks.FIRE, Blocks.SOUL_FIRE, Blocks.SOUL_CAMPFIRE); + AllBlockTags.FAN_HEATERS.includeIn(AllBlockTags.PASSIVE_BOILER_HEATERS); + AllBlockTags.ACTIVE_BOILER_HEATERS.add(Blocks.FURNACE, Blocks.BLAST_FURNACE, Blocks.SMOKER); AllBlockTags.SAFE_NBT.includeAll(BlockTags.SIGNS); AllBlockTags.WRENCH_PICKUP.includeAll(BlockTags.RAILS); @@ -345,7 +350,7 @@ public class AllTags { AllBlockTags.WRENCH_PICKUP.add(Blocks.REDSTONE_WIRE, Blocks.REDSTONE_TORCH, Blocks.REPEATER, Blocks.LEVER, Blocks.COMPARATOR, Blocks.OBSERVER, Blocks.REDSTONE_WALL_TORCH, Blocks.PISTON, Blocks.STICKY_PISTON, Blocks.TRIPWIRE, Blocks.TRIPWIRE_HOOK, Blocks.DAYLIGHT_DETECTOR, Blocks.TARGET); - + AllBlockTags.ORE_OVERRIDE_STONE.includeAll(BlockTags.STONE_ORE_REPLACEABLES); } diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index 9fe7c8688..896d4b948 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -52,6 +52,9 @@ import com.simibubi.create.content.contraptions.components.press.PressInstance; import com.simibubi.create.content.contraptions.components.saw.SawInstance; import com.simibubi.create.content.contraptions.components.saw.SawRenderer; import com.simibubi.create.content.contraptions.components.saw.SawTileEntity; +import com.simibubi.create.content.contraptions.components.steam.PoweredShaftTileEntity; +import com.simibubi.create.content.contraptions.components.steam.SteamEngineRenderer; +import com.simibubi.create.content.contraptions.components.steam.SteamEngineTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.BearingInstance; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.BearingRenderer; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.ClockworkBearingTileEntity; @@ -506,6 +509,19 @@ public class AllTileEntities { .validBlocks(AllBlocks.PORTABLE_FLUID_INTERFACE) .renderer(() -> PortableStorageInterfaceRenderer::new) .register(); + + public static final BlockEntityEntry STEAM_ENGINE = Create.registrate() + .tileEntity("steam_engine", SteamEngineTileEntity::new) + .validBlocks(AllBlocks.STEAM_ENGINE) + .renderer(() -> SteamEngineRenderer::new) + .register(); + + public static final BlockEntityEntry POWERED_SHAFT = Create.registrate() + .tileEntity("powered_shaft", PoweredShaftTileEntity::new) + .instance(() -> SingleRotatingInstance::new, false) + .validBlocks(AllBlocks.POWERED_SHAFT) + .renderer(() -> KineticTileEntityRenderer::new) + .register(); public static final BlockEntityEntry FLYWHEEL = Create.registrate() .tileEntity("flywheel", FlywheelTileEntity::new) diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java index 543465645..3ba882463 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java @@ -586,5 +586,9 @@ public class KineticTileEntity extends SmartTileEntity protected boolean isNoisy() { return true; } + + public int getRotationAngleOffset(Axis axis) { + return 0; + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntityRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntityRenderer.java index 296e434ae..3ef7482b8 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntityRenderer.java @@ -113,13 +113,13 @@ public class KineticTileEntityRenderer extends SafeTileEntityRenderer extends B if (d == 0) { offset = 22.5f; } - return offset; + return offset + blockEntity.getRotationAngleOffset(axis); } protected Direction.Axis getRotationAxis() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/steam/PoweredShaftBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/steam/PoweredShaftBlock.java new file mode 100644 index 000000000..8b9f32a96 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/steam/PoweredShaftBlock.java @@ -0,0 +1,80 @@ +package com.simibubi.create.content.contraptions.components.steam; + +import static net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED; + +import java.util.Random; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllShapes; +import com.simibubi.create.AllTileEntities; +import com.simibubi.create.content.contraptions.base.KineticTileEntity; +import com.simibubi.create.content.contraptions.relays.elementary.AbstractShaftBlock; +import com.simibubi.create.content.contraptions.relays.elementary.ShaftBlock; +import com.simibubi.create.foundation.utility.Iterate; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.RenderShape; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +public class PoweredShaftBlock extends AbstractShaftBlock { + + public PoweredShaftBlock(Properties properties) { + super(properties); + } + + @Override + public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) { + return AllShapes.EIGHT_VOXEL_POLE.get(pState.getValue(AXIS)); + } + + @Override + public BlockEntityType getTileEntityType() { + return AllTileEntities.POWERED_SHAFT.get(); + } + + @Override + public RenderShape getRenderShape(BlockState pState) { + return RenderShape.ENTITYBLOCK_ANIMATED; + } + + @Override + public void tick(BlockState pState, ServerLevel pLevel, BlockPos pPos, Random pRandom) { + if (!stillValid(pState, pLevel, pPos)) + pLevel.setBlock(pPos, AllBlocks.SHAFT.getDefaultState() + .setValue(ShaftBlock.AXIS, pState.getValue(AXIS)) + .setValue(WATERLOGGED, pState.getValue(WATERLOGGED)), 3); + } + + @Override + public ItemStack getCloneItemStack(BlockGetter pLevel, BlockPos pPos, BlockState pState) { + return AllBlocks.SHAFT.asStack(); + } + + public static boolean stillValid(BlockState pState, LevelAccessor pLevel, BlockPos pPos) { + for (Direction d : Iterate.directions) { + if (d.getAxis() == pState.getValue(AXIS)) + continue; + BlockState engineState = pLevel.getBlockState(pPos.relative(d, 2)); + if (!(engineState.getBlock()instanceof SteamEngineBlock engine)) + continue; + if (SteamEngineBlock.isShaftValid(engineState, pState)) + return true; + } + return false; + } + + public static BlockState getEquivalent(BlockState stateForPlacement) { + return AllBlocks.POWERED_SHAFT.getDefaultState() + .setValue(PoweredShaftBlock.AXIS, stateForPlacement.getValue(ShaftBlock.AXIS)) + .setValue(WATERLOGGED, stateForPlacement.getValue(WATERLOGGED)); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/steam/PoweredShaftTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/steam/PoweredShaftTileEntity.java new file mode 100644 index 000000000..6c7a56449 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/steam/PoweredShaftTileEntity.java @@ -0,0 +1,77 @@ +package com.simibubi.create.content.contraptions.components.steam; + +import java.util.HashMap; +import java.util.Map; + +import com.jozufozu.flywheel.repack.joml.Math; +import com.simibubi.create.content.contraptions.base.GeneratingKineticTileEntity; +import com.simibubi.create.foundation.utility.NBTHelper; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction.Axis; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.nbt.Tag; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; + +public class PoweredShaftTileEntity extends GeneratingKineticTileEntity { + + public Map sources; + + public PoweredShaftTileEntity(BlockEntityType typeIn, BlockPos pos, BlockState state) { + super(typeIn, pos, state); + sources = new HashMap<>(); + } + + public void update(BlockPos sourcePos, int score) { + BlockPos key = worldPosition.subtract(sourcePos); + Integer prev = sources.put(key, score); + if (prev != null && prev.intValue() == score) + return; + updateGeneratedRotation(); + } + + public void remove(BlockPos sourcePos) { + BlockPos key = worldPosition.subtract(sourcePos); + Integer prev = sources.remove(key); + if (prev == null) + return; + updateGeneratedRotation(); + } + + @Override + protected void write(CompoundTag compound, boolean clientPacket) { + compound.put("Sources", NBTHelper.writeCompoundList(sources.entrySet(), e -> { + CompoundTag nbt = new CompoundTag(); + nbt.put("Pos", NbtUtils.writeBlockPos(e.getKey())); + nbt.putInt("Value", e.getValue()); + return nbt; + })); + super.write(compound, clientPacket); + } + + @Override + protected void read(CompoundTag compound, boolean clientPacket) { + super.read(compound, clientPacket); + sources.clear(); + NBTHelper.iterateCompoundList(compound.getList("Sources", Tag.TAG_COMPOUND), + c -> sources.put(NbtUtils.readBlockPos(c.getCompound("Pos")), c.getInt("Value"))); + } + + @Override + public float getGeneratedSpeed() { + int max = 0; + for (Integer integer : sources.values()) + if (Math.abs(integer) > max) + max = integer; + return 8 * max; + } + + @Override + public int getRotationAngleOffset(Axis axis) { + int combinedCoords = axis.choose(worldPosition.getX(), worldPosition.getY(), worldPosition.getZ()); + return super.getRotationAngleOffset(axis) + (combinedCoords % 2 == 0 ? 180 : 0); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamEngineBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamEngineBlock.java new file mode 100644 index 000000000..cfc85c572 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamEngineBlock.java @@ -0,0 +1,153 @@ +package com.simibubi.create.content.contraptions.components.steam; + +import static net.minecraft.world.level.block.state.properties.BlockStateProperties.WATERLOGGED; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllShapes; +import com.simibubi.create.AllTileEntities; +import com.simibubi.create.content.contraptions.fluids.tank.FluidTankBlock; +import com.simibubi.create.content.contraptions.fluids.tank.FluidTankConnectivityHandler; +import com.simibubi.create.content.contraptions.fluids.tank.FluidTankTileEntity; +import com.simibubi.create.content.contraptions.relays.elementary.ShaftBlock; +import com.simibubi.create.content.contraptions.wrench.IWrenchable; +import com.simibubi.create.foundation.block.ITE; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.FaceAttachedHorizontalDirectionalBlock; +import net.minecraft.world.level.block.SimpleWaterloggedBlock; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition.Builder; +import net.minecraft.world.level.block.state.properties.AttachFace; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.level.pathfinder.PathComputationType; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; + +public class SteamEngineBlock extends FaceAttachedHorizontalDirectionalBlock + implements SimpleWaterloggedBlock, IWrenchable, ITE { + + public SteamEngineBlock(Properties p_53182_) { + super(p_53182_); + } + + @Override + protected void createBlockStateDefinition(Builder pBuilder) { + super.createBlockStateDefinition(pBuilder.add(FACE, FACING, WATERLOGGED)); + } + + @Override + public boolean canSurvive(BlockState pState, LevelReader pLevel, BlockPos pPos) { + return canAttach(pLevel, pPos, getConnectedDirection(pState).getOpposite()); + } + + public static boolean canAttach(LevelReader pReader, BlockPos pPos, Direction pDirection) { + BlockPos blockpos = pPos.relative(pDirection); + return pReader.getBlockState(blockpos) + .getBlock() instanceof FluidTankBlock; + } + + @Override + public FluidState getFluidState(BlockState state) { + return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : Fluids.EMPTY.defaultFluidState(); + } + + @Override + public BlockState updateShape(BlockState state, Direction direction, BlockState neighbourState, LevelAccessor world, + BlockPos pos, BlockPos neighbourPos) { + if (state.getValue(WATERLOGGED)) + world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); + return state; + } + + @Override + public void onPlace(BlockState pState, Level pLevel, BlockPos pPos, BlockState pOldState, boolean pIsMoving) { + updateAttachedTank(pState, pLevel, pPos); + BlockPos shaftPos = getShaftPos(pState, pPos); + BlockState shaftState = pLevel.getBlockState(shaftPos); + if (isShaftValid(pState, shaftState)) + pLevel.setBlock(shaftPos, PoweredShaftBlock.getEquivalent(shaftState), 3); + } + + @Override + public void onRemove(BlockState pState, Level pLevel, BlockPos pPos, BlockState pNewState, boolean pIsMoving) { + if (pState.hasBlockEntity() && (!pState.is(pNewState.getBlock()) || !pNewState.hasBlockEntity())) + pLevel.removeBlockEntity(pPos); + updateAttachedTank(pState, pLevel, pPos); + + BlockPos shaftPos = getShaftPos(pState, pPos); + BlockState shaftState = pLevel.getBlockState(shaftPos); + if (AllBlocks.POWERED_SHAFT.has(shaftState)) + pLevel.scheduleTick(shaftPos, shaftState.getBlock(), 1); + } + + private void updateAttachedTank(BlockState pState, Level pLevel, BlockPos pPos) { + BlockPos tankPos = pPos.relative(getFacing(pState).getOpposite()); + BlockState tankState = pLevel.getBlockState(tankPos); + if (!FluidTankBlock.isTank(tankState)) + return; + FluidTankTileEntity tankTE = FluidTankConnectivityHandler.anyTankAt(pLevel, tankPos); + if (tankTE == null) + return; + FluidTankTileEntity controllerTE = tankTE.getControllerTE(); + if (controllerTE == null) + return; + controllerTE.updateBoilerState(); + } + + @Override + public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) { + AttachFace face = pState.getValue(FACE); + Direction direction = pState.getValue(FACING); + return face == AttachFace.CEILING ? AllShapes.STEAM_ENGINE_CEILING.get(direction.getAxis()) + : face == AttachFace.FLOOR ? AllShapes.STEAM_ENGINE.get(direction.getAxis()) + : AllShapes.STEAM_ENGINE_WALL.get(direction); + } + + @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { + Level level = context.getLevel(); + BlockPos pos = context.getClickedPos(); + FluidState ifluidstate = level.getFluidState(pos); + BlockState state = super.getStateForPlacement(context); + if (state == null) + return null; + return state.setValue(WATERLOGGED, Boolean.valueOf(ifluidstate.getType() == Fluids.WATER)); + } + + @Override + public boolean isPathfindable(BlockState state, BlockGetter reader, BlockPos pos, PathComputationType type) { + return false; + } + + public static Direction getFacing(BlockState sideState) { + return getConnectedDirection(sideState); + } + + public static BlockPos getShaftPos(BlockState sideState, BlockPos pos) { + return pos.relative(getConnectedDirection(sideState), 2); + } + + public static boolean isShaftValid(BlockState state, BlockState shaft) { + return AllBlocks.SHAFT.has(shaft) && shaft.getValue(ShaftBlock.AXIS) != getFacing(state).getAxis(); + } + + @Override + public Class getTileEntityClass() { + return SteamEngineTileEntity.class; + } + + @Override + public BlockEntityType getTileEntityType() { + return AllTileEntities.STEAM_ENGINE.get(); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamEngineRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamEngineRenderer.java new file mode 100644 index 000000000..97ec957de --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamEngineRenderer.java @@ -0,0 +1,81 @@ +package com.simibubi.create.content.contraptions.components.steam; + +import com.jozufozu.flywheel.core.PartialModel; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; +import com.simibubi.create.foundation.render.CachedBufferer; +import com.simibubi.create.foundation.render.SuperByteBuffer; +import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; +import com.simibubi.create.foundation.utility.AngleHelper; + +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.core.Direction; +import net.minecraft.core.Direction.Axis; +import net.minecraft.util.Mth; +import net.minecraft.world.level.block.state.BlockState; + +public class SteamEngineRenderer extends SafeTileEntityRenderer { + + public SteamEngineRenderer(BlockEntityRendererProvider.Context context) {} + + @Override + protected void renderSafe(SteamEngineTileEntity te, float partialTicks, PoseStack ms, MultiBufferSource buffer, + int light, int overlay) { + VertexConsumer vb = buffer.getBuffer(RenderType.solid()); + + BlockState blockState = te.getBlockState(); + Direction facing = SteamEngineBlock.getFacing(blockState); + Axis facingAxis = facing.getAxis(); + Axis axis = Axis.Y; + + PoweredShaftTileEntity shaft = te.getShaft(); + if (shaft != null) + axis = KineticTileEntityRenderer.getRotationAxisOf(shaft); + + Float angle = te.getTargetAngle(); + if (angle == null) + return; + + float sine = Mth.sin(angle); + float sine2 = Mth.sin(angle - Mth.HALF_PI); + float piston = ((1 - sine) / 4) * 24 / 16f; + boolean roll90 = facingAxis.isHorizontal() && axis == Axis.Y || facingAxis.isVertical() && axis == Axis.Z; + + transformed(AllBlockPartials.ENGINE_PISTON, blockState, facing).rotateY(roll90 ? -90 : 0) + .unCentre() + .light(light) + .translate(0, piston, 0) + .renderInto(ms, vb); + + transformed(AllBlockPartials.ENGINE_LINKAGE, blockState, facing).rotateY(roll90 ? -90 : 0) + .translate(0, 1, 0) + .unCentre() + .translate(0, piston, 0) + .translate(0, 4 / 16f, 8 / 16f) + .rotateX(sine2 * 23f) + .translate(0, -4 / 16f, -8 / 16f) + .light(light) + .renderInto(ms, vb); + + transformed(AllBlockPartials.ENGINE_CONNECTOR, blockState, facing).rotateY(roll90 ? -90 : 0) + .unCentre() + .light(light) + .translate(0, 2, 0) + .centre() + .rotateXRadians(-angle + Mth.HALF_PI) + .unCentre() + .renderInto(ms, vb); + } + + private SuperByteBuffer transformed(PartialModel model, BlockState blockState, Direction facing) { + return CachedBufferer.partial(model, blockState) + .centre() + .rotateY(AngleHelper.horizontalAngle(facing)) + .rotateX(AngleHelper.verticalAngle(facing) + 90); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamEngineTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamEngineTileEntity.java new file mode 100644 index 000000000..6a6c356d1 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamEngineTileEntity.java @@ -0,0 +1,196 @@ +package com.simibubi.create.content.contraptions.components.steam; + +import java.lang.ref.WeakReference; +import java.util.List; + +import javax.annotation.Nullable; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.content.contraptions.base.GeneratingKineticTileEntity; +import com.simibubi.create.content.contraptions.base.IRotate; +import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; +import com.simibubi.create.content.contraptions.fluids.tank.FluidTankConnectivityHandler; +import com.simibubi.create.content.contraptions.fluids.tank.FluidTankTileEntity; +import com.simibubi.create.foundation.tileEntity.SmartTileEntity; +import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.Debug; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Direction.Axis; +import net.minecraft.core.Direction.AxisDirection; +import net.minecraft.util.Mth; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.fml.DistExecutor; + +public class SteamEngineTileEntity extends SmartTileEntity { + + public WeakReference target; + public WeakReference source; + + public SteamEngineTileEntity(BlockEntityType type, BlockPos pos, BlockState state) { + super(type, pos, state); + source = new WeakReference<>(null); + target = new WeakReference<>(null); + } + + @Override + public void addBehaviours(List behaviours) {} + + @Override + public void tick() { + super.tick(); + FluidTankTileEntity tank = getTank(); + PoweredShaftTileEntity shaft = getShaft(); + if (tank == null || shaft == null) + return; + + boolean verticalTarget = false; + BlockState shaftState = shaft.getBlockState(); + Axis targetAxis = Axis.X; + if (shaftState.getBlock()instanceof IRotate ir) + targetAxis = ir.getRotationAxis(shaftState); + verticalTarget = targetAxis == Axis.Y; + + BlockState blockState = getBlockState(); + if (!AllBlocks.STEAM_ENGINE.has(blockState)) + return; + Direction facing = SteamEngineBlock.getFacing(blockState); + if (facing.getAxis() == Axis.Y) + facing = blockState.getValue(SteamEngineBlock.FACING); + + int score = Math.max(0, tank.boiler.engineScore); + int conveyedSpeedLevel = + verticalTarget ? score : (int) GeneratingKineticTileEntity.convertToDirection(score, facing); + if (targetAxis == Axis.Z) + conveyedSpeedLevel *= -1; + shaft.update(worldPosition, conveyedSpeedLevel); + + if (!level.isClientSide) + return; + + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> this::spawnParticles); + } + + @Override + protected void setRemovedNotDueToChunkUnload() { + PoweredShaftTileEntity shaft = getShaft(); + if (shaft != null) + shaft.remove(worldPosition); + super.setRemovedNotDueToChunkUnload(); + } + + @Override + public AABB getRenderBoundingBox() { + return super.getRenderBoundingBox().inflate(2); + } + + public PoweredShaftTileEntity getShaft() { + PoweredShaftTileEntity shaft = target.get(); + if (shaft == null || shaft.isRemoved()) { + if (shaft != null) + target = new WeakReference<>(null); + Direction facing = SteamEngineBlock.getFacing(getBlockState()); + BlockEntity anyShaftAt = level.getBlockEntity(worldPosition.relative(facing, 2)); + if (anyShaftAt instanceof PoweredShaftTileEntity ps) + target = new WeakReference<>(shaft = ps); + } + return shaft; + } + + public FluidTankTileEntity getTank() { + FluidTankTileEntity tank = source.get(); + if (tank == null || tank.isRemoved()) { + if (tank != null) + source = new WeakReference<>(null); + Direction facing = SteamEngineBlock.getFacing(getBlockState()); + FluidTankTileEntity anyTankAt = + FluidTankConnectivityHandler.anyTankAt(level, worldPosition.relative(facing.getOpposite())); + if (anyTankAt != null) + source = new WeakReference<>(tank = anyTankAt); + } + if (tank == null) + return null; + return tank.getControllerTE(); + } + + float prevAngle = 0; + + @OnlyIn(Dist.CLIENT) + private void spawnParticles() { + Float targetAngle = getTargetAngle(); + if (targetAngle == null) + return; + + float angle = AngleHelper.deg(targetAngle); + angle += (angle < 0) ? -180 + 75 : 360 - 75; + angle %= 360; + + PoweredShaftTileEntity shaft = getShaft(); + if (shaft == null || shaft.getSpeed() == 0) + return; + + if (angle >= 0 && !(prevAngle > 180 && angle < 180)) { + prevAngle = angle; + return; + } + if (angle < 0 && !(prevAngle < -180 && angle > -180)) { + prevAngle = angle; + return; + } + + Direction facing = SteamEngineBlock.getFacing(getBlockState()); + + for (int i = 0; i < 2; i++) { + Vec3 offset = VecHelper.rotate(new Vec3(0, 0, 1).add(VecHelper.offsetRandomly(Vec3.ZERO, level.random, 1) + .multiply(1, 1, 0) + .normalize() + .scale(.5f)), AngleHelper.verticalAngle(facing), Axis.X); + offset = VecHelper.rotate(offset, AngleHelper.horizontalAngle(facing), Axis.Y); + Vec3 v = offset.scale(.5f) + .add(Vec3.atCenterOf(worldPosition)); + Vec3 m = offset.subtract(Vec3.atLowerCornerOf(facing.getNormal()) + .scale(.75f)); + level.addParticle(new SteamJetParticleData(1), v.x, v.y, v.z, m.x, m.y, m.z); + } + + prevAngle = angle; + } + + @Nullable + @OnlyIn(Dist.CLIENT) + public Float getTargetAngle() { + float angle = 0; + BlockState blockState = getBlockState(); + if (!AllBlocks.STEAM_ENGINE.has(blockState)) + return null; + + Direction facing = SteamEngineBlock.getFacing(blockState); + PoweredShaftTileEntity shaft = getShaft(); + Axis facingAxis = facing.getAxis(); + Axis axis = Axis.Y; + + if (shaft == null) + return null; + + axis = KineticTileEntityRenderer.getRotationAxisOf(shaft); + angle = KineticTileEntityRenderer.getAngleForTe(shaft, shaft.getBlockPos(), axis); + + if (axis == facingAxis) + return null; + if (axis.isHorizontal() && (facingAxis == Axis.X ^ facing.getAxisDirection() == AxisDirection.POSITIVE)) + angle *= -1; + if (axis == Axis.X && facing == Direction.DOWN) + angle *= -1; + return angle; + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamJetParticle.java b/src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamJetParticle.java new file mode 100644 index 000000000..5f1f70c1f --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamJetParticle.java @@ -0,0 +1,117 @@ +package com.simibubi.create.content.contraptions.components.steam; + +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Quaternion; +import com.mojang.math.Vector3f; + +import net.minecraft.client.Camera; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.particle.Particle; +import net.minecraft.client.particle.ParticleProvider; +import net.minecraft.client.particle.ParticleRenderType; +import net.minecraft.client.particle.SimpleAnimatedParticle; +import net.minecraft.client.particle.SpriteSet; +import net.minecraft.client.renderer.LevelRenderer; +import net.minecraft.core.BlockPos; +import net.minecraft.util.Mth; +import net.minecraft.world.phys.Vec3; + +public class SteamJetParticle extends SimpleAnimatedParticle { + + private float yaw, pitch; + + protected SteamJetParticle(ClientLevel world, SteamJetParticleData data, double x, double y, double z, double dx, + double dy, double dz, SpriteSet sprite) { + super(world, x, y, z, sprite, world.random.nextFloat() * .5f); + xd = 0; + yd = 0; + zd = 0; + gravity = 0; + quadSize = .375f; + setLifetime(21); + setPos(x, y, z); + roll = oRoll = world.random.nextFloat() * Mth.PI; + yaw = (float) Mth.atan2(dx, dz) - Mth.PI; + pitch = (float) Mth.atan2(dy, Math.sqrt(dx * dx + dz * dz)) - Mth.PI / 2; + this.setSpriteFromAge(sprite); + } + + public ParticleRenderType getRenderType() { + return ParticleRenderType.PARTICLE_SHEET_OPAQUE; + } + + public void render(VertexConsumer pBuffer, Camera pRenderInfo, float pPartialTicks) { + Vec3 vec3 = pRenderInfo.getPosition(); + float f = (float) (x - vec3.x); + float f1 = (float) (y - vec3.y); + float f2 = (float) (z - vec3.z); + float f3 = Mth.lerp(pPartialTicks, this.oRoll, this.roll); + float f7 = this.getU0(); + float f8 = this.getU1(); + float f5 = this.getV0(); + float f6 = this.getV1(); + float f4 = this.getQuadSize(pPartialTicks); + + for (int i = 0; i < 4; i++) { + Quaternion quaternion = new Quaternion(Vector3f.YP, yaw, false); + quaternion.mul(Vector3f.XP.rotation(pitch)); + quaternion.mul(Vector3f.YP.rotation(f3 + Mth.PI / 2 * i + roll)); + Vector3f vector3f1 = new Vector3f(-1.0F, -1.0F, 0.0F); + vector3f1.transform(quaternion); + + Vector3f[] avector3f = new Vector3f[] { new Vector3f(-1.0F, -1.0F, 0.0F), new Vector3f(-1.0F, 1.0F, 0.0F), + new Vector3f(1.0F, 1.0F, 0.0F), new Vector3f(1.0F, -1.0F, 0.0F) }; + + for (int j = 0; j < 4; ++j) { + Vector3f vector3f = avector3f[j]; + vector3f.add(0, 1, 0); + vector3f.transform(quaternion); + vector3f.mul(f4); + vector3f.add(f, f1, f2); + } + + int j = this.getLightColor(pPartialTicks); + pBuffer.vertex((double) avector3f[0].x(), (double) avector3f[0].y(), (double) avector3f[0].z()) + .uv(f8, f6) + .color(this.rCol, this.gCol, this.bCol, this.alpha) + .uv2(j) + .endVertex(); + pBuffer.vertex((double) avector3f[1].x(), (double) avector3f[1].y(), (double) avector3f[1].z()) + .uv(f8, f5) + .color(this.rCol, this.gCol, this.bCol, this.alpha) + .uv2(j) + .endVertex(); + pBuffer.vertex((double) avector3f[2].x(), (double) avector3f[2].y(), (double) avector3f[2].z()) + .uv(f7, f5) + .color(this.rCol, this.gCol, this.bCol, this.alpha) + .uv2(j) + .endVertex(); + pBuffer.vertex((double) avector3f[3].x(), (double) avector3f[3].y(), (double) avector3f[3].z()) + .uv(f7, f6) + .color(this.rCol, this.gCol, this.bCol, this.alpha) + .uv2(j) + .endVertex(); + + } + } + + @Override + public int getLightColor(float partialTick) { + BlockPos blockpos = new BlockPos(this.x, this.y, this.z); + return this.level.isLoaded(blockpos) ? LevelRenderer.getLightColor(level, blockpos) : 0; + } + + public static class Factory implements ParticleProvider { + private final SpriteSet spriteSet; + + public Factory(SpriteSet animatedSprite) { + this.spriteSet = animatedSprite; + } + + public Particle createParticle(SteamJetParticleData data, ClientLevel worldIn, double x, double y, double z, + double xSpeed, double ySpeed, double zSpeed) { + return new SteamJetParticle(worldIn, data, x, y, z, xSpeed, ySpeed, zSpeed, this.spriteSet); + } + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamJetParticleData.java b/src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamJetParticleData.java new file mode 100644 index 000000000..6b20e0405 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamJetParticleData.java @@ -0,0 +1,82 @@ +package com.simibubi.create.content.contraptions.components.steam; + +import java.util.Locale; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import com.simibubi.create.AllParticleTypes; +import com.simibubi.create.content.contraptions.particle.ICustomParticleDataWithSprite; + +import net.minecraft.client.particle.ParticleEngine.SpriteParticleRegistration; +import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.core.particles.ParticleType; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +public class SteamJetParticleData implements ParticleOptions, ICustomParticleDataWithSprite { + + public static final Codec CODEC = RecordCodecBuilder.create(i -> i + .group(Codec.FLOAT.fieldOf("speed") + .forGetter(p -> p.speed)) + .apply(i, SteamJetParticleData::new)); + + public static final ParticleOptions.Deserializer DESERIALIZER = + new ParticleOptions.Deserializer() { + public SteamJetParticleData fromCommand(ParticleType particleTypeIn, + StringReader reader) throws CommandSyntaxException { + reader.expect(' '); + float speed = reader.readFloat(); + return new SteamJetParticleData(speed); + } + + public SteamJetParticleData fromNetwork(ParticleType particleTypeIn, + FriendlyByteBuf buffer) { + return new SteamJetParticleData(buffer.readFloat()); + } + }; + + float speed; + + public SteamJetParticleData(float speed) { + this.speed = speed; + } + + public SteamJetParticleData() { + this(0); + } + + @Override + public ParticleType getType() { + return AllParticleTypes.STEAM_JET.get(); + } + + @Override + public void writeToNetwork(FriendlyByteBuf buffer) { + buffer.writeFloat(speed); + } + + @Override + public String writeToString() { + return String.format(Locale.ROOT, "%s %f", AllParticleTypes.STEAM_JET.parameter(), speed); + } + + @Override + public Deserializer getDeserializer() { + return DESERIALIZER; + } + + @Override + public Codec getCodec(ParticleType type) { + return CODEC; + } + + @Override + @OnlyIn(Dist.CLIENT) + public SpriteParticleRegistration getMetaFactory() { + return SteamJetParticle.Factory::new; + } + +} \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java index aae58d324..6c687ec08 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java @@ -749,7 +749,7 @@ public abstract class Contraption { if (tankInventory instanceof FluidTank) ((FluidTank) tankInventory).setFluid(mfs.tank.getFluid()); tank.getFluidLevel() - .start(tank.getFillState()); + .startWithValue(tank.getFillState()); mfs.assignTileEntity(tank); }); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MountedFluidStorage.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MountedFluidStorage.java index cd2db1403..a86acebfa 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MountedFluidStorage.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MountedFluidStorage.java @@ -7,7 +7,8 @@ import com.simibubi.create.content.contraptions.fluids.tank.FluidTankTileEntity; import com.simibubi.create.foundation.fluid.SmartFluidTank; import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.utility.NBTHelper; -import com.simibubi.create.foundation.utility.animation.InterpolatedChasingValue; +import com.simibubi.create.foundation.utility.animation.LerpedFloat; +import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; @@ -73,7 +74,7 @@ public class MountedFluidStorage { return; FluidTankTileEntity tank = (FluidTankTileEntity) te; tank.getFluidLevel() - .tick(); + .tickChaser(); } public void updateFluid(FluidStack fluid) { @@ -83,9 +84,10 @@ public class MountedFluidStorage { float fillState = tank.getFluidAmount() / (float) tank.getCapacity(); FluidTankTileEntity tank = (FluidTankTileEntity) te; if (tank.getFluidLevel() == null) - tank.setFluidLevel(new InterpolatedChasingValue().start(fillState)); + tank.setFluidLevel(LerpedFloat.linear() + .startWithValue(fillState)); tank.getFluidLevel() - .target(fillState); + .chase(fillState, 0.5, Chaser.EXP); IFluidTank tankInventory = tank.getTankInventory(); if (tankInventory instanceof SmartFluidTank) ((SmartFluidTank) tankInventory).setFluid(fluid); @@ -120,7 +122,8 @@ public class MountedFluidStorage { return; SmartFluidTank inv = (SmartFluidTank) teHandler; - inv.setFluid(tank.getFluid().copy()); + inv.setFluid(tank.getFluid() + .copy()); } public IFluidHandler getFluidHandler() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/BracketBlock.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/BracketBlock.java index 579500ce7..2d663dd90 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/BracketBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/BracketBlock.java @@ -5,7 +5,7 @@ import java.util.Optional; import com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock; import com.simibubi.create.content.contraptions.base.RotatedPillarKineticBlock; import com.simibubi.create.content.contraptions.fluids.FluidPropagator; -import com.simibubi.create.content.contraptions.relays.elementary.AbstractShaftBlock; +import com.simibubi.create.content.contraptions.relays.elementary.AbstractSimpleShaftBlock; import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock; import com.simibubi.create.foundation.block.WrenchableDirectionalBlock; import com.simibubi.create.foundation.utility.Lang; @@ -47,7 +47,7 @@ public class BracketBlock extends WrenchableDirectionalBlock { } public Optional getSuitableBracket(BlockState blockState, Direction direction) { - if (blockState.getBlock() instanceof AbstractShaftBlock) + if (blockState.getBlock() instanceof AbstractSimpleShaftBlock) return getSuitableBracket(blockState.getValue(RotatedPillarKineticBlock.AXIS), direction, blockState.getBlock() instanceof CogWheelBlock ? BracketType.COG : BracketType.SHAFT); return getSuitableBracket(FluidPropagator.getStraightPipeAxis(blockState), direction, BracketType.PIPE); diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/BoilerData.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/BoilerData.java new file mode 100644 index 000000000..d3d0bae21 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/BoilerData.java @@ -0,0 +1,306 @@ +package com.simibubi.create.content.contraptions.fluids.tank; + +import java.util.Arrays; +import java.util.List; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.Create; +import com.simibubi.create.content.contraptions.components.steam.SteamEngineBlock; +import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation; +import com.simibubi.create.foundation.fluid.FluidHelper; +import com.simibubi.create.foundation.utility.Debug; +import com.simibubi.create.foundation.utility.Iterate; +import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.foundation.utility.animation.LerpedFloat; +import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser; + +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.util.Mth; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.capability.IFluidHandler; + +public class BoilerData { + + static final int SAMPLE_RATE = 5; + public int gatheredSupply; + public float[] supplyOverTime = new float[10]; + int ticksUntilNextSample; + int currentIndex; + boolean needsTemperatureUpdate; + + public float currentTemperature; + public float targetTemperature; + public float waterSupply; + public float steamUnits; + public int attachedEngines; + public int engineScore; + + public LerpedFloat pressure = LerpedFloat.linear(); + + static final float MAX_ENGINE_USAGE = 32; + + public void tick(FluidTankTileEntity controller) { + if (!isActive()) + return; + if (controller.getLevel().isClientSide) { + pressure.tickChaser(); + float current = pressure.getValue(1); + if (current > 1 && Create.RANDOM.nextFloat() < 1 / 2f) + pressure.setValueNoUpdate(current + Math.min(-(current - 1) * Create.RANDOM.nextFloat(), 0)); + return; + } + if (needsTemperatureUpdate && updateTemperature(controller)) + controller.notifyUpdate(); + ticksUntilNextSample--; + if (ticksUntilNextSample > 0) + return; + int capacity = controller.tankInventory.getCapacity(); + if (capacity == 0) + return; + + ticksUntilNextSample = SAMPLE_RATE; + waterSupply -= supplyOverTime[currentIndex]; + supplyOverTime[currentIndex] = gatheredSupply / (float) SAMPLE_RATE; + waterSupply += supplyOverTime[currentIndex]; + currentIndex = (currentIndex + 1) % supplyOverTime.length; + gatheredSupply = 0; + + if (currentIndex == 0) { + waterSupply = 0; + for (float i : supplyOverTime) + waterSupply += i; + } + + currentTemperature = Mth.clamp(currentTemperature + Math.signum(targetTemperature - currentTemperature) + * (0.5f + (targetTemperature - currentTemperature) * .125f), 0, targetTemperature); + + float steamPerTick = Math.min(waterSupply / 2, currentTemperature - 100); + steamUnits += steamPerTick; + + float pressure = steamUnits / capacity; + float engineEfficiency = (float) (Math.max(0, pressure - 0.5) * 2); + float usagePerEngine = engineEfficiency * MAX_ENGINE_USAGE; + float consumedSteam = Math.min(steamUnits, attachedEngines * usagePerEngine); + float equilibrium = steamPerTick / (attachedEngines * MAX_ENGINE_USAGE * 2) + .5f; + +// if (Math.abs(engineEfficiency - equilibrium) < 1 / 8f) // Anti-flicker at balance point +// engineEfficiency = equilibrium; + + engineScore = Mth.floor(engineEfficiency * 8); + steamUnits -= consumedSteam; + + if (steamUnits > capacity * 1.25f) { + Debug.debugChat("Boiler exploding: Bang. " + controller.getBlockPos()); + steamUnits = 0; + } + + controller.notifyUpdate(); + } + + String spacing = " "; + Component componentSpacing = new TextComponent(spacing); + + public boolean addToGoggleTooltip(List tooltip, boolean isPlayerSneaking) { + if (!isActive()) + return false; + + float steamPerTick = Math.min(waterSupply / 2, currentTemperature - 100); + float equilibrium = steamPerTick / (attachedEngines * MAX_ENGINE_USAGE * 2) + .5f; + + tooltip.add(componentSpacing.plainCopy() + .append(Lang.translate("gui.goggles.fluid_container"))); + TranslatableComponent mb = Lang.translate("generic.unit.millibuckets"); + + Component engines = new TextComponent("Engines: ").withStyle(ChatFormatting.GRAY) + .append(new TextComponent(attachedEngines + "").withStyle(ChatFormatting.GOLD)); + Component power = new TextComponent("Temperature: ").withStyle(ChatFormatting.GRAY) + .append(new TextComponent(IHaveGoggleInformation.format(currentTemperature) + "") + .withStyle(ChatFormatting.GOLD)); + Component score = new TextComponent("Engine Efficiency: ").withStyle(ChatFormatting.GRAY) + .append(new TextComponent(engineScore + "").withStyle(ChatFormatting.GOLD)); + Component supply = new TextComponent("Water Supply: ").withStyle(ChatFormatting.GRAY) + .append(new TextComponent(IHaveGoggleInformation.format(waterSupply)).append(mb) + .withStyle(ChatFormatting.GOLD)); + Component steam = new TextComponent("Steam Volume: ").withStyle(ChatFormatting.GRAY) + .append(new TextComponent(IHaveGoggleInformation.format(steamUnits)).append(mb) + .withStyle(ChatFormatting.GOLD)); + + int approachingPressure = (int) (equilibrium * 100); + int actualPressure = + (int) ((this.pressure.getChaseTarget() > 1 ? this.pressure.getChaseTarget() : this.pressure.getValue()) + * 100); + MutableComponent pressure = new TextComponent("Pressure: ").withStyle(ChatFormatting.GRAY) + .append(new TextComponent(IHaveGoggleInformation.format(actualPressure)).append(new TextComponent("%")) + .withStyle(ChatFormatting.GOLD)); + if (actualPressure != approachingPressure) + pressure.append(new TextComponent(" >> ").append( + new TextComponent(IHaveGoggleInformation.format(approachingPressure)).append(new TextComponent("%")) + .withStyle(ChatFormatting.GREEN))); + + Component indent = new TextComponent(spacing + " "); + + tooltip.add(indent.plainCopy() + .append(engines)); + tooltip.add(indent.plainCopy() + .append(score)); + tooltip.add(indent.plainCopy() + .append(power)); + tooltip.add(indent.plainCopy() + .append(supply)); + tooltip.add(indent.plainCopy() + .append(steam)); + tooltip.add(indent.plainCopy() + .append(pressure)); + return true; + } + + public boolean evaluate(FluidTankTileEntity controller) { + BlockPos controllerPos = controller.getBlockPos(); + Level level = controller.getLevel(); + int prev = attachedEngines; + attachedEngines = 0; + + for (int yOffset = 0; yOffset < controller.height; yOffset++) { + for (int xOffset = 0; xOffset < controller.width; xOffset++) { + for (int zOffset = 0; zOffset < controller.width; zOffset++) { + + BlockPos pos = controllerPos.offset(xOffset, yOffset, zOffset); + BlockState blockState = level.getBlockState(pos); + if (!FluidTankBlock.isTank(blockState)) + continue; + for (Direction d : Iterate.directions) { + BlockPos enginePos = pos.relative(d); + BlockState engineState = level.getBlockState(enginePos); + if (!AllBlocks.STEAM_ENGINE.has(engineState)) + continue; + if (SteamEngineBlock.getFacing(engineState) != d) + continue; + attachedEngines++; + } + } + } + } + + needsTemperatureUpdate = true; + return prev != attachedEngines; + } + + public boolean updateTemperature(FluidTankTileEntity controller) { + BlockPos controllerPos = controller.getBlockPos(); + Level level = controller.getLevel(); + float prev = targetTemperature; + targetTemperature = 0; + needsTemperatureUpdate = false; + + for (int xOffset = 0; xOffset < controller.width; xOffset++) { + for (int zOffset = 0; zOffset < controller.width; zOffset++) { + BlockPos pos = controllerPos.offset(xOffset, -1, zOffset); + BlockState blockState = level.getBlockState(pos); + targetTemperature += BoilerHeaters.getAddedHeatOf(blockState); + } + } + + if (targetTemperature != 0) + targetTemperature += 100; + + return prev != attachedEngines; + } + + public boolean isActive() { + return attachedEngines > 0; + } + + public void clear() { + waterSupply = 0; + targetTemperature = 0; + attachedEngines = 0; + steamUnits = 0; + engineScore = 0; + Arrays.fill(supplyOverTime, 0); + } + + public CompoundTag write() { + CompoundTag nbt = new CompoundTag(); + nbt.putFloat("Supply", waterSupply); + nbt.putFloat("Temperature", currentTemperature); + nbt.putFloat("Power", targetTemperature); + nbt.putFloat("Pressure", steamUnits); + nbt.putInt("Engines", attachedEngines); + nbt.putBoolean("Update", needsTemperatureUpdate); + nbt.putInt("Score", engineScore); + return nbt; + } + + public void read(CompoundTag nbt, int capacity) { + waterSupply = nbt.getFloat("Supply"); + currentTemperature = nbt.getFloat("Temperature"); + targetTemperature = nbt.getFloat("Power"); + steamUnits = nbt.getFloat("Pressure"); + engineScore = nbt.getInt("Score"); + attachedEngines = nbt.getInt("Engines"); + needsTemperatureUpdate = nbt.getBoolean("Update"); + Arrays.fill(supplyOverTime, (int) waterSupply); + if (capacity > 0) + pressure.chase(steamUnits / capacity, 0.125f, Chaser.EXP); + } + + public BoilerFluidHandler createHandler() { + return new BoilerFluidHandler(); + } + + public class BoilerFluidHandler implements IFluidHandler { + + @Override + public int getTanks() { + return 1; + } + + @Override + public FluidStack getFluidInTank(int tank) { + return FluidStack.EMPTY; + } + + @Override + public int getTankCapacity(int tank) { + return 10000; + } + + @Override + public boolean isFluidValid(int tank, FluidStack stack) { + return FluidHelper.isWater(stack.getFluid()); + } + + @Override + public int fill(FluidStack resource, FluidAction action) { + if (!isFluidValid(0, resource)) + return 0; + if (targetTemperature == 0) + return 0; + int amount = resource.getAmount(); + if (action.execute()) + gatheredSupply += amount; + return amount; + } + + @Override + public FluidStack drain(FluidStack resource, FluidAction action) { + return FluidStack.EMPTY; + } + + @Override + public FluidStack drain(int maxDrain, FluidAction action) { + return FluidStack.EMPTY; + } + + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/BoilerHeaters.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/BoilerHeaters.java new file mode 100644 index 000000000..acf03c379 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/BoilerHeaters.java @@ -0,0 +1,39 @@ +package com.simibubi.create.content.contraptions.fluids.tank; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllTags.AllBlockTags; +import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock; +import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel; + +import net.minecraft.world.level.block.AbstractFurnaceBlock; +import net.minecraft.world.level.block.state.BlockState; + +public class BoilerHeaters { // API? + + public static float getAddedHeatOf(BlockState state) { + if (AllBlocks.BLAZE_BURNER.has(state)) { + HeatLevel value = state.getValue(BlazeBurnerBlock.HEAT_LEVEL); + switch (value) { + case SMOULDERING: + return 24; + case FADING: + case KINDLED: + return 96; + case SEETHING: + return 32 * 8; + default: + case NONE: + return 0; + } + } + if (state.hasProperty(AbstractFurnaceBlock.LIT) && !state.getValue(AbstractFurnaceBlock.LIT)) + return 0; + if (AllBlockTags.ACTIVE_BOILER_HEATERS.matches(state)) + return 48; + if (AllBlockTags.PASSIVE_BOILER_HEATERS.matches(state)) + return 12; + return 0; + + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankBlock.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankBlock.java index f128fba7a..26ac6e4de 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankBlock.java @@ -12,6 +12,7 @@ import com.simibubi.create.foundation.tileEntity.ComparatorUtil; import com.simibubi.create.foundation.utility.Lang; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.core.particles.BlockParticleOption; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.sounds.SoundEvent; @@ -28,6 +29,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Mirror; @@ -90,7 +92,7 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE p_206840_1_) { p_206840_1_.add(TOP, BOTTOM, SHAPE); } - + @Override public int getLightEmission(BlockState state, BlockGetter world, BlockPos pos) { FluidTankTileEntity tankAt = FluidTankConnectivityHandler.anyTankAt(world, pos); @@ -108,6 +110,14 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE getTileEntityClass() { return FluidTankTileEntity.class; } - + @Override public BlockEntityType getTileEntityType() { return creative ? AllTileEntities.CREATIVE_FLUID_TANK.get() : AllTileEntities.FLUID_TANK.get(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankConnectivityHandler.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankConnectivityHandler.java index 5bd68dcca..de42a06f9 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankConnectivityHandler.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankConnectivityHandler.java @@ -26,10 +26,7 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.capability.CapabilityFluidHandler; -import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction; import net.minecraftforge.fluids.capability.templates.FluidTank; @@ -139,6 +136,7 @@ public class FluidTankConnectivityHandler { te.setWindows(te.window); te.onFluidStackChanged(te.tankInventory.getFluid()); + te.updateBoilerState(); te.setChanged(); } @@ -152,10 +150,8 @@ public class FluidTankConnectivityHandler { BlockEntityType type = te.getType(); Level world = te.getLevel(); BlockPos origin = te.getBlockPos(); - LazyOptional capability = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY); - FluidTank teTank = (FluidTank) capability.orElse(null); - FluidStack fluid = capability.map(ifh -> ifh.getFluidInTank(0)) - .orElse(FluidStack.EMPTY); + FluidTank teTank = te.tankInventory; + FluidStack fluid = te.tankInventory.getFluidInTank(0); Search: @@ -236,7 +232,6 @@ public class FluidTankConnectivityHandler { } te.setWindows(!opaque); - return amount; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankRenderer.java index a8311a3c4..a247708f4 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankRenderer.java @@ -1,30 +1,40 @@ package com.simibubi.create.content.contraptions.fluids.tank; +import com.jozufozu.flywheel.util.transform.TransformStack; import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.simibubi.create.AllBlockPartials; import com.simibubi.create.foundation.fluid.FluidRenderer; +import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; -import com.simibubi.create.foundation.utility.animation.InterpolatedChasingValue; +import com.simibubi.create.foundation.utility.Iterate; +import com.simibubi.create.foundation.utility.animation.LerpedFloat; import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.core.Direction; import net.minecraft.util.Mth; +import net.minecraft.world.level.block.state.BlockState; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.templates.FluidTank; public class FluidTankRenderer extends SafeTileEntityRenderer { - public FluidTankRenderer(BlockEntityRendererProvider.Context context) { - } + public FluidTankRenderer(BlockEntityRendererProvider.Context context) {} @Override protected void renderSafe(FluidTankTileEntity te, float partialTicks, PoseStack ms, MultiBufferSource buffer, int light, int overlay) { if (!te.isController()) return; - if (!te.window) + if (!te.window) { + if (te.boiler.isActive()) + renderAsBoiler(te, partialTicks, ms, buffer, light, overlay); return; + } - InterpolatedChasingValue fluidLevel = te.getFluidLevel(); + LerpedFloat fluidLevel = te.getFluidLevel(); if (fluidLevel == null) return; @@ -33,7 +43,7 @@ public class FluidTankRenderer extends SafeTileEntityRenderer type, BlockPos pos, BlockState state) { super(type, pos, state); tankInventory = createInventory(); @@ -66,6 +69,7 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI window = true; height = 1; width = 1; + boiler = new BoilerData(); refreshCapability(); } @@ -101,9 +105,11 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI if (updateConnectivity) updateConnectivity(); if (fluidLevel != null) - fluidLevel.tick(); + fluidLevel.tickChaser(); + if (isController()) + boiler.tick(this); } - + @Override public BlockPos getLastKnownPos() { return lastKnownPos; @@ -111,8 +117,8 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI @Override public boolean isController() { - return controller == null - || worldPosition.getX() == controller.getX() && worldPosition.getY() == controller.getY() && worldPosition.getZ() == controller.getZ(); + return controller == null || worldPosition.getX() == controller.getX() + && worldPosition.getY() == controller.getY() && worldPosition.getZ() == controller.getZ(); } @Override @@ -161,11 +167,12 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI setChanged(); sendData(); } - + if (isVirtual()) { if (fluidLevel == null) - fluidLevel = new InterpolatedChasingValue().start(getFillState()); - fluidLevel.target(getFillState()); + fluidLevel = LerpedFloat.linear() + .startWithValue(getFillState()); + fluidLevel.chase(getFillState(), .5f, Chaser.EXP); } } @@ -204,6 +211,7 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI controller = null; width = 1; height = 1; + boiler.clear(); onFluidStackChanged(tankInventory.getFluid()); BlockState state = getBlockState(); @@ -223,8 +231,19 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI FluidTankTileEntity te = getControllerTE(); if (te == null) return; + if (te.boiler.isActive()) + return; te.setWindows(!te.window); } + + public void updateBoilerTemperature() { + FluidTankTileEntity te = getControllerTE(); + if (te == null) + return; + if (!te.boiler.isActive()) + return; + te.boiler.needsTemperatureUpdate = true; + } public void sendDataImmediately() { syncCooldown = 0; @@ -277,6 +296,22 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI } } + public void updateBoilerState() { + if (!isController()) + return; + + boolean wasBoiler = boiler.isActive(); + boolean changed = boiler.evaluate(this); + + if (wasBoiler != boiler.isActive()) { + if (boiler.isActive()) + setWindows(false); + refreshCapability(); + } + if (changed) + notifyUpdate(); + } + @Override public void setController(BlockPos controller) { if (level.isClientSide && !isVirtual()) @@ -291,11 +326,15 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI private void refreshCapability() { LazyOptional oldCap = fluidCapability; - fluidCapability = LazyOptional.of(() -> isController() ? tankInventory - : getControllerTE() != null ? getControllerTE().tankInventory : new FluidTank(0)); + fluidCapability = LazyOptional.of(() -> handlerForCapability()); oldCap.invalidate(); } + private IFluidHandler handlerForCapability() { + return isController() ? boiler.isActive() ? boiler.createHandler() : tankInventory + : getControllerTE() != null ? getControllerTE().handlerForCapability() : new FluidTank(0); + } + @Override public BlockPos getController() { return isController() ? worldPosition : controller; @@ -322,6 +361,8 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI FluidTankTileEntity controllerTE = getControllerTE(); if (controllerTE == null) return false; + if (controllerTE.boiler.addToGoggleTooltip(tooltip, isPlayerSneaking)) + return true; return containedFluidTooltip(tooltip, isPlayerSneaking, controllerTE.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)); } @@ -354,10 +395,12 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI if (tankInventory.getSpace() < 0) tankInventory.drain(-tankInventory.getSpace(), FluidAction.EXECUTE); } + + boiler.read(compound.getCompound("Boiler"), tankInventory.getCapacity()); if (compound.contains("ForceFluidLevel") || fluidLevel == null) - fluidLevel = new InterpolatedChasingValue().start(getFillState()) - .withSpeed(1 / 2f); + fluidLevel = LerpedFloat.linear() + .startWithValue(getFillState()); if (!clientPacket) return; @@ -374,8 +417,9 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI if (isController()) { float fillState = getFillState(); if (compound.contains("ForceFluidLevel") || fluidLevel == null) - fluidLevel = new InterpolatedChasingValue().start(fillState); - fluidLevel.target(fillState); + fluidLevel = LerpedFloat.linear() + .startWithValue(fillState); + fluidLevel.chase(fillState, 0.5f, Chaser.EXP); } if (luminosity != prevLum && hasLevel()) level.getChunkSource() @@ -383,7 +427,7 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI .checkBlock(worldPosition); if (compound.contains("LazySync")) - fluidLevel.withSpeed(compound.contains("LazySync") ? 1 / 8f : 1 / 2f); + fluidLevel.chase(fluidLevel.getChaseTarget(), 0.125f, Chaser.EXP); } public float getFillState() { @@ -394,6 +438,7 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI public void write(CompoundTag compound, boolean clientPacket) { if (updateConnectivity) compound.putBoolean("Uninitialized", true); + compound.put("Boiler", boiler.write()); if (lastKnownPos != null) compound.put("LastKnownPos", NbtUtils.writeBlockPos(lastKnownPos)); if (!isController()) @@ -454,11 +499,11 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI return AllConfigs.SERVER.fluids.fluidTankMaxHeight.get(); } - public InterpolatedChasingValue getFluidLevel() { + public LerpedFloat getFluidLevel() { return fluidLevel; } - public void setFluidLevel(InterpolatedChasingValue fluidLevel) { + public void setFluidLevel(LerpedFloat fluidLevel) { this.fluidLevel = fluidLevel; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/item/BeltConnectorItem.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/item/BeltConnectorItem.java index 5f0ce683a..03d894716 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/item/BeltConnectorItem.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/item/BeltConnectorItem.java @@ -11,7 +11,7 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.relays.belt.BeltBlock; import com.simibubi.create.content.contraptions.relays.belt.BeltPart; import com.simibubi.create.content.contraptions.relays.belt.BeltSlope; -import com.simibubi.create.content.contraptions.relays.elementary.AbstractShaftBlock; +import com.simibubi.create.content.contraptions.relays.elementary.AbstractSimpleShaftBlock; import com.simibubi.create.content.contraptions.relays.elementary.ShaftBlock; import com.simibubi.create.foundation.advancement.AllTriggers; import com.simibubi.create.foundation.config.AllConfigs; @@ -141,7 +141,7 @@ public class BeltConnectorItem extends BlockItem { boolean pulley = ShaftBlock.isShaft(shaftState); if (part == BeltPart.MIDDLE && pulley) part = BeltPart.PULLEY; - if (pulley && shaftState.getValue(AbstractShaftBlock.AXIS) == Axis.Y) + if (pulley && shaftState.getValue(AbstractSimpleShaftBlock.AXIS) == Axis.Y) slope = BeltSlope.SIDEWAYS; KineticTileEntity.switchToBlockState(world, pos, beltBlock.setValue(BeltBlock.SLOPE, slope) .setValue(BeltBlock.PART, part) @@ -244,7 +244,7 @@ public class BeltConnectorItem extends BlockItem { for (BlockPos currentPos = first.offset(step); !currentPos.equals(second) && limit-- > 0; currentPos = currentPos.offset(step)) { BlockState blockState = world.getBlockState(currentPos); - if (ShaftBlock.isShaft(blockState) && blockState.getValue(AbstractShaftBlock.AXIS) == shaftAxis) + if (ShaftBlock.isShaft(blockState) && blockState.getValue(AbstractSimpleShaftBlock.AXIS) == shaftAxis) continue; if (!blockState.getMaterial() .isReplaceable()) diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/AbstractShaftBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/AbstractShaftBlock.java index 57289662f..47be6d5c1 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/AbstractShaftBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/AbstractShaftBlock.java @@ -1,38 +1,27 @@ package com.simibubi.create.content.contraptions.relays.elementary; -import java.util.Optional; - -import com.simibubi.create.AllTileEntities; +import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.RotatedPillarKineticBlock; -import com.simibubi.create.content.contraptions.wrench.IWrenchableWithBracket; import com.simibubi.create.foundation.block.ITE; -import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Direction.Axis; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.SimpleWaterloggedBlock; -import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition.Builder; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.material.Fluids; -import net.minecraft.world.level.material.PushReaction; import net.minecraft.world.level.pathfinder.PathComputationType; public abstract class AbstractShaftBlock extends RotatedPillarKineticBlock - implements ITE, SimpleWaterloggedBlock, IWrenchableWithBracket { + implements ITE, SimpleWaterloggedBlock { public AbstractShaftBlock(Properties properties) { super(properties); @@ -40,25 +29,15 @@ public abstract class AbstractShaftBlock extends RotatedPillarKineticBlock } @Override - public InteractionResult onWrenched(BlockState state, UseOnContext context) { - return IWrenchableWithBracket.super.onWrenched(state, context); + public boolean isPathfindable(BlockState state, BlockGetter reader, BlockPos pos, PathComputationType type) { + return false; } @Override - public PushReaction getPistonPushReaction(BlockState state) { - return PushReaction.NORMAL; + public Class getTileEntityClass() { + return KineticTileEntity.class; } - @Override - @SuppressWarnings("deprecation") - public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean isMoving) { - if (state != newState && !isMoving) - removeBracket(world, pos, true).ifPresent(stack -> Block.popResource(world, pos, stack)); - super.onRemove(state, world, pos, newState, isMoving); - } - - // IRotate: - @Override public boolean hasShaftTowards(LevelReader world, BlockPos pos, BlockState state, Direction face) { return face.getAxis() == state.getValue(AXIS); @@ -84,7 +63,7 @@ public abstract class AbstractShaftBlock extends RotatedPillarKineticBlock @Override public BlockState updateShape(BlockState state, Direction direction, BlockState neighbourState, LevelAccessor world, BlockPos pos, BlockPos neighbourPos) { - if (state.getValue(BlockStateProperties.WATERLOGGED)) + if (state.getValue(BlockStateProperties.WATERLOGGED)) world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); return state; } @@ -97,31 +76,4 @@ public abstract class AbstractShaftBlock extends RotatedPillarKineticBlock Boolean.valueOf(ifluidstate.getType() == Fluids.WATER)); } - @Override - public Optional removeBracket(BlockGetter world, BlockPos pos, boolean inOnReplacedContext) { - BracketedTileEntityBehaviour behaviour = TileEntityBehaviour.get(world, pos, BracketedTileEntityBehaviour.TYPE); - if (behaviour == null) - return Optional.empty(); - BlockState bracket = behaviour.getBracket(); - behaviour.removeBracket(inOnReplacedContext); - if (bracket == Blocks.AIR.defaultBlockState()) - return Optional.empty(); - return Optional.of(new ItemStack(bracket.getBlock())); - } - - @Override - public boolean isPathfindable(BlockState state, BlockGetter reader, BlockPos pos, PathComputationType type) { - return false; - } - - @Override - public Class getTileEntityClass() { - return SimpleKineticTileEntity.class; - } - - @Override - public BlockEntityType getTileEntityType() { - return AllTileEntities.BRACKETED_KINETIC.get(); - } - } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/AbstractSimpleShaftBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/AbstractSimpleShaftBlock.java new file mode 100644 index 000000000..85f84b697 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/AbstractSimpleShaftBlock.java @@ -0,0 +1,63 @@ +package com.simibubi.create.content.contraptions.relays.elementary; + +import java.util.Optional; + +import com.simibubi.create.AllTileEntities; +import com.simibubi.create.content.contraptions.base.KineticTileEntity; +import com.simibubi.create.content.contraptions.wrench.IWrenchableWithBracket; +import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.PushReaction; + +public abstract class AbstractSimpleShaftBlock extends AbstractShaftBlock implements IWrenchableWithBracket { + + public AbstractSimpleShaftBlock(Properties properties) { + super(properties); + } + + @Override + public InteractionResult onWrenched(BlockState state, UseOnContext context) { + return IWrenchableWithBracket.super.onWrenched(state, context); + } + + @Override + public PushReaction getPistonPushReaction(BlockState state) { + return PushReaction.NORMAL; + } + + @Override + @SuppressWarnings("deprecation") + public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean isMoving) { + if (state != newState && !isMoving) + removeBracket(world, pos, true).ifPresent(stack -> Block.popResource(world, pos, stack)); + super.onRemove(state, world, pos, newState, isMoving); + } + + @Override + public Optional removeBracket(BlockGetter world, BlockPos pos, boolean inOnReplacedContext) { + BracketedTileEntityBehaviour behaviour = TileEntityBehaviour.get(world, pos, BracketedTileEntityBehaviour.TYPE); + if (behaviour == null) + return Optional.empty(); + BlockState bracket = behaviour.getBracket(); + behaviour.removeBracket(inOnReplacedContext); + if (bracket == Blocks.AIR.defaultBlockState()) + return Optional.empty(); + return Optional.of(new ItemStack(bracket.getBlock())); + } + + @Override + public BlockEntityType getTileEntityType() { + return AllTileEntities.BRACKETED_KINETIC.get(); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/BracketedKineticTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/BracketedKineticTileEntity.java index 840c10fa7..552c861bf 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/BracketedKineticTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/BracketedKineticTileEntity.java @@ -19,7 +19,7 @@ public class BracketedKineticTileEntity extends SimpleKineticTileEntity implemen @Override public void addBehaviours(List behaviours) { - behaviours.add(new BracketedTileEntityBehaviour(this, state -> state.getBlock() instanceof AbstractShaftBlock) + behaviours.add(new BracketedTileEntityBehaviour(this, state -> state.getBlock() instanceof AbstractSimpleShaftBlock) .withTrigger(state -> AllTriggers.BRACKET_APPLY_TRIGGER.constructTriggerFor(state.getBlock()))); super.addBehaviours(behaviours); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/CogWheelBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/CogWheelBlock.java index 19962113a..617f53263 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/CogWheelBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/CogWheelBlock.java @@ -33,7 +33,7 @@ import net.minecraft.world.phys.shapes.VoxelShape; @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault -public class CogWheelBlock extends AbstractShaftBlock implements ICogWheel { +public class CogWheelBlock extends AbstractSimpleShaftBlock implements ICogWheel { boolean isLarge; diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/ShaftBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/ShaftBlock.java index 2fd7e911a..b6f589da3 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/ShaftBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/elementary/ShaftBlock.java @@ -7,6 +7,7 @@ import java.util.function.Predicate; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllShapes; import com.simibubi.create.content.contraptions.base.KineticTileEntity; +import com.simibubi.create.content.contraptions.components.steam.PoweredShaftBlock; import com.simibubi.create.content.contraptions.relays.encased.EncasedShaftBlock; import com.simibubi.create.content.curiosities.girder.GirderEncasedShaftBlock; import com.simibubi.create.foundation.advancement.AllTriggers; @@ -23,6 +24,7 @@ import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; @@ -30,7 +32,7 @@ import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; -public class ShaftBlock extends AbstractShaftBlock { +public class ShaftBlock extends AbstractSimpleShaftBlock { private static final int placementHelperId = PlacementHelpers.register(new PlacementHelper()); @@ -42,6 +44,14 @@ public class ShaftBlock extends AbstractShaftBlock { return AllBlocks.SHAFT.has(state); } + @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { + BlockState stateForPlacement = super.getStateForPlacement(context); + if (PoweredShaftBlock.stillValid(stateForPlacement, context.getLevel(), context.getClickedPos())) + return PoweredShaftBlock.getEquivalent(stateForPlacement); + return stateForPlacement; + } + @Override public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) { return AllShapes.SIX_VOXEL_POLE.get(state.getValue(AXIS)); @@ -106,13 +116,13 @@ public class ShaftBlock extends AbstractShaftBlock { // shafts and cogs private PlacementHelper() { - super(state -> state.getBlock() instanceof AbstractShaftBlock, state -> state.getValue(AXIS), AXIS); + super(state -> state.getBlock() instanceof AbstractSimpleShaftBlock, state -> state.getValue(AXIS), AXIS); } @Override public Predicate getItemPredicate() { return i -> i.getItem() instanceof BlockItem - && ((BlockItem) i.getItem()).getBlock() instanceof AbstractShaftBlock; + && ((BlockItem) i.getItem()).getBlock() instanceof AbstractSimpleShaftBlock; } @Override diff --git a/src/main/java/com/simibubi/create/content/curiosities/girder/GirderBlock.java b/src/main/java/com/simibubi/create/content/curiosities/girder/GirderBlock.java index b74b5b2e4..29ae93931 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/girder/GirderBlock.java +++ b/src/main/java/com/simibubi/create/content/curiosities/girder/GirderBlock.java @@ -125,7 +125,8 @@ public class GirderBlock extends Block implements SimpleWaterloggedBlock, IWrenc Axis axis = direction.getAxis(); Property updateProperty = axis == Axis.X ? X : axis == Axis.Z ? Z : direction == Direction.UP ? TOP : BOTTOM; - state = state.setValue(updateProperty, false); + if (!isConnected(world, pos, state, direction) && !isConnected(world, pos, state, direction.getOpposite())) + state = state.setValue(updateProperty, false); for (Direction d : Iterate.directionsInAxis(axis)) state = updateState(world, pos, state, d); return state; @@ -158,9 +159,11 @@ public class GirderBlock extends Block implements SimpleWaterloggedBlock, IWrenc if (sideState.getBlock() instanceof GirderEncasedShaftBlock && sideState.getValue(GirderEncasedShaftBlock.HORIZONTAL_AXIS) != axis) state = state.setValue(updateProperty, true); - if (sideState.getBlock() == state.getBlock() && sideState.getValue(updateProperty)) + else if (sideState.getBlock() == state.getBlock() && sideState.getValue(updateProperty)) state = state.setValue(updateProperty, true); - if (sideState.getBlock() instanceof NixieTubeBlock && NixieTubeBlock.getFacing(sideState) == d) + else if (sideState.getBlock() instanceof NixieTubeBlock && NixieTubeBlock.getFacing(sideState) == d) + state = state.setValue(updateProperty, true); + else if (isFacingBracket(level, pos, d)) state = state.setValue(updateProperty, true); for (Direction d2 : Iterate.directionsInAxis(axis == Axis.X ? Axis.Z : Axis.X)) { @@ -176,33 +179,51 @@ public class GirderBlock extends Block implements SimpleWaterloggedBlock, IWrenc return state; } + public static boolean isFacingBracket(BlockAndTintGetter level, BlockPos pos, Direction d) { + BlockEntity blockEntity = level.getBlockEntity(pos.relative(d)); + if (!(blockEntity instanceof SmartTileEntity ste)) + return false; + BracketedTileEntityBehaviour behaviour = ste.getBehaviour(BracketedTileEntityBehaviour.TYPE); + if (behaviour == null) + return false; + BlockState bracket = behaviour.getBracket(); + if (!bracket.hasProperty(BracketBlock.FACING)) + return false; + return bracket.getValue(BracketBlock.FACING) == d; + } + public static BlockState updateVerticalProperty(LevelAccessor level, BlockPos pos, BlockState state, Property updateProperty, BlockState sideState, Direction d) { - if (sideState.getBlock() == state.getBlock() && sideState.getValue(X) == sideState.getValue(Z)) + if (isGirder(sideState) && isXGirder(sideState) == isZGirder(sideState)) state = state.setValue(updateProperty, true); - else if (sideState.getBlock() == state.getBlock() && sideState.getValue(X) != state.getValue(X) - && sideState.getValue(Z) != state.getValue(Z)) + else if (isGirder(sideState) && isXGirder(sideState) != isXGirder(state) + && isZGirder(sideState) != isZGirder(state)) state = state.setValue(updateProperty, true); else if (sideState.hasProperty(WallBlock.UP) && sideState.getValue(WallBlock.UP)) state = state.setValue(updateProperty, true); else if (sideState.getBlock() instanceof NixieTubeBlock && NixieTubeBlock.getFacing(sideState) == d) state = state.setValue(updateProperty, true); - else if (sideState.hasBlockEntity()) { - BlockEntity blockEntity = level.getBlockEntity(pos.relative(d)); - if (!(blockEntity instanceof SmartTileEntity ste)) - return state; - BracketedTileEntityBehaviour behaviour = ste.getBehaviour(BracketedTileEntityBehaviour.TYPE); - if (behaviour == null) - return state; - BlockState bracket = behaviour.getBracket(); - if (!bracket.hasProperty(BracketBlock.FACING)) - return state; - if (bracket.getValue(BracketBlock.FACING) == d) - state = state.setValue(updateProperty, true); - } + else if (isFacingBracket(level, pos, d)) + state = state.setValue(updateProperty, true); return state; } + public static boolean isGirder(BlockState state) { + return state.getBlock() instanceof GirderBlock || state.getBlock() instanceof GirderEncasedShaftBlock; + } + + public static boolean isXGirder(BlockState state) { + return (state.getBlock() instanceof GirderBlock && state.getValue(X)) + || (state.getBlock() instanceof GirderEncasedShaftBlock + && state.getValue(GirderEncasedShaftBlock.HORIZONTAL_AXIS) == Axis.Z); + } + + public static boolean isZGirder(BlockState state) { + return (state.getBlock() instanceof GirderBlock && state.getValue(Z)) + || (state.getBlock() instanceof GirderEncasedShaftBlock + && state.getValue(GirderEncasedShaftBlock.HORIZONTAL_AXIS) == Axis.X); + } + @Override public VoxelShape getShape(BlockState state, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) { boolean x = state.getValue(GirderBlock.X); @@ -221,7 +242,7 @@ public class GirderBlock extends Block implements SimpleWaterloggedBlock, IWrenc if (state.getBlock() instanceof GirderBlock && !state.getValue(axis == Axis.X ? X : Z)) return false; if (state.getBlock() instanceof GirderEncasedShaftBlock - && state.getValue(GirderEncasedShaftBlock.HORIZONTAL_AXIS) != axis) + && state.getValue(GirderEncasedShaftBlock.HORIZONTAL_AXIS) == axis) return false; BlockPos relative = pos.relative(side); BlockState blockState = world.getBlockState(relative); @@ -229,6 +250,8 @@ public class GirderBlock extends Block implements SimpleWaterloggedBlock, IWrenc return false; if (blockState.getBlock() instanceof NixieTubeBlock && NixieTubeBlock.getFacing(blockState) == side) return true; + if (isFacingBracket(world, pos, side)) + return true; VoxelShape shape = blockState.getShape(world, relative); if (shape.isEmpty()) return false; diff --git a/src/main/java/com/simibubi/create/content/schematics/block/LaunchedItem.java b/src/main/java/com/simibubi/create/content/schematics/block/LaunchedItem.java index 99f97cf6f..0f9fc901d 100644 --- a/src/main/java/com/simibubi/create/content/schematics/block/LaunchedItem.java +++ b/src/main/java/com/simibubi/create/content/schematics/block/LaunchedItem.java @@ -6,7 +6,7 @@ import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.relays.belt.BeltBlock; import com.simibubi.create.content.contraptions.relays.belt.BeltPart; import com.simibubi.create.content.contraptions.relays.belt.item.BeltConnectorItem; -import com.simibubi.create.content.contraptions.relays.elementary.AbstractShaftBlock; +import com.simibubi.create.content.contraptions.relays.elementary.AbstractSimpleShaftBlock; import com.simibubi.create.foundation.utility.BlockHelper; import net.minecraft.core.BlockPos; @@ -153,7 +153,7 @@ public abstract class LaunchedItem { BlockPos offset = BeltBlock.nextSegmentPosition(state, BlockPos.ZERO, isStart); int i = length - 1; Axis axis = state.getValue(BeltBlock.HORIZONTAL_FACING).getClockWise().getAxis(); - world.setBlockAndUpdate(target, AllBlocks.SHAFT.getDefaultState().setValue(AbstractShaftBlock.AXIS, axis)); + world.setBlockAndUpdate(target, AllBlocks.SHAFT.getDefaultState().setValue(AbstractSimpleShaftBlock.AXIS, axis)); BeltConnectorItem .createBelts(world, target, target.offset(offset.getX() * i, offset.getY() * i, offset.getZ() * i)); } diff --git a/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonTileEntity.java b/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonTileEntity.java index 057ea73dd..af727e8fe 100644 --- a/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonTileEntity.java +++ b/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonTileEntity.java @@ -14,7 +14,7 @@ import com.simibubi.create.content.contraptions.relays.belt.BeltBlock; import com.simibubi.create.content.contraptions.relays.belt.BeltPart; import com.simibubi.create.content.contraptions.relays.belt.BeltSlope; import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity; -import com.simibubi.create.content.contraptions.relays.elementary.AbstractShaftBlock; +import com.simibubi.create.content.contraptions.relays.elementary.AbstractSimpleShaftBlock; import com.simibubi.create.content.schematics.ItemRequirement; import com.simibubi.create.content.schematics.ItemRequirement.ItemUseType; import com.simibubi.create.content.schematics.MaterialChecklist; @@ -710,7 +710,7 @@ public class SchematicannonTileEntity extends SmartTileEntity implements MenuPro if (!isLastSegment) blockState = (blockState.getValue(BeltBlock.PART) == BeltPart.MIDDLE) ? Blocks.AIR.defaultBlockState() : AllBlocks.SHAFT.getDefaultState() - .setValue(AbstractShaftBlock.AXIS, facing.getClockWise() + .setValue(AbstractSimpleShaftBlock.AXIS, facing.getClockWise() .getAxis()); return blockState; } diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/ValueBoxRenderer.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/ValueBoxRenderer.java index 56d201d34..79e188a9f 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/ValueBoxRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/ValueBoxRenderer.java @@ -1,7 +1,7 @@ package com.simibubi.create.foundation.tileEntity.behaviour; import com.mojang.blaze3d.vertex.PoseStack; -import com.simibubi.create.content.contraptions.relays.elementary.AbstractShaftBlock; +import com.simibubi.create.content.contraptions.relays.elementary.AbstractSimpleShaftBlock; import com.simibubi.create.content.logistics.item.filter.FilterItem; import net.minecraft.client.Minecraft; @@ -37,7 +37,7 @@ public class ValueBoxRenderer { return NUDGE; if (item instanceof BlockItem) { Block block = ((BlockItem) item).getBlock(); - if (block instanceof AbstractShaftBlock) + if (block instanceof AbstractSimpleShaftBlock) return NUDGE; if (block instanceof FenceBlock) return NUDGE; diff --git a/src/main/java/com/simibubi/create/foundation/utility/animation/LerpedFloat.java b/src/main/java/com/simibubi/create/foundation/utility/animation/LerpedFloat.java index 5f6ac78f7..a8c2892de 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/animation/LerpedFloat.java +++ b/src/main/java/com/simibubi/create/foundation/utility/animation/LerpedFloat.java @@ -69,6 +69,10 @@ public class LerpedFloat { value = chaseFunction.chase(value, chaseSpeed, chaseTarget); } + public void setValueNoUpdate(double value) { + this.value = (float) value; + } + public void setValue(double value) { this.previousValue = this.value; this.value = (float) value; diff --git a/src/main/resources/assets/create/models/block/powered_shaft.json b/src/main/resources/assets/create/models/block/powered_shaft.json new file mode 100644 index 000000000..ae13b5392 --- /dev/null +++ b/src/main/resources/assets/create/models/block/powered_shaft.json @@ -0,0 +1,42 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "2": "create:block/axis_top", + "3": "create:block/axis", + "particle": "create:block/axis" + }, + "elements": [ + { + "from": [6, 0, 6], + "to": [10, 2, 10], + "rotation": {"angle": 0, "axis": "x", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [6, 0, 10, 2], "texture": "#3"}, + "east": {"uv": [6, 0, 10, 2], "rotation": 180, "texture": "#3"}, + "south": {"uv": [6, 0, 10, 2], "texture": "#3"}, + "west": {"uv": [6, 0, 10, 2], "texture": "#3"}, + "down": {"uv": [6, 6, 10, 10], "rotation": 180, "texture": "#2"} + } + }, + { + "from": [6, 14, 6], + "to": [10, 16, 10], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [6, 0, 10, 2], "rotation": 180, "texture": "#3"}, + "east": {"uv": [6, 0, 10, 2], "rotation": 180, "texture": "#3"}, + "south": {"uv": [6, 0, 10, 2], "rotation": 180, "texture": "#3"}, + "west": {"uv": [6, 0, 10, 2], "texture": "#3"}, + "up": {"uv": [6, 6, 10, 10], "texture": "#2"} + } + } + ], + "groups": [ + { + "name": "Cam", + "origin": [-7.5, 18, 8], + "color": 0, + "children": [0, 1] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/steam_engine/Steam Piston.bbmodel b/src/main/resources/assets/create/models/block/steam_engine/Steam Piston.bbmodel new file mode 100644 index 000000000..c1e8ec7c6 --- /dev/null +++ b/src/main/resources/assets/create/models/block/steam_engine/Steam Piston.bbmodel @@ -0,0 +1 @@ +{"meta":{"format_version":"4.0","creation_time":1645009708,"model_format":"java_block","box_uv":false},"name":"Steam Piston","parent":"","ambientocclusion":true,"front_gui_light":false,"visible_box":[1,1,0],"variable_placeholders":"","resolution":{"width":16,"height":16},"elements":[{"name":"cube","rescale":false,"locked":false,"from":[5,3,5],"to":[11,22,11],"autouv":0,"color":7,"origin":[0,0,0],"faces":{"north":{"uv":[4,6.5,7,16],"texture":0},"east":{"uv":[1,6.5,4,16],"texture":0},"south":{"uv":[4,6.5,7,16],"texture":0},"west":{"uv":[1,6.5,4,16],"texture":0},"up":{"uv":[4,3.5,7,6.5],"texture":0},"down":{"uv":[0,0,0,0],"texture":null}},"uuid":"bb5f68d8-d633-6589-b61a-ac1f08516ef1"},{"name":"cube","rescale":false,"locked":false,"from":[1,0,1],"to":[15,3,15],"autouv":0,"color":4,"origin":[0,0,0],"faces":{"north":{"uv":[0.5,6.5,7.5,8],"texture":1},"east":{"uv":[0.5,6.5,7.5,8],"texture":1},"south":{"uv":[0.5,6.5,7.5,8],"texture":1},"west":{"uv":[0.5,6.5,7.5,8],"texture":1},"up":{"uv":[0.5,8.5,7.5,15.5],"rotation":90,"texture":1},"down":{"uv":[8.5,8.5,15.5,15.5],"rotation":270,"texture":1}},"uuid":"1758ddcd-ecbd-3569-9c40-06e40b82914b"},{"name":"cube","rescale":false,"locked":false,"from":[3,3,3],"to":[13,15,13],"autouv":0,"color":3,"origin":[0,0,0],"faces":{"north":{"uv":[1.5,0.5,6.5,6.5],"texture":1},"east":{"uv":[1.5,0.5,6.5,6.5],"texture":1},"south":{"uv":[1.5,0.5,6.5,6.5],"texture":1},"west":{"uv":[1.5,0.5,6.5,6.5],"texture":1},"up":{"uv":[6.5,0,11.5,5],"rotation":90,"texture":1},"down":{"uv":[0,0,0,0],"rotation":270,"texture":null}},"uuid":"10fc7e13-136d-fe5a-12e8-5ab0d56572d2"},{"name":"cube","rescale":false,"locked":false,"from":[13,5,4],"to":[15,13,12],"autouv":0,"color":5,"origin":[0,0,0],"faces":{"north":{"uv":[11.5,0,15.5,1],"rotation":90,"texture":1},"east":{"uv":[11.5,1,15.5,5],"texture":1},"south":{"uv":[11.5,0,15.5,1],"rotation":270,"texture":1},"west":{"uv":[0,0,0,0],"texture":null},"up":{"uv":[11.5,0,15.5,1],"rotation":270,"texture":1},"down":{"uv":[11.5,0,15.5,1],"rotation":270,"texture":1}},"uuid":"84d1f78c-210d-d43e-7c3e-c44dbccd739e"},{"name":"cube","rescale":false,"locked":false,"from":[1,5,4],"to":[3,13,12],"autouv":0,"color":3,"origin":[0,0,8],"faces":{"north":{"uv":[11.5,0,15.5,1],"rotation":270,"texture":1},"east":{"uv":[0,0,0,0],"texture":null},"south":{"uv":[11.5,0,15.5,1],"rotation":90,"texture":1},"west":{"uv":[11.5,1,15.5,5],"texture":1},"up":{"uv":[11.5,0,15.5,1],"rotation":90,"texture":1},"down":{"uv":[11.5,0,15.5,1],"rotation":90,"texture":1}},"uuid":"18bdbdbf-c454-d659-4a8c-a8858d177eef"},{"name":"cube","rescale":false,"locked":false,"from":[6,17,4],"to":[10,23,12],"autouv":0,"color":3,"origin":[0,0,0],"faces":{"north":{"uv":[8.5,11,10.5,14],"texture":0},"east":{"uv":[10.5,11,14.5,14],"texture":0},"south":{"uv":[8.5,11,10.5,14],"texture":0},"west":{"uv":[10.5,11,14.5,14],"texture":0},"up":{"uv":[10.5,9,14.5,11],"rotation":90,"texture":0},"down":{"uv":[10.5,14,14.5,16],"rotation":90,"texture":0}},"uuid":"af28fce2-d208-0379-54b4-7dc0c86a7ea3"},{"name":"cube","rescale":false,"locked":false,"from":[6,31,4],"to":[10,37,12],"autouv":0,"color":5,"origin":[0,0,0],"faces":{"north":{"uv":[8.5,11,10.5,14],"texture":0},"east":{"uv":[10.5,11,14.5,14],"texture":0},"south":{"uv":[8.5,11,10.5,14],"texture":0},"west":{"uv":[10.5,11,14.5,14],"texture":0},"up":{"uv":[10.5,9,14.5,11],"rotation":90,"texture":0},"down":{"uv":[10.5,14,14.5,16],"rotation":90,"texture":0}},"uuid":"3e9020ae-d9d2-cf05-68cc-0f8c69f877e0"},{"name":"cube","rescale":false,"locked":false,"from":[6,23,6],"to":[10,31,10],"autouv":0,"color":4,"origin":[0,0,0],"faces":{"north":{"uv":[1.5,1,3.5,6],"texture":0},"east":{"uv":[1.5,1,3.5,6],"texture":0},"south":{"uv":[1.5,1,3.5,6],"texture":0},"west":{"uv":[1.5,1,3.5,6],"texture":0},"up":{"uv":[0,0,0,0],"texture":null},"down":{"uv":[0,0,0,0],"texture":null}},"uuid":"1efd911a-c293-52f1-caf1-c5c9950b283d"},{"name":"cube","rescale":false,"locked":false,"from":[2,37,5],"to":[5,43,11],"autouv":0,"color":4,"origin":[8,24,8],"faces":{"north":{"uv":[9.5,1.5,11,4.5],"texture":0},"east":{"uv":[11,1.5,14,4.5],"texture":0},"south":{"uv":[9.5,1.5,11,4.5],"texture":0},"west":{"uv":[11,1.5,14,4.5],"texture":0},"up":{"uv":[11,0,14,1.5],"rotation":90,"texture":0},"down":{"uv":[11,4.5,14,6],"rotation":90,"texture":0}},"uuid":"13918418-0f93-bf99-b472-24afd4156970"},{"name":"cube","rescale":false,"locked":false,"from":[11,37,5],"to":[14,43,11],"autouv":0,"color":1,"origin":[8,24,8],"faces":{"north":{"uv":[9.5,1.5,11,4.5],"texture":0},"east":{"uv":[11,1.5,14,4.5],"texture":0},"south":{"uv":[9.5,1.5,11,4.5],"texture":0},"west":{"uv":[11,1.5,14,4.5],"texture":0},"up":{"uv":[11,0,14,1.5],"rotation":90,"texture":0},"down":{"uv":[11,4.5,14,6],"rotation":90,"texture":0}},"uuid":"2899e055-4fd8-4120-d61e-504018a868dd"},{"name":"cube","rescale":false,"locked":false,"from":[0,38,6],"to":[2,42,10],"autouv":0,"color":4,"origin":[0,0,0],"faces":{"north":{"uv":[6,0,10,2],"rotation":90,"texture":3},"east":{"uv":[0,0,0,0],"texture":null},"south":{"uv":[6,0,10,2],"rotation":90,"texture":3},"west":{"uv":[6,6,10,10],"texture":2},"up":{"uv":[6,0,10,2],"rotation":90,"texture":3},"down":{"uv":[6,0,10,2],"rotation":90,"texture":3}},"uuid":"26c50f51-a6e4-9674-ae96-9054706335aa"},{"name":"cube","rescale":false,"locked":false,"from":[14,38,6],"to":[16,42,10],"autouv":0,"color":6,"origin":[15,24,8],"faces":{"north":{"uv":[6,0,10,2],"rotation":90,"texture":3},"east":{"uv":[6,6,10,10],"texture":2},"south":{"uv":[6,0,10,2],"rotation":90,"texture":3},"west":{"uv":[0,0,0,0],"texture":null},"up":{"uv":[6,0,10,2],"rotation":270,"texture":3},"down":{"uv":[6,0,10,2],"rotation":270,"texture":3}},"uuid":"f2ab5727-659d-b068-2849-7438bbd0f2a4"},{"name":"cube","rescale":false,"locked":false,"from":[3,31,5],"to":[6,37,11],"autouv":0,"color":5,"origin":[-7.5,18,8],"faces":{"north":{"uv":[9.5,1.5,11,4.5],"rotation":180,"texture":0},"east":{"uv":[11,1.5,14,4.5],"rotation":180,"texture":0},"south":{"uv":[9.5,1.5,11,4.5],"rotation":180,"texture":0},"west":{"uv":[11,1.5,14,4.5],"rotation":180,"texture":0},"up":{"uv":[11,4.5,14,6],"rotation":90,"texture":0},"down":{"uv":[11,0,14,1.5],"rotation":90,"texture":0}},"uuid":"d16d9c0b-c1b9-65c3-169f-6511041f08c4"},{"name":"cube","rescale":false,"locked":false,"from":[10,31,5],"to":[13,37,11],"autouv":0,"color":0,"origin":[-7.5,18,8],"faces":{"north":{"uv":[9.5,1.5,11,4.5],"rotation":180,"texture":0},"east":{"uv":[11,1.5,14,4.5],"rotation":180,"texture":0},"south":{"uv":[9.5,1.5,11,4.5],"rotation":180,"texture":0},"west":{"uv":[11,1.5,14,4.5],"rotation":180,"texture":0},"up":{"uv":[11,4.5,14,6],"rotation":90,"texture":0},"down":{"uv":[11,0,14,1.5],"rotation":90,"texture":0}},"uuid":"0b46da4d-19b5-92d6-b592-dc1d22714f0d"}],"outliner":[{"name":"Housing","origin":[8,0,0],"color":0,"uuid":"599acd84-2b4c-3b15-3ff1-43e46c4a58f1","export":true,"isOpen":true,"locked":false,"visibility":true,"autouv":0,"children":["1758ddcd-ecbd-3569-9c40-06e40b82914b","10fc7e13-136d-fe5a-12e8-5ab0d56572d2","84d1f78c-210d-d43e-7c3e-c44dbccd739e","18bdbdbf-c454-d659-4a8c-a8858d177eef"]},{"name":"Piston","origin":[0,0,0],"color":0,"uuid":"7d34f50a-dfb1-51df-666c-1f7cb7055eb1","export":true,"isOpen":true,"locked":false,"visibility":true,"autouv":0,"children":["bb5f68d8-d633-6589-b61a-ac1f08516ef1"]},{"name":"Linkage","origin":[8,8,8],"color":0,"uuid":"5e49a9d4-7c65-c86f-eb33-d42733debbcf","export":true,"isOpen":true,"locked":false,"visibility":true,"autouv":0,"children":["af28fce2-d208-0379-54b4-7dc0c86a7ea3","3e9020ae-d9d2-cf05-68cc-0f8c69f877e0","1efd911a-c293-52f1-caf1-c5c9950b283d"]},{"name":"Cam","origin":[-7.5,18,8],"color":0,"uuid":"851f342b-9502-2a1b-248a-6da25144590d","export":true,"isOpen":true,"locked":false,"visibility":true,"autouv":0,"children":["13918418-0f93-bf99-b472-24afd4156970","2899e055-4fd8-4120-d61e-504018a868dd","26c50f51-a6e4-9674-ae96-9054706335aa","f2ab5727-659d-b068-2849-7438bbd0f2a4","d16d9c0b-c1b9-65c3-169f-6511041f08c4","0b46da4d-19b5-92d6-b592-dc1d22714f0d"]}],"textures":[{"path":"C:\\Users\\simon\\Desktop\\Modding\\Forge 18 Concealed\\Create\\src\\main\\resources\\assets\\create\\textures\\block\\cam_linkage.png","name":"cam_linkage.png","folder":"block","namespace":"create","id":"0","particle":true,"render_mode":"normal","visible":true,"mode":"bitmap","saved":true,"uuid":"ccfa89b2-739d-ff62-a4cb-d963e94195ab","relative_path":"../../../../textures/block/cam_linkage.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAA59JREFUWEfFl21IU1EYxx9hqWu65hBCzJYYGAlTv6QWphWYSghKGgmC9vKhKIgMKnqjNypICIz6UOSHwEjDIELID4FJb598AcEgW0vnmshcm8OXhBv/Y+dy7vVuc9dFz5d5n3nP8zv/5+WcxdE/spqaWslsNitW9/v91NXVGSc6FQ+xZCkr2yslJZmJQyD4zIyfenrehAYo2V0sZdkyGMeoc4x63/bpBtSlwPWLzVJFeRUN9feTyzNGl260RAWAoNgldo5PLQurwKGmeqliTzmNjAySw+WmJ23tUQE0Nh6WIDVkn5gYp2AwSLOzs4zDaDSSyWQKn4IzJ5qkgsJdDOCXz0t377dFDcB3DYCpqSmqrixlmxkY/EKpqamRAbZm5zL59QKICgAgLzebpgM+cn7z6APoaC6Rnj0fVaTz4IEsqmvpXaaOugYAMD8/x95NSEhcGYA6BZ8f7pNu3xxQAJy7kEcFx17HHkCrCMc/HJdO1r1SALR2VNGG7Q/C1gfmQNQKaLWhNPNUqtlyXgHQNXKL4pIaYg+gNYiiSYFIqUsBrcERTRHqGeWyjAhk25xM2xoOkGvoI7kGf5Dza4Ac7kX69M6pWLtwp43Otr+PakaEgpMXgdTpuRuprdvIBse1oxYZYqVtuCoFOMDlRz42OFpPb/o/AJAeBjV4GlaiQE5OjoRhYzCsoYWFOYqPT2Tr8L8XF3/LAmE4DQ8PM/VjVgMAsFhS2IFjMBgoMXEtO5QmJ3+ywHiGeTxu8vmmlwPcqd8hZaYZCIUI4wXoHguQ0+FVpNeWaaV7fUMhi5CnM91epHiPF7c4RSMqgBU4FF8NcFpnAf+edxTSyNJpL1J0lviuDFC9v1JKSbaQ1ZTAXvIG51kxwrT8L190h1RAVFOrrcUWlhfBGE5fn0H2/HxyfHdSYNrLjmW2Aw1/uNuSrhSsRgEE5DVTWpwidxFPCU8BntFZmjWwGgVwYortywMBSjTUEupCPEnlFOA6ts5iZXJz6XErgmn5xesaTkxUOC84fHZeeawIzh9qrx5RnKQyAO4CKEAEgyE4ChGm5RcvrDwFYseod88BoIJmCgDAg/EuELcgdgf8IgDaDocWDLMkksW8DdF2GFiwtIylQRbONNuQd4H4ojgH1P5Ic4ADqUEAGBIA/4yhA+PB+QJqfziAU8V2ST2+5RpQjXG5CHEds1qTFQBe75KsWv5wvxt1A/BgrAj/BufkgBD94QDEmoiUgj9fr/M/8yY+nQAAAABJRU5ErkJggg=="},{"path":"C:\\Users\\simon\\Desktop\\Modding\\Forge 18 Concealed\\Create\\src\\main\\resources\\assets\\create\\textures\\block\\engine.png","name":"engine.png","folder":"block","namespace":"create","id":"1","particle":false,"render_mode":"normal","visible":true,"mode":"bitmap","saved":true,"uuid":"ba8f5076-d10e-7dbe-f689-60fc0a6e475e","relative_path":"../../../../textures/block/engine.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAABNNJREFUWEfFV2toW2UYfrM0ze2krUuytGvZ7E28bYsoVlrHZCudjFF1ihc6/eGvOaHDH1oQ2Y86hDH94QTdLxV1KKJThwqObkwdUaFiOx0Dt15W2qVZE2yak1uT7Mjznn2n56RpSJaK75+cc77vfb/ne95rTHQTMnb4acVsd5CrycXa0gYv/8pTc/wbm45RLpmgI99NU221lZxrFMMp8esmii6m6dhP50wm/UqphnH4mZ+D5LZbyOkgcq2zqQdfS1E8QRRJZmj71gbes8FtIUe1mcx1Ft6Tm89QYjFHU5EM9Q10kQHAYM92pdWrGpPMVQbUci7L72NzKXpx3yY69/UEjc7K5JFsZDOrN0zlTBSWU7SlXqIHH23mPd469XCfR+I9obDMIObmc7zHAODdPbuURqlKU2rzNzCdeqUZOUtP7W2nP05N0N/XsnTbuiq+IQRGsY5v9/Q08x7cdDqapqZaK+8Rz2Cm7U6PEcDxvl0Kbg5aYXR92y3a4aAN9IKJJ17qpJGT5+nCxRjd3mDT6IULcOBdd7jI37uZ9/zwa5h2PuAhXAZyeSSofcO7gYFvnutVxOFYBHWgCwIAEIB4uP9+Nv77XzL5m6zaPuwBK/feLTGAYGCc4wDxABYhcIX4dvXyP8UB5DMgAMB3oDcwLrO/AVoIvnW2SOwC3BYgAQjsQMDsyHRa+1aQAbExP3L1ABBggatxTjGkFUQ8d653coDpQSIYRZwgeAESbBoA5MeA3gVCGTHQ1VFfUhqODoc5KJEZepDIHAR7IpEpnAXFghAGd3bUUCmF6MfhaNFakcukb64OHDx1xsDcUgSU9/Rmb7diMPTbwScVj3MN1bX72BJKrCiveJ+/FKJw/Dp1DH6+KgAO9TxkBCAKkXAB0koUGVEH4IL9J75fFQCvb7sBIND/mOJrtLJfIcWaDNbRaEIzaeo8+lVFQAa6tqkMoAcgMmvtRD6X2gNw83wGQrEs9whkAnrCasQCAxjo3qEghwECAiCFmlE0qQaZSKvDQ6crYgC2KjZQXtwv380AKo2BShhkABhEPj09q8Gz2YyzgFhIpdSZAPLMjnpqHfhMi6F4XG1WUpWJ7LWF9ZPRLMlZdXZwOs0cQ2xg8ujzyiffjlNrjX1FRh0OC5dOBryQpL27W+jW/vdZH+l7JRQnf4OuK+VZ0uuPBBO00efkdNYAfDE0RY3VFppZzFB7nUPrcKIOsKsmY7z25+zCMgCRSILavPaS9ddKjiUAkRMHlA8+vMAAgFS01/xZDiAw9QDAC/u2kHvP23wBNLFgbLEs/Wavg/qO32BAD8DrUYdIiGjHGCL0Y1k+AAwyl+YTDKBU/U31NfTIRydVF6SHDynvDJ5lekXfFhMQ5jYcjoECwAQDL7/RTdb7XmN9AaAc/WUAjrw6RPgIAOJwMW6LURoDBNzzy8UFeuUtIwCwUo7+5o06BuCC946NchaAQshKh2MNAPYfWIoBMAAA5egXBaA/HAfqGZmdTNH5K0YACMKJuYQGoBT9liZdEKIOfPzlOAEVgmmrf632R0KfzkhV+BkAnn3cWAeQhuXou926NBQAkMdIQ65UeTUF/hdSCIAoRKXoB8aixkIkSrGSXrEQaiWU48NpKlqKC1kRJVisGUrx/96MVr73f7/yLxn0juUSP7i0AAAAAElFTkSuQmCC"},{"path":"C:\\Users\\simon\\Desktop\\Modding\\Forge 18 Concealed\\Create\\src\\main\\resources\\assets\\create\\textures\\block\\axis_top.png","name":"axis_top.png","folder":"block","namespace":"create","id":"2","particle":false,"render_mode":"normal","visible":true,"mode":"bitmap","saved":true,"uuid":"07072ef3-cbb1-53ec-389b-0005d44ab5c9","relative_path":"../../../../textures/block/axis_top.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAGpJREFUOE/tkjEOABEQRb9eoeVuWrXKIVRq1yQToZi9wNqwWtPPS/7LEzg8cfiPC8DcgXOOlVLovYOIkHN+9TWV6L1nYwxaa6i1Isa4BwghsJQSYwyUUpBS2gNYa1lr/X/CamA3pI+QViU+DW8oEedEdfMAAAAASUVORK5CYII="},{"path":"C:\\Users\\simon\\Desktop\\Modding\\Forge 18 Concealed\\Create\\src\\main\\resources\\assets\\create\\textures\\block\\axis.png","name":"axis.png","folder":"block","namespace":"create","id":"3","particle":false,"render_mode":"normal","visible":true,"mode":"bitmap","saved":true,"uuid":"b699b2d2-5f79-2328-a547-b19b3b3f640d","relative_path":"../../../../textures/block/axis.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAKNJREFUOE+lkyEOBCEMRTuCESBAgIC7ITAcCjvnwoIFg2VTkklWzCY7pZKUx//l94Af5b2f1loYY0DvHa7rOp5aHw+xMYQwhRDrDhnAGAPnHOSc3yuIMU58XSkFtVYa4DxP0FrvKUALpRRIKb0b4reF1hoNgBY450ACYA6klGsGJAt3kFABCYBBMsYsC6QcbAPwFzBEWFtBQgskwL1MZMC/6/wBkRp2ERiWaKEAAAAASUVORK5CYII="}]} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/steam_engine/block.json b/src/main/resources/assets/create/models/block/steam_engine/block.json new file mode 100644 index 000000000..553241d17 --- /dev/null +++ b/src/main/resources/assets/create/models/block/steam_engine/block.json @@ -0,0 +1,63 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "1": "create:block/engine", + "particle": "create:block/copper_plating" + }, + "elements": [ + { + "from": [1, 0, 1], + "to": [15, 3, 15], + "faces": { + "north": {"uv": [0.5, 6.5, 7.5, 8], "texture": "#1"}, + "east": {"uv": [0.5, 6.5, 7.5, 8], "texture": "#1"}, + "south": {"uv": [0.5, 6.5, 7.5, 8], "texture": "#1"}, + "west": {"uv": [0.5, 6.5, 7.5, 8], "texture": "#1"}, + "up": {"uv": [0.5, 8.5, 7.5, 15.5], "rotation": 90, "texture": "#1"}, + "down": {"uv": [8.5, 8.5, 15.5, 15.5], "rotation": 270, "texture": "#1"} + } + }, + { + "from": [3, 3, 3], + "to": [13, 15, 13], + "faces": { + "north": {"uv": [1.5, 0.5, 6.5, 6.5], "texture": "#1"}, + "east": {"uv": [1.5, 0.5, 6.5, 6.5], "texture": "#1"}, + "south": {"uv": [1.5, 0.5, 6.5, 6.5], "texture": "#1"}, + "west": {"uv": [1.5, 0.5, 6.5, 6.5], "texture": "#1"}, + "up": {"uv": [6.5, 0, 11.5, 5], "rotation": 90, "texture": "#1"} + } + }, + { + "from": [13, 5, 4], + "to": [15, 13, 12], + "faces": { + "north": {"uv": [11.5, 0, 15.5, 1], "rotation": 90, "texture": "#1"}, + "east": {"uv": [11.5, 1, 15.5, 5], "texture": "#1"}, + "south": {"uv": [11.5, 0, 15.5, 1], "rotation": 270, "texture": "#1"}, + "up": {"uv": [11.5, 0, 15.5, 1], "rotation": 270, "texture": "#1"}, + "down": {"uv": [11.5, 0, 15.5, 1], "rotation": 270, "texture": "#1"} + } + }, + { + "from": [1, 5, 4], + "to": [3, 13, 12], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 0, 8]}, + "faces": { + "north": {"uv": [11.5, 0, 15.5, 1], "rotation": 270, "texture": "#1"}, + "south": {"uv": [11.5, 0, 15.5, 1], "rotation": 90, "texture": "#1"}, + "west": {"uv": [11.5, 1, 15.5, 5], "texture": "#1"}, + "up": {"uv": [11.5, 0, 15.5, 1], "rotation": 90, "texture": "#1"}, + "down": {"uv": [11.5, 0, 15.5, 1], "rotation": 90, "texture": "#1"} + } + } + ], + "groups": [ + { + "name": "Housing", + "origin": [8, 0, 0], + "color": 0, + "children": [0, 1, 2, 3] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/steam_engine/gauge.json b/src/main/resources/assets/create/models/block/steam_engine/gauge.json new file mode 100644 index 000000000..83023a3a5 --- /dev/null +++ b/src/main/resources/assets/create/models/block/steam_engine/gauge.json @@ -0,0 +1,37 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "1": "create:block/boiler_gauge", + "2": "create:block/gauge", + "particle": "create:block/boiler_gauge" + }, + "elements": [ + { + "name": "GaugeButton", + "from": [15.5, 5.2, 5.2], + "to": [16.5, 6.3, 6.3], + "rotation": {"angle": 0, "axis": "y", "origin": [10, 8, 8]}, + "faces": { + "north": {"uv": [0, 9.5, 0.5, 10], "texture": "#2"}, + "east": {"uv": [0, 9.5, 0.5, 10], "texture": "#2"}, + "south": {"uv": [0, 9.5, 0.5, 10], "texture": "#2"}, + "west": {"uv": [0, 9.5, 0.5, 10], "texture": "#2"}, + "up": {"uv": [0, 9.5, 0.5, 10], "texture": "#2"}, + "down": {"uv": [0, 9.5, 0.5, 10], "texture": "#2"} + } + }, + { + "name": "GuageMetalBack", + "from": [14, 3, 3], + "to": [16, 13, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [9, 8, 8]}, + "faces": { + "north": {"uv": [11, 0, 13, 10], "texture": "#1"}, + "east": {"uv": [0, 0, 10, 10], "texture": "#1"}, + "south": {"uv": [11, 0, 13, 10], "rotation": 180, "texture": "#1"}, + "up": {"uv": [11, 0, 13, 10], "rotation": 180, "texture": "#1"}, + "down": {"uv": [11, 0, 13, 10], "rotation": 180, "texture": "#1"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/steam_engine/item.json b/src/main/resources/assets/create/models/block/steam_engine/item.json new file mode 100644 index 000000000..3e1797a1a --- /dev/null +++ b/src/main/resources/assets/create/models/block/steam_engine/item.json @@ -0,0 +1,157 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "0": "create:block/cam_linkage", + "1": "create:block/engine", + "particle": "create:block/copper_plating" + }, + "elements": [ + { + "from": [5, 8, 5], + "to": [11, 27, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 5, 0]}, + "faces": { + "north": {"uv": [4, 6.5, 7, 16], "texture": "#0"}, + "east": {"uv": [1, 6.5, 4, 16], "texture": "#0"}, + "south": {"uv": [4, 6.5, 7, 16], "texture": "#0"}, + "west": {"uv": [1, 6.5, 4, 16], "texture": "#0"}, + "up": {"uv": [4, 3.5, 7, 6.5], "texture": "#0"} + } + }, + { + "from": [1, 0, 1], + "to": [15, 3, 15], + "faces": { + "north": {"uv": [0.5, 6.5, 7.5, 8], "texture": "#1"}, + "east": {"uv": [0.5, 6.5, 7.5, 8], "texture": "#1"}, + "south": {"uv": [0.5, 6.5, 7.5, 8], "texture": "#1"}, + "west": {"uv": [0.5, 6.5, 7.5, 8], "texture": "#1"}, + "up": {"uv": [0.5, 8.5, 7.5, 15.5], "rotation": 90, "texture": "#1"}, + "down": {"uv": [8.5, 8.5, 15.5, 15.5], "rotation": 270, "texture": "#1"} + } + }, + { + "from": [3, 3, 3], + "to": [13, 15, 13], + "faces": { + "north": {"uv": [1.5, 0.5, 6.5, 6.5], "texture": "#1"}, + "east": {"uv": [1.5, 0.5, 6.5, 6.5], "texture": "#1"}, + "south": {"uv": [1.5, 0.5, 6.5, 6.5], "texture": "#1"}, + "west": {"uv": [1.5, 0.5, 6.5, 6.5], "texture": "#1"}, + "up": {"uv": [6.5, 0, 11.5, 5], "rotation": 90, "texture": "#1"} + } + }, + { + "from": [13, 5, 4], + "to": [15, 13, 12], + "faces": { + "north": {"uv": [11.5, 0, 15.5, 1], "rotation": 90, "texture": "#1"}, + "east": {"uv": [11.5, 1, 15.5, 5], "texture": "#1"}, + "south": {"uv": [11.5, 0, 15.5, 1], "rotation": 270, "texture": "#1"}, + "up": {"uv": [11.5, 0, 15.5, 1], "rotation": 270, "texture": "#1"}, + "down": {"uv": [11.5, 0, 15.5, 1], "rotation": 270, "texture": "#1"} + } + }, + { + "from": [1, 5, 4], + "to": [3, 13, 12], + "rotation": {"angle": 0, "axis": "y", "origin": [0, 0, 8]}, + "faces": { + "north": {"uv": [11.5, 0, 15.5, 1], "rotation": 270, "texture": "#1"}, + "south": {"uv": [11.5, 0, 15.5, 1], "rotation": 90, "texture": "#1"}, + "west": {"uv": [11.5, 1, 15.5, 5], "texture": "#1"}, + "up": {"uv": [11.5, 0, 15.5, 1], "rotation": 90, "texture": "#1"}, + "down": {"uv": [11.5, 0, 15.5, 1], "rotation": 90, "texture": "#1"} + } + }, + { + "from": [6, 22, 4], + "to": [10, 28, 12], + "rotation": {"angle": 45, "axis": "x", "origin": [15, 25, 8]}, + "faces": { + "north": {"uv": [8.5, 11, 10.5, 14], "rotation": 180, "texture": "#0"}, + "east": {"uv": [10.5, 11, 14.5, 14], "rotation": 180, "texture": "#0"}, + "south": {"uv": [8.5, 11, 10.5, 14], "rotation": 180, "texture": "#0"}, + "west": {"uv": [10.5, 11, 14.5, 14], "rotation": 180, "texture": "#0"}, + "up": {"uv": [10.5, 14, 14.5, 16], "rotation": 90, "texture": "#0"}, + "down": {"uv": [10.5, 9, 14.5, 11], "rotation": 90, "texture": "#0"} + } + }, + { + "from": [6, 8, 4], + "to": [10, 14, 12], + "rotation": {"angle": 45, "axis": "x", "origin": [15, 25, 8]}, + "faces": { + "north": {"uv": [8.5, 11, 10.5, 14], "rotation": 180, "texture": "#0"}, + "east": {"uv": [10.5, 11, 14.5, 14], "rotation": 180, "texture": "#0"}, + "south": {"uv": [8.5, 11, 10.5, 14], "rotation": 180, "texture": "#0"}, + "west": {"uv": [10.5, 11, 14.5, 14], "rotation": 180, "texture": "#0"}, + "up": {"uv": [10.5, 14, 14.5, 16], "rotation": 90, "texture": "#0"}, + "down": {"uv": [10.5, 9, 14.5, 11], "rotation": 90, "texture": "#0"} + } + }, + { + "from": [6, 14, 6], + "to": [10, 22, 10], + "rotation": {"angle": 45, "axis": "x", "origin": [15, 25, 8]}, + "faces": { + "north": {"uv": [1.5, 1, 3.5, 6], "rotation": 180, "texture": "#0"}, + "east": {"uv": [1.5, 1, 3.5, 6], "rotation": 180, "texture": "#0"}, + "south": {"uv": [1.5, 1, 3.5, 6], "rotation": 180, "texture": "#0"}, + "west": {"uv": [1.5, 1, 3.5, 6], "rotation": 180, "texture": "#0"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "thirdperson_lefthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "firstperson_righthand": { + "rotation": [0, 45, 0], + "scale": [0.4, 0.4, 0.4] + }, + "firstperson_lefthand": { + "rotation": [0, 225, 0], + "scale": [0.4, 0.4, 0.4] + }, + "ground": { + "translation": [0, 3, 0], + "scale": [0.25, 0.25, 0.25] + }, + "gui": { + "rotation": [30, -45, 0], + "translation": [0, -2, 0], + "scale": [0.5, 0.5, 0.5] + }, + "fixed": { + "scale": [0.5, 0.5, 0.5] + } + }, + "groups": [ + { + "name": "Piston", + "origin": [0, 0, 0], + "color": 0, + "children": [0] + }, + { + "name": "Housing", + "origin": [8, 0, 0], + "color": 0, + "children": [1, 2, 3, 4] + }, + { + "name": "Linkage", + "origin": [8, 8, 8], + "color": 0, + "children": [5, 6, 7] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/steam_engine/linkage.json b/src/main/resources/assets/create/models/block/steam_engine/linkage.json new file mode 100644 index 000000000..8d44b9cc0 --- /dev/null +++ b/src/main/resources/assets/create/models/block/steam_engine/linkage.json @@ -0,0 +1,51 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "0": "create:block/cam_linkage" + }, + "elements": [ + { + "from": [6, 1, 4], + "to": [10, 7, 12], + "faces": { + "north": {"uv": [8.5, 11, 10.5, 14], "texture": "#0"}, + "east": {"uv": [10.5, 11, 14.5, 14], "texture": "#0"}, + "south": {"uv": [8.5, 11, 10.5, 14], "texture": "#0"}, + "west": {"uv": [10.5, 11, 14.5, 14], "texture": "#0"}, + "up": {"uv": [10.5, 9, 14.5, 11], "rotation": 90, "texture": "#0"}, + "down": {"uv": [10.5, 14, 14.5, 16], "rotation": 90, "texture": "#0"} + } + }, + { + "from": [6, 15, 4], + "to": [10, 21, 12], + "faces": { + "north": {"uv": [8.5, 11, 10.5, 14], "texture": "#0"}, + "east": {"uv": [10.5, 11, 14.5, 14], "texture": "#0"}, + "south": {"uv": [8.5, 11, 10.5, 14], "texture": "#0"}, + "west": {"uv": [10.5, 11, 14.5, 14], "texture": "#0"}, + "up": {"uv": [10.5, 9, 14.5, 11], "rotation": 90, "texture": "#0"}, + "down": {"uv": [10.5, 14, 14.5, 16], "rotation": 90, "texture": "#0"} + } + }, + { + "from": [6, 7, 6], + "to": [10, 15, 10], + "faces": { + "north": {"uv": [1.5, 1, 3.5, 6], "texture": "#0"}, + "east": {"uv": [1.5, 1, 3.5, 6], "texture": "#0"}, + "south": {"uv": [1.5, 1, 3.5, 6], "texture": "#0"}, + "west": {"uv": [1.5, 1, 3.5, 6], "texture": "#0"} + } + } + ], + "display": {}, + "groups": [ + { + "name": "Linkage", + "origin": [8, 8, 8], + "color": 0, + "children": [0, 1, 2] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/steam_engine/piston.json b/src/main/resources/assets/create/models/block/steam_engine/piston.json new file mode 100644 index 000000000..0d814b0cf --- /dev/null +++ b/src/main/resources/assets/create/models/block/steam_engine/piston.json @@ -0,0 +1,28 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "0": "create:block/cam_linkage" + }, + "elements": [ + { + "from": [5, 3, 5], + "to": [11, 22, 11], + "faces": { + "north": {"uv": [4, 6.5, 7, 16], "texture": "#0"}, + "east": {"uv": [1, 6.5, 4, 16], "texture": "#0"}, + "south": {"uv": [4, 6.5, 7, 16], "texture": "#0"}, + "west": {"uv": [1, 6.5, 4, 16], "texture": "#0"}, + "up": {"uv": [4, 3.5, 7, 6.5], "texture": "#0"} + } + } + ], + "display": {}, + "groups": [ + { + "name": "Piston", + "origin": [0, 0, 0], + "color": 0, + "children": [0] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/steam_engine/shaft_connector.json b/src/main/resources/assets/create/models/block/steam_engine/shaft_connector.json new file mode 100644 index 000000000..7ea0d906c --- /dev/null +++ b/src/main/resources/assets/create/models/block/steam_engine/shaft_connector.json @@ -0,0 +1,68 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "0": "create:block/cam_linkage" + }, + "elements": [ + { + "from": [11, 5, 5], + "to": [14, 11, 11], + "rotation": {"angle": 0, "axis": "x", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [9.5, 1.5, 11, 4.5], "texture": "#0"}, + "east": {"uv": [11, 1.5, 14, 4.5], "texture": "#0"}, + "south": {"uv": [9.5, 1.5, 11, 4.5], "texture": "#0"}, + "west": {"uv": [11, 1.5, 14, 4.5], "texture": "#0"}, + "up": {"uv": [11, 0, 14, 1.5], "rotation": 270, "texture": "#0"}, + "down": {"uv": [11, 4.5, 14, 6], "rotation": 270, "texture": "#0"} + } + }, + { + "from": [2, 5, 5], + "to": [5, 11, 11], + "rotation": {"angle": 0, "axis": "x", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [9.5, 1.5, 11, 4.5], "texture": "#0"}, + "east": {"uv": [11, 1.5, 14, 4.5], "texture": "#0"}, + "south": {"uv": [9.5, 1.5, 11, 4.5], "texture": "#0"}, + "west": {"uv": [11, 1.5, 14, 4.5], "texture": "#0"}, + "up": {"uv": [11, 0, 14, 1.5], "rotation": 270, "texture": "#0"}, + "down": {"uv": [11, 4.5, 14, 6], "rotation": 270, "texture": "#0"} + } + }, + { + "from": [10, -1, 5], + "to": [13, 5, 11], + "rotation": {"angle": 0, "axis": "x", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [9.5, 1.5, 11, 4.5], "rotation": 180, "texture": "#0"}, + "east": {"uv": [11, 1.5, 14, 4.5], "rotation": 180, "texture": "#0"}, + "south": {"uv": [9.5, 1.5, 11, 4.5], "rotation": 180, "texture": "#0"}, + "west": {"uv": [11, 1.5, 14, 4.5], "rotation": 180, "texture": "#0"}, + "up": {"uv": [11, 4.5, 14, 6], "rotation": 270, "texture": "#0"}, + "down": {"uv": [11, 0, 14, 1.5], "rotation": 270, "texture": "#0"} + } + }, + { + "from": [3, -1, 5], + "to": [6, 5, 11], + "rotation": {"angle": 0, "axis": "x", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [9.5, 1.5, 11, 4.5], "rotation": 180, "texture": "#0"}, + "east": {"uv": [11, 1.5, 14, 4.5], "rotation": 180, "texture": "#0"}, + "south": {"uv": [9.5, 1.5, 11, 4.5], "rotation": 180, "texture": "#0"}, + "west": {"uv": [11, 1.5, 14, 4.5], "rotation": 180, "texture": "#0"}, + "up": {"uv": [11, 4.5, 14, 6], "rotation": 270, "texture": "#0"}, + "down": {"uv": [11, 0, 14, 1.5], "rotation": 270, "texture": "#0"} + } + } + ], + "groups": [ + { + "name": "Cam", + "origin": [-7.5, 18, 8], + "color": 0, + "children": [0, 1, 2, 3] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/particles/steam_jet.json b/src/main/resources/assets/create/particles/steam_jet.json new file mode 100644 index 000000000..5ce2d2638 --- /dev/null +++ b/src/main/resources/assets/create/particles/steam_jet.json @@ -0,0 +1,27 @@ +{ + "textures": [ + "create:steam_jet_0", + "create:steam_jet_1", + "create:steam_jet_2", + "create:steam_jet_3", + "create:steam_jet_4", + "create:steam_jet_5", + "create:steam_jet_6", + "create:steam_jet_7", + "create:steam_jet_8", + "create:steam_jet_9", + "create:steam_jet_10", + "create:steam_jet_11", + "create:steam_jet_12", + "create:steam_jet_13", + "create:steam_jet_14", + "create:steam_jet_15", + "create:steam_jet_16", + "create:steam_jet_17", + "create:steam_jet_18", + "create:steam_jet_19", + "create:steam_jet_20", + "create:steam_jet_21", + "create:steam_jet_22" + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/textures/block/boiler_gauge.png b/src/main/resources/assets/create/textures/block/boiler_gauge.png new file mode 100644 index 0000000000000000000000000000000000000000..d03923615c3be3a425018560bf99b2da74833d43 GIT binary patch literal 360 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%Lhh0G|-o9zT~BH-~0>hbA|tpJ!SgOiJ1q=T~ZPH!a9(->GdIb}c{98-JoY z?wEbxuA^I*hj^A-+aJpdtiF0JVb_h_a}qK-FK*hmF(4qIef&K$V;Y9+AZi419+{nDKc2iWHz=uBVG*h(_?%bCG-v z1{^FG7O|E`uPt4D=l`rnL5tZ7gzDnhnt~XPGpNj2c4o~Kw@C~9EKd6$ShVKVGRMpq zhqs!??j`L0H$i-Yuw<5Sc*CCJ$0nYSt+-z7oj+alF;@nU$f0G)hwXOCPyYFYJ>eeX Y3U`qJ7q3a0K#LhXUHx3vIVCg!0I1%VG5`Po literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/cam_linkage.png b/src/main/resources/assets/create/textures/block/cam_linkage.png new file mode 100644 index 0000000000000000000000000000000000000000..d8b35b80c22f742a8ddd4ae747729136e01fbfd1 GIT binary patch literal 1454 zcmV;f1yTBmP)EX>4Tx04R}tkv&MmKpe$iQ%glEigplj$WWauh>AE$6^me@v=v%)FuC*#nlvOS zE{=k0!NHHks)LKOt`4q(Aou~|=H{g6A|?JWDYS_3;J6>}?mh0_0Yam~RI_UWP&La) z#baVNw<-o-5kNl%5QJZ1rk+SIX5cx#?&0I>U6f~epZjz4DtVIuK9P8i>4rtTK|Hf* z>74h8!>lAJ#OK8023?T&k?XR{Z=8z`3p_JyWK#3QVPdh^!Ey()lA#h$6Gs$PqkJLj zvch?bvs$UK);;+PLwRi_&2^e1h+_!}Bq2gZ4P{hdAxf)8iis5M$2|PQjz38*nOtQs zax9<<6_Voz|AXJ%nuV!JHz^bY0x!1xF$x5Cfo9#dzmILZc>?&Kfh(=;uQq_$Ptxmc zEpi0(Z37qAZB5<-E_Z;TCtWfmNAlAY3I*W(jJ_!c4Bi4gYi@6?eVjf38R}~J1~@nb z#)_1^?(y#K&ffk#)9UXB2ZC~Z1sa@$00006VoOIv0Ez&L0E*+<=Oh3C010qNS#tmY zE+YT{E+YYWr9XB6000McNlirueSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00V|eL_t(o!?l*rixX!U$3H32WX)!1EJebwNrMZmENp5I zTefA{MZ{_;g$k`Gcr3-U2k+v+9txh?KcJwf)ZPk}vJkfQ#~!+7A=-jVOhQQ4!z9im zWTQ*tVRk0(%=^xm-RwRPc;}mW=KVh3_xbTg*dsfA`s==?X&%fpP43*e9TBm&_KHBe zZDN|HXY+R3l-`Sq5A(<7`iHX<0IXGN6c(2vJ0&nat|2PmS3^nQ_$M=*I{785D=Xym zG=;^bZOh(nn~aZZwA<>4LkX1Y4a(0d)Yog2>y2$k?L?_*Hi1s3L$})nU~FuRL?R*i zcyi!iBBosLgakmh+vTgz7x*y$zDp#O0D#prMoK<0@f=l~R%^H;P}!}E^Zgq)*F4zS zGl%)+heAZPx&PcBE*Ala#p1&$kW3x)JZC49l9LMCsd*GIIz4Hv=QF?~kCTnbCN`N9 zCqC;BL%^dzPEV72FN=O?f}EbVH=CZ7oK)DZDDcOf4(U>sjyukP*_}w z6nrmKo?4QV3iI3DyT3=aMc~%O`F?gX$;|mP)K~9QFIK5MwJ0|>B_|a&vI5!3Bziu> zm8*{^*IQivHUm@viw8cZTspdI1f(*2Q{&ielS27!#@x}Ao|>BK$6|4!(S5vpxxxPZ zcH?o@o13rPcYD1JN~Kc7L%>d~>PR`@44i269pdo=Xqv|J=l=l^j~@VFeZ4`iw;?NF zf7F7l5_2|h)Z~m;VNOH<4}bciujk*D`h^`>mya*}8IcI&(ow`Ja1t<=PI2~JMk>Q= zAy)-QO|fx_sw#8fMkPVY(70V%+-k)dP3wOEQikS^XQR_|@gQ^69O6h_0v~;F1pUwi z(?^d|epbP18r0YAZm7b4<+nfr3v(&-e8xQjeR|gZt==bFtip8#fxrKGLb=}H@xMhO z(w1AADqK8sC%T2Xl;_OFBM2?SQ53MJW0maWU{ZR{`nuR&Y0Vu`t{> z9i8>Ptxf&OIdgs%_)#Wc&;P-PU$hM2eh`EYrlS*Wwpa~KQ2!)VTu6+7%ZZGOkqxpt zd{PFMVbf}nO1|y+(@C}4{`80Z|1p z${;+*8a0bbdARGnJN67iW^5Q%Aig)ZV&TKXtb@!ibJ%~c0c9%<{9 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/engine.png b/src/main/resources/assets/create/textures/block/engine.png new file mode 100644 index 0000000000000000000000000000000000000000..31cb01d136b532ca83f109919b365006110ccd77 GIT binary patch literal 9791 zcmeHtXH=70w{DOkMVf$g389w|LX}97PUs*gO(6}4KoXJ=stSrqlP)MAU3!s@(nOko zSV2GqQKUB&r3lCg=-%6X&v(CbzcKFlx5G%tTI-q5oaK?Pf}3OR{(&$GRV$>Y>V&*5{P(rtTzTo4kTcJm;kIh01)uH{FY;) zSQV?mZXmNrPGeHfdx7_Y8ygpTWx-=dAqeNRQ*enWx-bJ!J9Ghmacml*dC8(Z{H9rn z%o$BR)*;pLuZ}XS%!;V+g`cD zf^PzNbzE!L-md7Ztb6F4zF_s$VPdJ}i)xmLCRgCP1NZXN$tvlg#EafOu^v;O-pXdR zP1Kk{M}-1dm-{sA$9es)#OM?r8tWKRwrLjr-un6bw!r+|UNC;At8{g_{>8%6@7=0j z&Yf3U_LKWgz>OYP2|vtrw^o~_Zei&${#{7OSF5ADz4b?L3h_1Ptz~ZUYLBm6Xcudk zX>D7%C~3N~5O=qA`OU^c>qW@q1qVBAxh8z{ce=!Pag{~OTK(e-htzVebY{M+DIPxc zvFN~Hw?#pYTi_kgeh)FLO-VB39DXN z@D&F;b;dS{*P7SI6t?CIArIU_d7k>L*LP+5EjZ#v4lEa9@@vf9uapkI47s@Bnz^g^ ze7uj}tMbbl4@E;%K$%;kMJXzDWM?BeB5e}6Mftj}ANI{a@u)hl+DOF(tLJ$;ZvApk z`hGl8cJZgY(ad5ZaC#ZXi27V=N&NO)G8i*cUAIxik#%+I$-&`r{#V_zlBe!ZoCh64 z(|E0>dp~vH9Xl_$CeHC(DvQbD+jX}q9AQ>$U7G`Iuii;c@@&Lp z>BnkJWtdgm<8jrCl(^wyT71X;bW2zPN-#a%>JNnhJ4%WXz^xUS5V}{4ZZGv;Z zE1zo&nmjdC5;d0T`BTCJ~PaHihP(y88m%K;)5e6;F%?~DT=jShIqRSIw)KX zf|bQEKdFu4<2=-Vzj5g}CF{`+6epRyD~nt9{}`jUz8jHYGkd{sS!8nUT9F0MWnU1b z`k7GS+03t~2eJb<3Y1>ExTdLGkI(R+mrq00y-!-Ic`6)??z_}0cw)`dsnSm(ow6=( zG{5DZ`fAxXwfS1t{UU6zmvTdd%!Q}-jIW}6gm(>rry3TS(e#X z9URkY=J4{HZmnZw>N6N(S@pfdr%V0DH&C|(yiUdjD>AqY*%VayvaR9NbqT|kfpE85HEfV3PY%f2tvx(6jj{fk~@&5SrCs)hXY`;91 ze!ChDZ9J?Fr%@^{FfodQ+t#QKb6ZKXJT{N!&JUuMj5$A~DYGs1DNC0RCSz+Q+z;#LeG*HKc!wyeiS+NaYH8o6Xn zm1Z$W41>jV(J-zzUpS(|gT;k+0>~a*ILJJ{9llv}P@G{Se~Md>nf`~_MnjZ(JdCG1 zM~L@}a*6UZY^^pPFQ5PUbB1h#o>$hj{uhjMN5si2HAX- zo3aur3rEwcW*iQ3#`aV-@aB7e+J*~o%kzc%!NdbA6e(RmR?0zf<#(tp9S2(D{5W8~RMM`||NB5~)x$*`W7q?yu-=}Dle8U&= z;$3&aWO>bNJ)t+1pGzem`X3K-q>tR4sG#4021@d`o6Qd(3P5_QX&7*Q$B3F({qOw;cGKZ!uBqRF`wa7-C-}O6X~G1>^>9qrI0b2RoZA! zhx=;$AwqB3i6b5P_i_cDKy$(BG_hdIw!SrQXkj|y-e3$M% z?(z?00#%ffUq|iT?K?UDjRe5yb>MO>hWP>eUp!7SgjI9 z?1a8{8kxv$Y(Gd!YY1-+y9~lLZ23j_X6!U?o<8lC5;yJ0L!vpa(|R@UWyPt-tefvn zpwTCen7^WM2-EA|m3$r+AVE7=l6xk53O5z{@e!NLVFqzm6+XwwUY>L9cS=lwlhW}L zOb;bLd9l+AXXM_m?iLpgw7l!t5z_b{yrud2z-qz4gOEoOJ2W|c#9dlU@PNJSK ze>9;G?+_eNZzGN^x=(*6{JKkq6T%!RT8w`smF|WH^ z6J0T<+|keIWKtdaHhZC2P~fA=qgQOwQjZ$#zw`}FCsV{8^!=PD2&oBA9dwF@Y#e(aA;@4iNm(Z z)IeoI32x{#O*DcIfpcKpd zIb2p&xTSHyjv;8c%*D3dwNv(c>k~E;Oo;g9CVg?6t*stpN!CtPv0gCI>1eX{qB!Rb z>%rcv^f@Ku@xBzTbL0q!G(u%oU4O#5%G*;{IQ~`UVyA1v>WVh!UE7sIJ`YYd+Lqt* zhi%u)*~o-E(r;#)9--HwUwg+u-L%-M4_;ozYlqNPyT^eXbD+ii<%AMN8AQl(9jc}+wJ zx2Qssy53w`Z!Vpdyr`?GSCSjkSaDK<48M6W%jL(;DbF=e)+q_MZD)-url6 z|Mn_j^V-SzqN9re7ao-KvFKe_P(5aPPF23LK(dG{i5Mp6$s?_iEy>_#75Uv{YUe$9 zC@+Vh!)jx;_WoU|QFzLY=UXi6mu(EDblC>0u!qQJ{M=ZNZ^WoZ)X?&3#=N-W^pa6j zCe}{ZabQx}$vg(ZLKYtEFZyvkR>QE5(Hi8|B`qYYY$@e@7%BXrQ5^p{RpknLytGBe z7W9?|xL_Ik=HeP<`wT|rK|!=D8*_@XprH(2c4x7Z%?e(%~W-LJiXm<`gr{_f6W`=Z9xr$ zpoTToHKv?|nIb+^xeot!)*G)M-iqYaj*hJWzTK9VfGl`BWv9SgU%2_ToDS+r*?P1| z_k0P(Al_VRk@Dho^}7<<@GFfI$L|w^WRg>vt{w7w7;h+X0_i4jX?NBz#yFfIIx*ad z44AZ37cd1*zxpmPWL24AuG6Q*qz-%L2^x{wlwLGR<|mIUuB7wDKMa7MZ`<2%JB zlCy6U)p(!WD}05uV2PDAfT+iUjt{7gUaYvQfQ*{<7V5JBAEuuZr^Q6Aw+k~b@{|`= z=t?;lmK43cdGcw9+qKQnSMGtI4E)0Rv$LIMg~*h{;@vH>pU!wghcgFCSC!FCbirp| zzC0GOn?f+|XtVe4n5z%BjuOin?A)|#g%*YUz+yqR7zJ$r_?>14cpq|Bp|ekrs0;vRpSEBzI5bKm&p8sL6c zh8^h-g{;j<&1I_~w!X$EAT4|5n-^=&rH_d&gz#Jl_cW{}C-3%~)E&0CM)JcfTlmNp z58PnZDAcIpaT{k3J}r9yMk-pR0lo|nrqc!ug-t`QQ!LZ8jh`?#5%e=Zyo!+>3*Wud zf1Pc%jV(D&GGbwn20c{HE)rrmSoOyeUD^okYwnM|~^0r@W(U%7et-Ak8`P0_Uj%bT9gvcs z6T6*ic_FTvVYIdZI8$n+v1=AqNyg>Xu;0)TZghP;?Gc-E#QJ_kQ4#8S(V;fyo7p&I z)9MuY?5`j05suPeSK@VzWyIacj|#X<9vdaNyiDH zF4vQ0hO$u<4&O)Cx8)HJxc#1Du}ZN%q^Mv;|et>tkVy}XBZHC_j-Rr^i4P)M}~Sq4|m6FLkW;jYMn zOcRLvghuP~`^kkf$sU1OTcoeDfk`yl2?4QlR}GtWHEXbQ8S9Z9W#TfOGo6zRXW};! z7OMO48PRMkn#$g2+tp44vTCHAc(5ih=dcx*F}HnQi0DG~!@%eor{bztTAM8Tfj$xg zeraM6C?+OxQ9UD8jGddPX{k|EB==H}=5|M{4qV}u3r3MBpUupZIC*gQ^1HFLE5&ei z8E)DGkop}cGo62!`&fNjoKI8WfsL#%x$>n-wa`(k7YjaMBHdRXTHawFi*Z^7|Ii$% zGfLvdUtV%E(@*Tgw8|VjG=4zK3x_X1pP>!lpFg+BaO@aecT{rA^5^B{C*wb~Ue2!^ zJa~y1(zHbBr9Mi@z)~NjI9Qm&Pfe(g^00#JY<4CXo zEzmwMjQV}A8v+9EL&#oQAO{O;pgx|60jemdC@6vr1F#e&kTx?=lZbYQ*%}!AqM)|4 zK%QhW0S1Bi`}-^SD=XlM9uTO8h6Y4Y38JI~rXs+kKpYtn0LGET_9%XG7+^>!B9=hL z;&H$|P6QI~N7e#?sN=w27Y!oI~G`gbH6^(T(t zNA%vupivNvH^zq=2#LxJ{TrT)b^mLD{x+Yzk^dG5)!m=`e?$MF*M2Pfy21?bD8D_Y za04ySUc4|g9)(52_P@F#l`!fkloI$D+Fcc_;;w-PBcT{&FiIJv?v7BzC?b`Vf1`rq zNMr;Kh1sK`k}F`TJgOLVBoeKR1iPc%mB1>>CdI6qHANLLLPJ#rtfZ`@hEUW%QpYs*srJ?ZrfUt? z0x2md{?%jcjUc<@i9Xcw!s5_)f6`w=c32C^m z=@T&sGM;FM$9rpm_PBw2l>0>m)cjR0FmpU=-*6v{LGM-EubR_CctG}>nvj17{%=et zJ@Njy|2Lk$pntOH63PB}qL&rX3V9BLBL91ye+B-N$(Fj?k;ueA`2R4e{{yG_Ght1r zws>OTZ~jkWe1EonZb{zQeW`%J{cQk-K>d`TgrH#1`%6I8@#hfA6M^%$^Hl;M%ROy z1Jre<7T5kd1EqiEpUmH*@%O~+C6}TS6s)KUhN{^qL1C&YFenuCbG3n*ki8xDkJ)PO z?Lih6u;2C2+}opI@V!Jl=|>=VV==_P>-0z7{9kat+5gJX|H=G!*iUPHJRy);#hzp< zf84)y|1W?)8O*UL4332VccK3d`6Ys#^9*;eg4z~^(?0K zBlR%OfHX5U07UKmO}?HHr}i)rOdLr7fP&cGnu_o1n%A1pAKW=1pw%3;Rd>P4jn_OPrcr_^Y!Rdqm5HO zj=FW>QaBiVm{Bp)wKq;cd~zDvaZ48!`4(Tlv203Ss=mF(9&?8JyMVjT+15(EpXoBA zxKrdMj@1dvJ+3(0lISBduA2brf*)zn@_yQ7bfGP%?dfVrmdL39hBwV5Qf>;XtQilW zY$_1YNnr;xOdZ}#WN$lX10Fyek<@5zs8r-*-TZnji+joOY*`9x>sFOT%c7frHMVy0 zoj zmyX|sl;89I!{qrS<#!{lCP&wL*jLlNl#C^H#95lJyNks3nt)yBvk~;VH{%}Q+gOf(SxH_j zdHEn?XDqzWCR_?(9NsLQeu&*5V7H|~YM@JFkXY9Gk{HZ160$m--=vIQN`hp`@qjWq z>6Wzx+#1LwQ-vyW0^9F}1j8x>k;MWa=Fvs^r@~>!buNln>Em5#H~}zPotQV}X@kMZ zQG|((P!3}{?9%Rv#VvbUj`grI2Ape~8eG5}c6Tr&$pUmUxw@f}FtglpjGpRUyKNZG zzHpy{92KW5yuQ~VYJYPgkTY`zfn}~Pp~;hJ)?wsCGz;Hy&p@%7XzA?QZgyJp8*$1^ z);DhsT0wh{z7ITF%F;czVH@L$?^khpZByxQggSN32*#c$3ut_oS~hqnVBYGC8@BJ( zXP#B-2UonGgvs1>k}F{8c`bKsruybN{yuvj$&l)8?%1G2dGS$;Lag)L`lP&EW6cLH zbJ0>thxD{ST$5lY7qrGYA9C!0(7>wW=X=~j_5n&ka;#bnDc`bcvU^&jiZ9kG!&>6^M7VCGK0NE^UV-;B0rky$L*So zY(}>>HVLO93gjf6UzBa+%bhdUZ?sjO)nqF$n1tJYg6DlJ3*fXYN)qMRJd9ye3(}s* z3eXimo)rCp!QC)}xx9$C?C^jJobdN}RPHt7e$;66VpBo!6U~?(Tx;xgT+^8r!6;+u PCI^5US{hX7xn24%!w6Ig literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/particle/steam_jet_0.png b/src/main/resources/assets/create/textures/particle/steam_jet_0.png new file mode 100644 index 0000000000000000000000000000000000000000..dde5384b499bad0372cf4cf78c81299bd2771364 GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucL19l9#}EtuWC_;A2_ijA1_=p3jRFje%Ux=c Pfzk|~u6{1-oD!MNS%G|>0G|-o*=x7||NsB=?LR<)Q}6A~K#}EtuWC_+E2j6VH{oi?}1*7tmV+Oiw*QR`r(_%qs^6APaP}zY zj1U)MkYt(a#OMOiw&nT%fASv*kYi<-@7NO{ z#e61i_h0)dCo>j2=Sni3wQ7@t3kTzbUIpe03?X8o29B8`3|lzgY_fb^*6`Ee00&FJ gGYyHHhDJt)_G_B;EAK8j2sEC-)78&qol`;+0AFJ{)&Kwi literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/particle/steam_jet_14.png b/src/main/resources/assets/create/textures/particle/steam_jet_14.png new file mode 100644 index 0000000000000000000000000000000000000000..298d1364287991fb44178f001d0700366edcae25 GIT binary patch literal 201 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G|>0G|-o)3^Wp|NnpX+U-Dr4FQKMLF!6^{DOgk3=Uc=zX1811s;*b3=DjS zL74G){)!Z!pqZzOV~9p@a)KMP2#3J|$$(jcz73t6YD^0y92w3uaTypG87*AFz{EB~ kW(Err52M6_n1-2>3^m7?&Y3HVf*j4@>FVdQ&MBb@07auVf&c&j literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/particle/steam_jet_15.png b/src/main/resources/assets/create/textures/particle/steam_jet_15.png new file mode 100644 index 0000000000000000000000000000000000000000..1e1a76be5f34768fad5fbe52a1471eb94171ef5d GIT binary patch literal 202 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G|>0G|-o*=x6-zWwL_|NlS%pP#!uKU7f*bP@ZUciu5&>O}oX46b@bL7UVCw1dF<>=dTp*>uD9*sB lAs@-$%gS@Xp<$*ZLtzZlVKc=oJApNS%G|>0G|-o*=x7||NsB=?LR<)Q}6A~KP({emB)yQ-G#0c)I$ztaD0e0su)`IaUAw literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/particle/steam_jet_17.png b/src/main/resources/assets/create/textures/particle/steam_jet_17.png new file mode 100644 index 0000000000000000000000000000000000000000..741f1c1f8cc117ac9d068880d4828d208208315c GIT binary patch literal 204 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G|>0G|-o*=x7||NsB=?LR<)Q}6A~KF1scNO>FVdQ&MBb@04#Vpj{pDw literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/particle/steam_jet_18.png b/src/main/resources/assets/create/textures/particle/steam_jet_18.png new file mode 100644 index 0000000000000000000000000000000000000000..8bee0c34a69f4602567057f5a3ca396e12a6696c GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}c0G|-o*=x7||NkGzdq3ySLmNS%G}c0G|-o|NsBbUb`Kn^ik4HAjMn~anMprE0ri(`mJaB_kZvjvNUgv3D;0R~nHNl8PN28L7ZTn#e?q)rByFwU?NVo7LV dWAgD~__mSp&V=6!b%B~0JYD@<);T3K0RRqrG9CZ` literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/particle/steam_jet_2.png b/src/main/resources/assets/create/textures/particle/steam_jet_2.png new file mode 100644 index 0000000000000000000000000000000000000000..599f73087cc731ca8f577ecda5e30ca30380cb8e GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucK}Am&#}EtuWC_;A2_if~2RN2)Z2IrOkZQ!l gIK?yczySt^Nu?}IHOIEL02MQMy85}Sb4q9e0E+)3%K!iX literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/particle/steam_jet_20.png b/src/main/resources/assets/create/textures/particle/steam_jet_20.png new file mode 100644 index 0000000000000000000000000000000000000000..e7468c3af6226e792291f3e85e7f75a10e149aa8 GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}c0G|-o*=x7||NkGzdq3ySLmOihRxUW*prhOg{P=V^Xy?< eoFKu##>Vhs8w+dT{gin?wG5uFelF{r5}E)o)FF%j literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/particle/steam_jet_3.png b/src/main/resources/assets/create/textures/particle/steam_jet_3.png new file mode 100644 index 0000000000000000000000000000000000000000..7807dd166ab08811eaad6cf5b7cfff5c8e8fa8bf GIT binary patch literal 156 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucK|@a$#}EtuWC_;A2_gb)%k%&LI3B|CWb`q2i4A%^y$y&jV^^@O1TaS?83{1ORX;Ee`+y literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/particle/steam_jet_4.png b/src/main/resources/assets/create/textures/particle/steam_jet_4.png new file mode 100644 index 0000000000000000000000000000000000000000..5e23b6cfb62b3f29fec943930c6b1780e03fa946 GIT binary patch literal 164 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucK}$~;#}EtuWC_;A2`mklxBvgsZdAymrqL_> zhn-17SX&|Ez)b7fddB^7+xpyx!sA@y8twV!PC{xWt~$( F695CXFa!Vq literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/particle/steam_jet_5.png b/src/main/resources/assets/create/textures/particle/steam_jet_5.png new file mode 100644 index 0000000000000000000000000000000000000000..16459eb570c678d06e4c287314a20414d2b195bc GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}c0G|-o)3^Wp|NkGz+xS-nq>;HK$S)WuaQzf7P%Q&zfk$L90|Vb-5N14{ zzaj-FsN(737@`rJoZ!UV9M{muc&drpU=gQ*k&|QrqeicRNIRFB8UxQp#*cZ{-=cu( O89ZJ6T-G@yGywn+1TSs? literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/particle/steam_jet_6.png b/src/main/resources/assets/create/textures/particle/steam_jet_6.png new file mode 100644 index 0000000000000000000000000000000000000000..440b528599ae84cf125bd7f32f7216acaf663f4e GIT binary patch literal 193 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G|>0G|-o)3^Wp|NnpX+U-Dr4FQKMLF!6^{DOgk3=Uc=zX1811s;*b3=DjS zL74G){)!Z!pq{6TV~9p@a)KLkvoC`lW2%9HfstdRK-bKP69o@7tZeu=F~mW#;IKi6 dgGO2!!vrm+2b;QIT?Xo8@O1TaS?83{1OOLbIeh>C literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/particle/steam_jet_7.png b/src/main/resources/assets/create/textures/particle/steam_jet_7.png new file mode 100644 index 0000000000000000000000000000000000000000..48213fbdd3e5e088278e98c534f81e074d0dddb8 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G|>0G|-o*=x7||NsB=?LR<)Q}6A~KWk4wvEz2y$qhNelF{r5}E*7*Ei4r literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/particle/steam_jet_8.png b/src/main/resources/assets/create/textures/particle/steam_jet_8.png new file mode 100644 index 0000000000000000000000000000000000000000..1f2702aaaa78a7e8f2d8da4caf8ab1a8a6004753 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc!B|fh#}EtuWCfOg|Nrx+_BJVUrLDi~XTT@9 z(1gw5`W&e@ouRtIQ;u;4HQ5|6(YyY@gkg!`vY9#zn*`YwI7KkV>7R+*&g>&>#G-Cd q`NS%G|>0G|-o*=x7||NsB=?LR<)Q}6A~K