Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- Copyright (c) 2010, Hendrik "Nevcairiel" Leppkes < [email protected] >
- All rights reserved.
- ]]
- local _, HotCandy = ...
- HotCandy = LibStub("AceAddon-3.0"):NewAddon(HotCandy, "HotCandy", "AceEvent-3.0", "AceBucket-3.0", "AceConsole-3.0", "LibBars-1.0")
- -- Lua APIs
- local select, pairs, tonumber, format, rawset = select, pairs, tonumber, string.format, rawset
- local _band = bit.band
- -- WoW APIs
- local UnitGUID, UnitClass, UnitBuff = UnitGUID, UnitClass, UnitBuff
- local GetSpellInfo, GetGlyphSocketInfo, GetTalentInfo, GetCombatRatingBonus = GetSpellInfo, GetGlyphSocketInfo, GetTalentInfo, GetCombatRatingBonus
- local InCombatLockdown, IsEquippedItem = InCombatLockdown, IsEquippedItem
- local COMBATLOG_OBJECT_TYPE_PLAYER, CR_HASTE_SPELL = COMBATLOG_OBJECT_TYPE_PLAYER, CR_HASTE_SPELL
- -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
- -- List them here for Mikk's FindGlobals script
- -- GLOBALS: LibStub
- local media = LibStub("LibSharedMedia-3.0")
- media:Register("statusbar", "BantoBar", "Interface\\Addons\\HotCandy\\textures\\default")
- local itemSets = {
- ["Stormrage"] = { 16897, 16898, 16899, 16900, 16901, 16902, 16903, 16904 }, -- Druid Tier 2
- ["Nordrassil"] = { 30216, 30217, 30219, 30220, 30221 }, -- Druid Tier 5
- ["Avatar Raiment"] = { 30150, 30151, 30152, 30153, 30154 }, -- Priest Tier 5
- }
- -- Spell Table Format
- -- CLASS = {
- -- <spell> = {
- -- id = <spellid> -- one spell id to get the name from using GetSpellInfo
- -- duration = X -- base duration of the HoT/Buff
- -- stackable = nil/true -- optionally specify if the buff is stackable (like Lifebloom)
- -- }
- local spells = {
- DRUID = {
- lifebloom = {
- id = 33763,
- duration = 10,
- stackable = true,
- },
- rejuvenation = {
- id = 774,
- duration = 12,
- },
- regrowth = {
- id = 8936,
- duration = 6,
- },
- wg = { -- wild growth
- id = 48438,
- duration = 7,
- },
- },
- PRIEST = {
- renew = {
- id = 139,
- duration = 12,
- },
- pom = { -- prayer of mending
- id = 33076,
- duration = 30,
- },
- pws = { -- Power Word: Shield
- id = 17,
- duration = 15,
- },
- serenity = {
- id = 88684,
- duration = 6,
- }
- },
- PALADIN = {
- beacon = {
- id = 53563,
- duration = 60,
- },
- },
- SHAMAN = {
- riptide = {
- id = 61295,
- duration = 15,
- },
- ancestral = {
- id = 16177,
- duration = 15,
- },
- earthliving = {
- id = 51945,
- duration = 12,
- },
- },
- HUNTER = {
- mendpet = {
- id = 136,
- duration = 10,
- },
- },
- }
- local playerGUID, playerClass
- local defaults = {
- profile = {
- unlocked = false,
- growup = false,
- texture = "BantoBar",
- width = 170,
- height = 15,
- scale = 1,
- flash = 0,
- stackfirst = true,
- noname = false,
- spells = {
- -- druid spells
- lifebloom = true,
- rejuvenation = true,
- regrowth = true,
- wg = false,
- -- priest spells
- renew = true,
- pom = true,
- pws = true,
- serenity = true,
- aspire = true,
- -- paladin spells
- beacon = true,
- -- shaman spells
- riptide = true,
- ancestral = false,
- earthliving = false,
- -- hunter spells
- mendpet = true,
- },
- position = {
- point = "CENTER",
- x = 0,
- y = 0,
- scale = 1,
- },
- }
- }
- local db
- local track, nameLookup = {}, {}
- function HotCandy:OnInitialize()
- self.db = LibStub("AceDB-3.0"):New("HotCandyDB", defaults, "Default")
- db = self.db.profile
- self.db.RegisterCallback(self, "OnProfileChanged", "Refresh")
- self.db.RegisterCallback(self, "OnProfileCopied", "Refresh")
- self.db.RegisterCallback(self, "OnProfileReset", "Refresh")
- -- Setup Options
- self:CreateOptions()
- self:CreateAnchor()
- self.track, self.nameLookup = track, nameLookup
- end
- local first = true
- function HotCandy:OnEnable()
- -- First Start, get the data from GetSpellInfo
- if first then
- playerGUID = UnitGUID("player")
- playerClass = select(2, UnitClass("player"))
- if spells[playerClass] then
- for k,v in pairs(spells[playerClass]) do
- local name, _, icon = GetSpellInfo(v.id)
- v.name = name
- track[k] = { name = name, icon = icon, duration = v.duration, enabled = db.spells[k], stackable = v.stackable }
- nameLookup[name] = k
- end
- end
- first = nil
- end
- -- CLEU handler for spell detection
- self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED", "CombatLogHandler")
- -- all bonus handling events
- self:RegisterBucketEvent("UNIT_INVENTORY_CHANGED", 1, "equipChanged")
- self:RegisterEvent("PLAYER_TALENT_UPDATE", "UpdateBonus")
- self:RegisterEvent("GLYPH_ADDED", "UpdateBonus")
- self:RegisterEvent("GLYPH_REMOVED", "UpdateBonus")
- self:RegisterEvent("GLYPH_UPDATED", "UpdateBonus")
- self:RegisterEvent("PLAYER_ALIVE", "UpdateBonus")
- self:Refresh()
- -- scan the users gear for Set Bonuses
- self:UpdateBonus()
- end
- function HotCandy:Refresh()
- db = self.db.profile
- self:RefreshAnchor()
- self:RefreshOptions()
- for k,v in pairs(track) do
- v.enabled = db.spells[k]
- end
- end
- -- ---------------------------------------------------------------------------------
- -- Bonus Handling
- -- Check for set bonuses
- local function getWornSetPieces(name)
- local ct = 0
- local data = itemSets[name]
- if data then
- for i = 1,#data do
- if IsEquippedItem(data[i]) then
- ct = ct + 1
- end
- end
- end
- return ct
- end
- -- check for glyph by id
- local function hasGlyph(id)
- for i = 1,9 do
- local _, _, _, spell = GetGlyphSocketInfo(i)
- if spell and tonumber(spell) == tonumber(id) then
- return true
- end
- end
- return false
- end
- function HotCandy:UpdateBonus()
- if spells[playerClass] then
- for k,v in pairs(spells[playerClass]) do
- track[k].duration = v.duration
- track[k].spellHasteModified = nil
- track[k].baseHaste = nil
- end
- else
- return
- end
- -- Equip Bonus
- if playerClass == "DRUID" then
- if (getWornSetPieces("Stormrage") >= 8) then
- track.rejuvenation.duration = track.rejuvenation.duration + 3
- end
- if (getWornSetPieces("Nordrassil") >= 2) then
- track.regrowth.duration = track.regrowth.duration + 6
- end
- elseif playerClass == "PRIEST" then
- if (getWornSetPieces("Avatar Raiment") >= 4) then
- track.renew.duration = track.renew.duration + 3
- end
- end
- -- Talent Bonus
- -- Glyph Bonus
- if playerClass == "DRUID" then
- elseif playerClass == "PRIEST" then
- elseif playerClass == "PALADIN" then
- -- Glyph of Beacon of Light
- if hasGlyph(63218) then
- track.beacon.duration = track.beacon.duration + 30
- end
- elseif playerClass == "SHAMAN" then
- -- Glyph of Riptide
- if hasGlyph(63273) then
- track.riptide.duration = track.riptide.duration + 6
- end
- end
- end
- function HotCandy:equipChanged(units)
- if not units or not units.player or InCombatLockdown() then
- return
- end
- self:UpdateBonus()
- end
- -- ---------------------------------------------------------------------------------
- -- Spell Handling
- local function makeBarId(spell, target)
- return format("HotCandy%s@%s", spell, target)
- end
- local stackCache = setmetatable({}, {__index = function(t,k) local new = {}; rawset(t,k,new); return new end})
- -- CombatLog Event Handler
- function HotCandy:CombatLogHandler(event, timestamp, clevent, hideCaster, srcGUID, srcName, srcFlags, srcRaidFlags, dstGUID, dstName, dstFlags, dstRaidFlags, spellId, spellName, school, type, stack)
- if srcGUID ~= playerGUID then return end
- local fullDstName = dstName
- -- Strip Server Names off the name
- if _band(dstFlags, COMBATLOG_OBJECT_TYPE_PLAYER) == COMBATLOG_OBJECT_TYPE_PLAYER and dstName:find("-", 1, true) then
- dstName = dstName:match("([^-]+)")
- end
- if clevent == "SPELL_AURA_APPLIED" or clevent == "SPELL_AURA_APPLIED_DOSE" then
- local token = nameLookup[spellName]
- if token then
- -- hack for PoM stack tracking
- if token == "pom" then stack = select(4, UnitBuff(fullDstName, spellName)) end
- self:FireSpell(track[token], dstName, dstGUID, stack)
- end
- elseif clevent == "SPELL_AURA_REFRESH" then
- local token = nameLookup[spellName]
- if token then
- -- refresh doesn't tell us the current number of stacks, so we assume a refresh doesn't change the number of stacks
- stack = -1
- -- hack for PoM stack tracking
- if token == "pom" then stack = select(4, UnitBuff(fullDstName, spellName)) end
- self:FireSpell(track[token], dstName, dstGUID, stack)
- end
- elseif clevent == "SPELL_HEAL" then
- if spellName == "Regrowth" or spellName == "Nourish" or spellName == "Healing Touch" then
- stack = select(4, UnitBuff(fullDstName, "Lifebloom", nil, "PLAYER"))
- if stack~=nil then
- token = nameLookup["Lifebloom"]
- self:FireSpell(track[token], dstName, dstGUID, stack)
- end
- end
- elseif clevent == "SPELL_CAST_SUCCESS" then
- if spellName == "Lifebloom" then
- stack = select(4, UnitBuff(fullDstName, "Lifebloom", nil, "PLAYER"))
- if stack~=nil then
- self:FireSpell(track[token], dstName, dstGUID, stack)
- end
- end
- elseif clevent == "SPELL_AURA_REMOVED" then
- local token = nameLookup[spellName]
- if token then
- self:StopBar(makeBarId(spellName, dstGUID))
- if track[token].stackable then
- stackCache[spellName][dstGUID] = nil
- end
- end
- end
- end
- -- Handler for showing the Spell as a Bar
- function HotCandy:FireSpell(spell, dstName, dstGUID, stackCount)
- if not spell or not spell.enabled then return end
- -- Validate the Spell is supposed to be tracked
- if spell.duration > 0 then
- local duration = spell.duration
- local spellName = spell.name
- local stack = ""
- local id = makeBarId(spellName, dstGUID)
- if stackCount == -1 and stackCache[spellName]then
- stackCount = stackCache[spellName][dstGUID]
- end
- if stackCount and stackCount > 1 then
- stack = format("(%d)", stackCount)
- stackCache[spellName][dstGUID] = stackCount
- end
- if spell.spellHasteModified then
- local totalHaste = spell.baseHaste + GetCombatRatingBonus(CR_HASTE_SPELL)
- duration = duration / (1 + totalHaste / 100)
- end
- -- Create Text for the bar according to configured format
- local text
- if not db.noname then
- if db.stackfirst then
- text = format("%s%s - %s", stack, spellName, dstName)
- else
- text = format("%s%s - %s", spellName, stack, dstName)
- end
- else
- text = format("%s%s", stack, dstName)
- end
- -- Create the Bar
- self:StartBar(id, text, duration, spell.icon)
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement