Skip to content

Commit

Permalink
configurable inverted tabs
Browse files Browse the repository at this point in the history
fixes #37
  • Loading branch information
sisby-folk committed Apr 6, 2024
1 parent e255279 commit 3e0fbcd
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 30 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
<center><img width=640 alt="EMI VGA Preview" src="https://cdn.modrinth.com/data/VD1aynYU/images/7356435a874c5f5c587b59f4b71461da2e997df1.png" /></center>

#### 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.<br/>
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.

---

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[versions]
loom = "1.4.+"
loom = "1.6.+"
githubRelease = "2.4.1"
minotaur = "2.6.0"

Expand Down
16 changes: 14 additions & 2 deletions src/main/java/folk/sisby/inventory_tabs/InventoryTabsConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -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("")
Expand All @@ -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<String, Integer> leftBoundOffsetOverride = ValueMap.builder(0).put("null", 0).build();
public final Map<String, Integer> leftBoundOffsetOverride = ValueMap.builder(0).put("minecraft:loom", 0).build();

@Comment("")
@Comment("-------------------------------")
Expand All @@ -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<String, Integer> rightBoundOffsetOverride = ValueMap.builder(0).put("null", 0).build();
public final Map<String, Integer> 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<String, Boolean> invertedTabsOverride = ValueMap.builder(false).put("minecraft:beacon", false).build();

@Comment("")
@Comment("-------------------------------")
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/folk/sisby/inventory_tabs/ScreenSupport.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class ScreenSupport {
public static Map<Identifier, Predicate<HandledScreen<?>>> DENY = new HashMap<>();
public static Map<Identifier, Predicate<HandledScreen<?>>> ALLOW = new HashMap<>();
public static Map<Identifier, Pair<Integer, Integer>> SCREEN_BOUND_OFFSETS = new HashMap<>();
public static Map<Identifier, Boolean> SCREEN_INVERTS = new HashMap<>();

public static Boolean allowTabs(RegistryKey<ScreenHandlerType<?>> type) {
if (InventoryTabs.CONFIG.screenOverrides.entrySet().stream().filter(e -> !e.getValue()).anyMatch(e -> Objects.equals(e.getKey(), type.getValue().toString()))) return false;
Expand Down Expand Up @@ -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));
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -18,14 +19,15 @@ default List<WidgetPosition> getTabPositions(int tabWidth) {
List<WidgetPosition> list = new ArrayList<>();
Identifier screenHandlerId = Registries.SCREEN_HANDLER.getId(screen.getScreenHandler().type);
Pair<Integer, Integer> 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);

int count = width / 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;
Expand Down
44 changes: 24 additions & 20 deletions src/main/java/folk/sisby/inventory_tabs/tabs/Tab.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand All @@ -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);
}
}
Expand Down

0 comments on commit 3e0fbcd

Please sign in to comment.