package at.hannibal2.skyhanni.utils import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.ItemUtils.getInternalNameOrNull import io.github.moulberry.notenoughupdates.NotEnoughUpdates import net.minecraft.client.Minecraft import net.minecraft.client.gui.inventory.GuiChest import net.minecraft.client.gui.inventory.GuiContainer import net.minecraft.entity.player.InventoryPlayer import net.minecraft.inventory.ContainerChest import net.minecraft.inventory.Slot import net.minecraft.item.ItemStack import kotlin.time.Duration.Companion.seconds object InventoryUtils { var itemInHandId = NEUInternalName.NONE var recentItemsInHand = mutableMapOf() var latestItemInHand: ItemStack? = null fun getItemsInOpenChest() = buildList { val guiChest = Minecraft.getMinecraft().currentScreen as? GuiChest ?: return emptyList() for (slot in guiChest.inventorySlots.inventorySlots) { if (slot.inventory is InventoryPlayer) break if (slot.stack != null) add(slot) } } // TODO add cache that persists until the next gui/window open/close packet is sent/received fun openInventoryName() = Minecraft.getMinecraft().currentScreen.let { if (it is GuiChest) { val chest = it.inventorySlots as ContainerChest chest.getInventoryName() } else "" } fun ContainerChest.getInventoryName() = this.lowerChestInventory.displayName.unformattedText.trim() fun getItemsInOwnInventory() = Minecraft.getMinecraft().thePlayer.inventory.mainInventory.filterNotNull() fun getItemsInOwnInventoryWithNull() = Minecraft.getMinecraft().thePlayer.inventory.mainInventory fun countItemsInLowerInventory(predicate: (ItemStack) -> Boolean) = getItemsInOwnInventory().filter { predicate(it) }.sumOf { it.stackSize } fun inStorage() = openInventoryName().let { (it.contains("Storage") && !it.contains("Rift Storage")) || it.contains("Ender Chest") || it.contains("Backpack") } fun getItemInHand(): ItemStack? = Minecraft.getMinecraft().thePlayer.heldItem fun getArmor(): Array = Minecraft.getMinecraft().thePlayer.inventory.armorInventory fun getHelmet(): ItemStack? = getArmor()[3] fun getChestplate(): ItemStack? = getArmor()[2] fun getLeggings(): ItemStack? = getArmor()[1] fun getBoots(): ItemStack? = getArmor()[0] val isNeuStorageEnabled = RecalculatingValue(10.seconds) { try { val config = NotEnoughUpdates.INSTANCE.config val storageField = config.javaClass.getDeclaredField("storageGUI") val storage = storageField.get(config) val booleanField = storage.javaClass.getDeclaredField("enableStorageGUI3") booleanField.get(storage) as Boolean } catch (e: Throwable) { ErrorManager.logErrorWithData(e, "Could not read NEU config to determine if the neu storage is emabled.") false } } fun isSlotInPlayerInventory(itemStack: ItemStack): Boolean { val screen = Minecraft.getMinecraft().currentScreen as? GuiContainer ?: return false return screen.slotUnderMouse.inventory is InventoryPlayer && screen.slotUnderMouse.stack == itemStack } fun isItemInInventory(name: NEUInternalName) = name.getAmountInInventory() > 0 fun ContainerChest.getUpperItems(): Map = buildMap { for ((slot, stack) in getAllItems()) { if (slot.slotNumber != slot.slotIndex) continue this[slot] = stack } } fun ContainerChest.getLowerItems(): Map = buildMap { for ((slot, stack) in getAllItems()) { if (slot.slotNumber == slot.slotIndex) continue this[slot] = stack } } fun ContainerChest.getAllItems(): Map = buildMap { for (slot in inventorySlots) { if (slot == null) continue val stack = slot.stack ?: continue this[slot] = stack } } fun getItemAtSlotIndex(slotIndex: Int): ItemStack? { return getItemsInOpenChest().find { it.slotIndex == slotIndex }?.stack } fun NEUInternalName.getAmountInInventory(): Int = countItemsInLowerInventory { it.getInternalNameOrNull() == this } }