From 4b0618b4ab8d8c6eeea89eca61c5be297576e645 Mon Sep 17 00:00:00 2001 From: David Cole <40234707+DavidArthurCole@users.noreply.github.com> Date: Wed, 20 Nov 2024 15:15:44 -0500 Subject: [PATCH] Fix: Hoppity/Choc Factory Updates (#2925) --- .../event/hoppity/HoppityEggsConfig.java | 30 ++- .../repo/HoppityEggLocationsJson.kt | 1 + .../skyhanni/events/hoppity/EggFoundEvent.kt | 2 + .../events/hoppity/RabbitFoundEvent.kt | 9 + .../features/event/hoppity/HoppityAPI.kt | 235 ++++++++++-------- .../event/hoppity/HoppityEggDisplayManager.kt | 16 +- .../features/event/hoppity/HoppityEggType.kt | 28 ++- .../event/hoppity/HoppityEggsCompactChat.kt | 158 +++--------- .../event/hoppity/HoppityEggsManager.kt | 14 +- .../hoppity/HoppityRabbitTheFishChecker.kt | 3 + .../features/event/hoppity/WarpMenuUniques.kt | 1 - .../chocolatefactory/ChocolateFactoryAPI.kt | 10 +- .../ChocolateFactoryBarnManager.kt | 11 +- .../ChocolateFactoryInventory.kt | 4 + .../chocolatefactory/ChocolateFactoryStats.kt | 1 - .../hannibal2/skyhanni/utils/SkyBlockTime.kt | 2 +- 16 files changed, 267 insertions(+), 258 deletions(-) diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/event/hoppity/HoppityEggsConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/event/hoppity/HoppityEggsConfig.java index e1b475b8110d..a27978a11550 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/event/hoppity/HoppityEggsConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/event/hoppity/HoppityEggsConfig.java @@ -99,14 +99,38 @@ public class HoppityEggsConfig { public boolean showClaimedEggs = false; @Expose - @ConfigOption(name = "Show Collected Locations", desc = "Show the number of found egg locations on this island.\n" + - "§eThis is not retroactive and may not be fully synced with Hypixel's count.") + @ConfigOption(name = "Unclaimed Eggs Order", desc = "Order in which to display unclaimed eggs.") + @ConfigEditorDropdown + public UnclaimedEggsOrder unclaimedEggsOrder = UnclaimedEggsOrder.SOONEST_FIRST; + + public enum UnclaimedEggsOrder { + SOONEST_FIRST("Soonest First"), + MEAL_ORDER("Meal Order"), + ; + + private final String name; + + UnclaimedEggsOrder(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } + } + + @Expose + @ConfigOption( + name = "Show Collected Locations", desc = "Show the number of found egg locations on this island.\n" + + "§eThis is not retroactive and may not be fully synced with Hypixel's count." + ) @ConfigEditorBoolean @FeatureToggle public boolean showCollectedLocationCount = false; @Expose - @ConfigOption(name = "Warn When Unclaimed", desc = "Warn when all three eggs are ready to be found.") + @ConfigOption(name = "Warn When Unclaimed", desc = "Warn when all six eggs are ready to be found.") @ConfigEditorBoolean @FeatureToggle public boolean warnUnclaimedEggs = false; 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 ead4eb83c298..8f418d1c78b0 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 @@ -20,6 +20,7 @@ data class HoppityEggLocationsJson( @Expose val timeTowerIndex: Int, @Expose val shrineIndex: Int, @Expose val coachRabbitIndex: Int, + @Expose val rabbitHitmanIndex: Int, @Expose val maxRabbits: Int, @Expose val maxPrestige: Int, @Expose val chocolateMilestones: TreeSet, diff --git a/src/main/java/at/hannibal2/skyhanni/events/hoppity/EggFoundEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/hoppity/EggFoundEvent.kt index 30cd282ac8b4..69072233fb2c 100644 --- a/src/main/java/at/hannibal2/skyhanni/events/hoppity/EggFoundEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/events/hoppity/EggFoundEvent.kt @@ -1,10 +1,12 @@ package at.hannibal2.skyhanni.events.hoppity import at.hannibal2.skyhanni.api.event.SkyHanniEvent +import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggType class EggFoundEvent( val type: HoppityEggType, val slotIndex: Int? = null, val note: String? = null, + val chatEvent: LorenzChatEvent? = null ) : SkyHanniEvent() diff --git a/src/main/java/at/hannibal2/skyhanni/events/hoppity/RabbitFoundEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/hoppity/RabbitFoundEvent.kt index 865f5a69047d..d9643820320b 100644 --- a/src/main/java/at/hannibal2/skyhanni/events/hoppity/RabbitFoundEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/events/hoppity/RabbitFoundEvent.kt @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.events.hoppity import at.hannibal2.skyhanni.api.event.SkyHanniEvent +import at.hannibal2.skyhanni.features.event.hoppity.HoppityAPI import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggType class RabbitFoundEvent( @@ -9,6 +10,14 @@ class RabbitFoundEvent( val rabbitName: String, val chocGained: Long = 0, ) : SkyHanniEvent() { + + constructor(dataSet: HoppityAPI.HoppityStateDataSet) : this( + dataSet.lastMeal ?: HoppityEggType.BREAKFAST, + dataSet.duplicate, + dataSet.lastName, + dataSet.lastDuplicateAmount ?: 0, + ) + override fun toString(): String = "§fType§7: ${eggType.coloredName}\n§fDuplicate§7: §b$duplicate\n§fRabbit§7: $rabbitName\n§fChoc Gained§7: §6$chocGained" } diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityAPI.kt index 28672114511b..b7722e553af8 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityAPI.kt @@ -1,19 +1,23 @@ package at.hannibal2.skyhanni.features.event.hoppity import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.api.event.HandleEvent +import at.hannibal2.skyhanni.api.event.HandleEvent.Companion.HIGHEST import at.hannibal2.skyhanni.events.GuiContainerEvent -import at.hannibal2.skyhanni.events.InventoryCloseEvent -import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.events.SecondPassedEvent import at.hannibal2.skyhanni.events.hoppity.EggFoundEvent import at.hannibal2.skyhanni.events.hoppity.RabbitFoundEvent +import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggType.BOUGHT import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggType.CHOCOLATE_FACTORY_MILESTONE import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggType.CHOCOLATE_SHOP_MILESTONE import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggType.Companion.getEggType +import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggType.Companion.resettingEntries +import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggType.HITMAN import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggType.SIDE_DISH import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggType.STRAY import at.hannibal2.skyhanni.features.inventory.chocolatefactory.ChocolateFactoryAPI +import at.hannibal2.skyhanni.features.inventory.chocolatefactory.ChocolateFactoryBarnManager import at.hannibal2.skyhanni.features.inventory.chocolatefactory.ChocolateFactoryStrayTracker import at.hannibal2.skyhanni.features.inventory.chocolatefactory.ChocolateFactoryStrayTracker.duplicateDoradoStrayPattern import at.hannibal2.skyhanni.features.inventory.chocolatefactory.ChocolateFactoryStrayTracker.duplicatePseudoStrayPattern @@ -27,7 +31,6 @@ import at.hannibal2.skyhanni.utils.LorenzRarity import at.hannibal2.skyhanni.utils.LorenzRarity.DIVINE import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.RegexUtils.anyMatches -import at.hannibal2.skyhanni.utils.RegexUtils.firstMatcher import at.hannibal2.skyhanni.utils.RegexUtils.groupOrNull import at.hannibal2.skyhanni.utils.RegexUtils.matchMatcher import at.hannibal2.skyhanni.utils.RegexUtils.matches @@ -36,49 +39,20 @@ import at.hannibal2.skyhanni.utils.SimpleTimeMark.Companion.asTimeMark import at.hannibal2.skyhanni.utils.SkyBlockTime import at.hannibal2.skyhanni.utils.SkyblockSeason import at.hannibal2.skyhanni.utils.StringUtils.removeColor +import net.minecraft.init.Blocks import net.minecraft.init.Items import net.minecraft.inventory.Slot +import net.minecraft.item.Item import net.minecraftforge.fml.common.eventhandler.EventPriority import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.reflect.KMutableProperty1 +import kotlin.reflect.full.memberProperties import kotlin.time.Duration.Companion.seconds @SkyHanniModule object HoppityAPI { - private var messageCount = 0 - private var duplicate = false - private var lastRarity = "" - private var lastName = "" - private var lastNameCache = "" - private var newRabbit = false - private var lastMeal: HoppityEggType? = null - private var lastDuplicateAmount: Long? = null - private var inMiscProcessInventory = false - private val processedSlots = mutableListOf() - - val hoppityRarities by lazy { LorenzRarity.entries.filter { it <= DIVINE } } - - private fun resetRabbitData() { - this.messageCount = 0 - this.duplicate = false - this.newRabbit = false - this.lastRarity = "" - this.lastName = "" - this.lastMeal = null - this.lastDuplicateAmount = null - } - - fun getLastRabbit(): String = this.lastNameCache - fun isHoppityEvent() = (SkyblockSeason.currentSeason == SkyblockSeason.SPRING || SkyHanniMod.feature.dev.debug.alwaysHoppitys) - fun getEventEndMark(): SimpleTimeMark? = if (isHoppityEvent()) { - SkyBlockTime.fromSbYearAndMonth(SkyBlockTime.now().year, 3).asTimeMark() - } else null - - - fun rarityByRabbit(rabbit: String): LorenzRarity? = hoppityRarities.firstOrNull { - it.chatColorCode == rabbit.substring(0, 2) - } - + // /** * REGEX-TEST: §f1st Chocolate Milestone * REGEX-TEST: §915th Chocolate Milestone @@ -133,8 +107,54 @@ object HoppityAPI { */ private val miscProcessInvPattern by ChocolateFactoryAPI.patternGroup.pattern( "inventory.misc", - "(?:§.)*Chocolate (?:Shop |(?:Factory|Breakfast|Lunch|Dinner|Brunch|Déjeuner|Supper) ?)(?:Milestones|Egg)?", + "(?:§.)*Chocolate (?:Shop |(?:Factory|Breakfast|Lunch|Dinner) ?)(?:Milestones|Egg)?", ) + // + + data class HoppityStateDataSet( + var hoppityMessages: MutableList = mutableListOf(), + var duplicate: Boolean = false, + var lastRarity: String = "", + var lastName: String = "", + var lastProfit: String = "", + var lastMeal: HoppityEggType? = null, + var lastDuplicateAmount: Long? = null + ) { + fun reset() { + val default = HoppityStateDataSet() + this::class.memberProperties + .filterIsInstance>() + .forEach { prop -> + prop.set(this, prop.get(default)) + } + } + } + + private val hoppityDataSet = HoppityStateDataSet() + private val processedSlots = mutableListOf() + private val S_GLASS_PANE_ITEM by lazy { Item.getItemFromBlock(Blocks.stained_glass_pane) } + private val CHEST_ITEM by lazy { Item.getItemFromBlock(Blocks.chest) } + + val hoppityRarities by lazy { LorenzRarity.entries.filter { it <= DIVINE } } + + fun isHoppityEvent() = (SkyblockSeason.currentSeason == SkyblockSeason.SPRING || SkyHanniMod.feature.dev.debug.alwaysHoppitys) + fun getEventEndMark(): SimpleTimeMark? = if (isHoppityEvent()) { + SkyBlockTime.fromSbYearAndMonth(SkyBlockTime.now().year, 3).asTimeMark() + } else null + fun rarityByRabbit(rabbit: String): LorenzRarity? = hoppityRarities.firstOrNull { + it.chatColorCode == rabbit.substring(0, 2) + } + fun SkyBlockTime.isAlternateDay(): Boolean { + if (!isHoppityEvent()) return false + // Spring 1st (first day of event) is a normal day. + // Spring 2nd is an alternate day, Spring 3rd is a normal day, etc. + // So Month 3, day 1 is used as the baseline. + + // Because months are all 31 days, it flip-flops every month. + // If the month is 1 or 3, alternate days are on even days. + // If the month is 2, alternate days are on odd days. + return (month % 2 == 1) == (day % 2 == 0) + } private fun addProcessedSlot(slot: Slot) { processedSlots.add(slot.slotNumber) @@ -152,6 +172,14 @@ object HoppityAPI { // All strays are skulls with a display name, and lore. slot.stack.hasDisplayName() && slot.stack.item == Items.skull && slot.stack.getLore().isNotEmpty() + private fun postApiEggFoundEvent(type: HoppityEggType, event: LorenzChatEvent, note: String? = null) { + EggFoundEvent( + type, + chatEvent = event, + note = note + ).post() + } + @SubscribeEvent(priority = EventPriority.HIGH) fun onTick(event: SecondPassedEvent) { if (!ChocolateFactoryAPI.inChocolateFactory) return @@ -162,11 +190,9 @@ object HoppityAPI { processed = true when (groupOrNull("name") ?: return@matchMatcher) { "Fish the Rabbit" -> { + hoppityDataSet.lastName = "§9Fish the Rabbit" + hoppityDataSet.duplicate = it.stack.getLore().any { line -> duplicatePseudoStrayPattern.matches(line) } EggFoundEvent(STRAY, it.slotNumber).post() - lastName = "§9Fish the Rabbit" - lastMeal = STRAY - duplicate = it.stack.getLore().any { line -> duplicatePseudoStrayPattern.matches(line) } - attemptFireRabbitFound() } else -> return@matchMatcher @@ -180,36 +206,28 @@ object HoppityAPI { // We don't need to do a handleStrayClicked here - the lore from El Dorado is already: // §6§lGolden Rabbit §d§lCAUGHT! // Which will trigger the above matcher. We only need to check name here to fire the found event for Dorado. + hoppityDataSet.lastName = "§6El Dorado" + hoppityDataSet.duplicate = it.stack.getLore().any { line -> duplicateDoradoStrayPattern.matches(line) } EggFoundEvent(STRAY, it.slotNumber).post() - lastName = "§6El Dorado" - lastMeal = STRAY - duplicate = it.stack.getLore().any { line -> duplicateDoradoStrayPattern.matches(line) } - attemptFireRabbitFound() } if (processed) addProcessedSlot(it) } } - @SubscribeEvent - fun onInventoryOpen(event: InventoryFullyOpenedEvent) { - inMiscProcessInventory = miscProcessInvPattern.matches(event.inventoryName) - } - - @SubscribeEvent - fun onInventoryClose(event: InventoryCloseEvent) { - inMiscProcessInventory = false - } - private fun shouldProcessMiscSlot(slot: Slot) = // Don't process the same slot twice. !processedSlots.contains(slot.slotNumber) && slot.stack != null && slot.stack.item != null && - // All misc items are skulls with a display name, and lore. - slot.stack.hasDisplayName() && slot.stack.item == Items.skull && slot.stack.getLore().isNotEmpty() + // All misc items are skulls, panes, or chests with a display name, and lore. + shouldProcessMiscSlotItem(slot.stack.item) && + slot.stack.hasDisplayName() && slot.stack.getLore().isNotEmpty() + + private fun shouldProcessMiscSlotItem(item: Item) = + item == Items.skull || item == S_GLASS_PANE_ITEM || item == CHEST_ITEM @SubscribeEvent(priority = EventPriority.HIGH) fun onSlotClick(event: GuiContainerEvent.SlotClickEvent) { - if (!inMiscProcessInventory) return + if (!miscProcessInvPattern.matches(InventoryUtils.openInventoryName())) return val slot = event.slot ?: return val index = slot.slotIndex.takeIf { it != -999 } ?: return if (!shouldProcessMiscSlot(slot)) return @@ -219,74 +237,95 @@ object HoppityAPI { ?.stack ?: return val nameText = (if (clickedStack.hasDisplayName()) clickedStack.displayName else clickedStack.itemName) - sideDishNamePattern.matchMatcher(nameText) { - EggFoundEvent(SIDE_DISH, index).post() - lastMeal = SIDE_DISH - attemptFireRabbitFound() - } + if (sideDishNamePattern.matches(nameText)) EggFoundEvent(SIDE_DISH, index).post() milestoneNamePattern.matchMatcher(nameText) { val lore = clickedStack.getLore() if (!claimableMilestonePattern.anyMatches(lore)) return - allTimeLorePattern.firstMatcher(lore) { - EggFoundEvent(CHOCOLATE_FACTORY_MILESTONE, index).post() - lastMeal = CHOCOLATE_FACTORY_MILESTONE - attemptFireRabbitFound() - } - shopLorePattern.firstMatcher(lore) { - EggFoundEvent(CHOCOLATE_SHOP_MILESTONE, index).post() - lastMeal = CHOCOLATE_SHOP_MILESTONE - attemptFireRabbitFound() - } + if (allTimeLorePattern.anyMatches(lore)) EggFoundEvent(CHOCOLATE_FACTORY_MILESTONE, index).post() + if (shopLorePattern.anyMatches(lore)) EggFoundEvent(CHOCOLATE_SHOP_MILESTONE, index).post() } } + @HandleEvent(priority = HIGHEST) + fun onEggFound(event: EggFoundEvent) { + hoppityDataSet.lastMeal = event.type + + when (event.type) { + SIDE_DISH -> + "§d§lHOPPITY'S HUNT §r§dYou found a §r§6§lSide Dish §r§6Egg §r§din the Chocolate Factory§r§d!" + CHOCOLATE_FACTORY_MILESTONE -> + "§d§lHOPPITY'S HUNT §r§dYou claimed a §r§6§lChocolate Milestone Rabbit §r§din the Chocolate Factory§r§d!" + CHOCOLATE_SHOP_MILESTONE -> + "§d§lHOPPITY'S HUNT §r§dYou claimed a §r§6§lShop Milestone Rabbit §r§din the Chocolate Factory§r§d!" + STRAY -> + "§d§lHOPPITY'S HUNT §r§dYou found a §r§aStray Rabbit§r§d!" + + // Each of these have their own from-Hypixel chats, so we don't need to add a message here + // as it will be handled in the attemptFireRabbitFound method, from the chat event. + in resettingEntries, HITMAN, BOUGHT -> null + else -> "§d§lHOPPITY'S HUNT §r§7Unknown Egg Type: §c§l${event.type}" + }?.let { hoppityDataSet.hoppityMessages.add(it) } + + attemptFireRabbitFound(event.chatEvent) + } + @SubscribeEvent(priority = EventPriority.HIGH) fun onChat(event: LorenzChatEvent) { if (!LorenzUtils.inSkyBlock) return HoppityEggsManager.eggFoundPattern.matchMatcher(event.message) { - resetRabbitData() - lastMeal = getEggType(event) + hoppityDataSet.reset() + val type = getEggType(event) val note = groupOrNull("note")?.removeColor() - lastMeal?.let { EggFoundEvent(it, note = note).post() } - attemptFireRabbitFound() + postApiEggFoundEvent(type, event, note) + } + + HoppityEggsManager.hitmanEggFoundPattern.matchMatcher(event.message) { + hoppityDataSet.reset() + postApiEggFoundEvent(HITMAN, event) } HoppityEggsManager.eggBoughtPattern.matchMatcher(event.message) { - if (group("rabbitname") == lastName) { - lastMeal = HoppityEggType.BOUGHT - EggFoundEvent(HoppityEggType.BOUGHT).post() - attemptFireRabbitFound() - } + if (group("rabbitname") != hoppityDataSet.lastName) return@matchMatcher + postApiEggFoundEvent(BOUGHT, event) } HoppityEggsManager.rabbitFoundPattern.matchMatcher(event.message) { - lastName = group("name") - lastNameCache = lastName - lastRarity = group("rarity") - attemptFireRabbitFound() + hoppityDataSet.lastName = group("name") + ChocolateFactoryBarnManager.processDataSet(hoppityDataSet) + hoppityDataSet.lastRarity = group("rarity") + attemptFireRabbitFound(event) } HoppityEggsManager.newRabbitFound.matchMatcher(event.message) { - newRabbit = true groupOrNull("other")?.let { - attemptFireRabbitFound() + hoppityDataSet.lastProfit = it + attemptFireRabbitFound(event) return } - attemptFireRabbitFound() + val chocolate = groupOrNull("chocolate") + val perSecond = group("perSecond") + hoppityDataSet.lastProfit = chocolate?.let { + "§6+$it §7and §6+${perSecond}x c/s!" + } ?: "§6+${perSecond}x c/s!" + attemptFireRabbitFound(event) } } - fun attemptFireRabbitFound(lastDuplicateAmount: Long? = null) { + fun attemptFireRabbitFound(event: LorenzChatEvent? = null, lastDuplicateAmount: Long? = null) { lastDuplicateAmount?.let { - this.lastDuplicateAmount = it - this.duplicate = true + hoppityDataSet.lastDuplicateAmount = it + hoppityDataSet.duplicate = true } - messageCount++ - val lastChatMeal = lastMeal ?: return - if (messageCount != 3) return - RabbitFoundEvent(lastChatMeal, duplicate, lastName, lastDuplicateAmount ?: 0).post() - resetRabbitData() + event?.let { hoppityDataSet.hoppityMessages.add(it.message) } + HoppityEggsCompactChat.compactChat(event, hoppityDataSet) + + // Theoretically impossible, but a failsafe. + if (hoppityDataSet.lastMeal == null) return + + if (hoppityDataSet.hoppityMessages.size != 3) return + RabbitFoundEvent(hoppityDataSet).post() + hoppityDataSet.reset() } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggDisplayManager.kt b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggDisplayManager.kt index fe908e58f62d..ce5bba6276cb 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggDisplayManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggDisplayManager.kt @@ -1,5 +1,6 @@ package at.hannibal2.skyhanni.features.event.hoppity +import at.hannibal2.skyhanni.config.features.event.hoppity.HoppityEggsConfig.UnclaimedEggsOrder.SOONEST_FIRST import at.hannibal2.skyhanni.data.mob.MobFilter.isRealPlayer import at.hannibal2.skyhanni.events.GuiRenderEvent import at.hannibal2.skyhanni.events.SecondPassedEvent @@ -75,18 +76,23 @@ object HoppityEggDisplayManager { if (!config.showClaimedEggs) return emptyList() if (ReminderUtils.isBusy() && !config.showWhileBusy) return emptyList() - val displayList = - HoppityEggType.resettingEntries.map { "§7 - ${it.formattedName} ${it.timeUntil().format()}" }.toMutableList() - displayList.add(0, "§bUnclaimed Eggs:") + val displayList: List = buildList { + add("§bUnclaimed Eggs:") + HoppityEggType.resettingEntries.let { entries -> + if (config.unclaimedEggsOrder == SOONEST_FIRST) entries.sortedBy { it.timeUntil() } + else entries + }.forEach { add("§7 - ${it.formattedName} ${it.timeUntil().format()}") } + + if (!config.showCollectedLocationCount || !LorenzUtils.inSkyBlock) return@buildList - if (config.showCollectedLocationCount && LorenzUtils.inSkyBlock) { val totalEggs = HoppityEggLocations.islandLocations.size if (totalEggs > 0) { val collectedEggs = HoppityEggLocations.islandCollectedLocations.size val collectedFormat = formatEggsCollected(collectedEggs) - displayList.add("§7Locations: $collectedFormat$collectedEggs§7/§a$totalEggs") + add("§7Locations: $collectedFormat$collectedEggs§7/§a$totalEggs") } } + if (displayList.size == 1) return emptyList() val container = Renderable.verticalContainer(displayList.map(Renderable::string)) diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggType.kt b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggType.kt index 7339f7d6e7f3..1cbbf4dceb98 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggType.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggType.kt @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.features.event.hoppity import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.features.event.hoppity.HoppityAPI.isAlternateDay import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.SimpleTimeMark.Companion.asTimeMark import at.hannibal2.skyhanni.utils.SkyBlockTime @@ -13,28 +14,34 @@ enum class HoppityEggType( val resetsAt: Int, var lastResetDay: Int = -1, private var claimed: Boolean = false, + private val altDay: Boolean = false ) { BREAKFAST("Breakfast", "§6", 7), LUNCH("Lunch", "§9", 14), DINNER("Dinner", "§a", 21), - BRUNCH("Brunch", "§6", -1), - DEJEUNER("Déjeuner", "§9", -1), - SUPPER("Supper", "§a", -1), + BRUNCH("Brunch", "§6", 7, altDay = true), + DEJEUNER("Déjeuner", "§9", 14, altDay = true), + SUPPER("Supper", "§a", 21, altDay = true), SIDE_DISH("Side Dish", "§6§l", -1), + HITMAN("Hitman", "§c", -1), BOUGHT("Bought", "§a", -1), - CHOCOLATE_SHOP_MILESTONE("Shop Milestone", "§6", -1), - CHOCOLATE_FACTORY_MILESTONE("Chocolate Milestone", "§6", -1), + CHOCOLATE_SHOP_MILESTONE("Shop Milestone", "§6§l", -1), + CHOCOLATE_FACTORY_MILESTONE("Chocolate Milestone", "§6§l", -1), STRAY("Stray Rabbit", "§a", -1) ; fun timeUntil(): Duration { if (resetsAt == -1) return Duration.INFINITE val now = SkyBlockTime.now() - if (now.hour >= resetsAt) { - return now.copy(day = now.day + 1, hour = resetsAt, minute = 0, second = 0) - .asTimeMark().timeUntil() + val isEggDayToday = altDay == now.isAlternateDay() + + val daysToAdd = when { + isEggDayToday && now.hour < resetsAt -> 0 + isEggDayToday && now.hour >= resetsAt -> 2 + else -> 1 } - return now.copy(hour = resetsAt, minute = 0, second = 0).asTimeMark().timeUntil() + + return now.copy(day = now.day + daysToAdd, hour = resetsAt, minute = 0, second = 0).asTimeMark().timeUntil() } fun markClaimed() { @@ -69,8 +76,9 @@ enum class HoppityEggType( val currentSbTime = SkyBlockTime.now() val currentSbDay = currentSbTime.day val currentSbHour = currentSbTime.hour + val isAltDay = currentSbTime.isAlternateDay() - for (eggType in resettingEntries) { + for (eggType in resettingEntries.filter { it.altDay == isAltDay }) { if (currentSbHour < eggType.resetsAt || eggType.lastResetDay == currentSbDay) continue eggType.markSpawned() eggType.lastResetDay = currentSbDay diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsCompactChat.kt b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsCompactChat.kt index 930be4ac55e3..556fc71b3fe5 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsCompactChat.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsCompactChat.kt @@ -1,28 +1,17 @@ package at.hannibal2.skyhanni.features.event.hoppity import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.api.event.HandleEvent import at.hannibal2.skyhanni.config.features.event.hoppity.HoppityEggsConfig import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.events.hoppity.EggFoundEvent -import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggType.BOUGHT -import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggType.CHOCOLATE_FACTORY_MILESTONE -import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggType.CHOCOLATE_SHOP_MILESTONE -import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggType.Companion.getEggType -import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggType.SIDE_DISH -import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggType.STRAY -import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggsManager.eggFoundPattern +import at.hannibal2.skyhanni.features.event.hoppity.HoppityAPI.HoppityStateDataSet +import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggType.Companion.resettingEntries import at.hannibal2.skyhanni.features.inventory.chocolatefactory.ChocolateFactoryAPI import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule import at.hannibal2.skyhanni.utils.ChatUtils import at.hannibal2.skyhanni.utils.DelayedRun -import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.NumberUtil.shortFormat -import at.hannibal2.skyhanni.utils.RegexUtils.groupOrNull -import at.hannibal2.skyhanni.utils.RegexUtils.matchMatcher import at.hannibal2.skyhanni.utils.SimpleTimeMark.Companion.fromNow import at.hannibal2.skyhanni.utils.TimeUtils.format -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.seconds @@ -31,88 +20,62 @@ typealias RarityType = HoppityEggsConfig.CompactRarityTypes @SkyHanniModule object HoppityEggsCompactChat { - private var hoppityEggChat = mutableListOf() - private var duplicate = false - private var lastRarity = "" - private var lastName = "" - private var lastProfit = "" - private var newRabbit = false - private var lastChatMeal: HoppityEggType? = null - private var lastDuplicateAmount: Long? = null + private var hoppityDataSet = HoppityStateDataSet() private val config get() = ChocolateFactoryAPI.config private val eventConfig get() = SkyHanniMod.feature.event.hoppityEggs + private val rarityConfig get() = HoppityEggsManager.config.rarityInCompact - fun compactChat(event: LorenzChatEvent? = null, lastDuplicateAmount: Long? = null) { + fun compactChat(event: LorenzChatEvent?, dataSet: HoppityStateDataSet) { if (!HoppityEggsManager.config.compactChat) return - lastDuplicateAmount?.let { - this.lastDuplicateAmount = it - this.duplicate = true - } - event?.let { - it.blockedReason = "compact_hoppity" - hoppityEggChat.add(it.message) - } - if (hoppityEggChat.size == 3) sendCompact() + hoppityDataSet = dataSet.copy() + event?.let { it.blockedReason = "compact_hoppity" } + if (hoppityDataSet.hoppityMessages.size == 3) sendCompact() } private fun sendCompact() { - if (lastChatMeal.let { HoppityEggType.resettingEntries.contains(it) } && eventConfig.sharedWaypoints) { + if (hoppityDataSet.lastMeal.let { HoppityEggType.resettingEntries.contains(it) } && eventConfig.sharedWaypoints) { DelayedRun.runDelayed(5.milliseconds) { - clickableCompact(HoppityEggsManager.getAndDisposeWaypointOnclick()) - resetCompactData() + createWaypointShareCompactMessage(HoppityEggsManager.getAndDisposeWaypointOnclick()) + hoppityDataSet.reset() } } else { - ChatUtils.hoverableChat(createCompactMessage(), hover = hoppityEggChat, prefix = false) - resetCompactData() + ChatUtils.hoverableChat(createCompactMessage(), hover = hoppityDataSet.hoppityMessages, prefix = false) + hoppityDataSet.reset() } } - private fun resetCompactData() { - this.hoppityEggChat = mutableListOf() - this.duplicate = false - this.newRabbit = false - this.lastRarity = "" - this.lastName = "" - this.lastProfit = "" - this.lastChatMeal = null - this.lastDuplicateAmount = null - } - private fun createCompactMessage(): String { - val mealNameFormat = when (lastChatMeal) { - BOUGHT -> "§aBought Rabbit" - SIDE_DISH -> "§6§lSide Dish §r§6Egg" - CHOCOLATE_SHOP_MILESTONE, CHOCOLATE_FACTORY_MILESTONE -> "§6§lMilestone Rabbit" - STRAY -> "§aStray Rabbit" - else -> "${lastChatMeal?.coloredName.orEmpty()} Egg" + val mealNameFormat = when (hoppityDataSet.lastMeal) { + in resettingEntries -> "${hoppityDataSet.lastMeal?.coloredName.orEmpty()} Egg" + else -> "${hoppityDataSet.lastMeal?.coloredName.orEmpty()} Rabbit" } - val rarityConfig = HoppityEggsManager.config.rarityInCompact - return if (duplicate) { - val format = lastDuplicateAmount?.shortFormat() ?: "?" - val timeFormatted = lastDuplicateAmount?.let { + return if (hoppityDataSet.duplicate) { + val format = hoppityDataSet.lastDuplicateAmount?.shortFormat() ?: "?" + val timeFormatted = hoppityDataSet.lastDuplicateAmount?.let { ChocolateFactoryAPI.timeUntilNeed(it).format(maxUnits = 2) } ?: "?" val dupeNumberFormat = if (eventConfig.showDuplicateNumber) { - (HoppityCollectionStats.getRabbitCount(this.lastName)).takeIf { it > 0 }?.let { + (HoppityCollectionStats.getRabbitCount(hoppityDataSet.lastName)).takeIf { it > 0 }?.let { " §7(§b#$it§7)" }.orEmpty() } else "" val showDupeRarity = rarityConfig.let { it == RarityType.BOTH || it == RarityType.DUPE } val timeStr = if (config.showDuplicateTime) ", §a+§b$timeFormatted§7" else "" - "$mealNameFormat! §7Duplicate ${if (showDupeRarity) "$lastRarity " else ""}" + - "$lastName$dupeNumberFormat §7(§6+$format Chocolate§7$timeStr)" - } else if (newRabbit) { + "$mealNameFormat! §7Duplicate ${if (showDupeRarity) "${hoppityDataSet.lastRarity} " else ""}" + + "${hoppityDataSet.lastName}$dupeNumberFormat §7(§6+$format Chocolate§7$timeStr)" + } else { val showNewRarity = rarityConfig.let { it == RarityType.BOTH || it == RarityType.NEW } - "$mealNameFormat! §d§lNEW ${if (showNewRarity) "$lastRarity " else ""}$lastName §7($lastProfit§7)" - } else "?" + "$mealNameFormat! §d§lNEW ${if (showNewRarity) "${hoppityDataSet.lastRarity} " else ""}" + + "${hoppityDataSet.lastName} §7(${hoppityDataSet.lastProfit}§7)" + } } - private fun clickableCompact(onClick: () -> Unit) { - val hover = hoppityEggChat.joinToString("\n") + " \n§eClick here to share the location of this chocolate egg with the server!" - hoppityEggChat.clear() + private fun createWaypointShareCompactMessage(onClick: () -> Unit) { + val hover = hoppityDataSet.hoppityMessages.joinToString("\n") + + " \n§eClick here to share the location of this chocolate egg with the server!" ChatUtils.clickableChat( createCompactMessage(), hover = hover, @@ -122,67 +85,4 @@ object HoppityEggsCompactChat { prefix = false, ) } - - @HandleEvent - fun onEggFound(event: EggFoundEvent) { - if (!HoppityEggsManager.config.compactChat || HoppityEggType.resettingEntries.contains(event.type) || event.type == BOUGHT) return - lastChatMeal = event.type - hoppityEggChat.add( - when (event.type) { - SIDE_DISH -> - "§d§lHOPPITY'S HUNT §r§dYou found a §r§6§lSide Dish §r§6Egg §r§din the Chocolate Factory§r§d!" - - CHOCOLATE_FACTORY_MILESTONE -> - "§d§lHOPPITY'S HUNT §r§dYou claimed a §r§6§lChocolate Milestone Rabbit §r§din the Chocolate Factory§r§d!" - - CHOCOLATE_SHOP_MILESTONE -> - "§d§lHOPPITY'S HUNT §r§dYou claimed a §r§6§lShop Milestone Rabbit §r§din the Chocolate Factory§r§d!" - - STRAY -> - "§d§lHOPPITY'S HUNT §r§dYou found a §r§aStray Rabbit§r§d!" - - else -> - "§d§lHOPPITY'S HUNT §r§7Unknown Egg Type?" - }, - ) - if (hoppityEggChat.size == 3) sendCompact() - } - - @SubscribeEvent - fun onChat(event: LorenzChatEvent) { - if (!LorenzUtils.inSkyBlock) return - eggFoundPattern.matchMatcher(event.message) { - resetCompactData() - lastChatMeal = getEggType(event) - compactChat(event) - } - - HoppityEggsManager.eggBoughtPattern.matchMatcher(event.message) { - if (group("rabbitname") == lastName) { - lastChatMeal = BOUGHT - compactChat(event) - } - } - - HoppityEggsManager.rabbitFoundPattern.matchMatcher(event.message) { - lastName = group("name") - lastRarity = group("rarity") - compactChat(event) - } - - HoppityEggsManager.newRabbitFound.matchMatcher(event.message) { - newRabbit = true - groupOrNull("other")?.let { - lastProfit = it - compactChat(event) - return - } - val chocolate = groupOrNull("chocolate") - val perSecond = group("perSecond") - lastProfit = chocolate?.let { - "§6+$it §7and §6+${perSecond}x c/s!" - } ?: "§6+${perSecond}x c/s!" - compactChat(event) - } - } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsManager.kt b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsManager.kt index 37a2dfb3b066..7a2cd2d8cf53 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityEggsManager.kt @@ -38,20 +38,30 @@ object HoppityEggsManager { * REGEX-TEST: §d§lHOPPITY'S HUNT §r§dYou found a §r§9Chocolate Lunch Egg §r§don a ledge next to the stairs up§r§d! * REGEX-TEST: §d§lHOPPITY'S HUNT §r§dYou found a §r§aChocolate Dinner Egg §r§dbehind Emissary Sisko§r§d! * REGEX-TEST: §d§lHOPPITY'S HUNT §r§dYou found a §r§9Chocolate Lunch Egg §r§dnear the Diamond Essence Shop§r§d! - * REGEX-TEST: §d§lHOPPITY'S HUNT §r§dYou found a §r§9Chocolate Déjeuner Egg §r§dwithin the wither cage§r§d! + * REGEX-TEST: §d§lHOPPITY'S HUNT §r§dYou found a §r§6Chocolate Brunch Egg §r§don a lower platform§r§d! + * REGEX-TEST: §d§lHOPPITY'S HUNT §r§dYou found a §r§9Chocolate Déjeuner Egg §r§don the arms of the Amethyst statue§r§d! + * REGEX-TEST: §d§lHOPPITY'S HUNT §r§dYou found a §r§aChocolate Supper Egg §r§dunderneath the stairwell§r§d! */ val eggFoundPattern by ChocolateFactoryAPI.patternGroup.pattern( "egg.found", "§d§lHOPPITY'S HUNT §r§dYou found a §r§.Chocolate (?[\\wé]+) Egg §r§d(?.*)§r§d!", ) + /** + * REGEX-TEST: §d§lHOPPITY'S HUNT §r§dYou found a §r§cHitman Egg§r§d! + */ + val hitmanEggFoundPattern by ChocolateFactoryAPI.patternGroup.pattern( + "egg.found.hitman", + "§d§lHOPPITY'S HUNT §r§dYou found a (?:§.)+Hitman Egg(?:§.)+!", + ) + /** * REGEX-TEST: §aYou bought §r§9Casanova §r§afor §r§6970,000 Coins§r§a! * REGEX-TEST: §aYou bought §r§fHeidie §r§afor §r§6194,000 Coins§r§a! */ val eggBoughtPattern by ChocolateFactoryAPI.patternGroup.pattern( "egg.bought", - "§aYou bought §r(?.*?) §r§afor §r§6[\\d|,]+ Coins§r§a!", + "§aYou bought §r(?.*?) §r§afor §r§6(?[\\d,]*) Coins§r§a!", ) /** diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityRabbitTheFishChecker.kt b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityRabbitTheFishChecker.kt index 93e34d20459f..b6ba397ec68e 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityRabbitTheFishChecker.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/HoppityRabbitTheFishChecker.kt @@ -25,6 +25,9 @@ object HoppityRabbitTheFishChecker { * REGEX-TEST: Chocolate Breakfast Egg * REGEX-TEST: Chocolate Lunch Egg * REGEX-TEST: Chocolate Dinner Egg + * REGEX-TEST: Chocolate Brunch Egg + * REGEX-TEST: Chocolate Déjeuner Egg + * REGEX-TEST: Chocolate Supper Egg */ val mealEggInventoryPattern by ChocolateFactoryAPI.patternGroup.pattern( "inventory.mealegg.name", diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/WarpMenuUniques.kt b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/WarpMenuUniques.kt index dfd22de9a88f..8dd7e7f7ea93 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/WarpMenuUniques.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/event/hoppity/WarpMenuUniques.kt @@ -45,7 +45,6 @@ object WarpMenuUniques { "The Barn" -> IslandType.THE_FARMING_ISLANDS else -> IslandType.getByNameOrNull(name) ?: return } - if (island == IslandType.DUNGEON_HUB) return if (HoppityEggLocations.apiEggLocations[island]?.size == null) return val maxEggs = 15 diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/chocolatefactory/ChocolateFactoryAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/chocolatefactory/ChocolateFactoryAPI.kt index dbcc919c2f7e..a9437533f1ec 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/chocolatefactory/ChocolateFactoryAPI.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/chocolatefactory/ChocolateFactoryAPI.kt @@ -82,18 +82,19 @@ object ChocolateFactoryAPI { var barnIndex = 34 var infoIndex = 13 var productionInfoIndex = 45 - var prestigeIndex = 28 + var prestigeIndex = 27 var milestoneIndex = 53 - var leaderboardIndex = 51 + var leaderboardIndex = 52 var handCookieIndex = 38 var timeTowerIndex = 39 var shrineIndex = 41 var coachRabbitIndex = 42 - var maxRabbits = 395 + var rabbitHitmanIndex = 51 + var maxRabbits = 503 private var chocolateMilestones = TreeSet() private var chocolateFactoryMilestones: MutableList = mutableListOf() private var chocolateShopMilestones: MutableList = mutableListOf() - private var maxPrestige = 5 + private var maxPrestige = 6 var inChocolateFactory = false var chocolateFactoryPaused = false @@ -152,6 +153,7 @@ object ChocolateFactoryAPI { timeTowerIndex = data.timeTowerIndex shrineIndex = data.shrineIndex coachRabbitIndex = data.coachRabbitIndex + rabbitHitmanIndex = data.rabbitHitmanIndex maxRabbits = data.maxRabbits maxPrestige = data.maxPrestige chocolateMilestones = data.chocolateMilestones diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/chocolatefactory/ChocolateFactoryBarnManager.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/chocolatefactory/ChocolateFactoryBarnManager.kt index 8ce0047d0aec..9bd5a97982a3 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/chocolatefactory/ChocolateFactoryBarnManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/chocolatefactory/ChocolateFactoryBarnManager.kt @@ -5,7 +5,6 @@ import at.hannibal2.skyhanni.events.LorenzChatEvent import at.hannibal2.skyhanni.features.event.hoppity.HoppityAPI import at.hannibal2.skyhanni.features.event.hoppity.HoppityCollectionData import at.hannibal2.skyhanni.features.event.hoppity.HoppityCollectionStats -import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggsCompactChat import at.hannibal2.skyhanni.features.event.hoppity.HoppityEggsManager import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule import at.hannibal2.skyhanni.utils.ChatUtils @@ -36,6 +35,11 @@ object ChocolateFactoryBarnManager { var barnFull = false private var sentBarnFullWarning = false + private var lastRabbit = "" + + fun processDataSet(dataSet: HoppityAPI.HoppityStateDataSet) { + lastRabbit = dataSet.lastName + } @SubscribeEvent fun onChat(event: LorenzChatEvent) { @@ -58,11 +62,10 @@ object ChocolateFactoryBarnManager { } } ChocolateAmount.addToAll(amount) - HoppityEggsCompactChat.compactChat(event, lastDuplicateAmount = amount) - HoppityAPI.attemptFireRabbitFound(lastDuplicateAmount = amount) + HoppityAPI.attemptFireRabbitFound(event, lastDuplicateAmount = amount) if (hoppityConfig.showDuplicateNumber && !hoppityConfig.compactChat) { - (HoppityCollectionStats.getRabbitCount(HoppityAPI.getLastRabbit())).takeIf { it > 0 }?.let { + (HoppityCollectionStats.getRabbitCount(lastRabbit)).takeIf { it > 0 }?.let { event.chatComponent = ChatComponentText( event.message.replace("§7§lDUPLICATE RABBIT!", "§7§lDUPLICATE RABBIT! §7(Duplicate §b#$it§7)§r"), ) diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/chocolatefactory/ChocolateFactoryInventory.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/chocolatefactory/ChocolateFactoryInventory.kt index 8997572b5bcc..337a62cc5cb3 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/chocolatefactory/ChocolateFactoryInventory.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/chocolatefactory/ChocolateFactoryInventory.kt @@ -5,6 +5,7 @@ import at.hannibal2.skyhanni.events.RenderInventoryItemTipEvent import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule import at.hannibal2.skyhanni.utils.InventoryUtils import at.hannibal2.skyhanni.utils.ItemUtils.getLore +import at.hannibal2.skyhanni.utils.KeyboardManager import at.hannibal2.skyhanni.utils.LorenzColor import at.hannibal2.skyhanni.utils.RegexUtils.firstMatcher import at.hannibal2.skyhanni.utils.RenderUtils.drawSlotText @@ -104,6 +105,9 @@ object ChocolateFactoryInventory { // this would break ChocolateFactoryKeybinds otherwise if (event.clickTypeEnum == GuiContainerEvent.ClickType.HOTBAR) return + // if the user is holding shift, we don't want to pickblock, handled by hypixel as +10 levels for rabbits + if (KeyboardManager.isShiftKeyDown() && slotNumber in ChocolateFactoryAPI.rabbitSlots.keys) return + event.makePickblock() } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/inventory/chocolatefactory/ChocolateFactoryStats.kt b/src/main/java/at/hannibal2/skyhanni/features/inventory/chocolatefactory/ChocolateFactoryStats.kt index 8c9acc5a13bb..feffabaf5ea2 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/inventory/chocolatefactory/ChocolateFactoryStats.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/inventory/chocolatefactory/ChocolateFactoryStats.kt @@ -112,7 +112,6 @@ object ChocolateFactoryStats { "§eHappens at: §b${timeTowerFull.formattedDate("EEEE, MMM d h:mm a")}" }, ) - put(ChocolateFactoryStat.TIME_TO_PRESTIGE, "§eTime To Prestige: $prestigeEstimate") put( ChocolateFactoryStat.RAW_PER_SECOND, "§eRaw Per Second: §6${profileStorage.rawChocPerSecond.addSeparators()}", diff --git a/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockTime.kt b/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockTime.kt index f4bc38a604b1..1c9f4316a653 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockTime.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/SkyBlockTime.kt @@ -46,7 +46,7 @@ data class SkyBlockTime( Instant.ofEpochMilli( SKYBLOCK_EPOCH_START_MILLIS + (SKYBLOCK_YEAR_MILLIS * year) + - (SKYBLOCK_MONTH_MILLIS * month) + (SKYBLOCK_MONTH_MILLIS * (month - 1)) ) )