Module:Infobox construction

From WIDEVERSE Wiki
Jump to navigation Jump to search

Documentation for this module may be created at Module:Infobox construction/doc

-- <nowiki>
--------------------------
-- Module for [[Template:Infobox Construction]]
-- Please test changes to this module at [[Module:Infobox construction/sandbox]] first
------------------------
local p = {}

-- "imports"
local onmain = require('Module:Mainonly').on_main
local yesno = require('Module:Yesno')
local paramtest = require('Module:Paramtest')
local editbutton = require('Module:Edit button')
local cleanimg = require('Module:Clean image').clean
local commas = require('Module:Addcommas')
local skillpic = require('Module:Skill_clickpic')._main
local infobox = require('Module:Infobox')

function p.main(frame)
	local args = frame:getParent().args
	local ret = infobox.new(args)
	
	ret:defineParams{
		{ name = 'name', func = 'name' },
		{ name = 'buildname', func = { name = buildnamearg, params = { 'buildname' }, flag = { 'd' } } },
		{ name = 'vanchor', func = { name = 'has_content', params = { 'version' }, flag = 'p' } },
		{ name = 'image', func = { name = imgarg, params = { 'image' }, flag = { 'd' } } },
		{ name = 'release', func = 'release' },
		{ name = 'removal', func = 'removal' },
		{ name = 'members', func = { name = membersarg, params = { 'members', 'level' }, flag = { 'd', 'p' } } },
		{ name = 'icon', func = { name = iconarg, params = { 'icon' }, flag = { 'd' } } },
		{ name = 'room', func = { name = link, params = { 'room' }, flag = { 'd' } } },
		{ name = 'hotspot', func = { name = link, params = { 'hotspot' }, flag = { 'd' } } },
		{ name = 'actions', func = { name = actionarg, params = { 'actions' }, flag = { 'd' } } },
		{ name = 'actions_smw', func = { name = actionsmw, params = { 'actions' }, flag = { 'p' } }, dupes = true },
		{ name = 'flatpack', func = { name = bool, params = { 'flatpack' }, flag = { 'd' } } },
		{ name = 'examine', func = 'has_content' },
		{ name = 'id', func = { name = iddisp,  params = { 'id' } } },
		{ name = 'id_smw', func = { name = idsmw, params = { 'id' }, flag = 'p' }, dupes = true },
		{ name = 'itemid', func = { name = iddisp,  params = { 'itemid' } } },
		{ name = 'chisel_links', func = { name = 'make_chisel_links', params = { 'name', '<br>', 'mrod', 'id', 'mrid', 'itemid' }, flag = { 'd', 'r', 'r', 'p', 'r', 'p' } } },
	}
	
	local function mat_list(args)
		local ret_list = {}
		for i=1,10,1 do
			local mat = args['mat'..i]
			if mat and paramtest.has_content(mat) then
				local name = mat
				local qty = paramtest.default_to(args['mat'..i..'qty'],'1')
				local img
				local note = ''
				if not ( name:lower() == 'nails' ) then
					img = paramtest.default_to(args['mat'..i..'img'],
										name..'.png')
										:gsub('File:','')
				else
					img = 'Steel nails.png'
					note_text = 'Any type of [[nails]] can be used'
					note = frame:extensionTag{ name = 'ref', content = note_text, args = { group = "nails" } }
				end

				table.insert(ret_list, {
					name = '[['..name..']]'..note,
					name_raw = name,
					quantity = qty,
					image = '[[File:'..img..'|link='..name..']]',
					image_raw = img
				} )
			end
		end
	
		return ret_list
	end
	
	--[[
	Function to get a list of additional requirements, should there be any
	Will take non-blank parameters and simply paste them as is into a table
	--]]
	local function get_other_reqs()
		local req_list = {}
		for i=1,5,1 do
			local req = args['misc'..i]
			if req and req:find('%S') then
				table.insert(req_list,req)
			end
		end
		return req_list
	end

	ret:useSMWOne({
		members = 'All Is members only',
		id_smw = 'All Object ID',
		
	})

	ret:useSMWSubobject({
		id_smw = 'Object ID',
		vanchor = 'Version anchor',
		name = 'Object name',
		members = 'Is members only',
		release = 'Release date',
		update = 'Release update',
		--removal = 'Removal date',
		removalupdate = 'Removal update',
		actions_smw = 'Actions'
	})

	ret:setMaxButtons(7)
	ret:create()
	ret:cleanParams()
	ret:customButtonPlacement(true)
	
	ret:linkParams{
		{ 'image' },
	}
	
	ret:defineLinks({ links = {{ 'Template:%s/doc', 'doc' },
		{ 'Template_talk:%s', 'Talk page' }}, colspan = 2 })
		
	ret:defineName('Infobox Construction')
	ret:addClass('infobox-construction')
	ret:addButtonsCaption()
	
	-- PARAMETER: image
	ret:addRow{
		{ tag = 'argd', content = 'image', class = 'infobox-image', colspan = '2' } }
	
	-- PARAMETER: name
	ret:addRow{
		{ tag = 'argh', content = 'name', class = 'infobox-header', colspan = '2' } }

	-- PARAMETER: buildname
		:addRow{ { tag = 'th', content = 'Build name' },
				{ tag = 'argd', content = 'buildname' } }

	-- PARAMETER: release
	-- (update included automatically by infobox)
		:addRow{ { tag = 'th', content = 'Release' },
				{ tag = 'argd', content = 'release' } }
	
	-- PARAMETER: removal
	if ret:paramDefined('removal') then
		ret:addRow{ { tag = 'th', content = 'Removal' },
				{ tag = 'argd', content = 'removal' } }
	end
	
	-- PARAMETER: members
	ret:addRow{
		{ tag = 'th', content = '[[Members]]' },
		{ tag = 'argd', content = 'members' } }
	
	-- PARAMETER: icon
	ret:addRow{
		{ tag = 'th', content = 'Icon' },
		{ tag = 'argd', content = 'icon' } }
	
	-- PARAMETERS: level and secLevel
	local levelrow = ret:tag('tr')
						    :tag('th')
							    :wikitext('Level')
							:tag('td')
	local level_defined = ret:paramDefined('level')
	local secLevel_defined = ret:paramDefined('secLevel')
	if level_defined and not secLevel_defined then
		levelrow:wikitext(tonumber(args.level)..' '..skillpic('Construction'))
	elseif level_defined and secLevel_defined then
		levelrow:tag('table')
					:tag('tr')
						:tag('td')
							:css({ ['text-align'] = 'right',
								   ['padding'] = 0
							})
							:wikitext(tonumber(args.level))
						:tag('td')
							:css({ ['text-align'] = 'left',
								   ['padding'] = 0 })
							:wikitext(skillpic('Construction'))
					:tag('tr')
						:tag('td')
							:css({ ['text-align'] = 'right',
								   ['padding'] = 0
							})
							:wikitext(tonumber(args.secLevel))
						:tag('td')
							:css({ ['text-align'] = 'left',
								   ['padding'] = 0 })
							:wikitext(skillpic(args.secSkill))
	end

	-- PARAMETERS: experience and secXP
	local exprow = ret:tag('tr')
						    :tag('th')
							    :wikitext('[[Experience]]')
							:tag('td')
	local experience_defined = ret:paramDefined('experience')
	if experience_defined and not ret:paramDefined('secSkill') then
		exprow:wikitext(tonumber(args.experience))
	elseif experience_defined and ret:paramDefined('secXP') then
		exprow:tag('table')
					:tag('tr')
						:tag('td')
							:css({ ['text-align'] = 'right',
								   ['padding'] = 0
							})
							:wikitext(tonumber(args.experience))
						:tag('td')
							:css({ ['text-align'] = 'left',
								   ['padding'] = 0 })
							:wikitext(skillpic('Construction'))
					:tag('tr')
						:tag('td')
							:css({ ['text-align'] = 'right',
								   ['padding'] = 0
							})
							:wikitext(tonumber(args.secXP))
						:tag('td')
							:css({ ['text-align'] = 'left',
								   ['padding'] = 0 })
							:wikitext(skillpic(args.secSkill))
	end
	
	-- PARAMETER: room
	ret:addRow{
		{ tag = 'th', content = '[[Player-owned house#Rooms|Room]]' },
		{ tag = 'argd', content = 'room' } }

	-- PARAMETER: hotspot
	:addRow{
		{ tag = 'th', content = '[[Hotspot]]' },
		{ tag = 'argd', content = 'hotspot' } }

	-- PARAMETERS: matx, matxqty, matximg
	local table_mats_wrap = ret:tag('tr')
						    :tag('th')
							    :wikitext('Materials')
							:tag('td')

	local materials = mat_list(args)
	if #materials > 0 then
		table_mats = table_mats_wrap:tag('table')
	end
	for _, v in ipairs(materials) do
		-- Fetch all the variables
		local mat_name = v.name
		local mat_qty = v.quantity
		local mat_img = v.image
		table_mats:tag('tr')
					:tag('td')
						:css({ ['text-align'] = 'right',
							   ['padding'] = 0,
							   ['white-space'] = 'nowrap'
						})
						:wikitext(commas._add(mat_qty)..' × ')
					:tag('td')
						:css({ ['text-align'] = 'center',
							   ['padding'] = 0 })
						:wikitext(mat_img)
					:tag('td')
						:css({ ['text-align'] = 'left',
							   ['padding'] = 0 })
						:wikitext(' '..mat_name)
	end

	-- Miscellaneous requirements for construction
	local misc_reqs = get_other_reqs()
	if #misc_reqs > 0 then
		for _, misc_req in ipairs(misc_reqs) do
			table_mats_wrap:wikitext(misc_req)
		end
	end
	
	-- If no materials found
	-- Indicate nothing listed, add an edit button for the page
	if #materials == 0 then
		if args['materials'] then
			table_mats_wrap	:wikitext(args['materials'])
					:done()
		else
			table_mats_wrap	:css({ ['font-style'] = 'italic' })
							:wikitext('Unknown materials '..editbutton())
						:done()
		end
	end
	
	-- PARAMETER: actions
	ret:addRow{
		{ tag = 'th', content = 'Actions' },
		{ tag = 'argd', content = 'actions' } }

	-- PARAMETER: flatpack
	ret:addRow{
		{ tag = 'th', content = '[[Flatpack|Flatpackable]]' },
		{ tag = 'argd', content = 'flatpack' } }

	-- PARAMETER: examine
	ret:addRow{
		{ tag = 'th', content = '[[Examine]]' },
		{ tag = 'argd', content = 'examine' } }
	
	-- References
	local ref = ''
	for _, v in ipairs(materials) do
		if v.name_raw:lower() == 'nails' then
			ref = '\n' .. frame:extensionTag{ name = 'references', args = { group = "nails" } }
			
		end
	end
	if ref ~= '' then
		ret:tag('tr')
				:tag('th')
					:addClass('infobox-subheader')
					:attr('colspan', '2')
					:wikitext('References')
			:tag('tr')
				:tag('td')
					:attr('colspan', '2')
					-- :css('text-align', 'center')
					:wikitext(ref)
	end
	
	-- Advanced data
	ret:addRow{
		{ tag = 'th', content = 'Advanced data', class = 'infobox-subheader', colspan = '2' },
		meta = {addClass = 'advanced-data'} }
	:addRow{
		{ tag = 'th', content = 'Object ID' },
		{ tag = 'argd', content = 'id' },
		meta = {addClass = 'advanced-data'} }
	if ret:paramDefined('itemid') then
		ret:addRow{
			{ tag = 'th', content = 'Item ID' },
			{ tag = 'argd', content = 'itemid' },
			meta = {addClass = 'advanced-data'} }
	end
	ret:addRow{
		{ tag = 'th', content = 'Links' },
		{ tag = 'argd', content = 'chisel_links' },
		meta = {addClass = 'advanced-data'} }

	ret:finish()
	if onmain() then
		local a1 = ret:param('all')
		local a2 = ret:categoryData()
		ret:wikitext(addcategories(a1,a2))
		
		-- SMW
		if #materials > 0 then
			smw = {}
			table.insert(smw,'Required materials:')
			local jsonmats = {}
			for _, v in ipairs(materials) do
				table.insert(jsonmats,{ name = v.name_raw, quantity = commas._strip(v.quantity), image = v.image_raw })
				table.insert(smw,string.format('[[Made from item::%s]]',v.name_raw))
			end
	
			local tojson = {
				product = args.buildname or mw.title.getCurrentTitle().text,
				link = mw.title.getCurrentTitle().text,
				image = '[[File:'..args.icon..'|link='..mw.title.getCurrentTitle().text..']]',
				ticks = args.ticks or editbutton(),
				improved = 0,
				method = 'construction',
				facility = 'Player-owned house',
				mats = jsonmats,
				skill = 'Construction',
				level = tonumber(args.level) or '?',
				exp = tonumber(args.experience) or '?',
				skill2 = args.secSkill or '?',
				level2 = tonumber(args.secLevel) or '?',
				exp2 = tonumber(args.secXP) or '?',
				skill3 = '?',
				level3 = '?',
				exp3 = '?',
				quantity = 1
			}
			mw.logObject(tojson)
			local json = mw.text.nowiki(mw.text.jsonEncode(tojson))
	
			table.insert(smw,'- - - - - - - - - -')
			table.insert(smw,'Production JSON:')
			table.insert(smw,string.format('[[Production JSON::%s]]',json))
			ret	:tag('div')
					:attr('smw-infobox-data')
					:addClass('hidden')
					:css('display','none')
					:wikitext(table.concat(smw,'\n'))
				:done()
		end
	end

	return ret:tostring()
	
