Skip to content

Commit

Permalink
Add Museum coins / skyblock xp sorting (NotEnoughUpdates#1398)
Browse files Browse the repository at this point in the history
Co-authored-by: CalMWolfs <[email protected]>
  • Loading branch information
NopoTheGamer and CalMWolfs authored Dec 9, 2024
1 parent 692598c commit 77f98c4
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,14 @@ public class Museum {
)
public int museumCheapestItemOverlayValueSource = 0;

@Expose
@ConfigOption(
name = "Sorting Method",
desc = "Sort by Skyblock XP or by Raw Value"
)
@ConfigEditorDropdown(
values = {"Skyblock XP", "Raw Value"}
)
public int museumCheapestItemOverlayUseXp = 0;

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 NotEnoughUpdates contributors
* Copyright (C) 2023-2024 NotEnoughUpdates contributors
*
* This file is part of NotEnoughUpdates.
*
Expand All @@ -23,10 +23,16 @@ import io.github.moulberry.notenoughupdates.NotEnoughUpdates
import io.github.moulberry.notenoughupdates.core.util.ArrowPagesUtils
import io.github.moulberry.notenoughupdates.core.util.render.TextRenderUtils
import io.github.moulberry.notenoughupdates.events.ButtonExclusionZoneEvent
import io.github.moulberry.notenoughupdates.miscfeatures.inventory.MuseumTooltipManager.isItemDonated
import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer
import io.github.moulberry.notenoughupdates.options.separatesections.Museum
import io.github.moulberry.notenoughupdates.util.*
import io.github.moulberry.notenoughupdates.util.Constants
import io.github.moulberry.notenoughupdates.util.ItemUtils
import io.github.moulberry.notenoughupdates.util.MuseumUtil
import io.github.moulberry.notenoughupdates.util.MuseumUtil.DonationState.MISSING
import io.github.moulberry.notenoughupdates.util.Rectangle
import io.github.moulberry.notenoughupdates.util.Utils
import io.github.moulberry.notenoughupdates.util.stripControlCodes
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.GuiScreen
import net.minecraft.client.gui.ScaledResolution
Expand Down Expand Up @@ -72,7 +78,8 @@ object MuseumCheapestItemOverlay {
var internalNames: List<String>,
var value: Double,
var priceRefreshedAt: Long,
var category: Category
var category: Category,
var sbXp: Int = 0
)

private const val ITEMS_PER_PAGE = 10
Expand All @@ -90,6 +97,7 @@ object MuseumCheapestItemOverlay {
private var itemsToDonate: MutableList<MuseumItem> = emptyList<MuseumItem>().toMutableList()
private var leftButtonRect = Rectangle(0, 0, 0, 0)
private var rightButtonRect = Rectangle(0, 0, 0, 0)
private var xpButtonRect = Rectangle(0, 0, 0, 0)
private var selectedCategory = Category.NOT_APPLICABLE
private var totalPages = 0

Expand Down Expand Up @@ -166,6 +174,9 @@ object MuseumCheapestItemOverlay {
updateAllValues()
} else if (Mouse.getEventButtonState() && rightButtonRect.contains(mouseX, mouseY)) {
advanceSelectedCategory()
} else if (Mouse.getEventButtonState() && xpButtonRect.contains(mouseX, mouseY)) {
config.museumCheapestItemOverlayUseXp = 1 - config.museumCheapestItemOverlayUseXp
updateAllValues()
}
}

Expand All @@ -177,12 +188,16 @@ object MuseumCheapestItemOverlay {
selectedCategory = enumValues<Category>()[nextValueIndex]
}


val BUTTON = ResourceLocation("notenoughupdates:icon_from_minion_helper.png");

/**
* Draw the two clickable buttons on the bottom right and display a tooltip if needed
*/
private fun drawButtons(guiLeft: Int, xSize: Int, guiTop: Int) {
RenderHelper.enableGUIStandardItemLighting()
val useBIN = config.museumCheapestItemOverlayValueSource == 0
val useCoinsPerXp = config.museumCheapestItemOverlayUseXp == 0
val mouseX = Utils.getMouseX()
val mouseY = Utils.getMouseY()
val scaledResolution = ScaledResolution(Minecraft.getMinecraft())
Expand Down Expand Up @@ -227,8 +242,7 @@ object MuseumCheapestItemOverlay {
mouseY,
width,
height,
-1,
Minecraft.getMinecraft().fontRendererObj
-1
)
}

Expand Down Expand Up @@ -273,8 +287,51 @@ object MuseumCheapestItemOverlay {
mouseY,
width,
height,
-1,
Minecraft.getMinecraft().fontRendererObj
-1
)
GlStateManager.color(1f, 1f, 1f, 1f)
}

