Terraria Wiki

  • Discussions are now available on the Terraria Wiki.
  • Miss the old Hydra Skin? Try out our Hydralize gadget! Visit the preferences page while logged in and turn on the gadget.

READ MORE

Terraria Wiki
Advertisement
Lua logo Documentation The documentation below is transcluded from Module:Item/doc. (edit | history)

This module is intended to provide functionality to the {{item}} template.


------- l10n info --------------
local l10n_info = mw.loadData('Module:Item/l10n')

------- The following is not related to l10n. --------------

local trim = mw.text.trim
local cargo = mw.ext.cargo
local eicons = require('Module:Exclusive').simpleEicons

local currentFrame
local args_table
local lang
local l10n_table

local l10n = function(key)
	return l10n_table[key] or l10n_info['en'][key]
end

local getArg = function(key)
	local value = args_table[key]
	if not value then
		return nil
	end
	value = trim(value)
	if value == '' then
		return nil
	end
	return value
end

-- credit: http://richard.warburton.it
-- this version is with trim.
local function explode(div,str) 
	if (div=='') then return false end
	local pos,arr = 0,{}
	-- for each divider found
	for st,sp in function() return string.find(str,div,pos,true) end do
		arr[#arr + 1] = trim(string.sub(str,pos,st-1)) -- Attach chars left of current divider
		pos = sp + 1 -- Jump past current divider
	end
	arr[#arr + 1] = trim(string.sub(str,pos)) -- Attach chars right of last divider
	return arr
end

local function parseSize(size)
	if not size then return end
	local basescale, width, height
	size, basescale = unpack(explode('*', size))
	if size ~= '' then
		width, height = unpack(explode('x', string.gsub(size, 'px', '')))
		width, height = tonumber(width), tonumber(height)
		if width == 0 then width = nil end
		if height == 0 then height = nil end
	end
	return basescale, width, height
end

local function getInfoFromCargo(image)
	-- try to get from cargo cache
	local result = mw.ext.cargo.query('Imageinfo', 'width, height, cached', {
		where = 'image='.. "'"..image:gsub("'", "\\'"):gsub("'", "\\'").."'",
		orderBy = "cached DESC",
		limit = 1,
	})
	for _, row in ipairs(result) do
		return tonumber(row['width']), tonumber(row['height']), row['cached']
	end
end

local function storeInfoToCargo(image)
	local width, height
	width = tonumber(currentFrame:callParserFunction( '#imgw', image))
	if width and width ~= 0 then -- save one expensive call when the file is not a valid image.
		height = tonumber(currentFrame:callParserFunction( '#imgh', image))
		if height and height ~= 0 then
			currentFrame:callParserFunction('#cargo_store:_table=Imageinfo',{
				image = image,
				width = width,
				height = height,
				cached = os.time(),
			})
		end
	end
	return width, height
end

local function getSizeInfo(image)
	local width, height, cached = getInfoFromCargo(image)
	-- cache missed, init cache
	if not cached then
		width, height = storeInfoToCargo(image)
	end
	if width == 0 then width = nil end
	if height == 0 then height = nil end
	return width, height
end

local function getImageSize(image, width, height, scale, maxwidth, maxheight)
	-- get size info from image file itself (may be expensive)
	local w, h = getSizeInfo(image) -- store data to cache

	if not width and not height and (scale or maxwidth or maxheight) then
		width, height = w, h
	end

	-- apply scale to width/height if needed
	if scale then
		if width then width = width * scale end
		if height then height = height * scale end
	end

	-- apply maxwidth/maxheight.
	if maxwidth then
		if width then
			if width > maxwidth then width = maxwidth end
		else
			if height then width = maxwidth end
		end
	end
	if maxheight then
		if height then
			if height > maxheight then height = maxheight end
		else
			if width then height = maxheight end
		end
	end

	-- rounding
	if width then width = math.ceil(width) end
	if height then height = math.ceil(height) end

	return width, height
end

local function parseMaxSize(maxsize)
	if not maxsize then return end
	local maxwidth, maxheight = unpack(explode('x', string.gsub(maxsize, 'px', '')))
	maxwidth, maxheight = tonumber(maxwidth), tonumber(maxheight)
	if maxwidth == 0 then maxwidth = nil end
	if maxheight == 0 then maxheight = nil end
	return maxwidth, maxheight
end

local function imagecode(image, link, text, size, scale, maxsize)
	local image_output = '[[File:' .. image .. '|link='.. link .. '|' .. text
	if size or scale or maxsize then
		local basescale, width, height = parseSize(size) -- width,height: number or nil
		scale = (tonumber(scale) or 1) * (tonumber(basescale) or 1)
		if scale == 0 or scale == 1 then
			scale = nil
		end
		local maxwidth, maxheight = parseMaxSize(maxsize)
		width, height = getImageSize(image, width, height, scale, maxwidth, maxheight) -- can be 0
		if width or height then
			return image_output .. '|' .. (width or '') .. 'x' .. (height or '') .. 'px]]'
		else
			return image_output .. ']]'
		end
	else
		return image_output .. ']]'
	end
end


local function images(image, link, text, size, scale, maxsize)
	
	if not image:find('/') then
		return imagecode(image, link, text, size, scale, maxsize)
	end

	image = explode('/', image)
	local result = ''
	if size and size:find('/') then
		size = explode('/', size)
		for i, v in ipairs(image) do
			result = result .. imagecode(v, link, text, size[i], scale, maxsize)
		end
	else
		for i, v in ipairs(image) do
			result = result .. imagecode(v, link, text, size, scale, maxsize)
		end
	end
	return result
end

local getIdText = function(_type)
	local id_text
	if _type == 'item' then -- a shortcut for faster
		id_text = l10n('id_text_item')
	elseif _type == 'tile' then
		id_text = l10n('id_text_tile')
	elseif _type == 'wall' then
		id_text = l10n('id_text_wall')
	elseif _type == 'npc' then
		id_text = l10n('id_text_npc')
	elseif _type == 'mount' then
		id_text = l10n('id_text_mount')
	elseif _type == 'buff' or _type == 'debuff' then
		id_text = l10n('id_text_buff')
	elseif _type == 'projectile' then
		id_text = l10n('id_text_projectile')
	elseif _type == 'armor' then
		id_text = l10n('id_text_armor')
	else
		id_text = l10n('id_text_item')
	end
	return id_text
end

-----------------------------------------------------------------
-- main return object
return {
	
go = function(frame, args)
	-- init cache
	currentFrame = frame
	args_table = args or frame.args
	lang = getArg('lang') or 'en'
	l10n_table = l10n_info[lang] or l10n_info['en']

	local _arg1 = getArg(1) or ''
	local _nolink = getArg('nolink')
	local _link = _nolink and '' or getArg('link') or frame:expandTemplate{ title = 'tr', args = {_arg1, link='y'} } -- now:  _link == ''  means nolink.

	local text = getArg(2) or ''

	local hovertext
	if _link ~= '' then
		hovertext = _link
	else
		if _arg1 ~= '' then
			hovertext = _arg1
		else
			hovertext = text
		end
	end


	local class = 'item-link'

	local output_image, output_text, output_table = true, true, false
	local _mode = getArg('mode')
	if _mode then
		if _mode == 'image' or _mode == 'imageonly' or _mode =='onlyimage' then
			output_text = false
		elseif _mode == 'text' or _mode == 'noimage' then
			output_image = false
		elseif _mode == 'table' or _mode == '2-cell' then
			output_table = true
		end
	end

	local image_output, text_output
	if output_image then
		image_output = images(getArg('image') or (string.gsub(_arg1, ":%s*", " ") .. '.' .. (getArg('ext') or 'png')), _link, hovertext, getArg('size'), getArg('scale'), getArg('maxsize'))
	else
		image_output = ''
	end
	if output_text then
		local _note, _note2, _showid, _id = getArg('note'), getArg('note2'), getArg('showid'), getArg('id')

		if _id and not _showid then
			_showid = true
		end
		if _showid and (_showid == 'n' or _showid == 'no') then
			_showid = false
		end

		local _wrap
		if _showid or _note2 then
			_wrap = false
		else
			_wrap = getArg('wrap')
		end

		if _link ~= '' then
			if text == _link then
				text = '<span>[['..text..']]</span>'
			else
				text = '<span>[['.._link..'|'..text..']]</span>'
			end
		else
			text = '<span title="'..hovertext..'">'..text..'</span>'
		end

		local _icon, icon = getArg('icons'), nil
		if _icon == 'n' or _icon == 'no' or _icon == 'off' then
			icon = ''
		else
			icon = eicons(getArg('epage') or _arg1, lang, (_showid or _note2 or _wrap or getArg('small')) and 'y')
		end

		local content = text -- item name link text first.
		-- '-w' class means 'wrapmode', optimized for multiple lines of text. But it should be disabled for single line text.
		if _wrap then
			-- eicons in the same line
			if icon ~= '' then
				class = class .. ' -w'
				content = content .. icon
			end
			-- note in next line
			if _note then
				class = class .. ' -w'
				content = content .. '<span class="note">' .. _note .. '</span>'
			end
		else
			-- note first
			if _note then
				content = content .. '<span class="note">' .. _note .. '</span>'
			end
			if icon ~= '' then
				content = content .. icon
			end
			if _note2 then
				class = class .. ' -w'
				content = content .. '<div class="note">' .. _note2 .. '</div>'
			end
			if _showid then
				class = class .. ' -w'
				local idtype = (getArg('type') or 'item'):lower() 
				if not _id then
					_id = frame:expandTemplate{ title = idtype .. 'IdFromName', args = {_arg1} }
				end
				local id_text = getIdText(idtype)
				content = content .. '<div class="id">' .. id_text .. _id .. '</div>'
			end
		end
		text_output = '<span>' .. content .. '</span>'
	else
		text_output = ''
	end

	local _class, _css = getArg('class'), getArg('css')
	if _class then
		class = class .. ' ' .. _class
	end
	local attr = {class = class}
	if _css then
		attr.style = _css
	end
	
	if getArg('anchor') then
		text_output = text_output .. '<div class="anchor" id="' .. frame:callParserFunction('anchorencode', _arg1) .. '"></div>'
	end
	if output_table then
		attr.class = class .. ' block aligncenter'
		local result = mw.text.tag('span', attr, image_output) .. '||'
		attr.class = class .. ' block alignleft'
		return result .. mw.text.tag('span', attr, text_output)
	else
		return mw.text.tag('span', attr, image_output .. text_output)
	end
end,
	
}
Advertisement