Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local TEXTURE = 'Interface\\AddOns\\tCastBars\\Texture'
- local FONT = 'Interface\\AddOns\\tCastBars\\Font.ttf'
- local BACKDROP = {
- bgFile = TEXTURE,
- insets = {top = -0.8, bottom = -0.8, left = -0.8, right = -0.8}
- }
- local castbars = {
- player = true,
- target = true,
- focus = true,
- pet = true,
- }
- local CastingBarFinishSpell = function(self) --this is called at the end of casts or channels
- self.barTexture:SetColorTexture(0.1, 0.9, 0.1) --set it green to show completion (to be honest you don't see this color change)
- self.fadeOut = 1 --we want to fade the frame out now
- self.casting = nil --we're no longer casting
- self.channeling = nil --we're no longer channeling
- end
- local function unitSpellcastStart(frame, event, unit) --this function gets called whenever a UNIT_SPELLCAST_START event fires for player, focus, pet, or target
- local name, text, texture, startTime, endTime, _, _, notInterruptible, spellID = UnitCastingInfo(unit)
- if not name then
- frame:Hide()
- return
- end
- if frame.lag then
- frame.lag:Show()
- end
- frame.value = GetTime() - (startTime / 1000)
- frame.maxValue = (endTime - startTime) / 1000
- frame.bar:SetMinMaxValues(0, frame.maxValue)
- frame.bar:SetValue(frame.value)
- frame.bar.text:SetText(text)
- frame.icon:SetTexture(texture)
- frame:SetAlpha(1)
- frame.holdTime = 0 --this is like a time to fade after a cast finishes that is checked in our OnUpdate
- frame.casting = 1
- frame.spellID = spellID
- frame.channeling = nil --we're not channeling, we're casting
- frame.fadeOut = nil
- if notInterruptible then --red if protected, green if interruptible
- frame.barTexture:SetColorTexture(0.7, 0.1, 0.1)
- else
- frame.barTexture:SetColorTexture(0.1, 0.9, 0.1)
- end
- if frame.showCastbar then
- frame:Show()
- end
- end
- local function unitSpellcastStop(frame, event, unit, ...) --this function gets called whenever a UNIT_SPELLCAST_STOP or UNIT_SPELLCAST_CHANNELING_STOP fires for player, focus, pet, or target
- local _, _, spellID = ...
- if ((frame.casting and event == 'UNIT_SPELLCAST_STOP' and spellID == frame.spellID) or (frame.channeling and event == 'UNIT_SPELLCAST_CHANNEL_STOP')) then
- frame.bar:SetValue(frame.maxValue)
- if event == 'UNIT_SPELLCAST_STOP' then
- frame.casting = nil
- frame.barTexture:SetColorTexture(0.8, 0.8, 0) --yellow for a cast that was stopped by movement or escaping (NOT INTERRUPTED)
- else
- frame.channeling = nil
- end
- frame.fadeOut = 1
- frame.holdTime = 0
- end
- end
- local function unitSpellcastFailedInterrupted(frame, event, unit, ...) --this function gets called whenever a UNIT_SPELLCAST_FAILED or UNIT_SPELLCAST_INTERRUPTED fires for player, focus, pet or target
- local _, _, spellID = ...
- if (frame:IsShown() and frame.casting and spellID == frame.spellID and not frame.fadeOut) then
- frame.bar:SetValue(frame.maxValue)
- frame.barTexture:SetColorTexture(1, 0.4, 0) --orange for interrupted or failed
- if event == 'UNIT_SPELLCAST_FAILED' then
- frame.bar.text:SetText('FAILED')
- else
- frame.bar.text:SetText('INTERRUPTED')
- end
- if frame.lag then
- frame.lag:Hide()
- end
- frame.casting = nil
- frame.channeling = nil
- frame.fadeOut = 1
- frame.holdTime = GetTime()
- end
- end
- local function unitSpellcastDelayed(frame, event, unit) --this function gets called whenever a UNIT_SPELLCAST_DELAYED occurs for player, pet, target, or focus
- if frame:IsShown() then
- local name, _, _, startTime, endTime = UnitCastingInfo(unit)
- if not name then
- frame:Hide()
- return
- end
- frame.value = GetTime() - (startTime / 1000)
- frame.maxValue = (endTime - startTime) / 1000
- frame.bar:SetMinMaxValues(0, frame.maxValue)
- if not frame.casting then
- frame.casting = 1
- frame.channeling = nil
- frame.fadeOut = 0
- end
- end
- end
- local function unitSpellcastChannelStart(frame, event, unit) --this function gets called whenever a UNIT_SPELLCAST_CHANNEL_START fires for player, target, focus, or pet
- local name, text, texture, startTime, endTime, _, notInterruptible = UnitChannelInfo(unit)
- if not name then
- frame:Hide()
- return
- end
- if frame.lag then
- frame.lag:Hide()
- end
- frame.value = (endTime / 1000) - GetTime()
- frame.maxValue = (endTime - startTime) / 1000
- frame.bar:SetMinMaxValues(0, frame.maxValue)
- if notInterruptible then --red if protected, green for interruptible
- frame.barTexture:SetColorTexture(0.7, 0.1, 0.1)
- else
- frame.barTexture:SetColorTexture(0.1, 0.9, 0.1)
- end
- frame.bar:SetValue(frame.value)
- frame.bar.text:SetText(text)
- frame.icon:SetTexture(texture)
- frame:SetAlpha(1)
- frame.holdTime = 0
- frame.casting = nil
- frame.channeling = 1
- frame.fadeOut = nil
- if frame.showCastbar then
- frame:Show()
- end
- end
- local function unitSpellcastChannelUpdate(frame, event, unit) --this function gets called whenever a UNIT_SPELLCAST_CHANNEL_UPDATE fires for player, target, focus, or pet
- if frame:IsShown() then
- local name, text, texture, startTime, endTime, _, notInterruptible = UnitChannelInfo(unit)
- if not name then
- frame:Hide()
- return
- end
- frame.value = (endTime / 1000) - GetTime()
- frame.maxValue = (endTime - startTime) / 1000
- frame.bar:SetMinMaxValues(0, frame.maxValue)
- frame.bar:SetValue(frame.value)
- end
- end
- local MakeCastBarFunctions = function(frame, event) --this function gets called during our MakeCastBars function, during which, it will create functions for the individual units (player, target, focus, pet)
- function frame:UNIT_SPELLCAST_START(event, unit)
- unitSpellcastStart(frame, event, unit)
- end
- function frame:UNIT_SPELLCAST_STOP(event, unit)
- unitSpellcastStop(frame, event, unit)
- end
- function frame:UNIT_SPELLCAST_CHANNEL_STOP(event, unit, ...)
- unitSpellcastStop(frame, event, unit, ...)
- end
- function frame:UNIT_SPELLCAST_FAILED(event, unit, ...)
- unitSpellcastFailedInterrupted(frame, event, unit, ...)
- end
- function frame:UNIT_SPELLCAST_INTERRUPTED(event, unit, ...)
- unitSpellcastFailedInterrupted(frame, event, unit, ...)
- end
- function frame:UNIT_SPELLCAST_DELAYED(event, unit)
- unitSpellcastDelayed(frame, event, unit)
- end
- function frame:UNIT_SPELLCAST_CHANNEL_START(event, unit)
- unitSpellcastChannelStart(frame, event, unit)
- end
- function frame:UNIT_SPELLCAST_CHANNEL_UPDATE(event, unit)
- unitSpellcastChannelUpdate(frame, event, unit)
- end
- function frame:UNIT_SPELLCAST_INTERRUPTIBLE()
- frame.barTexture:SetColorTexture(0.1, 0.9, 0.1)
- end
- function frame:UNIT_SPELLCAST_NOT_INTERRUPTIBLE()
- frame.barTexture:SetColorTexture(0.7, 0.1, 0.1)
- end
- end
- local MakeCastBar = function(unit, enable) --this function will make castbars, place them, register their events, and make their functions for player, target, focus, and pet units
- local frame = _G[unit..'tCastBar'] or CreateFrame('frame', unit..'tCastBar', UIParent)
- frame:SetSize(228, 22)
- frame:SetBackdrop(BACKDROP)
- frame:SetBackdropColor(0, 0, 0)
- frame:SetPoint('CENTER', UIParent, 'CENTER')
- if not frame.bar then
- frame.bar = CreateFrame('StatusBar', nil, frame)
- frame.bar:SetAllPoints()
- frame.bar:SetMinMaxValues(0, 1)
- frame.bar:SetValue(0)
- frame.barTexture = frame:CreateTexture(nil, 'BORDER')
- frame.barTexture:SetTexture(TEXTURE)
- frame.bar:SetStatusBarTexture(frame.barTexture)
- frame.bar.bg = frame.bar:CreateTexture(nil, 'BACKGROUND')
- frame.bar.bg:SetTexture(TEXTURE)
- frame.bar.bg:SetColorTexture(0.2, 0.2, 0.2)
- frame.bar.bg:SetAllPoints()
- frame.bar.text = frame.bar:CreateFontString(nil, 'OVERLAY')
- frame.bar.text:SetFont(FONT, 12, 'OUTLINE')
- frame.bar.text:SetJustifyH('CENTER')
- frame.bar.text:SetJustifyV('MIDDLE')
- frame.bar.text:SetPoint('CENTER')
- frame.bar.timer = frame.bar:CreateFontString(nil, 'OVERLAY')
- frame.bar.timer:SetFont(FONT, 12, 'OUTLINE')
- frame.bar.timer:SetJustifyH('RIGHT')
- frame.bar.timer:SetJustifyV('MIDDLE')
- frame.bar.timer:SetPoint('RIGHT', frame, 'RIGHT', -3, 0)
- frame.icon = frame:CreateTexture(nil, 'ARTWORK')
- frame.icon:SetSize(22, 22)
- frame.icon:SetPoint('TOPRIGHT', frame, 'TOPLEFT', -1, 1)
- frame.icon:SetPoint('BOTTOMRIGHT', frame, 'BOTTOMLEFT', -1, -1)
- frame.icon:SetTexCoord(.06, .94, .06, .94)
- end
- if unit == 'player' then
- frame.lag = _G[frame:GetName()..'Lag'] or frame.bar:CreateTexture(frame:GetName()..'Lag', 'BORDER')
- frame.lag:SetPoint('TOPRIGHT') --this anchors the lag frame to the right of the cast bar (since we cast from left to right)
- frame.lag:SetPoint('BOTTOMRIGHT')
- frame.lag:SetTexture(TEXTURE)
- frame.lag:SetColorTexture(1, 0.4, 0)
- frame:SetPoint('CENTER', UIParent, 'CENTER', 11, -238)
- elseif unit == 'pet' then
- frame:SetPoint('CENTER', UIParent, 'CENTER', 11, -375)
- elseif unit == 'target' then
- frame:SetPoint('CENTER', UIParent, 'CENTER', 11, 100)
- elseif unit == 'focus' then
- frame:SetPoint('CENTER', UIParent, 'CENTER', 11, -150)
- end
- frame.timerUpdate = 0.1 --this controls how many times per second our OnUpdate fires (1/frame.timerUpdate) = # of times updated in a second, lower = more = smoother appearance = more CPU usage
- frame:RegisterEvent('PLAYER_TARGET_CHANGED')
- frame:RegisterEvent('PLAYER_FOCUS_CHANGED')
- frame:RegisterUnitEvent('UNIT_SPELLCAST_START', unit)
- frame:RegisterUnitEvent('UNIT_SPELLCAST_STOP', unit)
- frame:RegisterUnitEvent('UNIT_SPELLCAST_FAILED', unit)
- frame:RegisterUnitEvent('UNIT_SPELLCAST_INTERRUPTED', unit)
- frame:RegisterUnitEvent('UNIT_SPELLCAST_DELAYED', unit)
- frame:RegisterUnitEvent('UNIT_SPELLCAST_CHANNEL_START', unit)
- frame:RegisterUnitEvent('UNIT_SPELLCAST_CHANNEL_UPDATE', unit)
- frame:RegisterUnitEvent('UNIT_SPELLCAST_CHANNEL_STOP', unit)
- frame:RegisterUnitEvent('UNIT_SPELLCAST_INTERRUPTIBLE', unit)
- frame:RegisterUnitEvent('UNIT_SPELLCAST_NOT_INTERRUPTIBLE', unit)
- frame:RegisterEvent('PLAYER_ENTERING_WORLD')
- frame.unit = unit
- frame.casting = nil
- frame.channeling = nil
- frame.holdTime = 0
- frame.showCastbar = castbars[unit]
- frame.locked = true
- frame:Hide()
- frame:SetScript('OnShow', function(self)
- if not self.locked then return end
- if self.casting then
- local _, _, _, startTime = UnitCastingInfo(self.unit)
- if startTime then
- self.value = GetTime() - (startTime / 1000)
- end
- else
- local _, _, _, _, endTime = UnitChannelInfo(self.unit)
- if endTime then
- self.value = (endTime / 1000) - GetTime()
- end
- end
- end)
- MakeCastBarFunctions(frame, event) --make our functions for the frame
- frame:SetScript('OnEvent', function(self, event, ...)
- if not self.locked then return end
- local arg1 = ...
- local unit = self.unit
- if (event == 'PLAYER_ENTERING_WORLD' or event == 'PLAYER_TARGET_CHANGED' or event == 'PLAYER_FOCUS_CHANGED') then
- local spellChannel = UnitChannelInfo(unit)
- local spellName = UnitCastingInfo(unit)
- if spellChannel then
- event = 'UNIT_SPELLCAST_CHANNEL_START'
- arg1 = unit
- elseif spellName then
- event = 'UNIT_SPELLCAST_START'
- arg1 = unit
- else
- CastingBarFinishSpell(self)
- end
- end
- if arg1 ~= unit then return end
- if self[event] then --handle the event for our frame
- self[event](frame, event, unit, ...)
- end
- end)
- frame:SetScript('OnUpdate', function(self, elapsed)
- if not self.bar.timer then return end
- if (self.timerUpdate and self.timerUpdate < elapsed) then
- if self.casting then
- self.bar.timer:SetText(format('%.1f', max(self.maxValue - self.value, 0)))
- elseif self.channeling then
- self.bar.timer:SetText(format('%.1f', max(self.value, 0)))
- else
- self.bar.timer:SetText('')
- end
- self.timerUpdate = 0.1
- else
- self.timerUpdate = self.timerUpdate - elapsed
- end
- if self.casting then
- self.value = self.value + elapsed
- if self.value >= self.maxValue then
- self.bar:SetValue(self.maxValue)
- CastingBarFinishSpell(self)
- return
- end
- self.bar:SetValue(self.value)
- if self.unit == 'player' then
- local down, up, lag = GetNetStats()
- local castingmin, castingmax = self.bar:GetMinMaxValues()
- local lagvalue = (lag / 1000) / (castingmax - castingmin)
- if lagvalue < 0 then
- lagvalue = 0
- elseif lagvalue > 1 then
- lagvalue = 1
- end
- self.lag:ClearAllPoints()
- self.lag:SetPoint('RIGHT')
- self.lag:SetHeight(self.bar:GetHeight())
- self.lag:SetWidth(self.bar:GetWidth() * lagvalue)
- end
- elseif self.channeling then
- self.value = self.value - elapsed
- if self.value <= 0 then
- CastingBarFinishSpell(self)
- return
- end
- self.bar:SetValue(self.value)
- elseif GetTime() < self.holdTime then
- return
- elseif self.fadeOut then
- self.fadeOut = nil
- self:Hide()
- end
- end)
- end
- local tCastBars = _G['tCastBars'] or CreateFrame('frame', 'tCastBars', UIParent)
- tCastBars:RegisterEvent('PLAYER_TALENT_UPDATE')
- tCastBars:RegisterEvent('PLAYER_ENTERING_WORLD')
- tCastBars:RegisterEvent('ADDON_LOADED')
- tCastBars:SetScript('OnEvent', function(self, event, arg1, ...)
- if (event == 'PLAYER_ENTERING_WORLD' or event == 'PLAYER_TALENT_UPDATE') then
- CastingBarFrame.showCastbar = false
- CastingBarFrame:UnregisterAllEvents()
- CastingBarFrame:SetScript('OnUpdate', function() end)
- TargetFrameSpellBar.showCastbar = false
- TargetFrameSpellBar:UnregisterAllEvents()
- TargetFrameSpellBar:SetScript('OnUpdate', function() end)
- FocusFrameSpellBar.showCastbar = false
- FocusFrameSpellBar:UnregisterAllEvents()
- FocusFrameSpellBar:SetScript('OnUpdate', function() end)
- PetCastingBarFrame.showCastbar = false
- PetCastingBarFrame:UnregisterAllEvents()
- PetCastingBarFrame:SetScript('OnUpdate', function() end)
- for unit, enable in pairs(castbars) do
- if enable then
- MakeCastBar(unit, enable)
- end
- end
- end
- end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement