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