Difference between revisions of "Module:Apt"
(Add a function to calculate average aptitude of a given skill.) |
m (Fix) |
||
(38 intermediate revisions by 6 users not shown) | |||
Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
+ | |||
+ | local data = mw.loadData('Module:Table of species') | ||
+ | |||
+ | local function name_arg(frame) | ||
+ | local name = frame.args[1] | ||
+ | if not name or name == "" then | ||
+ | name = mw.title.getCurrentTitle().text | ||
+ | end | ||
+ | return name | ||
+ | end | ||
+ | |||
+ | local function is_colored_draconian(species) | ||
+ | return species:match(" Draconian$") | ||
+ | end | ||
+ | |||
+ | local function is_obsolete(species) | ||
+ | return data[species].Obsolete or false | ||
+ | end | ||
+ | |||
+ | local function is_obsolete_sk(skill) | ||
+ | return skill == "Charms" or skill == "Slings" or skill == "Bows" or skill == "Crossbows" or skill == "Stabbing" or skill == "Traps" | ||
+ | end | ||
+ | |||
+ | local function is_spell_sk(skill) | ||
+ | return skill == "Spellcasting" or skill == "Conjurations" or skill == "Hexes" or skill == "Summonings" or skill == "Necromancy" or skill == "Translocations" or skill == "Fire Magic" or skill == "Ice Magic" or skill == "Air Magic" or skill == "Earth Magic" or skill == "Alchemy" | ||
+ | end | ||
+ | |||
+ | local function species_sorted(include_obsolete) | ||
+ | include_obsolete = include_obsolete or false | ||
+ | local species = {} | ||
+ | for sp in pairs(data) do | ||
+ | if not is_colored_draconian(sp) and (include_obsolete or not is_obsolete(sp)) then | ||
+ | table.insert(species, sp) | ||
+ | end | ||
+ | end | ||
+ | table.sort(species) | ||
+ | return species | ||
+ | end | ||
+ | |||
+ | local function skill_average(skill) | ||
+ | local count = 0 | ||
+ | local sum = 0 | ||
+ | for name, sp in pairs(data) do | ||
+ | if sp.Aptitudes[skill] and not is_colored_draconian(name) and name ~= "Gnoll" and (is_obsolete_sk(skill) or not is_obsolete(name)) and (name ~= "Djinni" or not is_spell_sk(skill)) then | ||
+ | count = count + 1 | ||
+ | sum = sum + sp.Aptitudes[skill] | ||
+ | end | ||
+ | end | ||
+ | return string.format("%.3f", sum / count) | ||
+ | end | ||
function p.aptitude(frame) | function p.aptitude(frame) | ||
− | |||
local sp = frame.args[1] | local sp = frame.args[1] | ||
local sk = frame.args[2] | local sk = frame.args[2] | ||
Line 8: | Line 57: | ||
return "" | return "" | ||
end | end | ||
− | return data[sp][sk] | + | if sp == "Average" then |
+ | return skill_average(sk) | ||
+ | else | ||
+ | return data[sp].Aptitudes[sk] or "N/A" | ||
+ | end | ||
end | end | ||
function p.skill_table(frame) | function p.skill_table(frame) | ||
− | local | + | local browser_width = frame.args[2] |
− | local skill = frame | + | browser_width = tonumber(browser_width) or 50 |
− | local species = { | + | local skill = name_arg(frame) |
− | + | local headers = {} | |
− | + | local species = species_sorted(is_obsolete_sk(skill)) | |
− | + | ||
− | + | local sp_headers_1 = {} | |
− | local result = [ | + | local sp_headers_2 = {} |
− | {| class="wikitable" border="1" | + | for i, sp in ipairs(species) do |
+ | local header = ("'''[[%s|%s]]'''"):format(sp, data[sp].Abbrev) | ||
+ | if i<browser_width then | ||
+ | table.insert(sp_headers_1, header) | ||
+ | else | ||
+ | table.insert(sp_headers_2, header) | ||
+ | end | ||
+ | end | ||
+ | |||
+ | local sk_headers_1 = {} | ||
+ | local sk_headers_2 = {} | ||
+ | for i, sp in ipairs(species) do | ||
+ | local header = ("%s"):format(data[sp].Aptitudes[skill] or "N/A") | ||
+ | if i<browser_width then | ||
+ | table.insert(sk_headers_1, header) | ||
+ | else | ||
+ | table.insert(sk_headers_2, header) | ||
+ | end | ||
+ | end | ||
+ | |||
+ | local result = [[{| class="wikitable" border="1" | ||
|- | |- | ||
− | | | + | |]] |
− | | | + | result = result .. table.concat(sp_headers_1, "\n|") |
− | | | + | result = result .. "\n|-\n| " |
− | | | + | result = result .. table.concat(sk_headers_1, "\n| ") |
− | + | if next(sp_headers_2) then | |
− | | | + | result = result .. "\n|-\n|" |
− | + | result = result .. table.concat(sp_headers_2, "\n|") | |
− | + | result = result .. "\n|-\n| " | |
− | + | result = result .. table.concat(sk_headers_2, "\n| ") | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | result = result .. "| " .. | ||
end | end | ||
− | result = result .. "|}" | + | result = result .. "\n|}" |
return result | return result | ||
end | end | ||
− | function p. | + | function p.skill_draconian_exceptions(frame) |
− | local | + | local skill = name_arg(frame) |
− | local | + | local normal = data['Draconian'].Aptitudes[skill] |
− | local | + | local result = '' |
− | + | for name, species in pairs(data) do | |
− | + | if is_colored_draconian(name) and (is_obsolete_sk(skill) or not is_obsolete(name)) and species.Aptitudes[skill] ~= normal then | |
− | + | local col = name:match("^%a*") | |
− | + | result = result .. '* [[Draconian#' .. col .. '|' .. col .. ' draconian]]s get ' .. species.Aptitudes[skill] .. '.\n' | |
− | + | end | |
− | for | ||
− | |||
end | end | ||
− | return | + | return result |
end | end | ||
− | function | + | local function aptitude_chart(skills, header) |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
local result = header | local result = header | ||
Line 86: | Line 130: | ||
local aa_ord = string.byte('A') | local aa_ord = string.byte('A') | ||
-- generates the table keys | -- generates the table keys | ||
− | function sort_key(i) | + | local function sort_key(i) |
local result | local result | ||
if i > z_ord - a_ord then | if i > z_ord - a_ord then | ||
Line 98: | Line 142: | ||
local i = 0 | local i = 0 | ||
− | for _, sp in ipairs( | + | for _, sp in ipairs(species_sorted()) do |
result = result .. '|<span style="display:none;">' .. sort_key(i) .. '</span>' .. sp .. "\n" | result = result .. '|<span style="display:none;">' .. sort_key(i) .. '</span>' .. sp .. "\n" | ||
− | for _,sk in ipairs(skills) do | + | for _, sk in ipairs(skills) do |
− | result = result .. "||" .. data[sp][sk] .. "\n" | + | result = result .. "||" .. (data[sp].Aptitudes[sk] or "N/A") .. "\n" |
end | end | ||
result = result .. "|-\n" | result = result .. "|-\n" | ||
Line 111: | Line 155: | ||
function p.aptitude_chart_general(frame) | function p.aptitude_chart_general(frame) | ||
− | local skills = {'Armour', 'Dodging', ' | + | local skills = {'Armour', 'Dodging', |
− | + | 'Shields', 'Stealth', 'Invocations', 'Evocations', 'Shapeshifting', 'Hit Points', 'Magic Points', 'Experience'} | |
local header = [=[ | local header = [=[ | ||
{| class="wikitable sortable" style="font-size:75%" border=1 | {| class="wikitable sortable" style="font-size:75%" border=1 | ||
Line 118: | Line 162: | ||
! scope="col" | [[Armour (skill)|Arm]] | ! scope="col" | [[Armour (skill)|Arm]] | ||
! scope="col" | [[Dodging|Ddg]] | ! scope="col" | [[Dodging|Ddg]] | ||
+ | ! scope="col" | [[Shields (skill)|Shd]] | ||
! scope="col" | [[Stealth|Sth]] | ! scope="col" | [[Stealth|Sth]] | ||
− | |||
! scope="col" | [[Invocations|Inv]] | ! scope="col" | [[Invocations|Inv]] | ||
! scope="col" | [[Evocations|Evo]] | ! scope="col" | [[Evocations|Evo]] | ||
+ | ! scope="col" | [[Shapeshifting|Shp]] | ||
! scope="col" | [[HP]] | ! scope="col" | [[HP]] | ||
! scope="col" | [[MP]] | ! scope="col" | [[MP]] | ||
Line 127: | Line 172: | ||
|- | |- | ||
]=] | ]=] | ||
− | return | + | return aptitude_chart(skills, header) |
end | end | ||
function p.aptitude_chart_combat(frame) | function p.aptitude_chart_combat(frame) | ||
− | local skills = {'Fighting | + | local skills = {'Fighting', 'Maces & Flails', |
− | 'Axes', 'Polearms', 'Staves', 'Unarmed Combat', 'Throwing', ' | + | 'Axes', 'Polearms', 'Staves', 'Unarmed Combat', 'Throwing', 'Short Blades', 'Long Blades', 'Ranged Weapons'} |
local header = [=[ | local header = [=[ | ||
{| class="wikitable sortable" style="font-size:75%" border=1 | {| class="wikitable sortable" style="font-size:75%" border=1 | ||
! scope="col" | [[Species]] | ! scope="col" | [[Species]] | ||
! scope="col" | [[Fighting|Fgt]] | ! scope="col" | [[Fighting|Fgt]] | ||
− | |||
− | |||
! scope="col" | [[Maces & Flails|M&F]] | ! scope="col" | [[Maces & Flails|M&F]] | ||
! scope="col" | [[Axes|Axs]] | ! scope="col" | [[Axes|Axs]] | ||
Line 145: | Line 188: | ||
! scope="col" | [[Unarmed Combat|UC]] | ! scope="col" | [[Unarmed Combat|UC]] | ||
! scope="col" | [[Throwing|Thr]] | ! scope="col" | [[Throwing|Thr]] | ||
− | ! scope="col" | [[ | + | ! scope="col" | [[Short Blades|SBl]] |
− | ! scope="col" | [[ | + | ! scope="col" | [[Long Blades|LBl]] |
− | ! scope="col" | [[ | + | ! scope="col" | [[Ranged Weapons|RW]] |
|- | |- | ||
]=] | ]=] | ||
− | return | + | return aptitude_chart(skills, header) |
end | end | ||
function p.aptitude_chart_magic(frame) | function p.aptitude_chart_magic(frame) | ||
− | local skills = {'Spellcasting', 'Conjurations', 'Hexes | + | local skills = {'Spellcasting', 'Conjurations', 'Hexes', |
− | 'Summonings', 'Necromancy', 'Translocations', ' | + | 'Summonings', 'Necromancy', 'Translocations', 'Alchemy', |
− | 'Fire Magic', 'Ice Magic', 'Air Magic', 'Earth | + | 'Fire Magic', 'Ice Magic', 'Air Magic', 'Earth Magic'} |
local header = [=[ | local header = [=[ | ||
{| class="wikitable sortable" style="font-size:75%" border=1 | {| class="wikitable sortable" style="font-size:75%" border=1 | ||
Line 163: | Line 206: | ||
! scope="col" | [[Conjurations|Coj]] | ! scope="col" | [[Conjurations|Coj]] | ||
! scope="col" | [[Hexes|Hex]] | ! scope="col" | [[Hexes|Hex]] | ||
− | |||
! scope="col" | [[Summonings|Sum]] | ! scope="col" | [[Summonings|Sum]] | ||
! scope="col" | [[Necromancy|Nec]] | ! scope="col" | [[Necromancy|Nec]] | ||
! scope="col" | [[Translocations|Trl]] | ! scope="col" | [[Translocations|Trl]] | ||
− | ! scope="col" | [[ | + | ! scope="col" | [[Alchemy|Alc]] |
! scope="col" | [[Fire Magic|Fir]] | ! scope="col" | [[Fire Magic|Fir]] | ||
! scope="col" | [[Ice Magic|Ice]] | ! scope="col" | [[Ice Magic|Ice]] | ||
! scope="col" | [[Air Magic|Air]] | ! scope="col" | [[Air Magic|Air]] | ||
! scope="col" | [[Earth Magic|Ear]] | ! scope="col" | [[Earth Magic|Ear]] | ||
− | |||
|- | |- | ||
]=] | ]=] | ||
− | return | + | return aptitude_chart(skills, header) |
end | end | ||
return p | return p |
Latest revision as of 14:55, 21 February 2024
Documentation for this module may be created at Module:Apt/doc
local p = {} local data = mw.loadData('Module:Table of species') local function name_arg(frame) local name = frame.args[1] if not name or name == "" then name = mw.title.getCurrentTitle().text end return name end local function is_colored_draconian(species) return species:match(" Draconian$") end local function is_obsolete(species) return data[species].Obsolete or false end local function is_obsolete_sk(skill) return skill == "Charms" or skill == "Slings" or skill == "Bows" or skill == "Crossbows" or skill == "Stabbing" or skill == "Traps" end local function is_spell_sk(skill) return skill == "Spellcasting" or skill == "Conjurations" or skill == "Hexes" or skill == "Summonings" or skill == "Necromancy" or skill == "Translocations" or skill == "Fire Magic" or skill == "Ice Magic" or skill == "Air Magic" or skill == "Earth Magic" or skill == "Alchemy" end local function species_sorted(include_obsolete) include_obsolete = include_obsolete or false local species = {} for sp in pairs(data) do if not is_colored_draconian(sp) and (include_obsolete or not is_obsolete(sp)) then table.insert(species, sp) end end table.sort(species) return species end local function skill_average(skill) local count = 0 local sum = 0 for name, sp in pairs(data) do if sp.Aptitudes[skill] and not is_colored_draconian(name) and name ~= "Gnoll" and (is_obsolete_sk(skill) or not is_obsolete(name)) and (name ~= "Djinni" or not is_spell_sk(skill)) then count = count + 1 sum = sum + sp.Aptitudes[skill] end end return string.format("%.3f", sum / count) end function p.aptitude(frame) local sp = frame.args[1] local sk = frame.args[2] if not sp or not sk then return "" end if sp == "Average" then return skill_average(sk) else return data[sp].Aptitudes[sk] or "N/A" end end function p.skill_table(frame) local browser_width = frame.args[2] browser_width = tonumber(browser_width) or 50 local skill = name_arg(frame) local headers = {} local species = species_sorted(is_obsolete_sk(skill)) local sp_headers_1 = {} local sp_headers_2 = {} for i, sp in ipairs(species) do local header = ("'''[[%s|%s]]'''"):format(sp, data[sp].Abbrev) if i<browser_width then table.insert(sp_headers_1, header) else table.insert(sp_headers_2, header) end end local sk_headers_1 = {} local sk_headers_2 = {} for i, sp in ipairs(species) do local header = ("%s"):format(data[sp].Aptitudes[skill] or "N/A") if i<browser_width then table.insert(sk_headers_1, header) else table.insert(sk_headers_2, header) end end local result = [[{| class="wikitable" border="1" |- |]] result = result .. table.concat(sp_headers_1, "\n|") result = result .. "\n|-\n| " result = result .. table.concat(sk_headers_1, "\n| ") if next(sp_headers_2) then result = result .. "\n|-\n|" result = result .. table.concat(sp_headers_2, "\n|") result = result .. "\n|-\n| " result = result .. table.concat(sk_headers_2, "\n| ") end result = result .. "\n|}" return result end function p.skill_draconian_exceptions(frame) local skill = name_arg(frame) local normal = data['Draconian'].Aptitudes[skill] local result = '' for name, species in pairs(data) do if is_colored_draconian(name) and (is_obsolete_sk(skill) or not is_obsolete(name)) and species.Aptitudes[skill] ~= normal then local col = name:match("^%a*") result = result .. '* [[Draconian#' .. col .. '|' .. col .. ' draconian]]s get ' .. species.Aptitudes[skill] .. '.\n' end end return result end local function aptitude_chart(skills, header) local result = header -- constants used by sort_key local a_ord = string.byte('a') local z_ord = string.byte('z') local aa_ord = string.byte('A') -- generates the table keys local function sort_key(i) local result if i > z_ord - a_ord then i = i - (z_ord - a_ord) - 1 result = '!' .. string.char(aa_ord + i) else result = '"' .. string.char(a_ord + i) end return result end local i = 0 for _, sp in ipairs(species_sorted()) do result = result .. '|<span style="display:none;">' .. sort_key(i) .. '</span>' .. sp .. "\n" for _, sk in ipairs(skills) do result = result .. "||" .. (data[sp].Aptitudes[sk] or "N/A") .. "\n" end result = result .. "|-\n" i = i + 1 end result = result .. "|}" return result end function p.aptitude_chart_general(frame) local skills = {'Armour', 'Dodging', 'Shields', 'Stealth', 'Invocations', 'Evocations', 'Shapeshifting', 'Hit Points', 'Magic Points', 'Experience'} local header = [=[ {| class="wikitable sortable" style="font-size:75%" border=1 ! scope="col" | [[Species]] ! scope="col" | [[Armour (skill)|Arm]] ! scope="col" | [[Dodging|Ddg]] ! scope="col" | [[Shields (skill)|Shd]] ! scope="col" | [[Stealth|Sth]] ! scope="col" | [[Invocations|Inv]] ! scope="col" | [[Evocations|Evo]] ! scope="col" | [[Shapeshifting|Shp]] ! scope="col" | [[HP]] ! scope="col" | [[MP]] ! scope="col" | [[Exp]] |- ]=] return aptitude_chart(skills, header) end function p.aptitude_chart_combat(frame) local skills = {'Fighting', 'Maces & Flails', 'Axes', 'Polearms', 'Staves', 'Unarmed Combat', 'Throwing', 'Short Blades', 'Long Blades', 'Ranged Weapons'} local header = [=[ {| class="wikitable sortable" style="font-size:75%" border=1 ! scope="col" | [[Species]] ! scope="col" | [[Fighting|Fgt]] ! scope="col" | [[Maces & Flails|M&F]] ! scope="col" | [[Axes|Axs]] ! scope="col" | [[Polearms|Pla]] ! scope="col" | [[Staves|Stv]] ! scope="col" | [[Unarmed Combat|UC]] ! scope="col" | [[Throwing|Thr]] ! scope="col" | [[Short Blades|SBl]] ! scope="col" | [[Long Blades|LBl]] ! scope="col" | [[Ranged Weapons|RW]] |- ]=] return aptitude_chart(skills, header) end function p.aptitude_chart_magic(frame) local skills = {'Spellcasting', 'Conjurations', 'Hexes', 'Summonings', 'Necromancy', 'Translocations', 'Alchemy', 'Fire Magic', 'Ice Magic', 'Air Magic', 'Earth Magic'} local header = [=[ {| class="wikitable sortable" style="font-size:75%" border=1 ! scope="col" | [[Species]] ! scope="col" | [[Spellcasting|Spc]] ! scope="col" | [[Conjurations|Coj]] ! scope="col" | [[Hexes|Hex]] ! scope="col" | [[Summonings|Sum]] ! scope="col" | [[Necromancy|Nec]] ! scope="col" | [[Translocations|Trl]] ! scope="col" | [[Alchemy|Alc]] ! scope="col" | [[Fire Magic|Fir]] ! scope="col" | [[Ice Magic|Ice]] ! scope="col" | [[Air Magic|Air]] ! scope="col" | [[Earth Magic|Ear]] |- ]=] return aptitude_chart(skills, header) end return p