From 59229f51789a445d863f6c4e8128fd24c83b27f8 Mon Sep 17 00:00:00 2001 From: Softrix Date: Mon, 19 Dec 2022 09:15:48 +0000 Subject: [PATCH] Initial commit --- .gitattributes | 2 + Bindings.xml | 11 + Icons/Deathknight.tga | Bin 0 -> 3628 bytes Icons/DeathknightPet.tga | Bin 0 -> 3592 bytes Icons/Demonhunter.tga | Bin 0 -> 3357 bytes Icons/Druid.tga | Bin 0 -> 4645 bytes Icons/Envoker.tga | Bin 0 -> 4140 bytes Icons/Hunter.tga | Bin 0 -> 4593 bytes Icons/HunterPet.tga | Bin 0 -> 4491 bytes Icons/IconDisabled.tga | Bin 0 -> 3116 bytes Icons/IconEnabled.tga | Bin 0 -> 3116 bytes Icons/Mage.tga | Bin 0 -> 4645 bytes Icons/MiniMapButtonDisabled.tga | Bin 0 -> 16428 bytes Icons/MiniMapButtonEnabled.tga | Bin 0 -> 16428 bytes Icons/Monk.tga | Bin 0 -> 3654 bytes Icons/Paladin.tga | Bin 0 -> 4645 bytes Icons/Priest.tga | Bin 0 -> 4645 bytes Icons/Rogue.tga | Bin 0 -> 4645 bytes Icons/Shaman.tga | Bin 0 -> 4645 bytes Icons/Warlock.tga | Bin 0 -> 4645 bytes Icons/WarlockPet.tga | Bin 0 -> 4497 bytes Icons/Warrior.tga | Bin 0 -> 4645 bytes Icons/empty.tga | Bin 0 -> 3552 bytes Libs/Broker_SmartBuff/Broker_SmartBuff.lua | 45 + Libs/Broker_SmartBuff/Broker_SmartBuff.toc | 10 + Libs/Broker_SmartBuff/LibDataBroker-1.1.lua | 90 + .../CallbackHandler-1.0.lua | 212 + Libs/LibStub/LibStub.lua | 30 + README.md | 83 + ReadMe.txt | 51 + SmartBuff.buffs.lua | 1425 +++++ SmartBuff.globals.lua | 54 + SmartBuff.lua | 4599 +++++++++++++++++ SmartBuff.toc | 17 + SmartBuff.xml | 3166 ++++++++++++ localization.cn.lua | 437 ++ localization.de.lua | 217 + localization.en.lua | 232 + localization.es.lua | 214 + localization.fr.lua | 215 + localization.ru.lua | 212 + localization.tw.lua | 220 + 42 files changed, 11542 insertions(+) create mode 100644 .gitattributes create mode 100644 Bindings.xml create mode 100644 Icons/Deathknight.tga create mode 100644 Icons/DeathknightPet.tga create mode 100644 Icons/Demonhunter.tga create mode 100644 Icons/Druid.tga create mode 100644 Icons/Envoker.tga create mode 100644 Icons/Hunter.tga create mode 100644 Icons/HunterPet.tga create mode 100644 Icons/IconDisabled.tga create mode 100644 Icons/IconEnabled.tga create mode 100644 Icons/Mage.tga create mode 100644 Icons/MiniMapButtonDisabled.tga create mode 100644 Icons/MiniMapButtonEnabled.tga create mode 100644 Icons/Monk.tga create mode 100644 Icons/Paladin.tga create mode 100644 Icons/Priest.tga create mode 100644 Icons/Rogue.tga create mode 100644 Icons/Shaman.tga create mode 100644 Icons/Warlock.tga create mode 100644 Icons/WarlockPet.tga create mode 100644 Icons/Warrior.tga create mode 100644 Icons/empty.tga create mode 100644 Libs/Broker_SmartBuff/Broker_SmartBuff.lua create mode 100644 Libs/Broker_SmartBuff/Broker_SmartBuff.toc create mode 100644 Libs/Broker_SmartBuff/LibDataBroker-1.1.lua create mode 100644 Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua create mode 100644 Libs/LibStub/LibStub.lua create mode 100644 README.md create mode 100644 ReadMe.txt create mode 100644 SmartBuff.buffs.lua create mode 100644 SmartBuff.globals.lua create mode 100644 SmartBuff.lua create mode 100644 SmartBuff.toc create mode 100644 SmartBuff.xml create mode 100644 localization.cn.lua create mode 100644 localization.de.lua create mode 100644 localization.en.lua create mode 100644 localization.es.lua create mode 100644 localization.fr.lua create mode 100644 localization.ru.lua create mode 100644 localization.tw.lua diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/Bindings.xml b/Bindings.xml new file mode 100644 index 0000000..11ed7a1 --- /dev/null +++ b/Bindings.xml @@ -0,0 +1,11 @@ + + + SMARTBUFF_Check(0); + + + SMARTBUFF_OptionsFrame_Toggle(); + + + SMARTBUFF_ResetBuffTimers(0); + + diff --git a/Icons/Deathknight.tga b/Icons/Deathknight.tga new file mode 100644 index 0000000000000000000000000000000000000000..6a337ffe48812872838f69e4a8767fc9bfece7b7 GIT binary patch literal 3628 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 O1iii}C2iqs>3;yZdsKJ; literal 0 HcmV?d00001 diff --git a/Icons/Demonhunter.tga b/Icons/Demonhunter.tga new file mode 100644 index 0000000000000000000000000000000000000000..9470d01b91b6e74151d19d13a374374b5e3559a1 GIT binary patch literal 3357 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 CHQ>Gg literal 0 HcmV?d00001 diff --git a/Icons/Druid.tga b/Icons/Druid.tga new file mode 100644 index 0000000000000000000000000000000000000000..c95ff258d88279eef4ac432fa36ee837cb6f7456 GIT binary patch literal 4645 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 b=9OFb>@|^rcF~-JVu!(_CFc@>VIG7qJ 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 NU#ZbCu~C1A{sTwWa0>tc literal 0 HcmV?d00001 diff --git a/Icons/IconEnabled.tga b/Icons/IconEnabled.tga new file mode 100644 index 0000000000000000000000000000000000000000..709884254e60ba116a1a072cd111cae7f1c20580 GIT binary patch literal 3116 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 E08#dd0ssI2 literal 0 HcmV?d00001 diff --git a/Icons/MiniMapButtonDisabled.tga b/Icons/MiniMapButtonDisabled.tga new file mode 100644 index 0000000000000000000000000000000000000000..67ccf661606e212fe2e4ffa510cd7c8f0797d984 GIT binary patch literal 16428 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 literal 0 HcmV?d00001 diff --git a/Icons/Monk.tga b/Icons/Monk.tga new file mode 100644 index 0000000000000000000000000000000000000000..a67ae1a42839ed36483391dd92a6ed0efbf6102d GIT binary patch literal 3654 zcmY+HX;55OcE?|Lzg}sYX6tUCcW9b@-!XtOP8 zv{=%_l184f>{!-#ERQ_)OcJ?jCZ0-VQb|o^sU%aWd~hZoCZCcIDSo*Pm71B?b?@75 zpZ~dM`JeM7$sqmz;g-ZtcO`tQbd zRqNr&ShTN;=DtDdgCVjiswqwLk?V;kE6zz(s*j4=YW5C}(|h_|impG!a_Jo|h5vaz zJjM4l=ST*%I(#h!LVfHW+)YVEA+hERv?>z{IeJr;wVSd+wW*M#O^rdn85L*SOmw*L zIg6+-FJq{GABC45GX2;8MOcoklDDOw4d3Z33As{|qtVpeTp{^(1!->^Az0)iGD3sd zARyFQR#iF!CP|?{QmRPw`U!-(>0emp;L3Rh7gyLbJVJg^A)#zL?X%N(pWN93Qz_Mw zR-=)&u(qZIS#wL06f;s@&nUrQ4}Mn}3WW|yABkEQi9!rjgc(T_fh2436_gSjnP&Ic zJY7dm(lfVA=kyX?vrAj&?1~*!q@^&ryOoq*ykg?B&yi)-A46V~>IMgB3Um--%cLQ& zlk9W>A?r{^#v+R$8N|IxM`}R@!Glu-`VUdlJ4VZ)8JfqYX&gFC{ooj-t-X}AAE0Mw zKgG^^`bz5YeEx;7jPeg5ePbu7?`S7lYrx@}qhjZ7#(Rq?OmhoZlYp}z30Sq*X~Tek znOvl(rHA}r2j!i8RCW(i+ObcZ_fvP^FrkT~49qVuHaUSWJ(;1VMpEv)&z4PB!=6kE zp1LZQ4v?Ibf-ydX{lE=0742jdRx{ZXpe2w&Ok5n2HkMeskJhm%M$cVkU}=?}`DOM@ z&C_<|7@e~x7&(1`+3UABvVM)e6HCmmU!bq2l@gDYjKu|7KK?OVsN2xx$4*e|ip8jN z;2C?H()T|lb>$wK!fw*a>zO{-!a$pd+t_%lE+4&fLgbAH9KZFD`CAWIx&N5c51ue{ zmTHj`^t8JZX+Iy#p0ghV>VCyAL_+zRe31=6RNX)7;AtuTm(Y8<`{ z{Cf_OJi1O+`y`nayNF0GLrTmO;Vu{;*FjTfE8`b8ICAwS*PnmJ{jXkg^W{%?^!gWK ze8Z6|?+~1rp?7JSLvJioC^Aba8!(t6*j*FAaqQCX6=*!TfKwNRT9(B_EwUuz@upL< zqfA7SjvYKYYo6L_+^Nzd~W6>k)2W5#GO;EYb9`Sb?bh7c}S{|qI8CbY5!YfL14D@K}+ zrl8e#p^p+KA5>G{>BZT(jQh>IB(q`d}{x)q&a0GqRt%$#zHb}Z61dY@*IG&z-L ziFYlC(NA7=2fK!=iLncckW6Tlf~gdd)HLrUvHK7%_s|?!d6hx|9R_0r9Wx2^pNS+U zDZDVuDK?C8F1%HBxI6Y^E!azfWdf6Jp4hyD6x3Fco9(2rW0>lWCGr}lDQFy{Xx9PC z_Y4pknPl#EGoJitqyz)z!fgerD|Qk!uz)M6ZwhZ(vCvF`RvnAq-G$TXM-wTb2=l1H zffQpSHo=B1rbE<@H%Z!k4*%JAaZj!jnHwNEC57V~Yh3)`BUT?jW$E5sCNHlM60FpF z{3!i%MPv@i6h2i`@D;eg1uF9)2oZau%brRG74mw?2Nvum1ag`02O*$@0AqXrDSx z(^whlJA_+5R1&zL!fVywOB5U35yaX$ip$bDiMMbk8kGWTtjL6jXq-uX*zDaH%xPE> z+@$%(a2K2)CM_RFu8HQ^MEt!6@y~ro{@Npq<&7wnDU{ZXa9Xg^pZ?`HY&?CzfiuHo z)i|kGkU0HYHG5Z76lZR`Ah)@V7{TkV#0F9Q8oESK$z*vvqGl>FnjN( zS3Hlqs+h!-ax9`WcQ4r(I+sMM=nN9-`Y*6EKtvE$4WB@rSu8A2-bzNOpO^?edC4x+YCV!D+!004$NZ zH;Bl0W40G!smaFGlEJmtI*wg83Z=R+Cmctq4uj8$4eS-lE%3oV{uQU5KIZBN9fVq9 zgiHzl2^HtAXOd{Kkvo14gTs$2OvRSN$M7aPFhy!nYqdg<5ue{g-?*QqX&Nm%Vsf<#0C6l|%` zX-OzCQ9seZ^4$jBeV$8B)e#}=J7U}?W%qkqu@MzIg|_$*)~XtUGf`Z8Pr;c}5rT-! z6t?!Es}BBN0e4A|jLUBmqcw~6Of9I`L~Ey!b6-i+AJU*#32?O-vd9RRk~1}jqlSa$xDzoCPN5Z9 z7T)}JA+|1Fz}dBrDB*matfZzXiuuP@JUcX~l%hhZ#B)IkdG#eUAIzY*K%!_uqVo#{ z@BC8YACNfpCko8F`tUD*Lfx~!p!Cki!p;-u^82u7h_=I)Kway8wCS~f*aHN5hlzae z0eR&us5A!bmQ<3QN5yrH2v!NLu$aR$OlfBmnUxZ0dn8KdWy-shxKbomU#NNUPYMG2 zEZCZll6CGQY9D=0%G_IMy$vF}qwo~eqVDP>P#M^U-fk&fr47WLy+TQp6Qdx3M9UCL z-C6X;N)nudq>CJL7Di)@m&gsNsp?TOazjPif=u5FB|k&WcfKzXU*N#lc!IR$m*h@e zMlWivJ;{Yp6n&l7x7}=QLkf#)W7D#6+_*_ib{$cYaId<82-7Uij0)n?rLbGDMybdz zP*F9Zr0Z)nq0=f#M-;65T*W8v{C86mo`#Hl;j^*lC?`o-J2@T z{z}8@lNcI%@^Qx5NNJzIzIdI?vRalt)tYkh|EO1YI2@8J%i;La##dG0TsVd6?i12` zM~N4o1ERYZtSMvGt2f=z@@DCTaH?j;>b}GZ;HWC6T*7=IoiF4 ziO0o=IminM|^?lT6ad?(Al>U;4vu-zqZWCX-2azU_xO zC+~Ys&N=ly_y6;MOD5^1KOYg2IJMF^AZf#UN64Fgh~vR?9M7Ln^76+-e*7)gdv_Rp z{Y&u;(mQ{dywmG9vTkz|MXpK`bMnZHizYeJpG1q5+?Z%`^7E)|YNO%kEa_+7Ct&oP zXNeK_62tDv^8NSUOYR%@a8z!ltf`DuIcWr1(lIDQP--$UEBrCYB}{S|3Y8M2+#93b z3wz*7in6oV`c^$@qgUzr`G1IIkWT((vP7?SQC+beS9&xiqZ*Y=LQ*JEDO70Xa%4({ zFk2>`$&ut*&pWxe*Xwj>)f#MJp;RV?QQgypePP?kWI>dU9J zKYZ*Fb=+;q3HKCK*wjd=qXu)(a$E-vl3cU_-!MDg5s@rw>B8T+9<9cRTCT@O@&I7VL4ijQaBWm9iStoC!b9Uq1K8uvsg=Oa{QYUWH_3F25n*SVCWgj7}?_w

V>1*zO_upK6`3=2ye@sg6Bq6nX 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 literal 0 HcmV?d00001 diff --git a/Icons/Shaman.tga b/Icons/Shaman.tga new file mode 100644 index 0000000000000000000000000000000000000000..6aac4d48ba4b2e6f739f8b5b3ce50671bf3b014c GIT binary patch literal 4645 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 St)ut;>@_bi`pO>z;eP-WDO)7~ literal 0 HcmV?d00001 diff --git a/Icons/Warlock.tga b/Icons/Warlock.tga new file mode 100644 index 0000000000000000000000000000000000000000..f187dccefda492c6833d8119c95a2b3ca402b797 GIT binary patch literal 4645 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 literal 0 HcmV?d00001 diff --git a/Icons/WarlockPet.tga b/Icons/WarlockPet.tga new file mode 100644 index 0000000000000000000000000000000000000000..bebaaedc6662172e966c886b7203d060b4bfc8bd GIT binary patch literal 4497 zcmeH~X>3$g7=~{{+nEl~meO_#beWd!OlhHXnYJ@6baPtT(gkS?wXFrp2xYZpiGni) z8CfEN2t?T;Dv21-C;@~ZDv8EFE*N8?Ci=%{qQnr5T9ViMe#5y10soo!!#3yK+jH;z zp6`9nch0>H(kz<#v1$6RS=$9bGbgOu4(GwMaJ_j6u1n`p^ZvU?e(MV)o_-DfkFM$W zKzqvQ#?NYRLw#o#s@zSmmpDR2+hdHu3m<7X}1Jb!INgp6c~^3Ep(nyB$X4Jec-6v=jF|z{EJU886M}QSdnlj zpk3f*W)R)IL|+iPoBADfpS>pXkA8F2;CtyowDND#dnbiR14w2D^qDN->GQzM*yuf5 z`yV&3;O9UNE&a<8wPHvN5Pa6aV`y{~Nbz-DJ$`Szh4}1&1`toA2-fR})6S++;klQc zY5tk#F!0+C2AtCB%3VlU;~$0B^bLw`R{q@g4+xyze|Y^{nR?M~;skPC(0SGs6Odxi zITPb1!^>`%BVI}krdHzUsAKC9Y&w1h=9Ky#xSBf*9Fes7E}Z3d9Brl?5(watjbr@V z$1arWmB|WRzhwtZ)lD!bEnJC0SFHi2&U=ERxkpeZV-if0RRSsr1!sZrK9189T3z?u zMMHOa{d`P*a4F2Tp0%*&l^S@?G4Ztc4x6Ko96M_0WO$<46h@)>H|v1~Pp`P2C_Kf{ zc4x^PL@XM__$i$$kdj$o;Fo=R`VPz0B7gVFJ9ii>n^q9?sW-db0L6DDwd zzB#2V(ix6Qg!g)p6xY2P={XL$iS@{xMa?%oVC(6A$e2|sQ_5LnTs(vl!g1N0Z&d@~ zyq|N=*xWW$0vWU2ur@4)Ikt5^CKrR+3HgE{n|bEeHzI0I9ZZv}AI6O8HiOOA8(n5#R*fJ99>mzxC)-v8 zqi{=MbY4+Jwe*-J1F(@y^?atRcRfO;6(BU$(SYoxg)*piwCcw^@_>&|#ZWi%P$k93 z8J4DVs?{F*_mw^&!zNMGWLE516%gG&3`;@=Ox#dom#w)2t?HWOVRk-ZBgKbXTuP(? z${XfG78~b{jVw{2UyEz%7~RC;Rt_O!W|=Tq-h6kl${Jhs_p^=@ql1*(VVQFR#_@~< zl6hpc^I=s=ikRQf3A58J#BeIK6}pkV^BE!XW;XQ|K&p~q*sEtD*t^*r;Uw|}yW#s! zBoy6M&PH~vfGILg*nwBIb!ZzB+X5?(a=H50m;iS$);4!8N@u%08PYhvlTrscd)%rmPAfkG`tITphg_fBZ1=9CJlKH+!O03Ti`Sf9ymTI0PiJ71dJS1nbT-`d7s=#N_5l z>XP-7^k{;!Lifg1itv|?And{=3J@RPQ^o8Hp|iti%l@bCb&Ha-FFycH~A2k z7f4j1`57|YZp*>cvIb;q^<%=GU5Glo4_UikMf%ngh#%aKasAs7wtNR7R&T?U)}@$~ zn2+>$yJWVV5q7dO7tJU_jsEg?R=F`p|BtAuwh^VeErmG+$V(60zJqsO4^sbp{eS## zJK!GZ?O#&6q<5{|HoLEHaNVkRjY0D V)~>q$y~X#xq-p+$z}348;V<1Jp;!O_ literal 0 HcmV?d00001 diff --git a/Icons/Warrior.tga b/Icons/Warrior.tga new file mode 100644 index 0000000000000000000000000000000000000000..daef21a8571e538b635b1487f2f0ca8f2129fa94 GIT binary patch literal 4645 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 Df&lNC literal 0 HcmV?d00001 diff --git a/Icons/empty.tga b/Icons/empty.tga new file mode 100644 index 0000000000000000000000000000000000000000..c21e7e1e6044cae2402baff9dedf8c6c36a44e28 GIT binary patch literal 3552 zcmYjUX>^li7Jj}xTa$E6nzl)srfr%gZJ-<7LhJ_Vl2Te|DU=rIDy6I~APh@ETcjum zD2m81P+Q$}G|7GL``qWf z_xS(~{`X1-`%{e*5tO9$qf~a}68SE?NxnBHsru@>lydP7Sbp5n%yps~;|cZU|- zzkeS)Lw81BLmSn!*HA%mE}3HTNGDoIR0=6dh$XX5M<#=s1W6>3k08B9OLo&tsw|pC zor_y3ckDS@^~pczkx-q%Br@<4 zMX*caWa4=>X+(kYvXaS`m_QAlL~2~KitMM3P&jHh=QwXm7X<<>lwq4if~cX?tUS_2 znMk8IPU#f&x(HqLcJ3N-)P!zO|Ct3Mwh(^3*iYNC+)Ht@|OWoZm>1iiYZfEi|(C z!0p(?a({MV8*KT0C}t-T&9Ru38UgSj#V{Zt0-T^?_gaXYn!&RFb2@+}#Xj(Z)7-Yk zSST$sl{)8CljF!~3ZsRKoe-&CLl(z z5ggmSC>YoV8Q~0?=d=ty#DWxtmv}*uAzlNEJbFqtHT;f=GI` z_P!wSPOVmh_J#8?xSnD+P=4N#?aADAERvEI?ND zczk3tuHM{^SEhRK{zuF4)RP&g$Ty<3Efdc^lZT;AKI9hpk>o6btg^BSgqT({wJB_6 zLSyeC3N#ucG;#5eCG`fKK}$8WeU!8|blU%$K=q0tvZ@U1pmFyiL@giUPGoC@PK97_ z27=9H*fw$r{ag29VT%`Mk9x3SxfLC4Wk~nTML~5BW|a@X<|;yzDH$qW2Ln@`%%l(* zXF)^vAUcLOAx>-LWnR9Q7;mSd-OtfOCtf0(y|$Bljf=>jsEHG>UoWaz-Wo7AppngZ zXKFLX$LnzN{9)|adkC8kIPm2+1-Nmo2x|vsLKm3`jU^4HBp=dC7NVqiCDOeW&}z*P zL@ipn2hck7E7UJu#u8&^lb7~eBNM20`=g{(HIU7=c#sNwb4U^8P$#QZ1PO}3z?C>S zoTd2m_9(vl%Ql?3*o2~zLIkTj5DcW?@)a{S4wvA)TX%3_>T`6h*aB~MJxrEjrk85i zV;#uN@}RJ=0>yLZp?BS;uwFz?t_>-1cI^VPEbJj$a_2g7drMdXDvFMZN-8QUgFB~? z2`T~|s~tVKmxHiowD#ErY(qIc_RXrw4K*0kdCu%$Di4XosS*FZ!b)ueo+UU zZg02*IkiEGDz71%rD{3NsA?uX8>KN?W9_1)y}0n!Rh;|eJ-qeCi#U7Ag4fQcWBZm| zxZQ;~etZ|c`nCxt4jC|UFau{#$6)_x6*3ap?&p}1?bcz(U>-icG7k@LPR5GXa$J1% z3NBoI3(rryfSP%AVG))t+elJYK4YM$o?H!!DN3s*MG*H#>Y_1zVgh?!ID;#ne82=Y zA3yz2hu@tmMN(26&b{yizW;FmCr+sG^oA^a_n{qA7t_$ZBn@SGE7&RUA;VLEN5;l5 zI=&UDj(Ehgk~YkrkN&|y4D>&^-x6o0oZeleNy?ybCyeV`%iKT`GZ?}>9WU{@)dB21 zbq4Fl#xXjw5&K4a@b>$sF}U#&EM2-1Uw?Cwm0=XuU$4VozsSc|UpHd^`9c`gP89nC zOe;Yw>RO63Y!fa=TDULDY*q=1$j2FC@8!+NBy+=}Upk?AaF{Y?mXfH`kVX(UR8|Er zxOpey6Ej##j)fs628#!~@%F8|IQ-Ok4EA*6_PghC``bPE=*|c(oxgyb>|CU##$d;u z6&M-{VB7X`loncHQ0bvz!%$?MQ4zTfI*pNX>)S|G7WgHB@r_0FUiojTc@%g_DN{F>yE-Z@k@y zGQS(8B?07kW)bvt=u+qL`6!Dlk|{$C?0}6t_h|@-x!HGnALK3{ruf z4SdEQ)G9RswE^sUbPQKN{S42Zdj%J-+(JvwdYH|rh|$FOO@{c}YGyJfvBWa3udMN4OA)4)}AOmF5b38F=9+AMiLVk^BGf3tl!j49(j)1@mOovt+oj8l} zqbG3s!X-?cnsBWd-gKnAqJ~U@hEiBeEpt*a`9;%KGHi`wZTYjwc;+PKtY1x8N;GrU z3WF1f#hl_)`gO8oEMavug}kdQN+QRLriF`_l`QV)T~}K>Zz_GpOq%(CkE}6fay0f+ z;_%~?HOo)o=+nkNwzQP2L)*yq^eM_*)J3rz$IJ|f<9SjsL(hn0{(>io8F}V2h^dNX zjfNDhM6voP(#&ok)83azSf9X1iO<`(h4au&`23;ti|Ho(YM#HKYGI%$&=B;rRtM^;vhg3Pi&kj> literal 0 HcmV?d00001 diff --git a/Libs/Broker_SmartBuff/Broker_SmartBuff.lua b/Libs/Broker_SmartBuff/Broker_SmartBuff.lua new file mode 100644 index 0000000..ae1b766 --- /dev/null +++ b/Libs/Broker_SmartBuff/Broker_SmartBuff.lua @@ -0,0 +1,45 @@ +------------------------------------------------------------------------------- +-- Broker: SmartBuff +-- Created by Aeldra (EU-Proudmoore) +-- +-- Data Broker support +------------------------------------------------------------------------------- + +if (not SMARTBUFF_TITLE) then return end + +local F = CreateFrame("Frame", "Broker_SmartBuff"); + +function SMARTBUFF_BROKER_SetIcon() + if (not F.LS) then return end + if (SMARTBUFF_Options and SMARTBUFF_Options.Toggle) then + F.LS.icon = "Interface\\AddOns\\SmartBuff\\Icons\\IconEnabled"; + else + F.LS.icon = "Interface\\AddOns\\SmartBuff\\Icons\\IconDisabled"; + end +end + +F.LS = LibStub:GetLibrary("LibDataBroker-1.1"):NewDataObject("SmartBuff", { + type = "launcher", + label = SMARTBUFF_TITLE, + OnClick = function(_, msg) + if (msg == "RightButton") then + SMARTBUFF_OToggle(); + SMARTBUFF_BROKER_SetIcon(); -- bug fix, credit: SunNova + elseif (msg == "LeftButton" and IsAltKeyDown()) then + if (IsAddOnLoaded("SmartDebuff")) then + SMARTDEBUFF_ToggleSF(); + end + elseif (msg == "LeftButton") then + SMARTBUFF_OptionsFrame_Toggle(); + end + end, + icon = "Interface\\AddOns\\SmartBuff\\Icons\\IconDisabled", + OnTooltipShow = function(tooltip) + if (not tooltip or not tooltip.AddLine) then return end + tooltip:AddLine("|cffffffff"..SMARTBUFF_TITLE.."|r"); + tooltip:AddLine(SMARTBUFF_TITAN_TT); + end, +}); + +F:Hide(); +--print("Borker - SmartBuff loaded"); diff --git a/Libs/Broker_SmartBuff/Broker_SmartBuff.toc b/Libs/Broker_SmartBuff/Broker_SmartBuff.toc new file mode 100644 index 0000000..f3e3f8f --- /dev/null +++ b/Libs/Broker_SmartBuff/Broker_SmartBuff.toc @@ -0,0 +1,10 @@ +## Interface: 90207 +## Title: Broker: Smart|cffffffffBuff|r +## Version: 1.90207 +## Notes: SmartBuff support for Data Broker +## Author: |cff20d2ffAeldra|r (EU-Proudmoore) +## Dependencies: SmartBuff +## X-Category: Miscellaneous + +LibDataBroker-1.1.lua +Broker_SmartBuff.lua diff --git a/Libs/Broker_SmartBuff/LibDataBroker-1.1.lua b/Libs/Broker_SmartBuff/LibDataBroker-1.1.lua new file mode 100644 index 0000000..f47c0cd --- /dev/null +++ b/Libs/Broker_SmartBuff/LibDataBroker-1.1.lua @@ -0,0 +1,90 @@ + +assert(LibStub, "LibDataBroker-1.1 requires LibStub") +assert(LibStub:GetLibrary("CallbackHandler-1.0", true), "LibDataBroker-1.1 requires CallbackHandler-1.0") + +local lib, oldminor = LibStub:NewLibrary("LibDataBroker-1.1", 4) +if not lib then return end +oldminor = oldminor or 0 + + +lib.callbacks = lib.callbacks or LibStub:GetLibrary("CallbackHandler-1.0"):New(lib) +lib.attributestorage, lib.namestorage, lib.proxystorage = lib.attributestorage or {}, lib.namestorage or {}, lib.proxystorage or {} +local attributestorage, namestorage, callbacks = lib.attributestorage, lib.namestorage, lib.callbacks + +if oldminor < 2 then + lib.domt = { + __metatable = "access denied", + __index = function(self, key) return attributestorage[self] and attributestorage[self][key] end, + } +end + +if oldminor < 3 then + lib.domt.__newindex = function(self, key, value) + if not attributestorage[self] then attributestorage[self] = {} end + if attributestorage[self][key] == value then return end + attributestorage[self][key] = value + local name = namestorage[self] + if not name then return end + callbacks:Fire("LibDataBroker_AttributeChanged", name, key, value, self) + callbacks:Fire("LibDataBroker_AttributeChanged_"..name, name, key, value, self) + callbacks:Fire("LibDataBroker_AttributeChanged_"..name.."_"..key, name, key, value, self) + callbacks:Fire("LibDataBroker_AttributeChanged__"..key, name, key, value, self) + end +end + +if oldminor < 2 then + function lib:NewDataObject(name, dataobj) + if self.proxystorage[name] then return end + + if dataobj then + assert(type(dataobj) == "table", "Invalid dataobj, must be nil or a table") + self.attributestorage[dataobj] = {} + for i,v in pairs(dataobj) do + self.attributestorage[dataobj][i] = v + dataobj[i] = nil + end + end + dataobj = setmetatable(dataobj or {}, self.domt) + self.proxystorage[name], self.namestorage[dataobj] = dataobj, name + self.callbacks:Fire("LibDataBroker_DataObjectCreated", name, dataobj) + return dataobj + end +end + +if oldminor < 1 then + function lib:DataObjectIterator() + return pairs(self.proxystorage) + end + + function lib:GetDataObjectByName(dataobjectname) + return self.proxystorage[dataobjectname] + end + + function lib:GetNameByDataObject(dataobject) + return self.namestorage[dataobject] + end +end + +if oldminor < 4 then + local next = pairs(attributestorage) + function lib:pairs(dataobject_or_name) + local t = type(dataobject_or_name) + assert(t == "string" or t == "table", "Usage: ldb:pairs('dataobjectname') or ldb:pairs(dataobject)") + + local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name + assert(attributestorage[dataobj], "Data object not found") + + return next, attributestorage[dataobj], nil + end + + local ipairs_iter = ipairs(attributestorage) + function lib:ipairs(dataobject_or_name) + local t = type(dataobject_or_name) + assert(t == "string" or t == "table", "Usage: ldb:ipairs('dataobjectname') or ldb:ipairs(dataobject)") + + local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name + assert(attributestorage[dataobj], "Data object not found") + + return ipairs_iter, attributestorage[dataobj], 0 + end +end diff --git a/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua b/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua new file mode 100644 index 0000000..a8377fe --- /dev/null +++ b/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua @@ -0,0 +1,212 @@ +--[[ $Id: CallbackHandler-1.0.lua 1186 2018-07-21 14:19:18Z nevcairiel $ ]] +local MAJOR, MINOR = "CallbackHandler-1.0", 7 +local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR) + +if not CallbackHandler then return end -- No upgrade needed + +local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end} + +-- Lua APIs +local tconcat = table.concat +local assert, error, loadstring = assert, error, loadstring +local setmetatable, rawset, rawget = setmetatable, rawset, rawget +local next, select, pairs, type, tostring = next, select, pairs, type, tostring + +-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded +-- List them here for Mikk's FindGlobals script +-- GLOBALS: geterrorhandler + +local xpcall = xpcall + +local function errorhandler(err) + return geterrorhandler()(err) +end + +local function Dispatch(handlers, ...) + local index, method = next(handlers) + if not method then return end + repeat + xpcall(method, errorhandler, ...) + index, method = next(handlers, index) + until not method +end + +-------------------------------------------------------------------------- +-- CallbackHandler:New +-- +-- target - target object to embed public APIs in +-- RegisterName - name of the callback registration API, default "RegisterCallback" +-- UnregisterName - name of the callback unregistration API, default "UnregisterCallback" +-- UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API. + +function CallbackHandler:New(target, RegisterName, UnregisterName, UnregisterAllName) + + RegisterName = RegisterName or "RegisterCallback" + UnregisterName = UnregisterName or "UnregisterCallback" + if UnregisterAllName==nil then -- false is used to indicate "don't want this method" + UnregisterAllName = "UnregisterAllCallbacks" + end + + -- we declare all objects and exported APIs inside this closure to quickly gain access + -- to e.g. function names, the "target" parameter, etc + + + -- Create the registry object + local events = setmetatable({}, meta) + local registry = { recurse=0, events=events } + + -- registry:Fire() - fires the given event/message into the registry + function registry:Fire(eventname, ...) + if not rawget(events, eventname) or not next(events[eventname]) then return end + local oldrecurse = registry.recurse + registry.recurse = oldrecurse + 1 + + Dispatch(events[eventname], eventname, ...) + + registry.recurse = oldrecurse + + if registry.insertQueue and oldrecurse==0 then + -- Something in one of our callbacks wanted to register more callbacks; they got queued + for eventname,callbacks in pairs(registry.insertQueue) do + local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten. + for self,func in pairs(callbacks) do + events[eventname][self] = func + -- fire OnUsed callback? + if first and registry.OnUsed then + registry.OnUsed(registry, target, eventname) + first = nil + end + end + end + registry.insertQueue = nil + end + end + + -- Registration of a callback, handles: + -- self["method"], leads to self["method"](self, ...) + -- self with function ref, leads to functionref(...) + -- "addonId" (instead of self) with function ref, leads to functionref(...) + -- all with an optional arg, which, if present, gets passed as first argument (after self if present) + target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]]) + if type(eventname) ~= "string" then + error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2) + end + + method = method or eventname + + local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten. + + if type(method) ~= "string" and type(method) ~= "function" then + error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2) + end + + local regfunc + + if type(method) == "string" then + -- self["method"] calling style + if type(self) ~= "table" then + error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2) + elseif self==target then + error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2) + elseif type(self[method]) ~= "function" then + error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2) + end + + if select("#",...)>=1 then -- this is not the same as testing for arg==nil! + local arg=select(1,...) + regfunc = function(...) self[method](self,arg,...) end + else + regfunc = function(...) self[method](self,...) end + end + else + -- function ref with self=object or self="addonId" or self=thread + if type(self)~="table" and type(self)~="string" and type(self)~="thread" then + error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string or thread expected.", 2) + end + + if select("#",...)>=1 then -- this is not the same as testing for arg==nil! + local arg=select(1,...) + regfunc = function(...) method(arg,...) end + else + regfunc = method + end + end + + + if events[eventname][self] or registry.recurse<1 then + -- if registry.recurse<1 then + -- we're overwriting an existing entry, or not currently recursing. just set it. + events[eventname][self] = regfunc + -- fire OnUsed callback? + if registry.OnUsed and first then + registry.OnUsed(registry, target, eventname) + end + else + -- we're currently processing a callback in this registry, so delay the registration of this new entry! + -- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency + registry.insertQueue = registry.insertQueue or setmetatable({},meta) + registry.insertQueue[eventname][self] = regfunc + end + end + + -- Unregister a callback + target[UnregisterName] = function(self, eventname) + if not self or self==target then + error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2) + end + if type(eventname) ~= "string" then + error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2) + end + if rawget(events, eventname) and events[eventname][self] then + events[eventname][self] = nil + -- Fire OnUnused callback? + if registry.OnUnused and not next(events[eventname]) then + registry.OnUnused(registry, target, eventname) + end + end + if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then + registry.insertQueue[eventname][self] = nil + end + end + + -- OPTIONAL: Unregister all callbacks for given selfs/addonIds + if UnregisterAllName then + target[UnregisterAllName] = function(...) + if select("#",...)<1 then + error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2) + end + if select("#",...)==1 and ...==target then + error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2) + end + + + for i=1,select("#",...) do + local self = select(i,...) + if registry.insertQueue then + for eventname, callbacks in pairs(registry.insertQueue) do + if callbacks[self] then + callbacks[self] = nil + end + end + end + for eventname, callbacks in pairs(events) do + if callbacks[self] then + callbacks[self] = nil + -- Fire OnUnused callback? + if registry.OnUnused and not next(callbacks) then + registry.OnUnused(registry, target, eventname) + end + end + end + end + end + end + + return registry +end + + +-- CallbackHandler purposefully does NOT do explicit embedding. Nor does it +-- try to upgrade old implicit embeds since the system is selfcontained and +-- relies on closures to work. + diff --git a/Libs/LibStub/LibStub.lua b/Libs/LibStub/LibStub.lua new file mode 100644 index 0000000..0a41ac0 --- /dev/null +++ b/Libs/LibStub/LibStub.lua @@ -0,0 +1,30 @@ +-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info +-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke +local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS! +local LibStub = _G[LIBSTUB_MAJOR] + +if not LibStub or LibStub.minor < LIBSTUB_MINOR then + LibStub = LibStub or {libs = {}, minors = {} } + _G[LIBSTUB_MAJOR] = LibStub + LibStub.minor = LIBSTUB_MINOR + + function LibStub:NewLibrary(major, minor) + assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)") + minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.") + + local oldminor = self.minors[major] + if oldminor and oldminor >= minor then return nil end + self.minors[major], self.libs[major] = minor, self.libs[major] or {} + return self.libs[major], oldminor + end + + function LibStub:GetLibrary(major, silent) + if not self.libs[major] and not silent then + error(("Cannot find a library instance of %q."):format(tostring(major)), 2) + end + return self.libs[major], self.minors[major] + end + + function LibStub:IterateLibraries() return pairs(self.libs) end + setmetatable(LibStub, { __call = LibStub.GetLibrary }) +end diff --git a/README.md b/README.md new file mode 100644 index 0000000..74fc040 --- /dev/null +++ b/README.md @@ -0,0 +1,83 @@ +# SmartBuff Retail + +For clarity, this repository is ONLY for the Retail version of the client and it is not the Classic version. + +SmartBuff is a buff addon to monitor you, your party or raids buffs easily and quickly allowing you to cast those that are missing - all classes are supported. + +Bind a key and it checks if you, a party/raid member or pets needs your buff and casts it. +Use the options menu to configure it you like, as example: buffs, raid subgroups, pets, etc. +Run the mod when ever you wish, if nothing is buffed, there is no penalty or cooldown. + + +## Features: + +- Supports all classes. +- Checks buffs and rebuffs you, raid, party members and pets. +- Setup your own buff templates (Solo, Party, Raid, Battleground, MC, Onyxia, BWL, AQ, ZG, Custom 1-5) +- Auto switch templates when playing solo, in a party or raid etc. +- Individual setup for each buff. +- Supports group buffs: 'Gift of the Wild'/'Arcane Brilliance'/'Prayer of Fortitude'/'Prayer of Spirit', incl. group size and reagence checks. +- Supports class buffs: all greater blessings of the Paladin. +- Supports self buffs. +- Supports weapon buffs (individual for main and off hand): Shaman, all poisons (Rogue), all stones and oils, incl. reagence checks. +- Supports character level based buffs. +- Supports tracking abilities. +- Reminder if a buff is missing (Splash/chat/sound). +- ReBuff Timers. +- Scrollwheel or only one key is needed. +- Fast and easy to use. +- FuBar support. +- Titan Panel support + + + +## Usage: + +Minimap button: +- Left click: opens SmartBuff options frame +- Right click: enables/disables SmartBuff +- Alt-Left click: SmartDebuff +- Shift-Left click: move minimap button + + + +## Commands: + +Type /sbm for options menu in game +Type /sb [command] or /smartbuff [command] in game + +- toggle, Toggles SmartBuff On/Off +- menu, Show/hide options menu +- rbt, reset buff timers +- sdb, SmartDebuff +- rafp, reset all frame positions + +Options frame: +Right click on buff checkbox: opens buff setup frame + + + +## Macro Usage + +If you prefer to use Smartbuff in a macro rather than scrolling your mouse or using the action button then simply use: + +/click SmartBuff_KeyButton + + +## Contact / Support + +You will find me on: +- Classic Server: Mik/Castanova/Amarantine/Paramedic on EU-Mirage Raceway +- Retail: Challenger, Castanova, Paramedic and many others on EU-Aszune + +Join me on discord to offer feedback, report bugs and much more: https://discord.gg/R6EkZ94TKK + +If you would like to help support the addon development please see the addon options screen. + + +## Curse + +The Curse project page can be found here: +https://www.curseforge.com/wow/addons/smartbuff-retail-burning-crusade-classic + + diff --git a/ReadMe.txt b/ReadMe.txt new file mode 100644 index 0000000..d679833 --- /dev/null +++ b/ReadMe.txt @@ -0,0 +1,51 @@ +*********************************************************************** +SmartBuff +*********************************************************************** + +SmartBuff is a buff addon, to cast buffs ease and quickly. All classes are supported. +Bind a key and it checks if you, a party/raid member, also hunter and warlock pets, needs your buff and cast it. +Use the options menu to configure it you like, as example: buffs, raid subgroups, pets, etc. +Run the mod when ever you wish, if nothing is buffed, there is no penalty or cool down. + +Features: +- Supports all classes +- Supports EN/DE/FR clients +- Checks buffs and rebuff you, raid/party members, raid/party pets +- Setup your own buff templates (Solo, Party, Raid, Battleground, MC, Ony, BWL, AQ, ZG, Custom 1-5) +- Auto switch templates +- Individual setup for each buff +- Supports group buffs: 'Gift of the Wild'/'Arcane Brilliance'/'Prayer of Fortitude'/'Prayer of Spirit', incl. group size and reagence check +- Supports class buffs: all greater blessings of the Paladin +- Supports self buffs +- Supports weapon buffs (individual for main and off hand): Shaman, all poisons (Rogue), all stones and oils, incl. reagence check +- Supports character level based buffs +- Supports tracking abilities +- Reminder if a buff is missing (Splash/chat/sound) +- ReBuff Timer +- Scrollwhell or only one key is needed +- Fast and easy to use +- FuBar support +- Titan Panel support + + +Usage: +Minimapbutton: +Left click: opens SmartBuff options frame +Right click: enables/disables SmartBuff +Alt-Left click: SmartDebuff +Shift-Left click: move minimap button + +Chat: +Type /sbm for options menu in game +Type /sb [command] or /smartbuff [command] in game +- cast buff +toggle - Toggles SmartBuff On/Off +menu - Show/hide options menu +rbt - reset buff timers +sdb - SmartDebuff +rafp - reset all frame positions + +Options frame: +Right click on buff checkbox: opens buff setup frame + + diff --git a/SmartBuff.buffs.lua b/SmartBuff.buffs.lua new file mode 100644 index 0000000..3fa7ae6 --- /dev/null +++ b/SmartBuff.buffs.lua @@ -0,0 +1,1425 @@ +local _; +local S = SMARTBUFF_GLOBALS; + +SMARTBUFF_PLAYERCLASS = nil; +SMARTBUFF_BUFFLIST = nil; + +-- Buff types +SMARTBUFF_CONST_ALL = "ALL"; +SMARTBUFF_CONST_GROUP = "GROUP"; +SMARTBUFF_CONST_GROUPALL = "GROUPALL"; +SMARTBUFF_CONST_SELF = "SELF"; +SMARTBUFF_CONST_FORCESELF = "FORCESELF"; +SMARTBUFF_CONST_TRACK = "TRACK"; +SMARTBUFF_CONST_WEAPON = "WEAPON"; +SMARTBUFF_CONST_INV = "INVENTORY"; +SMARTBUFF_CONST_FOOD = "FOOD"; +SMARTBUFF_CONST_SCROLL = "SCROLL"; +SMARTBUFF_CONST_POTION = "POTION"; +SMARTBUFF_CONST_STANCE = "STANCE"; +SMARTBUFF_CONST_ITEM = "ITEM"; +SMARTBUFF_CONST_ITEMGROUP = "ITEMGROUP"; +SMARTBUFF_CONST_TOY = "TOY"; + +S.CheckPet = "CHECKPET"; +S.CheckPetNeeded = "CHECKPETNEEDED"; +S.CheckFishingPole = "CHECKFISHINGPOLE"; +S.NIL = "x"; +S.Toybox = { }; + +local function GetItems(items) + local t = { }; + for _, id in pairs(items) do + local name = GetItemInfo(id); + if (name) then + --print("Item found: "..id..", "..name); + tinsert(t, name); + end + end + return t; +end + +local function InsertItem(t, type, itemId, spellId, duration, link) + local item = GetItemInfo(itemId); + local spell = GetSpellInfo(spellId); + if (item and spell) then + --print("Item found: "..item..", "..spell); + tinsert(t, {item, duration, type, nil, spell, link}); + end +end + +local function AddItem(itemId, spellId, duration, link) + InsertItem(SMARTBUFF_SCROLL, SMARTBUFF_CONST_SCROLL, itemId, spellId, duration, link); +end + +local function LoadToys() + C_ToyBox.SetCollectedShown(true) + C_ToyBox.SetAllSourceTypeFilters(true) + C_ToyBox.SetFilterString("") + + local nTotal = C_ToyBox.GetNumTotalDisplayedToys(); + local nLearned = C_ToyBox.GetNumLearnedDisplayedToys() or 0; + if (nLearned <= 0) then + return; + end + + for i = 1, nTotal do + local num = C_ToyBox.GetToyFromIndex(i); + local id, name, icon = C_ToyBox.GetToyInfo(num); + if (id) then + if (PlayerHasToy(id)) then + S.Toybox[tostring(name)] = {id, icon}; + end + end + end + + SMARTBUFF_AddMsgD("Toys initialized"); +end + +function SMARTBUFF_InitItemList() + -- Stones and oils + SMARTBUFF_HEALTHSTONE = GetItemInfo(5512); --"Healthstone" + SMARTBUFF_MANAGEM = GetItemInfo(36799); --"Mana Gem" + SMARTBUFF_BRILLIANTMANAGEM = GetItemInfo(81901); --"Brilliant Mana Gem" + SMARTBUFF_SSROUGH = GetItemInfo(2862); --"Rough Sharpening Stone" + SMARTBUFF_SSCOARSE = GetItemInfo(2863); --"Coarse Sharpening Stone" + SMARTBUFF_SSHEAVY = GetItemInfo(2871); --"Heavy Sharpening Stone" + SMARTBUFF_SSSOLID = GetItemInfo(7964); --"Solid Sharpening Stone" + SMARTBUFF_SSDENSE = GetItemInfo(12404); --"Dense Sharpening Stone" + SMARTBUFF_SSELEMENTAL = GetItemInfo(18262); --"Elemental Sharpening Stone" + SMARTBUFF_SSFEL = GetItemInfo(23528); --"Fel Sharpening Stone" + SMARTBUFF_SSADAMANTITE = GetItemInfo(23529); --"Adamantite Sharpening Stone" + SMARTBUFF_WSROUGH = GetItemInfo(3239); --"Rough Weightstone" + SMARTBUFF_WSCOARSE = GetItemInfo(3240); --"Coarse Weightstone" + SMARTBUFF_WSHEAVY = GetItemInfo(3241); --"Heavy Weightstone" + SMARTBUFF_WSSOLID = GetItemInfo(7965); --"Solid Weightstone" + SMARTBUFF_WSDENSE = GetItemInfo(12643); --"Dense Weightstone" + SMARTBUFF_WSFEL = GetItemInfo(28420); --"Fel Weightstone" + SMARTBUFF_WSADAMANTITE = GetItemInfo(28421); --"Adamantite Weightstone" + SMARTBUFF_SHADOWOIL = GetItemInfo(3824); --"Shadow Oil" + SMARTBUFF_FROSTOIL = GetItemInfo(3829); --"Frost Oil" + SMARTBUFF_MANAOIL1 = GetItemInfo(20745); --"Minor Mana Oil" + SMARTBUFF_MANAOIL2 = GetItemInfo(20747); --"Lesser Mana Oil" + SMARTBUFF_MANAOIL3 = GetItemInfo(20748); --"Brilliant Mana Oil" + SMARTBUFF_MANAOIL4 = GetItemInfo(22521); --"Superior Mana Oil" + SMARTBUFF_WIZARDOIL1 = GetItemInfo(20744); --"Minor Wizard Oil" + SMARTBUFF_WIZARDOIL2 = GetItemInfo(20746); --"Lesser Wizard Oil" + SMARTBUFF_WIZARDOIL3 = GetItemInfo(20750); --"Wizard Oil" + SMARTBUFF_WIZARDOIL4 = GetItemInfo(20749); --"Brilliant Wizard Oil" + SMARTBUFF_WIZARDOIL5 = GetItemInfo(22522); --"Superior Wizard Oil" + SMARTBUFF_SHADOWCOREOIL = GetItemInfo(171285); --"Shadowcore Oil" + SMARTBUFF_EMBALMERSOIL = GetItemInfo(171286); --"Embalmer's Oil" + -- Food +-- SMARTBUFF_KIBLERSBITS = GetItemInfo(33874); --"Kibler's Bits" +-- SMARTBUFF_STORMCHOPS = GetItemInfo(33866); --"Stormchops" + SMARTBUFF_JUICYBEARBURGER = GetItemInfo(35565); --"Juicy Bear Burger" + SMARTBUFF_CRUNCHYSPIDER = GetItemInfo(22645); --"Crunchy Spider Surprise" + SMARTBUFF_LYNXSTEAK = GetItemInfo(27635); --"Lynx Steak" + SMARTBUFF_CHARREDBEARKABOBS = GetItemInfo(35563); --"Charred Bear Kabobs" + SMARTBUFF_BATBITES = GetItemInfo(27636); --"Bat Bites" + SMARTBUFF_ROASTEDMOONGRAZE = GetItemInfo(24105); --"Roasted Moongraze Tenderloin" + SMARTBUFF_MOKNATHALSHORTRIBS = GetItemInfo(31672); --"Mok'Nathal Shortribs" + SMARTBUFF_CRUNCHYSERPENT = GetItemInfo(31673); --"Crunchy Serpent" + SMARTBUFF_ROASTEDCLEFTHOOF = GetItemInfo(27658); --"Roasted Clefthoof" + SMARTBUFF_FISHERMANSFEAST = GetItemInfo(33052); --"Fisherman's Feast" + SMARTBUFF_WARPBURGER = GetItemInfo(27659); --"Warp Burger" + SMARTBUFF_RAVAGERDOG = GetItemInfo(27655); --"Ravager Dog" + SMARTBUFF_SKULLFISHSOUP = GetItemInfo(33825); --"Skullfish Soup" + SMARTBUFF_BUZZARDBITES = GetItemInfo(27651); --"Buzzard Bites" + SMARTBUFF_TALBUKSTEAK = GetItemInfo(27660); --"Talbuk Steak" + SMARTBUFF_GOLDENFISHSTICKS = GetItemInfo(27666); --"Golden Fish Sticks" + SMARTBUFF_SPICYHOTTALBUK = GetItemInfo(33872); --"Spicy Hot Talbuk" + SMARTBUFF_FELTAILDELIGHT = GetItemInfo(27662); --"Feltail Delight" + SMARTBUFF_BLACKENEDSPOREFISH = GetItemInfo(27663); --"Blackened Sporefish" + SMARTBUFF_HOTAPPLECIDER = GetItemInfo(34411); --"Hot Apple Cider" + SMARTBUFF_BROILEDBLOODFIN = GetItemInfo(33867); --"Broiled Bloodfin" + SMARTBUFF_SPICYCRAWDAD = GetItemInfo(27667); --"Spicy Crawdad" + SMARTBUFF_POACHEDBLUEFISH = GetItemInfo(27665); --"Poached Bluefish" + SMARTBUFF_BLACKENEDBASILISK = GetItemInfo(27657); --"Blackened Basilisk" + SMARTBUFF_GRILLEDMUDFISH = GetItemInfo(27664); --"Grilled Mudfish" + SMARTBUFF_CLAMBAR = GetItemInfo(30155); --"Clam Bar" + SMARTBUFF_SAGEFISHDELIGHT = GetItemInfo(21217); --"Sagefish Delight" + SMARTBUFF_SALTPEPPERSHANK = GetItemInfo(133557); --"Salt & Pepper Shank" + SMARTBUFF_PICKLEDSTORMRAY = GetItemInfo(133562); --"Pickled Stormray" + SMARTBUFF_DROGBARSTYLESALMON = GetItemInfo(133569); --"Drogbar-Style Salmon" + SMARTBUFF_BARRACUDAMRGLGAGH = GetItemInfo(133567); --"Barracuda Mrglgagh" + SMARTBUFF_FIGHTERCHOW = GetItemInfo(133577); --"Fighter Chow" + SMARTBUFF_FARONAARFIZZ = GetItemInfo(133563); --"Faronaar Fizz" + SMARTBUFF_BEARTARTARE = GetItemInfo(133576); --"Bear Tartare" + SMARTBUFF_LEGIONCHILI = GetItemInfo(118428); --"Legion Chili" + SMARTBUFF_DEEPFRIEDMOSSGILL = GetItemInfo(133561); --"Deep-Fried Mossgill" + SMARTBUFF_MONDAZI = GetItemInfo(154885); --"Mon'Dazi" + SMARTBUFF_KULTIRAMISU = GetItemInfo(154881); --"Kul Tiramisu" + SMARTBUFF_GRILLEDCATFISH = GetItemInfo(154889); --"Grilled Catfish" + SMARTBUFF_LOALOAF = GetItemInfo(154887); --"Loa Loaf" + SMARTBUFF_HONEYHAUNCHES = GetItemInfo(154882); --"Honey-Glazed Haunches" + SMARTBUFF_RAVENBERRYTARTS = GetItemInfo(154883); --"Ravenberry Tarts" + SMARTBUFF_SWAMPFISHNCHIPS = GetItemInfo(154884); --"Swamp Fish 'n Chips" + SMARTBUFF_SEASONEDLOINS = GetItemInfo(154891); --"Seasoned Loins" + SMARTBUFF_SAILORSPIE = GetItemInfo(154888); --"Sailor's Pie" + SMARTBUFF_SPICEDSNAPPER = GetItemInfo(154886); --"Spiced Snapper" + --SMARTBUFF_HEARTSBANEHEXWURST = GetItemInfo(163781); --"Heartsbane Hexwurst" + SMARTBUFF_ABYSSALFRIEDRISSOLE = GetItemInfo(168311); --"Abyssal-Fried Rissole" + SMARTBUFF_BAKEDPORTTATO = GetItemInfo(168313); --"Baked Port Tato" + SMARTBUFF_BILTONG = GetItemInfo(168314); --"Bil'Tong" + SMARTBUFF_BIGMECH = GetItemInfo(168310); --"Mech-Dowel's 'Big Mech'" + SMARTBUFF_FRAGRANTKAKAVIA = GetItemInfo(168312); --"Fragrant Kakavia" + SMARTBUFF_BANANABEEFPUDDING = GetItemInfo(172069); --"Banana Beef Pudding" + SMARTBUFF_BUTTERSCOTCHRIBS = GetItemInfo(172040); --"Butterscotch Marinated Ribs" + SMARTBUFF_CINNAMONBONEFISH = GetItemInfo(172044); --"Cinnamon Bonefish Stew" + SMARTBUFF_EXTRALEMONYFILET = GetItemInfo(184682); --"Extra Lemony Herb Filet" + SMARTBUFF_FRIEDBONEFISH = GetItemInfo(172063); --"Friedn Bonefish" + SMARTBUFF_IRIDESCENTRAVIOLI = GetItemInfo(172049); --"Iridescent Ravioli with Apple Sauce" + SMARTBUFF_MEATYAPPLEDUMPLINGS = GetItemInfo(172048); --"Meaty Apple Dumplings" + SMARTBUFF_PICKLEDMEATSMOOTHIE = GetItemInfo(172068); --"Pickled Meat Smoothie" + SMARTBUFF_SERAPHTENDERS = GetItemInfo(172061); --"Seraph Tenders" + SMARTBUFF_SPINEFISHSOUFFLE = GetItemInfo(172041); --"Spinefish Souffle and Fries" + SMARTBUFF_STEAKALAMODE = GetItemInfo(172051); --"Steak ala Mode" + SMARTBUFF_SWEETSILVERGILL = GetItemInfo(172050); --"Sweet Silvergill Sausages" + SMARTBUFF_TENEBROUSCROWNROAST = GetItemInfo(172045); --"Tenebrous Crown Roast Aspic" + + + -- Food item IDs + S.FoodItems = GetItems({ + -- WotLK + 39691, 34125, 42779, 42997, 42998, 42999, 43000, 34767, 42995, 34769, 34754, 34758, 34766, 42994, 42996, 34756, 34768, 42993, 34755, 43001, 34757, 34752, 34751, 34750, 34749, 34764, 34765, 34763, 34762, 42942, 43268, 34748, + -- CT + 62651, 62652, 62653, 62654, 62655, 62656, 62657, 62658, 62659, 62660, 62661, 62662, 62663, 62664, 62665, 62666, 62667, 62668, 62669, 62670, 62671, 62649, + -- MoP + 74645, 74646, 74647, 74648, 74649, 74650, 74652, 74653, 74655, 74656, 86069, 86070, 86073, 86074, 81400, 81401, 81402, 81403, 81404, 81405, 81406, 81408, 81409, 81410, 81411, 81412, 81413, 81414, + -- WoD + 111431, 111432, 111433, 111434, 111435, 111436, 111437, 111438, 111439, 111440, 11441, 111442, 111443, 111444, 111445, 111446, 111447, 111448, 111449, 111450, 111451, 111452, 111453, 111454,127991, 111457, 111458, 118576, + }); + + -- Conjured mage food IDs + SMARTBUFF_CONJUREDMANA = GetItemInfo(113509); --"Conjured Mana Buns" + S.FoodMage = GetItems({113509, 80618, 80610, 65499, 43523, 43518, 34062, 65517, 65516, 65515, 65500, 42955}); + + --SMARTBUFF_BCPETFOOD1 = GetItemInfo(33874); --"Kibler's Bits (Pet food)" + --SMARTBUFF_WOTLKPETFOOD1 = GetItemInfo(43005); --"Spiced Mammoth Treats (Pet food)" + + -- Scrolls + SMARTBUFF_SOAGILITY1 = GetItemInfo(3012); --"Scroll of Agility I" + SMARTBUFF_SOAGILITY2 = GetItemInfo(1477); --"Scroll of Agility II" + SMARTBUFF_SOAGILITY3 = GetItemInfo(4425); --"Scroll of Agility III" + SMARTBUFF_SOAGILITY4 = GetItemInfo(10309); --"Scroll of Agility IV" + SMARTBUFF_SOAGILITY5 = GetItemInfo(27498); --"Scroll of Agility V" + SMARTBUFF_SOAGILITY6 = GetItemInfo(33457); --"Scroll of Agility VI" + SMARTBUFF_SOAGILITY7 = GetItemInfo(43463); --"Scroll of Agility VII" + SMARTBUFF_SOAGILITY8 = GetItemInfo(43464); --"Scroll of Agility VIII" + SMARTBUFF_SOAGILITY9 = GetItemInfo(63303); --"Scroll of Agility IX" + SMARTBUFF_SOINTELLECT1 = GetItemInfo(955); --"Scroll of Intellect I" + SMARTBUFF_SOINTELLECT2 = GetItemInfo(2290); --"Scroll of Intellect II" + SMARTBUFF_SOINTELLECT3 = GetItemInfo(4419); --"Scroll of Intellect III" + SMARTBUFF_SOINTELLECT4 = GetItemInfo(10308); --"Scroll of Intellect IV" + SMARTBUFF_SOINTELLECT5 = GetItemInfo(27499); --"Scroll of Intellect V" + SMARTBUFF_SOINTELLECT6 = GetItemInfo(33458); --"Scroll of Intellect VI" + SMARTBUFF_SOINTELLECT7 = GetItemInfo(37091); --"Scroll of Intellect VII" + SMARTBUFF_SOINTELLECT8 = GetItemInfo(37092); --"Scroll of Intellect VIII" + SMARTBUFF_SOINTELLECT9 = GetItemInfo(63305); --"Scroll of Intellect IX" + SMARTBUFF_SOSTAMINA1 = GetItemInfo(1180); --"Scroll of Stamina I" + SMARTBUFF_SOSTAMINA2 = GetItemInfo(1711); --"Scroll of Stamina II" + SMARTBUFF_SOSTAMINA3 = GetItemInfo(4422); --"Scroll of Stamina III" + SMARTBUFF_SOSTAMINA4 = GetItemInfo(10307); --"Scroll of Stamina IV" + SMARTBUFF_SOSTAMINA5 = GetItemInfo(27502); --"Scroll of Stamina V" + SMARTBUFF_SOSTAMINA6 = GetItemInfo(33461); --"Scroll of Stamina VI" + SMARTBUFF_SOSTAMINA7 = GetItemInfo(37093); --"Scroll of Stamina VII" + SMARTBUFF_SOSTAMINA8 = GetItemInfo(37094); --"Scroll of Stamina VIII" + SMARTBUFF_SOSTAMINA9 = GetItemInfo(63306); --"Scroll of Stamina IX" + SMARTBUFF_SOSPIRIT1 = GetItemInfo(1181); --"Scroll of Spirit I" + SMARTBUFF_SOSPIRIT2 = GetItemInfo(1712); --"Scroll of Spirit II" + SMARTBUFF_SOSPIRIT3 = GetItemInfo(4424); --"Scroll of Spirit III" + SMARTBUFF_SOSPIRIT4 = GetItemInfo(10306); --"Scroll of Spirit IV" + SMARTBUFF_SOSPIRIT5 = GetItemInfo(27501); --"Scroll of Spirit V" + SMARTBUFF_SOSPIRIT6 = GetItemInfo(33460); --"Scroll of Spirit VI" + SMARTBUFF_SOSPIRIT7 = GetItemInfo(37097); --"Scroll of Spirit VII" + SMARTBUFF_SOSPIRIT8 = GetItemInfo(37098); --"Scroll of Spirit VIII" + SMARTBUFF_SOSPIRIT9 = GetItemInfo(63307); --"Scroll of Spirit IX" + SMARTBUFF_SOSTRENGHT1 = GetItemInfo(954); --"Scroll of Strength I" + SMARTBUFF_SOSTRENGHT2 = GetItemInfo(2289); --"Scroll of Strength II" + SMARTBUFF_SOSTRENGHT3 = GetItemInfo(4426); --"Scroll of Strength III" + SMARTBUFF_SOSTRENGHT4 = GetItemInfo(10310); --"Scroll of Strength IV" + SMARTBUFF_SOSTRENGHT5 = GetItemInfo(27503); --"Scroll of Strength V" + SMARTBUFF_SOSTRENGHT6 = GetItemInfo(33462); --"Scroll of Strength VI" + SMARTBUFF_SOSTRENGHT7 = GetItemInfo(43465); --"Scroll of Strength VII" + SMARTBUFF_SOSTRENGHT8 = GetItemInfo(43466); --"Scroll of Strength VIII" + SMARTBUFF_SOSTRENGHT9 = GetItemInfo(63304); --"Scroll of Strength IX" + SMARTBUFF_SOPROTECTION9 = GetItemInfo(63308); --"Scroll of Protection IX" + + SMARTBUFF_MiscItem1 = GetItemInfo(178512); --"Celebration Package" + SMARTBUFF_MiscItem2 = GetItemInfo(44986); --"Warts-B-Gone Lip Balm" + SMARTBUFF_MiscItem3 = GetItemInfo(69775); --"Vrykul Drinking Horn" + SMARTBUFF_MiscItem4 = GetItemInfo(86569); --"Crystal of Insanity" + SMARTBUFF_MiscItem5 = GetItemInfo(85500); --"Anglers Fishing Raft" + SMARTBUFF_MiscItem6 = GetItemInfo(85973); --"Ancient Pandaren Fishing Charm" + SMARTBUFF_MiscItem7 = GetItemInfo(94604); --"Burning Seed" + SMARTBUFF_MiscItem9 = GetItemInfo(92738); --"Safari Hat" + SMARTBUFF_MiscItem10 = GetItemInfo(110424); --"Savage Safari Hat" + SMARTBUFF_MiscItem11 = GetItemInfo(118922); --"Oralius' Whispering Crystal" + SMARTBUFF_MiscItem12 = GetItemInfo(129192); --"Inquisitor's Menacing Eye" + SMARTBUFF_MiscItem13 = GetItemInfo(129210); --"Fel Crystal Fragments" + SMARTBUFF_MiscItem14 = GetItemInfo(128475); --"Empowered Augment Rune" + SMARTBUFF_MiscItem15 = GetItemInfo(128482); --"Empowered Augment Rune" + SMARTBUFF_MiscItem17 = GetItemInfo(147707); --"Repurposed Fel Focuser" + + SMARTBUFF_AugmentRune = GetItemInfo(190384); --"Eternal Augment Rune" + SMARTBUFF_VieledAugment = GetItemInfo(181468); --"Veiled Augment Rune" + + SMARTBUFF_FLASKTBC1 = GetItemInfo(22854); --"Flask of Relentless Assault" + SMARTBUFF_FLASKTBC2 = GetItemInfo(22866); --"Flask of Pure Death" + SMARTBUFF_FLASKTBC3 = GetItemInfo(22851); --"Flask of Fortification" + SMARTBUFF_FLASKTBC4 = GetItemInfo(22861); --"Flask of Blinding Light" + SMARTBUFF_FLASKTBC5 = GetItemInfo(22853); --"Flask of Mighty Versatility" + SMARTBUFF_FLASK1 = GetItemInfo(46377); --"Flask of Endless Rage" + SMARTBUFF_FLASK2 = GetItemInfo(46376); --"Flask of the Frost Wyrm" + SMARTBUFF_FLASK3 = GetItemInfo(46379); --"Flask of Stoneblood" + SMARTBUFF_FLASK4 = GetItemInfo(46378); --"Flask of Pure Mojo" + SMARTBUFF_FLASKCT1 = GetItemInfo(58087); --"Flask of the Winds" + SMARTBUFF_FLASKCT2 = GetItemInfo(58088); --"Flask of Titanic Strength" + SMARTBUFF_FLASKCT3 = GetItemInfo(58086); --"Flask of the Draconic Mind" + SMARTBUFF_FLASKCT4 = GetItemInfo(58085); --"Flask of Steelskin" + SMARTBUFF_FLASKCT5 = GetItemInfo(67438); --"Flask of Flowing Water" + SMARTBUFF_FLASKCT7 = GetItemInfo(65455); --"Flask of Battle" + SMARTBUFF_FLASKMOP1 = GetItemInfo(75525); --"Alchemist's Flask" + SMARTBUFF_FLASKMOP2 = GetItemInfo(76087); --"Flask of the Earth" + SMARTBUFF_FLASKMOP3 = GetItemInfo(76086); --"Flask of Falling Leaves" + SMARTBUFF_FLASKMOP4 = GetItemInfo(76084); --"Flask of Spring Blossoms" + SMARTBUFF_FLASKMOP5 = GetItemInfo(76085); --"Flask of the Warm Sun" + SMARTBUFF_FLASKMOP6 = GetItemInfo(76088); --"Flask of Winter's Bite" + SMARTBUFF_FLASKWOD1 = GetItemInfo(109152); --"Draenic Stamina Flask" + SMARTBUFF_FLASKWOD2 = GetItemInfo(109148); --"Draenic Strength Flask" + SMARTBUFF_FLASKWOD3 = GetItemInfo(109147); --"Draenic Intellect Flask" + SMARTBUFF_FLASKWOD4 = GetItemInfo(109145); --"Draenic Agility Flask" + SMARTBUFF_GRFLASKWOD1 = GetItemInfo(109160); --"Greater Draenic Stamina Flask" + SMARTBUFF_GRFLASKWOD2 = GetItemInfo(109156); --"Greater Draenic Strength Flask" + SMARTBUFF_GRFLASKWOD3 = GetItemInfo(109155); --"Greater Draenic Intellect Flask" + SMARTBUFF_GRFLASKWOD4 = GetItemInfo(109153); --"Greater Draenic Agility Flask" + SMARTBUFF_FLASKLEG1 = GetItemInfo(127850); --"Flask of Ten Thousand Scars" + SMARTBUFF_FLASKLEG2 = GetItemInfo(127849); --"Flask of the Countless Armies" + SMARTBUFF_FLASKLEG3 = GetItemInfo(127847); --"Flask of the Whispered Pact" + SMARTBUFF_FLASKLEG4 = GetItemInfo(127848); --"Flask of the Seventh Demon" + SMARTBUFF_FLASKBFA1 = GetItemInfo(152639); --"Flask of Endless Fathoms" + SMARTBUFF_FLASKBFA2 = GetItemInfo(152638); --"Flask of the Currents" + SMARTBUFF_FLASKBFA3 = GetItemInfo(152641); --"Flask of the Undertow" + SMARTBUFF_FLASKBFA4 = GetItemInfo(152640); --"Flask of the Vast Horizon" + SMARTBUFF_GRFLASKBFA1 = GetItemInfo(168652); --"Greather Flask of Endless Fathoms" + SMARTBUFF_GRFLASKBFA2 = GetItemInfo(168651); --"Greater Flask of the Currents" + SMARTBUFF_GRFLASKBFA3 = GetItemInfo(168654); --"Greather Flask of teh Untertow" + SMARTBUFF_GRFLASKBFA4 = GetItemInfo(168653); --"Greater Flask of the Vast Horizon" + SMARTBUFF_FLASKSL1 = GetItemInfo(171276); --"Spectral Flask of Power" + SMARTBUFF_FLASKSL2 = GetItemInfo(171278); --"Spectral Flask of Stamina" + + SMARTBUFF_ELIXIRTBC1 = GetItemInfo(22831); --"Elixir of Major Agility" + SMARTBUFF_ELIXIRTBC2 = GetItemInfo(28104); --"Elixir of Mastery" + SMARTBUFF_ELIXIRTBC3 = GetItemInfo(22825); --"Elixir of Healing Power" + SMARTBUFF_ELIXIRTBC4 = GetItemInfo(22834); --"Elixir of Major Defense" + SMARTBUFF_ELIXIRTBC5 = GetItemInfo(22824); --"Elixir of Major Strangth" + SMARTBUFF_ELIXIRTBC6 = GetItemInfo(32062); --"Elixir of Major Fortitude" + SMARTBUFF_ELIXIRTBC7 = GetItemInfo(22840); --"Elixir of Major Mageblood" + SMARTBUFF_ELIXIRTBC8 = GetItemInfo(32067); --"Elixir of Draenic Wisdom" + SMARTBUFF_ELIXIRTBC9 = GetItemInfo(28103); --"Adept's Elixir" + SMARTBUFF_ELIXIRTBC10 = GetItemInfo(22848); --"Elixir of Empowerment" + SMARTBUFF_ELIXIRTBC11 = GetItemInfo(28102); --"Onslaught Elixir" + SMARTBUFF_ELIXIRTBC12 = GetItemInfo(22835); --"Elixir of Major Shadow Power" + SMARTBUFF_ELIXIRTBC13 = GetItemInfo(32068); --"Elixir of Ironskin" + SMARTBUFF_ELIXIRTBC14 = GetItemInfo(32063); --"Earthen Elixir" + SMARTBUFF_ELIXIRTBC15 = GetItemInfo(22827); --"Elixir of Major Frost Power" + SMARTBUFF_ELIXIRTBC16 = GetItemInfo(31679); --"Fel Strength Elixir" + SMARTBUFF_ELIXIRTBC17 = GetItemInfo(22833); --"Elixir of Major Firepower" + SMARTBUFF_ELIXIR1 = GetItemInfo(39666); --"Elixir of Mighty Agility" + SMARTBUFF_ELIXIR2 = GetItemInfo(44332); --"Elixir of Mighty Thoughts" + SMARTBUFF_ELIXIR3 = GetItemInfo(40078); --"Elixir of Mighty Fortitude" + SMARTBUFF_ELIXIR4 = GetItemInfo(40073); --"Elixir of Mighty Strength" + SMARTBUFF_ELIXIR5 = GetItemInfo(40072); --"Elixir of Spirit" + SMARTBUFF_ELIXIR6 = GetItemInfo(40097); --"Elixir of Protection" + SMARTBUFF_ELIXIR7 = GetItemInfo(44328); --"Elixir of Mighty Defense" + SMARTBUFF_ELIXIR8 = GetItemInfo(44331); --"Elixir of Lightning Speed" + SMARTBUFF_ELIXIR9 = GetItemInfo(44329); --"Elixir of Expertise" + SMARTBUFF_ELIXIR10 = GetItemInfo(44327); --"Elixir of Deadly Strikes" + SMARTBUFF_ELIXIR11 = GetItemInfo(44330); --"Elixir of Armor Piercing" + SMARTBUFF_ELIXIR12 = GetItemInfo(44325); --"Elixir of Accuracy" + SMARTBUFF_ELIXIR13 = GetItemInfo(40076); --"Guru's Elixir" + SMARTBUFF_ELIXIR14 = GetItemInfo(9187); --"Elixir of Greater Agility" + SMARTBUFF_ELIXIR15 = GetItemInfo(28103); --"Adept's Elixir" + SMARTBUFF_ELIXIR16 = GetItemInfo(40070); --"Spellpower Elixir" + SMARTBUFF_ELIXIRCT1 = GetItemInfo(58148); --"Elixir of the Master" + SMARTBUFF_ELIXIRCT2 = GetItemInfo(58144); --"Elixir of Mighty Speed" + SMARTBUFF_ELIXIRCT3 = GetItemInfo(58094); --"Elixir of Impossible Accuracy" + SMARTBUFF_ELIXIRCT4 = GetItemInfo(58143); --"Prismatic Elixir" + SMARTBUFF_ELIXIRCT5 = GetItemInfo(58093); --"Elixir of Deep Earth" + SMARTBUFF_ELIXIRCT6 = GetItemInfo(58092); --"Elixir of the Cobra" + SMARTBUFF_ELIXIRCT7 = GetItemInfo(58089); --"Elixir of the Naga" + SMARTBUFF_ELIXIRCT8 = GetItemInfo(58084); --"Ghost Elixir" + SMARTBUFF_ELIXIRMOP1 = GetItemInfo(76081); --"Elixir of Mirrors" + SMARTBUFF_ELIXIRMOP2 = GetItemInfo(76079); --"Elixir of Peace" + SMARTBUFF_ELIXIRMOP3 = GetItemInfo(76080); --"Elixir of Perfection" + SMARTBUFF_ELIXIRMOP4 = GetItemInfo(76078); --"Elixir of the Rapids" + SMARTBUFF_ELIXIRMOP5 = GetItemInfo(76077); --"Elixir of Weaponry" + SMARTBUFF_ELIXIRMOP6 = GetItemInfo(76076); --"Mad Hozen Elixir" + SMARTBUFF_ELIXIRMOP7 = GetItemInfo(76075); --"Mantid Elixir" + SMARTBUFF_ELIXIRMOP8 = GetItemInfo(76083); --"Monk's Elixir" + + -- Draught of Ten Lands + SMARTBUFF_EXP_POTION = GetItemInfo(166750); --"Draught of Ten Lands" + + -- fishing pole + _, _, _, _, _, _, S.FishingPole = GetItemInfo(6256); --"Fishing Pole" + + SMARTBUFF_AddMsgD("Item list initialized"); + -- i still want to load them regardless of the option to turn them off/hide them + -- so that my settings are preserved and loaded should i turn it back on. + LoadToys(); +end + + +function SMARTBUFF_InitSpellIDs() + SMARTBUFF_TESTSPELL = GetSpellInfo(774); + + -- Druid + SMARTBUFF_DRUID_CAT = GetSpellInfo(768); --"Cat Form" + SMARTBUFF_DRUID_TREE = GetSpellInfo(33891); --"Incarnation: Tree of Life" + SMARTBUFF_DRUID_TREANT = GetSpellInfo(114282);--"Treant Form" + SMARTBUFF_DRUID_MOONKIN = GetSpellInfo(24858); --"Moonkin Form" + --SMARTBUFF_DRUID_MKAURA = GetSpellInfo(24907); --"Moonkin Aura" + SMARTBUFF_DRUID_TRACK = GetSpellInfo(5225); --"Track Humanoids" + SMARTBUFF_MOTW = GetSpellInfo(1126); --"Mark of the Wild" + SMARTBUFF_BARKSKIN = GetSpellInfo(22812); --"Barkskin" + SMARTBUFF_TIGERSFURY = GetSpellInfo(5217); --"Tiger's Fury" + SMARTBUFF_SAVAGEROAR = GetSpellInfo(52610); --"Savage Roar" + SMARTBUFF_CENARIONWARD = GetSpellInfo(102351);--"Cenarion Ward" + SMARTBUFF_DRUID_BEAR = GetSpellInfo(5487); --"Bear Form" + + -- Priest + SMARTBUFF_PWF = GetSpellInfo(21562); --"Power Word: Fortitude" + SMARTBUFF_PWS = GetSpellInfo(17); --"Power Word: Shield" + --SMARTBUFF_FEARWARD = GetSpellInfo(6346); --"Fear Ward" + SMARTBUFF_RENEW = GetSpellInfo(139); --"Renew" + SMARTBUFF_LEVITATE = GetSpellInfo(1706); --"Levitate" + SMARTBUFF_SHADOWFORM = GetSpellInfo(232698); --"Shadowform" + SMARTBUFF_VAMPIRICEMBRACE = GetSpellInfo(15286); --"Vampiric Embrace" + --SMARTBUFF_LIGHTWELL = GetSpellInfo(724); --"Lightwell" + --SMARTBUFF_CHAKRA1 = GetSpellInfo(81206) --"Chakra Sanctuary" + --SMARTBUFF_CHAKRA2 = GetSpellInfo(81208) --"Chakra Serenity" + --SMARTBUFF_CHAKRA3 = GetSpellInfo(81209) --"Chakra Chastise" + -- Priest buff links + S.LinkPriestChakra = { SMARTBUFF_CHAKRA1, SMARTBUFF_CHAKRA2, SMARTBUFF_CHAKRA3 }; + + -- Mage + SMARTBUFF_AB = GetSpellInfo(1459); --"Arcane Intellect" + SMARTBUFF_DALARANB = GetSpellInfo(61316); --"Dalaran Brilliance" + SMARTBUFF_FROSTARMOR = GetSpellInfo(7302); --"Frost Armor" + SMARTBUFF_MAGEARMOR = GetSpellInfo(6117); --"Mage Armor" + --SMARTBUFF_MOLTENARMOR = GetSpellInfo(30482); --"Molten Armor" + SMARTBUFF_MANASHIELD = GetSpellInfo(35064); --"Mana Shield" + --SMARTBUFF_ICEWARD = GetSpellInfo(111264);--"Ice Ward" + SMARTBUFF_ICEBARRIER = GetSpellInfo(11426); --"Ice Barrier" + --SMARTBUFF_COMBUSTION = GetSpellInfo(11129); --"Combustion" + SMARTBUFF_ARCANEPOWER = GetSpellInfo(12042); --"Arcane Power" + SMARTBUFF_PRESENCEOFMIND = GetSpellInfo(205025); --"Presence of Mind" + SMARTBUFF_ICYVEINS = GetSpellInfo(12472); --"Icy Veins" + SMARTBUFF_SUMMONWATERELE = GetSpellInfo(31687); --"Summon Water Elemental" + SMARTBUFF_SLOWFALL = GetSpellInfo(130); --"Slow Fall" + SMARTBUFF_REFRESHMENT = GetSpellInfo(42955); --"Conjure Refreshment" + SMARTBUFF_TEMPSHIELD = GetSpellInfo(198111);--"Temporal Shield" + --SMARTBUFF_AMPMAGIC = GetSpellInfo(159916);--"Amplify Magic" + + SMARTBUFF_PRISBARRIER = GetSpellInfo(235450);--"Prismatic Barrier" + SMARTBUFF_IMPPRISBARRIER = GetSpellInfo(321745);--"Improved Prismatic Barrier" + + SMARTBUFF_BLAZBARRIER = GetSpellInfo(235313);--"Blazing Barrier" + SMARTBUFF_ARCANEFAMILIAR = GetSpellInfo(205022);--"Arcane Familiar" + SMARTBUFF_CREATEMG = GetSpellInfo(759); --"Conjure Mana Gem" + + -- Mage buff links + S.ChainMageArmor = { SMARTBUFF_FROSTARMOR, SMARTBUFF_MAGEARMOR, SMARTBUFF_MOLTENARMOR }; + + -- Warlock + SMARTBUFF_AMPLIFYCURSE = GetSpellInfo(328774);--"Amplify Curse" + SMARTBUFF_DEMONARMOR = GetSpellInfo(285933);--"Demon ARmor" + SMARTBUFF_DARKINTENT = GetSpellInfo(183582);--"Dark Intent" + SMARTBUFF_UNENDINGBREATH = GetSpellInfo(5697); --"Unending Breath" + SMARTBUFF_SOULLINK = GetSpellInfo(108447);--"Soul Link" + SMARTBUFF_LIFETAP = GetSpellInfo(1454); --"Life Tap" + SMARTBUFF_CREATEHS = GetSpellInfo(6201); --"Create Healthstone" + SMARTBUFF_SOULSTONE = GetSpellInfo(20707); --"Soulstone" + SMARTBUFF_GOSACRIFICE = GetSpellInfo(108503);--"Grimoire of Sacrifice" + SMARTBUFF_INQUISITORGAZE = GetSpellInfo(386344);--"Inquisitor's Gaze" + + -- Hunter + SMARTBUFF_TRUESHOTAURA = GetSpellInfo(193526); --"Trueshot Aura" (P) + SMARTBUFF_VOLLEY = GetSpellInfo(194386); --"Volley" + SMARTBUFF_RAPIDFIRE = GetSpellInfo(3045); --"Rapid Fire" + SMARTBUFF_FOCUSFIRE = GetSpellInfo(82692); --"Focus Fire" + --SMARTBUFF_TRAPLAUNCHER = GetSpellInfo(77769); --"Trap Launcher" + --SMARTBUFF_CAMOFLAUGE = GetSpellInfo(51753); --"Camoflauge" + SMARTBUFF_AOTC = GetSpellInfo(186257); --"Aspect of the Cheetah" + --SMARTBUFF_AOTP = GetSpellInfo(13159); --"Aspect of the Pack" + --SMARTBUFF_AOTF = GetSpellInfo(172106); --"Aspect of the Fox" + SMARTBUFF_AOTW = GetSpellInfo(193530); --"Aspect of the Wild" + SMARTBUFF_AMMOI = GetSpellInfo(162536); --"Incendiary Ammo" + SMARTBUFF_AMMOP = GetSpellInfo(162537); --"Poisoned Ammo" + SMARTBUFF_AMMOF = GetSpellInfo(162539); --"Frozen Ammo" + --SMARTBUFF_LW1 = GetSpellInfo(160200); --"Lone Wolf: Ferocity of the Raptor" + --SMARTBUFF_LW2 = GetSpellInfo(160203); --"Lone Wolf: Haste of the Hyena" + --SMARTBUFF_LW3 = GetSpellInfo(160198); --"Lone Wolf: Grace of the Cat" + --SMARTBUFF_LW4 = GetSpellInfo(160206); --"Lone Wolf: Power of the Primates" + --SMARTBUFF_LW5 = GetSpellInfo(160199); --"Lone Wolf: Fortitude of the Bear" + --SMARTBUFF_LW6 = GetSpellInfo(160205); --"Lone Wolf: Wisdom of the Serpent" + --SMARTBUFF_LW7 = GetSpellInfo(172967); --"Lone Wolf: Versatility of the Ravager" + --SMARTBUFF_LW8 = GetSpellInfo(172968); --"Lone Wolf: Quickness of the Dragonhawk" + -- Hunter buff links + S.LinkAspects = { SMARTBUFF_AOTF, SMARTBUFF_AOTC, SMARTBUFF_AOTP, SMARTBUFF_AOTW }; + S.LinkAmmo = { SMARTBUFF_AMMOI, SMARTBUFF_AMMOP, SMARTBUFF_AMMOF }; + S.LinkLoneWolf = { SMARTBUFF_LW1, SMARTBUFF_LW2, SMARTBUFF_LW3, SMARTBUFF_LW4, SMARTBUFF_LW5, SMARTBUFF_LW6, SMARTBUFF_LW7, SMARTBUFF_LW8 }; + + -- Shaman + SMARTBUFF_LIGHTNINGSHIELD = GetSpellInfo(192106); --"Lightning Shield" + SMARTBUFF_WATERSHIELD = GetSpellInfo(52127); --"Water Shield" + SMARTBUFF_EARTHSHIELD = GetSpellInfo(974); --"Earth Shield" + SMARTBUFF_WATERWALKING = GetSpellInfo(546); --"Water Walking" + SMARTBUFF_EMASTERY = GetSpellInfo(16166); --"Elemental Mastery" + SMARTBUFF_ASCENDANCE_ELE = GetSpellInfo(114050); --"Ascendance (Elemental)" + SMARTBUFF_ASCENDANCE_ENH = GetSpellInfo(114051); --"Ascendance (Enhancement)" + SMARTBUFF_ASCENDANCE_RES = GetSpellInfo(114052); --"Ascendance (Restoration)" + SMARTBUFF_WINDFURYW = GetSpellInfo(33757); --"Windfury Weapon" + SMARTBUFF_FLAMETONGUEW = GetSpellInfo(318038); --"Flametongue Weapon" + SMARTBUFF_EVERLIVINGW = GetSpellInfo(382021); --"Everliving Weapon" + + -- Shaman buff links + S.ChainShamanShield = { SMARTBUFF_LIGHTNINGSHIELD, SMARTBUFF_WATERSHIELD, SMARTBUFF_EARTHSHIELD }; + + -- Warrior + SMARTBUFF_BATTLESHOUT = GetSpellInfo(6673); --"Battle Shout" + --SMARTBUFF_COMMANDINGSHOUT = GetSpellInfo(97462); --"Reallying Cry" + SMARTBUFF_BERSERKERRAGE = GetSpellInfo(18499); --"Berserker Rage" + SMARTBUFF_BATSTANCE = GetSpellInfo(386164); --"Battle Stance" + SMARTBUFF_DEFSTANCE = GetSpellInfo(197690); --"Defensive Stance" + SMARTBUFF_GLADSTANCE = GetSpellInfo(156291); --"Gladiator Stance" + SMARTBUFF_SHIELDBLOCK = GetSpellInfo(2565); --"Shield Block" + + -- Warrior buff links + S.ChainWarriorStance = { SMARTBUFF_BATSTANCE, SMARTBUFF_DEFSTANCE, SMARTBUFF_GLADSTANCE }; + S.ChainWarriorShout = { SMARTBUFF_BATTLESHOUT, SMARTBUFF_COMMANDINGSHOUT }; + + -- Rogue + SMARTBUFF_STEALTH = GetSpellInfo(1784); --"Stealth" + SMARTBUFF_BLADEFLURRY = GetSpellInfo(13877); --"Blade Flurry" + SMARTBUFF_SAD = GetSpellInfo(5171); --"Slice and Dice" + SMARTBUFF_EVASION = GetSpellInfo(5277); --"Evasion" + SMARTBUFF_HUNGERFORBLOOD = GetSpellInfo(60177); --"Hunger For Blood" + SMARTBUFF_TRICKS = GetSpellInfo(57934); --"Tricks of the Trade" + SMARTBUFF_RECUPERATE = GetSpellInfo(185311); --"Crimson Vial + -- Poisons + SMARTBUFF_WOUNDPOISON = GetSpellInfo(8679); --"Wound Poison" + SMARTBUFF_CRIPPLINGPOISON = GetSpellInfo(3408); --"Crippling Poison" + SMARTBUFF_DEADLYPOISON = GetSpellInfo(2823); --"Deadly Poison" + SMARTBUFF_LEECHINGPOISON = GetSpellInfo(108211); --"Leeching Poison" + SMARTBUFF_INSTANTPOISON = GetSpellInfo(315584); --"Instant Poison" + SMARTBUFF_NUMBINGPOISON = GetSpellInfo(5761); --"Numbing Poison" + SMARTBUFF_AMPLIFYPOISON = GetSpellInfo(381664); --"Amplifying Poison" + SMARTBUFF_ATROPHICPOISON = GetSpellInfo(381637); --"Atrophic Poison" + + -- Rogue buff links + S.ChainRoguePoisonsLethal = { SMARTBUFF_DEADLYPOISON, SMARTBUFF_WOUNDPOISON, SMARTBUFF_INSTANTPOISON, SMARTBUFF_AGONIZINGPOISON, SMARTBUFF_AMPLIFYPOISON }; + S.ChainRoguePoisonsNonLethal = { SMARTBUFF_CRIPPLINGPOISON, SMARTBUFF_LEECHINGPOISON, SMARTBUFF_NUMBINGPOISON, SMARTBUFF_ATROPHICPOISON }; + + -- Paladin + SMARTBUFF_RIGHTEOUSFURY = GetSpellInfo(25780); --"Righteous Fury" +-- SMARTBUFF_HOLYSHIELD = GetSpellInfo(20925); --"Sacred Shield" + SMARTBUFF_BOK = GetSpellInfo(203538); --"Greater Blessing of Kings" +-- SMARTBUFF_BOM = GetSpellInfo(203528); --"Greater Blessing of Might" + SMARTBUFF_BOW = GetSpellInfo(203539); --"Greater Blessing of Wisdom" + SMARTBUFF_HOF = GetSpellInfo(1044); --"Blessing of Freedom" + SMARTBUFF_HOP = GetSpellInfo(1022); --"Blessing of Protection" + SMARTBUFF_HOSAL = GetSpellInfo(204013); --"Blessing of Salvation" +-- SMARTBUFF_SOJUSTICE = GetSpellInfo(20164); --"Seal of Justice" +-- SMARTBUFF_SOINSIGHT = GetSpellInfo(20165); --"Seal of Insight" +-- SMARTBUFF_SORIGHTEOUSNESS = GetSpellInfo(20154); --"Seal of Righteousness" +-- SMARTBUFF_SOTRUTH = GetSpellInfo(31801); --"Seal of Truth" +-- SMARTBUFF_SOCOMMAND = GetSpellInfo(105361); --"Seal of Command" + SMARTBUFF_AVENGINGWARTH = GetSpellInfo(31884); --"Avenging Wrath" + SMARTBUFF_BEACONOFLIGHT = GetSpellInfo(53563); --"Beacon of Light" + SMARTBUFF_BEACONOFAITH = GetSpellInfo(156910); --"Beacon of Faith" + SMARTBUFF_CRUSADERAURA = GetSpellInfo(32223); --"Crusader Aura" + SMARTBUFF_DEVOTIONAURA = GetSpellInfo(465); --"Devotion Aura" + SMARTBUFF_RETRIBUTIONAURA = GetSpellInfo(183435); --"Retribution Aura" + -- Paladin buff links + S.ChainPaladinAura = { SMARTBUFF_DEVOTIONAURA, SMARTBUFF_RETRIBUTIONAURA }; + S.ChainPaladinSeal = { SMARTBUFF_SOCOMMAND, SMARTBUFF_SOTRUTH, SMARTBUFF_SOJUSTICE, SMARTBUFF_SOINSIGHT, SMARTBUFF_SORIGHTEOUSNESS }; + S.ChainPaladinBlessing = { SMARTBUFF_BOK, SMARTBUFF_BOM, SMARTBUFF_BOW}; + + -- Death Knight + SMARTBUFF_DANCINGRW = GetSpellInfo(49028); --"Dancing Rune Weapon" +-- SMARTBUFF_BLOODPRESENCE = GetSpellInfo(48263); --"Blood Presence" +-- SMARTBUFF_FROSTPRESENCE = GetSpellInfo(48266); --"Frost Presence" +-- SMARTBUFF_UNHOLYPRESENCE = GetSpellInfo(48265); --"Unholy Presence" + SMARTBUFF_PATHOFFROST = GetSpellInfo(3714); --"Path of Frost" +-- SMARTBUFF_BONESHIELD = GetSpellInfo(49222); --"Bone Shield" + SMARTBUFF_HORNOFWINTER = GetSpellInfo(57330); --"Horn of Winter" + SMARTBUFF_RAISEDEAD = GetSpellInfo(46584); --"Raise Dead" +-- SMARTBUFF_POTGRAVE = GetSpellInfo(155522); --"Power of the Grave" (P) + -- Death Knight buff links + S.ChainDKPresence = { SMARTBUFF_BLOODPRESENCE, SMARTBUFF_FROSTPRESENCE, SMARTBUFF_UNHOLYPRESENCE }; + + -- Monk +-- SMARTBUFF_LOTWT = GetSpellInfo(116781); --"Legacy of the White Tiger" +-- SMARTBUFF_LOTE = GetSpellInfo(115921); --"Legacy of the Emperor" + SMARTBUFF_BLACKOX = GetSpellInfo(115315); --"Summon Black Ox Statue" + SMARTBUFF_JADESERPENT = GetSpellInfo(115313); --"Summon Jade Serpent Statue" + SMARTBUFF_SOTFIERCETIGER = GetSpellInfo(103985); --"Stance of the Fierce Tiger" + SMARTBUFF_SOTSTURDYOX = GetSpellInfo(115069); --"Stagger" +-- SMARTBUFF_SOTWISESERPENT = GetSpellInfo(115070); --"Stance of the Wise Serpent" +-- SMARTBUFF_SOTSPIRITEDCRANE= GetSpellInfo(154436); --"Stance of the Spirited Crane" + + -- Monk buff links + S.ChainMonkStatue = { SMARTBUFF_BLACKOX, SMARTBUFF_JADESERPENT }; + S.ChainMonkStance = { SMARTBUFF_SOTFIERCETIGER, SMARTBUFF_SOTSTURDYOX, SMARTBUFF_SOTWISESERPENT, SMARTBUFF_SOTSPIRITEDCRANE }; + + -- Evoker + SMARTBUFF_BRONZEBLESSING = GetSpellInfo(364342); --"Blessing of the Bronze" + + -- Demon Hunter + + + -- Tracking + SMARTBUFF_FINDMINERALS = GetSpellInfo(2580); --"Find Minerals" + SMARTBUFF_FINDHERBS = GetSpellInfo(2383); --"Find Herbs" + SMARTBUFF_FINDTREASURE = GetSpellInfo(2481); --"Find Treasure" + SMARTBUFF_TRACKHUMANOIDS = GetSpellInfo(19883); --"Track Humanoids" + SMARTBUFF_TRACKBEASTS = GetSpellInfo(1494); --"Track Beasts" + SMARTBUFF_TRACKUNDEAD = GetSpellInfo(19884); --"Track Undead" + SMARTBUFF_TRACKHIDDEN = GetSpellInfo(19885); --"Track Hidden" + SMARTBUFF_TRACKELEMENTALS = GetSpellInfo(19880); --"Track Elementals" + SMARTBUFF_TRACKDEMONS = GetSpellInfo(19878); --"Track Demons" + SMARTBUFF_TRACKGIANTS = GetSpellInfo(19882); --"Track Giants" + SMARTBUFF_TRACKDRAGONKIN = GetSpellInfo(19879); --"Track Dragonkin" + + -- Racial + SMARTBUFF_STONEFORM = GetSpellInfo(20594); --"Stoneform" + SMARTBUFF_BLOODFURY = GetSpellInfo(20572); --"Blood Fury" 33697, 33702 + SMARTBUFF_BERSERKING = GetSpellInfo(26297); --"Berserking" + SMARTBUFF_WOTFORSAKEN = GetSpellInfo(7744); --"Will of the Forsaken" + SMARTBUFF_WarStomp = GetSpellInfo(20549); --"War Stomp" + + -- Food + SMARTBUFF_FOOD_AURA = GetSpellInfo(46899); --"Well Fed" + SMARTBUFF_FOOD_SPELL = GetSpellInfo(433); --"Food" + SMARTBUFF_DRINK_SPELL = GetSpellInfo(430); --"Drink" + + -- Misc + SMARTBUFF_KIRUSSOV = GetSpellInfo(46302); --"K'iru's Song of Victory" + SMARTBUFF_FISHING = GetSpellInfo(7620) or GetSpellInfo(111541); --"Fishing" + + -- Scroll + SMARTBUFF_SBAGILITY = GetSpellInfo(8115); --"Scroll buff: Agility" + SMARTBUFF_SBINTELLECT = GetSpellInfo(8096); --"Scroll buff: Intellect" + SMARTBUFF_SBSTAMINA = GetSpellInfo(8099); --"Scroll buff: Stamina" + SMARTBUFF_SBSPIRIT = GetSpellInfo(8112); --"Scroll buff: Spirit" + SMARTBUFF_SBSTRENGHT = GetSpellInfo(8118); --"Scroll buff: Strength" + SMARTBUFF_SBPROTECTION = GetSpellInfo(89344); --"Scroll buff: Armor" + SMARTBUFF_BMiscItem1 = GetSpellInfo(326396); --"WoW's 16th Anniversary" + SMARTBUFF_BMiscItem2 = GetSpellInfo(62574); --"Warts-B-Gone Lip Balm" + SMARTBUFF_BMiscItem3 = GetSpellInfo(98444); --"Vrykul Drinking Horn" + SMARTBUFF_BMiscItem4 = GetSpellInfo(127230); --"Visions of Insanity" + SMARTBUFF_BMiscItem5 = GetSpellInfo(124036); --"Anglers Fishing Raft" + SMARTBUFF_BMiscItem6 = GetSpellInfo(125167); --"Ancient Pandaren Fishing Charm" + SMARTBUFF_BMiscItem7 = GetSpellInfo(138927); --"Burning Essence" + SMARTBUFF_BMiscItem8 = GetSpellInfo(160331); --"Blood Elf Illusion" + SMARTBUFF_BMiscItem9 = GetSpellInfo(158486); --"Safari Hat" + SMARTBUFF_BMiscItem10 = GetSpellInfo(158474); --"Savage Safari Hat" + SMARTBUFF_BMiscItem11 = GetSpellInfo(176151); --"Whispers of Insanity" + SMARTBUFF_BMiscItem12 = GetSpellInfo(193456); --"Gaze of the Legion" + SMARTBUFF_BMiscItem13 = GetSpellInfo(193547); --"Fel Crystal Infusion" + SMARTBUFF_BMiscItem14 = GetSpellInfo(190668); --"Empower" + SMARTBUFF_BMiscItem14_1 = GetSpellInfo(175457); --"Focus Augmentation" + SMARTBUFF_BMiscItem14_2 = GetSpellInfo(175456); --"Hyper Augmentation" + SMARTBUFF_BMiscItem14_3 = GetSpellInfo(175439); --"Stout Augmentation + SMARTBUFF_BMiscItem16 = GetSpellInfo(181642); --"Bodyguard Miniaturization Device" + SMARTBUFF_BMiscItem17 = GetSpellInfo(242551); --"Fel Focus" + + SMARTBUFF_BAugmentRune = GetSpellInfo(367405); --"Eternal Augmentation from Eternal Augment Rune" + SMARTBUFF_BVieledAugment = GetSpellInfo(347901); --"Veiled Augmentation from Veiled Augment Rune" + + S.LinkSafariHat = { SMARTBUFF_BMiscItem9, SMARTBUFF_BMiscItem10 }; + S.LinkAugment = { SMARTBUFF_BMiscItem14, SMARTBUFF_BMiscItem14_1, SMARTBUFF_BMiscItem14_2, SMARTBUFF_BMiscItem14_3, SMARTBUFF_BAugmentRune, SMARTBUFF_BVieledAugment }; + + -- Flasks & Elixirs + SMARTBUFF_BFLASKTBC1 = GetSpellInfo(28520); --"Flask of Relentless Assault" + SMARTBUFF_BFLASKTBC2 = GetSpellInfo(28540); --"Flask of Pure Death" + SMARTBUFF_BFLASKTBC3 = GetSpellInfo(28518); --"Flask of Fortification" + SMARTBUFF_BFLASKTBC4 = GetSpellInfo(28521); --"Flask of Blinding Light" + SMARTBUFF_BFLASKTBC5 = GetSpellInfo(28519); --"Flask of Mighty Versatility" + SMARTBUFF_BFLASK1 = GetSpellInfo(53760); --"Flask of Endless Rage" + SMARTBUFF_BFLASK2 = GetSpellInfo(53755); --"Flask of the Frost Wyrm" + SMARTBUFF_BFLASK3 = GetSpellInfo(53758); --"Flask of Stoneblood" + SMARTBUFF_BFLASK4 = GetSpellInfo(54212); --"Flask of Pure Mojo" + SMARTBUFF_BFLASKCT1 = GetSpellInfo(79471); --"Flask of the Winds" + SMARTBUFF_BFLASKCT2 = GetSpellInfo(79472); --"Flask of Titanic Strength" + SMARTBUFF_BFLASKCT3 = GetSpellInfo(79470); --"Flask of the Draconic Mind" + SMARTBUFF_BFLASKCT4 = GetSpellInfo(79469); --"Flask of Steelskin" + SMARTBUFF_BFLASKCT5 = GetSpellInfo(94160); --"Flask of Flowing Water" + SMARTBUFF_BFLASKCT7 = GetSpellInfo(92679); --"Flask of Battle" + SMARTBUFF_BFLASKMOP1 = GetSpellInfo(105617); --"Alchemist's Flask" + SMARTBUFF_BFLASKMOP2 = GetSpellInfo(105694); --"Flask of the Earth" + SMARTBUFF_BFLASKMOP3 = GetSpellInfo(105693); --"Flask of Falling Leaves" + SMARTBUFF_BFLASKMOP4 = GetSpellInfo(105689); --"Flask of Spring Blossoms" + SMARTBUFF_BFLASKMOP5 = GetSpellInfo(105691); --"Flask of the Warm Sun" + SMARTBUFF_BFLASKMOP6 = GetSpellInfo(105696); --"Flask of Winter's Bite" + SMARTBUFF_BFLASKCT61 = GetSpellInfo(79640); --"Enhanced Intellect" + SMARTBUFF_BFLASKCT62 = GetSpellInfo(79639); --"Enhanced Agility" + SMARTBUFF_BFLASKCT63 = GetSpellInfo(79638); --"Enhanced Strength" + SMARTBUFF_BFLASKWOD1 = GetSpellInfo(156077); --"Draenic Stamina Flask" + SMARTBUFF_BFLASKWOD2 = GetSpellInfo(156071); --"Draenic Strength Flask" + SMARTBUFF_BFLASKWOD3 = GetSpellInfo(156070); --"Draenic Intellect Flask" + SMARTBUFF_BFLASKWOD4 = GetSpellInfo(156073); --"Draenic Agility Flask" + SMARTBUFF_BGRFLASKWOD1 = GetSpellInfo(156084); --"Greater Draenic Stamina Flask" + SMARTBUFF_BGRFLASKWOD2 = GetSpellInfo(156080); --"Greater Draenic Strength Flask" + SMARTBUFF_BGRFLASKWOD3 = GetSpellInfo(156079); --"Greater Draenic Intellect Flask" + SMARTBUFF_BGRFLASKWOD4 = GetSpellInfo(156064); --"Greater Draenic Agility Flask" + SMARTBUFF_BFLASKLEG1 = GetSpellInfo(188035); --"Flask of Ten Thousand Scars" + SMARTBUFF_BFLASKLEG2 = GetSpellInfo(188034); --"Flask of the Countless Armies" + SMARTBUFF_BFLASKLEG3 = GetSpellInfo(188031); --"Flask of the Whispered Pact" + SMARTBUFF_BFLASKLEG4 = GetSpellInfo(188033); --"Flask of the Seventh Demon" + SMARTBUFF_BFLASKBFA1 = GetSpellInfo(251837); --"Flask of Endless Fathoms" + SMARTBUFF_BFLASKBFA2 = GetSpellInfo(251836); --"Flask of the Currents" + SMARTBUFF_BFLASKBFA3 = GetSpellInfo(251839); --"Flask of the Undertow" + SMARTBUFF_BFLASKBFA4 = GetSpellInfo(251838); --"Flask of the Vast Horizon" + SMARTBUFF_BGRFLASKBFA1 = GetSpellInfo(298837); --"Greather Flask of Endless Fathoms" + SMARTBUFF_BGRFLASKBFA2 = GetSpellInfo(298836); --"Greater Flask of the Currents" + SMARTBUFF_BGRFLASKBFA3 = GetSpellInfo(298841); --"Greather Flask of teh Untertow" + SMARTBUFF_BGRFLASKBFA4 = GetSpellInfo(298839); --"Greater Flask of the Vast Horizon" + SMARTBUFF_BFLASKSL1 = GetSpellInfo(307185); --"Spectral Flask of Power" + SMARTBUFF_BFLASKSL2 = GetSpellInfo(307187); --"Spectral Flask of Stamina" + + S.LinkFlaskTBC = { SMARTBUFF_BFLASKTBC1, SMARTBUFF_BFLASKTBC2, SMARTBUFF_BFLASKTBC3, SMARTBUFF_BFLASKTBC4, SMARTBUFF_BFLASKTBC5 }; + S.LinkFlaskCT7 = { SMARTBUFF_BFLASKCT1, SMARTBUFF_BFLASKCT2, SMARTBUFF_BFLASKCT3, SMARTBUFF_BFLASKCT4, SMARTBUFF_BFLASKCT5 }; + S.LinkFlaskMoP = { SMARTBUFF_BFLASKCT61, SMARTBUFF_BFLASKCT62, SMARTBUFF_BFLASKCT63, SMARTBUFF_BFLASKMOP2, SMARTBUFF_BFLASKMOP3, SMARTBUFF_BFLASKMOP4, SMARTBUFF_BFLASKMOP5, SMARTBUFF_BFLASKMOP6 }; + S.LinkFlaskWoD = { SMARTBUFF_BFLASKWOD1, SMARTBUFF_BFLASKWOD2, SMARTBUFF_BFLASKWOD3, SMARTBUFF_BFLASKWOD4, SMARTBUFF_BGRFLASKWOD1, SMARTBUFF_BGRFLASKWOD2, SMARTBUFF_BGRFLASKWOD3, SMARTBUFF_BGRFLASKWOD4 }; + S.LinkFlaskLeg = { SMARTBUFF_BFLASKLEG1, SMARTBUFF_BFLASKLEG2, SMARTBUFF_BFLASKLEG3, SMARTBUFF_BFLASKLEG4 }; + S.LinkFlaskBfA = { SMARTBUFF_BFLASKBFA1, SMARTBUFF_BFLASKBFA2, SMARTBUFF_BFLASKBFA3, SMARTBUFF_BFLASKBFA4, SMARTBUFF_BGRFLASKBFA1, SMARTBUFF_BGRFLASKBFA2, SMARTBUFF_BGRFLASKBFA3, SMARTBUFF_BGRFLASKBFA4 }; + S.LinkFlaskSL = { SMARTBUFF_BFLASKSL1, SMARTBUFF_BFLASKSL2 }; + + SMARTBUFF_BELIXIRTBC1 = GetSpellInfo(54494); --"Major Agility" B + SMARTBUFF_BELIXIRTBC2 = GetSpellInfo(33726); --"Mastery" B + SMARTBUFF_BELIXIRTBC3 = GetSpellInfo(28491); --"Healing Power" B + SMARTBUFF_BELIXIRTBC4 = GetSpellInfo(28502); --"Major Defense" G + SMARTBUFF_BELIXIRTBC5 = GetSpellInfo(28490); --"Major Strength" B + SMARTBUFF_BELIXIRTBC6 = GetSpellInfo(39625); --"Major Fortitude" G + SMARTBUFF_BELIXIRTBC7 = GetSpellInfo(28509); --"Major Mageblood" B + SMARTBUFF_BELIXIRTBC8 = GetSpellInfo(39627); --"Draenic Wisdom" B + SMARTBUFF_BELIXIRTBC9 = GetSpellInfo(54452); --"Adept's Elixir" B + SMARTBUFF_BELIXIRTBC10 = GetSpellInfo(134870); --"Empowerment" B + SMARTBUFF_BELIXIRTBC11 = GetSpellInfo(33720); --"Onslaught Elixir" B + SMARTBUFF_BELIXIRTBC12 = GetSpellInfo(28503); --"Major Shadow Power" B + SMARTBUFF_BELIXIRTBC13 = GetSpellInfo(39628); --"Ironskin" G + SMARTBUFF_BELIXIRTBC14 = GetSpellInfo(39626); --"Earthen Elixir" G + SMARTBUFF_BELIXIRTBC15 = GetSpellInfo(28493); --"Major Frost Power" B + SMARTBUFF_BELIXIRTBC16 = GetSpellInfo(38954); --"Fel Strength Elixir" B + SMARTBUFF_BELIXIRTBC17 = GetSpellInfo(28501); --"Major Firepower" B + SMARTBUFF_BELIXIR1 = GetSpellInfo(28497); --"Mighty Agility" B + SMARTBUFF_BELIXIR2 = GetSpellInfo(60347); --"Mighty Thoughts" G + SMARTBUFF_BELIXIR3 = GetSpellInfo(53751); --"Elixir of Mighty Fortitude" G + SMARTBUFF_BELIXIR4 = GetSpellInfo(53748); --"Mighty Strength" B + SMARTBUFF_BELIXIR5 = GetSpellInfo(53747); --"Elixir of Spirit" B + SMARTBUFF_BELIXIR6 = GetSpellInfo(53763); --"Protection" G + SMARTBUFF_BELIXIR7 = GetSpellInfo(60343); --"Mighty Defense" G + SMARTBUFF_BELIXIR8 = GetSpellInfo(60346); --"Lightning Speed" B + SMARTBUFF_BELIXIR9 = GetSpellInfo(60344); --"Expertise" B + SMARTBUFF_BELIXIR10 = GetSpellInfo(60341); --"Deadly Strikes" B + SMARTBUFF_BELIXIR11 = GetSpellInfo(80532); --"Armor Piercing" + SMARTBUFF_BELIXIR12 = GetSpellInfo(60340); --"Accuracy" B + SMARTBUFF_BELIXIR13 = GetSpellInfo(53749); --"Guru's Elixir" B + SMARTBUFF_BELIXIR14 = GetSpellInfo(11334); --"Elixir of Greater Agility" B + SMARTBUFF_BELIXIR15 = GetSpellInfo(54452); --"Adept's Elixir" B + SMARTBUFF_BELIXIR16 = GetSpellInfo(33721); --"Spellpower Elixir" B + SMARTBUFF_BELIXIRCT1 = GetSpellInfo(79635); --"Elixir of the Master" B + SMARTBUFF_BELIXIRCT2 = GetSpellInfo(79632); --"Elixir of Mighty Speed" B + SMARTBUFF_BELIXIRCT3 = GetSpellInfo(79481); --"Elixir of Impossible Accuracy" B + SMARTBUFF_BELIXIRCT4 = GetSpellInfo(79631); --"Prismatic Elixir" G + SMARTBUFF_BELIXIRCT5 = GetSpellInfo(79480); --"Elixir of Deep Earth" G + SMARTBUFF_BELIXIRCT6 = GetSpellInfo(79477); --"Elixir of the Cobra" B + SMARTBUFF_BELIXIRCT7 = GetSpellInfo(79474); --"Elixir of the Naga" B + SMARTBUFF_BELIXIRCT8 = GetSpellInfo(79468); --"Ghost Elixir" B + SMARTBUFF_BELIXIRMOP1 = GetSpellInfo(105687); --"Elixir of Mirrors" G + SMARTBUFF_BELIXIRMOP2 = GetSpellInfo(105685); --"Elixir of Peace" B + SMARTBUFF_BELIXIRMOP3 = GetSpellInfo(105686); --"Elixir of Perfection" B + SMARTBUFF_BELIXIRMOP4 = GetSpellInfo(105684); --"Elixir of the Rapids" B + SMARTBUFF_BELIXIRMOP5 = GetSpellInfo(105683); --"Elixir of Weaponry" B + SMARTBUFF_BELIXIRMOP6 = GetSpellInfo(105682); --"Mad Hozen Elixir" B + SMARTBUFF_BELIXIRMOP7 = GetSpellInfo(105681); --"Mantid Elixir" G + SMARTBUFF_BELIXIRMOP8 = GetSpellInfo(105688); --"Monk's Elixir" B + -- Draught of Ten Lands + SMARTBUFF_BEXP_POTION = GetSpellInfo(289982); --Draught of Ten Lands + + --if (SMARTBUFF_GOTW) then + -- SMARTBUFF_AddMsgD(SMARTBUFF_GOTW.." found"); + --end + + -- Buff map + S.LinkStats = { SMARTBUFF_BOK, SMARTBUFF_MOTW, SMARTBUFF_LOTE, SMARTBUFF_LOTWT, + GetSpellInfo(159988), -- Bark of the Wild + GetSpellInfo(203538), -- Greater Blessing of Kings + GetSpellInfo(90363), -- Embrace of the Shale Spider + GetSpellInfo(160077) -- Strength of the Earth + }; + + S.LinkSta = { SMARTBUFF_PWF, SMARTBUFF_COMMANDINGSHOUT, SMARTBUFF_BLOODPACT, + GetSpellInfo(50256), -- Invigorating Roar + GetSpellInfo(90364), -- Qiraji Fortitude + GetSpellInfo(160014), -- Sturdiness + GetSpellInfo(160003) -- Savage Vigor + }; + + S.LinkAp = { SMARTBUFF_HORNOFWINTER, SMARTBUFF_BATTLESHOUT, SMARTBUFF_TRUESHOTAURA }; + + S.LinkMa = { SMARTBUFF_BOM, SMARTBUFF_DRUID_MKAURA, SMARTBUFF_GRACEOFAIR, SMARTBUFF_POTGRAVE, + GetSpellInfo(93435), -- Roar of Courage + GetSpellInfo(160039), -- Keen Senses + GetSpellInfo(128997), -- Spirit Beast Blessing + GetSpellInfo(160073) -- Plainswalking + }; + + S.LinkInt = { SMARTBUFF_BOW, SMARTBUFF_AB, SMARTBUFF_DALARANB }; + + --S.LinkSp = { SMARTBUFF_DARKINTENT, SMARTBUFF_AB, SMARTBUFF_DALARANB, SMARTBUFF_STILLWATER }; + + --SMARTBUFF_AddMsgD("Spell IDs initialized"); +end + + +function SMARTBUFF_InitSpellList() + if (SMARTBUFF_PLAYERCLASS == nil) then return; end + + --if (SMARTBUFF_GOTW) then + -- SMARTBUFF_AddMsgD(SMARTBUFF_GOTW.." found"); + --end + + -- Druid + if (SMARTBUFF_PLAYERCLASS == "DRUID") then + SMARTBUFF_BUFFLIST = { + {SMARTBUFF_DRUID_MOONKIN, -1, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_DRUID_TREANT, -1, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_DRUID_BEAR, -1, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_DRUID_CAT, -1, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_DRUID_TREE, 0.5, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_MOTW, 60, SMARTBUFF_CONST_GROUP, {1,10,20,30,40,50,60,70,80}, "WPET;DKPET"}, + {SMARTBUFF_CENARIONWARD, 0.5, SMARTBUFF_CONST_GROUP, {1}, "WARRIOR;DRUID;SHAMAN;HUNTER;ROGUE;MAGE;PRIEST;PALADIN;WARLOCK;DEATHKNIGHT;MONK;DEMONHUNTER;EVOKER"}, + {SMARTBUFF_MOTW, 0.5, SMARTBUFF_CONST_GROUP, {1}, "HPET;WPET;DKPET"}, + {SMARTBUFF_BARKSKIN, 0.25, SMARTBUFF_CONST_FORCESELF}, + {SMARTBUFF_TIGERSFURY, 0.1, SMARTBUFF_CONST_SELF, nil, SMARTBUFF_DRUID_CAT}, + {SMARTBUFF_SAVAGEROAR, 0.15, SMARTBUFF_CONST_SELF, nil, SMARTBUFF_DRUID_CAT} + }; + end + + -- Priest + if (SMARTBUFF_PLAYERCLASS == "PRIEST") then + SMARTBUFF_BUFFLIST = { + {SMARTBUFF_SHADOWFORM, -1, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_VAMPIRICEMBRACE, 30, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_PWF, 60, SMARTBUFF_CONST_GROUP, {14}, "HPET;WPET;DKPET", S.LinkSta}, + {SMARTBUFF_PWS, 0.5, SMARTBUFF_CONST_GROUP, {6}, "MAGE;WARLOCK;ROGUE;PALADIN;WARRIOR;DRUID;HUNTER;SHAMAN;DEATHKNIGHT;MONK;DEMONHUNTER;EVOKER;HPET;WPET;DKPET"}, + {SMARTBUFF_FEARWARD, 3, SMARTBUFF_CONST_GROUP, {54}, "HPET;WPET;DKPET"}, + {SMARTBUFF_LEVITATE, 2, SMARTBUFF_CONST_GROUP, {34}, "HPET;WPET;DKPET"}, + {SMARTBUFF_CHAKRA1, 0.5, SMARTBUFF_CONST_SELF, nil, nil, S.LinkPriestChakra}, + {SMARTBUFF_CHAKRA2, 0.5, SMARTBUFF_CONST_SELF, nil, nil, S.LinkPriestChakra}, + {SMARTBUFF_CHAKRA3, 0.5, SMARTBUFF_CONST_SELF, nil, nil, S.LinkPriestChakra}, + {SMARTBUFF_LIGHTWELL, 3, SMARTBUFF_CONST_SELF} + }; + end + + -- Mage + if (SMARTBUFF_PLAYERCLASS == "MAGE") then + SMARTBUFF_BUFFLIST = { + {SMARTBUFF_AB, 60, SMARTBUFF_CONST_GROUP, {1,14,28,42,56,70,80}, nil, S.LinkInt, S.LinkInt}, + {SMARTBUFF_DALARANB, 60, SMARTBUFF_CONST_GROUP, {80,80,80,80,80,80,80}, nil, S.LinkInt, S.LinkInt}, + {SMARTBUFF_TEMPSHIELD, 0.067, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_AMPMAGIC, 0.1, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_SUMMONWATERELE, -1, SMARTBUFF_CONST_SELF, nil, S.CheckPet}, + {SMARTBUFF_FROSTARMOR, -1, SMARTBUFF_CONST_SELF, nil, nil, nil, S.ChainMageArmor}, + {SMARTBUFF_MAGEARMOR, -1, SMARTBUFF_CONST_SELF, nil, nil, nil, S.ChainMageArmor}, + {SMARTBUFF_MOLTENARMOR, -1, SMARTBUFF_CONST_SELF, nil, nil, nil, S.ChainMageArmor}, + {SMARTBUFF_SLOWFALL, 0.5, SMARTBUFF_CONST_GROUP, {32}, "HPET;WPET;DKPET"}, + {SMARTBUFF_MANASHIELD, 0.5, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_ICEWARD, 0.5, SMARTBUFF_CONST_GROUP, {45}, "HPET;WPET;DKPET"}, + {SMARTBUFF_ICEBARRIER, 1, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_COMBUSTION, -1, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_ICYVEINS, 0.333, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_ARCANEFAMILIAR, 60, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_ARCANEPOWER, 0.25, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_PRESENCEOFMIND, 0.165, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_PRISBARRIER, 1, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_IMPPRISBARRIER, 1, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_BLAZBARRIER, 1, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_REFRESHMENT, 0.03, SMARTBUFF_CONST_ITEM, nil, SMARTBUFF_CONJUREDMANA, nil, S.FoodMage}, + {SMARTBUFF_CREATEMG, 0.03, SMARTBUFF_CONST_ITEM, nil, SMARTBUFF_MANAGEM}, +-- {SMARTBUFF_ARCANEINTELLECT, 60, SMARTBUFF_CONST_GROUP, {32}, "HPET;WPET;DKPET"} + }; + end + + -- Warlock + if (SMARTBUFF_PLAYERCLASS == "WARLOCK") then + SMARTBUFF_BUFFLIST = { + {SMARTBUFF_DEMONARMOR, -1, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_AMPLIFYCURSE, 1, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_INQUISITORGAZE, 60, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_DARKINTENT, 60, SMARTBUFF_CONST_GROUP, nil, "WARRIOR;HUNTER;ROGUE"}, + {SMARTBUFF_SOULLINK, -1, SMARTBUFF_CONST_SELF, nil, S.CheckPetNeeded}, + {SMARTBUFF_UNENDINGBREATH, 10, SMARTBUFF_CONST_GROUP, {16}, "HPET;WPET;DKPET"}, + {SMARTBUFF_LIFETAP, 0.025, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_GOSACRIFICE, 60, SMARTBUFF_CONST_SELF, nil, S.CheckPetNeeded}, + {SMARTBUFF_BLOODHORROR, 1, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_SOULSTONE, 15, SMARTBUFF_CONST_GROUP, {18}, "WARRIOR;DRUID;SHAMAN;HUNTER;ROGUE;MAGE;PRIEST;PALADIN;WARLOCK;DEATHKNIGHT;EVOKER;MONK;DEMONHUNTER;HPET;WPET;DKPET"}, + {SMARTBUFF_CREATEHS, 0.03, SMARTBUFF_CONST_ITEM, nil, SMARTBUFF_HEALTHSTONE} + }; + end + + -- Hunter + if (SMARTBUFF_PLAYERCLASS == "HUNTER") then + SMARTBUFF_BUFFLIST = { + {SMARTBUFF_RAPIDFIRE, 0.2, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_FOCUSFIRE, 0.25, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_TRAPLAUNCHER, -1, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_VOLLEY, -1, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_CAMOFLAUGE, 1, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_AMMOI, 60, SMARTBUFF_CONST_SELF, nil, nil, S.LinkAmmo}, + {SMARTBUFF_AMMOP, 60, SMARTBUFF_CONST_SELF, nil, nil, S.LinkAmmo}, + {SMARTBUFF_AMMOF, 60, SMARTBUFF_CONST_SELF, nil, nil, S.LinkAmmo}, + {SMARTBUFF_LW1, -1, SMARTBUFF_CONST_SELF, nil, nil, S.LinkLoneWolf}, + {SMARTBUFF_LW2, -1, SMARTBUFF_CONST_SELF, nil, nil, S.LinkLoneWolf}, + {SMARTBUFF_LW3, -1, SMARTBUFF_CONST_SELF, nil, nil, S.LinkLoneWolf}, + {SMARTBUFF_LW4, -1, SMARTBUFF_CONST_SELF, nil, nil, S.LinkLoneWolf}, + {SMARTBUFF_LW5, -1, SMARTBUFF_CONST_SELF, nil, nil, S.LinkLoneWolf}, + {SMARTBUFF_LW6, -1, SMARTBUFF_CONST_SELF, nil, nil, S.LinkLoneWolf}, + {SMARTBUFF_LW7, -1, SMARTBUFF_CONST_SELF, nil, nil, S.LinkLoneWolf}, + {SMARTBUFF_LW8, -1, SMARTBUFF_CONST_SELF, nil, nil, S.LinkLoneWolf}, + {SMARTBUFF_AOTF, 0.1, SMARTBUFF_CONST_SELF, nil, nil, S.LinkAspects}, + {SMARTBUFF_AOTC, -1, SMARTBUFF_CONST_SELF, nil, nil, S.LinkAspects}, + {SMARTBUFF_AOTP, -1, SMARTBUFF_CONST_SELF, nil, nil, S.LinkAspects}, + {SMARTBUFF_AOTW, -1, SMARTBUFF_CONST_SELF, nil, nil, S.LinkAspects} + }; + end + + -- Shaman + if (SMARTBUFF_PLAYERCLASS == "SHAMAN") then + SMARTBUFF_BUFFLIST = { + {SMARTBUFF_LIGHTNINGSHIELD, 60, SMARTBUFF_CONST_SELF, nil, nil, nil, S.ChainShamanShield}, + {SMARTBUFF_WATERSHIELD, 60, SMARTBUFF_CONST_SELF, nil, nil, nil, S.ChainShamanShield}, + {SMARTBUFF_WINDFURYW, 60, SMARTBUFF_CONST_WEAPON}, + {SMARTBUFF_FLAMETONGUEW, 60, SMARTBUFF_CONST_WEAPON}, + {SMARTBUFF_EVERLIVINGW, 60, SMARTBUFF_CONST_WEAPON}, + {SMARTBUFF_EARTHSHIELD, 10, SMARTBUFF_CONST_GROUP, {50,60,70,75,80}, "WARRIOR;DEATHKNIGHT;DRUID;SHAMAN;HUNTER;ROGUE;MAGE;PRIEST;PALADIN;WARLOCK;MONK;DEMONHUNTER;EVOKER;HPET;WPET;DKPET"}, + {SMARTBUFF_UNLEASHFLAME, 0.333, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_ASCENDANCE_ELE, 0.25, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_ASCENDANCE_ENH, 0.25, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_ASCENDANCE_RES, 0.25, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_EMASTERY, 0.5, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_WATERWALKING, 10, SMARTBUFF_CONST_GROUP, {28}} + }; + end + + -- Warrior + if (SMARTBUFF_PLAYERCLASS == "WARRIOR") then + SMARTBUFF_BUFFLIST = { + {SMARTBUFF_BATTLESHOUT, 60, SMARTBUFF_CONST_SELF, nil, nil, S.LinkAp, S.ChainWarriorShout}, + {SMARTBUFF_COMMANDINGSHOUT, 60, SMARTBUFF_CONST_SELF, nil, nil, S.LinkSta, S.ChainWarriorShout}, + {SMARTBUFF_BERSERKERRAGE, 0.165, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_SHIELDBLOCK, 0.1666, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_BATSTANCE, -1, SMARTBUFF_CONST_SELF, nil, nil, nil, S.ChainWarriorStance}, + {SMARTBUFF_DEFSTANCE, -1, SMARTBUFF_CONST_SELF, nil, nil, nil, S.ChainWarriorStance}, + {SMARTBUFF_GLADSTANCE, -1, SMARTBUFF_CONST_SELF, nil, nil, nil, S.ChainWarriorStance} + }; + end + + -- Rogue + if (SMARTBUFF_PLAYERCLASS == "ROGUE") then + SMARTBUFF_BUFFLIST = { + {SMARTBUFF_STEALTH, -1, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_BLADEFLURRY, -1, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_SAD, 0.2, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_TRICKS, 0.5, SMARTBUFF_CONST_GROUP, {75}, "WARRIOR;DEATHKNIGHT;DRUID;SHAMAN;HUNTER;ROGUE;MAGE;PRIEST;PALADIN;WARLOCK;MONK;DEMONHUNTER;EVOKER;HPET;WPET;DKPET"}, + {SMARTBUFF_HUNGERFORBLOOD, 0.5, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_RECUPERATE, 0.5, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_EVASION, 0.2, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_INSTANTPOISON, 60, SMARTBUFF_CONST_SELF, nil, S.CheckFishingPole, nil, S.ChainRoguePoisonsLethal}, + {SMARTBUFF_DEADLYPOISON, 60, SMARTBUFF_CONST_SELF, nil, S.CheckFishingPole, nil, S.ChainRoguePoisonsLethal}, + {SMARTBUFF_WOUNDPOISON, 60, SMARTBUFF_CONST_SELF, nil, S.CheckFishingPole, nil, S.ChainRoguePoisonsLethal}, + {SMARTBUFF_AGONIZINGPOISON, 60, SMARTBUFF_CONST_SELF, nil, S.CheckFishingPole, nil, S.ChainRoguePoisonsLethal}, + {SMARTBUFF_LEECHINGPOISON, 60, SMARTBUFF_CONST_SELF, nil, S.CheckFishingPole, nil, S.ChainRoguePoisonsNonLethal}, + {SMARTBUFF_NUMBINGPOISON, 60, SMARTBUFF_CONST_SELF, nil, S.CheckFishingPole, nil, S.ChainRoguePoisonsNonLethal}, + {SMARTBUFF_CRIPPLINGPOISON, 60, SMARTBUFF_CONST_SELF, nil, S.CheckFishingPole, nil, S.ChainRoguePoisonsNonLethal}, + {SMARTBUFF_AMPLIFYPOISON, 60, SMARTBUFF_CONST_SELF, nil, S.CheckFishingPole, nil, S.ChainRoguePoisonsNonLethal}, + {SMARTBUFF_ATROPHICPOISON, 60, SMARTBUFF_CONST_SELF, nil, S.CheckFishingPole, nil, S.ChainRoguePoisonsNonLethal} + }; + end + + -- Paladin + if (SMARTBUFF_PLAYERCLASS == "PALADIN") then + SMARTBUFF_BUFFLIST = { + {SMARTBUFF_RIGHTEOUSFURY, 30, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_HOLYSHIELD, 0.166, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_AVENGINGWARTH, 0.333, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_BOK, 60, SMARTBUFF_CONST_GROUP, {20}, nil, S.LinkStats}, + {SMARTBUFF_BOM, 60, SMARTBUFF_CONST_GROUP, {20}, nil, S.LinkMa}, + {SMARTBUFF_BOW, 60, SMARTBUFF_CONST_GROUP, {20}, nil, S.LinkInt}, + {SMARTBUFF_HOF, 0.1, SMARTBUFF_CONST_GROUP, {52}, "WARRIOR;DEATHKNIGHT;DRUID;SHAMAN;HUNTER;ROGUE;MAGE;PRIEST;PALADIN;WARLOCK;MONK;DEMONHUNTER;EVOKER;HPET;WPET;DKPET"}, + {SMARTBUFF_HOSAL, 0.1, SMARTBUFF_CONST_GROUP, {66}, "WARRIOR;DEATHKNIGHT;DRUID;SHAMAN;HUNTER;ROGUE;MAGE;PRIEST;PALADIN;WARLOCK;MONK;DEMONHUNTER;EVOKER;HPET;WPET;DKPET"}, + {SMARTBUFF_BEACONOFLIGHT, 5, SMARTBUFF_CONST_GROUP, {39}, "WARRIOR;DRUID;SHAMAN;HUNTER;ROGUE;MAGE;PRIEST;PALADIN;WARLOCK;DEATHKNIGHT;MONK;DEMONHUNTER;EVOKER;HPET;WPET;DKPET"}, + {SMARTBUFF_BEACONOFAITH, 5, SMARTBUFF_CONST_GROUP, {39}, "WARRIOR;DRUID;SHAMAN;HUNTER;ROGUE;MAGE;PRIEST;PALADIN;WARLOCK;DEATHKNIGHT;MONK;DEMONHUNTER;EVOKER;HPET;WPET;DKPET"}, + {SMARTBUFF_CRUSADERAURA, -1, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_DEVOTIONAURA, -1, SMARTBUFF_CONST_SELF, nil, nil, nil, S.ChainPaladinAura}, + {SMARTBUFF_RETRIBUTIONAURA, -1, SMARTBUFF_CONST_SELF, nil, nil, nil, S.ChainPaladinAura}, + {SMARTBUFF_SOTRUTH, -1, SMARTBUFF_CONST_STANCE, nil, nil, nil, S.ChainPaladinSeal}, + {SMARTBUFF_SORIGHTEOUSNESS, -1, SMARTBUFF_CONST_STANCE, nil, nil, nil, S.ChainPaladinSeal}, + {SMARTBUFF_SOJUSTICE, -1, SMARTBUFF_CONST_STANCE, nil, nil, nil, S.ChainPaladinSeal}, + {SMARTBUFF_SOINSIGHT, -1, SMARTBUFF_CONST_STANCE, nil, nil, nil, S.ChainPaladinSeal}, + {SMARTBUFF_SOCOMMAND, -1, SMARTBUFF_CONST_STANCE, nil, nil, nil, S.ChainPaladinSeal} + }; + end + + -- Deathknight + if (SMARTBUFF_PLAYERCLASS == "DEATHKNIGHT") then + SMARTBUFF_BUFFLIST = { + {SMARTBUFF_DANCINGRW, 0.2, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_BLOODPRESENCE, -1, SMARTBUFF_CONST_STANCE, nil, nil, nil, S.ChainDKPresence}, + {SMARTBUFF_FROSTPRESENCE, -1, SMARTBUFF_CONST_STANCE, nil, nil, nil, S.ChainDKPresence}, + {SMARTBUFF_UNHOLYPRESENCE, -1, SMARTBUFF_CONST_STANCE, nil, nil, nil, S.ChainDKPresence}, + {SMARTBUFF_HORNOFWINTER, 60, SMARTBUFF_CONST_SELF, nil, nil, S.LinkAp}, + {SMARTBUFF_BONESHIELD, 5, SMARTBUFF_CONST_SELF}, + {SMARTBUFF_RAISEDEAD, 1, SMARTBUFF_CONST_SELF, nil, S.CheckPet}, + {SMARTBUFF_PATHOFFROST, -1, SMARTBUFF_CONST_SELF} + }; + end + + -- Monk + if (SMARTBUFF_PLAYERCLASS == "MONK") then + SMARTBUFF_BUFFLIST = { + {SMARTBUFF_LOTWT, 60, SMARTBUFF_CONST_GROUP, {81}}, + {SMARTBUFF_LOTE, 60, SMARTBUFF_CONST_GROUP, {22}, nil, S.LinkStats}, + {SMARTBUFF_SOTFIERCETIGER, -1, SMARTBUFF_CONST_STANCE, nil, nil, nil, S.ChainMonkStance}, + {SMARTBUFF_SOTSTURDYOX, -1, SMARTBUFF_CONST_STANCE, nil, nil, nil, S.ChainMonkStance}, + {SMARTBUFF_SOTWISESERPENT, -1, SMARTBUFF_CONST_STANCE, nil, nil, nil, S.ChainMonkStance}, + {SMARTBUFF_SOTSPIRITEDCRANE, -1, SMARTBUFF_CONST_STANCE, nil, nil, nil, S.ChainMonkStance}, + {SMARTBUFF_BLACKOX, 15, SMARTBUFF_CONST_SELF, nil, nil, nil, S.ChainMonkStatue}, + {SMARTBUFF_SMARTBUFF_JADESERPENT, 15, SMARTBUFF_CONST_SELF, nil, nil, nil, S.ChainMonkStatue} + }; + end + + -- Demon Hunter + if (SMARTBUFF_PLAYERCLASS == "DEMONHUNTER") then + SMARTBUFF_BUFFLIST = { + }; + end + + -- Evoker + if (SMARTBUFF_PLAYERCLASS == "EVOKER") then + SMARTBUFF_BUFFLIST = { + {SMARTBUFF_BRONZEBLESSING, 60, SMARTBUFF_CONST_SELF}, + }; + end + + -- Stones and oils + SMARTBUFF_WEAPON = { + {SMARTBUFF_SSROUGH, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_SSCOARSE, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_SSHEAVY, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_SSSOLID, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_SSDENSE, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_SSELEMENTAL, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_SSFEL, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_SSADAMANTITE, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_WSROUGH, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_WSCOARSE, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_WSHEAVY, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_WSSOLID, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_WSDENSE, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_WSFEL, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_WSADAMANTITE, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_SHADOWOIL, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_FROSTOIL, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_MANAOIL4, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_MANAOIL3, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_MANAOIL2, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_MANAOIL1, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_WIZARDOIL5, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_WIZARDOIL4, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_WIZARDOIL3, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_WIZARDOIL2, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_WIZARDOIL1, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_SHADOWCOREOIL, 60, SMARTBUFF_CONST_INV}, + {SMARTBUFF_EMBALMERSOIL, 60, SMARTBUFF_CONST_INV} + }; + + -- Tracking + SMARTBUFF_TRACKING = { + {SMARTBUFF_FINDMINERALS, -1, SMARTBUFF_CONST_TRACK}, + {SMARTBUFF_FINDHERBS, -1, SMARTBUFF_CONST_TRACK}, + {SMARTBUFF_FINDTREASURE, -1, SMARTBUFF_CONST_TRACK}, + {SMARTBUFF_TRACKHUMANOIDS, -1, SMARTBUFF_CONST_TRACK}, + {SMARTBUFF_TRACKBEASTS, -1, SMARTBUFF_CONST_TRACK}, + {SMARTBUFF_TRACKUNDEAD, -1, SMARTBUFF_CONST_TRACK}, + {SMARTBUFF_TRACKHIDDEN, -1, SMARTBUFF_CONST_TRACK}, + {SMARTBUFF_TRACKELEMENTALS, -1, SMARTBUFF_CONST_TRACK}, + {SMARTBUFF_TRACKDEMONS, -1, SMARTBUFF_CONST_TRACK}, + {SMARTBUFF_TRACKGIANTS, -1, SMARTBUFF_CONST_TRACK}, + {SMARTBUFF_TRACKDRAGONKIN, -1, SMARTBUFF_CONST_TRACK} + }; + + -- Racial + SMARTBUFF_RACIAL = { + {SMARTBUFF_STONEFORM, 0.133, SMARTBUFF_CONST_SELF}, -- Dwarv + --{SMARTBUFF_PRECEPTION, 0.333, SMARTBUFF_CONST_SELF}, -- Human + {SMARTBUFF_BLOODFURY, 0.416, SMARTBUFF_CONST_SELF}, -- Orc + {SMARTBUFF_BERSERKING, 0.166, SMARTBUFF_CONST_SELF}, -- Troll + {SMARTBUFF_WOTFORSAKEN, 0.083, SMARTBUFF_CONST_SELF}, -- Undead + {SMARTBUFF_WarStomp, 0.033, SMARTBUFF_CONST_SELF} -- Tauer + }; + + -- FOOD + SMARTBUFF_FOOD = { + {SMARTBUFF_ABYSSALFRIEDRISSOLE, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_BAKEDPORTTATO, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_BANANABEEFPUDDING, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_BARRACUDAMRGLGAGH, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_BATBITES, 15, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_BEARTARTARE, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_BILTONG, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_BIGMECH, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_BLACKENEDBASILISK, 30, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_BLACKENEDSPOREFISH, 30, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_BROILEDBLOODFIN, 30, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_BUTTERSCOTCHRIBS, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_BUZZARDBITES, 30, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_CHARREDBEARKABOBS, 15, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_CINNAMONBONEFISH, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_CLAMBAR, 30, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_CRUNCHYSERPENT, 30, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_CRUNCHYSPIDER, 15, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_DEEPFRIEDMOSSGILL, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_DROGBARSTYLESALMON, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_EXTRALEMONYFILET, 20, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_FARONAARFIZZ, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_FELTAILDELIGHT, 30, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_FIGHTERCHOW, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_FRAGRANTKAKAVIA, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_FRIEDBONEFISH, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_GOLDENFISHSTICKS, 30, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_GRILLEDCATFISH, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_GRILLEDMUDFISH, 30, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_HEARTSBANEHEXWURST, 5, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_HONEYHAUNCHES, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_IRIDESCENTRAVIOLI, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_JUICYBEARBURGER, 15, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_KIBLERSBITS, 20, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_KULTIRAMISU, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_LEGIONCHILI, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_LOALOAF, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_LYNXSTEAK, 15, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_MEATYAPPLEDUMPLINGS, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_MOKNATHALSHORTRIBS, 30, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_MONDAZI, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_PICKLEDMEATSMOOTHIE, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_PICKLEDSTORMRAY, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_POACHEDBLUEFISH, 30, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_RAVAGERDOG, 30, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_RAVENBERRYTARTS, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_ROASTEDCLEFTHOOF, 30, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_ROASTEDMOONGRAZE, 15, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_SAGEFISHDELIGHT, 15, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_SAILORSPIE, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_SALTPEPPERSHANK, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_SEASONEDLOINS, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_SERAPHTENDERS, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_SKULLFISHSOUP, 30, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_SPICEDSNAPPER, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_SPICYCRAWDAD, 30, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_SPICYHOTTALBUK, 30, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_SPINEFISHSOUFFLE, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_STEAKALAMODE, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_STORMCHOPS, 30, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_SWAMPFISHNCHIPS, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_SWEETSILVERGILL, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_TALBUKSTEAK, 30, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_TENEBROUSCROWNROAST, 60, SMARTBUFF_CONST_FOOD}, + {SMARTBUFF_WARPBURGER, 30, SMARTBUFF_CONST_FOOD} + + }; + + for n, name in pairs(S.FoodItems) do + if (name) then + --print("Adding: "..n..". "..name); + tinsert(SMARTBUFF_FOOD, 1, {name, 60, SMARTBUFF_CONST_FOOD}); + end + end + + --[[ + for _, v in pairs(SMARTBUFF_FOOD) do + if (v and v[1]) then + print("List: "..v[1]); + end + end + ]]-- + + + -- Scrolls + SMARTBUFF_SCROLL = { + {SMARTBUFF_MiscItem17, 60, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_BMiscItem17, S.LinkFlaskLeg}, + {SMARTBUFF_MiscItem16, 60, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_BMiscItem16}, + {SMARTBUFF_MiscItem15, 60, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_BMiscItem14, S.LinkAugment}, + {SMARTBUFF_MiscItem14, 60, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_BMiscItem14, S.LinkAugment}, + {SMARTBUFF_MiscItem13, 10, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_BMiscItem13}, + {SMARTBUFF_MiscItem12, 60, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_BMiscItem12}, + {SMARTBUFF_MiscItem11, 60, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_BMiscItem11, S.LinkFlaskWoD}, + {SMARTBUFF_MiscItem10, -1, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_BMiscItem10, S.LinkSafariHat}, + {SMARTBUFF_MiscItem9, -1, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_BMiscItem9, S.LinkSafariHat}, + {SMARTBUFF_MiscItem1, -1, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_BMiscItem1}, + {SMARTBUFF_MiscItem2, -1, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_BMiscItem2}, + {SMARTBUFF_MiscItem3, 10, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_BMiscItem3}, + {SMARTBUFF_MiscItem4, 60, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_BMiscItem4, S.LinkFlaskMoP}, + {SMARTBUFF_MiscItem5, 10, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_BMiscItem5}, + {SMARTBUFF_MiscItem6, 60, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_BMiscItem6}, + {SMARTBUFF_MiscItem7, 60, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_BMiscItem7}, + {SMARTBUFF_MiscItem8, 5, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_BMiscItem8}, + {SMARTBUFF_AugmentRune, 60, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_BAugmentRune, S.LinkAugment}, + {SMARTBUFF_VieledAugment, 60, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_BVieledAugment, S.LinkAugment}, + {SMARTBUFF_SOAGILITY9, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBAGILITY}, + {SMARTBUFF_SOAGILITY8, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBAGILITY}, + {SMARTBUFF_SOAGILITY7, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBAGILITY}, + {SMARTBUFF_SOAGILITY6, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBAGILITY}, + {SMARTBUFF_SOAGILITY5, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBAGILITY}, + {SMARTBUFF_SOAGILITY4, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBAGILITY}, + {SMARTBUFF_SOAGILITY3, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBAGILITY}, + {SMARTBUFF_SOAGILITY2, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBAGILITY}, + {SMARTBUFF_SOAGILITY1, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBAGILITY}, + {SMARTBUFF_SOINTELLECT9, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBINTELLECT}, + {SMARTBUFF_SOINTELLECT8, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBINTELLECT}, + {SMARTBUFF_SOINTELLECT7, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBINTELLECT}, + {SMARTBUFF_SOINTELLECT6, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBINTELLECT}, + {SMARTBUFF_SOINTELLECT5, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBINTELLECT}, + {SMARTBUFF_SOINTELLECT4, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBINTELLECT}, + {SMARTBUFF_SOINTELLECT3, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBINTELLECT}, + {SMARTBUFF_SOINTELLECT2, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBINTELLECT}, + {SMARTBUFF_SOINTELLECT1, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBINTELLECT}, + {SMARTBUFF_SOSTAMINA9, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSTAMINA}, + {SMARTBUFF_SOSTAMINA8, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSTAMINA}, + {SMARTBUFF_SOSTAMINA7, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSTAMINA}, + {SMARTBUFF_SOSTAMINA6, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSTAMINA}, + {SMARTBUFF_SOSTAMINA5, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSTAMINA}, + {SMARTBUFF_SOSTAMINA4, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSTAMINA}, + {SMARTBUFF_SOSTAMINA3, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSTAMINA}, + {SMARTBUFF_SOSTAMINA2, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSTAMINA}, + {SMARTBUFF_SOSTAMINA1, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSTAMINA}, + {SMARTBUFF_SOSPIRIT9, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSPIRIT}, + {SMARTBUFF_SOSPIRIT8, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSPIRIT}, + {SMARTBUFF_SOSPIRIT7, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSPIRIT}, + {SMARTBUFF_SOSPIRIT6, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSPIRIT}, + {SMARTBUFF_SOSPIRIT5, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSPIRIT}, + {SMARTBUFF_SOSPIRIT4, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSPIRIT}, + {SMARTBUFF_SOSPIRIT3, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSPIRIT}, + {SMARTBUFF_SOSPIRIT2, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSPIRIT}, + {SMARTBUFF_SOSPIRIT1, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSPIRIT}, + {SMARTBUFF_SOSTRENGHT9, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSTRENGHT}, + {SMARTBUFF_SOSTRENGHT8, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSTRENGHT}, + {SMARTBUFF_SOSTRENGHT7, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSTRENGHT}, + {SMARTBUFF_SOSTRENGHT6, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSTRENGHT}, + {SMARTBUFF_SOSTRENGHT5, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSTRENGHT}, + {SMARTBUFF_SOSTRENGHT4, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSTRENGHT}, + {SMARTBUFF_SOSTRENGHT3, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSTRENGHT}, + {SMARTBUFF_SOSTRENGHT2, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSTRENGHT}, + {SMARTBUFF_SOSTRENGHT1, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBSTRENGHT}, + {SMARTBUFF_SOPROTECTION9, 30, SMARTBUFF_CONST_SCROLL, nil, SMARTBUFF_SBPROTECTION} + }; + + -- ItemId, SpellId, Duration [min] + AddItem(174906, 270058, 60); -- Lightning-Forged Augment Rune + AddItem(153023, 224001, 60); -- Lightforged Augment Rune + AddItem(160053, 270058, 60); --Battle-Scarred Augment Rune + AddItem(164375, 281303, 10); --Bad Mojo Banana + AddItem(129165, 193345, 10); --Barnacle-Encrusted Gem + AddItem(116115, 170869, 60); -- Blazing Wings + AddItem(133997, 203533, 0); --Black Ice + AddItem(122298, 181642, 60); --Bodyguard Miniaturization Device + AddItem(163713, 279934, 30); --Brazier Cap + AddItem(128310, 189363, 10); --Burning Blade + AddItem(116440, 171554, 20); --Burning Defender's Medallion + AddItem(128807, 192225, 60); -- Coin of Many Faces + AddItem(138878, 217668, 5); --Copy of Daglop's Contract + AddItem(143662, 232613, 60); --Crate of Bobbers: Pepe + AddItem(142529, 231319, 60); --Crate of Bobbers: Cat Head + AddItem(142530, 231338, 60); --Crate of Bobbers: Tugboat + AddItem(142528, 231291, 60); --Crate of Bobbers: Can of Worms + AddItem(142532, 231349, 60); --Crate of Bobbers: Murloc Head + AddItem(147308, 240800, 60); --Crate of Bobbers: Enchanted Bobber + AddItem(142531, 231341, 60); --Crate of Bobbers: Squeaky Duck + AddItem(147312, 240801, 60); --Crate of Bobbers: Demon Noggin + AddItem(147307, 240803, 60); --Crate of Bobbers: Carved Wooden Helm + AddItem(147309, 240806, 60); --Crate of Bobbers: Face of the Forest + AddItem(147310, 240802, 60); --Crate of Bobbers: Floating Totem + AddItem(147311, 240804, 60); --Crate of Bobbers: Replica Gondola + AddItem(122117, 179872, 15); --Cursed Feather of Ikzan + AddItem( 54653, 75532, 30); -- Darkspear Pride + AddItem(108743, 160688, 10); --Deceptia's Smoldering Boots + AddItem(129149, 193333, 30); --Death's Door Charm + AddItem(159753, 279366, 5); --Desert Flute + AddItem(164373, 281298, 10); --Enchanted Soup Stone + AddItem(140780, 224992, 5); --Fal'dorei Egg + AddItem(122304, 138927, 10); -- Fandral's Seed Pouch + AddItem(102463, 148429, 10); -- Fire-Watcher's Oath + AddItem(128471, 190655, 30); --Frostwolf Grunt's Battlegear + AddItem(128462, 190653, 30); --Karabor Councilor's Attire + AddItem(161342, 275089, 30); --Gem of Acquiescence + AddItem(127659, 188228, 60); --Ghostly Iron Buccaneer's Hat + AddItem( 54651, 75531, 30); -- Gnomeregan Pride + AddItem(118716, 175832, 5); --Goren Garb + AddItem(138900, 217708, 10); --Gravil Goldbraid's Famous Sausage Hat + AddItem(159749, 277572, 5); --Haw'li's Hot & Spicy Chili + AddItem(163742, 279997, 60); --Heartsbane Grimoire + AddItem(129149, 193333, 60); -- Helheim Spirit Memory + AddItem(140325, 223446, 10); --Home Made Party Mask + AddItem(136855, 210642,0.25); --Hunter's Call + AddItem( 43499, 58501, 10); -- Iron Boot Flask + AddItem(118244, 173956, 60); --Iron Buccaneer's Hat + AddItem(170380, 304369, 120); --Jar of Sunwarmed Sand + AddItem(127668, 187174, 5); --Jewel of Hellfire + AddItem( 26571, 127261, 10); --Kang's Bindstone + AddItem( 68806, 96312, 30); -- Kalytha's Haunted Locket + AddItem(163750, 280121, 10); --Kovork Kostume + AddItem(164347, 281302, 10); --Magic Monkey Banana + AddItem(118938, 176180, 10); --Manastorm's Duplicator + AddItem(163775, 280133, 10); --Molok Morion + AddItem(101571, 144787, 0); --Moonfang Shroud + AddItem(105898, 145255, 10); --Moonfang's Paw + AddItem( 52201, 73320, 10); --Muradin's Favor + AddItem(138873, 217597, 5); --Mystical Frosh Hat + AddItem(163795, 280308, 10); --Oomgut Ritual Drum + AddItem( 1973, 16739, 5); --Orb of Deception + AddItem( 35275, 160331, 30); --Orb of the Sin'dorei + AddItem(158149, 264091, 30); --Overtuned Corgi Goggles + AddItem(130158, 195949, 5); --Path of Elothir + AddItem(127864, 188172, 60); --Personal Spotlight + AddItem(127394, 186842, 5); --Podling Camouflage + AddItem(108739, 162402, 5); --Pretty Draenor Pearl + AddItem(129093, 129999, 10); --Ravenbear Disguise + AddItem(153179, 254485, 5); --Blue Conservatory Scroll + AddItem(153180, 254486, 5); --Yellow Conservatory Scroll + AddItem(153181, 254487, 5); --Red Conservatory Scroll + AddItem(104294, 148529, 15); --Rime of the Time-Lost Mariner + AddItem(119215, 176898, 10); --Robo-Gnomebobulator + AddItem(119134, 176569, 30); --Sargerei Disguise + AddItem(129055, 62089, 60); --Shoe Shine Kit + AddItem(163436, 279977, 30); --Spectral Visage + AddItem(156871, 261981, 60); --Spitzy + AddItem( 66888, 6405, 3); --Stave of Fur and Claw + AddItem(111476, 169291, 5); --Stolen Breath + AddItem(140160, 222630, 10); --Stormforged Vrykul Horn + AddItem(163738, 279983, 30); --Syndicate Mask + AddItem(130147, 195509, 5); --Thistleleaf Branch + AddItem(113375, 166592, 5); --Vindicator's Armor Polish Kit + AddItem(163565, 279407, 5); --Vulpera Scrapper's Armor + AddItem(163924, 280632, 30); --Whiskerwax Candle + AddItem( 97919, 141917, 3); --Whole-Body Shrinka' + AddItem(167698, 293671, 60); --Secret Fish Goggles + AddItem(169109, 299445, 60); --Beeholder's Goggles + + + -- Potions + SMARTBUFF_POTION = { + {SMARTBUFF_ELIXIRTBC1, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRTBC1}, + {SMARTBUFF_ELIXIRTBC2, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRTBC2}, + {SMARTBUFF_ELIXIRTBC3, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRTBC3}, + {SMARTBUFF_ELIXIRTBC4, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRTBC4}, + {SMARTBUFF_ELIXIRTBC5, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRTBC5}, + {SMARTBUFF_ELIXIRTBC6, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRTBC6}, + {SMARTBUFF_ELIXIRTBC7, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRTBC7}, + {SMARTBUFF_ELIXIRTBC8, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRTBC8}, + {SMARTBUFF_ELIXIRTBC9, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRTBC9}, + {SMARTBUFF_ELIXIRTBC10, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRTBC10}, + {SMARTBUFF_ELIXIRTBC11, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRTBC11}, + {SMARTBUFF_ELIXIRTBC12, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRTBC12}, + {SMARTBUFF_ELIXIRTBC13, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRTBC13}, + {SMARTBUFF_ELIXIRTBC14, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRTBC14}, + {SMARTBUFF_ELIXIRTBC15, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRTBC15}, + {SMARTBUFF_ELIXIRTBC16, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRTBC16}, + {SMARTBUFF_ELIXIRTBC17, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRTBC17}, + {SMARTBUFF_FLASKTBC1, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKTBC1}, --, S.LinkFlaskTBC}, + {SMARTBUFF_FLASKTBC2, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKTBC2}, + {SMARTBUFF_FLASKTBC3, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKTBC3}, + {SMARTBUFF_FLASKTBC4, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKTBC4}, + {SMARTBUFF_FLASKTBC5, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKTBC5}, + {SMARTBUFF_FLASKLEG1, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKLEG1, S.LinkFlaskLeg}, + {SMARTBUFF_FLASKLEG2, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKLEG2}, + {SMARTBUFF_FLASKLEG3, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKLEG3}, + {SMARTBUFF_FLASKLEG4, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKLEG4}, + {SMARTBUFF_FLASKWOD1, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKWOD1, S.LinkFlaskWoD}, + {SMARTBUFF_FLASKWOD2, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKWOD2}, + {SMARTBUFF_FLASKWOD3, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKWOD3}, + {SMARTBUFF_FLASKWOD4, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKWOD4}, + {SMARTBUFF_GRFLASKWOD1, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BGRFLASKWOD1}, + {SMARTBUFF_GRFLASKWOD2, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BGRFLASKWOD2}, + {SMARTBUFF_GRFLASKWOD3, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BGRFLASKWOD3}, + {SMARTBUFF_GRFLASKWOD4, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BGRFLASKWOD4}, + {SMARTBUFF_FLASKMOP1, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKMOP1, S.LinkFlaskMoP}, + {SMARTBUFF_FLASKMOP2, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKMOP2}, + {SMARTBUFF_FLASKMOP3, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKMOP3}, + {SMARTBUFF_FLASKMOP4, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKMOP4}, + {SMARTBUFF_FLASKMOP5, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKMOP5}, + {SMARTBUFF_FLASKMOP6, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKMOP6}, + {SMARTBUFF_ELIXIRMOP1, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRMOP1}, + {SMARTBUFF_ELIXIRMOP2, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRMOP2}, + {SMARTBUFF_ELIXIRMOP3, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRMOP3}, + {SMARTBUFF_ELIXIRMOP4, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRMOP4}, + {SMARTBUFF_ELIXIRMOP5, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRMOP5}, + {SMARTBUFF_ELIXIRMOP6, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRMOP6}, + {SMARTBUFF_ELIXIRMOP7, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRMOP7}, + {SMARTBUFF_ELIXIRMOP8, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRMOP8}, + {SMARTBUFF_EXP_POTION, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BEXP_POTION}, + {SMARTBUFF_FLASKCT1, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKCT1}, + {SMARTBUFF_FLASKCT2, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKCT2}, + {SMARTBUFF_FLASKCT3, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKCT3}, + {SMARTBUFF_FLASKCT4, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKCT4}, + {SMARTBUFF_FLASKCT5, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKCT5}, + {SMARTBUFF_FLASKCT7, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKCT7, S.LinkFlaskCT7}, + {SMARTBUFF_ELIXIRCT1, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRCT1}, + {SMARTBUFF_ELIXIRCT2, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRCT2}, + {SMARTBUFF_ELIXIRCT3, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRCT3}, + {SMARTBUFF_ELIXIRCT4, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRCT4}, + {SMARTBUFF_ELIXIRCT5, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRCT5}, + {SMARTBUFF_ELIXIRCT6, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRCT6}, + {SMARTBUFF_ELIXIRCT7, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRCT7}, + {SMARTBUFF_ELIXIRCT8, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIRCT8}, + {SMARTBUFF_FLASK1, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASK1}, + {SMARTBUFF_FLASK2, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASK2}, + {SMARTBUFF_FLASK3, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASK3}, + {SMARTBUFF_FLASK4, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASK4}, + {SMARTBUFF_ELIXIR1, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIR1}, + {SMARTBUFF_ELIXIR2, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIR2}, + {SMARTBUFF_ELIXIR3, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIR3}, + {SMARTBUFF_ELIXIR4, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIR4}, + {SMARTBUFF_ELIXIR5, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIR5}, + {SMARTBUFF_ELIXIR6, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIR6}, + {SMARTBUFF_ELIXIR7, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIR7}, + {SMARTBUFF_ELIXIR8, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIR8}, + {SMARTBUFF_ELIXIR9, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIR9}, + {SMARTBUFF_ELIXIR10, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIR10}, + {SMARTBUFF_ELIXIR11, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIR11}, + {SMARTBUFF_ELIXIR12, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIR12}, + {SMARTBUFF_ELIXIR13, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIR13}, + {SMARTBUFF_ELIXIR14, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIR14}, + {SMARTBUFF_ELIXIR15, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIR15}, + {SMARTBUFF_ELIXIR16, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BELIXIR16}, + {SMARTBUFF_FLASKBFA1, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKBFA1, S.LinkFlaskBfA}, + {SMARTBUFF_FLASKBFA2, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKBFA2}, + {SMARTBUFF_FLASKBFA3, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKBFA3}, + {SMARTBUFF_FLASKBFA4, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKBFA4}, + {SMARTBUFF_GRFLASKBFA1, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BGRFLASKBFA1}, + {SMARTBUFF_GRFLASKBFA2, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BGRFLASKBFA2}, + {SMARTBUFF_GRFLASKBFA3, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BGRFLASKBFA3}, + {SMARTBUFF_GRFLASKBFA4, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BGRFLASKBFA4}, + {SMARTBUFF_FLASKSL1, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKSL1, S.LinkFlaskSL}, + {SMARTBUFF_FLASKSL2, 60, SMARTBUFF_CONST_POTION, nil, SMARTBUFF_BFLASKSL2} + } + + SMARTBUFF_AddMsgD("Spell list initialized"); + +-- LoadToys(); + +end diff --git a/SmartBuff.globals.lua b/SmartBuff.globals.lua new file mode 100644 index 0000000..7512d1c --- /dev/null +++ b/SmartBuff.globals.lua @@ -0,0 +1,54 @@ +------------------------------------------------------------------------------- +-- Globals +------------------------------------------------------------------------------- + +SMARTBUFF_GLOBALS = { }; +local SG = SMARTBUFF_GLOBALS; + +SMARTBUFF_TTC_R = 1; +SMARTBUFF_TTC_G = 1; +SMARTBUFF_TTC_B = 1; +SMARTBUFF_TTC_A = 1; + +SMARTBUFF_OPTIONSFRAME_HEIGHT = 720; +SMARTBUFF_OPTIONSFRAME_WIDTH = 500; + +SMARTBUFF_ACTION_ITEM = "item"; +SMARTBUFF_ACTION_SPELL = "spell"; + +SMARTBUFF_CONST_AUTOSOUND = "Deathbind Sound"; +--SMARTBUFF_CONST_AUTOSOUND = "TaxiNodeDiscovered"; +--SMARTBUFF_CONST_AUTOSOUND = "GLUECREATECHARACTERBUTTON"; + +--[[ +SystemFont +GameFontNormal +GameFontNormalSmall +GameFontNormalLarge +GameFontHighlight +GameFontHighlightSmall +GameFontHighlightSmallOutline +GameFontHighlightLarge +GameFontDisable +GameFontDisableSmall +GameFontDisableLarge +GameFontGreen +GameFontGreenSmall +GameFontGreenLarge +GameFontRed +GameFontRedSmall +GameFontRedLarge +GameFontWhite +GameFontDarkGraySmall +NumberFontNormalYellow +NumberFontNormalSmallGray +QuestFontNormalSmall +DialogButtonHighlightText +ErrorFont +TextStatusBarText +CombatLogFont +NumberFontNormalLarge +NumberFontNormalHuge +]]-- + + diff --git a/SmartBuff.lua b/SmartBuff.lua new file mode 100644 index 0000000..284d330 --- /dev/null +++ b/SmartBuff.lua @@ -0,0 +1,4599 @@ +------------------------------------------------------------------------------- +-- SmartBuff +-- Originally created by Aeldra (EU-Proudmoore) +-- Retail version fixes / improvements by Codermik +-- Discord: https://discord.gg/R6EkZ94TKK +-- Cast the most important buffs on you, tanks or party/raid members/pets. +------------------------------------------------------------------------------- + +SMARTBUFF_DATE = "191222"; + +SMARTBUFF_VERSION = "r15."..SMARTBUFF_DATE; +SMARTBUFF_VERSIONNR = 100002; +SMARTBUFF_TITLE = "SmartBuff"; +SMARTBUFF_SUBTITLE = "Supports you in casting buffs"; +SMARTBUFF_DESC = "Cast the most important buffs on you, your tanks, party/raid members/pets"; +SMARTBUFF_VERS_TITLE = SMARTBUFF_TITLE .. " " .. SMARTBUFF_VERSION; +SMARTBUFF_OPTIONS_TITLE = SMARTBUFF_VERS_TITLE.." Retail "; + +-- addon name +local addonName = ... +local SmartbuffPrefix = "Smartbuff"; +local SmartbuffSession = true; +local SmartbuffVerCheck = false; -- for my use when checking guild users/testers versions :) +local buildInfo = select(4, GetBuildInfo()) +local SmartbuffRevision = 15; +local SmartbuffVerNotifyList = {} + +local SG = SMARTBUFF_GLOBALS; +local OG = nil; -- Options global +local O = nil; -- Options local +local B = nil; -- Buff settings local +local _; + +BINDING_HEADER_SMARTBUFF = "SmartBuff"; +SMARTBUFF_BOOK_TYPE_SPELL = "spell"; + + +local GlobalCd = 1.5; +local maxSkipCoolDown = 3; +local maxRaid = 40; +local maxBuffs = 40; +local maxScrollButtons = 23; +local numBuffs = 0; + +local isLoaded = false; +local isPlayer = false; +local isInit = false; +local isCombat = false; +local isSetBuffs = false; +local isSetZone = false; +local isFirstError = false; +local isMounted = false; +local isCTRA = true; +local isSetUnits = false; +local isKeyUpChanged = false; +local isKeyDownChanged = false; +local isAuraChanged = false; +local isClearSplash = false; +local isRebinding = false; +local isParrot = false; +local isSync = false; +local isSyncReq = false; +local isInitBtn = false; + +local isShapeshifted = false; +local sShapename = ""; + +local tStartZone = 0; +local tTicker = 0; +local tSync = 0; + +local sRealmName = nil; +local sPlayerName = nil; +local sID = nil; +local sPlayerClass = nil; +local tLastCheck = 0; +local iGroupSetup = -1; +local iLastBuffSetup = -1; +local sLastTexture = ""; +local iLastGroupSetup = -99; +local sLastZone = ""; +local tAutoBuff = 0; +local tDebuff = 0; +local sMsgWarning = ""; +local iCurrentFont = 1; +local iCurrentList = -1; +local iLastPlayer = -1; + +local isPlayerMoving = false; + +local cGroups = { }; +local cClassGroups = { }; +local cBuffs = { }; +local cBuffIndex = { }; +local cBuffTimer = { }; +local cBlacklist = { }; +local cUnits = { }; +local cBuffsCombat = { }; + +local cScrBtnBO = nil; + +local cAddUnitList = { }; +local cIgnoreUnitList = { }; + +local cClasses = {"DRUID", "HUNTER", "MAGE", "PALADIN", "PRIEST", "ROGUE", "SHAMAN", "WARLOCK", "WARRIOR", "DEATHKNIGHT", "MONK", "DEMONHUNTER", "EVOKER", "HPET", "WPET", "DKPET", "TANK", "HEALER", "DAMAGER"}; +local cOrderGrp = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; +local cFonts = {"NumberFontNormal", "NumberFontNormalLarge", "NumberFontNormalHuge", "GameFontNormal", "GameFontNormalLarge", "GameFontNormalHuge", "ChatFontNormal", "QuestFont", "MailTextFontNormal", "QuestTitleFont"}; + +local currentUnit = nil; +local currentSpell = nil; +local currentTemplate = nil; +local currentSpec = nil; + +local imgSB = "Interface\\Icons\\Spell_Nature_Purge"; +local imgIconOn = "Interface\\AddOns\\SmartBuff\\Icons\\MiniMapButtonEnabled"; +local imgIconOff = "Interface\\AddOns\\SmartBuff\\Icons\\MiniMapButtonDisabled"; + +local IconPaths = { + ["Pet"] = "Interface\\Icons\\spell_nature_spiritwolf", + ["Roles"] = "Interface\\LFGFrame\\UI-LFG-ICON-PORTRAITROLES", + ["Classes"] = "Interface\\WorldStateFrame\\Icons-Classes", +}; + +local Icons = { + ["WARRIOR"] = { IconPaths.Classes, 0.00, 0.25, 0.00, 0.25 }, + ["MAGE"] = { IconPaths.Classes, 0.25, 0.50, 0.00, 0.25 }, + ["ROGUE"] = { IconPaths.Classes, 0.50, 0.75, 0.00, 0.25 }, + ["DRUID"] = { IconPaths.Classes, 0.75, 1.00, 0.00, 0.25 }, + ["HUNTER"] = { IconPaths.Classes, 0.00, 0.25, 0.25, 0.50 }, + ["SHAMAN"] = { IconPaths.Classes, 0.25, 0.50, 0.25, 0.50 }, + ["PRIEST"] = { IconPaths.Classes, 0.50, 0.75, 0.25, 0.50 }, + ["WARLOCK"] = { IconPaths.Classes, 0.75, 1.00, 0.25, 0.50 }, + ["PALADIN"] = { IconPaths.Classes, 0.00, 0.25, 0.50, 0.75 }, + ["DEATHKNIGHT"] = { IconPaths.Classes, 0.25, 0.50, 0.50, 0.75 }, + ["MONK"] = { IconPaths.Classes, 0.50, 0.75, 0.50, 0.75 }, + ["DEMONHUNTER"] = { IconPaths.Classes, 0.75, 1.00, 0.50, 0.75 }, + ["EVOKER"] = { IconPaths.Classes, 0.75, 1.00, 0.50, 0.75 }, + ["PET"] = { IconPaths.Pet, 0.08, 0.92, 0.08, 0.92}, + ["TANK"] = { IconPaths.Roles, 0.0, 19/64, 22/64, 41/64 }, + ["HEALER"] = { IconPaths.Roles, 20/64, 39/64, 1/64, 20/64 }, + ["DAMAGER"] = { IconPaths.Roles, 20/64, 39/64, 22/64, 41/64 }, + ["NONE"] = { IconPaths.Roles, 20/64, 39/64, 22/64, 41/64 }, +}; + +-- available sounds (25) +local Sounds = { 1141, 3784, 4574, 17318, 15262, 13830, 15273, 10042, 10720, 17316, 3337, 7894, 7914, 10033, 416, 57207, 78626, 49432, 10571, 58194, 21970, 17339, 84261, 43765} + +local DebugChatFrame = DEFAULT_CHAT_FRAME; + +-- Popup +StaticPopupDialogs["SMARTBUFF_DATA_PURGE"] = { + text = SMARTBUFF_OFT_PURGE_DATA, + button1 = SMARTBUFF_OFT_YES, + button2 = SMARTBUFF_OFT_NO, + OnAccept = function() SMARTBUFF_ResetAll() end, + timeout = 0, + whileDead = 1, + hideOnEscape = 1 +} + + +-- Rounds a number to the given number of decimal places. +local r_mult; +local function Round(num, idp) + r_mult = 10^(idp or 0); + return math.floor(num * r_mult + 0.5) / r_mult; +end + +-- Returns a chat color code string +local function BCC(r, g, b) + return string.format("|cff%02x%02x%02x", (r*255), (g*255), (b*255)); +end + +local BL = BCC(0, 0, 1); +local BLD = BCC(0, 0, 0.7); +local BLL = BCC(0.5, 0.8, 1); +local GR = BCC(0, 1, 0); +local GRD = BCC(0, 0.7, 0); +local GRL = BCC(0.6, 1, 0.6); +local RD = BCC(1, 0, 0); +local RDD = BCC(0.7, 0, 0); +local RDL = BCC(1, 0.3, 0.3); +local YL = BCC(1, 1, 0); +local YLD = BCC(0.7, 0.7, 0); +local YLL = BCC(1, 1, 0.5); +local OR = BCC(1, 0.7, 0); +local ORD = BCC(0.7, 0.5, 0); +local ORL = BCC(1, 0.6, 0.3); +local WH = BCC(1, 1, 1); +local CY = BCC(0.5, 1, 1); + +-- function to preview selected warning sound in options screen +function SMARTBUFF_PlaySpashSound() + PlaySound(Sounds[O.AutoSoundSelection]); +end + +-- Reorders values in the table +local function treorder(t, i, n) + if (t and type(t) == "table" and t[i]) then + local s = t[i]; + tremove(t, i); + if (i + n < 1) then + tinsert(t, 1, s); + elseif (i + n > #t) then + tinsert(t, s); + else + tinsert(t, i + n, s); + end + end +end + +-- Finds a value in the table and returns the index +local function tfind(t, s) + if (t and type(t) == "table" and s) then + for k, v in pairs(t) do + if (v and v == s) then + return k; + end + end + end + return false; +end + +local function ChkS(text) + if (text == nil) then + text = ""; + end + return text; +end + +local function IsVisibleToPlayer(self) + if (not self) then return false; end + + local w, h = UIParent:GetWidth(), UIParent:GetHeight(); + local x, y = self:GetLeft(), UIParent:GetHeight() - self:GetTop(); + + --print(format("w = %.0f, h = %.0f, x = %.0f, y = %.0f", w, h, x, y)); + if (x >= 0 and x < (w - self:GetWidth()) and y >= 0 and y < (h - self:GetHeight())) then + return true; + end + return false; +end + + +local function CS() + if (currentSpec == nil) then + currentSpec = GetSpecialization(); + end + if (currentSpec == nil) then + currentSpec = 1; + SMARTBUFF_AddMsgErr("Could not detect active talent group, set to default = 1"); + end + return currentSpec; +end + +local function CT() + return currentTemplate; +end + +local function GetBuffSettings(buff) + if (B and buff) then + return B[CS()][CT()][buff]; + end + return nil; +end + +local function InitBuffSettings(cBI, reset) + local buff = cBI.BuffS; + local cBuff = GetBuffSettings(buff); + if (cBuff == nil) then + B[CS()][CT()][buff] = { }; + cBuff = B[CS()][CT()][buff]; + reset = true; + end + + if (reset) then + wipe(cBuff); + cBuff.EnableS = false; + cBuff.EnableG = false; + cBuff.SelfOnly = false; + cBuff.SelfNot = false; + cBuff.CIn = false; + cBuff.COut = true; + cBuff.MH = false; + cBuff.OH = false; + cBuff.RH = false; + cBuff.Reminder = true; + cBuff.RBTime = 0; + cBuff.ManaLimit = 0; + if (cBI.Type == SMARTBUFF_CONST_GROUP or cBI.Type == SMARTBUFF_CONST_ITEMGROUP) then + for n in pairs(cClasses) do + if (cBI.Type == SMARTBUFF_CONST_GROUP and n <= 13 and not string.find(cBI.Params, cClasses[n])) then + cBuff[cClasses[n]] = true; + else + cBuff[cClasses[n]] = false; + end + end + end + end + + -- Upgrades + if (cBuff.RBTime == nil) then cBuff.Reminder = true; cBuff.RBTime = 0; end -- to 1.10g + if (cBuff.ManaLimit == nil) then cBuff.ManaLimit = 0; end -- to 1.12b + if (cBuff.SelfNot == nil) then cBuff.SelfNot = false; end -- to 2.0i + if (cBuff.AddList == nil) then cBuff.AddList = { }; end -- to 2.1a + if (cBuff.IgnoreList == nil) then cBuff.IgnoreList = { }; end -- to 2.1a + if (cBuff.RH == nil) then cBuff.RH = false; end -- to 4.0b + +end + +local function InitBuffOrder(reset) + if (B[CS()].Order == nil) then + B[CS()].Order = { }; + end + + local b; + local i; + local ord = B[CS()].Order; + if (reset) then + wipe(ord); + SMARTBUFF_AddMsgD("Reset buff order"); + end + + -- Remove not longer existing buffs in the order list + for k, v in pairs(ord) do + if (v and cBuffIndex[v] == nil) then + SMARTBUFF_AddMsgD("Remove from buff order: "..v); + tremove(ord, k); + end + end + + i = 1; + while (cBuffs[i] and cBuffs[i].BuffS) do + b = false; + for _, v in pairs(ord) do + if (v and v == cBuffs[i].BuffS) then + b = true; + break; + end + end + -- buff not found add it to order list + if (not b) then + tinsert(ord, cBuffs[i].BuffS); + SMARTBUFF_AddMsgD("Add to buff order: "..cBuffs[i].BuffS); + end + i = i + 1; + end +end + +local function IsMinLevel(minLevel) + if (not minLevel) then + return true; + end + if (minLevel > UnitLevel("player")) then + return false; + end + return true; +end + +local function IsPlayerInGuild() + return IsInGuild() -- and GetGuildInfo("player") +end + +local function SendSmartbuffVersion(player, unit) + -- if ive announced to this player / the player is me then just return. + if player == UnitName("player") then return end + for count,value in ipairs(SmartbuffVerNotifyList) do + if value[1] == player then return end + end + -- not announced, add the player and announce. + tinsert(SmartbuffVerNotifyList, {player, unit, GetTime()}) + C_ChatInfo.SendAddonMessage(SmartbuffPrefix, SmartbuffRevision, "WHISPER", player) +end + +-- TODO: Redesign if reactivated! +local function IsTalentSkilled(t, i, name) + local _, tName, _, _, tAvailable = GetTalentInfo(t, i); + if (tName) then + isTTreeLoaded = true; + SMARTBUFF_AddMsgD("Talent: "..tName..", Points = "..tAvailable); + if (name and name == tName and tAvailable > 0) then + SMARTBUFF_AddMsgD("Debuff talent found: "..name..", Points = "..tAvailable); + return true, tAvailable; + end + else + SMARTBUFF_AddMsgD("Talent tree not available!"); + isTTreeLoaded = false; + end + return false, 0; +end + + +-- SMARTBUFF_OnLoad +function SMARTBUFF_OnLoad(self) + self:RegisterEvent("ADDON_LOADED"); + self:RegisterEvent("PLAYER_LOGIN"); -- added + self:RegisterEvent("PLAYER_ENTERING_WORLD"); + self:RegisterEvent("UNIT_NAME_UPDATE"); + self:RegisterEvent("GROUP_ROSTER_UPDATE"); + self:RegisterEvent("PLAYER_REGEN_ENABLED"); + self:RegisterEvent("PLAYER_REGEN_DISABLED"); + self:RegisterEvent("PLAYER_STARTED_MOVING"); -- added + self:RegisterEvent("PLAYER_STOPPED_MOVING"); -- added + self:RegisterEvent("PLAYER_TALENT_UPDATE"); + self:RegisterEvent("SPELLS_CHANGED"); + self:RegisterEvent("ACTIONBAR_HIDEGRID"); + self:RegisterEvent("UNIT_AURA"); + self:RegisterEvent("CHAT_MSG_ADDON"); + self:RegisterEvent("CHAT_MSG_CHANNEL"); + self:RegisterEvent("UPDATE_MOUSEOVER_UNIT"); + self:RegisterEvent("UNIT_SPELLCAST_FAILED"); + self:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED"); + + --One of them allows SmartBuff to be closed with the Escape key + tinsert(UISpecialFrames, "SmartBuffOptionsFrame"); + UIPanelWindows["SmartBuffOptionsFrame"] = nil; + + SlashCmdList["SMARTBUFF"] = SMARTBUFF_command; + SLASH_SMARTBUFF1 = "/sbo"; + SLASH_SMARTBUFF2 = "/sbuff"; + SLASH_SMARTBUFF3 = "/smartbuff"; + + SlashCmdList["SMARTBUFFMENU"] = SMARTBUFF_OptionsFrame_Toggle; + SLASH_SMARTBUFFMENU1 = "/sbm"; + + SlashCmdList["SmartReloadUI"] = function(msg) ReloadUI(); end; + SLASH_SmartReloadUI1 = "/rui"; + + SMARTBUFF_InitSpellIDs(); + + --DEFAULT_CHAT_FRAME:AddMessage("SB OnLoad"); +end +-- END SMARTBUFF_OnLoad + + +-- SMARTBUFF_OnEvent +function SMARTBUFF_OnEvent(self, event, ...) + local arg1, arg2, arg3, arg4, arg5 = ...; + + if ((event == "UNIT_NAME_UPDATE" and arg1 == "player") or event == "PLAYER_ENTERING_WORLD") then + if IsPlayerInGuild() and event == "PLAYER_ENTERING_WORLD" then + C_ChatInfo.SendAddonMessage(SmartbuffPrefix, SmartbuffRevision, "GUILD") + end + isPlayer = true; + if (event == "PLAYER_ENTERING_WORLD" and isInit and O.Toggle) then + isSetZone = true; + tStartZone = GetTime(); + end + + elseif(event == "ADDON_LOADED" and arg1 == SMARTBUFF_TITLE) then + isLoaded = true; + end + + -- PLAYER_LOGIN + if event == "PLAYER_LOGIN" then + local prefixResult = C_ChatInfo.RegisterAddonMessagePrefix(SmartbuffPrefix) + end + + -- CHAT_MSG_ADDON + if event == "CHAT_MSG_ADDON" then + if arg1 == SmartbuffPrefix then + -- its us. + if arg2 then + arg2 = tonumber(arg2) + if arg2 > SmartbuffRevision and SmartbuffSession then + DEFAULT_CHAT_FRAME:AddMessage(SMARTBUFF_MSG_NEWVER1..SMARTBUFF_VERSION..SMARTBUFF_MSG_NEWVER2..arg2..SMARTBUFF_MSG_NEWVER3) + SmartbuffSession = false + end + if arg5 and arg5 ~= UnitName("player") and SmartbuffVerCheck then + DEFAULT_CHAT_FRAME:AddMessage("|cff00e0ffSmartbuff : |cffFFFF00"..arg5.." ("..arg3..")|cffffffff has revision |cffFFFF00r"..arg2.."|cffffffff installed.") + end + end + end + end + + if (event == "SMARTBUFF_UPDATE" and isLoaded and isPlayer and not isInit and not InCombatLockdown()) then + SMARTBUFF_Options_Init(self); +-- print(buildInfo) + end + + if (not isInit or O == nil) then + return; + end; + + if (event == "GROUP_ROSTER_UPDATE") then + isSetUnits = true; + + elseif (event == "PLAYER_REGEN_DISABLED") then + SMARTBUFF_Ticker(true); + + if (O.Toggle) then + if (O.InCombat) then + for spell, data in pairs(cBuffsCombat) do + if (data and data.Unit and data.ActionType) then + if (data.Type == SMARTBUFF_CONST_SELF or data.Type == SMARTBUFF_CONST_FORCESELF or data.Type == SMARTBUFF_CONST_STANCE or data.Type == SMARTBUFF_CONST_ITEM) then + SmartBuff_KeyButton:SetAttribute("unit", nil); + else + SmartBuff_KeyButton:SetAttribute("unit", data.Unit); + end + SmartBuff_KeyButton:SetAttribute("type", data.ActionType); + SmartBuff_KeyButton:SetAttribute("spell", spell); + SmartBuff_KeyButton:SetAttribute("item", nil); + SmartBuff_KeyButton:SetAttribute("target-slot", nil); + SmartBuff_KeyButton:SetAttribute("target-item", nil); + SmartBuff_KeyButton:SetAttribute("macrotext", nil); + SmartBuff_KeyButton:SetAttribute("action", nil); + SMARTBUFF_AddMsgD("Enter Combat, set button: " .. spell .. " on " .. data.Unit .. ", " .. data.ActionType); + break; + end + end + end + SMARTBUFF_SyncBuffTimers(); + SMARTBUFF_Check(1, true); + end + + elseif (event == "PLAYER_REGEN_ENABLED") then + SMARTBUFF_Ticker(true); + + if (O.Toggle) then + if (O.InCombat) then + SmartBuff_KeyButton:SetAttribute("type", nil); + SmartBuff_KeyButton:SetAttribute("unit", nil); + SmartBuff_KeyButton:SetAttribute("spell", nil); + end + SMARTBUFF_SyncBuffTimers(); + SMARTBUFF_Check(1, true); + end + + -- PLAYER_STARTED_MOVING / PLAYER_STOPPED_MOVING + elseif (event == "PLAYER_STARTED_MOVING") then + isPlayerMoving = true; + + elseif (event == "PLAYER_STOPPED_MOVING") then + isPlayerMoving = false; + + elseif (event == "PLAYER_TALENT_UPDATE") then + if(SmartBuffOptionsFrame:IsVisible()) then + SmartBuffOptionsFrame:Hide(); + end + if (currentSpec ~= GetSpecialization()) then + currentSpec = GetSpecialization(); + if (B[currentSpec] == nil) then + B[currentSpec] = { }; + end + SMARTBUFF_AddMsg(format(SMARTBUFF_MSG_SPECCHANGED, tostring(currentSpec)), true); + isSetBuffs = true; + end + + elseif (event == "SPELLS_CHANGED" or event == "ACTIONBAR_HIDEGRID") then + isSetBuffs = true; + end + + if (not O.Toggle) then + return; + end; + + if (event == "UNIT_AURA") then + + if (UnitAffectingCombat("player") and (arg1 == "player" or string.find(arg1, "^party") or string.find(arg1, "^raid"))) then + isSyncReq = true; + end + + -- checks if aspect of cheetah or pack is active and cancel it if someone gets dazed + if (sPlayerClass == "HUNTER" and O.AntiDaze and (arg1 == "player" or string.find(arg1, "^party") or string.find(arg1, "^raid") or string.find(arg1, "pet"))) then + local _, _, stuntex = GetSpellInfo(1604); --get Dazed icon + if (SMARTBUFF_IsDebuffTexture(arg1, stuntex)) then + buff = nil; + if (arg1 == "player" and SMARTBUFF_CheckBuff(arg1, SMARTBUFF_AOTC)) then + buff = SMARTBUFF_AOTC; + elseif (SMARTBUFF_CheckBuff(arg1, SMARTBUFF_AOTP, true)) then + buff = SMARTBUFF_AOTP; + end + if (buff) then + if (O.ToggleAutoSplash and not SmartBuffOptionsFrame:IsVisible()) then + SmartBuffSplashFrame:Clear(); + SmartBuffSplashFrame:SetTimeVisible(1); + SmartBuffSplashFrame:AddMessage("!!! CANCEL "..buff.." !!!", O.ColSplashFont.r, O.ColSplashFont.g, O.ColSplashFont.b, 1.0); + end + if (O.ToggleAutoChat) then + SMARTBUFF_AddMsgWarn("!!! CANCEL "..buff.." !!!", true); + end + end + end + end + end + + if (event == "UI_ERROR_MESSAGE") then + SMARTBUFF_AddMsgD(string.format("Error message: %s",arg1)); + end + + if (event == "UNIT_SPELLCAST_FAILED") then + currentUnit = arg1; + SMARTBUFF_AddMsgD(string.format("Spell failed: %s",arg1)); + if (currentUnit and (string.find(currentUnit, "party") or string.find(currentUnit, "raid") or (currentUnit == "target" and O.Debug))) then + if (UnitName(currentUnit) ~= sPlayerName and O.BlacklistTimer > 0) then + cBlacklist[currentUnit] = GetTime(); + if (currentUnit and UnitName(currentUnit)) then + end + end + end + currentUnit = nil; + + elseif (event == "UNIT_SPELLCAST_SUCCEEDED") then + if (arg1 and arg1 == "player") then + local unit = nil; + local spell = nil; + local target = nil; + + if (arg1 and arg2) then + if (not arg3) then arg3 = ""; end + if (not arg4) then arg4 = ""; end + SMARTBUFF_AddMsgD("Spellcast succeeded: " .. arg1 .. ", " .. arg2 .. ", " .. arg3 .. ", " .. arg4) + if (string.find(arg1, "party") or string.find(arg1, "raid")) then + spell = arg2; + end + --SMARTBUFF_SetButtonTexture(SmartBuff_KeyButton, imgSB); + end + + if (currentUnit and currentSpell and currentUnit ~= "target") then + unit = currentUnit; + spell = currentSpell; + end + + if (unit) then + local name = UnitName(unit); + if (cBuffTimer[unit] == nil) then + cBuffTimer[unit] = { }; + end + cBuffTimer[unit][spell] = GetTime(); + if (name ~= nil) then + SMARTBUFF_AddMsg(name .. ": " .. spell .. " " .. SMARTBUFF_MSG_BUFFED); + currentUnit = nil; + currentSpell = nil; + end + end + + if (isClearSplash) then + isClearSplash = false; + SMARTBUFF_Splash_Clear(); + end + + end + + end + +end +-- END SMARTBUFF_OnEvent + + +function SMARTBUFF_OnUpdate(self, elapsed) + if not self.Elapsed then + self.Elapsed = 0.2 + end + self.Elapsed = self.Elapsed - elapsed + if self.Elapsed > 0 then + return + end + self.Elapsed = 0.2 + + if (not isInit) then + if (isLoaded and GetTime() > tAutoBuff + 0.5) then + tAutoBuff = GetTime(); + local specID = GetSpecialization() + if (specID) then + SMARTBUFF_OnEvent(self, "SMARTBUFF_UPDATE"); + end + end + else + if (isSetZone and GetTime() > (tStartZone + 4)) then + SMARTBUFF_CheckLocation(); + end + SMARTBUFF_Ticker(); + SMARTBUFF_Check(1); + end +end + +function SMARTBUFF_Ticker(force) + if (force or GetTime() > tTicker + 1) then + tTicker = GetTime(); + + if (isSetUnits) then + isSetUnits = false; + SMARTBUFF_SetUnits(); + isSyncReq = true; + end + + if (isSyncReq or tTicker > tSync + 10) then + SMARTBUFF_SyncBuffTimers(); + end + + if (isAuraChanged) then + isAuraChanged = false; + SMARTBUFF_Check(1, true); + end + + end +end + + +-- Will dump the value of msg to the default chat window +function SMARTBUFF_AddMsg(msg, force) + if (DEFAULT_CHAT_FRAME and (force or not O.ToggleMsgNormal)) then + DEFAULT_CHAT_FRAME:AddMessage(YLL .. msg .. "|r"); + end +end + +function SMARTBUFF_AddMsgErr(msg, force) + if (DEFAULT_CHAT_FRAME and (force or not O.ToggleMsgError)) then + DEFAULT_CHAT_FRAME:AddMessage(RDL .. SMARTBUFF_TITLE .. ": " .. msg .. "|r"); + end +end + +function SMARTBUFF_AddMsgWarn(msg, force) + if (DEFAULT_CHAT_FRAME and (force or not O.ToggleMsgWarning)) then + if (isParrot) then + Parrot:ShowMessage(CY .. msg .. "|r"); + else + DEFAULT_CHAT_FRAME:AddMessage(CY .. msg .. "|r"); + end + end +end + +function SMARTBUFF_AddMsgD(msg, r, g, b) + if (r == nil) then r = 0.5; end + if (g == nil) then g = 0.8; end + if (b == nil) then b = 1; end + if (DebugChatFrame and O and O.Debug) then + DebugChatFrame:AddMessage(msg, r, g, b); + end +end + + +-- Creates an array of units +function SMARTBUFF_SetUnits() + if (InCombatLockdown()) then + isSetUnits = true; + return; + end + if (SmartBuffOptionsFrame:IsVisible()) then return; end + + local i = 0; + local n = 0; + local j = 0; + local s = nil; + local psg = 0; + local b = false; + local f = nil + local iBFA = SMARTBUFF_IsActiveBattlefield(); + + if (iBFA > 0) then + SMARTBUFF_CheckLocation(); + end + + -- player + -- pet + -- party1-4 + -- partypet1-4 + -- raid1-40 + -- raidpet1-40 + + iGroupSetup = -1; + if (IsInRaid()) then + iGroupSetup = 3; + elseif (GetNumSubgroupMembers() ~= 0) then + iGroupSetup = 2; + else + iGroupSetup = 1; + end + + if (iGroupSetup ~= iLastGroupSetup) then + iLastGroupSetup = iGroupSetup; + wipe(cBlacklist); + wipe(cBuffTimer); + if (SMARTBUFF_TEMPLATES[iGroupSetup] == nil) then + SMARTBUFF_SetBuffs(); + end + local tmp = SMARTBUFF_TEMPLATES[iGroupSetup]; + if (O.AutoSwitchTemplate and currentTemplate ~= tmp and iBFA == 0) then + SMARTBUFF_AddMsg(SMARTBUFF_OFT_AUTOSWITCHTMP .. ": " .. currentTemplate .. " -> " .. tmp); + currentTemplate = tmp; + SMARTBUFF_SetBuffs(); + end + --SMARTBUFF_AddMsgD("Group type changed"); + end + + wipe(cUnits); + wipe(cGroups); + cClassGroups = nil; + wipe(cAddUnitList); + wipe(cIgnoreUnitList); + + -- Raid Setup + if (iGroupSetup == 3) then + cClassGroups = { }; + local name, server, rank, subgroup, level, class, classeng, zone, online, isDead; + local sRUnit = nil; + + j = 1; + for n = 1, maxRaid, 1 do + name, rank, subgroup, level, class, classeng, zone, online, isDead = GetRaidRosterInfo(n); + if (name) then + server = nil; + f = name; + i = string.find(name, "-", 1, true); + if (i and i > 0) then + server = string.sub(name, i + 1); + name = string.sub(name, 1, i - 1); + SMARTBUFF_AddMsgD(name .. ", " .. server); + end + sRUnit = "raid"..n; + + --SMARTBUFF_AddMsgD(name .. ", " .. sRUnit .. ", " .. UnitName(sRUnit)); + + SMARTBUFF_AddUnitToClass("raid", n); + SmartBuff_AddToUnitList(1, sRUnit, subgroup); + SmartBuff_AddToUnitList(2, sRUnit, subgroup); + + if (name == sPlayerName and not server) then + psg = subgroup; + end + + if (O.ToggleGrp[subgroup]) then + s = ""; + if (name == UnitName(sRUnit)) then + if (cGroups[subgroup] == nil) then + cGroups[subgroup] = { }; + end + if (name == sPlayerName and not server) then b = true; end + cGroups[subgroup][j] = sRUnit; + j = j + 1; + end + end + -- attempt to announce the addon version (if they have it) +-- if online and O.SendVerInfo then SendSmartbuffVersion(f, sRUnit) end + end + end --end for + + if (not b or B[CS()][currentTemplate].SelfFirst) then + SMARTBUFF_AddSoloSetup(); + --SMARTBUFF_AddMsgD("Player not in selected groups or buff self first"); + end + + SMARTBUFF_AddMsgD("Raid Unit-Setup finished"); + + -- Party Setup + elseif (iGroupSetup == 2) then + cClassGroups = { }; + if (B[CS()][currentTemplate].SelfFirst) then + SMARTBUFF_AddSoloSetup(); + --SMARTBUFF_AddMsgD("Buff self first"); + end + + cGroups[1] = { }; + cGroups[1][0] = "player"; + SMARTBUFF_AddUnitToClass("player", 0); + for j = 1, 4, 1 do + cGroups[1][j] = "party"..j; + SMARTBUFF_AddUnitToClass("party", j); + SmartBuff_AddToUnitList(1, "party"..j, 1); + SmartBuff_AddToUnitList(2, "party"..j, 1); + name, _, _, _, _, _, _, online, _, _ = GetRaidRosterInfo(j); + if name and online then SendSmartbuffVersion(name, "party") end + end + SMARTBUFF_AddMsgD("Party Unit-Setup finished"); + + -- Solo Setup + else + SMARTBUFF_AddSoloSetup(); + SMARTBUFF_AddMsgD("Solo Unit-Setup finished"); + end + + --collectgarbage(); +end + + +function SMARTBUFF_AddUnitToClass(unit, i) + local u = unit; + local up = "pet"; + if (unit ~= "player") then + u = unit..i; + up = unit.."pet"..i; + end + if (UnitExists(u)) then + if (not cUnits[1]) then + cUnits[1] = { }; + end + cUnits[1][i] = u; + SMARTBUFF_AddMsgD("Unit added: " .. UnitName(u) .. ", " .. u); + + local _, uc = UnitClass(u); + if (uc and not cClassGroups[uc]) then + cClassGroups[uc] = { }; + end + if (uc) then + cClassGroups[uc][i] = u; + end + end +end + +function SMARTBUFF_AddSoloSetup() + cGroups[0] = { }; + cGroups[0][0] = "player"; + cUnits[0] = { }; + cUnits[0][0] = "player"; + if (sPlayerClass == "HUNTER" or sPlayerClass == "WARLOCK" or sPlayerClass == "DEATHKNIGHT" or sPlayerClass == "MAGE") then cGroups[0][1] = "pet"; end + + if (B[CS()][currentTemplate] and B[CS()][currentTemplate].SelfFirst) then + if (not cClassGroups) then + cClassGroups = { }; + end + cClassGroups[0] = { }; + cClassGroups[0][0] = "player"; + end +end +-- END SMARTBUFF_SetUnits + + +-- Get Spell ID from spellbook +function SMARTBUFF_GetSpellID(spellname) + if (spellname) then + spellname = string.lower(spellname); + else + return nil; + end + + local i = 0; + local nSpells = 0; + local id = nil; + local spellN, spellId, skillType; + + -- Get number of spells + --for i = 1, GetNumSpellTabs() do + -- Common and specialization + for i = 1, GetNumSpellTabs() do + local _, _, _, n = GetSpellTabInfo(i); + nSpells = nSpells + n; + end + + i = 0; + while (i < nSpells) do + i = i + 1; + spellN = GetSpellBookItemName(i, BOOKTYPE_SPELL); + skillType, spellId = GetSpellBookItemInfo(i, BOOKTYPE_SPELL); + --print(spellN.." "..spellId); + + if (skillType == "FLYOUT") then + for j = 1, GetNumFlyouts() do + local fid = GetFlyoutID(j); + local name, description, numSlots, isKnown = GetFlyoutInfo(fid) + if (isKnown) then + for s = 1, numSlots do + local flySpellID, overrideSpellID, isKnown, spellN, slotSpecID = GetFlyoutSlotInfo(fid, s); + if (isKnown and string.lower(spellN) == spellname) then + --print(spellname.." "..spellN.." "..flySpellID); + return flySpellID; + end + end + end + end + end + + if (spellN ~= nil and string.lower(spellN) == spellname) then + id = spellId; + break; + end + end + + if (id) then + if (IsPassiveSpell(id) or skillType == "FUTURESPELL" or not IsSpellKnown(id)) then + id = nil; + i = nil; + end + end + + return id, i; +end +-- END SMARTBUFF_GetSpellID + +-- Set the buff array +function SMARTBUFF_SetBuffs() + if (B == nil) then return; end + + local n = 1; + local buff = nil; + local ct = currentTemplate; + + if (B[CS()] == nil) then + B[CS()] = { }; + end + + SMARTBUFF_InitItemList(); + SMARTBUFF_InitSpellList(); + + if (B[CS()][ct] == nil) then + B[CS()][ct] = { }; + B[CS()][ct].SelfFirst = false; + end + + wipe(cBuffs); + wipe(cBuffIndex); + numBuffs = 0; + + for _, buff in pairs(SMARTBUFF_BUFFLIST) do + n = SMARTBUFF_SetBuff(buff, n, true); + end + + for _, buff in pairs(SMARTBUFF_WEAPON) do + n = SMARTBUFF_SetBuff(buff, n); + end + + for _, buff in pairs(SMARTBUFF_RACIAL) do + n = SMARTBUFF_SetBuff(buff, n); + end + + for _, buff in pairs(SMARTBUFF_TRACKING) do + n = SMARTBUFF_SetBuff(buff, n); + end + + for _, buff in pairs(SMARTBUFF_POTION) do + n = SMARTBUFF_SetBuff(buff, n); + end + + for _, buff in pairs(SMARTBUFF_SCROLL) do + n = SMARTBUFF_SetBuff(buff, n); + end + + for _, buff in pairs(SMARTBUFF_FOOD) do + n = SMARTBUFF_SetBuff(buff, n); + end + + wipe(cBuffsCombat); + SMARTBUFF_SetInCombatBuffs(); + + InitBuffOrder(); + + numBuffs = n - 1; + isSetBuffs = false; +end + +function SMARTBUFF_SetBuff(buff, i, ia) + if (buff == nil or buff[1] == nil) then return i; end + + cBuffs[i] = nil; + cBuffs[i] = { }; + cBuffs[i].BuffS = buff[1]; + cBuffs[i].DurationS = ceil(buff[2] * 60); + cBuffs[i].Type = buff[3]; + cBuffs[i].CanCharge = false; + if (SMARTBUFF_IsSpell(cBuffs[i].Type)) then + --print(cBuffs[i].BuffS); + cBuffs[i].IDS, cBuffs[i].BookID = SMARTBUFF_GetSpellID(cBuffs[i].BuffS); + end + if (cBuffs[i].IDS == nil and not(SMARTBUFF_IsItem(cBuffs[i].Type) or cBuffs[i].Type == SMARTBUFF_CONST_TRACK)) then + cBuffs[i] = nil; + return i; + end + + --print(cBuffs[i].IDS); + + if (buff[4] ~= nil) then cBuffs[i].LevelsS = buff[4] else cBuffs[i].LevelsS = nil end + if (buff[5] ~= nil) then cBuffs[i].Params = buff[5] else cBuffs[i].Params = SG.NIL end + cBuffs[i].Links = buff[6]; + cBuffs[i].Chain = buff[7]; + + -- Warlock Nether Ward fix + --if (cBuffs[i].BuffS == SMARTBUFF_SHADOWWARD and IsTalentSkilled(3, 13, SMARTBUFF_NETHERWARD)) then + -- cBuffs[i].BuffS = SMARTBUFF_NETHERWARD; + --end + + if (cBuffs[i].IDS ~= nil) then + cBuffs[i].IconS = GetSpellTexture(cBuffs[i].BuffS); + else + if (cBuffs[i].Type == SMARTBUFF_CONST_TRACK) then + local b = false; + for n = 1, C_Minimap.GetNumTrackingTypes() do + local trackN, trackT, trackA, trackC = C_Minimap.GetTrackingInfo(n); + if (trackN ~= nil) then + --SMARTBUFF_AddMsgD(n..". "..trackN.." ("..trackC..")"); + if (trackN == cBuffs[i].BuffS) then + b = true; + --cBuffs[i].IDS = SMARTBUFF_GetSpellID(cBuffs[i].BuffS); + cBuffs[i].IDS = nil; + cBuffs[i].IconS = trackT; + end + end + end + if (not b) then + cBuffs[i] = nil; + return i; + end + elseif (ia or cBuffs[i].Type == SMARTBUFF_CONST_ITEMGROUP) then + -- itemName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, itemTexture, itemSellPrice + local _, _, _, _, minLevel, _, _, _, _, texture = GetItemInfo(cBuffs[i].BuffS); + if (not IsMinLevel(minLevel)) then + cBuffs[i] = nil; + return i; + end + cBuffs[i].IconS = texture; + else + local _, _, _, _, minLevel = GetItemInfo(cBuffs[i].BuffS); + if (not IsMinLevel(minLevel)) then + cBuffs[i] = nil; + return i; + end + + local _, _, count, texture = SMARTBUFF_FindItem(cBuffs[i].BuffS, cBuffs[i].Chain); + if count then + if (count <= 0) then + cBuffs[i] = nil; + return i; + end + else + cBuffs[i] = nil; + return i; + end + cBuffs[i].IconS = texture; + end + end + + SMARTBUFF_AddMsgD("Add "..buff[1]); + + cBuffs[i].BuffG = nil; --buff[6]; -- Disabled for Cataclysm + cBuffs[i].IDG = nil; --SMARTBUFF_GetSpellID(cBuffs[i].BuffG); + if (cBuffs[i].IDG ~= nil) then + cBuffs[i].IconG = GetSpellTexture(cBuffs[i].BuffG); + else + cBuffs[i].IconG = nil; + end + --if (buff[7] ~= nil) then cBuffs[i].DurationG = ceil(buff[7] * 60); else cBuffs[i].DurationG = nil; end + --if (buff[8] ~= nil) then cBuffs[i].LevelsG = buff[8]; else cBuffs[i].LevelsG = nil; end + --if (buff[9] ~= nil) then cBuffs[i].ReagentG = buff[9]; else cBuffs[i].ReagentG = nil; end + + --[[ + if (O.Debug) then + local s = name; + if (cBuffs[i].IDS) then s = s .. " ID = " .. cBuffs[i].IDS .. ", Icon = " .. cBuffs[i].IconS; else s = s .. " ID = nil"; end + if (cBuffs[i].BuffG ~= nil) then + s = s .. " - " .. cBuffs[i].BuffG; + if (cBuffs[i].IDG) then s = s .. " ID = " .. cBuffs[i].IDG .. ", Icon = " .. cBuffs[i].IconG; else s = s .. " ID = nil"; end + end + SMARTBUFF_AddMsgD(s); + end + ]]-- + + cBuffIndex[cBuffs[i].BuffS] = i; + if (cBuffs[i].IDG ~= nil) then + cBuffIndex[cBuffs[i].BuffG] = i; + end + + InitBuffSettings(cBuffs[i]); + + return i + 1; +end + +function SMARTBUFF_SetInCombatBuffs() + local ct = currentTemplate; + if (ct == nil or B[CS()] == nil or B[CS()][ct] == nil) then + return; + end + for name, data in pairs(B[CS()][ct]) do + --SMARTBUFF_AddMsgD(name .. ", type = " .. type(data)); + if (type(data) == "table" and cBuffIndex[name] and (B[CS()][ct][name].EnableS or B[CS()][ct][name].EnableG) and B[CS()][ct][name].CIn) then + if (cBuffsCombat[name]) then + wipe(cBuffsCombat[name]); + else + cBuffsCombat[name] = { }; + end + cBuffsCombat[name].Unit = "player"; + cBuffsCombat[name].Type = cBuffs[cBuffIndex[name]].Type; + cBuffsCombat[name].ActionType = "spell"; + SMARTBUFF_AddMsgD("Set combat spell: " .. name); + --break; + end + end +end +-- END SMARTBUFF_SetBuffs + + +function SMARTBUFF_IsTalentFrameVisible() + return PlayerTalentFrame and PlayerTalentFrame:IsVisible(); +end + + +-- Main Check functions +function SMARTBUFF_PreCheck(mode, force) + if (not isInit) then return false end + + if (not isInitBtn) then + SMARTBUFF_InitActionButtonPos(); + end + + if (not O.Toggle) then + if (mode == 0) then + SMARTBUFF_AddMsg(SMARTBUFF_MSG_DISABLED); + end + return false; + end + + if (mode == 1 and not force) then + if ((GetTime() - tLastCheck) < O.AutoTimer) then + return false; + end + end + --SMARTBUFF_AddMsgD(string.format("%.2f, %.2f", GetTime(), GetTime() - tLastCheck)); + tLastCheck = GetTime(); + + -- If buffs can't casted, hide UI elements + if (C_PetBattles.IsInBattle() or UnitInVehicle("player") or UnitHasVehicleUI("player")) then + if (not InCombatLockdown() and SmartBuff_KeyButton:IsVisible()) then + SmartBuff_KeyButton:Hide(); + end + return false; + else + SMARTBUFF_ShowSAButton(); + end + + SMARTBUFF_SetButtonTexture(SmartBuff_KeyButton, imgSB); + if (SmartBuffOptionsFrame:IsVisible()) then return false; end + + -- check for mount-spells + if (sPlayerClass == "PALADIN" and (IsMounted() or IsFlying()) and not SMARTBUFF_CheckBuff("player", SMARTBUFF_CRUSADERAURA)) then + return true; + elseif (sPlayerClass == "DEATHKNIGHT" and IsMounted() and not SMARTBUFF_CheckBuff("player", SMARTBUFF_PATHOFFROST)) then + return true; + end + + if ((mode == 1 and not O.ToggleAuto) or IsMounted() or IsFlying() or LootFrame:IsVisible() + or UnitOnTaxi("player") or UnitIsDeadOrGhost("player") or UnitIsCorpse("player") + or (mode ~= 1 and (SMARTBUFF_IsPicnic("player") or SMARTBUFF_IsFishing("player"))) + or (UnitInVehicle("player") or UnitHasVehicleUI("player")) + --or (mode == 1 and (O.ToggleAutoRest and IsResting()) and not UnitIsPVP("player")) + or (not O.BuffInCities and IsResting() and not UnitIsPVP("player"))) then + + if (UnitIsDeadOrGhost("player")) then + SMARTBUFF_CheckBuffTimers(); + end + + return false; + end + --SMARTBUFF_AddMsgD("2: " .. GetTime() - tLastCheck); + + if (UnitAffectingCombat("player")) then + isCombat = true; + --SMARTBUFF_AddMsgD("In combat"); + else + isCombat = false; + --SMARTBUFF_AddMsgD("Out of combat"); + end + + if (not isCombat and isSetBuffs) then + SMARTBUFF_SetBuffs(); + isSyncReq = true; + end + + sMsgWarning = ""; + isFirstError = true; + + return true; +end + + +-- Bufftimer check functions +function SMARTBUFF_CheckBuffTimers() + local n = 0; + local ct = currentTemplate; + + --SMARTBUFF_AddMsgD("SMARTBUFF_CheckBuffTimers"); + + local cGrp = cUnits; + for subgroup in pairs(cGrp) do + n = 0; + if (cGrp[subgroup] ~= nil) then + for _, unit in pairs(cGrp[subgroup]) do + if (unit) then + if (SMARTBUFF_CheckUnitBuffTimers(unit)) then + n = n + 1; + end + end + end + if (cBuffTimer[subgroup]) then + cBuffTimer[subgroup] = nil; + SMARTBUFF_AddMsgD("Group " .. subgroup .. ": group timer reseted"); + end + end + end +end +-- END SMARTBUFF_CheckBuffTimers + +-- if unit is dead, remove all timers +function SMARTBUFF_CheckUnitBuffTimers(unit) + if (UnitExists(unit) and UnitIsConnected(unit) and UnitIsFriend("player", unit) and UnitIsPlayer(unit) and UnitIsDeadOrGhost(unit)) then + local _, uc = UnitClass(unit); + local fd = nil; + if (uc == "HUNTER") then + fd = SMARTBUFF_IsFeignDeath(unit); + end + if (not fd) then + if (cBuffTimer[unit]) then + cBuffTimer[unit] = nil; + SMARTBUFF_AddMsgD(UnitName(unit) .. ": unit timer reseted"); + end + if (cBuffTimer[uc]) then + cBuffTimer[uc] = nil; + SMARTBUFF_AddMsgD(uc .. ": class timer reseted"); + end + return true; + end + end +end +-- END SMARTBUFF_CheckUnitBuffTimers + + +-- Reset the buff timers and set them to running out soon +function SMARTBUFF_ResetBuffTimers() + if (not isInit) then return; end + + local ct = currentTemplate; + local t = GetTime(); + local rbTime = 0; + local i = 0; + local d = 0; + local tl = 0; + local buffS = nil; + local buff = nil; + local unit = nil; + local obj = nil; + local uc = nil; + + local cGrp = cGroups; + for subgroup in pairs(cGrp) do + n = 0; + if (cGrp[subgroup] ~= nil) then + + for _, unit in pairs(cGrp[subgroup]) do + if (unit and UnitExists(unit) and UnitIsConnected(unit) and UnitIsFriend("player", unit) and UnitIsPlayer(unit) and not UnitIsDeadOrGhost(unit)) then + _, uc = UnitClass(unit); + i = 1; + while (cBuffs[i] and cBuffs[i].BuffS) do + d = -1; + buff = nil; + rbTime = 0; + buffS = cBuffs[i].BuffS; + + rbTime = B[CS()][ct][buffS].RBTime; + if (rbTime <= 0) then + rbTime = O.RebuffTimer; + end + + if (cBuffs[i].BuffG and B[CS()][ct][buffS].EnableG and cBuffs[i].IDG ~= nil and cBuffs[i].DurationG > 0) then + d = cBuffs[i].DurationG; + buff = cBuffs[i].BuffG; + obj = subgroup; + end + + if (d > 0 and buff) then + if (not cBuffTimer[obj]) then + cBuffTimer[obj] = { }; + end + cBuffTimer[obj][buff] = t - d + rbTime - 1; + end + + buff = nil; + if (buffS and B[CS()][ct][buffS].EnableS and cBuffs[i].IDS ~= nil and cBuffs[i].DurationS > 0 + and uc and B[CS()][ct][buffS][uc]) then + d = cBuffs[i].DurationS; + buff = buffS; + obj = unit; + end + + if (d > 0 and buff) then + if (not cBuffTimer[obj]) then + cBuffTimer[obj] = { }; + end + cBuffTimer[obj][buff] = t - d + rbTime - 1; + end + + i = i + 1; + end + + end + end + end + end + --isAuraChanged = true; + SMARTBUFF_Check(1, true); +end + +function SMARTBUFF_ShowBuffTimers() + if (not isInit) then return; end + + local ct = currentTemplate; + local t = GetTime(); + local rbTime = 0; + local i = 0; + local d = 0; + local tl = 0; + local buffS = nil; + + for unit in pairs(cBuffTimer) do + for buff in pairs(cBuffTimer[unit]) do + if (unit and buff and cBuffTimer[unit][buff]) then + + d = -1; + buffS = nil; + if (cBuffIndex[buff]) then + i = cBuffIndex[buff]; + if (cBuffs[i].BuffS == buff and cBuffs[i].DurationS > 0) then + d = cBuffs[i].DurationS; + buffS = cBuffs[i].BuffS; + elseif (cBuffs[i].BuffG == buff and cBuffs[i].DurationG > 0) then + d = cBuffs[i].DurationG; + buffS = cBuffs[i].BuffS; + end + i = i + 1; + end + + if (buffS and B[CS()][ct][buffS] ~= nil) then + if (d > 0) then + rbTime = B[CS()][ct][buffS].RBTime; + if (rbTime <= 0) then + rbTime = O.RebuffTimer; + end + tl = cBuffTimer[unit][buff] + d - t; + if (tl >= 0) then + local s = ""; + if (string.find(unit, "^party") or string.find(unit, "^raid") or string.find(unit, "^player") or string.find(unit, "^pet")) then + local un = UnitName(unit); + if (un) then + un = " (" .. un .. ")"; + else + un = ""; + end + s = "Unit " .. unit .. un; + elseif (string.find(unit, "^%d$")) then + s = "Grp " .. unit; + else + s = "Class " .. unit; + end + --SMARTBUFF_AddMsg(s .. ": " .. buff .. ", time left: " .. string.format(": %.0f", tl) .. ", rebuff time: " .. rbTime); + SMARTBUFF_AddMsg(string.format("%s: %s, time left: %.0f, rebuff time: %.0f", s, buff, tl, rbTime)); + else + cBuffTimer[unit][buff] = nil; + end + else + --SMARTBUFF_AddMsgD("Removed: " .. buff); + cBuffTimer[unit][buff] = nil; + end + end + + end + end + end + +end +-- END SMARTBUFF_ResetBuffTimers + + +-- Synchronize the internal buff timers with the UI timers +function SMARTBUFF_SyncBuffTimers() + if (not isInit or isSync or isSetBuffs or SMARTBUFF_IsTalentFrameVisible()) then return; end + isSync = true; + tSync = GetTime(); + + local ct = currentTemplate; + local rbTime = 0; + local i = 0; + local buffS = nil; + local unit = nil; + local uc = nil; + + local cGrp = cGroups; + for subgroup in pairs(cGrp) do + n = 0; + if (cGrp[subgroup] ~= nil) then + for _, unit in pairs(cGrp[subgroup]) do + if (unit and UnitExists(unit) and UnitIsConnected(unit) and UnitIsFriend("player", unit) and UnitIsPlayer(unit) and not UnitIsDeadOrGhost(unit)) then + _, uc = UnitClass(unit); + i = 1; + while (cBuffs[i] and cBuffs[i].BuffS) do + rbTime = 0; + buffS = cBuffs[i].BuffS; + + -- TOCHECK + rbTime = B[CS()][ct][buffS].RBTime; + if (rbTime <= 0) then + rbTime = O.RebuffTimer; + end + + if (buffS and B[CS()][ct][buffS].EnableS and cBuffs[i].IDS ~= nil and cBuffs[i].DurationS > 0) then + if (cBuffs[i].Type ~= SMARTBUFF_CONST_SELF or (cBuffs[i].Type == SMARTBUFF_CONST_SELF and SMARTBUFF_IsPlayer(unit))) then + SMARTBUFF_SyncBuffTimer(unit, unit, cBuffs[i]); + end + end + + i = i + 1; + end -- END while + end + end -- END for + end + end -- END for + + isSync = false; + isSyncReq = false; +end + + +function SMARTBUFF_SyncBuffTimer(unit, grp, cBuff) + if (not unit or not grp or not cBuff) then return end + local d = cBuff.DurationS; + local buff = cBuff.BuffS; + if (d and d > 0 and buff) then + local t = GetTime(); + local ret, _, _, timeleft = SMARTBUFF_CheckUnitBuffs(unit, buff, cBuff.Type, cBuff.Links, cBuff.Chain); + if (ret == nil and timeleft ~= nil) then + if (not cBuffTimer[grp]) then cBuffTimer[grp] = { } end + st = Round(t - d + timeleft, 2); + if (not cBuffTimer[grp][buff] or (cBuffTimer[grp][buff] and cBuffTimer[grp][buff] ~= st)) then + cBuffTimer[grp][buff] = st; + if (timeleft > 60) then + SMARTBUFF_AddMsgD("Buff timer sync: " .. grp .. ", " .. buff .. ", " .. string.format("%.1f", timeleft/60) .. "min"); + else + SMARTBUFF_AddMsgD("Buff timer sync: " .. grp .. ", " .. buff .. ", " .. string.format("%.1f", timeleft) .. "sec"); + end + end + end + end +end + + +-- check if the player is shapeshifted +function SMARTBUFF_IsShapeshifted() + if (sPlayerClass == "SHAMAN") then + if (GetShapeshiftForm(true) > 0) then + return true, "Ghost Wolf"; + end + elseif (sPlayerClass == "DRUID") then + local i; + for i = 1, GetNumShapeshiftForms(), 1 do + local icon, active, castable, spellId = GetShapeshiftFormInfo(i); + local name = GetSpellInfo(spellId); + if (active and castable and name ~= SMARTBUFF_DRUID_TREANT) then + return true, name; + end + end + end + return false, nil; +end +-- END SMARTBUFF_IsShapeshifted + + +local IsChecking = false; +function SMARTBUFF_Check(mode, force) + if (IsChecking or not SMARTBUFF_PreCheck(mode, force)) then return; end + IsChecking = true; + + local ct = currentTemplate; + local unit = nil; + local units = nil; + local unitsGrp = nil; + local unitB = nil; + local unitL = nil; + local unitU = nil; + local uLevel = nil; + local uLevelL = nil; + local uLevelU = nil; + local idL = nil; + local idU = nil; + local subgroup = 0; + local i; + local j; + local n; + local m; + local rc; + local rank; + local reagent; + local nGlobal = 0; + + SMARTBUFF_checkBlacklist(); + + -- 1. check in combat buffs + if (InCombatLockdown()) then -- and O.InCombat + for spell in pairs(cBuffsCombat) do + if (spell) then + local ret, actionType, spellName, slot, unit, buffType = SMARTBUFF_BuffUnit("player", 0, mode, spell) + --SMARTBUFF_AddMsgD("Check combat spell: " .. spell .. ", ret = " .. ret); + if (ret and ret == 0) then + IsChecking = false; + return; + end + end + end + end + + -- 2. buff target, if enabled + if ((mode == 0 or mode == 5) and O.BuffTarget) then + local actionType, spellName, slot, buffType; + i, actionType, spellName, slot, _, buffType = SMARTBUFF_BuffUnit("target", 0, mode); + if (i <= 1) then + if (i == 0) then + --tLastCheck = GetTime() - O.AutoTimer + GlobalCd; + end + IsChecking = false; + return i, actionType, spellName, slot, "target", buffType; + end + end + + -- 3. check groups + local cGrp = cGroups; + local cOrd = cOrderGrp; + isMounted = IsMounted() or IsFlying(); + for _, subgroup in pairs(cOrd) do + --SMARTBUFF_AddMsgD("Checking subgroup " .. subgroup .. ", " .. GetTime()); + if (cGrp[subgroup] ~= nil or (type(subgroup) == "number" and subgroup == 1)) then + + if (cGrp[subgroup] ~= nil) then + units = cGrp[subgroup]; + else + units = nil; + end + + if (cUnits and type(subgroup) == "number" and subgroup == 1) then + unitsGrp = cUnits[1]; + else + unitsGrp = units; + end + + -- check buffs + if (units) then + for _, unit in pairs(units) do + if (isSetBuffs) then break; end + SMARTBUFF_AddMsgD("Checking single unit = "..unit); + local spellName, actionType, slot, buffType; + i, actionType, spellName, slot, _, buffType = SMARTBUFF_BuffUnit(unit, subgroup, mode); + + if (i <= 1) then + if (i == 0 and mode ~= 1) then + --tLastCheck = GetTime() - O.AutoTimer + GlobalCd; + if (actionType == SMARTBUFF_ACTION_ITEM) then + --tLastCheck = tLastCheck + 2; + end + end + IsChecking = false; + return i, actionType, spellName, slot, unit, buffType; + end + end + end + + end + end -- for groups + + if (mode == 0) then + if (sMsgWarning == "" or sMsgWarning == " ") then + SMARTBUFF_AddMsg(SMARTBUFF_MSG_NOTHINGTODO); + else + SMARTBUFF_AddMsgWarn(sMsgWarning); + sMsgWarning = ""; + end + end + --tLastCheck = GetTime(); + IsChecking = false; +end +-- END SMARTBUFF_Check + + +-- Buffs a unit +function SMARTBUFF_BuffUnit(unit, subgroup, mode, spell) + local bs = nil; + local buff = nil; + local buffname = nil; + local buffnS = nil; + local uc = nil; + local ur = "NONE"; + local un = nil; + local uct = nil; + local ucf = nil; + local r; + local i; + local bt = 0; + local cd = 0; + local cds = 0; + local charges = 0; + local handtype = ""; + local bExpire = false; + local isPvP = false; + local bufftarget = nil; + local rbTime = 0; + local bUsable = false; + local time = GetTime(); + local cBuff = nil; + local iId = nil; + local iSlot = -1; + + if (UnitIsPVP("player")) then isPvP = true end + + SMARTBUFF_CheckUnitBuffTimers(unit); + + --SMARTBUFF_AddMsgD("Checking " .. unit); + + if (UnitExists(unit) and UnitIsFriend("player", unit) and not UnitIsDeadOrGhost(unit) and not UnitIsCorpse(unit) + and UnitIsConnected(unit) and UnitIsVisible(unit) and not UnitOnTaxi(unit) and not cBlacklist[unit] + and ((not UnitIsPVP(unit) and (not isPvP or O.BuffPvP)) or (UnitIsPVP(unit) and (isPvP or O.BuffPvP)))) then + --and not SmartBuff_UnitIsIgnored(unit) + + --print("Prep Check"); + + _, uc = UnitClass(unit); + un = UnitName(unit); + ur = UnitGroupRolesAssigned(unit); + uct = UnitCreatureType(unit); + ucf = UnitCreatureFamily(unit); + if (uct == nil) then uct = ""; end + if (ucf == nil) then ucf = ""; end + +-- if (un) then print("Grp "..subgroup.." checking "..un.." ("..unit.."/"..uc.."/"..ur.."/"..uct.."/"..ucf..")", 0, 1, 0.5); end + + isShapeshifted, sShapename = SMARTBUFF_IsShapeshifted(); + --while (cBuffs[i] and cBuffs[i].BuffS) do + for i, buffnS in pairs(B[CS()].Order) do + if (isSetBuffs or SmartBuffOptionsFrame:IsVisible()) then break; end + cBuff = cBuffs[cBuffIndex[buffnS]]; + --buffnS = cBuff.BuffS; + bs = GetBuffSettings(buffnS); + bExpire = false; + handtype = ""; + charges = -1; + bufftarget = nil; + bUsable = false; + iId = nil; + iSlot = -1; + + if (cBuff and bs) then bUsable = bs.EnableS end + + if (bUsable and spell and spell ~= buffnS) then + bUsable = false; + --SMARTBUFF_AddMsgD("Exclusive check on " .. spell .. ", current spell = " .. buffnS); + end + + if (bUsable and cBuff.Type == SMARTBUFF_CONST_SELF and not SMARTBUFF_IsPlayer(unit)) then bUsable = false end + if (bUsable and not cBuff.Type == SMARTBUFF_CONST_TRACK and not SMARTBUFF_IsItem(cBuff.Type) and not IsUsableSpell(buffnS)) then bUsable = false end + if (bUsable and bs.SelfNot and SMARTBUFF_IsPlayer(unit)) then bUsable = false end + if (bUsable and cBuff.Params == SG.CheckFishingPole and SMARTBUFF_IsFishingPoleEquiped()) then bUsable = false end + + -- Check for buffs which depends on a pet + if (bUsable and cBuff.Params == SG.CheckPet and UnitExists("pet")) then bUsable = false end + if (bUsable and cBuff.Params == SG.CheckPetNeeded and not UnitExists("pet")) then bUsable = false end + + -- Check for mount auras + if (bUsable and (sPlayerClass == "PALADIN" or sPlayerClass == "DEATHKNIGHT")) then + isMounted = false; + if (sPlayerClass == "PALADIN") then + isMounted = IsMounted() or IsFlying(); + if ((buffnS ~= SMARTBUFF_CRUSADERAURA and isMounted) or (buffnS == SMARTBUFF_CRUSADERAURA and not isMounted)) then + bUsable = false; + end + elseif (sPlayerClass == "DEATHKNIGHT") then + isMounted = IsMounted(); + if (buffnS ~= SMARTBUFF_PATHOFFROST and isMounted) then + bUsable = false; + end + end + end + + if (bUsable and not (cBuff.Type == SMARTBUFF_CONST_TRACK or SMARTBUFF_IsItem(cBuff.Type))) then + -- check if you have enough mana/rage/energy to cast + local isUsable, notEnoughMana = IsUsableSpell(buffnS); + if (notEnoughMana) then + bUsable = false; + --SMARTBUFF_AddMsgD("Buff " .. cBuff.BuffS .. ", not enough mana!"); + elseif (mode ~= 1 and isUsable == nil and buffnS ~= SMARTBUFF_PWS) then + bUsable = false; + --SMARTBUFF_AddMsgD("Buff " .. cBuff.BuffS .. " is not usable!"); + end + end + + if (bUsable and bs.EnableS and (cBuff.IDS ~= nil or SMARTBUFF_IsItem(cBuff.Type) or cBuff.Type == SMARTBUFF_CONST_TRACK) + and ((mode ~= 1 and ((isCombat and bs.CIn) or (not isCombat and bs.COut))) + or (mode == 1 and bs.Reminder and ((not isCombat and bs.COut) + or (isCombat and (bs.CIn or O.ToggleAutoCombat)))))) then + + --print("Check: "..buffnS) + + if (not bs.SelfOnly or (bs.SelfOnly and SMARTBUFF_IsPlayer(unit))) then + -- get current spell cooldown + cd = 0; + cds = 0; + if (cBuff.IDS) then + cds, cd = GetSpellCooldown(buffnS); + cd = (cds + cd) - GetTime(); + if (cd < 0) then + cd = 0; + end + --SMARTBUFF_AddMsgD(buffnS.." cd = "..cd); + end + + -- check if spell has cooldown + if (cd <= 0 or (mode == 1 and cd <= 1.5)) then + if (cBuff.IDS and sMsgWarning == SMARTBUFF_MSG_CD) then + sMsgWarning = " "; + end + + rbTime = bs.RBTime; + if (rbTime <= 0) then + rbTime = O.RebuffTimer; + end + + --SMARTBUFF_AddMsgD(uc.." "..CT()); + if (not SMARTBUFF_IsInList(unit, un, bs.IgnoreList) and (((cBuff.Type == SMARTBUFF_CONST_GROUP or cBuff.Type == SMARTBUFF_CONST_ITEMGROUP) + and (bs[ur] + or (bs.SelfOnly and SMARTBUFF_IsPlayer(unit)) + or (bs[uc] and (UnitIsPlayer(unit) or uct == SMARTBUFF_HUMANOID or (uc == "DRUID" and (uct == SMARTBUFF_BEAST or uct == SMARTBUFF_ELEMENTAL)))) + or (bs["HPET"] and uct == SMARTBUFF_BEAST and uc ~= "DRUID") + or (bs["DKPET"] and utc == SMARTBUFF_UNDEAD) + or (bs["WPET"] and (uct == SMARTBUFF_DEMON or (uc ~= "DRUID" and uct == SMARTBUFF_ELEMENTAL)) and ucf ~= SMARTBUFF_DEMONTYPE))) + or (cBuff.Type ~= SMARTBUFF_CONST_GROUP and SMARTBUFF_IsPlayer(unit)) + or SMARTBUFF_IsInList(unit, un, bs.AddList))) then + buff = nil; + + + -- Tracking ability ------------------------------------------------------------------------ + if (cBuff.Type == SMARTBUFF_CONST_TRACK) then + + --print("Check tracking: "..buffnS) + local count = C_Minimap.GetNumTrackingTypes(); + for n = 1, C_Minimap.GetNumTrackingTypes() do + local trackN, trackT, trackA, trackC = C_Minimap.GetTrackingInfo(n); + if (trackN ~= nil and not trackA) then + --SMARTBUFF_AddMsgD(n..". "..trackN.." ("..trackC..")"); + if (trackN == buffnS) then + if (sPlayerClass == "DRUID" and buffnS == SMARTBUFF_DRUID_TRACK) then + if (isShapeshifted and sShapename == SMARTBUFF_DRUID_CAT) then + buff = buffnS; + SetTracking(n, 1); + end + else + buff = buffnS; + C_Minimap.SetTracking(n, 1); + --print("SetTracking: "..n) + end + if (buff ~= nil) then + SMARTBUFF_AddMsgD("Tracking enabled: "..buff); + buff = nil; + end + end + end + end + + -- Food, Scroll, Potion or conjured items ------------------------------------------------------------------------ + elseif (cBuff.Type == SMARTBUFF_CONST_FOOD or cBuff.Type == SMARTBUFF_CONST_SCROLL or cBuff.Type == SMARTBUFF_CONST_POTION or + cBuff.Type == SMARTBUFF_CONST_ITEM or cBuff.Type == SMARTBUFF_CONST_ITEMGROUP) then + + if (cBuff.Type == SMARTBUFF_CONST_ITEM) then + bt = nil; + buff = nil; + if (cBuff.Params ~= SG.NIL) then + local cr = SMARTBUFF_CountReagent(cBuff.Params, cBuff.Chain); + --SMARTBUFF_AddMsgD(cr.." "..cBuff.Params.." found"); + if (cr == 0) then + buff = cBuff.Params; + end + end + + -- dont attempt to use food while moving or we will waste them. + elseif (cBuff.Type == SMARTBUFF_CONST_FOOD and isPlayerMoving == false) then + if (not SMARTBUFF_IsPicnic(unit)) then + buff, index, buffname, bt, charges = SMARTBUFF_CheckUnitBuffs(unit, SMARTBUFF_FOOD_AURA, cBuff.Type, cBuff.Links, cBuff.Chain); + end + else + if (cBuff.Params ~= SG.NIL) then + if (cBuff.Links and cBuff.Links == SG.CheckFishingPole) then + if (SMARTBUFF_IsFishingPoleEquiped()) then + buff, index, buffname, bt, charges = SMARTBUFF_CheckUnitBuffs(unit, cBuff.Params, cBuff.Type); + else + buff = nil; + end + else + buff, index, buffname, bt, charges = SMARTBUFF_CheckUnitBuffs(unit, cBuff.Params, cBuff.Type, cBuff.Links, cBuff.Chain); + end + --SMARTBUFF_AddMsgD("Buff time ("..cBuff.Params..") = "..tostring(bt)); + else + buff = nil; + end + end + + if (buff == nil and cBuff.DurationS >= 1 and rbTime > 0) then + if (charges == nil) then charges = -1; end + if (charges > 1) then cBuff.CanCharge = true; end + bufftarget = nil; + end + + if (bt and bt <= rbTime) then + buff = buffnS; + bExpire = true; + end + + if (buff) then + if (cBuff.Type ~= SMARTBUFF_CONST_ITEM) then + local cr, iid = SMARTBUFF_CountReagent(buffnS, cBuff.Chain); + if (cr > 0) then + buff = buffnS; + if (cBuff.Type == SMARTBUFF_CONST_ITEMGROUP or cBuff.Type == SMARTBUFF_CONST_SCROLL) then + cds, cd = GetItemCooldown(iid); + cd = (cds + cd) - GetTime(); + --SMARTBUFF_AddMsgD(cr.." "..buffnS.." found, cd = "..cd); + if (cd > 0) then + buff = nil; + end + end + --SMARTBUFF_AddMsgD(cr .. " " .. buffnS .. " found"); + else + --SMARTBUFF_AddMsgD("No " .. buffnS .. " found"); + buff = nil; + bExpire = false; + end + end + end + + -- Weapon buff ------------------------------------------------------------------------ + elseif (cBuff.Type == SMARTBUFF_CONST_WEAPON or cBuff.Type == SMARTBUFF_CONST_INV) then + --SMARTBUFF_AddMsgD("Check weapon Buff"); + local bMh, tMh, cMh, _, bOh, tOh, cOh = GetWeaponEnchantInfo(); + + if (bs.MH) then + iSlot = 16; + iId = GetInventoryItemID("player", iSlot); + if (iId and SMARTBUFF_CanApplyWeaponBuff(buffnS, iSlot)) then + if (bMh) then + if (rbTime > 0 and cBuff.DurationS >= 1) then + --if (tMh == nil) then tMh = 0; end + tMh = floor(tMh/1000); + charges = cMh; + if (charges == nil) then charges = -1; end + if (charges > 1) then cBuff.CanCharge = true; end + --SMARTBUFF_AddMsgD(un .. " (WMH): " .. buffnS .. string.format(" %.0f sec left", tMh) .. ", " .. charges .. " charges left"); + if (tMh <= rbTime or (O.CheckCharges and cBuff.CanCharge and charges > 0 and charges <= O.MinCharges)) then + buff = buffnS; + bt = tMh; + bExpire = true; + end + end + else + handtype = "main"; + buff = buffnS; + end + else + --SMARTBUFF_AddMsgD("Weapon Buff cannot be cast, no mainhand weapon equipped or wrong weapon/stone type"); + end + end + + if (bs.OH and not bExpire and handtype == "") then + iSlot = 17; + iId = GetInventoryItemID("player", iSlot); + if (iId and SMARTBUFF_CanApplyWeaponBuff(buffnS, iSlot)) then + if (bOh) then + if (rbTime > 0 and cBuff.DurationS >= 1) then + --if (tOh == nil) then tOh = 0; end + tOh = floor(tOh/1000); + charges = cOh; + if (charges == nil) then charges = -1; end + if (charges > 1) then cBuff.CanCharge = true; end + --SMARTBUFF_AddMsgD(un .. " (WOH): " .. buffnS .. string.format(" %.0f sec left", tOh) .. ", " .. charges .. " charges left"); + if (tOh <= rbTime or (O.CheckCharges and cBuff.CanCharge and charges > 0 and charges <= O.MinCharges)) then + buff = buffnS; + bt = tOh; + bExpire = true; + end + end + else + handtype = "off"; + buff = buffnS; + end + else + --SMARTBUFF_AddMsgD("Weapon Buff cannot be cast, no offhand weapon equipped or wrong weapon/stone type"); + end + end + + if (buff and cBuff.Type == SMARTBUFF_CONST_INV) then + local cr = SMARTBUFF_CountReagent(buffnS, cBuff.Chain); + if (cr > 0) then + --SMARTBUFF_AddMsgD(cr .. " " .. buffnS .. " found"); + else + --SMARTBUFF_AddMsgD("No " .. buffnS .. " found"); + buff = nil; + end + end + + -- Normal buff ------------------------------------------------------------------------ + else + local index = nil; + + -- check timer object + buff, index, buffname, bt, charges = SMARTBUFF_CheckUnitBuffs(unit, buffnS, cBuff.Type, cBuff.Links, cBuff.Chain); + if (charges == nil) then charges = -1; end + if (charges > 1) then cBuff.CanCharge = true; end + + if (unit ~= "target" and buff == nil and cBuff.DurationS >= 1 and rbTime > 0) then + if (SMARTBUFF_IsPlayer(unit)) then + if (cBuffTimer[unit] ~= nil and cBuffTimer[unit][buffnS] ~= nil) then + local tbt = cBuff.DurationS - (time - cBuffTimer[unit][buffnS]); + if (not bt or bt - tbt > rbTime) then + bt = tbt; + end + end + --if (charges == nil) then charges = -1; end + --if (charges > 1) then cBuff.CanCharge = true; end + bufftarget = nil; + --SMARTBUFF_AddMsgD(un .. " (P): " .. index .. ". " .. GetPlayerBuffTexture(index) .. "(" .. charges .. ") - " .. buffnS .. string.format(" %.0f sec left", bt)); + elseif (cBuffTimer[unit] ~= nil and cBuffTimer[unit][buffnS] ~= nil) then + bt = cBuff.DurationS - (time - cBuffTimer[unit][buffnS]); + bufftarget = nil; + --SMARTBUFF_AddMsgD(un .. " (S): " .. buffnS .. string.format(" %.0f sec left", bt)); + elseif (cBuff.BuffG ~= nil and cBuffTimer[subgroup] ~= nil and cBuffTimer[subgroup][cBuff.BuffG] ~= nil) then + bt = cBuff.DurationG - (time - cBuffTimer[subgroup][cBuff.BuffG]); + if (type(subgroup) == "number") then + bufftarget = SMARTBUFF_MSG_GROUP .. " " .. subgroup; + else + bufftarget = SMARTBUFF_MSG_CLASS .. " " .. UnitClass(unit); + end + --SMARTBUFF_AddMsgD(bufftarget .. ": " .. cBuff.BuffG .. string.format(" %.0f sec left", bt)); + elseif (cBuff.BuffG ~= nil and cBuffTimer[uc] ~= nil and cBuffTimer[uc][cBuff.BuffG] ~= nil) then + bt = cBuff.DurationG - (time - cBuffTimer[uc][cBuff.BuffG]); + bufftarget = SMARTBUFF_MSG_CLASS .. " " .. UnitClass(unit); + --SMARTBUFF_AddMsgD(bufftarget .. ": " .. cBuff.BuffG .. string.format(" %.0f sec left", bt)); + else + bt = nil; + end + + if ((bt and bt <= rbTime) or (O.CheckCharges and cBuff.CanCharge and charges > 0 and charges <= O.MinCharges)) then + if (buffname) then + buff = buffname; + else + buff = buffnS; + end + bExpire = true; + end + end + + -- check if the group buff is active, in this case it is not possible to cast the single buff + if (buffname and mode ~= 1 and buffname ~= buffnS) then + buff = nil; + --SMARTBUFF_AddMsgD("Group buff is active, single buff canceled!"); + end + + end -- END normal buff + + -- check if shapeshifted and cancel buff if it is not possible to cast it + if (buff and cBuff.Type ~= SMARTBUFF_CONST_TRACK and cBuff.Type ~= SMARTBUFF_CONST_FORCESELF) then + --isShapeshifted = true; + --sShapename = "Moonkingestalt"; + if (isShapeshifted) then + if (string.find(cBuff.Params, sShapename)) then + --SMARTBUFF_AddMsgD("Cast " .. buff .. " while shapeshifted"); + else + if(cBuff.Params == SMARTBUFF_DRUID_CAT) then + buff = nil; + end + if (buff and mode ~= 1 and not O.InShapeshift and (sShapename ~= SMARTBUFF_DRUID_MOONKIN and sShapename ~= SMARTBUFF_DRUID_TREANT)) then + --sMsgWarning = SMARTBUFF_MSG_SHAPESHIFT .. ": " .. sShapename; + buff = nil; + end + end + else + if(cBuff.Params == SMARTBUFF_DRUID_CAT) then + buff = nil; + end + end + end + + if (buff) then + + -- we have a buff, set the cvar - this will be reverted back + -- once smartbuff has finished its work. If we are in combat + -- lockdown then keep it at 0 + + if not InCombatLockdown() and O.SBButtonFix then + SetCVar("ActionButtonUseKeyDown",1 ); + elseif O.SBButtonFix then + SetCVar("ActionButtonUseKeyDown", O.SBButtonDownVal ); + end + + --if (cBuff.IDS) then + --SMARTBUFF_AddMsgD("Checking " ..i .. " - " .. cBuff.IDS .. " " .. buffnS); + --end + + -- Cast mode --------------------------------------------------------------------------------------- + if (mode == 0 or mode == 5) then + currentUnit = nil; + currentSpell = nil; + + --try to apply weapon buffs on main/off hand + if (cBuff.Type == SMARTBUFF_CONST_INV) then + if (iSlot and (handtype ~= "" or bExpire)) then + local bag, slot, count = SMARTBUFF_FindItem(buffnS, cBuff.Chain); + if (count > 0) then + sMsgWarning = ""; + return 0, SMARTBUFF_ACTION_ITEM, buffnS, iSlot, "player", cBuff.Type; + end + end + r = 50; + elseif (cBuff.Type == SMARTBUFF_CONST_WEAPON) then + if (iId and (handtype ~= "" or bExpire)) then + sMsgWarning = ""; + return 0, SMARTBUFF_ACTION_SPELL, buffnS, iSlot, "player", cBuff.Type; + --return 0, SMARTBUFF_ACTION_SPELL, buffnS, iId, "player", cBuff.Type; + end + r = 50; + + -- eat food or use scroll or potion + elseif (cBuff.Type == SMARTBUFF_CONST_FOOD or cBuff.Type == SMARTBUFF_CONST_SCROLL or cBuff.Type == SMARTBUFF_CONST_POTION) then + local bag, slot, count = SMARTBUFF_FindItem(buffnS, cBuff.Chain); + if (count > 0 or bExpire) then + sMsgWarning = ""; + return 0, SMARTBUFF_ACTION_ITEM, buffnS, 0, "player", cBuff.Type; + end + r = 20; + + -- use item on a unit + elseif (cBuff.Type == SMARTBUFF_CONST_ITEMGROUP) then + local bag, slot, count = SMARTBUFF_FindItem(buffnS, cBuff.Chain); + if (count > 0) then + sMsgWarning = ""; + return 0, SMARTBUFF_ACTION_ITEM, buffnS, 0, unit, cBuff.Type; + end + r = 20; + + -- create item + elseif (cBuff.Type == SMARTBUFF_CONST_ITEM) then + r = 20; + local bag, slot, count = SMARTBUFF_FindItem(buff, cBuff.Chain); + if (count == 0) then + r = SMARTBUFF_doCast(unit, cBuff.IDS, buffnS, cBuff.LevelsS, cBuff.Type); + if (r == 0) then + currentUnit = unit; + currentSpell = buffnS; + end + end + + -- cast spell + else + r = SMARTBUFF_doCast(unit, cBuff.IDS, buffnS, cBuff.LevelsS, cBuff.Type); + if (r == 0) then + currentUnit = unit; + currentSpell = buffnS; + end + end + + -- Check mode --------------------------------------------------------------------------------------- + elseif (mode == 1) then + currentUnit = nil; + currentSpell = nil; + if (bufftarget == nil) then bufftarget = un; end + + if (cBuff.IDS ~= nil or SMARTBUFF_IsItem(cBuff.Type) or cBuff.Type == SMARTBUFF_CONST_TRACK) then + -- clean up buff timer, if expired + if (bt and bt < 0 and bExpire) then + bt = 0; + if (cBuffTimer[unit] ~= nil and cBuffTimer[unit][buffnS] ~= nil) then + cBuffTimer[unit][buffnS] = nil; + --SMARTBUFF_AddMsgD(un .. " (S): " .. buffnS .. " timer reset"); + end + if (cBuff.IDG ~= nil) then + if (cBuffTimer[subgroup] ~= nil and cBuffTimer[subgroup][cBuff.BuffG] ~= nil) then + cBuffTimer[subgroup][cBuff.BuffG] = nil; + --SMARTBUFF_AddMsgD("Group " .. subgroup .. ": " .. buffnS .. " timer reset"); + end + if (cBuffTimer[uc] ~= nil and cBuffTimer[uc][cBuff.BuffG] ~= nil) then + cBuffTimer[uc][cBuff.BuffG] = nil; + --SMARTBUFF_AddMsgD("Class " .. uc .. ": " .. cBuff.BuffG .. " timer reset"); + end + end + tLastCheck = time - O.AutoTimer + 0.5; + return 0; + end + + SMARTBUFF_SetMissingBuffMessage(bufftarget, buff, cBuff.IconS, cBuff.CanCharge, charges, bt, bExpire); + SMARTBUFF_SetButtonTexture(SmartBuff_KeyButton, cBuff.IconS); + return 0; + end + end + + if (r == 0) then + -- target buffed + -- Message will printed in the "SPELLCAST_STOP" event + sMsgWarning = ""; + return 0, SMARTBUFF_ACTION_SPELL, buffnS, -1, unit, cBuff.Type; + elseif (r == 1) then + -- spell cooldown + if (mode == 0) then SMARTBUFF_AddMsgWarn(buffnS .. " " .. SMARTBUFF_MSG_CD); end + return 1; + elseif (r == 2) then + -- can not target + if (mode == 0 and ucf ~= SMARTBUFF_DEMONTYPE) then SMARTBUFF_AddMsgD("Can not target " .. un); end + elseif (r == 3) then + -- target oor + if (mode == 0) then SMARTBUFF_AddMsgWarn(un .. " " .. SMARTBUFF_MSG_OOR); end + break; + elseif (r == 4) then + -- spell cooldown > maxSkipCoolDown + if (mode == 0) then SMARTBUFF_AddMsgD(buffnS .. " " .. SMARTBUFF_MSG_CD .. " > " .. maxSkipCoolDown); end + elseif (r == 5) then + -- target to low + if (mode == 0) then SMARTBUFF_AddMsgD(un .. " is to low to get buffed with " .. buffnS); end + elseif (r == 6) then + -- not enough mana/rage/energy + sMsgWarning = SMARTBUFF_MSG_OOM; + elseif (r == 7) then + -- tracking ability is already active + if (mode == 0) then SMARTBUFF_AddMsgD(buffnS .. " not used, other ability already active"); end + elseif (r == 8) then + -- actionslot is not defined + if (mode == 0) then SMARTBUFF_AddMsgD(buffnS .. " has no actionslot"); end + elseif (r == 9) then + -- spell ID not found + if (mode == 0) then SMARTBUFF_AddMsgD(buffnS .. " spellID not found"); end + elseif (r == 10) then + -- target could not buffed + if (mode == 0) then SMARTBUFF_AddMsgD(buffnS .. " could not buffed on " .. un); end + elseif (r == 20) then + -- item not found + if (mode == 0) then SMARTBUFF_AddMsgD(buffnS .. " could not used"); end + elseif (r == 50) then + -- weapon buff could not applied + if (mode == 0) then SMARTBUFF_AddMsgD(buffnS .. " could not applied"); end + else + -- no spell selected + if (mode == 0) then SMARTBUFF_AddMsgD(SMARTBUFF_MSG_CHAT); end + end + else + -- finished + if O.SBButtonFix then SetCVar("ActionButtonUseKeyDown", O.SBButtonDownVal ); end + end + else + -- target does not need this buff + if O.SBButtonFix then SetCVar("ActionButtonUseKeyDown", O.SBButtonDownVal ); end + end + else + -- cooldown + if (sMsgWarning == "") then + sMsgWarning = SMARTBUFF_MSG_CD; + end + --SMARTBUFF_AddMsgD("Spell on cd: "..buffnS); + end + end -- group or self + end + --i = i + 1; + end -- for buff + + end + return 3; +end +-- END SMARTBUFF_BuffUnit + + +function SMARTBUFF_IsInList(unit, unitname, list) + if (list ~= nil) then + for un in pairs(list) do + if (un ~= nil and UnitIsPlayer(unit) and un == unitname) then + return true; + end + end + end + return false; +end + + +function SMARTBUFF_SetMissingBuffMessage(target, buff, icon, bCanCharge, nCharges, tBuffTimeLeft, bExpire) + local f = SmartBuffSplashFrame; + -- show splash buff message + if (f and O.ToggleAutoSplash and not SmartBuffOptionsFrame:IsVisible()) then + local s; + local sd = O.SplashDuration; + local si = ""; + + if (OG.SplashIcon and icon) then + local n = O.SplashIconSize; + if (n == nil or n <= 0) then + n = O.CurrentFontSize; + end + si = string.format("\124T%s:%d:%d:1:0\124t ", icon, n, n) or ""; + end + if (OG.SplashMsgShort and si == "") then si = buff end + if (O.AutoTimer < 4) then + sd = 1; + f:Clear(); + end + + f:SetTimeVisible(sd); + if (not nCharges) then nCharges = 0; end + if (O.CheckCharges and bCanCharge and nCharges > 0 and nCharges <= O.MinCharges and bExpire) then + if (OG.SplashMsgShort) then + s = target.." > "..si.." < "..format(SMARTBUFF_ABBR_CHARGES_OL, nCharges); + else + s = target.."\n"..SMARTBUFF_MSG_REBUFF.." "..si..buff..": "..format(ITEM_SPELL_CHARGES, nCharges).." "..SMARTBUFF_MSG_LEFT; + end + elseif (bExpire) then + if (OG.SplashMsgShort) then + s = target.." > "..si.." < "..format(SECOND_ONELETTER_ABBR, tBuffTimeLeft); + else + s = target.."\n"..SMARTBUFF_MSG_REBUFF.." "..si..buff..": "..format(SECONDS_ABBR, tBuffTimeLeft).." "..SMARTBUFF_MSG_LEFT; + end + else + if (OG.SplashMsgShort) then + s = target.." > "..si; + else + s = target.." "..SMARTBUFF_MSG_NEEDS.." "..si..buff; + end + end + f:AddMessage(s, O.ColSplashFont.r, O.ColSplashFont.g, O.ColSplashFont.b, 1.0); + end + + -- show chat buff message + if (O.ToggleAutoChat) then + if (O.CheckCharges and bCanCharge and nCharges > 0 and nCharges <= O.MinCharges and bExpire) then + SMARTBUFF_AddMsgWarn(target..": "..SMARTBUFF_MSG_REBUFF.." "..buff..", "..format(ITEM_SPELL_CHARGES, nCharges).." ".. SMARTBUFF_MSG_LEFT, true); + elseif (bExpire) then + SMARTBUFF_AddMsgWarn(target..": "..SMARTBUFF_MSG_REBUFF.." "..buff..format(SECONDS_ABBR, tBuffTimeLeft).." "..SMARTBUFF_MSG_LEFT, true); + else + SMARTBUFF_AddMsgWarn(target.." "..SMARTBUFF_MSG_NEEDS.." "..buff, true); + end + end + + -- play sound + if (O.ToggleAutoSound) then + PlaySound(Sounds[O.AutoSoundSelection]); + end +end + + +-- check if a spell/reagent could applied on a weapon +function SMARTBUFF_CanApplyWeaponBuff(buff, slot) + local cWeaponTypes = nil; + if (string.find(buff, SMARTBUFF_WEAPON_SHARP_PATTERN)) then + cWeaponTypes = SMARTBUFF_WEAPON_SHARP; + elseif (string.find(buff, SMARTBUFF_WEAPON_BLUNT_PATTERN)) then + cWeaponTypes = SMARTBUFF_WEAPON_BLUNT; + else + cWeaponTypes = SMARTBUFF_WEAPON_STANDARD; + end + + local itemLink = GetInventoryItemLink("player", slot); + local _, _, itemCode = string.find(itemLink, "(%d+):"); + local _, _, _, _, _, itemType, itemSubType = GetItemInfo(itemCode); + + --if (itemType and itemSubType) then + -- SMARTBUFF_AddMsgD("Type: " .. itemType .. ", Subtype: " .. itemSubType); + --end + + if (cWeaponTypes and itemSubType) then + for _, weapon in pairs(cWeaponTypes) do + --SMARTBUFF_AddMsgD(weapon); + if (string.find(itemSubType, weapon)) then + --SMARTBUFF_AddMsgD("Can apply " .. buff .. " on " .. itemSubType); + return true, weapon; + end + end + + end + return false; +end +-- END SMARTBUFF_CanApplyWeaponBuff + + +-- Check the unit blacklist +function SMARTBUFF_checkBlacklist() + local t = GetTime(); + for unit in pairs(cBlacklist) do + if (t > (cBlacklist[unit] + O.BlacklistTimer)) then + cBlacklist[unit] = nil; + end + end +end +-- END SMARTBUFF_checkBlacklist + + +-- Casts a spell +function SMARTBUFF_doCast(unit, id, spellName, levels, type) + if (id == nil) then return 9; end + if (type == SMARTBUFF_CONST_TRACK and (GetTrackingTexture() ~= "Interface\\Minimap\\Tracking\\None")) then + --SMARTBUFF_AddMsgD("Track already enabled: " .. iconTrack); + return 7; + end + + -- check if spell has cooldown + local _, cd = GetSpellCooldown(spellName) + if (not cd) then + -- move on + elseif (cd > maxSkipCoolDown) then + return 4; + elseif (cd > 0) then + return 1; + end + + -- Rangecheck + --SMARTBUFF_AddMsgD("Spell has range: "..spellName.." = "..ChkS(SpellHasRange(spellName))); + if (type == SMARTBUFF_CONST_GROUP or type == SMARTBUFF_CONST_ITEMGROUP) then + if (SpellHasRange(spellName)) then + if (IsSpellInRange(spellName, unit) ~= 1) then + return 3; + end + else + if (UnitInRange(unit) ~= 1) then + return 3; + end + end + end + + -- check if you have enough mana/energy/rage to cast + local isUsable, notEnoughMana = IsUsableSpell(spellName); + if (notEnoughMana) then + return 6; + end + + return 0; +end +-- END SMARTBUFF_doCast + + +-- checks if the unit is the player +function SMARTBUFF_IsPlayer(unit) + if (unit and UnitIsUnit("player", unit)) then + return true; + end + return false; +end +-- END SMARTBUFF_IsPlayer + + +function UnitBuffByBuffName(target,buffname,filter) + for i = 1,40 do + name = UnitBuff(target, i, filter); + if not name then return end + if name == buffname then + return UnitBuff(target, i, filter); + end + end +end + +-- Will return the name of the buff to cast +function SMARTBUFF_CheckUnitBuffs(unit, buffN, buffT, buffL, buffC) + if (not unit or (not buffN and not buffL)) then return end + + local i, n, v; + local buff = nil; + local defBuff = nil; + local timeleft = nil; + local duration = nil; + local caster = nil; + local count = nil; + local icon = nil; + local time = GetTime(); + local uname = UnitName(unit) or "?"; + + if (buffN) then + defBuff = buffN; + else + defBuff = buffL[1]; + end + + -- Stance/Presence/Seal check, these are not in the aura list + n = cBuffIndex[defBuff]; + if (cBuffs[n] and cBuffs[n].Type == SMARTBUFF_CONST_STANCE) then + if (defBuff and buffC and #buffC >= 1) then + local t = B[CS()].Order; + if (t and #t >= 1) then + --SMARTBUFF_AddMsgD("Check chained stance: "..defBuff); + for i = 1, #t, 1 do + --print("Check for chained stance: "..t[i]); + if (t[i] and tfind(buffC, t[i])) then + v = GetBuffSettings(t[i]); + if (v and v.EnableS) then + for n = 1, GetNumShapeshiftForms(), 1 do + local _, name, active, castable = GetShapeshiftFormInfo(n); + --print(t[i]..", "..name..", active = "..(active or "nil")); + if (name and not active and castable and name == t[i]) then + return defBuff, nil, nil, nil, nil; + elseif (name and active and castable and name == t[i]) then + --print("Chained stance found: "..t[i]); + return nil, i, defBuff, 1800, -1; + end + end + end + end + end + end + end + return defBuff, nil, nil, nil, nil; + + --[[ + count = tonumber(cBuffs[n].Params); + if (count) then + if (count == GetShapeshiftForm()) then + return nil, n, defBuff, 1800, -1; + else + SMARTBUFF_AddMsgD("BonusBarOffset: "..GetShapeshiftForm().." -> "..count); + end + return defBuff, nil, nil, nil, nil; + end + ]]-- + end + + -- Check linked buffs + if (buffL) then + if (not O.LinkSelfBuffCheck and buffT == SMARTBUFF_CONST_SELF) then + -- Do not check linked self buffs + elseif (not O.LinkGrpBuffCheck and buffT == SMARTBUFF_CONST_GROUP) then + -- Do not check linked group buffs + else + for n, v in pairs(buffL) do + if (v and v ~= defBuff) then + SMARTBUFF_AddMsgD("Check linked buff ("..uname.."): "..v); + buff, icon, count, _, duration, timeleft, caster = UnitBuffByBuffName(unit, v); + if (buff) then + timeleft = timeleft - GetTime(); + if (timeleft > 0) then + timeleft = timeleft; + else + timeleft = time; + end + SMARTBUFF_AddMsgD("Linked buff found: "..buff..", "..timeleft..", "..icon); + return nil, n, defBuff, timeleft, count; + end + end + end + end + end + + -- Check chained buffs + if (defBuff and buffC and #buffC > 1) then + local t = B[CS()].Order; + if (t and #t > 1) then + --SMARTBUFF_AddMsgD("Check chained buff ("..uname.."): "..defBuff); + for i = 1, #t, 1 do + if (t[i] and tfind(buffC, t[i])) then + v = GetBuffSettings(t[i]); + if (v and v.EnableS) then + local b, tl, im = SMARTBUFF_CheckBuff(unit, t[i]); + if (b and im) then + --SMARTBUFF_AddMsgD("Chained buff found: "..t[i]..", "..tl); + if (SMARTBUFF_CheckBuffLink(unit, t[i], v.Type, v.Links)) then + return nil, i, defBuff, tl, -1; + end + elseif (not b and t[i] == defBuff) then + return defBuff, nil, nil, nil, nil; + end + end + end + end + end + end + + -- Check default buff + if (defBuff) then + SMARTBUFF_AddMsgD("Check default buff ("..uname.."): "..defBuff); + buff, icon, count, _, duration, timeleft, caster = UnitBuffByBuffName(unit, defBuff); + if (buff) then + timeleft = timeleft - GetTime(); + if (timeleft > 0) then + timeleft = timeleft; + else + timeleft = time; + end + if (SMARTBUFF_IsPlayer(caster)) then + SMARTBUFF_UpdateBuffDuration(defBuff, duration); + end + SMARTBUFF_AddMsgD("Default buff found: "..buff..", "..timeleft..", "..icon); + return nil, 0, defBuff, timeleft, count; + end + end + + -- Buff not found, return default buff + return defBuff, nil, nil, nil, nil; +end + + +function SMARTBUFF_CheckBuffLink(unit, defBuff, buffT, buffL) + -- Check linked buffs + if (buffL) then + if (not O.LinkSelfBuffCheck and buffT == SMARTBUFF_CONST_SELF) then + -- Do not check linked self buffs + elseif (not O.LinkGrpBuffCheck and buffT == SMARTBUFF_CONST_GROUP) then + -- Do not check linked group buffs + else + for n, v in pairs(buffL) do + if (v and v ~= defBuff) then + SMARTBUFF_AddMsgD("Check linked buff ("..uname.."): "..v); + buff, icon, count, _, duration, timeleft, caster = UnitBuffByBuffName(unit, v); + if (buff) then + timeleft = timeleft - GetTime(); + if (timeleft > 0) then + timeleft = timeleft; + else + timeleft = time; + end + SMARTBUFF_AddMsgD("Linked buff found: "..buff..", "..timeleft..", "..icon); + return nil, n, defBuff, timeleft, count; + end + end + end + end + end + return defBuff; +end + +function SMARTBUFF_CheckBuffChain(unit, buff, chain) + local i; + if (buff and chain and #chain > 1) then + local t = B[CS()].Order; + if (t and #t > 1) then + SMARTBUFF_AddMsgD("Check chained buff: "..buff); + for i = 1, #t, 1 do + if (t[i] and t[i] ~= buff and tfind(chain, t[i])) then + local b, tl, im = SMARTBUFF_CheckBuff(unit, t[i], true); + if (b and im) then + SMARTBUFF_AddMsgD("Chained buff found: "..t[i]); + return nil, i, buff, tl, -1; + end + end + end + end + end + return buff; +end + + +function SMARTBUFF_UpdateBuffDuration(buff, duration) + local i = cBuffIndex[buff]; + if (i ~= nil and cBuffs[i] ~= nil and buff == cBuffs[i].BuffS) then + if (cBuffs[i].DurationS ~= nil and cBuffs[i].DurationS > 0 and cBuffs[i].DurationS ~= duration) then + SMARTBUFF_AddMsgD("Updated buff duration: "..buff.." = "..duration.."sec, old = "..cBuffs[i].DurationS); + cBuffs[i].DurationS = duration; + end + end +end + + +function UnitAuraBySpellName(target,spellname,filter) + for i = 1,40 do + name = UnitAura(target, i, filter); + if not name then return end + if name == spellname then + return UnitAura(target, i, filter); + end + end +end + +function SMARTBUFF_CheckBuff(unit, buffName, isMine) + if (not unit or not buffName) then + return false, 0; + end + local buff, _, _, _, _, timeleft, caster = UnitAuraBySpellName(unit, buffName, "HELPFUL"); + if (buff) then + SMARTBUFF_AddMsgD(UnitName(unit).." buff found: "..buff, 0, 1, 0.5); + if (buff == buffName) then + timeleft = timeleft - GetTime(); + if (timeleft > 0) then + timeleft = timeleft; + else + timeleft = time; + end + if (isMine and caster) then + if (SMARTBUFF_IsPlayer(caster)) then + return true, timeleft, caster; + end + return false, 0, nil; + end + return true, timeleft, SMARTBUFF_IsPlayer(caster); + end + end + return false, 0; +end +-- END SMARTBUFF_CheckUnitBuffs + + +-- Will return the name/description of the buff +function SMARTBUFF_GetBuffName(unit, buffIndex, line) + local i = buffIndex; + local name = nil; + if (i < 0 or i > maxBuffs) then + return nil; + end + --SmartBuffTooltip:SetOwner(SmartBuffFrame, "ANCHOR_NONE"); + SmartBuffTooltip:ClearLines(); + SmartBuffTooltip:SetUnitBuff(unit, i); + local obj = _G["SmartBuffTooltipTextLeft" .. line]; + if (obj) then + name = obj:GetText(); + end + return name; +end +-- END SMARTBUFF_GetBuffName + + +-- IsFeignDeath(unit) +function SMARTBUFF_IsFeignDeath(unit) + return UnitIsFeignDeath(unit); +end +-- END SMARTBUFF_IsFeignDeath + + +-- IsPicnic(unit) +function SMARTBUFF_IsPicnic(unit) + if (not SMARTBUFF_CheckUnitBuffs(unit, SMARTBUFF_FOOD_SPELL, SMARTBUFF_CONST_FOOD, {SMARTBUFF_FOOD_SPELL, SMARTBUFF_DRINK_SPELL})) then + return true; + end + return false; +end +-- END SMARTBUFF_IsPicnic + + +-- IsFishing(unit) +function SMARTBUFF_IsFishing(unit) + -- spell, rank, displayName, icon, startTime, endTime, isTradeSkill = UnitChannelInfo("unit") + local spell = UnitChannelInfo(unit); + if (spell ~= nil and SMARTBUFF_FISHING ~= nil and spell == SMARTBUFF_FISHING) then + --SMARTBUFF_AddMsgD("Channeling "..SMARTBUFF_FISHING); + return true; + end + return false; +end + +function SMARTBUFF_IsFishingPoleEquiped() + if (not SG or not SG.FishingPole) then return false end + + local link = GetInventoryItemLink("player", GetInventorySlotInfo("MainHandSlot")); + if (not link) then return false end + + local _, _, _, _, _, _, subType = GetItemInfo(link); + if (not subType) then return false end + + --print(SG.FishingPole.." - "..subType); + if (SG.FishingPole == subType) then return true end + + return false; +end +-- END SMARTBUFF_IsFishing + +-- SMARTBUFF_IsSpell(sType) +function SMARTBUFF_IsSpell(sType) + return sType == SMARTBUFF_CONST_GROUP or sType == SMARTBUFF_CONST_GROUPALL or sType == SMARTBUFF_CONST_SELF or sType == SMARTBUFF_CONST_FORCESELF or sType == SMARTBUFF_CONST_WEAPON or sType == SMARTBUFF_CONST_STANCE or sType == SMARTBUFF_CONST_ITEM; +end +-- END SMARTBUFF_IsSpell + +-- SMARTBUFF_IsItem(sType) +function SMARTBUFF_IsItem(sType) + return sType == SMARTBUFF_CONST_INV or sType == SMARTBUFF_CONST_FOOD or sType == SMARTBUFF_CONST_SCROLL or sType == SMARTBUFF_CONST_POTION or sType == SMARTBUFF_CONST_ITEMGROUP; +end +-- END SMARTBUFF_IsItem + + +-- Loops through all of the debuffs currently active looking for a texture string match +function SMARTBUFF_IsDebuffTexture(unit, debufftex) + local active = false; + local i = 1; + local name, icon; + -- name,rank,icon,count,type = UnitDebuff("unit", id or "name"[,"rank"]) + while (UnitDebuff(unit, i)) do + name, icon, _, _ = UnitDebuff(unit, i); + --SMARTBUFF_AddMsgD(i .. ". " .. name .. ", " .. icon); + if (string.find(icon, debufftex)) then + active = true; + break + end + i = i + 1; + end + return active; +end +-- END SMARTASPECT_IsDebuffTex + + +-- Returns the number of a reagent currently in player's bag +function SMARTBUFF_CountReagent(reagent, chain) + if (reagent == nil) then + return -1, nil; + end + + if(O.IncludeToys) then + local toy = SG.Toybox[reagent]; + if (toy) then + return 1, toy[1]; + end + end + + local n = 0; + local id = nil; + local bag = 0; + local slot = 0; + local tmpItem, itemName, count; + if (chain == nil) then chain = { reagent }; end + for bag = 0, NUM_BAG_FRAMES do + for slot = 1, C_Container.GetContainerNumSlots(bag) do + tmpItem = C_Container.GetContainerItemLink(bag, slot); +-- if tmpItem then print(tmpItem) end + if (tmpItem ~= nil) then + for i = 1, #chain, 1 do + --print(chain[i]); + if (chain[i] and string.find(tmpItem, "["..chain[i].."]", 1, true)) then +-- print("Item found: "..chain[i]); + containerInfo = C_Container.GetContainerItemInfo(bag, slot); + count = containerInfo.stackCount; + id = C_Container.GetContainerItemID(bag, slot); + n = n + count; + end + end + end + end + end + return n, id; +end + +function SMARTBUFF_FindItem(reagent, chain) + if (reagent == nil) then + return nil, nil, -1, nil; + end + + if(O.IncludeToys) then + local toy = SG.Toybox[reagent]; + if (toy) then + return 999, toy[1], 1, toy[2]; + end + end + + local n = 0; + local bag = 0; + local slot = 0; + local tmpItem, itemName, texture, count; + if (chain == nil) then chain = { reagent }; end + for bag = 0, NUM_BAG_FRAMES do + for slot = 1, C_Container.GetContainerNumSlots(bag) do + tmpItem = C_Container.GetContainerItemLink(bag, slot); + if (tmpItem ~= nil) then + --SMARTBUFF_AddMsgD("Reagent found: " .. tmpItem); + for i = 1, #chain, 1 do + --print(chain[i]); +-- if (chain[i] and string.find(itemName, chain[i], 1, true)) then + if (chain[i] and string.find(tmpItem, "["..chain[i].."]", 1, true)) then +-- print("Item found: "..chain[i]); + containerInfo = C_Container.GetContainerItemInfo(bag, slot); + return bag, slot, containerInfo.stackCount, containerInfo.iconFileID; + end + end + end + end + end + return nil, nil, 0, nil; +end +-- END Reagent functions + + +-- check the current zone and set buff template +function SMARTBUFF_CheckLocation() + if (not O.AutoSwitchTemplate and not O.AutoSwitchTemplateInst) then return; end + + local zone = GetRealZoneText(); + if (zone == nil) then + SMARTBUFF_AddMsgD("No zone found, try again..."); + tStartZone = GetTime(); + isSetZone = true; + return; + end + + isSetZone = false; + local tmp = nil; + local b = false; + + SMARTBUFF_AddMsgD("Current zone: "..zone..", last zone: "..sLastZone); + if (zone ~= sLastZone) then + sLastZone = zone; + if (IsActiveBattlefieldArena()) then + tmp = SMARTBUFF_TEMPLATES[5]; + elseif (SMARTBUFF_IsActiveBattlefield(zone) == 1) then + tmp = SMARTBUFF_TEMPLATES[4]; + else + if (O.AutoSwitchTemplateInst) then + local i = 1; + for _ in pairs(SMARTBUFF_INSTANCES) do + if (string.find(string.lower(zone), string.lower(SMARTBUFF_INSTANCES[i]))) then + b = true; + break; + end + i = i + 1; + end + tmp = nil; + if (b) then + if (SMARTBUFF_TEMPLATES[i + 5] ~= nil) then + tmp = SMARTBUFF_TEMPLATES[i + 5] + end + end + end + end + + --SMARTBUFF_AddMsgD("Current tmpl: " .. currentTemplate .. " - new tmpl: " .. tmp); + if (tmp and currentTemplate ~= tmp) then + SMARTBUFF_AddMsg(SMARTBUFF_OFT_AUTOSWITCHTMP .. ": " .. currentTemplate .. " -> " .. tmp); + currentTemplate = tmp; + SMARTBUFF_SetBuffs(); + end + end +end +-- END SMARTBUFF_CheckLocation + + +-- checks if the player is inside a battlefield +function SMARTBUFF_IsActiveBattlefield(zone) + local i, status, map, instanceId, teamSize; + for i = 1, GetMaxBattlefieldID() do + status, map, instanceId, _, _, teamSize = GetBattlefieldStatus(i); + if (status and status ~= "none") then + SMARTBUFF_AddMsgD("Battlefield status = "..ChkS(status)..", Id = "..ChkS(instanceId)..", TS = "..ChkS(teamSize)..", Map = "..ChkS(map)..", Zone = "..ChkS(zone)); + else + SMARTBUFF_AddMsgD("Battlefield status = none"); + end + if (status and status == "active" and map) then + if (teamSize and type(teamSize) == "number" and teamSize > 0) then + return 2; + end + return 1; + end + end + return 0; +end +-- END IsActiveBattlefield + + +-- Helper functions --------------------------------------------------------------------------------------- +function SMARTBUFF_toggleBool(b, msg) + if (not b or b == nil) then + b = true; + SMARTBUFF_AddMsg(SMARTBUFF_TITLE .. ": " .. msg .. GR .. "On", true); + else + b = false + SMARTBUFF_AddMsg(SMARTBUFF_TITLE .. ": " .. msg .. RD .."Off", true); + end + return b; +end + +function SMARTBUFF_BoolState(b, msg) + if (b) then + SMARTBUFF_AddMsg(SMARTBUFF_TITLE .. ": " .. msg .. GR .. "On", true); + else + SMARTBUFF_AddMsg(SMARTBUFF_TITLE .. ": " .. msg .. RD .."Off", true); + end +end + +function SMARTBUFF_Split(msg, char) + local arr = { }; + while (string.find(msg, char)) do + local iStart, iEnd = string.find(msg, char); + tinsert(arr, strsub(msg, 1, iStart - 1)); + msg = strsub(msg, iEnd + 1, strlen(msg)); + end + if (strlen(msg) > 0) then + tinsert(arr, msg); + end + return arr; +end +-- END Bool helper functions + + +-- Init the SmartBuff variables --------------------------------------------------------------------------------------- +function SMARTBUFF_Options_Init(self) + + if (isInit) then return; end + + self:UnregisterEvent("CHAT_MSG_CHANNEL"); + self:UnregisterEvent("UPDATE_MOUSEOVER_UNIT"); + + --DebugChatFrame:AddMessage("Starting init SB"); + + _, sPlayerClass = UnitClass("player"); + sRealmName = GetRealmName(); + sPlayerName = UnitName("player"); + sID = sRealmName .. ":" .. sPlayerName; + --AutoSelfCast = GetCVar("autoSelfCast"); + + SMARTBUFF_PLAYERCLASS = sPlayerClass; + + + if (not SMARTBUFF_Buffs) then SMARTBUFF_Buffs = { }; end + B = SMARTBUFF_Buffs; + if (not SMARTBUFF_Options) then SMARTBUFF_Options = { }; end + O = SMARTBUFF_Options; + + SMARTBUFF_BROKER_SetIcon(); + + + if (O.Toggle == nil) then O.Toggle = true; end + if (O.SendVerInfo == nil) then O.SendVerInfo = true; end + if (O.ToggleAuto == nil) then O.ToggleAuto = true; end + if (O.AutoTimer == nil) then O.AutoTimer = 5; end + if (O.BlacklistTimer == nil) then O.BlacklistTimer = 5; end + if (O.ToggleAutoCombat == nil) then O.ToggleAutoCombat = false; end + if (O.ToggleAutoChat == nil) then O.ToggleAutoChat = false; end + if (O.ToggleAutoSplash == nil) then O.ToggleAutoSplash = true; end + if (O.ToggleAutoSound == nil) then O.ToggleAutoSound = true; end + if (O.AutoSoundSelection == nil) then O.AutoSoundSelection = 4; end; + if (O.CheckCharges == nil) then O.CheckCharges = true; end + --if (O.ToggleAutoRest == nil) then O.ToggleAutoRest = true; end + if (O.RebuffTimer == nil) then O.RebuffTimer = 20; end + if (O.SplashDuration == nil) then O.SplashDuration = 2; end + if (O.SplashIconSize == nil) then O.SplashIconSize = 16; end + + if (O.BuffTarget == nil) then O.BuffTarget = false; end + if (O.BuffPvP == nil) then O.BuffPvP = false; end + if (O.BuffInCities == nil) then O.BuffInCities = true; end + if (O.LinkSelfBuffCheck == nil) then O.LinkSelfBuffCheck = true; end + if (O.LinkGrpBuffCheck == nil) then O.LinkGrpBuffCheck = true; end + if (O.AntiDaze == nil) then O.AntiDaze = true; end + + if (O.ScrollWheel ~= nil and O.ScrollWheelUp == nil) then O.ScrollWheelUp = O.ScrollWheel; end + if (O.ScrollWheel ~= nil and O.ScrollWheelDown == nil) then O.ScrollWheelDown = O.ScrollWheel; end + if (O.ScrollWheelUp == nil) then O.ScrollWheelUp = true; end + if (O.ScrollWheelDown == nil) then O.ScrollWheelDown = true; end + + if (O.InCombat == nil) then O.InCombat = true; end + if (O.IncludeToys == nil) then O.IncludeToys = false; end + if (O.AutoSwitchTemplate == nil) then O.AutoSwitchTemplate = true; end + if (O.AutoSwitchTemplateInst == nil) then O.AutoSwitchTemplateInst = true; end + if (O.InShapeshift == nil) then O.InShapeshift = true; end + + O.ToggleGrp = {true, true, true, true, true, true, true, true}; + + if (O.ToggleMsgNormal == nil) then O.ToggleMsgNormal = false; end + if (O.ToggleMsgWarning == nil) then O.ToggleMsgWarning = false; end + if (O.ToggleMsgError == nil) then O.ToggleMsgError = false; end + + if (O.HideMmButton == nil) then O.HideMmButton = false; end + if (O.HideSAButton == nil) then O.HideSAButton = false; end + + if (O.SBButtonFix == nil) then O.SBButtonFix = false; end + if (O.SBButtonDownVal == nil) then O.SBButtonDownVal = GetCVarBool("ActionButtonUseKeyDown"); end + + if (O.MinCharges == nil) then + if (sPlayerClass == "SHAMAN" or sPlayerClass == "PRIEST") then + O.MinCharges = 1; + else + O.MinCharges = 3; + end + end + + if (not O.AddList) then O.AddList = { }; end + if (not O.IgnoreList) then O.IgnoreList = { }; end + + if (O.LastTemplate == nil) then O.LastTemplate = SMARTBUFF_TEMPLATES[1]; end + local b = false; + while (SMARTBUFF_TEMPLATES[i] ~= nil) do + if (SMARTBUFF_TEMPLATES[i] == O.LastTemplate) then + b = true; + break; + end + i = i + 1; + end + if (not b) then + O.LastTemplate = SMARTBUFF_TEMPLATES[1]; + end + + currentTemplate = O.LastTemplate; + currentSpec = GetSpecialization(); + + if (O.OldWheelUp == nil) then O.OldWheelUp = ""; end + if (O.OldWheelDown == nil) then O.OldWheelDown = ""; end + + SMARTBUFF_InitActionButtonPos(); + + if (O.SplashX == nil) then O.SplashX = 100; end + if (O.SplashY == nil) then O.SplashY = -100; end + if (O.CurrentFont == nil) then O.CurrentFont = 9; end + if (O.ColSplashFont == nil) then + O.ColSplashFont = { }; + O.ColSplashFont.r = 1.0; + O.ColSplashFont.g = 1.0; + O.ColSplashFont.b = 1.0; + end + iCurrentFont = O.CurrentFont; + + if (O.Debug == nil) then O.Debug = false; end + + -- Cosmos support + if(EarthFeature_AddButton) then + EarthFeature_AddButton( + { id = SMARTBUFF_TITLE; + name = SMARTBUFF_TITLE; + subtext = SMARTBUFF_TITLE; + tooltip = ""; + icon = imgSB; + callback = SMARTBUFF_OptionsFrame_Toggle; + test = nil; + } ) + elseif (Cosmos_RegisterButton) then + Cosmos_RegisterButton(SMARTBUFF_TITLE, SMARTBUFF_TITLE, SMARTBUFF_TITLE, imgSB, SMARTBUFF_OptionsFrame_Toggle); + end + + if (IsAddOnLoaded("Parrot")) then + isParrot = true; + end + + SMARTBUFF_FindItem("ScanBagsForSBInit"); + + SMARTBUFF_AddMsg(SMARTBUFF_VERS_TITLE .. " " .. SMARTBUFF_MSG_LOADED, true); + SMARTBUFF_AddMsg("/sbm - " .. SMARTBUFF_OFT_MENU, true); + isInit = true; + + SMARTBUFF_CheckMiniMapButton(); + SMARTBUFF_MinimapButton_OnUpdate(SmartBuff_MiniMapButton); + SMARTBUFF_ShowSAButton(); + SMARTBUFF_Splash_Hide(); + + if (O.UpgradeToDualSpec == nil) then + for n = 1, GetNumSpecGroups(), 1 do + if (B[n] == nil) then + B[n] = { }; + end + for k, v in pairs(SMARTBUFF_TEMPLATES) do + SMARTBUFF_AddMsgD(v); + if (B[v] ~= nil) then + B[n][v] = B[v]; + end + end + end + for k, v in pairs(SMARTBUFF_TEMPLATES) do + if (B[v] ~= nil) then + wipe(B[v]); + B[v] = nil; + end + end + O.UpgradeToDualSpec = true; + SMARTBUFF_AddMsg("Upgraded to dual spec", true); + end + + for k, v in pairs(cClasses) do + if (SMARTBUFF_CLASSES[k] == nil) then + SMARTBUFF_CLASSES[k] = v; + end + end + + if (O.VersionNr == nil or O.VersionNr < SMARTBUFF_VERSIONNR) then + O.VersionNr = SMARTBUFF_VERSIONNR; + SMARTBUFF_SetBuffs(); + InitBuffOrder(true); + print("Upgraded SmartBuff to "..SMARTBUFF_VERSION); + end + + if (SMARTBUFF_OptionsGlobal == nil) then SMARTBUFF_OptionsGlobal = { }; end + OG = SMARTBUFF_OptionsGlobal; + if (OG.SplashIcon == nil) then OG.SplashIcon = true; end + if (OG.SplashMsgShort == nil) then OG.SplashMsgShort = false; end + if (OG.FirstStart == nil) then OG.FirstStart = "V0"; end + + SMARTBUFF_Splash_ChangeFont(0); + if (OG.FirstStart ~= SMARTBUFF_VERSION) then + OG.FirstStart = SMARTBUFF_VERSION; + SMARTBUFF_OptionsFrame_Open(true); + + if (OG.Tutorial == nil) then + OG.Tutorial = SMARTBUFF_VERSIONNR; + SMARTBUFF_ToggleTutorial(); + end + + SmartBuffWNF_lblText:SetText(SMARTBUFF_WHATSNEW); + SmartBuffWNF:Show(); + else + SMARTBUFF_SetBuffs(); + end + + if (not IsVisibleToPlayer(SmartBuff_KeyButton)) then + SmartBuff_KeyButton:ClearAllPoints(); + SmartBuff_KeyButton:SetPoint("CENTER", UIParent, "CENTER", 0, 100); + end + + SMARTBUFF_SetUnits(); + SMARTBUFF_RebindKeys(); + isSyncReq = true; +end +-- END SMARTBUFF_Options_Init + +function SMARTBUFF_InitActionButtonPos() + if (InCombatLockdown()) then return end + + isInitBtn = true; + if (O.ActionBtnX == nil) then + SMARTBUFF_SetButtonPos(SmartBuff_KeyButton); + else + SmartBuff_KeyButton:ClearAllPoints(); + SmartBuff_KeyButton:SetPoint("TOPLEFT", UIParent, "TOPLEFT", O.ActionBtnX, O.ActionBtnY); + end + --print(format("x = %.0f, y = %.0f", O.ActionBtnX, O.ActionBtnY)); +end + +function SMARTBUFF_ResetAll() + wipe(SMARTBUFF_Buffs); + wipe(SMARTBUFF_Options); + ReloadUI(); +end + +function SMARTBUFF_SetButtonPos(self) + local x, y = self:GetLeft(), self:GetTop() - UIParent:GetHeight(); + O.ActionBtnX = x; + O.ActionBtnY = y; + --print(format("x = %.0f, y = %.0f", x, y)); +end + +function SMARTBUFF_RebindKeys() + local i; + isRebinding = true; + for i = 1, GetNumBindings(), 1 do + local s = ""; + local command, key1, key2 = GetBinding(i); + + --if (command and key1) then + -- SMARTBUFF_AddMsgD(i .. " = " .. command .. " - " .. key1; + --end + + if (key1 and key1 == "MOUSEWHEELUP" and command ~= "SmartBuff_KeyButton") then + O.OldWheelUp = command; + --SMARTBUFF_AddMsgD("Old wheel up: " .. command); + elseif (key1 and key1 == "MOUSEWHEELDOWN" and command ~= "SmartBuff_KeyButton") then + O.OldWheelDown = command; + --SMARTBUFF_AddMsgD("Old wheel down: " .. command); + end + + if (command and command == "SMARTBUFF_BIND_TRIGGER") then + --s = i .. " = " .. command; + if (key1) then + --s = s .. ", key1 = " .. key1 .. " rebound"; + SetBindingClick(key1, "SmartBuff_KeyButton"); + end + if (key2) then + --s = s .. ", key2 = " .. key2 .. " rebound"; + SetBindingClick(key2, "SmartBuff_KeyButton"); + end + --SMARTBUFF_AddMsgD(s); + break; + end + end + + if (O.ScrollWheelUp) then + isKeyUpChanged = true; + SetOverrideBindingClick(SmartBuffFrame, false, "MOUSEWHEELUP", "SmartBuff_KeyButton", "MOUSEWHEELUP"); + --SMARTBUFF_AddMsgD("Set wheel up"); + else + if (isKeyUpChanged) then + isKeyUpChanged = false; + SetOverrideBinding(SmartBuffFrame, false, "MOUSEWHEELUP"); + --SMARTBUFF_AddMsgD("Set old wheel up: " .. O.OldWheelUp); + end + end + + if (O.ScrollWheelDown) then + isKeyDownChanged = true; + SetOverrideBindingClick(SmartBuffFrame, false, "MOUSEWHEELDOWN", "SmartBuff_KeyButton", "MOUSEWHEELDOWN"); + --SMARTBUFF_AddMsgD("Set wheel down"); + else + if (isKeyDownChanged) then + isKeyDownChanged = false; + SetOverrideBinding(SmartBuffFrame, false, "MOUSEWHEELDOWN"); + --SMARTBUFF_AddMsgD("Set old wheel down: " .. O.OldWheelDown); + end + end + isRebinding = false; +end + +function SMARTBUFF_ResetBindings() + if (not isRebinding) then + isRebinding = true; + if (O.OldWheelUp == "SmartBuff_KeyButton") then + SetBinding("MOUSEWHEELUP", "CAMERAZOOMIN"); + else + SetBinding("MOUSEWHEELUP", O.OldWheelUp); + end + if (O.OldWheelDown == "SmartBuff_KeyButton") then + SetBinding("MOUSEWHEELDOWN", "CAMERAZOOMOUT"); + else + SetBinding("MOUSEWHEELDOWN", O.OldWheelDown); + end + SaveBindings(GetCurrentBindingSet()); + SMARTBUFF_RebindKeys(); + end +end + + +-- SmartBuff commandline menu --------------------------------------------------------------------------------------- +function SMARTBUFF_command(msg) + if (not isInit) then + SMARTBUFF_AddMsgWarn(SMARTBUFF_VERS_TITLE.." not initialized correctly!", true); + return; + end + + if(msg == "toggle" or msg == "t") then + SMARTBUFF_OToggle(); + SMARTBUFF_SetUnits(); + elseif (msg == "menu") then + SMARTBUFF_OptionsFrame_Toggle(); + elseif (msg == "rbt") then + SMARTBUFF_ResetBuffTimers(); + elseif (msg == "sbt") then + SMARTBUFF_ShowBuffTimers(); + elseif (msg == "target") then + if (SMARTBUFF_PreCheck(0)) then + SMARTBUFF_checkBlacklist(); + SMARTBUFF_BuffUnit("target", 0, 0); + end + elseif (msg == "debug") then + O.Debug = SMARTBUFF_toggleBool(O.Debug, "Debug active = "); + elseif (msg == "open") then + SMARTBUFF_OptionsFrame_Open(true); + elseif (msg == "sync") then + SMARTBUFF_SyncBuffTimers(); + elseif (msg == "rb") then + SMARTBUFF_ResetBindings(); + SMARTBUFF_AddMsg("SmartBuff key and mouse bindings reset.", true); + elseif (msg == "rafp") then + SmartBuffSplashFrame:ClearAllPoints(); + SmartBuffSplashFrame:SetPoint("CENTER", UIParent, "CENTER"); + SmartBuff_MiniMapButton:ClearAllPoints(); + SmartBuff_MiniMapButton:SetPoint("TOPLEFT", Minimap, "TOPLEFT"); + SmartBuff_KeyButton:ClearAllPoints(); + SmartBuff_KeyButton:SetPoint("CENTER", UIParent, "CENTER"); + SmartBuffOptionsFrame:ClearAllPoints(); + SmartBuffOptionsFrame:SetPoint("CENTER", UIParent, "CENTER"); + elseif (msg == "test") then + + -- Test Code ****************************************** + -- **************************************************** + --local spellname = "Mind--numbing Poison"; + --SMARTBUFF_AddMsg("Original: " .. spellname, true); + --if (string.find(spellname, "%-%-") ~= nil) then + -- spellname = string.gsub(spellname, "%-%-", "%-"); + --end + --SMARTBUFF_AddMsg("Modified: " .. spellname, true); + -- **************************************************** + -- **************************************************** + + else + --SMARTBUFF_Check(0); + SMARTBUFF_AddMsg(SMARTBUFF_VERS_TITLE, true); + SMARTBUFF_AddMsg("Syntax: /sbo [command] or /sbuff [command] or /smartbuff [command]", true); + SMARTBUFF_AddMsg("toggle - " .. SMARTBUFF_OFT, true); + SMARTBUFF_AddMsg("menu - " .. SMARTBUFF_OFT_MENU, true); + SMARTBUFF_AddMsg("target - " .. SMARTBUFF_OFT_TARGET, true); + SMARTBUFF_AddMsg("rbt - " .. "Reset buff timers", true); + SMARTBUFF_AddMsg("sbt - " .. "Show buff timers", true); + SMARTBUFF_AddMsg("rafp - " .. "Reset all frame positions", true); + SMARTBUFF_AddMsg("sync - " .. "Sync buff timers with UI", true); + SMARTBUFF_AddMsg("rb - " .. "Reset key/mouse bindings", true); + end +end +-- END SMARTBUFF_command + + +-- SmartBuff options toggle --------------------------------------------------------------------------------------- +function SMARTBUFF_OToggle() + if (not isInit) then return; end + O.Toggle = SMARTBUFF_toggleBool(O.Toggle, "Active = "); + SMARTBUFF_CheckMiniMapButton(); + if (O.Toggle) then + SMARTBUFF_SetUnits(); + end +end + +function SMARTBUFF_OToggleAuto() + O.ToggleAuto = not O.ToggleAuto; +end +function SMARTBUFF_OToggleAutoCombat() + O.ToggleAutoCombat = not O.ToggleAutoCombat; +end +function SMARTBUFF_OToggleAutoChat() + O.ToggleAutoChat = not O.ToggleAutoChat; +end +function SMARTBUFF_OToggleAutoSplash() + O.ToggleAutoSplash = not O.ToggleAutoSplash; +end +function SMARTBUFF_OToggleAutoSound() + O.ToggleAutoSound = not O.ToggleAutoSound; +end + +--function SMARTBUFF_OToggleCheckCharges() +-- O.ToggleCheckCharges = not O.ToggleCheckCharges; +--end +--function SMARTBUFF_OToggleAutoRest() +-- O.ToggleAutoRest = not O.ToggleAutoRest; +--end + +function SMARTBUFF_OAutoSwitchTmp() + O.AutoSwitchTemplate = not O.AutoSwitchTemplate; +end +function SMARTBUFF_OAutoSwitchTmpInst() + O.AutoSwitchTemplateInst = not O.AutoSwitchTemplateInst; +end + +function SMARTBUFF_OBuffTarget() + O.BuffTarget = not O.BuffTarget; +end + +function SMARTBUFF_OBuffPvP() + O.BuffPvP = not O.BuffPvP; +end + +function SMARTBUFF_OBuffInCities() + O.BuffInCities = not O.BuffInCities; +end + +function SMARTBUFF_OLinkSelfBuffCheck() + O.LinkSelfBuffCheck = not O.LinkSelfBuffCheck; +end +function SMARTBUFF_OLinkGrpBuffCheck() + O.LinkGrpBuffCheck = not O.LinkGrpBuffCheck; +end +function SMARTBUFF_OAntiDaze() + O.AntiDaze = not O.AntiDaze; +end + +function SMARTBUFF_OScrollWheelUp() + O.ScrollWheelUp = not O.ScrollWheelUp; + isKeyUpChanged = true; +end +function SMARTBUFF_OScrollWheelDown() + O.ScrollWheelDown = not O.ScrollWheelDown; + isKeyDownChanged = true; +end +function SMARTBUFF_OInShapeshift() + O.InShapeshift = not O.InShapeshift; +end +function SMARTBUFF_OInCombat() + O.InCombat = not O.InCombat; +end +function SMARTBUFF_OIncludeToys() + O.IncludeToys = not O.IncludeToys; + SMARTBUFF_Options_OnShow(); + SMARTBUFF_BuffOrderReset(); +end +function SMARTBUFF_OToggleMsgNormal() + O.ToggleMsgNormal = not O.ToggleMsgNormal; +end +function SMARTBUFF_OToggleMsgWarning() + O.ToggleMsgWarning = not O.ToggleMsgWarning; +end +function SMARTBUFF_OToggleMsgError() + O.ToggleMsgError = not O.ToggleMsgError; +end + +function SMARTBUFF_OHideMmButton() + O.HideMmButton = not O.HideMmButton; + SMARTBUFF_CheckMiniMapButton(); +end +function SMARTBUFF_OHideSAButton() + O.HideSAButton = not O.HideSAButton; + SMARTBUFF_ShowSAButton(); +end + +function SMARTBUFF_OSelfFirst() + B[CS()][currentTemplate].SelfFirst = not B[CS()][currentTemplate].SelfFirst; +end + +function SMARTBUFF_OToggleBuff(s, i) + local bs = GetBuffSettings(cBuffs[i].BuffS); + if (bs == nil) then + return; + end + + if (s == "S") then + bs.EnableS = not bs.EnableS; + --SMARTBUFF_AddMsgD("OToggleBuff = "..cBuffs[i].BuffS..", "..tostring(bs.EnableS)); + if (bs.EnableS) then + SmartBuff_BuffSetup_Show(i); + else + SmartBuff_BuffSetup:Hide(); + iLastBuffSetup = -1; + SmartBuff_PlayerSetup:Hide(); + end + elseif (s == "G") then + bs.EnableG = not bs.EnableG; + end + +end + +function SMARTBUFF_OToggleDebug() + O.Debug = not O.Debug; +end + +function SMARTBUFF_ToggleFixBuffing() + O.SBButtonFix = not O.SBButtonFix; + if not O.SBButtonFix then SetCVar("ActionButtonUseKeyDown", O.SBButtonDownVal ); end +end + +function SMARTBUFF_OptionsFrame_Toggle() + if (not isInit) then return; end + + if(SmartBuffOptionsFrame:IsVisible()) then + if(iLastBuffSetup > 0) then + SmartBuff_BuffSetup:Hide(); + iLastBuffSetup = -1; + SmartBuff_PlayerSetup:Hide(); + end + SmartBuffOptionsFrame:Hide(); + else + SmartBuffOptionsCredits_lblText:SetText(SMARTBUFF_CREDITS); + SmartBuffOptionsFrame:Show(); + SmartBuff_PlayerSetup:Hide(); + end + + SMARTBUFF_MinimapButton_CheckPos(); +end + +function SMARTBUFF_OptionsFrame_Open(force) + if (not isInit) then return; end + if(not SmartBuffOptionsFrame:IsVisible() or force) then + SmartBuffOptionsFrame:Show(); + end +end + +function SmartBuff_BuffSetup_Show(i) + local icon1 = cBuffs[i].IconS; + local icon2 = cBuffs[i].IconG; + local name = cBuffs[i].BuffS; + local btype = cBuffs[i].Type; + local hidden = true; + local n = 0; + local bs = GetBuffSettings(name); + + if (name == nil or btype == SMARTBUFF_CONST_TRACK) then + SmartBuff_BuffSetup:Hide(); + iLastBuffSetup = -1; + SmartBuff_PlayerSetup:Hide(); + return; + end + + if(SmartBuff_BuffSetup:IsVisible() and i == iLastBuffSetup) then + SmartBuff_BuffSetup:Hide(); + iLastBuffSetup = -1; + SmartBuff_PlayerSetup:Hide(); + return; + else + if (btype == SMARTBUFF_CONST_GROUP or btype == SMARTBUFF_CONST_ITEMGROUP) then + hidden = false; + end + + if (icon2 and bs.EnableG) then + SmartBuff_BuffSetup_BuffIcon2:SetNormalTexture(icon2); + SmartBuff_BuffSetup_BuffIcon2:Show(); + else + SmartBuff_BuffSetup_BuffIcon2:Hide(); + end + if (icon1) then + SmartBuff_BuffSetup_BuffIcon1:SetNormalTexture(icon1); + if (icon2 and bs.EnableG) then + SmartBuff_BuffSetup_BuffIcon1:SetPoint("TOPLEFT", 44, -30); + else + SmartBuff_BuffSetup_BuffIcon1:SetPoint("TOPLEFT", 64, -30); + end + SmartBuff_BuffSetup_BuffIcon1:Show(); + else + SmartBuff_BuffSetup_BuffIcon1:SetPoint("TOPLEFT", 24, -30); + SmartBuff_BuffSetup_BuffIcon1:Hide(); + end + + local obj = SmartBuff_BuffSetup_BuffText; + if (name) then + obj:SetText(name); + --SMARTBUFF_AddMsgD(name); + else + obj:SetText(""); + end + + SmartBuff_BuffSetup_cbSelf:SetChecked(bs.SelfOnly); + SmartBuff_BuffSetup_cbSelfNot:SetChecked(bs.SelfNot); + SmartBuff_BuffSetup_cbCombatIn:SetChecked(bs.CIn); + SmartBuff_BuffSetup_cbCombatOut:SetChecked(bs.COut); + SmartBuff_BuffSetup_cbMH:SetChecked(bs.MH); + SmartBuff_BuffSetup_cbOH:SetChecked(bs.OH); + SmartBuff_BuffSetup_cbRH:SetChecked(bs.RH); + SmartBuff_BuffSetup_cbReminder:SetChecked(bs.Reminder); + SmartBuff_BuffSetup_txtManaLimit:SetNumber(bs.ManaLimit); + + --SMARTBUFF_AddMsgD("Test Buff setup show 1"); + if (cBuffs[i].DurationS > 0) then + SmartBuff_BuffSetup_RBTime:SetMinMaxValues(0, cBuffs[i].DurationS); + _G[SmartBuff_BuffSetup_RBTime:GetName().."High"]:SetText(cBuffs[i].DurationS); + if (cBuffs[i].DurationS <= 60) then + SmartBuff_BuffSetup_RBTime:SetValueStep(1); + elseif (cBuffs[i].DurationS <= 180) then + SmartBuff_BuffSetup_RBTime:SetValueStep(5); + elseif (cBuffs[i].DurationS <= 600) then + SmartBuff_BuffSetup_RBTime:SetValueStep(10); + else + SmartBuff_BuffSetup_RBTime:SetValueStep(30); + end + SmartBuff_BuffSetup_RBTime:SetValue(bs.RBTime); + _G[SmartBuff_BuffSetup_RBTime:GetName().."Text"]:SetText(bs.RBTime .. "\nsec"); + SmartBuff_BuffSetup_RBTime:Show(); + else + SmartBuff_BuffSetup_RBTime:Hide(); + end + --SMARTBUFF_AddMsgD("Test Buff setup show 2"); + + SmartBuff_BuffSetup_txtManaLimit:Hide(); + if (cBuffs[i].Type == SMARTBUFF_CONST_INV or cBuffs[i].Type == SMARTBUFF_CONST_WEAPON) then + SmartBuff_BuffSetup_cbMH:Show(); + SmartBuff_BuffSetup_cbOH:Show(); + SmartBuff_BuffSetup_cbRH:Hide(); + else + SmartBuff_BuffSetup_cbMH:Hide(); + SmartBuff_BuffSetup_cbOH:Hide(); + SmartBuff_BuffSetup_cbRH:Hide(); + if (cBuffs[i].Type ~= SMARTBUFF_CONST_FOOD and cBuffs[i].Type ~= SMARTBUFF_CONST_SCROLL and cBuffs[i].Type ~= SMARTBUFF_CONST_POTION) then + SmartBuff_BuffSetup_txtManaLimit:Show(); + --SMARTBUFF_AddMsgD("Show ManaLimit"); + end + end + + if (cBuffs[i].Type == SMARTBUFF_CONST_GROUP or cBuffs[i].Type == SMARTBUFF_CONST_ITEMGROUP) then + SmartBuff_BuffSetup_cbSelf:Show(); + SmartBuff_BuffSetup_cbSelfNot:Show(); + SmartBuff_BuffSetup_btnPriorityList:Show(); + SmartBuff_BuffSetup_btnIgnoreList:Show(); + else + SmartBuff_BuffSetup_cbSelf:Hide(); + SmartBuff_BuffSetup_cbSelfNot:Hide(); + SmartBuff_BuffSetup_btnPriorityList:Hide(); + SmartBuff_BuffSetup_btnIgnoreList:Hide(); + SmartBuff_PlayerSetup:Hide(); + end + + local cb = nil; + local btn = nil; + n = 0; + --SMARTBUFF_AddMsgD("Test Buff setup show 3"); + for _ in pairs(cClasses) do + n = n + 1; + cb = _G["SmartBuff_BuffSetup_cbClass"..n]; + btn = _G["SmartBuff_BuffSetup_ClassIcon"..n]; + if (hidden) then + cb:Hide(); + btn:Hide(); + else + cb:SetChecked(bs[cClasses[n]]); + cb:Show(); + btn:Show(); + end + end + iLastBuffSetup = i; + --SMARTBUFF_AddMsgD("Test Buff setup show 4"); + SmartBuff_BuffSetup:Show(); + + if (SmartBuff_PlayerSetup:IsVisible()) then + SmartBuff_PS_Show(iCurrentList); + end + end +end + +function SmartBuff_BuffSetup_ManaLimitChanged(self) + local i = iLastBuffSetup; + if (i <= 0) then + return; + end + local ct = currentTemplate; + local name = cBuffs[i].BuffS; + B[CS()][ct][name].ManaLimit = self:GetNumber(); +end + +function SmartBuff_BuffSetup_OnClick() + local i = iLastBuffSetup; + local ct = currentTemplate; + if (i <= 0) then + return; + end + local name = cBuffs[i].BuffS; + local cBuff = GetBuffSettings(name); + + cBuff.SelfOnly = SmartBuff_BuffSetup_cbSelf:GetChecked(); + cBuff.SelfNot = SmartBuff_BuffSetup_cbSelfNot:GetChecked(); + cBuff.CIn = SmartBuff_BuffSetup_cbCombatIn:GetChecked(); + cBuff.COut = SmartBuff_BuffSetup_cbCombatOut:GetChecked(); + cBuff.MH = SmartBuff_BuffSetup_cbMH:GetChecked(); + cBuff.OH = SmartBuff_BuffSetup_cbOH:GetChecked(); + cBuff.RH = SmartBuff_BuffSetup_cbRH:GetChecked(); + cBuff.Reminder = SmartBuff_BuffSetup_cbReminder:GetChecked(); + + cBuff.RBTime = SmartBuff_BuffSetup_RBTime:GetValue(); + _G[SmartBuff_BuffSetup_RBTime:GetName().."Text"]:SetText(cBuff.RBTime .. "\nsec"); + + if (cBuffs[i].Type == SMARTBUFF_CONST_GROUP or cBuffs[i].Type == SMARTBUFF_CONST_ITEMGROUP) then + local n = 0; + local cb = nil; + for _ in pairs(cClasses) do + n = n + 1; + cb = _G["SmartBuff_BuffSetup_cbClass"..n]; + cBuff[cClasses[n]] = cb:GetChecked(); + end + end + --SMARTBUFF_AddMsgD("Buff setup saved"); +end + +function SmartBuff_BuffSetup_ToolTip(mode) + local i = iLastBuffSetup; + if (i <= 0) then + return; + end + local ids = cBuffs[i].IDS; + local idg = cBuffs[i].IDG; + local btype = cBuffs[i].Type + + GameTooltip:ClearLines(); + if (SMARTBUFF_IsItem(btype)) then + local bag, slot, count, texture = SMARTBUFF_FindItem(cBuffs[i].BuffS, cBuffs[i].Chain); + if (bag and slot) then + if (bag == 999) then -- Toy + GameTooltip:SetToyByItemID(slot); + else + GameTooltip:SetBagItem(bag, slot); + end + end + else + if (mode == 1 and ids) then + local link = GetSpellLink(ids); + if (link) then GameTooltip:SetHyperlink(link); end + elseif (mode == 2 and idg) then + local link = GetSpellLink(idg); + if (link) then GameTooltip:SetHyperlink(link); end + end + end + GameTooltip:Show(); +end +-- END SmartBuff options toggle + + +-- Options frame functions --------------------------------------------------------------------------------------- +function SMARTBUFF_Options_OnLoad(self) +end + +function SMARTBUFF_Options_OnShow() + -- Check if the options frame is out of screen area + local top = GetScreenHeight() - math.abs(SmartBuffOptionsFrame:GetTop()); + local bottom = GetScreenHeight() - math.abs(SmartBuffOptionsFrame:GetBottom()); + local left = SmartBuffOptionsFrame:GetLeft(); + local right = SmartBuffOptionsFrame:GetRight(); + + --SMARTBUFF_AddMsgD("X: " .. GetScreenWidth() .. ", " .. left .. ", " .. right); + --SMARTBUFF_AddMsgD("Y: " .. GetScreenHeight() .. ", " .. top .. ", " .. bottom); + + if (GetScreenWidth() < left + 20 or GetScreenHeight() < top + 20 or right < 20 or bottom < 20) then + SmartBuffOptionsFrame:SetPoint("TOPLEFT", UIParent, "CENTER", -SmartBuffOptionsFrame:GetWidth() / 2, SmartBuffOptionsFrame:GetHeight() / 2); + end + + SmartBuff_ShowControls("SmartBuffOptionsFrame", true); + + SmartBuffOptionsFrame_cbSB:SetChecked(O.Toggle); + SmartBuffOptionsFrame_cbAuto:SetChecked(O.ToggleAuto); + SmartBuffOptionsFrameAutoTimer:SetValue(O.AutoTimer); + SmartBuff_SetSliderText(SmartBuffOptionsFrameAutoTimer, SMARTBUFF_OFT_AUTOTIMER, O.AutoTimer, INT_SPELL_DURATION_SEC); + SmartBuffOptionsFrame_cbAutoCombat:SetChecked(O.ToggleAutoCombat); + SmartBuffOptionsFrame_cbAutoChat:SetChecked(O.ToggleAutoChat); + SmartBuffOptionsFrame_cbAutoSplash:SetChecked(O.ToggleAutoSplash); + SmartBuffOptionsFrame_cbAutoSound:SetChecked(O.ToggleAutoSound); + + --SmartBuffOptionsFrame_cbCheckCharges:SetChecked(O.ToggleCheckCharges); + --SmartBuffOptionsFrame_cbAutoRest:SetChecked(O.ToggleAutoRest); + SmartBuffOptionsFrame_cbAutoSwitchTmp:SetChecked(O.AutoSwitchTemplate); + SmartBuffOptionsFrame_cbAutoSwitchTmpInst:SetChecked(O.AutoSwitchTemplateInst); + SmartBuffOptionsFrame_cbBuffPvP:SetChecked(O.BuffPvP); + SmartBuffOptionsFrame_cbBuffTarget:SetChecked(O.BuffTarget); + SmartBuffOptionsFrame_cbBuffInCities:SetChecked(O.BuffInCities); + SmartBuffOptionsFrame_cbInShapeshift:SetChecked(O.InShapeshift); + SmartBuffOptionsFrame_cbFixBuffIssue:SetChecked(O.SBButtonFix); + + SmartBuffOptionsFrame_cbAntiDaze:SetChecked(O.AntiDaze); + SmartBuffOptionsFrame_cbLinkGrpBuffCheck:SetChecked(O.LinkGrpBuffCheck); + SmartBuffOptionsFrame_cbLinkSelfBuffCheck:SetChecked(O.LinkSelfBuffCheck); + + SmartBuffOptionsFrame_cbScrollWheelUp:SetChecked(O.ScrollWheelUp); + SmartBuffOptionsFrame_cbScrollWheelDown:SetChecked(O.ScrollWheelDown); + SmartBuffOptionsFrame_cbInCombat:SetChecked(O.InCombat); + SmartBuffOptionsFrame_cbIncludeToys:SetChecked(O.IncludeToys); + SmartBuffOptionsFrame_cbMsgNormal:SetChecked(O.ToggleMsgNormal); + SmartBuffOptionsFrame_cbMsgWarning:SetChecked(O.ToggleMsgWarning); + SmartBuffOptionsFrame_cbMsgError:SetChecked(O.ToggleMsgError); + SmartBuffOptionsFrame_cbHideMmButton:SetChecked(O.HideMmButton); + SmartBuffOptionsFrame_cbHideSAButton:SetChecked(O.HideSAButton); + + SmartBuffOptionsFrameRebuffTimer:SetValue(O.RebuffTimer); + SmartBuff_SetSliderText(SmartBuffOptionsFrameRebuffTimer, SMARTBUFF_OFT_REBUFFTIMER, O.RebuffTimer, INT_SPELL_DURATION_SEC); + SmartBuffOptionsFrameBLDuration:SetValue(O.BlacklistTimer); + SmartBuff_SetSliderText(SmartBuffOptionsFrameBLDuration, SMARTBUFF_OFT_BLDURATION, O.BlacklistTimer, INT_SPELL_DURATION_SEC); + + SMARTBUFF_SetCheckButtonBuffs(0); + + SmartBuffOptionsFrame_cbSelfFirst:SetChecked(B[CS()][currentTemplate].SelfFirst); + + SMARTBUFF_Splash_Show(); + + SMARTBUFF_AddMsgD("Option frame updated: " .. currentTemplate); +end + +function SMARTBUFF_ShowSubGroups(frame, grpTable) + local i; + for i = 1, 8, 1 do + obj = _G[frame.."_cbGrp"..i]; + if (obj) then + obj:SetChecked(grpTable[i]); + end + end +end + +function SMARTBUFF_Options_OnHide() + if (SmartBuffWNF:IsVisible()) then + SmartBuffWNF:Hide(); + end + SMARTBUFF_ToggleTutorial(true); + SmartBuffOptionsFrame:SetHeight(SMARTBUFF_OPTIONSFRAME_HEIGHT); + --SmartBuff_BuffSetup:SetHeight(SMARTBUFF_OPTIONSFRAME_HEIGHT); + wipe(cBuffsCombat); + SMARTBUFF_SetInCombatBuffs(); + SmartBuff_BuffSetup:Hide(); + SmartBuff_PlayerSetup:Hide(); + SMARTBUFF_SetUnits(); + SMARTBUFF_Splash_Hide(); + SMARTBUFF_RebindKeys(); + --collectgarbage(); +end + +function SmartBuff_ShowControls(sName, bShow) + local children = {_G[sName]:GetChildren()}; + for i, child in pairs(children) do + --SMARTBUFF_AddMsgD(i .. ": " .. child:GetName()); + if (i > 1 and string.find(child:GetName(), "^"..sName..".+")) then + if (bShow) then + child:Show(); + else + child:Hide(); + end + end + end +end + +function SmartBuffOptionsFrameSlider_OnLoad(self, low, high, step, labels) + _G[self:GetName().."Text"]:SetFontObject(GameFontNormalSmall); + if (labels) then + if (self:GetOrientation() ~= "VERTICAL") then + _G[self:GetName().."Low"]:SetText(low); + else + _G[self:GetName().."Low"]:SetText(""); + end + _G[self:GetName().."High"]:SetText(high); + else + _G[self:GetName().."Low"]:SetText(""); + _G[self:GetName().."High"]:SetText(""); + end + self:SetMinMaxValues(low, high); + self:SetValueStep(step); + self:SetStepsPerPage(step); + + if (step < 1) then return; end + + self.GetValueBase = self.GetValue; + self.GetValue = function() + local n = self:GetValueBase(); + if (n) then + local r = Round(n); + if (r ~= n) then + self:SetValue(n); + end + return r; + end + return low; + end; +end + +function SmartBuff_SetSliderText(self, text, value, valformat, setval) + if (not self or not value) then return end + local s; + if (setval) then self:SetValue(value) end + if (valformat) then + s = string.format(valformat, value); + else + s = tostring(value); + end + getglobal(self:GetName().."Text"):SetText(text.." "..WH..s.."|r"); +end + +function SmartBuff_BuffSetup_RBTime_OnValueChanged(self) + _G[SmartBuff_BuffSetup_RBTime:GetName().."Text"]:SetText(WH..format("%.0f", self:GetValue()).."\nsec|r"); +end + +function SMARTBUFF_SetCheckButtonBuffs(mode) + local objS; + local objG; + local i = 1; + local ct = currentTemplate; + + if (mode == 0) then + SMARTBUFF_SetBuffs(); + end + + SmartBuffOptionsFrame_cbAntiDaze:Hide(); + + if (sPlayerClass == "HUNTER" or sPlayerClass == "ROGUE" or sPlayerClass == "WARRIOR") then + SmartBuffOptionsFrameBLDuration:Hide(); + if (sPlayerClass == "HUNTER") then + SmartBuffOptionsFrame_cbLinkGrpBuffCheck:Hide(); + SmartBuffOptionsFrame_cbAntiDaze:Show(); + end + end + + if (sPlayerClass == "DRUID" or sPlayerClass == "SHAMAN") then + SmartBuffOptionsFrame_cbInShapeshift:Show(); + else + SmartBuffOptionsFrame_cbInShapeshift:Hide(); + end + + SMARTBUFF_BuffOrderOnScroll(); +end + + +function SMARTBUFF_DropDownTemplate_OnShow(self) + local i = 0; + for _, tmp in pairs(SMARTBUFF_TEMPLATES) do + i = i + 1; + --SMARTBUFF_AddMsgD(i .. "." .. tmp); + if (tmp == currentTemplate) then + break; + end + end + UIDropDownMenu_Initialize(self, SMARTBUFF_DropDownTemplate_Initialize); + UIDropDownMenu_SetSelectedValue(SmartBuffOptionsFrame_ddTemplates, i); + UIDropDownMenu_SetWidth(SmartBuffOptionsFrame_ddTemplates, 135); +end + +function SMARTBUFF_DropDownTemplate_Initialize() + local info = UIDropDownMenu_CreateInfo(); + info.text = ALL; + info.value = -1; + info.func = SMARTBUFF_DropDownTemplate_OnClick; + for k, v in pairs(SMARTBUFF_TEMPLATES) do + info.text = SMARTBUFF_TEMPLATES[k]; + info.value = k; + info.func = SMARTBUFF_DropDownTemplate_OnClick; + info.checked = nil; + UIDropDownMenu_AddButton(info); + end +end + +function SMARTBUFF_DropDownTemplate_OnClick(self) + local i = self.value; + local tmp = nil; + UIDropDownMenu_SetSelectedValue(SmartBuffOptionsFrame_ddTemplates, i); + tmp = SMARTBUFF_TEMPLATES[i]; + --SMARTBUFF_AddMsgD("Selected/Current Buff-Template: " .. tmp .. "/" .. currentTemplate); + if (currentTemplate ~= tmp) then + SmartBuff_BuffSetup:Hide(); + iLastBuffSetup = -1; + SmartBuff_PlayerSetup:Hide(); + + currentTemplate = tmp; + SMARTBUFF_Options_OnShow(); + O.LastTemplate = currentTemplate; + end +end +-- END Options frame functions + + +-- Splash screen functions --------------------------------------------------------------------------------------- +function SMARTBUFF_Splash_Show() + if (not isInit) then return; end + SMARTBUFF_Splash_ChangeFont(1); + SmartBuffSplashFrame:EnableMouse(true); + SmartBuffSplashFrame:Show(); + SmartBuffSplashFrame:SetTimeVisible(60); + SmartBuffSplashFrameOptions:Show(); +end + +function SMARTBUFF_Splash_Hide() + if (not isInit) then return; end + SMARTBUFF_Splash_Clear(); + SMARTBUFF_Splash_ChangePos(); + SmartBuffSplashFrame:EnableMouse(false); + SmartBuffSplashFrame:SetFadeDuration(O.SplashDuration); + SmartBuffSplashFrame:SetTimeVisible(O.SplashDuration); + SmartBuffSplashFrameOptions:Hide(); +end + +function SMARTBUFF_Splash_Clear() + SmartBuffSplashFrame:Clear(); +end + +function SMARTBUFF_Splash_ChangePos() + local x, y = SmartBuffSplashFrame:GetLeft(), SmartBuffSplashFrame:GetTop() - UIParent:GetHeight(); + if (O) then + O.SplashX = x; + O.SplashY = y; + end +end + +function SMARTBUFF_Splash_ChangeFont(mode) + local f = SmartBuffSplashFrame; + + if (mode > 1) then + SMARTBUFF_Splash_ChangePos(); + iCurrentFont = iCurrentFont + 1; + end + if (not cFonts[iCurrentFont]) then + iCurrentFont = 1; + end + O.CurrentFont = iCurrentFont; + f:ClearAllPoints(); + f:SetPoint("TOPLEFT", O.SplashX, O.SplashY); + + local fo = f:GetFontObject(); + local fName, fHeight, fFlags = _G[cFonts[iCurrentFont]]:GetFont(); + if (mode > 1 or O.CurrentFontSize == nil) then + O.CurrentFontSize = fHeight; + end + fo:SetFont(fName, O.CurrentFontSize, fFlags); + SmartBuffSplashFrameOptions.size:SetValue(O.CurrentFontSize); + + f:SetInsertMode("TOP"); + f:SetJustifyV("MIDDLE"); + if (mode > 0) then + local si = ""; + if (OG.SplashIcon) then + local n = O.SplashIconSize; + if (n == nil or n <= 0) then + n = O.CurrentFontSize; + end + si = string.format(" \124T%s:%d:%d:1:0\124t", "Interface\\Icons\\INV_Misc_QuestionMark", n, n) or ""; + else + si = " BuffXYZ"; + end + SMARTBUFF_Splash_Clear(); + if (OG.SplashMsgShort) then + f:AddMessage(cFonts[iCurrentFont].." >"..si.."\ndrag'n'drop to move", O.ColSplashFont.r, O.ColSplashFont.g, O.ColSplashFont.b, 1.0); + else + f:AddMessage(cFonts[iCurrentFont].." "..SMARTBUFF_MSG_NEEDS..si.."\ndrag'n'drop to move", O.ColSplashFont.r, O.ColSplashFont.g, O.ColSplashFont.b, 1.0); + end + end +end +-- END Splash screen events + + +-- Playerlist functions --------------------------------------------------------------------------------------- +function SmartBuff_PlayerSetup_OnShow() +end + +function SmartBuff_PlayerSetup_OnHide() +end + +function SmartBuff_PS_GetList() + if (iLastBuffSetup <= 0) then return { } end + + local name = cBuffs[iLastBuffSetup].BuffS; + if (name) then + if (iCurrentList == 1) then + return B[CS()][currentTemplate][name].AddList; + else + return B[CS()][currentTemplate][name].IgnoreList; + end + end +end + +function SmartBuff_PS_GetUnitList() + if (iCurrentList == 1) then + return cAddUnitList; + else + return cIgnoreUnitList; + end +end + +function SmartBuff_UnitIsAdd(unit) + if (unit and cAddUnitList[unit]) then return true end + return false; +end + +function SmartBuff_UnitIsIgnored(unit) + if (unit and cIgnoreUnitList[unit]) then return true end + return false; +end + +function SmartBuff_PS_Show(i) + iCurrentList = i; + iLastPlayer = -1; + local obj = SmartBuff_PlayerSetup_Title; + if (iCurrentList == 1) then + obj:SetText("Additional list"); + else + obj:SetText("Ignore list"); + end + obj:ClearFocus(); + SmartBuff_PlayerSetup_EditBox:ClearFocus(); + SmartBuff_PlayerSetup:Show(); + SmartBuff_PS_SelectPlayer(0); +end + +function SmartBuff_PS_AddPlayer() + local cList = SmartBuff_PS_GetList(); + local un = UnitName("target"); + if (un and UnitIsPlayer("target") and (UnitInRaid("target") or UnitInParty("target") or O.Debug)) then + if (not cList[un]) then + cList[un] = true; + SmartBuff_PS_SelectPlayer(0); + end + end +end + +function SmartBuff_PS_RemovePlayer() + local n = 0; + local cList = SmartBuff_PS_GetList(); + for player in pairs(cList) do + n = n + 1; + if (n == iLastPlayer) then + cList[player] = nil; + break; + end + end + SmartBuff_PS_SelectPlayer(0); +end + +function SmartBuff_AddToUnitList(idx, unit, subgroup) + iCurrentList = idx; + local cList = SmartBuff_PS_GetList(); + local cUnitList = SmartBuff_PS_GetUnitList(); + if (unit and subgroup) then + local un = UnitName(unit); + if (un and cList[un]) then + cUnitList[unit] = subgroup; + --SMARTBUFF_AddMsgD("Added to UnitList:" .. un .. "(" .. unit .. ")"); + end + end +end + +function SmartBuff_PS_SelectPlayer(iOp) + local idx = iLastPlayer + iOp; + local cList = SmartBuff_PS_GetList(); + local s = ""; + + local tn = 0; + for player in pairs(cList) do + tn = tn + 1; + s = s .. player .. "\n"; + end + + -- update list in textbox + if (iOp == 0) then + SmartBuff_PlayerSetup_EditBox:SetText(s); + --SmartBuff_PlayerSetup_EditBox:ClearFocus(); + end + + -- highlight selected player + if (tn > 0) then + if (idx > tn) then idx = tn; end + if (idx < 1) then idx = 1; end + iLastPlayer = idx; + --SmartBuff_PlayerSetup_EditBox:ClearFocus(); + local n = 0; + local i = 0; + local w = 0; + for player in pairs(cList) do + n = n + 1; + w = string.len(player); + if (n == idx) then + SmartBuff_PlayerSetup_EditBox:HighlightText(i + n - 1, i + n + w); + break; + end + i = i + w; + end + end +end + +function SmartBuff_PS_Resize() + local h = SmartBuffOptionsFrame:GetHeight(); + local b = true; + + if (h < 200) then + SmartBuffOptionsFrame:SetHeight(SMARTBUFF_OPTIONSFRAME_HEIGHT); + --SmartBuff_BuffSetup:SetHeight(SMARTBUFF_OPTIONSFRAME_HEIGHT); + b = true; + else + SmartBuffOptionsFrame:SetHeight(40); + --SmartBuff_BuffSetup:SetHeight(40); + b = false; + end + SmartBuff_ShowControls("SmartBuffOptionsFrame", b); + if (b) then + SMARTBUFF_SetCheckButtonBuffs(1); + end +end +-- END Playerlist functions + + +-- Secure button functions, NEW TBC --------------------------------------------------------------------------------------- + +function SMARTBUFF_ShowSAButton() + if (not InCombatLockdown()) then + if (O.HideSAButton) then + SmartBuff_KeyButton:Hide(); + else + SmartBuff_KeyButton:Show(); + end + end +end + +local sScript; +function SMARTBUFF_OnClick(obj) + SMARTBUFF_AddMsgD("OnClick"); +end + + +local lastBuffType = ""; +function SMARTBUFF_OnPreClick(self, button, down) + if (not isInit) then return end + local mode = 0; + if (button) then + if (button == "MOUSEWHEELUP" or button == "MOUSEWHEELDOWN") then + mode = 5; + end + end + + if (not InCombatLockdown()) then + + self:SetAttribute("type", nil); + self:SetAttribute("unit", nil); + self:SetAttribute("spell", nil); + self:SetAttribute("item", nil); + self:SetAttribute("macrotext", nil); + self:SetAttribute("target-slot", nil); + self:SetAttribute("target-item", nil); + self:SetAttribute("action", nil); + + end + + --sScript = self:GetScript("OnClick"); + --self:SetScript("OnClick", SMARTBUFF_OnClick); + + local td; + if (lastBuffType == "") then + td = 0.8; + else + td = GlobalCd; + end + --SMARTBUFF_AddMsgD("Last buff type: " .. lastBuffType .. ", set cd: " .. td); + + if (UnitCastingInfo("player")) then + --print("Channeling...reset AutoBuff timer"); + tAutoBuff = GetTime() + 0.7; + return; + end + + if (GetTime() < (tAutoBuff + td)) then return end + + --SMARTBUFF_AddMsgD("next buff check"); + tAutoBuff = GetTime(); + lastBuffType = ""; + currentUnit = nil; + currentSpell = nil; + + if (not InCombatLockdown()) then + local ret, actionType, spellName, slot, unit, buffType = SMARTBUFF_Check(mode); + if (ret and ret == 0 and actionType and spellName and unit) then + lastBuffType = buffType; + self:SetAttribute("type", actionType); + self:SetAttribute("unit", unit); + if (actionType == SMARTBUFF_ACTION_SPELL) then + if (slot and slot > 0 and unit == "player") then + self:SetAttribute("type", "macro"); + self:SetAttribute("macrotext", string.format("/use %s\n/use %i\n/click StaticPopup1Button1", spellName, slot)); + --self:SetAttribute("target-item", slot); + SMARTBUFF_AddMsgD("Weapon buff "..spellName..", "..slot); + else + self:SetAttribute("spell", spellName); + end + + if (cBuffIndex[spellName]) then + currentUnit = unit; + currentSpell = spellName; + end + + elseif (actionType == SMARTBUFF_ACTION_ITEM and slot) then + self:SetAttribute("item", spellName); + if (slot > 0) then + self:SetAttribute("type", "macro"); + self:SetAttribute("macrotext", string.format("/use %s\n/use %i\n/click StaticPopup1Button1", spellName, slot)); + end + elseif (actionType == "action" and slot) then + self:SetAttribute("action", slot); + else + SMARTBUFF_AddMsgD("Preclick: not supported actiontype -> " .. actionType); + end + + --isClearSplash = true; + tLastCheck = GetTime() - O.AutoTimer + GlobalCd; + end + end +end + +function SMARTBUFF_OnPostClick(self, button, down) + if (not isInit) then return end + if (button) then + if (button == "MOUSEWHEELUP") then + CameraZoomIn(1); + elseif (button == "MOUSEWHEELDOWN") then + CameraZoomOut(1); + end + end + + if (InCombatLockdown()) then return end + + self:SetAttribute("type", nil); + self:SetAttribute("unit", nil); + self:SetAttribute("spell", nil); + self:SetAttribute("item", nil); + self:SetAttribute("target-slot", nil); + self:SetAttribute("target-item", nil); + self:SetAttribute("macrotext", nil); + self:SetAttribute("action", nil); + + SMARTBUFF_SetButtonTexture(SmartBuff_KeyButton, imgSB); + + --SMARTBUFF_AddMsgD("Button reseted, " .. button); + --self:SetScript("OnClick", sScript); +end + +function SMARTBUFF_SetButtonTexture(button, texture, text) + --if (InCombatLockdown()) then return; end + + if (button and texture and texture ~= sLastTexture) then + sLastTexture = texture; + button:SetNormalTexture(texture); + --SMARTBUFF_AddMsgD("Button slot texture set -> " .. texture); + if (text) then + --button.title:SetText(spell); + end + end +end +-- END secure button functions + + +-- Minimap button functions --------------------------------------------------------------------------------------- +-- Sets the correct icon on the minimap button +function SMARTBUFF_CheckMiniMapButton() + if (O.Toggle) then + SmartBuff_MiniMapButton:SetNormalTexture(imgIconOn); + else + SmartBuff_MiniMapButton:SetNormalTexture(imgIconOff); + end + + if (O.HideMmButton) then + SmartBuff_MiniMapButton:Hide(); + else + SmartBuff_MiniMapButton:Show(); + end + + -- Update the Titan Panel icon + if (TitanPanelBarButton and TitanPanelSmartBuffButton_SetIcon ~= nil) then + TitanPanelSmartBuffButton_SetIcon(); + end + + -- Update the FuBar icon + if (IsAddOnLoaded("FuBar") and IsAddOnLoaded("FuBar_SmartBuffFu") and SMARTBUFF_Fu_SetIcon ~= nil) then + SMARTBUFF_Fu_SetIcon(); + end + + -- Update the Broker icon + if (IsAddOnLoaded("Broker_SmartBuff") and SMARTBUFF_BROKER_SetIcon ~= nil) then + SMARTBUFF_BROKER_SetIcon(); + end + +end + +function SMARTBUFF_MinimapButton_CheckPos() + if (not isInit or not SmartBuff_MiniMapButton) then return; end + local x = SmartBuff_MiniMapButton:GetLeft(); + local y = SmartBuff_MiniMapButton:GetTop(); + if (x == nil or y == nil) then return; end + x = x - Minimap:GetLeft(); + y = y - Minimap:GetTop(); + if (math.abs(x) < 180 and math.abs(y) < 180) then + O.MMCPosX = x; + O.MMCPosY = y; + --SMARTBUFF_AddMsgD("x = " .. O.MMCPosX .. ", y = " .. O.MMCPosY); + end +end + +-- Function to move the minimap button arround the minimap +function SMARTBUFF_MinimapButton_OnUpdate(self, move) + if (not isInit or self == nil or not self:IsVisible()) then + return; + end + + local xpos, ypos; +self:ClearAllPoints() + if (move or O.MMCPosX == nil) then + local pos, r + local xmin, ymin = Minimap:GetLeft(), Minimap:GetBottom(); + xpos, ypos = GetCursorPosition(); + xpos = xmin-xpos/Minimap:GetEffectiveScale()+70; + ypos = ypos/Minimap:GetEffectiveScale()-ymin-70; + pos = math.deg(math.atan2(ypos,xpos)); + r = math.sqrt(xpos*xpos + ypos*ypos); + --SMARTBUFF_AddMsgD("x = " .. xpos .. ", y = " .. ypos .. ", r = " .. r .. ", pos = " .. pos); + + if (r < 75) then + r = 75; + elseif(r > 105) then + r = 105; + end + + xpos = 52-r*cos(pos); + ypos = r*sin(pos)-52; + O.MMCPosX = xpos; + O.MMCPosY = ypos; + --SMARTBUFF_AddMsgD("Update minimap button position"); + else + xpos = O.MMCPosX; + ypos = O.MMCPosY; + --SMARTBUFF_AddMsgD("Load minimap button position"); + end +self:ClearAllPoints() + self:SetPoint("TOPLEFT", "Minimap", "TOPLEFT", xpos, ypos); + --SMARTBUFF_AddMsgD("x = " .. O.MMCPosX .. ", y = " .. O.MMCPosY); + --SmartBuff_MiniMapButton:SetUserPlaced(true); + --SMARTBUFF_AddMsgD("Update minimap button"); +end +-- END Minimap button functions + + + +-- Scroll frame functions --------------------------------------------------------------------------------------- + +local ScrBtnSize = 20; +local ScrLineHeight = 18; +local function SetPosScrollButtons(parent, cBtn) + local btn; + local name; + for i = 1, #cBtn, 1 do + btn = cBtn[i]; + btn:ClearAllPoints(); + btn:SetPoint("TOPLEFT", parent, "TOPLEFT", 2, -2 - ScrLineHeight*(i-1)); + end +end + +local StartY, EndY; +local function CreateScrollButton(name, parent, cBtn, onClick, onDragStop) + local btn = CreateFrame("CheckButton", name, parent, "UICheckButtonTemplate"); + btn:SetWidth(ScrBtnSize); + btn:SetHeight(ScrBtnSize); + --btn:RegisterForClicks("LeftButtonUp"); + btn:SetScript("OnClick", onClick); +-- btn:SetScript("OnMouseUp", onClick); + + if (onDragStop ~= nil) then + btn:SetMovable(true); + btn:RegisterForDrag("LeftButton"); + btn:SetScript("OnDragStart", function(self, b) + StartY = self:GetTop(); + self:StartMoving(); + end + ); + btn:SetScript("OnDragStop", function(self, b) + EndY = self:GetTop(); + local i = tonumber(self:GetID()) + FauxScrollFrame_GetOffset(parent); + local n = math.floor((StartY-EndY) / ScrLineHeight); + self:StopMovingOrSizing(); + SetPosScrollButtons(parent, cBtn); + onDragStop(i, n); + end + ); + end + + local text = btn:CreateFontString(nil, nil, "GameFontNormal"); + text:SetJustifyH("LEFT"); + --text:SetAllPoints(btn); + text:SetPoint("TOPLEFT", btn, "TOPLEFT", ScrBtnSize, 0); + text:SetWidth(parent:GetWidth()-ScrBtnSize); + text:SetHeight(ScrBtnSize); + btn:SetFontString(text); + btn:SetHighlightFontObject("GameFontHighlight"); + + local highlight = btn:CreateTexture(); + --highlight:SetAllPoints(btn); + highlight:SetPoint("TOPLEFT", btn, "TOPLEFT", 0, -2); + highlight:SetWidth(parent:GetWidth()); + highlight:SetHeight(ScrLineHeight-3); + + highlight:SetTexture("Interface/QuestFrame/UI-QuestTitleHighlight"); + btn:SetHighlightTexture(highlight); + + return btn; +end + + +local function CreateScrollButtons(self, cBtn, sBtnName, onClick, onDragStop) + local btn, i; + for i = 1, maxScrollButtons, 1 do + btn = CreateScrollButton(sBtnName..i, self, cBtn, onClick, onDragStop); + btn:SetID(i); + cBtn[i] = btn; + end + SetPosScrollButtons(self, cBtn); +end + + +local function OnScroll(self, cData, sBtnName) + local num = #cData; + local n, numToDisplay; + + if (num <= maxScrollButtons) then + numToDisplay = num-1; + else + numToDisplay = maxScrollButtons; + end + + FauxScrollFrame_Update(self, num, floor(numToDisplay/3+0.5), ScrLineHeight); + local t = B[CS()][CT()]; + for i = 1, maxScrollButtons, 1 do + n = i + FauxScrollFrame_GetOffset(self); + btn = _G[sBtnName..i]; + if (btn) then + if (n <= num) then + btn:SetNormalFontObject("GameFontNormalSmall"); + btn:SetHighlightFontObject("GameFontHighlightSmall"); + btn:SetText(cData[n]); + btn:SetChecked(t[cData[n]].EnableS); + btn:Show(); + else + btn:Hide(); + end + end + end +end + + +function SMARTBUFF_BuffOrderOnScroll(self, arg1) + if (not self) then + self = SmartBuffOptionsFrame_ScrollFrameBuffs; + end + + local name = "SMARTBUFF_BtnScrollBO"; + if (not cScrBtnBO and self) then + cScrBtnBO = { }; + CreateScrollButtons(self, cScrBtnBO, name, SMARTBUFF_BuffOrderBtnOnClick, SMARTBUFF_BuffOrderBtnOnDragStop); + end + + if (B[CS()].Order == nil) then + B[CS()].Order = { }; + end + + local t = { }; + for _, v in pairs(B[CS()].Order) do + if (v) then + tinsert(t, v); + end + end + OnScroll(self, t, name); +end + +function SMARTBUFF_BuffOrderBtnOnClick(self, button) + local n = self:GetID() + FauxScrollFrame_GetOffset(self:GetParent()); + local i = cBuffIndex[B[CS()].Order[n]]; + --SMARTBUFF_AddMsgD("Buff OnClick = "..n..", "..button); + if (button == "LeftButton") then + SMARTBUFF_OToggleBuff("S", i); + else + SmartBuff_BuffSetup_Show(i); + end +end + +function SMARTBUFF_BuffOrderBtnOnDragStop(i, n) + treorder(B[CS()].Order, i, n); + SMARTBUFF_BuffOrderOnScroll(); +end + +function SMARTBUFF_BuffOrderReset() + InitBuffOrder(true); + SMARTBUFF_BuffOrderOnScroll(); +end + + +-- Help plate functions --------------------------------------------------------------------------------------- + +local HelpPlateList = { + FramePos = { x = 20, y = -20 }, + FrameSize = { width = 480, height = 500 }, + [1] = { ButtonPos = { x = 344, y = -80 }, HighLightBox = { x = 260, y = -50, width = 204, height = 410 }, ToolTipDir = "DOWN", ToolTipText = "Spell list\nDrag'n'Drop to change the priority order" }, + [2] = { ButtonPos = { x = 105, y = -110 }, HighLightBox = { x = 10, y = -30, width = 230, height = 125 }, ToolTipDir = "DOWN", ToolTipText = "Buff reminder options" }, + [3] = { ButtonPos = { x = 105, y = -250 }, HighLightBox = { x = 10, y = -165, width = 230, height = 135 }, ToolTipDir = "DOWN", ToolTipText = "Character based options" }, + [4] = { ButtonPos = { x = 200, y = -320 }, HighLightBox = { x = 10, y = -300, width = 230, height = 90 }, ToolTipDir = "RIGHT", ToolTipText = "Additional UI options" }, +} + +function SMARTBUFF_ToggleTutorial(close) + local helpPlate = HelpPlateList; + if (not helpPlate) then return end; + + local b = HelpPlate_IsShowing(helpPlate); + if (close) then + HelpPlate_Hide(false); + return; + end + + if (not b) then + HelpPlate_Show(helpPlate, SmartBuffOptionsFrame, SmartBuffOptionsFrame_TutorialButton, true); + else + HelpPlate_Hide(true); + end +end diff --git a/SmartBuff.toc b/SmartBuff.toc new file mode 100644 index 0000000..48d6ccc --- /dev/null +++ b/SmartBuff.toc @@ -0,0 +1,17 @@ +## Interface: 100002 +## Title: SmartBuff |cffffffff(Retail)|r by |cff00ff00Codermik & Aeldra|r +## Version: 15.100002 +## Author: |cff20d2ffCodermik & Aeldra|r (EU-Proudmoore) +## Notes: Cast the most important buffs on you or party/raid members/pets. Use /sbm for options menu. +## DefaultState: Enabled +## LoadOnDemand: 0 +## SavedVariables: SMARTBUFF_OptionsGlobal +## SavedVariablesPerCharacter: SMARTBUFF_Options, SMARTBUFF_Buffs + +Libs\LibStub\LibStub.lua +Libs\CallbackHandler-1.0\CallbackHandler-1.0.lua +SmartBuff.globals.lua +SmartBuff.xml + +Libs\Broker_SmartBuff\LibDataBroker-1.1.lua +Libs\Broker_SmartBuff\Broker_SmartBuff.lua diff --git a/SmartBuff.xml b/SmartBuff.xml new file mode 100644 index 0000000..322e23d --- /dev/null +++ b/SmartBuff.xml @@ -0,0 +1,3166 @@ + +