diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index 264330a9d..da4fb047b 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -18,7 +18,7 @@ a579c40c43dc2174afb66f42d00d0c4a0efaaeee assets/create/blockstates/andesite_bric 11908c2f8603e61bec88010bc6d0890e6339c6b1 assets/create/blockstates/andesite_funnel.json 398922758a6219544e5b85c91c9cf8a543b437e5 assets/create/blockstates/andesite_pillar.json 1d2d8081581e07d9be4b382aede4f2de4401cc6b assets/create/blockstates/andesite_tunnel.json -f9fa6aa530eb0891a74eadfbebc663172a57147a assets/create/blockstates/basin.json +e555e3c2b2d3f01440e48db4ba88f7e00fd99b6f assets/create/blockstates/basin.json f25693a9429f6337149ff24f27900dc4eb82a7c2 assets/create/blockstates/belt.json cf9045eb16e5299a1d917c4cb536289f49411276 assets/create/blockstates/birch_window.json 94a1a91403eb4b035fec48071e7fcae57a8a6abd assets/create/blockstates/birch_window_pane.json @@ -132,7 +132,7 @@ de8a40b7daf1497d5aecee47a43b3e0b1d030b00 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 6372fe02ba0065acb0758121c45a15a1a8fdc5de assets/create/blockstates/fancy_weathered_limestone_bricks_wall.json -3d97226b5e8d8f70ed08e45e78db1faf78d5e28b assets/create/blockstates/fluid_pipe.json +4c3e0500f9382d2e426e823fe876f57f4d7ee3b4 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 @@ -312,7 +312,7 @@ e8b0a401c10d1ba67ed71ba31bd5f9bc28571b65 assets/create/blockstates/powered_toggl 469e430d96cb0a5e1aaf6b7cc5d401d488c9e600 assets/create/blockstates/pulse_repeater.json 92957119abd5fbcca36a113b2a80255fd70fc303 assets/create/blockstates/purple_seat.json 61035f8afe75ff7bbd291da5d8690bcbebe679eb assets/create/blockstates/purple_valve_handle.json -8d7e653bfd9846e684a0d3725595714a19201017 assets/create/blockstates/radial_chassis.json +bdd56f32ce0a148b6e466a55ab2777f69fc08cfc assets/create/blockstates/radial_chassis.json da1b08387af7afa0855ee8d040f620c01f20660a assets/create/blockstates/red_seat.json 722fc77bbf387af8a4016e42cbf9501d2b968881 assets/create/blockstates/red_valve_handle.json 8929677f2cc5354aa19ef182af69f9f0b41eb242 assets/create/blockstates/redstone_contact.json @@ -368,16 +368,16 @@ a3a11524cd3515fc01d905767b4b7ea782adaf03 assets/create/blockstates/yellow_seat.j 7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json c113d0a180880243538e9b1c3019c863df3fbdc1 assets/create/lang/en_ud.json -88bb3904aaac091ed7ce4bb336dbf3e770c022dd assets/create/lang/en_us.json -ca20d938212e7bd07f98b6547113dd7054ebb8ac assets/create/lang/unfinished/de_de.json -3e59c20a5966a30f80fd4c565bbdb48a08f16aab assets/create/lang/unfinished/fr_fr.json -2e6088860eba69341a168d44c9db6aef9bcc2682 assets/create/lang/unfinished/it_it.json -0135c7d92bac5955a620c25588ed86785479dd4b assets/create/lang/unfinished/ja_jp.json -b7fb3f75f54e9568e9eda012df72ce9deb2aae09 assets/create/lang/unfinished/ko_kr.json -9630962c49ec42b5f76b20ca5ea0b35f285eae24 assets/create/lang/unfinished/nl_nl.json -4ceb1a664412c9385faa27f409f4bc5669aaf7f8 assets/create/lang/unfinished/pt_br.json -f66486f19a4142831608e2e38d8074b967a324c1 assets/create/lang/unfinished/ru_ru.json -b37970264c2fda5394ed38a6f3d56be01185ed07 assets/create/lang/unfinished/zh_cn.json +a4cd12907a1ddfd60883077b2d11c5459d436016 assets/create/lang/en_us.json +063195daed96a4420588e6d6d13f4a9b1f099ff4 assets/create/lang/unfinished/de_de.json +30da89bafac8a5ea4d82903928ba4d2a63385117 assets/create/lang/unfinished/fr_fr.json +faddc5022cc10c8fca1649d66427e910cfa28286 assets/create/lang/unfinished/it_it.json +7f448e863397725c11ab083d39af68d205d579d7 assets/create/lang/unfinished/ja_jp.json +48d61d21ee096513f2b9e06df38882cf6ace96db assets/create/lang/unfinished/ko_kr.json +a908ecd03bd7ede95b5e5f0698157353ae2bec6c assets/create/lang/unfinished/nl_nl.json +ffa305b619c58bdff92d2e69b2bbc81ad5b8dcb6 assets/create/lang/unfinished/pt_br.json +6588d559aaafb4f036ba47ba2414caaa9d2f6f6a assets/create/lang/unfinished/ru_ru.json +4593a6013875039a6a30ac64d45bb4f140190fe1 assets/create/lang/unfinished/zh_cn.json 846200eb548d3bfa2e77b41039de159b4b6cfb45 assets/create/models/block/acacia_window.json 1930fa3a3c98d53dd19e4ee7f55bc27fd47aa281 assets/create/models/block/acacia_window_pane_noside.json 1763ea2c9b981d187f5031ba608f3d5d3be3986a assets/create/models/block/acacia_window_pane_noside_alt.json @@ -1045,7 +1045,7 @@ b0f664dd6de3d0ee9afcb6223fbcd53b97fa0d65 assets/create/models/item/andesite_cobb 7490819e7e5445019b6b8cb2538f12a5b6717a46 assets/create/models/item/andesite_funnel.json 75b8b00c2418b9660d35a7fabd0774925cf1c02f assets/create/models/item/andesite_pillar.json c0e35daccfb398947532e9499d6bda963387cd9c assets/create/models/item/andesite_tunnel.json -bf1fc6bdf7fca6f1958a2d3e96202c1cecb50669 assets/create/models/item/basin.json +421e481b7fbca4c4a1080ed703401eb25375e087 assets/create/models/item/basin.json 1da382e7e58eaa9788f5b1d92221ccac573e068f assets/create/models/item/belt_connector.json 9044243882cfd49a2827e1b910a4c9b0e46daa47 assets/create/models/item/birch_window.json 6ed49f59ea91068ef68720f43e67a9237594bdf0 assets/create/models/item/birch_window_pane.json @@ -1481,7 +1481,7 @@ d531f87f425d199aee4777a588c1cd6cab6f5173 data/create/advancements/recipes/create 2eef3201017af03f6a2f0f015645e3ff5e25d9c1 data/create/advancements/recipes/create.base/crafting/curiosities/wand_of_symmetry.json d97d96e1b2ddd25df15fe1ef1c3d084f15bb9789 data/create/advancements/recipes/create.base/crafting/kinetics/adjustable_pulley.json 92416ced6ede6965fd728e1c7336bb05a3e41ea2 data/create/advancements/recipes/create.base/crafting/kinetics/analog_lever.json -2105b4f1fd9a170a100efc083a794fdb9e068924 data/create/advancements/recipes/create.base/crafting/kinetics/attribute_filter.json +3e9753006da898d4569bbeabf95997e8c90847c8 data/create/advancements/recipes/create.base/crafting/kinetics/attribute_filter.json bec8c280b717306f87050b08a418feab53be71cb data/create/advancements/recipes/create.base/crafting/kinetics/basin.json 5af08853632fb5970fe542b3ecbde0ad16d64714 data/create/advancements/recipes/create.base/crafting/kinetics/belt_connector.json 80d87f1dde60adb5334e0cff25a9f0b7f67c1526 data/create/advancements/recipes/create.base/crafting/kinetics/black_seat.json @@ -2428,6 +2428,8 @@ d9021504be855cd2d4d91503a82b84233052adb0 data/create/recipes/blasting/gold_ingot c323b106e88b7de77fea71ff12494abdbb818d15 data/create/recipes/chiseled_limestone_from_limestone_stonecutting.json da9a919b476954c1de34826aa7706bf6056a8f12 data/create/recipes/chiseled_scoria_from_scoria_stonecutting.json 09faa4ddcf9f3907dcdb3ab3e8b68c1deb2486e5 data/create/recipes/chiseled_weathered_limestone_from_weathered_limestone_stonecutting.json +c3cfdc9552a23e4749c42e71fbddd153b76ca708 data/create/recipes/compacting/ice.json +5758a1804287c261e1c953bda599d8495ba7c40a data/create/recipes/compacting/temp_gabbro.json 19526da3a59fc136654ff1bc93c0251581f397a9 data/create/recipes/crafting/appliances/dough.json 7b5f863dda3d05a79cb85943a178eba0bd8a7dc7 data/create/recipes/crafting/appliances/slime_ball.json b159ba84428eee6ef6e23df1766f2a18f2c8a63e data/create/recipes/crafting/appliances/tree_fertilizer.json @@ -2437,7 +2439,7 @@ b159ba84428eee6ef6e23df1766f2a18f2c8a63e data/create/recipes/crafting/appliances fcbc04d0a7eaf820a74bc7e4736a4a581e0a9dff data/create/recipes/crafting/curiosities/wand_of_symmetry.json 696df0fe5f8e29220ea15527f8c119c39b418819 data/create/recipes/crafting/kinetics/adjustable_pulley.json 88de51b451469698665b7319e5b9cfb9a87ae3e0 data/create/recipes/crafting/kinetics/analog_lever.json -6912101930aae627820783c27358dcf2ff4016aa data/create/recipes/crafting/kinetics/attribute_filter.json +cf1f3a6306d47025cebe153cf05949ef69ccbe5a data/create/recipes/crafting/kinetics/attribute_filter.json 059d12526529b2896ed583555373afa31839a0de data/create/recipes/crafting/kinetics/basin.json dcf98e667d321fb4bd9fa6dfec7927a84cdbd5d6 data/create/recipes/crafting/kinetics/belt_connector.json 1123903a11b13448b61cf8f8a5dc2e8013d39ac0 data/create/recipes/crafting/kinetics/black_seat.json @@ -2675,6 +2677,7 @@ ddda28bb6efc43b7e3149756daf53e1664187283 data/create/recipes/dolomite_cobbleston 500ecdfdcf34e9d26256948e206aab4f0b79e659 data/create/recipes/dolomite_cobblestone_wall_from_dolomite_cobblestone_stonecutting.json ff39e629b242ae91e23aec86b0a1f757dd938305 data/create/recipes/dolomite_pillar.json b4a8d14d9a20e812e0acb691b5b511a87e8b0576 data/create/recipes/dolomite_pillar_from_dolomite_stonecutting.json +ae6698363e49f7cb5f2ed52c6b8805bebed31fa2 data/create/recipes/emptying/water_bottle.json 0e11aa1accb71ed62e212f23a7069b7b7b4e8119 data/create/recipes/fancy_andesite_bricks_from_andesite_stonecutting.json 8b86fc9a9416adeaab3f26192a73a481887675c3 data/create/recipes/fancy_andesite_bricks_slab.json c7b762b25c7a6705dba3e922e981be851ac4f36b data/create/recipes/fancy_andesite_bricks_slab_from_fancy_andesite_bricks_stonecutting.json @@ -2860,6 +2863,7 @@ e7bfaa806d57573d060fac0a5e7a84f345b8bb85 data/create/recipes/mixing/andesite_all 76939e4d3e5b615ae21d14c0ff7b917a622bcf80 data/create/recipes/mixing/chromatic_compound.json d9a3dff1288d675ab812eef1eb73cb27dcc71bd2 data/create/recipes/mixing/crushed_brass.json 00b165ea38d834c7955440e87062004a8182c3f8 data/create/recipes/mixing/gunpowder.json +35c4e8a765479861f307afb9ec650f912f92b998 data/create/recipes/mixing/temp_cobble.json 1998c6f84f871d6da58ec29d729401d18f8f1aa1 data/create/recipes/mossy_andesite_from_andesite_stonecutting.json 89929d9cb11b5c589b2ecfa821c61add1ef7b62b data/create/recipes/mossy_dark_scoria_from_dark_scoria_stonecutting.json 4b8b1191dd3a21294293dc5ad237af89b849df28 data/create/recipes/mossy_diorite_from_diorite_stonecutting.json diff --git a/src/generated/resources/assets/create/blockstates/basin.json b/src/generated/resources/assets/create/blockstates/basin.json index 2bc6fd9d1..0e511666e 100644 --- a/src/generated/resources/assets/create/blockstates/basin.json +++ b/src/generated/resources/assets/create/blockstates/basin.json @@ -1,7 +1,22 @@ { "variants": { - "": { - "model": "create:block/basin" + "facing=down": { + "model": "create:block/basin/block" + }, + "facing=north": { + "model": "create:block/basin/block_directional", + "y": 180 + }, + "facing=south": { + "model": "create:block/basin/block_directional" + }, + "facing=west": { + "model": "create:block/basin/block_directional", + "y": 90 + }, + "facing=east": { + "model": "create:block/basin/block_directional", + "y": 270 } } } \ No newline at end of file diff --git a/src/generated/resources/assets/create/blockstates/radial_chassis.json b/src/generated/resources/assets/create/blockstates/radial_chassis.json index 9d00ea8b1..1aa3d3728 100644 --- a/src/generated/resources/assets/create/blockstates/radial_chassis.json +++ b/src/generated/resources/assets/create/blockstates/radial_chassis.json @@ -89,8 +89,8 @@ }, { "when": { - "sticky_west": "true", - "axis": "x" + "axis": "x", + "sticky_west": "true" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky", @@ -99,8 +99,8 @@ }, { "when": { - "sticky_west": "true", - "axis": "y" + "axis": "y", + "sticky_west": "true" }, "apply": { "model": "create:block/radial_chassis_side_y_sticky", @@ -109,8 +109,8 @@ }, { "when": { - "sticky_west": "true", - "axis": "z" + "axis": "z", + "sticky_west": "true" }, "apply": { "model": "create:block/radial_chassis_side_z_sticky", @@ -119,8 +119,8 @@ }, { "when": { - "sticky_west": "false", - "axis": "x" + "axis": "x", + "sticky_west": "false" }, "apply": { "model": "create:block/radial_chassis_side_x", @@ -129,8 +129,8 @@ }, { "when": { - "sticky_west": "false", - "axis": "y" + "axis": "y", + "sticky_west": "false" }, "apply": { "model": "create:block/radial_chassis_side_y", @@ -139,8 +139,8 @@ }, { "when": { - "sticky_west": "false", - "axis": "z" + "axis": "z", + "sticky_west": "false" }, "apply": { "model": "create:block/radial_chassis_side_z", @@ -149,8 +149,8 @@ }, { "when": { - "sticky_north": "true", - "axis": "x" + "axis": "x", + "sticky_north": "true" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky" @@ -158,8 +158,8 @@ }, { "when": { - "sticky_north": "true", - "axis": "y" + "axis": "y", + "sticky_north": "true" }, "apply": { "model": "create:block/radial_chassis_side_y_sticky", @@ -168,8 +168,8 @@ }, { "when": { - "sticky_north": "true", - "axis": "z" + "axis": "z", + "sticky_north": "true" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky", @@ -178,8 +178,8 @@ }, { "when": { - "sticky_north": "false", - "axis": "x" + "axis": "x", + "sticky_north": "false" }, "apply": { "model": "create:block/radial_chassis_side_x" @@ -187,8 +187,8 @@ }, { "when": { - "sticky_north": "false", - "axis": "y" + "axis": "y", + "sticky_north": "false" }, "apply": { "model": "create:block/radial_chassis_side_y", @@ -197,8 +197,8 @@ }, { "when": { - "sticky_north": "false", - "axis": "z" + "axis": "z", + "sticky_north": "false" }, "apply": { "model": "create:block/radial_chassis_side_x", @@ -207,8 +207,8 @@ }, { "when": { - "sticky_east": "true", - "axis": "x" + "axis": "x", + "sticky_east": "true" }, "apply": { "model": "create:block/radial_chassis_side_x_sticky", @@ -217,8 +217,8 @@ }, { "when": { - "sticky_east": "true", - "axis": "y" + "axis": "y", + "sticky_east": "true" }, "apply": { "model": "create:block/radial_chassis_side_y_sticky", @@ -227,8 +227,8 @@ }, { "when": { - "sticky_east": "true", - "axis": "z" + "axis": "z", + "sticky_east": "true" }, "apply": { "model": "create:block/radial_chassis_side_z_sticky" @@ -236,8 +236,8 @@ }, { "when": { - "sticky_east": "false", - "axis": "x" + "axis": "x", + "sticky_east": "false" }, "apply": { "model": "create:block/radial_chassis_side_x", @@ -246,8 +246,8 @@ }, { "when": { - "sticky_east": "false", - "axis": "y" + "axis": "y", + "sticky_east": "false" }, "apply": { "model": "create:block/radial_chassis_side_y", @@ -256,8 +256,8 @@ }, { "when": { - "sticky_east": "false", - "axis": "z" + "axis": "z", + "sticky_east": "false" }, "apply": { "model": "create:block/radial_chassis_side_z" diff --git a/src/generated/resources/assets/create/lang/en_us.json b/src/generated/resources/assets/create/lang/en_us.json index 934c85910..225ade75f 100644 --- a/src/generated/resources/assets/create/lang/en_us.json +++ b/src/generated/resources/assets/create/lang/en_us.json @@ -678,12 +678,9 @@ "create.gui.adjustable_crate.title": "Adjustable Crate", "create.gui.adjustable_crate.storageSpace": "Storage Space", "create.gui.stockpile_switch.title": "Stockpile Switch", - "create.gui.stockpile_switch.lowerLimit": "Lower Threshold", - "create.gui.stockpile_switch.upperLimit": "Upper Threshold", - "create.gui.stockpile_switch.startAt": "Start Signal at", - "create.gui.stockpile_switch.startAbove": "Start Signal above", - "create.gui.stockpile_switch.stopAt": "Stop Signal at", - "create.gui.stockpile_switch.stopBelow": "Stop Signal below", + "create.gui.stockpile_switch.invert_signal": "Invert Signal", + "create.gui.stockpile_switch.move_to_lower_at": "Move to lower lane at %1$s%%", + "create.gui.stockpile_switch.move_to_upper_at": "Move to upper lane at %1$s%%", "create.gui.sequenced_gearshift.title": "Sequenced Gearshift", "create.gui.sequenced_gearshift.instruction": "Instruction", "create.gui.sequenced_gearshift.instruction.turn_angle": "Turn", @@ -704,7 +701,8 @@ "create.schematicAndQuill.secondPos": "Second position set.", "create.schematicAndQuill.noTarget": "Hold [Ctrl] to select Air blocks.", "create.schematicAndQuill.abort": "Removed selection.", - "create.schematicAndQuill.prompt": "Enter a name for the Schematic:", + "create.schematicAndQuill.title": "Schematic Name:", + "create.schematicAndQuill.convert": "Save and Deploy Immediately", "create.schematicAndQuill.fallbackName": "My Schematic", "create.schematicAndQuill.saved": "Saved as %1$s", @@ -751,28 +749,33 @@ "create.schematic.tool.flip.description.3": "", "create.schematics.synchronizing": "Syncing...", - "create.schematics.uploadTooLarge": "Your schematic is too big.", + "create.schematics.uploadTooLarge": "Your schematic exceeds limitations specified by the server.", "create.schematics.maxAllowedSize": "The maximum allowed schematic file size is:", "create.gui.schematicTable.title": "Schematic Table", + "create.gui.schematicTable.refresh": "Refresh Files", + "create.gui.schematicTable.open_folder": "Open Folder", "create.gui.schematicTable.availableSchematics": "Available Schematics", "create.gui.schematicTable.noSchematics": "No Schematics Saved", "create.gui.schematicTable.uploading": "Uploading...", "create.gui.schematicTable.finished": "Upload Finished!", "create.gui.schematicannon.title": "Schematicannon", - "create.gui.schematicannon.settingsTitle": "Placement Settings", - "create.gui.schematicannon.listPrinter": "Material List Printer", + "create.gui.schematicannon.listPrinter": "Checklist Printer", "create.gui.schematicannon.gunpowderLevel": "Gunpowder at %1$s%%", "create.gui.schematicannon.shotsRemaining": "Shots left: %1$s", "create.gui.schematicannon.shotsRemainingWithBackup": "With backup: %1$s", "create.gui.schematicannon.optionEnabled": "Currently Enabled", "create.gui.schematicannon.optionDisabled": "Currently Disabled", + "create.gui.schematicannon.showOptions": "Show Printer Settings", "create.gui.schematicannon.option.dontReplaceSolid": "Don't Replace Solid Blocks", "create.gui.schematicannon.option.replaceWithSolid": "Replace Solid with Solid", "create.gui.schematicannon.option.replaceWithAny": "Replace Solid with Any", "create.gui.schematicannon.option.replaceWithEmpty": "Replace Solid with Empty", "create.gui.schematicannon.option.skipMissing": "Skip missing Blocks", "create.gui.schematicannon.option.skipTileEntities": "Protect Tile Entities", + "create.gui.schematicannon.slot.gunpowder": "Add gunpowder to fuel the cannon", + "create.gui.schematicannon.slot.listPrinter": "Place books here to print a Checklist for your Schematic", + "create.gui.schematicannon.slot.schematic": "Add your Schematic here. Make sure it is deployed at a specific location.", "create.gui.schematicannon.option.skipMissing.description": "If the cannon cannot find a required Block for placement, it will continue at the next Location.", "create.gui.schematicannon.option.skipTileEntities.description": "The cannon will avoid replacing data holding blocks such as Chests.", "create.gui.schematicannon.option.dontReplaceSolid.description": "The cannon will never replace any Solid blocks in its working area, only non-Solid and Air.", @@ -808,23 +811,42 @@ "create.gui.filter.ignore_data.description": "Items match regardless of their attributes.", "create.item_attributes.placeable": "is placeable", + "create.item_attributes.placeable.inverted": "is not placeable", "create.item_attributes.consumable": "can be eaten", + "create.item_attributes.consumable.inverted": "cannot be eaten", "create.item_attributes.smeltable": "can be Smelted", + "create.item_attributes.smeltable.inverted": "cannot be Smelted", "create.item_attributes.washable": "can be Washed", + "create.item_attributes.washable.inverted": "cannot be Washed", "create.item_attributes.smokable": "can be Smoked", + "create.item_attributes.smokable.inverted": "cannot be Smoked", + "create.item_attributes.crushable": "can be Crushed", + "create.item_attributes.crushable.inverted": "cannot be Crushed", "create.item_attributes.blastable": "is smeltable in Blast Furnace", + "create.item_attributes.blastable.inverted": "is not smeltable in Blast Furnace", "create.item_attributes.enchanted": "is enchanted", + "create.item_attributes.enchanted.inverted": "is unenchanted", "create.item_attributes.damaged": "is damaged", + "create.item_attributes.damaged.inverted": "is not damaged", "create.item_attributes.badly_damaged": "is heavily damaged", + "create.item_attributes.badly_damaged.inverted": "is not heavily damaged", "create.item_attributes.not_stackable": "cannot stack", + "create.item_attributes.not_stackable.inverted": "can be stacked", "create.item_attributes.equipable": "can be equipped", + "create.item_attributes.equipable.inverted": "cannot be equipped", "create.item_attributes.furnace_fuel": "is furnace fuel", + "create.item_attributes.furnace_fuel.inverted": "is not furnace fuel", "create.item_attributes.in_tag": "is tagged %1$s", - "create.item_attributes.in_item_group": "belongs to %1$s", + "create.item_attributes.in_tag.inverted": "is not tagged %1$s", + "create.item_attributes.in_item_group": "is in group '%1$s'", + "create.item_attributes.in_item_group.inverted": "is not in group '%1$s'", "create.item_attributes.added_by": "was added by %1$s", + "create.item_attributes.added_by.inverted": "was not added by %1$s", "create.gui.attribute_filter.no_selected_attributes": "No attributes selected", "create.gui.attribute_filter.selected_attributes": "Selected attributes:", + "create.gui.attribute_filter.add_attribute": "Add attribute to List", + "create.gui.attribute_filter.add_inverted_attribute": "Add opposite attribute to List", "create.gui.attribute_filter.whitelist_disjunctive": "Whitelist (Any)", "create.gui.attribute_filter.whitelist_disjunctive.description": "Items pass if they have any of the selected attributes.", "create.gui.attribute_filter.whitelist_conjunctive": "Whitelist (All)", 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 e184d37aa..aec16a020 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: 823", + "_": "Missing Localizations: 853", "_": "->------------------------] Game Elements [------------------------<-", @@ -679,12 +679,9 @@ "create.gui.adjustable_crate.title": "adjustable_crate", "create.gui.adjustable_crate.storageSpace": "Lagerraum", "create.gui.stockpile_switch.title": "Vorratssensor", - "create.gui.stockpile_switch.lowerLimit": "Untergrenze", - "create.gui.stockpile_switch.upperLimit": "Obergrenze", - "create.gui.stockpile_switch.startAt": "Signal bei", - "create.gui.stockpile_switch.startAbove": "Signal über", - "create.gui.stockpile_switch.stopAt": "Signalstopp bei", - "create.gui.stockpile_switch.stopBelow": "Signalstopp über", + "create.gui.stockpile_switch.invert_signal": "UNLOCALIZED: Invert Signal", + "create.gui.stockpile_switch.move_to_lower_at": "UNLOCALIZED: Move to lower lane at %1$s%%", + "create.gui.stockpile_switch.move_to_upper_at": "UNLOCALIZED: Move to upper lane at %1$s%%", "create.gui.sequenced_gearshift.title": "UNLOCALIZED: Sequenced Gearshift", "create.gui.sequenced_gearshift.instruction": "UNLOCALIZED: Instruction", "create.gui.sequenced_gearshift.instruction.turn_angle": "UNLOCALIZED: Turn", @@ -705,7 +702,8 @@ "create.schematicAndQuill.secondPos": "Zweite Position festgelegt.", "create.schematicAndQuill.noTarget": "Halte [Strg] zur Auswahl von Luft.", "create.schematicAndQuill.abort": "Auswahl zurückgesetzt.", - "create.schematicAndQuill.prompt": "Gib dem Bauplan einen Namen:", + "create.schematicAndQuill.title": "UNLOCALIZED: Schematic Name:", + "create.schematicAndQuill.convert": "UNLOCALIZED: Save and Deploy Immediately", "create.schematicAndQuill.fallbackName": "Mein Bauplan", "create.schematicAndQuill.saved": "Gespeichert als %1$s", @@ -756,24 +754,29 @@ "create.schematics.maxAllowedSize": "Die maximale Bauplan-Dateigröße ist:", "create.gui.schematicTable.title": "Bauplantisch", + "create.gui.schematicTable.refresh": "UNLOCALIZED: Refresh Files", + "create.gui.schematicTable.open_folder": "UNLOCALIZED: Open Folder", "create.gui.schematicTable.availableSchematics": "Verfügbare Baupläne", "create.gui.schematicTable.noSchematics": "Keine gespeicherten Baupläne", "create.gui.schematicTable.uploading": "Hochladen...", "create.gui.schematicTable.finished": "Hochgeladen!", "create.gui.schematicannon.title": "Bauplankanone", - "create.gui.schematicannon.settingsTitle": "Platzier-Optionen", "create.gui.schematicannon.listPrinter": "Materiallistendruck", "create.gui.schematicannon.gunpowderLevel": "Schwarzpulver bei %1$s%%", "create.gui.schematicannon.shotsRemaining": "%1$s Schuss übrig", "create.gui.schematicannon.shotsRemainingWithBackup": "Mit Reserve: %1$s", "create.gui.schematicannon.optionEnabled": "Aktiviert", "create.gui.schematicannon.optionDisabled": "Deaktiviert", + "create.gui.schematicannon.showOptions": "UNLOCALIZED: Show Printer Settings", "create.gui.schematicannon.option.dontReplaceSolid": "Feste Blöcke nicht ersetzen", "create.gui.schematicannon.option.replaceWithSolid": "Feste Blöcke mit festen ersetzen", "create.gui.schematicannon.option.replaceWithAny": "Feste Blöcke immer ersetzen", "create.gui.schematicannon.option.replaceWithEmpty": "Feste Blöcke mit Leere ersetzen", "create.gui.schematicannon.option.skipMissing": "Fehlende Blöcke ignorieren", "create.gui.schematicannon.option.skipTileEntities": "Tile Entities ignorieren", + "create.gui.schematicannon.slot.gunpowder": "UNLOCALIZED: Add gunpowder to fuel the cannon", + "create.gui.schematicannon.slot.listPrinter": "UNLOCALIZED: Place books here to print a Checklist for your Schematic", + "create.gui.schematicannon.slot.schematic": "UNLOCALIZED: Add your Schematic here. Make sure it is deployed at a specific location.", "create.gui.schematicannon.option.skipMissing.description": "Wenn die Bauplankanone einen benötigten Block nicht finden kann, wird sie einfach beim nächsten weiter machen.", "create.gui.schematicannon.option.skipTileEntities.description": "Die Bauplankanone wird versuchen, Blöcke mit extra Daten, beispielsweise Truhen, nicht zu ersetzen.", "create.gui.schematicannon.option.dontReplaceSolid.description": "Die Kanone wird ausschließlich nicht feste Blöcke und Luft in ihrem Arbeitsbereich ersetzen.", @@ -809,23 +812,42 @@ "create.gui.filter.ignore_data.description": "UNLOCALIZED: Items match regardless of their attributes.", "create.item_attributes.placeable": "UNLOCALIZED: is placeable", + "create.item_attributes.placeable.inverted": "UNLOCALIZED: is not placeable", "create.item_attributes.consumable": "UNLOCALIZED: can be eaten", + "create.item_attributes.consumable.inverted": "UNLOCALIZED: cannot be eaten", "create.item_attributes.smeltable": "UNLOCALIZED: can be Smelted", + "create.item_attributes.smeltable.inverted": "UNLOCALIZED: cannot be Smelted", "create.item_attributes.washable": "UNLOCALIZED: can be Washed", + "create.item_attributes.washable.inverted": "UNLOCALIZED: cannot be Washed", "create.item_attributes.smokable": "UNLOCALIZED: can be Smoked", + "create.item_attributes.smokable.inverted": "UNLOCALIZED: cannot be Smoked", + "create.item_attributes.crushable": "UNLOCALIZED: can be Crushed", + "create.item_attributes.crushable.inverted": "UNLOCALIZED: cannot be Crushed", "create.item_attributes.blastable": "UNLOCALIZED: is smeltable in Blast Furnace", + "create.item_attributes.blastable.inverted": "UNLOCALIZED: is not smeltable in Blast Furnace", "create.item_attributes.enchanted": "UNLOCALIZED: is enchanted", + "create.item_attributes.enchanted.inverted": "UNLOCALIZED: is unenchanted", "create.item_attributes.damaged": "UNLOCALIZED: is damaged", + "create.item_attributes.damaged.inverted": "UNLOCALIZED: is not damaged", "create.item_attributes.badly_damaged": "UNLOCALIZED: is heavily damaged", + "create.item_attributes.badly_damaged.inverted": "UNLOCALIZED: is not heavily damaged", "create.item_attributes.not_stackable": "UNLOCALIZED: cannot stack", + "create.item_attributes.not_stackable.inverted": "UNLOCALIZED: can be stacked", "create.item_attributes.equipable": "UNLOCALIZED: can be equipped", + "create.item_attributes.equipable.inverted": "UNLOCALIZED: cannot be equipped", "create.item_attributes.furnace_fuel": "UNLOCALIZED: is furnace fuel", + "create.item_attributes.furnace_fuel.inverted": "UNLOCALIZED: is not furnace fuel", "create.item_attributes.in_tag": "UNLOCALIZED: is tagged %1$s", - "create.item_attributes.in_item_group": "UNLOCALIZED: belongs to %1$s", + "create.item_attributes.in_tag.inverted": "UNLOCALIZED: is not tagged %1$s", + "create.item_attributes.in_item_group": "UNLOCALIZED: is in group '%1$s'", + "create.item_attributes.in_item_group.inverted": "UNLOCALIZED: is not in group '%1$s'", "create.item_attributes.added_by": "UNLOCALIZED: was added by %1$s", + "create.item_attributes.added_by.inverted": "UNLOCALIZED: was not added by %1$s", "create.gui.attribute_filter.no_selected_attributes": "UNLOCALIZED: No attributes selected", "create.gui.attribute_filter.selected_attributes": "UNLOCALIZED: Selected attributes:", + "create.gui.attribute_filter.add_attribute": "UNLOCALIZED: Add attribute to List", + "create.gui.attribute_filter.add_inverted_attribute": "UNLOCALIZED: Add opposite attribute to List", "create.gui.attribute_filter.whitelist_disjunctive": "UNLOCALIZED: Whitelist (Any)", "create.gui.attribute_filter.whitelist_disjunctive.description": "UNLOCALIZED: Items pass if they have any of the selected attributes.", "create.gui.attribute_filter.whitelist_conjunctive": "UNLOCALIZED: Whitelist (All)", 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 64940f884..cac22b50d 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: 447", + "_": "Missing Localizations: 477", "_": "->------------------------] Game Elements [------------------------<-", @@ -679,12 +679,9 @@ "create.gui.adjustable_crate.title": "Caisse réglable", "create.gui.adjustable_crate.storageSpace": "Espace de stockage", "create.gui.stockpile_switch.title": "Commutateur de stockage", - "create.gui.stockpile_switch.lowerLimit": "Seuil inférieur", - "create.gui.stockpile_switch.upperLimit": "Seuil supérieur", - "create.gui.stockpile_switch.startAt": "Signal de départ à", - "create.gui.stockpile_switch.startAbove": "Signal de démarrage au-dessus", - "create.gui.stockpile_switch.stopAt": "Signal d'arrêt à", - "create.gui.stockpile_switch.stopBelow": "Signal d'arrêt en-dessous", + "create.gui.stockpile_switch.invert_signal": "UNLOCALIZED: Invert Signal", + "create.gui.stockpile_switch.move_to_lower_at": "UNLOCALIZED: Move to lower lane at %1$s%%", + "create.gui.stockpile_switch.move_to_upper_at": "UNLOCALIZED: Move to upper lane at %1$s%%", "create.gui.sequenced_gearshift.title": "Décaleur de rotation séquencé", "create.gui.sequenced_gearshift.instruction": "Instructions", "create.gui.sequenced_gearshift.instruction.turn_angle": "Tourner", @@ -705,7 +702,8 @@ "create.schematicAndQuill.secondPos": "Seconde position définie.", "create.schematicAndQuill.noTarget": "Enfoncez [Ctrl] pour sélectionner les blocs d'air.", "create.schematicAndQuill.abort": "Sélection supprimée.", - "create.schematicAndQuill.prompt": "Entrez un nom pour le schéma:", + "create.schematicAndQuill.title": "UNLOCALIZED: Schematic Name:", + "create.schematicAndQuill.convert": "UNLOCALIZED: Save and Deploy Immediately", "create.schematicAndQuill.fallbackName": "Mon schéma", "create.schematicAndQuill.saved": "Sauvegardé en tant que %1$s", @@ -756,24 +754,29 @@ "create.schematics.maxAllowedSize": "La taille de fichier schématique maximale autorisée est:", "create.gui.schematicTable.title": "Table à schéma", + "create.gui.schematicTable.refresh": "UNLOCALIZED: Refresh Files", + "create.gui.schematicTable.open_folder": "UNLOCALIZED: Open Folder", "create.gui.schematicTable.availableSchematics": "Schémas disponibles", "create.gui.schematicTable.noSchematics": "Aucun schéma enregistré", "create.gui.schematicTable.uploading": "Téléchargement...", "create.gui.schematicTable.finished": "Téléchargement terminé!", "create.gui.schematicannon.title": "Schémacanon", - "create.gui.schematicannon.settingsTitle": "Options de placement", "create.gui.schematicannon.listPrinter": "Imprimante de liste de matériaux", "create.gui.schematicannon.gunpowderLevel": "Poudre à canon à %1$s%%", "create.gui.schematicannon.shotsRemaining": "Tirs restants: %1$s", "create.gui.schematicannon.shotsRemainingWithBackup": "Avec sauvegarde: %1$s", "create.gui.schematicannon.optionEnabled": "Actuellement activé", "create.gui.schematicannon.optionDisabled": "Actuellement désactivé", + "create.gui.schematicannon.showOptions": "UNLOCALIZED: Show Printer Settings", "create.gui.schematicannon.option.dontReplaceSolid": "Ne remplacez pas les blocs solides", "create.gui.schematicannon.option.replaceWithSolid": "Remplacer solide par solide", "create.gui.schematicannon.option.replaceWithAny": "Remplacer le solide par n'importe quoi", "create.gui.schematicannon.option.replaceWithEmpty": "Remplacer le solide par rien", "create.gui.schematicannon.option.skipMissing": "Ignorer les blocs manquants", "create.gui.schematicannon.option.skipTileEntities": "Protéger les Tile Entities", + "create.gui.schematicannon.slot.gunpowder": "UNLOCALIZED: Add gunpowder to fuel the cannon", + "create.gui.schematicannon.slot.listPrinter": "UNLOCALIZED: Place books here to print a Checklist for your Schematic", + "create.gui.schematicannon.slot.schematic": "UNLOCALIZED: Add your Schematic here. Make sure it is deployed at a specific location.", "create.gui.schematicannon.option.skipMissing.description": "Si le canon ne peut pas trouver un bloc requis pour le placement, il continuera au prochain emplacement.", "create.gui.schematicannon.option.skipTileEntities.description": "Le canon évitera de remplacer les blocs de stockage de données tels que les coffres.", "create.gui.schematicannon.option.dontReplaceSolid.description": "Le canon ne remplacera jamais les blocs solides dans sa zone de travail, seulement non solides et air.", @@ -809,23 +812,42 @@ "create.gui.filter.ignore_data.description": "Les éléments correspondent indépendamment de leurs attributs.", "create.item_attributes.placeable": "est placeable", + "create.item_attributes.placeable.inverted": "UNLOCALIZED: is not placeable", "create.item_attributes.consumable": "peut être mangé", + "create.item_attributes.consumable.inverted": "UNLOCALIZED: cannot be eaten", "create.item_attributes.smeltable": "UNLOCALIZED: can be Smelted", + "create.item_attributes.smeltable.inverted": "UNLOCALIZED: cannot be Smelted", "create.item_attributes.washable": "UNLOCALIZED: can be Washed", + "create.item_attributes.washable.inverted": "UNLOCALIZED: cannot be Washed", "create.item_attributes.smokable": "UNLOCALIZED: can be Smoked", + "create.item_attributes.smokable.inverted": "UNLOCALIZED: cannot be Smoked", + "create.item_attributes.crushable": "UNLOCALIZED: can be Crushed", + "create.item_attributes.crushable.inverted": "UNLOCALIZED: cannot be Crushed", "create.item_attributes.blastable": "UNLOCALIZED: is smeltable in Blast Furnace", + "create.item_attributes.blastable.inverted": "UNLOCALIZED: is not smeltable in Blast Furnace", "create.item_attributes.enchanted": "est enchanté", + "create.item_attributes.enchanted.inverted": "UNLOCALIZED: is unenchanted", "create.item_attributes.damaged": "est endommagé", + "create.item_attributes.damaged.inverted": "UNLOCALIZED: is not damaged", "create.item_attributes.badly_damaged": "est fortement damaged", + "create.item_attributes.badly_damaged.inverted": "UNLOCALIZED: is not heavily damaged", "create.item_attributes.not_stackable": "ne peut pas s'empiler", + "create.item_attributes.not_stackable.inverted": "UNLOCALIZED: can be stacked", "create.item_attributes.equipable": "peut être équipé", + "create.item_attributes.equipable.inverted": "UNLOCALIZED: cannot be equipped", "create.item_attributes.furnace_fuel": "est du combustible", + "create.item_attributes.furnace_fuel.inverted": "UNLOCALIZED: is not furnace fuel", "create.item_attributes.in_tag": "est étiqueté %1$s", + "create.item_attributes.in_tag.inverted": "UNLOCALIZED: is not tagged %1$s", "create.item_attributes.in_item_group": "appartient à %1$s", + "create.item_attributes.in_item_group.inverted": "UNLOCALIZED: is not in group '%1$s'", "create.item_attributes.added_by": "a été ajouté par %1$s", + "create.item_attributes.added_by.inverted": "UNLOCALIZED: was not added by %1$s", "create.gui.attribute_filter.no_selected_attributes": "Aucun attribut sélectionné", "create.gui.attribute_filter.selected_attributes": "Attributs sélectionnés:", + "create.gui.attribute_filter.add_attribute": "UNLOCALIZED: Add attribute to List", + "create.gui.attribute_filter.add_inverted_attribute": "UNLOCALIZED: Add opposite attribute to List", "create.gui.attribute_filter.whitelist_disjunctive": "Liste blanche (n'importe)", "create.gui.attribute_filter.whitelist_disjunctive.description": "Les objets réussissent s'ils possèdent l'un des attributs sélectionnés.", "create.gui.attribute_filter.whitelist_conjunctive": "Liste blanche (tout)", 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 469aed4fe..8bd21d4f1 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: 431", + "_": "Missing Localizations: 461", "_": "->------------------------] Game Elements [------------------------<-", @@ -679,12 +679,9 @@ "create.gui.adjustable_crate.title": "Baule Regolabile", "create.gui.adjustable_crate.storageSpace": "Spazio di Immagazzinamento", "create.gui.stockpile_switch.title": "Interruttore Accumulatore", - "create.gui.stockpile_switch.lowerLimit": "Soglia Inferiore", - "create.gui.stockpile_switch.upperLimit": "Soglia Superiore", - "create.gui.stockpile_switch.startAt": "Inizia Segnale al", - "create.gui.stockpile_switch.startAbove": "Inizia il Segnale dop.", - "create.gui.stockpile_switch.stopAt": "Ferma Segnale al", - "create.gui.stockpile_switch.stopBelow": "Ferma il Segnale dop.", + "create.gui.stockpile_switch.invert_signal": "UNLOCALIZED: Invert Signal", + "create.gui.stockpile_switch.move_to_lower_at": "UNLOCALIZED: Move to lower lane at %1$s%%", + "create.gui.stockpile_switch.move_to_upper_at": "UNLOCALIZED: Move to upper lane at %1$s%%", "create.gui.sequenced_gearshift.title": "Cambio Sequenziale", "create.gui.sequenced_gearshift.instruction": "Istruzione", "create.gui.sequenced_gearshift.instruction.turn_angle": "Gira", @@ -705,7 +702,8 @@ "create.schematicAndQuill.secondPos": "Seconda posizione impostata.", "create.schematicAndQuill.noTarget": "Premi [Ctrl] per selezionare il Blocco d'Aria.", "create.schematicAndQuill.abort": "Selezione rimossa.", - "create.schematicAndQuill.prompt": "Immettere un nome per lo schema:", + "create.schematicAndQuill.title": "UNLOCALIZED: Schematic Name:", + "create.schematicAndQuill.convert": "UNLOCALIZED: Save and Deploy Immediately", "create.schematicAndQuill.fallbackName": "La mia Schematica", "create.schematicAndQuill.saved": "Salvata come %1$s", @@ -756,24 +754,29 @@ "create.schematics.maxAllowedSize": "La dimensione massima consentita del file schematica è:", "create.gui.schematicTable.title": "Banco Schematico", + "create.gui.schematicTable.refresh": "UNLOCALIZED: Refresh Files", + "create.gui.schematicTable.open_folder": "UNLOCALIZED: Open Folder", "create.gui.schematicTable.availableSchematics": "Schatiche disponibili", "create.gui.schematicTable.noSchematics": "Nessuna Schatica Salvata", "create.gui.schematicTable.uploading": "Caricamento...", "create.gui.schematicTable.finished": "Caricamento Finito!", "create.gui.schematicannon.title": "Cannoneschematico", - "create.gui.schematicannon.settingsTitle": "Impostazioni di Posizionamento", "create.gui.schematicannon.listPrinter": "Stampante Lisra dei Materiali", "create.gui.schematicannon.gunpowderLevel": "Polvere da sparo al %1$s%%", "create.gui.schematicannon.shotsRemaining": "Spari Rimanenti: %1$s", "create.gui.schematicannon.shotsRemainingWithBackup": "Con il backup: %1$s", "create.gui.schematicannon.optionEnabled": "Attualmente Abilitato", "create.gui.schematicannon.optionDisabled": "Attualmente Disabilitato", + "create.gui.schematicannon.showOptions": "UNLOCALIZED: Show Printer Settings", "create.gui.schematicannon.option.dontReplaceSolid": "Non sostituire i Blocchi Solidi", "create.gui.schematicannon.option.replaceWithSolid": "Sostituisci Solidi con Solidi", "create.gui.schematicannon.option.replaceWithAny": "Sostituisci Solidi con Qualsiasi", "create.gui.schematicannon.option.replaceWithEmpty": "Sostituisci Solidi con il Vuoto", "create.gui.schematicannon.option.skipMissing": "Salta i Blocchi Mancanti", "create.gui.schematicannon.option.skipTileEntities": "Proteggi i Blocchi Entità", + "create.gui.schematicannon.slot.gunpowder": "UNLOCALIZED: Add gunpowder to fuel the cannon", + "create.gui.schematicannon.slot.listPrinter": "UNLOCALIZED: Place books here to print a Checklist for your Schematic", + "create.gui.schematicannon.slot.schematic": "UNLOCALIZED: Add your Schematic here. Make sure it is deployed at a specific location.", "create.gui.schematicannon.option.skipMissing.description": "Se il cannone non riesce a trovare un blocco richiesto per il posizionamento, continuerà nella posizione successiva.", "create.gui.schematicannon.option.skipTileEntities.description": "Il cannone eviterà di sostituire i blocchi di dati come bauli.", "create.gui.schematicannon.option.dontReplaceSolid.description": "Il cannone non sostituirà mai alcun blocco Solido nella sua area di lavoro, solo non solidi e aria.", @@ -809,23 +812,42 @@ "create.gui.filter.ignore_data.description": "Gli oggetti corrispondono indipendentemente dai loro attributi.", "create.item_attributes.placeable": "è posizionabile", + "create.item_attributes.placeable.inverted": "UNLOCALIZED: is not placeable", "create.item_attributes.consumable": "può essere mangiato", + "create.item_attributes.consumable.inverted": "UNLOCALIZED: cannot be eaten", "create.item_attributes.smeltable": "può essere Fuso", + "create.item_attributes.smeltable.inverted": "UNLOCALIZED: cannot be Smelted", "create.item_attributes.washable": "può essere Lavato", + "create.item_attributes.washable.inverted": "UNLOCALIZED: cannot be Washed", "create.item_attributes.smokable": "può essere Affumicato", + "create.item_attributes.smokable.inverted": "UNLOCALIZED: cannot be Smoked", + "create.item_attributes.crushable": "UNLOCALIZED: can be Crushed", + "create.item_attributes.crushable.inverted": "UNLOCALIZED: cannot be Crushed", "create.item_attributes.blastable": "è fondibile in un Forno fusorio", + "create.item_attributes.blastable.inverted": "UNLOCALIZED: is not smeltable in Blast Furnace", "create.item_attributes.enchanted": "è incantato", + "create.item_attributes.enchanted.inverted": "UNLOCALIZED: is unenchanted", "create.item_attributes.damaged": "è danneggiato", + "create.item_attributes.damaged.inverted": "UNLOCALIZED: is not damaged", "create.item_attributes.badly_damaged": "è gravemente danneggiato", + "create.item_attributes.badly_damaged.inverted": "UNLOCALIZED: is not heavily damaged", "create.item_attributes.not_stackable": "non impilabile", + "create.item_attributes.not_stackable.inverted": "UNLOCALIZED: can be stacked", "create.item_attributes.equipable": "può essere equipaggiato", + "create.item_attributes.equipable.inverted": "UNLOCALIZED: cannot be equipped", "create.item_attributes.furnace_fuel": "è il combustibile della fornace", + "create.item_attributes.furnace_fuel.inverted": "UNLOCALIZED: is not furnace fuel", "create.item_attributes.in_tag": "è etichettato %1$s", + "create.item_attributes.in_tag.inverted": "UNLOCALIZED: is not tagged %1$s", "create.item_attributes.in_item_group": "appartiene a %1$s", + "create.item_attributes.in_item_group.inverted": "UNLOCALIZED: is not in group '%1$s'", "create.item_attributes.added_by": "è stato aggiunto da %1$s", + "create.item_attributes.added_by.inverted": "UNLOCALIZED: was not added by %1$s", "create.gui.attribute_filter.no_selected_attributes": "Nessun attributo selezionato", "create.gui.attribute_filter.selected_attributes": "Attributi selezionati:", + "create.gui.attribute_filter.add_attribute": "UNLOCALIZED: Add attribute to List", + "create.gui.attribute_filter.add_inverted_attribute": "UNLOCALIZED: Add opposite attribute to List", "create.gui.attribute_filter.whitelist_disjunctive": "Lista Bianca (Qualsiasi)", "create.gui.attribute_filter.whitelist_disjunctive.description": "Gli oggetti passano se hanno uno degli attributi selezionati.", "create.gui.attribute_filter.whitelist_conjunctive": "Lista Bianca (Tutti)", 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 adc7f0ed1..2344475a9 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: 426", + "_": "Missing Localizations: 456", "_": "->------------------------] Game Elements [------------------------<-", @@ -679,12 +679,9 @@ "create.gui.adjustable_crate.title": "調整可能なクレート", "create.gui.adjustable_crate.storageSpace": "収納スペース", "create.gui.stockpile_switch.title": "在庫スイッチ", - "create.gui.stockpile_switch.lowerLimit": "下限しきい値", - "create.gui.stockpile_switch.upperLimit": "上限しきい値", - "create.gui.stockpile_switch.startAt": "開始信号", - "create.gui.stockpile_switch.startAbove": "以上の開始信号", - "create.gui.stockpile_switch.stopAt": "停止信号", - "create.gui.stockpile_switch.stopBelow": "以下の停止信号", + "create.gui.stockpile_switch.invert_signal": "UNLOCALIZED: Invert Signal", + "create.gui.stockpile_switch.move_to_lower_at": "UNLOCALIZED: Move to lower lane at %1$s%%", + "create.gui.stockpile_switch.move_to_upper_at": "UNLOCALIZED: Move to upper lane at %1$s%%", "create.gui.sequenced_gearshift.title": "シーケンスギアシフト", "create.gui.sequenced_gearshift.instruction": "命令", "create.gui.sequenced_gearshift.instruction.turn_angle": "回転", @@ -705,7 +702,8 @@ "create.schematicAndQuill.secondPos": "2番目の位置セット。", "create.schematicAndQuill.noTarget": "[Ctrl] を押したままで空気ブロックを選択します", "create.schematicAndQuill.abort": "選択を削除しました。", - "create.schematicAndQuill.prompt": "概略図の名前を入力してください:", + "create.schematicAndQuill.title": "UNLOCALIZED: Schematic Name:", + "create.schematicAndQuill.convert": "UNLOCALIZED: Save and Deploy Immediately", "create.schematicAndQuill.fallbackName": "My Schematic", "create.schematicAndQuill.saved": "%1$s として保存しました", @@ -756,24 +754,29 @@ "create.schematics.maxAllowedSize": "最大許容概略図ファイルサイズは:", "create.gui.schematicTable.title": "概略図テーブル", + "create.gui.schematicTable.refresh": "UNLOCALIZED: Refresh Files", + "create.gui.schematicTable.open_folder": "UNLOCALIZED: Open Folder", "create.gui.schematicTable.availableSchematics": "利用可能な概略図", "create.gui.schematicTable.noSchematics": "保存された概略図はありません", "create.gui.schematicTable.uploading": "アップロードしています...", "create.gui.schematicTable.finished": "アップロードが完了しました!", "create.gui.schematicannon.title": "概略図砲", - "create.gui.schematicannon.settingsTitle": "配置設定", "create.gui.schematicannon.listPrinter": "材料リストプリンター", "create.gui.schematicannon.gunpowderLevel": "火薬はあと %1$s%% 残っています", "create.gui.schematicannon.shotsRemaining": "残りのショット数: %1$s", "create.gui.schematicannon.shotsRemainingWithBackup": "バックアップあり: %1$s", "create.gui.schematicannon.optionEnabled": "現在有効", "create.gui.schematicannon.optionDisabled": "現在無効", + "create.gui.schematicannon.showOptions": "UNLOCALIZED: Show Printer Settings", "create.gui.schematicannon.option.dontReplaceSolid": "固体ブロックを置き換えない", "create.gui.schematicannon.option.replaceWithSolid": "固体を固体に置き換える", "create.gui.schematicannon.option.replaceWithAny": "固体を任意のものに置き換える", "create.gui.schematicannon.option.replaceWithEmpty": "空の固体と交換", "create.gui.schematicannon.option.skipMissing": "不足しているブロックをスキップ", "create.gui.schematicannon.option.skipTileEntities": "タイルエンティティを保護する", + "create.gui.schematicannon.slot.gunpowder": "UNLOCALIZED: Add gunpowder to fuel the cannon", + "create.gui.schematicannon.slot.listPrinter": "UNLOCALIZED: Place books here to print a Checklist for your Schematic", + "create.gui.schematicannon.slot.schematic": "UNLOCALIZED: Add your Schematic here. Make sure it is deployed at a specific location.", "create.gui.schematicannon.option.skipMissing.description": "大砲が配置に必要なブロックを見つけられない場合、次の場所に進みます。", "create.gui.schematicannon.option.skipTileEntities.description": "大砲は、チェストなどのデータ保持ブロックの交換を回避します。", "create.gui.schematicannon.option.dontReplaceSolid.description": "大砲は、その作業領域の固体ブロックを置き換えることはなく、非固体と空気のみを置き換えます。", @@ -809,23 +812,42 @@ "create.gui.filter.ignore_data.description": "アイテムは属性に関係なく一致します。", "create.item_attributes.placeable": "設置可能か", + "create.item_attributes.placeable.inverted": "UNLOCALIZED: is not placeable", "create.item_attributes.consumable": "食べられるか", + "create.item_attributes.consumable.inverted": "UNLOCALIZED: cannot be eaten", "create.item_attributes.smeltable": "精錬可能か", + "create.item_attributes.smeltable.inverted": "UNLOCALIZED: cannot be Smelted", "create.item_attributes.washable": "洗えるか", + "create.item_attributes.washable.inverted": "UNLOCALIZED: cannot be Washed", "create.item_attributes.smokable": "燻製可能か", + "create.item_attributes.smokable.inverted": "UNLOCALIZED: cannot be Smoked", + "create.item_attributes.crushable": "UNLOCALIZED: can be Crushed", + "create.item_attributes.crushable.inverted": "UNLOCALIZED: cannot be Crushed", "create.item_attributes.blastable": "高炉で製錬可能か", + "create.item_attributes.blastable.inverted": "UNLOCALIZED: is not smeltable in Blast Furnace", "create.item_attributes.enchanted": "エンチャント済みか", + "create.item_attributes.enchanted.inverted": "UNLOCALIZED: is unenchanted", "create.item_attributes.damaged": "破損してるか", + "create.item_attributes.damaged.inverted": "UNLOCALIZED: is not damaged", "create.item_attributes.badly_damaged": "ひどく損傷してるか", + "create.item_attributes.badly_damaged.inverted": "UNLOCALIZED: is not heavily damaged", "create.item_attributes.not_stackable": "スタック可能か", + "create.item_attributes.not_stackable.inverted": "UNLOCALIZED: can be stacked", "create.item_attributes.equipable": "装備可能か", + "create.item_attributes.equipable.inverted": "UNLOCALIZED: cannot be equipped", "create.item_attributes.furnace_fuel": "かまどの燃料か", + "create.item_attributes.furnace_fuel.inverted": "UNLOCALIZED: is not furnace fuel", "create.item_attributes.in_tag": "%1$s のタグが付けられてるか", + "create.item_attributes.in_tag.inverted": "UNLOCALIZED: is not tagged %1$s", "create.item_attributes.in_item_group": "%1$s に属してるか", + "create.item_attributes.in_item_group.inverted": "UNLOCALIZED: is not in group '%1$s'", "create.item_attributes.added_by": "%1$s によって追加されたか", + "create.item_attributes.added_by.inverted": "UNLOCALIZED: was not added by %1$s", "create.gui.attribute_filter.no_selected_attributes": "属性が選択されていません", "create.gui.attribute_filter.selected_attributes": "選択された属性:", + "create.gui.attribute_filter.add_attribute": "UNLOCALIZED: Add attribute to List", + "create.gui.attribute_filter.add_inverted_attribute": "UNLOCALIZED: Add opposite attribute to List", "create.gui.attribute_filter.whitelist_disjunctive": "ホワイトリスト(どれか)", "create.gui.attribute_filter.whitelist_disjunctive.description": "選択した属性のいずれかを持っている場合、アイテムは通り抜けます。", "create.gui.attribute_filter.whitelist_conjunctive": "ホワイトリスト(全て)", 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 345430ff2..cd6cdeed1 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: 431", + "_": "Missing Localizations: 461", "_": "->------------------------] Game Elements [------------------------<-", @@ -679,12 +679,9 @@ "create.gui.adjustable_crate.title": "가변 창고 ", "create.gui.adjustable_crate.storageSpace": "저장 공간", "create.gui.stockpile_switch.title": "수량 스위치", - "create.gui.stockpile_switch.lowerLimit": "최소 신호 유지수량", - "create.gui.stockpile_switch.upperLimit": "최초 신호 발동수량", - "create.gui.stockpile_switch.startAt": "다음 수량에 신호 주기", - "create.gui.stockpile_switch.startAbove": "다음 수량이상일떄 신호 주기", - "create.gui.stockpile_switch.stopAt": "다음 수량에 신호 멈추기", - "create.gui.stockpile_switch.stopBelow": "다음 수량이하일때 신호 멈추기", + "create.gui.stockpile_switch.invert_signal": "UNLOCALIZED: Invert Signal", + "create.gui.stockpile_switch.move_to_lower_at": "UNLOCALIZED: Move to lower lane at %1$s%%", + "create.gui.stockpile_switch.move_to_upper_at": "UNLOCALIZED: Move to upper lane at %1$s%%", "create.gui.sequenced_gearshift.title": "순서 기어쉬프트", "create.gui.sequenced_gearshift.instruction": "설명", "create.gui.sequenced_gearshift.instruction.turn_angle": "회전", @@ -705,7 +702,8 @@ "create.schematicAndQuill.secondPos": "두번째 위치 지정됨.", "create.schematicAndQuill.noTarget": "[Ctrl]을 눌러 공기 블럭을 선택하기.", "create.schematicAndQuill.abort": "위치 제거됨.", - "create.schematicAndQuill.prompt": "청사진의 제목을 작성하기:", + "create.schematicAndQuill.title": "UNLOCALIZED: Schematic Name:", + "create.schematicAndQuill.convert": "UNLOCALIZED: Save and Deploy Immediately", "create.schematicAndQuill.fallbackName": "내 청사진", "create.schematicAndQuill.saved": "%1$s로 저장됨", @@ -756,24 +754,29 @@ "create.schematics.maxAllowedSize": "최대 청사진 파일 크기는:", "create.gui.schematicTable.title": "청사진 테이블", + "create.gui.schematicTable.refresh": "UNLOCALIZED: Refresh Files", + "create.gui.schematicTable.open_folder": "UNLOCALIZED: Open Folder", "create.gui.schematicTable.availableSchematics": "이용가능한 청사진", "create.gui.schematicTable.noSchematics": "저장된 청사진 없음", "create.gui.schematicTable.uploading": "업로딩 중...", "create.gui.schematicTable.finished": "업로드 완료!", "create.gui.schematicannon.title": "청사진 대포", - "create.gui.schematicannon.settingsTitle": "설치 설정", "create.gui.schematicannon.listPrinter": "재료 목록 프린터", "create.gui.schematicannon.gunpowderLevel": "화약 용량 %1$s%%", "create.gui.schematicannon.shotsRemaining": "남은 발포 수 : %1$s", "create.gui.schematicannon.shotsRemainingWithBackup": "화약 여분: %1$s", "create.gui.schematicannon.optionEnabled": "현재 활성화 됨", "create.gui.schematicannon.optionDisabled": "현재 비활성화 됨", + "create.gui.schematicannon.showOptions": "UNLOCALIZED: Show Printer Settings", "create.gui.schematicannon.option.dontReplaceSolid": "온전한 블럭을 대체하지 않음", "create.gui.schematicannon.option.replaceWithSolid": "온전한 블럭을 재료로 대체함", "create.gui.schematicannon.option.replaceWithAny": "온전한 블럭을 아무 재료로 대체함", "create.gui.schematicannon.option.replaceWithEmpty": "온전한 블럭을 공기로 채움", "create.gui.schematicannon.option.skipMissing": "부족한 블럭을 무시하고 진행", "create.gui.schematicannon.option.skipTileEntities": "타일 엔티티를 보호", + "create.gui.schematicannon.slot.gunpowder": "UNLOCALIZED: Add gunpowder to fuel the cannon", + "create.gui.schematicannon.slot.listPrinter": "UNLOCALIZED: Place books here to print a Checklist for your Schematic", + "create.gui.schematicannon.slot.schematic": "UNLOCALIZED: Add your Schematic here. Make sure it is deployed at a specific location.", "create.gui.schematicannon.option.skipMissing.description": "만약 대포가 설치에 필요한 블럭을 찾지 못할 경우,건너뛰고 다음 블럭 설치를 진행합니다.", "create.gui.schematicannon.option.skipTileEntities.description": "대포가 상세정보가 든 상자같은 타일 엔티티 설치를 무시합니다.", "create.gui.schematicannon.option.dontReplaceSolid.description": "대포가 작업구역의 온전한 블럭을 대체하지 않습니다.", @@ -809,23 +812,42 @@ "create.gui.filter.ignore_data.description": "상세정보와 상관없이 아이템 종류만 일치한다면 통과시킵니다.", "create.item_attributes.placeable": "설치할 수 있음", + "create.item_attributes.placeable.inverted": "UNLOCALIZED: is not placeable", "create.item_attributes.consumable": "먹을 수 있음", + "create.item_attributes.consumable.inverted": "UNLOCALIZED: cannot be eaten", "create.item_attributes.smeltable": "구워질 수 있음", + "create.item_attributes.smeltable.inverted": "UNLOCALIZED: cannot be Smelted", "create.item_attributes.washable": "세척될 수 있음", + "create.item_attributes.washable.inverted": "UNLOCALIZED: cannot be Washed", "create.item_attributes.smokable": "훈연될 수 있음", + "create.item_attributes.smokable.inverted": "UNLOCALIZED: cannot be Smoked", + "create.item_attributes.crushable": "UNLOCALIZED: can be Crushed", + "create.item_attributes.crushable.inverted": "UNLOCALIZED: cannot be Crushed", "create.item_attributes.blastable": "용광로에 녹일 수 있음", + "create.item_attributes.blastable.inverted": "UNLOCALIZED: is not smeltable in Blast Furnace", "create.item_attributes.enchanted": "마법부여됨", + "create.item_attributes.enchanted.inverted": "UNLOCALIZED: is unenchanted", "create.item_attributes.damaged": "내구도가 닮", + "create.item_attributes.damaged.inverted": "UNLOCALIZED: is not damaged", "create.item_attributes.badly_damaged": "심각하게 내구도가 닮", + "create.item_attributes.badly_damaged.inverted": "UNLOCALIZED: is not heavily damaged", "create.item_attributes.not_stackable": "겹쳐질 수 없음", + "create.item_attributes.not_stackable.inverted": "UNLOCALIZED: can be stacked", "create.item_attributes.equipable": "장착할 수 있음", + "create.item_attributes.equipable.inverted": "UNLOCALIZED: cannot be equipped", "create.item_attributes.furnace_fuel": "화로 연료로 쓸 수 있음", + "create.item_attributes.furnace_fuel.inverted": "UNLOCALIZED: is not furnace fuel", "create.item_attributes.in_tag": "%1$s로 등록됨", + "create.item_attributes.in_tag.inverted": "UNLOCALIZED: is not tagged %1$s", "create.item_attributes.in_item_group": "%1$s탭에 속함", + "create.item_attributes.in_item_group.inverted": "UNLOCALIZED: is not in group '%1$s'", "create.item_attributes.added_by": "%1$s가 추가함", + "create.item_attributes.added_by.inverted": "UNLOCALIZED: was not added by %1$s", "create.gui.attribute_filter.no_selected_attributes": "속성이 선택되지 않음", "create.gui.attribute_filter.selected_attributes": "선택된 속성:", + "create.gui.attribute_filter.add_attribute": "UNLOCALIZED: Add attribute to List", + "create.gui.attribute_filter.add_inverted_attribute": "UNLOCALIZED: Add opposite attribute to List", "create.gui.attribute_filter.whitelist_disjunctive": "화이트리스트 (최소)", "create.gui.attribute_filter.whitelist_disjunctive.description": "아이템이 선택된 속성 중 하나라도 가지고 있다면 통과시킵니다.", "create.gui.attribute_filter.whitelist_conjunctive": "화이트리스트 (모두)", 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 a9bd3d243..4f50be3b3 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: 761", + "_": "Missing Localizations: 791", "_": "->------------------------] Game Elements [------------------------<-", @@ -679,12 +679,9 @@ "create.gui.adjustable_crate.title": "FlexKrat", "create.gui.adjustable_crate.storageSpace": "Opslagruimte", "create.gui.stockpile_switch.title": "Voorraad Schakelaar", - "create.gui.stockpile_switch.lowerLimit": "Lagere drempel", - "create.gui.stockpile_switch.upperLimit": "Hogere drempel", - "create.gui.stockpile_switch.startAt": "Start Signaal op", - "create.gui.stockpile_switch.startAbove": "Start Signaal boven", - "create.gui.stockpile_switch.stopAt": "Stop Signaal op", - "create.gui.stockpile_switch.stopBelow": "Stop Signaal onder", + "create.gui.stockpile_switch.invert_signal": "UNLOCALIZED: Invert Signal", + "create.gui.stockpile_switch.move_to_lower_at": "UNLOCALIZED: Move to lower lane at %1$s%%", + "create.gui.stockpile_switch.move_to_upper_at": "UNLOCALIZED: Move to upper lane at %1$s%%", "create.gui.sequenced_gearshift.title": "UNLOCALIZED: Sequenced Gearshift", "create.gui.sequenced_gearshift.instruction": "UNLOCALIZED: Instruction", "create.gui.sequenced_gearshift.instruction.turn_angle": "UNLOCALIZED: Turn", @@ -705,7 +702,8 @@ "create.schematicAndQuill.secondPos": "Tweede positie ingesteld.", "create.schematicAndQuill.noTarget": "Houd [Ctrl] ingedrukt om een Lucht block te kiezen.", "create.schematicAndQuill.abort": "Keuze verwijderd.", - "create.schematicAndQuill.prompt": "Vul een naam in voor de bouwtekening:", + "create.schematicAndQuill.title": "UNLOCALIZED: Schematic Name:", + "create.schematicAndQuill.convert": "UNLOCALIZED: Save and Deploy Immediately", "create.schematicAndQuill.fallbackName": "Mijn Bouwtekening", "create.schematicAndQuill.saved": "Opgeslagen als %1$s", @@ -756,24 +754,29 @@ "create.schematics.maxAllowedSize": "De maximum toegestane grote van een Bouwtekings bestand is:", "create.gui.schematicTable.title": "Bouwtekening Tafel", + "create.gui.schematicTable.refresh": "UNLOCALIZED: Refresh Files", + "create.gui.schematicTable.open_folder": "UNLOCALIZED: Open Folder", "create.gui.schematicTable.availableSchematics": "Beschikbare Bouwtekeningen", "create.gui.schematicTable.noSchematics": "Geen Bouwtekeningen opgeslagen", "create.gui.schematicTable.uploading": "Uploaden...", "create.gui.schematicTable.finished": "Upload Klaar!", "create.gui.schematicannon.title": "Bouwtekeningkannon", - "create.gui.schematicannon.settingsTitle": "Plaatsing Instellingen", "create.gui.schematicannon.listPrinter": "Materiaal lijst Printer", "create.gui.schematicannon.gunpowderLevel": "Buskruit op %1$s%%", "create.gui.schematicannon.shotsRemaining": "Schoten over: %1$s", "create.gui.schematicannon.shotsRemainingWithBackup": "Met backup: %1$s", "create.gui.schematicannon.optionEnabled": "Momenteel Ingeschakeld", "create.gui.schematicannon.optionDisabled": "Momenteel Uitgeschakeld", + "create.gui.schematicannon.showOptions": "UNLOCALIZED: Show Printer Settings", "create.gui.schematicannon.option.dontReplaceSolid": "Niet vaste blokken vervangen", "create.gui.schematicannon.option.replaceWithSolid": "Vervang vast met vast", "create.gui.schematicannon.option.replaceWithAny": "Vervang vast met alles", "create.gui.schematicannon.option.replaceWithEmpty": "Vervang vast met leeg", "create.gui.schematicannon.option.skipMissing": "Sla missende blokken over", "create.gui.schematicannon.option.skipTileEntities": "Bescherm Tile Entities", + "create.gui.schematicannon.slot.gunpowder": "UNLOCALIZED: Add gunpowder to fuel the cannon", + "create.gui.schematicannon.slot.listPrinter": "UNLOCALIZED: Place books here to print a Checklist for your Schematic", + "create.gui.schematicannon.slot.schematic": "UNLOCALIZED: Add your Schematic here. Make sure it is deployed at a specific location.", "create.gui.schematicannon.option.skipMissing.description": "Als het Bouwtekeningkannon niet een geschikt blok kan vinden om te plaatsen gaat hij door bij de volgende locatie.", "create.gui.schematicannon.option.skipTileEntities.description": "Het Bouwtekeningkannon probeert blokken met data zoals kisten te vermijden", "create.gui.schematicannon.option.dontReplaceSolid.description": "Het Bouwtekeningkannon zal nooit vaste blokken in zijn gebied vervangen, alleen niet-vaste blokken en lucht", @@ -809,23 +812,42 @@ "create.gui.filter.ignore_data.description": "UNLOCALIZED: Items match regardless of their attributes.", "create.item_attributes.placeable": "UNLOCALIZED: is placeable", + "create.item_attributes.placeable.inverted": "UNLOCALIZED: is not placeable", "create.item_attributes.consumable": "UNLOCALIZED: can be eaten", + "create.item_attributes.consumable.inverted": "UNLOCALIZED: cannot be eaten", "create.item_attributes.smeltable": "UNLOCALIZED: can be Smelted", + "create.item_attributes.smeltable.inverted": "UNLOCALIZED: cannot be Smelted", "create.item_attributes.washable": "UNLOCALIZED: can be Washed", + "create.item_attributes.washable.inverted": "UNLOCALIZED: cannot be Washed", "create.item_attributes.smokable": "UNLOCALIZED: can be Smoked", + "create.item_attributes.smokable.inverted": "UNLOCALIZED: cannot be Smoked", + "create.item_attributes.crushable": "UNLOCALIZED: can be Crushed", + "create.item_attributes.crushable.inverted": "UNLOCALIZED: cannot be Crushed", "create.item_attributes.blastable": "UNLOCALIZED: is smeltable in Blast Furnace", + "create.item_attributes.blastable.inverted": "UNLOCALIZED: is not smeltable in Blast Furnace", "create.item_attributes.enchanted": "UNLOCALIZED: is enchanted", + "create.item_attributes.enchanted.inverted": "UNLOCALIZED: is unenchanted", "create.item_attributes.damaged": "UNLOCALIZED: is damaged", + "create.item_attributes.damaged.inverted": "UNLOCALIZED: is not damaged", "create.item_attributes.badly_damaged": "UNLOCALIZED: is heavily damaged", + "create.item_attributes.badly_damaged.inverted": "UNLOCALIZED: is not heavily damaged", "create.item_attributes.not_stackable": "UNLOCALIZED: cannot stack", + "create.item_attributes.not_stackable.inverted": "UNLOCALIZED: can be stacked", "create.item_attributes.equipable": "UNLOCALIZED: can be equipped", + "create.item_attributes.equipable.inverted": "UNLOCALIZED: cannot be equipped", "create.item_attributes.furnace_fuel": "UNLOCALIZED: is furnace fuel", + "create.item_attributes.furnace_fuel.inverted": "UNLOCALIZED: is not furnace fuel", "create.item_attributes.in_tag": "UNLOCALIZED: is tagged %1$s", - "create.item_attributes.in_item_group": "UNLOCALIZED: belongs to %1$s", + "create.item_attributes.in_tag.inverted": "UNLOCALIZED: is not tagged %1$s", + "create.item_attributes.in_item_group": "UNLOCALIZED: is in group '%1$s'", + "create.item_attributes.in_item_group.inverted": "UNLOCALIZED: is not in group '%1$s'", "create.item_attributes.added_by": "UNLOCALIZED: was added by %1$s", + "create.item_attributes.added_by.inverted": "UNLOCALIZED: was not added by %1$s", "create.gui.attribute_filter.no_selected_attributes": "UNLOCALIZED: No attributes selected", "create.gui.attribute_filter.selected_attributes": "UNLOCALIZED: Selected attributes:", + "create.gui.attribute_filter.add_attribute": "UNLOCALIZED: Add attribute to List", + "create.gui.attribute_filter.add_inverted_attribute": "UNLOCALIZED: Add opposite attribute to List", "create.gui.attribute_filter.whitelist_disjunctive": "UNLOCALIZED: Whitelist (Any)", "create.gui.attribute_filter.whitelist_disjunctive.description": "UNLOCALIZED: Items pass if they have any of the selected attributes.", "create.gui.attribute_filter.whitelist_conjunctive": "UNLOCALIZED: Whitelist (All)", 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 cddf57c76..8b67ae7a3 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: 830", + "_": "Missing Localizations: 860", "_": "->------------------------] Game Elements [------------------------<-", @@ -679,12 +679,9 @@ "create.gui.adjustable_crate.title": "adjustable_crate", "create.gui.adjustable_crate.storageSpace": "Espaço de Armazenamento", "create.gui.stockpile_switch.title": "Disjuntor de Armazenamento", - "create.gui.stockpile_switch.lowerLimit": "Limite Mínimo", - "create.gui.stockpile_switch.upperLimit": "Limite Máximo", - "create.gui.stockpile_switch.startAt": "Iniciar Sinal em", - "create.gui.stockpile_switch.startAbove": "Iniciar Sinal acima de", - "create.gui.stockpile_switch.stopAt": "Parar Sinal em", - "create.gui.stockpile_switch.stopBelow": "Parar Sinal abaixo de", + "create.gui.stockpile_switch.invert_signal": "UNLOCALIZED: Invert Signal", + "create.gui.stockpile_switch.move_to_lower_at": "UNLOCALIZED: Move to lower lane at %1$s%%", + "create.gui.stockpile_switch.move_to_upper_at": "UNLOCALIZED: Move to upper lane at %1$s%%", "create.gui.sequenced_gearshift.title": "UNLOCALIZED: Sequenced Gearshift", "create.gui.sequenced_gearshift.instruction": "UNLOCALIZED: Instruction", "create.gui.sequenced_gearshift.instruction.turn_angle": "UNLOCALIZED: Turn", @@ -705,7 +702,8 @@ "create.schematicAndQuill.secondPos": "Segunda posição feita.", "create.schematicAndQuill.noTarget": "Seguro [Ctrl] para selecionar Blocos de Ar.", "create.schematicAndQuill.abort": "Seleção removida.", - "create.schematicAndQuill.prompt": "Informe um nome para o Esquema:", + "create.schematicAndQuill.title": "UNLOCALIZED: Schematic Name:", + "create.schematicAndQuill.convert": "UNLOCALIZED: Save and Deploy Immediately", "create.schematicAndQuill.fallbackName": "Meu Esquema", "create.schematicAndQuill.saved": "Salvo como %1$s", @@ -756,24 +754,29 @@ "create.schematics.maxAllowedSize": "O tamanho máximo permitido para o esquema é:", "create.gui.schematicTable.title": "Mesa de Desenho", + "create.gui.schematicTable.refresh": "UNLOCALIZED: Refresh Files", + "create.gui.schematicTable.open_folder": "UNLOCALIZED: Open Folder", "create.gui.schematicTable.availableSchematics": "UNLOCALIZED: Available Schematics", "create.gui.schematicTable.noSchematics": "UNLOCALIZED: No Schematics Saved", "create.gui.schematicTable.uploading": "Importando...", "create.gui.schematicTable.finished": "Envio Concluído!", "create.gui.schematicannon.title": "Esquemaannon", - "create.gui.schematicannon.settingsTitle": "Parâmetros de Posicionamento", "create.gui.schematicannon.listPrinter": "Impressora de Lista de Materiais", "create.gui.schematicannon.gunpowderLevel": "Pólvora em %1$s%%", "create.gui.schematicannon.shotsRemaining": "Disparos faltantes: %1$s", "create.gui.schematicannon.shotsRemainingWithBackup": "Com backup: %1$s", "create.gui.schematicannon.optionEnabled": "Habilitado Atualmente", "create.gui.schematicannon.optionDisabled": "Desabilitado Atualmente", + "create.gui.schematicannon.showOptions": "UNLOCALIZED: Show Printer Settings", "create.gui.schematicannon.option.dontReplaceSolid": "Não Substituir Blocos Sólidos", "create.gui.schematicannon.option.replaceWithSolid": "Substituir Blocos Sólidos", "create.gui.schematicannon.option.replaceWithAny": "Substituir Sólidos com Qualquer", "create.gui.schematicannon.option.replaceWithEmpty": "Substituir Sólidos com Vazio", "create.gui.schematicannon.option.skipMissing": "Pulando Blocos faltantes", "create.gui.schematicannon.option.skipTileEntities": "Proteger Entidades Entalhadas", + "create.gui.schematicannon.slot.gunpowder": "UNLOCALIZED: Add gunpowder to fuel the cannon", + "create.gui.schematicannon.slot.listPrinter": "UNLOCALIZED: Place books here to print a Checklist for your Schematic", + "create.gui.schematicannon.slot.schematic": "UNLOCALIZED: Add your Schematic here. Make sure it is deployed at a specific location.", "create.gui.schematicannon.option.skipMissing.description": "Se o Esquemaannon não encontrar o Bloco para colocar, ele irá continuar para a próx. Posição.", "create.gui.schematicannon.option.skipTileEntities.description": "O Esquemaannon vai evitar substituir blocos que contêm dados como Baus.", "create.gui.schematicannon.option.dontReplaceSolid.description": "O canhão irá nunca substituir Blocos sólidos na área em trabalho, apenas não-Sólidos e Ar.", @@ -809,23 +812,42 @@ "create.gui.filter.ignore_data.description": "UNLOCALIZED: Items match regardless of their attributes.", "create.item_attributes.placeable": "UNLOCALIZED: is placeable", + "create.item_attributes.placeable.inverted": "UNLOCALIZED: is not placeable", "create.item_attributes.consumable": "UNLOCALIZED: can be eaten", + "create.item_attributes.consumable.inverted": "UNLOCALIZED: cannot be eaten", "create.item_attributes.smeltable": "UNLOCALIZED: can be Smelted", + "create.item_attributes.smeltable.inverted": "UNLOCALIZED: cannot be Smelted", "create.item_attributes.washable": "UNLOCALIZED: can be Washed", + "create.item_attributes.washable.inverted": "UNLOCALIZED: cannot be Washed", "create.item_attributes.smokable": "UNLOCALIZED: can be Smoked", + "create.item_attributes.smokable.inverted": "UNLOCALIZED: cannot be Smoked", + "create.item_attributes.crushable": "UNLOCALIZED: can be Crushed", + "create.item_attributes.crushable.inverted": "UNLOCALIZED: cannot be Crushed", "create.item_attributes.blastable": "UNLOCALIZED: is smeltable in Blast Furnace", + "create.item_attributes.blastable.inverted": "UNLOCALIZED: is not smeltable in Blast Furnace", "create.item_attributes.enchanted": "UNLOCALIZED: is enchanted", + "create.item_attributes.enchanted.inverted": "UNLOCALIZED: is unenchanted", "create.item_attributes.damaged": "UNLOCALIZED: is damaged", + "create.item_attributes.damaged.inverted": "UNLOCALIZED: is not damaged", "create.item_attributes.badly_damaged": "UNLOCALIZED: is heavily damaged", + "create.item_attributes.badly_damaged.inverted": "UNLOCALIZED: is not heavily damaged", "create.item_attributes.not_stackable": "UNLOCALIZED: cannot stack", + "create.item_attributes.not_stackable.inverted": "UNLOCALIZED: can be stacked", "create.item_attributes.equipable": "UNLOCALIZED: can be equipped", + "create.item_attributes.equipable.inverted": "UNLOCALIZED: cannot be equipped", "create.item_attributes.furnace_fuel": "UNLOCALIZED: is furnace fuel", + "create.item_attributes.furnace_fuel.inverted": "UNLOCALIZED: is not furnace fuel", "create.item_attributes.in_tag": "UNLOCALIZED: is tagged %1$s", - "create.item_attributes.in_item_group": "UNLOCALIZED: belongs to %1$s", + "create.item_attributes.in_tag.inverted": "UNLOCALIZED: is not tagged %1$s", + "create.item_attributes.in_item_group": "UNLOCALIZED: is in group '%1$s'", + "create.item_attributes.in_item_group.inverted": "UNLOCALIZED: is not in group '%1$s'", "create.item_attributes.added_by": "UNLOCALIZED: was added by %1$s", + "create.item_attributes.added_by.inverted": "UNLOCALIZED: was not added by %1$s", "create.gui.attribute_filter.no_selected_attributes": "UNLOCALIZED: No attributes selected", "create.gui.attribute_filter.selected_attributes": "UNLOCALIZED: Selected attributes:", + "create.gui.attribute_filter.add_attribute": "UNLOCALIZED: Add attribute to List", + "create.gui.attribute_filter.add_inverted_attribute": "UNLOCALIZED: Add opposite attribute to List", "create.gui.attribute_filter.whitelist_disjunctive": "UNLOCALIZED: Whitelist (Any)", "create.gui.attribute_filter.whitelist_disjunctive.description": "UNLOCALIZED: Items pass if they have any of the selected attributes.", "create.gui.attribute_filter.whitelist_conjunctive": "UNLOCALIZED: Whitelist (All)", 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 0aaaab8c0..cc0e86c5a 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: 824", + "_": "Missing Localizations: 854", "_": "->------------------------] Game Elements [------------------------<-", @@ -679,12 +679,9 @@ "create.gui.adjustable_crate.title": "Гибкий ящик", "create.gui.adjustable_crate.storageSpace": "Обьём хранилища", "create.gui.stockpile_switch.title": "Сенсор хранилища", - "create.gui.stockpile_switch.lowerLimit": "Нижний порог", - "create.gui.stockpile_switch.upperLimit": "Верхний порог", - "create.gui.stockpile_switch.startAt": "Включить на", - "create.gui.stockpile_switch.startAbove": "Включить выше", - "create.gui.stockpile_switch.stopAt": "Отключить на", - "create.gui.stockpile_switch.stopBelow": "Отключить ниже", + "create.gui.stockpile_switch.invert_signal": "UNLOCALIZED: Invert Signal", + "create.gui.stockpile_switch.move_to_lower_at": "UNLOCALIZED: Move to lower lane at %1$s%%", + "create.gui.stockpile_switch.move_to_upper_at": "UNLOCALIZED: Move to upper lane at %1$s%%", "create.gui.sequenced_gearshift.title": "UNLOCALIZED: Sequenced Gearshift", "create.gui.sequenced_gearshift.instruction": "UNLOCALIZED: Instruction", "create.gui.sequenced_gearshift.instruction.turn_angle": "UNLOCALIZED: Turn", @@ -705,7 +702,8 @@ "create.schematicAndQuill.secondPos": "Вторая позиция установлена.", "create.schematicAndQuill.noTarget": "Зажмите [Ctrl], чтобы выделять блоки воздуха.", "create.schematicAndQuill.abort": "Выделение удалено.", - "create.schematicAndQuill.prompt": "Введите название для новой схемы:", + "create.schematicAndQuill.title": "UNLOCALIZED: Schematic Name:", + "create.schematicAndQuill.convert": "UNLOCALIZED: Save and Deploy Immediately", "create.schematicAndQuill.fallbackName": "Моя схема", "create.schematicAndQuill.saved": "Сохранено как %1$s", @@ -756,24 +754,29 @@ "create.schematics.maxAllowedSize": "Максимальный размер файла схемы:", "create.gui.schematicTable.title": "Стол для схем", + "create.gui.schematicTable.refresh": "UNLOCALIZED: Refresh Files", + "create.gui.schematicTable.open_folder": "UNLOCALIZED: Open Folder", "create.gui.schematicTable.availableSchematics": "Доступные схемы", "create.gui.schematicTable.noSchematics": "Нет сохранённых схем", "create.gui.schematicTable.uploading": "Загрузка...", "create.gui.schematicTable.finished": "Загрузка завершена!", "create.gui.schematicannon.title": "Схемопушка", - "create.gui.schematicannon.settingsTitle": "Параметры размещения", "create.gui.schematicannon.listPrinter": "Распечатать список материалов", "create.gui.schematicannon.gunpowderLevel": "Порох: %1$s%%", "create.gui.schematicannon.shotsRemaining": "Выстрелов осталось: %1$s", "create.gui.schematicannon.shotsRemainingWithBackup": "C запасом: %1$s", "create.gui.schematicannon.optionEnabled": "Включена", "create.gui.schematicannon.optionDisabled": "Отключена", + "create.gui.schematicannon.showOptions": "UNLOCALIZED: Show Printer Settings", "create.gui.schematicannon.option.dontReplaceSolid": "Не заменять целые блоки", "create.gui.schematicannon.option.replaceWithSolid": "Заменять целые блоки целыми блоками", "create.gui.schematicannon.option.replaceWithAny": "Заменять целые блоки чем угодно", "create.gui.schematicannon.option.replaceWithEmpty": "Заменять целые блоки пустотой", "create.gui.schematicannon.option.skipMissing": "Пропускать отсутствующие блоки", "create.gui.schematicannon.option.skipTileEntities": "Защита от сущностей", + "create.gui.schematicannon.slot.gunpowder": "UNLOCALIZED: Add gunpowder to fuel the cannon", + "create.gui.schematicannon.slot.listPrinter": "UNLOCALIZED: Place books here to print a Checklist for your Schematic", + "create.gui.schematicannon.slot.schematic": "UNLOCALIZED: Add your Schematic here. Make sure it is deployed at a specific location.", "create.gui.schematicannon.option.skipMissing.description": "Если схемопушка не найдёт нужный блок, то она продолжит в следующем месте.", "create.gui.schematicannon.option.skipTileEntities.description": "Схемопушка будет избегать замены блоков с данными, например сундуки.", "create.gui.schematicannon.option.dontReplaceSolid.description": "Схемопушка никогда не заменит целые блоки, только не целые и воздух.", @@ -809,23 +812,42 @@ "create.gui.filter.ignore_data.description": "UNLOCALIZED: Items match regardless of their attributes.", "create.item_attributes.placeable": "UNLOCALIZED: is placeable", + "create.item_attributes.placeable.inverted": "UNLOCALIZED: is not placeable", "create.item_attributes.consumable": "UNLOCALIZED: can be eaten", + "create.item_attributes.consumable.inverted": "UNLOCALIZED: cannot be eaten", "create.item_attributes.smeltable": "UNLOCALIZED: can be Smelted", + "create.item_attributes.smeltable.inverted": "UNLOCALIZED: cannot be Smelted", "create.item_attributes.washable": "UNLOCALIZED: can be Washed", + "create.item_attributes.washable.inverted": "UNLOCALIZED: cannot be Washed", "create.item_attributes.smokable": "UNLOCALIZED: can be Smoked", + "create.item_attributes.smokable.inverted": "UNLOCALIZED: cannot be Smoked", + "create.item_attributes.crushable": "UNLOCALIZED: can be Crushed", + "create.item_attributes.crushable.inverted": "UNLOCALIZED: cannot be Crushed", "create.item_attributes.blastable": "UNLOCALIZED: is smeltable in Blast Furnace", + "create.item_attributes.blastable.inverted": "UNLOCALIZED: is not smeltable in Blast Furnace", "create.item_attributes.enchanted": "UNLOCALIZED: is enchanted", + "create.item_attributes.enchanted.inverted": "UNLOCALIZED: is unenchanted", "create.item_attributes.damaged": "UNLOCALIZED: is damaged", + "create.item_attributes.damaged.inverted": "UNLOCALIZED: is not damaged", "create.item_attributes.badly_damaged": "UNLOCALIZED: is heavily damaged", + "create.item_attributes.badly_damaged.inverted": "UNLOCALIZED: is not heavily damaged", "create.item_attributes.not_stackable": "UNLOCALIZED: cannot stack", + "create.item_attributes.not_stackable.inverted": "UNLOCALIZED: can be stacked", "create.item_attributes.equipable": "UNLOCALIZED: can be equipped", + "create.item_attributes.equipable.inverted": "UNLOCALIZED: cannot be equipped", "create.item_attributes.furnace_fuel": "UNLOCALIZED: is furnace fuel", + "create.item_attributes.furnace_fuel.inverted": "UNLOCALIZED: is not furnace fuel", "create.item_attributes.in_tag": "UNLOCALIZED: is tagged %1$s", - "create.item_attributes.in_item_group": "UNLOCALIZED: belongs to %1$s", + "create.item_attributes.in_tag.inverted": "UNLOCALIZED: is not tagged %1$s", + "create.item_attributes.in_item_group": "UNLOCALIZED: is in group '%1$s'", + "create.item_attributes.in_item_group.inverted": "UNLOCALIZED: is not in group '%1$s'", "create.item_attributes.added_by": "UNLOCALIZED: was added by %1$s", + "create.item_attributes.added_by.inverted": "UNLOCALIZED: was not added by %1$s", "create.gui.attribute_filter.no_selected_attributes": "UNLOCALIZED: No attributes selected", "create.gui.attribute_filter.selected_attributes": "UNLOCALIZED: Selected attributes:", + "create.gui.attribute_filter.add_attribute": "UNLOCALIZED: Add attribute to List", + "create.gui.attribute_filter.add_inverted_attribute": "UNLOCALIZED: Add opposite attribute to List", "create.gui.attribute_filter.whitelist_disjunctive": "UNLOCALIZED: Whitelist (Any)", "create.gui.attribute_filter.whitelist_disjunctive.description": "UNLOCALIZED: Items pass if they have any of the selected attributes.", "create.gui.attribute_filter.whitelist_conjunctive": "UNLOCALIZED: Whitelist (All)", 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 7d9492e23..ac6a23398 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: 111", + "_": "Missing Localizations: 141", "_": "->------------------------] Game Elements [------------------------<-", @@ -679,12 +679,9 @@ "create.gui.adjustable_crate.title": "板条箱", "create.gui.adjustable_crate.storageSpace": "储存空间", "create.gui.stockpile_switch.title": "储存开关", - "create.gui.stockpile_switch.lowerLimit": "阈值下限", - "create.gui.stockpile_switch.upperLimit": "阈值上限", - "create.gui.stockpile_switch.startAt": "启动信号", - "create.gui.stockpile_switch.startAbove": "给予红石信号当容量大于", - "create.gui.stockpile_switch.stopAt": "停止信号", - "create.gui.stockpile_switch.stopBelow": "停止红石信号当容量小于", + "create.gui.stockpile_switch.invert_signal": "UNLOCALIZED: Invert Signal", + "create.gui.stockpile_switch.move_to_lower_at": "UNLOCALIZED: Move to lower lane at %1$s%%", + "create.gui.stockpile_switch.move_to_upper_at": "UNLOCALIZED: Move to upper lane at %1$s%%", "create.gui.sequenced_gearshift.title": "可编程齿轮箱", "create.gui.sequenced_gearshift.instruction": "指令", "create.gui.sequenced_gearshift.instruction.turn_angle": "旋转", @@ -705,7 +702,8 @@ "create.schematicAndQuill.secondPos": "第二个位置.", "create.schematicAndQuill.noTarget": "按住Ctrl选择空气方块.", "create.schematicAndQuill.abort": "删除选择.", - "create.schematicAndQuill.prompt": "输入蓝图的名称:", + "create.schematicAndQuill.title": "UNLOCALIZED: Schematic Name:", + "create.schematicAndQuill.convert": "UNLOCALIZED: Save and Deploy Immediately", "create.schematicAndQuill.fallbackName": "我的蓝图", "create.schematicAndQuill.saved": "另存为 %1$s", @@ -756,24 +754,29 @@ "create.schematics.maxAllowedSize": "允许的最大蓝图文件大小为:", "create.gui.schematicTable.title": "蓝图桌", + "create.gui.schematicTable.refresh": "UNLOCALIZED: Refresh Files", + "create.gui.schematicTable.open_folder": "UNLOCALIZED: Open Folder", "create.gui.schematicTable.availableSchematics": "可用蓝图", "create.gui.schematicTable.noSchematics": "没有保存的蓝图", "create.gui.schematicTable.uploading": "正在上传...", "create.gui.schematicTable.finished": "上传完成!", "create.gui.schematicannon.title": "蓝图加农炮", - "create.gui.schematicannon.settingsTitle": "放置设置", "create.gui.schematicannon.listPrinter": "物品清单打印机", "create.gui.schematicannon.gunpowderLevel": "火药 %1$s%%", "create.gui.schematicannon.shotsRemaining": "发射进度: %1$s", "create.gui.schematicannon.shotsRemainingWithBackup": "备份: %1$s", "create.gui.schematicannon.optionEnabled": "当前启用", "create.gui.schematicannon.optionDisabled": "当前禁用", + "create.gui.schematicannon.showOptions": "UNLOCALIZED: Show Printer Settings", "create.gui.schematicannon.option.dontReplaceSolid": "不要替换方块", "create.gui.schematicannon.option.replaceWithSolid": "用固体方块替换工作区域内的方块", "create.gui.schematicannon.option.replaceWithAny": "用任何方块替换工作区域内的方块", "create.gui.schematicannon.option.replaceWithEmpty": "用空气替换工作区域内的方块", "create.gui.schematicannon.option.skipMissing": "绕过缺少的方块", "create.gui.schematicannon.option.skipTileEntities": "保护存储方块", + "create.gui.schematicannon.slot.gunpowder": "UNLOCALIZED: Add gunpowder to fuel the cannon", + "create.gui.schematicannon.slot.listPrinter": "UNLOCALIZED: Place books here to print a Checklist for your Schematic", + "create.gui.schematicannon.slot.schematic": "UNLOCALIZED: Add your Schematic here. Make sure it is deployed at a specific location.", "create.gui.schematicannon.option.skipMissing.description": "如果缺失材料, 蓝图大炮将忽略当前缺失材料并且使用其他已有材料继续工作", "create.gui.schematicannon.option.skipTileEntities.description": "蓝图将避免更换存储方块,如箱子.", "create.gui.schematicannon.option.dontReplaceSolid.description": "蓝图加农炮将不会替换工作范围内的任何固体方块.", @@ -809,23 +812,42 @@ "create.gui.filter.ignore_data.description": "匹配时忽视物品的耐久、附魔等其他属性", "create.item_attributes.placeable": "可放置", + "create.item_attributes.placeable.inverted": "UNLOCALIZED: is not placeable", "create.item_attributes.consumable": "可食用", + "create.item_attributes.consumable.inverted": "UNLOCALIZED: cannot be eaten", "create.item_attributes.smeltable": "可被熔炉烧制", + "create.item_attributes.smeltable.inverted": "UNLOCALIZED: cannot be Smelted", "create.item_attributes.washable": "可被筛洗", + "create.item_attributes.washable.inverted": "UNLOCALIZED: cannot be Washed", "create.item_attributes.smokable": "可被烟熏", + "create.item_attributes.smokable.inverted": "UNLOCALIZED: cannot be Smoked", + "create.item_attributes.crushable": "UNLOCALIZED: can be Crushed", + "create.item_attributes.crushable.inverted": "UNLOCALIZED: cannot be Crushed", "create.item_attributes.blastable": "可被高炉冶炼", + "create.item_attributes.blastable.inverted": "UNLOCALIZED: is not smeltable in Blast Furnace", "create.item_attributes.enchanted": "已被附魔", + "create.item_attributes.enchanted.inverted": "UNLOCALIZED: is unenchanted", "create.item_attributes.damaged": "已损坏", + "create.item_attributes.damaged.inverted": "UNLOCALIZED: is not damaged", "create.item_attributes.badly_damaged": "严重受损", + "create.item_attributes.badly_damaged.inverted": "UNLOCALIZED: is not heavily damaged", "create.item_attributes.not_stackable": "无法堆叠", + "create.item_attributes.not_stackable.inverted": "UNLOCALIZED: can be stacked", "create.item_attributes.equipable": "可装备", + "create.item_attributes.equipable.inverted": "UNLOCALIZED: cannot be equipped", "create.item_attributes.furnace_fuel": "是燃料", + "create.item_attributes.furnace_fuel.inverted": "UNLOCALIZED: is not furnace fuel", "create.item_attributes.in_tag": "标签是%1$s", + "create.item_attributes.in_tag.inverted": "UNLOCALIZED: is not tagged %1$s", "create.item_attributes.in_item_group": "属于 %1$s", + "create.item_attributes.in_item_group.inverted": "UNLOCALIZED: is not in group '%1$s'", "create.item_attributes.added_by": "由%1$s添加", + "create.item_attributes.added_by.inverted": "UNLOCALIZED: was not added by %1$s", "create.gui.attribute_filter.no_selected_attributes": "没有标记任何属性", "create.gui.attribute_filter.selected_attributes": "已选择的属性:", + "create.gui.attribute_filter.add_attribute": "UNLOCALIZED: Add attribute to List", + "create.gui.attribute_filter.add_inverted_attribute": "UNLOCALIZED: Add opposite attribute to List", "create.gui.attribute_filter.whitelist_disjunctive": "任意匹配白名单 (任何)", "create.gui.attribute_filter.whitelist_disjunctive.description": "只要有其中一项属性符合,就可以通过", "create.gui.attribute_filter.whitelist_conjunctive": "全匹配白名单 (所有)", diff --git a/src/generated/resources/assets/create/models/item/basin.json b/src/generated/resources/assets/create/models/item/basin.json index 1dc14b2e8..a1ed06ff7 100644 --- a/src/generated/resources/assets/create/models/item/basin.json +++ b/src/generated/resources/assets/create/models/item/basin.json @@ -1,3 +1,3 @@ { - "parent": "create:block/basin" + "parent": "create:block/basin/block" } \ No newline at end of file diff --git a/src/generated/resources/data/create/advancements/recipes/create.base/crafting/kinetics/attribute_filter.json b/src/generated/resources/data/create/advancements/recipes/create.base/crafting/kinetics/attribute_filter.json index 5b1c63f80..e41c26b07 100644 --- a/src/generated/resources/data/create/advancements/recipes/create.base/crafting/kinetics/attribute_filter.json +++ b/src/generated/resources/data/create/advancements/recipes/create.base/crafting/kinetics/attribute_filter.json @@ -11,7 +11,7 @@ "conditions": { "items": [ { - "item": "create:andesite_alloy" + "tag": "forge:ingots/brass" } ] } diff --git a/src/generated/resources/data/create/recipes/compacting/ice.json b/src/generated/resources/data/create/recipes/compacting/ice.json new file mode 100644 index 000000000..98ae992e9 --- /dev/null +++ b/src/generated/resources/data/create/recipes/compacting/ice.json @@ -0,0 +1,14 @@ +{ + "type": "create:compacting", + "ingredients": [ + { + "item": "minecraft:ice" + } + ], + "results": [ + { + "fluid": "minecraft:water", + "amount": 250 + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/recipes/compacting/temp_gabbro.json b/src/generated/resources/data/create/recipes/compacting/temp_gabbro.json new file mode 100644 index 000000000..c5474f6f5 --- /dev/null +++ b/src/generated/resources/data/create/recipes/compacting/temp_gabbro.json @@ -0,0 +1,18 @@ +{ + "type": "create:compacting", + "ingredients": [ + { + "item": "minecraft:cobblestone" + }, + { + "fluidTag": "minecraft:lava", + "amount": 250 + } + ], + "results": [ + { + "item": "create:gabbro", + "count": 1 + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/recipes/crafting/kinetics/attribute_filter.json b/src/generated/resources/data/create/recipes/crafting/kinetics/attribute_filter.json index 15bd0d895..5e1cfd2cc 100644 --- a/src/generated/resources/data/create/recipes/crafting/kinetics/attribute_filter.json +++ b/src/generated/resources/data/create/recipes/crafting/kinetics/attribute_filter.json @@ -8,7 +8,7 @@ "tag": "minecraft:wool" }, "A": { - "tag": "forge:nuggets/copper" + "tag": "forge:nuggets/brass" } }, "result": { diff --git a/src/generated/resources/data/create/recipes/emptying/water_bottle.json b/src/generated/resources/data/create/recipes/emptying/water_bottle.json new file mode 100644 index 000000000..1a34fd570 --- /dev/null +++ b/src/generated/resources/data/create/recipes/emptying/water_bottle.json @@ -0,0 +1,18 @@ +{ + "type": "create:emptying", + "ingredients": [ + { + "item": "minecraft:potion" + } + ], + "results": [ + { + "item": "minecraft:glass_bottle", + "count": 1 + }, + { + "fluid": "minecraft:water", + "amount": 250 + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/create/recipes/mixing/temp_cobble.json b/src/generated/resources/data/create/recipes/mixing/temp_cobble.json new file mode 100644 index 000000000..f20d0e6cf --- /dev/null +++ b/src/generated/resources/data/create/recipes/mixing/temp_cobble.json @@ -0,0 +1,19 @@ +{ + "type": "create:mixing", + "ingredients": [ + { + "fluidTag": "minecraft:water", + "amount": 250 + }, + { + "fluidTag": "minecraft:lava", + "amount": 250 + } + ], + "results": [ + { + "item": "minecraft:cobblestone", + "count": 1 + } + ] +} \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/AllBlocks.java b/src/main/java/com/simibubi/create/AllBlocks.java index c90ae2de4..c7f9c8cef 100644 --- a/src/main/java/com/simibubi/create/AllBlocks.java +++ b/src/main/java/com/simibubi/create/AllBlocks.java @@ -73,6 +73,7 @@ import com.simibubi.create.content.contraptions.fluids.tank.FluidTankGenerator; import com.simibubi.create.content.contraptions.fluids.tank.FluidTankItem; import com.simibubi.create.content.contraptions.fluids.tank.FluidTankModel; import com.simibubi.create.content.contraptions.processing.BasinBlock; +import com.simibubi.create.content.contraptions.processing.BasinGenerator; import com.simibubi.create.content.contraptions.processing.BasinMovementBehaviour; import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock; import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlockItem; @@ -408,9 +409,10 @@ public class AllBlocks { public static final BlockEntry BASIN = REGISTRATE.block("basin", BasinBlock::new) .initialProperties(SharedProperties::stone) - .blockstate((ctx, prov) -> prov.simpleBlock(ctx.getEntry(), AssetLookup.standardModel(ctx, prov))) + .blockstate(new BasinGenerator()::generate) .onRegister(addMovementBehaviour(new BasinMovementBehaviour())) - .simpleItem() + .item() + .transform(customItemModel("_", "block")) .register(); public static final BlockEntry BLAZE_BURNER = diff --git a/src/main/java/com/simibubi/create/AllRecipeTypes.java b/src/main/java/com/simibubi/create/AllRecipeTypes.java index 2e2e6515e..908e39e87 100644 --- a/src/main/java/com/simibubi/create/AllRecipeTypes.java +++ b/src/main/java/com/simibubi/create/AllRecipeTypes.java @@ -1,5 +1,6 @@ package com.simibubi.create; +import java.util.Optional; import java.util.function.Supplier; import com.simibubi.create.compat.jei.ConversionRecipe; @@ -7,10 +8,13 @@ import com.simibubi.create.content.contraptions.components.crafter.MechanicalCra import com.simibubi.create.content.contraptions.components.crusher.CrushingRecipe; import com.simibubi.create.content.contraptions.components.fan.SplashingRecipe; import com.simibubi.create.content.contraptions.components.millstone.MillingRecipe; +import com.simibubi.create.content.contraptions.components.mixer.CompactingRecipe; import com.simibubi.create.content.contraptions.components.mixer.MixingRecipe; import com.simibubi.create.content.contraptions.components.press.PressingRecipe; import com.simibubi.create.content.contraptions.components.saw.CuttingRecipe; import com.simibubi.create.content.contraptions.fluids.actors.FillingRecipe; +import com.simibubi.create.content.contraptions.processing.BasinRecipe; +import com.simibubi.create.content.contraptions.processing.EmptyingRecipe; import com.simibubi.create.content.contraptions.processing.ProcessingRecipe; import com.simibubi.create.content.contraptions.processing.ProcessingRecipeBuilder.ProcessingRecipeFactory; import com.simibubi.create.content.contraptions.processing.ProcessingRecipeSerializer; @@ -25,22 +29,26 @@ import net.minecraft.item.crafting.IRecipeType; import net.minecraft.item.crafting.ShapedRecipe; import net.minecraft.util.ResourceLocation; import net.minecraft.util.registry.Registry; +import net.minecraft.world.World; import net.minecraftforge.event.RegistryEvent; public enum AllRecipeTypes { BLOCKZAPPER_UPGRADE(BlockzapperUpgradeRecipe.Serializer::new, IRecipeType.CRAFTING), MECHANICAL_CRAFTING(MechanicalCraftingRecipe.Serializer::new), - + CONVERSION(processingSerializer(ConversionRecipe::new)), CRUSHING(processingSerializer(CrushingRecipe::new)), CUTTING(processingSerializer(CuttingRecipe::new)), MILLING(processingSerializer(MillingRecipe::new)), + BASIN(processingSerializer(BasinRecipe::new)), MIXING(processingSerializer(MixingRecipe::new)), + COMPACTING(processingSerializer(CompactingRecipe::new)), PRESSING(processingSerializer(PressingRecipe::new)), SANDPAPER_POLISHING(processingSerializer(SandPaperPolishingRecipe::new)), SPLASHING(processingSerializer(SplashingRecipe::new)), FILLING(processingSerializer(FillingRecipe::new)), + EMPTYING(processingSerializer(EmptyingRecipe::new)), ; @@ -89,4 +97,9 @@ public enum AllRecipeTypes { public > T getType() { return (T) type; } + + public > Optional find(C inv, World world) { + return world.getRecipeManager() + .getRecipe(getType(), inv, world); + } } diff --git a/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java b/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java index 41ba41b63..bdc276c35 100644 --- a/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java +++ b/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java @@ -23,10 +23,12 @@ import com.simibubi.create.compat.jei.category.PressingCategory; import com.simibubi.create.compat.jei.category.SawingCategory; import com.simibubi.create.compat.jei.category.SmokingViaFanCategory; import com.simibubi.create.compat.jei.category.SplashingCategory; -import com.simibubi.create.content.contraptions.components.mixer.MixingRecipe; import com.simibubi.create.content.contraptions.components.press.MechanicalPressTileEntity; +import com.simibubi.create.content.contraptions.processing.BasinRecipe; import com.simibubi.create.content.logistics.block.inventories.AdjustableCrateScreen; import com.simibubi.create.content.schematics.block.SchematicannonScreen; +import com.simibubi.create.foundation.config.AllConfigs; +import com.simibubi.create.foundation.config.CRecipes; import com.simibubi.create.foundation.utility.Lang; import mezz.jei.api.IModPlugin; @@ -96,44 +98,62 @@ public class CreateJEI implements IModPlugin { @Override public void registerCategories(IRecipeCategoryRegistration registration) { - registration - .addRecipeCategories(millingCategory, crushingCategory, splashingCategory, pressingCategory, - smokingCategory, blastingCategory, blockzapperCategory, mixingCategory, sawingCategory, - blockCuttingCategory, packingCategory, polishingCategory, mysteryConversionCategory, - mechanicalCraftingCategory); + registration.addRecipeCategories(millingCategory, crushingCategory, splashingCategory, pressingCategory, + smokingCategory, blastingCategory, blockzapperCategory, mixingCategory, sawingCategory, + blockCuttingCategory, packingCategory, polishingCategory, mysteryConversionCategory, + mechanicalCraftingCategory); } @Override public void registerRecipes(IRecipeRegistration registration) { + CRecipes recipeConfig = AllConfigs.SERVER.recipes; + registration.addRecipes(findRecipes(AllRecipeTypes.MILLING), millingCategory.getUid()); registration.addRecipes(findRecipes(AllRecipeTypes.CRUSHING), crushingCategory.getUid()); - registration.addRecipes(findRecipesByTypeExcluding(AllRecipeTypes.MILLING.getType(), AllRecipeTypes.CRUSHING.getType()), - crushingCategory.getUid()); + registration.addRecipes( + findRecipesByTypeExcluding(AllRecipeTypes.MILLING.getType(), AllRecipeTypes.CRUSHING.getType()), + crushingCategory.getUid()); registration.addRecipes(findRecipes(AllRecipeTypes.SPLASHING), splashingCategory.getUid()); registration.addRecipes(findRecipes(AllRecipeTypes.PRESSING), pressingCategory.getUid()); registration.addRecipes(findRecipesById(AllRecipeTypes.BLOCKZAPPER_UPGRADE.serializer.getRegistryName()), - blockzapperCategory.getUid()); + blockzapperCategory.getUid()); registration.addRecipes(findRecipesByType(IRecipeType.SMOKING), smokingCategory.getUid()); registration.addRecipes(findRecipesByTypeExcluding(IRecipeType.SMELTING, IRecipeType.SMOKING), - blastingCategory.getUid()); + blastingCategory.getUid()); registration.addRecipes(findRecipes(AllRecipeTypes.MIXING), mixingCategory.getUid()); - registration.addRecipes(findRecipes(r -> r.getSerializer() == IRecipeSerializer.CRAFTING_SHAPELESS - && !MechanicalPressTileEntity.canCompress(r.getIngredients())).stream().map(MixingRecipe::convertShapeless) - .collect(Collectors.toList()), + + if (recipeConfig.allowShapelessInMixer.get()) + registration.addRecipes(findRecipes(r -> r.getSerializer() == IRecipeSerializer.CRAFTING_SHAPELESS + && !MechanicalPressTileEntity.canCompress(r.getIngredients())).stream() + .map(BasinRecipe::convert) + .collect(Collectors.toList()), mixingCategory.getUid()); + registration.addRecipes(findRecipes(AllRecipeTypes.CUTTING), sawingCategory.getUid()); - registration.addRecipes( + + if (recipeConfig.allowStonecuttingOnSaw.get()) + registration.addRecipes( CondensedBlockCuttingRecipe.condenseRecipes(findRecipesByType(IRecipeType.STONECUTTING)), blockCuttingCategory.getUid()); - registration.addRecipes(findRecipes( - r -> (r instanceof ICraftingRecipe) && MechanicalPressTileEntity.canCompress(r.getIngredients())), + + registration.addRecipes(findRecipes(AllRecipeTypes.COMPACTING), packingCategory.getUid()); + if (recipeConfig.allowShapedSquareInPress.get()) + registration.addRecipes(findRecipes( + r -> (r instanceof ICraftingRecipe) && MechanicalPressTileEntity.canCompress(r.getIngredients())) + .stream() + .map(BasinRecipe::convert) + .collect(Collectors.toList()), packingCategory.getUid()); + registration.addRecipes(findRecipes(AllRecipeTypes.SANDPAPER_POLISHING), polishingCategory.getUid()); registration.addRecipes(MysteriousItemConversionCategory.getRecipes(), mysteryConversionCategory.getUid()); registration.addRecipes(findRecipes(r -> (r.getType() == AllRecipeTypes.MECHANICAL_CRAFTING.type)), - mechanicalCraftingCategory.getUid()); - registration.addRecipes(findRecipes(r -> (r.getType() == IRecipeType.CRAFTING - && r.getType() != AllRecipeTypes.MECHANICAL_CRAFTING.type) && (r instanceof ShapedRecipe)), + mechanicalCraftingCategory.getUid()); + + if (recipeConfig.allowRegularCraftingInCrafter.get()) + registration.addRecipes(findRecipes( + r -> (r.getType() == IRecipeType.CRAFTING && r.getType() != AllRecipeTypes.MECHANICAL_CRAFTING.type) + && (r instanceof ShapedRecipe)), mechanicalCraftingCategory.getUid()); } @@ -141,17 +161,13 @@ public class CreateJEI implements IModPlugin { public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) { ItemStack fan = new ItemStack(AllBlocks.ENCASED_FAN.get()); - ItemStack splashingFan = fan - .copy() - .setDisplayName(new StringTextComponent(TextFormatting.RESET + Lang.translate("recipe.splashing.fan"))); - ItemStack smokingFan = fan - .copy() - .setDisplayName( - new StringTextComponent(TextFormatting.RESET + Lang.translate("recipe.smokingViaFan.fan"))); - ItemStack blastingFan = fan - .copy() - .setDisplayName( - new StringTextComponent(TextFormatting.RESET + Lang.translate("recipe.blastingViaFan.fan"))); + ItemStack splashingFan = fan.copy() + .setDisplayName(new StringTextComponent(TextFormatting.RESET + Lang.translate("recipe.splashing.fan"))); + ItemStack smokingFan = fan.copy() + .setDisplayName(new StringTextComponent(TextFormatting.RESET + Lang.translate("recipe.smokingViaFan.fan"))); + ItemStack blastingFan = fan.copy() + .setDisplayName( + new StringTextComponent(TextFormatting.RESET + Lang.translate("recipe.blastingViaFan.fan"))); registration.addRecipeCatalyst(new ItemStack(AllBlocks.MILLSTONE.get()), millingCategory.getUid()); registration.addRecipeCatalyst(new ItemStack(AllBlocks.CRUSHING_WHEEL.get()), crushingCategory.getUid()); @@ -170,9 +186,8 @@ public class CreateJEI implements IModPlugin { registration.addRecipeCatalyst(new ItemStack(AllBlocks.BASIN.get()), packingCategory.getUid()); registration.addRecipeCatalyst(AllItems.SAND_PAPER.asStack(), polishingCategory.getUid()); registration.addRecipeCatalyst(AllItems.RED_SAND_PAPER.asStack(), polishingCategory.getUid()); - registration - .addRecipeCatalyst(new ItemStack(AllBlocks.MECHANICAL_CRAFTER.get()), - mechanicalCraftingCategory.getUid()); + registration.addRecipeCatalyst(new ItemStack(AllBlocks.MECHANICAL_CRAFTER.get()), + mechanicalCraftingCategory.getUid()); } @Override @@ -186,30 +201,29 @@ public class CreateJEI implements IModPlugin { } private static List> findRecipes(Predicate> pred) { - return Minecraft.getInstance().world - .getRecipeManager() - .getRecipes() - .stream() - .filter(pred) - .collect(Collectors.toList()); + return Minecraft.getInstance().world.getRecipeManager() + .getRecipes() + .stream() + .filter(pred) + .collect(Collectors.toList()); } private static List> findRecipesByType(IRecipeType type) { - return Minecraft.getInstance().world - .getRecipeManager() - .getRecipes() - .stream() - .filter(r -> r.getType() == type) - .collect(Collectors.toList()); + return Minecraft.getInstance().world.getRecipeManager() + .getRecipes() + .stream() + .filter(r -> r.getType() == type) + .collect(Collectors.toList()); } private static List> findRecipesById(ResourceLocation id) { - return Minecraft.getInstance().world - .getRecipeManager() - .getRecipes() - .stream() - .filter(r -> r.getSerializer().getRegistryName().equals(id)) - .collect(Collectors.toList()); + return Minecraft.getInstance().world.getRecipeManager() + .getRecipes() + .stream() + .filter(r -> r.getSerializer() + .getRegistryName() + .equals(id)) + .collect(Collectors.toList()); } private static List> findRecipesByTypeExcluding(IRecipeType type, IRecipeType excludingType) { @@ -217,10 +231,14 @@ public class CreateJEI implements IModPlugin { List> byExcludingType = findRecipesByType(excludingType); byType.removeIf(recipe -> { for (IRecipe r : byExcludingType) { - ItemStack[] matchingStacks = recipe.getIngredients().get(0).getMatchingStacks(); + ItemStack[] matchingStacks = recipe.getIngredients() + .get(0) + .getMatchingStacks(); if (matchingStacks.length == 0) return true; - if (r.getIngredients().get(0).test(matchingStacks[0])) + if (r.getIngredients() + .get(0) + .test(matchingStacks[0])) return true; } return false; diff --git a/src/main/java/com/simibubi/create/compat/jei/category/BasinCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/BasinCategory.java new file mode 100644 index 000000000..02f1463cb --- /dev/null +++ b/src/main/java/com/simibubi/create/compat/jei/category/BasinCategory.java @@ -0,0 +1,88 @@ +package com.simibubi.create.compat.jei.category; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.mutable.MutableInt; + +import com.simibubi.create.content.contraptions.processing.BasinRecipe; +import com.simibubi.create.content.contraptions.processing.HeatCondition; +import com.simibubi.create.foundation.gui.AllGuiTextures; +import com.simibubi.create.foundation.item.ItemHelper; +import com.simibubi.create.foundation.utility.Pair; + +import mezz.jei.api.constants.VanillaTypes; +import mezz.jei.api.gui.IRecipeLayout; +import mezz.jei.api.gui.drawable.IDrawable; +import mezz.jei.api.gui.ingredient.IGuiItemStackGroup; +import mezz.jei.api.ingredients.IIngredients; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.util.NonNullList; + +public class BasinCategory extends CreateRecipeCategory { + + public BasinCategory(String id, IDrawable icon, IDrawable background) { + super(id, icon, background); + } + + @Override + public Class getRecipeClass() { + return BasinRecipe.class; + } + + @Override + public void setIngredients(BasinRecipe recipe, IIngredients ingredients) { + ingredients.setInputIngredients(recipe.getIngredients()); + ingredients.setOutput(VanillaTypes.ITEM, recipe.getRecipeOutput()); + } + + @Override + public void setRecipe(IRecipeLayout recipeLayout, BasinRecipe recipe, IIngredients ingredients) { + IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks(); + NonNullList recipeIngredients = recipe.getIngredients(); + List> actualIngredients = ItemHelper.condenseIngredients(recipeIngredients); + + int size = actualIngredients.size(); + int xOffset = size < 3 ? (3 - size) * 19 / 2 : 0; + int yOffset = recipe.getRequiredHeat() != HeatCondition.NONE ? 30 : 10; + + int i; + for (i = 0; i < actualIngredients.size(); i++) { + itemStacks.init(i, true, 16 + xOffset + (i % 3) * 19, 50 - (i / 3) * 19 + yOffset); + List stacks = new ArrayList<>(); + Pair pair = actualIngredients.get(i); + Ingredient ingredient = pair.getFirst(); + MutableInt amount = pair.getSecond(); + + for (ItemStack itemStack : ingredient.getMatchingStacks()) { + ItemStack stack = itemStack.copy(); + stack.setCount(amount.getValue()); + stacks.add(stack); + } + + itemStacks.set(i, stacks); + } + + itemStacks.init(i, false, 141, 50 + yOffset); + itemStacks.set(i, recipe.getRecipeOutput() + .getStack()); + } + + @Override + public void draw(BasinRecipe recipe, double mouseX, double mouseY) { + List> actualIngredients = ItemHelper.condenseIngredients(recipe.getIngredients()); + + int size = actualIngredients.size(); + int xOffset = size < 3 ? (3 - size) * 19 / 2 : 0; + HeatCondition requiredHeat = recipe.getRequiredHeat(); + int yOffset = requiredHeat != HeatCondition.NONE ? 30 : 10; + for (int i = 0; i < size; i++) + AllGuiTextures.JEI_SLOT.draw(16 + xOffset + (i % 3) * 19, 50 - (i / 3) * 19 + yOffset); + + AllGuiTextures.JEI_SLOT.draw(141, 50 + yOffset); + AllGuiTextures.JEI_DOWN_ARROW.draw(136, 32 + yOffset); + AllGuiTextures.JEI_SHADOW.draw(81, 57 + yOffset); + } + +} diff --git a/src/main/java/com/simibubi/create/compat/jei/category/MixingCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/MixingCategory.java index ce8697c94..d379b3436 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/MixingCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/MixingCategory.java @@ -1,28 +1,12 @@ package com.simibubi.create.compat.jei.category; -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.lang3.mutable.MutableInt; - import com.simibubi.create.AllBlocks; import com.simibubi.create.compat.jei.category.animations.AnimatedBlazeBurner; import com.simibubi.create.compat.jei.category.animations.AnimatedMixer; -import com.simibubi.create.content.contraptions.components.mixer.MixingRecipe; +import com.simibubi.create.content.contraptions.processing.BasinRecipe; import com.simibubi.create.content.contraptions.processing.HeatCondition; -import com.simibubi.create.foundation.gui.AllGuiTextures; -import com.simibubi.create.foundation.item.ItemHelper; -import com.simibubi.create.foundation.utility.Pair; -import mezz.jei.api.constants.VanillaTypes; -import mezz.jei.api.gui.IRecipeLayout; -import mezz.jei.api.gui.ingredient.IGuiItemStackGroup; -import mezz.jei.api.ingredients.IIngredients; -import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.Ingredient; -import net.minecraft.util.NonNullList; - -public class MixingCategory extends CreateRecipeCategory { +public class MixingCategory extends BasinCategory { private AnimatedMixer mixer = new AnimatedMixer(); private AnimatedBlazeBurner heater = new AnimatedBlazeBurner(); @@ -33,63 +17,9 @@ public class MixingCategory extends CreateRecipeCategory { } @Override - public Class getRecipeClass() { - return MixingRecipe.class; - } - - @Override - public void setIngredients(MixingRecipe recipe, IIngredients ingredients) { - ingredients.setInputIngredients(recipe.getIngredients()); - ingredients.setOutput(VanillaTypes.ITEM, recipe.getRecipeOutput()); - } - - @Override - public void setRecipe(IRecipeLayout recipeLayout, MixingRecipe recipe, IIngredients ingredients) { - IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks(); - NonNullList recipeIngredients = recipe.getIngredients(); - List> actualIngredients = ItemHelper.condenseIngredients(recipeIngredients); - - int size = actualIngredients.size(); - int xOffset = size < 3 ? (3 - size) * 19 / 2 : 0; - int yOffset = recipe.getRequiredHeat() != HeatCondition.NONE ? 30 : 10; - - int i; - for (i = 0; i < actualIngredients.size(); i++) { - itemStacks.init(i, true, 16 + xOffset + (i % 3) * 19, 50 - (i / 3) * 19 + yOffset); - List stacks = new ArrayList<>(); - Pair pair = actualIngredients.get(i); - Ingredient ingredient = pair.getFirst(); - MutableInt amount = pair.getSecond(); - - for (ItemStack itemStack : ingredient.getMatchingStacks()) { - ItemStack stack = itemStack.copy(); - stack.setCount(amount.getValue()); - stacks.add(stack); - } - - itemStacks.set(i, stacks); - } - - itemStacks.init(i, false, 141, 50 + yOffset); - itemStacks.set(i, recipe.getRecipeOutput() - .getStack()); - } - - @Override - public void draw(MixingRecipe recipe, double mouseX, double mouseY) { - List> actualIngredients = ItemHelper.condenseIngredients(recipe.getIngredients()); - - int size = actualIngredients.size(); - int xOffset = size < 3 ? (3 - size) * 19 / 2 : 0; + public void draw(BasinRecipe recipe, double mouseX, double mouseY) { + super.draw(recipe, mouseX, mouseY); HeatCondition requiredHeat = recipe.getRequiredHeat(); - int yOffset = requiredHeat != HeatCondition.NONE ? 30 : 10; - for (int i = 0; i < size; i++) - AllGuiTextures.JEI_SLOT.draw(16 + xOffset + (i % 3) * 19, 50 - (i / 3) * 19 + yOffset); - - AllGuiTextures.JEI_SLOT.draw(141, 50 + yOffset); - AllGuiTextures.JEI_DOWN_ARROW.draw(136, 32 + yOffset); - AllGuiTextures.JEI_SHADOW.draw(81, 57 + yOffset); - if (requiredHeat != HeatCondition.NONE) heater.withHeat(requiredHeat.visualizeAsBlazeBurner()) .draw(getBackground().getWidth() / 2 + 3, 55); diff --git a/src/main/java/com/simibubi/create/compat/jei/category/PackingCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/PackingCategory.java index daaee43a5..b554fea4f 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/PackingCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/PackingCategory.java @@ -4,18 +4,16 @@ import java.util.Arrays; import com.simibubi.create.AllBlocks; import com.simibubi.create.compat.jei.category.animations.AnimatedPress; +import com.simibubi.create.content.contraptions.processing.BasinRecipe; import com.simibubi.create.foundation.gui.AllGuiTextures; -import mezz.jei.api.constants.VanillaTypes; import mezz.jei.api.gui.IRecipeLayout; import mezz.jei.api.gui.ingredient.IGuiItemStackGroup; import mezz.jei.api.ingredients.IIngredients; -import net.minecraft.item.crafting.ICraftingRecipe; -import net.minecraft.item.crafting.IRecipe; import net.minecraft.item.crafting.Ingredient; import net.minecraft.util.NonNullList; -public class PackingCategory extends CreateRecipeCategory> { +public class PackingCategory extends BasinCategory { private AnimatedPress press = new AnimatedPress(true); @@ -25,18 +23,12 @@ public class PackingCategory extends CreateRecipeCategory> { } @Override - public Class> getRecipeClass() { - return ICraftingRecipe.class; - } - - @Override - public void setIngredients(IRecipe recipe, IIngredients ingredients) { - ingredients.setInputIngredients(recipe.getIngredients()); - ingredients.setOutput(VanillaTypes.ITEM, recipe.getRecipeOutput()); - } - - @Override - public void setRecipe(IRecipeLayout recipeLayout, IRecipe recipe, IIngredients ingredients) { + public void setRecipe(IRecipeLayout recipeLayout, BasinRecipe recipe, IIngredients ingredients) { + if (!recipe.convertedRecipe) { + super.setRecipe(recipeLayout, recipe, ingredients); + return; + } + IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks(); int i = 0; @@ -55,16 +47,21 @@ public class PackingCategory extends CreateRecipeCategory> { } @Override - public void draw(IRecipe recipe, double mouseX, double mouseY) { - NonNullList ingredients2 = recipe.getIngredients(); - int size = ingredients2.size(); - int rows = size == 4 ? 2 : 3; - for (int i = 0; i < size; i++) { - AllGuiTextures.JEI_SLOT.draw((rows == 2 ? 26 : 17) + (i % rows) * 19, 50 - (i / rows) * 19); + public void draw(BasinRecipe recipe, double mouseX, double mouseY) { + if (!recipe.convertedRecipe) { + super.draw(recipe, mouseX, mouseY); + + } else { + NonNullList ingredients2 = recipe.getIngredients(); + int size = ingredients2.size(); + int rows = size == 4 ? 2 : 3; + for (int i = 0; i < size; i++) + AllGuiTextures.JEI_SLOT.draw((rows == 2 ? 26 : 17) + (i % rows) * 19, 50 - (i / rows) * 19); + AllGuiTextures.JEI_SLOT.draw(141, 50); + AllGuiTextures.JEI_DOWN_ARROW.draw(136, 32); + AllGuiTextures.JEI_SHADOW.draw(81, 57); } - AllGuiTextures.JEI_SLOT.draw(141, 50); - AllGuiTextures.JEI_DOWN_ARROW.draw(136, 32); - AllGuiTextures.JEI_SHADOW.draw(81, 57); + press.draw(getBackground().getWidth() / 2 + 6, 30); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/crafter/RecipeGridHandler.java b/src/main/java/com/simibubi/create/content/contraptions/components/crafter/RecipeGridHandler.java index 55c04b434..20de1a509 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/crafter/RecipeGridHandler.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/crafter/RecipeGridHandler.java @@ -15,6 +15,7 @@ import org.apache.commons.lang3.tuple.Pair; import com.google.common.base.Predicates; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllRecipeTypes; +import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.utility.Pointing; import net.minecraft.block.BlockState; @@ -139,16 +140,16 @@ public class RecipeGridHandler { public static ItemStack tryToApplyRecipe(World world, GroupedItems items) { items.calcStats(); CraftingInventory craftinginventory = new MechanicalCraftingInventory(items); - ItemStack result = world.getRecipeManager() - .getRecipe(IRecipeType.CRAFTING, craftinginventory, world) - .map(r -> r.getCraftingResult(craftinginventory)) - .orElse(null); - if (result == null) + ItemStack result = null; + if (AllConfigs.SERVER.recipes.allowRegularCraftingInCrafter.get()) result = world.getRecipeManager() - .getRecipe(AllRecipeTypes.MECHANICAL_CRAFTING.getType(), craftinginventory, world) + .getRecipe(IRecipeType.CRAFTING, craftinginventory, world) + .map(r -> r.getCraftingResult(craftinginventory)) + .orElse(null); + if (result == null) + result = AllRecipeTypes.MECHANICAL_CRAFTING.find(craftinginventory, world) .map(r -> r.getCraftingResult(craftinginventory)) .orElse(null); - return result; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelControllerTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelControllerTileEntity.java index d78798576..010bf1610 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelControllerTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelControllerTileEntity.java @@ -206,11 +206,9 @@ public class CrushingWheelControllerTileEntity extends SmartTileEntity { } public Optional> findRecipe() { - Optional> crushingRecipe = world.getRecipeManager() - .getRecipe(AllRecipeTypes.CRUSHING.getType(), wrapper, world); + Optional> crushingRecipe = AllRecipeTypes.CRUSHING.find(wrapper, world); if (!crushingRecipe.isPresent()) - crushingRecipe = world.getRecipeManager() - .getRecipe(AllRecipeTypes.MILLING.getType(), wrapper, world); + crushingRecipe = AllRecipeTypes.MILLING.find(wrapper, world); return crushingRecipe; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/AirCurrent.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/AirCurrent.java index f77d9c5a1..a92bb9181 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/AirCurrent.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/AirCurrent.java @@ -13,6 +13,7 @@ import com.simibubi.create.content.logistics.InWorldProcessing.Type; import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour; +import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.VecHelper; @@ -305,7 +306,7 @@ public class AirCurrent { InWorldProcessing.spawnParticlesForProcessing(world, handler.getWorldPositionOf(transported), processingType); if (world.isRemote) - return null; + return TransportedResult.doNothing(); return InWorldProcessing.applyProcessing(transported, world, processingType); }); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillstoneTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillstoneTileEntity.java index e70a13bae..a438ccd31 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillstoneTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillstoneTileEntity.java @@ -65,8 +65,7 @@ public class MillstoneTileEntity extends KineticTileEntity { RecipeWrapper inventoryIn = new RecipeWrapper(inputInv); if (lastRecipe == null || !lastRecipe.matches(inventoryIn, world)) { - Optional recipe = world.getRecipeManager() - .getRecipe(AllRecipeTypes.MILLING.getType(), inventoryIn, world); + Optional recipe = AllRecipeTypes.MILLING.find(inventoryIn, world); if (!recipe.isPresent()) { timer = 100; sendData(); @@ -86,8 +85,7 @@ public class MillstoneTileEntity extends KineticTileEntity { RecipeWrapper inventoryIn = new RecipeWrapper(inputInv); if (lastRecipe == null || !lastRecipe.matches(inventoryIn, world)) { - Optional recipe = world.getRecipeManager() - .getRecipe(AllRecipeTypes.MILLING.getType(), inventoryIn, world); + Optional recipe = AllRecipeTypes.MILLING.find(inventoryIn, world); if (!recipe.isPresent()) return; lastRecipe = recipe.get(); @@ -153,8 +151,7 @@ public class MillstoneTileEntity extends KineticTileEntity { if (lastRecipe != null && lastRecipe.matches(inventoryIn, world)) return true; - return world.getRecipeManager() - .getRecipe(AllRecipeTypes.MILLING.getType(), inventoryIn, world) + return AllRecipeTypes.MILLING.find(inventoryIn, world) .isPresent(); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/CompactingRecipe.java b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/CompactingRecipe.java new file mode 100644 index 000000000..7e25e410e --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/CompactingRecipe.java @@ -0,0 +1,13 @@ +package com.simibubi.create.content.contraptions.components.mixer; + +import com.simibubi.create.AllRecipeTypes; +import com.simibubi.create.content.contraptions.processing.BasinRecipe; +import com.simibubi.create.content.contraptions.processing.ProcessingRecipeBuilder.ProcessingRecipeParams; + +public class CompactingRecipe extends BasinRecipe { + + public CompactingRecipe(ProcessingRecipeParams params) { + super(AllRecipeTypes.COMPACTING, params); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerTileEntity.java index 360c4b2db..17bbf9fce 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MechanicalMixerTileEntity.java @@ -1,37 +1,29 @@ package com.simibubi.create.content.contraptions.components.mixer; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.LinkedList; -import java.util.List; import java.util.Optional; import com.simibubi.create.AllRecipeTypes; -import com.simibubi.create.AllTags; import com.simibubi.create.content.contraptions.components.press.MechanicalPressTileEntity; import com.simibubi.create.content.contraptions.processing.BasinOperatingTileEntity; import com.simibubi.create.content.contraptions.processing.BasinTileEntity; -import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock; -import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel; +import com.simibubi.create.foundation.advancement.AllTriggers; +import com.simibubi.create.foundation.advancement.ITriggerable; +import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.item.SmartInventory; import com.simibubi.create.foundation.utility.VecHelper; -import net.minecraft.block.BlockState; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipe; import net.minecraft.item.crafting.IRecipeSerializer; -import net.minecraft.item.crafting.Ingredient; import net.minecraft.nbt.CompoundNBT; import net.minecraft.particles.ItemParticleData; import net.minecraft.particles.ParticleTypes; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction.Axis; -import net.minecraft.util.NonNullList; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; -import net.minecraftforge.fluids.FluidStack; public class MechanicalMixerTileEntity extends BasinOperatingTileEntity { @@ -99,13 +91,6 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity { super.write(compound, clientPacket); } - @Override - public void lazyTick() { - super.lazyTick(); - if (world != null && world.isRemote && running && !basinItemInv.isPresent()) - updateBasin(); - } - @Override public void tick() { super.tick(); @@ -168,45 +153,11 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity { @Override protected boolean matchStaticFilters(IRecipe r) { - return (r.getSerializer() == IRecipeSerializer.CRAFTING_SHAPELESS || r.getType() == AllRecipeTypes.MIXING.type) + return ((r.getSerializer() == IRecipeSerializer.CRAFTING_SHAPELESS + && AllConfigs.SERVER.recipes.allowShapelessInMixer.get()) || r.getType() == AllRecipeTypes.MIXING.type) && !MechanicalPressTileEntity.canCompress(r.getIngredients()); } - @Override - protected boolean matchBasinRecipe(IRecipe recipe) { - if (!super.matchBasinRecipe(recipe)) - return false; - - NonNullList ingredients = recipe.getIngredients(); - List remainingItems = new ArrayList<>(); - itemInputs.forEach(stack -> remainingItems.add(stack.copy())); - List remainingFluids = new ArrayList<>(); - fluidInputs.forEach(stack -> remainingFluids.add(stack.copy())); - - // TODO: match fluid inputs - - // Sort by leniency - List sortedIngredients = new LinkedList<>(ingredients); - sortedIngredients.sort(Comparator.comparingInt(i -> i.getMatchingStacks().length)); - - Ingredients: for (Ingredient ingredient : sortedIngredients) { - for (ItemStack stack : remainingItems) { - if (stack.isEmpty()) - continue; - if (ingredient.test(stack)) { - stack.shrink(1); - continue Ingredients; - } - } - return false; - } - - if (!(recipe instanceof MixingRecipe)) - return true; - return ((MixingRecipe) recipe).getRequiredHeat() - .testBlazeBurner(getHeatLevel()); - } - @Override public void startProcessingBasin() { if (running && runningTicks <= 20) @@ -239,13 +190,10 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity { protected boolean isRunning() { return running; } - - private HeatLevel getHeatLevel() { - if (world == null) - return HeatLevel.NONE; - BlockState state = world.getBlockState(pos.down(3)); - if (state.has(BlazeBurnerBlock.HEAT_LEVEL)) - return state.get(BlazeBurnerBlock.HEAT_LEVEL); - return AllTags.AllBlockTags.FAN_HEATERS.matches(state) ? HeatLevel.SMOULDERING : HeatLevel.NONE; + + @Override + protected Optional getProcessedRecipeTrigger() { + return Optional.of(AllTriggers.MIXER_MIX); } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixingRecipe.java b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixingRecipe.java index c36564c57..12e1d7b0f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixingRecipe.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/mixer/MixingRecipe.java @@ -1,98 +1,13 @@ package com.simibubi.create.content.contraptions.components.mixer; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.LinkedList; -import java.util.List; - -import javax.annotation.Nonnull; - import com.simibubi.create.AllRecipeTypes; -import com.simibubi.create.content.contraptions.processing.ProcessingRecipe; -import com.simibubi.create.content.contraptions.processing.ProcessingRecipeBuilder; +import com.simibubi.create.content.contraptions.processing.BasinRecipe; import com.simibubi.create.content.contraptions.processing.ProcessingRecipeBuilder.ProcessingRecipeParams; -import com.simibubi.create.foundation.item.SmartInventory; -import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.IRecipe; -import net.minecraft.item.crafting.Ingredient; -import net.minecraft.util.NonNullList; -import net.minecraft.world.World; - -public class MixingRecipe extends ProcessingRecipe { - - /** - * For JEI purposes only - */ - public static MixingRecipe convertShapeless(IRecipe recipe) { - return new ProcessingRecipeBuilder<>(MixingRecipe::new, recipe.getId()) - .withItemIngredients(recipe.getIngredients()) - .withSingleItemOutput(recipe.getRecipeOutput()) - .build(); - } +public class MixingRecipe extends BasinRecipe { public MixingRecipe(ProcessingRecipeParams params) { super(AllRecipeTypes.MIXING, params); } - @Override - protected int getMaxInputCount() { - return 9; - } - - @Override - protected int getMaxOutputCount() { - return 1;// TODO increase - } - - @Override - protected int getMaxFluidInputCount() { - return 2; - } - - @Override - protected int getMaxFluidOutputCount() { - return 1;// TODO increase? - } - - @Override - protected boolean canRequireHeat() { - return true; - } - - @Override - public boolean matches(SmartInventory inv, @Nonnull World worldIn) { - if (inv.isEmpty()) - return false; - - NonNullList ingredients = this.getIngredients(); - if (!ingredients.stream() - .allMatch(Ingredient::isSimple)) - return false; - - List remaining = new ArrayList<>(); - for (int slot = 0; slot < inv.getSizeInventory(); ++slot) { - ItemStack itemstack = inv.getStackInSlot(slot); - if (!itemstack.isEmpty()) { - remaining.add(itemstack.copy()); - } - } - - // sort by leniency - List sortedIngredients = new LinkedList<>(ingredients); - sortedIngredients.sort(Comparator.comparingInt(i -> i.getMatchingStacks().length)); - Ingredients: for (Ingredient ingredient : sortedIngredients) { - for (ItemStack stack : remaining) { - if (stack.isEmpty()) - continue; - if (ingredient.test(stack)) { - stack.shrink(1); - continue Ingredients; - } - } - return false; - } - return true; - } - } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/press/MechanicalPressTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/press/MechanicalPressTileEntity.java index a93bc77a1..bc8a0818d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/press/MechanicalPressTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/press/MechanicalPressTileEntity.java @@ -10,6 +10,8 @@ import com.simibubi.create.content.contraptions.processing.BasinOperatingTileEnt import com.simibubi.create.content.contraptions.processing.BasinTileEntity; import com.simibubi.create.content.logistics.InWorldProcessing; import com.simibubi.create.foundation.advancement.AllTriggers; +import com.simibubi.create.foundation.advancement.ITriggerable; +import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.item.ItemHelper; import com.simibubi.create.foundation.item.SmartInventory; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; @@ -41,29 +43,12 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity { private static final Object compressingRecipesKey = new Object(); public List pressedItems = new ArrayList<>(); - - public static class PressingInv extends RecipeWrapper { - public PressingInv() { - super(new ItemStackHandler(1)); - } - } - - enum Mode { - WORLD(1), BELT(19f / 16f), BASIN(22f / 16f) - - ; - - float headOffset; - - Mode(float headOffset) { - this.headOffset = headOffset; - } - } - - private static final PressingInv pressingInv = new PressingInv(); public BeltProcessingBehaviour processingBehaviour; + public int prevRunningTicks; public int runningTicks; + static final int CYCLE = 240; + public boolean running; public Mode mode; public boolean finished; @@ -87,7 +72,7 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity { running = compound.getBoolean("Running"); mode = Mode.values()[compound.getInt("Mode")]; finished = compound.getBoolean("Finished"); - runningTicks = compound.getInt("Ticks"); + prevRunningTicks = runningTicks = compound.getInt("Ticks"); super.read(compound, clientPacket); if (clientPacket) { @@ -105,8 +90,10 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity { compound.putInt("Ticks", runningTicks); super.write(compound, clientPacket); - if (clientPacket) + if (clientPacket) { compound.put("ParticleItems", NBTHelper.writeCompoundList(pressedItems, ItemStack::serializeNBT)); + pressedItems.clear(); + } } @Override @@ -116,15 +103,12 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity { } public float getRenderedHeadOffset(float partialTicks) { - if (running) { - if (runningTicks < 40) { - float num = (runningTicks - 1 + partialTicks) / 30f; - return MathHelper.clamp(num * num * num, 0, mode.headOffset); - } - return MathHelper.clamp(((60 - runningTicks) + 1 - partialTicks) / 20f * mode.headOffset, 0, - mode.headOffset); - } - return 0; + if (!running) + return 0; + float ticks = MathHelper.lerp(partialTicks, prevRunningTicks, runningTicks); + if (runningTicks < (CYCLE * 2) / 3) + return (float) MathHelper.clamp(Math.pow(ticks / CYCLE * 2, 3), 0, mode.headOffset); + return MathHelper.clamp((CYCLE - ticks) / CYCLE * 3 * mode.headOffset, 0, mode.headOffset); } public void start(Mode mode) { @@ -150,50 +134,11 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity { if (!running || world == null) return; - if (runningTicks == 30) { - - if (inWorld()) { - AxisAlignedBB bb = new AxisAlignedBB(pos.down(1)); - pressedItems.clear(); - for (Entity entity : world.getEntitiesWithinAABBExcludingEntity(null, bb)) { - if (!(entity instanceof ItemEntity)) - continue; - - ItemEntity itemEntity = (ItemEntity) entity; - - if (!world.isRemote) { - pressedItems.add(itemEntity.getItem()); - sendData(); - Optional recipe = getRecipe(itemEntity.getItem()); - if (recipe.isPresent()) { - InWorldProcessing.applyRecipeOn(itemEntity, recipe.get()); - AllTriggers.triggerForNearbyPlayers(AllTriggers.BONK, world, pos, 4); - } - } - } - } - - if (onBasin()) { - if (!world.isRemote) { - pressedItems.clear(); - applyBasinRecipe(); - - Optional basin = getBasin(); - SmartInventory inputs = basin.get() - .getInputInventory(); - if (basin.isPresent()) { - for (int slot = 0; slot < inputs.getSlots(); slot++) { - ItemStack stackInSlot = inputs.getStackInSlot(slot); - if (stackInSlot.isEmpty()) - continue; - pressedItems.add(stackInSlot); - } - } - sendData(); - } - - } - + if (runningTicks == CYCLE / 2) { + if (inWorld()) + applyPressingInWorld(); + if (onBasin()) + applyCompactingOnBasin(); if (!world.isRemote) { world.playSound(null, getPos(), AllSoundEvents.MECHANICAL_PRESS_ITEM_BREAK.get(), SoundCategory.BLOCKS, .5f, 1f); @@ -202,105 +147,125 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity { } } - if (!world.isRemote && runningTicks > 60) { + if (!world.isRemote && runningTicks > CYCLE) { finished = true; if (inWorld()) finished = world.isBlockPowered(pos); running = false; - if (onBasin()) { - gatherInputs(); - if (matchBasinRecipe(lastRecipe)) { - startProcessingBasin(); - } - } + if (onBasin() && matchBasinRecipe(currentRecipe)) + startProcessingBasin(); pressedItems.clear(); sendData(); return; } - runningTicks++; + prevRunningTicks = runningTicks; + runningTicks += getRunningTickSpeed(); + if (prevRunningTicks < CYCLE / 2 && runningTicks >= CYCLE / 2) + runningTicks = CYCLE / 2; + } + + protected void applyCompactingOnBasin() { + if (world.isRemote) + return; + pressedItems.clear(); + applyBasinRecipe(); + Optional basin = getBasin(); + SmartInventory inputs = basin.get() + .getInputInventory(); + if (basin.isPresent()) { + for (int slot = 0; slot < inputs.getSlots(); slot++) { + ItemStack stackInSlot = inputs.getStackInSlot(slot); + if (stackInSlot.isEmpty()) + continue; + pressedItems.add(stackInSlot); + } + } + sendData(); + } + + protected void applyPressingInWorld() { + AxisAlignedBB bb = new AxisAlignedBB(pos.down(1)); + pressedItems.clear(); + if (world.isRemote) + return; + for (Entity entity : world.getEntitiesWithinAABBExcludingEntity(null, bb)) { + if (!(entity instanceof ItemEntity)) + continue; + ItemEntity itemEntity = (ItemEntity) entity; + pressedItems.add(itemEntity.getItem()); + sendData(); + Optional recipe = getRecipe(itemEntity.getItem()); + if (!recipe.isPresent()) + continue; + InWorldProcessing.applyRecipeOn(itemEntity, recipe.get()); + AllTriggers.triggerForNearbyPlayers(AllTriggers.BONK, world, pos, 4); + } + } + + public int getRunningTickSpeed() { + if (getSpeed() == 0) + return 0; + return (int) MathHelper.lerp(MathHelper.clamp(Math.abs(getSpeed()) / 512f, 0, 1), 1, 60); } protected void spawnParticles() { if (pressedItems.isEmpty()) return; - if (mode == Mode.BASIN) { + if (mode == Mode.BASIN) pressedItems.forEach(stack -> makeCompactingParticleEffect(VecHelper.getCenterOf(pos.down(2)), stack)); - } - if (mode == Mode.BELT) { + if (mode == Mode.BELT) pressedItems.forEach(stack -> makePressingParticleEffect(VecHelper.getCenterOf(pos.down(2)) .add(0, 8 / 16f, 0), stack)); - } - if (mode == Mode.WORLD) { + if (mode == Mode.WORLD) pressedItems.forEach(stack -> makePressingParticleEffect(VecHelper.getCenterOf(pos.down(1)) .add(0, -1 / 4f, 0), stack)); - } pressedItems.clear(); } public void makePressingParticleEffect(Vec3d pos, ItemStack stack) { - if (world != null && world.isRemote) { - for (int i = 0; i < 20; i++) { - Vec3d motion = VecHelper.offsetRandomly(Vec3d.ZERO, world.rand, .125f) - .mul(1, 0, 1); - world.addParticle(new ItemParticleData(ParticleTypes.ITEM, stack), pos.x, pos.y - .25f, pos.z, motion.x, - motion.y + .125f, motion.z); - } + if (world == null || !world.isRemote) + return; + for (int i = 0; i < 20; i++) { + Vec3d motion = VecHelper.offsetRandomly(Vec3d.ZERO, world.rand, .125f) + .mul(1, 0, 1); + world.addParticle(new ItemParticleData(ParticleTypes.ITEM, stack), pos.x, pos.y - .25f, pos.z, motion.x, + motion.y + .125f, motion.z); } } public void makeCompactingParticleEffect(Vec3d pos, ItemStack stack) { - if (world != null && world.isRemote) { - for (int i = 0; i < 20; i++) { - Vec3d motion = VecHelper.offsetRandomly(Vec3d.ZERO, world.rand, .175f) - .mul(1, 0, 1); - world.addParticle(new ItemParticleData(ParticleTypes.ITEM, stack), pos.x, pos.y, pos.z, motion.x, - motion.y + .25f, motion.z); - } + if (world == null || !world.isRemote) + return; + for (int i = 0; i < 20; i++) { + Vec3d motion = VecHelper.offsetRandomly(Vec3d.ZERO, world.rand, .175f) + .mul(1, 0, 1); + world.addParticle(new ItemParticleData(ParticleTypes.ITEM, stack), pos.x, pos.y, pos.z, motion.x, + motion.y + .25f, motion.z); } } + private static final RecipeWrapper pressingInv = new RecipeWrapper(new ItemStackHandler(1)); + public Optional getRecipe(ItemStack item) { pressingInv.setInventorySlotContents(0, item); - return world.getRecipeManager() - .getRecipe(AllRecipeTypes.PRESSING.getType(), pressingInv, world); + return AllRecipeTypes.PRESSING.find(pressingInv, world); } public static boolean canCompress(NonNullList ingredients) { - return (ingredients.size() == 4 || ingredients.size() == 9) && ItemHelper.condenseIngredients(ingredients) - .size() == 1; + return AllConfigs.SERVER.recipes.allowShapedSquareInPress.get() + && (ingredients.size() == 4 || ingredients.size() == 9) && ItemHelper.condenseIngredients(ingredients) + .size() == 1; } @Override protected boolean matchStaticFilters(IRecipe recipe) { - return recipe instanceof ICraftingRecipe && canCompress(recipe.getIngredients()); - } - - @Override - protected boolean matchBasinRecipe(IRecipe recipe) { - if (!super.matchBasinRecipe(recipe)) - return false; - - NonNullList ingredients = recipe.getIngredients(); - List remainingItems = new ArrayList<>(); - itemInputs.forEach(stack -> remainingItems.add(stack.copy())); - - Ingredients: for (Ingredient ingredient : ingredients) { - for (ItemStack stack : remainingItems) { - if (stack.isEmpty()) - continue; - if (ingredient.test(stack)) { - stack.shrink(1); - continue Ingredients; - } - } - return false; - } - return true; + return (recipe instanceof ICraftingRecipe && canCompress(recipe.getIngredients())) + || recipe.getType() == AllRecipeTypes.COMPACTING.type; } @Override @@ -310,7 +275,7 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity { @Override public void startProcessingBasin() { - if (running && runningTicks <= 30) + if (running && runningTicks <= CYCLE / 2) return; super.startProcessingBasin(); start(Mode.BASIN); @@ -329,4 +294,21 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity { return running; } + @Override + protected Optional getProcessedRecipeTrigger() { + return Optional.of(AllTriggers.PRESS_COMPACT); + } + + enum Mode { + WORLD(1), BELT(19f / 16f), BASIN(22f / 16f) + + ; + + float headOffset; + + Mode(float headOffset) { + this.headOffset = headOffset; + } + } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/press/PressingRecipe.java b/src/main/java/com/simibubi/create/content/contraptions/components/press/PressingRecipe.java index b08c0e1c9..481acc8e0 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/press/PressingRecipe.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/press/PressingRecipe.java @@ -3,21 +3,21 @@ package com.simibubi.create.content.contraptions.components.press; import javax.annotation.ParametersAreNonnullByDefault; import com.simibubi.create.AllRecipeTypes; -import com.simibubi.create.content.contraptions.components.press.MechanicalPressTileEntity.PressingInv; import com.simibubi.create.content.contraptions.processing.ProcessingRecipe; import com.simibubi.create.content.contraptions.processing.ProcessingRecipeBuilder.ProcessingRecipeParams; import net.minecraft.world.World; +import net.minecraftforge.items.wrapper.RecipeWrapper; @ParametersAreNonnullByDefault -public class PressingRecipe extends ProcessingRecipe { +public class PressingRecipe extends ProcessingRecipe { public PressingRecipe(ProcessingRecipeParams params) { super(AllRecipeTypes.PRESSING, params); } @Override - public boolean matches(PressingInv inv, World worldIn) { + public boolean matches(RecipeWrapper inv, World worldIn) { if (inv.isEmpty()) return false; return ingredients.get(0) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawTileEntity.java index 97ab1000a..e824c1ebc 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawTileEntity.java @@ -8,9 +8,11 @@ import java.util.List; import java.util.Random; import java.util.stream.Collectors; +import com.google.common.base.Predicate; import com.simibubi.create.AllRecipeTypes; import com.simibubi.create.content.contraptions.components.actors.BlockBreakingKineticTileEntity; import com.simibubi.create.content.contraptions.processing.ProcessingInventory; +import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.item.ItemHelper; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour; @@ -264,8 +266,10 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity { } private List> getRecipes() { - List> startedSearch = RecipeFinder.get(cuttingRecipesKey, world, - RecipeConditions.isOfType(IRecipeType.STONECUTTING, AllRecipeTypes.CUTTING.getType())); + Predicate> types = AllConfigs.SERVER.recipes.allowStonecuttingOnSaw.get() + ? RecipeConditions.isOfType(IRecipeType.STONECUTTING, AllRecipeTypes.CUTTING.getType()) + : RecipeConditions.isOfType(AllRecipeTypes.CUTTING.getType()); + List> startedSearch = RecipeFinder.get(cuttingRecipesKey, world, types); return startedSearch.stream() .filter(RecipeConditions.outputMatchesFilter(filtering)) .filter(RecipeConditions.firstIngredientMatches(inventory.getStackInSlot(0))) 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 9cc0d311c..9484af64c 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 @@ -9,13 +9,13 @@ import java.util.Iterator; import java.util.List; import java.util.stream.Stream; -import com.simibubi.create.AllMovementBehaviours; import org.apache.commons.lang3.mutable.MutableBoolean; import org.apache.commons.lang3.mutable.MutableObject; import com.google.common.base.Predicates; import com.google.common.collect.ImmutableSet; import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllMovementBehaviours; import com.simibubi.create.content.contraptions.components.actors.BlockBreakingMovementBehaviour; import com.simibubi.create.content.contraptions.components.structureMovement.sync.ClientMotionPacket; import com.simibubi.create.foundation.collision.ContinuousOBBCollider.ContinuousSeparationManifold; @@ -28,6 +28,7 @@ import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.block.BlockState; import net.minecraft.block.CocoaBlock; +import net.minecraft.client.entity.player.ClientPlayerEntity; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.player.PlayerEntity; @@ -37,6 +38,7 @@ import net.minecraft.util.Direction.AxisDirection; import net.minecraft.util.ReuseableStream; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.shapes.IBooleanFunction; import net.minecraft.util.math.shapes.ISelectionContext; @@ -44,6 +46,9 @@ import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.world.World; import net.minecraft.world.gen.feature.template.Template.BlockInfo; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.fml.DistExecutor; public class ContraptionCollider { @@ -54,14 +59,20 @@ public class ContraptionCollider { for (Iterator> iterator = list.iterator(); iterator.hasNext();) { WeakReference weakReference = iterator.next(); ContraptionEntity contraptionEntity = weakReference.get(); - if (contraptionEntity == null || !contraptionEntity.isAlive()) { + if (contraptionEntity == null) { iterator.remove(); continue; } + if (!contraptionEntity.isAlive()) + continue; collideEntities(contraptionEntity); } } + enum PlayerType { + NONE, CLIENT, REMOTE, SERVER + } + private static void collideEntities(ContraptionEntity contraptionEntity) { World world = contraptionEntity.getEntityWorld(); Contraption contraption = contraptionEntity.getContraption(); @@ -87,8 +98,10 @@ public class ContraptionCollider { for (Entity entity : world.getEntitiesWithinAABB((EntityType) null, bounds.grow(2) .expand(0, 32, 0), contraptionEntity::canCollideWith)) { - boolean player = entity instanceof PlayerEntity; - boolean serverPlayer = player && !world.isRemote; + + PlayerType playerType = getPlayerType(entity); + if (playerType == PlayerType.REMOTE) + continue; // Init matrix if (rotation == null) { @@ -199,7 +212,7 @@ public class ContraptionCollider { totalResponse = rotation.transform(totalResponse); rotation.transpose(); - if (futureCollision.isTrue() && !serverPlayer) { + if (futureCollision.isTrue() && playerType != PlayerType.SERVER) { if (motionResponse.y != entityMotion.y) { entity.setMotion(entityMotion.mul(1, 0, 1) .add(0, motionResponse.y, 0)); @@ -212,7 +225,7 @@ public class ContraptionCollider { entity.fallDistance = 0; entity.onGround = true; contraptionEntity.collidingEntities.add(entity); - if (!serverPlayer) + if (playerType != PlayerType.SERVER) contactPointMotion = contraptionEntity.getContactPointMotion(entityPosition); } @@ -236,7 +249,7 @@ public class ContraptionCollider { if (!hardCollision && surfaceCollision.isFalse()) continue; - if (serverPlayer && entity instanceof ServerPlayerEntity) { + if (playerType == PlayerType.SERVER && entity instanceof ServerPlayerEntity) { ((ServerPlayerEntity) entity).connection.floatingTickCount = 0; continue; } @@ -249,8 +262,15 @@ public class ContraptionCollider { entityPosition.z + allowedMovement.z); entity.setMotion(entityMotion); - if (!serverPlayer && player) - AllPackets.channel.sendToServer(new ClientMotionPacket(entityMotion, true)); + if (playerType != PlayerType.CLIENT) + continue; + + double d0 = entity.getX() - entity.prevPosX - contactPointMotion.x; + double d1 = entity.getZ() - entity.prevPosZ - contactPointMotion.z; + 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)); } } @@ -296,6 +316,21 @@ public class ContraptionCollider { return vec3d; } + private static PlayerType getPlayerType(Entity entity) { + if (!(entity instanceof PlayerEntity)) + return PlayerType.NONE; + if (!entity.world.isRemote) + return PlayerType.SERVER; + MutableBoolean isClient = new MutableBoolean(false); + DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> isClient.setValue(isClientPlayerEntity(entity))); + return isClient.booleanValue() ? PlayerType.CLIENT : PlayerType.REMOTE; + } + + @OnlyIn(Dist.CLIENT) + private static boolean isClientPlayerEntity(Entity entity) { + return entity instanceof ClientPlayerEntity; + } + private static ReuseableStream getPotentiallyCollidedShapes(World world, Contraption contraption, AxisAlignedBB localBB) { @@ -395,10 +430,10 @@ public class ContraptionCollider { BlockInfo blockInfo = contraption.blocks.get(pos); if (AllMovementBehaviours.hasMovementBehaviour(blockInfo.state.getBlock())) { - MovementBehaviour movementBehaviour = AllMovementBehaviours.getMovementBehaviour(blockInfo.state.getBlock()); + MovementBehaviour movementBehaviour = + AllMovementBehaviours.getMovementBehaviour(blockInfo.state.getBlock()); if (movementBehaviour instanceof BlockBreakingMovementBehaviour) { - BlockBreakingMovementBehaviour behaviour = - (BlockBreakingMovementBehaviour) movementBehaviour; + BlockBreakingMovementBehaviour behaviour = (BlockBreakingMovementBehaviour) movementBehaviour; if (!behaviour.canBreak(world, colliderPos, collidedState) && !collidedState.getCollisionShape(world, pos) .isEmpty()) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java index 29766dc28..072407d4e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionEntity.java @@ -78,6 +78,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD final List collidingEntities = new ArrayList<>(); private boolean isSerializingFurnaceCart; private boolean attachedExtraInventories; + private boolean prevPosInvalid; private static final Ingredient FUEL_ITEMS = Ingredient.fromItems(Items.COAL, Items.CHARCOAL); private static final DataParameter STALLED = @@ -107,6 +108,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD isSerializingFurnaceCart = false; attachedExtraInventories = false; forcedAngle = -1; + prevPosInvalid = true; } public static ContraptionEntity createMounted(World world, Contraption contraption, float initialAngle) { @@ -289,26 +291,32 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD remove(); return; } + + prevPosX = getX(); + prevPosY = getY(); + prevPosZ = getZ(); + prevPosInvalid = false; if (!initialized) contraptionInitialize(); - checkController(); Entity mountedEntity = getRidingEntity(); if (mountedEntity != null) { tickAsPassenger(mountedEntity); + super.tick(); return; } if (getMotion().length() < 1 / 4098f) setMotion(Vec3d.ZERO); - + move(getMotion().x, getMotion().y, getMotion().z); if (ContraptionCollider.collideBlocks(this)) getController().collided(); - tickActors(getPositionVec().subtract(prevPosX, prevPosY, prevPosZ)); + Vec3d movement = getPositionVec().subtract(prevPosX, prevPosY, prevPosZ); + tickActors(movement); prevYaw = yaw; prevPitch = pitch; @@ -439,8 +447,6 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD furnaceCart.deserializeNBT(nbt); } } - - super.tick(); } public void tickActors(Vec3d movementVector) { @@ -846,6 +852,9 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD } public Vec3d getContactPointMotion(Vec3d globalContactPoint) { + if (prevPosInvalid) + return Vec3d.ZERO; + Vec3d positionVec = getPositionVec(); Vec3d conMotion = positionVec.subtract(getPrevPositionVec()); Vec3d conAngularMotion = getRotationVec().subtract(getPrevRotationVec()); @@ -906,5 +915,10 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD public void setCoupledCart(UUID id) { dataManager.set(COUPLED_CART, Optional.ofNullable(id)); } + + @Override + public boolean isOnePlayerRiding() { + return false; + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionHandler.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionHandler.java index ff63f6662..e959ea513 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionHandler.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionHandler.java @@ -4,6 +4,7 @@ import static java.util.concurrent.TimeUnit.SECONDS; import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutionException; @@ -28,7 +29,8 @@ public class ContraptionHandler { if (!(entity instanceof ContraptionEntity)) return; try { - List> list = activeContraptions.get(world, ArrayList::new); + List> list = + activeContraptions.get(world, () -> Collections.synchronizedList(new ArrayList<>())); ContraptionEntity contraption = (ContraptionEntity) entity; list.add(new WeakReference<>(contraption)); } catch (ExecutionException e) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionInteractionHandler.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionHandlerClient.java similarity index 72% rename from src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionInteractionHandler.java rename to src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionHandlerClient.java index 36ada9e88..191f19bc3 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionInteractionHandler.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionHandlerClient.java @@ -1,4 +1,5 @@ package com.simibubi.create.content.contraptions.components.structureMovement; + import org.apache.commons.lang3.mutable.MutableObject; import com.simibubi.create.content.contraptions.components.structureMovement.sync.ContraptionInteractionPacket; @@ -9,6 +10,8 @@ import com.simibubi.create.foundation.utility.RaycastHelper.PredicateTraceResult import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.player.ClientPlayerEntity; +import net.minecraft.client.entity.player.RemoteClientPlayerEntity; +import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.Direction; import net.minecraft.util.Hand; import net.minecraft.util.math.AxisAlignedBB; @@ -20,11 +23,38 @@ import net.minecraft.world.gen.feature.template.Template.BlockInfo; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.client.event.InputEvent.ClickInputEvent; +import net.minecraftforge.event.TickEvent.Phase; +import net.minecraftforge.event.TickEvent.PlayerTickEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; @EventBusSubscriber -public class ContraptionInteractionHandler { +public class ContraptionHandlerClient { + + @SubscribeEvent + @OnlyIn(Dist.CLIENT) + public static void preventRemotePlayersWalkingAnimations(PlayerTickEvent event) { + if (event.phase == Phase.START) + return; + if (!(event.player instanceof RemoteClientPlayerEntity)) + return; + RemoteClientPlayerEntity remotePlayer = (RemoteClientPlayerEntity) event.player; + CompoundNBT data = remotePlayer.getPersistentData(); + if (!data.contains("LastOverrideLimbSwingUpdate")) + return; + + int lastOverride = data.getInt("LastOverrideLimbSwingUpdate"); + data.putInt("LastOverrideLimbSwingUpdate", lastOverride + 1); + if (lastOverride > 5) { + data.remove("LastOverrideLimbSwingUpdate"); + data.remove("OverrideLimbSwing"); + return; + } + + float limbSwing = data.getFloat("OverrideLimbSwing"); + remotePlayer.prevPosX = remotePlayer.getX() - (limbSwing / 4); + remotePlayer.prevPosZ = remotePlayer.getZ(); + } @SubscribeEvent @OnlyIn(Dist.CLIENT) @@ -38,11 +68,12 @@ public class ContraptionInteractionHandler { if (!event.isUseItem()) return; Vec3d origin = RaycastHelper.getTraceOrigin(player); - + double reach = mc.playerController.getBlockReachDistance(); - if (mc.objectMouseOver != null && mc.objectMouseOver.getHitVec() != null) - reach = Math.min(mc.objectMouseOver.getHitVec().distanceTo(origin), reach); - + if (mc.objectMouseOver != null && mc.objectMouseOver.getHitVec() != null) + reach = Math.min(mc.objectMouseOver.getHitVec() + .distanceTo(origin), reach); + Vec3d target = RaycastHelper.getTraceTarget(player, reach, origin); for (ContraptionEntity contraptionEntity : mc.world.getEntitiesWithinAABB(ContraptionEntity.class, new AxisAlignedBB(origin, target))) { @@ -75,11 +106,10 @@ public class ContraptionInteractionHandler { Hand hand = event.getHand(); Direction face = rayTraceResult.getFace(); BlockPos pos = rayTraceResult.getPos(); - + if (!contraptionEntity.handlePlayerInteraction(player, pos, face, hand)) return; - AllPackets.channel.sendToServer(new ContraptionInteractionPacket(contraptionEntity, hand, - pos, face)); + AllPackets.channel.sendToServer(new ContraptionInteractionPacket(contraptionEntity, hand, pos, face)); event.setCanceled(true); event.setSwingHand(false); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerTileEntity.java index 2638f75bf..4e98a97be 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerTileEntity.java @@ -10,9 +10,12 @@ import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform; import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.INamedIconOptions; import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollOptionBehaviour; import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.foundation.utility.VecHelper; +import net.minecraft.state.properties.RailShape; import net.minecraft.tileentity.TileEntityType; -import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.Vec3d; public class CartAssemblerTileEntity extends SmartTileEntity { private static final int assemblyCooldown = 8; @@ -24,11 +27,11 @@ public class CartAssemblerTileEntity extends SmartTileEntity { super(type); ticksSinceMinecartUpdate = assemblyCooldown; } - + @Override public void tick() { super.tick(); - if(ticksSinceMinecartUpdate < assemblyCooldown) { + if (ticksSinceMinecartUpdate < assemblyCooldown) { ticksSinceMinecartUpdate++; } } @@ -36,15 +39,36 @@ public class CartAssemblerTileEntity extends SmartTileEntity { @Override public void addBehaviours(List behaviours) { movementMode = new ScrollOptionBehaviour<>(CartMovementMode.class, - Lang.translate("contraptions.cart_movement_mode"), this, getMovementModeSlot()); + Lang.translate("contraptions.cart_movement_mode"), this, getMovementModeSlot()); movementMode.requiresWrench(); behaviours.add(movementMode); } protected ValueBoxTransform getMovementModeSlot() { - return new CenteredSideValueBoxTransform((state, d) -> d == Direction.UP); + return new CartAssemblerValueBoxTransform(); } + private class CartAssemblerValueBoxTransform extends CenteredSideValueBoxTransform { + + public CartAssemblerValueBoxTransform() { + super((state, d) -> { + if (d.getAxis() + .isVertical()) + return false; + if (!state.has(CartAssemblerBlock.RAIL_SHAPE)) + return false; + RailShape railShape = state.get(CartAssemblerBlock.RAIL_SHAPE); + return (d.getAxis() == Axis.X) == (railShape == RailShape.NORTH_SOUTH); + }); + } + + @Override + protected Vec3d getSouthLocation() { + return VecHelper.voxelSpace(8, 8, 18); + } + + } + public static enum CartMovementMode implements INamedIconOptions { ROTATE(AllIcons.I_CART_ROTATE), @@ -71,11 +95,11 @@ public class CartAssemblerTileEntity extends SmartTileEntity { return translationKey; } } - + public void resetTicksSinceMinecartUpdate() { ticksSinceMinecartUpdate = 0; } - + public boolean isMinecartUpdateValid() { return ticksSinceMinecartUpdate >= assemblyCooldown; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyRenderer.java index 9994c52ec..6365ac1ae 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyRenderer.java @@ -26,6 +26,11 @@ public class PulleyRenderer extends KineticTileEntityRenderer { public PulleyRenderer(TileEntityRendererDispatcher dispatcher) { super(dispatcher); } + + @Override + public boolean isGlobalRenderer(KineticTileEntity p_188185_1_) { + return true; + } @Override protected void renderSafe(KineticTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java index 04d0e1e81..7e9fd847c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java @@ -39,7 +39,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity { public double getMaxRenderDistanceSquared() { return super.getMaxRenderDistanceSquared() + offset * offset; } - + @Override protected void assemble() { if (!(world.getBlockState(pos) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ClientMotionPacket.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ClientMotionPacket.java index a80351080..f5bb6758e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ClientMotionPacket.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ClientMotionPacket.java @@ -2,26 +2,31 @@ package com.simibubi.create.content.contraptions.components.structureMovement.sy import java.util.function.Supplier; +import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.networking.SimplePacketBase; import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.network.PacketBuffer; import net.minecraft.util.math.Vec3d; import net.minecraftforge.fml.network.NetworkEvent.Context; +import net.minecraftforge.fml.network.PacketDistributor; public class ClientMotionPacket extends SimplePacketBase { private Vec3d motion; private boolean onGround; + private float limbSwing; - public ClientMotionPacket(Vec3d motion, boolean onGround) { + public ClientMotionPacket(Vec3d motion, boolean onGround, float limbSwing) { this.motion = motion; this.onGround = onGround; + this.limbSwing = limbSwing; } public ClientMotionPacket(PacketBuffer buffer) { motion = new Vec3d(buffer.readFloat(), buffer.readFloat(), buffer.readFloat()); onGround = buffer.readBoolean(); + limbSwing = buffer.readFloat(); } @Override @@ -30,6 +35,7 @@ public class ClientMotionPacket extends SimplePacketBase { buffer.writeFloat((float) motion.y); buffer.writeFloat((float) motion.z); buffer.writeBoolean(onGround); + buffer.writeFloat(limbSwing); } @Override @@ -47,6 +53,8 @@ public class ClientMotionPacket extends SimplePacketBase { sender.fallDistance = 0; sender.connection.floatingTickCount = 0; } + AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> sender), + new LimbSwingUpdatePacket(sender.getEntityId(), sender.getPositionVec(), limbSwing)); }); context.get() .setPacketHandled(true); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/LimbSwingUpdatePacket.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/LimbSwingUpdatePacket.java new file mode 100644 index 000000000..4d3bfea33 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/LimbSwingUpdatePacket.java @@ -0,0 +1,62 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.sync; + +import java.util.function.Supplier; + +import com.simibubi.create.foundation.networking.SimplePacketBase; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.entity.Entity; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.math.Vec3d; +import net.minecraftforge.fml.network.NetworkEvent.Context; + +public class LimbSwingUpdatePacket extends SimplePacketBase { + + private int entityId; + private Vec3d position; + private float limbSwing; + + public LimbSwingUpdatePacket(int entityId, Vec3d position, float limbSwing) { + this.entityId = entityId; + this.position = position; + this.limbSwing = limbSwing; + } + + public LimbSwingUpdatePacket(PacketBuffer buffer) { + entityId = buffer.readInt(); + position = new Vec3d(buffer.readFloat(), buffer.readFloat(), buffer.readFloat()); + limbSwing = buffer.readFloat(); + } + + @Override + public void write(PacketBuffer buffer) { + buffer.writeInt(entityId); + buffer.writeFloat((float) position.x); + buffer.writeFloat((float) position.y); + buffer.writeFloat((float) position.z); + buffer.writeFloat(limbSwing); + } + + @Override + public void handle(Supplier context) { + context.get() + .enqueueWork(() -> { + ClientWorld world = Minecraft.getInstance().world; + if (world == null) + return; + Entity entity = world.getEntityByID(entityId); + if (entity == null) + return; + CompoundNBT data = entity.getPersistentData(); + data.putInt("LastOverrideLimbSwingUpdate", 0); + data.putFloat("OverrideLimbSwing", limbSwing); + entity.setPositionAndRotationDirect(position.x, position.y, position.z, entity.rotationYaw, + entity.rotationPitch, 2, false); + }); + context.get() + .setPacketHandled(true); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/FillingBySpout.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/FillingBySpout.java index 59a3b3ada..4afe6f0d6 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/FillingBySpout.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/FillingBySpout.java @@ -24,8 +24,7 @@ public class FillingBySpout { public static boolean canItemBeFilled(World world, ItemStack stack) { wrapper.setInventorySlotContents(0, stack); - if (world.getRecipeManager() - .getRecipe(AllRecipeTypes.FILLING.getType(), wrapper, world) + if (AllRecipeTypes.FILLING.find(wrapper, world) .isPresent()) return true; @@ -44,8 +43,7 @@ public class FillingBySpout { public static int getRequiredAmountForItem(World world, ItemStack stack, FluidStack availableFluid) { wrapper.setInventorySlotContents(0, stack); - Optional> recipe = world.getRecipeManager() - .getRecipe(AllRecipeTypes.FILLING.getType(), wrapper, world); + Optional> recipe = AllRecipeTypes.FILLING.find(wrapper, world); if (recipe.isPresent()) { FillingRecipe fillingRecipe = (FillingRecipe) recipe.get(); FluidIngredient requiredFluid = fillingRecipe.getRequiredFluid(); @@ -71,8 +69,7 @@ public class FillingBySpout { availableFluid.shrink(requiredAmount); wrapper.setInventorySlotContents(0, stack); - Optional> recipe = world.getRecipeManager() - .getRecipe(AllRecipeTypes.FILLING.getType(), wrapper, world); + Optional> recipe = AllRecipeTypes.FILLING.find(wrapper, world); if (recipe.isPresent()) { FillingRecipe fillingRecipe = (FillingRecipe) recipe.get(); FluidIngredient requiredFluid = fillingRecipe.getRequiredFluid(); 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 0b209bbbf..f761f9d5a 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 @@ -100,6 +100,9 @@ public class FluidTankBlock extends Block implements IWrenchable, ITE tankCapability = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, ray.getFace()); diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinBlock.java b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinBlock.java index 39fbddf41..6a57ebbb1 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinBlock.java @@ -9,16 +9,23 @@ import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.item.ItemHelper; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour; +import com.simibubi.create.foundation.utility.Iterate; +import com.simibubi.create.foundation.utility.Pair; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUseContext; +import net.minecraft.state.DirectionProperty; +import net.minecraft.state.StateContainer.Builder; +import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ActionResultType; +import net.minecraft.util.Direction; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockRayTraceResult; @@ -26,14 +33,22 @@ import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction; import net.minecraftforge.items.IItemHandlerModifiable; import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.ItemStackHandler; public class BasinBlock extends Block implements ITE, IWrenchable { + public static final DirectionProperty FACING = BlockStateProperties.FACING_EXCEPT_UP; + public BasinBlock(Properties p_i48440_1_) { super(p_i48440_1_); + setDefaultState(getDefaultState().with(FACING, Direction.DOWN)); } @Override @@ -41,6 +56,11 @@ public class BasinBlock extends Block implements ITE, IWrenchab return true; } + @Override + protected void fillStateContainer(Builder p_206840_1_) { + super.fillStateContainer(p_206840_1_.add(FACING)); + } + @Override public TileEntity createTileEntity(BlockState state, IBlockReader world) { return AllTileEntities.BASIN.create(); @@ -54,12 +74,16 @@ public class BasinBlock extends Block implements ITE, IWrenchab @Override public ActionResultType onUse(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) { - if (!player.getHeldItem(handIn) - .isEmpty()) - return ActionResultType.PASS; + ItemStack heldItem = player.getHeldItem(handIn); try { BasinTileEntity te = getTileEntity(worldIn, pos); + if (!heldItem.isEmpty()) { + if (tryEmptyItemIntoBasin(worldIn, player, handIn, heldItem, te)) + return ActionResultType.SUCCESS; + return ActionResultType.PASS; + } + IItemHandlerModifiable inv = te.itemCapability.orElse(new ItemStackHandler(1)); for (int slot = 0; slot < inv.getSlots(); slot++) { player.inventory.placeItemBackInInventory(worldIn, inv.getStackInSlot(slot)); @@ -72,6 +96,30 @@ public class BasinBlock extends Block implements ITE, IWrenchab return ActionResultType.SUCCESS; } + protected boolean tryEmptyItemIntoBasin(World worldIn, PlayerEntity player, Hand handIn, ItemStack heldItem, + BasinTileEntity te) { + if (!EmptyingByBasin.canItemBeEmptied(worldIn, heldItem)) + return false; + + Pair emptyItem = EmptyingByBasin.emptyItem(worldIn, heldItem, true); + LazyOptional capability = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY); + IFluidHandler tank = capability.orElse(null); + FluidStack fluidStack = emptyItem.getFirst(); + + if (tank == null || fluidStack.getAmount() != tank.fill(fluidStack, FluidAction.SIMULATE)) + return false; + if (worldIn.isRemote) + return true; + + EmptyingByBasin.emptyItem(worldIn, heldItem, false); + tank.fill(fluidStack, FluidAction.EXECUTE); + if (heldItem.isEmpty()) + player.setHeldItem(handIn, emptyItem.getSecond()); + else + player.inventory.placeItemBackInInventory(worldIn, emptyItem.getSecond()); + return true; + } + @Override public void onLanded(IBlockReader worldIn, Entity entityIn) { super.onLanded(worldIn, entityIn); @@ -102,6 +150,11 @@ public class BasinBlock extends Block implements ITE, IWrenchab return AllShapes.BASIN_BLOCK_SHAPE; } + @Override + public void onBlockAdded(BlockState state, World world, BlockPos pos, BlockState p_220082_4_, boolean p_220082_5_) { + updateDiagonalNeighbours(state, world, pos); + } + @Override public VoxelShape getCollisionShape(BlockState state, IBlockReader reader, BlockPos pos, ISelectionContext ctx) { if (ctx.getEntity() instanceof ItemEntity) @@ -111,6 +164,7 @@ public class BasinBlock extends Block implements ITE, IWrenchab @Override public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) { + updateDiagonalNeighbours(state, worldIn, pos); if (!state.hasTileEntity() || state.getBlock() == newState.getBlock()) return; TileEntityBehaviour.destroy(worldIn, pos, FilteringBehaviour.TYPE); @@ -140,4 +194,35 @@ public class BasinBlock extends Block implements ITE, IWrenchab return BasinTileEntity.class; } + @Override + public BlockState getStateForPlacement(BlockItemUseContext ctx) { + BlockState state = super.getStateForPlacement(ctx); + World world = ctx.getWorld(); + BlockPos pos = ctx.getPos(); + return updateDiagonalState(state, world, pos); + } + + protected void updateDiagonalNeighbours(BlockState state, World world, BlockPos pos) { + for (Direction direction : Iterate.horizontalDirections) { + BlockPos toUpdate = pos.up() + .offset(direction); + BlockState stateToUpdate = world.getBlockState(toUpdate); + BlockState updated = updateDiagonalState(stateToUpdate, world, toUpdate); + if (stateToUpdate != updated && !world.isRemote) + world.setBlockState(toUpdate, updated); + } + } + + public static BlockState updateDiagonalState(BlockState state, IBlockReader world, BlockPos pos) { + if (!(state.getBlock() instanceof BasinBlock)) + return state; + for (Direction direction : Iterate.horizontalDirections) { + BlockState diagonaloutputBasin = world.getBlockState(pos.down() + .offset(direction)); + if (diagonaloutputBasin.getBlock() instanceof BasinBlock) + return state.with(FACING, direction); + } + return state.with(FACING, Direction.DOWN); + } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinGenerator.java b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinGenerator.java new file mode 100644 index 000000000..fe96055ac --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinGenerator.java @@ -0,0 +1,32 @@ +package com.simibubi.create.content.contraptions.processing; + +import com.simibubi.create.foundation.data.AssetLookup; +import com.simibubi.create.foundation.data.SpecialBlockStateGen; +import com.tterrag.registrate.providers.DataGenContext; +import com.tterrag.registrate.providers.RegistrateBlockstateProvider; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraftforge.client.model.generators.ModelFile; + +public class BasinGenerator extends SpecialBlockStateGen { + + @Override + protected int getXRotation(BlockState state) { + return 0; + } + + @Override + protected int getYRotation(BlockState state) { + return horizontalAngle(state.get(BasinBlock.FACING)); + } + + @Override + public ModelFile getModel(DataGenContext ctx, RegistrateBlockstateProvider prov, + BlockState state) { + if (state.get(BasinBlock.FACING).getAxis().isVertical()) + return AssetLookup.partialBaseModel(ctx, prov); + return AssetLookup.partialBaseModel(ctx, prov, "directional"); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinInputInventory.java b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinInputInventory.java deleted file mode 100644 index 6f105dd5e..000000000 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinInputInventory.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.simibubi.create.content.contraptions.processing; - -import com.simibubi.create.foundation.item.SmartInventory; - -import net.minecraft.item.ItemStack; -import net.minecraftforge.items.ItemHandlerHelper; - -public class BasinInputInventory extends SmartInventory { - - public BasinInputInventory(int slots, BasinTileEntity te) { - super(slots, te); - } - - @Override - public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { - // Only insert if no other slot already has a 'full' stack of this item - for (int i = 0; i < getSlots(); i++) { - ItemStack stackInSlot = getStackInSlot(i); - if (ItemHandlerHelper.canItemStacksStack(stack, stackInSlot) - && stackInSlot.getCount() == getStackLimit(i, stackInSlot)) - return stack; - } - - return super.insertItem(slot, stack, simulate); - } - -} diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinInventory.java b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinInventory.java new file mode 100644 index 000000000..3e3ac469a --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinInventory.java @@ -0,0 +1,23 @@ +package com.simibubi.create.content.contraptions.processing; + +import com.simibubi.create.foundation.item.SmartInventory; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.items.ItemHandlerHelper; + +public class BasinInventory extends SmartInventory { + + public BasinInventory(int slots, BasinTileEntity te) { + super(slots, te, 16, true); + } + + @Override + public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { + // Only insert if no other slot already has a stack of this item + for (int i = 0; i < getSlots(); i++) + if (i != slot && ItemHandlerHelper.canItemStacksStack(stack, inv.getStackInSlot(i))) + return stack; + return super.insertItem(slot, stack, simulate); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinOperatingTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinOperatingTileEntity.java index 26320f935..20383e4f4 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinOperatingTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinOperatingTileEntity.java @@ -1,49 +1,29 @@ package com.simibubi.create.content.contraptions.processing; -import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; -import com.simibubi.create.AllTileEntities; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.foundation.advancement.AllTriggers; -import com.simibubi.create.foundation.advancement.SimpleTrigger; -import com.simibubi.create.foundation.item.SmartInventory; +import com.simibubi.create.foundation.advancement.ITriggerable; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.simple.DeferralBehaviour; import com.simibubi.create.foundation.utility.recipe.RecipeFinder; import net.minecraft.inventory.IInventory; -import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipe; -import net.minecraft.item.crafting.Ingredient; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; -import net.minecraft.util.NonNullList; -import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.capability.CapabilityFluidHandler; -import net.minecraftforge.fluids.capability.IFluidHandler; -import net.minecraftforge.items.CapabilityItemHandler; -import net.minecraftforge.items.IItemHandler; -import net.minecraftforge.items.ItemHandlerHelper; public abstract class BasinOperatingTileEntity extends KineticTileEntity { public DeferralBehaviour basinChecker; public boolean basinRemoved; - protected IRecipe lastRecipe; - - protected LazyOptional basinItemInv = LazyOptional.empty(); - protected List itemInputs; - protected LazyOptional basinFluidInv = LazyOptional.empty(); - protected List fluidInputs; + protected IRecipe currentRecipe; public BasinOperatingTileEntity(TileEntityType typeIn) { super(typeIn); - itemInputs = new ArrayList<>(); - fluidInputs = new ArrayList<>(); } @Override @@ -58,29 +38,10 @@ public abstract class BasinOperatingTileEntity extends KineticTileEntity { super.onSpeedChanged(prevSpeed); if (getSpeed() == 0) basinRemoved = true; + basinRemoved = false; basinChecker.scheduleUpdate(); } - public void gatherInputs() { - itemInputs.clear(); - basinItemInv.ifPresent(handler -> { - for (int slot = 0; slot < handler.getSlots(); ++slot) { - ItemStack itemstack = handler.getStackInSlot(slot); - if (!itemstack.isEmpty()) - itemInputs.add(itemstack); - } - }); - - fluidInputs.clear(); - basinFluidInv.ifPresent(handler -> { - for (int tank = 0; tank < handler.getTanks(); tank++) { - FluidStack fluidInTank = handler.getFluidInTank(tank); - if (!fluidInTank.isEmpty()) - fluidInputs.add(fluidInTank); - } - }); - } - @Override public void tick() { if (basinRemoved) { @@ -100,28 +61,13 @@ public abstract class BasinOperatingTileEntity extends KineticTileEntity { return true; if (isRunning()) return false; - - Optional basinTe = getBasin(); - if (!basinTe.isPresent()) - return true; - if (!basinItemInv.isPresent()) - basinItemInv = basinTe.get() - .getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY); - if (!basinFluidInv.isPresent()) - basinFluidInv = basinTe.get() - .getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY); - if (!basinFluidInv.isPresent() || !basinItemInv.isPresent()) - return true; - if (world == null || world.isRemote) return true; - gatherInputs(); List> recipes = getMatchingRecipes(); if (recipes.isEmpty()) return true; - - lastRecipe = recipes.get(0); + currentRecipe = recipes.get(0); startProcessingBasin(); sendData(); return true; @@ -135,58 +81,37 @@ public abstract class BasinOperatingTileEntity extends KineticTileEntity { return true; } - public void applyBasinRecipe() { - if (lastRecipe == null) - return; - if (!basinItemInv.isPresent() || !basinFluidInv.isPresent()) - return; - + protected boolean matchBasinRecipe(IRecipe recipe) { + if (recipe == null) + return false; Optional basin = getBasin(); if (!basin.isPresent()) + return false; + return BasinRecipe.match(basin.get(), recipe); + } + + protected void applyBasinRecipe() { + if (currentRecipe == null) return; - SmartInventory inputs = basin.get().getInputInventory(); - SmartInventory outputs = basin.get().getOutputInventory(); - List containers = new ArrayList<>(); - - NonNullList ingredients = lastRecipe.getIngredients(); - Ingredients: for (int i = 0; i < ingredients.size(); i++) { - Ingredient ingredient = ingredients.get(i); - - for (int slot = 0; slot < inputs.getSlots(); slot++) { - if (!ingredient.test(inputs.extractItem(slot, 1, true))) - continue; - ItemStack extracted = inputs.extractItem(slot, 1, false); - if (extracted.hasContainerItem()) - containers.add(extracted.getContainerItem() - .copy()); - continue Ingredients; - } - - // something wasn't found + + Optional optionalBasin = getBasin(); + if (!optionalBasin.isPresent()) return; - } - - if (world != null && !world.isRemote) { - SimpleTrigger trigger = AllTriggers.MIXER_MIX; - if (AllTileEntities.MECHANICAL_PRESS.is(this)) - trigger = AllTriggers.PRESS_COMPACT; - AllTriggers.triggerForNearbyPlayers(trigger, world, pos, 4); - } - - outputs.allowInsertion(); - ItemHandlerHelper.insertItemStacked(outputs, lastRecipe.getRecipeOutput() - .copy(), false); // TODO only works for single item output - containers.forEach(stack -> ItemHandlerHelper.insertItemStacked(outputs, stack, false)); - outputs.forbidInsertion(); - + BasinTileEntity basin = optionalBasin.get(); + if (!BasinRecipe.apply(basin, currentRecipe)) + return; + Optional processedRecipeTrigger = getProcessedRecipeTrigger(); + if (world != null && !world.isRemote && processedRecipeTrigger.isPresent()) + AllTriggers.triggerForNearbyPlayers(processedRecipeTrigger.get(), world, pos, 4); + basin.inputTank.sendDataImmediately(); + // Continue mixing - gatherInputs(); - if (matchBasinRecipe(lastRecipe)) { + if (matchBasinRecipe(currentRecipe)) { continueWithPreviousRecipe(); sendData(); } - getBasin().ifPresent(BasinTileEntity::notifyChangeOfContents); + basin.notifyChangeOfContents(); } protected List> getMatchingRecipes() { @@ -210,28 +135,13 @@ public abstract class BasinOperatingTileEntity extends KineticTileEntity { return Optional.empty(); return Optional.of((BasinTileEntity) basinTE); } + + protected Optional getProcessedRecipeTrigger() { + return Optional.empty(); + } protected abstract boolean matchStaticFilters(IRecipe recipe); - protected boolean matchBasinRecipe(IRecipe recipe) { - if (recipe == null) - return false; - - Optional basin = getBasin(); - if (!basin.isPresent()) - return false; - BasinTileEntity basinTileEntity = basin.get(); - if (!basinTileEntity.getFilter() - .test(recipe.getRecipeOutput())) - return false; - - NonNullList ingredients = recipe.getIngredients(); - if (!ingredients.stream() - .allMatch(ingredient -> (ingredient.isSimple() || ingredient.getMatchingStacks().length == 1))) - return false; - return true; - } - protected abstract Object getRecipeCacheKey(); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinRecipe.java b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinRecipe.java new file mode 100644 index 000000000..6fc0a451d --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinRecipe.java @@ -0,0 +1,199 @@ +package com.simibubi.create.content.contraptions.processing; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; + +import javax.annotation.Nonnull; + +import com.simibubi.create.AllRecipeTypes; +import com.simibubi.create.content.contraptions.processing.ProcessingRecipeBuilder.ProcessingRecipeParams; +import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel; +import com.simibubi.create.foundation.fluid.FluidIngredient; +import com.simibubi.create.foundation.item.SmartInventory; +import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour; +import com.simibubi.create.foundation.tileEntity.behaviour.fluid.SmartFluidTankBehaviour; +import com.simibubi.create.foundation.tileEntity.behaviour.fluid.SmartFluidTankBehaviour.TankSegment; +import com.simibubi.create.foundation.utility.Iterate; + +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.item.crafting.Ingredient; +import net.minecraft.world.World; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.IItemHandler; + +public class BasinRecipe extends ProcessingRecipe { + + public static boolean match(BasinTileEntity basin, IRecipe recipe) { + FilteringBehaviour filter = basin.getFilter(); + if (filter == null || !filter.test(recipe.getRecipeOutput())) + return false; + return apply(basin, recipe, true); + } + + public static boolean apply(BasinTileEntity basin, IRecipe recipe) { + return apply(basin, recipe, false); + } + + private static boolean apply(BasinTileEntity basin, IRecipe recipe, boolean test) { + boolean isBasinRecipe = recipe instanceof BasinRecipe; + IItemHandler availableItems = basin.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) + .orElse(null); + IFluidHandler availableFluids = basin.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) + .orElse(null); + + if (availableItems == null || availableFluids == null) + return false; + + HeatLevel heat = basin.getHeatLevel(); + if (isBasinRecipe && !((BasinRecipe) recipe).getRequiredHeat() + .testBlazeBurner(heat)) + return false; + + List recipeOutputItems = new ArrayList<>(); + List recipeOutputFluids = new ArrayList<>(); + + List ingredients = new LinkedList<>(recipe.getIngredients()); + ingredients.sort(Comparator.comparingInt(i -> i.getMatchingStacks().length)); + List fluidIngredients = + isBasinRecipe ? ((BasinRecipe) recipe).getFluidIngredients() : Collections.emptyList(); + + for (boolean simulate : Iterate.trueAndFalse) { + + if (!simulate && test) + return true; + + int[] extractedItemsFromSlot = new int[availableItems.getSlots()]; + int[] extractedFluidsFromTank = new int[availableFluids.getTanks()]; + + Ingredients: for (int i = 0; i < ingredients.size(); i++) { + Ingredient ingredient = ingredients.get(i); + + for (int slot = 0; slot < availableItems.getSlots(); slot++) { + if (simulate && availableItems.getStackInSlot(slot) + .getCount() <= extractedItemsFromSlot[slot]) + continue; + ItemStack extracted = availableItems.extractItem(slot, 1, true); + if (!ingredient.test(extracted)) + continue; + if (!simulate) + availableItems.extractItem(slot, 1, false); + else if (extracted.hasContainerItem()) + recipeOutputItems.add(extracted.getContainerItem() + .copy()); + extractedItemsFromSlot[slot]++; + continue Ingredients; + } + + // something wasn't found + return false; + } + + boolean fluidsAffected = false; + FluidIngredients: for (int i = 0; i < fluidIngredients.size(); i++) { + FluidIngredient fluidIngredient = fluidIngredients.get(i); + int amountRequired = fluidIngredient.getRequiredAmount(); + + for (int tank = 0; tank < availableFluids.getTanks(); tank++) { + FluidStack fluidStack = availableFluids.getFluidInTank(tank); + if (simulate && fluidStack.getAmount() <= extractedFluidsFromTank[tank]) + continue; + if (!fluidIngredient.test(fluidStack)) + continue; + int drainedAmount = Math.min(amountRequired, fluidStack.getAmount()); + if (!simulate) { + fluidStack.shrink(drainedAmount); + fluidsAffected = true; + } + amountRequired -= drainedAmount; + if (amountRequired != 0) + continue; + extractedFluidsFromTank[tank] += drainedAmount; + continue FluidIngredients; + } + + // something wasn't found + return false; + } + + if (fluidsAffected) { + basin.getBehaviour(SmartFluidTankBehaviour.INPUT) + .foreach(TankSegment::onFluidStackChanged); + basin.getBehaviour(SmartFluidTankBehaviour.OUTPUT) + .foreach(TankSegment::onFluidStackChanged); + } + + if (simulate) { + if (recipe instanceof BasinRecipe) { + recipeOutputItems.addAll(((BasinRecipe) recipe).rollResults()); + recipeOutputFluids.addAll(((BasinRecipe) recipe).getFluidResults()); + } else + recipeOutputItems.add(recipe.getRecipeOutput()); + } + + if (!basin.acceptOutputs(recipeOutputItems, recipeOutputFluids, simulate)) + return false; + } + + return true; + } + + /** + * For JEI purposes only + */ + public boolean convertedRecipe; + + public static BasinRecipe convert(IRecipe recipe) { + BasinRecipe basinRecipe = new ProcessingRecipeBuilder<>(BasinRecipe::new, recipe.getId()) + .withItemIngredients(recipe.getIngredients()) + .withSingleItemOutput(recipe.getRecipeOutput()) + .build(); + basinRecipe.convertedRecipe = true; + return basinRecipe; + } + + protected BasinRecipe(AllRecipeTypes type, ProcessingRecipeParams params) { + super(type, params); + } + + public BasinRecipe(ProcessingRecipeParams params) { + this(AllRecipeTypes.BASIN, params); + } + + @Override + protected int getMaxInputCount() { + return 9; + } + + @Override + protected int getMaxOutputCount() { + return 4; + } + + @Override + protected int getMaxFluidInputCount() { + return 2; + } + + @Override + protected int getMaxFluidOutputCount() { + return 2; + } + + @Override + protected boolean canRequireHeat() { + return true; + } + + @Override + public boolean matches(SmartInventory inv, @Nonnull World worldIn) { + return false; + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinRenderer.java index e9e232abd..a02cb4eed 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinRenderer.java @@ -79,16 +79,19 @@ public class BasinRenderer extends SmartTileEntityRenderer { if (tankSegment.getRenderedFluid() .isEmpty()) continue; - totalUnits += tankSegment.getTotalUnits(partialTicks); + float units = tankSegment.getTotalUnits(partialTicks); + if (units < 1) + continue; + totalUnits += units; renderedFluids++; } } if (renderedFluids == 0) return 0; - if (totalUnits == 0) + if (totalUnits < 1) return 0; - + float fluidLevel = MathHelper.clamp(totalUnits / 2000, 0, 1); float xMin = 2 / 16f; @@ -105,8 +108,11 @@ public class BasinRenderer extends SmartTileEntityRenderer { FluidStack renderedFluid = tankSegment.getRenderedFluid(); if (renderedFluid.isEmpty()) continue; - - float partial = tankSegment.getTotalUnits(partialTicks) / totalUnits; + float units = tankSegment.getTotalUnits(partialTicks); + if (units < 1) + continue; + + float partial = units / totalUnits; xMax += partial * 12 / 16f; FluidRenderer.renderTiledFluidBB(renderedFluid, xMin, yMin, zMin, xMax, yMax, zMax, buffer, ms, light, false); @@ -114,7 +120,7 @@ public class BasinRenderer extends SmartTileEntityRenderer { xMin = xMax; } } - + return fluidLevel; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinTileEntity.java index 6b437512f..1ee7746c8 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinTileEntity.java @@ -5,6 +5,9 @@ import java.util.Optional; import javax.annotation.Nonnull; +import com.simibubi.create.AllTags; +import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock; +import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel; import com.simibubi.create.foundation.fluid.CombinedTankWrapper; import com.simibubi.create.foundation.item.SmartInventory; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; @@ -13,30 +16,36 @@ import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform; import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.fluid.SmartFluidTankBehaviour; +import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.block.BlockState; +import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction; import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; +import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.wrapper.CombinedInvWrapper; public class BasinTileEntity extends SmartTileEntity implements ITickableTileEntity { - public BasinInputInventory inputInventory; + public BasinInventory inputInventory; public SmartFluidTankBehaviour inputTank; - protected SmartInventory outputInventory; protected SmartFluidTankBehaviour outputTank; @@ -48,12 +57,11 @@ public class BasinTileEntity extends SmartTileEntity implements ITickableTileEnt public BasinTileEntity(TileEntityType type) { super(type); - inputInventory = new BasinInputInventory(9, this); - inputInventory.withMaxStackSize(8) - .forbidExtraction(); - outputInventory = new SmartInventory(9, this).forbidInsertion(); - itemCapability = LazyOptional.of(() -> new CombinedInvWrapper(inputInventory, outputInventory)); + inputInventory = new BasinInventory(9, this); + inputInventory.whenContentsChanged(() -> contentsChanged = true); + outputInventory = new BasinInventory(9, this).forbidInsertion(); + itemCapability = LazyOptional.of(() -> new CombinedInvWrapper(inputInventory, outputInventory)); contentsChanged = true; } @@ -65,7 +73,8 @@ public class BasinTileEntity extends SmartTileEntity implements ITickableTileEnt .forRecipes(); behaviours.add(filtering); - inputTank = new SmartFluidTankBehaviour(SmartFluidTankBehaviour.INPUT, this, 2, 1000, true).forbidExtraction(); + inputTank = new SmartFluidTankBehaviour(SmartFluidTankBehaviour.INPUT, this, 2, 1000, true) + .whenFluidUpdates(() -> contentsChanged = true); outputTank = new SmartFluidTankBehaviour(SmartFluidTankBehaviour.OUTPUT, this, 2, 1000, true).forbidInsertion(); behaviours.add(inputTank); behaviours.add(outputTank); @@ -112,6 +121,16 @@ public class BasinTileEntity extends SmartTileEntity implements ITickableTileEnt return super.getCapability(cap, side); } + @Override + public void notifyUpdate() { + super.notifyUpdate(); + } + + @Override + public void lazyTick() { + super.lazyTick(); + } + @Override public void tick() { super.tick(); @@ -119,6 +138,17 @@ public class BasinTileEntity extends SmartTileEntity implements ITickableTileEnt return; contentsChanged = false; getOperator().ifPresent(te -> te.basinChecker.scheduleUpdate()); + + for (Direction offset : Iterate.horizontalDirections) { + BlockPos toUpdate = pos.up() + .offset(offset); + BlockState stateToUpdate = world.getBlockState(toUpdate); + if (stateToUpdate.getBlock() instanceof BasinBlock && stateToUpdate.get(BasinBlock.FACING) == offset.getOpposite()) { + TileEntity te = world.getTileEntity(toUpdate); + if (te instanceof BasinTileEntity) + ((BasinTileEntity) te).contentsChanged = true; + } + } } private Optional getOperator() { @@ -152,11 +182,64 @@ public class BasinTileEntity extends SmartTileEntity implements ITickableTileEnt return 256; } + public boolean acceptOutputs(List outputItems, List outputFluids, boolean simulate) { + outputInventory.allowInsertion(); + outputTank.allowInsertion(); + boolean acceptOutputsInner = acceptOutputsInner(outputItems, outputFluids, simulate); + outputInventory.forbidInsertion(); + outputTank.forbidInsertion(); + return acceptOutputsInner; + } + + private boolean acceptOutputsInner(List outputItems, List outputFluids, boolean simulate) { + BlockState blockState = getBlockState(); + if (!(blockState.getBlock() instanceof BasinBlock)) + return false; + Direction direction = blockState.get(BasinBlock.FACING); + + IItemHandler targetInv = null; + IFluidHandler targetTank = null; + + if (direction == Direction.DOWN) { + // No output basin, gather locally + targetInv = outputInventory; + targetTank = outputTank.getCapability() + .orElse(null); + + } else { + // Output basin, try moving items to it + TileEntity te = world.getTileEntity(pos.down() + .offset(direction)); + if (!(te instanceof BasinTileEntity)) + return false; + targetInv = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) + .orElse(null); + targetTank = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) + .orElse(null); + } + + if (targetInv == null) + return false; + for (ItemStack itemStack : outputItems) + if (!ItemHandlerHelper.insertItemStacked(targetInv, itemStack.copy(), simulate) + .isEmpty()) + return false; + + if (targetTank == null) + return false; + for (FluidStack fluidStack : outputFluids) + if (targetTank.fill(fluidStack.copy(), simulate ? FluidAction.SIMULATE : FluidAction.EXECUTE) != fluidStack + .getAmount()) + return false; + + return true; + } + class BasinValueBox extends ValueBoxTransform.Sided { @Override protected Vec3d getSouthLocation() { - return VecHelper.voxelSpace(8, 12, 16); + return VecHelper.voxelSpace(8, 12, 15.75); } @Override @@ -171,4 +254,11 @@ public class BasinTileEntity extends SmartTileEntity implements ITickableTileEnt inputInventory.deserializeNBT(compound.getCompound("InputItems")); outputInventory.deserializeNBT(compound.getCompound("OutputItems")); } + + public HeatLevel getHeatLevel() { + BlockState state = world.getBlockState(pos.down(1)); + if (state.has(BlazeBurnerBlock.HEAT_LEVEL)) + return state.get(BlazeBurnerBlock.HEAT_LEVEL); + return AllTags.AllBlockTags.FAN_HEATERS.matches(state) ? HeatLevel.SMOULDERING : HeatLevel.NONE; + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/EmptyingByBasin.java b/src/main/java/com/simibubi/create/content/contraptions/processing/EmptyingByBasin.java new file mode 100644 index 000000000..041647651 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/EmptyingByBasin.java @@ -0,0 +1,75 @@ +package com.simibubi.create.content.contraptions.processing; + +import java.util.List; +import java.util.Optional; + +import com.simibubi.create.AllRecipeTypes; +import com.simibubi.create.foundation.utility.Pair; + +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.world.World; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction; +import net.minecraftforge.fluids.capability.IFluidHandlerItem; +import net.minecraftforge.items.ItemStackHandler; +import net.minecraftforge.items.wrapper.RecipeWrapper; + +public class EmptyingByBasin { + + static RecipeWrapper wrapper = new RecipeWrapper(new ItemStackHandler(1)); + + public static boolean canItemBeEmptied(World world, ItemStack stack) { + wrapper.setInventorySlotContents(0, stack); + if (AllRecipeTypes.EMPTYING.find(wrapper, world) + .isPresent()) + return true; + + LazyOptional capability = + stack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY); + IFluidHandlerItem tank = capability.orElse(null); + if (tank == null) + return false; + for (int i = 0; i < tank.getTanks(); i++) { + if (tank.getFluidInTank(i) + .getAmount() > 0) + return true; + } + return false; + } + + public static Pair emptyItem(World world, ItemStack stack, boolean simulate) { + FluidStack resultingFluid = FluidStack.EMPTY; + ItemStack resultingItem = ItemStack.EMPTY; + + wrapper.setInventorySlotContents(0, stack); + Optional> recipe = AllRecipeTypes.EMPTYING.find(wrapper, world); + if (recipe.isPresent()) { + EmptyingRecipe emptyingRecipe = (EmptyingRecipe) recipe.get(); + List results = emptyingRecipe.rollResults(); + if (!simulate) + stack.shrink(1); + resultingItem = results.isEmpty() ? ItemStack.EMPTY : results.get(0); + resultingFluid = emptyingRecipe.getResultingFluid(); + return Pair.of(resultingFluid, resultingItem); + } + + ItemStack split = stack.copy(); + split.setCount(1); + LazyOptional capability = + split.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY); + IFluidHandlerItem tank = capability.orElse(null); + if (tank == null) + return Pair.of(resultingFluid, resultingItem); + resultingFluid = tank.drain(1000, simulate ? FluidAction.SIMULATE : FluidAction.EXECUTE); + resultingItem = tank.getContainer() + .copy(); + if (!simulate) + stack.shrink(1); + + return Pair.of(resultingFluid, resultingItem); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/EmptyingRecipe.java b/src/main/java/com/simibubi/create/content/contraptions/processing/EmptyingRecipe.java new file mode 100644 index 000000000..fbed9d886 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/EmptyingRecipe.java @@ -0,0 +1,42 @@ +package com.simibubi.create.content.contraptions.processing; + +import com.simibubi.create.AllRecipeTypes; +import com.simibubi.create.content.contraptions.processing.ProcessingRecipeBuilder.ProcessingRecipeParams; + +import net.minecraft.world.World; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.items.wrapper.RecipeWrapper; + +public class EmptyingRecipe extends ProcessingRecipe { + + public EmptyingRecipe(ProcessingRecipeParams params) { + super(AllRecipeTypes.EMPTYING, params); + } + + @Override + public boolean matches(RecipeWrapper inv, World p_77569_2_) { + return ingredients.get(0).test(inv.getStackInSlot(0)); + } + + @Override + protected int getMaxInputCount() { + return 1; + } + + @Override + protected int getMaxOutputCount() { + return 1; + } + + @Override + protected int getMaxFluidOutputCount() { + return 1; + } + + public FluidStack getResultingFluid() { + if (fluidResults.isEmpty()) + throw new IllegalStateException("Emptying Recipe: " + id.toString() + " has no fluid output!"); + return fluidResults.get(0); + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencedGearshiftBlock.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencedGearshiftBlock.java index 8f6fc42a3..3341651f4 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencedGearshiftBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencedGearshiftBlock.java @@ -141,5 +141,15 @@ public class SequencedGearshiftBlock extends HorizontalAxisKineticBlock implemen public Class getTileEntityClass() { return SequencedGearshiftTileEntity.class; } + + @Override + public boolean hasComparatorInputOverride(BlockState p_149740_1_) { + return true; + } + + @Override + public int getComparatorInputOverride(BlockState state, World world, BlockPos pos) { + return state.get(STATE).intValue(); + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencedGearshiftScreen.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencedGearshiftScreen.java index 0932fe187..500240631 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencedGearshiftScreen.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencedGearshiftScreen.java @@ -3,11 +3,15 @@ package com.simibubi.create.content.contraptions.relays.advanced.sequencer; import com.simibubi.create.AllBlocks; import com.simibubi.create.foundation.gui.AbstractSimiScreen; import com.simibubi.create.foundation.gui.AllGuiTextures; +import com.simibubi.create.foundation.gui.AllIcons; import com.simibubi.create.foundation.gui.GuiGameElement; +import com.simibubi.create.foundation.gui.widgets.IconButton; import com.simibubi.create.foundation.gui.widgets.ScrollInput; import com.simibubi.create.foundation.gui.widgets.SelectionScrollInput; import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.utility.Lang; + +import net.minecraft.client.Minecraft; import net.minecraft.item.ItemStack; import net.minecraft.nbt.ListNBT; import net.minecraft.util.math.BlockPos; @@ -18,6 +22,7 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen { private final ItemStack renderedItem = AllBlocks.SEQUENCED_GEARSHIFT.asStack(); private final AllGuiTextures background = AllGuiTextures.SEQUENCER; + private IconButton confirmButton; private final String title = Lang.translate("gui.sequenced_gearshift.title"); private ListNBT compareTag; @@ -47,9 +52,9 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen { } public void initInputsOfRow(int row) { - int x = guiLeft + 28; - int y = guiTop + 29; - int rowHeight = 18; + int x = guiLeft + 30; + int y = guiTop + 18; + int rowHeight = 22; Vector rowInputs = inputs.get(row); rowInputs.forEach(widgets::remove); @@ -58,16 +63,16 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen { Instruction instruction = instructions.get(row); ScrollInput type = - new SelectionScrollInput(x, y + rowHeight * row, 50, 14).forOptions(SequencerInstructions.getOptions()) - .calling(state -> instructionUpdated(index, state)) - .setState(instruction.instruction.ordinal()) - .titled(Lang.translate("gui.sequenced_gearshift.instruction")); + new SelectionScrollInput(x, y + rowHeight * row, 50, 18).forOptions(SequencerInstructions.getOptions()) + .calling(state -> instructionUpdated(index, state)) + .setState(instruction.instruction.ordinal()) + .titled(Lang.translate("gui.sequenced_gearshift.instruction")); ScrollInput value = - new ScrollInput(x + 54, y + rowHeight * row, 30, 14).calling(state -> instruction.value = state); - ScrollInput direction = new SelectionScrollInput(x + 88, y + rowHeight * row, 18, 14) - .forOptions(InstructionSpeedModifiers.getOptions()) - .calling(state -> instruction.speedModifier = InstructionSpeedModifiers.values()[state]) - .titled(Lang.translate("gui.sequenced_gearshift.speed")); + new ScrollInput(x + 58, y + rowHeight * row, 28, 18).calling(state -> instruction.value = state); + ScrollInput direction = new SelectionScrollInput(x + 88, y + rowHeight * row, 28, 18) + .forOptions(InstructionSpeedModifiers.getOptions()) + .calling(state -> instruction.speedModifier = InstructionSpeedModifiers.values()[state]) + .titled(Lang.translate("gui.sequenced_gearshift.speed")); rowInputs.add(type); rowInputs.add(value); @@ -75,6 +80,10 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen { widgets.addAll(rowInputs); updateParamsOfRow(row); + + confirmButton = + new IconButton(guiLeft + background.width - 33, guiTop + background.height - 24, AllIcons.I_CONFIRM); + widgets.add(confirmButton); } public void updateParamsOfRow(int row) { @@ -88,10 +97,10 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen { value.active = value.visible = hasValue; if (hasValue) value.withRange(1, def.maxValue + 1) - .titled(Lang.translate(def.parameterKey)) - .withShiftStep(def.shiftStep) - .setState(instruction.value) - .onChanged(); + .titled(Lang.translate(def.parameterKey)) + .withShiftStep(def.shiftStep) + .setState(instruction.value) + .onChanged(); if (def == SequencerInstructions.WAIT) { value.withStepFunction(context -> { int v = context.currentValue; @@ -112,40 +121,37 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen { @Override protected void renderWindow(int mouseX, int mouseY, float partialTicks) { - int hFontColor = 0xD3CBBE; background.draw(this, guiLeft, guiTop); for (int row = 0; row < instructions.capacity(); row++) { AllGuiTextures toDraw = AllGuiTextures.SEQUENCER_EMPTY; int yOffset = toDraw.height * row; - if (row < instructions.size()) { - Instruction instruction = instructions.get(row); - SequencerInstructions def = instruction.instruction; - def.background.draw(guiLeft + 14, guiTop + 29 + yOffset); - - label(32, 6 + yOffset, Lang.translate(def.translationKey)); - if (def.hasValueParameter) { - String text = def.formatValue(instruction.value); - int stringWidth = font.getStringWidth(text); - label(85 + (12 - stringWidth / 2), 6 + yOffset, text); - } - if (def.hasSpeedParameter) - label(120, 6 + yOffset, instruction.speedModifier.label); - + if (row >= instructions.size()) { + toDraw.draw(guiLeft, guiTop + 14 + yOffset); continue; } - toDraw.draw(guiLeft + 14, guiTop + 29 + yOffset); + Instruction instruction = instructions.get(row); + SequencerInstructions def = instruction.instruction; + def.background.draw(guiLeft, guiTop + 14 + yOffset); + + label(36, yOffset - 3, Lang.translate(def.translationKey)); + if (def.hasValueParameter) { + String text = def.formatValue(instruction.value); + int stringWidth = font.getStringWidth(text); + label(90 + (12 - stringWidth / 2), yOffset - 3, text); + } + if (def.hasSpeedParameter) + label(127, yOffset - 3, instruction.speedModifier.label); } - font.drawStringWithShadow(title, guiLeft - 3 + (background.width - font.getStringWidth(title)) / 2, guiTop + 10, - hFontColor); + font.drawStringWithShadow(title, guiLeft - 3 + (background.width - font.getStringWidth(title)) / 2, guiTop + 3, 0xffffff); GuiGameElement.of(renderedItem) - .at(guiLeft + background.width + 20, guiTop + 50) - .scale(5) - .render(); + .at(guiLeft + background.width + 20, guiTop + 50) + .scale(5) + .render(); } private void label(int x, int y, String text) { @@ -184,4 +190,14 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen { } } + @Override + public boolean mouseClicked(double x, double y, int button) { + if (confirmButton.isHovered()) { + Minecraft.getInstance().player.closeScreen(); + return true; + } + + return super.mouseClicked(x, y, button); + } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencerInstructions.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencerInstructions.java index e4b397bc7..3bb06ba8e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencerInstructions.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/sequencer/SequencerInstructions.java @@ -9,7 +9,7 @@ import com.simibubi.create.foundation.utility.Lang; public enum SequencerInstructions { TURN_ANGLE("angle", AllGuiTextures.SEQUENCER_INSTRUCTION, true, true, 360, 45, 90), - TURN_DISTANCE("distance", AllGuiTextures.SEQUENCER_INSTRUCTION, true, true, 50, 5, 5), + TURN_DISTANCE("distance", AllGuiTextures.SEQUENCER_INSTRUCTION, true, true, 128, 5, 5), WAIT("duration", AllGuiTextures.SEQUENCER_WAIT, true, false, 600, 20, 10), END("", AllGuiTextures.SEQUENCER_END), diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java index c5c9cd256..8d4188d50 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java @@ -40,6 +40,11 @@ public class BeltRenderer extends SafeTileEntityRenderer { public BeltRenderer(TileEntityRendererDispatcher dispatcher) { super(dispatcher); } + + @Override + public boolean isGlobalRenderer(BeltTileEntity te) { + return BeltBlock.canTransportObjects(te.getBlockState()); + } @Override protected void renderSafe(BeltTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java index 2fb39ce91..bde2e2483 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java @@ -76,7 +76,7 @@ public class BeltTileEntity extends KineticTileEntity { casing = CasingType.NONE; color = -1; } - + @Override public void addBehaviours(List behaviours) { super.addBehaviours(behaviours); diff --git a/src/main/java/com/simibubi/create/content/curiosities/symmetry/SymmetryHandler.java b/src/main/java/com/simibubi/create/content/curiosities/symmetry/SymmetryHandler.java index f3efe5f37..76d66499a 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/symmetry/SymmetryHandler.java +++ b/src/main/java/com/simibubi/create/content/curiosities/symmetry/SymmetryHandler.java @@ -13,7 +13,6 @@ import net.minecraft.block.Blocks; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.player.ClientPlayerEntity; import net.minecraft.client.renderer.ActiveRenderInfo; -import net.minecraft.client.renderer.Atlases; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.model.IBakedModel; @@ -103,7 +102,7 @@ public class SymmetryHandler { double speed = 1 / 16d; yShift = MathHelper.sin((float) (AnimationTickHolder.getRenderTick() * speed)) / 5f; - IRenderTypeBuffer buffer = Minecraft.getInstance() + IRenderTypeBuffer.Impl buffer = Minecraft.getInstance() .getBufferBuilders() .getEntityVertexConsumers(); ActiveRenderInfo info = mc.gameRenderer.getActiveRenderInfo(); @@ -117,7 +116,7 @@ public class SymmetryHandler { mirror.applyModelTransform(ms); IBakedModel model = mirror.getModel() .get(); - IVertexBuilder builder = buffer.getBuffer(RenderType.getTranslucent()); + IVertexBuilder builder = buffer.getBuffer(RenderType.getSolid()); mc.getBlockRendererDispatcher() .getBlockModelRenderer() @@ -125,11 +124,7 @@ public class SymmetryHandler { player.world.getRandom(), MathHelper.getPositionRandom(pos), OverlayTexture.DEFAULT_UV, EmptyModelData.INSTANCE); - Minecraft.getInstance() - .getBufferBuilders() - .getEntityVertexConsumers() - .draw(Atlases.getEntityTranslucent()); - + buffer.draw(); ms.pop(); } } diff --git a/src/main/java/com/simibubi/create/content/curiosities/symmetry/SymmetryWandScreen.java b/src/main/java/com/simibubi/create/content/curiosities/symmetry/SymmetryWandScreen.java index cba957ade..cface0dc2 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/symmetry/SymmetryWandScreen.java +++ b/src/main/java/com/simibubi/create/content/curiosities/symmetry/SymmetryWandScreen.java @@ -2,16 +2,24 @@ package com.simibubi.create.content.curiosities.symmetry; import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.systems.RenderSystem; -import com.simibubi.create.content.curiosities.symmetry.mirror.*; +import com.simibubi.create.content.curiosities.symmetry.mirror.CrossPlaneMirror; +import com.simibubi.create.content.curiosities.symmetry.mirror.EmptyMirror; +import com.simibubi.create.content.curiosities.symmetry.mirror.PlaneMirror; +import com.simibubi.create.content.curiosities.symmetry.mirror.SymmetryMirror; +import com.simibubi.create.content.curiosities.symmetry.mirror.TriplePlaneMirror; import com.simibubi.create.foundation.gui.AbstractSimiScreen; import com.simibubi.create.foundation.gui.AllGuiTextures; +import com.simibubi.create.foundation.gui.AllIcons; import com.simibubi.create.foundation.gui.GuiGameElement; +import com.simibubi.create.foundation.gui.widgets.IconButton; import com.simibubi.create.foundation.gui.widgets.Label; import com.simibubi.create.foundation.gui.widgets.ScrollInput; import com.simibubi.create.foundation.gui.widgets.SelectionScrollInput; import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.networking.NbtPacket; import com.simibubi.create.foundation.utility.Lang; + +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.Vector3f; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; @@ -25,6 +33,7 @@ public class SymmetryWandScreen extends AbstractSimiScreen { private Label labelType; private ScrollInput areaAlign; private Label labelAlign; + private IconButton confirmButton; private final String mirrorType = Lang.translate("gui.symmetryWand.mirrorType"); private final String orientation = Lang.translate("gui.symmetryWand.orientation"); @@ -37,9 +46,9 @@ public class SymmetryWandScreen extends AbstractSimiScreen { super(); currentElement = SymmetryWandItem.getMirror(wand); - if (currentElement instanceof EmptyMirror) { + if (currentElement instanceof EmptyMirror) currentElement = new PlaneMirror(Vec3d.ZERO); - } + this.hand = hand; this.wand = wand; } @@ -47,16 +56,17 @@ public class SymmetryWandScreen extends AbstractSimiScreen { @Override public void init() { super.init(); - this.setWindowSize(AllGuiTextures.WAND_SYMMETRY.width + 50, AllGuiTextures.WAND_SYMMETRY.height + 50); + AllGuiTextures background = AllGuiTextures.WAND_OF_SYMMETRY; + this.setWindowSize(background.width + 50, background.height + 50); - labelType = new Label(guiLeft + 122, guiTop + 15, "").colored(0xFFFFFFFF) + labelType = new Label(guiLeft + 49, guiTop + 26, "").colored(0xFFFFFFFF) .withShadow(); - labelAlign = new Label(guiLeft + 122, guiTop + 35, "").colored(0xFFFFFFFF) + labelAlign = new Label(guiLeft + 49, guiTop + 48, "").colored(0xFFFFFFFF) .withShadow(); int state = currentElement instanceof TriplePlaneMirror ? 2 : currentElement instanceof CrossPlaneMirror ? 1 : 0; - areaType = new SelectionScrollInput(guiLeft + 119, guiTop + 12, 70, 14).forOptions(SymmetryMirror.getMirrors()) + areaType = new SelectionScrollInput(guiLeft + 45, guiTop + 21, 109, 18).forOptions(SymmetryMirror.getMirrors()) .titled(mirrorType) .writingTo(labelType) .setState(state); @@ -85,15 +95,17 @@ public class SymmetryWandScreen extends AbstractSimiScreen { widgets.add(labelAlign); widgets.add(areaType); widgets.add(labelType); + + confirmButton = new IconButton(guiLeft + background.width - 33, guiTop + background.height - 24, AllIcons.I_CONFIRM); + widgets.add(confirmButton); } private void initAlign(SymmetryMirror element) { - if (areaAlign != null) { + if (areaAlign != null) widgets.remove(areaAlign); - } - areaAlign = new SelectionScrollInput(guiLeft + 119, guiTop + 32, 70, 14).forOptions(element.getAlignToolTips()) + areaAlign = new SelectionScrollInput(guiLeft + 45, guiTop + 43, 109, 18).forOptions(element.getAlignToolTips()) .titled(orientation) .writingTo(labelAlign) .setState(element.getOrientationIndex()) @@ -104,30 +116,26 @@ public class SymmetryWandScreen extends AbstractSimiScreen { @Override protected void renderWindow(int mouseX, int mouseY, float partialTicks) { - AllGuiTextures.WAND_SYMMETRY.draw(this, guiLeft, guiTop); + AllGuiTextures.WAND_OF_SYMMETRY.draw(this, guiLeft, guiTop); - int x = guiLeft + 63; - int y = guiTop + 15; - - font.drawString(mirrorType, x - 5, y, AllGuiTextures.FONT_COLOR); - font.drawString(orientation, x - 5, y + 20, AllGuiTextures.FONT_COLOR); + font.drawStringWithShadow(wand.getDisplayName() + .getFormattedText(), guiLeft + 11, guiTop + 3, 0xffffff); renderBlock(); - GuiGameElement.of(wand) - .at(guiLeft + 200, guiTop + 170) - .scale(4) - .rotate(-70, 20, 20) - .render(); + .at(guiLeft + 170, guiTop + 200) + .scale(4) + .rotate(-70, 20, 20) + .render(); } protected void renderBlock() { RenderSystem.pushMatrix(); MatrixStack ms = new MatrixStack(); - ms.translate(guiLeft + 18, guiTop + 11, 20); + ms.translate(guiLeft + 25.5f, guiTop + 21, 20); ms.multiply(new Vector3f(.3f, 1f, 0f).getDegreesQuaternion(-22.5f)); - ms.scale(32, -32, 32); + ms.scale(16, -16, 16); currentElement.applyModelTransform(ms); RenderSystem.multMatrix(ms.peek() .getModel()); @@ -147,5 +155,15 @@ public class SymmetryWandScreen extends AbstractSimiScreen { minecraft.player.setHeldItem(hand, heldItem); super.removed(); } + + @Override + public boolean mouseClicked(double x, double y, int button) { + if (confirmButton.isHovered()) { + Minecraft.getInstance().player.closeScreen(); + return true; + } + + return super.mouseClicked(x, y, button); + } } diff --git a/src/main/java/com/simibubi/create/content/curiosities/zapper/ZapperScreen.java b/src/main/java/com/simibubi/create/content/curiosities/zapper/ZapperScreen.java index 2beb5a4e7..6354da3e4 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/zapper/ZapperScreen.java +++ b/src/main/java/com/simibubi/create/content/curiosities/zapper/ZapperScreen.java @@ -5,6 +5,7 @@ import java.util.Vector; import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.foundation.gui.AbstractSimiScreen; import com.simibubi.create.foundation.gui.AllGuiTextures; +import com.simibubi.create.foundation.gui.AllIcons; import com.simibubi.create.foundation.gui.GuiGameElement; import com.simibubi.create.foundation.gui.widgets.IconButton; import com.simibubi.create.foundation.networking.AllPackets; @@ -14,20 +15,19 @@ import com.simibubi.create.foundation.utility.Lang; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.texture.AtlasTexture; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.NBTUtil; import net.minecraft.util.Hand; -@SuppressWarnings("deprecation") public class ZapperScreen extends AbstractSimiScreen { protected ItemStack zapper; protected boolean offhand; protected float animationProgress; protected AllGuiTextures background; - + private IconButton confirmButton; + protected final String patternSection = Lang.translate("gui.blockzapper.patternSection"); protected String title; @@ -41,7 +41,7 @@ public class ZapperScreen extends AbstractSimiScreen { this.zapper = zapper; this.offhand = offhand; title = ""; - brightColor = 0xCCDDFF; + brightColor = 0xfefefe; fontColor = AllGuiTextures.FONT_COLOR; } @@ -51,6 +51,9 @@ public class ZapperScreen extends AbstractSimiScreen { setWindowSize(background.width + 40, background.height); super.init(); widgets.clear(); + + confirmButton = new IconButton(guiLeft + background.width - 53, guiTop + background.height - 24, AllIcons.I_CONFIRM); + widgets.add(confirmButton); int i = guiLeft - 20; int j = guiTop; @@ -61,7 +64,7 @@ public class ZapperScreen extends AbstractSimiScreen { for (int col = 0; col <= 2; col++) { int id = patternButtons.size(); PlacementPatterns pattern = PlacementPatterns.values()[id]; - patternButtons.add(new IconButton(i + 147 + col * 18, j + 23 + row * 18, pattern.icon)); + patternButtons.add(new IconButton(i + background.width - 76 + col * 18, j + 19 + row * 18, pattern.icon)); patternButtons.get(id) .setToolTip(Lang.translate("gui.blockzapper.pattern." + pattern.translationKey)); } @@ -82,17 +85,12 @@ public class ZapperScreen extends AbstractSimiScreen { background.draw(this, i, j); drawOnBackground(i, j); - minecraft.getTextureManager() - .bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE); - RenderSystem.enableBlend(); - renderBlock(); renderZapper(); } protected void drawOnBackground(int i, int j) { - font.drawStringWithShadow(title, i + 8, j + 10, brightColor); - font.drawString(patternSection, i + 148, j + 11, fontColor); + font.drawStringWithShadow(title, i + 11, j + 3, brightColor); } @Override @@ -122,20 +120,25 @@ public class ZapperScreen extends AbstractSimiScreen { nbt.putString("Pattern", PlacementPatterns.values()[patternButtons.indexOf(patternButton)].name()); } } + + if (confirmButton.isHovered()) { + Minecraft.getInstance().player.closeScreen(); + return true; + } return super.mouseClicked(x, y, button); } protected void renderZapper() { GuiGameElement.of(zapper) - .at((this.width - this.sWidth) / 2 + 210, this.height / 2 - this.sHeight / 4) + .at((this.width - this.sWidth) / 2 + 220, this.height / 2 - this.sHeight / 4 + 30) .scale(4) .render(); } protected void renderBlock() { RenderSystem.pushMatrix(); - RenderSystem.translated(guiLeft + 1.7f, guiTop + 48, 120); + RenderSystem.translated(guiLeft + 7f, guiTop + 43.5f, 120); RenderSystem.rotatef(-30f, .5f, .9f, -.1f); RenderSystem.scaled(20, 20, 20); diff --git a/src/main/java/com/simibubi/create/content/curiosities/zapper/blockzapper/BlockzapperScreen.java b/src/main/java/com/simibubi/create/content/curiosities/zapper/blockzapper/BlockzapperScreen.java index d0e5794f9..ad92257d2 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/zapper/blockzapper/BlockzapperScreen.java +++ b/src/main/java/com/simibubi/create/content/curiosities/zapper/blockzapper/BlockzapperScreen.java @@ -43,26 +43,26 @@ public class BlockzapperScreen extends ZapperScreen { int j = guiTop; CompoundNBT nbt = zapper.getOrCreateTag(); - replaceModeIndicator = new Indicator(i + 51, j + 36, ""); - replaceModeButton = new IconButton(i + 51, j + 41, AllIcons.I_REPLACE_SOLID); + replaceModeIndicator = new Indicator(i + 49, j + 67, ""); + replaceModeButton = new IconButton(i + 49, j + 73, AllIcons.I_REPLACE_SOLID); if (nbt.contains("Replace") && nbt.getBoolean("Replace")) replaceModeIndicator.state = State.ON; replaceModeButton.setToolTip(Lang.translate("gui.blockzapper.replaceMode")); - spreadDiagonallyIndicator = new Indicator(i + 74, j + 36, ""); - spreadDiagonallyButton = new IconButton(i + 74, j + 41, AllIcons.I_FOLLOW_DIAGONAL); + spreadDiagonallyIndicator = new Indicator(i + 8, j + 67, ""); + spreadDiagonallyButton = new IconButton(i + 8, j + 73, AllIcons.I_FOLLOW_DIAGONAL); if (nbt.contains("SearchDiagonal") && nbt.getBoolean("SearchDiagonal")) spreadDiagonallyIndicator.state = State.ON; spreadDiagonallyButton.setToolTip(Lang.translate("gui.blockzapper.searchDiagonal")); - spreadMaterialIndicator = new Indicator(i + 92, j + 36, ""); - spreadMaterialButton = new IconButton(i + 92, j + 41, AllIcons.I_FOLLOW_MATERIAL); + spreadMaterialIndicator = new Indicator(i + 26, j + 67, ""); + spreadMaterialButton = new IconButton(i + 26, j + 73, AllIcons.I_FOLLOW_MATERIAL); if (nbt.contains("SearchFuzzy") && nbt.getBoolean("SearchFuzzy")) spreadMaterialIndicator.state = State.ON; spreadMaterialButton.setToolTip(Lang.translate("gui.blockzapper.searchFuzzy")); - spreadRangeLabel = new Label(i + 119, j + 46, "").withShadow().withSuffix("m"); - spreadRangeInput = new ScrollInput(i + 115, j + 43, 22, 14).withRange(1, BlockzapperItem.getMaxAoe(zapper)) + spreadRangeLabel = new Label(i + 79, j + 78, "").withShadow().withSuffix("m"); + spreadRangeInput = new ScrollInput(i + 73, j + 73, 26, 18).withRange(1, BlockzapperItem.getMaxAoe(zapper)) .setState(1).titled(Lang.translate("gui.blockzapper.range")).writingTo(spreadRangeLabel); if (nbt.contains("SearchDistance")) diff --git a/src/main/java/com/simibubi/create/content/curiosities/zapper/terrainzapper/WorldshaperScreen.java b/src/main/java/com/simibubi/create/content/curiosities/zapper/terrainzapper/WorldshaperScreen.java index f9d6ec474..0e6b7bca4 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/zapper/terrainzapper/WorldshaperScreen.java +++ b/src/main/java/com/simibubi/create/content/curiosities/zapper/terrainzapper/WorldshaperScreen.java @@ -38,8 +38,7 @@ public class WorldshaperScreen extends ZapperScreen { public WorldshaperScreen(ItemStack zapper, boolean offhand) { super(AllGuiTextures.TERRAINZAPPER, zapper, offhand); - brightColor = 0xDFF6FF; - fontColor = 0x436B77; + fontColor = 0x767676; title = Lang.translate("gui.terrainzapper.title"); nbt = zapper.getOrCreateTag(); } @@ -51,8 +50,8 @@ public class WorldshaperScreen extends ZapperScreen { i = guiLeft - 20; j = guiTop; - brushLabel = new Label(i + 58, j + 28, "").withShadow(); - brushInput = new SelectionScrollInput(i + 55, j + 25, 78, 14).forOptions(brushOptions) + brushLabel = new Label(i + 61, j + 23, "").withShadow(); + brushInput = new SelectionScrollInput(i + 56, j + 18, 77, 18).forOptions(brushOptions) .titled(Lang.translate("gui.terrainzapper.brush")) .writingTo(brushLabel) .calling(this::brushChanged); @@ -68,7 +67,7 @@ public class WorldshaperScreen extends ZapperScreen { TerrainTools[] toolValues = TerrainTools.values(); for (int id = 0; id < toolValues.length; id++) { TerrainTools tool = toolValues[id]; - toolButtons.add(new IconButton(i + 8 + id * 18, j + 76, tool.icon)); + toolButtons.add(new IconButton(i + 7 + id * 18, j + 77, tool.icon)); toolButtons.get(id) .setToolTip(Lang.translate("gui.terrainzapper.tool." + tool.translationKey)); } @@ -82,7 +81,7 @@ public class WorldshaperScreen extends ZapperScreen { PlacementOptions[] placementValues = PlacementOptions.values(); for (int id = 0; id < placementValues.length; id++) { PlacementOptions option = placementValues[id]; - placementButtons.add(new IconButton(i + 147 + id * 18, j + 76, option.icon)); + placementButtons.add(new IconButton(i + 136 + id * 18, j + 77, option.icon)); placementButtons.get(id) .setToolTip(Lang.translate("gui.terrainzapper.placement." + option.translationKey)); } @@ -114,15 +113,15 @@ public class WorldshaperScreen extends ZapperScreen { Brush currentBrush = TerrainBrushes.values()[brushInput.getState()].get(); for (int index = 0; index < 3; index++) { - Label label = new Label(i + 62 + 18 * index, j + 46, "").withShadow(); + Label label = new Label(i + 65 + 20 * index, j + 43, "").withShadow(); brushParamLabels.add(label); int indexFinal = index; - ScrollInput input = new ScrollInput(i + 55 + 18 * index, j + 43, 14, 14) + ScrollInput input = new ScrollInput(i + 56 + 20 * index, j + 38, 18, 18) .withRange(currentBrush.getMin(index), currentBrush.getMax(index) + 1) .writingTo(label) .titled(currentBrush.getParamLabel(index)) .calling(state -> { - label.x = i + 62 + 18 * indexFinal - font.getStringWidth(label.text) / 2; + label.x = i + 65 + 20 * indexFinal - font.getStringWidth(label.text) / 2; }); input.setState(params[index]); input.onChanged(); @@ -175,12 +174,11 @@ public class WorldshaperScreen extends ZapperScreen { super.drawOnBackground(i, j); Brush currentBrush = TerrainBrushes.values()[brushInput.getState()].get(); - for (int index = 2; index >= currentBrush.amtParams; index--) { - AllGuiTextures.TERRAINZAPPER_INACTIVE_PARAM.draw(i + 55 + index * 18, j + 43); - } + for (int index = 2; index >= currentBrush.amtParams; index--) + AllGuiTextures.TERRAINZAPPER_INACTIVE_PARAM.draw(i + 56 + 20 * index, j + 38); - font.drawString(toolSection, i + 8, j + 64, fontColor); - font.drawString(placementSection, i + 148, j + 64, fontColor); + font.drawString(toolSection, i + 7, j + 66, fontColor); + font.drawString(placementSection, i + 136, j + 66, fontColor); } @Override diff --git a/src/main/java/com/simibubi/create/content/logistics/InWorldProcessing.java b/src/main/java/com/simibubi/create/content/logistics/InWorldProcessing.java index ca60ccfd3..97aea25f9 100644 --- a/src/main/java/com/simibubi/create/content/logistics/InWorldProcessing.java +++ b/src/main/java/com/simibubi/create/content/logistics/InWorldProcessing.java @@ -120,8 +120,7 @@ public class InWorldProcessing { public static boolean isWashable(ItemStack stack, World world) { splashingInv.setInventorySlotContents(0, stack); - Optional recipe = world.getRecipeManager() - .getRecipe(AllRecipeTypes.SPLASHING.getType(), splashingInv, world); + Optional recipe = AllRecipeTypes.SPLASHING.find(splashingInv, world); return recipe.isPresent(); } @@ -176,8 +175,7 @@ public class InWorldProcessing { private static List process(ItemStack stack, Type type, World world) { if (type == Type.SPLASHING) { splashingInv.setInventorySlotContents(0, stack); - Optional recipe = world.getRecipeManager() - .getRecipe(AllRecipeTypes.SPLASHING.getType(), splashingInv, world); + Optional recipe = AllRecipeTypes.SPLASHING.find(splashingInv, world); if (recipe.isPresent()) return applyRecipeOn(stack, recipe.get()); return null; diff --git a/src/main/java/com/simibubi/create/content/logistics/block/inventories/AdjustableCrateContainer.java b/src/main/java/com/simibubi/create/content/logistics/block/inventories/AdjustableCrateContainer.java index 68c13d22a..d67062c1f 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/inventories/AdjustableCrateContainer.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/inventories/AdjustableCrateContainer.java @@ -40,17 +40,17 @@ public class AdjustableCrateContainer extends Container { private void init() { doubleCrate = te.isDoubleCrate(); - int x = doubleCrate ? 52 : 124; + int x = doubleCrate ? 51 : 123; int maxCol = doubleCrate ? 8 : 4; for (int row = 0; row < 4; ++row) { for (int col = 0; col < maxCol; ++col) { - this.addSlot(new SlotItemHandler(te.inventory, col + row * maxCol, x + col * 18, 25 + row * 18)); + this.addSlot(new SlotItemHandler(te.inventory, col + row * maxCol, x + col * 18, 20 + row * 18)); } } // player Slots int xOffset = 58; - int yOffset = 157; + int yOffset = 155; for (int row = 0; row < 3; ++row) { for (int col = 0; col < 9; ++col) { this.addSlot(new Slot(playerInventory, col + row * 9 + 9, xOffset + col * 18, yOffset + row * 18)); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/inventories/AdjustableCrateScreen.java b/src/main/java/com/simibubi/create/content/logistics/block/inventories/AdjustableCrateScreen.java index 2a58b5e08..6a312a59c 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/inventories/AdjustableCrateScreen.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/inventories/AdjustableCrateScreen.java @@ -1,7 +1,7 @@ package com.simibubi.create.content.logistics.block.inventories; -import static com.simibubi.create.foundation.gui.AllGuiTextures.FLEXCRATE; -import static com.simibubi.create.foundation.gui.AllGuiTextures.FLEXCRATE_DOUBLE; +import static com.simibubi.create.foundation.gui.AllGuiTextures.ADJUSTABLE_CRATE; +import static com.simibubi.create.foundation.gui.AllGuiTextures.ADJUSTABLE_DOUBLE_CRATE; import static com.simibubi.create.foundation.gui.AllGuiTextures.PLAYER_INVENTORY; import java.util.ArrayList; @@ -43,11 +43,11 @@ public class AdjustableCrateScreen extends AbstractSimiContainerScreen(); - extraAreas.add(new Rectangle2d(guiLeft + FLEXCRATE.width + 110, guiTop + 46, 71, 70)); + extraAreas.add(new Rectangle2d(guiLeft + ADJUSTABLE_CRATE.width + 110, guiTop + 46, 71, 70)); } @Override @@ -68,18 +68,17 @@ public class AdjustableCrateScreen extends AbstractSimiContainerScreen slot * 64) continue; int slotsPerRow = (container.doubleCrate ? 8 : 4); - int x = crateLeft + 23 + (slot % slotsPerRow) * 18; - int y = crateTop + 24 + (slot / slotsPerRow) * 18; - AllGuiTextures.FLEXCRATE_LOCKED_SLOT.draw(this, x, y); + int x = crateLeft + 22 + (slot % slotsPerRow) * 18; + int y = crateTop + 19 + (slot / slotsPerRow) * 18; + AllGuiTextures.ADJUSTABLE_CRATE_LOCKED_SLOT.draw(this, x, y); } GuiGameElement.of(renderedItem) - .at(guiLeft + FLEXCRATE.width + 110, guiTop + 40) + .at(guiLeft + ADJUSTABLE_CRATE.width + 110, guiTop + 40) .scale(5) .render(); } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/redstone/StockpileSwitchBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/redstone/StockpileSwitchBlock.java index 1dff71e17..a701a2b07 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/redstone/StockpileSwitchBlock.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/redstone/StockpileSwitchBlock.java @@ -80,7 +80,7 @@ public class StockpileSwitchBlock extends HorizontalBlock implements ITE { - offBelowLabel.text = state + "%"; - lastModification = 0; - if (onAbove.getState() - 4 <= state) { - onAbove.setState(state + 5); - onAbove.onChanged(); - } - }) - .setState((int) (te.offWhenBelow * 100)); + cursor = LerpedFloat.linear() + .startWithValue(te.getLevelForDisplay()); + cursorLane = LerpedFloat.linear() + .startWithValue(te.getState() ? 1 : 0); - onAboveLabel = new Label(guiLeft + 116, guiTop + 55, "").colored(0xD3CBBE) - .withShadow(); - onAbove = new ScrollInput(guiLeft + 113, guiTop + 52, 33, 14).withRange(5, 101) - .titled(upperLimit) - .calling(state -> { - onAboveLabel.text = state + "%"; - lastModification = 0; - if (offBelow.getState() + 4 >= state) { - offBelow.setState(state - 5); - offBelow.onChanged(); - } - }) - .setState((int) (te.onWhenAbove * 100)); + offBelow = new ScrollInput(guiLeft + 36, guiTop + 40, 102, 18).withRange(0, 100) + .titled("") + .calling(state -> { + lastModification = 0; + offBelow.titled(Lang.translate("gui.stockpile_switch.move_to_upper_at", state)); + if (onAbove.getState() <= state) { + onAbove.setState(state + 1); + onAbove.onChanged(); + } + }) + .setState((int) (te.offWhenBelow * 100)); + + onAbove = new ScrollInput(guiLeft + 36, guiTop + 18, 102, 18).withRange(1, 101) + .titled("") + .calling(state -> { + lastModification = 0; + onAbove.titled(Lang.translate("gui.stockpile_switch.move_to_lower_at", state)); + if (offBelow.getState() >= state) { + offBelow.setState(state - 1); + offBelow.onChanged(); + } + }) + .setState((int) (te.onWhenAbove * 100)); onAbove.onChanged(); offBelow.onChanged(); - widgets.addAll(Arrays.asList(offBelowLabel, offBelow, onAbove, onAboveLabel)); + + widgets.add(onAbove); + widgets.add(offBelow); + + confirmButton = + new IconButton(guiLeft + background.width - 33, guiTop + background.height - 24, AllIcons.I_CONFIRM); + widgets.add(confirmButton); + + flipSignals = new IconButton(guiLeft + 14, guiTop + 40, AllIcons.I_FLIP); + flipSignals.setToolTip(invertSignal); + widgets.add(flipSignals); } @Override protected void renderWindow(int mouseX, int mouseY, float partialTicks) { - int hFontColor = 0xD3CBBE; - int fontColor = 0x4B3A22; STOCKSWITCH.draw(this, guiLeft, guiTop); - font.drawStringWithShadow(title, guiLeft - 3 + (STOCKSWITCH.width - font.getStringWidth(title)) / 2, - guiTop + 10, hFontColor); - font.drawString(onAbove.getState() == 100 ? startAt : startAbove, guiLeft + 13, guiTop + 55, fontColor); - font.drawString(offBelow.getState() == 0 ? stopAt : stopBelow, guiLeft + 13, guiTop + 72, fontColor); + + AllGuiTextures.STOCKSWITCH_POWERED_LANE.draw(this, guiLeft + 36, guiTop + (te.isInverted() ? 18 : 40)); + AllGuiTextures.STOCKSWITCH_UNPOWERED_LANE.draw(this, guiLeft + 36, guiTop + (te.isInverted() ? 40 : 18)); + + font.drawStringWithShadow(title, guiLeft - 3 + (STOCKSWITCH.width - font.getStringWidth(title)) / 2, guiTop + 3, + 0xffffff); AllGuiTextures sprite = AllGuiTextures.STOCKSWITCH_INTERVAL; - float lowerBound = offBelow.getState() / 100f * (sprite.width - 20) + 10; - float upperBound = onAbove.getState() / 100f * (sprite.width - 20) + 10; + float lowerBound = offBelow.getState(); + float upperBound = onAbove.getState(); sprite.bind(); - blit((int) (guiLeft + lowerBound), guiTop + 26, (int) (sprite.startX + lowerBound), sprite.startY, - (int) (upperBound - lowerBound), sprite.height); + blit((int) (guiLeft + upperBound) + 37, guiTop + 18, (int) (sprite.startX + upperBound), sprite.startY, + (int) (sprite.width - upperBound), sprite.height); + blit(guiLeft + 37, guiTop + 40, sprite.startX, sprite.startY, (int) (lowerBound), sprite.height); - sprite = AllGuiTextures.STOCKSWITCH_INTERVAL_END; - sprite.bind(); - blit((int) (guiLeft + upperBound), guiTop + 26, (int) (sprite.startX + upperBound), sprite.startY, - (int) (sprite.width - upperBound), sprite.height); + AllGuiTextures.STOCKSWITCH_ARROW_UP.draw(this, (int) (guiLeft + lowerBound + 36) - 2, guiTop + 35); + AllGuiTextures.STOCKSWITCH_ARROW_DOWN.draw(this, (int) (guiLeft + upperBound + 36) - 3, guiTop + 17); - AllGuiTextures.STOCKSWITCH_BOUND_LEFT.draw(this, (int) (guiLeft + lowerBound) - 1, guiTop + 24); - AllGuiTextures.STOCKSWITCH_BOUND_RIGHT.draw(this, (int) (guiLeft + upperBound) - 5, guiTop + 24); - - AllGuiTextures cursor = - te.powered ? AllGuiTextures.STOCKSWITCH_CURSOR_ON : AllGuiTextures.STOCKSWITCH_CURSOR_OFF; - RenderSystem.pushMatrix(); - RenderSystem.translatef((cursorPos * (sprite.width - 20) + 10), 0, 0); - cursor.draw(this, guiLeft - 4, guiTop + 24); - RenderSystem.popMatrix(); + if (te.currentLevel != -1) { + AllGuiTextures cursor = AllGuiTextures.STOCKSWITCH_CURSOR; + RenderSystem.pushMatrix(); + RenderSystem.translatef(Math.min(99, this.cursor.getValue(partialTicks) * sprite.width), + cursorLane.getValue(partialTicks) * 22, 0); + cursor.draw(this, guiLeft + 34, guiTop + 19); + RenderSystem.popMatrix(); + } RenderSystem.pushMatrix(); GuiGameElement.of(renderedItem) - .at(guiLeft + STOCKSWITCH.width + 15, guiTop + 20) - .scale(5) - .render(); + .at(guiLeft + STOCKSWITCH.width + 15, guiTop + 20) + .scale(5) + .render(); RenderSystem.popMatrix(); } @@ -127,25 +135,39 @@ public class StockpileSwitchScreen extends AbstractSimiScreen { public void tick() { super.tick(); - if (te.currentLevel == -1) - cursorPos = 0; - else - cursorPos += (te.currentLevel - cursorPos) / 4; + cursor.chase(te.getLevelForDisplay(), 1 / 4f, Chaser.EXP); + cursor.tickChaser(); + cursorLane.chase(te.getState() ? 1 : 0, 1 / 4f, Chaser.EXP); + cursorLane.tickChaser(); if (lastModification >= 0) lastModification++; if (lastModification >= 20) { lastModification = -1; - AllPackets.channel.sendToServer( - new ConfigureStockswitchPacket(te.getPos(), offBelow.getState() / 100f, onAbove.getState() / 100f)); + send(te.isInverted()); } } @Override public void removed() { - AllPackets.channel.sendToServer( - new ConfigureStockswitchPacket(te.getPos(), offBelow.getState() / 100f, onAbove.getState() / 100f)); + send(te.isInverted()); + } + + protected void send(boolean invert) { + AllPackets.channel.sendToServer(new ConfigureStockswitchPacket(te.getPos(), offBelow.getState() / 100f, + onAbove.getState() / 100f, invert)); + } + + @Override + public boolean mouseClicked(double x, double y, int button) { + if (flipSignals.isHovered()) + send(!te.isInverted()); + if (confirmButton.isHovered()) { + Minecraft.getInstance().player.closeScreen(); + return true; + } + return super.mouseClicked(x, y, button); } } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/redstone/StockpileSwitchTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/redstone/StockpileSwitchTileEntity.java index 863070eb1..4f44d92d8 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/redstone/StockpileSwitchTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/redstone/StockpileSwitchTileEntity.java @@ -20,7 +20,8 @@ public class StockpileSwitchTileEntity extends SmartTileEntity { public float onWhenAbove; public float offWhenBelow; public float currentLevel; - public boolean powered; + private boolean state; + private boolean inverted; private FilteringBehaviour filtering; private InvManipulationBehaviour observedInventory; @@ -30,7 +31,8 @@ public class StockpileSwitchTileEntity extends SmartTileEntity { onWhenAbove = .75f; offWhenBelow = .25f; currentLevel = -1; - powered = false; + state = false; + inverted = false; setLazyTickRate(10); } @@ -39,7 +41,8 @@ public class StockpileSwitchTileEntity extends SmartTileEntity { onWhenAbove = compound.getFloat("OnAbove"); offWhenBelow = compound.getFloat("OffBelow"); currentLevel = compound.getFloat("Current"); - powered = compound.getBoolean("Powered"); + state = compound.getBoolean("Powered"); + inverted = compound.getBoolean("Inverted"); super.read(compound, clientPacket); } @@ -48,7 +51,8 @@ public class StockpileSwitchTileEntity extends SmartTileEntity { compound.putFloat("OnAbove", onWhenAbove); compound.putFloat("OffBelow", offWhenBelow); compound.putFloat("Current", currentLevel); - compound.putBoolean("Powered", powered); + compound.putBoolean("Powered", state); + compound.putBoolean("Inverted", inverted); super.write(compound, clientPacket); } @@ -57,13 +61,15 @@ public class StockpileSwitchTileEntity extends SmartTileEntity { } public void updateCurrentLevel() { + boolean changed = false; if (!observedInventory.hasInventory()) { if (currentLevel == -1) return; world.setBlockState(pos, getBlockState().with(StockpileSwitchBlock.INDICATOR, 0), 3); currentLevel = -1; - powered = false; + state = false; world.notifyNeighbors(pos, getBlockState().getBlock()); + sendData(); return; } @@ -85,15 +91,18 @@ public class StockpileSwitchTileEntity extends SmartTileEntity { occupied += count * (1f / space); } - currentLevel = (float) occupied / totalSpace; + float level = (float) occupied / totalSpace; + if (currentLevel != level) + changed = true; + currentLevel = level; currentLevel = MathHelper.clamp(currentLevel, 0, 1); - boolean previouslyPowered = powered; - if (powered && currentLevel <= offWhenBelow) - powered = false; - else if (!powered && currentLevel >= onWhenAbove) - powered = true; - boolean update = previouslyPowered != powered; + boolean previouslyPowered = state; + if (state && currentLevel <= offWhenBelow) + state = false; + else if (!state && currentLevel >= onWhenAbove) + state = true; + boolean update = previouslyPowered != state; int displayLevel = 0; if (currentLevel > 0) @@ -101,6 +110,8 @@ public class StockpileSwitchTileEntity extends SmartTileEntity { world.setBlockState(pos, getBlockState().with(StockpileSwitchBlock.INDICATOR, displayLevel), update ? 3 : 2); if (update) world.notifyNeighbors(pos, getBlockState().getBlock()); + if (changed || update) + sendData(); } @Override @@ -120,4 +131,27 @@ public class StockpileSwitchTileEntity extends SmartTileEntity { observedInventory = new InvManipulationBehaviour(this, InterfaceProvider.towardBlockFacing()).bypassSidedness(); behaviours.add(observedInventory); } + + public float getLevelForDisplay() { + return currentLevel == -1 ? 0 : currentLevel; + } + + public boolean getState() { + return state; + } + + public boolean isPowered() { + return inverted != state; + } + + public boolean isInverted() { + return inverted; + } + + public void setInverted(boolean inverted) { + if (inverted == this.inverted) + return; + this.inverted = inverted; + world.notifyNeighbors(pos, getBlockState().getBlock()); + } } diff --git a/src/main/java/com/simibubi/create/content/logistics/item/filter/AbstractFilterScreen.java b/src/main/java/com/simibubi/create/content/logistics/item/filter/AbstractFilterScreen.java index 73e532dc4..ae138ce3d 100644 --- a/src/main/java/com/simibubi/create/content/logistics/item/filter/AbstractFilterScreen.java +++ b/src/main/java/com/simibubi/create/content/logistics/item/filter/AbstractFilterScreen.java @@ -41,8 +41,8 @@ public abstract class AbstractFilterScreen ex super.init(); widgets.clear(); - resetButton = new IconButton(guiLeft + 15, guiTop + background.height - 30, AllIcons.I_TRASH); - confirmButton = new IconButton(guiLeft + 159, guiTop + background.height - 30, AllIcons.I_CONFIRM); + resetButton = new IconButton(guiLeft + background.width - 62, guiTop + background.height - 24, AllIcons.I_TRASH); + confirmButton = new IconButton(guiLeft + background.width - 33, guiTop + background.height - 24, AllIcons.I_CONFIRM); widgets.add(resetButton); widgets.add(confirmButton); @@ -59,14 +59,7 @@ public abstract class AbstractFilterScreen ex PLAYER_INVENTORY.draw(this, invX, invY); font.drawString(playerInventory.getDisplayName().getFormattedText(), invX + 7, invY + 6, 0x666666); - font.drawString(I18n.format(container.filterItem.getTranslationKey()), x + 15, y + 9, 0x5B5037); - - /*RenderHelper.enableGuiDepthLighting(); - RenderSystem.pushMatrix(); - RenderSystem.translated(guiLeft + background.width + 0, guiTop + background.height - 60, 0); - RenderSystem.scaled(5, 5, 5); - itemRenderer.renderItemIntoGUI(container.filterItem, 0, 0); - RenderSystem.popMatrix();*/ + font.drawStringWithShadow(I18n.format(container.filterItem.getTranslationKey()), x + 15, y + 3, 0xdedede); GuiGameElement.of(container.filterItem) .at(guiLeft + background.width, guiTop +background.height -60) diff --git a/src/main/java/com/simibubi/create/content/logistics/item/filter/AttributeFilterContainer.java b/src/main/java/com/simibubi/create/content/logistics/item/filter/AttributeFilterContainer.java index 45595fd97..54e945ca9 100644 --- a/src/main/java/com/simibubi/create/content/logistics/item/filter/AttributeFilterContainer.java +++ b/src/main/java/com/simibubi/create/content/logistics/item/filter/AttributeFilterContainer.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.List; import com.simibubi.create.AllContainerTypes; +import com.simibubi.create.foundation.utility.Pair; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; @@ -27,7 +28,7 @@ public class AttributeFilterContainer extends AbstractFilterContainer { } WhitelistMode whitelistMode; - List selectedAttributes; + List> selectedAttributes; public AttributeFilterContainer(int id, PlayerInventory inv, PacketBuffer extraData) { super(AllContainerTypes.ATTRIBUTE_FILTER.type, id, inv, extraData); @@ -37,21 +38,21 @@ public class AttributeFilterContainer extends AbstractFilterContainer { super(AllContainerTypes.ATTRIBUTE_FILTER.type, id, inv, stack); } - public void appendSelectedAttribute(ItemAttribute itemAttribute) { - selectedAttributes.add(itemAttribute); + public void appendSelectedAttribute(ItemAttribute itemAttribute, boolean inverted) { + selectedAttributes.add(Pair.of(itemAttribute, inverted)); } @Override protected void clearContents() { selectedAttributes.clear(); } - + @Override protected void init() { super.init(); ItemStack stack = new ItemStack(Items.NAME_TAG); stack.setDisplayName( - new StringTextComponent("Selected Tags").applyTextStyles(TextFormatting.RESET, TextFormatting.BLUE)); + new StringTextComponent("Selected Tags").applyTextStyles(TextFormatting.RESET, TextFormatting.BLUE)); filterInventory.setStackInSlot(1, stack); } @@ -61,8 +62,8 @@ public class AttributeFilterContainer extends AbstractFilterContainer { } protected void addFilterSlots() { - this.addSlot(new SlotItemHandler(filterInventory, 0, 16, 23)); - this.addSlot(new SlotItemHandler(filterInventory, 1, 59, 56) { + this.addSlot(new SlotItemHandler(filterInventory, 0, 16, 22)); + this.addSlot(new SlotItemHandler(filterInventory, 1, 22, 57) { @Override public boolean canTakeStack(PlayerEntity playerIn) { return false; @@ -110,29 +111,37 @@ public class AttributeFilterContainer extends AbstractFilterContainer { @Override protected int getInventoryOffset() { - return 86; + return 83; } @Override protected void readData(ItemStack filterItem) { selectedAttributes = new ArrayList<>(); - whitelistMode = WhitelistMode.values()[filterItem.getOrCreateTag().getInt("WhitelistMode")]; - ListNBT attributes = filterItem.getOrCreateTag().getList("MatchedAttributes", NBT.TAG_COMPOUND); - attributes.forEach(inbt -> selectedAttributes.add(ItemAttribute.fromNBT((CompoundNBT) inbt))); + whitelistMode = WhitelistMode.values()[filterItem.getOrCreateTag() + .getInt("WhitelistMode")]; + ListNBT attributes = filterItem.getOrCreateTag() + .getList("MatchedAttributes", NBT.TAG_COMPOUND); + attributes.forEach(inbt -> { + CompoundNBT compound = (CompoundNBT) inbt; + selectedAttributes.add(Pair.of(ItemAttribute.fromNBT(compound), compound.getBoolean("Inverted"))); + }); } @Override protected void saveData(ItemStack filterItem) { - filterItem.getOrCreateTag().putInt("WhitelistMode", whitelistMode.ordinal()); + filterItem.getOrCreateTag() + .putInt("WhitelistMode", whitelistMode.ordinal()); ListNBT attributes = new ListNBT(); selectedAttributes.forEach(at -> { if (at == null) return; CompoundNBT compoundNBT = new CompoundNBT(); - at.serializeNBT(compoundNBT); + at.getFirst().serializeNBT(compoundNBT); + compoundNBT.putBoolean("Inverted", at.getSecond()); attributes.add(compoundNBT); }); - filterItem.getOrCreateTag().put("MatchedAttributes", attributes); + filterItem.getOrCreateTag() + .put("MatchedAttributes", attributes); } } diff --git a/src/main/java/com/simibubi/create/content/logistics/item/filter/AttributeFilterScreen.java b/src/main/java/com/simibubi/create/content/logistics/item/filter/AttributeFilterScreen.java index d31e29cf9..aec61f789 100644 --- a/src/main/java/com/simibubi/create/content/logistics/item/filter/AttributeFilterScreen.java +++ b/src/main/java/com/simibubi/create/content/logistics/item/filter/AttributeFilterScreen.java @@ -16,6 +16,7 @@ import com.simibubi.create.foundation.gui.widgets.Label; import com.simibubi.create.foundation.gui.widgets.SelectionScrollInput; import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.foundation.utility.Pair; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.item.ItemStack; @@ -30,6 +31,10 @@ public class AttributeFilterScreen extends AbstractFilterScreen { - }); + attributeSelector.removeCallback(); referenceItemChanged(container.filterInventory.getStackInSlot(0)); widgets.add(attributeSelector); @@ -88,8 +96,9 @@ public class AttributeFilterScreen extends AbstractFilterScreen selectedAttributes.add(TextFormatting.GRAY + "- " + at.format())); + .add(TextFormatting.YELLOW + (container.selectedAttributes.isEmpty() ? noSelectedT : selectedT)); + container.selectedAttributes.forEach(at -> selectedAttributes.add(TextFormatting.GRAY + "- " + at.getFirst() + .format(at.getSecond()))); } @@ -101,17 +110,22 @@ public class AttributeFilterScreen extends AbstractFilterScreen { }); return; } add.active = true; - attributeSelector.titled(stack.getDisplayName().getFormattedText() + "..."); + addInverted.active = true; + attributeSelector.titled(stack.getDisplayName() + .getFormattedText() + "..."); attributesOfItem.clear(); for (ItemAttribute itemAttribute : ItemAttribute.types) attributesOfItem.addAll(itemAttribute.listAttributesOf(stack, this.minecraft.world)); - List options = attributesOfItem.stream().map(ItemAttribute::format).collect(Collectors.toList()); + List options = attributesOfItem.stream() + .map(ia -> ia.format(false)) + .collect(Collectors.toList()); attributeSelector.forOptions(options); attributeSelector.active = true; attributeSelector.visible = true; @@ -119,17 +133,20 @@ public class AttributeFilterScreen extends AbstractFilterScreen { attributeSelectorLabel.setTextAndTrim(options.get(i), true, 112); ItemAttribute selected = attributesOfItem.get(i); - for (ItemAttribute existing : container.selectedAttributes) { + for (Pair existing : container.selectedAttributes) { CompoundNBT testTag = new CompoundNBT(); CompoundNBT testTag2 = new CompoundNBT(); - existing.serializeNBT(testTag); + existing.getFirst() + .serializeNBT(testTag); selected.serializeNBT(testTag2); if (testTag.equals(testTag2)) { add.active = false; + addInverted.active = false; return; } } add.active = true; + addInverted.active = true; }); attributeSelector.onChanged(); } @@ -141,8 +158,8 @@ public class AttributeFilterScreen extends AbstractFilterScreen= attributesOfItem.size()) + return false; + add.active = false; + addInverted.active = false; + CompoundNBT tag = new CompoundNBT(); + ItemAttribute itemAttribute = attributesOfItem.get(index); + itemAttribute.serializeNBT(tag); + AllPackets.channel + .sendToServer(new FilterScreenPacket(inverted ? Option.ADD_INVERTED_TAG : Option.ADD_TAG, tag)); + container.appendSelectedAttribute(itemAttribute, inverted); + if (container.selectedAttributes.size() == 1) + selectedAttributes.set(0, TextFormatting.YELLOW + selectedT); + selectedAttributes.add(TextFormatting.GRAY + "- " + itemAttribute.format(inverted)); + return true; + } + @Override protected void contentsCleared() { selectedAttributes.clear(); selectedAttributes.add(TextFormatting.YELLOW + noSelectedT); - if (!lastItemScanned.isEmpty()) + if (!lastItemScanned.isEmpty()) { add.active = true; + addInverted.active = true; + } } @Override diff --git a/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterContainer.java b/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterContainer.java index 6356878cd..483ac1190 100644 --- a/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterContainer.java +++ b/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterContainer.java @@ -24,8 +24,8 @@ public class FilterContainer extends AbstractFilterContainer { @Override protected void addFilterSlots() { - int x = 16; - int y = 21; + int x = 23; + int y = 20; for (int row = 0; row < 2; ++row) for (int col = 0; col < 9; ++col) @@ -39,7 +39,7 @@ public class FilterContainer extends AbstractFilterContainer { @Override protected int getInventoryOffset() { - return 100; + return 97; } @Override diff --git a/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterItem.java b/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterItem.java index feb43b008..67f6a9ac1 100644 --- a/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterItem.java +++ b/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterItem.java @@ -4,6 +4,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import javax.annotation.Nonnull; + import com.simibubi.create.AllItems; import com.simibubi.create.AllKeys; import com.simibubi.create.content.logistics.item.filter.AttributeFilterContainer.WhitelistMode; @@ -36,8 +38,6 @@ import net.minecraftforge.fml.network.NetworkHooks; import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.ItemStackHandler; -import javax.annotation.Nonnull; - public class FilterItem extends Item implements INamedContainerProvider { private FilterType type; @@ -121,12 +121,14 @@ public class FilterItem extends Item implements INamedContainerProvider { ListNBT attributes = filter.getOrCreateTag() .getList("MatchedAttributes", NBT.TAG_COMPOUND); for (INBT inbt : attributes) { - ItemAttribute attribute = ItemAttribute.fromNBT((CompoundNBT) inbt); + CompoundNBT compound = (CompoundNBT) inbt; + ItemAttribute attribute = ItemAttribute.fromNBT(compound); + boolean inverted = compound.getBoolean("Inverted"); if (count > 3) { list.add(TextFormatting.DARK_GRAY + "- ..."); break; } - list.add(TextFormatting.GRAY + "- " + attribute.format()); + list.add(TextFormatting.GRAY + "- " + attribute.format(inverted)); count++; } @@ -211,8 +213,9 @@ public class FilterItem extends Item implements INamedContainerProvider { ListNBT attributes = filter.getOrCreateTag() .getList("MatchedAttributes", NBT.TAG_COMPOUND); for (INBT inbt : attributes) { - ItemAttribute attribute = ItemAttribute.fromNBT((CompoundNBT) inbt); - boolean matches = attribute.appliesTo(stack, world); + CompoundNBT compound = (CompoundNBT) inbt; + ItemAttribute attribute = ItemAttribute.fromNBT(compound); + boolean matches = attribute.appliesTo(stack, world) != compound.getBoolean("Inverted"); if (matches) { switch (whitelistMode) { diff --git a/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterScreen.java b/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterScreen.java index 9a1defe51..2144bbda1 100644 --- a/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterScreen.java +++ b/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterScreen.java @@ -42,20 +42,20 @@ public class FilterScreen extends AbstractFilterScreen { int x = guiLeft; int y = guiTop; - blacklist = new IconButton(x + 58, y + 72, AllIcons.I_BLACKLIST); + blacklist = new IconButton(x + 18, y + 73, AllIcons.I_BLACKLIST); blacklist.setToolTip(blacklistN); - whitelist = new IconButton(x + 76, y + 72, AllIcons.I_WHITELIST); + whitelist = new IconButton(x + 36, y + 73, AllIcons.I_WHITELIST); whitelist.setToolTip(whitelistN); - blacklistIndicator = new Indicator(x + 58, y + 67, ""); - whitelistIndicator = new Indicator(x + 76, y + 67, ""); + blacklistIndicator = new Indicator(x + 18, y + 67, ""); + whitelistIndicator = new Indicator(x + 36, y + 67, ""); widgets.addAll(Arrays.asList(blacklist, whitelist, blacklistIndicator, whitelistIndicator)); - respectNBT = new IconButton(x + 98, y + 72, AllIcons.I_RESPECT_NBT); + respectNBT = new IconButton(x + 60, y + 73, AllIcons.I_RESPECT_NBT); respectNBT.setToolTip(respectDataN); - ignoreNBT = new IconButton(x + 116, y + 72, AllIcons.I_IGNORE_NBT); + ignoreNBT = new IconButton(x + 78, y + 73, AllIcons.I_IGNORE_NBT); ignoreNBT.setToolTip(ignoreDataN); - respectNBTIndicator = new Indicator(x + 98, y + 67, ""); - ignoreNBTIndicator = new Indicator(x + 116, y + 67, ""); + respectNBTIndicator = new Indicator(x + 60, y + 67, ""); + ignoreNBTIndicator = new Indicator(x + 78, y + 67, ""); widgets.addAll(Arrays.asList(respectNBT, ignoreNBT, respectNBTIndicator, ignoreNBTIndicator)); handleIndicators(); } diff --git a/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterScreenPacket.java b/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterScreenPacket.java index 8d49abeb4..984f455ec 100644 --- a/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterScreenPacket.java +++ b/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterScreenPacket.java @@ -13,7 +13,7 @@ import net.minecraftforge.fml.network.NetworkEvent.Context; public class FilterScreenPacket extends SimplePacketBase { enum Option { - CLEAR, WHITELIST, WHITELIST2, BLACKLIST, RESPECT_DATA, IGNORE_DATA, ADD_TAG; + CLEAR, WHITELIST, WHITELIST2, BLACKLIST, RESPECT_DATA, IGNORE_DATA, ADD_TAG, ADD_INVERTED_TAG; } private Option option; @@ -75,7 +75,9 @@ public class FilterScreenPacket extends SimplePacketBase { if (option == Option.BLACKLIST) c.whitelistMode = WhitelistMode.BLACKLIST; if (option == Option.ADD_TAG) - c.appendSelectedAttribute(ItemAttribute.fromNBT(data)); + c.appendSelectedAttribute(ItemAttribute.fromNBT(data), false); + if (option == Option.ADD_INVERTED_TAG) + c.appendSelectedAttribute(ItemAttribute.fromNBT(data), true); } }); diff --git a/src/main/java/com/simibubi/create/content/logistics/item/filter/ItemAttribute.java b/src/main/java/com/simibubi/create/content/logistics/item/filter/ItemAttribute.java index 3759744aa..fe8dca539 100644 --- a/src/main/java/com/simibubi/create/content/logistics/item/filter/ItemAttribute.java +++ b/src/main/java/com/simibubi/create/content/logistics/item/filter/ItemAttribute.java @@ -12,6 +12,7 @@ import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import com.google.common.base.Predicates; +import com.simibubi.create.AllRecipeTypes; import com.simibubi.create.content.logistics.InWorldProcessing; import com.simibubi.create.foundation.utility.Lang; @@ -95,8 +96,9 @@ public interface ItemAttribute { } @OnlyIn(value = Dist.CLIENT) - default String format() { - return Lang.translate("item_attributes." + getTranslationKey(), getTranslationParameters()); + default String format(boolean inverted) { + return Lang.translate("item_attributes." + getTranslationKey() + (inverted ? ".inverted" : ""), + getTranslationParameters()); } public static enum StandardTraits implements ItemAttribute { @@ -111,6 +113,8 @@ public interface ItemAttribute { EQUIPABLE(s -> s.getEquipmentSlot() != null), FURNACE_FUEL(AbstractFurnaceTileEntity::isFuel), WASHABLE(InWorldProcessing::isWashable), + CRUSHABLE((s, w) -> testRecipe(s, w, AllRecipeTypes.CRUSHING.getType()) + || testRecipe(s, w, AllRecipeTypes.MILLING.getType())), SMELTABLE((s, w) -> testRecipe(s, w, IRecipeType.SMELTING)), SMOKABLE((s, w) -> testRecipe(s, w, IRecipeType.SMOKING)), BLASTABLE((s, w) -> testRecipe(s, w, IRecipeType.BLASTING)); @@ -123,11 +127,13 @@ public interface ItemAttribute { this.test = test; } - private static boolean testRecipe(ItemStack s, World w, IRecipeType> smelting) { + private static boolean testRecipe(ItemStack s, World w, IRecipeType> type) { RECIPE_WRAPPER.setInventorySlotContents(0, s.copy()); - return w.getRecipeManager().getRecipe(smelting, RECIPE_WRAPPER, w).isPresent(); + return w.getRecipeManager() + .getRecipe(type, RECIPE_WRAPPER, w) + .isPresent(); } - + private StandardTraits(BiPredicate test) { this.testWithWorld = test; } @@ -193,12 +199,18 @@ public interface ItemAttribute { @Override public boolean appliesTo(ItemStack stack) { - return stack.getItem().getTags().contains(tagName); + return stack.getItem() + .getTags() + .contains(tagName); } @Override public List listAttributesOf(ItemStack stack) { - return stack.getItem().getTags().stream().map(InTag::new).collect(Collectors.toList()); + return stack.getItem() + .getTags() + .stream() + .map(InTag::new) + .collect(Collectors.toList()); } @Override @@ -240,7 +252,8 @@ public interface ItemAttribute { @Override public List listAttributesOf(ItemStack stack) { - ItemGroup group = stack.getItem().getGroup(); + ItemGroup group = stack.getItem() + .getGroup(); return group == null ? Collections.emptyList() : Arrays.asList(new InItemGroup(group)); } @@ -249,9 +262,11 @@ public interface ItemAttribute { return "in_item_group"; } + @Override @OnlyIn(value = Dist.CLIENT) - public String format() { - return Lang.translate("item_attributes." + getTranslationKey(), I18n.format(group.getTranslationKey())); + public String format(boolean inverted) { + return Lang.translate("item_attributes." + getTranslationKey() + (inverted ? ".inverted" : ""), + I18n.format(group.getTranslationKey())); } @Override @@ -263,7 +278,8 @@ public interface ItemAttribute { public ItemAttribute readNBT(CompoundNBT nbt) { String readPath = nbt.getString("path"); for (ItemGroup group : ItemGroup.GROUPS) - if (group.getPath().equals(readPath)) + if (group.getPath() + .equals(readPath)) return new InItemGroup(group); return null; } @@ -280,12 +296,14 @@ public interface ItemAttribute { @Override public boolean appliesTo(ItemStack stack) { - return modId.equals(stack.getItem().getCreatorModId(stack)); + return modId.equals(stack.getItem() + .getCreatorModId(stack)); } @Override public List listAttributesOf(ItemStack stack) { - String id = stack.getItem().getCreatorModId(stack); + String id = stack.getItem() + .getCreatorModId(stack); return id == null ? Collections.emptyList() : Arrays.asList(new AddedBy(id)); } @@ -296,9 +314,11 @@ public interface ItemAttribute { @Override public Object[] getTranslationParameters() { - Optional modContainerById = ModList.get().getModContainerById(modId); - String name = modContainerById.map(ModContainer::getModInfo).map(IModInfo::getDisplayName) - .orElse(StringUtils.capitalize(modId)); + Optional modContainerById = ModList.get() + .getModContainerById(modId); + String name = modContainerById.map(ModContainer::getModInfo) + .map(IModInfo::getDisplayName) + .orElse(StringUtils.capitalize(modId)); return new Object[] { name }; } diff --git a/src/main/java/com/simibubi/create/content/logistics/packet/ConfigureStockswitchPacket.java b/src/main/java/com/simibubi/create/content/logistics/packet/ConfigureStockswitchPacket.java index 3f6febd1f..7822cc9f9 100644 --- a/src/main/java/com/simibubi/create/content/logistics/packet/ConfigureStockswitchPacket.java +++ b/src/main/java/com/simibubi/create/content/logistics/packet/ConfigureStockswitchPacket.java @@ -10,11 +10,13 @@ public class ConfigureStockswitchPacket extends TileEntityConfigurationPacket maxSize * 1000) { - Minecraft.getInstance().player.sendMessage(new StringTextComponent( - Lang.translate("schematics.uploadTooLarge") + " (" + size / 1000 + " KB).")); - Minecraft.getInstance().player.sendMessage( - new StringTextComponent(Lang.translate("schematics.maxAllowedSize") + " " + maxSize + " KB")); + if (!validateSizeLimitation(size)) return; - } in = Files.newInputStream(path, StandardOpenOption.READ); activeUploads.put(schematic, in); @@ -83,6 +77,20 @@ public class ClientSchematicLoader { } } + public static boolean validateSizeLimitation(long size) { + if (Minecraft.getInstance().isSingleplayer()) + return true; + Integer maxSize = AllConfigs.SERVER.schematics.maxTotalSchematicSize.get(); + if (size > maxSize * 1000) { + Minecraft.getInstance().player.sendMessage(new StringTextComponent( + Lang.translate("schematics.uploadTooLarge") + " (" + size / 1000 + " KB).")); + Minecraft.getInstance().player.sendMessage( + new StringTextComponent(Lang.translate("schematics.maxAllowedSize") + " " + maxSize + " KB")); + return false; + } + return true; + } + private void continueUpload(String schematic) { if (activeUploads.containsKey(schematic)) { Integer maxPacketSize = AllConfigs.SERVER.schematics.maxSchematicPacketSize.get(); diff --git a/src/main/java/com/simibubi/create/content/schematics/ServerSchematicLoader.java b/src/main/java/com/simibubi/create/content/schematics/ServerSchematicLoader.java index 3755dff63..8c8e117fa 100644 --- a/src/main/java/com/simibubi/create/content/schematics/ServerSchematicLoader.java +++ b/src/main/java/com/simibubi/create/content/schematics/ServerSchematicLoader.java @@ -14,7 +14,10 @@ import java.util.Optional; import java.util.Set; import java.util.stream.Stream; +import org.apache.commons.io.IOUtils; + import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllItems; import com.simibubi.create.Create; import com.simibubi.create.content.schematics.block.SchematicTableTileEntity; import com.simibubi.create.content.schematics.item.SchematicItem; @@ -23,12 +26,17 @@ import com.simibubi.create.foundation.config.CSchematics; import com.simibubi.create.foundation.utility.FilesHelper; import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.TranslationTextComponent; import net.minecraft.world.World; +import net.minecraft.world.gen.feature.template.Template; public class ServerSchematicLoader { @@ -92,17 +100,12 @@ public class ServerSchematicLoader { // Unsupported Format if (!schematic.endsWith(".nbt")) { Create.logger.warn("Attempted Schematic Upload with non-supported Format: " + playerSchematicId); + return; } // Too big - Integer maxFileSize = getConfig().maxTotalSchematicSize.get(); - if (size > maxFileSize * 1000) { - player.sendMessage(new TranslationTextComponent("create.schematics.uploadTooLarge") - .appendSibling(new StringTextComponent(" (" + size / 1000 + " KB)."))); - player.sendMessage(new TranslationTextComponent("create.schematics.maxAllowedSize") - .appendSibling(new StringTextComponent(" " + maxFileSize + " KB"))); + if (!validateSchematicSizeOnServer(player, size)) return; - } // Skip existing Uploads if (activeUploads.containsKey(playerSchematicId)) @@ -134,8 +137,7 @@ public class ServerSchematicLoader { // Open Stream OutputStream writer = Files.newOutputStream(Paths.get(getSchematicPath(), playerSchematicId), StandardOpenOption.CREATE_NEW); - activeUploads.put(playerSchematicId, - new SchematicUploadEntry(writer, size, player.getServerWorld(), pos)); + activeUploads.put(playerSchematicId, new SchematicUploadEntry(writer, size, player.getServerWorld(), pos)); // Notify Tile Entity table.startUpload(schematic); @@ -146,6 +148,18 @@ public class ServerSchematicLoader { } } + protected boolean validateSchematicSizeOnServer(ServerPlayerEntity player, long size) { + Integer maxFileSize = getConfig().maxTotalSchematicSize.get(); + if (size > maxFileSize * 1000) { + player.sendMessage(new TranslationTextComponent("create.schematics.uploadTooLarge") + .appendSibling(new StringTextComponent(" (" + size / 1000 + " KB)."))); + player.sendMessage(new TranslationTextComponent("create.schematics.maxAllowedSize") + .appendSibling(new StringTextComponent(" " + maxFileSize + " KB"))); + return false; + } + return true; + } + public CSchematics getConfig() { return AllConfigs.SERVER.schematics; } @@ -231,7 +245,7 @@ public class ServerSchematicLoader { SchematicUploadEntry removed = activeUploads.remove(playerSchematicId); World world = removed.world; BlockPos pos = removed.tablePos; - + Create.logger.info("New Schematic Uploaded: " + playerSchematicId); if (pos == null) return; @@ -252,6 +266,65 @@ public class ServerSchematicLoader { e.printStackTrace(); } } - } + + public void handleInstantSchematic(ServerPlayerEntity player, String schematic, World world, BlockPos pos, + BlockPos bounds) { + String playerPath = getSchematicPath() + "/" + player.getName() + .getFormattedText(); + String playerSchematicId = player.getName() + .getFormattedText() + "/" + schematic; + FilesHelper.createFolderIfMissing(playerPath); + + // Unsupported Format + if (!schematic.endsWith(".nbt")) { + Create.logger.warn("Attempted Schematic Upload with non-supported Format: " + playerSchematicId); + return; + } + + // Not holding S&Q + if (!AllItems.SCHEMATIC_AND_QUILL.isIn(player.getHeldItemMainhand())) + return; + + try { + // Delete schematic with same name + Path path = Paths.get(getSchematicPath(), playerSchematicId); + Files.deleteIfExists(path); + + // Too many Schematics + Stream list = Files.list(Paths.get(playerPath)); + if (list.count() >= getConfig().maxSchematics.get()) { + Stream list2 = Files.list(Paths.get(playerPath)); + Optional lastFilePath = list2.filter(f -> !Files.isDirectory(f)) + .min(Comparator.comparingLong(f -> f.toFile() + .lastModified())); + list2.close(); + if (lastFilePath.isPresent()) + Files.deleteIfExists(lastFilePath.get()); + } + list.close(); + + Template t = new Template(); + t.takeBlocksFromWorld(world, pos, bounds, true, Blocks.AIR); + + OutputStream outputStream = null; + try { + outputStream = Files.newOutputStream(path, StandardOpenOption.CREATE); + CompoundNBT nbttagcompound = t.writeToNBT(new CompoundNBT()); + CompressedStreamTools.writeCompressed(nbttagcompound, outputStream); + player.setHeldItem(Hand.MAIN_HAND, SchematicItem.create(schematic, player.getName() + .getFormattedText())); + + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (outputStream != null) + IOUtils.closeQuietly(outputStream); + } + } catch (IOException e) { + Create.logger.error("Exception Thrown in direct Schematic Upload: " + playerSchematicId); + e.printStackTrace(); + } + } + } diff --git a/src/main/java/com/simibubi/create/content/schematics/block/SchematicTableContainer.java b/src/main/java/com/simibubi/create/content/schematics/block/SchematicTableContainer.java index 00192180d..b1ae26663 100644 --- a/src/main/java/com/simibubi/create/content/schematics/block/SchematicTableContainer.java +++ b/src/main/java/com/simibubi/create/content/schematics/block/SchematicTableContainer.java @@ -41,7 +41,7 @@ public class SchematicTableContainer extends Container { } protected void init() { - inputSlot = new SlotItemHandler(te.inventory, 0, -9, 40) { + inputSlot = new SlotItemHandler(te.inventory, 0, -35, 41) { @Override public boolean isItemValid(ItemStack stack) { return AllItems.EMPTY_SCHEMATIC.isIn(stack) || AllItems.SCHEMATIC_AND_QUILL.isIn(stack) @@ -49,7 +49,7 @@ public class SchematicTableContainer extends Container { } }; - outputSlot = new SlotItemHandler(te.inventory, 1, 75, 40) { + outputSlot = new SlotItemHandler(te.inventory, 1, 110, 41) { @Override public boolean isItemValid(ItemStack stack) { return false; diff --git a/src/main/java/com/simibubi/create/content/schematics/block/SchematicTableScreen.java b/src/main/java/com/simibubi/create/content/schematics/block/SchematicTableScreen.java index b063dfc60..14a8052f9 100644 --- a/src/main/java/com/simibubi/create/content/schematics/block/SchematicTableScreen.java +++ b/src/main/java/com/simibubi/create/content/schematics/block/SchematicTableScreen.java @@ -38,6 +38,8 @@ public class SchematicTableScreen extends AbstractSimiContainerScreen availableSchematics = CreateClient.schematicSender.getAvailableSchematics(); - schematicsLabel = new Label(mainLeft + 36, mainTop + 26, "").withShadow(); + schematicsLabel = new Label(mainLeft + 49, mainTop + 26, "").withShadow(); schematicsLabel.text = ""; if (!availableSchematics.isEmpty()) { schematicsArea = - new SelectionScrollInput(mainLeft + 33, mainTop + 23, 134, 14).forOptions(availableSchematics) + new SelectionScrollInput(mainLeft + 45, mainTop + 21, 139, 18).forOptions(availableSchematics) .titled(availableSchematicsTitle) .writingTo(schematicsLabel); widgets.add(schematicsArea); widgets.add(schematicsLabel); } - confirmButton = new IconButton(mainLeft + 69, mainTop + 55, AllIcons.I_CONFIRM); - folderButton = new IconButton(mainLeft + 204, mainTop + 6, AllIcons.I_OPEN_FOLDER); - refreshButton = new IconButton(mainLeft + 204, mainTop + 26, AllIcons.I_REFRESH); + confirmButton = new IconButton(mainLeft + 44, mainTop + 56, AllIcons.I_CONFIRM); + + folderButton = new IconButton(mainLeft + 21, mainTop + 21, AllIcons.I_OPEN_FOLDER); + folderButton.setToolTip(folder); + refreshButton = new IconButton(mainLeft + 207, mainTop + 21, AllIcons.I_REFRESH); + refreshButton.setToolTip(refresh); + widgets.add(confirmButton); widgets.add(folderButton); widgets.add(refreshButton); @@ -104,13 +110,13 @@ public class SchematicTableScreen extends AbstractSimiContainerScreen { public SchematicannonRenderer(TileEntityRendererDispatcher dispatcher) { super(dispatcher); } + + @Override + public boolean isGlobalRenderer(SchematicannonTileEntity p_188185_1_) { + return true; + } @Override protected void renderSafe(SchematicannonTileEntity tileEntityIn, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) { - Minecraft.getInstance().getTextureManager().bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE); - double yaw = 0; double pitch = 40; double recoil = 0; @@ -96,8 +96,8 @@ public class SchematicannonRenderer extends SafeTileEntityRenderer launched.totalTicks - 10) { + if ((launched.ticksRemaining + 1 - partialTicks) > launched.totalTicks - 10) recoil = Math.max(recoil, (launched.ticksRemaining + 1 - partialTicks) - launched.totalTicks + 10); - } // Render particles for launch if (launched.ticksRemaining == launched.totalTicks && tileEntityIn.firstRenderTick) { diff --git a/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonScreen.java b/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonScreen.java index 42fabac2a..ddcad6026 100644 --- a/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonScreen.java +++ b/src/main/java/com/simibubi/create/content/schematics/block/SchematicannonScreen.java @@ -15,12 +15,15 @@ import com.simibubi.create.foundation.item.ItemDescription.Palette; import com.simibubi.create.foundation.item.TooltipHelper; import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.utility.Lang; + +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.widget.Widget; import net.minecraft.client.renderer.Rectangle2d; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.item.ItemStack; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextFormatting; +import net.minecraft.util.text.TranslationTextComponent; import java.util.ArrayList; import java.util.Collections; @@ -31,6 +34,9 @@ import static net.minecraft.util.text.TextFormatting.GRAY; public class SchematicannonScreen extends AbstractSimiContainerScreen { + private static final AllGuiTextures BG_BOTTOM = AllGuiTextures.SCHEMATICANNON_BOTTOM; + private static final AllGuiTextures BG_TOP = AllGuiTextures.SCHEMATICANNON_TOP; + protected Vector replaceLevelIndicators; protected Vector replaceLevelButtons; @@ -47,27 +53,37 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen extraAreas; + protected List placementSettingWidgets; private final String title = Lang.translate("gui.schematicannon.title"); - private final String settingsTitle = Lang.translate("gui.schematicannon.settingsTitle"); private final String listPrinter = Lang.translate("gui.schematicannon.listPrinter"); private final String _gunpowderLevel = "gui.schematicannon.gunpowderLevel"; private final String _shotsRemaining = "gui.schematicannon.shotsRemaining"; + private final String _showSettings = "gui.schematicannon.showOptions"; private final String _shotsRemainingWithBackup = "gui.schematicannon.shotsRemainingWithBackup"; + private final String _slotGunpowder = "gui.schematicannon.slot.gunpowder"; + private final String _slotListPrinter = "gui.schematicannon.slot.listPrinter"; + private final String _slotSchematic = "gui.schematicannon.slot.schematic"; + private final String optionEnabled = Lang.translate("gui.schematicannon.optionEnabled"); private final String optionDisabled = Lang.translate("gui.schematicannon.optionDisabled"); private final ItemStack renderedItem = AllBlocks.SCHEMATICANNON.asStack(); + private IconButton confirmButton; + private IconButton showSettingsButton; + private Indicator showSettingsIndicator; + public SchematicannonScreen(SchematicannonContainer container, PlayerInventory inventory, - ITextComponent p_i51105_3_) { + ITextComponent p_i51105_3_) { super(container, inventory, p_i51105_3_); + placementSettingWidgets = new ArrayList<>(); } @Override protected void init() { - setWindowSize(AllGuiTextures.SCHEMATICANNON_BG.width + 50, AllGuiTextures.SCHEMATICANNON_BG.height + 80); + setWindowSize(BG_TOP.width + 50, BG_BOTTOM.height + BG_TOP.height + 80); super.init(); int x = guiLeft + 20; @@ -76,63 +92,87 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen(4); - replaceLevelIndicators = new Vector<>(4); - List icons = ImmutableList - .of(AllIcons.I_DONT_REPLACE, AllIcons.I_REPLACE_SOLID, AllIcons.I_REPLACE_ANY, - AllIcons.I_REPLACE_EMPTY); - List toolTips = ImmutableList - .of(Lang.translate("gui.schematicannon.option.dontReplaceSolid"), - Lang.translate("gui.schematicannon.option.replaceWithSolid"), - Lang.translate("gui.schematicannon.option.replaceWithAny"), - Lang.translate("gui.schematicannon.option.replaceWithEmpty")); - - for (int i = 0; i < 4; i++) { - replaceLevelIndicators.add(new Indicator(x + 16 + i * 18, y + 96, "")); - replaceLevelButtons.add(new IconButton(x + 16 + i * 18, y + 101, icons.get(i))); - replaceLevelButtons.get(i).setToolTip(toolTips.get(i)); - } - widgets.addAll(replaceLevelButtons); - widgets.addAll(replaceLevelIndicators); - - // Other Settings - skipMissingButton = new IconButton(x + 106, y + 101, AllIcons.I_SKIP_MISSING); - skipMissingButton.setToolTip(Lang.translate("gui.schematicannon.option.skipMissing")); - skipMissingIndicator = new Indicator(x + 106, y + 96, ""); - Collections.addAll(widgets, skipMissingButton, skipMissingIndicator); - - skipTilesButton = new IconButton(x + 124, y + 101, AllIcons.I_SKIP_TILES); - skipTilesButton.setToolTip(Lang.translate("gui.schematicannon.option.skipTileEntities")); - skipTilesIndicator = new Indicator(x + 124, y + 96, ""); - Collections.addAll(widgets, skipTilesButton, skipTilesIndicator); + Collections.addAll(widgets, playButton, playIndicator, pauseButton, pauseIndicator, resetButton, + resetIndicator); extraAreas = new ArrayList<>(); extraAreas.add(new Rectangle2d(guiLeft + 240, guiTop + 88, 84, 113)); + confirmButton = new IconButton(x + 180, guiTop + 117, AllIcons.I_CONFIRM); + widgets.add(confirmButton); + showSettingsButton = new IconButton(guiLeft + 29, guiTop + 117, AllIcons.I_PLACEMENT_SETTINGS); + showSettingsButton.setToolTip(Lang.translate(_showSettings)); + widgets.add(showSettingsButton); + showSettingsIndicator = new Indicator(guiLeft + 29, guiTop + 111, ""); + widgets.add(showSettingsIndicator); + tick(); } + private void initPlacementSettings() { + widgets.removeAll(placementSettingWidgets); + placementSettingWidgets.clear(); + + if (placementSettingsHidden()) + return; + + int x = guiLeft + 20; + int y = guiTop; + + // Replace settings + replaceLevelButtons = new Vector<>(4); + replaceLevelIndicators = new Vector<>(4); + List icons = ImmutableList.of(AllIcons.I_DONT_REPLACE, AllIcons.I_REPLACE_SOLID, + AllIcons.I_REPLACE_ANY, AllIcons.I_REPLACE_EMPTY); + List toolTips = ImmutableList.of(Lang.translate("gui.schematicannon.option.dontReplaceSolid"), + Lang.translate("gui.schematicannon.option.replaceWithSolid"), + Lang.translate("gui.schematicannon.option.replaceWithAny"), + Lang.translate("gui.schematicannon.option.replaceWithEmpty")); + + for (int i = 0; i < 4; i++) { + replaceLevelIndicators.add(new Indicator(x + 33 + i * 18, y + 111, "")); + replaceLevelButtons.add(new IconButton(x + 33 + i * 18, y + 117, icons.get(i))); + replaceLevelButtons.get(i) + .setToolTip(toolTips.get(i)); + } + placementSettingWidgets.addAll(replaceLevelButtons); + placementSettingWidgets.addAll(replaceLevelIndicators); + + // Other Settings + skipMissingButton = new IconButton(x + 111, y + 117, AllIcons.I_SKIP_MISSING); + skipMissingButton.setToolTip(Lang.translate("gui.schematicannon.option.skipMissing")); + skipMissingIndicator = new Indicator(x + 111, y + 111, ""); + Collections.addAll(placementSettingWidgets, skipMissingButton, skipMissingIndicator); + + skipTilesButton = new IconButton(x + 129, y + 117, AllIcons.I_SKIP_TILES); + skipTilesButton.setToolTip(Lang.translate("gui.schematicannon.option.skipTileEntities")); + skipTilesIndicator = new Indicator(x + 129, y + 111, ""); + Collections.addAll(placementSettingWidgets, skipTilesButton, skipTilesIndicator); + + widgets.addAll(placementSettingWidgets); + } + + protected boolean placementSettingsHidden() { + return showSettingsIndicator.state == State.OFF; + } + @Override public void tick() { - SchematicannonTileEntity te = container.getTileEntity(); - replaceLevelIndicators.get(0).state = te.replaceMode == 0 ? State.ON : State.OFF; - for (int replaceMode = 1; replaceMode < replaceLevelButtons.size(); replaceMode++) - replaceLevelIndicators.get(replaceMode).state = replaceMode <= te.replaceMode ? State.ON : State.OFF; - skipMissingIndicator.state = te.skipMissing ? State.ON : State.OFF; - skipTilesIndicator.state = !te.replaceTileEntities ? State.ON : State.OFF; + if (!placementSettingsHidden()) { + for (int replaceMode = 0; replaceMode < replaceLevelButtons.size(); replaceMode++) + replaceLevelIndicators.get(replaceMode).state = replaceMode == te.replaceMode ? State.ON : State.OFF; + skipMissingIndicator.state = te.skipMissing ? State.ON : State.OFF; + skipTilesIndicator.state = !te.replaceTileEntities ? State.ON : State.OFF; + } playIndicator.state = State.OFF; pauseIndicator.state = State.OFF; @@ -167,12 +207,18 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen tip = button.getToolTip(); tip.add(TextFormatting.BLUE + (enabled ? optionEnabled : optionDisabled)); - tip - .addAll(TooltipHelper - .cutString(Lang.translate("gui.schematicannon.option." + tooltipKey + ".description"), GRAY, - GRAY)); + tip.addAll(TooltipHelper.cutString(Lang.translate("gui.schematicannon.option." + tooltipKey + ".description"), + GRAY, GRAY)); } @Override protected void renderWindow(int mouseX, int mouseY, float partialTicks) { AllGuiTextures.PLAYER_INVENTORY.draw(this, guiLeft - 10, guiTop + 145); - AllGuiTextures.SCHEMATICANNON_BG.draw(this, guiLeft + 20, guiTop); + BG_TOP.draw(this, guiLeft + 20, guiTop); + BG_BOTTOM.draw(this, guiLeft + 20, guiTop + BG_TOP.height); SchematicannonTileEntity te = container.getTileEntity(); renderPrintingProgress(te.schematicProgress); renderFuelBar(te.fuelLevel); renderChecklistPrinterProgress(te.bookPrintingProgress); - if (!te.inventory.getStackInSlot(0).isEmpty()) + if (!te.inventory.getStackInSlot(0) + .isEmpty()) renderBlueprintHighlight(); GuiGameElement.of(renderedItem) - .at(guiLeft + 240, guiTop + 120) - .scale(5) - .render(); + .at(guiLeft + 230, guiTop + 110) + .scale(5) + .render(); - - font.drawString(title, guiLeft + 80, guiTop + 10, AllGuiTextures.FONT_COLOR); + font.drawStringWithShadow(title, guiLeft + 80, guiTop + 3, 0xfefefe); String msg = Lang.translate("schematicannon.status." + te.statusMsg); int stringWidth = font.getStringWidth(msg); if (te.missingItem != null) { stringWidth += 15; - itemRenderer.renderItemIntoGUI(te.missingItem, guiLeft + 145, guiTop + 25); + itemRenderer.renderItemIntoGUI(te.missingItem, guiLeft + 150, guiTop + 46); } - font.drawStringWithShadow(msg, guiLeft + 20 + 96 - stringWidth / 2, guiTop + 30, 0xCCDDFF); - - font.drawString(settingsTitle, guiLeft + 20 + 13, guiTop + 84, AllGuiTextures.FONT_COLOR); - font - .drawString(playerInventory.getDisplayName().getFormattedText(), guiLeft - 10 + 7, guiTop + 145 + 6, - 0x666666); + font.drawStringWithShadow(msg, guiLeft + 20 + 102 - stringWidth / 2, guiTop + 50, 0xCCDDFF); + font.drawString(playerInventory.getDisplayName() + .getFormattedText(), guiLeft - 10 + 7, guiTop + 145 + 6, 0x666666); // to see or debug the bounds of the extra area uncomment the following lines // Rectangle2d r = extraAreas.get(0); @@ -241,92 +283,128 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen= fuelX && mouseY >= fuelY && mouseX <= fuelX + AllGuiTextures.SCHEMATICANNON_FUEL.width - && mouseY <= fuelY + AllGuiTextures.SCHEMATICANNON_FUEL.height) { - container.getTileEntity(); - - double fuelUsageRate = te.getFuelUsageRate(); - int shotsLeft = (int) (te.fuelLevel / fuelUsageRate); - int shotsLeftWithItems = (int) (shotsLeft - + te.inventory.getStackInSlot(4).getCount() * (te.getFuelAddedByGunPowder() / fuelUsageRate)); - - List tooltip = new ArrayList<>(); - float f = te.hasCreativeCrate ? 100 : te.fuelLevel * 100; - tooltip.add(Lang.translate(_gunpowderLevel, "" + (int) f)); - if (!te.hasCreativeCrate) - tooltip.add(GRAY + Lang.translate(_shotsRemaining, "" + TextFormatting.BLUE + shotsLeft)); - if (shotsLeftWithItems != shotsLeft) - tooltip - .add(GRAY + Lang - .translate(_shotsRemainingWithBackup, "" + TextFormatting.BLUE + shotsLeftWithItems)); - + && mouseY <= fuelY + AllGuiTextures.SCHEMATICANNON_FUEL.height) { + List tooltip = getFuelLevelTooltip(te); renderTooltip(tooltip, mouseX, mouseY); } + if (hoveredSlot != null && !hoveredSlot.getHasStack()) { + if (hoveredSlot.getSlotIndex() == 0) + renderTooltip( + TooltipHelper.cutString(Lang.translate(_slotSchematic), TextFormatting.GRAY, TextFormatting.BLUE), + mouseX, mouseY); + if (hoveredSlot.getSlotIndex() == 2) + renderTooltip( + TooltipHelper.cutString(Lang.translate(_slotListPrinter), TextFormatting.GRAY, TextFormatting.BLUE), + mouseX, mouseY); + if (hoveredSlot.getSlotIndex() == 4) + renderTooltip( + TooltipHelper.cutString(Lang.translate(_slotGunpowder), TextFormatting.GRAY, TextFormatting.BLUE), + mouseX, mouseY); + } + if (te.missingItem != null) { - int missingBlockX = guiLeft + 145, missingBlockY = guiTop + 25; + int missingBlockX = guiLeft + 150, missingBlockY = guiTop + 46; if (mouseX >= missingBlockX && mouseY >= missingBlockY && mouseX <= missingBlockX + 16 - && mouseY <= missingBlockY + 16) { + && mouseY <= missingBlockY + 16) { renderTooltip(te.missingItem, mouseX, mouseY); } } - int paperX = guiLeft + 20 + 202, paperY = guiTop + 20; - if (mouseX >= paperX && mouseY >= paperY && mouseX <= paperX + 16 && mouseY <= paperY + 16) { + int paperX = guiLeft + 132, paperY = guiTop + 19; + if (mouseX >= paperX && mouseY >= paperY && mouseX <= paperX + 16 && mouseY <= paperY + 16) renderTooltip(listPrinter, mouseX, mouseY); - } super.renderWindowForeground(mouseX, mouseY, partialTicks); } - @Override - public boolean mouseClicked(double x, double y, int button) { + protected List getFuelLevelTooltip(SchematicannonTileEntity te) { + double fuelUsageRate = te.getFuelUsageRate(); + int shotsLeft = (int) (te.fuelLevel / fuelUsageRate); + int shotsLeftWithItems = (int) (shotsLeft + te.inventory.getStackInSlot(4) + .getCount() * (te.getFuelAddedByGunPowder() / fuelUsageRate)); + List tooltip = new ArrayList<>(); - for (int replaceMode = 0; replaceMode < replaceLevelButtons.size(); replaceMode++) { - if (!replaceLevelButtons.get(replaceMode).isHovered()) - continue; - if (container.getTileEntity().replaceMode == replaceMode) - continue; - sendOptionUpdate(Option.values()[replaceMode], true); + if (te.hasCreativeCrate) { + tooltip.add(Lang.translate(_gunpowderLevel, "" + 100)); + tooltip.add(TextFormatting.DARK_PURPLE + "(" + new TranslationTextComponent(AllBlocks.CREATIVE_CRATE.get() + .getTranslationKey()).getFormattedText() + ")"); + return tooltip; } - if (skipMissingButton.isHovered()) - sendOptionUpdate(Option.SKIP_MISSING, !container.getTileEntity().skipMissing); - if (skipTilesButton.isHovered()) - sendOptionUpdate(Option.SKIP_TILES, !container.getTileEntity().replaceTileEntities); + float f = te.fuelLevel * 100; + tooltip.add(Lang.translate(_gunpowderLevel, "" + (int) f)); + tooltip.add(GRAY + Lang.translate(_shotsRemaining, "" + TextFormatting.BLUE + shotsLeft)); + if (shotsLeftWithItems != shotsLeft) + tooltip + .add(GRAY + Lang.translate(_shotsRemainingWithBackup, "" + TextFormatting.BLUE + shotsLeftWithItems)); + return tooltip; + } + + @Override + public boolean mouseClicked(double x, double y, int button) { + if (showSettingsButton.isHovered()) { + showSettingsIndicator.state = placementSettingsHidden() ? State.GREEN : State.OFF; + initPlacementSettings(); + } + + if (confirmButton.isHovered()) { + Minecraft.getInstance().player.closeScreen(); + return true; + } + + if (!placementSettingsHidden()) { + for (int replaceMode = 0; replaceMode < replaceLevelButtons.size(); replaceMode++) { + if (!replaceLevelButtons.get(replaceMode) + .isHovered()) + continue; + if (container.getTileEntity().replaceMode == replaceMode) + continue; + sendOptionUpdate(Option.values()[replaceMode], true); + } + if (skipMissingButton.isHovered()) + sendOptionUpdate(Option.SKIP_MISSING, !container.getTileEntity().skipMissing); + if (skipTilesButton.isHovered()) + sendOptionUpdate(Option.SKIP_TILES, !container.getTileEntity().replaceTileEntities); + } if (playButton.isHovered() && playButton.active) sendOptionUpdate(Option.PLAY, true); @@ -344,8 +422,8 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen { - }); - guiScreenIn.setTitle(Lang.translate("schematicAndQuill.prompt")); - guiScreenIn.setButtonTextConfirm(Lang.translate("action.saveToFile")); - guiScreenIn.setButtonTextAbort(Lang.translate("action.discard")); - ScreenOpener.open(guiScreenIn); + ScreenOpener.open(new SchematicPromptScreen()); return; } @@ -128,6 +125,13 @@ public class SchematicAndQuillHandler { firstPos = selectedPos; Lang.sendStatus(player, "schematicAndQuill.firstPos"); } + + public void discard() { + ClientPlayerEntity player = Minecraft.getInstance().player; + firstPos = null; + secondPos = null; + Lang.sendStatus(player, "schematicAndQuill.abort"); + } public void tick() { if (!isActive()) @@ -200,11 +204,13 @@ public class SchematicAndQuillHandler { && Minecraft.getInstance().currentScreen == null; } - public void saveSchematic(String string) { + public void saveSchematic(String string, boolean convertImmediately) { Template t = new Template(); MutableBoundingBox bb = new MutableBoundingBox(firstPos, secondPos); - t.takeBlocksFromWorld(Minecraft.getInstance().world, new BlockPos(bb.minX, bb.minY, bb.minZ), - new BlockPos(bb.getXSize(), bb.getYSize(), bb.getZSize()), true, Blocks.AIR); + BlockPos origin = new BlockPos(bb.minX, bb.minY, bb.minZ); + BlockPos bounds = new BlockPos(bb.getXSize(), bb.getYSize(), bb.getZSize()); + + t.takeBlocksFromWorld(Minecraft.getInstance().world, origin, bounds, true, Blocks.AIR); if (string.isEmpty()) string = Lang.translate("schematicAndQuill.fallbackName"); @@ -214,9 +220,10 @@ public class SchematicAndQuillHandler { String filename = FilesHelper.findFirstValidFilename(string, folderPath, "nbt"); String filepath = folderPath + "/" + filename; + Path path = Paths.get(filepath); OutputStream outputStream = null; try { - outputStream = Files.newOutputStream(Paths.get(filepath), StandardOpenOption.CREATE); + outputStream = Files.newOutputStream(path, StandardOpenOption.CREATE); CompoundNBT nbttagcompound = t.writeToNBT(new CompoundNBT()); CompressedStreamTools.writeCompressed(nbttagcompound, outputStream); } catch (IOException e) { @@ -228,6 +235,23 @@ public class SchematicAndQuillHandler { firstPos = null; secondPos = null; Lang.sendStatus(Minecraft.getInstance().player, "schematicAndQuill.saved", filepath); + + if (!convertImmediately) + return; + if (!Files.exists(path)) { + Create.logger.fatal("Missing Schematic file: " + path.toString()); + return; + } + try { + if (!ClientSchematicLoader.validateSizeLimitation(Files.size(path))) + return; + AllPackets.channel.sendToServer(new InstantSchematicPacket(filename, origin, bounds)); + + } catch (IOException e) { + Create.logger.fatal("Error finding Schematic file: " + path.toString()); + e.printStackTrace(); + return; + } } private Outliner outliner() { diff --git a/src/main/java/com/simibubi/create/content/schematics/client/SchematicEditScreen.java b/src/main/java/com/simibubi/create/content/schematics/client/SchematicEditScreen.java index 1f1c91ea4..401aff0c9 100644 --- a/src/main/java/com/simibubi/create/content/schematics/client/SchematicEditScreen.java +++ b/src/main/java/com/simibubi/create/content/schematics/client/SchematicEditScreen.java @@ -8,11 +8,14 @@ import com.simibubi.create.AllItems; import com.simibubi.create.CreateClient; import com.simibubi.create.foundation.gui.AbstractSimiScreen; import com.simibubi.create.foundation.gui.AllGuiTextures; +import com.simibubi.create.foundation.gui.AllIcons; +import com.simibubi.create.foundation.gui.widgets.IconButton; import com.simibubi.create.foundation.gui.widgets.Label; import com.simibubi.create.foundation.gui.widgets.ScrollInput; import com.simibubi.create.foundation.gui.widgets.SelectionScrollInput; import com.simibubi.create.foundation.utility.Lang; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.widget.TextFieldWidget; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTUtil; @@ -26,12 +29,12 @@ public class SchematicEditScreen extends AbstractSimiScreen { private TextFieldWidget xInput; private TextFieldWidget yInput; private TextFieldWidget zInput; + private IconButton confirmButton; private final List rotationOptions = Lang.translatedOptions("schematic.rotation", "none", "cw90", "cw180", "cw270"); private final List mirrorOptions = Lang.translatedOptions("schematic.mirror", "none", "leftRight", "frontBack"); - private final String positionLabel = Lang.translate("schematic.position"); private final String rotationLabel = Lang.translate("schematic.rotation"); private final String mirrorLabel = Lang.translate("schematic.mirror"); @@ -41,16 +44,18 @@ public class SchematicEditScreen extends AbstractSimiScreen { @Override protected void init() { - setWindowSize(AllGuiTextures.SCHEMATIC.width + 50, AllGuiTextures.SCHEMATIC.height); + AllGuiTextures background = AllGuiTextures.SCHEMATIC; + setWindowSize(background.width + 50, background.height); int x = guiLeft; int y = guiTop; handler = CreateClient.schematicHandler; - xInput = new TextFieldWidget(font, x + 75, y + 32, 32, 10, ""); - yInput = new TextFieldWidget(font, x + 115, y + 32, 32, 10, ""); - zInput = new TextFieldWidget(font, x + 155, y + 32, 32, 10, ""); + xInput = new TextFieldWidget(font, x + 50, y + 26, 34, 10, ""); + yInput = new TextFieldWidget(font, x + 90, y + 26, 34, 10, ""); + zInput = new TextFieldWidget(font, x + 130, y + 26, 34, 10, ""); - BlockPos anchor = handler.getTransformation().getAnchor(); + BlockPos anchor = handler.getTransformation() + .getAnchor(); if (handler.isDeployed()) { xInput.setText("" + anchor.getX()); yInput.setText("" + anchor.getY()); @@ -80,18 +85,29 @@ public class SchematicEditScreen extends AbstractSimiScreen { }); } - PlacementSettings settings = handler.getTransformation().toSettings(); - Label labelR = new Label(x + 99, y + 52, "").withShadow(); - rotationArea = new SelectionScrollInput(x + 96, y + 49, 94, 14).forOptions(rotationOptions).titled("Rotation") - .setState(settings.getRotation().ordinal()).writingTo(labelR); + PlacementSettings settings = handler.getTransformation() + .toSettings(); + Label labelR = new Label(x + 50, y + 48, "").withShadow(); + rotationArea = new SelectionScrollInput(x + 45, y + 43, 118, 18).forOptions(rotationOptions) + .titled(rotationLabel) + .setState(settings.getRotation() + .ordinal()) + .writingTo(labelR); - Label labelM = new Label(x + 99, y + 72, "").withShadow(); - mirrorArea = new SelectionScrollInput(x + 96, y + 69, 94, 14).forOptions(mirrorOptions).titled("Mirror") - .setState(settings.getMirror().ordinal()).writingTo(labelM); + Label labelM = new Label(x + 50, y + 70, "").withShadow(); + mirrorArea = new SelectionScrollInput(x + 45, y + 65, 118, 18).forOptions(mirrorOptions) + .titled(mirrorLabel) + .setState(settings.getMirror() + .ordinal()) + .writingTo(labelM); Collections.addAll(widgets, xInput, yInput, zInput); Collections.addAll(widgets, labelR, labelM, rotationArea, mirrorArea); + confirmButton = + new IconButton(guiLeft + background.width - 33, guiTop + background.height - 24, AllIcons.I_CONFIRM); + widgets.add(confirmButton); + super.init(); } @@ -132,14 +148,10 @@ public class SchematicEditScreen extends AbstractSimiScreen { AllGuiTextures.SCHEMATIC.draw(this, x, y); font.drawStringWithShadow(handler.getCurrentSchematicName(), - x + 103 - font.getStringWidth(handler.getCurrentSchematicName()) / 2, y + 10, 0xDDEEFF); - - font.drawString(positionLabel, x + 10, y + 32, AllGuiTextures.FONT_COLOR); - font.drawString(rotationLabel, x + 10, y + 52, AllGuiTextures.FONT_COLOR); - font.drawString(mirrorLabel, x + 10, y + 72, AllGuiTextures.FONT_COLOR); + x + 93 - font.getStringWidth(handler.getCurrentSchematicName()) / 2, y + 3, 0xffffff); RenderSystem.pushMatrix(); - RenderSystem.translated(guiLeft + 220, guiTop + 20, 0); + RenderSystem.translated(guiLeft + 200, guiTop + 80, 0); RenderSystem.scaled(3, 3, 3); itemRenderer.renderItemIntoGUI(new ItemStack(AllItems.SCHEMATIC.get()), 0, 0); RenderSystem.popMatrix(); @@ -151,7 +163,7 @@ public class SchematicEditScreen extends AbstractSimiScreen { BlockPos newLocation = null; try { newLocation = new BlockPos(Integer.parseInt(xInput.getText()), Integer.parseInt(yInput.getText()), - Integer.parseInt(zInput.getText())); + Integer.parseInt(zInput.getText())); } catch (NumberFormatException e) { validCoords = false; } @@ -159,19 +171,31 @@ public class SchematicEditScreen extends AbstractSimiScreen { PlacementSettings settings = new PlacementSettings(); settings.setRotation(Rotation.values()[rotationArea.getState()]); settings.setMirror(Mirror.values()[mirrorArea.getState()]); - + if (validCoords && newLocation != null) { ItemStack item = handler.getActiveSchematicItem(); if (item != null) { - item.getTag().putBoolean("Deployed", true); - item.getTag().put("Anchor", NBTUtil.writeBlockPos(newLocation)); + item.getTag() + .putBoolean("Deployed", true); + item.getTag() + .put("Anchor", NBTUtil.writeBlockPos(newLocation)); } - handler.getTransformation().init(newLocation, settings, handler.getBounds()); + handler.getTransformation() + .init(newLocation, settings, handler.getBounds()); handler.markDirty(); handler.deploy(); } + } + @Override + public boolean mouseClicked(double x, double y, int button) { + if (confirmButton.isHovered()) { + Minecraft.getInstance().player.closeScreen(); + return true; + } + + return super.mouseClicked(x, y, button); } } diff --git a/src/main/java/com/simibubi/create/content/schematics/client/SchematicHotbarSlotOverlay.java b/src/main/java/com/simibubi/create/content/schematics/client/SchematicHotbarSlotOverlay.java index 0190de43a..e303daf14 100644 --- a/src/main/java/com/simibubi/create/content/schematics/client/SchematicHotbarSlotOverlay.java +++ b/src/main/java/com/simibubi/create/content/schematics/client/SchematicHotbarSlotOverlay.java @@ -11,10 +11,10 @@ public class SchematicHotbarSlotOverlay extends AbstractGui { public void renderOn(int slot) { MainWindow mainWindow = Minecraft.getInstance().getWindow(); - int x = mainWindow.getScaledWidth() / 2 - 92; - int y = mainWindow.getScaledHeight() - 23; + int x = mainWindow.getScaledWidth() / 2 - 88; + int y = mainWindow.getScaledHeight() - 19; RenderSystem.enableAlphaTest(); - AllGuiTextures.BLUEPRINT_SLOT.draw(this, x + 20 * slot, y); + AllGuiTextures.SCHEMATIC_SLOT.draw(this, x + 20 * slot, y); RenderSystem.disableAlphaTest(); } diff --git a/src/main/java/com/simibubi/create/content/schematics/client/SchematicPromptScreen.java b/src/main/java/com/simibubi/create/content/schematics/client/SchematicPromptScreen.java new file mode 100644 index 000000000..df3617635 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/schematics/client/SchematicPromptScreen.java @@ -0,0 +1,103 @@ +package com.simibubi.create.content.schematics.client; + +import org.lwjgl.glfw.GLFW; + +import com.simibubi.create.AllItems; +import com.simibubi.create.CreateClient; +import com.simibubi.create.foundation.gui.AbstractSimiScreen; +import com.simibubi.create.foundation.gui.AllGuiTextures; +import com.simibubi.create.foundation.gui.AllIcons; +import com.simibubi.create.foundation.gui.widgets.IconButton; +import com.simibubi.create.foundation.utility.Lang; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.widget.TextFieldWidget; + +public class SchematicPromptScreen extends AbstractSimiScreen { + + private final String title = Lang.translate("schematicAndQuill.title"); + private final String convertLabel = Lang.translate("schematicAndQuill.convert"); + private final String abortLabel = Lang.translate("action.discard"); + private final String confirmLabel = Lang.translate("action.saveToFile"); + + private TextFieldWidget nameField; + private IconButton confirm; + private IconButton abort; + private IconButton convert; + + @Override + public void init() { + super.init(); + AllGuiTextures background = AllGuiTextures.SCHEMATIC_PROMPT; + setWindowSize(background.width, background.height + 30); + + nameField = new TextFieldWidget(font, guiLeft + 49, guiTop + 26, 131, 10, ""); + nameField.setTextColor(-1); + nameField.setDisabledTextColour(-1); + nameField.setEnableBackgroundDrawing(false); + nameField.setMaxStringLength(35); + nameField.changeFocus(true); + + abort = new IconButton(guiLeft + 7, guiTop + 53, AllIcons.I_TRASH); + abort.setToolTip(abortLabel); + widgets.add(abort); + + confirm = new IconButton(guiLeft + 158, guiTop + 53, AllIcons.I_CONFIRM); + confirm.setToolTip(confirmLabel); + widgets.add(confirm); + + convert = new IconButton(guiLeft + 180, guiTop + 53, AllIcons.I_SCHEMATIC); + convert.setToolTip(convertLabel); + widgets.add(convert); + + widgets.add(confirm); + widgets.add(convert); + widgets.add(abort); + widgets.add(nameField); + } + + @Override + public void renderWindow(int mouseX, int mouseY, float partialTicks) { + AllGuiTextures.SCHEMATIC_PROMPT.draw(this, guiLeft, guiTop); + font.drawStringWithShadow(title, guiLeft + (sWidth / 2) - (font.getStringWidth(title) / 2), guiTop + 3, + 0xffffff); + itemRenderer.renderItemIntoGUI(AllItems.SCHEMATIC.asStack(), guiLeft + 22, guiTop + 23); + } + + @Override + public boolean keyPressed(int keyCode, int p_keyPressed_2_, int p_keyPressed_3_) { + if (keyCode == GLFW.GLFW_KEY_ENTER) { + confirm(false); + return true; + } + if (keyCode == 256 && this.shouldCloseOnEsc()) { + this.onClose(); + return true; + } + return nameField.keyPressed(keyCode, p_keyPressed_2_, p_keyPressed_3_); + } + + @Override + public boolean mouseClicked(double x, double y, int button) { + if (confirm.isHovered()) { + confirm(false); + return true; + } + if (abort.isHovered()) { + CreateClient.schematicAndQuillHandler.discard(); + Minecraft.getInstance().player.closeScreen(); + return true; + } + if (convert.isHovered()) { + confirm(true); + return true; + } + return super.mouseClicked(x, y, button); + } + + private void confirm(boolean convertImmediately) { + CreateClient.schematicAndQuillHandler.saveSchematic(nameField.getText(), convertImmediately); + Minecraft.getInstance().player.closeScreen(); + } + +} diff --git a/src/main/java/com/simibubi/create/content/schematics/packet/InstantSchematicPacket.java b/src/main/java/com/simibubi/create/content/schematics/packet/InstantSchematicPacket.java new file mode 100644 index 000000000..30a4fdcba --- /dev/null +++ b/src/main/java/com/simibubi/create/content/schematics/packet/InstantSchematicPacket.java @@ -0,0 +1,52 @@ +package com.simibubi.create.content.schematics.packet; + +import java.util.function.Supplier; + +import com.simibubi.create.Create; +import com.simibubi.create.foundation.networking.SimplePacketBase; + +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.math.BlockPos; +import net.minecraftforge.fml.network.NetworkEvent.Context; + +public class InstantSchematicPacket extends SimplePacketBase { + + private String name; + private BlockPos origin; + private BlockPos bounds; + + public InstantSchematicPacket(String name, BlockPos origin, BlockPos bounds) { + this.name = name; + this.origin = origin; + this.bounds = bounds; + } + + public InstantSchematicPacket(PacketBuffer buffer) { + name = buffer.readString(32767); + origin = buffer.readBlockPos(); + bounds = buffer.readBlockPos(); + } + + @Override + public void write(PacketBuffer buffer) { + buffer.writeString(name); + buffer.writeBlockPos(origin); + buffer.writeBlockPos(bounds); + } + + @Override + public void handle(Supplier context) { + context.get() + .enqueueWork(() -> { + ServerPlayerEntity player = context.get() + .getSender(); + if (player == null) + return; + Create.schematicReceiver.handleInstantSchematic(player, name, player.world, origin, bounds); + }); + context.get() + .setPacketHandled(true); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/config/CKinetics.java b/src/main/java/com/simibubi/create/foundation/config/CKinetics.java index 3f83c62f2..31a728123 100644 --- a/src/main/java/com/simibubi/create/foundation/config/CKinetics.java +++ b/src/main/java/com/simibubi/create/foundation/config/CKinetics.java @@ -27,6 +27,8 @@ public class CKinetics extends ConfigBase { public ConfigInt maxPistonPoles = i(64, 1, "maxPistonPoles", Comments.maxPistonPoles); public ConfigInt maxRopeLength = i(128, 1, "maxRopeLength", Comments.maxRopeLength); public ConfigInt maxCartCouplingLength = i(32, 1, "maxCartCouplingLength", Comments.maxCartCouplingLength); + + public CStress stressValues = nested(0, CStress::new, Comments.stress); public ConfigGroup state = group(0, "stats", Comments.stats); public ConfigFloat mediumSpeed = f(30, 0, 4096, "mediumSpeed", Comments.rpm, Comments.mediumSpeed); @@ -37,8 +39,6 @@ public class CKinetics extends ConfigBase { public ConfigFloat mediumCapacity = f(128, 0, 4096, "mediumCapacity", Comments.su, Comments.mediumCapacity); public ConfigFloat highCapacity = f(512, 0, 65535, "highCapacity", Comments.su, Comments.highCapacity); - public CStress stressValues = nested(0, CStress::new, Comments.stress); - @Override public String getName() { return "kinetics"; diff --git a/src/main/java/com/simibubi/create/foundation/config/CRecipes.java b/src/main/java/com/simibubi/create/foundation/config/CRecipes.java new file mode 100644 index 000000000..b7eba1242 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/config/CRecipes.java @@ -0,0 +1,26 @@ +package com.simibubi.create.foundation.config; + +public class CRecipes extends ConfigBase { + + public ConfigBool allowShapelessInMixer = b(true, "allowShapelessInMixer", Comments.allowShapelessInMixer); + public ConfigBool allowShapedSquareInPress = b(true, "allowShapedSquareInPress", Comments.allowShapedSquareInPress); + public ConfigBool allowRegularCraftingInCrafter = b(true, "allowRegularCraftingInCrafter", Comments.allowRegularCraftingInCrafter); + public ConfigBool allowStonecuttingOnSaw = b(true, "allowStonecuttingOnSaw", Comments.allowStonecuttingOnSaw); + + @Override + public String getName() { + return "recipes"; + } + + private static class Comments { + static String allowShapelessInMixer = + "When true, allows any shapeless crafting recipes to be processed by a Mechanical Mixer + Basin."; + static String allowShapedSquareInPress = + "When true, allows any single-ingredient 2x2 or 3x3 crafting recipes to be processed by a Mechanical Press + Basin."; + static String allowRegularCraftingInCrafter = + "When true, allows any standard crafting recipes to be processed by Mechanical Crafters."; + static String allowStonecuttingOnSaw = + "When true, allows any stonecutting recipes to be processed by a Mechanical Saw."; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/config/CServer.java b/src/main/java/com/simibubi/create/foundation/config/CServer.java index 5534e8df7..8ce3783bd 100644 --- a/src/main/java/com/simibubi/create/foundation/config/CServer.java +++ b/src/main/java/com/simibubi/create/foundation/config/CServer.java @@ -6,6 +6,7 @@ public class CServer extends ConfigBase { public ConfigInt tickrateSyncTimer = i(20, 5, "tickrateSyncTimer", "[in Ticks]", Comments.tickrateSyncTimer, Comments.tickrateSyncTimer2); + public CRecipes recipes = nested(0, CRecipes::new, Comments.recipes); public CKinetics kinetics = nested(0, CKinetics::new, Comments.kinetics); public CFluids fluids = nested(0, CFluids::new, Comments.fluids); public CLogistics logistics = nested(0, CLogistics::new, Comments.logistics); @@ -19,6 +20,7 @@ public class CServer extends ConfigBase { } private static class Comments { + static String recipes = "Packmakers' control panel for internal recipe compat"; static String schematics = "Everything related to Schematic tools"; static String kinetics = "Parameters and abilities of Create's kinetic mechanisms"; static String fluids = "Create's liquid manipulation tools"; diff --git a/src/main/java/com/simibubi/create/foundation/data/recipe/CompactingRecipeGen.java b/src/main/java/com/simibubi/create/foundation/data/recipe/CompactingRecipeGen.java new file mode 100644 index 000000000..97e135718 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/data/recipe/CompactingRecipeGen.java @@ -0,0 +1,35 @@ +package com.simibubi.create.foundation.data.recipe; + +import com.simibubi.create.AllRecipeTypes; +import com.simibubi.create.content.palettes.AllPaletteBlocks; + +import net.minecraft.data.DataGenerator; +import net.minecraft.fluid.Fluids; +import net.minecraft.item.Items; +import net.minecraft.tags.FluidTags; + +public class CompactingRecipeGen extends ProcessingRecipeGen { + + GeneratedRecipe + + TEMPGABBRO = create("temp_gabbro", b -> b + .require(Items.COBBLESTONE) + .require(FluidTags.LAVA, 250) + .output(AllPaletteBlocks.GABBRO.get(), 1)), + + ICE = create("ice", b -> b + .require(Items.ICE) + .output(Fluids.WATER, 250)) + + ; + + public CompactingRecipeGen(DataGenerator p_i48262_1_) { + super(p_i48262_1_); + } + + @Override + protected AllRecipeTypes getRecipeType() { + return AllRecipeTypes.COMPACTING; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/data/recipe/EmptyingRecipeGen.java b/src/main/java/com/simibubi/create/foundation/data/recipe/EmptyingRecipeGen.java new file mode 100644 index 000000000..9106e54a8 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/data/recipe/EmptyingRecipeGen.java @@ -0,0 +1,33 @@ +package com.simibubi.create.foundation.data.recipe; + +import com.simibubi.create.AllRecipeTypes; + +import net.minecraft.data.DataGenerator; +import net.minecraft.fluid.Fluids; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.potion.PotionUtils; +import net.minecraft.potion.Potions; +import net.minecraftforge.common.crafting.NBTIngredient; + +public class EmptyingRecipeGen extends ProcessingRecipeGen { + + GeneratedRecipe + + WATER_BOTTLE = create("water_bottle", b -> b + .require(NBTIngredient.fromStacks(PotionUtils.addPotionToItemStack(new ItemStack(Items.POTION), Potions.WATER))) + .output(Fluids.WATER, 250) + .output(Items.GLASS_BOTTLE)) + + ; + + public EmptyingRecipeGen(DataGenerator p_i48262_1_) { + super(p_i48262_1_); + } + + @Override + protected AllRecipeTypes getRecipeType() { + return AllRecipeTypes.EMPTYING; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/data/recipe/MixingRecipeGen.java b/src/main/java/com/simibubi/create/foundation/data/recipe/MixingRecipeGen.java index 524846b60..31369b8b9 100644 --- a/src/main/java/com/simibubi/create/foundation/data/recipe/MixingRecipeGen.java +++ b/src/main/java/com/simibubi/create/foundation/data/recipe/MixingRecipeGen.java @@ -8,6 +8,7 @@ import com.simibubi.create.content.contraptions.processing.HeatCondition; import net.minecraft.block.Blocks; import net.minecraft.data.DataGenerator; import net.minecraft.item.Items; +import net.minecraft.tags.FluidTags; import net.minecraft.tags.ItemTags; import net.minecraftforge.common.Tags; @@ -15,6 +16,11 @@ public class MixingRecipeGen extends ProcessingRecipeGen { GeneratedRecipe + TEMPCOBBLE = create("temp_cobble", b -> b + .require(FluidTags.WATER, 250) + .require(FluidTags.LAVA, 250) + .output(Blocks.COBBLESTONE, 1)), + BRASS_INGOT = create("brass_ingot", b -> b.require(I.copper()) .require(I.zinc()) .output(AllItems.BRASS_INGOT.get(), 2) diff --git a/src/main/java/com/simibubi/create/foundation/data/recipe/ProcessingRecipeGen.java b/src/main/java/com/simibubi/create/foundation/data/recipe/ProcessingRecipeGen.java index a5daca809..094d59133 100644 --- a/src/main/java/com/simibubi/create/foundation/data/recipe/ProcessingRecipeGen.java +++ b/src/main/java/com/simibubi/create/foundation/data/recipe/ProcessingRecipeGen.java @@ -32,8 +32,10 @@ public abstract class ProcessingRecipeGen extends CreateRecipeProvider { generators.add(new WashingRecipeGen(gen)); generators.add(new PolishingRecipeGen(gen)); generators.add(new MixingRecipeGen(gen)); + generators.add(new CompactingRecipeGen(gen)); generators.add(new PressingRecipeGen(gen)); generators.add(new FillingRecipeGen(gen)); + generators.add(new EmptyingRecipeGen(gen)); gen.addProvider(new IDataProvider() { diff --git a/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java b/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java index 4f8716c89..4b72a6da6 100644 --- a/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java +++ b/src/main/java/com/simibubi/create/foundation/data/recipe/StandardRecipeGen.java @@ -201,9 +201,9 @@ public class StandardRecipeGen extends CreateRecipeProvider { .key('A', Tags.Items.NUGGETS_IRON) .patternLine("ASA")), - ATTRIBUTE_FILTER = create(AllItems.ATTRIBUTE_FILTER).unlockedBy(I::andesite) + ATTRIBUTE_FILTER = create(AllItems.ATTRIBUTE_FILTER).unlockedByTag(I::brass) .viaShaped(b -> b.key('S', ItemTags.WOOL) - .key('A', I.copperNugget()) + .key('A', I.brassNugget()) .patternLine("ASA")), BRASS_HAND = create(AllItems.BRASS_HAND).unlockedByTag(I::brass) diff --git a/src/main/java/com/simibubi/create/foundation/fluid/CombinedTankWrapper.java b/src/main/java/com/simibubi/create/foundation/fluid/CombinedTankWrapper.java index 2a5bb5661..67fce3854 100644 --- a/src/main/java/com/simibubi/create/foundation/fluid/CombinedTankWrapper.java +++ b/src/main/java/com/simibubi/create/foundation/fluid/CombinedTankWrapper.java @@ -62,6 +62,9 @@ public class CombinedTankWrapper implements IFluidHandler { @Override public int fill(FluidStack resource, FluidAction action) { + if (resource.isEmpty()) + return 0; + int filled = 0; resource = resource.copy(); @@ -85,6 +88,9 @@ public class CombinedTankWrapper implements IFluidHandler { @Override public FluidStack drain(FluidStack resource, FluidAction action) { + if (resource.isEmpty()) + return resource; + FluidStack drained = FluidStack.EMPTY; resource = resource.copy(); diff --git a/src/main/java/com/simibubi/create/foundation/fluid/FluidHelper.java b/src/main/java/com/simibubi/create/foundation/fluid/FluidHelper.java index 774927b19..581e9c087 100644 --- a/src/main/java/com/simibubi/create/foundation/fluid/FluidHelper.java +++ b/src/main/java/com/simibubi/create/foundation/fluid/FluidHelper.java @@ -74,6 +74,9 @@ public class FluidHelper { int amount = JSONUtils.getInt(json, "amount"); FluidStack stack = new FluidStack(fluid, amount); + if (!json.has("nbt")) + return stack; + try { JsonElement element = json.get("nbt"); stack.setTag(JsonToNBT.getTagFromJson( diff --git a/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java b/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java index 49d7882b6..dc0ddd181 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java +++ b/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java @@ -13,43 +13,47 @@ public enum AllGuiTextures { // Inventories PLAYER_INVENTORY("player_inventory.png", 176, 108), - WAND_SYMMETRY("wand_symmetry.png", 207, 58), - BLOCKZAPPER("zapper.png", 217, 70), - TERRAINZAPPER("zapper.png", 0, 70, 217, 105), - TERRAINZAPPER_INACTIVE_PARAM("zapper.png", 0, 175, 14, 14), + WAND_OF_SYMMETRY("curiosities.png", 188, 99), + BLOCKZAPPER("curiosities.png", 0, 99, 214, 97), + TERRAINZAPPER("curiosities_2.png", 0, 0, 234, 101), + TERRAINZAPPER_INACTIVE_PARAM("curiosities_2.png", 238, 0, 18, 18), - SCHEMATIC_TABLE("schematic_table.png", 207, 89), - SCHEMATIC_TABLE_PROGRESS("schematic_table.png", 209, 0, 24, 17), - SCHEMATIC("schematic.png", 207, 95), + SCHEMATIC("schematics.png", 192, 121), + SCHEMATIC_SLOT("widgets.png", 54, 0, 16, 16), + SCHEMATIC_PROMPT("schematics_2.png", 213, 77), + HUD_BACKGROUND("overlay.png", 0, 0, 16, 16), - SCHEMATICANNON_BG("schematicannon.png", 247, 161), - SCHEMATICANNON_BG_FUEL("schematicannon.png", 247, 161), - SCHEMATICANNON_PROGRESS("schematicannon.png", 0, 161, 121, 16), - SCHEMATICANNON_PROGRESS_2("schematicannon.png", 122, 161, 16, 15), - SCHEMATICANNON_HIGHLIGHT("schematicannon.png", 0, 182, 28, 28), - SCHEMATICANNON_FUEL("schematicannon.png", 0, 215, 82, 4), - SCHEMATICANNON_FUEL_CREATIVE("schematicannon.png", 0, 219, 82, 4), + SCHEMATIC_TABLE("schematics.png", 0, 121, 214, 83), + SCHEMATIC_TABLE_PROGRESS("schematics.png", 0, 204, 84, 16), - FLEXCRATE("flex_crate_and_stockpile_switch.png", 125, 129), - FLEXCRATE_DOUBLE("double_flexcrate.png", 197, 129), - FLEXCRATE_LOCKED_SLOT("flex_crate_and_stockpile_switch.png", 138, 0, 18, 18), + SCHEMATICANNON_TOP("schematics_2.png", 0, 77, 213, 42), + SCHEMATICANNON_BOTTOM("schematics_2.png", 0, 119, 213, 99), + SCHEMATICANNON_PROGRESS("schematics_2.png", 76, 239, 114, 16), + SCHEMATICANNON_CHECKLIST_PROGRESS("schematics_2.png", 191, 240, 16, 14), + SCHEMATICANNON_HIGHLIGHT("schematics_2.png", 1, 229, 26, 26), + SCHEMATICANNON_FUEL("schematics_2.png", 28, 222, 47, 16), + SCHEMATICANNON_FUEL_CREATIVE("schematics_2.png", 28, 239, 47, 16), - STOCKSWITCH("flex_crate_and_stockpile_switch.png", 0, 129, 205, 93), - STOCKSWITCH_INTERVAL("flex_crate_and_stockpile_switch.png", 0, 222, 198, 17), - STOCKSWITCH_INTERVAL_END("flex_crate_and_stockpile_switch.png", 0, 239, 198, 17), - STOCKSWITCH_CURSOR_ON("flex_crate_and_stockpile_switch.png", 218, 129, 8, 21), - STOCKSWITCH_CURSOR_OFF("flex_crate_and_stockpile_switch.png", 226, 129, 8, 21), - STOCKSWITCH_BOUND_LEFT("flex_crate_and_stockpile_switch.png", 234, 129, 7, 21), - STOCKSWITCH_BOUND_RIGHT("flex_crate_and_stockpile_switch.png", 241, 129, 7, 21), + STOCKSWITCH("logistics.png", 182, 93), + STOCKSWITCH_ARROW_UP("logistics.png", 191, 0, 7, 24), + STOCKSWITCH_ARROW_DOWN("logistics.png", 198, 0, 7, 24), + STOCKSWITCH_CURSOR("logistics.png", 206, 0, 7, 16), + STOCKSWITCH_INTERVAL("logistics.png", 0, 93, 100, 18), + STOCKSWITCH_UNPOWERED_LANE("logistics.png", 36, 18, 102, 18), + STOCKSWITCH_POWERED_LANE("logistics.png", 36, 40, 102, 18), - FILTER("filter.png", 200, 100), - ATTRIBUTE_FILTER("filter.png", 0, 100, 200, 86), + ADJUSTABLE_CRATE("logistics_2.png", 124, 127), + ADJUSTABLE_DOUBLE_CRATE("logistics_2.png", 0, 127, 196, 127), + ADJUSTABLE_CRATE_LOCKED_SLOT("logistics_2.png", 125, 109, 18, 18), - SEQUENCER("sequencer.png", 156, 128), - SEQUENCER_INSTRUCTION("sequencer.png", 14, 47, 131, 18), - SEQUENCER_WAIT("sequencer.png", 14, 65, 131, 18), - SEQUENCER_END("sequencer.png", 14, 83, 131, 18), - SEQUENCER_EMPTY("sequencer.png", 14, 101, 131, 18), + FILTER("filters.png", 214, 97), + ATTRIBUTE_FILTER("filters.png", 0, 97, 241, 83), + + SEQUENCER("sequencer.png", 173, 159), + SEQUENCER_INSTRUCTION("sequencer.png", 0, 14, 162, 22), + SEQUENCER_WAIT("sequencer.png", 0, 58, 162, 22), + SEQUENCER_END("sequencer.png", 0, 80, 162, 22), + SEQUENCER_EMPTY("sequencer.png", 0, 102, 162, 22), // JEI JEI_SLOT("jei/widgets.png", 18, 18), @@ -64,19 +68,14 @@ public enum AllGuiTextures { BLOCKZAPPER_UPGRADE_RECIPE("jei/widgets.png", 0, 75, 144, 66), // Widgets - PALETTE_BUTTON("palette_picker.png", 0, 236, 20, 20), - TEXT_INPUT("widgets.png", 0, 28, 194, 47), BUTTON("widgets.png", 18, 18), BUTTON_HOVER("widgets.png", 18, 0, 18, 18), BUTTON_DOWN("widgets.png", 36, 0, 18, 18), - INDICATOR("widgets.png", 0, 18, 18, 5), - INDICATOR_WHITE("widgets.png", 18, 18, 18, 5), - INDICATOR_GREEN("widgets.png", 0, 23, 18, 5), - INDICATOR_YELLOW("widgets.png", 18, 23, 18, 5), - INDICATOR_RED("widgets.png", 36, 23, 18, 5), - GRAY("background.png", 0, 0, 16, 16), - - BLUEPRINT_SLOT("widgets.png", 90, 0, 24, 24), + INDICATOR("widgets.png", 0, 18, 18, 6), + INDICATOR_WHITE("widgets.png", 18, 18, 18, 6), + INDICATOR_GREEN("widgets.png", 36, 18, 18, 6), + INDICATOR_YELLOW("widgets.png", 54, 18, 18, 6), + INDICATOR_RED("widgets.png", 72, 18, 18, 6), ; diff --git a/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java b/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java index af547236b..d542bfb31 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java +++ b/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java @@ -92,10 +92,14 @@ public class AllIcons { I_ARM_ROUND_ROBIN = next(), I_ARM_FORCED_ROUND_ROBIN = next(), I_ARM_PREFER_FIRST = next(), + + I_ADD_INVERTED_ATTRIBUTE = next(), + I_FLIP = next(), I_PLAY = newRow(), I_PAUSE = next(), I_STOP = next(), + I_PLACEMENT_SETTINGS = next(), I_PATTERN_SOLID = newRow(), I_PATTERN_CHECKERED = next(), @@ -105,7 +109,9 @@ public class AllIcons { I_PATTERN_CHANCE_50 = newRow(), I_PATTERN_CHANCE_75 = next(), I_FOLLOW_DIAGONAL = next(), - I_FOLLOW_MATERIAL = next(); + I_FOLLOW_MATERIAL = next(), + + I_SCHEMATIC = newRow(); public AllIcons(int x, int y) { iconX = x * 16; diff --git a/src/main/java/com/simibubi/create/foundation/gui/TextInputPromptScreen.java b/src/main/java/com/simibubi/create/foundation/gui/TextInputPromptScreen.java deleted file mode 100644 index 27a52be14..000000000 --- a/src/main/java/com/simibubi/create/foundation/gui/TextInputPromptScreen.java +++ /dev/null @@ -1,106 +0,0 @@ -package com.simibubi.create.foundation.gui; - -import java.util.function.Consumer; - -import org.lwjgl.glfw.GLFW; - -import com.simibubi.create.foundation.utility.Lang; - -import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.client.gui.widget.button.Button; - -public class TextInputPromptScreen extends AbstractSimiScreen { - - private final String defaultConfirm = Lang.translate("action.confirm"); - private final String defaultAbort = Lang.translate("action.abort"); - - private Consumer callback; - private Consumer abortCallback; - - private TextFieldWidget nameField; - private Button confirm; - private Button abort; - - private String buttonTextConfirm; - private String buttonTextAbort; - private String title; - - private boolean confirmed; - - public TextInputPromptScreen(Consumer callBack, Consumer abortCallback) { - super(); - this.callback = callBack; - this.abortCallback = abortCallback; - - buttonTextConfirm = defaultConfirm; - buttonTextAbort = defaultAbort; - confirmed = false; - } - - @Override - public void init() { - super.init(); - setWindowSize(AllGuiTextures.TEXT_INPUT.width, AllGuiTextures.TEXT_INPUT.height + 30); - - this.nameField = new TextFieldWidget(font, guiLeft + 33, guiTop + 26, 128, 8, ""); - this.nameField.setTextColor(-1); - this.nameField.setDisabledTextColour(-1); - this.nameField.setEnableBackgroundDrawing(false); - this.nameField.setMaxStringLength(35); - this.nameField.changeFocus(true); - - confirm = new Button(guiLeft - 5, guiTop + 50, 100, 20, buttonTextConfirm, button -> { - callback.accept(nameField.getText()); - confirmed = true; - minecraft.displayGuiScreen(null); - }); - - abort = new Button(guiLeft + 100, guiTop + 50, 100, 20, buttonTextAbort, button -> { - minecraft.displayGuiScreen(null); - }); - - widgets.add(confirm); - widgets.add(abort); - widgets.add(nameField); - } - - @Override - public void renderWindow(int mouseX, int mouseY, float partialTicks) { - AllGuiTextures.TEXT_INPUT.draw(this, guiLeft, guiTop); - font.drawString(title, guiLeft + (sWidth / 2) - (font.getStringWidth(title) / 2), guiTop + 11, - AllGuiTextures.FONT_COLOR); - } - - @Override - public void removed() { - if (!confirmed) - abortCallback.accept(nameField.getText()); - super.removed(); - } - - public void setButtonTextConfirm(String buttonTextConfirm) { - this.buttonTextConfirm = buttonTextConfirm; - } - - public void setButtonTextAbort(String buttonTextAbort) { - this.buttonTextAbort = buttonTextAbort; - } - - public void setTitle(String title) { - this.title = title; - } - - @Override - public boolean keyPressed(int keyCode, int p_keyPressed_2_, int p_keyPressed_3_) { - if (keyCode == GLFW.GLFW_KEY_ENTER) { - confirm.onPress(); - return true; - } - if (keyCode == 256 && this.shouldCloseOnEsc()) { - this.onClose(); - return true; - } - return nameField.keyPressed(keyCode, p_keyPressed_2_, p_keyPressed_3_); - } - -} diff --git a/src/main/java/com/simibubi/create/foundation/gui/ToolSelectionScreen.java b/src/main/java/com/simibubi/create/foundation/gui/ToolSelectionScreen.java index 8ec08b02c..d49a94861 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/ToolSelectionScreen.java +++ b/src/main/java/com/simibubi/create/foundation/gui/ToolSelectionScreen.java @@ -63,7 +63,7 @@ public class ToolSelectionScreen extends Screen { RenderSystem.pushMatrix(); RenderSystem.translatef(0, -yOffset, focused ? 100 : 0); - AllGuiTextures gray = AllGuiTextures.GRAY; + AllGuiTextures gray = AllGuiTextures.HUD_BACKGROUND; RenderSystem.enableBlend(); RenderSystem.color4f(1, 1, 1, focused ? 7 / 8f : 1 / 2f); diff --git a/src/main/java/com/simibubi/create/foundation/gui/widgets/ScrollInput.java b/src/main/java/com/simibubi/create/foundation/gui/widgets/ScrollInput.java index 415fae287..69fda4a82 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/widgets/ScrollInput.java +++ b/src/main/java/com/simibubi/create/foundation/gui/widgets/ScrollInput.java @@ -45,6 +45,11 @@ public class ScrollInput extends AbstractSimiWidget { this.onScroll = onScroll; return this; } + + public ScrollInput removeCallback() { + this.onScroll = null; + return this; + } public ScrollInput titled(String title) { this.title = title; diff --git a/src/main/java/com/simibubi/create/foundation/item/SmartInventory.java b/src/main/java/com/simibubi/create/foundation/item/SmartInventory.java index 7e5050848..19773a317 100644 --- a/src/main/java/com/simibubi/create/foundation/item/SmartInventory.java +++ b/src/main/java/com/simibubi/create/foundation/item/SmartInventory.java @@ -10,17 +10,29 @@ import net.minecraftforge.common.util.INBTSerializable; import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.wrapper.RecipeWrapper; -public class SmartInventory extends RecipeWrapper implements IItemHandlerModifiableIntermediate, INBTSerializable { +public class SmartInventory extends RecipeWrapper + implements IItemHandlerModifiableIntermediate, INBTSerializable { - private boolean extractionAllowed; - private boolean insertionAllowed; - private int stackSize; + protected boolean extractionAllowed; + protected boolean insertionAllowed; + protected boolean stackNonStackables; + protected int stackSize; public SmartInventory(int slots, SyncedTileEntity te) { - super(new SyncedStackHandler(slots, te)); + this(slots, te, 64, false); + } + + public SmartInventory(int slots, SyncedTileEntity te, int stackSize, boolean stackNonStackables) { + super(new SyncedStackHandler(slots, te, stackNonStackables, stackSize)); + this.stackNonStackables = stackNonStackables; insertionAllowed = true; extractionAllowed = true; - stackSize = 64; + this.stackSize = stackSize; + } + + public SmartInventory whenContentsChanged(Runnable updateCallback) { + ((SyncedStackHandler) inv).whenContentsChange(updateCallback); + return this; } public SmartInventory allowInsertion() { @@ -43,11 +55,6 @@ public class SmartInventory extends RecipeWrapper implements IItemHandlerModifia return this; } - public SmartInventory withMaxStackSize(int stackSize) { - this.stackSize = stackSize; - return this; - } - @Override public int getSlots() { return inv.getSlots(); @@ -64,6 +71,11 @@ public class SmartInventory extends RecipeWrapper implements IItemHandlerModifia public ItemStack extractItem(int slot, int amount, boolean simulate) { if (!extractionAllowed) return ItemStack.EMPTY; + if (stackNonStackables) { + ItemStack extractItem = inv.extractItem(slot, amount, true); + if (!extractItem.isEmpty() && extractItem.getMaxStackSize() < extractItem.getCount()) + amount = extractItem.getMaxStackSize(); + } return inv.extractItem(slot, amount, simulate); } @@ -86,7 +98,7 @@ public class SmartInventory extends RecipeWrapper implements IItemHandlerModifia public ItemStack getStackInSlot(int slot) { return super.getStackInSlot(slot); } - + public int getStackLimit(int slot, @Nonnull ItemStack stack) { return Math.min(getSlotLimit(slot), stack.getMaxStackSize()); } @@ -100,7 +112,7 @@ public class SmartInventory extends RecipeWrapper implements IItemHandlerModifia public void deserializeNBT(CompoundNBT nbt) { getInv().deserializeNBT(nbt); } - + private SyncedStackHandler getInv() { return (SyncedStackHandler) inv; } @@ -108,18 +120,34 @@ public class SmartInventory extends RecipeWrapper implements IItemHandlerModifia private static class SyncedStackHandler extends ItemStackHandler { private SyncedTileEntity te; + private boolean stackNonStackables; + private int stackSize; + private Runnable updateCallback; - public SyncedStackHandler(int slots, SyncedTileEntity te) { + public SyncedStackHandler(int slots, SyncedTileEntity te, boolean stackNonStackables, int stackSize) { super(slots); this.te = te; + this.stackNonStackables = stackNonStackables; + this.stackSize = stackSize; } @Override protected void onContentsChanged(int slot) { super.onContentsChanged(slot); + if (updateCallback != null) + updateCallback.run(); te.notifyUpdate(); } + @Override + public int getSlotLimit(int slot) { + return Math.min(stackNonStackables ? 64 : super.getSlotLimit(slot), stackSize); + } + + public void whenContentsChange(Runnable updateCallback) { + this.updateCallback = updateCallback; + } + } @Override 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 5200f3255..b1e6a8a25 100644 --- a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java +++ b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java @@ -10,6 +10,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.glu import com.simibubi.create.content.contraptions.components.structureMovement.sync.ClientMotionPacket; 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; import com.simibubi.create.content.contraptions.components.structureMovement.train.MinecartCouplingCreationPacket; import com.simibubi.create.content.contraptions.components.structureMovement.train.MinecartCouplingSyncPacket; import com.simibubi.create.content.contraptions.components.structureMovement.train.PersistantDataPacket; @@ -23,6 +24,7 @@ import com.simibubi.create.content.logistics.item.filter.FilterScreenPacket; import com.simibubi.create.content.logistics.packet.ConfigureFlexcratePacket; 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.foundation.command.ConfigureConfigPacket; @@ -55,6 +57,7 @@ public enum AllPackets { PLACE_ARM(ArmPlacementPacket.class, ArmPlacementPacket::new), MINECART_COUPLING_CREATION(MinecartCouplingCreationPacket.class, MinecartCouplingCreationPacket::new), PERSISTANT_DATA_REQUEST(PersistantDataPacketRequest.class, PersistantDataPacketRequest::new), + INSTANT_SCHEMATIC(InstantSchematicPacket.class, InstantSchematicPacket::new), // Server to Client SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new), @@ -66,6 +69,7 @@ public enum AllPackets { MINECART_COUPLING_SYNC(MinecartCouplingSyncPacket.class, MinecartCouplingSyncPacket::new), CONTRAPTION_SEAT_MAPPING(ContraptionSeatMappingPacket.class, ContraptionSeatMappingPacket::new), PERSISTANT_DATA(PersistantDataPacket.class, PersistantDataPacket::new), + LIMBSWING_UPDATE(LimbSwingUpdatePacket.class, LimbSwingUpdatePacket::new), ; diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/fluid/SmartFluidTankBehaviour.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/fluid/SmartFluidTankBehaviour.java index 810f84b60..445ab0a91 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/fluid/SmartFluidTankBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/fluid/SmartFluidTankBehaviour.java @@ -34,6 +34,7 @@ public class SmartFluidTankBehaviour extends TileEntityBehaviour { protected LazyOptional capability; protected boolean extractionAllowed; protected boolean insertionAllowed; + protected Runnable fluidUpdateCallback; private BehaviourType behaviourType; @@ -55,6 +56,13 @@ public class SmartFluidTankBehaviour extends TileEntityBehaviour { handlers[i] = tankSegment.tank; } capability = LazyOptional.of(() -> new InternalFluidHandler(handlers, enforceVariety)); + fluidUpdateCallback = () -> { + }; + } + + public SmartFluidTankBehaviour whenFluidUpdates(Runnable fluidUpdateCallback) { + this.fluidUpdateCallback = fluidUpdateCallback; + return this; } public SmartFluidTankBehaviour allowInsertion() { @@ -76,7 +84,7 @@ public class SmartFluidTankBehaviour extends TileEntityBehaviour { extractionAllowed = false; return this; } - + @Override public void initialize() { super.initialize(); @@ -84,7 +92,7 @@ public class SmartFluidTankBehaviour extends TileEntityBehaviour { return; foreach(ts -> { ts.fluidLevel.forceNextSync(); - ts.onFluidStackChanged(ts.tank.getFluid()); + ts.onFluidStackChanged(); }); } @@ -94,8 +102,8 @@ public class SmartFluidTankBehaviour extends TileEntityBehaviour { if (syncCooldown > 0) { syncCooldown--; - if (syncCooldown == 0 && queuedSync) - tileEntity.sendData(); + if (syncCooldown == 0 && queuedSync) + updateFluids(); } foreach(te -> { @@ -108,7 +116,7 @@ public class SmartFluidTankBehaviour extends TileEntityBehaviour { public void sendDataImmediately() { syncCooldown = 0; queuedSync = false; - tileEntity.sendData(); + updateFluids(); } public void sendDataLazily() { @@ -116,11 +124,16 @@ public class SmartFluidTankBehaviour extends TileEntityBehaviour { queuedSync = true; return; } - tileEntity.sendData(); + updateFluids(); queuedSync = false; syncCooldown = SYNC_RATE; } + protected void updateFluids() { + fluidUpdateCallback.run(); + tileEntity.sendData(); + } + @Override public void remove() { super.remove(); @@ -174,36 +187,36 @@ public class SmartFluidTankBehaviour extends TileEntityBehaviour { index.increment(); }); } - + class InternalFluidHandler extends CombinedTankWrapper { - + public InternalFluidHandler(IFluidHandler[] handlers, boolean enforceVariety) { super(handlers); if (enforceVariety) enforceVariety(); } - + @Override public int fill(FluidStack resource, FluidAction action) { if (!insertionAllowed) return 0; return super.fill(resource, action); } - + @Override public FluidStack drain(FluidStack resource, FluidAction action) { if (!extractionAllowed) return FluidStack.EMPTY; return super.drain(resource, action); } - + @Override public FluidStack drain(int maxDrain, FluidAction action) { if (!extractionAllowed) return FluidStack.EMPTY; return super.drain(maxDrain, action); } - + } public class TankSegment { @@ -213,14 +226,14 @@ public class SmartFluidTankBehaviour extends TileEntityBehaviour { protected FluidStack renderedFluid; public TankSegment(int capacity) { - tank = new SmartFluidTank(1000, f -> onFluidStackChanged(f)); + tank = new SmartFluidTank(1000, f -> onFluidStackChanged()); fluidLevel = LerpedFloat.linear() .startWithValue(0) .chase(0, .25, Chaser.EXP); renderedFluid = FluidStack.EMPTY; } - protected void onFluidStackChanged(FluidStack newFluidStack) { + public void onFluidStackChanged() { if (!tileEntity.hasWorld()) return; fluidLevel.chase(tank.getFluidAmount() / (float) tank.getCapacity(), .25, Chaser.EXP); @@ -235,7 +248,7 @@ public class SmartFluidTankBehaviour extends TileEntityBehaviour { public LerpedFloat getFluidLevel() { return fluidLevel; } - + public float getTotalUnits(float partialTicks) { return fluidLevel.getValue(partialTicks) * tank.getCapacity(); } diff --git a/src/main/resources/assets/create/lang/default/messages.json b/src/main/resources/assets/create/lang/default/messages.json index 0c2536fc2..7ef4f7db8 100644 --- a/src/main/resources/assets/create/lang/default/messages.json +++ b/src/main/resources/assets/create/lang/default/messages.json @@ -158,13 +158,10 @@ "create.gui.adjustable_crate.storageSpace": "Storage Space", "create.gui.stockpile_switch.title": "Stockpile Switch", - "create.gui.stockpile_switch.lowerLimit": "Lower Threshold", - "create.gui.stockpile_switch.upperLimit": "Upper Threshold", - "create.gui.stockpile_switch.startAt": "Start Signal at", - "create.gui.stockpile_switch.startAbove": "Start Signal above", - "create.gui.stockpile_switch.stopAt": "Stop Signal at", - "create.gui.stockpile_switch.stopBelow": "Stop Signal below", - + "create.gui.stockpile_switch.invert_signal": "Invert Signal", + "create.gui.stockpile_switch.move_to_lower_at": "Move to lower lane at %1$s%%", + "create.gui.stockpile_switch.move_to_upper_at": "Move to upper lane at %1$s%%", + "create.gui.sequenced_gearshift.title": "Sequenced Gearshift", "create.gui.sequenced_gearshift.instruction": "Instruction", "create.gui.sequenced_gearshift.instruction.turn_angle": "Turn", @@ -185,7 +182,8 @@ "create.schematicAndQuill.secondPos": "Second position set.", "create.schematicAndQuill.noTarget": "Hold [Ctrl] to select Air blocks.", "create.schematicAndQuill.abort": "Removed selection.", - "create.schematicAndQuill.prompt": "Enter a name for the Schematic:", + "create.schematicAndQuill.title": "Schematic Name:", + "create.schematicAndQuill.convert": "Save and Deploy Immediately", "create.schematicAndQuill.fallbackName": "My Schematic", "create.schematicAndQuill.saved": "Saved as %1$s", @@ -234,9 +232,12 @@ "create.schematic.tool.flip.description.3": "", "create.schematics.synchronizing": "Syncing...", - "create.schematics.uploadTooLarge": "Your schematic is too big.", + "create.schematics.uploadTooLarge": "Your schematic exceeds limitations specified by the server.", "create.schematics.maxAllowedSize": "The maximum allowed schematic file size is:", + "create.gui.schematicTable.title": "Schematic Table", + "create.gui.schematicTable.refresh": "Refresh Files", + "create.gui.schematicTable.open_folder": "Open Folder", "create.gui.schematicTable.title": "Schematic Table", "create.gui.schematicTable.availableSchematics": "Available Schematics", "create.gui.schematicTable.noSchematics": "No Schematics Saved", @@ -244,19 +245,23 @@ "create.gui.schematicTable.finished": "Upload Finished!", "create.gui.schematicannon.title": "Schematicannon", - "create.gui.schematicannon.settingsTitle": "Placement Settings", - "create.gui.schematicannon.listPrinter": "Material List Printer", + "create.gui.schematicannon.listPrinter": "Checklist Printer", "create.gui.schematicannon.gunpowderLevel": "Gunpowder at %1$s%%", "create.gui.schematicannon.shotsRemaining": "Shots left: %1$s", "create.gui.schematicannon.shotsRemainingWithBackup": "With backup: %1$s", "create.gui.schematicannon.optionEnabled": "Currently Enabled", "create.gui.schematicannon.optionDisabled": "Currently Disabled", + "create.gui.schematicannon.showOptions": "Show Printer Settings", "create.gui.schematicannon.option.dontReplaceSolid": "Don't Replace Solid Blocks", "create.gui.schematicannon.option.replaceWithSolid": "Replace Solid with Solid", "create.gui.schematicannon.option.replaceWithAny": "Replace Solid with Any", "create.gui.schematicannon.option.replaceWithEmpty": "Replace Solid with Empty", "create.gui.schematicannon.option.skipMissing": "Skip missing Blocks", "create.gui.schematicannon.option.skipTileEntities": "Protect Tile Entities", + + "create.gui.schematicannon.slot.gunpowder": "Add gunpowder to fuel the cannon", + "create.gui.schematicannon.slot.listPrinter": "Place books here to print a Checklist for your Schematic", + "create.gui.schematicannon.slot.schematic": "Add your Schematic here. Make sure it is deployed at a specific location.", "create.gui.schematicannon.option.skipMissing.description": "If the cannon cannot find a required Block for placement, it will continue at the next Location.", "create.gui.schematicannon.option.skipTileEntities.description": "The cannon will avoid replacing data holding blocks such as Chests.", @@ -293,23 +298,42 @@ "create.gui.filter.ignore_data.description": "Items match regardless of their attributes.", "create.item_attributes.placeable": "is placeable", + "create.item_attributes.placeable.inverted": "is not placeable", "create.item_attributes.consumable": "can be eaten", + "create.item_attributes.consumable.inverted": "cannot be eaten", "create.item_attributes.smeltable": "can be Smelted", + "create.item_attributes.smeltable.inverted": "cannot be Smelted", "create.item_attributes.washable": "can be Washed", + "create.item_attributes.washable.inverted": "cannot be Washed", "create.item_attributes.smokable": "can be Smoked", + "create.item_attributes.smokable.inverted": "cannot be Smoked", + "create.item_attributes.crushable": "can be Crushed", + "create.item_attributes.crushable.inverted": "cannot be Crushed", "create.item_attributes.blastable": "is smeltable in Blast Furnace", + "create.item_attributes.blastable.inverted": "is not smeltable in Blast Furnace", "create.item_attributes.enchanted": "is enchanted", + "create.item_attributes.enchanted.inverted": "is unenchanted", "create.item_attributes.damaged": "is damaged", + "create.item_attributes.damaged.inverted": "is not damaged", "create.item_attributes.badly_damaged": "is heavily damaged", + "create.item_attributes.badly_damaged.inverted": "is not heavily damaged", "create.item_attributes.not_stackable": "cannot stack", + "create.item_attributes.not_stackable.inverted": "can be stacked", "create.item_attributes.equipable": "can be equipped", + "create.item_attributes.equipable.inverted": "cannot be equipped", "create.item_attributes.furnace_fuel": "is furnace fuel", + "create.item_attributes.furnace_fuel.inverted": "is not furnace fuel", "create.item_attributes.in_tag": "is tagged %1$s", - "create.item_attributes.in_item_group": "belongs to %1$s", + "create.item_attributes.in_tag.inverted": "is not tagged %1$s", + "create.item_attributes.in_item_group": "is in group '%1$s'", + "create.item_attributes.in_item_group.inverted": "is not in group '%1$s'", "create.item_attributes.added_by": "was added by %1$s", + "create.item_attributes.added_by.inverted": "was not added by %1$s", "create.gui.attribute_filter.no_selected_attributes": "No attributes selected", "create.gui.attribute_filter.selected_attributes": "Selected attributes:", + "create.gui.attribute_filter.add_attribute": "Add attribute to List", + "create.gui.attribute_filter.add_inverted_attribute": "Add opposite attribute to List", "create.gui.attribute_filter.whitelist_disjunctive": "Whitelist (Any)", "create.gui.attribute_filter.whitelist_disjunctive.description": "Items pass if they have any of the selected attributes.", "create.gui.attribute_filter.whitelist_conjunctive": "Whitelist (All)", diff --git a/src/main/resources/assets/create/models/block/basin/basin_canal.bbmodel b/src/main/resources/assets/create/models/block/basin/basin_canal.bbmodel new file mode 100644 index 000000000..63122598a --- /dev/null +++ b/src/main/resources/assets/create/models/block/basin/basin_canal.bbmodel @@ -0,0 +1 @@ +{"meta":{"format_version":"3.2","model_format":"java_block","box_uv":false},"name":"basin","parent":"block/block","ambientocclusion":true,"front_gui_light":false,"resolution":{"width":16,"height":16},"elements":[{"name":"Side1","from":[0,2,0],"to":[2,16,16],"autouv":0,"color":2,"locked":false,"origin":[8,24,8],"faces":{"north":{"uv":[14,0,16,14],"texture":0},"east":{"uv":[0,0,16,14],"texture":0},"south":{"uv":[0,0,2,14],"texture":0},"west":{"uv":[0,0,16,14],"texture":0},"up":{"uv":[0,0,2,16],"texture":1},"down":{"uv":[0,0,2,16],"texture":1}},"uuid":"e372420e-1abe-a2b9-ae96-df6b128888ad"},{"name":"BasinBottom","from":[2,0,2],"to":[14,2,14],"autouv":0,"color":0,"locked":false,"origin":[8,25,8],"faces":{"north":{"uv":[2,14,14,16],"texture":0},"east":{"uv":[2,14,14,16],"texture":0},"south":{"uv":[2,14,14,16],"texture":0},"west":{"uv":[2,14,14,16],"texture":0},"up":{"uv":[2,2,14,14],"texture":1},"down":{"uv":[2,2,14,14],"texture":1}},"uuid":"e82556b1-3f66-7c35-71b2-f33c0c4c1385"},{"name":"Side4","from":[2,2,0],"to":[14,16,2],"autouv":0,"color":1,"locked":false,"origin":[8,24,8],"faces":{"north":{"uv":[2,0,14,14],"texture":0},"east":{"uv":[0,0,0,0],"texture":null},"south":{"uv":[2,0,14,14],"texture":0},"west":{"uv":[0,0,0,0],"texture":null},"up":{"uv":[2,0,14,2],"texture":1},"down":{"uv":[2,14,14,16],"texture":1}},"uuid":"2e5cfd25-7f80-2f04-e080-b005bc67fecb"},{"name":"Side2","from":[2,2,14],"to":[14,16,16],"autouv":0,"color":4,"locked":false,"origin":[8,24,8],"faces":{"north":{"uv":[2,0,14,14],"texture":0},"east":{"uv":[0,0,0,0],"texture":null},"south":{"uv":[2,0,14,14],"texture":0},"west":{"uv":[0,0,0,0],"texture":null},"up":{"uv":[2,14,14,16],"texture":1},"down":{"uv":[2,0,14,2],"texture":1}},"uuid":"e007a6de-4ee0-52db-0763-61d4c3ab8a3f"},{"name":"Side3","from":[14,2,0],"to":[16,16,16],"autouv":0,"color":5,"locked":false,"origin":[8,40,8],"faces":{"north":{"uv":[0,0,2,14],"texture":0},"east":{"uv":[0,0,16,14],"texture":0},"south":{"uv":[14,0,16,14],"texture":0},"west":{"uv":[0,0,16,14],"texture":0},"up":{"uv":[14,0,16,16],"texture":1},"down":{"uv":[14,0,16,16],"texture":1}},"uuid":"c5b067a4-6114-bb79-a5bf-1321988a497c"},{"name":"Side2","from":[0,-14,-16],"to":[2,0,0],"autouv":0,"color":2,"locked":false,"origin":[8,8,-8],"faces":{"north":{"uv":[14,0,16,14],"texture":0},"east":{"uv":[0,0,16,14],"texture":0},"south":{"uv":[0,0,2,14],"texture":0},"west":{"uv":[0,0,16,14],"texture":0},"up":{"uv":[0,0,2,16],"texture":1},"down":{"uv":[0,0,2,16],"texture":1}},"uuid":"b641f651-2872-3ebc-e9e3-2dfbbb10e8e4"},{"name":"BasinBottom","from":[2,-16,-14],"to":[14,-14,-2],"autouv":0,"color":0,"locked":false,"origin":[8,9,-8],"faces":{"north":{"uv":[2,14,14,16],"texture":0},"east":{"uv":[2,14,14,16],"texture":0},"south":{"uv":[2,14,14,16],"texture":0},"west":{"uv":[2,14,14,16],"texture":0},"up":{"uv":[2,2,14,14],"texture":1},"down":{"uv":[2,2,14,14],"texture":1}},"uuid":"07500784-c31b-dc51-7e03-f0ec55ee6028"},{"name":"Side5","from":[2,-14,-16],"to":[14,0,-14],"autouv":0,"color":1,"locked":false,"origin":[8,8,-8],"faces":{"north":{"uv":[2,0,14,14],"texture":0},"east":{"uv":[0,0,0,0],"texture":null},"south":{"uv":[2,0,14,14],"texture":0},"west":{"uv":[0,0,0,0],"texture":null},"up":{"uv":[2,0,14,2],"texture":1},"down":{"uv":[2,14,14,16],"texture":1}},"uuid":"dd76fad0-e0ed-1147-e7bd-3870f72987da"},{"name":"Side3","from":[2,-14,-2],"to":[14,0,0],"autouv":0,"color":4,"locked":false,"origin":[8,8,-8],"faces":{"north":{"uv":[2,0,14,14],"texture":0},"east":{"uv":[0,0,0,0],"texture":null},"south":{"uv":[2,0,14,14],"texture":0},"west":{"uv":[0,0,0,0],"texture":null},"up":{"uv":[2,14,14,16],"texture":1},"down":{"uv":[2,0,14,2],"texture":1}},"uuid":"32636eab-627e-34f5-7be6-2a31400bd957"},{"name":"Side4","from":[14,-14,-16],"to":[16,0,0],"autouv":0,"color":5,"locked":false,"origin":[8,24,-8],"faces":{"north":{"uv":[0,0,2,14],"texture":0},"east":{"uv":[0,0,16,14],"texture":0},"south":{"uv":[14,0,16,14],"texture":0},"west":{"uv":[0,0,16,14],"texture":0},"up":{"uv":[14,0,16,16],"texture":1},"down":{"uv":[14,0,16,16],"texture":1}},"uuid":"06344246-e61c-e8fd-c700-dae02563797e"},{"name":"cube","from":[3,0,0],"to":[4,2,2],"autouv":0,"color":6,"locked":false,"origin":[11,8,8],"faces":{"north":{"uv":[0,0,10,2],"texture":2},"east":{"uv":[14,10,16,12],"texture":2},"south":{"uv":[14,10,16,11],"rotation":90,"texture":2},"west":{"uv":[14,10,16,12],"rotation":90,"texture":2},"up":{"uv":[14,10,15,12],"rotation":180,"texture":2},"down":{"uv":[15,10,16,12],"texture":2}},"uuid":"41346be7-9b03-225c-14be-3be6e1719311"},{"name":"cube","from":[3,0,-1],"to":[4,10,0],"autouv":0,"color":6,"locked":false,"origin":[11,8,7],"faces":{"north":{"uv":[6,12,16,13],"rotation":90,"texture":2},"east":{"uv":[6,12,16,13],"rotation":90,"texture":2},"south":{"uv":[6,12,16,13],"rotation":90,"texture":2},"west":{"uv":[6,12,16,13],"rotation":90,"texture":2},"up":{"uv":[6,12,7,13],"texture":2},"down":{"uv":[15,12,16,13],"texture":2}},"uuid":"fa4b61d1-8e47-aa7d-207c-025608871716"},{"name":"cube","from":[5,1,-6],"to":[11,2,3],"autouv":0,"color":4,"locked":false,"rotation":[-22.5,0,0],"origin":[8,9,-1],"faces":{"north":{"uv":[9,7,15,8],"texture":2},"east":{"uv":[0,0,9,1],"texture":2},"south":{"uv":[9,7,15,8],"texture":2},"west":{"uv":[0,0,9,1],"texture":2},"up":{"uv":[1,0,7,9],"texture":2},"down":{"uv":[1,0,7,9],"rotation":180,"texture":2}},"uuid":"c4b10bec-d6bb-cac8-b369-d588c98601ce"},{"name":"cube","from":[4,1,-6],"to":[5,9,3],"autouv":0,"color":4,"locked":false,"rotation":[-22.5,0,0],"origin":[8,9,-1],"faces":{"north":{"uv":[15,0,16,8],"texture":2},"east":{"uv":[0,0,8,9],"rotation":90,"texture":2},"south":{"uv":[8,0,9,8],"texture":2},"west":{"uv":[0,0,8,9],"rotation":90,"texture":2},"up":{"uv":[0,0,1,9],"rotation":180,"texture":2},"down":{"uv":[0,0,1,9],"texture":2}},"uuid":"655e4f5c-68aa-c6ca-ea54-6ee2f1eb0cbf"},{"name":"cube","from":[11,1,-6],"to":[12,9,3],"autouv":0,"color":4,"locked":false,"rotation":[-22.5,0,0],"origin":[15,9,-1],"faces":{"north":{"uv":[8,0,9,8],"texture":2},"east":{"uv":[0,0,8,9],"rotation":270,"texture":2},"south":{"uv":[15,0,16,8],"texture":2},"west":{"uv":[0,0,8,9],"rotation":90,"texture":2},"up":{"uv":[0,0,1,9],"rotation":180,"texture":2},"down":{"uv":[0,0,1,9],"texture":2}},"uuid":"cf5d8d2d-6849-5958-087c-a48f1ab945e5"},{"name":"cube","from":[5,8,-6],"to":[11,9,3],"autouv":0,"color":4,"locked":false,"rotation":[-22.5,0,0],"origin":[8,9,-1],"faces":{"north":{"uv":[9,0,15,1],"texture":2},"east":{"uv":[0,0,9,1],"texture":2},"south":{"uv":[9,0,15,1],"texture":2},"west":{"uv":[0,0,9,1],"texture":2},"up":{"uv":[1,0,7,9],"rotation":180,"texture":2},"down":{"uv":[1,0,7,9],"texture":2}},"uuid":"1655c96c-ae98-f14d-527c-6052c1fab719"},{"name":"cube","from":[5,2,-4],"to":[11,8,2],"autouv":0,"color":4,"locked":false,"rotation":[-22.5,0,0],"origin":[8,9,-1],"faces":{"north":{"uv":[9,1,15,7],"texture":2},"east":{"uv":[0,0,0,0],"texture":null},"south":{"uv":[9,1,15,7],"texture":2},"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":"a2eb892a-15a7-46c2-d526-c062c9c151ba"},{"name":"cube","from":[12,0,-1],"to":[13,10,0],"autouv":0,"color":6,"locked":false,"origin":[20,8,7],"faces":{"north":{"uv":[6,12,16,13],"rotation":90,"texture":2},"east":{"uv":[6,12,16,13],"rotation":90,"texture":2},"south":{"uv":[6,12,16,13],"rotation":90,"texture":2},"west":{"uv":[6,12,16,13],"rotation":90,"texture":2},"up":{"uv":[6,12,7,13],"texture":2},"down":{"uv":[15,12,16,13],"texture":2}},"uuid":"baaf226d-53b0-814c-ca53-75621435fc45"},{"name":"cube","from":[4,9,-1],"to":[12,10,0],"autouv":0,"color":6,"locked":false,"origin":[12,8,7],"faces":{"north":{"uv":[8,9,16,10],"texture":2},"east":{"uv":[0,0,0,0],"rotation":90,"texture":null},"south":{"uv":[8,9,16,10],"texture":2},"west":{"uv":[0,0,0,0],"rotation":90,"texture":null},"up":{"uv":[8,9,16,10],"texture":2},"down":{"uv":[0,0,0,0],"texture":null}},"uuid":"7aebcd85-9ae9-b4b0-9af3-a8a96d6e3709"},{"name":"cube","from":[12,0,0],"to":[13,2,2],"autouv":0,"color":6,"locked":false,"origin":[20,8,8],"faces":{"north":{"uv":[0,0,10,2],"texture":2},"east":{"uv":[14,10,16,12],"texture":2},"south":{"uv":[14,10,16,11],"rotation":90,"texture":2},"west":{"uv":[14,10,16,12],"rotation":90,"texture":2},"up":{"uv":[14,10,15,12],"rotation":180,"texture":2},"down":{"uv":[15,10,16,12],"texture":2}},"uuid":"25e35b80-a713-fd17-aac6-033104233acd"},{"name":"cube","from":[4,0,-1],"to":[12,1,2],"autouv":0,"color":6,"locked":false,"origin":[12,8,7],"faces":{"north":{"uv":[7,15,15,16],"texture":2},"east":{"uv":[14,10,16,12],"texture":2},"south":{"uv":[8,14,9,15],"rotation":90,"texture":2},"west":{"uv":[14,10,16,12],"rotation":90,"texture":2},"up":{"uv":[11,10,12,11],"rotation":180,"texture":2},"down":{"uv":[7,13,15,16],"texture":2}},"uuid":"18b2aeec-e7d6-9262-7e3d-995f9d7320ac"}],"outliner":[{"name":"Basins","uuid":"4822b3b4-2c19-aadd-c096-85534b94f809","export":true,"isOpen":false,"locked":false,"visibility":true,"autouv":0,"origin":[8,8,8],"children":[{"name":"Basin top","uuid":"ef36da1c-a925-5b8d-5f56-b9b2136ca98f","export":true,"isOpen":false,"locked":false,"visibility":true,"autouv":0,"origin":[8,8,8],"children":["e372420e-1abe-a2b9-ae96-df6b128888ad","e82556b1-3f66-7c35-71b2-f33c0c4c1385","2e5cfd25-7f80-2f04-e080-b005bc67fecb","e007a6de-4ee0-52db-0763-61d4c3ab8a3f","c5b067a4-6114-bb79-a5bf-1321988a497c"]},{"name":"Basin bottom","uuid":"52077833-3587-b2ad-4a2a-8a61173f4d54","export":true,"isOpen":false,"locked":false,"visibility":true,"autouv":0,"origin":[8,8,8],"children":["b641f651-2872-3ebc-e9e3-2dfbbb10e8e4","07500784-c31b-dc51-7e03-f0ec55ee6028","dd76fad0-e0ed-1147-e7bd-3870f72987da","32636eab-627e-34f5-7be6-2a31400bd957","06344246-e61c-e8fd-c700-dae02563797e"]}]},{"name":"Canal","uuid":"c916ca14-dcb2-5442-2b8a-1fa3ea05e167","export":true,"isOpen":false,"locked":false,"visibility":true,"autouv":0,"origin":[8,8,8],"children":[{"name":"Frame","uuid":"1dfe7732-4e1a-7674-3237-0ecf68c5c60e","export":true,"isOpen":true,"locked":false,"visibility":true,"autouv":0,"origin":[8,8,8],"children":["41346be7-9b03-225c-14be-3be6e1719311","25e35b80-a713-fd17-aac6-033104233acd","18b2aeec-e7d6-9262-7e3d-995f9d7320ac","fa4b61d1-8e47-aa7d-207c-025608871716","7aebcd85-9ae9-b4b0-9af3-a8a96d6e3709","baaf226d-53b0-814c-ca53-75621435fc45"]},"c4b10bec-d6bb-cac8-b369-d588c98601ce","1655c96c-ae98-f14d-527c-6052c1fab719","a2eb892a-15a7-46c2-d526-c062c9c151ba","cf5d8d2d-6849-5958-087c-a48f1ab945e5","655e4f5c-68aa-c6ca-ea54-6ee2f1eb0cbf"]}],"textures":[{"path":"C:\\Users\\krypp\\Desktop\\create 1.15.2\\assets\\create\\textures\\block\\basin_side.png","name":"basin_side.png","folder":"block","namespace":"create","id":"1","particle":false,"mode":"bitmap","saved":true,"uuid":"a20a92f6-149c-8147-a096-ebf6df449714","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAB4UlEQVQ4T2VTy27bMBAcAhVF2bAlpacATr/BQFs7pzy+I0Bv6cXH9Fd8aT4p7U8UObVoTMe1JUoHFrMUJSchIOxyuTuaHXLV19tbn2gNrswYsVzjNO19OnvnZF/VdR9vmwbq5uaLH49SEISBaJkVgRnfHxyYRys/6Hx1cXHlnatRFCWqqpJD7tPUIMsyiXHPFXMYt3YjOWq5PPfGZAA88ryA66hOJtMXLXDTNK4/j8BqPp97rQ3KskQqfSsMxR5N00BrxoPPtd1a1J0WarE490VRyIExRpIJlCQJ2rZFkmi0bdPb3W4nuQSo6wrq8vLas4BtaK07FsBoNMbhcBCgJHknPtkNbXhYawlw5SkGPzKIYvHvchMdE+5ZHER2AwOKmOel9DidFkjT8CZIfWgj6Ri81UEYeB/650cBh76DDjxXircQRIwMnKugFoulL8sTOWAbQXH6ursBMtHY7/+JRhRRxFMKm80T1Le7O//w42cnYigOtxEAuEiRf2VRLKb9/Okj1Gq18tbu8Pj4S0C4yIKCRfs69vxsMZt9QFFMoOIwxTngQHFgjgeLADFGezwzKr5XAv192vZaHL/jOAvUiP77kxzf7++ltgdgK0T+/WfTD08siAKz+Gx2KlO6Xq+l9j+hVCuQux00ywAAAABJRU5ErkJggg=="},{"path":"C:\\Users\\krypp\\Desktop\\create 1.15.2\\assets\\create\\textures\\block\\basin.png","name":"basin.png","folder":"block","namespace":"create","id":"12","particle":true,"mode":"bitmap","saved":true,"uuid":"e8bd46f1-4674-7125-0c6a-15be8f476bed","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABmElEQVQ4T41TyU7DMBB9dpykS8oFKIhFwMfBpcdy4sJXcuHAIhaxHgJp3cR2jGaiJG0poiNFHsfxy7w388TZ6akPowgU3U6HV4p+HDd5nUzyvHmnZzOYooAYjUb+8fGFD8Iw5LXXbYFoP9Wz5qIxpskPDnZbgKJo0ZUKIQUAIaCURFkCZenhnIVzrqqwn2BnZxPifDz2d/dPmEwydLsdKBUgzw1fEEIgigI452Gt4XOtC863t7Yw2OgvAhAFIYA4jvhDKQW89/AenNPfCdRayxUcH+1XAG9vn0jTFKUvIYSsLvxBgconIKpgONyEuLy48LcPz0i/vhAEci0KQRBgY5AsAaQpfKXbvxSiUDGFk8O9toKpniDPC1DlURyy8iSoMQ4lbUBCWhayanV/ESDLMuiZhpSSdaDH2gJKKb5YB7W46sJ2S+Hq+obVdc6srQEBL3Th/eODJ3EdDX61sR4k4vyfBr1egiz7bieRvPD6+smTSJEkA2g9XaEBQbfRjHJtptpItZnIQPOmWmUoNtO8nZctvWzrVXb+ARkgOfimiFHjAAAAAElFTkSuQmCC"},{"path":"C:\\Users\\krypp\\Documents\\Pixel Art\\Create Mod\\basin\\Basin Canal\\Basin Canal.png","name":"Basin Canal.png","folder":"Basin Canal","namespace":"","id":"2","particle":false,"mode":"bitmap","saved":true,"uuid":"4459ee5f-e243-a1a9-b39e-fd8adcac4b69","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABc0lEQVQ4T4VTTU/CQBB9TWi3WiGIMdGYcFD4J0iFhMQDB5Mm3PDSYzlx8Q/I3+FifwrxB5B4kNja3ZKsmdElwdBlLrMfndf33sw6syTR30WBUim4ngcKsz7xfd7b7p1+/0EL4cP3fXieB6UUFxVFASkLdLt3SNN0d86XAH/b6/XgjEaPmoqD4AxlqeC6HmcCIpDrq0u8pSmklKaWsxAC9wQQRRNNB1Toui7KsuSc5zkAjWazjuVyeRBgOBzCCcOB9jzBiOYvZq2URKdzawcYj5+YgRDE4Jc+5Sz7YqrnzbpdAnnQaDRYszHRZPKg3b6xmxjHsV6t3kEyyEwqojD0qZXWNh6bg9fFYs/9/xuHrbbELEmYgRkw7tjfwBG7owBhOGB5RhatSR5l8u4oQBzHB8d8vf7gDlUCvMznyKTcM5DeSJZLBKcCqtQIAlENEEUTq3nmspIBAWw2n9hut6yXdNdqtR0onbdaF9UMnqdTpmsLkvIDiqLjULkp6X8AAAAASUVORK5CYII="}]} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/basin.json b/src/main/resources/assets/create/models/block/basin/block.json similarity index 100% rename from src/main/resources/assets/create/models/block/basin.json rename to src/main/resources/assets/create/models/block/basin/block.json diff --git a/src/main/resources/assets/create/models/block/basin/block_directional.json b/src/main/resources/assets/create/models/block/basin/block_directional.json new file mode 100644 index 000000000..6a6e9a8ba --- /dev/null +++ b/src/main/resources/assets/create/models/block/basin/block_directional.json @@ -0,0 +1,237 @@ +{ + "credit": "Made with Blockbench", + "parent": "block/block", + "textures": { + "1": "create:block/basin_side", + "2": "create:block/basin_canal", + "12": "create:block/basin", + "particle": "create:block/basin" + }, + "elements": [ + { + "name": "Side1", + "from": [14, 2, 0], + "to": [16, 16, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 24, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 14], "texture": "#1"}, + "east": {"uv": [0, 0, 16, 14], "texture": "#1"}, + "south": {"uv": [14, 0, 16, 14], "texture": "#1"}, + "west": {"uv": [0, 0, 16, 14], "texture": "#1"}, + "up": {"uv": [0, 0, 2, 16], "rotation": 180, "texture": "#12"}, + "down": {"uv": [0, 0, 2, 16], "rotation": 180, "texture": "#12"} + } + }, + { + "name": "BasinBottom", + "from": [2, 0, 2], + "to": [14, 2, 14], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 25, 8]}, + "faces": { + "north": {"uv": [2, 14, 14, 16], "texture": "#1"}, + "east": {"uv": [2, 14, 14, 16], "texture": "#1"}, + "south": {"uv": [2, 14, 14, 16], "texture": "#1"}, + "west": {"uv": [2, 14, 14, 16], "texture": "#1"}, + "up": {"uv": [2, 2, 14, 14], "rotation": 180, "texture": "#12"}, + "down": {"uv": [2, 2, 14, 14], "rotation": 180, "texture": "#12"} + } + }, + { + "name": "Side4", + "from": [2, 2, 14], + "to": [14, 16, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 24, 8]}, + "faces": { + "north": {"uv": [2, 0, 14, 14], "texture": "#1"}, + "south": {"uv": [2, 0, 14, 14], "texture": "#1"}, + "up": {"uv": [2, 0, 14, 2], "rotation": 180, "texture": "#12"}, + "down": {"uv": [2, 14, 14, 16], "rotation": 180, "texture": "#12"} + } + }, + { + "name": "Side2", + "from": [2, 2, 0], + "to": [14, 16, 2], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 24, 8]}, + "faces": { + "north": {"uv": [2, 0, 14, 14], "texture": "#1"}, + "south": {"uv": [2, 0, 14, 14], "texture": "#1"}, + "up": {"uv": [2, 14, 14, 16], "rotation": 180, "texture": "#12"}, + "down": {"uv": [2, 0, 14, 2], "rotation": 180, "texture": "#12"} + } + }, + { + "name": "Side3", + "from": [0, 2, 0], + "to": [2, 16, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 40, 8]}, + "faces": { + "north": {"uv": [14, 0, 16, 14], "texture": "#1"}, + "east": {"uv": [0, 0, 16, 14], "texture": "#1"}, + "south": {"uv": [0, 0, 2, 14], "texture": "#1"}, + "west": {"uv": [0, 0, 16, 14], "texture": "#1"}, + "up": {"uv": [14, 0, 16, 16], "rotation": 180, "texture": "#12"}, + "down": {"uv": [14, 0, 16, 16], "rotation": 180, "texture": "#12"} + } + }, + { + "from": [12, 0, 14], + "to": [13, 2, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [5, 8, 8]}, + "faces": { + "north": {"uv": [14, 10, 16, 11], "rotation": 90, "texture": "#2"}, + "east": {"uv": [14, 10, 16, 12], "rotation": 90, "texture": "#2"}, + "south": {"uv": [0, 0, 10, 2], "texture": "#2"}, + "west": {"uv": [14, 10, 16, 12], "texture": "#2"}, + "up": {"uv": [14, 10, 15, 12], "texture": "#2"}, + "down": {"uv": [15, 10, 16, 12], "rotation": 180, "texture": "#2"} + } + }, + { + "from": [3, 0, 14], + "to": [4, 2, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [-4, 8, 8]}, + "faces": { + "north": {"uv": [14, 10, 16, 11], "rotation": 90, "texture": "#2"}, + "east": {"uv": [14, 10, 16, 12], "rotation": 90, "texture": "#2"}, + "south": {"uv": [0, 0, 10, 2], "texture": "#2"}, + "west": {"uv": [14, 10, 16, 12], "texture": "#2"}, + "up": {"uv": [14, 10, 15, 12], "texture": "#2"}, + "down": {"uv": [15, 10, 16, 12], "rotation": 180, "texture": "#2"} + } + }, + { + "from": [4, 0, 14], + "to": [12, 1, 17], + "rotation": {"angle": 0, "axis": "y", "origin": [4, 8, 9]}, + "faces": { + "north": {"uv": [8, 14, 9, 15], "rotation": 90, "texture": "#2"}, + "east": {"uv": [14, 10, 16, 12], "rotation": 90, "texture": "#2"}, + "south": {"uv": [7, 15, 15, 16], "texture": "#2"}, + "west": {"uv": [14, 10, 16, 12], "texture": "#2"}, + "up": {"uv": [11, 10, 12, 11], "texture": "#2"}, + "down": {"uv": [7, 13, 15, 16], "rotation": 180, "texture": "#2"} + } + }, + { + "from": [12, 0, 16], + "to": [13, 10, 17], + "rotation": {"angle": 0, "axis": "y", "origin": [5, 8, 9]}, + "faces": { + "north": {"uv": [6, 12, 16, 13], "rotation": 90, "texture": "#2"}, + "east": {"uv": [6, 12, 16, 13], "rotation": 90, "texture": "#2"}, + "south": {"uv": [6, 12, 16, 13], "rotation": 90, "texture": "#2"}, + "west": {"uv": [6, 12, 16, 13], "rotation": 90, "texture": "#2"}, + "up": {"uv": [6, 12, 7, 13], "rotation": 180, "texture": "#2"}, + "down": {"uv": [15, 12, 16, 13], "rotation": 180, "texture": "#2"} + } + }, + { + "from": [4, 9, 16], + "to": [12, 10, 17], + "rotation": {"angle": 0, "axis": "y", "origin": [4, 8, 9]}, + "faces": { + "north": {"uv": [8, 9, 16, 10], "texture": "#2"}, + "south": {"uv": [8, 9, 16, 10], "texture": "#2"}, + "up": {"uv": [8, 9, 16, 10], "rotation": 180, "texture": "#2"} + } + }, + { + "from": [3, 0, 16], + "to": [4, 10, 17], + "rotation": {"angle": 0, "axis": "y", "origin": [-4, 8, 9]}, + "faces": { + "north": {"uv": [6, 12, 16, 13], "rotation": 90, "texture": "#2"}, + "east": {"uv": [6, 12, 16, 13], "rotation": 90, "texture": "#2"}, + "south": {"uv": [6, 12, 16, 13], "rotation": 90, "texture": "#2"}, + "west": {"uv": [6, 12, 16, 13], "rotation": 90, "texture": "#2"}, + "up": {"uv": [6, 12, 7, 13], "rotation": 180, "texture": "#2"}, + "down": {"uv": [15, 12, 16, 13], "rotation": 180, "texture": "#2"} + } + }, + { + "from": [5, 1, 13], + "to": [11, 2, 22], + "rotation": {"angle": 22.5, "axis": "x", "origin": [8, 9, 17]}, + "faces": { + "north": {"uv": [9, 7, 15, 8], "texture": "#2"}, + "east": {"uv": [0, 0, 9, 1], "texture": "#2"}, + "south": {"uv": [9, 7, 15, 8], "texture": "#2"}, + "west": {"uv": [0, 0, 9, 1], "texture": "#2"}, + "up": {"uv": [1, 0, 7, 9], "rotation": 180, "texture": "#2"}, + "down": {"uv": [1, 0, 7, 9], "texture": "#2"} + } + }, + { + "from": [5, 8, 13], + "to": [11, 9, 22], + "rotation": {"angle": 22.5, "axis": "x", "origin": [8, 9, 17]}, + "faces": { + "north": {"uv": [9, 0, 15, 1], "texture": "#2"}, + "east": {"uv": [0, 0, 9, 1], "texture": "#2"}, + "south": {"uv": [9, 0, 15, 1], "texture": "#2"}, + "west": {"uv": [0, 0, 9, 1], "texture": "#2"}, + "up": {"uv": [1, 0, 7, 9], "texture": "#2"}, + "down": {"uv": [1, 0, 7, 9], "rotation": 180, "texture": "#2"} + } + }, + { + "from": [5, 2, 14], + "to": [11, 8, 20], + "rotation": {"angle": 22.5, "axis": "x", "origin": [8, 9, 17]}, + "faces": { + "north": {"uv": [9, 1, 15, 7], "texture": "#2"}, + "south": {"uv": [9, 1, 15, 7], "texture": "#2"} + } + }, + { + "from": [4, 1, 13], + "to": [5, 9, 22], + "rotation": {"angle": 22.5, "axis": "x", "origin": [1, 9, 17]}, + "faces": { + "north": {"uv": [15, 0, 16, 8], "texture": "#2"}, + "east": {"uv": [0, 0, 8, 9], "rotation": 90, "texture": "#2"}, + "south": {"uv": [8, 0, 9, 8], "texture": "#2"}, + "west": {"uv": [0, 0, 8, 9], "rotation": 270, "texture": "#2"}, + "up": {"uv": [0, 0, 1, 9], "texture": "#2"}, + "down": {"uv": [0, 0, 1, 9], "rotation": 180, "texture": "#2"} + } + }, + { + "from": [11, 1, 13], + "to": [12, 9, 22], + "rotation": {"angle": 22.5, "axis": "x", "origin": [8, 9, 17]}, + "faces": { + "north": {"uv": [8, 0, 9, 8], "texture": "#2"}, + "east": {"uv": [0, 0, 8, 9], "rotation": 90, "texture": "#2"}, + "south": {"uv": [15, 0, 16, 8], "texture": "#2"}, + "west": {"uv": [0, 0, 8, 9], "rotation": 90, "texture": "#2"}, + "up": {"uv": [0, 0, 1, 9], "texture": "#2"}, + "down": {"uv": [0, 0, 1, 9], "rotation": 180, "texture": "#2"} + } + } + ], + "groups": [ + { + "name": "Basins", + "origin": [8, 8, 8], + "children": [ + { + "name": "Basin top", + "origin": [8, 8, 8], + "children": [0, 1, 2, 3, 4] + } + ] + }, + { + "name": "Canal", + "origin": [8, 8, 8], + "children": [ + { + "name": "Frame", + "origin": [8, 8, 8], + "children": [5, 6, 7, 8, 9, 10] + }, 11, 12, 13, 14, 15] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/symmetry_effect/crossplane.json b/src/main/resources/assets/create/models/block/symmetry_effect/crossplane.json index fede15ab1..0fdbb9668 100644 --- a/src/main/resources/assets/create/models/block/symmetry_effect/crossplane.json +++ b/src/main/resources/assets/create/models/block/symmetry_effect/crossplane.json @@ -1,144 +1,143 @@ { - "__comment": "Model generated using MrCrayfish's Model Creator (http://mrcrayfish.com/modelcreator/)", - "textures": { - "0": "block/white_stained_glass", - "1": "block/obsidian", - "2": "block/packed_ice" - }, - "elements": [ - { - "name": "Mirror", - "from": [ 4.0, 1.0, 7.500000007450581 ], - "to": [ 7.0, 12.0, 8.50000000745058 ], - "faces": { - "north": { "texture": "#0", "uv": [ 4.0, 1.0, 7.0, 12.0 ] }, - "east": { "texture": "#0", "uv": [ 3.0, 1.0, 4.0, 12.0 ] }, - "south": { "texture": "#0", "uv": [ 4.0, 1.0, 7.0, 12.0 ] }, - "west": { "texture": "#0", "uv": [ 12.0, 1.0, 13.0, 12.0 ] }, - "up": { "texture": "#0", "uv": [ 4.0, 1.0, 7.0, 2.0 ] }, - "down": { "texture": "#0", "uv": [ 4.0, 14.0, 7.0, 15.0 ] } - } - }, - { - "name": "rod_left_bottom", - "from": [ 1.2000000029802322, 3.0, 7.0 ], - "to": [ 3.2000000029802322, 4.0, 9.0 ], - "rotation": { "origin": [ 8.0, 8.0, 8.0 ], "axis": "y", "angle": -22.5 }, - "faces": { - "north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "east": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "west": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] }, - "down": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] } - } - }, - { - "name": "rod_left_top", - "from": [ 1.2000000029802322, 12.0, 7.0 ], - "to": [ 3.2000000029802322, 13.0, 9.0 ], - "rotation": { "origin": [ 8.0, 8.0, 8.0 ], "axis": "y", "angle": -22.5 }, - "faces": { - "north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "east": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "west": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] }, - "down": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] } - } - }, - { - "name": "rod_left", - "from": [ 2.0, 4.0, 7.499999992549419 ], - "to": [ 3.0, 12.0, 8.49999999254942 ], - "shade": false, - "rotation": { "origin": [ 8.0, 8.0, 8.0 ], "axis": "y", "angle": -22.5 }, - "faces": { - "north": { "texture": "#2", "uv": [ 3.0, 1.0, 4.0, 9.0 ] }, - "east": { "texture": "#2", "uv": [ 3.0, 0.0, 4.0, 8.0 ] }, - "south": { "texture": "#2", "uv": [ 3.0, 1.0, 4.0, 9.0 ] }, - "west": { "texture": "#2", "uv": [ 5.0, 1.0, 6.0, 9.0 ] } - } - }, - { - "name": "rod_right_bottom", - "from": [ 12.799999997019768, 3.0, 7.0 ], - "to": [ 14.799999997019768, 4.0, 9.0 ], - "rotation": { "origin": [ 8.0, 8.0, 8.0 ], "axis": "y", "angle": -22.5 }, - "faces": { - "north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "east": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "west": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] }, - "down": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] } - } - }, - { - "name": "rod_right", - "from": [ 13.0, 4.0, 7.499999992549419 ], - "to": [ 14.0, 12.0, 8.49999999254942 ], - "shade": false, - "rotation": { "origin": [ 8.0, 8.0, 8.0 ], "axis": "y", "angle": -22.5 }, - "faces": { - "north": { "texture": "#2", "uv": [ 3.0, 2.0, 4.0, 10.0 ] }, - "east": { "texture": "#2", "uv": [ 3.0, 3.0, 4.0, 11.0 ] }, - "south": { "texture": "#2", "uv": [ 4.0, 3.0, 5.0, 11.0 ] }, - "west": { "texture": "#2", "uv": [ 5.0, 0.0, 6.0, 8.0 ] } - } - }, - { - "name": "rod_right_top", - "from": [ 12.799999997019768, 12.0, 7.0 ], - "to": [ 14.799999997019768, 13.0, 9.0 ], - "rotation": { "origin": [ 8.0, 8.0, 8.0 ], "axis": "y", "angle": -22.5 }, - "faces": { - "north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "east": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "west": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] }, - "down": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] } - } - }, - { - "name": "CrossMirror", - "from": [ 7.499999992549419, 4.0, 9.50000000745058 ], - "to": [ 8.49999999254942, 15.0, 12.50000000745058 ], - "faces": { - "north": { "texture": "#0", "uv": [ 4.0, 1.0, 5.0, 12.0 ] }, - "east": { "texture": "#0", "uv": [ 3.0, 1.0, 6.0, 12.0 ] }, - "south": { "texture": "#0", "uv": [ 4.0, 1.0, 5.0, 12.0 ] }, - "west": { "texture": "#0", "uv": [ 9.0, 1.0, 12.0, 12.0 ] }, - "up": { "texture": "#0", "uv": [ 3.0, 3.0, 4.0, 6.0 ] }, - "down": { "texture": "#0", "uv": [ 5.0, 9.0, 6.0, 12.0 ] } - } - }, - { - "name": "Mirror II", - "from": [ 9.0, 3.0, 7.500000007450581 ], - "to": [ 12.0, 14.0, 8.50000000745058 ], - "faces": { - "north": { "texture": "#0", "uv": [ 4.0, 1.0, 7.0, 12.0 ] }, - "east": { "texture": "#0", "uv": [ 3.0, 1.0, 4.0, 12.0 ] }, - "south": { "texture": "#0", "uv": [ 4.0, 1.0, 7.0, 12.0 ] }, - "west": { "texture": "#0", "uv": [ 12.0, 1.0, 13.0, 12.0 ] }, - "up": { "texture": "#0", "uv": [ 4.0, 1.0, 7.0, 2.0 ] }, - "down": { "texture": "#0", "uv": [ 4.0, 14.0, 7.0, 15.0 ] } - } - }, - { - "name": "CrossMirror II", - "from": [ 7.499999992549419, 2.0, 3.5000000074505806 ], - "to": [ 8.49999999254942, 13.0, 6.500000007450581 ], - "faces": { - "north": { "texture": "#0", "uv": [ 4.0, 1.0, 5.0, 12.0 ] }, - "east": { "texture": "#0", "uv": [ 3.0, 1.0, 6.0, 12.0 ] }, - "south": { "texture": "#0", "uv": [ 4.0, 3.0, 5.0, 14.0 ] }, - "west": { "texture": "#0", "uv": [ 9.0, 2.0, 12.0, 13.0 ] }, - "up": { "texture": "#0", "uv": [ 4.0, 3.0, 5.0, 6.0 ] }, - "down": { "texture": "#0", "uv": [ 4.0, 8.0, 5.0, 11.0 ] } - } - } - ] + "credit": "Made with Blockbench", + "textures": { + "0": "create:block/symmetry_mirror", + "2": "create:block/brass_block" + }, + "elements": [ + { + "name": "Mirror", + "from": [4, 1, 7.5], + "to": [7, 12, 8.5], + "faces": { + "north": {"uv": [4, 1, 7, 12], "texture": "#0"}, + "east": {"uv": [3, 1, 4, 12], "texture": "#0"}, + "south": {"uv": [4, 1, 7, 12], "texture": "#0"}, + "west": {"uv": [12, 1, 13, 12], "texture": "#0"}, + "up": {"uv": [4, 1, 7, 2], "texture": "#0"}, + "down": {"uv": [4, 14, 7, 15], "texture": "#0"} + } + }, + { + "name": "rod_left_bottom", + "from": [1, 3, 7], + "to": [3, 4, 9], + "rotation": {"angle": -22.5, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "east": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "south": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "west": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "up": {"uv": [13, 13, 15, 15], "texture": "#2"}, + "down": {"uv": [13, 13, 15, 15], "texture": "#2"} + } + }, + { + "name": "rod_left_bottom", + "from": [13, 3, 7], + "to": [15, 4, 9], + "rotation": {"angle": -22.5, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "east": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "south": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "west": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "up": {"uv": [13, 13, 15, 15], "rotation": 180, "texture": "#2"}, + "down": {"uv": [13, 13, 15, 15], "rotation": 180, "texture": "#2"} + } + }, + { + "name": "rod_left_top", + "from": [1, 12, 7], + "to": [3, 13, 9], + "rotation": {"angle": -22.5, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "east": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "south": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "west": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "up": {"uv": [13, 13, 15, 15], "texture": "#2"}, + "down": {"uv": [13, 13, 15, 15], "texture": "#2"} + } + }, + { + "name": "rod_left_top", + "from": [13, 12, 7], + "to": [15, 13, 9], + "rotation": {"angle": -22.5, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "east": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "south": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "west": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "up": {"uv": [13, 13, 15, 15], "rotation": 180, "texture": "#2"}, + "down": {"uv": [13, 13, 15, 15], "rotation": 180, "texture": "#2"} + } + }, + { + "name": "rod_left", + "from": [1, 4, 7.5], + "to": [3, 12, 8.5], + "shade": false, + "rotation": {"angle": -22.5, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [3, 5, 1, 13], "texture": "#2"}, + "east": {"uv": [8, 4, 9, 12], "texture": "#2"}, + "south": {"uv": [1, 3, 3, 11], "texture": "#2"}, + "west": {"uv": [1, 6, 2, 14], "texture": "#2"} + } + }, + { + "name": "rod_left", + "from": [13, 4, 7.5], + "to": [15, 12, 8.5], + "shade": false, + "rotation": {"angle": -22.5, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [1, 3, 3, 11], "texture": "#2"}, + "east": {"uv": [1, 6, 2, 14], "texture": "#2"}, + "south": {"uv": [3, 5, 1, 13], "texture": "#2"}, + "west": {"uv": [8, 4, 9, 12], "texture": "#2"} + } + }, + { + "name": "CrossMirror", + "from": [7.5, 4, 9.5], + "to": [8.5, 15, 12.5], + "faces": { + "north": {"uv": [4, 1, 5, 12], "texture": "#0"}, + "east": {"uv": [3, 1, 6, 12], "texture": "#0"}, + "south": {"uv": [4, 1, 5, 12], "texture": "#0"}, + "west": {"uv": [9, 1, 12, 12], "texture": "#0"}, + "up": {"uv": [3, 3, 4, 6], "texture": "#0"}, + "down": {"uv": [5, 9, 6, 12], "texture": "#0"} + } + }, + { + "name": "Mirror II", + "from": [9, 3, 7.5], + "to": [12, 14, 8.5], + "faces": { + "north": {"uv": [4, 1, 7, 12], "texture": "#0"}, + "east": {"uv": [3, 1, 4, 12], "texture": "#0"}, + "south": {"uv": [4, 1, 7, 12], "texture": "#0"}, + "west": {"uv": [12, 1, 13, 12], "texture": "#0"}, + "up": {"uv": [4, 1, 7, 2], "texture": "#0"}, + "down": {"uv": [4, 14, 7, 15], "texture": "#0"} + } + }, + { + "name": "CrossMirror II", + "from": [7.5, 2, 3.5], + "to": [8.5, 13, 6.5], + "faces": { + "north": {"uv": [4, 1, 5, 12], "texture": "#0"}, + "east": {"uv": [3, 1, 6, 12], "texture": "#0"}, + "south": {"uv": [4, 3, 5, 14], "texture": "#0"}, + "west": {"uv": [9, 2, 12, 13], "texture": "#0"}, + "up": {"uv": [4, 3, 5, 6], "texture": "#0"}, + "down": {"uv": [4, 8, 5, 11], "texture": "#0"} + } + } + ] } \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/symmetry_effect/plane.json b/src/main/resources/assets/create/models/block/symmetry_effect/plane.json index 5d36206de..5717ed96f 100644 --- a/src/main/resources/assets/create/models/block/symmetry_effect/plane.json +++ b/src/main/resources/assets/create/models/block/symmetry_effect/plane.json @@ -1,99 +1,105 @@ { - "__comment": "Model generated using MrCrayfish's Model Creator (http://mrcrayfish.com/modelcreator/)", - "textures": { - "0": "block/white_stained_glass", - "1": "block/obsidian", - "2": "block/packed_ice" - }, - "elements": [ - { - "name": "Mirror", - "from": [ 4.0, 1.0, 7.500000007450581 ], - "to": [ 12.0, 15.0, 8.50000000745058 ], - "faces": { - "north": { "texture": "#0", "uv": [ 4.0, 1.0, 12.0, 15.0 ] }, - "east": { "texture": "#0", "uv": [ 3.0, 1.0, 4.0, 15.0 ] }, - "south": { "texture": "#0", "uv": [ 4.0, 1.0, 12.0, 15.0 ] }, - "west": { "texture": "#0", "uv": [ 12.0, 1.0, 13.0, 15.0 ] }, - "up": { "texture": "#0", "uv": [ 4.0, 1.0, 12.0, 2.0 ] }, - "down": { "texture": "#0", "uv": [ 4.0, 14.0, 12.0, 15.0 ] } - } - }, - { - "name": "rod_left_bottom", - "from": [ 1.2000000029802322, 3.0, 7.0 ], - "to": [ 3.2000000029802322, 4.0, 9.0 ], - "faces": { - "north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "east": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "west": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] }, - "down": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] } - } - }, - { - "name": "rod_left_top", - "from": [ 1.2000000029802322, 12.0, 7.0 ], - "to": [ 3.2000000029802322, 13.0, 9.0 ], - "faces": { - "north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "east": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "west": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] }, - "down": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] } - } - }, - { - "name": "rod_left", - "from": [ 2.0, 4.0, 7.499999992549419 ], - "to": [ 3.0, 12.0, 8.49999999254942 ], - "shade": false, - "faces": { - "north": { "texture": "#2", "uv": [ 3.0, 1.0, 4.0, 9.0 ] }, - "east": { "texture": "#2", "uv": [ 3.0, 0.0, 4.0, 8.0 ] }, - "south": { "texture": "#2", "uv": [ 3.0, 1.0, 4.0, 9.0 ] }, - "west": { "texture": "#2", "uv": [ 5.0, 1.0, 6.0, 9.0 ] } - } - }, - { - "name": "rod_right_bottom", - "from": [ 12.799999997019768, 3.0, 7.0 ], - "to": [ 14.799999997019768, 4.0, 9.0 ], - "faces": { - "north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "east": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "west": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] }, - "down": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] } - } - }, - { - "name": "rod_right", - "from": [ 13.0, 4.0, 7.499999992549419 ], - "to": [ 14.0, 12.0, 8.49999999254942 ], - "shade": false, - "faces": { - "north": { "texture": "#2", "uv": [ 3.0, 2.0, 4.0, 10.0 ] }, - "east": { "texture": "#2", "uv": [ 3.0, 3.0, 4.0, 11.0 ] }, - "south": { "texture": "#2", "uv": [ 4.0, 3.0, 5.0, 11.0 ] }, - "west": { "texture": "#2", "uv": [ 5.0, 0.0, 6.0, 8.0 ] } - } - }, - { - "name": "rod_right_top", - "from": [ 12.799999997019768, 12.0, 7.0 ], - "to": [ 14.799999997019768, 13.0, 9.0 ], - "faces": { - "north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "east": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "west": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] }, - "down": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] } - } - } - ] + "credit": "Made with Blockbench", + "textures": { + "0": "create:block/symmetry_mirror", + "1_2": "create:block/brass_block" + }, + "elements": [ + { + "name": "Mirror", + "from": [4, 1, 7.5], + "to": [12, 15, 8.5], + "faces": { + "north": {"uv": [4, 1, 12, 15], "texture": "#0"}, + "east": {"uv": [3, 1, 4, 15], "texture": "#0"}, + "south": {"uv": [4, 1, 12, 15], "texture": "#0"}, + "west": {"uv": [12, 1, 13, 15], "texture": "#0"}, + "up": {"uv": [4, 1, 12, 2], "texture": "#0"}, + "down": {"uv": [4, 14, 12, 15], "texture": "#0"} + } + }, + { + "name": "rod_left_bottom", + "from": [1, 3, 7], + "to": [3, 4, 9], + "faces": { + "north": {"uv": [0, 0, 2, 1], "texture": "#1_2"}, + "east": {"uv": [0, 0, 2, 1], "texture": "#1_2"}, + "south": {"uv": [0, 0, 2, 1], "texture": "#1_2"}, + "west": {"uv": [0, 0, 2, 1], "texture": "#1_2"}, + "up": {"uv": [13, 13, 15, 15], "texture": "#1_2"}, + "down": {"uv": [13, 13, 15, 15], "texture": "#1_2"} + } + }, + { + "name": "rod_left_bottom", + "from": [13, 3, 7], + "to": [15, 4, 9], + "faces": { + "north": {"uv": [0, 0, 2, 1], "texture": "#1_2"}, + "east": {"uv": [0, 0, 2, 1], "texture": "#1_2"}, + "south": {"uv": [0, 0, 2, 1], "texture": "#1_2"}, + "west": {"uv": [0, 0, 2, 1], "texture": "#1_2"}, + "up": {"uv": [13, 13, 15, 15], "rotation": 180, "texture": "#1_2"}, + "down": {"uv": [13, 13, 15, 15], "rotation": 180, "texture": "#1_2"} + } + }, + { + "name": "rod_left_top", + "from": [1, 12, 7], + "to": [3, 13, 9], + "faces": { + "north": {"uv": [0, 0, 2, 1], "texture": "#1_2"}, + "east": {"uv": [0, 0, 2, 1], "texture": "#1_2"}, + "south": {"uv": [0, 0, 2, 1], "texture": "#1_2"}, + "west": {"uv": [0, 0, 2, 1], "texture": "#1_2"}, + "up": {"uv": [13, 13, 15, 15], "texture": "#1_2"}, + "down": {"uv": [13, 13, 15, 15], "texture": "#1_2"} + } + }, + { + "name": "rod_left_top", + "from": [13, 12, 7], + "to": [15, 13, 9], + "faces": { + "north": {"uv": [0, 0, 2, 1], "texture": "#1_2"}, + "east": {"uv": [0, 0, 2, 1], "texture": "#1_2"}, + "south": {"uv": [0, 0, 2, 1], "texture": "#1_2"}, + "west": {"uv": [0, 0, 2, 1], "texture": "#1_2"}, + "up": {"uv": [13, 13, 15, 15], "rotation": 180, "texture": "#1_2"}, + "down": {"uv": [13, 13, 15, 15], "rotation": 180, "texture": "#1_2"} + } + }, + { + "name": "rod_left", + "from": [1, 4, 7.5], + "to": [3, 12, 8.5], + "shade": false, + "faces": { + "north": {"uv": [3, 5, 1, 13], "texture": "#1_2"}, + "east": {"uv": [8, 4, 9, 12], "texture": "#1_2"}, + "south": {"uv": [1, 3, 3, 11], "texture": "#1_2"}, + "west": {"uv": [1, 6, 2, 14], "texture": "#1_2"} + } + }, + { + "name": "rod_left", + "from": [13, 4, 7.5], + "to": [15, 12, 8.5], + "shade": false, + "faces": { + "north": {"uv": [1, 3, 3, 11], "texture": "#1_2"}, + "east": {"uv": [1, 6, 2, 14], "texture": "#1_2"}, + "south": {"uv": [3, 5, 1, 13], "texture": "#1_2"}, + "west": {"uv": [8, 4, 9, 12], "texture": "#1_2"} + } + } + ], + "groups": [0, + { + "name": "crossplane", + "origin": [8, 8, 8], + "children": [1, 2, 3, 4, 5, 6] + } + ] } \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/symmetry_effect/tripleplane.json b/src/main/resources/assets/create/models/block/symmetry_effect/tripleplane.json index 2af7a097f..99450d7ca 100644 --- a/src/main/resources/assets/create/models/block/symmetry_effect/tripleplane.json +++ b/src/main/resources/assets/create/models/block/symmetry_effect/tripleplane.json @@ -1,172 +1,178 @@ { - "__comment": "Model generated using MrCrayfish's Model Creator (http://mrcrayfish.com/modelcreator/)", - "textures": { - "0": "block/white_stained_glass", - "1": "block/obsidian", - "2": "block/packed_ice" - }, - "elements": [ - { - "name": "Mirror", - "from": [ 6.499999992549419, 1.0, 10.50000000745058 ], - "to": [ 9.49999999254942, 12.0, 11.50000000745058 ], - "faces": { - "north": { "texture": "#0", "uv": [ 4.0, 1.0, 7.0, 12.0 ] }, - "east": { "texture": "#0", "uv": [ 3.0, 1.0, 4.0, 12.0 ] }, - "south": { "texture": "#0", "uv": [ 4.0, 1.0, 7.0, 12.0 ] }, - "west": { "texture": "#0", "uv": [ 12.0, 1.0, 13.0, 12.0 ] }, - "up": { "texture": "#0", "uv": [ 4.0, 1.0, 7.0, 2.0 ] }, - "down": { "texture": "#0", "uv": [ 4.0, 14.0, 7.0, 15.0 ] } - } - }, - { - "name": "rod_left_bottom", - "from": [ 1.2000000029802322, 3.0, 7.0 ], - "to": [ 3.2000000029802322, 4.0, 9.0 ], - "rotation": { "origin": [ 8.0, 8.0, 8.0 ], "axis": "y", "angle": -45.0 }, - "faces": { - "north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "east": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "west": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] }, - "down": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] } - } - }, - { - "name": "rod_left_top", - "from": [ 1.2000000029802322, 12.0, 7.0 ], - "to": [ 3.2000000029802322, 13.0, 9.0 ], - "rotation": { "origin": [ 8.0, 8.0, 8.0 ], "axis": "y", "angle": -45.0 }, - "faces": { - "north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "east": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "west": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] }, - "down": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] } - } - }, - { - "name": "rod_left", - "from": [ 2.0, 4.0, 7.499999992549419 ], - "to": [ 3.0, 12.0, 8.49999999254942 ], - "shade": false, - "rotation": { "origin": [ 8.0, 8.0, 8.0 ], "axis": "y", "angle": -45.0 }, - "faces": { - "north": { "texture": "#2", "uv": [ 3.0, 1.0, 4.0, 9.0 ] }, - "east": { "texture": "#2", "uv": [ 3.0, 0.0, 4.0, 8.0 ] }, - "south": { "texture": "#2", "uv": [ 3.0, 1.0, 4.0, 9.0 ] }, - "west": { "texture": "#2", "uv": [ 5.0, 1.0, 6.0, 9.0 ] } - } - }, - { - "name": "rod_right_bottom", - "from": [ 12.799999997019768, 3.0, 7.0 ], - "to": [ 14.799999997019768, 4.0, 9.0 ], - "rotation": { "origin": [ 8.0, 8.0, 8.0 ], "axis": "y", "angle": -45.0 }, - "faces": { - "north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "east": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "west": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] }, - "down": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] } - } - }, - { - "name": "rod_right", - "from": [ 13.0, 4.0, 7.499999992549419 ], - "to": [ 14.0, 12.0, 8.49999999254942 ], - "shade": false, - "rotation": { "origin": [ 8.0, 8.0, 8.0 ], "axis": "y", "angle": -45.0 }, - "faces": { - "north": { "texture": "#2", "uv": [ 3.0, 2.0, 4.0, 10.0 ] }, - "east": { "texture": "#2", "uv": [ 3.0, 3.0, 4.0, 11.0 ] }, - "south": { "texture": "#2", "uv": [ 4.0, 3.0, 5.0, 11.0 ] }, - "west": { "texture": "#2", "uv": [ 5.0, 0.0, 6.0, 8.0 ] } - } - }, - { - "name": "rod_right_top", - "from": [ 12.799999997019768, 12.0, 7.0 ], - "to": [ 14.799999997019768, 13.0, 9.0 ], - "rotation": { "origin": [ 8.0, 8.0, 8.0 ], "axis": "y", "angle": -45.0 }, - "faces": { - "north": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "east": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "south": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "west": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 1.0 ] }, - "up": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] }, - "down": { "texture": "#1", "uv": [ 0.0, 0.0, 2.0, 2.0 ] } - } - }, - { - "name": "CrossMirror", - "from": [ 4.499999977648258, 2.0, 6.500000007450581 ], - "to": [ 5.499999977648258, 13.0, 9.50000000745058 ], - "faces": { - "north": { "texture": "#0", "uv": [ 4.0, 1.0, 5.0, 12.0 ] }, - "east": { "texture": "#0", "uv": [ 3.0, 1.0, 6.0, 12.0 ] }, - "south": { "texture": "#0", "uv": [ 4.0, 1.0, 5.0, 12.0 ] }, - "west": { "texture": "#0", "uv": [ 9.0, 1.0, 12.0, 12.0 ] }, - "up": { "texture": "#0", "uv": [ 3.0, 3.0, 4.0, 6.0 ] }, - "down": { "texture": "#0", "uv": [ 5.0, 9.0, 6.0, 12.0 ] } - } - }, - { - "name": "Mirror II", - "from": [ 6.499999992549419, 3.0, 4.500000007450581 ], - "to": [ 9.49999999254942, 14.0, 5.500000007450581 ], - "faces": { - "north": { "texture": "#0", "uv": [ 4.0, 1.0, 7.0, 12.0 ] }, - "east": { "texture": "#0", "uv": [ 3.0, 1.0, 4.0, 12.0 ] }, - "south": { "texture": "#0", "uv": [ 4.0, 1.0, 7.0, 12.0 ] }, - "west": { "texture": "#0", "uv": [ 12.0, 1.0, 13.0, 12.0 ] }, - "up": { "texture": "#0", "uv": [ 4.0, 1.0, 7.0, 2.0 ] }, - "down": { "texture": "#0", "uv": [ 4.0, 14.0, 7.0, 15.0 ] } - } - }, - { - "name": "CrossMirror II", - "from": [ 10.50000000745058, 4.0, 6.500000007450581 ], - "to": [ 11.50000000745058, 15.0, 9.50000000745058 ], - "faces": { - "north": { "texture": "#0", "uv": [ 4.0, 1.0, 5.0, 12.0 ] }, - "east": { "texture": "#0", "uv": [ 3.0, 1.0, 6.0, 12.0 ] }, - "south": { "texture": "#0", "uv": [ 4.0, 3.0, 5.0, 14.0 ] }, - "west": { "texture": "#0", "uv": [ 9.0, 2.0, 12.0, 13.0 ] }, - "up": { "texture": "#0", "uv": [ 4.0, 3.0, 5.0, 6.0 ] }, - "down": { "texture": "#0", "uv": [ 4.0, 8.0, 5.0, 11.0 ] } - } - }, - { - "name": "Cube", - "from": [ 7.499999992549419, 6.0, -0.4999999925494194 ], - "to": [ 8.49999999254942, 10.0, 3.5000000074505806 ], - "rotation": { "origin": [ 8.0, 8.0, 8.0 ], "axis": "y", "angle": -45.0 }, - "faces": { - "north": { "texture": "#0", "uv": [ 4.0, 1.0, 5.0, 5.0 ] }, - "east": { "texture": "#0", "uv": [ 3.0, 1.0, 7.0, 5.0 ] }, - "south": { "texture": "#0", "uv": [ 4.0, 3.0, 5.0, 7.0 ] }, - "west": { "texture": "#0", "uv": [ 9.0, 2.0, 13.0, 6.0 ] }, - "up": { "texture": "#0", "uv": [ 4.0, 3.0, 5.0, 7.0 ] }, - "down": { "texture": "#0", "uv": [ 4.0, 8.0, 5.0, 12.0 ] } - } - }, - { - "name": "Cube", - "from": [ 7.499999992549419, 6.0, 12.50000000745058 ], - "to": [ 8.49999999254942, 10.0, 16.50000000745058 ], - "rotation": { "origin": [ 8.0, 8.0, 8.0 ], "axis": "y", "angle": -45.0 }, - "faces": { - "north": { "texture": "#0", "uv": [ 4.0, 1.0, 5.0, 5.0 ] }, - "east": { "texture": "#0", "uv": [ 3.0, 1.0, 7.0, 5.0 ] }, - "south": { "texture": "#0", "uv": [ 4.0, 3.0, 5.0, 7.0 ] }, - "west": { "texture": "#0", "uv": [ 9.0, 2.0, 13.0, 6.0 ] }, - "up": { "texture": "#0", "uv": [ 4.0, 3.0, 5.0, 7.0 ] }, - "down": { "texture": "#0", "uv": [ 4.0, 8.0, 5.0, 12.0 ] } - } - } - ] + "credit": "Made with Blockbench", + "textures": { + "0": "create:block/symmetry_mirror", + "2": "create:block/brass_block" + }, + "elements": [ + { + "name": "Mirror", + "from": [6.5, 1, 10.5], + "to": [9.5, 12, 11.5], + "faces": { + "north": {"uv": [4, 1, 7, 12], "texture": "#0"}, + "east": {"uv": [3, 1, 4, 12], "texture": "#0"}, + "south": {"uv": [4, 1, 7, 12], "texture": "#0"}, + "west": {"uv": [12, 1, 13, 12], "texture": "#0"}, + "up": {"uv": [4, 1, 7, 2], "texture": "#0"}, + "down": {"uv": [4, 14, 7, 15], "texture": "#0"} + } + }, + { + "name": "CrossMirror", + "from": [4.5, 2, 6.5], + "to": [5.5, 13, 9.5], + "faces": { + "north": {"uv": [4, 1, 5, 12], "texture": "#0"}, + "east": {"uv": [3, 1, 6, 12], "texture": "#0"}, + "south": {"uv": [4, 1, 5, 12], "texture": "#0"}, + "west": {"uv": [9, 1, 12, 12], "texture": "#0"}, + "up": {"uv": [3, 3, 4, 6], "texture": "#0"}, + "down": {"uv": [5, 9, 6, 12], "texture": "#0"} + } + }, + { + "name": "Mirror II", + "from": [6.5, 3, 4.5], + "to": [9.5, 14, 5.5], + "faces": { + "north": {"uv": [4, 1, 7, 12], "texture": "#0"}, + "east": {"uv": [3, 1, 4, 12], "texture": "#0"}, + "south": {"uv": [4, 1, 7, 12], "texture": "#0"}, + "west": {"uv": [12, 1, 13, 12], "texture": "#0"}, + "up": {"uv": [4, 1, 7, 2], "texture": "#0"}, + "down": {"uv": [4, 14, 7, 15], "texture": "#0"} + } + }, + { + "name": "CrossMirror II", + "from": [10.5, 4, 6.5], + "to": [11.5, 15, 9.5], + "faces": { + "north": {"uv": [4, 1, 5, 12], "texture": "#0"}, + "east": {"uv": [3, 1, 6, 12], "texture": "#0"}, + "south": {"uv": [4, 3, 5, 14], "texture": "#0"}, + "west": {"uv": [9, 2, 12, 13], "texture": "#0"}, + "up": {"uv": [4, 3, 5, 6], "texture": "#0"}, + "down": {"uv": [4, 8, 5, 11], "texture": "#0"} + } + }, + { + "name": "Cube", + "from": [7.5, 6, -0.5], + "to": [8.5, 10, 3.5], + "rotation": {"angle": -45, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [4, 1, 5, 5], "texture": "#0"}, + "east": {"uv": [3, 1, 7, 5], "texture": "#0"}, + "south": {"uv": [4, 3, 5, 7], "texture": "#0"}, + "west": {"uv": [9, 2, 13, 6], "texture": "#0"}, + "up": {"uv": [4, 3, 5, 7], "texture": "#0"}, + "down": {"uv": [4, 8, 5, 12], "texture": "#0"} + } + }, + { + "name": "Cube", + "from": [7.5, 6, 12.5], + "to": [8.5, 10, 16.5], + "rotation": {"angle": -45, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [4, 1, 5, 5], "texture": "#0"}, + "east": {"uv": [3, 1, 7, 5], "texture": "#0"}, + "south": {"uv": [4, 3, 5, 7], "texture": "#0"}, + "west": {"uv": [9, 2, 13, 6], "texture": "#0"}, + "up": {"uv": [4, 3, 5, 7], "texture": "#0"}, + "down": {"uv": [4, 8, 5, 12], "texture": "#0"} + } + }, + { + "name": "rod_left_bottom", + "from": [1, 3, 7], + "to": [3, 4, 9], + "rotation": {"angle": -22.5, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "east": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "south": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "west": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "up": {"uv": [13, 13, 15, 15], "texture": "#2"}, + "down": {"uv": [13, 13, 15, 15], "texture": "#2"} + } + }, + { + "name": "rod_left_bottom", + "from": [13, 3, 7], + "to": [15, 4, 9], + "rotation": {"angle": -22.5, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "east": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "south": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "west": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "up": {"uv": [13, 13, 15, 15], "rotation": 180, "texture": "#2"}, + "down": {"uv": [13, 13, 15, 15], "rotation": 180, "texture": "#2"} + } + }, + { + "name": "rod_left_top", + "from": [1, 12, 7], + "to": [3, 13, 9], + "rotation": {"angle": -22.5, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "east": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "south": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "west": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "up": {"uv": [13, 13, 15, 15], "texture": "#2"}, + "down": {"uv": [13, 13, 15, 15], "texture": "#2"} + } + }, + { + "name": "rod_left_top", + "from": [13, 12, 7], + "to": [15, 13, 9], + "rotation": {"angle": -22.5, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "east": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "south": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "west": {"uv": [0, 0, 2, 1], "texture": "#2"}, + "up": {"uv": [13, 13, 15, 15], "rotation": 180, "texture": "#2"}, + "down": {"uv": [13, 13, 15, 15], "rotation": 180, "texture": "#2"} + } + }, + { + "name": "rod_left", + "from": [1, 4, 7.5], + "to": [3, 12, 8.5], + "shade": false, + "rotation": {"angle": -22.5, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [3, 5, 1, 13], "texture": "#2"}, + "east": {"uv": [8, 4, 9, 12], "texture": "#2"}, + "south": {"uv": [1, 3, 3, 11], "texture": "#2"}, + "west": {"uv": [1, 6, 2, 14], "texture": "#2"} + } + }, + { + "name": "rod_left", + "from": [13, 4, 7.5], + "to": [15, 12, 8.5], + "shade": false, + "rotation": {"angle": -22.5, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [1, 3, 3, 11], "texture": "#2"}, + "east": {"uv": [1, 6, 2, 14], "texture": "#2"}, + "south": {"uv": [3, 5, 1, 13], "texture": "#2"}, + "west": {"uv": [8, 4, 9, 12], "texture": "#2"} + } + } + ], + "groups": [0, 1, 2, 3, 4, 5, + { + "name": "crossplane", + "origin": [8, 8, 8], + "children": [6, 7, 8, 9, 10, 11] + } + ] } \ No newline at end of file diff --git a/src/main/resources/assets/create/textures/block/basin_canal.png b/src/main/resources/assets/create/textures/block/basin_canal.png new file mode 100644 index 000000000..c300a2a1b Binary files /dev/null and b/src/main/resources/assets/create/textures/block/basin_canal.png differ diff --git a/src/main/resources/assets/create/textures/block/symmetry_mirror.png b/src/main/resources/assets/create/textures/block/symmetry_mirror.png new file mode 100644 index 000000000..b29da0866 Binary files /dev/null and b/src/main/resources/assets/create/textures/block/symmetry_mirror.png differ diff --git a/src/main/resources/assets/create/textures/gui/curiosities.png b/src/main/resources/assets/create/textures/gui/curiosities.png new file mode 100644 index 000000000..ed7333357 Binary files /dev/null and b/src/main/resources/assets/create/textures/gui/curiosities.png differ diff --git a/src/main/resources/assets/create/textures/gui/curiosities_2.png b/src/main/resources/assets/create/textures/gui/curiosities_2.png new file mode 100644 index 000000000..1a19c375f Binary files /dev/null and b/src/main/resources/assets/create/textures/gui/curiosities_2.png differ diff --git a/src/main/resources/assets/create/textures/gui/double_flexcrate.png b/src/main/resources/assets/create/textures/gui/double_flexcrate.png deleted file mode 100644 index 57df53fe6..000000000 Binary files a/src/main/resources/assets/create/textures/gui/double_flexcrate.png and /dev/null differ diff --git a/src/main/resources/assets/create/textures/gui/filter.png b/src/main/resources/assets/create/textures/gui/filter.png deleted file mode 100644 index 00a65a06f..000000000 Binary files a/src/main/resources/assets/create/textures/gui/filter.png and /dev/null differ diff --git a/src/main/resources/assets/create/textures/gui/filters.png b/src/main/resources/assets/create/textures/gui/filters.png new file mode 100644 index 000000000..e1f39a915 Binary files /dev/null and b/src/main/resources/assets/create/textures/gui/filters.png differ diff --git a/src/main/resources/assets/create/textures/gui/flex_crate_and_stockpile_switch.png b/src/main/resources/assets/create/textures/gui/flex_crate_and_stockpile_switch.png deleted file mode 100644 index b6da1409e..000000000 Binary files a/src/main/resources/assets/create/textures/gui/flex_crate_and_stockpile_switch.png and /dev/null differ diff --git a/src/main/resources/assets/create/textures/gui/icons.png b/src/main/resources/assets/create/textures/gui/icons.png index 865f8b22e..a8557a63b 100644 Binary files a/src/main/resources/assets/create/textures/gui/icons.png and b/src/main/resources/assets/create/textures/gui/icons.png differ diff --git a/src/main/resources/assets/create/textures/gui/logistics.png b/src/main/resources/assets/create/textures/gui/logistics.png new file mode 100644 index 000000000..9aeee18e9 Binary files /dev/null and b/src/main/resources/assets/create/textures/gui/logistics.png differ diff --git a/src/main/resources/assets/create/textures/gui/logistics_2.png b/src/main/resources/assets/create/textures/gui/logistics_2.png new file mode 100644 index 000000000..f56b7c911 Binary files /dev/null and b/src/main/resources/assets/create/textures/gui/logistics_2.png differ diff --git a/src/main/resources/assets/create/textures/gui/background.png b/src/main/resources/assets/create/textures/gui/overlay.png similarity index 100% rename from src/main/resources/assets/create/textures/gui/background.png rename to src/main/resources/assets/create/textures/gui/overlay.png diff --git a/src/main/resources/assets/create/textures/gui/schematic.png b/src/main/resources/assets/create/textures/gui/schematic.png deleted file mode 100644 index a46e2686b..000000000 Binary files a/src/main/resources/assets/create/textures/gui/schematic.png and /dev/null differ diff --git a/src/main/resources/assets/create/textures/gui/schematic_table.png b/src/main/resources/assets/create/textures/gui/schematic_table.png deleted file mode 100644 index 06ae3203c..000000000 Binary files a/src/main/resources/assets/create/textures/gui/schematic_table.png and /dev/null differ diff --git a/src/main/resources/assets/create/textures/gui/schematicannon.png b/src/main/resources/assets/create/textures/gui/schematicannon.png deleted file mode 100644 index cb838679c..000000000 Binary files a/src/main/resources/assets/create/textures/gui/schematicannon.png and /dev/null differ diff --git a/src/main/resources/assets/create/textures/gui/schematics.png b/src/main/resources/assets/create/textures/gui/schematics.png new file mode 100644 index 000000000..a3cc2615a Binary files /dev/null and b/src/main/resources/assets/create/textures/gui/schematics.png differ diff --git a/src/main/resources/assets/create/textures/gui/schematics_2.png b/src/main/resources/assets/create/textures/gui/schematics_2.png new file mode 100644 index 000000000..3d2dffdef Binary files /dev/null and b/src/main/resources/assets/create/textures/gui/schematics_2.png differ diff --git a/src/main/resources/assets/create/textures/gui/sequencer.png b/src/main/resources/assets/create/textures/gui/sequencer.png index 13a8cbd33..5dcbea527 100644 Binary files a/src/main/resources/assets/create/textures/gui/sequencer.png and b/src/main/resources/assets/create/textures/gui/sequencer.png differ diff --git a/src/main/resources/assets/create/textures/gui/wand_symmetry.png b/src/main/resources/assets/create/textures/gui/wand_symmetry.png deleted file mode 100644 index 49405bd24..000000000 Binary files a/src/main/resources/assets/create/textures/gui/wand_symmetry.png and /dev/null differ diff --git a/src/main/resources/assets/create/textures/gui/widgets.png b/src/main/resources/assets/create/textures/gui/widgets.png index 335460ca9..6b62bdd32 100644 Binary files a/src/main/resources/assets/create/textures/gui/widgets.png and b/src/main/resources/assets/create/textures/gui/widgets.png differ diff --git a/src/main/resources/assets/create/textures/gui/zapper.png b/src/main/resources/assets/create/textures/gui/zapper.png deleted file mode 100644 index 771941d43..000000000 Binary files a/src/main/resources/assets/create/textures/gui/zapper.png and /dev/null differ diff --git a/src/main/resources/assets/create/textures/item/logistical_filter.png b/src/main/resources/assets/create/textures/item/logistical_filter.png deleted file mode 100644 index a2989b1db..000000000 Binary files a/src/main/resources/assets/create/textures/item/logistical_filter.png and /dev/null differ diff --git a/src/main/resources/assets/create/textures/item/property_filter.png b/src/main/resources/assets/create/textures/item/property_filter.png index 935c38456..dd99191d0 100644 Binary files a/src/main/resources/assets/create/textures/item/property_filter.png and b/src/main/resources/assets/create/textures/item/property_filter.png differ