diff --git a/src/main/java/at/hannibal2/skyhanni/api/HotmAPI.kt b/src/main/java/at/hannibal2/skyhanni/api/HotmAPI.kt index 6c585a9b69e2..7b16747ee07a 100644 --- a/src/main/java/at/hannibal2/skyhanni/api/HotmAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/api/HotmAPI.kt @@ -26,7 +26,7 @@ object HotmAPI { val activeMiningAbility get() = HotmData.abilities.firstOrNull { it.enabled } - private val blueGoblinEgg = "GOBLIN_EGG_BLUE".asInternalName() + private val blueGoblinEgg = "goblin_omelette_blue_cheese".asInternalName() private val blueEggCache = TimeLimitedCache(10.0.seconds) val isBlueEggActive @@ -90,4 +90,31 @@ object HotmAPI { setTotal(0) } } + + var skymall: SkymallPerk? = null + + var mineshaftMayhem: MayhemPerk? = null + + enum class SkymallPerk(chat: String, itemString: String) { + MINING_SPEED("Gain §r§a+100 §r§6⸕ Mining Speed§r§f.", "Gain §a+100 §6⸕ Mining Speed§7."), + MINING_FORTUNE("Gain §r§a+50 §r§6☘ Mining Fortune§r§f.", "Gain §a+50 §6☘ Mining Fortune§7."), + EXTRA_POWDER("Gain §r§a+15% §r§fmore Powder while mining.", "Gain §a+15% §7more Powder while mining."), + ABILITY_COOLDOWN("Reduce Pickaxe Ability cooldown by §r§a20%§r§f.", "Reduce Pickaxe Ability cooldown by"), + GOBLIN_CHANCE("§r§a10x §r§fchance to find Golden and Diamond Goblins.", "§a10x §7chance to find Golden and"), + TITANIUM("Gain §r§a5x §r§9Titanium §r§fdrops", "Gain §a+15% §7more Powder while mining.") + ; + + val chatPattern by RepoPattern.pattern("mining.hotm.skymall.chat.$name", chat) + val itemPattern by RepoPattern.pattern("mining.hotm.skymall.item.$name", itemString) + } + + enum class MayhemPerk(chat: String) { + SCRAP_CHANCE("Your §r§9Suspicious Scrap §r§7chance was buffed by your §r§aMineshaft Mayhem §r§7perk!"), + MINING_FORTUNE("You received a §r§a§r§6☘ Mining Fortune §r§7buff from your §r§aMineshaft Mayhem §r§7perk!"), + MINING_SPEED("You received a §r§a§r§6⸕ Mining Speed §r§7buff from your §r§aMineshaft Mayhem §r§7perk!"), + COLD_RESISTANCE("You received a §r§a§r§b❄ Cold Resistance §r§7buff from your §r§aMineshaft Mayhem §r§7perk!"), + ABILITY_COOLDOWN("Your Pickaxe Ability cooldown was reduced §r§7from your §r§aMineshaft Mayhem §r§7perk!"); + + val chatPattern by RepoPattern.pattern("mining.hotm.mayhem.chat.$name", chat) + } } diff --git a/src/main/java/at/hannibal2/skyhanni/data/HotmData.kt b/src/main/java/at/hannibal2/skyhanni/data/HotmData.kt index dc821d2c4471..515361588a25 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/HotmData.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/HotmData.kt @@ -1,15 +1,19 @@ package at.hannibal2.skyhanni.data import at.hannibal2.skyhanni.api.HotmAPI +import at.hannibal2.skyhanni.api.HotmAPI.MayhemPerk +import at.hannibal2.skyhanni.api.HotmAPI.SkymallPerk import at.hannibal2.skyhanni.config.storage.ProfileSpecificStorage import at.hannibal2.skyhanni.data.jsonobjects.local.HotmTree import at.hannibal2.skyhanni.events.DebugDataCollectEvent import at.hannibal2.skyhanni.events.InventoryCloseEvent import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent +import at.hannibal2.skyhanni.events.IslandChangeEvent import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.events.ProfileJoinEvent import at.hannibal2.skyhanni.events.ScoreboardChangeEvent import at.hannibal2.skyhanni.features.gui.customscoreboard.ScoreboardPattern +import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.ChatUtils import at.hannibal2.skyhanni.utils.ConditionalUtils.transformIf import at.hannibal2.skyhanni.utils.DelayedRun @@ -20,6 +24,7 @@ import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators import at.hannibal2.skyhanni.utils.NumberUtil.formatLong import at.hannibal2.skyhanni.utils.StringUtils.allLettersFirstUppercase +import at.hannibal2.skyhanni.utils.StringUtils.indexOfFirstMatch import at.hannibal2.skyhanni.utils.StringUtils.matchFirst import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.StringUtils.matches @@ -373,6 +378,16 @@ enum class HotmData( "inventory.reset.token", "\\s+§8- §5(?\\d+) Token of the Mountain" ) + private val skymallPattern by repoGroup.pattern( + "skymall", + "(?:§eNew buff§r§r§r: §r§f|§8 ■ §7)(?.*)" + ) + + private val mayhemChatPattern by repoGroup.pattern( + "mayhem", + "§b§lMAYHEM! §r§7(?.*)" + ) + var inInventory = false var tokens: Int @@ -395,6 +410,13 @@ enum class HotmData( it.heartPattern it.resetPattern } + HotmAPI.SkymallPerk.entries.forEach { + it.chatPattern + it.itemPattern + } + HotmAPI.MayhemPerk.entries.forEach { + it.chatPattern + } } fun getPerkByNameOrNull(name: String): HotmData? = entries.find { it.guiName == name } @@ -439,6 +461,8 @@ enum class HotmData( return } entry.enabled = lore.any { enabledPattern.matches(it) } + + if (entry == SKY_MALL) handelSkyMall(lore) } private fun Slot.handlePowder(): Boolean { @@ -486,6 +510,34 @@ enum class HotmData( return true } + private val skyMallCurrentEffect by repoGroup.pattern("skymall.current", "§aYour Current Effect") + + private fun handelSkyMall(lore: List) { + if (!SKY_MALL.enabled || !SKY_MALL.isUnlocked) HotmAPI.skymall = null + else { + val index = lore.indexOfFirstMatch(skyMallCurrentEffect)?.plus(1) ?: run { + ErrorManager.logErrorStateWithData( + "Could not read the skymall effect from the hotm tree", + "skyMallCurrentEffect didn't match", + "lore" to lore + ) + return + } + skymallPattern.matchMatcher(lore[index]) { + val perk = group("perk") + HotmAPI.skymall = SkymallPerk.entries.firstOrNull { it.itemPattern.matches(perk) } ?: run { + ErrorManager.logErrorStateWithData( + "Could not read the skymall effect from the hotm tree", + "no itemPattern matched", + "lore" to lore, + "perk" to perk + ) + null + } + } + } + } + @SubscribeEvent fun onScoreboardUpdate(event: ScoreboardChangeEvent) { if (!LorenzUtils.inSkyBlock) return @@ -525,8 +577,46 @@ enum class HotmData( @SubscribeEvent fun onChat(event: LorenzChatEvent) { if (!LorenzUtils.inSkyBlock) return - if (!resetChatPattern.matches(event.message)) return - resetTree() + if (resetChatPattern.matches(event.message)) { + resetTree() + return + } + skymallPattern.matchMatcher(event.message) { + val perk = group("perk") + HotmAPI.skymall = SkymallPerk.entries.firstOrNull { it.chatPattern.matches(perk) } ?: run { + ErrorManager.logErrorStateWithData( + "Could not read the skymall effect from chat", + "no chatPattern matched", + "chat" to event.message, + "perk" to perk + ) + null + } + ChatUtils.debug("setting skymall to ${HotmAPI.skymall}") + return + } + DelayedRun.runNextTick { + mayhemChatPattern.matchMatcher(event.message) { + val perk = group("perk") + HotmAPI.mineshaftMayhem = MayhemPerk.entries.firstOrNull { it.chatPattern.matches(perk) } ?: run { + ErrorManager.logErrorStateWithData( + "Could not read the mayhem effect from chat", + "no chatPattern matched", + "chat" to event.message, + "perk" to perk + ) + null + } + ChatUtils.debug("setting mineshaftMayhem to ${HotmAPI.mineshaftMayhem}") + } + } + } + + @SubscribeEvent + fun onWorldSwitch(event: IslandChangeEvent) { + if (HotmAPI.mineshaftMayhem == null) return + HotmAPI.mineshaftMayhem = null + ChatUtils.debug("resetting mineshaftMayhem") } @SubscribeEvent @@ -550,6 +640,8 @@ enum class HotmData( } add("Ability: ${HotmAPI.activeMiningAbility?.printName}") add("Blue Egg: ${HotmAPI.isBlueEggActive}") + add("SkyMall: ${HotmAPI.skymall}") + add("Mineshaft Mayhem: ${HotmAPI.mineshaftMayhem}") } event.title("HotM - Tree") event.addIrrelevant( diff --git a/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt index 4e5bce0107e7..34b40288512f 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/StringUtils.kt @@ -116,6 +116,13 @@ object StringUtils { return null } + fun List.indexOfFirstMatch(pattern: Pattern): Int? { + for ((index, line) in this.withIndex()) { + pattern.matcher(line).let { if (it.matches()) return index } + } + return null + } + inline fun List.matchAll(pattern: Pattern, consumer: Matcher.() -> T): T? { for (line in this) { pattern.matcher(line).let { if (it.find()) consumer(it) } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/TimeLimitedCache.kt b/src/main/java/at/hannibal2/skyhanni/utils/TimeLimitedCache.kt index 2e5d556ca230..182b1381bfa7 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/TimeLimitedCache.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/TimeLimitedCache.kt @@ -18,17 +18,6 @@ class TimeLimitedCache( fun getOrNull(key: K): V? = cache.getIfPresent(key) - fun getOrPut(key: K, defaultValue: () -> V): V { - val value = cache.getIfPresent(key) - return if (value == null) { - val answer = defaultValue() - put(key, answer) - answer - } else { - value - } - } - fun getOrPut(key: K, defaultValue: () -> V) = getOrNull(key) ?: defaultValue().also { put(key, it) } fun clear() = cache.invalidateAll()