- Fluid tanks become boilers when engines are attached
- Added the steam engine
- Some tweaks and fixes to girder connectivity
This commit is contained in:
simibubi 2022-02-22 19:41:30 +01:00
parent fcb5267ae0
commit cf308cdc7f
97 changed files with 2221 additions and 181 deletions

View file

@ -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

View file

@ -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
}
}
}

View file

@ -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
}
}
}

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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": "在庫スイッチ",

View file

@ -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": "수량 스위치",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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": "Настраиваемый компаратор",

View file

@ -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": "存量转换器",

View file

@ -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": "存量偵測器",

View file

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

View file

@ -28,8 +28,8 @@
"trigger": "create:bracket_apply",
"conditions": {
"accepted_entries": [
"create:large_cogwheel",
"create:cogwheel"
"create:cogwheel",
"create:large_cogwheel"
]
}
},

View file

@ -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"
}
]
}
]
}

View file

@ -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"
}
]
}
]
}

View file

@ -0,0 +1,8 @@
{
"replace": false,
"values": [
"minecraft:furnace",
"minecraft:blast_furnace",
"minecraft:smoker"
]
}

View file

@ -0,0 +1,6 @@
{
"replace": false,
"values": [
"#create:fan_heaters"
]
}

View file

@ -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",

View file

@ -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"),

View file

@ -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<SteamEngineBlock> 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<PoweredShaftBlock> 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<MechanicalPistonBlock> MECHANICAL_PISTON =

View file

@ -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),

View file

@ -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)
;

View file

@ -72,7 +72,7 @@ public class AllTags {
return b -> {
for (String p : path)
b.tag(forgeBlockTag(p));
ItemBuilder<BlockItem,BlockBuilder<T,P>> item = b.item();
ItemBuilder<BlockItem, BlockBuilder<T, P>> item = b.item();
for (String p : path)
item.tag(forgeItemTag(p));
return item;
@ -115,6 +115,9 @@ public class AllTags {
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);

View file

@ -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;
@ -507,6 +510,19 @@ public class AllTileEntities {
.renderer(() -> PortableStorageInterfaceRenderer::new)
.register();
public static final BlockEntityEntry<SteamEngineTileEntity> STEAM_ENGINE = Create.registrate()
.tileEntity("steam_engine", SteamEngineTileEntity::new)
.validBlocks(AllBlocks.STEAM_ENGINE)
.renderer(() -> SteamEngineRenderer::new)
.register();
public static final BlockEntityEntry<PoweredShaftTileEntity> 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<FlywheelTileEntity> FLYWHEEL = Create.registrate()
.tileEntity("flywheel", FlywheelTileEntity::new)
.instance(() -> FlyWheelInstance::new, false)

View file

@ -587,4 +587,8 @@ public class KineticTileEntity extends SmartTileEntity
return true;
}
public int getRotationAngleOffset(Axis axis) {
return 0;
}
}

View file

@ -113,13 +113,13 @@ public class KineticTileEntityRenderer extends SafeTileEntityRenderer<KineticTil
return buffer;
}
protected static float getRotationOffsetForPosition(KineticTileEntity te, final BlockPos pos, final Axis axis) {
public static float getRotationOffsetForPosition(KineticTileEntity te, final BlockPos pos, final Axis axis) {
float offset = ICogWheel.isLargeCog(te.getBlockState()) ? 11.25f : 0;
double d = (((axis == Axis.X) ? 0 : pos.getX()) + ((axis == Axis.Y) ? 0 : pos.getY())
+ ((axis == Axis.Z) ? 0 : pos.getZ())) % 2;
if (d == 0)
offset = 22.5f;
return offset;
return offset + te.getRotationAngleOffset(axis);
}
public static BlockState shaft(Axis axis) {

View file

@ -70,7 +70,7 @@ public abstract class KineticTileInstance<T extends KineticTileEntity> extends B
if (d == 0) {
offset = 22.5f;
}
return offset;
return offset + blockEntity.getRotationAngleOffset(axis);
}
protected Direction.Axis getRotationAxis() {

View file

@ -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<? extends KineticTileEntity> 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));
}
}

View file

@ -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<BlockPos, Integer> 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);
}
}

View file

@ -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<SteamEngineTileEntity> {
public SteamEngineBlock(Properties p_53182_) {
super(p_53182_);
}
@Override
protected void createBlockStateDefinition(Builder<Block, BlockState> 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<SteamEngineTileEntity> getTileEntityClass() {
return SteamEngineTileEntity.class;
}
@Override
public BlockEntityType<? extends SteamEngineTileEntity> getTileEntityType() {
return AllTileEntities.STEAM_ENGINE.get();
}
}

View file

@ -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<SteamEngineTileEntity> {
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);
}
}

