Module:Infobox Scenery

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

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

-- "imports"
local onmain = require('Module:Mainonly').on_main
local yesno = require('Module:Yesno')
local paramtest = require('Module:Paramtest')
local cleanimg = require('Module:Clean image').clean
local infobox = require('Module:Infobox')

-- location restriction
local restriction_map = {
	surface = 'surface',
	dungeoneering = 'dungeoneering',
	dg = 'dungeoneering',
	daemonheim = 'dungeoneering',
	quest = 'quest',
	minigame = 'minigame',
	activity = 'minigame',
	beta = 'removed',
	gone = 'removed',
	removed = 'removed',
	limited = 'limited',
	['time limited'] = 'limited',
	th = 'microtransaction',
	sof = 'microtransaction',
	['treasure hunter'] = 'microtransaction',
	['squeal of fortune'] = 'microtransaction',
	cache = 'cache'
}

function p.main(frame)
	local args = frame:getParent().args
	local ret = infobox.new(args)
	
	ret:defineParams{
		{ name = 'name', func = 'name' },
		{ name = 'aka', func = 'has_content' },
		{ name = 'image', func = { name = imgarg, params = { 'image' }, flag = { 'd' } } },
		{ name = 'imagebackground', func = { name = imgback, params = { 'imagebackground' }, flag = { 'd' } }, dupes = true },
		{ name = 'vanchor', func = { name = 'has_content', params = { 'version' }, flag = 'p' } },
		{ name = 'release', func = 'release' },
		{ name = 'removal', func = 'removal' },
		{ name = 'members', func = 'has_content' },
		{ name = 'quest', func = { name = 'has_content', params = { 'quest', 'No'}, flag = { 'd', 'r' } } },
		{ name = 'location', func = 'has_content' },
		{ name = 'examine', func = { name = examinearg, params = { 'examine' }, flag = { 'd' } } },
		{ name = 'actions', func = { name = actionarg, params = { 'actions', 'examine' }, flag = { 'd', 'd' } } },
		{ name = 'actions_smw', func = { name = actionsmw, params = { 'actions', 'examine' }, flag = { 'p', 'd' } }, dupes = true },
		{ name = 'thievelvl', func = { name = thievarg, params = { 'thievelvl' }, flag = { 'd' } } },
		{ name = 'thievelvl_smw', func = { name = thievarg, params = { 'thievelvl' }, flag = { 'd' } }, dupes = true },
		{ name = 'map', func = { name = maparg, params = { 'map' }, flag = { 'd' } } },
		{ name = 'intmap', func = { name = intmaparg, params = { 'intmap' }, flag = { 'd' } } },
		{ name = 'mapdisp', func = { name = mapdisp, params = { 'map', 'intmap' }, flag = { 'd', 'd' } }, dupes = true },
		{ name = 'restriction', func = restrictionarg },
		{ name = 'restrictionsurface', func = { name = restrsurfarg , params = { 'restriction', 'restriction', 'quest' }, flag = { 'd', 'p', 'd' } } },
		{ name = 'id', func = { name = iddisp,  params = { 'id' }, flag = 'p' } },
		{ name = 'npcid', func = { name = iddisp,  params = { 'npcid' }, flag = 'p' } },
		{ name = 'id_smw', func = { name = idsmw, params = { 'id' }, flag = 'p' }, dupes = true },
		{ name = 'npcid_smw', func = { name = idsmw, params = { 'npcid' }, flag = 'p' }, dupes = true },
		{ name = 'chisel_links', func = { name = 'make_chisel_links', params = { 'name', '<br>', 'mrod', 'id', 'mrnd', 'npcid' }, flag = { 'p', 'r', 'r', 'p', 'r', 'p' } } },
	}
	
	ret:useSMW({
		members = 'Is members only',
		thievelvl_smw = 'Thieving level'
	})

	ret:useSMWOne({
		id_smw = 'All Object ID',
		npcid_smw = 'All NPC ID'
	})

	ret:useSMWSubobject({
		id_smw = 'Object ID',
		npcid_smw = 'NPC ID',
		vanchor = 'Version anchor',
		name = 'Object name',
		members = 'Is members only',
		restriction = 'Location restriction',
		release = 'Release date',
		update = 'Release update',
		--removal = 'Removal date',
		removalupdate = 'Removal update',
		thievelvl_smw = 'Thieving level',
		actions_smw = 'Actions',
		examine = 'Examine'
	})

	
	ret:setMaxButtons(6)
	ret:create()
	ret:cleanParams()
	ret:customButtonPlacement(true)
	
	ret:linkParams{
		image = 'imagebackground'
	}
	
	ret:defineLinks({ links = {{ 'Template:%s/doc', 'doc' },
		{ 'Template_talk:%s', 'Talk page' }}, colspan = 2 })
		
	ret:defineName('Infobox Scenery')
	ret:addClass('infobox-scenery')
	
	if onmain() then
		local a2 = ret:categoryData()
		if not a2['restriction'].all_defined then
			ret:useSMWSubobject({
				restrictionsurface = 'Location restriction',
			})
		end
	end
	
	ret:addButtonsCaption()
	
	-- PARAMETER: image
	ret:addRow{
		{ tag = 'argd', content = 'image', class = 'infobox-image bordered-image', colspan = '2' },
		meta = { addClass = ret:param('imagebackground', 'r') }
	}
	
	-- PARAMETER: name
	ret:addRow{
		{ tag = 'argh', content = 'name', class = 'infobox-header', colspan = '2' } }
	
	-- 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: aka
	if ret:paramDefined('aka') then
		   ret:addRow{ { tag = 'th', content = '[[Slang dictionary|AKA]]' },
				{ tag = 'argd', content = 'aka' } }
	end
	
	-- PARAMETER: members
	ret:addRow{
		{ tag = 'th', content = '[[Members]]' },
		{ tag = 'argd', content = 'members' } }
	
	-- PARAMETER: quest
	:addRow{
		{ tag = 'th', content = '[[Quest]]' },
		{ tag = 'argd', content = 'quest' } }
	
	-- PARAMETER: location
	:addRow{
		{ tag = 'th', content = 'Location' },
		{ tag = 'argd', content = 'location' } }
	
	-- PARAMETER: actions
	:addRow{
		{ tag = 'th', content = 'Actions' },
		{ tag = 'argd', content = 'actions' } }
	
	-- PARAMETER: thievelvl
	if ret:paramDefined('thievelvl') then
		ret:addRow{
			{ tag = 'th', content = '[[File:Thieving-icon.png|link=Thieving|frameless|20px|alt=Thieving level|Thieving level]] [[Thieving|Level]]' },
			{ tag = 'argd', content = 'thievelvl' } }
	end
	
	-- PARAMETER: examine
	ret:addRow{
		{ tag = 'th', content = '[[Examine]]' },
		{ tag = 'argd', content = 'examine' } }
	
	-- PARAMETER: map
	if ret:paramGrep('mapdisp', function(x) return x == true end) then
		local mapcontent
		if ret:paramDefined('map') then
			mapcontent = 'map'
		elseif ret:paramDefined('intmap') then
			mapcontent = 'intmap'
		end
		ret:addRow{
			{ tag = 'argd', content = mapcontent, class = 'infobox-map', colspan = '2' } }
	end
	
	-- Advanced data
	ret:addRow{
		{ tag = 'th', content = 'Advanced data', class = 'infobox-subheader', colspan = '2' },
		meta = {addClass = 'advanced-data'} }
	local has_id = ret:paramGrep('id', function(x) return string.lower(x or 'none') ~= 'none' end)
	if has_id then
		ret:addRow{
			{ tag = 'th', content = 'Object ID' },
			{ tag = 'argd', content = 'id' },
			meta = {addClass = 'advanced-data'} }
	end
	local has_npcid = ret:paramDefined('npcid', 'all')
	if has_npcid then
		ret:addRow{
			{ tag = 'th', content = 'NPC ID' },
			{ tag = 'argd', content = 'npcid' },
			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))
	end
	return ret:tostring()
