aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/io
diff options
context:
space:
mode:
authorLulonaut <lulonaut@lulonaut.tech>2024-03-12 13:10:12 +0100
committerGitHub <noreply@github.com>2024-03-12 13:10:12 +0100
commit1a2c5501ce22254f85c588cc38ad20d1611eb231 (patch)
tree576c904248487a0b290256c101653136e108950e /src/main/kotlin/io
parenta9221f2203318496c3f692abc82dc7264c3dfed8 (diff)
downloadNotEnoughUpdates-1a2c5501ce22254f85c588cc38ad20d1611eb231.tar.gz
NotEnoughUpdates-1a2c5501ce22254f85c588cc38ad20d1611eb231.tar.bz2
NotEnoughUpdates-1a2c5501ce22254f85c588cc38ad20d1611eb231.zip
add price source and sorting buttons to /pv sack page (#1039)
* add price source and sorting buttons to /pv sack page * Change default price source and make the buttons behave similarly * apply suggestions
Diffstat (limited to 'src/main/kotlin/io')
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/profileviewer/SacksPage.kt171
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/util/KotlinRenderUtils.kt56
2 files changed, 211 insertions, 16 deletions
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/profileviewer/SacksPage.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/profileviewer/SacksPage.kt
index 8e5a2973..7ef0bc43 100644
--- a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/profileviewer/SacksPage.kt
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/profileviewer/SacksPage.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2023 NotEnoughUpdates contributors
+ * Copyright (C) 2023-2024 NotEnoughUpdates contributors
*
* This file is part of NotEnoughUpdates.
*
@@ -29,16 +29,24 @@ import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewerPage
import io.github.moulberry.notenoughupdates.profileviewer.SkyblockProfiles
import io.github.moulberry.notenoughupdates.util.*
import io.github.moulberry.notenoughupdates.util.hypixelapi.HypixelItemAPI
+import io.github.moulberry.notenoughupdates.util.kotlin.set
import net.minecraft.client.renderer.GlStateManager
+import net.minecraft.init.Blocks
+import net.minecraft.init.Items
+import net.minecraft.item.ItemStack
import net.minecraft.util.ResourceLocation
import org.lwjgl.input.Mouse
import org.lwjgl.opengl.GL11
-
+import kotlin.collections.component1
+import kotlin.collections.component2
+import kotlin.collections.set
+import kotlin.math.max
class SacksPage(pvInstance: GuiProfileViewer) : GuiProfileViewerPage(pvInstance) {
private val manager get() = NotEnoughUpdates.INSTANCE.manager
private val pv_sacks = ResourceLocation("notenoughupdates:pv_sacks.png")
private var sacksJson = Constants.SACKS
+ private var sackTypes = sacksJson.getAsJsonObject("sacks") ?: JsonObject()
private var tooltipToDisplay = listOf<String>()
private var currentProfile: SkyblockProfiles.SkyblockProfile? = null
@@ -61,7 +69,27 @@ class SacksPage(pvInstance: GuiProfileViewer) : GuiProfileViewerPage(pvInstance)
private val sackGridYSize = 41
private val itemIconSize = 20
- private val sackContents = mutableMapOf<String, SackInfo>()
+ // Lazy initialisation to allow for guiLeft and guiTop to be initialized first
+ private val priceSourceButtonRect by lazy { Rectangle(guiLeft + 54, guiTop + 155, 20, 20) }
+
+ private enum class PriceSource {
+ Bazaar,
+ NPC
+ }
+
+ private var currentPriceSource = PriceSource.Bazaar
+
+
+ private val sortButtonRect by lazy { Rectangle(guiLeft + 76, guiTop + 155, 20, 20) }
+
+ private enum class SortMode {
+ Value,
+ Quantity
+ }
+
+ private var currentSortMode = SortMode.Value
+
+ private var sackContents = mutableMapOf<String, SackInfo>()
private val sackItems = mutableMapOf<String, SackItem>()
private val playerRunes = mutableListOf<String>()
@@ -123,8 +151,6 @@ class SacksPage(pvInstance: GuiProfileViewer) : GuiProfileViewerPage(pvInstance)
GlStateManager.enableDepth()
- val sackTypes = sacksJson.getAsJsonObject("sacks")
-
val startIndex = page * pageSize
val endIndex = (page + 1) * pageSize
if (currentSack == "All") {
@@ -203,6 +229,14 @@ class SacksPage(pvInstance: GuiProfileViewer) : GuiProfileViewerPage(pvInstance)
sackItemNames = playerRunes
}
+ sackItemNames = sackItemNames.sortedByDescending {
+ val sackInfo = sackItems[it] ?: SackItem(0, 0.0)
+ when (currentSortMode) {
+ SortMode.Value -> sackInfo.value
+ SortMode.Quantity -> sackInfo.amount.toDouble()
+ }
+ }
+
for ((index, itemName) in sackItemNames.withIndex()) {
if (index < startIndex || index >= endIndex) continue
val adjustedIndex = index - startIndex
@@ -210,6 +244,7 @@ class SacksPage(pvInstance: GuiProfileViewer) : GuiProfileViewerPage(pvInstance)
val xIndex = adjustedIndex % columns
val yIndex = adjustedIndex / columns
if (yIndex >= rows) continue
+ val itemInfo = sackItems[itemName] ?: SackItem(0, 0.0)
val itemStack = manager.createItem(itemName)
@@ -229,7 +264,6 @@ class SacksPage(pvInstance: GuiProfileViewer) : GuiProfileViewerPage(pvInstance)
GL11.GL_NEAREST
)
- val itemInfo = sackItems[itemName] ?: SackItem(0, 0.0)
Utils.drawStringCentered(
"§6${StringUtils.shortNumberFormat(itemInfo.value.roundToDecimals(0))}",
x + itemIconSize / 2,
@@ -262,7 +296,12 @@ class SacksPage(pvInstance: GuiProfileViewer) : GuiProfileViewerPage(pvInstance)
100,
true
)
- Utils.renderShadowedString("§2Back", (guiLeft + sackArrayLeft + 40).toFloat(), (guiTop + arrowsHeight + 3).toFloat(), 79)
+ Utils.renderShadowedString(
+ "§2Back",
+ (guiLeft + sackArrayLeft + 40).toFloat(),
+ (guiTop + arrowsHeight + 3).toFloat(),
+ 79
+ )
if (Mouse.getEventButtonState() && Utils.isWithinRect(mouseX, mouseY, buttonRect)) {
currentSack = "All"
@@ -272,6 +311,8 @@ class SacksPage(pvInstance: GuiProfileViewer) : GuiProfileViewerPage(pvInstance)
}
}
+ renderPriceSourceAndSortButtons(mouseX, mouseY)
+
GlStateManager.color(1f, 1f, 1f, 1f)
ArrowPagesUtils.onDraw(guiLeft, guiTop, intArrayOf(sackArrayLeft + arrowsXPos, arrowsHeight), page, maxPage + 1)
@@ -282,6 +323,65 @@ class SacksPage(pvInstance: GuiProfileViewer) : GuiProfileViewerPage(pvInstance)
}
}
+ private fun renderPriceSourceAndSortButtons(mouseX: Int, mouseY: Int) {
+ KotlinRenderUtils.renderItemStackButton(
+ priceSourceButtonRect,
+ when (currentPriceSource) {
+ PriceSource.Bazaar -> {
+ // Bazaar NPC
+ val uuid = "c232e3820897429157619b0ee099fec0628f602fff12b695de54aef11d923ad7"
+ ItemUtils.createSkullItemStack(
+ uuid,
+ uuid,
+ "https://textures.minecraft.net/texture/$uuid"
+ )
+ }
+
+ PriceSource.NPC -> ItemUtils.getCoinItemStack(100000.0)
+ },
+ GuiProfileViewer.pv_elements
+ )
+ if (priceSourceButtonRect.contains(mouseX, mouseY)) {
+ val tooltip = mutableListOf(
+ "§6Select price source",
+ )
+ tooltip.addAll(generateTooltipFromEnum(currentPriceSource))
+ tooltipToDisplay = tooltip
+ }
+
+ KotlinRenderUtils.renderItemStackButton(
+ sortButtonRect,
+ when (currentSortMode) {
+ SortMode.Value -> ItemStack(Items.gold_ingot)
+ SortMode.Quantity -> ItemStack(Blocks.hopper)
+ },
+ GuiProfileViewer.pv_elements
+ )
+ if (sortButtonRect.contains(mouseX, mouseY)) {
+ val tooltip = mutableListOf(
+ "§6Select sorting mode",
+ )
+ tooltip.addAll(generateTooltipFromEnum(currentSortMode))
+ tooltipToDisplay = tooltip
+ }
+ }
+
+ private inline fun <reified T : Enum<T>> generateTooltipFromEnum(currentlySelected: T): List<String> {
+ val tooltip = mutableListOf<String>()
+ for (enumValue in enumValues<T>()) {
+ var line = " "
+ line += if (enumValue == currentlySelected) {
+ "§2> ${enumValue.name}"
+ } else {
+ enumValue.name
+ }
+ tooltip.add(line)
+ }
+ tooltip.add("")
+ tooltip.add("§eClick to switch!")
+ return tooltip
+ }
+
fun mouseClick(mouseX: Int, mouseY: Int, mouseButton: Int): Boolean {
super.mouseClicked(mouseX, mouseY, mouseButton)
@@ -291,8 +391,6 @@ class SacksPage(pvInstance: GuiProfileViewer) : GuiProfileViewerPage(pvInstance)
// after this point everything in the constants json exists and does not need to be checked again
if (currentSack == "All") {
- val sackTypes = sacksJson.getAsJsonObject("sacks")
-
val startIndex = page * pageSize
val endIndex = (page + 1) * pageSize
@@ -321,6 +419,18 @@ class SacksPage(pvInstance: GuiProfileViewer) : GuiProfileViewerPage(pvInstance)
}
}
+ if (priceSourceButtonRect.contains(mouseX, mouseY)) {
+ currentPriceSource = PriceSource.values()[(currentPriceSource.ordinal + 1) % PriceSource.values().size]
+ Utils.playPressSound()
+ getData()
+ }
+
+ if (sortButtonRect.contains(mouseX, mouseY)) {
+ currentSortMode = SortMode.values()[(currentSortMode.ordinal + 1) % SortMode.values().size]
+ Utils.playPressSound()
+ getData()
+ }
+
ArrowPagesUtils.onPageSwitchMouse(
guiLeft,
guiTop,
@@ -366,7 +476,6 @@ class SacksPage(pvInstance: GuiProfileViewer) : GuiProfileViewerPage(pvInstance)
playerRunes.clear()
if (!sacksJson.has("sacks") || !sacksJson.get("sacks").isJsonObject) return
- val sackTypes = sacksJson.getAsJsonObject("sacks")
val selectedProfile = selectedProfile?.profileJson ?: return
val sacksInfo = Utils.getElementOrDefault(selectedProfile, "inventory.sacks_counts", JsonObject()).asJsonObject
@@ -407,22 +516,52 @@ class SacksPage(pvInstance: GuiProfileViewer) : GuiProfileViewerPage(pvInstance)
sackContents[sackName] = SackInfo(sackItemCount, sackValue)
}
+ sackTypes = sortSackTypesList()
+
+
for ((itemName, _) in sacksInfo.entrySet()) {
val adjustedName = itemName.replace(":", "-")
- if (adjustedName.contains(Regex("(RUNE|PERFECT_|MUSHROOM_COLLECTION)"))) continue
- if (adjustedName in sackItems) continue
+ if ((adjustedName in sackItems) || adjustedName.contains(Regex("(RUNE|PERFECT_|MUSHROOM_COLLECTION)"))) continue
println("$adjustedName missing from repo sacks file!")
}
sackContents["All"] = SackInfo(totalItems, totalValue)
}
+ /**
+ * Sort the sackTypes list via the chosen sorting mode.
+ *
+ * This will control the order in which the list will be rendered later
+ *
+ * @see SortMode
+ */
+ private fun sortSackTypesList(): JsonObject {
+ val sortedTypes = JsonObject()
+ Constants.SACKS.getAsJsonObject("sacks").entrySet()
+ .sortedByDescending { (key, _) ->
+ val sack = sackContents[key] ?: SackInfo(0, 0.0)
+ when (currentSortMode) {
+ SortMode.Value -> sack.sackValue
+ SortMode.Quantity -> sack.itemCount.toDouble()
+ }
+ }
+ .forEach { (key, value) ->
+ sortedTypes[key] = value
+ }
+ return sortedTypes
+ }
+
private fun getPrice(itemName: String): Double {
val npcPrice = HypixelItemAPI.getNPCSellPrice(itemName) ?: 0.0
- val bazaarInfo = manager.auctionManager.getBazaarInfo(itemName) ?: return npcPrice
- val buyPrice = bazaarInfo.getDoubleOrValue("curr_buy", 0.0)
- val sellPrice = bazaarInfo.getDoubleOrValue("curr_sell", 0.0)
- return maxOf(npcPrice, buyPrice, sellPrice)
+ return when (currentPriceSource) {
+ PriceSource.NPC -> npcPrice
+ PriceSource.Bazaar -> {
+ val bazaarInfo = manager.auctionManager.getBazaarInfo(itemName) ?: return npcPrice
+ val buyPrice = bazaarInfo.getDoubleOrValue("curr_buy", 0.0)
+ val sellPrice = bazaarInfo.getDoubleOrValue("curr_sell", 0.0)
+ max(buyPrice, sellPrice)
+ }
+ }
}
private fun getRuneData(sacksInfo: JsonObject): Int {
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/KotlinRenderUtils.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/KotlinRenderUtils.kt
new file mode 100644
index 00000000..5ab1d09b
--- /dev/null
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/KotlinRenderUtils.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2024 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.util
+
+import net.minecraft.client.renderer.GlStateManager
+import net.minecraft.item.ItemStack
+import net.minecraft.util.ResourceLocation
+import org.lwjgl.opengl.GL11
+
+object KotlinRenderUtils {
+
+ @JvmStatic
+ fun renderItemStackButton(button: Rectangle, item: ItemStack, texture: ResourceLocation) {
+ renderItemStackButton(button.x, button.y, item, texture)
+ }
+
+ @JvmStatic
+ fun renderItemStackButton(x: Int, y: Int, item: ItemStack, texture: ResourceLocation) {
+ MC.textureManager.bindTexture(texture)
+ GlStateManager.color(1f, 1f, 1f, 1f)
+ Utils.drawTexturedRect(
+ x.toFloat(),
+ y.toFloat(),
+ 20f,
+ 20f,
+ 0f,
+ 20 / 256f,
+ 0f,
+ 20 / 256f,
+ GL11.GL_NEAREST
+ )
+
+ Utils.drawItemStack(
+ item,
+ x + 2,
+ y + 2
+ )
+ }
+}