View file

@ -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<PoweredShaftTileEntity> target;
public WeakReference<FluidTankTileEntity> 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<TileEntityBehaviour> 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;
}
}

View file

@ -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<SteamJetParticleData> {
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);
}
}
}

View file

@ -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<SteamJetParticleData> {
public static final Codec<SteamJetParticleData> CODEC = RecordCodecBuilder.create(i -> i
.group(Codec.FLOAT.fieldOf("speed")
.forGetter(p -> p.speed))
.apply(i, SteamJetParticleData::new));
public static final ParticleOptions.Deserializer<SteamJetParticleData> DESERIALIZER =
new ParticleOptions.Deserializer<SteamJetParticleData>() {
public SteamJetParticleData fromCommand(ParticleType<SteamJetParticleData> particleTypeIn,
StringReader reader) throws CommandSyntaxException {
reader.expect(' ');
float speed = reader.readFloat();
return new SteamJetParticleData(speed);
}
public SteamJetParticleData fromNetwork(ParticleType<SteamJetParticleData> 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<SteamJetParticleData> getDeserializer() {
return DESERIALIZER;
}
@Override
public Codec<SteamJetParticleData> getCodec(ParticleType<SteamJetParticleData> type) {
return CODEC;
}
@Override
@OnlyIn(Dist.CLIENT)
public SpriteParticleRegistration<SteamJetParticleData> getMetaFactory() {
return SteamJetParticle.Factory::new;
}
}

View file

@ -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);
});

View file

@ -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() {

View file

@ -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<BlockState> 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);

View file

@ -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<Component> 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;
}
}
}

View file

@ -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;
}
}

View file

@ -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;
@ -108,6 +110,14 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE<FluidTankT
return InteractionResult.SUCCESS;
}
@Override
public BlockState updateShape(BlockState pState, Direction pDirection, BlockState pNeighborState,
LevelAccessor pLevel, BlockPos pCurrentPos, BlockPos pNeighborPos) {
if (pDirection == Direction.DOWN && pNeighborState.getBlock() != this)
withTileEntityDo(pLevel, pCurrentPos, FluidTankTileEntity::updateBoilerTemperature);
return pState;
}
@Override
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand,
BlockHitResult ray) {
@ -162,8 +172,7 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE<FluidTankT
FluidAttributes attributes = fluid.getAttributes();
soundevent = attributes.getEmptySound();
if (soundevent == null)
soundevent =
fluid.is(FluidTags.LAVA) ? SoundEvents.BUCKET_EMPTY_LAVA : SoundEvents.BUCKET_EMPTY;
soundevent = fluid.is(FluidTags.LAVA) ? SoundEvents.BUCKET_EMPTY_LAVA : SoundEvents.BUCKET_EMPTY;
}
if (exchange == FluidExchange.TANK_TO_ITEM) {
if (creative && !onClient)
@ -176,8 +185,7 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE<FluidTankT
soundevent = fluid.getAttributes()
.getFillSound();
if (soundevent == null)
soundevent =
fluid.is(FluidTags.LAVA) ? SoundEvents.BUCKET_FILL_LAVA : SoundEvents.BUCKET_FILL;
soundevent = fluid.is(FluidTags.LAVA) ? SoundEvents.BUCKET_FILL_LAVA : SoundEvents.BUCKET_FILL;
}
if (soundevent != null && !onClient) {
@ -194,7 +202,8 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE<FluidTankT
FluidTankTileEntity controllerTE = ((FluidTankTileEntity) te).getControllerTE();
if (controllerTE != null) {
if (fluidState != null && onClient) {
BlockParticleOption blockParticleData = new BlockParticleOption(ParticleTypes.BLOCK, fluidState);
BlockParticleOption blockParticleData =
new BlockParticleOption(ParticleTypes.BLOCK, fluidState);
float level = (float) fluidInTank.getAmount() / fluidTank.getTankCapacity(0);
boolean reversed = fluidInTank.getFluid()

View file

@ -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<IFluidHandler> 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;
}

View file

@ -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<FluidTankTileEntity> {
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<FluidTankTileEntit
float minPuddleHeight = 1 / 16f;
float totalHeight = te.height - 2 * capHeight - minPuddleHeight;
float level = fluidLevel.get(partialTicks);
float level = fluidLevel.getValue(partialTicks);
if (level < 1 / (512f * totalHeight))
return;
float clampedLevel = Mth.clamp(level * totalHeight, 0, totalHeight);
@ -67,6 +77,40 @@ public class FluidTankRenderer extends SafeTileEntityRenderer<FluidTankTileEntit
ms.popPose();
}
protected void renderAsBoiler(FluidTankTileEntity te, float partialTicks, PoseStack ms, MultiBufferSource buffer,
int light, int overlay) {
BlockState blockState = te.getBlockState();
VertexConsumer vb = buffer.getBuffer(RenderType.solid());
ms.pushPose();
TransformStack msr = TransformStack.cast(ms);
msr.translate(te.width / 2f, 0.5, te.width / 2f);
float dialPivot = 5.75f / 16;
float progress = te.boiler.pressure.getValue(partialTicks);
for (Direction d : Iterate.horizontalDirections) {
ms.pushPose();
CachedBufferer.partial(AllBlockPartials.BOILER_GAUGE, blockState)
.rotateY(d.toYRot())
.unCentre()
.translate(te.width / 2f - 6 / 16f, 0, 0)
.light(light)
.renderInto(ms, vb);
CachedBufferer.partial(AllBlockPartials.GAUGE_DIAL, blockState)
.rotateY(d.toYRot())
.unCentre()
.translate(te.width / 2f - 6 / 16f, 0, 0)
.translate(0, dialPivot, dialPivot)
.rotateX(-90 * progress)
.translate(0, -dialPivot, -dialPivot)
.light(light)
.renderInto(ms, vb);
ms.popPose();
}
ms.popPose();
}
@Override
public boolean shouldRenderOffScreen(FluidTankTileEntity te) {
return te.isController();

View file

@ -14,7 +14,8 @@ import com.simibubi.create.foundation.fluid.SmartFluidTank;
import com.simibubi.create.foundation.tileEntity.IMultiTileContainer;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
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.core.Direction;
@ -50,12 +51,14 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI
protected int width;
protected int height;
public BoilerData boiler;
private static final int SYNC_RATE = 8;
protected int syncCooldown;
protected boolean queuedSync;
// For rendering purposes only
private InterpolatedChasingValue fluidLevel;
private LerpedFloat fluidLevel;
public FluidTankTileEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
@ -66,6 +69,7 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI
window = true;
height = 1;
width = 1;
boiler = new BoilerData();
refreshCapability();
}
@ -101,7 +105,9 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI
if (updateConnectivity)
updateConnectivity();
if (fluidLevel != null)
fluidLevel.tick();
fluidLevel.tickChaser();
if (isController())
boiler.tick(this);
}
@Override
@ -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
@ -164,8 +170,9 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI
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,9 +231,20 @@ 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;
queuedSync = false;
@ -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<IFluidHandler> 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));
}
@ -355,9 +396,11 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI
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;
}