end

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

function imgback(arg)
	if infobox.isDefined(arg) then
		if yesno(arg) then
			return 'infobox-imgbg'
		end
	end
	return ''
end

function actionarg(arg, exam)
	if infobox.isDefined(arg) then
		if string.lower(arg) == 'none' or string.lower(arg) == 'examine' then
			if infobox.isDefined(exam) then
				local estr = string.lower(exam)
				if estr == 'no' or estr == 'none' or estr == 'n/a' then
					return 'None'
				end
			end
			return '<ul><li>Examine</li></ul>'
		end
		local has_examine = false
		local ret = mw.html.create('ul')
		for x in mw.text.gsplit(arg, ',') do
			ret:tag('li'):wikitext(mw.text.trim(x))
			has_examine = has_examine or (string.find(x, 'Examine') ~= nil)
		end
		if not has_examine then
			ret:tag('li'):wikitext('Examine')
		end
		ret = tostring(ret)
		ret = mw.ustring.gsub(ret, '%[*[Ww]alk [Hh]ere%]*', '[[Walk here|Walk here]]')
		ret = mw.ustring.gsub(ret, '%[*[Ee]xamine%]*', 'Examine')
		return ret
	end
	return nil
end

function actionsmw(arg, exam)
	if infobox.isDefined(arg) then
		if string.lower(arg) == 'none' or string.lower(arg) == 'examine' then
			if infobox.isDefined(exam) then
				local estr = string.lower(exam)
				if estr == 'no' or estr == 'none' or estr == 'n/a' then
					return 'None'
				end
			end
			return 'Examine'
		end
		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('Examine') then
			r = r .. infobox.splitpoint .. 'Examine'
		end
		return r
	end
	return nil
end

function examinearg(arg)
	if infobox.isDefined(arg) then
		local lstr = string.lower(arg)
		if lstr == 'no' or lstr == 'none' or lstr == 'n/a' then
			return 'N/A'
		end
		local r = string.gsub(arg, '*', '<br />\'\'\'&bull;\'\'\' ')
		r = mw.ustring.gsub(r, '<br%s*/?>', '', 1)
		return r
	end
	return nil
