vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 
2 -- Add the module to the tree
3 local mod = klhtm
4 local me = {}
5 mod.data = me
6  
7 --[[
8 Data.lua
9  
10 A list of constants, and a few helper methods. Raw properties of threat, talents, sets.
11  
12 ]]--
13  
14  
15 --[[
16 Special onload() method called by Core.
17 ]]
18 me.onload = function()
19  
20 me.infermissingspellranks()
21  
22 end
23  
24 --[[
25 me.infermissingspellranks()
26 For some abilities, we don't know the threat values for all ranks. For a missing rank, we just assume the threat
27 value is <maxrank threat> * <rank> / <max rank>, where <maxrank> is the highest rank for which values are known,
28 and <rank> is the currently unknown rank.
29 ]]
30 me.infermissingspellranks = function()
31  
32 local dataset, maxlevel, x, newvalues, maxlevelset
33  
34 for _, dataset in me.spells do
35  
36 -- only do this for class abilities without multipliers
37 if (dataset.class ~= "item") and (dataset.multiplier == nil) then
38  
39 -- find the maximum rank that is known
40 for x = 20, 1, -1 do
41 maxlevel = x
42 if dataset[tostring(x)] ~= nil then
43 break
44 end
45 end
46  
47 -- look for missing ranks below the maximum
48 maxlevelset = dataset[tostring(maxlevel)]
49 for x = 1, maxlevel -1 do
50  
51 if dataset[tostring(x)] == nil then
52 newvalues = { }
53 newvalues.threat = math.floor(maxlevelset.threat * x / maxlevel)
54  
55 -- add nextattack if it exists
56 if maxlevelset.nextattack then
57 newvalues.nextattack = math.floor(maxlevelset.nextattack * x / maxlevel)
58 end
59  
60 dataset[tostring(x)] = newvalues
61 end
62 end
63 end
64 end
65 end
66  
67 --[[
68 This is basically a list of all known abilities that do threat stuff.
69 The key of each item in the list, e.g. "heroicstrike", matches the localisation key. The localised name of the spell
70 is mod.string.get("spell", <key>), e.g. mod.string.get("spell", "heroicstrike").
71 Each spell has a <class> property, whose value is lower case, locale independent. Also it has the value "item" for
72 spells from weapons such as thunderfury or black amnesty.
73 <rage> is an optional parameter for warriors and druids, and assumed to be constant.
74 <multiplier> says that each point of damage from the spell causes x threat, where x is the value of multipler. When this
75 property is present, any <threat> value are ignored. i.e. it is assumed that a spell either multiplies the damage to get
76 threat, or adds a fixed amount, and not both.
77 For abilities with multiple ranks, add a key-value pair, where the key is the rank represented as a STRING, and the value
78 is a table with the properties of that rank. So in the table you might have a <threat> property, and a <nextattack> property.
79 ]]
80 me.spells =
81 {
82 -- only ranks 8 (default for 60) and 9 (AQ book) are known
83 ["heroicstrike"] =
84 {
85 class = "warrior",
86 rage = 15,
87 ["8"] =
88 {
89 threat = 145,
90 nextattack = 138,
91 },
92 ["9"] =
93 {
94 ["threat"] = 173,
95 ["nextattack"] = 157,
96 }
97 },
98 ["maul"] =
99 {
100 class = "druid",
101 rage = 15,
102 multiplier = 1.75,
103 ["7"] = { nextattack = 128 },
104 ["6"] = { nextattack = 101 },
105 ["5"] = { nextattack = 71 },
106 ["4"] = { nextattack = 49 },
107 ["3"] = { nextattack = 37 },
108 ["2"] = { nextattack = 27 },
109 ["1"] = { nextattack = 18 },
110 },
111 ["swipe"] =
112 {
113 class = "druid",
114 rage = 20,
115 multiplier = 1.75,
116 },
117 ["shieldslam"] =
118 {
119 class = "warrior",
120 rage = 20,
121 ["4"] = { threat = 250 }
122 },
123 ["revenge"] =
124 {
125 class = "warrior",
126 rage = 5,
127 ["5"] = { threat = 315 },
128 ["6"] = { threat = 355 },
129 },
130 ["shieldbash"] =
131 {
132 class = "warrior",
133 rage = 10,
134 ["3"] = { threat = 180 },
135 },
136 ["sunder"] =
137 {
138 class = "warrior",
139 rage = 15,
140 ["5"] = { threat = 260 },
141 },
142 ["cleave"] =
143 {
144 class = "warrior",
145 rage = 20,
146 ["5"] = { threat = 100 },
147 },
148 ["feint"] =
149 {
150 class = "rogue",
151 ["5"] = { threat = -800 },
152 ["4"] = { threat = -600 },
153 ["3"] = { threat = -390 },
154 ["2"] = { threat = -240 },
155 ["1"] = { threat = -150 },
156 },
157 ["cower"] =
158 {
159 class = "druid",
160 rage = 0,
161 ["3"] = { threat = -600 },
162 ["2"] = { threat = -390 },
163 ["1"] = { threat = -240 },
164 },
165 ["searingpain"] =
166 {
167 class = "warlock",
168 multiplier = 2.0,
169 },
170 ["earthshock"] =
171 {
172 class = "shaman",
173 multiplier = 2.0,
174 },
175 ["mindblast"] =
176 {
177 class = "priest",
178 multiplier = 2.0,
179 },
180 ["holyshield"] =
181 {
182 class = "paladin",
183 multiplier = 1.2,
184 },
185 ["distractingshot"] =
186 {
187 class = "hunter",
188 ["1"] = { threat = 110 },
189 ["2"] = { threat = 160 },
190 ["3"] = { threat = 250 },
191 ["4"] = { threat = 350 },
192 ["5"] = { threat = 465 },
193 ["6"] = { threat = 600 },
194 },
195 ["fade"] =
196 {
197 class = "priest",
198 ["1"] = { threat = 55 },
199 ["2"] = { threat = 155 },
200 ["3"] = { threat = 285 },
201 ["4"] = { threat = 440 },
202 ["5"] = { threat = 620 },
203 ["6"] = { threat = 820 },
204 },
205 ["thunderfury"] =
206 {
207 class = "item",
208 threat = 241,
209 },
210 ["graceofearth"] =
211 {
212 class = "item",
213 threat = -650,
214 },
215 ["blackamnesty"] =
216 {
217 class = "item",
218 threat = -540,
219 },
220 ["whitedamage"] =
221 {
222 class = "item",
223 threat = 0,
224 },
225 }
226  
227 -- These are the DPS modifiers for ranks of rockbiter. Whenever a hit lands with a rockbiter weapon, the added threat
228 -- equals the speed of the weapon times the rockbiter value, e.g. 72 dps for max rank.
229 me.rockbiter =
230 {
231 [1] = 6, -- 1
232 [2] = 10, -- 8
233 [3] = 16, -- 16
234 [4] = 27, -- 24
235 [5] = 41, -- 34
236 [6] = 55, -- 44
237 [7] = 72, -- 54
238 }
239  
240 -- A bunch of firm constants.
241 me.threatconstants =
242 {
243 ["healing"] = 0.5,
244 ["meleeaggrogain"] = 1.1,
245 ["rangeaggrogain"] = 1.3,
246 ["ragegain"] = 5.0,
247 ["energygain"] = 5.0,
248 ["managain"] = 0.5,
249 }
250  
251 --[[
252 mod.data.isbuffpresent(texture)
253 Looks in your buff list for an icon matching the supplied texture.
254 <texture> is the path of the texture, e.g. "Interface\\Icons\\Ability_Warrior_Sunder"
255 Returns: true if the buff is present, false otherwise
256 ]]
257 me.isbuffpresent = function(texture)
258  
259 local x
260 local bufftexture
261  
262 for x = 1, 16 do
263 bufftexture = UnitBuff("player", x)
264  
265 if bufftexture == nil then
266 break
267  
268 elseif bufftexture == texture then
269 return true
270 end
271 end
272  
273 return false
274 end
275  
276 --------------------------------------------------------------------------
277  
278 ------------------------------
279 -- Spell Sets --
280 ------------------------------
281  
282 --[[
283 Certain items and abilities only affect particular schools of spells. For these specific sets, we keep
284 a list of all the possible spells, and provide a method to query a spell as from a school.
285 ]]
286 me.spellsets =
287 {
288 ["Warlock Destruction"] =
289 { "shadowbolt", "immolate", "conflagrate", "searingpain", "rainoffire", "soulfire", "shadowburn", "hellfire" },
290 }
291  
292 --[[
293 mod.data.spellmatchesset(setname, spellname)
294 Returns: true if the spell is in the set, false otherwise.
295 <setname> is a key to me.spellsets above, e.g. "Priest Shadow Spells".
296 <spellname> is the name of a spell. It is localised.
297 ]]
298 me.spellmatchesset = function(setname, spellid)
299  
300 local x = 0
301 local spellset = me.spellsets[setname]
302 local spell
303  
304 while true do
305 x = x + 1
306 spell = spellset[x]
307  
308 if spell == nil then
309 return false
310  
311 elseif spell == spellid then
312 return true
313 end
314 end
315  
316 end
317  
318  
319 --------------------------------------------------------------------------
320  
321 ------------------------------
322 -- Talent Points --
323 ------------------------------
324  
325 -- Values are {Page, Talent, Class}
326 me.talentinfo =
327 {
328 sunder = {3, 10, "warrior"},
329 heroicstrike = {1, 1, "warrior"},
330 defiance = {3, 9, "warrior"},
331 impale = {1, 11, "warrior"},
332 silentresolve = {1, 3, "priest"},
333 shadowaffinity = {3, 3, "priest"},
334 druidsubtlety = {3, 8, "druid"},
335 feralinstinct = {2, 3, "druid"},
336 ferocity = {2, 1, "druid"},
337 tranquility = {3, 13, "druid"},
338 savagefury = {2, 13,"druid"},
339 masterdemonologist = {2, 15, "warlock"},
340 arcanesubtlety = {1, 1, "mage"},
341 frostchanneling = {3, 12, "mage"},
342 burningsoul = {2, 9, "mage"},
343 righteousfury = {2, 7, "paladin"},
344 healinggrace = {3, 9, "shaman"},
345 }
346  
347 --[[
348 me.gettalentrank(talent)
349 Returns: how many points you have invested in the specified talent.
350 <talent> is a value from the me.talentinfo array.
351 ]]
352 me.gettalentrank = function(talent)
353  
354 local info = me.talentinfo[talent]
355 local rank
356 _, _, _, _, rank = GetTalentInfo(info[1], info[2])
357  
358 return rank
359 end
360  
361 -- This is a pretty simple function to print out the talents you havee that the mod is checking for
362 me.testtalents = function()
363  
364 local key, value, rank
365 local numtalents = 0
366  
367 for key, value in me.talentinfo do
368  
369 if value[3] == mod.my.class then
370 rank = me.gettalentrank(key)
371 numtalents = numtalents + 1
372  
373 mod.out.print(string.format(mod.string.get("print", "data", "talentpoint"), rank, mod.string.get("talent", key)))
374 end
375 end
376  
377 mod.out.print(string.format(mod.string.get("print", "data", "talent"), numtalents, UnitClass("player")))
378 end
379  
380  
381 --------------------------------------------------------------------------
382  
383 -------------------------------------------
384 -- Checking for Set Pieces --
385 -------------------------------------------
386  
387 -- This will print a list of all the (significant) set pieces you are wearing.
388 me.testitemsets = function()
389  
390 local setname
391 local output
392 local pieces
393  
394 for setname in me.itemsets do
395 output = mod.string.get("sets", setname) .. ": {"
396 _, pieces = me.getsetpieces(setname, "non-nil")
397 output = output .. pieces .. "}"
398 mod.out.print(output)
399 end
400  
401 end
402  
403 -- the key is the description, the value is the item slot index, for GetInventoryItemLink
404 me.itemslots =
405 {
406 head = 1,
407 legs = 7,
408 shoulder = 3,
409 feet = 8,
410 waist = 6,
411 wrist = 9,
412 chest = 5,
413 hands = 10,
414 }
415  
416 -- values are item numbers. The numbers will be contained in an item link string.
417 me.itemsets =
418 {
419 might =
420 {
421 head = "16866",
422 legs = "16867",
423 shoulder = "16868",
424 feet = "16862",
425 waist = "16864",
426 wrist = "16861",
427 chest = "16865",
428 hands = "16863",
429 },
430 bloodfang =
431 {
432 head = "16908",
433 legs = "16909",
434 shoulder = "16832",
435 feet = "16906",
436 waist = "16910",
437 wrist = "16911",
438 chest = "16905",
439 hands = "16907",
440 },
441 arcanist =
442 {
443 head = "16795",
444 legs = "16796",
445 shoulder = "16797",
446 feet = "16800",
447 waist = "16802",
448 wrist = "16799",
449 chest = "16798",
450 hands = "16801",
451 },
452 netherwind =
453 {
454 head = "16914",
455 legs = "16915",
456 shoulder = "16917",
457 feet = "16912",
458 waist = "16818",
459 wrist = "16918",
460 chest = "16916",
461 hands = "16913",
462 },
463 nemesis =
464 {
465 head = "16929",
466 legs = "16930",
467 shoulder = "16932",
468 feet = "16927",
469 waist = "16933",
470 wrist = "16934",
471 chest = "16931",
472 hands = "16928",
473 },
474 }
475  
476 --[[
477 mod.data.getsetpieces(setname, isdebug)
478 Returns: the number of set pieces the player is currently wearing.
479 <setname> is the localised name of the set.
480 if <isdebug> is non-nil, the method will also generate and return as the second value a printout.
481 ]]
482 me.getsetpieces = function(setname, isdebug)
483  
484 -- 1) Get the set list
485 local setlist = me.itemsets[setname]
486  
487 if setlist == nil then
488 me.out.printtrace("assertion", string.format("The set |cffffff00%s|r does not exist in our database.", setname))
489 return 0
490 end
491  
492 local slotname
493 local slotnumber
494 local debugout = ""
495 local itemlink
496 local numitems = 0
497  
498 for slotname, slotnumber in me.itemslots do
499 itemlink = GetInventoryItemLink("player", slotnumber)
500  
501 if itemlink and string.find(itemlink, setlist[slotname]) then
502 numitems = numitems + 1
503  
504 -- if it's for debug, print out which piece it is
505 if isdebug then
506 if numitems > 1 then
507 debugout = debugout .. ", "
508 end
509  
510 debugout = debugout .. slotname
511 end
512 end
513 end
514  
515 return numitems, debugout
516  
517 end