Skip to content

Commit

Permalink
implement non-unique items in full
Browse files Browse the repository at this point in the history
  • Loading branch information
sisby-folk committed Apr 4, 2024
1 parent cdaac8a commit 1373e62
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 17 deletions.
27 changes: 18 additions & 9 deletions src/main/java/folk/sisby/inventory_tabs/TabManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public static void initScreen(MinecraftClient client, HandledScreen<?> screen) {

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

public static void screenDiscarded() {
currentTab = null;
if (currentTab != null) {
currentTab.close(MinecraftClient.getInstance().player, MinecraftClient.getInstance().world, MinecraftClient.getInstance().player != null ? MinecraftClient.getInstance().player.currentScreenHandler : null, MinecraftClient.getInstance().interactionManager);
currentTab = null;
}
nextTab = null;
currentPage = 0;
}
Expand All @@ -91,20 +94,26 @@ public static void tick(ClientWorld world) {
if (currentTab != null && !tabs.contains(currentTab)) currentTab = null;
}

public static void openTabImmediate(Tab tab, ClientPlayerEntity player, ClientPlayerInteractionManager interactionManager, ClientWorld world) {
nextTab = tab;
HandlerSlotUtil.push(player, MinecraftClient.getInstance().interactionManager, currentScreen.getScreenHandler(), tab.isInstant());
player.networkHandler.sendPacket(new CloseHandledScreenC2SPacket(currentScreen.getScreenHandler().syncId));
tab.open(player, world, currentScreen.getScreenHandler(), interactionManager);
if (tab.isInstant()) { // Instant screens don't have slot updates to wait for, so finish now.
finishOpeningScreen(currentScreen.getScreenHandler());
}
}


public static void openTab(Tab tab) {
if (tab != currentTab) {
ClientPlayerEntity player = MinecraftClient.getInstance().player;
ClientPlayerInteractionManager interactionManager = MinecraftClient.getInstance().interactionManager;
ClientPlayNetworkHandler networkHandler = MinecraftClient.getInstance().getNetworkHandler();
if (player != null && interactionManager != null && networkHandler != null && player.getWorld() instanceof ClientWorld world) {
if (!tab.shouldBeRemoved(world, false)) {
nextTab = tab;
HandlerSlotUtil.push(player, MinecraftClient.getInstance().interactionManager, currentScreen.getScreenHandler(), tab.isInstant());
player.networkHandler.sendPacket(new CloseHandledScreenC2SPacket(currentScreen.getScreenHandler().syncId));
tab.open(player, world, currentScreen.getScreenHandler(), interactionManager);
if (tab.isInstant()) { // Instant screens don't have slot updates to wait for, so finish now.
finishOpeningScreen(currentScreen.getScreenHandler());
}
if (tab.isBuffered()) openTabImmediate(new PlayerInventoryTab(), player, interactionManager, world);
openTabImmediate(tab, player, interactionManager, world);
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/folk/sisby/inventory_tabs/TabProviders.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import folk.sisby.inventory_tabs.providers.SimpleItemTabProvider;
import folk.sisby.inventory_tabs.providers.SimpleStorageBlockTabProvider;
import folk.sisby.inventory_tabs.providers.SneakEntityTabProvider;
import folk.sisby.inventory_tabs.providers.SneakItemTabProvider;
import folk.sisby.inventory_tabs.providers.TabProvider;
import folk.sisby.inventory_tabs.providers.UniqueBlockTabProvider;
import folk.sisby.inventory_tabs.providers.UniqueItemTabProvider;
Expand Down Expand Up @@ -61,6 +62,7 @@ public class TabProviders {
public static final SimpleEntityTabProvider ENTITY_SIMPLE = register(InventoryTabs.id("entity_simple"), new SimpleEntityTabProvider());

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

// Single-Purpose
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public void addAvailableTabs(ClientPlayerEntity player, Consumer<Tab> addTab) {
}

public Tab createTab(ItemStack stack, int slot) {
return new ItemTab(stack, slot, preclusions, isUnique());
return new ItemTab(stack, slot, preclusions, isUnique(), doSneakInteract());
}

public boolean doSneakInteract() {
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package folk.sisby.inventory_tabs.providers;

public class SneakItemTabProvider extends ItemTabProvider {
@Override
public int getRegistryPriority() {
return 20;
}

@Override
public boolean doSneakInteract() {
return true;
}
}
41 changes: 37 additions & 4 deletions src/main/java/folk/sisby/inventory_tabs/tabs/ItemTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import net.minecraft.client.network.ClientPlayerInteractionManager;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.item.ItemStack;
import net.minecraft.network.packet.c2s.play.ClientCommandC2SPacket;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.slot.SlotActionType;
import net.minecraft.text.Text;
Expand All @@ -21,23 +22,50 @@

public class ItemTab implements Tab {
public final ItemStack stack;
public final int slot;
public int slot;
public final boolean unique;
public final boolean sneakInteract;
public final Map<Identifier, Predicate<ItemStack>> preclusions;
public ItemStack swappedStack = null;
public int swappedSlot = -1;

public ItemTab(ItemStack stack, int slot, Map<Identifier, Predicate<ItemStack>> preclusions, boolean unique) {
public ItemTab(ItemStack stack, int slot, Map<Identifier, Predicate<ItemStack>> preclusions, boolean unique, boolean sneakInteract) {
this.stack = stack;
this.slot = slot;
this.preclusions = preclusions;
this.unique = unique;
this.sneakInteract = sneakInteract;
}

public ItemTab(ItemStack stack, int slot, Map<Identifier, Predicate<ItemStack>> preclusions, boolean unique) {
this(stack, slot, preclusions, unique, false);
}

@Override
public void close(ClientPlayerEntity player, ClientWorld world, ScreenHandler handler, ClientPlayerInteractionManager interactionManager) {
if (player == null) return;
if (swappedSlot != -1) {
ItemStack inSwappedSlot = player.getInventory().getStack(swappedSlot);
if (ItemStack.areEqual(inSwappedSlot, swappedStack)) {
int slotIndex = handler.getSlotIndex(player.getInventory(), swappedSlot).getAsInt();
interactionManager.clickSlot(handler.syncId, slotIndex, player.getInventory().selectedSlot, SlotActionType.SWAP, player);
}
}
}

@Override
public void open(ClientPlayerEntity player, ClientWorld world, ScreenHandler handler, ClientPlayerInteractionManager interactionManager) {
int slotIndex = handler.getSlotIndex(player.getInventory(), slot).getAsInt();
interactionManager.clickSlot(handler.syncId, slotIndex, player.getInventory().selectedSlot, SlotActionType.SWAP, player);
if (slotIndex != player.getInventory().selectedSlot) interactionManager.clickSlot(handler.syncId, slotIndex, player.getInventory().selectedSlot, SlotActionType.SWAP, player);
if (sneakInteract) player.networkHandler.sendPacket(new ClientCommandC2SPacket(player, ClientCommandC2SPacket.Mode.PRESS_SHIFT_KEY));
interactionManager.interactItem(player, Hand.MAIN_HAND);
HandlerSlotUtil.mainHandSwapSlot = slot;
if (sneakInteract) player.networkHandler.sendPacket(new ClientCommandC2SPacket(player, ClientCommandC2SPacket.Mode.RELEASE_SHIFT_KEY));
if (unique && slotIndex != player.getInventory().selectedSlot) HandlerSlotUtil.mainHandSwapSlot = slot; // Can't swap back for non-uniques
if (!unique) {
this.swappedSlot = this.slot;
this.swappedStack = player.getInventory().getStack(this.slot);
this.slot = player.getInventory().selectedSlot;
}
}

@Override
Expand All @@ -51,6 +79,11 @@ public boolean shouldBeRemoved(World world, boolean current) {
return false;
}

@Override
public boolean isBuffered() {
return true;
}

@Override
public Text getHoverText() {
return stack.hasCustomName() ? stack.getName().copy().formatted(Formatting.ITALIC) : stack.getName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ public void open(ClientPlayerEntity player, ClientWorld world, ScreenHandler han
}

@Override
public void close() {
ClientPlayerEntity player = MinecraftClient.getInstance().player;
public void close(ClientPlayerEntity player, ClientWorld world, ScreenHandler handler, ClientPlayerInteractionManager interactionManager) {
if (player != null) player.playerScreenHandler.setCursorStack(ItemStack.EMPTY);
}

Expand Down
8 changes: 7 additions & 1 deletion src/main/java/folk/sisby/inventory_tabs/tabs/Tab.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public interface Tab {
/**
* Called when the screen associated with the tab is closed (for handlers that aren't destroyed when closed on the servers)
*/
default void close() {}
default void close(ClientPlayerEntity player, ClientWorld world, ScreenHandler handler, ClientPlayerInteractionManager interactionManager) {}

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

/**
* @return whether the tab can only be safely opened through the player inventory screen.
* Helps prevent lockups, but might flicker.
*/
default boolean isBuffered() { return false; }

default void render(DrawContext drawContext, WidgetPosition pos, int width, int height, double mouseX, double mouseY, boolean current) {
int y = pos.y + (pos.up ? -height : height);
int drawHeight = height + (current ? TAB_INSET_HEIGHT_SELECTED : TAB_INSET_HEIGHT_UNSELECTED);
Expand Down

0 comments on commit 1373e62

Please sign in to comment.