comparison ui/GearComparisonTab.lua @ 17:e77e01abce98

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