-
Notifications
You must be signed in to change notification settings - Fork 7
/
CataReforgeDetection.lua
244 lines (218 loc) · 8.64 KB
/
CataReforgeDetection.lua
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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
local Env = select(2, ...)
-- Map stat IDs used in reforging to their localised (tooltip) strings.
---@type table<integer, {statString:string, statStringNoVar:string}>
local statIdToStrings = {
[6] = { statString = ITEM_MOD_SPIRIT_SHORT }, -- Spirit
[13] = { statString = ITEM_MOD_DODGE_RATING }, -- Increases your dodge rating by %s.
[14] = { statString = ITEM_MOD_PARRY_RATING }, -- Increases your parry rating by %s.
[31] = { statString = ITEM_MOD_HIT_RATING }, -- Improves hit rating by %s.
[32] = { statString = ITEM_MOD_CRIT_RATING }, -- Improves critical strike rating by %s.
[36] = { statString = ITEM_MOD_HASTE_RATING }, -- Improves haste rating by %s.
[37] = { statString = ITEM_MOD_EXPERTISE_RATING }, -- Increases your expertise rating by %s.
[49] = { statString = ITEM_MOD_MASTERY_RATING_SHORT }, -- Mastery
}
-- Add strings without the placeholder.
for _, v in pairs(statIdToStrings) do
v.statStringNoVar = v.statString:format(".-")
end
-- Map localised strings to stat IDs.
local statStringToId = (function()
---@type table<string, integer>
local t = {}
for id, v in pairs(statIdToStrings) do
t[v.statString] = id
end
return t
end)()
---Table of reforgeIds and the corresponding src and dest stat ID.
---@type table<integer, {srcStat:integer, destStat:integer}>
local reforges = {
[113] = { srcStat = 6, destStat = 13 },
[114] = { srcStat = 6, destStat = 14 },
[115] = { srcStat = 6, destStat = 31 },
[116] = { srcStat = 6, destStat = 32 },
[117] = { srcStat = 6, destStat = 36 },
[118] = { srcStat = 6, destStat = 37 },
[119] = { srcStat = 6, destStat = 49 },
[120] = { srcStat = 13, destStat = 6 },
[121] = { srcStat = 13, destStat = 14 },
[122] = { srcStat = 13, destStat = 31 },
[123] = { srcStat = 13, destStat = 32 },
[124] = { srcStat = 13, destStat = 36 },
[125] = { srcStat = 13, destStat = 37 },
[126] = { srcStat = 13, destStat = 49 },
[127] = { srcStat = 14, destStat = 6 },
[128] = { srcStat = 14, destStat = 13 },
[129] = { srcStat = 14, destStat = 31 },
[130] = { srcStat = 14, destStat = 32 },
[131] = { srcStat = 14, destStat = 36 },
[132] = { srcStat = 14, destStat = 37 },
[133] = { srcStat = 14, destStat = 49 },
[134] = { srcStat = 31, destStat = 6 },
[135] = { srcStat = 31, destStat = 13 },
[136] = { srcStat = 31, destStat = 14 },
[137] = { srcStat = 31, destStat = 32 },
[138] = { srcStat = 31, destStat = 36 },
[139] = { srcStat = 31, destStat = 37 },
[140] = { srcStat = 31, destStat = 49 },
[141] = { srcStat = 32, destStat = 6 },
[142] = { srcStat = 32, destStat = 13 },
[143] = { srcStat = 32, destStat = 14 },
[144] = { srcStat = 32, destStat = 31 },
[145] = { srcStat = 32, destStat = 36 },
[146] = { srcStat = 32, destStat = 37 },
[147] = { srcStat = 32, destStat = 49 },
[148] = { srcStat = 36, destStat = 6 },
[149] = { srcStat = 36, destStat = 13 },
[150] = { srcStat = 36, destStat = 14 },
[151] = { srcStat = 36, destStat = 31 },
[152] = { srcStat = 36, destStat = 32 },
[153] = { srcStat = 36, destStat = 37 },
[154] = { srcStat = 36, destStat = 49 },
[155] = { srcStat = 37, destStat = 6 },
[156] = { srcStat = 37, destStat = 13 },
[157] = { srcStat = 37, destStat = 14 },
[158] = { srcStat = 37, destStat = 31 },
[159] = { srcStat = 37, destStat = 32 },
[160] = { srcStat = 37, destStat = 36 },
[161] = { srcStat = 37, destStat = 49 },
[162] = { srcStat = 49, destStat = 6 },
[163] = { srcStat = 49, destStat = 13 },
[164] = { srcStat = 49, destStat = 14 },
[165] = { srcStat = 49, destStat = 31 },
[166] = { srcStat = 49, destStat = 32 },
[167] = { srcStat = 49, destStat = 36 },
[168] = { srcStat = 49, destStat = 37 },
}
--------------------------------------------------------
-- Item stat functions
--------------------------------------------------------
---Get table of stat IDs used in reforging and their default value for an item.
---@param unit string
---@param itemSlot integer
---@return table<integer, number>
local function GetItemDefaultStats(unit, itemSlot)
local itemLink = GetInventoryItemLink(unit, itemSlot)
local stats = GetItemStats(itemLink)
local defaultStats = {}
for statStringConstName, value in pairs(stats) do
local statString = _G[statStringConstName]
local statId = statStringToId[statString]
if statId then
defaultStats[statId] = value
end
end
return defaultStats
end
CreateFrame("GameTooltip", "WSEScanningTooltip", nil, "GameTooltipTemplate")
WSEScanningTooltip:SetOwner(WorldFrame, "ANCHOR_NONE")
local baseItemLink = "item:9333:"
C_Item.RequestLoadItemDataByID(baseItemLink)
---@return table<integer, string>
local function GetBaseItemText()
WSEScanningTooltip:ClearLines()
WSEScanningTooltip:SetHyperlink(baseItemLink)
local regions = { WSEScanningTooltip:GetRegions() }
local itemText = {}
for i = 1, #regions do
local region = regions[i]
if region and region:GetObjectType() == "FontString" then
local text = region:GetText()
if text then
itemText[i] = text
end
end
end
return itemText
end
local baseItemText
---Get the text of an item's enchant as it will appear in the tooltip
---@param unit string
---@param itemSlot integer
---@return string
local function GetItemEnchantText(unit, itemSlot)
local itemLink = GetInventoryItemLink(unit, itemSlot)
local enchantID = itemLink:match("item:.-:(.-):")
if not baseItemText then
baseItemText = GetBaseItemText()
end
WSEScanningTooltip:ClearLines()
WSEScanningTooltip:SetHyperlink(baseItemLink .. enchantID)
local regions = { WSEScanningTooltip:GetRegions() }
for i = 1, #regions do
local region = regions[i]
if region and region:GetObjectType() == "FontString" then
local text = region:GetText()
if text and baseItemText[i] ~= text then
return text
end
end
end
return ""
end
local socketBonus = "^" .. ITEM_SOCKET_BONUS:format("")
---Parse stats used in reforging and their current value from item tooltip.
---@param unit string
---@param itemSlot integer
---@param enchantText string
---@return table<integer, number>
local function GetItemCurrentStats(unit, itemSlot, enchantText)
local currentStats = {}
WSEScanningTooltip:ClearLines()
WSEScanningTooltip:SetInventoryItem(unit, itemSlot)
local regions = { WSEScanningTooltip:GetRegions() }
for i = 1, #regions do
local region = regions[i]
if region and region:GetObjectType() == "FontString" then
local text = region:GetText()
if text and text ~= enchantText and not text:find(socketBonus) and not text:find("^|") then
for statId, v in pairs(statIdToStrings) do
local pos = text:find(v.statStringNoVar)
if pos then
local value = text:match("%d+")
currentStats[statId] = tonumber(value)
end
end
end
end
end
return currentStats
end
--------------------------------------------------------
-- Reforge detection
--------------------------------------------------------
---Attempt to get reforged src and dest stat.
---@param unit string
---@param itemSlot integer
local function GetItemReforgedStats(unit, itemSlot)
local enchantText = GetItemEnchantText(unit, itemSlot)
local statsCurrent = GetItemCurrentStats(unit, itemSlot, enchantText)
local statsDefault = GetItemDefaultStats(unit, itemSlot)
-- Find src stat, i.e. the reduced default stat
for statId, baseValue in pairs(statsDefault) do
local currentValue = statsCurrent[statId]
if currentValue and currentValue < baseValue then
-- Find dest stat, i.e. the stat that does not exist by default
for destStatId in pairs(statsCurrent) do
if not statsDefault[destStatId] then
return statId, destStatId
end
end
break
end
end
end
---Try to get the reforge ID for an item.
---@param unit string
---@param itemSlot integer
---@return integer|nil
function Env.GetReforgeId(unit, itemSlot)
local srcId, destId = GetItemReforgedStats(unit, itemSlot)
if srcId and destId then
for reforgeId, v in pairs(reforges) do
if v.srcStat == srcId and v.destStat == destId then
return reforgeId
end
end
end
end