vanilla-wow-addons – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | -- Masks |
2 | |||
3 | -- These look a little ugly but the idea is decent... |
||
4 | lazyr.masks = {} |
||
5 | |||
6 | -- klugy, but hey |
||
7 | lazyr.masks.alreadyInsideInterruptExceptionCriteria = false |
||
8 | |||
9 | function lazyr.masks.negWrapper(f, negate) |
||
10 | return function() |
||
11 | local r = f() |
||
12 | return ((r and not negate) or (not r and negate)) |
||
13 | end |
||
14 | end |
||
15 | |||
16 | -- returns a super mask. Returns true if any of the given masks are true (an "OR"). |
||
17 | -- however if negate is true, then returns true only if ALL of then given masks are false ("AND") |
||
18 | function lazyr.masks.maskGroup(masks, negate) |
||
19 | return function() |
||
20 | if (not negate) then |
||
21 | for idx, mask in masks do |
||
22 | if (mask()) then |
||
23 | return true |
||
24 | end |
||
25 | end |
||
26 | return false |
||
27 | else |
||
28 | for idx, mask in masks do |
||
29 | if (mask()) then |
||
30 | return false |
||
31 | end |
||
32 | end |
||
33 | return true |
||
34 | end |
||
35 | end |
||
36 | end |
||
37 | |||
38 | |||
39 | function lazyr.masks.ComboPoints(cp, gtLtEq) |
||
40 | cp = tonumber(cp) |
||
41 | return function() |
||
42 | if (not gtLtEq or gtLtEq == "") then |
||
43 | return (GetComboPoints() >= cp) |
||
44 | end |
||
45 | if (gtLtEq == ">") then |
||
46 | return (GetComboPoints() > cp) |
||
47 | elseif (gtLtEq == "=") then |
||
48 | return (GetComboPoints() == cp) |
||
49 | else |
||
50 | return (GetComboPoints() < cp) |
||
51 | end |
||
52 | end |
||
53 | end |
||
54 | |||
55 | function lazyr.masks.IsBeingGanked() |
||
56 | return function() |
||
57 | return lazyr.ganked |
||
58 | end |
||
59 | end |
||
60 | |||
61 | function lazyr.masks.DebuffSpace() |
||
62 | return function() |
||
63 | if UnitExists("target") then |
||
64 | for i=1,16 do |
||
65 | s=UnitDebuff("target", i) |
||
66 | if (not s) then |
||
67 | return true |
||
68 | end |
||
69 | end |
||
70 | end |
||
71 | return false |
||
72 | end |
||
73 | end |
||
74 | |||
75 | function lazyr.masks.IsImmune(action) |
||
76 | return function() |
||
77 | if (lazyr.perPlayerConf.Immunities[action] and lazyr.perPlayerConf.Immunities[action][UnitName("target")]) then |
||
78 | if (lazyr.perPlayerConf.showReasonForTargetCCd) then |
||
79 | lazyr.p("-ifTargetImmune: "..UnitName("target").." has immunity to "..action) |
||
80 | end |
||
81 | return true |
||
82 | end |
||
83 | return false |
||
84 | end |
||
85 | end |
||
86 | |||
87 | |||
88 | function lazyr.masks.IsFlagRunner() |
||
89 | return function() |
||
90 | if (not lrLocale.BGWGTEXT0) then |
||
91 | lazyr.p("Sorry, ifFlagRunner not supported for your locale.") |
||
92 | return false |
||
93 | end |
||
94 | if (UnitName("target")==lazyr.flagHolder) and UnitExists("target") then |
||
95 | return true |
||
96 | else |
||
97 | return false |
||
98 | end |
||
99 | end |
||
100 | end |
||
101 | |||
102 | function lazyr.masks.IsFlaggedPVP(unit) |
||
103 | return function() |
||
104 | if unit ~= "Target" then |
||
105 | if UnitIsPVP("player") then |
||
106 | return true |
||
107 | else |
||
108 | return false |
||
109 | end |
||
110 | else |
||
111 | if (UnitIsPVP("target") and UnitIsEnemy("target","player") and UnitExists("target")) then |
||
112 | return true |
||
113 | else |
||
114 | return false |
||
115 | end |
||
116 | end |
||
117 | end |
||
118 | end |
||
119 | |||
120 | function lazyr.masks.IsDueling() |
||
121 | return function() |
||
122 | return lazyr.InDuel |
||
123 | end |
||
124 | end |
||
125 | |||
126 | |||
127 | function lazyr.masks.IsBeingAttackedBy(num, gtLtEq) |
||
128 | num = tonumber(num) |
||
129 | return function() |
||
130 | if (not gtLtEq or gtLtEq == "") then |
||
131 | return (lazyr.numberOfAttackers >= num) |
||
132 | end |
||
133 | if (gtLtEq == ">") then |
||
134 | return (lazyr.numberOfAttackers > num) |
||
135 | elseif (gtLtEq == "=") then |
||
136 | return (lazyr.numberOfAttackers == num) |
||
137 | else |
||
138 | return (lazyr.numberOfAttackers < num) |
||
139 | end |
||
140 | end |
||
141 | end |
||
142 | |||
143 | function lazyr.masks.IsTargetOfTarget() |
||
144 | return function() |
||
145 | return UnitIsUnit("player", "targettarget") |
||
146 | end |
||
147 | end |
||
148 | |||
149 | function lazyr.masks.IsTargetOfTargetClass(class) |
||
150 | return function() |
||
151 | return (class == UnitClass("targettarget")) |
||
152 | end |
||
153 | end |
||
154 | |||
155 | |||
156 | -- :-( |
||
157 | function lazyr.masks.IsStealthed() |
||
158 | local icon, name, active, castable = GetShapeshiftFormInfo(1) |
||
159 | return (active == 1) |
||
160 | end |
||
161 | |||
162 | function lazyr.masks.IsStealthedMask() |
||
163 | return function() |
||
164 | return lazyr.masks.IsStealthed() |
||
165 | end |
||
166 | end |
||
167 | |||
168 | function lazyr.masks.BehindAttackHasNotFailedRecently() |
||
169 | return function() |
||
170 | return ((GetTime() - lazyr.behindAttackLastFailedAt) >= .3) |
||
171 | end |
||
172 | end |
||
173 | |||
174 | function lazyr.masks.BehindAttackFailedRecently() |
||
175 | return function() |
||
176 | return ((GetTime() - lazyr.behindAttackLastFailedAt) < .3) |
||
177 | end |
||
178 | end |
||
179 | |||
180 | function lazyr.masks.InFrontAttackHasNotFailedRecently() |
||
181 | return function() |
||
182 | return ((GetTime() - lazyr.inFrontAttackLastFailedAt) >= .3) |
||
183 | end |
||
184 | end |
||
185 | |||
186 | function lazyr.masks.InFrontAttackFailedRecently() |
||
187 | return function() |
||
188 | return ((GetTime() - lazyr.inFrontAttackLastFailedAt) < .3) |
||
189 | end |
||
190 | end |
||
191 | |||
192 | function lazyr.masks.InCooldown(action) |
||
193 | return function() |
||
194 | local actionInfo = lazyr.ParseArg(action) |
||
195 | if (not actionInfo) then |
||
196 | return false |
||
197 | end |
||
198 | local action = actionInfo[1] |
||
199 | local start, duration, enable = GetActionCooldown(action:GetSlot()); |
||
200 | if ( (duration - (GetTime() - start)) > 1) then |
||
201 | return true |
||
202 | else |
||
203 | return false |
||
204 | end |
||
205 | end |
||
206 | end |
||
207 | |||
208 | -- :-( |
||
209 | function lazyr.masks.FindTalentPoints(icon) |
||
210 | -- Okay, there is no event that gets fired when talents have changed, so |
||
211 | -- normally we'd need to scan the talent tree every single time. |
||
212 | -- Instead, for fun, we cache talent point lookups for 1 minute. Not sure |
||
213 | -- how much this really helps performance, but hey. |
||
214 | |||
215 | local cacheInfo = lazyr.talentCache[icon] |
||
216 | if (cacheInfo) then |
||
217 | local time = cacheInfo[1] |
||
218 | local rank = cacheInfo[2] |
||
219 | if (time and time > (GetTime() - 60)) then |
||
220 | return rank |
||
221 | end |
||
222 | end |
||
223 | |||
224 | rank = 0 |
||
225 | for i = 1, GetNumTalentTabs() do |
||
226 | for j = 1, GetNumTalents(i) do |
||
227 | local name, thisIcon, _, _, rank, max = GetTalentInfo(i, j) |
||
228 | if (thisIcon and string.find(thisIcon, icon)) then |
||
229 | lazyr.talentCache[icon] = {GetTime(), rank} |
||
230 | return rank |
||
231 | end |
||
232 | end |
||
233 | end |
||
234 | |||
235 | lazyr.talentCache[icon] = {GetTime(), 0} |
||
236 | return 0 |
||
237 | end |
||
238 | |||
239 | -- :-( |
||
240 | function lazyr.masks.CalculateBaseEviscDamage(cp) |
||
241 | -- find eviscerate rank |
||
242 | -- lookup damage cp using damage table |
||
243 | local rank = lazyr.actions.eviscerate:GetRank() |
||
244 | if (rank == 0) then |
||
245 | return false |
||
246 | end |
||
247 | local eviscDamage = lazyr.eviscDamage[rank][cp] |
||
248 | if (not eviscDamage) then |
||
249 | lazyr.p("strange, damage lookup failed") |
||
250 | return false |
||
251 | end |
||
252 | --origEviscDamage = eviscDamage |
||
253 | |||
254 | -- adjust for Improved Eviscerate, if invested |
||
255 | local ieAdjust = { 1.05, 1.1, 1.15 } |
||
256 | local tpts = lazyr.masks.FindTalentPoints("Ability_Rogue_Eviscerate") |
||
257 | if (tpts > 0) then |
||
258 | eviscDamage = eviscDamage * ieAdjust[tpts] |
||
259 | end |
||
260 | |||
261 | -- adjust for Aggression, if invested |
||
262 | local aggrAdjust = { 1.02, 1.04, 1.06 } |
||
263 | local tpts = lazyr.masks.FindTalentPoints("Ability_Racial_Avatar") |
||
264 | if (tpts > 0) then |
||
265 | eviscDamage = eviscDamage * aggrAdjust[tpts] |
||
266 | end |
||
267 | |||
268 | return eviscDamage |
||
269 | end |
||
270 | |||
271 | -- :-( |
||
272 | function lazyr.masks.CalculateObservedEviscDamage(cp) |
||
273 | if (lazyr.perPlayerConf.useEviscTracking) then |
||
274 | local observedDamage, observedCt = lazyr.et.GetEviscTrackingInfo(cp) |
||
275 | if (observedCt > 0) then |
||
276 | --lazyr.d("Calculate Evisc Dmg: Using the OBSERVED Evisc ("..cp.."cp) damage of: "..observedDamage) |
||
277 | return observedDamage |
||
278 | end |
||
279 | end |
||
280 | |||
281 | local dmg = lazyr.masks.CalculateBaseEviscDamage(cp) |
||
282 | --lazyr.d("Calculate Evisc Dmg: Using the OPTIMAL Evisc ("..cp.."cp) damage of: "..dmg) |
||
283 | return dmg |
||
284 | end |
||
285 | |||
286 | function lazyr.masks.IsEviscKillShot(assumeCBActive, goalPct) |
||
287 | return function() |
||
288 | local cp = GetComboPoints() |
||
289 | if (cp == 0) then |
||
290 | return false |
||
291 | end |
||
292 | |||
293 | local hp = lazyr.masks.GetUnitHealth("target") |
||
294 | -- adjust hp for goalPct |
||
295 | if (goalPct ~= 100) then |
||
296 | hp = hp * (goalPct / 100) |
||
297 | end |
||
298 | |||
299 | local eviscDamage = lazyr.masks.CalculateObservedEviscDamage(cp) |
||
300 | |||
301 | -- adjust for Cold Blood, if we're asked to, or if active |
||
302 | if (assumeCBActive or lazyr.masks.HasBuffOrDebuff("player", "buff", |
||
303 | lazyr.actions.coldBlood.texture, |
||
304 | lrLocale.BUFF_TTS.coldBlood)) then |
||
305 | -- Cold Blood guarantees a crit (if it hits) |
||
306 | eviscDamage = eviscDamage * 2 |
||
307 | end |
||
308 | |||
309 | --lazyr.d("Adjusted evisc dmg: "..origEviscDamage.." vs "..eviscDamage) |
||
310 | --lazyr.d("Avg evisc dmg with "..cp.." combo points is "..eviscDamage..", vs: "..hp) |
||
311 | if (hp <= eviscDamage) then |
||
312 | if (cp < 5) then |
||
313 | lazyr.d("Early eviscerate! Kill shot!") |
||
314 | end |
||
315 | return true |
||
316 | else |
||
317 | return false |
||
318 | end |
||
319 | end |
||
320 | end |
||
321 | |||
322 | -- :-( |
||
323 | -- supported unitIds: player, (enemy) target |
||
324 | function lazyr.masks.GetUnitHealth(unitId, wantPct) |
||
325 | if (unitId == "player") then |
||
326 | if (wantPct) then |
||
327 | return (UnitHealth(unitId) / UnitHealthMax(unitId)) * 100 |
||
328 | else |
||
329 | return UnitHealth(unitId) |
||
330 | end |
||
331 | elseif (unitId == "target") then |
||
332 | if (wantPct) then |
||
333 | return UnitHealth(unitId) |
||
334 | else |
||
335 | if (not MobHealth_GetTargetCurHP) then |
||
336 | lazyr.p("MobInfo2 (or equivalent) not installed, can't determine target's HP.") |
||
337 | -- return something huge |
||
338 | return 1000000 |
||
339 | end |
||
340 | local hp = MobHealth_GetTargetCurHP() |
||
341 | if (not hp or hp == 0) then |
||
342 | -- no mob info, return something huge |
||
343 | hp = 1000000 |
||
344 | end |
||
345 | return hp |
||
346 | end |
||
347 | end |
||
348 | end |
||
349 | |||
350 | -- :-( |
||
351 | -- returns mana, energy, or rage |
||
352 | function lazyr.masks.GetUnitMana(unitId, wantPct) |
||
353 | -- mana is different than health, we get actual values for everything, even enemies |
||
354 | if (wantPct) then |
||
355 | return (UnitMana(unitId) / UnitManaMax(unitId)) * 100 |
||
356 | else |
||
357 | return UnitMana(unitId) |
||
358 | end |
||
359 | end |
||
360 | |||
361 | function lazyr.masks.UnitPowerMask(unitId, gtLtEq, val, powerType, wantPct) |
||
362 | return function() |
||
363 | local compareVal = 0 |
||
364 | |||
365 | if (powerType == "hp") then |
||
366 | compareVal = lazyr.masks.GetUnitHealth(unitId, wantPct) |
||
367 | elseif (powerType == "mana" or powerType == "energy") then |
||
368 | compareVal = lazyr.masks.GetUnitMana(unitId, wantPct) |
||
369 | end |
||
370 | |||
371 | if (gtLtEq == ">") then |
||
372 | return (compareVal > val) |
||
373 | elseif (gtLtEq == "=") then |
||
374 | return (compareVal == val) |
||
375 | else |
||
376 | return (compareVal < val) |
||
377 | end |
||
378 | end |
||
379 | end |
||
380 | |||
381 | |||
382 | |||
383 | -- :-( |
||
384 | -- |
||
385 | -- Checking buffs/debuffs is fun! |
||
386 | -- We accept one or more of: |
||
387 | -- - the buff/debuff texture |
||
388 | -- - the Tooltip title |
||
389 | -- - a line found inside the body of the tooltip. |
||
390 | -- |
||
391 | function lazyr.masks.HasBuffOrDebuff(unitId, buffOrDebuff, texture, ttTitle, ttBody) |
||
392 | local candidates = {} |
||
393 | local buffId = 1 |
||
394 | while true do |
||
395 | local thisTexture |
||
396 | if (buffOrDebuff == "buff") then |
||
397 | thisTexture = UnitBuff(unitId, buffId) |
||
398 | else |
||
399 | thisTexture = UnitDebuff(unitId, buffId) |
||
400 | end |
||
401 | if (not thisTexture) then |
||
402 | break |
||
403 | end |
||
404 | |||
405 | if (not texture) then |
||
406 | -- no texture criteria given, so just add to list of candidates |
||
407 | candidates[buffId] = true |
||
408 | |||
409 | elseif (string.find(thisTexture, texture)) then |
||
410 | lazyr.d("HasBuffOrDebuff: found texture "..texture.." at buffId: "..buffId) |
||
411 | candidates[buffId] = true |
||
412 | |||
413 | else |
||
414 | candidates[buffId] = false |
||
415 | end |
||
416 | buffId = buffId + 1 |
||
417 | end |
||
418 | |||
419 | if (ttTitle) then |
||
420 | for buffId, isCandidate in ipairs(candidates) do |
||
421 | if (isCandidate) then |
||
422 | LazyRogue_Tooltip:ClearLines() |
||
423 | if (buffOrDebuff == "buff") then |
||
424 | LazyRogue_Tooltip:SetUnitBuff(unitId, buffId) |
||
425 | else |
||
426 | LazyRogue_Tooltip:SetUnitDebuff(unitId, buffId) |
||
427 | end |
||
428 | local thisTTTitle = LazyRogue_TooltipTextLeft1:GetText() |
||
429 | if (thisTTTitle and string.find(thisTTTitle, "^"..ttTitle)) then |
||
430 | lazyr.d("HasBuffOrDebuff: found ttTitle "..ttTitle.." at buffId: "..buffId) |
||
431 | else |
||
432 | lazyr.d("HasBuffOrDebuff: did NOT find ttTitle "..ttTitle.." at buffId: "..buffId) |
||
433 | candidates[buffId] = false |
||
434 | end |
||
435 | end |
||
436 | end |
||
437 | end |
||
438 | |||
439 | if (ttBody) then |
||
440 | for buffId, isCandidate in ipairs(candidates) do |
||
441 | if (isCandidate) then |
||
442 | LazyRogue_Tooltip:ClearLines() |
||
443 | if (buffOrDebuff == "buff") then |
||
444 | LazyRogue_Tooltip:SetUnitBuff(unitId, buffId) |
||
445 | else |
||
446 | LazyRogue_Tooltip:SetUnitDebuff(unitId, buffId) |
||
447 | end |
||
448 | local ttNumlines = LazyRogue_Tooltip:NumLines() |
||
449 | for i = 2, ttNumlines do |
||
450 | local thisTTBody = getglobal("LazyRogue_TooltipTextLeft"..i):GetText() |
||
451 | if (thisTTBody and string.find(thisTTBody, "^"..ttBody)) then |
||
452 | lazyr.d("HasBuffOrDebuff: found ttBody "..ttBody.." at buffId: "..buffId) |
||
453 | else |
||
454 | lazyr.d("HasBuffOrDebuff: did NOT find ttBody "..ttBody.." at buffId: "..buffId) |
||
455 | candidates[buffId] = false |
||
456 | end |
||
457 | end |
||
458 | end |
||
459 | end |
||
460 | end |
||
461 | |||
462 | for buffId, isCandidate in ipairs(candidates) do |
||
463 | if (isCandidate) then |
||
464 | return buffId |
||
465 | end |
||
466 | end |
||
467 | |||
468 | return nil |
||
469 | end |
||
470 | |||
471 | |||
472 | function lazyr.masks.BuffOrDebuffMask(attack) |
||
473 | return function() |
||
474 | local unitId = "target" |
||
475 | local buffOrDebuff = "debuff" |
||
476 | local texture |
||
477 | local ttTitle |
||
478 | if (attack == "Adrenaline") then |
||
479 | unitId = "player" |
||
480 | buffOrDebuff = "buff" |
||
481 | texture = lazyr.actions.adrenalineRush.texture |
||
482 | ttTitle = lrLocale.BUFF_TTS.adrenalineRush |
||
483 | elseif (attack == "Berserking") then |
||
484 | unitId = "player" |
||
485 | buffOrDebuff = "buff" |
||
486 | texture = lazyr.actions.berserking.texture |
||
487 | ttTitle = lrLocale.BUFF_TTS.berserking |
||
488 | elseif (attack == "BladeFlurry") then |
||
489 | unitId = "player" |
||
490 | buffOrDebuff = "buff" |
||
491 | texture = lazyr.actions.bladeFlurry.texture |
||
492 | ttTitle = lrLocale.BUFF_TTS.bladeFlurry |
||
493 | elseif (attack == "Blind") then |
||
494 | texture = lazyr.actions.blind.texture |
||
495 | ttTitle = lrLocale.BUFF_TTS.blind |
||
496 | elseif (attack == "ColdBlood") then |
||
497 | unitId = "player" |
||
498 | buffOrDebuff = "buff" |
||
499 | texture = lazyr.actions.coldBlood.texture |
||
500 | ttTitle = lrLocale.BUFF_TTS.coldBlood |
||
501 | elseif (attack == "Cs") then |
||
502 | texture = lazyr.actions.cheapShot.texture |
||
503 | ttTitle = lrLocale.BUFF_TTS.cheapShot |
||
504 | elseif (attack == "Evasion") then |
||
505 | unitId = "player" |
||
506 | buffOrDebuff = "buff" |
||
507 | texture = lazyr.actions.evasion.texture |
||
508 | ttTitle = lrLocale.BUFF_TTS.evasion |
||
509 | elseif (attack == "Expose") then |
||
510 | texture = lazyr.actions.exposeArmor.texture |
||
511 | ttTitle = lrLocale.BUFF_TTS.exposeArmor |
||
512 | elseif (attack == "Garrote") then |
||
513 | texture = lazyr.actions.garrote.texture |
||
514 | ttTitle = lrLocale.BUFF_TTS.garrote |
||
515 | elseif (attack == "Ghostly") then |
||
516 | unitId = "player" |
||
517 | buffOrDebuff = "buff" |
||
518 | texture = lazyr.actions.ghostlyStrike.texture |
||
519 | ttTitle = lrLocale.BUFF_TTS.ghostlyStrike |
||
520 | elseif (attack == "Gouge") then |
||
521 | texture = lazyr.actions.gouge.texture |
||
522 | ttTitle = lrLocale.BUFF_TTS.gouge |
||
523 | elseif (attack == "Hemo") then |
||
524 | texture = lazyr.actions.hemorrhage.texture |
||
525 | ttTitle = lrLocale.BUFF_TTS.hemorrhage |
||
526 | elseif (attack == "Ks") then |
||
527 | texture = lazyr.actions.kidneyShot.texture |
||
528 | ttTitle = lrLocale.BUFF_TTS.kidneyShot |
||
529 | elseif (attack == "RecentlyBandaged") then |
||
530 | unitId = "player" |
||
531 | texture = "INV_Misc_Bandage_08" |
||
532 | ttTitle = lrLocale.BUFF_TTS.recentlyBandaged |
||
533 | elseif (attack == "FirstAid") then |
||
534 | unitId = "player" |
||
535 | buffOrDebuff = "buff" |
||
536 | texture = "Spell_Holy_Heal" |
||
537 | ttTitle = lrLocale.BUFF_TTS.firstAid |
||
538 | elseif (attack == "Remorseless") then |
||
539 | unitId = "player" |
||
540 | buffOrDebuff = "buff" |
||
541 | texture = "Ability_FiegnDead" |
||
542 | ttTitle = lrLocale.BUFF_TTS.remorseless |
||
543 | elseif (attack == "Rupture") then |
||
544 | texture = lazyr.actions.rupture.texture |
||
545 | ttTitle = lrLocale.BUFF_TTS.rupture |
||
546 | elseif (attack == "Sap") then |
||
547 | texture = lazyr.actions.sap.texture |
||
548 | ttTitle = lrLocale.BUFF_TTS.sap |
||
549 | elseif (attack == "Snd") then |
||
550 | unitId = "player" |
||
551 | buffOrDebuff = "buff" |
||
552 | texture = lazyr.actions.sliceNDice.texture |
||
553 | ttTitle = lrLocale.BUFF_TTS.sliceNDice |
||
554 | elseif (attack == "Stealth") then |
||
555 | unitId = "player" |
||
556 | buffOrDebuff = "buff" |
||
557 | texture = lazyr.actions.stealth.texture |
||
558 | ttTitle = lrLocale.BUFF_TTS.stealth |
||
559 | elseif (attack == "Vanish") then |
||
560 | unitId = "player" |
||
561 | buffOrDebuff = "buff" |
||
562 | texture = lazyr.actions.vanish.texture |
||
563 | ttTitle = lrLocale.BUFF_TTS.vanish |
||
564 | else |
||
565 | lazyr.p("internal error, unknown attack: "..attack) |
||
566 | return false |
||
567 | end |
||
568 | |||
569 | return lazyr.masks.HasBuffOrDebuff(unitId, buffOrDebuff, texture, ttTitle) |
||
570 | end |
||
571 | end |
||
572 | |||
573 | function lazyr.masks.TargetClass(class) |
||
574 | return function() |
||
575 | return (class == UnitClass("target")) |
||
576 | end |
||
577 | end |
||
578 | |||
579 | function lazyr.masks.TargetLevel(gtLtEq, val) |
||
580 | return function() |
||
581 | if (not UnitExists("target")) then |
||
582 | return false |
||
583 | end |
||
584 | local tLevel = UnitLevel("target") |
||
585 | if (tLevel == -1) then |
||
586 | -- "??" |
||
587 | -- means target is > 10 levels above the player. |
||
588 | -- hmm, special case. we can still be smart here. |
||
589 | -- if the criteria was greater than something, where something |
||
590 | -- is at most your level + 10, then we can return true. |
||
591 | -- otherwise we can't be sure. |
||
592 | local pLevel = UnitLevel("player") |
||
593 | if (gtLtEq == ">" and (val <= pLevel + 10)) then |
||
594 | return true |
||
595 | end |
||
596 | return false |
||
597 | end |
||
598 | |||
599 | if (gtLtEq == ">") then |
||
600 | return (tLevel > val) |
||
601 | elseif (gtLtEq == "=") then |
||
602 | return (tLevel == val) |
||
603 | else |
||
604 | return (tLevel < val) |
||
605 | end |
||
606 | end |
||
607 | end |
||
608 | |||
609 | function lazyr.masks.TargetMyLevel(gtLtEq, val) |
||
610 | return function() |
||
611 | if (not UnitExists("target")) then |
||
612 | return false |
||
613 | end |
||
614 | local tLevel = tonumber(UnitLevel("target")) |
||
615 | local pLevel = tonumber(UnitLevel("player")) |
||
616 | local tmp=pLevel+val |
||
617 | --not sure how to code this with the information availble |
||
618 | --if (tLevel == -1) then |
||
619 | -- "??" |
||
620 | -- means target is > 10 levels above the player. |
||
621 | -- hmm, special case. we can still be smart here. |
||
622 | -- if the criteria was greater than something, where something |
||
623 | -- is at most your level + 10, then we can return true. |
||
624 | -- otherwise we can't be sure. |
||
625 | -- if (gtLtEq == ">" and (tmp <= pLevel + 10)) then |
||
626 | -- return true |
||
627 | -- end |
||
628 | -- return false |
||
629 | -- end |
||
630 | if (gtLtEq == ">") then |
||
631 | lazyr.d("Search for target over lvl "..tmp) |
||
632 | return (tmp < tLevel) |
||
633 | elseif (gtLtEq == "=") then |
||
634 | lazyr.d("Search for target equal to lvl "..tmp) |
||
635 | return (tmp == tLevel) |
||
636 | else |
||
637 | lazyr.d("Search for target under lvl "..tmp) |
||
638 | return (tmp > tLevel) |
||
639 | end |
||
640 | end |
||
641 | end |
||
642 | |||
643 | function lazyr.masks.TargetType(type) |
||
644 | return function() |
||
645 | return (type == UnitCreatureType("target")) |
||
646 | end |
||
647 | end |
||
648 | |||
649 | function lazyr.masks.TargetNamed(nameRegex) |
||
650 | return function() |
||
651 | local tName = UnitName("target") |
||
652 | if (tName and string.find(tName, nameRegex)) then |
||
653 | return true |
||
654 | end |
||
655 | return false |
||
656 | end |
||
657 | end |
||
658 | |||
659 | function lazyr.masks.TargetNPC() |
||
660 | return function() |
||
661 | return not UnitIsPlayer("target") |
||
662 | end |
||
663 | end |
||
664 | |||
665 | function lazyr.masks.TargetHostile() |
||
666 | return function() |
||
667 | -- http://www.wowwiki.com/API_UnitReaction |
||
668 | local reaction = UnitReaction("player", "target") |
||
669 | if (not reaction) then |
||
670 | -- dunno... |
||
671 | return false |
||
672 | end |
||
673 | return (reaction <= 3) |
||
674 | end |
||
675 | end |
||
676 | |||
677 | function lazyr.masks.TargetInCombat() |
||
678 | return function() |
||
679 | return UnitAffectingCombat("target") |
||
680 | end |
||
681 | end |
||
682 | |||
683 | function lazyr.masks.TargetAlive() |
||
684 | return function() |
||
685 | if UnitName("target") then |
||
686 | return (not UnitIsDead("target")) |
||
687 | else |
||
688 | return false |
||
689 | end |
||
690 | end |
||
691 | end |
||
692 | |||
693 | function lazyr.masks.TargetCCd() |
||
694 | return function() |
||
695 | for texture, ttInfo in lrLocale.CC_TTS do |
||
696 | local ttTitle = ttInfo[1] |
||
697 | local ttBody = ttInfo[2] |
||
698 | if (lazyr.masks.HasBuffOrDebuff("target", "debuff", texture, ttTitle, ttBody)) then |
||
699 | if (lazyr.perPlayerConf.showReasonForTargetCCd) then |
||
700 | if (not ttTitle) then |
||
701 | ttTitle = texture |
||
702 | end |
||
703 | lazyr.p("ifTargetCCd: target afflicted by "..ttTitle) |
||
704 | end |
||
705 | return true |
||
706 | end |
||
707 | end |
||
708 | return false |
||
709 | end |
||
710 | end |
||
711 | |||
712 | function lazyr.masks.IsMarked() |
||
713 | return function() |
||
714 | if (not lrLocale.HuntersMark_TTS) then |
||
715 | lazyr.p("Sorry, ifHuntersMark not supported for your locale.") |
||
716 | return false |
||
717 | end |
||
718 | for texture, ttTitle in lrLocale.HuntersMark_TTS do |
||
719 | if (lazyr.masks.HasBuffOrDebuff("player", "debuff", texture, ttTitle)) then |
||
720 | lazyr.d("player afflicted by Hunter's Mark") |
||
721 | return true |
||
722 | end |
||
723 | end |
||
724 | return false |
||
725 | end |
||
726 | end |
||
727 | |||
728 | function lazyr.masks.IsPolymorphed() |
||
729 | return function() |
||
730 | if (not lrLocale.Polymorph_TTS) then |
||
731 | lazyr.p("Sorry, ifPolymorphed not supported for your locale.") |
||
732 | return false |
||
733 | end |
||
734 | for texture, ttTitle in lrLocale.Polymorph_TTS do |
||
735 | if (lazyr.masks.HasBuffOrDebuff("player", "debuff", texture, ttTitle)) then |
||
736 | lazyr.d("player afflicted by Polymorph") |
||
737 | return true |
||
738 | end |
||
739 | end |
||
740 | return false |
||
741 | end |
||
742 | end |
||
743 | |||
744 | |||
745 | function lazyr.masks.IsBleeding() |
||
746 | return function() |
||
747 | if (not lrLocale.Bleed_TTS) then |
||
748 | lazyr.p("Sorry, ifBleeding not supported for your locale.") |
||
749 | return false |
||
750 | end |
||
751 | for texture, ttTitle in lrLocale.Bleed_TTS do |
||
752 | if (lazyr.masks.HasBuffOrDebuff("player", "debuff", texture, ttTitle)) then |
||
753 | if (lazyr.perPlayerConf.showReasonForTargetCCd) then |
||
754 | if (not ttTitle) then |
||
755 | ttTitle = texture |
||
756 | end |
||
757 | lazyr.p("ifBleeding: player afflicted by "..ttTitle) |
||
758 | end |
||
759 | return true |
||
760 | end |
||
761 | end |
||
762 | return false |
||
763 | end |
||
764 | end |
||
765 | |||
766 | function lazyr.masks.IsDotted() |
||
767 | return function() |
||
768 | if (not lrLocale.DOT_TTS) then |
||
769 | lazyr.p("Sorry, ifDotted not supported for your locale.") |
||
770 | return false |
||
771 | end |
||
772 | for idx, ttBody in lrLocale.DOT_TTS do |
||
773 | if (lazyr.masks.HasBuffOrDebuff("player", "debuff", nil, nil, ttBody)) then |
||
774 | if (lazyr.perPlayerConf.showReasonForTargetCCd) then |
||
775 | lazyr.p("ifDotted: player afflicted by "..ttBody) |
||
776 | end |
||
777 | return true |
||
778 | end |
||
779 | end |
||
780 | return false |
||
781 | end |
||
782 | end |
||
783 | |||
784 | function lazyr.masks.IsFeared() |
||
785 | return function() |
||
786 | if (not lrLocale.FEAR_TTS) then |
||
787 | lazyr.p("Sorry, ifFeared not supported for your locale.") |
||
788 | return false |
||
789 | end |
||
790 | for idx, ttBody in lrLocale.FEAR_TTS do |
||
791 | if (lazyr.masks.HasBuffOrDebuff("player", "debuff", nil, nil, ttBody)) then |
||
792 | if (lazyr.perPlayerConf.showReasonForTargetCCd) then |
||
793 | lazyr.p("ifFeared: player afflicted by "..ttBody) |
||
794 | end |
||
795 | return true |
||
796 | end |
||
797 | end |
||
798 | return false |
||
799 | end |
||
800 | end |
||
801 | |||
802 | function lazyr.masks.IsImmobile() |
||
803 | return function() |
||
804 | if (not lrLocale.IMMOBILE_TTS) then |
||
805 | lazyr.p("Sorry, ifImmobile not supported for your locale.") |
||
806 | return false |
||
807 | end |
||
808 | for idx, ttBody in lrLocale.IMMOBILE_TTS do |
||
809 | if (lazyr.masks.HasBuffOrDebuff("player", "debuff", nil, nil, ttBody)) then |
||
810 | if (lazyr.perPlayerConf.showReasonForTargetCCd) then |
||
811 | lazyr.p("ifImmobile: player afflicted by "..ttBody) |
||
812 | end |
||
813 | return true |
||
814 | end |
||
815 | end |
||
816 | return false |
||
817 | end |
||
818 | end |
||
819 | |||
820 | function lazyr.masks.UnitStunned(unitId) |
||
821 | return function() |
||
822 | if (not lrLocale.STUNNED_TTS) then |
||
823 | lazyr.p("Sorry, if[Target]Stunned not supported for your locale.") |
||
824 | return false |
||
825 | end |
||
826 | for idx, ttBody in lrLocale.STUNNED_TTS do |
||
827 | if (lazyr.masks.HasBuffOrDebuff(unitId, "debuff", nil, nil, ttBody)) then |
||
828 | if (lazyr.perPlayerConf.showReasonForTargetCCd) then |
||
829 | lazyr.p("ifStunned: played afflicted by "..ttBody) |
||
830 | end |
||
831 | return true |
||
832 | end |
||
833 | end |
||
834 | return false |
||
835 | end |
||
836 | end |
||
837 | |||
838 | function lazyr.masks.UnitSlowed(unitId) |
||
839 | return function() |
||
840 | if (not lrLocale.SLOWED_TTS) then |
||
841 | lazyr.p("Sorry, if[Target]Slowed not supported for your locale.") |
||
842 | return false |
||
843 | end |
||
844 | for idx, ttBody in lrLocale.SLOWED_TTS do |
||
845 | if (lazyr.masks.HasBuffOrDebuff(unitId, "debuff", nil, nil, ttBody)) then |
||
846 | if (lazyr.perPlayerConf.showReasonForTargetCCd) then |
||
847 | lazyr.p("ifSlowed: player afflicted by "..ttBody) |
||
848 | end |
||
849 | return true |
||
850 | end |
||
851 | end |
||
852 | return false |
||
853 | end |
||
854 | end |
||
855 | |||
856 | function lazyr.masks.IsInstance(unitId) |
||
857 | return function() |
||
858 | if (not lrLocale.INSTANCES) then |
||
859 | lazyr.p("Sorry, ifInstance not supported for your locale.") |
||
860 | return false |
||
861 | end |
||
862 | zone = GetZoneText() |
||
863 | for idx, instance in lrLocale.INSTANCES do |
||
864 | if string.find(zone, instance) then |
||
865 | return true |
||
866 | end |
||
867 | end |
||
868 | return false |
||
869 | end |
||
870 | end |
||
871 | function lazyr.masks.IsBattleground(unitId) |
||
872 | return function() |
||
873 | for i = 1, MAX_BATTLEFIELD_QUEUES do |
||
874 | status, mapName, instanceID = GetBattlefieldStatus(i) |
||
875 | if (status == "active") then |
||
876 | lazyr.d("You're in batteground: "..mapName) |
||
877 | return true |
||
878 | end |
||
879 | |||
880 | return false |
||
881 | end |
||
882 | end |
||
883 | end |
||
884 | |||
885 | function lazyr.masks.TargetIsCasting(nameRegex) |
||
886 | return function() |
||
887 | if (lazyr.interrupt.targetCasting and ((GetTime() - lazyr.interrupt.castingDetectedAt) <= 5)) then |
||
888 | if (not nameRegex or nameRegex == "") then |
||
889 | return true |
||
890 | end |
||
891 | if (string.find(lazyr.interrupt.targetCasting, nameRegex)) then |
||
892 | return true |
||
893 | end |
||
894 | end |
||
895 | return false |
||
896 | end |
||
897 | end |
||
898 | |||
899 | -- if any of the exception criteria return true, we return FALSE |
||
900 | function lazyr.masks.InterruptExceptionCriteria() |
||
901 | return function() |
||
902 | lazyr.masks.alreadyInsideInterruptExceptionCriteria = true |
||
903 | local actionInfos = lazyr.ParseForm(lrConf.interruptExceptionCriteria) |
||
904 | lazyr.masks.alreadyInsideInterruptExceptionCriteria = false |
||
905 | |||
906 | for idx, actionInfo in actionInfos do |
||
907 | local action = actionInfo[1] -- should be nil |
||
908 | local masks = actionInfo[2] |
||
909 | local areAllTrue = true |
||
910 | if (masks) then |
||
911 | for idx, mask in masks do |
||
912 | if (not mask()) then |
||
913 | areAllTrue = false |
||
914 | break |
||
915 | end |
||
916 | end |
||
917 | if (areAllTrue) then |
||
918 | -- all criteria on this line returned true, so this mask returns false |
||
919 | return false |
||
920 | end |
||
921 | end |
||
922 | end |
||
923 | |||
924 | return true |
||
925 | end |
||
926 | end |
||
927 | |||
928 | function lazyr.masks.TargetElite() |
||
929 | return function() |
||
930 | return string.find(UnitClassification("target"), "elite") |
||
931 | end |
||
932 | end |
||
933 | |||
934 | function lazyr.masks.TargetInMeleRange() |
||
935 | return function() |
||
936 | return CheckInteractDistance("target", 1) |
||
937 | end |
||
938 | end |
||
939 | |||
940 | function lazyr.masks.TargetInBlindRange() |
||
941 | return function() |
||
942 | return CheckInteractDistance("target", 2) |
||
943 | end |
||
944 | end |
||
945 | |||
946 | function lazyr.masks.PlayerInCombat() |
||
947 | return function() |
||
948 | return lazyr.isInCombat |
||
949 | end |
||
950 | end |
||
951 | |||
952 | function lazyr.masks.PlayerInGroup() |
||
953 | return function() |
||
954 | return (GetNumPartyMembers() > 0) |
||
955 | end |
||
956 | end |
||
957 | |||
958 | function lazyr.masks.PlayerInRaid() |
||
959 | return function() |
||
960 | return (GetNumRaidMembers() > 0) |
||
961 | end |
||
962 | end |
||
963 | |||
964 | function lazyr.masks.PlayerInGroupOrRaid() |
||
965 | return function() |
||
966 | return ((GetNumPartyMembers() > 0) or (GetNumRaidMembers() > 0)) |
||
967 | end |
||
968 | end |
||
969 | |||
970 | |||
971 | -- if you don't eviscerate now, will you have time for 2 ticks before the target dies? |
||
972 | -- we determine the rate of damage, and estimate when the target will be dead |
||
973 | -- then we look at the last tick, and add 4 seconds, and see if that's before he'll die. |
||
974 | function lazyr.masks.IsLastChance() |
||
975 | return function() |
||
976 | -- MobInfo-2 required |
||
977 | if (not MobHealth_GetTargetCurHP) then |
||
978 | return false |
||
979 | end |
||
980 | if (GetComboPoints() == 0 or not UnitName("target") or UnitHealth("target") == 0) then |
||
981 | return false |
||
982 | end |
||
983 | |||
984 | local n = lazyr.targetHealthHistory:GetN() |
||
985 | -- we want at least a couple data points |
||
986 | if (n < 3) then |
||
987 | return false |
||
988 | end |
||
989 | |||
990 | local startTime = GetTime() |
||
991 | |||
992 | -- m is the slope, or hp per second |
||
993 | local m = lazyr.targetHealthHistory:ComputeSlope() |
||
994 | if (not m) then |
||
995 | return false |
||
996 | end |
||
997 | if (m >= 0) then |
||
998 | lazyr.d("IsLastChance: m is positive? target healing?") |
||
999 | return false |
||
1000 | end |
||
1001 | local currentHp = lazyr.masks.GetUnitHealth("target") |
||
1002 | local secondsTilDeath = math.abs(currentHp / m) |
||
1003 | |||
1004 | -- now, we know when he'll die. |
||
1005 | -- look at the last tick, and add 4 seconds (and a 1/4s buffer), and see |
||
1006 | -- if that's before he'll die. |
||
1007 | -- Also consider the player's current energy: |
||
1008 | -- Maybe we won't need 2 ticks... to be really smart, we'd need to know what attack |
||
1009 | -- the player will use if he doesn't evisc right now... well, the maximum attack is |
||
1010 | -- backstab (60), but more likely a SS (40-45). |
||
1011 | -- Okay, for simplicity let's just assume the player will SS (40). |
||
1012 | local ticksNeeded = 2 |
||
1013 | local currentEnergy = lazyr.masks.GetUnitMana("player") |
||
1014 | if (currentEnergy >= 60) then |
||
1015 | ticksNeeded = 1 |
||
1016 | elseif (currentEnergy >= 80) then |
||
1017 | ticksNeeded = 0 |
||
1018 | end |
||
1019 | local whenTicks = lazyr.lastTickTime + (ticksNeeded * 2) |
||
1020 | |||
1021 | local isLastChance |
||
1022 | if ((whenTicks + .25) > (GetTime() + secondsTilDeath)) then |
||
1023 | isLastChance = true |
||
1024 | else |
||
1025 | isLastChance = false |
||
1026 | end |
||
1027 | |||
1028 | local msg = "IsLastChance: n: "..n.. |
||
1029 | ", m: "..math.abs(string.format("%.1f", m)).."hp/s, ".. |
||
1030 | " hp: "..currentHp.. ", DEAD IN ".. |
||
1031 | string.format("%.1f", secondsTilDeath).."s (".. |
||
1032 | string.format("%.1f", (GetTime() - startTime)).."s)" |
||
1033 | if (isLastChance) then |
||
1034 | msg = msg.." EVISCERATE NOW" |
||
1035 | end |
||
1036 | msg = msg.."." |
||
1037 | lazyr.d(msg) |
||
1038 | |||
1039 | return isLastChance |
||
1040 | end |
||
1041 | end |
||
1042 | |||
1043 | function lazyr.masks.IsEquipped(item) |
||
1044 | return function() |
||
1045 | local itemId |
||
1046 | local itemName |
||
1047 | if (string.find(item, '^%d')) then |
||
1048 | itemId = tonumber(item) |
||
1049 | else |
||
1050 | itemName = item |
||
1051 | end |
||
1052 | for slot = 0, 19 do |
||
1053 | local link = GetInventoryItemLink("player", slot) |
||
1054 | if (link) then |
||
1055 | local id, name = lazyr.IdAndNameFromLink(link) |
||
1056 | if (id) then |
||
1057 | if ((itemId and id == itemId)) then |
||
1058 | return true |
||
1059 | elseif (itemName) then |
||
1060 | if string.lower(name) == string.lower(itemName) then |
||
1061 | return true |
||
1062 | end |
||
1063 | end |
||
1064 | end |
||
1065 | end |
||
1066 | end |
||
1067 | return false |
||
1068 | end |
||
1069 | end |
||
1070 | |||
1071 | function lazyr.masks.IsKeyDown(key) |
||
1072 | return function() |
||
1073 | if (key == "Ctrl") then |
||
1074 | return IsControlKeyDown() |
||
1075 | elseif (key == "Alt") then |
||
1076 | return IsAltKeyDown() |
||
1077 | elseif (key == "Shift") then |
||
1078 | return IsShiftKeyDown() |
||
1079 | end |
||
1080 | return false |
||
1081 | end |
||
1082 | end |
||
1083 | |||
1084 | function lazyr.masks.Every(action, seconds) |
||
1085 | return function() |
||
1086 | if (GetTime() > (action.everyTimer + seconds))or action.everyTimer==nil then |
||
1087 | return true |
||
1088 | end |
||
1089 | return false |
||
1090 | end |
||
1091 | end |
||
1092 | |||
1093 | function lazyr.masks.Timer(action, seconds) |
||
1094 | return function() |
||
1095 | if lazyr.actions[action] then |
||
1096 | if (GetTime() > (lazyr.actions[action].everyTimer + seconds)) then |
||
1097 | return true |
||
1098 | end |
||
1099 | elseif lazyr.forms[action] then |
||
1100 | if (GetTime() > (lazyr.setForm[action].everyTimer + seconds)) then |
||
1101 | return true |
||
1102 | end |
||
1103 | elseif lazyr.items[action] then |
||
1104 | if (GetTime() > (lazyr.item[action].everyTimer + seconds)) then |
||
1105 | return true |
||
1106 | end |
||
1107 | elseif lazyr.pseudoActions[action] then |
||
1108 | if (GetTime() > (lazyr.pseudoActions[action].everyTimer + seconds)) then |
||
1109 | return true |
||
1110 | end |
||
1111 | elseif lazyr.comboActions[action] then |
||
1112 | if (GetTime() > (lazyr.comboActions[action].everyTimer + seconds)) then |
||
1113 | return true |
||
1114 | end |
||
1115 | end |
||
1116 | return false |
||
1117 | end |
||
1118 | end |
||
1119 | |||
1120 | -- :-( |
||
1121 | -- This code is good for a Rogue. It skips over some annoying exceptions that only |
||
1122 | -- Hunters and Druids face. Do not rip off this code unless you're writing a Rogue-only addon. |
||
1123 | function lazyr.masks.PlayerMountedIndex() |
||
1124 | local buffId = 0 |
||
1125 | local mountBuffIndex = nil |
||
1126 | while true do |
||
1127 | local buffIndex = GetPlayerBuff(buffId, "HELPFUL|PASSIVE") |
||
1128 | if (buffIndex < 0) then |
||
1129 | break |
||
1130 | end |
||
1131 | |||
1132 | local texture = GetPlayerBuffTexture(buffIndex) |
||
1133 | |||
1134 | local skip = false |
||
1135 | |||
1136 | if (string.find(texture, "Ability_Mount_") or |
||
1137 | string.find(texture, "Spell_Nature_Swiftness") or |
||
1138 | string.find(texture, "INV_Misc_Foot_Kodo")) then |
||
1139 | |||
1140 | -- Whoa, one exception though: Is it really a mount? (Spotted Frostsaber?) |
||
1141 | -- or just a Hunter in the party with Aspect of the Pack? |
||
1142 | if (string.find(texture, "Ability_Mount_WhiteTiger")) then |
||
1143 | lazyr.d("PlayerMountedIndex: Whoa, Ability_Mount_WhiteTiger is suspect, having to parse TT") |
||
1144 | LazyRogue_Tooltip:ClearLines() |
||
1145 | LazyRogue_Tooltip:SetPlayerBuff(buffIndex) |
||
1146 | local ttText = LazyRogue_TooltipTextLeft2:GetText() |
||
1147 | if (not string.find(ttText, "^"..lrLocale.MOUNTED_BUFF_TT)) then |
||
1148 | lazyr.d("PlayerMountedIndex: IGNORING: it's not really a mount: "..ttText) |
||
1149 | skip = true -- uggh, Lua really needs a continue function |
||
1150 | end |
||
1151 | end |
||
1152 | |||
1153 | if (not skip) then |
||
1154 | lazyr.d("PlayerMountedIndex: OK, you're mounted: "..texture) |
||
1155 | mountBuffIndex = buffIndex |
||
1156 | break |
||
1157 | end |
||
1158 | end |
||
1159 | |||
1160 | buffId = buffId + 1 |
||
1161 | end |
||
1162 | |||
1163 | return mountBuffIndex |
||
1164 | end |
||
1165 | |||
1166 | |||
1167 | function lazyr.masks.PlayerMounted() |
||
1168 | return function() |
||
1169 | return lazyr.masks.PlayerMountedIndex() |
||
1170 | end |
||
1171 | end |
||
1172 | |||
1173 | |||
1174 | function lazyr.masks.InZone(nameRegex) |
||
1175 | return function() |
||
1176 | if (string.find(GetRealZoneText(), nameRegex)) then |
||
1177 | return true |
||
1178 | end |
||
1179 | return false |
||
1180 | end |
||
1181 | end |
||
1182 | |||
1183 | function lazyr.masks.IsPoisoned(weapon) |
||
1184 | return function() |
||
1185 | bMh, tMh, cMh, bOh, tOh, cOh = GetWeaponEnchantInfo(); |
||
1186 | if (weapon == "MainHand" and bMh) then |
||
1187 | return true |
||
1188 | elseif (weapon == "OffHand" and bOh) then |
||
1189 | return true |
||
1190 | else |
||
1191 | return false |
||
1192 | end |
||
1193 | return false |
||
1194 | end |
||
1195 | end |
||
1196 | |||
1197 | function lazyr.masks.IsGlobalCooldown() |
||
1198 | return function() |
||
1199 | if not lazyr.globalCooldownSlot then |
||
1200 | for slot = 1, 120 do |
||
1201 | if (not GetActionText(slot)) then -- ignore any Player macros :-) |
||
1202 | local text = GetActionTexture(slot) |
||
1203 | if (text and (string.find(text, "INV_Misc_Rune_01"))) then |
||
1204 | lazyr.globalCooldownSlot = slot |
||
1205 | break |
||
1206 | end |
||
1207 | end |
||
1208 | end |
||
1209 | if not lazyr.globalCooldownSlot then |
||
1210 | lazyr.p("Sorry -if[Not]GlobalCooldown function is not available to this char.") |
||
1211 | return false |
||
1212 | end |
||
1213 | local start, duration, enable = GetActionCooldown(lazyr.globalCooldownSlot) |
||
1214 | if (enable > 0) then |
||
1215 | return true |
||
1216 | else |
||
1217 | return false |
||
1218 | end |
||
1219 | |||
1220 | |||
1221 | |||
1222 | else |
||
1223 | local start, duration, enable = GetActionCooldown(lazyr.globalCooldownSlot) |
||
1224 | if ( start > 0 and duration > 0 and enable > 0) then |
||
1225 | return true |
||
1226 | else |
||
1227 | return false |
||
1228 | end |
||
1229 | end |
||
1230 | end |
||
1231 | end |
||
1232 | |||
1233 | function lazyr.masks.History(gtLtEq, val, action) |
||
1234 | return function() |
||
1235 | local historySize = table.getn(lazyr.actionHistory) |
||
1236 | if (gtLtEq == ">") then |
||
1237 | local i = val + 1 |
||
1238 | while true do |
||
1239 | if (not lazyr.actionHistory[i]) then |
||
1240 | return false |
||
1241 | end |
||
1242 | if (lazyr.actionHistory[i] == action) then |
||
1243 | return true |
||
1244 | end |
||
1245 | i = i + 1 |
||
1246 | end |
||
1247 | elseif (gtLtEq == "<") then |
||
1248 | local i = val - 1 |
||
1249 | while (i > 0) do |
||
1250 | if (lazyr.actionHistory[i] and lazyr.actionHistory[i] == action) then |
||
1251 | return true |
||
1252 | end |
||
1253 | i = i - 1 |
||
1254 | end |
||
1255 | return false |
||
1256 | else |
||
1257 | if (lazyr.actionHistory[val] and lazyr.actionHistory[val] == action) then |
||
1258 | return true |
||
1259 | end |
||
1260 | return false |
||
1261 | end |
||
1262 | end |
||
1263 | end |
||
1264 | |||
1265 | |||
1266 | |||
1267 | |||
1268 | function lazyr.ParseArg(arg) |
||
1269 | -- remove comments: # .... or // .... |
||
1270 | -- trim leading/trailing whitespace |
||
1271 | -- ignore blank lines |
||
1272 | arg = string.gsub(arg, "#.*", "") |
||
1273 | arg = string.gsub(arg, "//.*", "") |
||
1274 | arg = string.gsub(arg, "%-%-.*", "") |
||
1275 | arg = string.gsub(arg, "^%s+", "") |
||
1276 | arg = string.gsub(arg, "%s+$", "") |
||
1277 | if (arg == "") then |
||
1278 | return 0 |
||
1279 | end |
||
1280 | |||
1281 | local bits = {} |
||
1282 | for bit in string.gfind(arg, "[^\-]+") do |
||
1283 | table.insert(bits, bit) |
||
1284 | end |
||
1285 | |||
1286 | local action |
||
1287 | local masks = {} |
||
1288 | for idx, bit in bits do |
||
1289 | if (string.sub(bit, 1, 6) == "action") then |
||
1290 | if (not lazyr.re(bit, "^action=(.+)$")) then |
||
1291 | lazyr.p("Can't parse: "..bit) |
||
1292 | return nil |
||
1293 | end |
||
1294 | local thisAction = lazyr.match1 |
||
1295 | if (not lazyr.otherActions[thisAction]) then |
||
1296 | lazyr.otherActions[thisAction] = lazyr.Action:New(thisAction, thisAction) |
||
1297 | end |
||
1298 | action = lazyr.otherActions[thisAction] |
||
1299 | elseif (bit == "adrenaline") then |
||
1300 | action = lazyr.actions.adrenalineRush |
||
1301 | elseif (bit == "ambush") then |
||
1302 | action = lazyr.actions.ambush |
||
1303 | elseif (bit == "cbAmbush") then |
||
1304 | action = lazyr.comboActions.cbAmbush |
||
1305 | elseif (bit == "berserking") then |
||
1306 | action = lazyr.actions.berserking |
||
1307 | elseif (bit == "bladeFlurry" or bit == "bladeflurry") then |
||
1308 | action = lazyr.actions.bladeFlurry |
||
1309 | elseif (bit == "blind") then |
||
1310 | action = lazyr.actions.blind |
||
1311 | elseif (bit == "bs") then |
||
1312 | action = lazyr.actions.backstab |
||
1313 | table.insert(masks, lazyr.masks.BehindAttackHasNotFailedRecently()) |
||
1314 | elseif (bit == "cbEvisc" or bit == "cbevisc") then |
||
1315 | action = lazyr.comboActions.cbEvisc |
||
1316 | elseif (bit == "coldBlood" or bit == "coldblood") then |
||
1317 | action = lazyr.actions.coldBlood |
||
1318 | elseif (bit == "cs") then |
||
1319 | action = lazyr.actions.cheapShot |
||
1320 | elseif (bit == "dismount") then |
||
1321 | action = lazyr.pseudoActions.dismount |
||
1322 | elseif (bit == "evasion") then |
||
1323 | action = lazyr.actions.evasion |
||
1324 | elseif (bit == "evisc") then |
||
1325 | action = lazyr.actions.eviscerate |
||
1326 | elseif (bit == "expose") then |
||
1327 | action = lazyr.actions.exposeArmor |
||
1328 | elseif (bit == "feint") then |
||
1329 | action = lazyr.actions.feint |
||
1330 | table.insert(masks, lazyr.masks.PlayerInGroupOrRaid()) |
||
1331 | elseif (bit == "garrote") then |
||
1332 | action = lazyr.actions.garrote |
||
1333 | table.insert(masks, lazyr.masks.BehindAttackHasNotFailedRecently()) |
||
1334 | elseif (bit == "ghostly") then |
||
1335 | action = lazyr.actions.ghostlyStrike |
||
1336 | elseif (bit == "gouge") then |
||
1337 | action = lazyr.actions.gouge |
||
1338 | table.insert(masks, lazyr.masks.InFrontAttackHasNotFailedRecently()) |
||
1339 | elseif (bit == "hemo") then |
||
1340 | action = lazyr.actions.hemorrhage |
||
1341 | elseif (bit == "kick") then |
||
1342 | action = lazyr.actions.kick |
||
1343 | table.insert(masks, lazyr.masks.TargetInMeleRange()) |
||
1344 | elseif (bit == "ks") then |
||
1345 | action = lazyr.actions.kidneyShot |
||
1346 | elseif (bit == "ping") then |
||
1347 | action = lazyr.pseudoActions.ping |
||
1348 | elseif (bit == "premeditation") then |
||
1349 | action = lazyr.actions.premeditation |
||
1350 | elseif (bit == "preparation") then |
||
1351 | action = lazyr.actions.preparation |
||
1352 | elseif (bit == "pickPocket") then |
||
1353 | action = lazyr.actions.pickPocket |
||
1354 | elseif (bit == "riposte") then |
||
1355 | action = lazyr.actions.riposte |
||
1356 | elseif (bit == "rupture") then |
||
1357 | action = lazyr.actions.rupture |
||
1358 | elseif (bit == "sap") then |
||
1359 | action = lazyr.actions.sap |
||
1360 | elseif (bit == "snd") then |
||
1361 | action = lazyr.actions.sliceNDice |
||
1362 | elseif (bit == "sprint") then |
||
1363 | action = lazyr.actions.sprint |
||
1364 | elseif (bit == "ss") then |
||
1365 | action = lazyr.actions.sinisterStrike |
||
1366 | elseif (bit == "stealth") then |
||
1367 | action = lazyr.actions.stealth |
||
1368 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.BuffOrDebuffMask("Stealth"), true)) |
||
1369 | elseif (bit == "stop") then |
||
1370 | action = lazyr.pseudoActions.stop |
||
1371 | elseif (bit == "stopAll" or bit == "stopall") then |
||
1372 | action = lazyr.pseudoActions.stopAll |
||
1373 | elseif (bit == "tea") then |
||
1374 | action = lazyr.items.thistleTea |
||
1375 | elseif (bit == "perception") then |
||
1376 | action = lazyr.actions.humanRacial |
||
1377 | elseif (bit == "stoneForm") then |
||
1378 | action = lazyr.actions.dwarfRacial |
||
1379 | elseif (bit == "escapeArtist") then |
||
1380 | action = lazyr.actions.gnomeRacial |
||
1381 | elseif (bit == "bloodFury") then |
||
1382 | action = lazyr.actions.orcRacial |
||
1383 | elseif (bit == "warStomp") then |
||
1384 | action = lazyr.actions.taurenRacial |
||
1385 | elseif (bit == "forsaken") then |
||
1386 | action = lazyr.actions.undeadRacial |
||
1387 | elseif (bit == "throw") then |
||
1388 | action = lazyr.actions.throw |
||
1389 | elseif (bit == "bow") then |
||
1390 | action = lazyr.actions.bow |
||
1391 | elseif (bit == "gun") then |
||
1392 | action = lazyr.actions.gun |
||
1393 | elseif (bit == "crossbow") then |
||
1394 | action = lazyr.actions.crossbow |
||
1395 | elseif (bit == "cannibalize") then |
||
1396 | action = lazyr.actions.cannibalize |
||
1397 | elseif (bit == "targetAssist") then |
||
1398 | action = lazyr.pseudoActions.targetAssist |
||
1399 | elseif (bit == "targetNearest") then |
||
1400 | action = lazyr.pseudoActions.targetNearest |
||
1401 | elseif (bit == "autoAttack") then |
||
1402 | action = lazyr.pseudoActions.autoAttack |
||
1403 | elseif (string.sub(bit, 1, 11) == "applyPoison") then |
||
1404 | lazyr.d("applyPoison") |
||
1405 | if (not lazyr.re(bit, "^applyPoison(%a+)=(.+)$")) then |
||
1406 | lazyr.p("Can't parse: "..bit) |
||
1407 | return nil |
||
1408 | end |
||
1409 | if (lazyr.match1 ~="MainHand" and lazyr.match1 ~="OffHand") then |
||
1410 | lazyr.p("Only MainHand and OffHand available, but not"..lazyr.match1) |
||
1411 | return nil |
||
1412 | end |
||
1413 | local weaponName=lazyr.match1 |
||
1414 | local poisonName=lazyr.match2 |
||
1415 | local key = weaponName..":"..poisonName |
||
1416 | if (not lazyr.poisonsUse[key]) then |
||
1417 | lazyr.poisonsUse[key] = lazyr.applyPoison:New(poisonName, weaponName) |
||
1418 | end |
||
1419 | action = lazyr.poisonsUse[key] |
||
1420 | |||
1421 | elseif (string.sub(bit, 1, 5) == "sayIn") then |
||
1422 | if (not lazyr.re(bit, "^sayIn(%a+)=(.+)$")) then |
||
1423 | lazyr.p("Can't parse: "..bit) |
||
1424 | return nil |
||
1425 | end |
||
1426 | if lazyr.match1 ~="Guild" and lazyr.match1 ~="Party" and lazyr.match1 ~="Raid" and lazyr.match1 ~="Say" and lazyr.match1 ~="Emote" and lazyr.match1 ~="RAID_WARNING" then |
||
1427 | lazyr.p("Unknown channel name: "..lazyr.match1) |
||
1428 | return nil |
||
1429 | end |
||
1430 | -- XXX: this will not work! these globals are set at parse time, but they |
||
1431 | -- might be changed before run time! |
||
1432 | lazyr.sayInChannel = lazyr.match1 |
||
1433 | lazyr.sayInMessage = lazyr.match2 |
||
1434 | |||
1435 | action = lazyr.pseudoActions.sayIn |
||
1436 | |||
1437 | elseif (string.sub(bit, 1, 8) == "setForm=") then |
||
1438 | if (not lazyr.re(bit, "^setForm=(.+)$")) then |
||
1439 | lazyr.p("Can't parse: "..bit) |
||
1440 | return nil |
||
1441 | end |
||
1442 | local form = lazyr.match1 |
||
1443 | if (not lazyr.forms[form]) then |
||
1444 | lazyr.forms[form] = lazyr.SetForm:New("form"..form, form) |
||
1445 | end |
||
1446 | action = lazyr.forms[form] |
||
1447 | |||
1448 | elseif (string.sub(bit, 1, 14) == "equipMainHand=") then |
||
1449 | if (not lazyr.re(bit, "^equipMainHand=(.+)$")) then |
||
1450 | lazyr.p("Can't parse: "..bit) |
||
1451 | return nil |
||
1452 | end |
||
1453 | local item = lazyr.match1 |
||
1454 | local itemId |
||
1455 | local itemName |
||
1456 | if (string.find(item, '^%d')) then |
||
1457 | itemId = tonumber(item) |
||
1458 | itemName = "Item "..itemId |
||
1459 | else |
||
1460 | itemName = item |
||
1461 | end |
||
1462 | if (not lazyr.mainHandItems[item]) then |
||
1463 | lazyr.mainHandItems[item] = lazyr.EquipItem:New(item, itemName, itemId, 16) |
||
1464 | end |
||
1465 | action = lazyr.mainHandItems[item] |
||
1466 | |||
1467 | elseif (string.sub(bit, 1, 13) == "equipOffHand=") then |
||
1468 | if (not lazyr.re(bit, "^equipOffHand=(.+)$")) then |
||
1469 | lazyr.p("Can't parse: "..bit) |
||
1470 | return nil |
||
1471 | end |
||
1472 | local item = lazyr.match1 |
||
1473 | local itemId |
||
1474 | local itemName |
||
1475 | if (string.find(item, '^%d')) then |
||
1476 | itemId = tonumber(item) |
||
1477 | itemName = "Item "..itemId |
||
1478 | else |
||
1479 | itemName = item |
||
1480 | end |
||
1481 | if (not lazyr.offHandItems[item]) then |
||
1482 | lazyr.offHandItems[item] = lazyr.EquipItem:New(item, itemName, itemId, 17) |
||
1483 | end |
||
1484 | action = lazyr.offHandItems[item] |
||
1485 | |||
1486 | elseif (string.sub(bit, 1, 3) == "use") then |
||
1487 | if (not lazyr.re(bit, "^use(E?q?u?i?p?p?e?d?)=?(.+)$")) then |
||
1488 | lazyr.p("Can't parse: "..bit) |
||
1489 | return nil |
||
1490 | end |
||
1491 | local equippedOnly = (lazyr.match1 == "Equipped") |
||
1492 | local item = lazyr.match2 |
||
1493 | local itemId |
||
1494 | local itemName |
||
1495 | if (string.find(item, '^%d')) then |
||
1496 | itemId = tonumber(item) |
||
1497 | itemName = "Item "..itemId |
||
1498 | else |
||
1499 | itemName = item |
||
1500 | end |
||
1501 | local myItemSet |
||
1502 | if (equippedOnly) then |
||
1503 | myItemSet = lazyr.equippedItems |
||
1504 | else |
||
1505 | myItemSet = lazyr.items |
||
1506 | end |
||
1507 | if (not myItemSet[item]) then |
||
1508 | myItemSet[item] = lazyr.Item:New(item, itemName, itemId, equippedOnly) |
||
1509 | end |
||
1510 | action = myItemSet[item] |
||
1511 | |||
1512 | elseif (bit == "vanish") then |
||
1513 | action = lazyr.actions.vanish |
||
1514 | |||
1515 | elseif (lazyr.re(bit, "^if(N?o?t?)Equipped=(.+)$")) then |
||
1516 | local negate = lazyr.match1 == "Not" |
||
1517 | local item = lazyr.match2 |
||
1518 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.IsEquipped(item), negate)) |
||
1519 | |||
1520 | elseif (lazyr.re(bit, "^if(N?o?t?)TargetOfTargetClass=(.+)$")) then |
||
1521 | local negate = (lazyr.match1 == "Not") |
||
1522 | |||
1523 | local subMasks = {} |
||
1524 | for class in string.gfind(lazyr.match2, "[^,]+") do |
||
1525 | table.insert(subMasks, lazyr.masks.IsTargetOfTargetClass(class)) |
||
1526 | end |
||
1527 | |||
1528 | table.insert(masks, lazyr.masks.maskGroup(subMasks, negate)) |
||
1529 | |||
1530 | elseif (lazyr.re(bit, "^if(N?o?t?)Dueling$")) then |
||
1531 | local negate = lazyr.match1 == "Not" |
||
1532 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.IsDueling(), negate)) |
||
1533 | |||
1534 | elseif (lazyr.re(bit, "^if(T?a?r?g?e?t?)FlaggedPVP$")) then |
||
1535 | local unit = lazyr.match1 |
||
1536 | table.insert(masks, lazyr.masks.IsFlaggedPVP(unit)) |
||
1537 | |||
1538 | elseif (lazyr.re(bit, "^if(N?o?t?)TargetOfTarget$")) then |
||
1539 | local negate = (lazyr.match1 == "Not") |
||
1540 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.IsTargetOfTarget(), negate)) |
||
1541 | |||
1542 | elseif (lazyr.re(bit, "^if(N?o?t?)Stealthed$")) then |
||
1543 | local negate = (lazyr.match1 == "Not") |
||
1544 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.IsStealthedMask(), negate)) |
||
1545 | |||
1546 | elseif (lazyr.re(bit, "^if(N?o?t?)InCombat$")) then |
||
1547 | local negate = (lazyr.match1 == "Not") |
||
1548 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.PlayerInCombat(), negate)) |
||
1549 | |||
1550 | elseif (lazyr.re(bit, "^if(N?o?t?)BehindAttackJustFailed$")) then |
||
1551 | local negate = (lazyr.match1 == "Not") |
||
1552 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.BehindAttackFailedRecently(), negate)) |
||
1553 | |||
1554 | elseif (lazyr.re(bit, "^if(N?o?t?)InFrontAttackJustFailed$")) then |
||
1555 | local negate = (lazyr.match1 == "Not") |
||
1556 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.InFrontAttackFailedRecently(), negate)) |
||
1557 | |||
1558 | elseif (lazyr.re(bit, "^if(N?o?t?)InGroup$")) then |
||
1559 | local negate = (lazyr.match1 == "Not") |
||
1560 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.PlayerInGroup(), negate)) |
||
1561 | |||
1562 | elseif (lazyr.re(bit, "^if(N?o?t?)InRaid$")) then |
||
1563 | local negate = (lazyr.match1 == "Not") |
||
1564 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.PlayerInRaid(), negate)) |
||
1565 | |||
1566 | elseif (lazyr.re(bit, "^if(N?o?t?)LastChance$")) then |
||
1567 | local negate = (lazyr.match1 == "Not") |
||
1568 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.IsLastChance(), negate)) |
||
1569 | |||
1570 | elseif (lazyr.re(bit, "^if(N?o?t?)Mounted$")) then |
||
1571 | local negate = (lazyr.match1 == "Not") |
||
1572 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.PlayerMounted(), negate)) |
||
1573 | |||
1574 | elseif (lazyr.re(bit, "^if(N?o?t?)Instance$")) then |
||
1575 | local negate = (lazyr.match1 == "Not") |
||
1576 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.IsInstance(), negate)) |
||
1577 | |||
1578 | elseif (lazyr.re(bit, "^if(N?o?t?)Battleground$")) then |
||
1579 | local negate = (lazyr.match1 == "Not") |
||
1580 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.IsBattleground(), negate)) |
||
1581 | |||
1582 | elseif (lazyr.re(bit, "^if(N?o?t?)Ganked$")) then |
||
1583 | local negate = (lazyr.match1 == "Not") |
||
1584 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.IsBeingGanked(), negate)) |
||
1585 | |||
1586 | elseif (lazyr.re(bit, "^if(N?o?t?)FlagRunner$")) then |
||
1587 | local negate = (lazyr.match1 == "Not") |
||
1588 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.IsFlagRunner(), negate)) |
||
1589 | |||
1590 | elseif (lazyr.re(bit, "^if(C?b?)KillShot=?(%d?%d?%d?)%%?$")) then |
||
1591 | local assumeCBActive = false |
||
1592 | local goalPct = 100 |
||
1593 | if (bit == "ifKillShot" and action ~= lazyr.actions.eviscerate) then |
||
1594 | lazyr.p("-ifKillShot only works with evisc") |
||
1595 | return nil |
||
1596 | elseif (bit == "^ifCbKillShot$" and action ~= lazyr.comboActions.cbEvisc and |
||
1597 | action ~= lazyr.actions.eviscerate) then |
||
1598 | lazyr.p("-ifCbKillShot only works with cbevisc or evisc") |
||
1599 | return nil |
||
1600 | end |
||
1601 | if (lazyr.match2 ~= "") then |
||
1602 | goalPct = tonumber(lazyr.match2) |
||
1603 | end |
||
1604 | table.insert(masks, lazyr.masks.IsEviscKillShot(assumeCBActive, goalPct)) |
||
1605 | |||
1606 | elseif (lazyr.re(bit, "^if([<=>]?)(%d+)cp$") or lazyr.re(bit, "^([<=>]?)(%d+)cp$")) then |
||
1607 | local gtLtEq = lazyr.match1 |
||
1608 | local val = tonumber(lazyr.match2) |
||
1609 | table.insert(masks, lazyr.masks.ComboPoints(val, gtLtEq)) |
||
1610 | |||
1611 | elseif (lazyr.re(bit, "^if([<=>]?)(%d+)attackers$")) then |
||
1612 | local gtLtEq = lazyr.match1 |
||
1613 | local val = tonumber(lazyr.match2) |
||
1614 | table.insert(masks, lazyr.masks.IsBeingAttackedBy(val, gtLtEq)) |
||
1615 | |||
1616 | elseif (lazyr.re(bit, "^if(%a+)([<=>])(%d+)(%%?)(%a+)$") or |
||
1617 | lazyr.re(bit, "^(%a+)([<=>])(%d+)(%%?)(%a+)$")) then |
||
1618 | local unitId = string.lower(lazyr.match1) |
||
1619 | local gtLtEq = lazyr.match2 |
||
1620 | local val = tonumber(lazyr.match3) |
||
1621 | local wantPct = (lazyr.match4 == "%") |
||
1622 | local powerType = lazyr.match5 |
||
1623 | |||
1624 | if (unitId ~= "player" and unitId ~= "target") then |
||
1625 | lazyr.p("UnitId must be Player or Target, "..unitId.." not supported.") |
||
1626 | return nil |
||
1627 | end |
||
1628 | if (powerType ~= "hp" and powerType ~= "mana" and powerType ~= "energy") then |
||
1629 | lazyr.p("Only hp and mana/energy are supported, not: "..powerType) |
||
1630 | return nil |
||
1631 | end |
||
1632 | |||
1633 | table.insert(masks, lazyr.masks.UnitPowerMask(unitId, gtLtEq, val, powerType, wantPct)) |
||
1634 | |||
1635 | elseif (lazyr.re(bit, "^if(N?o?t?)(%a-)(N?o?t?)Active$")) then |
||
1636 | -- Okay, this is a little messy, but it will fix up those |
||
1637 | -- N?o?t?s from capturing pieces of %a- they shouldn't. |
||
1638 | if (lazyr.match1 ~= "" and lazyr.match1 ~= "Not") then |
||
1639 | lazyr.match2 = lazyr.match1..lazyr.match2 |
||
1640 | end |
||
1641 | if (lazyr.match3 ~= "" and lazyr.match3 ~= "Not") then |
||
1642 | lazyr.match2 = lazyr.match2..lazyr.match3 |
||
1643 | end |
||
1644 | local attack = lazyr.match2 |
||
1645 | local negate = (lazyr.match1 == "Not" or lazyr.match3 == "Not") |
||
1646 | |||
1647 | if (attack ~= "Adrenaline" and attack ~= "Berserking" |
||
1648 | and attack ~= "BladeFlurry" and attack ~= "Blind" and attack ~= "ColdBlood" |
||
1649 | and attack ~= "Cs" and attack ~= "Evasion" |
||
1650 | and attack ~= "Expose" and attack ~= "Garrote" and attack ~= "Ghostly" |
||
1651 | and attack ~= "Gouge" and attack ~= "FirstAid" |
||
1652 | and attack ~= "Hemo" and attack ~= "Ks" |
||
1653 | and attack ~= "RecentlyBandaged" and attack ~= "Remorseless" |
||
1654 | and attack ~= "Rupture" and attack ~= "Sap" and attack ~= "Snd" |
||
1655 | and attack ~= "Vanish") then |
||
1656 | lazyr.p("Only Adrenaline, Berserking, BladeFlurry, Blind, ColdBlood, Cs, Evasion, Expose, FirstAid (Bandage), Garrote, Ghostly, Gouge, Hemo, Ks, RecentlyBandaged, Remorseless, Rupture, Sap, Snd, and Vanish are supported, not: "..attack) |
||
1657 | return nil |
||
1658 | end |
||
1659 | |||
1660 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.BuffOrDebuffMask(attack), negate)) |
||
1661 | |||
1662 | elseif (lazyr.re(bit, "^if(N?o?t?)GlobalCooldown$")) then |
||
1663 | local negate = (lazyr.match1 == "Not" ) |
||
1664 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.IsGlobalCooldown(), negate)) |
||
1665 | |||
1666 | elseif (lazyr.re(bit, "^if(N?o?t?)TargetClass=?(.+)$")) then |
||
1667 | local negate = (lazyr.match1 == "Not") |
||
1668 | local subMasks = {} |
||
1669 | for class in string.gfind(lazyr.match2, "[^,]+") do |
||
1670 | table.insert(subMasks, lazyr.masks.TargetClass(class)) |
||
1671 | end |
||
1672 | table.insert(masks, lazyr.masks.maskGroup(subMasks, negate)) |
||
1673 | |||
1674 | elseif (lazyr.re(bit, "^if(N?o?t?)TargetLevel([<=>])(%d+)$")) then |
||
1675 | local negate = (lazyr.match1 == "Not" ) |
||
1676 | local gtLtEq = lazyr.match2 |
||
1677 | local val = tonumber(lazyr.match3) |
||
1678 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.TargetLevel(gtLtEq, val), negate)) |
||
1679 | |||
1680 | |||
1681 | elseif (lazyr.re(bit, "^if(N?o?t?)TargetMyLevel([<=>])(%a*)(%d+)$")) then |
||
1682 | local val = nil |
||
1683 | local negate = (lazyr.match1 == "Not" ) |
||
1684 | local gtLtEq = lazyr.match2 |
||
1685 | if lazyr.match3 == "plus" or lazyr.match3 == "" then |
||
1686 | val = tonumber(lazyr.match4) |
||
1687 | elseif lazyr.match3 == "minus" then |
||
1688 | val = tonumber(lazyr.match4*-1) |
||
1689 | else |
||
1690 | lazyr.d("unable to determine plus/minus sign") |
||
1691 | return nil |
||
1692 | end |
||
1693 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.TargetMyLevel(gtLtEq, val), negate)) |
||
1694 | |||
1695 | elseif (lazyr.re(bit, "^if(N?o?t?)TargetType=?(.+)$")) then |
||
1696 | local negate = (lazyr.match1 == "Not") |
||
1697 | local subMasks = {} |
||
1698 | for type in string.gfind(lazyr.match2, "[^,]+") do |
||
1699 | table.insert(subMasks, lazyr.masks.TargetType(type)) |
||
1700 | end |
||
1701 | table.insert(masks, lazyr.masks.maskGroup(subMasks, negate)) |
||
1702 | |||
1703 | elseif (lazyr.re(bit, "^if(N?o?t?)TargetNamed=(.+)$")) then |
||
1704 | local negate = (lazyr.match1 == "Not") |
||
1705 | local nameRegex = lazyr.match2 |
||
1706 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.TargetNamed(nameRegex), negate)) |
||
1707 | |||
1708 | elseif (lazyr.re(bit, "^if(N?o?t?)TargetNPC$")) then |
||
1709 | local negate = (lazyr.match1 == "Not") |
||
1710 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.TargetNPC(), negate)) |
||
1711 | |||
1712 | elseif (lazyr.re(bit, "^if(N?o?t?)TargetHostile$")) then |
||
1713 | local negate = (lazyr.match1 == "Not") |
||
1714 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.TargetHostile(), negate)) |
||
1715 | |||
1716 | elseif (lazyr.re(bit, "^if(N?o?t?)TargetInCombat$")) then |
||
1717 | local negate = (lazyr.match1 == "Not") |
||
1718 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.TargetInCombat(), negate)) |
||
1719 | |||
1720 | elseif (lazyr.re(bit, "^if(N?o?t?)TargetSlowed$")) then |
||
1721 | local negate = (lazyr.match1 == "Not" ) |
||
1722 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.UnitSlowed("target"), negate)) |
||
1723 | |||
1724 | elseif (lazyr.re(bit, "^if(N?o?t?)Slowed$")) then |
||
1725 | local negate = (lazyr.match1 == "Not") |
||
1726 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.UnitSlowed("player"), negate)) |
||
1727 | |||
1728 | elseif (lazyr.re(bit, "^if(N?o?t?)TargetStunned$")) then |
||
1729 | local negate = (lazyr.match1 == "Not" ) |
||
1730 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.UnitStunned("target"), negate)) |
||
1731 | |||
1732 | elseif (lazyr.re(bit, "^if(N?o?t?)Stunned$")) then |
||
1733 | local negate = (lazyr.match1 == "Not") |
||
1734 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.UnitStunned("player"), negate)) |
||
1735 | |||
1736 | elseif (lazyr.re(bit, "^if(N?o?t?)Feared$")) then |
||
1737 | local negate = (lazyr.match1 == "Not") |
||
1738 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.IsFeared(), negate)) |
||
1739 | |||
1740 | elseif (lazyr.re(bit, "^if(N?o?t?)Immobile$")) then |
||
1741 | local negate = (lazyr.match1 == "Not") |
||
1742 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.IsImmobile(), negate)) |
||
1743 | |||
1744 | elseif (lazyr.re(bit, "^if(N?o?t?)TargetAlive$")) then |
||
1745 | local negate = (lazyr.match1 == "Not") |
||
1746 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.TargetAlive(), negate)) |
||
1747 | |||
1748 | elseif (lazyr.re(bit, "^if(N?o?t?)TargetCCd$")) then |
||
1749 | local negate = (lazyr.match1 == "Not") |
||
1750 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.TargetCCd(), negate)) |
||
1751 | |||
1752 | elseif (lazyr.re(bit, "^if(N?o?t?)TargetIsCasting=?(.*)$")) then |
||
1753 | local negate = (lazyr.match1 == "Not") |
||
1754 | if (lazyr.match2 ~= "") then |
||
1755 | local subMasks = {} |
||
1756 | for nameRegex in string.gfind(lazyr.match2, "[^,]+") do |
||
1757 | table.insert(subMasks, lazyr.masks.TargetIsCasting(nameRegex)) |
||
1758 | end |
||
1759 | table.insert(masks, lazyr.masks.maskGroup(subMasks, negate)) |
||
1760 | else |
||
1761 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.TargetIsCasting(), negate)) |
||
1762 | end |
||
1763 | -- XXX this is kinda strange, should rethink this. |
||
1764 | if (not negate and not lazyr.masks.alreadyInsideInterruptExceptionCriteria) then |
||
1765 | table.insert(masks, lazyr.masks.InterruptExceptionCriteria()) |
||
1766 | end |
||
1767 | |||
1768 | elseif (lazyr.re(bit, "^if(N?o?t?)TargetElite$")) then |
||
1769 | local negate = (lazyr.match1 == "Not") |
||
1770 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.TargetElite(), negate)) |
||
1771 | |||
1772 | elseif (lazyr.re(bit, "^if(N?o?t?)(%a+)Down$")) then |
||
1773 | local negate = (lazyr.match1 == "Not") |
||
1774 | local key = lazyr.match2 |
||
1775 | if (key ~= "Ctrl" and key ~= "Alt" and key ~= "Shift") then |
||
1776 | lazyr.p("Only Ctrl, Alt, and Shift are supported, not: "..key) |
||
1777 | end |
||
1778 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.IsKeyDown(key), negate)) |
||
1779 | |||
1780 | elseif (lazyr.re(bit, "^every(%d+)s$")) then |
||
1781 | if (action == nil) then |
||
1782 | lazyr.p("you must put the action before the -everyXXs") |
||
1783 | return nil |
||
1784 | end |
||
1785 | local val = tonumber(lazyr.match1) |
||
1786 | table.insert(masks, lazyr.masks.Every(action, val)) |
||
1787 | |||
1788 | elseif (lazyr.re(bit, "^if(N?o?t?)Timer=(.+)>(.+)s$")) then |
||
1789 | if (lazyr.match2 == nil) or (lazyr.match3 == nil) then |
||
1790 | lazyr.p("syntax eg. -ifTimer=gouge>5s") |
||
1791 | return nil |
||
1792 | end |
||
1793 | local negate = (lazyr.match1 == "Not") |
||
1794 | local val = tonumber(lazyr.match3) |
||
1795 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.Timer(string.lower(lazyr.match2), val), negate)) |
||
1796 | |||
1797 | elseif (lazyr.re(bit, "^if(N?o?t?)Zone=(.+)$")) then |
||
1798 | local negate = (lazyr.match1 == "Not") |
||
1799 | local nameRegex = lazyr.match2 |
||
1800 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.InZone(nameRegex), negate)) |
||
1801 | |||
1802 | elseif (lazyr.re(bit, "^if(N?o?t?)History([<=>])(%d+)=(.+)$")) then |
||
1803 | local negate = (lazyr.match1 == "Not") |
||
1804 | local gtLtEq = lazyr.match2 |
||
1805 | local val = tonumber(lazyr.match3) |
||
1806 | local action = lazyr.match4 |
||
1807 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.History(gtLtEq, val, action), negate)) |
||
1808 | |||
1809 | elseif (lazyr.re(bit, "^if(N?o?t?)TargetInMeleeRange$")) then |
||
1810 | local negate = (lazyr.match1 == "Not") |
||
1811 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.TargetInMeleRange(), negate)) |
||
1812 | |||
1813 | elseif (lazyr.re(bit, "^if(N?o?t?)TargetInBlindRange$")) then |
||
1814 | local negate = (lazyr.match1 == "Not") |
||
1815 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.TargetInBlindRange(), negate)) |
||
1816 | |||
1817 | elseif (lazyr.re(bit, "^if(N?o?t?)InCooldown=(.+)$")) then |
||
1818 | local negate = (lazyr.match1 == "Not") |
||
1819 | local action = lazyr.match2 |
||
1820 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.InCooldown(action), negate)) |
||
1821 | |||
1822 | elseif (lazyr.re(bit, "^if(N?o?t?)Dotted$")) then |
||
1823 | local negate = (lazyr.match1 == "Not") |
||
1824 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.IsDotted(), negate)) |
||
1825 | |||
1826 | elseif (lazyr.re(bit, "^if(N?o?t?)Bleeding$")) then |
||
1827 | local negate = (lazyr.match1 == "Not") |
||
1828 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.IsBleeding(), negate)) |
||
1829 | |||
1830 | elseif (lazyr.re(bit, "^if(N?o?t?)HuntersMark$")) then |
||
1831 | local negate = (lazyr.match1 == "Not") |
||
1832 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.IsMarked(), negate)) |
||
1833 | |||
1834 | elseif (lazyr.re(bit, "^if(N?o?t?)Polymorphed$")) then |
||
1835 | local negate = (lazyr.match1 == "Not") |
||
1836 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.IsPolymorphed(), negate)) |
||
1837 | |||
1838 | elseif (lazyr.re(bit, "^if(N?o?t?)CanDebuff$")) then |
||
1839 | local negate = (lazyr.match1 == "Not") |
||
1840 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.DebuffSpace(), negate)) |
||
1841 | |||
1842 | elseif (lazyr.re(bit, "^if(N?o?t?)TargetImmune=?(.*)$")) then |
||
1843 | local negate = (lazyr.match1 == "Not") |
||
1844 | if (lazyr.match2 ~= "") then |
||
1845 | local subMasks = {} |
||
1846 | for thisAction in string.gfind(lazyr.match2, "[^,]+") do |
||
1847 | table.insert(subMasks, lazyr.masks.IsImmune(thisAction)) |
||
1848 | end |
||
1849 | table.insert(masks, lazyr.masks.maskGroup(subMasks, negate)) |
||
1850 | else |
||
1851 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.IsImmune(lazyr.match2), negate)) |
||
1852 | end |
||
1853 | |||
1854 | elseif (lazyr.re(bit, "^if(N?o?t?)Poisoned=(%a+)$")) then |
||
1855 | if (lazyr.match2 ~="MainHand" and lazyr.match2 ~="OffHand") then |
||
1856 | lazyr.p("Only MainHand and OffHand available, but not"..lazyr.match1) |
||
1857 | return nil |
||
1858 | end |
||
1859 | local negate = (lazyr.match1 == "Not") |
||
1860 | local targetW = lazyr.match2 |
||
1861 | table.insert(masks, lazyr.masks.negWrapper(lazyr.masks.IsPoisoned(targetW), negate)) |
||
1862 | |||
1863 | else |
||
1864 | lazyr.d("ParseArg: parse failure: "..arg) |
||
1865 | return nil |
||
1866 | end |
||
1867 | end |
||
1868 | |||
1869 | return {action, masks} |
||
1870 | end |
||
1871 | |||
1872 | function lazyr.ParseForm(args) |
||
1873 | local startTime = GetTime() |
||
1874 | local actions = {} |
||
1875 | for idx, arg in args do |
||
1876 | local actionInfo = lazyr.ParseArg(arg) |
||
1877 | if (not actionInfo) then |
||
1878 | lazyr.p("Can't parse: "..arg) |
||
1879 | return nil |
||
1880 | elseif (actionInfo == 0) then |
||
1881 | -- was empty (comments?) just ignore this |
||
1882 | else |
||
1883 | table.insert(actions, actionInfo) |
||
1884 | end |
||
1885 | end |
||
1886 | --lazyr.d("ParseForm: time: "..string.format("%f", (GetTime() - startTime)).."s") |
||
1887 | return actions |
||
1888 | end |
||
1889 | |||
1890 | function lazyr.FindForm(formName) |
||
1891 | if (not formName) then |
||
1892 | return nil |
||
1893 | end |
||
1894 | for thisFormName, actions in lrConf.forms do |
||
1895 | if (thisFormName == formName) then |
||
1896 | return actions |
||
1897 | end |
||
1898 | end |
||
1899 | return nil |
||
1900 | end |
||
1901 | |||
1902 | -- speed optimization, skip parsing and regexes every time |
||
1903 | function lazyr.FindParsedForm(formName) |
||
1904 | if (not formName) then |
||
1905 | return nil |
||
1906 | end |
||
1907 | local startTime = GetTime() |
||
1908 | if (lazyr.parsedFormCache[formName] == nil) then |
||
1909 | local actions = lazyr.FindForm(formName) |
||
1910 | if (actions) then |
||
1911 | lazyr.parsedFormCache[formName] = lazyr.ParseForm(actions) |
||
1912 | end |
||
1913 | end |
||
1914 | --lazyr.d("FindParsedForm: time: "..string.format("%f", (GetTime() - startTime)).."s") |
||
1915 | return lazyr.parsedFormCache[formName] |
||
1916 | end |
||
1917 | |||
1918 | function lazyr.ClearParsedForm(formName) |
||
1919 | lazyr.parsedFormCache[formName] = nil |
||
1920 | end |
||
1921 | |||
1922 | function lazyr.Try(action, masks) |
||
1923 | if (masks) then |
||
1924 | for idx, mask in masks do |
||
1925 | if (not mask()) then |
||
1926 | return false |
||
1927 | end |
||
1928 | end |
||
1929 | end |
||
1930 | return action:Use() |
||
1931 | end |
||
1932 | |||
1933 | function lazyr.TryActions(actions) |
||
1934 | local actionThatSucceeded = nil |
||
1935 | |||
1936 | if (not UnitName("target") and lazyr.perPlayerConf.autoTarget) then |
||
1937 | TargetNearestEnemy() |
||
1938 | end |
||
1939 | |||
1940 | if (actions) then |
||
1941 | for idx, actionInfo in actions do |
||
1942 | local action = actionInfo[1] |
||
1943 | local masks = actionInfo[2] |
||
1944 | if (lazyr.Try(action, masks)) then |
||
1945 | actionThatSucceeded = action |
||
1946 | break |
||
1947 | end |
||
1948 | end |
||
1949 | end |
||
1950 | |||
1951 | if (not lazyr.mock |
||
1952 | and lazyr.perPlayerConf.initiateAutoAttack |
||
1953 | and not actionThatSucceeded |
||
1954 | and not lazyr.masks.IsStealthed()) then |
||
1955 | |||
1956 | if (not lazyr.IsAutoAttacking()) then |
||
1957 | lazyr.d("Initiating auto-attack...") |
||
1958 | lazyr.StartAutoAttack() |
||
1959 | end |
||
1960 | end |
||
1961 | |||
1962 | if (actionThatSucceeded) then |
||
1963 | return actionThatSucceeded.name |
||
1964 | else |
||
1965 | return nil |
||
1966 | end |
||
1967 | end |
||
1968 | |||
1969 |