/
## Interface: 20400 |
## Title: NaturCombat |
## Version: 9.0BETA2 |
## Author: Macca, Beladona |
## Notes: Enemy cast bars for cooldowns, buffs, debuffs and casts for both pvp and pve |
## OptionalDeps: LibStub, LibWombat, GTB-1.0, LibSharedMedia-3.0 |
## SavedVariables: NaturDB |
embed\LibStub\LibStub.lua |
embed\LibWombat\LibWombat.lua |
embed\GTB\GTB.xml |
embed\LibSharedMedia-3.0\LibSharedMedia-3.0.lua |
addon\spells.lua |
addon\spells\Druid.lua |
addon\spells\Rogue.lua |
addon\spells\Priest.lua |
addon\spells\Paladin.lua |
addon\spells\Hunter.lua |
addon\spells\Shaman.lua |
addon\spells\Mage.lua |
addon\spells\Warlock.lua |
addon\spells\Warrior.lua |
addon\generator.lua |
addon\parser.lua |
local addon = LibStub:GetLibrary("NaturCombat"); |
addon.spells[11305] = {duration=15,cooldown=300,type="BUFF"}; -- Sprint |
addon.spells[26669] = {duration=15,cooldown=300,type="BUFF"}; -- Evasion |
addon.spells[26889] = {duration=10,cooldown=210,type="BUFF"}; -- Vanish |
addon.spells[13877] = {duration=15,cooldown=120,type="BUFF"}; -- Blade Flurry |
addon.spells[13750] = {duration=15,cooldown=300,type="BUFF"}; -- Adren. Rush |
addon.spells[31224] = {duration=4,cooldown=60,type="BUFF"}; -- CloS |
addon.spells[36554] = {duration=10,cooldown=30,type="BUFF"}; -- Shadowstep |
addon.spells[26679] = {duration=5,type="DEBUFF"}; -- Deadly Throw |
addon.spells[2094] = {duration=10,type="DEBUFF",drcat="Cyclone"}; -- Blind |
addon.spells[8629] = {duration=4,talent={2,1,4,0.5,"ROGUE"},stun=true,type="DEBUFF",drcat="Disorient"}; -- Gouge |
addon.spells[8643] = {duration=6,combo=true,stun=true,type="DEBUFF",drcat="Kidney Shot"}; -- Kidney shot |
addon.spells[1833] = {duration=4,stun=true,type="DEBUFF",drcat="Stun"}; -- Cheapshot |
addon.spells[26867] = {duration=16,combo=true,dot=true,type="DEBUFF"}; -- Rupture |
addon.spells[8632] = {duration=18,dot=true,type="DEBUFF"}; -- Garrote |
addon.spells[2070] = {duration=45,pvpdur=10,stun=true,type="DEBUFF",drcat="Disorient"}; -- Sap |
addon.spells[26866] = {duration=30,type="DEBUFF"}; -- Expose Armor |
addon.spells[3420] = {duration=12,type="DEBUFF"}; -- Crip Poison |
addon.spells[3421] = {duration=12,type="DEBUFF"}; -- Crip Poison 2 |
addon.spells[13220] = {duration=15,stacks=true,type="DEBUFF"}; -- Wound |
addon.spells[13228] = {duration=15,stacks=true,type="DEBUFF"}; -- Wound |
addon.spells[13229] = {duration=15,stacks=true,type="DEBUFF"}; -- Wound |
addon.spells[13230] = {duration=15,stacks=true,type="DEBUFF"}; -- Wound |
addon.spells[27283] = {duration=15,stacks=true,type="DEBUFF"}; -- Wound |
addon.spells[5763] = {duration=10,type="DEBUFF"}; -- Mind |
addon.spells[8694] = {duration=10,type="DEBUFF"}; -- Mind |
addon.spells[11400] = {duration=10,type="DEBUFF"}; -- Mind |
addon.spells[2835] = {duration=12,stacks=true,dot=true,type="DEBUFF"}; -- Deadly |
addon.spells[2837] = {duration=12,stacks=true,dot=true,type="DEBUFF"}; -- Deadly |
addon.spells[11357] = {duration=12,stacks=true,dot=true,type="DEBUFF"}; -- Deadly |
addon.spells[11358] = {duration=12,stacks=true,dot=true,type="DEBUFF"}; -- Deadly |
addon.spells[25347] = {duration=12,stacks=true,dot=true,type="DEBUFF"}; -- Deadly |
addon.spells[26969] = {duration=12,stacks=true,dot=true,type="DEBUFF"}; -- Deadly |
addon.spells[27282] = {duration=12,stacks=true,dot=true,type="DEBUFF"}; -- Deadly |
local addon = LibStub:GetLibrary("NaturCombat"); |
addon.spells[18288] = {cooldown=180,instant=true,type="CAST"}; -- Amp. Curse |
addon.spells[18708] = {duration=15,cooldown=900,type="BUFF"}; -- Fel Domination |
addon.spells[34939] = {duration=8,type="BUFF"}; -- Backlash |
addon.spells[18095] = {duration=10,type="BUFF"}; -- Nightfall |
addon.spells[1094] = {duration=15,dot=true,type="DEBUFF"}; -- Immolate |
addon.spells[7651] = {duration=5,dot=true,type="DEBUFF"}; -- Drain Life |
addon.spells[27221] = {duration=5,dot=true,type="DEBUFF"}; -- Drain Mana |
addon.spells[7648] = {duration=18,dot=true,type="DEBUFF"}; -- Corruption |
addon.spells[6217] = {duration=25,dot=true,type="DEBUFF"}; -- CoA |
addon.spells[18880] = {duration=30,dot=true,type="DEBUFF"}; -- Siphon Life |
addon.spells[17962] = {duration=3,type="DEBUFF"}; -- Death Coil |
addon.spells[6213] = {duration=20,pvpdur=10,type="DEBUFF"}; -- Fear |
addon.spells[17928] = {duration=8,type="DEBUFF"}; -- HoT |
addon.spells[18223] = {duration=12,type="DEBUFF"}; -- CoE |
addon.spells[11719] = {duration=30,pvpdur=10,type="DEBUFF"}; -- CoT |
local addon = LibStub:GetLibrary("NaturCombat"); |
addon.spells[14327] = {cooldown=30,instant=true,type="CAST"}; -- Scare Beast |
addon.spells[3054] = {duraton=15,cooldown=300,type="BUFF"}; -- Rapid Fire |
addon.spells[19263] = {duration=10,cooldown=300,type="BUFF"}; -- Deterrence |
addon.spells[34692] = {duration=18,cooldown=120,type="BUFF"}; -- The Beast Within |
addon.spells[19574] = {duration=18,cooldown=120,type="BUFF"}; -- Beasial Wrath |
addon.spells[14268] = {duration=10,type="DEBUFF"}; -- Wing Clip |
addon.spells[19233] = {duration=5,type="DEBUFF"}; -- Wing Clip Improved |
addon.spells[27018] = {duration=8,dot=true,type="DEBUFF"}; -- Viper Sting |
addon.spells[20904] = {duration=10,type="DEBUFF"}; -- Aimed Shot |
addon.spells[34490] = {duration=3,type="DEBUFF"}; -- Silencing Shot |
addon.spells[25295] = {duration=15,dot=true,type="DEBUFF"}; -- Serpent Sting |
addon.spells[14311] = {duration=20,pvpdur=10,type="DEBUFF"}; -- Freezing Trap |
addon.spells[19503] = {duration=4,type="DEBUFF"}; -- Scatter Shot |
local addon = LibStub:GetLibrary("NaturCombat"); |
addon.spells[2687] = {duration=10,cooldown=60,type="BUFF"}; -- Bloodrage |
addon.spells[18499] = {duration=10,cooldown=30,type="BUFF"}; -- Berserker Rage |
addon.spells[12292] = {duration=30,cooldown=180,type="BUFF"}; -- Deathwish |
addon.spells[23920] = {duration=5,cooldown=10,type="BUFF"}; -- Spell Reflection |
addon.spells[29838] = {duration=10,type="BUFF"}; -- Second Wind |
addon.spells[25212] = {duration=10,type="DEBUFF"}; -- Hamstring |
addon.spells[23695] = {duration=5,type="DEBUFF"}; -- Imp. HS |
addon.spells[12323] = {duration=6,type="DEBUFF"}; -- P. Howl |
addon.spells[5246] = {duration=8,type="DEBUFF"}; -- Itim. Shout |
addon.spells[30330] = {duration=10,type="DEBUFF"}; -- MS |
addon.spells[25225] = {duration=30,stacks=true,type="DEBUFF"}; -- Sunder Armor |
addon.spells[43104] = {duration=12,dot=true,type="DEBUFF"}; -- Deep Wound |
addon.spells[25208] = {duration=21,dot=true,type="DEBUFF"}; -- Rend |
local addon = LibStub:GetLibrary("NaturCombat"); |
addon.spells[25221] = {duration=15,type="BUFF"}; -- Renew |
addon.spells[19275] = {duration=15,cooldown=180,type="BUFF"}; -- Feedback |
addon.spells[10060] = {duration=15,cooldown=180,type="BUFF"}; -- Power Infusion |
addon.spells[25218] = {duration=30,cooldown=15,type="BUFF"}; -- PW: Shield |
addon.spells[14751] = {cooldown=180,instant=true,type="CAST"}; -- Inner Focus |
addon.spells[33206] = {duration=8,cooldown=120,type="BUFF"}; -- Pain Suppression |
addon.spells[25368] = {duration=18,type="DEBUFF"}; -- SW: Pain |
addon.spells[32996] = {cooldown=12,instant=true,type="CAST"}; -- SW: Death |
addon.spells[25375] = {cooldown=8,instant=true,type="CAST"}; -- Mind blast |
addon.spells[34433] = {duration=15,cooldown=300,instant=true,type="CAST"}; -- Shadowfiend |
addon.spells[10890] = {duration=8,cooldown=27,instant=true,type="CAST"}; -- Fear |
local addon = LibStub:GetLibrary("NaturCombat"); |
addon.spells[33831] = {cooldown=180,instant=true,type="CAST"}; -- Force of Nature |
addon.spells[26980] = {duration=21,type="BUFF"}; -- Regrowth |
addon.spells[33357] = {duration=15,cooldown=300,type="BUFF"}; -- Dash |
addon.spells[22812] = {duration=12,cooldown=60,type="BUFF"}; -- Barkskin |
addon.spells[29166] = {duration=20,cooldown=360,type="BUFF"}; -- Innervate |
addon.spells[26999] = {duration=10,cooldown=180,type="BUFF"}; -- Frenzied Regeneration |
addon.spells[25299] = {duration=12,type="BUFF"}; -- Rejuvenation |
addon.spells[2893] = {duration=7,type="BUFF"}; -- Abolish Poison |
addon.spells[27009] = {duration=45,cooldown=60,type="BUFF"}; -- Nature's Grasp |
addon.spells[33763] = {duration=7,stacks=true,type="BUFF"}; -- Lifebloom |
addon.spells[17116] = {cooldown=180,instant=true,type="CAST"}; -- Nature's Swiftness |
addon.spells[33786] = {duration=6,type="DEBUFF",drcat="Cyclone"}; -- Cyclone |
addon.spells[26989] = {duration=45,pvpdur=10,type="DEBUFF",drcat="Root"}; -- Entangling Roots |
addon.spells[27013] = {duration=12,dot=true,type="DEBUFF"}; -- Insect Swarm |
addon.spells[18658] = {duration=40,pvpdur=10,type="DEBUFF",drcat="SLeep"}; -- Hibernate |
addon.spells[26993] = {duration=40,type="DEBUFF"}; -- Faeire Fire |
addon.spells[17392] = {duration=40,type="DEBUFF"}; -- Feral Faeire Fire |
addon.spells[9898] = {duration=30,type="DEBUFF"}; -- Demo. Roar |
addon.spells[33986] = {duration=12,type="DEBUFF"}; -- Mangle (Bear) |
addon.spells[33982] = {duration=12,type="DEBUFF"}; -- Mangle (Cat) |
addon.spells[45334] = {duration=4,type="DEBUFF"}; -- Feral Charge |
addon.spells[33745] = {duration=15,stacks=true,dot=true,type="DEBUFF"}; -- Lacerate |
addon.spells[9834] = {duration=12,dot=true,type="DEBUFF"}; -- Moonfire |
addon.spells[27008] = {duration=12,dot=true,type="DEBUFF"}; -- Rip |
addon.spells[1823] = {duration=9,dot=true,type="DEBUFF"}; -- Rake |
addon.spells[27006] = {duration=4,stun=true,combo=true,talent={2,4,4,0.5,"DRUID"},type="DEBUFF",drcat="Stun"}; -- Pounce |
addon.spells[27007] = {duration=18,dot=true,type="DEBUFF"}; -- Pounce Bleed |
addon.spells[22570] = {duration=7,stun=true,combo={1,7},type="DEBUFF",drcat="Disorient"}; -- Maim |
addon.spells[6798] = {duration=5,stun=true,talent={2,4,5,0.5,"DRUID"},type="DEBUFF",drcat="Stun"}; -- Bash |
local addon = LibStub:GetLibrary("NaturCombat"); |
addon.spells[32182] = {duration=30,cooldown=600,type="BUFF"}; -- Heroism |
addon.spells[2825] = {duration=30,cooldown=600,type="BUFF"}; -- Bloodlust |
addon.spells[25464] = {duration=8,type="DEBUFF"}; -- Frost Shock |
addon.spells[25457] = {duration=12,type="DEBUFF"}; -- Flame Shock |
addon.spells[25442] = {cooldown=6,type="CAST"}; -- CLightning |
addon.spells[16190] = {duration=12,cooldown=300,instant=true,type="CAST"}; -- Mana Tide Totme |
local addon = LibStub:GetLibrary("NaturCombat"); |
addon.spells[1020] = {duration=12,cooldown=300,type="BUFF"}; -- Divine Shield |
addon.spells[10278] = {duration=10,cooldown=300,type="BUFF"}; -- BoP |
addon.spells[1044] = {duration=16,cooldown=25,type="BUFF"}; -- BoF |
addon.spells[27184] = {duration=30,type="BUFF"}; -- BoS |
addon.spells[20059] = {duration=30,stacks=true,type="BUFF"}; -- Vengeance |
addon.spells[31884] = {duration=20,cooldown=180,type="BUFF"}; -- Avenging Wrath |
addon.spells[31842] = {duration=15,cooldown=180,type="BUFF"}; -- Divine Illumination |
addon.spells[20216] = {cooldown=120,instant=true,type="CAST"}; -- Divine Favor |
addon.spells[10308] = {duration=5,stun=true,type="DEBUFF"}; -- HoJ |
addon.spells[27180] = {cooldown=6,instant=true,type="CAST"}; -- HoW |
local addon = LibStub:GetLibrary("NaturCombat"); |
addon.spells[10225] = {duration=30,type="BUFF"}; -- Fire Ward |
addon.spells[32796] = {duration=30,type="BUFF"}; -- Frost Ward |
addon.spells[12051] = {duration=8,cooldown=480,type="BUFF"}; -- Evocation |
addon.spells[45438] = {duration=10,cooldown=300,type="BUFF"}; -- Ice Block |
addon.spells[33405] = {duration=30,type="BUFF"}; -- Ice Barrier |
addon.spells[66] = {duration=8,cooldown=300,type="BUFF"}; -- Invisibility |
addon.spells[12043] = {cooldown=180,instant=true,type="CAST"}; -- Pressence of Mind |
addon.spells[12472] = {duraton=20,cooldown=180,type="BUFF"}; -- Icy Veins |
addon.spells[31642] = {duration=8,type="BUFF"}; -- Blazing Speed |
addon.spells[12042] = {duration=15,cooldown=180,type="BUFF"}; -- Arcane Power |
addon.spells[33042] = {duration=3,type="DEBUFF"}; -- Dragon's Breath |
addon.spells[27088] = {duration=8,type="DEBUFF"}; -- Frost Nova |
addon.spells[12497] = {duration=5,type="DEBUFF"}; -- Frostbite |
addon.spells[10161] = {duration=8,type="DEBUFF"}; -- Cone of Cold |
addon.spells[28594] = {duration=15,stacks=true,type="DEBUFF"}; -- Winter's Chill |
addon.spells[22959] = {duration=30,stacks=true,type="DEBUFF"}; -- Fire Vulnerability |
addon.spells[12359] = {duration=2,stun=true,type="DEBUFF"}; -- Impact |
addon.spells[12825] = {duration=50,pvpdur=10,type="DEBUFF",drcat="Disorient"}; -- Polymorph |
addon.spells[28272] = {duration=50,pvpdur=10,type="DEBUFF",drcat="Disorient"}; -- Polymorph: Pig |
addon.spells[28271] = {duration=40,pvpdur=10,type="DEBUFF",drcat="Disorient"}; -- Polymorph: Turtle |
addon.spells[30942] = {duration=9,type="DEBUFF"}; -- Frostbolt |
addon.spells[1953] = {cooldown=15,instant=true,type="CAST"}; -- blink |
addon.spells[31687] = {duration=45,cooldown=180,instant=true,type="CAST"}; -- Water Ele |
addon.spells[11985] = {cooldown=600,instant=true,type="CAST"}; -- Cold Snap |
local addon = LibStub:NewLibrary("NaturCombat",20080514); |
assert(addon,"NaturCombatTimers failed to load in 'NaturCombatTimers\addon\spells.lua' on line 1"); |
---------------------------------------------------------------------------------------------------- |
addon.spelldata = {}; -- lookup table used for data storage, stored by spellid |
addon.spellkeys = {}; -- lookup table used for spell names that default to a spellid |
addon.spellmeta = {}; |
addon.spellmeta.__newindex = function(tbl,key,value) |
local name = GetSpellInfo(key); |
if (not addon.spelldata[key]) then addon.spelldata[key] = value; end |
if (not addon.spellkeys[name]) then addon.spellkeys[name] = key; end |
end; |
addon.spellmeta.__index = function(tbl,key) |
local name,rank,icon,_,_,_,castTime = GetSpellInfo(key); |
if (not addon.spelldata[key]) then key = addon.spellkeys[name]; end |
local data = addon.spelldata[key] or {}; |
data.id, data.name, data.rank, data.icon, data.castTime = key, name, rank, icon, castTime/1000; |
return data; |
end; |
addon.spells = setmetatable({},addon.spellmeta); |
function addon:GetSpellData(id) |
if (id) then return addon.spells[id]; end |
end; |
---------------------------------------------------------------------------------------------------- |
-- RACIALS |
addon.spells[20600] = {duration=20,cooldown=180,type="BUFF"}; -- Perception |
addon.spells[7744] = {duration=5,cooldown=120,type="BUFF"}; -- Will of the Forsaken |
addon.spells[20594] = {duration=8,cooldown=180,type="BUFF"}; -- Stoneform |
addon.spells[26297] = {duration=10,cooldown=180,type="BUFF"}; -- Berseking |
addon.spells[28880] = {duration=15,cooldown=180,type="BUFF"}; -- Gift of the Naaru |
addon.spells[20549] = {duration=2,type="DEBUFF"}; -- War Stomp |
addon.spells[25467] = {duration=24,dot=true,type="DEBUFF"}; -- Devouring Plague |
addon.spells[25446] = {duration=15,dot=true,type="DEBUFF"}; -- Starshards |
-- Misc. |
addon.spells[5530] = {duration=3,stun=true,type="DEBUFF"}; -- Mace Stun |
local addon = LibStub:GetLibrary("NaturCombat"); |
assert(addon,"NaturCombat failed to load in 'NaturCombat\addon\generator.lua' on line 1"); |
addon.bar = LibStub:GetLibrary("GTB-1.0"); |
assert(addon.bar,"GTB-1.0 failed to load in 'NaturCombat\addon\generator.lua' on line 3"); |
addon.media = LibStub:GetLibrary("LibSharedMedia-3.0"); |
assert(addon.media, "LibSharedMedia-3.0 failed to load in 'NaturCombat\addon\generator.lua' on line 5"); |
---------------------------------------------------------------------------------------------------- |
addon.colors = {}; |
addon.colors["HOSTILECAST"] = {r = 1, g = 0, b = 0}; |
addon.colors["FRIENDLYCAST"] = {r = 0, g= 1, b = 0}; |
addon.colors["COOLDOWN"] = {r = 0, g = 0, b = 1}; |
addon.colors["HOSTILEBUFF"] = {r = 0.5, g = 0, b = 0.65}; |
addon.colors["FRIENDLYBUFF"] = {r = 1, g = 0, b = 1}; |
addon.colors["STUN"] = {r = 0.5, g = 0.2, b = 0.1}; |
addon.colors["DOT"] = {r = 0, g = 0.8, b = 0.8}; |
addon.colors["DEBUFF"] = {r = 0.8, g = 0.8, b = 0}; |
---------------------------------------------------------------------------------------------------- |
addon.media:Register("statusbar", "NaturGlaze", [[Interface\AddOns\NaturCombat\media\glaze]]); |
---------------------------------------------------------------------------------------------------- |
addon.media:Register("sound", "First Blood", [[Interface\AddOns\NaturCombat\media\sounds\firstblood.mp3]]); |
addon.media:Register("sound", "Dominating", [[Interface\AddOns\NaturCombat\media\sounds\dominating.mp3]]); |
addon.media:Register("sound", "Killing Spree", [[Interface\AddOns\NaturCombat\media\sounds\killingspree.mp3]]); |
addon.media:Register("sound", "Unstoppable", [[Interface\AddOns\NaturCombat\media\sounds\unstoppable.mp3]]); |
addon.media:Register("sound", "Monster Kill", [[Interface\AddOns\NaturCombat\media\sounds\monsterkill.mp3]]); |
addon.media:Register("sound", "Godlike", [[Interface\AddOns\NaturCombat\media\sounds\godlike.mp3]]); |
---------------------------------------------------------------------------------------------------- |
-- This is to deal with realm names from cross realm battlegroups |
function addon:StripName(name) |
name = string.match(name, "[^-]*"); |
return name; |
end |
---------------------------------------------------------------------------------------------------- |
local f = CreateFrame("Frame", nil, InterfaceOptionsFrame) |
f:SetScript("OnShow", function(self) LoadAddOn("NaturOptions"); self:SetScript("OnShow", nil) end); |
SlashCmdList["NaturCombat"] = function() |
if (LoadAddOn("NaturOptions")) then |
InterfaceOptionsFrame_OpenToFrame("NaturCombat"); |
end |
end; |
SLASH_NaturCombat1 = "/necb"; |
SLASH_NaturCombat2 = "/natur"; |
local addon = LibStub:GetLibrary("NaturCombat"); |
assert(addon,"NaturCombatTimers failed to load in 'NaturCombat\addon\parser.lua' on line 1"); |
LibStub:GetLibrary("LibWombat"):NewParser(addon); |
assert(addon.StartParsing,"LibWombat failed to load in 'NaturCombat\addon\parser.lua' on line 3"); |
NaturDB = NaturDB or {Height=20,Width=270,Scale=1,FontSize=15,MaxBars=10,Lock=true,Growth="UP",Invert=true,Texture="NaturGlaze",Cooldowns=true,Diminishing=true}; |
addon.factor = 1; |
local CPAura, KillCounter, KillTimer = false, 0; |
local expTime, activeDR = {}, {}; |
local CDTable = {}; |
---------------------------------------------------------------------------------------------------- |
addon:StartParsing("VARIABLES_LOADED", function() |
addon.group = addon.bar:RegisterGroup("NaturCombat", addon.media:Fetch("statusbar", NaturDB.Texture)); |
addon.group:SetScale(NaturDB.Scale); |
addon.group:SetWidth(NaturDB.Width); |
addon.group:SetHeight(NaturDB.Height); |
addon.group:SetDisplayGroup("NaturCombat"); -- This redirects every bar to this certain group. |
addon.group:SetAnchorVisible(NaturDB.Lock); |
addon.group:SetGroupFontSize(NaturDB.FontSize); |
addon.group:SetMaxBars(NaturDB.MaxBars); |
addon.group:SetBarGrowth(NaturDB.Growth); |
addon.group:SetInvert(NaturDB.Invert); |
addon.group:SetPoint("CENTER"); |
addon.group:RegisterOnFade(addon, "OnFade"); |
end); |
---------------------------------------------------------------------------------------------------- |
addon:StartParsing("PLAYER_ENTERING_WORLD", function() |
local _, z = IsInInstance(); |
if (z == "arena") then -- Player is in an arena, clean bars |
addon.group:UnregisterAllBars(); |
end |
end); |
---------------------------------------------------------------------------------------------------- |
addon:StartParsing("SPELL_AURA_APPLIED", function(when,what,srcGUID,srcName,srcFlags,dstGUID,dstName,dstFlags,...) |
local spell = addon:GetSpellData(...); |
if (dstGUID == UnitGUID("target") or dstGUID == UnitGUID("focus")) and (dstGUID ~= UnitGUID("player")) then |
if (spell) and (spell.duration) then |
-- Talents? |
if (spell.talent) then |
if (spell.talent[5] == select(2,UnitClass("player"))) then |
local _, _, _, _, rank = GetTalentInfo(spell.talent[1], spell.talent[2]); |
if (rank) and (rank > 0) then |
spell.duration = spell.talent[3] + rank * spell.talent[4]; |
end |
end |
end |
-- Set Bar Color |
local color; |
if (spell.type == "BUFF") then |
if (CombatLog_Object_IsA(dstFlags, COMBATLOG_FILTER_HOSTILE_PLAYERS)) then |
color = addon.colors["HOSTILEBUFF"]; |
elseif (CombatLog_Object_IsA(dstFlags, COMBATLOG_FILTER_FRIENDLY_UNITS)) then |
color = addon.colors["FRIENDLYBUFF"]; |
end |
elseif (spell.type == "DEBUFF") then |
if (spell.stun) then |
color = addon.colors["STUN"]; |
elseif (spell.dot) then |
color = addon.colors["DOT"]; |
else |
color = addon.colors["DEBUFF"]; |
end |
end |
-- PVP Duration? |
local duration = 1; |
local guid = strsub(dstGUID, 1 ,5); |
if (spell.pvpdur) and (bit.band(guid, 0x00F) == 0) then -- Player? |
duration = spell.pvpdur; |
else |
duration = spell.duration; |
end |
-- DR? |
if (spell.drcat) and (NaturDB.Diminishing) then |
addon:ApplyDiminish(spell.id, dstName, dstGUID); |
duration = duration * addon.factor; |
end |
-- Combo? |
if (spell.combo) then CPAura = true; end |
local text = spell.name .. " - " .. addon:StripName(dstName); |
addon.group:RegisterBar(dstGUID..spell.id, text, duration, nil, spell.icon, color.r, color.g, color.b); |
end |
end |
end); |
---------------------------------------------------------------------------------------------------- |
-- Deal with cooldowns and instant casts |
-- Add cooldown to the CDTable so we can remove/show on target change |
addon:StartParsing("SPELL_CAST_SUCCESS", function(when,what,srcGUID,srcName,srcFlags,dstGUID,dstName,dstFlags,...) |
local spell = addon:GetSpellData(...); |
if (srcGUID == UnitGUID("player")) then return; end |
if (srcGUID == UnitGUID("target")) then --We don't want to show cooldowns for our focus.. maybe change this if someone requests it. |
if (spell) and (spell.cooldown) then |
if (spell.type == "CAST") and (spell.instant) then |
if (spell.duration) then |
local color; |
if (CombatLog_Object_IsA(srcFlags, COMBATLOG_FILTER_HOSTILE_PLAYERS)) then |
color = addon.colors["HOSTILEBUFF"]; |
elseif (CombatLog_Object_IsA(srcFlags, COMBATLOG_FILTER_FRIENDLY_UNITS)) then |
color = addon.colors["FRIENDLYBUFF"]; |
end |
local text = spell.name .. " - " .. addon:StripName(srcName); |
addon.group:RegisterBar(srcGUID..spell.id, text, spell.duration, nil, spell.icon, color.r, color.g, color.b); |
end |
if (NaturDB.Cooldowns) then |
local color = addon.colors["COOLDOWN"]; |
local text = spell.name .. " [CD] - " .. addon:StripName(srcName); |
addon.group:RegisterBar(srcGUID..spell.id.."CD", text, spell.cooldown, nil, spell.icon, color.r, color.g, color.b); |
--Add to CDTable |
CDTable[srcGUID..spell.id.."CD"] = {srcGUID,spell.cooldown}; |
end |
elseif (spell.type == "BUFF") then |
if (NaturDB.Cooldowns) then |
local color = addon.colors["COOLDOWN"]; |
local text = spell.name .. " [CD] - " .. addon:StripName(srcName); |
addon.group:RegisterBar(srcGUID..spell.id.."CD", text, spell.cooldown, nil, spell.icon, color.r, color.g, color.b); |
-- Add to DB |
CDTable[srcGUID..spell.id.."CD"] = {srcGUID,spell.cooldown}; |
end |
end |
end |
end |
end); |
---------------------------------------------------------------------------------------------------- |
addon:StartParsing("SPELL_AURA_REMOVED", function(when,what,srcGUID,srcName,srcFlags,dstGUID,dstName,dstFlags,...) |
local spell = addon:GetSpellData(...); |
if (spell) and (spell.duration) then |
if (spell.combo) then CPAura = false; end |
if (spell.drcat) then |
addon:RemoveDiminish(spell.id, dstName, dstGUID); |
end |
addon.group:UnregisterBar(dstGUID..spell.id); |
end |
end); |
---------------------------------------------------------------------------------------------------- |
addon:StartParsing("SPELL_AURA_DISPELLED", function(when,what,srcGUID,srcName,srcFlags,dstGUID,dstName,dstFlags,...) |
local spell = addon:GetSpellData(select(12, ...)); |
if (spell) and (spell.duration) then |
addon.group:UnregisterBar(dstGUID..spell.id); |
end |
end); |
---------------------------------------------------------------------------------------------------- |
addon:StartParsing("SPELL_INTERRUPT", function(when,what,srcGUID,srcName,srcFlags,dstGUID,dstName,dstFlags,...) |
local spell = addon:GetSpellData(select(12, ...)); |
if (spell) and (spell.duration) then |
addon.group:UnregisterBar(dstGUID..spell.id); |
end |
end); |
---------------------------------------------------------------------------------------------------- |
addon:StartParsing("SPELL_MISSED", function(when,what,srcGUID,srcName,srcFlags,dstGUID,dstName,dstFlags,...) |
local spell = addon:GetSpellData(...); |
if (spell) and (spell.duration) then |
addon.group:UnregisterBar(dstGUID..spell.id); |
end |
end); |
---------------------------------------------------------------------------------------------------- |
addon:StartParsing("SPELL_AURA_APPLIED_DOSE", function(when,what,srcGUID,srcName,srcFlags,dstGUID,dstName,dstFlags,...) |
local spell = addon:GetSpellData(...); |
local stack = select(5, ...); |
if (dstGUID == UnitGUID("player")) then return; end |
if (dstGUID == UnitGUID("target")) or (dstGUID == UnitGUID("focus")) then |
if (spell) and (spell.stacks) and (spell.duration) then |
local text = "(" .. stack .. ") " .. spell.name .. " - " .. addon:StripName(dstName); |
addon.group:SetBarText(dstGUID..spell.id, text); |
addon.group:SetTime(dstGUID..spell.id, spell.duration); |
end |
end |
end); |
---------------------------------------------------------------------------------------------------- |
addon:StartParsing("SPELL_AURA_REMOVED_DOSE", function(when,what,srcGUID,srcName,srcFlags,dstGUID,dstName,dstFlags,...) |
local spell = addon:GetSpellData(...); |
local stack = select(5, ...); |
if (dstGUID == UnitGUID("player")) then return; end |
if (dstGUID == UnitGUID("target")) or (dstGUID == UnitGUID("focus")) then |
if (spell) and (spell.stacks) and (spell.duration) then |
local text = "(" .. stack .. ") " .. spell.name .. " - " .. addon:StripName(dstName); |
addon.group:SetBarText(dstGUID..spell.id, text); |
end |
end |
end); |
---------------------------------------------------------------------------------------------------- |
addon:StartParsing("UNIT_DIED", function(when,what,srcGUID,srcName,srcFlags,dstGUID,dstName,dstFlags,...) |
if (dstGUID == UnitGUID("player")) then return; end |
for k, v in pairs(addon.spelldata) do |
addon.group:UnregisterBar(dstGUID..k); |
addon.group:UnregisterBar(dstGUID..k.."CD"); |
if (addon.spelldata[k].drcat) then |
addon.group:UnregisterBar(dstGUID..addon.spelldata[k].drcat); |
end |
end |
end); |
---------------------------------------------------------------------------------------------------- |
addon:StartParsing("UNIT_SPELLCAST_START", function(unitid, spell, ...) |
if (UnitGUID(unitid) == UnitGUID("player")) then return; end |
if (unitid == "target" and spell) or (unitid == "focus" and spell) then |
local color; |
if (UnitReaction(unitid, "player") < 4) then -- Hostile |
color = addon.colors["HOSTILECAST"]; |
else |
color = addon.colors["FRIENDLYCAST"]; |
end |
local icon, sTime, eTime = select(4, UnitCastingInfo(unitid)); |
local text = spell .. " - " .. addon:StripName(UnitName(unitid)); |
sTime, eTime = sTime/1000, eTime/1000; |
addon.group:RegisterBar(UnitGUID(unitid).."cast", text, eTime - sTime, nil, icon, color.r, color.g, color.b); |
end |
end); |
addon:StartParsing("UNIT_SPELLCAST_STOP", function(unitid, ...) -- This is suppose to return the spellname yet fails to do so.. |
if (UnitGUID(unitid) == UnitGUID("player")) then return; end |
if (unitid == "target") or (unitid == "focus") then |
addon.group:UnregisterBar(UnitGUID(unitid).."cast"); |
end |
end); |
---------------------------------------------------------------------------------------------------- |
addon:StartParsing("UNIT_SPELLCAST_CHANNEL_START", function(unitid, spell, ...) |
if (UnitGUID(unitid) == UnitGUID("player")) then return; end |
if (unitid == "target" and spell) or (unitid == "focus" and spell) then |
local color; |
if (UnitReaction(unitid, "player") < 4) then -- Hostile |
color = addon.colors["HOSTILECAST"]; |
else |
color = addon.colors["FRIENDLYCAST"]; |
end |
local icon, sTime, eTime = select(4, UnitChannelInfo(unitid)); |
local text = spell .. " - " .. addon:StripName(UnitName(unitid)); |
sTime, eTime = sTime/1000, eTime/1000; |
addon.group:RegisterBar(UnitGUID(unitid).."channel", text, eTime - sTime, nil, icon, color.r, color.g, color.b); |
end |
end); |
---------------------------------------------------------------------------------------------------- |
addon:StartParsing("UNIT_SPELLCAST_CHANNEL_STOP", function(unitid, spell, ...) |
if (UnitGUID(unitid) == UnitGUID("player")) then return; end |
if (unitid == "target") or (unitid == "focus") then |
addon.group:UnregisterBar(UnitGUID(unitid).."channel"); |
end |
end); |
---------------------------------------------------------------------------------------------------- |
-- NOTE: There has to be a better way to deal with combo point abilites :/ |
addon:StartParsing("UNIT_AURA", function(unitid) |
if (UnitGUID(unitid) == UnitGUID("player")) then return; end |
if (unitid == "target") or (unitid == "focus") then |
local name, duration; |
if (not CPAura) then return; end |
local id = 0; |
while (true) do |
id = id + 1; |
name, _, _, _, _, duration = UnitDebuff(unitid, id); |
if (not name) then break; end |
if (addon.spellkeys[name]) then |
if (addon.spelldata[addon.spellkeys[name]].combo) and (addon.spelldata[addon.spellkeys[name]].duration) then |
local text = name .. " - " .. addon:StripName(UnitName(unitid)); |
if (not duration) then |
duration = addon.spelldata[addon.spellkeys[name]].duration; |
end |
addon.group:SetTime(UnitGUID(unitid)..addon.spelldata[addon.spellkeys[name]].id, duration); |
CPAura = false; |
end |
end |
end |
end |
end); |
---------------------------------------------------------------------------------------------------- |
addon:StartParsing("PLAYER_TARGET_CHANGED", function() |
-- Remove CD's from old target |
for id, cooldown in pairs(CDTable) do |
if (UnitGUID("target") ~= cooldown[1]) then |
addon.group:HideBar(id); |
else |
addon.group:ShowBar(id, cooldown[2]); |
end |
end |
end); |
---------------------------------------------------------------------------------------------------- |
addon:StartParsing("PARTY_KILL", function(when,what,srcGUID,srcName,srcFlags,dstGUID,dstName,dstFlags,...) |
local guid = strsub(dstGUID, 1, 5); |
if (srcGUID == UnitGUID("player")) and (bit.band(guid, 0x00F) == 0) then |
if (not KillTimer) or (GetTime() - KillTimer > 60) then |
PlaySoundFile(addon.media:Fetch("sound", "First Blood")); |
KillCounter = 0; |
elseif (GetTime() - KillTimer <= 60) then |
KillCounter = KillCounter + 1 |
if (KillCounter == 1) then |
PlaySoundFile(addon.media:Fetch("sound", "Dominating")); |
elseif (KillCounter == 2) then |
PlaySoundFile(addon.media:Fetch("sound", "Killing Spree")); |
elseif (KillCounter == 3) then |
PlaySoundFile(addon.media:Fetch("sound", "Unstoppable")); |
elseif (KillCounter == 4) then |
PlaySoundFile(addon.media:Fetch("sound", "Monster Kill")); |
elseif (KillCounter > 4) then |
PlaySoundFile(addon.media:Fetch("sound", "Godlike")); |
end |
end |
KillTimer = GetTime(); |
end |
end); |
---------------------------------------------------------------------------------------------------- |
-- TODO: Look over DR code and improve it. |
-- Massive thanks to Shadowd the author of DR Tracker. |
function addon:ApplyDiminish(spellID, dstName, dstGUID) |
local spell = addon:GetSpellData(spellID); |
local id = dstGUID .. spell.drcat; |
local time = GetTime(); |
local diminished = 100; |
if (expTime[id] and expTime[id] >= time) then |
diminished = self:GetDR(activeDR[id]); |
addon.factor = select(3, self:GetDR(activeDR[id])); |
activeDR[id] = diminished; |
expTime[id] = GetTime() + 15; |
addon.group:UnregisterBar(id); |
elseif (not expTime[id] or expTime[id] <= time) then |
activeDR[id] = diminished; |
addon.factor = 1; |
expTime[id] = GetTime() + 15; |
end |
end; |
---------------------------------------------------------------------------------------------------- |
function addon:RemoveDiminish(spellId, dstName, dstGUID) |
local spell = addon:GetSpellData(spellId); |
local id = dstGUID .. spell.drcat; |
if (activeDR[id]) then |
local text = spell.name .. " [".. spell.drcat .." |cffff2020DR " .. select(2,addon:GetDR(activeDR[id])) .. "/3|r] - " .. addon:StripName(dstName); |
local color = addon.colors["COOLDOWN"]; |
addon.group:RegisterBar(id, text, 15, nil, spell.icon, color.r, color.g, color.b); |
end |
expTime[id] = GetTime() + 15; |
end; |
---------------------------------------------------------------------------------------------------- |
function addon:GetDR(dr) |
if (dr == 100) then |
return 50, 1, 0.5; |
elseif (dr == 50) then |
return 25, 2, 0.25; |
elseif (dr == 25) then |
return 0, "Immune! 3", 0; |
end |
end; |
---------------------------------------------------------------------------------------------------- |
function addon:OnFade(barid) |
if (CDTable[barid]) then |
CDTable[barid] = nil; |
end |
end; |
local wombat = LibStub:NewLibrary("LibWombat",200800512); |
assert(wombat,"LibWombat failed to load in 'LibWombat.lua' on line 1"); |
---------------------------------------------------------------------------------------------------- |
local watcher = getglobal("LibWombatWatcherFrame") or CreateFrame("Frame","LibWombatWatcherFrame"); |
watcher:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED"); |
-- Added events for NaturCombat |
watcher:RegisterEvent("PLAYER_ENTERING_WORLD"); |
watcher:RegisterEvent("VARIABLES_LOADED"); |
watcher:RegisterEvent("UNIT_SPELLCAST_START"); |
watcher:RegisterEvent("UNIT_SPELLCAST_STOP"); |
watcher:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START"); |
watcher:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP"); |
watcher:RegisterEvent("UNIT_AURA"); |
watcher:RegisterEvent("PLAYER_TARGET_CHANGED"); |
-- |
wombat.parser = wombat.parser or {}; |
local CleanParser = function() |
for event,list in pairs(wombat.parser) do |
local exists = false; |
for serial,callback in pairs(list) do exists = true; end |
if (not exists) then wombat.parser[event] = nil; end |
end |
end; |
---------------------------------------------------------------------------------------------------- |
---------------------------------------------------------------------------------------------------- |
function wombat:NewParser(target) |
function target:StartParsing(event,method) |
if (type(event) ~= "string") or (type(method) ~= "function") then return; end |
wombat.parser[event] = wombat.parser[event] or {}; |
wombat.parser[event][target] = method; |
end |
function target:StopParsing(event) |
if (not wombat.parser[event]) then return; end |
wombat.parser[event][target] = nil; |
CleanParser(); |
end |
function target:StopAllParsing(event) |
for event,list in pairs(wombat.parser) do |
if (list[target]) then wombat.parser[event][target] = nil; end |
end |
CleanParser(); |
end |
end |
---------------------------------------------------------------------------------------------------- |
watcher:SetScript("OnEvent",function(...) |
local event = select(2, ...); |
if (event == "COMBAT_LOG_EVENT_UNFILTERED") then |
local when,what = select(3,...); |
if (wombat.parser[what]) then |
local data = {select(5,...)}; |
for k,callback in pairs(wombat.parser[what]) do |
callback(when,what,unpack(data)); |
end |
end |
else |
if (wombat.parser[event]) then |
local data = {select(3, ...)}; |
for k, callback in pairs(wombat.parser[event]) do |
callback(unpack(data)); |
end |
end |
end |
end); |
## Interface: 20400 |
## Title: Lib: Wombat |
## Notes: Wombat is a Combat Watcher. It basically dispatches combat events that the author is interested in, and sends the resulting raw data to a callback handler of the author's choosing. |
## Version 1.0 |
## Author: Beladona |
## OptionalDeps: LibStub |
LibWombat.lua |
## Interface: 20100 |
## Title: Lib: LibStub |
## Notes: Universal Library Stub |
## Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel |
## X-Website: http://jira.wowace.com/browse/LS | http://www.wowace.com/wiki/LibStub |
## X-Category: Library |
## X-License: Public Domain |
LibStub.lua |
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info |
-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke |
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS! |
local LibStub = _G[LIBSTUB_MAJOR] |
if not LibStub or LibStub.minor < LIBSTUB_MINOR then |
LibStub = LibStub or {libs = {}, minors = {} } |
_G[LIBSTUB_MAJOR] = LibStub |
LibStub.minor = LIBSTUB_MINOR |
function LibStub:NewLibrary(major, minor) |
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)") |
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.") |
local oldminor = self.minors[major] |
if oldminor and oldminor >= minor then return nil end |
self.minors[major], self.libs[major] = minor, self.libs[major] or {} |
return self.libs[major], oldminor |
end |
function LibStub:GetLibrary(major, silent) |
if not self.libs[major] and not silent then |
error(("Cannot find a library instance of %q."):format(tostring(major)), 2) |
end |
return self.libs[major], self.minors[major] |
end |
function LibStub:IterateLibraries() return pairs(self.libs) end |
setmetatable(LibStub, { __call = LibStub.GetLibrary }) |
end |
--[[ |
Name: LibSharedMedia-3.0 |
Revision: $Revision: 66370 $ |
Author: Elkano (elkano@gmx.de) |
Inspired By: SurfaceLib by Haste/Otravi (troeks@gmail.com) |
Website: http:// |
Documentation: http://www.wowace.com/wiki/LibSharedMedia-3.0 |
SVN: http://svn.wowace.com/wowace/trunk/LibSharedMedia-3.0/ |
Description: Shared handling of media data (fonts, sounds, textures, ...) between addons. |
Dependencies: LibStub, CallbackHandler-1.0 |
License: LGPL v2.1 |
]] |
local MAJOR, MINOR = "LibSharedMedia-3.0", "$Revision: 66370 $" |
local lib = LibStub:NewLibrary(MAJOR, MINOR) |
if not lib then return end |
local _G = getfenv(0) |
local pairs = _G.pairs |
local type = _G.type |
local band = _G.bit.band |
local table_insert = _G.table.insert |
local table_sort = _G.table.sort |
local locale = GetLocale() |
local locale_is_western |
local LOCALE_MASK = 0 |
lib.LOCALE_BIT_koKR = 1 |
lib.LOCALE_BIT_zhCN = 2 |
lib.LOCALE_BIT_zhTW = 4 |
lib.LOCALE_BIT_western = 128 |
local function CallbackHandlerCleanup() |
for owner,list in pairs(lib.callbacks) do |
local exists = false; |
for event,method in pairs(list) do exists = true; end |
if (not exists) then lib.callbacks[owner] = nil; end |
end |
end |
local function CallbackHandlerRegister(owner,event,method,...) |
assert(type(event) == "string","LibShardMedia CallbackHandlerRegister (string expected for 'event')"); |
lib.callbacks[owner] = lib.callbacks[owner] or {}; |
lib.callbacks[owner][event] = method or nil; |
end |
local function CallbackHandlerUnregister(owner,event) |
if (not lib.callbacks[owner]) then return; end |
lib.callbacks[owner][event] = nil; |
CallbackHandlerCleanup(); |
end; |
local function CallbackHandlerFire(owner,event,...) |
if (not lib.callbacks[owner]) then return; end |
local callback = lib.callbacks[owner][event]; |
if (callback) then |
local data = {...}; |
callback(event,unpack(data)); |
end |
end |
local function CallbackHandlerCreate(owner) |
owner.Fire = CallbackHandlerFire; |
owner.RegisterCallback = CallbackHandlerRegister; |
owner.UnregisterCallback = CallbackHandlerUnregister; |
return owner; |
end |
lib.callbacks = lib.callbacks or CallbackHandlerCreate(lib) |
lib.DefaultMedia = lib.DefaultMedia or {} |
lib.MediaList = lib.MediaList or {} |
lib.MediaTable = lib.MediaTable or {} |
lib.MediaType = lib.MediaType or {} |
lib.OverrideMedia = lib.OverrideMedia or {} |
local defaultMedia = lib.DefaultMedia |
local mediaList = lib.MediaList |
local mediaTable = lib.MediaTable |
local overrideMedia = lib.OverrideMedia |
-- create mediatype constants |
lib.MediaType.BACKGROUND = "background" -- background textures |
lib.MediaType.BORDER = "border" -- border textures |
lib.MediaType.FONT = "font" -- fonts |
lib.MediaType.STATUSBAR = "statusbar" -- statusbar textures |
lib.MediaType.SOUND = "sound" -- sound files |
-- populate lib with default Blizzard data |
-- BACKGROUND |
if not lib.MediaTable.background then lib.MediaTable.background = {} end |
lib.MediaTable.background["Blizzard Low Health"] = [[Interface\FullScreenTextures\LowHealth]] |
lib.MediaTable.background["Blizzard Out of Control"] = [[Interface\FullScreenTextures\OutOfControl]] |
lib.MediaTable.background["Blizzard Tabard Background"] = [[Interface\TabardFrame\TabardFrameBackground]] |
lib.MediaTable.background["Solid"] = [[Interface\Buttons\WHITE8X8]] |
lib.MediaTable.background["Blizzard Tooltip"] = [[Interface\Tooltips\UI-Tooltip-Background]] |
-- BORDER |
if not lib.MediaTable.border then lib.MediaTable.border = {} end |
lib.MediaTable.border["None"] = [[Interface\None]] |
lib.MediaTable.border["Blizzard Dialog"] = [[Interface\DialogFrame\UI-DialogBox-Border]] |
lib.MediaTable.border["Blizzard Tooltip"] = [[Interface\Tooltips\UI-Tooltip-Border]] |
-- FONT |
if not lib.MediaTable.font then lib.MediaTable.font = {} end |
local SML_MT_font = lib.MediaTable.font |
if locale == "koKR" then |
LOCALE_MASK = lib.LOCALE_BIT_koKR |
-- |
SML_MT_font["êµµì ê¸ê¼´"] = [[Fonts\2002B.TTF]] |
SML_MT_font["기본 ê¸ê¼´"] = [[Fonts\2002.TTF]] |
SML_MT_font["ë°ë¯¸ì§ ê¸ê¼´"] = [[Fonts\K_Damage.TTF]] |
SML_MT_font["íì¤í¸ ê¸ê¼´"] = [[Fonts\K_Pagetext.TTF]] |
-- |
lib.DefaultMedia["font"] = "기본 ê¸ê¼´" -- someone from koKR please adjust if needed |
-- |
elseif locale == "zhCN" then |
LOCALE_MASK = lib.LOCALE_BIT_zhCN |
-- |
SML_MT_font["伤害æ°å"] = [[Fonts\ZYKai_C.ttf]] |
SML_MT_font["é»è®¤"] = [[Fonts\ZYKai_T.ttf]] |
SML_MT_font["è天"] = [[Fonts\ZYHei.ttf]] |
-- |
lib.DefaultMedia["font"] = "é»è®¤" -- someone from zhCN please adjust if needed |
-- |
elseif locale == "zhTW" then |
LOCALE_MASK = lib.LOCALE_BIT_zhTW |
-- |
SML_MT_font["æ示è¨æ¯"] = [[Fonts\bHEI00M.ttf]] |
SML_MT_font["è天"] = [[Fonts\bHEI01B.ttf]] |
SML_MT_font["å·å®³æ¸å"] = [[Fonts\bKAI00M.ttf]] |
SML_MT_font["é è¨"] = [[Fonts\bLEI00D.ttf]] |
-- |
lib.DefaultMedia["font"] = "é è¨" -- someone from zhTW please adjust if needed |
-- |
else |
LOCALE_MASK = lib.LOCALE_BIT_western |
locale_is_western = true |
-- |
SML_MT_font["Arial Narrow"] = [[Fonts\ARIALN.TTF]] |
SML_MT_font["Friz Quadrata TT"] = [[Fonts\FRIZQT__.TTF]] |
SML_MT_font["Morpheus"] = [[Fonts\MORPHEUS.TTF]] |
SML_MT_font["Skurri"] = [[Fonts\SKURRI.TTF]] |
-- |
lib.DefaultMedia.font = "Friz Quadrata TT" |
-- |
end |
-- STATUSBAR |
if not lib.MediaTable.statusbar then lib.MediaTable.statusbar = {} end |
lib.MediaTable.statusbar["Blizzard"] = [[Interface\TargetingFrame\UI-StatusBar]] |
lib.DefaultMedia.statusbar = "Blizzard" |
-- SOUND |
if not lib.MediaTable.sound then lib.MediaTable.sound = {} end |
lib.MediaTable.sound["None"] = [[Interface\Quiet.mp3]] -- Relies on the fact that PlaySound[File] doesn't error on non-existing input. |
lib.DefaultMedia.sound = "None" |
local function rebuildMediaList(mediatype) |
local mtable = mediaTable[mediatype] |
if not mtable then return end |
if not mediaList[mediatype] then mediaList[mediatype] = {} end |
local mlist = mediaList[mediatype] |
-- list can only get larger, so simply overwrite it |
local i = 0 |
for k in pairs(mtable) do |
i = i + 1 |
mlist[i] = k |
end |
table_sort(mlist) |
end |
function lib:Register(mediatype, key, data, langmask) |
if mediatype == lib.MediaType.FONT and ((langmask and band(langmask, LOCALE_MASK) == 0) or not (langmask or locale_is_western)) then return false end |
mediatype = mediatype:lower() |
if not mediaTable[mediatype] then mediaTable[mediatype] = {} end |
local mtable = mediaTable[mediatype] |
if mtable[key] then return false end |
mtable[key] = data |
rebuildMediaList(mediatype) |
self.callbacks:Fire(self, "LibSharedMedia_Registered", mediatype, key) |
return true |
end |
function lib:Fetch(mediatype, key, noDefault) |
local mtt = mediaTable[mediatype] |
local overridekey = overrideMedia[mediatype] |
local result = mtt and ((overridekey and mtt[overridekey] or mtt[key]) or (not noDefault and defaultMedia[mediatype] and mtt[defaultMedia[mediatype]])) or nil |
return result |
end |
function lib:IsValid(mediatype, key) |
return mediaTable[mediatype] and (not key or mediaTable[mediatype][key]) and true or false |
end |
function lib:HashTable(mediatype) |
return mediaTable[mediatype] |
end |
function lib:List(mediatype) |
if not mediaTable[mediatype] then |
return nil |
end |
if not mediaList[mediatype] then |
rebuildMediaList(mediatype) |
end |
return mediaList[mediatype] |
end |
function lib:GetGlobal(mediatype) |
return overrideMedia[mediatype] |
end |
function lib:SetGlobal(mediatype, key) |
if not mediaTable[mediatype] then |
return false |
end |
overrideMedia[mediatype] = (key and mediaTable[mediatype][key]) and key or nil |
self.callbacks:Fire(self, "LibSharedMedia_SetGlobal", mediatype, overrideMedia[mediatype]) |
return true |
end |
function lib:GetDefault(mediatype) |
return defaultMedia[mediatype] |
end |
function lib:SetDefault(mediatype, key) |
if mediaTable[mediatype] and mediaTable[mediatype][key] and not defaultMedia[mediatype] then |
defaultMedia[mediatype] = key |
return true |
else |
return false |
end |
end |
## Interface: 20400 |
## Title: Lib: SharedMedia-3.0 |
## Notes: Shared handling of media data (fonts, sounds, textures, ...) between addons. |
## Version: 3.0 |
## Author: Elkano |
## X-Category: Library |
## LoadOnDemand: 1 |
LibSharedMedia-3.0.lua |
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ |
..\FrameXML\UI.xsd"> |
<Script file="GTB.lua"/> |
</Ui> |
local major = "GTB-1.0" |
local minor = tonumber(string.match("$Revision: 752 $", "(%d+)") or 1) |
assert(LibStub, string.format("%s requires LibStub.", major)) |
local GTB = LibStub:NewLibrary(major, minor) |
if( not GTB ) then return end |
local L = { |
["BAD_ARGUMENT"] = "bad argument #%d for '%s' (%s expected, got %s)", |
["MUST_CALL"] = "You must call '%s' from a registered GTB object.", |
["GROUP_EXISTS"] = "The group '%s' already exists.", |
["BAD_FUNC"] = "You must pass an actual handler and function to '%s'.", |
["ALT_DRAG"] = "ALT + Drag to move the frame anchor.", |
} |
-- Validation for passed arguments |
local function assert(level,condition,message) |
if( not condition ) then |
error(message,level) |
end |
end |
local function argcheck(value, num, ...) |
if( type(num) ~= "number" ) then |
error(L["BAD_ARGUMENT"]:format(2, "argcheck", "number", type(num)), 1) |
end |
for i=1,select("#", ...) do |
if( type(value) == select(i, ...) ) then return end |
end |
local types = string.join(", ", ...) |
local name = string.match(debugstack(2,2,0), ": in function [`<](.-)['>]") |
error(L["BAD_ARGUMENT"]:format(num, name, types, type(value)), 3) |
end |
-- GTB Library |
GTB.framePool = GTB.framePool or {} |
GTB.groups = GTB.groups or {} |
local framePool = GTB.framePool |
local groups = GTB.groups |
local methods = {"RegisterOnMove", "SetAnchorVisible", "GetReversed", "GetGrowth", "GetMaxBars", "GetScale", "GetFontSize", "GetWidth", "GetHeight", "SetMaxBars", "SetBaseColor", "EnableGradient", "SetPoint", "SetScale", "SetWidth", "SetHeight", "SetTexture", "SetBarGrowth", "SetIconPosition", "SetTextColor", "HideBar", "ShowBar", "SortBars", |
"SetTimerColor", "SetFadeTime", "RegisterOnFade", "RegisterOnClick", "SetGroupFontSize", "SetInvert", "SetDisplayGroup", "GetDisplayGroup", "RegisterBar", "UnregisterBar", "SetRepeatingTimer", "UnregisterAllBars", "SetBarIcon", "SetTime", "SetBarText"} |
-- Internal functions for managing bars |
local function getFrame() |
-- Check for an unused bar |
if( #(framePool) > 0 ) then |
return table.remove(framePool, 1) |
end |
-- Create the actual bar |
local frame = CreateFrame("StatusBar", nil, UIParent) |
frame:SetClampedToScreen(true) |
frame:SetMinMaxValues(0, 1) |
frame:SetValue(1) |
frame.bg = CreateFrame("StatusBar", nil, frame) |
frame.bg:SetMinMaxValues(0, 1) |
frame.bg:SetValue(1) |
frame.bg:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, 0) |
frame.bg:SetFrameLevel(0) |
-- None available, create a new one |
frame.button = CreateFrame("Button", nil, frame) |
frame.button:EnableMouse(true) |
frame.button:SetAllPoints(frame) |
frame.button:SetClampedToScreen(true) |
frame.button:RegisterForClicks("LeftButtonUp", "RightButtonUp", "MiddleButtonUp", "Button4Up", "Button5Up") |
--frame.button:Hide() |
-- Create icon |
frame.icon = frame:CreateTexture(nil, "ARTWORK") |
-- Sparky |
frame.spark = frame:CreateTexture(nil, "OVERLAY") |
frame.spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark") |
frame.spark:SetWidth(16) |
frame.spark:SetBlendMode("ADD") |
-- Timer text |
frame.timer = frame:CreateFontString(nil, "OVERLAY") |
frame.timer:SetFontObject(GameFontHighlight) |
frame.timer:SetJustifyH("RIGHT") |
-- Display Text |
frame.text = frame:CreateFontString(nil, "OVERLAY") |
frame.text:SetFontObject(GameFontHighlight) |
frame.text:SetJustifyH("LEFT") |
return frame |
end |
-- Release it to be reused later |
local function releaseFrame(frame) |
-- Stop updates |
frame:SetScript("OnUpdate", nil) |
frame:EnableMouse(false) |
frame:Hide() |
-- Reset alpha so everythings visible again |
frame:SetAlpha(1.0) |
-- Clear out our OnClick info |
frame.clickHandler = nil |
frame.clickFunc = nil |
frame.args = nil |
-- And now readd to the frame pool |
table.insert(framePool, frame) |
end |
local function triggerFadeCallback(group, barID) |
if( type(group.onFadeHandler) == "table" and type(group.onFadeFunc) == "string" ) then |
group.onFadeHandler[group.onFadeFunc](group.onFadeHandler, barID) |
elseif( type(group.onFadeFunc) == "string" ) then |
local func = getglobal(group.onFadeFunc) |
getglobal(group.onFadeFunc)(barID) |
elseif( type(group.onFadeFunc) == "function" ) then |
group.onFadeFunc(barID) |
end |
end |
-- Fadeout OnUpdate |
local function fadeOnUpdate(self, elapsed) |
local time = GetTime() |
self.fadeTime = self.fadeTime - (time - self.lastUpdate) |
self.lastUpdate = time |
-- Done fading, hide |
if( self.fadeTime <= 0 ) then |
groups[self.owner]:UnregisterBar(self.barID) |
triggerFadeCallback(groups[self.originalOwner], self.barID) |
return |
end |
self:SetAlpha(self.fadeTime / self.timeToFade) |
end |
-- Starts to fade out the actual bar |
local function fadeoutBar(self) |
local group = groups[self.owner] |
-- Don't fade at all, remove right now |
if( group.fadeTime <= 0 ) then |
group:UnregisterBar(self.barID) |
triggerFadeCallback(groups[self.originalOwner]) |
return |
end |
-- Start fading |
self.timeToFade = group.fadeTime |
self.fadeTime = group.fadeTime |
self:SetScript("OnUpdate", fadeOnUpdate) |
end |
-- Reposition the group |
-- edited for NaturCombat |
local function sortBars(a, b) |
local group = groups["NaturCombat"] |
for id, bar in pairs(group.bars) do |
if (not bar:IsShown()) then -- this specific bar exists.. but it's hidden |
return false |
else |
return a.endTime < b.endTime |
end |
end |
end |
local function repositionFrames(group) |
table.sort(group.usedBars, sortBars) |
local offset = 0 |
if( group.iconPosition == "LEFT" ) then |
offset = group.height |
end |
for i, bar in pairs(group.usedBars) do |
bar:ClearAllPoints() |
if( i > 1 ) then |
if( group.barGrowth == "DOWN" ) then |
bar:SetPoint("TOPLEFT", group.usedBars[i - 1], "BOTTOMLEFT", 0, 0) |
else |
bar:SetPoint("BOTTOMLEFT", group.usedBars[i - 1], "TOPLEFT", 0, 0) |
end |
elseif( group.barGrowth == "UP" ) then |
bar:SetPoint("BOTTOMLEFT", group.frame, "TOPLEFT", offset, 0) |
else |
bar:SetPoint("TOPLEFT", group.frame, "BOTTOMLEFT", offset, 0) |
end |
-- Did we hit the bar limit yet? |
if( i <= group.maxBars ) then |
bar:Show() |
else |
bar:Hide() |
end |
end |
end |
-- OnUpdate for a bar |
local function barOnUpdate(self) |
local time = GetTime() |
-- Check if times ran out and that we need to start fading it out |
self.secondsLeft = self.secondsLeft - (time - self.lastUpdate) |
self.lastUpdate = time |
if( self.secondsLeft <= 0 ) then |
-- Check if it's a repeating timer |
local bar = groups[self.groupName].bars[self.barID] |
if( bar.repeating ) then |
self.secondsLeft = self.startSeconds |
self.lastUpdate = time |
return |
end |
self:SetValue(0) |
self.spark:Hide() |
fadeoutBar(self) |
return |
end |
-- Timer text, need to see if this can be optimized a bit later |
local hour = floor(self.secondsLeft / 3600) |
local minutes = self.secondsLeft - (hour * 3600) |
minutes = floor(minutes / 60) |
local seconds = self.secondsLeft - ((hour * 3600) + (minutes * 60)) |
if( hour > 0 ) then |
self.timer:SetFormattedText("%d:%02d", hour, minute) |
elseif( minutes > 0 ) then |
self.timer:SetFormattedText("%d:%02d", minutes, floor(seconds)) |
elseif( seconds < 10 ) then |
self.timer:SetFormattedText("%.1f", seconds) |
else |
self.timer:SetFormattedText("%.0f", floor(seconds)) |
end |
local percent = self.secondsLeft / self.startSeconds |
local reversed = self.reversed |
-- Color gradient towards red |
--if( self.gradients ) then |
-- finalColor + (currentColor - finalColor) * percentLeft |
-- self:SetStatusBarColor(1.0 + (self.r - 1.0) * percent, self.g * percent, self.b * percent) |
--end |
-- Spark position |
local sp = self:GetWidth() * percent |
sp = reversed and -sp or sp |
self.spark:SetPoint("CENTER", self, reversed and "RIGHT" or "LEFT", sp, 0) |
-- Now update the actual displayed bar |
self:SetValue(reversed and 1-percent or percent) |
end |
------------------------ |
-- GTB PUBLIC METHODS -- |
------------------------ |
-- Register a new group |
local backdrop = {bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", |
insets = {left = 1, right = 1, top = 1, bottom = 1}} |
-- Dragging functions |
local function OnDragStart(self) |
if( IsAltKeyDown() ) then |
self.isMoving = true |
self:StartMoving() |
end |
end |
local function OnDragStop(self) |
if( self.isMoving ) then |
self.isMoving = nil |
self:StopMovingOrSizing() |
--local scale = self:GetEffectiveScale() |
--local x, y = self:GetLeft() * scale, self:GetTop() * scale |
local x, y = self:GetLeft(), self:GetTop() |
local group = groups[self.name] |
if( group.onMoveHandler and group.onMoveFunc ) then |
group.onMoveHandler[group.onMoveFunc](group.onMoveHandler, self, x, y) |
elseif( type(group.onMoveFunc) == "string" ) then |
getglobal(group.onMoveFunc)(self, x, y) |
elseif( type(group.onMoveFunc) == "function" ) then |
group.onMoveFunc(self, x, y) |
end |
end |
end |
local function OnEnter(self) |
GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT") |
GameTooltip:SetText(L["ALT_DRAG"], nil, nil, nil, nil, 1) |
end |
local function OnLeave(self) |
GameTooltip:Hide() |
end |
function GTB:RegisterGroup(name, texture) |
argcheck(name, 1, "string") |
argcheck(texture, 2, "string") |
assert(3, not groups[name], string.format(L["GROUP_EXISTS"], name)) |
local obj = {name = name, frame = CreateFrame("Frame", name, UIParent), fontSize = 11, height = 16, obj = obj, bars = {}, usedBars = {}, reversed = false} |
-- Inject our methods |
for _, func in pairs(methods) do |
obj[func] = GTB[func] |
end |
-- Register |
groups[name] = obj |
-- Set defaults |
local frame = obj.frame |
frame:SetHeight(12) |
frame:SetMovable(true) |
frame:EnableMouse(true) |
frame:SetClampedToScreen(true) |
frame:RegisterForDrag("LeftButton") |
frame:SetBackdrop(backdrop) |
frame:SetBackdropColor(0, 0, 0, 1.0) |
frame:SetBackdropBorderColor(0.75, 0.75, 0.75, 1.0) |
frame:SetScript("OnDragStart", OnDragStart) |
frame:SetScript("OnDragStop", OnDragStop) |
frame:SetScript("OnShow", OnShow) |
frame:SetScript("OnEnter", OnEnter) |
frame:SetScript("OnLeave", OnLeave) |
frame.name = name |
-- Display name |
frame.text = frame:CreateFontString(nil, "OVERLAY") |
frame.text:SetPoint("CENTER", frame) |
frame.text:SetFontObject(GameFontHighlightSmall) |
frame.text:SetText(name) |
obj:SetScale(1.0) |
obj:SetWidth(200) |
obj:SetFadeTime(0.25) |
obj:SetMaxBars(20) |
obj:EnableGradient(true) |
obj:SetAnchorVisible(true) |
obj:SetBarGrowth("DOWN") |
obj:SetIconPosition("LEFT") |
obj:SetTexture(texture) |
obj:SetBaseColor(0.0, 1.0, 0.0) |
obj:SetTextColor(1.0, 1.0, 1.0) |
obj:SetTimerColor(1.0, 1.0, 1.0) |
obj:SetPoint("CENTER", UIParent, "CENTER") |
return obj |
end |
-- Retrieve a group after it's been registered |
function GTB:GetGroup(name) |
argcheck(name, 1, "string") |
return groups[name] and groups[name].obj |
end |
-- Returns every registered group and it's config obj |
function GTB:GetGroups() |
return groups |
end |
----------------- |
----- MISC ------ |
----------------- |
function GTB.SetAnchorVisible(group, flag) |
assert(3, group.name and groups[group.name], string.format(L["MUST_CALL"], "SetAnchorVisible")) |
group.anchorShown = flag |
if( flag ) then |
group.frame:EnableMouse(true) |
group.frame:SetAlpha(1.0) |
else |
group.frame:EnableMouse(false) |
group.frame:SetAlpha(0) |
end |
end |
function GTB.RegisterOnMove(group, handler, func) |
argcheck(handler, 2, "table", "function", "string") |
argcheck(func, 2, "string", "nil") |
if( func ) then |
if( not handler[func] ) then |
error(string.format(L["BAD_FUNC"], "RegisterOnMove"), 3) |
end |
group.onMoveHandler = handler |
group.onMoveFunc = func |
else |
if( type(handler) == "function" and not handler ) then |
error(string.format(L["BAD_FUNC"], "RegisterOnMove"), 3) |
end |
group.onMoveFunc = handler |
end |
end |
-- Associate a function to call when bars fade |
function GTB.RegisterOnFade(group, handler, func) |
argcheck(handler, 2, "table", "function", "string") |
argcheck(func, 2, "string", "nil") |
if( func ) then |
if( not handler[func] ) then |
error(string.format(L["BAD_FUNC"], "RegisterOnFade"), 3) |
end |
group.onFadeHandler = handler |
group.onFadeFunc = func |
else |
if( type(handler) == "function" and not handler ) then |
error(string.format(L["BAD_FUNC"], "RegisterOnFade"), 3) |
end |
group.onFadeFunc = handler |
end |
end |
----------------- |
-- BAR DISPLAY -- |
----------------- |
-- Gradients from base color -> red depending on time left |
function GTB.EnableGradient(group, flag) |
argcheck(flag, 2, "boolean") |
assert(3, group.name and groups[group.name], string.format(L["MUST_CALL"], "EnableGradient")) |
group.gradients = flag |
end |
-- Sets the max number of bars that can show up in this group |
function GTB.SetMaxBars(group, max) |
argcheck(max, 2, "number") |
assert(3, group.name and groups[group.name], string.format(L["MUST_CALL"], "EnableGradient")) |
group.maxBars = max |
end |
-- Group frame positioning, and all the timers inside it |
function GTB.SetPoint(group, point, relativeFrame, relativePoint, xOff, yOff) |
argcheck(point, 2, "string") |
argcheck(relativeFrame, 3, "table", "string", "nil") |
argcheck(relativePoint, 4, "string", "nil") |
argcheck(xOff, 5, "number", "nil") |
argcheck(yOff, 6, "number", "nil") |
assert(3, group.name and groups[group.name], string.format(L["MUST_CALL"], "SetPoint")) |
group.point = point |
group.relativeFrame = relativeFrame |
group.relativePoint = relativePoint |
group.xOff = xOff |
group.yOff = yOff |
group.frame:ClearAllPoints() |
group.frame:SetPoint(point, relativeFrame, relativePoint, xOff, yOff) |
end |
-- Bar scale |
function GTB.SetScale(group, scale) |
argcheck(scale, 2, "number") |
assert(3, group.name and groups[group.name], string.format(L["MUST_CALL"], "SetScale")) |
group.scale = scale |
group.frame:SetScale(scale) |
end |
-- Width of all the bars |
function GTB.SetWidth(group, width) |
argcheck(width, 2, "number") |
assert(3, group.name and groups[group.name], string.format(L["MUST_CALL"], "SetWidth")) |
group.width = width |
group.frame:SetWidth(width + group.height) |
for _, bar in pairs(group.bars) do |
bar.text:SetWidth((group.width - ((group.fontSize or size) * 3.6)) * 0.90) |
bar.bg:SetWidth(group.width) |
bar:SetWidth(group.width) |
end |
end |
-- Height of all the bars |
function GTB.SetHeight(group, height) |
argcheck(height, 2, "number") |
assert(3, group.name and groups[group.name], string.format(L["MUST_CALL"], "SetHeight")) |
group.height = height |
group.frame:SetHeight(height) |
for _, bar in pairs(group.bars) do |
bar.bg:SetHeight(height) |
bar:SetHeight(height) |
end |
end |
--Edit the timer value of a bar |
function GTB.SetTime(group, id, value) |
if not group.bars[id] then return end |
group.bars[id].timer:SetText(value) |
group.bars[id].secondsLeft = value |
group.bars[id].startSeconds = value |
-- do we need to call update? |
end |
-- Edit the text on an active bar |
local origBarID = {} |
function GTB.SetBarText(group, id, text) |
if not group.bars[id] then return end |
group.bars[id].text:SetText(text) |
group.bars[id].barText = text |
end |
function GTB.HideBar(group, id) |
if not group.bars[id] then return end |
--Keep record of this timer |
origBarID[id] = {update=group.bars[id].lastUpdate,text=group.bars[id].barText,timer=group.bars[id].secondsLeft,icon=group.bars[id].iconPath,color={r=group.bars[id].r,g=group.bars[id].g,b=group.bars[id].b}} |
GTB.UnregisterBar(group, id) |
end |
function GTB.ShowBar(group, id, timer) |
local time = origBarID[id].timer - (GetTime() - origBarID[id].update) |
-- group, id, text, 60, 54, icon, r, g, b |
GTB.RegisterBar(group, id, origBarID[id].text, time, timer, origBarID[id].icon, origBarID[id].color.r, origBarID[id].color.g, origBarID[id].color.b) |
end |
function GTB.SetInvert(group, value) |
group.reversed = value |
end |
function GTB.GetReversed(group) |
return group.reversed |
end |
function GTB.GetHeight(group) |
return group.height |
end |
function GTB.GetWidth(group) |
return group.width |
end |
function GTB.GetScale(group) |
return group.scale |
end |
function GTB.GetFontSize(group) |
return group.fontSize |
end |
function GTB.GetMaxBars(group) |
return group.maxBars |
end |
function GTB.GetGrowth(group) |
return group.barGrowth |
end |
-- Change the font size of the group |
function GTB.SetGroupFontSize(group, size) |
group.fontSize = size |
end |
-- Bar texture |
function GTB.SetTexture(group, texture) |
argcheck(texture, 2, "string") |
assert(3, group.name and groups[group.name], string.format(L["MUST_CALL"], "SetTexture")) |
group.texture = texture |
end |
-- Bar growth mode (UP/DOWN) |
function GTB.SetBarGrowth(group, type) |
assert(3, type == "UP" or type == "DOWN", string.format(L["BAD_ARGUMENT"], 2, "SetBarGrowth", "UP, DOWN", tostring(type))) |
assert(3, group.name and groups[group.name], string.format(L["MUST_CALL"], "SetBarGrowth")) |
group.barGrowth = type |
end |
-- Icon positioning (LEFT/RIGHT) |
function GTB.SetIconPosition(group, position) |
assert(3, position == "LEFT" or position == "RIGHT", string.format(L["BAD_ARGUMENT"], 2, "SetBarGrowth", "UP, DOWN", tostring(position))) |
assert(3, group.name and groups[group.name], string.format(L["MUST_CALL"], "SetBarGrowth")) |
group.iconPosition = position |
end |
-- Group object |
function GTB.SetBaseColor(group, r, g, b) |
argcheck(r, 2, "number") |
argcheck(g, 3, "number") |
argcheck(b, 4, "number") |
assert(3, group.name and groups[group.name], string.format(L["MUST_CALL"], "SetBaseColor")) |
if( not group.baseColor ) then |
group.baseColor = {} |
end |
group.baseColor.r = r |
group.baseColor.g = g |
group.baseColor.b = b |
end |
-- Text color |
function GTB.SetTextColor(group, r, g, b) |
argcheck(r, 2, "number") |
argcheck(g, 3, "number") |
argcheck(b, 4, "number") |
assert(3, group.name and groups[group.name], string.format(L["MUST_CALL"], "SetTextColor")) |
if( not group.textColor ) then |
group.textColor = {} |
end |
group.textColor.r = r |
group.textColor.g = g |
group.textColor.b = b |
end |
-- Timer text color |
function GTB.SetTimerColor(group, r, g, b) |
argcheck(r, 2, "number") |
argcheck(g, 3, "number") |
argcheck(b, 4, "number") |
assert(3, group.name and groups[group.name], string.format(L["MUST_CALL"], "SetTimerColor")) |
if( not group.timerColor ) then |
group.timerColor = {} |
end |
group.timerColor.r = r |
group.timerColor.g = g |
group.timerColor.b = b |
end |
-- How many seconds we should take to fade out |
function GTB.SetFadeTime(group, seconds) |
argcheck(seconds, 2, "number") |
assert(3, group.name and groups[group.name], string.format(L["MUST_CALL"], "SetFadeTime")) |
group.fadeTime = seconds |
end |
-- Redirect everything to the specified group |
function GTB.SetDisplayGroup(group, name) |
argcheck(name, 2, "string", "nil") |
assert(3, group.name and groups[group.name], string.format(L["MUST_CALL"], "SetDisplayGroup")) |
-- Don't allow setting the group to redirect to itself |
if( name == "" or name == group.name ) then |
name = nil |
end |
-- Reset the bars if the display group changed |
if( group.redirectTo ~= name ) then |
group:UnregisterAllBars() |
end |
group.redirectTo = name |
end |
-- Gets the current display group |
function GTB.GetDisplayGroup(group) |
assert(3, group.name and groups[group.name], string.format(L["MUST_CALL"], "SetDisplayGroup")) |
return group.redirectTo |
end |
-------------------- |
-- BAR MANAGEMENT -- |
-------------------- |
-- Register |
function GTB.RegisterBar(group, id, text, seconds, startSeconds, icon, r, g, b) |
argcheck(id, 2, "string", "number") |
argcheck(text, 3, "string") |
argcheck(seconds, 4, "number") |
argcheck(icon, 5, "string", "nil") |
argcheck(r, 6, "number", "nil") |
argcheck(g, 7, "number", "nil") |
argcheck(b, 8, "number", "nil") |
assert(3, group.name and groups[group.name], string.format(L["MUST_CALL"], "RegisterBar")) |
local originalOwner = group.name |
-- Check if we're supposed to redirect this to another group, and that the group exists |
if( group.redirectTo and groups[group.redirectTo] ) then |
group = groups[group.redirectTo] |
end |
-- Already exists, remove the old one quickly |
if( group.bars[id] ) then |
group:UnregisterBar(id) |
end |
-- Retrieve a frame thats either recycled, or a newly created one |
local frame = getFrame() |
-- So we can do sorting and positioning |
table.insert(group.usedBars, frame) |
-- Grab basic info about the font |
local path, size, style = GameFontHighlight:GetFont() |
size = group.fontSize or size |
-- Timer text |
local timerTextWidth = size * 3.6 |
frame.timer:SetPoint("RIGHT", frame, "RIGHT", 0, 0) |
frame.timer:SetFont(path, size, style) |
frame.timer:SetText(seconds) |
frame.timer:SetHeight(group.height) |
frame.timer:SetWidth(timerTextWidth) |
-- Display text |
frame.text:SetPoint("LEFT", frame, "LEFT", 0, 0) |
frame.text:SetFont(path, size, style) |
frame.text:SetText(text) |
frame.text:SetHeight(group.height) |
frame.text:SetWidth((group.width - timerTextWidth) * 0.90) |
-- Timer spark |
frame.spark:SetHeight(group.height + 25) |
frame.spark:Show() |
-- Update icon |
if( icon ) then |
frame.icon:SetTexture(icon) |
if( frame.icon:GetTexture() ) then |
local offset = 0 |
if( group.iconPosition == "LEFT" ) then |
offset = -group.height |
end |
frame.icon:SetWidth(group.height) |
frame.icon:SetHeight(group.height) |
frame.icon:SetTexCoord(0.07, 0.93, 0.07, 0.93) |
frame.icon:SetPoint("TOPLEFT", frame, "TOP" .. group.iconPosition, offset, 0) |
frame.icon:Show() |
else |
frame.icon:Hide() |
end |
else |
frame.icon:Hide() |
end |
-- Set info the bar needs to know |
frame.r = r or group.baseColor.r |
frame.g = g or group.baseColor.g |
frame.b = b or group.baseColor.b |
frame.owner = group.name |
frame.originalOwner = originalOwner |
frame.lastUpdate = GetTime() |
frame.endTime = GetTime() + seconds |
frame.secondsLeft = seconds |
frame.remSeconds = seconds |
frame.startSeconds = startSeconds or seconds |
frame.gradients = group.gradients |
frame.groupName = group.name |
frame.iconPath = icon |
frame.barText = text |
frame.barID = id |
frame.group = group |
frame.reversed = group.reversed |
-- Setup background |
frame.bg:SetStatusBarTexture(group.texture) |
frame.bg:SetStatusBarColor(0.0, 0.5, 0.5, 0.5) |
frame.bg:SetWidth(group.width) |
frame.bg:SetHeight(group.height) |
-- Start it up |
frame:SetStatusBarTexture(group.texture) |
frame:SetStatusBarColor(frame.r, frame.g, frame.b) |
frame:SetWidth(group.width) |
frame:SetHeight(group.height) |
frame:SetScale(group.scale) |
frame:SetScript("OnUpdate", barOnUpdate) |
--[[frame.button:SetScript("OnClick", function(self, button) |
if (button == "RightButton") then |
-- delete bar |
GTB.UnregisterBar(group, id) |
end |
end)]] |
-- Reposition this group |
repositionFrames(group) |
-- Register it |
group.bars[id] = frame |
end |
-- Remove all bars |
function GTB.UnregisterAllBars(group) |
assert(3, group.name and groups[group.name], string.format(L["MUST_CALL"], "UnregisteRAllBars")) |
-- Check if we're supposed to redirect this to another group, and that the group exists |
if( group.redirectTo and groups[group.redirectTo] ) then |
group = groups[group.redirectTo] |
end |
-- Clear the used bars list |
local totalBars = #(group.usedBars) |
for i=totalBars, 1, -1 do |
table.remove(group.usedBars, i) |
end |
-- Release all the frames |
for id, bar in pairs(group.bars) do |
releaseFrame(bar) |
group.bars[id] = nil |
end |
return (totalBars > 0) |
end |
-- Unregistering |
function GTB.UnregisterBar(group, id) |
argcheck(id, 2, "string", "number") |
assert(3, group.name and groups[group.name], string.format(L["MUST_CALL"], "UnregisterBar")) |
-- Check if we're supposed to redirect this to another group, and that the group exists |
if( group.redirectTo and groups[group.redirectTo] ) then |
group = groups[group.redirectTo] |
end |
-- Remove the old entry, if it exists |
if( not group.bars[id] ) then |
return nil |
end |
-- Remove from list of used bars |
for i=#(group.usedBars), 1, -1 do |
if( group.usedBars[i].barID == id ) then |
table.remove(group.usedBars, i) |
break |
end |
end |
releaseFrame(group.bars[id]) |
repositionFrames(group) |
group.bars[id] = nil |
return true |
end |
-- Icon |
function GTB.SetBarIcon(group, id, icon, left, right, top, bottom) |
argcheck(id, 2, "string", "number") |
argcheck(icon, 3, "string", "nil") |
argcheck(left, 4, "number", "nil") |
argcheck(right, 5, "number", "nil") |
argcheck(top, 6, "number", "nil") |
argcheck(bottom, 7, "number", "nil") |
assert(3, group.name and groups[group.name], string.format(L["MUST_CALL"], "SetBarIcon")) |
-- Check if we're supposed to redirect this to another group, and that the group exists |
if( group.redirectTo and groups[group.redirectTo] ) then |
group = groups[group.redirectTo] |
end |
local bar = group.bars[id] |
if( not bar ) then |
return |
end |
-- Display icon |
if( icon ) then |
bar.bar.icon:SetTexture(icon) |
if( bar.bar.icon:GetTexture() ) then |
local mod = -1 |
if( group.iconPosition == "RIGHT" ) then |
mod = 1 |
end |
bar.icon:SetWidth(group.height) |
bar.icon:SetHeight(group.height) |
bar.icon:SetTexCoord(0.07, 0.93, 0.07, 0.93) |
bar.icon:SetPoint("TOPLEFT", bar, "TOP" .. group.iconPosition, mod * group.height, 0) |
bar.icon:Show() |
else |
bar.bar.icon:Hide() |
end |
else |
bar.bar.icon:Hide() |
end |
end |
-- Change it to a repeating timer |
function GTB.SetRepeatingTimer(group, id, flag) |
argcheck(id, 2, "string", "number") |
argcheck(flag, 3, "boolean") |
assert(3, group.name and groups[group.name], string.format(L["MUST_CALL"], "SetRepeatingTimer")) |
-- Check if we're supposed to redirect this to another group, and that the group exists |
if( group.redirectTo and groups[group.redirectTo] ) then |
group = groups[group.redirectTo] |
end |
local bar = group.bars[id] |
if( bar ) then |
bar.repeating = flag |
end |
end |
-- Associate OnClick |
function GTB.RegisterOnClick(group, handler, func, ...) |
--argcheck(id, 2, "string", "number") |
argcheck(handler, 2, "table", "nil") |
argcheck(func, 3, "function", "string") |
assert(3, group.name and groups[group.name], string.format(L["MUST_CALL"], "RegisterOnClick")) |
-- Check if we're supposed to redirect this to another group, and that the group exists |
if( group.redirectTo and groups[group.redirectTo] ) then |
group = groups[group.redirectTo] |
end |
-- Release all the frames |
for id, bar in pairs(group.bars) do |
group.bars[id]:EnableMouse(true) |
group.bars[id].clickHandler = handler |
group.bars[id].clickFunc = func |
group.bars[id].args = {...} |
end |
--[[local bar = group.bars[id] |
if( not bar ) then |
return |
end |
bar:EnableMouse(true) |
-- Save for when we actually click |
bar.clickHandler = handler |
bar.clickFunc = func |
bar.args = {...}]] |
end |
## Interface: 20300 |
## Title: GTB |
## Notes: Graphical timer bars libray |
## Author: Mayen |
## OptionalDeps: LibStub |
GTB.xml |