# HG changeset patch # User Nenue # Date 1450184841 18000 # Node ID 766d8a40a1d69e5e8199d0c93b419fc89e4f52ee # Parent ebbcc148a4071d934d6cbe3fe4c2a9659f5f0610 first commit? diff -r ebbcc148a407 -r 766d8a40a1d6 .pkgmeta --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.pkgmeta Tue Dec 15 08:07:21 2015 -0500 @@ -0,0 +1,18 @@ +externals: + Libs/LibStub: + url: svn://svn.wowace.com/wow/libstub/mainline/trunk + tag: latest + Libs/CallbackHandler-1.0: + url: svn://svn.wowace.com/wow/callbackhandler/mainline/trunk/CallbackHandler-1.0 + tag: latest + Libs/AceAddon-3.0: + url: svn://svn.wowace.com/wow/ace3/mainline/trunk/AceAddon-3.0 + tag: latest + + +ignore: + - Debug.lua + - Turok.iml + - .idea + +enable-nolib-creation: no \ No newline at end of file diff -r ebbcc148a407 -r 766d8a40a1d6 Equip.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Equip.lua Tue Dec 15 08:07:21 2015 -0500 @@ -0,0 +1,94 @@ +-- User: Krakyn +-- Created: 12/4/2015 11:20 PM +-- Equipment, spec, etc. +local T = LibStub("AceAddon-3.0"):GetAddon("Turok") +local mod = T:NewModule("Equip", "AceEvent-3.0") +--setprinthandler(function (...) T:debug('Equip', nil, ...) end) + +local t18_slots = { + [INVSLOT_HEAD] = 124296, -- head + [INVSLOT_SHOULDER] = 124307, -- shoulders + [INVSLOT_CHEST] = 124284, -- chest + [INVSLOT_LEGS] = 124301, -- legs + [INVSLOT_HAND] = 124292, -- hands +} + + +local use_slots = { + [INVSLOT_FINGER1] = 1, + [INVSLOT_FINGER2] = 2, + [INVSLOT_TRINKET1] = 3, + [INVSLOT_TRINKET2] = 4, + +} +function mod:OnEnable() + self.equipped = {} + self:RegisterEvent('COMBAT_RATING_UPDATE', 'UpdateCombatRatings') + self:RegisterEvent('PLAYER_EQUIPMENT_CHANGED', 'UpdateEquipment') + self:RegisterEvent('PLAYER_SPECIALIZATION_CHANGED', 'UpdateSpec') +end + +function mod:UpdateEquipment (_, slot, hasItem) + -- ratings event will handle the rest + if not t18_slots[slot] or use_slots[slot] then + return + end + -- debug + local link = GetInventoryItemID('player', slot) + print('|cFF00FFFFequipment ', slot, hasItem, link) + -- /debug + + if t18_slots[slot] then + t18_count = 0 + for slot, itemID in pairs(t18_slots) do + if GetInventoryItemID(slot) == itemID then + t18_count = t18_count + 1 + end + end + if t18 >= 4 then + T.stats.aimedshot = s.gcd + else + T.stats.aimedshot = 2 * T.stats.castingmod + end + T.statstext =string.format('%.2f', s.aimedshot) + end + + if use_slots[slot] then + if hasItem then + local itemID = GetInventoryItemID('player', slot) + self.equipped[slot] = itemID + T:GetModule("Spirit").item_watch[itemID] = {GetInventoryItemCooldown('player', slot) } + else + if self.equipped[slot] then + self.equipped[slot] = nil + end + + end + end + +end + + +function mod:UpdateCombatRatings() + local s = T.stats + s.haste = UnitSpellHaste('player') + s.focusregen = 4 * (1 + s.haste/100) + s.castingmod = 1+ s.haste/1000 + s.gcd = 1.5 * s.castingmod + T.statstext = { + haste = string.format('%.2f', s.haste), + focusregen = string.format('%.2f', s.focusregen), + castingmod = string.format('%.2f', s.castingmod), + } + local t = T.statstext + + print('|cFF00FFFFCOMBAT_RATING_UPDATE:|r', 'haste:', t.haste, 'regen:', t.focusregen) +end + +function mod:UpdateSpec (e, unit) + if unit ~= 'player' then + return + end + + T.stats.focusmax = UnitPowerMax('player') +end \ No newline at end of file diff -r ebbcc148a407 -r 766d8a40a1d6 Fog.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Fog.lua Tue Dec 15 08:07:21 2015 -0500 @@ -0,0 +1,326 @@ +-- User: Krakyn +-- Created: 12/4/2015 11:13 PM +--[[ +-- Core tools, mostly frame handling business. It's an interface script after all. +-- Types: +-- StatusFrame +-- Primary container for status data, carries primary value information by default +-- FIELDS +-- value = exact primary value represented by frame +-- min = exact minimum for primary value +-- max = exact maximum for primary value +-- percent = value / max +-- alpha = base frame alpha level, set when a fade animation has completed +-- fadeTo = when set, the frame will begin fading to this level +-- fadeDuration = set with fadeTo when the transition needs to be time-adjusted for unpredictable alpha states +-- fadeTime = set with fadeTo when the transition has an explicit desired timing +-- throttle_rate = animation frame delay +-- +-- METHODS +-- Update() = Runs the frame's Update script, and calls UpdateText() +-- UpdateText() = Iterates over frame children and calls Update() if it is a StatusText frame +-- +-- StatusText +-- Sub-container for individual text elements, carries string output values, controlled by from Update(). By default +-- these are derived from the parent's primary value data, but is mostly overridden in module code. +-- FIELDS +-- text = WoW FontString object housing text data +-- format = a format string for expressing complex data (timer bars, etc.) +-- METHODS +-- SetText() = shortcut for text:SetText(...) +-- SetJustifyH() = shortcut for text:SetJustifyH(...) +-- Implements: +-- frame = CreateBar(name, config root) +-- Creates and displays a generic bar frame with progress textures and default updater, based on the variables from +-- the smart config table. Seeded with methods Update() and UpdateText(). +-- Update() will refresh the entire frame and tail call UpdateText() +-- UpdateText() will iterate over the contents of frame:GetChildren() and call Update() +-- NEVER CREATE A CHILD FRAME WITHOUT Update() DEFINED +-- NEVER INVOKE METHODS FROM A GetParent() RETURN +-- +-- Bar_SetUpdateHandler(frame, function) +-- Takes the desired OnUpdate script and wraps it inside frame throttling logic, then does SetScript +-- +-- frame = AddLabel(frame, config root, name) +-- Constructs a text display and adds it to the frame's list of internal text objects. Contains method Update(), which +-- refreshed text. +-- +-- HANDLERS +-- Bar_Update([value, min/duration, max/end]) +-- Default handler for any non-timed bar (where isTimer = false in config vars. Invoked by frame:Update() +]] +local T = LibStub("AceAddon-3.0"):GetAddon("Turok") +local LSM = LibStub("LibSharedMedia-3.0") +local TL = 'Fog' +local print = function(...) + _G.print(TL, ...) +end +--setprinthandler(function (...) T:debug('Fog', nil, ...) end) +local time = _G.ct +local FADE_OUT_TIME = 1 -- duration per 1-0 alpha transition +local FADE_IN_TIME = 0.4 -- duration per 0-1 alpha transition + +local inset_factor = { + ['TOPLEFT'] = {-1, 1}, + ['TOP'] = {0, 1}, + ['TOPRIGHT'] = {1, 1}, + ['RIGHT'] = {1, 0}, + ['BOTTOMRIGHT'] = {1, -1}, + ['BOTTOM'] = {0, -1}, + ['BOTTOMLEFT'] = {-1,-1}, + ['LEFT'] = {-1, 0} +} + +T.anchor_inverse = { ['LEFT'] = 'RIGHT', ['RIGHT'] = 'LEFT', ['UP'] = 'DOWN', ['DOWN'] = 'UP' } -- directional inverse +T.direction_coord = { ['LEFT'] = {1, 0}, ['RIGHT'] = {-1,0}, ['UP'] = {0, -1}, ['DOWN'] = {0, 1 } } -- directional derivatives +T.anchor_direction = { ['LEFT'] = 'RIGHT', ['RIGHT'] = 'LEFT', ['UP'] = 'BOTTOM', ['DOWN'] = 'TOP'} -- directional anchors + +function T:CreateBar(name, config) + local parent = type(config.parent) == 'string' and _G[config.parent] or parent + if not parent then + parent = CreateFrame('Frame', config.parent, UIParent) + print('creating dry frame |cFFDDDDDD' .. config.parent .. '|r for |cFFFFFF00' .. name .. '|r') + end + + local f + if _G[name] and _G[name].GetFrameType and _G[name].GetFrameType() == 'Frame' then + f = _G[name] + print('found existing table |cFFFFFF00' .. name .. '|r') + else + print('creating statusbar '.. name, config.anchor, parent:GetName(), config.anchorTo, config.posX, config.posY) + end + + + f = CreateFrame('Frame', name, UIParent) + f.db = config + + -- state vars + f.combat = InCombatLockdown() + f.min = 0 + f.max = 1 + f.value = 0 + f.percent = 0 + f.alpha = f.combat and config.alpha or config.alpha_ooc + f:SetAlpha(f.combat and config.alpha or config.alpha_ooc) + f:SetPoint(config.anchor, config.parent, config.anchorTo, config.posX, config.posY) + f:SetSize(config.width, config.height) + f:SetFrameStrata(config.strata) + self:CreateStatusTextures(f, config) + + f.throttle_rate = 0.0166666666 -- ~60fps + f.throttle_point = time + + -- default handler + f.Update = T.Bar_Update + f.UpdateText = T.Bar_UpdateText + T:Bar_SetUpdateHandler(f, T.Bar_Update) + + return f +end + +function T:CreateStatusTextures(region, c) + c = c and c or region.db + print('STATUSTEX_make', region:GetName(), c.background_texture, c.background_color, c.foreground_texture, c.foreground_color) + region.background = region:CreateTexture('background', 'BACKGROUND') + region.background:SetAllPoints(region) + if c.background_texture then + region.background:SetTexture(LSM:Fetch('statusbar', c.background_texture)) + region.background:SetVertexColor(unpack(c.background_color)) + else + region.background:SetTexture(unpack(c.background_color)) + end + region.background:SetBlendMode(c.background_blend) + + region.foreground = region:CreateTexture('foreground', 'ARTWORK') + region.foreground:SetPoint('TOPLEFT', region, 'TOPLEFT', 0-c.foreground_inset, c.foreground_inset) + region.foreground:SetPoint('BOTTOMRIGHT', region, 'BOTTOMRIGHT', c.foreground_inset, 0-c.foreground_inset) + if c.foreground_texture then + region.foreground:SetTexture(LSM:Fetch('statusbar', c.foreground_texture)) + region.foreground:SetVertexColor(unpack(c.foreground_color)) + else + region.foreground:SetTexture(unpack(c.foreground_color)) + end + region.foreground:SetBlendMode(c.foreground_blend) +end + +function T:CreateStatusIcon(region, c) + local file = type(c) == 'string' and c or region.icon + if type(c) ~= 'table' then + c = region.db + end + print('STATUSICON', region:GetName(), file, c.icon_show) + +end + +-- Sets the OnUpdate handler within a timing scheme +function T:Bar_SetUpdateHandler(bar, func) + bar:SetScript('OnUpdate', function(bar) + if GetTime() < bar.throttle_point then + return + end + + bar.throttle_point = bar.throttle_point + bar.throttle_rate + if type(func) == 'string' then + if type(bar[func]) ~= 'function' then + error('TurokBar:SetUpdateScript(); string "' ..func.. '" is not a valid method name') + return + end + elseif type(func) ~= 'function' then + error('TurokBar:SetUpdateScript(function or string); got '.. type(func) .. 'instead') + return + end + + func(bar) + end) +end + +-- Default update loop +function T:Bar_Update (value, min, max) + + if value ~= nil then -- could be 0 + self.value = value + end + if (min ~= nil and max ~= nil) then + if self.isTimer then + self.duration = min + self.endTime = max + else + self.min = min + self.max = max + self.duration = max + end + end + + if self.combat ~= InCombatLockdown() then + self.combat = InCombatLockdown() + if self.combat then + self.fadeTo = self.db.alpha + self.fadeDuration = FADE_IN_TIME + else + self.fadeTo = self.db.alpha_ooc + self.fadeDuration = FADE_OUT_TIME + end + end + + -- we need the time for something + if self.isTimer or self.fadeTo ~= nil then + local time = GetTime() + + -- start doing fade animation things + if self.fadeTo ~= nil then + + if not self.fadeFrom then + self.fadeFrom = self:GetAlpha() + end + + -- fadeDuration missing, fill it in + if not self.fadeDuration then + self.fadeDuration = self.fadeFrom > self.fadeTo and FADE_OUT_TIME or FADE_IN_TIME + end + + -- fadeTime missing, + if not self.fadeTime then + local fadeRatio = 1 + if self.fadeFrom ~= self.alpha then + fadeRatio = (self.fadeTo - self.fadeFrom) / (self.fadeTo - self.alpha) -- target delta + end + --print(fadeRatio, self.fadeDuration) + self.fadeTime = time + fadeRatio * self.fadeDuration -- fixed rate of change + end + + -- are we done? + if time >= self.fadeTime then + self:SetAlpha(self.fadeTo) + self.alpha = self.fadeTo + self.fadeTo = nil + self.fadeFrom = nil + self.fadeDuration = nil + self.fadeTime = nil + else --nope + local remaining = (self.fadeTime - time) / self.fadeDuration + local fadeTotal = (self.fadeTo - self.fadeFrom) + --print(self.fadeTo - (fadeTotal * remaining), fadeTotal * remaining) + self:SetAlpha(self.fadeTo - (fadeTotal * remaining)) + end + end + + -- termination check + if self.isTimer then + if time >= self.endTime and self.fadeTo == nil then + self:Hide() + return + else + self.percent = (self.endTime - time) / self.duration + end + end + + else + self.percent = (self.value - self.min) / (self.max - self.min) + end + + self:UpdateText() + self.foreground:SetPoint('BOTTOMRIGHT', self, 'BOTTOMLEFT', self.db.width * self.percent + self.db.foreground_inset, 0-self.db.foreground_inset) +end + +function T:Bar_UpdateText() + local c = {self:GetChildren()} + for _, rl in ipairs(c) do + if rl.text then + rl.format = self.db.label_string + rl:Update() + end + end +end + +-- addon:AddLabel +-- Constructs a text display and adds it to that region +-- +function T:AddLabel (region, config, labelname) + assert(region:IsObjectType('Frame'), "T:CreateLabel(table, table [, string])") + labelname = (labelname or string.format('%x', GetTime() % 1000000)) + print('assigning frame for text object |cFFFF9922'..labelname..'|r to '..region:GetName()) + + local lf = CreateFrame('Frame', region:GetName()..'_'..labelname, region) + local ft = lf:CreateFontString(labelname, 'OVERLAY') + local lx, ly, lp = 0,0, config.label_point + if config.label_inset ~= 0 and lp ~= 'CENTER' then + lx = config.label_inset * inset_factor[lp][1] + ly = config.label_inset * inset_factor[lp][2] + end + + lf:SetPoint(lp, region, lp, lx, ly) + lf:SetSize(region:GetWidth(), region:GetHeight()) + lf:SetFrameStrata(config.label_strata) + + ft:SetFont(LSM:Fetch('font', config.label_font), config.label_size, config.label_outline) + ft:SetAllPoints(lf) + ft:SetJustifyH(config.label_justifyH or (config.label_point:find('LEFT') and 'LEFT' or (config.label_point:find('RIGHT') and 'RIGHT' or 'CENTER'))) + ft:SetJustifyV(config.label_justifyV or (config.label_point:find('TOP') and 'TOP' or (config.label_point:find('BOTTOM') and 'BOTTOM' or 'MIDDLE'))) + ft:SetTextColor(1, 1, 1) + ft:SetText('SET ME!') + + lf.Update = region.isTimer and T.Label_UpdateFormat or T.Label_Update + lf.SetJustifyH = function(self, justify) ft:SetJustifyH(justify) end + lf.SetText = function(self, text) ft:SetText(text) end + + lf.text = ft + region[labelname] = lf + return lf +end + +-- one of two possible assignments for label:Update() +function T:Label_UpdateFormat() + local region = self:GetParent() + if self.format then + self.value = string.gsub(self.format, '%%p', string.format('%.1f', region.value)) + self.value = string.gsub(self.value, '%%d', region.duration) + if region.name then + self.value = string.gsub(self.value, '%%n', region.name) + end + end + self.text:SetText(self.value) +end +function T:Label_Update() + self.text:SetText(self:GetParent().value) +end + diff -r ebbcc148a407 -r 766d8a40a1d6 Lost.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lost.lua Tue Dec 15 08:07:21 2015 -0500 @@ -0,0 +1,165 @@ +-- User: Krakyn +-- Created: 12/14/2015 3:03 PM +local T = LibStub("AceAddon-3.0"):GetAddon("Turok") +local TL = 'Lost' +local print = function(...) _G.print(TL, ...) end +local LSM = LibStub("LibSharedMedia-3.0") +local mod = T:NewModule(TL, "AceTimer-3.0") +local time = _G.ct +local spell_trunc = {} +local inv = T.anchor_inverse +local d = T.direction_coord +local a = T.anchor_direction + +function mod:OnEnable() + self.raidbuffs_active = {} -- active raid buffs + self.raidbuffs_text = {} -- raid buff text + self.raidbuffs_avail = {} -- availability info + self.raidbuffs_display = {} -- buff list ordering info + self.unit_cache = {} -- remember GUIDs we've seen before + + local db = _G.TurokData + db.raidbuff = { + parent = 'UIParent', + anchor = 'BOTTOMRIGHT', anchorTo = 'BOTTOMRIGHT', + posX = -300, posY = 300, + height = 50, width = 150, + icon_size = 25, + label_size = 11, + label_font = 'ArchivoNarrow-Bold', + } + + local rw = CreateFrame('Frame', 'TkRaidWatch', UIParent) + local c = db.raidbuff + self.raid_watcher = rw + rw:SetPoint(c.anchor, c.parent, c.anchorTo, c.posX, c.posY) + rw:SetSize(c.width, c.height) + rw:SetMovable(true) + local bd = rw:CreateTexture() + bd:SetTexture(1,1,1,1) + bd:SetGradient('VERTICAL', 0,0,0,1,1,1) + bd:SetBlendMode('MOD') + bd:SetPoint('TOPLEFT',rw,'TOPLEFT', -2, 2) + bd:SetPoint('BOTTOMRIGHT',rw,'BOTTOMRIGHT', 2, -2) + + for i = 1, 9 do + local icon = rw:CreateTexture('TkRaidWatchButton'..i, 'ARTWORK') + icon:SetSize(c.icon_size,c.icon_size) + icon:SetTexCoord(0.15, 0.85, 0.15, 0.85) + + + self.raidbuffs_active[i] = icon + rw:EnableMouse(true) + rw:SetScript('OnMouseDown', function(self) self:StartMoving() end) + rw:SetScript('OnMouseUp', function(self) self:StopMovingOrSizing() end) + + local text = rw:CreateFontString('TkRaidWatchText'.. i, 'OVERLAY') + text:SetPoint('CENTER', icon, 'CENTER') + text:SetFont(LSM:Fetch('font', c.label_font), c.label_size, 'OUTLINE') + text:SetText(i) + self.raidbuffs_text[i] = text + end + + + db.raidevent = {} + + + self:RegisterEvent('PARTY_MEMBERS_CHANGED') + self:RegisterEvent('PLAYER_SPECIALIZATION_CHANGED') + self:RegisterEvent('ENCOUNTER_START') + self:RegisterEvent('INSPECT_READY') + self:RegisterEvent('UNIT_AURA', 'RaidBuffScan') + + self:RaidBuffScan() + self:RosterScan() +end +function mod:PLAYER_REGEN_ENABLED(e,...) end +function mod:PLAYER_REGEN_DISABLED(e, ...) end + +function mod:INSPECT_READY() +end +function mod:PLAYER_SPECIALIZATION_CHANGED(e,unit) + local specID + print(e, unit) + if unit == 'player' then + specID = GetSpecializationInfo(GetSpecialization()) + else + --NotifyInspect(unit) + specID = GetInspectSpecialization() + end + + print(GetSpecializationInfoByID(specID)) + self:RosterScan() +end + +function mod:PARTY_MEMBERS_CHANGED(e, ...) +end +function mod:ENCOUNTER_START(e,...) +end + +-- Updates available raid/party buffs +function mod:RaidBuffScan(unit) + + -- search for unit data + + local changed = false + local c = T.db.raidbuff + -- update raidbuffs + local k = 1 + for i = 1, NUM_LE_RAID_BUFF_TYPES do + local rb = self.raidbuffs_active[i] + local rt = self.raidbuffs_text[i] + local name, rank, texture, duration, expiration, spellId, slot = GetRaidBuffTrayAuraInfo(i) + if name then + rb:Hide() + rt:Hide() + self.raidbuffs_display[i] = nil + else + rb:Show() + rt:Show() + if self.raidbuffs_avail[i] then + rb:SetTexture(0.5,0.5,0.5,0.1) + rb:SetBlendMode('MOD') + else + rb:SetTexture(1,0.2,0,0.5) + rb:SetBlendMode('ADD') + end + self.raidbuffs_text[i]:SetText(string.sub(_G['RAID_BUFF_'..i],0,2)) + + if not self.raidbuffs_display[i] or self.raidbuffs_display[i] ~= k then + self.raidbuffs_display[i] = k + local axis_a, axis_b = c.icon_size, c.width + local w = axis_a * (k-1) % axis_b + local h = math.floor((k-1) / (axis_b / axis_a)) * axis_a + print(axis_a, axis_b, w, h) + rb:SetPoint('BOTTOMLEFT', TkRaidWatch, 'BOTTOMLEFT', w, h) + end + + k = k + 1 + end + end +end + +function mod:RosterScan() + local lim = 1 + if IsInRaid() then + lim = 40 + elseif IsInGroup() then + lim = 5 + end + + for i = 1, lim do + local name, rank, subgroup, level, class, fileName, zone, online, isDead, role, isML = GetRaidRosterInfo(i) + if name then + if string.find(name,'-') then + name, realm = string.match(name, "(.+)-(.+)") + else + realm = GetRealmName() + end + + print(i, name, class, role) + end + + end + +end \ No newline at end of file diff -r ebbcc148a407 -r 766d8a40a1d6 Spirit.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Spirit.lua Tue Dec 15 08:07:21 2015 -0500 @@ -0,0 +1,276 @@ +-- User: Krakyn +-- Created: 12/8/2015 7:30 PM +local T = LibStub("AceAddon-3.0"):GetAddon("Turok") +local TL = 'Spirit' +local print = function(...) _G.print(TL, ...) end +local LSM = LibStub("LibSharedMedia-3.0") +local mod = T:NewModule("Spirit", "AceTimer-3.0") +local time = _G.ct +local auras = { + 168811, -- sniper training + 168809, -- sniper training: recently moved + 13159, -- aspect of the pack, + 187615, -- Maalus +} +local spells = { + 3045, -- rapid fire, + 26297, -- berserking, + 121818, -- stampede, + +} +local FRAME_PREFIX = 'TkSpirit' +local FADE_TIME = 0.5 +-- local repetitive tasks +local function FindSpirit(id) + local db = T.db + local c = db.spirit + local isIcon = false + if db.spirit.progressbar[id] then + c = db.spirit.progressbar[id] + elseif db.spirit.icon[id] then + c = db.spirit.icon[id] + isIcon = true + end + local name, rank, icon, castingTime, minRange, maxRange, spellID = GetSpellInfo(id) + local s = { + name = name, + rank = rank, + icon = icon, + castingTime = castingTime, + minRange = minRange, + maxRange = maxRange, + spellID = spellID + } + + return s, c, isIcon +end + +function mod:OnEnable() + local db = _G.TurokData + self.aura_watch = {} + self.cooldown_watch = {} + self.item_watch = {} + self.myGUID = UnitGUID('player') + + + db.spirit = { + foreground_color = {1, 1, 1, 0.7}, + foreground_texture = 'Cilo', + foreground_blend = 'BLEND', + foreground_inset = -1, + background_color = {0, 0, 0, 0.7}, + background_blend = 'BLEND', + background_texture = 'Cilo', + icon_show = true, + width = 250, height = 20, + anchor = 'CENTER', parent = 'UIParent', anchorTo = 'CENTER', + posX = 0, posY = -150, + label_color = {1, 1, 1, 1}, + label_font = 'turok', + label_size = 14, + label_inset = -2, + label_point = 'LEFT', + label_outline = 'OUTLINE', + label_string = '%n %p', + label_strata = 'HIGH', + expire_sound = LSM:Fetch('sound'), + strata = 'LOW', + icon = { + [13159] = { -- Aspect of the Pack + posX = 20, posY = 20, width = 140, height = 140, + }, + [3045] = { + parent = 13159, anchor = 'RIGHT', anchorTo = 'LEFT', + posx = 0, posY = 0, width = 64, height = 64, + } + }, + progressbar = { + [168811] = { -- Sniper Training (duration) + background_color = {0,0,0,0}, + foreground_color = {1,0,0,1}, + anchor = 'BOTTOMLEFT', parent = 'TkFocusBar', anchorTo = 'TOPLEFT', + posX = 0, posY = 0, height = 16, width = 250, + label_string = '', + label_point = 'TOPLEFT', + strata = 'LOW', + attach = {{ + width_relative = 0.5, + height_relative = 1, + background_color = {1,0,0,1}, + foreground_color = {1,1,0.5, 1}, + background_blend = 'ADD', + foreground_blend = 'ADD', + + anchor = 'LEFT', + anchorTo = 'LEFT', + strata = 'MEDIUM', + }} + }, + [168809] = { -- Sniper Training: Recently Moved + background_color = {0,0,0,0 }, + foreground_color = {1,1,1,1}, + foreground_blend = 'ADD', + anchor = 'BOTTOMLEFT', parent = 'TkFocusBar', anchorTo = 'TOPLEFT', + strata = 'HIGH', + posX = 0, posY = 0, height = 16, width = 125, + icon_show = false, + label_string = '', + exceptions = { + function(aura) + return (mod.aura_watch[168811].expires < aura.expires) + end + }, + }, + }, + } + + for _, id in pairs(auras) do + -- store spellinfo fetch + self.aura_watch[id] = self:CreateSpiritFrame(id) + self.aura_watch[id].count = 0 + self.aura_watch[id].duration = 0 + self.aura_watch[id].expires = 0 + self.aura_watch[id].caster = 0 + print('AURA', id, self.aura_watch[id].name) + end + + for _, id in ipairs(spells) do + self.cooldown_watch[id] = self:CreateSpiritFrame(id) + print('COOLDOWN', id, self.cooldown_watch[id].name) + end + + self:SpiritScan() + self:RegisterEvent('UNIT_AURA') + self:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED') + self:RegisterEvent('PLAYER_REGEN_DISABLED') + self:RegisterEvent('PLAYER_REGEN_ENABLED') +end + +-- StatusBar factory +function mod:CreateSpiritFrame(id) + local s, c, isIcon = FindSpirit(id) + + -- how much frame do we need? + local f + if isIcon then + f = CreateFrame('Frame', FRAME_PREFIX..id, UIParent) + f.db = c + function f:Update() end + else + f = T:CreateBar('TkAuraBar'..id, c) + f.isTimer = true + if (c.label_string ~= '') then + print('has label, add it', id) + T:AddLabel(f, c) + end + end + f:Hide() + + -- general display + f:SetPoint(c.anchor, c.parent, c.anchorTo, c.posX, c.posY) + f:SetSize(c.width, c.height) + f:SetFrameStrata(c.strata) + + -- icon? + f.icon = s.icon + T:CreateStatusIcon(f) + + -- attachment frames? + if c.attach then + for i, e in ipairs(c.attach) do + local ef = CreateFrame('Frame', 'TkExtra'..id, f) + f[i] = ef + ef:SetPoint(e.anchor, f, e.anchorTo) + ef:SetSize(c.width * e.width_relative or e.width, c.height * e.height_relative or e.height) + ef:SetFrameStrata(e.strata or c.strata) + T:CreateStatusTextures(ef, e) + end + end + + -- setup suppression checking + if c.exceptions then + function s:ExceptionCheck () + for i, func in ipairs(c.exceptions) do + if not func(self) then + return false, i + end + end + return true + end + else + function s:ExceptionCheck () return true end + end + + -- access linkage + f.format = c.label_string + f.spirit = s + f.name = s.name + s.frame = f + return s +end + +function mod:UNIT_AURA(e, unit) + if unit == 'player' then + self:SpiritScan() + end +end + +-- Updates aura watches +function mod:SpiritScan() + local db = _G.TurokData + for id, aura in pairs(self.aura_watch) do + local c = aura.conf + local f = aura.frame + + local name, _, _, count, _, duration, expires, caster = UnitAura('player', aura.name) + + if name then + aura.duration = duration + aura.expires = expires + aura.caster = caster + aura.count = count + local test, i = aura:ExceptionCheck() + print(name, duration, expires) + if not test then + print('suppressing '..aura.name..' (failed test #'..i..')') + else + f.name = name + f:Update(nil, duration, expires) + f:Show() + end + end + end +end + +function mod:PLAYER_REGEN_ENABLED() + for id, aura in pairs(self.aura_watch) do + print('non-combat alpha for #', id, aura.name, 'is', aura.frame.db.alpha_ooc) + aura.frame.fadeTo = aura.frame.db.alpha_ooc + aura.frame.fadeDuration = FADE_TIME + end +end + +function mod:PLAYER_REGEN_DISABLED() + for id, aura in pairs(self.aura_watch) do + print('combat alpha for #', id, aura.name, 'is', aura.frame.db.alpha) + aura.frame.fadeTo = aura.frame.db.alpha + aura.frame.fadeDuration = FADE_TIME + end +end + +-- This is the most reliable way of catching item and spell uses, other events are delayed or too vague to be useful +function mod:COMBAT_LOG_EVENT_UNFILTERED(e, ...) + local timestamp, combatEvent, hideCaster, sourceGUID, sourceName, sourceFlags, sourceRaidFlags, destGUID, destName, destFlags, destRaidFlags = + ...; -- Those arguments appear for all combat event variants. + local eventPrefix, eventSuffix = combatEvent:match("^(.-)_?([^_]*)$"); + if eventPrefix ~= 'SPELL_' or sourceGUID ~= self.myGUID then + return + end + + local spellid, name, count, type = select(13, select('#', ...), ...) + local kc = '' + for i=1,4 do + kc = kc .. string.format('%X',((string.byte(eventSuffix,i) % 8) + 8)) + end + print('|cFFFF'..kc..eventSuffix..'|r', sourceName, destName, spellid, name) +end \ No newline at end of file diff -r ebbcc148a407 -r 766d8a40a1d6 Tek.lua --- /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 + + + + diff -r ebbcc148a407 -r 766d8a40a1d6 Turok.iml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Turok.iml Tue Dec 15 08:07:21 2015 -0500 @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff -r ebbcc148a407 -r 766d8a40a1d6 Turok.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Turok.lua Tue Dec 15 08:07:21 2015 -0500 @@ -0,0 +1,152 @@ + +-- GLOBALS: DEFAULT_CHAT_FRAME, SlashCmdList, hash_SlashCmdList +local T = LibStub("AceAddon-3.0"):NewAddon("Turok", "AceConsole-3.0", "AceEvent-3.0") +local _G = _G +local rawset = _G.rawset +local time = GetTime() +_G.Turok = T +local print = function(...) + --_G.print('Core', ...) +end + + +T.mods = {} +T:SetDefaultModuleState(true) +T:SetDefaultModuleLibraries("AceEvent-3.0") +T:SetDefaultModulePrototype({OnInitialize = function(mod) + print('CORE', mod:GetName().. ' found') +end}) + +-- propagates parameter data around +function T:LinkTable(parent, child, pname, cname) + local mt = { + __index = function(t,k) + if parent[k] then + t[k] = parent[k] + end + print('|cFFFF8800'.. pname ..'.' .. cname .. '|r.|cFFFFFF00'.. k ..'|r inheriting value at |cFFFF8800' .. pname ..'|r.|cFFFFFF00'.. k..'|r') + return parent[k] + end, + __newindex = function (t, k, v) + rawset(t,k,v) + if type(v) == 'table' then + T:LinkTable(child, v, pname, k) + print('|cFFFF8800'.. pname ..'.' .. cname .. '|r.|cFFFFFF00'.. k ..'|r sub-table created') + end + end + } + print('|cFFFF8800'.. pname ..'.|cFFFFFF00'.. cname ..'|r sub-tables will be retconned') + setmetatable(child, mt) + for k, v in pairs(child) do + if type(v) == 'table' then + T:LinkTable(child, v, cname, k) + end + end +end + +function T:OnInitialize() + + local defaults = { + background_color = {0,0,0,0}, + background_blend = 'BLEND', + foreground_color = {1,1,1,0.5}, + foreground_blend = 'BLEND', + foreground_inset = -1, + width = 250, + height = 100, + alpha = 1, + alpha_ooc = 0.1, + strata = 'LOW', + label_strata = 'HIGH', + label_justifyH = 'LEFT', + label_color = {1, 1, 1, 1}, + label_font = 'turok', + label_size = 14, + label_inset = -2, + label_point = 'LEFT', + label_outline = 'OUTLINE', + anchor = 'CENTER', parent = 'UIParent', anchorTo = 'CENTER', + focusbar = { + foreground_color = {1, 1, 1, 0.7}, + background_color = {0,0,0,0.8}, + width = 300, height = 24, + posX = 0, posY = -150, + }, + } + _G.TurokData = defaults + if not _G.TurokData then + _G.TurokData = defaults + end + + T.db = _G.TurokData + local db = T.db + for k, v in pairs(db) do + if type(v) == 'table' then + T:LinkTable(db, v, 'db', k) + end + end + setmetatable(db, + {__newindex = function (t, k, v) + rawset(t,k,v) + if type(v) == 'table' then + T:LinkTable(db, v, 'db', k) + print('CFG', '|cFFFF0000db|r.|cFF00FFFF' .. k ..'|r created at bottom level') + end + end}) + + options = { + type = 'group', + name = 'Turok', + handler = T, + set = function(info,value) + local k = db[info[1]] + for i = 2, #info-1 do + if type(k[i]) ~= 'table' then + print('fart') + end + + k = k[i] + end + k[info[#info]] = value + end, + get = function(info) + local k = db[info[1]] + for i = 2, #info-1 do + if type(k[i]) ~= 'table' then + print('fart') + end + + k = k[i] + end + return k[info[#info]] + end, + desc = '"Dinosaur" Hunter', + args = { + background_color = { + type = 'color', + name = 'Background Color', + hasAlpha = true, + } + } + } + LibStub("AceConfig-3.0"):RegisterOptionsTable('Turok', options, {"tk"}) + +end + + +function T:OnEnable() + local db = _G.TurokData + + print('I... am Turok') + + self.stats = {} + + + T.focusbar = T:CreateBar('TkFocusBar', db.focusbar) + local fb = T.focusbar + T:AddLabel(fb, db.focusbar) + fb:Update(UnitPower("player"), 0, UnitPowerMax("player")) + T:Bar_SetUpdateHandler(fb, function(self) + T.Bar_Update(fb, UnitPower("player")) + end) +end diff -r ebbcc148a407 -r 766d8a40a1d6 readme.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/readme.txt Tue Dec 15 08:07:21 2015 -0500 @@ -0,0 +1,11 @@ +Turok: Dinosaur HUD + +Hardcode of various WeakAura configurations. This is created as a personal learning challenge, so it may or may not be faster than the actual jumble of WeakAuras because that addon is written very well. + +Project Goals: + + - Focus bar with dynamic coloring and prediction lines based on talent effects + - Unit cast bars that are thematically linked with everything else + - Dynamically arranged tracking icons and sliders cooldown/aura information + - Quality-of-life alerts for Lone Wolf and Aspect of the Pack +