yellowfive@57: local Amr = LibStub("AceAddon-3.0"):GetAddon("AskMrRobot") yellowfive@57: local L = LibStub("AceLocale-3.0"):GetLocale("AskMrRobot", true) yellowfive@57: yellowfive@57: -- min import version that we will read from the website yellowfive@59: Amr.MIN_IMPORT_VERSION = 21 yellowfive@57: yellowfive@57: -- min addon version that we will support for inter-addon communication for e.g. the team optimizer yellowfive@63: -- last update to version 24 when item link format changed yellowfive@63: Amr.MIN_ADDON_VERSION = 24 yellowfive@57: yellowfive@57: -- import some constants from the serializer for convenience yellowfive@57: Amr.ChatPrefix = Amr.Serializer.ChatPrefix yellowfive@57: Amr.RegionNames = Amr.Serializer.RegionNames yellowfive@57: Amr.SlotIds = Amr.Serializer.SlotIds yellowfive@57: Amr.SpecIds = Amr.Serializer.SpecIds yellowfive@57: Amr.ClassIds = Amr.Serializer.ClassIds yellowfive@57: Amr.ProfessionIds = Amr.Serializer.ProfessionIds yellowfive@57: Amr.RaceIds = Amr.Serializer.RaceIds yellowfive@57: Amr.FactionIds = Amr.Serializer.FactionIds yellowfive@57: Amr.InstanceIds = Amr.Serializer.InstanceIds yellowfive@57: Amr.SupportedInstanceIds = Amr.Serializer.SupportedInstanceIds yellowfive@57: Amr.ParseItemLink = Amr.Serializer.ParseItemLink yellowfive@57: Amr.IsSupportedInstanceId = Amr.Serializer.IsSupportedInstanceId yellowfive@57: Amr.IsSupportedInstance = Amr.Serializer.IsSupportedInstance yellowfive@57: Amr.SetTokenIds = Amr.Serializer.SetTokenIds yellowfive@57: yellowfive@57: -- map of slot ID to display text yellowfive@57: Amr.SlotDisplayText = { yellowfive@57: [1] = _G["HEADSLOT"], yellowfive@57: [2] = _G["NECKSLOT"], yellowfive@57: [3] = _G["SHOULDERSLOT"], yellowfive@57: [5] = _G["CHESTSLOT"], yellowfive@57: [6] = _G["WAISTSLOT"], yellowfive@57: [7] = _G["LEGSSLOT"], yellowfive@57: [8] = _G["FEETSLOT"], yellowfive@57: [9] = _G["WRISTSLOT"], yellowfive@57: [10] = _G["HANDSSLOT"], yellowfive@57: [11] = _G["FINGER0SLOT"] .. " 1", yellowfive@57: [12] = _G["FINGER1SLOT"] .. " 2", yellowfive@57: [13] = _G["TRINKET0SLOT"] .. " 1", yellowfive@57: [14] = _G["TRINKET1SLOT"] .. " 2", yellowfive@57: [15] = _G["BACKSLOT"], yellowfive@57: [16] = _G["MAINHANDSLOT"], yellowfive@57: [17] = _G["SECONDARYHANDSLOT"] yellowfive@57: } yellowfive@57: yellowfive@57: Amr.SlotEnumDisplayText = { yellowfive@57: Head = _G["HEADSLOT"], yellowfive@57: Neck = _G["NECKSLOT"], yellowfive@57: Shoulder = _G["SHOULDERSLOT"], yellowfive@57: Chest = _G["CHESTSLOT"], yellowfive@57: Waist = _G["WAISTSLOT"], yellowfive@57: Legs = _G["LEGSSLOT"], yellowfive@57: Feet = _G["FEETSLOT"], yellowfive@57: Wrist = _G["WRISTSLOT"], yellowfive@57: Hands = _G["HANDSSLOT"], yellowfive@57: Finger1 = _G["FINGER0SLOT"], yellowfive@57: Finger2 = _G["FINGER0SLOT"], yellowfive@57: Trinket1 = _G["TRINKET0SLOT"], yellowfive@57: Trinket2 = _G["TRINKET0SLOT"], yellowfive@57: Back = _G["BACKSLOT"], yellowfive@57: MainHand = _G["MAINHANDSLOT"], yellowfive@57: OffHand = _G["SECONDARYHANDSLOT"] yellowfive@57: } yellowfive@57: yellowfive@57: Amr.SpecIcons = { yellowfive@57: [1] = "spell_deathknight_bloodpresence", -- DeathKnightBlood yellowfive@57: [2] = "spell_deathknight_frostpresence", -- DeathKnightFrost yellowfive@57: [3] = "spell_deathknight_unholypresence", -- DeathKnightUnholy yellowfive@57: [4] = "spell_nature_starfall", -- DruidBalance yellowfive@57: [5] = "ability_druid_catform", -- DruidFeral yellowfive@57: [6] = "ability_racial_bearform", -- DruidGuardian yellowfive@57: [7] = "spell_nature_healingtouch", -- DruidRestoration yellowfive@57: [8] = "ability_hunter_bestialdiscipline", -- HunterBeastMastery yellowfive@57: [9] = "ability_hunter_focusedaim", -- HunterMarksmanship yellowfive@57: [10] = "ability_hunter_camouflage", -- HunterSurvival yellowfive@57: [11] = "spell_holy_magicalsentry", -- MageArcane yellowfive@57: [12] = "spell_fire_firebolt02", -- MageFire yellowfive@57: [13] = "spell_frost_frostbolt02", -- MageFrost yellowfive@57: [14] = "spell_monk_brewmaster_spec", -- MonkBrewmaster yellowfive@57: [15] = "spell_monk_mistweaver_spec", -- MonkMistweaver yellowfive@57: [16] = "spell_monk_windwalker_spec", -- MonkWindwalker yellowfive@57: [17] = "spell_holy_holybolt", -- PaladinHoly yellowfive@57: [18] = "ability_paladin_shieldofthetemplar", -- PaladinProtection yellowfive@57: [19] = "spell_holy_auraoflight", -- PaladinRetribution yellowfive@57: [20] = "spell_holy_powerwordshield", -- PriestDiscipline yellowfive@57: [21] = "spell_holy_guardianspirit", -- PriestHoly yellowfive@57: [22] = "spell_shadow_shadowwordpain", -- PriestShadow yellowfive@57: [23] = "ability_rogue_eviscerate", -- RogueAssassination yellowfive@57: [24] = "ability_backstab", -- RogueCombat yellowfive@57: [25] = "ability_stealth", -- RogueSubtlety yellowfive@57: [26] = "spell_nature_lightning", -- ShamanElemental yellowfive@57: [27] = "spell_nature_lightningshield", -- ShamanEnhancement yellowfive@57: [28] = "spell_nature_magicimmunity", -- ShamanRestoration yellowfive@57: [29] = "spell_shadow_deathcoil", -- WarlockAffliction yellowfive@57: [30] = "spell_shadow_metamorphosis", -- WarlockDemonology yellowfive@57: [31] = "spell_shadow_rainoffire", -- WarlockDestruction yellowfive@57: [32] = "ability_warrior_savageblow", -- WarriorArms yellowfive@57: [33] = "ability_warrior_innerrage", -- WarriorFury yellowfive@57: [34] = "ability_warrior_defensivestance", -- WarriorProtection yellowfive@57: [38] = "ability_warrior_defensivestance", -- WarriorProtection, used for special subspec handling yellowfive@57: [39] = "spell_warrior_gladiatorstance" -- WarriorProtectionGlad, used for special subspec handling yellowfive@57: } yellowfive@57: yellowfive@57: -- instance IDs ordered in preferred display order yellowfive@61: Amr.InstanceIdsOrdered = { 1448, 1205, 1228 } yellowfive@57: yellowfive@57: Amr.Difficulties = { yellowfive@57: Lfr = 17, yellowfive@57: Normal = 14, yellowfive@57: Heroic = 15, yellowfive@57: Mythic = 16 yellowfive@57: } yellowfive@57: yellowfive@57: -- get the game's spec id from the AMR spec id yellowfive@57: function Amr.GetGameSpecId(specId) yellowfive@57: for k, v in pairs(Amr.SpecIds) do yellowfive@57: if v == specId then return k end yellowfive@57: end yellowfive@57: return nil yellowfive@57: end yellowfive@57: yellowfive@57: yellowfive@57: ------------------------------------------------------------------------------------------ yellowfive@57: -- Item Methods yellowfive@57: ------------------------------------------------------------------------------------------ yellowfive@57: yellowfive@57: -- item link format: |cffa335ee|Hitem:itemID:enchant:gem1:gem2:gem3:gem4:suffixID:uniqueID:level:upgradeId:instanceDifficultyID:numBonusIDs:bonusID1:bonusID2...|h[item name]|h|r yellowfive@57: yellowfive@57: function Amr.CreateItemLink(itemObj) yellowfive@57: yellowfive@57: if itemObj == nil or itemObj.id == nil or itemObj.id == 0 then return nil end yellowfive@57: yellowfive@57: local parts = {} yellowfive@57: table.insert(parts, "item") yellowfive@57: table.insert(parts, itemObj.id) yellowfive@57: table.insert(parts, itemObj.enchantId) yellowfive@57: table.insert(parts, itemObj.gemIds[1]) yellowfive@57: table.insert(parts, itemObj.gemIds[2]) yellowfive@57: table.insert(parts, itemObj.gemIds[3]) yellowfive@57: table.insert(parts, itemObj.gemIds[4]) yellowfive@57: yellowfive@57: if itemObj.suffixId == 0 then yellowfive@57: table.insert(parts, 0) yellowfive@57: else yellowfive@57: table.insert(parts, -math.abs(itemObj.suffixId)) yellowfive@57: end yellowfive@57: yellowfive@57: table.insert(parts, 0) yellowfive@57: table.insert(parts, UnitLevel("player")) yellowfive@57: table.insert(parts, itemObj.upgradeId) yellowfive@57: table.insert(parts, 0) yellowfive@57: yellowfive@57: if itemObj.bonusIds then yellowfive@57: table.insert(parts, #itemObj.bonusIds) yellowfive@57: for i,v in ipairs(itemObj.bonusIds) do yellowfive@57: table.insert(parts, v) yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: return table.concat(parts, ":") yellowfive@57: end yellowfive@57: yellowfive@57: -- a unique ID useful for determining if a player has an item equipped or not yellowfive@57: function Amr.GetItemUniqueId(item, noUpgrade) yellowfive@57: if item == nil then return "" end yellowfive@57: local ret = item.id .. "" yellowfive@57: if item.bonusIds then yellowfive@57: for i = 1, #item.bonusIds do yellowfive@57: ret = ret .. "b" .. item.bonusIds[i] yellowfive@57: end yellowfive@57: end yellowfive@57: if item.suffixId ~= 0 then yellowfive@57: ret = ret .. "s" .. item.suffixId yellowfive@57: end yellowfive@57: if not noUpgrade and item.upgradeId ~= 0 then yellowfive@57: ret = ret .. "u" .. item.upgradeId yellowfive@57: end yellowfive@57: return ret yellowfive@57: end yellowfive@57: yellowfive@57: -- the server event for getting item info does not specify which item it just fetched... have to track manually yellowfive@57: local _pendingItemIds = {} yellowfive@57: yellowfive@57: -- helper for getting item information, which is not always guaranteed to be loaded into memory yellowfive@57: function Amr.GetItemInfo(itemIdOrLinkOrName, callback, customArg) yellowfive@57: if not itemIdOrLinkOrName then yellowfive@57: callback(customArg) yellowfive@57: return yellowfive@57: end yellowfive@57: yellowfive@57: -- see if we can get the information immediately yellowfive@57: local name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture, vendorPrice = GetItemInfo(itemIdOrLinkOrName) yellowfive@57: if name then yellowfive@57: callback(customArg, name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture, vendorPrice) yellowfive@57: return yellowfive@57: end yellowfive@57: yellowfive@57: -- get the list of registered callbacks for this particular item yellowfive@57: local list = _pendingItemIds[itemIdOrLinkOrName] yellowfive@57: -- if there was a list, then just add the callback to the list yellowfive@57: if list then yellowfive@57: table.insert(list, { Callback = callback, Arg = customArg }) yellowfive@57: else yellowfive@57: -- there wasn't a list, so make a new one with this callback yellowfive@57: _pendingItemIds[itemIdOrLinkOrName] = { { Callback = callback, Arg = customArg } } yellowfive@57: end yellowfive@57: end yellowfive@57: yellowfive@57: Amr:AddEventHandler("GET_ITEM_INFO_RECEIVED", function() yellowfive@57: -- go through all unresolved items since we don't know which one was just resolved yellowfive@57: for itemId, callbacks in pairs(_pendingItemIds) do yellowfive@57: -- attempt to get the item info again, remove from pending list if we find it yellowfive@57: local name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture, vendorPrice = GetItemInfo(itemId) yellowfive@57: if name then yellowfive@57: _pendingItemIds[itemId] = nil yellowfive@57: yellowfive@57: -- call each callback yellowfive@57: for i = 1, #callbacks do yellowfive@57: callbacks[i].Callback(callbacks[i].Arg, name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture, vendorPrice) yellowfive@57: end yellowfive@57: end yellowfive@57: end yellowfive@57: end)