end

function thievarg(arg)
	arg = string.gsub(arg or '',',','')
	return tonumber(arg, 10)
end

function maparg(arg)
	if infobox.isDefined(arg) then
		local low = string.lower(arg)
		if yesno(low) == false then
			return nil
		elseif low == 'name' then
			return string.format('[[File:%s location.png]]', mw.title.getCurrentTitle().text)
		elseif string.find(low, '.png') then
			return cleanimg{ file = arg, width = 250 }
		else
			return arg
		end
	else
		return nil
	end
end

function intmaparg(arg)
	if infobox.isDefined(arg) then
		if yesno(arg) == false then
			return nil
		else
			return mw.getCurrentFrame():preprocess( arg )
		end
	else
		return nil
	end
end

function mapdisp(map, intmap)
	if infobox.isDefined(intmap) then
		intmap = string.lower(intmap)
		if not (intmap == 'no' or intmap == 'none') then
			return true
		end
	end
	if infobox.isDefined(map) then
		map = string.lower(map)
		if not (map == 'no' or map == 'none') then
			return true
		end
	end
	return false
end

function restrictionarg(arg)
	if paramtest.is_empty(arg) then
		return nil
	end
	return restriction_map[string.lower(arg)]
end
function restrsurfarg(cleaned, passed)
	if infobox.isDefined(cleaned) then
		return nil
	end
	return restriction_map.surface
end

function iddisp(id)
	if infobox.isDefined(id) then
		if id:lower() ~= 'no' and id:lower() ~= 'none' then
			local r = string.gsub(id, ', *', ', ')
			return r
		elseif id:lower() == 'no' or id:lower() == 'none' then
			return 'None'
		end
	end
	return nil
end
function idsmw(id)
	if infobox.isDefined(id) and id:lower() ~= 'no' and id:lower() ~= 'none' then
		local r = string.gsub(id, ', *', infobox.splitpoint)
		return r
	end
	return nil
end

-- Categories
function addcategories(args,catargs)
	local ret = {}
	table.insert(ret, 'Scenery')
	
	
	-- ID based categories
	local misID = {}
	if args.id.switches then
		for i,v in ipairs(args.id.switches) do
			if infobox.isDefined(v) and v ~= 'None' then
				table.insert(ret, 'Cache scenery')
			else
				misID[i] = true
			end
		end
	elseif args.id.d ~= 'None' then
		table.insert(ret, 'Cache scenery')
	end
	
	if args.npcid.switches then
		for i,v in ipairs(args.npcid.switches) do
			if infobox.isDefined(v) and v ~= 'None' then
				table.insert(ret, 'Cache NPCs')
				if misID[i] then
					misID[i] = false
				end
				-- "Interactive characters" and "Non-interactive characters" removed so they only apply to entities interacted with as NPCs
				-- which should use [[Template:Infobox NPC]]
			end
		end
	elseif infobox.isDefined(args.npcid.d) and args.npcid.d ~= 'None' then
		table.insert(ret, 'Cache NPCs')
		misID = {}
		-- "Interactive characters" and "Non-interactive characters" removed so they only apply to entities interacted with as NPCs
		-- which should use [[Template:Infobox NPC]]
	end
	for _,v in pairs(misID) do
		if v then
			table.insert(ret, 'Needs ID')
		end
	end
	
	-- Action based categories
	if args.actions_smw.switches then
		for _,v in ipairs(args.actions_smw.switches) do
			if infobox.isDefined(v) then
				if v == 'Examine' or v == 'None' then
					table.insert(ret, 'Non-interactive scenery')
				else
					table.insert(ret, 'Interactive scenery')
				end
			end
		end
	elseif infobox.isDefined(args.actions_smw.d) then
		if args.actions_smw.d == 'Examine' or v == 'None' then
			table.insert(ret, 'Non-interactive scenery')
		else
			table.insert(ret, 'Interactive scenery')
		end	
	end
	
	-- Non-examinable scenery
	if args.examine.switches then
		for _,v in ipairs(args.examine.switches) do
			if infobox.isDefined(v) and v == 'N/A' then
				table.insert(ret, 'Non-examinable scenery')
			end
		end
	elseif infobox.isDefined(args.examine.d) then
		if args.examine.d == 'N/A' then
			table.insert(ret, 'Non-examinable scenery')
		end
	end
	
	local cat_map = {
		-- Added if the parameter has content
		defined = {
			aka = 'Pages with AKA',
			thievelvl = 'Thievable entities',
		},
		-- 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',
			quest = 'Scenery missing quest',
			mapdisp = 'Needs map'
			},
	}
	
	-- 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
	
	-- quest restriction
	-- just look for a link
	if args.quest.d:find('%[%[') then
		table.insert(ret,'Quest scenery')
	end
	if args.quest.switches then
		for _, v in ipairs(args.quest.switches) do
			if v:find('%[%[') then
				table.insert(ret,'Quest scenery')
				break
			end
		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>