/*
* Copyright (C) 2023 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 .
*/
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
import net.minecraft.item.EnumDyeColor
import net.minecraft.item.ItemDye
import net.minecraft.item.ItemStack
object MuseumUtil {
data class MuseumItem(
/**
* A potentially non-exhaustive list of item ids that are required for this museum donation.
*/
val skyblockItemIds: List,
val state: DonationState,
)
enum class DonationState {
/**
* Donated armor only shows one piece, so we use that for id resolution, which might result in incomplete
* results (hence the separate state). This still means that the entire set is donated, but it is guaranteed to
* be only a partial result. Other values of this enum do not guarantee a full result, but at least they do not
* guarantee a partial one.
*/
DONATED_PRESENT_PARTIAL,
DONATED_PRESENT,
DONATED_VACANT,
MISSING,
}
fun findMuseumItem(stack: ItemStack, isOnArmorPage: Boolean): MuseumItem? {
val item = stack.item ?: return null
val items by lazy { findItemsByName(stack.displayName, isOnArmorPage)}
if (item is ItemDye) {
val dyeColor = EnumDyeColor.byDyeDamage(stack.itemDamage)
if (dyeColor == EnumDyeColor.LIME) {
// Item is donated, but not present in the museum
return MuseumItem(items, DonationState.DONATED_VACANT)
} else if (dyeColor == EnumDyeColor.GRAY) {
// Item is not donated
return MuseumItem(items, DonationState.MISSING)
}
// Otherwise unknown item, try to analyze as normal item.
}
val skyblockId = NotEnoughUpdates.INSTANCE.manager.createItemResolutionQuery().withItemStack(stack)
.resolveInternalName()
if (skyblockId != null) {
return MuseumItem(
listOf(skyblockId),
if (isOnArmorPage) DonationState.DONATED_PRESENT_PARTIAL else DonationState.DONATED_PRESENT
)
}
return MuseumItem(
items,
DonationState.DONATED_PRESENT
)
}
fun findItemsByName(displayName: String, armor: Boolean): List {
return (if (armor)
findMuseumArmorSetByName(displayName)
else
listOf(findMuseumItemByName(displayName))).filterNotNull()
}
fun findMuseumItemByName(displayName: String): String? =
ItemResolutionQuery.findInternalNameByDisplayName(displayName, true)
fun findMuseumArmorSetByName(displayName: String): List {
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
}
}
}
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 findInternalId = NotEnoughUpdates.INSTANCE.manager.createItemResolutionQuery().withKnownInternalName(internalId).resolveToItemStack()
return if (findInternalId != null) {
internalId
} else {
null
}
}
fun isMuseumInventory(inventory: IInventory): Boolean {
return StringUtils.cleanColour(inventory.displayName.unformattedText).startsWith("Museum ➜")
}
}