Module:Experience
Documentation for this module may be created at Module:Experience/doc
-- <nowiki>
--
-- All functions relating to experience needed etc
--
local p = {}
local commas = require('Module:Addcommas')
local yn = require('Module:Yesno')
local NormalXPAtLevel = mw.loadData('Module:Experience/data')
local NormalXPAtLevelUnr = mw.loadData('Module:Experience/dataunr')
local EliteXPAtLevel = mw.loadData('Module:Experience/elitedata')
local EliteXPAtLevelUnr = mw.loadData('Module:Experience/elitedataunr')
--
-- Returns lowest needed XP to have required level
-- [[Template:XP]]
--
function p._xp_at_level(level, isElite)
local XPAtLevel = NormalXPAtLevel
if yn(isElite) then
XPAtLevel = EliteXPAtLevel
end
-- calling tonumber on a string returns nil
if not level then
return "You must pass numbers as arguments"
end
return XPAtLevel[level]
end
function p.xp_at_level(frame)
return p._xp_at_level(tonumber(frame.args[1]), frame.args.elite)
end
-- Same as above, but with the 120/150 level cap removed
function p._xp_at_level_unr(level, isElite)
local XPAtLevelUnr = NormalXPAtLevelUnr
if yn(isElite) then
XPAtLevelUnr= EliteXPAtLevelUnr
end
-- calling tonumber on a string returns nil
if not level then
return "You must pass numbers as arguments"
end
return XPAtLevelUnr[level]
end
function p.xp_at_level_unr(frame)
return p._xp_at_level_unr(tonumber(frame.args[1]), frame.args.elite)
end
--
-- The maximum amount of experience you can have at a given level
-- [[Template:Max XP for level]]
--
function p._max_xp_at_level(level, isElite)
local XPAtLevel = NormalXPAtLevel
if yn(isElite) then
XPAtLevel = EliteXPAtLevel
end
-- calling tonumber on a string returns nil
if not level then
return "You must pass numbers as arguments"
end
if level == -1 then
return 0
elseif level <= 0 or level > 120 then
return "Value must be in the range 1 - 120"
-- Highest level is 120, highest XP is 200M
elseif (level == 120) then
return 200000000
end
-- Just in case
level = math.floor(level)
-- Return XP required for the *next* level minus 1
local xp_at_next = XPAtLevel[level + 1]
return xp_at_next - 1
end
function p.max_xp_at_level(frame)
return p._max_xp_at_level(tonumber(frame.args[1]), frame.args.elite)
end
--
-- What level you have when at a given xp
-- [[Template:Level]]
--
function p._level_at_xp(xp, isElite)
local XPAtLevel = NormalXPAtLevel
if yn(isElite) then
XPAtLevel = EliteXPAtLevel
end
-- just in case
if type(xp) == 'string' then
xp = commas._strip(xp)
xp = tonumber(xp)
end
-- calling tonumber on an empty string returns nil
if not xp then
return "You must pass numbers as arguments"
end
if xp < 0 or xp > 200000000 then
return "Value must be in the range 0 - 200,000,000"
end
local level
local level_max = 120
if yn(isElite) then
level_max = 150
end
for i=level_max,1,-1 do
if (XPAtLevel[i]<= xp) then
level = i
break
end
end
return level
end
function p.level_at_xp(frame)
return p._level_at_xp(frame.args[1], frame.args.elite)
end
-- Same as above, but with the 120/150 level cap removed
function p._level_at_xp_unr(xp, isElite)
local XPAtLevelUnr = NormalXPAtLevelUnr
if yn(isElite) then
XPAtLevelUnr = EliteXPAtLevelUnr
end
-- just in case
if type(xp) == 'string' then
xp = commas._strip(xp)
xp = tonumber(xp)
end
-- calling tonumber on a string returns nil
if not xp then
return "You must pass numbers as arguments"
end
if xp == -1 then
return 0
elseif xp < 0 or xp > 200000000 then
return "Value must be in the range 0 - 200,000,000"
end
local level
local level_max = 126
if yn(isElite) then
level_max = 150
end
for i=level_max,1,-1 do
if (XPAtLevelUnr[i]<= xp) then
level = i
break
end
end
return level
end
function p.level_at_xp_unr(frame)
return p._level_at_xp_unr(frame.args[1], frame.args.elite)
end
--
-- Experience needed to obtain a level from a given amount of xp
-- If current xp is greater than target, returns 0
-- [[Template:XP to Level]]
--
function p._xp_to_level(xp, target, isElite)
local XPAtLevel = NormalXPAtLevel
if yn(isElite) then
XPAtLevel = EliteXPAtLevel
end
-- just in case
if type(xp) == 'string' then
xp = commas._strip(xp)
xp = tonumber(xp)
end
if (xp < 0 or xp > 200000000) then
return "XP value must be in the range 0 - 200,000,000"
end
if (target < 2 or target > 120) then
return "Level value must be in the range 2 - 120"
end
-- calling tonumber on a string returns nil
if not xp or not target then
return "You must pass numbers as arguments"
end
local target_xp = XPAtLevel[target]
if (xp >= target_xp) then
return 0
else
return target_xp - xp
end
end
function p.xp_to_level(frame)
return p._xp_to_level(frame.args[1], tonumber(frame.args[2]), frame.args.elite)
end
--
-- Experience between two levels; will always return absolute value
-- [[Template:XP level to level]]
--
function p._level_to_level(level1, level2, isElite)
local XPAtLevel = NormalXPAtLevel
if yn(isElite) then
XPAtLevel = EliteXPAtLevel
end
-- just in case
if type(level1) == 'string' then
level1 = commas._strip(level1)
level1 = tonumber(level1)
end
if type(level2) == 'string' then
level2 = commas._strip(level2)
level2 = tonumber(level2)
end
if not level1 or not level2 then
return "You must pass numbers as arguments"
end
local difference = XPAtLevel[level1]- XPAtLevel[level2]
difference = math.abs(difference)
return difference
end
function p.level_to_level(frame)
return p._level_to_level(tonumber(frame.args[1]), tonumber(frame.args[2]), frame.args.elite)
end
-- Same as above, but with the 120/150 level cap removed
function p._level_to_level_unr(level1, level2, isElite)
local XPAtLevelUnr = NormalXPAtLevelUnr
if yn(isElite) then
XPAtLevelUnr = EliteXPAtLevelUnr
end
-- just in case
if type(level1) == 'string' then
level1 = commas._strip(level1)
level1 = tonumber(level1)
end
if type(level2) == 'string' then
level2 = commas._strip(level2)
level2 = tonumber(level2)
end
if not level1 or not level2 then
return "You must pass numbers as arguments"
end
local difference = XPAtLevelUnr[level1]- XPAtLevelUnr[level2]
difference = math.abs(difference)
return difference
end
function p.level_to_level_unr(frame)
return p._level_to_level_unr(tonumber(frame.args[1]), tonumber(frame.args[2]), frame.args.elite)
end
--[=[ remainingExp
-- Finds and returns experiences and levels based on inputs
-- Inputs:
-- curLvl The current level or 1
-- curXP The current xp or 1
-- tgtLvl The target level or 0
-- tgtXP The target xp or 0
-- Returns:
-- current level,
-- current experience,
-- goal level,
-- goal experience,
-- experience remaining
--]=]
function p.remainingExp(curLvl, curXP, tgtLvl, tgtXP, isElite)
local remaining
local elite = 0
if isElite then
elite = 1
end
if curLvl > 120 and curXP == 1 then
curXP = curLvl
elseif curXP <= 120 and curLvl == 1 then
curLvl = curXP
curXP = 1
end
if tgtLvl > 120 and tgtXP == 0 then
tgtXP = tgtLvl
elseif tgtXP <= 120 and tgtLvl == 0 then
tgtLvl = tgtXP
tgtXP = 0
end
if curXP == 1 then
curXP = p.xp_at_level({args = {curLvl, elite = elite}})
else
curLvl = p.level_at_xp({args = {curXP, elite = elite}})
end
if tgtLvl > 0 or tgtXP > 0 then
if tgtXP == 0 then
tgtXP = p.xp_at_level({args = {tgtLvl, elite = elite}})
else
tgtLvl = p.level_at_xp({args = {tgtXP, elite = elite}})
end
end
-- Prevent negative values
local remaining = math.ceil(tgtXP - curXP)
if remaining < 0 then
remaining = 0
end
return curLvl, curXP, tgtLvl, tgtXP, remaining
end
return p
-- </nowiki>