-- this is for new blizzard style castbars that flash and stuff -- table to hold castbars for all units local _casters = {} local _barFrames = {} local _updateRaidSetup = true local _raidMembers,_partyMembers local _enabled = true local _disableOnPEW = true local _castBars = {} local _redColor = {1,0,0} local babbleSpells = BabbleLib:GetInstance('Spell 1.1') local babbleCore = BabbleLib:GetInstance('Core 1.1') local function _finishSpell(barSpark, barFlash) this:SetStatusBarColor(0.0, 1.0, 0.0); if ( barSpark ) then barSpark:Hide(); end if ( barFlash ) then barFlash:SetAlpha(0.0); barFlash:Show(); end this.flash = 1; this.fadeOut = 1; this.casting = nil; this.channeling = nil; end local function _onUpdate() local barSpark = this.spark local barFlash = this.barFlash local barTime = this.time if ( this.casting ) then local status = GetTime(); if ( status > this.maxValue ) then status = this.maxValue; end if ( status == this.maxValue ) then this:SetValue(this.maxValue); _finishSpell(); return; end this:SetValue(status); if ( barFlash ) then barFlash:Hide(); end local sparkPosition = ((status - this.startTime) / (this.maxValue - this.startTime)) * this:GetWidth(); if ( sparkPosition < 0 ) then sparkPosition = 0; end if ( barSpark ) then barSpark:SetPoint("CENTER", this, "LEFT", sparkPosition, 2); end barTime:SetText(string.format('%.1f',this.maxValue - status)) elseif ( this.channeling ) then local time = GetTime(); if ( time > this.endTime ) then time = this.endTime; end if ( time == this.endTime ) then _finishSpell(); return; end local barValue = this.startTime + (this.endTime - time); this:SetValue( barValue ); if ( barFlash ) then barFlash:Hide(); end barTime:SetText(string.format('%.1f',this.endTime - time)) elseif ( GetTime() < this.holdTime ) then return; elseif ( this.flash ) then local alpha = 0; if ( barFlash ) then alpha = barFlash:GetAlpha() + CASTING_BAR_FLASH_STEP; end if ( alpha < 1 ) then if ( barFlash ) then barFlash:SetAlpha(alpha); end else if ( barFlash ) then barFlash:SetAlpha(1.0); end this.flash = nil; end elseif ( this.fadeOut ) then local alpha = this:GetAlpha() - CASTING_BAR_ALPHA_STEP; if ( alpha > 0 ) then this:SetAlpha(alpha); else this.fadeOut = nil; this:Hide(); HealWatch.RemoveCastBar(this.target,this) if (not this.unit) then return end for i,bar in pairs(_casters[this.unit]) do if (bar == this) then tremove(_casters[this.unit],i) end end this.unit = nil this.target = nil tinsert(_castBars,this) end end end local function _CreateCastBar(unit) local width = HealWatch.Options.labelWidth-10 local frame = CreateFrame('StatusBar','HealWatchCastFrame'..#_barFrames+1) frame:SetHeight(18) frame:SetWidth(width) frame.width = width - 10 frame:SetParent(HealWatchCastFrame) frame:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar","ARTWORK") frame:SetStatusBarColor(1, 0, 0, 1) frame.bar = frame -- transparent background local bgTexture = frame:CreateTexture(nil, "BACKGROUND") bgTexture:SetTexture(0,0,0,0.5) bgTexture:SetAllPoints(frame) frame.bgTexture = bgTexture local border = frame:CreateTexture(frame:GetName().."StatusBarBorder", "ARTWORK") border:SetTexture("Interface\\Tooltips\\UI-StatusBar-Border") border:SetWidth(width+5) border:SetHeight(23) border:SetPoint("CENTER", frame, "CENTER", 0, 0) frame.border = border local caster = frame:CreateFontString(nil, "ARTWORK") caster:Show() caster:SetFontObject(GameFontHighlight) caster:SetWidth(math.floor(0.75*width)) caster:SetHeight(13) caster:ClearAllPoints() caster:SetPoint("LEFT", frame, "LEFT", 7, 0) caster:SetJustifyH("LEFT") caster:SetParent(frame) frame.caster = caster local time = frame:CreateFontString(nil, "ARTWORK") time:Show() time:SetFontObject(GameFontHighlight) time:SetWidth(math.floor(0.5*width)) time:SetHeight(13) time:ClearAllPoints() time:SetPoint("RIGHT", frame, "RIGHT", -10, 0) time:SetJustifyH("RIGHT") time:SetParent(frame) frame.time = time local spark = frame:CreateTexture(nil, "OVERLAY") spark:SetWidth(32) spark:SetHeight(32) spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark") spark:Show() spark:SetBlendMode("ADD") spark:ClearAllPoints() spark:SetPoint("CENTER", frame, "LEFT", 0, 0) spark:SetParent(frame) frame.spark = spark local flash = frame:CreateTexture(nil,"OVERLAY") flash:SetWidth(width) flash:SetHeight(64) flash:SetTexture("Interface\\Tooltips\\UI-CastingBar-Flash") flash:SetBlendMode("ADD") flash:ClearAllPoints() flash:SetPoint("TOP",frame,"TOP",0,28) frame.barFlash = flash local icon = frame:CreateTexture(nil,"ARTWORK") icon:SetWidth(16) icon:SetHeight(16) icon:ClearAllPoints() icon:Hide() icon:SetPoint("RIGHT",frame,"LEFT",-5,0) frame.icon = icon frame.casting = nil; frame.channeling = nil; frame.holdTime = 0; frame.showCastbar = true; frame:SetScript("OnUpdate", _onUpdate) table.insert(_barFrames,frame) frame.inUse = true return frame end function HealWatch.UpdateBarWidths(width) local bar for i=1,#_barFrames do bar = _barFrames[i] bar:SetWidth(width-10) bar.caster:SetWidth(math.floor(0.75*width)) end end local function _getCastBar() return tremove(_castBars) or _CreateCastBar() end local function _freeCastBar(bar) bar.unit = nil tinsert(_castBars,bar) end local function _tableCasters() local unit -- reset the group compositions _raidMembers = GetNumRaidMembers() _partyMembers = GetNumPartyMembers() if (_raidMembers > 0) then for i = 1,GetNumRaidMembers() do unit = 'raid'..i if (not _casters[unit]) then _casters[unit] = _CreateCastBar(unit) end end if (not isRaid) then isRaid = true end elseif (_partyMembers > 0) then for i=1,GetNumPartyMembers() do unit = 'party'..i if (not _casters[unit]) then _casters[unit] = _CreateCastBar(unit) end end end if (not _casters['player']) then _casters['player'] = _CreateCastBar('player') end end local function _onEvent(self,event,arg1,spell,rank,target) if (not _enabled or arg1 == "target") then return end if (event == "PLAYER_LOGIN") then --_tableCasters() if (_disableOnPEW) then _enabled = false end return elseif (event == "RAID_ROSTER_UPDATE" or event == "PARTY_MEMBERS_CHANGED") then --_tableCasters() return elseif (event == "UNIT_TARGET") then local unit = arg1 if (unit == "player") then if (UnitExists('target') and UnitCanAssist('player','target')) then HealWatch.UpdateTarget(unit,UnitName('target'),'target') else HealWatch.UpdateTarget(unit) end else HealWatch.UpdateTarget(unit,nil,unit.."target") end end local newevent = event local newarg1 = arg1 local uName = UnitName(arg1) local unit = arg1 if (not _casters[unit]) then _casters[unit] = {} end if (event == "UNIT_SPELLCAST_SENT") then -- we're not reporting information yet, so no need to watch our own heals local curSpell = babbleSpells:GetEnglish(spell) if (not HealWatch.spells['watch'][curSpell]) then return end if (HealWatch.SendHWMessage) then HealWatch.SendHWMessage(target,curSpell) end if (HealWatch.spells['unique'][spell]) then HealWatch.customTarget = target HealWatch.UpdateTarget('player',target,nil,true) end return elseif (event == "UNIT_SPELLCAST_START") then local name, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitCastingInfo(unit); if ( not name or not HealWatch.spells['watch'][name]) then --DevTools_Dump("Spell not watched: "..tostring(name)) return end local barSpark,barFlash,barIcon,caster,time,color if (not HealWatch.spells['unique'][name]) then local groupSetup = HealWatch.groupSetup if (not isRaid) then for i=1,GetNumPartyMembers() do local this = _getCastBar() this.unit = unit this.target = UnitExists('party'..i) and UnitName('party'..i) barSpark = this.spark barFlash = this.barFlash barIcon = this.icon caster = this.caster time = this.time color = HealWatch.spells.spellColors[name] if (unit == 'player' and HealWatch.Options.colorMyHeals) then color = _redColor end if (color) then this:SetStatusBarColor(color[1],color[2],color[3],1) end --this:SetStatusBarColor(1.0, 0.7, 0.0); if ( barSpark ) then barSpark:Show(); end this.startTime = startTime / 1000; this.maxValue = endTime / 1000; -- startTime to maxValue no endTime this:SetMinMaxValues(this.startTime, this.maxValue); this:SetValue(this.startTime); if ( caster ) then caster:SetText(string.format("%s: %s(%s)",uName,text,nameSubtext)) end if ( barIcon ) then barIcon:SetTexture(texture); end this:SetAlpha(1.0); this.holdTime = 0; this.casting = 1; this.channeling = nil; this.fadeOut = nil; if ( this.showCastbar ) then HealWatch.InsertCastBar(this.target,this) this:Show() end tinsert(_casters[unit],this) end -- add one for oneself local this = _getCastBar() this.unit = unit this.target = UnitName('player') barSpark = this.spark barFlash = this.barFlash barIcon = this.icon caster = this.caster time = this.time color = HealWatch.spells.spellColors[name] if (unit == 'player' and HealWatch.Options.colorMyHeals) then color = _redColor end if (color) then this:SetStatusBarColor(color[1],color[2],color[3],1) end --this:SetStatusBarColor(1.0, 0.7, 0.0); if ( barSpark ) then barSpark:Show(); end this.startTime = startTime / 1000; this.maxValue = endTime / 1000; -- startTime to maxValue no endTime this:SetMinMaxValues(this.startTime, this.maxValue); this:SetValue(this.startTime); if ( caster ) then caster:SetText(string.format("%s: %s(%s)",uName,text,nameSubtext)) end if ( barIcon ) then barIcon:SetTexture(texture); end this:SetAlpha(1.0); this.holdTime = 0; this.casting = 1; this.channeling = nil; this.fadeOut = nil; if ( this.showCastbar ) then HealWatch.InsertCastBar(this.target,this) this:Show() end tinsert(_casters[unit],this) return elseif (groupSetup[caster]) then local group = groupSetup[caster]["group"] if (groupSetup[group]) then for i=1,table.getn(groupSetup[group]) do local this = _getCastBar() this.unit = unit this.target = groupSetup[group][i] barSpark = this.spark barFlash = this.barFlash barIcon = this.icon caster = this.caster time = this.time color = HealWatch.spells.spellColors[name] if (unit == 'player' and HealWatch.Options.colorMyHeals) then color = _redColor end if (color) then this:SetStatusBarColor(color[1],color[2],color[3],1) end --this:SetStatusBarColor(1.0, 0.7, 0.0); if ( barSpark ) then barSpark:Show(); end this.startTime = startTime / 1000; this.maxValue = endTime / 1000; -- startTime to maxValue no endTime this:SetMinMaxValues(this.startTime, this.maxValue); this:SetValue(this.startTime); if ( caster ) then caster:SetText(string.format("%s: %s(%s)",uName,text,nameSubtext)) end if ( barIcon ) then barIcon:SetTexture(texture); end this:SetAlpha(1.0); this.holdTime = 0; this.casting = 1; this.channeling = nil; this.fadeOut = nil; if ( this.showCastbar ) then HealWatch.InsertCastBar(this.target,this) this:Show() end tinsert(_casters[unit],this) end return end end end local this = _getCastBar() this.unit = unit barSpark = this.spark barFlash = this.barFlash barIcon = this.icon caster = this.caster time = this.time color = HealWatch.spells.spellColors[name] if (unit == 'player' and HealWatch.Options.colorMyHeals) then color = _redColor end if (color) then this:SetStatusBarColor(color[1],color[2],color[3],1) end --this:SetStatusBarColor(1.0, 0.7, 0.0); if ( barSpark ) then barSpark:Show(); end this.startTime = startTime / 1000; this.maxValue = endTime / 1000; -- startTime to maxValue no endTime this:SetMinMaxValues(this.startTime, this.maxValue); this:SetValue(this.startTime); if ( caster ) then caster:SetText(string.format("%s: %s(%s)",uName,text,nameSubtext)) end if ( barIcon ) then barIcon:SetTexture(texture); end this:SetAlpha(1.0); this.holdTime = 0; this.casting = 1; this.channeling = nil; this.fadeOut = nil; if ( this.showCastbar ) then this.target = HealWatch.GetTarget(unit) HealWatch.InsertCastBar(this.target,this) this:Show() end tinsert(_casters[unit],this) elseif ( newevent == "UNIT_SPELLCAST_STOP" or newevent == "UNIT_SPELLCAST_CHANNEL_STOP" ) then local this for i,v in pairs(_casters[unit]) do this = _casters[unit][i] if ( not this:IsVisible() ) then this:Hide(); HealWatch.RemoveCastBar(this.target,this) if (not this.unit) then return end for i,bar in pairs(_casters[this.unit]) do if (bar == this) then tremove(_casters[this.unit],i) end end this.unit = nil this.target = nil tinsert(_castBars,this) end if ( this:IsShown() ) then if ( barSpark ) then barSpark:Hide(); end if ( barFlash ) then barFlash:SetAlpha(0.0); barFlash:Show(); end this:SetValue(this.maxValue); if ( newevent == "UNIT_SPELLCAST_STOP" ) then this:SetStatusBarColor(0.0, 1.0, 0.0); this.casting = nil; else this.channeling = nil; end this.flash = 1; this.fadeOut = 1; this.holdTime = 0; end end if (unit == 'player') then HealWatch.customTarget = nil end elseif ( newevent == "UNIT_SPELLCAST_FAILED" or newevent == "UNIT_SPELLCAST_INTERRUPTED" ) then local this for i,v in pairs(_casters[unit]) do this = _casters[unit][i] local time = this.time if ( this:IsShown() and not this.channeling ) then this:SetValue(this.maxValue); this:SetStatusBarColor(1.0, 0.0, 0.0); if ( barSpark ) then barSpark:Hide(); end if ( time ) then if ( newevent == "UNIT_SPELLCAST_FAILED" ) then time:SetText(FAILED); else time:SetText(INTERRUPTED); end end this.casting = nil; this.channeling = nil; this.fadeOut = 1; this.holdTime = GetTime() + CASTING_BAR_HOLD_TIME; end end elseif ( newevent == "UNIT_SPELLCAST_DELAYED" ) then local this local name, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitCastingInfo(this.unit); local watch = HealWatch.spells['watch'][name] for i,v in pairs(_casters[unit]) do this = _casters[unit][i] if ( this:IsShown() ) then if ( not name or not watch) then -- if there is no name, there is no bar this:Hide(); HealWatch.RemoveCastBar(this.target,this) for i,bar in pairs(_casters[this.unit]) do if (bar == this) then tremove(_casters[this.unit],i) end end this.unit = nil this.target = nil tinsert(_castBars,this) return; end this.startTime = startTime / 1000; this.maxValue = endTime / 1000; this:SetMinMaxValues(this.startTime, this.maxValue); if ( not this.casting ) then this:SetStatusBarColor(1.0, 0.7, 0.0); if ( barSpark ) then barSpark:Show(); end if ( barFlash ) then barFlash:SetAlpha(0.0); barFlash:Hide(); end this.casting = 1; this.channeling = nil; this.flash = 0; this.fadeOut = 0; end end end elseif ( newevent == "UNIT_SPELLCAST_CHANNEL_START" ) then local name, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitChannelInfo(unit); if ( not name or not HealWatch.spells['watch'][name]) then return end if (not _casters[arg1]) then _casters[arg1] = {} end if ( not name or not HealWatch.spells['watch'][name]) then -- if there is no name, there is no bar for i,bar in pairs(_casters[this.unit]) do if (bar == this) then tremove(_casters[this.unit],i) end end this.unit = nil this.target = nil tinsert(_castBars,this) return; end this:SetStatusBarColor(0.0, 1.0, 0.0); this.startTime = startTime / 1000; this.endTime = endTime / 1000; this.duration = this.endTime - this.startTime; this.maxValue = this.startTime; -- startTime to endTime no maxValue this:SetMinMaxValues(this.startTime, this.endTime); this:SetValue(this.endTime); if ( caster ) then caster:SetText(string.format("%s: %s(%s)",uName,text,nameSubtext)) end if ( barIcon ) then barIcon:SetTexture(texture); end this:SetAlpha(1.0); this.holdTime = 0; this.casting = nil; this.channeling = 1; this.fadeOut = nil; if ( this.showCastbar ) then this.target = HealWatch.GetTarget(this.unit) HealWatch.InsertCastBar(this.target,this) this:Show(); end elseif ( newevent == "UNIT_SPELLCAST_CHANNEL_UPDATE" ) then local this local name, nameSubtext, text, texture, startTime, endTime, isTradeSkill = UnitChannelInfo(unit); local watch = HealWatch.spells['watch'][name] for i,v in pairs(_casters[unit]) do this = _casters[unit][i] if ( this:IsShown() ) then if ( not name or not watch) then -- if there is no name, there is no bar this:Hide(); HealWatch.RemoveCastBar(this.target,this) for i,bar in pairs(_casters[this.unit]) do if (bar == this) then tremove(_casters[this.unit],i) end end this.unit = nil this.target = nil tinsert(_castBars,this) return; end this.startTime = startTime / 1000; this.endTime = endTime / 1000; this.maxValue = this.startTime; this:SetMinMaxValues(this.startTime, this.endTime); end end end end function HealWatch.HW2Toggle(state) _enabled = state or not _enabled return _enabled end function HealWatch.DumpHW2Status() return _enabled end local tFrame = CreateFrame("Frame") tFrame:SetScript("OnEvent",_onEvent) tFrame:RegisterEvent("UNIT_SPELLCAST_SENT") tFrame:RegisterEvent("UNIT_SPELLCAST_START") tFrame:RegisterEvent("UNIT_SPELLCAST_STOP") tFrame:RegisterEvent("UNIT_SPELLCAST_FAILED") tFrame:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED") tFrame:RegisterEvent("UNIT_SPELLCAST_DELAYED") tFrame:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED") tFrame:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START") tFrame:RegisterEvent("UNIT_SPELLCAST_CHANNEL_UPDATE") tFrame:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP") tFrame:RegisterEvent("RAID_ROSTER_UPDATE") tFrame:RegisterEvent("PARTY_MEMBERS_CHANGED") tFrame:RegisterEvent("PLAYER_LOGIN") tFrame:RegisterEvent("UNIT_TARGET")