Mercurial > wow > turok
comparison Tek.lua @ 1:766d8a40a1d6
first commit?
| author | Nenue |
|---|---|
| date | Tue, 15 Dec 2015 08:07:21 -0500 |
| parents | |
| children | 8ace773d6bfc |
comparison
equal
deleted
inserted
replaced
| 0:ebbcc148a407 | 1:766d8a40a1d6 |
|---|---|
| 1 addon, T_ = ... | |
| 2 -- User: Krakyn | |
| 3 -- Created: 12/4/2015 11:17 PM | |
| 4 local T = LibStub("AceAddon-3.0"):GetAddon("Turok") | |
| 5 local TL = 'Tek' | |
| 6 local mod = T:NewModule("Tek") | |
| 7 local print = function(...) | |
| 8 _G.print('Tek', ...) | |
| 9 end | |
| 10 local time = _G.ct | |
| 11 | |
| 12 -- events & units | |
| 13 local TRACKED_UNITS = {'player', 'target', 'focus', 'pet'} | |
| 14 local TRACKED_EVENTS = {'UNIT_SPELLCAST_START', 'UNIT_SPELLCAST_DELAYED', 'UNIT_SPELLCAST_STOP', 'UNIT_SPELLCAST_FAILED', 'UNIT_SPELLCAST_FAILED_QUIET', | |
| 15 'UNIT_SPELLCAST_INTERRUPTED', 'UNIT_SPELLCAST_SUCCEEDED', 'UNIT_SPELLCAST_CHANNEL_START', 'UNIT_SPELLCAST_CHANNEL_STOP', 'UNIT_SPELLCAST_CHANNEL_UPDATE' } | |
| 16 | |
| 17 local FADE_OUT_TIME, FADE_IN_TIME = 1000, 200 -- animation timings | |
| 18 | |
| 19 -- values MUST be in chronological order | |
| 20 local CHANNEL_START, CAST_START, CAST_INTERRUPTED, CAST_SUCCEEDED, CAST_STOPPED, CAST_FAILED, CHANNEL_STOPPED = 1, 2, 3, 4, 5, 6, 7 | |
| 21 local TEXTURE_SUFFIX = { | |
| 22 [CHANNEL_START] = '_channeling', | |
| 23 [CAST_START] = '_casting', | |
| 24 [CAST_INTERRUPTED] = '_interrupted', | |
| 25 [CAST_SUCCEEDED] = '_finished', | |
| 26 [CAST_STOPPED] = '_failed', | |
| 27 [CAST_FAILED] = '_failed', | |
| 28 [CHANNEL_STOPPED] = '' | |
| 29 } | |
| 30 local inv = T.anchor_inverse | |
| 31 local d = T.direction_coord | |
| 32 local a = T.anchor_direction | |
| 33 local c = {} | |
| 34 -- c[unit]=nil is used by frame update, thus any indexing from a valid frame is implied to be for new casting info | |
| 35 setmetatable(c, { | |
| 36 __index = function(t,k) | |
| 37 t[k] = {} | |
| 38 return t[k] | |
| 39 end | |
| 40 }) | |
| 41 | |
| 42 function mod:OnEnable() | |
| 43 local db = T.db | |
| 44 | |
| 45 db.castbar = { | |
| 46 --T.defaults.castbar = { | |
| 47 width = 300, height = 24, | |
| 48 anchor = 'TOP', parent = 'TkFocusBar', anchorTo = 'BOTTOM', | |
| 49 posX = 0, posY = -2, | |
| 50 foreground_casting = {0.80784313725, 0.87843137254, 0.0156862745, 1}, | |
| 51 background_casting = {0,0,0,0.4}, | |
| 52 background_interrupted = {1,0,0,1}, | |
| 53 background_failed = {0.60784313725, 0.87843137254, 0.0156862745, 1}, | |
| 54 foreground_interrupted = {1, 0.5, 0, 1}, | |
| 55 foreground_failed = {0,0,0,1}, | |
| 56 foreground_finished = {0.60784313725, 0.87843137254, 0.0156862745, 1}, | |
| 57 background_finished = {0.60784313725, 0.87843137254, 0.0156862745, 1}, | |
| 58 foreground_inset = -1, | |
| 59 fill_direction = 'RIGHT', | |
| 60 fill_inverse = false, | |
| 61 glow_texture = "Tooltip-BigBorder", | |
| 62 glow_size = 2, | |
| 63 spark_texture = "Tooltip-BigBorder", | |
| 64 spark_size = 2, | |
| 65 ['player'] = {}, | |
| 66 ['target'] = { | |
| 67 width = 300, height = 24, | |
| 68 anchor = 'BOTTOMLEFT', parent = 'TkplayerCastBar', anchorTo = 'TOPRIGHT', | |
| 69 posX = 4, posY = 4, | |
| 70 }, | |
| 71 ['focus'] = { | |
| 72 width = 300, height = 24, | |
| 73 anchor = 'TOPLEFT', parent = 'TkplayerCastBar', anchorTo='BOTTOMRIGHT', | |
| 74 posX = 2, posY = -2 | |
| 75 }, | |
| 76 ['pet'] = { | |
| 77 width = 300, height = 24, | |
| 78 anchor = 'TOPRIGHT', parent = 'TkFocusBar', anchorTo='TOPLEFT', | |
| 79 posX = -2, posY = 0 | |
| 80 }, | |
| 81 } | |
| 82 | |
| 83 self.casting = c | |
| 84 self.castbar = {} | |
| 85 | |
| 86 | |
| 87 for _, unit in pairs(TRACKED_UNITS) do | |
| 88 local cdb = db.castbar[unit] | |
| 89 print('|cFFFF44FF' .. unit .. '|r castbar creation') | |
| 90 | |
| 91 | |
| 92 -- State info | |
| 93 c[unit] = {} | |
| 94 | |
| 95 -- Set frames | |
| 96 local fn = 'Tk' .. unit .. 'CastBar' | |
| 97 self.castbar[unit] = T:CreateBar(fn, cdb) | |
| 98 local pc = self.castbar[unit] | |
| 99 pc:Hide() | |
| 100 pc:SetAlpha(0) | |
| 101 | |
| 102 T:AddLabel(pc, cdb, 'spelltext') | |
| 103 local casttime = T:AddLabel(pc, cdb, 'casttime') | |
| 104 local latency = T:AddLabel(pc, cdb, 'latency') | |
| 105 pc.foreground:SetWidth(0) | |
| 106 | |
| 107 casttime:SetPoint('RIGHT', pc, 'RIGHT') | |
| 108 casttime:SetJustifyH('RIGHT') | |
| 109 latency:SetPoint('TOPRIGHT', pc.casttime, 'BOTTOMRIGHT') | |
| 110 latency:SetJustifyH('RIGHT') | |
| 111 | |
| 112 pc.transpt = a[cdb.fill_direction] | |
| 113 pc.xtrans = function() return math.min((cdb.width + cdb.foreground_inset) * pc.percent * d[pc.transpt][1], cdb.width) end | |
| 114 pc.ytrans = function() return math.min((cdb.height + cdb.foreground_inset) * pc.percent * d[pc.transpt][2], cdb.height) end | |
| 115 | |
| 116 pc.movement_x = 1 | |
| 117 pc.moving_end = 'LEFT' | |
| 118 | |
| 119 local glow = pc:CreateTexture('glow', 'OVERLAY') | |
| 120 glow:SetTexture(CASTBAR_TAILGLOW) | |
| 121 glow:SetPoint('TOPLEFT', pc, 'TOPLEFT', -5, 5) | |
| 122 glow:SetPoint('BOTTOMRIGHT', pc, 'BOTTOMRIGHT', 5, -5) | |
| 123 pc.glow = glow | |
| 124 | |
| 125 local icon = pc:CreateTexture('icon', 'ARTWORK') | |
| 126 icon:SetPoint('RIGHT', pc, 'LEFT', -2, 0) | |
| 127 icon:SetWidth(pc.foreground:GetHeight()) | |
| 128 icon:SetHeight(pc.foreground:GetHeight()) | |
| 129 icon:SetTexture(0,0,0,1) | |
| 130 pc.icon = icon | |
| 131 | |
| 132 pc.unit = unit | |
| 133 T:Bar_SetUpdateHandler(pc, self.TekUpdate) | |
| 134 | |
| 135 | |
| 136 | |
| 137 --print('created', fn) | |
| 138 end | |
| 139 | |
| 140 -- Casting table events | |
| 141 for i, event in pairs(TRACKED_EVENTS) do | |
| 142 print('listening to |cFF00FFFF' .. event .. '|r') | |
| 143 self:RegisterEvent(event, 'TekEvent') | |
| 144 end | |
| 145 | |
| 146 -- Extra events | |
| 147 self:RegisterEvent('PLAYER_TARGET_CHANGED') | |
| 148 self:RegisterEvent('PLAYER_FOCUS_CHANGED') | |
| 149 | |
| 150 CastingBarFrame:SetScript('OnUpdate', nil) | |
| 151 CastingBarFrame:SetScript('OnEvent', nil) | |
| 152 CastingBarFrame:Hide() | |
| 153 end | |
| 154 | |
| 155 -- Update handler for castbar | |
| 156 function mod:TekUpdate() | |
| 157 local glow = self.glow | |
| 158 local foreground = self.foreground | |
| 159 local background = self.background | |
| 160 local latency = self.latency | |
| 161 local time = GetTime() * 1000 | |
| 162 local spelltext = self.spelltext | |
| 163 local timetext = self.timetext | |
| 164 local cdb = self.db | |
| 165 if mod.casting[self.unit] ~= nil then | |
| 166 | |
| 167 local u = self.unit | |
| 168 local s = mod.casting[u] | |
| 169 local alpha = self:GetAlpha() | |
| 170 | |
| 171 -- is something casting at all? | |
| 172 if s.casting <= CAST_START then | |
| 173 | |
| 174 -- start = true whenever a new spell cast could be active (i.e. target switching) | |
| 175 if s.init then | |
| 176 print('|cFFDD77DD'..u..'|r init_cast (spell='..s.displayName..', startTime='..s.startTime..', endTime='..s.endTime..', channel=',s.channel,')') | |
| 177 print(self:GetName(), self:IsVisible(), self:IsShown()) | |
| 178 | |
| 179 -- update translation point | |
| 180 if s.casting == CHANNEL_START and not cdb.fill_inverse then | |
| 181 self.transpt = inv[a[cdb.fill_direction]] | |
| 182 else | |
| 183 self.transpt = a[cdb.fill_direction] | |
| 184 end | |
| 185 | |
| 186 -- update frame contents | |
| 187 foreground:SetTexture(unpack(cdb['foreground' .. TEXTURE_SUFFIX[s.casting]] and cdb['foreground' .. TEXTURE_SUFFIX[s.casting]] or cdb.foreground_color)) | |
| 188 background:SetTexture(unpack(cdb['background' .. TEXTURE_SUFFIX[s.casting]] and cdb['background' .. TEXTURE_SUFFIX[s.casting]] or cdb.background_color)) | |
| 189 | |
| 190 self.icon:SetTexture(s.texture) | |
| 191 spelltext:SetText(s.displayName) | |
| 192 latency:SetText(s.latency) | |
| 193 self.duration = s.endTime - s.startTime | |
| 194 self.fadeIn = s.startTime + (1-alpha) * FADE_IN_TIME | |
| 195 self.fadeOut = s.endTime + FADE_OUT_TIME -- needs to exist for target changes | |
| 196 | |
| 197 print(s.startTime, self.fadeIn, self.fadeIn - s.startTime) | |
| 198 -- clear 'start' | |
| 199 s.init = nil | |
| 200 end | |
| 201 | |
| 202 -- if we're checking this and start was never flipped, then something happened | |
| 203 if time <= self.fadeIn then | |
| 204 alpha = 1- ((self.fadeIn - time) / FADE_IN_TIME) | |
| 205 self:SetAlpha(alpha) | |
| 206 elseif alpha ~= 1 then | |
| 207 self:SetAlpha(1) | |
| 208 end | |
| 209 self.value = time - s.startTime | |
| 210 self.percent = self.value / self.duration | |
| 211 self.casttime:SetText(format("%.1f", self.value / 1000)) | |
| 212 | |
| 213 -- s.casting is nil when the spellcast has finished | |
| 214 else | |
| 215 -- something set a term flag | |
| 216 if s.casting < CHANNEL_STOPPED and s.fade then | |
| 217 print(TL, '|cFFDD77DD'..u..'|r init_fadeout (spell='..s.displayName..', startTime='..s.startTime..', endTime='..s.endTime..', channel=',s.channel,')') | |
| 218 self.fadeOut = time + FADE_OUT_TIME | |
| 219 foreground:SetTexture(unpack(cdb['foreground' .. TEXTURE_SUFFIX[s.casting]] and cdb['foreground' .. TEXTURE_SUFFIX[s.casting]] or cdb.foreground_color)) | |
| 220 background:SetTexture(unpack(cdb['background' .. TEXTURE_SUFFIX[s.casting]] and cdb['background' .. TEXTURE_SUFFIX[s.casting]] or cdb.background_color)) | |
| 221 s.fade = nil | |
| 222 self.value = self.duration | |
| 223 self.percent = 1 | |
| 224 end | |
| 225 | |
| 226 if time < self.fadeOut then | |
| 227 alpha = (self.fadeOut - time) / FADE_OUT_TIME | |
| 228 self:SetAlpha(alpha) | |
| 229 else | |
| 230 alpha = 0 | |
| 231 self:Hide() | |
| 232 self:SetAlpha(alpha) | |
| 233 self.casttime:SetText(nil) | |
| 234 self.spelltext:SetText(nil) | |
| 235 self.latency:SetText(nil) | |
| 236 self.debugged = false | |
| 237 self.percent = 0 | |
| 238 mod.casting[self.unit] = nil | |
| 239 print('|cFFDD77DD'..u..'|r work complete, hiding...') | |
| 240 end | |
| 241 -- hide and wait until we're pulled out again | |
| 242 end | |
| 243 self.foreground:SetPoint('RIGHT', self, self.transpt, self.xtrans(), self.ytrans()) | |
| 244 end | |
| 245 end | |
| 246 | |
| 247 | |
| 248 -- event stub, filters out unwanted cast events | |
| 249 function mod:TekEvent(e, unit, ...) | |
| 250 if not self.castbar[unit] then | |
| 251 return | |
| 252 end | |
| 253 if not self[e] then | |
| 254 error('No method signature for event ' .. tostring(e)) | |
| 255 end | |
| 256 print('popped |cFF00FFFF' .. e .. '|r: ', unit, ...) | |
| 257 self[e](self, e, unit, ...) | |
| 258 end | |
| 259 | |
| 260 function mod:PLAYER_TARGET_CHANGED (e, cause) | |
| 261 print(e) | |
| 262 self:UpdateUnit('target') | |
| 263 end | |
| 264 function mod:PLAYER_FOCUS_CHANGED (e, cause) | |
| 265 print(e) | |
| 266 self:UpdateUnit('focus') | |
| 267 end | |
| 268 function mod:UpdateUnit(unit) | |
| 269 if UnitCastingInfo(unit) then | |
| 270 mod:UNIT_SPELLCAST_START('UNIT_SPELLCAST_START', unit) | |
| 271 elseif UnitChannelInfo(unit) then | |
| 272 mod:UNIT_SPELLCAST_CHANNEL_START('UNIT_SPELLCAST_CHANNEL_START', unit) | |
| 273 else | |
| 274 mod.castbar[unit]:Hide() | |
| 275 end | |
| 276 end | |
| 277 | |
| 278 -- Spell event handlers | |
| 279 function mod:UNIT_SPELLCAST_SENT(e, unit, spellname, rank, target) | |
| 280 -- triggered an action buttton tied to a cast | |
| 281 c[unit].sentTime = math.floor(GetTime() * 1000) | |
| 282 print('|cFF44FF44',e,':|r', unit, spellname, c[unit].sentTime) | |
| 283 c[unit].spell = spellname | |
| 284 c[unit].rank = rank | |
| 285 c[unit].target = target | |
| 286 end | |
| 287 | |
| 288 function mod:UNIT_SPELLCAST_START(e, unit) -- Server says: someone started casting | |
| 289 local spellname, rank, displayName, texture, startTime, endTime, isTradeSkill, castID, nonInterruptible = UnitCastingInfo(unit) | |
| 290 print('casting['..unit..'] state updated (=start): spellname='.. spellname ..', startTime='.. startTime ..', endTime='.. endTime) | |
| 291 | |
| 292 c[unit].castID = castID | |
| 293 c[unit].spell = spellname | |
| 294 c[unit].rank = rank | |
| 295 c[unit].displayName = displayName | |
| 296 c[unit].texture = texture | |
| 297 c[unit].startTime = startTime | |
| 298 c[unit].endTime = endTime | |
| 299 c[unit].nonInterruptible = nonInterruptible | |
| 300 c[unit].isTradeSkill = isTradeSkill | |
| 301 if c[unit].sentTime then | |
| 302 c[unit].latency = c[unit].startTime - c[unit].sentTime | |
| 303 end | |
| 304 | |
| 305 -- set state and show | |
| 306 c[unit].casting = CAST_START | |
| 307 c[unit].init = true | |
| 308 self.castbar[unit]:Show() | |
| 309 end | |
| 310 | |
| 311 function mod:UNIT_SPELLCAST_DELAYED(e, unit, spellname, rank, castID, target) -- Server says: they're still casting but it'll take longer | |
| 312 local spellname, rank, displayName, texture, startTime, endTime, isTradeSkill, castID, nonInterruptible = UnitCastingInfo(unit) | |
| 313 print('casting['..unit..'] state updated (=delayed): spellname='.. spellname ..', startTime='.. startTime ..', endTime='.. endTime) | |
| 314 c[unit].castID = castID | |
| 315 c[unit].channel = false | |
| 316 c[unit].startTime = startTime | |
| 317 c[unit].endTime = endTime | |
| 318 -- just update timing data, frame script will adjust | |
| 319 end | |
| 320 | |
| 321 -- set exit states | |
| 322 function mod:UNIT_SPELLCAST_STOP(e, unit, spellname, rank, castID, target) -- Server says: someone stopped casting for some reason | |
| 323 --c[unit].casting = CAST_STOPPED | |
| 324 end | |
| 325 | |
| 326 function mod:UNIT_SPELLCAST_INTERRUPTED(e, unit, spellname, rank, castID, target) -- Server says: someone got interrupted | |
| 327 c[unit].casting = CAST_INTERRUPTED | |
| 328 c[unit].fade = true | |
| 329 end | |
| 330 | |
| 331 function mod:UNIT_SPELLCAST_SUCCEEDED(e, unit, spellname, rank, castID, target) -- Server says: they stopped because they're done | |
| 332 | |
| 333 if c[unit].castID == castID and c[unit].casting ~= CHANNEL_START then | |
| 334 c[unit].casting = CAST_SUCCEEDED | |
| 335 c[unit].fade = true | |
| 336 end | |
| 337 end | |
| 338 | |
| 339 function mod:UNIT_SPELLCAST_FAILED(e, unit, spellname, rank, castID, target) -- Server says: someone tried to cast something but they weren't allowed | |
| 340 if c[unit].castID ~= castID then -- can fire from keybind spam | |
| 341 return | |
| 342 end | |
| 343 c[unit].casting = CAST_FAILED | |
| 344 c[unit].fade = true | |
| 345 end | |
| 346 | |
| 347 function mod:UNIT_SPELLCAST_FAILED_QUIET(e, unit, spellname, rank, castID, target) -- Server says: someone tried to cast something but they weren't allowed | |
| 348 if c[unit].castID == castID and c[unit].casting == CAST_START then | |
| 349 c[unit].casting = CAST_FAILED | |
| 350 end | |
| 351 end | |
| 352 | |
| 353 function mod:UNIT_SPELLCAST_INTERRUPTIBLE(e, unit) | |
| 354 c[unit].notInterruptible = false | |
| 355 end | |
| 356 function mod:UNIT_SPELLCAST_NOT_INTERRUPTIBLE(e, unit) | |
| 357 c[unit].notInterruptible = true | |
| 358 end | |
| 359 | |
| 360 function mod:UNIT_SPELLCAST_CHANNEL_START(e, unit, spellname, rank, castID, spellID) | |
| 361 local spellname, rank, displayName, texture, startTime, endTime, isTradeSkill, nonInterruptible = UnitChannelInfo(unit) | |
| 362 displayName = spellname -- channels sometimes just appear as 'Channeling' according to Quartz author | |
| 363 print('casting['..unit..'] state updated (=start, channel): spellname='.. spellname ..', startTime='.. startTime ..', endTime='.. endTime) | |
| 364 c[unit].casting = CHANNEL_START | |
| 365 c[unit].spellname = spellname | |
| 366 c[unit].rank = rank | |
| 367 c[unit].displayName = displayName | |
| 368 c[unit].texture = texture | |
| 369 c[unit].startTime = startTime | |
| 370 c[unit].endTime = endTime | |
| 371 c[unit].nonInterruptible = nonInterruptible | |
| 372 c[unit].isTradeSkill = isTradeSkill | |
| 373 c[unit].init = true | |
| 374 mod.castbar[unit]:Show() | |
| 375 end -- start up | |
| 376 function mod:UNIT_SPELLCAST_CHANNEL_STOP(e, unit, spellname, rank, castID, spellID) | |
| 377 c[unit].casting = CHANNEL_STOPPED | |
| 378 end | |
| 379 function mod:UNIT_SPELLCAST_CHANNEL_UPDATE(e, unit, spellname, rank, castID, spellID) | |
| 380 spellname, rank, displayName, texture, startTime, endTime, isTradeSkill, nonInterruptible = UnitChannelInfo(unit) | |
| 381 displayName = spellname -- channels sometimes just appear as 'Channeling' according to Quartz author | |
| 382 c[unit].channel = true | |
| 383 end -- recalc | |
| 384 | |
| 385 | |
| 386 | |
| 387 |