end

function buildnamearg(arg)
	if infobox.isDefined(arg) then
		return arg
	else
		return mw.title.getCurrentTitle().text
	end
end

function imgarg(arg)
	if infobox.isDefined(arg) then
		return cleanimg{ file = arg, width = 300, height = 300 }
	end
	return nil
end

function iconarg(arg)
	if infobox.isDefined(arg) then
		return '[[File:'..arg..']]'
	end
	return nil
end

function membersarg(member, level)
	if infobox.isDefined(member) then
		return yesno(member) and 'Yes' or 'No'
	elseif infobox.isDefined(level) then
		if tonumber(level) > 5 then
			return 'Yes'
		elseif tonumber(level) <= 5 then
			return 'No'
		end
	end
end

function bool(arg)
	if infobox.isDefined(arg) then
		return yesno(arg) and 'Yes' or 'No'
	end
end

function link(arg)
	if infobox.isDefined(arg) then
		if arg:find('%[%[') then
			return arg
		end
		return '[['..arg..']]'
	end
	return nil
end

function actionarg(arg)
	if infobox.isDefined(arg) then
		local r = string.gsub(arg, ',%s*', '<br />\'\'\'&bull;\'\'\' ')
		r = '\'\'\'&bull;\'\'\' ' .. r
		r = mw.ustring.gsub(r, '%[*[Ww]alk [Hh]ere%]*', '[[Walk here|Walk here]]')
		r = mw.ustring.gsub(r, '%[*[Ee]xamine%]*', '[[Examine]]')
		if not r:find('Remove') then
			r = r .. '<br />\'\'\'&bull;\'\'\' Remove'
		end
		if not r:find('Examine') then
			r = r .. '<br />\'\'\'&bull;\'\'\' [[Examine]]'
		end
		return r
	else
		return nil
	end
