aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman / Linnea Gräf <nea@nea.moe>2023-03-31 21:32:42 +0200
committerGitHub <noreply@github.com>2023-03-31 21:32:42 +0200
commit53c1440fa4a42613b140f4f099b60c3664ba0fdd (patch)
tree0341c3b48d533fdc3f2efa9e172cd4f6c37eeb14
parente6bcc8f902e410c348ff720ab73de14e5cf04280 (diff)
downloadskyhanni-53c1440fa4a42613b140f4f099b60c3664ba0fdd.tar.gz
skyhanni-53c1440fa4a42613b140f4f099b60c3664ba0fdd.tar.bz2
skyhanni-53c1440fa4a42613b140f4f099b60c3664ba0fdd.zip
Add rancher boot overlay for optimal crop speeds (#25)
Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com>
-rw-r--r--CHANGELOG.md1
-rw-r--r--FEATURES.md1
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/Garden.java9
-rw-r--r--src/main/java/at/hannibal2/skyhanni/data/GuiEditManager.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt28
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt39
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt29
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt101
9 files changed, 180 insertions, 39 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2e034c470..bc66c1f29 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -37,6 +37,7 @@
+ Added farming weight next leaderboard position eta.
+ Added **Dicer Counter** - Count RNG drops for Melon Dicer and Pumpkin Dicer.
+ Added **Optimal Speed** - Show the optimal speed for your current tool in the hand. (Ty MelonKingDE for the values)
+ + Also available to select directly in the rancher boots overlay (contributed by nea)
+ 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.
diff --git a/FEATURES.md b/FEATURES.md
index 54098e876..1e393809d 100644
--- a/FEATURES.md
+++ b/FEATURES.md
@@ -180,6 +180,7 @@
+ **Amount and Time** - Show the exact item amount and the remaining time when farmed manually. Especially useful for ironman.
+ **Custom Keybinds** - Use custom keybinds while having a farming tool or Daedalus Axe in the hand in the garden.
+ **Optimal Speed** - Show the optimal speed for your current tool in the hand. (Ty MelonKingDE for the values)
+ + Also available to select directly in the rancher boots overlay (contributed by nea)
+ Desk shortcut in SkyBlock Menu.
+ **Garden Level Display** - Show the current garden level and progress to the next level.
+ **Farming Weight and Leaderboard**, provided by the elite skyblock farmers.
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 f6879a86d..2414d4c35 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java
@@ -396,6 +396,15 @@ public class Garden {
public boolean optimalSpeedWarning = false;
@Expose
+ @ConfigOption(name = "Rancher Boots", desc = "Allows you to set the optimal speed in the rancher boots overlay by clicking on the presets.")
+ @ConfigEditorBoolean
+ @ConfigAccordionId(id = 9)
+ public boolean optimalSpeedSignEnabled = true;
+
+ @Expose
+ public Position optimalSpeedSignPosition = new Position(200, 20, false, true);
+
+ @Expose
@ConfigOption(name = "Custom Speed", desc = "Change the exact speed for every single crop.")
@Accordion
@ConfigAccordionId(id = 9)
diff --git a/src/main/java/at/hannibal2/skyhanni/data/GuiEditManager.kt b/src/main/java/at/hannibal2/skyhanni/data/GuiEditManager.kt
index 0b761f442..7beaff605 100644
--- a/src/main/java/at/hannibal2/skyhanni/data/GuiEditManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/data/GuiEditManager.kt
@@ -8,6 +8,7 @@ import at.hannibal2.skyhanni.utils.LorenzUtils
import io.github.moulberry.notenoughupdates.NEUOverlay
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.inventory.GuiChest
+import net.minecraft.client.gui.inventory.GuiEditSign
import net.minecraft.client.gui.inventory.GuiInventory
import net.minecraft.client.renderer.GlStateManager
import net.minecraftforge.fml.common.eventhandler.EventPriority
@@ -24,7 +25,7 @@ class GuiEditManager {
if (!LorenzUtils.inSkyBlock) return
Minecraft.getMinecraft().currentScreen?.let {
- if (it !is GuiInventory && it !is GuiChest) return
+ if (it !is GuiInventory && it !is GuiChest && it !is GuiEditSign) return
}
if (!Keyboard.getEventKeyState()) return
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt
index 5de01ffaa..1d71c8553 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt
@@ -1,18 +1,24 @@
package at.hannibal2.skyhanni.features.garden
-enum class CropType(val cropName: String, val toolName: String) {
- WHEAT("Wheat", "THEORETICAL_HOE_WHEAT"),
- CARROT("Carrot", "THEORETICAL_HOE_CARROT"),
- POTATO("Potato", "THEORETICAL_HOE_POTATO"),
- NETHER_WART("Nether Wart", "THEORETICAL_HOE_WARTS"),
- PUMPKIN("Pumpkin", "PUMPKIN_DICER"),
- MELON("Melon", "MELON_DICER"),
- COCOA_BEANS("Cocoa Beans", "COCO_CHOPPER"),
- SUGAR_CANE("Sugar Cane", "THEORETICAL_HOE_CANE"),
- CACTUS("Cactus", "CACTUS_KNIFE"),
- MUSHROOM("Mushroom", "FUNGI_CUTTER"),
+import net.minecraft.init.Blocks
+import net.minecraft.init.Items
+import net.minecraft.item.EnumDyeColor
+import net.minecraft.item.ItemStack
+
+enum class CropType(val cropName: String, val toolName: String, iconSupplier: () -> ItemStack) {
+ WHEAT("Wheat", "THEORETICAL_HOE_WHEAT", { ItemStack(Items.wheat) }),
+ CARROT("Carrot", "THEORETICAL_HOE_CARROT", { ItemStack(Items.carrot) }),
+ POTATO("Potato", "THEORETICAL_HOE_POTATO", { ItemStack(Items.potato) }),
+ NETHER_WART("Nether Wart", "THEORETICAL_HOE_WARTS", { ItemStack(Items.nether_wart) }),
+ PUMPKIN("Pumpkin", "PUMPKIN_DICER", { ItemStack(Blocks.pumpkin) }),
+ MELON("Melon", "MELON_DICER", { ItemStack(Items.melon) }),
+ COCOA_BEANS("Cocoa Beans", "COCO_CHOPPER", { ItemStack(Items.dye, 1, EnumDyeColor.BROWN.dyeDamage) }),
+ SUGAR_CANE("Sugar Cane", "THEORETICAL_HOE_CANE", { ItemStack(Items.reeds) }),
+ CACTUS("Cactus", "CACTUS_KNIFE", { ItemStack(Blocks.cactus) }),
+ MUSHROOM("Mushroom", "FUNGI_CUTTER", { ItemStack(Blocks.red_mushroom_block) }),
;
+ val icon by lazy { iconSupplier() }
override fun toString(): String {
return cropName
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt
index 1168b7f40..67b543c03 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenAPI.kt
@@ -128,15 +128,9 @@ class GardenAPI {
return CropType.getByName(itemName)
}
- private fun getItemStackForCrop(crop: CropType): ItemStack {
- val cropName = if (crop == CropType.MUSHROOM) "Red Mushroom Block" else crop.cropName
- val internalName = NEUItems.getInternalName(cropName)
- return NEUItems.getItemStack(internalName)
- }
-
fun addGardenCropToList(crop: CropType, list: MutableList<Any>) {
try {
- list.add(getItemStackForCrop(crop))
+ list.add(crop.icon)
} catch (e: NullPointerException) {
e.printStackTrace()
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt
index 1fa138455..2a1f8b4dc 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/GardenOptimalSpeed.kt
@@ -7,7 +7,15 @@ import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.TabListUpdateEvent
import at.hannibal2.skyhanni.utils.LorenzUtils
import at.hannibal2.skyhanni.utils.RenderUtils.renderString
+import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
+import at.hannibal2.skyhanni.utils.StringUtils.removeColor
+import at.hannibal2.skyhanni.utils.renderables.Renderable
+import io.github.moulberry.notenoughupdates.mixins.AccessorGuiEditSign
import net.minecraft.client.Minecraft
+import net.minecraft.client.gui.inventory.GuiEditSign
+import net.minecraft.util.ChatComponentText
+import net.minecraftforge.client.event.GuiOpenEvent
+import net.minecraftforge.client.event.GuiScreenEvent.DrawScreenEvent
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import java.util.regex.Pattern
@@ -19,6 +27,7 @@ class GardenOptimalSpeed {
private val currentSpeedPattern = Pattern.compile(" Speed: §r§f✦(.*)")
private var lastWarnTime = 0L
private var cropInHand: CropType? = null
+ private var rancherOverlayList: List<List<Any?>> = emptyList()
@SubscribeEvent
fun onTabListUpdate(event: TabListUpdateEvent) {
@@ -30,6 +39,35 @@ class GardenOptimalSpeed {
}
}
+
+ @SubscribeEvent
+ fun onGuiOpen(event: GuiOpenEvent) {
+ rancherOverlayList = CropType.values().map { crop ->
+ listOf(crop.icon, Renderable.link("${crop.cropName} - ${crop.getOptimalSpeed()}") {
+ val gui = Minecraft.getMinecraft().currentScreen
+ if (gui !is GuiEditSign) return@link
+ gui as AccessorGuiEditSign
+ gui.tileSign.signText[0] = ChatComponentText("${crop.getOptimalSpeed()}")
+ })
+ }
+ }
+
+ @SubscribeEvent
+ fun onGuiRender(event: DrawScreenEvent.Post) {
+ if (!isRancherOverlayEnabled()) return
+ val gui = event.gui
+ if (gui !is GuiEditSign) return
+ gui as AccessorGuiEditSign
+ if (gui.tileSign.signText[1].unformattedText.removeColor() != "^^^^^^"
+ || gui.tileSign.signText[2].unformattedText.removeColor() != "Set your"
+ || gui.tileSign.signText[3].unformattedText.removeColor() != "speed cap!"
+ ) return
+ config.optimalSpeedSignPosition.renderStringsAndItems(
+ rancherOverlayList,
+ posLabel = "Optimal Speed Rancher Overlay"
+ )
+ }
+
@SubscribeEvent
fun onGardenToolChange(event: GardenToolChangeEvent) {
cropInHand = event.crop
@@ -75,5 +113,6 @@ class GardenOptimalSpeed {
}
}
+ private fun isRancherOverlayEnabled() = GardenAPI.inGarden() && config.optimalSpeedSignEnabled
private fun isEnabled() = GardenAPI.inGarden() && config.optimalSpeedEnabled
} \ 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 491b73d31..df5567415 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt
@@ -4,7 +4,7 @@ import at.hannibal2.skyhanni.config.core.config.Position
import at.hannibal2.skyhanni.data.GuiEditManager
import at.hannibal2.skyhanni.data.GuiEditManager.Companion.getAbsX
import at.hannibal2.skyhanni.data.GuiEditManager.Companion.getAbsY
-import at.hannibal2.skyhanni.utils.NEUItems.renderOnScreen
+import at.hannibal2.skyhanni.utils.renderables.Renderable
import io.github.moulberry.moulconfig.internal.TextRenderUtils
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.FontRenderer
@@ -14,7 +14,6 @@ import net.minecraft.client.renderer.Tessellator
import net.minecraft.client.renderer.vertex.DefaultVertexFormats
import net.minecraft.entity.Entity
import net.minecraft.inventory.Slot
-import net.minecraft.item.ItemStack
import net.minecraft.util.AxisAlignedBB
import net.minecraft.util.MathHelper
import net.minecraft.util.ResourceLocation
@@ -517,27 +516,17 @@ object RenderUtils {
}
private fun Position.renderLine(line: List<Any?>, offsetY: Int, itemScale: Double = 1.0): Int {
- val renderer = Minecraft.getMinecraft().fontRendererObj
+ GlStateManager.pushMatrix()
+ GlStateManager.translate(getAbsX().toFloat(), (getAbsY() + offsetY).toFloat(), 0F)
var offsetX = 0
for (any in line) {
- if (any == null) {
- offsetX += 12
- continue
- }
- if (any is String) {
- renderString0(any, offsetX, offsetY)
- val width = renderer.getStringWidth(any)
- offsetX += width
- } else if (any is ItemStack) {
- val isX = getAbsX() + offsetX
- val isY = getAbsY() + offsetY
-
- any.renderOnScreen(isX.toFloat(), isY.toFloat(), itemScale)
- offsetX += 12
- } else {
- throw RuntimeException("Unknown render object: $any")
- }
+ val renderable = Renderable.fromAny(any, itemScale = itemScale) ?: throw RuntimeException("Unknown render object: ${any}")
+
+ renderable.render(getAbsX() + offsetX, getAbsY() + offsetY)
+ offsetX += renderable.width
+ GlStateManager.translate(renderable.width.toFloat(), 0F, 0F)
}
+ GlStateManager.popMatrix()
return offsetX
}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt b/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt
new file mode 100644
index 000000000..73bba5686
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt
@@ -0,0 +1,101 @@
+package at.hannibal2.skyhanni.utils.renderables
+
+import at.hannibal2.skyhanni.utils.NEUItems.renderOnScreen
+import io.github.moulberry.notenoughupdates.util.Utils
+import net.minecraft.client.Minecraft
+import net.minecraft.item.ItemStack
+import org.lwjgl.input.Mouse
+import kotlin.math.max
+
+interface Renderable {
+ val width: Int
+ fun isHovered(posX: Int, posY: Int) =
+ Utils.getMouseX() in (posX..posX + width)
+ && Utils.getMouseY() in (posY..posY + 10) // TODO: adjust for variable height?
+
+ /**
+ * N.B.: the offset is absolute, not relative to the position and should not be used for rendering
+ * (the GL matrix stack should already be pre transformed)
+ */
+ fun render(posX: Int, posY: Int)
+
+ companion object {
+ fun fromAny(any: Any?, itemScale: Double = 1.0): Renderable? {
+ return when (any) {
+ null -> placeholder(12)
+ is Renderable -> any
+ is String -> string(any)
+ is ItemStack -> itemStack(any, itemScale)
+ else -> null
+ }
+ }
+
+ fun link(text: String, onClick: () -> Unit): Renderable {
+ return clickable(hoverable(string("§n$text"), string(text)), onClick)
+ }
+
+ fun clickable(render: Renderable, onClick: () -> Unit, button: Int = 0): Renderable {
+ return object : Renderable {
+ override val width: Int
+ get() = render.width
+
+ var wasDown = false
+
+ override fun render(posX: Int, posY: Int) {
+ val isDown = Mouse.isButtonDown(button)
+ if (isDown > wasDown && isHovered(posX, posY)) {
+ onClick()
+ }
+ wasDown = isDown
+ render.render(posX, posY)
+ }
+
+ }
+ }
+
+ fun hoverable(hovered: Renderable, unhovered: Renderable): Renderable {
+ return object : Renderable {
+ override val width: Int
+ get() = max(hovered.width, unhovered.width)
+
+ override fun render(posX: Int, posY: Int) {
+ if (isHovered(posX, posY))
+ hovered.render(posX, posY)
+ else
+ unhovered.render(posX, posY)
+ }
+ }
+ }
+
+ fun itemStack(any: ItemStack, scale: Double = 1.0): Renderable {
+ return object : Renderable {
+ override val width: Int
+ get() = 12
+
+ override fun render(posX: Int, posY: Int) {
+ any.renderOnScreen(0F, 0F, scaleMultiplier = scale)
+ }
+ }
+ }
+
+ fun string(string: String): Renderable {
+ return object : Renderable {
+ override val width: Int
+ get() = Minecraft.getMinecraft().fontRendererObj.getStringWidth(string)
+
+ override fun render(posX: Int, posY: Int) {
+ Minecraft.getMinecraft().fontRendererObj.drawStringWithShadow("§f$string", 1f, 1f, 0)
+ }
+ }
+ }
+
+ fun placeholder(width: Int): Renderable {
+ return object : Renderable {
+ override val width: Int = width
+
+ override fun render(posX: Int, posY: Int) {
+ }
+ }
+ }
+ }
+} \ No newline at end of file