diff options
Diffstat (limited to 'src/main')
4 files changed, 130 insertions, 19 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/misc/BitsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/misc/BitsConfig.java index 9b3cc32e8..7179a2aab 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/misc/BitsConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/misc/BitsConfig.java @@ -7,6 +7,25 @@ import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorSlider; import io.github.notenoughupdates.moulconfig.annotations.ConfigOption; public class BitsConfig { + + @Expose + @ConfigOption(name = "Bulk Buy Cookie Time", desc = "Corrects the time for cookies if bought in bulk on the buy item.") + @ConfigEditorBoolean + @FeatureToggle + public boolean bulkBuyCookieTime = true; + + @Expose + @ConfigOption(name = "Bits on Cookie", desc = "Show the bits you would gain on a cookies.") + @ConfigEditorBoolean + @FeatureToggle + public boolean showBitsOnCookie = true; + + @Expose + @ConfigOption(name = "Bits on Cookie Change", desc = "Show the change in available bits on cookies.") + @ConfigEditorBoolean + @FeatureToggle + public boolean showBitsChangeOnCookie = false; + @Expose @ConfigOption(name = "Enable No Bits Warning", desc = "Alerts you when you have no bits available.") @ConfigEditorBoolean diff --git a/src/main/java/at/hannibal2/skyhanni/data/BitsAPI.kt b/src/main/java/at/hannibal2/skyhanni/data/BitsAPI.kt index 72928fd25..e9e58fa46 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/BitsAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/BitsAPI.kt @@ -60,7 +60,7 @@ object BitsAPI { // Scoreboard patterns val bitsScoreboardPattern by bitsDataGroup.pattern( "scoreboard", - "^Bits: §b(?<amount>[\\d,.]+).*$" + "^Bits: §b(?<amount>[\\d,.]+).*$", ) // Chat patterns @@ -68,17 +68,17 @@ object BitsAPI { private val bitsFromFameRankUpChatPattern by bitsChatGroup.pattern( "rankup.bits", - "§eYou gained §3(?<amount>.*) Bits Available §ecompounded from all your §epreviously eaten §6cookies§e! Click here to open §6cookie menu§e!" + "§eYou gained §3(?<amount>.*) Bits Available §ecompounded from all your §epreviously eaten §6cookies§e! Click here to open §6cookie menu§e!", ) private val fameRankUpPattern by bitsChatGroup.pattern( "rankup.rank", - "[§\\w\\s]+FAME RANK UP (?:§.)+(?<rank>.*)" + "[§\\w\\s]+FAME RANK UP (?:§.)+(?<rank>.*)", ) private val boosterCookieAte by bitsChatGroup.pattern( "boostercookieate", - "§eYou consumed a §6Booster Cookie§e!.*" + "§eYou consumed a §6Booster Cookie§e!.*", ) // GUI patterns @@ -86,12 +86,12 @@ object BitsAPI { private val bitsAvailableMenuPattern by bitsGuiGroup.pattern( "availablemenu", - "§7Bits Available: §b(?<toClaim>[\\d,]+)(§3.+)?" + "§7Bits Available: §b(?<toClaim>[\\d,]+)(§3.+)?", ) private val fameRankSbMenuPattern by bitsGuiGroup.pattern( "sbmenufamerank", - "§7Your rank: §e(?<rank>.*)" + "§7Your rank: §e(?<rank>.*)", ) /** @@ -99,47 +99,47 @@ object BitsAPI { */ private val cookieDurationPattern by bitsGuiGroup.pattern( "cookieduration", - "\\s*§7Duration: §a(?<time>.*)" + "\\s*§7Duration: §a(?<time>.*)", ) private val noCookieActiveSBMenuPattern by bitsGuiGroup.pattern( "sbmenunocookieactive", - " §7Status: §cNot active!" + " §7Status: §cNot active!", ) private val noCookieActiveCookieMenuPattern by bitsGuiGroup.pattern( "cookiemenucookieactive", - "(§7§cYou do not currently have a|§cBooster Cookie active!)" + "(§7§cYou do not currently have a|§cBooster Cookie active!)", ) private val fameRankCommunityShopPattern by bitsGuiGroup.pattern( "communityshopfamerank", - "§7Fame Rank: §e(?<rank>.*)" + "§7Fame Rank: §e(?<rank>.*)", ) private val bitsGuiNamePattern by bitsGuiGroup.pattern( "mainmenuname", - "^SkyBlock Menu$" + "^SkyBlock Menu$", ) private val cookieGuiStackPattern by bitsGuiGroup.pattern( "mainmenustack", - "^§6Booster Cookie$" + "^§6Booster Cookie$", ) private val bitsStackPattern by bitsGuiGroup.pattern( "bitsstack", - "§bBits" + "§bBits", ) private val fameRankGuiNamePattern by bitsGuiGroup.pattern( "famerankmenuname", - "^(Community Shop|Booster Cookie)$" + "^(Community Shop|Booster Cookie)$", ) private val fameRankGuiStackPattern by bitsGuiGroup.pattern( "famerankmenustack", - "^(§aCommunity Shop|§eFame Rank)$" + "^(§aCommunity Shop|§eFame Rank)$", ) @SubscribeEvent @@ -187,14 +187,14 @@ object BitsAPI { "FameRank $rank not found", "Rank" to rank, "Message" to message, - "FameRanks" to FameRanks.fameRanks + "FameRanks" to FameRanks.fameRanks, ) return } boosterCookieAte.matchMatcher(message) { - bitsAvailable += (defaultCookieBits * (currentFameRank?.bitsMultiplier ?: return)).toInt() + bitsAvailable += bitsPerCookie() val cookieTime = cookieBuffTime cookieBuffTime = if (cookieTime == null) SimpleTimeMark.now() + 4.days else cookieTime + 4.days sendBitsAvailableGainedEvent() @@ -203,6 +203,8 @@ object BitsAPI { } } + fun bitsPerCookie(): Int = (defaultCookieBits * (currentFameRank?.bitsMultiplier ?: 1.0)).toInt() + @SubscribeEvent fun onInventoryOpen(event: InventoryFullyOpenedEvent) { if (!isEnabled()) return @@ -258,7 +260,7 @@ object BitsAPI { "FameRank $rank not found", "Rank" to rank, "Lore" to fameRankStack.getLore(), - "FameRanks" to FameRanks.fameRanks + "FameRanks" to FameRanks.fameRanks, ) continue@line @@ -273,7 +275,7 @@ object BitsAPI { "FameRank $rank not found", "Rank" to rank, "Lore" to fameRankStack.getLore(), - "FameRanks" to FameRanks.fameRanks + "FameRanks" to FameRanks.fameRanks, ) continue@line diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/BitsPerCookieVisual.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/BitsPerCookieVisual.kt new file mode 100644 index 000000000..8b38238ad --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/BitsPerCookieVisual.kt @@ -0,0 +1,80 @@ +package at.hannibal2.skyhanni.features.inventory + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.data.BitsAPI +import at.hannibal2.skyhanni.events.LorenzToolTipEvent +import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule +import at.hannibal2.skyhanni.utils.ItemUtils.getInternalNameOrNull +import at.hannibal2.skyhanni.utils.ItemUtils.name +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName +import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators +import at.hannibal2.skyhanni.utils.RegexUtils.firstMatcherWithIndex +import at.hannibal2.skyhanni.utils.RegexUtils.indexOfFirstMatch +import at.hannibal2.skyhanni.utils.RegexUtils.matches +import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +@SkyHanniModule +object BitsPerCookieVisual { + + private val config get() = SkyHanniMod.feature.misc.bits + + private val boosterCookie = "BOOSTER_COOKIE".asInternalName() + + private val patternGroup = RepoPattern.group("cookie.bits") + + private val wrongCookiePattern by patternGroup.pattern("wrong", "§[de]Booster Cookie") + + /** + * REGEX-TEST: §5§o§7Amount: §a1§7x + * REGEX-TEST: §5§o§6Booster Cookie §8x6 + */ + private val amountPattern by patternGroup.pattern("amount", "§5§o(?:§6Booster Cookie §8x|§7Amount: §a)(?<amount>\\d+).*") + + /** REGEX-TEST: §5§o§7§b4 §7days: + * */ + private val timePattern by patternGroup.pattern("time", "§5§o§7§b4 §7days:") + + @SubscribeEvent + fun onTooltip(event: LorenzToolTipEvent) { + if (!isEnabled()) return + if (event.itemStack.getInternalNameOrNull() != boosterCookie) return + if (wrongCookiePattern.matches(event.itemStack.name)) return + var timeReplaced = false + + val toolTip = event.toolTip + val (cookieAmount, loreIndex) = amountPattern.firstMatcherWithIndex(toolTip) { + group("amount").toInt() to it + } ?: (1 to 0) + val positionIndex = timePattern.indexOfFirstMatch(toolTip)?.also { + timeReplaced = true + if (config.bulkBuyCookieTime) { + toolTip.removeAt(it) + } + } ?: (loreIndex + 1) + + val gain = BitsAPI.bitsPerCookie() * cookieAmount + val newAvailable = BitsAPI.bitsAvailable + gain + val duration = 4 * cookieAmount + + var index = positionIndex + + if (timeReplaced) { + if (config.bulkBuyCookieTime) toolTip.add(index++, "§7§b$duration §7days") + toolTip.add(index++, "") + } else { + toolTip.add(index++, "") + if (config.bulkBuyCookieTime) toolTip.add(index++, "§8‣ §7Cookie Buff for §b$duration §7days") + } + + if (config.showBitsOnCookie) toolTip.add(index++, "§8‣ §7Gain §b${gain.addSeparators()} Bits") + if (config.showBitsChangeOnCookie) toolTip.add( + index++, + "§8‣ §7Available Bits: §3${BitsAPI.bitsAvailable.addSeparators()} §6→ §3${newAvailable.addSeparators()}", + ) + } + + private fun isEnabled() = LorenzUtils.inSkyBlock && + config.let { it.bulkBuyCookieTime || it.showBitsOnCookie || it.showBitsChangeOnCookie } +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/RegexUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/RegexUtils.kt index 068dfce1d..4faa9969c 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/RegexUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/RegexUtils.kt @@ -21,11 +21,21 @@ object RegexUtils { return null } + inline fun <T> Pattern.firstMatcherWithIndex(sequence: Sequence<String>, consumer: Matcher.(Int) -> T): T? { + for ((index, line) in sequence.withIndex()) { + matcher(line).let { if (it.matches()) return consumer(it, index) } + } + return null + } + @Deprecated("", ReplaceWith("pattern.firstMatcher(this) { consumer() }")) inline fun <T> List<String>.matchFirst(pattern: Pattern, consumer: Matcher.() -> T): T? = pattern.firstMatcher(this, consumer) inline fun <T> Pattern.firstMatcher(list: List<String>, consumer: Matcher.() -> T): T? = firstMatcher(list.asSequence(), consumer) + inline fun <T> Pattern.firstMatcherWithIndex(list: List<String>, consumer: Matcher.(Int) -> T): T? = + firstMatcherWithIndex(list.asSequence(), consumer) + @Deprecated("", ReplaceWith("pattern.matchAll(this) { consumer() }")) inline fun <T> List<String>.matchAll(pattern: Pattern, consumer: Matcher.() -> T): T? = pattern.matchAll(this, consumer) |