Mercurial > wow > askmrrobot
comparison AskMrRobot.lua @ 17:e77e01abce98
Warlords of Draenor pre-patch
| author | Adam tegen <adam.tegen@gmail.com> |
|---|---|
| date | Mon, 13 Oct 2014 21:28:32 -0500 |
| parents | bb0c8ce689d1 |
| children | a400b906acca |
comparison
equal
deleted
inserted
replaced
| 16:9793e8b683d2 | 17:e77e01abce98 |
|---|---|
| 1 local _, AskMrRobot = ... | 1 local _, AskMrRobot = ... |
| 2 local L = AskMrRobot.L; | 2 local L = AskMrRobot.L; |
| 3 | 3 |
| 4 AskMrRobot.eventListener = CreateFrame("FRAME"); -- Need a frame to respond to events | 4 AskMrRobot.eventListener = CreateFrame("FRAME") -- Need a frame to respond to events |
| 5 AskMrRobot.eventListener:RegisterEvent("ADDON_LOADED"); -- Fired when saved variables are loaded | 5 AskMrRobot.eventListener:RegisterEvent("ADDON_LOADED") -- Fired when saved variables are loaded |
| 6 AskMrRobot.eventListener:RegisterEvent("ITEM_PUSH"); | 6 AskMrRobot.eventListener:RegisterEvent("ITEM_PUSH") |
| 7 AskMrRobot.eventListener:RegisterEvent("DELETE_ITEM_CONFIRM"); | 7 AskMrRobot.eventListener:RegisterEvent("DELETE_ITEM_CONFIRM") |
| 8 AskMrRobot.eventListener:RegisterEvent("UNIT_INVENTORY_CHANGED"); | 8 AskMrRobot.eventListener:RegisterEvent("UNIT_INVENTORY_CHANGED") |
| 9 AskMrRobot.eventListener:RegisterEvent("BANKFRAME_OPENED"); | 9 AskMrRobot.eventListener:RegisterEvent("BANKFRAME_OPENED") |
| 10 AskMrRobot.eventListener:RegisterEvent("BANKFRAME_CLOSED"); | 10 --AskMrRobot.eventListener:RegisterEvent("BANKFRAME_CLOSED"); |
| 11 AskMrRobot.eventListener:RegisterEvent("PLAYERBANKSLOTS_CHANGED"); | 11 AskMrRobot.eventListener:RegisterEvent("PLAYERBANKSLOTS_CHANGED") |
| 12 AskMrRobot.eventListener:RegisterEvent("CHARACTER_POINTS_CHANGED"); | 12 AskMrRobot.eventListener:RegisterEvent("CHARACTER_POINTS_CHANGED") |
| 13 AskMrRobot.eventListener:RegisterEvent("CONFIRM_TALENT_WIPE"); | 13 AskMrRobot.eventListener:RegisterEvent("CONFIRM_TALENT_WIPE") |
| 14 AskMrRobot.eventListener:RegisterEvent("PLAYER_TALENT_UPDATE"); | 14 AskMrRobot.eventListener:RegisterEvent("PLAYER_TALENT_UPDATE") |
| 15 AskMrRobot.eventListener:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED"); | 15 AskMrRobot.eventListener:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED") |
| 16 AskMrRobot.eventListener:RegisterEvent("PLAYER_ENTERING_WORLD"); | 16 AskMrRobot.eventListener:RegisterEvent("PLAYER_ENTERING_WORLD") |
| 17 AskMrRobot.eventListener:RegisterEvent("PLAYER_LOGOUT"); -- Fired when about to log out | 17 --AskMrRobot.eventListener:RegisterEvent("PLAYER_LOGOUT") -- Fired when about to log out |
| 18 AskMrRobot.eventListener:RegisterEvent("PLAYER_LEVEL_UP"); | 18 --AskMrRobot.eventListener:RegisterEvent("PLAYER_LEVEL_UP") |
| 19 --AskMrRobot.eventListener:RegisterEvent("GET_ITEM_INFO_RECEIVED") | 19 --AskMrRobot.eventListener:RegisterEvent("GET_ITEM_INFO_RECEIVED") |
| 20 AskMrRobot.eventListener:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED") | 20 AskMrRobot.eventListener:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED") |
| 21 AskMrRobot.eventListener:RegisterEvent("SOCKET_INFO_UPDATE") | 21 AskMrRobot.eventListener:RegisterEvent("SOCKET_INFO_UPDATE") |
| 22 AskMrRobot.eventListener:RegisterEvent("SOCKET_INFO_CLOSE") | 22 AskMrRobot.eventListener:RegisterEvent("SOCKET_INFO_CLOSE") |
| 23 AskMrRobot.eventListener:RegisterEvent("BAG_UPDATE") | 23 AskMrRobot.eventListener:RegisterEvent("BAG_UPDATE") |
| 29 AskMrRobot.eventListener:RegisterEvent("PLAYER_DIFFICULTY_CHANGED") | 29 AskMrRobot.eventListener:RegisterEvent("PLAYER_DIFFICULTY_CHANGED") |
| 30 | 30 |
| 31 AskMrRobot.AddonName = ... | 31 AskMrRobot.AddonName = ... |
| 32 AskMrRobot.ChatPrefix = "_AMR" | 32 AskMrRobot.ChatPrefix = "_AMR" |
| 33 | 33 |
| 34 local amrLDB | 34 -- the main user interface window |
| 35 local icon | 35 AskMrRobot.mainWindow = nil |
| 36 local reforgequeue | 36 |
| 37 local reforgeFrame = nil | 37 local _amrLDB |
| 38 local LoggingCombat = _G.LoggingCombat | 38 local _minimapIcon |
| 39 | |
| 40 AskMrRobot.itemDiffs = { | |
| 41 items = {}, -- slotNum -> nil (no change) or current <item id>, optimized <item id> | |
| 42 enchants = {}, -- slotNum -> nil (no change) or current <enchant id>, optimized <enchant id> | |
| 43 gems = {}, -- slotNum -> nil (no change) or ? | |
| 44 reforges = {} -- slotNum -> nil (no change) or current <reforge id>, optimized <reforge id> | |
| 45 } | |
| 46 | |
| 47 AskMrRobot.instanceIds = { | |
| 48 HeartOfFear = 1009, | |
| 49 MogushanVaults = 1008, | |
| 50 SiegeOfOrgrimmar = 1136, | |
| 51 TerraceOfEndlessSpring = 996, | |
| 52 ThroneOfThunder = 1098 | |
| 53 } | |
| 54 | |
| 55 -- instances that we currently support logging for | |
| 56 AskMrRobot.supportedInstanceIds = { | |
| 57 [1136] = true | |
| 58 } | |
| 59 | |
| 60 -- returns true if currently in a supported instance | |
| 61 function AskMrRobot.IsSupportedInstance() | |
| 62 | |
| 63 local zone, _, difficultyIndex, _, _, _, _, instanceMapID = GetInstanceInfo() | |
| 64 if AskMrRobot.supportedInstanceIds[tonumber(instanceMapID)] then | |
| 65 return true | |
| 66 else | |
| 67 return false | |
| 68 end | |
| 69 end | |
| 70 | |
| 71 -- upgrade id -> upgrade level | |
| 72 local upgradeTable = { | |
| 73 [0] = 0, | |
| 74 [1] = 1, -- 1/1 -> 8 | |
| 75 [373] = 1, -- 1/2 -> 4 | |
| 76 [374] = 2, -- 2/2 -> 8 | |
| 77 [375] = 1, -- 1/3 -> 4 | |
| 78 [376] = 2, -- 2/3 -> 4 | |
| 79 [377] = 3, -- 3/3 -> 4 | |
| 80 [378] = 1, -- 1/1 -> 7 | |
| 81 [379] = 1, -- 1/2 -> 4 | |
| 82 [380] = 2, -- 2/2 -> 4 | |
| 83 [445] = 0, -- 0/2 -> 0 | |
| 84 [446] = 1, -- 1/2 -> 4 | |
| 85 [447] = 2, -- 2/2 -> 8 | |
| 86 [451] = 0, -- 0/1 -> 0 | |
| 87 [452] = 1, -- 1/1 -> 8 | |
| 88 [453] = 0, -- 0/2 -> 0 | |
| 89 [454] = 1, -- 1/2 -> 4 | |
| 90 [455] = 2, -- 2/2 -> 8 | |
| 91 [456] = 0, -- 0/1 -> 0 | |
| 92 [457] = 1, -- 1/1 -> 8 | |
| 93 [458] = 0, -- 0/4 -> 0 | |
| 94 [459] = 1, -- 1/4 -> 4 | |
| 95 [460] = 2, -- 2/4 -> 8 | |
| 96 [461] = 3, -- 3/4 -> 12 | |
| 97 [462] = 4, -- 4/4 -> 16 | |
| 98 [465] = 0, -- 0/2 -> 0 | |
| 99 [466] = 1, -- 1/2 -> 4 | |
| 100 [467] = 2, -- 2/2 -> 8 | |
| 101 [468] = 0, -- 0/4 -> 0 | |
| 102 [469] = 1, -- 1/4 -> 4 | |
| 103 [470] = 2, -- 2/4 -> 8 | |
| 104 [471] = 3, -- 3/4 -> 12 | |
| 105 [472] = 4, -- 4/4 -> 16 | |
| 106 [476] = 0, -- ? -> 0 | |
| 107 [479] = 0, -- ? -> 0 | |
| 108 [491] = 0, -- ? -> 0 | |
| 109 [492] = 1, -- ? -> 0 | |
| 110 [493] = 2, -- ? -> 0 | |
| 111 [494] = 0, | |
| 112 [495] = 1, | |
| 113 [496] = 2, | |
| 114 [497] = 3, | |
| 115 [498] = 4, | |
| 116 [504] = 3, | |
| 117 [505] = 4, | |
| 118 [506] = 5, | |
| 119 [507] = 6 | |
| 120 } | |
| 121 | |
| 122 local professionIds = { | |
| 123 ["None"] = 0, | |
| 124 ["Mining"] = 1, | |
| 125 ["Skinning"] = 2, | |
| 126 ["Herbalism"] = 3, | |
| 127 ["Enchanting"] = 4, | |
| 128 ["Jewelcrafting"] = 5, | |
| 129 ["Engineering"] = 6, | |
| 130 ["Blacksmithing"] = 7, | |
| 131 ["Leatherworking"] = 8, | |
| 132 ["Inscription"] = 9, | |
| 133 ["Tailoring"] = 10, | |
| 134 ["Alchemy"] = 11, | |
| 135 ["Fishing"] = 12, | |
| 136 ["Cooking"] = 13, | |
| 137 ["First Aid"] = 14, | |
| 138 ["Archaeology"] = 15 | |
| 139 } | |
| 140 | |
| 141 local raceIds = { | |
| 142 ["None"] = 0, | |
| 143 ["BloodElf"] = 1, | |
| 144 ["Draenei"] = 2, | |
| 145 ["Dwarf"] = 3, | |
| 146 ["Gnome"] = 4, | |
| 147 ["Human"] = 5, | |
| 148 ["NightElf"] = 6, | |
| 149 ["Orc"] = 7, | |
| 150 ["Tauren"] = 8, | |
| 151 ["Troll"] = 9, | |
| 152 ["Scourge"] = 10, | |
| 153 ["Undead"] = 10, | |
| 154 ["Goblin"] = 11, | |
| 155 ["Worgen"] = 12, | |
| 156 ["Pandaren"] = 13 | |
| 157 } | |
| 158 | |
| 159 local factionIds = { | |
| 160 ["None"] = 0, | |
| 161 ["Alliance"] = 1, | |
| 162 ["Horde"] = 2 | |
| 163 } | |
| 164 | |
| 165 local function OnExport() | |
| 166 if (AmrOptions.exportToClient) then | |
| 167 AskMrRobot.SaveAll() | |
| 168 ReloadUI() | |
| 169 else | |
| 170 AskMrRobot_ReforgeFrame:Show() | |
| 171 AskMrRobot_ReforgeFrame:ShowTab("export") | |
| 172 end | |
| 173 end | |
| 174 | 39 |
| 175 function AskMrRobot.eventListener:OnEvent(event, ...) | 40 function AskMrRobot.eventListener:OnEvent(event, ...) |
| 176 if event == "ADDON_LOADED" then | 41 if event == "ADDON_LOADED" then |
| 177 local addon = select(1, ...) | 42 local addon = select(1, ...) |
| 178 if (addon == "AskMrRobot") then | 43 if (addon == "AskMrRobot") then |
| 179 print(L.AMR_ON_EVENT_LOADED.format(GetAddOnMetadata(AskMrRobot.AddonName, "Version"))) | 44 --print(L.AMR_ON_EVENT_LOADED:format(GetAddOnMetadata(AskMrRobot.AddonName, "Version"))) |
| 45 | |
| 46 AskMrRobot.InitializeSettings() | |
| 47 AskMrRobot.InitializeMinimap() | |
| 180 | 48 |
| 181 -- listen for messages from other AMR addons | 49 -- listen for messages from other AMR addons |
| 182 RegisterAddonMessagePrefix(AskMrRobot.ChatPrefix) | 50 RegisterAddonMessagePrefix(AskMrRobot.ChatPrefix) |
| 183 | 51 |
| 184 AmrRealmName = GetRealmName() | 52 AskMrRobot.mainWindow = AskMrRobot.AmrUI:new() |
| 185 AmrCharacterName = UnitName("player") | 53 end |
| 186 | 54 |
| 187 AskMrRobot.CombatLogTab.InitializeVariable() | 55 elseif event == "UNIT_INVENTORY_CHANGED" then |
| 188 | 56 AskMrRobot.ScanEquipped() |
| 189 if not AmrIconInfo then AmrIconInfo = {} end | 57 |
| 190 if not AmrBankItems then AmrBankItems = {} end | 58 elseif event == "ITEM_PUSH" or event == "DELETE_ITEM_CONFIRM" or event == "SOCKET_INFO_CLOSE" or event == "PLAYER_SPECIALIZATION_CHANGED" or event == "BAG_UPDATE" then |
| 191 if not AmrCurrencies then AmrCurrencies = {} end | 59 --if AskMrRobot_ReforgeFrame then |
| 192 if not AmrSpecializations then AmrSpecializations = {} end | 60 -- AskMrRobot_ReforgeFrame:OnUpdate() |
| 193 if not AmrOptions then AmrOptions = {} end | 61 --end |
| 194 if not AmrGlyphs then AmrGlyphs = {} end | |
| 195 if not AmrTalents then AmrTalents = {} end | |
| 196 if not AmrBankItemsAndCounts then AmrBankItemsAndCounts = {} end | |
| 197 if not AmrImportString then AmrImportString = "" end | |
| 198 if not AmrImportDate then AmrImportDate = "" end | |
| 199 | |
| 200 if not AmrSettings then AmrSettings = {} end | |
| 201 if not AmrSettings.Logins then AmrSettings.Logins = {} end | |
| 202 | |
| 203 if not AmrSendSettings then | |
| 204 AmrSendSettings = { | |
| 205 SendGems = true, | |
| 206 SendEnchants = true, | |
| 207 SendEnchantMaterials = true, | |
| 208 SendToType = "a friend", | |
| 209 SendTo = "" | |
| 210 } | |
| 211 end | |
| 212 | |
| 213 amrLDB = LibStub("LibDataBroker-1.1"):NewDataObject("AskMrRobot", { | |
| 214 type = "launcher", | |
| 215 text = "Ask Mr. Robot", | |
| 216 icon = "Interface\\AddOns\\AskMrRobot\\Media\\icon", | |
| 217 OnClick = function() | |
| 218 if IsControlKeyDown() then | |
| 219 AskMrRobot_ReforgeFrame.combatLogTab:LogWipe() | |
| 220 elseif IsModifiedClick("CHATLINK") then | |
| 221 OnExport() | |
| 222 else | |
| 223 AskMrRobot_ReforgeFrame:Toggle() | |
| 224 end | |
| 225 end, | |
| 226 OnTooltipShow = function(tt) | |
| 227 tt:AddLine("Ask Mr. Robot", 1, 1, 1); | |
| 228 tt:AddLine(" "); | |
| 229 tt:AddLine(L.AMR_ON_EVENT_TOOLTIP) | |
| 230 end | |
| 231 }); | |
| 232 | |
| 233 | |
| 234 AskMrRobot.AmrUpdateMinimap() | |
| 235 | |
| 236 AskMrRobot_ReforgeFrame = AskMrRobot.AmrUI:new() | |
| 237 | |
| 238 -- remember the import settings between sessions | |
| 239 AskMrRobot_ReforgeFrame.summaryTab.importDate = AmrImportDate or "" | |
| 240 AskMrRobot_ReforgeFrame.buttons[2]:Click() | |
| 241 | |
| 242 -- the previous import string is loaded when the UI is first shown, otherwise the game spams events and it lags | |
| 243 end | |
| 244 | |
| 245 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 | |
| 246 if AskMrRobot_ReforgeFrame then | |
| 247 AskMrRobot_ReforgeFrame:OnUpdate() | |
| 248 end | |
| 249 --AskMrRobot.SaveBags(); | 62 --AskMrRobot.SaveBags(); |
| 250 --AskMrRobot.SaveEquiped(); | 63 --AskMrRobot.SaveEquiped(); |
| 251 --AskMrRonot.GetCurrencies(); | 64 --AskMrRonot.GetCurrencies(); |
| 252 --AskMrRobot.GetGold(); | 65 --AskMrRobot.GetGold(); |
| 66 | |
| 253 elseif event == "BANKFRAME_OPENED" or event == "PLAYERBANKSLOTS_CHANGED" then | 67 elseif event == "BANKFRAME_OPENED" or event == "PLAYERBANKSLOTS_CHANGED" then |
| 254 --print("Scanning Bank: " .. event); | |
| 255 AskMrRobot.ScanBank(); | 68 AskMrRobot.ScanBank(); |
| 256 elseif event == "BANKFRAME_CLOSED" then | 69 |
| 257 --print("Stop Scanning Bank"); | |
| 258 --inBank = false; | |
| 259 elseif event == "CHARACTER_POINTS_CHANGED" or event == "CONFIRM_TALENT_WIPE" or event == "PLAYER_TALENT_UPDATE" or event == "ACTIVE_TALENT_GROUP_CHANGED" then | 70 elseif event == "CHARACTER_POINTS_CHANGED" or event == "CONFIRM_TALENT_WIPE" or event == "PLAYER_TALENT_UPDATE" or event == "ACTIVE_TALENT_GROUP_CHANGED" then |
| 260 --AskMrRobot.GetAmrSpecializations(); | 71 --AskMrRobot.GetAmrSpecializations(); |
| 261 if AskMrRobot_ReforgeFrame then | 72 --if AskMrRobot_ReforgeFrame then |
| 262 AskMrRobot_ReforgeFrame:OnUpdate() | 73 -- AskMrRobot_ReforgeFrame:OnUpdate() |
| 263 end | 74 --end |
| 264 elseif event == "PLAYER_LEVEL_UP" then | 75 |
| 265 --GetLevel(); | |
| 266 elseif event == "ITEM_UNLOCKED" then | 76 elseif event == "ITEM_UNLOCKED" then |
| 267 AskMrRobot.On_ITEM_UNLOCKED() | 77 --AskMrRobot.On_ITEM_UNLOCKED() |
| 268 elseif event == "PLAYER_LOGOUT" then | 78 |
| 269 -- doing nothing right now, but leaving this in case we need something here | 79 elseif event == "PLAYER_ENTERING_WORLD" then |
| 270 elseif event == "PLAYER_ENTERING_WORLD" then | 80 AskMrRobot.RecordLogin() |
| 271 | |
| 272 -- delete entries that are more than 10 days old to prevent the table from growing indefinitely | |
| 273 if AmrSettings.Logins and #AmrSettings.Logins > 0 then | |
| 274 local now = time() | |
| 275 local oldDuration = 60 * 60 * 24 * 10 | |
| 276 local entryTime | |
| 277 repeat | |
| 278 -- parse entry and get time | |
| 279 local parts = {} | |
| 280 for part in string.gmatch(AmrSettings.Logins[1], "([^;]+)") do | |
| 281 tinsert(parts, part) | |
| 282 end | |
| 283 entryTime = tonumber(parts[3]) | |
| 284 | |
| 285 -- entries are in order, remove first entry if it is old | |
| 286 if difftime(now, entryTime) > oldDuration then | |
| 287 tremove(AmrSettings.Logins, 1) | |
| 288 end | |
| 289 until #AmrSettings.Logins == 0 or difftime(now, entryTime) <= oldDuration | |
| 290 end | |
| 291 | |
| 292 -- record the time a player logs in, used to figure out which player logged which parts of their log file | |
| 293 local key = AmrRealmName .. ";" .. AmrCharacterName .. ";" | |
| 294 local loginData = key .. time() | |
| 295 if AmrSettings.Logins and #AmrSettings.Logins > 0 then | |
| 296 local last = AmrSettings.Logins[#AmrSettings.Logins] | |
| 297 if string.len(last) >= string.len(key) and string.sub(last, 1, string.len(key)) ~= key then | |
| 298 table.insert(AmrSettings.Logins, loginData) | |
| 299 end | |
| 300 else | |
| 301 table.insert(AmrSettings.Logins, loginData) | |
| 302 end | |
| 303 | 81 |
| 304 elseif event == "PLAYER_REGEN_DISABLED" then | 82 elseif event == "PLAYER_REGEN_DISABLED" then |
| 305 | |
| 306 -- send data about this character when a player enters combat in a supported zone | 83 -- send data about this character when a player enters combat in a supported zone |
| 307 if AskMrRobot.IsSupportedInstance() then | 84 if AskMrRobot.IsSupportedInstance() then |
| 308 local t = time() | 85 local t = time() |
| 309 AskMrRobot.SaveAll() | 86 AskMrRobot.SaveAll() |
| 310 AskMrRobot.ExportToAddonChat(t) | 87 AskMrRobot.ExportToAddonChat(t) |
| 311 AskMrRobot.ExportLoggingData(t) | 88 AskMrRobot.CombatLogTab.SaveExtras(t) |
| 312 end | 89 end |
| 313 | 90 |
| 314 elseif event == "CHAT_MSG_ADDON" then | 91 elseif event == "CHAT_MSG_ADDON" then |
| 315 local chatPrefix, message = select(1, ...) | 92 local chatPrefix, message = select(1, ...) |
| 316 local isLogging = AskMrRobot_ReforgeFrame.combatLogTab:IsLogging() | 93 local isLogging = AskMrRobot.CombatLogTab.IsLogging() |
| 317 if (isLogging and chatPrefix == AskMrRobot.ChatPrefix) then | 94 if (isLogging and chatPrefix == AskMrRobot.ChatPrefix) then |
| 318 AskMrRobot_ReforgeFrame.combatLogTab:ReadAddonMessage(message) | 95 AskMrRobot.mainWindow.combatLogTab:ReadAddonMessage(message) |
| 319 end | 96 end |
| 97 | |
| 320 elseif event == "UPDATE_INSTANCE_INFO" or event == "PLAYER_DIFFICULTY_CHANGED" then | 98 elseif event == "UPDATE_INSTANCE_INFO" or event == "PLAYER_DIFFICULTY_CHANGED" then |
| 321 AskMrRobot_ReforgeFrame.combatLogTab:UpdateAutoLogging() | 99 AskMrRobot.mainWindow.combatLogTab:UpdateAutoLogging() |
| 100 | |
| 322 end | 101 end |
| 323 | 102 |
| 324 end | 103 end |
| 325 | 104 |
| 326 AskMrRobot.eventListener:SetScript("OnEvent", AskMrRobot.eventListener.OnEvent); | 105 AskMrRobot.eventListener:SetScript("OnEvent", AskMrRobot.eventListener.OnEvent) |
| 327 | 106 |
| 328 local function parseItemLink(input) | |
| 329 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+)|"); | |
| 330 local item = {} | |
| 331 item.itemId = tonumber(itemId) | |
| 332 item.suffixId = tonumber(suffixId) | |
| 333 item.enchantId = tonumber(enchantId) | |
| 334 item.reforgeId = tonumber(reforgeId) | |
| 335 item.upgradeId = tonumber(upgradeId) | |
| 336 item.gemEnchantIds = { tonumber(gemEnchantId1), tonumber(gemEnchantId2), tonumber(gemEnchantId3), tonumber(gemEnchantId4) } | |
| 337 return item | |
| 338 end | |
| 339 | 107 |
| 340 SLASH_AMR1 = "/amr"; | 108 SLASH_AMR1 = "/amr"; |
| 341 function SlashCmdList.AMR(msg) | 109 function SlashCmdList.AMR(msg) |
| 342 | 110 |
| 343 if msg == 'toggle' then | 111 if msg == 'toggle' then |
| 344 AskMrRobot_ReforgeFrame:Toggle() | 112 AskMrRobot.mainWindow:Toggle() |
| 345 elseif msg == 'show' then | 113 elseif msg == 'show' then |
| 346 AskMrRobot_ReforgeFrame:Show() | 114 AskMrRobot.mainWindow:Show() |
| 347 elseif msg == 'hide' then | 115 elseif msg == 'hide' then |
| 348 AskMrRobot_ReforgeFrame:Hide() | 116 AskMrRobot.mainWindow:Hide() |
| 349 elseif msg == 'export' then | 117 elseif msg == 'export' then |
| 350 OnExport() | 118 AskMrRobot.mainWindow.exportTab:Show() |
| 351 elseif msg == 'wipe' then | 119 elseif msg == 'wipe' then |
| 352 AskMrRobot_ReforgeFrame.combatLogTab:LogWipe() | 120 AskMrRobot.mainWindow.combatLogTab:LogWipe() |
| 353 elseif msg == 'unwipe' then | 121 elseif msg == 'unwipe' then |
| 354 AskMrRobot_ReforgeFrame.combatLogTab:LogUnwipe() | 122 AskMrRobot.mainWindow.combatLogTab:LogUnwipe() |
| 355 else | 123 else |
| 356 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) | 124 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) |
| 357 end | 125 end |
| 358 end | 126 end |
| 359 | 127 |
| 128 -- initialize settings when the addon loads | |
| 129 function AskMrRobot.InitializeSettings() | |
| 130 | |
| 131 -- global settings | |
| 132 if not AmrSettings then AmrSettings = {} end | |
| 133 if not AmrSettings.Logins then AmrSettings.Logins = {} end | |
| 134 | |
| 135 -- per-character settings | |
| 136 if not AmrDb then AmrDb = {} end | |
| 137 | |
| 138 -- addon stuff | |
| 139 if not AmrDb.IconInfo then AmrDb.IconInfo = {} end | |
| 140 if not AmrDb.Options then AmrDb.Options = {} end | |
| 141 if not AmrDb.LastCharacterImport then AmrDb.LastCharacterImport = "" end | |
| 142 if not AmrDb.LastCharacterImportDate then AmrDb.LastCharacterImportDate = "" end | |
| 143 | |
| 144 if not AmrDb.SendSettings then | |
| 145 AmrDb.SendSettings = { | |
| 146 SendGems = true, | |
| 147 SendEnchants = true, | |
| 148 SendEnchantMaterials = true, | |
| 149 SendToType = "a friend", | |
| 150 SendTo = "" | |
| 151 } | |
| 152 end | |
| 153 | |
| 154 -- character stuff | |
| 155 AskMrRobot.ScanCharacter() | |
| 156 if not AmrDb.BankItems then AmrDb.BankItems = {} end | |
| 157 if not AmrDb.BagItems then AmrDb.BagItems = {} end | |
| 158 if not AmrDb.Currencies then AmrDb.Currencies = {} end | |
| 159 if not AmrDb.Reps then AmrDb.Reps = {} end | |
| 160 -- data saved for both specs | |
| 161 if not AmrDb.Specs then AmrDb.Specs = {} end | |
| 162 if not AmrDb.Glyphs then AmrDb.Glyphs = {} end | |
| 163 if not AmrDb.Talents then AmrDb.Talents = {} end | |
| 164 if not AmrDb.Equipped then AmrDb.Equipped = {} end | |
| 165 | |
| 166 -- combat log specific settings | |
| 167 AskMrRobot.CombatLogTab.InitializeVariable() | |
| 168 end | |
| 169 | |
| 170 -- record logins when the addon starts up, used to help figure out which character logged which parts of a log file | |
| 171 function AskMrRobot.RecordLogin() | |
| 172 | |
| 173 -- delete entries that are more than 10 days old to prevent the table from growing indefinitely | |
| 174 if AmrSettings.Logins and #AmrSettings.Logins > 0 then | |
| 175 local now = time() | |
| 176 local oldDuration = 60 * 60 * 24 * 10 | |
| 177 local entryTime | |
| 178 repeat | |
| 179 -- parse entry and get time | |
| 180 local parts = {} | |
| 181 for part in string.gmatch(AmrSettings.Logins[1], "([^;]+)") do | |
| 182 tinsert(parts, part) | |
| 183 end | |
| 184 entryTime = tonumber(parts[3]) | |
| 185 | |
| 186 -- entries are in order, remove first entry if it is old | |
| 187 if difftime(now, entryTime) > oldDuration then | |
| 188 tremove(AmrSettings.Logins, 1) | |
| 189 end | |
| 190 until #AmrSettings.Logins == 0 or difftime(now, entryTime) <= oldDuration | |
| 191 end | |
| 192 | |
| 193 -- record the time a player logs in, used to figure out which player logged which parts of their log file | |
| 194 local key = AmrDb.RealmName .. ";" .. AmrDb.CharacterName .. ";" | |
| 195 local loginData = key .. time() | |
| 196 if AmrSettings.Logins and #AmrSettings.Logins > 0 then | |
| 197 local last = AmrSettings.Logins[#AmrSettings.Logins] | |
| 198 if string.len(last) >= string.len(key) and string.sub(last, 1, string.len(key)) ~= key then | |
| 199 table.insert(AmrSettings.Logins, loginData) | |
| 200 end | |
| 201 else | |
| 202 table.insert(AmrSettings.Logins, loginData) | |
| 203 end | |
| 204 end | |
| 205 | |
| 206 function AskMrRobot.InitializeMinimap() | |
| 207 | |
| 208 -- minimap icon and data broker icon plugin thingy | |
| 209 _amrLDB = LibStub("LibDataBroker-1.1"):NewDataObject("AskMrRobot", { | |
| 210 type = "launcher", | |
| 211 text = "Ask Mr. Robot", | |
| 212 icon = "Interface\\AddOns\\AskMrRobot\\Media\\icon", | |
| 213 OnClick = function() | |
| 214 if IsControlKeyDown() then | |
| 215 AskMrRobot.mainWindow.combatLogTab:LogWipe() | |
| 216 elseif IsModifiedClick("CHATLINL") then | |
| 217 AskMrRobot.mainWindow.exportTab:Show() | |
| 218 else | |
| 219 AskMrRobot.mainWindow:Toggle() | |
| 220 end | |
| 221 end, | |
| 222 OnTooltipShow = function(tt) | |
| 223 tt:AddLine("Ask Mr. Robot", 1, 1, 1); | |
| 224 tt:AddLine(" "); | |
| 225 tt:AddLine(L.AMR_ON_EVENT_TOOLTIP) | |
| 226 end | |
| 227 }); | |
| 228 | |
| 229 AskMrRobot.AmrUpdateMinimap() | |
| 230 end | |
| 231 | |
| 232 function AskMrRobot.AmrUpdateMinimap() | |
| 233 if AmrDb.Options.hideMapIcon then | |
| 234 if _minimapIcon then | |
| 235 _minimapIcon:Hide("AskMrRobot") | |
| 236 end | |
| 237 else | |
| 238 if not _minimapIcon then | |
| 239 _minimapIcon = LibStub("LibDBIcon-1.0") | |
| 240 _minimapIcon:Register("AskMrRobot", _amrLDB, AmrDb.IconInfo) | |
| 241 end | |
| 242 | |
| 243 if AskMrRobot.CombatLogTab.IsLogging() then | |
| 244 _amrLDB.icon = 'Interface\\AddOns\\AskMrRobot\\Media\\icon_green' | |
| 245 else | |
| 246 _amrLDB.icon = 'Interface\\AddOns\\AskMrRobot\\Media\\icon' | |
| 247 end | |
| 248 | |
| 249 _minimapIcon:Show("AskMrRobot") | |
| 250 end | |
| 251 end | |
| 252 | |
| 253 | |
| 360 function AskMrRobot.SaveAll() | 254 function AskMrRobot.SaveAll() |
| 255 AskMrRobot.ScanCharacter() | |
| 361 AskMrRobot.ScanBank() | 256 AskMrRobot.ScanBank() |
| 362 AskMrRobot.SaveBags() | 257 AskMrRobot.ScanBags() |
| 363 AskMrRobot.SaveEquiped() | 258 AskMrRobot.ScanEquipped() |
| 364 AskMrRobot.GetCurrencies() | 259 AskMrRobot.GetCurrencies() |
| 365 AskMrRobot.GetGold() | 260 AskMrRobot.GetReputations() |
| 366 AskMrRobot.GetAmrSpecializations() | 261 AskMrRobot.GetSpecs() |
| 367 AskMrRobot.GetAmrProfessions() | 262 end |
| 368 AskMrRobot.GetRace() | 263 |
| 369 AskMrRobot.GetLevel() | 264 -- gets all basic character properties |
| 370 AskMrRobot.GetAmrGlyphs() | 265 function AskMrRobot.ScanCharacter() |
| 371 AskMrRobot.GetAmrTalents() | 266 AmrDb.RealmName = GetRealmName() |
| 372 --ReloadUI() | 267 AmrDb.CharacterName = UnitName("player") |
| 373 end | 268 AmrDb.Guild = GetGuildInfo("player") |
| 374 | 269 AmrDb.ActiveSpec = GetActiveSpecGroup() |
| 375 local function InitIcon() | 270 AmrDb.Level = UnitLevel("player"); |
| 376 icon = LibStub("LibDBIcon-1.0"); | 271 |
| 377 icon:Register("AskMrRobot", amrLDB, AmrIconInfo); | 272 local cls, clsEn = UnitClass("player") |
| 378 end | 273 AmrDb.Class = clsEn; |
| 379 | 274 |
| 380 function AskMrRobot.AmrUpdateMinimap() | 275 local race, raceEn = UnitRace("player") |
| 381 if AmrOptions.hideMapIcon then | 276 AmrDb.Race = raceEn; |
| 382 if icon then | 277 AmrDb.Faction = UnitFactionGroup("player") |
| 383 icon:Hide("AskMrRobot"); | 278 |
| 384 end | 279 AskMrRobot.GetAmrProfessions() |
| 385 else | |
| 386 if not icon then | |
| 387 InitIcon() | |
| 388 end | |
| 389 --if AskMrRobot_ReforgeFrame.combatLogTab:IsLogging() then | |
| 390 if AskMrRobot.CombatLogTab.IsLogging(nil) then | |
| 391 amrLDB.icon = 'Interface\\AddOns\\AskMrRobot\\Media\\icon_green' | |
| 392 else | |
| 393 amrLDB.icon = 'Interface\\AddOns\\AskMrRobot\\Media\\icon' | |
| 394 end | |
| 395 icon:Show("AskMrRobot"); | |
| 396 end | |
| 397 end | |
| 398 | |
| 399 local function getToolTipText(tip) | |
| 400 return EnumerateTooltipLines_helper(tip:GetRegions()) | |
| 401 end | |
| 402 | |
| 403 local bagItems = {} | |
| 404 local bagItemsWithCount = {} | |
| 405 | |
| 406 function AskMrRobot.ScanBag(bagId) | |
| 407 local numSlots = GetContainerNumSlots(bagId); | |
| 408 for slotId = 1, numSlots do | |
| 409 local _, itemCount, _, _, _, _, itemLink = GetContainerItemInfo(bagId, slotId); | |
| 410 if itemLink ~= nil then | |
| 411 local itemData = parseItemLink(itemLink) | |
| 412 if itemData.itemId ~= nil then | |
| 413 tinsert(bagItems, itemLink); | |
| 414 tinsert(bagItemsWithCount, {link = itemLink, count = itemCount}) | |
| 415 end | |
| 416 end | |
| 417 end | |
| 418 end | |
| 419 | |
| 420 local BACKPACK_CONTAINER = 0; | |
| 421 local BANK_CONTAINER = -1; | |
| 422 | |
| 423 function AskMrRobot.ScanEquiped() | |
| 424 local equipedItems = {}; | |
| 425 for slotNum = 1, #AskMrRobot.slotIds do | |
| 426 local slotId = AskMrRobot.slotIds[slotNum]; | |
| 427 local itemLink = GetInventoryItemLink("player", slotId); | |
| 428 if (itemLink ~= nil) then | |
| 429 equipedItems[slotId .. ""] = itemLink; | |
| 430 end | |
| 431 end | |
| 432 return equipedItems | |
| 433 end | |
| 434 | |
| 435 function AskMrRobot.SaveEquiped() | |
| 436 AmrEquipedItems = AskMrRobot.ScanEquiped(); | |
| 437 end | |
| 438 | |
| 439 function AskMrRobot.ScanBags() | |
| 440 bagItems = {} | |
| 441 bagItemsWithCount = {} | |
| 442 | |
| 443 AskMrRobot.ScanBag(BACKPACK_CONTAINER); -- backpack | |
| 444 | |
| 445 for bagId = 1, NUM_BAG_SLOTS do | |
| 446 AskMrRobot.ScanBag(bagId); | |
| 447 end | |
| 448 | |
| 449 | |
| 450 return bagItems, bagItemsWithCount | |
| 451 end | |
| 452 | |
| 453 function AskMrRobot.SaveBags() | |
| 454 AmrBagItems, _ = AskMrRobot.ScanBags() | |
| 455 end | |
| 456 | |
| 457 function AskMrRobot.GetGold() | |
| 458 AmrGold = GetMoney(); | |
| 459 end | |
| 460 | |
| 461 local lastBankBagId = nil; | |
| 462 local lastBankSlotId = nil; | |
| 463 local bankItems = {}; | |
| 464 local bankItemsAndCount = {}; | |
| 465 AmrBankItemsAndCounts = {}; | |
| 466 | |
| 467 local function ScanBankBag(bagId) | |
| 468 local numSlots = GetContainerNumSlots(bagId); | |
| 469 for slotId = 1, numSlots do | |
| 470 local _, itemCount, _, _, _, _, itemLink = GetContainerItemInfo(bagId, slotId); | |
| 471 if itemLink ~= nil then | |
| 472 local itemData = parseItemLink(itemLink) | |
| 473 if itemData.itemId ~= nil then | |
| 474 lastBankBagId = bagId; | |
| 475 lastBankSlotId = slotId; | |
| 476 tinsert(bankItems, itemLink); | |
| 477 tinsert(bankItemsAndCount, {link = itemLink, count = itemCount}) | |
| 478 end | |
| 479 end | |
| 480 end | |
| 481 end | |
| 482 | |
| 483 function AskMrRobot.ScanBank() | |
| 484 | |
| 485 bankItems = {}; | |
| 486 bankItemsAndCount = {} | |
| 487 | |
| 488 ScanBankBag(BANK_CONTAINER); | |
| 489 for bagId = NUM_BAG_SLOTS + 1, NUM_BAG_SLOTS + NUM_BANKBAGSLOTS do | |
| 490 ScanBankBag(bagId); | |
| 491 end | |
| 492 | |
| 493 -- see if the scan completed before the window closed | |
| 494 if lastBankBagId ~= nil then | |
| 495 local itemLink = GetContainerItemLink(lastBankBagId, lastBankSlotId); | |
| 496 if itemLink ~= nil then --still open | |
| 497 AmrBankItems = bankItems; | |
| 498 AmrBankItemsAndCounts = bankItemsAndCount | |
| 499 end | |
| 500 end | |
| 501 end | |
| 502 | |
| 503 local function GetCurrencyAmount(index) | |
| 504 local localized_label, amount, icon_file_name = GetCurrencyInfo(index); | |
| 505 return amount; | |
| 506 end | |
| 507 | |
| 508 function AskMrRobot.GetCurrencies() | |
| 509 local currencies = {}; | |
| 510 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}; | |
| 511 | |
| 512 for i, currency in pairs(currencyList) do | |
| 513 local amount = GetCurrencyAmount(currency); | |
| 514 if amount ~= 0 then | |
| 515 currencies[currencyList[i]] = amount; | |
| 516 end | |
| 517 end | |
| 518 AmrCurrencies = currencies; | |
| 519 end | |
| 520 | |
| 521 local function GetAmrSpecialization(specGroup) | |
| 522 local spec = GetSpecialization(false, false, specGroup); | |
| 523 return spec and GetSpecializationInfo(spec); | |
| 524 end | |
| 525 | |
| 526 function AskMrRobot.GetAmrSpecializations() | |
| 527 | |
| 528 AmrSpecializations = {}; | |
| 529 | |
| 530 AmrActiveSpec = GetActiveSpecGroup(); | |
| 531 | |
| 532 for group = 1, 2 do | |
| 533 AmrSpecializations[group .. ""] = GetAmrSpecialization(group) | |
| 534 end | |
| 535 | |
| 536 -- Death Knight | |
| 537 -- 250 - Blood | |
| 538 -- 251 - Frost | |
| 539 -- 252 - Unholy | |
| 540 -- Druid | |
| 541 -- 102 - Balance | |
| 542 -- 103 - Feral Combat | |
| 543 -- 104 - Guardian | |
| 544 -- 105 - Restoration | |
| 545 -- Hunter | |
| 546 -- 253 - Beast Mastery | |
| 547 -- 254 - Marksmanship | |
| 548 -- 255 - Survival | |
| 549 -- Mage | |
| 550 -- 62 - Arcane | |
| 551 -- 63 - Fire | |
| 552 -- 64 - Frost | |
| 553 -- Monk | |
| 554 -- 268 - Brewmaster | |
| 555 -- 269 - Windwalker | |
| 556 -- 270 - Mistweaver | |
| 557 -- Paladin | |
| 558 -- 65 - Holy | |
| 559 -- 66 - Protection | |
| 560 -- 70 - Retribution | |
| 561 -- Priest | |
| 562 -- 256 Discipline | |
| 563 -- 257 Holy | |
| 564 -- 258 Shadow | |
| 565 -- Rogue | |
| 566 -- 259 - Assassination | |
| 567 -- 260 - Combat | |
| 568 -- 261 - Subtlety | |
| 569 -- Shaman | |
| 570 -- 262 - Elemental | |
| 571 -- 263 - Enhancement | |
| 572 -- 264 - Restoration | |
| 573 -- Warlock | |
| 574 -- 265 - Affliction | |
| 575 -- 266 - Demonology | |
| 576 -- 267 - Destruction | |
| 577 -- Warrior | |
| 578 -- 71 - Arms | |
| 579 -- 72 - Fury | |
| 580 -- 73 - Protection | |
| 581 end | 280 end |
| 582 | 281 |
| 583 function AskMrRobot.GetAmrProfessions() | 282 function AskMrRobot.GetAmrProfessions() |
| 584 | 283 |
| 585 local profMap = { | 284 local profMap = { |
| 599 [393] = "Skinning", | 298 [393] = "Skinning", |
| 600 [197] = "Tailoring" | 299 [197] = "Tailoring" |
| 601 } | 300 } |
| 602 | 301 |
| 603 local prof1, prof2, archaeology, fishing, cooking, firstAid = GetProfessions(); | 302 local prof1, prof2, archaeology, fishing, cooking, firstAid = GetProfessions(); |
| 604 AmrProfessions = {}; | 303 AmrDb.Professions = {}; |
| 605 if prof1 then | 304 if prof1 then |
| 606 local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(prof1); | 305 local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(prof1); |
| 607 if profMap[skillLine] ~= nil then | 306 if profMap[skillLine] ~= nil then |
| 608 AmrProfessions[profMap[skillLine]] = skillLevel; | 307 AmrDb.Professions[profMap[skillLine]] = skillLevel; |
| 609 end | 308 end |
| 610 end | 309 end |
| 611 if prof2 then | 310 if prof2 then |
| 612 local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(prof2); | 311 local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(prof2); |
| 613 if profMap[skillLine] ~= nil then | 312 if profMap[skillLine] ~= nil then |
| 614 AmrProfessions[profMap[skillLine]] = skillLevel; | 313 AmrDb.Professions[profMap[skillLine]] = skillLevel; |
| 615 end | 314 end |
| 616 end | 315 end |
| 617 if archaeology then | 316 if archaeology then |
| 618 local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(archaeology); | 317 local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(archaeology); |
| 619 if profMap[skillLine] ~= nil then | 318 if profMap[skillLine] ~= nil then |
| 620 AmrProfessions[profMap[skillLine]] = skillLevel; | 319 AmrDb.Professions[profMap[skillLine]] = skillLevel; |
| 621 end | 320 end |
| 622 end | 321 end |
| 623 if fishing then | 322 if fishing then |
| 624 local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(fishing); | 323 local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(fishing); |
| 625 if profMap[skillLine] ~= nil then | 324 if profMap[skillLine] ~= nil then |
| 626 AmrProfessions[profMap[skillLine]] = skillLevel; | 325 AmrDb.Professions[profMap[skillLine]] = skillLevel; |
| 627 end | 326 end |
| 628 end | 327 end |
| 629 if cooking then | 328 if cooking then |
| 630 local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(cooking); | 329 local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(cooking); |
| 631 if profMap[skillLine] ~= nil then | 330 if profMap[skillLine] ~= nil then |
| 632 AmrProfessions[profMap[skillLine]] = skillLevel; | 331 AmrDb.Professions[profMap[skillLine]] = skillLevel; |
| 633 end | 332 end |
| 634 end | 333 end |
| 635 if firstAid then | 334 if firstAid then |
| 636 local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(firstAid); | 335 local name, icon, skillLevel, maxSkillLevel, numAbilities, spelloffset, skillLine, skillModifier = GetProfessionInfo(firstAid); |
| 637 if profMap[skillLine] ~= nil then | 336 if profMap[skillLine] ~= nil then |
| 638 AmrProfessions[profMap[skillLine]] = skillLevel; | 337 AmrDb.Professions[profMap[skillLine]] = skillLevel; |
| 639 end | 338 end |
| 640 end | 339 end |
| 641 end | 340 end |
| 642 | 341 |
| 643 function AskMrRobot.GetRace() | 342 |
| 644 local race, raceEn = UnitRace("player"); | 343 -- use some local variables to deal with the fact that a user can close the bank before a scan completes |
| 645 AmrRace = raceEn; | 344 local _lastBankBagId = nil |
| 646 AmrFaction = UnitFactionGroup("player"); | 345 local _lastBankSlotId = nil |
| 647 end | 346 local BACKPACK_CONTAINER = 0 |
| 648 | 347 local BANK_CONTAINER = -1 |
| 649 function AskMrRobot.GetLevel() | 348 |
| 650 AmrLevel = UnitLevel("player"); | 349 local function scanBag(bagId, isBank, bagTable, bagItemsWithCount) |
| 651 end | 350 local numSlots = GetContainerNumSlots(bagId) |
| 652 | 351 for slotId = 1, numSlots do |
| 653 local SlotNames = { | 352 local _, itemCount, _, _, _, _, itemLink = GetContainerItemInfo(bagId, slotId) |
| 654 "HeadSlot", | 353 -- we skip any stackable item, as far as we know, there is no equippable gear that can be stacked |
| 655 "NeckSlot", | 354 if itemLink ~= nil then |
| 656 "ShoulderSlot", | 355 local itemData = AskMrRobot.parseItemLink(itemLink) |
| 657 "ShirtSlot", | 356 if itemData ~= nil then |
| 658 "ChestSlot", | 357 if itemCount == 1 then |
| 659 "WaistSlot", | 358 if isBank then |
| 660 "LegsSlot", | 359 _lastBankBagId = bagId |
| 661 "FeetSlot", | 360 _lastBankSlotId = slotId |
| 662 "WristSlot", | 361 end |
| 663 "HandsSlot", | 362 tinsert(bagTable, itemLink) |
| 664 "Finger0Slot", | 363 end |
| 665 "Finger1Slot", | 364 if bagItemsWithCount then |
| 666 "Trinket0Slot", | 365 if bagItemsWithCount[itemData.id] then |
| 667 "Trinket1Slot", | 366 bagItemsWithCount[itemData.id] = bagItemsWithCount[itemData.id] + itemCount |
| 668 "BackSlot", | 367 else |
| 669 "MainHandSlot", | 368 bagItemsWithCount[itemData.id] = itemCount |
| 670 "SecondaryHandSlot", | 369 end |
| 671 -- "RangedSlot", | 370 end |
| 672 "TabardSlot", | 371 end |
| 673 } | 372 end |
| 674 | 373 end |
| 675 local function GetAmrTalentsForSpec(spec) | 374 end |
| 375 | |
| 376 function AskMrRobot.ScanBank(bankItemsWithCount) | |
| 377 local bankItems = {} | |
| 378 local bankItemsAndCounts = {} | |
| 379 | |
| 380 scanBag(BANK_CONTAINER, true, bankItems, bankItemsAndCounts) | |
| 381 for bagId = NUM_BAG_SLOTS + 1, NUM_BAG_SLOTS + NUM_BANKBAGSLOTS do | |
| 382 scanBag(bagId, true, bankItems, bankItemsAndCounts) | |
| 383 end | |
| 384 | |
| 385 -- see if the scan completed before the window closed, otherwise we don't overwrite with partial data | |
| 386 if _lastBankBagId ~= nil then | |
| 387 local itemLink = GetContainerItemLink(_lastBankBagId, _lastBankSlotId) | |
| 388 if itemLink ~= nil then --still open | |
| 389 AmrDb.BankItems = bankItems | |
| 390 AmrDb.BankItemsAndCounts = bankItemsAndCounts | |
| 391 end | |
| 392 end | |
| 393 end | |
| 394 | |
| 395 function AskMrRobot.ScanBags(bagItemsWithCount) | |
| 396 local bagItems = {} | |
| 397 scanBag(BACKPACK_CONTAINER, false, bagItems, bagItemsWithCount) -- backpack | |
| 398 for bagId = 1, NUM_BAG_SLOTS do | |
| 399 scanBag(bagId, false, bagItems, bagItemsWithCount) | |
| 400 end | |
| 401 AmrDb.BagItems = bagItems | |
| 402 end | |
| 403 | |
| 404 function AskMrRobot.ScanEquipped() | |
| 405 local equippedItems = {}; | |
| 406 for slotNum = 1, #AskMrRobot.slotIds do | |
| 407 local slotId = AskMrRobot.slotIds[slotNum]; | |
| 408 local itemLink = GetInventoryItemLink("player", slotId); | |
| 409 if (itemLink ~= nil) then | |
| 410 equippedItems[slotId] = itemLink; | |
| 411 end | |
| 412 end | |
| 413 | |
| 414 -- store last-seen equipped gear for each spec | |
| 415 AmrDb.Equipped[GetActiveSpecGroup()] = equippedItems | |
| 416 end | |
| 417 | |
| 418 | |
| 419 local function getCurrencyAmount(index) | |
| 420 local localized_label, amount, icon_file_name = GetCurrencyInfo(index); | |
| 421 return amount; | |
| 422 end | |
| 423 | |
| 424 function AskMrRobot.GetCurrencies() | |
| 425 local currencies = {}; | |
| 426 currencies[-1] = GetMoney() | |
| 427 | |
| 428 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} | |
| 429 for i, currency in pairs(currencyList) do | |
| 430 local amount = getCurrencyAmount(currency) | |
| 431 if amount ~= 0 then | |
| 432 currencies[currency] = amount | |
| 433 end | |
| 434 end | |
| 435 | |
| 436 AmrDb.Currencies = currencies | |
| 437 end | |
| 438 | |
| 439 | |
| 440 local function getRepStanding(factionId) | |
| 441 local name, description, standingId, _ = GetFactionInfoByID(factionId) | |
| 442 return standingId - 1; -- our rep enum correspond to what the armory returns, are 1 less than what the game returns | |
| 443 end | |
| 444 | |
| 445 function AskMrRobot.GetReputations() | |
| 446 local reps = {} | |
| 447 | |
| 448 local repList = {1375,1376,1270,1269,1341,1337,1387,1388,1435} | |
| 449 for i, repId in pairs(repList) do | |
| 450 local standing = getRepStanding(repId) | |
| 451 if standing >= 0 then | |
| 452 reps[repId] = standing | |
| 453 end | |
| 454 end | |
| 455 | |
| 456 AmrDb.Reps = reps; | |
| 457 end | |
| 458 | |
| 459 | |
| 460 local function getSpecId(specGroup) | |
| 461 local spec = GetSpecialization(false, false, specGroup); | |
| 462 return spec and GetSpecializationInfo(spec); | |
| 463 end | |
| 464 | |
| 465 local function getTalents(specGroup) | |
| 676 local talentInfo = {} | 466 local talentInfo = {} |
| 677 local maxTiers = 6 | 467 local maxTiers = 7 |
| 678 for talent = 1, GetNumTalents() do | 468 for tier = 1, maxTiers do |
| 679 local name, texture, tier, column, selected, available = GetTalentInfo(talent, false, spec) | 469 for col = 1, 3 do |
| 680 if tier > maxTiers then | 470 local id, name, texture, selected, available = GetTalentInfo(tier, col, specGroup) |
| 681 maxTiers = tier | 471 if selected then |
| 682 end | 472 talentInfo[tier] = col |
| 683 if selected then | 473 end |
| 684 talentInfo[tier] = column | 474 end |
| 685 end | |
| 686 end | 475 end |
| 687 | 476 |
| 688 local str = "" | 477 local str = "" |
| 689 for i = 1, maxTiers do | 478 for i = 1, maxTiers do |
| 690 if talentInfo[i] then | 479 if talentInfo[i] then |
| 695 end | 484 end |
| 696 | 485 |
| 697 return str | 486 return str |
| 698 end | 487 end |
| 699 | 488 |
| 700 function AskMrRobot.GetAmrTalents() | 489 local function getGlyphs(specGroup) |
| 701 AmrTalents = {} | |
| 702 for spec = 1, GetNumSpecGroups() do | |
| 703 AmrTalents[spec] = GetAmrTalentsForSpec(spec); | |
| 704 end | |
| 705 end | |
| 706 | |
| 707 local function GetAmrGlyphsForSpec(spec) | |
| 708 local glyphs = {} | 490 local glyphs = {} |
| 709 for i = 1, NUM_GLYPH_SLOTS do | 491 for i = 1, NUM_GLYPH_SLOTS do |
| 710 local _, _, _, glyphSpellID, _, glyphID = GetGlyphSocketInfo(i, spec) | 492 local _, _, _, glyphSpellID, _, glyphID = GetGlyphSocketInfo(i, specGroup) |
| 711 if (glyphID) then | 493 if (glyphID) then |
| 712 tinsert(glyphs, glyphSpellID) | 494 tinsert(glyphs, glyphSpellID) |
| 713 end | 495 end |
| 714 end | 496 end |
| 715 return glyphs; | 497 return glyphs; |
| 716 end | 498 end |
| 717 | 499 |
| 718 function AskMrRobot.GetAmrGlyphs() | 500 -- get specs, talents, and glyphs |
| 719 AmrGlyphs = {} | 501 function AskMrRobot.GetSpecs() |
| 720 for spec = 1, GetNumSpecGroups() do | 502 |
| 721 AmrGlyphs[spec] = GetAmrGlyphsForSpec(spec) | 503 AmrDb.Specs = {} |
| 722 end | 504 AmrDb.Talents = {} |
| 723 end | 505 AmrDb.Glyphs = {} |
| 724 | 506 |
| 725 --[[ | 507 for group = 1, GetNumSpecGroups() do |
| 726 local function ItemLinkToExportString(itemLink, slot) | 508 -- spec, convert game spec id to one of our spec ids |
| 727 local itemData = parseItemLink(itemLink) | 509 local specId = getSpecId(group) |
| 728 local ret = {} | 510 if specId then |
| 729 table.insert(ret, slot) | 511 AmrDb.Specs[group] = AskMrRobot.specIds[specId] |
| 730 table.insert(ret, itemData.itemId) | 512 else |
| 731 table.insert(ret, itemData.suffixId) | 513 AmrDb.Specs[group] = 0 |
| 732 table.insert(ret, itemData.upgradeId) | 514 end |
| 733 table.insert(ret, itemData.gemEnchantIds[1]) | 515 |
| 734 table.insert(ret, itemData.gemEnchantIds[2]) | 516 AmrDb.Talents[group] = getTalents(group) |
| 735 table.insert(ret, itemData.gemEnchantIds[3]) | 517 AmrDb.Glyphs[group] = getGlyphs(group) |
| 736 table.insert(ret, itemData.enchantId) | 518 end |
| 737 table.insert(ret, itemData.reforgeId) | 519 end |
| 738 return table.concat(ret, ":") | 520 |
| 739 end | 521 ---------------------------------------------------------------------------- |
| 740 ]] | 522 -- Export |
| 741 | 523 ---------------------------------------------------------------------------- |
| 742 local function toCompressedNumberList(list) | 524 |
| 525 function AskMrRobot.toCompressedNumberList(list) | |
| 743 -- ensure the values are numbers, sorted from lowest to highest | 526 -- ensure the values are numbers, sorted from lowest to highest |
| 744 local nums = {} | 527 local nums = {} |
| 745 for i, v in ipairs(list) do | 528 for i, v in ipairs(list) do |
| 746 table.insert(nums, tonumber(v)) | 529 table.insert(nums, tonumber(v)) |
| 747 end | 530 end |
| 756 end | 539 end |
| 757 | 540 |
| 758 return table.concat(ret, ",") | 541 return table.concat(ret, ",") |
| 759 end | 542 end |
| 760 | 543 |
| 761 -- create a more compact but less readable string | 544 -- appends a list of items to the export |
| 762 function AskMrRobot.ExportToCompressedString(includeInventory) | 545 local function appendItemsToExport(fields, itemObjects) |
| 546 | |
| 547 -- sort by item id so we can compress it more easily | |
| 548 table.sort(itemObjects, function(a, b) return a.id < b.id end) | |
| 549 | |
| 550 -- append to the export string | |
| 551 local prevItemId = 0 | |
| 552 local prevGemId = 0 | |
| 553 local prevEnchantId = 0 | |
| 554 local prevUpgradeId = 0 | |
| 555 local prevBonusId = 0 | |
| 556 for i, itemData in ipairs(itemObjects) do | |
| 557 local itemParts = {} | |
| 558 | |
| 559 table.insert(itemParts, itemData.id - prevItemId) | |
| 560 prevItemId = itemData.id | |
| 561 | |
| 562 if itemData.slot ~= nil then table.insert(itemParts, "s" .. itemData.slot) end | |
| 563 if itemData.suffixId ~= 0 then table.insert(itemParts, "f" .. itemData.suffixId) end | |
| 564 if itemData.upgradeId ~= 0 then | |
| 565 table.insert(itemParts, "u" .. (itemData.upgradeId - prevUpgradeId)) | |
| 566 prevUpgradeId = itemData.upgradeId | |
| 567 end | |
| 568 if itemData.bonusIds then | |
| 569 for bIndex, bValue in ipairs(itemData.bonusIds) do | |
| 570 table.insert(itemParts, "b" .. (bValue - prevBonusId)) | |
| 571 prevBonusId = bValue | |
| 572 end | |
| 573 end | |
| 574 if itemData.gemIds[1] ~= 0 then | |
| 575 table.insert(itemParts, "x" .. (itemData.gemIds[1] - prevGemId)) | |
| 576 prevGemId = itemData.gemIds[1] | |
| 577 end | |
| 578 if itemData.gemIds[2] ~= 0 then | |
| 579 table.insert(itemParts, "y" .. (itemData.gemIds[2] - prevGemId)) | |
| 580 prevGemId = itemData.gemIds[2] | |
| 581 end | |
| 582 if itemData.gemIds[3] ~= 0 then | |
| 583 table.insert(itemParts, "z" .. (itemData.gemIds[3] - prevGemId)) | |
| 584 prevGemId = itemData.gemIds[3] | |
| 585 end | |
| 586 if itemData.enchantId ~= 0 then | |
| 587 table.insert(itemParts, "e" .. (itemData.enchantId - prevEnchantId)) | |
| 588 prevEnchantId = itemData.enchantId | |
| 589 end | |
| 590 | |
| 591 table.insert(fields, table.concat(itemParts, "")) | |
| 592 end | |
| 593 end | |
| 594 | |
| 595 -- create a compact string representing this player | |
| 596 -- if complete is true, exports everything (inventory, both specs) | |
| 597 -- otherwise only exports the player's active gear, spec, etc. | |
| 598 function AskMrRobot.ExportToCompressedString(complete) | |
| 763 local fields = {} | 599 local fields = {} |
| 764 | 600 |
| 765 -- compressed string uses a fixed order rather than inserting identifiers | 601 -- compressed string uses a fixed order rather than inserting identifiers |
| 766 table.insert(fields, GetAddOnMetadata(AskMrRobot.AddonName, "Version")) | 602 table.insert(fields, GetAddOnMetadata(AskMrRobot.AddonName, "Version")) |
| 767 table.insert(fields, AmrRealmName) | 603 table.insert(fields, AmrDb.RealmName) |
| 768 table.insert(fields, AmrCharacterName) | 604 table.insert(fields, AmrDb.CharacterName) |
| 769 | 605 |
| 770 -- guild name | 606 -- guild name |
| 771 local guildName = GetGuildInfo("player") | 607 local guildName = GetGuildInfo("player") |
| 772 if guildName == nil then | 608 if guildName == nil then |
| 773 table.insert(fields, "") | 609 table.insert(fields, "") |
| 774 else | 610 else |
| 775 table.insert(fields, guildName) | 611 table.insert(fields, guildName) |
| 776 end | 612 end |
| 777 | 613 |
| 778 -- race, default to pandaren if we can't read it for some reason | 614 -- race, default to pandaren if we can't read it for some reason |
| 779 local raceval = raceIds[AmrRace] | 615 local raceval = AskMrRobot.raceIds[AmrDb.Race] |
| 780 if raceval == nil then raceval = 13 end | 616 if raceval == nil then raceval = 13 end |
| 781 table.insert(fields, raceval) | 617 table.insert(fields, raceval) |
| 782 | 618 |
| 783 -- faction, default to alliance if we can't read it for some reason | 619 -- faction, default to alliance if we can't read it for some reason |
| 784 raceval = factionIds[AmrFaction] | 620 raceval = AskMrRobot.factionIds[AmrDb.Faction] |
| 785 if raceval == nil then raceval = 1 end | 621 if raceval == nil then raceval = 1 end |
| 786 table.insert(fields, raceval) | 622 table.insert(fields, raceval) |
| 787 | 623 |
| 788 table.insert(fields, AmrLevel) | 624 table.insert(fields, AmrDb.Level) |
| 789 | 625 |
| 790 local profs = {} | 626 local profs = {} |
| 791 local noprofs = true | 627 local noprofs = true |
| 792 if AmrProfessions then | 628 if AmrDb.Professions then |
| 793 for k, v in pairs(AmrProfessions) do | 629 for k, v in pairs(AmrDb.Professions) do |
| 794 local profval = professionIds[k] | 630 local profval = AskMrRobot.professionIds[k] |
| 795 if profval ~= nil then | 631 if profval ~= nil then |
| 796 noprofs = false | 632 noprofs = false |
| 797 table.insert(profs, profval .. ":" .. v) | 633 table.insert(profs, profval .. ":" .. v) |
| 798 end | 634 end |
| 799 end | 635 end |
| 803 table.insert(profs, "0:0") | 639 table.insert(profs, "0:0") |
| 804 end | 640 end |
| 805 | 641 |
| 806 table.insert(fields, table.concat(profs, ",")) | 642 table.insert(fields, table.concat(profs, ",")) |
| 807 | 643 |
| 808 if (AmrActiveSpec ~= nil) then | 644 -- export specs |
| 809 table.insert(fields, AmrActiveSpec) | 645 table.insert(fields, AmrDb.ActiveSpec) |
| 810 table.insert(fields, AmrSpecializations[AmrActiveSpec .. ""]) | 646 for spec = 1, 2 do |
| 811 table.insert(fields, AmrTalents[AmrActiveSpec]) | 647 if AmrDb.Specs[spec] and (complete or spec == AmrDb.ActiveSpec) then |
| 812 table.insert(fields, toCompressedNumberList(AmrGlyphs[AmrActiveSpec])) | 648 table.insert(fields, ".s" .. spec) -- indicates the start of a spec block |
| 813 else | 649 table.insert(fields, AmrDb.Specs[spec]) |
| 814 table.insert(fields, "_") | 650 table.insert(fields, AmrDb.Talents[spec]) |
| 815 table.insert(fields, "_") | 651 table.insert(fields, AskMrRobot.toCompressedNumberList(AmrDb.Glyphs[spec])) |
| 816 table.insert(fields, "_") | 652 end |
| 817 table.insert(fields, "_") | 653 end |
| 818 end | 654 |
| 819 | 655 -- export equipped gear |
| 820 -- convert items to parsed objects, sorted by id | 656 if AmrDb.Equipped then |
| 821 local itemObjects = {} | 657 for spec = 1, 2 do |
| 822 if AmrEquipedItems then | 658 if AmrDb.Equipped[spec] and (complete or spec == AmrDb.ActiveSpec) then |
| 823 for k, v in pairs(AmrEquipedItems) do | 659 table.insert(fields, ".q" .. spec) -- indicates the start of an equipped gear block |
| 824 local itemData = parseItemLink(v) | 660 |
| 825 itemData.slot = k | 661 local itemObjects = {} |
| 826 table.insert(itemObjects, itemData) | 662 for k, v in pairs(AmrDb.Equipped[spec]) do |
| 827 end | 663 local itemData = AskMrRobot.parseItemLink(v) |
| 828 end | 664 itemData.slot = k |
| 829 | 665 table.insert(itemObjects, itemData) |
| 830 -- if desired, include bank/bag items too | 666 end |
| 831 if includeInventory then | 667 |
| 832 if AmrBagItems then | 668 appendItemsToExport(fields, itemObjects) |
| 833 for i, v in ipairs(AmrBagItems) do | 669 end |
| 834 local itemData = parseItemLink(v) | 670 end |
| 835 if itemData.itemId ~= nil then | 671 end |
| 672 | |
| 673 -- if doing a complete export, include reputations and bank/bag items too | |
| 674 if complete then | |
| 675 | |
| 676 -- export reputations | |
| 677 local reps = {} | |
| 678 local noreps = true | |
| 679 if AmrDb.Reps then | |
| 680 for k, v in pairs(AmrDb.Reps) do | |
| 681 noreps = false | |
| 682 table.insert(reps, k .. ":" .. v) | |
| 683 end | |
| 684 end | |
| 685 if noreps then | |
| 686 table.insert(reps, "_") | |
| 687 end | |
| 688 | |
| 689 table.insert(fields, ".r") | |
| 690 table.insert(fields, table.concat(reps, ",")) | |
| 691 | |
| 692 -- export bag and bank | |
| 693 local itemObjects = {} | |
| 694 if AmrDb.BagItems then | |
| 695 for i, v in ipairs(AmrDb.BagItems) do | |
| 696 local itemData = AskMrRobot.parseItemLink(v) | |
| 697 if itemData ~= nil then | |
| 836 table.insert(itemObjects, itemData) | 698 table.insert(itemObjects, itemData) |
| 837 end | 699 end |
| 838 end | 700 end |
| 839 end | 701 end |
| 840 if AmrBankItems then | 702 if AmrDb.BankItems then |
| 841 for i, v in ipairs(AmrBankItems) do | 703 for i, v in ipairs(AmrDb.BankItems) do |
| 842 local itemData = parseItemLink(v) | 704 local itemData = AskMrRobot.parseItemLink(v) |
| 843 if itemData.itemId ~= nil then | 705 if itemData ~= nil then |
| 844 table.insert(itemObjects, itemData) | 706 table.insert(itemObjects, itemData) |
| 845 end | 707 end |
| 846 end | 708 end |
| 847 end | 709 end |
| 848 end | 710 |
| 849 | 711 table.insert(fields, ".inv") |
| 850 -- sort by item id so we can compress it more easily | 712 appendItemsToExport(fields, itemObjects) |
| 851 table.sort(itemObjects, function(a, b) return a.itemId < b.itemId end) | |
| 852 | |
| 853 -- append to the export string | |
| 854 local prevItemId = 0 | |
| 855 local prevGemId = 0 | |
| 856 local prevEnchantId = 0 | |
| 857 for i, itemData in ipairs(itemObjects) do | |
| 858 | |
| 859 local itemParts = {} | |
| 860 | |
| 861 table.insert(itemParts, itemData.itemId - prevItemId) | |
| 862 prevItemId = itemData.itemId | |
| 863 | |
| 864 if itemData.slot ~= nil then table.insert(itemParts, "s" .. itemData.slot) end | |
| 865 if itemData.suffixId ~= 0 then table.insert(itemParts, "f" .. itemData.suffixId) end | |
| 866 if upgradeTable[itemData.upgradeId] ~= 0 then table.insert(itemParts, "u" .. upgradeTable[itemData.upgradeId]) end | |
| 867 if itemData.gemEnchantIds[1] ~= 0 then | |
| 868 table.insert(itemParts, "a" .. (itemData.gemEnchantIds[1] - prevGemId)) | |
| 869 prevGemId = itemData.gemEnchantIds[1] | |
| 870 end | |
| 871 if itemData.gemEnchantIds[2] ~= 0 then | |
| 872 table.insert(itemParts, "b" .. (itemData.gemEnchantIds[2] - prevGemId)) | |
| 873 prevGemId = itemData.gemEnchantIds[2] | |
| 874 end | |
| 875 if itemData.gemEnchantIds[3] ~= 0 then | |
| 876 table.insert(itemParts, "c" .. (itemData.gemEnchantIds[3] - prevGemId)) | |
| 877 prevGemId = itemData.gemEnchantIds[3] | |
| 878 end | |
| 879 if itemData.enchantId ~= 0 then | |
| 880 table.insert(itemParts, "e" .. (itemData.enchantId - prevEnchantId)) | |
| 881 prevEnchantId = itemData.enchantId | |
| 882 end | |
| 883 if itemData.reforgeId ~= 0 then table.insert(itemParts, "r" .. (itemData.reforgeId - 113)) end | |
| 884 | |
| 885 table.insert(fields, table.concat(itemParts, "")) | |
| 886 end | 713 end |
| 887 | 714 |
| 888 return "$" .. table.concat(fields, ";") .. "$" | 715 return "$" .. table.concat(fields, ";") .. "$" |
| 889 end | |
| 890 | |
| 891 local function GetPlayerExtraData(data, index) | |
| 892 | |
| 893 local unitId = "raid" .. index | |
| 894 | |
| 895 local guid = UnitGUID(unitId) | |
| 896 if guid == nil then | |
| 897 return nil | |
| 898 end | |
| 899 | |
| 900 local fields = {} | |
| 901 | |
| 902 local buffs = {} | |
| 903 for i=1,40 do | |
| 904 local _,_,_,count,_,_,_,_,_,_,spellId = UnitAura(unitId, i, "HELPFUL") | |
| 905 table.insert(buffs, spellId) | |
| 906 end | |
| 907 if #buffs == 0 then | |
| 908 table.insert(fields, "_") | |
| 909 else | |
| 910 table.insert(fields, toCompressedNumberList(buffs)) | |
| 911 end | |
| 912 | |
| 913 local petGuid = UnitGUID("raidpet" .. index) | |
| 914 if petGuid then | |
| 915 table.insert(fields, guid .. "," .. petGuid) | |
| 916 else | |
| 917 table.insert(fields, '_') | |
| 918 end | |
| 919 | |
| 920 local name = GetRaidRosterInfo(index) | |
| 921 local realm = GetRealmName() | |
| 922 local splitPos = string.find(name, "-") | |
| 923 if splitPos ~= nil then | |
| 924 realm = string.sub(name, splitPos + 1) | |
| 925 name = string.sub(name, 1, splitPos - 1) | |
| 926 end | |
| 927 | |
| 928 data[realm .. ":" .. name] = table.concat(fields, ";") | |
| 929 end | |
| 930 | |
| 931 function AskMrRobot.ExportLoggingData(timestamp) | |
| 932 | |
| 933 local isLogging = AskMrRobot_ReforgeFrame.combatLogTab:IsLogging() | |
| 934 if not isLogging then | |
| 935 return | |
| 936 end | |
| 937 | |
| 938 -- we only get extra information for people if in a raid | |
| 939 if not IsInRaid() then | |
| 940 return | |
| 941 end | |
| 942 | |
| 943 local data = {} | |
| 944 for i = 1,40 do | |
| 945 GetPlayerExtraData(data, i) | |
| 946 end | |
| 947 | |
| 948 AskMrRobot.CombatLogTab.SaveExtras(data, timestamp) | |
| 949 end | 716 end |
| 950 | 717 |
| 951 function AskMrRobot.ExportToAddonChat(timestamp) | 718 function AskMrRobot.ExportToAddonChat(timestamp) |
| 952 local msg = AskMrRobot.ExportToCompressedString(false) | 719 local msg = AskMrRobot.ExportToCompressedString(false) |
| 953 local msgPrefix = timestamp .. "\n" .. AmrRealmName .. "\n" .. AmrCharacterName .. "\n" | 720 local msgPrefix = timestamp .. "\n" .. AmrRealmName .. "\n" .. AmrCharacterName .. "\n" |
| 971 SendAddonMessage(AskMrRobot.ChatPrefix, msgPrefix .. "done", "RAID") | 738 SendAddonMessage(AskMrRobot.ChatPrefix, msgPrefix .. "done", "RAID") |
| 972 end | 739 end |
| 973 | 740 |
| 974 -- Create an export string that can be copied to the website | 741 -- Create an export string that can be copied to the website |
| 975 function AskMrRobot.ExportToString() | 742 function AskMrRobot.ExportToString() |
| 976 | |
| 977 --[[ | |
| 978 local fields = {} | |
| 979 | |
| 980 fields["realm"] = AmrRealmName | |
| 981 fields["name"] = AmrCharacterName | |
| 982 fields["race"] = AmrRace | |
| 983 fields["faction"] = AmrFaction | |
| 984 fields["level"] = AmrLevel | |
| 985 | |
| 986 local profs = {} | |
| 987 for k, v in pairs(AmrProfessions) do | |
| 988 table.insert(profs, k .. ":" .. v) | |
| 989 end | |
| 990 fields["professions"] = table.concat(profs, ",") | |
| 991 | |
| 992 if (AmrActiveSpec ~= nil) then | |
| 993 fields["activespec"] = AmrActiveSpec | |
| 994 fields["spec"] = AmrSpecializations[AmrActiveSpec .. ""] | |
| 995 fields["talents"] = AmrTalents[AmrActiveSpec] | |
| 996 fields["glyphs"] = table.concat(AmrGlyphs[AmrActiveSpec], ",") | |
| 997 end | |
| 998 | |
| 999 local items = {} | |
| 1000 for k, v in pairs(AmrEquipedItems) do | |
| 1001 table.insert(items, ItemLinkToExportString(v, k)) | |
| 1002 end | |
| 1003 for i, v in ipairs(AmrBagItems) do | |
| 1004 table.insert(items, ItemLinkToExportString(v, "-1")) | |
| 1005 end | |
| 1006 for i, v in ipairs(AmrBankItems) do | |
| 1007 table.insert(items, ItemLinkToExportString(v, "-1")) | |
| 1008 end | |
| 1009 fields["items"] = table.concat(items, "_") | |
| 1010 | |
| 1011 local fieldList = {} | |
| 1012 for k, v in pairs(fields) do | |
| 1013 table.insert(fieldList, k .. "=" .. v) | |
| 1014 end | |
| 1015 ]] | |
| 1016 | |
| 1017 --return table.concat(fieldList, ";") | |
| 1018 | |
| 1019 return AskMrRobot.ExportToCompressedString(true) | 743 return AskMrRobot.ExportToCompressedString(true) |
| 1020 --return AskMrRobot.ExportToAddonChat(time()) | 744 end |
| 1021 end | 745 |
| 1022 | 746 |
| 1023 local function parseGlyphs(input) | 747 ---------------------------------------------------------------------------- |
| 1024 local glyphs = {} | 748 -- Import |
| 1025 for glyph in string.gmatch(input, "([^,]+)") do | 749 ---------------------------------------------------------------------------- |
| 1026 tinsert(glyphs, glyph) | 750 |
| 1027 end | 751 -- imports will give us extra information about items, gems, and enchants |
| 1028 table.sort(glyphs) | 752 AskMrRobot.ExtraItemData = {} -- keyed by item id |
| 1029 return glyphs | 753 AskMrRobot.ExtraGemData = {} -- keyed by gem enchant id |
| 1030 end | 754 AskMrRobot.ExtraEnchantData = {} -- keyed by enchant id |
| 1031 | 755 |
| 1032 local function parseProfessions(input) | 756 -- the data that was last imported |
| 1033 local professions = {} | 757 AskMrRobot.ImportData = nil -- keyed by slot id |
| 1034 for prof, v in string.gmatch(input, "([^:,]+):([^,]+)") do | 758 |
| 1035 professions[prof] = tonumber(v); | 759 local MIN_IMPORT_VERSION = 2 |
| 1036 end | 760 |
| 1037 return professions; | 761 -- |
| 1038 end | 762 -- Import a character, returning nil on success, otherwise an error message, import result stored in AskMrRobot.ImportData |
| 1039 | 763 -- |
| 1040 local gemColorMapping = { | 764 function AskMrRobot.ImportCharacter(data) |
| 1041 y = 'Yellow', | 765 |
| 1042 b = 'Blue', | 766 -- make sure all data is up to date before importing |
| 1043 r = 'Red', | 767 AskMrRobot.SaveAll() |
| 1044 h = 'Hydraulic', | 768 |
| 1045 p = 'Prismatic', | 769 if data == nil or string.len(data) == 0 then |
| 1046 m = 'Meta', | 770 return L.AMR_IMPORT_ERROR_EMPTY |
| 1047 c = 'Cogwheel' | 771 end |
| 1048 } | 772 |
| 1049 | 773 local data1 = { strsplit("$", data) } |
| 1050 local function parseAmrItem(input) | 774 if #data1 ~= 3 then |
| 1051 local slot, itemId, suffixList, upgradeId, gemColorString, gemEnchantIdString, gemIdString, enchantId, reforgeId = string.match(input, "^(%d+):(%d+):([^:]+):([^:]+):([^:]+):([^:]+):([^:]+):(%d+):(%d+)"); | 775 return L.AMR_IMPORT_ERROR_FORMAT |
| 1052 -- parse the gem enchant ids out of their comma seperated list | 776 end |
| 1053 local gems = {} | 777 |
| 1054 for gemEnchantId in string.gmatch(gemEnchantIdString, '(%d+)') do | 778 local parts = { strsplit(";", data1[2]) } |
| 1055 tinsert(gems, {enchantId = tonumber(gemEnchantId), id = 0}) | 779 |
| 1056 end | 780 -- require a minimum version |
| 1057 -- make sure we have 4 gem ids | 781 local ver = tonumber(parts[1]) |
| 1058 for i = #gems + 1, 4 do | 782 if ver < MIN_IMPORT_VERSION then |
| 1059 tinsert(gems, {enchantId = 0, id = 0}) | 783 return L.AMR_IMPORT_ERROR_VERSION |
| 1060 end | 784 end |
| 1061 -- parse the gem ids out of their comma seperated list | 785 |
| 1062 local gemIds = {} | 786 -- require realm/name match |
| 1063 i = 1 | 787 local realm = parts[2] |
| 1064 for gemId in string.gmatch(gemIdString, '(%d+)') do | 788 local name = parts[3] |
| 1065 gems[i].id = tonumber(gemId) | 789 if realm ~= AmrDb.RealmName or name ~= AmrDb.CharacterName then |
| 1066 i = i + 1 | 790 local badPers = name .. " (" .. realm .. ")" |
| 1067 end | 791 local goodPers = AmrDb.CharacterName .. " (" .. AmrDb.RealmName .. ")" |
| 1068 i = 1 | 792 return L.AMR_IMPORT_ERROR_CHAR:format(badPers, goodPers) |
| 1069 for gemColor in string.gmatch(gemColorString, '([^,])') do | 793 end |
| 1070 gems[i].color = gemColorMapping[gemColor] | 794 |
| 1071 i = i + 1 | 795 -- require race match |
| 1072 end | 796 local race = tonumber(parts[5]) |
| 1073 | 797 if race ~= AskMrRobot.raceIds[AmrDb.Race] then |
| 1074 -- parse the possible suffixes out of their comma seperated list and put them in a set (number -> bool) | 798 return L.AMR_IMPORT_ERROR_RACE |
| 1075 local suffixes = {} | 799 end |
| 1076 for suffixId in string.gmatch(suffixList, '(%-?%d+)') do | 800 |
| 1077 suffixes[tonumber(suffixId)] = true | 801 -- require faction match |
| 1078 end | 802 local faction = tonumber(parts[6]) |
| 1079 | 803 if faction ~= AskMrRobot.factionIds[AmrDb.Faction] then |
| 1080 local item = { | 804 return L.AMR_IMPORT_ERROR_FACTION |
| 1081 itemId = tonumber(itemId), | 805 end |
| 1082 suffixes = suffixes, | 806 |
| 1083 upgradeId = tonumber(upgradeId), | 807 -- require level match |
| 1084 gems = gems, | 808 local level = tonumber(parts[7]) |
| 1085 enchantId = tonumber(enchantId), | 809 if level ~= AmrDb.Level then |
| 1086 reforgeId = tonumber(reforgeId) | 810 return L.AMR_IMPORT_ERROR_LEVEL |
| 1087 } | 811 end |
| 1088 return slot, item | 812 |
| 1089 end | 813 -- require spec match |
| 1090 | 814 local spec = tonumber(parts[11]) |
| 1091 | 815 if spec ~= AmrDb.Specs[AmrDb.ActiveSpec] then |
| 1092 function AskMrRobot.parseAmr(input) | 816 print(AmrDb.ActiveSpec) |
| 1093 local parsedInput = {} | 817 print(spec) |
| 1094 parsedInput.items = {} | 818 print(AmrDb.Specs[AmrDb.ActiveSpec]) |
| 1095 for k, v in string.gmatch(input, "([^=;]+)=([^;]*)") do | 819 local _, specName = GetSpecializationInfoByID(AskMrRobot.gameSpecIds[spec]) |
| 1096 if (k == 'item') then | 820 return L.AMR_IMPORT_ERROR_SPEC:format(specName) |
| 1097 local slot, item = parseAmrItem(v); | 821 end |
| 1098 parsedInput.items[AskMrRobot.slotIdToSlotNum[tonumber(slot) + 1]] = item; | 822 |
| 1099 elseif (k == 'glyphs') then | 823 -- require talent match |
| 1100 parsedInput.glyphs = parseGlyphs(v) | 824 local talents = parts[12] |
| 1101 elseif (k == 'professions') then | 825 if talents ~= AmrDb.Talents[AmrDb.ActiveSpec] then |
| 1102 parsedInput.professions = parseProfessions(v) | 826 return L.AMR_IMPORT_ERROR_TALENT |
| 1103 else | 827 end |
| 1104 parsedInput[k]=v | 828 |
| 1105 end | 829 -- require glyph match |
| 1106 end | 830 -- TODO: re-enable this check when glyphs are more consistent |
| 1107 return parsedInput | 831 --local glyphs = parts[13] |
| 1108 end | 832 --if glyphs ~= AskMrRobot.toCompressedNumberList(AmrDb.Glyphs[AmrDb.ActiveSpec]) then |
| 1109 | 833 -- return L.AMR_IMPORT_ERROR_GLYPH |
| 1110 function AskMrRobot.validateRealm(realm) | 834 --end |
| 1111 return realm == GetRealmName(); | 835 |
| 1112 end | 836 -- if we make it this far, the data is valid, so read item information |
| 1113 | 837 local importData = {} |
| 1114 function AskMrRobot.validateCharacterName(characterName) | 838 |
| 1115 return UnitName("player") == characterName | 839 local itemInfo = {} |
| 1116 end | 840 local gemInfo = {} |
| 1117 | 841 local enchantInfo = {} |
| 1118 function AskMrRobot.validateRace(race) | 842 |
| 1119 local _, raceEn = UnitRace("player") | 843 local prevItemId = 0 |
| 1120 return raceEn == race or (raceEn == "Scourge" and race == "Undead") | 844 local prevGemId = 0 |
| 1121 end | 845 local prevEnchantId = 0 |
| 1122 | 846 local prevUpgradeId = 0 |
| 1123 function AskMrRobot.validateFaction(faction) | 847 local prevBonusId = 0 |
| 1124 return faction == UnitFactionGroup("player") | 848 local digits = { |
| 1125 end | 849 ["-"] = true, |
| 1126 | 850 ["0"] = true, |
| 1127 function AskMrRobot.validateSpec(spec) | 851 ["1"] = true, |
| 1128 if spec == 'nil' then | 852 ["2"] = true, |
| 1129 spec = nil | 853 ["3"] = true, |
| 1130 end | 854 ["4"] = true, |
| 1131 local currentSpec = GetAmrSpecialization(GetActiveSpecGroup()) | 855 ["5"] = true, |
| 1132 return (not currentSpec and not spec) or tostring(currentSpec) == spec | 856 ["6"] = true, |
| 1133 end | 857 ["7"] = true, |
| 1134 | 858 ["8"] = true, |
| 1135 function AskMrRobot.validateTalents(talents) | 859 ["9"] = true, |
| 1136 if talents == nil then | 860 } |
| 1137 talents = '' | 861 for i = 15, #parts do |
| 1138 end | 862 local itemString = parts[i] |
| 1139 return talents == GetAmrTalentsForSpec(GetActiveSpecGroup()) | 863 if itemString ~= "" and itemString ~= "_" then |
| 1140 end | 864 local tokens = {} |
| 1141 | 865 local bonusIds = {} |
| 1142 function AskMrRobot.validateGlyphs(glyphs) | 866 local hasBonuses = false |
| 1143 if (glyphs == nil) then | 867 local token = "" |
| 1144 glyphs = {}; | 868 local prop = "i" |
| 1145 end | 869 local tokenComplete = false |
| 1146 local currentGlyphs = GetAmrGlyphsForSpec(GetActiveSpecGroup()) | 870 for j = 1, string.len(itemString) do |
| 1147 table.sort(glyphs, function(a,b) return tostring(a) < tostring(b) end) | 871 local c = string.sub(itemString, j, j) |
| 1148 table.sort(currentGlyphs, function(a,b) return tostring(a) < tostring(b) end) | 872 if digits[c] == nil then |
| 1149 | 873 tokenComplete = true |
| 1150 if #glyphs ~= #currentGlyphs then | 874 else |
| 1151 return false | 875 token = token .. c |
| 1152 end | 876 end |
| 1153 for i = 1, #glyphs do | 877 |
| 1154 if tostring(glyphs[i]) ~= tostring(currentGlyphs[i]) then | 878 if tokenComplete or j == string.len(itemString) then |
| 1155 return false | 879 local val = tonumber(token) |
| 1156 end | 880 if prop == "i" then |
| 1157 end | 881 val = val + prevItemId |
| 1158 | 882 prevItemId = val |
| 1159 return true | 883 elseif prop == "u" then |
| 1160 end | 884 val = val + prevUpgradeId |
| 1161 | 885 prevUpgradeId = val |
| 1162 local function getPrimaryProfessions() | 886 elseif prop == "b" then |
| 1163 local profs = {} | 887 val = val + prevBonusId |
| 1164 local prof1, prof2 = GetProfessions() | 888 prevBonusId = val |
| 1165 local profMap = { | 889 elseif prop == "x" or prop == "y" or prop == "z" then |
| 1166 [794] = "Archaeology", | 890 val = val + prevGemId |
| 1167 [171] = "Alchemy", | 891 prevGemId = val |
| 1168 [164] = "Blacksmithing", | 892 elseif prop == "e" then |
| 1169 [185] = "Cooking", | 893 val = val + prevEnchantId |
| 1170 [333] = "Enchanting", | 894 prevEnchantId = val |
| 1171 [202] = "Engineering", | 895 end |
| 1172 [129] = "First Aid", | 896 |
| 1173 [356] = "Fishing", | 897 if prop == "b" then |
| 1174 [182] = "Herbalism", | 898 table.insert(bonusIds, val) |
| 1175 [773] = "Inscription", | 899 hasBonuses = true |
| 1176 [755] = "Jewelcrafting", | 900 else |
| 1177 [165] = "Leatherworking", | 901 tokens[prop] = val |
| 1178 [186] = "Mining", | 902 end |
| 1179 [393] = "Skinning", | 903 |
| 1180 [197] = "Tailoring" | 904 token = "" |
| 1181 } | 905 tokenComplete = false |
| 1182 | 906 |
| 1183 if prof1 then | 907 -- we have moved on to the next token |
| 1184 local _, _, skillLevel, _, _, _, skillLine = GetProfessionInfo(prof1); | 908 prop = c |
| 1185 if profMap[skillLine] ~= nil then | 909 end |
| 1186 profs[profMap[skillLine]] = skillLevel | 910 end |
| 1187 end | 911 |
| 1188 end | 912 local obj = {} |
| 1189 if prof2 then | 913 importData[tonumber(tokens["s"])] = obj |
| 1190 local _, _, skillLevel, _, _, _, skillLine = GetProfessionInfo(prof2); | 914 |
| 1191 if profMap[skillLine] ~= nil then | 915 obj.id = tokens["i"] |
| 1192 profs[profMap[skillLine]] = skillLevel | 916 obj.suffixId = tokens["f"] or 0 |
| 1193 end | 917 obj.upgradeId = tokens["u"] or 0 |
| 1194 end | 918 obj.enchantId = tokens["e"] or 0 |
| 1195 return profs; | 919 |
| 1196 end | 920 obj.gemIds = {} |
| 1197 | 921 table.insert(obj.gemIds, tokens["x"] or 0) |
| 1198 local professionThresholds = { | 922 table.insert(obj.gemIds, tokens["y"] or 0) |
| 1199 Leatherworking = 575, | 923 table.insert(obj.gemIds, tokens["z"] or 0) |
| 1200 Inscription = 600, | 924 table.insert(obj.gemIds, 0) |
| 1201 Alchemy = 50, | 925 |
| 1202 Enchanting = 550, | 926 if hasBonuses then |
| 1203 Jewelcrafting = 550, | 927 obj.bonusIds = bonusIds |
| 1204 Blacksmithing = 550, | 928 end |
| 1205 Tailoring = 550 | 929 |
| 1206 } | 930 local itemObj = {} |
| 1207 | 931 itemObj.id = obj.id |
| 1208 function AskMrRobot.validateProfessions(professions) | 932 itemInfo[obj.id] = itemObj |
| 1209 local currentProfessions = getPrimaryProfessions() | 933 |
| 1210 if #currentProfessions ~= #professions then | 934 -- look for any socket color information, add to our extra data |
| 1211 return false | 935 if tokens["c"] then |
| 1212 end | 936 itemObj.socketColors = {} |
| 1213 for k, v in pairs(professions) do | 937 for j = 1, string.len(tokens["c"]) do |
| 1214 if currentProfessions[k] then | 938 table.insert(itemObj.socketColors, tonumber(string.sub(tokens["c"], j, j))) |
| 1215 local threshold = professionThresholds[k] | 939 end |
| 1216 if not threshold then | 940 end |
| 1217 threshold = 1 | 941 |
| 1218 end | 942 -- look for item ID duplicate info, deals with old SoO items |
| 1219 -- compare the desired profession against the threshold | 943 if tokens["d"] then |
| 1220 local desired = v >= threshold | 944 itemObj.duplicateId = tonumber(tokens["d"]) |
| 1221 -- compare the current profession against the threshold | 945 end |
| 1222 local has = currentProfessions[k] and currentProfessions[k] >= threshold | 946 |
| 1223 -- if the current value is on the other side of the threshold | 947 end |
| 1224 -- then we don't match | 948 end |
| 1225 if desired ~= has then | 949 |
| 1226 return false | 950 -- now read any extra display information |
| 1227 end | 951 parts = { strsplit("@", data1[3]) } |
| 1228 else | 952 for i = 1, #parts do |
| 1229 return false | 953 local infoParts = { strsplit("\\", parts[i]) } |
| 1230 end | 954 |
| 1231 end | 955 if infoParts[1] == "g" then |
| 1232 return true | 956 |
| 1233 end | 957 local gemObj = {} |
| 1234 | 958 gemObj.enchantId = tonumber(infoParts[2]) |
| 1235 function AskMrRobot.populateItemDiffs(amrItem, itemLink, slotNum) | 959 gemObj.id = tonumber(infoParts[3]) |
| 1236 AskMrRobot.itemDiffs.items[slotNum] = nil | 960 |
| 1237 AskMrRobot.itemDiffs.gems[slotNum] = nil | 961 local identicalGems = infoParts[4] |
| 1238 AskMrRobot.itemDiffs.enchants[slotNum] = nil | 962 if string.len(identicalGems) > 0 then |
| 1239 AskMrRobot.itemDiffs.reforges[slotNum] = nil | 963 gemObj.identicalGroup = {} |
| 1240 | 964 identicalGems = { strsplit(",", identicalGems) } |
| 1241 local needsUpgrade = false | 965 for j = 1, #identicalGems do |
| 1242 local aSuffix = 0 | 966 gemObj.identicalGroup[tonumber(identicalGems[j])] = true |
| 1243 if amrItem then | 967 end |
| 1244 for k,v in pairs(amrItem.suffixes) do | 968 end |
| 1245 aSuffix = k | 969 |
| 1246 end | 970 gemObj.text = string.gsub(infoParts[5], "_(%a+)_", function(s) return L.AMR_STAT_SHORT_STRINGS[s] end) |
| 1247 end | 971 if infoParts[6] == nil or string.len(infoParts[6]) == 0 then |
| 1248 | 972 gemObj.identicalItemGroup = {[gemObj.id]=true} |
| 1249 if itemLink == nil then | 973 else |
| 1250 if amrItem ~= nil then | 974 local identicalIds = { strsplit(',', infoParts[6]) } |
| 1251 AskMrRobot.itemDiffs.items[slotNum] = { | 975 gemObj.identicalItemGroup = {} |
| 1252 current = nil, | 976 for j = 1, #identicalIds do |
| 1253 optimized = { itemId = amrItem.itemId, upgradeId = amrItem.upgradeId, suffixId = aSuffix }, | 977 gemObj.identicalItemGroup[tonumber(identicalIds[j])] = true |
| 1254 needsUpgrade = false | 978 end |
| 1255 } | 979 end |
| 1256 end | 980 |
| 1257 return | 981 gemInfo[gemObj.enchantId] = gemObj |
| 1258 end | 982 |
| 1259 local item = parseItemLink(itemLink) | 983 elseif infoParts[1] == "e" then |
| 1260 local isItemBad = false | 984 |
| 1261 | 985 local enchObj = {} |
| 1262 if amrItem == nil or item.itemId ~= amrItem.itemId then | 986 enchObj.id = tonumber(infoParts[2]) |
| 1263 isItemBad = true | 987 enchObj.itemId = tonumber(infoParts[3]) |
| 1264 else | 988 enchObj.spellId = tonumber(infoParts[4]) |
| 1265 if item.suffixId == 0 then | 989 enchObj.text = string.gsub(infoParts[5], "_(%a+)_", function(s) return L.AMR_STAT_SHORT_STRINGS[s] end) |
| 1266 if #amrItem.suffixes > 0 then | 990 |
| 1267 isItemBad = true | 991 local mats = infoParts[6] |
| 1268 end | 992 if string.len(mats) > 0 then |
| 1269 else | 993 enchObj.materials = {} |
| 1270 if not amrItem.suffixes[item.suffixId] then | 994 mats = { strsplit(",", mats) } |
| 1271 isItemBad = true | 995 for j = 1, #mats do |
| 1272 end | 996 local kv = { strsplit("=", mats[j]) } |
| 1273 end | 997 enchObj.materials[tonumber(kv[1])] = tonumber(kv[2]) |
| 1274 if not isItemBad and upgradeTable[item.upgradeId] ~= upgradeTable[amrItem.upgradeId] then | 998 end |
| 1275 isItemBad = true | 999 end |
| 1276 needsUpgrade = true | 1000 |
| 1277 end | 1001 enchantInfo[enchObj.id] = enchObj |
| 1278 end | 1002 |
| 1279 | 1003 end |
| 1280 if isItemBad then | 1004 end |
| 1281 AskMrRobot.itemDiffs.items[slotNum] = { | 1005 |
| 1282 current = item.itemId, | 1006 -- we have succeeded, record the result |
| 1283 optimized = { itemId = amrItem and amrItem.itemId or 0, upgradeId = amrItem and amrItem.upgradeId or 0, suffixId = aSuffix }, | 1007 AskMrRobot.ImportData = importData |
| 1284 needsUpgrade = needsUpgrade | 1008 AskMrRobot.ExtraItemData = itemInfo |
| 1285 } | 1009 AskMrRobot.ExtraGemData = gemInfo |
| 1286 return | 1010 AskMrRobot.ExtraEnchantData = enchantInfo |
| 1287 end | 1011 |
| 1288 | 1012 AmrDb.LastCharacterImport = data |
| 1289 local badGemCount, gemInfo = AskMrRobot.MatchesGems(itemLink, item.gemEnchantIds, amrItem.gems) | 1013 AmrDb.LastCharacterImportDate = date() |
| 1290 if badGemCount > 0 then | 1014 end |
| 1291 AskMrRobot.itemDiffs.gems[slotNum] = gemInfo | |
| 1292 end | |
| 1293 | |
| 1294 if item.enchantId ~= amrItem.enchantId then | |
| 1295 AskMrRobot.itemDiffs.enchants[slotNum] = { | |
| 1296 current = item.enchantId, | |
| 1297 optimized = amrItem.enchantId | |
| 1298 } | |
| 1299 end | |
| 1300 | |
| 1301 if item.reforgeId ~= amrItem.reforgeId then | |
| 1302 AskMrRobot.itemDiffs.reforges[slotNum] = { | |
| 1303 current = item.reforgeId, | |
| 1304 optimized = amrItem.reforgeId | |
| 1305 } | |
| 1306 end | |
| 1307 end | |
| 1308 | |
| 1309 --[[ | |
| 1310 function AskMrRobot.StartLogging() | |
| 1311 if not LoggingCombat() then | |
| 1312 LoggingCombat(1) | |
| 1313 print("Started Combat Logging") | |
| 1314 end | |
| 1315 end | |
| 1316 | |
| 1317 function AskMrRobot.FinishLogging() | |
| 1318 if LoggingCombat() then | |
| 1319 LoggingCombat(0) | |
| 1320 print("Finished Combat Logging") | |
| 1321 end | |
| 1322 end | |
| 1323 | |
| 1324 -- local difficultyLookup = { | |
| 1325 -- DUNGEON_DIFFICULTY1, | |
| 1326 -- DUNGEON_DIFFICULTY2, | |
| 1327 -- RAID_DIFFICULTY_10PLAYER, | |
| 1328 -- RAID_DIFFICULTY_25PLAYER, | |
| 1329 -- RAID_DIFFICULTY_10PLAYER_HEROIC, | |
| 1330 -- RAID_DIFFICULTY_25PLAYER_HEROIC, | |
| 1331 -- RAID_FINDER, | |
| 1332 -- CHALLENGE_MODE, | |
| 1333 -- RAID_DIFFICULTY_40PLAYER, | |
| 1334 -- nil, | |
| 1335 -- nil, -- Norm scen | |
| 1336 -- nil, -- heroic scen | |
| 1337 -- nil, | |
| 1338 -- PLAYER_DIFFICULTY4 | |
| 1339 -- } | |
| 1340 | |
| 1341 --http://wowpedia.org/InstanceMapID | |
| 1342 local instanceMaps = { | |
| 1343 HeartOfFear = 1009, | |
| 1344 MogushanVaults = 1008, | |
| 1345 SiegeOfOrgrimmar = 1136, | |
| 1346 TerraceOfEndlessSpring = 996, | |
| 1347 ThroneOfThunder = 1098 | |
| 1348 } | |
| 1349 | |
| 1350 function AskMrRobot.UpdateLogging() | |
| 1351 | |
| 1352 -- get the info about the instance | |
| 1353 --local zone, zonetype, difficultyIndex, difficultyName, maxPlayers, dynamicDifficulty, isDynamic, instanceMapID = GetInstanceInfo() | |
| 1354 local zone, _, difficultyIndex, _, _, _, _, instanceMapID = GetInstanceInfo() | |
| 1355 --local difficulty = difficultyIndex | |
| 1356 -- Unless Blizzard fixes scenarios to not return nil, let's hardcode this into returning "scenario" -Znuff | |
| 1357 --if zonetype == nil and difficultyIndex == 1 then | |
| 1358 --zonetype = "scenario" | |
| 1359 --end | |
| 1360 | |
| 1361 -- if nothing has changed, then bail | |
| 1362 --if (not zone) and difficulty == 0 then return end | |
| 1363 if zone == AskMrRobot.lastzone and difficultyIndex == AskMrRobot.lastdiff then | |
| 1364 -- do nothing if the zone hasn't ACTUALLY changed | |
| 1365 -- otherwise we may override the user's manual enable/disable | |
| 1366 return | |
| 1367 end | |
| 1368 | |
| 1369 AskMrRobot.lastzone = zone | |
| 1370 AskMrRobot.lastdiff = difficultyIndex | |
| 1371 | |
| 1372 if AmrOptions.autoLog[tonumber(instanceMapID)] then | |
| 1373 if instanceMapID == instanceMaps.SiegeOfOrgrimmar then | |
| 1374 AskMrRobot.StartLogging() | |
| 1375 else | |
| 1376 AskMrRobot.FinishLogging() | |
| 1377 end | |
| 1378 end | |
| 1379 end | |
| 1380 ]] |
