aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhannibal2 <24389977+hannibal00212@users.noreply.github.com>2023-03-19 13:57:16 +0100
committerhannibal2 <24389977+hannibal00212@users.noreply.github.com>2023-03-19 13:57:16 +0100
commit25b6fe99c4d03c565bc8cb024c4b6e232203614d (patch)
tree148651d131c41acb5685638a82048d9d0a2bf8d4
parentfef46f5b4b6f6ade36dd56ebb39c199402f521b6 (diff)
downloadskyhanni-25b6fe99c4d03c565bc8cb024c4b6e232203614d.tar.gz
skyhanni-25b6fe99c4d03c565bc8cb024c4b6e232203614d.tar.bz2
skyhanni-25b6fe99c4d03c565bc8cb024c4b6e232203614d.zip
Added farming contest timer
-rw-r--r--CHANGELOG.md1
-rw-r--r--FEATURES.md1
-rw-r--r--src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java1
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/Features.java5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/Garden.java17
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenNextJacobContest.kt187
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt9
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())