Advertisement
Guest User

Untitled

a guest
Jul 9th, 2011
432
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.28 KB | None | 0 0
  1. --[[
  2.   Copyright (c) 2010, Hendrik "Nevcairiel" Leppkes < [email protected] >
  3.   All rights reserved.
  4. ]]
  5.  
  6. local _, HotCandy = ...
  7. HotCandy = LibStub("AceAddon-3.0"):NewAddon(HotCandy, "HotCandy", "AceEvent-3.0", "AceBucket-3.0", "AceConsole-3.0", "LibBars-1.0")
  8.  
  9. -- Lua APIs
  10. local select, pairs, tonumber, format, rawset = select, pairs, tonumber, string.format, rawset
  11. local _band = bit.band
  12.  
  13. -- WoW APIs
  14. local UnitGUID, UnitClass, UnitBuff = UnitGUID, UnitClass, UnitBuff
  15. local GetSpellInfo, GetGlyphSocketInfo, GetTalentInfo, GetCombatRatingBonus = GetSpellInfo, GetGlyphSocketInfo, GetTalentInfo, GetCombatRatingBonus
  16. local InCombatLockdown, IsEquippedItem = InCombatLockdown, IsEquippedItem
  17.  
  18. local COMBATLOG_OBJECT_TYPE_PLAYER, CR_HASTE_SPELL = COMBATLOG_OBJECT_TYPE_PLAYER, CR_HASTE_SPELL
  19.  
  20. -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
  21. -- List them here for Mikk's FindGlobals script
  22. -- GLOBALS: LibStub
  23.  
  24. local media = LibStub("LibSharedMedia-3.0")
  25. media:Register("statusbar", "BantoBar", "Interface\\Addons\\HotCandy\\textures\\default")
  26.  
  27. local itemSets = {
  28.     ["Stormrage"] = { 16897, 16898, 16899, 16900, 16901, 16902, 16903, 16904 }, -- Druid Tier 2
  29.     ["Nordrassil"] = { 30216, 30217, 30219, 30220, 30221 }, -- Druid Tier 5
  30.     ["Avatar Raiment"] = { 30150, 30151, 30152, 30153, 30154 }, -- Priest Tier 5
  31. }
  32.  
  33. -- Spell Table Format
  34. -- CLASS = {
  35. --   <spell> = {
  36. --     id = <spellid>        -- one spell id to get the name from using GetSpellInfo
  37. --     duration = X          -- base duration of the HoT/Buff
  38. --     stackable = nil/true  -- optionally specify if the buff is stackable (like Lifebloom)
  39. --  }
  40. local spells = {
  41.     DRUID = {
  42.         lifebloom = {
  43.             id = 33763,
  44.             duration = 10,
  45.             stackable = true,
  46.         },
  47.         rejuvenation = {
  48.             id = 774,
  49.             duration = 12,
  50.         },
  51.         regrowth = {
  52.             id = 8936,
  53.             duration = 6,
  54.         },
  55.         wg = { -- wild growth
  56.             id = 48438,
  57.             duration = 7,
  58.         },
  59.     },
  60.     PRIEST = {
  61.         renew = {
  62.             id = 139,
  63.             duration = 12,
  64.         },
  65.         pom = { -- prayer of mending
  66.             id = 33076,
  67.             duration = 30,
  68.         },
  69.         pws = { -- Power Word: Shield
  70.             id = 17,
  71.             duration = 15,
  72.         },
  73.         serenity = {
  74.             id = 88684,
  75.             duration = 6,
  76.         }
  77.     },
  78.     PALADIN = {
  79.         beacon = {
  80.             id = 53563,
  81.             duration = 60,
  82.         },
  83.     },
  84.     SHAMAN = {
  85.         riptide = {
  86.             id = 61295,
  87.             duration = 15,
  88.         },
  89.         ancestral = {
  90.             id = 16177,
  91.             duration = 15,
  92.         },
  93.         earthliving = {
  94.             id = 51945,
  95.             duration = 12,
  96.         },
  97.     },
  98.     HUNTER = {
  99.         mendpet = {
  100.             id = 136,
  101.             duration = 10,
  102.         },
  103.     },
  104. }
  105. local playerGUID, playerClass
  106.  
  107. local defaults = {
  108.     profile = {
  109.         unlocked = false,
  110.         growup = false,
  111.         texture = "BantoBar",
  112.         width = 170,
  113.         height = 15,
  114.         scale = 1,
  115.         flash = 0,
  116.         stackfirst = true,
  117.         noname = false,
  118.         spells = {
  119.             -- druid spells
  120.             lifebloom = true,
  121.             rejuvenation = true,
  122.             regrowth = true,
  123.             wg = false,
  124.             -- priest spells
  125.             renew = true,
  126.             pom = true,
  127.             pws = true,
  128.             serenity = true,
  129.             aspire = true,
  130.             -- paladin spells
  131.             beacon = true,
  132.             -- shaman spells
  133.             riptide = true,
  134.             ancestral = false,
  135.             earthliving = false,
  136.             -- hunter spells
  137.             mendpet = true,
  138.         },
  139.         position = {
  140.             point = "CENTER",
  141.             x = 0,
  142.             y = 0,
  143.             scale = 1,
  144.         },
  145.     }
  146. }
  147.  
  148. local db
  149. local track, nameLookup = {}, {}
  150.  
  151. function HotCandy:OnInitialize()
  152.     self.db = LibStub("AceDB-3.0"):New("HotCandyDB", defaults, "Default")
  153.     db = self.db.profile
  154.  
  155.     self.db.RegisterCallback(self, "OnProfileChanged", "Refresh")
  156.     self.db.RegisterCallback(self, "OnProfileCopied", "Refresh")
  157.     self.db.RegisterCallback(self, "OnProfileReset", "Refresh")
  158.  
  159.     -- Setup Options
  160.     self:CreateOptions()
  161.     self:CreateAnchor()
  162.  
  163.     self.track, self.nameLookup = track, nameLookup
  164. end
  165.  
  166. local first = true
  167. function HotCandy:OnEnable()
  168.     -- First Start, get the data from GetSpellInfo
  169.     if first then
  170.         playerGUID = UnitGUID("player")
  171.         playerClass = select(2, UnitClass("player"))
  172.  
  173.         if spells[playerClass] then
  174.             for k,v in pairs(spells[playerClass]) do
  175.                 local name, _, icon = GetSpellInfo(v.id)
  176.                 v.name = name
  177.                 track[k] = { name = name, icon = icon, duration = v.duration, enabled = db.spells[k], stackable = v.stackable }
  178.                 nameLookup[name] = k
  179.             end
  180.         end
  181.        
  182.         first = nil
  183.     end
  184.  
  185.     -- CLEU handler for spell detection
  186.     self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED", "CombatLogHandler")
  187.  
  188.     -- all bonus handling events
  189.     self:RegisterBucketEvent("UNIT_INVENTORY_CHANGED", 1, "equipChanged")
  190.     self:RegisterEvent("PLAYER_TALENT_UPDATE", "UpdateBonus")
  191.     self:RegisterEvent("GLYPH_ADDED", "UpdateBonus")
  192.     self:RegisterEvent("GLYPH_REMOVED", "UpdateBonus")
  193.     self:RegisterEvent("GLYPH_UPDATED", "UpdateBonus")
  194.     self:RegisterEvent("PLAYER_ALIVE", "UpdateBonus")
  195.  
  196.     self:Refresh()
  197.  
  198.     -- scan the users gear for Set Bonuses
  199.     self:UpdateBonus()
  200. end
  201.  
  202. function HotCandy:Refresh()
  203.     db = self.db.profile
  204.     self:RefreshAnchor()
  205.     self:RefreshOptions()
  206.    
  207.     for k,v in pairs(track) do
  208.         v.enabled = db.spells[k]
  209.     end
  210. end
  211.  
  212. -- ---------------------------------------------------------------------------------
  213. -- Bonus Handling
  214.  
  215. -- Check for set bonuses
  216. local function getWornSetPieces(name)
  217.     local ct = 0
  218.     local data = itemSets[name]
  219.     if data then
  220.         for i = 1,#data do
  221.             if IsEquippedItem(data[i]) then
  222.                 ct = ct + 1
  223.             end
  224.         end
  225.     end
  226.     return ct
  227. end
  228.  
  229. -- check for glyph by id
  230. local function hasGlyph(id)
  231.     for i = 1,9 do
  232.         local _, _, _, spell = GetGlyphSocketInfo(i)
  233.         if spell and tonumber(spell) == tonumber(id) then
  234.             return true
  235.         end
  236.     end
  237.     return false
  238. end
  239.  
  240. function HotCandy:UpdateBonus()
  241.     if spells[playerClass] then
  242.         for k,v in pairs(spells[playerClass]) do
  243.             track[k].duration = v.duration
  244.             track[k].spellHasteModified = nil
  245.             track[k].baseHaste = nil
  246.         end
  247.     else
  248.         return
  249.     end
  250.  
  251.     -- Equip Bonus
  252.     if playerClass == "DRUID" then
  253.         if (getWornSetPieces("Stormrage") >= 8) then
  254.             track.rejuvenation.duration = track.rejuvenation.duration + 3
  255.         end
  256.         if (getWornSetPieces("Nordrassil") >= 2) then
  257.             track.regrowth.duration = track.regrowth.duration + 6
  258.         end
  259.     elseif playerClass == "PRIEST" then
  260.         if (getWornSetPieces("Avatar Raiment") >= 4) then
  261.             track.renew.duration = track.renew.duration + 3
  262.         end
  263.     end
  264.  
  265.     -- Talent Bonus
  266.  
  267.     -- Glyph Bonus
  268.     if playerClass == "DRUID" then
  269.  
  270.     elseif playerClass == "PRIEST" then
  271.  
  272.     elseif playerClass == "PALADIN" then
  273.         -- Glyph of Beacon of Light
  274.         if hasGlyph(63218) then
  275.             track.beacon.duration = track.beacon.duration + 30
  276.         end
  277.     elseif playerClass == "SHAMAN" then
  278.         -- Glyph of Riptide
  279.         if hasGlyph(63273) then
  280.             track.riptide.duration = track.riptide.duration + 6
  281.         end
  282.     end
  283. end
  284.  
  285. function HotCandy:equipChanged(units)
  286.     if not units or not units.player or InCombatLockdown() then
  287.         return
  288.     end
  289.     self:UpdateBonus()
  290. end
  291.  
  292. -- ---------------------------------------------------------------------------------
  293. -- Spell Handling
  294.  
  295. local function makeBarId(spell, target)
  296.     return format("HotCandy%s@%s", spell, target)
  297. end
  298.  
  299. local stackCache = setmetatable({}, {__index = function(t,k) local new = {}; rawset(t,k,new); return new end})
  300.  
  301. -- CombatLog Event Handler
  302. function HotCandy:CombatLogHandler(event, timestamp, clevent, hideCaster, srcGUID, srcName, srcFlags, srcRaidFlags, dstGUID, dstName, dstFlags, dstRaidFlags, spellId, spellName, school, type, stack)
  303.     if srcGUID ~= playerGUID then return end
  304.     local fullDstName = dstName
  305.     -- Strip Server Names off the name
  306.     if _band(dstFlags, COMBATLOG_OBJECT_TYPE_PLAYER) == COMBATLOG_OBJECT_TYPE_PLAYER and dstName:find("-", 1, true) then
  307.         dstName = dstName:match("([^-]+)")
  308.     end
  309.     if clevent == "SPELL_AURA_APPLIED" or clevent == "SPELL_AURA_APPLIED_DOSE" then
  310.         local token = nameLookup[spellName]
  311.         if token then
  312.             -- hack for PoM stack tracking
  313.             if token == "pom" then stack = select(4, UnitBuff(fullDstName, spellName)) end
  314.             self:FireSpell(track[token], dstName, dstGUID, stack)
  315.         end
  316.     elseif clevent == "SPELL_AURA_REFRESH" then
  317.         local token = nameLookup[spellName]
  318.         if token then
  319.             -- refresh doesn't tell us the current number of stacks, so we assume a refresh doesn't change the number of stacks
  320.             stack = -1
  321.             -- hack for PoM stack tracking
  322.             if token == "pom" then stack = select(4, UnitBuff(fullDstName, spellName)) end
  323.             self:FireSpell(track[token], dstName, dstGUID, stack)
  324.         end
  325.     elseif clevent == "SPELL_HEAL" then
  326.         if spellName == "Regrowth" or spellName == "Nourish" or spellName == "Healing Touch" then
  327.             stack = select(4, UnitBuff(fullDstName, "Lifebloom", nil, "PLAYER"))
  328.             if stack~=nil then
  329.                 token = nameLookup["Lifebloom"]
  330.                 self:FireSpell(track[token], dstName, dstGUID, stack)
  331.             end
  332.         end
  333.     elseif clevent == "SPELL_CAST_SUCCESS" then
  334.         if spellName == "Lifebloom" then
  335.             stack = select(4, UnitBuff(fullDstName, "Lifebloom", nil, "PLAYER"))
  336.             if stack~=nil then
  337.                 self:FireSpell(track[token], dstName, dstGUID, stack)
  338.             end
  339.         end            
  340.     elseif clevent == "SPELL_AURA_REMOVED" then
  341.         local token = nameLookup[spellName]
  342.         if token then
  343.             self:StopBar(makeBarId(spellName, dstGUID))
  344.             if track[token].stackable then
  345.                 stackCache[spellName][dstGUID] = nil
  346.             end
  347.         end
  348.     end
  349. end
  350.  
  351. -- Handler for showing the Spell as a Bar
  352. function HotCandy:FireSpell(spell, dstName, dstGUID, stackCount)
  353.     if not spell or not spell.enabled then return end
  354.     -- Validate the Spell is supposed to be tracked
  355.     if spell.duration > 0 then
  356.         local duration = spell.duration
  357.         local spellName = spell.name
  358.         local stack = ""
  359.  
  360.         local id = makeBarId(spellName, dstGUID)
  361.  
  362.         if stackCount == -1 and stackCache[spellName]then
  363.             stackCount = stackCache[spellName][dstGUID]
  364.         end
  365.  
  366.         if stackCount and stackCount > 1 then
  367.             stack = format("(%d)", stackCount)
  368.             stackCache[spellName][dstGUID] = stackCount
  369.         end
  370.  
  371.         if spell.spellHasteModified then
  372.             local totalHaste = spell.baseHaste + GetCombatRatingBonus(CR_HASTE_SPELL)
  373.             duration = duration / (1 + totalHaste / 100)
  374.         end
  375.  
  376.         -- Create Text for the bar according to configured format
  377.         local text
  378.         if not db.noname then
  379.             if db.stackfirst then
  380.                 text = format("%s%s - %s", stack, spellName, dstName)
  381.             else
  382.                 text = format("%s%s - %s", spellName, stack, dstName)
  383.             end
  384.         else
  385.             text = format("%s%s", stack, dstName)
  386.         end
  387.         -- Create the Bar
  388.         self:StartBar(id, text, duration, spell.icon)
  389.     end
  390. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement