vanilla-wow-addons – Rev 1
?pathlinks?

-- Add the module to the tree
local mod = klhtm
local me = {}
mod.data = me
--[[
Data.lua
A list of constants, and a few helper methods. Raw properties of threat, talents, sets.
]]--
--[[
Special onload() method called by Core.
]]
me.onload = function()
me.infermissingspellranks()
end
--[[
me.infermissingspellranks()
For some abilities, we don't know the threat values for all ranks. For a missing rank, we just assume the threat
value is <maxrank threat> * <rank> / <max rank>, where <maxrank> is the highest rank for which values are known,
and <rank> is the currently unknown rank.
]]
me.infermissingspellranks = function()
local dataset, maxlevel, x, newvalues, maxlevelset
for _, dataset in me.spells do
-- only do this for class abilities without multipliers
if (dataset.class ~= "item") and (dataset.multiplier == nil) then
-- find the maximum rank that is known
for x = 20, 1, -1 do
maxlevel = x
if dataset[tostring(x)] ~= nil then
break
end
end
-- look for missing ranks below the maximum
maxlevelset = dataset[tostring(maxlevel)]
for x = 1, maxlevel -1 do
if dataset[tostring(x)] == nil then
newvalues = { }
newvalues.threat = math.floor(maxlevelset.threat * x / maxlevel)
-- add nextattack if it exists
if maxlevelset.nextattack then
newvalues.nextattack = math.floor(maxlevelset.nextattack * x / maxlevel)
end
dataset[tostring(x)] = newvalues
end
end
end
end
end
--[[
This is basically a list of all known abilities that do threat stuff.
The key of each item in the list, e.g. "heroicstrike", matches the localisation key. The localised name of the spell
is mod.string.get("spell", <key>), e.g. mod.string.get("spell", "heroicstrike").
Each spell has a <class> property, whose value is lower case, locale independent. Also it has the value "item" for
spells from weapons such as thunderfury or black amnesty.
<rage> is an optional parameter for warriors and druids, and assumed to be constant.
<multiplier> says that each point of damage from the spell causes x threat, where x is the value of multipler. When this
property is present, any <threat> value are ignored. i.e. it is assumed that a spell either multiplies the damage to get
threat, or adds a fixed amount, and not both.
For abilities with multiple ranks, add a key-value pair, where the key is the rank represented as a STRING, and the value
is a table with the properties of that rank. So in the table you might have a <threat> property, and a <nextattack> property.
]]
me.spells =
{
-- only ranks 8 (default for 60) and 9 (AQ book) are known
["heroicstrike"] =
{
class = "warrior",
rage = 15,
["8"] =
{
threat = 145,
nextattack = 138,
},
["9"] =
{
["threat"] = 173,
["nextattack"] = 157,
}
},
["maul"] =
{
class = "druid",
rage = 15,
multiplier = 1.75,
["7"] = { nextattack = 128 },
["6"] = { nextattack = 101 },
["5"] = { nextattack = 71 },
["4"] = { nextattack = 49 },
["3"] = { nextattack = 37 },
["2"] = { nextattack = 27 },
["1"] = { nextattack = 18 },
},
["swipe"] =
{
class = "druid",
rage = 20,
multiplier = 1.75,
},
["shieldslam"] =
{
class = "warrior",
rage = 20,
["4"] = { threat = 250 }
},
["revenge"] =
{
class = "warrior",
rage = 5,
["5"] = { threat = 315 },
["6"] = { threat = 355 },
},
["shieldbash"] =
{
class = "warrior",
rage = 10,
["3"] = { threat = 180 },
},
["sunder"] =
{
class = "warrior",
rage = 15,
["5"] = { threat = 260 },
},
["cleave"] =
{
class = "warrior",
rage = 20,
["5"] = { threat = 100 },
},
["feint"] =
{
class = "rogue",
["5"] = { threat = -800 },
["4"] = { threat = -600 },
["3"] = { threat = -390 },
["2"] = { threat = -240 },
["1"] = { threat = -150 },
},
["cower"] =
{
class = "druid",
rage = 0,
["3"] = { threat = -600 },
["2"] = { threat = -390 },
["1"] = { threat = -240 },
},
["searingpain"] =
{
class = "warlock",
multiplier = 2.0,
},
["earthshock"] =
{
class = "shaman",
multiplier = 2.0,
},
["mindblast"] =
{
class = "priest",
multiplier = 2.0,
},
["holyshield"] =
{
class = "paladin",
multiplier = 1.2,
},
["distractingshot"] =
{
class = "hunter",
["1"] = { threat = 110 },
["2"] = { threat = 160 },
["3"] = { threat = 250 },
["4"] = { threat = 350 },
["5"] = { threat = 465 },
["6"] = { threat = 600 },
},
["fade"] =
{
class = "priest",
["1"] = { threat = 55 },
["2"] = { threat = 155 },
["3"] = { threat = 285 },
["4"] = { threat = 440 },
["5"] = { threat = 620 },
["6"] = { threat = 820 },
},
["thunderfury"] =
{
class = "item",
threat = 241,
},
["graceofearth"] =
{
class = "item",
threat = -650,
},
["blackamnesty"] =
{
class = "item",
threat = -540,
},
["whitedamage"] =
{
class = "item",
threat = 0,
},
}
-- These are the DPS modifiers for ranks of rockbiter. Whenever a hit lands with a rockbiter weapon, the added threat
-- equals the speed of the weapon times the rockbiter value, e.g. 72 dps for max rank.
me.rockbiter =
{
[1] = 6, -- 1
[2] = 10, -- 8
[3] = 16, -- 16
[4] = 27, -- 24
[5] = 41, -- 34
[6] = 55, -- 44
[7] = 72, -- 54
}
-- A bunch of firm constants.
me.threatconstants =
{
["healing"] = 0.5,
["meleeaggrogain"] = 1.1,
["rangeaggrogain"] = 1.3,
["ragegain"] = 5.0,
["energygain"] = 5.0,
["managain"] = 0.5,
}
--[[
mod.data.isbuffpresent(texture)
Looks in your buff list for an icon matching the supplied texture.
<texture> is the path of the texture, e.g. "Interface\\Icons\\Ability_Warrior_Sunder"
Returns: true if the buff is present, false otherwise
]]
me.isbuffpresent = function(texture)
local x
local bufftexture
for x = 1, 16 do
bufftexture = UnitBuff("player", x)
if bufftexture == nil then
break
elseif bufftexture == texture then
return true
end
end
return false
end
--------------------------------------------------------------------------
------------------------------
-- Spell Sets --
------------------------------
--[[
Certain items and abilities only affect particular schools of spells. For these specific sets, we keep
a list of all the possible spells, and provide a method to query a spell as from a school.
]]
me.spellsets =
{
["Warlock Destruction"] =
{ "shadowbolt", "immolate", "conflagrate", "searingpain", "rainoffire", "soulfire", "shadowburn", "hellfire" },
}
--[[
mod.data.spellmatchesset(setname, spellname)
Returns: true if the spell is in the set, false otherwise.
<setname> is a key to me.spellsets above, e.g. "Priest Shadow Spells".
<spellname> is the name of a spell. It is localised.
]]
me.spellmatchesset = function(setname, spellid)
local x = 0
local spellset = me.spellsets[setname]
local spell
while true do
x = x + 1
spell = spellset[x]
if spell == nil then
return false
elseif spell == spellid then
return true
end
end
end
--------------------------------------------------------------------------
------------------------------
-- Talent Points --
------------------------------
-- Values are {Page, Talent, Class}
me.talentinfo =
{
sunder = {3, 10, "warrior"},
heroicstrike = {1, 1, "warrior"},
defiance = {3, 9, "warrior"},
impale = {1, 11, "warrior"},
silentresolve = {1, 3, "priest"},
shadowaffinity = {3, 3, "priest"},
druidsubtlety = {3, 8, "druid"},
feralinstinct = {2, 3, "druid"},
ferocity = {2, 1, "druid"},
tranquility = {3, 13, "druid"},
savagefury = {2, 13,"druid"},
masterdemonologist = {2, 15, "warlock"},
arcanesubtlety = {1, 1, "mage"},
frostchanneling = {3, 12, "mage"},
burningsoul = {2, 9, "mage"},
righteousfury = {2, 7, "paladin"},
healinggrace = {3, 9, "shaman"},
}
--[[
me.gettalentrank(talent)
Returns: how many points you have invested in the specified talent.
<talent> is a value from the me.talentinfo array.
]]
me.gettalentrank = function(talent)
local info = me.talentinfo[talent]
local rank
_, _, _, _, rank = GetTalentInfo(info[1], info[2])
return rank
end
-- This is a pretty simple function to print out the talents you havee that the mod is checking for
me.testtalents = function()
local key, value, rank
local numtalents = 0
for key, value in me.talentinfo do
if value[3] == mod.my.class then
rank = me.gettalentrank(key)
numtalents = numtalents + 1
mod.out.print(string.format(mod.string.get("print", "data", "talentpoint"), rank, mod.string.get("talent", key)))
end
end
mod.out.print(string.format(mod.string.get("print", "data", "talent"), numtalents, UnitClass("player")))
end
--------------------------------------------------------------------------
-------------------------------------------
-- Checking for Set Pieces --
-------------------------------------------
-- This will print a list of all the (significant) set pieces you are wearing.
me.testitemsets = function()
local setname
local output
local pieces
for setname in me.itemsets do
output = mod.string.get("sets", setname) .. ": {"
_, pieces = me.getsetpieces(setname, "non-nil")
output = output .. pieces .. "}"
mod.out.print(output)
end
end
-- the key is the description, the value is the item slot index, for GetInventoryItemLink
me.itemslots =
{
head = 1,
legs = 7,
shoulder = 3,
feet = 8,
waist = 6,
wrist = 9,
chest = 5,
hands = 10,
}
-- values are item numbers. The numbers will be contained in an item link string.
me.itemsets =
{
might =
{
head = "16866",
legs = "16867",
shoulder = "16868",
feet = "16862",
waist = "16864",
wrist = "16861",
chest = "16865",
hands = "16863",
},
bloodfang =
{
head = "16908",
legs = "16909",
shoulder = "16832",
feet = "16906",
waist = "16910",
wrist = "16911",
chest = "16905",
hands = "16907",
},
arcanist =
{
head = "16795",
legs = "16796",
shoulder = "16797",
feet = "16800",
waist = "16802",
wrist = "16799",
chest = "16798",
hands = "16801",
},
netherwind =
{
head = "16914",
legs = "16915",
shoulder = "16917",
feet = "16912",
waist = "16818",
wrist = "16918",
chest = "16916",
hands = "16913",
},
nemesis =
{
head = "16929",
legs = "16930",
shoulder = "16932",
feet = "16927",
waist = "16933",
wrist = "16934",
chest = "16931",
hands = "16928",
},
}
--[[
mod.data.getsetpieces(setname, isdebug)
Returns: the number of set pieces the player is currently wearing.
<setname> is the localised name of the set.
if <isdebug> is non-nil, the method will also generate and return as the second value a printout.
]]
me.getsetpieces = function(setname, isdebug)
-- 1) Get the set list
local setlist = me.itemsets[setname]
if setlist == nil then
me.out.printtrace("assertion", string.format("The set |cffffff00%s|r does not exist in our database.", setname))
return 0
end
local slotname
local slotnumber
local debugout = ""
local itemlink
local numitems = 0
for slotname, slotnumber in me.itemslots do
itemlink = GetInventoryItemLink("player", slotnumber)
if itemlink and string.find(itemlink, setlist[slotname]) then
numitems = numitems + 1
-- if it's for debug, print out which piece it is
if isdebug then
if numitems > 1 then
debugout = debugout .. ", "
end
debugout = debugout .. slotname
end
end
end
return numitems, debugout
end