You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
515 lines
18 KiB
515 lines
18 KiB
local _, addon = ...
|
|
|
|
local ClassTalentTooltipUtil = {};
|
|
addon.ClassTalentTooltipUtil = ClassTalentTooltipUtil;
|
|
|
|
local PrimaryTooltip;
|
|
local SecondaryTooltip;
|
|
|
|
local NarciAPI = NarciAPI;
|
|
local SecondsToCooldownAbbrev = NarciAPI.SecondsToCooldownAbbrev;
|
|
|
|
local C_TooltipInfo = C_TooltipInfo;
|
|
local C_Traits = C_Traits;
|
|
local GetSpellInfo = GetSpellInfo;
|
|
local GetSpellBaseCooldown = GetSpellBaseCooldown;
|
|
local C_Spell = C_Spell;
|
|
local IsPassiveSpell = IsPassiveSpell;
|
|
local GetActiveSpecGroup = GetActiveSpecGroup;
|
|
local GetPvpTalentInfoByID = GetPvpTalentInfoByID;
|
|
local GetCursorDelta = GetCursorDelta;
|
|
|
|
local type = type;
|
|
|
|
local PADDING_PIXEL_SIZE = 16;
|
|
local ICON_PIXEL_SIZE = 36;
|
|
local HEADER_PIXEL_SIZE = 16;
|
|
local TEXT_PIEXL_SIZE = 15;
|
|
local DESC_PIXEL_SIZE = 288;
|
|
|
|
local PIXEL = 1;
|
|
local PADDING = 16;
|
|
local COOLDOWN_ICON = "";
|
|
local DESC_MAX_LINES = 2;
|
|
local DESC_MAX_WIDTH = 288;
|
|
|
|
local function Tooltip_UpdatePixel(tooltip)
|
|
local px = NarciAPI.GetPixelForWidget(tooltip, 1);
|
|
PIXEL = px;
|
|
PADDING = PADDING_PIXEL_SIZE * px;
|
|
COOLDOWN_ICON = string.format("|TInterface\\AddOns\\Narcissus\\Art\\Modules\\TalentTree\\CooldownTextIcon2:%d:%d:0:0:16:16:0:16:0:16:%d:%d:%d|t", 0, 1, 171, 171, 171);
|
|
|
|
tooltip.Icon:SetSize(ICON_PIXEL_SIZE*px, ICON_PIXEL_SIZE*px);
|
|
tooltip.IconBorder:SetSize(64*px, 64*px);
|
|
|
|
local font, _, flag = tooltip.Header:GetFont();
|
|
tooltip.Header:SetFont(font, HEADER_PIXEL_SIZE*px, flag);
|
|
|
|
font, _, flag = tooltip.Subtext:GetFont();
|
|
tooltip.Subtext:SetFont(font, TEXT_PIEXL_SIZE*px, flag);
|
|
tooltip.Description:SetFont(font, TEXT_PIEXL_SIZE*px, flag);
|
|
|
|
tooltip.Icon:ClearAllPoints();
|
|
tooltip.Header:ClearAllPoints();
|
|
tooltip.Subtext:ClearAllPoints();
|
|
tooltip.Description:ClearAllPoints();
|
|
|
|
tooltip.Icon:SetPoint("TOPLEFT", tooltip, "TOPLEFT", PADDING, -PADDING);
|
|
tooltip.Header:SetPoint("TOPLEFT", tooltip.Icon, "TOPRIGHT", 8*px, 0);
|
|
tooltip.Subtext:SetPoint("BOTTOMLEFT", tooltip.Icon, "BOTTOMRIGHT", 8*px, 0);
|
|
tooltip.Description:SetPoint("TOPLEFT", tooltip.Icon, "BOTTOMLEFT", 0, -8*px);
|
|
|
|
DESC_MAX_WIDTH = DESC_PIXEL_SIZE * px;
|
|
tooltip.Description:SetWidth(DESC_MAX_WIDTH);
|
|
end
|
|
|
|
local function CreateTooltip()
|
|
local tooltip = CreateFrame("Frame", "TT", NarciMiniTalentTree, "NarciTalentTreeTraitTooltipTemplate");
|
|
NarciAPI.NineSliceUtil.SetUpBackdrop(tooltip.Background, "classTalentTrait");
|
|
Tooltip_UpdatePixel(tooltip);
|
|
tooltip:SetFixedFrameStrata(true);
|
|
tooltip:SetFrameStrata("TOOLTIP");
|
|
tooltip:SetFrameLevel(80);
|
|
tooltip.Description:SetMaxLines(DESC_MAX_LINES);
|
|
|
|
return tooltip
|
|
end
|
|
|
|
local function Tooltip_UpdateSize(tooltip)
|
|
local headerWidth = (ICON_PIXEL_SIZE + 8) * PIXEL + math.max(tooltip.Header:GetWrappedWidth() or 0, tooltip.Subtext:GetWrappedWidth() or 0);
|
|
local descHeight = tooltip.Description:GetHeight();
|
|
local descWidth = tooltip.Description:GetWrappedWidth() or 0;
|
|
if tooltip.Description:IsTruncated() then
|
|
descWidth = DESC_MAX_WIDTH;
|
|
end
|
|
tooltip:SetSize(2*PADDING + math.max(headerWidth, descWidth), (ICON_PIXEL_SIZE + 8 + 2*PADDING_PIXEL_SIZE)*PIXEL + descHeight);
|
|
end
|
|
|
|
local function Tooltip_FadeIn_OnUpdate(self, elapsed)
|
|
self.t = self.t + elapsed;
|
|
if self.t >= 0 then
|
|
if self.t < 0.125 then
|
|
self:SetAlpha(8 * self.t);
|
|
else
|
|
self:SetAlpha(1);
|
|
self:SetScript("OnUpdate", nil);
|
|
end
|
|
else
|
|
self:SetAlpha(0);
|
|
end
|
|
end
|
|
|
|
local function Tooltip_FadeIn(tooltip)
|
|
if not tooltip.animIn then
|
|
tooltip.animIn = tooltip:CreateAnimationGroup();
|
|
local ag = tooltip.animIn;
|
|
local tran1 = ag:CreateAnimation("translation");
|
|
tran1:SetDuration(0);
|
|
tran1:SetOrder(1);
|
|
tran1:SetOffset(0, -8);
|
|
local tran2 = ag:CreateAnimation("translation");
|
|
tran2:SetSmoothing("OUT");
|
|
tran2:SetDuration(0.15);
|
|
tran2:SetOrder(1);
|
|
tran2:SetStartDelay(0.08);
|
|
tran2:SetOffset(0, 8);
|
|
tooltip.tran1 = tran1;
|
|
tooltip.tran2 = tran2;
|
|
end
|
|
local deltaX, deltaY = ClassTalentTooltipUtil:GetCursorDelta();
|
|
local d = math.sqrt(deltaX*deltaX + deltaY*deltaY);
|
|
if d == 0 then
|
|
tooltip.tran1:SetOffset(0, 0);
|
|
tooltip.tran2:SetOffset(0, 0);
|
|
else
|
|
tooltip.tran1:SetOffset(-deltaX, -deltaY);
|
|
tooltip.tran2:SetOffset(deltaX, deltaY);
|
|
end
|
|
tooltip.animIn:Stop();
|
|
tooltip.animIn:Play();
|
|
tooltip.t = (tooltip.isSecondary and -0.05) or 0;
|
|
tooltip:SetAlpha(0);
|
|
tooltip:SetScript("OnUpdate", Tooltip_FadeIn_OnUpdate);
|
|
end
|
|
|
|
local function Tooltip_SetActive(tooltip, isActive)
|
|
if isActive ~= tooltip.isActive then
|
|
tooltip.isActive = isActive;
|
|
if isActive then
|
|
tooltip.Header:SetTextColor(1, 1, 1);
|
|
tooltip.Subtext:SetTextColor(0.67, 0.67, 0.67);
|
|
tooltip.Description:SetTextColor(1, 0.82, 0);
|
|
tooltip.Icon:SetDesaturated(false);
|
|
tooltip.Icon:SetVertexColor(1, 1, 1);
|
|
else
|
|
tooltip.Header:SetTextColor(0.67, 0.67, 0.67);
|
|
tooltip.Subtext:SetTextColor(0.5, 0.5, 0.5);
|
|
tooltip.Description:SetTextColor(0.67, 0.67, 0.67);
|
|
tooltip.Icon:SetDesaturated(true);
|
|
tooltip.Icon:SetVertexColor(0.8, 0.8, 0.8);
|
|
end
|
|
end
|
|
end
|
|
|
|
local function SetTooltipLineText(fontString, line)
|
|
if line and line.args then
|
|
if line.args[2] then
|
|
fontString:SetText(line.args[2].stringVal);
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
|
|
local function IsLineColorYellow(colorVal)
|
|
if colorVal then
|
|
local r, g, b = colorVal.r, colorVal.g, colorVal.b;
|
|
if (r > 0.99 and r < 1.01) and (g > 0.81 and g < 0.83) then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
|
|
local function GetLineText(line, yellowTextOnly)
|
|
local text;
|
|
|
|
if line and line.args then
|
|
if line.args[2] then
|
|
text = line.args[2].stringVal;
|
|
end
|
|
AG = line.args
|
|
else
|
|
return
|
|
end
|
|
|
|
if text == "" then
|
|
return
|
|
else
|
|
if yellowTextOnly then
|
|
--usually the spell's descriotion
|
|
if IsLineColorYellow(line.args[3].colorVal) then
|
|
if text ~= "" then
|
|
return text
|
|
end
|
|
end
|
|
else
|
|
return text
|
|
end
|
|
end
|
|
end
|
|
|
|
local function Tooltip_OnSpellDataLoaded_TraitEntry(self, event, spellID, success)
|
|
--print(event, spellID)
|
|
if spellID == self.pendingSpell then
|
|
self:SetScript("OnEvent", nil);
|
|
self:UnregisterEvent("SPELL_DATA_LOAD_RESULT");
|
|
self.pendingSpell = nil;
|
|
local data = C_TooltipInfo.GetTraitEntry(self.entryID, self.rank);
|
|
if data and data.lines then
|
|
local text = GetLineText(data.lines[3]);
|
|
self.Description:SetText(text);
|
|
Tooltip_UpdateSize(self);
|
|
end
|
|
return
|
|
end
|
|
|
|
if not self.pendingSpell then
|
|
self:SetScript("OnEvent", nil);
|
|
self:UnregisterEvent("SPELL_DATA_LOAD_RESULT");
|
|
end
|
|
end
|
|
|
|
local function Tooltip_OnSpellDataLoaded_PvPTalent(self, event, spellID, success)
|
|
--print(event, spellID)
|
|
if spellID == self.pendingSpell then
|
|
self:SetScript("OnEvent", nil);
|
|
self:UnregisterEvent("SPELL_DATA_LOAD_RESULT");
|
|
self.pendingSpell = nil;
|
|
local data = C_TooltipInfo.GetPvpTalent(self.talentID, self.isInspecting, self.specGroupIndex, self.Index);
|
|
if data and data.lines then
|
|
local text = GetLineText(data.lines[3], true);
|
|
if not text then
|
|
text = GetLineText(data.lines[4], true);
|
|
end
|
|
if not text then
|
|
text = "Loading"
|
|
end
|
|
DT = data.lines
|
|
self.Description:SetText(text);
|
|
Tooltip_UpdateSize(self);
|
|
end
|
|
return
|
|
end
|
|
|
|
if not self.pendingSpell then
|
|
self:SetScript("OnEvent", nil);
|
|
self:UnregisterEvent("SPELL_DATA_LOAD_RESULT");
|
|
end
|
|
end
|
|
|
|
local function SetupTooltipBySpellID(tooltip, spellID, subtext, castTime)
|
|
local isPassive = IsPassiveSpell(spellID);
|
|
local extraText;
|
|
|
|
if isPassive then
|
|
if not tooltip.isPassive then
|
|
tooltip.isPassive = true;
|
|
tooltip.IconMask:SetTexture("Interface\\AddOns\\Narcissus\\Art\\Masks\\Circle");
|
|
tooltip.IconBorder:SetTexCoord(0.5, 1, 0, 1);
|
|
end
|
|
extraText = SPELL_PASSIVE;
|
|
else
|
|
if tooltip.isPassive then
|
|
tooltip.isPassive = nil;
|
|
tooltip.IconMask:SetTexture("Interface\\AddOns\\Narcissus\\Art\\Masks\\Full");
|
|
tooltip.IconBorder:SetTexCoord(0, 0.5, 0, 1);
|
|
end
|
|
|
|
if not castTime then
|
|
local _;
|
|
_, _, _, castTime = GetSpellInfo(spellID);
|
|
end
|
|
if castTime == 0 then
|
|
extraText = SPELL_CAST_TIME_INSTANT;
|
|
else
|
|
extraText = "Cast";
|
|
end
|
|
|
|
local cd = GetSpellBaseCooldown(spellID or 0);
|
|
if cd and cd > 0 then
|
|
local cdText = SecondsToCooldownAbbrev(cd / 1000);
|
|
extraText = extraText.. " CD: " .. cdText;
|
|
end
|
|
end
|
|
|
|
if subtext then
|
|
subtext = subtext.." "..extraText;
|
|
else
|
|
subtext = extraText;
|
|
end
|
|
|
|
tooltip.Subtext:SetText(subtext);
|
|
end
|
|
|
|
local function Tooltip_SetTraitEntry(tooltip, entryID, rank, definitionID, ranksPurchased, maxRanks, selectedEntryID)
|
|
if not entryID then
|
|
tooltip:Hide();
|
|
return
|
|
end
|
|
|
|
tooltip.entryID = entryID;
|
|
tooltip.rank = rank;
|
|
tooltip.definitionID = definitionID;
|
|
|
|
if type(entryID) == "table" then
|
|
if not SecondaryTooltip then
|
|
SecondaryTooltip = CreateTooltip();
|
|
SecondaryTooltip:SetPoint("TOPLEFT", PrimaryTooltip, "BOTTOMLEFT", 0, 0);
|
|
SecondaryTooltip:SetFrameLevel(PrimaryTooltip:GetFrameLevel() - 4);
|
|
SecondaryTooltip.isSecondary = true;
|
|
end
|
|
|
|
local firstEntryID = entryID[1];
|
|
local secondEntryID = entryID[2];
|
|
local firstEntryInfo = NarciMiniTalentTree:GetAndCacheEntryInfo(firstEntryID);
|
|
local secondEntryInfo = NarciMiniTalentTree:GetAndCacheEntryInfo(secondEntryID);
|
|
|
|
if selectedEntryID == firstEntryID or selectedEntryID == secondEntryID then
|
|
if selectedEntryID == firstEntryID then
|
|
Tooltip_SetTraitEntry(tooltip, firstEntryID, 0, firstEntryInfo.definitionID, 1, 1);
|
|
Tooltip_SetTraitEntry(SecondaryTooltip, secondEntryID, 0, secondEntryInfo.definitionID, 0, 1);
|
|
SecondaryTooltip:SetPoint("TOPLEFT", PrimaryTooltip, "BOTTOMLEFT", 32*PIXEL, 0);
|
|
else
|
|
Tooltip_SetTraitEntry(tooltip, secondEntryID, 0, secondEntryInfo.definitionID, 1, 1);
|
|
Tooltip_SetTraitEntry(SecondaryTooltip, firstEntryID, 0, firstEntryInfo.definitionID, 0, 1);
|
|
SecondaryTooltip:SetPoint("TOPLEFT", PrimaryTooltip, "BOTTOMLEFT", -32*PIXEL, 0);
|
|
end
|
|
else
|
|
Tooltip_SetTraitEntry(tooltip, firstEntryID, 0, firstEntryInfo.definitionID, 0, 1);
|
|
Tooltip_SetTraitEntry(SecondaryTooltip, secondEntryID, 0, secondEntryInfo.definitionID, 0, 1);
|
|
SecondaryTooltip:SetPoint("TOPLEFT", PrimaryTooltip, "BOTTOMLEFT", 32*PIXEL, 0);
|
|
end
|
|
return
|
|
end
|
|
|
|
local data = C_TooltipInfo.GetTraitEntry(entryID, rank);
|
|
if data and data.lines then
|
|
local traitName, icon, castTime, _, minRange, maxRange, originalIcon;
|
|
local spellID, isPassive;
|
|
if definitionID then
|
|
local definitionInfo = C_Traits.GetDefinitionInfo(definitionID);
|
|
spellID = definitionInfo and (definitionInfo.spellID or definitionInfo.overriddenSpellID);
|
|
icon = (definitionInfo and definitionInfo.overrideIcon);
|
|
if spellID then
|
|
traitName, _, _, castTime, minRange, maxRange, _, originalIcon = GetSpellInfo(spellID);
|
|
if not icon then
|
|
icon = originalIcon;
|
|
end
|
|
end
|
|
else
|
|
print("NarcissusTalentTree: Missing DefinitionID");
|
|
return
|
|
end
|
|
|
|
tooltip.Icon:SetTexture(icon);
|
|
tooltip.Header:SetText(traitName);
|
|
|
|
local text, text2;
|
|
|
|
if ranksPurchased and maxRanks then
|
|
text2 = ranksPurchased.."/"..maxRanks;
|
|
if ranksPurchased > 0 then
|
|
Tooltip_SetActive(tooltip, true);
|
|
if ranksPurchased ~= maxRanks then
|
|
text2 = "|cffffffff"..text2.."|r";
|
|
end
|
|
else
|
|
Tooltip_SetActive(tooltip, false);
|
|
end
|
|
end
|
|
SetupTooltipBySpellID(tooltip, spellID, text2, castTime);
|
|
|
|
local isSpellDescriptionCached;
|
|
|
|
if C_Spell.IsSpellDataCached(spellID) then
|
|
text = GetLineText(data.lines[3]);
|
|
if not text then
|
|
text = GetLineText(data.lines[2]); --sometimes the second line is the description
|
|
end
|
|
if text then
|
|
isSpellDescriptionCached = true;
|
|
tooltip.Description:SetText(text);
|
|
end
|
|
end
|
|
|
|
if isSpellDescriptionCached and icon then
|
|
tooltip.pendingSpell = nil;
|
|
else
|
|
tooltip.Description:SetText(RETRIEVING_DATA);
|
|
tooltip.pendingSpell = spellID;
|
|
tooltip:RegisterEvent("SPELL_DATA_LOAD_RESULT");
|
|
tooltip:SetScript("OnEvent", Tooltip_OnSpellDataLoaded_TraitEntry);
|
|
C_Spell.RequestLoadSpellData(spellID);
|
|
end
|
|
|
|
Tooltip_UpdateSize(tooltip);
|
|
tooltip:Show();
|
|
Tooltip_FadeIn(tooltip);
|
|
else
|
|
tooltip:Hide();
|
|
end
|
|
end
|
|
|
|
local function Tooltip_SetPvpTalent(tooltip, talentID, isInspecting, slotIndex)
|
|
if not talentID then
|
|
tooltip:Hide();
|
|
return
|
|
end
|
|
|
|
local specGroupIndex = GetActiveSpecGroup(isInspecting);
|
|
local data = C_TooltipInfo.GetPvpTalent(talentID, isInspecting, specGroupIndex, slotIndex);
|
|
|
|
tooltip.talentID, tooltip.isInspecting, tooltip.specGroupIndex, tooltip.Index = talentID, isInspecting, specGroupIndex, slotIndex;
|
|
|
|
if data and data.lines then
|
|
local _, name, icon, _, _, spellID = GetPvpTalentInfoByID(talentID, isInspecting, specGroupIndex, slotIndex);
|
|
tooltip.Icon:SetTexture(icon);
|
|
tooltip.Header:SetText(name);
|
|
|
|
SetupTooltipBySpellID(tooltip, spellID);
|
|
|
|
local isSpellDescriptionCached;
|
|
|
|
if C_Spell.IsSpellDataCached(spellID) then
|
|
local text = GetLineText(data.lines[3], true);
|
|
if not text then
|
|
text = GetLineText(data.lines[4], true);
|
|
end
|
|
if text then
|
|
tooltip.Description:SetText(text);
|
|
isSpellDescriptionCached = true;
|
|
end
|
|
end
|
|
|
|
if isSpellDescriptionCached then
|
|
tooltip.pendingSpell = nil;
|
|
else
|
|
tooltip.Description:SetText(RETRIEVING_DATA);
|
|
tooltip.pendingSpell = spellID;
|
|
tooltip:RegisterEvent("SPELL_DATA_LOAD_RESULT");
|
|
tooltip:SetScript("OnEvent", Tooltip_OnSpellDataLoaded_PvPTalent);
|
|
C_Spell.RequestLoadSpellData(spellID);
|
|
end
|
|
|
|
Tooltip_UpdateSize(tooltip);
|
|
Tooltip_SetActive(tooltip, true);
|
|
tooltip:Show();
|
|
Tooltip_FadeIn(tooltip);
|
|
else
|
|
tooltip:Hide();
|
|
end
|
|
end
|
|
|
|
function ClassTalentTooltipUtil.SetFromNode(nodeButton)
|
|
if not PrimaryTooltip then
|
|
PrimaryTooltip = CreateTooltip();
|
|
PrimaryTooltip:SetScript("OnHide", ClassTalentTooltipUtil.HideTooltip);
|
|
end
|
|
|
|
PrimaryTooltip:Hide();
|
|
PrimaryTooltip:SetPoint("TOPLEFT", nodeButton, "TOPRIGHT", 4, 0);
|
|
Tooltip_SetTraitEntry(PrimaryTooltip, nodeButton.entryIDs or nodeButton.entryID, nodeButton.rank, nodeButton.definitionID, nodeButton.currentRank, nodeButton.maxRanks, nodeButton.entryID);
|
|
end
|
|
|
|
function ClassTalentTooltipUtil.HideTooltip()
|
|
if PrimaryTooltip then
|
|
PrimaryTooltip:Hide();
|
|
end
|
|
if SecondaryTooltip then
|
|
SecondaryTooltip:Hide();
|
|
end
|
|
end
|
|
|
|
function ClassTalentTooltipUtil.SetFromPvPButton(pvpButton)
|
|
if not PrimaryTooltip then
|
|
PrimaryTooltip = CreateTooltip();
|
|
PrimaryTooltip:SetScript("OnHide", ClassTalentTooltipUtil.HideTooltip);
|
|
end
|
|
|
|
PrimaryTooltip:Hide();
|
|
PrimaryTooltip:SetPoint("TOPLEFT", pvpButton, "TOPRIGHT", 4, 0);
|
|
Tooltip_SetPvpTalent(PrimaryTooltip, pvpButton.talentID, pvpButton.isInspecting, pvpButton.index);
|
|
end
|
|
|
|
function ClassTalentTooltipUtil.UpdateMaxLines()
|
|
if PrimaryTooltip then
|
|
PrimaryTooltip.Description:SetMaxLines(DESC_MAX_LINES);
|
|
end
|
|
|
|
if SecondaryTooltip then
|
|
SecondaryTooltip.Description:SetMaxLines(DESC_MAX_LINES);
|
|
end
|
|
end
|
|
|
|
function ClassTalentTooltipUtil:UpdateCursorDelta()
|
|
self.deltaX, self.deltaY = GetCursorDelta();
|
|
end
|
|
|
|
function ClassTalentTooltipUtil:GetCursorDelta()
|
|
return (self.deltaX or 0), (self.deltaY or 0)
|
|
end
|
|
|
|
do
|
|
local SettingFunctions = addon.SettingFunctions;
|
|
|
|
function SettingFunctions.TruncateTalentTreeTooltip(state, db)
|
|
if state == nil then
|
|
state = db["TalentTreeShortTooltip"];
|
|
end
|
|
if state then
|
|
DESC_MAX_LINES = 2;
|
|
else
|
|
DESC_MAX_LINES = 0;
|
|
end
|
|
ClassTalentTooltipUtil.UpdateMaxLines();
|
|
end
|
|
end
|