aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/io/github/moulberry/notenoughupdates/util/MuseumUtil.kt
blob: 95b61b5122461771d5ce71b1771bad7638e55744 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
 * 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 <https://www.gnu.org/licenses/>.
 */

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<String>,
        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<String> {
        return (if (armor)
            findMuseumArmorSetByName(displayName)
        else
            listOf(findMuseumItemByName(displayName))).filterNotNull()

    }

    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
            }
        }
    }

    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 ➜")
    }
}