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