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

From Brighter Shores Wiki
Jump to navigation Jump to search
Content added Content deleted
(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...")
 
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[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 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, 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 107: 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 132: 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 154: 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 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()
:tag('br'):done()
out:tag('tr')
:IF(other.date == 'now')
:tag('td')
:css({['text-align']='center'})
:wikitext(lang:formatDate('j F Y h:i:s', 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
return out:allDone()
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