diff --git a/README.md b/README.md index c636741..a60e4da 100644 --- a/README.md +++ b/README.md @@ -30,12 +30,12 @@ You can also use Tab and Shift+Tab to cycle through available screens. - Fits on-screen with [EMI](https://modrinth.com/mod/emi), even on very high GUI scales - Use `Left (Compressed)` effects.
EMI VGA Preview
-#### Anti-Cheat & Convenience +#### Anti-Cheat & Fairness Inventory Tabs 4 offers no guarantees or defence against server moderation or anti-cheat - tabs provide an unfair advantage, and look outwardly suspicious to onlookers in multiplayer.
-In fact, some fully non-vanilla actions are possible for convenience, such as: - - Accessing your full regular inventory while riding a horse or chest boat. - - Accessing sneak-interact inventories without dismounting from a vehicle. +Notably, the mod allows some usually impossible actions for the sake of convenience, e.g. + - The full player inventory can be accessed while riding a horse or chest boat. + - Sneak-interact inventories can be accessed without dismounting from a vehicle. --- diff --git a/gradle.properties b/gradle.properties index 91e7379..8242505 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,6 +7,6 @@ org.gradle.configureondemand=true # Enable advanced multi-module optimizations (share tiny-remaper instance between projects) fabric.loom.multiProjectOptimisation=true # Mod Properties -baseVersion = 1.2.0 +baseVersion = 1.3.0 defaultBranch = 1.20 branch = 1.20 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index db9a6b8..17655d0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/libs.versions.toml b/libs.versions.toml index 4cd782d..1e39131 100644 --- a/libs.versions.toml +++ b/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -loom = "1.4.+" +loom = "1.6.+" githubRelease = "2.4.1" minotaur = "2.6.0" diff --git a/src/main/java/folk/sisby/inventory_tabs/InventoryTabsConfig.java b/src/main/java/folk/sisby/inventory_tabs/InventoryTabsConfig.java index 018f3e1..6bf6ef7 100644 --- a/src/main/java/folk/sisby/inventory_tabs/InventoryTabsConfig.java +++ b/src/main/java/folk/sisby/inventory_tabs/InventoryTabsConfig.java @@ -39,6 +39,9 @@ public class InventoryTabsConfig extends WrappedConfig { @Comment("Whether to show tabs on screens that aren't specified below") public final Boolean allowScreensByDefault = true; + @Comment("Whether to show tabs on the bottom of screens that aren't specified below") + public final Boolean invertTabsByDefault = false; + @Comment("") @Comment("-------------------------------") @Comment("") @@ -55,7 +58,7 @@ public class InventoryTabsConfig extends WrappedConfig { @Comment("Positive values expand the left boundary, allowing more tabs to be drawn") @Comment("null means the player inventory") @Comment("") - public final Map leftBoundOffsetOverride = ValueMap.builder(0).put("null", 0).build(); + public final Map leftBoundOffsetOverride = ValueMap.builder(0).put("minecraft:loom", 0).build(); @Comment("") @Comment("-------------------------------") @@ -64,7 +67,16 @@ public class InventoryTabsConfig extends WrappedConfig { @Comment("Positive values expand the right boundary, allowing more tabs to be drawn") @Comment("null means the player inventory") @Comment("") - public final Map rightBoundOffsetOverride = ValueMap.builder(0).put("null", 0).build(); + public final Map rightBoundOffsetOverride = ValueMap.builder(0).put("minecraft:loom", 0).build(); + + @Comment("") + @Comment("-------------------------------") + @Comment("") + @Comment("Manually choose where to place tabs on a given screen") + @Comment("false means above, true means below") + @Comment("null key means the player inventory") + @Comment("") + public final Map invertedTabsOverride = ValueMap.builder(false).put("minecraft:beacon", false).build(); @Comment("") @Comment("-------------------------------") diff --git a/src/main/java/folk/sisby/inventory_tabs/ScreenSupport.java b/src/main/java/folk/sisby/inventory_tabs/ScreenSupport.java index 77e2cec..5aa6833 100644 --- a/src/main/java/folk/sisby/inventory_tabs/ScreenSupport.java +++ b/src/main/java/folk/sisby/inventory_tabs/ScreenSupport.java @@ -19,6 +19,7 @@ public class ScreenSupport { public static Map>> DENY = new HashMap<>(); public static Map>> ALLOW = new HashMap<>(); public static Map> SCREEN_BOUND_OFFSETS = new HashMap<>(); + public static Map SCREEN_INVERTS = new HashMap<>(); public static Boolean allowTabs(RegistryKey> type) { if (InventoryTabs.CONFIG.screenOverrides.entrySet().stream().filter(e -> !e.getValue()).anyMatch(e -> Objects.equals(e.getKey(), type.getValue().toString()))) return false; @@ -48,5 +49,6 @@ public static boolean allowTabs(Screen screen) { ALLOW.put(InventoryTabs.id("horse_screen"), hs -> hs instanceof HorseScreen); InventoryTabs.CONFIG.leftBoundOffsetOverride.forEach((screenHandlerId, offset) -> SCREEN_BOUND_OFFSETS.put(screenHandlerId.equals("null") ? null : new Identifier(screenHandlerId), new Pair<>(offset, 0))); InventoryTabs.CONFIG.rightBoundOffsetOverride.forEach((screenHandlerId, offset) -> SCREEN_BOUND_OFFSETS.merge(screenHandlerId.equals("null") ? null : new Identifier(screenHandlerId), new Pair<>(0, offset), (o, n) -> new Pair<>(o.getLeft(), n.getRight()))); + InventoryTabs.CONFIG.invertedTabsOverride.forEach((screenHandlerId, doInvert) -> SCREEN_INVERTS.put(screenHandlerId.equals("null") ? null : new Identifier(screenHandlerId), doInvert)); } } diff --git a/src/main/java/folk/sisby/inventory_tabs/duck/InventoryTabsScreen.java b/src/main/java/folk/sisby/inventory_tabs/duck/InventoryTabsScreen.java index b124405..f0b5389 100644 --- a/src/main/java/folk/sisby/inventory_tabs/duck/InventoryTabsScreen.java +++ b/src/main/java/folk/sisby/inventory_tabs/duck/InventoryTabsScreen.java @@ -1,5 +1,6 @@ package folk.sisby.inventory_tabs.duck; +import folk.sisby.inventory_tabs.InventoryTabs; import folk.sisby.inventory_tabs.ScreenSupport; import folk.sisby.inventory_tabs.util.WidgetPosition; import net.minecraft.client.gui.screen.ingame.HandledScreen; @@ -18,6 +19,7 @@ default List getTabPositions(int tabWidth) { List list = new ArrayList<>(); Identifier screenHandlerId = Registries.SCREEN_HANDLER.getId(screen.getScreenHandler().type); Pair offsets = ScreenSupport.SCREEN_BOUND_OFFSETS.getOrDefault(screenHandlerId, new Pair<>(0,0)); + boolean invert = ScreenSupport.SCREEN_INVERTS.getOrDefault(screenHandlerId, InventoryTabs.CONFIG.invertTabsByDefault); int width = screen.backgroundWidth + offsets.getLeft() + offsets.getRight(); int left = Math.max(screen.x - offsets.getLeft(), 0); @@ -25,7 +27,7 @@ default List getTabPositions(int tabWidth) { int margins = width - tabWidth * count; for (int i = 0; i < count; i++) { - list.add(new WidgetPosition(left + margins / 2 + i * tabWidth, screen.y, true)); + list.add(new WidgetPosition(left + margins / 2 + i * tabWidth, invert ? screen.y + screen.backgroundHeight : screen.y, !invert)); } return list; diff --git a/src/main/java/folk/sisby/inventory_tabs/tabs/Tab.java b/src/main/java/folk/sisby/inventory_tabs/tabs/Tab.java index 9598e27..caa21f2 100644 --- a/src/main/java/folk/sisby/inventory_tabs/tabs/Tab.java +++ b/src/main/java/folk/sisby/inventory_tabs/tabs/Tab.java @@ -16,16 +16,13 @@ public interface Tab { Identifier TABS_TEXTURE = new Identifier("textures/gui/container/creative_inventory/tabs.png"); - int TAB_INSET_HEIGHT_SELECTED = 4; - int TAB_INSET_HEIGHT_UNSELECTED = 0; - int TAB_TEXTURE_WIDTH = 26; - int TAB_TEXTURE_HEIGHT_SELECTED = 32; - int TAB_TEXTURE_HEIGHT_UNSELECTED = 30; - int TAB_TEXTURE_U = 26; - int TAB_TEXTURE_V_UNSELECTED = 2; - int TAB_TEXTURE_V_UNSELECTED_INVERTED = 64; - int TAB_TEXTURE_V_SELECTED = 32; - int TAB_TEXTURE_V_SELECTED_INVERTED = 96; + int TEXTURE_WIDTH = 26; + int TEXTURE_U = 26; + int[] TEXTURE_V = new int[]{2, 32, 64, 96}; + int[] TEXTURE_HEIGHT = new int[]{30, 32, 28, 32}; + int[] Y_OFFSET = new int[]{0, 0, 0, -4}; + int[] ITEM_Y_OFFSET = new int[]{0, 0, -3, -3}; + int[] HEIGHT_OFFSET = new int[]{0, 4, 0, 4}; /** * Opens the screen associated with the tab. @@ -50,7 +47,8 @@ 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(ClientPlayerEntity player, ClientWorld world, ScreenHandler handler, ClientPlayerInteractionManager interactionManager) {} + 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. @@ -63,23 +61,29 @@ default int getPriority() { * @return whether the tabs open method instantly opens the screen on the client side without slot sync. * Used for the survival inventory. Helps preserve cursor stacks. */ - default boolean isInstant() { return false; } + 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 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); - int textureHeight = current ? TAB_TEXTURE_HEIGHT_SELECTED : TAB_TEXTURE_HEIGHT_UNSELECTED; - int v = current ? (pos.up ? TAB_TEXTURE_V_SELECTED : TAB_TEXTURE_V_SELECTED_INVERTED) : (pos.up ? TAB_TEXTURE_V_UNSELECTED : TAB_TEXTURE_V_UNSELECTED_INVERTED); - DrawUtil.drawCrunched(drawContext, TABS_TEXTURE, pos.x, y, width, drawHeight, TAB_TEXTURE_WIDTH, textureHeight, TAB_TEXTURE_U, v); + int type = pos.up ? (!current ? 0 : 1) : (!current ? 2 : 3); + int y = pos.y + (pos.up ? -height : 0); + int drawHeight = height + HEIGHT_OFFSET[type]; + int drawY = y + Y_OFFSET[type]; + DrawUtil.drawCrunched(drawContext, TABS_TEXTURE, pos.x, drawY, width, drawHeight, TEXTURE_WIDTH, TEXTURE_HEIGHT[type], TEXTURE_U, TEXTURE_V[type]); int itemPadding = Math.max(0, (width - 16) / 2); - drawContext.drawItem(getTabIcon(), pos.x + itemPadding, y + itemPadding); - if (new Rect2i(pos.x + itemPadding, y + itemPadding, 16, 16).contains((int) mouseX, (int) mouseY)) { + int itemX = pos.x + itemPadding; + int itemY = y + itemPadding + ITEM_Y_OFFSET[type]; + drawContext.drawItem(getTabIcon(), itemX, itemY); + if (new Rect2i(itemX, itemY, 16, 16).contains((int) mouseX, (int) mouseY)) { drawContext.drawTooltip(MinecraftClient.getInstance().textRenderer, getHoverText(), (int) mouseX, (int) mouseY); } }