PageRenderTime 57ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/WoWPro/WoWPro_Trade.lua

http://github.com/Jiyambi/WoW-Pro-Guides
Lua | 412 lines | 326 code | 45 blank | 41 comment | 33 complexity | c892ea93648bde074d59d4ce01283dd1 MD5 | raw file
  1. -- luacheck: globals pairs ipairs tonumber
  2. --------------------------------------
  3. -- WoWPro_Profession_Trade --
  4. --------------------------------------
  5. -- list of all available professions and their skillLine ID
  6. WoWPro.ProfessionSkillLines = {
  7. [164] = { name = 'Blacksmithing' },
  8. [2437] = { exp = 7, parent = 164, name = 'Battle for Azeroth Blacksmithing' },
  9. [2454] = { exp = 6, parent = 164, name = 'Legion Blacksmithing' },
  10. [2472] = { exp = 5, parent = 164, name = 'Draenor Blacksmithing' },
  11. [2473] = { exp = 4, parent = 164, name = 'Pandaria Blacksmithing' },
  12. [2474] = { exp = 3, parent = 164, name = 'Cataclysm Blacksmithing' },
  13. [2475] = { exp = 2, parent = 164, name = 'Northrend Blacksmithing' },
  14. [2476] = { exp = 1, parent = 164, name = 'Outland Blacksmithing' },
  15. [2477] = { exp = 0, parent = 164, name = 'Blacksmithing' },
  16. [165] = { name = 'Leatherworking' },
  17. [2525] = { exp = 7, parent = 165, name = 'Battle for Azeroth Leatherworking' },
  18. [2526] = { exp = 6, parent = 165, name = 'Legion Leatherworking' },
  19. [2527] = { exp = 5, parent = 165, name = 'Draenor Leatherworking' },
  20. [2528] = { exp = 4, parent = 165, name = 'Pandaria Leatherworking' },
  21. [2529] = { exp = 3, parent = 165, name = 'Cataclysm Leatherworking' },
  22. [2530] = { exp = 2, parent = 165, name = 'Northrend Leatherworking' },
  23. [2531] = { exp = 1, parent = 165, name = 'Outland Leatherworking' },
  24. [2532] = { exp = 0, parent = 165, name = 'Leatherworking' },
  25. [171] = { name = 'Alchemy' },
  26. [2478] = { exp = 7, parent = 171, name = 'Battle for Azeroth Alchemy' },
  27. [2479] = { exp = 6, parent = 171, name = 'Legion Alchemy' },
  28. [2480] = { exp = 5, parent = 171, name = 'Draenor Alchemy' },
  29. [2481] = { exp = 4, parent = 171, name = 'Pandaria Alchemy' },
  30. [2482] = { exp = 3, parent = 171, name = 'Cataclysm Alchemy' },
  31. [2483] = { exp = 2, parent = 171, name = 'Northrend Alchemy' },
  32. [2484] = { exp = 1, parent = 171, name = 'Outland Alchemy' },
  33. [2485] = { exp = 0, parent = 171, name = 'Alchemy' },
  34. [182] = { name = 'Herbalism' },
  35. [2549] = { exp = 7, parent = 182, name = 'Battle for Azeroth Herbalism' },
  36. [2550] = { exp = 6, parent = 182, name = 'Legion Herbalism' },
  37. [2551] = { exp = 5, parent = 182, name = 'Draenor Herbalism' },
  38. [2552] = { exp = 4, parent = 182, name = 'Pandaria Herbalism' },
  39. [2553] = { exp = 3, parent = 182, name = 'Cataclysm Herbalism' },
  40. [2554] = { exp = 2, parent = 182, name = 'Northrend Herbalism' },
  41. [2555] = { exp = 1, parent = 182, name = 'Outland Herbalism' },
  42. [2556] = { exp = 0, parent = 182, name = 'Herbalism' },
  43. -- Cooking is not included in GetTradeSkillLineInfoByID()
  44. [185] = { name = 'Cooking' },
  45. [2541] = { exp = 7, parent = 185, name = 'Battle for Azeroth Cooking' },
  46. [2542] = { exp = 6, parent = 185, name = 'Legion Cooking' },
  47. [2543] = { exp = 5, parent = 185, name = 'Draenor Cooking' },
  48. [2544] = { exp = 4, parent = 185, name = 'Pandaria Cooking' },
  49. -- Cooking Pandaria Specializations
  50. [975] = { exp = 4, parent = 185, name = 'Way of the Grill' },
  51. [976] = { exp = 4, parent = 185, name = 'Way of the Wok' },
  52. [977] = { exp = 4, parent = 185, name = 'Way of the Pot' },
  53. [978] = { exp = 4, parent = 185, name = 'Way of the Steamer' },
  54. [979] = { exp = 4, parent = 185, name = 'Way of the Oven' },
  55. [980] = { exp = 4, parent = 185, name = 'Way of the Brew' },
  56. [2545] = { exp = 3, parent = 185, name = 'Cataclysm Cooking' },
  57. [2546] = { exp = 2, parent = 185, name = 'Northrend Cooking' },
  58. [2547] = { exp = 1, parent = 185, name = 'Outland Cooking' },
  59. [2548] = { exp = 0, parent = 185, name = 'Cooking' },
  60. [186] = { name = 'Mining' },
  61. [2565] = { exp = 7, parent = 186, name = 'Battle for Azeroth Mining' },
  62. [2566] = { exp = 6, parent = 186, name = 'Legion Mining' },
  63. [2567] = { exp = 5, parent = 186, name = 'Draenor Mining' },
  64. [2568] = { exp = 4, parent = 186, name = 'Pandaria Mining' },
  65. [2569] = { exp = 3, parent = 186, name = 'Cataclysm Mining' },
  66. [2570] = { exp = 2, parent = 186, name = 'Northrend Mining' },
  67. [2571] = { exp = 1, parent = 186, name = 'Outland Mining' },
  68. [2572] = { exp = 0, parent = 186, name = 'Mining' },
  69. [197] = { name = 'Tailoring' },
  70. [2533] = { exp = 7, parent = 197, name = 'Battle for Azeroth Tailoring' },
  71. [2534] = { exp = 6, parent = 197, name = 'Legion Tailoring' },
  72. [2535] = { exp = 5, parent = 197, name = 'Draenor Tailoring' },
  73. [2536] = { exp = 4, parent = 197, name = 'Pandaria Tailoring' },
  74. [2537] = { exp = 3, parent = 197, name = 'Cataclysm Tailoring' },
  75. [2538] = { exp = 2, parent = 197, name = 'Northrend Tailoring' },
  76. [2539] = { exp = 1, parent = 197, name = 'Outland Tailoring' },
  77. [2540] = { exp = 0, parent = 197, name = 'Tailoring' },
  78. [202] = { name = 'Engineering' },
  79. [2499] = { exp = 7, parent = 202, name = 'Battle for Azeroth Engineering' },
  80. [2500] = { exp = 6, parent = 202, name = 'Legion Engineering' },
  81. [2501] = { exp = 5, parent = 202, name = 'Draenor Engineering' },
  82. [2502] = { exp = 4, parent = 202, name = 'Pandaria Engineering' },
  83. [2503] = { exp = 3, parent = 202, name = 'Cataclysm Engineering' },
  84. [2504] = { exp = 2, parent = 202, name = 'Northrend Engineering' },
  85. [2505] = { exp = 1, parent = 202, name = 'Outland Engineering' },
  86. [2506] = { exp = 0, parent = 202, name = 'Engineering' },
  87. [333] = { name = 'Enchanting' },
  88. [2486] = { exp = 7, parent = 333, name = 'Battle for Azeroth Enchanting' },
  89. [2487] = { exp = 6, parent = 333, name = 'Legion Enchanting' },
  90. [2488] = { exp = 5, parent = 333, name = 'Draenor Enchanting' },
  91. [2489] = { exp = 4, parent = 333, name = 'Pandaria Enchanting' },
  92. [2491] = { exp = 3, parent = 333, name = 'Cataclysm Enchanting' },
  93. [2492] = { exp = 2, parent = 333, name = 'Northrend Enchanting' },
  94. [2493] = { exp = 1, parent = 333, name = 'Outland Enchanting' },
  95. [2494] = { exp = 0, parent = 333, name = 'Enchanting' },
  96. -- Fishing is not included in GetTradeSkillLineInfoByID()
  97. [356] = { name = 'Fishing' },
  98. [2585] = { exp = 8, parent = 356, name = 'Battle for Azeroth Fishing' },
  99. [2586] = { exp = 7, parent = 356, name = 'Legion Fishing' },
  100. [2587] = { exp = 5, parent = 356, name = 'Draenor Fishing' },
  101. [2588] = { exp = 4, parent = 356, name = 'Pandaria Fishing' },
  102. [2589] = { exp = 3, parent = 356, name = 'Cataclysm Fishing' },
  103. [2590] = { exp = 2, parent = 356, name = 'Northrend Fishing' },
  104. [2591] = { exp = 1, parent = 356, name = 'Outland Fishing' },
  105. [2592] = { exp = 0, parent = 356, name = 'Fishing' },
  106. [393] = { name = 'Skinning' },
  107. [2557] = { exp = 7, parent = 393, name = 'Battle for Azeroth Skinning' },
  108. [2558] = { exp = 6, parent = 393, name = 'Legion Skinning' },
  109. [2559] = { exp = 5, parent = 393, name = 'Draenor Skinning' },
  110. [2560] = { exp = 4, parent = 393, name = 'Pandaria Skinning' },
  111. [2561] = { exp = 3, parent = 393, name = 'Cataclysm Skinning' },
  112. [2562] = { exp = 2, parent = 393, name = 'Northrend Skinning' },
  113. [2563] = { exp = 1, parent = 393, name = 'Outland Sknning' },
  114. [2564] = { exp = 0, parent = 393, name = 'Skinning' },
  115. [755] = { name = 'Jewelcrafting' },
  116. [2517] = { exp = 7, parent = 755, name = 'Battle for Azeroth Jewelcrafting' },
  117. [2518] = { exp = 6, parent = 755, name = 'Legion Jewelcrafting' },
  118. [2519] = { exp = 5, parent = 755, name = 'Draenor Jewelcrafting' },
  119. [2520] = { exp = 4, parent = 755, name = 'Pandaria Jewelcrafting' },
  120. [2521] = { exp = 3, parent = 755, name = 'Cataclysm Jewelcrafting' },
  121. [2522] = { exp = 2, parent = 755, name = 'Northrend Jewelcrafting' },
  122. [2523] = { exp = 1, parent = 755, name = 'Outland Jewelcrafting' },
  123. [2524] = { exp = 0, parent = 755, name = 'Jewelcrafting' },
  124. [773] = { name = 'Inscription' },
  125. [2507] = { exp = 7, name = 'Battle for Azeroth Inscription' },
  126. [2508] = { exp = 6, name = 'Legion Inscription' },
  127. [2509] = { exp = 5, name = 'Draenor Inscription' },
  128. [2510] = { exp = 4, name = 'Pandaria Inscription' },
  129. [2511] = { exp = 3, name = 'Cataclysm Inscription' },
  130. [2512] = { exp = 2, name = 'Northrend Inscription' },
  131. [2513] = { exp = 1, name = 'Outland Inscription' },
  132. [2514] = { exp = 0, name = 'Inscription' },
  133. -- Not included in GetTradeSkillLineInfoByID()
  134. [794] = { name = 'Archaeology' },
  135. [960] = { name = 'Runeforging' },
  136. [2720] = { name = 'Junkyard Tinkering'}
  137. }
  138. -- mapping of profession categories to tradeskill lines we are interested in
  139. WoWPro.ProfessionCategories = {
  140. -- Cooking Pandaria Specializations
  141. [64] = 975, -- Way of the Grill
  142. [65] = 976, -- Way of the Wok
  143. [66] = 977, -- Way of the Pot
  144. [67] = 978, -- Way of the Steamer
  145. [68] = 979, -- Way of the Oven
  146. [69] = 980, -- Way of the Brew
  147. -- Cooking
  148. [1016] = 2548, -- Classic
  149. [1017] = 2547, -- Outland
  150. [1018] = 2548, -- Northrend
  151. [1019] = 2545, -- Cataclysm
  152. [1015] = 2544, -- Pandaria
  153. [1013] = 2543, -- Draenor
  154. [1014] = 2542, -- Legion
  155. [1117] = 2541, -- Battle for Azeroth
  156. -- Fishing
  157. [1099] = 2592, -- Classic
  158. [1101] = 2591, -- Outland
  159. [1103] = 2590, -- Northrend
  160. [1105] = 2589, -- Cataclysm
  161. [1107] = 2588, -- Pandaria
  162. [1109] = 2587, -- Draenor
  163. [1111] = 2586, -- Legion
  164. [1113] = 2585 -- Battle for Azeroth
  165. }
  166. -- special handling for Classic because of the reduced addon API
  167. if WoWPro.CLASSIC then
  168. -- list of all available professions and SpellIDs with their names
  169. WoWPro.ProfessionSpellIDs = {
  170. ['Alchemy'] = 2259,
  171. ['Archaeology'] = 78670,
  172. ['Blacksmithing'] = 2018,
  173. ['Cooking'] = 2550,
  174. ['Enchanting'] = 7411,
  175. ['Engineering'] = 4036,
  176. ['First Aid'] = 3273,
  177. ['Fishing'] = 7620,
  178. ['Herbalism'] = 9134,
  179. ['Inscription'] = 45357,
  180. ['Jewelcrafting'] = 25229,
  181. ['Leatherworking'] = 2108,
  182. ['Mining'] = 2575,
  183. ['Skinning'] = 8613,
  184. ['Tailoring'] = 3908,
  185. ['Lockpicking'] = 1809
  186. }
  187. -- generate a list of localized profession names via GetSpellInfo()
  188. WoWPro.ProfessionLocalNames = {}
  189. for profName, spellID in pairs(WoWPro.ProfessionSpellIDs) do
  190. local localName = _G.GetSpellInfo(spellID)
  191. if localName ~= nil then
  192. WoWPro.ProfessionLocalNames[localName] = profName
  193. end
  194. end
  195. -- generate a lookup table for profession names to profession skill lines
  196. WoWPro.ProfessionNameToSkillLine = {}
  197. for profID, profession in pairs(WoWPro.ProfessionSkillLines) do
  198. if not profession.exp then
  199. WoWPro.ProfessionNameToSkillLine[profession.name] = profID
  200. end
  201. end
  202. -- get tradeskill information from skill lines
  203. function WoWPro.UpdateTradeSkills()
  204. local scanned = 0
  205. local tradeskills = {}
  206. for idx = 1, _G.GetNumSkillLines() do
  207. local localName, header, _, skillLevel, _, skillModifier, skillMaxRank = _G.GetSkillLineInfo(idx)
  208. local skillName = WoWPro.ProfessionLocalNames[localName]
  209. local profID = WoWPro.ProfessionNameToSkillLine[skillName]
  210. if not header and profID and skillName then
  211. tradeskills[profID] = {
  212. name = skillName,
  213. skillLvl = skillLevel,
  214. skillMod = skillModifier,
  215. skillMax = skillMaxRank
  216. }
  217. scanned = scanned + 1
  218. end
  219. end
  220. WoWPro.UpdateTradeSkillsTable(tradeskills)
  221. WoWPro:dbp("UpdateTradeSkills() for Classic scanned %d tradeskills", scanned)
  222. end
  223. else
  224. -- get tradeskill information from GetProfession/GetProfessionInfo
  225. function WoWPro.UpdateTradeSkills()
  226. local scanned = 0
  227. local tradeskills = {}
  228. -- first scan all profession tradeskill lines that are learned
  229. for _, skillLineID in ipairs(_G.C_TradeSkillUI.GetAllProfessionTradeSkillLines()) do
  230. local _, skillLineRank, skillLineMaxRank, skillLineModifier = _G.C_TradeSkillUI.GetTradeSkillLineInfoByID(skillLineID)
  231. if skillLineRank > 0 and WoWPro.ProfessionSkillLines[skillLineID] then
  232. tradeskills[skillLineID] = {
  233. name = WoWPro.ProfessionSkillLines[skillLineID].name,
  234. skillLvl = skillLineRank,
  235. skillMax = skillLineMaxRank,
  236. skillMod = skillLineModifier
  237. }
  238. scanned = scanned + 1
  239. end
  240. end
  241. -- scan with GetProfessions()
  242. for _, profID in ipairs({_G.GetProfessions()}) do
  243. local name, _, skillLineRank, skillLineMaxRank, _, _, skillLineID, skillLineModifier, _, _, subName = _G.GetProfessionInfo(profID)
  244. -- skillLineID is always the parent ID, so once you learn an expansion
  245. -- GetProfessionInfo() is no longer useful except for Archaeology
  246. if WoWPro.ProfessionSkillLines[skillLineID] and (not subName or name == subName) then
  247. tradeskills[skillLineID] = {
  248. name = WoWPro.ProfessionSkillLines[skillLineID].name,
  249. skillLvl = skillLineRank,
  250. skillMax = skillLineMaxRank,
  251. skillMod = skillLineModifier
  252. }
  253. scanned = scanned + 1
  254. end
  255. end
  256. WoWPro.UpdateTradeSkillsTable(tradeskills)
  257. WoWPro:dbp("UpdateTradeSkills() scanned %d tradeskills", scanned)
  258. end
  259. end
  260. -- update WoWProCharDB.Tradeskill map so we don't forget detailed ScanTrade() info
  261. function WoWPro.UpdateTradeSkillsTable(tradeskills)
  262. if not WoWProCharDB.Tradeskills then
  263. WoWProCharDB.Tradeskills = tradeskills
  264. return
  265. end
  266. -- remove unlearned/unavailable professions, except for cooking or fishing
  267. for trade in pairs(WoWProCharDB.Tradeskills) do
  268. local skillLine = WoWPro.ProfessionSkillLines[trade]
  269. if not skillLine then
  270. WoWProCharDB.Tradeskills[trade] = nil
  271. elseif tradeskills[trade] == nil and trade ~= 185 and skillLine.parent ~= 185 and trade ~= 356 and skillLine.parent ~= 356 then
  272. WoWProCharDB.Tradeskills[trade] = nil
  273. end
  274. end
  275. -- add/update learned professions
  276. for trade, info in pairs(tradeskills) do
  277. WoWProCharDB.Tradeskills[trade] = info
  278. end
  279. end
  280. -- special handling for Classic because of the reduced addon API
  281. if WoWPro.CLASSIC then
  282. -- scan Tradeskill information and recipes on Classic
  283. function WoWPro.ScanTrade()
  284. WoWPro:dbp("ScanTrade() for Classic")
  285. -- FIXME: find a way to scan recipes without C_TradeSkillUI and
  286. -- GetSpellInfo("name", "") doesn't return information for tradeskills
  287. -- GetTradeSkillItemLink() returns the resulting item, not the spellID
  288. -- skillName, skillType, numAvailable = GetTradeSkillInfo(index)
  289. end
  290. else
  291. -- scan Tradeskill information and recipes on Live
  292. function WoWPro.ScanTrade()
  293. -- read tradeskill information from GetTradeSkillLine()
  294. local skillLineID, skillLineName, skillLineRank, skillLineMaxRank, skillLineModifier = _G.C_TradeSkillUI.GetTradeSkillLine();
  295. if not skillLineID then
  296. return
  297. end
  298. -- don't scan other players tradeskills
  299. if _G.C_TradeSkillUI.IsTradeSkillLinked() then
  300. return
  301. end
  302. WoWPro:dbp("ScanTrade() opened %s/%d window", skillLineName, skillLineID)
  303. -- update tradeskill information directly
  304. local tradeInfo = WoWProCharDB.Tradeskills[skillLineID] or {}
  305. tradeInfo.name = WoWPro.ProfessionSkillLines[skillLineID].name
  306. tradeInfo.skillLvl = skillLineRank
  307. tradeInfo.skillMax = skillLineMaxRank
  308. tradeInfo.skillMod = skillLineModifier
  309. WoWProCharDB.Tradeskills[skillLineID] = tradeInfo
  310. -- scan catgegories
  311. local catInfo = {}
  312. for _, catID in ipairs({_G.C_TradeSkillUI.GetCategories()}) do
  313. -- only scan category IDs we are interested in
  314. skillLineID = WoWPro.ProfessionSkillLines[catID]
  315. if skillLineID then
  316. _G.C_TradeSkillUI.GetCategoryInfo(catID, catInfo)
  317. if catInfo.hasProgressBar and catInfo.skillLineCurrentLevel and catInfo.skillLineMaxLevel then
  318. tradeInfo = WoWProCharDB.Tradeskills[skillLineID] or {}
  319. tradeInfo.name = WoWPro.ProfessionSkillLines[skillLineID].name
  320. tradeInfo.skillLvl = skillLineRank
  321. tradeInfo.skillMax = skillLineMaxRank
  322. tradeInfo.skillMod = skillLineModifier
  323. WoWProCharDB.Tradeskills[skillLineID] = tradeInfo
  324. end
  325. end
  326. end
  327. -- scan all recipes available and store them
  328. WoWProCharDB.Trades = WoWProCharDB.Trades or {}
  329. local Trades = WoWProCharDB.Trades
  330. local recipes = 0
  331. local learned = 0
  332. local recipeInfo = {}
  333. for _, recipeID in pairs(_G.C_TradeSkillUI.GetAllRecipeIDs()) do
  334. _G.C_TradeSkillUI.GetRecipeInfo(recipeID, recipeInfo)
  335. if recipeInfo.type == 'recipe' and recipeInfo.learned then
  336. local link = _G.C_TradeSkillUI.GetRecipeLink(recipeID)
  337. local _, _, spellId = link:find("^|%x+|Henchant:(.+)|h%[.+%]")
  338. spellId = tonumber(spellId)
  339. if not spellId then
  340. local safe_link = link:gsub("|", "¦")
  341. WoWPro:Error("Error scanning recipeID %d for [%s]: %s", recipeID, recipeInfo.name, safe_link)
  342. else
  343. if not Trades[spellId] then
  344. Trades[spellId] = true
  345. WoWPro:dbp("Newly learned %s:%d", recipeInfo.name, spellId)
  346. learned = learned + 1
  347. end
  348. recipes = recipes + 1
  349. end
  350. end
  351. end
  352. WoWPro:dbp("ScanTrade() recorded %d known recipes, %d learned", recipes, learned)
  353. end
  354. end
  355. -- learn recipe from NEW_RECIPE_LEARNED event
  356. function WoWPro.LearnRecipe(spellID)
  357. spellID = tonumber(spellID)
  358. if spellID then
  359. if WoWProCharDB.Trades[spellID] then
  360. -- You managed to learn something you already knew?
  361. WoWPro:Warning("Recipe %d was already recorded as learned.", spellID)
  362. else
  363. WoWProCharDB.Trades[spellID] = true
  364. WoWPro:dbp("Newly learned %d", spellID)
  365. end
  366. end
  367. end