Bigger Boxes
- Added the Item Vault
|
@ -200,6 +200,7 @@ be3bef7e091d8b50bfc1c6b7275946d1f636aefd assets/create/blockstates/horizontal_fr
|
|||
18d9fdaa1352a7e2ec91135e46dae5c02ccd8f8f assets/create/blockstates/horizontal_framed_glass_pane.json
|
||||
30ec347dfc827a9ae52cf3da964b828005acede1 assets/create/blockstates/hose_pulley.json
|
||||
6651c84ea621777d572a3d7aa13b75d9f061191b assets/create/blockstates/item_drain.json
|
||||
10ef455fd61ed1ca831d27bf2b533d05dec9c67d assets/create/blockstates/item_vault.json
|
||||
5d851c90d23de5087ce546d4bbe509e112b84c49 assets/create/blockstates/jungle_window.json
|
||||
b15bea757ef981e0ca60f740ca234ee2014eb7b7 assets/create/blockstates/jungle_window_pane.json
|
||||
f651091db216b009b3379b2f48d56d03481c8675 assets/create/blockstates/large_cogwheel.json
|
||||
|
@ -442,20 +443,20 @@ bf2b0310500213ff853c748c236eb5d01f61658e assets/create/blockstates/yellow_toolbo
|
|||
6801fa1f466f172700e573e5b8ee8ee5f9ca4583 assets/create/blockstates/yellow_valve_handle.json
|
||||
7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json
|
||||
b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json
|
||||
7c31858e6239b72e4da8830fa4cf1748ef2a7ae1 assets/create/lang/en_ud.json
|
||||
124dd97c100eda3e8078c5e524db74ba91bf206c assets/create/lang/en_us.json
|
||||
738b1c5391dedb308e2b782d48cf867c8a8bf041 assets/create/lang/unfinished/de_de.json
|
||||
a987345dd3375ad01fe4900f93941570d374dba9 assets/create/lang/unfinished/es_es.json
|
||||
9c26f0e9e28c76ef1f5e5e8bf6d0de8eb4d956d6 assets/create/lang/unfinished/fr_fr.json
|
||||
211c4c8cbd62546a08616b2482319c63d87083a5 assets/create/lang/unfinished/it_it.json
|
||||
9590169c9c1708af58db1adba3e38e7c58952cfd assets/create/lang/unfinished/ja_jp.json
|
||||
97eb7f70b3dffea14fc4df5a0147395c3663f321 assets/create/lang/unfinished/ko_kr.json
|
||||
a9a7bacadde4d6daa4f4ae85da2821c33252442b assets/create/lang/unfinished/nl_nl.json
|
||||
e8a42aacad3b0b606cf79a30d209dabe6e13a6b3 assets/create/lang/unfinished/pl_pl.json
|
||||
1a0fa057db601d3aa35c971a9e3d113d3cf61cca assets/create/lang/unfinished/pt_br.json
|
||||
4d0e6890f838528bed5c7ec58703b4369b10a0b4 assets/create/lang/unfinished/ru_ru.json
|
||||
6aeaa68280d6fb85aa0e3eabc27d4723a2af4b8b assets/create/lang/unfinished/zh_cn.json
|
||||
a4b3fceb0d539b6f9cc27d6d81ea1f862f83f3c0 assets/create/lang/unfinished/zh_tw.json
|
||||
1467113c879a243b2f077b196839491306733e98 assets/create/lang/en_ud.json
|
||||
b2c605fc34b13c7239521f9269498e81f9206df8 assets/create/lang/en_us.json
|
||||
a6a58d7de53eb8604d4931ebae0ac2db21cdc294 assets/create/lang/unfinished/de_de.json
|
||||
1e17cccd3640755df4791103703321b20939270a assets/create/lang/unfinished/es_es.json
|
||||
b3080971e3ee4fa68a939aa950a2efb526c2514b assets/create/lang/unfinished/fr_fr.json
|
||||
d049c3352e50b7e712a7e8f960bacbf05ccd67c2 assets/create/lang/unfinished/it_it.json
|
||||
f5b457214c5e016819cfc40963a8416b87f0f6c0 assets/create/lang/unfinished/ja_jp.json
|
||||
dc58414c920b5a133aabc0199c31c6d1825cf49b assets/create/lang/unfinished/ko_kr.json
|
||||
020b76171c6c05ed68aa850e7178a5d3b66dc726 assets/create/lang/unfinished/nl_nl.json
|
||||
eb77d2c1b2e596811a201d8ad99c05fd1a2f87ec assets/create/lang/unfinished/pl_pl.json
|
||||
0b5a48da526045a8ca23aabb7ee188bdf799355a assets/create/lang/unfinished/pt_br.json
|
||||
5e853989000583f44b25721d8f3fe6d456ef3127 assets/create/lang/unfinished/ru_ru.json
|
||||
baf3023293ad9565d6898ec18e54109e0fc9c7e1 assets/create/lang/unfinished/zh_cn.json
|
||||
b5d55f65cf5ac2b262622b0bf15cfd2b03100dcf 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
|
||||
|
@ -1498,6 +1499,7 @@ ff92f6a9dfb73a6ee1eaaed3279c89390ff04a80 assets/create/models/item/hose_pulley.j
|
|||
153a185852af79654f0fb216c4b1b8e69c85ee8a assets/create/models/item/incomplete_precision_mechanism.json
|
||||
9d605ce0da83a73b535bce45c107e604364e2b20 assets/create/models/item/iron_sheet.json
|
||||
52e435014cb03e93411666c4799ebff206e55fc9 assets/create/models/item/item_drain.json
|
||||
76ab46c9b64faf5e94391579eec5115360dff73d assets/create/models/item/item_vault.json
|
||||
83fa8699318e51f838b483b40b3e897c34ed53d1 assets/create/models/item/jungle_window.json
|
||||
766323f6026c3505a75db2dee2996d342370d9c2 assets/create/models/item/jungle_window_pane.json
|
||||
bcaaf60d9a853cce90169dabcb36d29a3ce19e18 assets/create/models/item/large_cogwheel.json
|
||||
|
@ -2674,6 +2676,7 @@ b80ea3ecf06dc3b394eb5006ed22a1cc1c276be7 data/create/loot_tables/blocks/haunted_
|
|||
6a95342ca2e88c1e829a649d33c9b4aa8ea9b590 data/create/loot_tables/blocks/horizontal_framed_glass_pane.json
|
||||
a40f78789e92c72d248cf5c99c04682e4fd29d28 data/create/loot_tables/blocks/hose_pulley.json
|
||||
d913437bf5ea95e80abd389fffa031343e14c49f data/create/loot_tables/blocks/item_drain.json
|
||||
34d7db36bfc0a6da4a8f1803a24de0d9765ce003 data/create/loot_tables/blocks/item_vault.json
|
||||
88a1de3ac08023cbc920c338db9f97a4ffecbd5d data/create/loot_tables/blocks/jungle_window.json
|
||||
bf2d5854965b850fe72fac1992924bf4a0bba456 data/create/loot_tables/blocks/jungle_window_pane.json
|
||||
7935444e5cef99d58c2dc26d72f234732b6b5632 data/create/loot_tables/blocks/large_cogwheel.json
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"variants": {
|
||||
"axis=x,large=false": {
|
||||
"model": "create:block/item_vault",
|
||||
"y": 90
|
||||
},
|
||||
"axis=z,large=false": {
|
||||
"model": "create:block/item_vault"
|
||||
},
|
||||
"axis=x,large=true": {
|
||||
"model": "create:block/item_vault",
|
||||
"y": 90
|
||||
},
|
||||
"axis=z,large=true": {
|
||||
"model": "create:block/item_vault"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -201,6 +201,7 @@
|
|||
"block.create.horizontal_framed_glass_pane": "\u01DDu\u0250\u0500 ss\u0250\u05DF\u2141 p\u01DD\u026F\u0250\u0279\u2132 \u05DF\u0250\u0287uoz\u0131\u0279oH",
|
||||
"block.create.hose_pulley": "\u028E\u01DD\u05DF\u05DFn\u0500 \u01DDsoH",
|
||||
"block.create.item_drain": "u\u0131\u0250\u0279\u15E1 \u026F\u01DD\u0287I",
|
||||
"block.create.item_vault": "\u0287\u05DFn\u0250\u039B \u026F\u01DD\u0287I",
|
||||
"block.create.jungle_window": "\u028Dopu\u0131M \u01DD\u05DFbun\u017F",
|
||||
"block.create.jungle_window_pane": "\u01DDu\u0250\u0500 \u028Dopu\u0131M \u01DD\u05DFbun\u017F",
|
||||
"block.create.large_cogwheel": "\u05DF\u01DD\u01DD\u0265\u028Dbo\u0186 \u01DDb\u0279\u0250\uA780",
|
||||
|
|
|
@ -204,6 +204,7 @@
|
|||
"block.create.horizontal_framed_glass_pane": "Horizontal Framed Glass Pane",
|
||||
"block.create.hose_pulley": "Hose Pulley",
|
||||
"block.create.item_drain": "Item Drain",
|
||||
"block.create.item_vault": "Item Vault",
|
||||
"block.create.jungle_window": "Jungle Window",
|
||||
"block.create.jungle_window_pane": "Jungle Window Pane",
|
||||
"block.create.large_cogwheel": "Large Cogwheel",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1166",
|
||||
"_": "Missing Localizations: 1167",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -205,6 +205,7 @@
|
|||
"block.create.horizontal_framed_glass_pane": "Horizontal Gerahmte Glasscheibe",
|
||||
"block.create.hose_pulley": "Umlenkrolle",
|
||||
"block.create.item_drain": "Abfluss",
|
||||
"block.create.item_vault": "UNLOCALIZED: Item Vault",
|
||||
"block.create.jungle_window": "Tropenholzfenster",
|
||||
"block.create.jungle_window_pane": "Tropenholzfensterscheibe",
|
||||
"block.create.large_cogwheel": "Großes Zahnrad",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 44",
|
||||
"_": "Missing Localizations: 45",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -205,6 +205,7 @@
|
|||
"block.create.horizontal_framed_glass_pane": "Panel de cristal con marco horizontal",
|
||||
"block.create.hose_pulley": "Polea de manguera",
|
||||
"block.create.item_drain": "Drenador de objetos",
|
||||
"block.create.item_vault": "UNLOCALIZED: Item Vault",
|
||||
"block.create.jungle_window": "Ventana de jungla",
|
||||
"block.create.jungle_window_pane": "Panel de ventana de jungla",
|
||||
"block.create.large_cogwheel": "Engranaje grande",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1417",
|
||||
"_": "Missing Localizations: 1418",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -205,6 +205,7 @@
|
|||
"block.create.horizontal_framed_glass_pane": "Vitre encadrée horizontale",
|
||||
"block.create.hose_pulley": "UNLOCALIZED: Hose Pulley",
|
||||
"block.create.item_drain": "UNLOCALIZED: Item Drain",
|
||||
"block.create.item_vault": "UNLOCALIZED: Item Vault",
|
||||
"block.create.jungle_window": "UNLOCALIZED: Jungle Window",
|
||||
"block.create.jungle_window_pane": "UNLOCALIZED: Jungle Window Pane",
|
||||
"block.create.large_cogwheel": "Grande roue dentée",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 946",
|
||||
"_": "Missing Localizations: 947",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -205,6 +205,7 @@
|
|||
"block.create.horizontal_framed_glass_pane": "Pannello di finestra di vetro orizzontale",
|
||||
"block.create.hose_pulley": "Carrucola per tubi",
|
||||
"block.create.item_drain": "Drenante di oggetti",
|
||||
"block.create.item_vault": "UNLOCALIZED: Item Vault",
|
||||
"block.create.jungle_window": "Finestra della giungla",
|
||||
"block.create.jungle_window_pane": "Pannello di finestra della giungla",
|
||||
"block.create.large_cogwheel": "Ruota dentata grande",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 53",
|
||||
"_": "Missing Localizations: 54",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -205,6 +205,7 @@
|
|||
"block.create.horizontal_framed_glass_pane": "横型ガラス窓板",
|
||||
"block.create.hose_pulley": "ホースプーリー",
|
||||
"block.create.item_drain": "アイテム排液口",
|
||||
"block.create.item_vault": "UNLOCALIZED: Item Vault",
|
||||
"block.create.jungle_window": "ジャングルの窓",
|
||||
"block.create.jungle_window_pane": "ジャングルの窓板",
|
||||
"block.create.large_cogwheel": "大きな歯車",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 68",
|
||||
"_": "Missing Localizations: 69",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -205,6 +205,7 @@
|
|||
"block.create.horizontal_framed_glass_pane": "수평 유리판",
|
||||
"block.create.hose_pulley": "호스 도르래",
|
||||
"block.create.item_drain": "아이템 배수구",
|
||||
"block.create.item_vault": "UNLOCALIZED: Item Vault",
|
||||
"block.create.jungle_window": "정글나무 유리창",
|
||||
"block.create.jungle_window_pane": "정글나무 유리판",
|
||||
"block.create.large_cogwheel": "큰 톱니바퀴",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1795",
|
||||
"_": "Missing Localizations: 1796",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -205,6 +205,7 @@
|
|||
"block.create.horizontal_framed_glass_pane": "UNLOCALIZED: Horizontal Framed Glass Pane",
|
||||
"block.create.hose_pulley": "UNLOCALIZED: Hose Pulley",
|
||||
"block.create.item_drain": "UNLOCALIZED: Item Drain",
|
||||
"block.create.item_vault": "UNLOCALIZED: Item Vault",
|
||||
"block.create.jungle_window": "UNLOCALIZED: Jungle Window",
|
||||
"block.create.jungle_window_pane": "UNLOCALIZED: Jungle Window Pane",
|
||||
"block.create.large_cogwheel": "Groot Tandwiel",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 44",
|
||||
"_": "Missing Localizations: 45",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -205,6 +205,7 @@
|
|||
"block.create.horizontal_framed_glass_pane": "Pozioma oprawiona szyba",
|
||||
"block.create.hose_pulley": "Krążek z wężem",
|
||||
"block.create.item_drain": "Odpływ",
|
||||
"block.create.item_vault": "UNLOCALIZED: Item Vault",
|
||||
"block.create.jungle_window": "Dżunglowe okno",
|
||||
"block.create.jungle_window_pane": "Dżunglowa szyba okienna",
|
||||
"block.create.large_cogwheel": "Duże koło zębate",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1644",
|
||||
"_": "Missing Localizations: 1645",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -205,6 +205,7 @@
|
|||
"block.create.horizontal_framed_glass_pane": "UNLOCALIZED: Horizontal Framed Glass Pane",
|
||||
"block.create.hose_pulley": "Polia de Mangueira",
|
||||
"block.create.item_drain": "Dreno de Item",
|
||||
"block.create.item_vault": "UNLOCALIZED: Item Vault",
|
||||
"block.create.jungle_window": "UNLOCALIZED: Jungle Window",
|
||||
"block.create.jungle_window_pane": "UNLOCALIZED: Jungle Window Pane",
|
||||
"block.create.large_cogwheel": "Roda Dentada Grande",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 49",
|
||||
"_": "Missing Localizations: 50",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -205,6 +205,7 @@
|
|||
"block.create.horizontal_framed_glass_pane": "Горизонтальная обрамлённая стеклянная панель",
|
||||
"block.create.hose_pulley": "Шкив со шлангом",
|
||||
"block.create.item_drain": "Предметный осушитель",
|
||||
"block.create.item_vault": "UNLOCALIZED: Item Vault",
|
||||
"block.create.jungle_window": "Окно из тропического дерева",
|
||||
"block.create.jungle_window_pane": "Панель окна из тропического дерева",
|
||||
"block.create.large_cogwheel": "Большая шестерня",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 48",
|
||||
"_": "Missing Localizations: 49",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -205,6 +205,7 @@
|
|||
"block.create.horizontal_framed_glass_pane": "竖直边框玻璃板",
|
||||
"block.create.hose_pulley": "软管滑轮",
|
||||
"block.create.item_drain": "分液池",
|
||||
"block.create.item_vault": "UNLOCALIZED: Item Vault",
|
||||
"block.create.jungle_window": "丛林木窗户",
|
||||
"block.create.jungle_window_pane": "丛林木窗户板",
|
||||
"block.create.large_cogwheel": "大齿轮",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 63",
|
||||
"_": "Missing Localizations: 64",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -205,6 +205,7 @@
|
|||
"block.create.horizontal_framed_glass_pane": "豎直邊框玻璃片",
|
||||
"block.create.hose_pulley": "軟管滑輪",
|
||||
"block.create.item_drain": "分液池",
|
||||
"block.create.item_vault": "UNLOCALIZED: Item Vault",
|
||||
"block.create.jungle_window": "叢林木窗戶",
|
||||
"block.create.jungle_window_pane": "叢林木窗戶片",
|
||||
"block.create.large_cogwheel": "大齒輪",
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"parent": "create:block/item_vault"
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"type": "minecraft:block",
|
||||
"pools": [
|
||||
{
|
||||
"rolls": 1.0,
|
||||
"bonus_rolls": 0.0,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "create:item_vault"
|
||||
}
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:survives_explosion"
|
||||
}
|
||||
],
|
||||
"functions": []
|
||||
}
|
||||
]
|
||||
}
|
|
@ -160,6 +160,9 @@ import com.simibubi.create.content.logistics.block.redstone.RedstoneContactBlock
|
|||
import com.simibubi.create.content.logistics.block.redstone.RedstoneLinkBlock;
|
||||
import com.simibubi.create.content.logistics.block.redstone.RedstoneLinkGenerator;
|
||||
import com.simibubi.create.content.logistics.block.redstone.StockpileSwitchBlock;
|
||||
import com.simibubi.create.content.logistics.block.vault.VaultBlock;
|
||||
import com.simibubi.create.content.logistics.block.vault.VaultCTBehaviour;
|
||||
import com.simibubi.create.content.logistics.block.vault.VaultItem;
|
||||
import com.simibubi.create.content.logistics.item.LecternControllerBlock;
|
||||
import com.simibubi.create.content.schematics.block.SchematicTableBlock;
|
||||
import com.simibubi.create.content.schematics.block.SchematicannonBlock;
|
||||
|
@ -181,6 +184,7 @@ import com.tterrag.registrate.providers.RegistrateRecipeProvider;
|
|||
import com.tterrag.registrate.util.entry.BlockEntry;
|
||||
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
import net.minecraft.core.Direction.AxisDirection;
|
||||
import net.minecraft.data.recipes.ShapedRecipeBuilder;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
@ -1241,6 +1245,19 @@ public class AllBlocks {
|
|||
.transform(customItemModel())
|
||||
.register();
|
||||
|
||||
public static final BlockEntry<VaultBlock> ITEM_VAULT = REGISTRATE.block("item_vault", VaultBlock::new)
|
||||
.initialProperties(SharedProperties::softMetal)
|
||||
.properties(p -> p.sound(SoundType.NETHERITE_BLOCK))
|
||||
.blockstate((c, p) -> p.getVariantBuilder(c.get())
|
||||
.forAllStates(s -> ConfiguredModel.builder()
|
||||
.modelFile(AssetLookup.standardModel(c, p))
|
||||
.rotationY(s.getValue(VaultBlock.HORIZONTAL_AXIS) == Axis.X ? 90 : 0)
|
||||
.build()))
|
||||
.onRegister(connectedTextures(new VaultCTBehaviour()))
|
||||
.item(VaultItem::new)
|
||||
.build()
|
||||
.register();
|
||||
|
||||
public static final BlockEntry<AndesiteFunnelBlock> ANDESITE_FUNNEL =
|
||||
REGISTRATE.block("andesite_funnel", AndesiteFunnelBlock::new)
|
||||
.initialProperties(SharedProperties::stone)
|
||||
|
|
|
@ -13,9 +13,11 @@ import com.simibubi.create.content.palettes.PaletteBlockPattern;
|
|||
import com.simibubi.create.content.palettes.PaletteBlockPattern.CTs;
|
||||
import com.simibubi.create.content.palettes.PaletteStoneVariants;
|
||||
import com.simibubi.create.foundation.block.connected.CTSpriteShiftEntry;
|
||||
import com.simibubi.create.foundation.block.connected.CTSpriteShifter;
|
||||
import com.simibubi.create.foundation.block.connected.CTSpriteShifter.CTType;
|
||||
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
|
||||
import com.simibubi.create.foundation.block.render.SpriteShifter;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
||||
import net.minecraft.world.item.DyeColor;
|
||||
|
@ -58,6 +60,9 @@ public class AllSpriteShifts {
|
|||
FLUID_TANK = getCT(CTType.CROSS, "fluid_tank"),
|
||||
CREATIVE_FLUID_TANK = getCT(CTType.CROSS, "creative_fluid_tank");
|
||||
|
||||
public static final Couple<CTSpriteShiftEntry> VAULT_TOP = vault("top"), VAULT_FRONT = vault("front"),
|
||||
VAULT_SIDE = vault("side"), VAULT_BOTTOM = vault("bottom");
|
||||
|
||||
public static final SpriteShiftEntry BELT = SpriteShifter.get("block/belt", "block/belt_scroll"),
|
||||
BELT_OFFSET = SpriteShifter.get("block/belt_offset", "block/belt_scroll"),
|
||||
BELT_DIAGONAL = SpriteShifter.get("block/belt_diagonal", "block/belt_diagonal_scroll"),
|
||||
|
@ -108,6 +113,12 @@ public class AllSpriteShifts {
|
|||
}
|
||||
}
|
||||
|
||||
static Couple<CTSpriteShiftEntry> vault(String name) {
|
||||
final String prefixed = "vault_" + name;
|
||||
return Couple
|
||||
.createWithContext(b -> getCT(CTSpriteShifter.CTType.CROSS, prefixed, b ? prefixed : prefixed + "_large"));
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
static CTSpriteShiftEntry omni(String name) {
|
||||
|
|
|
@ -163,6 +163,7 @@ import com.simibubi.create.content.logistics.block.redstone.NixieTubeRenderer;
|
|||
import com.simibubi.create.content.logistics.block.redstone.NixieTubeTileEntity;
|
||||
import com.simibubi.create.content.logistics.block.redstone.RedstoneLinkTileEntity;
|
||||
import com.simibubi.create.content.logistics.block.redstone.StockpileSwitchTileEntity;
|
||||
import com.simibubi.create.content.logistics.block.vault.VaultTileEntity;
|
||||
import com.simibubi.create.content.logistics.item.LecternControllerRenderer;
|
||||
import com.simibubi.create.content.logistics.item.LecternControllerTileEntity;
|
||||
import com.simibubi.create.content.schematics.block.SchematicTableTileEntity;
|
||||
|
@ -406,6 +407,11 @@ public class AllTileEntities {
|
|||
.validBlocks(AllBlocks.MECHANICAL_ARM)
|
||||
.renderer(() -> ArmRenderer::new)
|
||||
.register();
|
||||
|
||||
public static final TileEntityEntry<VaultTileEntity> ITEM_VAULT = Create.registrate()
|
||||
.tileEntity("item_vault", VaultTileEntity::new)
|
||||
.validBlocks(AllBlocks.ITEM_VAULT)
|
||||
.register();
|
||||
|
||||
public static final TileEntityEntry<MechanicalPistonTileEntity> MECHANICAL_PISTON = Create.registrate()
|
||||
.tileEntity("mechanical_piston", MechanicalPistonTileEntity::new)
|
||||
|
|
|
@ -29,6 +29,8 @@ import com.simibubi.create.content.contraptions.components.structureMovement.pul
|
|||
import com.simibubi.create.content.contraptions.fluids.tank.FluidTankBlock;
|
||||
import com.simibubi.create.content.contraptions.fluids.tank.FluidTankConnectivityHandler;
|
||||
import com.simibubi.create.content.logistics.block.redstone.RedstoneLinkBlock;
|
||||
import com.simibubi.create.content.logistics.block.vault.VaultBlock;
|
||||
import com.simibubi.create.content.logistics.block.vault.VaultConnectivityHandler;
|
||||
import com.simibubi.create.foundation.config.ContraptionMovementSetting;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -331,6 +333,8 @@ public class BlockMovementChecks {
|
|||
.getAxis();
|
||||
if (state.getBlock() instanceof FluidTankBlock)
|
||||
return FluidTankConnectivityHandler.isConnected(world, pos, pos.relative(direction));
|
||||
if (state.getBlock() instanceof VaultBlock)
|
||||
return VaultConnectivityHandler.isConnected(world, pos, pos.relative(direction));
|
||||
if (AllBlocks.STICKER.has(state) && state.getValue(StickerBlock.EXTENDED)) {
|
||||
return direction == state.getValue(StickerBlock.FACING)
|
||||
&& !isNotSupportive(world.getBlockState(pos.relative(direction)), direction.getOpposite());
|
||||
|
|
|
@ -59,6 +59,7 @@ import com.simibubi.create.content.contraptions.relays.belt.BeltBlock;
|
|||
import com.simibubi.create.content.logistics.block.inventories.AdjustableCrateBlock;
|
||||
import com.simibubi.create.content.logistics.block.inventories.CreativeCrateTileEntity;
|
||||
import com.simibubi.create.content.logistics.block.redstone.RedstoneContactBlock;
|
||||
import com.simibubi.create.content.logistics.block.vault.VaultTileEntity;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.fluid.CombinedTankWrapper;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
||||
|
@ -656,7 +657,8 @@ public abstract class Contraption {
|
|||
nbt.remove("y");
|
||||
nbt.remove("z");
|
||||
|
||||
if (tileentity instanceof FluidTankTileEntity && nbt.contains("Controller"))
|
||||
if ((tileentity instanceof FluidTankTileEntity || tileentity instanceof VaultTileEntity)
|
||||
&& nbt.contains("Controller"))
|
||||
nbt.put("Controller",
|
||||
NbtUtils.writeBlockPos(toLocalPos(NbtUtils.readBlockPos(nbt.getCompound("Controller")))));
|
||||
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
package com.simibubi.create.content.logistics.block.vault;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.content.contraptions.wrench.IWrenchable;
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
import com.simibubi.create.foundation.item.ItemHelper;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
import net.minecraft.core.Direction.AxisDirection;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.item.context.UseOnContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Mirror;
|
||||
import net.minecraft.world.level.block.Rotation;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition.Builder;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||
import net.minecraft.world.level.block.state.properties.Property;
|
||||
import net.minecraftforge.common.util.ForgeSoundType;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
|
||||
public class VaultBlock extends Block implements IWrenchable, ITE<VaultTileEntity> {
|
||||
|
||||
public static final Property<Axis> HORIZONTAL_AXIS = BlockStateProperties.HORIZONTAL_AXIS;
|
||||
public static final BooleanProperty LARGE = BooleanProperty.create("large");
|
||||
|
||||
public VaultBlock(Properties p_i48440_1_) {
|
||||
super(p_i48440_1_);
|
||||
registerDefaultState(defaultBlockState().setValue(LARGE, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(Builder<Block, BlockState> pBuilder) {
|
||||
pBuilder.add(HORIZONTAL_AXIS, LARGE);
|
||||
super.createBlockStateDefinition(pBuilder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext pContext) {
|
||||
if (pContext.getPlayer() == null || !pContext.getPlayer()
|
||||
.isSteppingCarefully()) {
|
||||
BlockState placedOn = pContext.getLevel()
|
||||
.getBlockState(pContext.getClickedPos()
|
||||
.relative(pContext.getClickedFace()
|
||||
.getOpposite()));
|
||||
Axis preferredAxis = getVaultBlockAxis(placedOn);
|
||||
if (preferredAxis != null)
|
||||
return this.defaultBlockState()
|
||||
.setValue(HORIZONTAL_AXIS, preferredAxis);
|
||||
}
|
||||
return this.defaultBlockState()
|
||||
.setValue(HORIZONTAL_AXIS, pContext.getHorizontalDirection()
|
||||
.getAxis());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlace(BlockState pState, Level pLevel, BlockPos pPos, BlockState pOldState, boolean pIsMoving) {
|
||||
if (pOldState.getBlock() == pState.getBlock())
|
||||
return;
|
||||
if (pIsMoving)
|
||||
return;
|
||||
withTileEntityDo(pLevel, pPos, VaultTileEntity::updateConnectivity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult onWrenched(BlockState state, UseOnContext context) {
|
||||
if (context.getClickedFace()
|
||||
.getAxis()
|
||||
.isVertical()) {
|
||||
BlockEntity te = context.getLevel()
|
||||
.getBlockEntity(context.getClickedPos());
|
||||
if (te instanceof VaultTileEntity) {
|
||||
VaultTileEntity vault = (VaultTileEntity) te;
|
||||
VaultConnectivityHandler.splitVault(vault);
|
||||
vault.removeController(true);
|
||||
}
|
||||
state = state.setValue(LARGE, false);
|
||||
}
|
||||
InteractionResult onWrenched = IWrenchable.super.onWrenched(state, context);
|
||||
return onWrenched;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean pIsMoving) {
|
||||
if (state.hasBlockEntity() && (state.getBlock() != newState.getBlock() || !newState.hasBlockEntity())) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
if (!(te instanceof VaultTileEntity))
|
||||
return;
|
||||
VaultTileEntity tankTE = (VaultTileEntity) te;
|
||||
ItemHelper.dropContents(world, pos, tankTE.inventory);
|
||||
world.removeBlockEntity(pos);
|
||||
VaultConnectivityHandler.splitVault(tankTE);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isVault(BlockState state) {
|
||||
return AllBlocks.ITEM_VAULT.has(state);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Axis getVaultBlockAxis(BlockState state) {
|
||||
if (!isVault(state))
|
||||
return null;
|
||||
return state.getValue(HORIZONTAL_AXIS);
|
||||
}
|
||||
|
||||
public static boolean isLarge(BlockState state) {
|
||||
if (!isVault(state))
|
||||
return false;
|
||||
return state.getValue(LARGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState rotate(BlockState state, Rotation rot) {
|
||||
Axis axis = state.getValue(HORIZONTAL_AXIS);
|
||||
return state.setValue(HORIZONTAL_AXIS, rot.rotate(Direction.fromAxisAndDirection(axis, AxisDirection.POSITIVE))
|
||||
.getAxis());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState mirror(BlockState state, Mirror mirrorIn) {
|
||||
return state;
|
||||
}
|
||||
|
||||
// Vaults are less noisy when placed in batch
|
||||
public static final SoundType SILENCED_METAL =
|
||||
new ForgeSoundType(0.1F, 1.5F, () -> SoundEvents.NETHERITE_BLOCK_BREAK, () -> SoundEvents.NETHERITE_BLOCK_STEP,
|
||||
() -> SoundEvents.NETHERITE_BLOCK_PLACE, () -> SoundEvents.NETHERITE_BLOCK_HIT,
|
||||
() -> SoundEvents.NETHERITE_BLOCK_FALL);
|
||||
|
||||
@Override
|
||||
public SoundType getSoundType(BlockState state, LevelReader world, BlockPos pos, Entity entity) {
|
||||
SoundType soundType = super.getSoundType(state, world, pos, entity);
|
||||
if (entity != null && entity.getPersistentData()
|
||||
.contains("SilenceVaultSound"))
|
||||
return SILENCED_METAL;
|
||||
return soundType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAnalogOutputSignal(BlockState p_149740_1_) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAnalogOutputSignal(BlockState pState, Level pLevel, BlockPos pPos) {
|
||||
return getTileEntityOptional(pLevel, pPos)
|
||||
.map(vte -> vte.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY))
|
||||
.map(lo -> lo.map(ItemHelper::calcRedstoneFromInventory)
|
||||
.orElse(0))
|
||||
.orElse(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntityType<? extends VaultTileEntity> getTileEntityType() {
|
||||
return AllTileEntities.ITEM_VAULT.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<VaultTileEntity> getTileEntityClass() {
|
||||
return VaultTileEntity.class;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package com.simibubi.create.content.logistics.block.vault;
|
||||
|
||||
import com.simibubi.create.AllSpriteShifts;
|
||||
import com.simibubi.create.foundation.block.connected.CTSpriteShiftEntry;
|
||||
import com.simibubi.create.foundation.block.connected.ConnectedTextureBehaviour;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
import net.minecraft.core.Direction.AxisDirection;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class VaultCTBehaviour extends ConnectedTextureBehaviour {
|
||||
|
||||
@Override
|
||||
public CTSpriteShiftEntry get(BlockState state, Direction direction) {
|
||||
Axis vaultBlockAxis = VaultBlock.getVaultBlockAxis(state);
|
||||
boolean small = !VaultBlock.isLarge(state);
|
||||
if (vaultBlockAxis == null)
|
||||
return null;
|
||||
|
||||
if (direction.getAxis() == vaultBlockAxis)
|
||||
return AllSpriteShifts.VAULT_FRONT.get(small);
|
||||
if (direction == Direction.UP)
|
||||
return AllSpriteShifts.VAULT_TOP.get(small);
|
||||
if (direction == Direction.DOWN)
|
||||
return AllSpriteShifts.VAULT_BOTTOM.get(small);
|
||||
|
||||
return AllSpriteShifts.VAULT_SIDE.get(small);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Direction getUpDirection(BlockAndTintGetter reader, BlockPos pos, BlockState state, Direction face) {
|
||||
Axis vaultBlockAxis = VaultBlock.getVaultBlockAxis(state);
|
||||
boolean alongX = vaultBlockAxis == Axis.X;
|
||||
if (face.getAxis()
|
||||
.isVertical() && alongX)
|
||||
return super.getUpDirection(reader, pos, state, face).getClockWise();
|
||||
if (face.getAxis() == vaultBlockAxis || face.getAxis()
|
||||
.isVertical())
|
||||
return super.getUpDirection(reader, pos, state, face);
|
||||
return Direction.fromAxisAndDirection(vaultBlockAxis, alongX ? AxisDirection.POSITIVE : AxisDirection.NEGATIVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Direction getRightDirection(BlockAndTintGetter reader, BlockPos pos, BlockState state, Direction face) {
|
||||
Axis vaultBlockAxis = VaultBlock.getVaultBlockAxis(state);
|
||||
if (face.getAxis()
|
||||
.isVertical() && vaultBlockAxis == Axis.X)
|
||||
return super.getRightDirection(reader, pos, state, face).getClockWise();
|
||||
if (face.getAxis() == vaultBlockAxis || face.getAxis()
|
||||
.isVertical())
|
||||
return super.getRightDirection(reader, pos, state, face);
|
||||
return Direction.fromAxisAndDirection(Axis.Y, face.getAxisDirection());
|
||||
}
|
||||
|
||||
public boolean buildContextForOccludedDirections() {
|
||||
return super.buildContextForOccludedDirections();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean connectsTo(BlockState state, BlockState other, BlockAndTintGetter reader, BlockPos pos,
|
||||
BlockPos otherPos, Direction face) {
|
||||
return state == other && VaultConnectivityHandler.isConnected(reader, pos, otherPos);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,329 @@
|
|||
package com.simibubi.create.content.logistics.block.vault;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
import net.minecraft.core.Direction.AxisDirection;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class VaultConnectivityHandler {
|
||||
|
||||
public static void formVaults(VaultTileEntity te) {
|
||||
VaultSearchCache cache = new VaultSearchCache();
|
||||
List<VaultTileEntity> frontier = new ArrayList<>();
|
||||
frontier.add(te);
|
||||
formVaults(te.getType(), te.getLevel(), cache, frontier);
|
||||
}
|
||||
|
||||
private static void formVaults(BlockEntityType<?> type, BlockGetter world, VaultSearchCache cache,
|
||||
List<VaultTileEntity> frontier) {
|
||||
PriorityQueue<Pair<Integer, VaultTileEntity>> creationQueue = makeCreationQueue();
|
||||
Set<BlockPos> visited = new HashSet<>();
|
||||
|
||||
int minY = Integer.MAX_VALUE;
|
||||
for (VaultTileEntity fluidTankTileEntity : frontier) {
|
||||
BlockPos pos = fluidTankTileEntity.getBlockPos();
|
||||
minY = Math.min(pos.getY(), minY);
|
||||
}
|
||||
|
||||
minY -= 3;
|
||||
|
||||
while (!frontier.isEmpty()) {
|
||||
VaultTileEntity tank = frontier.remove(0);
|
||||
BlockPos tankPos = tank.getBlockPos();
|
||||
if (visited.contains(tankPos))
|
||||
continue;
|
||||
|
||||
visited.add(tankPos);
|
||||
|
||||
int amount = tryToFormNewVault(tank, cache, true);
|
||||
if (amount > 1)
|
||||
creationQueue.add(Pair.of(amount, tank));
|
||||
|
||||
for (Axis axis : Iterate.axes) {
|
||||
Direction d = Direction.fromAxisAndDirection(axis, AxisDirection.NEGATIVE);
|
||||
BlockPos next = tankPos.relative(d);
|
||||
|
||||
if (next.getY() <= minY)
|
||||
continue;
|
||||
if (visited.contains(next))
|
||||
continue;
|
||||
VaultTileEntity nextTank = vaultAt(type, world, next);
|
||||
if (nextTank == null)
|
||||
continue;
|
||||
if (nextTank.isRemoved())
|
||||
continue;
|
||||
frontier.add(nextTank);
|
||||
}
|
||||
}
|
||||
|
||||
visited.clear();
|
||||
|
||||
while (!creationQueue.isEmpty()) {
|
||||
Pair<Integer, VaultTileEntity> next = creationQueue.poll();
|
||||
VaultTileEntity toCreate = next.getValue();
|
||||
if (visited.contains(toCreate.getBlockPos()))
|
||||
continue;
|
||||
visited.add(toCreate.getBlockPos());
|
||||
tryToFormNewVault(toCreate, cache, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void splitVault(VaultTileEntity te) {
|
||||
splitVaultAndInvalidate(te, null, false);
|
||||
}
|
||||
|
||||
private static int tryToFormNewVault(VaultTileEntity te, VaultSearchCache cache, boolean simulate) {
|
||||
int bestWidth = 1;
|
||||
int bestAmount = -1;
|
||||
|
||||
if (!te.isController())
|
||||
return 0;
|
||||
|
||||
for (int w = 1; w <= 3; w++) {
|
||||
int amount = tryToFormNewVaultOfRadius(te, w, cache, true);
|
||||
if (amount < bestAmount)
|
||||
continue;
|
||||
bestWidth = w;
|
||||
bestAmount = amount;
|
||||
}
|
||||
|
||||
if (!simulate) {
|
||||
if (te.radius == bestWidth && te.radius * te.radius * te.length == bestAmount)
|
||||
return bestAmount;
|
||||
|
||||
splitVaultAndInvalidate(te, cache, false);
|
||||
tryToFormNewVaultOfRadius(te, bestWidth, cache, simulate);
|
||||
te.updateConnectivity = false;
|
||||
te.radius = bestWidth;
|
||||
te.length = bestAmount / bestWidth / bestWidth;
|
||||
|
||||
BlockState state = te.getBlockState();
|
||||
if (VaultBlock.isVault(state))
|
||||
te.getLevel()
|
||||
.setBlock(te.getBlockPos(), state.setValue(VaultBlock.LARGE, te.radius > 2), 22);
|
||||
|
||||
te.itemCapability.invalidate();
|
||||
te.setChanged();
|
||||
}
|
||||
|
||||
return bestAmount;
|
||||
}
|
||||
|
||||
private static int tryToFormNewVaultOfRadius(VaultTileEntity te, int width, VaultSearchCache cache,
|
||||
boolean simulate) {
|
||||
int amount = 0;
|
||||
int height = 0;
|
||||
BlockEntityType<?> type = te.getType();
|
||||
Level world = te.getLevel();
|
||||
BlockPos origin = te.getBlockPos();
|
||||
boolean alongZ = VaultBlock.getVaultBlockAxis(te.getBlockState()) == Axis.Z;
|
||||
|
||||
Search:
|
||||
|
||||
for (int yOffset = 0; yOffset < VaultTileEntity.getMaxLength(width); yOffset++) {
|
||||
for (int xOffset = 0; xOffset < width; xOffset++) {
|
||||
for (int zOffset = 0; zOffset < width; zOffset++) {
|
||||
|
||||
BlockPos pos =
|
||||
alongZ ? origin.offset(xOffset, zOffset, yOffset) : origin.offset(yOffset, xOffset, zOffset);
|
||||
Optional<VaultTileEntity> tank = cache.getOrCache(type, world, pos);
|
||||
if (!tank.isPresent())
|
||||
break Search;
|
||||
|
||||
VaultTileEntity controller = tank.get();
|
||||
int otherWidth = controller.radius;
|
||||
if (otherWidth > width)
|
||||
break Search;
|
||||
if (otherWidth == width && controller.length == VaultTileEntity.getMaxLength(width))
|
||||
break Search;
|
||||
if ((VaultBlock.getVaultBlockAxis(controller.getBlockState()) == Axis.Z) != alongZ)
|
||||
break Search;
|
||||
|
||||
BlockPos controllerPos = controller.getBlockPos();
|
||||
if (!controllerPos.equals(origin)) {
|
||||
if (alongZ && controllerPos.getX() < origin.getX())
|
||||
break Search;
|
||||
if (controllerPos.getY() < origin.getY())
|
||||
break Search;
|
||||
if (!alongZ && controllerPos.getZ() < origin.getZ())
|
||||
break Search;
|
||||
if (alongZ && controllerPos.getX() + otherWidth > origin.getX() + width)
|
||||
break Search;
|
||||
if (controllerPos.getY() + otherWidth > origin.getY() + width)
|
||||
break Search;
|
||||
if (!alongZ && controllerPos.getZ() + otherWidth > origin.getZ() + width)
|
||||
break Search;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
amount += width * width;
|
||||
height++;
|
||||
}
|
||||
|
||||
if (simulate)
|
||||
return amount;
|
||||
|
||||
for (int yOffset = 0; yOffset < height; yOffset++) {
|
||||
for (int xOffset = 0; xOffset < width; xOffset++) {
|
||||
for (int zOffset = 0; zOffset < width; zOffset++) {
|
||||
BlockPos pos =
|
||||
alongZ ? origin.offset(xOffset, zOffset, yOffset) : origin.offset(yOffset, xOffset, zOffset);
|
||||
VaultTileEntity tank = vaultAt(type, world, pos);
|
||||
if (tank == te)
|
||||
continue;
|
||||
|
||||
splitVaultAndInvalidate(tank, cache, false);
|
||||
tank.setController(origin);
|
||||
tank.updateConnectivity = false;
|
||||
cache.put(pos, te);
|
||||
|
||||
BlockState state = world.getBlockState(pos);
|
||||
if (!VaultBlock.isVault(state))
|
||||
continue;
|
||||
state = state.setValue(VaultBlock.LARGE, width > 2);
|
||||
world.setBlock(pos, state, 22);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
private static void splitVaultAndInvalidate(VaultTileEntity te, @Nullable VaultSearchCache cache,
|
||||
boolean tryReconnect) {
|
||||
// tryReconnect helps whenever only few tanks have been removed
|
||||
|
||||
te = te.getControllerTE();
|
||||
if (te == null)
|
||||
return;
|
||||
|
||||
int height = te.length;
|
||||
int width = te.radius;
|
||||
BlockState state = te.getBlockState();
|
||||
boolean alongZ = VaultBlock.getVaultBlockAxis(state) == Axis.Z;
|
||||
if (width == 1 && height == 1)
|
||||
return;
|
||||
|
||||
Level world = te.getLevel();
|
||||
BlockPos origin = te.getBlockPos();
|
||||
List<VaultTileEntity> frontier = new ArrayList<>();
|
||||
|
||||
for (int yOffset = 0; yOffset < height; yOffset++) {
|
||||
for (int xOffset = 0; xOffset < width; xOffset++) {
|
||||
for (int zOffset = 0; zOffset < width; zOffset++) {
|
||||
|
||||
BlockPos pos =
|
||||
alongZ ? origin.offset(xOffset, zOffset, yOffset) : origin.offset(yOffset, xOffset, zOffset);
|
||||
VaultTileEntity tankAt = vaultAt(te.getType(), world, pos);
|
||||
if (tankAt == null)
|
||||
continue;
|
||||
if (!tankAt.getController()
|
||||
.equals(origin))
|
||||
continue;
|
||||
|
||||
tankAt.removeController(true);
|
||||
|
||||
if (tryReconnect) {
|
||||
frontier.add(tankAt);
|
||||
tankAt.updateConnectivity = false;
|
||||
}
|
||||
if (cache != null)
|
||||
cache.put(pos, tankAt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
te.itemCapability.invalidate();
|
||||
if (tryReconnect)
|
||||
formVaults(te.getType(), world, cache == null ? new VaultSearchCache() : cache, frontier);
|
||||
}
|
||||
|
||||
private static PriorityQueue<Pair<Integer, VaultTileEntity>> makeCreationQueue() {
|
||||
return new PriorityQueue<>(new Comparator<Pair<Integer, VaultTileEntity>>() {
|
||||
@Override
|
||||
public int compare(Pair<Integer, VaultTileEntity> o1, Pair<Integer, VaultTileEntity> o2) {
|
||||
return o2.getKey() - o1.getKey();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static VaultTileEntity vaultAt(BlockEntityType<?> type, BlockGetter world, BlockPos pos) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
if (te instanceof VaultTileEntity && te.getType() == type)
|
||||
return (VaultTileEntity) te;
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class VaultSearchCache {
|
||||
Map<BlockPos, Optional<VaultTileEntity>> controllerMap;
|
||||
|
||||
public VaultSearchCache() {
|
||||
controllerMap = new HashMap<>();
|
||||
}
|
||||
|
||||
void put(BlockPos pos, VaultTileEntity target) {
|
||||
controllerMap.put(pos, Optional.of(target));
|
||||
}
|
||||
|
||||
void putEmpty(BlockPos pos) {
|
||||
controllerMap.put(pos, Optional.empty());
|
||||
}
|
||||
|
||||
boolean hasVisited(BlockPos pos) {
|
||||
return controllerMap.containsKey(pos);
|
||||
}
|
||||
|
||||
Optional<VaultTileEntity> getOrCache(BlockEntityType<?> type, BlockGetter world, BlockPos pos) {
|
||||
if (hasVisited(pos))
|
||||
return controllerMap.get(pos);
|
||||
VaultTileEntity tankAt = vaultAt(type, world, pos);
|
||||
if (tankAt == null) {
|
||||
putEmpty(pos);
|
||||
return Optional.empty();
|
||||
}
|
||||
VaultTileEntity controller = tankAt.getControllerTE();
|
||||
if (controller == null) {
|
||||
putEmpty(pos);
|
||||
return Optional.empty();
|
||||
}
|
||||
put(pos, controller);
|
||||
return Optional.of(controller);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static boolean isConnected(BlockGetter world, BlockPos tankPos, BlockPos otherTankPos) {
|
||||
BlockEntity te1 = world.getBlockEntity(tankPos);
|
||||
BlockEntity te2 = world.getBlockEntity(otherTankPos);
|
||||
if (!(te1 instanceof VaultTileEntity) || !(te2 instanceof VaultTileEntity))
|
||||
return false;
|
||||
return ((VaultTileEntity) te1).getController()
|
||||
.equals(((VaultTileEntity) te2).getController());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
package com.simibubi.create.content.logistics.block.vault;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
import net.minecraft.core.Direction.AxisDirection;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class VaultItem extends BlockItem {
|
||||
|
||||
public VaultItem(Block p_i48527_1_, Properties p_i48527_2_) {
|
||||
super(p_i48527_1_, p_i48527_2_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult place(BlockPlaceContext ctx) {
|
||||
InteractionResult initialResult = super.place(ctx);
|
||||
if (!initialResult.consumesAction())
|
||||
return initialResult;
|
||||
tryMultiPlace(ctx);
|
||||
return initialResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updateCustomBlockEntityTag(BlockPos p_195943_1_, Level p_195943_2_, Player p_195943_3_,
|
||||
ItemStack p_195943_4_, BlockState p_195943_5_) {
|
||||
MinecraftServer minecraftserver = p_195943_2_.getServer();
|
||||
if (minecraftserver == null)
|
||||
return false;
|
||||
CompoundTag nbt = p_195943_4_.getTagElement("BlockEntityTag");
|
||||
if (nbt != null) {
|
||||
nbt.remove("Length");
|
||||
nbt.remove("Size");
|
||||
nbt.remove("Controller");
|
||||
nbt.remove("LastKnownPos");
|
||||
}
|
||||
return super.updateCustomBlockEntityTag(p_195943_1_, p_195943_2_, p_195943_3_, p_195943_4_, p_195943_5_);
|
||||
}
|
||||
|
||||
private void tryMultiPlace(BlockPlaceContext ctx) {
|
||||
Player player = ctx.getPlayer();
|
||||
if (player == null)
|
||||
return;
|
||||
if (player.isSteppingCarefully())
|
||||
return;
|
||||
Direction face = ctx.getClickedFace();
|
||||
ItemStack stack = ctx.getItemInHand();
|
||||
Level world = ctx.getLevel();
|
||||
BlockPos pos = ctx.getClickedPos();
|
||||
BlockPos placedOnPos = pos.relative(face.getOpposite());
|
||||
BlockState placedOnState = world.getBlockState(placedOnPos);
|
||||
|
||||
if (!VaultBlock.isVault(placedOnState))
|
||||
return;
|
||||
VaultTileEntity tankAt = VaultConnectivityHandler.vaultAt(AllTileEntities.ITEM_VAULT.get(), world, placedOnPos);
|
||||
if (tankAt == null)
|
||||
return;
|
||||
VaultTileEntity controllerTE = tankAt.getControllerTE();
|
||||
if (controllerTE == null)
|
||||
return;
|
||||
|
||||
int width = controllerTE.radius;
|
||||
if (width == 1)
|
||||
return;
|
||||
|
||||
int tanksToPlace = 0;
|
||||
Axis vaultBlockAxis = VaultBlock.getVaultBlockAxis(placedOnState);
|
||||
if (vaultBlockAxis == null)
|
||||
return;
|
||||
if (face.getAxis() != vaultBlockAxis)
|
||||
return;
|
||||
|
||||
Direction vaultFacing = Direction.fromAxisAndDirection(vaultBlockAxis, AxisDirection.POSITIVE);
|
||||
BlockPos startPos = face == vaultFacing.getOpposite() ? controllerTE.getBlockPos()
|
||||
.relative(vaultFacing.getOpposite())
|
||||
: controllerTE.getBlockPos()
|
||||
.relative(vaultFacing, controllerTE.length);
|
||||
|
||||
if (VecHelper.getCoordinate(startPos, vaultBlockAxis) != VecHelper.getCoordinate(pos, vaultBlockAxis))
|
||||
return;
|
||||
|
||||
for (int xOffset = 0; xOffset < width; xOffset++) {
|
||||
for (int zOffset = 0; zOffset < width; zOffset++) {
|
||||
BlockPos offsetPos = vaultBlockAxis == Axis.X ? startPos.offset(0, xOffset, zOffset)
|
||||
: startPos.offset(xOffset, zOffset, 0);
|
||||
BlockState blockState = world.getBlockState(offsetPos);
|
||||
if (VaultBlock.isVault(blockState))
|
||||
continue;
|
||||
if (!blockState.getMaterial()
|
||||
.isReplaceable())
|
||||
return;
|
||||
tanksToPlace++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!player.isCreative() && stack.getCount() < tanksToPlace)
|
||||
return;
|
||||
|
||||
for (int xOffset = 0; xOffset < width; xOffset++) {
|
||||
for (int zOffset = 0; zOffset < width; zOffset++) {
|
||||
BlockPos offsetPos = vaultBlockAxis == Axis.X ? startPos.offset(0, xOffset, zOffset)
|
||||
: startPos.offset(xOffset, zOffset, 0);
|
||||
BlockState blockState = world.getBlockState(offsetPos);
|
||||
if (VaultBlock.isVault(blockState))
|
||||
continue;
|
||||
BlockPlaceContext context = BlockPlaceContext.at(ctx, offsetPos, face);
|
||||
player.getPersistentData()
|
||||
.putBoolean("SilenceVaultSound", true);
|
||||
super.place(context);
|
||||
player.getPersistentData()
|
||||
.remove("SilenceVaultSound");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,245 @@
|
|||
package com.simibubi.create.content.logistics.block.vault;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
||||
|
||||
public class VaultTileEntity extends SmartTileEntity {
|
||||
|
||||
protected LazyOptional<IItemHandler> itemCapability;
|
||||
|
||||
protected ItemStackHandler inventory;
|
||||
protected BlockPos controller;
|
||||
protected BlockPos lastKnownPos;
|
||||
protected boolean updateConnectivity;
|
||||
protected int radius;
|
||||
protected int length;
|
||||
protected Axis axis;
|
||||
|
||||
public VaultTileEntity(BlockEntityType<?> tileEntityTypeIn, BlockPos pos, BlockState state) {
|
||||
super(tileEntityTypeIn, pos, state);
|
||||
|
||||
inventory = new ItemStackHandler(AllConfigs.SERVER.logistics.vaultCapacity.get()) {
|
||||
@Override
|
||||
protected void onContentsChanged(int slot) {
|
||||
super.onContentsChanged(slot);
|
||||
updateComparators();
|
||||
}
|
||||
};
|
||||
|
||||
itemCapability = LazyOptional.empty();
|
||||
radius = 1;
|
||||
length = 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {}
|
||||
|
||||
protected void updateConnectivity() {
|
||||
updateConnectivity = false;
|
||||
if (level.isClientSide())
|
||||
return;
|
||||
if (!isController())
|
||||
return;
|
||||
VaultConnectivityHandler.formVaults(this);
|
||||
}
|
||||
|
||||
protected void updateComparators() {
|
||||
VaultTileEntity controllerTE = getControllerTE();
|
||||
if (controllerTE == null)
|
||||
return;
|
||||
|
||||
BlockPos pos = controllerTE.getBlockPos();
|
||||
for (int y = 0; y < controllerTE.radius; y++) {
|
||||
for (int z = 0; z < (controllerTE.axis == Axis.X ? controllerTE.radius : controllerTE.length); z++) {
|
||||
for (int x = 0; x < (controllerTE.axis == Axis.Z ? controllerTE.radius : controllerTE.length); x++) {
|
||||
level.updateNeighbourForOutputSignal(pos.offset(x, y, z), getBlockState().getBlock());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
if (lastKnownPos == null)
|
||||
lastKnownPos = getBlockPos();
|
||||
else if (!lastKnownPos.equals(worldPosition) && worldPosition != null) {
|
||||
onPositionChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
if (updateConnectivity)
|
||||
updateConnectivity();
|
||||
}
|
||||
|
||||
public boolean isController() {
|
||||
return controller == null || worldPosition.getX() == controller.getX()
|
||||
&& worldPosition.getY() == controller.getY() && worldPosition.getZ() == controller.getZ();
|
||||
}
|
||||
|
||||
private void onPositionChanged() {
|
||||
removeController(true);
|
||||
lastKnownPos = worldPosition;
|
||||
}
|
||||
|
||||
public VaultTileEntity getControllerTE() {
|
||||
if (isController())
|
||||
return this;
|
||||
BlockEntity tileEntity = level.getBlockEntity(controller);
|
||||
if (tileEntity instanceof VaultTileEntity)
|
||||
return (VaultTileEntity) tileEntity;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void removeController(boolean keepContents) {
|
||||
if (level.isClientSide())
|
||||
return;
|
||||
updateConnectivity = true;
|
||||
controller = null;
|
||||
radius = 1;
|
||||
length = 1;
|
||||
|
||||
BlockState state = getBlockState();
|
||||
if (VaultBlock.isVault(state)) {
|
||||
state = state.setValue(VaultBlock.LARGE, false);
|
||||
getLevel().setBlock(worldPosition, state, 22);
|
||||
}
|
||||
|
||||
itemCapability.invalidate();
|
||||
setChanged();
|
||||
sendData();
|
||||
}
|
||||
|
||||
public void setController(BlockPos controller) {
|
||||
if (level.isClientSide())
|
||||
return;
|
||||
if (controller.equals(this.controller))
|
||||
return;
|
||||
this.controller = controller;
|
||||
itemCapability.invalidate();
|
||||
setChanged();
|
||||
sendData();
|
||||
}
|
||||
|
||||
public BlockPos getController() {
|
||||
return isController() ? worldPosition : controller;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fromTag(CompoundTag compound, boolean clientPacket) {
|
||||
super.fromTag(compound, clientPacket);
|
||||
|
||||
BlockPos controllerBefore = controller;
|
||||
int prevSize = radius;
|
||||
int prevLength = length;
|
||||
|
||||
updateConnectivity = compound.contains("Uninitialized");
|
||||
controller = null;
|
||||
lastKnownPos = null;
|
||||
|
||||
if (compound.contains("LastKnownPos"))
|
||||
lastKnownPos = NbtUtils.readBlockPos(compound.getCompound("LastKnownPos"));
|
||||
if (compound.contains("Controller"))
|
||||
controller = NbtUtils.readBlockPos(compound.getCompound("Controller"));
|
||||
|
||||
if (isController()) {
|
||||
radius = compound.getInt("Size");
|
||||
length = compound.getInt("Length");
|
||||
}
|
||||
|
||||
if (!clientPacket) {
|
||||
inventory.deserializeNBT(compound.getCompound("Inventory"));
|
||||
return;
|
||||
}
|
||||
|
||||
boolean changeOfController =
|
||||
controllerBefore == null ? controller != null : !controllerBefore.equals(controller);
|
||||
if (hasLevel() && (changeOfController || prevSize != radius || prevLength != length))
|
||||
level.setBlocksDirty(getBlockPos(), Blocks.AIR.defaultBlockState(), getBlockState());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void write(CompoundTag compound, boolean clientPacket) {
|
||||
if (updateConnectivity)
|
||||
compound.putBoolean("Uninitialized", true);
|
||||
if (lastKnownPos != null)
|
||||
compound.put("LastKnownPos", NbtUtils.writeBlockPos(lastKnownPos));
|
||||
if (!isController())
|
||||
compound.put("Controller", NbtUtils.writeBlockPos(controller));
|
||||
if (isController()) {
|
||||
compound.putInt("Size", radius);
|
||||
compound.putInt("Length", length);
|
||||
}
|
||||
|
||||
super.write(compound, clientPacket);
|
||||
|
||||
if (!clientPacket)
|
||||
compound.put("Inventory", inventory.serializeNBT());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
|
||||
if (isItemHandlerCap(cap)) {
|
||||
initCapability();
|
||||
return itemCapability.cast();
|
||||
}
|
||||
return super.getCapability(cap, side);
|
||||
}
|
||||
|
||||
private void initCapability() {
|
||||
if (itemCapability.isPresent())
|
||||
return;
|
||||
if (!isController()) {
|
||||
VaultTileEntity controllerTE = getControllerTE();
|
||||
if (controllerTE == null)
|
||||
return;
|
||||
controllerTE.initCapability();
|
||||
itemCapability = controllerTE.itemCapability;
|
||||
return;
|
||||
}
|
||||
|
||||
boolean alongZ = VaultBlock.getVaultBlockAxis(getBlockState()) == Axis.Z;
|
||||
IItemHandlerModifiable[] invs = new IItemHandlerModifiable[length * radius * radius];
|
||||
for (int yOffset = 0; yOffset < length; yOffset++) {
|
||||
for (int xOffset = 0; xOffset < radius; xOffset++) {
|
||||
for (int zOffset = 0; zOffset < radius; zOffset++) {
|
||||
BlockPos vaultPos = alongZ ? worldPosition.offset(xOffset, zOffset, yOffset)
|
||||
: worldPosition.offset(yOffset, xOffset, zOffset);
|
||||
VaultTileEntity vaultAt =
|
||||
VaultConnectivityHandler.vaultAt(AllTileEntities.ITEM_VAULT.get(), level, vaultPos);
|
||||
invs[yOffset * radius * radius + xOffset * radius + zOffset] =
|
||||
vaultAt != null ? vaultAt.inventory : new ItemStackHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CombinedInvWrapper combinedInvWrapper = new CombinedInvWrapper(invs);
|
||||
itemCapability = LazyOptional.of(() -> combinedInvWrapper);
|
||||
}
|
||||
|
||||
public static int getMaxLength(int radius) {
|
||||
return radius * 3;
|
||||
}
|
||||
|
||||
}
|
|
@ -7,6 +7,7 @@ public class CLogistics extends ConfigBase {
|
|||
public final ConfigInt psiTimeout = i(20, 1, "psiTimeout", Comments.psiTimeout);
|
||||
public final ConfigInt mechanicalArmRange = i(5, 1, "mechanicalArmRange", Comments.mechanicalArmRange);
|
||||
public final ConfigInt linkRange = i(128, 1, "linkRange", Comments.linkRange);
|
||||
public final ConfigInt vaultCapacity = i(27, 1, "vaultCapacity", Comments.vaultCapacity);
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
|
@ -22,6 +23,7 @@ public class CLogistics extends ConfigBase {
|
|||
static String psiTimeout =
|
||||
"The amount of ticks a portable storage interface waits for transfers until letting contraptions move along.";
|
||||
static String mechanicalArmRange = "Maximum distance in blocks a Mechanical Arm can reach across.";
|
||||
static String vaultCapacity = "The total amount of stacks a vault can hold per block in size.";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,6 +30,10 @@ public class Couple<T> extends Pair<T, T> implements Iterable<T> {
|
|||
return new Couple<>(factory.get(), factory.get());
|
||||
}
|
||||
|
||||
public static <T> Couple<T> createWithContext(Function<Boolean, T> factory) {
|
||||
return new Couple<>(factory.apply(true), factory.apply(false));
|
||||
}
|
||||
|
||||
public T get(boolean first) {
|
||||
return first ? getFirst() : getSecond();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"credit": "Made with Blockbench",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"0": "create:block/vault_bottom",
|
||||
"1": "create:block/vault_front",
|
||||
"2": "create:block/vault_side",
|
||||
"3": "create:block/vault_top",
|
||||
"particle": "create:block/vault_bottom"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [0, 0, 0],
|
||||
"to": [16, 16, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 16, 16], "texture": "#1"},
|
||||
"east": {"uv": [0, 0, 16, 16], "rotation": 90, "texture": "#2"},
|
||||
"south": {"uv": [0, 0, 16, 16], "texture": "#1"},
|
||||
"west": {"uv": [0, 16, 16, 0], "rotation": 90, "texture": "#2"},
|
||||
"up": {"uv": [0, 0, 16, 16], "texture": "#3"},
|
||||
"down": {"uv": [0, 0, 16, 16], "texture": "#0"}
|
||||
}
|
||||
}
|
||||
],
|
||||
"display": {
|
||||
"gui": {
|
||||
"rotation": [ 30, 135, 0 ],
|
||||
"translation": [ 0, 0, 0],
|
||||
"scale":[ 0.625, 0.625, 0.625 ]
|
||||
}
|
||||
}
|
||||
}
|
BIN
src/main/resources/assets/create/textures/block/vault_bottom.png
Normal file
After Width: | Height: | Size: 241 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.9 KiB |
BIN
src/main/resources/assets/create/textures/block/vault_front.png
Normal file
After Width: | Height: | Size: 425 B |
After Width: | Height: | Size: 2 KiB |
After Width: | Height: | Size: 2.5 KiB |
BIN
src/main/resources/assets/create/textures/block/vault_side.png
Normal file
After Width: | Height: | Size: 289 B |
After Width: | Height: | Size: 2 KiB |
After Width: | Height: | Size: 1.9 KiB |
BIN
src/main/resources/assets/create/textures/block/vault_top.png
Normal file
After Width: | Height: | Size: 337 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.8 KiB |