diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/GearComparisonTab.lua	Mon Oct 13 21:28:32 2014 -0500
@@ -0,0 +1,361 @@
+local _, AskMrRobot = ...
+local L = AskMrRobot.L;
+
+-- initialize the GearComparisonTab class
+AskMrRobot.GearComparisonTab = AskMrRobot.inheritsFrom(AskMrRobot.Frame)
+
+-- stores the results of the last gear comparison
+AskMrRobot.ComparisonResult = {
+    items = {},
+    gems = {},
+    enchants = {}
+}
+
+local function createTabButton(tab, text, index)
+    local button = CreateFrame("Button", "GearComparisonTab" .. index, tab, "TabButtonTemplate")
+    if  index == 1 then
+        button:SetPoint("TOPLEFT")
+    else
+        button:SetPoint("LEFT", "GearComparisonTab" .. (index - 1), "RIGHT")
+    end
+    
+    button:SetText(text)
+    button:SetWidth(50)
+    button:SetHeight(20)
+    button:SetID(index)
+    button:SetScript("OnClick", AskMrRobot.GearComparisonTab.tabButtonClick)
+    return button
+end
+
+function AskMrRobot.GearComparisonTab:tabButtonClick()
+    local tab = self:GetParent()
+    local id = self:GetID()
+    PanelTemplates_SetTab(tab, id)
+    for i = 1, #tab.tabs do
+        local t = tab.tabs[i]
+        if t:GetID() == id then
+            t:Show()
+        else
+            t:Hide()
+        end
+    end
+end
+
+function AskMrRobot.GearComparisonTab:new(parent)
+
+	local tab = AskMrRobot.Frame:new("GearComparison", parent)	
+	setmetatable(tab, { __index = AskMrRobot.GearComparisonTab })
+	tab:SetPoint("TOPLEFT")
+	tab:SetPoint("BOTTOMRIGHT")
+	tab:Hide()
+    
+    tab.initialized = false
+
+    tab.tabButtons = {
+        createTabButton(tab, L.AMR_UI_BUTTON_IMPORT, 1),
+        createTabButton(tab, L.AMR_UI_BUTTON_SUMMARY, 2),
+        createTabButton(tab, L.AMR_UI_BUTTON_GEMS, 3),
+        createTabButton(tab, L.AMR_UI_BUTTON_ENCHANTS, 4),
+        createTabButton(tab, L.AMR_UI_BUTTON_SHOPPING_LIST, 5)
+    }
+
+    PanelTemplates_SetNumTabs(tab, 5)
+    PanelTemplates_SetTab(tab, 1)
+    for i = 1, #tab.tabButtons do
+        PanelTemplates_TabResize(tab.tabButtons[i], 0)
+    end
+   
+    PanelTemplates_DisableTab(tab, 2)
+    PanelTemplates_DisableTab(tab, 3)
+    PanelTemplates_DisableTab(tab, 4)
+    PanelTemplates_DisableTab(tab, 5)
+
+    -- create the import tab
+    tab.importTab = AskMrRobot.ImportTab:new(tab)
+    tab.importTab:SetID(1)
+
+    -- set the tab left of the tab
+    tab.importTab:SetPoint("TOPLEFT", tab, "TOPLEFT", 0, -30)
+
+    tab.summaryTab = AskMrRobot.SummaryTab:new(tab)
+    tab.summaryTab:SetID(2)
+    tab.summaryTab:SetPoint("TOPLEFT", tab, "TOPLEFT", 0, -30)
+
+    tab.gemTab = AskMrRobot.GemTab:new(tab)
+    tab.gemTab:SetID(3)
+    tab.gemTab:SetPoint("TOPLEFT", tab, "TOPLEFT", 0, -30)
+
+    tab.enchantTab = AskMrRobot.EnchantTab:new(tab)
+    tab.enchantTab:SetID(4)
+    tab.enchantTab:SetPoint("TOPLEFT", tab, "TOPLEFT", 0, -30)
+
+    tab.shoppingTab = AskMrRobot.ShoppingListTab:new(tab)
+    tab.shoppingTab:SetID(5)
+    tab.shoppingTab:SetPoint("TOPLEFT", tab, "TOPLEFT", 0, -30)
+
+    tab.tabs = {tab.importTab, tab.summaryTab, tab.gemTab, tab.enchantTab, tab.shoppingTab}
+
+    -- show the first tab
+    tab.importTab:Show()
+
+    -- setup the import button to run the import
+    tab.importTab.button:SetScript("OnClick", function()
+        tab:Import()
+        tab.tabButtonClick(tab.tabButtons[2])
+    end)
+    
+    tab:SetScript("OnShow", AskMrRobot.GearComparisonTab.OnShow)
+    
+    --tab:RegisterEvent("ITEM_PUSH")
+    --tab:RegisterEvent("DELETE_ITEM_CONFIRM")
+    tab:RegisterEvent("SOCKET_INFO_CLOSE")
+    tab:RegisterEvent("SOCKET_INFO_UPDATE")
+    tab:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED")
+    tab:RegisterEvent("BAG_UPDATE")
+
+    tab:SetScript("OnEvent", AskMrRobot.GearComparisonTab.OnEvent)
+
+	return tab
+end
+
+function AskMrRobot.GearComparisonTab:On_SOCKET_INFO_CLOSE()
+    self:Import()
+end
+
+function AskMrRobot.GearComparisonTab:On_SOCKET_INFO_UPDATE()
+    self:Import()
+end
+
+function AskMrRobot.GearComparisonTab:On_PLAYER_SPECIALIZATION_CHANGED()
+    self:Import()
+end
+
+function AskMrRobot.GearComparisonTab:On_BAG_UPDATE()
+    self:Import()
+end
+
+function AskMrRobot.GearComparisonTab:On_ITEM_PUSH()
+    self:Import()
+end
+
+function AskMrRobot.GearComparisonTab:On_DELETE_ITEM_CONFIRM()
+    self:Import()
+end
+
+function AskMrRobot.GearComparisonTab:OnShow()
+    if not self.initialized then
+        self.initialized = true
+
+        -- on first show, load the last import
+        if AmrDb.LastCharacterImport and AmrDb.LastCharacterImport ~= "" then
+            self.importTab:SetImportText(AmrDb.LastCharacterImport)
+            self:Import()
+        else
+            self:Update()
+        end
+    else
+        self:Update()
+    end        
+end
+
+function AskMrRobot.GearComparisonTab:Import()
+
+    -- example string
+    -- $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 
+    
+    local err = AskMrRobot.ImportCharacter(self.importTab:GetImportText())
+    -- goto the summary tab
+    self.summaryTab:showImportError(err)
+    PanelTemplates_EnableTab(self, 2)
+    if err then
+        PanelTemplates_DisableTab(self, 3)
+        PanelTemplates_DisableTab(self, 4)
+        PanelTemplates_DisableTab(self, 5)
+    else
+        PanelTemplates_EnableTab(self, 3)
+        PanelTemplates_EnableTab(self, 4)
+        PanelTemplates_EnableTab(self, 5)
+        self:Update()
+    end
+end
+
+-- update the panel and state
+function AskMrRobot.GearComparisonTab:Update()
+    -- update the comparison
+    if self.summaryTab then
+        AskMrRobot.GearComparisonTab.Compare()   
+        self.summaryTab:showBadItems()
+        self.gemTab:Update()
+        self.enchantTab:Update()
+        self.shoppingTab:Update()
+    end
+end
+
+
+-- Helper for checking for swapped items, returns a number indicating how different two items are (0 means the same, higher means more different)
+local function countItemDifferences(item1, item2)
+    if item1 == nil and item2 == nil then return 0 end
+    
+    -- different items (id + bonus ids + suffix, constitutes a different physical drop)
+    if AskMrRobot.getItemUniqueId(item1, true) ~= AskMrRobot.getItemUniqueId(item2, true) then
+        if item1 == nil or item2 == nil then return 1000 end        
+        -- do a check to deal with SoO item variants, see if we have duplicate ID information
+        local info = AskMrRobot.ExtraItemData[item2.id]
+        if info == nil then
+            info = AskMrRobot.ExtraItemData[item1.id]
+            if info == nil or info.duplicateId ~= item2.id then
+                return 1000
+            end
+        elseif info.duplicateId ~= item1.id then
+            return 1000
+        end
+    end
+    
+    -- different upgrade levels of the same item (only for older gear, player has control over upgrade level)
+    if item1.upgradeId ~= item2.upgradeId then
+        return 100
+    end
+    
+    -- different gems
+    local gemDiffs = 0
+    for i = 1, 3 do
+        if item1.gemIds[i] ~= item2.gemIds[i] then
+            gemDiffs = gemDiffs + 1
+        end
+    end
+    
+    local enchantDiff = 0
+    if item1.enchantId ~= item2.enchantId then
+        enchantDiff = 1
+    end
+    
+    return gemDiffs + enchantDiff
+end
+
+function AskMrRobot.GearComparisonTab:OnEvent(event, ...)
+    local handler = self["On_" .. event]
+    if handler then
+        handler(self, ...)
+    end
+end
+
+-- modifies data2 such that differences between data1 and data2 in the two specified slots is the smallest
+local function checkSwappedItems(data1, data2, slot1, slot2)
+    local diff = countItemDifferences(data1[slot1], data2[slot1]) + countItemDifferences(data1[slot2], data2[slot2])
+    local swappedDiff
+    if diff > 0 then
+        swappedDiff = countItemDifferences(data1[slot1], data2[slot2]) + countItemDifferences(data1[slot2], data2[slot1])
+        if swappedDiff < diff then
+            local temp = data2[slot1]
+            data2[slot1] = data2[slot2]
+            data2[slot2] = temp
+        end
+    end
+end
+
+-- compare the last import data to the player's current state
+function AskMrRobot.GearComparisonTab.Compare()
+    if not AskMrRobot.ImportData then return end
+    
+    AskMrRobot.SaveAll()
+    
+    -- first parse the player's equipped gear into item objects
+    local equipped = {}
+    for k, v in pairs(AmrDb.Equipped[AmrDb.ActiveSpec]) do
+        equipped[k] = AskMrRobot.parseItemLink(v)
+    end
+    
+    -- swap finger/trinket in AskMrRobot.ImportData such that the number of differences is the smallest
+    checkSwappedItems(equipped, AskMrRobot.ImportData, INVSLOT_FINGER1, INVSLOT_FINGER2)
+    checkSwappedItems(equipped, AskMrRobot.ImportData, INVSLOT_TRINKET1, INVSLOT_TRINKET2)
+    
+    -- clear previous comparison result
+    AskMrRobot.ComparisonResult = {
+        items = {},
+        gems = {},
+        enchants = {}
+    }
+    
+    local result = {
+        items = {},
+        gems = {},
+        enchants = {}
+    }
+    
+    -- determine specific differences
+    for i,slotId in ipairs(AskMrRobot.slotIds) do
+        local itemEquipped = equipped[slotId]
+        local itemImported = AskMrRobot.ImportData[slotId]
+        
+        local itemsDifferent = AskMrRobot.getItemUniqueId(itemEquipped) ~= AskMrRobot.getItemUniqueId(itemImported)
+        if itemsDifferent and itemEquipped ~= nil and itemImported ~= nil then
+            -- 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
+            local info = AskMrRobot.ExtraItemData[itemImported.id]            
+            if info and info.duplicateId == itemEquipped.id then
+                itemsDifferent = false
+            end
+        end
+        
+        if itemsDifferent then
+            -- the items are different
+            local needsUpgrade = false
+            if itemEquipped and itemImported and itemEquipped.id == itemImported.id and itemImported.upgradeId > itemEquipped.upgradeId then
+                needsUpgrade = true
+            end
+            result.items[slotId] = {
+                current = itemEquipped,
+                optimized = itemImported,
+                needsUpgrade = needsUpgrade
+            }
+        elseif itemEquipped then
+            if AskMrRobot.ExtraItemData[itemEquipped.id] and AskMrRobot.ExtraItemData[itemEquipped.id].socketColors then
+            -- items are same, check for gem/enchant differences
+            --   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)
+                local hasBadGems = false
+                for g = 1, #AskMrRobot.ExtraItemData[itemEquipped.id].socketColors do
+                    if not AskMrRobot.AreGemsCompatible(itemEquipped.gemIds[g], itemImported.gemIds[g]) then
+                        hasBadGems = true
+                        break
+                    end
+                end
+
+                if hasBadGems then
+                    result.gems[slotId] = {                    
+                        current = {},
+                        optimized = {}
+                    }
+
+                    for g = 1, #AskMrRobot.ExtraItemData[itemEquipped.id].socketColors do
+                        result.gems[slotId].current[g] = itemEquipped.gemIds[g]
+                        result.gems[slotId].optimized[g] = itemImported.gemIds[g]
+                    end
+                end
+            end
+            
+            if itemEquipped.enchantId ~= itemImported.enchantId then
+                result.enchants[slotId] = {
+                    current = itemEquipped.enchantId,
+                    optimized = itemImported.enchantId
+                }
+            end
+        end
+    end
+    
+    -- only set the new result if it is completely successful
+    AskMrRobot.ComparisonResult = result
+end
+
+-- checks our extra gem information to see if the two gems are functionally equivalent
+function AskMrRobot.AreGemsCompatible(gemId1, gemId2)
+    if gemId1 == gemId2 then return true end
+    
+    -- see if we have extra gem information
+    local extraInfo = AskMrRobot.ExtraGemData[gemId1]
+    if not extraInfo then
+        extraInfo = AskMrRobot.ExtraGemData[gemId2]
+    end
+    if extraInfo == nil or extraInfo.identicalGroup == nil then return false end
+    
+    -- if identicalGroup contains both gem ids, they are equivalent
+    return extraInfo.identicalGroup[gemId1] and extraInfo.identicalGroup[gemId2]
+end
\ No newline at end of file