WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   General Authoring Discussion (https://www.wowinterface.com/forums/forumdisplay.php?f=20)
-   -   [Solved] Custom xp,ap,azerite bar does not trigger on login, only after reloadui (https://www.wowinterface.com/forums/showthread.php?t=56470)

Zenjaa 07-29-18 09:49 AM

[Solved] Custom xp,ap,azerite bar does not trigger on login, only after reloadui
 
Hello.
I'm in need of some help again. Since the advice I got last time was super helpful, I thought I'll try my luck again.
The following code is part of my personal ui specifically the progressbar, which shows xp,ap,azerite,reputation.
With my chars that are below level 110, I'm not experiencing any problems (xp bar is displayed at the first login and shows xp/restxp), but with my level 110 toons, the bar does not show until after I do a reload. I guess I'm missing something regarding the events, but my lua knowledge is limited and I can't figure it out myself.
Maybe someone can help me out with this. Any help is greatly appreciated.

Code:

local F, C, L = unpack(select(2, ...))

if not C.general.progressbars then return end

------------------------
-- create frames
------------------------
local backdrop = CreateFrame("Frame", nil, Minimap)
backdrop:SetHeight(6)
backdrop:SetPoint("BOTTOM", Minimap, "TOP")
backdrop:SetPoint("BOTTOMLEFT", Minimap, "TOPLEFT", -1, -20)
backdrop:SetPoint("BOTTOMRIGHT", Minimap, "TOPRIGHT", 1, 20)
F.CreateBD(backdrop, .6)

--xp,ap,azerite
local bar = CreateFrame("StatusBar", nil, backdrop)
bar:SetHeight(4)
bar:SetPoint("TOP", backdrop, "TOP", 0, -1)
bar:SetPoint("LEFT", backdrop, 1, 0)
bar:SetPoint("RIGHT", backdrop, -1, 0)
bar:SetStatusBarTexture(C.media.texture)

--restxp
local rest = CreateFrame("Statusbar", nil, backdrop)
rest:SetHeight(4)
rest:SetPoint("TOP", backdrop, "TOP", 0, -1)
rest:SetPoint("LEFT", backdrop, 1, 0)
rest:SetPoint("RIGHT", backdrop, -1, 0)
rest:SetStatusBarTexture(C.media.texture)
rest:SetFrameLevel(bar:GetFrameLevel() - 1)
bar.restBar = rest


--mouseframe
local mouseFrame = CreateFrame("Frame", "ZenjaaUIExpBar", backdrop)
mouseFrame:SetAllPoints(backdrop)
mouseFrame:EnableMouse(true)

-----------------------
--update bar function
-----------------------

local function updateStatus()
  local rest = bar.restBar
  if rest then rest:Hide() end

        --xp
        if UnitLevel("player") < MAX_PLAYER_LEVEL then
                local xp, mxp, rxp = UnitXP("player"), UnitXPMax("player"), GetXPExhaustion()
                bar:SetStatusBarColor(.5, 0, .75)
                bar:SetMinMaxValues(0, mxp)
                bar:SetValue(xp)
                bar:Show()
                if rxp then
                        rest:SetStatusBarColor(0, .4, .8)
                        rest:SetMinMaxValues(0, mxp)
                        rest:SetValue(math.min(xp + rxp, mxp))
                        rest:Show()
                end
                if IsXPUserDisabled() then bar:SetStatusBarColor(.7, 0, 0) end
               
        --reputation
        elseif GetWatchedFactionInfo() then
                local _, standing, min, max, value, factionID = GetWatchedFactionInfo()
                local friendID, friendRep, _, _, _, _, _, friendThreshold, nextFriendThreshold = GetFriendshipReputation(factionID)
                if friendID then
                        if nextFriendThreshold then
                                min, max, value = friendThreshold, nextFriendThreshold, friendRep
                        else
                                min, max, value = 0, 1, 1
                        end
                        standing = 5
                elseif C_Reputation.IsFactionParagon(factionID) then
                        local currentValue, threshold = C_Reputation.GetFactionParagonInfo(factionID)
                        currentValue = mod(currentValue, threshold)
                        min, max, value = 0, threshold, currentValue
                else
                        if standing == MAX_REPUTATION_REACTION then min, max, value = 0, 1, 1 end
                end
                bar:SetStatusBarColor(FACTION_BAR_COLORS[standing].r, FACTION_BAR_COLORS[standing].g, FACTION_BAR_COLORS[standing].b, .85)
                bar:SetMinMaxValues(min, max)
                bar:SetValue(value)
                bar:Show()
               
        --azerite
        elseif C_AzeriteItem.HasActiveAzeriteItem() then
                local azeriteItemLocation = C_AzeriteItem.FindActiveAzeriteItem()
                local xp, totalLevelXP = C_AzeriteItem.GetAzeriteItemXPInfo(azeriteItemLocation)
                bar:SetStatusBarColor(.9, .8, .6)
                bar:SetMinMaxValues(0, totalLevelXP)
                bar:SetValue(xp)
                bar:Show()
               
        --artifact
        elseif HasArtifactEquipped() then
                local _, _, _, _, totalXP, pointsSpent, _, _, _, _, _, _, artifactTier = C_ArtifactUI.GetEquippedArtifactInfo()
                local _, xp, xpForNextPoint = ArtifactBarGetNumArtifactTraitsPurchasableFromXP(pointsSpent, totalXP, artifactTier)
                xp = xpForNextPoint == 0 and 0 or xp
                bar:SetStatusBarColor(.9, .8, .6)
                bar:SetMinMaxValues(0, xpForNextPoint)
                bar:SetValue(xp)
                bar:Show()
        else
                bar:Hide()
                backdrop:Hide()
        end
       
end

-------------------------
--tooltip function
-------------------------

mouseFrame:SetScript("OnEnter", function()
        GameTooltip:SetOwner(mouseFrame, "ANCHOR_BOTTOMLEFT", -1, 6)
        GameTooltip:SetClampedToScreen( true )
        GameTooltip:ClearLines()
        GameTooltip:AddLine(UnitName("player").." ("..LEVEL.." "..UnitLevel("player")..")", C.r, C.g, C.b)
       
        --experience
        if UnitLevel("player") < MAX_PLAYER_LEVEL then
                local xp, mxp, rxp = UnitXP("player"), UnitXPMax("player"), GetXPExhaustion()
                GameTooltip:AddDoubleLine("XP: ", string.format('%s/%s (%d%%)', BreakUpLargeNumbers(xp), BreakUpLargeNumbers(mxp), (xp/mxp)*100), r, g, b, 1, 1, 1)
                GameTooltip:AddDoubleLine("Remaining: ", string.format('%s', BreakUpLargeNumbers(mxp-xp)), r, g, b, 1, 1, 1)
                if rxp then
                        GameTooltip:AddDoubleLine("Rested: ", "+"..rxp.." ("..floor(rxp/mxp*100).."%)", r, g, b, .3, .7, 1)
                end
                if IsXPUserDisabled() then GameTooltip:AddLine("|cffff0000"..XP..LOCKED) end
        end
       
        --reputation
        if GetWatchedFactionInfo() then
                local name, standing, min, max, value, factionID = GetWatchedFactionInfo()
                local friendID, _, _, _, _, _, friendTextLevel, _, nextFriendThreshold = GetFriendshipReputation(factionID)
                local currentRank, maxRank = GetFriendshipReputationRanks(friendID)
                local standingtext
                if friendID then
                        if maxRank > 0 then
                                name = name.." ("..currentRank.." / "..maxRank..")"
                        end
                        if not nextFriendThreshold then
                                value = max - 1
                        end
                        standingtext = friendTextLevel
                else
                        if standing == MAX_REPUTATION_REACTION then
                                max = min + 1e3
                                value = max - 1
                        end
                        standingtext = GetText("FACTION_STANDING_LABEL"..standing, UnitSex("player"))
                end
                GameTooltip:AddLine(" ")
                GameTooltip:AddLine(name, 243/250, 222627/250, 57/250)
                GameTooltip:AddDoubleLine(standingtext, value - min.."/"..max - min.." ("..floor((value - min)/(max - min)*100).."%)", 131/250, 239/250, 131/250, 1,1,1)

                if C_Reputation.IsFactionParagon(factionID) then
                        local currentValue, threshold = C_Reputation.GetFactionParagonInfo(factionID)
                        local paraCount = floor(currentValue/threshold)
                        currentValue = mod(currentValue, threshold)
                        GameTooltip:AddDoubleLine("ParagonRep"..paraCount, currentValue.."/"..threshold.." ("..floor(currentValue/threshold*100).."%)", 131/250, 239/250, 131/250, 1,1,1)
                end
        end
       
        --honor
        if IsWatchingHonorAsXP() then
                local current, max, level = UnitHonor("player"), UnitHonorMax("player"), UnitHonorLevel("player")
                GameTooltip:AddLine(" ")
                GameTooltip:AddLine(HONOR, .243/250, 222627/250, 57/250)
                GameTooltip:AddDoubleLine(LEVEL.." "..level, current.."/"..max, 131/250, 239/250, 131/250, 1,1,1)
        end
       
        --azerite
        if C_AzeriteItem.HasActiveAzeriteItem() then
                local azeriteItemLocation = C_AzeriteItem.FindActiveAzeriteItem()
                local azeriteItem = Item:CreateFromItemLocation(azeriteItemLocation)
                local azeriteItemName = azeriteItem:GetItemName()
                local xp, totalLevelXP = C_AzeriteItem.GetAzeriteItemXPInfo(C_AzeriteItem.FindActiveAzeriteItem())
                local currentLevel = C_AzeriteItem.GetPowerLevel(azeriteItemLocation)
                GameTooltip:AddLine(" ")
                GameTooltip:AddLine(azeriteItemName.." ("..format(SPELLBOOK_AVAILABLE_AT, currentLevel)..")", 243/250, 222627/250, 57/250)
                GameTooltip:AddDoubleLine(ARTIFACT_POWER, F.Numb(xp).."/"..F.Numb(totalLevelXP).." ("..floor(xp/totalLevelXP*100).."%)", 131/250, 239/250, 131/250, 1,1,1)
        end
       
        --artifact
        if HasArtifactEquipped() then
                local _, _, name, _, totalXP, pointsSpent, _, _, _, _, _, _, artifactTier = C_ArtifactUI.GetEquippedArtifactInfo()
                local num, xp, xpForNextPoint = ArtifactBarGetNumArtifactTraitsPurchasableFromXP(pointsSpent, totalXP, artifactTier)
                GameTooltip:AddLine(" ")
                if pointsSpent > 51 then
                        GameTooltip:AddLine(name.." ("..format(SPELLBOOK_AVAILABLE_AT, pointsSpent).." ".."Paragon"..(pointsSpent - 51)..")", 243/250, 222627/250, 57/250)
                else
                        GameTooltip:AddLine(name.." ("..format(SPELLBOOK_AVAILABLE_AT, pointsSpent)..")", 243/250, 222627/250, 57/250)
                end
                local numText = num > 0 and " ("..num..")" or ""
                GameTooltip:AddDoubleLine(ARTIFACT_POWER, F.Numb(totalXP)..numText, 131/250, 239/250, 131/250, 1,1,1)
                if xpForNextPoint ~= 0 then
                        local perc = " ("..floor(xp/xpForNextPoint*100).."%)"
                        GameTooltip:AddDoubleLine("Next Trait", F.Numb(xp).."/"..F.Numb(xpForNextPoint)..perc, 131/250, 239/250, 131/250, 1,1,1)
                end
        end
       
        GameTooltip:Show()
       
end)

mouseFrame:SetScript("OnMouseDown", function()
        if not ArtifactFrame or not ArtifactFrame:IsShown() then
                ShowUIPanel(SocketInventoryItem(16))
        elseif ArtifactFrame and ArtifactFrame:IsShown() then
                HideUIPanel(ArtifactFrame)
        end
end)

mouseFrame:SetScript("OnLeave", function()
        GameTooltip:Hide()
end)

------------------------
--events
------------------------
F.RegisterEvent("PLAYER_ENTERING_WORLD", updateStatus)
F.RegisterEvent("PLAYER_XP_UPDATE", updateStatus) --xp
F.RegisterEvent("PLAYER_LEVEL_UP", updateStatus) --xp
F.RegisterEvent("UPDATE_EXHAUSTION", updateStatus) --xp
F.RegisterEvent("ENABLE_XP_GAIN", updateStatus) --xp
F.RegisterEvent("DISABLE_XP_GAIN", updateStatus) --xp
F.RegisterEvent("ARTIFACT_XP_UPDATE", updateStatus) --artifact
F.RegisterEvent("UNIT_INVENTORY_CHANGED", updateStatus) --artifact/azerite
F.RegisterEvent("AZERITE_ITEM_EXPERIENCE_CHANGED", updateStatus) -- azerite
F.RegisterEvent("UPDATE_FACTION", updateStatus) --reputation


Rilgamon 07-29-18 10:08 AM

Lua Code:
  1. if UnitLevel("player") < MAX_PLAYER_LEVEL
Not sure ... but MAX_PLAYER_LEVEL is still 110. So your xp is not triggered for maxed chars?

Kanegasi 07-29-18 11:10 AM

MAX_PLAYER_LEVEL is declared in this function in ReputationFrame.lua:

Lua Code:
  1. function ReputationWatchBar_UpdateMaxLevel()
  2.     -- Initialize max player level
  3.     MAX_PLAYER_LEVEL = MAX_PLAYER_LEVEL_TABLE[GetExpansionLevel()];
  4. end

MX_PLAYER_LEVEL_TABLE is declared in Constants.lua:

Lua Code:
  1. MAX_PLAYER_LEVEL_TABLE = {};
  2. MAX_PLAYER_LEVEL_TABLE[LE_EXPANSION_CLASSIC] = 60;
  3. MAX_PLAYER_LEVEL_TABLE[LE_EXPANSION_BURNING_CRUSADE] = 70;
  4. MAX_PLAYER_LEVEL_TABLE[LE_EXPANSION_WRATH_OF_THE_LICH_KING] = 80;
  5. MAX_PLAYER_LEVEL_TABLE[LE_EXPANSION_CATACLYSM] = 85;
  6. MAX_PLAYER_LEVEL_TABLE[LE_EXPANSION_MISTS_OF_PANDARIA] = 90;
  7. MAX_PLAYER_LEVEL_TABLE[LE_EXPANSION_WARLORDS_OF_DRAENOR] = 100;
  8. MAX_PLAYER_LEVEL_TABLE[LE_EXPANSION_LEGION] = 110;
  9. MAX_PLAYER_LEVEL_TABLE[LE_EXPANSION_BATTLE_FOR_AZEROTH] = 120;
  10. MAX_PLAYER_LEVEL_TABLE[LE_EXPANSION_9_0] = 120;
  11. MAX_PLAYER_LEVEL_TABLE[LE_EXPANSION_10_0] = 120;
  12. MAX_PLAYER_LEVEL_TABLE[LE_EXPANSION_11_0] = 120;

And the listed LE globals are as follows:

Lua Code:
  1. LE_EXPANSION_CLASSIC = 0
  2. LE_EXPANSION_BURNING_CRUSADE = 1
  3. LE_EXPANSION_WRATH_OF_THE_LICH_KING = 2
  4. LE_EXPANSION_CATACLYSM = 3
  5. LE_EXPANSION_MISTS_OF_PANDARIA = 4
  6. LE_EXPANSION_WARLORDS_OF_DRAENOR = 5
  7. LE_EXPANSION_LEGION = 6
  8. LE_EXPANSION_BATTLE_FOR_AZEROTH = 7
  9. LE_EXPANSION_9_0 = 8
  10. LE_EXPANSION_10_0 = 9
  11. LE_EXPANSION_11_0 = 10

GetExpansionLevel() returns what a player can currently access, which is currently 6 for everyone due to Legion being included with just a sub, while GetAccountExpansionLevel() returns what BfA purchasers will be able to access on August 14th, which is 7. Therefore, the global MAX_LEVEL_PLAYER should be 110 for everyone with a sub as of this comment.

I'm not sure why your XP bar is showing on your max level characters after a reload, but your code is working correctly at login.

Zenjaa 07-29-18 11:36 AM

But shouldn't the elseif statement which can't really return nothing at this point (everyone is wearing an artifact weapon still and my chars do have a reputation tracked) trigger despite all this?

Apologies if this is actually a dumb question. But that would mean, that my logic behind the code is actually wrong.

Edit: the scenario described above is exactly what happens after the reloadui btw

Rilgamon 07-29-18 11:53 AM

Only one part (the first that returns true) of your if/elsif construct will be handled.
Since your xp-bar is only touched when playerlevel is below max level it should never trigger on maxed chars.
You should change your if/elsif construct to update the part your event indicates. And if you want your maxed chars to have an xp-bar you need to allow it. The current code only handles chars < max level

Rilgamon 07-29-18 12:04 PM

Perhaps you can add ADDON_LOADED/PLAYER_ENTERING_WORLD event to call your update function.
Your function calls might be triggered so early that they dont return the right value.

Edit: What I mean is that you only register ADDON_LOADED/PLAYER_ENTERING_WORLD and when that fires you register your
other events.

Zenjaa 07-29-18 03:00 PM

hmm... thank you for your help. Probably gonna end up, splitting the different modules and see how that goes then.

Tim 07-29-18 09:08 PM

You could add a timer and have it call your function after a certain duration.

Code:

F:SetScript("OnEvent", function(_, event)

  if (event == "PLAYER_ENTERING_WORLD") then
      C_Timer.After(5, updateStatus)
  end

end)


myrroddin 07-29-18 09:30 PM

The Azerite Bar does not exist in game yet, because no gear uses it. What I had to do in my ElvUI plugin is check if an Azerite item is found.
Lua Code:
  1. local azeriteItemLocation = C_AzeriteItem.FindActiveAzeriteItem()
  2. if azeriteItemLocation then
  3.     -- do stuff
  4. end
You can create your status bar now, give it starting text, color it, whatever. You'll have to Hide() it until the expansion drops, and any event scripts will have to check as I have above. The code you see is found inside my event handler that updates the bar.

Zenjaa 07-30-18 02:06 AM

solved
 
Well...it took me a while and I might have a headache now, but I found the problem.

Logic, code and events did work out fine in the first place. Nothing wrong there.

But I found this advice from Seerah on another thread in this forum:
Quote:

Frames are hidden and shown when their parents are (unless specifically hidden/shown on their own).
Which makes total sense... could have thought about that earlier.

So I went and simply added
Code:

backdrop:Show()
to the different parts of the updateStatus function, since I specified the backdrop as the parent frame and voilá... everthing is working as intended.

Thought I might leave this comment here for anyone that might have similar problems.


All times are GMT -6. The time now is 10:03 AM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI