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 0000000..6a337ff Binary files /dev/null and b/Icons/Deathknight.tga differ diff --git a/Icons/DeathknightPet.tga b/Icons/DeathknightPet.tga new file mode 100644 index 0000000..d9512e0 Binary files /dev/null and b/Icons/DeathknightPet.tga differ diff --git a/Icons/Demonhunter.tga b/Icons/Demonhunter.tga new file mode 100644 index 0000000..9470d01 Binary files /dev/null and b/Icons/Demonhunter.tga differ diff --git a/Icons/Druid.tga b/Icons/Druid.tga new file mode 100644 index 0000000..c95ff25 Binary files /dev/null and b/Icons/Druid.tga differ diff --git a/Icons/Envoker.tga b/Icons/Envoker.tga new file mode 100644 index 0000000..6d31d3a Binary files /dev/null and b/Icons/Envoker.tga differ diff --git a/Icons/Hunter.tga b/Icons/Hunter.tga new file mode 100644 index 0000000..537eedb Binary files /dev/null and b/Icons/Hunter.tga differ diff --git a/Icons/HunterPet.tga b/Icons/HunterPet.tga new file mode 100644 index 0000000..4264c6e Binary files /dev/null and b/Icons/HunterPet.tga differ diff --git a/Icons/IconDisabled.tga b/Icons/IconDisabled.tga new file mode 100644 index 0000000..978e877 Binary files /dev/null and b/Icons/IconDisabled.tga differ diff --git a/Icons/IconEnabled.tga b/Icons/IconEnabled.tga new file mode 100644 index 0000000..7098842 Binary files /dev/null and b/Icons/IconEnabled.tga differ diff --git a/Icons/Mage.tga b/Icons/Mage.tga new file mode 100644 index 0000000..847858b Binary files /dev/null and b/Icons/Mage.tga differ diff --git a/Icons/MiniMapButtonDisabled.tga b/Icons/MiniMapButtonDisabled.tga new file mode 100644 index 0000000..67ccf66 Binary files /dev/null and b/Icons/MiniMapButtonDisabled.tga differ diff --git a/Icons/MiniMapButtonEnabled.tga b/Icons/MiniMapButtonEnabled.tga new file mode 100644 index 0000000..8ca07c4 Binary files /dev/null and b/Icons/MiniMapButtonEnabled.tga differ diff --git a/Icons/Monk.tga b/Icons/Monk.tga new file mode 100644 index 0000000..a67ae1a Binary files /dev/null and b/Icons/Monk.tga differ diff --git a/Icons/Paladin.tga b/Icons/Paladin.tga new file mode 100644 index 0000000..5f71bb8 Binary files /dev/null and b/Icons/Paladin.tga differ diff --git a/Icons/Priest.tga b/Icons/Priest.tga new file mode 100644 index 0000000..d9b3d86 Binary files /dev/null and b/Icons/Priest.tga differ diff --git a/Icons/Rogue.tga b/Icons/Rogue.tga new file mode 100644 index 0000000..6338be6 Binary files /dev/null and b/Icons/Rogue.tga differ diff --git a/Icons/Shaman.tga b/Icons/Shaman.tga new file mode 100644 index 0000000..6aac4d4 Binary files /dev/null and b/Icons/Shaman.tga differ diff --git a/Icons/Warlock.tga b/Icons/Warlock.tga new file mode 100644 index 0000000..f187dcc Binary files /dev/null and b/Icons/Warlock.tga differ diff --git a/Icons/WarlockPet.tga b/Icons/WarlockPet.tga new file mode 100644 index 0000000..bebaaed Binary files /dev/null and b/Icons/WarlockPet.tga differ diff --git a/Icons/Warrior.tga b/Icons/Warrior.tga new file mode 100644 index 0000000..daef21a Binary files /dev/null and b/Icons/Warrior.tga differ diff --git a/Icons/empty.tga b/Icons/empty.tga new file mode 100644 index 0000000..c21e7e1 Binary files /dev/null and b/Icons/empty.tga differ 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 @@ + +