Click to Craft
- Added Crafting Blueprints - Bit of "Ghost-item" Container refactoring
|
@ -407,21 +407,21 @@ a3a11524cd3515fc01d905767b4b7ea782adaf03 assets/create/blockstates/yellow_seat.j
|
|||
6801fa1f466f172700e573e5b8ee8ee5f9ca4583 assets/create/blockstates/yellow_valve_handle.json
|
||||
7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json
|
||||
b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json
|
||||
e9c463e0cf56ed28ee26a33debeae3ecc2e941d2 assets/create/lang/en_ud.json
|
||||
dceb2a935135d2ef502cdcba7c9d58f64062513f assets/create/lang/en_us.json
|
||||
eb40acb99f3c7af50b840f3c2058d7a7bdd5cff7 assets/create/lang/unfinished/de_de.json
|
||||
bcbfd3a6768daf265a1c01a424e985a3fdec6504 assets/create/lang/unfinished/es_es.json
|
||||
50dec8a7eb983ac4d29f3eeba3273dbaeca26902 assets/create/lang/unfinished/es_mx.json
|
||||
cc723673107651024f3fc0e43690ac467ff729b2 assets/create/lang/unfinished/fr_fr.json
|
||||
99452bacb5d80715ea0a52106b7e2734a32c55d4 assets/create/lang/unfinished/it_it.json
|
||||
f3058ea623666a43029af307f632197c8ff8dcab assets/create/lang/unfinished/ja_jp.json
|
||||
d756b02573d6a3a3b73bd03ec69fe760825e1606 assets/create/lang/unfinished/ko_kr.json
|
||||
281712735ab6437a417dde63c855e18eb19493a0 assets/create/lang/unfinished/nl_nl.json
|
||||
24056aefb7ff79a2127c194fe2918ab9e745d6b5 assets/create/lang/unfinished/pl_pl.json
|
||||
0f9c83a9f70d809d8f66c0438529b169b92ffdb1 assets/create/lang/unfinished/pt_br.json
|
||||
ff35273842d3190aa361f2a8ca7edae80f97864d assets/create/lang/unfinished/ru_ru.json
|
||||
139a31cfd09d4aaca33d118d28de735ba72f4f0d assets/create/lang/unfinished/zh_cn.json
|
||||
19bfa8f57e8b395a2cfd98039f44301a61c1f73c assets/create/lang/unfinished/zh_tw.json
|
||||
c71f5246d2cb8e9913d1552d23fcc82c43cde7a0 assets/create/lang/en_ud.json
|
||||
16738c5e5eeba8be9808ea44b695a76cd665156d assets/create/lang/en_us.json
|
||||
ffe020d59e813db401690b6c225b47a6e40c5c0b assets/create/lang/unfinished/de_de.json
|
||||
37bd77cae941d650e641079ce826894a9d738a15 assets/create/lang/unfinished/es_es.json
|
||||
5dc0552006fc2ca19bd12801bdfd9ebd34ce9ff1 assets/create/lang/unfinished/es_mx.json
|
||||
ad91c2c41ec0cbfab9341256f2e9bf5cf08b8cdc assets/create/lang/unfinished/fr_fr.json
|
||||
effbb185a45057ca686bdd5ef96f722f1c17bf4f assets/create/lang/unfinished/it_it.json
|
||||
e7a925d5187e3ca3cc417356012bfc68e08e262c assets/create/lang/unfinished/ja_jp.json
|
||||
3fcd98c23d179b63f48fff65806686f36170c09c assets/create/lang/unfinished/ko_kr.json
|
||||
04852300087f939dba6cd6941af3e0a35c710dfa assets/create/lang/unfinished/nl_nl.json
|
||||
b839c1dae703adaf5de99f3f40f3444f363752d9 assets/create/lang/unfinished/pl_pl.json
|
||||
2a514e604fb6e75ba79670576f2eb1d976be4416 assets/create/lang/unfinished/pt_br.json
|
||||
67c0bd43defecbc059a0afd89dae55d99198c95e assets/create/lang/unfinished/ru_ru.json
|
||||
1f5da639f8450d8cd818d938a871fad9a1041b3a assets/create/lang/unfinished/zh_cn.json
|
||||
25bf9dbb6163fb4be36afa0d4917bedbecb1cd3b assets/create/lang/unfinished/zh_tw.json
|
||||
487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json
|
||||
b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.json
|
||||
3066db1bf03cffa1a9c7fbacf47ae586632f4eb3 assets/create/models/block/acacia_window_pane_noside_alt.json
|
||||
|
@ -1273,6 +1273,7 @@ d7cb2f7bac8fae893fc5179af8140786a908f3f5 assets/create/models/item/copper_shingl
|
|||
f56bf22324faf8958eaef4d94b958f1108d52e5a assets/create/models/item/copper_tiles.json
|
||||
5583368909c319acfcf0f7a419bedf23272fe613 assets/create/models/item/copper_valve_handle.json
|
||||
4e253e7c0626dfd76e2d39786ce1a34e0baaa62d assets/create/models/item/crafter_slot_cover.json
|
||||
1f947dafff30da701b7675f5b026ccab3129b079 assets/create/models/item/crafting_blueprint.json
|
||||
7b333dea353afaa27b182aedc647c9e9e34e92ef assets/create/models/item/creative_crate.json
|
||||
f7d06c52c3ca8c22ad67f5741471f06ac22e7fcb assets/create/models/item/creative_fluid_tank.json
|
||||
5b39403f6c81f05e566b621b62e267267de47c41 assets/create/models/item/creative_motor.json
|
||||
|
@ -1653,7 +1654,7 @@ d080b1b25e5bc8baf5aee68691b08c7f12ece3b0 assets/create/models/item/windmill_bear
|
|||
a80fb25a0b655e76be986b5b49fcb0f03461a1ab assets/create/models/item/zinc_nugget.json
|
||||
b1689617190c05ef34bd18456b0c7ae09bb3210f assets/create/models/item/zinc_ore.json
|
||||
6490fa0587db770cf7c794b47f3bcd2b691f4226 assets/create/sounds.json
|
||||
0f1b4b980afba9bf2caf583b88e261bba8b10313 data/create/advancements/aesthetics.json
|
||||
5d0cc4c0255dc241e61c173b31ddca70c88d08e4 data/create/advancements/aesthetics.json
|
||||
187921fa131b06721bfaf63f2623a28c141aae9a data/create/advancements/andesite_alloy.json
|
||||
0ea2db7173b5be28b289ea7c9a6a0cf5805c60c7 data/create/advancements/andesite_casing.json
|
||||
83c046bd200623933545c9e4326f782fb02c87fa data/create/advancements/arm_blaze_burner.json
|
||||
|
|
|
@ -409,6 +409,7 @@
|
|||
"block.create.zinc_block": "\u0254u\u0131Z \u025Fo \u029E\u0254o\u05DF\u15FA",
|
||||
"block.create.zinc_ore": "\u01DD\u0279O \u0254u\u0131Z",
|
||||
"entity.create.contraption": "uo\u0131\u0287d\u0250\u0279\u0287uo\u0186",
|
||||
"entity.create.crafting_blueprint": "\u0287u\u0131\u0279d\u01DDn\u05DF\u15FA bu\u0131\u0287\u025F\u0250\u0279\u0186",
|
||||
"entity.create.gantry_contraption": "uo\u0131\u0287d\u0250\u0279\u0287uo\u0186 \u028E\u0279\u0287u\u0250\u2141",
|
||||
"entity.create.seat": "\u0287\u0250\u01DDS",
|
||||
"entity.create.stationary_contraption": "uo\u0131\u0287d\u0250\u0279\u0287uo\u0186 \u028E\u0279\u0250uo\u0131\u0287\u0250\u0287S",
|
||||
|
@ -437,6 +438,7 @@
|
|||
"item.create.copper_nugget": "\u0287\u01DDbbnN \u0279\u01DDddo\u0186",
|
||||
"item.create.copper_sheet": "\u0287\u01DD\u01DD\u0265S \u0279\u01DDddo\u0186",
|
||||
"item.create.crafter_slot_cover": "\u0279\u01DD\u028Co\u0186 \u0287o\u05DFS \u0279\u01DD\u0287\u025F\u0250\u0279\u0186",
|
||||
"item.create.crafting_blueprint": "\u0287u\u0131\u0279d\u01DDn\u05DF\u15FA bu\u0131\u0287\u025F\u0250\u0279\u0186",
|
||||
"item.create.crushed_aluminum_ore": "\u01DD\u0279O \u026Fnu\u0131\u026Fn\u05DF\u2C6F p\u01DD\u0265sn\u0279\u0186",
|
||||
"item.create.crushed_brass": "ss\u0250\u0279\u15FA p\u01DD\u0265sn\u0279\u0186",
|
||||
"item.create.crushed_copper_ore": "\u01DD\u0279O \u0279\u01DDddo\u0186 p\u01DD\u0265sn\u0279\u0186",
|
||||
|
|
|
@ -413,6 +413,7 @@
|
|||
"block.create.zinc_ore": "Zinc Ore",
|
||||
|
||||
"entity.create.contraption": "Contraption",
|
||||
"entity.create.crafting_blueprint": "Crafting Blueprint",
|
||||
"entity.create.gantry_contraption": "Gantry Contraption",
|
||||
"entity.create.seat": "Seat",
|
||||
"entity.create.stationary_contraption": "Stationary Contraption",
|
||||
|
@ -443,6 +444,7 @@
|
|||
"item.create.copper_nugget": "Copper Nugget",
|
||||
"item.create.copper_sheet": "Copper Sheet",
|
||||
"item.create.crafter_slot_cover": "Crafter Slot Cover",
|
||||
"item.create.crafting_blueprint": "Crafting Blueprint",
|
||||
"item.create.crushed_aluminum_ore": "Crushed Aluminum Ore",
|
||||
"item.create.crushed_brass": "Crushed Brass",
|
||||
"item.create.crushed_copper_ore": "Crushed Copper Ore",
|
||||
|
@ -1111,6 +1113,14 @@
|
|||
"create.linked_controller.frequency_slot_1": "Keybind: %1$s, Freq. #1",
|
||||
"create.linked_controller.frequency_slot_2": "Keybind: %1$s, Freq. #2",
|
||||
|
||||
"create.crafting_blueprint.crafting_slot": "Ingredient Slot",
|
||||
"create.crafting_blueprint.filter_items_viable": "Advanced filter items are viable",
|
||||
"create.crafting_blueprint.display_slot": "Display Slot",
|
||||
"create.crafting_blueprint.inferred": "Inferred from recipe",
|
||||
"create.crafting_blueprint.manually_assigned": "Manually assigned",
|
||||
"create.crafting_blueprint.secondary_display_slot": "Secondary Display Slot",
|
||||
"create.crafting_blueprint.optional": "Optional",
|
||||
|
||||
"create.hint.hose_pulley.title": "Bottomless Supply",
|
||||
"create.hint.hose_pulley": "The targeted body of fluid is considered infinite.",
|
||||
"create.hint.mechanical_arm_no_targets.title": "No Targets",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 953",
|
||||
"_": "Missing Localizations: 962",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -414,6 +414,7 @@
|
|||
"block.create.zinc_ore": "Zinkerz",
|
||||
|
||||
"entity.create.contraption": "Vorrichtung",
|
||||
"entity.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"entity.create.gantry_contraption": "Portalkran Vorrichtung",
|
||||
"entity.create.seat": "Sitz",
|
||||
"entity.create.stationary_contraption": "Stationäre Vorrichtung",
|
||||
|
@ -444,6 +445,7 @@
|
|||
"item.create.copper_nugget": "Kupferklumpen",
|
||||
"item.create.copper_sheet": "Kupferblech",
|
||||
"item.create.crafter_slot_cover": "Handwerkseinheit Slot Abdeckung",
|
||||
"item.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"item.create.crushed_aluminum_ore": "Zerkleinertes Aluminiumerz",
|
||||
"item.create.crushed_brass": "Zerkleinertes Messing",
|
||||
"item.create.crushed_copper_ore": "Zerkleinertes Kupfererz",
|
||||
|
@ -1112,6 +1114,14 @@
|
|||
"create.linked_controller.frequency_slot_1": "UNLOCALIZED: Keybind: %1$s, Freq. #1",
|
||||
"create.linked_controller.frequency_slot_2": "UNLOCALIZED: Keybind: %1$s, Freq. #2",
|
||||
|
||||
"create.crafting_blueprint.crafting_slot": "UNLOCALIZED: Ingredient Slot",
|
||||
"create.crafting_blueprint.filter_items_viable": "UNLOCALIZED: Advanced filter items are viable",
|
||||
"create.crafting_blueprint.display_slot": "UNLOCALIZED: Display Slot",
|
||||
"create.crafting_blueprint.inferred": "UNLOCALIZED: Inferred from recipe",
|
||||
"create.crafting_blueprint.manually_assigned": "UNLOCALIZED: Manually assigned",
|
||||
"create.crafting_blueprint.secondary_display_slot": "UNLOCALIZED: Secondary Display Slot",
|
||||
"create.crafting_blueprint.optional": "UNLOCALIZED: Optional",
|
||||
|
||||
"create.hint.hose_pulley.title": "Endlose Versorgung",
|
||||
"create.hint.hose_pulley": "Das angewählte Gewässer wird als unendlich betrachtet.",
|
||||
"create.hint.mechanical_arm_no_targets.title": "Keine Ziele",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 654",
|
||||
"_": "Missing Localizations: 663",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -414,6 +414,7 @@
|
|||
"block.create.zinc_ore": "Mineral de zinc",
|
||||
|
||||
"entity.create.contraption": "Artilugio",
|
||||
"entity.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"entity.create.gantry_contraption": "Artilugio de grúa",
|
||||
"entity.create.seat": "Asiento",
|
||||
"entity.create.stationary_contraption": "Artilugio estacionario",
|
||||
|
@ -444,6 +445,7 @@
|
|||
"item.create.copper_nugget": "Pepita de cobre",
|
||||
"item.create.copper_sheet": "Lámina de cobre",
|
||||
"item.create.crafter_slot_cover": "Tapa de ranura del Autoensamblador mecánico",
|
||||
"item.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"item.create.crushed_aluminum_ore": "Mineral de aluminio molido",
|
||||
"item.create.crushed_brass": "Latón molido",
|
||||
"item.create.crushed_copper_ore": "Mineral de cobre molido",
|
||||
|
@ -1112,6 +1114,14 @@
|
|||
"create.linked_controller.frequency_slot_1": "UNLOCALIZED: Keybind: %1$s, Freq. #1",
|
||||
"create.linked_controller.frequency_slot_2": "UNLOCALIZED: Keybind: %1$s, Freq. #2",
|
||||
|
||||
"create.crafting_blueprint.crafting_slot": "UNLOCALIZED: Ingredient Slot",
|
||||
"create.crafting_blueprint.filter_items_viable": "UNLOCALIZED: Advanced filter items are viable",
|
||||
"create.crafting_blueprint.display_slot": "UNLOCALIZED: Display Slot",
|
||||
"create.crafting_blueprint.inferred": "UNLOCALIZED: Inferred from recipe",
|
||||
"create.crafting_blueprint.manually_assigned": "UNLOCALIZED: Manually assigned",
|
||||
"create.crafting_blueprint.secondary_display_slot": "UNLOCALIZED: Secondary Display Slot",
|
||||
"create.crafting_blueprint.optional": "UNLOCALIZED: Optional",
|
||||
|
||||
"create.hint.hose_pulley.title": "Suministro sin fondo",
|
||||
"create.hint.hose_pulley": "La masa de fluido objetivo se considera infinita",
|
||||
"create.hint.mechanical_arm_no_targets.title": "No hay objetivos",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1277",
|
||||
"_": "Missing Localizations: 1286",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -414,6 +414,7 @@
|
|||
"block.create.zinc_ore": "Mineral de Zinc",
|
||||
|
||||
"entity.create.contraption": "Artefacto",
|
||||
"entity.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"entity.create.gantry_contraption": "UNLOCALIZED: Gantry Contraption",
|
||||
"entity.create.seat": "Asiento",
|
||||
"entity.create.stationary_contraption": "Artefacto Estacionario",
|
||||
|
@ -444,6 +445,7 @@
|
|||
"item.create.copper_nugget": "Pepita de Cobre",
|
||||
"item.create.copper_sheet": "Lámina de Cobre",
|
||||
"item.create.crafter_slot_cover": "Cubierta de Ranura del Crafter",
|
||||
"item.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"item.create.crushed_aluminum_ore": "Mineral de Aluminio Molido",
|
||||
"item.create.crushed_brass": "Latón Molido",
|
||||
"item.create.crushed_copper_ore": "Mineral de Cobre Molido",
|
||||
|
@ -1112,6 +1114,14 @@
|
|||
"create.linked_controller.frequency_slot_1": "UNLOCALIZED: Keybind: %1$s, Freq. #1",
|
||||
"create.linked_controller.frequency_slot_2": "UNLOCALIZED: Keybind: %1$s, Freq. #2",
|
||||
|
||||
"create.crafting_blueprint.crafting_slot": "UNLOCALIZED: Ingredient Slot",
|
||||
"create.crafting_blueprint.filter_items_viable": "UNLOCALIZED: Advanced filter items are viable",
|
||||
"create.crafting_blueprint.display_slot": "UNLOCALIZED: Display Slot",
|
||||
"create.crafting_blueprint.inferred": "UNLOCALIZED: Inferred from recipe",
|
||||
"create.crafting_blueprint.manually_assigned": "UNLOCALIZED: Manually assigned",
|
||||
"create.crafting_blueprint.secondary_display_slot": "UNLOCALIZED: Secondary Display Slot",
|
||||
"create.crafting_blueprint.optional": "UNLOCALIZED: Optional",
|
||||
|
||||
"create.hint.hose_pulley.title": "UNLOCALIZED: Bottomless Supply",
|
||||
"create.hint.hose_pulley": "UNLOCALIZED: The targeted body of fluid is considered infinite.",
|
||||
"create.hint.mechanical_arm_no_targets.title": "UNLOCALIZED: No Targets",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1205",
|
||||
"_": "Missing Localizations: 1214",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -414,6 +414,7 @@
|
|||
"block.create.zinc_ore": "Minerai de zinc",
|
||||
|
||||
"entity.create.contraption": "Engin",
|
||||
"entity.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"entity.create.gantry_contraption": "UNLOCALIZED: Gantry Contraption",
|
||||
"entity.create.seat": "Siège",
|
||||
"entity.create.stationary_contraption": "Engin stationnaire",
|
||||
|
@ -444,6 +445,7 @@
|
|||
"item.create.copper_nugget": "Pépite de cuivre",
|
||||
"item.create.copper_sheet": "Plaques de cuivre",
|
||||
"item.create.crafter_slot_cover": "Couvercle",
|
||||
"item.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"item.create.crushed_aluminum_ore": "Aluminium concassé",
|
||||
"item.create.crushed_brass": "Laiton concassé",
|
||||
"item.create.crushed_copper_ore": "Cuivre concassé",
|
||||
|
@ -1112,6 +1114,14 @@
|
|||
"create.linked_controller.frequency_slot_1": "UNLOCALIZED: Keybind: %1$s, Freq. #1",
|
||||
"create.linked_controller.frequency_slot_2": "UNLOCALIZED: Keybind: %1$s, Freq. #2",
|
||||
|
||||
"create.crafting_blueprint.crafting_slot": "UNLOCALIZED: Ingredient Slot",
|
||||
"create.crafting_blueprint.filter_items_viable": "UNLOCALIZED: Advanced filter items are viable",
|
||||
"create.crafting_blueprint.display_slot": "UNLOCALIZED: Display Slot",
|
||||
"create.crafting_blueprint.inferred": "UNLOCALIZED: Inferred from recipe",
|
||||
"create.crafting_blueprint.manually_assigned": "UNLOCALIZED: Manually assigned",
|
||||
"create.crafting_blueprint.secondary_display_slot": "UNLOCALIZED: Secondary Display Slot",
|
||||
"create.crafting_blueprint.optional": "UNLOCALIZED: Optional",
|
||||
|
||||
"create.hint.hose_pulley.title": "UNLOCALIZED: Bottomless Supply",
|
||||
"create.hint.hose_pulley": "UNLOCALIZED: The targeted body of fluid is considered infinite.",
|
||||
"create.hint.mechanical_arm_no_targets.title": "UNLOCALIZED: No Targets",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 671",
|
||||
"_": "Missing Localizations: 680",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -414,6 +414,7 @@
|
|||
"block.create.zinc_ore": "Zinco grezzo",
|
||||
|
||||
"entity.create.contraption": "Contrazione",
|
||||
"entity.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"entity.create.gantry_contraption": "UNLOCALIZED: Gantry Contraption",
|
||||
"entity.create.seat": "Sedile",
|
||||
"entity.create.stationary_contraption": "Contrazione stazionaria",
|
||||
|
@ -444,6 +445,7 @@
|
|||
"item.create.copper_nugget": "Pepita di rame",
|
||||
"item.create.copper_sheet": "Lamiera di rame",
|
||||
"item.create.crafter_slot_cover": "Rivestimento per slot da costruzione",
|
||||
"item.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"item.create.crushed_aluminum_ore": "Alluminio grezzo frantumato",
|
||||
"item.create.crushed_brass": "Ottone frantumato",
|
||||
"item.create.crushed_copper_ore": "Rame grezzo frantumato",
|
||||
|
@ -1112,6 +1114,14 @@
|
|||
"create.linked_controller.frequency_slot_1": "UNLOCALIZED: Keybind: %1$s, Freq. #1",
|
||||
"create.linked_controller.frequency_slot_2": "UNLOCALIZED: Keybind: %1$s, Freq. #2",
|
||||
|
||||
"create.crafting_blueprint.crafting_slot": "UNLOCALIZED: Ingredient Slot",
|
||||
"create.crafting_blueprint.filter_items_viable": "UNLOCALIZED: Advanced filter items are viable",
|
||||
"create.crafting_blueprint.display_slot": "UNLOCALIZED: Display Slot",
|
||||
"create.crafting_blueprint.inferred": "UNLOCALIZED: Inferred from recipe",
|
||||
"create.crafting_blueprint.manually_assigned": "UNLOCALIZED: Manually assigned",
|
||||
"create.crafting_blueprint.secondary_display_slot": "UNLOCALIZED: Secondary Display Slot",
|
||||
"create.crafting_blueprint.optional": "UNLOCALIZED: Optional",
|
||||
|
||||
"create.hint.hose_pulley.title": "Buco senza fondo",
|
||||
"create.hint.hose_pulley": "Il corpo fluido selezionato è considerato infinito.",
|
||||
"create.hint.mechanical_arm_no_targets.title": "Nessun bersaglio",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 35",
|
||||
"_": "Missing Localizations: 44",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -414,6 +414,7 @@
|
|||
"block.create.zinc_ore": "亜鉛鉱石",
|
||||
|
||||
"entity.create.contraption": "からくり",
|
||||
"entity.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"entity.create.gantry_contraption": "ガントリーからくり",
|
||||
"entity.create.seat": "シート",
|
||||
"entity.create.stationary_contraption": "付設からくり",
|
||||
|
@ -444,6 +445,7 @@
|
|||
"item.create.copper_nugget": "銅塊",
|
||||
"item.create.copper_sheet": "銅板",
|
||||
"item.create.crafter_slot_cover": "クラフタースロットカバー",
|
||||
"item.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"item.create.crushed_aluminum_ore": "砕いたアルミニウム鉱石",
|
||||
"item.create.crushed_brass": "砕いた真鍮",
|
||||
"item.create.crushed_copper_ore": "砕いた銅鉱石",
|
||||
|
@ -1112,6 +1114,14 @@
|
|||
"create.linked_controller.frequency_slot_1": "UNLOCALIZED: Keybind: %1$s, Freq. #1",
|
||||
"create.linked_controller.frequency_slot_2": "UNLOCALIZED: Keybind: %1$s, Freq. #2",
|
||||
|
||||
"create.crafting_blueprint.crafting_slot": "UNLOCALIZED: Ingredient Slot",
|
||||
"create.crafting_blueprint.filter_items_viable": "UNLOCALIZED: Advanced filter items are viable",
|
||||
"create.crafting_blueprint.display_slot": "UNLOCALIZED: Display Slot",
|
||||
"create.crafting_blueprint.inferred": "UNLOCALIZED: Inferred from recipe",
|
||||
"create.crafting_blueprint.manually_assigned": "UNLOCALIZED: Manually assigned",
|
||||
"create.crafting_blueprint.secondary_display_slot": "UNLOCALIZED: Secondary Display Slot",
|
||||
"create.crafting_blueprint.optional": "UNLOCALIZED: Optional",
|
||||
|
||||
"create.hint.hose_pulley.title": "底なし搬出",
|
||||
"create.hint.hose_pulley": "対象となる液体は無限とみなされています。",
|
||||
"create.hint.mechanical_arm_no_targets.title": "ターゲットが見つかりません",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 724",
|
||||
"_": "Missing Localizations: 733",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -414,6 +414,7 @@
|
|||
"block.create.zinc_ore": "아연 광석",
|
||||
|
||||
"entity.create.contraption": "장치",
|
||||
"entity.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"entity.create.gantry_contraption": "UNLOCALIZED: Gantry Contraption",
|
||||
"entity.create.seat": "좌석",
|
||||
"entity.create.stationary_contraption": "고정된 장치",
|
||||
|
@ -444,6 +445,7 @@
|
|||
"item.create.copper_nugget": "구리 조각",
|
||||
"item.create.copper_sheet": "구리 판",
|
||||
"item.create.crafter_slot_cover": "조합기 슬롯 덮개",
|
||||
"item.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"item.create.crushed_aluminum_ore": "UNLOCALIZED: Crushed Aluminum Ore",
|
||||
"item.create.crushed_brass": "분쇄된 황동",
|
||||
"item.create.crushed_copper_ore": "분쇄된 구리 광석",
|
||||
|
@ -1112,6 +1114,14 @@
|
|||
"create.linked_controller.frequency_slot_1": "UNLOCALIZED: Keybind: %1$s, Freq. #1",
|
||||
"create.linked_controller.frequency_slot_2": "UNLOCALIZED: Keybind: %1$s, Freq. #2",
|
||||
|
||||
"create.crafting_blueprint.crafting_slot": "UNLOCALIZED: Ingredient Slot",
|
||||
"create.crafting_blueprint.filter_items_viable": "UNLOCALIZED: Advanced filter items are viable",
|
||||
"create.crafting_blueprint.display_slot": "UNLOCALIZED: Display Slot",
|
||||
"create.crafting_blueprint.inferred": "UNLOCALIZED: Inferred from recipe",
|
||||
"create.crafting_blueprint.manually_assigned": "UNLOCALIZED: Manually assigned",
|
||||
"create.crafting_blueprint.secondary_display_slot": "UNLOCALIZED: Secondary Display Slot",
|
||||
"create.crafting_blueprint.optional": "UNLOCALIZED: Optional",
|
||||
|
||||
"create.hint.hose_pulley.title": "UNLOCALIZED: Bottomless Supply",
|
||||
"create.hint.hose_pulley": "UNLOCALIZED: The targeted body of fluid is considered infinite.",
|
||||
"create.hint.mechanical_arm_no_targets.title": "목표 없음",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1588",
|
||||
"_": "Missing Localizations: 1597",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -414,6 +414,7 @@
|
|||
"block.create.zinc_ore": "UNLOCALIZED: Zinc Ore",
|
||||
|
||||
"entity.create.contraption": "UNLOCALIZED: Contraption",
|
||||
"entity.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"entity.create.gantry_contraption": "UNLOCALIZED: Gantry Contraption",
|
||||
"entity.create.seat": "UNLOCALIZED: Seat",
|
||||
"entity.create.stationary_contraption": "UNLOCALIZED: Stationary Contraption",
|
||||
|
@ -444,6 +445,7 @@
|
|||
"item.create.copper_nugget": "Koper klompje",
|
||||
"item.create.copper_sheet": "UNLOCALIZED: Copper Sheet",
|
||||
"item.create.crafter_slot_cover": "UNLOCALIZED: Crafter Slot Cover",
|
||||
"item.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"item.create.crushed_aluminum_ore": "UNLOCALIZED: Crushed Aluminum Ore",
|
||||
"item.create.crushed_brass": "Gemalen Brons",
|
||||
"item.create.crushed_copper_ore": "UNLOCALIZED: Crushed Copper Ore",
|
||||
|
@ -1112,6 +1114,14 @@
|
|||
"create.linked_controller.frequency_slot_1": "UNLOCALIZED: Keybind: %1$s, Freq. #1",
|
||||
"create.linked_controller.frequency_slot_2": "UNLOCALIZED: Keybind: %1$s, Freq. #2",
|
||||
|
||||
"create.crafting_blueprint.crafting_slot": "UNLOCALIZED: Ingredient Slot",
|
||||
"create.crafting_blueprint.filter_items_viable": "UNLOCALIZED: Advanced filter items are viable",
|
||||
"create.crafting_blueprint.display_slot": "UNLOCALIZED: Display Slot",
|
||||
"create.crafting_blueprint.inferred": "UNLOCALIZED: Inferred from recipe",
|
||||
"create.crafting_blueprint.manually_assigned": "UNLOCALIZED: Manually assigned",
|
||||
"create.crafting_blueprint.secondary_display_slot": "UNLOCALIZED: Secondary Display Slot",
|
||||
"create.crafting_blueprint.optional": "UNLOCALIZED: Optional",
|
||||
|
||||
"create.hint.hose_pulley.title": "UNLOCALIZED: Bottomless Supply",
|
||||
"create.hint.hose_pulley": "UNLOCALIZED: The targeted body of fluid is considered infinite.",
|
||||
"create.hint.mechanical_arm_no_targets.title": "UNLOCALIZED: No Targets",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 11",
|
||||
"_": "Missing Localizations: 20",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -414,6 +414,7 @@
|
|||
"block.create.zinc_ore": "Ruda cynku",
|
||||
|
||||
"entity.create.contraption": "Maszyna",
|
||||
"entity.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"entity.create.gantry_contraption": "Maszyna suwnicowa",
|
||||
"entity.create.seat": "Siedzenie",
|
||||
"entity.create.stationary_contraption": "Maszyna stacjonarna",
|
||||
|
@ -444,6 +445,7 @@
|
|||
"item.create.copper_nugget": "Bryłka miedzi",
|
||||
"item.create.copper_sheet": "Arkusz miedzi",
|
||||
"item.create.crafter_slot_cover": "Przykrywka na slot stołu rzemieślniczego",
|
||||
"item.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"item.create.crushed_aluminum_ore": "Rozkruszona ruda żelaza",
|
||||
"item.create.crushed_brass": "Rozkruszony mosiądz",
|
||||
"item.create.crushed_copper_ore": "Rozkruszona ruda miedzi",
|
||||
|
@ -1112,6 +1114,14 @@
|
|||
"create.linked_controller.frequency_slot_1": "UNLOCALIZED: Keybind: %1$s, Freq. #1",
|
||||
"create.linked_controller.frequency_slot_2": "UNLOCALIZED: Keybind: %1$s, Freq. #2",
|
||||
|
||||
"create.crafting_blueprint.crafting_slot": "UNLOCALIZED: Ingredient Slot",
|
||||
"create.crafting_blueprint.filter_items_viable": "UNLOCALIZED: Advanced filter items are viable",
|
||||
"create.crafting_blueprint.display_slot": "UNLOCALIZED: Display Slot",
|
||||
"create.crafting_blueprint.inferred": "UNLOCALIZED: Inferred from recipe",
|
||||
"create.crafting_blueprint.manually_assigned": "UNLOCALIZED: Manually assigned",
|
||||
"create.crafting_blueprint.secondary_display_slot": "UNLOCALIZED: Secondary Display Slot",
|
||||
"create.crafting_blueprint.optional": "UNLOCALIZED: Optional",
|
||||
|
||||
"create.hint.hose_pulley.title": "Niewyczerpany zapas",
|
||||
"create.hint.hose_pulley": "Wybrane zbiornik cieczy jest uznany za nieskończony",
|
||||
"create.hint.mechanical_arm_no_targets.title": "Brak celi",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1640",
|
||||
"_": "Missing Localizations: 1649",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -414,6 +414,7 @@
|
|||
"block.create.zinc_ore": "UNLOCALIZED: Zinc Ore",
|
||||
|
||||
"entity.create.contraption": "UNLOCALIZED: Contraption",
|
||||
"entity.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"entity.create.gantry_contraption": "UNLOCALIZED: Gantry Contraption",
|
||||
"entity.create.seat": "UNLOCALIZED: Seat",
|
||||
"entity.create.stationary_contraption": "UNLOCALIZED: Stationary Contraption",
|
||||
|
@ -444,6 +445,7 @@
|
|||
"item.create.copper_nugget": "UNLOCALIZED: Copper Nugget",
|
||||
"item.create.copper_sheet": "UNLOCALIZED: Copper Sheet",
|
||||
"item.create.crafter_slot_cover": "UNLOCALIZED: Crafter Slot Cover",
|
||||
"item.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"item.create.crushed_aluminum_ore": "UNLOCALIZED: Crushed Aluminum Ore",
|
||||
"item.create.crushed_brass": "UNLOCALIZED: Crushed Brass",
|
||||
"item.create.crushed_copper_ore": "UNLOCALIZED: Crushed Copper Ore",
|
||||
|
@ -1112,6 +1114,14 @@
|
|||
"create.linked_controller.frequency_slot_1": "UNLOCALIZED: Keybind: %1$s, Freq. #1",
|
||||
"create.linked_controller.frequency_slot_2": "UNLOCALIZED: Keybind: %1$s, Freq. #2",
|
||||
|
||||
"create.crafting_blueprint.crafting_slot": "UNLOCALIZED: Ingredient Slot",
|
||||
"create.crafting_blueprint.filter_items_viable": "UNLOCALIZED: Advanced filter items are viable",
|
||||
"create.crafting_blueprint.display_slot": "UNLOCALIZED: Display Slot",
|
||||
"create.crafting_blueprint.inferred": "UNLOCALIZED: Inferred from recipe",
|
||||
"create.crafting_blueprint.manually_assigned": "UNLOCALIZED: Manually assigned",
|
||||
"create.crafting_blueprint.secondary_display_slot": "UNLOCALIZED: Secondary Display Slot",
|
||||
"create.crafting_blueprint.optional": "UNLOCALIZED: Optional",
|
||||
|
||||
"create.hint.hose_pulley.title": "UNLOCALIZED: Bottomless Supply",
|
||||
"create.hint.hose_pulley": "UNLOCALIZED: The targeted body of fluid is considered infinite.",
|
||||
"create.hint.mechanical_arm_no_targets.title": "UNLOCALIZED: No Targets",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 568",
|
||||
"_": "Missing Localizations: 577",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -414,6 +414,7 @@
|
|||
"block.create.zinc_ore": "Цинковая руда",
|
||||
|
||||
"entity.create.contraption": "Штуковина",
|
||||
"entity.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"entity.create.gantry_contraption": "UNLOCALIZED: Gantry Contraption",
|
||||
"entity.create.seat": "Сиденье",
|
||||
"entity.create.stationary_contraption": "Стационарная штуковина",
|
||||
|
@ -444,6 +445,7 @@
|
|||
"item.create.copper_nugget": "Кусочек меди",
|
||||
"item.create.copper_sheet": "Медный лист",
|
||||
"item.create.crafter_slot_cover": "Крышка на слот крафтера",
|
||||
"item.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"item.create.crushed_aluminum_ore": "Измельчённая алюминиевая руда",
|
||||
"item.create.crushed_brass": "Дроблёная латунь",
|
||||
"item.create.crushed_copper_ore": "Дроблёная медная руда",
|
||||
|
@ -1112,6 +1114,14 @@
|
|||
"create.linked_controller.frequency_slot_1": "UNLOCALIZED: Keybind: %1$s, Freq. #1",
|
||||
"create.linked_controller.frequency_slot_2": "UNLOCALIZED: Keybind: %1$s, Freq. #2",
|
||||
|
||||
"create.crafting_blueprint.crafting_slot": "UNLOCALIZED: Ingredient Slot",
|
||||
"create.crafting_blueprint.filter_items_viable": "UNLOCALIZED: Advanced filter items are viable",
|
||||
"create.crafting_blueprint.display_slot": "UNLOCALIZED: Display Slot",
|
||||
"create.crafting_blueprint.inferred": "UNLOCALIZED: Inferred from recipe",
|
||||
"create.crafting_blueprint.manually_assigned": "UNLOCALIZED: Manually assigned",
|
||||
"create.crafting_blueprint.secondary_display_slot": "UNLOCALIZED: Secondary Display Slot",
|
||||
"create.crafting_blueprint.optional": "UNLOCALIZED: Optional",
|
||||
|
||||
"create.hint.hose_pulley.title": "Безграничное снабжение",
|
||||
"create.hint.hose_pulley": "Целевой водный резервуар считается бесконечным.",
|
||||
"create.hint.mechanical_arm_no_targets.title": "Нет целей",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 54",
|
||||
"_": "Missing Localizations: 63",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -414,6 +414,7 @@
|
|||
"block.create.zinc_ore": "锌矿石",
|
||||
|
||||
"entity.create.contraption": "装置",
|
||||
"entity.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"entity.create.gantry_contraption": "起重机装置",
|
||||
"entity.create.seat": "坐垫",
|
||||
"entity.create.stationary_contraption": "固定装置",
|
||||
|
@ -444,6 +445,7 @@
|
|||
"item.create.copper_nugget": "铜粒",
|
||||
"item.create.copper_sheet": "铜板",
|
||||
"item.create.crafter_slot_cover": "合成器盖板",
|
||||
"item.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"item.create.crushed_aluminum_ore": "粉碎铝矿石",
|
||||
"item.create.crushed_brass": "粉碎黄铜",
|
||||
"item.create.crushed_copper_ore": "粉碎铜矿石",
|
||||
|
@ -1112,6 +1114,14 @@
|
|||
"create.linked_controller.frequency_slot_1": "UNLOCALIZED: Keybind: %1$s, Freq. #1",
|
||||
"create.linked_controller.frequency_slot_2": "UNLOCALIZED: Keybind: %1$s, Freq. #2",
|
||||
|
||||
"create.crafting_blueprint.crafting_slot": "UNLOCALIZED: Ingredient Slot",
|
||||
"create.crafting_blueprint.filter_items_viable": "UNLOCALIZED: Advanced filter items are viable",
|
||||
"create.crafting_blueprint.display_slot": "UNLOCALIZED: Display Slot",
|
||||
"create.crafting_blueprint.inferred": "UNLOCALIZED: Inferred from recipe",
|
||||
"create.crafting_blueprint.manually_assigned": "UNLOCALIZED: Manually assigned",
|
||||
"create.crafting_blueprint.secondary_display_slot": "UNLOCALIZED: Secondary Display Slot",
|
||||
"create.crafting_blueprint.optional": "UNLOCALIZED: Optional",
|
||||
|
||||
"create.hint.hose_pulley.title": "无限供应",
|
||||
"create.hint.hose_pulley": "目标液体对象被视为无限量的。",
|
||||
"create.hint.mechanical_arm_no_targets.title": "没有目标",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 47",
|
||||
"_": "Missing Localizations: 56",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -414,6 +414,7 @@
|
|||
"block.create.zinc_ore": "鋅礦石",
|
||||
|
||||
"entity.create.contraption": "結構",
|
||||
"entity.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"entity.create.gantry_contraption": "門式結構",
|
||||
"entity.create.seat": "坐墊",
|
||||
"entity.create.stationary_contraption": "固定結構",
|
||||
|
@ -444,6 +445,7 @@
|
|||
"item.create.copper_nugget": "銅粒",
|
||||
"item.create.copper_sheet": "銅板",
|
||||
"item.create.crafter_slot_cover": "合成器蓋板",
|
||||
"item.create.crafting_blueprint": "UNLOCALIZED: Crafting Blueprint",
|
||||
"item.create.crushed_aluminum_ore": "碎狀鋁礦石",
|
||||
"item.create.crushed_brass": "碎狀黃銅",
|
||||
"item.create.crushed_copper_ore": "碎狀銅礦石",
|
||||
|
@ -1112,6 +1114,14 @@
|
|||
"create.linked_controller.frequency_slot_1": "UNLOCALIZED: Keybind: %1$s, Freq. #1",
|
||||
"create.linked_controller.frequency_slot_2": "UNLOCALIZED: Keybind: %1$s, Freq. #2",
|
||||
|
||||
"create.crafting_blueprint.crafting_slot": "UNLOCALIZED: Ingredient Slot",
|
||||
"create.crafting_blueprint.filter_items_viable": "UNLOCALIZED: Advanced filter items are viable",
|
||||
"create.crafting_blueprint.display_slot": "UNLOCALIZED: Display Slot",
|
||||
"create.crafting_blueprint.inferred": "UNLOCALIZED: Inferred from recipe",
|
||||
"create.crafting_blueprint.manually_assigned": "UNLOCALIZED: Manually assigned",
|
||||
"create.crafting_blueprint.secondary_display_slot": "UNLOCALIZED: Secondary Display Slot",
|
||||
"create.crafting_blueprint.optional": "UNLOCALIZED: Optional",
|
||||
|
||||
"create.hint.hose_pulley.title": "無限供應",
|
||||
"create.hint.hose_pulley": "目標液體為無限供應",
|
||||
"create.hint.mechanical_arm_no_targets.title": "沒有目標",
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "create:item/crafting_blueprint"
|
||||
}
|
||||
}
|
|
@ -28,8 +28,8 @@
|
|||
"trigger": "create:bracket_apply",
|
||||
"conditions": {
|
||||
"accepted_entries": [
|
||||
"create:cogwheel",
|
||||
"create:large_cogwheel"
|
||||
"create:large_cogwheel",
|
||||
"create:cogwheel"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
|
@ -102,6 +102,10 @@ public class AllBlockPartials {
|
|||
COPPER_BACKTANK_SHAFT = get("copper_backtank/block_shaft_input"),
|
||||
COPPER_BACKTANK_COGS = get("copper_backtank/block_cogs"),
|
||||
|
||||
CRAFTING_BLUEPRINT_1x1 = getEntity("crafting_blueprint_small"),
|
||||
CRAFTING_BLUEPRINT_2x2 = getEntity("crafting_blueprint_medium"),
|
||||
CRAFTING_BLUEPRINT_3x3 = getEntity("crafting_blueprint_large"),
|
||||
|
||||
COUPLING_ATTACHMENT = getEntity("minecart_coupling/attachment"),
|
||||
COUPLING_RING = getEntity("minecart_coupling/ring"),
|
||||
COUPLING_CONNECTOR = getEntity("minecart_coupling/connector")
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
import com.simibubi.create.content.curiosities.tools.BlueprintContainer;
|
||||
import com.simibubi.create.content.curiosities.tools.BlueprintScreen;
|
||||
import com.simibubi.create.content.logistics.block.inventories.AdjustableCrateContainer;
|
||||
import com.simibubi.create.content.logistics.block.inventories.AdjustableCrateScreen;
|
||||
import com.simibubi.create.content.logistics.item.LinkedControllerContainer;
|
||||
|
@ -38,6 +40,9 @@ public class AllContainerTypes {
|
|||
public static final ContainerEntry<AttributeFilterContainer> ATTRIBUTE_FILTER =
|
||||
register("attribute_filter", AttributeFilterContainer::new, () -> AttributeFilterScreen::new);
|
||||
|
||||
public static final ContainerEntry<BlueprintContainer> CRAFTING_BLUEPRINT =
|
||||
register("crafting_blueprint", BlueprintContainer::new, () -> BlueprintScreen::new);
|
||||
|
||||
public static final ContainerEntry<LinkedControllerContainer> LINKED_CONTROLLER =
|
||||
register("linked_controller", LinkedControllerContainer::new, () -> LinkedControllerScreen::new);
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Ori
|
|||
import com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryContraptionEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueRenderer;
|
||||
import com.simibubi.create.content.curiosities.tools.BlueprintEntity;
|
||||
import com.simibubi.create.content.curiosities.tools.BlueprintRenderer;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.tterrag.registrate.util.entry.EntityEntry;
|
||||
import com.tterrag.registrate.util.nullness.NonNullConsumer;
|
||||
|
@ -35,6 +37,11 @@ public class AllEntityTypes {
|
|||
public static final EntityEntry<SuperGlueEntity> SUPER_GLUE =
|
||||
register("super_glue", SuperGlueEntity::new, () -> SuperGlueRenderer::new,
|
||||
EntityClassification.MISC, 10, Integer.MAX_VALUE, false, true, SuperGlueEntity::build);
|
||||
|
||||
public static final EntityEntry<BlueprintEntity> CRAFTING_BLUEPRINT =
|
||||
register("crafting_blueprint", BlueprintEntity::new, () -> BlueprintRenderer::new,
|
||||
EntityClassification.MISC, 10, Integer.MAX_VALUE, false, true, BlueprintEntity::build);
|
||||
|
||||
public static final EntityEntry<SeatEntity> SEAT =
|
||||
register("seat", SeatEntity::new, () -> SeatEntity.Render::new,
|
||||
EntityClassification.MISC, 0, Integer.MAX_VALUE, false, true, SeatEntity::build);
|
||||
|
|
|
@ -35,6 +35,7 @@ import com.simibubi.create.content.curiosities.armor.DivingBootsItem;
|
|||
import com.simibubi.create.content.curiosities.armor.DivingHelmetItem;
|
||||
import com.simibubi.create.content.curiosities.symmetry.SymmetryWandItem;
|
||||
import com.simibubi.create.content.curiosities.symmetry.client.SymmetryWandModel;
|
||||
import com.simibubi.create.content.curiosities.tools.BlueprintItem;
|
||||
import com.simibubi.create.content.curiosities.tools.ExtendoGripItem;
|
||||
import com.simibubi.create.content.curiosities.tools.ExtendoGripModel;
|
||||
import com.simibubi.create.content.curiosities.tools.SandPaperItem;
|
||||
|
@ -197,6 +198,10 @@ public class AllItems {
|
|||
REGISTRATE.item("minecart_coupling", MinecartCouplingItem::new)
|
||||
.register();
|
||||
|
||||
public static final ItemEntry<BlueprintItem> CRAFTING_BLUEPRINT =
|
||||
REGISTRATE.item("crafting_blueprint", BlueprintItem::new)
|
||||
.register();
|
||||
|
||||
public static final ItemEntry<SandPaperItem> SAND_PAPER = REGISTRATE.item("sand_paper", SandPaperItem::new)
|
||||
.transform(CreateRegistrate.customRenderedItem(() -> SandPaperModel::new))
|
||||
.register();
|
||||
|
@ -222,7 +227,7 @@ public class AllItems {
|
|||
.transform(CreateRegistrate.customRenderedItem(() -> LinkedControllerModel::new))
|
||||
.model(AssetLookup.itemModelWithPartials())
|
||||
.register();
|
||||
|
||||
|
||||
public static final ItemEntry<SymmetryWandItem> WAND_OF_SYMMETRY =
|
||||
REGISTRATE.item("wand_of_symmetry", SymmetryWandItem::new)
|
||||
.transform(CreateRegistrate.customRenderedItem(() -> SymmetryWandModel::new))
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package com.simibubi.create.compat.jei;
|
||||
|
||||
import com.simibubi.create.content.curiosities.tools.BlueprintAssignCompleteRecipePacket;
|
||||
import com.simibubi.create.content.curiosities.tools.BlueprintContainer;
|
||||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
|
||||
import mezz.jei.api.gui.IRecipeLayout;
|
||||
import mezz.jei.api.recipe.transfer.IRecipeTransferError;
|
||||
import mezz.jei.api.recipe.transfer.IRecipeTransferHandler;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
|
||||
public class BlueprintTransferHandler implements IRecipeTransferHandler<BlueprintContainer> {
|
||||
|
||||
@Override
|
||||
public Class<BlueprintContainer> getContainerClass() {
|
||||
return BlueprintContainer.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IRecipeTransferError transferRecipe(BlueprintContainer container, Object recipe, IRecipeLayout recipeLayout,
|
||||
PlayerEntity player, boolean maxTransfer, boolean doTransfer) {
|
||||
if (!(recipe instanceof IRecipe))
|
||||
return null;
|
||||
IRecipe<?> iRecipe = (IRecipe<?>) recipe;
|
||||
// Continued server-side in BlueprintItem.assignCompleteRecipe()
|
||||
AllPackets.channel.sendToServer(new BlueprintAssignCompleteRecipePacket(iRecipe.getId()));
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -39,6 +39,7 @@ import com.simibubi.create.content.contraptions.components.press.MechanicalPress
|
|||
import com.simibubi.create.content.contraptions.components.saw.SawTileEntity;
|
||||
import com.simibubi.create.content.contraptions.fluids.recipe.PotionMixingRecipeManager;
|
||||
import com.simibubi.create.content.contraptions.processing.BasinRecipe;
|
||||
import com.simibubi.create.content.curiosities.tools.BlueprintScreen;
|
||||
import com.simibubi.create.content.logistics.block.inventories.AdjustableCrateScreen;
|
||||
import com.simibubi.create.content.logistics.item.filter.AbstractFilterScreen;
|
||||
import com.simibubi.create.content.logistics.item.filter.AttributeFilterScreen;
|
||||
|
@ -51,10 +52,12 @@ import com.simibubi.create.foundation.config.ConfigBase.ConfigBool;
|
|||
|
||||
import mezz.jei.api.IModPlugin;
|
||||
import mezz.jei.api.JeiPlugin;
|
||||
import mezz.jei.api.constants.VanillaRecipeCategoryUid;
|
||||
import mezz.jei.api.registration.IGuiHandlerRegistration;
|
||||
import mezz.jei.api.registration.IRecipeCatalystRegistration;
|
||||
import mezz.jei.api.registration.IRecipeCategoryRegistration;
|
||||
import mezz.jei.api.registration.IRecipeRegistration;
|
||||
import mezz.jei.api.registration.IRecipeTransferRegistration;
|
||||
import mezz.jei.api.runtime.IIngredientManager;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
@ -84,9 +87,9 @@ public class CreateJEI implements IModPlugin {
|
|||
private final List<CreateRecipeCategory<?>> allCategories = new ArrayList<>();
|
||||
private final CreateRecipeCategory<?>
|
||||
|
||||
milling = register("milling", MillingCategory::new).recipes(AllRecipeTypes.MILLING)
|
||||
.catalyst(AllBlocks.MILLSTONE::get)
|
||||
.build(),
|
||||
milling = register("milling", MillingCategory::new).recipes(AllRecipeTypes.MILLING)
|
||||
.catalyst(AllBlocks.MILLSTONE::get)
|
||||
.build(),
|
||||
|
||||
crushing = register("crushing", CrushingCategory::new).recipes(AllRecipeTypes.CRUSHING)
|
||||
.recipesExcluding(AllRecipeTypes.MILLING::getType, AllRecipeTypes.CRUSHING::getType)
|
||||
|
@ -167,9 +170,10 @@ public class CreateJEI implements IModPlugin {
|
|||
.catalyst(AllItems.SAND_PAPER::get)
|
||||
.catalyst(AllItems.RED_SAND_PAPER::get)
|
||||
.build(),
|
||||
|
||||
|
||||
deploying = register("deploying", DeployingCategory::new)
|
||||
.recipeList(() -> DeployerApplicationRecipe.convert(findRecipesByType(AllRecipeTypes.SANDPAPER_POLISHING.type)))
|
||||
.recipeList(
|
||||
() -> DeployerApplicationRecipe.convert(findRecipesByType(AllRecipeTypes.SANDPAPER_POLISHING.type)))
|
||||
.recipes(AllRecipeTypes.DEPLOYING)
|
||||
.catalyst(AllBlocks.DEPLOYER::get)
|
||||
.catalyst(AllBlocks.DEPOT::get)
|
||||
|
@ -213,6 +217,11 @@ public class CreateJEI implements IModPlugin {
|
|||
return new CategoryBuilder<T>(name, supplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRecipeTransferHandlers(IRecipeTransferRegistration registration) {
|
||||
registration.addRecipeTransferHandler(new BlueprintTransferHandler(), VanillaRecipeCategoryUid.CRAFTING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerCategories(IRecipeCategoryRegistration registration) {
|
||||
allCategories.forEach(registration::addRecipeCategories);
|
||||
|
@ -238,7 +247,8 @@ public class CreateJEI implements IModPlugin {
|
|||
registration.addGuiContainerHandler(SchematicTableScreen.class, slotMover);
|
||||
registration.addGuiContainerHandler(FilterScreen.class, slotMover);
|
||||
registration.addGuiContainerHandler(AttributeFilterScreen.class, slotMover);
|
||||
registration.addGhostIngredientHandler(AbstractFilterScreen.class, new FilterGhostIngredientHandler());
|
||||
registration.addGhostIngredientHandler(AbstractFilterScreen.class, new GhostIngredientHandler());
|
||||
registration.addGhostIngredientHandler(BlueprintScreen.class, new GhostIngredientHandler());
|
||||
}
|
||||
|
||||
private class CategoryBuilder<T extends IRecipe<?>> {
|
||||
|
@ -278,12 +288,12 @@ public class CreateJEI implements IModPlugin {
|
|||
return recipeList(list, null);
|
||||
}
|
||||
|
||||
public CategoryBuilder<T> recipeList(Supplier<List<? extends IRecipe<?>>> list, Function<IRecipe<?>, T> converter) {
|
||||
public CategoryBuilder<T> recipeList(Supplier<List<? extends IRecipe<?>>> list,
|
||||
Function<IRecipe<?>, T> converter) {
|
||||
recipeListConsumers.add(recipes -> {
|
||||
List<? extends IRecipe<?>> toAdd = list.get();
|
||||
if (converter != null)
|
||||
toAdd = toAdd
|
||||
.stream()
|
||||
toAdd = toAdd.stream()
|
||||
.map(converter)
|
||||
.collect(Collectors.toList());
|
||||
recipes.addAll(toAdd);
|
||||
|
|
|
@ -5,12 +5,10 @@ import java.util.List;
|
|||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
import com.simibubi.create.content.logistics.item.filter.AbstractFilterContainer;
|
||||
import com.simibubi.create.content.logistics.item.filter.AbstractFilterScreen;
|
||||
import com.simibubi.create.content.logistics.item.filter.AttributeFilterScreen;
|
||||
import com.simibubi.create.content.logistics.item.filter.FilterScreenPacket;
|
||||
import com.simibubi.create.foundation.gui.AbstractSimiContainerScreen;
|
||||
import com.simibubi.create.foundation.gui.GhostItemContainer;
|
||||
import com.simibubi.create.foundation.gui.GhostItemSubmitPacket;
|
||||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
|
@ -18,21 +16,20 @@ import mezz.jei.api.gui.handlers.IGhostIngredientHandler;
|
|||
import net.minecraft.client.renderer.Rectangle2d;
|
||||
import net.minecraft.inventory.container.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
|
||||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault
|
||||
public class FilterGhostIngredientHandler<T extends AbstractFilterContainer>
|
||||
implements IGhostIngredientHandler<AbstractFilterScreen<T>> {
|
||||
public class GhostIngredientHandler<T extends GhostItemContainer<?>>
|
||||
implements IGhostIngredientHandler<AbstractSimiContainerScreen<T>> {
|
||||
|
||||
@Override
|
||||
public <I> List<Target<I>> getTargets(AbstractFilterScreen<T> gui, I ingredient, boolean doStart) {
|
||||
public <I> List<Target<I>> getTargets(AbstractSimiContainerScreen<T> gui, I ingredient, boolean doStart) {
|
||||
List<Target<I>> targets = new ArrayList<>();
|
||||
boolean isAttributeFilter = gui instanceof AttributeFilterScreen;
|
||||
|
||||
if (ingredient instanceof ItemStack) {
|
||||
for (int i = 36; i < gui.getContainer().inventorySlots.size(); i++) {
|
||||
targets.add(new FilterGhostTarget<>(gui, i - 36, isAttributeFilter));
|
||||
targets.add(new GhostTarget<>(gui, i - 36, isAttributeFilter));
|
||||
|
||||
// Only accept items in 1st slot. 2nd is used for functionality, don't wanna override that one
|
||||
if (isAttributeFilter)
|
||||
|
@ -52,14 +49,14 @@ public class FilterGhostIngredientHandler<T extends AbstractFilterContainer>
|
|||
return true;
|
||||
}
|
||||
|
||||
private static class FilterGhostTarget<I, T extends AbstractFilterContainer> implements Target<I> {
|
||||
private static class GhostTarget<I, T extends GhostItemContainer<?>> implements Target<I> {
|
||||
|
||||
private final Rectangle2d area;
|
||||
private final AbstractFilterScreen<T> gui;
|
||||
private final AbstractSimiContainerScreen<T> gui;
|
||||
private final int slotIndex;
|
||||
private final boolean isAttributeFilter;
|
||||
|
||||
public FilterGhostTarget(AbstractFilterScreen<T> gui, int slotIndex, boolean isAttributeFilter) {
|
||||
public GhostTarget(AbstractSimiContainerScreen<T> gui, int slotIndex, boolean isAttributeFilter) {
|
||||
this.gui = gui;
|
||||
this.slotIndex = slotIndex;
|
||||
this.isAttributeFilter = isAttributeFilter;
|
||||
|
@ -75,19 +72,14 @@ public class FilterGhostIngredientHandler<T extends AbstractFilterContainer>
|
|||
@Override
|
||||
public void accept(I ingredient) {
|
||||
ItemStack stack = ((ItemStack) ingredient).copy();
|
||||
LogManager.getLogger()
|
||||
.info(stack);
|
||||
stack.setCount(1);
|
||||
gui.getContainer().filterInventory.setStackInSlot(slotIndex, stack);
|
||||
gui.getContainer().ghostInventory.setStackInSlot(slotIndex, stack);
|
||||
|
||||
if (isAttributeFilter)
|
||||
return;
|
||||
|
||||
// sync new filter contents with server
|
||||
CompoundNBT data = new CompoundNBT();
|
||||
data.putInt("Slot", slotIndex);
|
||||
data.put("Item", stack.serializeNBT());
|
||||
AllPackets.channel.sendToServer(new FilterScreenPacket(FilterScreenPacket.Option.UPDATE_FILTER_ITEM, data));
|
||||
AllPackets.channel.sendToServer(new GhostItemSubmitPacket(stack, slotIndex));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.simibubi.create.content.curiosities.tools;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.network.NetworkEvent.Context;
|
||||
|
||||
public class BlueprintAssignCompleteRecipePacket extends SimplePacketBase {
|
||||
|
||||
private ResourceLocation recipeID;
|
||||
|
||||
public BlueprintAssignCompleteRecipePacket(ResourceLocation recipeID) {
|
||||
this.recipeID = recipeID;
|
||||
}
|
||||
|
||||
public BlueprintAssignCompleteRecipePacket(PacketBuffer buffer) {
|
||||
recipeID = buffer.readResourceLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketBuffer buffer) {
|
||||
buffer.writeResourceLocation(recipeID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Supplier<Context> context) {
|
||||
context.get()
|
||||
.enqueueWork(() -> {
|
||||
ServerPlayerEntity player = context.get()
|
||||
.getSender();
|
||||
if (player == null)
|
||||
return;
|
||||
if (player.openContainer instanceof BlueprintContainer) {
|
||||
BlueprintContainer c = (BlueprintContainer) player.openContainer;
|
||||
player.getServerWorld()
|
||||
.getRecipeManager()
|
||||
.getRecipe(recipeID)
|
||||
.ifPresent(r -> BlueprintItem.assignCompleteRecipe(c.ghostInventory, r));
|
||||
}
|
||||
});
|
||||
context.get()
|
||||
.setPacketHandled(true);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,172 @@
|
|||
package com.simibubi.create.content.curiosities.tools;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import com.simibubi.create.AllContainerTypes;
|
||||
import com.simibubi.create.content.curiosities.tools.BlueprintEntity.BlueprintSection;
|
||||
import com.simibubi.create.foundation.gui.GhostItemContainer;
|
||||
import com.simibubi.create.foundation.gui.IClearableContainer;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.inventory.CraftingInventory;
|
||||
import net.minecraft.inventory.container.Container;
|
||||
import net.minecraft.inventory.container.ContainerType;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.ICraftingRecipe;
|
||||
import net.minecraft.item.crafting.IRecipeType;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.network.play.server.SSetSlotPacket;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.minecraftforge.items.SlotItemHandler;
|
||||
|
||||
public class BlueprintContainer extends GhostItemContainer<BlueprintSection> implements IClearableContainer {
|
||||
|
||||
public BlueprintContainer(ContainerType<?> type, int id, PlayerInventory inv, PacketBuffer extraData) {
|
||||
super(type, id, inv, extraData);
|
||||
}
|
||||
|
||||
public BlueprintContainer(ContainerType<?> type, int id, PlayerInventory inv, BlueprintSection section) {
|
||||
super(type, id, inv, section);
|
||||
}
|
||||
|
||||
public static BlueprintContainer create(int id, PlayerInventory inv, BlueprintSection section) {
|
||||
return new BlueprintContainer(AllContainerTypes.CRAFTING_BLUEPRINT.get(), id, inv, section);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean allowRepeats() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addSlots() {
|
||||
addPlayerSlots(33, 137);
|
||||
|
||||
int x = 29;
|
||||
int y = 21;
|
||||
int index = 0;
|
||||
for (int row = 0; row < 3; ++row)
|
||||
for (int col = 0; col < 3; ++col)
|
||||
this.addSlot(new BlueprintCraftSlot(ghostInventory, index++, x + col * 18, y + row * 18));
|
||||
|
||||
addSlot(new BlueprintCraftSlot(ghostInventory, index++, 123, 40));
|
||||
addSlot(new SlotItemHandler(ghostInventory, index++, 135, 57));
|
||||
}
|
||||
|
||||
public void onCraftMatrixChanged() {
|
||||
if (contentHolder.getBlueprintWorld().isRemote)
|
||||
return;
|
||||
|
||||
ServerPlayerEntity serverplayerentity = (ServerPlayerEntity) player;
|
||||
CraftingInventory craftingInventory = new BlueprintCraftingInventory(this, ghostInventory);
|
||||
Optional<ICraftingRecipe> optional = player.getServer()
|
||||
.getRecipeManager()
|
||||
.getRecipe(IRecipeType.CRAFTING, craftingInventory, player.getEntityWorld());
|
||||
|
||||
if (!optional.isPresent()) {
|
||||
if (ghostInventory.getStackInSlot(9)
|
||||
.isEmpty())
|
||||
return;
|
||||
if (!contentHolder.inferredIcon)
|
||||
return;
|
||||
|
||||
ghostInventory.setStackInSlot(9, ItemStack.EMPTY);
|
||||
serverplayerentity.connection.sendPacket(new SSetSlotPacket(windowId, 36 + 9, ItemStack.EMPTY));
|
||||
contentHolder.inferredIcon = false;
|
||||
return;
|
||||
}
|
||||
|
||||
ICraftingRecipe icraftingrecipe = optional.get();
|
||||
ItemStack itemstack = icraftingrecipe.getCraftingResult(craftingInventory);
|
||||
ghostInventory.setStackInSlot(9, itemstack);
|
||||
contentHolder.inferredIcon = true;
|
||||
ItemStack toSend = itemstack.copy();
|
||||
toSend.getOrCreateTag()
|
||||
.putBoolean("InferredFromRecipe", true);
|
||||
serverplayerentity.connection.sendPacket(new SSetSlotPacket(windowId, 36 + 9, toSend));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putStackInSlot(int p_75141_1_, ItemStack p_75141_2_) {
|
||||
if (p_75141_1_ == 36 + 9) {
|
||||
if (p_75141_2_.hasTag()) {
|
||||
contentHolder.inferredIcon = p_75141_2_.getTag()
|
||||
.getBoolean("InferredFromRecipe");
|
||||
p_75141_2_.getTag()
|
||||
.remove("InferredFromRecipe");
|
||||
} else
|
||||
contentHolder.inferredIcon = false;
|
||||
}
|
||||
super.putStackInSlot(p_75141_1_, p_75141_2_);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemStackHandler createGhostInventory() {
|
||||
return contentHolder.getItems();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readData(BlueprintSection contentHolder) {}
|
||||
|
||||
@Override
|
||||
protected void saveData(BlueprintSection contentHolder) {
|
||||
contentHolder.save(ghostInventory);
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
protected BlueprintSection createOnClient(PacketBuffer extraData) {
|
||||
int entityID = extraData.readVarInt();
|
||||
int section = extraData.readVarInt();
|
||||
Entity entityByID = Minecraft.getInstance().world.getEntityByID(entityID);
|
||||
if (!(entityByID instanceof BlueprintEntity))
|
||||
return null;
|
||||
BlueprintEntity blueprintEntity = (BlueprintEntity) entityByID;
|
||||
BlueprintSection blueprintSection = blueprintEntity.getSection(section);
|
||||
return blueprintSection;
|
||||
}
|
||||
|
||||
static class BlueprintCraftingInventory extends CraftingInventory {
|
||||
|
||||
public BlueprintCraftingInventory(Container container, ItemStackHandler items) {
|
||||
super(container, 3, 3);
|
||||
for (int y = 0; y < 3; y++) {
|
||||
for (int x = 0; x < 3; x++) {
|
||||
ItemStack stack = items.getStackInSlot(y * 3 + x);
|
||||
setInventorySlotContents(y * 3 + x, stack == null ? ItemStack.EMPTY : stack.copy());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class BlueprintCraftSlot extends SlotItemHandler {
|
||||
|
||||
private int index;
|
||||
|
||||
public BlueprintCraftSlot(IItemHandler itemHandler, int index, int xPosition, int yPosition) {
|
||||
super(itemHandler, index, xPosition, yPosition);
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSlotChanged() {
|
||||
super.onSlotChanged();
|
||||
if (index == 9 && getHasStack() && !contentHolder.getBlueprintWorld().isRemote) {
|
||||
contentHolder.inferredIcon = false;
|
||||
ServerPlayerEntity serverplayerentity = (ServerPlayerEntity) player;
|
||||
serverplayerentity.connection.sendPacket(new SSetSlotPacket(windowId, 36 + 9, getStack()));
|
||||
}
|
||||
if (index < 9)
|
||||
onCraftMatrixChanged();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,527 @@
|
|||
package com.simibubi.create.content.curiosities.tools;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import com.simibubi.create.AllEntityTypes;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.logistics.item.filter.FilterItem;
|
||||
import com.simibubi.create.content.schematics.ISpecialEntityItemRequirement;
|
||||
import com.simibubi.create.content.schematics.ItemRequirement;
|
||||
import com.simibubi.create.content.schematics.ItemRequirement.ItemUseType;
|
||||
import com.simibubi.create.foundation.networking.ISyncPersistentData;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.RedstoneDiodeBlock;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntitySize;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.Pose;
|
||||
import net.minecraft.entity.item.HangingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.inventory.CraftingInventory;
|
||||
import net.minecraft.inventory.container.Container;
|
||||
import net.minecraft.inventory.container.INamedContainerProvider;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.ICraftingRecipe;
|
||||
import net.minecraft.item.crafting.IRecipeType;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.network.IPacket;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.world.GameRules;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.common.ForgeHooks;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
||||
import net.minecraftforge.fml.hooks.BasicEventHooks;
|
||||
import net.minecraftforge.fml.network.NetworkHooks;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.minecraftforge.items.wrapper.InvWrapper;
|
||||
|
||||
public class BlueprintEntity extends HangingEntity
|
||||
implements IEntityAdditionalSpawnData, ISpecialEntityItemRequirement, ISyncPersistentData {
|
||||
|
||||
protected int size;
|
||||
protected Direction verticalOrientation;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public BlueprintEntity(EntityType<?> p_i50221_1_, World p_i50221_2_) {
|
||||
super((EntityType<? extends HangingEntity>) p_i50221_1_, p_i50221_2_);
|
||||
size = 1;
|
||||
}
|
||||
|
||||
public BlueprintEntity(World world, BlockPos pos, Direction facing, Direction verticalOrientation) {
|
||||
super(AllEntityTypes.CRAFTING_BLUEPRINT.get(), world, pos);
|
||||
|
||||
for (int size = 3; size > 0; size--) {
|
||||
this.size = size;
|
||||
this.updateFacingWithBoundingBox(facing, verticalOrientation);
|
||||
if (this.onValidSurface())
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static EntityType.Builder<?> build(EntityType.Builder<?> builder) {
|
||||
@SuppressWarnings("unchecked")
|
||||
EntityType.Builder<BlueprintEntity> entityBuilder = (EntityType.Builder<BlueprintEntity>) builder;
|
||||
return entityBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPacket<?> createSpawnPacket() {
|
||||
return NetworkHooks.getEntitySpawningPacket(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeAdditional(CompoundNBT p_213281_1_) {
|
||||
p_213281_1_.putByte("Facing", (byte) this.facingDirection.getIndex());
|
||||
p_213281_1_.putByte("Orientation", (byte) this.verticalOrientation.getIndex());
|
||||
p_213281_1_.putInt("Size", size);
|
||||
super.writeAdditional(p_213281_1_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readAdditional(CompoundNBT p_70037_1_) {
|
||||
this.facingDirection = Direction.byIndex(p_70037_1_.getByte("Facing"));
|
||||
this.verticalOrientation = Direction.byIndex(p_70037_1_.getByte("Orientation"));
|
||||
this.size = p_70037_1_.getInt("Size");
|
||||
super.readAdditional(p_70037_1_);
|
||||
this.updateFacingWithBoundingBox(this.facingDirection, this.verticalOrientation);
|
||||
}
|
||||
|
||||
protected void updateFacingWithBoundingBox(Direction facing, Direction verticalOrientation) {
|
||||
Validate.notNull(facing);
|
||||
this.facingDirection = facing;
|
||||
this.verticalOrientation = verticalOrientation;
|
||||
if (facing.getAxis()
|
||||
.isHorizontal()) {
|
||||
this.rotationPitch = 0.0F;
|
||||
this.rotationYaw = (float) (this.facingDirection.getHorizontalIndex() * 90);
|
||||
} else {
|
||||
this.rotationPitch = (float) (-90 * facing.getAxisDirection()
|
||||
.getOffset());
|
||||
this.rotationYaw = verticalOrientation.getAxis()
|
||||
.isHorizontal() ? 180 + verticalOrientation.getHorizontalAngle() : 0;
|
||||
}
|
||||
|
||||
this.prevRotationPitch = this.rotationPitch;
|
||||
this.prevRotationYaw = this.rotationYaw;
|
||||
this.updateBoundingBox();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getEyeHeight(Pose p_213316_1_, EntitySize p_213316_2_) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateBoundingBox() {
|
||||
if (this.facingDirection == null)
|
||||
return;
|
||||
if (this.verticalOrientation == null)
|
||||
return;
|
||||
|
||||
Vector3d pos = Vector3d.of(hangingPosition)
|
||||
.add(.5, .5, .5)
|
||||
.subtract(Vector3d.of(facingDirection.getDirectionVec())
|
||||
.scale(0.46875));
|
||||
double d1 = pos.x;
|
||||
double d2 = pos.y;
|
||||
double d3 = pos.z;
|
||||
this.setPos(d1, d2, d3);
|
||||
|
||||
Axis axis = facingDirection.getAxis();
|
||||
if (size == 2)
|
||||
pos = pos.add(Vector3d.of(axis.isHorizontal() ? facingDirection.rotateYCCW()
|
||||
.getDirectionVec()
|
||||
: verticalOrientation.rotateY()
|
||||
.getDirectionVec())
|
||||
.scale(0.5))
|
||||
.add(Vector3d
|
||||
.of(axis.isHorizontal() ? Direction.UP.getDirectionVec()
|
||||
: facingDirection == Direction.UP ? verticalOrientation.getDirectionVec()
|
||||
: verticalOrientation.getOpposite()
|
||||
.getDirectionVec())
|
||||
.scale(0.5));
|
||||
|
||||
d1 = pos.x;
|
||||
d2 = pos.y;
|
||||
d3 = pos.z;
|
||||
|
||||
double d4 = (double) this.getWidthPixels();
|
||||
double d5 = (double) this.getHeightPixels();
|
||||
double d6 = (double) this.getWidthPixels();
|
||||
Direction.Axis direction$axis = this.facingDirection.getAxis();
|
||||
switch (direction$axis) {
|
||||
case X:
|
||||
d4 = 1.0D;
|
||||
break;
|
||||
case Y:
|
||||
d5 = 1.0D;
|
||||
break;
|
||||
case Z:
|
||||
d6 = 1.0D;
|
||||
}
|
||||
|
||||
d4 = d4 / 32.0D;
|
||||
d5 = d5 / 32.0D;
|
||||
d6 = d6 / 32.0D;
|
||||
this.setBoundingBox(new AxisAlignedBB(d1 - d4, d2 - d5, d3 - d6, d1 + d4, d2 + d5, d3 + d6));
|
||||
}
|
||||
|
||||
public boolean onValidSurface() {
|
||||
if (!world.isSpaceEmpty(this))
|
||||
return false;
|
||||
|
||||
int i = Math.max(1, this.getWidthPixels() / 16);
|
||||
int j = Math.max(1, this.getHeightPixels() / 16);
|
||||
BlockPos blockpos = this.hangingPosition.offset(this.facingDirection.getOpposite());
|
||||
Direction upDirection = facingDirection.getAxis()
|
||||
.isHorizontal() ? Direction.UP
|
||||
: facingDirection == Direction.UP ? verticalOrientation : verticalOrientation.getOpposite();
|
||||
Direction direction = facingDirection.getAxis()
|
||||
.isVertical() ? verticalOrientation.rotateY() : facingDirection.rotateYCCW();
|
||||
BlockPos.Mutable blockpos$mutable = new BlockPos.Mutable();
|
||||
|
||||
for (int k = 0; k < i; ++k) {
|
||||
for (int l = 0; l < j; ++l) {
|
||||
int i1 = (i - 1) / -2;
|
||||
int j1 = (j - 1) / -2;
|
||||
blockpos$mutable.setPos(blockpos)
|
||||
.move(direction, k + i1)
|
||||
.move(upDirection, l + j1);
|
||||
BlockState blockstate = this.world.getBlockState(blockpos$mutable);
|
||||
if (Block.hasEnoughSolidSide(this.world, blockpos$mutable, this.facingDirection))
|
||||
continue;
|
||||
if (!blockstate.getMaterial()
|
||||
.isSolid() && !RedstoneDiodeBlock.isDiode(blockstate)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.world.getEntitiesInAABBexcluding(this, this.getBoundingBox(), IS_HANGING_ENTITY)
|
||||
.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidthPixels() {
|
||||
return 16 * size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeightPixels() {
|
||||
return 16 * size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBroken(@Nullable Entity p_110128_1_) {
|
||||
if (!world.getGameRules()
|
||||
.getBoolean(GameRules.DO_ENTITY_DROPS))
|
||||
return;
|
||||
|
||||
playSound(SoundEvents.ENTITY_PAINTING_BREAK, 1.0F, 1.0F);
|
||||
if (p_110128_1_ instanceof PlayerEntity) {
|
||||
PlayerEntity playerentity = (PlayerEntity) p_110128_1_;
|
||||
if (playerentity.abilities.isCreativeMode) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
entityDropItem(AllItems.CRAFTING_BLUEPRINT.asStack());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getPickedResult(RayTraceResult target) {
|
||||
return AllItems.CRAFTING_BLUEPRINT.asStack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemRequirement getRequiredItems() {
|
||||
return new ItemRequirement(ItemUseType.CONSUME, AllItems.CRAFTING_BLUEPRINT.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playPlaceSound() {
|
||||
this.playSound(SoundEvents.ENTITY_PAINTING_PLACE, 1.0F, 1.0F);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLocationAndAngles(double p_70012_1_, double p_70012_3_, double p_70012_5_, float p_70012_7_,
|
||||
float p_70012_8_) {
|
||||
this.setPosition(p_70012_1_, p_70012_3_, p_70012_5_);
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void setPositionAndRotationDirect(double p_180426_1_, double p_180426_3_, double p_180426_5_,
|
||||
float p_180426_7_, float p_180426_8_, int p_180426_9_, boolean p_180426_10_) {
|
||||
BlockPos blockpos =
|
||||
this.hangingPosition.add(p_180426_1_ - this.getX(), p_180426_3_ - this.getY(), p_180426_5_ - this.getZ());
|
||||
this.setPosition((double) blockpos.getX(), (double) blockpos.getY(), (double) blockpos.getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSpawnData(PacketBuffer buffer) {
|
||||
CompoundNBT compound = new CompoundNBT();
|
||||
writeAdditional(compound);
|
||||
buffer.writeCompoundTag(compound);
|
||||
buffer.writeCompoundTag(getPersistentData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSpawnData(PacketBuffer additionalData) {
|
||||
readAdditional(additionalData.readCompoundTag());
|
||||
getPersistentData().merge(additionalData.readCompoundTag());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType applyPlayerInteraction(PlayerEntity player, Vector3d vec, Hand hand) {
|
||||
if (player instanceof FakePlayer)
|
||||
return ActionResultType.PASS;
|
||||
|
||||
BlueprintSection section = getSectionAt(vec);
|
||||
|
||||
if (!AllItems.WRENCH.isIn(player.getHeldItem(hand)) && !world.isRemote) {
|
||||
boolean empty = true;
|
||||
ItemStackHandler items = section.getItems();
|
||||
for (int i = 0; i < 9; i++) {
|
||||
if (!items.getStackInSlot(i)
|
||||
.isEmpty()) {
|
||||
empty = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty) {
|
||||
IItemHandlerModifiable playerInv = new InvWrapper(player.inventory);
|
||||
boolean firstPass = true;
|
||||
int amountCrafted = 0;
|
||||
ForgeHooks.setCraftingPlayer(player);
|
||||
Optional<ICraftingRecipe> recipe = Optional.empty();
|
||||
|
||||
do {
|
||||
Map<Integer, ItemStack> stacksTaken = new HashMap<>();
|
||||
Map<Integer, ItemStack> craftingGrid = new HashMap<>();
|
||||
boolean success = true;
|
||||
|
||||
Search: for (int i = 0; i < 9; i++) {
|
||||
ItemStack requestedItem = items.getStackInSlot(i);
|
||||
if (requestedItem.isEmpty()) {
|
||||
craftingGrid.put(i, ItemStack.EMPTY);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int slot = 0; slot < playerInv.getSlots(); slot++) {
|
||||
if (!FilterItem.test(world, playerInv.getStackInSlot(slot), requestedItem))
|
||||
continue;
|
||||
ItemStack currentItem = playerInv.extractItem(slot, 1, false);
|
||||
if (stacksTaken.containsKey(slot)) {
|
||||
stacksTaken.get(slot)
|
||||
.grow(1);
|
||||
} else {
|
||||
stacksTaken.put(slot, currentItem.copy());
|
||||
}
|
||||
craftingGrid.put(i, currentItem);
|
||||
continue Search;
|
||||
}
|
||||
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (success) {
|
||||
CraftingInventory craftingInventory = new BlueprintCraftingInventory(craftingGrid);
|
||||
|
||||
if (!recipe.isPresent())
|
||||
recipe = world.getRecipeManager()
|
||||
.getRecipe(IRecipeType.CRAFTING, craftingInventory, world);
|
||||
ItemStack result = recipe.filter(r -> r.matches(craftingInventory, world))
|
||||
.map(r -> r.getCraftingResult(craftingInventory))
|
||||
.orElse(ItemStack.EMPTY);
|
||||
|
||||
if (result.isEmpty()) {
|
||||
success = false;
|
||||
} else if (result.getCount() + amountCrafted > 64) {
|
||||
success = false;
|
||||
} else {
|
||||
amountCrafted += result.getCount();
|
||||
result.onCrafting(player.world, player, 1);
|
||||
BasicEventHooks.firePlayerCraftingEvent(player, result, craftingInventory);
|
||||
NonNullList<ItemStack> nonnulllist = world.getRecipeManager()
|
||||
.getRecipeNonNull(IRecipeType.CRAFTING, craftingInventory, world);
|
||||
|
||||
if (firstPass)
|
||||
world.playSound(null, player.getBlockPos(), SoundEvents.ENTITY_ITEM_PICKUP,
|
||||
SoundCategory.PLAYERS, .2f, 1f + Create.RANDOM.nextFloat());
|
||||
player.inventory.placeItemBackInInventory(world, result);
|
||||
for (ItemStack itemStack : nonnulllist)
|
||||
player.inventory.placeItemBackInInventory(world, itemStack);
|
||||
firstPass = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
for (Entry<Integer, ItemStack> entry : stacksTaken.entrySet())
|
||||
playerInv.insertItem(entry.getKey(), entry.getValue(), false);
|
||||
break;
|
||||
}
|
||||
|
||||
} while (player.isSneaking());
|
||||
ForgeHooks.setCraftingPlayer(null);
|
||||
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
int i = section.index;
|
||||
if (!world.isRemote && player instanceof ServerPlayerEntity) {
|
||||
NetworkHooks.openGui((ServerPlayerEntity) player, section, buf -> {
|
||||
buf.writeVarInt(getEntityId());
|
||||
buf.writeVarInt(i);
|
||||
});
|
||||
}
|
||||
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
||||
public BlueprintSection getSectionAt(Vector3d vec) {
|
||||
int index = 0;
|
||||
if (size > 1) {
|
||||
vec = VecHelper.rotate(vec, rotationYaw, Axis.Y);
|
||||
vec = VecHelper.rotate(vec, -rotationPitch, Axis.X);
|
||||
vec = vec.add(0.5, 0.5, 0);
|
||||
if (size == 3)
|
||||
vec = vec.add(1, 1, 0);
|
||||
int x = MathHelper.clamp(MathHelper.floor(vec.x), 0, size - 1);
|
||||
int y = MathHelper.clamp(MathHelper.floor(vec.y), 0, size - 1);
|
||||
index = x + y * size;
|
||||
}
|
||||
|
||||
BlueprintSection section = getSection(index);
|
||||
return section;
|
||||
}
|
||||
|
||||
static class BlueprintCraftingInventory extends CraftingInventory {
|
||||
|
||||
private static Container dummyContainer = new Container(null, -1) {
|
||||
public boolean canInteractWith(PlayerEntity playerIn) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
public BlueprintCraftingInventory(Map<Integer, ItemStack> items) {
|
||||
super(dummyContainer, 3, 3);
|
||||
for (int y = 0; y < 3; y++) {
|
||||
for (int x = 0; x < 3; x++) {
|
||||
ItemStack stack = items.get(y * 3 + x);
|
||||
setInventorySlotContents(y * 3 + x, stack == null ? ItemStack.EMPTY : stack.copy());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public CompoundNBT getOrCreateRecipeCompound() {
|
||||
CompoundNBT persistentData = getPersistentData();
|
||||
if (!persistentData.contains("Recipes"))
|
||||
persistentData.put("Recipes", new CompoundNBT());
|
||||
return persistentData.getCompound("Recipes");
|
||||
}
|
||||
|
||||
private Map<Integer, BlueprintSection> sectionCache = new HashMap<>();
|
||||
|
||||
public BlueprintSection getSection(int index) {
|
||||
return sectionCache.computeIfAbsent(index, i -> new BlueprintSection(i));
|
||||
}
|
||||
|
||||
class BlueprintSection implements INamedContainerProvider {
|
||||
int index;
|
||||
Couple<ItemStack> cachedDisplayItems;
|
||||
public boolean inferredIcon = false;
|
||||
|
||||
public BlueprintSection(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public Couple<ItemStack> getDisplayItems() {
|
||||
if (cachedDisplayItems != null)
|
||||
return cachedDisplayItems;
|
||||
ItemStackHandler items = getItems();
|
||||
return cachedDisplayItems = Couple.create(items.getStackInSlot(9), items.getStackInSlot(10));
|
||||
}
|
||||
|
||||
public ItemStackHandler getItems() {
|
||||
ItemStackHandler newInv = new ItemStackHandler(11);
|
||||
CompoundNBT list = getOrCreateRecipeCompound();
|
||||
CompoundNBT invNBT = list.getCompound(index + "");
|
||||
inferredIcon = list.getBoolean("InferredIcon");
|
||||
if (!invNBT.isEmpty())
|
||||
newInv.deserializeNBT(invNBT);
|
||||
return newInv;
|
||||
}
|
||||
|
||||
public void save(ItemStackHandler inventory) {
|
||||
CompoundNBT list = getOrCreateRecipeCompound();
|
||||
list.put(index + "", inventory.serializeNBT());
|
||||
list.putBoolean("InferredIcon", inferredIcon);
|
||||
cachedDisplayItems = null;
|
||||
if (!world.isRemote)
|
||||
syncPersistentDataWithTracking(BlueprintEntity.this);
|
||||
}
|
||||
|
||||
public boolean isEntityAlive() {
|
||||
return isAlive();
|
||||
}
|
||||
|
||||
public World getBlueprintWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Container createMenu(int id, PlayerInventory inv, PlayerEntity player) {
|
||||
return BlueprintContainer.create(id, inv, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextComponent getDisplayName() {
|
||||
return new StringTextComponent("");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPersistentDataUpdated() {
|
||||
sectionCache.clear();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
package com.simibubi.create.content.curiosities.tools;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.content.logistics.item.filter.AttributeFilterContainer.WhitelistMode;
|
||||
import com.simibubi.create.content.logistics.item.filter.FilterItem;
|
||||
import com.simibubi.create.content.logistics.item.filter.ItemAttribute;
|
||||
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.item.HangingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.item.crafting.Ingredient.IItemList;
|
||||
import net.minecraft.item.crafting.Ingredient.SingleItemList;
|
||||
import net.minecraft.item.crafting.Ingredient.TagList;
|
||||
import net.minecraft.item.crafting.ShapedRecipe;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.JSONUtils;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.crafting.StackList;
|
||||
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
|
||||
public class BlueprintItem extends Item {
|
||||
|
||||
public BlueprintItem(Properties p_i48487_1_) {
|
||||
super(p_i48487_1_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType onItemUse(ItemUseContext ctx) {
|
||||
Direction face = ctx.getFace();
|
||||
PlayerEntity player = ctx.getPlayer();
|
||||
ItemStack stack = ctx.getItem();
|
||||
BlockPos pos = ctx.getPos()
|
||||
.offset(face);
|
||||
|
||||
if (player != null && !player.canPlayerEdit(pos, face, stack))
|
||||
return ActionResultType.FAIL;
|
||||
|
||||
World world = ctx.getWorld();
|
||||
HangingEntity hangingentity = new BlueprintEntity(world, pos, face, face.getAxis()
|
||||
.isHorizontal() ? Direction.DOWN : ctx.getPlacementHorizontalFacing());
|
||||
CompoundNBT compoundnbt = stack.getTag();
|
||||
|
||||
if (compoundnbt != null)
|
||||
EntityType.applyItemNBT(world, player, hangingentity, compoundnbt);
|
||||
if (!hangingentity.onValidSurface())
|
||||
return ActionResultType.CONSUME;
|
||||
if (!world.isRemote) {
|
||||
hangingentity.playPlaceSound();
|
||||
world.addEntity(hangingentity);
|
||||
}
|
||||
|
||||
stack.shrink(1);
|
||||
return ActionResultType.success(world.isRemote);
|
||||
}
|
||||
|
||||
protected boolean canPlace(PlayerEntity p_200127_1_, Direction p_200127_2_, ItemStack p_200127_3_,
|
||||
BlockPos p_200127_4_) {
|
||||
return p_200127_1_.canPlayerEdit(p_200127_4_, p_200127_2_, p_200127_3_);
|
||||
}
|
||||
|
||||
public static void assignCompleteRecipe(ItemStackHandler inv, IRecipe<?> recipe) {
|
||||
NonNullList<Ingredient> ingredients = recipe.getIngredients();
|
||||
|
||||
for (int i = 0; i < 9; i++)
|
||||
inv.setStackInSlot(i, ItemStack.EMPTY);
|
||||
inv.setStackInSlot(9, recipe.getRecipeOutput());
|
||||
|
||||
if (recipe instanceof ShapedRecipe) {
|
||||
ShapedRecipe shapedRecipe = (ShapedRecipe) recipe;
|
||||
for (int row = 0; row < shapedRecipe.getHeight(); row++)
|
||||
for (int col = 0; col < shapedRecipe.getWidth(); col++)
|
||||
inv.setStackInSlot(row * 3 + col,
|
||||
convertIngredientToFilter(ingredients.get(row * shapedRecipe.getWidth() + col)));
|
||||
} else {
|
||||
for (int i = 0; i < ingredients.size(); i++)
|
||||
inv.setStackInSlot(i, convertIngredientToFilter(ingredients.get(i)));
|
||||
}
|
||||
}
|
||||
|
||||
private static ItemStack convertIngredientToFilter(Ingredient ingredient) {
|
||||
Ingredient.IItemList[] acceptedItems =
|
||||
ObfuscationReflectionHelper.getPrivateValue(Ingredient.class, ingredient, "field_199807_b");
|
||||
if (acceptedItems == null || acceptedItems.length > 18)
|
||||
return ItemStack.EMPTY;
|
||||
if (acceptedItems.length == 0)
|
||||
return ItemStack.EMPTY;
|
||||
if (acceptedItems.length == 1)
|
||||
return convertIItemListToFilter(acceptedItems[0]);
|
||||
|
||||
ItemStack result = AllItems.FILTER.asStack();
|
||||
ItemStackHandler filterItems = FilterItem.getFilterItems(result);
|
||||
for (int i = 0; i < acceptedItems.length; i++)
|
||||
filterItems.setStackInSlot(i, convertIItemListToFilter(acceptedItems[i]));
|
||||
result.getOrCreateTag()
|
||||
.put("Items", filterItems.serializeNBT());
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ItemStack convertIItemListToFilter(IItemList itemList) {
|
||||
Collection<ItemStack> stacks = itemList.getStacks();
|
||||
if (itemList instanceof SingleItemList) {
|
||||
for (ItemStack itemStack : stacks)
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
if (itemList instanceof TagList) {
|
||||
ResourceLocation resourcelocation = new ResourceLocation(JSONUtils.getString(itemList.serialize(), "tag"));
|
||||
ItemStack filterItem = AllItems.ATTRIBUTE_FILTER.asStack();
|
||||
filterItem.getOrCreateTag()
|
||||
.putInt("WhitelistMode", WhitelistMode.WHITELIST_DISJ.ordinal());
|
||||
ListNBT attributes = new ListNBT();
|
||||
ItemAttribute at = new ItemAttribute.InTag(resourcelocation);
|
||||
CompoundNBT compoundNBT = new CompoundNBT();
|
||||
at.serializeNBT(compoundNBT);
|
||||
compoundNBT.putBoolean("Inverted", false);
|
||||
attributes.add(compoundNBT);
|
||||
filterItem.getOrCreateTag()
|
||||
.put("MatchedAttributes", attributes);
|
||||
return filterItem;
|
||||
}
|
||||
|
||||
if (itemList instanceof StackList) {
|
||||
ItemStack result = AllItems.FILTER.asStack();
|
||||
ItemStackHandler filterItems = FilterItem.getFilterItems(result);
|
||||
int i = 0;
|
||||
for (ItemStack itemStack : stacks) {
|
||||
if (i >= 18)
|
||||
break;
|
||||
filterItems.setStackInSlot(i++, itemStack);
|
||||
}
|
||||
CompoundNBT tag = result.getOrCreateTag();
|
||||
tag.put("Items", filterItems.serializeNBT());
|
||||
tag.putBoolean("RespectNBT", true);
|
||||
return result;
|
||||
}
|
||||
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,240 @@
|
|||
package com.simibubi.create.content.curiosities.tools;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.simibubi.create.content.curiosities.tools.BlueprintEntity.BlueprintCraftingInventory;
|
||||
import com.simibubi.create.content.curiosities.tools.BlueprintEntity.BlueprintSection;
|
||||
import com.simibubi.create.content.logistics.item.filter.FilterItem;
|
||||
import com.simibubi.create.foundation.gui.AllGuiTextures;
|
||||
import com.simibubi.create.foundation.gui.GuiGameElement;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.Pair;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
import net.minecraft.inventory.CraftingInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.item.crafting.ICraftingRecipe;
|
||||
import net.minecraft.item.crafting.IRecipeType;
|
||||
import net.minecraft.util.math.EntityRayTraceResult;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.RayTraceResult.Type;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
|
||||
public class BlueprintOverlayRenderer {
|
||||
|
||||
static boolean active;
|
||||
static boolean empty;
|
||||
static boolean lastSneakState;
|
||||
static BlueprintSection lastTargetedSection;
|
||||
|
||||
static List<Pair<ItemStack, Boolean>> ingredients = new ArrayList<>();
|
||||
static ItemStack result = ItemStack.EMPTY;
|
||||
static boolean resultCraftable = false;
|
||||
|
||||
public static void tick() {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
RayTraceResult mouseOver = mc.objectMouseOver;
|
||||
BlueprintSection last = lastTargetedSection;
|
||||
boolean sneak = mc.player.isSneaking();
|
||||
lastTargetedSection = null;
|
||||
active = false;
|
||||
if (mouseOver == null)
|
||||
return;
|
||||
if (mouseOver.getType() != Type.ENTITY)
|
||||
return;
|
||||
|
||||
EntityRayTraceResult entityRay = (EntityRayTraceResult) mouseOver;
|
||||
if (!(entityRay.getEntity() instanceof BlueprintEntity))
|
||||
return;
|
||||
|
||||
BlueprintEntity blueprintEntity = (BlueprintEntity) entityRay.getEntity();
|
||||
BlueprintSection sectionAt = blueprintEntity.getSectionAt(entityRay.getHitVec()
|
||||
.subtract(blueprintEntity.getPositionVec()));
|
||||
|
||||
lastTargetedSection = last;
|
||||
active = true;
|
||||
|
||||
if (sectionAt != lastTargetedSection || AnimationTickHolder.getTicks() % 10 == 0 || lastSneakState != sneak)
|
||||
rebuild(sectionAt, sneak);
|
||||
|
||||
lastTargetedSection = sectionAt;
|
||||
lastSneakState = sneak;
|
||||
}
|
||||
|
||||
public static void rebuild(BlueprintSection sectionAt, boolean sneak) {
|
||||
ItemStackHandler items = sectionAt.getItems();
|
||||
boolean empty = true;
|
||||
for (int i = 0; i < 9; i++) {
|
||||
if (!items.getStackInSlot(i)
|
||||
.isEmpty()) {
|
||||
empty = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BlueprintOverlayRenderer.empty = empty;
|
||||
BlueprintOverlayRenderer.result = ItemStack.EMPTY;
|
||||
|
||||
if (empty)
|
||||
return;
|
||||
|
||||
boolean firstPass = true;
|
||||
boolean success = true;
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
ItemStackHandler playerInv = new ItemStackHandler(mc.player.inventory.getSizeInventory());
|
||||
for (int i = 0; i < playerInv.getSlots(); i++)
|
||||
playerInv.setStackInSlot(i, mc.player.inventory.getStackInSlot(i)
|
||||
.copy());
|
||||
|
||||
int amountCrafted = 0;
|
||||
Optional<ICraftingRecipe> recipe = Optional.empty();
|
||||
Map<Integer, ItemStack> craftingGrid = new HashMap<>();
|
||||
ingredients.clear();
|
||||
ItemStackHandler missingItems = new ItemStackHandler(64);
|
||||
ItemStackHandler availableItems = new ItemStackHandler(64);
|
||||
List<ItemStack> newlyAdded = new ArrayList<>();
|
||||
List<ItemStack> newlyMissing = new ArrayList<>();
|
||||
boolean invalid = false;
|
||||
|
||||
do {
|
||||
craftingGrid.clear();
|
||||
newlyAdded.clear();
|
||||
newlyMissing.clear();
|
||||
|
||||
Search: for (int i = 0; i < 9; i++) {
|
||||
ItemStack requestedItem = items.getStackInSlot(i);
|
||||
if (requestedItem.isEmpty()) {
|
||||
craftingGrid.put(i, ItemStack.EMPTY);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int slot = 0; slot < playerInv.getSlots(); slot++) {
|
||||
if (!FilterItem.test(mc.world, playerInv.getStackInSlot(slot), requestedItem))
|
||||
continue;
|
||||
ItemStack currentItem = playerInv.extractItem(slot, 1, false);
|
||||
craftingGrid.put(i, currentItem);
|
||||
newlyAdded.add(currentItem);
|
||||
continue Search;
|
||||
}
|
||||
|
||||
success = false;
|
||||
newlyMissing.add(requestedItem);
|
||||
}
|
||||
|
||||
if (success) {
|
||||
CraftingInventory craftingInventory = new BlueprintCraftingInventory(craftingGrid);
|
||||
if (!recipe.isPresent())
|
||||
recipe = mc.world.getRecipeManager()
|
||||
.getRecipe(IRecipeType.CRAFTING, craftingInventory, mc.world);
|
||||
ItemStack resultFromRecipe = recipe.filter(r -> r.matches(craftingInventory, mc.world))
|
||||
.map(r -> r.getCraftingResult(craftingInventory))
|
||||
.orElse(ItemStack.EMPTY);
|
||||
|
||||
if (resultFromRecipe.isEmpty()) {
|
||||
if (!recipe.isPresent())
|
||||
invalid = true;
|
||||
success = false;
|
||||
} else if (resultFromRecipe.getCount() + amountCrafted > 64) {
|
||||
success = false;
|
||||
} else {
|
||||
amountCrafted += resultFromRecipe.getCount();
|
||||
if (result.isEmpty())
|
||||
result = resultFromRecipe.copy();
|
||||
else
|
||||
result.grow(resultFromRecipe.getCount());
|
||||
resultCraftable = true;
|
||||
firstPass = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (success || firstPass) {
|
||||
newlyAdded.forEach(s -> ItemHandlerHelper.insertItemStacked(availableItems, s, false));
|
||||
newlyMissing.forEach(s -> ItemHandlerHelper.insertItemStacked(missingItems, s, false));
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
if (firstPass) {
|
||||
result = invalid ? ItemStack.EMPTY : items.getStackInSlot(9);
|
||||
resultCraftable = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!sneak)
|
||||
break;
|
||||
|
||||
} while (success);
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
ItemStack available = availableItems.getStackInSlot(i);
|
||||
if (available.isEmpty())
|
||||
continue;
|
||||
ingredients.add(Pair.of(available, true));
|
||||
}
|
||||
for (int i = 0; i < 9; i++) {
|
||||
ItemStack missing = missingItems.getStackInSlot(i);
|
||||
if (missing.isEmpty())
|
||||
continue;
|
||||
ingredients.add(Pair.of(missing, false));
|
||||
}
|
||||
}
|
||||
|
||||
public static void renderOverlay(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay,
|
||||
float partialTicks) {
|
||||
if (!active || empty)
|
||||
return;
|
||||
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
int w = 30 + 21 * ingredients.size() + 21;
|
||||
|
||||
int x = (mc.getWindow()
|
||||
.getScaledWidth() - w) / 2;
|
||||
int y = (int) (mc.getWindow()
|
||||
.getScaledHeight() / 3f * 2);
|
||||
|
||||
for (Pair<ItemStack, Boolean> pair : ingredients) {
|
||||
RenderSystem.enableBlend();
|
||||
(pair.getSecond() ? AllGuiTextures.HOTSLOT_ACTIVE : AllGuiTextures.HOTSLOT).draw(ms, x, y);
|
||||
ItemStack itemStack = pair.getFirst();
|
||||
GuiGameElement.of(itemStack)
|
||||
.at(x + 3, y + 3)
|
||||
.render(ms);
|
||||
mc.getItemRenderer()
|
||||
.renderItemOverlayIntoGUI(mc.fontRenderer, itemStack, x + 3, y + 3,
|
||||
pair.getSecond() || itemStack.getCount() == 1 ? null
|
||||
: TextFormatting.GOLD.toString() + itemStack.getCount());
|
||||
x += 21;
|
||||
}
|
||||
|
||||
x += 5;
|
||||
RenderSystem.enableBlend();
|
||||
AllGuiTextures.HOTSLOT_ARROW.draw(ms, x, y + 4);
|
||||
x += 25;
|
||||
|
||||
if (result.isEmpty()) {
|
||||
AllGuiTextures.HOTSLOT.draw(ms, x, y);
|
||||
GuiGameElement.of(Items.BARRIER)
|
||||
.at(x + 3, y + 3)
|
||||
.render(ms);
|
||||
} else {
|
||||
(resultCraftable ? AllGuiTextures.HOTSLOT_SUPER_ACTIVE : AllGuiTextures.HOTSLOT).draw(ms,
|
||||
resultCraftable ? x - 1 : x, resultCraftable ? y - 1 : y);
|
||||
GuiGameElement.of(result)
|
||||
.at(x + 3, y + 3)
|
||||
.render(ms);
|
||||
mc.getItemRenderer()
|
||||
.renderItemOverlayIntoGUI(mc.fontRenderer, result, x + 3, y + 3, null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
package com.simibubi.create.content.curiosities.tools;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.content.curiosities.tools.BlueprintEntity.BlueprintSection;
|
||||
import com.simibubi.create.foundation.render.PartialBufferer;
|
||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.render.backend.core.PartialModel;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.WorldRenderer;
|
||||
import net.minecraft.client.renderer.entity.EntityRenderer;
|
||||
import net.minecraft.client.renderer.entity.EntityRendererManager;
|
||||
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.vector.Matrix3f;
|
||||
|
||||
public class BlueprintRenderer extends EntityRenderer<BlueprintEntity> {
|
||||
|
||||
public BlueprintRenderer(EntityRendererManager p_i46179_1_) {
|
||||
super(p_i46179_1_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(BlueprintEntity entity, float yaw, float pt, MatrixStack ms, IRenderTypeBuffer buffer,
|
||||
int overlay) {
|
||||
PartialModel partialModel = entity.size == 3 ? AllBlockPartials.CRAFTING_BLUEPRINT_3x3
|
||||
: entity.size == 2 ? AllBlockPartials.CRAFTING_BLUEPRINT_2x2 : AllBlockPartials.CRAFTING_BLUEPRINT_1x1;
|
||||
SuperByteBuffer sbb = PartialBufferer.get(partialModel, Blocks.AIR.getDefaultState());
|
||||
int light = WorldRenderer.getLightmapCoordinates(entity.world, entity.getBlockPos());
|
||||
sbb.matrixStacker()
|
||||
.rotateY(-yaw)
|
||||
.rotateX(90.0F + entity.rotationPitch)
|
||||
.translate(-.5, -1 / 32f, -.5);
|
||||
if (entity.size == 2)
|
||||
sbb.translate(.5, 0, -.5);
|
||||
sbb.light(light)
|
||||
.renderInto(ms, buffer.getBuffer(RenderType.getSolid()));
|
||||
super.render(entity, yaw, pt, ms, buffer, light);
|
||||
|
||||
ms.push();
|
||||
|
||||
MatrixStacker.of(ms)
|
||||
.rotateY(-yaw)
|
||||
.rotateX(entity.rotationPitch == -90 ? -45 : entity.rotationPitch == 0 ? -15 : -5);
|
||||
Matrix3f copy = ms.peek()
|
||||
.getNormal()
|
||||
.copy();
|
||||
|
||||
ms.pop();
|
||||
ms.push();
|
||||
|
||||
MatrixStacker.of(ms)
|
||||
.rotateY(-yaw)
|
||||
.rotateX(entity.rotationPitch)
|
||||
.translate(0, 0, 1 / 32f + .001);
|
||||
|
||||
if (entity.size == 3)
|
||||
ms.translate(-1, -1, 0);
|
||||
|
||||
for (int x = 0; x < entity.size; x++) {
|
||||
ms.push();
|
||||
for (int y = 0; y < entity.size; y++) {
|
||||
BlueprintSection section = entity.getSection(x * entity.size + y);
|
||||
Couple<ItemStack> displayItems = section.getDisplayItems();
|
||||
ms.push();
|
||||
ms.scale(.5f, .5f, 1 / 1024f);
|
||||
displayItems.forEachWithContext((stack, primary) -> {
|
||||
if (stack.isEmpty())
|
||||
return;
|
||||
|
||||
ms.push();
|
||||
if (!primary) {
|
||||
ms.translate(0.325f, -0.325f, 1);
|
||||
ms.scale(.625f, .625f, 1);
|
||||
}
|
||||
|
||||
Matrix3f n = ms.peek()
|
||||
.getNormal();
|
||||
n.a00 = copy.a00;
|
||||
n.a01 = copy.a01;
|
||||
n.a02 = copy.a02;
|
||||
n.a10 = copy.a10;
|
||||
n.a11 = copy.a11;
|
||||
n.a12 = copy.a12;
|
||||
n.a20 = copy.a20;
|
||||
n.a21 = copy.a21;
|
||||
n.a22 = copy.a22;
|
||||
|
||||
Minecraft.getInstance()
|
||||
.getItemRenderer()
|
||||
.renderItem(stack, TransformType.GUI, light, overlay, ms, buffer);
|
||||
ms.pop();
|
||||
});
|
||||
ms.pop();
|
||||
ms.translate(1, 0, 0);
|
||||
}
|
||||
ms.pop();
|
||||
ms.translate(0, 1, 0);
|
||||
}
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getEntityTexture(BlueprintEntity p_110775_1_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,192 @@
|
|||
package com.simibubi.create.content.curiosities.tools;
|
||||
|
||||
import static com.simibubi.create.foundation.gui.AllGuiTextures.PLAYER_INVENTORY;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.content.logistics.item.filter.FilterScreenPacket;
|
||||
import com.simibubi.create.content.logistics.item.filter.FilterScreenPacket.Option;
|
||||
import com.simibubi.create.foundation.gui.AbstractSimiContainerScreen;
|
||||
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;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
||||
import net.minecraft.client.renderer.Rectangle2d;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
|
||||
public class BlueprintScreen extends AbstractSimiContainerScreen<BlueprintContainer> {
|
||||
|
||||
protected AllGuiTextures background;
|
||||
private List<Rectangle2d> extraAreas = Collections.emptyList();
|
||||
|
||||
private IconButton resetButton;
|
||||
private IconButton confirmButton;
|
||||
|
||||
public BlueprintScreen(BlueprintContainer container, PlayerInventory inv, ITextComponent title) {
|
||||
super(container, inv, title);
|
||||
this.background = AllGuiTextures.BLUEPRINT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
setWindowSize(background.width + 50, background.height + PLAYER_INVENTORY.height + 20);
|
||||
super.init();
|
||||
widgets.clear();
|
||||
int x = guiLeft;
|
||||
int offset = guiTop < 30 ? 30 - guiTop : 0;
|
||||
extraAreas =
|
||||
ImmutableList.of(new Rectangle2d(x, guiTop + offset, background.width + 70, background.height - offset));
|
||||
|
||||
resetButton = new IconButton(x + background.width - 62, guiTop + background.height - 24, AllIcons.I_TRASH);
|
||||
confirmButton = new IconButton(x + background.width - 33, guiTop + background.height - 24, AllIcons.I_CONFIRM);
|
||||
|
||||
widgets.add(resetButton);
|
||||
widgets.add(confirmButton);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
int x = guiLeft;
|
||||
int y = guiTop;
|
||||
background.draw(ms, this, x, y);
|
||||
|
||||
int invX = guiLeft + 25;
|
||||
int invY = y + background.height + 10;
|
||||
PLAYER_INVENTORY.draw(ms, this, invX, invY);
|
||||
|
||||
String localizedName = I18n.format(AllItems.CRAFTING_BLUEPRINT.get()
|
||||
.getTranslationKey());
|
||||
textRenderer.draw(ms, playerInventory.getDisplayName(), invX + 7, invY + 6, 0x666666);
|
||||
textRenderer.draw(ms, localizedName, x + 15, y + 4, 0xFFFFFF);
|
||||
|
||||
GuiGameElement.of(AllBlockPartials.CRAFTING_BLUEPRINT_1x1).<GuiGameElement
|
||||
.GuiRenderBuilder>at(x + background.width + 20, guiTop + background.height - 35, 0)
|
||||
.rotate(45, -45, 22.5f)
|
||||
.scale(40)
|
||||
.render(ms);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawMouseoverTooltip(MatrixStack ms, int x, int y) {
|
||||
if (!this.client.player.inventory.getItemStack()
|
||||
.isEmpty() || this.hoveredSlot == null || this.hoveredSlot.getHasStack()
|
||||
|| hoveredSlot.inventory == container.playerInventory) {
|
||||
super.drawMouseoverTooltip(ms, x, y);
|
||||
return;
|
||||
}
|
||||
renderWrappedToolTip(ms, addToTooltip(new LinkedList<>(), hoveredSlot.getSlotIndex(), true), x, y,
|
||||
textRenderer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ITextComponent> getTooltipFromItem(ItemStack stack) {
|
||||
List<ITextComponent> list = super.getTooltipFromItem(stack);
|
||||
if (hoveredSlot.inventory == container.playerInventory)
|
||||
return list;
|
||||
return hoveredSlot != null ? addToTooltip(list, hoveredSlot.getSlotIndex(), false) : list;
|
||||
}
|
||||
|
||||
private List<ITextComponent> addToTooltip(List<ITextComponent> list, int slot, boolean isEmptySlot) {
|
||||
if (slot < 0 || slot > 10)
|
||||
return list;
|
||||
|
||||
if (slot < 9) {
|
||||
list.add(Lang.createTranslationTextComponent("crafting_blueprint.crafting_slot")
|
||||
.formatted(TextFormatting.GOLD));
|
||||
if (isEmptySlot)
|
||||
list.add(Lang.createTranslationTextComponent("crafting_blueprint.filter_items_viable")
|
||||
.formatted(TextFormatting.GRAY));
|
||||
|
||||
} else if (slot == 9) {
|
||||
list.add(Lang.createTranslationTextComponent("crafting_blueprint.display_slot")
|
||||
.formatted(TextFormatting.GOLD));
|
||||
if (!isEmptySlot)
|
||||
list.add(Lang
|
||||
.createTranslationTextComponent("crafting_blueprint."
|
||||
+ (container.contentHolder.inferredIcon ? "inferred" : "manually_assigned"))
|
||||
.formatted(TextFormatting.GRAY));
|
||||
|
||||
} else if (slot == 10) {
|
||||
list.add(Lang.createTranslationTextComponent("crafting_blueprint.secondary_display_slot")
|
||||
.formatted(TextFormatting.GOLD));
|
||||
if (isEmptySlot)
|
||||
list.add(Lang.createTranslationTextComponent("crafting_blueprint.optional")
|
||||
.formatted(TextFormatting.GRAY));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
// handleTooltips();
|
||||
super.tick();
|
||||
|
||||
if (!container.contentHolder.isEntityAlive())
|
||||
client.player.closeScreen();
|
||||
}
|
||||
|
||||
// protected void handleTooltips() {
|
||||
// List<IconButton> tooltipButtons = getTooltipButtons();
|
||||
//
|
||||
// for (IconButton button : tooltipButtons) {
|
||||
// if (!button.getToolTip()
|
||||
// .isEmpty()) {
|
||||
// button.setToolTip(button.getToolTip()
|
||||
// .get(0));
|
||||
// button.getToolTip()
|
||||
// .add(TooltipHelper.holdShift(Palette.Yellow, hasShiftDown()));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (hasShiftDown()) {
|
||||
// List<IFormattableTextComponent> tooltipDescriptions = getTooltipDescriptions();
|
||||
// for (int i = 0; i < tooltipButtons.size(); i++)
|
||||
// fillToolTip(tooltipButtons.get(i), tooltipDescriptions.get(i));
|
||||
// }
|
||||
// }
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double x, double y, int button) {
|
||||
boolean mouseClicked = super.mouseClicked(x, y, button);
|
||||
|
||||
if (button == 0) {
|
||||
if (confirmButton.isHovered()) {
|
||||
client.player.closeScreen();
|
||||
return true;
|
||||
}
|
||||
if (resetButton.isHovered()) {
|
||||
container.clearContents();
|
||||
contentsCleared();
|
||||
container.sendClearPacket();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return mouseClicked;
|
||||
}
|
||||
|
||||
protected void contentsCleared() {}
|
||||
|
||||
protected void sendOptionUpdate(Option option) {
|
||||
AllPackets.channel.sendToServer(new FilterScreenPacket(option));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Rectangle2d> getExtraAreas() {
|
||||
return extraAreas;
|
||||
}
|
||||
}
|
|
@ -38,7 +38,8 @@ public class LinkedControllerScreen extends AbstractSimiContainerScreen<LinkedCo
|
|||
@Override
|
||||
protected void drawMouseoverTooltip(MatrixStack ms, int x, int y) {
|
||||
if (!this.client.player.inventory.getItemStack()
|
||||
.isEmpty() || this.hoveredSlot == null || this.hoveredSlot.getHasStack()) {
|
||||
.isEmpty() || this.hoveredSlot == null || this.hoveredSlot.getHasStack()
|
||||
|| hoveredSlot.inventory == container.playerInventory) {
|
||||
super.drawMouseoverTooltip(ms, x, y);
|
||||
return;
|
||||
}
|
||||
|
@ -48,6 +49,8 @@ public class LinkedControllerScreen extends AbstractSimiContainerScreen<LinkedCo
|
|||
@Override
|
||||
public List<ITextComponent> getTooltipFromItem(ItemStack stack) {
|
||||
List<ITextComponent> list = super.getTooltipFromItem(stack);
|
||||
if (hoveredSlot.inventory == container.playerInventory)
|
||||
return list;
|
||||
return hoveredSlot != null ? addToTooltip(list, hoveredSlot.getSlotIndex()) : list;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,145 +1,58 @@
|
|||
package com.simibubi.create.content.logistics.item.filter;
|
||||
|
||||
import com.simibubi.create.foundation.gui.IClearableContainer;
|
||||
import com.simibubi.create.foundation.gui.GhostItemContainer;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.inventory.container.ClickType;
|
||||
import net.minecraft.inventory.container.Container;
|
||||
import net.minecraft.inventory.container.ContainerType;
|
||||
import net.minecraft.inventory.container.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
public abstract class AbstractFilterContainer extends Container implements IClearableContainer {
|
||||
|
||||
public PlayerEntity player;
|
||||
protected PlayerInventory playerInventory;
|
||||
public ItemStack filterItem;
|
||||
public ItemStackHandler filterInventory;
|
||||
public abstract class AbstractFilterContainer extends GhostItemContainer<ItemStack> {
|
||||
|
||||
protected AbstractFilterContainer(ContainerType<?> type, int id, PlayerInventory inv, PacketBuffer extraData) {
|
||||
this(type, id, inv, extraData.readItemStack());
|
||||
super(type, id, inv, extraData);
|
||||
}
|
||||
|
||||
protected AbstractFilterContainer(ContainerType<?> type, int id, PlayerInventory inv, ItemStack filterItem) {
|
||||
super(type, id);
|
||||
player = inv.player;
|
||||
playerInventory = inv;
|
||||
this.filterItem = filterItem;
|
||||
init();
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
this.filterInventory = createFilterInventory();
|
||||
readData(filterItem);
|
||||
addPlayerSlots();
|
||||
addFilterSlots();
|
||||
detectAndSendChanges();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearContents() {
|
||||
for (int i = 0; i < filterInventory.getSlots(); i++)
|
||||
filterInventory.setStackInSlot(i, ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
protected abstract int getInventoryOffset();
|
||||
|
||||
protected abstract void addFilterSlots();
|
||||
|
||||
protected abstract ItemStackHandler createFilterInventory();
|
||||
|
||||
protected abstract void readData(ItemStack filterItem);
|
||||
|
||||
protected abstract void saveData(ItemStack filterItem);
|
||||
|
||||
protected void addPlayerSlots() {
|
||||
int x = 8;
|
||||
int y = 28 + getInventoryOffset();
|
||||
|
||||
for (int hotbarSlot = 0; hotbarSlot < 9; ++hotbarSlot)
|
||||
this.addSlot(new Slot(playerInventory, hotbarSlot, x + hotbarSlot * 18, y + 58));
|
||||
for (int row = 0; row < 3; ++row)
|
||||
for (int col = 0; col < 9; ++col)
|
||||
this.addSlot(new Slot(playerInventory, col + row * 9 + 9, x + col * 18, y + row * 18));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMergeSlot(ItemStack stack, Slot slotIn) {
|
||||
return canDragIntoSlot(slotIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDragIntoSlot(Slot slotIn) {
|
||||
return slotIn.inventory == playerInventory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInteractWith(PlayerEntity playerIn) {
|
||||
return true;
|
||||
protected AbstractFilterContainer(ContainerType<?> type, int id, PlayerInventory inv, ItemStack contentHolder) {
|
||||
super(type, id, inv, contentHolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack slotClick(int slotId, int dragType, ClickType clickTypeIn, PlayerEntity player) {
|
||||
if (slotId == playerInventory.currentItem && clickTypeIn != ClickType.THROW)
|
||||
return ItemStack.EMPTY;
|
||||
|
||||
ItemStack held = playerInventory.getItemStack();
|
||||
if (slotId < 36)
|
||||
return super.slotClick(slotId, dragType, clickTypeIn, player);
|
||||
if (clickTypeIn == ClickType.THROW)
|
||||
return ItemStack.EMPTY;
|
||||
|
||||
int slot = slotId - 36;
|
||||
if (clickTypeIn == ClickType.CLONE) {
|
||||
if (player.isCreative() && held.isEmpty()) {
|
||||
ItemStack stackInSlot = filterInventory.getStackInSlot(slot).copy();
|
||||
stackInSlot.setCount(64);
|
||||
playerInventory.setItemStack(stackInSlot);
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
if (held.isEmpty()) {
|
||||
filterInventory.setStackInSlot(slot, ItemStack.EMPTY);
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
ItemStack insert = held.copy();
|
||||
insert.setCount(1);
|
||||
filterInventory.setStackInSlot(slot, insert);
|
||||
return held;
|
||||
return super.slotClick(slotId, dragType, clickTypeIn, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) {
|
||||
if (index < 36) {
|
||||
ItemStack stackToInsert = playerInventory.getStackInSlot(index);
|
||||
for (int i = 0; i < filterInventory.getSlots(); i++) {
|
||||
ItemStack stack = filterInventory.getStackInSlot(i);
|
||||
if (ItemHandlerHelper.canItemStacksStack(stack, stackToInsert))
|
||||
break;
|
||||
if (stack.isEmpty()) {
|
||||
ItemStack copy = stackToInsert.copy();
|
||||
copy.setCount(1);
|
||||
filterInventory.insertItem(i, copy, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else
|
||||
filterInventory.extractItem(index - 36, 1, false);
|
||||
return ItemStack.EMPTY;
|
||||
protected boolean allowRepeats() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContainerClosed(PlayerEntity playerIn) {
|
||||
super.onContainerClosed(playerIn);
|
||||
filterItem.getOrCreateTag().put("Items", filterInventory.serializeNBT());
|
||||
saveData(filterItem);
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
protected ItemStack createOnClient(PacketBuffer extraData) {
|
||||
return extraData.readItemStack();
|
||||
}
|
||||
|
||||
protected abstract int getPlayerInventoryXOffset();
|
||||
|
||||
protected abstract void addFilterSlots();
|
||||
|
||||
@Override
|
||||
protected void addSlots() {
|
||||
addPlayerSlots(8, 28 + getPlayerInventoryXOffset());
|
||||
addFilterSlots();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveData(ItemStack contentHolder) {
|
||||
contentHolder.getOrCreateTag()
|
||||
.put("Items", ghostInventory.serializeNBT());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -66,9 +66,9 @@ public abstract class AbstractFilterScreen<F extends AbstractFilterContainer> ex
|
|||
int invY = y + background.height + 10;
|
||||
PLAYER_INVENTORY.draw(ms, this, invX, invY);
|
||||
textRenderer.draw(ms, playerInventory.getDisplayName(), invX + 7, invY + 6, 0x666666);
|
||||
textRenderer.draw(ms, I18n.format(container.filterItem.getTranslationKey()), x + 15, y + 3, 0xdedede);
|
||||
textRenderer.draw(ms, I18n.format(container.contentHolder.getTranslationKey()), x + 15, y + 3, 0xdedede);
|
||||
|
||||
GuiGameElement.of(container.filterItem)
|
||||
GuiGameElement.of(container.contentHolder)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(x + background.width, guiTop + background.height - 60, -200)
|
||||
.scale(5)
|
||||
.render(ms);
|
||||
|
@ -82,7 +82,7 @@ public abstract class AbstractFilterScreen<F extends AbstractFilterContainer> ex
|
|||
handleIndicators();
|
||||
|
||||
if (!container.player.getHeldItemMainhand()
|
||||
.equals(container.filterItem, false))
|
||||
.equals(container.contentHolder, false))
|
||||
client.player.closeScreen();
|
||||
}
|
||||
|
||||
|
|
|
@ -53,22 +53,22 @@ public class AttributeFilterContainer extends AbstractFilterContainer {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
protected void init(PlayerInventory inv, ItemStack contentHolder) {
|
||||
super.init(inv, contentHolder);
|
||||
ItemStack stack = new ItemStack(Items.NAME_TAG);
|
||||
stack.setDisplayName(
|
||||
new StringTextComponent("Selected Tags").formatted(TextFormatting.RESET, TextFormatting.BLUE));
|
||||
filterInventory.setStackInSlot(1, stack);
|
||||
ghostInventory.setStackInSlot(1, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemStackHandler createFilterInventory() {
|
||||
protected ItemStackHandler createGhostInventory() {
|
||||
return new ItemStackHandler(2);
|
||||
}
|
||||
|
||||
protected void addFilterSlots() {
|
||||
this.addSlot(new SlotItemHandler(filterInventory, 0, -34, 22));
|
||||
this.addSlot(new SlotItemHandler(filterInventory, 1, -28, 57) {
|
||||
this.addSlot(new SlotItemHandler(ghostInventory, 0, -34, 22));
|
||||
this.addSlot(new SlotItemHandler(ghostInventory, 1, -28, 57) {
|
||||
@Override
|
||||
public boolean canTakeStack(PlayerEntity playerIn) {
|
||||
return false;
|
||||
|
@ -102,20 +102,20 @@ public class AttributeFilterContainer extends AbstractFilterContainer {
|
|||
if (index == 37)
|
||||
return ItemStack.EMPTY;
|
||||
if (index == 36) {
|
||||
filterInventory.setStackInSlot(37, ItemStack.EMPTY);
|
||||
ghostInventory.setStackInSlot(37, ItemStack.EMPTY);
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
if (index < 36) {
|
||||
ItemStack stackToInsert = playerInventory.getStackInSlot(index);
|
||||
ItemStack copy = stackToInsert.copy();
|
||||
copy.setCount(1);
|
||||
filterInventory.setStackInSlot(0, copy);
|
||||
ghostInventory.setStackInSlot(0, copy);
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getInventoryOffset() {
|
||||
protected int getPlayerInventoryXOffset() {
|
||||
return 83;
|
||||
}
|
||||
|
||||
|
@ -134,6 +134,7 @@ public class AttributeFilterContainer extends AbstractFilterContainer {
|
|||
|
||||
@Override
|
||||
protected void saveData(ItemStack filterItem) {
|
||||
super.saveData(filterItem);
|
||||
filterItem.getOrCreateTag()
|
||||
.putInt("WhitelistMode", whitelistMode.ordinal());
|
||||
ListNBT attributes = new ListNBT();
|
||||
|
@ -141,7 +142,8 @@ public class AttributeFilterContainer extends AbstractFilterContainer {
|
|||
if (at == null)
|
||||
return;
|
||||
CompoundNBT compoundNBT = new CompoundNBT();
|
||||
at.getFirst().serializeNBT(compoundNBT);
|
||||
at.getFirst()
|
||||
.serializeNBT(compoundNBT);
|
||||
compoundNBT.putBoolean("Inverted", at.getSecond());
|
||||
attributes.add(compoundNBT);
|
||||
});
|
||||
|
|
|
@ -91,7 +91,7 @@ public class AttributeFilterScreen extends AbstractFilterScreen<AttributeFilterC
|
|||
attributeSelector = new SelectionScrollInput(x + 39, y + 21, 137, 18);
|
||||
attributeSelector.forOptions(Arrays.asList(StringTextComponent.EMPTY));
|
||||
attributeSelector.removeCallback();
|
||||
referenceItemChanged(container.filterInventory.getStackInSlot(0));
|
||||
referenceItemChanged(container.ghostInventory.getStackInSlot(0));
|
||||
|
||||
widgets.add(attributeSelector);
|
||||
widgets.add(attributeSelectorLabel);
|
||||
|
@ -160,7 +160,7 @@ public class AttributeFilterScreen extends AbstractFilterScreen<AttributeFilterC
|
|||
|
||||
@Override
|
||||
public void renderWindowForeground(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
|
||||
ItemStack stack = container.filterInventory.getStackInSlot(1);
|
||||
ItemStack stack = container.ghostInventory.getStackInSlot(1);
|
||||
matrixStack.push();
|
||||
matrixStack.translate(0.0F, 0.0F, 32.0F);
|
||||
this.setZOffset(200);
|
||||
|
@ -177,7 +177,7 @@ public class AttributeFilterScreen extends AbstractFilterScreen<AttributeFilterC
|
|||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
ItemStack stackInSlot = container.filterInventory.getStackInSlot(0);
|
||||
ItemStack stackInSlot = container.ghostInventory.getStackInSlot(0);
|
||||
if (!stackInSlot.equals(lastItemScanned, false))
|
||||
referenceItemChanged(stackInSlot);
|
||||
}
|
||||
|
|
|
@ -31,19 +31,18 @@ public class FilterContainer extends AbstractFilterContainer {
|
|||
protected void addFilterSlots() {
|
||||
int x = -27;
|
||||
int y = 20;
|
||||
|
||||
for (int row = 0; row < 2; ++row)
|
||||
for (int col = 0; col < 9; ++col)
|
||||
this.addSlot(new SlotItemHandler(filterInventory, col + row * 9, x + col * 18, y + row * 18));
|
||||
this.addSlot(new SlotItemHandler(ghostInventory, col + row * 9, x + col * 18, y + row * 18));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemStackHandler createFilterInventory() {
|
||||
return FilterItem.getFilterItems(filterItem);
|
||||
protected ItemStackHandler createGhostInventory() {
|
||||
return FilterItem.getFilterItems(contentHolder);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getInventoryOffset() {
|
||||
protected int getPlayerInventoryXOffset() {
|
||||
return 97;
|
||||
}
|
||||
|
||||
|
@ -56,6 +55,7 @@ public class FilterContainer extends AbstractFilterContainer {
|
|||
|
||||
@Override
|
||||
protected void saveData(ItemStack filterItem) {
|
||||
super.saveData(filterItem);
|
||||
CompoundNBT tag = filterItem.getOrCreateTag();
|
||||
tag.putBoolean("RespectNBT", respectNBT);
|
||||
tag.putBoolean("Blacklist", blacklist);
|
||||
|
|
|
@ -57,7 +57,7 @@ public class FilterScreenPacket extends SimplePacketBase {
|
|||
if (option == Option.IGNORE_DATA)
|
||||
c.respectNBT = false;
|
||||
if (option == Option.UPDATE_FILTER_ITEM)
|
||||
c.filterInventory.setStackInSlot(
|
||||
c.ghostInventory.setStackInSlot(
|
||||
data.getInt("Slot"),
|
||||
net.minecraft.item.ItemStack.read(data.getCompound("Item")));
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import com.simibubi.create.content.contraptions.components.turntable.TurntableHa
|
|||
import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.item.BeltConnectorHandler;
|
||||
import com.simibubi.create.content.curiosities.armor.CopperBacktankArmorLayer;
|
||||
import com.simibubi.create.content.curiosities.tools.BlueprintOverlayRenderer;
|
||||
import com.simibubi.create.content.curiosities.tools.ExtendoGripRenderHandler;
|
||||
import com.simibubi.create.content.curiosities.zapper.ZapperItem;
|
||||
import com.simibubi.create.content.curiosities.zapper.ZapperRenderHandler;
|
||||
|
@ -143,6 +144,7 @@ public class ClientEvents {
|
|||
CreateClient.OUTLINER.tickOutlines();
|
||||
CreateClient.GHOST_BLOCKS.tickGhosts();
|
||||
ContraptionRenderDispatcher.tick();
|
||||
BlueprintOverlayRenderer.tick();
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
@ -225,6 +227,7 @@ public class ClientEvents {
|
|||
float partialTicks) {
|
||||
CreateClient.SCHEMATIC_HANDLER.renderOverlay(ms, buffer, light, overlay, partialTicks);
|
||||
LinkedControllerClientHandler.renderOverlay(ms, buffer, light, overlay, partialTicks);
|
||||
BlueprintOverlayRenderer.renderOverlay(ms, buffer, light, overlay, partialTicks);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
|
|
@ -59,6 +59,7 @@ public enum AllGuiTextures implements IScreenRenderable {
|
|||
SEQUENCER_AWAIT("sequencer.png", 0, 160, 162, 22),
|
||||
|
||||
LINKED_CONTROLLER("curiosities2.png", 180, 109),
|
||||
BLUEPRINT("curiosities2.png", 0, 109, 179, 109),
|
||||
|
||||
// JEI
|
||||
JEI_SLOT("jei/widgets.png", 18, 18),
|
||||
|
@ -83,6 +84,11 @@ public enum AllGuiTextures implements IScreenRenderable {
|
|||
INDICATOR_GREEN("widgets.png", 36, 18, 18, 6),
|
||||
INDICATOR_YELLOW("widgets.png", 54, 18, 18, 6),
|
||||
INDICATOR_RED("widgets.png", 72, 18, 18, 6),
|
||||
|
||||
HOTSLOT_ARROW("widgets.png", 24, 51, 20, 12),
|
||||
HOTSLOT("widgets.png", 0, 68, 22, 22),
|
||||
HOTSLOT_ACTIVE("widgets.png", 0, 46, 22, 22),
|
||||
HOTSLOT_SUPER_ACTIVE("widgets.png", 27, 67, 24, 24),
|
||||
|
||||
SPEECH_TOOLTIP_BACKGROUND("widgets.png", 0, 24, 8, 8),
|
||||
SPEECH_TOOLTIP_COLOR("widgets.png", 8, 24, 8, 8),
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
package com.simibubi.create.foundation.gui;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.inventory.container.ClickType;
|
||||
import net.minecraft.inventory.container.Container;
|
||||
import net.minecraft.inventory.container.ContainerType;
|
||||
import net.minecraft.inventory.container.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
|
||||
public abstract class GhostItemContainer<T> extends Container implements IClearableContainer {
|
||||
|
||||
public PlayerEntity player;
|
||||
public PlayerInventory playerInventory;
|
||||
public ItemStackHandler ghostInventory;
|
||||
public T contentHolder;
|
||||
|
||||
protected GhostItemContainer(ContainerType<?> type, int id, PlayerInventory inv, PacketBuffer extraData) {
|
||||
super(type, id);
|
||||
init(inv, createOnClient(extraData));
|
||||
}
|
||||
|
||||
protected GhostItemContainer(ContainerType<?> type, int id, PlayerInventory inv, T contentHolder) {
|
||||
super(type, id);
|
||||
init(inv, contentHolder);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
protected abstract T createOnClient(PacketBuffer extraData);
|
||||
|
||||
protected abstract void addSlots();
|
||||
|
||||
protected abstract ItemStackHandler createGhostInventory();
|
||||
|
||||
protected abstract void readData(T contentHolder);
|
||||
|
||||
protected abstract void saveData(T contentHolder);
|
||||
|
||||
protected abstract boolean allowRepeats();
|
||||
|
||||
protected void init(PlayerInventory inv, T contentHolder) {
|
||||
player = inv.player;
|
||||
playerInventory = inv;
|
||||
this.contentHolder = contentHolder;
|
||||
ghostInventory = createGhostInventory();
|
||||
readData(contentHolder);
|
||||
addSlots();
|
||||
detectAndSendChanges();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearContents() {
|
||||
for (int i = 0; i < ghostInventory.getSlots(); i++)
|
||||
ghostInventory.setStackInSlot(i, ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
protected void addPlayerSlots(int x, int y) {
|
||||
for (int hotbarSlot = 0; hotbarSlot < 9; ++hotbarSlot)
|
||||
this.addSlot(new Slot(playerInventory, hotbarSlot, x + hotbarSlot * 18, y + 58));
|
||||
for (int row = 0; row < 3; ++row)
|
||||
for (int col = 0; col < 9; ++col)
|
||||
this.addSlot(new Slot(playerInventory, col + row * 9 + 9, x + col * 18, y + row * 18));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMergeSlot(ItemStack stack, Slot slotIn) {
|
||||
return slotIn.inventory == playerInventory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDragIntoSlot(Slot slotIn) {
|
||||
if (allowRepeats())
|
||||
return true;
|
||||
return slotIn.inventory == playerInventory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInteractWith(PlayerEntity playerIn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack slotClick(int slotId, int dragType, ClickType clickTypeIn, PlayerEntity player) {
|
||||
ItemStack held = playerInventory.getItemStack();
|
||||
if (slotId < 36)
|
||||
return super.slotClick(slotId, dragType, clickTypeIn, player);
|
||||
if (clickTypeIn == ClickType.THROW)
|
||||
return ItemStack.EMPTY;
|
||||
|
||||
int slot = slotId - 36;
|
||||
if (clickTypeIn == ClickType.CLONE) {
|
||||
if (player.isCreative() && held.isEmpty()) {
|
||||
ItemStack stackInSlot = ghostInventory.getStackInSlot(slot)
|
||||
.copy();
|
||||
stackInSlot.setCount(stackInSlot.getMaxStackSize());
|
||||
playerInventory.setItemStack(stackInSlot);
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
if (held.isEmpty()) {
|
||||
ghostInventory.setStackInSlot(slot, ItemStack.EMPTY);
|
||||
getSlot(slotId).onSlotChanged();
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
ItemStack insert = held.copy();
|
||||
insert.setCount(1);
|
||||
ghostInventory.setStackInSlot(slot, insert);
|
||||
getSlot(slotId).onSlotChanged();
|
||||
return held;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) {
|
||||
if (index < 36) {
|
||||
ItemStack stackToInsert = playerInventory.getStackInSlot(index);
|
||||
for (int i = 0; i < ghostInventory.getSlots(); i++) {
|
||||
ItemStack stack = ghostInventory.getStackInSlot(i);
|
||||
if (!allowRepeats() && ItemHandlerHelper.canItemStacksStack(stack, stackToInsert))
|
||||
break;
|
||||
if (stack.isEmpty()) {
|
||||
ItemStack copy = stackToInsert.copy();
|
||||
copy.setCount(1);
|
||||
ghostInventory.insertItem(i, copy, false);
|
||||
getSlot(i + 36).onSlotChanged();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ghostInventory.extractItem(index - 36, 1, false);
|
||||
getSlot(index).onSlotChanged();
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onContainerClosed(PlayerEntity playerIn) {
|
||||
super.onContainerClosed(playerIn);
|
||||
saveData(contentHolder);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package com.simibubi.create.foundation.gui;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraftforge.fml.network.NetworkEvent.Context;
|
||||
|
||||
public class GhostItemSubmitPacket extends SimplePacketBase {
|
||||
|
||||
private final ItemStack item;
|
||||
private final int slot;
|
||||
|
||||
public GhostItemSubmitPacket(ItemStack item, int slot) {
|
||||
this.item = item;
|
||||
this.slot = slot;
|
||||
}
|
||||
|
||||
public GhostItemSubmitPacket(PacketBuffer buffer) {
|
||||
item = buffer.readItemStack();
|
||||
slot = buffer.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketBuffer buffer) {
|
||||
buffer.writeItemStack(item);
|
||||
buffer.writeInt(slot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Supplier<Context> context) {
|
||||
context.get()
|
||||
.enqueueWork(() -> {
|
||||
ServerPlayerEntity player = context.get()
|
||||
.getSender();
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
if (player.openContainer instanceof GhostItemContainer) {
|
||||
GhostItemContainer<?> c = (GhostItemContainer<?>) player.openContainer;
|
||||
c.ghostInventory.setStackInSlot(slot, item);
|
||||
c.getSlot(36 + slot).onSlotChanged();
|
||||
}
|
||||
|
||||
});
|
||||
context.get()
|
||||
.setPacketHandled(true);
|
||||
}
|
||||
|
||||
}
|
|
@ -22,6 +22,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.tra
|
|||
import com.simibubi.create.content.contraptions.fluids.actors.FluidSplashPacket;
|
||||
import com.simibubi.create.content.contraptions.relays.advanced.sequencer.ConfigureSequencedGearshiftPacket;
|
||||
import com.simibubi.create.content.curiosities.symmetry.SymmetryEffectPacket;
|
||||
import com.simibubi.create.content.curiosities.tools.BlueprintAssignCompleteRecipePacket;
|
||||
import com.simibubi.create.content.curiosities.tools.ExtendoGripInteractionPacket;
|
||||
import com.simibubi.create.content.curiosities.zapper.ZapperBeamPacket;
|
||||
import com.simibubi.create.content.logistics.block.depot.EjectorElytraPacket;
|
||||
|
@ -44,6 +45,7 @@ import com.simibubi.create.foundation.command.HighlightPacket;
|
|||
import com.simibubi.create.foundation.command.SConfigureConfigPacket;
|
||||
import com.simibubi.create.foundation.config.ui.CConfigureConfigPacket;
|
||||
import com.simibubi.create.foundation.gui.ClearContainerPacket;
|
||||
import com.simibubi.create.foundation.gui.GhostItemSubmitPacket;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringCountUpdatePacket;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollValueUpdatePacket;
|
||||
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
||||
|
@ -88,6 +90,8 @@ public enum AllPackets {
|
|||
LINKED_CONTROLLER_INPUT(LinkedControllerInputPacket.class, LinkedControllerInputPacket::new, PLAY_TO_SERVER),
|
||||
LINKED_CONTROLLER_BIND(LinkedControllerBindPacket.class, LinkedControllerBindPacket::new, PLAY_TO_SERVER),
|
||||
C_CONFIGURE_CONFIG(CConfigureConfigPacket.class, CConfigureConfigPacket::new, PLAY_TO_SERVER),
|
||||
SUBMIT_GHOST_ITEM(GhostItemSubmitPacket.class, GhostItemSubmitPacket::new, PLAY_TO_SERVER),
|
||||
BLUEPRINT_COMPLETE_RECIPE(BlueprintAssignCompleteRecipePacket.class, BlueprintAssignCompleteRecipePacket::new, PLAY_TO_SERVER),
|
||||
|
||||
// Server to Client
|
||||
SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_TO_CLIENT),
|
||||
|
@ -106,6 +110,7 @@ public enum AllPackets {
|
|||
BLOCK_HIGHLIGHT(HighlightPacket.class, HighlightPacket::new, PLAY_TO_CLIENT),
|
||||
TUNNEL_FLAP(TunnelFlapPacket.class, TunnelFlapPacket::new, PLAY_TO_CLIENT),
|
||||
FUNNEL_FLAP(FunnelFlapPacket.class, FunnelFlapPacket::new, PLAY_TO_CLIENT),
|
||||
PERSISTENT_DATA(ISyncPersistentData.Packet.class, ISyncPersistentData.Packet::new, PLAY_TO_CLIENT),
|
||||
|
||||
;
|
||||
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
package com.simibubi.create.foundation.networking;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraftforge.fml.network.NetworkEvent.Context;
|
||||
import net.minecraftforge.fml.network.PacketDistributor;
|
||||
|
||||
public interface ISyncPersistentData {
|
||||
|
||||
void onPersistentDataUpdated();
|
||||
|
||||
default void syncPersistentDataWithTracking(Entity self) {
|
||||
AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> self), new Packet(self));
|
||||
}
|
||||
|
||||
public static class Packet extends SimplePacketBase {
|
||||
|
||||
private int entityId;
|
||||
private Entity entity;
|
||||
private CompoundNBT readData;
|
||||
|
||||
public Packet(Entity entity) {
|
||||
this.entity = entity;
|
||||
this.entityId = entity.getEntityId();
|
||||
}
|
||||
|
||||
public Packet(PacketBuffer buffer) {
|
||||
entityId = buffer.readInt();
|
||||
readData = buffer.readCompoundTag();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketBuffer buffer) {
|
||||
buffer.writeInt(entityId);
|
||||
buffer.writeCompoundTag(entity.getPersistentData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Supplier<Context> context) {
|
||||
context.get()
|
||||
.enqueueWork(() -> {
|
||||
Entity entityByID = Minecraft.getInstance().world.getEntityByID(entityId);
|
||||
if (!(entityByID instanceof ISyncPersistentData))
|
||||
return;
|
||||
CompoundNBT data = entityByID.getPersistentData();
|
||||
for (Iterator<String> iterator = data.keySet()
|
||||
.iterator(); iterator.hasNext();) {
|
||||
data.remove(iterator.next());
|
||||
}
|
||||
data.merge(readData);
|
||||
((ISyncPersistentData) entityByID).onPersistentDataUpdated();
|
||||
});
|
||||
context.get()
|
||||
.setPacketHandled(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -470,6 +470,14 @@
|
|||
"create.linked_controller.frequency_slot_1": "Keybind: %1$s, Freq. #1",
|
||||
"create.linked_controller.frequency_slot_2": "Keybind: %1$s, Freq. #2",
|
||||
|
||||
"create.crafting_blueprint.crafting_slot": "Ingredient Slot",
|
||||
"create.crafting_blueprint.filter_items_viable": "Advanced filter items are viable",
|
||||
"create.crafting_blueprint.display_slot": "Display Slot",
|
||||
"create.crafting_blueprint.inferred": "Inferred from recipe",
|
||||
"create.crafting_blueprint.manually_assigned": "Manually assigned",
|
||||
"create.crafting_blueprint.secondary_display_slot": "Secondary Display Slot",
|
||||
"create.crafting_blueprint.optional": "Optional",
|
||||
|
||||
"create.hint.hose_pulley.title": "Bottomless Supply",
|
||||
"create.hint.hose_pulley": "The targeted body of fluid is considered infinite.",
|
||||
"create.hint.mechanical_arm_no_targets.title": "No Targets",
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"credit": "Made with Blockbench",
|
||||
"textures": {
|
||||
"0": "create:entity/blueprint_large",
|
||||
"particle": "create:entity/blueprint_large"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [-16, 0, -16],
|
||||
"to": [32, 1, 32],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 12, 0.25], "rotation": 180, "texture": "#0"},
|
||||
"east": {"uv": [11.75, 0, 12, 12], "rotation": 90, "texture": "#0"},
|
||||
"south": {"uv": [0, 11.75, 12, 12], "texture": "#0"},
|
||||
"west": {"uv": [0, 0, 0.25, 12], "rotation": 270, "texture": "#0"},
|
||||
"up": {"uv": [0, 0, 12, 12], "texture": "#0"},
|
||||
"down": {"uv": [0, 0, 12, 12], "rotation": 270, "texture": "#0"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"credit": "Made with Blockbench",
|
||||
"textures": {
|
||||
"0": "create:entity/blueprint_medium",
|
||||
"particle": "create:entity/blueprint_medium"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [-8, 0, -8],
|
||||
"to": [24, 1, 24],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 16, 0.5], "rotation": 180, "texture": "#0"},
|
||||
"east": {"uv": [0, 15.5, 16, 16], "rotation": 180, "texture": "#0"},
|
||||
"south": {"uv": [0, 15.5, 16, 16], "texture": "#0"},
|
||||
"west": {"uv": [0, 0, 0.5, 16], "rotation": 270, "texture": "#0"},
|
||||
"up": {"uv": [0, 0, 16, 16], "texture": "#0"},
|
||||
"down": {"uv": [0, 0, 16, 16], "rotation": 270, "texture": "#0"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"credit": "Made with Blockbench",
|
||||
"textures": {
|
||||
"0": "create:entity/blueprint_small",
|
||||
"particle": "create:entity/blueprint_small"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [0, 0, 0],
|
||||
"to": [16, 1, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 16, 1], "rotation": 180, "texture": "#0"},
|
||||
"east": {"uv": [0, 15, 16, 16], "rotation": 180, "texture": "#0"},
|
||||
"south": {"uv": [0, 15, 16, 16], "texture": "#0"},
|
||||
"west": {"uv": [0, 0, 1, 16], "rotation": 270, "texture": "#0"},
|
||||
"up": {"uv": [0, 0, 16, 16], "texture": "#0"},
|
||||
"down": {"uv": [0, 0, 16, 16], "rotation": 270, "texture": "#0"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
After Width: | Height: | Size: 674 B |
After Width: | Height: | Size: 737 B |
After Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 259 B |