annotate AskMrRobot.lua @ 4:6ef021bd17b2 1.2.12.0

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