Thread Tools Display Modes
07-29-18, 09:49 AM   #1
Zenjaa
A Deviate Faerie Dragon
Join Date: Jul 2009
Posts: 10
Question [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

Last edited by Zenjaa : 07-30-18 at 02:06 AM. Reason: Solved
  Reply With Quote
07-29-18, 10:08 AM   #2
Rilgamon
Premium Member
 
Rilgamon's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 822
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?
__________________
The cataclysm broke the world ... and the pandas could not fix it!
  Reply With Quote
07-29-18, 11:10 AM   #3
Kanegasi
A Molten Giant
 
Kanegasi's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2007
Posts: 666
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.
  Reply With Quote
07-29-18, 11:36 AM   #4
Zenjaa
A Deviate Faerie Dragon
Join Date: Jul 2009
Posts: 10
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

Last edited by Zenjaa : 07-29-18 at 11:40 AM.
  Reply With Quote
07-29-18, 11:53 AM   #5
Rilgamon
Premium Member
 
Rilgamon's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 822
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
__________________
The cataclysm broke the world ... and the pandas could not fix it!
  Reply With Quote
07-29-18, 12:04 PM   #6
Rilgamon
Premium Member
 
Rilgamon's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 822
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.
__________________
The cataclysm broke the world ... and the pandas could not fix it!

Last edited by Rilgamon : 07-29-18 at 12:40 PM.
  Reply With Quote
07-29-18, 03:00 PM   #7
Zenjaa
A Deviate Faerie Dragon
Join Date: Jul 2009
Posts: 10
hmm... thank you for your help. Probably gonna end up, splitting the different modules and see how that goes then.
  Reply With Quote
07-29-18, 09:08 PM   #8
Tim
A Rage Talon Dragon Guard
 
Tim's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2008
Posts: 308
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)
__________________
AddOns: Tim @ WoWInterface
Characters: Mage, Priest, Devoker, Pally
Battle Tag: Mysterio#11164
Current PC Setup: PCPartPicker List
  Reply With Quote
07-29-18, 09:30 PM   #9
myrroddin
A Pyroguard Emberseer
 
myrroddin's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 1,240
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.
  Reply With Quote
07-30-18, 02:06 AM   #10
Zenjaa
A Deviate Faerie Dragon
Join Date: Jul 2009
Posts: 10
Smile 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:
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.
  Reply With Quote

WoWInterface » Developer Discussions » General Authoring Discussion » [Solved] Custom xp,ap,azerite bar does not trigger on login, only after reloadui

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off