Module:Sandbox/User:Californ1a/T/Professions
Jump to navigation
Jump to search
Documentation for this module may be created at Module:Sandbox/User:Californ1a/T/Professions/doc
require('strict')
require('Module:Mw.html extension')
local pt = require('Module:Paramtest')
local yn = require('Module:Yesno')
local lang = mw.language.getContentLanguage()
local p = {}
local icon_size = 20
local ep_icon_size = 16
-- List episodes with their professions
local episodes = {
{
free = true,
name = 'Hopeport',
color = '#b99f46',
professions = {'guard', 'chef', 'fisher', 'forager', 'alchemist'},
}, {
free = true,
name = 'Hopeforest',
color = '#84b876',
professions = {'scout', 'gatherer', 'woodcutter', 'carpenter'},
}, {
name = 'Mine of Mantuban',
color = '#68ABF1',
professions = {'minefighter', 'bonewright', 'miner', 'blacksmith', 'stonemason'},
}, {
name = 'Crenopolis',
color = '#979797',
professions = {'watchperson', 'detective', 'leatherworker', 'merchant'},
}, {
released = false,
name = 'Stonemaw Hill',
color = '#C57F41',
professions = {'shieldbearer', 'builder', 'armorer', 'delver'},
}, {
released = false,
name = 'Bleakholm Crags',
color = '#68ABF1',
professions = {},
},
}
-- Get professions levels given an episode order number
function p.filter_by_episode(professions, episodeOrder)
local filtered = {}
local episodeProfessions = episodes[episodeOrder].professions
-- Add the professions and the total for the episode
for _, profession in ipairs(episodeProfessions) do
if professions[profession] ~= nil then
filtered[profession] = professions[profession]
end
end
-- Add the total for the episode
local ep_name = episodes[episodeOrder].name:lower()
if professions[ep_name] ~= nil then
filtered[ep_name] = professions[ep_name]
end
return filtered
end
-- Template entrypoint
function p.main(frame)
return p._main(frame:getParent().args)
end
function p._main(args)
-- Create main profession and goals lists
local professions = {
total = 0
}
local goals = {}
-- Build the professions + goals lists
for i, episode in ipairs(episodes) do
local ep_name = episode.name:lower()
professions[ep_name] = 0
for _, profession in ipairs(episode.professions) do
-- Add the profession and goal to their respective lists
professions[profession] = pt.default_to(tonumber(args[profession]), 0)
goals[profession] = pt.default_to(tonumber(args[profession..' goal']), 0)
-- Add this profession's level to the episode's total
local value = professions[profession] or 0
professions[ep_name] = professions[ep_name] + value
end
-- Add this episode's total to the overall total
professions.total = professions.total + professions[ep_name]
end
-- Non-profession config params
local other = {
vertical = yn(pt.default_to(args.vertical, true), true),
free = yn(pt.default_to(args.free, false), false),
date = pt.default_to(args.date, ''),
right = yn(pt.default_to(args.right, false), false),
infobox = yn(pt.default_to(args.infobox, false), false),
}
--local debug_str = '<pre>'..mw.text.jsonEncode(professions, mw.text.JSON_PRETTY)..', '..mw.text.jsonEncode(goals, mw.text.JSON_PRETTY)..'</pre>'
return tostring(p.create_table(professions, goals, other))--..debug_str
end
function p.create_row(tbl, episodeOrder, professions, goals, vertical)
if vertical then
tbl:tag('tr')
end
-- Create icons
local cache = {}
for _,profession in ipairs(episodes[episodeOrder].professions) do
local PRO = pt.ucflc(profession)
local size = icon_size
if profession == 'alchemist' then -- Alchemist icon is a bit larger than others
size = icon_size - 5
end
local icon = mw.ustring.format('[[File:%s small icon.png|link=%s|%spx]]', PRO, PRO, size)
cache[profession] = {
name = PRO,
icon = icon
}
if vertical then
tbl:tag('td')
:css({border='none'})
:wikitext(icon)
:done()
end
end
if vertical then
tbl:done() -- /tr
end
tbl:tag('tr')
-- Create levels
for _, profession in ipairs(episodes[episodeOrder].professions) do
local PRO = cache[profession].name
local lvl = tostring(professions[profession])
if goals[profession] ~= 0 then
lvl = lvl..'/'..tostring(goals[profession])
end
if vertical then
tbl:tag('td')
:css({border='none'})
:wikitext(lvl)
:done()
else
tbl:tag('td')
:wikitext(cache[profession].icon..' '..lvl)
:done()
end
end
return tbl:done()
end
function p.create_episode_table(episodeOrder, professions, goals, other)
local ep_professions = episodes[episodeOrder].professions
local profession_count = #ep_professions
local EP = episodes[episodeOrder].name
local ep_name = episodes[episodeOrder].name:lower()
local out = mw.html.create('tr'):tag('td'):tag('table')
:addClass('center')
:IF(other.infobox)
:addClass('infobox')
:addClass('infobox-'..EP:gsub(' ', '_'))
:css({
margin = '0',
['table-layout'] = 'auto',
width = '100%',
float = 'unset',
})
:ELSE()
:addClass('wikitable')
:css({margin='0', padding='0'})
:END()
:tag('tr')
:tag('th')
:IF(other.infobox)
:addClass('infobox-header')
:css({padding='0.5em'})
:ELSE()
:css({
['background-color'] = episodes[episodeOrder].color,
padding='0 0.5em',
})
:END()
:attr({colspan = profession_count})
:wikitext(mw.ustring.format('[[File:%s episode icon.png|link=%s|%spx]] [[%s]] (%s)', EP, EP, ep_icon_size, EP, professions[ep_name]))
:done()
:done()
out = p.create_row(out, episodeOrder, professions, goals, other.vertical)
return out:done():done():done() -- /table /td /tr
end
local function getReleasedEpisodes()
local filtered = {}
for i, episode in ipairs(episodes) do
if episode.released ~= false then
table.insert(filtered, episode)
end
end
return filtered
end
function p.create_table(professions, goals, other)
local ep_tbl = {}
local released_episodes = getReleasedEpisodes()
for i in ipairs(released_episodes) do
local ep_lvls = p.filter_by_episode(professions, i)
local ep_goals = p.filter_by_episode(goals, i)
table.insert(ep_tbl, p.create_episode_table(i, ep_lvls, ep_goals, other))
end
local out = mw.html.create('table')
:tag('caption')
:css({['font-weight']='bold'})
:wikitext(mw.ustring.format('[[File:Professions icon.png|link=Professions|%spx]] [[Professions]] (%s)', ep_icon_size, professions.total))
:done()
for i, tbl in ipairs(ep_tbl) do
if (not other.free and episodes[i].free ~= true)
or episodes[i].free == true then
out:node(tbl)
end
end
if pt.has_content(other.date) then
out:tag('tr')
:tag('td')
:css({['text-align']='center'})
:tag('small')
:tag('b')
:wikitext('Last Updated:')
:done()
:tag('br'):done()
:IF(other.date == 'now')
:wikitext(lang:formatDate('j F Y', mw.getCurrentFrame():preprocess('{{REVISIONTIMESTAMP}}')))
:ELSE()
:wikitext(other.date)
:END()
:done()
:done()
:done()
end
out:allDone()
local div = out
if other.right then
div = mw.html.create('div')
:css({float='right'})
:node(out)
:done()
end
return div
end
return p