// Coins per xp button
val skyblockXpItemStack = if (useCoinsPerXp) {
ItemStack(Items.experience_bottle)
} else {
ItemStack(Items.glass_bottle)
}
xpButtonRect = Rectangle(
guiLeft + xSize + 112,
guiTop + 106,
16,
16
)
Minecraft.getMinecraft().textureManager.bindTexture(BUTTON)
Utils.drawTexturedRect(xpButtonRect.x.toFloat(), xpButtonRect.y.toFloat(), 16f, 16f, 0f, 1f, 0f, 1f, GL11.GL_NEAREST)
Minecraft.getMinecraft().renderItem.renderItemIntoGUI(
skyblockXpItemStack,
xpButtonRect.x,
xpButtonRect.y - 1
)
if (xpButtonRect.contains(mouseX, mouseY)) {
val tooltip = if (useCoinsPerXp) {
listOf(
"${EnumChatFormatting.GREEN}Sort by SkyBlock XP",
"",
"${EnumChatFormatting.YELLOW}Click to switch to Raw Value!"
)
} else {
listOf(
"${EnumChatFormatting.GREEN}Sort by Raw Value",
"",
"${EnumChatFormatting.YELLOW}Click to switch Skyblock XP!"
)
}
Utils.drawHoveringText(
tooltip,
mouseX,
mouseY,
width,
height,
-1
)
}
RenderHelper.disableStandardItemLighting()
Expand All @@ -284,7 +341,13 @@ object MuseumCheapestItemOverlay {
* Sort the collected items by their calculated value
*/
private fun sortByValue() {
itemsToDonate.sortBy { it.value }
itemsToDonate.sortBy {
if (config.museumCheapestItemOverlayUseXp == 0 && it.sbXp > 0) {
it.value / it.sbXp
} else {
it.value
}
}
}

/**
Expand Down Expand Up @@ -412,10 +475,13 @@ object MuseumCheapestItemOverlay {
tooltip.add("")
}

if (line.sbXp > 0) {
tooltip.add("${EnumChatFormatting.GRAY}Reward: ${EnumChatFormatting.AQUA}+${line.sbXp} SkyBlock XP")
}

if (line.internalNames.isEmpty()) {
tooltip.add("${EnumChatFormatting.RED}Could not determine item!")
}
else if (NotEnoughUpdates.INSTANCE.manager.getRecipesFor(line.internalNames[0]).isNotEmpty()) {
} else if (NotEnoughUpdates.INSTANCE.manager.getRecipesFor(line.internalNames[0]).isNotEmpty()) {
tooltip.add("${EnumChatFormatting.YELLOW}${EnumChatFormatting.BOLD}Click to open recipe!")
} else {
tooltip.add("${EnumChatFormatting.RED}${EnumChatFormatting.BOLD}No recipe available!")
Expand Down Expand Up @@ -484,6 +550,7 @@ object MuseumCheapestItemOverlay {
}
val armor = category == Category.ARMOUR_SETS
for (i in 0..53) {
if (!MuseumUtil.isValidSlot(i)) continue
val stack = slots[i].stack ?: continue
val parsedItems = MuseumUtil.findMuseumItem(stack, armor) ?: continue
when (parsedItems.state) {
Expand All @@ -501,13 +568,15 @@ object MuseumCheapestItemOverlay {

//if the list does not already contain it, insert this MuseumItem
if (itemsToDonate.none { it.internalNames == parsedItems.skyblockItemIds }) {
val xp = calculateSkyblockXp(parsedItems.skyblockItemIds, false)
itemsToDonate.add(
MuseumItem(
displayName,
parsedItems.skyblockItemIds,
calculateValue(parsedItems.skyblockItemIds),
time,
category
category,
xp
)
)
}
Expand All @@ -520,6 +589,51 @@ object MuseumCheapestItemOverlay {
}.start()
}

private fun calculateSkyblockXp(internalNames: List<String>, factorDonatedItems: Boolean): Int {
var xp = 0
val reversedJsonObject = Constants.MUSEUM?.get("armor_to_id")?.asJsonObject?.entrySet()
?.associateBy({ it.value.asString }, { it.key })
var currentItem = ""
if (internalNames.size == 1) {
val xpAmount = Constants.MUSEUM?.get("itemToXp")?.asJsonObject?.get(
internalNames.first()
)?.asInt ?: 0
if (isItemDonated(internalNames.first()) && !factorDonatedItems) {
xp = 0
} else {
xp = xpAmount
}
currentItem = internalNames.first()
} else {
for (skyblockItemId in internalNames) {
val xpAmount = Constants.MUSEUM?.get("itemToXp")?.asJsonObject?.get(
reversedJsonObject?.get(skyblockItemId)
)?.asInt ?: 0
if (isItemDonated(internalNames.first()) && !factorDonatedItems) {
xp = 0
} else {
xp = xpAmount
}
if (xp != 0) {
currentItem = skyblockItemId
break
}
}
}

var child = Constants.MUSEUM?.get("children")?.asJsonObject?.get(currentItem)?.asString
if (child != null) {
xp += calculateSkyblockXp(listOf(child), factorDonatedItems)
} else {
val armour = reversedJsonObject?.get(currentItem) ?: currentItem
child = Constants.MUSEUM?.get("children")?.asJsonObject?.get(armour)?.asString
if (child != null) {
xp += calculateSkyblockXp(listOf(child), factorDonatedItems)
}
}
return xp
}

/**
* Check if the highest page for the current category is currently open and update [checkedPages] accordingly
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ object MuseumTooltipManager {

if (!slots.equals(previousSlots)) {
for (i in 0..53) {
if (!MuseumUtil.isValidSlot(i)) continue
val slot = slots[i]
if (slot == null || slot.stack == null) continue
val item = MuseumUtil.findMuseumItem(slot.stack, armor) ?: continue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

package io.github.moulberry.notenoughupdates.util

import io.github.moulberry.notenoughupdates.NEUManager
import io.github.moulberry.notenoughupdates.NotEnoughUpdates
import io.github.moulberry.notenoughupdates.core.util.StringUtils
import net.minecraft.inventory.IInventory
Expand Down Expand Up @@ -86,68 +85,37 @@ object MuseumUtil {

}

fun findMuseumItemByName(displayName: String): String? =
private fun findMuseumItemByName(displayName: String): String? =
ItemResolutionQuery.findInternalNameByDisplayName(displayName, true)


fun findMuseumArmorSetByName(displayName: String): List<String?> {
val armorSlots = arrayOf(
"HELMET",
"LEGGINGS",
"CHESTPLATE",
"BOOTS",
"NECKLACE",
"CLOAK",
"BELT",
"GAUNTLET",
"HOOD",
"TROUSERS",
"TUNIC",
"SLIPPERS",
"HAT",
)
val monochromeName = NEUManager.cleanForTitleMapSearch(displayName)
val results = ItemResolutionQuery.findInternalNameCandidatesForDisplayName(displayName)
.asSequence()
.filter {
val item = NotEnoughUpdates.INSTANCE.manager.createItem(it)
val name = NEUManager.cleanForTitleMapSearch(item.displayName)
monochromeName.replace("armor", "") in name
}
.toSet()
return armorSlots.map { armorSlot ->
var singleOrNull = results.singleOrNull { armorSlot in it }
if (singleOrNull == null) {
convertArmourNameToId(monochromeName, armorSlot)
} else {
singleOrNull
}
}
}
private fun findMuseumArmorSetByName(displayName: String): List<String?> {
var cleanedString = StringUtils.cleanColour(displayName)
.replace("'s", "").replace("- ", "").lowercase().trim()
.removeSuffix(" armor").removeSuffix(" equipment").removeSuffix(" set")
.replace(" ", "_").uppercase()

fun convertArmourNameToId(name: String, armorSlot: String): String? {
var internalId = ""
if (name.contains("perfect ")) {
try {
Utils.parseRomanNumeral(name.replace("perfect armor tier ", "").uppercase()).let {
internalId = "PERFECT_${armorSlot}_$it"
}
} catch (_: Exception) {
}
} else if (name.contains("divan")) {
internalId = "DIVAN_$armorSlot"
} else {
internalId = "${name.replace("armor", "").uppercase().replace(" ", "_")}$armorSlot"
val museumJson = Constants.MUSEUM
museumJson?.get("set_exceptions")?.asJsonObject?.get(cleanedString)?.let { pieces ->
cleanedString = pieces.asString
}
museumJson?.get("sets_to_items")?.asJsonObject?.get(cleanedString)?.let { pieces ->
return pieces.asJsonArray.map { it.asString }
}
val findInternalId = NotEnoughUpdates.INSTANCE.manager.createItemResolutionQuery().withKnownInternalName(internalId).resolveToItemStack()
return if (findInternalId != null) {
internalId
} else {
null
val withArmor = "${cleanedString}_ARMOR"
museumJson?.get("sets_to_items")?.asJsonObject?.get(withArmor)?.let { pieces ->
return pieces.asJsonArray.map { it.asString }
}
println("Could not find $cleanedString in museum sets for name: \"$displayName\"")
return emptyList()
}

fun isMuseumInventory(inventory: IInventory): Boolean {
return StringUtils.cleanColour(inventory.displayName.unformattedText).startsWith("Museum ➜")
}

fun isValidSlot(slot: Int): Boolean {
if (slot % 9 !in 1..7) return false
return slot in 9..44
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 77f98c4

Please sign in to comment.