adam@17
|
1 local _, AskMrRobot = ...
|
adam@17
|
2 local L = AskMrRobot.L;
|
adam@17
|
3
|
adam@17
|
4 -- initialize the GearComparisonTab class
|
adam@17
|
5 AskMrRobot.GearComparisonTab = AskMrRobot.inheritsFrom(AskMrRobot.Frame)
|
adam@17
|
6
|
adam@17
|
7 -- stores the results of the last gear comparison
|
adam@17
|
8 AskMrRobot.ComparisonResult = {
|
adam@17
|
9 items = {},
|
adam@17
|
10 gems = {},
|
adam@17
|
11 enchants = {}
|
adam@17
|
12 }
|
adam@17
|
13
|
adam@17
|
14 local function createTabButton(tab, text, index)
|
adam@17
|
15 local button = CreateFrame("Button", "GearComparisonTab" .. index, tab, "TabButtonTemplate")
|
adam@17
|
16 if index == 1 then
|
adam@17
|
17 button:SetPoint("TOPLEFT")
|
adam@17
|
18 else
|
adam@17
|
19 button:SetPoint("LEFT", "GearComparisonTab" .. (index - 1), "RIGHT")
|
adam@17
|
20 end
|
adam@17
|
21
|
adam@17
|
22 button:SetText(text)
|
adam@17
|
23 button:SetWidth(50)
|
adam@17
|
24 button:SetHeight(20)
|
adam@17
|
25 button:SetID(index)
|
adam@17
|
26 button:SetScript("OnClick", AskMrRobot.GearComparisonTab.tabButtonClick)
|
adam@17
|
27 return button
|
adam@17
|
28 end
|
adam@17
|
29
|
adam@17
|
30 function AskMrRobot.GearComparisonTab:tabButtonClick()
|
adam@17
|
31 local tab = self:GetParent()
|
adam@17
|
32 local id = self:GetID()
|
adam@17
|
33 PanelTemplates_SetTab(tab, id)
|
adam@17
|
34 for i = 1, #tab.tabs do
|
adam@17
|
35 local t = tab.tabs[i]
|
adam@17
|
36 if t:GetID() == id then
|
adam@17
|
37 t:Show()
|
adam@17
|
38 else
|
adam@17
|
39 t:Hide()
|
adam@17
|
40 end
|
adam@17
|
41 end
|
adam@17
|
42 end
|
adam@17
|
43
|
adam@17
|
44 function AskMrRobot.GearComparisonTab:new(parent)
|
adam@17
|
45
|
adam@17
|
46 local tab = AskMrRobot.Frame:new("GearComparison", parent)
|
adam@17
|
47 setmetatable(tab, { __index = AskMrRobot.GearComparisonTab })
|
adam@17
|
48 tab:SetPoint("TOPLEFT")
|
adam@17
|
49 tab:SetPoint("BOTTOMRIGHT")
|
adam@17
|
50 tab:Hide()
|
adam@17
|
51
|
adam@17
|
52 tab.initialized = false
|
adam@17
|
53
|
adam@17
|
54 tab.tabButtons = {
|
adam@17
|
55 createTabButton(tab, L.AMR_UI_BUTTON_IMPORT, 1),
|
adam@17
|
56 createTabButton(tab, L.AMR_UI_BUTTON_SUMMARY, 2),
|
adam@17
|
57 createTabButton(tab, L.AMR_UI_BUTTON_GEMS, 3),
|
adam@17
|
58 createTabButton(tab, L.AMR_UI_BUTTON_ENCHANTS, 4),
|
adam@17
|
59 createTabButton(tab, L.AMR_UI_BUTTON_SHOPPING_LIST, 5)
|
adam@17
|
60 }
|
adam@17
|
61
|
adam@17
|
62 PanelTemplates_SetNumTabs(tab, 5)
|
adam@17
|
63 PanelTemplates_SetTab(tab, 1)
|
adam@17
|
64 for i = 1, #tab.tabButtons do
|
adam@17
|
65 PanelTemplates_TabResize(tab.tabButtons[i], 0)
|
adam@17
|
66 end
|
adam@17
|
67
|
adam@17
|
68 PanelTemplates_DisableTab(tab, 2)
|
adam@17
|
69 PanelTemplates_DisableTab(tab, 3)
|
adam@17
|
70 PanelTemplates_DisableTab(tab, 4)
|
adam@17
|
71 PanelTemplates_DisableTab(tab, 5)
|
adam@17
|
72
|
adam@17
|
73 -- create the import tab
|
adam@17
|
74 tab.importTab = AskMrRobot.ImportTab:new(tab)
|
adam@17
|
75 tab.importTab:SetID(1)
|
adam@17
|
76
|
adam@17
|
77 -- set the tab left of the tab
|
adam@17
|
78 tab.importTab:SetPoint("TOPLEFT", tab, "TOPLEFT", 0, -30)
|
adam@17
|
79
|
adam@17
|
80 tab.summaryTab = AskMrRobot.SummaryTab:new(tab)
|
adam@17
|
81 tab.summaryTab:SetID(2)
|
adam@17
|
82 tab.summaryTab:SetPoint("TOPLEFT", tab, "TOPLEFT", 0, -30)
|
adam@17
|
83
|
adam@17
|
84 tab.gemTab = AskMrRobot.GemTab:new(tab)
|
adam@17
|
85 tab.gemTab:SetID(3)
|
adam@17
|
86 tab.gemTab:SetPoint("TOPLEFT", tab, "TOPLEFT", 0, -30)
|
adam@17
|
87
|
adam@17
|
88 tab.enchantTab = AskMrRobot.EnchantTab:new(tab)
|
adam@17
|
89 tab.enchantTab:SetID(4)
|
adam@17
|
90 tab.enchantTab:SetPoint("TOPLEFT", tab, "TOPLEFT", 0, -30)
|
adam@17
|
91
|
adam@17
|
92 tab.shoppingTab = AskMrRobot.ShoppingListTab:new(tab)
|
adam@17
|
93 tab.shoppingTab:SetID(5)
|
adam@17
|
94 tab.shoppingTab:SetPoint("TOPLEFT", tab, "TOPLEFT", 0, -30)
|
adam@17
|
95
|
adam@17
|
96 tab.tabs = {tab.importTab, tab.summaryTab, tab.gemTab, tab.enchantTab, tab.shoppingTab}
|
adam@17
|
97
|
adam@17
|
98 -- show the first tab
|
adam@17
|
99 tab.importTab:Show()
|
adam@17
|
100
|
adam@17
|
101 -- setup the import button to run the import
|
adam@17
|
102 tab.importTab.button:SetScript("OnClick", function()
|
adam@17
|
103 tab:Import()
|
adam@17
|
104 tab.tabButtonClick(tab.tabButtons[2])
|
adam@17
|
105 end)
|
adam@17
|
106
|
adam@17
|
107 tab:SetScript("OnShow", AskMrRobot.GearComparisonTab.OnShow)
|
adam@17
|
108
|
adam@17
|
109 --tab:RegisterEvent("ITEM_PUSH")
|
adam@17
|
110 --tab:RegisterEvent("DELETE_ITEM_CONFIRM")
|
adam@17
|
111 tab:RegisterEvent("SOCKET_INFO_CLOSE")
|
adam@17
|
112 tab:RegisterEvent("SOCKET_INFO_UPDATE")
|
adam@17
|
113 tab:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED")
|
adam@17
|
114 tab:RegisterEvent("BAG_UPDATE")
|
adam@17
|
115
|
adam@17
|
116 tab:SetScript("OnEvent", AskMrRobot.GearComparisonTab.OnEvent)
|
adam@17
|
117
|
adam@17
|
118 return tab
|
adam@17
|
119 end
|
adam@17
|
120
|
adam@17
|
121 function AskMrRobot.GearComparisonTab:On_SOCKET_INFO_CLOSE()
|
yellowfive@31
|
122 if self.initialized then
|
yellowfive@31
|
123 self:Import()
|
yellowfive@31
|
124 end
|
adam@17
|
125 end
|
adam@17
|
126
|
adam@17
|
127 function AskMrRobot.GearComparisonTab:On_SOCKET_INFO_UPDATE()
|
yellowfive@31
|
128 if self.initialized then
|
yellowfive@31
|
129 self:Import()
|
yellowfive@31
|
130 end
|
adam@17
|
131 end
|
adam@17
|
132
|
adam@17
|
133 function AskMrRobot.GearComparisonTab:On_PLAYER_SPECIALIZATION_CHANGED()
|
yellowfive@31
|
134 if self.initialized then
|
yellowfive@31
|
135 self:Import()
|
yellowfive@31
|
136 end
|
adam@17
|
137 end
|
adam@17
|
138
|
adam@17
|
139 function AskMrRobot.GearComparisonTab:On_BAG_UPDATE()
|
yellowfive@31
|
140 if self.initialized then
|
yellowfive@31
|
141 self:Import()
|
yellowfive@31
|
142 end
|
adam@17
|
143 end
|
adam@17
|
144
|
adam@17
|
145 function AskMrRobot.GearComparisonTab:On_ITEM_PUSH()
|
yellowfive@31
|
146 if self.initialized then
|
yellowfive@31
|
147 self:Import()
|
yellowfive@31
|
148 end
|
adam@17
|
149 end
|
adam@17
|
150
|
adam@17
|
151 function AskMrRobot.GearComparisonTab:On_DELETE_ITEM_CONFIRM()
|
yellowfive@31
|
152 if self.initialized then
|
yellowfive@31
|
153 self:Import()
|
yellowfive@31
|
154 end
|
adam@17
|
155 end
|
adam@17
|
156
|
adam@17
|
157 function AskMrRobot.GearComparisonTab:OnShow()
|
adam@17
|
158 if not self.initialized then
|
adam@17
|
159 self.initialized = true
|
adam@17
|
160
|
adam@17
|
161 -- on first show, load the last import
|
adam@17
|
162 if AmrDb.LastCharacterImport and AmrDb.LastCharacterImport ~= "" then
|
adam@17
|
163 self.importTab:SetImportText(AmrDb.LastCharacterImport)
|
adam@17
|
164 self:Import()
|
yellowfive@31
|
165 self.tabButtonClick(self.tabButtons[2])
|
adam@17
|
166 else
|
adam@17
|
167 self:Update()
|
adam@17
|
168 end
|
adam@17
|
169 else
|
adam@17
|
170 self:Update()
|
adam@17
|
171 end
|
adam@17
|
172 end
|
adam@17
|
173
|
adam@17
|
174 function AskMrRobot.GearComparisonTab:Import()
|
adam@17
|
175
|
yellowfive@31
|
176 local err = AskMrRobot.ImportCharacter(self.importTab:GetImportText(), AskMrRobot.debug)
|
adam@17
|
177 -- goto the summary tab
|
adam@17
|
178 self.summaryTab:showImportError(err)
|
adam@17
|
179 PanelTemplates_EnableTab(self, 2)
|
adam@17
|
180 if err then
|
adam@17
|
181 PanelTemplates_DisableTab(self, 3)
|
adam@17
|
182 PanelTemplates_DisableTab(self, 4)
|
adam@17
|
183 PanelTemplates_DisableTab(self, 5)
|
adam@17
|
184 else
|
adam@17
|
185 PanelTemplates_EnableTab(self, 3)
|
adam@17
|
186 PanelTemplates_EnableTab(self, 4)
|
adam@17
|
187 PanelTemplates_EnableTab(self, 5)
|
adam@17
|
188 self:Update()
|
adam@17
|
189 end
|
adam@17
|
190 end
|
adam@17
|
191
|
adam@17
|
192 -- update the panel and state
|
adam@17
|
193 function AskMrRobot.GearComparisonTab:Update()
|
adam@17
|
194 -- update the comparison
|
adam@17
|
195 if self.summaryTab then
|
adam@17
|
196 AskMrRobot.GearComparisonTab.Compare()
|
adam@17
|
197 self.summaryTab:showBadItems()
|
adam@17
|
198 self.gemTab:Update()
|
adam@17
|
199 self.enchantTab:Update()
|
adam@17
|
200 self.shoppingTab:Update()
|
adam@17
|
201 end
|
adam@17
|
202 end
|
adam@17
|
203
|
adam@17
|
204
|
adam@17
|
205 -- Helper for checking for swapped items, returns a number indicating how different two items are (0 means the same, higher means more different)
|
adam@17
|
206 local function countItemDifferences(item1, item2)
|
adam@17
|
207 if item1 == nil and item2 == nil then return 0 end
|
adam@17
|
208
|
adam@17
|
209 -- different items (id + bonus ids + suffix, constitutes a different physical drop)
|
adam@17
|
210 if AskMrRobot.getItemUniqueId(item1, true) ~= AskMrRobot.getItemUniqueId(item2, true) then
|
adam@17
|
211 if item1 == nil or item2 == nil then return 1000 end
|
adam@17
|
212 -- do a check to deal with SoO item variants, see if we have duplicate ID information
|
adam@17
|
213 local info = AskMrRobot.ExtraItemData[item2.id]
|
adam@17
|
214 if info == nil then
|
adam@17
|
215 info = AskMrRobot.ExtraItemData[item1.id]
|
adam@17
|
216 if info == nil or info.duplicateId ~= item2.id then
|
adam@17
|
217 return 1000
|
adam@17
|
218 end
|
adam@17
|
219 elseif info.duplicateId ~= item1.id then
|
adam@17
|
220 return 1000
|
adam@17
|
221 end
|
adam@17
|
222 end
|
adam@17
|
223
|
adam@17
|
224 -- different upgrade levels of the same item (only for older gear, player has control over upgrade level)
|
adam@17
|
225 if item1.upgradeId ~= item2.upgradeId then
|
adam@17
|
226 return 100
|
adam@17
|
227 end
|
adam@17
|
228
|
adam@17
|
229 -- different gems
|
adam@17
|
230 local gemDiffs = 0
|
adam@17
|
231 for i = 1, 3 do
|
adam@17
|
232 if item1.gemIds[i] ~= item2.gemIds[i] then
|
adam@17
|
233 gemDiffs = gemDiffs + 1
|
adam@17
|
234 end
|
adam@17
|
235 end
|
adam@17
|
236
|
adam@17
|
237 local enchantDiff = 0
|
adam@17
|
238 if item1.enchantId ~= item2.enchantId then
|
adam@17
|
239 enchantDiff = 1
|
adam@17
|
240 end
|
adam@17
|
241
|
adam@17
|
242 return gemDiffs + enchantDiff
|
adam@17
|
243 end
|
adam@17
|
244
|
adam@17
|
245 function AskMrRobot.GearComparisonTab:OnEvent(event, ...)
|
adam@17
|
246 local handler = self["On_" .. event]
|
adam@17
|
247 if handler then
|
adam@17
|
248 handler(self, ...)
|
adam@17
|
249 end
|
adam@17
|
250 end
|
adam@17
|
251
|
adam@17
|
252 -- modifies data2 such that differences between data1 and data2 in the two specified slots is the smallest
|
adam@17
|
253 local function checkSwappedItems(data1, data2, slot1, slot2)
|
adam@17
|
254 local diff = countItemDifferences(data1[slot1], data2[slot1]) + countItemDifferences(data1[slot2], data2[slot2])
|
adam@17
|
255 local swappedDiff
|
adam@17
|
256 if diff > 0 then
|
adam@17
|
257 swappedDiff = countItemDifferences(data1[slot1], data2[slot2]) + countItemDifferences(data1[slot2], data2[slot1])
|
adam@17
|
258 if swappedDiff < diff then
|
adam@17
|
259 local temp = data2[slot1]
|
adam@17
|
260 data2[slot1] = data2[slot2]
|
adam@17
|
261 data2[slot2] = temp
|
adam@17
|
262 end
|
adam@17
|
263 end
|
adam@17
|
264 end
|
adam@17
|
265
|
adam@17
|
266 -- compare the last import data to the player's current state
|
adam@17
|
267 function AskMrRobot.GearComparisonTab.Compare()
|
adam@17
|
268 if not AskMrRobot.ImportData then return end
|
adam@17
|
269
|
adam@17
|
270 AskMrRobot.SaveAll()
|
adam@17
|
271
|
adam@17
|
272 -- first parse the player's equipped gear into item objects
|
adam@17
|
273 local equipped = {}
|
adam@17
|
274 for k, v in pairs(AmrDb.Equipped[AmrDb.ActiveSpec]) do
|
adam@17
|
275 equipped[k] = AskMrRobot.parseItemLink(v)
|
adam@17
|
276 end
|
adam@17
|
277
|
adam@17
|
278 -- swap finger/trinket in AskMrRobot.ImportData such that the number of differences is the smallest
|
adam@17
|
279 checkSwappedItems(equipped, AskMrRobot.ImportData, INVSLOT_FINGER1, INVSLOT_FINGER2)
|
adam@17
|
280 checkSwappedItems(equipped, AskMrRobot.ImportData, INVSLOT_TRINKET1, INVSLOT_TRINKET2)
|
adam@17
|
281
|
adam@17
|
282 -- clear previous comparison result
|
adam@17
|
283 AskMrRobot.ComparisonResult = {
|
adam@17
|
284 items = {},
|
adam@17
|
285 gems = {},
|
adam@17
|
286 enchants = {}
|
adam@17
|
287 }
|
adam@17
|
288
|
adam@17
|
289 local result = {
|
adam@17
|
290 items = {},
|
adam@17
|
291 gems = {},
|
adam@17
|
292 enchants = {}
|
adam@17
|
293 }
|
adam@17
|
294
|
adam@17
|
295 -- determine specific differences
|
adam@17
|
296 for i,slotId in ipairs(AskMrRobot.slotIds) do
|
adam@17
|
297 local itemEquipped = equipped[slotId]
|
adam@17
|
298 local itemImported = AskMrRobot.ImportData[slotId]
|
adam@17
|
299
|
adam@17
|
300 local itemsDifferent = AskMrRobot.getItemUniqueId(itemEquipped) ~= AskMrRobot.getItemUniqueId(itemImported)
|
adam@17
|
301 if itemsDifferent and itemEquipped ~= nil and itemImported ~= nil then
|
adam@17
|
302 -- do an extra check for old versions of SoO items, our server code always converts to new, equivalent version, but need to check backwards for the addon
|
adam@17
|
303 local info = AskMrRobot.ExtraItemData[itemImported.id]
|
adam@17
|
304 if info and info.duplicateId == itemEquipped.id then
|
adam@17
|
305 itemsDifferent = false
|
adam@17
|
306 end
|
adam@17
|
307 end
|
adam@17
|
308
|
adam@17
|
309 if itemsDifferent then
|
adam@17
|
310 -- the items are different
|
adam@17
|
311 local needsUpgrade = false
|
adam@17
|
312 if itemEquipped and itemImported and itemEquipped.id == itemImported.id and itemImported.upgradeId > itemEquipped.upgradeId then
|
adam@17
|
313 needsUpgrade = true
|
adam@17
|
314 end
|
adam@17
|
315 result.items[slotId] = {
|
adam@17
|
316 current = itemEquipped,
|
adam@17
|
317 optimized = itemImported,
|
adam@17
|
318 needsUpgrade = needsUpgrade
|
adam@17
|
319 }
|
adam@17
|
320 elseif itemEquipped then
|
adam@17
|
321 if AskMrRobot.ExtraItemData[itemEquipped.id] and AskMrRobot.ExtraItemData[itemEquipped.id].socketColors then
|
adam@17
|
322 -- items are same, check for gem/enchant differences
|
adam@17
|
323 -- NOTE: we used to do a bunch of fancy gem checks, but we can ditch all that logic b/c WoD gems are much simpler (no socket bonuses, gem/socket colors to worry about)
|
adam@17
|
324 local hasBadGems = false
|
adam@17
|
325 for g = 1, #AskMrRobot.ExtraItemData[itemEquipped.id].socketColors do
|
adam@17
|
326 if not AskMrRobot.AreGemsCompatible(itemEquipped.gemIds[g], itemImported.gemIds[g]) then
|
adam@17
|
327 hasBadGems = true
|
adam@17
|
328 break
|
adam@17
|
329 end
|
adam@17
|
330 end
|
adam@17
|
331
|
adam@17
|
332 if hasBadGems then
|
adam@17
|
333 result.gems[slotId] = {
|
adam@17
|
334 current = {},
|
adam@17
|
335 optimized = {}
|
adam@17
|
336 }
|
adam@17
|
337
|
adam@17
|
338 for g = 1, #AskMrRobot.ExtraItemData[itemEquipped.id].socketColors do
|
adam@17
|
339 result.gems[slotId].current[g] = itemEquipped.gemIds[g]
|
adam@17
|
340 result.gems[slotId].optimized[g] = itemImported.gemIds[g]
|
adam@17
|
341 end
|
adam@17
|
342 end
|
adam@17
|
343 end
|
adam@17
|
344
|
adam@17
|
345 if itemEquipped.enchantId ~= itemImported.enchantId then
|
adam@17
|
346 result.enchants[slotId] = {
|
adam@17
|
347 current = itemEquipped.enchantId,
|
adam@17
|
348 optimized = itemImported.enchantId
|
adam@17
|
349 }
|
adam@17
|
350 end
|
adam@17
|
351 end
|
adam@17
|
352 end
|
adam@17
|
353
|
adam@17
|
354 -- only set the new result if it is completely successful
|
adam@17
|
355 AskMrRobot.ComparisonResult = result
|
adam@17
|
356 end
|
adam@17
|
357
|
adam@17
|
358 -- checks our extra gem information to see if the two gems are functionally equivalent
|
adam@17
|
359 function AskMrRobot.AreGemsCompatible(gemId1, gemId2)
|
adam@17
|
360 if gemId1 == gemId2 then return true end
|
adam@17
|
361
|
adam@17
|
362 -- see if we have extra gem information
|
adam@17
|
363 local extraInfo = AskMrRobot.ExtraGemData[gemId1]
|
adam@17
|
364 if not extraInfo then
|
adam@17
|
365 extraInfo = AskMrRobot.ExtraGemData[gemId2]
|
adam@17
|
366 end
|
adam@17
|
367 if extraInfo == nil or extraInfo.identicalGroup == nil then return false end
|
adam@17
|
368
|
adam@17
|
369 -- if identicalGroup contains both gem ids, they are equivalent
|
adam@17
|
370 return extraInfo.identicalGroup[gemId1] and extraInfo.identicalGroup[gemId2]
|
adam@17
|
371 end |