Skip to content

Commit

Permalink
feat: add support for Forestry backpacks (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
mainrs authored Sep 25, 2024
1 parent d9c5b0e commit 9a54f7c
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 22 deletions.
1 change: 1 addition & 0 deletions dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ dependencies {
compileOnly('com.github.GTNewHorizons:GT5-Unofficial:5.09.49.05:dev')
compileOnly('com.github.GTNewHorizons:EnderIO:2.8.17:dev')
compileOnly('com.github.GTNewHorizons:Draconic-Evolution:1.3.6-GTNH:dev')
api('com.github.GTNewHorizons:ForestryMC:4.9.16:dev')
}
31 changes: 18 additions & 13 deletions src/main/java/com/gtnh/findit/FindIt.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,23 @@ public class FindIt {
@Mod.Instance(MOD_ID)
public static FindIt INSTANCE;

private boolean extraUtilitiesLoaded;
private boolean gregTechloaded;
private boolean enderIOloaded;

private boolean draconicEvolutionLoaded;
private boolean isDraconicEvolutionLoaded;
private boolean isEnderIOLoaded;
private boolean isExtraUtilitiesLoaded;
private boolean isForestryLoaded;
private boolean isGregTechLoaded;

private SearchCooldownService cooldownService;
private BlockFindService blockFindService;
private ItemFindService itemFindService;

@Mod.EventHandler
public void preInit(FMLPreInitializationEvent event) {
this.extraUtilitiesLoaded = Loader.isModLoaded("ExtraUtilities");
this.gregTechloaded = Loader.isModLoaded("gregtech");
this.enderIOloaded = Loader.isModLoaded("EnderIO");
this.draconicEvolutionLoaded = Loader.isModLoaded("DraconicEvolution");
this.isExtraUtilitiesLoaded = Loader.isModLoaded("ExtraUtilities");
this.isGregTechLoaded = Loader.isModLoaded("gregtech");
this.isEnderIOLoaded = Loader.isModLoaded("EnderIO");
this.isDraconicEvolutionLoaded = Loader.isModLoaded("DraconicEvolution");
this.isForestryLoaded = Loader.isModLoaded("Forestry");

FindItConfig.setup(event.getSuggestedConfigurationFile());
boolean isClient = event.getSide() == Side.CLIENT;
Expand All @@ -66,18 +67,22 @@ public static ItemFindService getItemFindService() {
}

public static boolean isExtraUtilitiesLoaded() {
return INSTANCE.extraUtilitiesLoaded;
return INSTANCE.isExtraUtilitiesLoaded;
}

public static boolean isGregTechLoaded() {
return INSTANCE.gregTechloaded;
return INSTANCE.isGregTechLoaded;
}

public static boolean isEnderIOLoaded() {
return INSTANCE.enderIOloaded;
return INSTANCE.isEnderIOLoaded;
}

public static boolean isDraconicEvolutionLoaded() {
return INSTANCE.draconicEvolutionLoaded;
return INSTANCE.isDraconicEvolutionLoaded;
}

public static boolean isForestryLoaded() {
return INSTANCE.isForestryLoaded;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,14 @@ public void onClientPostTick(TickEvent.ClientTickEvent event) {
return;
}

// `WorldClient` is only available on the client-side, thus effectively checking if the game is running on
// the client. We are only interested in highlighting slots when the player is in a GUI; the operation is
// bound client-side.
if (Minecraft.getMinecraft().theWorld == null) {
return;
}

// We are only interested in GUIs that contain some kind of inventory.
final GuiScreen screen = Minecraft.getMinecraft().currentScreen;
if (!(screen instanceof GuiContainer)) {
return;
Expand All @@ -107,21 +111,26 @@ public void onClientPostTick(TickEvent.ClientTickEvent event) {
final GuiContainer gui = (GuiContainer) screen;
final HashSet<Slot> highlightedSlots = new HashSet<>();

// If the expiration time has passed, we reset the found item. This is done to prevent the item from being
// highlighted indefinitely.
if (System.currentTimeMillis() > expirationTime) {
foundItem = null;
}
if (foundItem == null) {
return;
}

if (foundItem != null) {
@SuppressWarnings("unchecked")
List<Slot> slots = gui.inventorySlots.inventorySlots;
// We continue to iterate over each slot of the given GUI's inventory and checking if the slot contains the
// item that we are looking for.
@SuppressWarnings("unchecked")
List<Slot> slots = gui.inventorySlots.inventorySlots;

for (Slot slot : slots) {
if (!(slot.inventory instanceof InventoryPlayer) && foundItem.isStackSatisfies(slot.getStack())) {
highlightedSlots.add(slot);
for (Slot slot : slots) {
if (!(slot.inventory instanceof InventoryPlayer) && foundItem.isStackSatisfies(slot.getStack())) {
highlightedSlots.add(slot);

if (highlightedSlots.size() > 256) {
break;
}
if (highlightedSlots.size() > 256) {
break;
}
}
}
Expand Down Expand Up @@ -152,6 +161,10 @@ protected boolean findStack(ItemStack stack) {
}
}

/**
* This class is responsible for removing the NEI ping handler from the list of input handlers. This is done to
* prevent the NEI ping handler from interfering with the FindIt keybind.
*/
public static class NEIEventListener {

@SubscribeEvent
Expand All @@ -164,6 +177,9 @@ public void onNEIConfigsLoaded(NEIConfigsLoadedEvent event) {
}
}

/**
* Returns the instance of the client item find service.
*/
public static ClientItemFindService getInstance() {
return (ClientItemFindService) FindIt.getItemFindService();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.gtnh.findit.service.itemfinder;

import java.util.Optional;

import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;

import com.gtnh.findit.FindIt;
import com.gtnh.findit.service.blockfinder.BlockFoundResponse;
import com.gtnh.findit.util.ProtoUtils;
import com.gtnh.findit.util.mods.ForestryUtils;

import codechicken.nei.recipe.StackInfo;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
Expand Down Expand Up @@ -60,6 +63,25 @@ public boolean isStackSatisfies(ItemStack stack) {
return targetFluidStack.isFluidEqual(StackInfo.getFluid(stack));
}

// Additionally check for backpacks that might contain the item itself.
if (FindIt.isForestryLoaded()) {
Optional<Boolean> result = ForestryUtils.getInventoryOfPotentialStorageItem(stack).map(inventory -> {
for (int i = 0; i < inventory.getSizeInventory(); i++) {
// This does a recursive call, but backpacks cannot store other backpacks, so we won't run into
// StackOverflowExceptions.
if (inventory.getStackInSlot(i) != null && isStackSatisfies(inventory.getStackInSlot(i))) {
return true;
}
}

// None of the inventory slots contained the item we were looking for.
return false;
});
if (result.isPresent()) {
return result.get();
}
}

return StackInfo.equalItemAndNBT(targetStack, stack, true);
}

Expand Down
37 changes: 37 additions & 0 deletions src/main/java/com/gtnh/findit/util/mods/ForestryUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.gtnh.findit.util.mods;

import java.util.Optional;

import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;

import forestry.storage.inventory.ItemInventoryBackpack;
import forestry.storage.items.ItemBackpack;

public class ForestryUtils {

private ForestryUtils() {}

public static Optional<IInventory> getInventoryOfPotentialStorageItem(ItemStack potentialBackpackItemStack) {
// Checks for Forestry backpacks.
Item item = potentialBackpackItemStack.getItem();
if (item instanceof ItemBackpack) {
ItemBackpack backpack = (ItemBackpack) item;

// We're running the GUI code client-side only, thus the only player interacting with the GUI is the
// player that the backpack's inventory is checked against.
EntityPlayer player = Minecraft.getMinecraft().thePlayer;

ItemInventoryBackpack inventory = new ItemInventoryBackpack(
player,
backpack.getBackpackSize(),
potentialBackpackItemStack);
return Optional.of(inventory);
}

return Optional.empty();
}
}

0 comments on commit 9a54f7c

Please sign in to comment.