vanilla-wow-addons – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | local _, class = UnitClass("player") |
2 | local returndata = {} |
||
3 | local summeddata = {} |
||
4 | |||
5 | local function findpattern(text, pattern, start) |
||
6 | if (text and pattern and (string.find(text, pattern, start))) then |
||
7 | return string.sub(text, string.find(text, pattern, start)) |
||
8 | else |
||
9 | return "" |
||
10 | end |
||
11 | end |
||
12 | |||
13 | local function round(arg1, decplaces) |
||
14 | if (decplaces == nil) then decplaces = 0 end |
||
15 | if arg1 == nil then arg1 = 0 end |
||
16 | return string.format ("%."..decplaces.."f", arg1) |
||
17 | end |
||
18 | |||
19 | local function TheoryCraft_AddData(arg1, data, summeddata) |
||
20 | if data == nil then return end |
||
21 | summeddata["tmpincrease"] = summeddata["tmpincrease"] + (data[arg1.."modifier"] or 0) |
||
22 | summeddata["tmpincreaseupfront"] = summeddata["tmpincreaseupfront"] + (data[arg1.."UpFrontmodifier"] or 0) |
||
23 | if summeddata["baseincrease"] ~= 0 then |
||
24 | summeddata["baseincrease"] = summeddata["baseincrease"] * ((data[arg1.."baseincrease"] or 0)+1) |
||
25 | else |
||
26 | summeddata["baseincrease"] = summeddata["baseincrease"] + (data[arg1.."baseincrease"] or 0) |
||
27 | end |
||
28 | if summeddata["baseincreaseupfront"] ~= 0 then |
||
29 | summeddata["baseincreaseupfront"] = summeddata["baseincreaseupfront"] * ((data[arg1.."UpFrontbaseincrease"] or 0)+1) |
||
30 | else |
||
31 | summeddata["baseincreaseupfront"] = summeddata["baseincreaseupfront"] + (data[arg1.."UpFrontbaseincrease"] or 0) |
||
32 | end |
||
33 | summeddata["talentmod"] = summeddata["talentmod"] + (data[arg1.."talentmod"] or 0) |
||
34 | summeddata["talentmodupfront"] = summeddata["talentmodupfront"] + (data[arg1.."UpFronttalentmod"] or 0) |
||
35 | if (summeddata["doshatter"] ~= 0) then |
||
36 | summeddata["critchance"] = summeddata["critchance"] + (data[arg1.."shatter"] or 0) |
||
37 | end |
||
38 | summeddata["illum"] = summeddata["illum"] + (data[arg1.."illum"] or 0) |
||
39 | summeddata["plusdam"] = summeddata["plusdam"] + (data[arg1] or 0) |
||
40 | summeddata["manacostmod"] = summeddata["manacostmod"] + (data[arg1.."manacost"] or 0) |
||
41 | summeddata["critchance"] = summeddata["critchance"] + (data[arg1.."critchance"] or 0) |
||
42 | summeddata["critbonus"] = summeddata["critbonus"] + (data[arg1.."critbonus"] or 0) |
||
43 | summeddata["ignitemodifier"] = summeddata["ignitemodifier"] + (data[arg1.."ignitemodifier"] or 0) |
||
44 | summeddata["sepignite"] = summeddata["sepignite"] + (data[arg1.."sepignite"] or 0) |
||
45 | summeddata["hitbonus"] = summeddata["hitbonus"] - (data[arg1.."hitchance"] or 0) |
||
46 | summeddata["casttime"] = summeddata["casttime"] + (data[arg1.."casttime"] or 0) |
||
47 | summeddata["regencasttime"] = summeddata["regencasttime"] + (data[arg1.."casttime"] or 0) |
||
48 | summeddata["penetration"] = summeddata["penetration"] + (data[arg1.."penetration"] or 0) |
||
49 | summeddata["grace"] = summeddata["grace"] + (data[arg1.."grace"] or 0) |
||
50 | summeddata["threat"] = summeddata["threat"] + (data[arg1.."threat"] or 0) |
||
51 | if data[arg1.."Netherwind"] == 1 then |
||
52 | summeddata["netherwind"] = 1 |
||
53 | end |
||
54 | end |
||
55 | |||
56 | local function TheoryCraft_DoSchool(arg1, summeddata) |
||
57 | if TheoryCraft_Data.Testing then |
||
58 | TheoryCraft_AddData(arg1, TheoryCraft_Data.TalentsTest, summeddata) |
||
59 | else |
||
60 | TheoryCraft_AddData(arg1, TheoryCraft_Data.Talents, summeddata) |
||
61 | end |
||
62 | TheoryCraft_AddData(arg1, TheoryCraft_Data.BaseData, summeddata) |
||
63 | TheoryCraft_AddData(arg1, TheoryCraft_Data.Stats, summeddata) |
||
64 | TheoryCraft_AddData(arg1, TheoryCraft_Data.PlayerBuffs, summeddata) |
||
65 | TheoryCraft_AddData(arg1, TheoryCraft_Data.TargetBuffs, summeddata) |
||
66 | TheoryCraft_AddData(arg1, TheoryCraft_Data.EquipEffects, summeddata) |
||
67 | TheoryCraft_AddData(arg1, TheoryCraft_Data.Target, summeddata) |
||
68 | end |
||
69 | |||
70 | local function SummateData(name, schools) |
||
71 | TheoryCraft_DeleteTable(summeddata) |
||
72 | summeddata["doshatter"] = (TheoryCraft_Data.TargetBuffs["doshatter"] or 0) |
||
73 | summeddata["tmpincrease"] = 0 |
||
74 | summeddata["tmpincreaseupfront"] = 0 |
||
75 | summeddata["baseincrease"] = 0 |
||
76 | summeddata["baseincreaseupfront"] = 0 |
||
77 | summeddata["talentmod"] = 0 |
||
78 | summeddata["talentmodupfront"] = 0 |
||
79 | summeddata["critchance"] = (TheoryCraft_Data.Stats["critchance"] or 0) |
||
80 | summeddata["illum"] = 0 |
||
81 | summeddata["plusdam"] = 0 |
||
82 | summeddata["manacostmod"] = 1 |
||
83 | summeddata["critbonus"] = 0 |
||
84 | summeddata["ignitemodifier"] = 0 |
||
85 | summeddata["sepignite"] = 0 |
||
86 | summeddata["hitbonus"] = 0 |
||
87 | summeddata["casttime"] = 0 |
||
88 | summeddata["regencasttime"] = 0 |
||
89 | summeddata["penetration"] = 0 |
||
90 | summeddata["grace"] = 0 |
||
91 | summeddata["netherwind"] = 0 |
||
92 | summeddata["threat"] = 0 |
||
93 | for k, v in pairs (schools) do |
||
94 | TheoryCraft_DoSchool(v, summeddata) |
||
95 | end |
||
96 | TheoryCraft_DoSchool(name, summeddata) |
||
97 | end |
||
98 | |||
99 | local function getcooldown(frame) |
||
100 | index = 1 |
||
101 | local rtext = getglobal(frame:GetName().."TextRight"..index):GetText() |
||
102 | local cooldown = 1.5 |
||
103 | while (rtext) do |
||
104 | if (getglobal(frame:GetName().."TextRight"..index):IsVisible()) then |
||
105 | if (strfind(rtext, "%d+.%d+"..TheoryCraft_Locale.Cooldown)) then |
||
106 | cooldown = findpattern(rtext, "%d+.%d+"); |
||
107 | elseif (strfind(rtext, "%d+"..TheoryCraft_Locale.Cooldown)) then |
||
108 | cooldown = findpattern(rtext, "%d+"); |
||
109 | end |
||
110 | end |
||
111 | index = index + 1; |
||
112 | rtext = getglobal(frame:GetName().."TextRight"..index):GetText() |
||
113 | end |
||
114 | return cooldown |
||
115 | end |
||
116 | |||
117 | local function getlifetap(returndata) |
||
118 | local i2 = 1 |
||
119 | local spellname = 1 |
||
120 | local spellrank = 1 |
||
121 | local quit = 0 |
||
122 | local found = 0 |
||
123 | while (spellname) do |
||
124 | spellname, spellrank = GetSpellName(i2,BOOKTYPE_SPELL) |
||
125 | spellrank = tonumber(findpattern(spellrank, "%d+")) |
||
126 | if (spellname == TheoryCraft_Locale.lifetap) then |
||
127 | found = 1 |
||
128 | elseif (found == 1) then |
||
129 | TCTooltip:SetOwner(UIParent,"ANCHOR_NONE") |
||
130 | TCTooltip:SetSpell(i2-1,BOOKTYPE_SPELL) |
||
131 | if (TCTooltip:NumLines() > 0) then |
||
132 | local description = getglobal("TCTooltipTextLeft"..TCTooltip:NumLines()):GetText() |
||
133 | returndata["lifetapHealth"] = findpattern(description, "%d+ health") |
||
134 | returndata["lifetapMana"] = findpattern(description, "%d+ mana") |
||
135 | if returndata["lifetapHealth"] then |
||
136 | returndata["lifetapHealth"] = tonumber(findpattern(returndata["lifetapHealth"], "%d+")) |
||
137 | end |
||
138 | if returndata["lifetapMana"] then |
||
139 | returndata["lifetapMana"] = tonumber(findpattern(returndata["lifetapMana"], "%d+")) |
||
140 | end |
||
141 | end |
||
142 | return |
||
143 | end |
||
144 | i2 = i2 + 1 |
||
145 | end |
||
146 | end |
||
147 | |||
148 | function TheoryCraft_GetStat(statname) |
||
149 | if TheoryCraft_Data.testing then |
||
150 | return (TheoryCraft_Data.BaseData[statname] or 0)+ |
||
151 | (TheoryCraft_Data.TalentsTest[statname] or 0)+ |
||
152 | (TheoryCraft_Data.Stats[statname] or 0)+ |
||
153 | (TheoryCraft_Data.PlayerBuffs[statname] or 0)+ |
||
154 | (TheoryCraft_Data.TargetBuffs[statname] or 0)+ |
||
155 | (TheoryCraft_Data.EquipEffects[statname] or 0)+ |
||
156 | (TheoryCraft_Data.Target[statname] or 0) |
||
157 | else |
||
158 | return (TheoryCraft_Data.BaseData[statname] or 0)+ |
||
159 | (TheoryCraft_Data.Talents[statname] or 0)+ |
||
160 | (TheoryCraft_Data.Stats[statname] or 0)+ |
||
161 | (TheoryCraft_Data.PlayerBuffs[statname] or 0)+ |
||
162 | (TheoryCraft_Data.TargetBuffs[statname] or 0)+ |
||
163 | (TheoryCraft_Data.EquipEffects[statname] or 0)+ |
||
164 | (TheoryCraft_Data.Target[statname] or 0) |
||
165 | end |
||
166 | end |
||
167 | |||
168 | local function agipercrit() |
||
169 | if TheoryCraft_agipercrit then |
||
170 | return TheoryCraft_agipercrit |
||
171 | else |
||
172 | return TheoryCraft_CritChance[class][1] |
||
173 | end |
||
174 | end |
||
175 | |||
176 | function TheoryCraft_intpercrit() |
||
177 | local critdivider |
||
178 | local agipercrit = agipercrit() |
||
179 | if agipercrit == TheoryCraft_CritChance[class][1] then |
||
180 | critdivider = UnitLevel("player")/60*TheoryCraft_CritChance[class][2] |
||
181 | if (critdivider < 5) then |
||
182 | critdivider = 5 |
||
183 | end |
||
184 | else |
||
185 | critdivider = agipercrit/TheoryCraft_CritChance[class][1]*TheoryCraft_CritChance[class][2] |
||
186 | end |
||
187 | return critdivider |
||
188 | end |
||
189 | |||
190 | --- Returns the cast time from the spell tooltip --- |
||
191 | |||
192 | local function getcasttime(frame) |
||
193 | index = 1; |
||
194 | local ltext = getglobal(frame:GetName().."TextLeft"..index):GetText() |
||
195 | local castTime = 0 |
||
196 | while (ltext) do |
||
197 | ltext = string.gsub(ltext, ",", ".") |
||
198 | if (strfind(ltext, "%d+.%d+"..TheoryCraft_Locale.SecCast)) then |
||
199 | castTime = findpattern(findpattern(ltext, "%d+.%d+"..TheoryCraft_Locale.SecCast), "%d+.%d+") |
||
200 | elseif (strfind(ltext, "%d+"..TheoryCraft_Locale.SecCast)) then |
||
201 | castTime = findpattern(findpattern(ltext, "%d+"..TheoryCraft_Locale.SecCast), "%d+") |
||
202 | end |
||
203 | index = index + 1 |
||
204 | ltext = getglobal(frame:GetName().."TextLeft"..index):GetText() |
||
205 | end |
||
206 | castTime = tonumber(castTime) |
||
207 | return castTime |
||
208 | end |
||
209 | |||
210 | --- Returns the dot duration from the spell tooltip --- |
||
211 | |||
212 | local function TheoryCraft_getDotDuration(description) |
||
213 | local i = 1 |
||
214 | local _, found |
||
215 | while TheoryCraft_DotDurations[i] do |
||
216 | if (strfind(description, TheoryCraft_DotDurations[i].text)) then |
||
217 | if TheoryCraft_DotDurations[i].amount == "n" then |
||
218 | _, _, found = strfind(description, TheoryCraft_DotDurations[i].text) |
||
219 | return found |
||
220 | else |
||
221 | return TheoryCraft_DotDurations[i].amount |
||
222 | end |
||
223 | end |
||
224 | i = i + 1 |
||
225 | end |
||
226 | return 1 |
||
227 | end |
||
228 | |||
229 | local function getmanacost(frame) |
||
230 | index = 1 |
||
231 | local ltext = getglobal(frame:GetName().."TextLeft"..index):GetText() |
||
232 | local manaCost = 0 |
||
233 | while (ltext) do |
||
234 | if (strfind(ltext, TheoryCraft_Locale.Mana)) then |
||
235 | manaCost = findpattern(ltext, "%d+") |
||
236 | end |
||
237 | index = index + 1; |
||
238 | ltext = getglobal(frame:GetName().."TextLeft"..index):GetText() |
||
239 | end |
||
240 | manaCost = tonumber(manaCost) |
||
241 | if manaCost then |
||
242 | return manaCost |
||
243 | else |
||
244 | return 0 |
||
245 | end |
||
246 | end |
||
247 | |||
248 | local function TheoryCraft_GetRangedSpeed() |
||
249 | TheoryCraftTooltip:SetOwner(UIParent,"ANCHOR_NONE") |
||
250 | TheoryCraftTooltip:SetInventoryItem ("player", GetInventorySlotInfo("RangedSlot")) |
||
251 | local index = 1 |
||
252 | ltext = getglobal(TheoryCraftTooltip:GetName().."TextLeft"..index) |
||
253 | rtext = getglobal(TheoryCraftTooltip:GetName().."TextRight"..index) |
||
254 | if ltext then |
||
255 | ltext = ltext:GetText() |
||
256 | end |
||
257 | if rtext then |
||
258 | if not (getglobal(TheoryCraftTooltip:GetName().."TextRight"..index):IsVisible()) then |
||
259 | rtext = nil |
||
260 | else |
||
261 | rtext = rtext:GetText() |
||
262 | end |
||
263 | end |
||
264 | while (ltext ~= nil) do |
||
265 | if (rtext) then |
||
266 | for k, v in pairs(TheoryCraft_EquipEveryRight) do |
||
267 | if (v.slot == nil) or (v.slot == "Ranged") then |
||
268 | _, start, found = strfind(rtext, v.text) |
||
269 | if found then |
||
270 | if v.amount then |
||
271 | TheoryCraftTooltip:ClearLines() |
||
272 | return v.amount |
||
273 | else |
||
274 | TheoryCraftTooltip:ClearLines() |
||
275 | return found |
||
276 | end |
||
277 | end |
||
278 | end |
||
279 | end |
||
280 | end |
||
281 | index = index + 1; |
||
282 | ltext = getglobal(TheoryCraftTooltip:GetName().."TextLeft"..index) |
||
283 | rtext = getglobal(TheoryCraftTooltip:GetName().."TextRight"..index) |
||
284 | if ltext then |
||
285 | ltext = ltext:GetText() |
||
286 | end |
||
287 | if rtext then |
||
288 | if not (getglobal(TheoryCraftTooltip:GetName().."TextRight"..index):IsVisible()) then |
||
289 | rtext = nil |
||
290 | else |
||
291 | rtext = rtext:GetText() |
||
292 | end |
||
293 | end |
||
294 | end |
||
295 | TheoryCraftTooltip:ClearLines() |
||
296 | return 2.8 |
||
297 | end |
||
298 | |||
299 | local function GetCritChance(critreport) |
||
300 | local critChance, iCritInfo, critNum |
||
301 | local remove = 0 |
||
302 | local id = 1 |
||
303 | local attackSpell = GetSpellName(id,BOOKTYPE_SPELL) |
||
304 | if (attackSpell ~= TheoryCraft_Locale.Attack) then |
||
305 | name, texture, offset, numSpells = GetSpellTabInfo(1) |
||
306 | for i=1, numSpells do |
||
307 | if (GetSpellName(i,BOOKTYPE_SPELL) == TheoryCraft_Locale.Attack) then |
||
308 | id = i |
||
309 | end |
||
310 | end |
||
311 | end |
||
312 | if GetSpellName(id,BOOKTYPE_SPELL) ~= TheoryCraft_Locale.Attack then |
||
313 | return 0 |
||
314 | end |
||
315 | TheoryCraftTooltip:SetOwner(UIParent,"ANCHOR_NONE") |
||
316 | TheoryCraftTooltip:SetSpell(id, BOOKTYPE_SPELL) |
||
317 | local spellName = TheoryCraftTooltipTextLeft2:GetText() |
||
318 | if not spellName then return 0 end |
||
319 | iCritInfo = string.find(spellName, "%s") |
||
320 | critNum = string.sub(spellName,0,(iCritInfo -2)) |
||
321 | critChance = string.gsub(critNum, ",", ".") |
||
322 | critChance = tonumber(critChance) |
||
323 | if critreport == nil then critreport = 0 end |
||
324 | if (critChance) and (critChance ~= critreport) then |
||
325 | local doweaponskill = true |
||
326 | if class == "DRUID" then |
||
327 | local _, _, active = GetShapeshiftFormInfo(1) |
||
328 | if active then doweaponskill = nil end |
||
329 | local _, _, active = GetShapeshiftFormInfo(3) |
||
330 | if active then doweaponskill = nil end |
||
331 | end |
||
332 | if doweaponskill then |
||
333 | TheoryCraftTooltip:SetOwner(UIParent,"ANCHOR_NONE") |
||
334 | TheoryCraftTooltip:SetInventoryItem ("player", GetInventorySlotInfo("MainHandSlot")) |
||
335 | local i, i2 = 1 |
||
336 | local ltext = getglobal(TheoryCraftTooltip:GetName().."TextLeft"..i):GetText() |
||
337 | local rtext = getglobal(TheoryCraftTooltip:GetName().."TextRight"..i):GetText() |
||
338 | local skill = TheoryCraft_WeaponSkillOther |
||
339 | local english = "Unarmed" |
||
340 | while ltext do |
||
341 | ltext = getglobal(TheoryCraftTooltip:GetName().."TextLeft"..i):GetText() |
||
342 | rtext = getglobal(TheoryCraftTooltip:GetName().."TextRight"..i):GetText() |
||
343 | if (rtext) and (getglobal(TheoryCraftTooltip:GetName().."TextRight"..i):IsVisible()) then |
||
344 | i2 = 1 |
||
345 | while TheoryCraft_WeaponSkills[i2] do |
||
346 | if (((TheoryCraft_WeaponSkills[i2].ltext) and (TheoryCraft_WeaponSkills[i2].ltext == ltext)) or (TheoryCraft_WeaponSkills[i2].ltext == nil)) and (TheoryCraft_WeaponSkills[i2].text == rtext) then |
||
347 | skill = TheoryCraft_WeaponSkills[i2].skill |
||
348 | english = TheoryCraft_WeaponSkills[i2].english |
||
349 | break |
||
350 | end |
||
351 | i2 = i2 + 1 |
||
352 | end |
||
353 | end |
||
354 | if skill ~= TheoryCraft_WeaponSkillOther then |
||
355 | break |
||
356 | end |
||
357 | i = i + 1 |
||
358 | end |
||
359 | local i = 1 |
||
360 | local skillTitle, header, isExpanded, skillRank |
||
361 | while GetSkillLineInfo(i) do |
||
362 | skillTitle, header, isExpanded, skillRank = GetSkillLineInfo(i) |
||
363 | if (skillTitle == skill) then |
||
364 | critChance = critChance + (UnitLevel("player")*5 - skillRank)*0.04 |
||
365 | break |
||
366 | end |
||
367 | i = i + 1 |
||
368 | end |
||
369 | -- remove weapon specs |
||
370 | critChance = critChance - TheoryCraft_GetStat(english.."specreal") |
||
371 | end |
||
372 | critChance = critChance - (TheoryCraft_GetStat("CritChangeTalents") or 0) |
||
373 | if doweaponskill == nil then |
||
374 | critChance = critChance - (TheoryCraft_Data.Talents["Formcritchancereal"] or 0) |
||
375 | remove = -1*(TheoryCraft_Data.Talents["Formcritchancereal"] or 0) |
||
376 | end |
||
377 | local critchance2 = critChance-TheoryCraft_GetStat("CritReport") |
||
378 | if doweaponskill == nil then |
||
379 | critChance = critChance + (TheoryCraft_Data.Talents["Formcritchance"] or 0) |
||
380 | end |
||
381 | if class == "WARRIOR" then |
||
382 | local _, _, active = GetShapeshiftFormInfo(3) |
||
383 | if active then |
||
384 | critchance2 = critchance2 - 3 |
||
385 | remove = -3 |
||
386 | end |
||
387 | end |
||
388 | if UnitLevel("player") == 60 then |
||
389 | if (class == "DRUID") then |
||
390 | if doweaponskill == nil then |
||
391 | remove = -1*(TheoryCraft_Data.Talents["Formcritchance"] or 0) |
||
392 | end |
||
393 | end |
||
394 | TheoryCraft_agipercrit = TheoryCraft_CritChance[class][1] |
||
395 | else |
||
396 | if (TheoryCraft_Data["outfit"] == nil) or (TheoryCraft_Data["outfit"] == 1) then |
||
397 | local _, agi = UnitStat("player", 2) |
||
398 | TheoryCraft_agipercrit = agi/(critchance2-TheoryCraft_CritChance[class][3]) |
||
399 | end |
||
400 | end |
||
401 | return (critChance or 0), remove |
||
402 | else |
||
403 | return 0, remove |
||
404 | end |
||
405 | end |
||
406 | |||
407 | function TheoryCraft_LoadStats(talents) |
||
408 | if talents == nil then talents = TheoryCraft_Data.Talents end |
||
409 | TheoryCraft_DeleteTable(TheoryCraft_Data.Stats) |
||
410 | local remove |
||
411 | TheoryCraft_Data.Stats["meleecritchance"], remove = GetCritChance() |
||
412 | TheoryCraft_Data.Stats["Rangedhastebonus"] = UnitRangedDamage("player")/TheoryCraft_GetRangedSpeed() |
||
413 | local outfit = (TheoryCraft_Data["outfit"] or 1) |
||
414 | if outfit == -1 then |
||
415 | outfit = 1 |
||
416 | end |
||
417 | |||
418 | local _, tmp = UnitStat("player", 1) |
||
419 | TheoryCraft_Data.Stats["strength"] = tmp |
||
420 | _, tmp = UnitStat("player", 2) |
||
421 | TheoryCraft_Data.Stats["agility"] = tmp |
||
422 | _, tmp = UnitStat("player", 3) |
||
423 | TheoryCraft_Data.Stats["stamina"] = tmp |
||
424 | _, tmp = UnitStat("player", 4) |
||
425 | TheoryCraft_Data.Stats["intellect"] = tmp |
||
426 | _, tmp = UnitStat("player", 5) |
||
427 | TheoryCraft_Data.Stats["spirit"] = tmp |
||
428 | TheoryCraft_Data.Stats["agipercrit"] = agipercrit() |
||
429 | |||
430 | local _, catform, bearform |
||
431 | if class == "DRUID" then |
||
432 | _, _, bearform = GetShapeshiftFormInfo(1) |
||
433 | _, _, catform = GetShapeshiftFormInfo(3) |
||
434 | TheoryCraft_Data.Stats["agilityapranged"] = 2 |
||
435 | TheoryCraft_Data.Stats["strengthapmelee"] = 2 |
||
436 | if catform then |
||
437 | TheoryCraft_Data.Stats["agilityapmelee"] = 1 |
||
438 | else |
||
439 | TheoryCraft_Data.Stats["agilityapmelee"] = 0 |
||
440 | end |
||
441 | elseif (class == "WARRIOR") or (class == "PALADIN") or (class == "SHAMAN") then |
||
442 | TheoryCraft_Data.Stats["agilityapranged"] = 2 |
||
443 | TheoryCraft_Data.Stats["strengthapmelee"] = 2 |
||
444 | TheoryCraft_Data.Stats["agilityapmelee"] = 0 |
||
445 | elseif (class == "ROGUE") or (class == "HUNTER") then |
||
446 | TheoryCraft_Data.Stats["agilityapranged"] = 2 |
||
447 | TheoryCraft_Data.Stats["strengthapmelee"] = 1 |
||
448 | TheoryCraft_Data.Stats["agilityapmelee"] = 1 |
||
449 | else |
||
450 | TheoryCraft_Data.Stats["agilityapranged"] = 0 |
||
451 | TheoryCraft_Data.Stats["strengthapmelee"] = 1 |
||
452 | TheoryCraft_Data.Stats["agilityapmelee"] = 0 |
||
453 | end |
||
454 | |||
455 | local base, pos, neg = UnitAttackPower("player") |
||
456 | TheoryCraft_Data.Stats["attackpower"] = base+pos+neg-TheoryCraft_Data.Stats["strengthapmelee"]*TheoryCraft_Data.Stats["strength"]-TheoryCraft_Data.Stats["agilityapmelee"]*TheoryCraft_Data.Stats["agility"]+(talents["AttackPowerTalents"] or 0) |
||
457 | base, pos, neg = UnitRangedAttackPower("player") |
||
458 | TheoryCraft_Data.Stats["rangedattackpower"] = (TheoryCraft_Data.TargetBuffs["huntersmark"] or 0)+base+pos+neg-TheoryCraft_Data.Stats["agilityapranged"]*TheoryCraft_Data.Stats["agility"] |
||
459 | |||
460 | TheoryCraft_Data.Stats["totalmana"] = UnitManaMax("player")/talents["manamultiplierreal"] |
||
461 | TheoryCraft_Data.Stats["totalhealth"] = UnitHealthMax("player")/talents["healthmultiplierreal"] |
||
462 | |||
463 | TheoryCraft_Data.Stats["meleecritchance"] = TheoryCraft_Data.Stats["meleecritchance"]-TheoryCraft_Data.Stats["agility"]/TheoryCraft_Data.Stats["agipercrit"] |
||
464 | TheoryCraft_Data.Stats["totalhealth"] = TheoryCraft_Data.Stats["totalhealth"] - TheoryCraft_Data.Stats["stamina"]*10 |
||
465 | TheoryCraft_Data.Stats["totalmana"] = TheoryCraft_Data.Stats["totalmana"] - TheoryCraft_Data.Stats["intellect"]*15 |
||
466 | |||
467 | TheoryCraft_Data.Stats["strength"] = TheoryCraft_Data.Stats["strength"]/talents["strmultiplierreal"] |
||
468 | TheoryCraft_Data.Stats["agility"] = TheoryCraft_Data.Stats["agility"]/talents["agimultiplierreal"] |
||
469 | TheoryCraft_Data.Stats["stamina"] = TheoryCraft_Data.Stats["stamina"]/talents["stammultiplierreal"] |
||
470 | TheoryCraft_Data.Stats["intellect"] = TheoryCraft_Data.Stats["intellect"]/talents["intmultiplierreal"] |
||
471 | TheoryCraft_Data.Stats["spirit"] = TheoryCraft_Data.Stats["spirit"]/talents["spiritmultiplierreal"] |
||
472 | TheoryCraft_Data.Stats["formattackpower"] = 0 |
||
473 | |||
474 | if (TheoryCraft_Outfits[outfit].meleecritchance) then TheoryCraft_Data.Stats["meleecritchance"] = TheoryCraft_Data.Stats["meleecritchance"]+TheoryCraft_Outfits[outfit].meleecritchance end |
||
475 | if (TheoryCraft_Outfits[outfit].rangedattackpower) then TheoryCraft_Data.Stats["rangedattackpower"] = TheoryCraft_Data.Stats["rangedattackpower"]+TheoryCraft_Outfits[outfit].rangedattackpower end |
||
476 | if (TheoryCraft_Outfits[outfit].attackpower) then TheoryCraft_Data.Stats["attackpower"] = TheoryCraft_Data.Stats["attackpower"]+TheoryCraft_Outfits[outfit].attackpower end |
||
477 | if (TheoryCraft_Outfits[outfit].formattackpower) then TheoryCraft_Data.Stats["formattackpower"] = TheoryCraft_Data.Stats["formattackpower"]+TheoryCraft_Outfits[outfit].formattackpower end |
||
478 | if (TheoryCraft_Outfits[outfit].strength) then TheoryCraft_Data.Stats["strength"] = TheoryCraft_Data.Stats["strength"]+TheoryCraft_Outfits[outfit].strength end |
||
479 | if (TheoryCraft_Outfits[outfit].agility) then TheoryCraft_Data.Stats["agility"] = TheoryCraft_Data.Stats["agility"]+TheoryCraft_Outfits[outfit].agility end |
||
480 | if (TheoryCraft_Outfits[outfit].stamina) then TheoryCraft_Data.Stats["stamina"] = TheoryCraft_Data.Stats["stamina"]+TheoryCraft_Outfits[outfit].stamina end |
||
481 | if (TheoryCraft_Outfits[outfit].intellect) then TheoryCraft_Data.Stats["intellect"] = TheoryCraft_Data.Stats["intellect"]+TheoryCraft_Outfits[outfit].intellect end |
||
482 | if (TheoryCraft_Outfits[outfit].spirit) then TheoryCraft_Data.Stats["spirit"] = TheoryCraft_Data.Stats["spirit"]+TheoryCraft_Outfits[outfit].spirit end |
||
483 | if (TheoryCraft_Outfits[outfit].totalmana) then TheoryCraft_Data.Stats["totalmana"] = TheoryCraft_Data.Stats["totalmana"]+TheoryCraft_Outfits[outfit].totalmana end |
||
484 | if (TheoryCraft_Outfits[outfit].totalhealth) then TheoryCraft_Data.Stats["totalhealth"] = TheoryCraft_Data.Stats["totalhealth"]+TheoryCraft_Outfits[outfit].totalhealth end |
||
485 | |||
486 | local i = 1 |
||
487 | TheoryCraft_Data.DequippedSets = {} |
||
488 | while (TheoryCraft_Outfits[outfit].destat[i]) do |
||
489 | TheoryCraft_Data.Stats = TheoryCraft_DequipEffect(TheoryCraft_Outfits[outfit].destat[i], TheoryCraft_Data.Stats, TheoryCraft_Data.DequippedSets) |
||
490 | i = i + 1 |
||
491 | end |
||
492 | |||
493 | local returndata |
||
494 | for k,count in pairs(TheoryCraft_Data.DequippedSets) do |
||
495 | if TheoryCraft_SetBonuses[k] then |
||
496 | for k,v in pairs(TheoryCraft_SetBonuses[k]) do |
||
497 | if (v["pieces"] <= count) then |
||
498 | returndata = {} |
||
499 | returndata = TheoryCraft_DequipLine(v["text"], returndata) |
||
500 | for k,v in pairs(returndata) do |
||
501 | TheoryCraft_Data.Stats[k] = (TheoryCraft_Data.Stats[k] or 0) + v |
||
502 | end |
||
503 | returndata = {} |
||
504 | returndata = TheoryCraft_DequipSpecial(v["text"], returndata) |
||
505 | for k,v in pairs(returndata) do |
||
506 | TheoryCraft_Data.Stats[k] = (TheoryCraft_Data.Stats[k] or 0) + v |
||
507 | end |
||
508 | end |
||
509 | end |
||
510 | end |
||
511 | end |
||
512 | |||
513 | if catform or bearform then TheoryCraft_Data.Stats["attackpower"] = TheoryCraft_Data.Stats["attackpower"] + TheoryCraft_Data.Stats["formattackpower"] end |
||
514 | TheoryCraft_Data.Stats["strength"] = math.floor(TheoryCraft_Data.Stats["strength"] * talents["strmultiplier"]) |
||
515 | TheoryCraft_Data.Stats["agility"] = math.floor(TheoryCraft_Data.Stats["agility"] * talents["agimultiplier"]) |
||
516 | TheoryCraft_Data.Stats["rangedattackpower"] = math.floor(TheoryCraft_Data.Stats["rangedattackpower"]+TheoryCraft_Data.Stats["agilityapranged"]*TheoryCraft_Data.Stats["agility"]) |
||
517 | TheoryCraft_Data.Stats["attackpower"] = math.floor(TheoryCraft_Data.Stats["attackpower"]+TheoryCraft_Data.Stats["strengthapmelee"]*TheoryCraft_Data.Stats["strength"]+TheoryCraft_Data.Stats["agilityapmelee"]*TheoryCraft_Data.Stats["agility"]) |
||
518 | TheoryCraft_Data.Stats["intellect"] = math.floor(TheoryCraft_Data.Stats["intellect"] * talents["intmultiplier"]) |
||
519 | TheoryCraft_Data.Stats["stamina"] = math.floor(TheoryCraft_Data.Stats["stamina"] * talents["stammultiplier"]) |
||
520 | TheoryCraft_Data.Stats["spirit"] = math.floor(TheoryCraft_Data.Stats["spirit"] * talents["spiritmultiplier"]) |
||
521 | TheoryCraft_Data.Stats["totalhealth"] = (TheoryCraft_Data.Stats["totalhealth"] + TheoryCraft_Data.Stats["stamina"]*10)*talents["healthmultiplier"] |
||
522 | TheoryCraft_Data.Stats["totalmana"] = (TheoryCraft_Data.Stats["totalmana"] + TheoryCraft_Data.Stats["intellect"]*15)*talents["manamultiplier"] |
||
523 | TheoryCraft_Data.Stats["meleecritchance"] = TheoryCraft_Data.Stats["meleecritchance"]+TheoryCraft_Data.Stats["agility"]/TheoryCraft_Data.Stats["agipercrit"] |
||
524 | TheoryCraft_Data.Stats["rangedcritchance"] = TheoryCraft_Data.Stats["meleecritchance"]+(talents["Huntercritchance"] or 0) |
||
525 | TheoryCraft_Data.Stats["critchance"] = TheoryCraft_Data.Stats["intellect"]/TheoryCraft_intpercrit()+TheoryCraft_CritChance[class][4] |
||
526 | if class == "MAGE" then |
||
527 | TheoryCraft_Data.Stats["regenfromspirit"] = TheoryCraft_Data.Stats["spirit"]/8+6.25 |
||
528 | elseif class == "PRIEST" then |
||
529 | TheoryCraft_Data.Stats["regenfromspirit"] = TheoryCraft_Data.Stats["spirit"]/8+6.25 |
||
530 | elseif class == "WARLOCK" then |
||
531 | TheoryCraft_Data.Stats["regenfromspirit"] = TheoryCraft_Data.Stats["spirit"]/10+7.5 |
||
532 | elseif class == "DRUID" then |
||
533 | TheoryCraft_Data.Stats["regenfromspirit"] = TheoryCraft_Data.Stats["spirit"]/10+7.5 |
||
534 | elseif class == "SHAMAN" then |
||
535 | TheoryCraft_Data.Stats["regenfromspirit"] = TheoryCraft_Data.Stats["spirit"]/10+8.5 |
||
536 | elseif class == "HUNTER" then |
||
537 | TheoryCraft_Data.Stats["regenfromspirit"] = TheoryCraft_Data.Stats["spirit"]/10+7.5 |
||
538 | elseif class == "PALADIN" then |
||
539 | TheoryCraft_Data.Stats["regenfromspirit"] = TheoryCraft_Data.Stats["spirit"]/10+7.5 |
||
540 | elseif class == "ROGUE" then |
||
541 | TheoryCraft_Data.Stats["regenfromspirit"] = 0 |
||
542 | elseif class == "WARRIOR" then |
||
543 | TheoryCraft_Data.Stats["regenfromspirit"] = 0 |
||
544 | end |
||
545 | |||
546 | TheoryCraft_Data.Stats["meleecritchancereal"] = TheoryCraft_Data.Stats["meleecritchance"]+(remove or 0) |
||
547 | if (TheoryCraft_Data.EquipEffects["FistEquipped"] or 0) >= 1 then |
||
548 | TheoryCraft_Data.Stats["meleecritchance"] = TheoryCraft_Data.Stats["meleecritchance"]+TheoryCraft_GetStat("Fistspec") |
||
549 | end |
||
550 | if (TheoryCraft_Data.EquipEffects["DaggerEquipped"] or 0) >= 1 then |
||
551 | TheoryCraft_Data.Stats["meleecritchance"] = TheoryCraft_Data.Stats["meleecritchance"]+TheoryCraft_GetStat("Daggerspec") |
||
552 | end |
||
553 | if (TheoryCraft_Data.EquipEffects["AxeEquipped"] or 0) >= 1 then |
||
554 | TheoryCraft_Data.Stats["meleecritchance"] = TheoryCraft_Data.Stats["meleecritchance"]+TheoryCraft_GetStat("Axespec") |
||
555 | end |
||
556 | if (TheoryCraft_Data.EquipEffects["PolearmEquipped"] or 0) >= 1 then |
||
557 | TheoryCraft_Data.Stats["meleecritchance"] = TheoryCraft_Data.Stats["meleecritchance"]+TheoryCraft_GetStat("Polearmspec") |
||
558 | end |
||
559 | local meleeapmult = TheoryCraft_GetStat("MeleeAPMult") |
||
560 | if meleeapmult > 3 then |
||
561 | TheoryCraft_Data.Stats["Meleemodifier"] = (talents["Twohandmodifier"] or 0)+(talents["Twohandtalentmod"] or 0) |
||
562 | elseif meleeapmult > 1 then |
||
563 | TheoryCraft_Data.Stats["Meleemodifier"] = (talents["Onehandmodifier"] or 0)+(talents["Onehandtalentmod"] or 0) |
||
564 | end |
||
565 | local manaregen = TheoryCraft_GetStat("manaperfive")/5 |
||
566 | manaregen = manaregen+TheoryCraft_Data.Stats["totalmana"]*TheoryCraft_GetStat("FelEnergy")/4 |
||
567 | TheoryCraft_Data.Stats["regen"] = manaregen+TheoryCraft_Data.Stats["regenfromspirit"] |
||
568 | TheoryCraft_Data.Stats["icregen"] = manaregen+(TheoryCraft_Data.Stats["regenfromspirit"])*TheoryCraft_GetStat("ICPercent") |
||
569 | if (class == "MAGE") then |
||
570 | TheoryCraft_Data.Stats["maxtotalmana"] = TheoryCraft_Data.Stats["totalmana"]+TheoryCraft_Data.Stats["regenfromspirit"]*15*8+1100+manaregen*8 |
||
571 | end |
||
572 | if (class == "WARLOCK") then |
||
573 | getlifetap(TheoryCraft_Data.Stats) |
||
574 | end |
||
575 | |||
576 | TheoryCraft_Data.Stats["All"] = math.floor(TheoryCraft_Data.Stats["spirit"]*(talents["Allspiritual"] or 0)) |
||
577 | TheoryCraft_Data.Stats["BlockValue"] = TheoryCraft_GetStat("BlockValueReport")+(TheoryCraft_Data.Stats["strength"]/20) - 1 |
||
578 | end |
||
579 | |||
580 | local function AddProcs(casttime, returndata, spelldata) |
||
581 | TheoryCraft_Data.Procs = {} |
||
582 | if TheoryCraft_Settings["procs"] == nil then return end |
||
583 | if (spelldata == nil) or (spelldata.Schools == nil) then return end |
||
584 | if TheoryCraft_Data.EquipEffects["procs"] then |
||
585 | local i = 1 |
||
586 | local amount, procduration |
||
587 | while TheoryCraft_Data.EquipEffects["procs"][i] do |
||
588 | amount = TheoryCraft_Data.EquipEffects["procs"][i].amount |
||
589 | if TheoryCraft_Data.EquipEffects["procs"][i].exact then |
||
590 | procduration = 1 - (1 - TheoryCraft_Data.EquipEffects["procs"][i].proc)^math.floor(TheoryCraft_Data.EquipEffects["procs"][i].duration/casttime) |
||
591 | else |
||
592 | procduration = 1 - (1 - TheoryCraft_Data.EquipEffects["procs"][i].proc)^(TheoryCraft_Data.EquipEffects["procs"][i].duration/casttime) |
||
593 | end |
||
594 | TheoryCraft_Data.Procs[TheoryCraft_Data.EquipEffects["procs"][i].type] = (TheoryCraft_Data.Procs[TheoryCraft_Data.EquipEffects["procs"][i].type] or 0)+amount*procduration |
||
595 | i = i + 1 |
||
596 | end |
||
597 | i = 1 |
||
598 | while (spelldata.Schools[i]) do |
||
599 | TheoryCraft_AddData(spelldata.Schools[i], TheoryCraft_Data.Procs, returndata) |
||
600 | i = i+1 |
||
601 | end |
||
602 | if TheoryCraft_Data.Procs["ICPercent"] then |
||
603 | TheoryCraft_Data.Stats["icregen"] = TheoryCraft_GetStat("manaperfive")/5+(TheoryCraft_Data.Stats["regenfromspirit"])*(TheoryCraft_GetStat("ICPercent")+TheoryCraft_Data.Procs["ICPercent"]) |
||
604 | end |
||
605 | end |
||
606 | end |
||
607 | |||
608 | local function CleanUp(spelldata, returndata) |
||
609 | if spelldata.percent == 0 then |
||
610 | returndata["plusdam"] = nil |
||
611 | returndata["damfinal"] = nil |
||
612 | returndata["damcoef"] = nil |
||
613 | end |
||
614 | if spelldata.ismelee then |
||
615 | returndata["manacost"] = nil |
||
616 | returndata["plusdam"] = nil |
||
617 | end |
||
618 | if spelldata.isheal then |
||
619 | returndata["penetration"] = nil |
||
620 | end |
||
621 | if spelldata.armor then |
||
622 | returndata["plusdam"] = nil |
||
623 | returndata["penetration"] = nil |
||
624 | end |
||
625 | if spelldata.dodps == nil then |
||
626 | returndata["hps"] = nil |
||
627 | returndata["withhothps"] = nil |
||
628 | returndata["hpsdam"] = nil |
||
629 | returndata["hpsdampercent"] = nil |
||
630 | returndata["dps"] = nil |
||
631 | returndata["withdotdps"] = nil |
||
632 | returndata["dpsdam"] = nil |
||
633 | returndata["dpsdampercent"] = nil |
||
634 | end |
||
635 | if (spelldata.usemelee) or (spelldata.petspell) then |
||
636 | returndata["nextpendam"] = nil |
||
637 | returndata["nextpen"] = nil |
||
638 | returndata["penetration"] = nil |
||
639 | end |
||
640 | if spelldata.petspell then |
||
641 | returndata["damcoef"] = nil |
||
642 | returndata["dpsdam"] = nil |
||
643 | returndata["dpsdampercent"] = nil |
||
644 | returndata["plusdam"] = nil |
||
645 | returndata["dameff"] = nil |
||
646 | returndata["damfinal"] = nil |
||
647 | returndata["lifetapdps"] = nil |
||
648 | returndata["lifetapdpm"] = nil |
||
649 | returndata["nextagidps"] = nil |
||
650 | returndata["nexthitdps"] = nil |
||
651 | returndata["nextcritdps"] = nil |
||
652 | returndata["nextstrdpsequive"] = nil |
||
653 | returndata["nextagidpsequive"] = nil |
||
654 | returndata["nexthitdpsequive"] = nil |
||
655 | returndata["nextcritdpsequive"] = nil |
||
656 | returndata["nextagidam"] = nil |
||
657 | returndata["nextpendam"] = nil |
||
658 | returndata["nexthitdam"] = nil |
||
659 | returndata["nextcritdam"] = nil |
||
660 | returndata["nextstrdamequive"] = nil |
||
661 | returndata["nextagidamequive"] = nil |
||
662 | returndata["nextpendamequive"] = nil |
||
663 | returndata["nexthitdamequive"] = nil |
||
664 | returndata["nextcritdamequive"] = nil |
||
665 | returndata["regendam"] = nil |
||
666 | returndata["icregendam"] = nil |
||
667 | returndata["nextcritheal"] = nil |
||
668 | returndata["nextcrithealequive"] = nil |
||
669 | returndata["hpsdam"] = nil |
||
670 | returndata["hpsdampercent"] = nil |
||
671 | returndata["regenheal"] = nil |
||
672 | returndata["icregenheal"] = nil |
||
673 | end |
||
674 | |||
675 | if (spelldata.dontdpsafterresists) then |
||
676 | returndata["nexthitdam"] = nil |
||
677 | end |
||
678 | |||
679 | if (spelldata.cancrit == nil) then |
||
680 | returndata["nextcritdam"] = nil |
||
681 | returndata["nextcritdamequive"] = nil |
||
682 | returndata["nextcritdps"] = nil |
||
683 | returndata["nextcritdpsequive"] = nil |
||
684 | returndata["critchance"] = nil |
||
685 | returndata["critdmgchance"] = nil |
||
686 | returndata["crithealchance"] = nil |
||
687 | returndata["critdmgmin"] = nil |
||
688 | returndata["critdmgmax"] = nil |
||
689 | returndata["critdmgminminusignite"] = nil |
||
690 | returndata["critdmgmaxminusignite"] = nil |
||
691 | returndata["crithealmin"] = nil |
||
692 | returndata["crithealmax"] = nil |
||
693 | end |
||
694 | end |
||
695 | |||
696 | local function GenerateTooltip(frame, returndata, spelldata, spellrank) |
||
697 | returndata["RangedAPMult"] = 2.8 |
||
698 | if (frame == nil) or (frame:NumLines() == 0) then |
||
699 | CleanUp(spelldata, returndata) |
||
700 | return |
||
701 | end |
||
702 | if spelldata.evocation then |
||
703 | CleanUp(spelldata, returndata) |
||
704 | returndata["evocation"] = TheoryCraft_GetStat("maxtotalmana")-TheoryCraft_GetStat("totalmana")-1100 |
||
705 | return |
||
706 | end |
||
707 | if (spelldata.isranged) then |
||
708 | if TheoryCraft_Data.EquipEffects["RangedSpeed"] == nil then |
||
709 | CleanUp(spelldata, returndata) |
||
710 | return |
||
711 | end |
||
712 | end |
||
713 | if (spelldata.isseal) then |
||
714 | if TheoryCraft_Data.EquipEffects["MainSpeed"] == nil then |
||
715 | CleanUp(spelldata, returndata) |
||
716 | return |
||
717 | end |
||
718 | end |
||
719 | if (spelldata.id == "Backstab") then |
||
720 | if TheoryCraft_GetStat("DaggerEquipped") == 0 then |
||
721 | CleanUp(spelldata, returndata) |
||
722 | return |
||
723 | end |
||
724 | end |
||
725 | if (spelldata.ismelee) then |
||
726 | if TheoryCraft_Data.EquipEffects["MainSpeed"] == nil then |
||
727 | CleanUp(spelldata, returndata) |
||
728 | return |
||
729 | end |
||
730 | local i = 1 |
||
731 | returndata["critchance"] = TheoryCraft_Data.Stats["meleecritchance"]+TheoryCraft_GetStat(spelldata.id.."critchance") |
||
732 | while spelldata.Schools[i] do |
||
733 | returndata["critchance"] = returndata["critchance"]+TheoryCraft_GetStat(spelldata.Schools[i].."critchance") |
||
734 | i = i + 1 |
||
735 | end |
||
736 | end |
||
737 | if (spelldata.bearform) then |
||
738 | local _, _, active = GetShapeshiftFormInfo(1) |
||
739 | if active == nil then |
||
740 | CleanUp(spelldata, returndata) |
||
741 | return |
||
742 | end |
||
743 | end |
||
744 | if (spelldata.catform) then |
||
745 | local _, _, active = GetShapeshiftFormInfo(3) |
||
746 | if active == nil then |
||
747 | CleanUp(spelldata, returndata) |
||
748 | return |
||
749 | end |
||
750 | end |
||
751 | if (spelldata.usemelee) then |
||
752 | returndata["critchance"] = (TheoryCraft_Data.Stats["meleecritchance"] or 0)+TheoryCraft_GetStat("Holycritchance") |
||
753 | returndata["critbonus"] = 1 |
||
754 | end |
||
755 | if (spelldata.isranged) or ((class == "HUNTER") and (spelldata.ismelee == nil)) then |
||
756 | returndata["critchance"] = TheoryCraft_Data.Stats["rangedcritchance"] |
||
757 | end |
||
758 | returndata["description"] = getglobal(frame:GetName().."TextLeft"..frame:NumLines()):GetText() |
||
759 | returndata["casttime"] = getcasttime(frame)+(returndata["casttime"] or 0) |
||
760 | returndata["manacost"] = getmanacost(frame) |
||
761 | if not (spelldata.shoot or spelldata.ismelee or spelldata.isranged) then |
||
762 | returndata["basemanacost"] = returndata["manacost"] |
||
763 | end |
||
764 | if returndata["casttime"] < 1.5 then |
||
765 | returndata["casttime"] = 1.5 |
||
766 | end |
||
767 | returndata["regencasttime"] = returndata["casttime"] |
||
768 | if (spelldata.casttime) then |
||
769 | returndata["casttime"] = spelldata.casttime |
||
770 | end |
||
771 | AddProcs(returndata["casttime"], returndata, spelldata) |
||
772 | if (spelldata.regencasttime) then |
||
773 | returndata["regencasttime"] = spelldata.regencasttime |
||
774 | end |
||
775 | if (returndata["netherwind"] == 1) and (TheoryCraft_Settings["procs"]) then |
||
776 | if (returndata["casttime"] > 1.5) then returndata["casttime"] = (returndata["casttime"]-1.5)*0.9+1.5 end |
||
777 | if (returndata["regencasttime"] > 1.5) then returndata["regencasttime"] = (returndata["regencasttime"]-1.5)*0.9+1.5 end |
||
778 | end |
||
779 | local spelllevel = 60 |
||
780 | local levelpercent = 1 |
||
781 | returndata["manamultiplier"] = spelldata.manamultiplier |
||
782 | if (spelldata["level"..spellrank]) then spelllevel = spelldata["level"..spellrank] end |
||
783 | if (spelldata["level"..spellrank.."per"]) then levelpercent = spelldata["level"..spellrank.."per"] end |
||
784 | if (spelldata["level"..spellrank.."manamult"]) then returndata["manamultiplier"] = spelldata["level"..spellrank.."manamult"] end |
||
785 | if (spelldata["level"..spellrank.."ct"]) then |
||
786 | returndata["casttime"] = spelldata["level"..spellrank.."ct"] |
||
787 | returndata["regencasttime"] = spelldata["level"..spellrank.."ct"] |
||
788 | end |
||
789 | if (spelllevel < 20) then |
||
790 | levelpercent = levelpercent*(0.0375*spelllevel+0.25) |
||
791 | end |
||
792 | |||
793 | returndata["dotduration"] = TheoryCraft_getDotDuration(returndata["description"]) |
||
794 | returndata["basedotduration"] = spelldata.basedotduration |
||
795 | if (spelldata.ismelee == nil) and (spelldata.isranged == nil) then |
||
796 | if (spelldata.isheal == nil) and (spelldata.talentsbeforegear == nil) then |
||
797 | returndata["damcoef"] = spelldata.percent*returndata["tmpincrease"]*returndata["tmpincreaseupfront"]*levelpercent |
||
798 | else |
||
799 | returndata["damcoef"] = spelldata.percent*levelpercent |
||
800 | end |
||
801 | if (spelldata.righteousness) then |
||
802 | if (TheoryCraft_Data.EquipEffects["MeleeAPMult"] >= 3) then |
||
803 | returndata["damcoef"] = spelldata.percent2*returndata["tmpincrease"]*levelpercent |
||
804 | end |
||
805 | end |
||
806 | if (spelldata.hasdot == 1) then |
||
807 | returndata["damcoef2"] = spelldata.percentdot |
||
808 | returndata["plusdam2"] = math.floor(returndata["plusdam"] * returndata["damcoef2"] * levelpercent) |
||
809 | end |
||
810 | if (newcasttime) and (spelldata.isdot) then |
||
811 | returndata["damcoef"] = returndata["damcoef"]*newcasttime/returndata["basedotduration"] |
||
812 | returndata["casttime"] = newcasttime |
||
813 | end |
||
814 | returndata["damfinal"] = returndata["plusdam"] * returndata["damcoef"] |
||
815 | end |
||
816 | |||
817 | if returndata["critchance"] > 100 then |
||
818 | returndata["critchance"] = 100 |
||
819 | end |
||
820 | returndata["critbonus"] = returndata["critbonus"]+returndata["sepignite"]*(returndata["baseincrease"]+returndata["ignitemodifier"]-1) |
||
821 | returndata["sepignite"] = returndata["sepignite"]*returndata["baseincrease"] |
||
822 | |||
823 | returndata["talentbaseincrease"] = (1/returndata["tmpincrease"])*(returndata["talentmod"]+returndata["tmpincrease"]) |
||
824 | returndata["talentbaseincreaseupfront"] = (1/returndata["tmpincreaseupfront"])*(returndata["talentmodupfront"]+returndata["tmpincreaseupfront"]) |
||
825 | if (spelldata.talentsbeforegear == nil) and (returndata["damcoef"]) then |
||
826 | returndata["damcoef"] = returndata["damcoef"]*returndata["talentbaseincrease"]*returndata["talentbaseincreaseupfront"] |
||
827 | end |
||
828 | if class == "DRUID" then |
||
829 | local _, bearform, catform |
||
830 | _, _, bearform = GetShapeshiftFormInfo(1) |
||
831 | _, _, catform = GetShapeshiftFormInfo(3) |
||
832 | if catform then |
||
833 | TheoryCraft_Data.EquipEffects["MeleeAPMult"] = 1 |
||
834 | TheoryCraft_Data.EquipEffects["MainSpeed"] = 1 |
||
835 | elseif bearform then |
||
836 | TheoryCraft_Data.EquipEffects["MeleeAPMult"] = 2.5 |
||
837 | TheoryCraft_Data.EquipEffects["MainSpeed"] = 2.5 |
||
838 | end |
||
839 | if (bearform) or (catform) then |
||
840 | local lowDmg, hiDmg, offlowDmg, offhiDmg, posBuff, negBuff, percentmod = UnitDamage("player") |
||
841 | local base, pos, neg = UnitAttackPower("player") |
||
842 | base = (base+pos+neg)/14*TheoryCraft_Data.EquipEffects["MeleeAPMult"] |
||
843 | TheoryCraft_Data.EquipEffects["MeleeMin"] = lowDmg-base |
||
844 | TheoryCraft_Data.EquipEffects["MeleeMax"] = hiDmg-lowDmg+TheoryCraft_Data.EquipEffects["MeleeMin"] |
||
845 | end |
||
846 | end |
||
847 | TheoryCraft_getMinMax(spelldata, returndata, frame) |
||
848 | if spelldata.cancrit then |
||
849 | if spelldata.drain then |
||
850 | returndata["critdmgchance"] = returndata["critchance"] |
||
851 | returndata["crithealchance"] = returndata["critchance"] |
||
852 | elseif spelldata.isheal then |
||
853 | returndata["crithealchance"] = returndata["critchance"] |
||
854 | else |
||
855 | returndata["critdmgchance"] = returndata["critchance"] |
||
856 | end |
||
857 | end |
||
858 | |||
859 | if spelldata.isheal == nil then |
||
860 | returndata["manacost"] = returndata["manacost"]-returndata["manacost"]*(TheoryCraft_Data.Talents["clearcast"] or 0) |
||
861 | end |
||
862 | if (returndata["manamultiplier"]) then |
||
863 | returndata["manacost"] = returndata["manacost"]*returndata["manamultiplier"] |
||
864 | end |
||
865 | returndata["manacost"] = returndata["manacost"]-TheoryCraft_Data.Stats["icregen"]*returndata["regencasttime"] |
||
866 | returndata["manacost"] = returndata["manacost"]*returndata["manacostmod"] |
||
867 | |||
868 | if (returndata["crithealchance"]) and (returndata["crithealchance"] > 100) then |
||
869 | returndata["crithealchance"] = 100 |
||
870 | end |
||
871 | if (returndata["critdmgchance"]) and (returndata["critdmgchance"] > 100) then |
||
872 | returndata["critdmgchance"] = 100 |
||
873 | end |
||
874 | |||
875 | if spelldata.dontusemelee then |
||
876 | returndata["critbonus"] = 0.5 |
||
877 | end |
||
878 | if (spelldata.isseal) or (spelldata.ismelee) or (spelldata.isranged) then |
||
879 | if (returndata["mindamage"] and returndata["maxdamage"] and (spelldata.isseal == nil)) and (spelldata.block == nil) then |
||
880 | returndata["critdmgmin"] = returndata["mindamage"]*(returndata["critbonus"]+1) |
||
881 | returndata["critdmgmax"] = returndata["maxdamage"]*(returndata["critbonus"]+1) |
||
882 | returndata["averagedamnocrit"] = (returndata["maxdamage"]+returndata["mindamage"])/2 |
||
883 | returndata["averagecritdam"] = returndata["averagedamnocrit"]*returndata["critbonus"] |
||
884 | returndata["averagedam"] = returndata["averagedamnocrit"]+returndata["averagecritdam"]*returndata["critdmgchance"]/100 |
||
885 | returndata["nextagidam"] = 10*TheoryCraft_Data.Talents["agimultiplier"] |
||
886 | if spelldata.ismelee then |
||
887 | if spelldata.nextattack then |
||
888 | local attackpower = 10*TheoryCraft_Data.Talents["agimultiplier"]*TheoryCraft_Data.Stats["agilityapmelee"] |
||
889 | local addeddamage = attackpower*(TheoryCraft_Data.EquipEffects["MainSpeed"])*returndata["backstabmult"]*returndata["baseincrease"]*TheoryCraft_GetStat("Meleemodifier")/14 |
||
890 | local addedcritpercent = 10*TheoryCraft_Data.Talents["agimultiplier"]/TheoryCraft_Data.Stats["agipercrit"]/100 |
||
891 | returndata["nextagidam"] = addedcritpercent*returndata["averagecritdam"]+addeddamage*(addedcritpercent+returndata["critdmgchance"]/100)*returndata["critbonus"]+addeddamage |
||
892 | returndata["damworth"] = (1+(returndata["critchance"]/100)*returndata["critbonus"])*(TheoryCraft_Data.EquipEffects["MainSpeed"])/14*returndata["backstabmult"]*returndata["baseincrease"]*TheoryCraft_GetStat("Meleemodifier") |
||
893 | elseif returndata["bloodthirstmult"] then |
||
894 | local attackpower = 10*TheoryCraft_Data.Talents["agimultiplier"]*TheoryCraft_Data.Stats["agilityapmelee"] |
||
895 | local addeddamage = attackpower*returndata["bloodthirstmult"]*returndata["backstabmult"]*returndata["baseincrease"]*TheoryCraft_GetStat("Meleemodifier")/14 |
||
896 | local addedcritpercent = 10*TheoryCraft_Data.Talents["agimultiplier"]/TheoryCraft_Data.Stats["agipercrit"]/100 |
||
897 | returndata["nextagidam"] = addedcritpercent*returndata["averagecritdam"]+addeddamage*(addedcritpercent+returndata["critdmgchance"]/100)*returndata["critbonus"]+addeddamage |
||
898 | returndata["damworth"] = (1+(returndata["critchance"]/100)*returndata["critbonus"])*returndata["bloodthirstmult"]*returndata["backstabmult"]*returndata["baseincrease"]*TheoryCraft_GetStat("Meleemodifier") |
||
899 | else |
||
900 | local attackpower = 10*TheoryCraft_Data.Talents["agimultiplier"]*TheoryCraft_Data.Stats["agilityapmelee"] |
||
901 | local addeddamage = attackpower*TheoryCraft_Data.EquipEffects["MeleeAPMult"]*returndata["backstabmult"]*returndata["baseincrease"]*TheoryCraft_GetStat("Meleemodifier")/14 |
||
902 | local addedcritpercent = 10*TheoryCraft_Data.Talents["agimultiplier"]/TheoryCraft_Data.Stats["agipercrit"]/100 |
||
903 | returndata["nextagidam"] = addedcritpercent*returndata["averagecritdam"]+addeddamage*(addedcritpercent+returndata["critdmgchance"]/100)*returndata["critbonus"]+addeddamage |
||
904 | returndata["damworth"] = (1+(returndata["critchance"]/100)*returndata["critbonus"])*TheoryCraft_Data.EquipEffects["MeleeAPMult"]/14*returndata["backstabmult"]*returndata["baseincrease"]*TheoryCraft_GetStat("Meleemodifier") |
||
905 | end |
||
906 | returndata["nextstrdam"] = 10*TheoryCraft_Data.Talents["strmultiplier"]*TheoryCraft_Data.Stats["strengthapmelee"]*returndata["damworth"] |
||
907 | else |
||
908 | local attackpower = 10*TheoryCraft_Data.Talents["agimultiplier"]*TheoryCraft_Data.Stats["agilityapranged"] |
||
909 | local addeddamage = attackpower*returndata["RangedAPMult"]*returndata["backstabmult"]*returndata["baseincrease"]*TheoryCraft_GetStat("Rangedmodifier")/14 |
||
910 | local addedcritpercent = 10*TheoryCraft_Data.Talents["agimultiplier"]/TheoryCraft_Data.Stats["agipercrit"]/100 |
||
911 | returndata["nextagidam"] = addedcritpercent*returndata["averagecritdam"]+addeddamage*(addedcritpercent+returndata["critdmgchance"]/100)*returndata["critbonus"]+addeddamage |
||
912 | returndata["damworth"] = (1+(returndata["critchance"]/100)*returndata["critbonus"])*returndata["RangedAPMult"]/14*returndata["backstabmult"]*returndata["baseincrease"]*TheoryCraft_GetStat("Rangedmodifier") |
||
913 | end |
||
914 | |||
915 | returndata["nextcritdam"] = returndata["averagecritdam"]/100 |
||
916 | returndata["nexthitdam"] = returndata["averagedamnocrit"]/100 |
||
917 | if (returndata["damworth"] ~= 0) then |
||
918 | if returndata["nextstrdam"] then |
||
919 | returndata["nextstrdamequive"] = returndata["nextstrdam"]/returndata["damworth"] |
||
920 | end |
||
921 | returndata["nexthitdamequive"] = returndata["nexthitdam"]/returndata["damworth"] |
||
922 | returndata["nextcritdamequive"] = returndata["nextcritdam"]/returndata["damworth"] |
||
923 | returndata["nextagidamequive"] = returndata["nextagidam"]/returndata["damworth"] |
||
924 | end |
||
925 | if (spelldata.isranged) and (spelldata.shoot == nil) then |
||
926 | if (spelldata.autoshot) then |
||
927 | returndata["dpm"] = returndata["msrotationlength"]*returndata["msrotationdps"]/returndata["manacost"] |
||
928 | returndata["maxoomdam"] = (TheoryCraft_Data.Stats["totalmana"]+TheoryCraft_GetStat("manarestore"))*returndata["dpm"] |
||
929 | returndata["maxoomdamtime"] = returndata["maxoomdam"]/returndata["dps"] |
||
930 | returndata["regendam"] = TheoryCraft_Data.Stats["regen"]*10*returndata["dpm"] |
||
931 | returndata["icregendam"] = TheoryCraft_Data.Stats["icregen"]*10*returndata["dpm"] |
||
932 | else |
||
933 | if TheoryCraft_Settings["dontcritdpm"] then |
||
934 | returndata["dpm"] = returndata["averagedamnocrit"]/returndata["manacost"] |
||
935 | else |
||
936 | returndata["dpm"] = returndata["averagedam"]/returndata["manacost"] |
||
937 | end |
||
938 | returndata["regendam"] = TheoryCraft_Data.Stats["regen"]*10*returndata["dpm"] |
||
939 | returndata["icregendam"] = TheoryCraft_Data.Stats["icregen"]*10*returndata["dpm"] |
||
940 | end |
||
941 | end |
||
942 | end |
||
943 | else |
||
944 | if class == "DRUID" then |
||
945 | if (spelldata.cancrit) and (returndata["grace"] ~= 0) and (not TheoryCraft_Settings["dontcrit"]) then |
||
946 | returndata["casttime"] = returndata["casttime"]-(returndata["critchance"]/100)*returndata["grace"] |
||
947 | if returndata["casttime"] < 1.5 then |
||
948 | returndata["casttime"] = 1.5 |
||
949 | end |
||
950 | end |
||
951 | end |
||
952 | if (class == "MAGE") then |
||
953 | if (returndata["critdmgchance"]) and (not TheoryCraft_Settings["dontcrit"]) then |
||
954 | returndata["manacost"] = returndata["manacost"]-returndata["manacost"]*((returndata["critdmgchance"]/100)*returndata["illum"]) |
||
955 | end |
||
956 | end |
||
957 | |||
958 | if returndata["mindamage"] then |
||
959 | if returndata["maxdamage"] == nil then |
||
960 | returndata["maxdamage"] = returndata["mindamage"] |
||
961 | end |
||
962 | returndata["critdmgmin"] = returndata["mindamage"]*(returndata["critbonus"]+1) |
||
963 | returndata["critdmgmax"] = returndata["maxdamage"]*(returndata["critbonus"]+1) |
||
964 | returndata["averagedamnocrit"] = (returndata["maxdamage"]+returndata["mindamage"])/2 |
||
965 | returndata["averagedpsdamnocrit"] = returndata["damfinal"] |
||
966 | if spelldata.cancrit then |
||
967 | returndata["critdmgmin"] = returndata["mindamage"]*(returndata["critbonus"]+1) |
||
968 | returndata["critdmgmax"] = returndata["maxdamage"]*(returndata["critbonus"]+1) |
||
969 | if (returndata["sepignite"] ~= 0) then |
||
970 | returndata["critdmgminminusignite"] = ((returndata["critdmgmin"]/(returndata["critbonus"]+1))*(1+returndata["critbonus"]-returndata["sepignite"])) |
||
971 | returndata["critdmgmaxminusignite"] = ((returndata["critdmgmax"]/(returndata["critbonus"]+1))*(1+returndata["critbonus"]-returndata["sepignite"])) |
||
972 | end |
||
973 | |||
974 | if (TheoryCraft_Settings["rollignites"]) and (not spelldata.dontdomax) and (returndata["sepignite"] ~= 0) and (returndata["critdmgchance"] < 99) then |
||
975 | local ignitecritmin = returndata["critdmgmin"]-(returndata["critdmgmin"]/(returndata["critbonus"]+1))*(1+returndata["critbonus"]-returndata["sepignite"]) |
||
976 | local ignitecritmax = returndata["critdmgmax"]-(returndata["critdmgmax"]/(returndata["critbonus"]+1))*(1+returndata["critbonus"]-returndata["sepignite"]) |
||
977 | local igniteaverage = (ignitecritmax-ignitecritmin)/2+ignitecritmin |
||
978 | local noignitecritmin = returndata["critdmgmin"]-ignitecritmin-returndata["mindamage"] |
||
979 | local noignitecritmax = returndata["critdmgmax"]-ignitecritmax-returndata["maxdamage"] |
||
980 | local noigniteaverage = (noignitecritmin+noignitecritmax)/2 |
||
981 | local rollchance = (returndata["critdmgchance"]/100) |
||
982 | local ignitelength = 4+rollchance*4+(rollchance^2)*4+(rollchance^3)*4+(rollchance^4)*4+(rollchance^5)*4+(rollchance^6)*4 |
||
983 | returndata["averagecritdam"] = noigniteaverage+ignitelength*igniteaverage/4 |
||
984 | rollchance = ((returndata["critdmgchance"]+1)/100) |
||
985 | local newignitelength = 4+rollchance*4+(rollchance^2)*4+(rollchance^3)*4+(rollchance^4)*4+(rollchance^5)*4+(rollchance^6)*4 |
||
986 | -- Average Crit Damage |
||
987 | returndata["nextcritdam"] = noigniteaverage+newignitelength*igniteaverage/4 |
||
988 | -- Damage from extra ignite length |
||
989 | returndata["nextcritdam"] = (returndata["nextcritdam"]+(newignitelength-ignitelength)*igniteaverage/4*returndata["critdmgchance"])/100 |
||
990 | else |
||
991 | returndata["averagecritdam"] = returndata["averagedamnocrit"]*returndata["critbonus"] |
||
992 | returndata["nextcritdam"] = returndata["averagecritdam"]/100 |
||
993 | end |
||
994 | returndata["damhitworth"] = returndata["damcoef"] |
||
995 | returndata["damcritworth"] = returndata["damcoef"]*(returndata["critbonus"]+1) |
||
996 | returndata["damworth"] = returndata["damcoef"]*(1+returndata["critdmgchance"]*returndata["critbonus"]/100) |
||
997 | returndata["averagedam"] = returndata["averagedamnocrit"]+returndata["averagecritdam"]*returndata["critdmgchance"]/100 |
||
998 | returndata["nextcritdam"] = returndata["nextcritdam"] + returndata["averagedam"]*returndata["grace"] |
||
999 | returndata["nextcritdamequive"] = returndata["nextcritdam"]/returndata["damworth"] |
||
1000 | else |
||
1001 | returndata["averagecritdam"] = 0 |
||
1002 | returndata["averagedam"] = returndata["averagedamnocrit"] |
||
1003 | returndata["damhitworth"] = returndata["damcoef"] |
||
1004 | returndata["damcritworth"] = 0 |
||
1005 | returndata["damworth"] = returndata["damcoef"] |
||
1006 | end |
||
1007 | returndata["averagedamthreat"] = returndata["averagedam"]*returndata["threat"] |
||
1008 | returndata["averagedamthreatpercent"] = returndata["averagedamthreat"]/returndata["averagedam"]*100 |
||
1009 | if (not TheoryCraft_Settings["dontcrit"]) then |
||
1010 | returndata["averagedpsdam"] = returndata["averagedpsdamnocrit"]*(returndata["averagedam"]/returndata["averagedamnocrit"]) |
||
1011 | else |
||
1012 | returndata["averagedpsdam"] = returndata["averagedpsdamnocrit"] |
||
1013 | end |
||
1014 | if spelldata.tickinterval then |
||
1015 | if (spelldata.hasdot) and (returndata["dotdamage"]) then |
||
1016 | returndata["averagedamtick"] = returndata["dotdamage"]/returndata["dotduration"]*spelldata.tickinterval |
||
1017 | returndata["averagedamticknocrit"] = returndata["dotdamage"]/returndata["dotduration"]*spelldata.tickinterval |
||
1018 | else |
||
1019 | if returndata["manamultiplier"] then |
||
1020 | if (TheoryCraft_Settings["dontcrit"]) then |
||
1021 | returndata["averagedamtick"] = returndata["averagedamnocrit"]/returndata["manamultiplier"]/returndata["dotduration"]*spelldata.tickinterval |
||
1022 | else |
||
1023 | returndata["averagedamtick"] = returndata["averagedam"]/returndata["manamultiplier"]/returndata["dotduration"]*spelldata.tickinterval |
||
1024 | end |
||
1025 | else |
||
1026 | if (TheoryCraft_Settings["dontcrit"]) then |
||
1027 | returndata["averagedamtick"] = returndata["averagedamnocrit"]/returndata["dotduration"]*spelldata.tickinterval |
||
1028 | else |
||
1029 | returndata["averagedamtick"] = returndata["averagedam"]/returndata["dotduration"]*spelldata.tickinterval |
||
1030 | end |
||
1031 | end |
||
1032 | end |
||
1033 | end |
||
1034 | if spelldata.coa then |
||
1035 | local tick1 = round((returndata["averagedam"]-returndata["damfinal"]*returndata["baseincrease"])/24+returndata["damfinal"]*returndata["baseincrease"]/12) |
||
1036 | local tick2 = round((returndata["averagedam"]-returndata["damfinal"]*returndata["baseincrease"])/12+returndata["damfinal"]*returndata["baseincrease"]/12) |
||
1037 | local tick3 = round((returndata["averagedam"]-returndata["damfinal"]*returndata["baseincrease"])/8+returndata["damfinal"]*returndata["baseincrease"]/12) |
||
1038 | returndata["averagedamtick"] = tick1..", "..tick2..", "..tick3 |
||
1039 | end |
||
1040 | if spelldata.starshards then |
||
1041 | local tick1 = round((returndata["averagedam"]-returndata["damfinal"]*returndata["baseincrease"])/10+returndata["damfinal"]*returndata["baseincrease"]/6) |
||
1042 | local tick2 = round((returndata["averagedam"]-returndata["damfinal"]*returndata["baseincrease"])/6+returndata["damfinal"]*returndata["baseincrease"]/6) |
||
1043 | local tick3 = round((returndata["averagedam"]-returndata["damfinal"]*returndata["baseincrease"])/4.5+returndata["damfinal"]*returndata["baseincrease"]/6) |
||
1044 | returndata["averagedamtick"] = tick1..", "..tick2..", "..tick3 |
||
1045 | end |
||
1046 | if (TheoryCraft_Settings["dontcrit"]) then |
||
1047 | returndata["dpm"] = returndata["averagedamnocrit"]/returndata["manacost"] |
||
1048 | else |
||
1049 | returndata["dpm"] = returndata["averagedam"]/returndata["manacost"] |
||
1050 | end |
||
1051 | if (TheoryCraft_Data.Stats["lifetapMana"]) and (TheoryCraft_Data.Stats["lifetapHealth"]) then |
||
1052 | returndata["lifetapdpm"] = returndata["dpm"]*returndata["manacost"]/(returndata["manacost"]/TheoryCraft_Data.Stats["lifetapMana"]*TheoryCraft_Data.Stats["lifetapHealth"]) |
||
1053 | end |
||
1054 | if (spelldata.overcooldown) then |
||
1055 | if (TheoryCraft_Settings["dontcrit"]) then |
||
1056 | returndata["dps"] = returndata["averagedamnocrit"]/getcooldown(frame) |
||
1057 | else |
||
1058 | returndata["dps"] = returndata["averagedam"]/getcooldown(frame) |
||
1059 | end |
||
1060 | returndata["dpsdam"] = returndata["averagedpsdam"]/getcooldown(frame) |
||
1061 | else |
||
1062 | if (TheoryCraft_Settings["dotoverct"]) and (spelldata.isdot) then |
||
1063 | if (TheoryCraft_Settings["dontcrit"]) then |
||
1064 | returndata["dps"] = returndata["averagedamnocrit"]/returndata["casttime"] |
||
1065 | else |
||
1066 | returndata["dps"] = returndata["averagedam"]/returndata["casttime"] |
||
1067 | end |
||
1068 | returndata["dpsdam"] = returndata["averagedpsdam"]/returndata["casttime"] |
||
1069 | else |
||
1070 | if spelldata.isdot then |
||
1071 | if (TheoryCraft_Settings["dontcrit"]) then |
||
1072 | returndata["dps"] = returndata["averagedamnocrit"]/returndata["dotduration"] |
||
1073 | else |
||
1074 | returndata["dps"] = returndata["averagedam"]/returndata["dotduration"] |
||
1075 | end |
||
1076 | returndata["dpsdam"] = returndata["averagedpsdam"]/returndata["dotduration"] |
||
1077 | else |
||
1078 | if (TheoryCraft_Settings["dontcrit"]) then |
||
1079 | returndata["dps"] = returndata["averagedamnocrit"]/returndata["casttime"] |
||
1080 | else |
||
1081 | returndata["dps"] = returndata["averagedam"]/returndata["casttime"] |
||
1082 | end |
||
1083 | returndata["dpsdam"] = returndata["averagedpsdam"]/returndata["casttime"] |
||
1084 | if TheoryCraft_Data.Stats["lifetapMana"] then |
||
1085 | if (TheoryCraft_Settings["dontcrit"]) then |
||
1086 | returndata["lifetapdps"] = returndata["averagedamnocrit"]/(returndata["casttime"]+(returndata["manacost"]/TheoryCraft_Data.Stats["lifetapMana"])*1.5) |
||
1087 | else |
||
1088 | returndata["lifetapdps"] = returndata["averagedam"]/(returndata["casttime"]+(returndata["manacost"]/TheoryCraft_Data.Stats["lifetapMana"])*1.5) |
||
1089 | end |
||
1090 | end |
||
1091 | end |
||
1092 | end |
||
1093 | end |
||
1094 | |||
1095 | if returndata["dotdamage"] then |
||
1096 | returndata["withdotdpm"] = (returndata["dpm"]*returndata["manacost"]+returndata["dotdamage"])/returndata["manacost"] |
||
1097 | if (TheoryCraft_Settings["combinedot"]) then |
||
1098 | if (TheoryCraft_Settings["dontcrit"]) then |
||
1099 | returndata["withdotdps"] = (returndata["averagedamnocrit"]+returndata["dotdamage"])/returndata["casttime"] |
||
1100 | else |
||
1101 | returndata["withdotdps"] = (returndata["averagedam"]+returndata["dotdamage"])/returndata["casttime"] |
||
1102 | end |
||
1103 | else |
||
1104 | returndata["withdotdps"] = returndata["dotdamage"]/returndata["dotduration"] |
||
1105 | end |
||
1106 | end |
||
1107 | |||
1108 | if spelldata.isdot then |
||
1109 | returndata["dameff"] = returndata["damcoef"]*returndata["baseincrease"]/returndata["dotduration"]*3.5 |
||
1110 | else |
||
1111 | if returndata["damcoef2"] then |
||
1112 | returndata["dameff"] = ((returndata["damcoef"]+returndata["damcoef2"])*returndata["baseincrease"])/returndata["casttime"]*3.5 |
||
1113 | else |
||
1114 | returndata["dameff"] = returndata["damcoef"]*returndata["baseincrease"]/returndata["casttime"]*3.5 |
||
1115 | end |
||
1116 | end |
||
1117 | if spelldata.dontdomax == nil then |
||
1118 | returndata["maxoomdam"] = (TheoryCraft_Data.Stats["totalmana"]+TheoryCraft_GetStat("manarestore"))*returndata["dpm"] |
||
1119 | returndata["maxoomdamtime"] = returndata["maxoomdam"]/returndata["dps"] |
||
1120 | if TheoryCraft_Data.Stats["maxtotalmana"] then |
||
1121 | returndata["maxevocoomdam"] = (TheoryCraft_Data.Stats["maxtotalmana"]+TheoryCraft_GetStat("manarestore"))*returndata["dpm"] |
||
1122 | returndata["maxevocoomdamtime"] = returndata["maxevocoomdam"]/returndata["dps"]+8 |
||
1123 | end |
||
1124 | end |
||
1125 | if (spelldata.isdot == nil) then |
||
1126 | returndata["nexthitdam"] = returndata["averagedamnocrit"]/100 |
||
1127 | returndata["nexthitdamequive"] = returndata["nexthitdam"]/returndata["damworth"] |
||
1128 | end |
||
1129 | returndata["nextpendam"] = returndata["averagedam"]*UnitLevel("player")/2400 |
||
1130 | returndata["nextpendamequive"] = returndata["nextpendam"]/returndata["damworth"] |
||
1131 | returndata["regendam"] = TheoryCraft_Data.Stats["regen"]*10*returndata["dpm"] |
||
1132 | returndata["icregendam"] = TheoryCraft_Data.Stats["icregen"]*10*returndata["dpm"] |
||
1133 | returndata["penetration"] = returndata["penetration"]/((20/3)*UnitLevel("player"))*returndata["dps"] |
||
1134 | if (returndata["manamultiplier"]) and (spelldata.lightningshield == nil) then |
||
1135 | returndata["averagedam"] = returndata["averagedam"]/returndata["manamultiplier"] |
||
1136 | returndata["averagedamnocrit"] = returndata["averagedamnocrit"]/returndata["manamultiplier"] |
||
1137 | returndata["averagedamthreat"] = returndata["averagedamthreat"]/returndata["manamultiplier"] |
||
1138 | end |
||
1139 | end |
||
1140 | |||
1141 | if (returndata["minheal"]) then |
||
1142 | if (class == "PALADIN") or (class == "MAGE") then |
||
1143 | if (returndata["crithealchance"]) then |
||
1144 | if (returndata["illum"] ~= 0) and (returndata["mindamage"]) then |
||
1145 | returndata["manacost2"] = returndata["manacost"] |
||
1146 | end |
||
1147 | returndata["manacost"] = returndata["manacost"]-returndata["manacost"]*((returndata["crithealchance"]/100)*returndata["illum"]) |
||
1148 | end |
||
1149 | end |
||
1150 | if returndata["maxheal"] == nil then |
||
1151 | returndata["maxheal"] = returndata["minheal"] |
||
1152 | end |
||
1153 | returndata["averagehealnocrit"] = (returndata["maxheal"]-returndata["minheal"])/2+returndata["minheal"] |
||
1154 | returndata["averagehpsdamnocrit"] = returndata["damfinal"] |
||
1155 | if spelldata.cancrit then |
||
1156 | if returndata["crithealchance"] == nil then returndata["crithealchance"] = 0 end |
||
1157 | returndata["crithealmin"] = returndata["minheal"]*(returndata["critbonus"]+1) |
||
1158 | returndata["crithealmax"] = returndata["maxheal"]*(returndata["critbonus"]+1) |
||
1159 | returndata["averagecritheal"] = returndata["averagehealnocrit"]*returndata["critbonus"] |
||
1160 | returndata["nextcrit"] = returndata["averagecritheal"]/100 |
||
1161 | returndata["healworth"] = returndata["damcoef"]*(1+returndata["crithealchance"]*returndata["critbonus"]/100) |
||
1162 | returndata["averageheal"] = returndata["averagehealnocrit"]+returndata["averagecritheal"]*returndata["crithealchance"]/100 |
||
1163 | returndata["nextcritheal"] = returndata["averagecritheal"]/100 |
||
1164 | returndata["nextcrithealequive"] = returndata["nextcritheal"]/returndata["healworth"] |
||
1165 | else |
||
1166 | returndata["averagecritheal"] = 0 |
||
1167 | returndata["averageheal"] = returndata["averagehealnocrit"] |
||
1168 | returndata["healworth"] = returndata["damcoef"] |
||
1169 | end |
||
1170 | returndata["averagehealthreat"] = returndata["averageheal"]*returndata["threat"] |
||
1171 | returndata["averagehealthreatpercent"] = returndata["averagehealthreat"]/returndata["averageheal"]*100 |
||
1172 | returndata["averagehpsdam"] = returndata["averagehpsdamnocrit"]*(returndata["averageheal"]/returndata["averagehealnocrit"]) |
||
1173 | if spelldata.tickinterval then |
||
1174 | if (spelldata.hasdot) and (returndata["hotheal"]) then |
||
1175 | returndata["averagehealtick"] = returndata["hotheal"]/returndata["dotduration"]*spelldata.tickinterval |
||
1176 | else |
||
1177 | if returndata["manamultiplier"] then |
||
1178 | returndata["averagehealtick"] = returndata["averageheal"]/returndata["manamultiplier"]/returndata["dotduration"]*spelldata.tickinterval |
||
1179 | else |
||
1180 | returndata["averagehealtick"] = returndata["averageheal"]/returndata["dotduration"]*spelldata.tickinterval |
||
1181 | end |
||
1182 | end |
||
1183 | end |
||
1184 | if TheoryCraft_Settings["dontcrithpm"] then |
||
1185 | returndata["hpm"] = returndata["averagehealnocrit"]/returndata["manacost"] |
||
1186 | else |
||
1187 | returndata["hpm"] = returndata["averageheal"]/returndata["manacost"] |
||
1188 | end |
||
1189 | if (TheoryCraft_Data.Stats["lifetapMana"]) and (TheoryCraft_Data.Stats["lifetapHealth"]) then |
||
1190 | returndata["lifetaphpm"] = returndata["hpm"]*returndata["manacost"]/(returndata["manacost"]/TheoryCraft_Data.Stats["lifetapMana"]*TheoryCraft_Data.Stats["lifetapHealth"]) |
||
1191 | end |
||
1192 | if (TheoryCraft_Settings["dotoverct"]) and (spelldata.isdot) then |
||
1193 | returndata["hps"] = returndata["averageheal"]/returndata["casttime"] |
||
1194 | returndata["hpsdam"] = returndata["averagehpsdam"]/returndata["casttime"] |
||
1195 | else |
||
1196 | if spelldata.isdot then |
||
1197 | returndata["hps"] = returndata["averageheal"]/returndata["dotduration"] |
||
1198 | returndata["hpsdam"] = returndata["averagehpsdam"]/returndata["dotduration"] |
||
1199 | else |
||
1200 | returndata["hps"] = returndata["averageheal"]/returndata["casttime"] |
||
1201 | returndata["hpsdam"] = returndata["averagehpsdam"]/returndata["casttime"] |
||
1202 | end |
||
1203 | end |
||
1204 | if TheoryCraft_Data.Stats["lifetapMana"] then |
||
1205 | returndata["lifetaphps"] = returndata["averageheal"]/(returndata["casttime"]+(returndata["manacost"]/TheoryCraft_Data.Stats["lifetapMana"])*1.5) |
||
1206 | end |
||
1207 | |||
1208 | if returndata["hotheal"] then |
||
1209 | returndata["withhothpm"] = (returndata["hpm"]*returndata["manacost"]+returndata["hotheal"])/returndata["manacost"] |
||
1210 | if (TheoryCraft_Settings["combinedot"]) then |
||
1211 | returndata["withhothps"] = (returndata["averageheal"]+returndata["hotheal"])/returndata["casttime"] |
||
1212 | else |
||
1213 | returndata["withhothps"] = returndata["hotheal"]/returndata["dotduration"] |
||
1214 | end |
||
1215 | end |
||
1216 | |||
1217 | if spelldata.isdot then |
||
1218 | returndata["dameff"] = returndata["damcoef"]*returndata["baseincrease"]/returndata["dotduration"]*3.5 |
||
1219 | else |
||
1220 | if returndata["damcoef2"] then |
||
1221 | returndata["dameff"] = ((returndata["damcoef"]+returndata["damcoef2"])*returndata["baseincrease"])/returndata["casttime"]*3.5 |
||
1222 | else |
||
1223 | returndata["dameff"] = returndata["damcoef"]*returndata["baseincrease"]/returndata["casttime"]*3.5 |
||
1224 | end |
||
1225 | end |
||
1226 | if spelldata.dontdomax == nil then |
||
1227 | returndata["maxoomheal"] = (TheoryCraft_Data.Stats["totalmana"]+TheoryCraft_GetStat("manarestore"))*returndata["hpm"] |
||
1228 | returndata["maxoomhealtime"] = returndata["maxoomheal"]/returndata["hps"] |
||
1229 | if returndata["maxtotalmana"] then |
||
1230 | returndata["maxevocoomheal"] = TheoryCraft_Data.Stats["maxtotalmana"]*returndata["hpm"] |
||
1231 | returndata["maxevocoomhealtime"] = returndata["maxevocoomheal"]/returndata["hps"]+8 |
||
1232 | end |
||
1233 | end |
||
1234 | returndata["regenheal"] = TheoryCraft_Data.Stats["regen"]*10*returndata["hpm"] |
||
1235 | returndata["icregenheal"] = TheoryCraft_Data.Stats["icregen"]*10*returndata["hpm"] |
||
1236 | if returndata["manamultiplier"] then |
||
1237 | returndata["averageheal"] = returndata["averageheal"]/returndata["manamultiplier"] |
||
1238 | returndata["averagehealnocrit"] = returndata["averagehealnocrit"]/returndata["manamultiplier"] |
||
1239 | returndata["averagehealthreat"] = returndata["averagehealthreat"]/returndata["manamultiplier"] |
||
1240 | end |
||
1241 | end |
||
1242 | end |
||
1243 | if (returndata["dps"]) then |
||
1244 | if (returndata["dpsdam"]) then |
||
1245 | returndata["dpsdampercent"] = returndata["dpsdam"]/returndata["dps"]*100 |
||
1246 | end |
||
1247 | end |
||
1248 | if (returndata["hps"]) then |
||
1249 | if (returndata["hpsdam"]) then |
||
1250 | returndata["hpsdampercent"] = returndata["hpsdam"]/returndata["hps"]*100 |
||
1251 | end |
||
1252 | end |
||
1253 | if (returndata["manamultiplier"]) then |
||
1254 | returndata["manacost"] = returndata["manacost"]/returndata["manamultiplier"] |
||
1255 | end |
||
1256 | if (spelldata.manamultiplier) and (returndata["damcoef"]) and (spelldata.lightningshield == nil) then |
||
1257 | returndata["damcoef"] = returndata["damcoef"]/spelldata.manamultiplier |
||
1258 | end |
||
1259 | |||
1260 | if (returndata["nextcritdam"]) and (returndata["critdmgchance"]) and (returndata["critdmgchance"] > 99) then |
||
1261 | if returndata["critdmgchance"] < 100 then |
||
1262 | returndata["nextcritdam"] = returndata["nextcritdam"]*(1 - (returndata["critdmgchance"] - 99)) |
||
1263 | returndata["nextcritdamequive"] = returndata["nextcritdamequive"]*(1 - (returndata["critdmgchance"] - 99)) |
||
1264 | else |
||
1265 | returndata["nextcritdam"] = 0 |
||
1266 | returndata["nextcritdamequive"] = 0 |
||
1267 | end |
||
1268 | end |
||
1269 | if (returndata["nextcritheal"]) and (returndata["crithealchance"]) and (returndata["crithealchance"] > 99) then |
||
1270 | if returndata["crithealchance"] < 100 then |
||
1271 | returndata["nextcritheal"] = returndata["nextcritheal"]*(1 - (returndata["crithealchance"] - 99)) |
||
1272 | returndata["nextcrithealequive"] = returndata["nextcrithealequive"]*(1 - (returndata["crithealchance"] - 99)) |
||
1273 | else |
||
1274 | returndata["nextcritheal"] = 0 |
||
1275 | returndata["nextcrithealequive"] = 0 |
||
1276 | end |
||
1277 | end |
||
1278 | |||
1279 | CleanUp(spelldata, returndata) |
||
1280 | |||
1281 | if returndata["basemindamage"] then |
||
1282 | if returndata["basemaxdamage"] == nil then |
||
1283 | returndata["basemaxdamage"] = returndata["basemindamage"] |
||
1284 | end |
||
1285 | returndata["damtodouble"] = (returndata["basemindamage"]+returndata["basemaxdamage"])/2/returndata["damcoef"] |
||
1286 | end |
||
1287 | |||
1288 | if returndata["damcoef"] then returndata["damcoef"] = returndata["damcoef"]*100 end |
||
1289 | if returndata["dameff"] then returndata["dameff"] = returndata["dameff"]*100 end |
||
1290 | |||
1291 | if returndata["dps"] and returndata["manacost"] then |
||
1292 | returndata["dpsmana"] = returndata["dps"]/returndata["manacost"] |
||
1293 | end |
||
1294 | if returndata["manacost"] then |
||
1295 | returndata["maxspellcasts"] = 1+math.floor((TheoryCraft_GetStat("totalmana")-(returndata["basemanacost"] or returndata["manacost"]))/returndata["manacost"]) |
||
1296 | if returndata["maxoomdam"] then |
||
1297 | returndata["maxoomdamfloored"] = returndata["dpm"]*returndata["manacost"]*returndata["maxspellcasts"] |
||
1298 | end |
||
1299 | if returndata["maxoomheal"] then |
||
1300 | returndata["maxoomhealfloored"] = returndata["hpm"]*returndata["manacost"]*returndata["maxspellcasts"] |
||
1301 | end |
||
1302 | end |
||
1303 | |||
1304 | return |
||
1305 | end |
||
1306 | |||
1307 | function TheoryCraft_GenerateTooltip(frame, spellname, spellrank, i2, showonbutton, macro, force) |
||
1308 | local timer = GetTime() |
||
1309 | local oldspellname = spellname |
||
1310 | local olddesc |
||
1311 | if i2 == nil then |
||
1312 | if (frame) and (frame ~= TCTooltip2) then |
||
1313 | if frame:NumLines() == 0 then return end |
||
1314 | i2 = 1 |
||
1315 | if getglobal(frame:GetName().."TextRight1") and getglobal(frame:GetName().."TextRight1"):IsVisible() then |
||
1316 | spellrank = getglobal(frame:GetName().."TextRight1"):GetText() |
||
1317 | spellrank = tonumber(findpattern(spellrank, "%d+")) |
||
1318 | if spellrank == nil then spellrank = 0 end |
||
1319 | else |
||
1320 | spellrank = nil |
||
1321 | end |
||
1322 | if getglobal(frame:GetName().."TextLeft1") and getglobal(frame:GetName().."TextLeft1"):GetText() then |
||
1323 | spellname = getglobal(frame:GetName().."TextLeft1"):GetText() |
||
1324 | else |
||
1325 | spellname = "" |
||
1326 | end |
||
1327 | local spellname2, spellrank2 |
||
1328 | while (true) do |
||
1329 | spellname2, spellrank2 = GetSpellName(i2,BOOKTYPE_SPELL) |
||
1330 | if spellname2 == nil then return end |
||
1331 | spellrank2 = tonumber(findpattern(spellrank2, "%d+")) |
||
1332 | if spellrank2 == nil then spellrank2 = 0 end |
||
1333 | if (spellname == spellname2) and ((spellrank == nil) or (spellrank == spellrank2)) then break end |
||
1334 | i2 = i2 + 1 |
||
1335 | end |
||
1336 | if spellname ~= spellname2 then return end |
||
1337 | if (spellrank) and (spellrank ~= spellrank2) then return end |
||
1338 | if (spellname == "Attack") then spellrank = 0 end |
||
1339 | if (spellrank == nil) then |
||
1340 | olddesc = getglobal(frame:GetName().."TextLeft"..frame:NumLines()):GetText() |
||
1341 | while (spellname == spellname2) do |
||
1342 | spellname2, spellrank = GetSpellName(i2,BOOKTYPE_SPELL) |
||
1343 | if spellname == nil then return end |
||
1344 | spellrank = tonumber(findpattern(spellrank, "%d+")) |
||
1345 | if spellrank == nil then spellrank = 0 end |
||
1346 | TCTooltip:SetOwner(UIParent,"ANCHOR_NONE") |
||
1347 | TCTooltip:SetSpell(i2,BOOKTYPE_SPELL) |
||
1348 | if (getglobal("TCTooltipTextLeft"..TCTooltip:NumLines())) and (getglobal("TCTooltipTextLeft"..TCTooltip:NumLines()):GetText() == olddesc) then |
||
1349 | break |
||
1350 | end |
||
1351 | i2 = i2 + 1 |
||
1352 | end |
||
1353 | if (TCTooltip) and (getglobal("TCTooltipTextLeft"..TCTooltip:NumLines())) and (getglobal("TCTooltipTextLeft"..TCTooltip:NumLines()):GetText() ~= olddesc) then |
||
1354 | return |
||
1355 | end |
||
1356 | end |
||
1357 | else |
||
1358 | i2 = 1 |
||
1359 | local spellname2, spellrank2 |
||
1360 | if (string.len(spellrank) == 1) and (string.len(spellname) ~= 13) then |
||
1361 | macro = nil |
||
1362 | end |
||
1363 | if (string.len(spellrank) == 2) and (string.len(spellname) ~= 12) then |
||
1364 | macro = nil |
||
1365 | end |
||
1366 | while (true) do |
||
1367 | spellname2, spellrank2 = GetSpellName(i2,BOOKTYPE_SPELL) |
||
1368 | if spellname2 == nil then return end |
||
1369 | spellrank2 = tonumber(findpattern(spellrank2, "%d+")) |
||
1370 | if spellrank2 == nil then spellrank2 = 0 end |
||
1371 | if (spellname == spellname2) or ((macro) and (spellname == string.sub(spellname2, 1, string.len(spellname)))) then |
||
1372 | spellname = spellname2 |
||
1373 | if spellrank == spellrank2 then |
||
1374 | break |
||
1375 | end |
||
1376 | end |
||
1377 | i2 = i2 + 1 |
||
1378 | end |
||
1379 | if spellname ~= spellname2 then return end |
||
1380 | if spellrank ~= spellrank2 then return end |
||
1381 | if frame == nil then |
||
1382 | frame = TCTooltip |
||
1383 | end |
||
1384 | frame:SetOwner(UIParent,"ANCHOR_NONE") |
||
1385 | frame:SetSpell(i2,BOOKTYPE_SPELL) |
||
1386 | if frame:NumLines() == 0 then return end |
||
1387 | end |
||
1388 | end |
||
1389 | if spellname == TheoryCraft_Locale.MinMax.autoshotname then |
||
1390 | local highestaimed, highestmulti, highestarcane |
||
1391 | local i2 = 1 |
||
1392 | local spellname, spellrank = GetSpellName(i2,BOOKTYPE_SPELL) |
||
1393 | while (spellname) do |
||
1394 | spellrank = tonumber(findpattern((spellrank or "0"), "%d+")) |
||
1395 | if (spellname == TheoryCraft_Locale.MinMax.aimedshotname) and ((highestaimed == nil) or (highestaimed < spellrank)) then |
||
1396 | highestaimed = spellrank |
||
1397 | end |
||
1398 | if (spellname == TheoryCraft_Locale.MinMax.multishotname) and ((highestmulti == nil) or (highestmulti < spellrank)) then |
||
1399 | highestmulti = spellrank |
||
1400 | end |
||
1401 | if (spellname == TheoryCraft_Locale.MinMax.arcaneshotname) and ((highestarcane == nil) or (highestarcane < spellrank)) then |
||
1402 | highestarcane = spellrank |
||
1403 | end |
||
1404 | i2 = i2 + 1 |
||
1405 | spellname, spellrank = GetSpellName(i2,BOOKTYPE_SPELL) |
||
1406 | end |
||
1407 | if (highestaimed) and (TheoryCraft_TooltipData[TheoryCraft_Locale.MinMax.aimedshotname.."("..highestaimed..")"] == nil) then |
||
1408 | TheoryCraft_GenerateTooltip(TCTooltip2, TheoryCraft_Locale.MinMax.aimedshotname, highestaimed, nil, nil, nil, true) |
||
1409 | end |
||
1410 | if (highestmulti) and (TheoryCraft_TooltipData[TheoryCraft_Locale.MinMax.multishotname.."("..highestmulti..")"] == nil) then |
||
1411 | TheoryCraft_GenerateTooltip(TCTooltip2, TheoryCraft_Locale.MinMax.multishotname, highestmulti, nil, nil, nil, true) |
||
1412 | end |
||
1413 | if (highestarcane) and (TheoryCraft_TooltipData[TheoryCraft_Locale.MinMax.arcaneshotname.."("..highestarcane..")"] == nil) then |
||
1414 | TheoryCraft_GenerateTooltip(TCTooltip2, TheoryCraft_Locale.MinMax.arcaneshotname, highestarcane, nil, nil, nil, true) |
||
1415 | end |
||
1416 | end |
||
1417 | if (not force) and (TheoryCraft_Settings["GenerateList"] ~= "") and (not string.find(TheoryCraft_Settings["GenerateList"], string.gsub(spellname, "-", "%%-").."%("..spellrank.."%)")) then |
||
1418 | return |
||
1419 | end |
||
1420 | local i |
||
1421 | for k, v in pairs(TheoryCraft_Spells[class]) do |
||
1422 | if v.name == spellname then |
||
1423 | i = v |
||
1424 | break |
||
1425 | end |
||
1426 | end |
||
1427 | if not i then return end |
||
1428 | -- TheoryCraft_Data.Testing = nil |
||
1429 | SummateData(i.id, i.Schools) |
||
1430 | olddesc = getglobal(frame:GetName().."TextLeft"..frame:NumLines()):GetText() |
||
1431 | |||
1432 | if TheoryCraft_TooltipData[olddesc] == nil then |
||
1433 | TheoryCraft_TooltipData[olddesc] = {} |
||
1434 | end |
||
1435 | TheoryCraft_DeleteTable(TheoryCraft_TooltipData[olddesc]) |
||
1436 | TheoryCraft_CopyTable(summeddata, TheoryCraft_TooltipData[olddesc]) |
||
1437 | if TheoryCraft_TooltipData[olddesc]["schools"] == nil then |
||
1438 | TheoryCraft_TooltipData[olddesc]["schools"] = {} |
||
1439 | end |
||
1440 | TheoryCraft_CopyTable(i.Schools, TheoryCraft_TooltipData[olddesc]["schools"]) |
||
1441 | GenerateTooltip(frame, TheoryCraft_TooltipData[olddesc], i, spellrank) |
||
1442 | if macro then |
||
1443 | TheoryCraft_TooltipData[oldspellname.."MACRO("..spellrank..")"] = olddesc |
||
1444 | end |
||
1445 | TheoryCraft_TooltipData[spellname.."("..spellrank..")"] = olddesc |
||
1446 | TheoryCraft_TooltipData[olddesc]["basedescription"] = olddesc |
||
1447 | if (i.shoot) or (i.ismelee) or (i.isranged) then |
||
1448 | if getglobal(frame:GetName().."TextLeft2") then |
||
1449 | TheoryCraft_TooltipData[olddesc]["wandlineleft2"] = getglobal(frame:GetName().."TextLeft2"):GetText() |
||
1450 | end |
||
1451 | if getglobal(frame:GetName().."TextRight2") and getglobal(frame:GetName().."TextRight2"):IsVisible() then |
||
1452 | TheoryCraft_TooltipData[olddesc]["wandlineright2"] = getglobal(frame:GetName().."TextRight2"):GetText() |
||
1453 | end |
||
1454 | if getglobal(frame:GetName().."TextLeft3") and getglobal(frame:GetName().."TextLeft3"):IsVisible() then |
||
1455 | TheoryCraft_TooltipData[olddesc]["wandlineleft3"] = getglobal(frame:GetName().."TextLeft3"):GetText() |
||
1456 | end |
||
1457 | if getglobal(frame:GetName().."TextRight3") and getglobal(frame:GetName().."TextRight3"):IsVisible() then |
||
1458 | TheoryCraft_TooltipData[olddesc]["wandlineright3"] = getglobal(frame:GetName().."TextRight3"):GetText() |
||
1459 | end |
||
1460 | if getglobal(frame:GetName().."TextLeft4") then |
||
1461 | if getglobal(frame:GetName().."TextLeft4"):GetText() ~= olddesc then |
||
1462 | TheoryCraft_TooltipData[olddesc]["wandlineleft4"] = getglobal(frame:GetName().."TextLeft4"):GetText() |
||
1463 | end |
||
1464 | end |
||
1465 | else |
||
1466 | if getglobal(frame:GetName().."TextLeft3") then |
||
1467 | if (getglobal(frame:GetName().."TextLeft3"):GetText()) then |
||
1468 | if (getglobal(frame:GetName().."TextLeft3"):GetText() ~= olddesc) and (strfind(getglobal(frame:GetName().."TextLeft3"):GetText(), (TheoryCraft_Locale.CooldownRem) or "Cooldown remaining: ") == nil) then |
||
1469 | TheoryCraft_TooltipData[olddesc]["basecasttime"] = getglobal(frame:GetName().."TextLeft3"):GetText() |
||
1470 | end |
||
1471 | end |
||
1472 | end |
||
1473 | if getglobal(frame:GetName().."TextRight2") and getglobal(frame:GetName().."TextRight2"):IsVisible() then |
||
1474 | TheoryCraft_TooltipData[olddesc]["spellrange"] = getglobal(frame:GetName().."TextRight2"):GetText() |
||
1475 | end |
||
1476 | if getglobal(frame:GetName().."TextRight3") and getglobal(frame:GetName().."TextRight3"):IsVisible() then |
||
1477 | TheoryCraft_TooltipData[olddesc]["cooldown"] = getglobal(frame:GetName().."TextRight3"):GetText() |
||
1478 | if (i.overcooldown) and (TheoryCraft_TooltipData[olddesc]["averagedam"]) then |
||
1479 | if (strfind(TheoryCraft_TooltipData[olddesc]["cooldown"], "%d+.%d+"..TheoryCraft_Locale.Cooldown)) then |
||
1480 | TheoryCraft_TooltipData[olddesc]["dps"] = TheoryCraft_TooltipData[olddesc]["averagedam"]/tonumber(findpattern(TheoryCraft_TooltipData[olddesc]["cooldown"], "%d+.%d+")) |
||
1481 | elseif (strfind(TheoryCraft_TooltipData[olddesc]["cooldown"], "%d+"..TheoryCraft_Locale.Cooldown)) then |
||
1482 | TheoryCraft_TooltipData[olddesc]["dps"] = TheoryCraft_TooltipData[olddesc]["averagedam"]/tonumber(findpattern(TheoryCraft_TooltipData[olddesc]["cooldown"], "%d+")) |
||
1483 | end |
||
1484 | end |
||
1485 | end |
||
1486 | end |
||
1487 | TheoryCraft_TooltipData[olddesc]["spellname"] = spellname |
||
1488 | TheoryCraft_TooltipData[olddesc]["spellrank"] = spellrank |
||
1489 | TheoryCraft_TooltipData[olddesc]["spellnumber"] = i2 |
||
1490 | TheoryCraft_TooltipData[olddesc]["dontdpsafterresists"] = i.dontdpsafterresists |
||
1491 | TheoryCraft_TooltipData[olddesc]["isheal"] = i.isheal |
||
1492 | TheoryCraft_TooltipData[olddesc]["iscombo"] = i.iscombo |
||
1493 | TheoryCraft_TooltipData[olddesc]["cancrit"] = i.cancrit |
||
1494 | TheoryCraft_TooltipData[olddesc]["shoot"] = i.shoot |
||
1495 | TheoryCraft_TooltipData[olddesc]["ismelee"] = i.ismelee |
||
1496 | TheoryCraft_TooltipData[olddesc]["isranged"] = i.isranged |
||
1497 | TheoryCraft_TooltipData[olddesc]["autoshot"] = i.autoshot |
||
1498 | TheoryCraft_TooltipData[olddesc]["armor"] = i.armor |
||
1499 | TheoryCraft_TooltipData[olddesc]["binary"] = i.binary |
||
1500 | TheoryCraft_TooltipData[olddesc]["dodps"] = i.dodps |
||
1501 | TheoryCraft_TooltipData[olddesc]["isseal"] = i.isseal |
||
1502 | TheoryCraft_TooltipData[olddesc]["drain"] = i.drain |
||
1503 | TheoryCraft_TooltipData[olddesc]["holynova"] = i.holynova |
||
1504 | TheoryCraft_TooltipData[olddesc]["dontdomax"] = i.dontdomax |
||
1505 | TheoryCraft_TooltipData[olddesc]["overcd"] = i.overcooldown |
||
1506 | if (TheoryCraft_Settings["GenerateList"] == "") or (string.find(TheoryCraft_Settings["GenerateList"], string.gsub(spellname, "-", "%%-").."%("..spellrank.."%)")) then |
||
1507 | TheoryCraft_TooltipData[olddesc]["showonbutton"] = true |
||
1508 | end |
||
1509 | if TheoryCraft_Data["reporttimes"] then |
||
1510 | TheoryCraft_Data["buttonsgenerated"] = TheoryCraft_Data["buttonsgenerated"]+1 |
||
1511 | TheoryCraft_Data["timetaken"] = TheoryCraft_Data["timetaken"]+GetTime()-timer |
||
1512 | end |
||
1513 | end |
||
1514 | |||
1515 | local data2 = {} |
||
1516 | |||
1517 | local function UpdateTarget(data) |
||
1518 | if data == nil then return end |
||
1519 | data["resistscore"] = 0 |
||
1520 | if data["basemanacost"] and data["manacost"] then |
||
1521 | if UnitMana("player") >= data["basemanacost"] then |
||
1522 | data["spellcasts"] = 1+math.floor((UnitMana("player")-(data["basemanacost"] or data["manacost"]))/data["manacost"]) |
||
1523 | if data["dpm"] and data["maxoomdam"] then |
||
1524 | data["maxoomdamremaining"] = data["dpm"]*data["manacost"]*data["spellcasts"] |
||
1525 | end |
||
1526 | if data["hpm"] and data["maxoomheal"] then |
||
1527 | data["maxoomhealremaining"] = data["hpm"]*data["manacost"]*data["spellcasts"] |
||
1528 | end |
||
1529 | else |
||
1530 | data["spellcasts"] = 0 |
||
1531 | if data["maxoomdam"] then |
||
1532 | data["maxoomdamremaining"] = 0 |
||
1533 | end |
||
1534 | if data["maxoomheal"] then |
||
1535 | data["maxoomdamremaining"] = 0 |
||
1536 | end |
||
1537 | end |
||
1538 | end |
||
1539 | |||
1540 | if data.iscombo then |
||
1541 | if data["description"] == nil then return end |
||
1542 | local points = GetComboPoints() |
||
1543 | data["mindamage"] = data["combo"..points.."mindamage"] or 0 |
||
1544 | data["maxdamage"] = data["combo"..points.."maxdamage"] or 0 |
||
1545 | if (data["comboconvert"]) and (points > 0) then |
||
1546 | local add = (UnitMana("player")-35)*data["comboconvert"] |
||
1547 | data["mindamage"] = data["mindamage"]+add |
||
1548 | data["maxdamage"] = data["maxdamage"]+add |
||
1549 | end |
||
1550 | data["critdmgmin"] = data["mindamage"]*(data["critbonus"]+1) |
||
1551 | data["critdmgmax"] = data["maxdamage"]*(data["critbonus"]+1) |
||
1552 | data["averagedamnocrit"] = (data["maxdamage"]+data["mindamage"])/2 |
||
1553 | data["averagecritdam"] = data["averagedamnocrit"]*data["critbonus"] |
||
1554 | data["averagedam"] = data["averagedamnocrit"]+data["averagecritdam"]*(data["critdmgchance"] or 0)/100 |
||
1555 | data["description"] = data["beforecombo"] |
||
1556 | local search = TheoryCraft_MeleeComboReader |
||
1557 | search = string.gsub(search, "%(%%d%+%)", points, 1) |
||
1558 | local replace = TheoryCraft_MeleeComboReplaceWith |
||
1559 | replace = "%*"..string.gsub(replace, "%$points%$", points).."%*" |
||
1560 | data["description"] = string.gsub(data["description"], search, replace) |
||
1561 | end |
||
1562 | if data["isheal"] then return end |
||
1563 | if data["armor"] and TheoryCraft_Settings["mitigation"] then |
||
1564 | TheoryCraft_DeleteTable(data2) |
||
1565 | TheoryCraft_CopyTable(data, data2) |
||
1566 | data = data2 |
||
1567 | |||
1568 | local armormult = TheoryCraft_Data.armormultinternal |
||
1569 | if data["description"] then |
||
1570 | if data["mindamage"] then |
||
1571 | data["description"] = string.gsub(data["description"], round(data["mindamage"]), round(data["mindamage"]*armormult)) |
||
1572 | end |
||
1573 | if data["maxdamage"] then |
||
1574 | data["description"] = string.gsub(data["description"], round(data["maxdamage"]), round(data["maxdamage"]*armormult)) |
||
1575 | end |
||
1576 | end |
||
1577 | |||
1578 | if data["mindamage"] then data["mindamage"] = data["mindamage"]*armormult end |
||
1579 | if data["maxdamage"] then data["maxdamage"] = data["maxdamage"]*armormult end |
||
1580 | if data["critdmgmin"] then data["critdmgmin"] = data["critdmgmin"]*armormult end |
||
1581 | if data["critdmgmax"] then data["critdmgmax"] = data["critdmgmax"]*armormult end |
||
1582 | if data["nextstrdam"] then data["nextstrdam"] = data["nextstrdam"]*armormult end |
||
1583 | if data["nextagidam"] then data["nextagidam"] = data["nextagidam"]*armormult end |
||
1584 | if data["nexthitdam"] then data["nexthitdam"] = data["nexthitdam"]*armormult end |
||
1585 | if data["nextcritdam"] then data["nextcritdam"] = data["nextcritdam"]*armormult end |
||
1586 | if data["dpm"] then data["dpm"] = data["dpm"]*armormult end |
||
1587 | if data["dps"] then data["dps"] = data["dps"]*armormult end |
||
1588 | if data["averagedam"] then data["averagedam"] = data["averagedam"]*armormult end |
||
1589 | if data["averagedamnocrit"] then data["averagedamnocrit"] = data["averagedamnocrit"]*armormult end |
||
1590 | if data["maxoomdam"] then data["maxoomdam"] = data["maxoomdam"]*armormult end |
||
1591 | if data["maxoomdamremaining"] then data["maxoomdamremaining"] = data["maxoomdamremaining"]*armormult end |
||
1592 | if data["maxoomdamfloored"] then data["maxoomdamfloored"] = data["maxoomdamfloored"]*armormult end |
||
1593 | |||
1594 | |||
1595 | if data["asrotationdps"] then data["asrotationdps"] = data["asrotationdps"]*armormult end |
||
1596 | if data["msrotationdps"] then data["asrotationdps"] = data["asrotationdps"]*armormult end |
||
1597 | if data["arcrotationdps"] then data["arcrotationdps"] = (data["arcrotationdps"] - (data["arcmagicdps"] or 0))*armormult + (data["arcmagicdps"] or 0) end |
||
1598 | |||
1599 | return data |
||
1600 | end |
||
1601 | if data["ismelee"] then return end |
||
1602 | if data["isseal"] then return end |
||
1603 | if data["autoshot"] then return end |
||
1604 | |||
1605 | local penamount = 0 |
||
1606 | if data["schools"] then |
||
1607 | for k, v in pairs(data["schools"]) do |
||
1608 | penamount = penamount + TheoryCraft_GetStat(v.."penetration") |
||
1609 | for k, v2 in pairs(TheoryCraft_PrimarySchools) do |
||
1610 | if (type(v2) == "table") and (v2.name == v) and (TheoryCraft_Settings["resistscores"][v2.name]) then |
||
1611 | if TheoryCraft_Settings["resistscores"][v2.name] == "~" then |
||
1612 | data["resistscore"] = data["resistscore"]+1000 |
||
1613 | else |
||
1614 | data["resistscore"] = data["resistscore"]+TheoryCraft_Settings["resistscores"][v2.name] |
||
1615 | end |
||
1616 | end |
||
1617 | end |
||
1618 | end |
||
1619 | end |
||
1620 | if data["resistscore"] > 0 then |
||
1621 | if data["resistscore"] < penamount then |
||
1622 | data["resistscore"] = 0 |
||
1623 | else |
||
1624 | data["resistscore"] = data["resistscore"]-penamount |
||
1625 | end |
||
1626 | end |
||
1627 | penamount = data["resistscore"] |
||
1628 | if penamount < 0 then |
||
1629 | penamount = 0 |
||
1630 | end |
||
1631 | |||
1632 | data["resistscore"] = data["resistscore"]/(UnitLevel("player")*20/3) |
||
1633 | if (data["resistscore"] > 0.75) and (data["resistscore"] < 2.5) then |
||
1634 | data["resistscore"] = 0.75 |
||
1635 | end |
||
1636 | |||
1637 | data["resistlevel"] = UnitLevel("target") |
||
1638 | local playerlevel = UnitLevel("player") |
||
1639 | if data["resistlevel"] == -1 then |
||
1640 | data["resistlevel"] = 63 |
||
1641 | end |
||
1642 | if data["resistlevel"] == 0 then |
||
1643 | data["resistlevel"] = playerlevel |
||
1644 | end |
||
1645 | data["resistrate"] = data["resistlevel"]-playerlevel |
||
1646 | if UnitIsPlayer("target") then |
||
1647 | if (data["resistrate"] < -2) then |
||
1648 | data["resistrate"] = 1 |
||
1649 | elseif (data["resistrate"] == -2) then |
||
1650 | data["resistrate"] = 2 |
||
1651 | elseif (data["resistrate"] == -1) then |
||
1652 | data["resistrate"] = 3 |
||
1653 | elseif (data["resistrate"] == 0) then |
||
1654 | data["resistrate"] = 4 |
||
1655 | elseif (data["resistrate"] == 1) then |
||
1656 | data["resistrate"] = 5 |
||
1657 | elseif (data["resistrate"] == 2) then |
||
1658 | data["resistrate"] = 6 |
||
1659 | elseif (data["resistrate"] > 2) then |
||
1660 | data["resistrate"] = 13+(data["resistrate"]-3)*7 |
||
1661 | end |
||
1662 | else |
||
1663 | if (data["resistrate"] < -2) then |
||
1664 | data["resistrate"] = 1 |
||
1665 | elseif (data["resistrate"] == -2) then |
||
1666 | data["resistrate"] = 2 |
||
1667 | elseif (data["resistrate"] == -1) then |
||
1668 | data["resistrate"] = 3 |
||
1669 | elseif (data["resistrate"] == 0) then |
||
1670 | data["resistrate"] = 4 |
||
1671 | elseif (data["resistrate"] == 1) then |
||
1672 | data["resistrate"] = 5 |
||
1673 | elseif (data["resistrate"] == 2) then |
||
1674 | data["resistrate"] = 6 |
||
1675 | elseif (data["resistrate"] > 2) then |
||
1676 | data["resistrate"] = 17+(data["resistrate"]-3)*11 |
||
1677 | end |
||
1678 | end |
||
1679 | if (data["resistrate"] > 99) then |
||
1680 | data["resistrate"] = 99 |
||
1681 | end |
||
1682 | data["resistrate"] = data["resistrate"]+(data["hitbonus"] or 0) |
||
1683 | local toomuchhit |
||
1684 | if (data["resistrate"] < 2) then |
||
1685 | toomuchhit = 1 |
||
1686 | data["resistrate"] = 1 |
||
1687 | end |
||
1688 | local damworth |
||
1689 | if (data["nexthitdam"]) and (not data["dontdpsafterresists"]) then |
||
1690 | |||
1691 | local misschance = data["resistrate"] |
||
1692 | |||
1693 | local critchance = (data["critchance"] or 0) |
||
1694 | if (misschance + critchance) > 100 then |
||
1695 | critchance = 100-misschance |
||
1696 | end |
||
1697 | local hitchance = 100-critchance-misschance |
||
1698 | |||
1699 | local averagehitdam = (data["averagedamnocrit"] or 0)*(data["manamultiplier"] or 1) |
||
1700 | local averagecritdam = ((data["averagedamnocrit"] or 0)*(data["manamultiplier"] or 1)+(data["averagecritdam"] or 0)) |
||
1701 | if TheoryCraft_Settings["dontcrit"] then |
||
1702 | hitchance = hitchance + critchance |
||
1703 | critchance = 0 |
||
1704 | end |
||
1705 | hitchance = hitchance/100*averagehitdam |
||
1706 | critchance = critchance/100*averagecritdam |
||
1707 | data["dpsafterresists"] = round((hitchance+critchance)/data["casttime"], 1) |
||
1708 | end |
||
1709 | |||
1710 | if not TheoryCraft_Settings["dontresist"] then |
||
1711 | return |
||
1712 | end |
||
1713 | TheoryCraft_DeleteTable(data2) |
||
1714 | TheoryCraft_CopyTable(data, data2) |
||
1715 | data = data2 |
||
1716 | |||
1717 | local resistmult = (1-data["resistscore"]) |
||
1718 | if data["binary"] then |
||
1719 | if resistmult > 1 then |
||
1720 | resistmult = 1 |
||
1721 | end |
||
1722 | end |
||
1723 | if resistmult < 0 then |
||
1724 | resistmult = 0 |
||
1725 | penamount = 0 |
||
1726 | end |
||
1727 | |||
1728 | if data["nextcritdam"] then data["nextcritdam"] = data["nextcritdam"] * resistmult end |
||
1729 | if data["nexthitdam"] then data["nexthitdam"] = data["nexthitdam"] * resistmult end |
||
1730 | |||
1731 | if data["overcd"] == nil then |
||
1732 | if data["dps"] and data["dpsafterresists"] then |
||
1733 | resistmult = resistmult * data["dpsafterresists"]/data["dps"] |
||
1734 | data["dps"] = data["dpsafterresists"] |
||
1735 | end |
||
1736 | end |
||
1737 | if data["binary"] then |
||
1738 | data["resistrate"] = data["resistrate"] + data["resistscore"]*100 |
||
1739 | if data["resistrate"] > 100 then |
||
1740 | data["resistrate"] = 100 |
||
1741 | end |
||
1742 | end |
||
1743 | |||
1744 | if data["damworth"] then data["damworth"] = data["damworth"] * resistmult end |
||
1745 | |||
1746 | if penamount < 10 then |
||
1747 | if data["nextpendam"] then |
||
1748 | data["nextpendam"] = data["nextpendam"] * (penamount/10) |
||
1749 | end |
||
1750 | end |
||
1751 | data["dontshowupto"] = "" |
||
1752 | |||
1753 | if data["nexthitdamequive"] and data["nexthitdam"] and data["damworth"] then data["nexthitdamequive"] = data["nexthitdam"] / data["damworth"] end |
||
1754 | if data["nextcritdamequive"] and data["nextcritdam"] and data["damworth"] then data["nextcritdamequive"] = data["nextcritdam"] / data["damworth"] end |
||
1755 | if data["nextpendamequive"] and data["nextpendam"] and data["damworth"] then data["nextpendamequive"] = data["nextpendam"] / data["damworth"] end |
||
1756 | |||
1757 | if data["damworth"] == 0 then data["nexthitdamequive"] = 0 end |
||
1758 | if data["damworth"] == 0 then data["nextcritdamequive"] = 0 end |
||
1759 | |||
1760 | if data["dps"] then data["dps"] = data["dps"] * resistmult end |
||
1761 | if data["withdotdps"] then data["withdotdps"] = data["withdotdps"] * resistmult end |
||
1762 | if data["dpsdam"] then data["dpsdam"] = data["dpsdam"] * resistmult end |
||
1763 | if data["averagedam"] then data["averagedam"] = data["averagedam"] * resistmult end |
||
1764 | if data["averagedamnocrit"] then data["averagedamnocrit"] = data["averagedamnocrit"] * resistmult end |
||
1765 | if data["dpm"] then data["dpm"] = data["dpm"] * resistmult end |
||
1766 | if data["withdotdpm"] then data["withdotdpm"] = data["withdotdpm"] * resistmult end |
||
1767 | if data["maxoomdam"] then data["maxoomdam"] = data["maxoomdam"] * resistmult end |
||
1768 | if data["maxevocoomdam"] then data["maxevocoomdam"] = data["maxevocoomdam"] * resistmult end |
||
1769 | if toomuchhit then data["nexthitdam"] = 0 data["nexthitdamequive"] = "At max, 0.00" end |
||
1770 | if penamount == 0 then data["nextpendamequive"] = "At max, 0.00" end |
||
1771 | return data |
||
1772 | end |
||
1773 | |||
1774 | function TheoryCraft_GetSpellDataByFrame(frame, force) |
||
1775 | if frame == nil then return nil end |
||
1776 | if frame:NumLines() == 0 then return nil end |
||
1777 | if getglobal(frame:GetName().."TextLeft"..frame:NumLines()) == nil then return nil end |
||
1778 | local desc = getglobal(frame:GetName().."TextLeft"..frame:NumLines()):GetText() |
||
1779 | if (frame:NumLines() == 1) and (desc ~= "Attack") then |
||
1780 | local pos = strfind(desc, "%(%d+%)") |
||
1781 | if not pos then return nil end |
||
1782 | local data = TheoryCraft_GetSpellDataByName(string.sub(desc, 1, pos-1), tonumber(string.sub(desc, pos+1, string.len(desc)-1)), force, true) |
||
1783 | if data == nil then return nil end |
||
1784 | if data.spellnumber == nil then return nil end |
||
1785 | frame:SetSpell(data.spellnumber,BOOKTYPE_SPELL) |
||
1786 | return data |
||
1787 | end |
||
1788 | if TheoryCraft_TooltipData[desc] and TheoryCraft_TooltipData[desc].spellname then |
||
1789 | return UpdateTarget(TheoryCraft_TooltipData[desc]) or TheoryCraft_TooltipData[desc] |
||
1790 | end |
||
1791 | TheoryCraft_GenerateTooltip(frame, nil, nil, nil, true, nil, force) |
||
1792 | return UpdateTarget(TheoryCraft_TooltipData[desc]) or TheoryCraft_TooltipData[desc] |
||
1793 | end |
||
1794 | |||
1795 | function TheoryCraft_GetSpellDataByName(spellname, spellrank, force, macro) |
||
1796 | if spellrank == nil then spellrank = 0 end |
||
1797 | local description = TheoryCraft_TooltipData[spellname.."("..spellrank..")"] or (macro and TheoryCraft_TooltipData[spellname.."MACRO("..spellrank..")"]) |
||
1798 | if (description) then |
||
1799 | if TheoryCraft_TooltipData[description] and TheoryCraft_TooltipData[description].spellname then |
||
1800 | return UpdateTarget(TheoryCraft_TooltipData[description]) or TheoryCraft_TooltipData[description] |
||
1801 | end |
||
1802 | end |
||
1803 | TheoryCraft_GenerateTooltip(nil, spellname, spellrank, nil, true, macro) |
||
1804 | if TheoryCraft_TooltipData[TheoryCraft_TooltipData[spellname.."("..spellrank..")"]] and TheoryCraft_TooltipData[TheoryCraft_TooltipData[spellname.."("..spellrank..")"]].spellname then |
||
1805 | return UpdateTarget(TheoryCraft_TooltipData[TheoryCraft_TooltipData[spellname.."("..spellrank..")"]]) or TheoryCraft_TooltipData[TheoryCraft_TooltipData[spellname.."("..spellrank..")"]] |
||
1806 | elseif TheoryCraft_TooltipData[TheoryCraft_TooltipData[spellname.."MACRO("..spellrank..")"]] and TheoryCraft_TooltipData[TheoryCraft_TooltipData[spellname.."MACRO("..spellrank..")"]].spellname then |
||
1807 | return UpdateTarget(TheoryCraft_TooltipData[TheoryCraft_TooltipData[spellname.."MACRO("..spellrank..")"]]) or TheoryCraft_TooltipData[TheoryCraft_TooltipData[spellname.."MACRO("..spellrank..")"]] |
||
1808 | end |
||
1809 | end |
||
1810 | |||
1811 | function TheoryCraft_GetSpellDataByDescription(description, force) |
||
1812 | if TheoryCraft_TooltipData[description] and TheoryCraft_TooltipData[description].spellname then |
||
1813 | return UpdateTarget(TheoryCraft_TooltipData[description]) or TheoryCraft_TooltipData[description] |
||
1814 | end |
||
1815 | if (force ~= true) and (TheoryCraft_Settings["GenerateList"] ~= "") then |
||
1816 | return |
||
1817 | end |
||
1818 | local i = 1 |
||
1819 | local spellname, spellrank |
||
1820 | local testdesc |
||
1821 | while (true) do |
||
1822 | spellname, spellrank = GetSpellName(i,BOOKTYPE_SPELL) |
||
1823 | if spellname == nil then break end |
||
1824 | spellrank = tonumber(findpattern(spellrank, "%d+")) |
||
1825 | if spellrank == nil then spellrank = 0 end |
||
1826 | TCTooltip:SetOwner(UIParent,"ANCHOR_NONE") |
||
1827 | TCTooltip:SetSpell(i,BOOKTYPE_SPELL) |
||
1828 | testdesc = getglobal("TCTooltipTextLeft"..TCTooltip:NumLines()):GetText() |
||
1829 | if testdesc == description then |
||
1830 | TheoryCraft_GenerateTooltip(TCTooltip, spellname, spellrank, i, true) |
||
1831 | return UpdateTarget(TheoryCraft_TooltipData[description]) or TheoryCraft_TooltipData[description] |
||
1832 | end |
||
1833 | i = i + 1 |
||
1834 | end |
||
1835 | end |
||
1836 | |||
1837 | function TheoryCraft_GenerateAll() |
||
1838 | TheoryCraft_DeleteTable(TheoryCraft_TooltipData) |
||
1839 | TheoryCraft_DeleteTable(TheoryCraft_UpdatedButtons) |
||
1840 | if TheoryCraft_UpdateOutfitTab then TheoryCraft_UpdateOutfitTab() end |
||
1841 | end |