yellowfive@57
|
1 local Amr = LibStub("AceAddon-3.0"):GetAddon("AskMrRobot")
|
yellowfive@57
|
2 local L = LibStub("AceLocale-3.0"):GetLocale("AskMrRobot", true)
|
yellowfive@57
|
3
|
yellowfive@57
|
4 -- min import version that we will read from the website
|
yellowfive@59
|
5 Amr.MIN_IMPORT_VERSION = 21
|
yellowfive@57
|
6
|
yellowfive@57
|
7 -- min addon version that we will support for inter-addon communication for e.g. the team optimizer
|
yellowfive@63
|
8 -- last update to version 24 when item link format changed
|
yellowfive@63
|
9 Amr.MIN_ADDON_VERSION = 24
|
yellowfive@57
|
10
|
yellowfive@57
|
11 -- import some constants from the serializer for convenience
|
yellowfive@57
|
12 Amr.ChatPrefix = Amr.Serializer.ChatPrefix
|
yellowfive@57
|
13 Amr.RegionNames = Amr.Serializer.RegionNames
|
yellowfive@57
|
14 Amr.SlotIds = Amr.Serializer.SlotIds
|
yellowfive@57
|
15 Amr.SpecIds = Amr.Serializer.SpecIds
|
yellowfive@57
|
16 Amr.ClassIds = Amr.Serializer.ClassIds
|
yellowfive@57
|
17 Amr.ProfessionIds = Amr.Serializer.ProfessionIds
|
yellowfive@57
|
18 Amr.RaceIds = Amr.Serializer.RaceIds
|
yellowfive@57
|
19 Amr.FactionIds = Amr.Serializer.FactionIds
|
yellowfive@57
|
20 Amr.InstanceIds = Amr.Serializer.InstanceIds
|
yellowfive@57
|
21 Amr.SupportedInstanceIds = Amr.Serializer.SupportedInstanceIds
|
yellowfive@57
|
22 Amr.ParseItemLink = Amr.Serializer.ParseItemLink
|
yellowfive@57
|
23 Amr.IsSupportedInstanceId = Amr.Serializer.IsSupportedInstanceId
|
yellowfive@57
|
24 Amr.IsSupportedInstance = Amr.Serializer.IsSupportedInstance
|
yellowfive@57
|
25 Amr.SetTokenIds = Amr.Serializer.SetTokenIds
|
yellowfive@57
|
26
|
yellowfive@57
|
27 -- map of slot ID to display text
|
yellowfive@57
|
28 Amr.SlotDisplayText = {
|
yellowfive@57
|
29 [1] = _G["HEADSLOT"],
|
yellowfive@57
|
30 [2] = _G["NECKSLOT"],
|
yellowfive@57
|
31 [3] = _G["SHOULDERSLOT"],
|
yellowfive@57
|
32 [5] = _G["CHESTSLOT"],
|
yellowfive@57
|
33 [6] = _G["WAISTSLOT"],
|
yellowfive@57
|
34 [7] = _G["LEGSSLOT"],
|
yellowfive@57
|
35 [8] = _G["FEETSLOT"],
|
yellowfive@57
|
36 [9] = _G["WRISTSLOT"],
|
yellowfive@57
|
37 [10] = _G["HANDSSLOT"],
|
yellowfive@57
|
38 [11] = _G["FINGER0SLOT"] .. " 1",
|
yellowfive@57
|
39 [12] = _G["FINGER1SLOT"] .. " 2",
|
yellowfive@57
|
40 [13] = _G["TRINKET0SLOT"] .. " 1",
|
yellowfive@57
|
41 [14] = _G["TRINKET1SLOT"] .. " 2",
|
yellowfive@57
|
42 [15] = _G["BACKSLOT"],
|
yellowfive@57
|
43 [16] = _G["MAINHANDSLOT"],
|
yellowfive@57
|
44 [17] = _G["SECONDARYHANDSLOT"]
|
yellowfive@57
|
45 }
|
yellowfive@57
|
46
|
yellowfive@57
|
47 Amr.SlotEnumDisplayText = {
|
yellowfive@57
|
48 Head = _G["HEADSLOT"],
|
yellowfive@57
|
49 Neck = _G["NECKSLOT"],
|
yellowfive@57
|
50 Shoulder = _G["SHOULDERSLOT"],
|
yellowfive@57
|
51 Chest = _G["CHESTSLOT"],
|
yellowfive@57
|
52 Waist = _G["WAISTSLOT"],
|
yellowfive@57
|
53 Legs = _G["LEGSSLOT"],
|
yellowfive@57
|
54 Feet = _G["FEETSLOT"],
|
yellowfive@57
|
55 Wrist = _G["WRISTSLOT"],
|
yellowfive@57
|
56 Hands = _G["HANDSSLOT"],
|
yellowfive@57
|
57 Finger1 = _G["FINGER0SLOT"],
|
yellowfive@57
|
58 Finger2 = _G["FINGER0SLOT"],
|
yellowfive@57
|
59 Trinket1 = _G["TRINKET0SLOT"],
|
yellowfive@57
|
60 Trinket2 = _G["TRINKET0SLOT"],
|
yellowfive@57
|
61 Back = _G["BACKSLOT"],
|
yellowfive@57
|
62 MainHand = _G["MAINHANDSLOT"],
|
yellowfive@57
|
63 OffHand = _G["SECONDARYHANDSLOT"]
|
yellowfive@57
|
64 }
|
yellowfive@57
|
65
|
yellowfive@57
|
66 Amr.SpecIcons = {
|
yellowfive@57
|
67 [1] = "spell_deathknight_bloodpresence", -- DeathKnightBlood
|
yellowfive@57
|
68 [2] = "spell_deathknight_frostpresence", -- DeathKnightFrost
|
yellowfive@57
|
69 [3] = "spell_deathknight_unholypresence", -- DeathKnightUnholy
|
yellowfive@57
|
70 [4] = "spell_nature_starfall", -- DruidBalance
|
yellowfive@57
|
71 [5] = "ability_druid_catform", -- DruidFeral
|
yellowfive@57
|
72 [6] = "ability_racial_bearform", -- DruidGuardian
|
yellowfive@57
|
73 [7] = "spell_nature_healingtouch", -- DruidRestoration
|
yellowfive@57
|
74 [8] = "ability_hunter_bestialdiscipline", -- HunterBeastMastery
|
yellowfive@57
|
75 [9] = "ability_hunter_focusedaim", -- HunterMarksmanship
|
yellowfive@57
|
76 [10] = "ability_hunter_camouflage", -- HunterSurvival
|
yellowfive@57
|
77 [11] = "spell_holy_magicalsentry", -- MageArcane
|
yellowfive@57
|
78 [12] = "spell_fire_firebolt02", -- MageFire
|
yellowfive@57
|
79 [13] = "spell_frost_frostbolt02", -- MageFrost
|
yellowfive@57
|
80 [14] = "spell_monk_brewmaster_spec", -- MonkBrewmaster
|
yellowfive@57
|
81 [15] = "spell_monk_mistweaver_spec", -- MonkMistweaver
|
yellowfive@57
|
82 [16] = "spell_monk_windwalker_spec", -- MonkWindwalker
|
yellowfive@57
|
83 [17] = "spell_holy_holybolt", -- PaladinHoly
|
yellowfive@57
|
84 [18] = "ability_paladin_shieldofthetemplar", -- PaladinProtection
|
yellowfive@57
|
85 [19] = "spell_holy_auraoflight", -- PaladinRetribution
|
yellowfive@57
|
86 [20] = "spell_holy_powerwordshield", -- PriestDiscipline
|
yellowfive@57
|
87 [21] = "spell_holy_guardianspirit", -- PriestHoly
|
yellowfive@57
|
88 [22] = "spell_shadow_shadowwordpain", -- PriestShadow
|
yellowfive@57
|
89 [23] = "ability_rogue_eviscerate", -- RogueAssassination
|
yellowfive@57
|
90 [24] = "ability_backstab", -- RogueCombat
|
yellowfive@57
|
91 [25] = "ability_stealth", -- RogueSubtlety
|
yellowfive@57
|
92 [26] = "spell_nature_lightning", -- ShamanElemental
|
yellowfive@57
|
93 [27] = "spell_nature_lightningshield", -- ShamanEnhancement
|
yellowfive@57
|
94 [28] = "spell_nature_magicimmunity", -- ShamanRestoration
|
yellowfive@57
|
95 [29] = "spell_shadow_deathcoil", -- WarlockAffliction
|
yellowfive@57
|
96 [30] = "spell_shadow_metamorphosis", -- WarlockDemonology
|
yellowfive@57
|
97 [31] = "spell_shadow_rainoffire", -- WarlockDestruction
|
yellowfive@57
|
98 [32] = "ability_warrior_savageblow", -- WarriorArms
|
yellowfive@57
|
99 [33] = "ability_warrior_innerrage", -- WarriorFury
|
yellowfive@57
|
100 [34] = "ability_warrior_defensivestance", -- WarriorProtection
|
yellowfive@57
|
101 [38] = "ability_warrior_defensivestance", -- WarriorProtection, used for special subspec handling
|
yellowfive@57
|
102 [39] = "spell_warrior_gladiatorstance" -- WarriorProtectionGlad, used for special subspec handling
|
yellowfive@57
|
103 }
|
yellowfive@57
|
104
|
yellowfive@57
|
105 -- instance IDs ordered in preferred display order
|
yellowfive@61
|
106 Amr.InstanceIdsOrdered = { 1448, 1205, 1228 }
|
yellowfive@57
|
107
|
yellowfive@57
|
108 Amr.Difficulties = {
|
yellowfive@57
|
109 Lfr = 17,
|
yellowfive@57
|
110 Normal = 14,
|
yellowfive@57
|
111 Heroic = 15,
|
yellowfive@57
|
112 Mythic = 16
|
yellowfive@57
|
113 }
|
yellowfive@57
|
114
|
yellowfive@57
|
115 -- get the game's spec id from the AMR spec id
|
yellowfive@57
|
116 function Amr.GetGameSpecId(specId)
|
yellowfive@57
|
117 for k, v in pairs(Amr.SpecIds) do
|
yellowfive@57
|
118 if v == specId then return k end
|
yellowfive@57
|
119 end
|
yellowfive@57
|
120 return nil
|
yellowfive@57
|
121 end
|
yellowfive@57
|
122
|
yellowfive@57
|
123
|
yellowfive@57
|
124 ------------------------------------------------------------------------------------------
|
yellowfive@57
|
125 -- Item Methods
|
yellowfive@57
|
126 ------------------------------------------------------------------------------------------
|
yellowfive@57
|
127
|
yellowfive@57
|
128 -- 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
|
129
|
yellowfive@57
|
130 function Amr.CreateItemLink(itemObj)
|
yellowfive@57
|
131
|
yellowfive@57
|
132 if itemObj == nil or itemObj.id == nil or itemObj.id == 0 then return nil end
|
yellowfive@57
|
133
|
yellowfive@57
|
134 local parts = {}
|
yellowfive@57
|
135 table.insert(parts, "item")
|
yellowfive@57
|
136 table.insert(parts, itemObj.id)
|
yellowfive@57
|
137 table.insert(parts, itemObj.enchantId)
|
yellowfive@57
|
138 table.insert(parts, itemObj.gemIds[1])
|
yellowfive@57
|
139 table.insert(parts, itemObj.gemIds[2])
|
yellowfive@57
|
140 table.insert(parts, itemObj.gemIds[3])
|
yellowfive@57
|
141 table.insert(parts, itemObj.gemIds[4])
|
yellowfive@57
|
142
|
yellowfive@57
|
143 if itemObj.suffixId == 0 then
|
yellowfive@57
|
144 table.insert(parts, 0)
|
yellowfive@57
|
145 else
|
yellowfive@57
|
146 table.insert(parts, -math.abs(itemObj.suffixId))
|
yellowfive@57
|
147 end
|
yellowfive@57
|
148
|
yellowfive@57
|
149 table.insert(parts, 0)
|
yellowfive@57
|
150 table.insert(parts, UnitLevel("player"))
|
yellowfive@65
|
151 table.insert(parts, 0) -- unknown
|
yellowfive@57
|
152 table.insert(parts, itemObj.upgradeId)
|
yellowfive@57
|
153 table.insert(parts, 0)
|
yellowfive@57
|
154
|
yellowfive@57
|
155 if itemObj.bonusIds then
|
yellowfive@57
|
156 table.insert(parts, #itemObj.bonusIds)
|
yellowfive@57
|
157 for i,v in ipairs(itemObj.bonusIds) do
|
yellowfive@57
|
158 table.insert(parts, v)
|
yellowfive@57
|
159 end
|
yellowfive@57
|
160 end
|
yellowfive@57
|
161
|
yellowfive@57
|
162 return table.concat(parts, ":")
|
yellowfive@57
|
163 end
|
yellowfive@57
|
164
|
yellowfive@57
|
165 -- a unique ID useful for determining if a player has an item equipped or not
|
yellowfive@57
|
166 function Amr.GetItemUniqueId(item, noUpgrade)
|
yellowfive@57
|
167 if item == nil then return "" end
|
yellowfive@57
|
168 local ret = item.id .. ""
|
yellowfive@57
|
169 if item.bonusIds then
|
yellowfive@57
|
170 for i = 1, #item.bonusIds do
|
yellowfive@57
|
171 ret = ret .. "b" .. item.bonusIds[i]
|
yellowfive@57
|
172 end
|
yellowfive@57
|
173 end
|
yellowfive@57
|
174 if item.suffixId ~= 0 then
|
yellowfive@57
|
175 ret = ret .. "s" .. item.suffixId
|
yellowfive@57
|
176 end
|
yellowfive@57
|
177 if not noUpgrade and item.upgradeId ~= 0 then
|
yellowfive@57
|
178 ret = ret .. "u" .. item.upgradeId
|
yellowfive@57
|
179 end
|
yellowfive@57
|
180 return ret
|
yellowfive@57
|
181 end
|
yellowfive@57
|
182
|
yellowfive@57
|
183 -- the server event for getting item info does not specify which item it just fetched... have to track manually
|
yellowfive@57
|
184 local _pendingItemIds = {}
|
yellowfive@57
|
185
|
yellowfive@57
|
186 -- helper for getting item information, which is not always guaranteed to be loaded into memory
|
yellowfive@57
|
187 function Amr.GetItemInfo(itemIdOrLinkOrName, callback, customArg)
|
yellowfive@57
|
188 if not itemIdOrLinkOrName then
|
yellowfive@57
|
189 callback(customArg)
|
yellowfive@57
|
190 return
|
yellowfive@57
|
191 end
|
yellowfive@57
|
192
|
yellowfive@57
|
193 -- see if we can get the information immediately
|
yellowfive@57
|
194 local name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture, vendorPrice = GetItemInfo(itemIdOrLinkOrName)
|
yellowfive@57
|
195 if name then
|
yellowfive@57
|
196 callback(customArg, name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture, vendorPrice)
|
yellowfive@57
|
197 return
|
yellowfive@57
|
198 end
|
yellowfive@57
|
199
|
yellowfive@57
|
200 -- get the list of registered callbacks for this particular item
|
yellowfive@57
|
201 local list = _pendingItemIds[itemIdOrLinkOrName]
|
yellowfive@57
|
202 -- if there was a list, then just add the callback to the list
|
yellowfive@57
|
203 if list then
|
yellowfive@57
|
204 table.insert(list, { Callback = callback, Arg = customArg })
|
yellowfive@57
|
205 else
|
yellowfive@57
|
206 -- there wasn't a list, so make a new one with this callback
|
yellowfive@57
|
207 _pendingItemIds[itemIdOrLinkOrName] = { { Callback = callback, Arg = customArg } }
|
yellowfive@57
|
208 end
|
yellowfive@57
|
209 end
|
yellowfive@57
|
210
|
yellowfive@57
|
211 Amr:AddEventHandler("GET_ITEM_INFO_RECEIVED", function()
|
yellowfive@57
|
212 -- go through all unresolved items since we don't know which one was just resolved
|
yellowfive@57
|
213 for itemId, callbacks in pairs(_pendingItemIds) do
|
yellowfive@57
|
214 -- attempt to get the item info again, remove from pending list if we find it
|
yellowfive@57
|
215 local name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture, vendorPrice = GetItemInfo(itemId)
|
yellowfive@57
|
216 if name then
|
yellowfive@57
|
217 _pendingItemIds[itemId] = nil
|
yellowfive@57
|
218
|
yellowfive@57
|
219 -- call each callback
|
yellowfive@57
|
220 for i = 1, #callbacks do
|
yellowfive@57
|
221 callbacks[i].Callback(callbacks[i].Arg, name, link, quality, iLevel, reqLevel, class, subclass, maxStack, equipSlot, texture, vendorPrice)
|
yellowfive@57
|
222 end
|
yellowfive@57
|
223 end
|
yellowfive@57
|
224 end
|
yellowfive@57
|
225 end)
|