diff options
author | Roman / Linnea Gräf <nea@nea.moe> | 2023-03-31 21:32:42 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-31 21:32:42 +0200 |
commit | 53c1440fa4a42613b140f4f099b60c3664ba0fdd (patch) | |
tree | 0341c3b48d533fdc3f2efa9e172cd4f6c37eeb14 | |
parent | e6bcc8f902e410c348ff720ab73de14e5cf04280 (diff) | |
download | skyhanni-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>
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 |