Thread Tools Display Modes
08-08-14, 05:36 PM   #1
liquidbase
A Warpwood Thunder Caller
 
liquidbase's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2010
Posts: 97
Division by zero for XP

Hi @all

I use for my XP display the following lines:

Lua Code:
  1. local function GetPlayerXP()
  2.     return UnitXP("player"), UnitXPMax("player")
  3. end

and

Lua Code:
  1. local XP, maxXP = GetPlayerXP()
  2. local restXP = GetXPExhaustion()
  3. local percXP = math.floor((XP / maxXP) * 100)

The last line gives rise to the error mentioned in the thread title. The funny thing here is that I use the same script on the live server and it works there. Also on the Beta server, the correct values ​​are calculated and shown what you see on the screenshot below.

The error also occurs only at login and at each subsequent reload it exists not even. My question now is ... Do I have a mistake, I do not see the forest for the trees or Blizzard has an error return values​​?

Thanks in advance for all input.

greetz
liquid
 
08-08-14, 05:54 PM   #2
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
They've done this for the past few betas - I believe it's so they can optimize the default UI; cut out any instances of division-by-zero that are otherwise handled (likely less efficiently) by the live version's Lua parser. Division by zero is, after all, something most programmers code against, not for.
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.
 
08-08-14, 06:08 PM   #3
liquidbase
A Warpwood Thunder Caller
 
liquidbase's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2010
Posts: 97
So then it would simply wait and see what is no satisfactory answer
 
08-08-14, 06:56 PM   #4
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
Lua Code:
  1. local percXP = (XP == 0) and 0 or math.floor((XP / maxXP) * 100)
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.
 
08-08-14, 07:22 PM   #5
liquidbase
A Warpwood Thunder Caller
 
liquidbase's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2010
Posts: 97
Thanks Torhal to solve the problem with this idea I did not come. I should just take a break

Last edited by liquidbase : 08-08-14 at 07:31 PM.
 
08-08-14, 07:26 PM   #6
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
Shouldn't that be (maxXP == 0)?
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
 
08-08-14, 07:32 PM   #7
liquidbase
A Warpwood Thunder Caller
 
liquidbase's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2010
Posts: 97
Could be netter. I will test it
Thanks for all help!
 
08-08-14, 07:59 PM   #8
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
Originally Posted by Torhal View Post
They've done this for the past few betas - I believe it's so they can optimize the default UI; cut out any instances of division-by-zero that are otherwise handled (likely less efficiently) by the live version's Lua parser. Division by zero is, after all, something most programmers code against, not for.
Lua is one of the few languages that makes use of the full IEEE 754 specification for floating point numbers by allowing the casting of divide-by-zero into signed infinity. Whether this is natively done by the computer's floating point processor or trapped and substituted for by the Lua interpreter, it would be much faster since the execution lies in C code rather than forcing the check through the interpreter itself.


Their decision to force Lua to throw division-by-zero errors was to make it act more like C.
Originally Posted by Bashiok
This is an intended change to keep the lua engine in line with changes to our game engine.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
 
08-08-14, 08:23 PM   #9
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
I'm curious why you have the extra function and function call and aren't just doing this?

Lua Code:
  1. local XP, maxMP = UnitXP("player"), UnitXPMax("player")
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

 
08-08-14, 10:49 PM   #10
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
Originally Posted by SDPhantom View Post
Shouldn't that be (maxXP == 0)?
I wouldn't see why - no matter your level, the maximum experience for that level would certainly be above 0. However, at level 1, with no experience gained...
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.
 
08-08-14, 11:08 PM   #11
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
It happened, otherwise the error would've never been thrown. The code as-is can already handle if XP is zero, but not maxXP.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 08-08-14 at 11:11 PM.
 
08-09-14, 12:57 AM   #12
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
Originally Posted by SDPhantom View Post
It happened, otherwise the error would've never been thrown. The code as-is can already handle if XP is zero, but not maxXP.
Meh. This is what I get for skimming. Whatever - I set him on the right path, at least. I hope. Damn!
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.
 
08-09-14, 02:26 PM   #13
liquidbase
A Warpwood Thunder Caller
 
liquidbase's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2010
Posts: 97
@Seerah
You're right. The function is a relict from the old script within the UI I had only copied.

@Torhal
Thanks to you it works fine

@SDPhantom
with (maxXP == 0) the script throw a error if I want to display the value in a tooltip because of the nil-value.
 
