diff options
author | Thunderblade73 <85900443+Thunderblade73@users.noreply.github.com> | 2024-03-09 21:46:04 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-09 21:46:04 +0100 |
commit | ea8d09297d037807f00b62778f99901060f4e375 (patch) | |
tree | cbae93e981dcc5da3f00e3e8760b32fe00cdc044 /src/main/java/at | |
parent | abedb7ead429d461ee2bab4d1e7977ba1e42b7de (diff) | |
download | skyhanni-ea8d09297d037807f00b62778f99901060f4e375.tar.gz skyhanni-ea8d09297d037807f00b62778f99901060f4e375.tar.bz2 skyhanni-ea8d09297d037807f00b62778f99901060f4e375.zip |
Feature: Kismet Feather Tracker (#1011)
Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com>
Diffstat (limited to 'src/main/java/at')
11 files changed, 381 insertions, 37 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt index 373acc031..dfaac0e6d 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt @@ -90,7 +90,7 @@ import at.hannibal2.skyhanni.features.commands.tabcomplete.PlayerTabComplete import at.hannibal2.skyhanni.features.commands.tabcomplete.WarpTabComplete import at.hannibal2.skyhanni.features.cosmetics.ArrowTrail import at.hannibal2.skyhanni.features.cosmetics.CosmeticFollowingLine -import at.hannibal2.skyhanni.features.dungeon.CroesusUnopenedChestTracker +import at.hannibal2.skyhanni.features.dungeon.CroesusChestTracker import at.hannibal2.skyhanni.features.dungeon.DungeonAPI import at.hannibal2.skyhanni.features.dungeon.DungeonBossHideDamageSplash import at.hannibal2.skyhanni.features.dungeon.DungeonBossMessages @@ -576,7 +576,7 @@ class SkyHanniMod { loadModule(HighlightBonzoMasks()) loadModule(BazaarCancelledBuyOrderClipboard()) loadModule(CompactSplashPotionMessage()) - loadModule(CroesusUnopenedChestTracker()) + loadModule(CroesusChestTracker()) loadModule(CompactBingoChat()) loadModule(BrewingStandOverlay()) loadModule(FishingTimer()) diff --git a/src/main/java/at/hannibal2/skyhanni/config/Storage.java b/src/main/java/at/hannibal2/skyhanni/config/Storage.java index 014eccee2..597d3a7eb 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/Storage.java +++ b/src/main/java/at/hannibal2/skyhanni/config/Storage.java @@ -5,6 +5,8 @@ import at.hannibal2.skyhanni.data.model.ComposterUpgrade; import at.hannibal2.skyhanni.features.bingo.card.goals.BingoGoal; import at.hannibal2.skyhanni.features.combat.endernodetracker.EnderNodeTracker; import at.hannibal2.skyhanni.features.combat.ghostcounter.GhostData; +import at.hannibal2.skyhanni.features.dungeon.CroesusChestTracker; +import at.hannibal2.skyhanni.features.dungeon.CroesusChestTracker.Companion.OpenedState; import at.hannibal2.skyhanni.features.dungeon.DungeonAPI; import at.hannibal2.skyhanni.features.event.diana.DianaProfitTracker; import at.hannibal2.skyhanni.features.event.diana.MythologicalCreatureTracker; @@ -30,6 +32,7 @@ import at.hannibal2.skyhanni.utils.LorenzVec; import at.hannibal2.skyhanni.utils.NEUInternalName; import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker; import com.google.gson.annotations.Expose; +import jline.internal.Nullable; import net.minecraft.item.ItemStack; import java.util.ArrayList; @@ -39,6 +42,8 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.Stream; public class Storage { @@ -460,6 +465,36 @@ public class Storage { @Expose public Map<DungeonAPI.DungeonFloor, Integer> bosses = new HashMap<>(); + + @Expose + public List<DungeonRunInfo> runs = Stream.generate(DungeonRunInfo::new) + .limit(CroesusChestTracker.Companion.getMaxChests()) + .collect(Collectors.toCollection(ArrayList::new)); + + + public static class DungeonRunInfo { + + public DungeonRunInfo() { + } + + public DungeonRunInfo(String floor) { + this.floor = floor; + this.openState = OpenedState.UNOPENED; + } + + @Nullable + @Expose + public String floor = null; + + @Expose + @Nullable + public OpenedState openState = null; + + @Expose + @Nullable + public Boolean kismetUsed = null; + + } } @Expose diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/DungeonChestConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/DungeonChestConfig.java new file mode 100644 index 000000000..e58bf0252 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/DungeonChestConfig.java @@ -0,0 +1,22 @@ +package at.hannibal2.skyhanni.config.features.dungeon; + +import at.hannibal2.skyhanni.config.FeatureToggle; +import com.google.gson.annotations.Expose; +import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean; +import io.github.moulberry.moulconfig.annotations.ConfigOption; + +public class DungeonChestConfig { + + + @Expose + @ConfigOption(name = "Kismet", desc = "Adds a visual highlight for used kismet feather to the Croesus inventory.") + @ConfigEditorBoolean + @FeatureToggle + public boolean kismet = true; + + @Expose + @ConfigOption(name = "Kismet Amount", desc = "Shows the amount of kismet feathers as stack size.") + @ConfigEditorBoolean + @FeatureToggle + public boolean kismetStackSize = true; +} diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/DungeonConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/DungeonConfig.java index 0b1eecff6..516346d33 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/DungeonConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/dungeon/DungeonConfig.java @@ -100,8 +100,13 @@ public class DungeonConfig { public boolean highlightSkeletonSkull = true; @Expose + @ConfigOption(name = "Chests Config", desc = "") + @Accordion + public DungeonChestConfig chest = new DungeonChestConfig(); + + @Expose @ConfigOption(name = "Croesus Chest", desc = "Adds a visual highlight to the Croesus inventory that " + - "shows unopened chests.") + "shows unopened chests.") // TODO move( , "dungeon.croesusUnopenedChestTracker" ,"dungeon.chest.showUnopened" ) @ConfigEditorBoolean @FeatureToggle public boolean croesusUnopenedChestTracker = true; diff --git a/src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt index e42bdb8af..f72d2d5d2 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/SackAPI.kt @@ -340,6 +340,7 @@ data class SackItem( ) { fun getStatus() = status ?: SackStatus.MISSING + fun statusIsCorrectOrAlright() = getStatus().let { it == SackStatus.CORRECT || it == SackStatus.ALRIGHT } } private val gemstoneMap = mapOf( @@ -355,7 +356,6 @@ private val gemstoneMap = mapOf( // ideally should be correct but using alright should also be fine unless they sold their whole sacks enum class SackStatus { - MISSING, CORRECT, ALRIGHT, diff --git a/src/main/java/at/hannibal2/skyhanni/events/DungeonCompleteEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/DungeonCompleteEvent.kt new file mode 100644 index 000000000..d278753cb --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/events/DungeonCompleteEvent.kt @@ -0,0 +1,3 @@ +package at.hannibal2.skyhanni.events + +class DungeonCompleteEvent(val floor: String) : LorenzEvent() diff --git a/src/main/java/at/hannibal2/skyhanni/events/InventoryFullyOpenedEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/InventoryFullyOpenedEvent.kt index bc9e97ed8..f8d6c4ab4 100644 --- a/src/main/java/at/hannibal2/skyhanni/events/InventoryFullyOpenedEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/events/InventoryFullyOpenedEvent.kt @@ -9,6 +9,9 @@ open class InventoryOpenEvent(private val inventory: OtherInventoryData.Inventor val inventoryName: String by lazy { inventory.title } val inventorySize: Int by lazy { inventory.slotCount } val inventoryItems: Map<Int, ItemStack> by lazy { inventory.items } + val inventoryItemsWithNull: Map<Int, ItemStack?> by lazy { + (0 until inventorySize).associateWith { inventoryItems[it] } + } val fullyOpenedOnce: Boolean get() = inventory.fullyOpenedOnce } diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/CroesusChestTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/CroesusChestTracker.kt new file mode 100644 index 000000000..e831a2a11 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/CroesusChestTracker.kt @@ -0,0 +1,275 @@ +package at.hannibal2.skyhanni.features.dungeon + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.config.Storage.ProfileSpecific.DungeonStorage.DungeonRunInfo +import at.hannibal2.skyhanni.data.ProfileStorageData +import at.hannibal2.skyhanni.data.SackAPI +import at.hannibal2.skyhanni.events.DungeonCompleteEvent +import at.hannibal2.skyhanni.events.GuiContainerEvent +import at.hannibal2.skyhanni.events.InventoryCloseEvent +import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent +import at.hannibal2.skyhanni.events.RenderInventoryItemTipEvent +import at.hannibal2.skyhanni.events.RenderItemTipEvent +import at.hannibal2.skyhanni.features.dungeon.DungeonAPI.DungeonChest +import at.hannibal2.skyhanni.test.command.ErrorManager +import at.hannibal2.skyhanni.utils.InventoryUtils +import at.hannibal2.skyhanni.utils.ItemUtils.getLore +import at.hannibal2.skyhanni.utils.ItemUtils.name +import at.hannibal2.skyhanni.utils.LorenzColor +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName +import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimal +import at.hannibal2.skyhanni.utils.RenderUtils.highlight +import at.hannibal2.skyhanni.utils.StringUtils.anyMatches +import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher +import at.hannibal2.skyhanni.utils.StringUtils.matches +import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern +import net.minecraft.init.Items +import net.minecraft.item.ItemStack +import net.minecraftforge.fml.common.eventhandler.EventPriority +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class CroesusChestTracker { + + private val config get() = SkyHanniMod.feature.dungeon.chest + + private val repoGroup = RepoPattern.group("dungeon.croesus") + + private val croesusPattern by repoGroup.pattern("inventory", "Croesus") + private val croesusEmptyPattern by repoGroup.pattern("empty", "§cNo treasures!") + private val kismetPattern by repoGroup.pattern("kismet.reroll", "§aReroll Chest") + private val kismetUsedPattern by repoGroup.pattern("kismet.used", "§aYou already rerolled a chest!") + + private val floorPattern by repoGroup.pattern("chest.floor", "§7Tier: §eFloor (?<floor>[IV]+)") + private val masterPattern by repoGroup.pattern("chest.master", ".*Master.*") + + private val keyUsedPattern by repoGroup.pattern("chest.state.keyused", "§aNo more Chests to open!") + private val openedPattern by repoGroup.pattern("chest.state.opened", "§8Opened Chest:.*") + private val unopenedPattern by repoGroup.pattern("chest.state.unopened", "§8No Chests Opened!") + + private val kismetSlotId = 50 + private val emptySlotId = 22 + private val frontArrowSlotId = 53 + private val backArrowSlotId = 45 + + private val kismetInternalName = "KISMET_FEATHER".asInternalName() + + private var inCroesusInventory = false + private var croesusEmpty = false + private var currentPage = 0 + private var pageSwitchable = false + + private var chestInventory: DungeonChest? = null + + private var currentRunIndex = 0 + + private var kismetAmountCache = 0 + + @SubscribeEvent(priority = EventPriority.LOW) + fun onBackgroundDrawn(event: GuiContainerEvent.BackgroundDrawnEvent) { + if (!LorenzUtils.inSkyBlock) return + if (!SkyHanniMod.feature.dungeon.croesusUnopenedChestTracker) return + + if (inCroesusInventory && !croesusEmpty) { + for ((run, slot) in InventoryUtils.getItemsInOpenChest() + .mapNotNull { slot -> runSlots(slot.slotIndex, slot) }) { + + // If one chest is null every followup chest is null. Therefore, an early return is possible + if (run.floor == null) return + + val state = run.openState ?: OpenedState.UNOPENED + + if (state != OpenedState.KEY_USED) { + slot highlight if (state == OpenedState.OPENED) LorenzColor.DARK_AQUA else LorenzColor.DARK_PURPLE + } + } + } + } + + @SubscribeEvent + fun onInventoryOpen(event: InventoryFullyOpenedEvent) { + if (!LorenzUtils.inSkyBlock) return + if ((SkyHanniMod.feature.dungeon.croesusUnopenedChestTracker || config.kismet) && croesusPattern.matches(event.inventoryName)) { + pageSetup(event) + + if (croesusEmpty) { + croesusChests?.forEach { + it.setValuesNull() + } + return + } + + // With null, since if an item is missing the chest will be set null + checkChests(event.inventoryItemsWithNull) + + return + } + if (config.kismet || config.kismetStackSize) { + kismetDungeonChestSetup(event) + } + } + + private fun kismetDungeonChestSetup(event: InventoryFullyOpenedEvent) { + chestInventory = DungeonChest.getByInventoryName(event.inventoryName) ?: return + if (config.kismetStackSize) { + kismetAmountCache = getKismetAmount().toInt() + } + if (config.kismet) { + val kismetItem = event.inventoryItems[kismetSlotId] ?: return + if (config.kismet && kismetUsedPattern.matches(kismetItem.getLore().lastOrNull())) + setKismetUsed() + } + } + + private fun checkChests(inventory: Map<Int, ItemStack?>) { + for ((run, item) in inventory.mapNotNull { (key, value) -> runSlots(key, value) }) { + if (item == null) { + run.setValuesNull() + continue + } + + val lore = item.getLore() + + if (run.floor == null) run.floor = + (if (masterPattern.matches(item.name)) "M" else "F") + (lore.firstNotNullOfOrNull { + floorPattern.matchMatcher(it) { group("floor").romanToDecimal() } + } ?: "0") + run.openState = when { + keyUsedPattern.anyMatches(lore) -> OpenedState.KEY_USED + openedPattern.anyMatches(lore) -> OpenedState.OPENED + unopenedPattern.anyMatches(lore) -> OpenedState.UNOPENED + else -> ErrorManager.logErrorStateWithData( + "Croesus Chest couldn't be read correctly.", + "Openstate check failed for chest.", + "run" to run, + "lore" to lore + ).run { null } + } + } + } + + private fun pageSetup(event: InventoryFullyOpenedEvent) { + inCroesusInventory = true + pageSwitchable = true + croesusEmpty = croesusEmptyPattern.matches(event.inventoryItems[emptySlotId]?.name) + if (event.inventoryItems[backArrowSlotId]?.item != Items.arrow) { + currentPage = 0 + } + } + + private fun DungeonRunInfo.setValuesNull() { + floor = null + openState = null + kismetUsed = null + } + + @SubscribeEvent + fun onInventoryClose(event: InventoryCloseEvent) { + inCroesusInventory = false + chestInventory = null + } + + @SubscribeEvent + fun onSlotClicked(event: GuiContainerEvent.SlotClickEvent) { + if (!LorenzUtils.inSkyBlock) return + if (!config.kismet) return + if (chestInventory != null && event.slotId == kismetSlotId) { + setKismetUsed() + return + } + if (inCroesusInventory && !croesusEmpty) { + if (event.slot == null) return + when (event.slotId) { + frontArrowSlotId -> if (pageSwitchable && event.slot.stack.isArrow()) { + pageSwitchable = false + currentPage++ + } + + backArrowSlotId -> if (pageSwitchable && event.slot.stack.isArrow()) { + pageSwitchable = false + currentPage-- + } + + else -> croesusSlotMapToRun(event.slotId)?.let { currentRunIndex = it } + } + } + } + + @SubscribeEvent + fun onRenderItemTipAmount(event: RenderItemTipEvent) { + if (!LorenzUtils.inSkyBlock) return + if (!config.kismetStackSize) return + if (chestInventory == null) return + if (!kismetPattern.matches(event.stack.name)) return + if (kismetUsedPattern.matches(event.stack.getLore().lastOrNull())) return + event.stackTip = "§a$kismetAmountCache" + } + + @SubscribeEvent + fun onRenderItemTipIsKismetable(event: RenderInventoryItemTipEvent) { + if (!LorenzUtils.inSkyBlock) return + if (!config.kismet) return + if (!inCroesusInventory) return + if (event.slot.slotIndex != event.slot.slotNumber) return + val run = croesusSlotMapToRun(event.slot.slotIndex) ?: return + if (!getKismetUsed(run)) return + event.offsetY = -1 + event.offsetX = -9 + event.stackTip = "§a✔" + } + + @SubscribeEvent + fun onDungeonComplete(event: DungeonCompleteEvent) { + if (event.floor == "E") return + croesusChests?.add(0, DungeonRunInfo(event.floor)) + currentRunIndex = 0 + if ((croesusChests?.size ?: 0) > maxChests) { + croesusChests?.dropLast(1) + } + } + + private fun Int.getRun() = getRun0(this) + + private fun getRun0(run: Int = currentRunIndex) = croesusChests?.takeIf { run < it.size }?.get(run) + + private fun setKismetUsed() { + getRun0()?.kismetUsed = true + } + + private fun getKismetUsed(runIndex: Int) = getRun0(runIndex)?.kismetUsed ?: false + + private fun getKismetAmount() = + (SackAPI.fetchSackItem(kismetInternalName).takeIf { it.statusIsCorrectOrAlright() }?.amount + ?: 0) + InventoryUtils.getAmountOfItemInInventory(kismetInternalName) + + private fun croesusSlotMapToRun(slotId: Int) = when (slotId) { + in 10..16 -> slotId - 10 // 0 - 6 + in 19..25 -> slotId - 12 // 7 - 13 + in 28..34 -> slotId - 14 // 14 - 20 + in 37..43 -> slotId - 16 // 21 - 27 + else -> null + }?.let { it + currentPage * 28 } + + private fun ItemStack.isArrow() = this.item == Items.arrow + + private inline fun <reified T> runSlots(slotId: Int, any: T) = + croesusSlotMapToRun(slotId)?.getRun()?.let { it to any } + + companion object { + val maxChests = 60 + + private val croesusChests get() = ProfileStorageData.profileSpecific?.dungeons?.runs + + fun getLastActiveChest(includeDungeonKey: Boolean = false) = + (croesusChests?.indexOfLast { + it.floor != null && + (it.openState == OpenedState.UNOPENED || (includeDungeonKey && it.openState == OpenedState.OPENED)) + } ?: -1) + 1 + + enum class OpenedState { + UNOPENED, + OPENED, + KEY_USED, + } + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/CroesusUnopenedChestTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/CroesusUnopenedChestTracker.kt deleted file mode 100644 index 7c52f4154..000000000 --- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/CroesusUnopenedChestTracker.kt +++ /dev/null @@ -1,33 +0,0 @@ -package at.hannibal2.skyhanni.features.dungeon - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.GuiContainerEvent -import at.hannibal2.skyhanni.utils.InventoryUtils -import at.hannibal2.skyhanni.utils.ItemUtils.getLore -import at.hannibal2.skyhanni.utils.LorenzColor -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.RenderUtils.highlight -import net.minecraftforge.fml.common.eventhandler.EventPriority -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class CroesusUnopenedChestTracker { - - @SubscribeEvent(priority = EventPriority.LOW) - fun onBackgroundDrawn(event: GuiContainerEvent.BackgroundDrawnEvent) { - if (!LorenzUtils.inSkyBlock) return - if (!SkyHanniMod.feature.dungeon.croesusUnopenedChestTracker) return - - val chestName = InventoryUtils.openInventoryName() - - if (chestName == "Croesus") { - for (slot in InventoryUtils.getItemsInOpenChest()) { - val stack = slot.stack - val lore = stack.getLore() - if ("§eClick to view chests!" in lore && "§aNo more Chests to open!" !in lore) { - val hasOpenedChests = lore.any { it.contains("Opened Chest") } - slot highlight if (hasOpenedChests) LorenzColor.DARK_AQUA else LorenzColor.DARK_PURPLE - } - } - } - } -}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonAPI.kt index bb38d09b9..7b5afb875 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonAPI.kt @@ -4,6 +4,7 @@ import at.hannibal2.skyhanni.data.ProfileStorageData import at.hannibal2.skyhanni.data.ScoreboardData import at.hannibal2.skyhanni.events.DebugDataCollectEvent import at.hannibal2.skyhanni.events.DungeonBossRoomEnterEvent +import at.hannibal2.skyhanni.events.DungeonCompleteEvent import at.hannibal2.skyhanni.events.DungeonEnterEvent import at.hannibal2.skyhanni.events.DungeonStartEvent import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent @@ -20,6 +21,7 @@ import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimalIfNecessary import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.StringUtils.removeColor import at.hannibal2.skyhanni.utils.TabListData +import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern import net.minecraft.item.ItemStack import net.minecraftforge.fml.common.eventhandler.SubscribeEvent @@ -49,6 +51,13 @@ class DungeonAPI { private val timePattern = "Time Elapsed:( )?(?:(?<minutes>\\d+)m)? (?<seconds>\\d+)s".toPattern() // Examples: Time Elapsed: 10m 10s, Time Elapsed: 2s + private val patternGroup = RepoPattern.group("dungeon") + + private val dungeonComplete by patternGroup.pattern( + "complete", + "§.\\s+§.§.(?:The|Master Mode) Catacombs §.§.- §.§.Floor (?<floor>M?[IV]{1,3}|Entrance)" + ) + fun inDungeon() = dungeonFloor != null fun isOneOf(vararg floors: String) = dungeonFloor?.equalsOneOf(*floors) == true @@ -153,6 +162,11 @@ class DungeonAPI { if (matches() && boss != null && boss !in bossCollections) { bossCollections.addOrPut(boss, 1) } + return + } + dungeonComplete.matchMatcher(event.message) { + DungeonCompleteEvent(floor).postAndCatch() + return } } @@ -261,4 +275,18 @@ class DungeonAPI { MAGE("Mage"), TANK("Tank") } + + enum class DungeonChest(val inventory: String) { + WOOD("Wood Chest"), + GOLD("Gold Chest"), + DIAMOND("Diamond Chest"), + EMERALD("Emerald Chest"), + OBSIDIAN("Obsidian Chest"), + BEDROCK("Bedrock Chest"), + ; + + companion object { + fun getByInventoryName(inventory: String) = entries.firstOrNull { it.inventory == inventory } + } + } } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt index 4774e4e7a..c0b5e04df 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/InventoryUtils.kt @@ -1,6 +1,7 @@ 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 @@ -74,4 +75,9 @@ object InventoryUtils { val screen = Minecraft.getMinecraft().currentScreen as? GuiContainer ?: return false return screen.slotUnderMouse.inventory is InventoryPlayer && screen.slotUnderMouse.stack == itemStack } + + fun getAmountOfItemInInventory(name: NEUInternalName) = + countItemsInLowerInventory { it.getInternalNameOrNull() == name } + + fun isItemInInventory(name: NEUInternalName) = getAmountOfItemInInventory(name) > 0 } |