View file

@ -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())

View file

@ -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<SimpleKineticTileEntity>, SimpleWaterloggedBlock, IWrenchableWithBracket {
implements ITE<KineticTileEntity>, 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<KineticTileEntity> 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);
@ -97,31 +76,4 @@ public abstract class AbstractShaftBlock extends RotatedPillarKineticBlock
Boolean.valueOf(ifluidstate.getType() == Fluids.WATER));
}
@Override
public Optional<ItemStack> 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<SimpleKineticTileEntity> getTileEntityClass() {
return SimpleKineticTileEntity.class;
}
@Override
public BlockEntityType<? extends SimpleKineticTileEntity> getTileEntityType() {
return AllTileEntities.BRACKETED_KINETIC.get();
}
}

View file

@ -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<ItemStack> 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<? extends KineticTileEntity> getTileEntityType() {
return AllTileEntities.BRACKETED_KINETIC.get();
}
}

View file

@ -19,7 +19,7 @@ public class BracketedKineticTileEntity extends SimpleKineticTileEntity implemen
@Override
public void addBehaviours(List<TileEntityBehaviour> 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);
}

View file

@ -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;

View file

@ -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<ItemStack> getItemPredicate() {
return i -> i.getItem() instanceof BlockItem
&& ((BlockItem) i.getItem()).getBlock() instanceof AbstractShaftBlock;
&& ((BlockItem) i.getItem()).getBlock() instanceof AbstractSimpleShaftBlock;
}
@Override

View file

@ -125,7 +125,8 @@ public class GirderBlock extends Block implements SimpleWaterloggedBlock, IWrenc
Axis axis = direction.getAxis();
Property<Boolean> 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<Boolean> 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;

View file

@ -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));
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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;

View file

@ -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]
}
]
}

File diff suppressed because one or more lines are too long

View file

@ -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]
}
]
}

View file

@ -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"}
}
}
]
}

View file

@ -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]
}
]
}

View file

@ -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]
}
]
}

View file

@ -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]
}
]
}

View file

@ -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]
}
]
}

View file

@ -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"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B