Module:Sandbox/User:Californ1a/T/Professions: Difference between revisions

From Brighter Shores Wiki
Jump to navigation Jump to search
Content added Content deleted
mNo edit summary
mNo edit summary
 
(One intermediate revision 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[episodeName]
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 episode, keys in pairs(episodes) do
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[key] = pt.default_to(tonumber(args[key]), 0)
professions[profession] = pt.default_to(tonumber(args[profession]), 0)
goals[key] = pt.default_to(tonumber(args[key..' goal']), 0)
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[key] or 0
local value = professions[profession] or 0
professions[episode] = professions[episode] + value
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[episode]
professions.total = professions.total + professions[ep_name]
end
end
Line 93: Line 97:
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)
right = yn(pt.default_to(args.right, false), false),
infobox = yn(pt.default_to(args.infobox, false), false),
}
}
Line 101: Line 106:
end
end


function p.create_row(tbl, episode, professions, goals, vertical)
function p.create_row(tbl, episodeOrder, professions, goals, vertical)
if vertical then
if vertical then
tbl:tag('tr')
tbl:tag('tr')
Line 108: Line 113:
-- Create icons
-- Create icons
local cache = {}
local cache = {}
for _,profession in ipairs(episodes[episode]) do
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 133: Line 138:
-- Create levels
-- Create levels
for _,profession in ipairs(episodes[episode]) do
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 155: Line 160:
end
end


function p.create_episode_table(episode, professions, goals, other)
function p.create_episode_table(episodeOrder, professions, goals, other)
local profession_count = #episodes[episode]
local ep_professions = episodes[episodeOrder].professions
local EP = ep_dict[episode]
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[episode]))
: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, episode, professions, goals, other.vertical)
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 ep_goals = p.filter_by_episode(goals, episode)
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 189: 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()
:tag('br'):done()
out:tag('tr')
:IF(other.date == 'now')
:tag('td')
:css({['text-align']='center'})
:wikitext(lang:formatDate('j F Y', mw.getCurrentFrame():preprocess('{{REVISIONTIMESTAMP}}')))
:ELSE()
:tag('small')
:wikitext(other.date)
:tag('b')
:END()
: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()
:END()
:done()
end
out:allDone()
out:allDone()

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