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.

701 lines
21 KiB

local _, addon = ...
local FadeFrame = NarciFadeUI.Fade;
local GetNumClassSetItems = NarciAPI.GetNumClassSetItems;
local floor = math.floor;
local After = C_Timer.After;
local outSine = addon.EasingFunctions.outSine;
local MAJORFACTION_EXPANSION = 9;
local function RoundLevel(lvl)
return floor(lvl * 100 + 0.5)/100
end
local function ClassSet_OnEnter(self)
local p = self:GetParent();
local nodes = p.ClassSetOverlay.Nodes;
for _, node in pairs(nodes) do
node.HighlightTexture.FadeIn:Play();
end
local f = NarciClassSetTooltip;
f:ClearAllPoints();
f:SetParent(p.ClassSetOverlay);
f:SetPoint("TOP", p, "BOTTOM", 0, -8);
f:SetFrameStrata("TOOLTIP");
f:FadeIn(true);
end
local function ClassSet_OnLeave(self)
local nodes = self:GetParent().ClassSetOverlay.Nodes;
if nodes then
for _, node in pairs(nodes) do
node.HighlightTexture.FadeOut:Play();
end
NarciClassSetTooltip:FadeOut();
end
end
local function GenericItemLevel_OnEnter(self)
Narci_ShowButtonTooltip(self);
end
local function Domination_OnEnter(self)
NarciAPI_RunDelayedFunction(self, 0.2, function()
local f = NarciGameTooltip;
self:GetParent().DominationOverlay:ShowTooltip(f, "TOP", self, "BOTTOM", 0, -12);
f:SetAlpha(0);
FadeFrame(f, 0.2, 1);
end);
end
local Themes = {
grey = {
fluidColor = {0.9, 0.9, 0.9},
showLevel = true,
frameTex = "HexagonTube",
backgroundTex = "QualityGrey",
highlightTex = "GenericHighlight",
highlightSize = 100,
highlightBlend = "ADD",
},
kyrian = {
fluidColor = {0.76, 0.89, 0.94},
showLevel = true,
frameTex = "HexagonTube",
backgroundTex = "CovenantKyrian",
highlightTex = "GenericHighlight",
highlightSize = 100,
highlightBlend = "ADD",
},
venthyr = {
fluidColor = {0.55, 0, 0.19},
showLevel = true,
frameTex = "HexagonTube",
backgroundTex = "CovenantVenthyr",
highlightTex = "GenericHighlight",
highlightSize = 100,
highlightBlend = "ADD",
},
fae = {
fluidColor = {0.11, 0.42, 0.80},
showLevel = true,
frameTex = "HexagonTube",
backgroundTex = "CovenantNightFae",
highlightTex = "GenericHighlight",
highlightSize = 100,
highlightBlend = "ADD",
},
necrolord = {
fluidColor = {0, 0.63, 0.43},
showLevel = true,
frameTex = "HexagonTube",
backgroundTex = "CovenantNecrolord",
highlightTex = "GenericHighlight",
highlightSize = 100,
highlightBlend = "ADD",
},
domination = {
frameTex = "Domination",
highlightTex = "DominationHighlight",
highlightSize = 128,
highlightBlend = "ADD",
onEnterFunc = Domination_OnEnter,
},
--[[
classSet = {
frameTex = "Progenitor\\ItemLevelHex",
highlightTex = "Progenitor\\ItemLevelHexHighlight",
nodeTex = "Progenitor\\SetPieceCount",
nodeHighlightTex = "Progenitor\\SetPieceCountHighlight",
highlightSize = 104,
highlightBlend = "ADD",
highlightLevel = 4,
onEnterFunc = ClassSet_OnEnter,
onLeaveFunc = ClassSet_OnLeave,
},
--]]
classSet = {
frameTex = "Neltharion\\ItemLevelHex",
highlightTex = "Neltharion\\ItemLevelHexHighlight",
nodeTex = "Neltharion\\SetPieceCount",
nodeHighlightTex = "Neltharion\\SetPieceCountHighlight",
highlightSize = 104,
highlightBlend = "ADD",
highlightLevel = 4,
onEnterFunc = ClassSet_OnEnter,
onLeaveFunc = ClassSet_OnLeave,
},
};
do
if addon.IsTOCVersionEqualOrNewerThan(100200) then
Themes.classSet = {
frameTex = "EmeraldDream\\ItemLevelHex",
--highlightTex = "EmeraldDream\\ItemLevelHexHighlight",
nodeTex = "EmeraldDream\\SetPieceCount",
nodeHighlightTex = "EmeraldDream\\SetPieceCountHighlight",
highlightSize = 104,
highlightBlend = "ADD",
highlightLevel = 4,
onEnterFunc = ClassSet_OnEnter,
onLeaveFunc = ClassSet_OnLeave,
};
end
end
NarciItemLevelFrameMixin = {};
function NarciItemLevelFrameMixin:UpdateItemLevel(playerLevel)
--playerLevel = playerLevel or UnitLevel("player");
local avgItemLevel, avgItemLevelEquipped, avgItemLevelPvp = GetAverageItemLevel();
local avgItemLevelBase = floor(avgItemLevel);
avgItemLevel = RoundLevel(avgItemLevel);
avgItemLevelEquipped = RoundLevel(avgItemLevelEquipped);
avgItemLevelPvp = RoundLevel(avgItemLevelPvp);
self.LeftButton.avgItemLevel = avgItemLevel;
self.LeftButton.avgItemLevelPvp = avgItemLevelPvp;
self.LeftButton.isSameLevel = (avgItemLevel == avgItemLevelEquipped);
self.LeftButton.Level:SetText(avgItemLevelEquipped);
local percentage = avgItemLevel - avgItemLevelBase;
local height; --Set the bar(Fluid) height in the Tube
if percentage < 0.10 then
height = 0.1;
elseif percentage > 0.90 then
height = 84;
else
height = 84 * percentage;
end
self.CenterButton.Fluid:SetHeight(height);
self.CenterButton.Level:SetText(avgItemLevelBase);
self.CenterButton.tooltipHeadline = STAT_AVERAGE_ITEM_LEVEL .." "..avgItemLevel;
end
function NarciItemLevelFrameMixin:UpdateCovenantRenownLevel(newLevel)
local renownLevel = newLevel or C_CovenantSanctumUI.GetRenownLevel() or 0;
local headerText = string.format(COVENANT_SANCTUM_LEVEL, renownLevel);
if C_CovenantSanctumUI.HasMaximumRenown() then
headerText = headerText.. " (maxed)";
end
local frame = self.RightButton;
frame.Header:SetText("RN");
frame.tooltipHeadline = headerText;
frame.Number:SetText(renownLevel);
frame.tooltipLine1 = COVENANT_RENOWN_TUTORIAL_PROGRESS;
end
function NarciItemLevelFrameMixin:UpdateRenownLevel()
if not self.majorFactionIDs then
local bestExpansionID;
local playerLevel = UnitLevel("player");
if playerLevel and playerLevel > 70 then
bestExpansionID = 10;
self.majorFactionLandingPageTitle = WAR_WITHIN_LANDING_PAGE_TITLE;
else
bestExpansionID = 9;
self.majorFactionLandingPageTitle = DRAGONFLIGHT_LANDING_PAGE_TITLE;
end
local tbl = {};
local factionIDs = C_MajorFactions.GetMajorFactionIDs();
for _, majorFactionID in ipairs(factionIDs) do
local data = C_MajorFactions.GetMajorFactionData(majorFactionID);
if data and data.expansionID >= bestExpansionID then
table.insert(tbl, majorFactionID);
end
end
self.majorFactionIDs = tbl;
end
local level, primaryFactionID;
local maxLevel = 0;
for _, majorFactionID in ipairs(self.majorFactionIDs) do
level = C_MajorFactions.GetCurrentRenownLevel(majorFactionID);
if level > maxLevel then
primaryFactionID = majorFactionID;
maxLevel = level;
end
end
local frame = self.RightButton;
frame.Header:SetText("RN");
frame.Number:SetText(maxLevel);
end
function NarciItemLevelFrameMixin:SetThemeByName(themeName)
if themeName ~= self.theme then
local asset = Themes[themeName];
local prefix = "Interface\\AddOns\\Narcissus\\Art\\Widgets\\ItemLevel\\";
local file = prefix.. asset.frameTex;
self.CenterButton.FluidBackground:SetTexture(file);
self.CenterButton.TubeBorder:SetTexture(file);
self.LeftButton.Background:SetTexture(file);
self.LeftButton.Highlight:SetTexture(file);
self.RightButton.Background:SetTexture(file);
self.RightButton.Highlight:SetTexture(file);
self.CenterButton:ShowMaxLevel(asset.showLevel);
if asset.highlightTex then
file = prefix.. asset.highlightTex;
self.CenterButton.Highlight:SetTexture(file, nil, nil, "TRILINEAR");
self.CenterButton.Highlight:SetSize(asset.highlightSize, asset.highlightSize);
self.CenterButton.Highlight:SetDrawLayer("OVERLAY", asset.highlightLevel or 1);
self.CenterButton.Highlight:SetBlendMode(asset.highlightBlend or "ADD");
end
if asset.backgroundTex then
self.CenterButton.Background:SetTexture(prefix.. asset.backgroundTex);
self.CenterButton.Background:SetTexCoord(0, 1, 0, 1);
else
self.CenterButton.Background:SetTexture(nil);
end
if asset.fluidColor then
self.CenterButton.Fluid:SetColorTexture(unpack(asset.fluidColor));
end
self.theme = themeName;
self.CenterButton.onEnterFunc = asset.onEnterFunc or GenericItemLevel_OnEnter;
self.CenterButton.onLeaveFunc = asset.onLeaveFunc;
self.ClassSetOverlay:SetShown(themeName == "classSet");
if self.ClassSetOverlay and self.ClassSetOverlay.Nodes then
local nodeTex, highlightTex;
if asset.nodeTex then
nodeTex = prefix.. asset.nodeTex;
end
if asset.nodeHighlightTex then
highlightTex = prefix.. asset.nodeHighlightTex;
end
for i, node in ipairs(self.ClassSetOverlay.Nodes) do
node.NormalTexture:SetTexture(nodeTex);
node.HighlightTexture:SetTexture(highlightTex);
end
end
end
end
function NarciItemLevelFrameMixin:UpdateDomination()
if not self.checkDomination then return end;
if not self.pauseUpdate then
self.pauseUpdate = true;
After(0, function()
local isDomination = self.DominationOverlay:Update();
if isDomination then
self:SetThemeByName("domination");
end
self.pauseUpdate = nil;
end)
end
end
function NarciItemLevelFrameMixin:UpdateClassSet(numSetItems)
local node;
local f = self.ClassSetOverlay;
if not f.Nodes then
f.Nodes = {};
local _, _, classID = UnitClass("player");
f.ClassIcon = f:CreateTexture(nil, "OVERLAY", nil, 4);
f.ClassIcon:SetSize(24, 24);
f.ClassIcon:SetPoint("CENTER", f, "CENTER", 0, 0);
f.ClassIcon:SetTexture( "Interface\\AddOns\\Narcissus\\Art\\Widgets\\Progenitor\\ClassIcon".. (classID or 1) );
end
f.ClassIcon:SetShown(numSetItems >= 2);
for i = 1, 4 do
node = f.Nodes[i];
if not node then
node = CreateFrame("Frame", nil, f, "NarciClassSetIndicatorNodeTemplate");
if i == 1 then
node:SetPoint("TOPRIGHT", f, "CENTER", 0, 0);
node.NormalTexture:SetTexCoord(0, 0.25, 0.25, 0.5);
node.HighlightTexture:SetTexCoord(0, 0.5, 0.5, 1);
elseif i == 2 then
node:SetPoint("BOTTOMRIGHT", f, "CENTER", 0, 0);
node.NormalTexture:SetTexCoord(0, 0.25, 0, 0.25);
node.HighlightTexture:SetTexCoord(0, 0.5, 0, 0.5);
elseif i == 3 then
node:SetPoint("BOTTOMLEFT", f, "CENTER", 0, 0);
node.NormalTexture:SetTexCoord(0.25, 0.5, 0, 0.25);
node.HighlightTexture:SetTexCoord(0.5, 1, 0, 0.5);
else
node:SetPoint("TOPLEFT", f, "CENTER", 0, 0);
node.NormalTexture:SetTexCoord(0.25, 0.5, 0.25, 0.5);
node.HighlightTexture:SetTexCoord(0.5, 1, 0.5, 1);
end
end
if i <= numSetItems then
if not node:IsShown() then
node:StopAnimating();
node.HighlightTexture.Shine:Play();
node:Show();
end
else
node:Hide();
end
end
f.numSetItems = numSetItems;
end
local function AsyncUpdate_OnUpdate(self, elapsed)
self.delay = self.delay + elapsed;
if self.delay >= 0 then
self:SetScript("OnUpdate", nil);
self:InstantUpdate();
self.delay = nil;
end
end
function NarciItemLevelFrameMixin:AsyncUpdate(delay)
if not self.delay then
self.delay = (delay and -delay) or 0;
self:SetScript("OnUpdate", AsyncUpdate_OnUpdate);
end
end
function NarciItemLevelFrameMixin:InstantUpdate()
local themeName;
local numSetItems = GetNumClassSetItems(true);
if numSetItems > 0 then
themeName = "classSet";
self:UpdateClassSet(numSetItems); --numSetItems
else
local covenantID = C_Covenants.GetActiveCovenantID();
if covenantID and covenantID ~= 0 then
if covenantID == 1 then
themeName = "kyrian";
elseif covenantID == 2 then
themeName = "venthyr";
elseif covenantID == 3 then
themeName = "fae";
elseif covenantID == 4 then
themeName = "necrolord";
end
else
themeName = "grey";
end
end
self:SetThemeByName(themeName);
self:UpdateItemLevel();
self:UpdateRenownLevel();
end
function NarciItemLevelFrameMixin:ToggleExtraInfo(state, replayAnimation)
if not self.animFrame then
self.animFrame = CreateFrame("Frame");
self.animFrame:Hide();
self.animFrame:SetScript("OnUpdate", function(f, elapsed)
f.t = f.t + elapsed;
local offsetX = outSine(f.t, f.fromX, f.toX, 0.4);
if f.t >= 0.4 then
offsetX = f.toX;
f:Hide();
if f.hideButton then
self.LeftButton:Hide();
self.RightButton:Hide();
end
end
self.LeftButton:SetPoint("RIGHT", self, "CENTER", -offsetX, 0);
self.RightButton:SetPoint("LEFT", self, "CENTER", offsetX, 0);
end);
end
self.animFrame:Hide();
self.animFrame.t = 0;
local _, _, _, fromX = self.RightButton:GetPoint();
self.animFrame.fromX = fromX;
if state then
self.animFrame.toX = 28;
self.LeftButton:Show();
self.RightButton:Show();
self.animFrame.hideButton = false;
else
self.animFrame.toX = -32;
self.animFrame.hideButton = true;
end
if fromX ~= self.animFrame.toX or replayAnimation then
self.animFrame:Show();
end
end
function NarciItemLevelFrameMixin:Init()
local function SideButton_OnEnter(f)
if f.onEnterFunc then
f.onEnterFunc(f);
FadeFrame(f.Highlight, 0.15, 1);
end
end
local function SideButton_OnLeave(f)
Narci:HideButtonTooltip();
FadeFrame(f.Highlight, 0.25, 0);
end
local function SideButton_ShowDetailedItemLevel(f)
if f.isSameLevel then
f.tooltipHeadline = string.format(f.tooltipFormat, f.Level:GetText());
else
f.tooltipHeadline = string.format(f.tooltipFormat, f.Level:GetText()) .. string.format(" (max %s)", f.avgItemLevel);
end
if f.avgItemLevelPvp and f.avgItemLevelPvp ~= 0 then
f.tooltipSpecial = string.format(STAT_AVERAGE_PVP_ITEM_LEVEL, f.avgItemLevelPvp);
else
f.tooltipSpecial = nil;
end
Narci_ShowButtonTooltip(f);
end
local function SideButton_ShowMajorFactionInfo(f)
local DefaultTooltip = NarciGameTooltip;
DefaultTooltip:HideTooltip();
if not self.majorFactionIDs then
self:UpdateRenownLevel();
end
DefaultTooltip:SetOwner(f, "ANCHOR_NONE");
DefaultTooltip:SetPoint("BOTTOM", f, "TOP", 0, 2);
DefaultTooltip:SetText(self.majorFactionLandingPageTitle);
local factionIDs = self.majorFactionIDs;
local factionList = {};
if factionIDs and #factionIDs > 0 then
local factionData;
for _, majorFactionID in ipairs(factionIDs) do
factionData = C_MajorFactions.GetMajorFactionData(majorFactionID);
if factionData then
table.insert(factionList, factionData);
end
end
local function UnlockOrderSort(faction1, faction2)
if faction1.uiPriority then
return faction1.uiPriority < faction2.uiPriority;
else
return faction1.unlockOrder < faction2.unlockOrder;
end
end
table.sort(factionList, UnlockOrderSort);
--Embedded Frame
if not f.FactionListFrame then
f.FactionListFrame = CreateFrame("Frame", nil, f);
f.factionButtons = {};
f.FactionListFrame:SetWidth(154);
end
for i = 1, #f.factionButtons do
f.factionButtons[i]:Hide();
end
local maxTextWidth = 0;
local description, level, textWidth;
for i, data in ipairs(factionList) do
if not f.factionButtons[i] then
f.factionButtons[i] = CreateFrame("Frame", nil, f.FactionListFrame, "NarciGameTooltipEmbeddedIconTextFrame");
if i == 1 then
f.factionButtons[i]:SetPoint("TOPLEFT", f.FactionListFrame, "TOPLEFT", 0, 0);
else
f.factionButtons[i]:SetPoint("TOPLEFT", f.factionButtons[i - 1], "BOTTOMLEFT", 0, -6);
end
end
level = data.renownLevel or 0;
if level < 10 then
level = level.." ";
end
if not data.isUnlocked then
description = MAJOR_FACTION_BUTTON_FACTION_LOCKED;
elseif C_MajorFactions.HasMaximumRenown(data.factionID) then
if C_Reputation.IsFactionParagon(data.factionID) then
local totalEarned, threshold = C_Reputation.GetFactionParagonInfo(data.factionID);
if totalEarned and threshold and threshold ~= 0 then
local paragonLevel = floor(totalEarned / threshold);
local currentValue = totalEarned - paragonLevel * threshold;
description = string.format("|cff00ccffP%s|r %d/%d", paragonLevel, currentValue, threshold);
else
description = MAJOR_FACTION_MAX_RENOWN_REACHED;
end
else
description = MAJOR_FACTION_MAX_RENOWN_REACHED;
end
else
description = string.format("|cffffd100%s|r %d/%d", level, data.renownReputationEarned, data.renownLevelThreshold);
end
f.factionButtons[i].Icon:SetAtlas(string.format("majorFactions_icons_%s512", data.textureKit), false);
f.factionButtons[i].Text:SetText(string.format("|cffffffff%s|r\n%s", data.name, description));
f.factionButtons[i].Text:SetTextColor(0.5, 0.5, 0.5);
f.factionButtons[i]:Show();
textWidth = f.factionButtons[i].Text:GetWrappedWidth();
if textWidth and textWidth > maxTextWidth then
maxTextWidth = textWidth;
end
end
local numButtons = #factionList;
f.FactionListFrame:SetHeight((28 + 6)*numButtons - 12);
f.FactionListFrame:SetWidth(floor(maxTextWidth + 0.5) + 28 + 6);
local function GameTooltip_InsertFrame(tooltipFrame, frame, verticalPadding) -- this is an exact copy of GameTooltip_InsertFrame to avoid "Execution tainted"
verticalPadding = verticalPadding or 0;
local textSpacing = tooltipFrame:GetCustomLineSpacing() or 2;
local textHeight = Round(_G[tooltipFrame:GetName().."TextLeft2"]:GetLineHeight());
local neededHeight = Round(frame:GetHeight() + verticalPadding);
local numLinesNeeded = math.ceil(neededHeight / (textHeight + textSpacing));
local currentLine = tooltipFrame:NumLines();
if numLinesNeeded ~= nil then
for i = 1, numLinesNeeded do
tooltipFrame:AddLine(" ");
end
end
frame:SetParent(tooltipFrame);
frame:ClearAllPoints();
frame:SetPoint("TOPLEFT", tooltipFrame:GetName().."TextLeft"..(currentLine + 1), "TOPLEFT", 0, -verticalPadding);
if not tooltipFrame.insertedFrames then
tooltipFrame.insertedFrames = { };
end
local frameWidth = frame:GetWidth();
if tooltipFrame:GetMinimumWidth() < frameWidth then
tooltipFrame:SetMinimumWidth(frameWidth);
end
frame:Show();
table.insert(tooltipFrame.insertedFrames, frame);
return (numLinesNeeded * textHeight) + (numLinesNeeded - 1) * textSpacing;
end
GameTooltip_InsertFrame(DefaultTooltip, f.FactionListFrame, 6);
else
DefaultTooltip:AddLine(MAJOR_FACTION_BUTTON_FACTION_LOCKED, 0.5, 0.5, 0.5, true);
end
DefaultTooltip:Show();
DefaultTooltip:FadeIn();
end
local LeftButton = self.LeftButton;
LeftButton:SetScript("OnEnter", SideButton_OnEnter);
LeftButton:SetScript("OnLeave", SideButton_OnLeave);
LeftButton.onEnterFunc = SideButton_ShowDetailedItemLevel;
LeftButton.tooltipFormat = Narci.L["Equipped Item Level Format"];
LeftButton.tooltipLine1 = STAT_AVERAGE_ITEM_LEVEL_TOOLTIP;
local RightButton = self.RightButton;
RightButton:SetScript("OnEnter", SideButton_OnEnter);
RightButton:SetScript("OnLeave", SideButton_OnLeave);
RightButton.onEnterFunc = SideButton_ShowMajorFactionInfo;
end
NarciItemLevelCenterButtonMixin = {};
function NarciItemLevelCenterButtonMixin:OnLoad()
self.tooltipLine1 = HIGHLIGHT_FONT_COLOR_CODE .. STAT_AVERAGE_ITEM_LEVEL_TOOLTIP .. FONT_COLOR_CODE_CLOSE;
--self.tooltip3 = L["Toggle Equipment Set Manager"];
self:SetScript("OnLoad", nil);
self.OnLoad = nil;
end
local function OnEnterDelay_OnUpdate(self, elapsed)
self.delay = self.delay + elapsed;
if self.delay > 0 then
if self.onEnterFunc then
self.onEnterFunc(self);
end
self:StopDelay();
end
end
function NarciItemLevelCenterButtonMixin:OnEnter()
FadeFrame(self.Highlight, 0.2, 1);
if self.onEnterFunc then
self.delay = -0.15;
self:SetScript("OnUpdate", OnEnterDelay_OnUpdate);
else
self:StopDelay();
end
end
function NarciItemLevelCenterButtonMixin:OnMouseDown()
self.Background:SetPoint("CENTER", 0, -4);
end
function NarciItemLevelCenterButtonMixin:OnMouseUp()
self.Background:SetPoint("CENTER", 0, 0);
end
function NarciItemLevelCenterButtonMixin:OnLeave()
FadeFrame(self.Highlight, 0.2, 0);
Narci:HideButtonTooltip();
if self.onLeaveFunc then
self.onLeaveFunc(self);
end
self:StopDelay();
end
function NarciItemLevelCenterButtonMixin:OnClick()
end
function NarciItemLevelCenterButtonMixin:OnHide()
if self.onHideFunc then
self.onHideFunc(self);
end
self:StopDelay();
end
function NarciItemLevelCenterButtonMixin:ShowItemLevel()
self:GetParent():Update();
end
function NarciItemLevelCenterButtonMixin:ShowMaxLevel(state)
self.Header:SetShown(state);
self.Level:SetShown(state);
self.Surface:SetShown(state);
self.Fluid:SetShown(state);
self.Background:SetShown(state);
end
function NarciItemLevelCenterButtonMixin:StopDelay()
if self.delay then
self:SetScript("OnUpdate", nil);
self.delay = nil;
end
end
function NarciItemLevelCenterButtonMixin:OnMouseWheel(delta)
if NarciClassSetTooltip:IsVisible() then
if delta > 0 then
NarciClassSetTooltip:CycleSpec(-1, true);
else
NarciClassSetTooltip:CycleSpec(1, true);
end
end
end