GLYPHTYPE_MAJOR = 1;
GLYPHTYPE_MINOR = 2;
GLYPH_MINOR = { r = 0, g = 0.25, b = 1};
GLYPH_MAJOR = { r = 1, g = 0.25, b = 0};
GLYPH_SLOTS = {};
-- Empty Texture
GLYPH_SLOTS[0] = { left = 0.78125, right = 0.91015625, top = 0.69921875, bottom = 0.828125 };
-- Major Glyphs
GLYPH_SLOTS[3] = { left = 0.392578125, right = 0.521484375, top = 0.87109375, bottom = 1 };
GLYPH_SLOTS[1] = { left = 0, right = 0.12890625, top = 0.87109375, bottom = 1 };
GLYPH_SLOTS[5] = { left = 0.26171875, right = 0.390625, top = 0.87109375, bottom = 1 };
-- Minor Glyphs
GLYPH_SLOTS[2] = { left = 0.130859375, right = 0.259765625, top = 0.87109375, bottom = 1 };
GLYPH_SLOTS[6] = { left = 0.654296875, right = 0.783203125, top = 0.87109375, bottom = 1 };
GLYPH_SLOTS[4] = { left = 0.5234375, right = 0.65234375, top = 0.87109375, bottom = 1 };
NUM_GLYPH_SLOTS = 6;
local slotAnimations = {};
local TOPLEFT, TOP, TOPRIGHT, BOTTOMRIGHT, BOTTOM, BOTTOMLEFT = 3, 1, 5, 4, 2, 6;
slotAnimations[TOPLEFT] = {["point"] = "CENTER", ["xStart"] = -13, ["xStop"] = -85, ["yStart"] = 17, ["yStop"] = 60};
slotAnimations[TOP] = {["point"] = "CENTER", ["xStart"] = -13, ["xStop"] = -13, ["yStart"] = 17, ["yStop"] = 100};
slotAnimations[TOPRIGHT] = {["point"] = "CENTER", ["xStart"] = -13, ["xStop"] = 59, ["yStart"] = 17, ["yStop"] = 60};
slotAnimations[BOTTOM] = {["point"] = "CENTER", ["xStart"] = -13, ["xStop"] = -13, ["yStart"] = 17, ["yStop"] = -64};
slotAnimations[BOTTOMLEFT] = {["point"] = "CENTER", ["xStart"] = -13, ["xStop"] = -87, ["yStart"] = 18, ["yStop"] = -27};
slotAnimations[BOTTOMRIGHT] = {["point"] = "CENTER", ["xStart"] = -13, ["xStop"] = 61, ["yStart"] = 18, ["yStop"] = -27};
local HIGHLIGHT_BASEALPHA = .4;
function GlyphFrame_Toggle ()
TalentFrame_LoadUI();
if ( PlayerTalentFrame_ToggleGlyphFrame ) then
PlayerTalentFrame_ToggleGlyphFrame(GetActiveTalentGroup());
end
end
function GlyphFrame_Open ()
TalentFrame_LoadUI();
if ( PlayerTalentFrame_OpenGlyphFrame ) then
PlayerTalentFrame_OpenGlyphFrame(GetActiveTalentGroup());
end
end
function GlyphFrameGlyph_OnLoad (self)
local name = self:GetName();
self:RegisterForClicks("LeftButtonUp", "RightButtonUp");
self.glyph = _G[name .. "Glyph"];
self.setting = _G[name .. "Setting"];
self.highlight = _G[name .. "Highlight"];
self.background = _G[name .. "Background"];
self.ring = _G[name .. "Ring"];
self.shine = _G[name .. "Shine"];
self.elapsed = 0;
self.tintElapsed = 0;
self.glyphType = nil;
end
function GlyphFrameGlyph_UpdateSlot (self)
local id = self:GetID();
local talentGroup = PlayerTalentFrame and PlayerTalentFrame.talentGroup;
local enabled, glyphType, glyphSpell, iconFilename = GetGlyphSocketInfo(id, talentGroup);
local isMinor = glyphType == 2;
if ( isMinor ) then
GlyphFrameGlyph_SetGlyphType(self, GLYPHTYPE_MINOR);
else
GlyphFrameGlyph_SetGlyphType(self, GLYPHTYPE_MAJOR);
end
self.elapsed = 0;
self.tintElapsed = 0;
local slotAnimation = slotAnimations[id];
if ( not enabled ) then
slotAnimation.glyph = nil;
if ( slotAnimation.sparkle ) then
slotAnimation.sparkle:StopAnimating();
slotAnimation.sparkle:Hide();
end
self.shine:Hide();
self.background:Hide();
self.glyph:Hide();
self.ring:Hide();
self.setting:SetTexture("Interface\\Spellbook\\UI-GlyphFrame-Locked");
self.setting:SetTexCoord(.1, .9, .1, .9);
elseif ( not glyphSpell ) then
slotAnimation.glyph = nil;
if ( slotAnimation.sparkle ) then
slotAnimation.sparkle:StopAnimating();
slotAnimation.sparkle:Hide();
end
self.spell = nil;
self.shine:Show();
self.background:Show();
self.background:SetTexCoord(GLYPH_SLOTS[0].left, GLYPH_SLOTS[0].right, GLYPH_SLOTS[0].top, GLYPH_SLOTS[0].bottom);
if ( not GlyphMatchesSocket(id) ) then
self.background:SetAlpha(1);
end
self.glyph:Hide();
self.ring:Show();
else
slotAnimation.glyph = true;
self.spell = glyphSpell;
self.shine:Show();
self.background:Show();
self.background:SetAlpha(1);
self.background:SetTexCoord(GLYPH_SLOTS[id].left, GLYPH_SLOTS[id].right, GLYPH_SLOTS[id].top, GLYPH_SLOTS[id].bottom);
self.glyph:Show();
if ( iconFilename ) then
self.glyph:SetTexture(iconFilename);
else
self.glyph:SetTexture("Interface\\Spellbook\\UI-Glyph-Rune1");
end
self.ring:Show();
end
end
function GlyphFrameGlyph_SetGlyphType (glyph, glyphType)
glyph.glyphType = glyphType;
glyph.setting:SetTexture("Interface\\Spellbook\\UI-GlyphFrame");
if ( glyphType == GLYPHTYPE_MAJOR ) then
glyph.glyph:SetVertexColor(GLYPH_MAJOR.r, GLYPH_MAJOR.g, GLYPH_MAJOR.b);
glyph.setting:SetWidth(108);
glyph.setting:SetHeight(108);
glyph.setting:SetTexCoord(0.740234375, 0.953125, 0.484375, 0.697265625);
glyph.highlight:SetWidth(108);
glyph.highlight:SetHeight(108);
glyph.highlight:SetTexCoord(0.740234375, 0.953125, 0.484375, 0.697265625);
glyph.ring:SetWidth(82);
glyph.ring:SetHeight(82);
glyph.ring:SetPoint("CENTER", glyph, "CENTER", 0, -1);
glyph.ring:SetTexCoord(0.767578125, 0.92578125, 0.32421875, 0.482421875);
glyph.shine:SetTexCoord(0.9609375, 1, 0.9609375, 1);
glyph.background:SetWidth(70);
glyph.background:SetHeight(70);
else
glyph.glyph:SetVertexColor(GLYPH_MINOR.r, GLYPH_MINOR.g, GLYPH_MINOR.b);
glyph.setting:SetWidth(86);
glyph.setting:SetHeight(86);
glyph.setting:SetTexCoord(0.765625, 0.927734375, 0.15625, 0.31640625);
glyph.highlight:SetWidth(86);
glyph.highlight:SetHeight(86);
glyph.highlight:SetTexCoord(0.765625, 0.927734375, 0.15625, 0.31640625);
glyph.ring:SetWidth(62);
glyph.ring:SetHeight(62);
glyph.ring:SetPoint("CENTER", glyph, "CENTER", 0, 1);
glyph.ring:SetTexCoord(0.787109375, 0.908203125, 0.033203125, 0.154296875);
glyph.shine:SetTexCoord(0.9609375, 1, 0.921875, 0.9609375);
glyph.background:SetWidth(64);
glyph.background:SetHeight(64);
end
end
function GlyphFrameGlyph_OnUpdate (self, elapsed)
local GLYPHFRAMEGLYPH_FINISHED = 6;
local GLYPHFRAMEGLYPH_START = 2;
local GLYPHFRAMEGLYPH_HOLD = 4;
local hasGlyph = self.glyph:IsShown();
if ( hasGlyph or self.elapsed > 0 ) then
self.elapsed = self.elapsed + elapsed;
elapsed = self.elapsed;
if ( elapsed >= GLYPHFRAMEGLYPH_FINISHED ) then
self.setting:SetAlpha(.6);
self.elapsed = 0;
elseif ( elapsed <= GLYPHFRAMEGLYPH_START ) then
self.setting:SetAlpha(.6 + (.4 * elapsed/GLYPHFRAMEGLYPH_START));
elseif ( elapsed >= GLYPHFRAMEGLYPH_HOLD ) then
self.setting:SetAlpha(1 - (.4 * (elapsed - GLYPHFRAMEGLYPH_HOLD) / (GLYPHFRAMEGLYPH_FINISHED - GLYPHFRAMEGLYPH_HOLD) ) );
end
elseif ( self.background:IsShown() ) then
self.setting:SetAlpha(.6);
else
self.setting:SetAlpha(.6);
end
local TINT_START, TINT_HOLD, TINT_FINISHED = .6, .8, 1.6;
local id = self:GetID();
if ( not hasGlyph and self.background:IsShown() and GlyphMatchesSocket(id) ) then
self.tintElapsed = self.tintElapsed + elapsed;
self.background:SetTexCoord(GLYPH_SLOTS[id].left, GLYPH_SLOTS[id].right, GLYPH_SLOTS[id].top, GLYPH_SLOTS[id].bottom);
local highlight = false;
if ( not self:IsMouseOver() ) then
self.highlight:Show();
highlight = true;
end
local alpha;
elapsed = self.tintElapsed;
if ( elapsed >= TINT_FINISHED ) then
alpha = 1;
self.tintElapsed = 0;
elseif ( elapsed <= TINT_START ) then
alpha = 1 - (.6 * elapsed/TINT_START);
elseif ( elapsed >= TINT_HOLD ) then
alpha = .4 + (.6 * (elapsed - TINT_HOLD) / (TINT_FINISHED - TINT_HOLD));
end
if ( alpha ) then
self.background:SetAlpha(alpha);
if ( highlight ) then
self.highlight:SetAlpha(HIGHLIGHT_BASEALPHA * alpha);
else
self.highlight:SetAlpha(HIGHLIGHT_BASEALPHA);
end
end
elseif ( not hasGlyph ) then
self.background:SetTexCoord(GLYPH_SLOTS[0].left, GLYPH_SLOTS[0].right, GLYPH_SLOTS[0].top, GLYPH_SLOTS[0].bottom);
self.background:SetAlpha(1);
end
if ( self.hasCursor and SpellIsTargeting() ) then
if ( GlyphMatchesSocket(self:GetID()) and self.background:IsShown() ) then
SetCursor("CAST_CURSOR");
else
SetCursor("CAST_ERROR_CURSOR");
end
end
end
function GlyphFrameGlyph_OnClick (self, button)
local id = self:GetID();
local talentGroup = PlayerTalentFrame and PlayerTalentFrame.talentGroup;
if ( IsModifiedClick("CHATLINK") and ChatEdit_GetActiveWindow() ) then
local link = GetGlyphLink(id, talentGroup);
if ( link ) then
ChatEdit_InsertLink(link);
end
elseif ( button == "RightButton" ) then
if ( IsShiftKeyDown() and talentGroup == GetActiveTalentGroup() ) then
local glyphName;
local _, _, glyphSpell = GetGlyphSocketInfo(id, talentGroup);
if ( glyphSpell ) then
glyphName = GetSpellInfo(glyphSpell);
local dialog = StaticPopup_Show("CONFIRM_REMOVE_GLYPH", glyphName);
dialog.data = id;
end
end
elseif ( talentGroup == GetActiveTalentGroup() ) then
if ( self.glyph:IsShown() and GlyphMatchesSocket(id) ) then
local dialog = StaticPopup_Show("CONFIRM_GLYPH_PLACEMENT", id);
dialog.data = id;
else
PlaceGlyphInSocket(id);
end
end
end
function GlyphFrameGlyph_OnEnter (self)
self.hasCursor = true;
if ( self.background:IsShown() ) then
self.highlight:Show();
end
GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
GameTooltip:SetGlyph(self:GetID(), PlayerTalentFrame and PlayerTalentFrame.talentGroup);
GameTooltip:Show();
end
function GlyphFrameGlyph_OnLeave (self)
self.hasCursor = nil;
self.highlight:Hide();
GameTooltip:Hide();
end
local GLYPH_SPARKLE_SIZES = 3;
local GLYPH_DURATION_MODIFIERS = { 1.25, 1.5, 1.8 };
function GlyphFrame_OnUpdate (self, elapsed)
for i = 1, #slotAnimations do
local animation = slotAnimations[i];
if ( animation.glyph and not (animation.sparkle and animation.sparkle.animGroup:IsPlaying()) ) then
local sparkleSize = math.random(GLYPH_SPARKLE_SIZES);
GlyphFrame_StartSlotAnimation(i, sparkleSize * GLYPH_DURATION_MODIFIERS[sparkleSize], sparkleSize);
end
end
end
function GlyphFrame_PulseGlow ()
GlyphFrame.glow:Show();
GlyphFrame.glow.pulse:Play();
end
function GlyphFrame_OnShow (self)
GlyphFrame_Update();
end
function GlyphFrame_OnLoad (self)
local name = self:GetName();
self.background = _G[name .. "Background"];
self.sparkleFrame = SparkleFrame:New(self);
self:RegisterEvent("ADDON_LOADED");
self:RegisterEvent("GLYPH_ADDED");
self:RegisterEvent("GLYPH_REMOVED");
self:RegisterEvent("GLYPH_UPDATED");
self:RegisterEvent("USE_GLYPH");
self:RegisterEvent("PLAYER_LEVEL_UP");
end
function GlyphFrame_OnEnter (self)
if ( SpellIsTargeting() ) then
SetCursor("CAST_ERROR_CURSOR");
end
end
function GlyphFrame_OnLeave (self)
end
function GlyphFrame_OnEvent (self, event, ...)
if ( event == "ADDON_LOADED" ) then
local name = ...;
if ( name == "Blizzard_GlyphUI" and IsAddOnLoaded("Blizzard_TalentUI") or name == "Blizzard_TalentUI" ) then
self:ClearAllPoints();
self:SetParent(PlayerTalentFrame);
self:SetAllPoints();
-- make sure this shows up above the talent UI
local frameLevel = self:GetParent():GetFrameLevel() + 4;
self:SetFrameLevel(frameLevel);
PlayerTalentFrameCloseButton:SetFrameLevel(frameLevel + 1);
end
elseif ( event == "USE_GLYPH" or event == "PLAYER_LEVEL_UP" ) then
GlyphFrame_Update();
elseif ( event == "GLYPH_ADDED" or event == "GLYPH_REMOVED" or event == "GLYPH_UPDATED" ) then
local index = ...;
local glyph = _G["GlyphFrameGlyph" .. index];
if ( glyph and self:IsVisible() ) then
-- update the glyph
GlyphFrameGlyph_UpdateSlot(glyph);
-- play effects based on the event and glyph type
GlyphFrame_PulseGlow();
local glyphType = glyph.glyphType;
if ( event == "GLYPH_ADDED" or event == "GLYPH_UPDATED" ) then
if ( glyphType == GLYPHTYPE_MINOR ) then
PlaySound("Glyph_MinorCreate");
elseif ( glyphType == GLYPHTYPE_MAJOR ) then
PlaySound("Glyph_MajorCreate");
end
elseif ( event == "GLYPH_REMOVED" ) then
GlyphFrame_StopSlotAnimation(index);
if ( glyphType == GLYPHTYPE_MINOR ) then
PlaySound("Glyph_MinorDestroy");
elseif ( glyphType == GLYPHTYPE_MAJOR ) then
PlaySound("Glyph_MajorDestroy");
end
end
end
--Refresh tooltip!
if ( GameTooltip:IsOwned(glyph) ) then
GlyphFrameGlyph_OnEnter(glyph);
end
end
end
function GlyphFrame_Update ()
local isActiveTalentGroup =
PlayerTalentFrame and not PlayerTalentFrame.pet and
PlayerTalentFrame.talentGroup == GetActiveTalentGroup(PlayerTalentFrame.pet);
SetDesaturation(GlyphFrame.background, not isActiveTalentGroup);
for i = 1, NUM_GLYPH_SLOTS do
GlyphFrameGlyph_UpdateSlot(_G["GlyphFrameGlyph"..i]);
end
end
function GlyphFrame_StartSlotAnimation (slotID, duration, size)
local animation = slotAnimations[slotID];
-- init texture to animate
local sparkleName = "GlyphFrameSparkle"..slotID;
local sparkle = _G[sparkleName];
if ( not sparkle ) then
sparkle = GlyphFrame:CreateTexture(sparkleName, "OVERLAY", "GlyphSparkleTexture");
sparkle.slotID = slotID;
end
local template;
if ( size == 1 ) then
template = "SparkleTextureSmall";
elseif ( size == 2 ) then
template = "SparkleTextureKindaSmall";
else
template = "SparkleTextureNormal";
end
local sparkleDim = SparkleDimensions[template];
sparkle:SetHeight(sparkleDim.height);
sparkle:SetWidth(sparkleDim.width);
sparkle:SetPoint("CENTER", GlyphFrame, animation.point, animation.xStart, animation.yStart);
sparkle:Show();
-- init animation
local offsetX, offsetY = animation.xStop - animation.xStart, animation.yStop - animation.yStart;
local animGroupAnim = sparkle.animGroup.translate;
animGroupAnim:SetOffset(offsetX, offsetY);
animGroupAnim:SetDuration(duration);
animGroupAnim:Play();
animation.sparkle = sparkle;
end
function GlyphFrame_StopSlotAnimation (slotID)
local animation = slotAnimations[slotID];
if ( animation.sparkle ) then
animation.sparkle.animGroup:Stop();
animation.sparkle:Hide();
animation.sparkle = nil;
end
end