Skip to content

Commit

Permalink
Feature: Bits on Cookie (#2265)
Browse files Browse the repository at this point in the history
Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com>
  • Loading branch information
Thunderblade73 and hannibal002 authored Aug 31, 2024
1 parent c834fbb commit 79d891d
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,25 @@
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
Expand Down
40 changes: 21 additions & 19 deletions src/main/java/at/hannibal2/skyhanni/data/BitsAPI.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,86 +60,86 @@ object BitsAPI {
// Scoreboard patterns
val bitsScoreboardPattern by bitsDataGroup.pattern(
"scoreboard",
"^Bits: §b(?<amount>[\\d,.]+).*$"
"^Bits: §b(?<amount>[\\d,.]+).*$",
)

// Chat patterns
private val bitsChatGroup = bitsDataGroup.group("chat")

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
private val bitsGuiGroup = bitsDataGroup.group("gui")

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>.*)",
)

/**
* REGEX-TEST: §7Duration: §a140d 8h 35m 36s
*/
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
Expand Down Expand Up @@ -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()
Expand All @@ -203,6 +203,8 @@ object BitsAPI {
}
}

fun bitsPerCookie(): Int = (defaultCookieBits * (currentFameRank?.bitsMultiplier ?: 1.0)).toInt()

@SubscribeEvent
fun onInventoryOpen(event: InventoryFullyOpenedEvent) {
if (!isEnabled()) return
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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 }
}
10 changes: 10 additions & 0 deletions src/main/java/at/hannibal2/skyhanni/utils/RegexUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down

0 comments on commit 79d891d

Please sign in to comment.