-
Notifications
You must be signed in to change notification settings - Fork 8
/
Necrosis-cata.lua
3248 lines (2849 loc) · 123 KB
/
Necrosis-cata.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
--[[
Necrosis
Copyright (C) - copyright file included in this release
--]]
local L = LibStub("AceLocale-3.0"):GetLocale(NECROSIS_ID, true)
-- Local variables || Variables locales
local Local = {}
local _G = getfenv(0)
local NU = Necrosis.Utils -- save typing
------------------------------------------------------------------------------------------------------
-- LOCAL FUNCTIONS || FONCTIONS LOCALES
------------------------------------------------------------------------------------------------------
-- Creating two functions, new and del || Création de deux fonctions, new et del
-- New creates a temporary array, del destroys it || new crée un tableau temporaire, del le détruit
-- These temporary tables are stored for reuse without having to recreate them. || Ces tableaux temporaires sont stockés pour être réutilisés sans être obligés de les recréer.
local new, del
do
local cache = setmetatable({}, {__mode='k'})
function new(populate, ...)
local tbl
local t = next(cache)
if ( t ) then
cache[t] = nil
tbl = t
else
tbl = {}
end
if ( populate ) then
local num = select("#", ...)
if ( populate == "hash" ) then
assert(math.fmod(num, 2) == 0)
local key
for i = 1, num do
local v = select(i, ...)
if not ( math.fmod(i, 2) == 0 ) then
key = v
else
tbl[key] = v
key = nil
end
end
elseif ( populate == "array" ) then
for i = 1, num do
local v = select(i, ...)
table.insert(tbl, i, v)
end
end
end
return tbl
end
function del(t)
for k in next, t do
t[k] = nil
end
cache[t] = true
end
end
-- Define a metatable which will be applied to any table object that uses it. || Métatable permettant d'utiliser les tableaux qui l'utilisent comme des objets
-- Common functions = :insert, :remove & :sort || Je définis les opérations :insert, :remove et :sort
-- Any table declared as follows "a = setmetatable({}, metatable)" will be able to use the common functions. || Tout tableau qui aura pour déclaration a = setmetatable({}, metatable) pourra utiliser ces opérateurs
local metatable = {
__index = {
["insert"] = table.insert,
["remove"] = table.remove,
["sort"] = table.sort,
}
}
-- Create the spell metatable. || Création de la métatable contenant les sorts de nécrosis
Necrosis.Spell = setmetatable({}, metatable)
------------------------------------------------------------------------------------------------------
-- DECLARATION OF VARIABLES || DÉCLARATION DES VARIABLES
------------------------------------------------------------------------------------------------------
-- Detection of initialisation || Détection des initialisations du mod
Local.LoggedIn = true
Local.InWorld = false -- as addon id loaded / parsed
-- Configuration defaults || Configuration par défaut
-- To be used if the configuration savedvariables is missing, or if the NecrosisConfig.Version number is changed. || Se charge en cas d'absence de configuration ou de changement de version
Local.DefaultConfig = {
AFK = true,
SoulshardContainer = 4,
ShadowTranceAlert = true,
ShowSpellTimers = true,
AntiFearAlert = true,
CreatureAlert = true,
NecrosisAlphaBar = 85,
NecrosisLockServ = true,
NecrosisAngle = 180,
StonePosition = {1, 2, 3, 4, 5, 6, 7 }, -- options to show or hide
-- 3 = Healthstone
-- 4 = Soulstone
-- 5 = Buff menu
-- 6 = Mounts
-- 7 = Demon menu
-- 8 = Curse menu
-- 9 = Soul Harvest
DemonSpellPosition = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
-- 1 = Fel Domination || Domination corrompue
-- 2 = Summon Imp
-- 3 = Summon Voidwalker || Marcheur
-- 4 = Summon Succubus
-- 5 = Summon Felhunter
-- 6 = Felguard || Gangregarde<<
-- 7 = Infernal
-- 8 = Doomguard
-- 9 = Enslave || Asservissement
-- 10 = Sacrifice
-- 11 = Demonic Empowerment || Renforcement
BuffSpellPosition = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
-- 1 = Demon Armor || Armure
-- 2 = Fel Armor || Gangrarmure
-- 3 = Unending Breath || Respiration
-- 4 = Detect Invisibility || Invisibilité
-- 5 = Eye of Kilrogg
-- 6 = Ritual of Summoning || TP
-- 7 = Soul Link || Lien Spirituel
-- 8 = Shadow Ward || Protection contre l'ombre
-- 9 = Demonic Empowerment || Renforcement démoniaque --
-- 10 = Banish || Bannir
NecrosisToolTip = true,
MainSpell = "soul_harvest",
PetMenuPos = {x=1, y=0, direction=1},
PetMenuDecalage = {x=1, y=26},
BuffMenuPos = {x=1, y=0, direction=1},
BuffMenuDecalage = {x=1, y=26},
CurseMenuPos = {x=1, y=0, direction=1},
CurseMenuDecalage = {x=1, y=-26},
ChatMsg = true,
ChatType = true,
Language = GetLocale(),
ShowCount = true,
CountType = 1,
DestroyShardwithsphere = false,
ShadowTranceScale = 100,
NecrosisButtonScale = 90,
NecroisButtonRadius = 1,
NecrosisColor = "Cata",
Sound = true,
SpellTimerPos = 1,
SpellTimerJust = "LEFT",
Circle = 1,
TimerType = 1,
SensListe = 1,
PetName = {},
DemonSummon = true,
BanishScale = 100,
ItemSwitchCombat = {},
DestroyCount = 3,
FramePosition = {
["NecrosisSpellTimerButton"] = {"CENTER", "UIParent", "CENTER", 100, 300},
["NecrosisButton"] = {"CENTER", "UIParent", "CENTER", 0, -200},
["NecrosisCreatureAlertButton_elemental"] = {"CENTER", "UIParent", "CENTER", -60, 0},
["NecrosisCreatureAlertButton_demon"] = {"CENTER", "UIParent", "CENTER", -50, 0},
["NecrosisAntiFearButton"] = {"CENTER", "UIParent", "CENTER", -20, 0},
["NecrosisShadowTranceButton"] = {"CENTER", "UIParent", "CENTER", 20, 0},
["NecrosisBacklashButton"] = {"CENTER", "UIParent", "CENTER", 60, 0},
["NecrosisFirestoneButton"] = {"CENTER", "UIParent", "CENTER", -121,-100},
["NecrosisSpellstoneButton"] = {"CENTER", "UIParent", "CENTER", -87,-100},
["NecrosisHealthstoneButton"] = {"CENTER", "UIParent", "CENTER", -53,-100},
["NecrosisSoulstoneButton"] = {"CENTER", "UIParent", "CENTER", -17,-100},
["NecrosisBuffMenuButton"] = {"CENTER", "UIParent", "CENTER", 17,-100},
["NecrosisMountButton"] = {"CENTER", "UIParent", "CENTER", 53,-100},
["NecrosisPetMenuButton"] = {"CENTER", "UIParent", "CENTER", 87,-100},
["NecrosisCurseMenuButton"] = {"CENTER", "UIParent", "CENTER", 121,-100},
["NecrosisDestroyShardsButton"] = {"CENTER", "UIParent", "CENTER", 154,-100},
},
PetShow = {true,true,true,true,true,true,true,true,true,},
CurseShow = {true,true,true,true,true,true,true,true,},
Timers = { -- Order is for options screen; overrides Warlock_Spells Timer
[1] = {usage = "breath", show = true},
[2] = {usage = "eye", show = false},
[3] = {usage = "summoning", show = true},
[4] = {usage = "ward", show = true},
[5] = {usage = "banish", show = true},
[6] = {usage = "enslave", show = true},
[7] = {usage = "soulburn", show = true},
[8] = {usage = "soulshatter", show = true},
},
}
-- Casted spell variables (name, rank, target, target level) || Variables des sorts castés (nom, rang, cible, niveau de la cible)
Local.SpellCasted = {}
-- Timers variables || Variables des timers
Local.TimerManagement = {
-- Spells to timer || Sorts à timer
SpellTimer = setmetatable({}, metatable),
-- Association of timers to Frames || Association des timers aux Frames
TimerTable = setmetatable({}, metatable),
-- Groups of timers by mobs || Groupes de timers par mobs
SpellGroup = setmetatable(
{
{Name = "Rez", SubName = " ", Visible = 0},
{Name = "Main", SubName = " ", Visible = 0},
{Name = "Cooldown", SubName = " ", Visible = 0}
},
metatable
),
-- Last cast spell || Dernier sort casté
LastSpell = {}
}
Necrosis.TimerManagement = Local.TimerManagement -- debug
-- Variables of the invocation messages || Variables des messages d'invocation
Local.SpeechManagement = {
-- Latest messages selected || Derniers messages sélectionnés
-- Added 'RoS = 0' by Draven (April 3rd, 2008) || Added 'RoS = 0' by Draven (April 3rd, 2008)
LastSpeech = {Pet = 0, Steed = 0, Rez = 0, TP = 0, RoS = 0},
-- Messages to use after the spell succeeds || Messages à utiliser après la réussite du sort
SpellSucceed = {
-- Added 'RoS = setmetatable ({}, metatable),' by Draven (April 3rd, 2008) || Added 'RoS = setmetatable({}, metatable),' by Draven (April 3rd, 2008)
RoS = setmetatable({}, metatable),
Pet = setmetatable({}, metatable),
Steed = setmetatable({}, metatable),
Rez = setmetatable({}, metatable),
TP = setmetatable({}, metatable),
Sacrifice = setmetatable({}, metatable)
},
}
Necrosis.XXYYZZ = Local.SpeechManagement -- debug
-- Variables used for managing summoning and stone buttons || Variables utilisées pour la gestion des boutons d'invocation et d'utilisation des pierres
Local.Stone = {
Soul = {Mode = 1, Location = {}},
Health = {Mode = 1, Location = {}},
Spell = {Mode = 1, Location = {}},
Hearth = {Location = {}},
Fire = {Mode = 1},
}
Local.SomethingOnHand = "Truc"
-- Component count variable || Variable de comptage des composants
Local.Reagent = {Infernal = 0, Demoniac = 0}
-- Variables used in demon management || Variables utilisées dans la gestion des démons
Local.Summon = {}
-- List of buttons available in each menu || Liste des boutons disponibles dans chaque menu
Local.Menu = {
Pet = setmetatable({}, metatable),
Buff = setmetatable({}, metatable),
Curse = setmetatable({}, metatable)
}
-- Active Buffs Variable || Variable des Buffs Actifs
Local.BuffActif = {}
-- Variable of the state of the buttons (grayed or not) || Variable de l'état des boutons (grisés ou non)
Local.Desatured = {}
-- Last image used for the sphere || Dernière image utilisée pour la sphere
Local.LastSphereSkin = "Aucune"
-- Variables of care stone exchanges || Variables des échanges de pierres de soins
Local.Trade = {}
-- Variables used for the management of soul fragments || Variables utilisées pour la gestion des fragments d'âme
Local.Soulshard = {Count = 0, Move = 0}
Local.BagIsSoulPouch = {}
-- Variables used for warnings || Variables utilisées pour les avertissements
-- Antifear and Demonic or Elemental Target || Antifear et Cible démoniaque ou élémentaire
Local.Warning = {
Antifear = {
Toggle = 2,
Icon = {"", "Immu", "Prot"}
}
}
-- Time elapsed between two OnUpdate events || Temps écoulé entre deux event OnUpdate
Local.LastUpdate = {0, 0}
-- Use these to get buffs via OnUpdate on init
Local.buff_needed = false
Local.buff_attempts = 0
LocalZZYY = Local
------------------------------------------------------------------------------------------------------
-- NECROSIS helper routines
------------------------------------------------------------------------------------------------------
local function BagNamesKnown()
local res = true
for container = 0, NUM_BAG_SLOTS, 1 do
local name, id = NU.GetBagName(container)
if name then
-- bag name is in cache
else
res = false
break
end
end
return res
end
-- Function to check the presence of a buff on the unit.
-- Strictly identical to UnitHasEffect, but as WoW distinguishes Buff and DeBuff, so we have to.
local function UnitHasBuff(unit, effect)
-- print(("%d=%s, %s, %.2f minutes left."):format(i,name,icon,(etime-GetTime())/60))
local res = false
for i=1,40 do
local name, icon, count, debuffType, duration,
expirationTime, source, isStealable, nameplateShowPersonal, spellId,
canApplyAura, isBossDebuff, castByPlayer, nameplateShowAll, timeMod
= UnitBuff(unit,i)
if name then
if name == effect then
res = true
break
else
-- continue
end
else
break -- no more
end
end
return res
end
-- Function to check the presence of a debuff on the unit || Fonction pour savoir si une unité subit un effet
-- F(string, string)->bool
local function UnitHasEffect(unit, effect)
local res = false
for i=1,40 do
local name, icon, count, debuffType, duration,
expirationTime, source, isStealable, nameplateShowPersonal, spellId,
canApplyAura, isBossDebuff, castByPlayer, nameplateShowAll, timeMod
= UnitDebuff(unit,i)
if name then
if name == effect then
res = true
break
else
-- continue
end
else
break -- no more
end
end
return res
end
-- Display the antifear button / warning || Affiche ou cache le bouton de détection de la peur suivant la cible.
local function ShowAntiFearWarning()
local Actif = false -- Must be False, or a number from 1 to Local.Warning.Antifear.Icon[] max element.
-- Checking if we have a target. Any fear need a target to be casted on
if UnitExists("target") and UnitCanAttack("player", "target") and not UnitIsDead("target") then
-- Checking if the target has natural immunity (only NPC target)
if not UnitIsPlayer("target") and ( UnitCreatureType("target") == Necrosis.Unit.Undead or UnitCreatureType("target") == "Mechanical" ) then
Actif = 2 -- Immun
end
-- We'll start to parse the target buffs, as his class doesn't give him natural permanent immunity
if not Actif then
for index=1, #Necrosis.AntiFear.Buff, 1 do
if UnitHasBuff("target",Necrosis.AntiFear.Buff[index]) then
Actif = 3 -- Prot
break
end
end
-- No buff found, let's try the debuffs
for index=1, #Necrosis.AntiFear.Debuff, 1 do
if UnitHasEffect("target",Necrosis.AntiFear.Debuff[index]) then
Actif = 3 -- Prot
break
end
end
end
-- An immunity has been detected before, but we still don't know why => show the button anyway
if Local.Warning.Antifear.Immune and not Actif then
Actif = 1
end
end
if Actif then
-- Antifear button is currently not visible, we have to change that
if not Local.Warning.Antifear.Actif then
Local.Warning.Antifear.Actif = true
Necrosis:Msg(Necrosis.ChatMessage.Information.FearProtect, "USER")
NecrosisAntiFearButton:SetNormalTexture("Interface\\Addons\\Necrosis\\UI\\AntiFear"..Local.Warning.Antifear.Icon[Actif].."-02")
if NecrosisConfig.Sound then PlaySoundFile(Necrosis.Sound.Fear) end
-- ShowUIPanel(NecrosisAntiFearButton)
NecrosisAntiFearButton:Show()
Local.Warning.Antifear.Blink = GetTime() + 0.6
Local.Warning.Antifear.Toggle = 2
-- Timer to make the button blink
elseif GetTime() >= Local.Warning.Antifear.Blink then
if Local.Warning.Antifear.Toggle == 1 then
Local.Warning.Antifear.Toggle = 2
else
Local.Warning.Antifear.Toggle = 1
end
Local.Warning.Antifear.Blink = GetTime() + 0.4
NecrosisAntiFearButton:SetNormalTexture("Interface\\Addons\\Necrosis\\UI\\AntiFear"..Local.Warning.Antifear.Icon[Actif].."-0"..Local.Warning.Antifear.Toggle)
end
elseif Local.Warning.Antifear.Actif then -- No antifear on target, but the button is still visible => gonna hide it
Local.Warning.Antifear.Actif = false
-- HideUIPanel(NecrosisAntiFearButton)
NecrosisAntiFearButton:Hide()
end
end
-- Function updating the buttons Necrosis and giving the state of the button of the soul stone || Fonction mettant à jour les boutons Necrosis et donnant l'état du bouton de la pierre d'âme
function UpdateIcons()
-- Soul Stone || Pierre d'âme
-----------------------------------------------
-- We inquire to know if a stone of soul was used -> verification in the timers || On se renseigne pour savoir si une pierre d'âme a été utilisée --> vérification dans les timers
local SoulstoneInUse = false
if Local.TimerManagement.SpellTimer then
for index = 1, #Local.TimerManagement.SpellTimer, 1 do
--print(Local.TimerManagement.SpellTimer[index].Name)
if Local.TimerManagement.SpellTimer[index].Name == Necrosis.GetSpellName("soulstone")
and Local.TimerManagement.SpellTimer[index].TimeMax > 0 then
SoulstoneInUse = true
break
end
end
end
-- If the stone was not used, and there is no stone in inventory -> Mode 1 || Si la Pierre n'a pas été utilisée, et qu'il n'y a pas de pierre en inventaire -> Mode 1
if not (Local.Stone.Soul.OnHand or SoulstoneInUse) then
--print ("mode1")
Local.Stone.Soul.Mode = 1
end
-- If the stone was not used, but there is a stone in inventory || Si la Pierre n'a pas été utilisée, mais qu'il y a une pierre en inventaire
--[[On Hand In Use
1 : no no
2 : yes no
3 : no yes
4 : yes yes
--]]
if Local.Stone.Soul.OnHand and (not SoulstoneInUse) then
-- If the stone in inventory contains a timer, and we leave a RL -> Mode 4 || Si la pierre en inventaire contient un timer, et qu'on sort d'un RL --> Mode 4
local start, duration = C_Container.GetContainerItemCooldown(Local.Stone.Soul.Location[1],Local.Stone.Soul.Location[2])
if Necrosis.Debug.timers then
_G["DEFAULT_CHAT_FRAME"]:AddMessage("UpdateIcons - soul stone found"
.." s'"..tostring(start or "nyl").."'"
.." d'"..tostring(duration or "nyl").."'"
.." l1'"..tostring(Local.Stone.Soul.Location[1] or "nyl").."'"
.." l2'"..tostring(Local.Stone.Soul.Location[2] or "nyl").."'"
)
end
if start > 0 and duration > 0 then
--[[ This situation is after a stone is used and another is created.
The timer is on USING a soul stone, not the stone itself.
So use the lowest soul stone 'resurrection' spell the warlock can learn just for the timer.
Take advantage that the various 'resurrection' spells share the same localized name AND the same cool down time.
From the id, WoW knows the health and mana to give if the soul stone is used.
Note: WoW will only allow one soul stone at a time so we do not have to worry about multiple stones...
Note: The target guid (below) must match the cool down setting in Functions.lua or two timers could be spawned.
--]]
if Local.Stone.Soul.Timer == true then
else
local spell = Necrosis.GetSpellById(20707)
local cast_info = {}
cast_info = {
usage = spell.Usage,
spell_id = 20707,
guid = nil,
}
local target = {}
target = {
name = "",
lvl = "",
guid = "",
}
Local.TimerManagement = Necrosis:TimerInsert(cast_info, target, Local.TimerManagement, "soul stone in inventory cool down", start, duration, spell.Cooldown)
Local.Stone.Soul.Mode = 4
Local.Stone.Soul.Timer = true
end
-- If the stone does not contain a timer, or you do not leave an RL -> Mode 2 || Si la pierre ne contient pas de timer, ou qu'on ne sort pas d'un RL --> Mode 2
else
Local.Stone.Soul.Mode = 2
end
else
if Local.Stone.Soul.Timer == true then
Local.Stone.Soul.Timer = false
local spell = Necrosis.GetSpell("minor_ss_used")
Necrosis:RetraitTimerParNom(spell.Name, Local.TimerManagement, "No soul stone...")
end
end
-- If the stone was used but there is no stone in inventory -> Mode 3 || Si la Pierre a été utilisée mais qu'il n'y a pas de pierre en inventaire --> Mode 3
if (not Local.Stone.Soul.OnHand) and SoulstoneInUse then
Local.Stone.Soul.Mode = 3
end
-- If the stone was used and there is a stone in inventory || Si la Pierre a été utilisée et qu'il y a une pierre en inventaire
if Local.Stone.Soul.OnHand and SoulstoneInUse then
Local.Stone.Soul.Mode = 4
end
--[[
-- If out of combat and we can create a stone, we associate the left button to create a stone. || Si hors combat et qu'on peut créer une pierre, on associe le bouton gauche à créer une pierre.
if Necrosis.IsSpellKnown("soulstone")
and NecrosisConfig.ItemSwitchCombat[4]
and (Local.Stone.Soul.Mode == 1 or Local.Stone.Soul.Mode == 3)
then
Necrosis:SoulstoneUpdateAttribute(Local.Stone.Soul.Mode)
end
--]]
local stone_exists = (Local.Stone.Soul.Mode == 1 or Local.Stone.Soul.Mode == 3) and true or false
Necrosis:SoulstoneUpdateAttribute(stone_exists)
-- Display of the mode icon || Affichage de l'icone liée au mode
local f = _G[Necrosis.Warlock_Buttons.soul_stone.f]
if f then
f:SetNormalTexture("Interface\\AddOns\\Necrosis\\UI\\SoulstoneButton-0"..Local.Stone.Soul.Mode)
end
-- Stone of life || Pierre de vie
-----------------------------------------------
-- Mode "I have one" (2) / "I have none" (1) || Mode "j'en ai une" (2) / "j'en ai pas" (1)
if (Local.Stone.Health.OnHand) then
Local.Stone.Health.Mode = 2
else
Local.Stone.Health.Mode = 1
-- If out of combat and we can create a stone, we associate the left button to create a stone. || Si hors combat et qu'on peut créer une pierre, on associe le bouton gauche à créer une pierre.
if Necrosis.IsSpellKnown("healthstone")
and NecrosisConfig.ItemSwitchCombat[3] then
Necrosis:HealthstoneUpdateAttribute("NoStone")
end
end
--Display of the mode icon || Affichage de l'icone liée au mode
local f = _G[Necrosis.Warlock_Buttons.health_stone.f]
if f then
f:SetNormalTexture("Interface\\AddOns\\Necrosis\\UI\\HealthstoneButton-0"..Local.Stone.Health.Mode)
end
-- Stone of spell || Pierre de sort
-----------------------------------------------
-- Stone in the inventory ... || Pierre dans l'inventaire...
if Local.Stone.Spell.OnHand then
-- ... and on the weapon = mode 3, otherwise = mode 2 || ... et sur l'arme = mode 3, sinon = mode 2
if Local.SomethingOnHand == NecrosisConfig.ItemSwitchCombat[1] then
Local.Stone.Spell.Mode = 3
else
Local.Stone.Spell.Mode = 2
end
-- Stone nonexistent ... || Pierre inexistante...
else
-- ... but on the weapon = mode 4, otherwise = mode 1 || ... mais sur l'arme = mode 4, sinon = mode 1
if Local.SomethingOnHand == NecrosisConfig.ItemSwitchCombat[1] then
Local.Stone.Spell.Mode = 4
else
Local.Stone.Spell.Mode = 1
end
-- If out of combat and we can create a stone, we associate the left button to create a stone. || Si hors combat et qu'on peut créer une pierre, on associe le bouton gauche à créer une pierre.
if Necrosis.IsSpellKnown("spellstone")
and NecrosisConfig.ItemSwitchCombat[3] then
Necrosis:SpellstoneUpdateAttribute("NoStone")
end
end
end
-- Event : UNIT_SPELLCAST_SUCCEEDED
-- Manages everything related to successful spell casts || Permet de gérer tout ce qui touche aux sorts une fois leur incantation réussie
function SpellManagement(SpellCasted)
local SortActif = false
local cast_spell = SpellCasted
if (cast_spell.Name) then
-- Messages Posts Cast (Démons et TP)
Local.SpeechManagement.SpellSucceed = Necrosis:Speech_Then(cast_spell, Local.SpeechManagement)
-- Handle any timers on cast spells
local spell = Necrosis.GetSpellById(cast_spell.Id)
if spell.Buff then
-- Handled by the aura events
elseif spell.Timer then
local target = {}
--[[
if cast_spell.TargetName == UnitName("player") then
cast_spell.TargetName = ""
cast_spell.TargetGUID = ""
target = {
name = "",
lvl = cast_spell.TargetLevel,
guid = "",
}
else
--]]
target = {
name = cast_spell.TargetName,
lvl = cast_spell.TargetLevel,
guid = cast_spell.TargetGUID,
}
-- end
local cast_info = {}
local spell = Necrosis.GetSpellById(cast_spell.Id)
cast_info = {
usage = spell.Usage,
spell_id = cast_spell.Id,
guid = cast_spell.Guid,
}
if Necrosis.Debug.spells_cast then
_G["DEFAULT_CHAT_FRAME"]:AddMessage("SpellManagement"
.." s'"..tostring(cast_spell.Name or "nyl").."'"
.." u'"..tostring(cast_info.usage or "nyl").."'"
.." tn'"..tostring(target.name or "nyl").."'"
.." tl'"..tostring(target.lvl or "nyl").."'"
.." tg'"..tostring(target.guid or "nyl").."'"
)
end
--print (spell.Usage,cast_spell.Id,cast_spell.Guid)
--print (cast_spell.TargetName,cast_spell.TargetLevel,cast_spell.TargetGUID)
--print (cast_spell.TargetName,cast_spell.TargetLevel,cast_spell.TargetGUID)
Local.TimerManagement = Necrosis:TimerInsert(cast_info, target, Local.TimerManagement, "spell cast")
--print (spell.Usage,cast_spell.Id,cast_spell.Guid)
end
end
return
end
function CheckCorruptionRefresh(target, cast_guid, spell_id)
-- On verifie si la corruption doit etre refresh , si le talent(Afflication eternelle) est appris, a la suite de SB ou hanter le timer de la corru est réinitialisé
local guid = UnitGUID("target")
local name = select(1, GetSpellInfo(spell_id))
if not target or not guid or target == "Player" or not Necrosis.GetSpellById(spell_id) then
-- nothing to do
return nil
elseif Necrosis.Warlock_Spells[spell_id].Usage == "bolt" or Necrosis.Warlock_Spells[spell_id].Usage == "haunt" then-- Trait de l'ombre ou Hanter
--print (guid, cast_guid, spell_id , name, Necrosis.Warlock_Spells[spell_id].Usage)
for i=1,40 do
local NameDebuff, _, _, _, _,expirationTime = UnitAura("target", i, "PLAYER|HARMFUL")
--On verifie que sur la cible on a bien corruption
if NameDebuff == Necrosis.GetSpellName("corruption") then
for index = 1, #Local.TimerManagement.SpellTimer, 1 do
-- On recherche dans la table des Timer la corruption correspondante à la cible
--if Local.TimerManagement.SpellTimer[index] then
--print(Necrosis.TimerManagement.SpellTimer[index].Name,NameDebuff,Necrosis.TimerManagement.SpellTimer[index].TargetGUID,UnitGUID("target"))
if Necrosis.TimerManagement.SpellTimer[index].Name == NameDebuff and Necrosis.TimerManagement.SpellTimer[index].TargetGUID == UnitGUID("target") then
-- On delete le timer actuel pour le remplacer
Necrosis:RetraitTimerParIndex(index, Local.TimerManagement, "spell expired")
--print ("spell deleted",index)
-- On rajoute une Corruption avec un timer refresh
SpellManagement(Local.SpellCasted[cast_guid])
Necrosis.GetSpellName("corruption")
local spell = Necrosis.GetSpellById(Necrosis.GetSpell("corruption").ID)
local cast_info = {}
cast_info = {
usage = "corruption",
spell_id = Necrosis.GetSpell("corruption").ID,
guid = cast_guid,
}
target = {
name = UnitName("Target"),--
lvl = UnitLevel("Target"),
guid = UnitGUID("Target")
}
--Local.TimerManagement = Necrosis:TimerInsert(cast_info, target, Necrosis.TimerManagement, "spell cast")
Local.TimerManagement = Necrosis:TimerInsert(cast_info, target, Local.TimerManagement, "spell cast")
SpellManagement(Local.SpellCasted[cast_guid])
end
--end
end
end
end
end
end
-- Events : CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS, CHAT_MSG_SPELL_AURA_GONE_SELF et CHAT_MSG_SPELL_BREAK_AURA
-- Manage the appearing and disappearing effects on the warlock || Permet de gérer les effets apparaissants et disparaissants sur le démoniste
-- Based on CombatLog || Basé sur le CombatLog
function SelfEffect(action, nom)
--print (action, nom)
if NecrosisConfig.LeftMount then
local NomCheval1 = GetSpellInfo(NecrosisConfig.LeftMount)
else
local NomCheval1 = Necrosis.Warlock_Spells[23161].Name -- Pallefroi 100 %
end
if NecrosisConfig.RightMount then
local NomCheval2 = GetSpellInfo(NecrosisConfig.RightMount)
else
local NomCheval2 = Necrosis.Warlock_Spells[5784].Name -- Pallefroi 60%
end
local f = _G[Necrosis.Warlock_Buttons.mounts.f]
if action == "BUFF" then
--print (nom)
local fs = _G[Necrosis.Warlock_Buttons.trance.f]
local fb = _G[Necrosis.Warlock_Buttons.backlash.f]
-- Changing the mount button when the Warlock is disassembled || Changement du bouton de monture quand le Démoniste est démonté
if nom == Necrosis.Warlock_Spells[5784].Name or nom == Necrosis.Warlock_Spells[23161].Name or nom == "NomCheval1" or nom == "NomCheval2" then
Local.BuffActif.Mount = true
if f then
f:SetNormalTexture(Necrosis.Warlock_Buttons.mounts.high)
f:GetNormalTexture():SetDesaturated(nil)
end
-- Change Dominated Domination Button if Enabled + Cooldown Timer || Changement du bouton de la domination corrompue si celle-ci est activée + Timer de cooldown
elseif Necrosis.IsSpellKnown("domination")
and (nom == Necrosis.GetSpellName("domination"))
then -- 15
Local.BuffActif.Domination = true
local f = _G[Necrosis.Warlock_Buttons.domination.f]
if f then
f:SetNormalTexture(Necrosis.Warlock_Buttons.domination.high)
f:GetNormalTexture():SetDesaturated(nil)
end
-- Change the spiritual link button if it is enabled || Changement du bouton du lien spirituel si celui-ci est activé
elseif Necrosis.IsSpellKnown("link")
and (nom == Necrosis.GetSpellName("link"))
then -- 38
Local.BuffActif.SoulLink = true
local f = _G[Necrosis.Warlock_Buttons.link.f]
if f then
f:SetNormalTexture(Necrosis.Warlock_Buttons.link.high)
f:GetNormalTexture():SetDesaturated(nil)
end
-- If Backlash or MoltenCore, to display the icon and we proc the sound || si Contrecoup, pouf on affiche l'icone et on proc le son
-- If By-effect, one-on-one icon and one proc the sound || if By-effect, pouf one posts the icon and one proc the sound
elseif nom == Necrosis.Translation.Proc.Backlash or nom == select(1, GetSpellInfo(47247)) and NecrosisConfig.ShadowTranceAlert then
if nom == select(1, GetSpellInfo(47247)) then -- Motencore
--print (select(1, GetSpellInfo(47247)))
Necrosis:Msg(Necrosis.ProcText.MoltenCore, "USER")
if NecrosisConfig.Sound then PlaySound(12977) end
else
Necrosis:Msg(Necrosis.ProcText.Backlash, "USER")
if NecrosisConfig.Sound then PlaySoundFile(Necrosis.Sound.Backlash) end
end
fb:Show()
-- If Twilight, to display the icon and sound || si Crépuscule, pouf on affiche l'icone et on proc le son
-- If Twilight / Nightfall, puff one posts the icon and one proc the sound || if Twilight/Nightfall, pouf one posts the icon and one proc the sound
elseif nom == Necrosis.Translation.Proc.ShadowTrance and NecrosisConfig.ShadowTranceAlert then
Necrosis:Msg(Necrosis.ProcText.ShadowTrance, "USER")
if NecrosisConfig.Sound then PlaySoundFile(Necrosis.Sound.ShadowTrance) end
fs:Show()
end
else
-- Changing the mount button when the Warlock is dismount || Changement du bouton de monture quand le Démoniste est démonté
if nom == Necrosis.Warlock_Spells[5784].Name or nom == Necrosis.Warlock_Spells[23161].Name or nom == "NomCheval1" or nom == "NomCheval2" then
Local.BuffActif.Mount = false
if f then
f:SetNormalTexture(Necrosis.Warlock_Buttons.mounts.norm)
end
-- Domination button change when Warlock is no longer under control || Changement du bouton de Domination quand le Démoniste n'est plus sous son emprise
elseif Necrosis.IsSpellKnown("domination") -- known
and (nom == Necrosis.GetSpellName("domination"))
then -- 15
Local.BuffActif.Domination = false
local f = _G[Necrosis.Warlock_Buttons.domination.f]
if f then
f:SetNormalTexture(Necrosis.Warlock_Buttons.mounts.norm)
end
-- Changing the Spiritual Link button when the Warlock is no longer under control || Changement du bouton du Lien Spirituel quand le Démoniste n'est plus sous son emprise
elseif Necrosis.IsSpellKnown("link") -- known
and (nom == Necrosis.GetSpellName("link"))
then -- 38
Local.BuffActif.SoulLink = false
local f = _G[Necrosis.Warlock_Buttons.link.f]
if f then
f:SetNormalTexture(Necrosis.Warlock_Buttons.link.norm)
end
-- Hide the shadowtrance (nightfall) or backlash buttons when the state is ended
elseif nom == Necrosis.Translation.Proc.ShadowTrance or nom == select(1, GetSpellInfo(47247)) or nom == Necrosis.Translation.Proc.Backlash then
local fs = _G[Necrosis.Warlock_Buttons.trance.f]
local fb = _G[Necrosis.Warlock_Buttons.backlash.f]
fs:Hide()
fb:Hide()
end
end
Necrosis:UpdateMana()
return
end
------------------------------------------------------------------------------------------------------
-- NECROSIS FUNCTIONS || FONCTIONS NECROSIS
------------------------------------------------------------------------------------------------------
local function SatList(list, val)
for i, v in pairs(list) do
menuVariable = _G[Necrosis.Warlock_Buttons[v.f_ptr].f]
if menuVariable then
menuVariable:GetNormalTexture():SetDesaturated(val)
end
end
end
-- Event : UNIT_PET
-- Allows the servo to be timed, as well as to prevent for servo breaks || Permet de timer les asservissements, ainsi que de prévenir pour les ruptures d'asservissement
-- Also change the name of the pet to the replacement of it || Change également le nom du pet au remplacement de celui-ci
function Necrosis:ChangeDemon()
if Necrosis.IsSpellKnown("enslave") then -- can enslave a demon
-- If the new demon is a slave demon, we put a 5 minute timer || Si le nouveau démon est un démon asservi, on place un timer de 5 minutes
if UnitHasEffect("pet", Necrosis.GetSpellName("enslave")) then
if (not Local.Summon.DemonEnslaved) then
Local.Summon.DemonEnslaved = true
--Necrosis:Msg("ENSLAVE", "USER")
--[[ timer should have been put in place on spell cast...
--]]
end
else
-- When the enslaved demon is lost, remove the timer and warn the warlock || Quand le démon asservi est perdu, on retire le Timer et on prévient le Démoniste
if (Local.Summon.DemonEnslaved) then
Local.Summon.DemonEnslaved = false
Local.TimerManagement = Necrosis:RetraitTimerParNom(
Necrosis.GetSpellName("enslave"), -- 10
Local.TimerManagement, "enslaved demon lost")
if NecrosisConfig.Sound then PlaySoundFile(Necrosis.Sound.EnslaveEnd) end
Necrosis:Msg(Necrosis.ChatMessage.Information.EnslaveBreak, "USER")
end
end
end
-- If the demon is not enslaved we define its title, and we update its name in Necrosis || Si le démon n'est pas asservi on définit son titre, et on met à jour son nom dans Necrosis
Local.Summon.LastDemonType = Local.Summon.DemonType
Local.Summon.DemonType = UnitCreatureFamily("pet") or nil
Local.Summon.DemonId = Necrosis.Utils.ParseGUID(UnitGUID("pet")) or nil
local high = nil
for i = 1, #Necrosis.Warlock_Lists.pets, 1 do -- pets + but we'll only match normal pets
local fn = Necrosis.Warlock_Buttons[Necrosis.Warlock_Lists.pets[i].f_ptr].f
local f = _G[fn]
local spell = Necrosis.GetSpell(Necrosis.Warlock_Lists.pets[i].high_of)
if f and spell.PetId then
if tonumber(Local.Summon.DemonId) == spell.PetId then
NecrosisConfig.PetInfo[Necrosis.Warlock_Lists.pets[i].high_of] = UnitName("pet")
high = spell.PetId -- only expect one
f:LockHighlight()
else
f:UnlockHighlight(f.norm)
end
end
end
Necrosis:UpdateMana()
--[[
_G["DEFAULT_CHAT_FRAME"]:AddMessage("ChangeDemon"
.." ld'"..tostring(Local.Summon.LastDemonType).."'"
.." dt'"..tostring(Local.Summon.DemonType).."'"
.." di'"..tostring(Local.Summon.DemonId).."'"
.." hi'"..tostring(high).."'"
.." up'"..tostring(UnitName("pet")).."'"
)
--]]
return
end
local function SetupSpells(reason)
Necrosis:SpellSetup(reason)
-- associate the mounts to the sphere button || Association du sort de monture correct au bouton
if GetSpellInfo(GetSpellInfo(5784)) or GetSpellInfo(GetSpellInfo(23161)) then
Local.Summon.SteedAvailable = true
else
Local.Summon.SteedAvailable = false
end
if not InCombatLockdown() then
Necrosis:MainButtonAttribute()
Necrosis:BuffSpellAttribute()
Necrosis:PetSpellAttribute()
Necrosis:CurseSpellAttribute()
Necrosis:StoneAttribute(Local.Summon.SteedAvailable)
end
-- (re)create the icons around the main sphere
Necrosis:CreateMenu()
Necrosis:ButtonSetup()
-- Check for stones - the buttons can be updated as needed
Necrosis:BagExplore()
--[[ Determine the pet out, if any, and mark its button.
Really to clear the buttons in case we 'lose' the pet
on a reload / crash / other reason.
The event UNIT_PET is triggered at init / reload IF a pet is out
--]]
Necrosis:ChangeDemon()
end
--[[ SetupBuffTimers
This routine is invoked during initialization to get warlock buffs, if any.
However, it seems buffs are not available until after Necrosis initializes on a login.
Use variables above and OnUpdate to get them, if needed.
--]]
function SetupBuffTimers()
-- print(("%d=%s, %s, %.2f minutes left."):format(i,name,icon,(etime-GetTime())/60))
if Necrosis.Debug.init_path then
print("SetupBuffTimers"
.." bn'"..tostring(Local.buff_needed).."'"
.." ba'"..tostring(Local.buff_attempts).."'"
)
end
local buffs_found = false
local res = false
for i=1,40 do -- hate hard coded numbers! Forums suggest the max buffs is 32 but no one is sure...
local name, icon, count, debuffType, duration,
expirationTime, source, isStealable, nameplateShowPersonal, spellId,
canApplyAura, isBossDebuff, castByPlayer, nameplateShowAll, timeMod
= UnitBuff("player", i)
if name then
buffs_found = true
if Necrosis.Debug.init_path then
print("SetupBuffTimers"
.." '"..name.."'"
.." "..Necrosis.Utils.TimeLeft(expirationTime-GetTime())
)
end
local s_id, s_usage, s_timer, s_buff, s_cool = Necrosis.GetSpellByName(name)
if s_timer and s_buff then
local target = {
name = UnitName("player"),
lvl = UnitLevel("player"),
guid = UnitGUID("player"),
}
local cast_info = {
usage = s_usage,
spell_id = s_id,
guid = "",
}
Local.TimerManagement = Necrosis:TimerInsert(cast_info, target, Local.TimerManagement, "buff found", expirationTime-duration, duration, s_cool)
else
end
else
break -- no more
end
end