adam@0: local _, AskMrRobot = ... yellowfive@11: local L = AskMrRobot.L; adam@0: adam@0: AskMrRobot.eventListener = CreateFrame("FRAME"); -- Need a frame to respond to events adam@0: AskMrRobot.eventListener:RegisterEvent("ADDON_LOADED"); -- Fired when saved variables are loaded adam@0: AskMrRobot.eventListener:RegisterEvent("ITEM_PUSH"); adam@0: AskMrRobot.eventListener:RegisterEvent("DELETE_ITEM_CONFIRM"); adam@0: AskMrRobot.eventListener:RegisterEvent("UNIT_INVENTORY_CHANGED"); adam@0: AskMrRobot.eventListener:RegisterEvent("BANKFRAME_OPENED"); adam@0: AskMrRobot.eventListener:RegisterEvent("BANKFRAME_CLOSED"); adam@0: AskMrRobot.eventListener:RegisterEvent("PLAYERBANKSLOTS_CHANGED"); adam@0: AskMrRobot.eventListener:RegisterEvent("CHARACTER_POINTS_CHANGED"); adam@0: AskMrRobot.eventListener:RegisterEvent("CONFIRM_TALENT_WIPE"); adam@0: AskMrRobot.eventListener:RegisterEvent("PLAYER_TALENT_UPDATE"); adam@0: AskMrRobot.eventListener:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED"); yellowfive@11: AskMrRobot.eventListener:RegisterEvent("PLAYER_ENTERING_WORLD"); adam@0: AskMrRobot.eventListener:RegisterEvent("PLAYER_LOGOUT"); -- Fired when about to log out adam@0: AskMrRobot.eventListener:RegisterEvent("PLAYER_LEVEL_UP"); adam@0: --AskMrRobot.eventListener:RegisterEvent("GET_ITEM_INFO_RECEIVED") adam@0: AskMrRobot.eventListener:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED") adam@0: AskMrRobot.eventListener:RegisterEvent("SOCKET_INFO_UPDATE") adam@0: AskMrRobot.eventListener:RegisterEvent("SOCKET_INFO_CLOSE") adam@0: AskMrRobot.eventListener:RegisterEvent("BAG_UPDATE") adam@0: AskMrRobot.eventListener:RegisterEvent("ITEM_UNLOCKED") yellowfive@11: AskMrRobot.eventListener:RegisterEvent("PLAYER_REGEN_DISABLED") yellowfive@11: --AskMrRobot.eventListener:RegisterEvent("ENCOUNTER_START") adam@0: AskMrRobot.eventListener:RegisterEvent("CHAT_MSG_ADDON") adam@0: AskMrRobot.eventListener:RegisterEvent("UPDATE_INSTANCE_INFO") adam@0: AskMrRobot.eventListener:RegisterEvent("PLAYER_DIFFICULTY_CHANGED") adam@0: adam@0: AskMrRobot.AddonName = ... adam@0: AskMrRobot.ChatPrefix = "_AMR" adam@0: adam@0: local amrLDB adam@0: local icon adam@0: local reforgequeue adam@0: local reforgeFrame = nil adam@0: local LoggingCombat = _G.LoggingCombat adam@0: adam@0: AskMrRobot.itemDiffs = { adam@0: items = {}, -- slotNum -> nil (no change) or current , optimized adam@0: enchants = {}, -- slotNum -> nil (no change) or current , optimized adam@0: gems = {}, -- slotNum -> nil (no change) or ? adam@0: reforges = {} -- slotNum -> nil (no change) or current , optimized adam@0: } adam@0: adam@0: AskMrRobot.instanceIds = { adam@0: HeartOfFear = 1009, adam@0: MogushanVaults = 1008, adam@0: SiegeOfOrgrimmar = 1136, adam@0: TerraceOfEndlessSpring = 996, adam@0: ThroneOfThunder = 1098 adam@0: } adam@0: yellowfive@11: -- instances that we currently support logging for yellowfive@11: AskMrRobot.supportedInstanceIds = { yellowfive@11: [1136] = true yellowfive@11: } yellowfive@11: yellowfive@11: -- returns true if currently in a supported instance yellowfive@11: function AskMrRobot.IsSupportedInstance() yellowfive@11: yellowfive@11: local zone, _, difficultyIndex, _, _, _, _, instanceMapID = GetInstanceInfo() yellowfive@11: if AskMrRobot.supportedInstanceIds[tonumber(instanceMapID)] then yellowfive@11: return true yellowfive@11: else yellowfive@11: return false yellowfive@11: end yellowfive@11: end yellowfive@11: adam@0: -- upgrade id -> upgrade level adam@0: local upgradeTable = { adam@0: [0] = 0, adam@0: [1] = 1, -- 1/1 -> 8 adam@0: [373] = 1, -- 1/2 -> 4 adam@0: [374] = 2, -- 2/2 -> 8 adam@0: [375] = 1, -- 1/3 -> 4 adam@0: [376] = 2, -- 2/3 -> 4 adam@0: [377] = 3, -- 3/3 -> 4 adam@0: [378] = 1, -- 1/1 -> 7 adam@0: [379] = 1, -- 1/2 -> 4 adam@0: [380] = 2, -- 2/2 -> 4 adam@0: [445] = 0, -- 0/2 -> 0 adam@0: [446] = 1, -- 1/2 -> 4 adam@0: [447] = 2, -- 2/2 -> 8 adam@0: [451] = 0, -- 0/1 -> 0 adam@0: [452] = 1, -- 1/1 -> 8 adam@0: [453] = 0, -- 0/2 -> 0 adam@0: [454] = 1, -- 1/2 -> 4 adam@0: [455] = 2, -- 2/2 -> 8 adam@0: [456] = 0, -- 0/1 -> 0 adam@0: [457] = 1, -- 1/1 -> 8 adam@0: [458] = 0, -- 0/4 -> 0 adam@0: [459] = 1, -- 1/4 -> 4 adam@0: [460] = 2, -- 2/4 -> 8 adam@0: [461] = 3, -- 3/4 -> 12 adam@0: [462] = 4, -- 4/4 -> 16 adam@0: [465] = 0, -- 0/2 -> 0 adam@0: [466] = 1, -- 1/2 -> 4 adam@0: [467] = 2, -- 2/2 -> 8 adam@0: [468] = 0, -- 0/4 -> 0 adam@0: [469] = 1, -- 1/4 -> 4 adam@0: [470] = 2, -- 2/4 -> 8 adam@0: [471] = 3, -- 3/4 -> 12 adam@0: [472] = 4, -- 4/4 -> 16 adam@0: [476] = 0, -- ? -> 0 adam@0: [479] = 0, -- ? -> 0 adam@0: [491] = 0, -- ? -> 0 adam@0: [492] = 1, -- ? -> 0 adam@0: [493] = 2, -- ? -> 0 adam@0: [494] = 0, adam@0: [495] = 1, adam@0: [496] = 2, adam@0: [497] = 3, adam@0: [498] = 4, adam@0: [504] = 3, yellowfive@11: [505] = 4, yellowfive@11: [506] = 5, yellowfive@11: [507] = 6 adam@0: } adam@0: adam@0: local professionIds = { adam@0: ["None"] = 0, adam@0: ["Mining"] = 1, adam@0: ["Skinning"] = 2, adam@0: ["Herbalism"] = 3, adam@0: ["Enchanting"] = 4, adam@0: ["Jewelcrafting"] = 5, adam@0: ["Engineering"] = 6, adam@0: ["Blacksmithing"] = 7, adam@0: ["Leatherworking"] = 8, adam@0: ["Inscription"] = 9, adam@0: ["Tailoring"] = 10, adam@0: ["Alchemy"] = 11, adam@0: ["Fishing"] = 12, adam@0: ["Cooking"] = 13, adam@0: ["First Aid"] = 14, adam@0: ["Archaeology"] = 15 adam@0: } adam@0: adam@0: local raceIds = { adam@0: ["None"] = 0, adam@0: ["BloodElf"] = 1, adam@0: ["Draenei"] = 2, adam@0: ["Dwarf"] = 3, adam@0: ["Gnome"] = 4, adam@0: ["Human"] = 5, adam@0: ["NightElf"] = 6, adam@0: ["Orc"] = 7, adam@0: ["Tauren"] = 8, adam@0: ["Troll"] = 9, adam@0: ["Scourge"] = 10, adam@0: ["Undead"] = 10, adam@0: ["Goblin"] = 11, adam@0: ["Worgen"] = 12, adam@0: ["Pandaren"] = 13 adam@0: } adam@0: adam@0: local factionIds = { adam@0: ["None"] = 0, adam@0: ["Alliance"] = 1, adam@0: ["Horde"] = 2 adam@0: } adam@0: adam@0: local function OnExport() adam@0: if (AmrOptions.exportToClient) then adam@0: AskMrRobot.SaveAll() adam@0: ReloadUI() adam@0: else adam@0: AskMrRobot_ReforgeFrame:Show() adam@0: AskMrRobot_ReforgeFrame:ShowTab("export") adam@0: end adam@0: end adam@0: adam@0: function AskMrRobot.eventListener:OnEvent(event, ...) adam@0: if event == "ADDON_LOADED" then adam@0: local addon = select(1, ...) adam@0: if (addon == "AskMrRobot") then yellowfive@11: print(L.AMR_ON_EVENT_LOADED.format(GetAddOnMetadata(AskMrRobot.AddonName, "Version"))) adam@0: adam@0: -- listen for messages from other AMR addons adam@0: RegisterAddonMessagePrefix(AskMrRobot.ChatPrefix) adam@0: adam@0: AmrRealmName = GetRealmName() adam@0: AmrCharacterName = UnitName("player") adam@0: yellowfive@11: AskMrRobot.CombatLogTab.InitializeVariable() adam@0: adam@0: if not AmrIconInfo then AmrIconInfo = {} end adam@0: if not AmrBankItems then AmrBankItems = {} end adam@0: if not AmrCurrencies then AmrCurrencies = {} end adam@0: if not AmrSpecializations then AmrSpecializations = {} end adam@0: if not AmrOptions then AmrOptions = {} end adam@0: if not AmrGlyphs then AmrGlyphs = {} end adam@0: if not AmrTalents then AmrTalents = {} end adam@0: if not AmrBankItemsAndCounts then AmrBankItemsAndCounts = {} end adam@0: if not AmrImportString then AmrImportString = "" end adam@0: if not AmrImportDate then AmrImportDate = "" end yellowfive@11: yellowfive@11: if not AmrSettings then AmrSettings = {} end yellowfive@11: if not AmrSettings.Logins then AmrSettings.Logins = {} end yellowfive@11: adam@0: if not AmrSendSettings then adam@0: AmrSendSettings = { adam@0: SendGems = true, adam@0: SendEnchants = true, adam@0: SendEnchantMaterials = true, adam@0: SendToType = "a friend", adam@0: SendTo = "" adam@0: } adam@0: end adam@0: adam@0: amrLDB = LibStub("LibDataBroker-1.1"):NewDataObject("AskMrRobot", { adam@0: type = "launcher", adam@0: text = "Ask Mr. Robot", adam@0: icon = "Interface\\AddOns\\AskMrRobot\\Media\\icon", adam@0: OnClick = function() yellowfive@11: if IsControlKeyDown() then yellowfive@11: AskMrRobot_ReforgeFrame.combatLogTab:LogWipe() yellowfive@11: elseif IsModifiedClick("CHATLINK") then adam@0: OnExport() adam@0: else adam@0: AskMrRobot_ReforgeFrame:Toggle() adam@0: end adam@0: end, adam@0: OnTooltipShow = function(tt) adam@0: tt:AddLine("Ask Mr. Robot", 1, 1, 1); adam@0: tt:AddLine(" "); yellowfive@11: tt:AddLine(L.AMR_ON_EVENT_TOOLTIP) adam@0: end adam@0: }); adam@0: adam@0: adam@0: AskMrRobot.AmrUpdateMinimap() adam@0: adam@0: AskMrRobot_ReforgeFrame = AskMrRobot.AmrUI:new() adam@0: adam@0: -- remember the import settings between sessions adam@0: AskMrRobot_ReforgeFrame.summaryTab.importDate = AmrImportDate or "" adam@0: AskMrRobot_ReforgeFrame.buttons[2]:Click() adam@0: adam@0: -- the previous import string is loaded when the UI is first shown, otherwise the game spams events and it lags adam@0: end adam@0: adam@0: 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 adam@0: if AskMrRobot_ReforgeFrame then adam@0: AskMrRobot_ReforgeFrame:OnUpdate() adam@0: end adam@0: --AskMrRobot.SaveBags(); adam@0: --AskMrRobot.SaveEquiped(); adam@0: --AskMrRonot.GetCurrencies(); adam@0: --AskMrRobot.GetGold(); adam@0: elseif event == "BANKFRAME_OPENED" or event == "PLAYERBANKSLOTS_CHANGED" then adam@0: --print("Scanning Bank: " .. event); adam@0: AskMrRobot.ScanBank(); adam@0: elseif event == "BANKFRAME_CLOSED" then adam@0: --print("Stop Scanning Bank"); adam@0: --inBank = false; adam@0: elseif event == "CHARACTER_POINTS_CHANGED" or event == "CONFIRM_TALENT_WIPE" or event == "PLAYER_TALENT_UPDATE" or event == "ACTIVE_TALENT_GROUP_CHANGED" then adam@0: --AskMrRobot.GetAmrSpecializations(); adam@0: if AskMrRobot_ReforgeFrame then adam@0: AskMrRobot_ReforgeFrame:OnUpdate() adam@0: end adam@0: elseif event == "PLAYER_LEVEL_UP" then adam@0: --GetLevel(); adam@0: elseif event == "ITEM_UNLOCKED" then adam@0: AskMrRobot.On_ITEM_UNLOCKED() adam@0: elseif event == "PLAYER_LOGOUT" then adam@0: -- doing nothing right now, but leaving this in case we need something here yellowfive@11: elseif event == "PLAYER_ENTERING_WORLD" then yellowfive@11: yellowfive@11: -- delete entries that are more than 10 days old to prevent the table from growing indefinitely yellowfive@13: if AmrSettings.Logins and #AmrSettings.Logins > 0 then yellowfive@13: local now = time() yellowfive@13: local oldDuration = 60 * 60 * 24 * 10 yellowfive@13: local entryTime yellowfive@13: repeat yellowfive@13: -- parse entry and get time yellowfive@13: local parts = {} yellowfive@13: for part in string.gmatch(AmrSettings.Logins[1], "([^;]+)") do yellowfive@13: tinsert(parts, part) yellowfive@13: end yellowfive@13: entryTime = tonumber(parts[3]) yellowfive@11: yellowfive@13: -- entries are in order, remove first entry if it is old yellowfive@13: if difftime(now, entryTime) > oldDuration then yellowfive@13: tremove(AmrSettings.Logins, 1) yellowfive@13: end yellowfive@13: until #AmrSettings.Logins == 0 or difftime(now, entryTime) <= oldDuration yellowfive@13: end yellowfive@11: yellowfive@11: -- record the time a player logs in, used to figure out which player logged which parts of their log file yellowfive@11: local key = AmrRealmName .. ";" .. AmrCharacterName .. ";" yellowfive@11: local loginData = key .. time() yellowfive@11: if AmrSettings.Logins and #AmrSettings.Logins > 0 then yellowfive@11: local last = AmrSettings.Logins[#AmrSettings.Logins] yellowfive@11: if string.len(last) >= string.len(key) and string.sub(last, 1, string.len(key)) ~= key then yellowfive@11: table.insert(AmrSettings.Logins, loginData) yellowfive@11: end yellowfive@11: else yellowfive@11: table.insert(AmrSettings.Logins, loginData) yellowfive@11: end yellowfive@11: yellowfive@11: elseif event == "PLAYER_REGEN_DISABLED" then yellowfive@11: yellowfive@11: -- send data about this character when a player enters combat in a supported zone yellowfive@11: if AskMrRobot.IsSupportedInstance() then yellowfive@11: local t = time() yellowfive@11: AskMrRobot.SaveAll() yellowfive@11: AskMrRobot.ExportToAddonChat(t) yellowfive@11: AskMrRobot.ExportLoggingData(t) yellowfive@11: end yellowfive@11: adam@0: elseif event == "CHAT_MSG_ADDON" then adam@0: local chatPrefix, message = select(1, ...) yellowfive@11: local isLogging = AskMrRobot_ReforgeFrame.combatLogTab:IsLogging() adam@0: if (isLogging and chatPrefix == AskMrRobot.ChatPrefix) then adam@0: AskMrRobot_ReforgeFrame.combatLogTab:ReadAddonMessage(message) adam@0: end adam@0: elseif event == "UPDATE_INSTANCE_INFO" or event == "PLAYER_DIFFICULTY_CHANGED" then adam@0: AskMrRobot_ReforgeFrame.combatLogTab:UpdateAutoLogging() adam@0: end adam@0: adam@0: end adam@0: adam@0: AskMrRobot.eventListener:SetScript("OnEvent", AskMrRobot.eventListener.OnEvent); adam@0: adam@0: local function parseItemLink(input) adam@0: 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+)|"); adam@0: local item = {} adam@0: item.itemId = tonumber(itemId) adam@0: item.suffixId = tonumber(suffixId) adam@0: item.enchantId = tonumber(enchantId) adam@0: item.reforgeId = tonumber(reforgeId) adam@0: item.upgradeId = tonumber(upgradeId) adam@0: item.gemEnchantIds = { tonumber(gemEnchantId1), tonumber(gemEnchantId2), tonumber(gemEnchantId3), tonumber(gemEnchantId4) } adam@0: return item adam@0: end adam@0: adam@0: SLASH_AMR1 = "/amr"; adam@0: function SlashCmdList.AMR(msg) adam@0: adam@0: if msg == 'toggle' then adam@0: AskMrRobot_ReforgeFrame:Toggle() adam@0: elseif msg == 'show' then adam@0: AskMrRobot_ReforgeFrame:Show() adam@0: elseif msg == 'hide' then adam@0: AskMrRobot_ReforgeFrame:Hide() adam@0: elseif msg == 'export' then adam@0: OnExport() yellowfive@11: elseif msg == 'wipe' then yellowfive@11: AskMrRobot_ReforgeFrame.combatLogTab:LogWipe() yellowfive@11: elseif msg == 'unwipe' then yellowfive@11: AskMrRobot_ReforgeFrame.combatLogTab:LogUnwipe() adam@0: else yellowfive@11: 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) adam@0: end adam@0: end adam@0: adam@0: function AskMrRobot.SaveAll() adam@0: AskMrRobot.ScanBank() adam@0: AskMrRobot.SaveBags() adam@0: AskMrRobot.SaveEquiped() adam@0: AskMrRobot.GetCurrencies() adam@0: AskMrRobot.GetGold() adam@0: AskMrRobot.GetAmrSpecializations() adam@0: AskMrRobot.GetAmrProfessions() adam@0: AskMrRobot.GetRace() adam@0: AskMrRobot.GetLevel() adam@0: AskMrRobot.GetAmrGlyphs() adam@0: AskMrRobot.GetAmrTalents() adam@0: --ReloadUI() adam@0: end adam@0: adam@0: local function InitIcon() adam@0: icon = LibStub("LibDBIcon-1.0"); yellowfive@11: icon:Register("AskMrRobot", amrLDB, AmrIconInfo); adam@0: end adam@0: yellowfive@11: function AskMrRobot.AmrUpdateMinimap() yellowfive@11: if AmrOptions.hideMapIcon then yellowfive@11: if icon then adam@0: icon:Hide("AskMrRobot"); adam@0: end adam@0: else yellowfive@11: if not icon then adam@0: InitIcon() adam@0: end yellowfive@11: --if AskMrRobot_ReforgeFrame.combatLogTab:IsLogging() then yellowfive@11: if AskMrRobot.CombatLogTab.IsLogging(nil) then yellowfive@11: amrLDB.icon = 'Interface\\AddOns\\AskMrRobot\\Media\\icon_green' yellowfive@11: else yellowfive@11: amrLDB.icon = 'Interface\\AddOns\\AskMrRobot\\Media\\icon' yellowfive@11: end adam@0: icon:Show("AskMrRobot"); adam@0: end adam@0: end adam@0: adam@0: local function getToolTipText(tip) adam@0: return EnumerateTooltipLines_helper(tip:GetRegions()) adam@0: end adam@0: adam@0: local bagItems = {} adam@0: local bagItemsWithCount = {} adam@0: adam@0: function AskMrRobot.ScanBag(bagId) adam@0: local numSlots = GetContainerNumSlots(bagId); adam@0: for slotId = 1, numSlots do adam@0: local _, itemCount, _, _, _, _, itemLink = GetContainerItemInfo(bagId, slotId); adam@0: if itemLink ~= nil then adam@0: local itemData = parseItemLink(itemLink) adam@0: if itemData.itemId ~= nil then adam@0: tinsert(bagItems, itemLink); adam@0: tinsert(bagItemsWithCount, {link = itemLink, count = itemCount}) adam@0: end adam@0: end adam@0: end adam@0: end adam@0: adam@0: local BACKPACK_CONTAINER = 0; adam@0: local BANK_CONTAINER = -1; adam@0: adam@0: function AskMrRobot.ScanEquiped() adam@0: local equipedItems = {}; adam@0: for slotNum = 1, #AskMrRobot.slotIds do adam@0: local slotId = AskMrRobot.slotIds[slotNum]; adam@0: local itemLink = GetInventoryItemLink("player", slotId); adam@0: if (itemLink ~= nil) then adam@0: equipedItems[slotId .. ""] = itemLink; adam@0: end adam@0: end adam@0: return equipedItems adam@0: end adam@0: adam@0: function AskMrRobot.SaveEquiped() adam@0: AmrEquipedItems = AskMrRobot.ScanEquiped(); adam@0: end adam@0: adam@0: function AskMrRobot.ScanBags() adam@0: bagItems = {} adam@0: bagItemsWithCount = {} adam@0: adam@0: AskMrRobot.ScanBag(BACKPACK_CONTAINER); -- backpack adam@0: adam@0: for bagId = 1, NUM_BAG_SLOTS do adam@0: AskMrRobot.ScanBag(bagId); adam@0: end adam@0: adam@0: adam@0: return bagItems, bagItemsWithCount adam@0: end adam@0: adam@0: function AskMrRobot.SaveBags() adam@0: AmrBagItems, _ = AskMrRobot.ScanBags() adam@0: end adam@0: adam@0: function AskMrRobot.GetGold() adam@0: AmrGold = GetMoney(); adam@0: end adam@0: adam@0: local lastBankBagId = nil; adam@0: local lastBankSlotId = nil; adam@0: local bankItems = {}; adam@0: local bankItemsAndCount = {}; adam@0: AmrBankItemsAndCounts = {}; adam@0: adam@0: local function ScanBankBag(bagId) adam@0: local numSlots = GetContainerNumSlots(bagId); adam@0: for slotId = 1, numSlots do adam@0: local _, itemCount, _, _, _, _, itemLink = GetContainerItemInfo(bagId, slotId); adam@0: if itemLink ~= nil then adam@0: local itemData = parseItemLink(itemLink) adam@0: if itemData.itemId ~= nil then adam@0: lastBankBagId = bagId; adam@0: lastBankSlotId = slotId; adam@0: tinsert(bankItems, itemLink); adam@0: tinsert(bankItemsAndCount, {link = itemLink, count = itemCount}) adam@0: end adam@0: end adam@0: end adam@0: end adam@0: adam@0: function AskMrRobot.ScanBank() adam@0: adam@0: bankItems = {}; adam@0: bankItemsAndCount = {} adam@0: adam@0: ScanBankBag(BANK_CONTAINER); adam@0: for bagId = NUM_BAG_SLOTS + 1, NUM_BAG_SLOTS + NUM_BANKBAGSLOTS do adam@0: ScanBankBag(bagId); adam@0: end adam@0: adam@0: -- see if the scan completed before the window closed adam@0: if lastBankBagId ~= nil then adam@0: local itemLink = GetContainerItemLink(lastBankBagId, lastBankSlotId); adam@0: if itemLink ~= nil then --still open adam@0: AmrBankItems = bankItems; adam@0: AmrBankItemsAndCounts = bankItemsAndCount adam@0: end adam@0: end adam@0: end adam@0: adam@0: local function GetCurrencyAmount(index) adam@0: local localized_label, amount, icon_file_name = GetCurrencyInfo(index); adam@0: return amount; adam@0: end adam@0: adam@0: function AskMrRobot.GetCurrencies() adam@0: local currencies = {}; adam@0: 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}; adam@0: adam@0: for i, currency in pairs(currencyList) do adam@0: local amount = GetCurrencyAmount(currency); adam@0: if amount ~= 0 then adam@0: currencies[currencyList[i]] = amount; adam@0: end adam@0: end adam@0: AmrCurrencies = currencies; adam@0: end adam@0: adam@0: local function GetAmrSpecialization(specGroup) adam@0: local spec = GetSpecialization(false, false, specGroup); adam@0: return spec and GetSpecializationInfo(spec); adam@0: end adam@0: adam@0: function AskMrRobot.GetAmrSpecializations() adam@0: adam@0: AmrSpecializations = {}; adam@0: adam@0: AmrActiveSpec = GetActiveSpecGroup(); adam@0: adam@0: for group = 1, 2 do adam@0: AmrSpecializations[group .. ""] = GetAmrSpecialization(group) adam@0: end adam@0: adam@0: -- Death Knight adam@0: -- 250 - Blood adam@0: -- 251 - Frost adam@0: -- 252 - Unholy adam@0: -- Druid adam@0: -- 102 - Balance adam@0: -- 103 - Feral Combat adam@0: -- 104 - Guardian adam@0: -- 105 - Restoration adam@0: -- Hunter adam@0: -- 253 - Beast Mastery adam@0: -- 254 - Marksmanship adam@0: -- 255 - Survival adam@0: -- Mage adam@0: -- 62 - Arcane adam@0: -- 63 - Fire adam@0: -- 64 - Frost adam@0: -- Monk adam@0: -- 268 - Brewmaster adam@0: -- 269 - Windwalker adam@0: -- 270 - Mistweaver adam@0: -- Paladin adam@0: -- 65 - Holy adam@0: -- 66 - Protection adam@0: -- 70 - Retribution adam@0: -- Priest adam@0: -- 256 Discipline adam@0: -- 257 Holy adam@0: -- 258 Shadow adam@0: -- Rogue adam@0: -- 259 - Assassination adam@0: -- 260 - Combat adam@0: -- 261 - Subtlety adam@0: -- Shaman adam@0: -- 262 - Elemental adam@0: -- 263 - Enhancement adam@0: -- 264 - Restoration adam@0: -- Warlock adam@0: -- 265 - Affliction adam@0: -- 266 - Demonology adam@0: -- 267 - Destruction adam@0: -- Warrior adam@0: -- 71 - Arms adam@0: -- 72 - Fury adam@0: -- 73 - Protection adam@0: end adam@0: adam@0: function AskMrRobot.GetAmrProfessions() adam@0: adam@0: local profMap = { adam@0: [794] = "Archaeology", adam@0: [171] = "Alchemy", adam@0: [164] = "Blacksmithing", adam@0: [185] = "Cooking", adam@0: [333] = "Enchanting", adam@0: [202] = "Engineering", adam@0: [129] = "First Aid", adam@0: [356] = "Fishing", adam@0: [182] = "Herbalism", adam@0: [773] = "Inscription", adam@0: [755] = "Jewelcrafting", adam@0: [165] = "Leatherworking", adam@0: [186] = "Mining", adam@0: [393] = "Skinning", adam@0: [197] = "Tailoring" adam@0: } adam@0: adam@0: local prof1, prof2, archaeology, fishing, cooking, firstAid = GetProfessions(); adam@0: AmrProfessions = {}; adam@0: if prof1 then adam@0: local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(prof1); adam@0: if profMap[skillLine] ~= nil then adam@0: AmrProfessions[profMap[skillLine]] = skillLevel; adam@0: end adam@0: end adam@0: if prof2 then adam@0: local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(prof2); adam@0: if profMap[skillLine] ~= nil then adam@0: AmrProfessions[profMap[skillLine]] = skillLevel; adam@0: end adam@0: end adam@0: if archaeology then adam@0: local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(archaeology); adam@0: if profMap[skillLine] ~= nil then adam@0: AmrProfessions[profMap[skillLine]] = skillLevel; adam@0: end adam@0: end adam@0: if fishing then adam@0: local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(fishing); adam@0: if profMap[skillLine] ~= nil then adam@0: AmrProfessions[profMap[skillLine]] = skillLevel; adam@0: end adam@0: end adam@0: if cooking then adam@0: local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(cooking); adam@0: if profMap[skillLine] ~= nil then adam@0: AmrProfessions[profMap[skillLine]] = skillLevel; adam@0: end adam@0: end adam@0: if firstAid then adam@0: local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(firstAid); adam@0: if profMap[skillLine] ~= nil then adam@0: AmrProfessions[profMap[skillLine]] = skillLevel; adam@0: end adam@0: end adam@0: end adam@0: adam@0: function AskMrRobot.GetRace() adam@0: local race, raceEn = UnitRace("player"); adam@0: AmrRace = raceEn; adam@0: AmrFaction = UnitFactionGroup("player"); adam@0: end adam@0: adam@0: function AskMrRobot.GetLevel() adam@0: AmrLevel = UnitLevel("player"); adam@0: end adam@0: adam@0: local SlotNames = { adam@0: "HeadSlot", adam@0: "NeckSlot", adam@0: "ShoulderSlot", adam@0: "ShirtSlot", adam@0: "ChestSlot", adam@0: "WaistSlot", adam@0: "LegsSlot", adam@0: "FeetSlot", adam@0: "WristSlot", adam@0: "HandsSlot", adam@0: "Finger0Slot", adam@0: "Finger1Slot", adam@0: "Trinket0Slot", adam@0: "Trinket1Slot", adam@0: "BackSlot", adam@0: "MainHandSlot", adam@0: "SecondaryHandSlot", adam@0: -- "RangedSlot", adam@0: "TabardSlot", adam@0: } adam@0: adam@0: local function GetAmrTalentsForSpec(spec) adam@0: local talentInfo = {} adam@0: local maxTiers = 6 adam@0: for talent = 1, GetNumTalents() do adam@0: local name, texture, tier, column, selected, available = GetTalentInfo(talent, false, spec) adam@0: if tier > maxTiers then adam@0: maxTiers = tier adam@0: end adam@0: if selected then adam@0: talentInfo[tier] = column adam@0: end adam@0: end adam@0: adam@0: local str = "" adam@0: for i = 1, maxTiers do adam@0: if talentInfo[i] then adam@0: str = str .. talentInfo[i] adam@0: else adam@0: str = str .. '0' adam@0: end adam@0: end adam@0: adam@0: return str adam@0: end adam@0: adam@0: function AskMrRobot.GetAmrTalents() adam@0: AmrTalents = {} adam@0: for spec = 1, GetNumSpecGroups() do adam@0: AmrTalents[spec] = GetAmrTalentsForSpec(spec); adam@0: end adam@0: end adam@0: adam@0: local function GetAmrGlyphsForSpec(spec) adam@0: local glyphs = {} adam@0: for i = 1, NUM_GLYPH_SLOTS do adam@0: local _, _, _, glyphSpellID, _, glyphID = GetGlyphSocketInfo(i, spec) adam@0: if (glyphID) then adam@0: tinsert(glyphs, glyphSpellID) adam@0: end adam@0: end adam@0: return glyphs; adam@0: end adam@0: adam@0: function AskMrRobot.GetAmrGlyphs() adam@0: AmrGlyphs = {} adam@0: for spec = 1, GetNumSpecGroups() do adam@0: AmrGlyphs[spec] = GetAmrGlyphsForSpec(spec) adam@0: end adam@0: end adam@0: adam@0: --[[ adam@0: local function ItemLinkToExportString(itemLink, slot) adam@0: local itemData = parseItemLink(itemLink) adam@0: local ret = {} adam@0: table.insert(ret, slot) adam@0: table.insert(ret, itemData.itemId) adam@0: table.insert(ret, itemData.suffixId) adam@0: table.insert(ret, itemData.upgradeId) adam@0: table.insert(ret, itemData.gemEnchantIds[1]) adam@0: table.insert(ret, itemData.gemEnchantIds[2]) adam@0: table.insert(ret, itemData.gemEnchantIds[3]) adam@0: table.insert(ret, itemData.enchantId) adam@0: table.insert(ret, itemData.reforgeId) adam@0: return table.concat(ret, ":") adam@0: end adam@0: ]] adam@0: adam@0: local function toCompressedNumberList(list) adam@0: -- ensure the values are numbers, sorted from lowest to highest adam@0: local nums = {} adam@0: for i, v in ipairs(list) do adam@0: table.insert(nums, tonumber(v)) adam@0: end adam@0: table.sort(nums) adam@0: adam@0: local ret = {} adam@0: local prev = 0 adam@0: for i, v in ipairs(nums) do adam@0: local diff = v - prev adam@0: table.insert(ret, diff) adam@0: prev = v adam@0: end adam@0: adam@0: return table.concat(ret, ",") adam@0: end adam@0: adam@0: -- create a more compact but less readable string adam@0: function AskMrRobot.ExportToCompressedString(includeInventory) adam@0: local fields = {} adam@0: adam@0: -- compressed string uses a fixed order rather than inserting identifiers adam@0: table.insert(fields, GetAddOnMetadata(AskMrRobot.AddonName, "Version")) adam@0: table.insert(fields, AmrRealmName) adam@0: table.insert(fields, AmrCharacterName) adam@0: adam@0: -- guild name adam@0: local guildName = GetGuildInfo("player") adam@0: if guildName == nil then adam@0: table.insert(fields, "") adam@0: else adam@0: table.insert(fields, guildName) adam@0: end adam@0: adam@0: -- race, default to pandaren if we can't read it for some reason adam@0: local raceval = raceIds[AmrRace] adam@0: if raceval == nil then raceval = 13 end adam@0: table.insert(fields, raceval) adam@0: adam@0: -- faction, default to alliance if we can't read it for some reason adam@0: raceval = factionIds[AmrFaction] adam@0: if raceval == nil then raceval = 1 end adam@0: table.insert(fields, raceval) adam@0: adam@0: table.insert(fields, AmrLevel) adam@0: adam@0: local profs = {} adam@0: local noprofs = true yellowfive@11: if AmrProfessions then yellowfive@11: for k, v in pairs(AmrProfessions) do yellowfive@11: local profval = professionIds[k] yellowfive@11: if profval ~= nil then yellowfive@11: noprofs = false yellowfive@11: table.insert(profs, profval .. ":" .. v) yellowfive@11: end yellowfive@11: end yellowfive@11: end adam@0: adam@0: if noprofs then adam@0: table.insert(profs, "0:0") adam@0: end adam@0: adam@0: table.insert(fields, table.concat(profs, ",")) adam@0: adam@0: if (AmrActiveSpec ~= nil) then adam@0: table.insert(fields, AmrActiveSpec) adam@0: table.insert(fields, AmrSpecializations[AmrActiveSpec .. ""]) adam@0: table.insert(fields, AmrTalents[AmrActiveSpec]) adam@0: table.insert(fields, toCompressedNumberList(AmrGlyphs[AmrActiveSpec])) adam@0: else adam@0: table.insert(fields, "_") adam@0: table.insert(fields, "_") adam@0: table.insert(fields, "_") adam@0: table.insert(fields, "_") adam@0: end adam@0: adam@0: -- convert items to parsed objects, sorted by id adam@0: local itemObjects = {} yellowfive@11: if AmrEquipedItems then yellowfive@11: for k, v in pairs(AmrEquipedItems) do yellowfive@11: local itemData = parseItemLink(v) yellowfive@11: itemData.slot = k yellowfive@11: table.insert(itemObjects, itemData) yellowfive@11: end yellowfive@11: end adam@0: adam@0: -- if desired, include bank/bag items too adam@0: if includeInventory then yellowfive@11: if AmrBagItems then yellowfive@11: for i, v in ipairs(AmrBagItems) do yellowfive@11: local itemData = parseItemLink(v) yellowfive@11: if itemData.itemId ~= nil then yellowfive@11: table.insert(itemObjects, itemData) yellowfive@11: end yellowfive@11: end yellowfive@11: end yellowfive@11: if AmrBankItems then yellowfive@11: for i, v in ipairs(AmrBankItems) do yellowfive@11: local itemData = parseItemLink(v) yellowfive@11: if itemData.itemId ~= nil then yellowfive@11: table.insert(itemObjects, itemData) yellowfive@11: end yellowfive@11: end yellowfive@11: end adam@0: end adam@0: adam@0: -- sort by item id so we can compress it more easily adam@0: table.sort(itemObjects, function(a, b) return a.itemId < b.itemId end) adam@0: adam@0: -- append to the export string adam@0: local prevItemId = 0 adam@0: local prevGemId = 0 adam@0: local prevEnchantId = 0 adam@0: for i, itemData in ipairs(itemObjects) do adam@0: adam@0: local itemParts = {} adam@0: adam@0: table.insert(itemParts, itemData.itemId - prevItemId) adam@0: prevItemId = itemData.itemId adam@0: adam@0: if itemData.slot ~= nil then table.insert(itemParts, "s" .. itemData.slot) end adam@0: if itemData.suffixId ~= 0 then table.insert(itemParts, "f" .. itemData.suffixId) end adam@0: if upgradeTable[itemData.upgradeId] ~= 0 then table.insert(itemParts, "u" .. upgradeTable[itemData.upgradeId]) end adam@0: if itemData.gemEnchantIds[1] ~= 0 then adam@0: table.insert(itemParts, "a" .. (itemData.gemEnchantIds[1] - prevGemId)) adam@0: prevGemId = itemData.gemEnchantIds[1] adam@0: end adam@0: if itemData.gemEnchantIds[2] ~= 0 then adam@0: table.insert(itemParts, "b" .. (itemData.gemEnchantIds[2] - prevGemId)) adam@0: prevGemId = itemData.gemEnchantIds[2] adam@0: end adam@0: if itemData.gemEnchantIds[3] ~= 0 then adam@0: table.insert(itemParts, "c" .. (itemData.gemEnchantIds[3] - prevGemId)) adam@0: prevGemId = itemData.gemEnchantIds[3] adam@0: end adam@0: if itemData.enchantId ~= 0 then adam@0: table.insert(itemParts, "e" .. (itemData.enchantId - prevEnchantId)) adam@0: prevEnchantId = itemData.enchantId adam@0: end adam@0: if itemData.reforgeId ~= 0 then table.insert(itemParts, "r" .. (itemData.reforgeId - 113)) end adam@0: adam@0: table.insert(fields, table.concat(itemParts, "")) adam@0: end yellowfive@11: adam@0: return "$" .. table.concat(fields, ";") .. "$" adam@0: end adam@0: yellowfive@11: local function GetPlayerExtraData(data, index) yellowfive@11: yellowfive@11: local unitId = "raid" .. index yellowfive@11: yellowfive@11: local guid = UnitGUID(unitId) yellowfive@11: if guid == nil then yellowfive@11: return nil yellowfive@11: end yellowfive@11: yellowfive@11: local fields = {} yellowfive@11: yellowfive@11: local buffs = {} yellowfive@11: for i=1,40 do yellowfive@11: local _,_,_,count,_,_,_,_,_,_,spellId = UnitAura(unitId, i, "HELPFUL") yellowfive@11: table.insert(buffs, spellId) yellowfive@11: end yellowfive@11: if #buffs == 0 then yellowfive@11: table.insert(fields, "_") yellowfive@11: else yellowfive@11: table.insert(fields, toCompressedNumberList(buffs)) yellowfive@11: end yellowfive@11: yellowfive@11: local petGuid = UnitGUID("raidpet" .. index) yellowfive@11: if petGuid then yellowfive@11: table.insert(fields, guid .. "," .. petGuid) yellowfive@11: else yellowfive@11: table.insert(fields, '_') yellowfive@11: end yellowfive@11: yellowfive@11: local name = GetRaidRosterInfo(index) yellowfive@11: local realm = GetRealmName() yellowfive@11: local splitPos = string.find(name, "-") yellowfive@11: if splitPos ~= nil then yellowfive@11: realm = string.sub(name, splitPos + 1) yellowfive@11: name = string.sub(name, 1, splitPos - 1) yellowfive@11: end yellowfive@11: yellowfive@11: data[realm .. ":" .. name] = table.concat(fields, ";") yellowfive@11: end yellowfive@11: yellowfive@11: function AskMrRobot.ExportLoggingData(timestamp) yellowfive@11: yellowfive@11: local isLogging = AskMrRobot_ReforgeFrame.combatLogTab:IsLogging() yellowfive@11: if not isLogging then yellowfive@11: return yellowfive@11: end yellowfive@11: yellowfive@11: -- we only get extra information for people if in a raid yellowfive@11: if not IsInRaid() then yellowfive@11: return yellowfive@11: end yellowfive@11: yellowfive@11: local data = {} yellowfive@11: for i = 1,40 do yellowfive@11: GetPlayerExtraData(data, i) yellowfive@11: end yellowfive@11: yellowfive@11: AskMrRobot.CombatLogTab.SaveExtras(data, timestamp) yellowfive@11: end yellowfive@11: adam@0: function AskMrRobot.ExportToAddonChat(timestamp) yellowfive@11: local msg = AskMrRobot.ExportToCompressedString(false) adam@0: local msgPrefix = timestamp .. "\n" .. AmrRealmName .. "\n" .. AmrCharacterName .. "\n" adam@0: adam@0: -- break the data into 250 character chunks (to deal with the short limit on addon message size) adam@0: local chunks = {} adam@0: local i = 1 yellowfive@11: local length = string.len(msg) adam@0: local chunkLen = 249 - string.len(msgPrefix) adam@0: while (i <= length) do adam@0: local endpos = math.min(i + chunkLen, length) yellowfive@11: table.insert(chunks, msgPrefix .. string.sub(msg, i, endpos)) adam@0: i = endpos + 1 adam@0: end adam@0: adam@0: for i, v in ipairs(chunks) do adam@0: SendAddonMessage(AskMrRobot.ChatPrefix, v, "RAID") adam@0: end adam@0: adam@0: -- send a completion message adam@0: SendAddonMessage(AskMrRobot.ChatPrefix, msgPrefix .. "done", "RAID") adam@0: end adam@0: adam@0: -- Create an export string that can be copied to the website adam@0: function AskMrRobot.ExportToString() adam@0: adam@0: --[[ adam@0: local fields = {} adam@0: adam@0: fields["realm"] = AmrRealmName adam@0: fields["name"] = AmrCharacterName adam@0: fields["race"] = AmrRace adam@0: fields["faction"] = AmrFaction adam@0: fields["level"] = AmrLevel adam@0: adam@0: local profs = {} adam@0: for k, v in pairs(AmrProfessions) do adam@0: table.insert(profs, k .. ":" .. v) adam@0: end adam@0: fields["professions"] = table.concat(profs, ",") adam@0: adam@0: if (AmrActiveSpec ~= nil) then adam@0: fields["activespec"] = AmrActiveSpec adam@0: fields["spec"] = AmrSpecializations[AmrActiveSpec .. ""] adam@0: fields["talents"] = AmrTalents[AmrActiveSpec] adam@0: fields["glyphs"] = table.concat(AmrGlyphs[AmrActiveSpec], ",") adam@0: end adam@0: adam@0: local items = {} adam@0: for k, v in pairs(AmrEquipedItems) do adam@0: table.insert(items, ItemLinkToExportString(v, k)) adam@0: end adam@0: for i, v in ipairs(AmrBagItems) do adam@0: table.insert(items, ItemLinkToExportString(v, "-1")) adam@0: end adam@0: for i, v in ipairs(AmrBankItems) do adam@0: table.insert(items, ItemLinkToExportString(v, "-1")) adam@0: end adam@0: fields["items"] = table.concat(items, "_") adam@0: adam@0: local fieldList = {} adam@0: for k, v in pairs(fields) do adam@0: table.insert(fieldList, k .. "=" .. v) adam@0: end adam@0: ]] adam@0: adam@0: --return table.concat(fieldList, ";") adam@0: adam@0: return AskMrRobot.ExportToCompressedString(true) adam@0: --return AskMrRobot.ExportToAddonChat(time()) adam@0: end adam@0: adam@0: local function parseGlyphs(input) adam@0: local glyphs = {} adam@0: for glyph in string.gmatch(input, "([^,]+)") do adam@0: tinsert(glyphs, glyph) adam@0: end adam@0: table.sort(glyphs) adam@0: return glyphs adam@0: end adam@0: adam@0: local function parseProfessions(input) adam@0: local professions = {} adam@0: for prof, v in string.gmatch(input, "([^:,]+):([^,]+)") do adam@0: professions[prof] = tonumber(v); adam@0: end adam@0: return professions; adam@0: end adam@0: adam@0: local gemColorMapping = { adam@0: y = 'Yellow', adam@0: b = 'Blue', adam@0: r = 'Red', adam@0: h = 'Hydraulic', adam@0: p = 'Prismatic', adam@0: m = 'Meta', adam@0: c = 'Cogwheel' adam@0: } adam@0: adam@0: local function parseAmrItem(input) adam@0: local slot, itemId, suffixList, upgradeId, gemColorString, gemEnchantIdString, gemIdString, enchantId, reforgeId = string.match(input, "^(%d+):(%d+):([^:]+):([^:]+):([^:]+):([^:]+):([^:]+):(%d+):(%d+)"); adam@0: -- parse the gem enchant ids out of their comma seperated list adam@0: local gems = {} adam@0: for gemEnchantId in string.gmatch(gemEnchantIdString, '(%d+)') do adam@0: tinsert(gems, {enchantId = tonumber(gemEnchantId), id = 0}) adam@0: end adam@0: -- make sure we have 4 gem ids adam@0: for i = #gems + 1, 4 do adam@0: tinsert(gems, {enchantId = 0, id = 0}) adam@0: end adam@0: -- parse the gem ids out of their comma seperated list adam@0: local gemIds = {} adam@0: i = 1 adam@0: for gemId in string.gmatch(gemIdString, '(%d+)') do adam@0: gems[i].id = tonumber(gemId) adam@0: i = i + 1 adam@0: end adam@0: i = 1 adam@0: for gemColor in string.gmatch(gemColorString, '([^,])') do adam@0: gems[i].color = gemColorMapping[gemColor] adam@0: i = i + 1 adam@0: end adam@0: adam@0: -- parse the possible suffixes out of their comma seperated list and put them in a set (number -> bool) adam@0: local suffixes = {} adam@0: for suffixId in string.gmatch(suffixList, '(%-?%d+)') do adam@0: suffixes[tonumber(suffixId)] = true adam@0: end adam@0: adam@0: local item = { adam@0: itemId = tonumber(itemId), adam@0: suffixes = suffixes, adam@0: upgradeId = tonumber(upgradeId), adam@0: gems = gems, adam@0: enchantId = tonumber(enchantId), adam@0: reforgeId = tonumber(reforgeId) adam@0: } adam@0: return slot, item adam@0: end adam@0: adam@0: adam@0: function AskMrRobot.parseAmr(input) adam@0: local parsedInput = {} adam@0: parsedInput.items = {} adam@0: for k, v in string.gmatch(input, "([^=;]+)=([^;]*)") do adam@0: if (k == 'item') then adam@0: local slot, item = parseAmrItem(v); adam@0: parsedInput.items[AskMrRobot.slotIdToSlotNum[tonumber(slot) + 1]] = item; adam@0: elseif (k == 'glyphs') then adam@0: parsedInput.glyphs = parseGlyphs(v) adam@0: elseif (k == 'professions') then adam@0: parsedInput.professions = parseProfessions(v) adam@0: else adam@0: parsedInput[k]=v adam@0: end adam@0: end adam@0: return parsedInput adam@0: end adam@0: adam@0: function AskMrRobot.validateRealm(realm) adam@0: return realm == GetRealmName(); adam@0: end adam@0: adam@0: function AskMrRobot.validateCharacterName(characterName) adam@0: return UnitName("player") == characterName adam@0: end adam@0: adam@0: function AskMrRobot.validateRace(race) adam@0: local _, raceEn = UnitRace("player") adam@0: return raceEn == race or (raceEn == "Scourge" and race == "Undead") adam@0: end adam@0: adam@0: function AskMrRobot.validateFaction(faction) adam@0: return faction == UnitFactionGroup("player") adam@0: end adam@0: adam@0: function AskMrRobot.validateSpec(spec) adam@0: if spec == 'nil' then adam@0: spec = nil adam@0: end adam@0: local currentSpec = GetAmrSpecialization(GetActiveSpecGroup()) adam@0: return (not currentSpec and not spec) or tostring(currentSpec) == spec adam@0: end adam@0: adam@0: function AskMrRobot.validateTalents(talents) adam@0: if talents == nil then adam@0: talents = '' adam@0: end adam@0: return talents == GetAmrTalentsForSpec(GetActiveSpecGroup()) adam@0: end adam@0: adam@0: function AskMrRobot.validateGlyphs(glyphs) adam@0: if (glyphs == nil) then adam@0: glyphs = {}; adam@0: end adam@0: local currentGlyphs = GetAmrGlyphsForSpec(GetActiveSpecGroup()) adam@0: table.sort(glyphs, function(a,b) return tostring(a) < tostring(b) end) adam@0: table.sort(currentGlyphs, function(a,b) return tostring(a) < tostring(b) end) adam@0: adam@0: if #glyphs ~= #currentGlyphs then adam@0: return false adam@0: end adam@0: for i = 1, #glyphs do adam@0: if tostring(glyphs[i]) ~= tostring(currentGlyphs[i]) then adam@0: return false adam@0: end adam@0: end adam@0: adam@0: return true adam@0: end adam@0: adam@0: local function getPrimaryProfessions() adam@0: local profs = {} adam@0: local prof1, prof2 = GetProfessions() adam@0: local profMap = { adam@0: [794] = "Archaeology", adam@0: [171] = "Alchemy", adam@0: [164] = "Blacksmithing", adam@0: [185] = "Cooking", adam@0: [333] = "Enchanting", adam@0: [202] = "Engineering", adam@0: [129] = "First Aid", adam@0: [356] = "Fishing", adam@0: [182] = "Herbalism", adam@0: [773] = "Inscription", adam@0: [755] = "Jewelcrafting", adam@0: [165] = "Leatherworking", adam@0: [186] = "Mining", adam@0: [393] = "Skinning", adam@0: [197] = "Tailoring" adam@0: } adam@0: adam@0: if prof1 then adam@0: local _, _, skillLevel, _, _, _, skillLine = GetProfessionInfo(prof1); adam@0: if profMap[skillLine] ~= nil then adam@0: profs[profMap[skillLine]] = skillLevel adam@0: end adam@0: end adam@0: if prof2 then adam@0: local _, _, skillLevel, _, _, _, skillLine = GetProfessionInfo(prof2); adam@0: if profMap[skillLine] ~= nil then adam@0: profs[profMap[skillLine]] = skillLevel adam@0: end adam@0: end adam@0: return profs; adam@0: end adam@0: adam@0: local professionThresholds = { adam@0: Leatherworking = 575, adam@0: Inscription = 600, adam@0: Alchemy = 50, adam@0: Enchanting = 550, adam@0: Jewelcrafting = 550, adam@0: Blacksmithing = 550, adam@0: Tailoring = 550 adam@0: } adam@0: adam@0: function AskMrRobot.validateProfessions(professions) adam@0: local currentProfessions = getPrimaryProfessions() adam@0: if #currentProfessions ~= #professions then adam@0: return false adam@0: end adam@0: for k, v in pairs(professions) do adam@0: if currentProfessions[k] then adam@0: local threshold = professionThresholds[k] adam@0: if not threshold then adam@0: threshold = 1 adam@0: end adam@0: -- compare the desired profession against the threshold adam@0: local desired = v >= threshold adam@0: -- compare the current profession against the threshold adam@0: local has = currentProfessions[k] and currentProfessions[k] >= threshold adam@0: -- if the current value is on the other side of the threshold adam@0: -- then we don't match adam@0: if desired ~= has then adam@0: return false adam@0: end adam@0: else adam@0: return false adam@0: end adam@0: end adam@0: return true adam@0: end adam@0: adam@0: function AskMrRobot.populateItemDiffs(amrItem, itemLink, slotNum) adam@0: AskMrRobot.itemDiffs.items[slotNum] = nil adam@0: AskMrRobot.itemDiffs.gems[slotNum] = nil adam@0: AskMrRobot.itemDiffs.enchants[slotNum] = nil adam@0: AskMrRobot.itemDiffs.reforges[slotNum] = nil adam@0: adam@0: local needsUpgrade = false adam@0: local aSuffix = 0 adam@0: if amrItem then adam@0: for k,v in pairs(amrItem.suffixes) do adam@0: aSuffix = k adam@0: end adam@0: end adam@0: adam@0: if itemLink == nil then adam@0: if amrItem ~= nil then adam@0: AskMrRobot.itemDiffs.items[slotNum] = { adam@0: current = nil, adam@0: optimized = { itemId = amrItem.itemId, upgradeId = amrItem.upgradeId, suffixId = aSuffix }, adam@0: needsUpgrade = false adam@0: } adam@0: end adam@0: return adam@0: end adam@0: local item = parseItemLink(itemLink) adam@0: local isItemBad = false adam@0: adam@0: if amrItem == nil or item.itemId ~= amrItem.itemId then adam@0: isItemBad = true adam@0: else adam@0: if item.suffixId == 0 then adam@0: if #amrItem.suffixes > 0 then adam@0: isItemBad = true adam@0: end adam@0: else adam@0: if not amrItem.suffixes[item.suffixId] then adam@0: isItemBad = true adam@0: end adam@0: end adam@0: if not isItemBad and upgradeTable[item.upgradeId] ~= upgradeTable[amrItem.upgradeId] then adam@0: isItemBad = true adam@0: needsUpgrade = true adam@0: end adam@0: end adam@0: adam@0: if isItemBad then adam@0: AskMrRobot.itemDiffs.items[slotNum] = { adam@0: current = item.itemId, adam@0: optimized = { itemId = amrItem and amrItem.itemId or 0, upgradeId = amrItem and amrItem.upgradeId or 0, suffixId = aSuffix }, adam@0: needsUpgrade = needsUpgrade adam@0: } adam@0: return adam@0: end adam@0: adam@0: local badGemCount, gemInfo = AskMrRobot.MatchesGems(itemLink, item.gemEnchantIds, amrItem.gems) adam@0: if badGemCount > 0 then adam@0: AskMrRobot.itemDiffs.gems[slotNum] = gemInfo adam@0: end adam@0: adam@0: if item.enchantId ~= amrItem.enchantId then adam@0: AskMrRobot.itemDiffs.enchants[slotNum] = { adam@0: current = item.enchantId, adam@0: optimized = amrItem.enchantId adam@0: } adam@0: end adam@0: adam@0: if item.reforgeId ~= amrItem.reforgeId then adam@0: AskMrRobot.itemDiffs.reforges[slotNum] = { adam@0: current = item.reforgeId, adam@0: optimized = amrItem.reforgeId adam@0: } adam@0: end adam@0: end adam@0: adam@0: --[[ adam@0: function AskMrRobot.StartLogging() adam@0: if not LoggingCombat() then adam@0: LoggingCombat(1) adam@0: print("Started Combat Logging") adam@0: end adam@0: end adam@0: adam@0: function AskMrRobot.FinishLogging() adam@0: if LoggingCombat() then adam@0: LoggingCombat(0) adam@0: print("Finished Combat Logging") adam@0: end adam@0: end adam@0: adam@0: -- local difficultyLookup = { adam@0: -- DUNGEON_DIFFICULTY1, adam@0: -- DUNGEON_DIFFICULTY2, adam@0: -- RAID_DIFFICULTY_10PLAYER, adam@0: -- RAID_DIFFICULTY_25PLAYER, adam@0: -- RAID_DIFFICULTY_10PLAYER_HEROIC, adam@0: -- RAID_DIFFICULTY_25PLAYER_HEROIC, adam@0: -- RAID_FINDER, adam@0: -- CHALLENGE_MODE, adam@0: -- RAID_DIFFICULTY_40PLAYER, adam@0: -- nil, adam@0: -- nil, -- Norm scen adam@0: -- nil, -- heroic scen adam@0: -- nil, adam@0: -- PLAYER_DIFFICULTY4 adam@0: -- } adam@0: adam@0: --http://wowpedia.org/InstanceMapID adam@0: local instanceMaps = { adam@0: HeartOfFear = 1009, adam@0: MogushanVaults = 1008, adam@0: SiegeOfOrgrimmar = 1136, adam@0: TerraceOfEndlessSpring = 996, adam@0: ThroneOfThunder = 1098 adam@0: } adam@0: adam@0: function AskMrRobot.UpdateLogging() adam@0: adam@0: -- get the info about the instance adam@0: --local zone, zonetype, difficultyIndex, difficultyName, maxPlayers, dynamicDifficulty, isDynamic, instanceMapID = GetInstanceInfo() adam@0: local zone, _, difficultyIndex, _, _, _, _, instanceMapID = GetInstanceInfo() adam@0: --local difficulty = difficultyIndex adam@0: -- Unless Blizzard fixes scenarios to not return nil, let's hardcode this into returning "scenario" -Znuff adam@0: --if zonetype == nil and difficultyIndex == 1 then adam@0: --zonetype = "scenario" adam@0: --end adam@0: adam@0: -- if nothing has changed, then bail adam@0: --if (not zone) and difficulty == 0 then return end adam@0: if zone == AskMrRobot.lastzone and difficultyIndex == AskMrRobot.lastdiff then adam@0: -- do nothing if the zone hasn't ACTUALLY changed adam@0: -- otherwise we may override the user's manual enable/disable adam@0: return adam@0: end adam@0: adam@0: AskMrRobot.lastzone = zone adam@0: AskMrRobot.lastdiff = difficultyIndex adam@0: adam@0: if AmrOptions.autoLog[tonumber(instanceMapID)] then adam@0: if instanceMapID == instanceMaps.SiegeOfOrgrimmar then adam@0: AskMrRobot.StartLogging() adam@0: else adam@0: AskMrRobot.FinishLogging() adam@0: end adam@0: end adam@0: end adam@0: ]]