vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 --[[
2 Decursive (v 1.9.7) add-on for World of Warcraft UI
3 Copyright (C) 2005 Archarodim ( http://www.2072productions.com/?to=decursive-continued.txt )
4 This is the continued work of the original Decursive (v1.9.4) by Quu
5 Decursive 1.9.4 is in public domain ( www.quutar.com )
6  
7 License:
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12  
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17  
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 --]]
22 --
23 -- TODO allow people to edit and store the debuffs them selves... to custimze the skip list
24 -- TODO add a debuff priority list... "IE look for these first"
25 -- TODO make the main bar "hideable" instead of just closeable
26 -- TODO figure out a way to show that there is more than one debuff in the live list
27 -- TODO add more macro and keybidnings
28 -- TODO do a code cleanup
29 -------------------------------------------------------------------------------
30  
31 -------------------------------------------------------------------------------
32 -- Debug commands
33 --
34 -- These are commands to change any of the default actions of Decursive.
35 -- Change these to customize how you want things. The purpose of these flags
36 -- is for mod developers to customize the behavour, or for confidant people
37 -- to muck with things
38 -------------------------------------------------------------------------------
39 -- this will spam... really only use it for testing
40 local Dcr_Print_Spell_Found = false; -- XXX
41 -- how many seconds... can be fractional... needs to be more than 0.4... 1.0 is optimal
42 local Dcr_SpellCombatDelay = 1.0;
43 -- print out a fuckload of info
44 Dcr_Print_DEBUG = false;
45 Dcr_Print_DEBUG_bis = false;
46 -------------------------------------------------------------------------------
47  
48  
49  
50 -------------------------------------------------------------------------------
51 -- here is the global variables, these should not be changed. These basically
52 -- are the limits of WoW client.
53 -------------------------------------------------------------------------------
54 DCR_MAXDEBUFFS = 16;
55 DCR_MAXBUFFS = 16;
56 DCR_START_SLOT = 1;
57 DCR_END_SLOT = 120;
58 -------------------------------------------------------------------------------
59 -- and any internal HARD settings for decursive
60 DCR_MAX_LIVE_SLOTS = 15;
61 DCR_TEXT_LIFETIME = 4;
62 -- DCR_MAX_RANGE_CHECK = 4;
63 -------------------------------------------------------------------------------
64  
65 -------------------------------------------------------------------------------
66 -- The stored variables
67 -------------------------------------------------------------------------------
68 Dcr_Saved = {
69 -- this is the items that are stored... I might later do this per account.
70  
71 -- this is the priority list of people to cure
72 PriorityList = { };
73  
74 -- this is the people to skip
75 SkipList = { };
76  
77 -- this is wiether or not to show the "live" list
78 Show_LiveList = true;
79  
80 -- This will turn on and off the sending of messages to the default chat frame
81 Print_ChatFrame = false;
82  
83 -- this will send the messages to a custom frame that is moveable
84 Print_CustomFrame = true;
85  
86 -- this will disable error messages
87 Print_Error = true;
88  
89 -- check for abolish XXX before curing poison or disease
90 Check_For_Abolish = true;
91  
92 -- this is "fix" for the fact that rank 1 of dispell magic does not always remove
93 -- the high level debuffs properly. This carrys over to other things.
94 AlwaysUseBestSpell = true;
95  
96 -- should we do the orders randomly?
97 Random_Order = false;
98  
99 -- should we scan pets
100 Scan_Pets = true;
101  
102 -- should we ignore stealthed units
103 Ingore_Stealthed = false;
104  
105 -- how many to show in the livelist
106 Amount_Of_Afflicted = 5;
107  
108 -- how many seconds to "black list" someone with a failed spell
109 CureBlacklist = 5.0;
110  
111 -- how often to poll for afflictions in seconds
112 ScanTime = 0.2;
113  
114 -- do a range check
115 -- RangeCheck = true;
116  
117 -- Are prio list members protected from blacklisting?
118 DoNot_Blacklist_Prio_List = false;
119  
120 -- Play a sound when there is something to decurse
121 PlaySound = true;
122  
123 -- Hide the buttons
124 HideButtons = false;
125  
126 };
127 -- this is something i use for remote debugging
128 DCR_REMOTE_DEBUG = { };
129 -- This array avoid to test someone we've just blackisted twice.
130 local DCR_ThisCleanBlaclisted = { };
131 -- local DCR_ThisNumberOoRUnits = 0;
132  
133 -------------------------------------------------------------------------------
134  
135 function Dcr_OnLoad (Frame)
136 Frame:RegisterEvent("PLAYER_LOGIN");
137 end
138  
139 local Dcr_CheckingPET = false;
140 local Dcr_DelayedReconf = false;
141  
142 function Dcr_OnEvent (event)
143 local Frame = this;
144  
145 -- Dcr_debug_bis ("Event was catch: " .. event);
146  
147  
148 if (event == "UNIT_PET" and arg1 == "player" and not Dcr_CheckingPET) then
149 Dcr_CheckingPET = true;
150 Dcr_debug_bis ("PLAYER pet detected! Poll in 2 seconds");
151 return;
152 elseif (event == "UNIT_PET" and (arg1 ~= "player" or Dcr_CheckingPET)) then
153 return;
154 elseif (event == "PLAYER_ENTER_COMBAT") then
155 Dcr_EnterCombat();
156 return;
157 elseif (event == "PLAYER_LEAVE_COMBAT") then
158 Dcr_LeaveCombat();
159 return;
160 elseif (event == "UI_ERROR_MESSAGE") then
161 if (arg1 == SPELL_FAILED_LINE_OF_SIGHT) then
162 Dcr_errln("Out of sight!");
163 Dcr_SpellCastFailed();
164 end
165 return;
166 --[[ elseif (
167 (event == "SPELLCAST_FAILED") or
168 (event == "SPELLCAST_INTERRUPTED")
169 ) then
170 if (arg1) then -- XXX
171 Dcr_errln("test arg on cast failed: " .. arg1);
172  
173 end
174 Dcr_SpellCastFailed();
175 return;
176 --]]
177 elseif (event == "SPELLCAST_STOP") then
178 Dcr_SpellWasCast();
179 return;
180 elseif (not Dcr_DelayedReconf and event == "SPELLS_CHANGED" and arg1==nil) then
181 Dcr_DelayedReconf = true;
182 return;
183 elseif (event == "LEARNED_SPELL_IN_TAB") then
184 Dcr_Configure();
185 return;
186  
187 end
188  
189 if (event == "PLAYER_LOGIN") then
190 Frame:RegisterEvent("PLAYER_ENTERING_WORLD");
191 Frame:RegisterEvent("PLAYER_LEAVING_WORLD");
192 Dcr_Init();
193 return;
194 end
195  
196 if (
197 (event == "PLAYER_ENTERING_WORLD")
198 ) then
199 Frame:RegisterEvent("PLAYER_ENTER_COMBAT");
200 Frame:RegisterEvent("PLAYER_LEAVE_COMBAT");
201 -- Frame:RegisterEvent("SPELLCAST_FAILED");
202 -- Frame:RegisterEvent("SPELLCAST_INTERRUPTED");
203 Frame:RegisterEvent("SPELLCAST_STOP");
204 Frame:RegisterEvent("UNIT_PET");
205 Frame:RegisterEvent("SPELLS_CHANGED");
206 Frame:RegisterEvent("LEARNED_SPELL_IN_TAB");
207 Frame:RegisterEvent("UI_ERROR_MESSAGE");
208  
209 elseif (event == "PLAYER_LEAVING_WORLD") then
210  
211 Frame:UnregisterEvent("PLAYER_ENTER_COMBAT");
212 Frame:UnregisterEvent("PLAYER_LEAVE_COMBAT");
213 -- Frame:UnregisterEvent("SPELLCAST_FAILED");
214 -- Frame:UnregisterEvent("SPELLCAST_INTERRUPTED");
215 Frame:UnregisterEvent("SPELLCAST_STOP");
216 Frame:UnregisterEvent("UNIT_PET");
217 Frame:UnregisterEvent("SPELLS_CHANGED");
218 Frame:UnregisterEvent("LEARNED_SPELL_IN_TAB");
219 Frame:UnregisterEvent("UI_ERROR_MESSAGE");
220 end
221  
222 end
223  
224 -------------------------------------------------------------------------------
225 -- and the printing functions
226 -------------------------------------------------------------------------------
227 function Dcr_debug( Message)
228 if (Dcr_Print_DEBUG) then
229 table.insert(DCR_REMOTE_DEBUG, Message);
230 DEFAULT_CHAT_FRAME:AddMessage(Message, 0.1, 0.1, 1);
231 end
232 end
233  
234  
235 function Dcr_debug_bis( Message)
236 if (Dcr_Print_DEBUG_bis) then
237 table.insert(DCR_REMOTE_DEBUG, Message);
238 DEFAULT_CHAT_FRAME:AddMessage(Message, 0.1, 0.1, 1);
239 end
240 end
241  
242 function Dcr_println( Message)
243  
244 if (Dcr_Saved.Print_ChatFrame) then
245 DEFAULT_CHAT_FRAME:AddMessage(Message, 1, 1, 1);
246 end
247 if (Dcr_Saved.Print_CustomFrame) then
248 DecursiveTextFrame:AddMessage(Message, 1, 1, 1, 0.9, DCR_TEXT_LIFETIME);
249 end
250 end
251  
252 function Dcr_errln( Message)
253 if (Dcr_Saved.Print_Error) then
254 if (Dcr_Saved.Print_ChatFrame) then
255 DEFAULT_CHAT_FRAME:AddMessage(Message, 1, 0.1, 0.1);
256 end
257 if (Dcr_Saved.Print_CustomFrame) then
258 DecursiveTextFrame:AddMessage(Message, 1, 0.1, 0.1, 0.9, DCR_TEXT_LIFETIME);
259 end
260 end
261 end
262 -------------------------------------------------------------------------------
263  
264 -------------------------------------------------------------------------------
265 -- local variables
266 -------------------------------------------------------------------------------
267 local Dcr_CuringAction_Icons = { };
268  
269 -- the new spellbook (made it simpler due to localization problems)
270 local DCR_HAS_SPELLS = false;
271 local DCR_SPELL_MAGIC_1 = {0,"", ""};
272 local DCR_SPELL_MAGIC_2 = {0,"", ""};
273 local DCR_CAN_CURE_MAGIC = false;
274 local DCR_SPELL_ENEMY_MAGIC_1 = {0,"", ""};
275 local DCR_SPELL_ENEMY_MAGIC_2 ={0,"", ""};
276 local DCR_CAN_CURE_ENEMY_MAGIC = false;
277 local DCR_SPELL_DISEASE_1 = {0,"", ""};
278 local DCR_SPELL_DISEASE_2 = {0,"", ""};
279 local DCR_CAN_CURE_DISEASE = false;
280 local DCR_SPELL_POISON_1 = {0,"", ""};
281 local DCR_SPELL_POISON_2 = {0,"", ""};
282 local DCR_CAN_CURE_POISON = false;
283 local DCR_SPELL_CURSE = {0,"", ""};
284 local DCR_CAN_CURE_CURSE = false;
285 local DCR_SPELL_COOLDOWN_CHECK = {0,"", ""};
286  
287 -- for the blacklist
288 local Dcr_Casting_Spell_On = nil;
289 local Dcr_Blacklist_Array = { };
290  
291 -------------------------------------------------------------------------------
292 -- init functions and configuration functions
293 -------------------------------------------------------------------------------
294 function Dcr_Init()
295 Dcr_println(DCR_VERSION_STRING);
296  
297 Dcr_debug_bis( "Decursive Initialization started !");
298  
299 Dcr_debug( "Registering the slash commands");
300 SLASH_DECURSIVE1 = DCR_MACRO_COMMAND;
301 SlashCmdList["DECURSIVE"] = function(msg)
302 Dcr_Clean();
303 end
304  
305 SLASH_DECURSIVEPRADD1 = DCR_MACRO_PRADD;
306 SlashCmdList["DECURSIVEPRADD"] = function(msg)
307 Dcr_AddTargetToPriorityList();
308 end
309 SLASH_DECURSIVEPRCLEAR1 = DCR_MACRO_PRCLEAR;
310 SlashCmdList["DECURSIVEPRCLEAR"] = function(msg)
311 Dcr_ClearPriorityList();
312 end
313 SLASH_DECURSIVEPRLIST1 = DCR_MACRO_PRLIST;
314 SlashCmdList["DECURSIVEPRLIST"] = function(msg)
315 Dcr_PrintPriorityList();
316 end
317 SLASH_DECURSIVEPRSHOW1 = DCR_MACRO_PRSHOW;
318 SlashCmdList["DECURSIVEPRSHOW"] = function(msg)
319 Dcr_ShowHidePriorityListUI();
320 end
321  
322 SLASH_DECURSIVESKADD1 = DCR_MACRO_SKADD;
323 SlashCmdList["DECURSIVESKADD"] = function(msg)
324 Dcr_AddTargetToSkipList();
325 end
326 SLASH_DECURSIVESKCLEAR1 = DCR_MACRO_SKCLEAR;
327 SlashCmdList["DECURSIVESKCLEAR"] = function(msg)
328 Dcr_ClearSkipList();
329 end
330 SLASH_DECURSIVESKLIST1 = DCR_MACRO_SKLIST;
331 SlashCmdList["DECURSIVESKLIST"] = function(msg)
332 Dcr_PrintSkipList();
333 end
334 SLASH_DECURSIVESKSHOW1 = DCR_MACRO_SKSHOW;
335 SlashCmdList["DECURSIVESKSHOW"] = function(msg)
336 Dcr_ShowHideSkipListUI();
337 end
338  
339 SLASH_DECURSIVESHOW1 = DCR_MACRO_SHOW;
340 SlashCmdList["DECURSIVESHOW"] = function(msg)
341 Dcr_ShowHideAfflictedListUI();
342 end
343  
344 SLASH_DECURSIVERESET1 = DCR_MACRO_RESET;
345 SlashCmdList["DECURSIVERESET"] = function(msg)
346 Dcr_ResetWindow();
347 end
348  
349 if (Dcr_Saved.Show_LiveList) then
350 DecursiveAfflictedListFrame:Show();
351 else
352 DecursiveAfflictedListFrame:Hide();
353 end
354  
355 if (Dcr_Saved.HideButtons == nil) then
356 Dcr_Saved.HideButtons = false;
357 end
358  
359 Dcr_ShowHideButtons(true);
360  
361 -- check the spellbook once
362 Dcr_Configure();
363 DEFAULT_CHAT_FRAME:AddMessage(DCR_IS_HERE_MSG, 0.3, 0.5, 1);
364 DEFAULT_CHAT_FRAME:AddMessage(DCR_SHOW_MSG, 0.3, 0.5, 1);
365 end
366  
367 -- this resets the location of the windows
368 function Dcr_ResetWindow()
369 DecursiveAfflictedListFrame:ClearAllPoints();
370 DecursiveAfflictedListFrame:SetPoint("CENTER", "UIParent");
371  
372 DecursivePriorityListFrame:ClearAllPoints();
373 DecursivePriorityListFrame:SetPoint("CENTER", "UIParent");
374  
375 DecursiveSkipListFrame:ClearAllPoints();
376 DecursiveSkipListFrame:SetPoint("CENTER", "UIParent");
377  
378 DecursivePopulateListFrame:ClearAllPoints();
379 DecursivePopulateListFrame:SetPoint("CENTER", "UIParent");
380  
381 DcrOptionsFrame:ClearAllPoints();
382 DcrOptionsFrame:SetPoint("CENTER", "UIParent");
383 end
384  
385 -- this gets an array of units for us to check
386 function Dcr_GetUnitArray()
387 -- TODO: OPTIMIZE this function... a lot of things are done several times.
388 local Dcr_Unit_Array = { };
389 -- create the array of curable units
390  
391 -- first... the priority list... names that go first!
392 local pname;
393 for _, pname in Dcr_Saved.PriorityList do
394 local unit = Dcr_NameToUnit( pname);
395 if (unit) then
396 table.insert(Dcr_Unit_Array,unit);
397 end
398 end
399  
400 -- then everything else
401 local i;
402 local raidnum = GetNumRaidMembers();
403 local temp_table = { };
404  
405 -- add your self (you are never skipped) except if you are already in the prio list...
406 if (not Dcr_IsInSkipOrPriorList(UnitName("player"))) then
407 table.insert(Dcr_Unit_Array, "player");
408 end
409  
410 -- add the party members... if they exist
411 for i = 1, 4 do
412 if (UnitExists("party"..i)) then
413 pname = UnitName("party"..i);
414 -- check the name to see if we skip
415 if (not Dcr_IsInSkipOrPriorList(pname)) then
416 -- we don't skip them
417 if (Dcr_Saved.Random_Order) then
418 table.insert(temp_table,"party"..i);
419 else
420 table.insert(Dcr_Unit_Array,"party"..i);
421 end
422 end
423 end
424 end
425 if (Dcr_Saved.Random_Order) then
426 local temp_max = table.getn(temp_table);
427 for i = 1, temp_max do
428 table.insert(Dcr_Unit_Array,table.remove(temp_table,random(1, table.getn(temp_table))));
429 end
430 end
431  
432 -- add the raid IDs that are valid...
433 -- add it from the sub group after yours... and then loop
434 -- around to the group right before yours
435 if ( raidnum > 0 ) then
436 local currentGroup = 0;
437 local name = UnitName( "player");
438  
439 for i = 1, raidnum do
440 local rName, _, rGroup = GetRaidRosterInfo(i);
441 if (rName == name) then
442 currentGroup = rGroup;
443 break;
444 end
445 end
446  
447 -- first the groups that are after yours
448 for i = 1, raidnum do
449 local pname, _, rGroup = GetRaidRosterInfo(i);
450 -- get the group and name
451 if (rGroup > currentGroup) then
452 -- group is after ours
453 if (not Dcr_IsInSkipOrPriorList(pname)) then
454 -- and we are not skipping this name
455 if (Dcr_Saved.Random_Order) then
456 table.insert(temp_table,"raid"..i);
457 else
458 table.insert(Dcr_Unit_Array,"raid"..i);
459 end
460 end
461 end
462 end
463 -- the the ones that are before yours
464 for i = 1, raidnum do
465 local pname, _, rGroup = GetRaidRosterInfo(i);
466 -- get the group and name
467 if (rGroup < currentGroup) then
468 -- its before our group
469 if (not Dcr_IsInSkipOrPriorList(pname)) then
470 -- and we are not skipping this name
471 if (Dcr_Saved.Random_Order) then
472 table.insert(temp_table,"raid"..i);
473 else
474 table.insert(Dcr_Unit_Array,"raid"..i);
475 end
476 end
477 end
478 end
479 -- don't bother with your own group... since its also party 1-4
480  
481 if (Dcr_Saved.Random_Order) then
482 local temp_max = table.getn(temp_table);
483 for i = 1, temp_max do
484 table.insert(Dcr_Unit_Array,table.remove(temp_table,random(1, table.getn(temp_table))));
485 end
486 end
487 end
488  
489 if (not Dcr_Saved.Scan_Pets) then
490 -- we are not doing pets... leave here
491 return Dcr_Unit_Array;
492 end
493 -- now the pets
494  
495 -- your own pet
496 if (UnitExists("pet")) then
497 table.insert(Dcr_Unit_Array,"pet");
498 end
499  
500 -- the parties pets if they have them
501 for i = 1, 4 do
502 if (UnitExists("partypet"..i)) then
503 pname = UnitName("partypet"..i);
504 -- get the pet name
505 if (not Dcr_IsInSkipOrPriorList(pname)) then
506 -- to see if we skip it
507 if (Dcr_Saved.Random_Order) then
508 table.insert(temp_table,"partypet"..i);
509 else
510 table.insert(Dcr_Unit_Array,"partypet"..i);
511 end
512 end
513 end
514 end
515 if (Dcr_Saved.Random_Order) then
516 local temp_max = table.getn(temp_table);
517 for i = 1, temp_max do
518 table.insert(Dcr_Unit_Array,table.remove(temp_table,random(1, table.getn(temp_table))));
519 end
520 end
521  
522 -- and then the raid pets if they are out
523 -- don't worry about the fancier logic with the pets
524 if ( raidnum > 0 ) then
525 for i = 1, raidnum do
526 if (UnitExists("raidpet"..i)) then
527 pname = UnitName("raidpet"..i);
528 -- get pet name
529 if (not Dcr_IsInSkipOrPriorList(pname)) then
530 -- to see if we skip it
531 if (Dcr_Saved.Random_Order) then
532 table.insert(temp_table,"raidpet"..i);
533 else
534 table.insert(Dcr_Unit_Array,"raidpet"..i);
535 end
536 end
537 end
538 end
539 if (Dcr_Saved.Random_Order) then
540 local temp_max = table.getn(temp_table);
541 for i = 1, temp_max do
542 table.insert(Dcr_Unit_Array,table.remove(temp_table,random(1, table.getn(temp_table))));
543 end
544 end
545 end
546  
547 return Dcr_Unit_Array;
548 end
549  
550 -- Raid/Party Name Check Function
551 -- this returns the UnitID that the Name points to
552 -- this does not check "target" or "mouseover"
553 function Dcr_NameToUnit( Name)
554 if (not Name) then
555 return false;
556 elseif (Name == UnitName("player")) then
557 return "player";
558 elseif (Name == UnitName("pet")) then
559 return "pet";
560 elseif (Name == UnitName("party1")) then
561 return "party1";
562 elseif (Name == UnitName("party2")) then
563 return "party2";
564 elseif (Name == UnitName("party3")) then
565 return "party3";
566 elseif (Name == UnitName("party4")) then
567 return "party4";
568 elseif (Name == UnitName("partypet1")) then
569 return "partypet1";
570 elseif (Name == UnitName("partypet2")) then
571 return "partypet2";
572 elseif (Name == UnitName("partypet3")) then
573 return "partypet3";
574 elseif (Name == UnitName("partypet4")) then
575 return "partypet4";
576 else
577 local numRaidMembers = GetNumRaidMembers();
578 if (numRaidMembers > 0) then
579 -- we are in a raid
580 local i;
581 for i=1, numRaidMembers do
582 local RaidName = GetRaidRosterInfo(i);
583 if ( Name == RaidName) then
584 return "raid"..i;
585 end
586 if ( Name == UnitName("raidpet"..i)) then
587 return "raidpet"..i;
588 end
589 end
590 end
591 end
592 return false;
593 end
594  
595 function Dcr_CheckSpellName (id, booktype, spellname)
596  
597 if id ~= 0 then
598 Dcr_debug_bis("testing spell for name changes: id="..id);
599 local found_spellname, spellrank = GetSpellName(id, booktype);
600  
601 if spellname ~= found_spellname then
602 return false;
603 end
604 end
605  
606 return true;
607 end
608  
609 function Dcr_ReConfigure()
610  
611 if not DCR_HAS_SPELLS then
612 return;
613 end
614  
615 Dcr_debug_bis("Dcr_ReConfigure was called!");
616  
617 local DoNotReconfigure = true;
618  
619 DoNotReconfigure = Dcr_CheckSpellName(DCR_SPELL_MAGIC_1[1], DCR_SPELL_MAGIC_1[2], DCR_SPELL_MAGIC_1[3]);
620 DoNotReconfigure = Dcr_CheckSpellName(DCR_SPELL_MAGIC_2[1], DCR_SPELL_MAGIC_2[2], DCR_SPELL_MAGIC_2[3]);
621  
622 DoNotReconfigure = Dcr_CheckSpellName(DCR_SPELL_ENEMY_MAGIC_1[1], DCR_SPELL_ENEMY_MAGIC_1[2], DCR_SPELL_ENEMY_MAGIC_1[3]);
623 DoNotReconfigure = Dcr_CheckSpellName(DCR_SPELL_ENEMY_MAGIC_2[1], DCR_SPELL_ENEMY_MAGIC_2[2], DCR_SPELL_ENEMY_MAGIC_2[3]);
624  
625 DoNotReconfigure = Dcr_CheckSpellName(DCR_SPELL_DISEASE_1[1], DCR_SPELL_DISEASE_1[2], DCR_SPELL_DISEASE_1[3]);
626 DoNotReconfigure = Dcr_CheckSpellName(DCR_SPELL_DISEASE_2[1], DCR_SPELL_DISEASE_2[2], DCR_SPELL_DISEASE_2[3]);
627  
628 DoNotReconfigure = Dcr_CheckSpellName(DCR_SPELL_POISON_1[1], DCR_SPELL_POISON_1[2], DCR_SPELL_POISON_1[3]);
629 DoNotReconfigure = Dcr_CheckSpellName(DCR_SPELL_POISON_2[1], DCR_SPELL_POISON_2[2], DCR_SPELL_POISON_2[3]);
630  
631 DoNotReconfigure = Dcr_CheckSpellName(DCR_SPELL_CURSE[1], DCR_SPELL_CURSE[2], DCR_SPELL_CURSE[3]);
632  
633 if DoNotReconfigure == false then
634 Dcr_debug_bis("Dcr_ReConfigure RECONFIGURATION!");
635 Dcr_Configure();
636 return;
637 end
638 Dcr_debug_bis("Dcr_ReConfigure No reconfiguration required!");
639  
640 end
641  
642 Dcr_PlayerClass = "";
643 function Dcr_Configure()
644  
645 -- first empty out the old "spellbook"
646 DCR_HAS_SPELLS = false;
647 DCR_SPELL_MAGIC_1 = {0,"", ""};
648 DCR_SPELL_MAGIC_2 = {0,"", ""};
649 DCR_CAN_CURE_MAGIC = false;
650 DCR_SPELL_ENEMY_MAGIC_1 = {0,"", ""};
651 DCR_SPELL_ENEMY_MAGIC_2 = {0,"", ""};
652 DCR_CAN_CURE_ENEMY_MAGIC = false;
653 DCR_SPELL_DISEASE_1 = {0,"", ""};
654 DCR_SPELL_DISEASE_2 = {0,"", ""};
655 DCR_CAN_CURE_DISEASE = false;
656 DCR_SPELL_POISON_1 = {0,"", ""};
657 DCR_SPELL_POISON_2 = {0,"", ""};
658 DCR_CAN_CURE_POISON = false;
659 DCR_SPELL_CURSE = {0,"", ""};
660 DCR_CAN_CURE_CURSE = false;
661  
662  
663 Dcr_debug_bis("Configuring Decursive...");
664 -- parse through the entire library...
665 -- look for known cleaning spells...
666 -- this will be called everytime the spellbook changes
667  
668 -- this is just used to make things simpler in the checking
669 local Dcr_Name_Array = {
670 [DCR_SPELL_CURE_DISEASE] = true,
671 [DCR_SPELL_ABOLISH_DISEASE] = true,
672 [DCR_SPELL_PURIFY] = true,
673 [DCR_SPELL_CLEANSE] = true,
674 [DCR_SPELL_DISPELL_MAGIC] = true,
675 [DCR_SPELL_CURE_POISON] = true,
676 [DCR_SPELL_ABOLISH_POISON] = true,
677 [DCR_SPELL_REMOVE_LESSER_CURSE] = true,
678 [DCR_SPELL_REMOVE_CURSE] = true,
679 [DCR_SPELL_PURGE] = true,
680 [DCR_PET_FEL_CAST] = true,
681 [DCR_PET_DOOM_CAST] = true,
682 }
683  
684 local i = 1;
685  
686 local BookType = BOOKTYPE_SPELL;
687 local break_flag = false
688 while not break_flag do
689  
690 while (true) do
691 local spellName, spellRank = GetSpellName(i, BookType);
692 if (not spellName) then
693 if (BookType == BOOKTYPE_PET) then
694 break_flag = true;
695 break;
696 end
697 BookType = BOOKTYPE_PET;
698 i = 1;
699 break;
700  
701 end
702  
703 Dcr_debug( "Checking spell - "..spellName);
704  
705 if (Dcr_Name_Array[spellName]) then
706 Dcr_debug( "Its one we care about");
707 DCR_HAS_SPELLS = true;
708  
709 -- any of them will work for the cooldown... we store the last
710 DCR_SPELL_COOLDOWN_CHECK[1] = i; DCR_SPELL_COOLDOWN_CHECK[2] = BookType;
711  
712 -- put it in the range icon array
713 local icon = GetSpellTexture(i, BookType)
714 Dcr_CuringAction_Icons[icon] = spellName;
715  
716 -- print out the spell
717 Dcr_debug( string.gsub(DCR_SPELL_FOUND, "$s", spellName));
718 if (Dcr_Print_Spell_Found) then
719 Dcr_println( string.gsub(DCR_SPELL_FOUND, "$s", spellName));
720 end
721  
722 -- big ass if statement... due to the way that the different localizations work
723 -- I used to do this more elegantly... but the german WoW broke it
724  
725 if ((spellName == DCR_SPELL_CURE_DISEASE) or (spellName == DCR_SPELL_ABOLISH_DISEASE) or
726 (spellName == DCR_SPELL_PURIFY) or (spellName == DCR_SPELL_CLEANSE)) then
727 DCR_CAN_CURE_DISEASE = true;
728 if ((spellName == DCR_SPELL_CURE_DISEASE) or (spellName == DCR_SPELL_PURIFY)) then
729 Dcr_debug( "Adding to disease 1");
730 DCR_SPELL_DISEASE_1[1] = i; DCR_SPELL_DISEASE_1[2] = BookType; DCR_SPELL_DISEASE_1[3] = spellName;
731 else
732 Dcr_debug( "Adding to disease 2");
733 DCR_SPELL_DISEASE_2[1] = i; DCR_SPELL_DISEASE_2[2] = BookType; DCR_SPELL_DISEASE_2[3] = spellName;
734 end
735 end
736  
737 if ((spellName == DCR_SPELL_CURE_POISON) or (spellName == DCR_SPELL_ABOLISH_POISON) or
738 (spellName == DCR_SPELL_PURIFY) or (spellName == DCR_SPELL_CLEANSE)) then
739 DCR_CAN_CURE_POISON = true;
740 if ((spellName == DCR_SPELL_CURE_POISON) or (spellName == DCR_SPELL_PURIFY)) then
741 Dcr_debug( "Adding to poison 1");
742 DCR_SPELL_POISON_1[1] = i; DCR_SPELL_POISON_1[2] = BookType; DCR_SPELL_POISON_1[3] = spellName;
743 else
744 Dcr_debug( "Adding to poison 2");
745 DCR_SPELL_POISON_2[1] = i; DCR_SPELL_POISON_2[2] = BookType; DCR_SPELL_POISON_2[3] = spellName;
746 end
747 end
748  
749 if ((spellName == DCR_SPELL_REMOVE_CURSE) or (spellName == DCR_SPELL_REMOVE_LESSER_CURSE)) then
750 Dcr_debug( "Adding to curse");
751 DCR_CAN_CURE_CURSE = true;
752 DCR_SPELL_CURSE[1] = i; DCR_SPELL_CURSE[2] = BookType; DCR_SPELL_CURSE[3] = spellName;
753 end
754  
755 if ((spellName == DCR_SPELL_DISPELL_MAGIC) or (spellName == DCR_SPELL_CLEANSE) or (spellName == DCR_PET_FEL_CAST) or (spellName == DCR_PET_DOOM_CAST)) then
756 DCR_CAN_CURE_MAGIC = true;
757 if (spellName == DCR_SPELL_CLEANSE) then
758 Dcr_debug( "Adding to magic 1");
759 DCR_SPELL_MAGIC_1[1] = i; DCR_SPELL_MAGIC_1[2] = BookType; DCR_SPELL_MAGIC_1[3] = spellName;
760 else
761 if (spellRank == DCR_SPELL_RANK_1) then
762 Dcr_debug( "Adding to magic 1");
763 Dcr_debug_bis( "Adding to magic 1");
764 DCR_SPELL_MAGIC_1[1] = i; DCR_SPELL_MAGIC_1[2] = BookType; DCR_SPELL_MAGIC_1[3] = spellName;
765 else
766 Dcr_debug( "adding to magic 2");
767 Dcr_debug_bis( "Adding to magic 2");
768 DCR_SPELL_MAGIC_2[1] = i; DCR_SPELL_MAGIC_2[2] = BookType; DCR_SPELL_MAGIC_2[3] = spellName;
769 end
770 end
771 end
772  
773 if ((spellName == DCR_SPELL_DISPELL_MAGIC) or (spellName == DCR_SPELL_PURGE) or (spellName == DCR_PET_FEL_CAST) or (spellName == DCR_PET_DOOM_CAST)) then
774 DCR_CAN_CURE_ENEMY_MAGIC = true;
775 if (spellRank == DCR_SPELL_RANK_1) then
776 Dcr_debug( "Adding to enemy magic 1");
777 Dcr_debug_bis( "Adding to enemy magic 1");
778 DCR_SPELL_ENEMY_MAGIC_1[1] = i; DCR_SPELL_ENEMY_MAGIC_1[2] = BookType; DCR_SPELL_ENEMY_MAGIC_1[3] = spellName;
779 else
780 Dcr_debug( "Adding to enemy magic 2");
781 Dcr_debug_bis( "Adding to enemy magic 2");
782 DCR_SPELL_ENEMY_MAGIC_2[1] = i; DCR_SPELL_ENEMY_MAGIC_2[2] = BookType; DCR_SPELL_ENEMY_MAGIC_2[3] = spellName;
783 end
784 end
785  
786 end
787  
788 i = i + 1
789 end
790 end
791  
792 local _, PlayerClass = UnitClass("player");
793  
794 Dcr_PlayerClass = PlayerClass;
795 --[[
796 if (DCR_HAS_SPELLS and Dcr_PlayerClass ~= DCR_CLASS_WARLOCK and Dcr_FindCureingActionSlot(Dcr_CuringAction_Icons)==0) then
797  
798 message(DCR_STR_NEED_CURE_ACTION_IN_BARS);
799 end
800 --]]
801  
802 end
803 -------------------------------------------------------------------------------
804  
805  
806 -------------------------------------------------------------------------------
807 -- the priority and skip list function... stuff to manage the lists
808 -------------------------------------------------------------------------------
809 function Dcr_ShowHideAfflictedListUI()
810 if (DecursiveAfflictedListFrame:IsVisible()) then
811 Dcr_Saved.Show_LiveList = false;
812 DecursiveAfflictedListFrame:Hide();
813 else
814 Dcr_Saved.Show_LiveList = true;
815 DecursiveAfflictedListFrame:Show();
816 end
817 end
818  
819 -- priority list stuff
820 function Dcr_ShowHidePriorityListUI()
821 if (DecursivePriorityListFrame:IsVisible()) then
822 DecursivePriorityListFrame:Hide();
823 else
824 DecursivePriorityListFrame:Show();
825 end
826 end
827  
828 function Dcr_ThisSetText(text)
829 getglobal(this:GetName().."Text"):SetText(text);
830 end
831  
832 function Dcr_AddTargetToPriorityList()
833 Dcr_debug( "Adding the target to the priority list");
834 DcrAddUnitToPriorityList("target");
835 end
836  
837 function DcrAddUnitToPriorityList( unit)
838 if (UnitExists(unit)) then
839 if (UnitIsPlayer(unit)) then
840 local name = UnitName( unit);
841 for _, pname in Dcr_Saved.PriorityList do
842 if (name == pname) then
843 return;
844 end
845 end
846 table.insert(Dcr_Saved.PriorityList,name);
847 end
848 DecursivePriorityListFrame.UpdateYourself = true;
849 end
850 end
851  
852 function Dcr_RemoveIDFromPriorityList(id)
853 table.remove( Dcr_Saved.PriorityList,id);
854 DecursivePriorityListFrame.UpdateYourself = true;
855 end
856  
857 function Dcr_ClearPriorityList()
858 local i;
859 local max = table.getn(Dcr_Saved.PriorityList);
860 for i = 1, max do
861 table.remove( Dcr_Saved.PriorityList);
862 end
863 DecursivePriorityListFrame.UpdateYourself = true;
864 end
865  
866 function Dcr_PrintPriorityList()
867 for id, name in Dcr_Saved.PriorityList do
868 Dcr_println( id.." - "..name);
869 end
870 end
871  
872 -- skip list stuff
873 function Dcr_ShowHideSkipListUI()
874 if (DecursiveSkipListFrame:IsVisible()) then
875 DecursiveSkipListFrame:Hide();
876 else
877 DecursiveSkipListFrame:Show();
878 end
879 end
880  
881 function Dcr_ShowHideOptionsUI()
882 if (DcrOptionsFrame:IsVisible()) then
883 DcrOptionsFrame:Hide();
884 else
885 DcrOptionsFrame:Show();
886 end
887 end
888  
889 function Dcr_ShowHideTextAnchor()
890 if (DecursiveAnchor:IsVisible()) then
891 DecursiveAnchor:Hide();
892 else
893 DecursiveAnchor:Show();
894 end
895 end
896  
897 function Dcr_ShowHideButtons(UseCurrentValue)
898  
899 local DecrFrame = "DecursiveAfflictedListFrame";
900 local buttons = {
901 DecrFrame .. "Priority",
902 DecrFrame .. "Skip",
903 DecrFrame .. "Options",
904 DecrFrame .. "Hide",
905 }
906  
907 DCRframeObject = getglobal(DecrFrame);
908  
909 if (not UseCurrentValue) then
910 Dcr_Saved.HideButtons = (not Dcr_Saved.HideButtons);
911 end
912  
913 for _, ButtonName in buttons do
914 Button = getglobal(ButtonName);
915  
916 if (Dcr_Saved.HideButtons) then
917 Button:Hide();
918 DCRframeObject.isLocked = 1;
919 else
920 Button:Show();
921 DCRframeObject.isLocked = 0;
922 end
923  
924 end
925  
926  
927  
928 end
929  
930 function Dcr_AddTargetToSkipList()
931 Dcr_debug( "Adding the target to the Skip list");
932 DcrAddUnitToSkipList("target");
933 end
934  
935 function DcrAddUnitToSkipList( unit)
936 if (UnitExists(unit)) then
937 if (UnitIsPlayer(unit)) then
938 local name = UnitName( unit);
939 for _, pname in Dcr_Saved.SkipList do
940 if (name == pname) then
941 return;
942 end
943 end
944 table.insert(Dcr_Saved.SkipList,name);
945 DecursiveSkipListFrame.UpdateYourself = true;
946 end
947 end
948 end
949  
950 function Dcr_RemoveIDFromSkipList(id)
951 table.remove( Dcr_Saved.SkipList,id);
952 DecursiveSkipListFrame.UpdateYourself = true;
953 end
954  
955 function Dcr_ClearSkipList()
956 local i;
957 local max = table.getn(Dcr_Saved.SkipList);
958 for i = 1, max do
959 table.remove( Dcr_Saved.SkipList);
960 end
961 DecursiveSkipListFrame.UpdateYourself = true;
962 end
963  
964 function Dcr_PrintSkipList()
965 for id, name in Dcr_Saved.SkipList do
966 Dcr_println( id.." - "..name);
967 end
968 end
969  
970 function Dcr_IsInPriorList (name)
971 for _, PriorName in Dcr_Saved.PriorityList do
972 if (PriorName == name) then
973 return true;
974 end
975 end
976 return false;
977 end
978  
979 function Dcr_IsInSkipList (name)
980 for _, SkipName in Dcr_Saved.SkipList do
981 if (SkipName == name) then
982 return true;
983 end
984 end
985 return false
986 end
987  
988 function Dcr_IsInSkipOrPriorList( name )
989 if (Dcr_IsInSkipList(name)) then
990 return true;
991 end
992  
993 if (Dcr_IsInPriorList(name)) then
994 return true;
995 end
996 return false;
997  
998 --[[
999 -- Dcr_debug_bis("Dcr_IsInSkipOrPriorList called with: " .. name);
1000 if (name) then
1001 for _, SkipName in Dcr_Saved.SkipList do
1002 if (SkipName == name) then
1003 return true;
1004 end
1005 end
1006 for _, PriorName in Dcr_Saved.PriorityList do
1007 if (PriorName == name) then
1008 return true;
1009 end
1010 end
1011 end
1012 return false;
1013 --]]
1014 end
1015 -------------------------------------------------------------------------------
1016  
1017 -------------------------------------------------------------------------------
1018 -- the combat saver functions and events. These keep us in combat mode
1019 -------------------------------------------------------------------------------
1020 local Dcr_CombatMode = false;
1021 function Dcr_EnterCombat()
1022 Dcr_debug("Entering combat");
1023 Dcr_CombatMode = true;
1024 end
1025  
1026 function Dcr_LeaveCombat()
1027 Dcr_debug("Leaving combat");
1028 Dcr_CombatMode = false;
1029 end
1030  
1031  
1032 local Dcr_CheckPet_Delay = 2;
1033 local Dcr_DelayedReconf_delay = 1;
1034  
1035 local Dcr_DelayedReconf_timer = 0;
1036 local Dcr_CheckPet_Timer = 0;
1037 local Dcr_Delay_Timer = 0;
1038  
1039 local last_DemonType = nil;
1040 local curr_DemonType = nil;
1041  
1042 -- This function update Decursive states :
1043 -- - Reconf if needed
1044 -- - check for a pet
1045 -- - clear the black list
1046 function Dcr_OnUpdate(arg1)
1047  
1048  
1049 --checkinfgfor reconf need
1050 if Dcr_DelayedReconf then
1051 Dcr_DelayedReconf_timer = Dcr_DelayedReconf_timer + arg1;
1052 if (Dcr_DelayedReconf_timer >= Dcr_DelayedReconf_delay) then
1053 Dcr_DelayedReconf_timer = 0;
1054  
1055 Dcr_ReConfigure();
1056 Dcr_DelayedReconf = false;
1057 return;
1058 end
1059 end
1060  
1061 -- checking for pet
1062 if (Dcr_CheckingPET) then
1063 Dcr_CheckPet_Timer = Dcr_CheckPet_Timer + arg1;
1064  
1065 if (Dcr_CheckPet_Timer >= Dcr_CheckPet_Delay) then
1066 Dcr_CheckPet_Timer = 0;
1067  
1068 curr_DemonType = UnitCreatureFamily("pet");
1069  
1070 if (curr_DemonType) then Dcr_debug_bis ("Pet Type: " .. curr_DemonType); end;
1071  
1072 if (last_DemonType ~= curr_DemonType) then
1073 if (curr_DemonType) then Dcr_debug_bis ("Pet name changed: " .. curr_DemonType); else Dcr_debug_bis ("No more pet!"); end;
1074  
1075 last_DemonType = curr_DemonType;
1076 Dcr_Configure();
1077 end
1078  
1079 Dcr_CheckingPET = false;
1080 return;
1081 end
1082  
1083 end
1084  
1085 -- clean up the blacklist
1086 for unit in Dcr_Blacklist_Array do
1087 Dcr_Blacklist_Array[unit] = Dcr_Blacklist_Array[unit] - arg1;
1088 if (Dcr_Blacklist_Array[unit] < 0) then
1089 Dcr_Blacklist_Array[unit] = nil;
1090 end
1091 end
1092  
1093 -- wow the next command SPAMS alot
1094 -- Dcr_debug("got update "..arg1);
1095  
1096 -- this is the fix for the AttackTarget() bug
1097 if (Dcr_Delay_Timer > 0) then
1098 Dcr_Delay_Timer = Dcr_Delay_Timer - arg1;
1099 if (Dcr_Delay_Timer <= 0) then
1100 if (not Dcr_CombatMode) then
1101 Dcr_debug("trying to reset the combat mode");
1102 AttackTarget();
1103 else
1104 Dcr_debug("already in combat mode");
1105 end
1106 end;
1107 end
1108 end
1109  
1110 -------------------------------------------------------------------------------
1111 -- Scanning functionalty... this scans the parties and groups
1112 -------------------------------------------------------------------------------
1113 local Dcr_AlreadyCleanning = false;
1114 local Dcr_RestoreTarget = true;
1115 function Dcr_Clean(UseThisTarget, SwitchToTarget)
1116 -----------------------------------------------------------------------
1117 -- first we do the setup, make sure we can cast the spells
1118 -----------------------------------------------------------------------
1119  
1120 if (not DCR_HAS_SPELLS) then
1121 -- check the spellbook again... (mod by Archarodim)
1122 Dcr_errln(DCR_NO_SPELLS);
1123 Dcr_Configure();
1124 if (not DCR_HAS_SPELLS) then
1125 Dcr_errln(DCR_NO_SPELLS);
1126 return false;
1127 end
1128 end
1129  
1130 Dcr_RestoreTarget = true;
1131 if (UseThisTarget and SwitchToTarget) then
1132 TargetUnit(UseThisTarget);
1133 Dcr_RestoreTarget = false;
1134 end
1135  
1136 if (Dcr_AlreadyCleanning) then
1137 Dcr_debug_bis("I'm already cleaning!!!!"); -- seems to be useless
1138 return false;
1139 end
1140  
1141 Dcr_AlreadyCleanning = true;
1142  
1143 --[[
1144 local isUsable, notEnoughMana = Dcr_IsSpellUsable();
1145  
1146 if (not isUsable) then
1147 if (notEnoughMana) then
1148 Dcr_errln(DCR_STR_NOMANA);
1149 Dcr_AlreadyCleanning = false;
1150 return false;
1151 elseif (Dcr_PlayerClass ~= DCR_CLASS_PRIEST) then
1152 Dcr_errln(DCR_STR_UNUSABLE);
1153 Dcr_AlreadyCleanning = false;
1154 return false;
1155 end
1156 end
1157 --]]
1158  
1159  
1160 local _, cooldown = GetSpellCooldown(DCR_SPELL_COOLDOWN_CHECK[1], DCR_SPELL_COOLDOWN_CHECK[2])
1161 if (cooldown ~= 0) then
1162 -- this used to be an errline... changed it to debugg
1163 Dcr_debug_bis(DCR_NO_SPELLS_RDY);
1164 Dcr_AlreadyCleanning = false;
1165 return false;
1166 end
1167  
1168  
1169 -- reset blaclisted people in this clean session
1170 DCR_ThisCleanBlaclisted = { };
1171 -- reset the number of out of ranged units for this clean session
1172 DCR_ThisNumberOoRUnits = 0;
1173  
1174  
1175 -----------------------------------------------------------------------
1176 -----------------------------------------------------------------------
1177 -- then we see what our target looks like, if freindly, check them
1178 -----------------------------------------------------------------------
1179  
1180 local targetEnemy = false;
1181 local targetName = nil; -- if friendly
1182 local cleaned = false;
1183 local resetCombatMode = false;
1184 Dcr_Casting_Spell_On = nil;
1185  
1186  
1187  
1188 if (UnitExists("target")) then
1189 Dcr_debug("We have a target");
1190 -- if we are currently targeting something
1191 -- ###
1192 -- This block is here to know what the current target is, so we can clean it, restor it
1193 -- or clear the target at the end of this function
1194 -- ###
1195  
1196 if (Dcr_CombatMode) then
1197 Dcr_debug("when done scanning... if switched target reset the mode!");
1198 resetCombatMode = true;
1199 end
1200  
1201 if (
1202 ( UnitIsFriend("target", "player") ) -- unit is a friend ie: not FriendLY just a friend that could be MC :/
1203 and
1204 (not UnitIsCharmed("target")) -- and is not mind controlled
1205 ) then
1206 Dcr_debug(" It is friendly");
1207  
1208 -- try cleaning the current target first
1209 -- if we are not asked to clean a specific target
1210 -- or if we already switched to the target to clean
1211 if (not UseThisTarget or SwitchToTarget) then
1212 cleaned = Dcr_CureUnit("target");
1213 end
1214  
1215 -- we are targeting a player that is not MC, save the name to switch back later
1216 targetName = UnitName("target");
1217  
1218 else -- unit is aggressiv or is charmed
1219 Dcr_debug(" It is not friendly");
1220 -- we are targeting an enemy... switch back when done
1221 targetEnemy = true;
1222  
1223 if ( UnitIsCharmed("target")) then
1224 Dcr_debug( "Unit is enemey... and charmed... so its a mind controlled friendly");
1225 -- try cleaning mind controlled person first
1226 if (not UseThisTarget or SwitchToTarget) then
1227 cleaned = Dcr_CureUnit("target");
1228 end
1229 end
1230 end
1231 end
1232  
1233 if (UseThisTarget and not SwitchToTarget and not cleaned) then
1234 Dcr_debug( "A target to clean was specifyed");
1235 if (UnitIsVisible(UseThisTarget)) then
1236 -- if the unit is even close by
1237  
1238  
1239 if (DCR_CAN_CURE_ENEMY_MAGIC and UnitIsCharmed(UseThisTarget)) then
1240 -- if the unit is mind controlled and we can cure it
1241 if (Dcr_CureUnit(UseThisTarget)) then
1242 cleaned = true;
1243 end
1244  
1245 else -- we can't cure magic on enemies or the unit is not charmed
1246 if (not Dcr_CheckUnitStealth(UseThisTarget)) then
1247 -- we are either not ignoring the stealthed people,
1248 -- or it's not stealthed
1249 if (Dcr_CureUnit(UseThisTarget)) then
1250 cleaned = true;
1251 end
1252 end
1253 end
1254 end
1255 end
1256  
1257 if (not cleaned) then
1258  
1259 -----------------------------------------------------------------------
1260 -----------------------------------------------------------------------
1261 -- now we check the partys (raid and local)
1262 -----------------------------------------------------------------------
1263 Dcr_debug( "Checking the arrays");
1264  
1265 -- this is the cleaning loops...
1266 local Dcr_Unit_Array = Dcr_GetUnitArray();
1267 -- the order is player, party1-4, raid, pet, partypet1-4, raidpet1-40
1268 -- the raid is current party + 1 to 8... then 1 to current party - 1
1269  
1270 -- mind control first
1271 if( not cleaned) then
1272 Dcr_debug(" looking for mind controll");
1273 if (DCR_CAN_CURE_ENEMY_MAGIC) then
1274 for _, unit in Dcr_Unit_Array do
1275 -- all of the units...
1276 if (not Dcr_Blacklist_Array[unit]) then
1277 -- if the unit is not black listed
1278 if (UnitIsVisible(unit)) then
1279 -- if the unit is even close by
1280 if (UnitIsCharmed(unit)) then
1281 -- if the unit is mind controlled
1282 if (Dcr_CureUnit(unit)) then
1283 cleaned = true;
1284 break;
1285 end
1286 end
1287 end
1288 end
1289 end
1290 end
1291 end
1292  
1293 -- normal cleaning
1294 if( not cleaned) then
1295 -- Dcr_debug(" normal loop");
1296 for _, unit in Dcr_Unit_Array do
1297 -- all of the units...
1298 if (not Dcr_Blacklist_Array[unit]) then
1299 -- if the unit is not black listed
1300 if (UnitIsVisible(unit)) then
1301 -- if the unit is even close by
1302 if (not UnitIsCharmed(unit)) then
1303 -- we can't cure mind controlled people
1304 if (not Dcr_CheckUnitStealth(unit)) then
1305 -- we are either not ignoring the stealthed people,
1306 -- or it's not stealthed
1307 if (Dcr_CureUnit(unit)) then
1308 cleaned = true;
1309 break;
1310 end
1311 end
1312 end
1313 end
1314 end
1315 end
1316 end
1317  
1318 if ( not cleaned) then
1319 Dcr_debug(" double check the black list");
1320 for unit in Dcr_Blacklist_Array do
1321 -- now... all of the black listed units
1322 if (not DCR_ThisCleanBlaclisted[unit]) then
1323 -- we do not re-check unit that have been blaclisted just before
1324 if (UnitExists(unit)) then
1325 -- if the unit still exists
1326 if (UnitIsVisible(unit)) then
1327 -- if the unit is even close by
1328 if (not Dcr_CheckUnitStealth(unit)) then
1329 -- we are either not ignoring the stealthed people,
1330 -- or it's not stealthed
1331 if (Dcr_CureUnit(unit)) then
1332 -- hey... we cleaned it... remove from the black list
1333 Dcr_Blacklist_Array[unit] = nil;
1334 cleaned = true;
1335 break;
1336 end
1337 end
1338 end
1339 end
1340 end
1341 end
1342 end
1343 end
1344 -----------------------------------------------------------------------
1345 -----------------------------------------------------------------------
1346 -- ok... done with the cleaning... lets try to clean this up
1347 -- basically switch targets back if they were changed
1348 -----------------------------------------------------------------------
1349  
1350 if (not SwitchToTarget) then -- if not explicitly ask to switch to the target
1351 if (targetEnemy) then
1352 -- we had somethign "bad" targeted
1353 if (not UnitIsEnemy("target", "player")) then
1354 -- and we tested for range, cast dispell magic, or some how broke target... switch back
1355 Dcr_debug("targeting enemy");
1356 -- TargetLastEnemy();
1357 TargetUnit("playertarget"); -- XXX to test
1358 if (resetCombatMode) then
1359 -- resetCombatMode is the fix for "auto attack"
1360 Dcr_Delay_Timer = Dcr_SpellCombatDelay;
1361 Dcr_debug("done... now we wait for the leave combat event");
1362 end
1363 end
1364 elseif (targetName) then
1365 -- we had a friendly targeted... switch back if not still targeted
1366 if ( targetName ~= UnitName("target") ) then
1367 TargetByName(targetName);
1368 end
1369 else
1370 -- we had nobody targeted originally
1371 if (UnitExists("target")) then
1372 -- we checked for range
1373 ClearTarget();
1374 end
1375 end
1376 end
1377  
1378 if (not cleaned) then
1379 Dcr_println( DCR_NOT_CLEANED);
1380 end
1381  
1382 Dcr_AlreadyCleanning = false;
1383 return cleaned;
1384 end
1385  
1386  
1387  
1388 -------------------------------------------------------------------------------
1389 -- these are the spells used to clean a "unit" given
1390 -------------------------------------------------------------------------------
1391 function Dcr_CureUnit(Unit)
1392 Dcr_debug( "Scanning to cure unit - "..Unit);
1393  
1394 local Magic_Count = 0;
1395 local Disease_Count = 0;
1396 local Poison_Count = 0;
1397 local Curse_Count = 0;
1398  
1399 local TClass, UClass = UnitClass(Unit);
1400  
1401 local i = 1;
1402 while (UnitDebuff(Unit, i)) do
1403 -- the "break" was not working all that well, so we stor a go on variable
1404 local Go_On = true;
1405  
1406 local debuff_name, debuff_type = Dcr_GetUnitDebuff(Unit, i);
1407  
1408 if (debuff_name == nil) then
1409 -- this should only happen when things are "broke"
1410 Dcr_errln("%$#@*& !!! Impossible to get debuff info from tooltip :'(, if this error continues to show up, type /console reloadui");
1411 Dcr_debug( "Debuff name not found!");
1412 Go_On = false;
1413 elseif (debuff_name ~= "") then
1414 Dcr_debug( debuff_name.." found!");
1415  
1416 -- test if we have to ignore this debuff {{{ --
1417 -- Ignore the ones that make the target immune... abort the user
1418 if (DCR_IGNORELIST[debuff_name]) then
1419 Dcr_errln( string.gsub( string.gsub(DCR_IGNORE_STRING, "$t", UnitName(Unit)), "$a", debuff_name));
1420 return false;
1421 end
1422  
1423  
1424 -- Ignore debuffs that are in fact buffs
1425 if (DCR_SKIP_LIST[debuff_name]) then
1426 Dcr_errln( string.gsub( string.gsub(DCR_IGNORE_STRING, "$t", UnitName(Unit)), "$a", debuff_name));
1427 Go_On = false; -- == continue
1428 end
1429  
1430 -- If we are in combat lets see if there is any debuffs we cn afford to not remove until ths fight is over
1431 if (UnitAffectingCombat("player")) then
1432 if (DCR_SKIP_BY_CLASS_LIST[UClass]) then
1433 if (DCR_SKIP_BY_CLASS_LIST[UClass][debuff_name]) then
1434 -- these are just ones you don't care about by class
1435 Dcr_errln( string.gsub( string.gsub(DCR_IGNORE_STRING, "$t", UnitName(Unit)), "$a", debuff_name));
1436 Go_On = false; -- == continue
1437 end
1438 end
1439 end
1440 -- }}}
1441  
1442 if (Go_On) then
1443 -- it is one we "care" about... lets catalog it -- {{{ --
1444 if (debuff_type and debuff_type ~= "") then
1445 if (debuff_type == DCR_MAGIC) then
1446 Dcr_debug( "it's magic");
1447 Magic_Count = Magic_Count + 1;
1448 elseif (debuff_type == DCR_DISEASE) then
1449 Dcr_debug( "it's disease");
1450 Disease_Count = Disease_Count + 1;
1451 elseif (debuff_type == DCR_POISON) then
1452 Dcr_debug( "it's poison");
1453 Poison_Count = Poison_Count + 1;
1454 elseif (debuff_type == DCR_CURSE) then
1455 Dcr_debug( "it's curse");
1456 Curse_Count = Curse_Count + 1
1457 else
1458 Dcr_debug( "it's unknown - "..debuff_type);
1459 end
1460 else
1461 Dcr_debug( "it's untyped");
1462 end
1463 -- }}}
1464 end
1465 end
1466  
1467 i = i + 1;
1468 end
1469  
1470 local res = false;
1471 -- order these in the way you find most important
1472 if (not res) then
1473 res = Dcr_Cure_Magic(Magic_Count, Unit);
1474 end
1475 if (not res) then
1476 res = Dcr_Cure_Curse( Curse_Count, Unit);
1477 end
1478 if (not res) then
1479 res = Dcr_Cure_Poison( Poison_Count, Unit);
1480 end
1481 if (not res) then
1482 res = Dcr_Cure_Disease( Disease_Count, Unit);
1483 end
1484  
1485 return res;
1486 end
1487  
1488 function Dcr_Cure_Magic(Magic_Count, Unit)
1489 Dcr_debug( "magic count "..Magic_Count);
1490 if (DCR_CAN_CURE_MAGIC) then
1491 Dcr_debug( "Can cure magic");
1492 end
1493 if (DCR_CAN_CURE_ENEMY_MAGIC) then
1494 Dcr_debug( "Can cure enemy magic");
1495 end
1496  
1497 if ( (not (DCR_CAN_CURE_MAGIC or DCR_CAN_CURE_ENEMY_MAGIC)) or (Magic_Count == 0) ) then
1498 -- here is no magical effects... or
1499 -- we can't cure magic don't bother going forward
1500 Dcr_debug( "no magic");
1501 return false;
1502 end
1503 Dcr_debug( "curing magic");
1504  
1505 if ( DCR_CAN_CURE_ENEMY_MAGIC and UnitIsCharmed(Unit) and UnitCanAttack("player", Unit) ) then
1506 -- unit is charmed... and has magic debuffs on them... and we CAN attack it
1507 -- there is a good chance that it is the mind controll type spell
1508 -- the checking for the UnitCanAttack is due to the mind controlled pets and other enslaves
1509 if (DCR_SPELL_ENEMY_MAGIC_2[1] ~= 0 ) and (Dcr_Saved.AlwaysUseBestSpell or (Magic_Count > 1) or (DCR_SPELL_MAGIC_1[1] == 0)) then
1510 return Dcr_Cast_CureSpell( DCR_SPELL_ENEMY_MAGIC_2, Unit, DCR_CHARMED, true);
1511 else
1512 return Dcr_Cast_CureSpell( DCR_SPELL_ENEMY_MAGIC_1, Unit, DCR_CHARMED, true);
1513 end
1514 elseif (DCR_CAN_CURE_MAGIC and (not UnitCanAttack("player", Unit))) then
1515 -- we can cure magic... and the unit is NOT hostile to us (we can't cast on those)
1516 if (DCR_SPELL_MAGIC_2[1] ~= 0 ) and (Dcr_Saved.AlwaysUseBestSpell or (Magic_Count > 1) or (DCR_SPELL_MAGIC_1[1] == 0)) then
1517 return Dcr_Cast_CureSpell( DCR_SPELL_MAGIC_2, Unit, DCR_MAGIC, DCR_CAN_CURE_ENEMY_MAGIC);
1518 else
1519 return Dcr_Cast_CureSpell( DCR_SPELL_MAGIC_1, Unit, DCR_MAGIC, DCR_CAN_CURE_ENEMY_MAGIC);
1520 end
1521 -- else
1522 -- what it means:
1523 -- not (DCR_CAN_CURE_ENEMY_MAGIC and UnitIsCharmed(Unit) and UnitCanAttack("player", Unit)
1524 -- not (DCR_CAN_CURE_MAGIC and (not UnitCanAttack("player", Unit)))
1525 --
1526 -- !DCR_CAN_CURE_ENEMY_MAGIC or !UnitIsCharmed(Unit) or !UnitCanAttack("player", Unit) =====> not MC or we can't attack it
1527 -- AND
1528 -- !DCR_CAN_CURE_MAGIC UnitCanAttack("player", Unit)
1529 --
1530 -- we can't cure enemy magic
1531 -- Dcr_errln("Something strange happened :/ Dcr_Cure_Magic() did nothing :-o");
1532 end
1533 return false;
1534 end
1535  
1536 function Dcr_Cure_Curse( Curse_Count, Unit)
1537 if ( (not DCR_CAN_CURE_CURSE) or (Curse_Count == 0)) then
1538 -- no curses or no curse curing spells
1539 Dcr_debug( "no curse");
1540 return false;
1541 end
1542 Dcr_debug( "curing curse");
1543  
1544 if (UnitIsCharmed(Unit)) then
1545 -- we can not cure a mind contorolled player
1546 return;
1547 end
1548  
1549 if (DCR_SPELL_CURSE ~= 0) then
1550 return Dcr_Cast_CureSpell(DCR_SPELL_CURSE, Unit, DCR_CURSE, false);
1551 end
1552 return false;
1553 end
1554  
1555 function Dcr_Cure_Poison(Poison_Count, Unit)
1556 if ( (not DCR_CAN_CURE_POISON) or (Poison_Count == 0)) then
1557 -- here is no magical effects... or
1558 -- we can't cure magic don't bother going forward
1559 Dcr_debug( "no poison");
1560 return false;
1561 end
1562 Dcr_debug( "curing poison");
1563  
1564 if (UnitIsCharmed(Unit)) then
1565 -- we can not cure a mind contorolled player
1566 return;
1567 end
1568  
1569 if (Dcr_Saved.Check_For_Abolish and Dcr_CheckUnitForBuff(Unit, DCR_SPELL_ABOLISH_POISON)) then
1570 return false;
1571 end
1572  
1573 if (DCR_SPELL_POISON_2[1] ~= 0 ) and (Dcr_Saved.AlwaysUseBestSpell or (Poison_Count > 1)) then
1574 return Dcr_Cast_CureSpell( DCR_SPELL_POISON_2, Unit, DCR_POISON, false);
1575 else
1576 return Dcr_Cast_CureSpell( DCR_SPELL_POISON_1, Unit, DCR_POISON, false);
1577 end
1578 end
1579  
1580 function Dcr_Cure_Disease(Disease_Count, Unit)
1581 if ( (not DCR_CAN_CURE_DISEASE) or (Disease_Count == 0) ) then
1582 -- here is no magical effects... or
1583 -- we can't cure magic don't bother going forward
1584 Dcr_debug( "no disease");
1585 return false;
1586 end
1587 Dcr_debug( "curing disease");
1588  
1589 if (UnitIsCharmed(Unit)) then
1590 -- we can not cure a mind contorolled player
1591 return;
1592 end
1593  
1594 if (Dcr_Saved.Check_For_Abolish and Dcr_CheckUnitForBuff(Unit, DCR_SPELL_ABOLISH_DISEASE)) then
1595 return false;
1596 end
1597  
1598 if (DCR_SPELL_DISEASE_2[1] ~= 0 ) and (Dcr_Saved.AlwaysUseBestSpell or (Disease_Count > 1)) then
1599 return Dcr_Cast_CureSpell( DCR_SPELL_DISEASE_2, Unit, DCR_DISEASE, false);
1600 else
1601 return Dcr_Cast_CureSpell( DCR_SPELL_DISEASE_1, Unit, DCR_DISEASE, false);
1602 end
1603 end
1604  
1605 function Dcr_Cast_CureSpell( spellID, Unit, AfflictionType, ClearCurrentTarget)
1606 local name = UnitName(Unit);
1607  
1608  
1609 if (spellID[1] == 0) then
1610 Dcr_errln("Stupid call to Dcr_Cast_CureSpell() with a null spellID!!!");
1611 return false;
1612 end
1613  
1614 -- check to see if we are in range
1615 if (
1616 (spellID[2] ~= BOOKTYPE_PET) and
1617 (not Dcr_UnitInRange(Unit))
1618 ) then
1619  
1620 -- XXX We do not blacklist out of range people any more, they don't prevent anything from hapenning
1621 -- it will just spam a bit if there are a lot of them...
1622  
1623 -- Dcr_Blacklist_Array[Unit] = nil; -- attempt to remove it
1624 -- Dcr_Blacklist_Array[Unit] = Dcr_Saved.CureBlacklist; -- add it to the blacklist, hopefully at the end
1625  
1626 -- DCR_ThisCleanBlaclisted[Unit] = true;
1627  
1628 Dcr_errln( string.gsub( string.gsub(DCR_OUT_OF_RANGE, "$t", name), "$a", AfflictionType));
1629 -- DCR_ThisNumberOoRUnits = DCR_ThisNumberOoRUnits + 1;
1630 return false;
1631 else
1632 Dcr_debug_bis("Unit is in range or we don't check for range");
1633 end
1634 Dcr_debug_bis( "try to cast: "..spellID[1] .." - ".. spellID[2]);
1635 local spellName = GetSpellName(spellID[1], spellID[2]);
1636 Dcr_debug( "casting - "..spellName);
1637  
1638 -- clear the target if it will interfear
1639 if (ClearCurrentTarget) then
1640 -- it can target enemys... do don't target ANYTHING else
1641 if ( not UnitIsUnit( "target", Unit) ) then
1642 ClearTarget();
1643 end
1644 elseif ( UnitIsFriend( "player", "target") ) then
1645 -- we can accedenally cure friendly targets...
1646 if ( not UnitIsUnit( "target", Unit) ) then
1647 -- and we want to cure someone else who is not targeted
1648 ClearTarget();
1649 end
1650 end
1651  
1652 -- ClearTarget();
1653 Dcr_println( string.gsub( string.gsub( string.gsub(DCR_CLEAN_STRING, "$t", string.upper(name)), "$a", AfflictionType), "$s", spellName));
1654 Dcr_debug_bis( "casting on " .. UnitName(Unit) .. " -- " .. Unit);
1655 if (spellID[2] == BOOKTYPE_PET) then
1656 TargetUnit(Unit);
1657 end
1658  
1659 -- if a spell is awaiting for a target, cancel it
1660 if ( SpellIsTargeting()) then
1661 SpellStopTargeting();
1662 end
1663  
1664 -- cast the spell
1665 Dcr_Casting_Spell_On = Unit;
1666 CastSpell(spellID[1], spellID[2]);
1667  
1668 -- if the spell doesn't need a target
1669 if (Dcr_RestoreTarget and spellID[2] == BOOKTYPE_PET) then
1670 TargetUnit("playertarget"); -- restore previous target
1671 else
1672 -- if the cast succeeded
1673 if (SpellIsTargeting()) then
1674 SpellTargetUnit(Unit);
1675 end
1676 end
1677  
1678 -- if the targeting failed (still waiting for a target), cancel the cast
1679 if ( SpellIsTargeting()) then
1680 SpellStopTargeting();
1681 end
1682  
1683 return true;
1684 end
1685  
1686  
1687 function Dcr_SpellCastFailed()
1688 if (
1689 Dcr_Casting_Spell_On -- a cast failed and we were casting on someone
1690 and not (
1691 UnitIsUnit(Dcr_Casting_Spell_On, "player") -- we do not blacklist ourself
1692 or
1693 (
1694 -- we do not blacklist people in the priority list
1695 Dcr_Saved.DoNot_Blacklist_Prio_List and Dcr_IsInPriorList ( UnitName(Dcr_Casting_Spell_On) )
1696 )
1697 )
1698 ) then
1699  
1700 Dcr_Blacklist_Array[Dcr_Casting_Spell_On] = nil;
1701 Dcr_Blacklist_Array[Dcr_Casting_Spell_On] = Dcr_Saved.CureBlacklist;
1702 DCR_ThisCleanBlaclisted[Dcr_Casting_Spell_On] = true;
1703 end
1704 end
1705  
1706 function Dcr_SpellWasCast()
1707 Dcr_Casting_Spell_On = nil;
1708 end
1709  
1710 function Dcr_GetUnitBuff (Unit, i)
1711 Dcr_ScanningTooltipTextLeft1:SetText("");
1712  
1713 Dcr_ScanningTooltip:SetUnitBuff(Unit, i); -- fill this fake thing with buff info
1714  
1715 local buff_name = Dcr_ScanningTooltipTextLeft1:GetText(); -- get the buff name
1716 -- local buff_type = Dcr_ScanningTooltipTextRight1:GetText();
1717  
1718 return buff_name;
1719  
1720 end
1721  
1722 function Dcr_GetUnitDebuff (Unit, i)
1723 -- Dcr_ScanningTooltip:ClearLines(); -- clear the tooltip
1724 Dcr_ScanningTooltipTextRight1:SetText("");
1725 Dcr_ScanningTooltipTextLeft1:SetText("");
1726  
1727 Dcr_ScanningTooltip:SetUnitDebuff(Unit, i); -- fill this fake thing with Debuff info
1728  
1729 local debuff_name = Dcr_ScanningTooltipTextLeft1:GetText(); -- get the debuff name
1730 local debuff_type = Dcr_ScanningTooltipTextRight1:GetText(); -- get the debuff type
1731  
1732 return debuff_name, debuff_type;
1733 end
1734  
1735 function Dcr_CheckUnitForBuff(Unit, BuffName)
1736 for i = 1, DCR_MAXBUFFS do
1737 local buff_texture = UnitBuff(Unit, i);
1738  
1739 if buff_texture then
1740  
1741 local found_buff_name = Dcr_GetUnitBuff(Unit, i);
1742  
1743 if (found_buff_name == BuffName) then
1744 return true;
1745 end
1746  
1747  
1748 else
1749 break; -- XXX to verify
1750 end
1751 end
1752 return false;
1753 end
1754  
1755 function Dcr_CheckUnitStealth(Unit)
1756 if (Dcr_Saved.Ingore_Stealthed) then
1757 for BuffName in DCR_INVISIBLE_LIST do
1758 if Dcr_CheckUnitForBuff(Unit, BuffName) then
1759 return true;
1760 end
1761 end
1762 end
1763 return false;
1764 end
1765  
1766 function Dcr_IsSpellUsable ()
1767 local CuringActionSlot = Dcr_FindCureingActionSlot(Dcr_CuringAction_Icons);
1768  
1769 if (CuringActionSlot ~= 0) then
1770 return IsUsableAction(CuringActionSlot);
1771 else
1772 return true;
1773 end
1774 end
1775  
1776 -------------------------------------------------------------------------------
1777 -- now the range functions....
1778 -------------------------------------------------------------------------------
1779 --[[
1780 function Dcr_UnitInRange(Unit)
1781 -- this means that we are not even fraking close...
1782 -- don't bother going further
1783 if (not UnitIsVisible(Unit)) then
1784 return false;
1785 end
1786  
1787 -- Dcr_Saved.RangeCheck = false; -- disable this option for now
1788 if (not Dcr_Saved.RangeCheck) then
1789 -- we are not bothering to check for range.
1790 -- this will keep a pally from breaking swing most times
1791 return true;
1792 end
1793  
1794 local Dcr_Range_Slot = Dcr_FindCureingActionSlot(Dcr_CuringAction_Icons);
1795  
1796 if (Dcr_Range_Slot ~= 0) then
1797 TargetUnit(Unit);
1798 if UnitIsUnit("target", Unit) then
1799 return (IsActionInRange(Dcr_Range_Slot) == 1);
1800 else
1801 return false; -- if we can't target... then its out of range
1802 end
1803 end
1804  
1805 -- we don't know... return true just in case
1806 return true;
1807  
1808 end
1809 --]]
1810  
1811  
1812 function Dcr_UnitInRange(Unit)
1813 -- if (not Dcr_Saved.RangeCheck) then
1814 -- return true;
1815 -- end
1816 if(CheckInteractDistance(Unit, 4)) then
1817 return true;
1818 end
1819 return false;
1820 end
1821  
1822  
1823 local Dcr_LastFoundSlot = nil;
1824 local Dcr_LastActionBarScan = 0;
1825 function Dcr_FindCureingActionSlot(iconArray)
1826  
1827 if (Dcr_PlayerClass == DCR_CLASS_WARLOCK) then
1828 return 0;
1829 end
1830  
1831 if (Dcr_LastFoundSlot) then
1832 if (HasAction(Dcr_LastFoundSlot)) then
1833 icon = GetActionTexture(Dcr_LastFoundSlot);
1834 if (iconArray[icon]) then
1835 if (GetActionText(Dcr_LastFoundSlot) == nil) then
1836 local spellName = iconArray[icon];
1837  
1838 Dcr_ScanningTooltipTextLeft1:SetText("");
1839  
1840 Dcr_ScanningTooltip:SetAction(Dcr_LastFoundSlot);
1841  
1842 local slotName = Dcr_ScanningTooltipTextLeft1:GetText();
1843  
1844 if (spellName == slotName) then
1845 Dcr_debug_bis("cache used!");
1846 return Dcr_LastFoundSlot;
1847 end
1848 end
1849 end
1850 end
1851 end
1852  
1853 -- This is to prevent a freeze issue
1854 if (GetTime() - Dcr_LastActionBarScan < 30) then
1855 return 0;
1856 end
1857 local i = 0;
1858 for i = DCR_START_SLOT, DCR_END_SLOT do
1859 if (HasAction(i)) then
1860 icon = GetActionTexture(i);
1861 if (iconArray[icon]) then
1862 if (GetActionText(i) == nil) then
1863 local spellName = iconArray[icon];
1864  
1865 Dcr_ScanningTooltipTextLeft1:SetText("");
1866  
1867 Dcr_ScanningTooltip:SetAction(i);
1868  
1869 local slotName = Dcr_ScanningTooltipTextLeft1:GetText();
1870  
1871 if (spellName == slotName) then
1872 Dcr_LastFoundSlot = i;
1873 return i;
1874 end
1875 else
1876 Dcr_debug_bis("GetActionText: " .. GetActionText(i) );
1877 end
1878 end
1879 end
1880 end
1881 Dcr_LastActionBarScan = GetTime();
1882 Dcr_errln("Decursive can't find your curing spell in your action bars, next try in 30 seconds...");
1883 return 0;
1884 end
1885  
1886 -------------------------------------------------------------------------------
1887 -- the UI code
1888 -------------------------------------------------------------------------------
1889  
1890 function Dcr_PriorityListEntryTemplate_OnClick()
1891 local id = this:GetID();
1892 if (id) then
1893 if (this.Priority) then
1894 Dcr_RemoveIDFromPriorityList(id);
1895 else
1896 Dcr_RemoveIDFromSkipList(id);
1897 end
1898 end
1899 this.UpdateYourself = true;
1900  
1901 end
1902  
1903 function Dcr_PriorityListEntryTemplate_OnUpdate()
1904 if (this.UpdateYourself) then
1905 this.UpdateYourself = false;
1906 local baseName = this:GetName();
1907 local NameText = getglobal(baseName.."Name");
1908  
1909 local id = this:GetID();
1910 if (id) then
1911 local name
1912 if (this.Priority) then
1913 name = Dcr_Saved.PriorityList[id];
1914 else
1915 name = Dcr_Saved.SkipList[id];
1916 end
1917 if (name) then
1918 NameText:SetText(id.." - "..name);
1919 else
1920 NameText:SetText("Error - ID Invalid!");
1921 end
1922 else
1923 NameText:SetText("Error - No ID!");
1924 end
1925 end
1926 end
1927  
1928 function Dcr_PriorityListFrame_OnUpdate()
1929 if (this.UpdateYourself) then
1930 this.UpdateYourself = false;
1931 local baseName = this:GetName();
1932 local up = getglobal(baseName.."Up");
1933 local down = getglobal(baseName.."Down");
1934  
1935  
1936 local size = table.getn(Dcr_Saved.PriorityList);
1937  
1938 if (size < 11 ) then
1939 this.Offset = 0;
1940 up:Hide();
1941 down:Hide();
1942 else
1943 if (this.Offset <= 0) then
1944 this.Offset = 0;
1945 up:Hide();
1946 down:Show();
1947 elseif (this.Offset >= (size - 10)) then
1948 this.Offset = (size - 10);
1949 up:Show();
1950 down:Hide();
1951 else
1952 up:Show();
1953 down:Show();
1954 end
1955 end
1956  
1957 local i;
1958 for i = 1, 10 do
1959 local id = ""..i;
1960 if (i < 10) then
1961 id = "0"..i;
1962 end
1963 local btn = getglobal(baseName.."Index"..id);
1964  
1965 btn:SetID( i + this.Offset);
1966 btn.UpdateYourself = true;
1967  
1968 if (i <= size) then
1969 btn:Show();
1970 else
1971 btn:Hide();
1972 end
1973 end
1974 end
1975  
1976 end
1977  
1978 function Dcr_SkipListFrame_OnUpdate()
1979 if (this.UpdateYourself) then
1980 this.UpdateYourself = false;
1981 local baseName = this:GetName();
1982 local up = getglobal(baseName.."Up");
1983 local down = getglobal(baseName.."Down");
1984  
1985  
1986 local size = table.getn(Dcr_Saved.SkipList);
1987  
1988 if (size < 11 ) then
1989 this.Offset = 0;
1990 up:Hide();
1991 down:Hide();
1992 else
1993 if (this.Offset <= 0) then
1994 this.Offset = 0;
1995 up:Hide();
1996 down:Show();
1997 elseif (this.Offset >= (size - 10)) then
1998 this.Offset = (size - 10);
1999 up:Show();
2000 down:Hide();
2001 else
2002 up:Show();
2003 down:Show();
2004 end
2005 end
2006  
2007 local i;
2008 for i = 1, 10 do
2009 local id = ""..i;
2010 if (i < 10) then
2011 id = "0"..i;
2012 end
2013 local btn = getglobal(baseName.."Index"..id);
2014  
2015 btn:SetID( i + this.Offset);
2016 btn.UpdateYourself = true;
2017  
2018 if (i <= size) then
2019 btn:Show();
2020 else
2021 btn:Hide();
2022 end
2023 end
2024 end
2025  
2026 end
2027  
2028 function Dcr_DisplayTooltip(Message, RelativeTo)
2029 DcrDisplay_Tooltip:SetOwner(RelativeTo, "ANCHOR_TOPRIGHT");
2030 DcrDisplay_Tooltip:ClearLines();
2031 DcrDisplay_Tooltip:SetText(Message);
2032 DcrDisplay_Tooltip:Show();
2033 end
2034  
2035 function Dcr_PopulateButtonPress()
2036 local addFunction = this:GetParent().addFunction;
2037  
2038 if (this.ClassType) then
2039 -- for the class type stuff... we do party
2040  
2041 local _, pclass = UnitClass("player");
2042 if (pclass == this.ClassType) then
2043 addFunction("player");
2044 end
2045  
2046 _, pclass = UnitClass("party1");
2047 if (pclass == this.ClassType) then
2048 addFunction("party1");
2049 end
2050 _, pclass = UnitClass("party2");
2051 if (pclass == this.ClassType) then
2052 addFunction("party2");
2053 end
2054 _, pclass = UnitClass("party3");
2055 if (pclass == this.ClassType) then
2056 addFunction("party3");
2057 end
2058 _, pclass = UnitClass("party4");
2059 if (pclass == this.ClassType) then
2060 addFunction("party4");
2061 end
2062 end
2063  
2064 local max = GetNumRaidMembers();
2065 local i;
2066 if (max > 0) then
2067 for i = 1, max do
2068 local _, _, pgroup, _, _, pclass = GetRaidRosterInfo(i);
2069  
2070 if (this.ClassType) then
2071 if (pclass == this.ClassType) then
2072 addFunction("raid"..i);
2073 end
2074 end
2075 if (this.GroupNumber) then
2076 if (pgroup == this.GroupNumber) then
2077 addFunction("raid"..i);
2078 end
2079 end
2080 end
2081 end
2082  
2083 end
2084  
2085 function Dcr_DebuffTemplate_OnEnter()
2086 DcrDisplay_Tooltip:SetOwner(this, "ANCHOR_CURSOR");
2087 DcrDisplay_Tooltip:ClearLines();
2088 DcrDisplay_Tooltip:SetUnitDebuff(this.unit,this.debuff); -- OK
2089 DcrDisplay_Tooltip:Show();
2090 end
2091  
2092 function Dcr_LiveListItem_OnUpdate()
2093 if (this.UpdateMe) then
2094 this.UpdateMe = false;
2095 local texture = UnitDebuff(this.unit,this.debuff);
2096 if (texture) then
2097 local baseFrame = this:GetName();
2098 getglobal(baseFrame.."DebuffIcon"):SetTexture(texture);
2099  
2100 getglobal(baseFrame.."Name"):SetText(UnitName(this.unit));
2101  
2102 local debuff_name, debuff_type = Dcr_GetUnitDebuff(this.unit, this.debuff);
2103  
2104 getglobal(baseFrame.."Affliction"):SetText(debuff_name);
2105 end
2106 end
2107 end
2108  
2109 local Dcr_SoundPlayed = false;
2110 function Dcr_PlaySound ()
2111 if (Dcr_Saved.PlaySound and not Dcr_SoundPlayed) then
2112 -- good sounds: Sound\\Doodad\\BellTollTribal.wav
2113 -- Sound\\interface\\AuctionWindowOpen.wav
2114 PlaySoundFile("Sound\\Doodad\\BellTollTribal.wav");
2115 Dcr_SoundPlayed = true;
2116 end
2117 end
2118  
2119 local Dcr_timeLeft = 0;
2120 function Dcr_AfflictedListFrame_OnUpdate(elapsed)
2121  
2122  
2123 -- XXX find the use of this block
2124 if Dcr_Saved.Amount_Of_Afflicted < 1 then
2125 Dcr_Saved.Amount_Of_Afflicted = 1;
2126 elseif Dcr_Saved.Amount_Of_Afflicted > DCR_MAX_LIVE_SLOTS then
2127 Dcr_Saved.Amount_Of_Afflicted = DCR_MAX_LIVE_SLOTS;
2128 end
2129  
2130 Dcr_timeLeft = Dcr_timeLeft - elapsed;
2131 if (Dcr_timeLeft <= 0) then
2132 Dcr_timeLeft = Dcr_Saved.ScanTime;
2133 local index = 1;
2134 local Dcr_Unit_Array = Dcr_GetUnitArray();
2135  
2136 if (DCR_CAN_CURE_ENEMY_MAGIC) then
2137 for _, unit in Dcr_Unit_Array do
2138 if (index > Dcr_Saved.Amount_Of_Afflicted) then
2139 break;
2140 end
2141 if (UnitIsVisible(unit)) then
2142 -- if the unit is even close by
2143 if (UnitIsCharmed(unit)) then
2144 -- if the unit is mind controlled
2145 if (Dcr_ScanUnit(unit, index)) then
2146 if (index == 1) then
2147 Dcr_PlaySound();
2148 end
2149 index = index + 1;
2150 end
2151 end
2152 end
2153 end
2154 end
2155  
2156 -- Dcr_debug(" normal loop");
2157 for _, unit in Dcr_Unit_Array do
2158 if (index > Dcr_Saved.Amount_Of_Afflicted) then
2159 break;
2160 end
2161 if (UnitIsVisible(unit)) then
2162 if (not UnitIsCharmed(unit)) then
2163 -- if the unit is even close by
2164 if (Dcr_ScanUnit(unit, index)) then
2165 if (index == 1) then
2166 Dcr_PlaySound();
2167 end
2168 index = index + 1;
2169 end
2170 end
2171 end
2172 end
2173  
2174 for i = index, DCR_MAX_LIVE_SLOTS do
2175 if i == 1 then
2176 Dcr_SoundPlayed = false;
2177 end
2178 local item = getglobal("DecursiveAfflictedListFrameListItem"..i);
2179 item.unit = "player";
2180 item.debuff = 0;
2181 item:Hide();
2182 end
2183  
2184 -- for testing only
2185 -- Dcr_UpdateLiveDisplay( 1, "player", 1)
2186  
2187 end
2188 end
2189  
2190 function Dcr_ScanUnit( Unit, Index)
2191 local i = 1;
2192 while (UnitDebuff(Unit, i)) do
2193  
2194 local debuff_name, debuff_type = Dcr_GetUnitDebuff(Unit, i);
2195  
2196 if (debuff_name ~= "") then
2197  
2198 -- test if we have to ignore this debuf {{{ --
2199 if (DCR_IGNORELIST[debuff_name]) then
2200 -- these are the BAD ones... the ones that make the target immune... abort the user
2201 Dcr_debug( string.gsub( string.gsub(DCR_IGNORE_STRING, "$t", UnitName(Unit)), "$a", debuff_name));
2202 return false;
2203 end
2204  
2205 if (DCR_SKIP_LIST[debuff_name]) then
2206 -- these are just ones you don't care about
2207 Dcr_debug( string.gsub( string.gsub(DCR_IGNORE_STRING, "$t", UnitName(Unit)), "$a", debuff_name));
2208 break;
2209 end
2210 if (UnitAffectingCombat("player")) then
2211 if (DCR_SKIP_BY_CLASS_LIST[UClass]) then
2212 if (DCR_SKIP_BY_CLASS_LIST[UClass][debuff_name]) then
2213 -- these are just ones you don't care about by class
2214 Dcr_debug( string.gsub( string.gsub(DCR_IGNORE_STRING, "$t", UnitName(Unit)), "$a", debuff_name));
2215 break;
2216 end
2217 end
2218 end
2219 -- }}}
2220  
2221 if (debuff_type and debuff_type ~= "") then
2222 -- // {{{ --
2223 if (debuff_type == DCR_MAGIC) then
2224 if (UnitIsCharmed(Unit)) then
2225 if (DCR_CAN_CURE_ENEMY_MAGIC) then
2226 Dcr_UpdateLiveDisplay(Index, Unit, i);
2227 return true;
2228 end
2229 else
2230 if (DCR_CAN_CURE_MAGIC) then
2231 Dcr_UpdateLiveDisplay(Index, Unit, i);
2232 return true;
2233 end
2234 end
2235 elseif (debuff_type == DCR_DISEASE) then
2236 if (DCR_CAN_CURE_DISEASE) then
2237 Dcr_UpdateLiveDisplay(Index, Unit, i);
2238 return true;
2239 end
2240 elseif (debuff_type == DCR_POISON) then
2241 if (DCR_CAN_CURE_POISON) then
2242 Dcr_UpdateLiveDisplay(Index, Unit, i);
2243 return true;
2244 end
2245 elseif (debuff_type == DCR_CURSE) then
2246 if (DCR_CAN_CURE_CURSE) then
2247 Dcr_UpdateLiveDisplay(Index, Unit, i);
2248 return true;
2249 end
2250 end
2251 -- // }}}
2252 end
2253  
2254 end -- end of if (debuff_name ~= "")
2255  
2256 i = i + 1;
2257 end
2258 return false;
2259 end
2260  
2261 function Dcr_UpdateLiveDisplay( Index, Unit, DebuffIndex)
2262 local item = getglobal("DecursiveAfflictedListFrameListItem"..Index);
2263 item.unit = Unit;
2264 item.debuff = DebuffIndex;
2265 item.UpdateMe = true;
2266 item:Show();
2267  
2268 item = getglobal("DecursiveAfflictedListFrameListItem"..Index.."Debuff");
2269 item.unit = Unit;
2270 item.debuff = DebuffIndex;
2271  
2272 item = getglobal("DecursiveAfflictedListFrameListItem"..Index.."ClickMe");
2273 item.unit = Unit;
2274 item.debuff = DebuffIndex;
2275 end
2276  
2277 function Dcr_AmountOfAfflictedSlider_OnShow()
2278 getglobal(this:GetName().."High"):SetText("15");
2279 getglobal(this:GetName().."Low"):SetText("5");
2280  
2281 getglobal(this:GetName() .. "Text"):SetText(DCR_AMOUNT_AFFLIC .. Dcr_Saved.Amount_Of_Afflicted);
2282  
2283 this:SetMinMaxValues(1, 15);
2284 this:SetValueStep(1);
2285 this:SetValue(Dcr_Saved.Amount_Of_Afflicted);
2286 end
2287  
2288 function Dcr_AmountOfAfflictedSlider_OnValueChanged()
2289 Dcr_Saved.Amount_Of_Afflicted = this:GetValue();
2290 getglobal(this:GetName() .. "Text"):SetText(DCR_AMOUNT_AFFLIC .. Dcr_Saved.Amount_Of_Afflicted);
2291 end
2292  
2293 function Dcr_CureBlacklistSlider_OnShow()
2294 getglobal(this:GetName().."High"):SetText("20");
2295 getglobal(this:GetName().."Low"):SetText("1");
2296  
2297 getglobal(this:GetName() .. "Text"):SetText(DCR_BLACK_LENGTH .. Dcr_Saved.CureBlacklist);
2298  
2299 this:SetMinMaxValues(1, 20);
2300 this:SetValueStep(0.1);
2301 this:SetValue(Dcr_Saved.CureBlacklist);
2302 end
2303  
2304 function Dcr_CureBlacklistSlider_OnValueChanged()
2305 Dcr_Saved.CureBlacklist = this:GetValue() * 10;
2306 if (Dcr_Saved.CureBlacklist < 0) then
2307 Dcr_Saved.CureBlacklist = ceil(Dcr_Saved.CureBlacklist - 0.5)
2308 else
2309 Dcr_Saved.CureBlacklist = floor(Dcr_Saved.CureBlacklist + 0.5)
2310 end
2311 Dcr_Saved.CureBlacklist = Dcr_Saved.CureBlacklist / 10;
2312 getglobal(this:GetName() .. "Text"):SetText(DCR_BLACK_LENGTH .. Dcr_Saved.CureBlacklist);
2313 end
2314  
2315 function Dcr_ScanTimeSlider_OnShow()
2316 getglobal(this:GetName().."High"):SetText("1");
2317 getglobal(this:GetName().."Low"):SetText("0.1");
2318  
2319 getglobal(this:GetName() .. "Text"):SetText(DCR_SCAN_LENGTH .. Dcr_Saved.ScanTime);
2320  
2321 this:SetMinMaxValues(0.1, 1);
2322 this:SetValueStep(0.1);
2323 this:SetValue(Dcr_Saved.ScanTime);
2324 end
2325  
2326 function Dcr_ScanTimeSlider_OnValueChanged()
2327 Dcr_Saved.ScanTime = this:GetValue() * 10;
2328 if (Dcr_Saved.ScanTime < 0) then
2329 Dcr_Saved.ScanTime = ceil(Dcr_Saved.ScanTime - 0.5)
2330 else
2331 Dcr_Saved.ScanTime = floor(Dcr_Saved.ScanTime + 0.5)
2332 end
2333 Dcr_Saved.ScanTime = Dcr_Saved.ScanTime / 10;
2334 getglobal(this:GetName() .. "Text"):SetText(DCR_SCAN_LENGTH .. Dcr_Saved.ScanTime);
2335 end