Module:Apt: Difference between revisions
From Ashenzari's Archive
More actions
imported>CommanderC No edit summary |
imported>NormalPerson7 Fix typo |
||
| (59 intermediate revisions by 7 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" or skill == "Forgecraft" | |||
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 | 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 | 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| ") | |||
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 | |||
for _, sp in ipairs( | |||
result = result .. "|" .. data[sp][ | 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 | end | ||
result = result .. "|}" | result = result .. "|}" | ||
return 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', 'Forgecraft', '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" | [[Forgecraft|Frg]] | |||
! 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 | end | ||
return p | return p | ||
Latest revision as of 16:44, 3 May 2025
This module is used by various templates related to species aptitudes, such as Template:Skill aptitudes, Template:Species aptitudes which in turn are used on species and skill pages.
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" or skill == "Forgecraft"
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', 'Forgecraft', '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" | [[Forgecraft|Frg]]
! 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