diff options
8 files changed, 174 insertions, 19 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt index 77c69e08d..2aa4e17fb 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.kt @@ -130,6 +130,7 @@ import at.hannibal2.skyhanni.features.event.chocolatefactory.ChocolateFactoryBar import at.hannibal2.skyhanni.features.event.chocolatefactory.ChocolateFactoryInventory import at.hannibal2.skyhanni.features.event.chocolatefactory.ChocolateFactoryShortcut import at.hannibal2.skyhanni.features.event.chocolatefactory.ChocolateFactoryStats +import at.hannibal2.skyhanni.features.event.chocolatefactory.ChocolateFactoryTimeTowerManager import at.hannibal2.skyhanni.features.event.chocolatefactory.HoppityCollectionStats import at.hannibal2.skyhanni.features.event.chocolatefactory.HoppityEggLocator import at.hannibal2.skyhanni.features.event.chocolatefactory.HoppityEggsManager @@ -629,6 +630,7 @@ class SkyHanniMod { loadModule(ChocolateFactoryInventory) loadModule(ChocolateFactoryStats) loadModule(FactoryItemTooltipFeatures) + loadModule(ChocolateFactoryTimeTowerManager) loadModule(HoppityEggsManager) loadModule(HoppityEggLocator) loadModule(HoppityEggsShared) diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/ChocolateFactoryConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/ChocolateFactoryConfig.java index a15f399a5..f2ca55a55 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/event/ChocolateFactoryConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/ChocolateFactoryConfig.java @@ -53,6 +53,7 @@ public class ChocolateFactoryConfig { ChocolateFactoryStat.EMPTY_2, ChocolateFactoryStat.MULTIPLIER, ChocolateFactoryStat.BARN, + ChocolateFactoryStat.TIME_TOWER, ChocolateFactoryStat.LEADERBOARD_POS )); @@ -91,6 +92,13 @@ public class ChocolateFactoryConfig { public boolean hoppityCollectionStats = true; @Expose + @ConfigOption(name = "Time Tower Warning", desc = "Notification when you have a new time tower usage available and " + + "continuously warn when your time tower is full.") + @ConfigEditorBoolean + @FeatureToggle + public boolean timeTowerWarning = false; + + @Expose @ConfigOption(name = "Hoppity Menu Shortcut", desc = "Add a Chocolate Factory button in the SkyBlock Menu that runs /chocolatefactory on click.") @ConfigEditorBoolean @FeatureToggle diff --git a/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java b/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java index f70d530e2..12861986e 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java +++ b/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java @@ -55,6 +55,15 @@ public class ProfileSpecificStorage { @Expose public int maxRabbits = -1; + + @Expose + public long nextTimeTower = 0; + + @Expose + public int currentTimeTowerUses = -1; + + @Expose + public int maxTimeTowerUses = 3; } @Expose diff --git a/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/HoppityEggLocationsJson.kt b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/HoppityEggLocationsJson.kt index 1aed17041..b5b4c699e 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/HoppityEggLocationsJson.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/jsonobjects/repo/HoppityEggLocationsJson.kt @@ -15,5 +15,6 @@ data class HoppityEggLocationsJson( @Expose val prestigeIndex: Int, @Expose val milestoneIndex: Int, @Expose val leaderboardIndex: Int, + @Expose val timeTowerIndex: Int, @Expose val maxRabbits: Int, ) diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryAPI.kt index af219fd25..53c003663 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryAPI.kt @@ -21,12 +21,14 @@ import at.hannibal2.skyhanni.utils.NumberUtil.formatDouble import at.hannibal2.skyhanni.utils.NumberUtil.formatInt import at.hannibal2.skyhanni.utils.NumberUtil.formatLong import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimal +import at.hannibal2.skyhanni.utils.SimpleTimeMark import at.hannibal2.skyhanni.utils.SkyblockSeason import at.hannibal2.skyhanni.utils.SoundUtils import at.hannibal2.skyhanni.utils.StringUtils.matchFirst import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.StringUtils.matches import at.hannibal2.skyhanni.utils.StringUtils.removeColor +import at.hannibal2.skyhanni.utils.TimeUtils import at.hannibal2.skyhanni.utils.UtilsPatterns import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern import net.minecraft.item.ItemStack @@ -78,6 +80,18 @@ object ChocolateFactoryAPI { "leaderboard.percentile", "§7§8You are in the top §.(?<percent>[\\d.]+)%§8 of players!" ) + private val timeTowerAmountPattern by patternGroup.pattern( + "timetower.amount", + "§7Charges: §.(?<uses>\\d+)§7/§a(?<max>\\d+)" + ) + private val timeTowerStatusPattern by patternGroup.pattern( + "timetower.status", + "§7Status: §.§l(?<status>INACTIVE|ACTIVE).*" + ) + private val timeTowerRechargePattern by patternGroup.pattern( + "timetower.recharge", + "§7Next Charge: §a(?<duration>\\w+)" + ) var rabbitSlots = mapOf<Int, Int>() var otherUpgradeSlots = setOf<Int>() @@ -88,6 +102,7 @@ object ChocolateFactoryAPI { private var prestigeIndex = 28 var milestoneIndex = 53 private var leaderboardIndex = 51 + private var timeTowerIndex = 39 var maxRabbits = 395 var inChocolateFactory = false @@ -100,6 +115,7 @@ object ChocolateFactoryAPI { var chocolateMultiplier = 1.0 var leaderboardPosition: Int? = null var leaderboardPercentile: Double? = null + var timeTowerActive = false val upgradeableSlots: MutableSet<Int> = mutableSetOf() var bestUpgrade: Int? = null @@ -125,14 +141,14 @@ object ChocolateFactoryAPI { } private fun updateInventoryItems(inventory: Map<Int, ItemStack>) { - val profileStorage = profileStorage ?: return - val infoItem = InventoryUtils.getItemAtSlotIndex(infoIndex) ?: return val prestigeItem = InventoryUtils.getItemAtSlotIndex(prestigeIndex) ?: return val productionInfoItem = InventoryUtils.getItemAtSlotIndex(productionInfoIndex) ?: return val leaderboardItem = InventoryUtils.getItemAtSlotIndex(leaderboardIndex) ?: return + val barnItem = InventoryUtils.getItemAtSlotIndex(barnIndex) ?: return + val timeTowerItem = InventoryUtils.getItemAtSlotIndex(timeTowerIndex) ?: return - processInfoItems(infoItem, prestigeItem, productionInfoItem, leaderboardItem) + processInfoItems(infoItem, prestigeItem, productionInfoItem, leaderboardItem, barnItem, timeTowerItem) bestUpgrade = null upgradeableSlots.clear() @@ -149,15 +165,6 @@ object ChocolateFactoryAPI { val lore = item.getLore() val upgradeCost = lore.getUpgradeCost() ?: continue - if (slotIndex == barnIndex) { - lore.matchFirst(barnAmountPattern) { - profileStorage.currentRabbits = group("rabbits").formatInt() - profileStorage.maxRabbits = group("max").formatInt() - - ChocolateFactoryBarnManager.trySendBarnFullMessage() - } - } - val canAfford = upgradeCost <= chocolateCurrent if (canAfford) upgradeableSlots.add(slotIndex) @@ -182,11 +189,15 @@ object ChocolateFactoryAPI { prestigeItem: ItemStack, productionItem: ItemStack, leaderboardItem: ItemStack, + barnItem: ItemStack, + timeTowerItem: ItemStack, ) { - leaderboardPosition = null - leaderboardPercentile = null + val profileStorage = profileStorage ?: return chocolateMultiplier = 1.0 + timeTowerActive = false + leaderboardPosition = null + leaderboardPercentile = null chocolateAmountPattern.matchMatcher(chocolateItem.name.removeColor()) { chocolateCurrent = group("amount").formatLong() @@ -216,6 +227,29 @@ object ChocolateFactoryAPI { leaderboardPercentile = group("percent").formatDouble() } } + barnItem.getLore().matchFirst(barnAmountPattern) { + profileStorage.currentRabbits = group("rabbits").formatInt() + profileStorage.maxRabbits = group("max").formatInt() + ChocolateFactoryBarnManager.trySendBarnFullMessage() + } + for (line in timeTowerItem.getLore()) { + timeTowerAmountPattern.matchMatcher(line) { + profileStorage.currentTimeTowerUses = group("uses").formatInt() + profileStorage.maxTimeTowerUses = group("max").formatInt() + ChocolateFactoryTimeTowerManager.checkTimeTowerWarning(true) + } + timeTowerStatusPattern.matchMatcher(line) { + timeTowerActive = group("status") == "ACTIVE" + } + timeTowerRechargePattern.matchMatcher(line) { + // todo in future fix this issue with TimeUtils.getDuration + val formattedGroup = group("duration").replace("h", "h ").replace("m", "m ") + + val timeUntilTower = TimeUtils.getDuration(formattedGroup) + val nextTimeTower = SimpleTimeMark.now() + timeUntilTower + profileStorage.nextTimeTower = nextTimeTower.toMillis() + } + } if (!config.statsDisplay) return ChocolateFactoryStats.updateDisplay() @@ -250,6 +284,7 @@ object ChocolateFactoryAPI { prestigeIndex = data.prestigeIndex milestoneIndex = data.milestoneIndex leaderboardIndex = data.leaderboardIndex + timeTowerIndex = data.timeTowerIndex maxRabbits = data.maxRabbits val disabledFeatures = event.getConstant<DisabledFeaturesJson>("DisabledFeatures") diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryBarnManager.kt b/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryBarnManager.kt index eeb44b630..0d953fcc4 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryBarnManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryBarnManager.kt @@ -52,9 +52,10 @@ object ChocolateFactoryBarnManager { val profileStorage = profileStorage ?: return + if (profileStorage.maxRabbits >= ChocolateFactoryAPI.maxRabbits) return + val remainingSpace = profileStorage.maxRabbits - profileStorage.currentRabbits - barnFull = - remainingSpace <= config.barnCapacityThreshold && profileStorage.maxRabbits < ChocolateFactoryAPI.maxRabbits + barnFull = remainingSpace <= config.barnCapacityThreshold if (!barnFull) return if (lastBarnFullWarning.passedSince() < 30.seconds) return diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryStats.kt b/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryStats.kt index 721d54892..ac16b7b14 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryStats.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryStats.kt @@ -26,6 +26,11 @@ object ChocolateFactoryStats { val perDay = perHour * 24 val position = ChocolateFactoryAPI.leaderboardPosition?.addSeparators() ?: "???" val percentile = ChocolateFactoryAPI.leaderboardPercentile?.let { "§7Top §a$it%" } ?: "" + val timeTowerInfo = if (ChocolateFactoryAPI.timeTowerActive) { + "§d§lActive" + } else { + "§6${ChocolateFactoryTimeTowerManager.timeTowerCharges()}" + } displayList = formatList(buildList { add("§6§lChocolate Factory Stats") @@ -47,19 +52,21 @@ object ChocolateFactoryStats { add("") add("") add("") + + add("§eTime Tower: §6$timeTowerInfo") }) } private fun formatList(list: List<String>): List<String> { return config.statsDisplayList - .filter { ChocolateFactoryAPI.currentPrestige != 1 || it != ChocolateFactoryStat.THIS_PRESTIGE } + .filter { it.shouldDisplay() } .map { list[it.ordinal] } } - enum class ChocolateFactoryStat(private val display: String) { + enum class ChocolateFactoryStat(private val display: String, val shouldDisplay: () -> Boolean = { true }) { HEADER("§6§lChocolate Factory Stats"), CURRENT("§eCurrent Chocolate: §65,272,230"), - THIS_PRESTIGE("§eThis Prestige: §6483,023,853"), + THIS_PRESTIGE("§eThis Prestige: §6483,023,853", { ChocolateFactoryAPI.currentPrestige != 1 }), ALL_TIME("§eAll-time: §6641,119,115"), PER_SECOND("§ePer Second: §63,780.72"), PER_MINUTE("§ePer Minute: §6226,843.2"), @@ -71,6 +78,7 @@ object ChocolateFactoryStats { EMPTY(""), EMPTY_2(""), EMPTY_3(""), + TIME_TOWER("§eTime Tower: §62/3 Charges", { ChocolateFactoryTimeTowerManager.currentCharges() != -1 }), ; override fun toString(): String { diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryTimeTowerManager.kt b/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryTimeTowerManager.kt new file mode 100644 index 000000000..28f601b66 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/event/chocolatefactory/ChocolateFactoryTimeTowerManager.kt @@ -0,0 +1,91 @@ +package at.hannibal2.skyhanni.features.event.chocolatefactory + +import at.hannibal2.skyhanni.events.ProfileJoinEvent +import at.hannibal2.skyhanni.events.SecondPassedEvent +import at.hannibal2.skyhanni.features.fame.ReminderUtils +import at.hannibal2.skyhanni.utils.ChatUtils +import at.hannibal2.skyhanni.utils.HypixelCommands +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.SimpleTimeMark +import at.hannibal2.skyhanni.utils.SoundUtils +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.time.Duration.Companion.hours +import kotlin.time.Duration.Companion.minutes +import kotlin.time.Duration.Companion.seconds + +object ChocolateFactoryTimeTowerManager { + + private val config get() = ChocolateFactoryAPI.config + private val profileStorage get() = ChocolateFactoryAPI.profileStorage + + private var lastTimeTowerWarning = SimpleTimeMark.farPast() + + @SubscribeEvent + fun onSecondPassed(event: SecondPassedEvent) { + if (!LorenzUtils.inSkyBlock) return + if (ChocolateFactoryAPI.inChocolateFactory) return + val profileStorage = profileStorage ?: return + + val nextCharge = SimpleTimeMark(profileStorage.nextTimeTower) + + if (nextCharge.isInPast() && !nextCharge.isFarPast() && currentCharges() < maxCharges()) { + profileStorage.currentTimeTowerUses++ + + // todo in future once have Einstein rabbit account for that + val nextTimeTower = SimpleTimeMark(profileStorage.nextTimeTower) + 8.hours + profileStorage.nextTimeTower = nextTimeTower.toMillis() + + if (!config.timeTowerWarning) return + ChatUtils.clickableChat( + "Your Time Tower has another charge available §7(${timeTowerCharges()})§e, " + + "Click here to use one", + onClick = { + HypixelCommands.chocolateFactory() + } + ) + SoundUtils.playBeepSound() + lastTimeTowerWarning = SimpleTimeMark.now() + return + } + checkTimeTowerWarning(false) + } + + fun checkTimeTowerWarning(inInventory: Boolean) { + if (!ChocolateFactoryAPI.isEnabled()) return + if (!config.timeTowerWarning) return + if (!timeTowerFull()) return + if (ReminderUtils.isBusy()) return + + val warningSeparation = if (inInventory) 30.seconds else 5.minutes + if (lastTimeTowerWarning.passedSince() < warningSeparation) return + + ChatUtils.clickableChat( + "§cYour Time Tower is full §7(${timeTowerCharges()})§c, " + + "Use one to avoid wasting time tower usages!", + onClick = { + HypixelCommands.chocolateFactory() + } + ) + SoundUtils.playBeepSound() + lastTimeTowerWarning = SimpleTimeMark.now() + } + + fun timeTowerCharges(): String { + return "${currentCharges()}/${maxCharges()} Charges" + } + + fun currentCharges(): Int { + return profileStorage?.currentTimeTowerUses ?: -1 + } + + private fun maxCharges(): Int { + return profileStorage?.maxTimeTowerUses ?: 3 + } + + private fun timeTowerFull() = currentCharges() >= maxCharges() + + @SubscribeEvent + fun onProfileChange(event: ProfileJoinEvent) { + lastTimeTowerWarning = SimpleTimeMark.farPast() + } +} |