diff options
author | hannibal2 <24389977+hannibal00212@users.noreply.github.com> | 2023-03-19 13:57:16 +0100 |
---|---|---|
committer | hannibal2 <24389977+hannibal00212@users.noreply.github.com> | 2023-03-19 13:57:16 +0100 |
commit | 25b6fe99c4d03c565bc8cb024c4b6e232203614d (patch) | |
tree | 148651d131c41acb5685638a82048d9d0a2bf8d4 | |
parent | fef46f5b4b6f6ade36dd56ebb39c199402f521b6 (diff) | |
download | skyhanni-25b6fe99c4d03c565bc8cb024c4b6e232203614d.tar.gz skyhanni-25b6fe99c4d03c565bc8cb024c4b6e232203614d.tar.bz2 skyhanni-25b6fe99c4d03c565bc8cb024c4b6e232203614d.zip |
Added farming contest timer
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | FEATURES.md | 1 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java | 1 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/config/Features.java | 5 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/config/features/Garden.java | 17 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt | 187 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt | 9 |
7 files changed, 221 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 67ed61cdf..8ca9e8d68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ + Added **Optimal Speed** - Show the optimal speed for your current tool in the hand. (Ty MelonKingDE for the values) + Added **Warn When Close** - Warn with title and sound when the next crop milestone upgrade happens in 5 seconds. Useful for switching to a different pet for leveling. + Added **Money per Hour** - Displays the money per hour YOU get with YOUR crop/minute value when selling the items to bazaar. ++ Added farming contest timer. ### Features from other Mods diff --git a/FEATURES.md b/FEATURES.md index f5c0a42b0..99e015246 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -184,6 +184,7 @@ + **Dicer Counter** - Count RNG drops for Melon Dicer and Pumpkin Dicer. + **Warn When Close** - Warn with title and sound when the next crop milestone upgrade happens in 5 seconds. Useful for switching to a different pet for leveling. + **Money per Hour** - Displays the money per hour YOU get with YOUR crop/minute value when selling the items to bazaar. ++ Farming contest timer. ## Commands - /wiki (using hypixel-skyblock.fandom.com instead of Hypixel wiki) diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java index d5f9a3929..d61c57812 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java @@ -222,6 +222,7 @@ public class SkyHanniMod { loadModule(new DicerRngDropCounter()); loadModule(new CropMoneyDisplay()); loadModule(new JacobFarmingContestsInventory()); + loadModule(new GardenNextJacobContest()); Commands.INSTANCE.init(); diff --git a/src/main/java/at/hannibal2/skyhanni/config/Features.java b/src/main/java/at/hannibal2/skyhanni/config/Features.java index e087b790c..8110b1003 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/Features.java +++ b/src/main/java/at/hannibal2/skyhanni/config/Features.java @@ -223,6 +223,11 @@ public class Features extends Config { editOverlay(activeConfigCategory, 200, 16, garden.moneyPerHourPos); return; } + + if (runnableId.equals("nextJacobContest")) { + editOverlay(activeConfigCategory, 200, 16, garden.nextJacobContestPos); + return; + } } @Expose diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java b/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java index 423705358..34c24dbb2 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java @@ -401,6 +401,23 @@ public class Garden { public Position moneyPerHourPos = new Position(16, -232, false, true); @Expose + @ConfigOption(name = "Next Jacob Contest", desc = "") + @ConfigEditorAccordion(id = 12) + public boolean nextJacobContest = false; + + @Expose + @ConfigOption(name = "Rng Drop Counter", desc = "Count RNG drops for Melon Dicer and Pumpkin Dicer.") + @ConfigEditorBoolean + @ConfigAccordionId(id = 12) + public boolean nextJacobContestDisplay = true; + + @Expose + @ConfigOption(name = "Dicer Counter Position", desc = "") + @ConfigEditorButton(runnableId = "nextJacobContest", buttonText = "Edit") + @ConfigAccordionId(id = 12) + public Position nextJacobContestPos = new Position(16, -232, false, true); + + @Expose @ConfigOption(name = "Plot Price", desc = "Show the price of the plot in coins when inside the Configure Plots inventory.") @ConfigEditorBoolean public boolean plotPrice = true; diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt new file mode 100644 index 000000000..193efecc6 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt @@ -0,0 +1,187 @@ +package at.hannibal2.skyhanni.features.garden + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.GuiRenderEvent +import at.hannibal2.skyhanni.events.InventoryCloseEvent +import at.hannibal2.skyhanni.events.InventoryOpenEvent +import at.hannibal2.skyhanni.utils.ItemUtils.getLore +import at.hannibal2.skyhanni.utils.ItemUtils.name +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.RenderUtils.renderSingleLineWithItems +import at.hannibal2.skyhanni.utils.TimeUtils +import io.github.moulberry.notenoughupdates.util.SkyBlockTime +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent +import java.time.Instant +import java.util.regex.Pattern + +class GardenNextJacobContest { + private val config get() = SkyHanniMod.feature.garden + private val display = mutableListOf<Any>() + private var tick = 0 + private var contests = mutableMapOf<Long, FarmingContest>() + private var inCalendar = false + + private val maxContestsPerYear = 124 + private val contestDuration = 1_000 * 60 * 20 + + @SubscribeEvent + fun onTick(event: TickEvent.ClientTickEvent) { + if (!isEnabled()) return + if (tick++ % (40) != 0) return + + if (inCalendar) return + update() + } + + @SubscribeEvent + fun onInventoryClose(event: InventoryCloseEvent) { + if (inCalendar) { + inCalendar = false + update() + } + } + + @SubscribeEvent + fun onInventoryOpen(event: InventoryOpenEvent) { + if (!config.nextJacobContestDisplay) return + + val backItem = event.inventoryItems[48] ?: return + val backName = backItem.name + if (backName != "§aGo Back") return + val lore = backItem.getLore() + if (lore.size != 1) return + if (lore[0] != "§7To Calendar and Events") return + + inCalendar = true + readCalendar(event) + } + + private fun readCalendar(event: InventoryOpenEvent) { + val inventoryName = event.inventoryName + + val patternMonth = Pattern.compile("(.*), Year (.*)") + val matcher = patternMonth.matcher(inventoryName) + if (!matcher.matches()) return + val rawMonth = matcher.group(1) + val year = matcher.group(2).toInt() + + if (contests.isNotEmpty()) { + val contest = contests.values.first() + val endTime = contest.endTime + val lastYear = SkyBlockTime.fromInstant(Instant.ofEpochMilli(endTime)).year + if (year != lastYear) { + contests.clear() + LorenzUtils.chat("§e[SkyHanni] New year detected, open all calendar months again!") + } + } + + + val month = LorenzUtils.getSBMonthByName(rawMonth) + + val patternDay = Pattern.compile("§aDay (.*)") + val patternCrop = Pattern.compile("§e○ §7(.*)") + for (item in event.inventoryItems.values) { + val lore = item.getLore() + if (!lore.any { it.contains("§6§eJacob's Farming Contest") }) continue + + val name = item.name ?: continue + val matcherDay = patternDay.matcher(name) + if (!matcherDay.matches()) continue + + val day = matcherDay.group(1).toInt() + + val sbTime = SkyBlockTime(year, month, day) + val startTime = sbTime.toMillis() + val crops = mutableListOf<String>() + for (line in lore) { + val matcherCrop = patternCrop.matcher(line) + if (!matcherCrop.matches()) continue + + val crop = matcherCrop.group(1) + crops.add(crop) + } + val contest = FarmingContest(startTime + contestDuration, crops) + contests[startTime] = contest + } + + update() + } + + class FarmingContest(val endTime: Long, val crops: List<String>) + + private fun update() { + val newDisplay = drawDisplay() + display.clear() + display.addAll(newDisplay) + } + + private fun drawDisplay(): List<Any> { + val list = mutableListOf<Any>() + + if (inCalendar) { + val size = contests.size + val percentage = size.toDouble() / maxContestsPerYear + val formatted = LorenzUtils.formatPercentage(percentage) + list.add("§eDetected $formatted of farming contests this year") + + return list + } + + if (contests.isEmpty()) { + list.add("§cOpen calendar to read jacob contest times!") + return list + } + + val nextContest = + contests.filter { it.value.endTime > System.currentTimeMillis() }.toSortedMap().firstNotNullOfOrNull { it.value } + if (nextContest == null) { + if (contests.size == maxContestsPerYear) { + list.add("§cNew SkyBlock Year! Open calendar again!") + } else { + list.add("§cOpen calendar to read jacob contest times!") + } + return list + } + + return drawNextContest(nextContest, list) + } + + private fun drawNextContest( + nextContest: FarmingContest, + list: MutableList<Any>, + ): MutableList<Any> { + for (crop in nextContest.crops) { + GardenAPI.addGardenCropToList(crop, list) + list.add(" ") + } + var duration = nextContest.endTime - System.currentTimeMillis() + if (duration < contestDuration) { + list.add("§aActive ") + } else { + list.add("§eNext ") + duration -= contestDuration + } + val format = TimeUtils.formatDuration(duration) + list.add("§b$format ") + + return list + } + + @SubscribeEvent + fun onRenderOverlay(event: GuiRenderEvent.GameOverlayRenderEvent) { + if (!isEnabled()) return + + config.nextJacobContestPos.renderSingleLineWithItems(display) + } + + @SubscribeEvent + fun onRenderOverlay(event: GuiRenderEvent.ChestBackgroundRenderEvent) { + if (!config.nextJacobContestDisplay) return + if (!inCalendar) return + + config.nextJacobContestPos.renderSingleLineWithItems(display) + } + + private fun isEnabled() = GardenAPI.inGarden() && config.nextJacobContestDisplay +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt index 62a8c2c61..e5c06a6a8 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt @@ -492,6 +492,15 @@ object RenderUtils { } } + /** + * Accepts a single line to print. + * This line is a list of things to print. Can print String or ItemStack objects. + */ + fun Position.renderSingleLineWithItems(list: List<Any?>) { + if (list.isEmpty()) return + renderLine(list, 0) + } + private fun Position.renderLine(line: List<Any?>, offsetY: Int) { val renderer = Minecraft.getMinecraft().fontRendererObj val resolution = ScaledResolution(Minecraft.getMinecraft()) |