aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/features/rift/ShowMotesNpcSellPrice.kt
blob: 36229aeb8a34be818b25f7969b1e36a8f6e9f374 (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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
package at.hannibal2.skyhanni.features.rift

import at.hannibal2.skyhanni.events.*
import at.hannibal2.skyhanni.features.rift.everywhere.RiftAPI
import at.hannibal2.skyhanni.features.rift.everywhere.RiftAPI.motesNpcPrice
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
import at.hannibal2.skyhanni.utils.LorenzColor
import at.hannibal2.skyhanni.utils.LorenzUtils.addAsSingletonList
import at.hannibal2.skyhanni.utils.LorenzUtils.addSelector
import at.hannibal2.skyhanni.utils.LorenzUtils.chat
import at.hannibal2.skyhanni.utils.NEUItems
import at.hannibal2.skyhanni.utils.NumberUtil
import at.hannibal2.skyhanni.utils.NumberUtil.addSeparators
import at.hannibal2.skyhanni.utils.RenderUtils.highlight
import at.hannibal2.skyhanni.utils.RenderUtils.renderStringsAndItems
import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher
import at.hannibal2.skyhanni.utils.renderables.Renderable
import net.minecraftforge.event.entity.player.ItemTooltipEvent
import net.minecraftforge.fml.common.eventhandler.EventPriority
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent

class ShowMotesNpcSellPrice {
    private val config get() = RiftAPI.config.motes
    private var display = emptyList<List<Any>>()
    private val pattern = ".*(?:§\\w)+You have (?:§\\w)+(?<amount>\\d) Grubber Stacks.*".toPattern()
    private val itemMap = mutableMapOf<String, Pair<MutableList<Int>, Double>>()
    private var inInventory = false
    private val slotList = mutableListOf<Int>()

    @SubscribeEvent
    fun onBackgroundDraw(event: GuiRenderEvent.ChestBackgroundRenderEvent) {
        if (!isInventoryValueEnabled()) return
        if (inInventory) {
            config.inventoryValue.position.renderStringsAndItems(
                display,
                itemScale = 1.3,
                posLabel = "Inventory Motes Value"
            )
        }
    }

    @SubscribeEvent
    fun onTick(event: LorenzTickEvent) {
        if (!isInventoryValueEnabled()) return
        if (event.isMod(10))
            processItems()
    }

    @SubscribeEvent(priority = EventPriority.LOW)
    fun onDrawSelectedTemplate(event: GuiContainerEvent.BackgroundDrawnEvent) {
        if (!isInventoryValueEnabled()) return
        val name = InventoryUtils.openInventoryName()
        if (!name.contains("Rift Storage")) return
        for (slot in InventoryUtils.getItemsInOpenChest()) {
            if (slotList.contains(slot.slotIndex))
                slot highlight LorenzColor.GREEN
        }
    }

    @SubscribeEvent
    fun onItemTooltipLow(event: ItemTooltipEvent) {
        if (!isShowPriceEnabled()) return

        val itemStack = event.itemStack ?: return

        val baseMotes = itemStack.motesNpcPrice() ?: return
        val burgerStacks = config.burgerStacks
        val burgerText = if (burgerStacks > 0) "(${burgerStacks}x≡) " else ""
        val size = itemStack.stackSize
        if (size > 1) {
            event.toolTip.add("§6NPC price: $burgerText§d${baseMotes.addSeparators()} Motes §7($size x §d${(baseMotes / size).addSeparators()} Motes§7)")
        } else {
            event.toolTip.add("§6NPC price: $burgerText§d${baseMotes.addSeparators()} Motes")
        }
    }

    @SubscribeEvent
    fun onInventoryOpen(event: InventoryOpenEvent) {
        reset()
    }

    @SubscribeEvent
    fun onInventoryClose(event: InventoryCloseEvent) {
        reset()
    }

    private fun reset() {
        if (!isInventoryValueEnabled()) return
        itemMap.clear()
        slotList.clear()
        inInventory = false
    }

    private fun processItems() {
        val inventoryName = InventoryUtils.openInventoryName()
        if (!inventoryName.contains("Rift Storage")) return
        val stacks = InventoryUtils.getItemsInOpenChest().map { it.slotIndex to it.stack }
        itemMap.clear()
        for ((index, stack) in stacks) {
            val itemValue = stack.motesNpcPrice() ?: continue
            if (itemMap.contains(stack.getInternalName())) {
                val (oldIndex, oldValue) = itemMap[stack.getInternalName()] ?: return
                oldIndex.add(index)
                itemMap[stack.getInternalName()] = Pair(oldIndex, oldValue + itemValue)
            } else {
                itemMap[stack.getInternalName()] = Pair(mutableListOf(index), itemValue)
            }
        }
        inInventory = true
        update()
    }

    @SubscribeEvent
    fun onChat(event: LorenzChatEvent) {
        if (!RiftAPI.inRift()) return
        pattern.matchMatcher(event.message) {
            config.burgerStacks = group("amount").toInt()
            chat("§6[SkyHanni] Set your McGrubber's burger stacks to ${group("amount")}.")
        }
    }

    private fun update() {
        display = drawDisplay()
    }

    private fun drawDisplay() = buildList<List<Any>> {
        val newDisplay = mutableListOf<List<Any>>()
        newDisplay.addAsSingletonList("§7Item Values:")
        val sorted = itemMap.toList().sortedByDescending { it.second.second }.toMap().toMutableMap()

        for ((internalName, pair) in sorted) {
            newDisplay.add(buildList {
                val (index, value) = pair
                val dashColor = if (slotList.containsAll(index)) "§a" else "§7"
                add("  $dashColor- ")
                val stack = NEUItems.getItemStack(internalName)
                add(stack)
                val price = value.formatPrice()
                val valuePer = stack.motesNpcPrice() ?: continue
                val tips = buildList {
                    add("§eClick to highlight in the chest !")
                    add("§6Value per: §d$valuePer Motes")
                    add("§6Total in chest: §d${(value / valuePer).toInt()}")
                }
                add(Renderable.clickAndHover("§6${stack.displayName}: §b$price", tips) {
                    for (slot in InventoryUtils.getItemsInOpenChest()) {
                        if (index.contains(slot.slotIndex)) {
                            if (slotList.contains(slot.slotIndex)) {
                                slotList.remove(slot.slotIndex)
                            } else {
                                slotList.add(slot.slotIndex)
                            }
                        }
                    }
                })
            })
        }
        val total = itemMap.values.fold(0.0) { acc, pair -> acc + pair.second }.formatPrice()
        newDisplay.addAsSingletonList("§7Total price: §b$total")
        val name = FormatType.values()[config.inventoryValue.formatType].type
        newDisplay.addAsSingletonList("§7Price format: §c$name")
        newDisplay.addSelector(" ", FormatType.values(),
            getName = { type -> type.type },
            isCurrent = { it.ordinal == config.inventoryValue.formatType },
            onChange = {
                config.inventoryValue.formatType = it.ordinal
                update()
            })
        return newDisplay
    }

    enum class FormatType(val type: String) {
        SHORT("Short"),
        LONG("Long")
    }

    private fun Double.formatPrice(): String = when (config.inventoryValue.formatType) {
        0 -> NumberUtil.format(this)
        1 -> this.addSeparators()
        else -> "0"
    }

    private fun isShowPriceEnabled() = RiftAPI.inRift() && config.showPrice

    private fun isInventoryValueEnabled() = RiftAPI.inRift() && config.inventoryValue.enabled
}