08-09-14, 09:36 PM   #14
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by liquidbase View Post
with (maxXP == 0) the script throw a error if I want to display the value in a tooltip because of the nil-value.
So wrap the whole thing in a check to make sure the maxXP isn't zero, and skip doing anything with XP in that case, since there's no valid information to show.

If you need help with specific changes, you'll have to show your code.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
 
08-10-14, 01:06 PM   #15
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
Originally Posted by liquidbase View Post
with (maxXP == 0) the script throw a error if I want to display the value in a tooltip because of the nil-value.
If you're combining both mine and Torhal's conditions, there may be unexpected results depending on how you write it. It will need to look like this.
Code:
local percXP = (maxXP == 0) and 0 or math.floor((XP / maxXP) * 100)
Otherwise, I don't see how it's possible that a nil can pass through without throwing another error at this line.



If you post your entire code, we'll be able to help better and may catch problems that you might not see.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 08-10-14 at 01:35 PM.
 
08-10-14, 06:40 PM   #16
liquidbase
A Warpwood Thunder Caller
 
liquidbase's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2010
Posts: 97
Sorry for the late response.
The error occurs on line 89 if the character has no rested experience. Without (maxXP == 0) the script works as should. And the problem is not "nil" (my mistake in the interpretation) but it is a boolean instead of strings returned. With the expression the script throws the following error:

Lua Code:
  1. DuffedUI-8.0015\modules\misc\experience.lua:89: bad argument #4 to "format" (string expected, got boolean)
  2. <in C code>
  3. DuffedUI-8.0015\modules\misc\experience.lua:89: in function <DuffedUI\modules\misc\experience.lua:67>
  4.  
  5. Locals:
  6. XP = 0
  7. maxXP = 0
  8. restXP = nil
  9. percXP = true
  10. (*temporary) = <function> defined =[C]:-1
  11. (*temporary) = mouseFrame_Text {
  12.  0 = <userdata>
  13. }
  14. IsMaxLevel = <function> defined @Interface\AddOns\DuffedUI\modules\misc\experience.lua:20
  15. xpBar = Experience_xpBar {
  16.  0 = <userdata>
  17.  lockShow = 0
  18. }
  19. restedxpBar = Experience_restedxpBar {
  20.  0 = <userdata>
  21.  lockShow = 0
  22. }
  23. repBar = Experience_repBar {
  24.  0 = <userdata>
  25.  lockShow = 0
  26. }
  27. barHeight = 10
  28. backdrop = Experience_Backdrop {
  29.  0 = <userdata>
  30.  backdrop = <unnamed> {
  31.  }
  32. }
  33. Text = mouseFrame_Text {
  34.  0 = <userdata>
  35. }

Thanks for all help, you guys are great

