Difference between revisions of "Module:Spellbook"

From CrawlWiki
Jump to: navigation, search
m (Fix pattern match in spell_sources.)
(Support new data format: https://github.com/plampila/crawl-wiki-modules)
Line 1: Line 1:
 
local p = {}
 
local p = {}
  
local function table_has_value(t, v)
+
local book_data = mw.loadData('Module:Table of spellbooks')
  if t ~= nil then
+
local spell_data = mw.loadData('Module:Table of spells')
    for _,x in pairs(t) do if x == v then return true end end
 
  end
 
  return false
 
end
 
  
 
local function table_keys_sorted(t)
 
local function table_keys_sorted(t)
Line 15: Line 11:
 
   table.sort(keys)
 
   table.sort(keys)
 
   return keys
 
   return keys
 +
end
 +
 +
local function spell_school_link(school)
 +
  local skill = nil
 +
  if school == 'Poison' or school == 'Air' or school == 'Fire' or
 +
    school == 'Ice' or school == 'Earth' then
 +
    skill = school .. ' Magic'
 +
  elseif school:sub(-1) ~= 'y' and school:sub(-1) ~= 's' then
 +
    -- "Necromancy" isn't pluralised as a skill,
 +
    -- and "Hexes" and "Charms" are already
 +
    -- pluralized as a magic school.  The others
 +
    -- are singular as a school, plural as a skill.
 +
    skill = school .. 's'
 +
  end
 +
 +
  if skill ~= nil then
 +
    return '[[' .. skill .. '|' .. school .. ']]'
 +
  else
 +
    return '[[' .. school .. ']]'
 +
  end
 +
end
 +
 +
local function format_schools(schools, no_link_for)
 +
  local ret = ''
 +
  for school in pairs(schools) do
 +
    if school == no_link_for then
 +
      ret = ret .. school .. '/'
 +
    else
 +
      ret = ret .. spell_school_link(school) .. '/'
 +
    end
 +
  end
 +
  return ret:sub(1, -2)
 
end
 
end
  
 
function p.spellbook_table(frame)
 
function p.spellbook_table(frame)
  local data = mw.loadData('Module:Table of spellbooks')
 
 
   local book = frame.args[1]
 
   local book = frame.args[1]
 
   if not book then
 
   if not book then
     return ""
+
     return ''
 
   end
 
   end
 
   local result = [==[{| cellpadding="5" border="1"
 
   local result = [==[{| cellpadding="5" border="1"
Line 27: Line 54:
 
! Tile || Spell || Type || Level
 
! Tile || Spell || Type || Level
 
]==]
 
]==]
   for _,sp in ipairs(data[book]) do
+
  local letters = 'abcdefghijklmnopqrstuvwxyz'
     result = result .. "|-\n| " .. sp.image .. " || " ..
+
   for i,name in pairs(book_data[book].spells) do
       sp.letter .. " - [[" .. sp.name .. "]] || " .. sp.schools ..  
+
     result = result .. '|-\n| [[File:' .. name:lower() .. '.png]] || ' ..
      " || " .. sp.level .. "\n"
+
       letters:sub(i, i) .. ' - [[' .. name .. ']] || ' ..
 +
      format_schools(spell_data[name].schools) .. ' || ' ..
 +
      spell_data[name].level .. '\n'
 
   end
 
   end
   result = result .. "|}\n"
+
   result = result .. '|}\n'
 
   return result
 
   return result
 
end
 
end
  
 
function p.short_spell_list(frame)
 
function p.short_spell_list(frame)
  local data = mw.loadData('Module:Table of spellbooks')
 
 
   local book = frame.args[1]
 
   local book = frame.args[1]
 
   if not book then
 
   if not book then
     return ""
+
     return ''
 
   end
 
   end
 
   local school = frame.args[2]
 
   local school = frame.args[2]
   if school == "" then school = nil end
+
   if school == '' then school = nil end
  local spell_data = nil
 
  if school ~= nil then
 
    spell_data = mw.loadData('Module:Table of spells')
 
  end
 
 
   local result = "'''[[" .. book .. "]]''': "
 
   local result = "'''[[" .. book .. "]]''': "
 
   local spell_list = {}
 
   local spell_list = {}
   for _,sp in ipairs(data[book]) do
+
   for _,name in pairs(book_data[book].spells) do
     if school == nil or table_has_value(spell_data[sp.name]["schools"], school) then
+
     if school == nil or spell_data[name]['schools'][school] then
       table.insert(spell_list, "[[".. sp.name .. "]]")
+
       table.insert(spell_list, '[['.. name .. ']]')
 
     end
 
     end
 
   end
 
   end
   result = result .. table.concat(spell_list, ", ")
+
   result = result .. table.concat(spell_list, ', ')
 
   return result
 
   return result
 
end
 
end
  
 
function p.spell_sources(frame)
 
function p.spell_sources(frame)
  local spell_data = mw.loadData('Module:Table of spells')
 
 
 
   local school = frame.args[1]
 
   local school = frame.args[1]
 
   local primary_books = frame.args[2]
 
   local primary_books = frame.args[2]
  
 
   local done = {}
 
   local done = {}
   local ret = ""
+
   local ret = ''
   if primary_books ~= nil and primary_books ~= "" then
+
   if primary_books ~= nil and primary_books ~= '' then
     ret = ret .. ";Main Texts\n"
+
     ret = ret .. ';Main Texts\n'
     for book in string.gmatch(primary_books, "[^,]+") do
+
     for book in string.gmatch(primary_books, '[^,]+') do
       ret = ret .. ":" .. frame:expandTemplate{title = "spellbook2", args = {book, school}} .. "\n"
+
       ret = ret .. ':' .. frame:expandTemplate{title = 'spellbook2', args = {book, school}} .. '\n'
 
       done[book] = true
 
       done[book] = true
 
     end
 
     end
Line 77: Line 99:
 
   local found = {}
 
   local found = {}
 
   for _,spell in pairs(spell_data) do
 
   for _,spell in pairs(spell_data) do
     if table_has_value(spell['schools'], school) then
+
     if spell['schools'][school] then
       for _,book in pairs(spell['books']) do
+
       for book in pairs(spell['books']) do
 
         if not done[book] and not found[book] then
 
         if not done[book] and not found[book] then
 
           found[book] = true
 
           found[book] = true
Line 87: Line 109:
  
 
   if next(found) ~= nil then
 
   if next(found) ~= nil then
     ret = ret .. ";Other Texts\n"
+
     ret = ret .. ';Other Texts\n'
 
     -- TODO: ignore "the" while sorting
 
     -- TODO: ignore "the" while sorting
 
     for _,book in ipairs(table_keys_sorted(found)) do
 
     for _,book in ipairs(table_keys_sorted(found)) do
       ret = ret .. ":" .. frame:expandTemplate{title = "spellbook2", args = {book, school}} .. "\n"
+
       ret = ret .. ':' .. frame:expandTemplate{title = 'spellbook2', args = {book, school}} .. '\n'
 
     end
 
     end
 
   end
 
   end

Revision as of 12:23, 3 November 2016

This module generates the spellbook tables in the pages of the category Category:Book, and the lists of spells in the Book page.

Required by: Template:Spellbook and Template:Spellbook2.

Requires: Module:Table of spellbooks and Module:Table of spells


local p = {}

local book_data = mw.loadData('Module:Table of spellbooks')
local spell_data = mw.loadData('Module:Table of spells')

local function table_keys_sorted(t)
  local keys = {}
  for k in pairs(t) do
    table.insert(keys, k)
  end
  table.sort(keys)
  return keys
end

local function spell_school_link(school)
  local skill = nil
  if school == 'Poison' or school == 'Air' or school == 'Fire' or
     school == 'Ice' or school == 'Earth' then
    skill = school .. ' Magic'
  elseif school:sub(-1) ~= 'y' and school:sub(-1) ~= 's' then
    -- "Necromancy" isn't pluralised as a skill,
    -- and "Hexes" and "Charms" are already
    -- pluralized as a magic school.  The others
    -- are singular as a school, plural as a skill.
    skill = school .. 's'
  end

  if skill ~= nil then
    return '[[' .. skill .. '|' .. school .. ']]'
  else
    return '[[' .. school .. ']]'
  end
end

local function format_schools(schools, no_link_for)
  local ret = ''
  for school in pairs(schools) do
    if school == no_link_for then
      ret = ret .. school .. '/'
    else
      ret = ret .. spell_school_link(school) .. '/'
    end
  end
  return ret:sub(1, -2)
end

function p.spellbook_table(frame)
  local book = frame.args[1]
  if not book then
    return ''
  end
  local result = [==[{| cellpadding="5" border="1"
|- align="center"
! Tile || Spell || Type || Level
]==]
  local letters = 'abcdefghijklmnopqrstuvwxyz'
  for i,name in pairs(book_data[book].spells) do
    result = result .. '|-\n| [[File:' .. name:lower() .. '.png]] || ' ..
       letters:sub(i, i) .. ' - [[' .. name .. ']] || ' ..
       format_schools(spell_data[name].schools) .. ' || ' ..
       spell_data[name].level .. '\n'
  end
  result = result .. '|}\n'
  return result
end

function p.short_spell_list(frame)
  local book = frame.args[1]
  if not book then
    return ''
  end
  local school = frame.args[2]
  if school == '' then school = nil end
  local result = "'''[[" .. book .. "]]''': "
  local spell_list = {}
  for _,name in pairs(book_data[book].spells) do
    if school == nil or spell_data[name]['schools'][school] then
      table.insert(spell_list, '[['.. name .. ']]')
    end
  end
  result = result .. table.concat(spell_list, ', ')
  return result
end

function p.spell_sources(frame)
  local school = frame.args[1]
  local primary_books = frame.args[2]

  local done = {}
  local ret = ''
  if primary_books ~= nil and primary_books ~= '' then
    ret = ret .. ';Main Texts\n'
    for book in string.gmatch(primary_books, '[^,]+') do
      ret = ret .. ':' .. frame:expandTemplate{title = 'spellbook2', args = {book, school}} .. '\n'
      done[book] = true
    end
  end

  local found = {}
  for _,spell in pairs(spell_data) do
    if spell['schools'][school] then
      for book in pairs(spell['books']) do
        if not done[book] and not found[book] then
          found[book] = true
        end
      end
    end
  end

  if next(found) ~= nil then
    ret = ret .. ';Other Texts\n'
    -- TODO: ignore "the" while sorting
    for _,book in ipairs(table_keys_sorted(found)) do
      ret = ret .. ':' .. frame:expandTemplate{title = 'spellbook2', args = {book, school}} .. '\n'
    end
  end

  return ret:sub(1, -2)
end

return p