diff --git a/README.md b/README.md index 3d8590c60..20d62523a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

Logo

Create
- Patreon + Patreon Supported Versions License Discord diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index fabed9db5..84c0cfaa3 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -58,6 +58,8 @@ ecf4a72411870bfdbf8a59469b114cd77621c343 assets/create/blockstates/copper_tiles. 3df0d5d5170a2f6cbab0f8a9bc8f2d64229589af assets/create/blockstates/creative_crate.json da3f1203dd0b0096ce19e09705060a0ed0478bee assets/create/blockstates/creative_fluid_tank.json f0031f5e970b3d5695472ed384950b8631b015ed assets/create/blockstates/creative_motor.json +24ee16e3dadb3e0221afce7af37643494f471fb0 assets/create/blockstates/crimson_window.json +3e6cd0945390b390b963474f7cf708e2dcba631c assets/create/blockstates/crimson_window_pane.json fe2f78b94c20944399101e7369e2d43324297fb6 assets/create/blockstates/crushing_wheel.json a1dd6cb3daa97ea871290ef7b178d28b564ee2a2 assets/create/blockstates/crushing_wheel_controller.json b1126c191877cff86b4e2de83e1fcbd151451cb7 assets/create/blockstates/cuckoo_clock.json @@ -137,7 +139,7 @@ fc652317e03b57c76e23a805da16a28d15254029 assets/create/blockstates/fancy_scoria_ fc9ac0a7e7191b93516719455a17177fa6524ecc assets/create/blockstates/fancy_weathered_limestone_bricks_slab.json b2a7c321b1795f20e7433f81a55ce4683de081b8 assets/create/blockstates/fancy_weathered_limestone_bricks_stairs.json 8e532856c3c2b4e4e59c65a2a81a694e35d14658 assets/create/blockstates/fancy_weathered_limestone_bricks_wall.json -3d97226b5e8d8f70ed08e45e78db1faf78d5e28b assets/create/blockstates/fluid_pipe.json +6e9589feb7fab2ac3bed5b4d70be383dfd7e9d7c assets/create/blockstates/fluid_pipe.json f0eaab18e16c4f3f65ebf3b55b08f0dc445720fe assets/create/blockstates/fluid_tank.json 5408d92ab02af86539ac42971d4033545970bb3a assets/create/blockstates/fluid_valve.json e9da1794b6ece7f9aa8bcb43d42c23a55446133b assets/create/blockstates/flywheel.json @@ -322,6 +324,7 @@ c8467d55bc22d2e2256b8b732c06c9fdc64d336f assets/create/blockstates/polished_weat 5d811eab3c5e8411f98e2ea98d93d35955ce18fc assets/create/blockstates/polished_weathered_limestone_slab.json acec6cdebe772ca72de94a85d98199e827495acb assets/create/blockstates/polished_weathered_limestone_stairs.json ad721e3911f48c61c3639edac1896680a31451ff assets/create/blockstates/polished_weathered_limestone_wall.json +3bb571d0a2597907bf3a30686b4bfa0841ac990a assets/create/blockstates/portable_fluid_interface.json 1b70b4e5792dccd2110b84e209016ac258005e28 assets/create/blockstates/portable_storage_interface.json 8296d43d5f1c2113012d127038fb319af83aaee4 assets/create/blockstates/powered_latch.json e8b0a401c10d1ba67ed71ba31bd5f9bc28571b65 assets/create/blockstates/powered_toggle_latch.json @@ -330,7 +333,7 @@ e8b0a401c10d1ba67ed71ba31bd5f9bc28571b65 assets/create/blockstates/powered_toggl d06cd9a1101b18d306a786320aab12018b1325d6 assets/create/blockstates/purple_sail.json 92957119abd5fbcca36a113b2a80255fd70fc303 assets/create/blockstates/purple_seat.json 61035f8afe75ff7bbd291da5d8690bcbebe679eb assets/create/blockstates/purple_valve_handle.json -5d1b30c2bab556f57c78e7780fd445b08f541a50 assets/create/blockstates/radial_chassis.json +4bb26546ac954604a0317b059f2c36a1123772cb assets/create/blockstates/radial_chassis.json 45877c4d90a7185c2f304edbd67379d800920439 assets/create/blockstates/red_sail.json da1b08387af7afa0855ee8d040f620c01f20660a assets/create/blockstates/red_seat.json 722fc77bbf387af8a4016e42cbf9501d2b968881 assets/create/blockstates/red_valve_handle.json @@ -371,6 +374,8 @@ a2454400b1cf9889f70aebdc89c52a1be25f543c assets/create/blockstates/tiled_glass_p a8094531617e27a545c4815ab2062bf0ffca3633 assets/create/blockstates/turntable.json 69dfe8afaa8eb6105dae9f76ab8b7847bf90b8c6 assets/create/blockstates/vertical_framed_glass.json c4db76b9d36cfb098df0d158cb6f8b82768ebe14 assets/create/blockstates/vertical_framed_glass_pane.json +3a5da54d9763e9512cfaa47b25226b79738b25f3 assets/create/blockstates/warped_window.json +19ef7a16c82f07d304fb60d121845185d189aecf assets/create/blockstates/warped_window_pane.json d995547bcd71603ba7378d8998098e462030bfd0 assets/create/blockstates/water_wheel.json f182669f7547964f9f2ef67916568556870def7b assets/create/blockstates/weathered_limestone.json 27e6740834c0f673acc3531371512daa6dcab025 assets/create/blockstates/weathered_limestone_bricks.json @@ -392,17 +397,17 @@ a3a11524cd3515fc01d905767b4b7ea782adaf03 assets/create/blockstates/yellow_seat.j 6801fa1f466f172700e573e5b8ee8ee5f9ca4583 assets/create/blockstates/yellow_valve_handle.json 7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json -04f295b9cbe610bb3664e956437ae68d2a0776ad assets/create/lang/en_ud.json -3912eddc0fdb76afe08961c9d9ad9fe776fbbef5 assets/create/lang/en_us.json -66e50a9482f186f3b0b066bcc7a8d6194b5892b4 assets/create/lang/unfinished/de_de.json -d0adae002c2ca46ad24d4f08037308334c239c69 assets/create/lang/unfinished/fr_fr.json -98b6589d85a68eb4460a7d2da96816b026436c14 assets/create/lang/unfinished/it_it.json -9a9477f8257367993760fbc9e4b65a2d8190b868 assets/create/lang/unfinished/ja_jp.json -e9e466d962ccba589d6d14e37c82e98076a3e614 assets/create/lang/unfinished/ko_kr.json -9e8277f247b069bb45fd45b086a5138ec160847f assets/create/lang/unfinished/nl_nl.json -707ec25a7f45dd3dca8b96d4031b38d1be64f840 assets/create/lang/unfinished/pt_br.json -f645e781db3e254d64ea4b20a553e713bfca3610 assets/create/lang/unfinished/ru_ru.json -1e8a48a6ba2d7ec7947c312835c332e869757526 assets/create/lang/unfinished/zh_cn.json +9b9e9c1867c7cc0247d36212df26e90e8b91ee8f assets/create/lang/en_ud.json +40261df65cf82a5e15069412ba98521897b6a42c assets/create/lang/en_us.json +51577716a7ad7a72b06e81b3ee8bd0ed4e96901f assets/create/lang/unfinished/de_de.json +b57edbe8a697a923ad993a7fb4dc9867bd88c038 assets/create/lang/unfinished/fr_fr.json +f4a1427a07cd88ae8566b9217e8a33be6ee5c941 assets/create/lang/unfinished/it_it.json +bb4ce8e1274f35f5157d042f5d9831532325d921 assets/create/lang/unfinished/ja_jp.json +cd166b00cfbdd6c92e21e809bb6278e0fbba2628 assets/create/lang/unfinished/ko_kr.json +d400b7c2850ddcc9fa1d96df28c2b3494b908d16 assets/create/lang/unfinished/nl_nl.json +e5d52c146688f5c0d7acf570d41d73969677a1a3 assets/create/lang/unfinished/pt_br.json +33ad047f902748c14188b9f67c79c7e9e571567e assets/create/lang/unfinished/ru_ru.json +de21d615b547f01107d3d562d8d0f2afe14e18be assets/create/lang/unfinished/zh_cn.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 @@ -492,7 +497,7 @@ bc23a91f300e46761bb14c597fad39c3d414e84d assets/create/models/block/brass_belt_f dfc6250e28e12ff193a45891978ec50c406fc0c2 assets/create/models/block/brass_belt_funnel__pulling.json 5409325494780afe32e6e30377314e2992ca4aa5 assets/create/models/block/brass_belt_funnel__pushing.json 97410a12b7c1461f88fb633f26ff566a0636b627 assets/create/models/block/brass_belt_funnel__retracted.json -2b1ca994d2feec8321fdb0388028c20d40326eb7 assets/create/models/block/brass_block.json +5adb8b446817eee3a31971d708320c7104d6bbd8 assets/create/models/block/brass_block.json 2e67c147d7c69aabd9ab9f7aa80f60671d5a03aa assets/create/models/block/brass_casing.json 838e7ab4c0c9d89eacfa078daf64995e505db896 assets/create/models/block/brass_funnel.json 6099ba0366065d15d3b2821474850a1ae85485ea assets/create/models/block/brass_funnel_powered.json @@ -547,6 +552,12 @@ feed58a4ad7d7a9e855f0cd7b3fc720616120b4b assets/create/models/block/creative_sin 59c43cc18525792ca96026c966076f52cf7ebef7 assets/create/models/block/creative_top_window_nw.json a6eea01609266b757342984889af16234ecd5189 assets/create/models/block/creative_top_window_se.json 6e1d2fb66291f2a3e3a213f43b47fb9760cb959f assets/create/models/block/creative_top_window_sw.json +8390ebba3a149135c21a3e48fcc84660eea5f766 assets/create/models/block/crimson_window.json +5e0c0ac8b2d222bb359a84a1f179c54c823ad5b8 assets/create/models/block/crimson_window_pane_noside.json +19503fe4a6eec4d250efb1a7a4fe53fd1035b429 assets/create/models/block/crimson_window_pane_noside_alt.json +14a14ab7c1a812a5ac8e282747f125461bf6b1d5 assets/create/models/block/crimson_window_pane_post.json +b9e6d8befe3f2281413288e0350425987256e238 assets/create/models/block/crimson_window_pane_side.json +bcbfa40524cff0314d9e764a64f90f2095d14064 assets/create/models/block/crimson_window_pane_side_alt.json 68843a02a32c156afad85830877b83f9b51c5147 assets/create/models/block/cyan_sail.json 6704782830b3d872321e895b6903709c18e3778f assets/create/models/block/cyan_seat.json f45ef4a5f0aa8482d493661673b1c0ab6d061157 assets/create/models/block/cyan_valve_handle.json @@ -1116,6 +1127,12 @@ d13df8a5920c5778d98081fb0e97f045e2fd46a2 assets/create/models/block/vertical_fra a5938ddd48109f067a19a90a0f9abab655c18821 assets/create/models/block/vertical_framed_glass_pane_post.json 41645919ece236df5804a5a73ef682720194de34 assets/create/models/block/vertical_framed_glass_pane_side.json 8bc0abaabdc62d0c27730dba7eb6da54607b7e96 assets/create/models/block/vertical_framed_glass_pane_side_alt.json +c6c7067a760d8c787841a72c8048172fb534d8c5 assets/create/models/block/warped_window.json +01a1034b3bad86f23874b045c5eceb0f1078d6d9 assets/create/models/block/warped_window_pane_noside.json +51179b8e4e3d91cfb6fbeb08e1920afc2c16c237 assets/create/models/block/warped_window_pane_noside_alt.json +82b11c5dbd3ffdbbd129c4b4244487a8f3256f33 assets/create/models/block/warped_window_pane_post.json +b3682b275994e1dac31d56b56f3f3c1e3b2962d7 assets/create/models/block/warped_window_pane_side.json +0b1c6b66d22338e0152a62f869475d734029611e assets/create/models/block/warped_window_pane_side_alt.json 867c400d32bc2242d041bf650149fced6e7104ed assets/create/models/block/weathered_limestone.json 0235f7c186a5cb6c5081c4bbddb2e5bb0af76c93 assets/create/models/block/weathered_limestone_bricks.json a569dd152c6a52281fe5ca704fa439768ca9b485 assets/create/models/block/weathered_limestone_bricks_slab.json @@ -1211,6 +1228,8 @@ f56bf22324faf8958eaef4d94b958f1108d52e5a assets/create/models/item/copper_tiles. 7b333dea353afaa27b182aedc647c9e9e34e92ef assets/create/models/item/creative_crate.json f7d06c52c3ca8c22ad67f5741471f06ac22e7fcb assets/create/models/item/creative_fluid_tank.json 5b39403f6c81f05e566b621b62e267267de47c41 assets/create/models/item/creative_motor.json +5680d7cee347c46bb29db8c77dc33f234a7eba41 assets/create/models/item/crimson_window.json +cdcc4c773bdda431e2aef26e83c061db36e66bae assets/create/models/item/crimson_window_pane.json 6281a7439c92459761893835f91fde25467fae76 assets/create/models/item/crushed_brass.json cd148cb7e881091ecce2390dac0d9f545573c91c assets/create/models/item/crushed_copper_ore.json 5b701661c7b847dfe5b4cbc854b48f128f90090c assets/create/models/item/crushed_gold_ore.json @@ -1480,6 +1499,7 @@ e95125318055b8557afd7d108488cf0bdd81fe49 assets/create/models/item/polished_scor 68fb04f7a89c8117bb641e347df9bfc1f1248335 assets/create/models/item/polished_weathered_limestone_slab.json 6d92ee7112aa20e8a1adfe73d8933031c299bed1 assets/create/models/item/polished_weathered_limestone_stairs.json d98a1d479dff88d7a6f084f2c9de8fbbf80961ef assets/create/models/item/polished_weathered_limestone_wall.json +0e5638cdbf04d7af2222ec15fbe1d960385ea237 assets/create/models/item/portable_fluid_interface.json 3bc60b0d9884c2ee0f1dd530e90fceb699eea737 assets/create/models/item/portable_storage_interface.json 417c301eb7e54f14c564975570f59d048cc88987 assets/create/models/item/powdered_obsidian.json 1e501c1f2e9250aaaadcf17db62646d08177d4e1 assets/create/models/item/powered_latch.json @@ -1538,6 +1558,8 @@ fb24881c4e92bbb7ffa54a71e0af6b1c66d84829 assets/create/models/item/turntable.jso 5e331da9d4086412f5722923e3008246ed286a00 assets/create/models/item/vertical_framed_glass_pane.json 00c2929de9b7171656bea74e1a6d694c6a45b075 assets/create/models/item/vertical_gearbox.json 2d4a31321cc13f62f5fd73aabdc5fd97e635bfbc assets/create/models/item/wand_of_symmetry.json +89493fa0691453d6c604e3ed9ae077fe43648d18 assets/create/models/item/warped_window.json +5f169d526b4697c85e6d113be4ff81a2b45b6e6a assets/create/models/item/warped_window_pane.json ae20383b0b0806431d0fdd8ffdd16fe2b0cc61ad assets/create/models/item/water_wheel.json 1d097a315c2817d16c241c86f66bd48e5e52f4b4 assets/create/models/item/weathered_limestone.json fcc8ab312989ec485e2d86b856d81dbafaf0e930 assets/create/models/item/weathered_limestone_bricks.json @@ -1694,6 +1716,7 @@ ccd49c33260333ba850d0b843c4913cb6371eee9 data/create/advancements/recipes/create ca21e2192a2fea0f112764f96c928d337762158b data/create/advancements/recipes/create.base/crafting/kinetics/pink_seat_from_other_seat.json 6c11444884679c4dd03d43f5893fca5cdc271915 data/create/advancements/recipes/create.base/crafting/kinetics/pink_valve_handle_from_other_valve_handle.json 960d03f13b383fca0d9b7d3a2885da346d97c4ef data/create/advancements/recipes/create.base/crafting/kinetics/piston_extension_pole.json +164563947ebd951d36a839ee0787714b104ba090 data/create/advancements/recipes/create.base/crafting/kinetics/portable_fluid_interface.json 3190b3800152879614127c7cd2616e5607f1a0b1 data/create/advancements/recipes/create.base/crafting/kinetics/portable_storage_interface.json 02258b70f1db3d91f0ccb5a5ffd362349f8f359d data/create/advancements/recipes/create.base/crafting/kinetics/propeller.json d2a430820a87c24104729eede57628c6a92b277e data/create/advancements/recipes/create.base/crafting/kinetics/purple_seat.json @@ -1806,6 +1829,8 @@ c31a4d1eacc892a0248315270a12c0b49f5edc63 data/create/advancements/recipes/create b873bd961cd865866a6f5035bee583a400073a3c data/create/advancements/recipes/create.palettes/chiseled_scoria_from_scoria_stonecutting.json 0ace6bef40eab8e365959e529a16cd04d15adfe6 data/create/advancements/recipes/create.palettes/chiseled_weathered_limestone_from_weathered_limestone_stonecutting.json b4651c8202331483e82b28b04edc6cd97e62ad1d data/create/advancements/recipes/create.palettes/crafting/palettes/dark_scoria.json +9a587cd39af620df5bf25ff0143108c6be9597f5 data/create/advancements/recipes/create.palettes/crimson_window.json +b2813566e6715c2d377dd4ef461b012cae7eb190 data/create/advancements/recipes/create.palettes/crimson_window_pane.json 25991d5667252d551e02c4fbbfa27ebf4353d28d data/create/advancements/recipes/create.palettes/dark_oak_window.json 4819383b1a7885b4401fdc25955d2c51f75b6236 data/create/advancements/recipes/create.palettes/dark_oak_window_pane.json ebd6413d530325eef6fcf42a0ee0ac840c1f7366 data/create/advancements/recipes/create.palettes/dark_scoria_bricks_from_dark_scoria_stonecutting.json @@ -2141,6 +2166,8 @@ ab0cacba05f8def9cc91b993d464c297babf6fc3 data/create/advancements/recipes/create d40c7ce6b79630ace624d17b92667286998d93bc data/create/advancements/recipes/create.palettes/tiled_glass_pane.json 24fafe59013a3e0439a73ea4e0cef114fc9a8e4b data/create/advancements/recipes/create.palettes/vertical_framed_glass_from_glass_colorless_stonecutting.json cd5ee73117872ee98434be1d24b4f271f7e94a48 data/create/advancements/recipes/create.palettes/vertical_framed_glass_pane.json +f26d1a1ee183b1b19d018fbdefc70f0bf29b41d0 data/create/advancements/recipes/create.palettes/warped_window.json +faf33c9c630eecab88bb969e3b9f7fd9e9f6ccf6 data/create/advancements/recipes/create.palettes/warped_window_pane.json ef0d351d13f7e9c633581b537c59bddc1fa4c3a4 data/create/advancements/recipes/create.palettes/weathered_limestone_bricks_from_weathered_limestone_stonecutting.json 1c931e15af3e5b5f78a0a62b8c159fdf9f0d7f3e data/create/advancements/recipes/create.palettes/weathered_limestone_bricks_slab.json bba639941526cc23570e328e0b5e2a5545667219 data/create/advancements/recipes/create.palettes/weathered_limestone_bricks_slab_from_weathered_limestone_bricks_stonecutting.json @@ -2243,6 +2270,8 @@ c013613df278f6e8b4c9dad5f16e0ec6c3e992e3 data/create/loot_tables/blocks/copper_t b160899aa785dc54d8c6cc095337f70b81f3e44f data/create/loot_tables/blocks/creative_crate.json 51d66e32581b87beb871d99b93cb45d45eada8dd data/create/loot_tables/blocks/creative_fluid_tank.json d8f2f8921b9200b1d9476a77ee1be32c25308ac3 data/create/loot_tables/blocks/creative_motor.json +08b427aea85e467d7fe58d0e691de428dd64da7f data/create/loot_tables/blocks/crimson_window.json +ba084fc3c680c9dea0d03fc664a831dfed18e52e data/create/loot_tables/blocks/crimson_window_pane.json c28fa42746a4d5ca2f824001b67e58673810169e data/create/loot_tables/blocks/crushing_wheel.json 205f5899101262f31f5c1a88bb7d954918d08d04 data/create/loot_tables/blocks/crushing_wheel_controller.json d370ee874b5b6b98e9a8c368218fe61f644d956d data/create/loot_tables/blocks/cuckoo_clock.json @@ -2507,6 +2536,7 @@ c7029af40b6f5dd2cd8f2ae7dfb89b37074624e6 data/create/loot_tables/blocks/polished 93f7be402a8088d33a94954572e111bcd71f11c8 data/create/loot_tables/blocks/polished_weathered_limestone_slab.json 6ef650c723d409c7a678ffac45212e22e37581c0 data/create/loot_tables/blocks/polished_weathered_limestone_stairs.json 58715bc033e4740dbb754f91c93a22b9d06828e6 data/create/loot_tables/blocks/polished_weathered_limestone_wall.json +ac945ab9e78d52daff38b9c288824ec6f643b23a data/create/loot_tables/blocks/portable_fluid_interface.json fbe98efcb1a5970b6795fdbbb671fee704c0945f data/create/loot_tables/blocks/portable_storage_interface.json 6a46f00d9de7050eb9748d5dbed182caa6b29949 data/create/loot_tables/blocks/powered_latch.json a3fb7d3e3bf9dc73ce754002f10c469d57db1f71 data/create/loot_tables/blocks/powered_toggle_latch.json @@ -2556,6 +2586,8 @@ e999969f05d2625e61757aa82092d232b99f6e0a data/create/loot_tables/blocks/tiled_gl 7b66ad2c48449bafd0cdbd086ac41218cb73a814 data/create/loot_tables/blocks/turntable.json 028e293b5cd694017962f67dc80dba719f904e28 data/create/loot_tables/blocks/vertical_framed_glass.json d0156602dd5f4a274c293df67e19374820c72890 data/create/loot_tables/blocks/vertical_framed_glass_pane.json +1afc5ede08e72221e33910603fa7acd0b3c7a2ee data/create/loot_tables/blocks/warped_window.json +f334fd2b9a92b0646674239e7e34e142fe2c5fad data/create/loot_tables/blocks/warped_window_pane.json 2883c63ceb1273009dbf91cb0693756cadf79a1a data/create/loot_tables/blocks/water_wheel.json 611d6195db52c074de484ec52d7ac9eb96b4ff10 data/create/loot_tables/blocks/weathered_limestone.json c1f379baad36a20fc767be094db10480a0378184 data/create/loot_tables/blocks/weathered_limestone_bricks.json @@ -2706,7 +2738,8 @@ af871a02d363a619fff8e9dde753aa417b265a80 data/create/recipes/crafting/kinetics/p 840dc5aac716e3d1b79883e8db4bf56f2dc427f9 data/create/recipes/crafting/kinetics/pink_seat_from_other_seat.json 7e73bcde2b599f1ae5a241dd707c8ab6ce8c5a6e data/create/recipes/crafting/kinetics/pink_valve_handle_from_other_valve_handle.json 5399c3496a90bed9428c48fdd334ad4f763cbf9a data/create/recipes/crafting/kinetics/piston_extension_pole.json -0b09786f6d9823c6eddc91c3a6837377690dde49 data/create/recipes/crafting/kinetics/portable_storage_interface.json +a8e996bed77d3d20725f9d592c250392b3adb106 data/create/recipes/crafting/kinetics/portable_fluid_interface.json +7ed5699349faf2981228769c873057105a5ea3ea data/create/recipes/crafting/kinetics/portable_storage_interface.json 16199a6729005a279854cb1838401f6e73bdebae data/create/recipes/crafting/kinetics/propeller.json 76ba751b65d312d1b34229d76fff2111b593091a data/create/recipes/crafting/kinetics/purple_seat.json e6c462d64e1de9c7fca95f9c9a25b8d1575979da data/create/recipes/crafting/kinetics/purple_seat_from_other_seat.json @@ -2787,6 +2820,8 @@ fe95f8f5f15edb0a5ff8da5a4757c9f8910b51bd data/create/recipes/crafting/palettes/d 5c47ac2e2b596439a684126fef7265f13de2379b data/create/recipes/crafting/schematics/schematic_and_quill.json 9fb943be76c51a24aa9d8a09de5b7bd17b44ab08 data/create/recipes/crafting/schematics/schematic_table.json 1a810338ea15ab5ac2f37e87579c56f72b2b371b data/create/recipes/crafting/schematics/schematicannon.json +4629d9a1a8a98a6b5b8b82c4507ca9e321c3a210 data/create/recipes/crimson_window.json +72cffde4281a1e34d77aa91c847e811833b68f21 data/create/recipes/crimson_window_pane.json 3da7a3cdb84f44e259b5399a94ddfbf94ebebd37 data/create/recipes/crushing/blaze_rod.json 5878767e89be5a522b8f28d6a2d7b2f8566cf0dd data/create/recipes/crushing/brass_block.json b83ef0af844ca068e0353330b8273bace5b6a8c3 data/create/recipes/crushing/coal_ore.json @@ -3289,6 +3324,8 @@ e2c1774577aeb0756fb1d092245d9d77e40ba5f8 data/create/recipes/splashing/yellow_co 39bd4bcaad003edbe035c91ffde61c51ee1edb87 data/create/recipes/tiled_glass_pane.json 7c6778a30bb670762c3a410cb19d1effc55a7063 data/create/recipes/vertical_framed_glass_from_glass_colorless_stonecutting.json dc6093427210bd7034a0e2184f6a1630c7b33b3e data/create/recipes/vertical_framed_glass_pane.json +40ec72d571002206c276aec5de72459155e043ce data/create/recipes/warped_window.json +8f4b0a3cfb0073f1414bf18c0d4e5e751c4a9185 data/create/recipes/warped_window_pane.json f75f25d3259dd51c29bee6ada2a4540a7a2bbeab data/create/recipes/weathered_limestone_bricks_from_weathered_limestone_stonecutting.json f58ef5eb552fc7dcd89f30aa4231286ecef5e00a data/create/recipes/weathered_limestone_bricks_slab.json ca9b163b3aaa526d6c3b070c2a7e50a56a38c6f4 data/create/recipes/weathered_limestone_bricks_slab_from_weathered_limestone_bricks_stonecutting.json @@ -3320,7 +3357,7 @@ d2dc4ff179ef7b2aa9276455c196e15d44aa95a8 data/create/tags/items/crushed_ores.jso abbe5d7cc9d1705509257888154ed7ca23292586 data/create/tags/items/upright_on_belt.json 50936b211d94167a35ec78c89954082a336b6269 data/create/tags/items/valve_handles.json 16bcb8fcbe9170c2c11f1ca8d99d8b36cd812bbd data/forge/tags/blocks/glass/colorless.json -81ced867d24ec814942909965dd4576eff1db685 data/forge/tags/blocks/glass_panes.json +81d3eb40b048160fcc2d6bb7ff12b49276297efd data/forge/tags/blocks/glass_panes.json 4b700ee8aa748c2ec70c29ef1589844879c0deae data/forge/tags/blocks/ores.json 4a0b13a9835106de9a1dd0a71a02372abb48e7b6 data/forge/tags/blocks/ores/copper.json d5ea262a0f5fb210612d22521818e26cf08e591a data/forge/tags/blocks/ores/zinc.json @@ -3331,7 +3368,7 @@ f6c8f34ceb475546dba5cc6ff288863ea795d20b data/forge/tags/blocks/storage_blocks/c d9ffc62a496946fc4848934e7c0a6e917337f8be data/forge/tags/items/beacon_payment.json 05ca51cdc60a5e109b5a0e3b782de13d34ebcb24 data/forge/tags/items/cobblestone.json 16bcb8fcbe9170c2c11f1ca8d99d8b36cd812bbd data/forge/tags/items/glass/colorless.json -81ced867d24ec814942909965dd4576eff1db685 data/forge/tags/items/glass_panes.json +81d3eb40b048160fcc2d6bb7ff12b49276297efd data/forge/tags/items/glass_panes.json d9ffc62a496946fc4848934e7c0a6e917337f8be data/forge/tags/items/ingots.json 2dfd21017cb51d4bdc18d977a7d16f103cc3a985 data/forge/tags/items/ingots/brass.json 8e0ca32df10a50544f54fbe3dbfe485971b23315 data/forge/tags/items/ingots/copper.json @@ -3353,7 +3390,7 @@ ff1900963bc4cd8ceffa78d58ef1952ceacb2fb7 data/forge/tags/items/storage_blocks/br f6c8f34ceb475546dba5cc6ff288863ea795d20b data/forge/tags/items/storage_blocks/copper.json 7f71a774800111e50b42de0e6159ed2d2a807d32 data/forge/tags/items/storage_blocks/zinc.json 508730d3822c54d355329bf6a33d58071653afad data/minecraft/tags/blocks/beacon_base_blocks.json -31424fe956db0354a9f24c61baf977a2961c8db6 data/minecraft/tags/blocks/impermeable.json +69f596fcb065e26b02ce246760432b5174191b76 data/minecraft/tags/blocks/impermeable.json 9dadc647e17b6262c13b6d8eda9139e30ce7e7d0 data/minecraft/tags/blocks/rails.json 29e6f7e3d4be9a9b0af1fca5d32fa55e29905ce2 data/minecraft/tags/blocks/slabs.json 0d188ad2c33d10ee8f0d455c4e63a4460a8302fb data/minecraft/tags/blocks/stairs.json diff --git a/src/generated/resources/assets/create/blockstates/fluid_pipe.json b/src/generated/resources/assets/create/blockstates/fluid_pipe.json index a4cffcde7..3b646b920 100644 --- a/src/generated/resources/assets/create/blockstates/fluid_pipe.json +++ b/src/generated/resources/assets/create/blockstates/fluid_pipe.json @@ -303,8 +303,8 @@ { "when": { "west": "false", - "down": "false", "east": "true", + "down": "false", "up": "true" }, "apply": { @@ -314,8 +314,8 @@ { "when": { "west": "true", - "down": "false", "east": "false", + "down": "false", "up": "true" }, "apply": { @@ -325,8 +325,8 @@ { "when": { "west": "false", - "down": "true", "east": "true", + "down": "true", "up": "false" }, "apply": { @@ -336,8 +336,8 @@ { "when": { "west": "true", - "down": "true", "east": "false", + "down": "true", "up": "false" }, "apply": { @@ -347,8 +347,8 @@ { "when": { "west": "false", - "down": "true", "east": "false", + "down": "true", "up": "true" }, "apply": { @@ -358,8 +358,8 @@ { "when": { "west": "false", - "down": "false", "east": "false", + "down": "false", "up": "true" }, "apply": { @@ -369,8 +369,8 @@ { "when": { "west": "false", - "down": "true", "east": "false", + "down": "true", "up": "false" }, "apply": { @@ -380,8 +380,8 @@ { "when": { "west": "true", - "down": "false", "east": "true", + "down": "false", "up": "false" }, "apply": { @@ -391,8 +391,8 @@ { "when": { "west": "false", - "down": "false", "east": "true", + "down": "false", "up": "false" }, "apply": { @@ -402,8 +402,8 @@ { "when": { "west": "true", - "down": "false", "east": "false", + "down": "false", "up": "false" }, "apply": { @@ -413,8 +413,8 @@ { "when": { "west": "false", - "down": "false", "east": "false", + "down": "false", "up": "false" }, "apply": { diff --git a/src/generated/resources/assets/create/blockstates/portable_fluid_interface.json b/src/generated/resources/assets/create/blockstates/portable_fluid_interface.json new file mode 100644 index 000000000..e231a5b5a --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/portable_fluid_interface.json @@ -0,0 +1,30 @@ +{ + "variants": { + "facing=down": { + "model": "create:block/portable_fluid_interface/block", + "x": 180 + }, + "facing=up": { + "model": "create:block/portable_fluid_interface/block" + }, + "facing=north": { + "model": "create:block/portable_fluid_interface/block", + "x": 90 + }, + "facing=south": { + "model": "create:block/portable_fluid_interface/block", + "x": 90, + "y": 180 + }, + "facing=west": { + "model": "create:block/portable_fluid_interface/block", + "x": 90, + "y": 270 + }, + "facing=east": { + "model": "create:block/portable_fluid_interface/block", + "x": 90, + "y": 90 + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/lang/en_ud.json b/src/generated/resources/assets/create/lang/en_ud.json index 1e75bdd5e..a98ffe1fb 100644 --- a/src/generated/resources/assets/create/lang/en_ud.json +++ b/src/generated/resources/assets/create/lang/en_ud.json @@ -323,6 +323,7 @@ "block.create.polished_weathered_limestone_slab": "q\u0250\u05DFS \u01DDuo\u0287s\u01DD\u026F\u0131\uA780 p\u01DD\u0279\u01DD\u0265\u0287\u0250\u01DDM p\u01DD\u0265s\u0131\u05DFo\u0500", "block.create.polished_weathered_limestone_stairs": "s\u0279\u0131\u0250\u0287S \u01DDuo\u0287s\u01DD\u026F\u0131\uA780 p\u01DD\u0279\u01DD\u0265\u0287\u0250\u01DDM p\u01DD\u0265s\u0131\u05DFo\u0500", "block.create.polished_weathered_limestone_wall": "\u05DF\u05DF\u0250M \u01DDuo\u0287s\u01DD\u026F\u0131\uA780 p\u01DD\u0279\u01DD\u0265\u0287\u0250\u01DDM p\u01DD\u0265s\u0131\u05DFo\u0500", + "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_toggle_latch": "\u0265\u0254\u0287\u0250\uA780 \u01DD\u05DFbbo\u27D8 p\u01DD\u0279\u01DD\u028Do\u0500", diff --git a/src/generated/resources/assets/create/lang/en_us.json b/src/generated/resources/assets/create/lang/en_us.json index 1b4620c5e..c4d69c991 100644 --- a/src/generated/resources/assets/create/lang/en_us.json +++ b/src/generated/resources/assets/create/lang/en_us.json @@ -326,6 +326,7 @@ "block.create.polished_weathered_limestone_slab": "Polished Weathered Limestone Slab", "block.create.polished_weathered_limestone_stairs": "Polished Weathered Limestone Stairs", "block.create.polished_weathered_limestone_wall": "Polished Weathered Limestone Wall", + "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_toggle_latch": "Powered Toggle Latch", diff --git a/src/generated/resources/assets/create/lang/unfinished/de_de.json b/src/generated/resources/assets/create/lang/unfinished/de_de.json index 31cd74c98..a0469d075 100644 --- a/src/generated/resources/assets/create/lang/unfinished/de_de.json +++ b/src/generated/resources/assets/create/lang/unfinished/de_de.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1042", + "_": "Missing Localizations: 1043", "_": "->------------------------] Game Elements [------------------------<-", @@ -327,6 +327,7 @@ "block.create.polished_weathered_limestone_slab": "Polierte Verwitterte Kalksteinstufe", "block.create.polished_weathered_limestone_stairs": "UNLOCALIZED: Polished Weathered Limestone Stairs", "block.create.polished_weathered_limestone_wall": "UNLOCALIZED: Polished Weathered Limestone Wall", + "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_toggle_latch": "UNLOCALIZED: Powered Toggle Latch", diff --git a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json index 734ffd347..3827b205c 100644 --- a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json +++ b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 671", + "_": "Missing Localizations: 672", "_": "->------------------------] Game Elements [------------------------<-", @@ -327,6 +327,7 @@ "block.create.polished_weathered_limestone_slab": "Dalle de calcaire patinées", "block.create.polished_weathered_limestone_stairs": "UNLOCALIZED: Polished Weathered Limestone Stairs", "block.create.polished_weathered_limestone_wall": "UNLOCALIZED: Polished Weathered Limestone Wall", + "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_toggle_latch": "Verrou alimenté à bascule", diff --git a/src/generated/resources/assets/create/lang/unfinished/it_it.json b/src/generated/resources/assets/create/lang/unfinished/it_it.json index 7b822c68d..ec2e3e609 100644 --- a/src/generated/resources/assets/create/lang/unfinished/it_it.json +++ b/src/generated/resources/assets/create/lang/unfinished/it_it.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 655", + "_": "Missing Localizations: 656", "_": "->------------------------] Game Elements [------------------------<-", @@ -327,6 +327,7 @@ "block.create.polished_weathered_limestone_slab": "Lastra di Calcare Consumato Levigato", "block.create.polished_weathered_limestone_stairs": "UNLOCALIZED: Polished Weathered Limestone Stairs", "block.create.polished_weathered_limestone_wall": "UNLOCALIZED: Polished Weathered Limestone Wall", + "block.create.portable_fluid_interface": "UNLOCALIZED: Portable Fluid Interface", "block.create.portable_storage_interface": "Interfaccia di Archiviazione Portatile", "block.create.powered_latch": "Leva Alimentata", "block.create.powered_toggle_latch": "Leva Alimentata Alterata", diff --git a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json index b8dbdb671..8283f2543 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json +++ b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 654", + "_": "Missing Localizations: 655", "_": "->------------------------] Game Elements [------------------------<-", @@ -327,6 +327,7 @@ "block.create.polished_weathered_limestone_slab": "磨かれた風化石灰岩のハーフブロック", "block.create.polished_weathered_limestone_stairs": "UNLOCALIZED: Polished Weathered Limestone Stairs", "block.create.polished_weathered_limestone_wall": "UNLOCALIZED: Polished Weathered Limestone Wall", + "block.create.portable_fluid_interface": "UNLOCALIZED: Portable Fluid Interface", "block.create.portable_storage_interface": "ポータブルストレージインターフェイス", "block.create.powered_latch": "パワードラッチ", "block.create.powered_toggle_latch": "パワードトグルラッチ", diff --git a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json index 3a019fae3..67dd3c869 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json +++ b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 655", + "_": "Missing Localizations: 656", "_": "->------------------------] Game Elements [------------------------<-", @@ -327,6 +327,7 @@ "block.create.polished_weathered_limestone_slab": "윤나는 풍화된 석회암 반 블록", "block.create.polished_weathered_limestone_stairs": "UNLOCALIZED: Polished Weathered Limestone Stairs", "block.create.polished_weathered_limestone_wall": "UNLOCALIZED: Polished Weathered Limestone Wall", + "block.create.portable_fluid_interface": "UNLOCALIZED: Portable Fluid Interface", "block.create.portable_storage_interface": "이동식 저장소 인터페이스", "block.create.powered_latch": "레드스톤 걸쇠", "block.create.powered_toggle_latch": "레드스톤 토글 걸쇠", diff --git a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json index f622b9656..b87dccf6b 100644 --- a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json +++ b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 983", + "_": "Missing Localizations: 984", "_": "->------------------------] Game Elements [------------------------<-", @@ -327,6 +327,7 @@ "block.create.polished_weathered_limestone_slab": "Gepolijste Verweerde Kalksteen Plaat", "block.create.polished_weathered_limestone_stairs": "UNLOCALIZED: Polished Weathered Limestone Stairs", "block.create.polished_weathered_limestone_wall": "UNLOCALIZED: Polished Weathered Limestone Wall", + "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_toggle_latch": "UNLOCALIZED: Powered Toggle Latch", diff --git a/src/generated/resources/assets/create/lang/unfinished/pt_br.json b/src/generated/resources/assets/create/lang/unfinished/pt_br.json index 80d89f6e0..14e55ca88 100644 --- a/src/generated/resources/assets/create/lang/unfinished/pt_br.json +++ b/src/generated/resources/assets/create/lang/unfinished/pt_br.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1049", + "_": "Missing Localizations: 1050", "_": "->------------------------] Game Elements [------------------------<-", @@ -327,6 +327,7 @@ "block.create.polished_weathered_limestone_slab": "Lajota de Calcário Polido Resistido", "block.create.polished_weathered_limestone_stairs": "UNLOCALIZED: Polished Weathered Limestone Stairs", "block.create.polished_weathered_limestone_wall": "UNLOCALIZED: Polished Weathered Limestone Wall", + "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_toggle_latch": "UNLOCALIZED: Powered Toggle Latch", diff --git a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json index 76a352012..ad536d123 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json +++ b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 324", + "_": "Missing Localizations: 325", "_": "->------------------------] Game Elements [------------------------<-", @@ -327,6 +327,7 @@ "block.create.polished_weathered_limestone_slab": "Плита из полированного выветренного известняка", "block.create.polished_weathered_limestone_stairs": "Ступени из полированного выветренного известняка", "block.create.polished_weathered_limestone_wall": "Стена из полированного выветренного известняка", + "block.create.portable_fluid_interface": "UNLOCALIZED: Portable Fluid Interface", "block.create.portable_storage_interface": "Портативный интерфейс хранения", "block.create.powered_latch": "Механизированная защёлка", "block.create.powered_toggle_latch": "Механизированная рычаг-защёлка", diff --git a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json index 8c1ef7e62..4e17d99ea 100644 --- a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json +++ b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 337", + "_": "Missing Localizations: 338", "_": "->------------------------] Game Elements [------------------------<-", @@ -327,6 +327,7 @@ "block.create.polished_weathered_limestone_slab": "磨制风化石灰岩台阶", "block.create.polished_weathered_limestone_stairs": "磨制风化石灰岩楼梯", "block.create.polished_weathered_limestone_wall": "磨制风化石灰岩墙", + "block.create.portable_fluid_interface": "UNLOCALIZED: Portable Fluid Interface", "block.create.portable_storage_interface": "移动式存储接口", "block.create.powered_latch": "锁存器", "block.create.powered_toggle_latch": "T触发器", diff --git a/src/generated/resources/assets/create/models/block/brass_block.json b/src/generated/resources/assets/create/models/block/brass_block.json index 124827f00..c3d4b94f4 100644 --- a/src/generated/resources/assets/create/models/block/brass_block.json +++ b/src/generated/resources/assets/create/models/block/brass_block.json @@ -1,6 +1,6 @@ { "parent": "minecraft:block/cube_all", "textures": { - "all": "create:block/brass_block" + "all": "create:block/brass_storage_block" } } \ No newline at end of file diff --git a/src/generated/resources/assets/create/models/item/portable_fluid_interface.json b/src/generated/resources/assets/create/models/item/portable_fluid_interface.json new file mode 100644 index 000000000..9418446e7 --- /dev/null +++ b/src/generated/resources/assets/create/models/item/portable_fluid_interface.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/portable_fluid_interface/item" +} \ No newline at end of file diff --git a/src/generated/resources/data/create/advancements/recipes/create.base/crafting/kinetics/portable_fluid_interface.json b/src/generated/resources/data/create/advancements/recipes/create.base/crafting/kinetics/portable_fluid_interface.json new file mode 100644 index 000000000..2b2f247b3 --- /dev/null +++ b/src/generated/resources/data/create/advancements/recipes/create.base/crafting/kinetics/portable_fluid_interface.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "rewards": { + "recipes": [ + "create:crafting/kinetics/portable_fluid_interface" + ] + }, + "criteria": { + "has_item": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "create:copper_casing" + } + ] + } + }, + "has_the_recipe": { + "trigger": "minecraft:recipe_unlocked", + "conditions": { + "recipe": "create:crafting/kinetics/portable_fluid_interface" + } + } + }, + "requirements": [ + [ + "has_item", + "has_the_recipe" + ] + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/portable_fluid_interface.json b/src/generated/resources/data/create/loot_tables/blocks/portable_fluid_interface.json new file mode 100644 index 000000000..d4f291dad --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/portable_fluid_interface.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "name": "create:portable_fluid_interface" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/recipes/crafting/kinetics/portable_fluid_interface.json b/src/generated/resources/data/create/recipes/crafting/kinetics/portable_fluid_interface.json new file mode 100644 index 000000000..61bf4785c --- /dev/null +++ b/src/generated/resources/data/create/recipes/crafting/kinetics/portable_fluid_interface.json @@ -0,0 +1,18 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + " B ", + " I " + ], + "key": { + "I": { + "item": "create:copper_casing" + }, + "B": { + "item": "create:andesite_funnel" + } + }, + "result": { + "item": "create:portable_fluid_interface" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/create/recipes/crafting/kinetics/portable_storage_interface.json b/src/generated/resources/data/create/recipes/crafting/kinetics/portable_storage_interface.json index 87f103a47..ee961eefa 100644 --- a/src/generated/resources/data/create/recipes/crafting/kinetics/portable_storage_interface.json +++ b/src/generated/resources/data/create/recipes/crafting/kinetics/portable_storage_interface.json @@ -6,7 +6,7 @@ ], "key": { "I": { - "item": "create:redstone_contact" + "item": "create:brass_casing" }, "B": { "item": "create:andesite_funnel" diff --git a/src/main/java/com/simibubi/create/AllBlockPartials.java b/src/main/java/com/simibubi/create/AllBlockPartials.java index 159010d12..d50e6dfbe 100644 --- a/src/main/java/com/simibubi/create/AllBlockPartials.java +++ b/src/main/java/com/simibubi/create/AllBlockPartials.java @@ -88,6 +88,10 @@ public class AllBlockPartials { PORTABLE_STORAGE_INTERFACE_MIDDLE = get("portable_storage_interface/block_middle"), PORTABLE_STORAGE_INTERFACE_MIDDLE_POWERED = get("portable_storage_interface/block_middle_powered"), PORTABLE_STORAGE_INTERFACE_TOP = get("portable_storage_interface/block_top"), + + PORTABLE_FLUID_INTERFACE_MIDDLE = get("portable_fluid_interface/block_middle"), + PORTABLE_FLUID_INTERFACE_MIDDLE_POWERED = get("portable_fluid_interface/block_middle_powered"), + PORTABLE_FLUID_INTERFACE_TOP = get("portable_fluid_interface/block_top"), ARM_COG = get("mechanical_arm/cog"), ARM_BASE = get("mechanical_arm/base"), ARM_LOWER_BODY = get("mechanical_arm/lower_body"), ARM_UPPER_BODY = get("mechanical_arm/upper_body"), diff --git a/src/main/java/com/simibubi/create/AllBlocks.java b/src/main/java/com/simibubi/create/AllBlocks.java index 509b4a2e4..83755b480 100644 --- a/src/main/java/com/simibubi/create/AllBlocks.java +++ b/src/main/java/com/simibubi/create/AllBlocks.java @@ -46,10 +46,10 @@ 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.structureMovement.bearing.StabilizedBearingMovementBehaviour; 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; +import com.simibubi.create.content.contraptions.components.structureMovement.bearing.StabilizedBearingMovementBehaviour; import com.simibubi.create.content.contraptions.components.structureMovement.bearing.WindmillBearingBlock; import com.simibubi.create.content.contraptions.components.structureMovement.chassis.LinearChassisBlock; import com.simibubi.create.content.contraptions.components.structureMovement.chassis.LinearChassisBlock.ChassisCTBehaviour; @@ -565,7 +565,7 @@ public class AllBlocks { .register(); public static final BlockEntry[] DYED_VALVE_HANDLES = new BlockEntry[DyeColor.values().length]; - + static { for (DyeColor colour : DyeColor.values()) { String colourName = colour.getString(); @@ -632,6 +632,15 @@ public class AllBlocks { .transform(customItemModel()) .register(); + public static final BlockEntry PORTABLE_FLUID_INTERFACE = + REGISTRATE.block("portable_fluid_interface", PortableStorageInterfaceBlock::forFluids) + .initialProperties(SharedProperties::softMetal) + .blockstate((c, p) -> p.directionalBlock(c.get(), AssetLookup.partialBaseModel(c, p))) + .onRegister(addMovementBehaviour(new PortableStorageInterfaceMovement())) + .item() + .transform(customItemModel()) + .register(); + // Contraptions public static final BlockEntry MECHANICAL_PISTON = @@ -792,7 +801,7 @@ public class AllBlocks { .register(); public static final BlockEntry PORTABLE_STORAGE_INTERFACE = - REGISTRATE.block("portable_storage_interface", PortableStorageInterfaceBlock::new) + REGISTRATE.block("portable_storage_interface", PortableStorageInterfaceBlock::forItems) .initialProperties(SharedProperties::stone) .blockstate((c, p) -> p.directionalBlock(c.get(), AssetLookup.partialBaseModel(c, p))) .onRegister(addMovementBehaviour(new PortableStorageInterfaceMovement())) @@ -1204,6 +1213,8 @@ public class AllBlocks { public static final BlockEntry BRASS_BLOCK = REGISTRATE.block("brass_block", p -> new Block(p)) .initialProperties(() -> Blocks.IRON_BLOCK) + .blockstate((c, p) -> p.simpleBlock(c.get(), p.models() + .cubeAll(c.getName(), p.modLoc("block/brass_storage_block")))) .tag(Tags.Blocks.STORAGE_BLOCKS) .tag(AllBlockTags.BEACON_BASE_BLOCKS.tag) .transform(tagBlockAndItem("storage_blocks/brass")) diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index 8d24eb6bc..aba35da40 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -5,8 +5,9 @@ import com.simibubi.create.content.contraptions.components.actors.DrillRenderer; import com.simibubi.create.content.contraptions.components.actors.DrillTileEntity; import com.simibubi.create.content.contraptions.components.actors.HarvesterRenderer; import com.simibubi.create.content.contraptions.components.actors.HarvesterTileEntity; +import com.simibubi.create.content.contraptions.components.actors.PortableFluidInterfaceTileEntity; +import com.simibubi.create.content.contraptions.components.actors.PortableItemInterfaceTileEntity; import com.simibubi.create.content.contraptions.components.actors.PortableStorageInterfaceRenderer; -import com.simibubi.create.content.contraptions.components.actors.PortableStorageInterfaceTileEntity; import com.simibubi.create.content.contraptions.components.clock.CuckooClockRenderer; import com.simibubi.create.content.contraptions.components.clock.CuckooClockTileEntity; import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterRenderer; @@ -349,13 +350,19 @@ public class AllTileEntities { .renderer(() -> HarvesterRenderer::new) .register(); - public static final TileEntityEntry PORTABLE_STORAGE_INTERFACE = + public static final TileEntityEntry PORTABLE_STORAGE_INTERFACE = Create.registrate() - .tileEntity("portable_storage_interface", PortableStorageInterfaceTileEntity::new) + .tileEntity("portable_storage_interface", PortableItemInterfaceTileEntity::new) .validBlocks(AllBlocks.PORTABLE_STORAGE_INTERFACE) .renderer(() -> PortableStorageInterfaceRenderer::new) .register(); + public static final TileEntityEntry PORTABLE_FLUID_INTERFACE = Create.registrate() + .tileEntity("portable_fluid_interface", PortableFluidInterfaceTileEntity::new) + .validBlocks(AllBlocks.PORTABLE_FLUID_INTERFACE) + .renderer(() -> PortableStorageInterfaceRenderer::new) + .register(); + public static final TileEntityEntry FLYWHEEL = Create.registrate() .tileEntity("flywheel", FlywheelTileEntity::new) .validBlocks(AllBlocks.FLYWHEEL) diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java index cec898c2b..f3ca34726 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java @@ -1,12 +1,5 @@ package com.simibubi.create.content.contraptions.base; -import static net.minecraft.util.text.TextFormatting.GOLD; -import static net.minecraft.util.text.TextFormatting.GRAY; - -import java.util.List; - -import javax.annotation.Nullable; - import com.simibubi.create.Create; import com.simibubi.create.content.contraptions.KineticNetwork; import com.simibubi.create.content.contraptions.RotationPropagator; @@ -20,7 +13,6 @@ import com.simibubi.create.foundation.item.TooltipHelper; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.utility.Lang; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.client.resources.I18n; @@ -37,6 +29,12 @@ import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; +import javax.annotation.Nullable; +import java.util.List; + +import static net.minecraft.util.text.TextFormatting.GOLD; +import static net.minecraft.util.text.TextFormatting.GRAY; + public abstract class KineticTileEntity extends SmartTileEntity implements ITickableTileEntity, IHaveGoggleInformation, IHaveHoveringInformation { @@ -354,13 +352,12 @@ public abstract class KineticTileEntity extends SmartTileEntity return; TileEntity tileEntityIn = world.getTileEntity(pos); + BlockState currentState = world.getBlockState(pos); boolean isKinetic = tileEntityIn instanceof KineticTileEntity; - if (tileEntityIn == null) + if (currentState == state) return; - if (tileEntityIn.getBlockState() == state) - return; - if (!isKinetic) { + if (tileEntityIn == null || !isKinetic) { world.setBlockState(pos, state, 3); return; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableFluidInterfaceTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableFluidInterfaceTileEntity.java new file mode 100644 index 000000000..981213c94 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableFluidInterfaceTileEntity.java @@ -0,0 +1,113 @@ +package com.simibubi.create.content.contraptions.components.actors; + +import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; + +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fluids.capability.templates.FluidTank; + +public class PortableFluidInterfaceTileEntity extends PortableStorageInterfaceTileEntity { + + protected LazyOptional capability; + + public PortableFluidInterfaceTileEntity(TileEntityType tileEntityTypeIn) { + super(tileEntityTypeIn); + capability = createEmptyHandler(); + } + + @Override + public void startTransferringTo(Contraption contraption, float distance) { + LazyOptional oldcap = capability; + capability = LazyOptional.of(() -> new InterfaceFluidHandler(contraption.fluidInventory)); + oldcap.invalidate(); + super.startTransferringTo(contraption, distance); + } + + @Override + protected void invalidateCapability() { + capability.invalidate(); + } + + @Override + protected void stopTransferring() { + LazyOptional oldcap = capability; + capability = createEmptyHandler(); + oldcap.invalidate(); + } + + private LazyOptional createEmptyHandler() { + return LazyOptional.of(() -> new InterfaceFluidHandler(new FluidTank(0))); + } + + @Override + public LazyOptional getCapability(Capability cap, Direction side) { + if (isFluidHandlerCap(cap)) + return capability.cast(); + return super.getCapability(cap, side); + } + + class InterfaceFluidHandler implements IFluidHandler { + + private IFluidHandler wrapped; + + public InterfaceFluidHandler(IFluidHandler wrapped) { + this.wrapped = wrapped; + } + + @Override + public int getTanks() { + return wrapped.getTanks(); + } + + @Override + public FluidStack getFluidInTank(int tank) { + return wrapped.getFluidInTank(tank); + } + + @Override + public int getTankCapacity(int tank) { + return wrapped.getTankCapacity(tank); + } + + @Override + public boolean isFluidValid(int tank, FluidStack stack) { + return wrapped.isFluidValid(tank, stack); + } + + @Override + public int fill(FluidStack resource, FluidAction action) { + if (!isConnected()) + return 0; + int fill = wrapped.fill(resource, action); + if (fill > 0 && action.execute()) + onContentTransferred(); + return fill; + } + + @Override + public FluidStack drain(FluidStack resource, FluidAction action) { + if (!isConnected()) + return FluidStack.EMPTY; + FluidStack drain = wrapped.drain(resource, action); + if (!drain.isEmpty() && action.execute()) + onContentTransferred(); + return drain; + } + + @Override + public FluidStack drain(int maxDrain, FluidAction action) { + if (!isConnected()) + return FluidStack.EMPTY; + FluidStack drain = wrapped.drain(maxDrain, action); + if (!drain.isEmpty() && (action.execute() || drain.getAmount() == 1)) + onContentTransferred(); + return drain; + } + + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableItemInterfaceTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableItemInterfaceTileEntity.java new file mode 100644 index 000000000..1642a30ed --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableItemInterfaceTileEntity.java @@ -0,0 +1,78 @@ +package com.simibubi.create.content.contraptions.components.actors; + +import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; +import com.simibubi.create.foundation.item.ItemHandlerWrapper; + +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.items.IItemHandlerModifiable; +import net.minecraftforge.items.ItemStackHandler; + +public class PortableItemInterfaceTileEntity extends PortableStorageInterfaceTileEntity { + + protected LazyOptional capability; + + public PortableItemInterfaceTileEntity(TileEntityType tileEntityTypeIn) { + super(tileEntityTypeIn); + capability = LazyOptional.empty(); + } + + @Override + public void startTransferringTo(Contraption contraption, float distance) { + LazyOptional oldCap = capability; + capability = LazyOptional.of(() -> new InterfaceItemHandler(contraption.inventory)); + oldCap.invalidate(); + super.startTransferringTo(contraption, distance); + } + + @Override + protected void stopTransferring() { + LazyOptional oldCap = capability; + capability = LazyOptional.of(() -> new InterfaceItemHandler(new ItemStackHandler(0))); + oldCap.invalidate(); + } + + @Override + protected void invalidateCapability() { + capability.invalidate(); + } + + @Override + public LazyOptional getCapability(Capability cap, Direction side) { + if (isItemHandlerCap(cap)) + return capability.cast(); + return super.getCapability(cap, side); + } + + class InterfaceItemHandler extends ItemHandlerWrapper { + + public InterfaceItemHandler(IItemHandlerModifiable wrapped) { + super(wrapped); + } + + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + if (!isConnected()) + return ItemStack.EMPTY; + ItemStack extractItem = super.extractItem(slot, amount, simulate); + if (!simulate && !extractItem.isEmpty()) + onContentTransferred(); + return extractItem; + } + + @Override + public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { + if (!isConnected()) + return stack; + ItemStack insertItem = super.insertItem(slot, stack, simulate); + if (!simulate && !insertItem.equals(stack, false)) + onContentTransferred(); + return insertItem; + } + + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceBlock.java index 078b33117..7afae49c4 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceBlock.java @@ -8,6 +8,7 @@ import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.block.ProperDirectionalBlock; import mcp.MethodsReturnNonnullByDefault; +import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.item.BlockItemUseContext; import net.minecraft.tileentity.TileEntity; @@ -22,8 +23,19 @@ import net.minecraft.world.World; public class PortableStorageInterfaceBlock extends ProperDirectionalBlock implements ITE { - public PortableStorageInterfaceBlock(Properties p_i48415_1_) { + boolean fluids; + + public static PortableStorageInterfaceBlock forItems(Properties p_i48415_1_) { + return new PortableStorageInterfaceBlock(p_i48415_1_, false); + } + + public static PortableStorageInterfaceBlock forFluids(Properties p_i48415_1_) { + return new PortableStorageInterfaceBlock(p_i48415_1_, true); + } + + private PortableStorageInterfaceBlock(Properties p_i48415_1_, boolean fluids) { super(p_i48415_1_); + this.fluids = fluids; } @Override @@ -33,7 +45,14 @@ public class PortableStorageInterfaceBlock extends ProperDirectionalBlock @Override public TileEntity createTileEntity(BlockState state, IBlockReader world) { - return AllTileEntities.PORTABLE_STORAGE_INTERFACE.create(); + return (fluids ? AllTileEntities.PORTABLE_FLUID_INTERFACE : AllTileEntities.PORTABLE_STORAGE_INTERFACE) + .create(); + } + + @Override + public void neighborChanged(BlockState state, World world, BlockPos pos, Block p_220069_4_, BlockPos p_220069_5_, + boolean p_220069_6_) { + withTileEntityDo(world, pos, PortableStorageInterfaceTileEntity::neighbourChanged); } @Override @@ -54,11 +73,8 @@ public class PortableStorageInterfaceBlock extends ProperDirectionalBlock @Override public int getComparatorInputOverride(BlockState blockState, World worldIn, BlockPos pos) { - try { - return getTileEntity(worldIn, pos).isConnected() ? 15 : 0; - } catch (TileEntityException e) { - } - return 0; + return getTileEntityOptional(worldIn, pos).map(te -> te.isConnected() ? 15 : 0) + .orElse(0); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceMovement.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceMovement.java index ec5f06fa9..62fef4898 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceMovement.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceMovement.java @@ -3,7 +3,6 @@ package com.simibubi.create.content.contraptions.components.actors; import java.util.Optional; import com.mojang.blaze3d.matrix.MatrixStack; -import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; import com.simibubi.create.foundation.utility.VecHelper; @@ -50,11 +49,12 @@ public class PortableStorageInterfaceMovement extends MovementBehaviour { return false; Direction currentFacing = currentFacingIfValid.get(); - PortableStorageInterfaceTileEntity psi = findStationaryInterface(context.world, pos, currentFacing); + PortableStorageInterfaceTileEntity psi = + findStationaryInterface(context.world, pos, context.state, currentFacing); if (psi == null) return false; - if (psi.isTransferring() && !context.world.isRemote) + if ((psi.isTransferring() || psi.isPowered()) && !context.world.isRemote) return false; context.data.put(_workingPos_, NBTUtil.writeBlockPos(psi.getPos())); if (!context.world.isRemote) { @@ -94,7 +94,7 @@ public class PortableStorageInterfaceMovement extends MovementBehaviour { return; PortableStorageInterfaceTileEntity stationaryInterface = - getStationaryInterfaceAt(context.world, pos, currentFacingIfValid.get()); + getStationaryInterfaceAt(context.world, pos, context.state, currentFacingIfValid.get()); if (stationaryInterface == null || !stationaryInterface.isTransferring()) { reset(context); return; @@ -112,10 +112,11 @@ public class PortableStorageInterfaceMovement extends MovementBehaviour { context.stall = false; } - private PortableStorageInterfaceTileEntity findStationaryInterface(World world, BlockPos pos, Direction facing) { + private PortableStorageInterfaceTileEntity findStationaryInterface(World world, BlockPos pos, BlockState state, + Direction facing) { for (int i = 0; i < 2; i++) { PortableStorageInterfaceTileEntity interfaceAt = - getStationaryInterfaceAt(world, pos.offset(facing, i), facing); + getStationaryInterfaceAt(world, pos.offset(facing, i), state, facing); if (interfaceAt == null) continue; return interfaceAt; @@ -123,12 +124,13 @@ public class PortableStorageInterfaceMovement extends MovementBehaviour { return null; } - private PortableStorageInterfaceTileEntity getStationaryInterfaceAt(World world, BlockPos pos, Direction facing) { + private PortableStorageInterfaceTileEntity getStationaryInterfaceAt(World world, BlockPos pos, BlockState state, + Direction facing) { TileEntity te = world.getTileEntity(pos); if (!(te instanceof PortableStorageInterfaceTileEntity)) return null; BlockState blockState = world.getBlockState(pos); - if (!AllBlocks.PORTABLE_STORAGE_INTERFACE.has(blockState)) + if (blockState.getBlock() != state.getBlock()) return null; if (blockState.get(PortableStorageInterfaceBlock.FACING) != facing.getOpposite()) return null; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceRenderer.java index 9efa6b692..c45de1c3f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceRenderer.java @@ -5,6 +5,7 @@ import java.util.function.Consumer; import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.vertex.IVertexBuilder; import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; import com.simibubi.create.foundation.utility.AngleHelper; @@ -33,7 +34,8 @@ public class PortableStorageInterfaceRenderer extends SafeTileEntityRenderer sbb.light(light).renderInto(ms, vb), ms); + render(blockState, progress, te.isConnected(), sbb -> sbb.light(light) + .renderInto(ms, vb), ms); } public static void renderInContraption(MovementContext context, MatrixStack ms, MatrixStack msLocal, @@ -43,14 +45,14 @@ public class PortableStorageInterfaceRenderer extends SafeTileEntityRenderer sbb.light(msLocal.peek() .getModel()) .renderInto(ms, vb), ms, msLocal); @@ -77,10 +79,8 @@ public class PortableStorageInterfaceRenderer extends SafeTileEntityRenderer capability; protected LerpedFloat connectionAnimation; + protected boolean powered; public PortableStorageInterfaceTileEntity(TileEntityType tileEntityTypeIn) { super(tileEntityTypeIn); transferTimer = 0; - capability = LazyOptional.empty(); - connectionAnimation = LerpedFloat.linear().startWithValue(0); + connectionAnimation = LerpedFloat.linear() + .startWithValue(0); + powered = false; } public void startTransferringTo(Contraption contraption, float distance) { - capability.invalidate(); - capability = LazyOptional.of(() -> new InterfaceItemHandler(contraption.inventory)); this.distance = distance; startConnecting(); notifyUpdate(); } + protected abstract void stopTransferring(); + + protected abstract void invalidateCapability(); + @Override public void tick() { super.tick(); boolean wasConnected = isConnected(); - + if (transferTimer > 0) { transferTimer--; - if (transferTimer == 0) - capability.invalidate(); + if (transferTimer == 0 || powered) + stopTransferring(); } - + boolean isConnected = isConnected(); if (wasConnected != isConnected && !world.isRemote) markDirty(); - + float progress = 0; int timeUnit = getTransferTimeout() / 2; if (isConnected) @@ -69,21 +66,41 @@ public class PortableStorageInterfaceTileEntity extends SmartTileEntity { progress = MathHelper.lerp(transferTimer / (float) timeUnit, 0, 1); connectionAnimation.setValue(progress); } - + + @Override + public void remove() { + super.remove(); + invalidateCapability(); + } + @Override protected void fromTag(BlockState state, CompoundNBT compound, boolean clientPacket) { super.fromTag(state, compound, clientPacket); transferTimer = compound.getInt("Timer"); distance = compound.getFloat("Distance"); + powered = compound.getBoolean("Powered"); } - + @Override protected void write(CompoundNBT compound, boolean clientPacket) { super.write(compound, clientPacket); compound.putInt("Timer", transferTimer); compound.putFloat("Distance", distance); + compound.putBoolean("Powered", powered); + } + + public void neighbourChanged() { + boolean isBlockPowered = world.isBlockPowered(pos); + if (isBlockPowered == powered) + return; + powered = isBlockPowered; + sendData(); } + public boolean isPowered() { + return powered; + } + @Override @OnlyIn(Dist.CLIENT) public AxisAlignedBB getRenderBoundingBox() { @@ -93,31 +110,24 @@ public class PortableStorageInterfaceTileEntity extends SmartTileEntity { public boolean isTransferring() { return transferTimer != 0; } - + boolean isConnected() { int timeUnit = getTransferTimeout() / 2; return transferTimer >= timeUnit && transferTimer <= timeUnit * 3; } - + float getExtensionDistance(float partialTicks) { return connectionAnimation.getValue(partialTicks) * distance / 2; } - + float getConnectionDistance() { return distance; } - @Override - public LazyOptional getCapability(Capability cap, Direction side) { - if (isItemHandlerCap(cap)) - return capability.cast(); - return super.getCapability(cap, side); - } - public void startConnecting() { transferTimer = getTransferTimeout() * 2; } - + public void onContentTransferred() { int timeUnit = getTransferTimeout() / 2; transferTimer = timeUnit * 3; @@ -131,32 +141,4 @@ public class PortableStorageInterfaceTileEntity extends SmartTileEntity { @Override public void addBehaviours(List behaviours) {} - class InterfaceItemHandler extends ItemHandlerWrapper { - - public InterfaceItemHandler(IItemHandlerModifiable wrapped) { - super(wrapped); - } - - @Override - public ItemStack extractItem(int slot, int amount, boolean simulate) { - if (!isConnected()) - return ItemStack.EMPTY; - ItemStack extractItem = super.extractItem(slot, amount, simulate); - if (!simulate && !extractItem.isEmpty()) - onContentTransferred(); - return extractItem; - } - - @Override - public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { - if (!isConnected()) - return stack; - ItemStack insertItem = super.insertItem(slot, stack, simulate); - if (!simulate && !insertItem.equals(stack, false)) - onContentTransferred(); - return insertItem; - } - - } - } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/NozzleBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/NozzleBlock.java index 34fd10d4e..2c0a842ce 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/NozzleBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/NozzleBlock.java @@ -2,9 +2,7 @@ package com.simibubi.create.content.contraptions.components.fan; import com.simibubi.create.AllShapes; import com.simibubi.create.AllTileEntities; -import com.simibubi.create.content.contraptions.wrench.IWrenchable; import com.simibubi.create.foundation.block.ProperDirectionalBlock; - import mcp.MethodsReturnNonnullByDefault; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -24,7 +22,7 @@ import javax.annotation.ParametersAreNonnullByDefault; @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault -public class NozzleBlock extends ProperDirectionalBlock implements IWrenchable { +public class NozzleBlock extends ProperDirectionalBlock { public NozzleBlock(Properties p_i48415_1_) { super(p_i48415_1_); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AbstractContraptionEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AbstractContraptionEntity.java index b411b10d2..3021cbf48 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AbstractContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AbstractContraptionEntity.java @@ -1,10 +1,13 @@ package com.simibubi.create.content.contraptions.components.structureMovement; -import java.util.ArrayList; +import java.util.IdentityHashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Map.Entry; import java.util.UUID; +import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.lang3.tuple.MutablePair; import com.simibubi.create.AllMovementBehaviours; @@ -49,7 +52,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit private static final DataParameter STALLED = EntityDataManager.createKey(AbstractContraptionEntity.class, DataSerializers.BOOLEAN); - public final List collidingEntities = new ArrayList<>(); + public final Map collidingEntities; protected Contraption contraption; protected boolean initialized; @@ -58,6 +61,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit public AbstractContraptionEntity(EntityType entityTypeIn, World worldIn) { super(entityTypeIn, worldIn); prevPosInvalid = true; + collidingEntities = new IdentityHashMap<>(); } protected void setContraption(Contraption contraption) { @@ -205,6 +209,13 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit return; } + for (Iterator> iterator = collidingEntities.entrySet() + .iterator(); iterator.hasNext();) + if (iterator.next() + .getValue() + .incrementAndGet() > 3) + iterator.remove(); + prevPosX = getX(); prevPosY = getY(); prevPosZ = getZ(); @@ -212,6 +223,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit if (!initialized) contraptionInitialize(); + contraption.onEntityTick(world); tickContraption(); super.tick(); } @@ -340,22 +352,6 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit this.dataManager.register(STALLED, false); } - @Override - protected void readAdditional(CompoundNBT compound) { - initialized = compound.getBoolean("Initialized"); - contraption = Contraption.fromNBT(world, compound.getCompound("Contraption")); - contraption.entity = this; - dataManager.set(STALLED, compound.getBoolean("Stalled")); - } - - @Override - protected void writeAdditional(CompoundNBT compound) { - if (contraption != null) - compound.put("Contraption", contraption.writeNBT()); - compound.putBoolean("Stalled", isStalled()); - compound.putBoolean("Initialized", initialized); - } - @Override public IPacket createSpawnPacket() { return NetworkHooks.getEntitySpawningPacket(this); @@ -364,13 +360,37 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit @Override public void writeSpawnData(PacketBuffer buffer) { CompoundNBT compound = new CompoundNBT(); - writeAdditional(compound); + writeAdditional(compound, true); buffer.writeCompoundTag(compound); } + + @Override + protected final void writeAdditional(CompoundNBT compound) { + writeAdditional(compound, false); + } + + protected void writeAdditional(CompoundNBT compound, boolean spawnPacket) { + if (contraption != null) + compound.put("Contraption", contraption.writeNBT(spawnPacket)); + compound.putBoolean("Stalled", isStalled()); + compound.putBoolean("Initialized", initialized); + } @Override public void readSpawnData(PacketBuffer additionalData) { - readAdditional(additionalData.readCompoundTag()); + readAdditional(additionalData.readCompoundTag(), true); + } + + @Override + protected final void readAdditional(CompoundNBT compound) { + readAdditional(compound, false); + } + + protected void readAdditional(CompoundNBT compound, boolean spawnData) { + initialized = compound.getBoolean("Initialized"); + contraption = Contraption.fromNBT(world, compound.getCompound("Contraption"), spawnData); + contraption.entity = this; + dataManager.set(STALLED, compound.getBoolean("Stalled")); } public void disassemble() { @@ -378,8 +398,13 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit return; if (contraption == null) return; + remove(); + StructureTransform transform = makeStructureTransform(); + AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> this), + new ContraptionDisassemblyPacket(this.getEntityId(), transform)); + contraption.addBlocksToWorld(world, transform); contraption.addPassengersToWorld(world, transform, getPassengers()); @@ -396,14 +421,17 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit } removePassengers(); + moveCollidedEntitiesOnDisassembly(transform); + } - for (Entity entity : collidingEntities) { - Vector3d positionVec = getPositionVec(); - Vector3d localVec = entity.getPositionVec() - .subtract(positionVec); - localVec = reverseRotation(localVec, 1); + private void moveCollidedEntitiesOnDisassembly(StructureTransform transform) { + for (Entity entity : collidingEntities.keySet()) { + Vector3d localVec = toLocalVector(entity.getPositionVec(), 0); Vector3d transformed = transform.apply(localVec); - entity.setPositionAndUpdate(transformed.x, transformed.y, transformed.z); + if (world.isRemote) + entity.setPosition(transformed.x, transformed.y + 1 / 16f, transformed.z); + else + entity.setPositionAndUpdate(transformed.x, transformed.y + 1 / 16f, transformed.z); } } @@ -449,6 +477,15 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit ce.handleStallInformation(packet.x, packet.y, packet.z, packet.angle); } + @OnlyIn(Dist.CLIENT) + static void handleDisassemblyPacket(ContraptionDisassemblyPacket packet) { + Entity entity = Minecraft.getInstance().world.getEntityByID(packet.entityID); + if (!(entity instanceof AbstractContraptionEntity)) + return; + AbstractContraptionEntity ce = (AbstractContraptionEntity) entity; + ce.moveCollidedEntitiesOnDisassembly(packet.transform); + } + protected abstract float getStalledAngle(); protected abstract void handleStallInformation(float x, float y, float z, float angle); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/BlockMovementTraits.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/BlockMovementTraits.java index b7c992a57..d2553ee06 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/BlockMovementTraits.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/BlockMovementTraits.java @@ -19,6 +19,8 @@ import com.simibubi.create.content.contraptions.components.structureMovement.pis import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.PistonState; import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyBlock; import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyTileEntity; +import com.simibubi.create.content.contraptions.fluids.tank.FluidTankBlock; +import com.simibubi.create.content.contraptions.fluids.tank.FluidTankConnectivityHandler; import com.simibubi.create.content.logistics.block.redstone.RedstoneLinkBlock; import com.simibubi.create.foundation.utility.BlockHelper; @@ -46,6 +48,7 @@ import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockReader; import net.minecraft.world.World; public class BlockMovementTraits { @@ -56,9 +59,11 @@ public class BlockMovementTraits { return true; if (state.getBlock() instanceof FenceGateBlock) return true; - if (state.getMaterial().isReplaceable()) + if (state.getMaterial() + .isReplaceable()) return false; - if (state.getCollisionShape(world, pos).isEmpty()) + if (state.getCollisionShape(world, pos) + .isEmpty()) return false; return true; } @@ -105,7 +110,7 @@ public class BlockMovementTraits { Block block = state.getBlock(); if (BlockHelper.hasBlockStateProperty(state, BlockStateProperties.HANGING)) return true; - + if (block instanceof LadderBlock) return true; if (block instanceof TorchBlock) @@ -130,7 +135,8 @@ public class BlockMovementTraits { /** * Attached blocks will move if blocks they are attached to are moved */ - public static boolean isBlockAttachedTowards(BlockState state, Direction direction) { + public static boolean isBlockAttachedTowards(IBlockReader world, BlockPos pos, BlockState state, + Direction direction) { Block block = state.getBlock(); if (block instanceof LadderBlock) return state.get(LadderBlock.FACING) == direction.getOpposite(); @@ -168,23 +174,30 @@ public class BlockMovementTraits { if (block instanceof AbstractRailBlock) return direction == Direction.DOWN; if (block instanceof AttachedActorBlock) - return direction == state.get(HarvesterBlock.HORIZONTAL_FACING).getOpposite(); + return direction == state.get(HarvesterBlock.HORIZONTAL_FACING) + .getOpposite(); if (block instanceof HandCrankBlock) - return direction == state.get(HandCrankBlock.FACING).getOpposite(); + return direction == state.get(HandCrankBlock.FACING) + .getOpposite(); if (block instanceof NozzleBlock) - return direction == state.get(NozzleBlock.FACING).getOpposite(); + return direction == state.get(NozzleBlock.FACING) + .getOpposite(); if (block instanceof EngineBlock) - return direction == state.get(EngineBlock.HORIZONTAL_FACING).getOpposite(); + return direction == state.get(EngineBlock.HORIZONTAL_FACING) + .getOpposite(); if (block instanceof BellBlock) { BellAttachment attachment = state.get(BlockStateProperties.BELL_ATTACHMENT); - if (attachment == BellAttachment.FLOOR) + if (attachment == BellAttachment.FLOOR) return direction == Direction.DOWN; - if (attachment == BellAttachment.CEILING) + if (attachment == BellAttachment.CEILING) return direction == Direction.UP; return direction == state.get(HorizontalBlock.HORIZONTAL_FACING); } if (state.getBlock() instanceof SailBlock) - return direction.getAxis() != state.get(SailBlock.FACING).getAxis(); + return direction.getAxis() != state.get(SailBlock.FACING) + .getAxis(); + if (state.getBlock() instanceof FluidTankBlock) + return FluidTankConnectivityHandler.isConnected(world, pos, pos.offset(direction)); return false; } @@ -210,8 +223,9 @@ public class BlockMovementTraits { if (state.getBlock() instanceof CarpetBlock) return facing == Direction.UP; if (state.getBlock() instanceof SailBlock) - return facing.getAxis() == state.get(SailBlock.FACING).getAxis(); + return facing.getAxis() == state.get(SailBlock.FACING) + .getAxis(); return isBrittle(state); } - + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java index 5068dc21f..d0d2bd2f7 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java @@ -39,10 +39,12 @@ import com.simibubi.create.content.contraptions.components.structureMovement.pul import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyBlock.MagnetBlock; import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyBlock.RopeBlock; import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyTileEntity; +import com.simibubi.create.content.contraptions.fluids.tank.FluidTankTileEntity; import com.simibubi.create.content.contraptions.relays.belt.BeltBlock; import com.simibubi.create.content.logistics.block.inventories.AdjustableCrateBlock; import com.simibubi.create.content.logistics.block.redstone.RedstoneContactBlock; import com.simibubi.create.foundation.config.AllConfigs; +import com.simibubi.create.foundation.fluid.CombinedTankWrapper; import com.simibubi.create.foundation.utility.BlockFace; import com.simibubi.create.foundation.utility.BlockHelper; import com.simibubi.create.foundation.utility.Iterate; @@ -81,6 +83,10 @@ import net.minecraft.world.World; import net.minecraft.world.gen.feature.template.Template.BlockInfo; import net.minecraftforge.common.util.Constants.BlockFlags; import net.minecraftforge.common.util.Constants.NBT; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fluids.capability.templates.FluidTank; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.wrapper.CombinedInvWrapper; @@ -88,12 +94,14 @@ public abstract class Contraption { public AbstractContraptionEntity entity; public CombinedInvWrapper inventory; + public CombinedTankWrapper fluidInventory; public AxisAlignedBB bounds; public BlockPos anchor; public boolean stalled; protected Map blocks; protected Map storage; + protected Map fluidStorage; protected List> actors; protected Set> superglue; protected List seats; @@ -105,7 +113,7 @@ public abstract class Contraption { private List pendingSubContraptions; // Client - public List renderedTileEntities; + public Map renderedTileEntities; public Contraption() { blocks = new HashMap<>(); @@ -114,9 +122,10 @@ public abstract class Contraption { actors = new ArrayList<>(); superglue = new HashSet<>(); seatMapping = new HashMap<>(); + fluidStorage = new HashMap<>(); glueToRemove = new ArrayList<>(); initialPassengers = new HashMap<>(); - renderedTileEntities = new ArrayList<>(); + renderedTileEntities = new HashMap<>(); pendingSubContraptions = new ArrayList<>(); stabilizedSubContraptions = new HashMap<>(); } @@ -140,10 +149,10 @@ public abstract class Contraption { return true; } - public static Contraption fromNBT(World world, CompoundNBT nbt) { + public static Contraption fromNBT(World world, CompoundNBT nbt, boolean spawnData) { String type = nbt.getString("Type"); Contraption contraption = AllContraptionTypes.fromType(type); - contraption.readNBT(world, nbt); + contraption.readNBT(world, nbt, spawnData); return contraption; } @@ -195,6 +204,13 @@ public abstract class Contraption { .map(MountedStorage::getItemHandler) .collect(Collectors.toList()); inventory = new CombinedInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class)); + + List fluidHandlers = fluidStorage.values() + .stream() + .map(MountedFluidStorage::getFluidHandler) + .collect(Collectors.toList()); + fluidInventory = new CombinedTankWrapper( + Arrays.copyOf(fluidHandlers.toArray(), fluidHandlers.size(), IFluidHandler[].class)); } public void onEntityInitialize(World world, AbstractContraptionEntity contraptionEntity) { @@ -218,6 +234,10 @@ public abstract class Contraption { } } + public void onEntityTick(World world) { + fluidStorage.forEach((pos, mfs) -> mfs.tick(entity, pos, world.isRemote)); + } + protected boolean moveBlock(World world, BlockPos pos, Direction forcedDirection, List frontier, Set visited) { visited.add(pos); @@ -289,7 +309,7 @@ public abstract class Contraption { boolean wasVisited = visited.contains(offsetPos); boolean faceHasGlue = superglue.containsKey(offset); boolean blockAttachedTowardsFace = - BlockMovementTraits.isBlockAttachedTowards(blockState, offset.getOpposite()); + BlockMovementTraits.isBlockAttachedTowards(world, offsetPos, blockState, offset.getOpposite()); boolean brittle = BlockMovementTraits.isBrittle(blockState); if (!wasVisited && ((isSlimeBlock && !brittle) || blockAttachedTowardsFace || faceHasGlue)) @@ -449,6 +469,8 @@ public abstract class Contraption { TileEntity te = pair.getValue(); if (te != null && MountedStorage.canUseAsStorage(te)) storage.put(localPos, new MountedStorage(te)); + if (te != null && MountedFluidStorage.canUseAsStorage(te)) + fluidStorage.put(localPos, new MountedFluidStorage(te)); if (AllMovementBehaviours.contains(captured.state.getBlock())) actors.add(MutablePair.of(blockInfo, null)); } @@ -462,6 +484,11 @@ public abstract class Contraption { nbt.remove("x"); nbt.remove("y"); nbt.remove("z"); + + if (tileentity instanceof FluidTankTileEntity && nbt.contains("Controller")) + nbt.put("Controller", + NBTUtil.writeBlockPos(toLocalPos(NBTUtil.readBlockPos(nbt.getCompound("Controller"))))); + return nbt; } @@ -484,7 +511,7 @@ public abstract class Contraption { return pos.equals(anchor); } - public void readNBT(World world, CompoundNBT nbt) { + public void readNBT(World world, CompoundNBT nbt, boolean spawnData) { blocks.clear(); renderedTileEntities.clear(); @@ -523,7 +550,7 @@ public abstract class Contraption { if (te instanceof KineticTileEntity) ((KineticTileEntity) te).setSpeed(0); te.getBlockState(); - renderedTileEntities.add(te); + renderedTileEntities.put(info.pos, te); } }); @@ -555,6 +582,24 @@ public abstract class Contraption { NBTHelper.iterateCompoundList(nbt.getList("Storage", NBT.TAG_COMPOUND), c -> storage .put(NBTUtil.readBlockPos(c.getCompound("Pos")), MountedStorage.deserialize(c.getCompound("Data")))); + fluidStorage.clear(); + NBTHelper.iterateCompoundList(nbt.getList("FluidStorage", NBT.TAG_COMPOUND), c -> fluidStorage + .put(NBTUtil.readBlockPos(c.getCompound("Pos")), MountedFluidStorage.deserialize(c.getCompound("Data")))); + + if (spawnData) + fluidStorage.forEach((pos, mfs) -> { + TileEntity tileEntity = renderedTileEntities.get(pos); + if (!(tileEntity instanceof FluidTankTileEntity)) + return; + FluidTankTileEntity tank = (FluidTankTileEntity) tileEntity; + IFluidTank tankInventory = tank.getTankInventory(); + if (tankInventory instanceof FluidTank) + ((FluidTank) tankInventory).setFluid(mfs.tank.getFluid()); + tank.getFluidLevel() + .start(tank.getFillState()); + mfs.assignTileEntity(tank); + }); + IItemHandlerModifiable[] handlers = new IItemHandlerModifiable[storage.size()]; int index = 0; for (MountedStorage mountedStorage : storage.values()) @@ -568,7 +613,7 @@ public abstract class Contraption { anchor = NBTUtil.readBlockPos(nbt.getCompound("Anchor")); } - public CompoundNBT writeNBT() { + public CompoundNBT writeNBT(boolean spawnPacket) { CompoundNBT nbt = new CompoundNBT(); nbt.putString("Type", getType().id); ListNBT blocksNBT = new ListNBT(); @@ -601,14 +646,27 @@ public abstract class Contraption { } ListNBT storageNBT = new ListNBT(); - for (BlockPos pos : storage.keySet()) { + if (!spawnPacket) { + for (BlockPos pos : storage.keySet()) { + CompoundNBT c = new CompoundNBT(); + MountedStorage mountedStorage = storage.get(pos); + if (!mountedStorage.isValid()) + continue; + c.put("Pos", NBTUtil.writeBlockPos(pos)); + c.put("Data", mountedStorage.serialize()); + storageNBT.add(c); + } + } + + ListNBT fluidStorageNBT = new ListNBT(); + for (BlockPos pos : fluidStorage.keySet()) { CompoundNBT c = new CompoundNBT(); - MountedStorage mountedStorage = storage.get(pos); + MountedFluidStorage mountedStorage = fluidStorage.get(pos); if (!mountedStorage.isValid()) continue; c.put("Pos", NBTUtil.writeBlockPos(pos)); c.put("Data", mountedStorage.serialize()); - storageNBT.add(c); + fluidStorageNBT.add(c); } nbt.put("Seats", NBTHelper.writeCompoundList(getSeats(), NBTUtil::writeBlockPos)); @@ -631,6 +689,7 @@ public abstract class Contraption { nbt.put("Actors", actorsNBT); nbt.put("Superglue", superglueNBT); nbt.put("Storage", storageNBT); + nbt.put("FluidStorage", fluidStorageNBT); nbt.put("Anchor", NBTUtil.writeBlockPos(anchor)); nbt.putBoolean("Stalled", stalled); @@ -645,6 +704,8 @@ public abstract class Contraption { public void removeBlocksFromWorld(World world, BlockPos offset) { storage.values() .forEach(MountedStorage::removeStorageFromWorld); + fluidStorage.values() + .forEach(MountedFluidStorage::removeStorageFromWorld); glueToRemove.forEach(SuperGlueEntity::remove); for (boolean brittles : Iterate.trueAndFalse) { @@ -733,13 +794,22 @@ public abstract class Contraption { tag.remove("InitialOffset"); } - tileEntity.fromTag(tileEntity.getBlockState(), tag); + if (tileEntity instanceof FluidTankTileEntity && tag.contains("LastKnownPos")) + tag.put("LastKnownPos", NBTUtil.writeBlockPos(BlockPos.ZERO.down())); + + tileEntity.fromTag(block.state, tag); if (storage.containsKey(block.pos)) { MountedStorage mountedStorage = storage.get(block.pos); if (mountedStorage.isValid()) mountedStorage.addStorageToWorld(tileEntity); } + + if (fluidStorage.containsKey(block.pos)) { + MountedFluidStorage mountedStorage = fluidStorage.get(block.pos); + if (mountedStorage.isValid()) + mountedStorage.addStorageToWorld(tileEntity); + } } } } @@ -858,4 +928,10 @@ public abstract class Contraption { return actors; } + public void updateContainedFluid(BlockPos localPos, FluidStack containedFluid) { + MountedFluidStorage mountedFluidStorage = fluidStorage.get(localPos); + if (mountedFluidStorage != null) + mountedFluidStorage.updateFluid(containedFluid); + } + } \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java index db1f565e5..7b881e086 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionCollider.java @@ -8,6 +8,8 @@ import java.util.List; import java.util.stream.Stream; import org.apache.commons.lang3.mutable.MutableBoolean; +import org.apache.commons.lang3.mutable.MutableFloat; +import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.lang3.mutable.MutableObject; import com.google.common.base.Predicates; @@ -64,8 +66,6 @@ public class ContraptionCollider { if (bounds == null) return; - contraptionEntity.collidingEntities.clear(); - Vector3d contraptionPosition = contraptionEntity.getPositionVec(); Vector3d contraptionMotion = contraptionPosition.subtract(contraptionEntity.getPrevPositionVec()); Vector3d anchorVec = contraptionEntity.getAnchorVec(); @@ -122,13 +122,12 @@ public class ContraptionCollider { // Prepare entity bounds OrientedBB obb = new OrientedBB(localBB); obb.setRotation(rotationMatrix); - motion = rotationMatrix.transform(motion); motion = motion.subtract(contraptionMotion); + motion = rotationMatrix.transform(motion); MutableObject collisionResponse = new MutableObject<>(Vector3d.ZERO); - MutableObject allowedMotion = new MutableObject<>(motion); - MutableBoolean futureCollision = new MutableBoolean(false); MutableBoolean surfaceCollision = new MutableBoolean(false); + MutableFloat temporalResponse = new MutableFloat(1); Vector3d obbCenter = obb.getCenter(); // Apply separation maths @@ -139,21 +138,22 @@ public class ContraptionCollider { boolean doHorizontalPass = !rotation.hasVerticalRotation(); for (boolean horizontalPass : Iterate.trueAndFalse) { + boolean verticalPass = !horizontalPass || !doHorizontalPass; for (AxisAlignedBB bb : bbs) { Vector3d currentResponse = collisionResponse.getValue(); obb.setCenter(obbCenter.add(currentResponse)); - ContinuousSeparationManifold intersect = obb.intersect(bb, allowedMotion.getValue()); + ContinuousSeparationManifold intersect = obb.intersect(bb, motion); if (intersect == null) continue; - if ((!horizontalPass || !doHorizontalPass) && surfaceCollision.isFalse()) + if (verticalPass && surfaceCollision.isFalse()) surfaceCollision.setValue(intersect.isSurfaceCollision()); double timeOfImpact = intersect.getTimeOfImpact(); if (timeOfImpact > 0 && timeOfImpact < 1) { - futureCollision.setTrue(); - allowedMotion.setValue(intersect.getAllowedMotion(allowedMotion.getValue())); + if (temporalResponse.getValue() > timeOfImpact) + temporalResponse.setValue(timeOfImpact); continue; } @@ -162,28 +162,28 @@ public class ContraptionCollider { collisionResponse.setValue(currentResponse.add(separation)); } - if (!horizontalPass || !doHorizontalPass) + if (verticalPass) break; - boolean noVerticalMotionResponse = allowedMotion.getValue().y == motion.y; + boolean noVerticalMotionResponse = temporalResponse.getValue() == 1; boolean noVerticalCollision = collisionResponse.getValue().y == 0; if (noVerticalCollision && noVerticalMotionResponse) break; // Re-run collisions with horizontal offset collisionResponse.setValue(collisionResponse.getValue() - .mul(1, 0, 1)); - allowedMotion.setValue(allowedMotion.getValue() - .mul(1, 0, 1) - .add(0, motion.y, 0)); + .mul(129 / 128f, 0, 129 / 128f)); continue; } // Resolve collision Vector3d entityMotion = entity.getMotion(); Vector3d totalResponse = collisionResponse.getValue(); - Vector3d motionResponse = allowedMotion.getValue(); boolean hardCollision = !totalResponse.equals(Vector3d.ZERO); + boolean temporalCollision = temporalResponse.getValue() != 1; + Vector3d motionResponse = !temporalCollision ? motion + : motion.normalize() + .scale(motion.length() * temporalResponse.getValue()); rotationMatrix.transpose(); motionResponse = rotationMatrix.transform(motionResponse) @@ -192,10 +192,11 @@ public class ContraptionCollider { totalResponse = VecHelper.rotate(totalResponse, yawOffset, Axis.Y); rotationMatrix.transpose(); - if (futureCollision.isTrue() && playerType != PlayerType.SERVER) { - if (motionResponse.y != entityMotion.y) { + if (temporalCollision && playerType != PlayerType.SERVER) { + double idealVerticalMotion = motionResponse.y; + if (idealVerticalMotion != entityMotion.y) { entity.setMotion(entityMotion.mul(1, 0, 1) - .add(0, motionResponse.y, 0)); + .add(0, idealVerticalMotion, 0)); entityMotion = entity.getMotion(); } } @@ -212,7 +213,8 @@ public class ContraptionCollider { if (motionX != 0 && Math.abs(intersectX) > horizonalEpsilon && motionX > 0 == intersectX < 0) entityMotion = entityMotion.mul(0, 1, 1); if (motionY != 0 && intersectY != 0 && motionY > 0 == intersectY < 0) - entityMotion = entityMotion.mul(1, 0, 1); + entityMotion = entityMotion.mul(1, 0, 1) + .add(0, contraptionMotion.y, 0); if (motionZ != 0 && Math.abs(intersectZ) > horizonalEpsilon && motionZ > 0 == intersectZ < 0) entityMotion = entityMotion.mul(1, 1, 0); } @@ -226,25 +228,24 @@ public class ContraptionCollider { } Vector3d allowedMovement = getAllowedMovement(totalResponse, entity); - contraptionEntity.collidingEntities.add(entity); - entity.velocityChanged = true; entity.setPosition(entityPosition.x + allowedMovement.x, entityPosition.y + allowedMovement.y, entityPosition.z + allowedMovement.z); entityPosition = entity.getPositionVec(); + entity.velocityChanged = true; Vector3d contactPointMotion = Vector3d.ZERO; + if (surfaceCollision.isTrue()) { entity.fallDistance = 0; entity.setOnGround(true); - contraptionEntity.collidingEntities.add(entity); + contraptionEntity.collidingEntities.put(entity, new MutableInt(0)); if (entity instanceof ItemEntity) entityMotion = entityMotion.mul(.5f, 1, .5f); - if (playerType != PlayerType.SERVER) { contactPointMotion = contraptionEntity.getContactPointMotion(entityPosition); allowedMovement = getAllowedMovement(contactPointMotion, entity); - entity.setPosition(entityPosition.x + allowedMovement.x, entityPosition.y + allowedMovement.y, - entityPosition.z + allowedMovement.z); + entity.setPosition(entityPosition.x + allowedMovement.x, + entityPosition.y, entityPosition.z + allowedMovement.z); } } @@ -258,7 +259,8 @@ public class ContraptionCollider { float limbSwing = MathHelper.sqrt(d0 * d0 + d1 * d1) * 4.0F; if (limbSwing > 1.0F) limbSwing = 1.0F; - AllPackets.channel.sendToServer(new ClientMotionPacket(entityMotion, true, limbSwing)); + AllPackets.channel + .sendToServer(new ClientMotionPacket(entityMotion, true, limbSwing)); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionDisassemblyPacket.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionDisassemblyPacket.java new file mode 100644 index 000000000..20baaaa45 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionDisassemblyPacket.java @@ -0,0 +1,42 @@ +package com.simibubi.create.content.contraptions.components.structureMovement; + +import java.util.function.Supplier; + +import com.simibubi.create.foundation.networking.SimplePacketBase; + +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.fml.DistExecutor; +import net.minecraftforge.fml.network.NetworkEvent.Context; + +public class ContraptionDisassemblyPacket extends SimplePacketBase { + + int entityID; + StructureTransform transform; + + public ContraptionDisassemblyPacket(int entityID, StructureTransform transform) { + this.entityID = entityID; + this.transform = transform; + } + + public ContraptionDisassemblyPacket(PacketBuffer buffer) { + entityID = buffer.readInt(); + transform = StructureTransform.fromBuffer(buffer); + } + + @Override + public void write(PacketBuffer buffer) { + buffer.writeInt(entityID); + transform.writeToBuffer(buffer); + } + + @Override + public void handle(Supplier context) { + context.get() + .enqueueWork(() -> DistExecutor.runWhenOn(Dist.CLIENT, + () -> () -> AbstractContraptionEntity.handleDisassemblyPacket(this))); + context.get() + .setPacketHandled(true); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionRenderer.java index c885a5e88..609b1ec85 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionRenderer.java @@ -71,7 +71,7 @@ public class ContraptionRenderer { private static void renderTileEntities(World world, Contraption c, MatrixStack ms, MatrixStack msLocal, IRenderTypeBuffer buffer) { - TileEntityRenderHelper.renderTileEntities(world, c.renderedTileEntities, ms, msLocal, buffer); + TileEntityRenderHelper.renderTileEntities(world, c.renderedTileEntities.values(), ms, msLocal, buffer); } private static SuperByteBuffer buildStructureBuffer(Contraption c, RenderType layer) { @@ -86,10 +86,13 @@ public class ContraptionRenderer { Random random = new Random(); BufferBuilder builder = new BufferBuilder(DefaultVertexFormats.BLOCK.getIntegerSize()); builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); + renderWorld.setTileEntities(c.renderedTileEntities.values()); - for (BlockInfo info : c.getBlocks().values()) + for (BlockInfo info : c.getBlocks() + .values()) renderWorld.setBlockState(info.pos, info.state); - for (BlockInfo info : c.getBlocks().values()) { + for (BlockInfo info : c.getBlocks() + .values()) { BlockState state = info.state; if (state.getRenderType() == BlockRenderType.ENTITYBLOCK_ANIMATED) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ControlledContraptionEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ControlledContraptionEntity.java index 1f7c9fbed..e05d714f5 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ControlledContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ControlledContraptionEntity.java @@ -49,6 +49,13 @@ public class ControlledContraptionEntity extends AbstractContraptionEntity { public boolean supportsTerrainCollision() { return contraption instanceof TranslatingContraption; } + + @Override + public Vec3d getContactPointMotion(Vec3d globalContactPoint) { + if (contraption instanceof TranslatingContraption) + return getMotion(); + return super.getContactPointMotion(globalContactPoint); + } @Override protected void setContraption(Contraption contraption) { @@ -60,8 +67,8 @@ public class ControlledContraptionEntity extends AbstractContraptionEntity { } @Override - protected void readAdditional(CompoundNBT compound) { - super.readAdditional(compound); + protected void readAdditional(CompoundNBT compound, boolean spawnPacket) { + super.readAdditional(compound, spawnPacket); controllerPos = NBTUtil.readBlockPos(compound.getCompound("Controller")); if (compound.contains("Axis")) rotationAxis = NBTHelper.readEnum(compound, "Axis", Axis.class); @@ -69,8 +76,8 @@ public class ControlledContraptionEntity extends AbstractContraptionEntity { } @Override - protected void writeAdditional(CompoundNBT compound) { - super.writeAdditional(compound); + protected void writeAdditional(CompoundNBT compound, boolean spawnPacket) { + super.writeAdditional(compound, spawnPacket); compound.put("Controller", NBTUtil.writeBlockPos(controllerPos)); if (rotationAxis != null) NBTHelper.writeEnum(compound, "Axis", rotationAxis); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MountedFluidStorage.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MountedFluidStorage.java index 0617a77e1..135996fb4 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MountedFluidStorage.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MountedFluidStorage.java @@ -1,5 +1,170 @@ package com.simibubi.create.content.contraptions.components.structureMovement; +import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionFluidPacket; +import com.simibubi.create.content.contraptions.fluids.tank.CreativeFluidTankTileEntity; +import com.simibubi.create.content.contraptions.fluids.tank.CreativeFluidTankTileEntity.CreativeSmartFluidTank; +import com.simibubi.create.content.contraptions.fluids.tank.FluidTankTileEntity; +import com.simibubi.create.foundation.fluid.SmartFluidTank; +import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue; +import com.simibubi.create.foundation.networking.AllPackets; +import com.simibubi.create.foundation.utility.NBTHelper; + +import net.minecraft.entity.Entity; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fml.network.PacketDistributor; + public class MountedFluidStorage { + SmartFluidTank tank; + private boolean valid; + private TileEntity te; + + private int packetCooldown = 0; + private boolean sendPacket = false; + + public static boolean canUseAsStorage(TileEntity te) { + if (te instanceof FluidTankTileEntity) + return ((FluidTankTileEntity) te).isController(); + return false; + } + + public MountedFluidStorage(TileEntity te) { + assignTileEntity(te); + } + + public void assignTileEntity(TileEntity te) { + this.te = te; + tank = createMountedTank(te); + } + + private SmartFluidTank createMountedTank(TileEntity te) { + if (te instanceof CreativeFluidTankTileEntity) + return new CreativeSmartFluidTank( + ((FluidTankTileEntity) te).getTotalTankSize() * FluidTankTileEntity.getCapacityMultiplier(), $ -> { + }); + if (te instanceof FluidTankTileEntity) + return new SmartFluidTank( + ((FluidTankTileEntity) te).getTotalTankSize() * FluidTankTileEntity.getCapacityMultiplier(), + this::onFluidStackChanged); + return null; + } + + public void tick(Entity entity, BlockPos pos, boolean isRemote) { + if (!isRemote) { + if (packetCooldown > 0) + packetCooldown--; + else if (sendPacket) { + sendPacket = false; + AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> entity), + new ContraptionFluidPacket(entity.getEntityId(), pos, tank.getFluid())); + packetCooldown = 8; + } + return; + } + + if (!(te instanceof FluidTankTileEntity)) + return; + FluidTankTileEntity tank = (FluidTankTileEntity) te; + tank.getFluidLevel() + .tick(); + } + + public void updateFluid(FluidStack fluid) { + tank.setFluid(fluid); + if (!(te instanceof FluidTankTileEntity)) + return; + float fillState = tank.getFluidAmount() / (float) tank.getCapacity(); + FluidTankTileEntity tank = (FluidTankTileEntity) te; + if (tank.getFluidLevel() == null) + tank.setFluidLevel(new InterpolatedChasingValue().start(fillState)); + tank.getFluidLevel() + .target(fillState); + IFluidTank tankInventory = tank.getTankInventory(); + if (tankInventory instanceof SmartFluidTank) + ((SmartFluidTank) tankInventory).setFluid(fluid); + } + + public void removeStorageFromWorld() { + valid = false; + if (te == null) + return; + + IFluidHandler teHandler = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) + .orElse(null); + if (!(teHandler instanceof SmartFluidTank)) + return; + SmartFluidTank smartTank = (SmartFluidTank) teHandler; + tank.setFluid(smartTank.getFluid()); + sendPacket = false; + valid = true; + } + + private void onFluidStackChanged(FluidStack fs) { + sendPacket = true; + } + + public void addStorageToWorld(TileEntity te) { + if (tank instanceof CreativeSmartFluidTank) + return; + + LazyOptional capability = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY); + IFluidHandler teHandler = capability.orElse(null); + if (!(teHandler instanceof SmartFluidTank)) + return; + + SmartFluidTank inv = (SmartFluidTank) teHandler; + inv.setFluid(tank.getFluid()); + } + + public IFluidHandler getFluidHandler() { + return tank; + } + + public CompoundNBT serialize() { + if (!valid) + return null; + CompoundNBT tag = tank.writeToNBT(new CompoundNBT()); + tag.putInt("Capacity", tank.getCapacity()); + + if (tank instanceof CreativeSmartFluidTank) { + NBTHelper.putMarker(tag, "Bottomless"); + tag.put("ProvidedStack", tank.getFluid() + .writeToNBT(new CompoundNBT())); + } + return tag; + } + + public static MountedFluidStorage deserialize(CompoundNBT nbt) { + MountedFluidStorage storage = new MountedFluidStorage(null); + if (nbt == null) + return storage; + + int capacity = nbt.getInt("Capacity"); + storage.tank = new SmartFluidTank(capacity, storage::onFluidStackChanged); + storage.valid = true; + + if (nbt.contains("Bottomless")) { + FluidStack providedStack = FluidStack.loadFluidStackFromNBT(nbt.getCompound("ProvidedStack")); + CreativeSmartFluidTank creativeSmartFluidTank = new CreativeSmartFluidTank(capacity, $ -> { + }); + creativeSmartFluidTank.setContainedFluid(providedStack); + storage.tank = creativeSmartFluidTank; + return storage; + } + + storage.tank.readFromNBT(nbt); + return storage; + } + + public boolean isValid() { + return valid; + } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MountedStorage.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MountedStorage.java index e1b17a9e0..02ce47715 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MountedStorage.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MountedStorage.java @@ -31,7 +31,7 @@ public class MountedStorage { public static boolean canUseAsStorage(TileEntity te) { if (te == null) return false; - + if (AllTileEntities.ADJUSTABLE_CRATE.is(te)) return true; if (AllTileEntities.CREATIVE_CRATE.is(te)) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/OrientedContraptionEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/OrientedContraptionEntity.java index 2dc1fce97..e32de6a55 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/OrientedContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/OrientedContraptionEntity.java @@ -146,8 +146,8 @@ public class OrientedContraptionEntity extends AbstractContraptionEntity { } @Override - protected void readAdditional(CompoundNBT compound) { - super.readAdditional(compound); + protected void readAdditional(CompoundNBT compound, boolean spawnPacket) { + super.readAdditional(compound, spawnPacket); if (compound.contains("InitialOrientation")) setInitialOrientation(NBTHelper.readEnum(compound, "InitialOrientation", Direction.class)); @@ -170,8 +170,8 @@ public class OrientedContraptionEntity extends AbstractContraptionEntity { } @Override - protected void writeAdditional(CompoundNBT compound) { - super.writeAdditional(compound); + protected void writeAdditional(CompoundNBT compound, boolean spawnPacket) { + super.writeAdditional(compound, spawnPacket); if (motionBeforeStall != null) compound.put("CachedMotion", diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/StructureTransform.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/StructureTransform.java index 686e9de52..d9572871e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/StructureTransform.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/StructureTransform.java @@ -20,6 +20,7 @@ import net.minecraft.block.BlockState; import net.minecraft.block.HorizontalFaceBlock; import net.minecraft.block.SlabBlock; import net.minecraft.block.StairsBlock; +import net.minecraft.network.PacketBuffer; import net.minecraft.state.BooleanProperty; import net.minecraft.state.properties.AttachFace; import net.minecraft.state.properties.BellAttachment; @@ -41,6 +42,13 @@ public class StructureTransform { Axis rotationAxis; BlockPos offset; + private StructureTransform(BlockPos offset, int angle, Axis axis, Rotation rotation) { + this.offset = offset; + this.angle = angle; + rotationAxis = axis; + this.rotation = rotation; + } + public StructureTransform(BlockPos offset, float xRotation, float yRotation, float zRotation) { this.offset = offset; if (xRotation != 0) { @@ -72,14 +80,16 @@ public class StructureTransform { public Vector3d apply(Vector3d localVec) { Vector3d vec = localVec; - vec = VecHelper.rotateCentered(vec, angle, rotationAxis); + if (rotationAxis != null) + vec = VecHelper.rotateCentered(vec, angle, rotationAxis); vec = vec.add(Vector3d.of(offset)); return vec; } - + public BlockPos apply(BlockPos localPos) { Vector3d vec = VecHelper.getCenterOf(localPos); - vec = VecHelper.rotateCentered(vec, angle, rotationAxis); + if (rotationAxis != null) + vec = VecHelper.rotateCentered(vec, angle, rotationAxis); localPos = new BlockPos(vec); return localPos.add(offset); } @@ -203,8 +213,9 @@ public class StructureTransform { protected BlockState transformBelt(BlockState state, boolean halfTurn) { Direction initialDirection = state.get(BeltBlock.HORIZONTAL_FACING); - boolean diagonal = state.get(BeltBlock.SLOPE) == BeltSlope.DOWNWARD || state.get(BeltBlock.SLOPE) == BeltSlope.UPWARD; - + boolean diagonal = + state.get(BeltBlock.SLOPE) == BeltSlope.DOWNWARD || state.get(BeltBlock.SLOPE) == BeltSlope.UPWARD; + if (!diagonal) { for (int i = 0; i < rotation.ordinal(); i++) { Direction direction = state.get(BeltBlock.HORIZONTAL_FACING); @@ -212,7 +223,7 @@ public class StructureTransform { boolean vertical = slope == BeltSlope.VERTICAL; boolean horizontal = slope == BeltSlope.HORIZONTAL; boolean sideways = slope == BeltSlope.SIDEWAYS; - + Direction newDirection = direction.getOpposite(); BeltSlope newSlope = BeltSlope.VERTICAL; @@ -230,15 +241,15 @@ public class StructureTransform { if (sideways) { newDirection = direction; - if (direction.getAxis() == rotationAxis) + if (direction.getAxis() == rotationAxis) newSlope = BeltSlope.HORIZONTAL; - else + else newDirection = direction.rotateYCCW(); } if (horizontal) { newDirection = direction; - if (direction.getAxis() == rotationAxis) + if (direction.getAxis() == rotationAxis) newSlope = BeltSlope.SIDEWAYS; } @@ -255,8 +266,7 @@ public class StructureTransform { boolean downward = slope == BeltSlope.DOWNWARD; // Rotate diagonal - if (direction.getAxisDirection() == AxisDirection.POSITIVE ^ downward - ^ direction.getAxis() == Axis.Z) { + if (direction.getAxisDirection() == AxisDirection.POSITIVE ^ downward ^ direction.getAxis() == Axis.Z) { state = state.with(BeltBlock.SLOPE, upward ? BeltSlope.DOWNWARD : BeltSlope.UPWARD); } else { state = state.with(BeltBlock.HORIZONTAL_FACING, newDirection); @@ -268,10 +278,10 @@ public class StructureTransform { Direction newDirection = direction.getOpposite(); BeltSlope slope = state.get(BeltBlock.SLOPE); boolean vertical = slope == BeltSlope.VERTICAL; - + if (diagonal) { - state = state.with(BeltBlock.SLOPE, - slope == BeltSlope.UPWARD ? BeltSlope.DOWNWARD : slope == BeltSlope.DOWNWARD ? BeltSlope.UPWARD : slope); + state = state.with(BeltBlock.SLOPE, slope == BeltSlope.UPWARD ? BeltSlope.DOWNWARD + : slope == BeltSlope.DOWNWARD ? BeltSlope.UPWARD : slope); } else if (vertical) { state = state.with(BeltBlock.HORIZONTAL_FACING, newDirection); } @@ -318,4 +328,21 @@ public class StructureTransform { return rotated; } + public static StructureTransform fromBuffer(PacketBuffer buffer) { + BlockPos readBlockPos = buffer.readBlockPos(); + int readAngle = buffer.readInt(); + int axisIndex = buffer.readVarInt(); + int rotationIndex = buffer.readVarInt(); + return new StructureTransform(readBlockPos, readAngle, + axisIndex == -1 ? null : Axis.values()[axisIndex], + rotationIndex == -1 ? null : Rotation.values()[rotationIndex]); + } + + public void writeToBuffer(PacketBuffer buffer) { + buffer.writeBlockPos(offset); + buffer.writeInt(angle); + buffer.writeVarInt(rotationAxis == null ? -1 : rotationAxis.ordinal()); + buffer.writeVarInt(rotation == null ? -1 : rotation.ordinal()); + } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingContraption.java index 8614d6c60..63f141114 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingContraption.java @@ -62,18 +62,18 @@ public class BearingContraption extends Contraption { } @Override - public CompoundNBT writeNBT() { - CompoundNBT tag = super.writeNBT(); + public CompoundNBT writeNBT(boolean spawnPacket) { + CompoundNBT tag = super.writeNBT(spawnPacket); tag.putInt("Sails", sailBlocks); tag.putInt("Facing", facing.getIndex()); return tag; } @Override - public void readNBT(World world, CompoundNBT tag) { + public void readNBT(World world, CompoundNBT tag, boolean spawnData) { sailBlocks = tag.getInt("Sails"); facing = Direction.byIndex(tag.getInt("Facing")); - super.readNBT(world, tag); + super.readNBT(world, tag, spawnData); } public int getSailBlocks() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkContraption.java index 7a772108d..31b7709f3 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/ClockworkContraption.java @@ -100,8 +100,8 @@ public class ClockworkContraption extends Contraption { } @Override - public CompoundNBT writeNBT() { - CompoundNBT tag = super.writeNBT(); + public CompoundNBT writeNBT(boolean spawnPacket) { + CompoundNBT tag = super.writeNBT(spawnPacket); tag.putInt("facing", facing.getIndex()); tag.putInt("offset", offset); NBTHelper.writeEnum(tag, "HandType", handType); @@ -109,11 +109,11 @@ public class ClockworkContraption extends Contraption { } @Override - public void readNBT(World world, CompoundNBT tag) { + public void readNBT(World world, CompoundNBT tag, boolean spawnData) { facing = Direction.byIndex(tag.getInt("Facing")); handType = NBTHelper.readEnum(tag, "HandType", HandType.class); offset = tag.getInt("offset"); - super.readNBT(world, tag); + super.readNBT(world, tag, spawnData); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedContraption.java index 2e70f6f92..f54d09beb 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedContraption.java @@ -42,16 +42,16 @@ public class StabilizedContraption extends Contraption { } @Override - public CompoundNBT writeNBT() { - CompoundNBT tag = super.writeNBT(); + public CompoundNBT writeNBT(boolean spawnPacket) { + CompoundNBT tag = super.writeNBT(spawnPacket); tag.putInt("Facing", facing.getIndex()); return tag; } @Override - public void readNBT(World world, CompoundNBT tag) { + public void readNBT(World world, CompoundNBT tag, boolean spawnData) { facing = Direction.byIndex(tag.getInt("Facing")); - super.readNBT(world, tag); + super.readNBT(world, tag, spawnData); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/glue/SuperGlueEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/glue/SuperGlueEntity.java index 7c34773c5..529a99e66 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/glue/SuperGlueEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/glue/SuperGlueEntity.java @@ -177,7 +177,7 @@ public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnDat public static boolean isValidFace(World world, BlockPos pos, Direction direction) { BlockState state = world.getBlockState(pos); - if (BlockMovementTraits.isBlockAttachedTowards(state, direction)) + if (BlockMovementTraits.isBlockAttachedTowards(world, pos, state, direction)) return true; if (!BlockMovementTraits.movementNecessary(world, pos)) return false; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MinecartContraptionItem.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MinecartContraptionItem.java index b3822ff1c..94ae89035 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MinecartContraptionItem.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MinecartContraptionItem.java @@ -167,7 +167,7 @@ public class MinecartContraptionItem extends Item { intialOrientation = Optional.of(NBTHelper.readEnum(contraptionTag, "InitialOrientation", Direction.class)); - Contraption mountedContraption = Contraption.fromNBT(world, contraptionTag); + Contraption mountedContraption = Contraption.fromNBT(world, contraptionTag, false); OrientedContraptionEntity contraptionEntity = OrientedContraptionEntity.create(world, mountedContraption, intialOrientation); @@ -220,7 +220,7 @@ public class MinecartContraptionItem extends Item { public static ItemStack create(Type type, OrientedContraptionEntity entity) { ItemStack stack = ItemStack.EMPTY; - + switch (type) { case RIDEABLE: stack = AllItems.MINECART_CONTRAPTION.asStack(); @@ -234,12 +234,12 @@ public class MinecartContraptionItem extends Item { default: break; } - + if (stack.isEmpty()) return stack; CompoundNBT tag = entity.getContraption() - .writeNBT(); + .writeNBT(false); tag.remove("UUID"); tag.remove("Pos"); tag.remove("Motion"); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java index 32693d269..72ec16a9c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java @@ -127,16 +127,16 @@ public class MountedContraption extends Contraption { } @Override - public CompoundNBT writeNBT() { - CompoundNBT writeNBT = super.writeNBT(); - NBTHelper.writeEnum(writeNBT, "RotationMode", rotationMode); - return writeNBT; + public CompoundNBT writeNBT(boolean spawnPacket) { + CompoundNBT tag = super.writeNBT(spawnPacket); + NBTHelper.writeEnum(tag, "RotationMode", rotationMode); + return tag; } @Override - public void readNBT(World world, CompoundNBT nbt) { + public void readNBT(World world, CompoundNBT nbt, boolean spawnData) { rotationMode = NBTHelper.readEnum(nbt, "RotationMode", CartMovementMode.class); - super.readNBT(world, nbt); + super.readNBT(world, nbt, spawnData); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java index 9e0e0972d..9c67056ee 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonContraption.java @@ -1,25 +1,11 @@ package com.simibubi.create.content.contraptions.components.structureMovement.piston; -import static com.simibubi.create.AllBlocks.MECHANICAL_PISTON_HEAD; -import static com.simibubi.create.AllBlocks.PISTON_EXTENSION_POLE; -import static com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.isExtensionPole; -import static com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.isPiston; -import static com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.isPistonHead; -import static com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.isStickyPiston; -import static net.minecraft.state.properties.BlockStateProperties.FACING; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.lang3.tuple.Pair; - import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes; import com.simibubi.create.content.contraptions.components.structureMovement.BlockMovementTraits; import com.simibubi.create.content.contraptions.components.structureMovement.TranslatingContraption; -import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.PistonState; +import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.*; import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.utility.VecHelper; - import net.minecraft.block.BlockState; import net.minecraft.block.CarpetBlock; import net.minecraft.nbt.CompoundNBT; @@ -32,6 +18,15 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.IWorld; import net.minecraft.world.World; import net.minecraft.world.gen.feature.template.Template.BlockInfo; +import org.apache.commons.lang3.tuple.Pair; + +import java.util.ArrayList; +import java.util.List; + +import static com.simibubi.create.AllBlocks.MECHANICAL_PISTON_HEAD; +import static com.simibubi.create.AllBlocks.PISTON_EXTENSION_POLE; +import static com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.*; +import static net.minecraft.state.properties.BlockStateProperties.FACING; public class PistonContraption extends TranslatingContraption { @@ -77,8 +72,7 @@ public class PistonContraption extends TranslatingContraption { return false; if (blockState.get(MechanicalPistonBlock.STATE) == PistonState.EXTENDED) { - while (isExtensionPole(nextBlock) && nextBlock.get(FACING) - .getAxis() == direction.getAxis() || isPistonHead(nextBlock) && nextBlock.get(FACING) == direction) { + while (PistonPolePlacementHelper.matchesAxis(nextBlock, direction.getAxis()) || isPistonHead(nextBlock) && nextBlock.get(FACING) == direction) { actualStart = actualStart.offset(direction); poles.add(new BlockInfo(actualStart, nextBlock.with(FACING, direction), null)); @@ -105,7 +99,7 @@ public class PistonContraption extends TranslatingContraption { nextBlock = world.getBlockState(end.offset(direction.getOpposite())); int extensionsInBack = 0; - while (isExtensionPole(nextBlock)) { + while (PistonPolePlacementHelper.matchesAxis(nextBlock, direction.getAxis())) { end = end.offset(direction.getOpposite()); poles.add(new BlockInfo(end, nextBlock.with(FACING, direction), null)); extensionsInBack++; @@ -209,20 +203,20 @@ public class PistonContraption extends TranslatingContraption { } @Override - public void readNBT(World world, CompoundNBT nbt) { - super.readNBT(world, nbt); + public void readNBT(World world, CompoundNBT nbt, boolean spawnData) { + super.readNBT(world, nbt, spawnData); initialExtensionProgress = nbt.getInt("InitialLength"); extensionLength = nbt.getInt("ExtensionLength"); orientation = Direction.byIndex(nbt.getInt("Orientation")); } @Override - public CompoundNBT writeNBT() { - CompoundNBT nbt = super.writeNBT(); - nbt.putInt("InitialLength", initialExtensionProgress); - nbt.putInt("ExtensionLength", extensionLength); - nbt.putInt("Orientation", orientation.getIndex()); - return nbt; + public CompoundNBT writeNBT(boolean spawnPacket) { + CompoundNBT tag = super.writeNBT(spawnPacket); + tag.putInt("InitialLength", initialExtensionProgress); + tag.putInt("ExtensionLength", extensionLength); + tag.putInt("Orientation", orientation.getIndex()); + return tag; } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonExtensionPoleBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonExtensionPoleBlock.java index bfd5b1e41..4c49bee1c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonExtensionPoleBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonExtensionPoleBlock.java @@ -4,10 +4,12 @@ import static com.simibubi.create.content.contraptions.components.structureMovem import static com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.isPiston; import static com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.isPistonHead; +import com.simibubi.create.AllBlocks; import com.simibubi.create.AllShapes; import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.PistonState; import com.simibubi.create.content.contraptions.wrench.IWrenchable; import com.simibubi.create.foundation.block.ProperDirectionalBlock; +import com.simibubi.create.foundation.utility.Pair; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -17,12 +19,16 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.fluid.FluidState; import net.minecraft.fluid.Fluids; import net.minecraft.item.BlockItemUseContext; +import net.minecraft.item.ItemStack; import net.minecraft.state.StateContainer.Builder; import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.util.ActionResultType; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.AxisDirection; +import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; @@ -31,91 +37,129 @@ import net.minecraft.world.World; public class PistonExtensionPoleBlock extends ProperDirectionalBlock implements IWrenchable, IWaterLoggable { - public PistonExtensionPoleBlock(Properties properties) { - super(properties); - setDefaultState(getDefaultState().with(FACING, Direction.UP).with(BlockStateProperties.WATERLOGGED, false)); - } + public PistonExtensionPoleBlock(Properties properties) { + super(properties); + setDefaultState(getDefaultState().with(FACING, Direction.UP) + .with(BlockStateProperties.WATERLOGGED, false)); + } - @Override - public PushReaction getPushReaction(BlockState state) { - return PushReaction.NORMAL; - } + @Override + public PushReaction getPushReaction(BlockState state) { + return PushReaction.NORMAL; + } - @Override - public void onBlockHarvested(World worldIn, BlockPos pos, BlockState state, PlayerEntity player) { - Axis axis = state.get(FACING) - .getAxis(); - Direction direction = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis); - BlockPos pistonHead = null; - BlockPos pistonBase = null; + @Override + public void onBlockHarvested(World worldIn, BlockPos pos, BlockState state, PlayerEntity player) { + Axis axis = state.get(FACING) + .getAxis(); + Direction direction = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis); + BlockPos pistonHead = null; + BlockPos pistonBase = null; - for (int modifier : new int[]{1, -1}) { - for (int offset = modifier; modifier * offset < MechanicalPistonBlock.maxAllowedPistonPoles(); offset += - modifier) { - BlockPos currentPos = pos.offset(direction, offset); - BlockState block = worldIn.getBlockState(currentPos); + for (int modifier : new int[] { 1, -1 }) { + for (int offset = modifier; modifier * offset < MechanicalPistonBlock.maxAllowedPistonPoles(); offset += + modifier) { + BlockPos currentPos = pos.offset(direction, offset); + BlockState block = worldIn.getBlockState(currentPos); - if (isExtensionPole(block) && axis == block.get(FACING) - .getAxis()) - continue; + if (isExtensionPole(block) && axis == block.get(FACING) + .getAxis()) + continue; - if (isPiston(block) && block.get(BlockStateProperties.FACING) - .getAxis() == axis) - pistonBase = currentPos; + if (isPiston(block) && block.get(BlockStateProperties.FACING) + .getAxis() == axis) + pistonBase = currentPos; - if (isPistonHead(block) && block.get(BlockStateProperties.FACING) - .getAxis() == axis) - pistonHead = currentPos; + if (isPistonHead(block) && block.get(BlockStateProperties.FACING) + .getAxis() == axis) + pistonHead = currentPos; - break; - } - } + break; + } + } - if (pistonHead != null && pistonBase != null && worldIn.getBlockState(pistonHead) - .get(BlockStateProperties.FACING) == worldIn.getBlockState(pistonBase) - .get(BlockStateProperties.FACING)) { + if (pistonHead != null && pistonBase != null && worldIn.getBlockState(pistonHead) + .get(BlockStateProperties.FACING) == worldIn.getBlockState(pistonBase) + .get(BlockStateProperties.FACING)) { - final BlockPos basePos = pistonBase; - BlockPos.getAllInBox(pistonBase, pistonHead) - .filter(p -> !p.equals(pos) && !p.equals(basePos)) - .forEach(p -> worldIn.destroyBlock(p, !player.isCreative())); - worldIn.setBlockState(basePos, worldIn.getBlockState(basePos) - .with(MechanicalPistonBlock.STATE, PistonState.RETRACTED)); - } + final BlockPos basePos = pistonBase; + BlockPos.getAllInBox(pistonBase, pistonHead) + .filter(p -> !p.equals(pos) && !p.equals(basePos)) + .forEach(p -> worldIn.destroyBlock(p, !player.isCreative())); + worldIn.setBlockState(basePos, worldIn.getBlockState(basePos) + .with(MechanicalPistonBlock.STATE, PistonState.RETRACTED)); + } - super.onBlockHarvested(worldIn, pos, state, player); - } + super.onBlockHarvested(worldIn, pos, state, player); + } - @Override - public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { - return AllShapes.FOUR_VOXEL_POLE.get(state.get(FACING) - .getAxis()); - } + @Override + public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) { + return AllShapes.FOUR_VOXEL_POLE.get(state.get(FACING) + .getAxis()); + } - @Override - public BlockState getStateForPlacement(BlockItemUseContext context) { - FluidState FluidState = context.getWorld().getFluidState(context.getPos()); - return getDefaultState().with(FACING, context.getFace().getOpposite()) - .with(BlockStateProperties.WATERLOGGED, Boolean.valueOf(FluidState.getFluid() == Fluids.WATER)); - } + @Override + public BlockState getStateForPlacement(BlockItemUseContext context) { + FluidState FluidState = context.getWorld() + .getFluidState(context.getPos()); + return getDefaultState().with(FACING, context.getFace() + .getOpposite()) + .with(BlockStateProperties.WATERLOGGED, Boolean.valueOf(FluidState.getFluid() == Fluids.WATER)); + } - @Override - public FluidState getFluidState(BlockState state) { - return state.get(BlockStateProperties.WATERLOGGED) ? Fluids.WATER.getStillFluidState(false) : Fluids.EMPTY.getDefaultState(); - } + @Override + public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, + BlockRayTraceResult ray) { + ItemStack heldItem = player.getHeldItem(hand); - @Override - protected void fillStateContainer(Builder builder) { - builder.add(BlockStateProperties.WATERLOGGED); - super.fillStateContainer(builder); - } + if (AllBlocks.PISTON_EXTENSION_POLE.isIn(heldItem) && !player.isSneaking()) { + Pair offset = PistonPolePlacementHelper.getPlacementOffset(world, state.get(FACING) + .getAxis(), pos, ray.getHitVec()); - @Override - public BlockState updatePostPlacement(BlockState state, Direction direction, BlockState neighbourState, - IWorld world, BlockPos pos, BlockPos neighbourPos) { - if (state.get(BlockStateProperties.WATERLOGGED)) { - world.getPendingFluidTicks().scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world)); - } - return state; - } + if (offset == null || offset.getSecond() == 0) + return ActionResultType.PASS; + + BlockPos newPos = pos.offset(offset.getFirst(), offset.getSecond()); + + if (!world.getBlockState(newPos) + .getMaterial() + .isReplaceable()) + return ActionResultType.PASS; + + if (world.isRemote) + return ActionResultType.SUCCESS; + + world.setBlockState(newPos, AllBlocks.PISTON_EXTENSION_POLE.getDefaultState() + .with(FACING, offset.getFirst())); + if (!player.isCreative()) + heldItem.shrink(1); + + return ActionResultType.SUCCESS; + } + + return ActionResultType.PASS; + } + + @Override + public FluidState getFluidState(BlockState state) { + return state.get(BlockStateProperties.WATERLOGGED) ? Fluids.WATER.getStillFluidState(false) + : Fluids.EMPTY.getDefaultState(); + } + + @Override + protected void fillStateContainer(Builder builder) { + builder.add(BlockStateProperties.WATERLOGGED); + super.fillStateContainer(builder); + } + + @Override + public BlockState updatePostPlacement(BlockState state, Direction direction, BlockState neighbourState, + IWorld world, BlockPos pos, BlockPos neighbourPos) { + if (state.get(BlockStateProperties.WATERLOGGED)) { + world.getPendingFluidTicks() + .scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world)); + } + return state; + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonPolePlacementHelper.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonPolePlacementHelper.java new file mode 100644 index 000000000..5559631e6 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonPolePlacementHelper.java @@ -0,0 +1,126 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.piston; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.CreateClient; +import com.simibubi.create.foundation.utility.Iterate; +import com.simibubi.create.foundation.utility.Pair; +import com.simibubi.create.foundation.utility.VecHelper; +import net.minecraft.block.BlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.Direction; +import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +import java.util.Arrays; + +public class PistonPolePlacementHelper { + + @OnlyIn(Dist.CLIENT) + public static void tick() { + Minecraft mc = Minecraft.getInstance(); + ClientWorld world = mc.world; + + if (!(mc.objectMouseOver instanceof BlockRayTraceResult)) + return; + + BlockRayTraceResult ray = (BlockRayTraceResult) mc.objectMouseOver; + + if (!isHoldingPole(mc.player)) + return; + + BlockPos pos = ray.getPos(); + BlockState state = world.getBlockState(pos); + if (!(state.getBlock() instanceof PistonExtensionPoleBlock)) + return; + + Pair offset = getPlacementOffset(world, state.get(PistonExtensionPoleBlock.FACING).getAxis(), pos, ray.getHitVec()); + if (offset == null || offset.getSecond() == 0) + return; + + Direction hitFace = ray.getFace(); + + if (hitFace.getAxis() == offset.getFirst().getAxis()) + return; + + Vec3d hitCenter = VecHelper.getCenterOf(pos).add(new Vec3d(hitFace.getDirectionVec()).scale(0.3)); + + //get the two perpendicular directions to form the arrow + Direction[] directions = Arrays.stream(Direction.Axis.values()).filter(axis -> axis != hitFace.getAxis() && axis != offset.getFirst().getAxis()).map(Iterate::directionsInAxis).findFirst().orElse(new Direction[]{}); + Vec3d startOffset = new Vec3d(offset.getFirst().getDirectionVec()); + Vec3d start = hitCenter.add(startOffset); + for (Direction dir : directions) { + Vec3d arrowOffset = new Vec3d(dir.getDirectionVec()).scale(.25); + Vec3d target = hitCenter.add(startOffset.scale(0.75)).add(arrowOffset); + CreateClient.outliner.showLine("poleHelp" + offset.getFirst() + dir, start, target).lineWidth(1/16f); + } + } + + // first indicates the direction that the position needs to be offset into + // second indicates by how many blocks the position needs to be offset by; is 0 if there was no valid position on either end of the pole + public static Pair getPlacementOffset(World world, Direction.Axis poleAxis, BlockPos pos, Vec3d hit) { + Pair offset = null; + double min = Double.MAX_VALUE; + Vec3d localPos = hit.subtract(VecHelper.getCenterOf(pos)); + + //find target direction + for (Direction dir : Iterate.directionsInAxis(poleAxis)) { + double distance = new Vec3d(dir.getDirectionVec()).distanceTo(localPos); + if (distance > min) + continue; + min = distance; + offset = Pair.of(dir, 0); + } + + if (offset == null)//?? + return null; + + //check for space at the end of the pole + int poles = attachedPoles(world, pos, offset.getFirst()); + BlockState state = world.getBlockState(pos.offset(offset.getFirst(), poles + 1)); + + if (state.getMaterial().isReplaceable()) { + offset.setSecond(poles + 1); + return offset; + } + + //check the other end of the pole + offset.setFirst(offset.getFirst().getOpposite()); + poles = attachedPoles(world, pos, offset.getFirst()); + state = world.getBlockState(pos.offset(offset.getFirst(), poles + 1)); + + if (state.getMaterial().isReplaceable()) { + offset.setSecond(poles + 1); + } + + return offset; + } + + public static int attachedPoles(World world, BlockPos pos, Direction direction) { + BlockPos checkPos = pos.offset(direction); + BlockState state = world.getBlockState(checkPos); + int count = 0; + while (matchesAxis(state, direction.getAxis())) { + count++; + checkPos = checkPos.offset(direction); + state = world.getBlockState(checkPos); + } + return count; + } + + //checks if the given state is a piston pole on the given axis + public static boolean matchesAxis(BlockState state, Direction.Axis axis) { + return AllBlocks.PISTON_EXTENSION_POLE.has(state) && state.get(PistonExtensionPoleBlock.FACING).getAxis() == axis; + } + + public static boolean isHoldingPole(PlayerEntity player) { + return Arrays.stream(Hand.values()).anyMatch(hand -> AllBlocks.PISTON_EXTENSION_POLE.isIn(player.getHeldItem(hand))); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyContraption.java index 021206c24..d4a48a889 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyContraption.java @@ -41,16 +41,16 @@ public class PulleyContraption extends TranslatingContraption { } @Override - public CompoundNBT writeNBT() { - CompoundNBT writeNBT = super.writeNBT(); - writeNBT.putInt("InitialOffset", initialOffset); - return writeNBT; + public CompoundNBT writeNBT(boolean spawnPacket) { + CompoundNBT tag = super.writeNBT(spawnPacket); + tag.putInt("InitialOffset", initialOffset); + return tag; } @Override - public void readNBT(World world, CompoundNBT nbt) { + public void readNBT(World world, CompoundNBT nbt, boolean spawnData) { initialOffset = nbt.getInt("InitialOffset"); - super.readNBT(world, nbt); + super.readNBT(world, nbt, spawnData); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ContraptionFluidPacket.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ContraptionFluidPacket.java new file mode 100644 index 000000000..bc0d308bd --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ContraptionFluidPacket.java @@ -0,0 +1,53 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.sync; + +import java.util.function.Supplier; + +import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; +import com.simibubi.create.foundation.networking.SimplePacketBase; + +import net.minecraft.client.Minecraft; +import net.minecraft.entity.Entity; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.math.BlockPos; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fml.network.NetworkEvent.Context; + +public class ContraptionFluidPacket extends SimplePacketBase { + + private int entityId; + private BlockPos localPos; + private FluidStack containedFluid; + + public ContraptionFluidPacket(int entityId, BlockPos localPos, FluidStack containedFluid) { + this.entityId = entityId; + this.localPos = localPos; + this.containedFluid = containedFluid; + } + + public ContraptionFluidPacket(PacketBuffer buffer) { + entityId = buffer.readInt(); + localPos = buffer.readBlockPos(); + containedFluid = FluidStack.readFromPacket(buffer); + } + + @Override + public void write(PacketBuffer buffer) { + buffer.writeInt(entityId); + buffer.writeBlockPos(localPos); + containedFluid.writeToPacket(buffer); + } + + @Override + public void handle(Supplier context) { + context.get() + .enqueueWork(() -> { + Entity entityByID = Minecraft.getInstance().world.getEntityByID(entityId); + if (!(entityByID instanceof AbstractContraptionEntity)) + return; + AbstractContraptionEntity contraptionEntity = (AbstractContraptionEntity) entityByID; + contraptionEntity.getContraption().updateContainedFluid(localPos, containedFluid); + }); + context.get() + .setPacketHandled(true); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/FluidFX.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/FluidFX.java index f19790713..bd22b97d1 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/FluidFX.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/FluidFX.java @@ -68,7 +68,7 @@ public class FluidFX { vec = VecHelper.clampComponentWise(vec, rimRadius) .mul(VecHelper.axisAlingedPlaneOf(directionVec)) .add(directionVec.scale(.45 + r.nextFloat() / 16f)); - Vector3d m = vec; + Vector3d m = vec.scale(.05f); vec = vec.add(VecHelper.getCenterOf(pos)); world.addOptionalParticle(particle, vec.x, vec.y - 1 / 16f, vec.z, m.x, m.y, m.z); diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/CreativeFluidTankTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/CreativeFluidTankTileEntity.java index aeb03c5f5..dfa661558 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/CreativeFluidTankTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/CreativeFluidTankTileEntity.java @@ -18,7 +18,7 @@ public class CreativeFluidTankTileEntity extends FluidTankTileEntity { return new CreativeSmartFluidTank(getCapacityMultiplier(), this::onFluidStackChanged); } - class CreativeSmartFluidTank extends SmartFluidTank { + public static class CreativeSmartFluidTank extends SmartFluidTank { public CreativeSmartFluidTank(int capacity, Consumer updateCallback) { super(capacity, updateCallback); @@ -33,7 +33,7 @@ public class CreativeFluidTankTileEntity extends FluidTankTileEntity { fluid = fluidStack.copy(); if (!fluidStack.isEmpty()) fluid.setAmount(getTankCapacity(0)); - notifyUpdate(); + onContentsChanged(); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankBlock.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankBlock.java index a154e5e9f..9648f3565 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankBlock.java @@ -28,6 +28,8 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ActionResultType; import net.minecraft.util.Hand; import net.minecraft.util.IStringSerializable; +import net.minecraft.util.Mirror; +import net.minecraft.util.Rotation; import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundEvent; import net.minecraft.util.SoundEvents; @@ -41,6 +43,7 @@ import net.minecraft.world.World; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.fluids.FluidAttributes; import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler; public class FluidTankBlock extends Block implements IWrenchable, ITE { @@ -72,9 +75,11 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE tankCapability = te.fluidCapability; + LazyOptional tankCapability = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY); if (!tankCapability.isPresent()) return ActionResultType.PASS; IFluidHandler fluidTank = tankCapability.orElse(null); @@ -142,7 +147,8 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE type = te.getType(); World world = te.getWorld(); BlockPos origin = te.getPos(); - FluidStack fluid = te.getTankInventory() - .getFluid(); + LazyOptional capability = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY); + FluidTank teTank = (FluidTank) capability.orElse(null); + FluidStack fluid = capability.map(ifh -> ifh.getFluidInTank(0)) + .orElse(FluidStack.EMPTY); Search: @@ -192,6 +199,8 @@ public class FluidTankConnectivityHandler { if (simulate) return amount; + + boolean opaque = false; for (int yOffset = 0; yOffset < height; yOffset++) { for (int xOffset = 0; xOffset < width; xOffset++) { @@ -201,10 +210,15 @@ public class FluidTankConnectivityHandler { if (tank == te) continue; - if (tank.isController()) { - te.tankInventory.fill(tank.tankInventory.getFluid(), FluidAction.EXECUTE); - tank.tankInventory.setFluid(FluidStack.EMPTY); + opaque |= !tank.window; + FluidTank tankTank = tank.tankInventory; + FluidStack fluidInTank = tankTank.getFluid(); + if (!fluidInTank.isEmpty()) { + if (teTank.isEmpty() && teTank instanceof CreativeSmartFluidTank) + ((CreativeSmartFluidTank) teTank).setContainedFluid(fluidInTank); + teTank.fill(fluidInTank, FluidAction.EXECUTE); } + tankTank.setFluid(FluidStack.EMPTY); splitTankAndInvalidate(tank, cache, false); tank.setController(origin); @@ -220,6 +234,8 @@ public class FluidTankConnectivityHandler { } } } + + te.setWindows(!opaque); return amount; } @@ -243,8 +259,9 @@ public class FluidTankConnectivityHandler { FluidStack toDistribute = te.tankInventory.getFluid() .copy(); int maxCapacity = FluidTankTileEntity.getCapacityMultiplier(); - if (!toDistribute.isEmpty()) + if (!toDistribute.isEmpty() && !te.isRemoved()) toDistribute.shrink(maxCapacity); + te.applyFluidTankSize(1); for (int yOffset = 0; yOffset < height; yOffset++) { for (int xOffset = 0; xOffset < width; xOffset++) { @@ -259,14 +276,19 @@ public class FluidTankConnectivityHandler { continue; FluidTankTileEntity controllerTE = tankAt.getControllerTE(); tankAt.window = controllerTE == null || controllerTE.window; - tankAt.removeController(); + tankAt.removeController(true); if (!toDistribute.isEmpty() && tankAt != te) { - int split = Math.min(maxCapacity, toDistribute.getAmount()); FluidStack copy = toDistribute.copy(); - copy.setAmount(split); - toDistribute.shrink(split); - tankAt.tankInventory.fill(copy, FluidAction.EXECUTE); + FluidTank tankInventory = tankAt.tankInventory; + if (tankInventory.isEmpty() && tankInventory instanceof CreativeSmartFluidTank) + ((CreativeSmartFluidTank) tankInventory).setContainedFluid(toDistribute); + else { + int split = Math.min(maxCapacity, toDistribute.getAmount()); + copy.setAmount(split); + toDistribute.shrink(split); + tankInventory.fill(copy, FluidAction.EXECUTE); + } } if (tryReconnect) { @@ -300,7 +322,7 @@ public class FluidTankConnectivityHandler { return (FluidTankTileEntity) te; return null; } - + @Nullable public static FluidTankTileEntity anyTankAt(IBlockReader world, BlockPos pos) { TileEntity te = world.getTileEntity(pos); diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankItem.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankItem.java index 9b4be3505..cec618615 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankItem.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankItem.java @@ -6,10 +6,13 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.server.MinecraftServer; import net.minecraft.util.ActionResultType; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraftforge.fluids.FluidStack; public class FluidTankItem extends BlockItem { @@ -26,6 +29,30 @@ public class FluidTankItem extends BlockItem { return initialResult; } + @Override + protected boolean onBlockPlaced(BlockPos p_195943_1_, World p_195943_2_, PlayerEntity p_195943_3_, + ItemStack p_195943_4_, BlockState p_195943_5_) { + MinecraftServer minecraftserver = p_195943_2_.getServer(); + if (minecraftserver == null) + return false; + CompoundNBT nbt = p_195943_4_.getChildTag("BlockEntityTag"); + if (nbt != null) { + nbt.remove("Luminosity"); + nbt.remove("Size"); + nbt.remove("Height"); + nbt.remove("Controller"); + nbt.remove("LastKnownPos"); + if (nbt.contains("TankContent")) { + FluidStack fluid = FluidStack.loadFluidStackFromNBT(nbt.getCompound("TankContent")); + if (!fluid.isEmpty()) { + fluid.setAmount(Math.min(FluidTankTileEntity.getCapacityMultiplier(), fluid.getAmount())); + nbt.put("TankContent", fluid.writeToNBT(new CompoundNBT())); + } + } + } + return super.onBlockPlaced(p_195943_1_, p_195943_2_, p_195943_3_, p_195943_4_, p_195943_5_); + } + private void tryMultiPlace(BlockItemUseContext ctx) { PlayerEntity player = ctx.getPlayer(); if (player == null) diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankTileEntity.java index 19a8c7eea..3f3ce1453 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/tank/FluidTankTileEntity.java @@ -42,6 +42,7 @@ public class FluidTankTileEntity extends SmartTileEntity { protected boolean forceFluidLevelUpdate; protected FluidTank tankInventory; protected BlockPos controller; + protected BlockPos lastKnownPos; protected boolean updateConnectivity; protected boolean window; protected int luminosity; @@ -88,6 +89,14 @@ public class FluidTankTileEntity extends SmartTileEntity { if (syncCooldown == 0 && queuedSync) sendData(); } + + if (lastKnownPos == null) + lastKnownPos = getPos(); + else if (!lastKnownPos.equals(pos) && pos != null) { + onPositionChanged(); + return; + } + if (updateConnectivity) updateConnectivity(); if (fluidLevel != null) @@ -104,6 +113,11 @@ public class FluidTankTileEntity extends SmartTileEntity { sendData(); } + private void onPositionChanged() { + removeController(true); + lastKnownPos = pos; + } + protected void onFluidStackChanged(FluidStack newFluidStack) { if (!hasWorld()) return; @@ -163,11 +177,12 @@ public class FluidTankTileEntity extends SmartTileEntity { forceFluidLevelUpdate = true; } - public void removeController() { + public void removeController(boolean keepFluids) { if (world.isRemote) return; updateConnectivity = true; - applyFluidTankSize(1); + if (!keepFluids) + applyFluidTankSize(1); controller = null; width = 1; height = 1; @@ -292,7 +307,10 @@ public class FluidTankTileEntity extends SmartTileEntity { updateConnectivity = compound.contains("Uninitialized"); luminosity = compound.getInt("Luminosity"); controller = null; + lastKnownPos = null; + if (compound.contains("LastKnownPos")) + lastKnownPos = NBTUtil.readBlockPos(compound.getCompound("LastKnownPos")); if (compound.contains("Controller")) controller = NBTUtil.readBlockPos(compound.getCompound("Controller")); @@ -336,7 +354,7 @@ public class FluidTankTileEntity extends SmartTileEntity { fluidLevel.withSpeed(compound.contains("LazySync") ? 1 / 8f : 1 / 2f); } - protected float getFillState() { + public float getFillState() { return (float) tankInventory.getFluidAmount() / tankInventory.getCapacity(); } @@ -344,6 +362,8 @@ public class FluidTankTileEntity extends SmartTileEntity { public void write(CompoundNBT compound, boolean clientPacket) { if (updateConnectivity) compound.putBoolean("Uninitialized", true); + if (lastKnownPos != null) + compound.put("LastKnownPos", NBTUtil.writeBlockPos(lastKnownPos)); if (!isController()) compound.put("Controller", NBTUtil.writeBlockPos(controller)); if (isController()) { @@ -394,12 +414,20 @@ public class FluidTankTileEntity extends SmartTileEntity { return MAX_SIZE; } - protected static int getCapacityMultiplier() { + public static int getCapacityMultiplier() { return AllConfigs.SERVER.fluids.fluidTankCapacity.get() * 1000; } public static int getMaxHeight() { return AllConfigs.SERVER.fluids.fluidTankMaxHeight.get(); } + + public InterpolatedChasingValue getFluidLevel() { + return fluidLevel; + } + + public void setFluidLevel(InterpolatedChasingValue fluidLevel) { + this.fluidLevel = fluidLevel; + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/goggles/GoggleOverlayRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/goggles/GoggleOverlayRenderer.java index 78eac7b00..ba2620724 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/goggles/GoggleOverlayRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/goggles/GoggleOverlayRenderer.java @@ -4,16 +4,23 @@ import java.util.ArrayList; import java.util.List; import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.AllBlocks; import com.simibubi.create.AllItems; +import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock; +import com.simibubi.create.content.contraptions.components.structureMovement.piston.PistonExtensionPoleBlock; +import com.simibubi.create.content.contraptions.components.structureMovement.piston.PistonPolePlacementHelper; import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.gui.GuiGameElement; +import com.simibubi.create.foundation.utility.Iterate; +import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.world.ClientWorld; import net.minecraft.inventory.EquipmentSlotType; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.RayTraceResult; @@ -28,7 +35,6 @@ import net.minecraftforge.fml.common.Mod.EventBusSubscriber; @EventBusSubscriber(value = Dist.CLIENT) public class GoggleOverlayRenderer { - @SubscribeEvent public static void lookingAtBlocksThroughGogglesShowsTooltip(RenderGameOverlayEvent.Post event) { MatrixStack ms = event.getMatrixStack(); @@ -43,51 +49,83 @@ public class GoggleOverlayRenderer { Minecraft mc = Minecraft.getInstance(); ClientWorld world = mc.world; BlockPos pos = result.getPos(); - ItemStack goggles = mc.player.getItemStackFromSlot(EquipmentSlotType.HEAD); + ItemStack headSlot = mc.player.getItemStackFromSlot(EquipmentSlotType.HEAD); TileEntity te = world.getTileEntity(pos); - boolean goggleInformation = te instanceof IHaveGoggleInformation; - boolean hoveringInformation = te instanceof IHaveHoveringInformation; + boolean wearingGoggles = AllItems.GOGGLES.isIn(headSlot); - if (!goggleInformation && !hoveringInformation) - return; + boolean hasGoggleInformation = te instanceof IHaveGoggleInformation; + boolean hasHoveringInformation = te instanceof IHaveHoveringInformation; + + boolean goggleAddedInformation = false; + boolean hoverAddedInformation = false; List tooltip = new ArrayList<>(); - if (goggleInformation && AllItems.GOGGLES.isIn(goggles)) { + if (hasGoggleInformation && wearingGoggles) { IHaveGoggleInformation gte = (IHaveGoggleInformation) te; - if (!gte.addToGoggleTooltip(tooltip, mc.player.isSneaking())) - goggleInformation = false; + goggleAddedInformation = gte.addToGoggleTooltip(tooltip, mc.player.isSneaking()); } - if (hoveringInformation) { - boolean goggleAddedInformation = !tooltip.isEmpty(); - if (goggleAddedInformation) + if (hasHoveringInformation) { + if (!tooltip.isEmpty()) tooltip.add(StringTextComponent.EMPTY); IHaveHoveringInformation hte = (IHaveHoveringInformation) te; - if (!hte.addToTooltip(tooltip, mc.player.isSneaking())) - hoveringInformation = false; - if (goggleAddedInformation && !hoveringInformation) + hoverAddedInformation = hte.addToTooltip(tooltip, mc.player.isSneaking()); + + if (goggleAddedInformation && !hoverAddedInformation) tooltip.remove(tooltip.size() - 1); } - if (!goggleInformation && !hoveringInformation) + // break early if goggle or hover returned false when present + if ((hasGoggleInformation && !goggleAddedInformation) && (hasHoveringInformation && !hoverAddedInformation)) return; + + // check for piston poles if goggles are worn + BlockState state = world.getBlockState(pos); + if (wearingGoggles && AllBlocks.PISTON_EXTENSION_POLE.has(state)) { + Direction[] directions = Iterate.directionsInAxis(state.get(PistonExtensionPoleBlock.FACING) + .getAxis()); + int poles = 1; + boolean pistonFound = false; + for (Direction dir : directions) { + int attachedPoles = PistonPolePlacementHelper.attachedPoles(world, pos, dir); + poles += attachedPoles; + pistonFound |= world.getBlockState(pos.offset(dir, attachedPoles + 1)) + .getBlock() instanceof MechanicalPistonBlock; + } + + if (!pistonFound) + return; + if (!tooltip.isEmpty()) + tooltip.add(StringTextComponent.EMPTY); + + tooltip.add(IHaveGoggleInformation.componentSpacing.copy().append(new StringTextComponent("Pole length: " + poles))); + } + if (tooltip.isEmpty()) return; ms.push(); Screen tooltipScreen = new TooltipScreen(null); - tooltipScreen.init(mc, mc.getWindow().getScaledWidth(), mc.getWindow().getScaledHeight()); + tooltipScreen.init(mc, mc.getWindow() + .getScaledWidth(), + mc.getWindow() + .getScaledHeight()); int posX = tooltipScreen.width / 2 + AllConfigs.CLIENT.overlayOffsetX.get(); int posY = tooltipScreen.height / 2 + AllConfigs.CLIENT.overlayOffsetY.get(); + // tooltipScreen.renderTooltip(tooltip, tooltipScreen.width / 2, + // tooltipScreen.height / 2); tooltipScreen.renderTooltip(ms, tooltip, posX, posY); ItemStack item = AllItems.GOGGLES.asStack(); - GuiGameElement.of(item).atLocal(posX + 10, posY, 450).render(ms); + // GuiGameElement.of(item).at(tooltipScreen.width / 2 + 10, tooltipScreen.height + // / 2 - 16).render(); + GuiGameElement.of(item) + .atLocal(posX + 10, posY, 450) + .render(ms); ms.pop(); } - private static final class TooltipScreen extends Screen { private TooltipScreen(ITextComponent p_i51108_1_) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinMovementBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinMovementBehaviour.java index d3d70b61e..dbf18420b 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinMovementBehaviour.java @@ -8,6 +8,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Mov import net.minecraft.entity.item.ItemEntity; import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.math.vector.Vector3d; import net.minecraftforge.items.ItemStackHandler; @@ -51,10 +52,9 @@ public class BasinMovementBehaviour extends MovementBehaviour { } context.tileData.put(key, itemStackHandler.serializeNBT()); }); - context.contraption.renderedTileEntities.stream() - .filter(te -> te.getPos() - .equals(context.localPos) && te instanceof BasinTileEntity) - .forEach(te -> ((BasinTileEntity) te).readOnlyItems(context.tileData)); + TileEntity tileEntity = context.contraption.renderedTileEntities.get(context.localPos); + if (tileEntity instanceof BasinTileEntity) + ((BasinTileEntity) tileEntity).readOnlyItems(context.tileData); context.temporaryData = false; // did already dump, so can't any more } } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/inventories/CrateBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/inventories/CrateBlock.java index 12ff27a6e..a54b6b92b 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/inventories/CrateBlock.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/inventories/CrateBlock.java @@ -3,7 +3,6 @@ package com.simibubi.create.content.logistics.block.inventories; import com.simibubi.create.AllShapes; import com.simibubi.create.content.contraptions.wrench.IWrenchable; import com.simibubi.create.foundation.block.ProperDirectionalBlock; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.item.BlockItemUseContext; @@ -80,6 +79,11 @@ public class CrateBlock extends ProperDirectionalBlock implements IWrenchable { return getDefaultState(); } + @Override + public BlockState getRotatedBlockState(BlockState originalState, Direction targetedFace) { + return originalState; + } + @Override protected void fillStateContainer(Builder builder) { super.fillStateContainer(builder.add(DOUBLE)); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/redstone/RedstoneContactBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/redstone/RedstoneContactBlock.java index 5815f778b..a467c4cd4 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/redstone/RedstoneContactBlock.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/redstone/RedstoneContactBlock.java @@ -1,14 +1,7 @@ package com.simibubi.create.content.logistics.block.redstone; -import java.util.Random; - -import javax.annotation.Nullable; -import javax.annotation.ParametersAreNonnullByDefault; - import com.simibubi.create.AllBlocks; -import com.simibubi.create.content.contraptions.wrench.IWrenchable; import com.simibubi.create.foundation.block.ProperDirectionalBlock; - import mcp.MethodsReturnNonnullByDefault; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -23,9 +16,13 @@ import net.minecraft.world.IWorld; import net.minecraft.world.World; import net.minecraft.world.server.ServerWorld; +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.Random; + @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault -public class RedstoneContactBlock extends ProperDirectionalBlock implements IWrenchable { +public class RedstoneContactBlock extends ProperDirectionalBlock { public static final BooleanProperty POWERED = BlockStateProperties.POWERED; diff --git a/src/main/java/com/simibubi/create/content/logistics/block/redstone/RedstoneLinkBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/redstone/RedstoneLinkBlock.java index 5251907a7..c16a548c9 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/redstone/RedstoneLinkBlock.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/redstone/RedstoneLinkBlock.java @@ -2,13 +2,11 @@ package com.simibubi.create.content.logistics.block.redstone; import com.simibubi.create.AllShapes; import com.simibubi.create.AllTileEntities; -import com.simibubi.create.content.contraptions.wrench.IWrenchable; import com.simibubi.create.content.logistics.block.funnel.FunnelBlock; import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.block.ProperDirectionalBlock; import com.simibubi.create.foundation.utility.BlockHelper; import com.simibubi.create.foundation.utility.Iterate; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; @@ -29,7 +27,7 @@ import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorldReader; import net.minecraft.world.World; -public class RedstoneLinkBlock extends ProperDirectionalBlock implements ITE, IWrenchable { +public class RedstoneLinkBlock extends ProperDirectionalBlock implements ITE { public static final BooleanProperty POWERED = BlockStateProperties.POWERED; public static final BooleanProperty RECEIVER = BooleanProperty.create("receiver"); @@ -153,7 +151,12 @@ public class RedstoneLinkBlock extends ProperDirectionalBlock implements ITE b.key('I', AllBlocks.REDSTONE_CONTACT.get()) + .viaShaped(b -> b.key('I', I.brassCasing()) + .key('B', AllBlocks.ANDESITE_FUNNEL.get()) + .patternLine(" B ") + .patternLine(" I ")), + + PORTABLE_FLUID_INTERFACE = create(AllBlocks.PORTABLE_FLUID_INTERFACE).unlockedBy(I::copperCasing) + .viaShaped(b -> b.key('I', I.copperCasing()) .key('B', AllBlocks.ANDESITE_FUNNEL.get()) .patternLine(" B ") .patternLine(" I ")), diff --git a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java index ebbea38e4..841357ad0 100644 --- a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java +++ b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java @@ -5,9 +5,11 @@ import java.util.function.Function; import java.util.function.Supplier; import com.simibubi.create.Create; +import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionDisassemblyPacket; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionStallPacket; import com.simibubi.create.content.contraptions.components.structureMovement.glue.GlueEffectPacket; import com.simibubi.create.content.contraptions.components.structureMovement.sync.ClientMotionPacket; +import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionFluidPacket; import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionInteractionPacket; import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionSeatMappingPacket; import com.simibubi.create.content.contraptions.components.structureMovement.sync.LimbSwingUpdatePacket; @@ -25,8 +27,8 @@ import com.simibubi.create.content.logistics.packet.ConfigureStockswitchPacket; import com.simibubi.create.content.schematics.packet.ConfigureSchematicannonPacket; import com.simibubi.create.content.schematics.packet.InstantSchematicPacket; import com.simibubi.create.content.schematics.packet.SchematicPlacePacket; -import com.simibubi.create.content.schematics.packet.SchematicUploadPacket; import com.simibubi.create.content.schematics.packet.SchematicSyncPacket; +import com.simibubi.create.content.schematics.packet.SchematicUploadPacket; import com.simibubi.create.foundation.command.ConfigureConfigPacket; import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringCountUpdatePacket; import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollValueUpdatePacket; @@ -69,11 +71,13 @@ public enum AllPackets { BEAM_EFFECT(ZapperBeamPacket.class, ZapperBeamPacket::new), CONFIGURE_CONFIG(ConfigureConfigPacket.class, ConfigureConfigPacket::new), CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::new), + CONTRAPTION_DISASSEMBLE(ContraptionDisassemblyPacket.class, ContraptionDisassemblyPacket::new), GLUE_EFFECT(GlueEffectPacket.class, GlueEffectPacket::new), CONTRAPTION_SEAT_MAPPING(ContraptionSeatMappingPacket.class, ContraptionSeatMappingPacket::new), LIMBSWING_UPDATE(LimbSwingUpdatePacket.class, LimbSwingUpdatePacket::new), MINECART_CONTROLLER(MinecartControllerUpdatePacket.class, MinecartControllerUpdatePacket::new), FLUID_SPLASH(FluidSplashPacket.class, FluidSplashPacket::new), + CONTRAPTION_FLUID(ContraptionFluidPacket.class, ContraptionFluidPacket::new), ; diff --git a/src/main/java/com/simibubi/create/foundation/utility/Iterate.java b/src/main/java/com/simibubi/create/foundation/utility/Iterate.java index bf6fe0122..84e7cccd1 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/Iterate.java +++ b/src/main/java/com/simibubi/create/foundation/utility/Iterate.java @@ -1,17 +1,17 @@ package com.simibubi.create.foundation.utility; -import java.util.Arrays; -import java.util.List; - import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; +import java.util.Arrays; +import java.util.List; + public class Iterate { - public static final boolean[] trueAndFalse = { true, false }; - public static final int[] zeroAndOne = { 0, 1 }; - public static final int[] positiveAndNegative = { 1, -1 }; + public static final boolean[] trueAndFalse = {true, false}; + public static final int[] zeroAndOne = {0, 1}; + public static final int[] positiveAndNegative = {1, -1}; public static final Direction[] directions = Direction.values(); public static final Direction[] horizontalDirections = getHorizontals(); public static final Axis[] axes = Axis.values(); @@ -22,10 +22,20 @@ public class Iterate { directions[i] = Direction.byHorizontalIndex(i); return directions; } - + + public static Direction[] directionsInAxis(Axis axis) { + switch (axis) { + case X: + return new Direction[]{Direction.EAST, Direction.WEST}; + case Y: + return new Direction[]{Direction.UP, Direction.DOWN}; + default: + case Z: + return new Direction[]{Direction.SOUTH, Direction.NORTH}; + } + } + public static List hereAndBelow(BlockPos pos) { return Arrays.asList(pos, pos.down()); } - - } diff --git a/src/main/java/com/simibubi/create/foundation/utility/TileEntityRenderHelper.java b/src/main/java/com/simibubi/create/foundation/utility/TileEntityRenderHelper.java index 1fc14fd8c..7568ac0a3 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/TileEntityRenderHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/TileEntityRenderHelper.java @@ -12,7 +12,6 @@ import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.renderer.tileentity.TileEntityRenderer; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; -import net.minecraft.crash.ReportedException; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.vector.Matrix4f; @@ -20,14 +19,14 @@ import net.minecraft.util.math.vector.Vector4f; import net.minecraft.world.World; public class TileEntityRenderHelper { - + public static void renderTileEntities(World world, Iterable customRenderTEs, MatrixStack ms, MatrixStack localTransform, IRenderTypeBuffer buffer) { float pt = Minecraft.getInstance() .getRenderPartialTicks(); Matrix4f matrix = localTransform.peek() .getModel(); - + for (Iterator iterator = customRenderTEs.iterator(); iterator.hasNext();) { TileEntity tileEntity = iterator.next(); TileEntityRenderer renderer = TileEntityRendererDispatcher.instance.getRenderer(tileEntity); @@ -49,17 +48,18 @@ public class TileEntityRenderHelper { OverlayTexture.DEFAULT_UV); ms.pop(); - } catch (ReportedException e) { - if (AllConfigs.CLIENT.explainRenderErrors.get()) { - Create.logger.error("TileEntity " + tileEntity.getType() - .getRegistryName() - .toString() + " didn't want to render while moved.\n", e); - } else { - Create.logger.error("TileEntity " + tileEntity.getType() - .getRegistryName() - .toString() + " didn't want to render while moved.\n"); - } + } catch (Exception e) { iterator.remove(); + + String message = "TileEntity " + tileEntity.getType() + .getRegistryName() + .toString() + " didn't want to render while moved.\n"; + if (AllConfigs.CLIENT.explainRenderErrors.get()) { + Create.logger.error(message, e); + continue; + } + + Create.logger.error(message); continue; } } diff --git a/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/PlacementSimulationWorld.java b/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/PlacementSimulationWorld.java index c01cc95c6..ee209d16f 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/PlacementSimulationWorld.java +++ b/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/PlacementSimulationWorld.java @@ -1,21 +1,30 @@ package com.simibubi.create.foundation.utility.worldWrappers; +import java.util.Collection; import java.util.HashMap; import java.util.function.Predicate; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; public class PlacementSimulationWorld extends WrappedWorld { public HashMap blocksAdded; + public HashMap tesAdded; public PlacementSimulationWorld(World wrapped) { super(wrapped); blocksAdded = new HashMap<>(); + tesAdded = new HashMap<>(); } - + + public void setTileEntities(Collection tileEntities) { + tesAdded.clear(); + tileEntities.forEach(te -> tesAdded.put(te.getPos(), te)); + } + public void clear() { blocksAdded.clear(); } @@ -31,16 +40,21 @@ public class PlacementSimulationWorld extends WrappedWorld { return setBlockState(pos, state, 0); } + @Override + public TileEntity getTileEntity(BlockPos pos) { + return tesAdded.get(pos); + } + @Override public boolean hasBlockState(BlockPos pos, Predicate condition) { return condition.test(getBlockState(pos)); } - + @Override public boolean isBlockPresent(BlockPos pos) { return true; } - + @Override public boolean isAreaLoaded(BlockPos center, int range) { return true; @@ -52,5 +66,5 @@ public class PlacementSimulationWorld extends WrappedWorld { return blocksAdded.get(pos); return Blocks.AIR.getDefaultState(); } - + } diff --git a/src/main/resources/assets/create/models/block/hose_pulley/block.json b/src/main/resources/assets/create/models/block/hose_pulley/block.json index 4e251b554..78baefdcc 100644 --- a/src/main/resources/assets/create/models/block/hose_pulley/block.json +++ b/src/main/resources/assets/create/models/block/hose_pulley/block.json @@ -3,9 +3,9 @@ "parent": "block/block", "textures": { "4": "create:block/copper_gearbox", - "8": "create:block/oxidized/copper_block_0", + "8": "create:block/copper_plating", "9": "create:block/fluid_pipe", - "particle": "create:block/oxidized/copper_block_0" + "particle": "create:block/copper_plating" }, "elements": [ { diff --git a/src/main/resources/assets/create/models/block/hose_pulley/copper_pulley.bbmodel b/src/main/resources/assets/create/models/block/hose_pulley/copper_pulley.bbmodel deleted file mode 100644 index 341190326..000000000 --- a/src/main/resources/assets/create/models/block/hose_pulley/copper_pulley.bbmodel +++ /dev/null @@ -1 +0,0 @@ -{"meta":{"format_version":"3.2","model_format":"java_block","box_uv":false},"name":"item","parent":"block/block","ambientocclusion":true,"resolution":{"width":16,"height":16},"elements":[{"name":"coil","from":[4,4,2],"to":[12,12,14],"autouv":0,"color":6,"rotation":[0,0,-45],"origin":[8,8,-10],"faces":{"north":{"uv":[0,0,0,0],"texture":null},"east":{"uv":[2,1,14,9],"texture":3},"south":{"uv":[0,0,0,0],"texture":null},"west":{"uv":[2,1,14,9],"rotation":180,"texture":3},"up":{"uv":[2,1,14,9],"rotation":270,"texture":3},"down":{"uv":[2,1,14,9],"rotation":90,"texture":3}},"uuid":"c6880831-d683-f703-04a3-fd39148ebb5c"},{"name":"coil","from":[3.5,3.5,3],"to":[12.5,12.5,7],"autouv":0,"color":6,"rotation":[0,0,45],"origin":[8,8,-10],"faces":{"north":{"uv":[0,0,1,1],"texture":3},"east":{"uv":[0,3,4,12],"rotation":180,"texture":3},"south":{"uv":[0,0,1,1],"texture":3},"west":{"uv":[0,3,4,12],"texture":3},"up":{"uv":[0,3,4,12],"rotation":90,"texture":3},"down":{"uv":[0,3,4,12],"rotation":270,"texture":3}},"uuid":"d93793b9-dd62-5818-2564-da40eed87601"},{"name":"side","from":[2,2,14],"to":[14,14,15],"autouv":0,"color":2,"origin":[8,-8,8],"faces":{"north":{"uv":[2,2,14,14],"texture":2},"east":{"uv":[0,0,0,0],"texture":null},"south":{"uv":[2,2,14,14],"texture":2},"west":{"uv":[0,0,0,0],"texture":null},"up":{"uv":[0,0,1,12],"rotation":270},"down":{"uv":[2,11,14,12],"texture":2}},"uuid":"50235661-64a5-c971-c6e6-0975baa71d99"},{"name":"side","from":[2,2,1],"to":[14,14,2],"autouv":0,"color":3,"origin":[8,-8,8],"faces":{"north":{"uv":[14,2,2,14],"texture":5},"east":{"uv":[0,0,0,0],"texture":null},"south":{"uv":[14,2,2,14],"texture":5},"west":{"uv":[0,0,0,0],"texture":null},"up":{"uv":[1,0,0,12],"rotation":270},"down":{"uv":[2,12,14,11],"texture":2}},"uuid":"f16b6f4f-7c00-62c6-e29b-a9d790a92d84"},{"name":"side_frame","from":[0,2,14],"to":[2,14,16],"autouv":0,"color":3,"origin":[8,1,8],"faces":{"north":{"uv":[14,2,16,14],"texture":5},"east":{"uv":[0,2,2,14],"texture":5},"south":{"uv":[14,2,16,14],"rotation":180,"texture":5},"west":{"uv":[14,2,16,14],"texture":5},"up":{"uv":[0,14,2,16],"texture":5},"down":{"uv":[0,0,2,2],"texture":5}},"uuid":"8e0b92f4-fea1-c76e-eec7-fa197247034b"},{"name":"side_frame","from":[0,2,0],"to":[2,14,2],"autouv":0,"color":6,"origin":[8,1,8],"faces":{"north":{"uv":[16,2,14,14],"rotation":180,"texture":5},"east":{"uv":[2,2,0,14],"texture":5},"south":{"uv":[16,2,14,14],"texture":5},"west":{"uv":[16,2,14,14],"texture":5},"up":{"uv":[0,16,2,14],"texture":5},"down":{"uv":[0,2,2,0],"texture":5}},"uuid":"c6e4de46-37af-8304-d04a-e3a06202a6d1"},{"name":"side_frame","from":[14,2,14],"to":[16,14,16],"autouv":0,"color":7,"origin":[8,1,8],"faces":{"north":{"uv":[2,2,0,14],"rotation":180,"texture":5},"east":{"uv":[16,2,14,14],"texture":5},"south":{"uv":[16,2,14,14],"rotation":180,"texture":5},"west":{"uv":[2,2,0,14],"texture":5},"up":{"uv":[2,14,0,16],"texture":5},"down":{"uv":[2,0,0,2],"texture":5}},"uuid":"22157158-613c-9abb-d3b9-2a2d576e1f98"},{"name":"side_frame","from":[14,2,0],"to":[16,14,2],"autouv":0,"color":5,"origin":[8,1,8],"faces":{"north":{"uv":[14,2,16,14],"rotation":180,"texture":5},"east":{"uv":[14,2,16,14],"texture":5},"south":{"uv":[0,2,2,14],"rotation":180,"texture":5},"west":{"uv":[0,2,2,14],"texture":5},"up":{"uv":[2,16,0,14],"texture":5},"down":{"uv":[2,2,0,0],"texture":5}},"uuid":"82c9a138-92db-c34a-f8e7-45283db7413d"},{"name":"side_frame","from":[0,0,14],"to":[16,2,16],"autouv":0,"color":3,"origin":[8,1,8],"faces":{"north":{"uv":[0,14,16,16],"texture":5},"east":{"uv":[0,14,2,16],"texture":5},"south":{"uv":[0,14,16,16],"texture":5},"west":{"uv":[14,14,16,16],"texture":5},"up":{"uv":[0,14,16,16],"rotation":180,"texture":5},"down":{"uv":[0,14,16,16],"rotation":180,"texture":5}},"uuid":"6965d55e-49aa-ab6d-4568-5de4c1501c57"},{"name":"side_frame","from":[0,14,14],"to":[16,16,16],"autouv":0,"color":2,"origin":[8,15,8],"faces":{"north":{"uv":[0,16,16,14],"texture":5},"east":{"uv":[0,16,2,14],"texture":5},"south":{"uv":[0,16,16,14],"texture":5},"west":{"uv":[14,16,16,14],"texture":5},"up":{"uv":[0,16,16,14],"rotation":180,"texture":5},"down":{"uv":[0,16,16,14],"rotation":180,"texture":5}},"uuid":"639134c9-125c-c945-7ece-ee0b946543c7"},{"name":"side_frame","from":[0,0,0],"to":[16,2,2],"autouv":0,"color":2,"origin":[8,1,8],"faces":{"north":{"uv":[16,14,0,16],"texture":5},"east":{"uv":[2,14,0,16],"texture":5},"south":{"uv":[16,14,0,16],"texture":5},"west":{"uv":[16,14,14,16],"texture":5},"up":{"uv":[0,16,16,14],"rotation":180,"texture":5},"down":{"uv":[0,14,16,16],"texture":5}},"uuid":"b27e1c88-26b6-190b-f005-a259810655a1"},{"name":"side_frame","from":[0,14,0],"to":[16,16,2],"autouv":0,"color":6,"origin":[8,15,8],"faces":{"north":{"uv":[16,16,0,14],"texture":5},"east":{"uv":[2,16,0,14],"texture":5},"south":{"uv":[16,16,0,14],"texture":5},"west":{"uv":[16,16,14,14],"texture":5},"up":{"uv":[0,16,16,14],"texture":5},"down":{"uv":[0,14,16,16],"rotation":180,"texture":5}},"uuid":"e06d0f90-92de-1302-190a-fbd10c267e74"},{"name":"front","from":[1,1,2],"to":[3,3,14],"autouv":0,"color":1,"origin":[8,-8,8],"faces":{"north":{"uv":[0,0,0,0],"texture":5},"east":{"uv":[2,14,14,16],"rotation":180,"texture":5},"south":{"uv":[0,0,0,0],"texture":5},"west":{"uv":[2,14,14,16],"texture":5},"up":{"uv":[2,0,14,2],"rotation":270,"texture":5},"down":{"uv":[2,14,14,16],"rotation":90,"texture":5}},"uuid":"8f39075d-3ce3-b4f6-6ef0-6bb131af4333"},{"name":"front","from":[13,1,2],"to":[15,3,14],"autouv":0,"color":1,"origin":[8,-8,8],"faces":{"north":{"uv":[0,0,0,0],"texture":5},"east":{"uv":[14,14,2,16],"texture":5},"south":{"uv":[0,0,0,0],"texture":5},"west":{"uv":[14,14,2,16],"rotation":180,"texture":5},"up":{"uv":[2,2,14,0],"rotation":90,"texture":5},"down":{"uv":[2,16,14,14],"rotation":90,"texture":5}},"uuid":"4af7b711-49e2-96cc-804f-025c079ee52f"},{"name":"front","from":[13,13,2],"to":[15,15,14],"autouv":0,"color":1,"origin":[8,10,8],"faces":{"north":{"uv":[0,0,0,0],"texture":5},"east":{"uv":[14,16,2,14],"texture":5},"south":{"uv":[0,0,0,0],"texture":5},"west":{"uv":[14,2,2,0],"texture":5},"up":{"uv":[14,15,2,13],"rotation":90,"texture":5},"down":{"uv":[14,2,2,0],"rotation":90,"texture":5}},"uuid":"ecde023c-1297-0247-44c2-571ac0de9df1"},{"name":"front","from":[1,13,2],"to":[3,15,14],"autouv":0,"color":0,"origin":[8,10,8],"faces":{"north":{"uv":[0,0,0,0],"texture":5},"east":{"uv":[2,2,14,0],"texture":5},"south":{"uv":[0,0,0,0],"texture":5},"west":{"uv":[2,16,14,14],"texture":5},"up":{"uv":[14,13,2,15],"rotation":90,"texture":5},"down":{"uv":[14,0,2,2],"rotation":270,"texture":5}},"uuid":"b062f25c-f8f3-548b-2f46-fc6bb96083b3"},{"name":"Axis","from":[6,6,8],"to":[10,10,16],"autouv":0,"color":5,"origin":[8,1,16],"faces":{"north":{"uv":[0,0,0,0],"rotation":180,"texture":null},"east":{"uv":[6,8,10,16],"rotation":90,"texture":0},"south":{"uv":[6,6,10,10],"texture":1},"west":{"uv":[6,8,10,16],"rotation":270,"texture":0},"up":{"uv":[6,8,10,16],"texture":0},"down":{"uv":[6,8,10,16],"rotation":180,"texture":0}},"uuid":"e3b9c976-9f92-23c7-9744-b6d5f4bca3b8"},{"name":"rope","from":[6,2,6],"to":[10,8,10],"autouv":0,"color":6,"origin":[7.75,13,8],"faces":{"north":{"uv":[12,10,16,16],"texture":4},"east":{"uv":[12,10,16,16],"texture":4},"south":{"uv":[12,10,16,16],"texture":4},"west":{"uv":[12,10,16,16],"texture":4},"up":{"uv":[12,0,16,4],"rotation":90,"texture":4},"down":{"uv":[0,0,0,0],"texture":null}},"uuid":"ffe805a0-fba3-54be-ff6f-ea4d1c3bd848"},{"name":"top","from":[2,14,2],"to":[14,16,14],"autouv":0,"color":6,"origin":[8,10,8],"faces":{"north":{"uv":[0,0,0,0],"texture":5},"east":{"uv":[2,1,14,3],"rotation":180,"texture":5},"south":{"uv":[0,0,0,0],"texture":5},"west":{"uv":[2,13,14,15],"texture":5},"up":{"uv":[2,2,14,14],"rotation":90,"texture":5},"down":{"uv":[2,2,14,14],"rotation":90,"texture":5}},"uuid":"06ae5406-365f-7935-e0d8-7832b0a3aaf9"},{"name":"coil","from":[3.5,3.5,9],"to":[12.5,12.5,13],"autouv":0,"color":6,"rotation":[0,0,45],"origin":[8,8,-4],"faces":{"north":{"uv":[0,0,1,1],"texture":3},"east":{"uv":[0,3,4,12],"rotation":180,"texture":3},"south":{"uv":[0,0,1,1],"texture":3},"west":{"uv":[0,3,4,12],"texture":3},"up":{"uv":[0,3,4,12],"rotation":90,"texture":3},"down":{"uv":[0,3,4,12],"rotation":270,"texture":3}},"uuid":"4a787d9b-a04d-eafd-9dc3-ae1b61869b56"},{"name":"side","from":[3,3,-1],"to":[13,13,1],"autouv":0,"color":3,"origin":[9,-7,7],"faces":{"north":{"uv":[11,0,6,5],"texture":6},"east":{"uv":[11,5,6,6],"rotation":90,"texture":6},"south":{"uv":[0,0,0,0],"texture":null},"west":{"uv":[11,5,6,6],"rotation":270,"texture":6},"up":{"uv":[11,5,6,6],"texture":6},"down":{"uv":[11,5,6,6],"rotation":180,"texture":6}},"uuid":"79d24535-547d-b692-62e2-bcb231a40b02"},{"name":"drain 1","from":[4.5,0,4.5],"to":[11.5,2,11.5],"autouv":0,"color":6,"origin":[6.75,14,6],"faces":{"north":{"uv":[0,0,7,2],"texture":4},"east":{"uv":[0,0,7,2],"texture":4},"south":{"uv":[0,0,7,2],"texture":4},"west":{"uv":[0,0,7,2],"texture":4},"up":{"uv":[0,0,0,0],"rotation":90,"texture":null},"down":{"uv":[0,2,7,9],"texture":4}},"uuid":"6bb4086f-6bf3-c374-3149-743ee69bfa01"},{"name":"drain 2","from":[4.5,2,4.5],"to":[11.5,3,11.5],"autouv":0,"color":6,"origin":[6.75,16,6],"faces":{"north":{"uv":[0,1,7,2],"texture":4},"east":{"uv":[0,1,7,2],"texture":4},"south":{"uv":[0,1,7,2],"texture":4},"west":{"uv":[0,1,7,2],"texture":4},"up":{"uv":[0,2,7,9],"rotation":90,"texture":4},"down":{"uv":[0,9,7,16],"texture":4}},"uuid":"fb8d9297-4cd4-2fe4-bca4-663c7a4bdb9d"},{"name":"drain 3","from":[5.5,2,5.5],"to":[10.5,5,10.5],"autouv":0,"color":6,"origin":[7.75,16,7],"faces":{"north":{"uv":[7,2,10,7],"rotation":270,"texture":4},"east":{"uv":[7,2,10,7],"rotation":270,"texture":4},"south":{"uv":[7,2,10,7],"rotation":270,"texture":4},"west":{"uv":[7,2,10,7],"rotation":270,"texture":4},"up":{"uv":[1,3,6,8],"rotation":90,"texture":4},"down":{"uv":[0,0,0,0],"texture":null}},"uuid":"f725e5f1-25eb-7f7a-da81-22f68d165e4b"}],"outliner":["c6880831-d683-f703-04a3-fd39148ebb5c","d93793b9-dd62-5818-2564-da40eed87601","4a787d9b-a04d-eafd-9dc3-ae1b61869b56","50235661-64a5-c971-c6e6-0975baa71d99","f16b6f4f-7c00-62c6-e29b-a9d790a92d84","79d24535-547d-b692-62e2-bcb231a40b02","8e0b92f4-fea1-c76e-eec7-fa197247034b","c6e4de46-37af-8304-d04a-e3a06202a6d1","22157158-613c-9abb-d3b9-2a2d576e1f98","82c9a138-92db-c34a-f8e7-45283db7413d","6965d55e-49aa-ab6d-4568-5de4c1501c57","639134c9-125c-c945-7ece-ee0b946543c7","b27e1c88-26b6-190b-f005-a259810655a1","e06d0f90-92de-1302-190a-fbd10c267e74","8f39075d-3ce3-b4f6-6ef0-6bb131af4333","4af7b711-49e2-96cc-804f-025c079ee52f","ecde023c-1297-0247-44c2-571ac0de9df1","b062f25c-f8f3-548b-2f46-fc6bb96083b3",{"name":"shaft","uuid":"93605e08-38e8-a8a7-4837-dba968998c73","export":true,"isOpen":false,"visibility":true,"autouv":0,"origin":[8,8,8],"children":["e3b9c976-9f92-23c7-9744-b6d5f4bca3b8"]},{"name":"rope_half_magnet","uuid":"4fe97f9a-28c6-d38d-a405-2cdf8eca9b88","export":true,"isOpen":true,"visibility":true,"autouv":0,"origin":[8,8,8],"children":["ffe805a0-fba3-54be-ff6f-ea4d1c3bd848","6bb4086f-6bf3-c374-3149-743ee69bfa01","fb8d9297-4cd4-2fe4-bca4-663c7a4bdb9d","f725e5f1-25eb-7f7a-da81-22f68d165e4b"]},"06ae5406-365f-7935-e0d8-7832b0a3aaf9"],"textures":[{"path":"C:\\Users\\simon\\Desktop\\Forge 15\\Create\\src\\main\\resources\\assets\\create\\textures\\block\\axis.png","name":"axis.png","folder":"block","namespace":"create","id":"0","particle":false,"mode":"bitmap","saved":true,"uuid":"3faf49c5-68db-fed3-b4ca-030214e86e3e","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAo0lEQVQ4T6WTIQ4EIQxFO4IRIECAgLshMBwKO+fCggWDZVOSSVbMJjulkpTH/+X3gB/lvZ/WWhhjQO8drus6nlofD7ExhDCFEOsOGcAYA+cc5JzfK4gxTnxdKQW1VhrgPE/QWu8pQAulFEgpvRvit4XWGg2AFjjnQAJgDqSUawYkC3eQUAEJgEEyxiwLpBxsA/AXMERYW0FCCyTAvUxkwL/r/AGRGnYRGJZooQAAAABJRU5ErkJggg=="},{"path":"C:\\Users\\simon\\Desktop\\Forge 15\\Create\\src\\main\\resources\\assets\\create\\textures\\block\\axis_top.png","name":"axis_top.png","folder":"block","namespace":"create","id":"1","particle":false,"mode":"bitmap","saved":true,"uuid":"8065816d-f585-f9e5-bf22-5659e0bd657b","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAaklEQVQ4T+2SMQ4AERBFv16h5W5atcohVGrXJBOhmL3A2rBa089L/ssTODxx+I8LwNyBc46VUui9g4iQc371NZXovWdjDFprqLUixrgHCCGwlBJjDJRSkFLaA1hrWWv9f8JqYDekj5BWJT4NbygR50R18wAAAABJRU5ErkJggg=="},{"path":"C:\\Users\\simon\\Desktop\\Forge 15\\Create\\src\\main\\resources\\assets\\create\\textures\\block\\copper_gearbox.png","name":"copper_gearbox.png","folder":"block","namespace":"create","id":"4","particle":false,"mode":"bitmap","saved":true,"uuid":"374c5dbd-5856-5c1a-324e-d8464907f61e","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAB/0lEQVQ4T42TQWsTQRTH/7PpbjRxd000TVYaIghWWSjSetBDLdSoICzaDyPevflJ/AA59eihkiiIRCSoBLu6dtNsm6VJU7JJN5GZYbKbhoBzmXnvzfzm/+bNI29flieIjeBsjGRKmnqoTUfcJ4I0Rt483Z7sWGtxBlufDLozvvA4YHbiWpLNnd8+9hpdDth+chOVXRurGYXfphA2B0MuTtiCWD8M2N5Gux8B7C8tFm96gzk1wkHTWEnzSyh8CthaN+D88dnhfj9E08ih5bpQFAWaroMQgkQigVuuh2xOxt2iCudvgF/HpyCvy48nz+8XpoDq0iV28GOthsN2m92WX16GUSiw9YtcBvdWdQawu0EEaHfO0Ng/wR6R8bVex4HrzqRywzBgmiY2pTEDHLUG+O4P5xV8TmmoVCoIw3AGQFOwLAsPcYoHd/JoNjscIKrg/vSZgv8FfPvh8xQEgFbB6Q9RJSpq1erCFMpXwBRQAHvEi4BPS1dx4DjYt+2ZR1zf2MCR52HHUOcBooxUQccb4f35ALIsI5PNQpIkVsbRaATT76GUT8O8nYkU0DJaz0oQH4lCxFAl/mniQ78MrBRjAJoCVfDug43NogY1m4SeTi38jTRA965d16KPVNJ4g/TG0e3Ujiu4GKOd2AvOQV5tPWId05vwtmUHCW/nuG+RpH+o0xp0yccJugAAAABJRU5ErkJggg=="},{"path":"C:\\Users\\simon\\Desktop\\Forge 15\\Create\\src\\main\\resources\\assets\\create\\textures\\block\\hose_pulley_rope.png","name":"hose_pulley_rope.png","folder":"block","namespace":"create","id":"5","particle":false,"mode":"bitmap","saved":true,"uuid":"36d79924-56fb-920d-44b5-79ac193e75bc","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAX0lEQVQ4T2M00tP4z8fLwfDp8w+GX7//MLCxsjCQwmfU0VT5r6IgwfDh0xe4IaTwGUddwEB5GLS1tf2Xl5dn0NDQYLhx4wbDw4cPGUjhMy5duvQ/uZpBlo2mgz/DIQwAKD7WmGK5ZIUAAAAASUVORK5CYII="},{"path":"C:\\Users\\simon\\Desktop\\Forge 15\\Create\\src\\main\\resources\\assets\\create\\textures\\block\\hose_pulley_magnet.png","name":"hose_pulley_magnet.png","folder":"block","namespace":"create","id":"6","particle":false,"mode":"bitmap","saved":true,"uuid":"e708a585-d298-4e3f-e1a3-6fe62e93581b","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABTElEQVQ4T2NkYGBgSLC2+r/g6DFGdBokhw6M9DT+8/FyMHz6/IPh1+8/DIwHK6L/f/z6jYGfm4uBWZid4e/bnwwwvn3HUkZ0A3Q0Vf6rKEgwfPj0BWwIXgNABl46/oJBVISdIXTWerBhGC7YlBv4/8nTnwwczP8Z2NkYGX7++s/w4y8jg4w0O4OQnCDYABDbbzLEAKwuuHv3HYOyshDcCzA+SAOILSLBATcAwwVHupP+P7zwgkHeQIKBn4OP4f6thwyf3/0E80HhATMMFh54XQALPHQXgFwHM4CkMID5GzkmSIoFbNFI/XQAisYLNz8yLD95CO7SSHM7BgN1fnjII3sBqwsypq/ESLIzMsPhAYcs2dbW9l9eXp5BQ0OD4caNGwyMoGhMbVmEYcDsmjgGm9J5GEl56dKl/2GaHz58CEnKpLgAIxaoEgaU5EYA9eFAmHAG4o8AAAAASUVORK5CYII="},{"path":"C:\\Users\\simon\\Desktop\\Forge 15\\Create\\src\\main\\resources\\assets\\create\\textures\\block\\oxidized\\copper_block_0.png","name":"copper_block_0.png","folder":"block/oxidized","namespace":"create","id":"8","particle":true,"mode":"bitmap","saved":true,"uuid":"7dd1a067-4a71-cdfe-245e-baad08910bcc","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAB9ElEQVQ4T22TXUsbURCG31VIaswmTRS/SKqInxRikF4UwQ9sqlAQWuhfKb3vXf+GNyJ4pwiCiFD0SsEWNK0aNDGtaRqzJtss2dQYmTk9m93EuTl75uw8552ZM8rnt7EabGYa93B7WiwP7cnsPnlIZ8qnhfnau6WIncHfhXLR4avemLxv7XDzmk9p2IsXBWD+9QDWt5IYDbjEbS6FV7MixMm9JH77bfK/8WypDkgeZfg88afcpEY6KI1Qu7iE4BZgdrIX6SuNgyd6vA5Au8fJO8wYGA+rSP80cXHzF8rH2Kvamxc9DsDZrYHpaBB6VqhRu57gy1Ee72PPsLxxieionwHJolkHZPMG4pcFTA16OaB6+w9GpcrfQ9Fe6Gkdv841bH8vMCCXKeOHVmlWQACPq9UK7u704vwkZ/kohZdj3Ugk8gIgu3B9prECqgHlTZC+oQC+HuR4T0oItrqTYsDxqSZSkADqQrpUwZjPwwFkJQOOYPLZAVzExwBUxOGnAiRvXttOcREfBcg2koK5SJClcvVDqqOHVMjN3QyejwQ4BauNS4v9kA+JINLUFvFo7OZvA0JhG4BSIAUr+0lMh31Qg274G19PA4T+jXT66gr6fWJA9Pv67ZyCTUHjGU2ibt5B+TA7wxOj18TYcqAixtnua8rlv+MBPoIXdEHcqvMAAAAASUVORK5CYII="},{"path":"C:\\Users\\simon\\Desktop\\Forge 15\\Create\\src\\main\\resources\\assets\\create\\textures\\block\\fluid_pipe.png","name":"fluid_pipe.png","folder":"block","namespace":"create","id":"9","particle":false,"mode":"bitmap","saved":true,"uuid":"e238433b-c06e-b068-b8f7-ba0f778775f1","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAE+ElEQVRYR5VX32scVRT+NunubHa7s9lJtj/MtrEGk0o1KkitaCu0WjAPIkKRUuiDoNT+A30pPkgffBdUFAQLoRSxfRAUFPpgHqxvsiBitPRHNk3MZnfNrpNkdpOMfHd6pncn093Z+3KzM3fu+c4533fOSeyjk8ddeysGrnSfq3ZZ8lx+b7VaeK6wE4m0oR4Z3oZsOqX2peqq2pu2g5U1IDvw8C7+Pn/te8+QtmIEUMgaMBKxtosdx7uIiwYbtXX8sWTj8MSQMmztz6l3mxXvDFf/kIHqvRrk28kj4yjenIXsZ6YfAWAsn8RtewM3654HiUTc86TZUvsRM4UD6R34rfSfArD3yRxu/HQHV379uc2b0y8ew/HXH8fCXzUFPmMZKM07KIwYaFQddARw+V4V6fQAjHgcZsZEvVFXlzutFmx7DWf3W5iZq2Pq2bwK+bnPrgajqX5/efGsH4XysoPJl/ag+Msi8sMGTn1xPTwFjMCVhToy6RSq/9bx/NNPobbSwJ25EqxBEw17FVODJorL0QEQDL0XAIzCm5+EALjw2gl3creBbytryvvRwggcp4lBM4M1x8Hd0rwCcHqv6UeA+X/v0uXQCHz+wTtYsb1ULi+uY2zMwq1bVQzvSYYDOHfsFffEwTy+/ruMYSsHI2Egl82oCDhNB47j+ADIgaOTQ4qA3QAwTTQsALi/+vH09hQQwOHdGVyrNNpSsFhexsI/ZT8F7x/KY6ZYUSQ8+Mworn9X7EjCXVZEAEzBRC6Bq4s1xOM7lAKYCiEgldBqbfgkZLQowwPjo6jOl335ZZMmVtbrPgEJ4PfZms+BQ+O58AgQwAtPmPhzycZMxWM+gXDRMNfLAymQqFTB0X2mqgsEQb3rxYiFSGoHv4skQ4lAKKO0h/dbmyhVV3sCEKkQkQPdjOvvC1YKVp8XIZZap+l9vr4ZQ7LfVXt1a0OdiVSKP317yuWHmVyyDQdLLy8L1u/pM1NulF4QVvXCHFW9oC/leSSe0QOurdUNfPjjjW3S6SVi3c7Geo1Atwt7fa8AsE6TzdJWeQkZzVoe1kJ7NdLpfOyrU2+4bMWUjN5iowKQFDJ9TN1j8X7fHjnERY7JEpJKin0AJBaLhzWSx+3Zu0rjUSIQNk+IMdYEUYlOcnlOaSsA/IDNgingUMF+zkUlvPvNDx1JSAAsUoygkuaD6UgakjzjvRxe5DnnA05JoRxg+GmcqxuAIIdoKGyxVEvpJgiJsALAglHYl1Pey4jFThYFACPI8DJ9QeM0ysUewXv194wyndwGgB/wcFQShgHQjYlDNC4NS+73AVCGQkC9o0UhoZ4CURGdkOGUf4vEBQRTIQ4qEjKEeovVc9StDgQBCNFkMqYKgikiOE5LlKRPQk66QhRRgsz3uo51PSuGD3hju3BAQi4eyvlgLZDnbQAk/4o4D5hKEDSga1r/HyIYYrmjNFdTMpNCpH8jd/kR0FWgE0WACFpqnMBk13XPv4XljIIOgPezTujf+XXg0lsn3Yld6TYZ6fIJapqXs1qKtHTDQZaTxFzBXtNWB3QSSiXUjYqkJLdiXD8T1LsY4JjH3iAk1KPnk5AR4L9deimVg+IdWauHWy/XusREftwlxEJUPQWiEFWKCYAoSRIuIZxMPeKpPmzKM5FY2Bm+Y7NhlwxOXG0k7NRO9TBLaw3KSp8F5Z0+UQ3v9Ea9R8nwf4KEhTJhQYO9AAAAAElFTkSuQmCC"}],"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,225,0],"scale":[0.625,0.625,0.625]},"fixed":{"scale":[0.5,0.5,0.5]}}} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/hose_pulley/copper_pulley_rope.bbmodel b/src/main/resources/assets/create/models/block/hose_pulley/copper_pulley_rope.bbmodel deleted file mode 100644 index 38a0b1b92..000000000 --- a/src/main/resources/assets/create/models/block/hose_pulley/copper_pulley_rope.bbmodel +++ /dev/null @@ -1 +0,0 @@ -{"meta":{"format_version":"3.2","model_format":"java_block","box_uv":false},"name":"rope","parent":"block/block","ambientocclusion":true,"front_gui_light":false,"resolution":{"width":16,"height":16},"elements":[{"name":"rope","from":[6,0,6],"to":[10,16,10],"autouv":0,"color":6,"locked":false,"origin":[7.75,0,8],"faces":{"north":{"uv":[0,0,4,16],"texture":0},"east":{"uv":[0,0,4,16],"texture":0},"south":{"uv":[0,0,4,16],"texture":0},"west":{"uv":[0,0,4,16],"texture":0},"up":{"uv":[0,0,4,4],"rotation":90,"texture":0},"down":{"uv":[0,0,4,4],"texture":0}},"uuid":"3f245b42-dde8-d34f-9f25-ae6eb2f322ae"}],"outliner":["3f245b42-dde8-d34f-9f25-ae6eb2f322ae"],"textures":[{"path":"C:\\Users\\krypp\\Documents\\Pixel Art\\Create Mod\\Pulley Pump\\copper_pulley_rope.png","name":"copper_pulley_rope.png","folder":"Pulley Pump","namespace":"create","id":"5","particle":true,"mode":"bitmap","saved":true,"uuid":"8ffc2f62-b5b6-1af9-ecc1-e22a9ae075aa","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAX0lEQVQ4T2M00tP4z8fLwfDp8w+GX7//MLCxsjCQwmfU0VT5r6IgwfDh0xe4IaTwGUddwEB5GLS1tf2Xl5dn0NDQYLhx4wbDw4cPGUjhMy5duvQ/uZpBlo2mgz/DIQwAKD7WmGK5ZIUAAAAASUVORK5CYII="}]} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/hose_pulley/item.json b/src/main/resources/assets/create/models/block/hose_pulley/item.json index b8c30a0cd..2554a770b 100644 --- a/src/main/resources/assets/create/models/block/hose_pulley/item.json +++ b/src/main/resources/assets/create/models/block/hose_pulley/item.json @@ -7,9 +7,9 @@ "4": "create:block/copper_gearbox", "5": "create:block/hose_pulley_rope", "6": "create:block/hose_pulley_magnet", - "8": "create:block/oxidized/copper_block_0", + "8": "create:block/copper_plating", "9": "create:block/fluid_pipe", - "particle": "create:block/oxidized/copper_block_0" + "particle": "create:block/copper_plating" }, "elements": [ { diff --git a/src/main/resources/assets/create/models/block/portable_fluid_interface/block.json b/src/main/resources/assets/create/models/block/portable_fluid_interface/block.json new file mode 100644 index 000000000..62c31c029 --- /dev/null +++ b/src/main/resources/assets/create/models/block/portable_fluid_interface/block.json @@ -0,0 +1,8 @@ +{ + "parent": "create:block/portable_storage_interface/block", + "textures": { + "0": "create:block/portable_fluid_interface", + "1": "create:block/copper_casing", + "particle": "create:block/copper_casing" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/portable_fluid_interface/block_middle.json b/src/main/resources/assets/create/models/block/portable_fluid_interface/block_middle.json new file mode 100644 index 000000000..0b3d3ab30 --- /dev/null +++ b/src/main/resources/assets/create/models/block/portable_fluid_interface/block_middle.json @@ -0,0 +1,6 @@ +{ + "parent": "create:block/portable_storage_interface/block_middle", + "textures": { + "0": "create:block/portable_fluid_interface" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/portable_fluid_interface/block_middle_powered.json b/src/main/resources/assets/create/models/block/portable_fluid_interface/block_middle_powered.json new file mode 100644 index 000000000..c2a3789b4 --- /dev/null +++ b/src/main/resources/assets/create/models/block/portable_fluid_interface/block_middle_powered.json @@ -0,0 +1,6 @@ +{ + "parent": "create:block/portable_storage_interface/block_middle_powered", + "textures": { + "0": "create:block/portable_fluid_interface" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/portable_fluid_interface/block_top.json b/src/main/resources/assets/create/models/block/portable_fluid_interface/block_top.json new file mode 100644 index 000000000..ebd764857 --- /dev/null +++ b/src/main/resources/assets/create/models/block/portable_fluid_interface/block_top.json @@ -0,0 +1,6 @@ +{ + "parent": "create:block/portable_storage_interface/block_top", + "textures": { + "0": "create:block/portable_fluid_interface" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/portable_fluid_interface/item.json b/src/main/resources/assets/create/models/block/portable_fluid_interface/item.json new file mode 100644 index 000000000..ffa83d0d0 --- /dev/null +++ b/src/main/resources/assets/create/models/block/portable_fluid_interface/item.json @@ -0,0 +1,7 @@ +{ + "parent": "create:block/portable_storage_interface/item", + "textures": { + "0": "create:block/portable_fluid_interface", + "1": "create:block/copper_casing" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/portable_storage_interface/brass_casing.png b/src/main/resources/assets/create/models/block/portable_storage_interface/brass_casing.png deleted file mode 100644 index fb657ce47..000000000 Binary files a/src/main/resources/assets/create/models/block/portable_storage_interface/brass_casing.png and /dev/null differ diff --git a/src/main/resources/assets/create/models/block/portable_storage_interface/portable_storage_interface.bbmodel b/src/main/resources/assets/create/models/block/portable_storage_interface/portable_storage_interface.bbmodel deleted file mode 100644 index 579e9291e..000000000 --- a/src/main/resources/assets/create/models/block/portable_storage_interface/portable_storage_interface.bbmodel +++ /dev/null @@ -1 +0,0 @@ -{"meta":{"format_version":"3.2","model_format":"java_block","box_uv":false},"name":"item","ambientocclusion":true,"front_gui_light":false,"resolution":{"width":16,"height":16},"elements":[{"name":"cube","from":[2,10,2],"to":[14,19,14],"autouv":0,"color":4,"locked":false,"origin":[10,18,10],"faces":{"north":{"uv":[1,3.5,7,8],"texture":0},"east":{"uv":[1,3.5,7,8],"texture":0},"south":{"uv":[1,3.5,7,8],"texture":0},"west":{"uv":[1,3.5,7,8],"texture":0},"up":{"uv":[1.5,3.5,2,4],"texture":0},"down":{"uv":[0,0,12,12],"texture":null}},"uuid":"de312b34-6e0e-d92a-f0cc-2b14d972edb8"},{"name":"cube","from":[0,0,0],"to":[16,12,16],"autouv":0,"color":3,"locked":false,"origin":[8,8,8],"faces":{"north":{"uv":[0,10,8,16],"texture":0},"east":{"uv":[0,10,8,16],"texture":0},"south":{"uv":[0,10,8,16],"texture":0},"west":{"uv":[0,10,8,16],"texture":0},"up":{"uv":[0,0,16,16],"texture":1},"down":{"uv":[0,0,16,16],"texture":1}},"uuid":"d78fa319-b9a7-d009-a299-e17e3ecd7b4c"},{"name":"cube","from":[0,12,1.9],"to":[2,14.1,14.1],"autouv":0,"color":2,"locked":false,"origin":[8,20,10],"faces":{"north":{"uv":[7,10,8,11],"texture":0},"east":{"uv":[0,0,0,0],"texture":null},"south":{"uv":[0,10,1,11],"texture":0},"west":{"uv":[1,9,7,10],"texture":0},"up":{"uv":[0,2,2,14],"texture":1},"down":{"uv":[0,0,0,0],"texture":null}},"uuid":"e5ea8437-3bd2-3033-9cb1-bca2918ad937"},{"name":"cube","from":[14,12,2],"to":[16,14,14],"autouv":0,"color":4,"locked":false,"origin":[8,20,6],"faces":{"north":{"uv":[0,10,1,11],"texture":0},"east":{"uv":[1,9,7,10],"texture":0},"south":{"uv":[7,10,8,11],"texture":0},"west":{"uv":[0,0,0,0],"texture":null},"up":{"uv":[0,2,2,14],"rotation":180,"texture":1},"down":{"uv":[0,0,0,0],"texture":null}},"uuid":"ef15b8aa-40de-3212-db76-9fc6c9269236"},{"name":"cube","from":[2,12,0],"to":[14,14,16],"autouv":0,"color":0,"locked":false,"origin":[10,20,8],"faces":{"north":{"uv":[1,9,7,10],"texture":0},"east":{"uv":[0,10,8,11],"texture":0},"south":{"uv":[1,9,7,10],"texture":0},"west":{"uv":[0,10,8,11],"texture":0},"up":{"uv":[2,0,14,16],"texture":1},"down":{"uv":[0,0,0,0],"texture":null}},"uuid":"a11c9348-80ea-30fd-5b35-bf4fab00a286"},{"name":"cube","from":[3,16,3],"to":[13,23.1,13],"autouv":0,"color":2,"locked":false,"origin":[11,24,11],"faces":{"north":{"uv":[1.5,0,6.5,3.5],"texture":0},"east":{"uv":[1.5,0,6.5,3.5],"texture":0},"south":{"uv":[1.5,0,6.5,3.5],"texture":0},"west":{"uv":[1.5,0,6.5,3.5],"texture":0},"up":{"uv":[0,0,0,0],"texture":null},"down":{"uv":[0,0,0,0],"texture":null}},"uuid":"6a52cb20-69df-718c-97da-3c42422e07e0"},{"name":"cube","from":[1,23,1],"to":[15,25,15],"autouv":0,"color":6,"locked":false,"origin":[8,24,8],"faces":{"north":{"uv":[8.5,15,15.5,16],"texture":0},"east":{"uv":[8.5,15,15.5,16],"texture":0},"south":{"uv":[8.5,15,15.5,16],"texture":0},"west":{"uv":[8.5,15,15.5,16],"texture":0},"up":{"uv":[8.5,8,15.5,15],"texture":0},"down":{"uv":[8.5,8,15.5,15],"texture":0}},"uuid":"323ba350-4ba9-9942-b94e-9918f2cb06bd"},{"name":"cube","from":[4,22.1,13],"to":[6,24.1,14],"autouv":0,"color":7,"locked":false,"rotation":[45,0,0],"origin":[8,23,13],"faces":{"north":{"uv":[0,0,0,0],"texture":null},"east":{"uv":[7.5,10,8,10.5],"texture":0},"south":{"uv":[10,15,11,16],"texture":0},"west":{"uv":[7.5,10,8,10.5],"texture":0},"up":{"uv":[0,0,0,0],"texture":null},"down":{"uv":[0,0,0,0],"texture":null}},"uuid":"1d3cd83e-6fc4-5767-4de6-42d59581a66b"},{"name":"cube","from":[10,22.1,2],"to":[12,24.1,3],"autouv":0,"color":5,"locked":false,"rotation":[-45,0,0],"origin":[8,23,3],"faces":{"north":{"uv":[10,15,11,16],"texture":0},"east":{"uv":[7.5,10,8,10.5],"texture":0},"south":{"uv":[0,0,0,0],"texture":null},"west":{"uv":[7.5,10,8,10.5],"texture":0},"up":{"uv":[0,0,0,0],"texture":null},"down":{"uv":[0,0,0,0],"texture":null}},"uuid":"ff86b4f3-c6ea-e7e4-228a-a2b21aca7a25"},{"name":"cube","from":[2,22.1,4],"to":[3,24.1,6],"autouv":0,"color":7,"locked":false,"rotation":[0,0,45],"origin":[3,23,8],"faces":{"north":{"uv":[7.5,10,8,10.5],"texture":0},"east":{"uv":[0,0,0,0],"texture":null},"south":{"uv":[7.5,10,8,10.5],"texture":0},"west":{"uv":[10,15,11,16],"texture":0},"up":{"uv":[0,0,0,0],"texture":null},"down":{"uv":[0,0,0,0],"texture":null}},"uuid":"f689fb7a-a97d-fd81-c390-380f16371935"},{"name":"cube","from":[13,22.1,10],"to":[14,24.1,12],"autouv":0,"color":6,"locked":false,"rotation":[0,0,-45],"origin":[13,23,8],"faces":{"north":{"uv":[7.5,10,8,10.5],"texture":0},"east":{"uv":[10,15,11,16],"texture":0},"south":{"uv":[7.5,10,8,10.5],"texture":0},"west":{"uv":[0,0,0,0],"texture":null},"up":{"uv":[0,0,0,0],"texture":null},"down":{"uv":[0,0,0,0],"texture":null}},"uuid":"848d1774-ecae-9eb6-f536-e332161c0954"},{"name":"cube","from":[10,22.1,13],"to":[12,24.1,14],"autouv":0,"color":6,"locked":false,"rotation":[45,0,0],"origin":[8,23,13],"faces":{"north":{"uv":[0,0,0,0],"texture":null},"east":{"uv":[7.5,10,8,10.5],"texture":0},"south":{"uv":[13,15,14,16],"texture":0},"west":{"uv":[7.5,10,8,10.5],"texture":0},"up":{"uv":[0,0,0,0],"texture":null},"down":{"uv":[0,0,0,0],"texture":null}},"uuid":"c71a2559-c9eb-ea19-f432-00ef36482906"},{"name":"cube","from":[4,22.1,2],"to":[6,24.1,3],"autouv":0,"color":7,"locked":false,"rotation":[-45,0,0],"origin":[8,23,3],"faces":{"north":{"uv":[13,15,14,16],"texture":0},"east":{"uv":[7.5,10,8,10.5],"texture":0},"south":{"uv":[0,0,0,0],"texture":null},"west":{"uv":[7.5,10,8,10.5],"texture":0},"up":{"uv":[0,0,0,0],"texture":null},"down":{"uv":[0,0,0,0],"texture":null}},"uuid":"76250b0e-a72a-5cf0-e6fe-92819c986668"},{"name":"cube","from":[2,22.1,10],"to":[3,24.1,12],"autouv":0,"color":1,"locked":false,"rotation":[0,0,45],"origin":[3,23,8],"faces":{"north":{"uv":[7.5,10,8,10.5],"texture":0},"east":{"uv":[0,0,0,0],"texture":null},"south":{"uv":[7.5,10,8,10.5],"texture":0},"west":{"uv":[13,15,14,16],"texture":0},"up":{"uv":[0,0,0,0],"texture":null},"down":{"uv":[0,0,0,0],"texture":null}},"uuid":"df73a796-af5b-89a2-cd8e-ba9c3babf799"},{"name":"cube","from":[13,22.1,4],"to":[14,24.1,6],"autouv":0,"color":6,"locked":false,"rotation":[0,0,-45],"origin":[13,23,8],"faces":{"north":{"uv":[7.5,10,8,10.5],"texture":0},"east":{"uv":[13,15,14,16],"texture":0},"south":{"uv":[7.5,10,8,10.5],"texture":0},"west":{"uv":[0,0,0,0],"texture":null},"up":{"uv":[0,0,0,0],"texture":null},"down":{"uv":[0,0,0,0],"texture":null}},"uuid":"3c79817e-58ff-9c30-ebcf-3bba7ec9e870"}],"outliner":[{"name":"Middle","uuid":"264b83b8-efae-9137-aa5e-0226a71ebafb","export":true,"isOpen":true,"locked":false,"visibility":true,"autouv":0,"origin":[10,22,10],"children":["de312b34-6e0e-d92a-f0cc-2b14d972edb8"]},{"name":"block","uuid":"bd1a7e4e-8dfb-30c7-82be-0b25df157ef2","export":true,"isOpen":true,"locked":false,"visibility":true,"autouv":0,"origin":[8,8,8],"children":[{"name":"Base","uuid":"2cfb4e18-3aea-9f2f-2880-12edf0e1d861","export":true,"isOpen":true,"locked":false,"visibility":true,"autouv":0,"origin":[10,20,8],"children":["d78fa319-b9a7-d009-a299-e17e3ecd7b4c","e5ea8437-3bd2-3033-9cb1-bca2918ad937","ef15b8aa-40de-3212-db76-9fc6c9269236","a11c9348-80ea-30fd-5b35-bf4fab00a286"]}]},{"name":"block_top","uuid":"0073ff5f-cbc9-63c3-ee64-74a557d08b5f","export":true,"isOpen":false,"locked":false,"visibility":true,"autouv":0,"origin":[8,8,8],"children":[{"name":"Top","uuid":"c293d84e-c942-8907-cf16-62a51d3e9ef3","export":true,"isOpen":false,"locked":false,"visibility":true,"autouv":0,"origin":[10,22,10],"children":["6a52cb20-69df-718c-97da-3c42422e07e0","323ba350-4ba9-9942-b94e-9918f2cb06bd","1d3cd83e-6fc4-5767-4de6-42d59581a66b","ff86b4f3-c6ea-e7e4-228a-a2b21aca7a25","f689fb7a-a97d-fd81-c390-380f16371935","848d1774-ecae-9eb6-f536-e332161c0954","c71a2559-c9eb-ea19-f432-00ef36482906","76250b0e-a72a-5cf0-e6fe-92819c986668","df73a796-af5b-89a2-cd8e-ba9c3babf799","3c79817e-58ff-9c30-ebcf-3bba7ec9e870"]}]}],"textures":[{"path":"C:\\Users\\simon\\Desktop\\Forgespace 1.15\\Create\\src\\main\\resources\\assets\\create\\textures\\block\\portable_storage_interface.png","name":"portable_storage_interface.png","folder":"block","namespace":"create","id":"0","particle":true,"mode":"bitmap","saved":true,"uuid":"0539e8a0-cc65-561f-c3f4-7d4ec0ab322f","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAE2UlEQVRYR61XXWgcVRT+JtmdzM7+NDHRVh9U6EMTfWhMFJpKBDGSkgRSIWCC+OZDCyJowb6V4oNoRXwR1BdfRBJh0Qaa0GqqaOgPQv6w5KdapH3QxGyan01mJ7ObjJwzOZM7yRDoNAeWe++ZPfd8c36+uVeDIi2vvOo6Tok1uh4DzWWUv9F66OpPmmon8472drdUKiEWi7FK5qqO9JcGBnz7wEa0gW07MAydjUulTcRiZTyKjjZXN1CBRLEPADjR2upalgPTJACbgQiIjgBdvnIlNAJR7AMbUQosy4ZpGuxcDaHo9kpBFPsAgJeaX3aXV1ZwIJNh52uWhaRp8ig6SsFvw7+ERiCKfWCj403Nbm5hATXV1ey0UCggkUjwKDoCdP3GcCiAKPaBjY4ebXRVp2qBCRAaJyZGQgFEsfc36unpcYvFIui3l8TjcdCvt7c3ACKqvb9JV1eX+8yRIxgdH8fq4CCSANIAFqGhCi5mAaTa2tBQX4/JmRlks9kAANX+iYEBPAfgIICnAPy+Nf+6vX2Xvb9JZ2enu7ZqgbogffMaO81vgaCxBA35Yy8ikzFRYRjo7+8PAFDt37wxjAyAWgB3ARQA/ArgVlPzLnt/EyKRlRWLmY963WOyTR6FjIQZw7ggqr0PgEiEAFCbEQiKhFCq0LHwQhgXRLX3ARCJzOfuc9+TY+IDmnsRiAV4IYwLotr7AIhEZufmuO/JMfEBzUmEjKRFw7ggqr0PgEhkdu4/xGLl7DifX+U5iXBAqbThP9/JBVHtfQBEIuTUC3k5yJlI2Pr27cldJBbFPpTR9mSikIfd3d3uaj7PdfLZ6Uoszy7h/A9AZVUV/3tpcRHnXwMOHKrEu18scU2l0mn09fVp+wJAPYgQCCnc8q2DyQafLbb10k10rtDe63jWrTQ2YCEOEx4N01xkp07W8r+Psn9o1ILyVqTf+T1RvyP0XKJF5woG8PRhE1XpciQNnf2u2Y4PYKdOXf89vYRz2Wlt6uLrLoWWQj49PQ3Lstjetm0eKyoqoGkaF3NdXR2nhFJVd/K7IICLQ/dQcjz2czbcQLbNhNcRJCdbnkR942EMfj+Bs9/c0m5+2epSzomip6am2HE+TwS+Lel0GoZhMIB12+aaOHZKiUD2xzuoSui+Y71cQ0zfouQtUJxbvQz/5gq4cOY4rl2/ywDUFIyOjmJ+fj7gXBY1NTVobGwMT0HfwF+IxTWUiq4/ssP4dp2qz1QA1AWUd5KxsbFdby8AUqkUGhoaeEnp4C6QGqAIJHWv+CTcajooIpQWGhcLDj58p8mPwL4BoBSISA0IGKuwTUzLaw6++qTNrwE1BSMjI8jlcg+eAomAWmzilN5a8k/j/LIdiIBahJOTk1hfX3/wIqQaeDRT4YdZwh3WEWtOkQH8fPXOrjYkAFQPruvCcbx2purn1Jomamtrw9tQLUK1+Kjwdq6pMFUA+0JEBODxmoTPA2FvTjopwnNvPY+R8X+4DR+aiokJBQDlXa14AaLWAfHAB6df8AE81MeI2vCxQ0lUPuIx4F6S1L1br9DxnzP3AxGge+WFN3TMLazi08s63zFJSH/mhIOD1Sm8/61395RLLvOAbniMx4WCYqSPER1g6Rx5tmOTvyWfDxl8x/QA2Hi7xWbgH18qY70cbP8HnbEaXWM9SskAAAAASUVORK5CYII="},{"path":"C:\\Users\\simon\\Desktop\\Forgespace 1.15\\Create\\src\\main\\resources\\assets\\create\\textures\\block\\brass_casing.png","name":"brass_casing.png","folder":"block","namespace":"create","id":"1","particle":false,"mode":"bitmap","saved":true,"uuid":"4871ad15-b223-c27e-7677-628b97f293d9","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABeUlEQVQ4T4VSv0/CUBC+J6WkVKUMGn9MSqJNkITEf0MXZTAOxsXB1Tg4Mzu4mejiYuLi/0IiJuiAbhocWojlQQFr7sqjfaUpt9x7vXtfv/vuY1eVkpeFAWBkNIVyNPp8GFu3OANWrZjehmlAebdATe1ve/I+t2JI917X/xFGh/egXmv5ADvlZaje1aiQVVOUlTSD4cCjHA78hnF5WpoGKKzNU3Ho/kmP3JEHaioA+un04fxoGz4aNjDUoGjqcPv0BkuLGcDmpEAgi7twdrgFrw0nALh/foe8phJA23EnYxCjMe2crhITZHByUIDPZj/Q4PrhBbAB48visJrXJCIIKup4RoBW8zcAuHmsSwyw2XF91XU1TWfMYoTj/U0fQGgQHUEAIH08CwZTIyQBhGcQDMgr4xFIg7gtCBG77oh8IbwQHUESMazBrDWKLcSKiI+jxhGAijpHJpPWGNZAWFfsPYmJ5ANjfSHRfXHFrsPAtjmwi71isndnQP8Dd8/5n9T5ysEAAAAASUVORK5CYII="}],"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,225,0],"translation":[0,-1.75,0],"scale":[0.45,0.45,0.45]},"head":{"rotation":[-180,0,0],"translation":[0,22.25,0]},"fixed":{"translation":[0,-1.25,0],"scale":[0.5,0.5,0.5]}}} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/portable_storage_interface/portable_storage_interface.png b/src/main/resources/assets/create/models/block/portable_storage_interface/portable_storage_interface.png deleted file mode 100644 index 0e9ade677..000000000 Binary files a/src/main/resources/assets/create/models/block/portable_storage_interface/portable_storage_interface.png and /dev/null differ diff --git a/src/main/resources/assets/create/models/block/spout/block.json b/src/main/resources/assets/create/models/block/spout/block.json index 6244a12c0..66ac7929e 100644 --- a/src/main/resources/assets/create/models/block/spout/block.json +++ b/src/main/resources/assets/create/models/block/spout/block.json @@ -3,7 +3,7 @@ "parent": "block/block", "textures": { "0": "create:block/spout", - "particle": "create:block/oxidized/copper_block_0" + "particle": "create:block/copper_plating" }, "elements": [ { diff --git a/src/main/resources/assets/create/models/block/spout/item.json b/src/main/resources/assets/create/models/block/spout/item.json index 6c147c000..ab0a476b0 100644 --- a/src/main/resources/assets/create/models/block/spout/item.json +++ b/src/main/resources/assets/create/models/block/spout/item.json @@ -3,7 +3,7 @@ "parent": "block/block", "textures": { "0": "create:block/spout", - "particle": "create:block/oxidized/copper_block_0" + "particle": "create:block/copper_plating" }, "elements": [ { diff --git a/src/main/resources/assets/create/textures/block/bearing_top_wooden.png b/src/main/resources/assets/create/textures/block/bearing_top_wooden.png index f9977a98d..05fb05a4d 100644 Binary files a/src/main/resources/assets/create/textures/block/bearing_top_wooden.png and b/src/main/resources/assets/create/textures/block/bearing_top_wooden.png differ diff --git a/src/main/resources/assets/create/textures/block/brass_storage_block.png b/src/main/resources/assets/create/textures/block/brass_storage_block.png new file mode 100644 index 000000000..7cc2fff4c Binary files /dev/null and b/src/main/resources/assets/create/textures/block/brass_storage_block.png differ diff --git a/src/main/resources/assets/create/textures/block/copper_plating.png b/src/main/resources/assets/create/textures/block/copper_plating.png new file mode 100644 index 000000000..ee40eba88 Binary files /dev/null and b/src/main/resources/assets/create/textures/block/copper_plating.png differ diff --git a/src/main/resources/assets/create/textures/block/oxidized/copper_block_0.png b/src/main/resources/assets/create/textures/block/oxidized/copper_block_0.png index ee40eba88..789760388 100644 Binary files a/src/main/resources/assets/create/textures/block/oxidized/copper_block_0.png and b/src/main/resources/assets/create/textures/block/oxidized/copper_block_0.png differ diff --git a/src/main/resources/assets/create/textures/block/oxidized/copper_shingles_0.png b/src/main/resources/assets/create/textures/block/oxidized/copper_shingles_0.png index 385718f7e..3a661304f 100644 Binary files a/src/main/resources/assets/create/textures/block/oxidized/copper_shingles_0.png and b/src/main/resources/assets/create/textures/block/oxidized/copper_shingles_0.png differ diff --git a/src/main/resources/assets/create/textures/block/oxidized/copper_tiles_0.png b/src/main/resources/assets/create/textures/block/oxidized/copper_tiles_0.png index d53825657..5df19a754 100644 Binary files a/src/main/resources/assets/create/textures/block/oxidized/copper_tiles_0.png and b/src/main/resources/assets/create/textures/block/oxidized/copper_tiles_0.png differ diff --git a/src/main/resources/assets/create/textures/block/portable_fluid_interface.png b/src/main/resources/assets/create/textures/block/portable_fluid_interface.png new file mode 100644 index 000000000..b0768413a Binary files /dev/null and b/src/main/resources/assets/create/textures/block/portable_fluid_interface.png differ diff --git a/src/main/resources/assets/create/textures/block/windmill_bearing_side.png b/src/main/resources/assets/create/textures/block/windmill_bearing_side.png index 942e1dee8..25299507d 100644 Binary files a/src/main/resources/assets/create/textures/block/windmill_bearing_side.png and b/src/main/resources/assets/create/textures/block/windmill_bearing_side.png differ diff --git a/src/main/resources/assets/create/textures/block/zinc_block.png b/src/main/resources/assets/create/textures/block/zinc_block.png index c1b565cfb..6ef49c21b 100644 Binary files a/src/main/resources/assets/create/textures/block/zinc_block.png and b/src/main/resources/assets/create/textures/block/zinc_block.png differ