Skip to content

Commit 1373e62

Browse files
committed
implement non-unique items in full
1 parent cdaac8a commit 1373e62

File tree

7 files changed

+83
-17
lines changed

7 files changed

+83
-17
lines changed

src/main/java/folk/sisby/inventory_tabs/TabManager.java

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public static void initScreen(MinecraftClient client, HandledScreen<?> screen) {
6262

6363
public static void finishOpeningScreen(ScreenHandler handler) {
6464
if (nextTab != null) {
65-
if (currentTab != null && currentTab != nextTab) currentTab.close();
65+
if (currentTab != null && currentTab != nextTab) currentTab.close(MinecraftClient.getInstance().player, MinecraftClient.getInstance().world, handler, MinecraftClient.getInstance().interactionManager);
6666
HandlerSlotUtil.tryPop(MinecraftClient.getInstance().player, MinecraftClient.getInstance().interactionManager, handler);
6767
currentTab = nextTab;
6868
setCurrentPage(tabPositions.isEmpty() ? 0 : tabs.indexOf(nextTab) / tabPositions.size());
@@ -71,7 +71,10 @@ public static void finishOpeningScreen(ScreenHandler handler) {
7171
}
7272

7373
public static void screenDiscarded() {
74-
currentTab = null;
74+
if (currentTab != null) {
75+
currentTab.close(MinecraftClient.getInstance().player, MinecraftClient.getInstance().world, MinecraftClient.getInstance().player != null ? MinecraftClient.getInstance().player.currentScreenHandler : null, MinecraftClient.getInstance().interactionManager);
76+
currentTab = null;
77+
}
7578
nextTab = null;
7679
currentPage = 0;
7780
}
@@ -91,20 +94,26 @@ public static void tick(ClientWorld world) {
9194
if (currentTab != null && !tabs.contains(currentTab)) currentTab = null;
9295
}
9396

97+
public static void openTabImmediate(Tab tab, ClientPlayerEntity player, ClientPlayerInteractionManager interactionManager, ClientWorld world) {
98+
nextTab = tab;
99+
HandlerSlotUtil.push(player, MinecraftClient.getInstance().interactionManager, currentScreen.getScreenHandler(), tab.isInstant());
100+
player.networkHandler.sendPacket(new CloseHandledScreenC2SPacket(currentScreen.getScreenHandler().syncId));
101+
tab.open(player, world, currentScreen.getScreenHandler(), interactionManager);
102+
if (tab.isInstant()) { // Instant screens don't have slot updates to wait for, so finish now.
103+
finishOpeningScreen(currentScreen.getScreenHandler());
104+
}
105+
}
106+
107+
94108
public static void openTab(Tab tab) {
95109
if (tab != currentTab) {
96110
ClientPlayerEntity player = MinecraftClient.getInstance().player;
97111
ClientPlayerInteractionManager interactionManager = MinecraftClient.getInstance().interactionManager;
98112
ClientPlayNetworkHandler networkHandler = MinecraftClient.getInstance().getNetworkHandler();
99113
if (player != null && interactionManager != null && networkHandler != null && player.getWorld() instanceof ClientWorld world) {
100114
if (!tab.shouldBeRemoved(world, false)) {
101-
nextTab = tab;
102-
HandlerSlotUtil.push(player, MinecraftClient.getInstance().interactionManager, currentScreen.getScreenHandler(), tab.isInstant());
103-
player.networkHandler.sendPacket(new CloseHandledScreenC2SPacket(currentScreen.getScreenHandler().syncId));
104-
tab.open(player, world, currentScreen.getScreenHandler(), interactionManager);
105-
if (tab.isInstant()) { // Instant screens don't have slot updates to wait for, so finish now.
106-
finishOpeningScreen(currentScreen.getScreenHandler());
107-
}
115+
if (tab.isBuffered()) openTabImmediate(new PlayerInventoryTab(), player, interactionManager, world);
116+
openTabImmediate(tab, player, interactionManager, world);
108117
}
109118
}
110119
}

src/main/java/folk/sisby/inventory_tabs/TabProviders.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import folk.sisby.inventory_tabs.providers.SimpleItemTabProvider;
2020
import folk.sisby.inventory_tabs.providers.SimpleStorageBlockTabProvider;
2121
import folk.sisby.inventory_tabs.providers.SneakEntityTabProvider;
22+
import folk.sisby.inventory_tabs.providers.SneakItemTabProvider;
2223
import folk.sisby.inventory_tabs.providers.TabProvider;
2324
import folk.sisby.inventory_tabs.providers.UniqueBlockTabProvider;
2425
import folk.sisby.inventory_tabs.providers.UniqueItemTabProvider;
@@ -61,6 +62,7 @@ public class TabProviders {
6162
public static final SimpleEntityTabProvider ENTITY_SIMPLE = register(InventoryTabs.id("entity_simple"), new SimpleEntityTabProvider());
6263

6364
public static final ItemTabProvider ITEM_UNIQUE = register(InventoryTabs.id("item_unique"), new UniqueItemTabProvider());
65+
public static final ItemTabProvider ITEM_SNEAK = register(InventoryTabs.id("item_sneak"), new SneakItemTabProvider());
6466
public static final ItemTabProvider ITEM_SIMPLE = register(InventoryTabs.id("item_simple"), new SimpleItemTabProvider());
6567

6668
// Single-Purpose

src/main/java/folk/sisby/inventory_tabs/providers/ItemTabProvider.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ public void addAvailableTabs(ClientPlayerEntity player, Consumer<Tab> addTab) {
3030
}
3131

3232
public Tab createTab(ItemStack stack, int slot) {
33-
return new ItemTab(stack, slot, preclusions, isUnique());
33+
return new ItemTab(stack, slot, preclusions, isUnique(), doSneakInteract());
34+
}
35+
36+
public boolean doSneakInteract() {
37+
return false;
3438
}
3539
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package folk.sisby.inventory_tabs.providers;
2+
3+
public class SneakItemTabProvider extends ItemTabProvider {
4+
@Override
5+
public int getRegistryPriority() {
6+
return 20;
7+
}
8+
9+
@Override
10+
public boolean doSneakInteract() {
11+
return true;
12+
}
13+
}

src/main/java/folk/sisby/inventory_tabs/tabs/ItemTab.java

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import net.minecraft.client.network.ClientPlayerInteractionManager;
88
import net.minecraft.client.world.ClientWorld;
99
import net.minecraft.item.ItemStack;
10+
import net.minecraft.network.packet.c2s.play.ClientCommandC2SPacket;
1011
import net.minecraft.screen.ScreenHandler;
1112
import net.minecraft.screen.slot.SlotActionType;
1213
import net.minecraft.text.Text;
@@ -21,23 +22,50 @@
2122

2223
public class ItemTab implements Tab {
2324
public final ItemStack stack;
24-
public final int slot;
25+
public int slot;
2526
public final boolean unique;
27+
public final boolean sneakInteract;
2628
public final Map<Identifier, Predicate<ItemStack>> preclusions;
29+
public ItemStack swappedStack = null;
30+
public int swappedSlot = -1;
2731

28-
public ItemTab(ItemStack stack, int slot, Map<Identifier, Predicate<ItemStack>> preclusions, boolean unique) {
32+
public ItemTab(ItemStack stack, int slot, Map<Identifier, Predicate<ItemStack>> preclusions, boolean unique, boolean sneakInteract) {
2933
this.stack = stack;
3034
this.slot = slot;
3135
this.preclusions = preclusions;
3236
this.unique = unique;
37+
this.sneakInteract = sneakInteract;
38+
}
39+
40+
public ItemTab(ItemStack stack, int slot, Map<Identifier, Predicate<ItemStack>> preclusions, boolean unique) {
41+
this(stack, slot, preclusions, unique, false);
42+
}
43+
44+
@Override
45+
public void close(ClientPlayerEntity player, ClientWorld world, ScreenHandler handler, ClientPlayerInteractionManager interactionManager) {
46+
if (player == null) return;
47+
if (swappedSlot != -1) {
48+
ItemStack inSwappedSlot = player.getInventory().getStack(swappedSlot);
49+
if (ItemStack.areEqual(inSwappedSlot, swappedStack)) {
50+
int slotIndex = handler.getSlotIndex(player.getInventory(), swappedSlot).getAsInt();
51+
interactionManager.clickSlot(handler.syncId, slotIndex, player.getInventory().selectedSlot, SlotActionType.SWAP, player);
52+
}
53+
}
3354
}
3455

3556
@Override
3657
public void open(ClientPlayerEntity player, ClientWorld world, ScreenHandler handler, ClientPlayerInteractionManager interactionManager) {
3758
int slotIndex = handler.getSlotIndex(player.getInventory(), slot).getAsInt();
38-
interactionManager.clickSlot(handler.syncId, slotIndex, player.getInventory().selectedSlot, SlotActionType.SWAP, player);
59+
if (slotIndex != player.getInventory().selectedSlot) interactionManager.clickSlot(handler.syncId, slotIndex, player.getInventory().selectedSlot, SlotActionType.SWAP, player);
60+
if (sneakInteract) player.networkHandler.sendPacket(new ClientCommandC2SPacket(player, ClientCommandC2SPacket.Mode.PRESS_SHIFT_KEY));
3961
interactionManager.interactItem(player, Hand.MAIN_HAND);
40-
HandlerSlotUtil.mainHandSwapSlot = slot;
62+
if (sneakInteract) player.networkHandler.sendPacket(new ClientCommandC2SPacket(player, ClientCommandC2SPacket.Mode.RELEASE_SHIFT_KEY));
63+
if (unique && slotIndex != player.getInventory().selectedSlot) HandlerSlotUtil.mainHandSwapSlot = slot; // Can't swap back for non-uniques
64+
if (!unique) {
65+
this.swappedSlot = this.slot;
66+
this.swappedStack = player.getInventory().getStack(this.slot);
67+
this.slot = player.getInventory().selectedSlot;
68+
}
4169
}
4270

4371
@Override
@@ -51,6 +79,11 @@ public boolean shouldBeRemoved(World world, boolean current) {
5179
return false;
5280
}
5381

82+
@Override
83+
public boolean isBuffered() {
84+
return true;
85+
}
86+
5487
@Override
5588
public Text getHoverText() {
5689
return stack.hasCustomName() ? stack.getName().copy().formatted(Formatting.ITALIC) : stack.getName();

src/main/java/folk/sisby/inventory_tabs/tabs/PlayerInventoryTab.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ public void open(ClientPlayerEntity player, ClientWorld world, ScreenHandler han
2626
}
2727

2828
@Override
29-
public void close() {
30-
ClientPlayerEntity player = MinecraftClient.getInstance().player;
29+
public void close(ClientPlayerEntity player, ClientWorld world, ScreenHandler handler, ClientPlayerInteractionManager interactionManager) {
3130
if (player != null) player.playerScreenHandler.setCursorStack(ItemStack.EMPTY);
3231
}
3332

src/main/java/folk/sisby/inventory_tabs/tabs/Tab.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public interface Tab {
5050
/**
5151
* Called when the screen associated with the tab is closed (for handlers that aren't destroyed when closed on the servers)
5252
*/
53-
default void close() {}
53+
default void close(ClientPlayerEntity player, ClientWorld world, ScreenHandler handler, ClientPlayerInteractionManager interactionManager) {}
5454

5555
/**
5656
* @return the tab's left-priority when being displayed. The player's inventory is at 100.
@@ -65,6 +65,12 @@ default int getPriority() {
6565
*/
6666
default boolean isInstant() { return false; }
6767

68+
/**
69+
* @return whether the tab can only be safely opened through the player inventory screen.
70+
* Helps prevent lockups, but might flicker.
71+
*/
72+
default boolean isBuffered() { return false; }
73+
6874
default void render(DrawContext drawContext, WidgetPosition pos, int width, int height, double mouseX, double mouseY, boolean current) {
6975
int y = pos.y + (pos.up ? -height : height);
7076
int drawHeight = height + (current ? TAB_INSET_HEIGHT_SELECTED : TAB_INSET_HEIGHT_UNSELECTED);

0 commit comments

Comments
 (0)