# HG changeset patch # User Adam tegen # Date 1413253712 18000 # Node ID e77e01abce98777643360d8d5b5ee3bcd084eb5e # Parent 9793e8b683d26e7dd865e098b26a15b9cf0239ce Warlords of Draenor pre-patch diff -r 9793e8b683d2 -r e77e01abce98 AskMrRobot.lua --- a/AskMrRobot.lua Thu Jul 10 15:32:11 2014 -0700 +++ b/AskMrRobot.lua Mon Oct 13 21:28:32 2014 -0500 @@ -1,21 +1,21 @@ local _, AskMrRobot = ... local L = AskMrRobot.L; -AskMrRobot.eventListener = CreateFrame("FRAME"); -- Need a frame to respond to events -AskMrRobot.eventListener:RegisterEvent("ADDON_LOADED"); -- Fired when saved variables are loaded -AskMrRobot.eventListener:RegisterEvent("ITEM_PUSH"); -AskMrRobot.eventListener:RegisterEvent("DELETE_ITEM_CONFIRM"); -AskMrRobot.eventListener:RegisterEvent("UNIT_INVENTORY_CHANGED"); -AskMrRobot.eventListener:RegisterEvent("BANKFRAME_OPENED"); -AskMrRobot.eventListener:RegisterEvent("BANKFRAME_CLOSED"); -AskMrRobot.eventListener:RegisterEvent("PLAYERBANKSLOTS_CHANGED"); -AskMrRobot.eventListener:RegisterEvent("CHARACTER_POINTS_CHANGED"); -AskMrRobot.eventListener:RegisterEvent("CONFIRM_TALENT_WIPE"); -AskMrRobot.eventListener:RegisterEvent("PLAYER_TALENT_UPDATE"); -AskMrRobot.eventListener:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED"); -AskMrRobot.eventListener:RegisterEvent("PLAYER_ENTERING_WORLD"); -AskMrRobot.eventListener:RegisterEvent("PLAYER_LOGOUT"); -- Fired when about to log out -AskMrRobot.eventListener:RegisterEvent("PLAYER_LEVEL_UP"); +AskMrRobot.eventListener = CreateFrame("FRAME") -- Need a frame to respond to events +AskMrRobot.eventListener:RegisterEvent("ADDON_LOADED") -- Fired when saved variables are loaded +AskMrRobot.eventListener:RegisterEvent("ITEM_PUSH") +AskMrRobot.eventListener:RegisterEvent("DELETE_ITEM_CONFIRM") +AskMrRobot.eventListener:RegisterEvent("UNIT_INVENTORY_CHANGED") +AskMrRobot.eventListener:RegisterEvent("BANKFRAME_OPENED") +--AskMrRobot.eventListener:RegisterEvent("BANKFRAME_CLOSED"); +AskMrRobot.eventListener:RegisterEvent("PLAYERBANKSLOTS_CHANGED") +AskMrRobot.eventListener:RegisterEvent("CHARACTER_POINTS_CHANGED") +AskMrRobot.eventListener:RegisterEvent("CONFIRM_TALENT_WIPE") +AskMrRobot.eventListener:RegisterEvent("PLAYER_TALENT_UPDATE") +AskMrRobot.eventListener:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED") +AskMrRobot.eventListener:RegisterEvent("PLAYER_ENTERING_WORLD") +--AskMrRobot.eventListener:RegisterEvent("PLAYER_LOGOUT") -- Fired when about to log out +--AskMrRobot.eventListener:RegisterEvent("PLAYER_LEVEL_UP") --AskMrRobot.eventListener:RegisterEvent("GET_ITEM_INFO_RECEIVED") AskMrRobot.eventListener:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED") AskMrRobot.eventListener:RegisterEvent("SOCKET_INFO_UPDATE") @@ -31,553 +31,252 @@ AskMrRobot.AddonName = ... AskMrRobot.ChatPrefix = "_AMR" -local amrLDB -local icon -local reforgequeue -local reforgeFrame = nil -local LoggingCombat = _G.LoggingCombat +-- the main user interface window +AskMrRobot.mainWindow = nil -AskMrRobot.itemDiffs = { - items = {}, -- slotNum -> nil (no change) or current , optimized - enchants = {}, -- slotNum -> nil (no change) or current , optimized - gems = {}, -- slotNum -> nil (no change) or ? - reforges = {} -- slotNum -> nil (no change) or current , optimized -} - -AskMrRobot.instanceIds = { - HeartOfFear = 1009, - MogushanVaults = 1008, - SiegeOfOrgrimmar = 1136, - TerraceOfEndlessSpring = 996, - ThroneOfThunder = 1098 -} - --- instances that we currently support logging for -AskMrRobot.supportedInstanceIds = { - [1136] = true -} - --- returns true if currently in a supported instance -function AskMrRobot.IsSupportedInstance() - - local zone, _, difficultyIndex, _, _, _, _, instanceMapID = GetInstanceInfo() - if AskMrRobot.supportedInstanceIds[tonumber(instanceMapID)] then - return true - else - return false - end -end - --- upgrade id -> upgrade level -local upgradeTable = { - [0] = 0, - [1] = 1, -- 1/1 -> 8 - [373] = 1, -- 1/2 -> 4 - [374] = 2, -- 2/2 -> 8 - [375] = 1, -- 1/3 -> 4 - [376] = 2, -- 2/3 -> 4 - [377] = 3, -- 3/3 -> 4 - [378] = 1, -- 1/1 -> 7 - [379] = 1, -- 1/2 -> 4 - [380] = 2, -- 2/2 -> 4 - [445] = 0, -- 0/2 -> 0 - [446] = 1, -- 1/2 -> 4 - [447] = 2, -- 2/2 -> 8 - [451] = 0, -- 0/1 -> 0 - [452] = 1, -- 1/1 -> 8 - [453] = 0, -- 0/2 -> 0 - [454] = 1, -- 1/2 -> 4 - [455] = 2, -- 2/2 -> 8 - [456] = 0, -- 0/1 -> 0 - [457] = 1, -- 1/1 -> 8 - [458] = 0, -- 0/4 -> 0 - [459] = 1, -- 1/4 -> 4 - [460] = 2, -- 2/4 -> 8 - [461] = 3, -- 3/4 -> 12 - [462] = 4, -- 4/4 -> 16 - [465] = 0, -- 0/2 -> 0 - [466] = 1, -- 1/2 -> 4 - [467] = 2, -- 2/2 -> 8 - [468] = 0, -- 0/4 -> 0 - [469] = 1, -- 1/4 -> 4 - [470] = 2, -- 2/4 -> 8 - [471] = 3, -- 3/4 -> 12 - [472] = 4, -- 4/4 -> 16 - [476] = 0, -- ? -> 0 - [479] = 0, -- ? -> 0 - [491] = 0, -- ? -> 0 - [492] = 1, -- ? -> 0 - [493] = 2, -- ? -> 0 - [494] = 0, - [495] = 1, - [496] = 2, - [497] = 3, - [498] = 4, - [504] = 3, - [505] = 4, - [506] = 5, - [507] = 6 -} - -local professionIds = { - ["None"] = 0, - ["Mining"] = 1, - ["Skinning"] = 2, - ["Herbalism"] = 3, - ["Enchanting"] = 4, - ["Jewelcrafting"] = 5, - ["Engineering"] = 6, - ["Blacksmithing"] = 7, - ["Leatherworking"] = 8, - ["Inscription"] = 9, - ["Tailoring"] = 10, - ["Alchemy"] = 11, - ["Fishing"] = 12, - ["Cooking"] = 13, - ["First Aid"] = 14, - ["Archaeology"] = 15 -} - -local raceIds = { - ["None"] = 0, - ["BloodElf"] = 1, - ["Draenei"] = 2, - ["Dwarf"] = 3, - ["Gnome"] = 4, - ["Human"] = 5, - ["NightElf"] = 6, - ["Orc"] = 7, - ["Tauren"] = 8, - ["Troll"] = 9, - ["Scourge"] = 10, - ["Undead"] = 10, - ["Goblin"] = 11, - ["Worgen"] = 12, - ["Pandaren"] = 13 -} - -local factionIds = { - ["None"] = 0, - ["Alliance"] = 1, - ["Horde"] = 2 -} - -local function OnExport() - if (AmrOptions.exportToClient) then - AskMrRobot.SaveAll() - ReloadUI() - else - AskMrRobot_ReforgeFrame:Show() - AskMrRobot_ReforgeFrame:ShowTab("export") - end -end +local _amrLDB +local _minimapIcon function AskMrRobot.eventListener:OnEvent(event, ...) if event == "ADDON_LOADED" then local addon = select(1, ...) if (addon == "AskMrRobot") then - print(L.AMR_ON_EVENT_LOADED.format(GetAddOnMetadata(AskMrRobot.AddonName, "Version"))) + --print(L.AMR_ON_EVENT_LOADED:format(GetAddOnMetadata(AskMrRobot.AddonName, "Version"))) + + AskMrRobot.InitializeSettings() + AskMrRobot.InitializeMinimap() -- listen for messages from other AMR addons - RegisterAddonMessagePrefix(AskMrRobot.ChatPrefix) - - AmrRealmName = GetRealmName() - AmrCharacterName = UnitName("player") + RegisterAddonMessagePrefix(AskMrRobot.ChatPrefix) - AskMrRobot.CombatLogTab.InitializeVariable() - - if not AmrIconInfo then AmrIconInfo = {} end - if not AmrBankItems then AmrBankItems = {} end - if not AmrCurrencies then AmrCurrencies = {} end - if not AmrSpecializations then AmrSpecializations = {} end - if not AmrOptions then AmrOptions = {} end - if not AmrGlyphs then AmrGlyphs = {} end - if not AmrTalents then AmrTalents = {} end - if not AmrBankItemsAndCounts then AmrBankItemsAndCounts = {} end - if not AmrImportString then AmrImportString = "" end - if not AmrImportDate then AmrImportDate = "" end - - if not AmrSettings then AmrSettings = {} end - if not AmrSettings.Logins then AmrSettings.Logins = {} end - - if not AmrSendSettings then - AmrSendSettings = { - SendGems = true, - SendEnchants = true, - SendEnchantMaterials = true, - SendToType = "a friend", - SendTo = "" - } - end - - amrLDB = LibStub("LibDataBroker-1.1"):NewDataObject("AskMrRobot", { - type = "launcher", - text = "Ask Mr. Robot", - icon = "Interface\\AddOns\\AskMrRobot\\Media\\icon", - OnClick = function() - if IsControlKeyDown() then - AskMrRobot_ReforgeFrame.combatLogTab:LogWipe() - elseif IsModifiedClick("CHATLINK") then - OnExport() - else - AskMrRobot_ReforgeFrame:Toggle() - end - end, - OnTooltipShow = function(tt) - tt:AddLine("Ask Mr. Robot", 1, 1, 1); - tt:AddLine(" "); - tt:AddLine(L.AMR_ON_EVENT_TOOLTIP) - end - }); - - - AskMrRobot.AmrUpdateMinimap() - - AskMrRobot_ReforgeFrame = AskMrRobot.AmrUI:new() - - -- remember the import settings between sessions - AskMrRobot_ReforgeFrame.summaryTab.importDate = AmrImportDate or "" - AskMrRobot_ReforgeFrame.buttons[2]:Click() - - -- the previous import string is loaded when the UI is first shown, otherwise the game spams events and it lags + AskMrRobot.mainWindow = AskMrRobot.AmrUI:new() end + + elseif event == "UNIT_INVENTORY_CHANGED" then + AskMrRobot.ScanEquipped() - elseif event == "ITEM_PUSH" or event == "DELETE_ITEM_CONFIRM" or event == "UNIT_INVENTORY_CHANGED" or event == "SOCKET_INFO_CLOSE" or event == "PLAYER_SPECIALIZATION_CHANGED" or event == "BAG_UPDATE" then - if AskMrRobot_ReforgeFrame then - AskMrRobot_ReforgeFrame:OnUpdate() - end + elseif event == "ITEM_PUSH" or event == "DELETE_ITEM_CONFIRM" or event == "SOCKET_INFO_CLOSE" or event == "PLAYER_SPECIALIZATION_CHANGED" or event == "BAG_UPDATE" then + --if AskMrRobot_ReforgeFrame then + -- AskMrRobot_ReforgeFrame:OnUpdate() + --end --AskMrRobot.SaveBags(); --AskMrRobot.SaveEquiped(); --AskMrRonot.GetCurrencies(); --AskMrRobot.GetGold(); + elseif event == "BANKFRAME_OPENED" or event == "PLAYERBANKSLOTS_CHANGED" then - --print("Scanning Bank: " .. event); AskMrRobot.ScanBank(); - elseif event == "BANKFRAME_CLOSED" then - --print("Stop Scanning Bank"); - --inBank = false; + elseif event == "CHARACTER_POINTS_CHANGED" or event == "CONFIRM_TALENT_WIPE" or event == "PLAYER_TALENT_UPDATE" or event == "ACTIVE_TALENT_GROUP_CHANGED" then --AskMrRobot.GetAmrSpecializations(); - if AskMrRobot_ReforgeFrame then - AskMrRobot_ReforgeFrame:OnUpdate() - end - elseif event == "PLAYER_LEVEL_UP" then - --GetLevel(); + --if AskMrRobot_ReforgeFrame then + -- AskMrRobot_ReforgeFrame:OnUpdate() + --end + elseif event == "ITEM_UNLOCKED" then - AskMrRobot.On_ITEM_UNLOCKED() - elseif event == "PLAYER_LOGOUT" then - -- doing nothing right now, but leaving this in case we need something here - elseif event == "PLAYER_ENTERING_WORLD" then + --AskMrRobot.On_ITEM_UNLOCKED() - -- delete entries that are more than 10 days old to prevent the table from growing indefinitely - if AmrSettings.Logins and #AmrSettings.Logins > 0 then - local now = time() - local oldDuration = 60 * 60 * 24 * 10 - local entryTime - repeat - -- parse entry and get time - local parts = {} - for part in string.gmatch(AmrSettings.Logins[1], "([^;]+)") do - tinsert(parts, part) - end - entryTime = tonumber(parts[3]) - - -- entries are in order, remove first entry if it is old - if difftime(now, entryTime) > oldDuration then - tremove(AmrSettings.Logins, 1) - end - until #AmrSettings.Logins == 0 or difftime(now, entryTime) <= oldDuration - end - - -- record the time a player logs in, used to figure out which player logged which parts of their log file - local key = AmrRealmName .. ";" .. AmrCharacterName .. ";" - local loginData = key .. time() - if AmrSettings.Logins and #AmrSettings.Logins > 0 then - local last = AmrSettings.Logins[#AmrSettings.Logins] - if string.len(last) >= string.len(key) and string.sub(last, 1, string.len(key)) ~= key then - table.insert(AmrSettings.Logins, loginData) - end - else - table.insert(AmrSettings.Logins, loginData) - end + elseif event == "PLAYER_ENTERING_WORLD" then + AskMrRobot.RecordLogin() elseif event == "PLAYER_REGEN_DISABLED" then - -- send data about this character when a player enters combat in a supported zone if AskMrRobot.IsSupportedInstance() then local t = time() AskMrRobot.SaveAll() AskMrRobot.ExportToAddonChat(t) - AskMrRobot.ExportLoggingData(t) + AskMrRobot.CombatLogTab.SaveExtras(t) end elseif event == "CHAT_MSG_ADDON" then local chatPrefix, message = select(1, ...) - local isLogging = AskMrRobot_ReforgeFrame.combatLogTab:IsLogging() + local isLogging = AskMrRobot.CombatLogTab.IsLogging() if (isLogging and chatPrefix == AskMrRobot.ChatPrefix) then - AskMrRobot_ReforgeFrame.combatLogTab:ReadAddonMessage(message) + AskMrRobot.mainWindow.combatLogTab:ReadAddonMessage(message) end + elseif event == "UPDATE_INSTANCE_INFO" or event == "PLAYER_DIFFICULTY_CHANGED" then - AskMrRobot_ReforgeFrame.combatLogTab:UpdateAutoLogging() + AskMrRobot.mainWindow.combatLogTab:UpdateAutoLogging() + end end -AskMrRobot.eventListener:SetScript("OnEvent", AskMrRobot.eventListener.OnEvent); +AskMrRobot.eventListener:SetScript("OnEvent", AskMrRobot.eventListener.OnEvent) -local function parseItemLink(input) - local itemId, enchantId, gemEnchantId1, gemEnchantId2, gemEnchantId3, gemEnchantId4, suffixId, _, _, reforgeId, upgradeId = string.match(input, "^|.-|Hitem:(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(-?%d+):(-?%d+):(-?%d+):(%d+):(%d+)|"); - local item = {} - item.itemId = tonumber(itemId) - item.suffixId = tonumber(suffixId) - item.enchantId = tonumber(enchantId) - item.reforgeId = tonumber(reforgeId) - item.upgradeId = tonumber(upgradeId) - item.gemEnchantIds = { tonumber(gemEnchantId1), tonumber(gemEnchantId2), tonumber(gemEnchantId3), tonumber(gemEnchantId4) } - return item -end SLASH_AMR1 = "/amr"; function SlashCmdList.AMR(msg) if msg == 'toggle' then - AskMrRobot_ReforgeFrame:Toggle() + AskMrRobot.mainWindow:Toggle() elseif msg == 'show' then - AskMrRobot_ReforgeFrame:Show() + AskMrRobot.mainWindow:Show() elseif msg == 'hide' then - AskMrRobot_ReforgeFrame:Hide() + AskMrRobot.mainWindow:Hide() elseif msg == 'export' then - OnExport() + AskMrRobot.mainWindow.exportTab:Show() elseif msg == 'wipe' then - AskMrRobot_ReforgeFrame.combatLogTab:LogWipe() + AskMrRobot.mainWindow.combatLogTab:LogWipe() elseif msg == 'unwipe' then - AskMrRobot_ReforgeFrame.combatLogTab:LogUnwipe() + AskMrRobot.mainWindow.combatLogTab:LogUnwipe() else print(L.AMR_SLASH_COMMAND_TEXT_1 .. L.AMR_SLASH_COMMAND_TEXT_2 .. L.AMR_SLASH_COMMAND_TEXT_3 .. L.AMR_SLASH_COMMAND_TEXT_4 .. L.AMR_SLASH_COMMAND_TEXT_5 .. L.AMR_SLASH_COMMAND_TEXT_6 .. L.AMR_SLASH_COMMAND_TEXT_7) end end -function AskMrRobot.SaveAll() - AskMrRobot.ScanBank() - AskMrRobot.SaveBags() - AskMrRobot.SaveEquiped() - AskMrRobot.GetCurrencies() - AskMrRobot.GetGold() - AskMrRobot.GetAmrSpecializations() - AskMrRobot.GetAmrProfessions() - AskMrRobot.GetRace() - AskMrRobot.GetLevel() - AskMrRobot.GetAmrGlyphs() - AskMrRobot.GetAmrTalents() - --ReloadUI() +-- initialize settings when the addon loads +function AskMrRobot.InitializeSettings() + + -- global settings + if not AmrSettings then AmrSettings = {} end + if not AmrSettings.Logins then AmrSettings.Logins = {} end + + -- per-character settings + if not AmrDb then AmrDb = {} end + + -- addon stuff + if not AmrDb.IconInfo then AmrDb.IconInfo = {} end + if not AmrDb.Options then AmrDb.Options = {} end + if not AmrDb.LastCharacterImport then AmrDb.LastCharacterImport = "" end + if not AmrDb.LastCharacterImportDate then AmrDb.LastCharacterImportDate = "" end + + if not AmrDb.SendSettings then + AmrDb.SendSettings = { + SendGems = true, + SendEnchants = true, + SendEnchantMaterials = true, + SendToType = "a friend", + SendTo = "" + } + end + + -- character stuff + AskMrRobot.ScanCharacter() + if not AmrDb.BankItems then AmrDb.BankItems = {} end + if not AmrDb.BagItems then AmrDb.BagItems = {} end + if not AmrDb.Currencies then AmrDb.Currencies = {} end + if not AmrDb.Reps then AmrDb.Reps = {} end + -- data saved for both specs + if not AmrDb.Specs then AmrDb.Specs = {} end + if not AmrDb.Glyphs then AmrDb.Glyphs = {} end + if not AmrDb.Talents then AmrDb.Talents = {} end + if not AmrDb.Equipped then AmrDb.Equipped = {} end + + -- combat log specific settings + AskMrRobot.CombatLogTab.InitializeVariable() end -local function InitIcon() - icon = LibStub("LibDBIcon-1.0"); - icon:Register("AskMrRobot", amrLDB, AmrIconInfo); +-- record logins when the addon starts up, used to help figure out which character logged which parts of a log file +function AskMrRobot.RecordLogin() + + -- delete entries that are more than 10 days old to prevent the table from growing indefinitely + if AmrSettings.Logins and #AmrSettings.Logins > 0 then + local now = time() + local oldDuration = 60 * 60 * 24 * 10 + local entryTime + repeat + -- parse entry and get time + local parts = {} + for part in string.gmatch(AmrSettings.Logins[1], "([^;]+)") do + tinsert(parts, part) + end + entryTime = tonumber(parts[3]) + + -- entries are in order, remove first entry if it is old + if difftime(now, entryTime) > oldDuration then + tremove(AmrSettings.Logins, 1) + end + until #AmrSettings.Logins == 0 or difftime(now, entryTime) <= oldDuration + end + + -- record the time a player logs in, used to figure out which player logged which parts of their log file + local key = AmrDb.RealmName .. ";" .. AmrDb.CharacterName .. ";" + local loginData = key .. time() + if AmrSettings.Logins and #AmrSettings.Logins > 0 then + local last = AmrSettings.Logins[#AmrSettings.Logins] + if string.len(last) >= string.len(key) and string.sub(last, 1, string.len(key)) ~= key then + table.insert(AmrSettings.Logins, loginData) + end + else + table.insert(AmrSettings.Logins, loginData) + end +end + +function AskMrRobot.InitializeMinimap() + + -- minimap icon and data broker icon plugin thingy + _amrLDB = LibStub("LibDataBroker-1.1"):NewDataObject("AskMrRobot", { + type = "launcher", + text = "Ask Mr. Robot", + icon = "Interface\\AddOns\\AskMrRobot\\Media\\icon", + OnClick = function() + if IsControlKeyDown() then + AskMrRobot.mainWindow.combatLogTab:LogWipe() + elseif IsModifiedClick("CHATLINL") then + AskMrRobot.mainWindow.exportTab:Show() + else + AskMrRobot.mainWindow:Toggle() + end + end, + OnTooltipShow = function(tt) + tt:AddLine("Ask Mr. Robot", 1, 1, 1); + tt:AddLine(" "); + tt:AddLine(L.AMR_ON_EVENT_TOOLTIP) + end + }); + + AskMrRobot.AmrUpdateMinimap() end function AskMrRobot.AmrUpdateMinimap() - if AmrOptions.hideMapIcon then - if icon then - icon:Hide("AskMrRobot"); + if AmrDb.Options.hideMapIcon then + if _minimapIcon then + _minimapIcon:Hide("AskMrRobot") end else - if not icon then - InitIcon() + if not _minimapIcon then + _minimapIcon = LibStub("LibDBIcon-1.0") + _minimapIcon:Register("AskMrRobot", _amrLDB, AmrDb.IconInfo) end - --if AskMrRobot_ReforgeFrame.combatLogTab:IsLogging() then - if AskMrRobot.CombatLogTab.IsLogging(nil) then - amrLDB.icon = 'Interface\\AddOns\\AskMrRobot\\Media\\icon_green' + + if AskMrRobot.CombatLogTab.IsLogging() then + _amrLDB.icon = 'Interface\\AddOns\\AskMrRobot\\Media\\icon_green' else - amrLDB.icon = 'Interface\\AddOns\\AskMrRobot\\Media\\icon' + _amrLDB.icon = 'Interface\\AddOns\\AskMrRobot\\Media\\icon' end - icon:Show("AskMrRobot"); + + _minimapIcon:Show("AskMrRobot") end end -local function getToolTipText(tip) - return EnumerateTooltipLines_helper(tip:GetRegions()) + +function AskMrRobot.SaveAll() + AskMrRobot.ScanCharacter() + AskMrRobot.ScanBank() + AskMrRobot.ScanBags() + AskMrRobot.ScanEquipped() + AskMrRobot.GetCurrencies() + AskMrRobot.GetReputations() + AskMrRobot.GetSpecs() end -local bagItems = {} -local bagItemsWithCount = {} - -function AskMrRobot.ScanBag(bagId) - local numSlots = GetContainerNumSlots(bagId); - for slotId = 1, numSlots do - local _, itemCount, _, _, _, _, itemLink = GetContainerItemInfo(bagId, slotId); - if itemLink ~= nil then - local itemData = parseItemLink(itemLink) - if itemData.itemId ~= nil then - tinsert(bagItems, itemLink); - tinsert(bagItemsWithCount, {link = itemLink, count = itemCount}) - end - end - end -end - -local BACKPACK_CONTAINER = 0; -local BANK_CONTAINER = -1; - -function AskMrRobot.ScanEquiped() - local equipedItems = {}; - for slotNum = 1, #AskMrRobot.slotIds do - local slotId = AskMrRobot.slotIds[slotNum]; - local itemLink = GetInventoryItemLink("player", slotId); - if (itemLink ~= nil) then - equipedItems[slotId .. ""] = itemLink; - end - end - return equipedItems -end - -function AskMrRobot.SaveEquiped() - AmrEquipedItems = AskMrRobot.ScanEquiped(); -end - -function AskMrRobot.ScanBags() - bagItems = {} - bagItemsWithCount = {} - - AskMrRobot.ScanBag(BACKPACK_CONTAINER); -- backpack - - for bagId = 1, NUM_BAG_SLOTS do - AskMrRobot.ScanBag(bagId); - end - - - return bagItems, bagItemsWithCount -end - -function AskMrRobot.SaveBags() - AmrBagItems, _ = AskMrRobot.ScanBags() -end - -function AskMrRobot.GetGold() - AmrGold = GetMoney(); -end - -local lastBankBagId = nil; -local lastBankSlotId = nil; -local bankItems = {}; -local bankItemsAndCount = {}; -AmrBankItemsAndCounts = {}; - -local function ScanBankBag(bagId) - local numSlots = GetContainerNumSlots(bagId); - for slotId = 1, numSlots do - local _, itemCount, _, _, _, _, itemLink = GetContainerItemInfo(bagId, slotId); - if itemLink ~= nil then - local itemData = parseItemLink(itemLink) - if itemData.itemId ~= nil then - lastBankBagId = bagId; - lastBankSlotId = slotId; - tinsert(bankItems, itemLink); - tinsert(bankItemsAndCount, {link = itemLink, count = itemCount}) - end - end - end -end - -function AskMrRobot.ScanBank() - - bankItems = {}; - bankItemsAndCount = {} - - ScanBankBag(BANK_CONTAINER); - for bagId = NUM_BAG_SLOTS + 1, NUM_BAG_SLOTS + NUM_BANKBAGSLOTS do - ScanBankBag(bagId); - end - - -- see if the scan completed before the window closed - if lastBankBagId ~= nil then - local itemLink = GetContainerItemLink(lastBankBagId, lastBankSlotId); - if itemLink ~= nil then --still open - AmrBankItems = bankItems; - AmrBankItemsAndCounts = bankItemsAndCount - end - end -end - -local function GetCurrencyAmount(index) - local localized_label, amount, icon_file_name = GetCurrencyInfo(index); - return amount; -end - -function AskMrRobot.GetCurrencies() - local currencies = {}; - local currencyList = {61, 81, 241, 361, 384, 394, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 416, 515, 614, 615, 676, 679}; - - for i, currency in pairs(currencyList) do - local amount = GetCurrencyAmount(currency); - if amount ~= 0 then - currencies[currencyList[i]] = amount; - end - end - AmrCurrencies = currencies; -end - -local function GetAmrSpecialization(specGroup) - local spec = GetSpecialization(false, false, specGroup); - return spec and GetSpecializationInfo(spec); -end - -function AskMrRobot.GetAmrSpecializations() - - AmrSpecializations = {}; - - AmrActiveSpec = GetActiveSpecGroup(); - - for group = 1, 2 do - AmrSpecializations[group .. ""] = GetAmrSpecialization(group) - end - --- Death Knight --- 250 - Blood --- 251 - Frost --- 252 - Unholy --- Druid --- 102 - Balance --- 103 - Feral Combat --- 104 - Guardian --- 105 - Restoration --- Hunter --- 253 - Beast Mastery --- 254 - Marksmanship --- 255 - Survival --- Mage --- 62 - Arcane --- 63 - Fire --- 64 - Frost --- Monk --- 268 - Brewmaster --- 269 - Windwalker --- 270 - Mistweaver --- Paladin --- 65 - Holy --- 66 - Protection --- 70 - Retribution --- Priest --- 256 Discipline --- 257 Holy --- 258 Shadow --- Rogue --- 259 - Assassination --- 260 - Combat --- 261 - Subtlety --- Shaman --- 262 - Elemental --- 263 - Enhancement --- 264 - Restoration --- Warlock --- 265 - Affliction --- 266 - Demonology --- 267 - Destruction --- Warrior --- 71 - Arms --- 72 - Fury --- 73 - Protection +-- gets all basic character properties +function AskMrRobot.ScanCharacter() + AmrDb.RealmName = GetRealmName() + AmrDb.CharacterName = UnitName("player") + AmrDb.Guild = GetGuildInfo("player") + AmrDb.ActiveSpec = GetActiveSpecGroup() + AmrDb.Level = UnitLevel("player"); + + local cls, clsEn = UnitClass("player") + AmrDb.Class = clsEn; + + local race, raceEn = UnitRace("player") + AmrDb.Race = raceEn; + AmrDb.Faction = UnitFactionGroup("player") + + AskMrRobot.GetAmrProfessions() end function AskMrRobot.GetAmrProfessions() @@ -601,88 +300,178 @@ } local prof1, prof2, archaeology, fishing, cooking, firstAid = GetProfessions(); - AmrProfessions = {}; + AmrDb.Professions = {}; if prof1 then local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(prof1); if profMap[skillLine] ~= nil then - AmrProfessions[profMap[skillLine]] = skillLevel; + AmrDb.Professions[profMap[skillLine]] = skillLevel; end end if prof2 then local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(prof2); if profMap[skillLine] ~= nil then - AmrProfessions[profMap[skillLine]] = skillLevel; + AmrDb.Professions[profMap[skillLine]] = skillLevel; end end if archaeology then local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(archaeology); if profMap[skillLine] ~= nil then - AmrProfessions[profMap[skillLine]] = skillLevel; + AmrDb.Professions[profMap[skillLine]] = skillLevel; end end if fishing then local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(fishing); if profMap[skillLine] ~= nil then - AmrProfessions[profMap[skillLine]] = skillLevel; + AmrDb.Professions[profMap[skillLine]] = skillLevel; end end if cooking then local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(cooking); if profMap[skillLine] ~= nil then - AmrProfessions[profMap[skillLine]] = skillLevel; + AmrDb.Professions[profMap[skillLine]] = skillLevel; end end if firstAid then local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(firstAid); if profMap[skillLine] ~= nil then - AmrProfessions[profMap[skillLine]] = skillLevel; + AmrDb.Professions[profMap[skillLine]] = skillLevel; end end end -function AskMrRobot.GetRace() - local race, raceEn = UnitRace("player"); - AmrRace = raceEn; - AmrFaction = UnitFactionGroup("player"); + +-- use some local variables to deal with the fact that a user can close the bank before a scan completes +local _lastBankBagId = nil +local _lastBankSlotId = nil +local BACKPACK_CONTAINER = 0 +local BANK_CONTAINER = -1 + +local function scanBag(bagId, isBank, bagTable, bagItemsWithCount) + local numSlots = GetContainerNumSlots(bagId) + for slotId = 1, numSlots do + local _, itemCount, _, _, _, _, itemLink = GetContainerItemInfo(bagId, slotId) + -- we skip any stackable item, as far as we know, there is no equippable gear that can be stacked + if itemLink ~= nil then + local itemData = AskMrRobot.parseItemLink(itemLink) + if itemData ~= nil then + if itemCount == 1 then + if isBank then + _lastBankBagId = bagId + _lastBankSlotId = slotId + end + tinsert(bagTable, itemLink) + end + if bagItemsWithCount then + if bagItemsWithCount[itemData.id] then + bagItemsWithCount[itemData.id] = bagItemsWithCount[itemData.id] + itemCount + else + bagItemsWithCount[itemData.id] = itemCount + end + end + end + end + end +end + +function AskMrRobot.ScanBank(bankItemsWithCount) + local bankItems = {} + local bankItemsAndCounts = {} + + scanBag(BANK_CONTAINER, true, bankItems, bankItemsAndCounts) + for bagId = NUM_BAG_SLOTS + 1, NUM_BAG_SLOTS + NUM_BANKBAGSLOTS do + scanBag(bagId, true, bankItems, bankItemsAndCounts) + end + + -- see if the scan completed before the window closed, otherwise we don't overwrite with partial data + if _lastBankBagId ~= nil then + local itemLink = GetContainerItemLink(_lastBankBagId, _lastBankSlotId) + if itemLink ~= nil then --still open + AmrDb.BankItems = bankItems + AmrDb.BankItemsAndCounts = bankItemsAndCounts + end + end end -function AskMrRobot.GetLevel() - AmrLevel = UnitLevel("player"); +function AskMrRobot.ScanBags(bagItemsWithCount) + local bagItems = {} + scanBag(BACKPACK_CONTAINER, false, bagItems, bagItemsWithCount) -- backpack + for bagId = 1, NUM_BAG_SLOTS do + scanBag(bagId, false, bagItems, bagItemsWithCount) + end + AmrDb.BagItems = bagItems end -local SlotNames = { - "HeadSlot", - "NeckSlot", - "ShoulderSlot", - "ShirtSlot", - "ChestSlot", - "WaistSlot", - "LegsSlot", - "FeetSlot", - "WristSlot", - "HandsSlot", - "Finger0Slot", - "Finger1Slot", - "Trinket0Slot", - "Trinket1Slot", - "BackSlot", - "MainHandSlot", - "SecondaryHandSlot", --- "RangedSlot", - "TabardSlot", -} +function AskMrRobot.ScanEquipped() + local equippedItems = {}; + for slotNum = 1, #AskMrRobot.slotIds do + local slotId = AskMrRobot.slotIds[slotNum]; + local itemLink = GetInventoryItemLink("player", slotId); + if (itemLink ~= nil) then + equippedItems[slotId] = itemLink; + end + end + + -- store last-seen equipped gear for each spec + AmrDb.Equipped[GetActiveSpecGroup()] = equippedItems +end -local function GetAmrTalentsForSpec(spec) + +local function getCurrencyAmount(index) + local localized_label, amount, icon_file_name = GetCurrencyInfo(index); + return amount; +end + +function AskMrRobot.GetCurrencies() + local currencies = {}; + currencies[-1] = GetMoney() + + local currencyList = {61, 81, 241, 361, 384, 394, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 416, 515, 614, 615, 676, 679} + for i, currency in pairs(currencyList) do + local amount = getCurrencyAmount(currency) + if amount ~= 0 then + currencies[currency] = amount + end + end + + AmrDb.Currencies = currencies +end + + +local function getRepStanding(factionId) + local name, description, standingId, _ = GetFactionInfoByID(factionId) + return standingId - 1; -- our rep enum correspond to what the armory returns, are 1 less than what the game returns +end + +function AskMrRobot.GetReputations() + local reps = {} + + local repList = {1375,1376,1270,1269,1341,1337,1387,1388,1435} + for i, repId in pairs(repList) do + local standing = getRepStanding(repId) + if standing >= 0 then + reps[repId] = standing + end + end + + AmrDb.Reps = reps; +end + + +local function getSpecId(specGroup) + local spec = GetSpecialization(false, false, specGroup); + return spec and GetSpecializationInfo(spec); +end + +local function getTalents(specGroup) local talentInfo = {} - local maxTiers = 6 - for talent = 1, GetNumTalents() do - local name, texture, tier, column, selected, available = GetTalentInfo(talent, false, spec) - if tier > maxTiers then - maxTiers = tier - end - if selected then - talentInfo[tier] = column - end + local maxTiers = 7 + for tier = 1, maxTiers do + for col = 1, 3 do + local id, name, texture, selected, available = GetTalentInfo(tier, col, specGroup) + if selected then + talentInfo[tier] = col + end + end end local str = "" @@ -697,17 +486,10 @@ return str end -function AskMrRobot.GetAmrTalents() - AmrTalents = {} - for spec = 1, GetNumSpecGroups() do - AmrTalents[spec] = GetAmrTalentsForSpec(spec); - end -end - -local function GetAmrGlyphsForSpec(spec) +local function getGlyphs(specGroup) local glyphs = {} for i = 1, NUM_GLYPH_SLOTS do - local _, _, _, glyphSpellID, _, glyphID = GetGlyphSocketInfo(i, spec) + local _, _, _, glyphSpellID, _, glyphID = GetGlyphSocketInfo(i, specGroup) if (glyphID) then tinsert(glyphs, glyphSpellID) end @@ -715,31 +497,32 @@ return glyphs; end -function AskMrRobot.GetAmrGlyphs() - AmrGlyphs = {} - for spec = 1, GetNumSpecGroups() do - AmrGlyphs[spec] = GetAmrGlyphsForSpec(spec) +-- get specs, talents, and glyphs +function AskMrRobot.GetSpecs() + + AmrDb.Specs = {} + AmrDb.Talents = {} + AmrDb.Glyphs = {} + + for group = 1, GetNumSpecGroups() do + -- spec, convert game spec id to one of our spec ids + local specId = getSpecId(group) + if specId then + AmrDb.Specs[group] = AskMrRobot.specIds[specId] + else + AmrDb.Specs[group] = 0 + end + + AmrDb.Talents[group] = getTalents(group) + AmrDb.Glyphs[group] = getGlyphs(group) end end ---[[ -local function ItemLinkToExportString(itemLink, slot) - local itemData = parseItemLink(itemLink) - local ret = {} - table.insert(ret, slot) - table.insert(ret, itemData.itemId) - table.insert(ret, itemData.suffixId) - table.insert(ret, itemData.upgradeId) - table.insert(ret, itemData.gemEnchantIds[1]) - table.insert(ret, itemData.gemEnchantIds[2]) - table.insert(ret, itemData.gemEnchantIds[3]) - table.insert(ret, itemData.enchantId) - table.insert(ret, itemData.reforgeId) - return table.concat(ret, ":") -end -]] +---------------------------------------------------------------------------- +-- Export +---------------------------------------------------------------------------- -local function toCompressedNumberList(list) +function AskMrRobot.toCompressedNumberList(list) -- ensure the values are numbers, sorted from lowest to highest local nums = {} for i, v in ipairs(list) do @@ -758,14 +541,67 @@ return table.concat(ret, ",") end --- create a more compact but less readable string -function AskMrRobot.ExportToCompressedString(includeInventory) +-- appends a list of items to the export +local function appendItemsToExport(fields, itemObjects) + + -- sort by item id so we can compress it more easily + table.sort(itemObjects, function(a, b) return a.id < b.id end) + + -- append to the export string + local prevItemId = 0 + local prevGemId = 0 + local prevEnchantId = 0 + local prevUpgradeId = 0 + local prevBonusId = 0 + for i, itemData in ipairs(itemObjects) do + local itemParts = {} + + table.insert(itemParts, itemData.id - prevItemId) + prevItemId = itemData.id + + if itemData.slot ~= nil then table.insert(itemParts, "s" .. itemData.slot) end + if itemData.suffixId ~= 0 then table.insert(itemParts, "f" .. itemData.suffixId) end + if itemData.upgradeId ~= 0 then + table.insert(itemParts, "u" .. (itemData.upgradeId - prevUpgradeId)) + prevUpgradeId = itemData.upgradeId + end + if itemData.bonusIds then + for bIndex, bValue in ipairs(itemData.bonusIds) do + table.insert(itemParts, "b" .. (bValue - prevBonusId)) + prevBonusId = bValue + end + end + if itemData.gemIds[1] ~= 0 then + table.insert(itemParts, "x" .. (itemData.gemIds[1] - prevGemId)) + prevGemId = itemData.gemIds[1] + end + if itemData.gemIds[2] ~= 0 then + table.insert(itemParts, "y" .. (itemData.gemIds[2] - prevGemId)) + prevGemId = itemData.gemIds[2] + end + if itemData.gemIds[3] ~= 0 then + table.insert(itemParts, "z" .. (itemData.gemIds[3] - prevGemId)) + prevGemId = itemData.gemIds[3] + end + if itemData.enchantId ~= 0 then + table.insert(itemParts, "e" .. (itemData.enchantId - prevEnchantId)) + prevEnchantId = itemData.enchantId + end + + table.insert(fields, table.concat(itemParts, "")) + end +end + +-- create a compact string representing this player +-- if complete is true, exports everything (inventory, both specs) +-- otherwise only exports the player's active gear, spec, etc. +function AskMrRobot.ExportToCompressedString(complete) local fields = {} -- compressed string uses a fixed order rather than inserting identifiers table.insert(fields, GetAddOnMetadata(AskMrRobot.AddonName, "Version")) - table.insert(fields, AmrRealmName) - table.insert(fields, AmrCharacterName) + table.insert(fields, AmrDb.RealmName) + table.insert(fields, AmrDb.CharacterName) -- guild name local guildName = GetGuildInfo("player") @@ -776,22 +612,22 @@ end -- race, default to pandaren if we can't read it for some reason - local raceval = raceIds[AmrRace] + local raceval = AskMrRobot.raceIds[AmrDb.Race] if raceval == nil then raceval = 13 end table.insert(fields, raceval) -- faction, default to alliance if we can't read it for some reason - raceval = factionIds[AmrFaction] + raceval = AskMrRobot.factionIds[AmrDb.Faction] if raceval == nil then raceval = 1 end table.insert(fields, raceval) - table.insert(fields, AmrLevel) + table.insert(fields, AmrDb.Level) local profs = {} local noprofs = true - if AmrProfessions then - for k, v in pairs(AmrProfessions) do - local profval = professionIds[k] + if AmrDb.Professions then + for k, v in pairs(AmrDb.Professions) do + local profval = AskMrRobot.professionIds[k] if profval ~= nil then noprofs = false table.insert(profs, profval .. ":" .. v) @@ -805,149 +641,80 @@ table.insert(fields, table.concat(profs, ",")) - if (AmrActiveSpec ~= nil) then - table.insert(fields, AmrActiveSpec) - table.insert(fields, AmrSpecializations[AmrActiveSpec .. ""]) - table.insert(fields, AmrTalents[AmrActiveSpec]) - table.insert(fields, toCompressedNumberList(AmrGlyphs[AmrActiveSpec])) - else - table.insert(fields, "_") - table.insert(fields, "_") - table.insert(fields, "_") - table.insert(fields, "_") + -- export specs + table.insert(fields, AmrDb.ActiveSpec) + for spec = 1, 2 do + if AmrDb.Specs[spec] and (complete or spec == AmrDb.ActiveSpec) then + table.insert(fields, ".s" .. spec) -- indicates the start of a spec block + table.insert(fields, AmrDb.Specs[spec]) + table.insert(fields, AmrDb.Talents[spec]) + table.insert(fields, AskMrRobot.toCompressedNumberList(AmrDb.Glyphs[spec])) + end end - -- convert items to parsed objects, sorted by id - local itemObjects = {} - if AmrEquipedItems then - for k, v in pairs(AmrEquipedItems) do - local itemData = parseItemLink(v) - itemData.slot = k - table.insert(itemObjects, itemData) - end + -- export equipped gear + if AmrDb.Equipped then + for spec = 1, 2 do + if AmrDb.Equipped[spec] and (complete or spec == AmrDb.ActiveSpec) then + table.insert(fields, ".q" .. spec) -- indicates the start of an equipped gear block + + local itemObjects = {} + for k, v in pairs(AmrDb.Equipped[spec]) do + local itemData = AskMrRobot.parseItemLink(v) + itemData.slot = k + table.insert(itemObjects, itemData) + end + + appendItemsToExport(fields, itemObjects) + end + end end - -- if desired, include bank/bag items too - if includeInventory then - if AmrBagItems then - for i, v in ipairs(AmrBagItems) do - local itemData = parseItemLink(v) - if itemData.itemId ~= nil then + -- if doing a complete export, include reputations and bank/bag items too + if complete then + + -- export reputations + local reps = {} + local noreps = true + if AmrDb.Reps then + for k, v in pairs(AmrDb.Reps) do + noreps = false + table.insert(reps, k .. ":" .. v) + end + end + if noreps then + table.insert(reps, "_") + end + + table.insert(fields, ".r") + table.insert(fields, table.concat(reps, ",")) + + -- export bag and bank + local itemObjects = {} + if AmrDb.BagItems then + for i, v in ipairs(AmrDb.BagItems) do + local itemData = AskMrRobot.parseItemLink(v) + if itemData ~= nil then table.insert(itemObjects, itemData) end end end - if AmrBankItems then - for i, v in ipairs(AmrBankItems) do - local itemData = parseItemLink(v) - if itemData.itemId ~= nil then + if AmrDb.BankItems then + for i, v in ipairs(AmrDb.BankItems) do + local itemData = AskMrRobot.parseItemLink(v) + if itemData ~= nil then table.insert(itemObjects, itemData) end end end - end - - -- sort by item id so we can compress it more easily - table.sort(itemObjects, function(a, b) return a.itemId < b.itemId end) - - -- append to the export string - local prevItemId = 0 - local prevGemId = 0 - local prevEnchantId = 0 - for i, itemData in ipairs(itemObjects) do - - local itemParts = {} - table.insert(itemParts, itemData.itemId - prevItemId) - prevItemId = itemData.itemId - - if itemData.slot ~= nil then table.insert(itemParts, "s" .. itemData.slot) end - if itemData.suffixId ~= 0 then table.insert(itemParts, "f" .. itemData.suffixId) end - if upgradeTable[itemData.upgradeId] ~= 0 then table.insert(itemParts, "u" .. upgradeTable[itemData.upgradeId]) end - if itemData.gemEnchantIds[1] ~= 0 then - table.insert(itemParts, "a" .. (itemData.gemEnchantIds[1] - prevGemId)) - prevGemId = itemData.gemEnchantIds[1] - end - if itemData.gemEnchantIds[2] ~= 0 then - table.insert(itemParts, "b" .. (itemData.gemEnchantIds[2] - prevGemId)) - prevGemId = itemData.gemEnchantIds[2] - end - if itemData.gemEnchantIds[3] ~= 0 then - table.insert(itemParts, "c" .. (itemData.gemEnchantIds[3] - prevGemId)) - prevGemId = itemData.gemEnchantIds[3] - end - if itemData.enchantId ~= 0 then - table.insert(itemParts, "e" .. (itemData.enchantId - prevEnchantId)) - prevEnchantId = itemData.enchantId - end - if itemData.reforgeId ~= 0 then table.insert(itemParts, "r" .. (itemData.reforgeId - 113)) end - - table.insert(fields, table.concat(itemParts, "")) + table.insert(fields, ".inv") + appendItemsToExport(fields, itemObjects) end return "$" .. table.concat(fields, ";") .. "$" end -local function GetPlayerExtraData(data, index) - - local unitId = "raid" .. index - - local guid = UnitGUID(unitId) - if guid == nil then - return nil - end - - local fields = {} - - local buffs = {} - for i=1,40 do - local _,_,_,count,_,_,_,_,_,_,spellId = UnitAura(unitId, i, "HELPFUL") - table.insert(buffs, spellId) - end - if #buffs == 0 then - table.insert(fields, "_") - else - table.insert(fields, toCompressedNumberList(buffs)) - end - - local petGuid = UnitGUID("raidpet" .. index) - if petGuid then - table.insert(fields, guid .. "," .. petGuid) - else - table.insert(fields, '_') - end - - local name = GetRaidRosterInfo(index) - local realm = GetRealmName() - local splitPos = string.find(name, "-") - if splitPos ~= nil then - realm = string.sub(name, splitPos + 1) - name = string.sub(name, 1, splitPos - 1) - end - - data[realm .. ":" .. name] = table.concat(fields, ";") -end - -function AskMrRobot.ExportLoggingData(timestamp) - - local isLogging = AskMrRobot_ReforgeFrame.combatLogTab:IsLogging() - if not isLogging then - return - end - - -- we only get extra information for people if in a raid - if not IsInRaid() then - return - end - - local data = {} - for i = 1,40 do - GetPlayerExtraData(data, i) - end - - AskMrRobot.CombatLogTab.SaveExtras(data, timestamp) -end - function AskMrRobot.ExportToAddonChat(timestamp) local msg = AskMrRobot.ExportToCompressedString(false) local msgPrefix = timestamp .. "\n" .. AmrRealmName .. "\n" .. AmrCharacterName .. "\n" @@ -973,408 +740,275 @@ -- Create an export string that can be copied to the website function AskMrRobot.ExportToString() + return AskMrRobot.ExportToCompressedString(true) +end - --[[ - local fields = {} + +---------------------------------------------------------------------------- +-- Import +---------------------------------------------------------------------------- + +-- imports will give us extra information about items, gems, and enchants +AskMrRobot.ExtraItemData = {} -- keyed by item id +AskMrRobot.ExtraGemData = {} -- keyed by gem enchant id +AskMrRobot.ExtraEnchantData = {} -- keyed by enchant id + +-- the data that was last imported +AskMrRobot.ImportData = nil -- keyed by slot id + +local MIN_IMPORT_VERSION = 2 + +-- +-- Import a character, returning nil on success, otherwise an error message, import result stored in AskMrRobot.ImportData +-- +function AskMrRobot.ImportCharacter(data) + + -- make sure all data is up to date before importing + AskMrRobot.SaveAll() - fields["realm"] = AmrRealmName - fields["name"] = AmrCharacterName - fields["race"] = AmrRace - fields["faction"] = AmrFaction - fields["level"] = AmrLevel - - local profs = {} - for k, v in pairs(AmrProfessions) do - table.insert(profs, k .. ":" .. v) - end - fields["professions"] = table.concat(profs, ",") - - if (AmrActiveSpec ~= nil) then - fields["activespec"] = AmrActiveSpec - fields["spec"] = AmrSpecializations[AmrActiveSpec .. ""] - fields["talents"] = AmrTalents[AmrActiveSpec] - fields["glyphs"] = table.concat(AmrGlyphs[AmrActiveSpec], ",") + if data == nil or string.len(data) == 0 then + return L.AMR_IMPORT_ERROR_EMPTY end - local items = {} - for k, v in pairs(AmrEquipedItems) do - table.insert(items, ItemLinkToExportString(v, k)) + local data1 = { strsplit("$", data) } + if #data1 ~= 3 then + return L.AMR_IMPORT_ERROR_FORMAT end - for i, v in ipairs(AmrBagItems) do - table.insert(items, ItemLinkToExportString(v, "-1")) + + local parts = { strsplit(";", data1[2]) } + + -- require a minimum version + local ver = tonumber(parts[1]) + if ver < MIN_IMPORT_VERSION then + return L.AMR_IMPORT_ERROR_VERSION end - for i, v in ipairs(AmrBankItems) do - table.insert(items, ItemLinkToExportString(v, "-1")) + + -- require realm/name match + local realm = parts[2] + local name = parts[3] + if realm ~= AmrDb.RealmName or name ~= AmrDb.CharacterName then + local badPers = name .. " (" .. realm .. ")" + local goodPers = AmrDb.CharacterName .. " (" .. AmrDb.RealmName .. ")" + return L.AMR_IMPORT_ERROR_CHAR:format(badPers, goodPers) end - fields["items"] = table.concat(items, "_") - local fieldList = {} - for k, v in pairs(fields) do - table.insert(fieldList, k .. "=" .. v) + -- require race match + local race = tonumber(parts[5]) + if race ~= AskMrRobot.raceIds[AmrDb.Race] then + return L.AMR_IMPORT_ERROR_RACE end - ]] - --return table.concat(fieldList, ";") + -- require faction match + local faction = tonumber(parts[6]) + if faction ~= AskMrRobot.factionIds[AmrDb.Faction] then + return L.AMR_IMPORT_ERROR_FACTION + end - return AskMrRobot.ExportToCompressedString(true) - --return AskMrRobot.ExportToAddonChat(time()) + -- require level match + local level = tonumber(parts[7]) + if level ~= AmrDb.Level then + return L.AMR_IMPORT_ERROR_LEVEL + end + + -- require spec match + local spec = tonumber(parts[11]) + if spec ~= AmrDb.Specs[AmrDb.ActiveSpec] then + print(AmrDb.ActiveSpec) + print(spec) + print(AmrDb.Specs[AmrDb.ActiveSpec]) + local _, specName = GetSpecializationInfoByID(AskMrRobot.gameSpecIds[spec]) + return L.AMR_IMPORT_ERROR_SPEC:format(specName) + end + + -- require talent match + local talents = parts[12] + if talents ~= AmrDb.Talents[AmrDb.ActiveSpec] then + return L.AMR_IMPORT_ERROR_TALENT + end + + -- require glyph match + -- TODO: re-enable this check when glyphs are more consistent + --local glyphs = parts[13] + --if glyphs ~= AskMrRobot.toCompressedNumberList(AmrDb.Glyphs[AmrDb.ActiveSpec]) then + -- return L.AMR_IMPORT_ERROR_GLYPH + --end + + -- if we make it this far, the data is valid, so read item information + local importData = {} + + local itemInfo = {} + local gemInfo = {} + local enchantInfo = {} + + local prevItemId = 0 + local prevGemId = 0 + local prevEnchantId = 0 + local prevUpgradeId = 0 + local prevBonusId = 0 + local digits = { + ["-"] = true, + ["0"] = true, + ["1"] = true, + ["2"] = true, + ["3"] = true, + ["4"] = true, + ["5"] = true, + ["6"] = true, + ["7"] = true, + ["8"] = true, + ["9"] = true, + } + for i = 15, #parts do + local itemString = parts[i] + if itemString ~= "" and itemString ~= "_" then + local tokens = {} + local bonusIds = {} + local hasBonuses = false + local token = "" + local prop = "i" + local tokenComplete = false + for j = 1, string.len(itemString) do + local c = string.sub(itemString, j, j) + if digits[c] == nil then + tokenComplete = true + else + token = token .. c + end + + if tokenComplete or j == string.len(itemString) then + local val = tonumber(token) + if prop == "i" then + val = val + prevItemId + prevItemId = val + elseif prop == "u" then + val = val + prevUpgradeId + prevUpgradeId = val + elseif prop == "b" then + val = val + prevBonusId + prevBonusId = val + elseif prop == "x" or prop == "y" or prop == "z" then + val = val + prevGemId + prevGemId = val + elseif prop == "e" then + val = val + prevEnchantId + prevEnchantId = val + end + + if prop == "b" then + table.insert(bonusIds, val) + hasBonuses = true + else + tokens[prop] = val + end + + token = "" + tokenComplete = false + + -- we have moved on to the next token + prop = c + end + end + + local obj = {} + importData[tonumber(tokens["s"])] = obj + + obj.id = tokens["i"] + obj.suffixId = tokens["f"] or 0 + obj.upgradeId = tokens["u"] or 0 + obj.enchantId = tokens["e"] or 0 + + obj.gemIds = {} + table.insert(obj.gemIds, tokens["x"] or 0) + table.insert(obj.gemIds, tokens["y"] or 0) + table.insert(obj.gemIds, tokens["z"] or 0) + table.insert(obj.gemIds, 0) + + if hasBonuses then + obj.bonusIds = bonusIds + end + + local itemObj = {} + itemObj.id = obj.id + itemInfo[obj.id] = itemObj + + -- look for any socket color information, add to our extra data + if tokens["c"] then + itemObj.socketColors = {} + for j = 1, string.len(tokens["c"]) do + table.insert(itemObj.socketColors, tonumber(string.sub(tokens["c"], j, j))) + end + end + + -- look for item ID duplicate info, deals with old SoO items + if tokens["d"] then + itemObj.duplicateId = tonumber(tokens["d"]) + end + + end + end + + -- now read any extra display information + parts = { strsplit("@", data1[3]) } + for i = 1, #parts do + local infoParts = { strsplit("\\", parts[i]) } + + if infoParts[1] == "g" then + + local gemObj = {} + gemObj.enchantId = tonumber(infoParts[2]) + gemObj.id = tonumber(infoParts[3]) + + local identicalGems = infoParts[4] + if string.len(identicalGems) > 0 then + gemObj.identicalGroup = {} + identicalGems = { strsplit(",", identicalGems) } + for j = 1, #identicalGems do + gemObj.identicalGroup[tonumber(identicalGems[j])] = true + end + end + + gemObj.text = string.gsub(infoParts[5], "_(%a+)_", function(s) return L.AMR_STAT_SHORT_STRINGS[s] end) + if infoParts[6] == nil or string.len(infoParts[6]) == 0 then + gemObj.identicalItemGroup = {[gemObj.id]=true} + else + local identicalIds = { strsplit(',', infoParts[6]) } + gemObj.identicalItemGroup = {} + for j = 1, #identicalIds do + gemObj.identicalItemGroup[tonumber(identicalIds[j])] = true + end + end + + gemInfo[gemObj.enchantId] = gemObj + + elseif infoParts[1] == "e" then + + local enchObj = {} + enchObj.id = tonumber(infoParts[2]) + enchObj.itemId = tonumber(infoParts[3]) + enchObj.spellId = tonumber(infoParts[4]) + enchObj.text = string.gsub(infoParts[5], "_(%a+)_", function(s) return L.AMR_STAT_SHORT_STRINGS[s] end) + + local mats = infoParts[6] + if string.len(mats) > 0 then + enchObj.materials = {} + mats = { strsplit(",", mats) } + for j = 1, #mats do + local kv = { strsplit("=", mats[j]) } + enchObj.materials[tonumber(kv[1])] = tonumber(kv[2]) + end + end + + enchantInfo[enchObj.id] = enchObj + + end + end + + -- we have succeeded, record the result + AskMrRobot.ImportData = importData + AskMrRobot.ExtraItemData = itemInfo + AskMrRobot.ExtraGemData = gemInfo + AskMrRobot.ExtraEnchantData = enchantInfo + + AmrDb.LastCharacterImport = data + AmrDb.LastCharacterImportDate = date() end - -local function parseGlyphs(input) - local glyphs = {} - for glyph in string.gmatch(input, "([^,]+)") do - tinsert(glyphs, glyph) - end - table.sort(glyphs) - return glyphs -end - -local function parseProfessions(input) - local professions = {} - for prof, v in string.gmatch(input, "([^:,]+):([^,]+)") do - professions[prof] = tonumber(v); - end - return professions; -end - -local gemColorMapping = { - y = 'Yellow', - b = 'Blue', - r = 'Red', - h = 'Hydraulic', - p = 'Prismatic', - m = 'Meta', - c = 'Cogwheel' -} - -local function parseAmrItem(input) - local slot, itemId, suffixList, upgradeId, gemColorString, gemEnchantIdString, gemIdString, enchantId, reforgeId = string.match(input, "^(%d+):(%d+):([^:]+):([^:]+):([^:]+):([^:]+):([^:]+):(%d+):(%d+)"); - -- parse the gem enchant ids out of their comma seperated list - local gems = {} - for gemEnchantId in string.gmatch(gemEnchantIdString, '(%d+)') do - tinsert(gems, {enchantId = tonumber(gemEnchantId), id = 0}) - end - -- make sure we have 4 gem ids - for i = #gems + 1, 4 do - tinsert(gems, {enchantId = 0, id = 0}) - end - -- parse the gem ids out of their comma seperated list - local gemIds = {} - i = 1 - for gemId in string.gmatch(gemIdString, '(%d+)') do - gems[i].id = tonumber(gemId) - i = i + 1 - end - i = 1 - for gemColor in string.gmatch(gemColorString, '([^,])') do - gems[i].color = gemColorMapping[gemColor] - i = i + 1 - end - - -- parse the possible suffixes out of their comma seperated list and put them in a set (number -> bool) - local suffixes = {} - for suffixId in string.gmatch(suffixList, '(%-?%d+)') do - suffixes[tonumber(suffixId)] = true - end - - local item = { - itemId = tonumber(itemId), - suffixes = suffixes, - upgradeId = tonumber(upgradeId), - gems = gems, - enchantId = tonumber(enchantId), - reforgeId = tonumber(reforgeId) - } - return slot, item -end - - -function AskMrRobot.parseAmr(input) - local parsedInput = {} - parsedInput.items = {} - for k, v in string.gmatch(input, "([^=;]+)=([^;]*)") do - if (k == 'item') then - local slot, item = parseAmrItem(v); - parsedInput.items[AskMrRobot.slotIdToSlotNum[tonumber(slot) + 1]] = item; - elseif (k == 'glyphs') then - parsedInput.glyphs = parseGlyphs(v) - elseif (k == 'professions') then - parsedInput.professions = parseProfessions(v) - else - parsedInput[k]=v - end - end - return parsedInput -end - -function AskMrRobot.validateRealm(realm) - return realm == GetRealmName(); -end - -function AskMrRobot.validateCharacterName(characterName) - return UnitName("player") == characterName -end - -function AskMrRobot.validateRace(race) - local _, raceEn = UnitRace("player") - return raceEn == race or (raceEn == "Scourge" and race == "Undead") -end - -function AskMrRobot.validateFaction(faction) - return faction == UnitFactionGroup("player") -end - -function AskMrRobot.validateSpec(spec) - if spec == 'nil' then - spec = nil - end - local currentSpec = GetAmrSpecialization(GetActiveSpecGroup()) - return (not currentSpec and not spec) or tostring(currentSpec) == spec -end - -function AskMrRobot.validateTalents(talents) - if talents == nil then - talents = '' - end - return talents == GetAmrTalentsForSpec(GetActiveSpecGroup()) -end - -function AskMrRobot.validateGlyphs(glyphs) - if (glyphs == nil) then - glyphs = {}; - end - local currentGlyphs = GetAmrGlyphsForSpec(GetActiveSpecGroup()) - table.sort(glyphs, function(a,b) return tostring(a) < tostring(b) end) - table.sort(currentGlyphs, function(a,b) return tostring(a) < tostring(b) end) - - if #glyphs ~= #currentGlyphs then - return false - end - for i = 1, #glyphs do - if tostring(glyphs[i]) ~= tostring(currentGlyphs[i]) then - return false - end - end - - return true -end - -local function getPrimaryProfessions() - local profs = {} - local prof1, prof2 = GetProfessions() - local profMap = { - [794] = "Archaeology", - [171] = "Alchemy", - [164] = "Blacksmithing", - [185] = "Cooking", - [333] = "Enchanting", - [202] = "Engineering", - [129] = "First Aid", - [356] = "Fishing", - [182] = "Herbalism", - [773] = "Inscription", - [755] = "Jewelcrafting", - [165] = "Leatherworking", - [186] = "Mining", - [393] = "Skinning", - [197] = "Tailoring" - } - - if prof1 then - local _, _, skillLevel, _, _, _, skillLine = GetProfessionInfo(prof1); - if profMap[skillLine] ~= nil then - profs[profMap[skillLine]] = skillLevel - end - end - if prof2 then - local _, _, skillLevel, _, _, _, skillLine = GetProfessionInfo(prof2); - if profMap[skillLine] ~= nil then - profs[profMap[skillLine]] = skillLevel - end - end - return profs; -end - -local professionThresholds = { - Leatherworking = 575, - Inscription = 600, - Alchemy = 50, - Enchanting = 550, - Jewelcrafting = 550, - Blacksmithing = 550, - Tailoring = 550 -} - -function AskMrRobot.validateProfessions(professions) - local currentProfessions = getPrimaryProfessions() - if #currentProfessions ~= #professions then - return false - end - for k, v in pairs(professions) do - if currentProfessions[k] then - local threshold = professionThresholds[k] - if not threshold then - threshold = 1 - end - -- compare the desired profession against the threshold - local desired = v >= threshold - -- compare the current profession against the threshold - local has = currentProfessions[k] and currentProfessions[k] >= threshold - -- if the current value is on the other side of the threshold - -- then we don't match - if desired ~= has then - return false - end - else - return false - end - end - return true -end - -function AskMrRobot.populateItemDiffs(amrItem, itemLink, slotNum) - AskMrRobot.itemDiffs.items[slotNum] = nil - AskMrRobot.itemDiffs.gems[slotNum] = nil - AskMrRobot.itemDiffs.enchants[slotNum] = nil - AskMrRobot.itemDiffs.reforges[slotNum] = nil - - local needsUpgrade = false - local aSuffix = 0 - if amrItem then - for k,v in pairs(amrItem.suffixes) do - aSuffix = k - end - end - - if itemLink == nil then - if amrItem ~= nil then - AskMrRobot.itemDiffs.items[slotNum] = { - current = nil, - optimized = { itemId = amrItem.itemId, upgradeId = amrItem.upgradeId, suffixId = aSuffix }, - needsUpgrade = false - } - end - return - end - local item = parseItemLink(itemLink) - local isItemBad = false - - if amrItem == nil or item.itemId ~= amrItem.itemId then - isItemBad = true - else - if item.suffixId == 0 then - if #amrItem.suffixes > 0 then - isItemBad = true - end - else - if not amrItem.suffixes[item.suffixId] then - isItemBad = true - end - end - if not isItemBad and upgradeTable[item.upgradeId] ~= upgradeTable[amrItem.upgradeId] then - isItemBad = true - needsUpgrade = true - end - end - - if isItemBad then - AskMrRobot.itemDiffs.items[slotNum] = { - current = item.itemId, - optimized = { itemId = amrItem and amrItem.itemId or 0, upgradeId = amrItem and amrItem.upgradeId or 0, suffixId = aSuffix }, - needsUpgrade = needsUpgrade - } - return - end - - local badGemCount, gemInfo = AskMrRobot.MatchesGems(itemLink, item.gemEnchantIds, amrItem.gems) - if badGemCount > 0 then - AskMrRobot.itemDiffs.gems[slotNum] = gemInfo - end - - if item.enchantId ~= amrItem.enchantId then - AskMrRobot.itemDiffs.enchants[slotNum] = { - current = item.enchantId, - optimized = amrItem.enchantId - } - end - - if item.reforgeId ~= amrItem.reforgeId then - AskMrRobot.itemDiffs.reforges[slotNum] = { - current = item.reforgeId, - optimized = amrItem.reforgeId - } - end -end - ---[[ -function AskMrRobot.StartLogging() - if not LoggingCombat() then - LoggingCombat(1) - print("Started Combat Logging") - end -end - -function AskMrRobot.FinishLogging() - if LoggingCombat() then - LoggingCombat(0) - print("Finished Combat Logging") - end -end - --- local difficultyLookup = { --- DUNGEON_DIFFICULTY1, --- DUNGEON_DIFFICULTY2, --- RAID_DIFFICULTY_10PLAYER, --- RAID_DIFFICULTY_25PLAYER, --- RAID_DIFFICULTY_10PLAYER_HEROIC, --- RAID_DIFFICULTY_25PLAYER_HEROIC, --- RAID_FINDER, --- CHALLENGE_MODE, --- RAID_DIFFICULTY_40PLAYER, --- nil, --- nil, -- Norm scen --- nil, -- heroic scen --- nil, --- PLAYER_DIFFICULTY4 --- } - ---http://wowpedia.org/InstanceMapID -local instanceMaps = { - HeartOfFear = 1009, - MogushanVaults = 1008, - SiegeOfOrgrimmar = 1136, - TerraceOfEndlessSpring = 996, - ThroneOfThunder = 1098 -} - -function AskMrRobot.UpdateLogging() - - -- get the info about the instance - --local zone, zonetype, difficultyIndex, difficultyName, maxPlayers, dynamicDifficulty, isDynamic, instanceMapID = GetInstanceInfo() - local zone, _, difficultyIndex, _, _, _, _, instanceMapID = GetInstanceInfo() - --local difficulty = difficultyIndex - -- Unless Blizzard fixes scenarios to not return nil, let's hardcode this into returning "scenario" -Znuff - --if zonetype == nil and difficultyIndex == 1 then - --zonetype = "scenario" - --end - - -- if nothing has changed, then bail - --if (not zone) and difficulty == 0 then return end - if zone == AskMrRobot.lastzone and difficultyIndex == AskMrRobot.lastdiff then - -- do nothing if the zone hasn't ACTUALLY changed - -- otherwise we may override the user's manual enable/disable - return - end - - AskMrRobot.lastzone = zone - AskMrRobot.lastdiff = difficultyIndex - - if AmrOptions.autoLog[tonumber(instanceMapID)] then - if instanceMapID == instanceMaps.SiegeOfOrgrimmar then - AskMrRobot.StartLogging() - else - AskMrRobot.FinishLogging() - end - end -end -]] diff -r 9793e8b683d2 -r e77e01abce98 AskMrRobot.toc --- a/AskMrRobot.toc Thu Jul 10 15:32:11 2014 -0700 +++ b/AskMrRobot.toc Mon Oct 13 21:28:32 2014 -0500 @@ -1,12 +1,12 @@ -## Interface: 50400 +## Interface: 60000 ## Title: Ask Mr. Robot ## Author: Team Robot, Inc. -## Version: 1.2.16.0 +## Version: 2 ## Notes: Exports/Imports data to/from askmrrobot.com. ## URL: www.askmrrobot.com ## DefaultState: Enabled ## LoadOnDemand: 0 -## SavedVariablesPerCharacter: AmrBagItems,AmrBankItems,AmrEquipedItems,AmrGold,AmrRealmName,AmrCharacterName,AmrIconInfo,AmrCurrencies,AmrProfessions,AmrSpecializations,AmrRace,AmrLevel,AmrFaction,AmrActiveSpec,AmrOptions,AmrGlyphs,AmrTalents,AmrBankItemsAndCounts,AmrImportString,AmrImportDate,AmrSendSettings,AmrLogData +## SavedVariablesPerCharacter: AmrDb ## SavedVariables: AmrSettings #@no-lib-strip@ @@ -26,29 +26,31 @@ wait.lua sort.lua -enchants.lua -gems.lua + ui\Components.lua -ui\FontString.lua -ui\ScrollFrame.lua +amr-constants.lua +AskMrRobot.lua +config.lua +AskMrRobotUi.lua ui\RobotStamp.lua ui\ItemTooltipFrame.lua ui\ItemLinkText.lua ui\ItemIcon.lua ui\GemIcon.lua ui\EnchantLinkText.lua +ui\FontString.lua +ui\ScrollFrame.lua +ui\ExportTab.lua ui\JewelPanel.lua ui\SummaryTab.lua ui\GemTab.lua ui\EnchantTab.lua ui\HelpTab.lua ui\ImportTab.lua -ui\ExportTab.lua -ui\ReforgesTab.lua ui\ShoppingListTab.lua +ui\GearComparisonTab.lua ui\CombatLogTab.lua -AskMrRobotUi.lua -AskMrRobot.lua -config.lua + AskMrRobot.xml + diff -r 9793e8b683d2 -r e77e01abce98 AskMrRobotUi.lua --- a/AskMrRobotUi.lua Thu Jul 10 15:32:11 2014 -0700 +++ b/AskMrRobotUi.lua Mon Oct 13 21:28:32 2014 -0500 @@ -1,193 +1,95 @@ local _, AskMrRobot = ... local L = AskMrRobot.L; -local showImportDetailsError = nil -local showImportErrorTab = nil - AskMrRobot.AmrUI = AskMrRobot.inheritsFrom(AskMrRobot.Frame) -function AskMrRobot.AmrUI:swapSimilarSlotsIfNeeded(slotName1, slotName2) - local slotId1 = GetInventorySlotInfo(slotName1) - local slotId2 = GetInventorySlotInfo(slotName2) - local slotNum1 = AskMrRobot.slotIdToSlotNum[slotId1] - local slotNum2 = AskMrRobot.slotIdToSlotNum[slotId2] +local _menuIds = { + export = 1, + gear = 2, + combatLog = 3, + help = 4 +} - local itemLink1 = GetInventoryItemLink("player", slotId1) - local itemLink2 = GetInventoryItemLink("player", slotId2) +function AskMrRobot.AmrUI:new() + local o = AskMrRobot.Frame:new("AskMrRobot_Dialog", nil, "BasicFrameTemplateWithInset") - -- see how bad the items are in the original order - AskMrRobot.populateItemDiffs(self.importedItems[slotNum1], itemLink1, slotNum1) - AskMrRobot.populateItemDiffs(self.importedItems[slotNum2], itemLink2, slotNum2) + -- use the AmrUI class + setmetatable(o, { __index = AskMrRobot.AmrUI }) - local badCountOriginalOrder = 0 - if AskMrRobot.itemDiffs.items[slotNum1] then badCountOriginalOrder = badCountOriginalOrder + 1 end - if AskMrRobot.itemDiffs.items[slotNum2] then badCountOriginalOrder = badCountOriginalOrder + 1 end + o:RegisterForDrag("LeftButton"); + o:SetWidth(615) + o:SetHeight(550) + o.InsetBg:SetPoint("TOPLEFT", 140, -24) - -- try the order swapped - AskMrRobot.populateItemDiffs(self.importedItems[slotNum1], itemLink2, slotNum1) - AskMrRobot.populateItemDiffs(self.importedItems[slotNum2], itemLink1, slotNum2) + o:SetParent("UIParent") + o:SetPoint("CENTER") + o:Hide() + o:EnableMouse(true) + o:EnableKeyboard(true) + o.hideOnEscape = 1 + o:SetMovable(true) + o:SetToplevel(true) - local badCountNewOrder = 0 - if AskMrRobot.itemDiffs.items[slotNum1] then badCountNewOrder = badCountNewOrder + 1 end - if AskMrRobot.itemDiffs.items[slotNum2] then badCountNewOrder = badCountNewOrder + 1 end + o:SetScript("OnDragStart", AskMrRobot.AmrUI.OnDragStart) + o:SetScript("OnDragStop", AskMrRobot.AmrUI.OnDragStop) + o:SetScript("OnHide", AskMrRobot.AmrUI.OnHide) + o:SetScript("OnShow", AskMrRobot.AmrUI.OnShow) - -- if the items were less bad in the new order, swap the imported items - if badCountNewOrder < badCountOriginalOrder then - local tempItem = self.importedItems[slotNum1] - self.importedItems[slotNum1] = self.importedItems[slotNum2] - self.importedItems[slotNum2] = tempItem - end + o:RegisterEvent("AUCTION_HOUSE_CLOSED") + o:RegisterEvent("AUCTION_HOUSE_SHOW") + o:RegisterEvent("SOCKET_INFO_UPDATE") + o:RegisterEvent("SOCKET_INFO_CLOSE") + + o:SetScript("OnEvent", function(...) + o:OnEvent(...) + end) + + tinsert(UISpecialFrames, o:GetName()) + + -- initialize some fields + o.initialized = false + o.visible = false + + -- title + o.TitleText:SetText("--BETA-- Ask Mr. Robot v" .. GetAddOnMetadata(AskMrRobot.AddonName, "Version")) + + -- create the main menu + o.menu = o:createMainMenu() + + local tabArea = AskMrRobot.Frame:new(nil, o) + tabArea:SetPoint("TOPLEFT", 155, -30) + tabArea:SetPoint("BOTTOMRIGHT") + + o.exportTab = AskMrRobot.ExportTab:new(tabArea) + o.menu[_menuIds["export"]].element = o.exportTab + + o.gearComparisonTab = AskMrRobot.GearComparisonTab:new(tabArea) + o.menu[_menuIds["gear"]].element = o.gearComparisonTab + + o.combatLogTab = AskMrRobot.CombatLogTab:new(tabArea) + o.menu[_menuIds["combatLog"]].element = o.combatLogTab + + o.helpTab = AskMrRobot.HelpTab:new(tabArea) + o.menu[_menuIds["help"]].element = o.helpTab + + o:Hide() + o:ShowMenu("export") + + return o end -function AskMrRobot.AmrUI:displayImportItems() - if not self.importedItems then - return false - end - - --see if rings or trinkets are swapped, and alter self.importedItems accordingly - self:swapSimilarSlotsIfNeeded("Finger0Slot", "Finger1Slot") - self:swapSimilarSlotsIfNeeded("Trinket0Slot", "Trinket1Slot") - - for slotNum = 1, #AskMrRobot.slotIds do - if AskMrRobot.OptimizationSlots[slotNum] then - local slotId = AskMrRobot.slotIds[slotNum] - local itemLink = GetInventoryItemLink("player", slotId) - AskMrRobot.populateItemDiffs(self.importedItems[slotNum], itemLink, slotNum) - end - end - - self.summaryTab:showBadItems() - - -- if there are incorrect items equiped, display errors on other tabs - if AskMrRobot.itemDiffs and AskMrRobot.itemDiffs.items then - for k,v in pairs(AskMrRobot.itemDiffs.items) do - if not v.needsUpgrade then - self.hasImportError = true - end - end - end - - if self.hasImportError then - showImportDetailsError() - else - self.gemTab:Update() - self.enchantTab:showBadEnchants() - self.reforgeTab:Render() - self.shoppingTab:Update() - end -end - -function AskMrRobot.AmrUI:showImportError(text, ...) - self.summaryTab:showImportError(text, ...) - if text then - self.hasImportError = true - showImportDetailsError() - else - self.hasImportError = false - end -end - -function AskMrRobot.AmrUI:showImportWarning(text, ...) - self.summaryTab:showImportWarning(text, ...) - self.hasImportError = false - if text then - showImportDetailsError() - end -end - -function AskMrRobot.AmrUI:validateInput(input) - - self.importedItems = nil - self.mostlySuccess = false - - local parsed = AskMrRobot.parseAmr(input) - - if not parsed.realm then - self:showImportError(L.AMR_UI_IMPORT_ERROR_IMPROPER,L.AMR_UI_IMPORT_ERROR_IMPROPER_GOTO) - elseif not AskMrRobot.validateCharacterName(parsed.name) then - self:showImportError(L.AMR_UI_IMPORT_ERROR_CHARACTER:format(parsed.name), L.AMR_UI_IMPORT_ERROR_CHARACTER_GOTO) - elseif not AskMrRobot.validateRace(parsed.race) then - self:showImportError(L.AMR_UI_IMPORT_ERROR_RACE, L.AMR_UI_IMPORT_ERROR_RACE_CURRENT:format(parsed.race)) - elseif not AskMrRobot.validateFaction(parsed.faction) then - self:showImportError(L.AMR_UI_IMPORT_ERROR_FACTION, L.AMR_UI_IMPORT_ERROR_FACTION_CURRENT:format(parsed.faction)) - elseif not AskMrRobot.validateProfessions(parsed.professions) then - self:showImportError(L.AMR_UI_IMPORT_ERROR_PROFESSIONS, L.AMR_UI_IMPORT_ERROR_PROFESSIONS_GOTO) - elseif not AskMrRobot.validateSpec(parsed.spec) then - if parsed.spec and parsed.spec ~= 'nil' then - local _, specName = GetSpecializationInfoByID(parsed.spec) - self:showImportError(L.AMR_UI_IMPORT_ERROR_SPEC, L.AMR_UI_IMPORT_ERROR_SPEC_CHANGE:format(specName)) - else - self:showImportError(L.AMR_UI_IMPORT_ERROR_SPEC, L.AMR_UI_IMPORT_ERROR_SPEC_UNEXPECTED) - end - self.mostlySuccess = true - self.summaryTab.badRealm = nil - self.summaryTab.badTalents = nil - self.summaryTab.badGlyphs = nil - AmrImportString = input - else - self.summaryTab.badRealm = not AskMrRobot.validateRealm(parsed.realm) and parsed.realm - self.summaryTab.badTalents = not AskMrRobot.validateTalents(parsed.talents) - self.summaryTab.badGlyphs = not AskMrRobot.validateGlyphs(parsed.glyphs) - self.mostlySuccess = true - self:showImportError(nil) - AmrImportString = input - self.importedItems = parsed.items - return self:displayImportItems() - end - return false -end - -local function createImportDetailsErrorTab(reforgeFrame) - local tab = CreateFrame("Frame", nil, reforgeFrame) - tab:SetPoint("TOPLEFT") - tab:SetPoint("BOTTOMRIGHT") - tab:Hide() - - local text = tab:CreateFontString("AmrImportDetailsText1", "ARTWORK", "GameFontNormalLarge") - text:SetPoint("TOPLEFT", 0, -5) - text:SetText("Help") - - local errorText1 = tab:CreateFontString("AmrImportDetailsText2", "ARTWORK", "GameFontRed") - errorText1:SetPoint("TOPLEFT", "AmrImportDetailsText1", "BOTTOMLEFT", 0, -20) - errorText1:SetText(L.AMR_UI_IMPORT_ERROR_NO_IMPORT) - errorText1:SetPoint("RIGHT", -10, 0) - errorText1:SetWidth(errorText1:GetWidth()) - errorText1:SetJustifyH("LEFT") - - showImportDetailsError = function() - errorText1:SetText(L.AMR_UI_IMPORT_ERROR_CANT_OPTIMIZE) - end - - showImportErrorTab = function(tabName) - if not tabName then - tab:Hide() - else - text:SetText(tabName) - tab:Show() - end - end - - return tab -end - -function AskMrRobot.AmrUI:createTabButtons() - local importTabButton = CreateFrame("Button", "AmrImportTabButton", self, "OptionsListButtonTemplate") - +function AskMrRobot.AmrUI:createMainMenu() local buttons = {} - self.hasImportError = true local function onTabButtonClick(clickedButton, event, ...) - showImportErrorTab(nil) for i = 1, #buttons do local button = buttons[i] if clickedButton == button then button.highlight:SetVertexColor(1, 1, 0) button:LockHighlight() - if self.hasImportError and button.isImportDetails then - showImportErrorTab(button:GetText()) - elseif button.element then - button.element:Show() - end + if button.element then + button.element:Show() + end else button.highlight:SetVertexColor(.196, .388, .8) button:UnlockHighlight() @@ -198,11 +100,10 @@ end end - local function createButton(text, spacing, isImportDetails) + local function createButton(text, spacing) local lastButton = #buttons local i = lastButton + 1 local tabButton = CreateFrame("Button", "AmrTabButton" .. i, self, "OptionsListButtonTemplate") - tabButton.isImportDetails = isImportDetails tabButton:SetText(text) tabText = tabButton:GetFontString() tabText:SetPoint("LEFT", 6, 0) @@ -211,154 +112,38 @@ else tabButton:SetPoint("TOPLEFT", "AmrTabButton" .. lastButton, "BOTTOMLEFT", 0, spacing) end - tabButton:SetWidth(125) + tabButton:SetWidth(140) tabButton:SetHeight(20) tinsert(buttons, tabButton) tabButton:SetScript("OnClick", onTabButtonClick) end - createButton(L.AMR_UI_BUTTON_IMPORT, -35, false) - createButton(L.AMR_UI_BUTTON_SUMMARY, -20, false) - createButton(L.AMR_UI_BUTTON_GEMS, 0, true) - createButton(L.AMR_UI_BUTTON_ENCHANTS, 0, true) - createButton(L.AMR_UI_BUTTON_REFORGES, 0, true) - createButton(L.AMR_UI_BUTTON_SHOPPING_LIST, 0, true) - createButton(L.AMR_UI_BUTTON_BEST_IN_BAGS, -20, false) - createButton(L.AMR_UI_BUTTON_COMBAT_LOG, 0, false) - createButton(L.AMR_UI_BUTTON_HELP, -20, false) + createButton(L.AMR_UI_MENU_EXPORT, -35) + createButton(L.AMR_UI_MENU_GEAR, -20) + createButton(L.AMR_UI_MENU_COMBAT_LOG, 0) + createButton(L.AMR_UI_MENU_HELP, 0) return buttons end -function AskMrRobot.AmrUI:new() - local o = AskMrRobot.Frame:new("AskMrRobot_Dialog", nil, "BasicFrameTemplateWithInset") - - -- use the AmrUI class - setmetatable(o, { __index = AskMrRobot.AmrUI }) - - o:RegisterForDrag("LeftButton"); - o:SetWidth(600) - o:SetHeight(530) - o.InsetBg:SetPoint("TOPLEFT", 125, -24) - - o:SetParent("UIParent") - o:SetPoint("CENTER") - o:Hide() - o:EnableMouse(true) - o:EnableKeyboard(true) - o.hideOnEscape = 1 - o:SetMovable(true) - o:SetToplevel(true) - - --o:SetScript("OnEscapePressed", function) - o:SetScript("OnDragStart", AskMrRobot.AmrUI.OnDragStart) - o:SetScript("OnDragStop", AskMrRobot.AmrUI.OnDragStop) - o:SetScript("OnHide", AskMrRobot.AmrUI.OnHide) - -- make the UI show the first tab when its opened - o:SetScript("OnShow", AskMrRobot.AmrUI.OnShow) - - o:RegisterEvent("AUCTION_HOUSE_CLOSED") - o:RegisterEvent("AUCTION_HOUSE_SHOW") - o:RegisterEvent("FORGE_MASTER_OPENED") - o:RegisterEvent("FORGE_MASTER_CLOSED") - o:RegisterEvent("SOCKET_INFO_UPDATE") - o:RegisterEvent("SOCKET_INFO_CLOSE") - - o:SetScript("OnEvent", function(...) - o:OnEvent(...) - end) - - tinsert(UISpecialFrames, o:GetName()) - - -- title - o.TitleText:SetText("Ask Mr. Robot " .. GetAddOnMetadata(AskMrRobot.AddonName, "Version")) - - -- create the tab buttons - o.buttons = o:createTabButtons() - - local tabArea = AskMrRobot.Frame:new(nil, o) - tabArea:SetPoint("TOPLEFT", 140, -30) - tabArea:SetPoint("BOTTOMRIGHT") - - createImportDetailsErrorTab(tabArea) - - -- create the import tab and associated it with the import tab button - o.importTab = AskMrRobot.ImportTab:new(tabArea) - o.buttons[1].element = o.importTab - o.importTab.scrollFrame.EditBox:SetScript("OnEscapePressed", function() - o:Hide() - end) - - o.importTab.button:SetScript("OnClick", function(...) - o.summaryTab.importDate = date() - AmrImportDate = o.summaryTab.importDate - o:OnUpdate() - if o.mostlySuccess then - -- save import between sessions - AmrImportString = o.importTab.scrollFrame.EditBox:GetText() - AmrImportDate = o.summaryTab.importDate - end - o:ShowTab("summary") - end) - - o.summaryTab = AskMrRobot.SummaryTab:new(tabArea) - o.buttons[2].element = o.summaryTab - - o.gemTab = AskMrRobot.GemTab:new(nil, tabArea) - o.buttons[3].element = o.gemTab - - o.enchantTab = AskMrRobot.EnchantTab:new(tabArea) - o.buttons[4].element = o.enchantTab - - o.reforgeTab = AskMrRobot.ReforgesTab:new(tabArea) - o.buttons[5].element = o.reforgeTab - - o.shoppingTab = AskMrRobot.ShoppingListTab:new(tabArea) - o.buttons[6].element = o.shoppingTab - - o.shoppingTab.sendTo:SetScript("OnEscapePressed", function() - o:Hide() - end) - - o.exportTab = AskMrRobot.ExportTab:new(tabArea) - o.buttons[7].element = o.exportTab - - o.combatLogTab = AskMrRobot.CombatLogTab:new(tabArea) - o.buttons[8].element = o.combatLogTab - - o.helpTab = AskMrRobot.HelpTab:new(tabArea) - o.buttons[9].element = o.helpTab - - o.isSocketWindowVisible = false - o.isReforgeVisible = false - o.isAuctionHouseVisible = false - - --hide the UI - o:Hide() - - o:ShowTab("import") - - o.initialize = false - - return o +function AskMrRobot.AmrUI:ShowMenu(menu) + local id = _menuIds[menu] + if id then + self.menu[id]:Click() + end end -function AskMrRobot.AmrUI:OnUpdate() - local input = self.importTab.scrollFrame.EditBox:GetText() - if input and input:len() > 0 then - self:validateInput(input) +function AskMrRobot.AmrUI:Toggle() + if self.visible then + self:Hide() + else + self.visible = true + self:Show() end end function AskMrRobot.AmrUI:OnShow() - if not self.initialized then - -- remember the import settings between sessions - self.importTab.scrollFrame.EditBox:SetText(AmrImportString or "") - self.initialized = true - end - - self:OnUpdate() end function AskMrRobot.AmrUI:OnDragStart() @@ -376,121 +161,9 @@ self:StopMovingOrSizing() end -function AskMrRobot.AmrUI:ShowReforgeFrame() - self.visible = true - self:Show() -end - -function AskMrRobot.AmrUI:Toggle() - if self.visible then - self:Hide() - else - self:ShowReforgeFrame() - end -end - -local nameToButtonNumber = { - import = 1, - summary = 2, - gems = 3, - enchants = 4, - reforges = 5, - shopping = 6, - export = 7, - combatLog = 8, - help = 9 -} - -function AskMrRobot.AmrUI:ShowTab(tabName) - local buttonNumber = nameToButtonNumber[tabName] - if buttonNumber then - self.buttons[buttonNumber]:Click() - end -end - function AskMrRobot.AmrUI:OnEvent(frame, event, ...) local handler = self["On_" .. event] if handler then handler(self, ...) end end - -function AskMrRobot.AmrUI:On_AUCTION_HOUSE_SHOW() - self.isAuctionHouseVisible = true - if self.mostlySuccess then - local showTab = self.visible - if not AmrOptions.manualShowShop and not self.visible then - - -- show if there is anything to buy - if self.shoppingTab:HasStuffToBuy() then - self:Show() - showTab = true - end - end - - if showTab then - self:ShowTab("shopping") - end - end -end - -function AskMrRobot.AmrUI:On_AUCTION_HOUSE_CLOSED() - self.isAuctionHouseVisible = false - if self.isReforgeVisible then - self:ShowTab("reforges") - elseif self.isSocketWindowVisible then - self:ShowTab("gems") - end -end - -function AskMrRobot.AmrUI:On_FORGE_MASTER_OPENED() - self.isReforgeVisible = true - if self.mostlySuccess then - local showTab = self.visible - if not AmrOptions.manualShowReforge and not self.visible then - - -- see if there are any reforges to do - local reforgeCount = 0 - for slotNum, badReforge in pairs(AskMrRobot.itemDiffs.reforges) do - reforgeCount = reforgeCount + 1 - end - - if reforgeCount > 0 then - self:Show() - showTab = true - end - end - - if showTab then - self:ShowTab("reforges") - end - end -end - -function AskMrRobot.AmrUI:On_FORGE_MASTER_CLOSED() - self.isReforgeVisible = false - if self.isAuctionHouseVisible then - self:ShowTab("shopping") - elseif self.isSocketWindowVisible then - self:ShowTab("gems") - end -end - -function AskMrRobot.AmrUI:On_SOCKET_INFO_UPDATE() - self.isSocketWindowVisible = true - if self.mostlySuccess then - if not self.visible then - self:Show() - end - self:ShowTab("gems") - end -end - -function AskMrRobot.AmrUI:On_SOCKET_INFO_CLOSE() - self.isSocketWindowVisible = false - if self.isAuctionHouseVisible then - self:ShowTab("shopping") - elseif self.isReforgeVisible then - self:ShowTab("reforges") - end -end \ No newline at end of file diff -r 9793e8b683d2 -r e77e01abce98 Media/AddonExport.tga Binary file Media/AddonExport.tga has changed diff -r 9793e8b683d2 -r e77e01abce98 Media/BiBScreen.tga Binary file Media/BiBScreen.tga has changed diff -r 9793e8b683d2 -r e77e01abce98 Media/icon_green.tga Binary file Media/icon_green.tga has changed diff -r 9793e8b683d2 -r e77e01abce98 amr-constants.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/amr-constants.lua Mon Oct 13 21:28:32 2014 -0500 @@ -0,0 +1,252 @@ +local _, AskMrRobot = ... +local L = AskMrRobot.L; + +-- item link format: |cffa335ee|Hitem:itemID:enchant:gem1:gem2:gem3:gem4:suffixID:uniqueID:level:upgradeId:instanceDifficultyID:numBonusIDs:bonusID1:bonusID2...|h[item name]|h|r + +-- get an object with all of the parts fo the item link format that we care about +function AskMrRobot.parseItemLink(itemLink) + if not itemLink then return nil end + + local str = string.match(itemLink, "|Hitem:([\-%d:]+)|") + if not str then return nil end + + local parts = { strsplit(":", str) } + + local item = {} + item.id = tonumber(parts[1]) + item.enchantId = tonumber(parts[2]) + item.gemIds = { tonumber(parts[3]), tonumber(parts[4]), tonumber(parts[5]), tonumber(parts[6]) } + item.suffixId = math.abs(tonumber(parts[7])) -- convert suffix to positive number, that's what we use in our code + --item.uniqueId = tonumber(parts[8]) + --item.level = tonumber(parts[9]) + item.upgradeId = tonumber(parts[10]) + --item.difficultyId = tonumber(parts[11]) + + local numBonuses = tonumber(parts[12]) + if numBonuses > 0 then + item.bonusIds = {} + for i = 13, 12 + numBonuses do + table.insert(item.bonusIds, tonumber(parts[i])) + end + end + + return item +end + +-- convenience to get just the item id (or 0 if not a valid link) from an item link +function AskMrRobot.getItemIdFromLink(itemLink) + if not itemLink then return 0 end + local parts = { strsplit(":", itemLink) } + local id = tonumber(parts[2]) + return (id and id ~= 0 and id or 0) +end + +function AskMrRobot.getItemUniqueId(item, noUpgrade) + if item == nil then return "" end + local ret = item.id .. "" + if item.bonusIds then + for i = 1, #item.bonusIds do + ret = ret .. "b" .. item.bonusIds[i] + end + end + if item.suffixId ~= 0 then + ret = ret .. "s" .. item.suffixId + end + if not noUpgrade and item.upgradeId ~= 0 then + ret = ret .. "u" .. item.upgradeId + end + return ret +end + +AskMrRobot.instanceIds = { + HeartOfFear = 1009, + MogushanVaults = 1008, + SiegeOfOrgrimmar = 1136, + TerraceOfEndlessSpring = 996, + ThroneOfThunder = 1098 +} + +-- instances that we currently support logging for +AskMrRobot.supportedInstanceIds = { + [1136] = true +} + +-- returns true if currently in a supported instance +function AskMrRobot.IsSupportedInstance() + + local zone, _, difficultyIndex, _, _, _, _, instanceMapID = GetInstanceInfo() + if AskMrRobot.supportedInstanceIds[tonumber(instanceMapID)] then + return true + else + return false + end +end + +AskMrRobot.classIds = { + ["NONE"] = 0, + ["DEATHKNIGHT"] = 1, + ["DRUID"] = 2, + ["HUNTER"] = 3, + ["MAGE"] = 4, + ["MONK"] = 5, + ["PALADIN"] = 6, + ["PRIEST"] = 7, + ["ROGUE"] = 8, + ["SHAMAN"] = 9, + ["WARLOCK"] = 10, + ["WARRIOR"] = 11, +} + +AskMrRobot.professionIds = { + ["None"] = 0, + ["Mining"] = 1, + ["Skinning"] = 2, + ["Herbalism"] = 3, + ["Enchanting"] = 4, + ["Jewelcrafting"] = 5, + ["Engineering"] = 6, + ["Blacksmithing"] = 7, + ["Leatherworking"] = 8, + ["Inscription"] = 9, + ["Tailoring"] = 10, + ["Alchemy"] = 11, + ["Fishing"] = 12, + ["Cooking"] = 13, + ["First Aid"] = 14, + ["Archaeology"] = 15 +} + +AskMrRobot.raceIds = { + ["None"] = 0, + ["BloodElf"] = 1, + ["Draenei"] = 2, + ["Dwarf"] = 3, + ["Gnome"] = 4, + ["Human"] = 5, + ["NightElf"] = 6, + ["Orc"] = 7, + ["Tauren"] = 8, + ["Troll"] = 9, + ["Scourge"] = 10, + ["Undead"] = 10, + ["Goblin"] = 11, + ["Worgen"] = 12, + ["Pandaren"] = 13 +} + +AskMrRobot.factionIds = { + ["None"] = 0, + ["Alliance"] = 1, + ["Horde"] = 2 +} + +AskMrRobot.specIds = { + [250] = 1, -- DeathKnightBlood + [251] = 2, -- DeathKnightFrost + [252] = 3, -- DeathKnightUnholy + [102] = 4, -- DruidBalance + [103] = 5, -- DruidFeral + [104] = 6, -- DruidGuardian + [105] = 7, -- DruidRestoration + [253] = 8, -- HunterBeastMastery + [254] = 9, -- HunterMarksmanship + [255] = 10, -- HunterSurvival + [62] = 11, -- MageArcane + [63] = 12, -- MageFire + [64] = 13, -- MageFrost + [268] = 14, -- MonkBrewmaster + [269] = 15, -- MonkMistweaver + [270] = 16, -- MonkWindwalker + [65] = 17, -- PaladinHoly + [66] = 18, -- PaladinProtection + [70] = 19, -- PaladinRetribution + [256] = 20, -- PriestDiscipline + [257] = 21, -- PriestHoly + [258] = 22, -- PriestShadow + [259] = 23, -- RogueAssassination + [260] = 24, -- RogueCombat + [261] = 25, -- RogueSubtlety + [262] = 26, -- ShamanElemental + [263] = 27, -- ShamanEnhancement + [264] = 28, -- ShamanRestoration + [265] = 29, -- WarlockAffliction + [266] = 30, -- WarlockDemonology + [267] = 31, -- WarlockDestruction + [71] = 32, -- WarriorArms + [72] = 33, -- WarriorFury + [73] = 34 -- WarriorProtection +} + +-- reverse map of our spec ID to the game's spec ID +AskMrRobot.gameSpecIds = {} +for k,v in pairs(AskMrRobot.specIds) do + AskMrRobot.gameSpecIds[v] = k +end + +-- lookup from our socket color ID to string +AskMrRobot.socketColorIds = { + [0] = "Prismatic", + [1] = "Red", + [2] = "Yellow", + [3] = "Blue", + [4] = "Meta", + [5] = "Cogwheel", + [6] = "ShaTouched" +} + +-- map of game slot names to slot IDs (same both in our code and in-game) +AskMrRobot.slotNameToId = { + ["HeadSlot"] = 1, + ["NeckSlot"] = 2, + ["ShoulderSlot"] = 3, + ["ChestSlot"] = 5, + ["WaistSlot"] = 6, + ["LegsSlot"] = 7, + ["FeetSlot"] = 8, + ["WristSlot"] = 9, + ["HandsSlot"] = 10, + ["Finger0Slot"] = 11, + ["Finger1Slot"] = 12, + ["Trinket0Slot"] = 13, + ["Trinket1Slot"] = 14, + ["BackSlot"] = 15, + ["MainHandSlot"] = 16, + ["SecondaryHandSlot"] = 17 +} + +-- map of slot ID to display text +AskMrRobot.slotDisplayText = { + [1] = _G["HEADSLOT"], + [2] = _G["NECKSLOT"], + [3] = _G["SHOULDERSLOT"], + [5] = _G["CHESTSLOT"], + [6] = _G["WAISTSLOT"], + [7] = _G["LEGSSLOT"], + [8] = _G["FEETSLOT"], + [9] = _G["WROSTSLOT"], + [10] = _G["HANDSSLOT"], + [11] = _G["FINGER0SLOT"], + [12] = _G["FINGER1SLOT"], + [13] = _G["TRINKET0SLOT"], + [14] = _G["TRINKET1SLOT"], + [15] = _G["BACKSLOT"], + [16] = _G["MAINHANDSLOT"], + [17] = _G["SECONDARYHANDSLOT"] +} + +-- all slot IDs that we care about, ordered in our standard display order +AskMrRobot.slotIds = { 16, 17, 1, 2, 3, 15, 5, 9, 10, 6, 7, 8, 11, 12, 13, 14 } + +-- cache slot orders to make slot sorting easier +local _slotIdToOrder = {} +for i = 1, #AskMrRobot.slotIds do + _slotIdToOrder[AskMrRobot.slotIds[i]] = i +end + +-- given a table where the keys are slot IDs, sort in the standard slot order +function AskMrRobot.sortSlots(t) + return AskMrRobot.spairs(t, function(x, a, b) + if a == nil and b == nil then return 0 end + return _slotIdToOrder[a] < _slotIdToOrder[b] + end) +end diff -r 9793e8b683d2 -r e77e01abce98 config.lua --- a/config.lua Thu Jul 10 15:32:11 2014 -0700 +++ b/config.lua Mon Oct 13 21:28:32 2014 -0500 @@ -1,6 +1,4 @@ local addonName, AskMrRobot = ... - ---if not addon.healthCheck then return end local L = AskMrRobot.L local wow_ver = select(4, GetBuildInfo()) @@ -43,70 +41,39 @@ subtitle:SetText(L.AMR_CONFIG_EXIMPORT) subTitleWrapper:SetHeight(subtitle:GetHeight()) + -- hide minimap icon local autoPopup = newCheckbox( L.AMR_CONFIG_CHECKBOX_MINIMAP_LABEL, L.AMR_CONFIG_CHECKBOX_MINIMAP_TOOLTIP_TITLE, L.AMR_CONFIG_CHECKBOX_MINIMAP_DESCRIPTION, function(self, value) - if AmrOptions.hideMapIcon then - AmrOptions.hideMapIcon = false + if AmrDb.Options.hideMapIcon then + AmrDb.Options.hideMapIcon = false else - AmrOptions.hideMapIcon = true + AmrDb.Options.hideMapIcon = true end AskMrRobot.AmrUpdateMinimap(); end ) - autoPopup:SetChecked(not AmrOptions.hideMapIcon) + autoPopup:SetChecked(not AmrDb.Options.hideMapIcon) autoPopup:SetPoint("TOPLEFT", subTitleWrapper, "BOTTOMLEFT", -2, -16) - local autoReforge = newCheckbox( - L.AMR_CONFIG_CHECKBOX_AUTOREFORGE_LABEL, - L.AMR_CONFIG_CHECKBOX_AUTOREFORGE_TOOLTIP_TITLE, - L.AMR_CONFIG_CHECKBOX_AUTOREFORGE_DESCRIPTION, - function(self, value) - if AmrOptions.manualShowReforge then - AmrOptions.manualShowReforge = false - else - AmrOptions.manualShowReforge = true - end - end - ) - autoReforge:SetChecked(not AmrOptions.manualShowReforge) - autoReforge:SetPoint("TOPLEFT", subTitleWrapper, "BOTTOMLEFT", -2, -52) + -- auto-show at auction house local autoAh = newCheckbox( L.AMR_CONFIG_CHECKBOX_AUTOAH_LABEL, L.AMR_CONFIG_CHECKBOX_AUTOAH_TOOLTIP_TITLE, L.AMR_CONFIG_CHECKBOX_AUTOAH_DESCRIPTION, function(self, value) - if AmrOptions.manualShowShop then - AmrOptions.manualShowShop = false + if AmrDb.Options.manualShowShop then + AmrDb.Options.manualShowShop = false else - AmrOptions.manualShowShop = true + AmrDb.Options.manualShowShop = true end end ) - autoAh:SetChecked(not AmrOptions.manualShowShop) - autoAh:SetPoint("TOPLEFT", subTitleWrapper, "BOTTOMLEFT", -2, -88) - - --[[ - AmrOptions.autoLog = AmrOptions.autoLog or {} - - local autoCombatLog = newCheckbox( - L.AMR_CONFIG_CHECKBOX_AUTOLOG_LABEL, - L.AMR_CONFIG_CHECKBOX_AUTOLOG_TOOLTIP_TITLE, - L.AMR_CONFIG_CHECKBOX_AUTOLOG_DESCRIPTION, - function(self, value) - if AmrOptions.autoLog[1136] then - AmrOptions.autoLog[1136] = false - else - AmrOptions.autoLog[1136] = true - end - end - ) - autoCombatLog:SetChecked(AmrOptions.autoLog[1136]) - autoCombatLog:SetPoint("TOPLEFT", subTitleWrapper, "BOTTOMLEFT", -2, -124) - ]] + autoAh:SetChecked(not AmrDb.Options.manualShowShop) + autoAh:SetPoint("TOPLEFT", subTitleWrapper, "BOTTOMLEFT", -2, -58) frame:SetScript("OnShow", nil) end) diff -r 9793e8b683d2 -r e77e01abce98 enchants.lua --- a/enchants.lua Thu Jul 10 15:32:11 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4247 +0,0 @@ -local _, AskMrRobot = ... - -local enchantNames = { -[-1000]="Belt Buckle", -[2]="Frostbrand", -[5]="Flametongue", -[13]="Sharpened (+3 Damage)", -[14]="Sharpened (+4 Damage)", -[15]="8 Armor", -[16]="16 Armor", -[17]="24 Armor", -[18]="32 Armor", -[19]="Weighted (+2 Damage)", -[20]="Weighted (+3 Damage)", -[21]="Weighted (+4 Damage)", -[24]="+5 Mana", -[25]="Shadow Oil", -[26]="Frost Oil", -[27]="Sundered", -[28]="+4 All Resistances", -[30]="Scope (+1 Damage)", -[31]="+4 Beastslaying", -[32]="Scope (+2 Damage)", -[33]="Scope (+3 Damage)", -[34]="20 Haste", -[36]="Enchant: Fiery Blaze", -[37]="Steel Weapon Chain", -[38]="5 Dodge", -[39]="Sharpened (+1 Damage)", -[40]="Sharpened (+2 Damage)", -[41]="+5 Health", -[43]="Iron Spike (8-12)", -[44]="Absorption (10)", -[63]="Absorption (25)", -[64]="3 Spirit", -[65]="+1 All Resistances", -[66]="1 Stam", -[67]="+1 Damage", -[68]="1 Str", -[69]="2 Str", -[70]="3 Str", -[71]="1 Stam", -[72]="2 Stam", -[73]="3 Stam", -[74]="1 Agi", -[75]="2 Agi", -[76]="3 Agi", -[77]="+2 Damage", -[78]="+3 Damage", -[79]="1 Int", -[80]="2 Int", -[81]="3 Int", -[82]="1 Spirit", -[83]="2 Spirit", -[84]="3 Spirit", -[85]="3 Armor", -[86]="8 Armor", -[87]="12 Armor", -[89]="16 Armor", -[90]="4 Agi", -[91]="5 Agi", -[92]="6 Agi", -[93]="7 Agi", -[94]="4 Int", -[95]="5 Int", -[96]="6 Int", -[97]="7 Int", -[98]="4 Spirit", -[99]="5 Spirit", -[100]="6 Spirit", -[101]="7 Spirit", -[102]="4 Stam", -[103]="5 Stam", -[104]="6 Stam", -[105]="7 Stam", -[106]="4 Str", -[107]="5 Str", -[108]="6 Str", -[109]="7 Str", -[110]="1 Dodge", -[111]="2 Dodge", -[112]="3 Dodge", -[113]="4 Dodge", -[114]="5 Dodge", -[115]="6 Dodge", -[116]="7 Dodge", -[117]="+4 Damage", -[118]="+5 Damage", -[119]="+6 Damage", -[120]="+7 Damage", -[121]="20 Armor", -[122]="24 Armor", -[123]="28 Armor", -[125]="+1 Sword Skill", -[126]="+2 Sword Skill", -[127]="+3 Sword Skill", -[128]="+4 Sword Skill", -[129]="+5 Sword Skill", -[130]="+6 Sword Skill", -[131]="+7 Sword Skill", -[132]="+1 Two-Handed Sword Skill", -[133]="+2 Two-Handed Sword Skill", -[134]="+3 Two-Handed Sword Skill", -[135]="+4 Two-Handed Sword Skill", -[136]="+5 Two-Handed Sword Skill", -[137]="+6 Two-Handed Sword Skill", -[138]="+7 Two-Handed Sword Skill", -[139]="+1 Mace Skill", -[140]="+2 Mace Skill", -[141]="+3 Mace Skill", -[142]="+4 Mace Skill", -[143]="+5 Mace Skill", -[144]="+6 Mace Skill", -[145]="+7 Mace Skill", -[146]="+1 Two-Handed Mace Skill", -[147]="+2 Two-Handed Mace Skill", -[148]="+3 Two-Handed Mace Skill", -[149]="+4 Two-Handed Mace Skill", -[150]="+5 Two-Handed Mace Skill", -[151]="+6 Two-Handed Mace Skill", -[152]="+7 Two-Handed Mace Skill", -[153]="+1 Axe Skill", -[154]="+2 Axe Skill", -[155]="+3 Axe Skill", -[156]="+4 Axe Skill", -[157]="+5 Axe Skill", -[158]="+6 Ase Skill", -[159]="+7 Axe Skill", -[160]="+1 Two-Handed Axe Skill", -[161]="+2 Two-Handed Axe Skill", -[162]="+3 Two-Handed Axe Skill", -[163]="+4 Two-Handed Axe Skill", -[164]="+5 Two-Handed Axe Skill", -[165]="+6 Two-Handed Axe Skill", -[166]="+7 Two-Handed Axe Skill", -[167]="+1 Dagger Skill", -[168]="+2 Dagger Skill", -[169]="+3 Dagger Skill", -[170]="+4 Dagger Skill", -[171]="+5 Dagger Skill", -[172]="+6 Dagger Skill", -[173]="+7 Dagger Skill", -[174]="+1 Gun Skill", -[175]="+2 Gun Skill", -[176]="+3 Gun Skill", -[177]="+4 Gun Skill", -[178]="+5 Gun Skill", -[179]="+6 Gun Skill", -[180]="+7 Gun Skill", -[181]="+1 Bow Skill", -[182]="+2 Bow Skill", -[183]="+3 Bow Skill", -[184]="+4 Bow Skill", -[185]="+5 Bow Skill", -[186]="+6 Bow Skill", -[187]="+7 Bow Skill", -[188]="+2 Beast Slaying", -[189]="+4 Beast Slaying", -[190]="+6 Beast Slaying", -[191]="+8 Beast Slaying", -[192]="+10 Beast Slaying", -[193]="+12 Beast Slaying", -[194]="+14 Beast Slaying", -[195]="14 Crit", -[196]="28 Crit", -[197]="42 Crit", -[198]="56 Crit", -[199]="10% On Get Hit: Shadow Bolt (10 Damage)", -[200]="10% On Get Hit: Shadow Bolt (20 Damage)", -[201]="10% On Get Hit: Shadow Bolt (30 Damage)", -[202]="10% On Get Hit: Shadow Bolt (40 Damage)", -[203]="10% On Get Hit: Shadow Bolt (50 Damage)", -[204]="10% On Get Hit: Shadow Bolt (60 Damage)", -[205]="10% On Get Hit: Shadow Bolt (70 Damage)", -[206]="1 SP", -[207]="2 SP", -[208]="4 SP", -[209]="5 SP", -[210]="6 SP", -[211]="7 SP", -[212]="8 SP", -[213]="+1 Fire Spell Damage", -[214]="+3 Fire Spell Damage", -[215]="+4 Fire Spell Damage", -[216]="+6 Fire Spell Damage", -[217]="+7 Fire Spell Damage", -[218]="+9 Fire Spell Damage", -[219]="+10 Fire Spell Damage", -[220]="+1 Nature Spell Damage", -[221]="+3 Nature Spell Damage", -[222]="+4 Nature Spell Damage", -[223]="+6 Nature Spell Damage", -[224]="+7 Nature Spell Damage", -[225]="+9 Nature Spell Damage", -[226]="+10 Nature Spell Damage", -[227]="+1 Frost Spell Damage", -[228]="+3 Frost Spell Damage", -[229]="+4 Frost Spell Damage", -[230]="+6 Frost Spell Damage", -[231]="+7 Frost Spell Damage", -[232]="+9 Frost Spell Damage", -[233]="+10 Frost Spell Damage", -[234]="+1 Shadow Spell Damage", -[235]="+3 Shadow Spell Damage", -[236]="+4 Shadow Spell Damage", -[237]="+6 Shadow Spell Damage", -[238]="+7 Shadow Spell Damage", -[239]="+9 Shadow Spell Damage", -[240]="+10 Shadow Spell Damage", -[241]="+2 Weapon Damage", -[242]="+15 Health", -[243]="1 Spirit", -[244]="4 Int", -[245]="5 Armor", -[246]="+20 Mana", -[247]="1 Agi", -[248]="1 Str", -[249]="+2 Beastslaying", -[250]="+1 Weapon Damage", -[251]="1 Int", -[252]="6 Spirit", -[253]="Absorption (50)", -[254]="+25 Health", -[255]="3 Spirit", -[256]="+5 Fire Resistance", -[257]="10 Armor", -[263]="Fishing Lure (+25 Fishing Skill)", -[264]="Fishing Lure (+50 Fishing Skill)", -[265]="Fishing Lure (+75 Fishing Skill)", -[266]="Fishing Lure (+100 Fishing Skill)", -[283]="Windfury", -[286]="+2 Weapon Fire Damage", -[287]="+4 Weapon Fire Damage", -[288]="+6 Weapon Fire Damage", -[289]="+8 Weapon Fire Damage", -[290]="+0 Weapon Fire Damage", -[291]="+12 Weapon Fire Damage", -[292]="+14 Weapon Fire Damage", -[303]="Orb of Fire", -[343]="8 Agi", -[344]="32 Armor", -[345]="40 Armor", -[346]="36 Armor", -[347]="44 Armor", -[348]="48 Armor", -[349]="9 Agi", -[350]="8 Int", -[351]="8 Spirit", -[352]="8 Str", -[353]="8 Stam", -[354]="9 Int", -[355]="9 Spirit", -[356]="9 Stam", -[357]="9 Str", -[358]="10 Agi", -[359]="10 Int", -[360]="10 Spirit", -[361]="10 Stam", -[362]="10 Str", -[363]="11 Agi", -[364]="11 Int", -[365]="11 Spirit", -[366]="11 Stam", -[367]="11 Str", -[368]="12 Agi", -[369]="12 Int", -[370]="12 Spirit", -[371]="12 Stam", -[372]="12 Str", -[383]="52 Armor", -[384]="56 Armor", -[385]="60 Armor", -[386]="16 Armor", -[387]="17 Armor", -[388]="18 Armor", -[389]="19 Armor", -[403]="13 Agi", -[404]="14 Agi", -[405]="13 Int", -[406]="14 Int", -[407]="13 Spirit", -[408]="14 Spirit", -[409]="13 Stam", -[410]="13 Str", -[411]="14 Stam", -[412]="14 Str", -[423]="1 SP", -[424]="2 SP", -[425]="Black Temple Dummy", -[426]="5 SP", -[427]="6 SP", -[428]="7 SP", -[429]="8 SP", -[430]="9 SP", -[431]="11 SP", -[432]="12 SP", -[433]="+11 Fire Spell Damage", -[434]="+13 Fire Spell Damage", -[435]="+14 Fire Spell Damage", -[436]="70 Crit", -[437]="+11 Frost Spell Damage", -[438]="+13 Frost Spell Damage", -[439]="+14 Frost Spell Damage", -[440]="9 SP", -[441]="11 SP", -[442]="12 SP", -[443]="+11 Nature Spell Damage", -[444]="+13 Nature Spell Damage", -[445]="+14 Nature Spell Damage", -[446]="+11 Shadow Spell Damage", -[447]="+13 Shadow Spell Damage", -[448]="+14 Shadow Spell Damage", -[463]="Mithril Spike (16-20)", -[464]="+4% Mount Speed", -[483]="Sharpened (+6 Damage)", -[484]="Weighted (+6 Damage)", -[583]="1 Agi, 1 Spirit", -[584]="1 Agi, 1 Int", -[585]="1 Agi, 1 Stam", -[586]="1 Agi, 1 Str", -[587]="1 Int, 1 Spirit", -[588]="1 Int, 1 Stam", -[589]="1 Int, 1 Str", -[590]="1 Stam, 1 Spirit", -[591]="1 Str, 1 Spirit", -[592]="1 Stam, 1 Str", -[663]="Scope (+5 Damage)", -[664]="Scope (+7 Damage)", -[684]="15 Str", -[723]="3 Int", -[724]="3 Stam", -[743]="+2 Stealth", -[744]="20 Armor", -[763]="+5 Shield Block", -[783]="10 Armor", -[803]="Fiery Weapon", -[804]="+10 Shadow Resistance", -[805]="+4 Weapon Damage", -[823]="3 Str", -[843]="+30 Mana", -[844]="+2 Mining", -[845]="+2 Herbalism", -[846]="+5 Fishing", -[847]="1 Str, 1 Agi, 1 Stam, 1 Int, 1 Spirit", -[848]="30 Armor", -[849]="3 Agi", -[850]="+35 Health", -[851]="5 Spirit", -[852]="5 Stam", -[853]="+6 Beastslaying", -[854]="+6 Elemental Slayer", -[855]="+5 Fire Resistance", -[856]="5 Str", -[857]="+50 Mana", -[863]="10 Parry", -[864]="+4 Weapon Damage", -[865]="+5 Skinning", -[866]="2 Str, 2 Agi, 2 Stam, 2 Int, 2 Spirit", -[883]="15 Agi", -[884]="50 Armor", -[903]="+3 All Resistances", -[904]="5 Agi", -[905]="5 Int", -[906]="+5 Mining", -[907]="7 Spirit", -[908]="+50 Health", -[909]="+5 Herbalism", -[910]="8 Agi, 8 Dodge", -[911]=", Run Speed", -[912]="Demonslaying", -[913]="+65 Mana", -[923]="5 Dodge", -[924]="2 Dodge", -[925]="3 Dodge", -[926]="+8 Frost Resistance", -[927]="7 Str", -[928]="3 Str, 3 Agi, 3 Stam, 3 Int, 3 Spirit", -[929]="7 Stam", -[930]="+2% Mount Speed", -[931]="10 Haste", -[943]="+3 Weapon Damage", -[963]="+7 Weapon Damage", -[983]="16 Agi", -[1003]="Venomhide Poison", -[1043]="16 Str", -[1044]="17 Str", -[1045]="18 Str", -[1046]="19 Str", -[1047]="20 Str", -[1048]="21 Str", -[1049]="22 Str", -[1050]="23 Str", -[1051]="24 Str", -[1052]="25 Str", -[1053]="26 Str", -[1054]="27 Str", -[1055]="28 Str", -[1056]="29 Str", -[1057]="30 Str", -[1058]="31 Str", -[1059]="32 Str", -[1060]="33 Str", -[1061]="34 Str", -[1062]="35 Str", -[1063]="36 Str", -[1064]="37 Str", -[1065]="38 Str", -[1066]="39 Str", -[1067]="40 Str", -[1068]="15 Stam", -[1069]="16 Stam", -[1070]="17 Stam", -[1071]="18 Stam", -[1072]="19 Stam", -[1073]="20 Stam", -[1074]="21 Stam", -[1075]="22 Stam", -[1076]="23 Stam", -[1077]="24 Stam", -[1078]="25 Stam", -[1079]="26 Stam", -[1080]="27 Stam", -[1081]="28 Stam", -[1082]="29 Stam", -[1083]="30 Stam", -[1084]="31 Stam", -[1085]="32 Stam", -[1086]="33 Stam", -[1087]="34 Stam", -[1088]="35 Stam", -[1089]="36 Stam", -[1090]="37 Stam", -[1091]="38 Stam", -[1092]="39 Stam", -[1093]="40 Stam", -[1094]="17 Agi", -[1095]="18 Agi", -[1096]="19 Agi", -[1097]="20 Agi", -[1098]="21 Agi", -[1099]="22 Agi", -[1100]="23 Agi", -[1101]="24 Agi", -[1102]="25 Agi", -[1103]="26 Agi", -[1104]="27 Agi", -[1105]="28 Agi", -[1106]="29 Agi", -[1107]="30 Agi", -[1108]="31 Agi", -[1109]="32 Agi", -[1110]="33 Agi", -[1111]="34 Agi", -[1112]="35 Agi", -[1113]="36 Agi", -[1114]="37 Agi", -[1115]="38 Agi", -[1116]="39 Agi", -[1117]="40 Agi", -[1118]="15 Int", -[1119]="16 Int", -[1120]="17 Int", -[1121]="18 Int", -[1122]="19 Int", -[1123]="20 Int", -[1124]="21 Int", -[1125]="22 Int", -[1126]="23 Int", -[1127]="24 Int", -[1128]="25 Int", -[1129]="26 Int", -[1130]="27 Int", -[1131]="28 Int", -[1132]="29 Int", -[1133]="30 Int", -[1134]="31 Int", -[1135]="32 Int", -[1136]="33 Int", -[1137]="34 Int", -[1138]="35 Int", -[1139]="36 Int", -[1140]="37 Int", -[1141]="38 Int", -[1142]="39 Int", -[1143]="40 Int", -[1144]="15 Spirit", -[1145]="16 Spirit", -[1146]="17 Spirit", -[1147]="18 Spirit", -[1148]="19 Spirit", -[1149]="20 Spirit", -[1150]="21 Spirit", -[1151]="22 Spirit", -[1152]="23 Spirit", -[1153]="24 Spirit", -[1154]="25 Spirit", -[1155]="26 Spirit", -[1156]="27 Spirit", -[1157]="28 Spirit", -[1158]="29 Spirit", -[1159]="30 Spirit", -[1160]="31 Spirit", -[1161]="32 Spirit", -[1162]="33 Spirit", -[1163]="34 Spirit", -[1164]="36 Spirit", -[1165]="37 Spirit", -[1166]="38 Spirit", -[1167]="39 Spirit", -[1168]="40 Spirit", -[1183]="35 Spirit", -[1203]="41 Str", -[1204]="42 Str", -[1205]="43 Str", -[1206]="44 Str", -[1207]="45 Str", -[1208]="46 Str", -[1209]="41 Stam", -[1210]="42 Stam", -[1211]="43 Stam", -[1212]="44 Stam", -[1213]="45 Stam", -[1214]="46 Stam", -[1215]="41 Agi", -[1216]="42 Agi", -[1217]="43 Agi", -[1218]="44 Agi", -[1219]="45 Agi", -[1220]="46 Agi", -[1221]="41 Int", -[1222]="42 Int", -[1223]="43 Int", -[1224]="44 Int", -[1225]="45 Int", -[1226]="46 Int", -[1227]="41 Spirit", -[1228]="42 Spirit", -[1229]="43 Spirit", -[1230]="44 Spirit", -[1231]="45 Spirit", -[1232]="46 Spirit", -[1243]="+1 Arcane Resistance", -[1244]="+2 Arcane Resistance", -[1245]="+3 Arcane Resistance", -[1246]="+4 Arcane Resistance", -[1247]="+5 Arcane Resistance", -[1248]="+6 Arcane Resistance", -[1249]="+7 Arcane Resistance", -[1250]="+8 Arcane Resistance", -[1251]="+9 Arcane Resistance", -[1252]="+10 Arcane Resistance", -[1253]="+11 Arcane Resistance", -[1254]="+12 Arcane Resistance", -[1255]="+13 Arcane Resistance", -[1256]="+14 Arcane Resistance", -[1257]="+15 Arcane Resistance", -[1258]="+16 Arcane Resistance", -[1259]="+17 Arcane Resistance", -[1260]="+18 Arcane Resistance", -[1261]="+19 Arcane Resistance", -[1262]="+20 Arcane Resistance", -[1263]="+21 Arcane Resistance", -[1264]="+22 Arcane Resistance", -[1265]="+23 Arcane Resistance", -[1266]="+24 Arcane Resistance", -[1267]="+25 Arcane Resistance", -[1268]="+26 Arcane Resistance", -[1269]="+27 Arcane Resistance", -[1270]="+28 Arcane Resistance", -[1271]="+29 Arcane Resistance", -[1272]="+30 Arcane Resistance", -[1273]="+31 Arcane Resistance", -[1274]="+32 Arcane Resistance", -[1275]="+33 Arcane Resistance", -[1276]="+34 Arcane Resistance", -[1277]="+35 Arcane Resistance", -[1278]="+36 Arcane Resistance", -[1279]="+37 Arcane Resistance", -[1280]="+38 Arcane Resistance", -[1281]="+39 Arcane Resistance", -[1282]="+40 Arcane Resistance", -[1283]="+41 Arcane Resistance", -[1284]="+42 Arcane Resistance", -[1285]="+43 Arcane Resistance", -[1286]="+44 Arcane Resistance", -[1287]="+45 Arcane Resistance", -[1288]="+46 Arcane Resistance", -[1289]="+1 Frost Resistance", -[1290]="+2 Frost Resistance", -[1291]="+3 Frost Resistance", -[1292]="+4 Frost Resistance", -[1293]="+5 Frost Resistance", -[1294]="+6 Frost Resistance", -[1295]="+7 Frost Resistance", -[1296]="+8 Frost Resistance", -[1297]="+9 Frost Resistance", -[1298]="+10 Frost Resistance", -[1299]="+11 Frost Resistance", -[1300]="+12 Frost Resistance", -[1301]="+13 Frost Resistance", -[1302]="+14 Frost Resistance", -[1303]="+15 Frost Resistance", -[1304]="+16 Frost Resistance", -[1305]="+17 Frost Resistance", -[1306]="+18 Frost Resistance", -[1307]="+19 Frost Resistance", -[1308]="+20 Frost Resistance", -[1309]="+21 Frost Resistance", -[1310]="+22 Frost Resistance", -[1311]="+23 Frost Resistance", -[1312]="+24 Frost Resistance", -[1313]="+25 Frost Resistance", -[1314]="+26 Frost Resistance", -[1315]="+27 Frost Resistance", -[1316]="+28 Frost Resistance", -[1317]="+29 Frost Resistance", -[1318]="+30 Frost Resistance", -[1319]="+31 Frost Resistance", -[1320]="+32 Frost Resistance", -[1321]="+33 Frost Resistance", -[1322]="+34 Frost Resistance", -[1323]="+35 Frost Resistance", -[1324]="+36 Frost Resistance", -[1325]="+37 Frost Resistance", -[1326]="+38 Frost Resistance", -[1327]="+39 Frost Resistance", -[1328]="+40 Frost Resistance", -[1329]="+41 Frost Resistance", -[1330]="+42 Frost Resistance", -[1331]="+43 Frost Resistance", -[1332]="+44 Frost Resistance", -[1333]="+45 Frost Resistance", -[1334]="+46 Frost Resistance", -[1335]="+1 Fire Resistance", -[1336]="+2 Fire Resistance", -[1337]="+3 Fire Resistance", -[1338]="+4 Fire Resistance", -[1339]="+5 Fire Resistance", -[1340]="+6 Fire Resistance", -[1341]="+7 Fire Resistance", -[1342]="+8 Fire Resistance", -[1343]="+9 Fire Resistance", -[1344]="+10 Fire Resistance", -[1345]="+11 Fire Resistance", -[1346]="+12 Fire Resistance", -[1347]="+13 Fire Resistance", -[1348]="+14 Fire Resistance", -[1349]="+15 Fire Resistance", -[1350]="+16 Fire Resistance", -[1351]="+17 Fire Resistance", -[1352]="+18 Fire Resistance", -[1353]="+19 Fire Resistance", -[1354]="+20 Fire Resistance", -[1355]="+21 Fire Resistance", -[1356]="+22 Fire Resistance", -[1357]="+23 Fire Resistance", -[1358]="+24 Fire Resistance", -[1359]="+25 Fire Resistance", -[1360]="+26 Fire Resistance", -[1361]="+27 Fire Resistance", -[1362]="+28 Fire Resistance", -[1363]="+29 Fire Resistance", -[1364]="+30 Fire Resistance", -[1365]="+31 Fire Resistance", -[1366]="+32 Fire Resistance", -[1367]="+33 Fire Resistance", -[1368]="+34 Fire Resistance", -[1369]="+35 Fire Resistance", -[1370]="+36 Fire Resistance", -[1371]="+37 Fire Resistance", -[1372]="+38 Fire Resistance", -[1373]="+39 Fire Resistance", -[1374]="+40 Fire Resistance", -[1375]="+41 Fire Resistance", -[1376]="+42 Fire Resistance", -[1377]="+43 Fire Resistance", -[1378]="+44 Fire Resistance", -[1379]="+45 Fire Resistance", -[1380]="+46 Fire Resistance", -[1381]="+1 Nature Resistance", -[1382]="+2 Nature Resistance", -[1383]="+3 Nature Resistance", -[1384]="+4 Nature Resistance", -[1385]="+5 Nature Resistance", -[1386]="+6 Nature Resistance", -[1387]="+7 Nature Resistance", -[1388]="+8 Nature Resistance", -[1389]="+9 Nature Resistance", -[1390]="+10 Nature Resistance", -[1391]="+11 Nature Resistance", -[1392]="+12 Nature Resistance", -[1393]="+13 Nature Resistance", -[1394]="+14 Nature Resistance", -[1395]="+15 Nature Resistance", -[1396]="+16 Nature Resistance", -[1397]="+17 Nature Resistance", -[1398]="+18 Nature Resistance", -[1399]="+19 Nature Resistance", -[1400]="+20 Nature Resistance", -[1401]="+21 Nature Resistance", -[1402]="+22 Nature Resistance", -[1403]="+23 Nature Resistance", -[1404]="+24 Nature Resistance", -[1405]="+25 Nature Resistance", -[1406]="+26 Nature Resistance", -[1407]="+27 Nature Resistance", -[1408]="+28 Nature Resistance", -[1409]="+29 Nature Resistance", -[1410]="+30 Nature Resistance", -[1411]="+31 Nature Resistance", -[1412]="+32 Nature Resistance", -[1413]="+33 Nature Resistance", -[1414]="+34 Nature Resistance", -[1415]="+35 Nature Resistance", -[1416]="+36 Nature Resistance", -[1417]="+37 Nature Resistance", -[1418]="+38 Nature Resistance", -[1419]="+39 Nature Resistance", -[1420]="+40 Nature Resistance", -[1421]="+41 Nature Resistance", -[1422]="+42 Nature Resistance", -[1423]="+43 Nature Resistance", -[1424]="+44 Nature Resistance", -[1425]="+45 Nature Resistance", -[1426]="+46 Nature Resistance", -[1427]="+1 Shadow Resistance", -[1428]="+2 Shadow Resistance", -[1429]="+3 Shadow Resistance", -[1430]="+4 Shadow Resistance", -[1431]="+5 Shadow Resistance", -[1432]="+6 Shadow Resistance", -[1433]="+7 Shadow Resistance", -[1434]="+8 Shadow Resistance", -[1435]="+9 Shadow Resistance", -[1436]="+10 Shadow Resistance", -[1437]="+11 Shadow Resistance", -[1438]="+12 Shadow Resistance", -[1439]="+13 Shadow Resistance", -[1440]="+14 Shadow Resistance", -[1441]="+15 Shadow Resistance", -[1442]="+16 Shadow Resistance", -[1443]="+17 Shadow Resistance", -[1444]="+18 Shadow Resistance", -[1445]="+19 Shadow Resistance", -[1446]="+20 Shadow Resistance", -[1447]="+21 Shadow Resistance", -[1448]="+22 Shadow Resistance", -[1449]="+23 Shadow Resistance", -[1450]="+24 Shadow Resistance", -[1451]="+25 Shadow Resistance", -[1452]="+26 Resist Shadow", -[1453]="+27 Shadow Resistance", -[1454]="+28 Shadow Resistance", -[1455]="+29 Shadow Resistance", -[1456]="+30 Shadow Resistance", -[1457]="+31 Shadow Resistance", -[1458]="+32 Shadow Resistance", -[1459]="+33 Shadow Resistance", -[1460]="+34 Shadow Resistance", -[1461]="+35 Shadow Resistance", -[1462]="+36 Shadow Resistance", -[1463]="+37 Shadow Resistance", -[1464]="+38 Shadow Resistance", -[1465]="+39 Shadow Resistance", -[1466]="+40 Shadow Resistance", -[1467]="+41 Shadow Resistance", -[1468]="+42 Shadow Resistance", -[1469]="+43 Shadow Resistance", -[1470]="+44 Shadow Resistance", -[1471]="+45 Shadow Resistance", -[1472]="+46 Shadow Resistance", -[1483]="+150 Mana", -[1503]="+100 Health", -[1504]="125 Armor", -[1505]="+20 Fire Resistance", -[1506]="8 Str", -[1507]="8 Stam", -[1508]="8 Agi", -[1509]="8 Int", -[1510]="8 Spirit", -[1523]="+85 Mana and +14 Fire Resistance", -[1524]="+75 Health and +14 Fire Resistance", -[1525]="110 Armor", -[1526]="10 Str", -[1527]="10 Stam", -[1528]="10 Agi", -[1529]="10 Int", -[1530]="10 Spirit", -[1531]="10 Str, 10 Stam", -[1532]="15 Str", -[1543]="15 Int", -[1563]="2 AP", -[1583]="4 AP", -[1584]="6 AP", -[1585]="8 AP", -[1586]="10 AP", -[1587]="12 AP", -[1588]="14 AP", -[1589]="16 AP", -[1590]="18 AP", -[1591]="20 AP", -[1592]="22 AP", -[1593]="24 AP", -[1594]="26 AP", -[1595]="28 AP", -[1596]="30 AP", -[1597]="32 AP", -[1598]="34 AP", -[1599]="36 AP", -[1600]="38 AP", -[1601]="32 AP", -[1602]="42 AP", -[1603]="44 AP", -[1604]="46 AP", -[1605]="48 AP", -[1606]="50 AP", -[1607]="52 AP", -[1608]="54 AP", -[1609]="56 AP", -[1610]="58 AP", -[1611]="60 AP", -[1612]="62 AP", -[1613]="64 AP", -[1614]="66 AP", -[1615]="68 AP", -[1616]="70 AP", -[1617]="72 AP", -[1618]="74 AP", -[1619]="76 AP", -[1620]="78 AP", -[1621]="80 AP", -[1622]="82 AP", -[1623]="84 AP", -[1624]="86 AP", -[1625]="88 AP", -[1626]="90 AP", -[1627]="92 AP", -[1643]="Sharpened (+8 Damage)", -[1703]="Weighted (+8 Damage)", -[1704]="Thorium Spike (20-30)", -[1723]="Omen of Clarity", -[1743]="MHTest02", -[1763]="Cold Blood", -[1803]="Firestone 1", -[1823]="Firestone 2", -[1824]="Firestone 3", -[1825]="Firestone 4", -[1843]="40 Armor", -[1883]="7 Int", -[1884]="9 Spirit", -[1885]="9 Str", -[1886]="9 Stam", -[1887]="7 Agi", -[1888]="+5 All Resistances", -[1889]="70 Armor", -[1890]="10 Stam, 10 Spirit", -[1891]="4 Str, 4 Agi, 4 Stam, 4 Int, 4 Spirit", -[1892]="+100 Health", -[1893]="+100 Mana", -[1894]="Icy Chill", -[1895]="+9 Damage", -[1896]="+9 Weapon Damage", -[1897]="+5 Weapon Damage", -[1898]="Lifestealing", -[1899]="Unholy Weapon", -[1900]="Crusader", -[1901]="9 Int", -[1903]="9 Spirit", -[1904]="9 Int", -[1923]="+3 Fire Resistance", -[1943]="12 Dodge", -[1944]="8 Dodge", -[1945]="9 Dodge", -[1946]="10 Dodge", -[1947]="11 Dodge", -[1948]="13 Dodge", -[1949]="14 Dodge", -[1950]="15 Dodge", -[1951]="18 Dodge", -[1952]="20 Dodge", -[1953]="22 Dodge", -[1954]="25 Dodge", -[1955]="32 Dodge", -[1956]="17 Dodge", -[1957]="18 Dodge", -[1958]="19 Dodge", -[1959]="21 Dodge", -[1960]="23 Dodge", -[1961]="24 Dodge", -[1962]="26 Dodge", -[1963]="27 Dodge", -[1964]="28 Dodge", -[1965]="29 Dodge", -[1966]="30 Dodge", -[1967]="31 Dodge", -[1968]="33 Dodge", -[1969]="34 Dodge", -[1970]="35 Dodge", -[1971]="36 Dodge", -[1972]="37 Dodge", -[1973]="38 Dodge", -[1983]="+5 Block", -[1984]="+10 Block", -[1985]="+15 Block", -[1986]="+20 Block", -[1987]="Block Level 14", -[1988]="Block Level 15", -[1989]="Block Level 16", -[1990]="Block Level 17", -[1991]="Block Level 18", -[1992]="Block Level 19", -[1993]="Block Level 20", -[1994]="Block Level 21", -[1995]="Block Level 22", -[1996]="Block Level 23", -[1997]="Block Level 24", -[1998]="Block Level 25", -[1999]="Block Level 26", -[2000]="Block Level 27", -[2001]="Block Level 28", -[2002]="Block Level 29", -[2003]="Block Level 30", -[2004]="Block Level 31", -[2005]="Block Level 32", -[2006]="Block Level 33", -[2007]="Block Level 34", -[2008]="Block Level 35", -[2009]="Block Level 36", -[2010]="Block Level 37", -[2011]="Block Level 38", -[2012]="Block Level 39", -[2013]="Block Level 40", -[2014]="Block Level 41", -[2015]="Block Level 42", -[2016]="Block Level 43", -[2017]="Block Level 44", -[2018]="Block Level 45", -[2019]="Block Level 46", -[2020]="Block Level 47", -[2021]="Block Level 48", -[2022]="Block Level 49", -[2023]="Block Level 50", -[2024]="Block Level 51", -[2025]="Block Level 52", -[2026]="Block Level 53", -[2027]="Block Level 54", -[2028]="Block Level 55", -[2029]="Block Level 56", -[2030]="Block Level 57", -[2031]="Block Level 58", -[2032]="Block Level 59", -[2033]="Block Level 60", -[2034]="Block Level 61", -[2035]="Block Level 62", -[2036]="Block Level 63", -[2037]="Block Level 64", -[2038]="Block Level 65", -[2039]="Block Level 66", -[2040]="+2 Ranged Attack Power", -[2041]="+5 Ranged Attack Power", -[2042]="+7 Ranged Attack Power", -[2043]="+10 Ranged Attack Power", -[2044]="+12 Ranged Attack Power", -[2045]="+14 Ranged Attack Power", -[2046]="+17 Ranged Attack Power", -[2047]="+19 Ranged Attack Power", -[2048]="+22 Ranged Attack Power", -[2049]="+24 Ranged Attack Power", -[2050]="+26 Ranged Attack Power", -[2051]="+29 Ranged Attack Power", -[2052]="+31 Ranged Attack Power", -[2053]="+34 Ranged Attack Power", -[2054]="+36 Ranged Attack Power", -[2055]="+38 Ranged Attack Power", -[2056]="+41 Ranged Attack Power", -[2057]="+43 Ranged Attack Power", -[2058]="+46 Ranged Attack Power", -[2059]="+48 Ranged Attack Power", -[2060]="+50 Ranged Attack Power", -[2061]="+53 Ranged Attack Power", -[2062]="+55 Ranged Attack Power", -[2063]="+58 Ranged Attack Power", -[2064]="+60 Ranged Attack Power", -[2065]="+62 Ranged Attack Power", -[2066]="+65 Ranged Attack Power", -[2067]="+67 Ranged Attack Power", -[2068]="+70 Ranged Attack Power", -[2069]="+72 Ranged Attack Power", -[2070]="+74 Ranged Attack Power", -[2071]="+77 Ranged Attack Power", -[2072]="+79 Ranged Attack Power", -[2073]="+82 Ranged Attack Power", -[2074]="+84 Ranged Attack Power", -[2075]="+86 Ranged Attack Power", -[2076]="+89 Ranged Attack Power", -[2077]="+91 Ranged Attack Power", -[2078]="12 Dodge", -[2079]="+1 Arcane Spell Damage", -[2080]="+3 Arcane Spell Damage", -[2081]="+4 Arcane Spell Damage", -[2082]="+6 Arcane Spell Damage", -[2083]="+7 Arcane Spell Damage", -[2084]="+9 Arcane Spell Damage", -[2085]="+10 Arcane Spell Damage", -[2086]="+11 Arcane Spell Damage", -[2087]="+13 Arcane Spell Damage", -[2088]="+14 Arcane Spell Damage", -[2089]="+16 Arcane Spell Damage", -[2090]="+17 Arcane Spell Damage", -[2091]="+19 Arcane Spell Damage", -[2092]="+20 Arcane Spell Damage", -[2093]="+21 Arcane Spell Damage", -[2094]="+23 Arcane Spell Damage", -[2095]="+24 Arcane Spell Damage", -[2096]="+26 Arcane Spell Damage", -[2097]="+27 Arcane Spell Damage", -[2098]="+29 Arcane Spell Damage", -[2099]="+30 Arcane Spell Damage", -[2100]="+31 Arcane Spell Damage", -[2101]="+33 Arcane Spell Damage", -[2102]="+34 Arcane Spell Damage", -[2103]="+36 Arcane Spell Damage", -[2104]="+37 Arcane Spell Damage", -[2105]="+39 Arcane Spell Damage", -[2106]="+40 Arcane Spell Damage", -[2107]="+41 Arcane Spell Damage", -[2108]="+43 Arcane Spell Damage", -[2109]="+44 Arcane Spell Damage", -[2110]="+46 Arcane Spell Damage", -[2111]="+47 Arcane Spell Damage", -[2112]="+49 Arcane Spell Damage", -[2113]="+50 Arcane Spell Damage", -[2114]="+51 Arcane Spell Damage", -[2115]="+53 Arcane Spell Damage", -[2116]="+54 Arcane Spell Damage", -[2117]="+1 Shadow Spell Damage", -[2118]="+3 Shadow Spell Damage", -[2119]="+4 Shadow Spell Damage", -[2120]="+6 Shadow Spell Damage", -[2121]="+7 Shadow Spell Damage", -[2122]="+9 Shadow Spell Damage", -[2123]="+10 Shadow Spell Damage", -[2124]="+11 Shadow Spell Damage", -[2125]="+13 Shadow Spell Damage", -[2126]="+14 Shadow Spell Damage", -[2127]="+16 Shadow Spell Damage", -[2128]="+17 Shadow Spell Damage", -[2129]="+19 Shadow Spell Damage", -[2130]="+20 Shadow Spell Damage", -[2131]="+21 Shadow Spell Damage", -[2132]="+23 Shadow Spell Damage", -[2133]="+24 Shadow Spell Damage", -[2134]="+26 Shadow Spell Damage", -[2135]="+27 Shadow Spell Damage", -[2136]="+29 Shadow Spell Damage", -[2137]="+30 Shadow Spell Damage", -[2138]="+31 Shadow Spell Damage", -[2139]="+33 Shadow Spell Damage", -[2140]="+34 Shadow Spell Damage", -[2141]="+36 Shadow Spell Damage", -[2142]="+37 Shadow Spell Damage", -[2143]="+39 Shadow Spell Damage", -[2144]="+40 Shadow Spell Damage", -[2145]="+41 Shadow Spell Damage", -[2146]="+43 Shadow Spell Damage", -[2147]="+44 Shadow Spell Damage", -[2148]="+46 Shadow Spell Damage", -[2149]="+47 Shadow Spell Damage", -[2150]="+49 Shadow Spell Damage", -[2151]="+50 Shadow Spell Damage", -[2152]="+51 Shadow Spell Damage", -[2153]="+53 Shadow Spell Damage", -[2154]="+54 Shadow Spell Damage", -[2155]="+1 Fire Spell Damage", -[2156]="+3 Fire Spell Damage", -[2157]="+4 Fire Spell Damage", -[2158]="+6 Fire Spell Damage", -[2159]="+7 Fire Spell Damage", -[2160]="+9 Fire Spell Damage", -[2161]="+10 Fire Spell Damage", -[2162]="+11 Fire Spell Damage", -[2163]="+13 Fire Spell Damage", -[2164]="+14 Fire Spell Damage", -[2165]="+16 Fire Spell Damage", -[2166]="+17 Fire Spell Damage", -[2167]="+19 Fire Spell Damage", -[2168]="+20 Fire Spell Damage", -[2169]="+21 Fire Spell Damage", -[2170]="+23 Fire Spell Damage", -[2171]="+24 Fire Spell Damage", -[2172]="+26 Fire Spell Damage", -[2173]="+27 Fire Spell Damage", -[2174]="+29 Fire Spell Damage", -[2175]="+30 Fire Spell Damage", -[2176]="+31 Fire Spell Damage", -[2177]="+33 Fire Spell Damage", -[2178]="+34 Fire Spell Damage", -[2179]="+36 Fire Spell Damage", -[2180]="+37 Fire Spell Damage", -[2181]="+39 Fire Spell Damage", -[2182]="+40 Fire Spell Damage", -[2183]="+41 Fire Spell Damage", -[2184]="+43 Fire Spell Damage", -[2185]="+44 Fire Spell Damage", -[2186]="+46 Fire Spell Damage", -[2187]="+47 Fire Spell Damage", -[2188]="+49 Fire Spell Damage", -[2189]="+50 Fire Spell Damage", -[2190]="+51 Fire Spell Damage", -[2191]="+53 Fire Spell Damage", -[2192]="+54 Fire Spell Damage", -[2193]="+1 Holy Spell Damage", -[2194]="+3 Holy Spell Damage", -[2195]="+4 Holy Spell Damage", -[2196]="+6 Holy Spell Damage", -[2197]="+7 Holy Spell Damage", -[2198]="+9 Holy Spell Damage", -[2199]="+10 Holy Spell Damage", -[2200]="+11 Holy Spell Damage", -[2201]="+13 Holy Spell Damage", -[2202]="+14 Holy Spell Damage", -[2203]="+16 Holy Spell Damage", -[2204]="+17 Holy Spell Damage", -[2205]="+19 Holy Spell Damage", -[2206]="+20 Holy Spell Damage", -[2207]="+21 Holy Spell Damage", -[2208]="+23 Holy Spell Damage", -[2209]="+24 Holy Spell Damage", -[2210]="+26 Holy Spell Damage", -[2211]="+27 Holy Spell Damage", -[2212]="+29 Holy Spell Damage", -[2213]="+30 Holy Spell Damage", -[2214]="+31 Holy Spell Damage", -[2215]="+33 Holy Spell Damage", -[2216]="+34 Holy Spell Damage", -[2217]="+36 Holy Spell Damage", -[2218]="+37 Holy Spell Damage", -[2219]="+39 Holy Spell Damage", -[2220]="+40 Holy Spell Damage", -[2221]="+41 Holy Spell Damage", -[2222]="+43 Holy Spell Damage", -[2223]="+44 Holy Spell Damage", -[2224]="+46 Holy Spell Damage", -[2225]="+47 Holy Spell Damage", -[2226]="+49 Holy Spell Damage", -[2227]="+50 Holy Spell Damage", -[2228]="+51 Holy Spell Damage", -[2229]="+53 Holy Spell Damage", -[2230]="+54 Holy Spell Damage", -[2231]="+1 Frost Spell Damage", -[2232]="+3 Frost Spell Damage", -[2233]="+4 Frost Spell Damage", -[2234]="+6 Frost Spell Damage", -[2235]="+7 Frost Spell Damage", -[2236]="+9 Frost Spell Damage", -[2237]="+10 Frost Spell Damage", -[2238]="+11 Frost Spell Damage", -[2239]="+13 Frost Spell Damage", -[2240]="+14 Frost Spell Damage", -[2241]="+16 Frost Spell Damage", -[2242]="+17 Frost Spell Damage", -[2243]="+19 Frost Spell Damage", -[2244]="+20 Frost Spell Damage", -[2245]="+21 Frost Spell Damage", -[2246]="+23 Frost Spell Damage", -[2247]="+24 Frost Spell Damage", -[2248]="+26 Frost Spell Damage", -[2249]="+27 Frost Spell Damage", -[2250]="+29 Frost Spell Damage", -[2251]="+30 Frost Spell Damage", -[2252]="+31 Frost Spell Damage", -[2253]="+33 Frost Spell Damage", -[2254]="+34 Frost Spell Damage", -[2255]="+36 Frost Spell Damage", -[2256]="+37 Frost Spell Damage", -[2257]="+39 Frost Spell Damage", -[2258]="+40 Frost Spell Damage", -[2259]="+41 Frost Spell Damage", -[2260]="+43 Frost Spell Damage", -[2261]="+44 Frost Spell Damage", -[2262]="+46 Frost Spell Damage", -[2263]="+47 Frost Spell Damage", -[2264]="+49 Frost Spell Damage", -[2265]="+50 Frost Spell Damage", -[2266]="+51 Frost Spell Damage", -[2267]="+53 Frost Spell Damage", -[2268]="+54 Frost Spell Damage", -[2269]="+1 Nature Spell Damage", -[2270]="+3 Nature Spell Damage", -[2271]="+4 Nature Spell Damage", -[2272]="+6 Nature Spell Damage", -[2273]="+7 Nature Spell Damage", -[2274]="+9 Nature Spell Damage", -[2275]="+10 Nature Spell Damage", -[2276]="+11 Nature Spell Damage", -[2277]="+13 Nature Spell Damage", -[2278]="+14 Nature Spell Damage", -[2279]="+16 Nature Spell Damage", -[2280]="+17 Nature Spell Damage", -[2281]="+19 Nature Spell Damage", -[2282]="+20 Nature Spell Damage", -[2283]="+21 Nature Spell Damage", -[2284]="+23 Nature Spell Damage", -[2285]="+24 Nature Spell Damage", -[2286]="+26 Nature Spell Damage", -[2287]="+27 Nature Spell Damage", -[2288]="+29 Nature Spell Damage", -[2289]="+30 Nature Spell Damage", -[2290]="+31 Nature Spell Damage", -[2291]="+33 Nature Spell Damage", -[2292]="+34 Nature Spell Damage", -[2293]="+36 Nature Spell Damage", -[2294]="+37 Nature Spell Damage", -[2295]="+39 Nature Spell Damage", -[2296]="+40 Nature Spell Damage", -[2297]="+41 Nature Spell Damage", -[2298]="+43 Nature Spell Damage", -[2299]="+44 Nature Spell Damage", -[2300]="+46 Nature Spell Damage", -[2301]="+47 Nature Spell Damage", -[2302]="+49 Nature Spell Damage", -[2303]="+50 Nature Spell Damage", -[2304]="+51 Nature Spell Damage", -[2305]="+53 Nature Spell Damage", -[2306]="+54 Nature Spell Damage", -[2307]="1 SP", -[2308]="2 SP", -[2309]="4 SP", -[2310]="5 SP", -[2311]="6 SP", -[2312]="7 SP", -[2313]="8 SP", -[2314]="9 SP", -[2315]="11 SP", -[2316]="12 SP", -[2317]="13 SP", -[2318]="14 SP", -[2319]="15 SP", -[2320]="16 SP", -[2321]="18 SP", -[2322]="19 SP", -[2323]="20 SP", -[2324]="21 SP", -[2325]="22 SP", -[2326]="23 SP", -[2327]="25 SP", -[2328]="26 SP", -[2329]="27 SP", -[2330]="28 SP", -[2331]="29 SP", -[2332]="30 SP", -[2333]="32 SP", -[2334]="33 SP", -[2335]="34 SP", -[2336]="35 SP", -[2337]="36 SP", -[2338]="37 SP", -[2339]="39 SP", -[2340]="40 SP", -[2341]="41 SP", -[2342]="42 SP", -[2343]="43 SP", -[2344]="44 SP", -[2363]="+1 mana every 5 sec.", -[2364]="+1 mana every 5 sec.", -[2365]="+1 mana every 5 sec.", -[2366]="+2 mana every 5 sec.", -[2367]="+2 mana every 5 sec.", -[2368]="+2 mana every 5 sec.", -[2369]="+3 mana every 5 sec.", -[2370]="+3 mana every 5 sec.", -[2371]="+4 mana every 5 sec.", -[2372]="+4 mana every 5 sec.", -[2373]="+4 mana every 5 sec.", -[2374]="+5 mana every 5 sec.", -[2375]="+5 mana every 5 sec.", -[2376]="+6 mana every 5 sec.", -[2377]="+6 mana every 5 sec.", -[2378]="+6 mana every 5 sec.", -[2379]="+7 mana every 5 sec.", -[2380]="+7 mana every 5 sec.", -[2381]="20 Spirit", -[2382]="+8 mana every 5 sec.", -[2383]="+8 mana every 5 sec.", -[2384]="+9 mana every 5 sec.", -[2385]="+9 mana every 5 sec.", -[2386]="24 Spirit", -[2387]="25 Spirit", -[2388]="26 Spirit", -[2389]="27 Spirit", -[2390]="28 Spirit", -[2391]="29 Spirit", -[2392]="30 Spirit", -[2393]="31 Spirit", -[2394]="32 Spirit", -[2395]="33 Spirit", -[2396]="+14 mana every 5 sec.", -[2397]="+14 mana every 5 sec.", -[2398]="+14 mana every 5 sec.", -[2399]="+15 mana every 5 sec.", -[2400]="+15 mana every 5 sec.", -[2401]="+1 health every 5 sec.", -[2402]="+1 health every 5 sec.", -[2403]="+1 health every 5 sec.", -[2404]="+1 health every 5 sec.", -[2405]="+1 health every 5 sec.", -[2406]="+2 health every 5 sec.", -[2407]="+2 health every 5 sec.", -[2408]="+2 health every 5 sec.", -[2409]="+2 health every 5 sec.", -[2410]="+3 health every 5 sec.", -[2411]="+3 health every 5 sec.", -[2412]="+5 health every 5 sec.", -[2413]="+5 health every 5 sec.", -[2414]="+4 health every 5 sec.", -[2415]="+4 health every 5 sec.", -[2416]="+4 health every 5 sec.", -[2417]="+4 health every 5 sec.", -[2418]="+5 health every 5 sec.", -[2419]="+5 health every 5 sec.", -[2420]="+5 health every 5 sec.", -[2421]="+5 health every 5 sec.", -[2422]="+6 health every 5 sec.", -[2423]="+6 health every 5 sec.", -[2424]="+6 health every 5 sec.", -[2425]="+6 health every 5 sec.", -[2426]="+7 health every 5 sec.", -[2427]="+7 health every 5 sec.", -[2428]="+7 health every 5 sec.", -[2429]="+7 health every 5 sec.", -[2430]="+8 health every 5 sec.", -[2431]="+8 health every 5 sec.", -[2432]="+8 health every 5 sec.", -[2433]="+8 health every 5 sec.", -[2434]="+9 health every 5 sec.", -[2435]="+9 health every 5 sec.", -[2436]="+9 health every 5 sec.", -[2437]="+9 health every 5 sec.", -[2438]="+10 health every 5 sec.", -[2443]="+7 Frost Spell Damage", -[2463]="+7 Fire Resistance", -[2483]="+5 Fire Resistance", -[2484]="+5 Frost Resistance", -[2485]="+5 Arcane Resistance", -[2486]="+5 Nature Resistance", -[2487]="+5 Shadow Resistance", -[2488]="+5 All Resistances", -[2503]="5 Dodge", -[2504]="30 SP", -[2505]="29 SP", -[2506]="+28 Melee Critical Strike", -[2523]="30 Hit", -[2543]="10 Haste", -[2544]="8 SP", -[2545]="12 Dodge", -[2563]="15 Str", -[2564]="15 Agi", -[2565]="9 Spirit", -[2566]="13 SP", -[2567]="20 Spirit", -[2568]="22 Int", -[2583]="10 Dodge", -[2584]="10 Int, 10 Dodge", -[2585]="28 AP, 12 Dodge", -[2586]="10 Stam, 10 Hit", -[2587]="13 SP, 15 Int", -[2588]="18 SP, 8 Hit", -[2589]="18 SP, 10 Stam", -[2590]="10 Int, 10 Spirit", -[2591]="10 Int", -[2603]="+2 Fishing", -[2604]="18 SP", -[2605]="18 SP", -[2606]="30 AP", -[2607]="12 SP", -[2608]="13 SP", -[2609]="15 SP", -[2610]="14 SP", -[2611]="zzOLDBlank", -[2612]="18 SP", -[2613]="+2% Threat", -[2614]="+20 Shadow Spell Power", -[2615]="+20 Frost Spell Power", -[2616]="+20 Fire Spell Power", -[2617]="16 SP", -[2618]="15 Agi", -[2619]="+15 Fire Resistance", -[2620]="+15 Nature Resistance", -[2621]="2% Reduced Threat", -[2622]="12 Dodge", -[2623]="Minor Wizard Oil", -[2624]="Minor Mana Oil", -[2625]="Lesser Mana Oil", -[2626]="Lesser Wizard Oil", -[2627]="Wizard Oil", -[2628]="Brilliant Wizard Oil", -[2629]="Brilliant Mana Oil", -[2645]="Firestone 5", -[2646]="25 Agi", -[2647]="12 Str", -[2648]="14 Dodge", -[2649]="12 Stam", -[2650]="15 SP", -[2651]="12 SP", -[2652]="11 SP", -[2653]="12 Dodge", -[2654]="12 Int", -[2655]="15 Parry", -[2656]="10 Stam, 10 Spirit", -[2657]="12 Agi", -[2658]="10 Hit, 10 Crit", -[2659]="+150 Health", -[2660]="+150 Mana", -[2661]="6 Str, 6 Agi, 6 Stam, 6 Int, 6 Spirit", -[2662]="120 Armor", -[2663]="+7 Resist All", -[2664]="+7 Resist All", -[2665]="35 Spirit", -[2666]="30 Int", -[2667]="70 AP", -[2668]="20 Str", -[2669]="40 SP", -[2670]="35 Agi", -[2671]="+50 Arcane and Fire Spell Power", -[2672]="+54 Shadow and Frost Spell Power", -[2673]="Mongoose", -[2674]="Spellsurge", -[2675]="Battlemaster", -[2676]="Superior Mana Oil", -[2677]="Superior Mana Oil", -[2678]="Superior Wizard Oil", -[2679]="12 Spirit", -[2680]="+7 Resist All", -[2681]="+10 Nature Resistance", -[2682]="+10 Frost Resistance", -[2683]="+10 Shadow Resistance", -[2684]="+100 Attack Power vs Undead", -[2685]="+60 Spell Power vs Undead", -[2686]="8 Str", -[2687]="8 Agi", -[2688]="8 Stam", -[2689]="+8 mana every 5 sec.", -[2690]="6 Int", -[2691]="6 Str", -[2692]="7 Int", -[2693]="6 Agi", -[2694]="6 Int", -[2695]="6 Crit", -[2696]="6 Dodge", -[2697]="6 Hit", -[2698]="9 Stam", -[2699]="6 Spirit", -[2700]="6 PvP Pow", -[2701]="6 Spirit", -[2702]="12 Agi", -[2703]="+4 Agility per different colored gem", -[2704]="+12 Strength if 4 blue gems equipped", -[2705]="3 Int, 3 Haste", -[2706]="4 Stam, 3 Dodge", -[2707]="3 Int, 3 Spirit", -[2708]="3 Int, 4 Stam", -[2709]="3 Int, 3 Spirit", -[2710]="3 Agi, 4 Stam", -[2711]="3 Str, 4 Stam", -[2712]="Sharpened (+12 Damage)", -[2713]="14 Crit", -[2714]="Felsteel Spike (26-38)", -[2715]="16 SP", -[2716]="16 Stam, 100 Armor", -[2717]="26 AP, 14 Crit", -[2718]="Lesser Rune of Warding", -[2719]="Lesser Ward of Shielding", -[2720]="Greater Ward of Shielding", -[2721]="15 SP, 14 Crit", -[2722]="Scope (+10 Damage)", -[2723]="Scope (+12 Damage)", -[2724]="28 Crit", -[2725]="8 Str", -[2726]="8 Agi", -[2727]="8 Int", -[2728]="8 Int", -[2729]="8 Agi", -[2730]="8 Dodge", -[2731]="12 Stam", -[2732]="8 Spirit", -[2733]="8 Spirit", -[2734]="8 Int", -[2735]="8 Crit", -[2736]="8 Crit", -[2737]="8 Dodge", -[2738]="4 Str, 6 Stam", -[2739]="4 Agi, 6 Stam", -[2740]="5 Int, 6 Stam", -[2741]="4 Int, 4 Spirit", -[2742]="4 Int, 4 Haste", -[2743]="6 Stam, 4 Dodge", -[2744]="4 Int, 4 Spirit", -[2745]="25 SP, 15 Stam", -[2746]="35 SP, 20 Stam", -[2747]="25 SP, 15 Stam", -[2748]="35 SP, 20 Stam", -[2749]="12 Int", -[2750]="6 mana per 5 sec.", -[2751]="14 Crit", -[2752]="3 Str, 3 Crit", -[2753]="4 Str, 4 Crit", -[2754]="8 Parry", -[2755]="3 Agi, 3 Hit", -[2756]="4 Agi, 4 Hit", -[2757]="4 Stam, 3 Crit", -[2758]="6 Stam, 4 Crit", -[2759]="8 Resil", -[2760]="3 Int, 3 Crit", -[2761]="4 Int, 4 Crit", -[2762]="3 PvP Pow, 3 Crit", -[2763]="4 PvP Pow, 4 Crit", -[2764]="8 Hit", -[2765]="8 PvP Pow", -[2766]="8 Int", -[2767]="8 Hit", -[2768]="16 SP", -[2769]="11 Hit", -[2770]="7 SP", -[2771]="8 Crit", -[2772]="14 Crit", -[2773]="16 Crit", -[2774]="11 Int", -[2775]="11 Crit", -[2776]="8 Spirit", -[2777]="13 Spirit", -[2778]="13 PvP Pow", -[2779]="16 Spirit", -[2780]="16 PvP Pow", -[2781]="19 Stam", -[2782]="10 Agi", -[2783]="14 Hit", -[2784]="12 Hit", -[2785]="13 Hit", -[2786]="7 Hit", -[2787]="8 Crit", -[2788]="9 Resil", -[2789]="15 Resil", -[2790]="ZZOLDLesser Rune of Warding", -[2791]="Greater Rune of Warding", -[2792]="8 Stam", -[2793]="8 Dodge", -[2794]="8 Spirit", -[2795]="Comfortable Insoles", -[2796]="15 Dodge", -[2797]="9 Dodge", -[2798]="1 Int", -[2799]="1 Stam", -[2800]="1 Armor", -[2801]="8 Resil", -[2802]="1 Agi", -[2803]="1 Stam", -[2804]="1 Int", -[2805]="1 Str", -[2806]="1 Spirit", -[2807]="+1 Arcane Damage", -[2808]="+1 Fire Damage", -[2809]="+1 Nature Damage", -[2810]="+1 Frost Damage", -[2811]="+1 Shadow Damage", -[2812]="+1 Healing", -[2813]="1 Dodge", -[2814]="+1 Health per 5 sec.", -[2815]="1 Dodge", -[2816]="+1 Mana Per 5 sec.", -[2817]="+1 Arcane Resistance", -[2818]="+1 Fire Resistance", -[2819]="+1 Frost Resistance", -[2820]="+1 Nature Resistance", -[2821]="+1 Shadow Resistance", -[2822]="1 Crit", -[2823]="1 Crit", -[2824]="1 SP", -[2825]="1 AP", -[2826]="+1 Block", -[2827]="14 Crit", -[2828]="Chance to Increase Spell Cast Speed", -[2829]="12 Crit", -[2830]="12 Crit", -[2831]="18 Stam", -[2832]="12 Int", -[2833]="12 Dodge", -[2834]="+3 Melee Damage and Chance to Stun Target", -[2835]="12 Int", -[2836]="3 mana per 5 sec.", -[2837]="7 Spirit", -[2838]="7 Crit", -[2839]="14 Crit", -[2840]="21 Stam", -[2841]="10 Stam", -[2842]="8 Spirit", -[2843]="8 Crit", -[2844]="8 Hit", -[2845]="11 Hit", -[2846]="4 mana per 5 sec.", -[2847]="4 mana per 5 sec.", -[2848]="5 mana per 5 sec.", -[2849]="7 Dodge", -[2850]="13 Crit", -[2851]="19 Stam", -[2852]="7 mana per 5 sec", -[2853]="8 mana per 5 sec", -[2854]="3 mana per 5 sec", -[2855]="5 mana per 5 sec.", -[2856]="4 Resil", -[2857]="2 Crit", -[2858]="2 Crit", -[2859]="3 Resil", -[2860]="3 Hit", -[2861]="3 Dodge", -[2862]="3 Resil", -[2863]="3 Int", -[2864]="4 Crit", -[2865]="4 Spirit", -[2866]="3 Spirit", -[2867]="2 Resil", -[2868]="6 Stam", -[2869]="4 Int", -[2870]="3 Parry", -[2871]="4 Dodge", -[2872]="5 SP", -[2873]="4 Hit", -[2874]="4 Crit", -[2875]="3 Crit", -[2876]="3 Dodge", -[2877]="4 Agi", -[2878]="4 Resil", -[2879]="3 Str", -[2880]="3 Hit", -[2881]="2 Spirit", -[2882]="6 Stam", -[2883]="4 Stam", -[2884]="2 Crit", -[2885]="2 Crit", -[2886]="2 Hit", -[2887]="3 Crit", -[2888]="+6 Block Value", -[2889]="5 SP", -[2890]="4 Spirit", -[2891]="10 Resil", -[2892]="4 Str", -[2893]="3 Agi", -[2894]="7 Str", -[2895]="4 Stam", -[2896]="7 Int", -[2897]="3 Stam", -[2898]="3 Stam, 4 Crit", -[2899]="3 Stam, 4 Crit", -[2900]="4 SP", -[2901]="2 SP", -[2902]="2 Crit", -[2906]="1 Stam, 1 Int", -[2907]="2 Parry", -[2908]="4 Hit", -[2909]="2 Hit", -[2910]="3 SP", -[2911]="10 Str", -[2912]="10 Int", -[2913]="10 Crit", -[2914]="10 Crit", -[2915]="5 Str", -[2916]="5 Int, 5 Crit", -[2917]="gem test enchantment", -[2918]="3 Stam", -[2919]="7 Str", -[2921]="3 Stam, 4 Crit", -[2922]="7 Str", -[2923]="3 Stam, 4 Crit", -[2924]="7 Int", -[2925]="3 Stam", -[2926]="2 Dodge", -[2927]="4 Str", -[2928]="10 Int", -[2929]="+2 Weapon Damage", -[2930]="10 Int", -[2931]="4 Str, 4 Agi, 4 Stam, 4 Int, 4 Spirit", -[2932]="4 Dodge", -[2933]="15 Resil", -[2934]="10 Crit", -[2935]="15 Hit", -[2936]="8 AP", -[2937]="20 SP", -[2938]="16 PvP Pow", -[2939]="6 Agi, Run Speed", -[2940]="9 Stam, Run Speed", -[2941]="2 Hit", -[2942]="6 Crit", -[2943]="7 Agi", -[2944]="7 Agi", -[2945]="10 Agi", -[2946]="5 Agi, 5 Crit", -[2947]="+3 Resist All", -[2948]="+4 Resist All", -[2949]="10 Agi", -[2950]="10 Crit", -[2951]="4 Crit", -[2952]="4 Crit", -[2953]="2 SP", -[2954]="Weighted (+12 Damage)", -[2955]="14 Crit", -[2956]="4 Str", -[2957]="4 Agi", -[2958]="4 Int", -[2959]="4 Int", -[2960]="4 Agi", -[2961]="6 Stam", -[2962]="4 Spirit", -[2963]="4 Spirit", -[2964]="4 Int", -[2965]="4 Crit", -[2966]="4 Hit", -[2967]="4 Crit", -[2968]="4 Dodge", -[2969]="10 Crit", -[2970]="10 Int", -[2971]="6 Agi", -[2972]="+4 Block", -[2973]="6 AP", -[2974]="4 SP", -[2975]="+5 Block Value", -[2976]="2 Dodge", -[2977]="13 Dodge", -[2978]="15 Stam, 15 Dodge", -[2979]="15 SP", -[2980]="15 Int, 10 Spirit", -[2981]="15 SP", -[2982]="18 SP, 10 Crit", -[2983]="26 AP", -[2984]="8 Stam", -[2985]="8 Stam", -[2986]="30 AP, 10 Crit", -[2987]="8 Stam", -[2988]="8 Stam", -[2989]="8 Stam", -[2990]="13 Dodge", -[2991]="15 Parry, 10 Dodge", -[2992]="12 Spirit", -[2993]="10 Int, 16 Spirit", -[2994]="13 Crit", -[2995]="12 SP, 15 Crit", -[2996]="13 Crit", -[2997]="20 AP, 15 Crit", -[2998]="+7 All Resistances", -[2999]="16 Parry, 17 Dodge", -[3000]="18 Stam, 12 Resil", -[3001]="16 Int, 18 Spirit", -[3002]="22 SP, 14 Hit", -[3003]="34 AP, 16 Hit", -[3004]="18 Stam, 20 Resil", -[3005]="+20 Nature Resistance", -[3006]="+20 Arcane Resistance", -[3007]="+20 Fire Resistance", -[3008]="+20 Frost Resistance", -[3009]="+20 Shadow Resistance", -[3010]="40 AP, 10 Crit", -[3011]="30 Stam, 10 Agi", -[3012]="50 AP, 12 Crit", -[3013]="40 Stam, 12 Agi", -[3015]="2 Str", -[3016]="2 Int", -[3017]="+3 Block", -[3021]="Rockbiter", -[3045]="5 Str, 6 Stam", -[3046]="5 Int, 4 Haste", -[3047]="6 Stam, 5 Crit", -[3048]="5 Agi, 6 Stam", -[3049]="5 Crit, 4 Spirit", -[3050]="5 Int, 4 Haste", -[3051]="5 Int, 6 Stam", -[3052]="5 Agi, 4 Hit", -[3053]="5 Parry, 4 Dodge", -[3054]="5 Int, 6 Stam", -[3055]="5 Agi, 4 Hit", -[3056]="5 Parry, 4 Dodge", -[3057]="5 Str, 4 Hit", -[3058]="5 Crit, 4 Spirit", -[3059]="5 Crit", -[3060]="6 Stam, 5 Dodge", -[3061]="5 Int, 4 Hit", -[3062]="6 Stam, 5 Crit", -[3063]="6 Stam, 5 Parry", -[3064]="5 Int, 5 Spirit", -[3065]="8 Str", -[3066]="5 Int, 5 PvP Pow", -[3067]="5 Agi, 6 Stam", -[3068]="5 Dodge, 4 Hit", -[3069]="5 Int, 4 Resil", -[3070]="5 Agi, 4 Crit", -[3071]="5 Int, 6 Stam", -[3072]="5 Str, 4 Crit", -[3073]="4 Agi, 5 Dodge", -[3074]="5 Int, 4 Spirit", -[3075]="5 Str, 4 Dodge", -[3076]="5 Int, 4 Crit", -[3077]="5 Int, 4 Spirit", -[3078]="6 Stam, 5 Dodge", -[3079]="5 Agi, 4 Resil", -[3080]="6 Stam, 5 Resil", -[3081]="5 Int, 4 Crit", -[3082]="6 Stam, 5 Dodge", -[3083]="5 Int, 4 Spirit", -[3084]="5 Resil, 6 Stam", -[3085]="6 Stam, 5 Crit", -[3086]="5 Int, 4 Spirit", -[3087]="5 Str, 4 Resil", -[3088]="5 Hit, 4 Dodge", -[3089]="5 Hit, 4 Haste", -[3090]="4 Resil, 5 Parry", -[3091]="5 PvP Pow, 5 Crit", -[3092]="3 Crit", -[3093]="+150 Attack Power vs Undead and Demons", -[3094]="4 Exp", -[3095]="+8 Resist All", -[3096]="17 Str, 16 Int", -[3097]="2 Spirit", -[3098]="2 SP", -[3099]="5 Int, 6 Stam", -[3100]="5 Int, 6 Stam", -[3101]="5 Str, 6 Stam", -[3102]="Poison", -[3103]="8 Str", -[3104]="6 Hit", -[3105]="8 Hit", -[3106]="3 Agi, 4 Stam", -[3107]="4 Agi, 6 Stam", -[3108]="3 Agi, 4 Stam", -[3109]="4 Agi, 4 Hit", -[3110]="3 Int, 3 Hit", -[3111]="4 Int, 4 Hit", -[3112]="4 Agi, 4 Crit", -[3113]="3 Agi, 3 Crit", -[3114]="4 AP", -[3115]="10 Str", -[3116]="10 Agi", -[3117]="10 Int", -[3118]="10 Int", -[3119]="10 Agi", -[3120]="10 Dodge", -[3121]="10 Parry", -[3122]="15 Stam", -[3123]="10 Spirit", -[3124]="10 Spirit", -[3125]="10 PvP Pow", -[3126]="10 Int", -[3127]="10 Crit", -[3128]="10 Hit", -[3129]="10 Crit", -[3130]="10 Dodge", -[3131]="10 Resil", -[3132]="10 Hit", -[3133]="5 Str, 7 Stam", -[3134]="5 Agi, 7 Stam", -[3135]="5 Agi, 7 Stam", -[3136]="5 Agi, 5 Hit", -[3137]="5 Int, 7 Stam", -[3138]="5 Int, 5 Spirit", -[3139]="5 Str, 5 Crit", -[3140]="5 Int, 5 Crit", -[3141]="5 Int, 5 Haste", -[3142]="5 Agi, 5 Hit", -[3143]="5 Int, 5 Hit", -[3144]="5 Agi, 5 Crit", -[3145]="7 Stam, 5 Dodge", -[3146]="5 PvP Pow, 5 Crit", -[3147]="5 Int, 5 Spirit", -[3148]="7 Stam, 5 Crit", -[3149]="2 Agi", -[3150]="14 Spirit", -[3151]="2 SP", -[3152]="2 Crit", -[3153]="2 SP", -[3154]="12 Agi", -[3155]="Chance to Increase Melee/Ranged Attack Speed", -[3156]="5 Agi, 6 Stam", -[3157]="4 Int, 6 Stam", -[3158]="5 Int, 4 Spirit", -[3159]="5 Agi, 4 Crit", -[3160]="5 Int, 4 Haste", -[3161]="4 Stam, 4 Crit", -[3162]="12 Crit", -[3163]="12 Int", -[3164]="3 Stam", -[3197]="10 Agi", -[3198]="5 SP", -[3199]="170 Armor", -[3200]="5 SP, 4 Spirit", -[3201]="3 Int, 3 Spirit", -[3202]="4 Int, 4 Spirit", -[3204]="3 Crit", -[3205]="3 Crit", -[3206]="8 Agi", -[3207]="12 Str", -[3208]="12 Agi", -[3209]="12 Agi", -[3210]="12 Int", -[3211]="12 Int", -[3212]="18 Stam", -[3213]="+6 Mana every 5 seconds", -[3214]="12 Spirit", -[3215]="12 Resil", -[3216]="12 Int", -[3217]="12 Crit", -[3218]="12 Hit", -[3219]="12 Hit", -[3220]="12 Crit", -[3221]="12 Dodge", -[3222]="20 Agi", -[3223]="Adamantite Weapon Chain", -[3224]="6 Agi", -[3225]="Executioner", -[3226]="4 Resil, 6 Stam", -[3227]="10 Crit", -[3228]="34 AP", -[3229]="12 Resil", -[3230]="+20 Frost Resistance", -[3231]="15 Exp", -[3232]="15 Stam, Run Speed", -[3233]="+250 Mana", -[3234]="20 Hit", -[3235]="+12 Resist All", -[3236]="+200 Health", -[3237]="+10 Weapon Damage", -[3238]="Gatherer", -[3239]="Icebreaker Weapon", -[3240]="23 SP", -[3241]="Lifeward", -[3242]="+5 Resist All", -[3243]="28 PvP Pow", -[3244]="14 Stam, 14 Spirit", -[3245]="20 Resil", -[3246]="28 SP", -[3247]="+140 Attack Power versus Undead", -[3248]="18 Exp", -[3249]="16 Crit", -[3250]="Icewalker", -[3251]="Giantslaying", -[3252]="8 All Stats", -[3253]="10 Parry", -[3254]="4 Str, 4 Agi, 4 Stam, 4 Int, 4 Spirit", -[3255]="55 SP, 20 Spirit", -[3256]="10 Agi, 40 Armor", -[3257]="54 SP", -[3258]="18 SP", -[3259]="22 Stam", -[3260]="24 Stam", -[3261]="12 Crit", -[3262]="15 Stam", -[3263]="4 Crit", -[3264]="150 Armor", -[3265]="Blessed Weapon Coating", -[3266]="Righteous Weapon Coating", -[3267]="4 Haste", -[3268]="15 Stam", -[3269]="+3 Fishing", -[3270]="8 Haste", -[3271]="4 Int, 4 Haste", -[3272]="6 Stam, 4 Haste", -[3273]="Deathfrost", -[3274]="12 Dodge", -[3275]="12 Int", -[3276]="20 AP", -[3277]="12 SP", -[3278]="12 SP", -[3279]="3 SP", -[3280]="6 Stam, 4 Dodge", -[3281]="10 Agi", -[3282]="10 Int", -[3283]="10 Int", -[3284]="5 Resil, 7 Stam", -[3285]="7 Stam, 5 Haste", -[3286]="5 Int, 5 Haste", -[3287]="10 Haste", -[3288]="Test Riding Crop Enchant", -[3289]="+10% Mount Speed", -[3290]="Use: Reduce your fall speed for 10 sec. (5 Min Cooldown) (5 Min Cooldown)", -[3292]="34 Agi", -[3293]="51 Stam", -[3294]="25 Stam", -[3295]="16 Haste", -[3296]="10 Spirit", -[3297]="+275 Health", -[3298]="Exceptional Mana Oil", -[3299]="Exceptional Wizard Oil", -[3300]="19 SP", -[3301]="6 Crit", -[3302]="8 Dodge", -[3303]="8 Haste", -[3304]="8 Dodge", -[3305]="12 Stam", -[3306]="2 mana per 5 sec.", -[3307]="9 Stam", -[3308]="4 Haste", -[3309]="6 Haste", -[3310]="6 Int", -[3311]="6 Spirit", -[3312]="8 Str", -[3313]="8 Agi", -[3314]="8 Crit", -[3315]="+3% Mount Speed", -[3316]="6 Crit", -[3317]="21 Stam", -[3318]="5 Int, 5 Spirit", -[3319]="Test Add Sockets Enchant", -[3320]="Test Skill Req Enchant", -[3321]="150 Armor", -[3322]="Frozen Rune Weapon", -[3324]="10 Crit", -[3325]="45 Stam, 15 Agi", -[3326]="55 AP, 15 Crit", -[3327]="55 Stam, 22 Agi", -[3328]="75 AP, 22 Crit", -[3329]="12 Stam", -[3330]="18 Stam", -[3331]="72 Stam, 35 Agi", -[3332]="100 AP, 36 Crit", -[3333]="QA Test Blank Purple Gem Enchant", -[3334]="Northrend Flight", -[3335]="10 Agi", -[3336]="10 Crit", -[3337]="5 Agi, 5 Crit", -[3338]="5 Int, 5 Crit", -[3339]="10 Int", -[3340]="10 Crit", -[3341]="Frozen Rune Weapon 2", -[3342]="Frozen Rune Weapon 3", -[3343]="Frozen Rune Weapon 4", -[3344]="Frozen Rune Weapon 5", -[3345]="Earthliving", -[3351]="6 Hit", -[3352]="8 Spirit", -[3353]="8 Int", -[3354]="12 Stam", -[3355]="6 Agi", -[3356]="12 AP", -[3357]="6 Str", -[3358]="6 Dodge", -[3359]="4 Parry", -[3360]="8 Parry", -[3361]="+6 Block", -[3362]="6 Exp", -[3363]="+9 Block Value", -[3364]="Empower Rune Weapon", -[3365]="Swordshattering", -[3366]="Lichbane", -[3367]="Spellshattering", -[3368]="Fallen Crusader", -[3369]="Cinderglacier", -[3370]="Razorice", -[3371]="12 Str", -[3374]="12 Agi", -[3375]="12 Agi", -[3376]="12 Dodge", -[3377]="12 Parry", -[3378]="12 Crit", -[3379]="12 Exp", -[3380]="12 Int", -[3381]="12 Int", -[3382]="12 Crit", -[3383]="12 Hit", -[3384]="12 Dodge", -[3385]="12 Resil", -[3386]="12 Haste", -[3387]="18 Stam", -[3388]="12 Spirit", -[3389]="12 Spirit", -[3390]="12 PvP Pow", -[3391]="9 Stam, 6 Crit", -[3392]="6 Str, 9 Stam", -[3393]="6 Agi, 9 Stam", -[3394]="6 Int, 9 Stam", -[3395]="6 Agi, 9 Stam", -[3396]="9 Stam, 6 Dodge", -[3397]="9 Stam, 6 Parry", -[3398]="9 Stam, 6 Exp", -[3399]="6 Int, 6 Spirit", -[3400]="6 Agi, 6 Hit", -[3401]="6 Int, 6 Spirit", -[3402]="6 Agi, 6 Hit", -[3403]="6 Int, 6 PvP Pow", -[3404]="6 Int, 6 Haste", -[3405]="6 Str, 6 Crit", -[3406]="6 Agi, 6 Hit", -[3407]="6 Str, 6 Dodge", -[3408]="6 Str, 6 Resil", -[3409]="6 Str, 6 Haste", -[3410]="6 Agi, 6 Crit", -[3411]="6 Str, 6 Hit", -[3412]="6 Agi, 6 Resil", -[3413]="6 Agi, 6 Haste", -[3414]="6 Int, 6 Crit", -[3415]="6 Int, 6 Hit", -[3416]="6 Int, 6 Resil", -[3417]="6 Int, 6 Haste", -[3418]="6 Dodge, 6 Parry", -[3419]="6 Parry, 6 Dodge", -[3420]="6 Exp, 6 Hit", -[3421]="6 Exp, 6 Dodge", -[3422]="6 Agi, 6 Crit", -[3423]="6 Agi, 6 Hit", -[3424]="6 Agi, 6 Resil", -[3426]="6 Agi, 6 Haste", -[3427]="6 Int, 9 Stam", -[3428]="9 Stam, 6 Crit", -[3429]="6 Hit, 6 Dodge", -[3430]="9 Stam, 6 Dodge", -[3431]="6 Resil, 9 Stam", -[3432]="9 Stam, 6 Haste", -[3433]="6 Int, 6 Spirit", -[3434]="6 Crit, 6 Spirit", -[3435]="6 Hit, 6 Haste", -[3436]="6 Resil, 6 Spirit", -[3437]="6 Haste, 6 Spirit", -[3438]="6 Int, 6 Spirit", -[3439]="6 Crit, 6 Spirit", -[3440]="6 Hit, 6 Haste", -[3441]="6 Resil, 6 Spirit", -[3442]="6 Haste, 6 Spirit", -[3443]="6 PvP Pow, 6 Crit", -[3444]="6 PvP Pow, 6 Crit", -[3445]="6 PvP Pow, 6 Haste", -[3446]="16 Str", -[3447]="16 Agi", -[3448]="16 Int", -[3449]="16 Agi", -[3450]="16 Dodge", -[3451]="16 Parry", -[3452]="16 Crit", -[3453]="16 Exp", -[3454]="24 Stam", -[3455]="16 Spirit", -[3456]="16 Spirit", -[3457]="16 PvP Pow", -[3458]="16 Int", -[3459]="16 Crit", -[3460]="16 Hit", -[3461]="16 Dodge", -[3462]="16 Resil", -[3463]="16 Haste", -[3464]="8 Str, 12 Stam", -[3465]="8 Agi, 12 Stam", -[3466]="8 Int, 12 Stam", -[3467]="8 Agi, 12 Stam", -[3468]="12 Stam, 8 Dodge", -[3469]="12 Stam, 8 Parry", -[3470]="12 Stam, 8 Crit", -[3471]="12 Stam, 8 Exp", -[3472]="8 Int, 8 Spirit", -[3473]="8 Int, 8 Spirit", -[3474]="8 Agi, 8 Hit", -[3475]="8 Agi, 8 Hit", -[3476]="8 Int, 8 PvP Pow", -[3477]="8 Str, 8 Crit", -[3478]="8 Str, 8 Hit", -[3479]="8 Str, 8 Dodge", -[3480]="8 Str, 8 Resil", -[3481]="8 Str, 8 Haste", -[3482]="8 Agi, 8 Crit", -[3483]="8 Agi, 8 Hit", -[3484]="8 Agi, 8 Resil", -[3485]="8 Agi, 8 Haste", -[3486]="8 Int, 8 Haste", -[3487]="8 Int, 8 Crit", -[3488]="8 Int, 8 Hit", -[3489]="8 Int, 8 Resil", -[3490]="8 Int, 8 Haste", -[3491]="8 Agi, 8 Crit", -[3492]="8 Agi, 8 Hit", -[3493]="8 Agi, 8 Resil", -[3494]="8 Agi, 8 Haste", -[3495]="8 Dodge, 8 Parry", -[3496]="8 Parry, 8 Dodge", -[3497]="8 Exp, 8 Hit", -[3498]="8 Exp, 8 Dodge", -[3499]="8 Int, 12 Stam", -[3500]="12 Stam, 8 Crit", -[3501]="8 Hit, 8 Dodge", -[3502]="12 Stam, 8 Dodge", -[3503]="8 Resil, 12 Stam", -[3504]="12 Stam, 8 Haste", -[3505]="8 Int, 8 Spirit", -[3506]="8 Crit, 8 Spirit", -[3507]="8 Hit, 8 Haste", -[3508]="8 Resil, 8 Spirit", -[3509]="8 Haste, 8 Spirit", -[3510]="8 Int, 8 Spirit", -[3511]="8 Crit, 8 Spirit", -[3512]="8 Hit, 8 Haste", -[3513]="8 Resil, 8 Spirit", -[3514]="8 Haste, 8 Spirit", -[3515]="8 PvP Pow, 8 Crit", -[3516]="8 PvP Pow, 8 Crit", -[3517]="8 PvP Pow, 8 Haste", -[3518]="20 Str", -[3519]="20 Agi", -[3520]="20 Int", -[3521]="20 Agi", -[3522]="20 Dodge", -[3523]="20 Parry", -[3524]="20 Exp", -[3525]="20 Crit", -[3526]="20 Int", -[3527]="20 Crit", -[3528]="20 Hit", -[3529]="20 Dodge", -[3530]="20 Resil", -[3531]="20 Haste", -[3532]="30 Stam", -[3533]="20 Spirit", -[3534]="20 Spirit", -[3535]="20 PvP Pow", -[3536]="10 Str, 15 Stam", -[3537]="10 Agi, 15 Stam", -[3538]="10 Int, 15 Stam", -[3539]="10 Agi, 15 Stam", -[3540]="15 Stam, 10 Dodge", -[3541]="15 Stam, 10 Parry", -[3542]="15 Stam, 10 Exp", -[3543]="15 Stam, 10 Crit", -[3544]="10 Agi, 10 Hit", -[3545]="10 Int, 10 Spirit", -[3546]="10 Int, 10 Spirit", -[3547]="10 Agi, 10 Hit", -[3548]="10 Int, 10 PvP Pow", -[3549]="10 Str, 10 Crit", -[3550]="10 Str, 10 Hit", -[3551]="10 Str, 10 Dodge", -[3552]="10 Str, 10 Resil", -[3553]="10 Str, 10 Haste", -[3554]="10 Agi, 10 Crit", -[3555]="10 Agi, 10 Hit", -[3556]="10 Agi, 10 Resil", -[3557]="10 Agi, 10 Haste", -[3558]="10 Int, 10 Spirit", -[3559]="10 Int, 10 Crit", -[3560]="10 Int, 10 Hit", -[3561]="10 Int, 10 Resil", -[3563]="10 Int, 10 Haste", -[3564]="10 Agi, 10 Crit", -[3565]="10 Agi, 10 Hit", -[3566]="10 Agi, 10 Resil", -[3567]="10 Agi, 10 Haste", -[3568]="10 Dodge, 10 Parry", -[3569]="10 Parry, 10 Dodge", -[3570]="10 Exp, 10 Hit", -[3571]="10 Exp, 10 Dodge", -[3572]="10 Int, 15 Stam", -[3573]="15 Stam, 10 Crit", -[3574]="10 Hit, 10 Dodge", -[3575]="15 Stam, 10 Dodge", -[3576]="10 Resil, 15 Stam", -[3577]="15 Stam, 10 Haste", -[3578]="10 Int, 10 Spirit", -[3579]="10 Crit, 10 Spirit", -[3580]="10 Hit, 10 Haste", -[3581]="10 Resil, 10 Spirit", -[3582]="10 Haste, 10 Spirit", -[3583]="10 Int, 10 Spirit", -[3584]="10 Crit, 10 Spirit", -[3585]="10 Hit, 10 Haste", -[3586]="10 Resil, 10 Spirit", -[3587]="10 Haste, 10 Spirit", -[3588]="10 PvP Pow, 10 Crit", -[3589]="10 PvP Pow, 10 Crit", -[3590]="10 PvP Pow, 10 Haste", -[3591]="4 Int", -[3592]="+100 Spell Power vs Undead", -[3593]="+170 Attack Power vs Undead", -[3594]="Swordbreaking", -[3595]="Spellbreaking", -[3596]="5 SP", -[3597]="Master Firestone", -[3599]="Use: Stuns all nearby Mechanical units for 3 sec. (1 Min Cooldown)", -[3600]="6 Resil", -[3601]="Use: Detatch and throw a thermal grenade, inflicting 10,000 Fire damage and incapacitating targets for 3 sec in a 3 yard radius. Any damage will break the effect. (1 Min Cooldown)", -[3602]="7 SP", -[3603]="Use: Fires an explosive rocket at an enemy for 1,165 Fire damage. (45 Sec Cooldown)", -[3604]="Use: Increases your haste by 240 for 12 sec. (1 Min Cooldown)", -[3605]="Use: Reduces your falling speed for 30 sec. (1 Min Cooldown)", -[3607]="40 Haste", -[3608]="40 Crit", -[3609]="Firestone", -[3610]="Firestone", -[3611]="Greater Firestone", -[3612]="Major Firestone", -[3613]="Fel Firestone", -[3614]="Grand Firestone", -[3615]="Spellstone", -[3616]="Greater Spellstone", -[3617]="Major Spellstone", -[3618]="Master Spellstone", -[3619]="Demonic Spellstone", -[3620]="Grand Spellstone", -[3621]="21 Crit", -[3622]="25 Crit", -[3623]="21 Int", -[3624]="21 Crit", -[3625]="21 Crit", -[3626]="21 Int", -[3627]="21 Int", -[3628]="21 Agi", -[3630]="21 Dodge", -[3631]="21 Dodge", -[3632]="21 Int", -[3633]="22 Spirit", -[3634]="32 Stam", -[3635]="21 Int", -[3636]="21 Crit", -[3637]="32 Stam", -[3638]="21 Crit", -[3639]="21 Int", -[3640]="21 Haste", -[3641]="21 Crit", -[3642]="32 Stam", -[3643]="Chance to Increase Melee/Ranged Attack Speed", -[3644]="14 Agi", -[3646]="14 Dodge", -[3647]="14 Exp", -[3648]="14 Parry", -[3649]="14 Str", -[3650]="14 Int", -[3651]="14 Agi", -[3652]="14 Crit", -[3653]="14 Spirit", -[3654]="14 Spirit", -[3655]="21 Stam", -[3656]="14 PvP Pow", -[3657]="14 Crit", -[3658]="14 Dodge", -[3659]="14 Haste", -[3660]="14 Hit", -[3661]="14 Int", -[3662]="14 Resil", -[3663]="7 Agi, 7 Hit", -[3664]="7 Agi, 10 Stam", -[3665]="10 Stam, 7 Crit", -[3666]="7 Agi, 7 Hit", -[3667]="7 Agi, 10 Stam", -[3668]="10 Stam, 7 Dodge", -[3669]="10 Stam, 7 Exp", -[3670]="10 Stam, 7 Parry", -[3671]="7 Str, 10 Stam", -[3672]="7 Int, 7 Spirit", -[3673]="7 Int, 7 Spirit", -[3674]="7 Int, 7 PvP Pow", -[3675]="7 Int, 10 Stam", -[3676]="14 AP, 7 Crit", -[3677]="7 Agi, 7 Haste", -[3678]="7 Agi, 7 Haste", -[3679]="7 Agi, 7 Hit", -[3680]="7 Agi, 7 Resil", -[3681]="7 Str, 7 Crit", -[3682]="7 Str, 7 Hit", -[3683]="7 Str, 7 Dodge", -[3684]="7 Str, 7 Resil", -[3685]="7 Str, 7 Haste", -[3686]="7 Agi, 7 Crit", -[3687]="7 Agi, 7 Hit", -[3688]="7 Agi, 7 Resil", -[3689]="7 Int, 7 Spirit", -[3690]="7 Int, 7 Crit", -[3691]="7 Int, 7 Hit", -[3692]="7 Int, 7 Resil", -[3693]="7 Int, 7 Haste", -[3694]="7 Dodge, 7 Parry", -[3695]="7 Parry, 7 Dodge", -[3696]="7 Exp, 7 Hit", -[3697]="7 Exp, 7 Dodge", -[3698]="7 Crit, 7 Spirit", -[3699]="10 Stam, 7 Crit", -[3700]="10 Stam, 7 Dodge", -[3701]="7 Haste, 7 Spirit", -[3702]="10 Stam, 7 Haste", -[3703]="7 Hit, 7 Haste", -[3704]="7 Hit, 7 Dodge", -[3705]="7 Int, 7 Spirit", -[3706]="7 Int, 10 Stam", -[3707]="7 Resil, 7 Spirit", -[3708]="7 Resil, 10 Stam", -[3709]="7 PvP Pow, 7 Crit", -[3710]="7 Crit, 7 Spirit", -[3711]="7 Int, 7 Spirit", -[3712]="7 Hit, 7 Haste", -[3713]="7 Resil, 7 Spirit", -[3714]="7 Haste, 7 Spirit", -[3715]="7 PvP Pow, 7 Crit", -[3716]="7 PvP Pow, 7 Haste", -[3717]="Socket Bracer", -[3718]="35 SP, 12 Spirit", -[3719]="50 SP, 20 Spirit", -[3720]="35 SP, 20 Stam", -[3721]="50 SP, 30 Stam", -[3722]="Lightweave 1", -[3723]="Socket Gloves", -[3726]="1 Haste", -[3727]="1 Hit", -[3728]="Darkglow 1", -[3729]="Socket Belt", -[3730]="Swordguard 1", -[3731]="28 Hit", -[3732]="34 Str", -[3733]="34 Agi", -[3734]="34 Int", -[3735]="34 Spirit", -[3736]="34 Spirit", -[3737]="34 Int", -[3738]="34 Crit", -[3739]="34 Haste", -[3740]="34 Dodge", -[3741]="34 Parry", -[3742]="34 Hit", -[3743]="34 Dodge", -[3744]="34 Resil", -[3745]="34 Crit", -[3746]="34 Exp", -[3747]="34 PvP Pow", -[3748]="Titanium Spike (45-67)", -[3749]="4 Str, 4 Agi, 4 Stam, 4 Int, 4 Spirit", -[3750]="6 Str, 6 Agi, 6 Stam, 6 Int, 6 Spirit", -[3751]="6 Dodge", -[3752]="5 SP", -[3753]="9 SP", -[3754]="24 AP", -[3755]="28 AP", -[3756]="130 AP", -[3757]="102 Stam", -[3758]="57 Int", -[3759]="102 Stam", -[3760]="102 Stam", -[3761]="102 Stam", -[3762]="102 Stam", -[3763]="102 Stam", -[3764]="12 AP", -[3765]="4 Crit", -[3766]="12 Stam", -[3767]="7 Agi, 7 Crit", -[3775]="30 SP, 15 Crit", -[3776]="45 AP, 15 Crit", -[3777]="22 Stam, 20 Dodge", -[3778]="8 Exp", -[3788]="25 Hit, 25 Crit", -[3789]="Berserking", -[3790]="Black Magic", -[3791]="30 Stam", -[3792]="20 Resil", -[3793]="40 AP, 15 Resil", -[3794]="23 SP, 15 Resil", -[3795]="50 AP, 20 Resil", -[3796]="29 SP, 20 Resil", -[3797]="29 SP, 20 Resil", -[3798]="17 Crit", -[3799]="17 Int", -[3800]="17 Crit", -[3801]="17 Crit", -[3802]="17 Int", -[3803]="17 Crit", -[3804]="26 Stam", -[3805]="17 Int", -[3806]="18 SP, 10 Crit", -[3807]="15 Int, 10 Spirit", -[3808]="40 AP, 15 Crit", -[3809]="21 Int, 16 Spirit", -[3810]="24 SP, 15 Crit", -[3811]="22 Stam, 20 Dodge", -[3812]="30 Stam", -[3813]="30 Stam", -[3814]="30 Stam", -[3815]="30 Stam", -[3816]="30 Stam", -[3817]="50 AP, 20 Crit", -[3818]="37 Stam, 20 Dodge", -[3819]="26 Int, 20 Spirit", -[3820]="26 Int, 20 Crit", -[3821]="8 Resil", -[3822]="55 Stam, 22 Agi", -[3823]="75 AP, 22 Crit", -[3824]="24 AP", -[3825]="15 Haste", -[3826]="12 Hit, 12 Crit", -[3827]="110 AP", -[3828]="85 AP", -[3829]="35 AP", -[3830]="50 SP", -[3831]="23 Haste", -[3832]="10 All Stats", -[3833]="65 AP", -[3834]="63 SP", -[3835]="120 AP, 15 Crit", -[3836]="60 Int, 15 Spirit", -[3837]="60 Dodge, 15 Parry", -[3838]="70 SP, 15 Crit", -[3839]="40 AP", -[3840]="20 Int", -[3841]="23 SP", -[3842]="30 Stam, 25 Resil", -[3843]="Scope (+15 Damage)", -[3844]="45 Spirit", -[3845]="50 AP", -[3846]="40 SP", -[3847]="Stoneskin Gargoyle", -[3848]="Socket Staff", -[3849]="Titanium Plating", -[3850]="40 Stam", -[3851]="50 Stam", -[3852]="30 Stam, 15 Resil", -[3853]="40 Resil, 28 Stam", -[3854]="81 SP", -[3855]="69 SP", -[3856]="100 Agi", -[3857]="6 Dodge", -[3858]="5 Hit", -[3859]="Use: Reduces your falling speed for 30 sec. (1 Min Cooldown)", -[3860]="Use: Increases your armor by 700 for 14 sec. (1 Min Cooldown)", -[3861]="20 Str", -[3862]="20 Agi", -[3863]="30 Stam", -[3864]="20 Spirit", -[3865]="20 Int", -[3866]="20 Int", -[3867]="20 Hit", -[3868]="Fishing Lure (+100 Fishing Skill)", -[3869]="Blade Ward", -[3870]="Blood Draining", -[3871]="6 Parry", -[3872]="50 SP, 20 Spirit", -[3873]="50 SP, 30 Stam", -[3874]="130 AP", -[3875]="30 AP, 10 Crit", -[3876]="15 Dodge, 10 Parry", -[3877]="16 AP", -[3879]="10 All Stats", -[3880]="6 Crit", -[3881]="+17 Mana every 5 seconds", -[3882]="8 Crit", -[3883]="Nerubian Carapace", -[3884]="24 Stam, 24 Agi", -[3885]="15 Mastery, 15 Spirit", -[3886]="15 Mastery, 15 Hit", -[3887]="18 Mastery, 17 Spirit", -[3888]="18 Mastery, 17 Hit", -[3889]="30 Str", -[3890]="30 Agi", -[3891]="30 Parry", -[3892]="30 Int", -[3893]="30 Exp", -[3894]="45 Stam", -[3895]="30 Spirit", -[3896]="30 PvP Pow", -[3897]="30 Hit", -[3898]="30 Dodge", -[3899]="30 Resil", -[3900]="30 Haste", -[3901]="30 Mastery", -[3902]="15 Str, 23 Stam", -[3903]="23 Stam, 15 Parry", -[3904]="15 Agi, 23 Stam", -[3905]="15 Int, 23 Stam", -[3906]="23 Stam, 15 Exp", -[3907]="15 Int, 15 Spirit", -[3908]="15 Str, 15 Hit", -[3909]="15 Agi, 15 Hit", -[3910]="15 Parry, 15 Hit", -[3911]="15 Int, 15 Hit", -[3912]="15 Exp, 15 Hit", -[3913]="15 Agi, 15 Dodge", -[3914]="15 Exp, 15 Dodge", -[3915]="15 Str, 15 Crit", -[3916]="15 Agi, 15 Crit", -[3917]="15 Int, 15 Crit", -[3918]="15 Str, 15 Haste", -[3919]="15 Agi, 15 Haste", -[3920]="15 Int, 15 Haste", -[3921]="15 Str, 15 Mastery", -[3922]="15 Agi, 15 Mastery", -[3923]="15 Parry, 15 Mastery", -[3924]="15 Int, 15 Mastery", -[3925]="15 Exp, 15 Mastery", -[3926]="23 Stam, 15 Dodge", -[3927]="15 Dodge, 15 Hit", -[3928]="23 Stam, 15 Crit", -[3929]="15 Crit, 15 Hit", -[3930]="15 Resil, 23 Stam", -[3931]="23 Stam, 15 Haste", -[3932]="15 Haste, 15 Hit", -[3933]="23 Stam, 15 Mastery", -[3936]="30 Crit", -[3937]="18 Str, 17 Hit", -[3938]="18 Int, 17 Spirit", -[3939]="26 Stam, 18 Exp", -[3940]="18 Int, 26 Stam", -[3941]="26 Stam, 18 Parry", -[3942]="18 Agi, 23 Stam", -[3943]="18 Str, 26 Stam", -[3944]="35 Mastery", -[3945]="35 Haste", -[3946]="35 Resil", -[3947]="35 Crit", -[3948]="35 Dodge", -[3949]="35 Hit", -[3950]="35 PvP Pow", -[3951]="35 Spirit", -[3952]="53 Stam", -[3953]="35 Exp", -[3954]="35 Int", -[3955]="35 Parry", -[3956]="35 Agi", -[3957]="35 Str", -[3958]="26 Stam, 18 Mastery", -[3959]="18 Haste, 17 Hit", -[3960]="26 Stam, 18 Haste", -[3961]="18 Resil, 26 Stam", -[3962]="18 Crit, 17 Hit", -[3963]="26 Stam, 18 Crit", -[3964]="18 Dodge, 17 Hit", -[3965]="26 Stam, 18 Dodge", -[3966]="18 Exp, 17 Mastery", -[3967]="18 Int, 17 Mastery", -[3968]="18 Parry, 17 Mastery", -[3969]="18 Agi, 17 Mastery", -[3970]="18 Str, 17 Mastery", -[3971]="18 Int, 17 Haste", -[3972]="18 Agi, 17 Haste", -[3973]="18 Str, 17 Haste", -[3974]="18 Int, 17 Crit", -[3975]="18 Agi, 17 Crit", -[3976]="18 Str, 17 Crit", -[3977]="18 Exp, 17 Dodge", -[3978]="18 Agi, 17 Dodge", -[3979]="18 Exp, 17 Hit", -[3980]="18 Int, 17 Hit", -[3981]="18 Parry, 17 Hit", -[3982]="18 Agi, 17 Hit", -[3983]="20 Exp, 20 Hit", -[3984]="30 Stam, 20 Parry", -[3985]="20 Str, 20 Hit", -[3986]="20 Int, 20 Hit", -[3987]="20 Agi, 20 Hit", -[3988]="30 Stam, 20 Exp", -[3989]="20 Parry, 20 Hit", -[3990]="20 Int, 20 Spirit", -[3991]="20 Agi, 30 Stam", -[3992]="20 Str, 30 Stam", -[3993]="20 Int, 30 Stam", -[3994]="40 Str", -[3995]="40 Int", -[3996]="40 Agi", -[3997]="40 Parry", -[3998]="40 Exp", -[3999]="40 Mastery", -[4000]="40 Resil", -[4001]="40 Haste", -[4002]="40 Crit", -[4003]="40 Dodge", -[4004]="40 Hit", -[4005]="60 Stam", -[4006]="40 Spirit", -[4007]="40 PvP Pow", -[4008]="20 Agi, 20 Mastery", -[4009]="20 Int, 20 Mastery", -[4010]="20 Int, 20 Haste", -[4011]="20 Agi, 20 Crit", -[4012]="20 Agi, 20 Haste", -[4013]="20 Str, 20 Haste", -[4014]="20 Parry, 20 Mastery", -[4015]="20 Str, 20 Crit", -[4016]="20 Exp, 20 Mastery", -[4017]="20 Agi, 20 Dodge", -[4018]="20 Int, 20 Crit", -[4019]="20 Str, 20 Mastery", -[4020]="20 Exp, 20 Dodge", -[4021]="30 Stam, 20 Haste", -[4022]="30 Stam, 20 Crit", -[4023]="20 Haste, 20 Hit", -[4024]="20 Dodge, 20 Hit", -[4025]="20 Crit, 20 Hit", -[4026]="30 Stam, 20 Mastery", -[4027]="30 Stam, 20 Dodge", -[4028]="20 Mastery, 20 Hit", -[4029]="20 Resil, 30 Stam", -[4030]="20 Mastery, 20 Spirit", -[4031]="67 Str", -[4032]="67 Int", -[4033]="67 Agi", -[4034]="67 Parry", -[4035]="67 Mastery", -[4036]="67 Resil", -[4037]="67 Exp", -[4038]="67 Haste", -[4039]="67 Hit", -[4040]="67 Crit", -[4041]="101 Stam", -[4042]="67 Spirit", -[4043]="67 PvP Pow", -[4044]="67 Dodge", -[4045]="54 Mastery", -[4046]="54 Crit", -[4047]="54 Int", -[4048]="81 Stam", -[4049]="81 Stam", -[4050]="81 Stam", -[4051]="54 Int", -[4052]="54 Spirit", -[4053]="54 Crit", -[4054]="81 Stam", -[4055]="54 Crit", -[4056]="54 Crit", -[4057]="54 Int", -[4058]="1 Exp", -[4059]="1 Mastery", -[4060]="1 Parry", -[4061]="50 Mastery", -[4062]="30 Stam, Run Speed", -[4063]="15 All Stats", -[4064]="56 PvP Pow", -[4065]="50 Haste", -[4066]="Mending", -[4067]="Avalanche", -[4068]="50 Haste", -[4069]="50 Haste", -[4070]="55 Stam", -[4071]="50 Crit", -[4072]="30 Int", -[4073]="16 Stam", -[4074]="Elemental Slayer", -[4075]="35 Str", -[4076]="35 Agi", -[4077]="40 Resil", -[4078]="40 Str", -[4079]="40 Agi", -[4080]="40 Int", -[4081]="60 Stam", -[4082]="50 Exp", -[4083]="Hurricane", -[4084]="Heartsong", -[4085]="50 Mastery", -[4086]="50 Dodge", -[4087]="50 Crit", -[4088]="40 Spirit", -[4089]="50 Hit", -[4090]="30 Stam", -[4091]="40 Int", -[4092]="50 Hit", -[4093]="50 Spirit", -[4094]="50 Mastery", -[4095]="50 Exp", -[4096]="50 Int", -[4097]="Power Torrent", -[4098]="Windwalk", -[4099]="Landslide", -[4100]="65 Crit", -[4101]="65 Crit", -[4102]="20 All Stats", -[4103]="75 Stam", -[4104]="35 Mastery, Run Speed", -[4105]="25 Agi, Run Speed", -[4106]="50 Str", -[4107]="65 Mastery", -[4108]="65 Haste", -[4109]="55 Int, 45 Spirit", -[4110]="95 Int, 55 Spirit", -[4111]="55 Int, 65 Stam", -[4112]="95 Int, 80 Stam", -[4113]="95 Int, 80 Stam", -[4114]="95 Int, 55 Spirit", -[4115]="Lightweave 2", -[4116]="Darkglow 2", -[4117]="Swordguard Embroidery", -[4118]="Swordguard 2", -[4119]="50 Str", -[4120]="36 Stam", -[4121]="44 Stam", -[4122]="110 AP, 45 Crit", -[4123]="10 Mastery", -[4124]="85 Stam, 45 Agi", -[4125]="30 Spirit", -[4126]="190 AP, 55 Crit", -[4127]="145 Stam, 55 Agi", -[4128]="30 Haste", -[4129]="20 Spirit", -[4130]="20 Crit", -[4131]="10 Crit", -[4132]="30 Crit", -[4134]="30 Stam", -[4135]="10 Str", -[4136]="20 Str", -[4137]="20 Mastery", -[4138]="30 Mastery", -[4139]="20 Parry", -[4140]="20 Haste", -[4141]="20 Hit", -[4142]="10 Spirit", -[4143]="10 Int", -[4144]="20 Int", -[4145]="30 Agi", -[4146]="10 Haste", -[4147]="10 Parry", -[4148]="30 Parry", -[4149]="20 Int", -[4150]="30 Int", -[4151]="10 Crit", -[4152]="20 Crit", -[4153]="30 Crit", -[4154]="15 Stam", -[4155]="10 Dodge", -[4156]="20 Dodge", -[4157]="30 Dodge", -[4158]="30 Str", -[4159]="45 Stam", -[4160]="10 Hit", -[4161]="20 Hit", -[4162]="30 Hit", -[4163]="10 Exp", -[4164]="20 Exp", -[4165]="30 Exp", -[4166]="208 Dodge", -[4167]="208 Crit", -[4168]="208 Haste", -[4169]="208 Mastery", -[4170]="208 Exp", -[4171]="208 Parry", -[4172]="208 Hit", -[4173]="208 Spirit", -[4175]="Gnomish X-Ray", -[4176]="88 Hit", -[4177]="88 Haste", -[4178]="900 Armor", -[4179]="Use: Increases your Intellect, Agility, or Strength by 480 for 10 sec. Your highest stat is always chosen. (1 Min Cooldown)", -[4180]="Use: Increases your armor by 1,500 for 13 sec. (1 Min Cooldown)", -[4181]="Use: Fires an electrified ball at an enemy for 4,800 Nature damage. (2 Min Cooldown)", -[4184]="10 Resil", -[4185]="20 Resil", -[4186]="30 Resil", -[4187]="Use: Activates a personal invisibility field. Cannot be used in combat. (3 Min Cooldown)", -[4188]="Use: Protects you with a shield of force that stops 18,000 damage for 8 sec. The strong magnetic field sometimes has strange side effects... (5 Min Cooldown)", -[4189]="195 Stam", -[4190]="130 Agi", -[4191]="130 Str", -[4192]="130 Int", -[4193]="130 Agi, 25 Mastery", -[4194]="130 Str, 25 Crit", -[4195]="195 Stam, 25 Dodge", -[4196]="130 Int, 25 Haste", -[4197]="45 Stam, 20 Dodge", -[4198]="75 Stam, 25 Dodge", -[4199]="30 Int, 20 Haste", -[4200]="50 Int, 25 Haste", -[4201]="30 Str, 20 Crit", -[4202]="50 Str, 25 Crit", -[4203]="30 Agi, 20 Mastery", -[4204]="50 Agi, 25 Mastery", -[4205]="30 Agi, 20 Mastery", -[4206]="90 Stam, 35 Dodge", -[4207]="60 Int, 35 Crit", -[4208]="60 Str, 35 Mastery", -[4209]="60 Agi, 35 Haste", -[4211]="10 Haste", -[4212]="7 Str", -[4213]="7 Str", -[4214]="Use: Summons a Cardboard Assassin to draw the attention of enemies. (5 Min Cooldown)", -[4215]="Elementium Spike (90-133)", -[4216]="Pyrium Spike (210-350)", -[4217]="40 Hit", -[4222]="Use: Engage in mental combat with a humanoid target in an attempt to pacify or control them. (10 Min Cooldown)", -[4223]="Use: Greatly increase your run speed for 5 sec. (3 Min Cooldown)", -[4225]="Fishing Lure (+150 Fishing Skill)", -[4227]="130 Agi", -[4236]="20 Int, 20 Resil", -[4237]="20 Agi, 20 Resil", -[4238]="20 Str, 20 Resil", -[4239]="208 Resil", -[4244]="20 Resil, 20 PvP Pow", -[4245]="60 Int, 35 Resil", -[4246]="60 Agi, 35 Resil", -[4247]="60 Str, 35 Resil", -[4248]="50 Int, 25 Resil", -[4249]="50 Str, 25 Resil", -[4250]="50 Agi, 25 Resil", -[4251]="54 Agi", -[4252]="54 Str", -[4253]="54 Int", -[4256]="50 Str", -[4257]="50 Int", -[4258]="50 Agi", -[4259]="+1 Fishing", -[4262]="30 Stam", -[4263]="20 Spirit", -[4264]="Fishing Lure (+15 Fishing Skill)", -[4265]="50 Int", -[4266]="50 Agi", -[4267]="Flintlocke's", -[4270]="145 Stam, 55 Dodge", -[4273]="50 Hit", -[4274]="50 PvP Pow", -[4275]="50 Spirit", -[4276]="75 Stam", -[4277]="25 Spirit, 25 Crit", -[4278]="25 Crit, 25 Hit", -[4279]="25 Haste, 25 Hit", -[4280]="25 Hit, 25 Mastery", -[4281]="25 PvP Pow, 25 Mastery", -[4282]="25 Spirit, 25 Mastery", -[4283]="25 Resil, 25 Hit", -[4284]="25 PvP Pow, 25 Resil", -[4285]="25 Resil, 25 Spirit", -[4286]="25 PvP Pow, 25 Crit", -[4287]="25 PvP Pow, 25 Haste", -[4288]="25 Haste, 25 Spirit", -[4289]="37 Stam, 25 Crit", -[4290]="37 Stam, 25 Dodge", -[4291]="37 Stam, 25 Haste", -[4292]="25 Hit, 25 Dodge", -[4293]="37 Stam, 25 Mastery", -[4294]="25 Resil, 37 Stam", -[4295]="25 Agi, 25 Crit", -[4296]="25 Exp, 25 Crit", -[4297]="25 Int, 25 Crit", -[4298]="25 Str, 25 Crit", -[4299]="25 Agi, 25 Dodge", -[4300]="25 Exp, 25 Dodge", -[4301]="25 Parry, 25 Dodge", -[4302]="25 Str, 25 Dodge", -[4303]="25 Agi, 25 Haste", -[4304]="25 Exp, 25 Haste", -[4305]="25 Int, 25 Haste", -[4306]="25 Str, 25 Haste", -[4307]="25 Agi, 25 Mastery", -[4308]="25 Exp, 25 Mastery", -[4309]="25 Int, 25 Mastery", -[4310]="25 Parry, 25 Mastery", -[4311]="25 Str, 25 Mastery", -[4312]="25 Agi, 25 Resil", -[4313]="25 Resil, 25 Exp", -[4314]="25 Int, 25 Resil", -[4315]="25 Resil, 25 Parry", -[4316]="25 Str, 25 Resil", -[4317]="25 Agi, 25 Hit", -[4318]="25 Exp, 25 Hit", -[4319]="25 Int, 25 Hit", -[4320]="25 Parry, 25 Hit", -[4321]="25 Str, 25 Hit", -[4322]="25 Int, 25 PvP Pow", -[4323]="25 Int, 25 Spirit", -[4324]="25 Agi, 37 Stam", -[4325]="37 Stam, 25 Exp", -[4326]="25 Int, 37 Stam", -[4327]="37 Stam, 25 Parry", -[4328]="25 Str, 37 Stam", -[4329]="50 Agi", -[4330]="50 Exp", -[4331]="50 Int", -[4332]="50 Parry", -[4333]="50 Str", -[4334]="50 Crit", -[4335]="50 Dodge", -[4336]="50 Haste", -[4337]="50 Mastery", -[4338]="50 Resil", -[4359]="160 Agi", -[4360]="160 Int", -[4361]="240 Stam", -[4411]="170 Mastery", -[4412]="170 Dodge", -[4414]="180 Int", -[4415]="180 Str", -[4416]="180 Agi", -[4417]="200 Resil", -[4418]="200 Spirit", -[4419]="80 All Stats", -[4420]="300 Stam", -[4421]="180 Hit", -[4422]="200 Stam", -[4423]="180 Int", -[4424]="180 Crit", -[4426]="175 Haste", -[4427]="175 Hit", -[4428]="140 Agi, Run Speed", -[4429]="140 Mastery, Run Speed", -[4430]="170 Haste", -[4431]="170 Exp", -[4432]="170 Str", -[4433]="170 Mastery", -[4434]="165 Int", -[4435]="145 Stam, 55 Dodge", -[4436]="145 Stam, 55 Agi", -[4437]="190 AP, 55 Crit", -[4438]="145 Stam, 55 Dodge", -[4439]="145 Stam, 55 Agi", -[4440]="190 AP, 55 Crit", -[4441]="Windsong", -[4442]="Jade Spirit", -[4443]="Elemental Force", -[4444]="Dancing Steel", -[4445]="Colossus", -[4446]="River's Song", -[4453]="240 Hit", -[4454]="240 PvP Pow", -[4455]="240 Spirit", -[4456]="180 Stam", -[4457]="120 Spirit, 120 Crit", -[4458]="120 Crit, 120 Hit", -[4459]="120 Haste, 120 Hit", -[4460]="120 Hit, 120 Mastery", -[4461]="120 PvP Pow, 120 Mastery", -[4462]="120 Spirit, 120 Mastery", -[4463]="120 Resil, 120 Hit", -[4464]="120 PvP Pow, 120 Resil", -[4465]="120 Resil, 120 Spirit", -[4466]="120 PvP Pow, 120 Crit", -[4467]="120 PvP Pow, 120 Haste", -[4468]="120 Haste, 120 Spirit", -[4469]="90 Stam, 120 Crit", -[4470]="90 Stam, 120 Dodge", -[4471]="90 Stam, 120 Haste", -[4472]="90 Stam, 120 Hit", -[4473]="90 Stam, 120 Mastery", -[4474]="120 Resil, 90 Stam", -[4475]="60 Agi, 120 Crit", -[4476]="120 Exp, 120 Crit", -[4477]="60 Int, 120 Crit", -[4478]="60 Str, 120 Crit", -[4479]="60 Agi, 120 Dodge", -[4480]="120 Exp, 120 Dodge", -[4481]="120 Parry, 120 Dodge", -[4482]="60 Str, 120 Dodge", -[4483]="60 Agi, 120 Haste", -[4484]="120 Exp, 120 Haste", -[4485]="60 Int, 120 Haste", -[4486]="60 Str, 120 Haste", -[4487]="60 Agi, 120 Mastery", -[4488]="120 Exp, 120 Mastery", -[4489]="60 Int, 120 Mastery", -[4490]="120 Parry, 120 Mastery", -[4491]="60 Str, 120 Mastery", -[4492]="60 Agi, 120 Resil", -[4493]="120 Resil, 120 Exp", -[4494]="60 Int, 120 Resil", -[4495]="120 Resil, 120 Parry", -[4496]="60 Str, 120 Resil", -[4497]="60 Agi, 120 Hit", -[4498]="120 Exp, 120 Hit", -[4499]="60 Int, 120 Hit", -[4500]="120 Parry, 120 Hit", -[4501]="60 Str, 120 Hit", -[4502]="60 Int, 120 PvP Pow", -[4503]="60 Int, 120 Spirit", -[4504]="60 Agi, 90 Stam", -[4505]="90 Stam, 120 Exp", -[4506]="60 Int, 90 Stam", -[4507]="90 Stam, 120 Parry", -[4508]="60 Str, 90 Stam", -[4509]="120 Agi", -[4511]="240 Exp", -[4512]="120 Int", -[4513]="240 Parry", -[4514]="120 Str", -[4515]="240 Crit", -[4516]="240 Dodge", -[4517]="240 Haste", -[4518]="240 Mastery", -[4519]="240 Resil", -[4520]="320 Hit", -[4521]="320 PvP Pow", -[4522]="320 Spirit", -[4523]="240 Stam", -[4524]="160 Spirit, 160 Crit", -[4525]="160 Crit, 160 Hit", -[4526]="160 Haste, 160 Hit", -[4527]="160 Hit, 160 Mastery", -[4528]="160 PvP Pow, 160 Mastery", -[4529]="160 Spirit, 160 Mastery", -[4530]="160 Resil, 160 Hit", -[4531]="160 PvP Pow, 160 Resil", -[4532]="160 Resil, 160 Spirit", -[4533]="160 PvP Pow, 160 Crit", -[4535]="160 PvP Pow, 160 Haste", -[4536]="160 Haste, 160 Spirit", -[4537]="120 Stam, 160 Crit", -[4538]="120 Stam, 160 Dodge", -[4539]="120 Stam, 160 Haste", -[4540]="120 Stam, 160 Hit", -[4541]="120 Stam, 160 Mastery", -[4542]="160 Resil, 120 Stam", -[4543]="80 Agi, 160 Crit", -[4544]="160 Exp, 160 Crit", -[4545]="80 Int, 160 Crit", -[4546]="80 Str, 160 Crit", -[4547]="80 Agi, 160 Dodge", -[4548]="160 Exp, 160 Dodge", -[4549]="160 Parry, 160 Dodge", -[4550]="80 Str, 160 Dodge", -[4551]="80 Agi, 160 Haste", -[4552]="160 Exp, 160 Haste", -[4553]="80 Int, 160 Haste", -[4554]="80 Str, 160 Haste", -[4555]="80 Agi, 160 Mastery", -[4556]="160 Exp, 160 Mastery", -[4557]="80 Int, 160 Mastery", -[4558]="160 Parry, 160 Mastery", -[4559]="80 Str, 160 Mastery", -[4560]="80 Agi, 160 Resil", -[4561]="160 Resil, 160 Exp", -[4562]="80 Int, 160 Resil", -[4563]="160 Resil, 160 Parry", -[4564]="80 Str, 160 Resil", -[4565]="80 Agi, 160 Hit", -[4566]="160 Exp, 160 Hit", -[4567]="80 Int, 160 Hit", -[4568]="160 Parry, 160 Hit", -[4569]="80 Str, 160 Hit", -[4570]="80 Int, 160 PvP Pow", -[4571]="80 Int, 160 Spirit", -[4572]="80 Agi, 120 Stam", -[4573]="120 Stam, 160 Exp", -[4574]="80 Int, 120 Stam", -[4575]="120 Stam, 160 Parry", -[4576]="80 Str, 120 Stam", -[4577]="160 Agi", -[4578]="320 Exp", -[4579]="160 Int", -[4580]="320 Parry", -[4581]="160 Str", -[4582]="320 Crit", -[4583]="320 Dodge", -[4584]="320 Haste", -[4585]="320 Mastery", -[4586]="320 Resil", -[4587]="320 Hit", -[4588]="320 PvP Pow", -[4589]="320 Spirit", -[4590]="240 Stam", -[4591]="160 Spirit, 160 Crit", -[4592]="160 Crit, 160 Hit", -[4593]="160 Haste, 160 Hit", -[4594]="160 Hit, 160 Mastery", -[4595]="160 PvP Pow, 160 Mastery", -[4596]="160 Spirit, 160 Mastery", -[4597]="160 Resil, 160 Hit", -[4598]="160 PvP Pow, 160 Resil", -[4599]="160 Resil, 160 Spirit", -[4600]="160 PvP Pow, 160 Crit", -[4601]="160 PvP Pow, 160 Haste", -[4602]="160 Haste, 160 Spirit", -[4603]="120 Stam, 160 Crit", -[4604]="120 Stam, 160 Dodge", -[4605]="120 Stam, 160 Haste", -[4606]="120 Stam, 160 Hit", -[4607]="120 Stam, 160 Mastery", -[4608]="160 Resil, 120 Stam", -[4609]="80 Agi, 160 Crit", -[4610]="160 Exp, 160 Crit", -[4611]="80 Int, 160 Crit", -[4612]="80 Str, 160 Crit", -[4613]="80 Agi, 160 Dodge", -[4614]="160 Exp, 160 Dodge", -[4615]="160 Parry, 160 Dodge", -[4616]="80 Str, 160 Dodge", -[4617]="80 Agi, 160 Haste", -[4618]="160 Exp, 160 Haste", -[4619]="80 Int, 160 Haste", -[4620]="80 Str, 160 Haste", -[4621]="80 Agi, 160 Mastery", -[4622]="160 Exp, 160 Mastery", -[4623]="80 Int, 160 Mastery", -[4624]="160 Parry, 160 Mastery", -[4625]="80 Str, 160 Mastery", -[4626]="80 Agi, 160 Resil", -[4627]="160 Resil, 160 Exp", -[4628]="80 Int, 160 Resil", -[4629]="160 Resil, 160 Parry", -[4630]="80 Str, 160 Resil", -[4631]="80 Agi, 160 Hit", -[4632]="160 Exp, 160 Hit", -[4633]="80 Int, 160 Hit", -[4634]="160 Parry, 160 Hit", -[4635]="80 Str, 160 Hit", -[4636]="80 Int, 160 PvP Pow", -[4637]="80 Int, 160 Spirit", -[4638]="80 Agi, 120 Stam", -[4640]="80 Int, 120 Stam", -[4641]="120 Stam, 160 Parry", -[4642]="80 Str, 120 Stam", -[4643]="160 Agi", -[4644]="160 Int", -[4645]="320 Parry", -[4646]="160 Str", -[4647]="320 Crit", -[4648]="320 Dodge", -[4649]="320 Haste", -[4650]="320 Mastery", -[4651]="320 Resil", -[4652]="120 Stam, 160 Exp", -[4653]="320 Exp", -[4654]="24 Hit", -[4655]="216 Int", -[4656]="216 Agi", -[4657]="216 Str", -[4658]="216 Int", -[4659]="432 Mastery", -[4660]="432 Spirit", -[4661]="432 Crit", -[4662]="324 Stam", -[4664]="432 Crit", -[4665]="432 Crit", -[4666]="216 Int", -[4667]="324 Stam", -[4668]="432 Dodge", -[4669]="324 Stam", -[4671]="10 Str", -[4672]="25 Resil, 25 Hit", -[4673]="25 PvP Pow, 25 Mastery", -[4674]="25 Agi, 25 Resil", -[4675]="25 Int, 25 PvP Pow", -[4676]="50 Resil", -[4677]="25 PvP Pow, 25 Crit", -[4678]="25 Str, 25 Resil", -[4679]="25 PvP Pow, 25 Haste", -[4680]="25 Resil, 25 Parry", -[4681]="25 Resil, 37 Stam", -[4682]="50 PvP Pow", -[4683]="25 Resil, 25 Exp", -[4684]="25 Resil, 25 Spirit", -[4685]="25 PvP Pow, 25 Resil", -[4686]="25 Int, 25 Resil", -[4687]="160 Agi", -[4688]="Samurai", -[4697]="Use: Increases your dodge by 480 for 10 sec. (1 Min Cooldown)", -[4698]="Use: Launches a cluster of highly explosive fireworks that detonate on impact for 14,000 Fire damage over 3 sec. (45 Sec Cooldown)", -[4699]="Blastington's", -[4700]="Mirror Scope", -[4701]="200 Str", -[4702]="400 Str", -[4717]="Pandamonium", -[4719]="Placeholder Shoulder Enchant", -[4720]="+5 Health", -[4721]="1 Stam", -[4722]="1 Stam", -[4723]="+2 Weapon Damage", -[4724]="1 Agi", -[4725]="1 Agi", -[4726]="3 Spirit", -[4727]="3 Spirit", -[4728]="3 Spirit", -[4729]="3 Int", -[4730]="3 Stam", -[4731]="3 Stam", -[4732]="+5 Fishing", -[4733]="30 Armor", -[4734]="3 Agi", -[4735]="5 Spirit", -[4736]="5 Spirit", -[4737]="5 Stam", -[4738]="5 Stam", -[4739]="5 Str", -[4740]="5 Agi", -[4741]="7 Spirit", -[4742]="7 Str", -[4743]="7 Stam", -[4744]="7 Stam", -[4745]="+3 Weapon Damage", -[4746]="+7 Weapon Damage", -[4747]="16 Agi", -[4748]="16 Agi", -[4750]="Use: Injects a Mythical Healing Potion directly into your bloodstream, increasing potency and healing you for 30,000. (1 Min Cooldown)", -[4753]="1 Str, 1 Agi, 1 Stam, 1 Int, 1 Spirit", -[4755]="3 Str, 3 Agi, 3 Stam, 3 Int, 3 Spirit", -[4757]="5 Str, 5 Agi, 5 Stam, 5 Int, 5 Spirit", -[4759]="7 Str, 7 Agi, 7 Stam, 7 Int, 7 Spirit", -[4760]="9 Str, 9 Agi, 9 Stam, 9 Int, 9 Spirit", -[4761]="3 Str, 3 Agi, 3 Stam, 3 Int, 3 Spirit", -[4762]="5 Str, 5 Agi, 5 Stam, 5 Int, 5 Spirit", -[4803]="200 Str, 100 Crit", -[4804]="200 Agi, 100 Crit", -[4805]="300 Stam, 100 Dodge", -[4806]="200 Int, 100 Crit", -[4807]="160 Str", -[4808]="Magic Weapon", -[4810]="320 Str", -[4811]="320 Int", -[4812]="320 Agi", -[4813]="480 Parry", -[4814]="480 Mastery", -[4815]="480 Exp", -[4816]="480 Haste", -[4817]="480 Hit", -[4818]="480 Crit", -[4819]="480 Dodge", -[4820]="480 Stam", -[4821]="480 Spirit", -[4822]="285 Agi, 165 Crit", -[4823]="285 Str, 165 Crit", -[4824]="430 Stam, 165 Dodge", -[4825]="285 Int, 165 Crit", -[4826]="285 Int, 165 Spirit", -[4827]="60 Agi", -[4828]="120 Agi", -[4829]="180 Agi", -[4830]="60 Str", -[4831]="60 Int", -[4832]="90 Stam", -[4833]="60 Crit", -[4834]="60 Mastery", -[4835]="60 Hit", -[4836]="60 Haste", -[4837]="60 Exp", -[4838]="60 Spirit", -[4839]="60 Dodge", -[4840]="60 Parry", -[4841]="60 PvP Pow", -[4842]="60 Resil", -[4843]="120 Crit", -[4844]="120 Dodge", -[4845]="120 Exp", -[4846]="120 Haste", -[4847]="120 Hit", -[4848]="120 Int", -[4849]="120 Mastery", -[4850]="120 Parry", -[4851]="120 Resil", -[4852]="120 Spirit", -[4853]="120 Str", -[4854]="180 Stam", -[4855]="180 Crit", -[4856]="180 Dodge", -[4857]="180 Exp", -[4858]="180 Haste", -[4859]="180 Hit", -[4860]="180 Int", -[4861]="180 Mastery", -[4862]="180 Parry", -[4863]="180 Resil", -[4864]="120 PvP Pow", -[4865]="180 PvP Pow", -[4866]="180 Spirit", -[4867]="270 Stam", -[4868]="180 Str", -[4869]="150 Stam", -[4870]="250 Stam, 100 Dodge", -[4871]="170 Agi, 100 Crit", -[4872]="170 Str, 100 Crit", -[4873]="57 Agi", -[4874]="57 Str", -[4875]="500 Agi", -[4877]="500 Int", -[4878]="750 Stam", -[4879]="500 Str", -[4880]="285 Agi, 165 Crit", -[4881]="285 Str, 165 Crit", -[4882]="430 Stam, 165 Dodge", -[4883]="95 Agi, 55 Crit", -[4884]="143 Stam, 55 Dodge", -[4885]="95 Str, 55 Crit", -[4886]="37 Agi, 22 Crit", -[4887]="55 Stam, 22 Dodge", -[4888]="37 Str, 22 Crit", -[4891]="Pandaren Fishing Lure", -[4892]="Lightweave 3", -[4893]="Darkglow 3", -[4894]="Swordguard 3", -[4895]="285 Int, 165 Crit", -[4896]="285 Int, 165 Spirit", -[4897]="Use: Reduces your falling speed for 2 min. (3 Min Cooldown)", -[4898]="Use: Increases your Intellect, Agility, or Strength by 1,920 for 10 sec. Your highest stat is always chosen. (1 Min Cooldown)", -[4899]="600 Parry", -[4900]="600 Mastery", -[4901]="600 Exp", -[4902]="600 Haste", -[4903]="600 Hit", -[4904]="600 Crit", -[4905]="600 Spirit", -[4906]="600 Dodge", -[4907]="120 Str, 80 Crit", -[4908]="120 Agi, 80 Crit", -[4909]="120 Int, 80 Crit", -[4910]="180 Stam, 80 Dodge", -[4911]="520 Str, 100 Crit", -[4912]="780 Stam, 100 Dodge", -[4913]="520 Str, 100 Crit", -[4914]="520 Agi, 100 Crit", -[4915]="520 Int, 100 Crit", -[4916]="520 Spirit, 100 Crit", -[4918]="200 Exp", -[4919]="Fishing Lure (+150 Fishing Skill)", -[4920]="+10 Maximum Health", -[4921]="200 Exp, 200 Hit", -[4922]="150 Stam, 200 Parry", -[4923]="100 Str, 200 Hit", -[4924]="100 Agi, 200 Hit", -[4925]="150 Stam, 200 Exp", -[4926]="100 Int, 200 Spirit", -[4927]="200 Parry, 200 Hit", -[4928]="100 Agi, 150 Stam", -[4929]="100 Str, 150 Stam", -[4930]="100 Int, 150 Stam", -[4931]="100 Int, 200 Hit", -[4932]="200 Resil, 200 Hit", -[4933]="200 PvP Pow, 200 Mastery", -[4934]="200 Haste, 200 Spirit", -[4935]="100 Str, 200 Hit", -[4936]="150 Stam, 200 Haste", -[4937]="150 Stam, 200 Crit", -[4938]="200 Haste, 200 Hit", -[4939]="200 Spirit, 200 Crit", -[4940]="150 Stam, 200 Hit", -[4941]="200 Crit, 200 Hit", -[4942]="150 Stam, 200 Mastery", -[4943]="200 PvP Pow, 200 Crit", -[4944]="150 Stam, 200 Dodge", -[4945]="200 Hit, 200 Mastery", -[4946]="200 PvP Pow, 200 Haste", -[4947]="200 Resil, 150 Stam", -[4948]="200 Resil, 200 Spirit", -[4949]="200 PvP Pow, 200 Resil", -[4950]="200 Spirit, 200 Mastery", -[4951]="100 Agi, 200 Mastery", -[4952]="100 Int, 200 Mastery", -[4953]="100 Str, 200 Dodge", -[4954]="200 Exp, 200 Crit", -[4955]="100 Agi, 200 Crit", -[4956]="100 Agi, 200 Haste", -[4957]="100 Str, 200 Haste", -[4958]="200 Parry, 200 Mastery", -[4959]="100 Str, 200 Crit", -[4960]="200 Exp, 200 Mastery", -[4961]="100 Agi, 200 Resil", -[4962]="100 Agi, 200 Dodge", -[4963]="100 Int, 200 Crit", -[4964]="100 Int, 200 Haste", -[4965]="200 Exp, 200 Dodge", -[4966]="100 Str, 200 Resil", -[4967]="100 Str, 200 Mastery", -[4968]="200 Resil, 200 Parry", -[4969]="200 Parry, 200 Dodge", -[4970]="200 Resil, 200 Exp", -[4971]="200 Exp, 200 Haste", -[4972]="100 Int, 200 Resil", -[4973]="100 Int, 200 PvP Pow", -[4984]="80 Str, 160 PvP Pow", -[4985]="60 Str, 120 PvP Pow", -[4986]="80 Str, 160 PvP Pow", -[4987]="100 Str, 200 PvP Pow", -[4988]="60 Agi, 120 PvP Pow", -[4989]="80 Agi, 160 PvP Pow", -[4990]="80 Agi, 160 PvP Pow", -[4991]="100 Agi, 200 PvP Pow", -[4992]="254 Str", -[4993]="170 Parry", -[4994]="Breath of the Agile Prince", -[4996]="500 Agi", -[4997]="500 Str", -[4998]="500 Int", -[5000]="Use: Allows you to walk on water and increases swim speed for up to 6 sec. (30 Sec Cooldown)", -[5001]="Ghost Iron Spike (600-1000)", -[5002]="Socket Belt", -[5003]="170 Int, 100 Crit", -[5004]="170 Int, 100 Spirit", -[5030]="324 Stam", -[5031]="324 Int", -[5032]="324 Crit", -[5033]="324 Crit", -[5034]="665 PvP Pow, 775 Resil", -[5035]="Tyranny", -[5125]="Bloody Dancing Steel"} - -local enchantItemIds = { - [-1000]=90046, - [1099]=44457, - [1597]=44469, - [3222]=38967, - [3246]=38979, - [3260]=34207, - [3845]=44815, - [3850]=44944, - [4061]=52687, - [4062]=52743, - [4063]=52744, - [4064]=52745, - [4065]=52746, - [4066]=52747, - [4067]=45872, - [4068]=52749, - [4069]=52750, - [4070]=52751, - [4071]=52752, - [4072]=52753, - [4073]=52754, - [4075]=52756, - [4076]=52757, - [4077]=52758, - [4082]=52759, - [4083]=52760, - [4084]=52761, - [4085]=52762, - [4086]=52763, - [4087]=52764, - [4088]=52765, - [4089]=52766, - [4090]=52767, - [4091]=52768, - [4092]=52769, - [4093]=52770, - [4094]=52771, - [4095]=52772, - [4096]=52773, - [4097]=52774, - [4098]=52775, - [4099]=52776, - [4100]=52777, - [4101]=52778, - [4102]=52779, - [4103]=52780, - [4104]=52782, - [4105]=52781, - [4106]=52783, - [4107]=52784, - [4108]=52785, - [4109]=54449, - [4110]=54450, - [4111]=54447, - [4112]=54448, - [4122]=56502, - [4124]=56503, - [4126]=56550, - [4127]=56551, - [4175]=59594, - [4176]=59595, - [4177]=59596, - [4197]=62321, - [4198]=62333, - [4199]=62342, - [4200]=62343, - [4201]=62344, - [4202]=62345, - [4204]=62346, - [4205]=62347, - [4217]=55057, - [4227]=68134, - [4248]=68772, - [4249]=68773, - [4250]=68774, - [4256]=68788, - [4257]=68786, - [4258]=68784, - [4267]=70139, - [4270]=71720, - [4411]=74700, - [4412]=74701, - [4414]=74703, - [4415]=74704, - [4416]=74705, - [4417]=74706, - [4418]=74707, - [4419]=74708, - [4420]=74709, - [4421]=74710, - [4422]=74711, - [4423]=74712, - [4424]=74713, - [4426]=74715, - [4427]=74716, - [4428]=74717, - [4429]=74718, - [4430]=74719, - [4431]=74720, - [4432]=74721, - [4433]=74722, - [4434]=74729, - [4441]=74723, - [4442]=74724, - [4443]=74725, - [4444]=74726, - [4445]=74727, - [4446]=74728, - [4699]=77529, - [4700]=77531, - [4803]=83006, - [4804]=83007, - [4805]=87560, - [4806]=87559, - [4822]=83764, - [4823]=83765, - [4824]=83763, - [4825]=82445, - [4826]=82444, - [4869]=85559, - [4870]=85570, - [4871]=85569, - [4872]=85568, - [4907]=87580, - [4908]=87579, - [4909]=87578, - [4910]=87577, - [4912]=87581, - [4913]=87585, - [4914]=87584, - [4915]=87582, - [4918]=86597, - [4993]=89737, - [5003]=82443, - [5004]=82442, - [5035]=95349, - [5125]=98163} - -local enchantSpellIds = { - [-1000]=122632, - [1099]=60663, - [1597]=60763, - [3222]=44529, - [3246]=44592, - [3255]=56039, - [3260]=44770, - [3365]=53323, - [3368]=53344, - [3369]=53341, - [3370]=53343, - [3594]=54446, - [3722]=55642, - [3728]=55769, - [3730]=55776, - [3757]=57690, - [3758]=57691, - [3845]=44575, - [3847]=62158, - [3850]=62256, - [3873]=56034, - [3883]=70164, - [4061]=74132, - [4062]=74189, - [4063]=74191, - [4064]=74192, - [4065]=74193, - [4066]=74195, - [4067]=74197, - [4068]=74198, - [4069]=74199, - [4070]=74200, - [4071]=74201, - [4072]=74202, - [4073]=74207, - [4075]=74212, - [4076]=74213, - [4077]=74214, - [4078]=74215, - [4079]=74216, - [4080]=74217, - [4081]=74218, - [4082]=74220, - [4083]=74223, - [4084]=74225, - [4085]=74226, - [4086]=74229, - [4087]=74230, - [4088]=74231, - [4089]=74232, - [4090]=74234, - [4091]=74235, - [4092]=44488, - [4093]=74237, - [4094]=74238, - [4095]=74239, - [4096]=74240, - [4097]=74242, - [4098]=74244, - [4099]=74246, - [4100]=74247, - [4101]=74248, - [4102]=74250, - [4103]=74251, - [4104]=74253, - [4105]=74252, - [4106]=74254, - [4107]=74255, - [4108]=74256, - [4109]=75255, - [4110]=75310, - [4111]=75250, - [4112]=75309, - [4113]=75154, - [4114]=75155, - [4115]=74172, - [4116]=75175, - [4118]=75177, - [4122]=78419, - [4124]=78420, - [4126]=78477, - [4127]=78478, - [4175]=84428, - [4176]=84408, - [4177]=84410, - [4189]=85007, - [4190]=85008, - [4191]=85009, - [4192]=85010, - [4193]=86375, - [4194]=86401, - [4195]=86402, - [4196]=86403, - [4217]=76442, - [4227]=95741, - [4256]=96261, - [4257]=96262, - [4258]=96264, - [4267]=100587, - [4270]=101599, - [4359]=103461, - [4360]=103462, - [4361]=103463, - [4411]=104338, - [4412]=104385, - [4414]=104389, - [4415]=104390, - [4416]=104391, - [4417]=104392, - [4418]=104393, - [4419]=104395, - [4420]=104397, - [4421]=104398, - [4422]=104401, - [4423]=104403, - [4424]=104404, - [4426]=104407, - [4427]=104408, - [4428]=104409, - [4429]=104414, - [4430]=104416, - [4431]=104417, - [4432]=104419, - [4433]=104420, - [4434]=104445, - [4441]=104425, - [4442]=104427, - [4443]=104430, - [4444]=104434, - [4445]=104440, - [4446]=104442, - [4699]=127115, - [4700]=127116, - [4803]=126997, - [4804]=126996, - [4805]=126994, - [4806]=126995, - [4807]=103465, - [4822]=124129, - [4823]=124127, - [4824]=124128, - [4825]=125555, - [4826]=125554, - [4869]=124628, - [4870]=124125, - [4871]=124124, - [4872]=124126, - [4873]=57683, - [4874]=124549, - [4875]=124551, - [4877]=124552, - [4878]=124553, - [4879]=124554, - [4880]=124559, - [4881]=124561, - [4882]=124563, - [4883]=124564, - [4884]=124565, - [4885]=124566, - [4886]=124567, - [4887]=124568, - [4888]=124569, - [4892]=125481, - [4893]=125482, - [4894]=125489, - [4895]=125496, - [4896]=125497, - [4907]=127016, - [4908]=127017, - [4909]=127018, - [4910]=127019, - [4912]=127024, - [4913]=127020, - [4914]=127021, - [4915]=127023, - [4918]=131929, - [4993]=130758, - [5003]=125553, - [5004]=125552, - [5035]=139631, - [5125]=142468} - -local enchantMaterials = { - [-1000]={[72104]=1}, - [1099]={[34054]=8, [34055]=2, [34052]=2}, - [1597]={[34055]=4, [34052]=4}, - [3222]={[34052]=1, [34055]=4}, - [3246]={[34054]=4, [34056]=1}, - [3255]={[38426]=1}, - [3260]={[23793]=4, [22452]=3}, - [3722]={[38426]=1}, - [3728]={[38426]=1}, - [3730]={[38426]=1}, - [3757]={[38426]=1}, - [3758]={[38426]=1}, - [3845]={[34055]=6, [34054]=24}, - [3850]={[34055]=4, [34057]=1}, - [3873]={[38426]=1}, - [4061]={[52718]=1, [52555]=1}, - [4062]={[52555]=2}, - [4063]={[52718]=2}, - [4064]={[52555]=3}, - [4065]={[52718]=1, [52555]=2}, - [4066]={[52719]=3, [52555]=11}, - [4067]={[52719]=6, [52555]=4}, - [4068]={[52718]=1, [52555]=4}, - [4069]={[52719]=1, [52555]=2}, - [4070]={[52555]=5, [52718]=1}, - [4071]={[52718]=2, [52555]=4}, - [4072]={[52555]=6}, - [4073]={[52719]=1, [52327]=15}, - [4075]={[52719]=2, [52555]=3}, - [4076]={[52719]=2, [52555]=4}, - [4077]={[52555]=9}, - [4078]={[52721]=1}, - [4079]={[52721]=1}, - [4080]={[52721]=1}, - [4081]={[52721]=1}, - [4082]={[52719]=2, [52555]=5}, - [4083]={[52721]=6, [52328]=6}, - [4084]={[52721]=3, [52719]=3, [52555]=9, [52329]=3}, - [4085]={[52555]=12}, - [4086]={[52719]=5, [52328]=1}, - [4087]={[52555]=8, [52719]=2}, - [4088]={[52555]=10, [52719]=2}, - [4089]={[52719]=1, [52555]=12}, - [4090]={[52555]=8, [52719]=3}, - [4091]={[52719]=4, [52555]=6}, - [4092]={[52719]=2, [52555]=2, [58094]=1}, - [4093]={[52719]=3, [52555]=9}, - [4094]={[52719]=3, [52555]=10}, - [4095]={[52719]=6, [52555]=4}, - [4096]={[52555]=9, [52719]=4}, - [4097]={[52722]=4, [52721]=8, [52555]=14}, - [4098]={[52722]=6, [52721]=6, [52719]=4}, - [4099]={[52722]=5, [52721]=5, [52719]=5, [52555]=6}, - [4100]={[52722]=5}, - [4101]={[52722]=1, [52721]=2, [52719]=3, [52555]=15}, - [4102]={[52722]=3, [52721]=3}, - [4103]={[52555]=10, [52721]=4, [52722]=2}, - [4104]={[52722]=1, [52721]=2, [52719]=10}, - [4105]={[52722]=1, [52721]=2, [52719]=7, [52555]=5}, - [4106]={[52722]=2, [52719]=8, [52555]=4}, - [4107]={[52722]=2, [52719]=5, [52555]=10}, - [4108]={[52722]=1, [52721]=2, [52719]=4, [52555]=12}, - [4109]={[53643]=3, [52326]=6}, - [4110]={[54440]=1}, - [4111]={[53643]=3, [52325]=6}, - [4112]={[54440]=1}, - [4113]={[38426]=2}, - [4114]={[38426]=2}, - [4115]={[38426]=2}, - [4116]={[38426]=2}, - [4118]={[38426]=2}, - [4122]={[52976]=6, [52325]=4}, - [4124]={[52976]=6, [52326]=4}, - [4126]={[52979]=20, [52980]=1}, - [4127]={[52980]=1, [52325]=20}, - [4189]={[38426]=1}, - [4190]={[38426]=1}, - [4191]={[38426]=1}, - [4192]={[38426]=1}, - [4217]={[51950]=1}, - [4227]={[52721]=3, [52719]=3, [52555]=3}, - [4256]={[52722]=2, [52555]=6, [52327]=25}, - [4257]={[52722]=2, [52326]=15, [52719]=4, [52555]=4}, - [4258]={[52722]=2, [52555]=12, [52328]=15}, - [4270]={[52980]=1, [52327]=20}, - [4359]={[74249]=2}, - [4360]={[74249]=2}, - [4361]={[74249]=2}, - [4411]={[74249]=4}, - [4412]={[74249]=8, [74250]=2}, - [4414]={[74248]=3}, - [4415]={[74248]=3}, - [4416]={[74248]=3}, - [4417]={[74249]=3, [74250]=1}, - [4418]={[74249]=4}, - [4419]={[74249]=2, [74250]=3}, - [4420]={[74249]=4, [74250]=1}, - [4421]={[74249]=7}, - [4422]={[74247]=2}, - [4423]={[74249]=3, [74250]=3}, - [4424]={[74250]=1}, - [4426]={[74249]=2, [74250]=1}, - [4427]={[74249]=2, [74250]=1}, - [4428]={[74247]=2}, - [4429]={[74249]=4, [74250]=3}, - [4430]={[74249]=4}, - [4431]={[74250]=2}, - [4432]={[74249]=3, [74250]=1, [74247]=1}, - [4433]={[74250]=3}, - [4434]={[74250]=3}, - [4441]={[74249]=12, [74247]=1}, - [4442]={[74250]=4, [74248]=10}, - [4443]={[74250]=3}, - [4444]={[74249]=12, [74248]=10}, - [4445]={[74247]=3}, - [4446]={[74250]=50, [76138]=1}, - [4699]={[72096]=27, [76131]=2, [76061]=1}, - [4700]={[72096]=12, [76133]=2}, - [4803]={[39354]=1, [79255]=3}, - [4804]={[39354]=1, [79255]=3}, - [4805]={[39354]=1, [79255]=3}, - [4806]={[39354]=1, [79255]=3}, - [4807]={[74249]=2}, - [4822]={[72163]=1, [76061]=1}, - [4823]={[72163]=1, [76061]=1}, - [4824]={[72163]=1, [76061]=1}, - [4825]={[82447]=1}, - [4826]={[82447]=1}, - [4869]={[72120]=4}, - [4870]={[79101]=12}, - [4871]={[72120]=12}, - [4872]={[72120]=12}, - [4873]={[38426]=1}, - [4874]={[38426]=1}, - [4875]={[38426]=1}, - [4877]={[38426]=1}, - [4878]={[38426]=1}, - [4879]={[38426]=1}, - [4880]={[38426]=1}, - [4881]={[38426]=1}, - [4882]={[38426]=1}, - [4883]={[38426]=1}, - [4884]={[38426]=1}, - [4885]={[38426]=1}, - [4886]={[38426]=1}, - [4887]={[38426]=1}, - [4888]={[38426]=1}, - [4892]={[38426]=3}, - [4893]={[38426]=3}, - [4894]={[38426]=3}, - [4895]={[38426]=3}, - [4896]={[38426]=3}, - [4907]={[39354]=1, [79254]=3}, - [4908]={[39354]=1, [79254]=3}, - [4909]={[39354]=1, [79254]=3}, - [4910]={[39354]=1, [79254]=3}, - [4912]={[39354]=1, [79254]=3}, - [4913]={[39354]=1, [79254]=3}, - [4914]={[39354]=1, [79254]=3}, - [4915]={[39354]=1, [79254]=3}, - [4918]={[72104]=1}, - [4993]={[74250]=3, [74247]=1}, - [5003]={[72988]=20}, - [5004]={[72988]=20}, - [5035]={[74249]=12, [74248]=10}, - [5125]={[74249]=12, [74248]=10}} - -local enchantIconNames = { -'ability_parry', -'inv_belt_42', -'inv_belt_42c', -'inv_belt_robe_pvpmage_d_01', -'inv_bracer_69', -'inv_enchant_formulagood_01', -'inv_enchant_formulasuperior_01', -'inv_inscription_runescrolloffortitude_blue', -'inv_inscription_runescrolloffortitude_yellow', -'inv_misc_armorkit_08', -'inv_misc_armorkit_26', -'inv_misc_armorkit_28', -'inv_misc_armorkit_29', -'inv_misc_armorkit_mop_00', -'inv_misc_armorkit_mop_01', -'inv_misc_armorkit_mop_02', -'inv_misc_armorkit_mop_04', -'inv_misc_cataclysmarmorkit_01', -'inv_misc_cataclysmarmorkit_02', -'inv_misc_cataclysmarmorkit_08', -'inv_misc_cataclysmarmorkit_10', -'inv_misc_cataclysmarmorkit_11', -'inv_misc_cataclysmarmorkit_12', -'inv_misc_enggizmos_37', -'inv_misc_gem_bloodstone_02', -'inv_misc_gem_crystal_01', -'inv_misc_gem_emeraldrough_02', -'inv_misc_gem_goldendraenite_01', -'inv_misc_mastersinscription', -'inv_misc_monsterscales_14', -'inv_misc_monsterscales_20', -'inv_misc_note_01', -'inv_misc_pelt_10', -'inv_misc_pelt_11', -'inv_misc_pelt_12', -'inv_misc_pelt_13', -'inv_misc_scopea', -'inv_misc_scopeb', -'inv_misc_scopec', -'inv_misc_steelweaponchain', -'inv_misc_thread_01', -'inv_misc_thread_eternium', -'inv_sword_130', -'inv_sword_61', -'item_spellcloththread', -'spell_fire_masterofelements', -'spell_frost_frostarmor', -'spell_holy_greaterheal', -'spell_holy_retributionaura', -'spell_nature_astralrecal', -'spell_nature_astralrecalgroup', -'spell_shadow_chilltouch', -'trade_engraving'} - -local enchantIconIndexes = { -[-1000]=4, -[1099]=48, -[1597]=6, -[3222]=48, -[3246]=48, -[3255]=51, -[3260]=10, -[3365]=1, -[3368]=49, -[3369]=52, -[3370]=47, -[3594]=1, -[3722]=41, -[3728]=41, -[3730]=41, -[3757]=33, -[3758]=34, -[3845]=6, -[3847]=43, -[3850]=7, -[3873]=51, -[3883]=44, -[4061]=48, -[4062]=48, -[4063]=48, -[4064]=48, -[4065]=48, -[4066]=48, -[4067]=48, -[4068]=48, -[4069]=48, -[4070]=48, -[4071]=48, -[4072]=48, -[4073]=48, -[4075]=48, -[4076]=48, -[4077]=48, -[4078]=48, -[4079]=48, -[4080]=48, -[4081]=48, -[4082]=48, -[4083]=48, -[4084]=48, -[4085]=48, -[4086]=48, -[4087]=48, -[4088]=48, -[4089]=48, -[4090]=48, -[4091]=48, -[4092]=48, -[4093]=48, -[4094]=48, -[4095]=48, -[4096]=48, -[4097]=6, -[4098]=6, -[4099]=6, -[4100]=6, -[4101]=6, -[4102]=6, -[4103]=6, -[4104]=6, -[4105]=6, -[4106]=6, -[4107]=6, -[4108]=6, -[4109]=50, -[4110]=51, -[4111]=45, -[4112]=42, -[4113]=51, -[4114]=51, -[4115]=41, -[4116]=41, -[4118]=41, -[4122]=11, -[4124]=13, -[4126]=30, -[4127]=31, -[4175]=37, -[4176]=39, -[4177]=24, -[4189]=33, -[4190]=36, -[4191]=35, -[4192]=34, -[4193]=29, -[4194]=29, -[4195]=29, -[4196]=29, -[4197]=26, -[4198]=26, -[4199]=25, -[4200]=25, -[4201]=27, -[4202]=27, -[4204]=28, -[4205]=28, -[4206]=46, -[4207]=46, -[4208]=46, -[4209]=46, -[4217]=40, -[4227]=48, -[4256]=7, -[4257]=7, -[4258]=7, -[4267]=38, -[4270]=20, -[4359]=32, -[4360]=32, -[4361]=32, -[4411]=32, -[4412]=32, -[4414]=7, -[4415]=7, -[4416]=7, -[4417]=32, -[4418]=32, -[4419]=32, -[4420]=32, -[4421]=32, -[4422]=32, -[4423]=32, -[4424]=32, -[4426]=32, -[4427]=32, -[4428]=32, -[4429]=32, -[4430]=32, -[4431]=32, -[4432]=32, -[4433]=32, -[4434]=32, -[4441]=7, -[4442]=7, -[4443]=7, -[4444]=7, -[4445]=7, -[4446]=7, -[4699]=38, -[4700]=37, -[4803]=9, -[4804]=9, -[4805]=9, -[4806]=9, -[4807]=32, -[4822]=19, -[4823]=17, -[4824]=15, -[4825]=2, -[4826]=3, -[4869]=12, -[4870]=14, -[4871]=18, -[4872]=16, -[4873]=36, -[4874]=35, -[4875]=36, -[4877]=34, -[4878]=33, -[4879]=35, -[4880]=23, -[4881]=22, -[4882]=21, -[4883]=23, -[4884]=21, -[4885]=22, -[4886]=23, -[4887]=21, -[4888]=22, -[4892]=41, -[4893]=41, -[4894]=41, -[4895]=51, -[4896]=51, -[4907]=8, -[4908]=8, -[4909]=8, -[4910]=8, -[4912]=29, -[4913]=29, -[4914]=29, -[4915]=29, -[4918]=40, -[4993]=48, -[5003]=42, -[5004]=5, -[5035]=53, -[5125]=7} --- return 'none', the name of the enchant, or 'unknown (id)' -function AskMrRobot.getEnchantName(enchantId) - if enchantId == 0 then return 'none' end - local enchantName = enchantNames[enchantId] - if not enchantName then return 'unknown (' .. enchantId .. ')' end - return enchantName -end - --- return the spell id, if we have it, otherwise nil -function AskMrRobot.getEnchantSpellId(enchantId) - if not enchantId then return nil end - return enchantSpellIds[enchantId] -end - --- return the item id, if we have it, otherwise nil -function AskMrRobot.getEnchantItemId(enchantId) - if not enchantId then return nil end - return enchantItemIds[enchantId] -end - --- return the enchant icon, if we have it, otherwise nil -function AskMrRobot.getEnchantIcon(enchantId) - if not enchantId then return nil end - local index = enchantIconIndexes[enchantId] - if not index then return nil end - return enchantIconNames[index] -end - --- material list -> itemId -> count -function AskMrRobot.addEnchantMaterials(materialList, enchantId) - local materials = enchantMaterials[enchantId] - if materials then - for materialId, count in pairs(materials) do - local existingCount = materialList[materialId] - if existingCount then - existingCount.total = existingCount.total + count - else - materialList[materialId] = {count = 0, total = count} - end - end - end -end diff -r 9793e8b683d2 -r e77e01abce98 gems.lua --- a/gems.lua Thu Jul 10 15:32:11 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3094 +0,0 @@ -local _, AskMrRobot = ... - -local gemToColor = { -[22459]="Prismatic", -[22460]="Prismatic", -[23094]="Red", -[23095]="Red", -[23096]="Red", -[23097]="Red", -[23098]="Orange", -[23099]="Orange", -[23100]="Purple", -[23101]="Orange", -[23103]="Green", -[23104]="Green", -[23105]="Green", -[23106]="Purple", -[23108]="Purple", -[23109]="Purple", -[23110]="Purple", -[23111]="Purple", -[23113]="Red", -[23114]="Yellow", -[23115]="Yellow", -[23116]="Blue", -[23118]="Blue", -[23119]="Blue", -[23120]="Blue", -[23121]="Blue", -[23233]="Red", -[23234]="Blue", -[23235]="Yellow", -[24027]="Red", -[24028]="Red", -[24029]="Red", -[24030]="Red", -[24031]="Red", -[24032]="Yellow", -[24033]="Blue", -[24035]="Blue", -[24036]="Red", -[24037]="Blue", -[24039]="Blue", -[24047]="Red", -[24048]="Yellow", -[24050]="Yellow", -[24051]="Blue", -[24052]="Yellow", -[24053]="Yellow", -[24054]="Purple", -[24055]="Purple", -[24056]="Purple", -[24057]="Purple", -[24058]="Orange", -[24059]="Orange", -[24060]="Orange", -[24061]="Purple", -[24062]="Green", -[24065]="Purple", -[24066]="Green", -[24067]="Green", -[25890]="Meta", -[25893]="Meta", -[25894]="Meta", -[25895]="Meta", -[25896]="Meta", -[25897]="Meta", -[25898]="Meta", -[25899]="Meta", -[25901]="Meta", -[27679]="Yellow", -[27777]="Red", -[27785]="Green", -[27786]="Green", -[27809]="Green", -[27812]="Red", -[27820]="Green", -[27863]="Blue", -[27864]="Blue", -[28118]="Red", -[28119]="Yellow", -[28120]="Yellow", -[28123]="Orange", -[28290]="Yellow", -[28360]="Red", -[28361]="Red", -[28362]="Red", -[28363]="Orange", -[28458]="Red", -[28459]="Red", -[28460]="Red", -[28461]="Red", -[28462]="Red", -[28463]="Blue", -[28464]="Blue", -[28465]="Blue", -[28466]="Red", -[28467]="Yellow", -[28468]="Blue", -[28469]="Yellow", -[28470]="Yellow", -[28556]="Meta", -[28557]="Meta", -[28595]="Red", -[30546]="Purple", -[30547]="Orange", -[30548]="Green", -[30549]="Purple", -[30550]="Green", -[30551]="Orange", -[30552]="Purple", -[30553]="Purple", -[30554]="Orange", -[30555]="Purple", -[30556]="Purple", -[30558]="Orange", -[30559]="Purple", -[30560]="Green", -[30563]="Green", -[30564]="Purple", -[30565]="Green", -[30566]="Purple", -[30571]="Red", -[30572]="Purple", -[30573]="Purple", -[30574]="Purple", -[30575]="Green", -[30581]="Orange", -[30582]="Orange", -[30583]="Purple", -[30584]="Orange", -[30585]="Orange", -[30586]="Purple", -[30587]="Orange", -[30588]="Orange", -[30589]="Purple", -[30590]="Green", -[30591]="Orange", -[30592]="Green", -[30593]="Orange", -[30594]="Green", -[30598]="Red", -[30600]="Purple", -[30601]="Green", -[30602]="Green", -[30603]="Purple", -[30604]="Orange", -[30605]="Green", -[30606]="Green", -[30607]="Orange", -[30608]="Green", -[31116]="Purple", -[31117]="Purple", -[31118]="Purple", -[31860]="Blue", -[31861]="Blue", -[31862]="Purple", -[31863]="Purple", -[31864]="Purple", -[31865]="Purple", -[31866]="Purple", -[31867]="Purple", -[31868]="Orange", -[31869]="Orange", -[32193]="Red", -[32194]="Red", -[32195]="Red", -[32196]="Red", -[32197]="Red", -[32198]="Yellow", -[32199]="Red", -[32200]="Blue", -[32201]="Blue", -[32202]="Blue", -[32203]="Blue", -[32204]="Red", -[32205]="Yellow", -[32206]="Blue", -[32207]="Yellow", -[32208]="Yellow", -[32209]="Yellow", -[32210]="Blue", -[32211]="Purple", -[32212]="Purple", -[32213]="Purple", -[32214]="Purple", -[32215]="Purple", -[32216]="Purple", -[32217]="Orange", -[32218]="Orange", -[32219]="Orange", -[32220]="Purple", -[32221]="Purple", -[32222]="Orange", -[32223]="Green", -[32224]="Green", -[32225]="Purple", -[32226]="Green", -[32409]="Meta", -[32410]="Meta", -[32634]="Purple", -[32635]="Purple", -[32636]="Purple", -[32637]="Orange", -[32638]="Orange", -[32639]="Green", -[32640]="Meta", -[32641]="Meta", -[32735]="Red", -[32833]="Purple", -[32836]="Purple", -[33060]="Yellow", -[33131]="Red", -[33132]="Red", -[33133]="Red", -[33134]="Red", -[33135]="Blue", -[33137]="Blue", -[33138]="Yellow", -[33139]="Red", -[33140]="Yellow", -[33141]="Blue", -[33142]="Yellow", -[33143]="Yellow", -[33144]="Yellow", -[33782]="Green", -[34220]="Meta", -[34256]="Blue", -[34831]="Blue", -[34967]="Yellow", -[35315]="Yellow", -[35316]="Orange", -[35318]="Green", -[35487]="Red", -[35488]="Red", -[35489]="Red", -[35501]="Meta", -[35503]="Meta", -[35707]="Green", -[35758]="Green", -[35759]="Green", -[35760]="Orange", -[35761]="Yellow", -[36766]="Red", -[36767]="Blue", -[37430]="Blue", -[37503]="Purple", -[38292]="Red", -[38545]="Red", -[38546]="Yellow", -[38547]="Orange", -[38548]="Orange", -[38549]="Red", -[38550]="Yellow", -[39900]="Red", -[39905]="Red", -[39906]="Red", -[39907]="Yellow", -[39908]="Red", -[39909]="Yellow", -[39910]="Red", -[39911]="Red", -[39912]="Red", -[39914]="Yellow", -[39915]="Blue", -[39916]="Yellow", -[39917]="Yellow", -[39918]="Yellow", -[39919]="Blue", -[39920]="Blue", -[39927]="Blue", -[39932]="Blue", -[39933]="Green", -[39934]="Purple", -[39935]="Purple", -[39936]="Purple", -[39937]="Purple", -[39938]="Green", -[39939]="Purple", -[39940]="Purple", -[39941]="Purple", -[39942]="Purple", -[39943]="Purple", -[39944]="Purple", -[39945]="Purple", -[39946]="Orange", -[39947]="Orange", -[39948]="Purple", -[39949]="Orange", -[39950]="Orange", -[39951]="Orange", -[39952]="Orange", -[39953]="Purple", -[39954]="Orange", -[39955]="Orange", -[39956]="Orange", -[39957]="Purple", -[39958]="Orange", -[39959]="Orange", -[39960]="Orange", -[39961]="Purple", -[39962]="Orange", -[39963]="Orange", -[39964]="Orange", -[39965]="Orange", -[39966]="Purple", -[39967]="Orange", -[39968]="Purple", -[39974]="Green", -[39975]="Green", -[39976]="Green", -[39977]="Green", -[39978]="Green", -[39979]="Purple", -[39980]="Green", -[39981]="Green", -[39982]="Green", -[39983]="Green", -[39984]="Purple", -[39985]="Green", -[39986]="Green", -[39988]="Green", -[39989]="Green", -[39990]="Green", -[39991]="Green", -[39992]="Green", -[39996]="Red", -[39997]="Red", -[39998]="Red", -[39999]="Red", -[40000]="Yellow", -[40001]="Red", -[40002]="Yellow", -[40003]="Red", -[40008]="Blue", -[40009]="Blue", -[40010]="Blue", -[40011]="Blue", -[40012]="Red", -[40013]="Yellow", -[40014]="Blue", -[40015]="Yellow", -[40016]="Yellow", -[40017]="Yellow", -[40022]="Purple", -[40023]="Purple", -[40024]="Purple", -[40025]="Purple", -[40026]="Purple", -[40027]="Purple", -[40028]="Purple", -[40029]="Purple", -[40030]="Purple", -[40031]="Green", -[40032]="Purple", -[40033]="Green", -[40034]="Purple", -[40037]="Orange", -[40038]="Purple", -[40039]="Orange", -[40040]="Orange", -[40041]="Orange", -[40043]="Orange", -[40044]="Purple", -[40045]="Orange", -[40046]="Orange", -[40047]="Orange", -[40048]="Orange", -[40049]="Purple", -[40050]="Orange", -[40051]="Orange", -[40052]="Orange", -[40053]="Purple", -[40054]="Orange", -[40055]="Orange", -[40056]="Orange", -[40057]="Orange", -[40058]="Purple", -[40059]="Orange", -[40085]="Purple", -[40086]="Green", -[40088]="Green", -[40089]="Green", -[40090]="Green", -[40091]="Green", -[40092]="Purple", -[40094]="Purple", -[40095]="Green", -[40096]="Green", -[40098]="Green", -[40099]="Green", -[40100]="Green", -[40101]="Green", -[40102]="Green", -[40103]="Green", -[40104]="Green", -[40105]="Green", -[40106]="Green", -[40111]="Red", -[40112]="Red", -[40113]="Red", -[40114]="Red", -[40115]="Yellow", -[40116]="Red", -[40117]="Yellow", -[40118]="Red", -[40119]="Blue", -[40120]="Blue", -[40121]="Blue", -[40122]="Blue", -[40123]="Red", -[40124]="Yellow", -[40125]="Blue", -[40126]="Yellow", -[40127]="Yellow", -[40128]="Yellow", -[40129]="Purple", -[40130]="Purple", -[40131]="Purple", -[40132]="Purple", -[40133]="Purple", -[40134]="Purple", -[40135]="Purple", -[40136]="Purple", -[40137]="Purple", -[40138]="Green", -[40139]="Purple", -[40140]="Green", -[40141]="Purple", -[40142]="Orange", -[40143]="Purple", -[40144]="Orange", -[40145]="Orange", -[40146]="Orange", -[40147]="Orange", -[40148]="Purple", -[40149]="Orange", -[40150]="Orange", -[40151]="Purple", -[40152]="Orange", -[40153]="Purple", -[40154]="Orange", -[40155]="Orange", -[40156]="Orange", -[40157]="Purple", -[40158]="Orange", -[40159]="Orange", -[40160]="Orange", -[40161]="Orange", -[40162]="Purple", -[40163]="Orange", -[40164]="Purple", -[40165]="Green", -[40166]="Green", -[40167]="Green", -[40168]="Green", -[40169]="Green", -[40170]="Purple", -[40171]="Green", -[40172]="Green", -[40173]="Green", -[40174]="Green", -[40175]="Purple", -[40176]="Green", -[40177]="Green", -[40178]="Green", -[40179]="Green", -[40180]="Green", -[40181]="Green", -[40182]="Green", -[41285]="Meta", -[41307]="Meta", -[41333]="Meta", -[41335]="Meta", -[41339]="Meta", -[41375]="Meta", -[41376]="Meta", -[41377]="Meta", -[41378]="Meta", -[41379]="Meta", -[41380]="Meta", -[41381]="Meta", -[41382]="Meta", -[41385]="Meta", -[41389]="Meta", -[41395]="Meta", -[41396]="Meta", -[41397]="Meta", -[41398]="Meta", -[41400]="Meta", -[41401]="Meta", -[41429]="Orange", -[41432]="Red", -[41433]="Red", -[41434]="Red", -[41435]="Red", -[41436]="Yellow", -[41437]="Red", -[41438]="Red", -[41439]="Yellow", -[41440]="Blue", -[41441]="Blue", -[41442]="Blue", -[41443]="Blue", -[41444]="Red", -[41445]="Yellow", -[41446]="Yellow", -[41447]="Blue", -[41448]="Yellow", -[41449]="Yellow", -[41450]="Purple", -[41451]="Purple", -[41452]="Purple", -[41453]="Purple", -[41454]="Purple", -[41455]="Purple", -[41456]="Green", -[41457]="Purple", -[41458]="Green", -[41459]="Purple", -[41460]="Purple", -[41461]="Purple", -[41462]="Purple", -[41463]="Purple", -[41464]="Green", -[41465]="Green", -[41466]="Green", -[41467]="Green", -[41468]="Green", -[41469]="Green", -[41470]="Green", -[41471]="Green", -[41472]="Green", -[41473]="Purple", -[41474]="Green", -[41475]="Green", -[41476]="Green", -[41477]="Green", -[41478]="Green", -[41479]="Purple", -[41480]="Green", -[41481]="Green", -[41482]="Purple", -[41483]="Orange", -[41484]="Orange", -[41485]="Orange", -[41486]="Orange", -[41487]="Orange", -[41488]="Purple", -[41489]="Orange", -[41490]="Orange", -[41491]="Purple", -[41492]="Orange", -[41493]="Orange", -[41494]="Purple", -[41495]="Orange", -[41496]="Purple", -[41497]="Orange", -[41498]="Orange", -[41499]="Orange", -[41500]="Orange", -[41501]="Orange", -[41502]="Purple", -[42142]="Red", -[42143]="Red", -[42144]="Red", -[42145]="Blue", -[42146]="Blue", -[42148]="Red", -[42149]="Yellow", -[42150]="Yellow", -[42151]="Yellow", -[42152]="Red", -[42153]="Yellow", -[42154]="Red", -[42155]="Blue", -[42156]="Blue", -[42157]="Yellow", -[42158]="Yellow", -[42701]="Prismatic", -[42702]="Prismatic", -[44066]="Yellow", -[44076]="Meta", -[44078]="Meta", -[44081]="Meta", -[44082]="Meta", -[44084]="Meta", -[44087]="Meta", -[44088]="Meta", -[44089]="Meta", -[45862]="Red", -[45879]="Red", -[45880]="Blue", -[45881]="Blue", -[45882]="Red", -[45883]="Red", -[45987]="Blue", -[49110]="Prismatic", -[52070]="Purple", -[52081]="Red", -[52082]="Red", -[52083]="Red", -[52084]="Red", -[52085]="Red", -[52086]="Blue", -[52087]="Blue", -[52088]="Blue", -[52089]="Blue", -[52090]="Yellow", -[52091]="Yellow", -[52092]="Yellow", -[52093]="Yellow", -[52094]="Yellow", -[52095]="Purple", -[52096]="Purple", -[52097]="Purple", -[52098]="Purple", -[52099]="Purple", -[52100]="Purple", -[52101]="Purple", -[52102]="Purple", -[52103]="Purple", -[52104]="Purple", -[52105]="Purple", -[52106]="Orange", -[52107]="Orange", -[52108]="Orange", -[52109]="Orange", -[52110]="Orange", -[52111]="Orange", -[52112]="Orange", -[52113]="Orange", -[52114]="Orange", -[52115]="Orange", -[52116]="Orange", -[52117]="Orange", -[52118]="Orange", -[52119]="Green", -[52120]="Green", -[52121]="Green", -[52122]="Green", -[52123]="Green", -[52124]="Green", -[52125]="Green", -[52126]="Green", -[52127]="Green", -[52128]="Green", -[52129]="Green", -[52130]="Green", -[52131]="Green", -[52132]="Green", -[52133]="Green", -[52134]="Green", -[52135]="Green", -[52136]="Green", -[52137]="Green", -[52138]="Green", -[52139]="Orange", -[52140]="Orange", -[52141]="Orange", -[52142]="Orange", -[52143]="Orange", -[52144]="Orange", -[52145]="Orange", -[52146]="Orange", -[52147]="Orange", -[52148]="Orange", -[52149]="Orange", -[52150]="Orange", -[52151]="Orange", -[52152]="Purple", -[52153]="Purple", -[52154]="Purple", -[52155]="Purple", -[52156]="Purple", -[52157]="Purple", -[52158]="Purple", -[52159]="Purple", -[52160]="Purple", -[52161]="Purple", -[52162]="Purple", -[52163]="Yellow", -[52164]="Yellow", -[52165]="Yellow", -[52166]="Yellow", -[52167]="Yellow", -[52168]="Blue", -[52169]="Blue", -[52170]="Blue", -[52171]="Blue", -[52172]="Red", -[52173]="Red", -[52174]="Red", -[52175]="Red", -[52176]="Red", -[52203]="Purple", -[52204]="Orange", -[52205]="Orange", -[52206]="Red", -[52207]="Red", -[52208]="Orange", -[52209]="Orange", -[52210]="Purple", -[52211]="Orange", -[52212]="Red", -[52213]="Purple", -[52214]="Orange", -[52215]="Orange", -[52216]="Red", -[52217]="Purple", -[52218]="Green", -[52219]="Yellow", -[52220]="Purple", -[52221]="Purple", -[52222]="Orange", -[52223]="Green", -[52224]="Orange", -[52225]="Green", -[52226]="Yellow", -[52227]="Green", -[52228]="Green", -[52229]="Orange", -[52230]="Red", -[52231]="Green", -[52232]="Yellow", -[52233]="Green", -[52234]="Purple", -[52235]="Blue", -[52236]="Purple", -[52237]="Green", -[52238]="Purple", -[52239]="Orange", -[52240]="Orange", -[52241]="Yellow", -[52242]="Blue", -[52243]="Purple", -[52244]="Blue", -[52245]="Green", -[52246]="Blue", -[52247]="Yellow", -[52248]="Purple", -[52249]="Orange", -[52250]="Green", -[52255]="Red", -[52257]="Red", -[52258]="Red", -[52259]="Red", -[52260]="Red", -[52261]="Blue", -[52262]="Blue", -[52263]="Blue", -[52264]="Blue", -[52265]="Yellow", -[52266]="Yellow", -[52267]="Yellow", -[52268]="Yellow", -[52269]="Yellow", -[52289]="Meta", -[52291]="Meta", -[52292]="Meta", -[52293]="Meta", -[52294]="Meta", -[52295]="Meta", -[52296]="Meta", -[52297]="Meta", -[52298]="Meta", -[52299]="Meta", -[52300]="Meta", -[52301]="Meta", -[52302]="Meta", -[54616]="Red", -[59477]="Cogwheel", -[59478]="Cogwheel", -[59479]="Cogwheel", -[59480]="Cogwheel", -[59489]="Cogwheel", -[59491]="Cogwheel", -[59493]="Cogwheel", -[59496]="Cogwheel", -[63696]="Red", -[63697]="Red", -[68356]="Orange", -[68357]="Orange", -[68358]="Orange", -[68660]="Cogwheel", -[68741]="Green", -[68778]="Meta", -[68779]="Meta", -[68780]="Meta", -[69922]="Red", -[69923]="Red", -[71817]="Blue", -[71818]="Blue", -[71819]="Blue", -[71820]="Blue", -[71822]="Green", -[71823]="Green", -[71824]="Green", -[71825]="Green", -[71826]="Green", -[71827]="Green", -[71828]="Green", -[71829]="Green", -[71830]="Green", -[71831]="Green", -[71832]="Green", -[71833]="Green", -[71834]="Green", -[71835]="Green", -[71836]="Green", -[71837]="Green", -[71838]="Green", -[71839]="Green", -[71840]="Orange", -[71841]="Orange", -[71842]="Orange", -[71843]="Orange", -[71844]="Orange", -[71845]="Orange", -[71846]="Orange", -[71847]="Orange", -[71848]="Orange", -[71849]="Orange", -[71850]="Orange", -[71851]="Orange", -[71852]="Orange", -[71853]="Orange", -[71854]="Orange", -[71855]="Orange", -[71856]="Orange", -[71857]="Orange", -[71858]="Orange", -[71859]="Orange", -[71860]="Orange", -[71861]="Orange", -[71862]="Purple", -[71863]="Purple", -[71864]="Purple", -[71865]="Purple", -[71866]="Purple", -[71867]="Purple", -[71868]="Purple", -[71869]="Purple", -[71870]="Purple", -[71871]="Purple", -[71872]="Purple", -[71873]="Purple", -[71874]="Yellow", -[71875]="Yellow", -[71876]="Yellow", -[71877]="Yellow", -[71878]="Yellow", -[71879]="Red", -[71880]="Red", -[71881]="Red", -[71882]="Red", -[71883]="Red", -[76502]="Blue", -[76504]="Blue", -[76505]="Blue", -[76506]="Blue", -[76507]="Green", -[76508]="Green", -[76509]="Green", -[76510]="Green", -[76511]="Green", -[76512]="Green", -[76513]="Green", -[76514]="Green", -[76515]="Green", -[76517]="Green", -[76518]="Green", -[76519]="Green", -[76520]="Green", -[76521]="Green", -[76522]="Green", -[76523]="Green", -[76524]="Green", -[76525]="Green", -[76526]="Orange", -[76527]="Orange", -[76528]="Orange", -[76529]="Orange", -[76530]="Orange", -[76531]="Orange", -[76532]="Orange", -[76533]="Orange", -[76534]="Orange", -[76535]="Orange", -[76536]="Orange", -[76537]="Orange", -[76538]="Orange", -[76539]="Orange", -[76540]="Orange", -[76541]="Orange", -[76542]="Orange", -[76543]="Orange", -[76544]="Orange", -[76545]="Orange", -[76546]="Orange", -[76547]="Orange", -[76548]="Purple", -[76549]="Purple", -[76550]="Purple", -[76551]="Purple", -[76552]="Purple", -[76553]="Purple", -[76554]="Purple", -[76555]="Purple", -[76556]="Purple", -[76557]="Purple", -[76558]="Purple", -[76559]="Purple", -[76560]="Red", -[76561]="Red", -[76562]="Red", -[76563]="Red", -[76564]="Red", -[76565]="Yellow", -[76566]="Yellow", -[76567]="Yellow", -[76568]="Yellow", -[76569]="Yellow", -[76570]="Blue", -[76571]="Blue", -[76572]="Blue", -[76573]="Blue", -[76574]="Green", -[76575]="Green", -[76576]="Green", -[76577]="Green", -[76578]="Green", -[76579]="Green", -[76580]="Green", -[76581]="Green", -[76582]="Green", -[76583]="Green", -[76584]="Green", -[76585]="Green", -[76586]="Green", -[76587]="Green", -[76588]="Green", -[76589]="Green", -[76590]="Green", -[76591]="Green", -[76592]="Orange", -[76593]="Orange", -[76594]="Orange", -[76595]="Orange", -[76596]="Orange", -[76597]="Orange", -[76598]="Orange", -[76599]="Orange", -[76600]="Orange", -[76601]="Orange", -[76602]="Orange", -[76603]="Orange", -[76604]="Orange", -[76605]="Orange", -[76606]="Orange", -[76607]="Orange", -[76608]="Orange", -[76609]="Orange", -[76610]="Orange", -[76611]="Orange", -[76612]="Orange", -[76613]="Orange", -[76614]="Purple", -[76615]="Purple", -[76616]="Purple", -[76617]="Purple", -[76618]="Purple", -[76619]="Purple", -[76620]="Purple", -[76621]="Purple", -[76622]="Purple", -[76623]="Purple", -[76624]="Purple", -[76625]="Purple", -[76626]="Red", -[76627]="Red", -[76628]="Red", -[76629]="Red", -[76630]="Red", -[76631]="Yellow", -[76632]="Yellow", -[76633]="Yellow", -[76634]="Yellow", -[76635]="Yellow", -[76636]="Blue", -[76637]="Blue", -[76638]="Blue", -[76639]="Blue", -[76640]="Green", -[76641]="Green", -[76642]="Green", -[76643]="Green", -[76644]="Green", -[76645]="Green", -[76646]="Green", -[76647]="Green", -[76648]="Green", -[76649]="Green", -[76650]="Green", -[76651]="Green", -[76652]="Green", -[76653]="Green", -[76654]="Green", -[76655]="Green", -[76656]="Green", -[76657]="Green", -[76658]="Orange", -[76659]="Orange", -[76660]="Orange", -[76661]="Orange", -[76662]="Orange", -[76663]="Orange", -[76664]="Orange", -[76665]="Orange", -[76666]="Orange", -[76667]="Orange", -[76668]="Orange", -[76669]="Orange", -[76670]="Orange", -[76671]="Orange", -[76672]="Orange", -[76673]="Orange", -[76674]="Orange", -[76675]="Orange", -[76676]="Orange", -[76677]="Orange", -[76678]="Orange", -[76679]="Orange", -[76680]="Purple", -[76681]="Purple", -[76682]="Purple", -[76683]="Purple", -[76684]="Purple", -[76685]="Purple", -[76686]="Purple", -[76687]="Purple", -[76688]="Purple", -[76689]="Purple", -[76690]="Purple", -[76691]="Purple", -[76692]="Red", -[76693]="Red", -[76694]="Red", -[76695]="Red", -[76696]="Red", -[76697]="Yellow", -[76698]="Yellow", -[76699]="Yellow", -[76700]="Yellow", -[76701]="Yellow", -[76879]="Meta", -[76884]="Meta", -[76885]="Meta", -[76886]="Meta", -[76887]="Meta", -[76888]="Meta", -[76890]="Meta", -[76891]="Meta", -[76892]="Meta", -[76893]="Meta", -[76894]="Meta", -[76895]="Meta", -[76896]="Meta", -[76897]="Meta", -[77130]="Green", -[77131]="Green", -[77132]="Orange", -[77133]="Purple", -[77134]="Yellow", -[77136]="Orange", -[77137]="Green", -[77138]="Orange", -[77139]="Green", -[77140]="Blue", -[77141]="Orange", -[77142]="Green", -[77143]="Green", -[77144]="Orange", -[77154]="Green", -[77540]="Cogwheel", -[77541]="Cogwheel", -[77542]="Cogwheel", -[77543]="Cogwheel", -[77544]="Cogwheel", -[77545]="Cogwheel", -[77546]="Cogwheel", -[77547]="Cogwheel", -[83141]="Red", -[83142]="Yellow", -[83143]="Yellow", -[83144]="Blue", -[83145]="Yellow", -[83146]="Yellow", -[83147]="Red", -[83148]="Blue", -[83149]="Blue", -[83150]="Red", -[83151]="Red", -[83152]="Red", -[88911]="Green", -[88912]="Green", -[88913]="Green", -[88914]="Green", -[88915]="Green", -[88916]="Green", -[88917]="Green", -[88918]="Green", -[88919]="Green", -[88920]="Green", -[88921]="Green", -[88922]="Green", -[88923]="Green", -[88924]="Green", -[88925]="Green", -[88926]="Green", -[88927]="Green", -[88928]="Green", -[88930]="Orange", -[88931]="Orange", -[88932]="Orange", -[88933]="Orange", -[88934]="Orange", -[88935]="Orange", -[88936]="Orange", -[88937]="Orange", -[88938]="Orange", -[88939]="Orange", -[88940]="Orange", -[88941]="Orange", -[88942]="Orange", -[88943]="Orange", -[88944]="Orange", -[88945]="Orange", -[88946]="Orange", -[88947]="Orange", -[88948]="Orange", -[88949]="Orange", -[88950]="Orange", -[88951]="Orange", -[88952]="Purple", -[88953]="Purple", -[88954]="Purple", -[88955]="Purple", -[88956]="Purple", -[88958]="Purple", -[88959]="Purple", -[88960]="Purple", -[88961]="Purple", -[88962]="Purple", -[88963]="Purple", -[88987]="Purple", -[89674]="Purple", -[89675]="Purple", -[89676]="Purple", -[89677]="Purple", -[89678]="Purple", -[89679]="Purple", -[89680]="Purple", -[89681]="Purple", -[89873]="Hydraulic", -[89881]="Hydraulic", -[89882]="Hydraulic", -[93364]="Hydraulic", -[93365]="Hydraulic", -[93366]="Hydraulic", -[93404]="Orange", -[93405]="Orange", -[93406]="Orange", -[93408]="Purple", -[93409]="Purple", -[93410]="Purple", -[93705]="Green", -[93706]="Green", -[93707]="Green", -[93708]="Green", -[95344]="Meta", -[95345]="Meta", -[95346]="Meta", -[95347]="Meta", -[95348]="Meta"} - -AskMrRobot.alternateGemName = { -[23094]="6 Int", -[23095]="6 Str", -[23096]="7 Int", -[23097]="6 Agi", -[23098]="3 Str, 6 Crit", -[23099]="3 Int, 6 Haste", -[23100]="3 Agi, 6 Hit", -[23101]="6 Int, 3 Crit", -[23103]="3 PvP Pow, 6 Crit", -[23104]="4 Stam, 6 Crit", -[23105]="4 Stam, 6 Dodge", -[23106]="3 Int, 6 Spirit", -[23108]="3 Int, 4 Stam", -[23109]="3 Int, 6 Spirit", -[23110]="3 Agi, 4 Stam", -[23111]="3 Str, 4 Stam", -[23113]="6 Int", -[23114]="12 Crit", -[23115]="12 Dodge", -[23116]="12 Hit", -[23118]="9 Stam", -[23119]="12 Spirit", -[23120]="6 PvP Pow", -[23121]="12 Spirit", -[23233]="8 Str", -[23234]="8 Agi", -[23235]="8 Stam", -[24027]="8 Str", -[24028]="8 Agi", -[24029]="8 Int", -[24030]="8 Int", -[24031]="8 Agi", -[24032]="16 Dodge", -[24033]="12 Stam", -[24035]="16 Spirit", -[24036]="16 Parry", -[24037]="16 Spirit", -[24039]="8 PvP Pow", -[24047]="8 Int", -[24048]="16 Crit", -[24050]="16 Crit", -[24051]="16 Hit", -[24052]="16 Dodge", -[24053]="8 Resil", -[24054]="4 Str, 6 Stam", -[24055]="4 Agi, 6 Stam", -[24056]="5 Int, 6 Stam", -[24057]="4 Int, 8 Spirit", -[24058]="8 Str, 4 Crit", -[24059]="4 Int, 8 Crit", -[24060]="4 Int, 8 Haste", -[24061]="4 Agi, 8 Hit", -[24062]="6 Stam, 8 Dodge", -[24065]="4 Int, 8 Spirit", -[24066]="4 PvP Pow, 8 Crit", -[24067]="6 Stam, 8 Crit", -[25890]="28 Crit, 1% Reflect", -[25894]="24 Crit", -[25895]="24 Crit, Snare", -[25896]="18 Stam, Stun", -[25897]="12 Int, 2% Threat", -[25898]="24 Dodge", -[25901]="12 Int", -[27679]="10 Resil", -[27777]="7 Int", -[27785]="3 Stam, 4 Crit", -[27786]="3 Stam, 4 Crit", -[27809]="3 Stam, 4 Crit", -[27812]="7 Int", -[27820]="3 Stam, 4 Crit", -[28118]="10 Int", -[28119]="10 Crit", -[28120]="10 Crit", -[28123]="5 Int, 5 Crit", -[28290]="12 Crit", -[28360]="7 Agi", -[28361]="7 Agi", -[28362]="10 Agi", -[28363]="5 Agi, 5 Crit", -[28458]="4 Str", -[28459]="4 Agi", -[28460]="4 Int", -[28461]="4 Int", -[28462]="4 Agi", -[28463]="6 Stam", -[28464]="8 Spirit", -[28465]="8 Spirit", -[28466]="4 Int", -[28467]="8 Crit", -[28468]="8 Hit", -[28469]="8 Crit", -[28470]="8 Dodge", -[28556]="10 Crit", -[28557]="10 Int", -[28595]="6 Agi", -[30546]="5 Str, 6 Stam", -[30547]="5 Int, 4 Haste", -[30548]="6 Stam, 10 Crit", -[30549]="5 Agi, 6 Stam", -[30550]="10 Crit, 8 Spirit", -[30551]="5 Int, 4 Haste", -[30552]="5 Int, 6 Stam", -[30553]="5 Agi, 4 Hit", -[30554]="5 Parry, 4 Dodge", -[30555]="5 Int, 6 Stam", -[30556]="5 Agi, 4 Hit", -[30558]="5 Parry, 4 Dodge", -[30559]="5 Str, 4 Hit", -[30560]="5 Crit, 4 Spirit", -[30563]="6 Stam, 5 Dodge", -[30564]="5 Int, 4 Hit", -[30565]="6 Stam, 5 Crit", -[30566]="6 Stam, 5 Parry", -[30571]="8 Str", -[30572]="5 Int, 10 Spirit", -[30573]="5 Int, 5 PvP Pow", -[30574]="5 Agi, 6 Stam", -[30575]="5 Dodge, 4 Hit", -[30581]="5 Int, 4 Resil", -[30582]="5 Agi, 4 Crit", -[30583]="5 Int, 6 Stam", -[30584]="5 Str, 4 Crit", -[30585]="4 Agi, 5 Dodge", -[30586]="5 Int, 4 Spirit", -[30587]="5 Str, 4 Dodge", -[30588]="5 Int, 4 Crit", -[30589]="5 Int, 4 Spirit", -[30590]="6 Stam, 5 Dodge", -[30591]="5 Agi, 4 Resil", -[30592]="6 Stam, 5 Resil", -[30593]="5 Int, 4 Crit", -[30594]="6 Stam, 5 Dodge", -[30598]="8 Str", -[30600]="5 Int, 4 Spirit", -[30601]="5 Resil, 6 Stam", -[30602]="6 Stam, 5 Crit", -[30603]="5 Int, 8 Spirit", -[30604]="5 Str, 4 Resil", -[30605]="10 Hit, 8 Dodge", -[30606]="10 Hit, 8 Haste", -[30607]="4 Resil, 5 Parry", -[30608]="5 PvP Pow, 5 Crit", -[31116]="5 Int, 6 Stam", -[31117]="5 Int, 6 Stam", -[31118]="5 Str, 6 Stam", -[31860]="12 Hit", -[31861]="16 Hit", -[31862]="3 Agi, 4 Stam", -[31863]="4 Agi, 6 Stam", -[31864]="3 Agi, 4 Stam", -[31865]="4 Agi, 8 Hit", -[31866]="3 Int, 6 Hit", -[31867]="4 Int, 8 Hit", -[31868]="4 Agi, 8 Crit", -[31869]="6 Agi, 3 Crit", -[32193]="10 Str", -[32194]="10 Agi", -[32195]="10 Int", -[32196]="10 Int", -[32197]="20 Agi", -[32198]="20 Dodge", -[32199]="20 Parry", -[32200]="15 Stam", -[32201]="20 Spirit", -[32202]="20 Spirit", -[32203]="10 PvP Pow", -[32204]="10 Int", -[32205]="20 Crit", -[32206]="20 Hit", -[32207]="20 Crit", -[32208]="20 Dodge", -[32209]="10 Resil", -[32210]="20 Hit", -[32211]="5 Str, 7 Stam", -[32212]="5 Agi, 7 Stam", -[32213]="5 Agi, 7 Stam", -[32214]="5 Agi, 10 Hit", -[32215]="5 Int, 7 Stam", -[32216]="5 Int, 10 Spirit", -[32217]="5 Str, 10 Crit", -[32218]="5 Int, 10 Crit", -[32219]="5 Int, 10 Haste", -[32220]="5 Agi, 10 Hit", -[32221]="5 Int, 10 Hit", -[32222]="5 Agi, 10 Crit", -[32223]="7 Stam, 10 Dodge", -[32224]="5 PvP Pow, 10 Crit", -[32225]="5 Int, 10 Spirit", -[32226]="7 Stam, 10 Crit", -[32409]="12 Agi", -[32634]="5 Agi, 6 Stam", -[32635]="4 Int, 6 Stam", -[32636]="5 Int, 4 Spirit", -[32637]="5 Agi, 8 Crit", -[32638]="5 Int, 4 Haste", -[32639]="4 Stam, 4 Crit", -[32640]="12 Crit", -[32641]="12 Int", -[32735]="10 Agi", -[32833]="3 Int, 6 Spirit", -[32836]="4 Int, 8 Spirit", -[33060]="8 Agi", -[33131]="12 Agi", -[33132]="12 Agi", -[33133]="12 Int", -[33134]="12 Int", -[33135]="18 Stam", -[33137]="24 Spirit", -[33138]="12 Resil", -[33139]="12 Int", -[33140]="24 Crit", -[33141]="24 Hit", -[33142]="24 Hit", -[33143]="24 Crit", -[33144]="24 Dodge", -[33782]="4 Resil, 6 Stam", -[34220]="24 Crit, 3% Crit Efct", -[34256]="15 Stam", -[34831]="15 Stam", -[35315]="16 Haste", -[35316]="4 Int, 8 Haste", -[35318]="6 Stam, 8 Haste", -[35487]="10 Agi", -[35488]="10 Int", -[35489]="10 Int", -[35501]="24 Dodge, 1% Block", -[35503]="12 Int, 2% Mana", -[35707]="6 Stam, 4 Dodge", -[35758]="5 Resil, 7 Stam", -[35759]="7 Stam, 5 Haste", -[35760]="5 Int, 10 Haste", -[35761]="20 Haste", -[36766]="34 Agi", -[36767]="51 Stam", -[37430]="24 Stam", -[37503]="5 Int, 10 Spirit", -[38292]="150 Armor", -[38545]="10 Agi", -[38546]="10 Crit", -[38547]="5 Agi, 5 Crit", -[38548]="5 Int, 5 Crit", -[38549]="10 Int", -[38550]="10 Crit", -[39900]="12 Str", -[39905]="12 Agi", -[39906]="12 Agi", -[39907]="24 Dodge", -[39908]="24 Parry", -[39909]="24 Crit", -[39910]="24 Exp", -[39911]="12 Int", -[39912]="12 Int", -[39914]="24 Crit", -[39915]="24 Hit", -[39916]="24 Dodge", -[39917]="12 Resil", -[39918]="24 Haste", -[39919]="18 Stam", -[39920]="24 Spirit", -[39927]="24 Spirit", -[39932]="12 PvP Pow", -[39933]="9 Stam, 12 Crit", -[39934]="6 Str, 9 Stam", -[39935]="6 Agi, 9 Stam", -[39936]="6 Int, 9 Stam", -[39937]="6 Agi, 9 Stam", -[39938]="9 Stam, 12 Dodge", -[39939]="9 Stam, 12 Parry", -[39940]="9 Stam, 12 Exp", -[39941]="6 Int, 12 Spirit", -[39942]="6 Agi, 12 Hit", -[39943]="6 Int, 12 Spirit", -[39944]="6 Agi, 12 Hit", -[39945]="6 Int, 6 PvP Pow", -[39946]="6 Int, 12 Haste", -[39947]="6 Str, 12 Crit", -[39948]="6 Str, 12 Hit", -[39949]="6 Str, 12 Dodge", -[39950]="6 Str, 6 Resil", -[39951]="6 Str, 12 Haste", -[39952]="6 Agi, 12 Crit", -[39953]="6 Agi, 12 Hit", -[39954]="6 Agi, 6 Resil", -[39955]="6 Agi, 12 Haste", -[39956]="6 Int, 12 Crit", -[39957]="6 Int, 12 Hit", -[39958]="6 Int, 6 Resil", -[39959]="6 Int, 12 Haste", -[39960]="6 Agi, 12 Crit", -[39961]="6 Agi, 12 Hit", -[39962]="6 Agi, 6 Resil", -[39963]="6 Agi, 12 Haste", -[39964]="12 Dodge, 12 Parry", -[39965]="12 Parry, 12 Dodge", -[39966]="12 Exp, 12 Hit", -[39967]="12 Exp, 12 Dodge", -[39968]="6 Int, 9 Stam", -[39974]="9 Stam, 12 Crit", -[39975]="12 Hit, 12 Dodge", -[39976]="9 Stam, 12 Dodge", -[39977]="6 Resil, 9 Stam", -[39978]="9 Stam, 12 Haste", -[39979]="6 Int, 12 Spirit", -[39980]="12 Crit, 12 Spirit", -[39981]="12 Hit, 12 Haste", -[39982]="6 Resil, 12 Spirit", -[39983]="12 Haste, 12 Spirit", -[39984]="6 Int, 12 Spirit", -[39985]="12 Crit, 12 Spirit", -[39986]="12 Hit, 12 Haste", -[39988]="6 Resil, 12 Spirit", -[39989]="12 Haste, 12 Spirit", -[39990]="6 PvP Pow, 12 Crit", -[39991]="6 PvP Pow, 12 Crit", -[39992]="6 PvP Pow, 12 Haste", -[39996]="16 Str", -[39997]="16 Agi", -[39998]="16 Int", -[39999]="16 Agi", -[40000]="32 Dodge", -[40001]="32 Parry", -[40002]="32 Crit", -[40003]="32 Exp", -[40008]="24 Stam", -[40009]="32 Spirit", -[40010]="32 Spirit", -[40011]="16 PvP Pow", -[40012]="16 Int", -[40013]="32 Crit", -[40014]="32 Hit", -[40015]="32 Dodge", -[40016]="16 Resil", -[40017]="32 Haste", -[40022]="8 Str, 12 Stam", -[40023]="8 Agi, 12 Stam", -[40024]="8 Agi, 16 Hit", -[40025]="8 Int, 12 Stam", -[40026]="8 Int, 16 Spirit", -[40027]="8 Int, 16 Spirit", -[40028]="8 Int, 8 PvP Pow", -[40029]="8 Agi, 12 Stam", -[40030]="8 Agi, 16 Hit", -[40031]="12 Stam, 16 Dodge", -[40032]="12 Stam, 16 Parry", -[40033]="12 Stam, 16 Crit", -[40034]="12 Stam, 16 Exp", -[40037]="8 Str, 16 Crit", -[40038]="8 Str, 16 Hit", -[40039]="8 Str, 16 Dodge", -[40040]="8 Str, 8 Resil", -[40041]="8 Str, 16 Haste", -[40043]="8 Agi, 16 Crit", -[40044]="8 Agi, 16 Hit", -[40045]="8 Agi, 8 Resil", -[40046]="8 Agi, 16 Haste", -[40047]="8 Int, 16 Haste", -[40048]="8 Int, 16 Crit", -[40049]="8 Int, 16 Hit", -[40050]="8 Int, 8 Resil", -[40051]="8 Int, 16 Haste", -[40052]="8 Agi, 16 Crit", -[40053]="8 Agi, 16 Hit", -[40054]="8 Agi, 8 Resil", -[40055]="8 Agi, 16 Haste", -[40056]="16 Dodge, 16 Parry", -[40057]="16 Parry, 16 Dodge", -[40058]="16 Exp, 16 Hit", -[40059]="16 Exp, 16 Dodge", -[40085]="8 Int, 12 Stam", -[40086]="12 Stam, 16 Crit", -[40088]="16 Hit, 16 Dodge", -[40089]="12 Stam, 16 Dodge", -[40090]="8 Resil, 12 Stam", -[40091]="12 Stam, 16 Haste", -[40092]="8 Int, 16 Spirit", -[40094]="8 Int, 16 Spirit", -[40095]="16 Crit, 16 Spirit", -[40096]="16 Crit, 16 Spirit", -[40098]="8 PvP Pow, 16 Crit", -[40099]="16 Hit, 16 Haste", -[40100]="16 Hit, 16 Haste", -[40101]="8 PvP Pow, 16 Crit", -[40102]="8 Resil, 16 Spirit", -[40103]="16 Resil, 8 Spirit", -[40104]="16 Haste, 16 Spirit", -[40105]="16 Haste, 16 Spirit", -[40106]="8 PvP Pow, 16 Haste", -[40111]="20 Str", -[40112]="20 Agi", -[40113]="20 Int", -[40114]="20 Agi", -[40115]="40 Dodge", -[40116]="40 Parry", -[40117]="40 Crit", -[40118]="40 Exp", -[40119]="30 Stam", -[40120]="40 Spirit", -[40121]="40 Spirit", -[40122]="20 PvP Pow", -[40123]="20 Int", -[40124]="40 Crit", -[40125]="40 Hit", -[40126]="40 Dodge", -[40127]="20 Resil", -[40128]="40 Haste", -[40129]="10 Str, 15 Stam", -[40130]="10 Agi, 15 Stam", -[40131]="10 Agi, 20 Hit", -[40132]="10 Int, 15 Stam", -[40133]="10 Int, 20 Spirit", -[40134]="10 Int, 20 Spirit", -[40135]="10 Int, 10 PvP Pow", -[40136]="10 Agi, 15 Stam", -[40137]="10 Agi, 20 Hit", -[40138]="15 Stam, 20 Dodge", -[40139]="15 Stam, 20 Parry", -[40140]="15 Stam, 20 Crit", -[40141]="15 Stam, 20 Exp", -[40142]="10 Str, 20 Crit", -[40143]="10 Str, 20 Hit", -[40144]="10 Str, 20 Dodge", -[40145]="10 Str, 10 Resil", -[40146]="10 Str, 20 Haste", -[40147]="10 Agi, 20 Crit", -[40148]="10 Agi, 20 Hit", -[40149]="10 Agi, 10 Resil", -[40150]="10 Agi, 20 Haste", -[40151]="10 Int, 20 Spirit", -[40152]="10 Int, 20 Crit", -[40153]="10 Int, 20 Hit", -[40154]="10 Int, 10 Resil", -[40155]="10 Int, 10 Haste", -[40156]="10 Agi, 20 Crit", -[40157]="10 Agi, 20 Hit", -[40158]="10 Agi, 10 Resil", -[40159]="10 Agi, 20 Haste", -[40160]="20 Dodge, 20 Parry", -[40161]="20 Parry, 20 Dodge", -[40162]="20 Exp, 20 Hit", -[40163]="20 Exp, 20 Dodge", -[40164]="10 Int, 15 Stam", -[40165]="15 Stam, 20 Crit", -[40166]="20 Hit, 20 Dodge", -[40167]="15 Stam, 20 Dodge", -[40168]="10 Resil, 15 Stam", -[40169]="15 Stam, 20 Haste", -[40170]="10 Int, 20 Spirit", -[40171]="20 Crit, 20 Spirit", -[40172]="20 Hit, 20 Haste", -[40173]="10 Resil, 20 Spirit", -[40174]="20 Haste, 20 Spirit", -[40175]="10 Int, 20 Spirit", -[40176]="20 Crit, 20 Spirit", -[40177]="20 Hit, 20 Haste", -[40178]="10 Resil, 20 Spirit", -[40179]="10 Haste, 20 Spirit", -[40180]="10 PvP Pow, 20 Crit", -[40181]="10 PvP Pow, 20 Crit", -[40182]="10 PvP Pow, 20 Haste", -[41285]="42 Crit, 3% Crit Efct", -[41307]="50 Crit, 1% Reflect", -[41333]="21 Int, 2% Mana", -[41335]="42 Crit, Snare", -[41339]="42 Crit", -[41375]="21 Int", -[41376]="42 Spirit, 3% Crit Efct", -[41377]="32 Stam", -[41378]="21 Int, Silence", -[41379]="42 Crit, Fear", -[41380]="32 Stam, 2% Armor", -[41381]="42 Crit", -[41382]="21 Int", -[41385]="42 Haste", -[41389]="42 Crit", -[41395]="21 Int, 2% Threat", -[41396]="42 Dodge, 1% Block", -[41397]="32 Stam, Stun", -[41398]="21 Agi", -[41401]="21 Int", -[41429]="7 Agi, 14 Crit", -[41432]="14 Str", -[41433]="14 Agi", -[41434]="14 Agi", -[41435]="28 Parry", -[41436]="28 Crit", -[41437]="28 Exp", -[41438]="14 Int", -[41439]="28 Dodge", -[41440]="28 Spirit", -[41441]="21 Stam", -[41442]="28 Spirit", -[41443]="14 PvP Pow", -[41444]="14 Int", -[41445]="14 Resil", -[41446]="28 Haste", -[41447]="28 Hit", -[41448]="28 Crit", -[41449]="28 Dodge", -[41450]="7 Agi, 10 Stam", -[41451]="10 Stam, 14 Parry", -[41452]="7 Int, 10 Stam", -[41453]="10 Stam, 14 Exp", -[41454]="7 Agi, 14 Hit", -[41455]="7 Int, 7 PvP Pow", -[41456]="10 Stam, 14 Crit", -[41457]="7 Int, 14 Spirit", -[41458]="10 Stam, 14 Dodge", -[41459]="7 Int, 14 Spirit", -[41460]="7 Agi, 10 Stam", -[41461]="7 Str, 10 Stam", -[41462]="7 Agi, 14 Hit", -[41463]="7 Int, 14 Spirit", -[41464]="10 Stam, 14 Dodge", -[41465]="14 Haste, 14 Spirit", -[41466]="10 Stam, 14 Haste", -[41467]="14 Haste, 14 Spirit", -[41468]="10 Stam, 14 Crit", -[41469]="14 Hit, 14 Haste", -[41470]="14 Crit, 14 Spirit", -[41471]="7 Resil, 14 Spirit", -[41472]="7 PvP Pow, 14 Crit", -[41473]="7 Int, 14 Spirit", -[41474]="7 PvP Pow, 14 Haste", -[41475]="14 Hit, 14 Haste", -[41476]="7 Resil, 10 Stam", -[41477]="14 Crit, 14 Spirit", -[41478]="7 PvP Pow, 14 Crit", -[41479]="7 Int, 10 Stam", -[41480]="7 Resil, 14 Spirit", -[41481]="14 Hit, 14 Dodge", -[41482]="14 Exp, 14 Hit", -[41483]="7 Str, 7 Dodge", -[41484]="7 Agi, 14 Crit", -[41485]="7 Agi, 14 Haste", -[41486]="7 Int, 7 Resil", -[41487]="7 Agi, 7 Resil", -[41488]="7 Str, 14 Hit", -[41489]="7 Str, 14 Haste", -[41490]="14 Parry, 14 Dodge", -[41491]="7 Agi, 14 Hit", -[41492]="7 Str, 14 Crit", -[41493]="7 Agi, 7 Resil", -[41494]="7 Int, 14 Spirit", -[41495]="7 Int, 14 Crit", -[41496]="7 Agi, 14 Hit", -[41497]="7 Int, 14 Haste", -[41498]="14 Exp, 14 Dodge", -[41499]="7 Str, 7 Resil", -[41500]="14 Dodge, 14 Parry", -[41501]="7 Agi, 14 Haste", -[41502]="7 Int, 14 Hit", -[42142]="34 Str", -[42143]="34 Agi", -[42144]="34 Int", -[42145]="68 Spirit", -[42146]="68 Spirit", -[42148]="34 Int", -[42149]="68 Crit", -[42150]="68 Haste", -[42151]="68 Dodge", -[42152]="68 Parry", -[42153]="68 Crit", -[42154]="68 Exp", -[42155]="34 PvP Pow", -[42156]="68 Hit", -[42157]="68 Dodge", -[42158]="34 Resil", -[42701]="12 Str, 12 Agi, 12 Stam, 12 Int, 12 Spirit", -[42702]="64 Str, 64 Agi, 64 Stam, 64 Int, 64 Spirit", -[44066]="20 Resil", -[44076]="17 Crit", -[44078]="17 Int", -[44081]="17 Crit, Snare", -[44082]="17 Crit, Fear", -[44084]="17 Int, Silence", -[44087]="17 Crit", -[44088]="26 Stam, Stun", -[44089]="17 Int", -[45862]="20 Str", -[45879]="20 Agi", -[45880]="30 Stam", -[45881]="40 Spirit", -[45882]="20 Int", -[45883]="20 Int", -[45987]="40 Hit", -[49110]="0 Str, 0 Agi, 0 Stam, 0 Int, 0 Spirit", -[52070]="24 Stam, 24 Agi", -[52081]="30 Str", -[52082]="30 Agi", -[52083]="60 Parry", -[52084]="30 Int", -[52085]="60 Exp", -[52086]="45 Stam", -[52087]="60 Spirit", -[52088]="30 PvP Pow", -[52089]="60 Hit", -[52090]="60 Dodge", -[52091]="60 Crit", -[52092]="30 Resil", -[52093]="60 Haste", -[52094]="60 Mastery", -[52095]="15 Str, 23 Stam", -[52096]="15 Agi, 23 Stam", -[52097]="23 Stam, 30 Parry", -[52098]="15 Int, 23 Stam", -[52099]="23 Stam, 30 Exp", -[52100]="15 Int, 30 Spirit", -[52101]="15 Str, 30 Hit", -[52102]="15 Agi, 30 Hit", -[52103]="30 Parry, 30 Hit", -[52104]="15 Int, 30 Hit", -[52105]="30 Exp, 30 Hit", -[52106]="15 Agi, 30 Dodge", -[52107]="30 Exp, 30 Dodge", -[52108]="15 Str, 30 Crit", -[52109]="15 Agi, 30 Crit", -[52110]="15 Int, 30 Crit", -[52111]="15 Str, 30 Haste", -[52112]="15 Agi, 30 Haste", -[52113]="15 Int, 30 Haste", -[52114]="15 Str, 30 Mastery", -[52115]="15 Agi, 30 Mastery", -[52116]="30 Parry, 30 Mastery", -[52117]="15 Int, 30 Mastery", -[52118]="30 Exp, 30 Mastery", -[52119]="23 Stam, 30 Dodge", -[52120]="30 Dodge, 30 Hit", -[52121]="23 Stam, 30 Crit", -[52122]="30 Crit, 30 Hit", -[52123]="15 Resil, 23 Stam", -[52124]="23 Stam, 30 Haste", -[52125]="30 Haste, 30 Hit", -[52126]="23 Stam, 30 Mastery", -[52127]="30 Mastery, 30 Spirit", -[52128]="30 Mastery, 30 Hit", -[52129]="35 Mastery, 35 Hit", -[52130]="35 Mastery, 35 Spirit", -[52131]="26 Stam, 35 Mastery", -[52132]="35 Haste, 35 Hit", -[52133]="26 Stam, 35 Haste", -[52134]="18 Resil, 26 Stam", -[52135]="35 Crit, 35 Hit", -[52136]="26 Stam, 35 Crit", -[52137]="35 Dodge, 35 Hit", -[52138]="26 Stam, 35 Dodge", -[52139]="35 Exp, 35 Mastery", -[52140]="18 Int, 35 Mastery", -[52141]="35 Parry, 35 Mastery", -[52142]="18 Agi, 35 Mastery", -[52143]="18 Str, 35 Mastery", -[52144]="18 Int, 35 Haste", -[52145]="18 Agi, 35 Haste", -[52146]="18 Str, 35 Haste", -[52147]="18 Int, 35 Crit", -[52148]="18 Agi, 35 Crit", -[52149]="18 Str, 35 Crit", -[52150]="35 Exp, 35 Dodge", -[52151]="18 Agi, 35 Dodge", -[52152]="35 Exp, 35 Hit", -[52153]="18 Int, 35 Hit", -[52154]="35 Parry, 35 Hit", -[52155]="17 Agi, 35 Hit", -[52156]="18 Str, 35 Hit", -[52157]="18 Int, 35 Spirit", -[52158]="26 Stam, 35 Exp", -[52159]="18 Int, 26 Stam", -[52160]="26 Stam, 35 Parry", -[52161]="18 Agi, 26 Stam", -[52162]="18 Str, 26 Stam", -[52163]="70 Mastery", -[52164]="70 Haste", -[52165]="35 Resil", -[52166]="70 Crit", -[52167]="70 Dodge", -[52168]="70 Hit", -[52169]="35 PvP Pow", -[52170]="70 Spirit", -[52171]="53 Stam", -[52172]="70 Exp", -[52173]="35 Int", -[52174]="70 Parry", -[52175]="35 Agi", -[52176]="35 Str", -[52203]="40 Exp, 40 Hit", -[52204]="20 Agi, 40 Mastery", -[52205]="20 Int, 40 Mastery", -[52206]="40 Str", -[52207]="40 Int", -[52208]="20 Int, 40 Haste", -[52209]="20 Agi, 40 Crit", -[52210]="30 Stam, 40 Parry", -[52211]="20 Agi, 40 Haste", -[52212]="40 Agi", -[52213]="20 Str, 40 Hit", -[52214]="20 Str, 40 Haste", -[52215]="40 Parry, 40 Mastery", -[52216]="80 Parry", -[52217]="20 Int, 40 Hit", -[52218]="30 Stam, 40 Haste", -[52219]="80 Mastery", -[52220]="20 Agi, 40 Hit", -[52221]="30 Stam, 40 Exp", -[52222]="20 Str, 40 Crit", -[52223]="30 Stam, 40 Crit", -[52224]="40 Exp, 40 Mastery", -[52225]="40 Haste, 40 Hit", -[52226]="40 Resil", -[52227]="40 Dodge, 40 Hit", -[52228]="40 Crit, 40 Hit", -[52229]="20 Agi, 40 Dodge", -[52230]="80 Exp", -[52231]="30 Stam, 20 Mastery", -[52232]="80 Haste", -[52233]="30 Stam, 40 Dodge", -[52234]="40 Parry, 40 Hit", -[52235]="80 Hit", -[52236]="20 Int, 40 Spirit", -[52237]="40 Mastery, 40 Hit", -[52238]="20 Agi, 30 Stam", -[52239]="20 Int, 40 Crit", -[52240]="20 Str, 40 Mastery", -[52241]="80 Crit", -[52242]="60 Stam", -[52243]="20 Str, 30 Stam", -[52244]="80 Spirit", -[52245]="20 Resil, 30 Stam", -[52246]="40 PvP Pow", -[52247]="80 Dodge", -[52248]="20 Int, 30 Stam", -[52249]="40 Exp, 40 Dodge", -[52250]="40 Mastery, 40 Spirit", -[52255]="67 Str", -[52257]="67 Int", -[52258]="67 Agi", -[52259]="67 Parry", -[52260]="134 Exp", -[52261]="101 Stam", -[52262]="134 Spirit", -[52263]="67 PvP Pow", -[52264]="134 Hit", -[52265]="134 Dodge", -[52266]="134 Crit", -[52267]="67 Resil", -[52268]="134 Haste", -[52269]="134 Mastery", -[52289]="108 Mastery, Run Speed", -[52291]="108 Crit, 3% Crit Efct", -[52292]="54 Int, 2% Threat", -[52293]="81 Stam, 1% Block", -[52294]="81 Stam, 2% Armor", -[52295]="81 Stam", -[52296]="54 Int, 2% Mana", -[52297]="108 Spirit, 3% Crit Efct", -[52298]="108 Crit, 1% Reflect", -[52299]="81 Stam, Stun", -[52300]="108 Crit, Snare", -[52301]="108 Crit, Fear", -[52302]="54 Int, Silence", -[54616]="50 Str", -[59477]="208 Dodge", -[59478]="208 Crit", -[59479]="208 Haste", -[59480]="208 Mastery", -[59489]="208 Exp", -[59491]="208 Parry", -[59493]="208 Hit", -[59496]="208 Spirit", -[63696]="7 Str", -[63697]="7 Str", -[68356]="20 Int, 20 Resil", -[68357]="20 Agi, 20 Resil", -[68358]="20 Str, 20 Resil", -[68660]="52 Resil", -[68741]="20 Resil, 20 PvP Pow", -[68778]="54 Agi, 3% Crit Efct", -[68779]="54 Str, 3% Crit Efct", -[68780]="54 Int, 3% Crit Efct", -[69922]="50 Int", -[69923]="50 Agi", -[71817]="100 Hit", -[71818]="100 PvP Pow", -[71819]="100 Spirit", -[71820]="75 Stam", -[71822]="50 Spirit, 50 Crit", -[71823]="50 Crit, 50 Hit", -[71824]="50 Haste, 50 Hit", -[71825]="50 Hit, 50 Mastery", -[71826]="25 PvP Pow, 50 Mastery", -[71827]="50 Spirit, 50 Mastery", -[71828]="25 Resil, 50 Hit", -[71829]="25 PvP Pow, 25 Resil", -[71830]="25 Resil, 50 Spirit", -[71831]="25 PvP Pow, 50 Crit", -[71832]="25 PvP Pow, 50 Haste", -[71833]="50 Haste, 50 Spirit", -[71834]="37 Stam, 50 Crit", -[71835]="37 Stam, 50 Dodge", -[71836]="37 Stam, 50 Haste", -[71837]="50 Hit, 50 Dodge", -[71838]="37 Stam, 50 Mastery", -[71839]="25 Resil, 37 Stam", -[71840]="25 Agi, 50 Crit", -[71841]="50 Exp, 50 Crit", -[71842]="25 Int, 50 Crit", -[71843]="25 Str, 50 Crit", -[71844]="25 Agi, 50 Dodge", -[71845]="50 Exp, 50 Dodge", -[71846]="50 Parry, 50 Dodge", -[71847]="25 Str, 50 Dodge", -[71848]="25 Agi, 50 Haste", -[71849]="50 Exp, 50 Haste", -[71850]="25 Int, 50 Haste", -[71851]="25 Str, 50 Haste", -[71852]="25 Agi, 50 Mastery", -[71853]="50 Exp, 50 Mastery", -[71854]="25 Int, 50 Mastery", -[71855]="50 Parry, 50 Mastery", -[71856]="25 Str, 50 Mastery", -[71857]="25 Agi, 25 Resil", -[71858]="25 Resil, 50 Exp", -[71859]="25 Int, 25 Resil", -[71860]="25 Resil, 50 Parry", -[71861]="25 Str, 25 Resil", -[71862]="25 Agi, 50 Hit", -[71863]="50 Exp, 50 Hit", -[71864]="25 Int, 50 Hit", -[71865]="50 Parry, 50 Hit", -[71866]="25 Str, 50 Hit", -[71867]="25 Int, 25 PvP Pow", -[71868]="25 Int, 50 Spirit", -[71869]="25 Agi, 37 Stam", -[71870]="37 Stam, 50 Exp", -[71871]="25 Int, 37 Stam", -[71872]="37 Stam, 50 Parry", -[71873]="25 Str, 37 Stam", -[71874]="100 Crit", -[71875]="100 Dodge", -[71876]="100 Haste", -[71877]="100 Mastery", -[71878]="50 Resil", -[71879]="50 Agi", -[71880]="100 Exp", -[71881]="50 Int", -[71882]="100 Parry", -[71883]="50 Str", -[76502]="240 Hit", -[76504]="120 PvP Pow", -[76505]="240 Spirit", -[76506]="180 Stam", -[76507]="120 Spirit, 120 Crit", -[76508]="120 Crit, 120 Hit", -[76509]="120 Haste, 120 Hit", -[76510]="120 Hit, 120 Mastery", -[76511]="60 PvP Pow, 120 Mastery", -[76512]="120 Spirit, 120 Mastery", -[76513]="60 Resil, 120 Hit", -[76514]="60 PvP Pow, 60 Resil", -[76515]="60 Resil, 120 Spirit", -[76517]="60 PvP Pow, 120 Crit", -[76518]="60 PvP Pow, 120 Haste", -[76519]="120 Haste, 120 Spirit", -[76520]="90 Stam, 120 Crit", -[76521]="90 Stam, 120 Dodge", -[76522]="90 Stam, 120 Haste", -[76523]="90 Stam, 120 Hit", -[76524]="90 Stam, 120 Mastery", -[76525]="60 Resil, 90 Stam", -[76526]="60 Agi, 120 Crit", -[76527]="120 Exp, 120 Crit", -[76528]="60 Int, 120 Crit", -[76529]="60 Str, 120 Crit", -[76530]="60 Agi, 120 Dodge", -[76531]="120 Exp, 120 Dodge", -[76532]="120 Parry, 120 Dodge", -[76533]="60 Str, 120 Dodge", -[76534]="60 Agi, 120 Haste", -[76535]="120 Exp, 120 Haste", -[76536]="60 Int, 120 Haste", -[76537]="60 Str, 120 Haste", -[76538]="60 Agi, 120 Mastery", -[76539]="120 Exp, 120 Mastery", -[76540]="60 Int, 120 Mastery", -[76541]="120 Parry, 120 Mastery", -[76542]="60 Str, 120 Mastery", -[76543]="60 Agi, 60 Resil", -[76544]="60 Resil, 120 Exp", -[76545]="60 Int, 60 Resil", -[76546]="60 Resil, 120 Parry", -[76547]="60 Str, 60 Resil", -[76548]="60 Agi, 120 Hit", -[76549]="120 Exp, 120 Hit", -[76550]="60 Int, 120 Hit", -[76551]="120 Parry, 120 Hit", -[76552]="60 Str, 120 Hit", -[76553]="60 Int, 60 PvP Pow", -[76554]="60 Int, 120 Spirit", -[76555]="60 Agi, 90 Stam", -[76556]="90 Stam, 120 Exp", -[76557]="60 Int, 90 Stam", -[76558]="90 Stam, 120 Parry", -[76559]="60 Str, 90 Stam", -[76560]="120 Agi", -[76561]="240 Exp", -[76562]="120 Int", -[76563]="240 Parry", -[76564]="120 Str", -[76565]="240 Crit", -[76566]="240 Dodge", -[76567]="240 Haste", -[76568]="240 Mastery", -[76569]="120 Resil", -[76570]="320 Hit", -[76571]="160 PvP Pow", -[76572]="320 Spirit", -[76573]="240 Stam", -[76574]="160 Spirit, 160 Crit", -[76575]="160 Crit, 160 Hit", -[76576]="160 Haste, 160 Hit", -[76577]="160 Hit, 160 Mastery", -[76578]="80 PvP Pow, 160 Mastery", -[76579]="160 Spirit, 160 Mastery", -[76580]="80 Resil, 160 Hit", -[76581]="80 PvP Pow, 80 Resil", -[76582]="80 Resil, 160 Spirit", -[76583]="80 PvP Pow, 160 Crit", -[76584]="80 PvP Pow, 160 Haste", -[76585]="160 Haste, 160 Spirit", -[76586]="120 Stam, 160 Crit", -[76587]="120 Stam, 160 Dodge", -[76588]="120 Stam, 160 Haste", -[76589]="120 Stam, 160 Hit", -[76590]="120 Stam, 160 Mastery", -[76591]="80 Resil, 120 Stam", -[76592]="80 Agi, 160 Crit", -[76593]="160 Exp, 160 Crit", -[76594]="80 Int, 160 Crit", -[76595]="80 Str, 160 Crit", -[76596]="80 Agi, 160 Dodge", -[76597]="160 Exp, 160 Dodge", -[76598]="160 Parry, 160 Dodge", -[76599]="80 Str, 160 Dodge", -[76600]="80 Agi, 160 Haste", -[76601]="160 Exp, 160 Haste", -[76602]="80 Int, 160 Haste", -[76603]="80 Str, 160 Haste", -[76604]="80 Agi, 160 Mastery", -[76605]="160 Exp, 160 Mastery", -[76606]="80 Int, 160 Mastery", -[76607]="160 Parry, 160 Mastery", -[76608]="80 Str, 160 Mastery", -[76609]="80 Agi, 80 Resil", -[76610]="80 Resil, 160 Exp", -[76611]="80 Int, 80 Resil", -[76612]="80 Resil, 160 Parry", -[76613]="80 Str, 80 Resil", -[76614]="80 Agi, 160 Hit", -[76615]="160 Exp, 160 Hit", -[76616]="80 Int, 160 Hit", -[76617]="160 Parry, 160 Hit", -[76618]="80 Str, 160 Hit", -[76619]="80 Int, 80 PvP Pow", -[76620]="80 Int, 160 Spirit", -[76621]="80 Agi, 120 Stam", -[76622]="120 Stam, 160 Exp", -[76623]="80 Int, 120 Stam", -[76624]="120 Stam, 160 Parry", -[76625]="80 Str, 120 Stam", -[76626]="160 Agi", -[76627]="320 Exp", -[76628]="160 Int", -[76629]="320 Parry", -[76630]="160 Str", -[76631]="320 Crit", -[76632]="320 Dodge", -[76633]="320 Haste", -[76634]="320 Mastery", -[76635]="160 Resil", -[76636]="320 Hit", -[76637]="160 PvP Pow", -[76638]="320 Spirit", -[76639]="240 Stam", -[76640]="160 Spirit, 160 Crit", -[76641]="160 Crit, 160 Hit", -[76642]="160 Haste, 160 Hit", -[76643]="160 Hit, 160 Mastery", -[76644]="80 PvP Pow, 160 Mastery", -[76645]="160 Spirit, 160 Mastery", -[76646]="80 Resil, 160 Hit", -[76647]="80 PvP Pow, 80 Resil", -[76648]="80 Resil, 160 Spirit", -[76649]="80 PvP Pow, 160 Crit", -[76650]="80 PvP Pow, 160 Haste", -[76651]="160 Haste, 160 Spirit", -[76652]="120 Stam, 160 Crit", -[76653]="120 Stam, 160 Dodge", -[76654]="120 Stam, 160 Haste", -[76655]="120 Stam, 160 Hit", -[76656]="120 Stam, 160 Mastery", -[76657]="80 Resil, 120 Stam", -[76658]="80 Agi, 160 Crit", -[76659]="160 Exp, 160 Crit", -[76660]="80 Int, 160 Crit", -[76661]="80 Str, 160 Crit", -[76662]="80 Agi, 160 Dodge", -[76663]="160 Exp, 160 Dodge", -[76664]="160 Parry, 160 Dodge", -[76665]="80 Str, 160 Dodge", -[76666]="80 Agi, 160 Haste", -[76667]="160 Exp, 160 Haste", -[76668]="80 Int, 160 Haste", -[76669]="80 Str, 160 Haste", -[76670]="80 Agi, 160 Mastery", -[76671]="160 Exp, 160 Mastery", -[76672]="80 Int, 160 Mastery", -[76673]="160 Parry, 160 Mastery", -[76674]="80 Str, 160 Mastery", -[76675]="80 Agi, 80 Resil", -[76676]="80 Resil, 160 Exp", -[76677]="80 Int, 80 Resil", -[76678]="80 Resil, 160 Parry", -[76679]="80 Str, 80 Resil", -[76680]="80 Agi, 160 Hit", -[76681]="160 Exp, 160 Hit", -[76682]="80 Int, 160 Hit", -[76683]="160 Parry, 160 Hit", -[76684]="80 Str, 160 Hit", -[76685]="80 Int, 80 PvP Pow", -[76686]="80 Int, 160 Spirit", -[76687]="80 Agi, 120 Stam", -[76688]="120 Stam, 160 Exp", -[76689]="80 Int, 120 Stam", -[76690]="120 Stam, 160 Parry", -[76691]="80 Str, 120 Stam", -[76692]="160 Agi", -[76693]="320 Exp", -[76694]="160 Int", -[76695]="320 Parry", -[76696]="160 Str", -[76697]="320 Crit", -[76698]="320 Dodge", -[76699]="320 Haste", -[76700]="320 Mastery", -[76701]="160 Resil", -[76879]="216 Int, 2% Mana", -[76884]="216 Agi, 3% Crit Efct", -[76885]="216 Int, 3% Crit Efct", -[76886]="216 Str, 3% Crit Efct", -[76887]="432 Mastery, Run Speed", -[76888]="432 Spirit, 3% Crit Efct", -[76890]="432 Crit, 1% Reflect", -[76891]="324 Stam, Stun", -[76892]="432 Crit, Snare", -[76893]="432 Crit, Fear", -[76894]="216 Int, Silence", -[76895]="324 Stam, 2% Armor", -[76896]="432 Dodge, 1% Block", -[76897]="324 Stam", -[77130]="25 Resil, 50 Hit", -[77131]="25 PvP Pow, 50 Mastery", -[77132]="25 Agi, 25 Resil", -[77133]="25 Int, 25 PvP Pow", -[77134]="50 Resil", -[77136]="25 Str, 25 Resil", -[77137]="25 PvP Pow, 50 Haste", -[77138]="25 Resil, 50 Parry", -[77139]="25 Resil, 37 Stam", -[77140]="50 PvP Pow", -[77141]="25 Resil, 50 Exp", -[77142]="25 Resil, 50 Spirit", -[77143]="25 PvP Pow, 25 Resil", -[77144]="25 Int, 25 Resil", -[77154]="25 PvP Pow, 50 Crit", -[77540]="600 Dodge", -[77541]="600 Crit", -[77542]="600 Haste", -[77543]="600 Exp", -[77544]="600 Parry", -[77545]="600 Hit", -[77546]="600 Spirit", -[77547]="600 Mastery", -[83141]="320 Str", -[83142]="480 Haste", -[83143]="480 Mastery", -[83144]="480 Hit", -[83145]="480 Dodge", -[83146]="480 Crit", -[83147]="480 Exp", -[83148]="480 Stam", -[83149]="480 Spirit", -[83150]="320 Int", -[83151]="320 Agi", -[83152]="480 Parry", -[88911]="100 Resil, 200 Hit", -[88912]="100 PvP Pow, 200 Mastery", -[88913]="200 Haste, 200 Spirit", -[88914]="150 Stam, 200 Haste", -[88915]="150 Stam, 200 Crit", -[88916]="200 Haste, 200 Hit", -[88917]="200 Spirit, 200 Crit", -[88918]="150 Stam, 200 Hit", -[88919]="200 Crit, 200 Hit", -[88920]="150 Stam, 200 Mastery", -[88921]="100 PvP Pow, 200 Crit", -[88922]="150 Stam, 200 Dodge", -[88923]="200 Hit, 200 Mastery", -[88924]="100 PvP Pow, 200 Haste", -[88925]="100 Resil, 150 Stam", -[88926]="100 Resil, 200 Spirit", -[88927]="100 PvP Pow, 100 Resil", -[88928]="200 Spirit, 200 Mastery", -[88930]="100 Agi, 200 Mastery", -[88931]="100 Int, 200 Mastery", -[88932]="100 Str, 200 Dodge", -[88933]="200 Exp, 200 Crit", -[88934]="100 Agi, 200 Crit", -[88935]="100 Agi, 200 Haste", -[88936]="100 Str, 200 Haste", -[88937]="200 Parry, 200 Mastery", -[88938]="100 Str, 200 Crit", -[88939]="200 Exp, 200 Mastery", -[88940]="100 Agi, 100 Resil", -[88941]="100 Agi, 200 Dodge", -[88942]="100 Int, 200 Crit", -[88943]="100 Int, 200 Haste", -[88944]="200 Exp, 200 Dodge", -[88945]="100 Str, 100 Resil", -[88946]="100 Str, 200 Mastery", -[88947]="100 Resil, 200 Parry", -[88948]="200 Parry, 200 Dodge", -[88949]="100 Resil, 200 Exp", -[88950]="200 Exp, 200 Haste", -[88951]="100 Int, 100 Resil", -[88952]="200 Exp, 200 Hit", -[88953]="150 Stam, 200 Parry", -[88954]="100 Str, 200 Hit", -[88955]="100 Agi, 200 Hit", -[88956]="150 Stam, 200 Exp", -[88958]="100 Int, 200 Spirit", -[88959]="200 Parry, 200 Hit", -[88960]="100 Agi, 150 Stam", -[88961]="100 Str, 150 Stam", -[88962]="100 Int, 150 Stam", -[88963]="100 Int, 200 Hit", -[88987]="100 Int, 100 PvP Pow", -[89674]="80 Str, 80 PvP Pow", -[89675]="60 Str, 60 PvP Pow", -[89676]="80 Str, 80 PvP Pow", -[89677]="100 Str, 100 PvP Pow", -[89678]="60 Agi, 60 PvP Pow", -[89679]="80 Agi, 80 PvP Pow", -[89680]="80 Agi, 80 PvP Pow", -[89681]="100 Agi, 100 PvP Pow", -[89873]="500 Agi", -[89881]="500 Str", -[89882]="500 Int", -[93364]="550 Agi", -[93365]="550 Str", -[93366]="550 Int", -[93404]="160 Str, 160 Resil", -[93405]="160 Agi, 160 Resil", -[93406]="160 Int, 160 Resil", -[93408]="160 Str, 160 PvP Pow", -[93409]="160 Agi, 160 PvP Pow", -[93410]="160 Int, 160 PvP Pow", -[93705]="160 Hit, 160 Dodge", -[93706]="120 Hit, 120 Dodge", -[93707]="160 Hit, 160 Dodge", -[93708]="200 Hit, 200 Dodge", -[95344]="Indomitable", -[95345]="Courageous", -[95346]="Capacitive", -[95347]="Sinister", -[95348]="665 PvP Pow, 775 Resil"} - -AskMrRobot.gemDuplicates = { -[76570]=76636, -[76571]=76637, -[76572]=76638, -[76573]=76639, -[76574]=76640, -[76575]=76641, -[76576]=76642, -[76577]=76643, -[76578]=76644, -[76579]=76645, -[76580]=76646, -[76581]=76647, -[76582]=76648, -[76583]=76649, -[76584]=76650, -[76585]=76651, -[76586]=76652, -[76587]=76653, -[76588]=76654, -[76589]=76655, -[76590]=76656, -[76591]=76657, -[76592]=76658, -[76593]=76659, -[76594]=76660, -[76595]=76661, -[76596]=76662, -[76597]=76663, -[76598]=76664, -[76599]=76665, -[76600]=76666, -[76601]=76667, -[76602]=76668, -[76603]=76669, -[76604]=76670, -[76605]=76671, -[76606]=76672, -[76607]=76673, -[76608]=76674, -[76609]=76675, -[76610]=76676, -[76611]=76677, -[76612]=76678, -[76613]=76679, -[76614]=76680, -[76615]=76681, -[76616]=76682, -[76617]=76683, -[76618]=76684, -[76619]=76685, -[76620]=76686, -[76621]=76687, -[76622]=76688, -[76623]=76689, -[76624]=76690, -[76625]=76691, -[76626]=76692, -[76627]=76693, -[76628]=76694, -[76629]=76695, -[76630]=76696, -[76631]=76697, -[76632]=76698, -[76633]=76699, -[76634]=76700, -[76635]=76701, -[76636]=76570, -[76637]=76571, -[76638]=76572, -[76639]=76573, -[76640]=76574, -[76641]=76575, -[76642]=76576, -[76643]=76577, -[76644]=76578, -[76645]=76579, -[76646]=76580, -[76647]=76581, -[76648]=76582, -[76649]=76583, -[76650]=76584, -[76651]=76585, -[76652]=76586, -[76653]=76587, -[76654]=76588, -[76655]=76589, -[76656]=76590, -[76657]=76591, -[76658]=76592, -[76659]=76593, -[76660]=76594, -[76661]=76595, -[76662]=76596, -[76663]=76597, -[76664]=76598, -[76665]=76599, -[76666]=76600, -[76667]=76601, -[76668]=76602, -[76669]=76603, -[76670]=76604, -[76671]=76605, -[76672]=76606, -[76673]=76607, -[76674]=76608, -[76675]=76609, -[76676]=76610, -[76677]=76611, -[76678]=76612, -[76679]=76613, -[76680]=76614, -[76681]=76615, -[76682]=76616, -[76683]=76617, -[76684]=76618, -[76685]=76619, -[76686]=76620, -[76687]=76621, -[76688]=76622, -[76689]=76623, -[76690]=76624, -[76691]=76625, -[76692]=76626, -[76693]=76627, -[76694]=76628, -[76695]=76629, -[76696]=76630, -[76697]=76631, -[76698]=76632, -[76699]=76633, -[76700]=76634, -[76701]=76635, -[89674]=89676, -[89676]=89674, -[89679]=89680, -[89680]=89679, -[93705]=93707, -[93707]=93705} - -local gemEnchantDuplicates = { -[4520]=4587, -[4521]=4588, -[4522]=4589, -[4523]=4590, -[4524]=4591, -[4525]=4592, -[4526]=4593, -[4527]=4594, -[4528]=4595, -[4529]=4596, -[4530]=4597, -[4531]=4598, -[4532]=4599, -[4533]=4600, -[4535]=4601, -[4536]=4602, -[4537]=4603, -[4538]=4604, -[4539]=4605, -[4540]=4606, -[4541]=4607, -[4542]=4608, -[4543]=4609, -[4544]=4610, -[4545]=4611, -[4546]=4612, -[4547]=4613, -[4548]=4614, -[4549]=4615, -[4550]=4616, -[4551]=4617, -[4552]=4618, -[4553]=4619, -[4554]=4620, -[4555]=4621, -[4556]=4622, -[4557]=4623, -[4558]=4624, -[4559]=4625, -[4560]=4626, -[4561]=4627, -[4562]=4628, -[4563]=4629, -[4564]=4630, -[4565]=4631, -[4566]=4632, -[4567]=4633, -[4568]=4634, -[4569]=4635, -[4570]=4636, -[4571]=4637, -[4572]=4638, -[4573]=4652, -[4574]=4640, -[4575]=4641, -[4576]=4642, -[4577]=4643, -[4578]=4653, -[4579]=4644, -[4580]=4645, -[4581]=4646, -[4582]=4647, -[4583]=4648, -[4584]=4649, -[4585]=4650, -[4586]=4651, -[4587]=4520, -[4588]=4521, -[4589]=4522, -[4590]=4523, -[4591]=4524, -[4592]=4525, -[4593]=4526, -[4594]=4527, -[4595]=4528, -[4596]=4529, -[4597]=4530, -[4598]=4531, -[4599]=4532, -[4600]=4533, -[4601]=4535, -[4602]=4536, -[4603]=4537, -[4604]=4538, -[4605]=4539, -[4606]=4540, -[4607]=4541, -[4608]=4542, -[4609]=4543, -[4610]=4544, -[4611]=4545, -[4612]=4546, -[4613]=4547, -[4614]=4548, -[4615]=4549, -[4616]=4550, -[4617]=4551, -[4618]=4552, -[4619]=4553, -[4620]=4554, -[4621]=4555, -[4622]=4556, -[4623]=4557, -[4624]=4558, -[4625]=4559, -[4626]=4560, -[4627]=4561, -[4628]=4562, -[4629]=4563, -[4630]=4564, -[4631]=4565, -[4632]=4566, -[4633]=4567, -[4634]=4568, -[4635]=4569, -[4636]=4570, -[4637]=4571, -[4638]=4572, -[4652]=4573, -[4640]=4574, -[4641]=4575, -[4642]=4576, -[4643]=4577, -[4653]=4578, -[4644]=4579, -[4645]=4580, -[4646]=4581, -[4647]=4582, -[4648]=4583, -[4649]=4584, -[4650]=4585, -[4651]=4586, -[4984]=4986, -[4986]=4984, -[4989]=4990, -[4990]=4989, -[5024]=5026, -[5026]=5024} - -local perfectGems = { -[76570]=1, -[76571]=1, -[76572]=1, -[76573]=1, -[76574]=1, -[76575]=1, -[76576]=1, -[76577]=1, -[76578]=1, -[76579]=1, -[76580]=1, -[76581]=1, -[76582]=1, -[76583]=1, -[76584]=1, -[76585]=1, -[76586]=1, -[76587]=1, -[76588]=1, -[76589]=1, -[76590]=1, -[76591]=1, -[76592]=1, -[76593]=1, -[76594]=1, -[76595]=1, -[76596]=1, -[76597]=1, -[76598]=1, -[76599]=1, -[76600]=1, -[76601]=1, -[76602]=1, -[76603]=1, -[76604]=1, -[76605]=1, -[76606]=1, -[76607]=1, -[76608]=1, -[76609]=1, -[76610]=1, -[76611]=1, -[76612]=1, -[76613]=1, -[76614]=1, -[76615]=1, -[76616]=1, -[76617]=1, -[76618]=1, -[76619]=1, -[76620]=1, -[76621]=1, -[76622]=1, -[76623]=1, -[76624]=1, -[76625]=1, -[76626]=1, -[76627]=1, -[76628]=1, -[76629]=1, -[76630]=1, -[76631]=1, -[76632]=1, -[76633]=1, -[76634]=1, -[76635]=1, -[89676]=1, -[89679]=1, -[93707]=1} - -AskMrRobot.JewelcrafterGems = { -[36766]=1, -[36767]=1, -[42142]=1, -[42143]=1, -[42144]=1, -[42145]=1, -[42146]=1, -[42148]=1, -[42149]=1, -[42150]=1, -[42151]=1, -[42152]=1, -[42153]=1, -[42154]=1, -[42155]=1, -[42156]=1, -[42157]=1, -[42158]=1, -[52255]=1, -[52257]=1, -[52258]=1, -[52259]=1, -[52260]=1, -[52261]=1, -[52262]=1, -[52263]=1, -[52264]=1, -[52265]=1, -[52266]=1, -[52267]=1, -[52268]=1, -[52269]=1, -[83141]=1, -[83142]=1, -[83143]=1, -[83144]=1, -[83145]=1, -[83146]=1, -[83147]=1, -[83148]=1, -[83149]=1, -[83150]=1, -[83151]=1, -[83152]=1, -[93404]=1, -[93405]=1, -[93406]=1, -[93408]=1, -[93409]=1, -[93410]=1} - -local function DoGemsMatch(gemIdA, gemIdB) - return gemIdA == gemIdB or (gemIdA and gemIdB and gemIdA == AskMrRobot.gemDuplicates[gemIdB]) -end - -local function DoGemEnchantsMatch(gemEnchantIdA, gemEnchantIdB) - return gemEnchantIdA == gemEnchantIdB or (gemEnchantIdA and gemEnchantIdB and gemEnchantIdA == gemEnchantDuplicates[gemEnchantIdB]) -end - -local function GemMatchesSocket(gemId, socketColor) - local gemColor = gemToColor[gemId] - if socketColor == 'Red' then - return gemColor =='Red' or gemColor == 'Orange' or gemColor == 'Purple' - elseif socketColor == 'Yellow' then - return gemColor == 'Yellow' or gemColor == 'Orange' or gemColor == 'Green' - elseif socketColor == 'Blue' then - return gemColor == 'Blue' or gemColor == 'Purple' or gemColor == 'Green' - elseif socketColor == 'Prismatic' then - return gemColor == 'Prismatic' or gemColor == 'Orange' or gemColor == 'Green' or gemColor == 'Purple' or gemColor == 'Red' or gemColor == 'Yellow' or gemColor == 'Blue' - else - return gemColor == socketColor - end -end - -local function CanInsertGem(gemId, socketColor) - local gemColor = gemToColor[gemId] - return gemColor == socketColor or ((socketColor == 'Red' or socketColor == 'Yellow' or socketColor == 'Blue' or socketColor == 'Prismatic') - and (gemColor == 'Orange' or gemColor == 'Green' or gemColor == 'Purple' or gemColor == 'Red' or gemColor == 'Yellow' or gemColor == 'Blue')) -end - --- in: [{id (gemId), color (socketColor)}] --- out: bool -local function AmrExpectsSocketBonus(gems) - local i - for i = 1, #gems do - local gem = gems[i] - if gem.color and not GemMatchesSocket(gem.id, gem.color) then - return false - end - end - return true -end - -local function GetGemPermuations(gems) - local count = 0 - local i - for i = 1, #gems do - if gems[i].color then - count = count + 1 - end - end - if count == 0 then - return {} - elseif count == 1 then - return { { gems[1] } } - elseif count == 2 then - return { { gems[1], gems[2] } , { gems[2], gems[1] } } - elseif count == 3 then - return { { gems[1], gems[2], gems[3] } , { gems[1], gems[3], gems[2] }, - { gems[2], gems[1], gems[3] } , { gems[2], gems[3], gems[1] }, - { gems[3], gems[1], gems[2] } , { gems[3], gems[2], gems[1] } - } - end -end - -local function GetMatchingGems(gems, bonus) - local perms = GetGemPermuations(gems) - local i, j - local valid = {} - for i = 1, #perms do - local isValid = true - for j = 1, #perms[i] do - if bonus then - if not GemMatchesSocket(perms[i][j].id, gems[j].color) then - isValid = false - break - end - elseif not CanInsertGem(perms[i][j].id, gems[j].color) then - isValid = false - break - end - end - if isValid then - tinsert(valid, perms[i]) - end - end - return valid -end - -local function GetBestGems(existingItemLink, gems, bonus) - local perms = GetMatchingGems(gems, bonus) - local bestScore = -1 - local bestPerm = gems - for i = 1, #perms do - local score = 0 - for j = 1, #perms[i] do - local existingGemLink = select(2, GetItemGem(existingItemLink, j)) - if existingGemLink then - local existingGemId = AskMrRobot.getItemIdFromLink(existingGemLink) - if DoGemsMatch(perms[i][j].id, existingGemId) then - score = score + 1 - end - end - end - if score > bestScore then - bestScore = score - bestPerm = perms[i] - end - end - - local result = {} --make a new variable, because we don't want to change the original objects - for i = 1, #bestPerm do - --restore the color from the original. This only really changes when bonus is false - result[i] = {id = bestPerm[i].id, enchantId = bestPerm[i].enchantId, color = gems[i].color} - end - return result -end - -local function GetBadGems(existingItemLink, existingGemEnchantIds, gems) - local i - - local badGemCount = 0 - local result = { optimized = gems, current = existingGemEnchantIds, badGems = {}} - for i = 1, #gems do - -- get the current gem in the specified slot - local existingGemLink = select(2, GetItemGem(existingItemLink, i)) - local existingGemId = existingGemLink and AskMrRobot.getItemIdFromLink(existingGemLink) or 0 - gems[i].matched = DoGemsMatch(existingGemId, gems[i].id) - if not gems[i].matched then - result.badGems[i] = true - badGemCount = badGemCount + 1 - end - end - result.current.link = existingItemLink - - return badGemCount, result -end - --- returns badGemCount and {optimized:[], current:[], badGems[]} -function AskMrRobot.MatchesGems(existingItemLink, existingGemEnchantIds, gems) - local bonus = AmrExpectsSocketBonus(gems) - local reorderedGems = GetBestGems(existingItemLink, gems, bonus) - return GetBadGems(existingItemLink, existingGemEnchantIds, reorderedGems) -end - - -local preferPerfectGems = false - -local function findItemInBag(bagId, itemId) - local numSlots = GetContainerNumSlots(bagId); - local lockedSlotId = nil - for slotId = 1, numSlots do - local _, itemCount, locked, _, _, _, itemLink = GetContainerItemInfo(bagId, slotId); - if itemLink ~= nil then - local bagItemId = AskMrRobot.getItemIdFromLink(itemLink) - if itemId == bagItemId then - if locked then - lockedSlotId = slotId - else - return slotId, false - end - end - end - end - return lockedSlotId, lockedSlotId ~= nil -end - --- returns bagId, badSlotId, isLocked -local function findItem(itemId) - local lockedSlotId, lockedBagId = nil, nil - local bagSlot, locked = findItemInBag(BACKPACK_CONTAINER, itemId) -- backpack - if bagSlot then - if locked then - lockedBagId = BACKPACK_CONTAINER - lockedSlotId = badGems - else - return BACKPACK_CONTAINER, bagSlot, false - end - end - - for bagId = 1, NUM_BAG_SLOTS do - bagSlot, locked = findItemInBag(bagId, itemId) - if locked then - lockedBagId = bagId - lockedSlotId = badGems - elseif bagSlot then - return bagId, bagSlot, false - end - end - - return lockedBagId, lockedSlotId, lockedSlotId ~= nil -end - -local autoGemCoRoutine = nil -local autoGemTime = nil - -local function checkAutoGemTimeout() - if autoGemTime and difftime(time(), autoGemTime) >= 5 then - autoGemTime = nil - autoGemCoRoutine = nil - return true - end - return false -end - -local function autoGemHelper(inventorySlotId, gemInfo, gemSlot) - -- get the gem id to socket - local gemId = gemInfo.optimized[gemSlot].id - - --loop forever until we get the item unlocked - while true do - --if preferPerfectGems then - --end - - -- attempt to find the gem in inventory - local bagId, bagSlot, locked = findItem(gemId) - local dupId = AskMrRobot.gemDuplicates[gemId] - if dupId ~= nil then - local bagId2, bagSlot2, locked2 = findItem(dupId) - if bagId == nil or (bagId2 ~= nil and perfectGems[dupId] == 1 and preferPerfectGems) then - bagId = bagId2 - bagSlot = bagSlot2 - locked = locked2 - end - end - - if locked or IsInventoryItemLocked(inventorySlotId) then - coroutine.yield() - if checkAutoGemTimeout() then - return - end - else - -- if found... - if bagId then - ClearCursor() - -- launch the gem ui with the item - SocketInventoryItem(inventorySlotId) - - if GetNumSockets() < gemSlot then - print('Ask Mr Robot: Something is wrong. There are not enough sockets on this item.') - - CloseSocketInfo() - ClearCursor() - return - end - - -- grab the gem from a bag - PickupContainerItem(bagId, bagSlot) - -- put the gem in the socket - ClickSocketButton(gemSlot) - -- -- save the changes - AcceptSockets() - -- close the UI - CloseSocketInfo() - ClearCursor() - end - break - end - end -end - -local function autoGem() - --http://wowprogramming.com/docs/api_categories#socket - for slotNum, gemInfo in AskMrRobot.sortSlots(AskMrRobot.itemDiffs.gems) do - local inventorySlotId = GetInventorySlotInfo(AskMrRobot.slotNames[slotNum]) - - -- do non-JC gems first - for gemSlot in pairs(gemInfo.badGems) do - if gemInfo.badGems[gemSlot] == true then - local gemId = gemInfo.optimized[gemSlot].id - if not AskMrRobot.JewelcrafterGems[gemId] then - autoGemHelper(inventorySlotId, gemInfo, gemSlot) - end - end - end - end - - for slotNum, gemInfo in AskMrRobot.sortSlots(AskMrRobot.itemDiffs.gems) do - local inventorySlotId = GetInventorySlotInfo(AskMrRobot.slotNames[slotNum]) - - -- do JC gems next - for gemSlot in pairs(gemInfo.badGems) do - if gemInfo.badGems[gemSlot] == true then - local gemId = gemInfo.optimized[gemSlot].id - if AskMrRobot.JewelcrafterGems[gemId] then - autoGemHelper(inventorySlotId, gemInfo, gemSlot) - end - end - end - end -end - -local function resumeAutoGemming() - if not autoGemCoRoutine then - return - end - if coroutine.status(autoGemCoRoutine) == 'dead' then - autoGemCoRoutine = nil - StaticPopup_Show('AUTOGEM_FINISHED') - return - end - if coroutine.status(autoGemCoRoutine) == 'suspended' then - coroutine.resume(autoGemCoRoutine) - if coroutine.status(autoGemCoRoutine) == 'dead' then - autoGemCoRoutine = nil - StaticPopup_Show('AUTOGEM_FINISHED') - end - return - end -end - -function AskMrRobot.AutoGem(preferPerfectGems1) - preferPerfectGems = preferPerfectGems1 - checkAutoGemTimeout() - if autoGemCoRoutine then - if coroutine.status(autoGemCoRoutine) == 'dead' then - autoGemCoRoutine = nil - else - return false - end - end - autoGemTime = time() - autoGemCoRoutine = coroutine.create(autoGem) - resumeAutoGemming() - return true -end - -function AskMrRobot.On_ITEM_UNLOCKED() - resumeAutoGemming() -end - diff -r 9793e8b683d2 -r e77e01abce98 localization/localization.de.lua --- a/localization/localization.de.lua Thu Jul 10 15:32:11 2014 -0700 +++ b/localization/localization.de.lua Mon Oct 13 21:28:32 2014 -0500 @@ -2,7 +2,23 @@ if GetLocale() ~= "deDE" then return end local _, AskMrRobot = ... local L = AskMrRobot.L; +--SlashCmdList.AMR +L.AMR_SLASH_COMMAND_TEXT_1 = 'Available AskMrRobot slash commands:\n' +L.AMR_SLASH_COMMAND_TEXT_2 = ' /amr show -- zeige Fenster\n' +L.AMR_SLASH_COMMAND_TEXT_3 = ' /amr hide -- verstecke Fenster\n' +L.AMR_SLASH_COMMAND_TEXT_4 = ' /amr toggle -- schalte Fenster um' +L.AMR_SLASH_COMMAND_TEXT_5 = ' /amr wipe -- logs a raid wipe. Used to ignore events in the fight after this point\n' +L.AMR_SLASH_COMMAND_TEXT_6 = ' /amr unwipe -- undo the last wipe command\n' +L.AMR_SLASH_COMMAND_TEXT_7 = ' /amr export -- exportiere Beutel- und Bankinhalt (benutzt deine zuletzt gewählte Methode und öffnet entweder das kopieren/einfügen-Fenster oder speichert und lädt die UI neu)' + --AskMrRobotUi.lua + +--createMainMenu +L.AMR_UI_MENU_EXPORT = "Export" +L.AMR_UI_MENU_GEAR = "Load a Gear Set" +L.AMR_UI_MENU_COMBAT_LOG = "Combat Log" +L.AMR_UI_MENU_HELP = "Help" + --validateInput L.AMR_UI_IMPORT_ERROR_IMPROPER = "Ups, du hattest keinen gültigen Importtext" L.AMR_UI_IMPORT_ERROR_IMPROPER_GOTO = "Bitte gehe zurück auf AskMrRobot.com und hole dir die Optimierungen für diesen Charakter" @@ -21,25 +37,18 @@ L.AMR_UI_IMPORT_ERROR_NO_IMPORT = 'Du hast noch keine Optimierungen importiert. Klicke auf den Reiter "Import" um zu starten.' L.AMR_UI_IMPORT_ERROR_CANT_OPTIMIZE = 'Ich kann gerade nicht optimieren. Bitte schaue im Reiter "Übersicht" nach den Gründen.' --createTabButtons -L.AMR_UI_BUTTON_IMPORT = "Import" -L.AMR_UI_BUTTON_SUMMARY = "Übersicht" +L.AMR_UI_BUTTON_IMPORT = "Load" +L.AMR_UI_BUTTON_SUMMARY = "Summary" L.AMR_UI_BUTTON_GEMS = "Edelsteine" L.AMR_UI_BUTTON_ENCHANTS = "Verzauberungen" -L.AMR_UI_BUTTON_REFORGES = "Umschmiedungen" L.AMR_UI_BUTTON_SHOPPING_LIST = "Einkaufsliste" -L.AMR_UI_BUTTON_BEST_IN_BAGS = "Beste im Beutel" L.AMR_UI_BUTTON_COMBAT_LOG = "Kampflog" L.AMR_UI_BUTTON_HELP = "Hilfe" --AskMrRobot.lua --eventListener:OnEvent -L.AMR_ON_EVENT_LOADED = "Ask Mr. Robot geladen, Version %s" +L.AMR_ON_EVENT_LOADED = "Ask Mr. Robot geladen, Version v%s" L.AMR_ON_EVENT_TOOLTIP = "Linksklick öffnet das AskMrRobot Fenster.\n\nShift + Linksklick um deinen Bank- und Beutelinhalt zu exportieren.\n\nCtrl + Linksklick um einen Kampf als wischen markieren." ---SlashCmdList.AMR -L.AMR_SLASH_COMMAND_TEXT_1 = 'Available AskMrRobot slash commands:\n' -L.AMR_SLASH_COMMAND_TEXT_2 = ' /amr show -- zeige Fenster\n' -L.AMR_SLASH_COMMAND_TEXT_3 = ' /amr hide -- verstecke Fenster\n' -L.AMR_SLASH_COMMAND_TEXT_4 = ' /amr toggle -- schalte Fenster um' -L.AMR_SLASH_COMMAND_TEXT_7 = ' /amr export -- exportiere Beutel- und Bankinhalt (benutzt deine zuletzt gewählte Methode und öffnet entweder das kopieren/einfügen-Fenster oder speichert und lädt die UI neu)' + --config.lua --frame:SetScript L.AMR_CONFIG_EXIMPORT = "Mr. Robot's addon kann deine Gegenstandsinformationen auf seine Webseite exportieren und die Optimierungen wieder ins Spiel." @@ -391,21 +400,14 @@ L.AMR_ENCHANTTAB_CURRENT = "Aktuell" L.AMR_ENCHANTTAB_OPTIMIZED = "Optimiert" L.AMR_ENCHANTTAB_TESTSLOT = "TestSlot" +L.AMR_ENCHANTTAB_NOTE = "Hit and expertise have been removed from gear, gems and enchants. If you had hit or expertise anywhere, it has automatically been replaced with another stat." --ui/ExportTab.lua -L.AMR_EXPORTTAB_EXPORT_BB = "Exportiere Ausrüstung für das Beste im Beutel" -L.AMR_EXPORTTAB_COPY_PASTE = "Kopieren/Einfügen" -L.AMR_EXPORTTAB_AMR_CLIENT = "AMR Client" -L.AMR_EXPORTTAB_COPY_PASTE_EXPORT = "KOPIEREN/EINFÜGEN EXPORT" +L.AMR_EXPORTTAB_EXPORT_TITLE = "Export your character to AskMrRobot.com" L.AMR_EXPORTTAB_COPY_PASTE_EXPORT_1 = "1. Öffne deine Bank" L.AMR_EXPORTTAB_COPY_PASTE_EXPORT_2 = "2. Kopiere den Text unterhalb mit Strg+C (oder Cmd+C auf einem Mac)" L.AMR_EXPORTTAB_COPY_PASTE_EXPORT_3 = "3. Gehe auf AskMrRobot.com und kopiere in das IMPORT-Fenster" -L.AMR_EXPORTTAB_COPY_PASTE_EXPORT_4 = "(befindet sich rechts neben deinem Charakternamen im oberen Bereich der Webseite, siehe Screenshot)" L.AMR_EXPORTTAB_COPY_PASTE_EXPORT_NOTE = "Hinweis: Falls du etwas änderst während dieses Fenster offen ist, dann klicke auf Aktualisieren unten." -L.AMR_EXPORTTAB_AMR_CLIENT_EXPORT = "AMR CLIENT EXPORT" -L.AMR_EXPORTTAB_AMR_CLIENT_EXPORT_1 = "1. Öffne deine Bank" -L.AMR_EXPORTTAB_AMR_CLIENT_EXPORT_2 = "2. Klicke auf den Button unten um die AskMrRobot.lua Datei zu aktualisieren" -L.AMR_EXPORTTAB_AMR_CLIENT_EXPORT_3 = "3. Gehe auf AskMrRobot.com und drücke REFRESH" -L.AMR_EXPORTTAB_AMR_CLIENT_EXPORT_4 = "(befindet sich rechts neben deinem Charakternamen im oberen Bereich der Webseite, siehe Screenshot)" + --ui/GemTab.lua --popup autogem finished L.AMR_GEMTAB_FINISHED = "Mr. Robot ist fertig mit dem automatischen sockeln. \rFalls Gegenstände nicht gesockelt wurden, hattest du vielleicht nicht genug Edelsteine. \rSollte dein Gürtel nicht gesockelt sein, fehlt eventuell die Gürtelschnalle." @@ -426,36 +428,27 @@ --ui/HelpTab.lua L.AMR_HELPTAB_TITLE = "Hilfe" L.AMR_HELPTAB_LINK = "Besuche |c003333ffhttp://blog.askmrrobot.com/addon/|r für eine komplette Anleitung und um Fragen zu stellen.\r\r" -L.AMR_HELPTAB_Q1 = "|c00999999Q:|r Muss ich zum Optimieren jedesmal einen neuen Text generieren?\r" -L.AMR_HELPTAB_A1 = '|c0066dd66A:|r Ja. Gehe auf die Webseite und klicke auf das grüne "Update from Armory" links von deinem Charakter damit immer die aktuellsten Daten vorliegen. Optimiere deine Ausrüstung und klicke dann auf "Export to Addon" um deinen neuen Text zu bekommen.\r\r' -L.AMR_HELPTAB_Q2 = "|c00999999Q:|r Die Gürtelschnalle taucht nicht in meiner Liste auf.\r" -L.AMR_HELPTAB_A2 = "|c0066dd66A:|r Korrekt, es ist schwierig diese im Spiel festzustellen. Aber wir arbeiten bereits an einem cleveren Weg sie zu erkennen!\r\r" -L.AMR_HELPTAB_Q3 = "|c00999999Q:|r Meine Zahnräder/Tüftlergetriebe werden nicht angezeigt.\r" -L.AMR_HELPTAB_A3 = "|c0066dd66A:|r Korrekt, wir arbeiten ebenfalls daran diese zu integrieren... das Problem ist, dass Mr. Robot alle aufgebraucht hat um Roboter zu bauen...\r\r" -L.AMR_HELPTAB_Q4 = "|c00999999Q:|r Kann ich meine Einkaufsliste an einen anderen meiner Charaktere schicken?\r" -L.AMR_HELPTAB_A4 = '|c0066dd66A:|r Ja, gehe in den Reiter Einkaufsliste und wähle "Post" als Option im Menü. Du kannst die Liste dann per Post verschicken.\r\r' -L.AMR_HELPTAB_Q5 = "|c00999999Q:|r Ich bin gerade im Raid und habe einen Gegenstand bekommen. Kann ich diesen schnell optimieren?\r" -L.AMR_HELPTAB_A5= "|c0066dd66A:|r Ja! Schaue in diese Anleitung hier: |c003333ffhttp://blog.askmrrobot.com/addon#raid|r" +L.AMR_HELPTAB_Q1 = "|c00999999Q:|r The armory won’t update my character on your website. Is there a workaround?" +L.AMR_HELPTAB_A1 = "|c0066dd66A:|r Yes. Go to the |c00ffd100Export|r section of this addon. Copy the text in the box. Then go to our |c00ffd100website|r, load your character, and click the green '|c0000ff00Import (from addon)|r' button, found just above your character name. Paste the text there. That process takes a snapshot of your current in-game character and imports it to the website!" +L.AMR_HELPTAB_Q2 = "|c00999999Q:|r Do I have to get a new text-string every time I need to optimize?" +L.AMR_HELPTAB_A2 = "|c0066dd66A:|r Yes. Go to the |c00ffd100website|r and click the green '|c0000ff00Update from Armory|r' button found just above your character name, to make sure you have updated gear. Optimize your gear and then click the blue '|c0018C0F7Export to Addon|r' button found to the right of your gear, in the purple '|c00BF28D6Now What?|r section. Return to this |c00ffd100addon|r, go to the '|c00ffd100Load a Gear Set|r' tab and paste the text in the box." +L.AMR_HELPTAB_Q3 = "|c00999999Q:|r Can I send my shopping list to an alt?" +L.AMR_HELPTAB_A3 = '|c0066dd66A:|r Yes, go to the shopping list tab and select the "mail" option in the drop down. You can mail the list to your alt.' +L.AMR_HELPTAB_Q4 = "|c00999999Q:|r I am in the middle of a raid and just won a piece of loot. Can I optimize really quick" +L.AMR_HELPTAB_A4 = "|c0066dd66A:|r Yes! You'll want to read the tutorial on that here: \r|c003333ffhttp://blog.askmrrobot.com/addon#raid" +L.AMR_HELPTAB_Q5 = "|c00999999Q:|r Where is auto gemming?" +L.AMR_HELPTAB_A5 = "|c0066dd66A:|r We have temporarily removed it. We plan to bring it back for WoD" +L.AMR_HELPTAB_Q6 = "|c00999999Q:|r Is Mr. Robot updated?" +L.AMR_HELPTAB_A6 = "|c0066dd66A:|r Yes! For more info, go to \r|c003333ffhttp://blog.askmrrobot.com/2014/10/what-to-do-for-6-0-2/" --ui/ImportTab.lua --new -L.AMR_IMPORTTAB_BUTTON = "Importieren!" -L.AMR_IMPORTTAB_TITLE = "Importiere Mr. Robot's Optimierungen" -L.AMR_IMPORTTAB_INSTRUCTIONS_1 = "1. Geh auf unsere Webseite, optmiere, klicke dann auf den 'export to addon'-Button der oberhalb der Statuswerte zu finden ist." -L.AMR_IMPORTTAB_INSTRUCTIONS_2 = "2. Ein Fenster öffnet sich, kopiere den Text dieses Fensters.\r\r3. Komm hierher zurück und füge den Text in das untere Fenster ein. Zum Kopieren drücke strg + v oder auf einem mac Apfeltaste + v.\r\r4. Klicke dann auf 'Importieren!' unten." -L.AMR_IMPORTTAB_INSTRUCTIONS_3 = "Füge den Text von AskMrRobot.com hier ein." ---ui/ReforgesTab.lua ---popup open reforge -L.AMR_REFORGESTAB_OPEN_WINDOW = "Du musst das Umschmidefenster öffnen, damit dies funktioniert." -L.AMR_REFORGESTAB_BUTTON_OK = "Ok" ---new -L.AMR_REFORGESTAB_TITLE = "Umschmiedungen" -L.AMR_REFORGESTAB_OPTIMAL = "Du bist 100% optimal umgeschmiedet!" -L.AMR_REFORGESTAB_INSTRUCTION = 'Öffne das Umschmiedefenster, klicke dann auf "Umschmieden!" damit dies automatisch ausgeführt wird.' -L.AMR_REFORGESTAB_BUTTON = "Umschmieden!" -L.AMR_REFORGESTAB_SLOT = "Platz" -L.AMR_REFORGESTAB_OPTIMAL_REFORGE = "Optimale Umschmiedung" -L.AMR_REFORGESTAB_RESTORE_THEN = 'Wiederherstellen, dann ' -L.AMR_REFORGESTAB_TOTAL_COST = "Gesamtkosten: ~%d Gold" +L.AMR_IMPORTTAB_BUTTON = "Load Gear" +L.AMR_IMPORTTAB_TITLE = "Load a gear set from the website" +L.AMR_IMPORTTAB_INSTRUCTIONS_1 = "1. Click the blue '|c0018C0F7Send to Addon|r' button on our |c00BF28D6website|r. It's found on the right side in the '|c33ffffffNow What?|r' section. Copy the text in the box that pops up.|n|c00999999To copy, press ctrl + c (or cmd + c on a mac)|r" +L.AMR_IMPORTTAB_INSTRUCTIONS_2 = "2. Then return to this window in the |c00ffd100addon|r. Paste the text in the box below, then click the 'Load Gear' button.|n|c00999999To paste, press ctrl + v in the window (or cmd + v on a mac)|r" +L.AMR_IMPORTTAB_EXPORT_INSTRUCTIONS_1 = "1. Select the text in the box below and copy it.|n|c00999999To copy, press ctrl + c (or cmd + c on a mac)|r" +L.AMR_IMPORTTAB_EXPORT_INSTRUCTIONS_2 = "2. Open your character on our |c00ffd100website|r. Click the green 'import' button found to the left of your characters name. Paste the text in the box the pops up.|n|c00999999To paste: press ctrl + v (or cmd + v on a mac)|r" +L.AMR_IMPORTTAB_EXPORT_NOTE = "NOTE: if you change something while this window is open, press the Update button below to generate a new export string. Make sure you’re recently opened your bags & bank so the addon can scan them." --ui/ShoppingListTab --popup mail L.AMR_SHOPPINGLISTTAB_OPEN_MAIL = "Du muss das Postfenster öffnen, damit dies funktioniert." @@ -500,7 +493,6 @@ L.AMR_SUMMARYTAB_VIEW_TABS = "Schaue in den Edelstein-,Verzauberungs- und Umschmiedungskategorien|n um die vorgeschlagenen Optimierungen zu sehen." L.AMR_SUMMARYTAB_GEMCOUNT = "%d \1244Edelstein:Edelsteine;" L.AMR_SUMMARYTAB_ENCHANTCOUNT = "%d \1244Verzauberung:Verzauberungen;" -L.AMR_SUMMARYTAB_REFORGECOUNT = "%d \1244Umschmiedung:Umschmiedungen;" L.AMR_SUMMARYTAB_OPTIMIZATIONCOUNT = "Du hast %d \1244Optimierung:Optimierungen; zu machen:" L.AMR_SUMMARYTAB_LAST_IMPORT_1 = "Letzer Import: %s\rDiese Optimierungen sind für %s" L.AMR_SUMMARYTAB_LAST_IMPORT_2 = "Letzter Import: %s\rDiese Optimierungen sind für %s's..." @@ -518,3 +510,4 @@ L.AMR_SUMMARYTAB_IMPORT_NOT_WORK = 'Fehler! Dein Import ist fehlgeschlagen:|n|n%s' --ui/RobotStamp.lua L.AMR_ROBOTSTAMP_TEXT = "ROBOT STAMP OF APPROVAL" +L.AMR_ROBOTSTAMP_GEMS = "Your gems are 100% optimal! You are truly, truly outrageous." \ No newline at end of file diff -r 9793e8b683d2 -r e77e01abce98 localization/localization.en.lua --- a/localization/localization.en.lua Thu Jul 10 15:32:11 2014 -0700 +++ b/localization/localization.en.lua Mon Oct 13 21:28:32 2014 -0500 @@ -13,7 +13,58 @@ return f:format(unpack(order)) end +-- stat strings for e.g. displaying gem/enchant abbreviations +L.AMR_STAT_SHORT_STRINGS = { + ["Strength"] = "Str", + ["Agility"] = "Agi", + ["Intellect"] = "Int", + ["CriticalStrike"] = "Crit", + ["Haste"] = "Haste", + ["Mastery"] = "Mastery", + ["Multistrike"] = "Multi", + ["Versatility"] = "Vers", + ["BonusArmor"] = "Armor", + ["Spirit"] = "Spirit", + ["Dodge"] = "Dodge", + ["Parry"] = "Parry", + ["MovementSpeed"] = "Speed", + ["Avoidance"] = "Avoid", + ["Stamina"] = "Stam", + ["Armor"] = "Armor", + ["AttackPower"] = "AP", + ["SpellPower"] = "SP", + ["PvpResilience"] = "PvP Res", + ["PvpPower"] = "PvP Pow", +} + +-- AskMrRobot.lua +L.AMR_IMPORT_ERROR_EMPTY = "The data string is empty." +L.AMR_IMPORT_ERROR_FORMAT = "The data string is not in the correct format." +L.AMR_IMPORT_ERROR_VERSION = "The data string is from an old version of the addon. Please go to the website and generate a new one." +L.AMR_IMPORT_ERROR_CHAR = "The data string is for %s, but you are %s!" +L.AMR_IMPORT_ERROR_RACE = "It looks your race may have changed. Please go the website and re-optimize." +L.AMR_IMPORT_ERROR_FACTION = "It looks your faction may have changed. Please go the website and re-optimize." +L.AMR_IMPORT_ERROR_LEVEL = "It looks your level may have changed. Please go the website and re-optimize." +L.AMR_IMPORT_ERROR_SPEC = "Please change your spec to %s to view this optimization." +L.AMR_IMPORT_ERROR_TALENT = "It looks like your talents may have changed. Please go the website and re-optimize." +L.AMR_IMPORT_ERROR_GLYPH = "It looks like your glyphs may have changed. Please go the website and re-optimize." +--SlashCmdList.AMR +L.AMR_SLASH_COMMAND_TEXT_1 = 'Available AskMrRobot slash commands:\n' +L.AMR_SLASH_COMMAND_TEXT_2 = ' /amr show -- show the main window\n' +L.AMR_SLASH_COMMAND_TEXT_3 = ' /amr hide -- hide the main window\n' +L.AMR_SLASH_COMMAND_TEXT_4 = ' /amr toggle -- toggle the main window\n' +L.AMR_SLASH_COMMAND_TEXT_5 = ' /amr wipe -- logs a raid wipe. Used to ignore events in the fight after this point\n' +L.AMR_SLASH_COMMAND_TEXT_6 = ' /amr unwipe -- undo the last wipe command\n' +L.AMR_SLASH_COMMAND_TEXT_7 = ' /amr export -- export character, bag, and bank data (opens the export copy/paste window)' + --AskMrRobotUi.lua + +--createMainMenu +L.AMR_UI_MENU_EXPORT = "Export" +L.AMR_UI_MENU_GEAR = "Load a Gear Set" +L.AMR_UI_MENU_COMBAT_LOG = "Combat Log" +L.AMR_UI_MENU_HELP = "Help" + --validateInput L.AMR_UI_IMPORT_ERROR_IMPROPER = "Oops, you didn't have proper import text" L.AMR_UI_IMPORT_ERROR_IMPROPER_GOTO = "Please go back to AskMrRobot.com and grab optimizations for this character" @@ -29,30 +80,21 @@ L.AMR_UI_IMPORT_ERROR_SPEC_CHANGE = "Change your spec to %s." L.AMR_UI_IMPORT_ERROR_SPEC_UNEXPECTED = "AskMrRobot.com did not expect to see a specialization." --createImportDetailsErrorTab -L.AMR_UI_IMPORT_ERROR_NO_IMPORT = 'You have no optimizations imported. Click the "Import" tab to get started.' +L.AMR_UI_IMPORT_ERROR_NO_IMPORT = 'You have no optimizations imported. Click the |c00ffd100Load|r tab to get started.' L.AMR_UI_IMPORT_ERROR_CANT_OPTIMIZE = "I can't optimize yet. Please go to the summary tab for more information." ---createTabButtons -L.AMR_UI_BUTTON_IMPORT = "Import" + +L.AMR_UI_BUTTON_IMPORT = "Load" L.AMR_UI_BUTTON_SUMMARY = "Summary" L.AMR_UI_BUTTON_GEMS = "Gems" L.AMR_UI_BUTTON_ENCHANTS = "Enchants" -L.AMR_UI_BUTTON_REFORGES = "Reforges" L.AMR_UI_BUTTON_SHOPPING_LIST = "Shopping List" -L.AMR_UI_BUTTON_BEST_IN_BAGS = "Best in Bags" L.AMR_UI_BUTTON_COMBAT_LOG = "Combat Log" L.AMR_UI_BUTTON_HELP = "Help" --AskMrRobot.lua --eventListener:OnEvent -L.AMR_ON_EVENT_LOADED = "Loaded Ask Mr. Robot %s" +L.AMR_ON_EVENT_LOADED = "Loaded Ask Mr. Robot v%s" L.AMR_ON_EVENT_TOOLTIP = "Left Click to open the Ask Mr. Robot window.\n\nShift + Left Click to export your bag and bank data.\n\nCtrl + Left Click to mark a fight as a wipe." ---SlashCmdList.AMR -L.AMR_SLASH_COMMAND_TEXT_1 = 'Available AskMrRobot slash commands:\n' -L.AMR_SLASH_COMMAND_TEXT_2 = ' /amr show -- show the main window\n' -L.AMR_SLASH_COMMAND_TEXT_3 = ' /amr hide -- hide the main window\n' -L.AMR_SLASH_COMMAND_TEXT_4 = ' /amr toggle -- toggle the main window\n' -L.AMR_SLASH_COMMAND_TEXT_5 = ' /amr wipe -- logs a raid wipe. Used to ignore events in the fight after this point\n' -L.AMR_SLASH_COMMAND_TEXT_6 = ' /amr unwipe -- undo the last wipe command\n' -L.AMR_SLASH_COMMAND_TEXT_7 = ' /amr export -- export bag and bank data (uses your last selected method and either opens the copy/paste window, or saves and reloads ui)' + --config.lua --frame:SetScript L.AMR_CONFIG_EXIMPORT = "Mr. Robot's addon can export your item information to his website, and import your optimizations into the game." @@ -404,21 +446,14 @@ L.AMR_ENCHANTTAB_CURRENT = "Current" L.AMR_ENCHANTTAB_OPTIMIZED = "Optimized" L.AMR_ENCHANTTAB_TESTSLOT = "TestSlot" +L.AMR_ENCHANTTAB_NOTE = "Hit and expertise have been removed from gear, gems and enchants. If you had hit or expertise anywhere, it has automatically been replaced with another stat." --ui/ExportTab.lua -L.AMR_EXPORTTAB_EXPORT_BB = "Export Gear for Best in Bags" -L.AMR_EXPORTTAB_COPY_PASTE = "Copy/Paste" -L.AMR_EXPORTTAB_AMR_CLIENT = "AMR Client" -L.AMR_EXPORTTAB_COPY_PASTE_EXPORT = "COPY/PASTE EXPORT" +L.AMR_EXPORTTAB_EXPORT_TITLE = "Export your character to AskMrRobot.com" L.AMR_EXPORTTAB_COPY_PASTE_EXPORT_1 = "1. Open your bank" L.AMR_EXPORTTAB_COPY_PASTE_EXPORT_2 = "2. Copy the text below by pressing Ctrl+C (or Cmd+C on a Mac)" -L.AMR_EXPORTTAB_COPY_PASTE_EXPORT_3 = "3. Go to AskMrRobot.com and paste into the IMPORT window" -L.AMR_EXPORTTAB_COPY_PASTE_EXPORT_4 = "(located to the right of your character name near the top of the web page, see screenshot)" +L.AMR_EXPORTTAB_COPY_PASTE_EXPORT_3 = "3. Go to |c00ffd100AskMrRobot.com|r and click the green '|c0000ff00Import from Armory|r' button found just above your character name. Paste the text into the window that pops up." L.AMR_EXPORTTAB_COPY_PASTE_EXPORT_NOTE = "NOTE: If you change something while this window is open, press the Update button below to generate a new export string." -L.AMR_EXPORTTAB_AMR_CLIENT_EXPORT = "AMR CLIENT EXPORT" -L.AMR_EXPORTTAB_AMR_CLIENT_EXPORT_1 = "1. Open your bank" -L.AMR_EXPORTTAB_AMR_CLIENT_EXPORT_2 = "2. Press the button below to update your AskMrRobot.lua file" -L.AMR_EXPORTTAB_AMR_CLIENT_EXPORT_3 = "3. Go to AskMrRobot.com and press REFRESH" -L.AMR_EXPORTTAB_AMR_CLIENT_EXPORT_4 = "(located to the right of your character name near the top of the web page, see screenshot:)" + --ui/GemTab.lua --popup autogem finished L.AMR_GEMTAB_FINISHED = "Mr. Robot finished auto-gemming. \rIf some items aren't gemmed, you may need to acquire more gems. \rIf your belt isn't gemmed, you may still need to buy a belt buckle." @@ -434,41 +469,33 @@ L.AMR_GEMTAB_SLOT = "Slot" L.AMR_GEMTAB_CURRENT = "Current" L.AMR_GEMTAB_OPTIMIZED = "Optimized" +L.AMR_GEMTAB_NOTE = "Hit and expertise have been removed from gear, gems and enchants. If you had hit or expertise anywhere, it has automatically been replaced with another stat." --Update L.AMR_GEMTAB_TO_OPTIMIZE = "You have %d \1244gem:gems; to optimize" --ui/HelpTab.lua L.AMR_HELPTAB_TITLE = "Help" -L.AMR_HELPTAB_LINK = "Visit |c003333ffhttp://blog.askmrrobot.com/addon/|r for a full tutorial and to ask questions.\r\r" -L.AMR_HELPTAB_Q1 = "|c00999999Q:|r Do I have to get a new text-string every time I need to optimize?\r" -L.AMR_HELPTAB_A1 = '|c0066dd66A:|r Yes. Go to the website and click the green "Update from Armory" button to the left of your character to make sure you have the most up-to-date gear. Optimize your gear and then click the "Export to Addon" button to get your new text-string.\r\r' -L.AMR_HELPTAB_Q2 = "|c00999999Q:|r The belt buckle didn't show up in my list.\r" -L.AMR_HELPTAB_A2 = "|c0066dd66A:|r Correct, it's actually quite hard to detect it's status in-game, believe it or not. But we're working on a clever way to detect it!\r\r" -L.AMR_HELPTAB_Q3 = "|c00999999Q:|r My cogwheels/tinkers didn't show up.\r" -L.AMR_HELPTAB_A3 = "|c0066dd66A:|r Correct, we're working on adding those into the list as well... the problem is Mr. Robot has been using them to build other robots...\r\r" -L.AMR_HELPTAB_Q4 = "|c00999999Q:|r Can I send my shopping list to an alt?\r" -L.AMR_HELPTAB_A4 = '|c0066dd66A:|r Yes, go to the shopping list tab and select the "mail" option in the drop down. You can mail the list to your alt.\r\r' -L.AMR_HELPTAB_Q5 = "|c00999999Q:|r I am in the middle of a raid and just won a piece of loot. Can I optimize really quick\r" -L.AMR_HELPTAB_A5= "|c0066dd66A:|r Yes! You'll want to read the tutorial on that here: |c003333ffhttp://blog.askmrrobot.com/addon#raid|r" +L.AMR_HELPTAB_LINK = "Visit |c003333ffhttp://blog.askmrrobot.com/addon/|r for a full tutorial and to ask questions.\r" +L.AMR_HELPTAB_Q1 = "|c00999999Q:|r The armory won’t update my character on your website. Is there a workaround?" +L.AMR_HELPTAB_A1 = "|c0066dd66A:|r Yes. Go to the |c00ffd100Export|r section of this addon. Copy the text in the box. Then go to our |c00ffd100website|r, load your character, and click the green '|c0000ff00Import (from addon)|r' button, found just above your character name. Paste the text there. That process takes a snapshot of your current in-game character and imports it to the website!" +L.AMR_HELPTAB_Q2 = "|c00999999Q:|r Do I have to get a new text-string every time I need to optimize?" +L.AMR_HELPTAB_A2 = "|c0066dd66A:|r Yes. Go to the |c00ffd100website|r and click the green '|c0000ff00Update from Armory|r' button found just above your character name, to make sure you have updated gear. Optimize your gear and then click the blue '|c0018C0F7Export to Addon|r' button found to the right of your gear, in the purple '|c00BF28D6Now What?|r section. Return to this |c00ffd100addon|r, go to the '|c00ffd100Load a Gear Set|r' tab and paste the text in the box." +L.AMR_HELPTAB_Q3 = "|c00999999Q:|r Can I send my shopping list to an alt?" +L.AMR_HELPTAB_A3 = '|c0066dd66A:|r Yes, go to the shopping list tab and select the "mail" option in the drop down. You can mail the list to your alt.' +L.AMR_HELPTAB_Q4 = "|c00999999Q:|r I am in the middle of a raid and just won a piece of loot. Can I optimize really quick" +L.AMR_HELPTAB_A4 = "|c0066dd66A:|r Yes! You'll want to read the tutorial on that here: \r|c003333ffhttp://blog.askmrrobot.com/addon#raid" +L.AMR_HELPTAB_Q5 = "|c00999999Q:|r Where is auto gemming?" +L.AMR_HELPTAB_A5 = "|c0066dd66A:|r We have temporarily removed it. We plan to bring it back for WoD" +L.AMR_HELPTAB_Q6 = "|c00999999Q:|r Is Mr. Robot updated?" +L.AMR_HELPTAB_A6 = "|c0066dd66A:|r Yes! For more info, go to \r|c003333ffhttp://blog.askmrrobot.com/2014/10/what-to-do-for-6-0-2/" --ui/ImportTab.lua --new -L.AMR_IMPORTTAB_BUTTON = "Import!" -L.AMR_IMPORTTAB_TITLE = "Import Mr. Robot's optimizations" -L.AMR_IMPORTTAB_INSTRUCTIONS_1 = "1. Go to our website, optimize, then click the 'export to addon' button found just above the stats section." -L.AMR_IMPORTTAB_INSTRUCTIONS_2 = "2. A window will popup, copy the text from that window.\r\r3. Return here and paste the text into the window below. To paste it, hold ctrl + v, or on a mac apple + v.\r\r4. Click the 'Import' button below" -L.AMR_IMPORTTAB_INSTRUCTIONS_3 = "Paste text from AskMrRobot.com here." ---ui/ReforgesTab.lua ---popup open reforge -L.AMR_REFORGESTAB_OPEN_WINDOW = "You need to open the reforge window for this to work" -L.AMR_REFORGESTAB_BUTTON_OK = "Ok" ---new -L.AMR_REFORGESTAB_TITLE = "Reforges" -L.AMR_REFORGESTAB_OPTIMAL = "Your reforges are 100% optimal!" -L.AMR_REFORGESTAB_INSTRUCTION = 'Open a reforge window, then click the "Reforge!" button to do it automatically.' -L.AMR_REFORGESTAB_BUTTON = "Reforge!" -L.AMR_REFORGESTAB_SLOT = "Slot" -L.AMR_REFORGESTAB_OPTIMAL_REFORGE = "Optimal Reforge" -L.AMR_REFORGESTAB_RESTORE_THEN = 'Restore, then ' -L.AMR_REFORGESTAB_TOTAL_COST = "Total reforge cost: ~%d Gold" +L.AMR_IMPORTTAB_BUTTON = "Load Gear" +L.AMR_IMPORTTAB_TITLE = "Load a gear set from the website" +L.AMR_IMPORTTAB_INSTRUCTIONS_1 = "1. Click the blue '|c0018C0F7Send to Addon|r' button on our |c00BF28D6website|r. It's found on the right side in the '|c33ffffffNow What?|r' section. Copy the text in the box that pops up.|n|c00999999To copy, press ctrl + c (or cmd + c on a mac)|r" +L.AMR_IMPORTTAB_INSTRUCTIONS_2 = "2. Then return to this window in the |c00ffd100addon|r. Paste the text in the box below, then click the 'Load Gear' button.|n|c00999999To paste, press ctrl + v in the window (or cmd + v on a mac)|r" +L.AMR_IMPORTTAB_EXPORT_INSTRUCTIONS_1 = "1. Select the text in the box below and copy it.|n|c00999999To copy, press ctrl + c (or cmd + c on a mac)|r" +L.AMR_IMPORTTAB_EXPORT_INSTRUCTIONS_2 = "2. Open your character on our |c00ffd100website|r. Click the green 'import' button found to the left of your characters name. Paste the text in the box the pops up.|n|c00999999To paste: press ctrl + v (or cmd + v on a mac)|r" +L.AMR_IMPORTTAB_EXPORT_NOTE = "NOTE: if you change something while this window is open, press the Update button below to generate a new export string. Make sure you’re recently opened your bags & bank so the addon can scan them." --ui/ShoppingListTab --popup mail L.AMR_SHOPPINGLISTTAB_OPEN_MAIL = "You need to open the mail window for this to work" @@ -500,7 +527,7 @@ --ui/SummaryTab.lua L.AMR_SUMMARYTAB_TITLE = "Summary" L.AMR_SUMMARYTAB_NO_IMPORT = "You have no optimizations imported." -L.AMR_SUMMARYTAB_GET_STARTED = 'Click the "Import" tab to get started.' +L.AMR_SUMMARYTAB_GET_STARTED = 'Click the |c00ffd100Load|r tab to get started.' L.AMR_SUMMARYTAB_GO_UPGRADE = "Please upgrade the following items:" L.AMR_SUMMARYTAB_SLOT = "Slot" L.AMR_SUMMARYTAB_ITEM_NAME = "Item Name" @@ -510,10 +537,9 @@ L.AMR_SUMMARYTAB_GEMS_TO_GO = "? gems" L.AMR_SUMMARYTAB_ENCHANTS_TO_GO = "? enchants" L.AMR_SUMMARYTAB_REFORGES_TO_GO = "? reforges" -L.AMR_SUMMARYTAB_VIEW_TABS = "View the Gem, Enchant and Reforge tabs for suggested optimizations." +L.AMR_SUMMARYTAB_VIEW_TABS = "View the Gem and Enchant tabs for suggested optimizations." L.AMR_SUMMARYTAB_GEMCOUNT = "%d \1244gem:gems;" L.AMR_SUMMARYTAB_ENCHANTCOUNT = "%d \1244enchant:enchants;" -L.AMR_SUMMARYTAB_REFORGECOUNT = "%d \1244reforge:reforges;" L.AMR_SUMMARYTAB_OPTIMIZATIONCOUNT = "You have %d \1244optimization:optimizations; to make:" L.AMR_SUMMARYTAB_LAST_IMPORT_1 = "Last import: %s\rThese optimizations are for %s" L.AMR_SUMMARYTAB_LAST_IMPORT_2 = "Last import: %s\rThese optimizations are for %s's..." diff -r 9793e8b683d2 -r e77e01abce98 sort.lua --- a/sort.lua Thu Jul 10 15:32:11 2014 -0700 +++ b/sort.lua Mon Oct 13 21:28:32 2014 -0500 @@ -22,10 +22,3 @@ end end end - -function AskMrRobot.sortSlots(t) - return AskMrRobot.spairs(t, function(x, a, b) - if a == nil and b == nil then return 0 end - return AskMrRobot.sortedSlots[a] < AskMrRobot.sortedSlots[b] - end) -end diff -r 9793e8b683d2 -r e77e01abce98 ui/CombatLogTab.lua --- a/ui/CombatLogTab.lua Thu Jul 10 15:32:11 2014 -0700 +++ b/ui/CombatLogTab.lua Mon Oct 13 21:28:32 2014 -0500 @@ -1,10 +1,10 @@ local _, AskMrRobot = ... local L = AskMrRobot.L; --- initialize the ExportTab class +-- initialize the CombatLogTab class AskMrRobot.CombatLogTab = AskMrRobot.inheritsFrom(AskMrRobot.Frame) --- these are valid keys in AmrLogData, all others will be deleted +-- these are valid keys in AmrDb.LogData, all others will be deleted local _logDataKeys = { ["_logging"] = true, ["_autoLog"] = true, @@ -88,17 +88,17 @@ L.AMR_COMBATLOGTAB_CHECKBOX_AUTOLOG_SOO_DESCRIPTION, function(self, value) if value then - AmrLogData._autoLog[AskMrRobot.instanceIds.SiegeOfOrgrimmar] = "enabled" + AmrDb.LogData._autoLog[AskMrRobot.instanceIds.SiegeOfOrgrimmar] = "enabled" else - AmrLogData._autoLog[AskMrRobot.instanceIds.SiegeOfOrgrimmar] = "disabled" + AmrDb.LogData._autoLog[AskMrRobot.instanceIds.SiegeOfOrgrimmar] = "disabled" end - AmrLogData._lastZone = nil - AmrLogData._lastDiff = nil + AmrDb.LogData._lastZone = nil + AmrDb.LogData._lastDiff = nil tab:UpdateAutoLogging() end ) - autoChk:SetChecked(AmrLogData._autoLog[AskMrRobot.instanceIds.SiegeOfOrgrimmar] == "enabled") + autoChk:SetChecked(AmrDb.LogData._autoLog[AskMrRobot.instanceIds.SiegeOfOrgrimmar] == "enabled") autoChk:SetPoint("TOPLEFT", btn, "BOTTOMLEFT", 0, -10) autoChk:SetHeight(30) @@ -171,18 +171,18 @@ local t = time() AskMrRobot.SaveAll() AskMrRobot.ExportToAddonChat(t) - AskMrRobot.ExportLoggingData(t) + AskMrRobot.CombatLogTab.SaveExtras(t) end) ]] -- when we start up, ensure that logging is still enabled if it was enabled when they last used the addon - if (tab:IsLogging()) then + if (AskMrRobot.CombatLogTab.IsLogging()) then SetCVar("advancedCombatLogging", 1) LoggingCombat(true) end -- if auto-logging is enabled, do a check when the addon is loaded to make sure that state is set correctly - if AmrLogData._autoLog[AskMrRobot.instanceIds.SiegeOfOrgrimmar] == "enabled" then + if AmrDb.LogData._autoLog[AskMrRobot.instanceIds.SiegeOfOrgrimmar] == "enabled" then tab:UpdateAutoLogging() end @@ -193,8 +193,8 @@ return tab end -function AskMrRobot.CombatLogTab:IsLogging() - return AmrLogData._logging == true +function AskMrRobot.CombatLogTab.IsLogging() + return AmrDb.LogData._logging == true end function AskMrRobot.CombatLogTab:StartLogging() @@ -203,19 +203,19 @@ local oldDuration = 60 * 60 * 24 * 10 -- archive the current logging session so that users don't accidentally blow away data before uploading it - if AmrLogData._current2 ~= nil then - if not AmrLogData._history2 then AmrLogData._history2 = {} end + if AmrDb.LogData._current2 ~= nil then + if not AmrDb.LogData._history2 then AmrDb.LogData._history2 = {} end -- add new entries - for name, timeList in AskMrRobot.spairs(AmrLogData._current2) do - if not AmrLogData._history2[name] then AmrLogData._history2[name] = {} end + for name, timeList in AskMrRobot.spairs(AmrDb.LogData._current2) do + if not AmrDb.LogData._history2[name] then AmrDb.LogData._history2[name] = {} end for timestamp, dataString in AskMrRobot.spairs(timeList) do - AmrLogData._history2[name][timestamp] = dataString + AmrDb.LogData._history2[name][timestamp] = dataString end end -- delete entries that are more than 10 days old - for name, timeList in AskMrRobot.spairs(AmrLogData._history2) do + for name, timeList in AskMrRobot.spairs(AmrDb.LogData._history2) do for timestamp, dataString in AskMrRobot.spairs(timeList) do if difftime(now, tonumber(timestamp)) > oldDuration then timeList[timestamp] = nil @@ -227,25 +227,25 @@ count = count + 1 end if count == 0 then - AmrLogData._history2[name] = nil + AmrDb.LogData._history2[name] = nil end end end -- same idea with extra info (auras, pets, whatever we end up adding to it) - if AmrLogData._currentExtra ~= nil then - if not AmrLogData._historyExtra then AmrLogData._historyExtra = {} end + if AmrDb.LogData._currentExtra ~= nil then + if not AmrDb.LogData._historyExtra then AmrDb.LogData._historyExtra = {} end -- add new entries - for name, timeList in AskMrRobot.spairs(AmrLogData._currentExtra) do - if not AmrLogData._historyExtra[name] then AmrLogData._historyExtra[name] = {} end + for name, timeList in AskMrRobot.spairs(AmrDb.LogData._currentExtra) do + if not AmrDb.LogData._historyExtra[name] then AmrDb.LogData._historyExtra[name] = {} end for timestamp, dataString in AskMrRobot.spairs(timeList) do - AmrLogData._historyExtra[name][timestamp] = dataString + AmrDb.LogData._historyExtra[name][timestamp] = dataString end end -- delete entries that are more than 10 days old - for name, timeList in AskMrRobot.spairs(AmrLogData._historyExtra) do + for name, timeList in AskMrRobot.spairs(AmrDb.LogData._historyExtra) do for timestamp, dataString in AskMrRobot.spairs(timeList) do if difftime(now, tonumber(timestamp)) > oldDuration then timeList[timestamp] = nil @@ -257,19 +257,19 @@ count = count + 1 end if count == 0 then - AmrLogData._historyExtra[name] = nil + AmrDb.LogData._historyExtra[name] = nil end end end -- delete _wipes entries that are more than 10 days old - if AmrLogData._wipes then + if AmrDb.LogData._wipes then local i = 1 - while i <= #AmrLogData._wipes do - local t = AmrLogData._wipes[i] + while i <= #AmrDb.LogData._wipes do + local t = AmrDb.LogData._wipes[i] if difftime(now, t) > oldDuration then - tremove(AmrLogData._wipes, i) + tremove(AmrDb.LogData._wipes, i) else i = i + 1 end @@ -277,21 +277,21 @@ end -- delete the _lastWipe if it is more than 10 days old - if AmrLogData._lastWipe and difftime(now, AmrLogData._lastWipe) > oldDuration then - AmrLogData_lastWipe = nil + if AmrDb.LogData._lastWipe and difftime(now, AmrDb.LogData._lastWipe) > oldDuration then + AmrDb.LogData_lastWipe = nil end -- clean up old-style logging data from previous versions of the addon - for k, v in AskMrRobot.spairs(AmrLogData) do + for k, v in AskMrRobot.spairs(AmrDb.LogData) do if not _logDataKeys[k] then - AmrLogData[k] = nil + AmrDb.LogData[k] = nil end end -- start a new logging session - AmrLogData._current2 = {} - AmrLogData._currentExtra = {} - AmrLogData._logging = true + AmrDb.LogData._current2 = {} + AmrDb.LogData._currentExtra = {} + AmrDb.LogData._logging = true -- always enable advanced combat logging via our addon, gathers more detailed data for better analysis SetCVar("advancedCombatLogging", 1) @@ -306,7 +306,7 @@ function AskMrRobot.CombatLogTab:StopLogging() LoggingCombat(false) - AmrLogData._logging = false + AmrDb.LogData._logging = false self:Update() AskMrRobot.AmrUpdateMinimap() @@ -315,7 +315,7 @@ end function AskMrRobot.CombatLogTab:ToggleLogging() - if self:IsLogging() then + if AskMrRobot.CombatLogTab.IsLogging() then self:StopLogging() else self:StartLogging() @@ -324,7 +324,7 @@ -- update the panel and state function AskMrRobot.CombatLogTab:Update() - local isLogging = self:IsLogging() + local isLogging = AskMrRobot.CombatLogTab.IsLogging() if isLogging then self.btnStart:SetText(L.AMR_COMBATLOGTAB_STOP_LOGGING) @@ -334,8 +334,8 @@ self.loggingStatus:SetText("") end - if AmrLogData._lastWipe then - self.lastWipeLabel:SetText(L.AMR_COMBATLOGTAB_LASTWIPE:format(date('%B %d', AmrLogData._lastWipe), date('%I:%M %p', AmrLogData._lastWipe))) + if AmrDb.LogData._lastWipe then + self.lastWipeLabel:SetText(L.AMR_COMBATLOGTAB_LASTWIPE:format(date('%B %d', AmrDb.LogData._lastWipe), date('%I:%M %p', AmrDb.LogData._lastWipe))) self.btnUnwipe:Show() else self.lastWipeLabel:SetText("") @@ -356,23 +356,23 @@ --zonetype = "scenario" --end - if zone == AmrLogData._lastZone and difficultyIndex == AmrLogData._lastDiff then + if zone == AmrDb.LogData._lastZone and difficultyIndex == AmrDb.LogData._lastDiff then -- do nothing if the zone hasn't actually changed, otherwise we may override the user's manual enable/disable return end - AmrLogData._lastZone = zone - AmrLogData._lastDiff = difficultyIndex + AmrDb.LogData._lastZone = zone + AmrDb.LogData._lastDiff = difficultyIndex - if AmrLogData._autoLog[AskMrRobot.instanceIds.SiegeOfOrgrimmar] == "enabled" then + if AmrDb.LogData._autoLog[AskMrRobot.instanceIds.SiegeOfOrgrimmar] == "enabled" then if tonumber(instanceMapID) == AskMrRobot.instanceIds.SiegeOfOrgrimmar then -- if in SoO, make sure logging is on - if not self:IsLogging() then + if not AskMrRobot.CombatLogTab.IsLogging() then self:StartLogging() end else -- not in SoO, turn logging off - if self:IsLogging() then + if AskMrRobot.CombatLogTab.IsLogging() then self:StopLogging() end end @@ -388,52 +388,105 @@ end end --- used to store wipes to AmrLogData so that we trim data after the wipe +-- used to store wipes to AmrDb.LogData so that we trim data after the wipe function AskMrRobot.CombatLogTab:LogWipe() local t = time() - tinsert(AmrLogData._wipes, t) - AmrLogData._lastWipe = t + tinsert(AmrDb.LogData._wipes, t) + AmrDb.LogData._lastWipe = t - if GetNumGroupMembers() > 0 then - SendChatMessage(L.AMR_COMBATLOGTAB_WIPE_CHAT, RaidChatType()) - end + --if GetNumGroupMembers() > 0 then + -- SendChatMessage(L.AMR_COMBATLOGTAB_WIPE_CHAT, RaidChatType()) + --end print(string.format(L.AMR_COMBATLOGTAB_WIPE_MSG, date('%I:%M %p', t))) self:Update() - --AskMrRobot.wait(301, AskMrRobot.CombatLogTab.Update, self) end -- used to undo the wipe command function AskMrRobot.CombatLogTab:LogUnwipe() - local t = AmrLogData._lastWipe + local t = AmrDb.LogData._lastWipe if not t then print(L.AMR_COMBATLOGTAB_NOWIPES) else - tremove(AmrLogData._wipes) - AmrLogData._lastWipe = nil + tremove(AmrDb.LogData._wipes) + AmrDb.LogData._lastWipe = nil print(string.format(L.AMR_COMBATLOGTAB_UNWIPE_MSG, date('%I:%M %p', t))) end self:Update() end --- initialize the AmrLogData variable +-- initialize the AmrDb.LogData variable function AskMrRobot.CombatLogTab.InitializeVariable() - if not AmrLogData then AmrLogData = {} end - if not AmrLogData._autoLog then AmrLogData._autoLog = {} end - if not AmrLogData._autoLog[AskMrRobot.instanceIds.SiegeOfOrgrimmar] then - AmrLogData._autoLog[AskMrRobot.instanceIds.SiegeOfOrgrimmar] = "disabled" + if not AmrDb.LogData then AmrDb.LogData = {} end + if not AmrDb.LogData._autoLog then AmrDb.LogData._autoLog = {} end + if not AmrDb.LogData._autoLog[AskMrRobot.instanceIds.SiegeOfOrgrimmar] then + AmrDb.LogData._autoLog[AskMrRobot.instanceIds.SiegeOfOrgrimmar] = "disabled" end - AmrLogData._wipes = AmrLogData._wipes or {} + AmrDb.LogData._wipes = AmrDb.LogData._wipes or {} end -function AskMrRobot.CombatLogTab.SaveExtras(data, timestamp) +local function GetPlayerExtraData(data, index) + local unitId = "raid" .. index + + local guid = UnitGUID(unitId) + if guid == nil then + return nil + end + + local fields = {} + + local buffs = {} + for i=1,40 do + local _,_,_,count,_,_,_,_,_,_,spellId = UnitAura(unitId, i, "HELPFUL") + table.insert(buffs, spellId) + end + if #buffs == 0 then + table.insert(fields, "_") + else + table.insert(fields, AskMrRobot.toCompressedNumberList(buffs)) + end + + local petGuid = UnitGUID("raidpet" .. index) + if petGuid then + table.insert(fields, guid .. "," .. petGuid) + else + table.insert(fields, '_') + end + + local name = GetRaidRosterInfo(index) + local realm = GetRealmName() + local splitPos = string.find(name, "-") + if splitPos ~= nil then + realm = string.sub(name, splitPos + 1) + name = string.sub(name, 1, splitPos - 1) + end + + data[realm .. ":" .. name] = table.concat(fields, ";") +end + +function AskMrRobot.CombatLogTab.SaveExtras(timestamp) + + if not AskMrRobot.CombatLogTab.IsLogging() then + return + end + + -- we only get extra information for people if in a raid + if not IsInRaid() then + return + end + + local data = {} + for i = 1,40 do + GetPlayerExtraData(data, i) + end + for name,val in pairs(data) do -- record aura stuff, we never check for duplicates, need to know it at each point in time - if AmrLogData._currentExtra[name] == nil then - AmrLogData._currentExtra[name] = {} + if AmrDb.LogData._currentExtra[name] == nil then + AmrDb.LogData._currentExtra[name] = {} end - AmrLogData._currentExtra[name][timestamp] = val + AmrDb.LogData._currentExtra[name][timestamp] = val end end @@ -452,32 +505,32 @@ if (data == "done") then -- we have finished receiving this message; now process it to reduce the amount of duplicate data - local setup = AmrLogData._current2[name][timestamp] + local setup = AmrDb.LogData._current2[name][timestamp] - if (AmrLogData._previousSetup == nil) then - AmrLogData._previousSetup = {} + if (AmrDb.LogData._previousSetup == nil) then + AmrDb.LogData._previousSetup = {} end - local previousSetup = AmrLogData._previousSetup[name] + local previousSetup = AmrDb.LogData._previousSetup[name] if (previousSetup == setup) then -- if the last-seen setup for this player is the same as the current one, we don't need this entry - AmrLogData._current2[name][timestamp] = nil + AmrDb.LogData._current2[name][timestamp] = nil else -- record the last-seen setup - AmrLogData._previousSetup[name] = setup + AmrDb.LogData._previousSetup[name] = setup end else -- concatenate messages with the same timestamp+name - if (AmrLogData._current2[name] == nil) then - AmrLogData._current2[name] = {} + if (AmrDb.LogData._current2[name] == nil) then + AmrDb.LogData._current2[name] = {} end - if (AmrLogData._current2[name][timestamp] == nil) then - AmrLogData._current2[name][timestamp] = data + if (AmrDb.LogData._current2[name][timestamp] == nil) then + AmrDb.LogData._current2[name][timestamp] = data else - AmrLogData._current2[name][timestamp] = AmrLogData._current2[name][timestamp] .. data + AmrDb.LogData._current2[name][timestamp] = AmrDb.LogData._current2[name][timestamp] .. data end end end diff -r 9793e8b683d2 -r e77e01abce98 ui/Components.lua --- a/ui/Components.lua Thu Jul 10 15:32:11 2014 -0700 +++ b/ui/Components.lua Mon Oct 13 21:28:32 2014 -0500 @@ -77,11 +77,6 @@ end end -function AskMrRobot.getItemIdFromLink(item) - if not item then return 0 end - local id = tonumber (item:match ("item:(%d+):%d+:%d+:%d+:%d+:%d+:%-?%d+:%-?%d+:%d+:%d+")) - return (id and id ~= 0 and id or 0) -end -- initialize the Frame class (inherit from a dummy frame) AskMrRobot.Frame = AskMrRobot.inheritsFrom(CreateFrame("Frame")) @@ -97,37 +92,3 @@ -- return the instance of the Frame return o end - -local MAINHAND = nil -local OFFHAND = nil - -AskMrRobot.slotNames = {"HeadSlot", "NeckSlot", "ShoulderSlot", "BackSlot", "ChestSlot", "ShirtSlot", "TabardSlot", "WristSlot", "HandsSlot", "WaistSlot", "LegsSlot", "FeetSlot", "Finger0Slot", "Finger1Slot", "Trinket0Slot", "Trinket1Slot", "MainHandSlot", "SecondaryHandSlot", "AmmoSlot" }; -AskMrRobot.OptimizationSlots = {} -AskMrRobot.slotIdToSlotNum = {} -AskMrRobot.slotIds = {}; -for slotNum = 1, #AskMrRobot.slotNames do - local slotId = GetInventorySlotInfo(AskMrRobot.slotNames[slotNum]) - AskMrRobot.slotIds[slotNum] = slotId - AskMrRobot.slotIdToSlotNum[slotId] = slotNum - local slotName = AskMrRobot.slotNames[slotNum] - if slotName == "MainHandSlot" then - MAINHAND = slotNum - end - if slotName == "SecondaryHandSlot" then - OFFHAND = slotNum - end - if slotName ~= "TabardSlot" and slotName ~= "AmmoSlot" and slotName ~= "ShirtSlot" then - AskMrRobot.OptimizationSlots[slotNum] = true - end - -end - -AskMrRobot.sortedSlots = {[MAINHAND] = 1, [OFFHAND] = 2} - -local i = 3 -for slotNum = 1, #AskMrRobot.slotNames do - if slotNum ~= MAINHAND and slotNum ~= OFFHAND then - AskMrRobot.sortedSlots[slotNum] = i - i = i + 1 - end -end \ No newline at end of file diff -r 9793e8b683d2 -r e77e01abce98 ui/EnchantLinkText.lua --- a/ui/EnchantLinkText.lua Thu Jul 10 15:32:11 2014 -0700 +++ b/ui/EnchantLinkText.lua Mon Oct 13 21:28:32 2014 -0500 @@ -18,22 +18,29 @@ end function AskMrRobot.EnchantLinkText:SetEnchantId(enchantId) - self.itemName = nil + --self.itemName = nil if enchantId and enchantId ~= 0 then - local spellId = AskMrRobot.getEnchantSpellId(enchantId) + local enchantData = AskMrRobot.ExtraEnchantData[enchantId]; + local spellId = enchantData and enchantData.spellId local link = nil if spellId then link = 'enchant:' .. spellId end self:SetItemLink(link) - if self.useSpellName then - local spellName = spellId and select(1, GetSpellInfo(spellId)) - self.itemText:SetText(spellName) - self.itemName = spellName + if enchantData then + self.itemText:SetText(enchantData.text) else - self.itemName = AskMrRobot.getEnchantName(enchantId) - self.itemText:SetText(self.itemName) + --self.itemText:SetText(enchantId) + self.itemText:SetText('unknown') end + -- if self.useSpellName then + -- local spellName = spellId and select(1, GetSpellInfo(spellId)) + -- self.itemText:SetText(spellName) + -- self.itemName = spellName + -- else + -- self.itemName = AskMrRobot.getEnchantName(enchantId) + -- self.itemText:SetText(self.itemName) + -- end else self:SetItemLink(nil) self.itemText:SetText('') @@ -83,8 +90,19 @@ function AskMrRobot.EnchantLinkIconAndText:SetEnchantId(enchantId) AskMrRobot.EnchantLinkText.SetEnchantId(self, enchantId) if enchantId and enchantId ~= 0 then - local texture = AskMrRobot.getEnchantIcon(enchantId) - self.icon:SetTexture('Interface/Icons/' .. texture) + --local texture = AskMrRobot.getEnchantIcon(enchantId) + --self.icon:SetTexture('Interface/Icons/' .. texture) + local enchantData = AskMrRobot.ExtraEnchantData[enchantId]; + local spellId = enchantData and enchantData.spellId + local link = nil + if spellId then + link = 'enchant:' .. spellId + local _, _, icon = GetSpellInfo(spellId) + if icon then + self.icon:SetTexture(icon) + end + end + self.iconFrame:Show() else self.iconFrame:Hide() diff -r 9793e8b683d2 -r e77e01abce98 ui/EnchantTab.lua --- a/ui/EnchantTab.lua Thu Jul 10 15:32:11 2014 -0700 +++ b/ui/EnchantTab.lua Mon Oct 13 21:28:32 2014 -0500 @@ -44,7 +44,7 @@ tab.badEnchantCurrent = {} tab.badEnchantOptimized = {} - for i = 1, #AskMrRobot.slotNames do + for i = 1, #AskMrRobot.slotIds do local itemText = tab:CreateFontString(nil, "ARTWORK", "GameFontWhite") itemText:SetPoint("TOPLEFT", "AmrBadEnchantSlotHeader", "TOPLEFT", 0, -26 * i) itemText:SetPoint("BOTTOMRIGHT", "AmrBadEnchantSlotHeader", "BOTTOMRIGHT", 0, -26 * i) @@ -66,21 +66,26 @@ return tab end -function AskMrRobot.EnchantTab:showBadEnchants() - - local badEnchants = AskMrRobot.itemDiffs.enchants +function AskMrRobot.EnchantTab:Update() local i = 1 -- for all the bad items - for slotNum, badEnchant in AskMrRobot.sortSlots(badEnchants) do - self.badEnchantSlots[i]:SetText(_G[strupper(AskMrRobot.slotNames[slotNum])]) - self.badEnchantSlots[i]:Show() + if AskMrRobot.ComparisonResult.enchants then + for iSlot = 1, #AskMrRobot.slotIds do + local slotId = AskMrRobot.slotIds[iSlot] + local badEnchant = AskMrRobot.ComparisonResult.enchants[slotId] + if badEnchant ~= nil then + self.badEnchantSlots[i]:SetText(AskMrRobot.slotDisplayText[slotId]) + self.badEnchantSlots[i]:Show() - self.badEnchantCurrent[i]:SetEnchantId(badEnchant.current) + self.badEnchantCurrent[i]:SetEnchantId(badEnchant.current) - self.badEnchantOptimized[i]:SetEnchantId(badEnchant.optimized) - i = i + 1 + self.badEnchantOptimized[i]:SetEnchantId(badEnchant.optimized) + i = i + 1 + end + end + end -- hide / show the headers diff -r 9793e8b683d2 -r e77e01abce98 ui/ExportTab.lua --- a/ui/ExportTab.lua Thu Jul 10 15:32:11 2014 -0700 +++ b/ui/ExportTab.lua Mon Oct 13 21:28:32 2014 -0500 @@ -5,7 +5,7 @@ AskMrRobot.ExportTab = AskMrRobot.inheritsFrom(AskMrRobot.Frame) -- helper to create text for this tab -local function CreateText(state, tab, font, relativeTo, xOffset, yOffset, text) +local function CreateText(tab, font, relativeTo, xOffset, yOffset, text) local t = tab:CreateFontString(nil, "ARTWORK", font) t:SetPoint("TOPLEFT", relativeTo, "BOTTOMLEFT", xOffset, yOffset) t:SetPoint("RIGHT", tab, "RIGHT", -25, 0) @@ -13,10 +13,6 @@ t:SetJustifyH("LEFT") t:SetText(text) - if (state ~= nil) then - table.insert(state, t) - end - return t end @@ -28,46 +24,13 @@ tab:SetPoint("BOTTOMRIGHT") tab:Hide() - -- used to toggle between the two states... could use like, tabs or a UI panel or something, but then I would have to read more pseudo-documentation. - tab.manualElements = {} - tab.autoElements = {} - local text = tab:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge") text:SetPoint("TOPLEFT", 0, -5) - text:SetText(L.AMR_EXPORTTAB_EXPORT_BB) - - local chooseText = CreateText(nil, tab, "GameFontWhite", text, 0, -15, "Choose a method:") - chooseText:SetJustifyV("MIDDLE") - chooseText:SetHeight(30) - - local btn = CreateFrame("Button", "AmrExportManual", tab, "UIPanelButtonTemplate") - btn:SetPoint("TOPLEFT", text, "BOTTOMLEFT", 125, -15) - btn:SetText(L.AMR_EXPORTTAB_COPY_PASTE) - btn:SetWidth(120) - btn:SetHeight(30) - tab.btnManual = btn - - btn:SetScript("OnClick", function() - AmrOptions.exportToClient = false - tab:Update() - end) - - btn = CreateFrame("Button", "AmrExportAuto", tab, "UIPanelButtonTemplate") - btn:SetPoint("TOPLEFT", text, "BOTTOMLEFT", 275, -15) - btn:SetText(L.AMR_EXPORTTAB_AMR_CLIENT) - btn:SetWidth(120) - btn:SetHeight(30) - tab.btnAuto = btn - - btn:SetScript("OnClick", function() - AmrOptions.exportToClient = true - tab:Update() - end) - + text:SetText(L.AMR_EXPORTTAB_EXPORT_TITLE) + -- copy/paste - text = CreateText(tab.manualElements, tab, "GameFontNormalLarge", chooseText, 0, -20, L.AMR_EXPORTTAB_COPY_PASTE_EXPORT) - local text2 = CreateText(tab.manualElements, tab, "GameFontWhite", text, 0, -15, L.AMR_EXPORTTAB_COPY_PASTE_EXPORT_1) - text = CreateText(tab.manualElements, tab, "GameFontWhite", text2, 0, -15, L.AMR_EXPORTTAB_COPY_PASTE_EXPORT_2) + local text2 = CreateText(tab, "GameFontWhite", text, 0, -15, L.AMR_EXPORTTAB_COPY_PASTE_EXPORT_1) + text = CreateText(tab, "GameFontWhite", text2, 0, -15, L.AMR_EXPORTTAB_COPY_PASTE_EXPORT_2) local txtExportString = CreateFrame("ScrollFrame", "AmrScrollFrame", tab, "InputScrollFrameTemplate") txtExportString:SetPoint("TOPLEFT", text, "BOTTOMLEFT", 12, -10) @@ -78,57 +41,24 @@ txtExportString.EditBox:SetMaxLetters(0) txtExportString.CharCount:Hide() tab.txtExportString = txtExportString - table.insert(tab.manualElements, txtExportString) txtExportString.EditBox:SetScript("OnEscapePressed", function() - AskMrRobot_ReforgeFrame:Hide() + AskMrRobot.mainWindow:Hide() end) - text = CreateText(tab.manualElements, tab, "GameFontWhite", txtExportString, -12, -20, L.AMR_EXPORTTAB_COPY_PASTE_EXPORT_3) - text2 = CreateText(tab.manualElements, tab, "GameFontWhite", text, 10, -5, L.AMR_EXPORTTAB_COPY_PASTE_EXPORT_4) - - local image = tab:CreateTexture(nil, "BACKGROUND") - image:SetPoint("TOPLEFT", text2, "BOTTOMLEFT", 2, -10) - image:SetTexture("Interface\\AddOns\\AskMrRobot\\Media\\BiBScreen") - table.insert(tab.manualElements, image) - - text = CreateText(tab.manualElements, tab, "GameFontWhite", text2, 0, -120, L.AMR_EXPORTTAB_COPY_PASTE_EXPORT_NOTE) + text = CreateText(tab, "GameFontWhite", txtExportString, -12, -20, L.AMR_EXPORTTAB_COPY_PASTE_EXPORT_3) + + text = CreateText(tab, "GameFontWhite", text, 0, -10, L.AMR_EXPORTTAB_COPY_PASTE_EXPORT_NOTE) btn = CreateFrame("Button", "AmrUpdateExportString", tab, "UIPanelButtonTemplate") - btn:SetPoint("TOPLEFT", text, "BOTTOMLEFT", 0, -5) + btn:SetPoint("TOPLEFT", text, "BOTTOMLEFT", -2, -10) btn:SetText("Update") - btn:SetWidth(120) - btn:SetHeight(25) - table.insert(tab.manualElements, btn) + btn:SetWidth(110) + btn:SetHeight(30) btn:SetScript("OnClick", function() tab:Update() end) - - -- amr client - text = CreateText(tab.autoElements, tab, "GameFontNormalLarge", chooseText, 0, -20, L.AMR_EXPORTTAB_AMR_CLIENT_EXPORT) - text2 = CreateText(tab.autoElements, tab, "GameFontWhite", text, 0, -15, L.AMR_EXPORTTAB_AMR_CLIENT_EXPORT_1) - text = CreateText(tab.autoElements, tab, "GameFontWhite", text2, 0, -15, L.AMR_EXPORTTAB_AMR_CLIENT_EXPORT_2) - - btn = CreateFrame("Button", "AmrExportFile", tab, "UIPanelButtonTemplate") - btn:SetPoint("TOPLEFT", text, "BOTTOMLEFT", 12, -10) - btn:SetText("Export to File") - btn:SetWidth(180) - btn:SetHeight(25) - table.insert(tab.autoElements, btn) - - btn:SetScript("OnClick", function() - AskMrRobot.SaveAll() - ReloadUI() - end) - - text = CreateText(tab.autoElements, tab, "GameFontWhite", btn, -12, -20, L.AMR_EXPORTTAB_AMR_CLIENT_EXPORT_3) - text2 = CreateText(tab.autoElements, tab, "GameFontWhite", text, 10, -5, L.AMR_EXPORTTAB_AMR_CLIENT_EXPORT_4) - - image = tab:CreateTexture(nil, "BACKGROUND") - image:SetPoint("TOPLEFT", text2, "BOTTOMLEFT", 2, -10) - image:SetTexture("Interface\\AddOns\\AskMrRobot\\Media\\BiBScreen") - table.insert(tab.autoElements, image) tab:SetScript("OnShow", function() tab:Update() @@ -139,21 +69,8 @@ -- update the panel and state function AskMrRobot.ExportTab:Update() - - if (AmrOptions.exportToClient) then - for i, v in ipairs(self.manualElements) do v:Hide() end - for i, v in ipairs(self.autoElements) do v:Show() end - self.btnManual:UnlockHighlight() - self.btnAuto:LockHighlight() - else - for i, v in ipairs(self.autoElements) do v:Hide() end - for i, v in ipairs(self.manualElements) do v:Show() end - self.btnAuto:UnlockHighlight() - self.btnManual:LockHighlight() - - AskMrRobot.SaveAll() - self.txtExportString.EditBox:SetText(AskMrRobot.ExportToString()) - self.txtExportString.EditBox:HighlightText() - self.txtExportString.EditBox:SetFocus() - end + AskMrRobot.SaveAll() + self.txtExportString.EditBox:SetText(AskMrRobot.ExportToString()) + self.txtExportString.EditBox:HighlightText() + self.txtExportString.EditBox:SetFocus() end diff -r 9793e8b683d2 -r e77e01abce98 ui/FontString.lua --- a/ui/FontString.lua Thu Jul 10 15:32:11 2014 -0700 +++ b/ui/FontString.lua Mon Oct 13 21:28:32 2014 -0500 @@ -23,6 +23,11 @@ self:SetFont(file, fontSize, flags) end +function AskMrRobot.FontString:IncreaseFontSize(add) + local file, fontSize, flags = self:GetFont() + self:SetFont(file, fontSize + add, flags) +end + function AskMrRobot.SetFontSize(fontString, fontSize) local file, _, flags = fontString:GetFont() fontString:SetFont(file, fontSize, flags) diff -r 9793e8b683d2 -r e77e01abce98 ui/GearComparisonTab.lua --- /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 diff -r 9793e8b683d2 -r e77e01abce98 ui/GemTab.lua --- a/ui/GemTab.lua Thu Jul 10 15:32:11 2014 -0700 +++ b/ui/GemTab.lua Mon Oct 13 21:28:32 2014 -0500 @@ -25,9 +25,9 @@ local MAX_SLOTS = 4 -- GemTab contructor -function AskMrRobot.GemTab:new(name, parent) +function AskMrRobot.GemTab:new(parent) -- create a new frame (if one isn't supplied) - local tab = AskMrRobot.Frame:new(name, parent) + local tab = AskMrRobot.Frame:new(nil, parent) tab:SetPoint("TOPLEFT") tab:SetPoint("BOTTOMRIGHT") -- use the GemTab class @@ -126,16 +126,22 @@ local i = 1 local badGemTotal = 0 - if AskMrRobot.itemDiffs.gems then - for slotNum, badGems in AskMrRobot.sortSlots(AskMrRobot.itemDiffs.gems) do - self.count = self.count + 1 - if i <= MAX_SLOTS then - self.jewelPanels[i]:Show() + if AskMrRobot.ComparisonResult.gems then + for iSlot = 1, #AskMrRobot.slotIds do + local slotId = AskMrRobot.slotIds[iSlot] + local badGems = AskMrRobot.ComparisonResult.gems[slotId] + if badGems ~= nil then + self.count = self.count + 1 + if i <= MAX_SLOTS then + self.jewelPanels[i]:Show() + end + for g = 1, #badGems.optimized do + if not AskMrRobot.AreGemsCompatible(badGems.optimized[g], badGems.current[g]) then + badGemTotal = badGemTotal + 1 + end + end + i = i + 1 end - for k, v in pairs(badGems.badGems) do - badGemTotal = badGemTotal + 1 - end - i = i + 1 end end @@ -155,8 +161,8 @@ self.gemCurrentHeader:Show() self.gemOptimizedHeader:Show() self.gemsTextToOptimize:Show() - self.button:Show() - self.usePerfectButton:Show() + --self.button:Show() + --self.usePerfectButton:Show() self.stamp:Hide() end @@ -179,18 +185,24 @@ local offset = FauxScrollFrame_GetOffset(scrollframe) local i = 1 - for slotNum, badGems in AskMrRobot.sortSlots(AskMrRobot.itemDiffs.gems) do - if offset > 0 then - offset = offset - 1 - else + if AskMrRobot.ComparisonResult.gems then + for iSlot = 1, #AskMrRobot.slotIds do + local slotId = AskMrRobot.slotIds[iSlot] + local badGems = AskMrRobot.ComparisonResult.gems[slotId] + if badGems ~= nil then + if offset > 0 then + offset = offset - 1 + else - if i > MAX_SLOTS then - break + if i > MAX_SLOTS then + break + end + + self.jewelPanels[i]:SetItemLink(AskMrRobot.slotDisplayText[slotId], AmrDb.Equipped[AmrDb.ActiveSpec][slotId]) + self.jewelPanels[i]:SetOptimizedGems(badGems.optimized, badGems.current) + i = i + 1 + end end - - self.jewelPanels[i]:SetItemLink(_G[strupper(AskMrRobot.slotNames[slotNum])], badGems.current.link ) - self.jewelPanels[i]:SetOptimizedGems(badGems.optimized, badGems.badGems) - i = i + 1 end end end \ No newline at end of file diff -r 9793e8b683d2 -r e77e01abce98 ui/HelpTab.lua --- a/ui/HelpTab.lua Thu Jul 10 15:32:11 2014 -0700 +++ b/ui/HelpTab.lua Mon Oct 13 21:28:32 2014 -0500 @@ -17,22 +17,31 @@ text:SetText(L.AMR_HELPTAB_TITLE) local text2 = tab:CreateFontString(nil, "ARTWORK", "GameFontWhite") - text2:SetPoint("TOPLEFT", text, "BOTTOMLEFT", 0, -20) - text2:SetPoint("RIGHT", tab, "RIGHT", -25, -20) + text2:SetPoint("TOPLEFT", text, "BOTTOMLEFT", 0, -10) + text2:SetPoint("RIGHT", tab, "RIGHT", -25, -8) text2:SetWidth(text2:GetWidth()) - text2:SetText(L.AMR_HELPTAB_LINK .. - L.AMR_HELPTAB_Q1 .. - L.AMR_HELPTAB_A1 .. - L.AMR_HELPTAB_Q2 .. - L.AMR_HELPTAB_A2 .. - L.AMR_HELPTAB_Q3 .. - L.AMR_HELPTAB_A3 .. - L.AMR_HELPTAB_Q4 .. - L.AMR_HELPTAB_A4 .. - L.AMR_HELPTAB_Q5 .. - L.AMR_HELPTAB_A5) - --text2:SetHeight(100) text2:SetJustifyH("LEFT") + text2:SetText(L.AMR_HELPTAB_LINK) + + local answer = text2 + for i = 1, 6 do + text = AskMrRobot.FontString:new(tab, nil, "ARTWORK", "GameFontWhite") + text:SetPoint("TOPLEFT", answer, "BOTTOMLEFT", 0, -11) + text:SetPoint("RIGHT", -18, 0) + text:SetWidth(text2:GetWidth()) + text:SetJustifyH("LEFT") + text:SetText(L['AMR_HELPTAB_Q' .. i]) + text:IncreaseFontSize(1) + text:SetTextColor(1,1,1) + + answer = tab:CreateFontString(nil, "ARTWORK", "GameFontWhite") + answer:SetPoint("TOPLEFT", text, "BOTTOMLEFT", 0, -4) + answer:SetPoint("RIGHT", tab, "RIGHT", -18, 0) + answer:SetWidth(text2:GetWidth()) + answer:SetJustifyH("LEFT") + answer:SetText(L['AMR_HELPTAB_A' .. i]) + answer:SetTextColor(0.7,0.7,0.7) + end return tab end \ No newline at end of file diff -r 9793e8b683d2 -r e77e01abce98 ui/ImportTab.lua --- a/ui/ImportTab.lua Thu Jul 10 15:32:11 2014 -0700 +++ b/ui/ImportTab.lua Mon Oct 13 21:28:32 2014 -0500 @@ -12,54 +12,61 @@ tab:SetPoint("BOTTOMRIGHT") tab:Hide() - -- import button - tab.button = CreateFrame("Button", "AmrImportButton", tab, "UIPanelButtonTemplate") - tab.button:SetPoint("BOTTOM") - tab.button:SetText(L.AMR_IMPORTTAB_BUTTON) - tab.button:SetWidth(100) - tab.button:SetHeight(20) - tab.button:SetPoint("BOTTOM", 0, 15) - local text = tab:CreateFontString("AmrImportText1", "ARTWORK", "GameFontNormalLarge") text:SetPoint("TOPLEFT", 0, -5) text:SetFormattedText(L.AMR_IMPORTTAB_TITLE) text = tab:CreateFontString("AmrImportText2", "ARTWORK", "GameFontWhite") text:SetPoint("TOPLEFT", "AmrImportText1", "BOTTOMLEFT", 0, -20) - text:SetPoint("RIGHT", 0, -20) + text:SetPoint("RIGHT", -15, 0) text:SetWidth(text:GetWidth()) text:SetJustifyH("LEFT") text:SetText(L.AMR_IMPORTTAB_INSTRUCTIONS_1) - local image = tab:CreateTexture(nil, "BACKGROUND") - image:SetPoint("TOPLEFT", text, "BOTTOMLEFT", 16, -10) - image:SetTexture("Interface\\AddOns\\AskMrRobot\\Media\\AddonExport") - image:SetSize(256, 256) - text = tab:CreateFontString("AmrImportText3", "ARTWORK", "GameFontWhite") - text:SetPoint("TOPLEFT", image, "BOTTOMLEFT", -16, 24) - text:SetPoint("RIGHT", -15, 40) + text:SetPoint("TOPLEFT", "AmrImportText2", "BOTTOMLEFT", 0, -10) + text:SetPoint("RIGHT", -15, 0) text:SetWidth(text:GetWidth()) text:SetJustifyH("LEFT") text:SetText(L.AMR_IMPORTTAB_INSTRUCTIONS_2) local scrollFrame = CreateFrame("ScrollFrame", "AmrImportScrollFrame", tab, "InputScrollFrameTemplate") scrollFrame:SetPoint("TOPLEFT", text, "BOTTOMLEFT", 5, -10) - scrollFrame:SetPoint("BOTTOM", "AmrImportButton", "TOP", 0, 10) scrollFrame:SetPoint("RIGHT", -30, 0) scrollFrame:SetWidth(430) + scrollFrame:SetHeight(60); scrollFrame.EditBox:SetWidth(scrollFrame:GetWidth()) - scrollFrame.EditBox:SetMaxLetters(1100) + scrollFrame.EditBox:SetMaxLetters(2400) scrollFrame.CharCount:Hide() - scrollFrame.EditBox.PromptText:SetText(L.AMR_IMPORTTAB_INSTRUCTIONS_3) scrollFrame.EditBox:SetFocus() scrollFrame.EditBox:HighlightText() tab.scrollFrame = scrollFrame - + + tab.button = CreateFrame("Button", "AmrImportButton", tab, "UIPanelButtonTemplate") + tab.button:SetText(L.AMR_IMPORTTAB_BUTTON) + tab.button:SetWidth(100) + tab.button:SetHeight(20) + tab.button:SetPoint("BOTTOM", tab, "BOTTOM", 0, 20) + scrollFrame:SetPoint("BOTTOM", tab.button, "TOP", 0, 15) + tab:SetScript("OnShow", function() tab.scrollFrame.EditBox:HighlightText() tab.scrollFrame.EditBox:SetFocus() + tab:Update() end) return tab end + +function AskMrRobot.ImportTab:GetImportText() + return self.scrollFrame.EditBox:GetText() +end + +function AskMrRobot.ImportTab:SetImportText(text) + self.scrollFrame.EditBox:SetText(text) + self.scrollFrame.EditBox:HighlightText() +end + +-- update the panel and state +function AskMrRobot.ImportTab:Update() +end \ No newline at end of file diff -r 9793e8b683d2 -r e77e01abce98 ui/JewelPanel.lua --- a/ui/JewelPanel.lua Thu Jul 10 15:32:11 2014 -0700 +++ b/ui/JewelPanel.lua Mon Oct 13 21:28:32 2014 -0500 @@ -113,6 +113,12 @@ -- if there is a gem to add (or remove) --if i <= #optimizedGems or currentGemLink then if i <= #optimizedGems or currentGemLink then + local optimizedGemId = 0 + if optimizedGems[i] > 0 then + optimizedGemId = AskMrRobot.ExtraGemData[optimizedGems[i]].id + end + --local currentGemId = AskMrRobot.ExtraGemData[showGems[i]].id + -- set the current gem icon / tooltip currentIcon:SetItemLink(currentGemLink) @@ -121,20 +127,28 @@ local optimizedGemLink = nil if i <= #optimizedGems then -- make a link for the optimized gem - optimizedGemLink = select(2, GetItemInfo(optimizedGems[i].id)) + optimizedGemLink = select(2, GetItemInfo(optimizedGemId)) - if not optimizedGemLink and optimizedGems[i].id and itemId then - AskMrRobot.RegisterItemInfoCallback(optimizedGems[i].id, function(name, link) + if not optimizedGemLink and optimizedGemId and itemId then + AskMrRobot.RegisterItemInfoCallback(optimizedGemId, function(name, link) optimizedIcon:SetItemLink(link) end) end end - if showGems[i] and optimizedGems[i] and optimizedGems[i].color then + + local mismatched = not AskMrRobot.AreGemsCompatible(optimizedGems[i], showGems[i]) + + --if showGems[i] and optimizedGems[i] and optimizedGems[i].color then + --if test and optimizedGems[i] and optimizedGems[i].color then + if mismatched and optimizedGems[i] > 0 then gemCount = gemCount + 1 -- set the optimized gem text text:SetTextColor(1,1,1) - text:SetText(AskMrRobot.alternateGemName[optimizedGems[i].id] or (optimizedGems[i].enchantId ~= 0 and AskMrRobot.getEnchantName(optimizedGems[i].enchantId)) or GetItemInfo(optimizedGems[i].id)) + --text:SetText(AskMrRobot.alternateGemName[optimizedGemId] or (optimizedGems[i] ~= 0 and AskMrRobot.getEnchantName(optimizedGems[i])) or GetItemInfo(optimizedGemId)) + + text:SetText(AskMrRobot.ExtraGemData[optimizedGems[i]].text) + currentIcon:Show() -- load the item image / tooltip @@ -143,7 +157,8 @@ optimizedIcon:SetBackdropBorderColor(1,1,1) currentIcon:SetBackdropBorderColor(1,1,1) else - if optimizedGems[i] and optimizedGems[i].color then + --if optimizedGems[i] and optimizedGems[i].color then + if optimizedGems[i] then text:SetText("no change") text:SetTextColor(0.5,0.5,0.5) currentIcon:Show() @@ -156,8 +171,11 @@ optimizedIcon:Hide() end - currentIcon:SetGemColor(optimizedGems[i] and optimizedGems[i].color) - optimizedIcon:SetGemColor(optimizedGems[i] and optimizedGems[i].color) + -- TODO highlight the socket color + local socketColorId = AskMrRobot.ExtraItemData[itemId].socketColors[i] + local socketName = AskMrRobot.socketColorIds[socketColorId]; + currentIcon:SetGemColor(optimizedGems[i] and socketName) + optimizedIcon:SetGemColor(optimizedGems[i] and socketName) -- show the gem row text:Show() diff -r 9793e8b683d2 -r e77e01abce98 ui/ReforgesTab.lua --- a/ui/ReforgesTab.lua Thu Jul 10 15:32:11 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,505 +0,0 @@ -local _, AskMrRobot = ... -local L = AskMrRobot.L; - --------------------------------------------------------------------- --- Local Reforge Utility Code --------------------------------------------------------------------- - -StaticPopupDialogs["REFORGE_TAB_PLEASE_OPEN"] = { - text = L.AMR_REFORGESTAB_OPEN_WINDOW, - button1 = L.AMR_REFORGESTAB_BUTTON_OK, - timeout = 0, - whileDead = true, - hideOnEscape = true, - preferredIndex = 3, -- avoid some UI taint, see http://www.wowace.com/announcements/how-to-avoid-some-ui-taint/ -} - ---from LibReforge -local SPI = 1 -local DODGE = 2 -local PARRY = 3 -local HIT = 4 -local CRIT = 5 -local HASTE = 6 -local EXP = 7 -local MASTERY = 8 - ---from LibReforge -local StatNames = { - ITEM_MOD_SPIRIT_SHORT, - ITEM_MOD_DODGE_RATING_SHORT, - ITEM_MOD_PARRY_RATING_SHORT, - ITEM_MOD_HIT_RATING_SHORT, - ITEM_MOD_CRIT_RATING_SHORT, - ITEM_MOD_HASTE_RATING_SHORT, - ITEM_MOD_EXPERTISE_RATING_SHORT, - ITEM_MOD_MASTERY_RATING_SHORT -} -StatNames[0] = NONE -local StatToString = { - "ITEM_MOD_SPIRIT_SHORT", - "ITEM_MOD_DODGE_RATING_SHORT", - "ITEM_MOD_PARRY_RATING_SHORT", - "ITEM_MOD_HIT_RATING_SHORT", - "ITEM_MOD_CRIT_RATING_SHORT", - "ITEM_MOD_HASTE_RATING_SHORT", - "ITEM_MOD_EXPERTISE_RATING_SHORT", - "ITEM_MOD_MASTERY_RATING_SHORT" -} - - -local REFORGE_TABLE_BASE = 112 -local REFORGE_TABLE = { - {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8}, - {2, 1}, {2, 3}, {2, 4}, {2, 5}, {2, 6}, {2, 7}, {2, 8}, - {3, 1}, {3, 2}, {3, 4}, {3, 5}, {3, 6}, {3, 7}, {3, 8}, - {4, 1}, {4, 2}, {4, 3}, {4, 5}, {4, 6}, {4, 7}, {4, 8}, - {5, 1}, {5, 2}, {5, 3}, {5, 4}, {5, 6}, {5, 7}, {5, 8}, - {6, 1}, {6, 2}, {6, 3}, {6, 4}, {6, 5}, {6, 7}, {6, 8}, - {7, 1}, {7, 2}, {7, 3}, {7, 4}, {7, 5}, {7, 6}, {7, 8}, - {8, 1}, {8, 2}, {8, 3}, {8, 4}, {8, 5}, {8, 6}, {8, 7}, -} - ---------------- returns the index into the REFORGE_TABLE or nil --- returns the reforge id or 0 -local function GetReforgeIdForItem(item) - local id = tonumber(item:match("item:%d+:%d+:%d+:%d+:%d+:%d+:%-?%d+:%-?%d+:%d+:(%d+)")) - return (id and id ~= 0 and id or 0) -end - -local function GetReforgeIdFromStats(fromStat, toStat) - if (toStat > fromStat) then - return REFORGE_TABLE_BASE + 7 * (fromStat - 1) + toStat - 1; - else - return REFORGE_TABLE_BASE + 7 * (fromStat - 1) + toStat; - end -end - - --------------------------------------------------------------------- --- Initialization --------------------------------------------------------------------- -AskMrRobot.ReforgesTab = AskMrRobot.inheritsFrom(AskMrRobot.Frame) - -function AskMrRobot.ReforgesTab:new(parent) - - local tab = AskMrRobot.Frame:new(nil, parent) - setmetatable(tab, { __index = AskMrRobot.ReforgesTab }) - tab:SetPoint("TOPLEFT") - tab:SetPoint("BOTTOMRIGHT") - tab:Hide() - - local text = tab:CreateFontString("AmrReforgesHeader", "ARTWORK", "GameFontNormalLarge") - text:SetPoint("TOPLEFT", 0, -5) - text:SetText(L.AMR_REFORGESTAB_TITLE) - - tab.stamp = AskMrRobot.RobotStamp:new(nil, tab) - tab.stamp:Hide() - tab.stamp.smallText:SetText(L.AMR_REFORGESTAB_OPTIMAL) - tab.stamp:SetPoint("TOPLEFT", text, "BOTTOMLEFT", 2, -15) - tab.stamp:SetPoint("RIGHT", tab, "RIGHT", -20, 0) - - tab.reforgeDetails = tab:CreateFontString("AmrReforgeDetails", "ARTWORK", "GameFontWhite") - tab.reforgeDetails:SetPoint("TOPLEFT", text, "BOTTOMLEFT", 0, -15) - tab.reforgeDetails:SetPoint("RIGHT", -30, 0) - tab.reforgeDetails:SetWordWrap(true) - tab.reforgeDetails:SetJustifyH("LEFT") - tab.reforgeDetails:SetText(L.AMR_REFORGESTAB_INSTRUCTION) - tab.reforgeDetails:SetHeight(50) - - tab.reforgeButton = CreateFrame("Button", "AmrReforgeButton", tab, "UIPanelButtonTemplate") - tab.reforgeButton:SetText(L.AMR_REFORGESTAB_BUTTON) - tab.reforgeButton:SetPoint("TOPLEFT", 0, -80) - tab.reforgeButton:SetWidth(140) - tab.reforgeButton:SetHeight(20) - tab.reforgeButton:SetScript("OnClick", function() - tab:OnReforge() - end) - - tab.reforgeCost = tab:CreateFontString(nil, "ARTWORK", "GameFontNormal") - tab.reforgeCost:SetPoint("TOPLEFT", tab.reforgeButton, "TOPRIGHT", 25, 0) - tab.reforgeCost:SetPoint("BOTTOM", tab.reforgeButton, "BOTTOM", 0, 0) - tab.reforgeCost:SetPoint("RIGHT", tab, "RIGHT", -30, 0) - tab.reforgeCost:SetText('') - - tab.slotHeader = tab:CreateFontString(nil, "ARTWORK", "GameFontNormal") - tab.slotHeader:SetText(L.AMR_REFORGESTAB_SLOT) - tab.slotHeader:SetPoint("TOPLEFT", tab.reforgeButton, "BOTTOMLEFT", 0, -30) - - tab.reforgeHeader = tab:CreateFontString(nil, "ARTWORK", "GameFontNormal") - tab.reforgeHeader:SetText(L.AMR_REFORGESTAB_OPTIMAL_REFORGE) - tab.reforgeHeader:SetPoint("TOPLEFT", tab.slotHeader, "TOPLEFT", 100, 0) - - -- pre-allocate a visual element for all possible slots; showBadReforges will set text and show the number that are needed, and hide the rest - tab.slots = {} - tab.optimized = {} - - for i = 1, #AskMrRobot.slotNames do - tab.slots[i] = tab:CreateFontString(nil, "ARTWORK", "GameFontWhite") - tab.slots[i]:SetPoint("TOPLEFT", tab.slotHeader, "TOPLEFT", 0, -20 * i) - tab.slots[i]:Hide() - - tab.optimized[i] = tab:CreateFontString(nil, "ARTWORK", "GameFontWhite") - tab.optimized[i]:SetPoint("TOPLEFT", tab.reforgeHeader, "TOPLEFT", 0, -20 * i) - tab.optimized[i]:Hide() - end - - tab:RegisterEvent("FORGE_MASTER_ITEM_CHANGED") - tab:RegisterEvent("FORGE_MASTER_SET_ITEM") - tab:RegisterEvent("FORGE_MASTER_OPENED") - tab:RegisterEvent("FORGE_MASTER_CLOSED") - - tab:SetScript("OnEvent", function(...) - tab:OnEvent(...) - end) - - - -- initialize stat required for performing the reforges - tab.state = {} - tab:ResetState() - - - return tab -end - - --------------------------------------------------------------------- --- Rendering --------------------------------------------------------------------- - -local function GetReforgeString(fromId, toId) - if toId == 0 then - return "Restore" - end - local pair = REFORGE_TABLE[toId - REFORGE_TABLE_BASE] - - local text = _G[StatToString[pair[1]]] .. ' -> ' .. _G[StatToString[pair[2]]] - --print('from ' .. fromId) - if fromId == 0 then - return text - end - return L.AMR_REFORGESTAB_RESTORE_THEN .. text -end - --- draw all of the reforges that still need to be performed -function AskMrRobot.ReforgesTab:Render() - - local reforges = AskMrRobot.itemDiffs.reforges - local i = 1 - local cost = 0 - - -- for all the bad items - for slotNum, badReforge in AskMrRobot.sortSlots(reforges) do - - self.optimized[i]:SetText(GetReforgeString(badReforge.current, badReforge.optimized)) - self.optimized[i]:Show() - - self.slots[i]:SetText(_G[strupper(AskMrRobot.slotNames[slotNum])]) - self.slots[i]:Show() - - -- Restore is free, so only add cost for non-restore reforges - if badReforge.optimized > 0 then - local slotId = AskMrRobot.slotIds[slotNum] - local itemLink = GetInventoryItemLink("player", slotId) - cost = cost + (itemLink and select (11, GetItemInfo(itemLink)) or 0) - end - - i = i + 1 - end - - self.reforgeCost:SetText(L.AMR_REFORGESTAB_TOTAL_COST:format(math.ceil(cost / 10000))) - - -- hide / show the headers - if i == 1 then - self.reforgeHeader:Hide() - self.slotHeader:Hide() - self.reforgeButton:Hide() - self.reforgeCost:Hide() - self.reforgeDetails:Hide() - self.stamp:Show() - else - self.stamp:Hide() - self.reforgeButton:Show() - self.reforgeCost:Show() - self.reforgeHeader:Show() - self.reforgeDetails:Show() - self.slotHeader:Show() - end - - -- hide the remaining slots - while i <= #self.slots do - self.optimized[i]:Hide() - self.slots[i]:Hide() - i = i + 1 - end -end - --------------------------------------------------------------------- --- Reforge Logic --------------------------------------------------------------------- - --- reset state for a fresh pass at automatic reforging -function AskMrRobot.ReforgesTab:ResetState() - - self.state.queue = {} -- list of all reforges actions that still need to be performed - self.state.currentItem = nil -- the current item we are trying to reforge - self.state.pendingSlot = nil -- the slot that we have requested to place into the reforger - self.state.currentSlot = nil -- the current slot in the reforger - self.state.pendingReforge = -1 -- the reforge that we have requested to perform on the current item -end - --- refresh the queue of reforges that still need to be performed -function AskMrRobot.ReforgesTab:RefreshQueue() - - -- clear the queue - self.state.queue = {} - - local reforges = AskMrRobot.itemDiffs.reforges - - -- add all reforges that need updating to the reforge queue - for slotNum, badReforge in AskMrRobot.sortSlots(reforges) do - self:AddToReforgeQueue(slotNum, badReforge.optimized); - end -end - -function AskMrRobot.ReforgesTab:AddToReforgeQueue(itemSlot, reforgeId) - - -- the game's slot id, not the same as the ids that we use on our servers - local gameSlot = AskMrRobot.slotIds[itemSlot] - - local item = GetInventoryItemLink("player", gameSlot) - if item == nil then - --print ('no item') - return - end - - local current = GetReforgeIdForItem(item) - - if current ~= reforgeId then - -- restore first - if current ~= 0 and reforgeId ~= 0 then - tinsert(self.state.queue, { ["slot"] = gameSlot, ["reforge"] = 0 }) - end - - -- then reforge to the specified reforge - tinsert(self.state.queue, { ["slot"] = gameSlot, ["reforge"] = reforgeId }) - end -end - -function AskMrRobot.ReforgesTab:IsQueueEmpty() - return self.state.queue == nil or #self.state.queue == 0 or self.state.queue == {}; -end - --- returns true if we are waiting on the game to finish a pending async reforge operation -function AskMrRobot.ReforgesTab:HasPendingOperation() - - -- waiting for an item to be placed into the reforger - if self.state.pendingSlot then - return true - end - - -- waiting for a reforge to be completed - if self.state.pendingReforge ~= -1 then - return true - end - - return false -end - --- put the next item in the reforge queue into the game's reforge UI -function AskMrRobot.ReforgesTab:PutNextItemInForge() - - if self:IsQueueEmpty() or self:HasPendingOperation() then - return - end - - -- get the first action in the queue - local currentAction = self.state.queue[1] - local itemSlot = currentAction.slot - - local item = GetInventoryItemLink("player", itemSlot) - - -- set current item that we are trying to reforge - self.state.currentItem = item - - -- if this item isn't already in the reforger, put it in - if self.state.currentSlot ~= itemSlot then - ClearCursor() -- make sure no item is selected - SetReforgeFromCursorItem() -- pick up the old item (calling this with an item already in the reforger will put it back on the mouse cursor) - ClearCursor() -- clear the cursor to finish removing any current item from the game reforge UI - PickupInventoryItem(itemSlot) -- pick up the right equipped item - - -- pending, listen for an event from the game to complete setting this item into the reforger - self.state.pendingSlot = itemSlot - - SetReforgeFromCursorItem() -- put the item into the reforger, and wait for the FORGE_MASTER_SET_ITEM event, which calls DoReforge - end - -end - --- an item is in the reforger, ready to be reforged, so do it -function AskMrRobot.ReforgesTab:DoReforge() - - if self:IsQueueEmpty() or self:HasPendingOperation() then - return - end - - local currentAction = self.state.queue[1] - local desiredReforge = currentAction.reforge - - -- the index that needs to be provided to WoW's ReforgeItem method, corresponds to one of the options in the game reforge UI - local reforgeIndex = -1 - - if desiredReforge ~= 0 then - local targetFrom = REFORGE_TABLE[desiredReforge - REFORGE_TABLE_BASE][1]; - local targetTo = REFORGE_TABLE[desiredReforge - REFORGE_TABLE_BASE][2]; - - for i=1, GetNumReforgeOptions() do - local from, _, _, to, _, _ = GetReforgeOptionInfo(i) - --print(i .. ': ' .. from .. " -> " .. to) - if StatNames[targetFrom] == from and StatNames[targetTo] == to then - reforgeIndex = i - break - end - end - else - reforgeIndex = 0 - end - - if reforgeIndex == -1 then - -- we couldn't do this reforge... we either had a bad reforge (wrong stats on an item), or the game had no options in the UI for some reason - - -- remove the item from the reforge window - ClearCursor() - SetReforgeFromCursorItem() - ClearCursor() - - -- reset state and quit reforging (clears the queue) - self:ResetState() - - else - - local currentReforge = GetReforgeIdForItem(self.state.currentItem); - if currentReforge == desiredReforge then - -- we already have this reforge on the item... probably shouldn't ever happen, but if it does, recalculate and start over - tremove(self.state.queue, 1) - - -- remove the item from the reforge window - ClearCursor() - SetReforgeFromCursorItem() - ClearCursor() - - -- update the state of the entire UI, and start again with the next required reforge - AskMrRobot_ReforgeFrame:OnUpdate() - self:OnReforge() - - else - -- we have a reforge (or restore) to do, kick it off and wait for CheckReforge to respond to completion - self:TryReforge(reforgeIndex) - end - - end - -end - --- wraps WoW API call to ReforgeItem, fires a manual timeout in case the UI does not raise an event -function AskMrRobot.ReforgesTab:TryReforge(reforgeIndex) - - -- we have a reforge (or restore) to do, kick it off and wait for FORGE_MASTER_ITEM_CHANGED, which calls CheckReforge - self.state.pendingReforge = reforgeIndex - ReforgeItem(reforgeIndex) - - -- sometimes the game doesn't send the FORGE_MASTER_ITEM_CHANGED event, so also check after a delay also - AskMrRobot.wait(0.250, AskMrRobot.ReforgesTab.CheckReforge, self) - -end - --- check that a requested reforge has been completed -function AskMrRobot.ReforgesTab:CheckReforge() - - if self:IsQueueEmpty() or self.state.pendingReforge == -1 then - - -- responding to a reforge that the user has manually performed, update the UI and terminate any automatic process that is going on - AskMrRobot_ReforgeFrame:OnUpdate() - self:ResetState() - - else - -- responding to a reforge that we have initiated - - local currentReforge, icon, name, quality, bound, cost = GetReforgeItemInfo(); - if currentReforge == self.state.pendingReforge then - tremove(self.state.queue, 1) - - -- remove the item from the reforge window - ClearCursor() - SetReforgeFromCursorItem() - ClearCursor() - - -- update the state of the entire UI, and start again with the next required reforge - AskMrRobot_ReforgeFrame:OnUpdate() - self:OnReforge() - else - -- try again - self:TryReforge(self.state.pendingReforge) - end - end - -end - - --------------------------------------------------------------------- --- Event Handling --------------------------------------------------------------------- - --- event called when the Mr. Robot Reforge button is clicked, kicks off automatic reforge -function AskMrRobot.ReforgesTab:OnReforge() - - -- need to be at a reforger for this to work - if not self.isReforgeOpen then - StaticPopup_Show("REFORGE_TAB_PLEASE_OPEN") - return - end - - -- reset state and refresh the queue of reforges that still need to be done - self:ResetState() - self:RefreshQueue() - - -- get goin, put the first item in the reforger - self:PutNextItemInForge() -end - -function AskMrRobot.ReforgesTab:On_FORGE_MASTER_SET_ITEM() - - if self.state.pendingSlot then - - -- we have successfully finished placing an item into the reforger - self.state.currentSlot = self.state.pendingSlot - - -- indicate that we are no longer waiting for an item - self.state.pendingSlot = nil - - -- now reforge it - self:DoReforge() - end - -end - -function AskMrRobot.ReforgesTab:On_FORGE_MASTER_ITEM_CHANGED() - self:CheckReforge() -end - -function AskMrRobot.ReforgesTab:On_FORGE_MASTER_OPENED() - self.isReforgeOpen = true -end - -function AskMrRobot.ReforgesTab:On_FORGE_MASTER_CLOSED() - self.isReforgeOpen = false -end - -function AskMrRobot.ReforgesTab:OnEvent(frame, event, ...) - --print("EVENT " .. event) - local handler = self["On_" .. event] - if handler then - handler(self, ...) - end -end \ No newline at end of file diff -r 9793e8b683d2 -r e77e01abce98 ui/ShoppingListTab.lua --- a/ui/ShoppingListTab.lua Thu Jul 10 15:32:11 2014 -0700 +++ b/ui/ShoppingListTab.lua Mon Oct 13 21:28:32 2014 -0500 @@ -52,8 +52,8 @@ end) tab.enchantMaterialsCheckbox = CreateFrame("CheckButton", "AmrEnchantMaterialsCheckbox", tab.shoppingPanel, "ChatConfigCheckButtonTemplate"); - tab.enchantMaterialsCheckbox:SetChecked(AmrSendSettings.SendEnchantMaterials) - tab.enchantMaterialsCheckbox:SetScript("OnClick", function () AmrSendSettings.SendEnchantMaterials = tab.enchantMaterialsCheckbox:GetChecked() end) + tab.enchantMaterialsCheckbox:SetChecked(AmrDb.SendSettings.SendEnchantMaterials) + tab.enchantMaterialsCheckbox:SetScript("OnClick", function () AmrDb.SendSettings.SendEnchantMaterials = tab.enchantMaterialsCheckbox:GetChecked() end) tab.enchantMaterialsCheckbox:SetPoint("TOPLEFT", tab.sendButton, "TOPLEFT", 0, 25) local text3 = getglobal(tab.enchantMaterialsCheckbox:GetName() .. 'Text') text3:SetFontObject("GameFontHighlightLarge") @@ -63,8 +63,8 @@ tab.enchantsCheckbox = CreateFrame("CheckButton", "AmrEnchantsCheckbox", tab.shoppingPanel, "ChatConfigCheckButtonTemplate"); - tab.enchantsCheckbox:SetChecked(AmrSendSettings.SendEnchants) - tab.enchantsCheckbox:SetScript("OnClick", function () AmrSendSettings.SendEnchants = tab.enchantsCheckbox:GetChecked() end) + tab.enchantsCheckbox:SetChecked(AmrDb.SendSettings.SendEnchants) + tab.enchantsCheckbox:SetScript("OnClick", function () AmrDb.SendSettings.SendEnchants = tab.enchantsCheckbox:GetChecked() end) tab.enchantsCheckbox:SetPoint("TOPLEFT", tab.sendButton, "TOPLEFT", 0, 50) local text2 = getglobal(tab.enchantsCheckbox:GetName() .. 'Text') text2:SetFontObject("GameFontHighlightLarge") @@ -76,8 +76,8 @@ tab.gemsCheckbox = CreateFrame("CheckButton", "AmrGemsCheckbox", tab.shoppingPanel, "ChatConfigCheckButtonTemplate"); tab.gemsCheckbox:SetPoint("TOPLEFT", tab.sendButton, "TOPLEFT", 0, 75) - tab.gemsCheckbox:SetChecked(AmrSendSettings.SendGems) - tab.gemsCheckbox:SetScript("OnClick", function () AmrSendSettings.SendGems = tab.gemsCheckbox:GetChecked() end) + tab.gemsCheckbox:SetChecked(AmrDb.SendSettings.SendGems) + tab.gemsCheckbox:SetScript("OnClick", function () AmrDb.SendSettings.SendGems = tab.gemsCheckbox:GetChecked() end) local text = getglobal(tab.gemsCheckbox:GetName() .. 'Text') text:SetFontObject("GameFontHighlightLarge") text:SetText(L.AMR_SHOPPINGLISTTAB_GEMS) @@ -167,7 +167,7 @@ tab.dropDown = CreateFrame("FRAME", "AmrSendType", tab.shoppingPanel, "UIDropDownMenuTemplate") tab.dropDown:SetPoint("TOPLEFT", tab.sendMessage3, "TOPRIGHT", 0, 5) UIDropDownMenu_SetWidth(tab.dropDown, 140) - UIDropDownMenu_SetText(tab.dropDown, AmrSendSettings.SendToType) + UIDropDownMenu_SetText(tab.dropDown, AmrDb.SendSettings.SendToType) local text = getglobal(tab.dropDown:GetName() .. 'Text') text:SetFontObject("GameFontHighlightLarge") @@ -176,7 +176,7 @@ local info = UIDropDownMenu_CreateInfo() info.justifyH = "RIGHT" info.text = optionText - info.checked = AmrSendSettings.SendToType == optionText + info.checked = AmrDb.SendSettings.SendToType == optionText info.arg1 = optionText info.func = list.SetValue info.owner = list @@ -196,9 +196,9 @@ end) function tab.dropDown:SetValue(newValue) - AmrSendSettings.SendToType = newValue + AmrDb.SendSettings.SendToType = newValue -- Update the text; if we merely wanted it to display newValue, we would not need to do this - UIDropDownMenu_SetText(tab.dropDown, AmrSendSettings.SendToType) + UIDropDownMenu_SetText(tab.dropDown, AmrDb.SendSettings.SendToType) -- Because this is called from a sub-menu, only that menu level is closed by default. -- Close the entire menu with this next call CloseDropDownMenus() @@ -208,11 +208,11 @@ tab.sendTo:SetPoint("TOPLEFT", tab.dropDown, "TOPRIGHT", 0, 0) tab.sendTo:SetPoint("RIGHT", 0, 0) tab.sendTo:SetHeight(30) - tab.sendTo:SetText(AmrSendSettings.SendTo or "") + tab.sendTo:SetText(AmrDb.SendSettings.SendTo or "") tab.sendTo:SetFontObject("GameFontHighlightLarge") tab.sendTo:SetAutoFocus(false) tab.sendTo:SetScript("OnChar", function() - AmrSendSettings.SendTo = tab.sendTo:GetText() + AmrDb.SendSettings.SendTo = tab.sendTo:GetText() end) tab.messageQueue = {} @@ -256,7 +256,8 @@ -- set the link (tooltip + icon) gemIcon:SetItemLink(gemLink) - gemIcon:SetGemColor(gemInfo.color) + --gemIcon:SetGemColor(gemInfo.color) + gemIcon:SetGemColor('Prismatic') -- if we didn't get one, its because WoW is slow if not gemLink and gemInfo.id then @@ -552,28 +553,33 @@ end function AskMrRobot.ShoppingListTab:CalculateItems() - -- build a map of missing gem-ids -> {id, color, enchantid, count, total} + -- build a map of missing gem-enchant-ids -> {id, enchantid, count, total} local gemList = {} - for slotNum, badGems in pairs(AskMrRobot.itemDiffs.gems) do - --badGems: {current: array of enchant ids, optimized: (array of {id, color, enchantId}) - for i = 1, #badGems.optimized do - if badGems.badGems[i] then - local goodGem = badGems.optimized[i] - if goodGem.id ~= 0 then - local gem = gemList[goodGem.id] - if gem == nil then - gemList[goodGem.id] = {id = goodGem.id, enchantId = goodGem.enchantId, color = goodGem.color, count = 0, total = 1} - else - gem.total = gem.total + 1 - end + + -- for each piece of gear that needs at least 1 gem changed + for _, badGems in pairs(AskMrRobot.ComparisonResult.gems) do + -- for each specified gem + for g = 1, #badGems.optimized do + local goodGemEnchantId = badGems.optimized[g] + -- if AMR says to optimized this gem AND it does *NOT* match matches the current gem + if goodGemEnchantId ~= 0 and not AskMrRobot.AreGemsCompatible(goodGemEnchantId, badGems.current[g]) then + -- see if this gem is in our list of gems to optimize + local gem = gemList[goodGemEnchantId] + if gem == nil then + -- if not, add it + gemList[goodGemEnchantId] = {id = AskMrRobot.ExtraGemData[goodGemEnchantId].id, enchantId = goodGemEnchantId, count = 0, total = 1, compatibleGemIds = AskMrRobot.ExtraGemData[goodGemEnchantId].identicalItemGroup} + else + -- if so, increase the total requested for this + gem.total = gem.total + 1 end end end end local enchantList = {} - for slot, enchantData in AskMrRobot.sortSlots(AskMrRobot.itemDiffs.enchants) do - local id = AskMrRobot.getEnchantItemId(enchantData.optimized) or enchantData.optimized + for slot, enchantData in AskMrRobot.sortSlots(AskMrRobot.ComparisonResult.enchants) do + local extraData = AskMrRobot.ExtraEnchantData[enchantData.optimized] + local id = extraData and extraData.itemId or enchantData.optimized local qty = enchantList[id] if qty then qty.total = qty.total + 1 @@ -584,63 +590,55 @@ end local enchantMaterials = {} - for slot, enchantData in pairs(AskMrRobot.itemDiffs.enchants) do - AskMrRobot.addEnchantMaterials(enchantMaterials, enchantData.optimized) + for slot, enchantData in pairs(AskMrRobot.ComparisonResult.enchants) do + local extraData = AskMrRobot.ExtraEnchantData[enchantData.optimized] + if extraData and extraData.materials then + local itemId + local count + for itemId, count in pairs(extraData.materials) do + if enchantMaterials[itemId] then + enchantMaterials[itemId].total = enchantMaterials[itemId].total + count + else + enchantMaterials[itemId] = { count = 0, total = count } + end + end + end + end - --substract any inventory we already have in the bank - for i = 1, #AmrBankItemsAndCounts do - local itemId = AskMrRobot.getItemIdFromLink(AmrBankItemsAndCounts[i].link) - if itemId then - local gem = gemList[itemId] - if gem then - gem.count = gem.count + AmrBankItemsAndCounts[i].count - else - local alternateGemId = AskMrRobot.gemDuplicates[itemId] - if alternateGemId then - gem = gemList[alternateGemId] - if gem then - gem.count = gem.count + AmrBankItemsAndCounts[i].count - end - end - end - local material = enchantMaterials[itemId] - if material then - material.count = material.count + AmrBankItemsAndCounts[i].count - end - local enchant = enchantList[itemId] - if enchant then - enchant.count = enchant.count + AmrBankItemsAndCounts[i].count - end + local bagItemsWithCounts = {} + -- copy the bank items into a new table so we don't alter them + if (AmrDb.BankItemsAndCounts) then + for id, count in pairs(AmrDb.BankItemsAndCounts) do + bagItemsWithCounts[id] = count end end - local _ , bagItemsWithCount = AskMrRobot.ScanBags() + -- add the items from the players bags + AskMrRobot.ScanBags(bagItemsWithCounts) - --substract any inventory we already have in bags - for i = 1, #bagItemsWithCount do - local itemId = AskMrRobot.getItemIdFromLink(bagItemsWithCount[i].link) - if itemId then - local gem = gemList[itemId] - if gem then - gem.count = gem.count + bagItemsWithCount[i].count - else - local alternateGemId = AskMrRobot.gemDuplicates[itemId] - if alternateGemId then - gem = gemList[alternateGemId] - if gem then - gem.count = gem.count + bagItemsWithCount[i].count - end + --substract any inventory we already have in bags/bank + for itemId, count in pairs(bagItemsWithCounts) do + for _, gem in pairs(gemList) do + if gem.compatibleGemIds[itemId] and gem.count < gem.total then + local needed = gem.total - gem.count + if count > needed then + gem.count = gem.total + -- only consume the number needed (subtract in case this is compatible with a different gem) + count = count - needed + else + gem.count = gem.count + count + count = 0 end end - local material = enchantMaterials[itemId] - if material then - material.count = material.count + bagItemsWithCount[i].count - end - local enchant = enchantList[itemId] - if enchant then - enchant.count = enchant.count + bagItemsWithCount[i].count - end + end + local material = enchantMaterials[itemId] + if material then + material.count = material.count + count + end + local enchant = enchantList[itemId] + if enchant then + enchant.count = enchant.count + count end end @@ -783,22 +781,22 @@ local gemList, enchantList, enchantMaterials = self:CalculateItems() - if AmrSendSettings.SendGems then + if AmrDb.SendSettings.SendGems then for k,v in pairs(gemList) do --exclude jewelcrafter gems - if not AskMrRobot.JewelcrafterGems[k] then + --if not AskMrRobot.JewelcrafterGems[k] then local needed = v.total - v.count if needed > 0 then - local itemName = GetItemInfo(k) + local itemName = GetItemInfo(v.id) if itemName then message = message .. "\n" .. needed .. "x " .. itemName end end - end + --end end end - if AmrSendSettings.SendEnchants then + if AmrDb.SendSettings.SendEnchants then for k,v in pairs(enchantList) do local needed = v.total - v.count if needed > 0 then @@ -810,7 +808,7 @@ end end - if AmrSendSettings.SendEnchantMaterials then + if AmrDb.SendSettings.SendEnchantMaterials then for k,v in pairs(enchantMaterials) do local needed = v.total - v.count if needed > 0 then @@ -823,8 +821,8 @@ end MailFrameTab_OnClick(nil, 2) - if AmrSendSettings.SendGems then - if AmrSendSettings.SendEnchants then + if AmrDb.SendSettings.SendGems then + if AmrDb.SendSettings.SendEnchants then SendMailSubjectEditBox:SetText(L.AMR_SHOPPINGLISTTAB_MAIL_SUBJECT_GE) else SendMailSubjectEditBox:SetText(L.AMR_SHOPPINGLISTTAB_MAIL_SUBJECT_G) @@ -832,21 +830,21 @@ else SendMailSubjectEditBox:SetText(L.AMR_SHOPPINGLISTTAB_MAIL_SUBJECT_E) end - SendMailNameEditBox:SetText(AmrSendSettings.SendTo) + SendMailNameEditBox:SetText(AmrDb.SendSettings.SendTo) SendMailBodyEditBox:SetText(message) end function AskMrRobot.ShoppingListTab:Send() local chatType = nil - if AmrSendSettings.SendToType == L.AMR_SHOPPINGLISTTAB_DROPDOWN_PARTY then + if AmrDb.SendSettings.SendToType == L.AMR_SHOPPINGLISTTAB_DROPDOWN_PARTY then chatType = "PARTY" - elseif AmrSendSettings.SendToType == L.AMR_SHOPPINGLISTTAB_DROPDOWN_GUILD then + elseif AmrDb.SendSettings.SendToType == L.AMR_SHOPPINGLISTTAB_DROPDOWN_GUILD then chatType = "GUILD" - elseif AmrSendSettings.SendToType == L.AMR_SHOPPINGLISTTAB_DROPDOWN_RAID then + elseif AmrDb.SendSettings.SendToType == L.AMR_SHOPPINGLISTTAB_DROPDOWN_RAID then chatType = "RAID" - elseif AmrSendSettings.SendToType == L.AMR_SHOPPINGLISTTAB_DROPDOWN_CHANNEL then + elseif AmrDb.SendSettings.SendToType == L.AMR_SHOPPINGLISTTAB_DROPDOWN_CHANNEL then chatType = "CHANNEL" - elseif AmrSendSettings.SendToType == L.AMR_SHOPPINGLISTTAB_DROPDOWN_MAIL then + elseif AmrDb.SendSettings.SendToType == L.AMR_SHOPPINGLISTTAB_DROPDOWN_MAIL then self:sendMail() return else @@ -860,18 +858,18 @@ local gemList, enchantList, enchantMaterials = self:CalculateItems() local items = {} - if AmrSendSettings.SendGems then + if AmrDb.SendSettings.SendGems then for k,v in pairs(gemList) do - if not AskMrRobot.JewelcrafterGems[k] then + --if not AskMrRobot.JewelcrafterGems[k] then local needed = v.total - v.count if needed > 0 then - tinsert(items, {id = k, needed = needed}) + tinsert(items, {id = v.id, needed = needed}) end - end + --end end end - if AmrSendSettings.SendEnchants then + if AmrDb.SendSettings.SendEnchants then for k,v in pairs(enchantList) do local needed = v.total - v.count if needed > 0 then @@ -880,7 +878,7 @@ end end - if AmrSendSettings.SendEnchantMaterials then + if AmrDb.SendSettings.SendEnchantMaterials then for k,v in pairs(enchantMaterials) do local needed = v.total - v.count if needed > 0 then @@ -895,7 +893,7 @@ message = message .. " " .. entry.needed .. "x " .. link count = count + 1 if count == 2 then - tinsert(self.messageQueue, {message = message, chatType = chatType, chatChannel = AmrSendSettings.SendTo}) + tinsert(self.messageQueue, {message = message, chatType = chatType, chatChannel = AmrDb.SendSettings.SendTo}) count = 0 message = L.AMR_SHOPPINGLISTTAB_CHAT_ROBOT_MESSAGE end @@ -903,7 +901,7 @@ end if count > 0 then - tinsert(self.messageQueue, {message = message, chatType = chatType, chatChannel = AmrSendSettings.SendTo}) + tinsert(self.messageQueue, {message = message, chatType = chatType, chatChannel = AmrDb.SendSettings.SendTo}) end self:SendNextMessage() diff -r 9793e8b683d2 -r e77e01abce98 ui/SummaryTab.lua --- a/ui/SummaryTab.lua Thu Jul 10 15:32:11 2014 -0700 +++ b/ui/SummaryTab.lua Mon Oct 13 21:28:32 2014 -0500 @@ -83,7 +83,7 @@ itemText:Hide() tab.upgradeItemHeader = itemText - for i = 1, #AskMrRobot.slotNames do + for i = 1, #AskMrRobot.slotIds do local itemText = tab:CreateFontString("AmrBadItemSlot" .. i, "ARTWORK", "GameFontWhite") itemText:SetPoint("TOPLEFT", "AmrBadItemSlot" .. (i-1), "BOTTOMLEFT", 0, -5) itemText:SetPoint("TOPRIGHT", "AmrBadItemSlot" .. (i-1), "BOTTOMRIGHT", 0, -5) @@ -102,7 +102,7 @@ tab.upgradeItemSlots = {} tab.upgradeItemNames = {} - for i = 1, #AskMrRobot.slotNames do + for i = 1, #AskMrRobot.slotIds do local itemText = tab:CreateFontString(nil, "ARTWORK", "GameFontWhite") if i == 1 then itemText:SetPoint("TOPLEFT", tab.upgradeSlotHeader, "BOTTOMLEFT", 0, -5) @@ -167,13 +167,8 @@ tab.enchantCount:SetText(L.AMR_SUMMARYTAB_ENCHANTS_TO_GO) tab.enchantCount:Hide() - tab.reforgeCount = tab:CreateFontString(nil, "ARTWORK", "GameFontWhite") - tab.reforgeCount:SetPoint("TOPLEFT", tab.enchantCount, "BOTTOMLEFT", 0, -5) - tab.reforgeCount:SetText(L.AMR_SUMMARYTAB_REFORGES_TO_GO) - tab.reforgeCount:Hide() - tab.instructions = tab:CreateFontString(nil, "ARTWORK", "GameFontWhite") - tab.instructions:SetPoint("TOPLEFT", tab.reforgeCount, "BOTTOMLEFT", 0, -15) + tab.instructions:SetPoint("TOPLEFT", tab.enchantCount, "BOTTOMLEFT", 0, -15) tab.instructions:SetText(L.AMR_SUMMARYTAB_VIEW_TABS) tab.instructions:Hide() @@ -191,17 +186,17 @@ end function AskMrRobot.SummaryTab:showBadItems() - local badItems = AskMrRobot.itemDiffs.items - local i = 2 - -- for all the bad items - for slotNum, badItem in AskMrRobot.sortSlots(badItems) do - if not badItem.needsUpgrade then - self.badItemSlots[i]:SetText(_G[strupper(AskMrRobot.slotNames[slotNum])]) + -- for all slots + for iSlot = 1, #AskMrRobot.slotIds do + local slotId = AskMrRobot.slotIds[iSlot] + local badItem = AskMrRobot.ComparisonResult.items[slotId] + if badItem ~= nil and not badItem.needsUpgrade then + self.badItemSlots[i]:SetText(AskMrRobot.slotDisplayText[slotId]) self.badItemSlots[i]:Show() if badItem.optimized then - self.badItemNames[i]:SetItemId(badItem.optimized.itemId, badItem.optimized.upgradeId, badItem.optimized.suffixId) + self.badItemNames[i]:SetItemId(badItem.optimized.id, badItem.optimized.upgradeId, badItem.optimized.suffixId) else self.badItemNames[i]:SetItemId(nil, 0, 0) end @@ -212,12 +207,14 @@ -- for all the upgrade items local j = 1 - for slotNum, badItem in AskMrRobot.sortSlots(badItems) do - if badItem.needsUpgrade then - self.upgradeItemSlots[j]:SetText(_G[strupper(AskMrRobot.slotNames[slotNum])]) + for iSlot = 1, #AskMrRobot.slotIds do + local slotId = AskMrRobot.slotIds[iSlot] + local badItem = AskMrRobot.ComparisonResult.items[slotId] + if badItem ~= nil and badItem.needsUpgrade then + self.upgradeItemSlots[j]:SetText(AskMrRobot.slotDisplayText[slotId]) self.upgradeItemSlots[j]:Show() if badItem.optimized then - self.upgradeItemNames[j]:SetItemId(badItem.optimized.itemId, badItem.optimized.upgradeId, badItem.optimized.suffixId) + self.upgradeItemNames[j]:SetItemId(badItem.optimized.id, badItem.optimized.upgradeId, badItem.optimized.suffixId) else self.upgradeItemNames[j]:SetItemId(nil, 0, 0) end @@ -236,46 +233,42 @@ self.optimizationSummary:Show() self.gemCount:Show() self.enchantCount:Show() - self.reforgeCount:Show() self.instructions:Show() self.specText:Show() local gemCount = 0 - for slotNum, badGems in pairs(AskMrRobot.itemDiffs.gems) do - for k, v in pairs(badGems.badGems) do - gemCount = gemCount + 1 + for slotNum, badGems in pairs(AskMrRobot.ComparisonResult.gems) do + --for k, v in pairs(badGems.badGems) do + --gemCount = gemCount + 1 + --end + for g = 1, 3 do + if not AskMrRobot.AreGemsCompatible(badGems.current[g], badGems.optimized[g]) then + gemCount = gemCount + 1 + end end end self.gemCount:SetFormattedText(L.AMR_SUMMARYTAB_GEMCOUNT, gemCount) local enchantCount = 0 - for slotNum, badEnchant in pairs(AskMrRobot.itemDiffs.enchants) do + for slotNum, badEnchant in pairs(AskMrRobot.ComparisonResult.enchants) do enchantCount = enchantCount + 1 end self.enchantCount:SetFormattedText(L.AMR_SUMMARYTAB_ENCHANTCOUNT, enchantCount) - local reforgeCount = 0 - for slotNum, badReforge in pairs(AskMrRobot.itemDiffs.reforges) do - reforgeCount = reforgeCount + 1 - end + self.optimizationSummary:SetFormattedText(L.AMR_SUMMARYTAB_OPTIMIZATIONCOUNT, gemCount + enchantCount) - self.reforgeCount:SetFormattedText(L.AMR_SUMMARYTAB_REFORGECOUNT, reforgeCount) - self.optimizationSummary:SetFormattedText(L.AMR_SUMMARYTAB_OPTIMIZATIONCOUNT, gemCount + enchantCount + reforgeCount) - - if gemCount + enchantCount + reforgeCount == 0 then + if gemCount + enchantCount == 0 then self.stamp:Show() self.optimizationSummary:Hide() self.enchantCount:Hide() - self.reforgeCount:Hide() self.instructions:Hide() self.gemCount:Hide() else self.stamp:Hide() self.optimizationSummary:Show() self.enchantCount:Show() - self.reforgeCount:Show() self.instructions:Show() self.gemCount:Show() end @@ -283,9 +276,9 @@ local activeSpecGroup = GetActiveSpecGroup() if activeSpecGroup == nil then - self.importInfo:SetFormattedText(L.AMR_SUMMARYTAB_LAST_IMPORT_1, self.importDate, UnitName("player")) + self.importInfo:SetFormattedText(L.AMR_SUMMARYTAB_LAST_IMPORT_1, AmrDb.LastCharacterImportDate, UnitName("player")) else - self.importInfo:SetFormattedText(L.AMR_SUMMARYTAB_LAST_IMPORT_2, self.importDate, UnitName("player")) + self.importInfo:SetFormattedText(L.AMR_SUMMARYTAB_LAST_IMPORT_2, AmrDb.LastCharacterImportDate, UnitName("player")) local spec = GetSpecialization(false, false, group); if spec then local _, name, _, icon = GetSpecializationInfo(spec); @@ -307,7 +300,6 @@ self.optimizationSummary:Hide() self.gemCount:Hide() self.enchantCount:Hide() - self.reforgeCount:Hide() self.instructions:Hide() self.specText:Hide() end @@ -403,7 +395,6 @@ self.stamp:Hide() self.gemCount:Hide() self.instructions:Hide() - self.reforgeCount:Hide() self.enchantCount:Hide() self.optimizationSummary:Hide() if text then @@ -423,11 +414,11 @@ self.errorText2:Hide() self.importInfo:Show() end - for i = 1, #AskMrRobot.slotNames + 1 do + for i = 1, #self.badItemSlots do self.badItemSlots[i]:Hide() self.badItemNames[i]:Hide() end - for i = 1, #AskMrRobot.slotNames do + for i = 1, #self.upgradeItemSlots do self.upgradeItemSlots[i]:Hide() self.upgradeItemNames[i]:Hide() end @@ -438,7 +429,6 @@ self.hasImportError = false self.gemCount:Hide() self.instructions:Hide() - self.reforgeCount:Hide() self.enchantCount:Hide() self.specIcon:Hide() self.specText:Hide()