Module:Apt

From CrawlWiki
Jump to: navigation, search

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 &amp; Flails|M&amp;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