diff --git a/.github/resources/BigInv_compat.png b/.github/resources/BigInv_compat.png
new file mode 100644
index 0000000..059b3d9
Binary files /dev/null and b/.github/resources/BigInv_compat.png differ
diff --git a/.github/resources/InventoryTabs.png b/.github/resources/InventoryTabs.png
new file mode 100644
index 0000000..e3112f6
Binary files /dev/null and b/.github/resources/InventoryTabs.png differ
diff --git a/.github/resources/Tabs_showcase.gif b/.github/resources/Tabs_showcase.gif
new file mode 100644
index 0000000..35cdf81
Binary files /dev/null and b/.github/resources/Tabs_showcase.gif differ
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..f7478a9
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,39 @@
+# Automatically build the project and run any configured tests for every push
+# and submitted pull request. This can help catch issues that only occur on
+# certain platforms or Java versions, and provides a first line of defence
+# against bad commits.
+
+name: build
+on: [pull_request, push]
+
+jobs:
+ build:
+ strategy:
+ matrix:
+ # Use these Java versions
+ java: [
+ 17 # Minimum supported by Minecraft
+ ]
+ # and run on both Linux and Windows
+ os: [ubuntu-20.04, windows-latest]
+ runs-on: ${{ matrix.os }}
+ steps:
+ - name: checkout repository
+ uses: actions/checkout@v2
+ - name: validate gradle wrapper
+ uses: gradle/wrapper-validation-action@v1
+ - name: setup jdk ${{ matrix.java }}
+ uses: actions/setup-java@v1
+ with:
+ java-version: ${{ matrix.java }}
+ - name: make gradle wrapper executable
+ if: ${{ runner.os != 'Windows' }}
+ run: chmod +x ./gradlew
+ - name: build
+ run: ./gradlew build
+ - name: capture build artifacts
+ if: ${{ runner.os == 'Linux' && matrix.java == '17' }} # Only upload artifacts built from latest java on one OS
+ uses: actions/upload-artifact@v2
+ with:
+ name: Artifacts
+ path: build/libs/
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..f623def
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,34 @@
+name: Publish Artifacts
+
+on:
+ release:
+ types: [published]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up JDK 17
+ uses: actions/setup-java@v2
+ with:
+ distribution: 'adopt-hotspot'
+ java-version: 17
+ cache: 'gradle'
+ - name: make gradle wrapper executable
+ run: chmod +x ./gradlew
+ - name: build
+ run: ./gradlew build
+ - uses: Kir-Antipov/mc-publish@v3.0
+ with:
+ curseforge-id: 585506
+ modrinth-id: F1AqcMCK
+ modrinth-featured: true
+ modrinth-unfeature-mode: intersection
+ modrinth-token: ${{ secrets.MODRINTH_TOKEN }}
+ curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }}
+ version-type: beta
+ version-resolver: all
+ loaders: |
+ fabric
+ quilt
\ No newline at end of file
diff --git a/README.md b/README.md
index b853262..b612534 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,48 @@
# InventoryTabs
-Adds tabs to access nearby blocks.
+Adds tabs to access nearby blocks without leaving your inventory. Completely client-side. Requires Cloth Config API.
+
+
|
+
+
+
+ |
+
+
+
+ |
+
+Also has [BigInv](https://github.com/SollyW/BigInv) and [PlayerEx](https://www.curseforge.com/minecraft/mc-mods/playerex) support!
+
+|
+
+
+
+ |
+
+
+
+ |
+
+New in 0.8.1: Chest icons and hover text can be changed by nearby item frames!
+
+
+
+New in 0.9.0: Entity support!
+
+|
+
+
+
+ |
+
+
+
+ |
+
## Devs
### Importing
-To add **Inventory Tabs** to your project, you need to add ``https://jitpack.io`` as a repo and ``com.github.cakewhip:inventorytabs:mcA.B.C-vX.Y.Z`` as a dependency. For example:
+To add **Inventory Tabs** to your project, you need to add ``https://jitpack.io`` as a repo and ``com.github.Andrew6rant:InventoryTabs:inventorytabs-(mod version)-(Minecraft version)`` as a dependency. For example:
```
repositories {
maven {
@@ -12,9 +51,10 @@ repositories {
}
dependencies {
- modImplementation "com.github.cakewhip:inventorytabs:mcA.B.C-vX.Y.Z"
+ modImplementation "com.github.Andrew6rant:InventoryTabs:inventorytabs-0.6.1-1.19.x"
}
```
+
See the releases page for available versions.
### Adding Custom Tabs
@@ -36,3 +76,6 @@ Your handled screen needs to update the ``TabManager``, which you can grab a ref
Finally, there are some methods to call for rendering and managing the tabs. In the ``render`` method before anything is drawn, call ``TabRenderer#renderBackground``. In the ``drawBackground``, call ``TabRenderer#renderForeground`` and ``TabRenderer#renderHoverTooltips``. In the ``mouseClicked`` method, call ``TabManager#mouseClicked``.
If your screen's GUI dynamically changes (in the case of a recipe book opening), you can implement the ``TabRenderingHints`` interface and offset the top and bottom rows however you like.
+
+## Credits
+This 1.18 and 1.19 port is based on LiamMCW's fork of the original mod by cakewhip. Full credits can be found at https://github.com/Andrew6rant/inventorytabs/graphs/contributors.
diff --git a/build.gradle b/build.gradle
index 4ea4e6d..14bfd2d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,19 +1,23 @@
plugins {
- id 'fabric-loom' version '0.8-SNAPSHOT'
+ id 'fabric-loom' version '0.12-SNAPSHOT'
id 'maven-publish'
}
-sourceCompatibility = JavaVersion.VERSION_16
-targetCompatibility = JavaVersion.VERSION_16
+sourceCompatibility = JavaVersion.VERSION_1_8
+targetCompatibility = JavaVersion.VERSION_1_8
archivesBaseName = project.archives_base_name
-version = "${project.mod_version}-${project.minecraft_version}"
+version = project.mod_version
group = project.maven_group
repositories {
maven {
url "https://maven.shedaniel.me/"
}
+ maven {
+ name = 'terraformers maven'
+ url "https://maven.terraformersmc.com/releases"
+ }
}
dependencies {
@@ -28,6 +32,11 @@ dependencies {
modApi("me.shedaniel.cloth:cloth-config-fabric:${project.clothconfig_version}") {
exclude(group: "net.fabricmc.fabric-api")
}
+
+
+ modCompileOnly("com.terraformersmc:modmenu:${project.modmenu_version}") {
+ transitive = false
+ }
// PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs.
// You may need to force-disable transitiveness on them.
}
@@ -47,8 +56,8 @@ tasks.withType(JavaCompile).configureEach {
// If Javadoc is generated, this must be specified in that task too.
it.options.encoding = "UTF-8"
- // Minecraft 1.17 (21w19a) upwards uses Java 16.
- it.options.release = 16
+ // Minecraft 1.18 (1.18-pre2) upwards uses Java 17.
+ it.options.release = 8
}
java {
@@ -58,6 +67,10 @@ java {
withSourcesJar()
}
+loom {
+ setupRemappedVariants = true
+}
+
jar {
from("LICENSE") {
rename { "${it}_${project.archivesBaseName}"}
@@ -68,13 +81,7 @@ jar {
publishing {
publications {
mavenJava(MavenPublication) {
- // add all the jars that should be included when publishing to maven
- artifact(remapJar) {
- builtBy remapJar
- }
- artifact(sourcesJar) {
- builtBy remapSourcesJar
- }
+ from components.java
}
}
diff --git a/gradle.properties b/gradle.properties
index 621d107..e7a026d 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -5,13 +5,14 @@ org.gradle.jvmargs=-Xmx1G
# check these on https://fabricmc.net/versions.html
minecraft_version=1.16.5
yarn_mappings=1.16.5+build.10
- loader_version=0.11.6
+ loader_version=0.14.9
# Mod Properties
- mod_version = 0.3.0
+ mod_version = 0.9.beta-1.16.5
maven_group = com.kqp
archives_base_name = inventorytabs
# Dependencies
- fabric_version=0.36.0+1.16
- clothconfig_version=4.11.26
+ fabric_version=0.42.0+1.16
+ clothconfig_version=4.14.54
+ modmenu_version=1.14.14
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 05679dc..e750102 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-7.1.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/jitpack.yml b/jitpack.yml
new file mode 100644
index 0000000..4a7f508
--- /dev/null
+++ b/jitpack.yml
@@ -0,0 +1,5 @@
+jdk:
+ - openjdk17
+before_install:
+ - sdk install java 17.0.1-open
+ - sdk use java 17.0.1-open
diff --git a/settings.gradle b/settings.gradle
index 5b60df3..b02216b 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,10 +1,10 @@
pluginManagement {
repositories {
- jcenter()
maven {
name = 'Fabric'
url = 'https://maven.fabricmc.net/'
}
+ mavenCentral()
gradlePluginPortal()
}
}
diff --git a/src/main/java/com/kqp/inventorytabs/api/TabProviderRegistry.java b/src/main/java/com/kqp/inventorytabs/api/TabProviderRegistry.java
index 596cefc..a9915ab 100644
--- a/src/main/java/com/kqp/inventorytabs/api/TabProviderRegistry.java
+++ b/src/main/java/com/kqp/inventorytabs/api/TabProviderRegistry.java
@@ -1,32 +1,32 @@
package com.kqp.inventorytabs.api;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import com.kqp.inventorytabs.init.InventoryTabs;
-import com.kqp.inventorytabs.tabs.provider.ChestTabProvider;
-import com.kqp.inventorytabs.tabs.provider.EnderChestTabProvider;
-import com.kqp.inventorytabs.tabs.provider.PlayerInventoryTabProvider;
-import com.kqp.inventorytabs.tabs.provider.ShulkerBoxTabProvider;
-import com.kqp.inventorytabs.tabs.provider.SimpleBlockTabProvider;
-import com.kqp.inventorytabs.tabs.provider.TabProvider;
-
-import net.minecraft.block.AnvilBlock;
-import net.minecraft.block.Block;
-import net.minecraft.block.Blocks;
+import com.kqp.inventorytabs.interf.TabManagerContainer;
+import com.kqp.inventorytabs.tabs.provider.*;
+
+import net.minecraft.block.*;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.tag.BlockTags;
+import net.minecraft.tag.Tag;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
/**
* Registry for tab providers.
*/
public class TabProviderRegistry {
+ private static final Logger LOGGER = LogManager.getLogger("InventoryTabs");
private static final Map TAB_PROVIDERS = new HashMap<>();
public static final PlayerInventoryTabProvider PLAYER_INVENTORY_TAB_PROVIDER = (PlayerInventoryTabProvider) register(
InventoryTabs.id("player_inventory_tab_provider"), new PlayerInventoryTabProvider());
+ public static final SimpleEntityTabProvider ENTITY_TAB_PROVIDER = (SimpleEntityTabProvider) register(
+ InventoryTabs.id("entity_tab_provider"), new SimpleEntityTabProvider());
public static final SimpleBlockTabProvider SIMPLE_BLOCK_TAB_PROVIDER = (SimpleBlockTabProvider) register(
InventoryTabs.id("simple_block_tab_provider"), new SimpleBlockTabProvider());
public static final ChestTabProvider CHEST_TAB_PROVIDER = (ChestTabProvider) register(
@@ -35,108 +35,104 @@ public class TabProviderRegistry {
InventoryTabs.id("ender_chest_tab_provider"), new EnderChestTabProvider());
public static final ShulkerBoxTabProvider SHULKER_BOX_TAB_PROVIDER = (ShulkerBoxTabProvider) register(
InventoryTabs.id("shulker_box_tab_provider"), new ShulkerBoxTabProvider());
-
- public static void init() {
- addVanillaSimpleBlockTabProviders();
- addVanillaChestTabProviders();
- addModSimpleBlockTabProviders();
- }
-
- private static void addVanillaSimpleBlockTabProviders() {
- registerSimpleBlock(Blocks.FURNACE);
- registerSimpleBlock(Blocks.CARTOGRAPHY_TABLE);
- registerSimpleBlock(Blocks.CRAFTING_TABLE);
- registerSimpleBlock(Blocks.ENCHANTING_TABLE);
- registerSimpleBlock(Blocks.GRINDSTONE);
- registerSimpleBlock(Blocks.LOOM);
- registerSimpleBlock(Blocks.SMITHING_TABLE);
- registerSimpleBlock(Blocks.STONECUTTER);
- registerSimpleBlock(Blocks.BARREL);
- registerSimpleBlock(Blocks.BLAST_FURNACE);
- registerSimpleBlock(Blocks.SMOKER);
- registerSimpleBlock(Blocks.BREWING_STAND);
- registerSimpleBlock(Blocks.DISPENSER);
- registerSimpleBlock(Blocks.DROPPER);
- registerSimpleBlock(Blocks.HOPPER);
-
+ public static final UniqueTabProvider UNIQUE_TAB_PROVIDER = (UniqueTabProvider) register(
+ InventoryTabs.id("crafting_table_tab_provider"), new UniqueTabProvider());
+ public static final LecternTabProvider LECTERN_TAB_PROVIDER = (LecternTabProvider) register(
+ InventoryTabs.id("lectern_tab_provider"), new LecternTabProvider());
+ public static final InventoryTabProvider INVENTORY_TAB_PROVIDER = (InventoryTabProvider) register(
+ InventoryTabs.id("inventory_tab_provider"), new InventoryTabProvider());
+
+ public static void init(String configMsg) {
+ LOGGER.info("InventoryTabs: Attempting to "+configMsg+" config...");
+ if (InventoryTabs.getConfig().debugEnabled) {
+ LOGGER.warn("InventoryTabs: DEBUG ENABLED");
+ }
+ Set invalidSet = new HashSet<>();
+ Set tagSet = new HashSet<>();
+ Set blockSet = new HashSet<>();
+ for (String overrideEntry : InventoryTabs.getConfig().excludeTab) {
+ if (overrideEntry.startsWith("#")) {
+ tagSet.add(overrideEntry.trim().substring(1));
+ } else {
+ blockSet.add(overrideEntry);
+ }
+ }
Registry.BLOCK.forEach(block -> {
- if (block instanceof AnvilBlock) {
- registerSimpleBlock(block);
+ if (block instanceof BlockEntityProvider) {
+ if (block instanceof AbstractChestBlock) {
+ registerChest(block);
+ } else if (!(block instanceof AbstractBannerBlock) && !(block instanceof AbstractSignBlock) && !(block instanceof AbstractSkullBlock) && !(block instanceof BeehiveBlock) && !(block instanceof BedBlock) && !(block instanceof BellBlock) && !(block instanceof CampfireBlock) && !(block instanceof ComparatorBlock) && !(block instanceof ConduitBlock) && !(block instanceof DaylightDetectorBlock) && !(block instanceof EndGatewayBlock) && !(block instanceof EndPortalBlock) && !(block instanceof JukeboxBlock) && !(block instanceof PistonExtensionBlock) && !(block instanceof SpawnerBlock)) {
+ registerSimpleBlock(block);
+ }
+ } else if (block instanceof CraftingTableBlock && !(block instanceof FletchingTableBlock) || block instanceof AnvilBlock || block instanceof CartographyTableBlock || block instanceof GrindstoneBlock || block instanceof LoomBlock || block instanceof StonecutterBlock) {
+ registerUniqueBlock(block);
}
+ configRemove(block, tagSet, invalidSet);
});
+ configRemove(blockSet);
+ configAdd();
+ registerEntity(new Identifier("minecraft:entity.minecraft.chest_minecart"));
+
+ MinecraftClient client = MinecraftClient.getInstance();
+ TabManagerContainer tabManagerContainer = (TabManagerContainer) client;
+ tabManagerContainer.getTabManager().removeTabs();
+ LOGGER.info(configMsg.equals("save") ? "InventoryTabs: Config saved!": "InventoryTabs: Config "+configMsg+"ed!");
+ }
+
+ private static void modCompatAdd() {
+ registerInventoryTab(new Identifier("onastick", "crafting_table_on_a_stick"));
+ registerInventoryTab(new Identifier("onastick", "smithing_table_on_a_stick"));
+ registerInventoryTab(new Identifier("onastick", "cartography_table_on_a_stick"));
+ registerInventoryTab(new Identifier("onastick", "anvil_on_a_stick"));
+ registerInventoryTab(new Identifier("onastick", "loom_on_a_stick"));
+ registerInventoryTab(new Identifier("onastick", "grindstone_on_a_stick"));
+ registerInventoryTab(new Identifier("onastick", "stonecutter_on_a_stick"));
+ registerInventoryTab(new Identifier("craftingpad", "craftingpad"));
+ }
+
+ public static boolean isValid(String overrideEntry, String[] splitEntry, Set invalidSet) {
+ if (splitEntry.length != 2) {
+ invalidSet.add(overrideEntry);
+ return false;
+ }
+ return true;
+ }
+
+ private static void configRemove(Set blockSet) {
+ for (String overrideEntry : blockSet) {
+ if (InventoryTabs.getConfig().debugEnabled) {
+ LOGGER.info("Excluding: " + overrideEntry);
+ }
+ removeSimpleBlock(new Identifier(overrideEntry));
+ }
+ }
+
+ private static void configRemove(Block block, Set tagSet, Set invalidSet) {
+ for (String overrideEntry : tagSet) {
+ String[] splitEntry = overrideEntry.split(":"); // split into two parts: tag id, item name
+ if (isValid(overrideEntry, splitEntry, invalidSet)) {
+ Tag blockTag = BlockTags.getTagGroup().getTag(new Identifier(splitEntry[0], splitEntry[1]));
+ if (blockTag != null && block.isIn(blockTag)) {
+ removeSimpleBlock(block);
+ if (InventoryTabs.getConfig().debugEnabled) {
+ LOGGER.info("Excluding: " + block);
+ }
+ }
+ }
+ }
+ }
+
+ private static void configAdd() {
+ for (String included_tab : InventoryTabs.getConfig().includeTab) {
+ if (InventoryTabs.getConfig().debugEnabled) {
+ LOGGER.info("Including: " + included_tab);
+ }
+ registerSimpleBlock(new Identifier(included_tab));
+ }
}
- private static void addVanillaChestTabProviders() {
- registerChest(Blocks.CHEST);
- registerChest(Blocks.TRAPPED_CHEST);
- }
-
- private static void addModSimpleBlockTabProviders() {
- registerSimpleBlock(new Identifier("morecraftingtables", "warped_crafting_table"));
- registerSimpleBlock(new Identifier("morecraftingtables", "spruce_crafting_table"));
- registerSimpleBlock(new Identifier("morecraftingtables", "jungle_crafting_table"));
- registerSimpleBlock(new Identifier("morecraftingtables", "dark_oak_crafting_table"));
- registerSimpleBlock(new Identifier("morecraftingtables", "crimson_crafting_table"));
- registerSimpleBlock(new Identifier("morecraftingtables", "birch_crafting_table"));
- registerSimpleBlock(new Identifier("morecraftingtables", "acacia_crafting_table"));
-
- registerSimpleBlock(new Identifier("linkedstorage", "storageblock"));
-
- registerSimpleBlock(new Identifier("fabric-furnaces", "obsidian_furnace"));
- registerSimpleBlock(new Identifier("fabric-furnaces", "nether_furnace"));
- registerSimpleBlock(new Identifier("fabric-furnaces", "iron_furnace"));
- registerSimpleBlock(new Identifier("fabric-furnaces", "gold_furnace"));
- registerSimpleBlock(new Identifier("fabric-furnaces", "fabric_furnace"));
- registerSimpleBlock(new Identifier("fabric-furnaces", "ethereal_furnace"));
- registerSimpleBlock(new Identifier("fabric-furnaces", "end_furnace"));
- registerSimpleBlock(new Identifier("fabric-furnaces", "emerald_furnace"));
- registerSimpleBlock(new Identifier("fabric-furnaces", "diamond_furnace"));
- registerSimpleBlock(new Identifier("fabric-furnaces", "crystal_obsidian_furnace"));
- registerSimpleBlock(new Identifier("fabric-furnaces", "crystal_nether_furnace"));
- registerSimpleBlock(new Identifier("fabric-furnaces", "crystal_iron_furnace"));
- registerSimpleBlock(new Identifier("fabric-furnaces", "crystal_gold_furnace"));
- registerSimpleBlock(new Identifier("fabric-furnaces", "crystal_fabric_furnace"));
- registerSimpleBlock(new Identifier("fabric-furnaces", "crystal_ethereal_furnace"));
- registerSimpleBlock(new Identifier("fabric-furnaces", "crystal_end_furnace"));
- registerSimpleBlock(new Identifier("fabric-furnaces", "crystal_emerald_furnace"));
- registerSimpleBlock(new Identifier("fabric-furnaces", "crystal_diamond_furnace"));
-
- registerSimpleBlock(new Identifier("automated_crafting", "auto_crafter"));
-
- registerSimpleBlock(new Identifier("byg", "zelkova_crafting_table"));
- registerSimpleBlock(new Identifier("byg", "witch_hazel_crafting_table"));
- registerSimpleBlock(new Identifier("byg", "willow_crafting_table"));
- registerSimpleBlock(new Identifier("byg", "skyris_crafting_table"));
- registerSimpleBlock(new Identifier("byg", "redwood_crafting_table"));
- registerSimpleBlock(new Identifier("byg", "rainbow_eucalyptus_crafting_table"));
- registerSimpleBlock(new Identifier("byg", "pine_crafting_table"));
- registerSimpleBlock(new Identifier("byg", "aspen_crafting_table"));
- registerSimpleBlock(new Identifier("byg", "baobab_crafting_table"));
- registerSimpleBlock(new Identifier("byg", "blue_enchanted_crafting_table"));
- registerSimpleBlock(new Identifier("byg", "cherry_crafting_table"));
- registerSimpleBlock(new Identifier("byg", "cika_crafting_table"));
- registerSimpleBlock(new Identifier("byg", "cypress_crafting_table"));
- registerSimpleBlock(new Identifier("byg", "ebony_crafting_table"));
- registerSimpleBlock(new Identifier("byg", "fir_crafting_table"));
- registerSimpleBlock(new Identifier("byg", "green_enchanted_crafting_table"));
- registerSimpleBlock(new Identifier("byg", "holly_crafting_table"));
- registerSimpleBlock(new Identifier("byg", "jacaranda_crafting_table"));
- registerSimpleBlock(new Identifier("byg", "mahogany_crafting_table"));
- registerSimpleBlock(new Identifier("byg", "mangrove_crafting_table"));
- registerSimpleBlock(new Identifier("byg", "maple_crafting_table"));
-
- registerSimpleBlock(new Identifier("better-nether", "crafting_table_crimson"));
- registerSimpleBlock(new Identifier("better-nether", "crafting_table_mushroom"));
- registerSimpleBlock(new Identifier("better-nether", "crafting_table_mushroom_fir"));
- registerSimpleBlock(new Identifier("better-nether", "crafting_table_reed"));
- registerSimpleBlock(new Identifier("better-nether", "crafting_table_rubeus"));
- registerSimpleBlock(new Identifier("better-nether", "crafting_table_stalagnate"));
- registerSimpleBlock(new Identifier("better-nether", "crafting_table_warped"));
- registerSimpleBlock(new Identifier("better-nether", "crafting_table_wart"));
- registerSimpleBlock(new Identifier("better-nether", "crafting_table_willow"));
- registerSimpleBlock(new Identifier("better-nether", "basalt_furnace"));
- registerSimpleBlock(new Identifier("better-nether", "blackstone_furnace"));
- registerSimpleBlock(new Identifier("better-nether", "netherrack_furnace"));
+ public static void registerInventoryTab(Identifier itemId) {
+ INVENTORY_TAB_PROVIDER.addItem(itemId);
}
/**
@@ -145,6 +141,9 @@ private static void addModSimpleBlockTabProviders() {
* @param block
*/
public static void registerSimpleBlock(Block block) {
+ if (InventoryTabs.getConfig().debugEnabled) {
+ LOGGER.info("Registering: " + block);
+ }
SIMPLE_BLOCK_TAB_PROVIDER.addBlock(block);
}
@@ -154,18 +153,47 @@ public static void registerSimpleBlock(Block block) {
* @param blockId
*/
public static void registerSimpleBlock(Identifier blockId) {
+ if (InventoryTabs.getConfig().debugEnabled) {
+ LOGGER.info("Registering: " + blockId);
+ }
SIMPLE_BLOCK_TAB_PROVIDER.addBlock(blockId);
}
+
+ public static void removeSimpleBlock(Block block) {
+ SIMPLE_BLOCK_TAB_PROVIDER.removeBlock(block);
+ }
+
+ public static void removeSimpleBlock(Identifier blockId) {
+ SIMPLE_BLOCK_TAB_PROVIDER.removeBlock(blockId);
+ }
+
/**
* Used to register a chest with the chest tab provider.
*
* @param block
*/
public static void registerChest(Block block) {
+ if (InventoryTabs.getConfig().debugEnabled) {
+ LOGGER.info("Registering: " + block);
+ }
CHEST_TAB_PROVIDER.addChestBlock(block);
}
+ public static void registerUniqueBlock(Block block) {
+ if (InventoryTabs.getConfig().debugEnabled) {
+ LOGGER.info("Registering: " + block);
+ }
+ UNIQUE_TAB_PROVIDER.addUniqueBlock(block);
+ }
+
+ public static void registerEntity(Identifier entityId) {
+ if (InventoryTabs.getConfig().debugEnabled) {
+ LOGGER.info("Registering: " + entityId);
+ }
+ ENTITY_TAB_PROVIDER.addEntity(entityId);
+ }
+
/**
* Used to register a chest with the chest tab provider.
*
@@ -177,7 +205,6 @@ public static void registerChest(Identifier blockId) {
public static TabProvider register(Identifier id, TabProvider tabProvider) {
TAB_PROVIDERS.put(id, tabProvider);
-
return tabProvider;
}
diff --git a/src/main/java/com/kqp/inventorytabs/init/InventoryTabs.java b/src/main/java/com/kqp/inventorytabs/init/InventoryTabs.java
index 1cfcc50..db40d74 100644
--- a/src/main/java/com/kqp/inventorytabs/init/InventoryTabs.java
+++ b/src/main/java/com/kqp/inventorytabs/init/InventoryTabs.java
@@ -1,12 +1,23 @@
package com.kqp.inventorytabs.init;
+import com.kqp.inventorytabs.api.TabProviderRegistry;
import me.shedaniel.autoconfig.AutoConfig;
-import me.shedaniel.autoconfig.serializer.JanksonConfigSerializer;
+import me.shedaniel.autoconfig.ConfigHolder;
+import me.shedaniel.autoconfig.serializer.GsonConfigSerializer;
import net.fabricmc.api.ModInitializer;
+import net.fabricmc.fabric.api.client.networking.v1.ClientLoginConnectionEvents;
+import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
+import net.fabricmc.loader.api.FabricLoader;
+import net.minecraft.util.ActionResult;
import net.minecraft.util.Identifier;
public class InventoryTabs implements ModInitializer {
public static final String ID = "inventorytabs";
+ static ConfigHolder inventoryTabsConfig;
+
+ public static boolean isBigInvLoaded;
+ public static boolean isPlayerExLoaded;
+ public static boolean isLevelzLoaded;
public static Identifier id(String path) {
return new Identifier(ID, path);
@@ -14,7 +25,17 @@ public static Identifier id(String path) {
@Override
public void onInitialize() {
- AutoConfig.register(InventoryTabsConfig.class, JanksonConfigSerializer::new);
+ inventoryTabsConfig = AutoConfig.register(InventoryTabsConfig.class, GsonConfigSerializer::new);
+ inventoryTabsConfig.registerSaveListener((configHolder, config) -> {
+ TabProviderRegistry.init("save");
+ return ActionResult.success(true);
+ });
+ ClientLoginConnectionEvents.INIT.register((handler, client) -> TabProviderRegistry.init("load"));
+ ServerLifecycleEvents.END_DATA_PACK_RELOAD.register((server, resourceManager, success) -> TabProviderRegistry.init("reload"));
+
+ isBigInvLoaded = FabricLoader.getInstance().isModLoaded("biginv");
+ isPlayerExLoaded = FabricLoader.getInstance().isModLoaded("playerex");
+ isLevelzLoaded = FabricLoader.getInstance().isModLoaded("levelz");
}
public static InventoryTabsConfig getConfig() {
diff --git a/src/main/java/com/kqp/inventorytabs/init/InventoryTabsClient.java b/src/main/java/com/kqp/inventorytabs/init/InventoryTabsClient.java
index 16029bc..33b82d3 100644
--- a/src/main/java/com/kqp/inventorytabs/init/InventoryTabsClient.java
+++ b/src/main/java/com/kqp/inventorytabs/init/InventoryTabsClient.java
@@ -1,6 +1,5 @@
package com.kqp.inventorytabs.init;
-import com.kqp.inventorytabs.api.TabProviderRegistry;
import com.kqp.inventorytabs.interf.TabManagerContainer;
import org.lwjgl.glfw.GLFW;
@@ -9,6 +8,9 @@
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
+import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.util.InputUtil;
@@ -20,8 +22,6 @@ public class InventoryTabsClient implements ClientModInitializer {
@Override
public void onInitializeClient() {
- TabProviderRegistry.init();
-
// Handle state of tab managerInventoryTabsClient
ClientTickEvents.START_WORLD_TICK.register(world -> {
MinecraftClient client = MinecraftClient.getInstance();
@@ -33,4 +33,8 @@ public void onInitializeClient() {
}
});
}
+
+ public static boolean screenSupported(Screen screen) {
+ return (screen instanceof HandledScreen>) && !(screen instanceof CreativeInventoryScreen);
+ }
}
diff --git a/src/main/java/com/kqp/inventorytabs/init/InventoryTabsConfig.java b/src/main/java/com/kqp/inventorytabs/init/InventoryTabsConfig.java
index e4fdff7..8708756 100644
--- a/src/main/java/com/kqp/inventorytabs/init/InventoryTabsConfig.java
+++ b/src/main/java/com/kqp/inventorytabs/init/InventoryTabsConfig.java
@@ -2,10 +2,27 @@
import me.shedaniel.autoconfig.ConfigData;
import me.shedaniel.autoconfig.annotation.Config;
+import me.shedaniel.autoconfig.annotation.ConfigEntry;
+
+import java.util.Arrays;
+import java.util.List;
@Config(name = "inventory_tabs")
public class InventoryTabsConfig implements ConfigData {
- public boolean doSightChecksFlag = false;
+ @ConfigEntry.Gui.Tooltip
+ public boolean doSightChecksFlag = true;
+ @ConfigEntry.Gui.Tooltip
public boolean rotatePlayer = false;
- public boolean targetAllScreenHandledBlocks = false;
+
+ @ConfigEntry.Gui.Tooltip
+ public List excludeTab = Arrays.asList(
+ "tiered:reforging_station",
+ "#techreborn:block_entities_without_inventories",
+ "#inventorytabs:mod_compat_blacklist"
+ );
+
+ @ConfigEntry.Gui.Tooltip
+ public List includeTab = Arrays.asList();
+
+ public boolean debugEnabled = false;
}
diff --git a/src/main/java/com/kqp/inventorytabs/init/InventoryTabsModMenu.java b/src/main/java/com/kqp/inventorytabs/init/InventoryTabsModMenu.java
new file mode 100644
index 0000000..976cf68
--- /dev/null
+++ b/src/main/java/com/kqp/inventorytabs/init/InventoryTabsModMenu.java
@@ -0,0 +1,15 @@
+package com.kqp.inventorytabs.init;
+
+import io.github.prospector.modmenu.api.ConfigScreenFactory;
+import io.github.prospector.modmenu.api.ModMenuApi;
+import me.shedaniel.autoconfig.AutoConfig;
+import net.fabricmc.api.EnvType;
+import net.fabricmc.api.Environment;
+
+@Environment(EnvType.CLIENT)
+public class InventoryTabsModMenu implements ModMenuApi {
+ @Override
+ public ConfigScreenFactory> getModConfigScreenFactory() {
+ return parent -> AutoConfig.getConfigScreen(InventoryTabsConfig.class, parent).get();
+ }
+}
diff --git a/src/main/java/com/kqp/inventorytabs/mixin/ControlsListWidget$KeyBindingEntryMixin_SoftConflict.java b/src/main/java/com/kqp/inventorytabs/mixin/ControlsListWidget$KeyBindingEntryMixin_SoftConflict.java
new file mode 100644
index 0000000..af502a3
--- /dev/null
+++ b/src/main/java/com/kqp/inventorytabs/mixin/ControlsListWidget$KeyBindingEntryMixin_SoftConflict.java
@@ -0,0 +1,36 @@
+package com.kqp.inventorytabs.mixin;
+
+import java.util.Objects;
+
+import com.kqp.inventorytabs.init.InventoryTabsClient;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.ModifyArg;
+
+import net.minecraft.client.gui.screen.option.ControlsListWidget;
+import net.minecraft.client.option.KeyBinding;
+import net.minecraft.text.Text;
+import net.minecraft.text.TextColor;
+import net.minecraft.util.Formatting;
+
+/**
+ * The 'Tab' keybinding conflicts with the multiplayer player list keybind, but since you can only see the player list when outside the inventory
+ * anyways, the conflict can be soft and not hard.
+ */
+@Mixin(ControlsListWidget.KeyBindingEntry.class)
+public class ControlsListWidget$KeyBindingEntryMixin_SoftConflict {
+ @Shadow @Final private KeyBinding binding;
+
+ @ModifyArg(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/widget/ButtonWidget;setMessage(Lnet/minecraft/text/Text;)V"))
+ public Text setMessage(Text text) {
+ TextColor c = text.getStyle().getColor();
+ if(c != null && c.getRgb() == Objects.requireNonNull(Formatting.RED.getColorValue())) {
+ if(this.binding == InventoryTabsClient.NEXT_TAB_KEY_BIND) {
+ text = text.copy().formatted(Formatting.GOLD);
+ }
+ }
+ return text;
+ }
+}
diff --git a/src/main/java/com/kqp/inventorytabs/mixin/KeyBindingMixin_SoftConflict.java b/src/main/java/com/kqp/inventorytabs/mixin/KeyBindingMixin_SoftConflict.java
new file mode 100644
index 0000000..0709020
--- /dev/null
+++ b/src/main/java/com/kqp/inventorytabs/mixin/KeyBindingMixin_SoftConflict.java
@@ -0,0 +1,64 @@
+package com.kqp.inventorytabs.mixin;
+
+import java.util.Map;
+import java.util.Objects;
+
+import com.kqp.inventorytabs.init.InventoryTabsClient;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
+
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.option.KeyBinding;
+import net.minecraft.client.util.InputUtil;
+
+@Mixin(KeyBinding.class)
+public abstract class KeyBindingMixin_SoftConflict {
+ @Shadow @Final private static Map keysById;
+
+ @Shadow private InputUtil.Key boundKey;
+
+ @Shadow private int timesPressed;
+
+ @Shadow public abstract void setPressed(boolean pressed);
+
+ @Shadow private boolean pressed;
+
+ @Inject(method = "onKeyPressed", at = @At(value = "FIELD", target = "Lnet/minecraft/client/option/KeyBinding;timesPressed:I"),
+ locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true)
+ private static void onKeyPressed(InputUtil.Key key, CallbackInfo ci, KeyBinding binding) {
+ KeyBindingMixin_SoftConflict alternative = (KeyBindingMixin_SoftConflict) (Object) findAlternative(key, binding, InventoryTabsClient.NEXT_TAB_KEY_BIND);
+ if(alternative != null) {
+ alternative.timesPressed++;
+ ci.cancel();
+ }
+ }
+
+ @Inject(method = "setKeyPressed", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/option/KeyBinding;setPressed(Z)V"), cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD)
+ private static void keyPressed(InputUtil.Key key, boolean pressed, CallbackInfo ci, KeyBinding keyBinding) {
+ KeyBinding alternative = findAlternative(key, keyBinding, InventoryTabsClient.NEXT_TAB_KEY_BIND);
+ if(alternative != null) {
+ alternative.setPressed(pressed);
+ ci.cancel();
+ }
+ }
+
+ private static KeyBinding findAlternative(InputUtil.Key key, KeyBinding binding, KeyBinding alternativeTo) {
+ Screen screen = MinecraftClient.getInstance().currentScreen;
+ if(binding == alternativeTo && !InventoryTabsClient.screenSupported(screen)) {
+ for(KeyBinding value : keysById.values()) {
+ KeyBindingMixin_SoftConflict self = (KeyBindingMixin_SoftConflict) (Object) value;
+ InputUtil.Key bound = self.boundKey;
+ if(Objects.equals(bound, key) && value != alternativeTo) {
+ return value;
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/com/kqp/inventorytabs/mixin/VanillaScreenTabAdder.java b/src/main/java/com/kqp/inventorytabs/mixin/VanillaScreenTabAdder.java
index 407f5a2..b5b7994 100644
--- a/src/main/java/com/kqp/inventorytabs/mixin/VanillaScreenTabAdder.java
+++ b/src/main/java/com/kqp/inventorytabs/mixin/VanillaScreenTabAdder.java
@@ -3,6 +3,7 @@
import java.util.HashSet;
import java.util.Set;
+import com.kqp.inventorytabs.init.InventoryTabsClient;
import com.kqp.inventorytabs.interf.TabManagerContainer;
import com.kqp.inventorytabs.tabs.TabManager;
import com.kqp.inventorytabs.tabs.render.TabRenderingHints;
@@ -10,6 +11,10 @@
import com.kqp.inventorytabs.tabs.tab.Tab;
import com.kqp.inventorytabs.util.ChestUtil;
+import net.fabricmc.loader.api.FabricLoader;
+
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.screen.ingame.*;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@@ -20,33 +25,24 @@
import net.fabricmc.api.Environment;
import net.minecraft.block.ChestBlock;
import net.minecraft.client.MinecraftClient;
-import net.minecraft.client.gui.screen.ingame.AbstractFurnaceScreen;
-import net.minecraft.client.gui.screen.ingame.AnvilScreen;
-import net.minecraft.client.gui.screen.ingame.BrewingStandScreen;
-import net.minecraft.client.gui.screen.ingame.CartographyTableScreen;
-import net.minecraft.client.gui.screen.ingame.CraftingScreen;
-import net.minecraft.client.gui.screen.ingame.EnchantmentScreen;
-import net.minecraft.client.gui.screen.ingame.Generic3x3ContainerScreen;
-import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
-import net.minecraft.client.gui.screen.ingame.GrindstoneScreen;
-import net.minecraft.client.gui.screen.ingame.HandledScreen;
-import net.minecraft.client.gui.screen.ingame.HopperScreen;
-import net.minecraft.client.gui.screen.ingame.InventoryScreen;
-import net.minecraft.client.gui.screen.ingame.LoomScreen;
-import net.minecraft.client.gui.screen.ingame.ShulkerBoxScreen;
-import net.minecraft.client.gui.screen.ingame.SmithingScreen;
-import net.minecraft.client.gui.screen.ingame.StonecutterScreen;
import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.Text;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@Environment(EnvType.CLIENT)
@Mixin(HandledScreen.class)
-public class VanillaScreenTabAdder implements TabRenderingHints {
+public abstract class VanillaScreenTabAdder extends Screen implements TabRenderingHints {
+ private static final boolean isBRBLoaded = FabricLoader.getInstance().isModLoaded("brb"); // Better Recipe Book compat
+
+ protected VanillaScreenTabAdder(Text title) {
+ super(title);
+ }
+
@Inject(method = "init", at = @At("RETURN"))
private void initTabRenderer(CallbackInfo callbackInfo) {
- if (screenSupported()) {
+ if (InventoryTabsClient.screenSupported(this)) {
MinecraftClient client = MinecraftClient.getInstance();
TabManager tabManager = ((TabManagerContainer) client).getTabManager();
@@ -97,7 +93,7 @@ private void initTabRenderer(CallbackInfo callbackInfo) {
@Inject(method = "render", at = @At("HEAD"))
protected void drawBackgroundTabs(MatrixStack matrices, int mouseX, int mouseY, float delta,
CallbackInfo callbackInfo) {
- if (screenSupported()) {
+ if (InventoryTabsClient.screenSupported(this)) {
if (!screenDoesDumbBlock()) {
MinecraftClient client = MinecraftClient.getInstance();
TabManager tabManager = ((TabManagerContainer) client).getTabManager();
@@ -110,7 +106,7 @@ protected void drawBackgroundTabs(MatrixStack matrices, int mouseX, int mouseY,
@Inject(method = "render", at = @At("TAIL"))
protected void drawForegroundTabs(MatrixStack matrices, int mouseX, int mouseY, float delta,
CallbackInfo callbackInfo) {
- if (screenSupported()) {
+ if (InventoryTabsClient.screenSupported(this)) {
MinecraftClient client = MinecraftClient.getInstance();
TabManager tabManager = ((TabManagerContainer) client).getTabManager();
@@ -121,7 +117,7 @@ protected void drawForegroundTabs(MatrixStack matrices, int mouseX, int mouseY,
@Inject(method = "mouseClicked", at = @At("HEAD"), cancellable = true)
public void mouseClicked(double mouseX, double mouseY, int button, CallbackInfoReturnable callbackInfo) {
- if (screenSupported()) {
+ if (InventoryTabsClient.screenSupported(this)) {
TabManager tabManager = ((TabManagerContainer) MinecraftClient.getInstance()).getTabManager();
if (tabManager.mouseClicked(mouseX, mouseY, button)) {
@@ -132,7 +128,7 @@ public void mouseClicked(double mouseX, double mouseY, int button, CallbackInfoR
@Inject(method = "keyPressed", at = @At("HEAD"), cancellable = true)
public void keyPressed(int keyCode, int scanCode, int modifiers, CallbackInfoReturnable callbackInfo) {
- if (screenSupported()) {
+ if (InventoryTabsClient.screenSupported(this)) {
TabManager tabManager = ((TabManagerContainer) MinecraftClient.getInstance()).getTabManager();
if (tabManager.keyPressed(keyCode, scanCode, modifiers)) {
@@ -143,21 +139,22 @@ public void keyPressed(int keyCode, int scanCode, int modifiers, CallbackInfoRet
@Override
public int getTopRowXOffset() {
- HandledScreen> screen = (HandledScreen>) (Object) this;
- if (screen instanceof InventoryScreen) {
- if (((InventoryScreen) screen).getRecipeBookWidget().isOpen()) {
- return 77;
- }
- } else if (screen instanceof AbstractFurnaceScreen) {
- if (((AbstractFurnaceScreen>) screen).recipeBook.isOpen()) {
- return 77;
- }
- } else if (screen instanceof CraftingScreen) {
- if (((CraftingScreen) screen).getRecipeBookWidget().isOpen()) {
- return 77;
+ if (!isBRBLoaded) {
+ HandledScreen> screen = (HandledScreen>) (Object) this;
+ if (screen instanceof InventoryScreen) {
+ if (((InventoryScreen) screen).getRecipeBookWidget().isOpen()) {
+ return 77;
+ }
+ } else if (screen instanceof AbstractFurnaceScreen) {
+ if (((AbstractFurnaceScreen>) screen).recipeBook.isOpen()) {
+ return 77;
+ }
+ } else if (screen instanceof CraftingScreen) {
+ if (((CraftingScreen) screen).getRecipeBookWidget().isOpen()) {
+ return 77;
+ }
}
}
-
return 0;
}
@@ -170,20 +167,7 @@ public int getBottomRowXOffset() {
public int getBottomRowYOffset() {
return screenNeedsOffset() ? -1 : 0;
}
-
- private boolean screenSupported() {
- HandledScreen> screen = (HandledScreen>) (Object) this;
-
- return screen instanceof GenericContainerScreen || screen instanceof InventoryScreen
- || screen instanceof AbstractFurnaceScreen || screen instanceof AnvilScreen
- || screen instanceof CraftingScreen || screen instanceof ShulkerBoxScreen
- || screen instanceof EnchantmentScreen || screen instanceof BrewingStandScreen
- || screen instanceof SmithingScreen || screen instanceof CartographyTableScreen
- || screen instanceof LoomScreen || screen instanceof StonecutterScreen
- || screen instanceof GrindstoneScreen || screen instanceof HopperScreen
- || screen instanceof Generic3x3ContainerScreen;
- }
-
+
private boolean screenDoesDumbBlock() {
HandledScreen> screen = (HandledScreen>) (Object) this;
diff --git a/src/main/java/com/kqp/inventorytabs/tabs/TabManager.java b/src/main/java/com/kqp/inventorytabs/tabs/TabManager.java
index 995be96..e60cf5e 100644
--- a/src/main/java/com/kqp/inventorytabs/tabs/TabManager.java
+++ b/src/main/java/com/kqp/inventorytabs/tabs/TabManager.java
@@ -11,20 +11,22 @@
import com.kqp.inventorytabs.mixin.accessor.HandledScreenAccessor;
import com.kqp.inventorytabs.tabs.render.TabRenderInfo;
import com.kqp.inventorytabs.tabs.render.TabRenderer;
+import com.kqp.inventorytabs.tabs.render.TabRenderingHints;
+import com.kqp.inventorytabs.tabs.tab.PlayerInventoryTab;
import com.kqp.inventorytabs.tabs.tab.Tab;
import com.kqp.inventorytabs.util.MouseUtil;
-import org.lwjgl.glfw.GLFW;
-
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.sound.PositionedSoundInstance;
-import net.minecraft.client.util.InputUtil;
import net.minecraft.network.packet.c2s.play.CloseHandledScreenC2SPacket;
import net.minecraft.sound.SoundEvents;
+import static com.kqp.inventorytabs.init.InventoryTabs.*;
+
/**
* Manages everything related to tabs.
*/
@@ -53,6 +55,12 @@ public void update() {
public void setCurrentTab(Tab tab) {
this.currentTab = tab;
}
+ public void removeTabs() {
+ for (int i = 0; i < tabs.size(); i++) {
+ tabs.remove(i);
+ i--;
+ }
+ }
private void refreshAvailableTabs() {
// Remove old ones
@@ -68,6 +76,17 @@ private void refreshAvailableTabs() {
tabProvider.addAvailableTabs(MinecraftClient.getInstance().player, tabs);
});
+ if (currentTab != null) {
+ for (int i = 0; i < tabs.size(); i++) {
+ Tab tab = tabs.get(i);
+ if (currentTab != tab && currentTab.equals(tab)) {
+ // We've come across a tab we already have open
+ tabs.set(i, currentTab);
+ break;
+ }
+ }
+ }
+
// Sort
tabs.sort(
Comparator.comparing(Tab::getPriority).reversed().thenComparing(tab -> tab.getHoverText().getString()));
@@ -85,7 +104,7 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) {
}
// Check back button
- if (new Rectangle(x - TabRenderer.BUTTON_WIDTH - 4, y - 16, TabRenderer.BUTTON_WIDTH,
+ if (new Rectangle(x - TabRenderer.BUTTON_WIDTH - 4 + ((TabRenderingHints) currentScreen).getTopRowXOffset(), y - 16, TabRenderer.BUTTON_WIDTH,
TabRenderer.BUTTON_HEIGHT).contains(mouseX, mouseY)) {
if (canGoBackAPage()) {
setCurrentPage(currentPage - 1);
@@ -96,7 +115,7 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) {
}
// Check forward button
- if (new Rectangle(x + guiWidth + 4, y - 16, TabRenderer.BUTTON_WIDTH, TabRenderer.BUTTON_HEIGHT)
+ if (new Rectangle(x + guiWidth + 4 + ((TabRenderingHints) currentScreen).getTopRowXOffset(), y - 16, TabRenderer.BUTTON_WIDTH, TabRenderer.BUTTON_HEIGHT)
.contains(mouseX, mouseY)) {
if (canGoForwardAPage()) {
setCurrentPage(currentPage + 1);
@@ -132,16 +151,18 @@ public boolean mouseClicked(double mouseX, double mouseY, int button) {
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
if (InventoryTabsClient.NEXT_TAB_KEY_BIND.matchesKey(keyCode, scanCode)) {
int currentTabIndex = tabs.indexOf(currentTab);
-
- if (InputUtil.isKeyPressed(MinecraftClient.getInstance().getWindow().getHandle(),
- GLFW.GLFW_KEY_LEFT_SHIFT)) {
+ if (Screen.hasShiftDown()) {
if (currentTabIndex > 0) {
onTabClick(tabs.get(currentTabIndex - 1));
+ } else {
+ onTabClick(tabs.get(tabs.size() - 1));
}
return true;
} else {
if (currentTabIndex < tabs.size() - 1) {
onTabClick(tabs.get(currentTabIndex + 1));
+ } else {
+ onTabClick(tabs.get(0));
}
return true;
@@ -164,7 +185,9 @@ public void onTabClick(Tab tab) {
MouseUtil.push();
// Set tab open flag
- tabOpenedRecently = true;
+ if (!(tab instanceof PlayerInventoryTab)) {
+ tabOpenedRecently = true;
+ }
// Close any handled screens
// This fixes the inventory desync issue
@@ -190,8 +213,13 @@ public void onOpenTab(Tab tab) {
public int pageOf(Tab tab) {
int index = tabs.indexOf(tab);
-
- return index / (getMaxRowLength() * 2);
+ if(isBigInvLoaded) {
+ return index / (getMaxRowLength() * 2 + 5);
+ } else if(isPlayerExLoaded || isLevelzLoaded) {
+ return index / (getMaxRowLength() * 2 - 2);
+ } else {
+ return index / (getMaxRowLength() * 2);
+ }
}
public int getMaxRowLength() {
@@ -210,7 +238,13 @@ public HandledScreen> getCurrentScreen() {
}
public void setCurrentPage(int page) {
- if (page > 0 && tabs.size() < getMaxRowLength() * 2) {
+ int maxRowLength = getMaxRowLength() * 2;
+ if (isPlayerExLoaded) {
+ maxRowLength =- 3;
+ } else if (isLevelzLoaded) {
+ maxRowLength =- 2;
+ }
+ if (page > 0 && tabs.size() < maxRowLength) {
System.err.println("Not enough tabs to paginate, ignoring");
return;
@@ -234,7 +268,15 @@ public boolean screenOpenedViaTab() {
}
public int getMaxPages() {
- return tabs.size() / (getMaxRowLength() * 2 + 1);
+ if(isBigInvLoaded) {
+ return tabs.size() / (getMaxRowLength() * 2 + 6);
+ } else if(isPlayerExLoaded) {
+ return tabs.size() / (getMaxRowLength() * 2 - 2);
+ } else if(isLevelzLoaded) {
+ return tabs.size() / (getMaxRowLength() * 2 - 1);
+ } else {
+ return tabs.size() / (getMaxRowLength() * 2 + 1);
+ }
}
public boolean canGoBackAPage() {
diff --git a/src/main/java/com/kqp/inventorytabs/tabs/provider/ChestTabProvider.java b/src/main/java/com/kqp/inventorytabs/tabs/provider/ChestTabProvider.java
index c93350f..70f7eab 100644
--- a/src/main/java/com/kqp/inventorytabs/tabs/provider/ChestTabProvider.java
+++ b/src/main/java/com/kqp/inventorytabs/tabs/provider/ChestTabProvider.java
@@ -38,9 +38,7 @@ public void addAvailableTabs(ClientPlayerEntity player, List tabs) {
// Add any chests that are blocked
chestTabs.stream().filter(tab -> ChestBlock.isChestBlocked(world, tab.blockPos)).forEach(tabsToRemove::add);
- for (int i = 0; i < chestTabs.size(); i++) {
- ChestTab tab = chestTabs.get(i);
-
+ for (ChestTab tab : chestTabs) {
if (!tabsToRemove.contains(tab)) {
if (ChestUtil.isDouble(world, tab.blockPos)) {
tabsToRemove.add(new ChestTab(tab.blockId, ChestUtil.getOtherChestBlockPos(world, tab.blockPos)));
diff --git a/src/main/java/com/kqp/inventorytabs/tabs/provider/EntityTabProvider.java b/src/main/java/com/kqp/inventorytabs/tabs/provider/EntityTabProvider.java
new file mode 100644
index 0000000..fac2ced
--- /dev/null
+++ b/src/main/java/com/kqp/inventorytabs/tabs/provider/EntityTabProvider.java
@@ -0,0 +1,62 @@
+package com.kqp.inventorytabs.tabs.provider;
+
+import com.kqp.inventorytabs.tabs.tab.Tab;
+import net.minecraft.client.network.ClientPlayerEntity;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.inventory.Inventory;
+import net.minecraft.inventory.InventoryChangedListener;
+import net.minecraft.util.math.Box;
+import net.minecraft.util.math.Vec3d;
+import net.minecraft.world.World;
+
+import java.util.List;
+
+public abstract class EntityTabProvider implements TabProvider {
+ public static final int SEARCH_DISTANCE = 5;
+ @Override
+ public void addAvailableTabs(ClientPlayerEntity player, List tabs) {
+ World world = player.world;
+ List entityList = world.getNonSpectatingEntities(Entity.class, new Box(player.getBlockPos().getX()-SEARCH_DISTANCE, player.getBlockPos().getY()-SEARCH_DISTANCE, player.getBlockPos().getZ()-SEARCH_DISTANCE, player.getBlockPos().getX()+SEARCH_DISTANCE, player.getBlockPos().getY()+SEARCH_DISTANCE, player.getBlockPos().getZ()+SEARCH_DISTANCE));
+
+ for (Entity entity : entityList) {
+ if (!(entity instanceof PlayerEntity) && ((entity instanceof Inventory) || (entity instanceof InventoryChangedListener))) {
+ if (matches(entity)) {
+ boolean add = false;
+
+ Vec3d playerHead = player.getPos().add(0D, player.getEyeHeight(player.getPose()), 0D);
+ Vec3d blockVec = new Vec3d(entity.getX() + 0.5D, entity.getY() + 0.5D,
+ entity.getZ() + 0.5D);
+
+ if (blockVec.subtract(playerHead).lengthSquared() <= SEARCH_DISTANCE * SEARCH_DISTANCE) {
+ add = true;
+ }
+
+
+ if (add) {
+ Tab tab = createTab(entity);
+
+ if (!tabs.contains(tab)) {
+ tabs.add(tab);
+ }
+ }
+ }
+ }
+ }
+ }
+ /**
+ * Checks to see if block at passsed block position matches criteria.
+ *
+ * @param entity
+ * @return
+ */
+ public abstract boolean matches(Entity entity);
+
+ /**
+ * Method to create tabs.
+ *
+ * @param entity
+ * @return
+ */
+ public abstract Tab createTab(Entity entity);
+}
\ No newline at end of file
diff --git a/src/main/java/com/kqp/inventorytabs/tabs/provider/InventoryTabProvider.java b/src/main/java/com/kqp/inventorytabs/tabs/provider/InventoryTabProvider.java
new file mode 100644
index 0000000..46d2a51
--- /dev/null
+++ b/src/main/java/com/kqp/inventorytabs/tabs/provider/InventoryTabProvider.java
@@ -0,0 +1,44 @@
+package com.kqp.inventorytabs.tabs.provider;
+
+import com.kqp.inventorytabs.tabs.tab.InventoryTab;
+import com.kqp.inventorytabs.tabs.tab.Tab;
+import net.minecraft.client.network.ClientPlayerEntity;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.Identifier;
+import net.minecraft.util.registry.Registry;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+public class InventoryTabProvider implements TabProvider {
+ private static final Set inventoryItems = new HashSet<>();
+
+ @Override
+ public void addAvailableTabs(ClientPlayerEntity player, List tabs) {
+ Set- itemSet = inventoryItems.stream().map(Registry.ITEM::get).collect(Collectors.toSet());
+ for (Item item : itemSet) {
+ if (player.inventory.contains(new ItemStack(item))) {
+ Tab tab = new InventoryTab(item);
+ if (tabs.stream().filter(c -> c instanceof InventoryTab).noneMatch(c -> ((InventoryTab) c).itemId == item)) {
+ tabs.add(tab);
+ }
+ }
+ }
+ }
+
+ public void addItem(Identifier blockId) {
+ inventoryItems.add(blockId);
+ }
+
+ public Set getItemIds() {
+ return inventoryItems;
+ }
+
+ public static Set
- getItems() {
+ return inventoryItems.stream().map(Registry.ITEM::get).collect(Collectors.toSet());
+ }
+
+}
diff --git a/src/main/java/com/kqp/inventorytabs/tabs/provider/LecternTabProvider.java b/src/main/java/com/kqp/inventorytabs/tabs/provider/LecternTabProvider.java
new file mode 100644
index 0000000..e5f0aa3
--- /dev/null
+++ b/src/main/java/com/kqp/inventorytabs/tabs/provider/LecternTabProvider.java
@@ -0,0 +1,52 @@
+package com.kqp.inventorytabs.tabs.provider;
+
+import com.kqp.inventorytabs.tabs.tab.SimpleBlockTab;
+import com.kqp.inventorytabs.tabs.tab.Tab;
+import net.minecraft.block.BlockState;
+import net.minecraft.block.Blocks;
+import net.minecraft.block.entity.BlockEntity;
+import net.minecraft.block.entity.LecternBlockEntity;
+import net.minecraft.client.network.ClientPlayerEntity;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.registry.Registry;
+import net.minecraft.world.World;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static net.minecraft.block.LecternBlock.HAS_BOOK;
+//import static net.minecraft.state.property.Properties.HAS_BOOK;
+
+public class LecternTabProvider extends BlockTabProvider {
+ @Override
+ public void addAvailableTabs(ClientPlayerEntity player, List tabs) {
+ super.addAvailableTabs(player, tabs);
+ Set tabsToRemove = new HashSet<>();
+ List lecternTabs = tabs.stream().filter(tab -> tab instanceof SimpleBlockTab).map(tab -> (SimpleBlockTab) tab)
+ .filter(tab -> tab.blockId == Registry.BLOCK.getId(Blocks.LECTERN)).collect(Collectors.toList());
+ lecternTabs.stream().filter(tab -> {
+ BlockEntity blockEntity = player.world.getBlockEntity(tab.blockPos);
+
+ if (blockEntity instanceof LecternBlockEntity) {
+ BlockState blockState = player.world.getBlockState(tab.blockPos);
+
+ return !blockState.get(HAS_BOOK);
+ }
+
+ return false;
+ }).forEach(tabsToRemove::add);
+
+ tabs.removeAll(tabsToRemove);
+ }
+ @Override
+ public boolean matches(World world, BlockPos pos) {
+ return false;
+ }
+
+ @Override
+ public Tab createTab(World world, BlockPos pos) {
+ return null;
+ }
+}
diff --git a/src/main/java/com/kqp/inventorytabs/tabs/provider/PlayerInventoryTabProvider.java b/src/main/java/com/kqp/inventorytabs/tabs/provider/PlayerInventoryTabProvider.java
index a14de88..099c300 100644
--- a/src/main/java/com/kqp/inventorytabs/tabs/provider/PlayerInventoryTabProvider.java
+++ b/src/main/java/com/kqp/inventorytabs/tabs/provider/PlayerInventoryTabProvider.java
@@ -10,12 +10,11 @@
public class PlayerInventoryTabProvider implements TabProvider {
@Override
public void addAvailableTabs(ClientPlayerEntity player, List tabs) {
- for (int i = 0; i < tabs.size(); i++) {
- if (tabs.get(i) instanceof PlayerInventoryTab) {
+ for (Tab tab : tabs) {
+ if (tab instanceof PlayerInventoryTab) {
return;
}
}
-
tabs.add(new PlayerInventoryTab());
}
}
diff --git a/src/main/java/com/kqp/inventorytabs/tabs/provider/ShulkerBoxTabProvider.java b/src/main/java/com/kqp/inventorytabs/tabs/provider/ShulkerBoxTabProvider.java
index c40c459..b5af14d 100644
--- a/src/main/java/com/kqp/inventorytabs/tabs/provider/ShulkerBoxTabProvider.java
+++ b/src/main/java/com/kqp/inventorytabs/tabs/provider/ShulkerBoxTabProvider.java
@@ -5,6 +5,7 @@
import java.util.Set;
import java.util.stream.Collectors;
+import com.kqp.inventorytabs.util.ShulkerBoxBlockInvoker;
import com.kqp.inventorytabs.tabs.tab.SimpleBlockTab;
import com.kqp.inventorytabs.tabs.tab.Tab;
@@ -13,9 +14,7 @@
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.ShulkerBoxBlockEntity;
import net.minecraft.client.network.ClientPlayerEntity;
-import net.minecraft.entity.mob.ShulkerLidCollisions;
import net.minecraft.util.math.BlockPos;
-import net.minecraft.util.math.Direction;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.World;
@@ -39,12 +38,9 @@ public void addAvailableTabs(ClientPlayerEntity player, List tabs) {
if (blockEntity instanceof ShulkerBoxBlockEntity) {
BlockState blockState = player.world.getBlockState(tab.blockPos);
- Direction direction = blockState.get(ShulkerBoxBlock.FACING);
- if (((ShulkerBoxBlockEntity) blockEntity)
- .getAnimationStage() == ShulkerBoxBlockEntity.AnimationStage.CLOSED) {
- return !player.world.isSpaceEmpty(ShulkerLidCollisions.getLidCollisionBox(tab.blockPos, direction));
- }
+ return !ShulkerBoxBlockInvoker.invokeCanOpen(blockState, player.world, tab.blockPos,
+ (ShulkerBoxBlockEntity) blockEntity);
}
return false;
diff --git a/src/main/java/com/kqp/inventorytabs/tabs/provider/SimpleBlockTabProvider.java b/src/main/java/com/kqp/inventorytabs/tabs/provider/SimpleBlockTabProvider.java
index b0ad0fe..db405e3 100644
--- a/src/main/java/com/kqp/inventorytabs/tabs/provider/SimpleBlockTabProvider.java
+++ b/src/main/java/com/kqp/inventorytabs/tabs/provider/SimpleBlockTabProvider.java
@@ -31,6 +31,14 @@ public void addBlock(Identifier identifier) {
blockIds.add(identifier);
}
+ public void removeBlock(Block block) {
+ blockIds.remove(Registry.BLOCK.getId(block));
+ }
+
+ public void removeBlock(Identifier identifier) {
+ blockIds.remove(identifier);
+ }
+
public Set getBlockIds() {
return this.blockIds;
}
diff --git a/src/main/java/com/kqp/inventorytabs/tabs/provider/SimpleEntityTabProvider.java b/src/main/java/com/kqp/inventorytabs/tabs/provider/SimpleEntityTabProvider.java
new file mode 100644
index 0000000..a4c5f69
--- /dev/null
+++ b/src/main/java/com/kqp/inventorytabs/tabs/provider/SimpleEntityTabProvider.java
@@ -0,0 +1,41 @@
+package com.kqp.inventorytabs.tabs.provider;
+
+import com.kqp.inventorytabs.tabs.tab.SimpleEntityTab;
+import com.kqp.inventorytabs.tabs.tab.Tab;
+import net.minecraft.client.network.ClientPlayerEntity;
+import net.minecraft.entity.Entity;
+import net.minecraft.util.Identifier;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class SimpleEntityTabProvider extends EntityTabProvider {
+ private final Set entities = new HashSet<>();
+
+ public SimpleEntityTabProvider() {
+ }
+
+ @Override
+ public void addAvailableTabs(ClientPlayerEntity player, List tabs) {
+ super.addAvailableTabs(player, tabs);
+ // Set tabsToRemove = new HashSet<>();
+ // List entityTabs = tabs.stream().filter(tab -> tab instanceof SimpleEntityTab).map(tab -> (SimpleEntityTab) tab)
+ // .filter(tab -> entities.contains(tab.entityId)).toList();
+ // World world = player.world;
+ }
+
+ @Override
+ public boolean matches(Entity entity) {
+ return entities.contains(new Identifier("minecraft:entity.minecraft.chest_minecart"));
+ }
+
+ public void addEntity(Identifier entityId) {
+ entities.add(entityId);
+ }
+
+ @Override
+ public Tab createTab(Entity entity) {
+ return new SimpleEntityTab(entity);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/kqp/inventorytabs/tabs/provider/UniqueTabProvider.java b/src/main/java/com/kqp/inventorytabs/tabs/provider/UniqueTabProvider.java
new file mode 100644
index 0000000..2a9fd4f
--- /dev/null
+++ b/src/main/java/com/kqp/inventorytabs/tabs/provider/UniqueTabProvider.java
@@ -0,0 +1,55 @@
+package com.kqp.inventorytabs.tabs.provider;
+
+import com.kqp.inventorytabs.tabs.tab.SimpleBlockTab;
+import com.kqp.inventorytabs.tabs.tab.Tab;
+import net.minecraft.block.Block;
+import net.minecraft.client.network.ClientPlayerEntity;
+import net.minecraft.util.Identifier;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.registry.Registry;
+import net.minecraft.world.World;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * Provides tabs for blocks that should only have one tab at a time (e.g. Crafting Tables).
+ **/
+public class UniqueTabProvider extends BlockTabProvider {
+ private final Set uniqueBlocks = new HashSet<>();
+
+ @Override
+ public void addAvailableTabs(ClientPlayerEntity player, List tabs) {
+ super.addAvailableTabs(player, tabs);
+ Set tabsToRemove = new HashSet<>();
+ List craftingTableTabs = tabs.stream().filter(tab -> tab instanceof SimpleBlockTab).map(tab -> (SimpleBlockTab) tab)
+ .filter(tab -> uniqueBlocks.contains(tab.blockId)).collect(Collectors.toList());
+
+ for (SimpleBlockTab tab : craftingTableTabs) {
+ if (!tabsToRemove.add(tab.blockId)) {
+ tabs.remove(tab);
+ }
+ }
+ }
+
+ public void addUniqueBlock(Block block) {
+ uniqueBlocks.add(Registry.BLOCK.getId(block));
+ }
+
+ public void addUniqueBlock(Identifier blockId) {
+ uniqueBlocks.add(blockId);
+ }
+
+ public void removeUniqueBlockId(Identifier blockId) {
+ uniqueBlocks.remove(blockId);
+ }
+ @Override
+ public boolean matches(World world, BlockPos pos) {
+ return uniqueBlocks.contains(Registry.BLOCK.getId(world.getBlockState(pos).getBlock()));
+ }
+
+ @Override
+ public Tab createTab(World world, BlockPos pos) {
+ return new SimpleBlockTab(Registry.BLOCK.getId(world.getBlockState(pos).getBlock()), pos);
+ }
+}
diff --git a/src/main/java/com/kqp/inventorytabs/tabs/render/TabRenderer.java b/src/main/java/com/kqp/inventorytabs/tabs/render/TabRenderer.java
index 640c618..fad6721 100644
--- a/src/main/java/com/kqp/inventorytabs/tabs/render/TabRenderer.java
+++ b/src/main/java/com/kqp/inventorytabs/tabs/render/TabRenderer.java
@@ -1,6 +1,8 @@
package com.kqp.inventorytabs.tabs.render;
import java.awt.Rectangle;
+import java.util.ArrayList;
+import java.util.List;
import com.kqp.inventorytabs.init.InventoryTabs;
import com.kqp.inventorytabs.mixin.accessor.HandledScreenAccessor;
@@ -14,8 +16,11 @@
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
+import static com.kqp.inventorytabs.init.InventoryTabs.*;
+
/**
* Handles the rendering of tabs.
*/
@@ -86,7 +91,9 @@ private void drawButtons(MatrixStack matrices, double mouseX, double mouseY) {
// Drawing back button
int x = oX - BUTTON_WIDTH - 4;
+ x += ((TabRenderingHints) currentScreen).getTopRowXOffset();
int y = oY - 16;
+ y += ((TabRenderingHints) currentScreen).getTopRowYOffset();
boolean hovered = new Rectangle(x, y, BUTTON_WIDTH, BUTTON_HEIGHT).contains(mouseX, mouseY);
int u = 0;
u += tabManager.canGoBackAPage() && hovered ? BUTTON_WIDTH * 2 : 0;
@@ -95,7 +102,9 @@ private void drawButtons(MatrixStack matrices, double mouseX, double mouseY) {
// Drawing forward button
x = oX + width + 4;
+ x += ((TabRenderingHints) currentScreen).getTopRowXOffset();
y = oY - 16;
+ y += ((TabRenderingHints) currentScreen).getTopRowYOffset();
hovered = new Rectangle(x, y, BUTTON_WIDTH, BUTTON_HEIGHT).contains(mouseX, mouseY);
u = 15;
u += tabManager.canGoForwardAPage() && hovered ? BUTTON_WIDTH * 2 : 0;
@@ -105,14 +114,15 @@ private void drawButtons(MatrixStack matrices, double mouseX, double mouseY) {
private void drawPageText(MatrixStack matrices) {
if (tabManager.getMaxPages() > 1 && pageTextRefreshTime > 0) {
- RenderSystem.pushMatrix();
+ // RenderSystem.pushMatrix();
+ // TODO: Figure out rendering
int color = 0xFFFFFFFF;
if (pageTextRefreshTime <= 20) {
RenderSystem.disableTexture();
RenderSystem.enableBlend();
- RenderSystem.disableAlphaTest();
+ // RenderSystem.disableAlphaTest();
RenderSystem.defaultBlendFunc();
RenderSystem.colorMask(true, true, true, true);
float transparency = pageTextRefreshTime / 20F;
@@ -134,7 +144,7 @@ private void drawPageText(MatrixStack matrices) {
MinecraftClient.getInstance().textRenderer.draw(matrices, text, x, y, color);
- RenderSystem.popMatrix();
+ // RenderSystem.popMatrix();
}
}
@@ -167,7 +177,16 @@ public TabRenderInfo[] getTabRenderInfos() {
HandledScreen> currentScreen = tabManager.getCurrentScreen();
int maxRowLength = tabManager.getMaxRowLength();
- int numVisibleTabs = maxRowLength * 2;
+ int numVisibleTabs;
+ if(isBigInvLoaded) {
+ numVisibleTabs = (maxRowLength * 2) + 5;
+ } else if (isPlayerExLoaded) {
+ numVisibleTabs = (maxRowLength * 2) - 3;
+ } else if (isLevelzLoaded) {
+ numVisibleTabs = (maxRowLength * 2) - 2;
+ }else {
+ numVisibleTabs = maxRowLength * 2;
+ }
int startingIndex = tabManager.currentPage * numVisibleTabs;
TabRenderInfo[] tabRenderInfo = new TabRenderInfo[numVisibleTabs];
@@ -180,6 +199,11 @@ public TabRenderInfo[] getTabRenderInfos() {
// Setup basic info
Tab tab = tabManager.tabs.get(startingIndex + i);
boolean topRow = i < maxRowLength;
+ if(isPlayerExLoaded) {
+ topRow = i < maxRowLength - 3;
+ } else if(isLevelzLoaded) {
+ topRow = i < maxRowLength - 2;
+ }
boolean selected = tab == tabManager.currentTab;
// Create tab info object
@@ -195,13 +219,13 @@ public TabRenderInfo[] getTabRenderInfos() {
// Calc y value
if (topRow) {
- tabInfo.y = y - 26;
-
- if (selected) {
- tabInfo.y = y - 28;
- }
+ tabInfo.y = y - 28;
} else {
- tabInfo.y = y + ((HandledScreenAccessor) currentScreen).getBackgroundHeight() - 4;
+ if(isBigInvLoaded) {
+ tabInfo.y = y + ((HandledScreenAccessor) currentScreen).getBackgroundHeight() + 32;
+ } else {
+ tabInfo.y = y + ((HandledScreenAccessor) currentScreen).getBackgroundHeight() - 4;
+ }
}
// Calc texture dimensions
@@ -242,14 +266,33 @@ public TabRenderInfo[] getTabRenderInfos() {
// Apply rendering hints
if (currentScreen instanceof TabRenderingHints) {
if (topRow) {
- tabInfo.x += ((TabRenderingHints) currentScreen).getTopRowXOffset();
+ if(isPlayerExLoaded) {
+ tabInfo.x += ((TabRenderingHints) currentScreen).getTopRowXOffset() + 87;
+ tabInfo.itemX += ((TabRenderingHints) currentScreen).getTopRowXOffset() + 87;
+ } else if(isLevelzLoaded) {
+ tabInfo.x += ((TabRenderingHints) currentScreen).getTopRowXOffset() + 54;
+ tabInfo.itemX += ((TabRenderingHints) currentScreen).getTopRowXOffset() + 54;
+ }else {
+ tabInfo.x += ((TabRenderingHints) currentScreen).getTopRowXOffset();
+ tabInfo.itemX += ((TabRenderingHints) currentScreen).getTopRowXOffset();
+ }
tabInfo.y += ((TabRenderingHints) currentScreen).getTopRowYOffset();
- tabInfo.itemX += ((TabRenderingHints) currentScreen).getTopRowXOffset();
tabInfo.itemY += ((TabRenderingHints) currentScreen).getTopRowYOffset();
} else {
- tabInfo.x += ((TabRenderingHints) currentScreen).getBottomRowXOffset();
+ if(isBigInvLoaded) {
+ tabInfo.x += ((TabRenderingHints) currentScreen).getBottomRowXOffset() - 145;
+ tabInfo.itemX += ((TabRenderingHints) currentScreen).getBottomRowXOffset() - 145;
+ } else if(isPlayerExLoaded) {
+ tabInfo.x += ((TabRenderingHints) currentScreen).getBottomRowXOffset() + 86;
+ tabInfo.itemX += ((TabRenderingHints) currentScreen).getBottomRowXOffset() + 86;
+ } else if(isLevelzLoaded) {
+ tabInfo.x += ((TabRenderingHints) currentScreen).getBottomRowXOffset() + 60;
+ tabInfo.itemX += ((TabRenderingHints) currentScreen).getBottomRowXOffset() + 60;
+ }else {
+ tabInfo.x += ((TabRenderingHints) currentScreen).getBottomRowXOffset();
+ tabInfo.itemX += ((TabRenderingHints) currentScreen).getBottomRowXOffset();
+ }
tabInfo.y += ((TabRenderingHints) currentScreen).getBottomRowYOffset();
- tabInfo.itemX += ((TabRenderingHints) currentScreen).getBottomRowXOffset();
tabInfo.itemY += ((TabRenderingHints) currentScreen).getBottomRowYOffset();
}
}
diff --git a/src/main/java/com/kqp/inventorytabs/tabs/tab/ChestTab.java b/src/main/java/com/kqp/inventorytabs/tabs/tab/ChestTab.java
index 786f33a..5a2d5a6 100644
--- a/src/main/java/com/kqp/inventorytabs/tabs/tab/ChestTab.java
+++ b/src/main/java/com/kqp/inventorytabs/tabs/tab/ChestTab.java
@@ -1,17 +1,38 @@
package com.kqp.inventorytabs.tabs.tab;
+import com.kqp.inventorytabs.mixin.accessor.ScreenAccessor;
+import com.kqp.inventorytabs.tabs.render.TabRenderInfo;
+import com.kqp.inventorytabs.util.ChestUtil;
import net.minecraft.block.ChestBlock;
import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.font.TextRenderer;
+import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.network.ClientPlayerEntity;
+import net.minecraft.client.render.item.ItemRenderer;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.entity.decoration.ItemFrameEntity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Box;
+import net.minecraft.util.registry.Registry;
+import net.minecraft.world.World;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
+
+import static com.kqp.inventorytabs.util.ChestUtil.getOtherChestBlockPos;
/**
* Tab for chests
*/
public class ChestTab extends SimpleBlockTab {
+ ItemStack itemStack;
public ChestTab(Identifier blockId, BlockPos blockPos) {
super(blockId, blockPos);
+ this.itemStack = new ItemStack(Registry.BLOCK.get(blockId));
}
@Override
@@ -24,4 +45,45 @@ public boolean shouldBeRemoved() {
return super.shouldBeRemoved();
}
+
+ @Override
+ public Text getHoverText() {
+ if (itemStack.hasCustomName()) {
+ return itemStack.getName();
+ }
+ return super.getHoverText();
+ }
+
+ @Override
+ public void renderTabIcon(MatrixStack matrices, TabRenderInfo tabRenderInfo, HandledScreen> currentScreen) {
+ ItemStack itemStack = getItemFrame();
+ ItemRenderer itemRenderer = ((ScreenAccessor) currentScreen).getItemRenderer();
+ TextRenderer textRenderer = ((ScreenAccessor) currentScreen).getTextRenderer();
+ itemRenderer.zOffset = 100.0F;
+ itemRenderer.renderInGuiWithOverrides(itemStack, tabRenderInfo.itemX, tabRenderInfo.itemY);
+ itemRenderer.renderGuiItemOverlay(textRenderer, itemStack, tabRenderInfo.itemX, tabRenderInfo.itemY);
+ itemRenderer.zOffset = 0.0F;
+ }
+
+ public ItemStack getItemFrame() {
+ World world = MinecraftClient.getInstance().player.world;
+ itemStack = new ItemStack(world.getBlockState(blockPos).getBlock());
+ BlockPos doubleChestPos = ChestUtil.isDouble(world, blockPos) ? getOtherChestBlockPos(world, blockPos) : blockPos;
+ Box box = new Box(blockPos, doubleChestPos);
+ double x = box.minX; double y = box.minY; double z = box.minZ;
+ double x1 = box.maxX; double y1 = box.maxY; double z1 = box.maxZ;
+ List list1 = world.getNonSpectatingEntities(ItemFrameEntity.class, new Box(x-0.8, y, z, x1+1.8, y1+0.8, z1+0.8));
+ List list2 = world.getNonSpectatingEntities(ItemFrameEntity.class, new Box(x, y, z-0.8, x1+0.8, y1+0.8, z1+1.8));
+ List list3 = world.getNonSpectatingEntities(ItemFrameEntity.class, new Box(x, y-0.8, z, x1+0.8, y1+1.8, z1+0.8));
+ List list = new ArrayList<>();
+ Stream.of(list1, list2, list3).forEach(list::addAll);
+ for(ItemFrameEntity itemFrame : list){
+ ItemStack item = itemFrame.getHeldItemStack();
+ if(item != null && !item.isEmpty()){
+ itemStack = item;
+ break;
+ }
+ }
+ return itemStack;
+ }
}
diff --git a/src/main/java/com/kqp/inventorytabs/tabs/tab/InventoryTab.java b/src/main/java/com/kqp/inventorytabs/tabs/tab/InventoryTab.java
new file mode 100644
index 0000000..3d7bb6a
--- /dev/null
+++ b/src/main/java/com/kqp/inventorytabs/tabs/tab/InventoryTab.java
@@ -0,0 +1,43 @@
+package com.kqp.inventorytabs.tabs.tab;
+
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.network.ClientPlayerEntity;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.text.LiteralText;
+import net.minecraft.text.Text;
+import net.minecraft.world.World;
+
+public class InventoryTab extends Tab {
+ public final Item itemId;
+ public InventoryTab(Item itemId) {
+ super(new ItemStack(itemId));
+ this.itemId = itemId;
+ }
+
+ @Override
+ public void open() {
+ System.out.println("TESTING: Opening inventory tab");
+ ClientPlayerEntity player = MinecraftClient.getInstance().player;
+ World world = MinecraftClient.getInstance().world;
+ System.out.println("Player: "+player);
+ System.out.println("World: "+world);
+ System.out.println("Item: "+itemId);
+ System.out.println("ItemStack: "+new ItemStack(itemId));
+ System.out.println("Active hand: "+player.getActiveHand());
+ Item item = new ItemStack(itemId).getItem();
+ item.use(world, player, player.getActiveHand());
+ //itemId.use(world, player, player.getActiveHand());
+ }
+
+ @Override
+ public boolean shouldBeRemoved() {
+ ClientPlayerEntity player = MinecraftClient.getInstance().player;
+ return (player == null || !player.inventory.contains(new ItemStack(itemId)));
+ }
+
+ @Override
+ public Text getHoverText() {
+ return new LiteralText(itemId.getName().getString());
+ }
+}
diff --git a/src/main/java/com/kqp/inventorytabs/tabs/tab/ShulkerBoxTab.java b/src/main/java/com/kqp/inventorytabs/tabs/tab/ShulkerBoxTab.java
index f83ae28..39be5c0 100644
--- a/src/main/java/com/kqp/inventorytabs/tabs/tab/ShulkerBoxTab.java
+++ b/src/main/java/com/kqp/inventorytabs/tabs/tab/ShulkerBoxTab.java
@@ -1,15 +1,14 @@
package com.kqp.inventorytabs.tabs.tab;
+import com.kqp.inventorytabs.util.ShulkerBoxBlockInvoker;
+
import net.minecraft.block.BlockState;
-import net.minecraft.block.ShulkerBoxBlock;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.ShulkerBoxBlockEntity;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
-import net.minecraft.entity.mob.ShulkerLidCollisions;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
-import net.minecraft.util.math.Direction;
/**
* Tab for shulker boxes.
@@ -27,14 +26,9 @@ public boolean shouldBeRemoved() {
if (blockEntity instanceof ShulkerBoxBlockEntity) {
BlockState blockState = player.world.getBlockState(blockPos);
- Direction direction = blockState.get(ShulkerBoxBlock.FACING);
-
- if (((ShulkerBoxBlockEntity) blockEntity)
- .getAnimationStage() == ShulkerBoxBlockEntity.AnimationStage.CLOSED) {
- if (!player.world.isSpaceEmpty(ShulkerLidCollisions.getLidCollisionBox(blockPos, direction))) {
- return true;
- }
- }
+
+ return !ShulkerBoxBlockInvoker.invokeCanOpen(blockState, player.world, blockPos,
+ (ShulkerBoxBlockEntity) blockEntity);
}
return super.shouldBeRemoved();
diff --git a/src/main/java/com/kqp/inventorytabs/tabs/tab/SimpleBlockTab.java b/src/main/java/com/kqp/inventorytabs/tabs/tab/SimpleBlockTab.java
index 008ddb9..4e0434c 100644
--- a/src/main/java/com/kqp/inventorytabs/tabs/tab/SimpleBlockTab.java
+++ b/src/main/java/com/kqp/inventorytabs/tabs/tab/SimpleBlockTab.java
@@ -9,7 +9,7 @@
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
-import net.minecraft.command.argument.EntityAnchorArgumentType;
+import net.minecraft.command.argument.EntityAnchorArgumentType.EntityAnchor;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.text.Text;
@@ -44,13 +44,13 @@ public void open() {
if (InventoryTabs.getConfig().doSightChecksFlag) {
hitResult = BlockUtil.getLineOfSight(blockPos, client.player, 5D);
} else {
- hitResult = new BlockHitResult(client.player.getPos(), Direction.EAST, blockPos, false);
+ hitResult = new BlockHitResult(Vec3d.ofCenter(blockPos), Direction.EAST, blockPos, false);
}
if (hitResult != null) {
if (InventoryTabs.getConfig().rotatePlayer) {
- MinecraftClient.getInstance().player.lookAt(EntityAnchorArgumentType.EntityAnchor.EYES,
- getBlockVec3d());
+ MinecraftClient.getInstance().player.lookAt(EntityAnchor.EYES,
+ Vec3d.ofCenter(blockPos));
}
MinecraftClient.getInstance().interactionManager.interactBlock(client.player, client.player.clientWorld,
@@ -69,13 +69,15 @@ public boolean shouldBeRemoved() {
if (InventoryTabs.getConfig().doSightChecksFlag) {
if (BlockUtil.getLineOfSight(blockPos, player, 5D) == null) {
return true;
+ } else {
+ return !BlockUtil.inRange(blockPos, player, 5D);
}
}
-
Vec3d playerHead = player.getPos().add(0D, player.getEyeHeight(player.getPose()), 0D);
- return getBlockVec3d().subtract(playerHead).lengthSquared() > BlockTabProvider.SEARCH_DISTANCE
+ return Vec3d.ofCenter(blockPos).subtract(playerHead).lengthSquared() > BlockTabProvider.SEARCH_DISTANCE
* BlockTabProvider.SEARCH_DISTANCE;
+
}
@Override
@@ -96,10 +98,6 @@ public Text getHoverText() {
return new TranslatableText(world.getBlockState(blockPos).getBlock().getTranslationKey());
}
- private Vec3d getBlockVec3d() {
- return new Vec3d(blockPos.getX() + 0.5D, blockPos.getY() + 0.5D, blockPos.getZ() + 0.5D);
- }
-
@Override
public boolean equals(Object o) {
if (this == o) {
diff --git a/src/main/java/com/kqp/inventorytabs/tabs/tab/SimpleEntityTab.java b/src/main/java/com/kqp/inventorytabs/tabs/tab/SimpleEntityTab.java
new file mode 100644
index 0000000..2ab0f52
--- /dev/null
+++ b/src/main/java/com/kqp/inventorytabs/tabs/tab/SimpleEntityTab.java
@@ -0,0 +1,92 @@
+package com.kqp.inventorytabs.tabs.tab;
+
+import com.kqp.inventorytabs.mixin.accessor.ScreenAccessor;
+import com.kqp.inventorytabs.tabs.render.TabRenderInfo;
+import com.kqp.inventorytabs.util.EntityUtil;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.font.TextRenderer;
+import net.minecraft.client.gui.screen.ingame.HandledScreen;
+import net.minecraft.client.network.ClientPlayerEntity;
+import net.minecraft.client.render.item.ItemRenderer;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityType;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.SpawnEggItem;
+import net.minecraft.text.Text;
+import net.minecraft.util.Hand;
+import net.minecraft.util.Identifier;
+import net.minecraft.util.math.Vec3d;
+import net.minecraft.util.registry.Registry;
+import java.util.Objects;
+
+public class SimpleEntityTab extends Tab {
+ public final Vec3d entityPos;
+ public final Identifier entityId;
+ public final Entity entity;
+
+ public SimpleEntityTab(Entity entity) {
+ super(new ItemStack(Registry.ITEM.get(new Identifier("minecraft", "barrier"))));
+ this.entity = entity;
+ this.entityPos = entity.getPos();
+ this.entityId = EntityType.getId(entity.getType());
+ }
+
+ @Override
+ public void open() {
+ ClientPlayerEntity player = MinecraftClient.getInstance().player;
+ if(player != null) {
+ Hand hand = player.getActiveHand();
+ if(hand == null){
+ hand = Hand.MAIN_HAND;
+ }
+ MinecraftClient.getInstance().interactionManager.interactEntity(player, entity, hand);
+ }
+ }
+
+ @Override
+ public boolean shouldBeRemoved() {
+ if (entity.removed) {
+ return true;
+ }
+ return entityPos.distanceTo(MinecraftClient.getInstance().player.getPos()) > 5;
+ }
+
+ @Override
+ public Text getHoverText() {
+ return entity.getName();
+ }
+
+ @Override
+ public void renderTabIcon(MatrixStack matrices, TabRenderInfo tabRenderInfo, HandledScreen> currentScreen) {
+ ItemStack itemStack = getItemStack();
+ ItemRenderer itemRenderer = ((ScreenAccessor) currentScreen).getItemRenderer();
+ TextRenderer textRenderer = ((ScreenAccessor) currentScreen).getTextRenderer();
+ itemRenderer.zOffset = 100.0F;
+ itemRenderer.renderInGuiWithOverrides(itemStack, tabRenderInfo.itemX, tabRenderInfo.itemY);
+ itemRenderer.renderGuiItemOverlay(textRenderer, itemStack, tabRenderInfo.itemX, tabRenderInfo.itemY);
+ itemRenderer.zOffset = 0.0F;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ SimpleEntityTab tab = (SimpleEntityTab) o;
+ return Objects.equals(entityId, tab.entityId);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(entityId);
+ }
+
+ public ItemStack getItemStack() {
+ ItemStack pickBlockResult = EntityUtil.getEntityPickResult(entity);
+ return pickBlockResult != null && !pickBlockResult.isEmpty() ? pickBlockResult : new ItemStack(Registry.ITEM.get(new Identifier("minecraft", "barrier")));
+ }
+}
diff --git a/src/main/java/com/kqp/inventorytabs/tabs/tab/Tab.java b/src/main/java/com/kqp/inventorytabs/tabs/tab/Tab.java
index 2aa73a9..c7f6079 100644
--- a/src/main/java/com/kqp/inventorytabs/tabs/tab/Tab.java
+++ b/src/main/java/com/kqp/inventorytabs/tabs/tab/Tab.java
@@ -2,7 +2,6 @@
import com.kqp.inventorytabs.mixin.accessor.ScreenAccessor;
import com.kqp.inventorytabs.tabs.render.TabRenderInfo;
-import com.mojang.blaze3d.systems.RenderSystem;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@@ -72,7 +71,7 @@ public void renderTabIcon(MatrixStack matrices, TabRenderInfo tabRenderInfo, Han
ItemRenderer itemRenderer = ((ScreenAccessor) currentScreen).getItemRenderer();
TextRenderer textRenderer = ((ScreenAccessor) currentScreen).getTextRenderer();
itemRenderer.zOffset = 100.0F;
- RenderSystem.enableRescaleNormal();
+ // RenderSystem.enableRescaleNormal();
itemRenderer.renderInGuiWithOverrides(renderItemStack, tabRenderInfo.itemX, tabRenderInfo.itemY);
itemRenderer.renderGuiItemOverlay(textRenderer, renderItemStack, tabRenderInfo.itemX, tabRenderInfo.itemY);
itemRenderer.zOffset = 0.0F;
diff --git a/src/main/java/com/kqp/inventorytabs/util/BlockUtil.java b/src/main/java/com/kqp/inventorytabs/util/BlockUtil.java
index 85bb1e2..01ef340 100644
--- a/src/main/java/com/kqp/inventorytabs/util/BlockUtil.java
+++ b/src/main/java/com/kqp/inventorytabs/util/BlockUtil.java
@@ -11,6 +11,20 @@
import net.minecraft.world.World;
public class BlockUtil {
+ public static boolean inRange(BlockPos pos, PlayerEntity player, double distance) {
+ double distanceSquared = distance * distance;
+
+ Vec3d playerHead = player.getPos().add(0D, player.getEyeHeight(player.getPose()), 0D);
+ Vec3d blockVec = new Vec3d(pos.getX(), pos.getY(), pos.getZ());
+
+ for (Vec3d sightOffset : SIGHT_OFFSETS) {
+ if (blockVec.add(sightOffset).squaredDistanceTo(playerHead) <= distanceSquared) {
+ return true;
+ }
+ }
+
+ return false;
+ }
public static BlockHitResult getLineOfSight(BlockPos pos, PlayerEntity player, double distance) {
World world = player.world;
BlockState blockState = world.getBlockState(pos);
@@ -19,8 +33,8 @@ public static BlockHitResult getLineOfSight(BlockPos pos, PlayerEntity player, d
Vec3d playerHead = player.getPos().add(0D, player.getEyeHeight(player.getPose()), 0D);
Vec3d blockVec = new Vec3d(pos.getX(), pos.getY(), pos.getZ());
- for (int i = 0; i < SIGHT_OFFSETS.length; i++) {
- Vec3d blockPosCheck = blockVec.add(SIGHT_OFFSETS[i]);
+ for (Vec3d sightOffset : SIGHT_OFFSETS) {
+ Vec3d blockPosCheck = blockVec.add(sightOffset);
BlockHitResult result = getBlockHitResult(playerHead, blockPosCheck, distanceSquared, world, pos,
blockState);
diff --git a/src/main/java/com/kqp/inventorytabs/util/ChestUtil.java b/src/main/java/com/kqp/inventorytabs/util/ChestUtil.java
index 5197d01..9b3796a 100644
--- a/src/main/java/com/kqp/inventorytabs/util/ChestUtil.java
+++ b/src/main/java/com/kqp/inventorytabs/util/ChestUtil.java
@@ -3,6 +3,7 @@
import net.minecraft.block.BlockState;
import net.minecraft.block.ChestBlock;
import net.minecraft.block.enums.ChestType;
+import net.minecraft.state.property.Properties;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
@@ -10,9 +11,11 @@
public class ChestUtil {
public static boolean isDouble(World world, BlockPos blockPos) {
BlockState blockState = world.getBlockState(blockPos);
- ChestType type = blockState.get(ChestBlock.CHEST_TYPE);
-
- return type == ChestType.LEFT || type == ChestType.RIGHT;
+ if (blockState.contains(Properties.CHEST_TYPE)) {
+ ChestType type = blockState.get(ChestBlock.CHEST_TYPE);
+ return type == ChestType.LEFT || type == ChestType.RIGHT;
+ }
+ return false;
}
public static BlockPos getOtherChestBlockPos(World world, BlockPos blockPos) {
diff --git a/src/main/java/com/kqp/inventorytabs/util/EntityUtil.java b/src/main/java/com/kqp/inventorytabs/util/EntityUtil.java
new file mode 100644
index 0000000..fb4bbb9
--- /dev/null
+++ b/src/main/java/com/kqp/inventorytabs/util/EntityUtil.java
@@ -0,0 +1,70 @@
+package com.kqp.inventorytabs.util;
+
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.decoration.ArmorStandEntity;
+import net.minecraft.entity.decoration.EndCrystalEntity;
+import net.minecraft.entity.decoration.ItemFrameEntity;
+import net.minecraft.entity.decoration.LeashKnotEntity;
+import net.minecraft.entity.decoration.painting.PaintingEntity;
+import net.minecraft.entity.vehicle.AbstractMinecartEntity;
+import net.minecraft.entity.vehicle.BoatEntity;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.Items;
+import net.minecraft.item.SpawnEggItem;
+
+public class EntityUtil {
+ /** Currently hard-coded, see {@link net.minecraft.client.MinecraftClient} */
+ public static ItemStack getEntityPickResult(Entity entity){
+ if (entity instanceof PaintingEntity) {
+ return new ItemStack(Items.PAINTING);
+ } else if (entity instanceof LeashKnotEntity) {
+ return new ItemStack(Items.LEAD);
+ } else if (entity instanceof ItemFrameEntity) {
+ ItemFrameEntity itemFrameEntity = (ItemFrameEntity)entity;
+ ItemStack itemStack2 = itemFrameEntity.getHeldItemStack();
+ return itemStack2.isEmpty() ? new ItemStack(Items.ITEM_FRAME) : itemStack2.copy();
+ } else if (entity instanceof AbstractMinecartEntity) {
+ Item item;
+ AbstractMinecartEntity abstractMinecartEntity = (AbstractMinecartEntity)entity;
+ switch (abstractMinecartEntity.getMinecartType()) {
+ case FURNACE: {
+ item = Items.FURNACE_MINECART;
+ break;
+ }
+ case CHEST: {
+ item = Items.CHEST_MINECART;
+ break;
+ }
+ case TNT: {
+ item = Items.TNT_MINECART;
+ break;
+ }
+ case HOPPER: {
+ item = Items.HOPPER_MINECART;
+ break;
+ }
+ case COMMAND_BLOCK: {
+ item = Items.COMMAND_BLOCK_MINECART;
+ break;
+ }
+ default: {
+ item = Items.MINECART;
+ }
+ }
+ return new ItemStack(item);
+ } else if (entity instanceof BoatEntity) {
+ return new ItemStack(((BoatEntity)entity).asItem());
+ } else if (entity instanceof ArmorStandEntity) {
+ return new ItemStack(Items.ARMOR_STAND);
+ } else if (entity instanceof EndCrystalEntity) {
+ return new ItemStack(Items.END_CRYSTAL);
+ } else {
+ SpawnEggItem spawnEggItem = SpawnEggItem.forEntity(entity.getType());
+ if (spawnEggItem == null) {
+ return ItemStack.EMPTY;
+ }
+ return new ItemStack(spawnEggItem);
+ }
+ }
+}
diff --git a/src/main/java/com/kqp/inventorytabs/util/ShulkerBoxBlockInvoker.java b/src/main/java/com/kqp/inventorytabs/util/ShulkerBoxBlockInvoker.java
new file mode 100644
index 0000000..9a0bcad
--- /dev/null
+++ b/src/main/java/com/kqp/inventorytabs/util/ShulkerBoxBlockInvoker.java
@@ -0,0 +1,26 @@
+package com.kqp.inventorytabs.util;
+
+import net.minecraft.entity.mob.ShulkerLidCollisions;
+import net.minecraft.util.math.Direction;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Invoker;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.block.ShulkerBoxBlock;
+import net.minecraft.block.entity.ShulkerBoxBlockEntity;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.World;
+
+import static net.minecraft.block.ShulkerBoxBlock.FACING;
+
+//@Mixin(ShulkerBoxBlock.class)
+public interface ShulkerBoxBlockInvoker {
+ public static boolean invokeCanOpen(BlockState state, World world, BlockPos pos, ShulkerBoxBlockEntity entity) {
+ if (entity.getAnimationStage() == ShulkerBoxBlockEntity.AnimationStage.CLOSED) {
+ Direction direction = state.get(FACING);
+ return world.isSpaceEmpty(ShulkerLidCollisions.getLidCollisionBox(pos, direction));
+ } else {
+ return true;
+ }
+ };
+}
diff --git a/src/main/resources/assets/inventorytabs/icon.png b/src/main/resources/assets/inventorytabs/icon.png
index 7a7704f..1e9bc6e 100644
Binary files a/src/main/resources/assets/inventorytabs/icon.png and b/src/main/resources/assets/inventorytabs/icon.png differ
diff --git a/src/main/resources/assets/inventorytabs/lang/en_us.json b/src/main/resources/assets/inventorytabs/lang/en_us.json
new file mode 100644
index 0000000..e121d86
--- /dev/null
+++ b/src/main/resources/assets/inventorytabs/lang/en_us.json
@@ -0,0 +1,13 @@
+{
+ "text.autoconfig.inventory_tabs.title": "Inventory Tabs Config",
+ "text.autoconfig.inventory_tabs.option.doSightChecksFlag": "Check if block is in line of sight",
+ "text.autoconfig.inventory_tabs.option.doSightChecksFlag.@Tooltip": "If §cNo§r, you are able to click on inventories through walls",
+ "text.autoconfig.inventory_tabs.option.rotatePlayer": "Rotate the player to face the tab's block",
+ "text.autoconfig.inventory_tabs.option.rotatePlayer.@Tooltip": "If §aYes§r, the player will snap to position",
+ "text.autoconfig.inventory_tabs.option.excludeTab": "§nDo not show§r tabs for these blocks:",
+ "text.autoconfig.inventory_tabs.option.excludeTab.@Tooltip": "Format: §emod_name:block_id§r, or §emod_name:tag_id§r",
+ "text.autoconfig.inventory_tabs.option.includeTab": "§nForce show§r tabs for these blocks:",
+ "text.autoconfig.inventory_tabs.option.includeTab.@Tooltip": "Format: §emod_name:block_id§r",
+ "text.autoconfig.inventory_tabs.option.debugEnabled": "Print debugging information (tab IDs added/removed) in the log",
+ "inventorytabs.key.next_tab": "Cycle Inventory Tab"
+}
\ No newline at end of file
diff --git a/src/main/resources/data/inventorytabs/tags/blocks/mod_compat_blacklist.json b/src/main/resources/data/inventorytabs/tags/blocks/mod_compat_blacklist.json
new file mode 100644
index 0000000..0cb96e3
--- /dev/null
+++ b/src/main/resources/data/inventorytabs/tags/blocks/mod_compat_blacklist.json
@@ -0,0 +1,6 @@
+{
+ "replace": false,
+ "values": [
+ {"id": "autopath:path", "required": false}
+ ]
+}
\ No newline at end of file
diff --git a/src/main/resources/data/techreborn/tags/blocks/block_entities_without_inventories.json b/src/main/resources/data/techreborn/tags/blocks/block_entities_without_inventories.json
new file mode 100644
index 0000000..e4cfd2c
--- /dev/null
+++ b/src/main/resources/data/techreborn/tags/blocks/block_entities_without_inventories.json
@@ -0,0 +1,33 @@
+{
+ "replace": false,
+ "values": [
+ {"id": "techreborn:basic_machine_casing", "required": false},
+ {"id": "techreborn:advanced_machine_casing", "required": false},
+ {"id": "techreborn:industrial_machine_casing", "required": false},
+ {"id": "techreborn:creative_solar_panel", "required": false},
+ {"id": "techreborn:copper_cable", "required": false},
+ {"id": "techreborn:tin_cable", "required": false},
+ {"id": "techreborn:gold_cable", "required": false},
+ {"id": "techreborn:hv_cable", "required": false},
+ {"id": "techreborn:glassfiber_cable", "required": false},
+ {"id": "techreborn:insulated_copper_cable", "required": false},
+ {"id": "techreborn:insulated_gold_cable", "required": false},
+ {"id": "techreborn:insulated_hv_cable", "required": false},
+ {"id": "techreborn:superconductor_cable", "required": false},
+ {"id": "techreborn:resin_basin", "required": false},
+ {"id": "techreborn:dragon_egg_syphon", "required": false},
+ {"id": "techreborn:lightning_rod", "required": false},
+ {"id": "techreborn:water_mill", "required": false},
+ {"id": "techreborn:wind_mill", "required": false},
+ {"id": "techreborn:drain", "required": false},
+ {"id": "techreborn:lsu_storage", "required": false},
+ {"id": "techreborn:lv_transformer", "required": false},
+ {"id": "techreborn:mv_transformer", "required": false},
+ {"id": "techreborn:hv_transformer", "required": false},
+ {"id": "techreborn:ev_transformer", "required": false},
+ {"id": "techreborn:alarm", "required": false},
+ {"id": "techreborn:lamp_incandescent", "required": false},
+ {"id": "techreborn:lamp_led", "required": false},
+ {"id": "techreborn:computer_cube", "required": false}
+ ]
+}
\ No newline at end of file
diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json
index ed148d5..da8880c 100644
--- a/src/main/resources/fabric.mod.json
+++ b/src/main/resources/fabric.mod.json
@@ -5,12 +5,15 @@
"name": "Inventory Tabs",
"description": "Adds tabs to your inventory that lead to nearby blocks.",
"authors": [
- "KQP"
+ "KQP",
+ "LiamMCW",
+ "Andrew6rant (Andrew Grant)",
+ "WNTIV> (1.16.5 backport)"
],
"contact": {
- "homepage": "https://github.com/LiamMCW/inventorytabs",
- "sources": "https://github.com/LiamMCW/inventorytabs",
- "issues": "https://github.com/LiamMCW/inventorytabs/issues"
+ "homepage": "https://github.com/Andrew6rant/inventorytabs",
+ "sources": "https://github.com/Andrew6rant/inventorytabs",
+ "issues": "https://github.com/Andrew6rant/inventorytabs/issues"
},
"license": "MIT",
"icon": "assets/inventorytabs/icon.png",
@@ -21,14 +24,28 @@
],
"client": [
"com.kqp.inventorytabs.init.InventoryTabsClient"
+ ],
+ "modmenu": [
+ "com.kqp.inventorytabs.init.InventoryTabsModMenu"
]
},
"mixins": [
"inventorytabs.mixins.json"
],
"depends": {
- "fabricloader": ">=0.11.6",
- "fabric": ">=0.36.0",
- "minecraft": "1.16.5"
+ "fabricloader": ">=0.14.9",
+ "fabric": ">=0.42.0",
+ "minecraft": "1.16.5",
+ "cloth-config2": "*"
+ },
+ "custom": {
+ "modmenu": [
+ "com.kqp.inventorytabs.init.InventoryTabsConfig"
+ ]
+ },
+ "suggests": {
+ "biginv": "*",
+ "playerex": "*",
+ "modmenu": "*"
}
-}
+}
\ No newline at end of file
diff --git a/src/main/resources/inventorytabs.mixins.json b/src/main/resources/inventorytabs.mixins.json
index 03abdb4..f9820d6 100644
--- a/src/main/resources/inventorytabs.mixins.json
+++ b/src/main/resources/inventorytabs.mixins.json
@@ -2,17 +2,21 @@
"required": true,
"minVersion": "0.8",
"package": "com.kqp.inventorytabs.mixin",
- "compatibilityLevel": "JAVA_16",
+ "compatibilityLevel": "JAVA_8",
"mixins": [
- "accessor.HandledScreenAccessor",
- "accessor.ScreenAccessor",
"CartographyTableScreenTabAdder",
"LoomScreenTabAdder",
"StonecutterScreenTabAdder",
"TabManagerContainerImplementer",
- "VanillaScreenTabAdder"
+ "VanillaScreenTabAdder",
+ "accessor.HandledScreenAccessor",
+ "accessor.ScreenAccessor"
],
"injectors": {
"defaultRequire": 1
- }
+ },
+ "client": [
+ "ControlsListWidget$KeyBindingEntryMixin_SoftConflict",
+ "KeyBindingMixin_SoftConflict"
+ ]
}