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