end

function actionsmw(arg)
	if infobox.isDefined(arg) then
		local r = string.gsub(arg, ',%s*', infobox.splitpoint)
		r = mw.ustring.gsub(r, '%[*[Ww]alk [Hh]ere%]*', 'Walk here')
		r = mw.ustring.gsub(r, '%[*[Ee]xamine%]*', 'Examine')
		if not r:find('Remove') then
			r = r .. infobox.splitpoint .. 'Remove'
		end
		if not r:find('Examine') then
			r = r .. infobox.splitpoint .. 'Examine'
		end
		return r
	end
	return nil
end

function iddisp(id)
	if infobox.isDefined(id) then
		local r = string.gsub(id, ', *', ', ')
		return r
	end
	return nil
end
function idsmw(id)
	if infobox.isDefined(id) then
		local r = string.gsub(id, ', *', infobox.splitpoint)
		return r
	end
	return nil
end

-- Categories
function addcategories(args,catargs)
	local ret = { 'Furniture' }
	
	local cat_map = {
		-- Added if the parameter has content
		defined = {
			-- parameter = 'category name',
		},
		-- Added if the parameter has no content
		notdefined = {
			image = 'Needs scenery image',
			members = 'Needs members status',
			release = 'Needs release date',
			actions = 'Needs actions added',
			examine = 'Needs examine added',
			id = 'Needs ID'
			},
	}
	
	-- Run and add mapped categories
	for n, v in pairs(cat_map.defined) do
		if catargs[n] and catargs[n].one_defined then
			table.insert(ret,v)
		end
	end
	for n, v in pairs(cat_map.notdefined) do
		if catargs[n] and catargs[n].all_defined == false then
			table.insert(ret,v)
		end
	end
	
	-- combine table and format category wikicode
	for i, v in ipairs(ret) do
		if (v ~= '') then
			ret[i] = string.format('[[Category:%s]]',v)
		end
	end

	return table.concat(ret,'')
end

return p
-- </nowiki>