Complete Script:
Lua Code:
  1. local D, C, L = unpack(select(2, ...))
  2.  
  3. local barHeight, barWidth = 10, 378
  4. local font, fontsize, flags = C["media"].font, 11, "THINOUTLINE"
  5. local barTex, flatTex = C["media"].normTex
  6. local color = RAID_CLASS_COLORS[D.Class]
  7. local FactionInfo = {
  8.     [1] = {{ 170/255, 70/255,  70/255 }, "Hated", "FFaa4646"},
  9.     [2] = {{ 170/255, 70/255,  70/255 }, "Hostile", "FFaa4646"},
  10.     [3] = {{ 170/255, 70/255,  70/255 }, "Unfriendly", "FFaa4646"},
  11.     [4] = {{ 200/255, 180/255, 100/255 }, "Neutral", "FFc8b464"},
  12.     [5] = {{ 75/255,  175/255, 75/255 }, "Friendly", "FF4baf4b"},
  13.     [6] = {{ 75/255,  175/255, 75/255 }, "Honored", "FF4baf4b"},
  14.     [7] = {{ 75/255,  175/255, 75/255 }, "Revered", "FF4baf4b"},
  15.     [8] = {{ 155/255,  255/255, 155/255 }, "Exalted","FF9bff9b"},
  16. }
  17.  
  18. function colorize(r) return FactionInfo[r][3] end
  19.  
  20. local function IsMaxLevel()
  21.     if UnitLevel("player") == MAX_PLAYER_LEVEL then
  22.         return true
  23.     end
  24. end
  25.  
  26. local backdrop = CreateFrame("Frame", "Experience_Backdrop", UIParent)
  27. backdrop:Size(barWidth, barHeight)
  28. backdrop:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", 7, 178)
  29. backdrop:SetBackdropColor(C["general"].backdropcolor)
  30. backdrop:SetBackdropBorderColor(C["general"].backdropcolor)
  31. backdrop:CreateBackdrop()
  32.  
  33. local xpBar = CreateFrame("StatusBar",  "Experience_xpBar", backdrop, "TextStatusBar")
  34. xpBar:SetWidth(barWidth)
  35. xpBar:SetHeight(GetWatchedFactionInfo() and (barHeight) or barHeight)
  36. xpBar:SetPoint("TOP", backdrop,"TOP", 0, 0)
  37. xpBar:SetStatusBarTexture(barTex)
  38. if C["general"].classcolor then xpBar:SetStatusBarColor(color.r, color.g, color.b) else xpBar:SetStatusBarColor(31/255, 41/255, 130/255) end
  39.  
  40. local restedxpBar = CreateFrame("StatusBar", "Experience_restedxpBar", backdrop, "TextStatusBar")
  41. restedxpBar:SetHeight(GetWatchedFactionInfo() and (barHeight) or barHeight)
  42. restedxpBar:SetWidth(barWidth)
  43. restedxpBar:SetPoint("TOP", backdrop, "TOP", 0, 0)
  44. restedxpBar:SetStatusBarTexture(barTex)
  45. restedxpBar:Hide()
  46.  
  47. local repBar = CreateFrame("StatusBar", "Experience_repBar", backdrop, "TextStatusBar")
  48. repBar:SetWidth(barWidth)
  49. repBar:SetHeight(IsMaxLevel() and barHeight - 0 or 0)
  50. repBar:SetPoint("BOTTOM", backdrop, "BOTTOM", 0, 0)
  51. repBar:SetStatusBarTexture(barTex)
  52.  
  53. local mouseFrame = CreateFrame("Frame", "Experience_mouseFrame", backdrop)
  54. mouseFrame:SetAllPoints(backdrop)
  55. mouseFrame:EnableMouse(true)
  56.  
  57. local Text = mouseFrame:CreateFontString("mouseFrame_Text", "OVERLAY")
  58. Text:SetFont(font, fontsize, flags)
  59. Text:SetPoint("CENTER", mouseFrame, "CENTER", 0, 0)
  60.  
  61. backdrop:SetFrameLevel(0)
  62. restedxpBar:SetFrameLevel(1)
  63. repBar:SetFrameLevel(2)
  64. xpBar:SetFrameLevel(2)
  65. mouseFrame:SetFrameLevel(3)
  66.  
  67. local function updateStatus()
  68.     local XP, maxXP, restXP = UnitXP("player"), UnitXPMax("player"), GetXPExhaustion()
  69.     local percXP = ((XP == 0) and (maxXP == 0)) or (math.floor((XP / maxXP) * 100))
  70.  
  71.     if IsMaxLevel() then
  72.         xpBar:Hide()
  73.         restedxpBar:Hide()
  74.         repBar:SetHeight(barHeight)
  75.         if not GetWatchedFactionInfo() then backdrop:Hide() else backdrop:Show() end
  76.     else
  77.         xpBar:SetMinMaxValues(min(0, XP), maxXP)
  78.         xpBar:SetValue(XP)
  79.  
  80.         if restXP then
  81.             Text:SetText(format("%s/%s (%s%%|cffb3e1ff+%d%%|r)", D.ShortValue(XP), D.ShortValue(maxXP), percXP, restXP / maxXP * 100))
  82.             restedxpBar:Show()
  83.             local r, g, b = color.r, color.g, color.b
  84.             restedxpBar:SetStatusBarColor(r, g, b, .40)
  85.             restedxpBar:SetMinMaxValues(min(0, XP), maxXP)
  86.             restedxpBar:SetValue(XP + restXP)
  87.         else
  88.             restedxpBar:Hide()
  89.             Text:SetText(format("%s/%s (%s%%)", D.ShortValue(XP), D.ShortValue(maxXP), percXP))
  90.         end
  91.  
  92.         if GetWatchedFactionInfo() then
  93.             xpBar:SetHeight(barHeight)
  94.             restedxpBar:SetHeight(barHeight)
  95.             repBar:SetHeight(2)
  96.             repBar:Show()
  97.         else
  98.             xpBar:SetHeight(barHeight)
  99.             restedxpBar:SetHeight(barHeight)
  100.             repBar:Hide()
  101.         end
  102.     end
  103.  
  104.     if GetWatchedFactionInfo() then
  105.         local name, rank, minRep, maxRep, value = GetWatchedFactionInfo()
  106.         repBar:SetMinMaxValues(minRep, maxRep)
  107.         repBar:SetValue(value)
  108.         repBar:SetStatusBarColor(unpack(FactionInfo[rank][1]))
  109.         Text:SetText(format("%d / %d (%d%%)", value - minRep, maxRep - minRep, (value - minRep) / (maxRep - minRep) * 100))
  110.     end
  111.  
  112.     mouseFrame:SetScript("OnEnter", function()
  113.         GameTooltip:SetOwner(mouseFrame, "ANCHOR_BOTTOMLEFT", -3, barHeight)
  114.         GameTooltip:ClearLines()
  115.         if not IsMaxLevel() then
  116.             GameTooltip:AddLine("Experience:")
  117.             GameTooltip:AddLine(string.format("XP: %s/%s (%d%%)", D.CommaValue(XP), D.CommaValue(maxXP), (XP / maxXP) * 100))
  118.             GameTooltip:AddLine(string.format("Remaining: %s", D.CommaValue(maxXP - XP)))
  119.             if restXP then GameTooltip:AddLine(string.format("|cffb3e1ffRested: %s (%d%%)", D.CommaValue(restXP), restXP / maxXP * 100)) end
  120.         end
  121.         if GetWatchedFactionInfo() then
  122.             local name, rank, min, max, value = GetWatchedFactionInfo()
  123.             if not IsMaxLevel() then GameTooltip:AddLine(" ") end
  124.             GameTooltip:AddLine(string.format("Reputation: %s", name))
  125.             GameTooltip:AddLine(string.format("Standing: |c"..colorize(rank) .. "%s|r", FactionInfo[rank][2]))
  126.             GameTooltip:AddLine(string.format("Rep: %s/%s (%d%%)", D.CommaValue(value - min), D.CommaValue(max - min), (value - min)/(max - min) * 100))
  127.             GameTooltip:AddLine(string.format("Remaining: %s", D.CommaValue(max - value)))
  128.         end
  129.         GameTooltip:Show()
  130.     end)
  131.     mouseFrame:SetScript("OnLeave", function() GameTooltip:Hide() end)
  132. end
  133.  
  134. local frame = CreateFrame("Frame",nil,UIParent)
  135. frame:RegisterEvent("PLAYER_LEVEL_UP")
  136. frame:RegisterEvent("PLAYER_XP_UPDATE")
  137. frame:RegisterEvent("UPDATE_EXHAUSTION")
  138. frame:RegisterEvent("CHAT_MSG_COMBAT_FACTION_CHANGE")
  139. frame:RegisterEvent("UPDATE_FACTION")
  140. frame:RegisterEvent("PLAYER_ENTERING_WORLD")
  141. frame:SetScript("OnEvent", updateStatus)
 
