Module:Experience

From Brighter Shores Wiki
Jump to navigation Jump to search
Module documentation
This documentation is transcluded from Module:Experience/doc. [edit] [history] [purge]
Module:Experience's function between is invoked by Template:XP/Between.
Module:Experience's function level_at is invoked by Template:XP/Level for.
Module:Experience's function to_next is invoked by Template:XP/To next.
Module:Experience's function total_xp is invoked by Template:XP/Total.
Module:Experience requires strict.
Module:Experience loads data from Module:Experience/data.
Module:Experience is required by Module:Skill calc.

This module is a helper module to be used by other modules; it may not designed to be invoked directly. See Brighter Shores:Lua/Helper modules for a full list and more information. For a full list of modules using this helper click here

FunctionTypeUse
_total_xp(level)numberReturns the total experience needed to reach a level (from 0).
_between(level_low, level_high)number, numberGiven a level_low and a level_high, return how much experience is needed, starting at level_low, to reach level_high. This is assuming you start at exactly level_low and end as soon as you reach level_high, with no extra experience.
_to_next(level)numberGiven a level, return the experience needed to get to the next level. Returns nil for level 500
_level_at(xp)numberReturns the level you would be at if you had xp experience. When the result is < 500, _total_xp(result) <= xp and xp < _total_xp(result+1)

require('strict')
local data = mw.loadData('Module:Experience/data')

local p = {}

function p.total_xp(frame)
	local args = frame:getParent().args
	return p._total_xp(args[1])
end

--[[
Returns the total experience needed to reach a level (from 0)
]]
function p._total_xp(level)
	level = tonumber(level) or 0
	local floor = math.floor(level)
	local frac = level - floor
	if frac ~= 0 then
		-- Linearly interpolate things like "level 100.5" as "halfway between level 100 and 101"
		local this_level = data.level[floor]
		local next_level = data.level[floor + 1]
		return this_level and next_level and this_level + (next_level - this_level) * frac
	end
	return data.level[tonumber(level) or 0]
end

function p.between(frame)
	local args = frame:getParent().args
	return p._between(args[1], args[2])
end

--[[
Given a level_low and a level_high, return how much
experience is needed, starting at level_low, to reach level_high.

This is assuming you start at exactly level_low and end as soon as you
reach level_high, with no extra experience.
]]
function p._between(level_low, level_high)
	local xp_low = p._total_xp(level_low)
	local xp_high = p._total_xp(level_high)
	return xp_low and xp_high and xp_high - xp_low
end

function p.to_next(frame)
	local args = frame:getParent().args
	return p._to_next(args[1])
end

--[[
Given a level, return the experience needed to get to the next level
Returns nil for level 500
]]
function p._to_next(level)
	level = tonumber(level) or 0
	return p._between(level, level + 1)
end

function p.level_at(frame)
	local args = frame:getParent().args
	return p._level_at(args[1])
end

--[[
Returns the level you would be at if you had total xp of xp.
When the result is < 500, _total_xp(result) <= xp and xp < _total_xp(result+1)
]]
function p._level_at(xp)
	if type(xp) == 'string' then
		xp = xp:gsub(',', '')  -- Remove commas
	end
	xp = tonumber(xp) or 0
	if xp >= data.level[500] then
		return 500
	end
	if xp < data.level[1] then
		return 0
	end
	local lvl = 0
	for i = 8, 0, -1 do
		local bin = 2^i
		if xp >= (data.level[lvl+bin] or math.huge) then
			lvl = lvl + bin
		end
	end
	return lvl
end

return p