Packing Up

- Added the Toolbox
This commit is contained in:
simibubi 2021-09-16 04:10:34 +02:00
parent 1ec299deff
commit 896ab01644
58 changed files with 2291 additions and 218 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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": "方向",

View file

@ -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": "거울의 방향",

View file

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

View file

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

View file

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

View file

@ -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": "Ориентация",

View file

@ -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": "方向",

View file

@ -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": "方向",

View file

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

View file

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

View file

@ -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<FluidTransportBehaviour.AttachmentTypes, Map<Direction, PartialModel>> 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<FluidTransportBehaviour.AttachmentTypes, Map<Direction, PartialModel>> PIPE_ATTACHMENTS =
new HashMap<>();
public static final Map<BlazeBurnerBlock.HeatLevel, PartialModel> BLAZES = new HashMap<>();
static {

View file

@ -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<ValveHandleBlock> 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<ValveHandleBlock> 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<FluidTankBlock> 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.<FluidTankItem>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.<FluidTankItem>customBlockItemModel("_", "block_single_window"))
.build()
.register();
public static final BlockEntry<FluidTankBlock> CREATIVE_FLUID_TANK =
@ -844,11 +849,11 @@ public class AllBlocks {
.register();
public static final BlockEntry<ControllerRailBlock> 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<PloughBlock> 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<SeatBlock> 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<SailBlock> 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<SailBlock> 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<SailBlock> 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<CasingBlock> 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<CasingBlock> 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<CasingBlock> 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<LecternControllerBlock> 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<ToolboxBlock> 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 {

View file

@ -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<LinkedControllerContainer> LINKED_CONTROLLER =
register("linked_controller", LinkedControllerContainer::new, () -> LinkedControllerScreen::new);
public static final ContainerEntry<ToolboxContainer> TOOLBOX =
register("toolbox", ToolboxContainer::new, () -> ToolboxScreen::new);
private static <C extends Container, S extends Screen & IHasContainer<C>> ContainerEntry<C> register(String name, ForgeContainerFactory<C> factory, NonNullSupplier<ScreenFactory<C, S>> screenFactory) {
return Create.registrate().container(name, factory, screenFactory).register();

View file

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

View file

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

View file

@ -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<ToolboxTileEntity> TOOLBOX = Create.registrate()
.tileEntity("toolbox", ToolboxTileEntity::new)
.validBlocks(AllBlocks.TOOLBOX)
.renderer(() -> ToolboxRenderer::new)
.register();
public static void register() {}
}

View file

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

View file

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

View file

@ -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<ToolboxTileEntity> toolboxes;
private ToolboxTileEntity selectedBox;
final int UNEQUIP = -5;
public RadialToolboxMenu(List<ToolboxTileEntity> 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_);
}
}

View file

@ -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<ToolboxTileEntity> {
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<Block, BlockState> 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<ToolboxTileEntity> getTileEntityClass() {
return ToolboxTileEntity.class;
}
}

View file

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

View file

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

View file

@ -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<WeakHashMap<BlockPos, ToolboxTileEntity>> 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<ToolboxTileEntity> 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;
}
}

View file

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

View file

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

View file

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

View file

@ -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<ToolboxContainer> {
AllGuiTextures BG = AllGuiTextures.TOOLBOX;
AllGuiTextures PLAYER = AllGuiTextures.PLAYER_INVENTORY;
protected Slot hoveredToolboxSlot;
private IconButton confirmButton;
private List<Rectangle2d> 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<Rectangle2d> getExtraAreas() {
return extraAreas;
}
}

View file

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

View file

@ -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<IItemHandler> inventoryProvider;
protected int openCount;
Map<Integer, WeakHashMap<PlayerEntity, Integer>> 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<TileEntityBehaviour> 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<Entry<Integer, WeakHashMap<PlayerEntity, Integer>>> toolboxSlots = connectedPlayers.entrySet()
.iterator(); toolboxSlots.hasNext();) {
Entry<Integer, WeakHashMap<PlayerEntity, Integer>> toolboxSlotEntry = toolboxSlots.next();
WeakHashMap<PlayerEntity, Integer> set = toolboxSlotEntry.getValue();
int slot = toolboxSlotEntry.getKey();
ItemStack referenceItem = inventory.filters.get(slot);
boolean clear = referenceItem.isEmpty();
for (Iterator<Entry<PlayerEntity, Integer>> playerEntries = set.entrySet()
.iterator(); playerEntries.hasNext();) {
Entry<PlayerEntity, Integer> 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 <T> LazyOptional<T> getCapability(Capability<T> 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<PlayerEntity, Integer> 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;
}
}

View file

@ -112,7 +112,8 @@ public class BlueprintContainer extends GhostItemContainer<BlueprintSection> {
}
@Override
protected void readData(BlueprintSection contentHolder) {
protected void initAndReadInventory(BlueprintSection contentHolder) {
super.initAndReadInventory(contentHolder);
}
@Override

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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<T> extends Container implements IClearableContainer {
public abstract class GhostItemContainer<T> extends ContainerBase<T> 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<T> 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<T> extends Container implements ICleara
return ItemStack.EMPTY;
}
@Override
public void removed(PlayerEntity playerIn) {
super.removed(playerIn);
saveData(contentHolder);
}
}

View file

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

View file

@ -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) {
context.get()
.enqueueWork(() -> {
Entity entityByID = Minecraft.getInstance().level.getEntity(entityId);
if (!(entityByID instanceof ISyncPersistentData))
return;
CompoundNBT data = entityByID.getPersistentData();
for (Iterator<String> 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);
}
}

View file

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

View file

@ -53,7 +53,7 @@ public class NBTHelper {
listNBT.forEach(inbt -> consumer.accept((CompoundNBT) inbt));
}
public static ListNBT writeItemList(List<ItemStack> stacks) {
public static ListNBT writeItemList(Iterable<ItemStack> stacks) {
return writeCompoundList(stacks, ItemStack::serializeNBT);
}

View file

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

View file

@ -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": {}
}

View file

@ -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": {}
}

View file

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

View file

@ -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": {}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB