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.

340 lines
12 KiB

local _, addon = ...
local API = addon.API;
local TooltipFrame = addon.SharedTooltip;
local Clamp = API.Clamp;
local Lerp = API.ClampLerp;
local GetFriendshipReputation = C_GossipInfo.GetFriendshipReputation;
local GetFriendshipReputationRanks = C_GossipInfo.GetFriendshipReputationRanks;
local FRAME_SIZE = 52;
local FriendshipBar = CreateFrame("Frame");
addon.FriendshipBar = FriendshipBar;
FriendshipBar:SetSize(FRAME_SIZE, FRAME_SIZE);
FriendshipBar.textures = {};
--Positive: Counter-clockwise
local RAD_FILL1_BEGIN = math.pi *(5/4);
local RAD_FILL1_END = math.pi *(1/2);
local RAD_FILL2_BEGIN = RAD_FILL1_END;
local RAD_FILL2_END = 0;
local RAD_FILL3_BEGIN = RAD_FILL2_END;
local RAD_FILL3_END = math.pi * (-1/2);
local RAD_FILL4_BEGIN = RAD_FILL3_END;
local RAD_FILL4_END = math.pi * (-5/4);
local function CreateTextureMask(frame, maskedTexture, layer)
local mask = frame:CreateMaskTexture(nil, layer);
maskedTexture:AddMaskTexture(mask);
mask:SetTexture("Interface/AddOns/DialogueUI/Art/BasicShapes/Mask-RightWhite", "CLAMPTOBLACKADDITIVE", "CLAMPTOBLACKADDITIVE");
mask:SetSize(26, 26);
return mask
end
local function SetTextureNumber(texture, number)
--Bake number into textures for visual consistency
number = Clamp(number, 1, 9);
texture:SetTexCoord((number - 1)*0.0625, number*0.0625, 0, 1);
end
function FriendshipBar:Init()
local Container = CreateFrame("Frame", nil, self);
Container:SetSize(FRAME_SIZE, FRAME_SIZE);
Container:SetPoint("CENTER", self, "CENTER", 0, 0);
self.Container = Container;
local tinsert = table.insert;
local FrontTexture = Container:CreateTexture(nil, "OVERLAY", nil, 3);
FrontTexture:SetTexCoord(0.0625, 0.4375, 0.0625, 0.4375);
FrontTexture:SetAllPoints(true);
self.FrontTexture = FrontTexture;
tinsert(self.textures, FrontTexture);
local BackTexture = Container:CreateTexture(nil, "BACKGROUND");
BackTexture:SetTexCoord(0.5625, 0.9375, 0.0625, 0.4375);
BackTexture:SetAllPoints(true);
self.BackTexture = BackTexture;
tinsert(self.textures, BackTexture);
local fillLayer = "ARTWORK";
local FillFull = Container:CreateTexture(nil, fillLayer);
FillFull:SetTexCoord(0.5625, 0.9375, 0.0625, 0.4375);
FillFull:SetAllPoints(true);
self.FillFull = FillFull;
tinsert(self.textures, FillFull);
--Top Right Piece
local Fill1 = Container:CreateTexture(nil, fillLayer);
Fill1:SetTexCoord(0.25, 0.4375, 0.5625, 0.703125);
Fill1:SetSize(FRAME_SIZE*0.5, FRAME_SIZE*0.5*0.75);
Fill1:SetPoint("BOTTOMLEFT", Container, "CENTER", 0, 6.4);
self.Fill1 = Fill1;
tinsert(self.textures, Fill1);
self.Mask1 = CreateTextureMask(Container, Fill1, fillLayer);
self.Mask1:SetSize(26, 26);
self.Mask1:SetPoint("CENTER", Container, "CENTER", FRAME_SIZE/6, FRAME_SIZE/6*0.75)
self.Mask1:SetRotation(RAD_FILL1_BEGIN);
--Bottom Right Piece
local Fill2 = Container:CreateTexture(nil, fillLayer);
Fill2:SetTexCoord(0.25, 0.4375, 0.703125, 0.9375);
Fill2:SetSize(FRAME_SIZE*0.5, FRAME_SIZE*0.5*1.25);
Fill2:SetPoint("TOPLEFT", Container, "CENTER", 0, 6.4);
self.Fill2 = Fill2;
tinsert(self.textures, Fill2);
self.Mask2 = CreateTextureMask(Container, Fill2, fillLayer);
self.Mask2:SetSize(52, 52);
self.Mask2:SetPoint("CENTER", Container, "CENTER", 0, 6.4);
self.Mask2:SetRotation(RAD_FILL2_BEGIN);
--Bottom Left Piece
local Fill3 = Container:CreateTexture(nil, fillLayer);
Fill3:SetTexCoord(0.0625, 0.25, 0.703125, 0.9375);
Fill3:SetSize(FRAME_SIZE*0.5, FRAME_SIZE*0.5*1.25);
Fill3:SetPoint("TOPRIGHT", Container, "CENTER", 0, 6.4);
self.Fill3 = Fill3;
tinsert(self.textures, Fill3);
self.Mask3 = CreateTextureMask(Container, Fill3, fillLayer);
self.Mask3:SetSize(52, 52);
self.Mask3:SetPoint("CENTER", Container, "CENTER", 0, 6.4);
self.Mask3:SetRotation(RAD_FILL3_BEGIN);
--Top Left Piece
local Fill4 = Container:CreateTexture(nil, fillLayer);
Fill4:SetTexCoord(0.0625, 0.25, 0.5625, 0.703125);
Fill4:SetSize(FRAME_SIZE*0.5, FRAME_SIZE*0.5*0.75);
Fill4:SetPoint("BOTTOMRIGHT", Container, "CENTER", 0, 6.4);
self.Fill4 = Fill4;
tinsert(self.textures, Fill4);
self.Mask4 = CreateTextureMask(Container, Fill4, fillLayer);
self.Mask4:SetSize(26, 26);
self.Mask4:SetPoint("CENTER", Container, "CENTER", -FRAME_SIZE/6, FRAME_SIZE/6*0.75)
self.Mask4:SetRotation(RAD_FILL4_BEGIN);
local Surface = Container:CreateTexture(nil, fillLayer, nil, 4);
Surface:SetTexCoord(0.5625, 0.9375, 0.5625, 0.9375);
Surface:SetSize(52, 52);
Surface:SetPoint("CENTER", Container, "CENTER", 0, 0);
Surface:Hide();
self.Surface = Surface;
tinsert(self.textures, Surface);
local FillMask = Container:CreateMaskTexture(nil, fillLayer, nil, 4);
Surface:AddMaskTexture(FillMask);
FillMask:SetTexture("Interface/AddOns/DialogueUI/Art/Theme_Shared/Mask-HeartFill", "CLAMPTOBLACKADDITIVE", "CLAMPTOBLACKADDITIVE");
FillMask:SetSize(69, 69);
FillMask:SetPoint("CENTER", Container, "CENTER", 0, 0);
--[[
local MaxLevelText = Container:CreateFontString(nil, "OVERLAY", "MirageFont_Serif_10_DarkBrown", 2);
MaxLevelText:SetJustifyH("CENTER");
MaxLevelText:SetJustifyV("MIDDLE");
MaxLevelText:SetPoint("CENTER", Container, "CENTER", 8.5, 4.8);
MaxLevelText:SetText(5);
self.MaxLevelText = MaxLevelText;
local CurrentLevelText = Container:CreateFontString(nil, "OVERLAY", "MirageFont_Serif_18_DarkBrown", 3);
CurrentLevelText:SetJustifyH("CENTER");
CurrentLevelText:SetJustifyV("MIDDLE");
CurrentLevelText:SetPoint("CENTER", Container, "CENTER", -8.5, 3);
CurrentLevelText:SetText(1);
self.CurrentLevelText = CurrentLevelText;
--]]
local CurrentLevelText = Container:CreateTexture(nil, "OVERLAY", nil, 5);
CurrentLevelText:SetPoint("CENTER", Container, "CENTER", -8, 3);
CurrentLevelText:SetSize(20, 20);
self.CurrentLevelText = CurrentLevelText;
local MaxLevelText = Container:CreateTexture(nil, "OVERLAY", nil, 5);
MaxLevelText:SetPoint("CENTER", Container, "CENTER", 8.5, 4.8);
MaxLevelText:SetSize(13, 13);
self.MaxLevelText = MaxLevelText;
self:SetScript("OnEnter", self.OnEnter);
self:SetScript("OnLeave", self.OnLeave);
self:SetScript("OnEvent", self.OnEvent);
self:SetScript("OnHide", self.OnHide);
self:SetHitRectInsets(1, 1, 2, 2);
self.Init = nil;
self:LoadTheme();
end
function FriendshipBar:LoadTheme()
if self.Init then return end;
local barFile = addon.ThemeUtil:GetTextureFile("FriendshipBar.png");
local numberFile = addon.ThemeUtil:GetTextureFile("FriendshipDigits.tga");
for _, tex in ipairs(self.textures) do
tex:SetTexture(barFile);
end
local filer = "TRILINEAR";
self.CurrentLevelText:SetTexture(numberFile, nil, nil, filer);
self.MaxLevelText:SetTexture(numberFile, nil, nil, filer);
end
local FILL1_RATIO;
local FILL2_RATIO;
local FILL3_RATIO;
local FILL4_RATIO;
do
local ARC1 = 0.75;
local ARC2 = 0.9;
local FULL_ARC = 2*(ARC1 + ARC2);
FILL1_RATIO = ARC1/FULL_ARC;
FILL2_RATIO = ARC2/FULL_ARC;
FILL3_RATIO = ARC2/FULL_ARC;
FILL4_RATIO = ARC1/FULL_ARC;
end
function FriendshipBar:SetRatio(ratio)
local ratio1 = ratio/FILL1_RATIO;
local ratio2 = (ratio - FILL1_RATIO)/FILL2_RATIO;
local ratio3 = (ratio - FILL1_RATIO - FILL2_RATIO)/FILL3_RATIO;
local ratio4 = (ratio - FILL1_RATIO - FILL2_RATIO - FILL3_RATIO)/FILL4_RATIO;
local rad1 = Lerp(RAD_FILL1_BEGIN, RAD_FILL1_END, ratio1);
local rad2 = Lerp(RAD_FILL2_BEGIN, RAD_FILL2_END, ratio2);
local rad3 = Lerp(RAD_FILL3_BEGIN, RAD_FILL3_END, ratio3);
local rad4 = Lerp(RAD_FILL4_BEGIN, RAD_FILL4_END, ratio4);
self.Mask1:SetRotation(rad1);
self.Mask2:SetRotation(rad2);
self.Mask3:SetRotation(rad3);
self.Mask4:SetRotation(rad4);
local surfRad, surfOffsetX, surfOffsetY;
if ratio4 > 0 then
surfRad = rad4;
surfOffsetX = -FRAME_SIZE/6;
surfOffsetY = FRAME_SIZE/6*0.75;
elseif ratio3 > 0 then
surfRad = rad3;
surfOffsetX = 0;
surfOffsetY = 6.4;
elseif ratio2 > 0 then
surfRad = rad2;
surfOffsetX = 0;
surfOffsetY = 6.4;
else
surfRad = rad1;
surfOffsetX = FRAME_SIZE/6;
surfOffsetY = FRAME_SIZE/6*0.75;
end
self.Surface:ClearAllPoints();
self.Surface:SetPoint("CENTER", self, "CENTER", surfOffsetX, surfOffsetY);
self.Surface:SetRotation(surfRad);
self.Surface:SetShown(ratio > 0.01 and ratio < 0.995);
end
function FriendshipBar:Update(factionID)
local repInfo = GetFriendshipReputation and GetFriendshipReputation(factionID or 0);
if repInfo and repInfo.friendshipFactionID and repInfo.friendshipFactionID > 0 then
if self.Init then
self:Init();
end
self.friendshipFactionID = repInfo.friendshipFactionID;
local fillRatio;
if repInfo.nextThreshold then
local current = repInfo.standing - repInfo.reactionThreshold;
local max = repInfo.nextThreshold - repInfo.reactionThreshold;
if max == 0 then
fillRatio = 1;
else
fillRatio = current / max;
end
else
fillRatio = 1;
end
self:SetRatio(fillRatio);
local rankInfo = GetFriendshipReputationRanks(repInfo.friendshipFactionID);
--self.CurrentLevelText:SetText(rankInfo.currentLevel);
--self.MaxLevelText:SetText(rankInfo.maxLevel);
SetTextureNumber(self.CurrentLevelText, rankInfo.currentLevel);
SetTextureNumber(self.MaxLevelText, rankInfo.maxLevel);
self:RegisterEvent("UPDATE_FACTION");
self.Container:Show();
elseif self.Container then
self.friendshipFactionID = nil;
self:UnregisterEvent("UPDATE_FACTION");
self.Container:Hide();
end
end
function FriendshipBar:OnUpdate(elapsed)
self:SetScript("OnUpdate", nil);
self:Update();
end
function FriendshipBar:RequestUpdate()
self:SetScript("OnUpdate", self.OnUpdate);
self:Show();
end
function FriendshipBar:OnEnter()
if not self.friendshipFactionID then return end;
local repInfo = GetFriendshipReputation(self.friendshipFactionID);
if repInfo and repInfo.friendshipFactionID and repInfo.friendshipFactionID > 0 then
TooltipFrame:Hide();
TooltipFrame:SetOwner(self, "ANCHOR_NONE");
TooltipFrame:SetPoint("BOTTOMLEFT", self, "TOPRIGHT", 0, 0);
local rankInfo = GetFriendshipReputationRanks(repInfo.friendshipFactionID);
if rankInfo.maxLevel > 0 then
TooltipFrame:SetTitle(repInfo.name.." ("..rankInfo.currentLevel.." / "..rankInfo.maxLevel..")", 1, 1, 1);
else
TooltipFrame:SetTitle(repInfo.name, 1, 1, 1);
end
TooltipFrame:AddLeftLine(repInfo.text, 1, 0.82, 0, true);
if repInfo.nextThreshold then
local current = repInfo.standing - repInfo.reactionThreshold;
local max = repInfo.nextThreshold - repInfo.reactionThreshold;
TooltipFrame:AddLeftLine(repInfo.reaction.." ("..current.." / "..max..")" , 1, 1, 1, true);
local diff = max - current;
TooltipFrame:AddLeftLine(addon.L["To Next Level Label"]..": |cffffffff"..diff.."|r", 1, 0.82, 0);
else
TooltipFrame:AddLeftLine(repInfo.reaction, 1, 1, 1, true);
end
TooltipFrame:Show();
end
end
function FriendshipBar:OnLeave()
TooltipFrame:Hide();
end
function FriendshipBar:OnEvent(event, ...)
if event == "UPDATE_FACTION" then
self:RequestUpdate();
end
end
function FriendshipBar:OnHide()
self:UnregisterEvent("UPDATE_FACTION");
end