Module:Skill cap: Difference between revisions

From HorizonXI Wiki
(add cap_to_rank function to convert a level 75 skill cap number (276) to a letter-grade rank (A+))
(allow level 75 cap as a numeric alias for grade-letter rank)
Line 21: Line 21:


local p = {}
local p = {}
--[[
cap_to_rank
Get the letter-grade rank, given the level 75 skill cap as the first parameter.
Example:
{{#invoke:Skill cap|cap to rank|276}}
]]
local function lookup_rank(search_value)
    if not search_value then
    return "invalid rank"
    end
    for rank, skill_caps in pairs(skill_cap_table) do
        if skill_caps[75] == search_value then
            return rank
        end
    end
    return "invalid rank"
end
function p.cap_to_rank(frame)
    local search_value = tonumber(frame.args[1])
return lookup_rank(search_value)
end
p["cap to rank"] = p.cap_to_rank -- alias


--[[
--[[
Line 27: Line 58:
Get the skill cap, given the skill rank (A+ through F) as the first parameter,
Get the skill cap, given the skill rank (A+ through F) as the first parameter,
and the level as the second parameter.
and the level as the second parameter.
You may also use the level 75 skill cap as an alias for the letter-grade rank.
For example, 276 is an alias for A+.


Example:
Example:
{{#invoke:Skill cap|get cap|A+|75}}
{{#invoke:Skill cap|get cap|A+|37}}
{{#invoke:Skill cap|get cap|276|37}}
]]
]]


Line 35: Line 70:
     local skill_rank = frame.args[1]
     local skill_rank = frame.args[1]
     local level = tonumber(frame.args[2])
     local level = tonumber(frame.args[2])
    if tonumber(skill_rank) then -- numerical alias for letter-grade
    skill_rank = lookup_rank(tonumber(skill_rank))
    end


if not skill_rank or not skill_cap_table[skill_rank] then
if not skill_rank or not skill_cap_table[skill_rank] then
Line 54: Line 93:
Get the minimum level required, given the skill rank (A+ through F) as the first
Get the minimum level required, given the skill rank (A+ through F) as the first
parameter, and the desired skill level as the second parameter.
parameter, and the desired skill level as the second parameter.
You may also use the level 75 skill cap as an alias for the letter-grade rank.
For example, 276 is an alias for A+.


Example:
Example:
{{#invoke:Skill cap|find minimum level|A+|250}}
{{#invoke:Skill cap|find minimum level|A+|250}}
{{#invoke:Skill cap|find minimum level|276|250}}
]]
]]


Line 62: Line 105:
     local skill_rank = frame.args[1]
     local skill_rank = frame.args[1]
     local skill_level = tonumber(frame.args[2])
     local skill_level = tonumber(frame.args[2])
    if tonumber(skill_rank) then -- numerical alias for letter-grade
    skill_rank = lookup_rank(tonumber(skill_rank))
    end


if not skill_rank or not skill_cap_table[skill_rank] then
if not skill_rank or not skill_cap_table[skill_rank] then
Line 92: Line 139:


p["find minimum level"] = p.find_minimum_level -- alias
p["find minimum level"] = p.find_minimum_level -- alias
--[[
cap_to_rank
Get the letter-grade rank, given the level 75 skill cap as the first parameter.
Example:
{{#invoke:Skill cap|cap to rank|276}}
]]
function p.cap_to_rank(frame)
    local search_value = tonumber(frame.args[1])
   
    if not search_value then
    return "invalid rank"
    end
    for rank, skill_caps in pairs(skill_cap_table) do
        if skill_caps[75] == search_value then
            return rank
        end
    end
    return "invalid rank"
end
p["cap to rank"] = p.cap_to_rank -- alias


return p
return p

Revision as of 02:03, 20 September 2025

Documentation for this module may be created at Module:Skill cap/doc

--[[

A module for functions relating to skill caps.

]]

local skill_cap_table = {
	-- Level  1  2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32   33   34   35   36   37   38   39   40   41   42   43   44   45   46   47   48   49   50   51   52   53   54   55   56   57   58   59   60   61   62   63   64   65   66   67   68   69   70   71   72   73   74   75
	["A+"] = {6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99, 102, 105, 108, 111, 114, 117, 120, 123, 126, 129, 132, 135, 138, 141, 144, 147, 150, 153, 158, 163, 168, 173, 178, 183, 188, 193, 198, 203, 207, 212, 217, 222, 227, 232, 236, 241, 246, 251, 256, 261, 266, 271, 276},
	["A-"] = {6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99, 102, 105, 108, 111, 114, 117, 120, 123, 126, 129, 132, 135, 138, 141, 144, 147, 150, 153, 158, 163, 168, 173, 178, 183, 188, 193, 198, 203, 207, 211, 215, 219, 223, 227, 231, 235, 239, 244, 249, 254, 259, 264, 269},
	["B+"] = {5, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 65, 68, 71, 74, 77, 80, 83, 86, 89, 92, 94,  97, 100, 103, 106, 109, 112, 115, 118, 121, 123, 126, 129, 132, 135, 138, 141, 144, 147, 151, 156, 161, 166, 171, 176, 181, 186, 191, 196, 199, 203, 207, 210, 214, 218, 221, 225, 229, 233, 237, 242, 246, 251, 256},
	["B" ] = {5, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 65, 68, 71, 74, 77, 80, 83, 86, 89, 92, 94,  97, 100, 103, 106, 109, 112, 115, 118, 121, 123, 126, 129, 132, 135, 138, 141, 144, 147, 151, 156, 161, 166, 171, 176, 181, 186, 191, 196, 199, 202, 205, 208, 212, 215, 218, 221, 225, 228, 232, 236, 241, 245, 250},
	["B-"] = {5, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 65, 68, 71, 74, 77, 80, 83, 86, 89, 92, 94,  97, 100, 103, 106, 109, 112, 115, 118, 121, 123, 126, 129, 132, 135, 138, 141, 144, 147, 151, 156, 161, 166, 171, 176, 181, 186, 191, 196, 198, 201, 204, 206, 209, 212, 214, 217, 220, 223, 226, 229, 233, 236, 240},
	["C+"] = {5, 7, 10, 13, 16, 19, 21, 24, 27, 30, 33, 35, 38, 41, 44, 47, 49, 52, 55, 58, 61, 63, 66, 69, 72, 75, 77, 80, 83, 86, 89, 91,  94,  97, 100, 103, 105, 108, 111, 114, 117, 119, 122, 125, 128, 130, 133, 136, 139, 142, 146, 151, 156, 161, 166, 170, 175, 180, 185, 190, 192, 195, 197, 200, 202, 205, 207, 210, 212, 215, 218, 221, 224, 227, 230},
	["C" ] = {5, 7, 10, 13, 16, 19, 21, 24, 27, 30, 33, 35, 38, 41, 44, 47, 49, 52, 55, 58, 61, 63, 66, 69, 72, 75, 77, 80, 83, 86, 89, 91,  94,  97, 100, 103, 105, 108, 111, 114, 117, 119, 122, 125, 128, 130, 133, 136, 139, 142, 146, 151, 156, 161, 166, 170, 175, 180, 185, 190, 192, 194, 196, 199, 201, 203, 205, 208, 210, 212, 214, 217, 219, 222, 225},
	["C-"] = {5, 7, 10, 13, 16, 19, 21, 24, 27, 30, 33, 35, 38, 41, 44, 47, 49, 52, 55, 58, 61, 63, 66, 69, 72, 75, 77, 80, 83, 86, 89, 91,  94,  97, 100, 103, 105, 108, 111, 114, 117, 119, 122, 125, 128, 130, 133, 136, 139, 142, 146, 151, 156, 161, 166, 170, 175, 180, 185, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220},
	["D" ] = {4, 6,  9, 12, 14, 17, 20, 22, 25, 28, 31, 33, 36, 39, 41, 44, 47, 49, 52, 55, 58, 60, 63, 66, 68, 71, 74, 76, 79, 82, 85, 87,  90,  93,  95,  98, 101, 103, 106, 109, 112, 114, 117, 120, 122, 125, 128, 130, 133, 136, 140, 145, 150, 154, 159, 164, 168, 173, 178, 183, 184, 186, 188, 190, 192, 194, 195, 197, 199, 201, 202, 204, 206, 208, 210},
	["E" ] = {4, 6,  9, 11, 14, 16, 19, 21, 24, 26, 29, 31, 34, 36, 39, 41, 44, 46, 49, 51, 54, 56, 59, 61, 64, 66, 69, 71, 74, 76, 79, 81,  84,  86,  89,  91,  94,  96,  99, 101, 104, 106, 109, 111, 114, 116, 119, 121, 124, 126, 130, 135, 139, 144, 148, 153, 157, 162, 166, 171, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200},
	["F" ] = {4, 6,  8, 10, 13, 15, 17, 20, 22, 24, 27, 29, 31, 33, 36, 38, 40, 43, 45, 47, 50, 52, 54, 56, 59, 61, 63, 66, 68, 70, 73, 75,  77,  79,  82,  84,  86,  89,  91,  93,  96,  98, 100, 102, 105, 107, 109, 112, 114, 116, 120, 124, 128, 133, 137, 141, 146, 150, 154, 159, 161, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, 183, 185, 187, 189}
}

local p = {}

--[[
cap_to_rank

Get the letter-grade rank, given the level 75 skill cap as the first parameter.

Example:
{{#invoke:Skill cap|cap to rank|276}}
]]

local function lookup_rank(search_value)
    if not search_value then
    	return "invalid rank"
    end

    for rank, skill_caps in pairs(skill_cap_table) do
        if skill_caps[75] == search_value then
            return rank
        end
    end

    return "invalid rank"
end

function p.cap_to_rank(frame)
    local search_value = tonumber(frame.args[1])

	return lookup_rank(search_value)
end

p["cap to rank"] = p.cap_to_rank -- alias

--[[
get_cap

Get the skill cap, given the skill rank (A+ through F) as the first parameter,
and the level as the second parameter.

You may also use the level 75 skill cap as an alias for the letter-grade rank.
For example, 276 is an alias for A+.

Example:
{{#invoke:Skill cap|get cap|A+|37}}
{{#invoke:Skill cap|get cap|276|37}}
]]

function p.get_cap(frame)
    local skill_rank = frame.args[1]
    local level = tonumber(frame.args[2])

    if tonumber(skill_rank) then -- numerical alias for letter-grade
    	skill_rank = lookup_rank(tonumber(skill_rank))
    end

	if not skill_rank or not skill_cap_table[skill_rank] then
	    return "invalid rank"
	end

	if not level or not skill_cap_table[skill_rank][level] then
	    return "invalid level"
	end

	return skill_cap_table[skill_rank][level]
end

p["get cap"] = p.get_cap -- alias

--[[
find_minimum_level

Get the minimum level required, given the skill rank (A+ through F) as the first
parameter, and the desired skill level as the second parameter.

You may also use the level 75 skill cap as an alias for the letter-grade rank.
For example, 276 is an alias for A+.

Example:
{{#invoke:Skill cap|find minimum level|A+|250}}
{{#invoke:Skill cap|find minimum level|276|250}}
]]

function p.find_minimum_level(frame)
    local skill_rank = frame.args[1]
    local skill_level = tonumber(frame.args[2])

    if tonumber(skill_rank) then -- numerical alias for letter-grade
    	skill_rank = lookup_rank(tonumber(skill_rank))
    end

	if not skill_rank or not skill_cap_table[skill_rank] then
	    return "invalid rank"
	end

	if not skill_level then
	    return "invalid level"
	end

    local arr = skill_cap_table[skill_rank]

    -- Do a binary search for the first number in the the skill cap table
    -- greater than or equal to skill_level
    local left, right = 1, 75
    local result = nil

    while left <= right do
        local mid = math.floor((left + right) / 2)
        if arr[mid] >= skill_level then
            result = mid  -- potential candidate
            right = mid - 1  -- search left side for earlier occurrence
        else
            left = mid + 1  -- search right side
        end
    end
    
    return result
end

p["find minimum level"] = p.find_minimum_level -- alias

return p