Module:Lamp

From the RuneScape Wiki, the wiki for all things RuneScape
Jump to navigation Jump to search
Module documentation
This documentation is transcluded from Module:Lamp/doc. [edit] [history] [purge]
Module:Lamp's function lamps_to_level is invoked by Calculator:Template/Other/XP Lamp.
Module:Lamp's function level_to_xp is invoked by Template:LampLevelXP.
Module:Lamp's function main is invoked by Template:LampXP.
Module:Lamp requires Module:Addcommas.
Module:Lamp requires Module:Arguments.
Module:Lamp requires Module:Experience.
Module:Lamp requires Module:Tables.
Module:Lamp requires strict.
Module:Lamp loads data from Module:Lamp/data.
Function list
L 14 — getMultiplier
L 40 — p._level_to_xp
L 54 — p._lamps_to_level
L 80 — p._xp_to_level
L 97 — p._main
L 127 — p.main
L 132 — p.xp_to_level
L 137 — p.lamps_to_level
L 142 — p.level_to_xp

This module provides methods to work with or display XP values gained from either lamp- or star-type reward items. Originally separate from Module:Star, this module now contains all of the logic and XP lookup table for both items. See the full documentation for more information.


require("strict");
local p = {}

local getArgs = require("Module:Arguments").getArgs;
local commas = require('Module:Addcommas')._add
local tables = require('Module:Tables')

local experiencemodule = require('Module:Experience')
local data = mw.loadData("Module:Lamp/data")

local lamp_xps = data.lamp_xps
p.lamp_xps = lamp_xps

local function getMultiplier(multiplier, is_star)
	local mult
	
	if tonumber(multiplier) then mult = multiplier end
	if not multiplier then mult = 1 end
	local synonym = data.multipliers[tostring(multiplier):upper()]
	if synonym then mult = synonym end
	
	-- otherwise
	if not mult then
		mw.log("Failed to determine multiplier; defaulting to 1")
		mult = 1
	end
	
	if is_star then
		mult = mult * 1.2
	end
	
	return mult
end

-- Returns the xp gained at a given level and multiplier
--	level: Level to query
--	multiplier: Size of the lamp/star as a case-insensitive string ("Small", "Medium", "Large", "Huge") or a raw numeric value
--
--	returns xp as an unformatted number
function p._level_to_xp(level, multiplier, is_star)
	multiplier = getMultiplier(multiplier, is_star)
	level = tonumber(level, 10)
	return math.floor((lamp_xps[level] * multiplier) * 10) / 10
end

-- Returns the number of lamps required to reach a certain experience, from a certain experience
--
-- startingXP: Experience level to start the calculation from
-- finishingXP: Experience level to end the calculation at
-- multiplier: Size of the lamp/star as a case-insensitive string ("Small", "Medium", "Large", "Huge") or a raw numeric value
-- elite: Specifies if the target skill is Elite (Invention) or not
--
-- returns number of lamps for the given inputs
function p._lamps_to_level(startingXP, finishingXP, multiplier, elite)
	multiplier = getMultiplier(multiplier, false)
	
	local currentXP, currentLevel, currentLampValue, totalLampsCounted
	
	currentXP = startingXP
	currentLevel = experiencemodule._level_at_xp(currentXP, elite)
	currentLampValue = lamp_xps[currentLevel] * multiplier
	totalLampsCounted = 0
	
	while tonumber(currentXP) < tonumber(finishingXP) do
		currentXP = currentXP + currentLampValue
		totalLampsCounted = totalLampsCounted + 1
		currentLevel = experiencemodule._level_at_xp(currentXP, elite)
		currentLampValue = lamp_xps[currentLevel] * multiplier
	end
	
	return totalLampsCounted
end

--  Returns the level required to gain the provided amount of xp
--	xp: Amount of xp to query
--	multiplier: Size of the lamp/star as a case-insensitive string ("Small", "Medium", "Large", "Huge") or a raw numeric value
--	(overflow): Whether to consider lamp/stars that would provide more than the requested xp (default: true)
--
--	returns level as an unformatted number
function p._xp_to_level(xp, multiplier, overflow, is_star)
	multiplier = getMultiplier(multiplier, is_star)
	if overflow == nil then overflow = true end
	local offset = 1
	if overflow then offset = 0 end
	
	local scan = xp / multiplier
	local level = 0
	
	repeat
		level = level + 1
	until level == 120 or scan < lamp_xps[level + offset] + 1 - offset
	
	return level
end

-- Print table
function p._main(args, is_star)
	local cols = tonumber(args.cols)
	local xptable = mw.html.create('table'):addClass('wikitable text-align-right')
	local maxLevel = tonumber(args.max) or 120
	local rows = math.ceil(maxLevel / cols)
	local data = {{{text = 'Skill level', tag = 'th'}, {text = 'Experience', tag = 'th'}}}
	for i=2,cols do
		data[1][3*i-3] = {text = '', tag = 'th', attr = {rowspan = rows + 1}}
		data[1][3*i-2] = {text = 'Skill level', tag = 'th'}
		data[1][3*i-1] = {text = 'Experience', tag = 'th'}
	end

	for i=1,rows do
		data[i+1] = {}
		for j=1,cols do
			local level = (j-1) * rows + i
			if level <= maxLevel then
				local xp = p._level_to_xp(level, args.multiplier, is_star)
				data[i+1][j*3-2] = {text = level}
				data[i+1][j*3-1] = {text = string.format("%s%s", commas(xp), xp == math.floor(xp) and ".0" or "")}
				data[i+1][j*3] = false
			end
		end
	end
	tables._table(xptable, data)
	return tostring(xptable)
end

---- Outward-facing functions

function p.main(frame)
	local args = getArgs(frame);
	return p._main(args, false)
end

function p.xp_to_level(frame)
	local args = getArgs(frame);
	return p._xp_to_level(args.xp, args.multiplier, args.overflow, false)
end

function p.lamps_to_level(frame)
	local args = getArgs(frame);
	return p._lamps_to_level(args.startingXP, args.finishingXP, args.multiplier, args.elite)
end

function p.level_to_xp(frame)
	local args = getArgs(frame);
	return p._level_to_xp(args.level, args.multiplier, false)
end

return p