Mercurial > wow > turok
diff Tek.lua @ 1:766d8a40a1d6
first commit?
author | Nenue |
---|---|
date | Tue, 15 Dec 2015 08:07:21 -0500 |
parents | |
children | 8ace773d6bfc |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Tek.lua Tue Dec 15 08:07:21 2015 -0500 @@ -0,0 +1,387 @@ +addon, T_ = ... +-- User: Krakyn +-- Created: 12/4/2015 11:17 PM +local T = LibStub("AceAddon-3.0"):GetAddon("Turok") +local TL = 'Tek' +local mod = T:NewModule("Tek") +local print = function(...) + _G.print('Tek', ...) +end +local time = _G.ct + +-- events & units +local TRACKED_UNITS = {'player', 'target', 'focus', 'pet'} +local TRACKED_EVENTS = {'UNIT_SPELLCAST_START', 'UNIT_SPELLCAST_DELAYED', 'UNIT_SPELLCAST_STOP', 'UNIT_SPELLCAST_FAILED', 'UNIT_SPELLCAST_FAILED_QUIET', + 'UNIT_SPELLCAST_INTERRUPTED', 'UNIT_SPELLCAST_SUCCEEDED', 'UNIT_SPELLCAST_CHANNEL_START', 'UNIT_SPELLCAST_CHANNEL_STOP', 'UNIT_SPELLCAST_CHANNEL_UPDATE' } + +local FADE_OUT_TIME, FADE_IN_TIME = 1000, 200 -- animation timings + +-- values MUST be in chronological order +local CHANNEL_START, CAST_START, CAST_INTERRUPTED, CAST_SUCCEEDED, CAST_STOPPED, CAST_FAILED, CHANNEL_STOPPED = 1, 2, 3, 4, 5, 6, 7 +local TEXTURE_SUFFIX = { + [CHANNEL_START] = '_channeling', + [CAST_START] = '_casting', + [CAST_INTERRUPTED] = '_interrupted', + [CAST_SUCCEEDED] = '_finished', + [CAST_STOPPED] = '_failed', + [CAST_FAILED] = '_failed', + [CHANNEL_STOPPED] = '' +} +local inv = T.anchor_inverse +local d = T.direction_coord +local a = T.anchor_direction +local c = {} +-- c[unit]=nil is used by frame update, thus any indexing from a valid frame is implied to be for new casting info +setmetatable(c, { + __index = function(t,k) + t[k] = {} + return t[k] + end +}) + +function mod:OnEnable() + local db = T.db + + db.castbar = { + --T.defaults.castbar = { + width = 300, height = 24, + anchor = 'TOP', parent = 'TkFocusBar', anchorTo = 'BOTTOM', + posX = 0, posY = -2, + foreground_casting = {0.80784313725, 0.87843137254, 0.0156862745, 1}, + background_casting = {0,0,0,0.4}, + background_interrupted = {1,0,0,1}, + background_failed = {0.60784313725, 0.87843137254, 0.0156862745, 1}, + foreground_interrupted = {1, 0.5, 0, 1}, + foreground_failed = {0,0,0,1}, + foreground_finished = {0.60784313725, 0.87843137254, 0.0156862745, 1}, + background_finished = {0.60784313725, 0.87843137254, 0.0156862745, 1}, + foreground_inset = -1, + fill_direction = 'RIGHT', + fill_inverse = false, + glow_texture = "Tooltip-BigBorder", + glow_size = 2, + spark_texture = "Tooltip-BigBorder", + spark_size = 2, + ['player'] = {}, + ['target'] = { + width = 300, height = 24, + anchor = 'BOTTOMLEFT', parent = 'TkplayerCastBar', anchorTo = 'TOPRIGHT', + posX = 4, posY = 4, + }, + ['focus'] = { + width = 300, height = 24, + anchor = 'TOPLEFT', parent = 'TkplayerCastBar', anchorTo='BOTTOMRIGHT', + posX = 2, posY = -2 + }, + ['pet'] = { + width = 300, height = 24, + anchor = 'TOPRIGHT', parent = 'TkFocusBar', anchorTo='TOPLEFT', + posX = -2, posY = 0 + }, + } + + self.casting = c + self.castbar = {} + + + for _, unit in pairs(TRACKED_UNITS) do + local cdb = db.castbar[unit] + print('|cFFFF44FF' .. unit .. '|r castbar creation') + + + -- State info + c[unit] = {} + + -- Set frames + local fn = 'Tk' .. unit .. 'CastBar' + self.castbar[unit] = T:CreateBar(fn, cdb) + local pc = self.castbar[unit] + pc:Hide() + pc:SetAlpha(0) + + T:AddLabel(pc, cdb, 'spelltext') + local casttime = T:AddLabel(pc, cdb, 'casttime') + local latency = T:AddLabel(pc, cdb, 'latency') + pc.foreground:SetWidth(0) + + casttime:SetPoint('RIGHT', pc, 'RIGHT') + casttime:SetJustifyH('RIGHT') + latency:SetPoint('TOPRIGHT', pc.casttime, 'BOTTOMRIGHT') + latency:SetJustifyH('RIGHT') + + pc.transpt = a[cdb.fill_direction] + pc.xtrans = function() return math.min((cdb.width + cdb.foreground_inset) * pc.percent * d[pc.transpt][1], cdb.width) end + pc.ytrans = function() return math.min((cdb.height + cdb.foreground_inset) * pc.percent * d[pc.transpt][2], cdb.height) end + + pc.movement_x = 1 + pc.moving_end = 'LEFT' + + local glow = pc:CreateTexture('glow', 'OVERLAY') + glow:SetTexture(CASTBAR_TAILGLOW) + glow:SetPoint('TOPLEFT', pc, 'TOPLEFT', -5, 5) + glow:SetPoint('BOTTOMRIGHT', pc, 'BOTTOMRIGHT', 5, -5) + pc.glow = glow + + local icon = pc:CreateTexture('icon', 'ARTWORK') + icon:SetPoint('RIGHT', pc, 'LEFT', -2, 0) + icon:SetWidth(pc.foreground:GetHeight()) + icon:SetHeight(pc.foreground:GetHeight()) + icon:SetTexture(0,0,0,1) + pc.icon = icon + + pc.unit = unit + T:Bar_SetUpdateHandler(pc, self.TekUpdate) + + + + --print('created', fn) + end + + -- Casting table events + for i, event in pairs(TRACKED_EVENTS) do + print('listening to |cFF00FFFF' .. event .. '|r') + self:RegisterEvent(event, 'TekEvent') + end + + -- Extra events + self:RegisterEvent('PLAYER_TARGET_CHANGED') + self:RegisterEvent('PLAYER_FOCUS_CHANGED') + + CastingBarFrame:SetScript('OnUpdate', nil) + CastingBarFrame:SetScript('OnEvent', nil) + CastingBarFrame:Hide() +end + +-- Update handler for castbar +function mod:TekUpdate() + local glow = self.glow + local foreground = self.foreground + local background = self.background + local latency = self.latency + local time = GetTime() * 1000 + local spelltext = self.spelltext + local timetext = self.timetext + local cdb = self.db + if mod.casting[self.unit] ~= nil then + + local u = self.unit + local s = mod.casting[u] + local alpha = self:GetAlpha() + + -- is something casting at all? + if s.casting <= CAST_START then + + -- start = true whenever a new spell cast could be active (i.e. target switching) + if s.init then + print('|cFFDD77DD'..u..'|r init_cast (spell='..s.displayName..', startTime='..s.startTime..', endTime='..s.endTime..', channel=',s.channel,')') + print(self:GetName(), self:IsVisible(), self:IsShown()) + + -- update translation point + if s.casting == CHANNEL_START and not cdb.fill_inverse then + self.transpt = inv[a[cdb.fill_direction]] + else + self.transpt = a[cdb.fill_direction] + end + + -- update frame contents + foreground:SetTexture(unpack(cdb['foreground' .. TEXTURE_SUFFIX[s.casting]] and cdb['foreground' .. TEXTURE_SUFFIX[s.casting]] or cdb.foreground_color)) + background:SetTexture(unpack(cdb['background' .. TEXTURE_SUFFIX[s.casting]] and cdb['background' .. TEXTURE_SUFFIX[s.casting]] or cdb.background_color)) + + self.icon:SetTexture(s.texture) + spelltext:SetText(s.displayName) + latency:SetText(s.latency) + self.duration = s.endTime - s.startTime + self.fadeIn = s.startTime + (1-alpha) * FADE_IN_TIME + self.fadeOut = s.endTime + FADE_OUT_TIME -- needs to exist for target changes + + print(s.startTime, self.fadeIn, self.fadeIn - s.startTime) + -- clear 'start' + s.init = nil + end + + -- if we're checking this and start was never flipped, then something happened + if time <= self.fadeIn then + alpha = 1- ((self.fadeIn - time) / FADE_IN_TIME) + self:SetAlpha(alpha) + elseif alpha ~= 1 then + self:SetAlpha(1) + end + self.value = time - s.startTime + self.percent = self.value / self.duration + self.casttime:SetText(format("%.1f", self.value / 1000)) + + -- s.casting is nil when the spellcast has finished + else + -- something set a term flag + if s.casting < CHANNEL_STOPPED and s.fade then + print(TL, '|cFFDD77DD'..u..'|r init_fadeout (spell='..s.displayName..', startTime='..s.startTime..', endTime='..s.endTime..', channel=',s.channel,')') + self.fadeOut = time + FADE_OUT_TIME + foreground:SetTexture(unpack(cdb['foreground' .. TEXTURE_SUFFIX[s.casting]] and cdb['foreground' .. TEXTURE_SUFFIX[s.casting]] or cdb.foreground_color)) + background:SetTexture(unpack(cdb['background' .. TEXTURE_SUFFIX[s.casting]] and cdb['background' .. TEXTURE_SUFFIX[s.casting]] or cdb.background_color)) + s.fade = nil + self.value = self.duration + self.percent = 1 + end + + if time < self.fadeOut then + alpha = (self.fadeOut - time) / FADE_OUT_TIME + self:SetAlpha(alpha) + else + alpha = 0 + self:Hide() + self:SetAlpha(alpha) + self.casttime:SetText(nil) + self.spelltext:SetText(nil) + self.latency:SetText(nil) + self.debugged = false + self.percent = 0 + mod.casting[self.unit] = nil + print('|cFFDD77DD'..u..'|r work complete, hiding...') + end + -- hide and wait until we're pulled out again + end + self.foreground:SetPoint('RIGHT', self, self.transpt, self.xtrans(), self.ytrans()) + end +end + + +-- event stub, filters out unwanted cast events +function mod:TekEvent(e, unit, ...) + if not self.castbar[unit] then + return + end + if not self[e] then + error('No method signature for event ' .. tostring(e)) + end + print('popped |cFF00FFFF' .. e .. '|r: ', unit, ...) + self[e](self, e, unit, ...) +end + +function mod:PLAYER_TARGET_CHANGED (e, cause) + print(e) + self:UpdateUnit('target') +end +function mod:PLAYER_FOCUS_CHANGED (e, cause) + print(e) + self:UpdateUnit('focus') +end +function mod:UpdateUnit(unit) + if UnitCastingInfo(unit) then + mod:UNIT_SPELLCAST_START('UNIT_SPELLCAST_START', unit) + elseif UnitChannelInfo(unit) then + mod:UNIT_SPELLCAST_CHANNEL_START('UNIT_SPELLCAST_CHANNEL_START', unit) + else + mod.castbar[unit]:Hide() + end +end + +-- Spell event handlers +function mod:UNIT_SPELLCAST_SENT(e, unit, spellname, rank, target) + -- triggered an action buttton tied to a cast + c[unit].sentTime = math.floor(GetTime() * 1000) + print('|cFF44FF44',e,':|r', unit, spellname, c[unit].sentTime) + c[unit].spell = spellname + c[unit].rank = rank + c[unit].target = target +end + +function mod:UNIT_SPELLCAST_START(e, unit) -- Server says: someone started casting + local spellname, rank, displayName, texture, startTime, endTime, isTradeSkill, castID, nonInterruptible = UnitCastingInfo(unit) + print('casting['..unit..'] state updated (=start): spellname='.. spellname ..', startTime='.. startTime ..', endTime='.. endTime) + + c[unit].castID = castID + c[unit].spell = spellname + c[unit].rank = rank + c[unit].displayName = displayName + c[unit].texture = texture + c[unit].startTime = startTime + c[unit].endTime = endTime + c[unit].nonInterruptible = nonInterruptible + c[unit].isTradeSkill = isTradeSkill + if c[unit].sentTime then + c[unit].latency = c[unit].startTime - c[unit].sentTime + end + + -- set state and show + c[unit].casting = CAST_START + c[unit].init = true + self.castbar[unit]:Show() +end + +function mod:UNIT_SPELLCAST_DELAYED(e, unit, spellname, rank, castID, target) -- Server says: they're still casting but it'll take longer + local spellname, rank, displayName, texture, startTime, endTime, isTradeSkill, castID, nonInterruptible = UnitCastingInfo(unit) + print('casting['..unit..'] state updated (=delayed): spellname='.. spellname ..', startTime='.. startTime ..', endTime='.. endTime) + c[unit].castID = castID + c[unit].channel = false + c[unit].startTime = startTime + c[unit].endTime = endTime + -- just update timing data, frame script will adjust +end + +-- set exit states +function mod:UNIT_SPELLCAST_STOP(e, unit, spellname, rank, castID, target) -- Server says: someone stopped casting for some reason + --c[unit].casting = CAST_STOPPED +end + +function mod:UNIT_SPELLCAST_INTERRUPTED(e, unit, spellname, rank, castID, target) -- Server says: someone got interrupted + c[unit].casting = CAST_INTERRUPTED + c[unit].fade = true +end + +function mod:UNIT_SPELLCAST_SUCCEEDED(e, unit, spellname, rank, castID, target) -- Server says: they stopped because they're done + + if c[unit].castID == castID and c[unit].casting ~= CHANNEL_START then + c[unit].casting = CAST_SUCCEEDED + c[unit].fade = true + end +end + +function mod:UNIT_SPELLCAST_FAILED(e, unit, spellname, rank, castID, target) -- Server says: someone tried to cast something but they weren't allowed + if c[unit].castID ~= castID then -- can fire from keybind spam + return + end + c[unit].casting = CAST_FAILED + c[unit].fade = true +end + +function mod:UNIT_SPELLCAST_FAILED_QUIET(e, unit, spellname, rank, castID, target) -- Server says: someone tried to cast something but they weren't allowed + if c[unit].castID == castID and c[unit].casting == CAST_START then + c[unit].casting = CAST_FAILED + end +end + +function mod:UNIT_SPELLCAST_INTERRUPTIBLE(e, unit) + c[unit].notInterruptible = false +end +function mod:UNIT_SPELLCAST_NOT_INTERRUPTIBLE(e, unit) + c[unit].notInterruptible = true +end + +function mod:UNIT_SPELLCAST_CHANNEL_START(e, unit, spellname, rank, castID, spellID) + local spellname, rank, displayName, texture, startTime, endTime, isTradeSkill, nonInterruptible = UnitChannelInfo(unit) + displayName = spellname -- channels sometimes just appear as 'Channeling' according to Quartz author + print('casting['..unit..'] state updated (=start, channel): spellname='.. spellname ..', startTime='.. startTime ..', endTime='.. endTime) + c[unit].casting = CHANNEL_START + c[unit].spellname = spellname + c[unit].rank = rank + c[unit].displayName = displayName + c[unit].texture = texture + c[unit].startTime = startTime + c[unit].endTime = endTime + c[unit].nonInterruptible = nonInterruptible + c[unit].isTradeSkill = isTradeSkill + c[unit].init = true + mod.castbar[unit]:Show() +end -- start up +function mod:UNIT_SPELLCAST_CHANNEL_STOP(e, unit, spellname, rank, castID, spellID) + c[unit].casting = CHANNEL_STOPPED +end +function mod:UNIT_SPELLCAST_CHANNEL_UPDATE(e, unit, spellname, rank, castID, spellID) + spellname, rank, displayName, texture, startTime, endTime, isTradeSkill, nonInterruptible = UnitChannelInfo(unit) + displayName = spellname -- channels sometimes just appear as 'Channeling' according to Quartz author + c[unit].channel = true +end -- recalc + + + +