08-10-14, 07:30 PM   #17
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
Do what SDPhantom says.
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

 
08-11-14, 02:19 AM   #18
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by liquidbase View Post
local XP, maxXP, restXP = UnitXP("player"), UnitXPMax("player"), GetXPExhaustion()
local percXP = ((XP == 0) and (maxXP == 0)) or (math.floor((XP / maxXP) * 100))
That second line is the problem; I don't think it's doing what you think it's doing. What you wrote is the equivalent of this:

Code:
if XP == 0 and maxXP == 0 then
     percXP = true
else
     percXP = floor(XP / maxXP * 100)
end
SDPhantom's suggestion will prevent the error from showing up, but I'd suggest doing this instead:

Code:
local XP, maxXP, restXP = UnitXP("player"), UnitXPMax("player"), GetXPExhaustion()
if not maxXP or maxXP == 0 then return end
local percXP = floor(XP / maxXP * 100)
There's no point in going on with the rest of your display logic if you don't have any valid information to display, or you just end up displaying wrong information.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
 
08-11-14, 04:57 AM   #19
liquidbase
A Warpwood Thunder Caller
 
liquidbase's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2010
Posts: 97
Thumbs up

Done it Phanx.
Thanks for all the input
 
 

WoWInterface » Site Forums » Archived Beta Forums » WoD Beta archived threads » Division by zero for XP

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