diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index 28f03b4a8..9c30843cb 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -396,6 +396,7 @@ f385988cb6fa9c48b5d59a6942ec50ed2b60c8bf assets/create/blockstates/stockpile_swi e815bfd854c2653f10828bb11950f7fb991d7efc assets/create/blockstates/stressometer.json 8b0c2c7ac72529565b3339aa8df7565858100afa assets/create/blockstates/tiled_glass.json a2454400b1cf9889f70aebdc89c52a1be25f543c assets/create/blockstates/tiled_glass_pane.json +a00f2e1bf002bd5c961d3571c67bdb1dab803bc7 assets/create/blockstates/toolbox.json a8094531617e27a545c4815ab2062bf0ffca3633 assets/create/blockstates/turntable.json 69dfe8afaa8eb6105dae9f76ab8b7847bf90b8c6 assets/create/blockstates/vertical_framed_glass.json c4db76b9d36cfb098df0d158cb6f8b82768ebe14 assets/create/blockstates/vertical_framed_glass_pane.json @@ -425,20 +426,20 @@ 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 -fb760b12b4bc8114744d3acc6a597b2fad88d988 assets/create/lang/en_ud.json -66e8ae18a98d86c66393c908ab51eae5060b8e04 assets/create/lang/en_us.json -9e94c2420840c516e24dfd7968aaad61da24b5a2 assets/create/lang/unfinished/de_de.json -f1a6ed9a5812c89e7c7152c9abf2b64c133fd27d assets/create/lang/unfinished/es_es.json -23a46ae0bc7b2181f26eeed70801714a254d2587 assets/create/lang/unfinished/fr_fr.json -5e95153e640edc367b963489df8c92c459badcd3 assets/create/lang/unfinished/it_it.json -a951315b2591051dad6c53739fe554fe78595250 assets/create/lang/unfinished/ja_jp.json -419a1fc9af7d7ea0ccd612847df74e0b45380864 assets/create/lang/unfinished/ko_kr.json -dbc823d8cb38598e75871a2187b2a58d7f77f86a assets/create/lang/unfinished/nl_nl.json -ac609477c295be1705d3efc07848ffe6779fd397 assets/create/lang/unfinished/pl_pl.json -95e17b968103e0ef62411489e699d39ac7ff0b64 assets/create/lang/unfinished/pt_br.json -b37f50f613b0df44032fe5d618a5ce7227be8087 assets/create/lang/unfinished/ru_ru.json -fa465cd2c595bcd71449ad432a1908e27897177a assets/create/lang/unfinished/zh_cn.json -6192a7ede669ae6b6f8de6701b8a924d6a756c4a assets/create/lang/unfinished/zh_tw.json +337227971382d97fbaa69170e0b6bcc621bdc494 assets/create/lang/en_ud.json +307e88153d5288781e906e566f73ccd59fbcd945 assets/create/lang/en_us.json +5268c9117961dabecdae27b3190d02a8c0ea1077 assets/create/lang/unfinished/de_de.json +2e2002aefd045f492b7232884bd63c7a68d41480 assets/create/lang/unfinished/es_es.json +78836cc1527a95e7e40bc7f50faa95f8cdf5cd9d assets/create/lang/unfinished/fr_fr.json +b83a58ff24f2eca59c628c9a49e286d2feeece35 assets/create/lang/unfinished/it_it.json +5e3e878fe3fd58ba7911877609bf4f0be5a7c71d assets/create/lang/unfinished/ja_jp.json +ff6560eef8744197ab55334392df0a91898d80b2 assets/create/lang/unfinished/ko_kr.json +d0637cc0fa640b328dcdbaf74ae6967a7e15b980 assets/create/lang/unfinished/nl_nl.json +a23c910164b9d295f7c1f5a5e4d9a08094f1f00c assets/create/lang/unfinished/pl_pl.json +bb56417e9607b45350f329f865d2caa7038ebcec assets/create/lang/unfinished/pt_br.json +b643778faf6706b85ad567066de7176272df73d9 assets/create/lang/unfinished/ru_ru.json +45f4a765689a28da8fa267c2845fcf59135c6034 assets/create/lang/unfinished/zh_cn.json +3ac73d1173b450a4fa4eb5622b903cf4b52fbd0b 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 @@ -1664,6 +1665,7 @@ bab8f78c319b2a79ed55c5d2a94b521ddaa44996 assets/create/models/item/stressometer. 088af343cda8a949f1d950e15e72b51ffca20a1d assets/create/models/item/sweet_roll.json b1d3d00ff05908feacad06a86800da96cc9bc65d assets/create/models/item/tiled_glass.json a7d0b746637897209bd86b1a6501ecbfb46d8270 assets/create/models/item/tiled_glass_pane.json +e3c708122fc5a5455bf7b4f8ac48e9d6c00278a9 assets/create/models/item/toolbox.json f8a4fa1ccecb16a3941cc46db7481ed8e8429a5e assets/create/models/item/tree_fertilizer.json fb24881c4e92bbb7ffa54a71e0af6b1c66d84829 assets/create/models/item/turntable.json 2a6be52ddedd614dc3b8a6b659bfbd7a4be54252 assets/create/models/item/vertical_framed_glass.json @@ -2829,6 +2831,7 @@ ec2889e712702644092197a4b41a682fb953817d data/create/loot_tables/blocks/stockpil 3479775008a256bc35f98b31655975f7d5c836b2 data/create/loot_tables/blocks/stressometer.json 05e843ca6eb5e299bf41de123977a1045c120ad4 data/create/loot_tables/blocks/tiled_glass.json e999969f05d2625e61757aa82092d232b99f6e0a data/create/loot_tables/blocks/tiled_glass_pane.json +ef939c8c30e7f6235290e85ff7afd96478c20408 data/create/loot_tables/blocks/toolbox.json 7b66ad2c48449bafd0cdbd086ac41218cb73a814 data/create/loot_tables/blocks/turntable.json 028e293b5cd694017962f67dc80dba719f904e28 data/create/loot_tables/blocks/vertical_framed_glass.json d0156602dd5f4a274c293df67e19374820c72890 data/create/loot_tables/blocks/vertical_framed_glass_pane.json diff --git a/src/generated/resources/assets/create/blockstates/toolbox.json b/src/generated/resources/assets/create/blockstates/toolbox.json new file mode 100644 index 000000000..37c3e2a2c --- /dev/null +++ b/src/generated/resources/assets/create/blockstates/toolbox.json @@ -0,0 +1,34 @@ +{ + "variants": { + "facing=north,waterlogged=false": { + "model": "create:block/toolbox/block" + }, + "facing=south,waterlogged=false": { + "model": "create:block/toolbox/block", + "y": 180 + }, + "facing=west,waterlogged=false": { + "model": "create:block/toolbox/block", + "y": 270 + }, + "facing=east,waterlogged=false": { + "model": "create:block/toolbox/block", + "y": 90 + }, + "facing=north,waterlogged=true": { + "model": "create:block/toolbox/block" + }, + "facing=south,waterlogged=true": { + "model": "create:block/toolbox/block", + "y": 180 + }, + "facing=west,waterlogged=true": { + "model": "create:block/toolbox/block", + "y": 270 + }, + "facing=east,waterlogged=true": { + "model": "create:block/toolbox/block", + "y": 90 + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/create/lang/en_ud.json b/src/generated/resources/assets/create/lang/en_ud.json index 9bdbea809..8f30bb79b 100644 --- a/src/generated/resources/assets/create/lang/en_ud.json +++ b/src/generated/resources/assets/create/lang/en_ud.json @@ -397,6 +397,7 @@ "block.create.stressometer": "\u0279\u01DD\u0287\u01DD\u026Foss\u01DD\u0279\u0287S", "block.create.tiled_glass": "ss\u0250\u05DF\u2141 p\u01DD\u05DF\u0131\u27D8", "block.create.tiled_glass_pane": "\u01DDu\u0250\u0500 ss\u0250\u05DF\u2141 p\u01DD\u05DF\u0131\u27D8", + "block.create.toolbox": "xoq\u05DFoo\u27D8", "block.create.turntable": "\u01DD\u05DFq\u0250\u0287u\u0279n\u27D8", "block.create.vertical_framed_glass": "ss\u0250\u05DF\u2141 p\u01DD\u026F\u0250\u0279\u2132 \u05DF\u0250\u0254\u0131\u0287\u0279\u01DD\u039B", "block.create.vertical_framed_glass_pane": "\u01DDu\u0250\u0500 ss\u0250\u05DF\u2141 p\u01DD\u026F\u0250\u0279\u2132 \u05DF\u0250\u0254\u0131\u0287\u0279\u01DD\u039B", diff --git a/src/generated/resources/assets/create/lang/en_us.json b/src/generated/resources/assets/create/lang/en_us.json index 268153180..7b6b6dca1 100644 --- a/src/generated/resources/assets/create/lang/en_us.json +++ b/src/generated/resources/assets/create/lang/en_us.json @@ -400,6 +400,7 @@ "block.create.stressometer": "Stressometer", "block.create.tiled_glass": "Tiled Glass", "block.create.tiled_glass_pane": "Tiled Glass Pane", + "block.create.toolbox": "Toolbox", "block.create.turntable": "Turntable", "block.create.vertical_framed_glass": "Vertical Framed Glass", "block.create.vertical_framed_glass_pane": "Vertical Framed Glass Pane", @@ -790,6 +791,11 @@ "create.gui.scrollInput.shiftScrollsFaster": "Shift to Scroll Faster", "create.gui.toolmenu.focusKey": "Hold [%1$s] to Focus", "create.gui.toolmenu.cycle": "[SCROLL] to Cycle", + + "create.toolbox.unequip": "Unequip: %1$s", + "create.toolbox.outOfRange": "Toolbox of held item not in Range", + "create.toolbox.detach": "Stop tracking and keep item", + "create.gui.symmetryWand.mirrorType": "Mirror", "create.gui.symmetryWand.orientation": "Orientation", diff --git a/src/generated/resources/assets/create/lang/unfinished/de_de.json b/src/generated/resources/assets/create/lang/unfinished/de_de.json index ce55f9519..5f096580d 100644 --- a/src/generated/resources/assets/create/lang/unfinished/de_de.json +++ b/src/generated/resources/assets/create/lang/unfinished/de_de.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1134", + "_": "Missing Localizations: 1138", "_": "->------------------------] Game Elements [------------------------<-", @@ -401,6 +401,7 @@ "block.create.stressometer": "Stressometer", "block.create.tiled_glass": "Glasfliesen", "block.create.tiled_glass_pane": "Glasfliesenscheibe", + "block.create.toolbox": "UNLOCALIZED: Toolbox", "block.create.turntable": "Drehtisch", "block.create.vertical_framed_glass": "Vertikal Gerahmtes Glas", "block.create.vertical_framed_glass_pane": "Vertikal Gerahmte Glasscheibe", @@ -791,6 +792,11 @@ "create.gui.scrollInput.shiftScrollsFaster": "Shift zum schnelleren Auswählen", "create.gui.toolmenu.focusKey": "Halte [%1$s] zum Fokussieren", "create.gui.toolmenu.cycle": "[Mausrad] zum Wechseln", + + "create.toolbox.unequip": "UNLOCALIZED: Unequip: %1$s", + "create.toolbox.outOfRange": "UNLOCALIZED: Toolbox of held item not in Range", + "create.toolbox.detach": "UNLOCALIZED: Stop tracking and keep item", + "create.gui.symmetryWand.mirrorType": "Spiegeln", "create.gui.symmetryWand.orientation": "Orientierung", diff --git a/src/generated/resources/assets/create/lang/unfinished/es_es.json b/src/generated/resources/assets/create/lang/unfinished/es_es.json index 79a683627..44d35f9f9 100644 --- a/src/generated/resources/assets/create/lang/unfinished/es_es.json +++ b/src/generated/resources/assets/create/lang/unfinished/es_es.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 0", + "_": "Missing Localizations: 4", "_": "->------------------------] Game Elements [------------------------<-", @@ -401,6 +401,7 @@ "block.create.stressometer": "Estresómetro", "block.create.tiled_glass": "Vidrio esmaltado", "block.create.tiled_glass_pane": "Panel de vidrio esmaltado", + "block.create.toolbox": "UNLOCALIZED: Toolbox", "block.create.turntable": "Plataforma giratoria mecánica", "block.create.vertical_framed_glass": "Vidrio esmaltado vertical", "block.create.vertical_framed_glass_pane": "Panel de vidrio esmaltado vertical", @@ -791,6 +792,11 @@ "create.gui.scrollInput.shiftScrollsFaster": "Mayús izdo para usar la rueda del ratón más rápido", "create.gui.toolmenu.focusKey": "Mantén [%1$s] para enfocar", "create.gui.toolmenu.cycle": "[RUEDA DEL RATÓN] para el ciclo", + + "create.toolbox.unequip": "UNLOCALIZED: Unequip: %1$s", + "create.toolbox.outOfRange": "UNLOCALIZED: Toolbox of held item not in Range", + "create.toolbox.detach": "UNLOCALIZED: Stop tracking and keep item", + "create.gui.symmetryWand.mirrorType": "Espejado", "create.gui.symmetryWand.orientation": "Orientación", diff --git a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json index 2e0c26dd4..78e9c4a2a 100644 --- a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json +++ b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1386", + "_": "Missing Localizations: 1390", "_": "->------------------------] Game Elements [------------------------<-", @@ -401,6 +401,7 @@ "block.create.stressometer": "Stressomètre", "block.create.tiled_glass": "Verre carrelé", "block.create.tiled_glass_pane": "Vitre carrelé", + "block.create.toolbox": "UNLOCALIZED: Toolbox", "block.create.turntable": "Plaque tournante", "block.create.vertical_framed_glass": "Fenêtre en verre verticale", "block.create.vertical_framed_glass_pane": "Vitre encadrée verticale", @@ -791,6 +792,11 @@ "create.gui.scrollInput.shiftScrollsFaster": "Maj pour défiler plus rapidement", "create.gui.toolmenu.focusKey": "Enfoncez [%1$s] pour focus", "create.gui.toolmenu.cycle": "[SCROLL] pour cycler", + + "create.toolbox.unequip": "UNLOCALIZED: Unequip: %1$s", + "create.toolbox.outOfRange": "UNLOCALIZED: Toolbox of held item not in Range", + "create.toolbox.detach": "UNLOCALIZED: Stop tracking and keep item", + "create.gui.symmetryWand.mirrorType": "Mirroir", "create.gui.symmetryWand.orientation": "Orientation", diff --git a/src/generated/resources/assets/create/lang/unfinished/it_it.json b/src/generated/resources/assets/create/lang/unfinished/it_it.json index 8108827f1..e8def88f1 100644 --- a/src/generated/resources/assets/create/lang/unfinished/it_it.json +++ b/src/generated/resources/assets/create/lang/unfinished/it_it.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 914", + "_": "Missing Localizations: 918", "_": "->------------------------] Game Elements [------------------------<-", @@ -401,6 +401,7 @@ "block.create.stressometer": "Stressometro", "block.create.tiled_glass": "Vetro piastrellato", "block.create.tiled_glass_pane": "Pannello di vetro piastrellato", + "block.create.toolbox": "UNLOCALIZED: Toolbox", "block.create.turntable": "Piatto", "block.create.vertical_framed_glass": "Finestra di vetro verticale", "block.create.vertical_framed_glass_pane": "Pannello di finestra di vetro verticale", @@ -791,6 +792,11 @@ "create.gui.scrollInput.shiftScrollsFaster": "Premi shift per scorrere più velocemente", "create.gui.toolmenu.focusKey": "Premi [%1$s] per aprire il menù", "create.gui.toolmenu.cycle": "[SCORRI] per navigare", + + "create.toolbox.unequip": "UNLOCALIZED: Unequip: %1$s", + "create.toolbox.outOfRange": "UNLOCALIZED: Toolbox of held item not in Range", + "create.toolbox.detach": "UNLOCALIZED: Stop tracking and keep item", + "create.gui.symmetryWand.mirrorType": "Specchio", "create.gui.symmetryWand.orientation": "Orientamento", diff --git a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json index 5650fe7dd..5c6496fab 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json +++ b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 9", + "_": "Missing Localizations: 13", "_": "->------------------------] Game Elements [------------------------<-", @@ -401,6 +401,7 @@ "block.create.stressometer": "応力メーター", "block.create.tiled_glass": "タイルガラス", "block.create.tiled_glass_pane": "タイルガラス板", + "block.create.toolbox": "UNLOCALIZED: Toolbox", "block.create.turntable": "ターンテーブル", "block.create.vertical_framed_glass": "縦型ガラス窓", "block.create.vertical_framed_glass_pane": "縦型ガラス窓板", @@ -791,6 +792,11 @@ "create.gui.scrollInput.shiftScrollsFaster": "シフトを押してスクロールを加速", "create.gui.toolmenu.focusKey": "[%1$s] 長押しでフォーカスする", "create.gui.toolmenu.cycle": "[スクロール] で循環", + + "create.toolbox.unequip": "UNLOCALIZED: Unequip: %1$s", + "create.toolbox.outOfRange": "UNLOCALIZED: Toolbox of held item not in Range", + "create.toolbox.detach": "UNLOCALIZED: Stop tracking and keep item", + "create.gui.symmetryWand.mirrorType": "ミラーの種類", "create.gui.symmetryWand.orientation": "方向", diff --git a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json index b45ee1cfb..987018999 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json +++ b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 24", + "_": "Missing Localizations: 28", "_": "->------------------------] Game Elements [------------------------<-", @@ -401,6 +401,7 @@ "block.create.stressometer": "피로도 계측기", "block.create.tiled_glass": "타일 유리", "block.create.tiled_glass_pane": "타일 유리판", + "block.create.toolbox": "UNLOCALIZED: Toolbox", "block.create.turntable": "돌림판", "block.create.vertical_framed_glass": "수직 유리", "block.create.vertical_framed_glass_pane": "수직 유리판", @@ -791,6 +792,11 @@ "create.gui.scrollInput.shiftScrollsFaster": "쉬프트-스크롤로 빨리 수정하기", "create.gui.toolmenu.focusKey": "[%1$s]를 눌러 세부정보 보기", "create.gui.toolmenu.cycle": "스크롤로 순환", + + "create.toolbox.unequip": "UNLOCALIZED: Unequip: %1$s", + "create.toolbox.outOfRange": "UNLOCALIZED: Toolbox of held item not in Range", + "create.toolbox.detach": "UNLOCALIZED: Stop tracking and keep item", + "create.gui.symmetryWand.mirrorType": "거울의 형태", "create.gui.symmetryWand.orientation": "거울의 방향", diff --git a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json index 2a8d48fd3..39010143c 100644 --- a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json +++ b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1766", + "_": "Missing Localizations: 1770", "_": "->------------------------] Game Elements [------------------------<-", @@ -401,6 +401,7 @@ "block.create.stressometer": "Stressmeter", "block.create.tiled_glass": "Getegeld Glas", "block.create.tiled_glass_pane": "Getegeld Glazen Paneel", + "block.create.toolbox": "UNLOCALIZED: Toolbox", "block.create.turntable": "Draaischijf", "block.create.vertical_framed_glass": "UNLOCALIZED: Vertical Framed Glass", "block.create.vertical_framed_glass_pane": "UNLOCALIZED: Vertical Framed Glass Pane", @@ -791,6 +792,11 @@ "create.gui.scrollInput.shiftScrollsFaster": "Shift om sneller te Scrollen", "create.gui.toolmenu.focusKey": "Hou [%1$s] ingedrukt om te Focusen", "create.gui.toolmenu.cycle": "[SCROLL] om te Cycleën", + + "create.toolbox.unequip": "UNLOCALIZED: Unequip: %1$s", + "create.toolbox.outOfRange": "UNLOCALIZED: Toolbox of held item not in Range", + "create.toolbox.detach": "UNLOCALIZED: Stop tracking and keep item", + "create.gui.symmetryWand.mirrorType": "Spiegelen", "create.gui.symmetryWand.orientation": "Orientatie", diff --git a/src/generated/resources/assets/create/lang/unfinished/pl_pl.json b/src/generated/resources/assets/create/lang/unfinished/pl_pl.json index 010fcaa58..45022fd4f 100644 --- a/src/generated/resources/assets/create/lang/unfinished/pl_pl.json +++ b/src/generated/resources/assets/create/lang/unfinished/pl_pl.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 256", + "_": "Missing Localizations: 260", "_": "->------------------------] Game Elements [------------------------<-", @@ -401,6 +401,7 @@ "block.create.stressometer": "Miernik obciążenia", "block.create.tiled_glass": "Kafelkowane szkło", "block.create.tiled_glass_pane": "Kafelkowana szyba", + "block.create.toolbox": "UNLOCALIZED: Toolbox", "block.create.turntable": "Talerz obrotowy", "block.create.vertical_framed_glass": "Pionowe oprawione szkło", "block.create.vertical_framed_glass_pane": "Pionowa oprawiona szyba", @@ -791,6 +792,11 @@ "create.gui.scrollInput.shiftScrollsFaster": "Naciśnij Shift, aby przewijać szybciej", "create.gui.toolmenu.focusKey": "Przytrzymaj [%1$s], aby skupić", "create.gui.toolmenu.cycle": "[SCROLL] przewijać", + + "create.toolbox.unequip": "UNLOCALIZED: Unequip: %1$s", + "create.toolbox.outOfRange": "UNLOCALIZED: Toolbox of held item not in Range", + "create.toolbox.detach": "UNLOCALIZED: Stop tracking and keep item", + "create.gui.symmetryWand.mirrorType": "Odbicie lustrzane", "create.gui.symmetryWand.orientation": "Orientacja", diff --git a/src/generated/resources/assets/create/lang/unfinished/pt_br.json b/src/generated/resources/assets/create/lang/unfinished/pt_br.json index 6d34e640a..8538ed5fa 100644 --- a/src/generated/resources/assets/create/lang/unfinished/pt_br.json +++ b/src/generated/resources/assets/create/lang/unfinished/pt_br.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 1807", + "_": "Missing Localizations: 1811", "_": "->------------------------] Game Elements [------------------------<-", @@ -401,6 +401,7 @@ "block.create.stressometer": "UNLOCALIZED: Stressometer", "block.create.tiled_glass": "Vidro Entalhado", "block.create.tiled_glass_pane": "Vidraça Entalhada", + "block.create.toolbox": "UNLOCALIZED: Toolbox", "block.create.turntable": "Mesa giratória", "block.create.vertical_framed_glass": "UNLOCALIZED: Vertical Framed Glass", "block.create.vertical_framed_glass_pane": "UNLOCALIZED: Vertical Framed Glass Pane", @@ -791,6 +792,11 @@ "create.gui.scrollInput.shiftScrollsFaster": "UNLOCALIZED: Shift to Scroll Faster", "create.gui.toolmenu.focusKey": "Segure [%1$s] para Focar", "create.gui.toolmenu.cycle": "[SCROLL] para Circular", + + "create.toolbox.unequip": "UNLOCALIZED: Unequip: %1$s", + "create.toolbox.outOfRange": "UNLOCALIZED: Toolbox of held item not in Range", + "create.toolbox.detach": "UNLOCALIZED: Stop tracking and keep item", + "create.gui.symmetryWand.mirrorType": "Espelhar", "create.gui.symmetryWand.orientation": "Orientação", diff --git a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json index 35b858bb2..8374dffca 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json +++ b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 5", + "_": "Missing Localizations: 9", "_": "->------------------------] Game Elements [------------------------<-", @@ -401,6 +401,7 @@ "block.create.stressometer": "Стрессометр", "block.create.tiled_glass": "Плиточное стекло", "block.create.tiled_glass_pane": "Плиточная стеклянная панель", + "block.create.toolbox": "UNLOCALIZED: Toolbox", "block.create.turntable": "Поворотный стол", "block.create.vertical_framed_glass": "Вертикальное обрамлённое стекло", "block.create.vertical_framed_glass_pane": "Вертикальная обрамлённая стеклянная панель", @@ -791,6 +792,11 @@ "create.gui.scrollInput.shiftScrollsFaster": "Нажмите Shift для быстрой прокрутки", "create.gui.toolmenu.focusKey": "Удерживайте [%1$s] для смены задач", "create.gui.toolmenu.cycle": "[Прокрутка] для переключения", + + "create.toolbox.unequip": "UNLOCALIZED: Unequip: %1$s", + "create.toolbox.outOfRange": "UNLOCALIZED: Toolbox of held item not in Range", + "create.toolbox.detach": "UNLOCALIZED: Stop tracking and keep item", + "create.gui.symmetryWand.mirrorType": "Зеркало", "create.gui.symmetryWand.orientation": "Ориентация", diff --git a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json index 0d0f8f5bc..318b583d9 100644 --- a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json +++ b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 4", + "_": "Missing Localizations: 8", "_": "->------------------------] Game Elements [------------------------<-", @@ -401,6 +401,7 @@ "block.create.stressometer": "应力表", "block.create.tiled_glass": "十字玻璃窗", "block.create.tiled_glass_pane": "十字玻璃窗户板", + "block.create.toolbox": "UNLOCALIZED: Toolbox", "block.create.turntable": "转盘", "block.create.vertical_framed_glass": "竖直边框玻璃", "block.create.vertical_framed_glass_pane": "竖直边框玻璃板", @@ -791,6 +792,11 @@ "create.gui.scrollInput.shiftScrollsFaster": "按住 Shift 滚动更快", "create.gui.toolmenu.focusKey": "按住 [%1$s] 鼠标滚轮选择", "create.gui.toolmenu.cycle": "[SCROLL] 循环", + + "create.toolbox.unequip": "UNLOCALIZED: Unequip: %1$s", + "create.toolbox.outOfRange": "UNLOCALIZED: Toolbox of held item not in Range", + "create.toolbox.detach": "UNLOCALIZED: Stop tracking and keep item", + "create.gui.symmetryWand.mirrorType": "镜子类型", "create.gui.symmetryWand.orientation": "方向", diff --git a/src/generated/resources/assets/create/lang/unfinished/zh_tw.json b/src/generated/resources/assets/create/lang/unfinished/zh_tw.json index 9ec60092a..644d74902 100644 --- a/src/generated/resources/assets/create/lang/unfinished/zh_tw.json +++ b/src/generated/resources/assets/create/lang/unfinished/zh_tw.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 19", + "_": "Missing Localizations: 23", "_": "->------------------------] Game Elements [------------------------<-", @@ -401,6 +401,7 @@ "block.create.stressometer": "動能錶", "block.create.tiled_glass": "十字玻璃窗", "block.create.tiled_glass_pane": "十字玻璃窗戶片", + "block.create.toolbox": "UNLOCALIZED: Toolbox", "block.create.turntable": "轉盤", "block.create.vertical_framed_glass": "豎直邊框玻璃", "block.create.vertical_framed_glass_pane": "豎直邊框玻璃片", @@ -791,6 +792,11 @@ "create.gui.scrollInput.shiftScrollsFaster": "按住Shift滾動更快", "create.gui.toolmenu.focusKey": "按住 [%1$s] 滑鼠滾輪選擇", "create.gui.toolmenu.cycle": "[SCROLL] 循環", + + "create.toolbox.unequip": "UNLOCALIZED: Unequip: %1$s", + "create.toolbox.outOfRange": "UNLOCALIZED: Toolbox of held item not in Range", + "create.toolbox.detach": "UNLOCALIZED: Stop tracking and keep item", + "create.gui.symmetryWand.mirrorType": "鏡子類型", "create.gui.symmetryWand.orientation": "方向", diff --git a/src/generated/resources/assets/create/models/item/toolbox.json b/src/generated/resources/assets/create/models/item/toolbox.json new file mode 100644 index 000000000..719de98e9 --- /dev/null +++ b/src/generated/resources/assets/create/models/item/toolbox.json @@ -0,0 +1,3 @@ +{ + "parent": "create:block/toolbox/item" +} \ No newline at end of file diff --git a/src/generated/resources/data/create/loot_tables/blocks/toolbox.json b/src/generated/resources/data/create/loot_tables/blocks/toolbox.json new file mode 100644 index 000000000..f25ecaa38 --- /dev/null +++ b/src/generated/resources/data/create/loot_tables/blocks/toolbox.json @@ -0,0 +1,36 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "rolls": 1, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:copy_name", + "source": "block_entity" + }, + { + "function": "minecraft:copy_nbt", + "source": "block_entity", + "ops": [ + { + "source": "Inventory", + "target": "Inventory", + "op": "replace" + } + ] + } + ], + "name": "create:toolbox" + } + ], + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/AllBlockPartials.java b/src/main/java/com/simibubi/create/AllBlockPartials.java index 8fb10077e..56b2a569e 100644 --- a/src/main/java/com/simibubi/create/AllBlockPartials.java +++ b/src/main/java/com/simibubi/create/AllBlockPartials.java @@ -93,27 +93,29 @@ public class AllBlockPartials { SPOUT_TOP = get("spout/top"), SPOUT_MIDDLE = get("spout/middle"), SPOUT_BOTTOM = get("spout/bottom"), - PECULIAR_BELL = get("peculiar_bell"), - HAUNTED_BELL = get("haunted_bell"), + PECULIAR_BELL = get("peculiar_bell"), HAUNTED_BELL = get("haunted_bell"), - SPEED_CONTROLLER_BRACKET = get("rotation_speed_controller/bracket"), + TOOLBOX_LID = get("toolbox/lid"), TOOLBOX_DRAWER = get("toolbox/drawer"), - GOGGLES = get("goggles"), + SPEED_CONTROLLER_BRACKET = get("rotation_speed_controller/bracket"), - EJECTOR_TOP = get("weighted_ejector/top"), + GOGGLES = get("goggles"), - COPPER_BACKTANK_SHAFT = get("copper_backtank/block_shaft_input"), - COPPER_BACKTANK_COGS = get("copper_backtank/block_cogs"), + EJECTOR_TOP = get("weighted_ejector/top"), - CRAFTING_BLUEPRINT_1x1 = getEntity("crafting_blueprint_small"), - CRAFTING_BLUEPRINT_2x2 = getEntity("crafting_blueprint_medium"), - CRAFTING_BLUEPRINT_3x3 = getEntity("crafting_blueprint_large"), + COPPER_BACKTANK_SHAFT = get("copper_backtank/block_shaft_input"), + COPPER_BACKTANK_COGS = get("copper_backtank/block_cogs"), - COUPLING_ATTACHMENT = getEntity("minecart_coupling/attachment"), - COUPLING_RING = getEntity("minecart_coupling/ring"), - COUPLING_CONNECTOR = getEntity("minecart_coupling/connector"); + CRAFTING_BLUEPRINT_1x1 = getEntity("crafting_blueprint_small"), + CRAFTING_BLUEPRINT_2x2 = getEntity("crafting_blueprint_medium"), + CRAFTING_BLUEPRINT_3x3 = getEntity("crafting_blueprint_large"), - public static final Map> PIPE_ATTACHMENTS = new HashMap<>(); + COUPLING_ATTACHMENT = getEntity("minecart_coupling/attachment"), + COUPLING_RING = getEntity("minecart_coupling/ring"), + COUPLING_CONNECTOR = getEntity("minecart_coupling/connector"); + + public static final Map> PIPE_ATTACHMENTS = + new HashMap<>(); public static final Map BLAZES = new HashMap<>(); static { diff --git a/src/main/java/com/simibubi/create/AllBlocks.java b/src/main/java/com/simibubi/create/AllBlocks.java index a990a6d10..230e2c0bd 100644 --- a/src/main/java/com/simibubi/create/AllBlocks.java +++ b/src/main/java/com/simibubi/create/AllBlocks.java @@ -118,6 +118,7 @@ import com.simibubi.create.content.curiosities.armor.CopperBacktankBlock; import com.simibubi.create.content.curiosities.bell.HauntedBellBlock; import com.simibubi.create.content.curiosities.bell.HauntedBellMovementBehaviour; import com.simibubi.create.content.curiosities.bell.PeculiarBellBlock; +import com.simibubi.create.content.curiosities.toolbox.ToolboxBlock; import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelBlock; import com.simibubi.create.content.logistics.block.belts.tunnel.BrassTunnelBlock; import com.simibubi.create.content.logistics.block.belts.tunnel.BrassTunnelCTBehaviour; @@ -160,9 +161,9 @@ import com.simibubi.create.content.logistics.block.redstone.StockpileSwitchBlock import com.simibubi.create.content.logistics.item.LecternControllerBlock; import com.simibubi.create.content.schematics.block.SchematicTableBlock; import com.simibubi.create.content.schematics.block.SchematicannonBlock; +import com.simibubi.create.foundation.block.BlockStressDefaults; import com.simibubi.create.foundation.block.DyedBlockList; import com.simibubi.create.foundation.block.ItemUseOverrides; -import com.simibubi.create.foundation.block.BlockStressDefaults; import com.simibubi.create.foundation.data.AssetLookup; import com.simibubi.create.foundation.data.BlockStateGen; import com.simibubi.create.foundation.data.BuilderTransformers; @@ -208,7 +209,7 @@ import net.minecraftforge.common.ToolType; public class AllBlocks { private static final CreateRegistrate REGISTRATE = Create.registrate() - .itemGroup(() -> Create.BASE_CREATIVE_TAB); + .itemGroup(() -> Create.BASE_CREATIVE_TAB); // Schematics @@ -224,11 +225,12 @@ public class AllBlocks { Builder builder = LootTable.lootTable(); IBuilder survivesExplosion = SurvivesExplosion.survivesExplosion(); lt.add(block, builder.withPool(LootPool.lootPool() - .when(survivesExplosion) - .setRolls(ConstantRange.exactly(1)) - .add(ItemLootEntry.lootTableItem(AllBlocks.SCHEMATICANNON.get().asItem()) - .apply(CopyNbt.copyData(CopyNbt.Source.BLOCK_ENTITY) - .copy("Options", "BlockEntityTag.Options"))))); + .when(survivesExplosion) + .setRolls(ConstantRange.exactly(1)) + .add(ItemLootEntry.lootTableItem(AllBlocks.SCHEMATICANNON.get() + .asItem()) + .apply(CopyNbt.copyData(CopyNbt.Source.BLOCK_ENTITY) + .copy("Options", "BlockEntityTag.Options"))))); }) .item() .transform(customItemModel()) @@ -501,11 +503,13 @@ public class AllBlocks { .addLayer(() -> RenderType::cutoutMipped) .tag(AllBlockTags.FAN_TRANSPARENT.tag, AllBlockTags.FAN_HEATERS.tag) .loot((lt, block) -> lt.dropOther(block, AllItems.EMPTY_BLAZE_BURNER.get())) - .blockstate((c, p) -> p.getVariantBuilder(c.get()).forAllStates(state -> - ConfiguredModel.builder() - .modelFile(p.models().getExistingFile(p.modLoc( - "block/blaze_burner/" + (state.getValue(LitBlazeBurnerBlock.FLAME_TYPE) == LitBlazeBurnerBlock.FlameType.SOUL ? "block_with_soul_fire" : "block_with_fire") - ))) + .blockstate((c, p) -> p.getVariantBuilder(c.get()) + .forAllStates(state -> ConfiguredModel.builder() + .modelFile(p.models() + .getExistingFile(p.modLoc("block/blaze_burner/" + + (state.getValue(LitBlazeBurnerBlock.FLAME_TYPE) == LitBlazeBurnerBlock.FlameType.SOUL + ? "block_with_soul_fire" + : "block_with_fire")))) .build())) .register(); @@ -598,7 +602,8 @@ public class AllBlocks { .initialProperties(SharedProperties::softMetal) .addLayer(() -> RenderType::cutoutMipped) .blockstate((c, p) -> BlockStateGen.axisBlock(c, p, s -> p.models() - .getExistingFile(p.modLoc("block/fluid_pipe/window" + (s.getValue(GlassFluidPipeBlock.ALT) ? "_alt" : ""))))) + .getExistingFile( + p.modLoc("block/fluid_pipe/window" + (s.getValue(GlassFluidPipeBlock.ALT) ? "_alt" : ""))))) .onRegister(CreateRegistrate.blockModel(() -> PipeAttachmentModel::new)) .loot((p, b) -> p.dropOther(b, FLUID_PIPE.get())) .register(); @@ -626,39 +631,39 @@ public class AllBlocks { .blockstate((c, p) -> BlockStateGen.directionalAxisBlock(c, p, (state, vertical) -> AssetLookup.partialBaseModel(c, p, vertical ? "vertical" : "horizontal", state.getValue(FluidValveBlock.ENABLED) ? "open" : "closed"))) - .onRegister(CreateRegistrate.blockModel(() -> PipeAttachmentModel::new)) - .item() - .transform(customItemModel()) - .register(); + .onRegister(CreateRegistrate.blockModel(() -> PipeAttachmentModel::new)) + .item() + .transform(customItemModel()) + .register(); public static final BlockEntry COPPER_VALVE_HANDLE = - REGISTRATE.block("copper_valve_handle", ValveHandleBlock::copper) - .transform(BuilderTransformers.valveHandle(null)) - .register(); + REGISTRATE.block("copper_valve_handle", ValveHandleBlock::copper) + .transform(BuilderTransformers.valveHandle(null)) + .register(); public static final DyedBlockList DYED_VALVE_HANDLES = new DyedBlockList<>(colour -> { String colourName = colour.getSerializedName(); return REGISTRATE.block(colourName + "_valve_handle", ValveHandleBlock::dyed) - .transform(BuilderTransformers.valveHandle(colour)) - .recipe((c, p) -> ShapedRecipeBuilder.shaped(c.get()) - .pattern("#") - .pattern("-") - .define('#', DyeHelper.getTagOfDye(colour)) - .define('-', AllItemTags.VALVE_HANDLES.tag) - .unlockedBy("has_valve", RegistrateRecipeProvider.hasItem(AllItemTags.VALVE_HANDLES.tag)) - .save(p, Create.asResource("crafting/kinetics/" + c.getName() + "_from_other_valve_handle"))) - .register(); + .transform(BuilderTransformers.valveHandle(colour)) + .recipe((c, p) -> ShapedRecipeBuilder.shaped(c.get()) + .pattern("#") + .pattern("-") + .define('#', DyeHelper.getTagOfDye(colour)) + .define('-', AllItemTags.VALVE_HANDLES.tag) + .unlockedBy("has_valve", RegistrateRecipeProvider.hasItem(AllItemTags.VALVE_HANDLES.tag)) + .save(p, Create.asResource("crafting/kinetics/" + c.getName() + "_from_other_valve_handle"))) + .register(); }); public static final BlockEntry FLUID_TANK = REGISTRATE.block("fluid_tank", FluidTankBlock::regular) - .initialProperties(SharedProperties::softMetal) - .properties(AbstractBlock.Properties::noOcclusion) - .blockstate(new FluidTankGenerator()::generate) - .onRegister(CreateRegistrate.blockModel(() -> FluidTankModel::standard)) - .addLayer(() -> RenderType::cutoutMipped) - .item(FluidTankItem::new) - .model(AssetLookup.customBlockItemModel("_", "block_single_window")) - .build() + .initialProperties(SharedProperties::softMetal) + .properties(AbstractBlock.Properties::noOcclusion) + .blockstate(new FluidTankGenerator()::generate) + .onRegister(CreateRegistrate.blockModel(() -> FluidTankModel::standard)) + .addLayer(() -> RenderType::cutoutMipped) + .item(FluidTankItem::new) + .model(AssetLookup.customBlockItemModel("_", "block_single_window")) + .build() .register(); public static final BlockEntry CREATIVE_FLUID_TANK = @@ -844,11 +849,11 @@ public class AllBlocks { .register(); public static final BlockEntry CONTROLLER_RAIL = - REGISTRATE.block("controller_rail", ControllerRailBlock::new) - .initialProperties(() -> Blocks.POWERED_RAIL) - .blockstate(new ControllerRailGenerator()::generate) - .addLayer(() -> RenderType::cutoutMipped) - .color(() -> ColorHandlers::getRedstonePower) + REGISTRATE.block("controller_rail", ControllerRailBlock::new) + .initialProperties(() -> Blocks.POWERED_RAIL) + .blockstate(new ControllerRailGenerator()::generate) + .addLayer(() -> RenderType::cutoutMipped) + .color(() -> ColorHandlers::getRedstonePower) .tag(BlockTags.RAILS) .item() .model((c, p) -> p.generated(c, Create.asResource("block/" + c.getName()))) @@ -957,68 +962,68 @@ public class AllBlocks { .addLayer(() -> RenderType::cutoutMipped) .item() .transform(customItemModel()) - .register(); + .register(); public static final BlockEntry MECHANICAL_PLOUGH = - REGISTRATE.block("mechanical_plough", PloughBlock::new) - .initialProperties(SharedProperties::stone) - .onRegister(addMovementBehaviour(new PloughMovementBehaviour())) - .blockstate(BlockStateGen.horizontalBlockProvider(false)) - .simpleItem() - .register(); + REGISTRATE.block("mechanical_plough", PloughBlock::new) + .initialProperties(SharedProperties::stone) + .onRegister(addMovementBehaviour(new PloughMovementBehaviour())) + .blockstate(BlockStateGen.horizontalBlockProvider(false)) + .simpleItem() + .register(); public static final DyedBlockList SEATS = new DyedBlockList<>(colour -> { String colourName = colour.getSerializedName(); SeatMovementBehaviour movementBehaviour = new SeatMovementBehaviour(); return REGISTRATE.block(colourName + "_seat", p -> new SeatBlock(p, colour == DyeColor.RED)) - .initialProperties(SharedProperties::wooden) - .onRegister(addMovementBehaviour(movementBehaviour)) - .blockstate((c, p) -> { - p.simpleBlock(c.get(), p.models() - .withExistingParent(colourName + "_seat", p.modLoc("block/seat")) - .texture("1", p.modLoc("block/seat/top_" + colourName)) - .texture("2", p.modLoc("block/seat/side_" + colourName))); - }) - .recipe((c, p) -> { - ShapedRecipeBuilder.shaped(c.get()) - .pattern("#") - .pattern("-") - .define('#', DyeHelper.getWoolOfDye(colour)) - .define('-', ItemTags.WOODEN_SLABS) - .unlockedBy("has_wool", RegistrateRecipeProvider.hasItem(ItemTags.WOOL)) - .save(p, Create.asResource("crafting/kinetics/" + c.getName())); - ShapedRecipeBuilder.shaped(c.get()) - .pattern("#") - .pattern("-") - .define('#', DyeHelper.getTagOfDye(colour)) - .define('-', AllItemTags.SEATS.tag) - .unlockedBy("has_seat", RegistrateRecipeProvider.hasItem(AllItemTags.SEATS.tag)) - .save(p, Create.asResource("crafting/kinetics/" + c.getName() + "_from_other_seat")); - }) - .onRegisterAfter(Item.class, v -> TooltipHelper.referTo(v, "block.create.seat")) - .tag(AllBlockTags.SEATS.tag) - .item() - .tag(AllItemTags.SEATS.tag) - .build() - .register(); + .initialProperties(SharedProperties::wooden) + .onRegister(addMovementBehaviour(movementBehaviour)) + .blockstate((c, p) -> { + p.simpleBlock(c.get(), p.models() + .withExistingParent(colourName + "_seat", p.modLoc("block/seat")) + .texture("1", p.modLoc("block/seat/top_" + colourName)) + .texture("2", p.modLoc("block/seat/side_" + colourName))); + }) + .recipe((c, p) -> { + ShapedRecipeBuilder.shaped(c.get()) + .pattern("#") + .pattern("-") + .define('#', DyeHelper.getWoolOfDye(colour)) + .define('-', ItemTags.WOODEN_SLABS) + .unlockedBy("has_wool", RegistrateRecipeProvider.hasItem(ItemTags.WOOL)) + .save(p, Create.asResource("crafting/kinetics/" + c.getName())); + ShapedRecipeBuilder.shaped(c.get()) + .pattern("#") + .pattern("-") + .define('#', DyeHelper.getTagOfDye(colour)) + .define('-', AllItemTags.SEATS.tag) + .unlockedBy("has_seat", RegistrateRecipeProvider.hasItem(AllItemTags.SEATS.tag)) + .save(p, Create.asResource("crafting/kinetics/" + c.getName() + "_from_other_seat")); + }) + .onRegisterAfter(Item.class, v -> TooltipHelper.referTo(v, "block.create.seat")) + .tag(AllBlockTags.SEATS.tag) + .item() + .tag(AllItemTags.SEATS.tag) + .build() + .register(); }); public static final BlockEntry SAIL_FRAME = REGISTRATE.block("sail_frame", p -> SailBlock.frame(p)) - .initialProperties(SharedProperties::wooden) - .properties(AbstractBlock.Properties::noOcclusion) - .blockstate(BlockStateGen.directionalBlockProvider(false)) - .tag(AllBlockTags.WINDMILL_SAILS.tag) - .tag(AllBlockTags.FAN_TRANSPARENT.tag) - .simpleItem() - .register(); + .initialProperties(SharedProperties::wooden) + .properties(AbstractBlock.Properties::noOcclusion) + .blockstate(BlockStateGen.directionalBlockProvider(false)) + .tag(AllBlockTags.WINDMILL_SAILS.tag) + .tag(AllBlockTags.FAN_TRANSPARENT.tag) + .simpleItem() + .register(); public static final BlockEntry SAIL = REGISTRATE.block("white_sail", p -> SailBlock.withCanvas(p)) - .initialProperties(SharedProperties::wooden) - .properties(AbstractBlock.Properties::noOcclusion) - .blockstate(BlockStateGen.directionalBlockProvider(false)) - .tag(AllBlockTags.WINDMILL_SAILS.tag) - .simpleItem() - .register(); + .initialProperties(SharedProperties::wooden) + .properties(AbstractBlock.Properties::noOcclusion) + .blockstate(BlockStateGen.directionalBlockProvider(false)) + .tag(AllBlockTags.WINDMILL_SAILS.tag) + .simpleItem() + .register(); public static final DyedBlockList DYED_SAILS = new DyedBlockList<>(colour -> { if (colour == DyeColor.WHITE) { @@ -1026,24 +1031,24 @@ public class AllBlocks { } String colourName = colour.getSerializedName(); return REGISTRATE.block(colourName + "_sail", p -> SailBlock.withCanvas(p)) - .properties(AbstractBlock.Properties::noOcclusion) - .initialProperties(SharedProperties::wooden) - .blockstate((c, p) -> p.directionalBlock(c.get(), p.models() - .withExistingParent(colourName + "_sail", p.modLoc("block/white_sail")) - .texture("0", p.modLoc("block/sail/canvas_" + colourName)))) - .tag(AllBlockTags.WINDMILL_SAILS.tag) - .tag(AllBlockTags.SAILS.tag) - .loot((p, b) -> p.dropOther(b, SAIL.get())) - .register(); + .properties(AbstractBlock.Properties::noOcclusion) + .initialProperties(SharedProperties::wooden) + .blockstate((c, p) -> p.directionalBlock(c.get(), p.models() + .withExistingParent(colourName + "_sail", p.modLoc("block/white_sail")) + .texture("0", p.modLoc("block/sail/canvas_" + colourName)))) + .tag(AllBlockTags.WINDMILL_SAILS.tag) + .tag(AllBlockTags.SAILS.tag) + .loot((p, b) -> p.dropOther(b, SAIL.get())) + .register(); }); public static final BlockEntry ANDESITE_CASING = REGISTRATE.block("andesite_casing", CasingBlock::new) - .transform(BuilderTransformers.casing(AllSpriteShifts.ANDESITE_CASING)) - .register(); + .transform(BuilderTransformers.casing(AllSpriteShifts.ANDESITE_CASING)) + .register(); public static final BlockEntry BRASS_CASING = REGISTRATE.block("brass_casing", CasingBlock::new) - .transform(BuilderTransformers.casing(AllSpriteShifts.BRASS_CASING)) - .register(); + .transform(BuilderTransformers.casing(AllSpriteShifts.BRASS_CASING)) + .register(); public static final BlockEntry COPPER_CASING = REGISTRATE.block("copper_casing", CasingBlock::new) .transform(BuilderTransformers.casing(AllSpriteShifts.COPPER_CASING)) @@ -1301,12 +1306,11 @@ public class AllBlocks { public static final BlockEntry LECTERN_CONTROLLER = REGISTRATE.block("lectern_controller", LecternControllerBlock::new) .initialProperties(() -> Blocks.LECTERN) - .blockstate((c,p) -> p.horizontalBlock(c.get(), p.models() + .blockstate((c, p) -> p.horizontalBlock(c.get(), p.models() .getExistingFile(p.mcLoc("block/lectern")))) .loot((lt, block) -> lt.dropOther(block, Blocks.LECTERN)) .register(); - // Curiosities static { @@ -1346,6 +1350,26 @@ public class AllBlocks { .onRegister(addMovementBehaviour(new HauntedBellMovementBehaviour())) .register(); + public static final BlockEntry TOOLBOX = REGISTRATE.block("toolbox", ToolboxBlock::new) + .blockstate((c, p) -> p.horizontalBlock(c.get(), AssetLookup.partialBaseModel(c, p))) + .initialProperties(SharedProperties::wooden) + .properties(p -> p.sound(SoundType.WOOD)) + .addLayer(() -> RenderType::cutoutMipped) + .loot((lt, block) -> { + Builder builder = LootTable.lootTable(); + IBuilder survivesExplosion = SurvivesExplosion.survivesExplosion(); + lt.add(block, builder.withPool(LootPool.lootPool() + .when(survivesExplosion) + .setRolls(ConstantRange.exactly(1)) + .add(ItemLootEntry.lootTableItem(AllBlocks.TOOLBOX.get()) + .apply(CopyName.copyName(CopyName.Source.BLOCK_ENTITY)) + .apply(CopyNbt.copyData(CopyNbt.Source.BLOCK_ENTITY) + .copy("Inventory", "Inventory"))))); + }) + .item() + .transform(customItemModel()) + .register(); + // Materials static { diff --git a/src/main/java/com/simibubi/create/AllContainerTypes.java b/src/main/java/com/simibubi/create/AllContainerTypes.java index 14d498753..79e5745f3 100644 --- a/src/main/java/com/simibubi/create/AllContainerTypes.java +++ b/src/main/java/com/simibubi/create/AllContainerTypes.java @@ -1,5 +1,7 @@ package com.simibubi.create; +import com.simibubi.create.content.curiosities.toolbox.ToolboxContainer; +import com.simibubi.create.content.curiosities.toolbox.ToolboxScreen; 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; @@ -45,6 +47,9 @@ public class AllContainerTypes { public static final ContainerEntry LINKED_CONTROLLER = register("linked_controller", LinkedControllerContainer::new, () -> LinkedControllerScreen::new); + + public static final ContainerEntry TOOLBOX = + register("toolbox", ToolboxContainer::new, () -> ToolboxScreen::new); private static > ContainerEntry register(String name, ForgeContainerFactory factory, NonNullSupplier> screenFactory) { return Create.registrate().container(name, factory, screenFactory).register(); diff --git a/src/main/java/com/simibubi/create/AllKeys.java b/src/main/java/com/simibubi/create/AllKeys.java index 6253094c1..e323ba47c 100644 --- a/src/main/java/com/simibubi/create/AllKeys.java +++ b/src/main/java/com/simibubi/create/AllKeys.java @@ -11,6 +11,7 @@ public enum AllKeys { TOOL_MENU("toolmenu", GLFW.GLFW_KEY_LEFT_ALT), ACTIVATE_TOOL("", GLFW.GLFW_KEY_LEFT_CONTROL), + TOOLBELT("toolbelt", GLFW.GLFW_KEY_LEFT_ALT), ; diff --git a/src/main/java/com/simibubi/create/AllShapes.java b/src/main/java/com/simibubi/create/AllShapes.java index 9ba3acccd..09bfd18cc 100644 --- a/src/main/java/com/simibubi/create/AllShapes.java +++ b/src/main/java/com/simibubi/create/AllShapes.java @@ -87,6 +87,7 @@ public class AllShapes { .forHorizontal(NORTH), FLUID_VALVE = shape(3, -1, 3, 13, 17, 13).add(2, 2, 2, 14, 14, 14) .forAxis(), + TOOLBOX = shape(1, 0, 4, 15, 9, 12).forHorizontal(NORTH), SMART_FLUID_PIPE_FLOOR = shape(4, 4, 0, 12, 12, 16).add(3, 3, 3, 13, 13, 13) .add(5, 13, 3, 11, 14, 11) .add(5, 14, 4, 11, 15, 10) @@ -110,7 +111,8 @@ public class AllShapes { .forDirectional(Direction.UP), CRUSHING_WHEEL_CONTROLLER_COLLISION = shape(0, 0, 0, 16, 13, 16).forDirectional(Direction.DOWN), - BELL_FLOOR = shape(0, 0, 5, 16, 11, 11).add(3, 1, 3, 13, 13, 13).forHorizontal(SOUTH), + BELL_FLOOR = shape(0, 0, 5, 16, 11, 11).add(3, 1, 3, 13, 13, 13) + .forHorizontal(SOUTH), BELL_WALL = shape(5, 5, 8, 11, 11, 16).add(3, 1, 3, 13, 13, 13) .forHorizontal(SOUTH), BELL_DOUBLE_WALL = shape(5, 5, 0, 11, 11, 16).add(3, 1, 3, 13, 13, 13) @@ -258,8 +260,7 @@ public class AllShapes { } public Builder erase(double x1, double y1, double z1, double x2, double y2, double z2) { - this.shape = - VoxelShapes.join(shape, cuboid(x1, y1, z1, x2, y2, z2), IBooleanFunction.ONLY_FIRST); + this.shape = VoxelShapes.join(shape, cuboid(x1, y1, z1, x2, y2, z2), IBooleanFunction.ONLY_FIRST); return this; } diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index b426c3421..1b5c74d5b 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -123,6 +123,8 @@ import com.simibubi.create.content.curiosities.armor.CopperBacktankTileEntity; import com.simibubi.create.content.curiosities.bell.BellRenderer; import com.simibubi.create.content.curiosities.bell.HauntedBellTileEntity; import com.simibubi.create.content.curiosities.bell.PeculiarBellTileEntity; +import com.simibubi.create.content.curiosities.toolbox.ToolboxRenderer; +import com.simibubi.create.content.curiosities.toolbox.ToolboxTileEntity; import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelInstance; import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelRenderer; import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelTileEntity; @@ -690,6 +692,12 @@ public class AllTileEntities { .validBlocks(AllBlocks.HAUNTED_BELL) .renderer(() -> BellRenderer::new) .register(); + + public static final TileEntityEntry TOOLBOX = Create.registrate() + .tileEntity("toolbox", ToolboxTileEntity::new) + .validBlocks(AllBlocks.TOOLBOX) + .renderer(() -> ToolboxRenderer::new) + .register(); public static void register() {} } diff --git a/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java b/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java index 2cf7dcf90..9ab838d65 100644 --- a/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java +++ b/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java @@ -40,6 +40,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.toolbox.ToolboxScreen; import com.simibubi.create.content.curiosities.tools.BlueprintScreen; import com.simibubi.create.content.logistics.block.inventories.AdjustableCrateScreen; import com.simibubi.create.content.logistics.item.LinkedControllerScreen; @@ -254,6 +255,7 @@ public class CreateJEI implements IModPlugin { registration.addGuiContainerHandler(AttributeFilterScreen.class, slotMover); registration.addGuiContainerHandler(BlueprintScreen.class, slotMover); registration.addGuiContainerHandler(LinkedControllerScreen.class, slotMover); + registration.addGuiContainerHandler(ToolboxScreen.class, slotMover); registration.addGhostIngredientHandler(AbstractFilterScreen.class, new GhostIngredientHandler()); registration.addGhostIngredientHandler(BlueprintScreen.class, new GhostIngredientHandler()); diff --git a/src/main/java/com/simibubi/create/content/curiosities/toolbox/ItemReturnInvWrapper.java b/src/main/java/com/simibubi/create/content/curiosities/toolbox/ItemReturnInvWrapper.java new file mode 100644 index 000000000..3b4f24dc3 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/toolbox/ItemReturnInvWrapper.java @@ -0,0 +1,23 @@ +package com.simibubi.create.content.curiosities.toolbox; + +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraftforge.items.wrapper.InvWrapper; + +/** + * For inserting items into a players' inventory anywhere except the hotbar + */ +public class ItemReturnInvWrapper extends InvWrapper { + + public ItemReturnInvWrapper(IInventory inv) { + super(inv); + } + + @Override + public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { + if (slot >= 0 && slot < 9) + return stack; + return super.insertItem(slot, stack, simulate); + } + +} diff --git a/src/main/java/com/simibubi/create/content/curiosities/toolbox/RadialToolboxMenu.java b/src/main/java/com/simibubi/create/content/curiosities/toolbox/RadialToolboxMenu.java new file mode 100644 index 000000000..d0156fbd7 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/toolbox/RadialToolboxMenu.java @@ -0,0 +1,257 @@ +package com.simibubi.create.content.curiosities.toolbox; + +import java.util.List; + +import com.jozufozu.flywheel.util.transform.MatrixTransformStack; +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllKeys; +import com.simibubi.create.foundation.gui.AbstractSimiScreen; +import com.simibubi.create.foundation.gui.AllGuiTextures; +import com.simibubi.create.foundation.gui.AllIcons; +import com.simibubi.create.foundation.gui.GuiGameElement; +import com.simibubi.create.foundation.networking.AllPackets; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.utility.Lang; + +import net.minecraft.client.MainWindow; +import net.minecraft.client.Minecraft; +import net.minecraft.client.util.InputMappings; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextFormatting; + +public class RadialToolboxMenu extends AbstractSimiScreen { + + public static enum State { + SELECT_BOX, SELECT_ITEM, SELECT_ITEM_UNEQUIP, DETACH + } + + private State state; + private int ticksOpen; + private int hoveredSlot; + + private List toolboxes; + private ToolboxTileEntity selectedBox; + final int UNEQUIP = -5; + + public RadialToolboxMenu(List toolboxes, State state) { + this.toolboxes = toolboxes; + this.state = state; + hoveredSlot = -1; + + if (state == State.SELECT_ITEM_UNEQUIP || state == State.SELECT_ITEM) + selectedBox = toolboxes.get(0); + } + + @Override + protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { + float fade = MathHelper.clamp((ticksOpen + AnimationTickHolder.getPartialTicks()) / 10f, 1 / 512f, 1); + + hoveredSlot = -1; + MainWindow window = getMinecraft().getWindow(); + float hoveredX = mouseX - window.getGuiScaledWidth() / 2; + float hoveredY = mouseY - window.getGuiScaledHeight() / 2; + + float distance = hoveredX * hoveredX + hoveredY * hoveredY; + if (distance > 25 && distance < 20000) + hoveredSlot = + (MathHelper.floor((AngleHelper.deg(MathHelper.atan2(hoveredY, hoveredX)) + 360 + 180 - 22.5f)) % 360) + / 45; + boolean renderCenterSlot = state == State.SELECT_ITEM_UNEQUIP; + if (renderCenterSlot && distance <= 150) + hoveredSlot = UNEQUIP; + + ms.pushPose(); + ms.translate(width / 2, height / 2, 0); + ITextComponent tip = null; + + if (state == State.DETACH) { + + tip = Lang.translate("toolbox.outOfRange"); + if (hoveredX > -20 && hoveredX < 20 && hoveredY > -80 && hoveredY < -20) + hoveredSlot = UNEQUIP; + + ms.pushPose(); + AllGuiTextures.TOOLBELT_INACTIVE_SLOT.draw(ms, this, -12, -12); + GuiGameElement.of(AllBlocks.TOOLBOX.asStack()) + .at(-9, -9) + .render(ms); + + ms.translate(0, -40 + (10 * (1 - fade) * (1 - fade)), 0); + AllGuiTextures.TOOLBELT_SLOT.draw(ms, this, -12, -12); + ms.translate(-0.5, 0.5, 0); + AllIcons.I_DISABLE.draw(ms, this, -9, -9); + ms.translate(0.5, -0.5, 0); + if (hoveredSlot == UNEQUIP) { + AllGuiTextures.TOOLBELT_SLOT_HIGHLIGHT.draw(ms, this, -13, -13); + tip = Lang.translate("toolbox.detach") + .withStyle(TextFormatting.GOLD); + } + ms.popPose(); + + } else { + for (int slot = 0; slot < 8; slot++) { + ms.pushPose(); + MatrixTransformStack.of(ms) + .rotateZ(slot * 45 - 45) + .translate(0, -40 + (10 * (1 - fade) * (1 - fade)), 0) + .rotateZ(-slot * 45 + 45); + ms.translate(-12, -12, 0); + + if (state == State.SELECT_ITEM || state == State.SELECT_ITEM_UNEQUIP) { + ToolboxInventory inv = selectedBox.inventory; + ItemStack stackInSlot = inv.filters.get(slot); + + if (!stackInSlot.isEmpty()) { + boolean empty = inv.getStackInSlot(slot * ToolboxInventory.STACKS_PER_COMPARTMENT) + .isEmpty(); + + (empty ? AllGuiTextures.TOOLBELT_INACTIVE_SLOT : AllGuiTextures.TOOLBELT_SLOT).draw(ms, this, 0, + 0); + GuiGameElement.of(stackInSlot) + .at(3, 3) + .render(ms); + + if (slot == hoveredSlot && !empty) { + AllGuiTextures.TOOLBELT_SLOT_HIGHLIGHT.draw(ms, this, -1, -1); + tip = stackInSlot.getHoverName(); + } + } else + AllGuiTextures.TOOLBELT_EMPTY_SLOT.draw(ms, this, 0, 0); + + } else if (state == State.SELECT_BOX) { + + if (slot < toolboxes.size()) { + AllGuiTextures.TOOLBELT_SLOT.draw(ms, this, 0, 0); + GuiGameElement.of(AllBlocks.TOOLBOX.asStack()) + .at(3, 3) + .render(ms); + + if (slot == hoveredSlot) { + AllGuiTextures.TOOLBELT_SLOT_HIGHLIGHT.draw(ms, this, -1, -1); + tip = toolboxes.get(slot) + .getDisplayName(); + } + } else + AllGuiTextures.TOOLBELT_EMPTY_SLOT.draw(ms, this, 0, 0); + + } + + ms.popPose(); + } + + if (renderCenterSlot) { + ms.pushPose(); + AllGuiTextures.TOOLBELT_SLOT.draw(ms, this, -12, -12); + AllIcons.I_TRASH.draw(ms, this, -9, -9); + if (UNEQUIP == hoveredSlot) { + AllGuiTextures.TOOLBELT_SLOT_HIGHLIGHT.draw(ms, this, -13, -13); + tip = Lang.translate("toolbox.unequip", minecraft.player.getMainHandItem() + .getHoverName()) + .withStyle(TextFormatting.GOLD); + } + ms.popPose(); + } + } + ms.popPose(); + + if (tip != null) { + int i1 = (int) (fade * 255.0F); + if (i1 > 255) + i1 = 255; + + if (i1 > 8) { + ms.pushPose(); + ms.translate((float) (width / 2), (float) (height - 68), 0.0F); + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + int k1 = 16777215; + int k = i1 << 24 & -16777216; + int l = font.width(tip); +// this.drawBackdrop(ms, font, -4, l, 16777215 | k); + font.draw(ms, tip, (float) (-l / 2), -4.0F, k1 | k); + RenderSystem.disableBlend(); + ms.popPose(); + } + } + + } + + @Override + public void renderBackground(MatrixStack p_238651_1_, int p_238651_2_) { + int a = ((int) (0x50 * Math.min(1, (ticksOpen + AnimationTickHolder.getPartialTicks()) / 20f))) << 24; + fillGradient(p_238651_1_, 0, 0, this.width, this.height, 0x101010 | a, 0x101010 | a); + } + + @Override + public void tick() { + ticksOpen++; + super.tick(); + } + + @Override + public void removed() { + super.removed(); + + if (state == State.SELECT_BOX) + return; + + if (state == State.DETACH) { + if (hoveredSlot == UNEQUIP) + AllPackets.channel.sendToServer( + new ToolboxEquipPacket(null, hoveredSlot, Minecraft.getInstance().player.inventory.selected)); + return; + } + + if (hoveredSlot == UNEQUIP) + AllPackets.channel.sendToServer(new ToolboxEquipPacket(selectedBox.getBlockPos(), hoveredSlot, + Minecraft.getInstance().player.inventory.selected)); + + if (hoveredSlot < 0) + return; + ToolboxInventory inv = selectedBox.inventory; + ItemStack stackInSlot = inv.filters.get(hoveredSlot); + if (stackInSlot.isEmpty()) + return; + if (inv.getStackInSlot(hoveredSlot * ToolboxInventory.STACKS_PER_COMPARTMENT) + .isEmpty()) + return; + + AllPackets.channel.sendToServer(new ToolboxEquipPacket(selectedBox.getBlockPos(), hoveredSlot, + Minecraft.getInstance().player.inventory.selected)); + } + + @Override + public boolean mouseClicked(double x, double y, int button) { + if (state == State.SELECT_BOX && hoveredSlot >= 0 && hoveredSlot < toolboxes.size()) { + state = State.SELECT_ITEM; + selectedBox = toolboxes.get(hoveredSlot); + return true; + } + + if (state == State.SELECT_ITEM || state == State.SELECT_ITEM_UNEQUIP) { + if (hoveredSlot == UNEQUIP || hoveredSlot >= 0) { + onClose(); + ToolboxHandlerClient.COOLDOWN = 10; + } + } + + return super.mouseClicked(x, y, button); + } + + @Override + public boolean keyReleased(int code, int p_keyPressed_2_, int p_keyPressed_3_) { + InputMappings.Input mouseKey = InputMappings.getKey(code, p_keyPressed_2_); + if (AllKeys.TOOLBELT.getKeybind() + .isActiveAndMatches(mouseKey)) { + this.onClose(); + return true; + } + return super.keyReleased(code, p_keyPressed_2_, p_keyPressed_3_); + } + +} \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxBlock.java b/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxBlock.java new file mode 100644 index 000000000..c56351184 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxBlock.java @@ -0,0 +1,137 @@ +package com.simibubi.create.content.curiosities.toolbox; + +import static net.minecraft.state.properties.BlockStateProperties.WATERLOGGED; + +import com.simibubi.create.AllShapes; +import com.simibubi.create.AllTileEntities; +import com.simibubi.create.foundation.block.ITE; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.HorizontalBlock; +import net.minecraft.block.IWaterLoggable; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.fluid.FluidState; +import net.minecraft.fluid.Fluids; +import net.minecraft.item.BlockItemUseContext; +import net.minecraft.item.ItemStack; +import net.minecraft.state.StateContainer.Builder; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Direction; +import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.shapes.ISelectionContext; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.world.IBlockReader; +import net.minecraft.world.IWorld; +import net.minecraft.world.World; +import net.minecraft.world.server.ServerWorld; +import net.minecraftforge.common.util.FakePlayer; +import net.minecraftforge.fml.network.NetworkHooks; + +public class ToolboxBlock extends HorizontalBlock implements IWaterLoggable, ITE { + + public ToolboxBlock(Properties p_i48377_1_) { + super(p_i48377_1_); + registerDefaultState(super.defaultBlockState().setValue(WATERLOGGED, false)); + } + + @Override + public FluidState getFluidState(BlockState state) { + return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : Fluids.EMPTY.defaultFluidState(); + } + + @Override + protected void createBlockStateDefinition(Builder builder) { + super.createBlockStateDefinition(builder.add(WATERLOGGED) + .add(FACING)); + } + + @Override + public void setPlacedBy(World worldIn, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) { + super.setPlacedBy(worldIn, pos, state, placer, stack); + if (worldIn.isClientSide) + return; + if (stack == null) + return; + withTileEntityDo(worldIn, pos, te -> { + te.readInventory(stack.getOrCreateTag() + .getCompound("Inventory")); + if (stack.hasCustomHoverName()) + te.setCustomName(stack.getHoverName()); + }); + } + + @Override + public void attack(BlockState state, World world, BlockPos pos, PlayerEntity player) { + if (player instanceof FakePlayer) + return; + if (world.isClientSide) + return; + if (world instanceof ServerWorld) { + for (ItemStack itemStack : Block.getDrops(state, (ServerWorld) world, pos, world.getBlockEntity(pos))) + player.inventory.placeItemBackInInventory(world, itemStack); + world.destroyBlock(pos, false); + } + } + + @Override + public BlockState updateShape(BlockState state, Direction direction, BlockState neighbourState, IWorld world, + BlockPos pos, BlockPos neighbourPos) { + if (state.getValue(WATERLOGGED)) + world.getLiquidTicks() + .scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); + return state; + } + + @Override + public VoxelShape getShape(BlockState state, IBlockReader p_220053_2_, BlockPos p_220053_3_, + ISelectionContext p_220053_4_) { + return AllShapes.TOOLBOX.get(state.getValue(FACING)); + } + + @Override + public boolean hasTileEntity(BlockState state) { + return true; + } + + @Override + public ActionResultType use(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, + BlockRayTraceResult ray) { + + if (player == null || player.isCrouching()) + return ActionResultType.PASS; + if (player instanceof FakePlayer) + return ActionResultType.PASS; + if (world.isClientSide) + return ActionResultType.SUCCESS; + + withTileEntityDo(world, pos, + toolbox -> NetworkHooks.openGui((ServerPlayerEntity) player, toolbox, toolbox::sendToContainer)); + return ActionResultType.SUCCESS; + } + + @Override + public TileEntity createTileEntity(BlockState state, IBlockReader world) { + return AllTileEntities.TOOLBOX.create(); + } + + @Override + public BlockState getStateForPlacement(BlockItemUseContext context) { + FluidState ifluidstate = context.getLevel() + .getFluidState(context.getClickedPos()); + return super.getStateForPlacement(context).setValue(FACING, context.getHorizontalDirection() + .getOpposite()) + .setValue(WATERLOGGED, Boolean.valueOf(ifluidstate.getType() == Fluids.WATER)); + } + + @Override + public Class getTileEntityClass() { + return ToolboxTileEntity.class; + } + +} diff --git a/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxContainer.java b/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxContainer.java new file mode 100644 index 000000000..c97fe1fad --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxContainer.java @@ -0,0 +1,162 @@ +package com.simibubi.create.content.curiosities.toolbox; + +import static com.simibubi.create.content.curiosities.toolbox.ToolboxInventory.STACKS_PER_COMPARTMENT; + +import com.simibubi.create.AllContainerTypes; +import com.simibubi.create.foundation.gui.ContainerBase; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.container.ClickType; +import net.minecraft.inventory.container.ContainerType; +import net.minecraft.inventory.container.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraftforge.items.ItemHandlerHelper; +import net.minecraftforge.items.SlotItemHandler; + +public class ToolboxContainer extends ContainerBase { + + public static ToolboxContainer create(int id, PlayerInventory inv, ToolboxTileEntity te) { + return new ToolboxContainer(AllContainerTypes.TOOLBOX.get(), id, inv, te); + } + + public ToolboxContainer(ContainerType type, int id, PlayerInventory inv, PacketBuffer extraData) { + super(type, id, inv, extraData); + } + + public ToolboxContainer(ContainerType type, int id, PlayerInventory inv, ToolboxTileEntity te) { + super(type, id, inv, te); + te.startOpen(player); + } + + @Override + protected ToolboxTileEntity createOnClient(PacketBuffer extraData) { + BlockPos readBlockPos = extraData.readBlockPos(); + CompoundNBT readNbt = extraData.readNbt(); + + ClientWorld world = Minecraft.getInstance().level; + TileEntity tileEntity = world.getBlockEntity(readBlockPos); + if (tileEntity instanceof ToolboxTileEntity) { + ToolboxTileEntity toolbox = (ToolboxTileEntity) tileEntity; + toolbox.handleUpdateTag(toolbox.getBlockState(), readNbt); + return toolbox; + } + + return null; + } + + @Override + public ItemStack quickMoveStack(PlayerEntity player, int index) { + Slot clickedSlot = getSlot(index); + if (!clickedSlot.hasItem()) + return ItemStack.EMPTY; + + ItemStack stack = clickedSlot.getItem(); + int size = contentHolder.inventory.getSlots(); + if (index < size) { + moveItemStackTo(stack, size, slots.size(), false); + contentHolder.inventory.onContentsChanged(index); + } else + moveItemStackTo(stack, 0, size - 1, false); + + return ItemStack.EMPTY; + } + + @Override + protected void initAndReadInventory(ToolboxTileEntity contentHolder) { + + } + + @Override + public ItemStack clicked(int index, int flags, ClickType type, PlayerEntity player) { + int size = contentHolder.inventory.getSlots(); + + if (index >= 0 && index < size) { + + ItemStack itemInClickedSlot = getSlot(index).getItem(); + PlayerInventory playerInv = player.inventory; + ItemStack carried = playerInv.getCarried(); + + if (type == ClickType.PICKUP && !carried.isEmpty() && !itemInClickedSlot.isEmpty() + && ItemHandlerHelper.canItemStacksStack(itemInClickedSlot, carried)) { + int subIndex = index % STACKS_PER_COMPARTMENT; + if (subIndex != STACKS_PER_COMPARTMENT - 1) + return clicked(index - subIndex + STACKS_PER_COMPARTMENT - 1, flags, type, player); + } + + if (type == ClickType.PICKUP && !carried.isEmpty() && itemInClickedSlot.isEmpty()) + contentHolder.inventory.filters.set(index / STACKS_PER_COMPARTMENT, carried); + + if (type == ClickType.PICKUP && carried.isEmpty() && itemInClickedSlot.isEmpty()) + if (!player.level.isClientSide) { + contentHolder.inventory.filters.set(index / STACKS_PER_COMPARTMENT, ItemStack.EMPTY); + contentHolder.sendData(); + } + + } + return super.clicked(index, flags, type, player); + } + + @Override + public boolean canDragTo(Slot slot) { + return slot.index > contentHolder.inventory.getSlots() && super.canDragTo(slot); + } + + public ItemStack getFilter(int compartment) { + return contentHolder.inventory.filters.get(compartment); + } + + public int totalCountInCompartment(int compartment) { + int count = 0; + int baseSlot = compartment * STACKS_PER_COMPARTMENT; + for (int i = 0; i < STACKS_PER_COMPARTMENT; i++) + count += getSlot(baseSlot + i).getItem() + .getCount(); + return count; + } + + public boolean renderPass; + + @Override + protected void addSlots() { + ToolboxInventory inventory = contentHolder.inventory; + + int x = 59; + int y = 37; + + int[] xOffsets = { x, x + 33, x + 66, x + 66 + 6, x + 66, x + 33, x, x - 6 }; + int[] yOffsets = { y, y - 6, y, y + 33, y + 66, y + 66 + 6, y + 66, y + 33 }; + + for (int compartment = 0; compartment < 8; compartment++) { + int baseIndex = compartment * STACKS_PER_COMPARTMENT; + + // Representative Slots + addSlot(new ToolboxSlot(this, inventory, baseIndex, xOffsets[compartment], yOffsets[compartment])); + + // Hidden Slots + for (int i = 1; i < STACKS_PER_COMPARTMENT; i++) + addSlot(new SlotItemHandler(inventory, baseIndex + i, -100, -100)); + } + + addPlayerSlots(-12, 166); + } + + @Override + protected void saveData(ToolboxTileEntity contentHolder) { + + } + + @Override + public void removed(PlayerEntity playerIn) { + super.removed(playerIn); + if (!playerIn.level.isClientSide) + contentHolder.stopOpen(playerIn); + } + +} diff --git a/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxEquipPacket.java b/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxEquipPacket.java new file mode 100644 index 000000000..078d23ff8 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxEquipPacket.java @@ -0,0 +1,117 @@ +package com.simibubi.create.content.curiosities.toolbox; + +import java.util.function.Supplier; + +import com.simibubi.create.foundation.networking.AllPackets; +import com.simibubi.create.foundation.networking.ISyncPersistentData; +import com.simibubi.create.foundation.networking.SimplePacketBase; + +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.NBTUtil; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import net.minecraftforge.fml.network.NetworkEvent.Context; +import net.minecraftforge.fml.network.PacketDistributor; +import net.minecraftforge.items.ItemHandlerHelper; + +public class ToolboxEquipPacket extends SimplePacketBase { + + private BlockPos toolboxPos; + private int slot; + private int hotbarSlot; + + public ToolboxEquipPacket(BlockPos toolboxPos, int slot, int hotbarSlot) { + this.toolboxPos = toolboxPos; + this.slot = slot; + this.hotbarSlot = hotbarSlot; + } + + public ToolboxEquipPacket(PacketBuffer buffer) { + if (buffer.readBoolean()) + toolboxPos = buffer.readBlockPos(); + slot = buffer.readVarInt(); + hotbarSlot = buffer.readVarInt(); + } + + @Override + public void write(PacketBuffer buffer) { + buffer.writeBoolean(toolboxPos != null); + if (toolboxPos != null) + buffer.writeBlockPos(toolboxPos); + buffer.writeVarInt(slot); + buffer.writeVarInt(hotbarSlot); + } + + @Override + public void handle(Supplier context) { + Context ctx = context.get(); + ctx.enqueueWork(() -> { + ServerPlayerEntity player = ctx.getSender(); + World world = player.level; + + if (toolboxPos == null) { + player.getPersistentData() + .getCompound("CreateToolboxData") + .remove(String.valueOf(hotbarSlot)); + sendData(player); + return; + } + + TileEntity blockEntity = world.getBlockEntity(toolboxPos); + + double maxRange = ToolboxHandler.getMaxRange(player); + if (ctx.getSender() + .distanceToSqr(toolboxPos.getX() + 0.5, toolboxPos.getY(), + toolboxPos.getZ() + 0.5) > maxRange * maxRange) + return; + if (!(blockEntity instanceof ToolboxTileEntity)) + return; + + ToolboxHandler.unequip(player, hotbarSlot); + + if (slot < 0 || slot >= 8) { + sendData(player); + return; + } + + ToolboxTileEntity toolboxTileEntity = (ToolboxTileEntity) blockEntity; + + ItemStack playerStack = player.inventory.getItem(hotbarSlot); + if (!playerStack.isEmpty() + && !ItemHandlerHelper.canItemStacksStack(playerStack, toolboxTileEntity.inventory.filters.get(slot))) { + ItemStack remainder = + ItemHandlerHelper.insertItemStacked(toolboxTileEntity.inventory, playerStack, false); + if (!remainder.isEmpty()) + remainder = ItemHandlerHelper.insertItemStacked(new ItemReturnInvWrapper(player.inventory), + remainder, false); + if (remainder.getCount() != playerStack.getCount()) + player.inventory.setItem(hotbarSlot, remainder); + } + + CompoundNBT compound = player.getPersistentData() + .getCompound("CreateToolboxData"); + String key = String.valueOf(hotbarSlot); + + CompoundNBT data = new CompoundNBT(); + data.putInt("Slot", slot); + data.put("Pos", NBTUtil.writeBlockPos(toolboxPos)); + compound.put(key, data); + + player.getPersistentData() + .put("CreateToolboxData", compound); + sendData(player); + + toolboxTileEntity.connectPlayer(slot, player, hotbarSlot); + }); + ctx.setPacketHandled(true); + } + + private void sendData(ServerPlayerEntity player) { + AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> player), new ISyncPersistentData.Packet(player)); + } + +} diff --git a/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxHandler.java b/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxHandler.java new file mode 100644 index 000000000..9daef8f34 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxHandler.java @@ -0,0 +1,79 @@ +package com.simibubi.create.content.curiosities.toolbox; + +import java.util.List; +import java.util.WeakHashMap; +import java.util.stream.Collectors; + +import com.simibubi.create.foundation.utility.WorldAttached; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.NBTUtil; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.world.IWorld; +import net.minecraft.world.World; + +public class ToolboxHandler { + + public static final WorldAttached> toolboxes = + new WorldAttached<>(w -> new WeakHashMap<>()); + + public static void onLoad(ToolboxTileEntity te) { + toolboxes.get(te.getLevel()) + .put(te.getBlockPos(), te); + } + + public static void onUnload(ToolboxTileEntity te) { + toolboxes.get(te.getLevel()) + .remove(te.getBlockPos()); + } + + public static List getNearest(IWorld world, PlayerEntity player, int maxAmount) { + Vector3d location = player.position(); + double maxRange = getMaxRange(player); + return toolboxes.get(world) + .keySet() + .stream() + .filter(p -> distance(location, p) < maxRange * maxRange) + .sorted((p1, p2) -> Double.compare(distance(location, p1), distance(location, p2))) + .limit(maxAmount) + .map(toolboxes.get(world)::get) + .collect(Collectors.toList()); + } + + public static void unequip(PlayerEntity player, int hotbarSlot) { + CompoundNBT compound = player.getPersistentData() + .getCompound("CreateToolboxData"); + World world = player.level; + String key = String.valueOf(hotbarSlot); + if (!compound.contains(key)) + return; + + CompoundNBT prevData = compound.getCompound(key); + BlockPos prevPos = NBTUtil.readBlockPos(prevData.getCompound("Pos")); + int prevSlot = prevData.getInt("Slot"); + + TileEntity prevBlockEntity = world.getBlockEntity(prevPos); + if (prevBlockEntity instanceof ToolboxTileEntity) + ((ToolboxTileEntity) prevBlockEntity).unequip(prevSlot, player, hotbarSlot); + compound.remove(key); + } + + public static boolean withinRange(PlayerEntity player, ToolboxTileEntity box) { + if (player.level != box.getLevel()) + return false; + double maxRange = getMaxRange(player); + return distance(player.position(), box.getBlockPos()) < maxRange * maxRange; + } + + public static double distance(Vector3d location, BlockPos p) { + return location.distanceToSqr(p.getX() + 0.5f, p.getY(), p.getZ() + 0.5f); + } + + public static double getMaxRange(PlayerEntity player) { + return 10; + } + +} diff --git a/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxHandlerClient.java b/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxHandlerClient.java new file mode 100644 index 000000000..7ac4b05d9 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxHandlerClient.java @@ -0,0 +1,123 @@ +package com.simibubi.create.content.curiosities.toolbox; + +import static com.simibubi.create.foundation.gui.AllGuiTextures.TOOLBELT_HOTBAR_OFF; +import static com.simibubi.create.foundation.gui.AllGuiTextures.TOOLBELT_HOTBAR_ON; +import static com.simibubi.create.foundation.gui.AllGuiTextures.TOOLBELT_SELECTED_OFF; +import static com.simibubi.create.foundation.gui.AllGuiTextures.TOOLBELT_SELECTED_ON; + +import java.util.List; + +import com.google.common.collect.ImmutableList; +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; +import com.simibubi.create.AllKeys; +import com.simibubi.create.foundation.gui.AllGuiTextures; +import com.simibubi.create.foundation.gui.ScreenOpener; + +import net.minecraft.client.MainWindow; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.player.ClientPlayerEntity; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.NBTUtil; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +public class ToolboxHandlerClient { + + static int COOLDOWN = 0; + + public static void clientTick() { + if (COOLDOWN > 0 && !AllKeys.TOOLBELT.isPressed()) + COOLDOWN--; + } + + public static void onKeyInput(int key, boolean pressed) { + if (key != AllKeys.TOOLBELT.getBoundCode()) + return; + if (COOLDOWN > 0) + return; + ClientPlayerEntity player = Minecraft.getInstance().player; + if (player == null) + return; + World level = player.level; + + List toolboxes = ToolboxHandler.getNearest(player.level, player, 8); + CompoundNBT compound = player.getPersistentData() + .getCompound("CreateToolboxData"); + + String slotKey = String.valueOf(player.inventory.selected); + boolean equipped = compound.contains(slotKey); + + if (equipped) { + BlockPos pos = NBTUtil.readBlockPos(compound.getCompound(slotKey) + .getCompound("Pos")); + double max = ToolboxHandler.getMaxRange(player); + boolean canReachToolbox = ToolboxHandler.distance(player.position(), pos) < max * max; + + if (canReachToolbox) { + TileEntity blockEntity = level.getBlockEntity(pos); + if (blockEntity instanceof ToolboxTileEntity) { + ScreenOpener.open(new RadialToolboxMenu(ImmutableList.of((ToolboxTileEntity) blockEntity), + RadialToolboxMenu.State.SELECT_ITEM_UNEQUIP)); + return; + } + } + + ScreenOpener.open(new RadialToolboxMenu(ImmutableList.of(), RadialToolboxMenu.State.DETACH)); + return; + } + + if (toolboxes.isEmpty()) + return; + +// ItemStack itemStackFromSlot = player.getItemStackFromSlot(EquipmentSlotType.LEGS); +// if (!AllItems.TOOLBELT.isIn(itemStackFromSlot)) +// return; + + if (toolboxes.size() == 1) + ScreenOpener.open(new RadialToolboxMenu(toolboxes, RadialToolboxMenu.State.SELECT_ITEM)); + else + ScreenOpener.open(new RadialToolboxMenu(toolboxes, RadialToolboxMenu.State.SELECT_BOX)); + } + + public static void renderOverlay(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay, + float partialTicks) { + MainWindow mainWindow = Minecraft.getInstance() + .getWindow(); + int x = mainWindow.getGuiScaledWidth() / 2 - 90; + int y = mainWindow.getGuiScaledHeight() - 23; + RenderSystem.enableDepthTest(); + + PlayerEntity player = Minecraft.getInstance().player; + CompoundNBT persistentData = player.getPersistentData(); + if (!persistentData.contains("CreateToolboxData")) + return; + + CompoundNBT compound = player.getPersistentData() + .getCompound("CreateToolboxData"); + + if (compound.isEmpty()) + return; + + ms.pushPose(); + for (int slot = 0; slot < 9; slot++) { + String key = String.valueOf(slot); + if (!compound.contains(key)) + continue; + BlockPos pos = NBTUtil.readBlockPos(compound.getCompound(key) + .getCompound("Pos")); + double max = ToolboxHandler.getMaxRange(player); + boolean selected = player.inventory.selected == slot; + int offset = selected ? 1 : 0; + AllGuiTextures texture = ToolboxHandler.distance(player.position(), pos) < max * max + ? selected ? TOOLBELT_SELECTED_ON : TOOLBELT_HOTBAR_ON + : selected ? TOOLBELT_SELECTED_OFF : TOOLBELT_HOTBAR_OFF; + texture.draw(ms, x + 20 * slot - offset, y + offset); + } + ms.popPose(); + } + +} diff --git a/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxInventory.java b/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxInventory.java new file mode 100644 index 000000000..741c77eb1 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxInventory.java @@ -0,0 +1,145 @@ +package com.simibubi.create.content.curiosities.toolbox; + +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.Nonnull; + +import com.simibubi.create.foundation.utility.NBTHelper; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import net.minecraftforge.common.util.Constants.NBT; +import net.minecraftforge.items.ItemHandlerHelper; +import net.minecraftforge.items.ItemStackHandler; + +public class ToolboxInventory extends ItemStackHandler { + + public static final int STACKS_PER_COMPARTMENT = 4; + List filters; + boolean settling; + private ToolboxTileEntity te; + + public ToolboxInventory(ToolboxTileEntity te) { + super(8 * STACKS_PER_COMPARTMENT); + this.te = te; + filters = new ArrayList<>(); + settling = false; + for (int i = 0; i < 8; i++) + filters.add(ItemStack.EMPTY); + } + + public void settle(int compartment) { + int totalCount = 0; + boolean valid = true; + boolean shouldBeEmpty = false; + ItemStack sample = ItemStack.EMPTY; + + for (int i = 0; i < STACKS_PER_COMPARTMENT; i++) { + ItemStack stackInSlot = getStackInSlot(compartment * STACKS_PER_COMPARTMENT + i); + totalCount += stackInSlot.getCount(); + if (!shouldBeEmpty) + shouldBeEmpty = stackInSlot.isEmpty() || stackInSlot.getCount() != stackInSlot.getMaxStackSize(); + else if (!stackInSlot.isEmpty()) { + valid = false; + sample = stackInSlot; + } + } + + if (valid) + return; + + settling = true; + for (int i = 0; i < STACKS_PER_COMPARTMENT; i++) { + ItemStack copy = totalCount <= 0 ? ItemStack.EMPTY + : ItemHandlerHelper.copyStackWithSize(sample, Math.min(totalCount, sample.getMaxStackSize())); + setStackInSlot(compartment * STACKS_PER_COMPARTMENT + i, copy); + totalCount -= copy.getCount(); + } + settling = false; + te.sendData(); + } + + @Override + public boolean isItemValid(int slot, ItemStack stack) { + if (slot < 0 || slot >= getSlots()) + return false; + int compartment = slot / STACKS_PER_COMPARTMENT; + ItemStack filter = filters.get(compartment); + if (!filter.isEmpty() && ItemHandlerHelper.canItemStacksStack(filter, stack)) + return super.isItemValid(slot, stack); + return false; + } + + @Override + public void setStackInSlot(int slot, ItemStack stack) { + super.setStackInSlot(slot, stack); + int compartment = slot / STACKS_PER_COMPARTMENT; + if (!stack.isEmpty() && filters.get(compartment) + .isEmpty()) + filters.set(compartment, ItemHandlerHelper.copyStackWithSize(stack, 1)); + } + + @Override + public CompoundNBT serializeNBT() { + CompoundNBT compound = super.serializeNBT(); + compound.put("Compartments", NBTHelper.writeItemList(filters)); + return compound; + } + + @Override + protected void onContentsChanged(int slot) { + if (!settling && !te.getWorld().isClientSide) + settle(slot / STACKS_PER_COMPARTMENT); + super.onContentsChanged(slot); + } + + @Override + public void deserializeNBT(CompoundNBT nbt) { + filters = NBTHelper.readItemList(nbt.getList("Compartments", NBT.TAG_COMPOUND)); + if (filters.size() != 8) { + filters.clear(); + for (int i = 0; i < 8; i++) + filters.add(ItemStack.EMPTY); + } + super.deserializeNBT(nbt); + } + + public ItemStack distributeToCompartment(@Nonnull ItemStack stack, int compartment, boolean simulate) { + if (stack.isEmpty()) + return stack; + + for (int i = STACKS_PER_COMPARTMENT - 1; i >= 0; i--) { + int slot = compartment * STACKS_PER_COMPARTMENT + i; + stack = insertItem(slot, stack, simulate); + if (stack.isEmpty()) + return ItemStack.EMPTY; + } + + return stack; + } + + public ItemStack takeFromCompartment(int amount, int compartment, boolean simulate) { + if (amount == 0) + return ItemStack.EMPTY; + + int remaining = amount; + ItemStack lastValid = ItemStack.EMPTY; + + for (int i = STACKS_PER_COMPARTMENT - 1; i >= 0; i--) { + int slot = compartment * STACKS_PER_COMPARTMENT + i; + ItemStack extracted = extractItem(slot, amount, simulate); + remaining -= extracted.getCount(); + if (!extracted.isEmpty()) + lastValid = extracted; + if (remaining == 0) + return ItemHandlerHelper.copyStackWithSize(lastValid, amount); + } + + if (remaining == amount) + return ItemStack.EMPTY; + + return ItemHandlerHelper.copyStackWithSize(lastValid, amount - remaining); + } + +} diff --git a/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxRenderer.java b/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxRenderer.java new file mode 100644 index 000000000..bb613206e --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxRenderer.java @@ -0,0 +1,59 @@ +package com.simibubi.create.content.curiosities.toolbox; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.vertex.IVertexBuilder; +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.foundation.render.PartialBufferer; +import com.simibubi.create.foundation.render.SuperByteBuffer; +import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer; +import com.simibubi.create.foundation.utility.Iterate; + +import net.minecraft.block.BlockState; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; +import net.minecraft.util.Direction; + +public class ToolboxRenderer extends SmartTileEntityRenderer { + + public ToolboxRenderer(TileEntityRendererDispatcher dispatcher) { + super(dispatcher); + } + + @Override + protected void renderSafe(ToolboxTileEntity tileEntityIn, float partialTicks, MatrixStack ms, + IRenderTypeBuffer buffer, int light, int overlay) { + + BlockState blockState = tileEntityIn.getBlockState(); + Direction facing = blockState.getValue(ToolboxBlock.FACING) + .getOpposite(); + SuperByteBuffer lid = PartialBufferer.get(AllBlockPartials.TOOLBOX_LID, blockState); + SuperByteBuffer drawer = PartialBufferer.get(AllBlockPartials.TOOLBOX_DRAWER, blockState); + + float lidAngle = tileEntityIn.lid.getValue(partialTicks); + float drawerOffset = tileEntityIn.drawers.getValue(partialTicks); + + IVertexBuilder layer = buffer.getBuffer(RenderType.solid()); + lid.matrixStacker() + .centre() + .rotateY(-facing.toYRot()) + .unCentre() + .translate(0, 6/16f, 12/16f) + .rotateX(135 * lidAngle) + .translate(0, -6/16f, -12/16f); + lid.light(light) + .renderInto(ms, layer); + + for (int offset : Iterate.zeroAndOne) { + drawer.matrixStacker() + .centre() + .rotateY(-facing.toYRot()) + .unCentre(); + drawer.translate(0, offset * 1 / 8f, -drawerOffset * .175f * (2 - offset)) + .light(light) + .renderInto(ms, layer); + } + + } + +} diff --git a/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxScreen.java b/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxScreen.java new file mode 100644 index 000000000..986d043ec --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxScreen.java @@ -0,0 +1,162 @@ +package com.simibubi.create.content.curiosities.toolbox; + +import java.util.Collections; +import java.util.List; + +import com.google.common.collect.ImmutableList; +import com.jozufozu.flywheel.util.transform.MatrixTransformStack; +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.AllBlocks; +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.utility.Iterate; + +import net.minecraft.client.renderer.Rectangle2d; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.container.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.util.text.ITextComponent; + +public class ToolboxScreen extends AbstractSimiContainerScreen { + + AllGuiTextures BG = AllGuiTextures.TOOLBOX; + AllGuiTextures PLAYER = AllGuiTextures.PLAYER_INVENTORY; + protected Slot hoveredToolboxSlot; + private IconButton confirmButton; + + private List extraAreas = Collections.emptyList(); + + public ToolboxScreen(ToolboxContainer container, PlayerInventory inv, ITextComponent title) { + super(container, inv, title); + init(); + } + + @Override + protected void init() { + super.init(); + widgets.clear(); + setWindowSize(BG.width, 256); + confirmButton = new IconButton(getGuiLeft() + BG.width - 23, getGuiTop() + BG.height - 24, AllIcons.I_CONFIRM); + widgets.add(confirmButton); + + extraAreas = ImmutableList.of(new Rectangle2d(118, 155, 80, 100), new Rectangle2d(308, 125, 100, 70)); + } + + @Override + public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { + menu.renderPass = true; + super.render(matrixStack, mouseX, mouseY, partialTicks); + menu.renderPass = false; + } + + @Override + public void setBlitOffset(int p_230926_1_) { + super.setBlitOffset(p_230926_1_); + } + + @Override + protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { + BG.draw(ms, this, leftPos + 10, topPos); + PLAYER.draw(ms, this, leftPos + (BG.width - PLAYER.width) / 2 - 26, topPos + imageHeight - PLAYER.height); + font.draw(ms, title, leftPos + 24, topPos + 4, 0x442000); + font.draw(ms, inventory.getDisplayName(), leftPos - 13, topPos + 154, 0x404040); + + renderToolbox(ms, mouseX, mouseY, partialTicks); + + hoveredToolboxSlot = null; + for (int compartment = 0; compartment < 8; compartment++) { + int baseIndex = compartment * ToolboxInventory.STACKS_PER_COMPARTMENT; + Slot slot = menu.slots.get(baseIndex); + ItemStack itemstack = slot.getItem(); + int i = slot.x + leftPos; + int j = slot.y + topPos; + + if (itemstack.isEmpty()) + itemstack = menu.getFilter(compartment); + + if (!itemstack.isEmpty()) { + int count = menu.totalCountInCompartment(compartment); + String s = count + ""; + setBlitOffset(100); + itemRenderer.blitOffset = 100.0F; + RenderSystem.enableDepthTest(); + itemRenderer.renderAndDecorateItem(minecraft.player, itemstack, i, j); + itemRenderer.renderGuiItemDecorations(font, itemstack, i, j, s); + setBlitOffset(0); + itemRenderer.blitOffset = 0.0F; + } + + if (isHovering(slot.x, slot.y, 16, 16, mouseX, mouseY)) { + hoveredToolboxSlot = slot; + RenderSystem.disableDepthTest(); + RenderSystem.colorMask(true, true, true, false); + int slotColor = this.getSlotColor(baseIndex); + fillGradient(ms, i, j, i + 16, j + 16, slotColor, slotColor); + RenderSystem.colorMask(true, true, true, true); + RenderSystem.enableDepthTest(); + } + } + } + + private void renderToolbox(MatrixStack ms, int mouseX, int mouseY, float partialTicks) { + ms.pushPose(); + ms.translate(397, 190, 100); + MatrixTransformStack.of(ms) + .scale(50) + .rotateX(-22) + .rotateY(-202); + + GuiGameElement.of(AllBlocks.TOOLBOX.getDefaultState()) + .render(ms); + + ms.pushPose(); + MatrixTransformStack.of(ms) + .translate(0, -6 / 16f, 12 / 16f) + .rotateX(-105 * menu.contentHolder.lid.getValue(partialTicks)) + .translate(0, 6 / 16f, -12 / 16f); + GuiGameElement.of(AllBlockPartials.TOOLBOX_LID) + .render(ms); + ms.popPose(); + + for (int offset : Iterate.zeroAndOne) { + ms.pushPose(); + ms.translate(0, -offset * 1 / 8f, menu.contentHolder.drawers.getValue(partialTicks) * -.175f * (2 - offset)); + GuiGameElement.of(AllBlockPartials.TOOLBOX_DRAWER) + .render(ms); + ms.popPose(); + } + ms.popPose(); + } + + @Override + protected void renderWindowForeground(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { + if (hoveredToolboxSlot != null) + hoveredSlot = hoveredToolboxSlot; + super.renderWindowForeground(matrixStack, mouseX, mouseY, partialTicks); + } + + @Override + public boolean mouseClicked(double x, double y, int button) { + boolean mouseClicked = super.mouseClicked(x, y, button); + + if (button == 0) { + if (confirmButton.isHovered()) { + minecraft.player.closeContainer(); + return true; + } + } + + return mouseClicked; + } + + @Override + public List getExtraAreas() { + return extraAreas; + } + +} diff --git a/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxSlot.java b/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxSlot.java new file mode 100644 index 000000000..b14d0573f --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxSlot.java @@ -0,0 +1,20 @@ +package com.simibubi.create.content.curiosities.toolbox; + +import net.minecraftforge.items.IItemHandler; +import net.minecraftforge.items.SlotItemHandler; + +public class ToolboxSlot extends SlotItemHandler { + + private ToolboxContainer toolboxMenu; + + public ToolboxSlot(ToolboxContainer container, IItemHandler itemHandler, int index, int xPosition, int yPosition) { + super(itemHandler, index, xPosition, yPosition); + this.toolboxMenu = container; + } + + @Override + public boolean isActive() { + return !toolboxMenu.renderPass && super.isActive(); + } + +} diff --git a/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxTileEntity.java b/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxTileEntity.java new file mode 100644 index 000000000..91bdd62d9 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/curiosities/toolbox/ToolboxTileEntity.java @@ -0,0 +1,291 @@ +package com.simibubi.create.content.curiosities.toolbox; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.WeakHashMap; + +import com.simibubi.create.foundation.networking.AllPackets; +import com.simibubi.create.foundation.networking.ISyncPersistentData; +import com.simibubi.create.foundation.tileEntity.SmartTileEntity; +import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; +import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.foundation.utility.animation.LerpedFloat; +import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser; + +import net.minecraft.block.BlockState; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.inventory.container.Container; +import net.minecraft.inventory.container.INamedContainerProvider; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; +import net.minecraft.util.INameable; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvents; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TranslationTextComponent; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.fml.network.PacketDistributor; +import net.minecraftforge.items.IItemHandler; +import net.minecraftforge.items.ItemHandlerHelper; + +public class ToolboxTileEntity extends SmartTileEntity implements INamedContainerProvider, INameable { + + public LerpedFloat lid = LerpedFloat.linear() + .startWithValue(0); + + public LerpedFloat drawers = LerpedFloat.linear() + .startWithValue(0); + + ToolboxInventory inventory; + LazyOptional inventoryProvider; + protected int openCount; + + Map> connectedPlayers; + + private ITextComponent customName; + + public ToolboxTileEntity(TileEntityType tileEntityTypeIn) { + super(tileEntityTypeIn); + connectedPlayers = new HashMap<>(); + inventory = new ToolboxInventory(this); + inventoryProvider = LazyOptional.of(() -> inventory); + setLazyTickRate(10); + } + + @Override + public void addBehaviours(List behaviours) {} + + @Override + public void initialize() { + super.initialize(); + ToolboxHandler.onLoad(this); + } + + @Override + public void setRemoved() { + super.setRemoved(); + ToolboxHandler.onUnload(this); + } + + @Override + public void tick() { + super.tick(); + + if (level.isClientSide) + tickAudio(); + if (!level.isClientSide) + tickPlayers(); + + lid.chase(openCount > 0 ? 1 : 0, 0.2f, Chaser.LINEAR); + drawers.chase(openCount > 0 ? 1 : 0, 0.2f, Chaser.EXP); + lid.tickChaser(); + drawers.tickChaser(); + } + + private void tickPlayers() { + for (Iterator>> toolboxSlots = connectedPlayers.entrySet() + .iterator(); toolboxSlots.hasNext();) { + + Entry> toolboxSlotEntry = toolboxSlots.next(); + WeakHashMap set = toolboxSlotEntry.getValue(); + int slot = toolboxSlotEntry.getKey(); + + ItemStack referenceItem = inventory.filters.get(slot); + boolean clear = referenceItem.isEmpty(); + + for (Iterator> playerEntries = set.entrySet() + .iterator(); playerEntries.hasNext();) { + Entry playerEntry = playerEntries.next(); + + PlayerEntity player = playerEntry.getKey(); + int hotbarSlot = playerEntry.getValue(); + + if (!clear && !ToolboxHandler.withinRange(player, this)) + continue; + + ItemStack playerStack = player.inventory.getItem(hotbarSlot); + + if (clear + || !playerStack.isEmpty() && !ItemHandlerHelper.canItemStacksStack(playerStack, referenceItem)) { + player.getPersistentData() + .getCompound("CreateToolboxData") + .remove(String.valueOf(hotbarSlot)); + playerEntries.remove(); + if (player instanceof ServerPlayerEntity) + AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) player), + new ISyncPersistentData.Packet(player)); + continue; + } + + int count = playerStack.getCount(); + int targetAmount = (referenceItem.getMaxStackSize() + 1) / 2; + + if (count < targetAmount) { + int amountToReplenish = targetAmount - count; + ItemStack extracted = inventory.takeFromCompartment(amountToReplenish, slot, false); + if (!extracted.isEmpty()) + player.inventory.setItem(hotbarSlot, + ItemHandlerHelper.copyStackWithSize(extracted, count + extracted.getCount())); + } + + if (count > targetAmount) { + int amountToDeposit = count - targetAmount; + ItemStack toDistribute = ItemHandlerHelper.copyStackWithSize(playerStack, amountToDeposit); + int deposited = amountToDeposit - inventory.distributeToCompartment(toDistribute, slot, false) + .getCount(); + if (deposited > 0) + player.inventory.setItem(hotbarSlot, + ItemHandlerHelper.copyStackWithSize(playerStack, count - deposited)); + } + } + + if (clear) + toolboxSlots.remove(); + } + } + + public void unequip(int slot, PlayerEntity player, int hotbarSlot) { + if (!connectedPlayers.containsKey(slot)) + return; + connectedPlayers.get(slot) + .remove(player); + if (!ToolboxHandler.withinRange(player, this)) + return; + + ItemStack playerStack = player.inventory.getItem(hotbarSlot); + ItemStack remainder = inventory.distributeToCompartment(playerStack, slot, false); + + if (remainder.getCount() != playerStack.getCount()) + player.inventory.setItem(hotbarSlot, remainder); + } + + private void tickAudio() { + Vector3d vec = VecHelper.getCenterOf(worldPosition); + if (lid.settled()) { + if (openCount > 0 && lid.getChaseTarget() == 0) { + level.playLocalSound(vec.x, vec.y, vec.z, SoundEvents.IRON_DOOR_OPEN, SoundCategory.BLOCKS, 0.25F, + level.random.nextFloat() * 0.1F + 1.2F, true); + level.playLocalSound(vec.x, vec.y, vec.z, SoundEvents.CHEST_OPEN, SoundCategory.BLOCKS, 0.1F, + level.random.nextFloat() * 0.1F + 1.1F, true); + } + if (openCount == 0 && lid.getChaseTarget() == 1) + level.playLocalSound(vec.x, vec.y, vec.z, SoundEvents.CHEST_CLOSE, SoundCategory.BLOCKS, 0.1F, + level.random.nextFloat() * 0.1F + 1.1F, true); + + } else if (openCount == 0 && lid.getChaseTarget() == 0 && lid.getValue(0) > 1 / 16f + && lid.getValue(1) < 1 / 16f) + level.playLocalSound(vec.x, vec.y, vec.z, SoundEvents.IRON_DOOR_CLOSE, SoundCategory.BLOCKS, 0.25F, + level.random.nextFloat() * 0.1F + 1.2F, true); + } + + @Override + public LazyOptional getCapability(Capability cap, Direction side) { + if (isItemHandlerCap(cap)) + return inventoryProvider.cast(); + return super.getCapability(cap, side); + } + + @Override + protected void fromTag(BlockState state, CompoundNBT compound, boolean clientPacket) { + inventory.deserializeNBT(compound.getCompound("Inventory")); + super.fromTag(state, compound, clientPacket); + if (compound.contains("CustomName", 8)) + this.customName = ITextComponent.Serializer.fromJson(compound.getString("CustomName")); + if (clientPacket) + openCount = compound.getInt("OpenCount"); + } + + @Override + protected void write(CompoundNBT compound, boolean clientPacket) { + compound.put("Inventory", inventory.serializeNBT()); + if (customName != null) + compound.putString("CustomName", ITextComponent.Serializer.toJson(customName)); + super.write(compound, clientPacket); + if (clientPacket) + compound.putInt("OpenCount", openCount); + } + + @Override + public Container createMenu(int id, PlayerInventory inv, PlayerEntity player) { + return ToolboxContainer.create(id, inv, this); + } + + @Override + public ITextComponent getDisplayName() { + return customName != null ? customName : new TranslationTextComponent("block.create.toolbox"); + } + + @Override + public void lazyTick() { + updateOpenCount(); + // keep re-advertising active TEs + ToolboxHandler.onLoad(this); + super.lazyTick(); + } + + void updateOpenCount() { + if (level.isClientSide) + return; + if (openCount == 0) + return; + + int prevOpenCount = openCount; + openCount = 0; + + for (PlayerEntity playerentity : level.getEntitiesOfClass(PlayerEntity.class, + new AxisAlignedBB(worldPosition).inflate(8))) + if (playerentity.containerMenu instanceof ToolboxContainer + && ((ToolboxContainer) playerentity.containerMenu).contentHolder == this) + openCount++; + + if (prevOpenCount != openCount) + sendData(); + } + + public void startOpen(PlayerEntity player) { + if (player.isSpectator()) + return; + if (openCount < 0) + openCount = 0; + openCount++; + sendData(); + } + + public void stopOpen(PlayerEntity player) { + if (player.isSpectator()) + return; + openCount--; + sendData(); + } + + public void connectPlayer(int slot, PlayerEntity player, int hotbarSlot) { + if (level.isClientSide) + return; + WeakHashMap map = connectedPlayers.computeIfAbsent(slot, WeakHashMap::new); + map.put(player, hotbarSlot); + } + + public void readInventory(CompoundNBT compound) { + inventory.deserializeNBT(compound); + } + + public void setCustomName(ITextComponent customName) { + this.customName = customName; + } + + @Override + public ITextComponent getName() { + return customName; + } + +} diff --git a/src/main/java/com/simibubi/create/content/curiosities/tools/BlueprintContainer.java b/src/main/java/com/simibubi/create/content/curiosities/tools/BlueprintContainer.java index bf08dde69..966e65579 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/tools/BlueprintContainer.java +++ b/src/main/java/com/simibubi/create/content/curiosities/tools/BlueprintContainer.java @@ -112,7 +112,8 @@ public class BlueprintContainer extends GhostItemContainer { } @Override - protected void readData(BlueprintSection contentHolder) { + protected void initAndReadInventory(BlueprintSection contentHolder) { + super.initAndReadInventory(contentHolder); } @Override diff --git a/src/main/java/com/simibubi/create/content/logistics/block/inventories/AdjustableCrateTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/inventories/AdjustableCrateTileEntity.java index 9ec1fbf31..978cac44b 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/inventories/AdjustableCrateTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/inventories/AdjustableCrateTileEntity.java @@ -11,7 +11,6 @@ import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.INamedContainerProvider; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; -import net.minecraft.network.PacketBuffer; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; @@ -162,11 +161,6 @@ public class AdjustableCrateTileEntity extends CrateTileEntity implements INamed return Lang.translate("gui.adjustable_crate.title"); } - public void sendToContainer(PacketBuffer buffer) { - buffer.writeBlockPos(getBlockPos()); - buffer.writeNbt(getUpdateTag()); - } - @Override public void setRemoved() { super.setRemoved(); diff --git a/src/main/java/com/simibubi/create/content/logistics/item/filter/AttributeFilterContainer.java b/src/main/java/com/simibubi/create/content/logistics/item/filter/AttributeFilterContainer.java index 8d0691975..3902a50a9 100644 --- a/src/main/java/com/simibubi/create/content/logistics/item/filter/AttributeFilterContainer.java +++ b/src/main/java/com/simibubi/create/content/logistics/item/filter/AttributeFilterContainer.java @@ -126,7 +126,8 @@ public class AttributeFilterContainer extends AbstractFilterContainer { } @Override - protected void readData(ItemStack filterItem) { + protected void initAndReadInventory(ItemStack filterItem) { + super.initAndReadInventory(filterItem); selectedAttributes = new ArrayList<>(); whitelistMode = WhitelistMode.values()[filterItem.getOrCreateTag() .getInt("WhitelistMode")]; diff --git a/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterContainer.java b/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterContainer.java index b0b19f5dc..0cc9acc13 100644 --- a/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterContainer.java +++ b/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterContainer.java @@ -52,7 +52,8 @@ public class FilterContainer extends AbstractFilterContainer { } @Override - protected void readData(ItemStack filterItem) { + protected void initAndReadInventory(ItemStack filterItem) { + super.initAndReadInventory(filterItem); CompoundNBT tag = filterItem.getOrCreateTag(); respectNBT = tag.getBoolean("RespectNBT"); blacklist = tag.getBoolean("Blacklist"); diff --git a/src/main/java/com/simibubi/create/events/ClientEvents.java b/src/main/java/com/simibubi/create/events/ClientEvents.java index c25d99b98..8ea90bf26 100644 --- a/src/main/java/com/simibubi/create/events/ClientEvents.java +++ b/src/main/java/com/simibubi/create/events/ClientEvents.java @@ -27,6 +27,7 @@ import com.simibubi.create.content.contraptions.itemAssembly.SequencedAssemblyRe import com.simibubi.create.content.contraptions.relays.belt.BeltSlicer; import com.simibubi.create.content.contraptions.relays.belt.item.BeltConnectorHandler; import com.simibubi.create.content.curiosities.armor.CopperBacktankArmorLayer; +import com.simibubi.create.content.curiosities.toolbox.ToolboxHandlerClient; import com.simibubi.create.content.curiosities.tools.BlueprintOverlayRenderer; import com.simibubi.create.content.curiosities.tools.ExtendoGripRenderHandler; import com.simibubi.create.content.curiosities.zapper.ZapperItem; @@ -145,6 +146,7 @@ public class ClientEvents { CreateClient.GHOST_BLOCKS.tickGhosts(); ContraptionRenderDispatcher.tick(world); BlueprintOverlayRenderer.tick(); + ToolboxHandlerClient.clientTick(); } @SubscribeEvent @@ -225,6 +227,7 @@ public class ClientEvents { LinkedControllerClientHandler.renderOverlay(ms, buffer, light, overlay, partialTicks); BlueprintOverlayRenderer.renderOverlay(ms, buffer, light, overlay, partialTicks); GoggleOverlayRenderer.renderOverlay(ms, buffer, light, overlay, partialTicks); + ToolboxHandlerClient.renderOverlay(ms, buffer, light, overlay, partialTicks); } @SubscribeEvent diff --git a/src/main/java/com/simibubi/create/events/InputEvents.java b/src/main/java/com/simibubi/create/events/InputEvents.java index 2b97cb343..f9decbf84 100644 --- a/src/main/java/com/simibubi/create/events/InputEvents.java +++ b/src/main/java/com/simibubi/create/events/InputEvents.java @@ -1,6 +1,7 @@ package com.simibubi.create.events; import com.simibubi.create.CreateClient; +import com.simibubi.create.content.curiosities.toolbox.ToolboxHandlerClient; import com.simibubi.create.content.logistics.item.LinkedControllerClientHandler; import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringHandler; import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollValueHandler; @@ -26,6 +27,7 @@ public class InputEvents { return; CreateClient.SCHEMATIC_HANDLER.onKeyInput(key, pressed); + ToolboxHandlerClient.onKeyInput(key, pressed); } @SubscribeEvent diff --git a/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java b/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java index 3998c7258..67b52074c 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java +++ b/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java @@ -52,6 +52,18 @@ public enum AllGuiTextures implements IScreenRenderable { FILTER("filters.png", 214, 97), ATTRIBUTE_FILTER("filters.png", 0, 97, 241, 83), + TOOLBOX("toolbox.png", 188, 171), + TOOLBELT_SLOT("minecraft", "widgets.png", 24, 23, 22, 22), + TOOLBELT_SLOT_HIGHLIGHT("minecraft", "widgets.png", 0, 22, 24, 24), + TOOLBELT_MAIN_SLOT("widgets.png", 0, 97, 24, 24), + TOOLBELT_EMPTY_SLOT("widgets.png", 27, 98, 22, 22), + TOOLBELT_INACTIVE_SLOT("widgets.png", 52, 98, 22, 22), + + TOOLBELT_HOTBAR_OFF("widgets.png", 0, 130, 20, 24), + TOOLBELT_HOTBAR_ON("widgets.png", 20, 130, 20, 24), + TOOLBELT_SELECTED_OFF("widgets.png", 0, 155, 22, 22), + TOOLBELT_SELECTED_ON("widgets.png", 22, 155, 22, 22), + SEQUENCER("sequencer.png", 173, 159), SEQUENCER_INSTRUCTION("sequencer.png", 0, 14, 162, 22), SEQUENCER_DELAY("sequencer.png", 0, 58, 162, 22), @@ -120,7 +132,11 @@ public enum AllGuiTextures implements IScreenRenderable { } private AllGuiTextures(String location, int startX, int startY, int width, int height) { - this.location = new ResourceLocation(Create.ID, "textures/gui/" + location); + this(Create.ID, location, startX, startY, width, height); + } + + private AllGuiTextures(String namespace, String location, int startX, int startY, int width, int height) { + this.location = new ResourceLocation(namespace, "textures/gui/" + location); this.width = width; this.height = height; this.startX = startX; diff --git a/src/main/java/com/simibubi/create/foundation/gui/ContainerBase.java b/src/main/java/com/simibubi/create/foundation/gui/ContainerBase.java new file mode 100644 index 000000000..fff1ae447 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/gui/ContainerBase.java @@ -0,0 +1,69 @@ +package com.simibubi.create.foundation.gui; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.container.Container; +import net.minecraft.inventory.container.ContainerType; +import net.minecraft.inventory.container.Slot; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +public abstract class ContainerBase extends Container { + + public PlayerEntity player; + public PlayerInventory playerInventory; + public T contentHolder; + + protected ContainerBase(ContainerType type, int id, PlayerInventory inv, PacketBuffer extraData) { + super(type, id); + init(inv, createOnClient(extraData)); + } + + protected ContainerBase(ContainerType type, int id, PlayerInventory inv, T contentHolder) { + super(type, id); + init(inv, contentHolder); + } + + protected void init(PlayerInventory inv, T contentHolderIn) { + player = inv.player; + playerInventory = inv; + contentHolder = contentHolderIn; + initAndReadInventory(contentHolder); + addSlots(); + broadcastChanges(); + } + + @OnlyIn(Dist.CLIENT) + protected abstract T createOnClient(PacketBuffer extraData); + + protected abstract void addSlots(); + + protected abstract void initAndReadInventory(T contentHolder); + + protected abstract void saveData(T contentHolder); + + 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 void removed(PlayerEntity playerIn) { + super.removed(playerIn); + saveData(contentHolder); + } + + @Override + public boolean stillValid(PlayerEntity player) { + if (contentHolder == null) + return false; + if (contentHolder instanceof IInteractionChecker) + return ((IInteractionChecker) contentHolder).canPlayerUse(player); + return true; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/gui/GhostItemContainer.java b/src/main/java/com/simibubi/create/foundation/gui/GhostItemContainer.java index d2b00bea3..7b7f1903c 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/GhostItemContainer.java +++ b/src/main/java/com/simibubi/create/foundation/gui/GhostItemContainer.java @@ -3,54 +3,32 @@ 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 extends Container implements IClearableContainer { +public abstract class GhostItemContainer extends ContainerBase 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)); + super(type, id, inv, extraData); } protected GhostItemContainer(ContainerType type, int id, PlayerInventory inv, T contentHolder) { - super(type, id); - init(inv, contentHolder); + super(type, id, 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; + @Override + protected void initAndReadInventory(T contentHolder) { ghostInventory = createGhostInventory(); - readData(contentHolder); - addSlots(); - broadcastChanges(); } @Override @@ -59,14 +37,6 @@ public abstract class GhostItemContainer extends Container implements ICleara 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 canTakeItemForPickAll(ItemStack stack, Slot slotIn) { return slotIn.container == playerInventory; @@ -135,10 +105,6 @@ public abstract class GhostItemContainer extends Container implements ICleara return ItemStack.EMPTY; } - @Override - public void removed(PlayerEntity playerIn) { - super.removed(playerIn); - saveData(contentHolder); - } + } diff --git a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java index 079bc0cbd..e26663161 100644 --- a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java +++ b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java @@ -23,6 +23,7 @@ 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.bell.SoulPulseEffectPacket; import com.simibubi.create.content.curiosities.symmetry.SymmetryEffectPacket; +import com.simibubi.create.content.curiosities.toolbox.ToolboxEquipPacket; import com.simibubi.create.content.curiosities.tools.BlueprintAssignCompleteRecipePacket; import com.simibubi.create.content.curiosities.tools.ExtendoGripInteractionPacket; import com.simibubi.create.content.curiosities.weapons.PotatoCannonPacket; @@ -96,6 +97,7 @@ public enum AllPackets { 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), + TOOLBOX_EQUIP(ToolboxEquipPacket.class, ToolboxEquipPacket::new, PLAY_TO_SERVER), // Server to Client SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_TO_CLIENT), diff --git a/src/main/java/com/simibubi/create/foundation/networking/ISyncPersistentData.java b/src/main/java/com/simibubi/create/foundation/networking/ISyncPersistentData.java index 77d3ccfde..1226eaabd 100644 --- a/src/main/java/com/simibubi/create/foundation/networking/ISyncPersistentData.java +++ b/src/main/java/com/simibubi/create/foundation/networking/ISyncPersistentData.java @@ -1,6 +1,6 @@ package com.simibubi.create.foundation.networking; -import java.util.Iterator; +import java.util.HashSet; import java.util.function.Supplier; import net.minecraft.client.Minecraft; @@ -43,20 +43,17 @@ public interface ISyncPersistentData { @Override public void handle(Supplier context) { context.get() - .enqueueWork(() -> { - Entity entityByID = Minecraft.getInstance().level.getEntity(entityId); - if (!(entityByID instanceof ISyncPersistentData)) - return; - CompoundNBT data = entityByID.getPersistentData(); - for (Iterator iterator = data.getAllKeys() - .iterator(); iterator.hasNext(); ) { - data.remove(iterator.next()); - } - data.merge(readData); - ((ISyncPersistentData) entityByID).onPersistentDataUpdated(); - }); + .enqueueWork(() -> { + Entity entityByID = Minecraft.getInstance().level.getEntity(entityId); + CompoundNBT data = entityByID.getPersistentData(); + new HashSet<>(data.getAllKeys()).forEach(data::remove); + data.merge(readData); + if (!(entityByID instanceof ISyncPersistentData)) + return; + ((ISyncPersistentData) entityByID).onPersistentDataUpdated(); + }); context.get() - .setPacketHandled(true); + .setPacketHandled(true); } } diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/SmartTileEntity.java b/src/main/java/com/simibubi/create/foundation/tileEntity/SmartTileEntity.java index 2b7541bb4..7d88ca00f 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/SmartTileEntity.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/SmartTileEntity.java @@ -15,6 +15,7 @@ import com.simibubi.create.foundation.utility.IPartialSafeNBT; import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.nbt.CompoundNBT; +import net.minecraft.network.PacketBuffer; import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.TileEntityType; import net.minecraft.world.World; @@ -214,10 +215,15 @@ public abstract class SmartTileEntity extends SyncedTileEntity implements ITicka @Override public boolean canPlayerUse(PlayerEntity player) { - if (level == null || level.getBlockEntity(worldPosition) != this) { + if (level == null || level.getBlockEntity(worldPosition) != this) return false; - } - return player.distanceToSqr(worldPosition.getX() + 0.5D, worldPosition.getY() + 0.5D, worldPosition.getZ() + 0.5D) <= 64.0D; + return player.distanceToSqr(worldPosition.getX() + 0.5D, worldPosition.getY() + 0.5D, + worldPosition.getZ() + 0.5D) <= 64.0D; + } + + public void sendToContainer(PacketBuffer buffer) { + buffer.writeBlockPos(getBlockPos()); + buffer.writeNbt(getUpdateTag()); } public World getWorld() { diff --git a/src/main/java/com/simibubi/create/foundation/utility/NBTHelper.java b/src/main/java/com/simibubi/create/foundation/utility/NBTHelper.java index 34d32c713..880f7e4ed 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/NBTHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/NBTHelper.java @@ -53,7 +53,7 @@ public class NBTHelper { listNBT.forEach(inbt -> consumer.accept((CompoundNBT) inbt)); } - public static ListNBT writeItemList(List stacks) { + public static ListNBT writeItemList(Iterable stacks) { return writeCompoundList(stacks, ItemStack::serializeNBT); } diff --git a/src/main/resources/assets/create/lang/default/messages.json b/src/main/resources/assets/create/lang/default/messages.json index 1df9899de..24ae8105f 100644 --- a/src/main/resources/assets/create/lang/default/messages.json +++ b/src/main/resources/assets/create/lang/default/messages.json @@ -104,6 +104,10 @@ "create.gui.toolmenu.focusKey": "Hold [%1$s] to Focus", "create.gui.toolmenu.cycle": "[SCROLL] to Cycle", + + "create.toolbox.unequip": "Unequip: %1$s", + "create.toolbox.outOfRange": "Toolbox of held item not in Range", + "create.toolbox.detach": "Stop tracking and keep item", "create.gui.symmetryWand.mirrorType": "Mirror", "create.gui.symmetryWand.orientation": "Orientation", diff --git a/src/main/resources/assets/create/models/block/toolbox/block.json b/src/main/resources/assets/create/models/block/toolbox/block.json new file mode 100644 index 000000000..5263d8999 --- /dev/null +++ b/src/main/resources/assets/create/models/block/toolbox/block.json @@ -0,0 +1,24 @@ +{ + "credit": "Made with Blockbench", + "texture_size": [32, 32], + "textures": { + "0": "create:block/toolbox", + "particle": "block/dark_oak_planks" + }, + "elements": [ + { + "from": [1, 0, 4], + "to": [15, 6, 12], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 1.5, 7, 4.5], "texture": "#0"}, + "east": {"uv": [6, 6, 10, 9], "texture": "#0"}, + "south": {"uv": [7, 1.5, 14, 4.5], "texture": "#0"}, + "west": {"uv": [6, 6, 10, 9], "texture": "#0"}, + "up": {"uv": [0, 11.5, 7, 15.5], "texture": "#0"}, + "down": {"uv": [7, 11.5, 14, 15.5], "texture": "#0"} + } + } + ], + "display": {} +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/toolbox/drawer.json b/src/main/resources/assets/create/models/block/toolbox/drawer.json new file mode 100644 index 000000000..0cb557f1f --- /dev/null +++ b/src/main/resources/assets/create/models/block/toolbox/drawer.json @@ -0,0 +1,23 @@ +{ + "credit": "Made with Blockbench", + "texture_size": [32, 32], + "textures": { + "0": "create:block/toolbox", + "particle": "block/dark_oak_planks" + }, + "elements": [ + { + "from": [2, 1, 4], + "to": [14, 3, 10], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 4.5, 6, 5.5], "texture": "#0"}, + "east": {"uv": [6, 9, 9, 10], "texture": "#0"}, + "west": {"uv": [9, 9, 6, 10], "texture": "#0"}, + "up": {"uv": [0, 5.5, 6, 8.5], "rotation": 180, "texture": "#0"}, + "down": {"uv": [0, 8.5, 6, 11.5], "texture": "#0"} + } + } + ], + "display": {} +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/toolbox/item.json b/src/main/resources/assets/create/models/block/toolbox/item.json new file mode 100644 index 000000000..5c2b40a1c --- /dev/null +++ b/src/main/resources/assets/create/models/block/toolbox/item.json @@ -0,0 +1,132 @@ +{ + "credit": "Made with Blockbench", + "texture_size": [32, 32], + "textures": { + "0": "create:block/toolbox", + "particle": "block/dark_oak_planks" + }, + "elements": [ + { + "from": [1, 0, 4], + "to": [15, 6, 12], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 1.5, 7, 4.5], "texture": "#0"}, + "east": {"uv": [6, 6, 10, 9], "texture": "#0"}, + "south": {"uv": [7, 1.5, 14, 4.5], "texture": "#0"}, + "west": {"uv": [6, 6, 10, 9], "texture": "#0"}, + "up": {"uv": [0, 11.5, 7, 15.5], "texture": "#0"}, + "down": {"uv": [7, 11.5, 14, 15.5], "texture": "#0"} + } + }, + { + "from": [1, 6, 4], + "to": [15, 9, 12], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 7, 1.5], "texture": "#0"}, + "east": {"uv": [6, 4.5, 10, 6], "texture": "#0"}, + "south": {"uv": [7, 0, 14, 1.5], "texture": "#0"}, + "west": {"uv": [6, 4.5, 10, 6], "texture": "#0"}, + "up": {"uv": [10, 4.5, 14, 11.5], "rotation": 90, "texture": "#0"}, + "down": {"uv": [7, 11.5, 14, 15.5], "texture": "#0"} + } + }, + { + "from": [11, 5, 3], + "to": [13, 8, 4], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [9, 9, 10, 10.5], "texture": "#0"}, + "east": {"uv": [9, 9, 9.5, 10.5], "texture": "#0"}, + "south": {"uv": [10, 9, 9, 10.5], "texture": "#0"}, + "west": {"uv": [9.5, 9, 10, 10.5], "texture": "#0"}, + "up": {"uv": [9, 9, 10, 9.5], "rotation": 180, "texture": "#0"}, + "down": {"uv": [9, 10, 10, 10.5], "rotation": 180, "texture": "#0"} + } + }, + { + "from": [4, 9, 8], + "to": [12, 11, 8], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [6, 10.5, 10, 11.5], "texture": "#0"}, + "south": {"uv": [6, 10.5, 10, 11.5], "texture": "#0"} + } + }, + { + "from": [1.95, 1.1, 3.7], + "to": [14.05, 3, 9.7], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 4.5, 6, 5.5], "texture": "#0"}, + "east": {"uv": [6, 9, 9, 10], "texture": "#0"}, + "west": {"uv": [9, 9, 6, 10], "texture": "#0"}, + "up": {"uv": [0, 5.5, 6, 8.5], "rotation": 180, "texture": "#0"}, + "down": {"uv": [0, 8.5, 6, 11.5], "texture": "#0"} + } + }, + { + "from": [1.95, 3, 3.7], + "to": [14.05, 5.05, 9.7], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 4.5, 6, 5.5], "texture": "#0"}, + "east": {"uv": [6, 9, 9, 10], "texture": "#0"}, + "west": {"uv": [9, 9, 6, 10], "texture": "#0"}, + "up": {"uv": [0, 5.5, 6, 8.5], "rotation": 180, "texture": "#0"}, + "down": {"uv": [0, 8.5, 6, 11.5], "texture": "#0"} + } + }, + { + "from": [3, 5, 3], + "to": [5, 8, 4], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [9, 9, 10, 10.5], "texture": "#0"}, + "east": {"uv": [9, 9, 9.5, 10.5], "texture": "#0"}, + "south": {"uv": [10, 9, 9, 10.5], "texture": "#0"}, + "west": {"uv": [9.5, 9, 10, 10.5], "texture": "#0"}, + "up": {"uv": [9, 9, 10, 9.5], "rotation": 180, "texture": "#0"}, + "down": {"uv": [9, 10, 10, 10.5], "rotation": 180, "texture": "#0"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, -77, 2], + "translation": [0, -2.5, -0.75], + "scale": [0.64, 0.64, 0.64] + }, + "thirdperson_lefthand": { + "rotation": [75, -77, 2], + "translation": [0, -2.5, -0.75], + "scale": [0.64, 0.64, 0.64] + }, + "firstperson_righthand": { + "rotation": [-5, 86, 0], + "translation": [1, -1.25, 0], + "scale": [0.88, 0.88, 0.88] + }, + "firstperson_lefthand": { + "rotation": [-5, 86, 0], + "translation": [1, -1.25, 0], + "scale": [0.88, 0.88, 0.88] + }, + "ground": { + "translation": [0, 2, 0], + "scale": [0.5, 0.5, 0.5] + }, + "gui": { + "rotation": [30, 225, 0], + "translation": [0.25, 2.25, 0], + "scale": [0.79, 0.79, 0.79] + }, + "head": { + "translation": [0, 2.75, 0] + }, + "fixed": { + "scale": [0.5, 0.5, 0.5] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/toolbox/lid.json b/src/main/resources/assets/create/models/block/toolbox/lid.json new file mode 100644 index 000000000..70afceaa4 --- /dev/null +++ b/src/main/resources/assets/create/models/block/toolbox/lid.json @@ -0,0 +1,59 @@ +{ + "credit": "Made with Blockbench", + "texture_size": [32, 32], + "textures": { + "0": "create:block/toolbox", + "particle": "block/dark_oak_planks" + }, + "elements": [ + { + "from": [1, 6, 4], + "to": [15, 9, 12], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 7, 1.5], "texture": "#0"}, + "east": {"uv": [6, 4.5, 10, 6], "texture": "#0"}, + "south": {"uv": [7, 0, 14, 1.5], "texture": "#0"}, + "west": {"uv": [6, 4.5, 10, 6], "texture": "#0"}, + "up": {"uv": [10, 4.5, 14, 11.5], "rotation": 90, "texture": "#0"}, + "down": {"uv": [7, 11.5, 14, 15.5], "texture": "#0"} + } + }, + { + "from": [11, 5, 3], + "to": [13, 8, 4], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [9, 9, 10, 10.5], "texture": "#0"}, + "east": {"uv": [9, 9, 9.5, 10.5], "texture": "#0"}, + "south": {"uv": [10, 9, 9, 10.5], "texture": "#0"}, + "west": {"uv": [9.5, 9, 10, 10.5], "texture": "#0"}, + "up": {"uv": [9, 9, 10, 9.5], "rotation": 180, "texture": "#0"}, + "down": {"uv": [9, 10, 10, 10.5], "rotation": 180, "texture": "#0"} + } + }, + { + "from": [4, 9, 8], + "to": [12, 11, 8], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [6, 10.5, 10, 11.5], "texture": "#0"}, + "south": {"uv": [6, 10.5, 10, 11.5], "texture": "#0"} + } + }, + { + "from": [3, 5, 3], + "to": [5, 8, 4], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [9, 9, 10, 10.5], "texture": "#0"}, + "east": {"uv": [9, 9, 9.5, 10.5], "texture": "#0"}, + "south": {"uv": [10, 9, 9, 10.5], "texture": "#0"}, + "west": {"uv": [9.5, 9, 10, 10.5], "texture": "#0"}, + "up": {"uv": [9, 9, 10, 9.5], "rotation": 180, "texture": "#0"}, + "down": {"uv": [9, 10, 10, 10.5], "rotation": 180, "texture": "#0"} + } + } + ], + "display": {} +} \ No newline at end of file diff --git a/src/main/resources/assets/create/textures/block/toolbox.png b/src/main/resources/assets/create/textures/block/toolbox.png new file mode 100644 index 000000000..629932887 Binary files /dev/null and b/src/main/resources/assets/create/textures/block/toolbox.png differ diff --git a/src/main/resources/assets/create/textures/gui/toolbox.png b/src/main/resources/assets/create/textures/gui/toolbox.png new file mode 100644 index 000000000..167920df5 Binary files /dev/null and b/src/main/resources/assets/create/textures/gui/toolbox.png differ diff --git a/src/main/resources/assets/create/textures/gui/widgets.png b/src/main/resources/assets/create/textures/gui/widgets.png index 3588a5cfc..ac4b8fdb9 100644 Binary files a/src/main/resources/assets/create/textures/gui/widgets.png and b/src/main/resources/assets/create/textures/gui/widgets.png differ