Module:Sandbox/User:Californ1a/T/Professions: Difference between revisions
Jump to navigation
Jump to search
Content added Content deleted
Californ1a (talk | contribs) (Created page with "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 = { hopeport = {"guard", "chef", "fisher", "forager", "alchemist"}, hopeforest = {"scout", "gatherer", "woodcutter", "carpenter"}, mine = {"minefighter", "bonewright", "miner", "black...") |
Californ1a (talk | contribs) mNo edit summary |
||
(3 intermediate revisions by the same user not shown) | |||
Line 11: | Line 11: | ||
-- List episodes with their professions |
-- List episodes with their professions |
||
local episodes = { |
local episodes = { |
||
{ |
|||
hopeport = {"guard", "chef", "fisher", "forager", "alchemist"}, |
|||
free = true, |
|||
hopeforest = {"scout", "gatherer", "woodcutter", "carpenter"}, |
|||
name = 'Hopeport', |
|||
mine = {"minefighter", "bonewright", "miner", "blacksmith", "stonemason"}, |
|||
color = '#b99f46', |
|||
crenopolis = {"watchperson", "detective", "leatherworker", "merchant"} |
|||
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 |
|||
local ep_dict = { |
|||
function p.filter_by_episode(professions, episodeOrder) |
|||
hopeport = 'Hopeport', |
|||
hopeforest = 'Hopeforest', |
|||
mine = 'Mine of Mantuban', |
|||
crenopolis = 'Crenopolis' |
|||
} |
|||
local ep_color = { |
|||
hopeport = '#b99f46', |
|||
hopeforest = '#84b876', |
|||
mine = '#68ABF1', |
|||
crenopolis = '#979797' |
|||
} |
|||
-- Get professions levels given an episode name |
|||
function p.filter_by_episode(professions, episodeName, goals) |
|||
goals = goals or false |
|||
local filtered = {} |
local filtered = {} |
||
local episodeProfessions = episodes[ |
local episodeProfessions = episodes[episodeOrder].professions |
||
if not episodeProfessions then |
|||
error('Invalid episode name: ' .. tostring(episodeName)) |
|||
end |
|||
-- Add the professions and the total for the episode |
-- Add the professions and the total for the episode |
||
for _, profession in ipairs(episodeProfessions) do |
for _, profession in ipairs(episodeProfessions) do |
||
if professions[profession] ~= nil then |
|||
local val = profession |
|||
filtered[profession] = professions[profession] |
|||
if goals then |
|||
val = profession..' goal' |
|||
end |
|||
if professions[val] ~= nil then |
|||
filtered[val] = professions[val] |
|||
end |
end |
||
end |
end |
||
-- Add the total for the episode |
-- Add the total for the episode |
||
local ep_name = episodes[episodeOrder].name:lower() |
|||
if professions[episodeName] ~= nil then |
|||
if professions[ep_name] ~= nil then |
|||
filtered[episodeName] = professions[episodeName] |
|||
filtered[ep_name] = professions[ep_name] |
|||
end |
end |
||
Line 73: | Line 76: | ||
-- Build the professions + goals lists |
-- Build the professions + goals lists |
||
for |
for i, episode in ipairs(episodes) do |
||
local ep_name = episode.name:lower() |
|||
professions[episode] = 0 |
|||
professions[ep_name] = 0 |
|||
for _, key in ipairs(keys) do |
|||
for _, profession in ipairs(episode.professions) do |
|||
-- Add the profession and goal to their respective lists |
-- Add the profession and goal to their respective lists |
||
professions[ |
professions[profession] = pt.default_to(tonumber(args[profession]), 0) |
||
goals[ |
goals[profession] = pt.default_to(tonumber(args[profession..' goal']), 0) |
||
-- Add this profession's level to the episode's total |
-- Add this profession's level to the episode's total |
||
local value = professions[ |
local value = professions[profession] or 0 |
||
professions[ |
professions[ep_name] = professions[ep_name] + value |
||
end |
end |
||
-- Add this episode's total to the overall total |
-- Add this episode's total to the overall total |
||
professions.total = professions.total + professions[ |
professions.total = professions.total + professions[ep_name] |
||
end |
end |
||
Line 92: | Line 96: | ||
vertical = yn(pt.default_to(args.vertical, true), true), |
vertical = yn(pt.default_to(args.vertical, true), true), |
||
free = yn(pt.default_to(args.free, false), false), |
free = yn(pt.default_to(args.free, false), false), |
||
date = pt.default_to(args.date, '') |
date = pt.default_to(args.date, ''), |
||
right = yn(pt.default_to(args.right, false), false), |
|||
infobox = yn(pt.default_to(args.infobox, false), false), |
|||
} |
} |
||
Line 100: | Line 106: | ||
end |
end |
||
function p.create_row(tbl, |
function p.create_row(tbl, episodeOrder, professions, goals, vertical) |
||
if vertical then |
if vertical then |
||
tbl:tag('tr') |
tbl:tag('tr') |
||
Line 107: | Line 113: | ||
-- Create icons |
-- Create icons |
||
local cache = {} |
local cache = {} |
||
for _,profession in ipairs(episodes[ |
for _,profession in ipairs(episodes[episodeOrder].professions) do |
||
local PRO = pt.ucflc(profession) |
local PRO = pt.ucflc(profession) |
||
local size = icon_size |
local size = icon_size |
||
Line 132: | Line 138: | ||
-- Create levels |
-- Create levels |
||
for _,profession in ipairs(episodes[ |
for _, profession in ipairs(episodes[episodeOrder].professions) do |
||
local PRO = cache[profession].name |
local PRO = cache[profession].name |
||
local lvl = tostring(professions[profession]) |
local lvl = tostring(professions[profession]) |
||
Line 154: | Line 160: | ||
end |
end |
||
function p.create_episode_table( |
function p.create_episode_table(episodeOrder, professions, goals, other) |
||
local |
local ep_professions = episodes[episodeOrder].professions |
||
local |
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') |
local out = mw.html.create('tr'):tag('td'):tag('table') |
||
:addClass('wikitable') |
|||
:addClass('center') |
:addClass('center') |
||
:IF(other.infobox) |
|||
:css({margin='0', padding='0'}) |
|||
: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('tr') |
||
:tag('th') |
:tag('th') |
||
:IF(other.infobox) |
|||
:css({['background-color']=ep_color[episode]}) |
|||
:addClass('infobox-header') |
|||
:css({padding='0.5em'}) |
|||
:ELSE() |
|||
:css({ |
|||
['background-color'] = episodes[episodeOrder].color, |
|||
padding='0 0.5em', |
|||
}) |
|||
:END() |
|||
:attr({colspan = profession_count}) |
: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[ |
: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() |
||
:done() |
:done() |
||
out = p.create_row(out, |
out = p.create_row(out, episodeOrder, professions, goals, other.vertical) |
||
return out:done():done():done() -- /table /td /tr |
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 |
end |
||
function p.create_table(professions, goals, other) |
function p.create_table(professions, goals, other) |
||
local ep_tbl = {} |
local ep_tbl = {} |
||
local released_episodes = getReleasedEpisodes() |
|||
for episode in pairs(episodes) do |
|||
for i in ipairs(released_episodes) do |
|||
local ep_lvls = p.filter_by_episode(professions, episode) |
|||
local |
local ep_lvls = p.filter_by_episode(professions, i) |
||
local ep_goals = p.filter_by_episode(goals, i) |
|||
ep_tbl[episode] = p.create_episode_table(episode, ep_lvls, ep_goals, other) |
|||
table.insert(ep_tbl, p.create_episode_table(i, ep_lvls, ep_goals, other)) |
|||
end |
end |
||
Line 188: | Line 226: | ||
:done() |
:done() |
||
-- Inner episode tables |
|||
:node(ep_tbl.hopeport) |
|||
:node(ep_tbl.hopeforest) |
|||
:IF(not other.free) |
|||
:node(ep_tbl.mine) |
|||
:node(ep_tbl.crenopolis) |
|||
:END() |
|||
for i, tbl in ipairs(ep_tbl) do |
|||
:IF(pt.has_content(other.date)) |
|||
if (not other.free and episodes[i].free ~= true) |
|||
:tag('tr') |
|||
or episodes[i].free == true then |
|||
:tag('td') |
|||
out:node(tbl) |
|||
:css({['text-align']='center'}) |
|||
end |
|||
:tag('small') |
|||
end |
|||
:tag('b') |
|||
:wikitext('Last Updated:') |
|||
if pt.has_content(other.date) then |
|||
:done() |
|||
out:tag('tr') |
|||
:tag('td') |
|||
:css({['text-align']='center'}) |
|||
:wikitext(lang:formatDate('j F Y h:i:s', mw.getCurrentFrame():preprocess('{{REVISIONTIMESTAMP}}'))) |
|||
:tag('small') |
|||
:tag('b') |
|||
: |
:wikitext('Last Updated:') |
||
:done() |
: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() |
: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 |
end |
||
Latest revision as of 03:05, 6 January 2025
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