Module:Item

From Granblue Fantasy Wiki
Jump to: navigation, search

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

local p = {}
local getArgs = require('Module:Arguments').getArgs
local itemData = mw.loadData('Module:ItemData')

function p.render(frame)
	args = getArgs(frame)
	return p._render(args)
end

function p.renderList(frame)
	args = getArgs(frame)
	return p._renderList(args)
end

function p._render(args)
	local options = {}
	for k,v in pairs(args) do
		local value = mw.text.trim(v)
		if k == 1 then
			local name
			local count
			name, count = p.parseName(value)
			
			local group = p.getItemGroup(name)
			if group ~= nil then
				local param = nil
				if group.type == itemData.types.group_element then
					param = args['element']
				elseif group.type == itemData.types.group_weapon then
					param = args['weapon']
				end
				if param ~= nil then
					name = group[param]
				else
					-- need to implement tooltip feature
				end
			end

			options.name = options.name or name
			options.title = options.title or name
			--options.icon = options.icon or name
			options.link = options.link or name
			if count ~= 0 then
				options.count = options.count or count
			end
		elseif k == 'count' then
			value = value:gsub(',', '')
			options.count = tonumber(value)
		elseif k == 'link' then
			options.link = value
		elseif k == 'title' then
			options.title = value
		elseif k == 'size' then
			options.size = tonumber(value)
		elseif k == 'element' then
			options.element = value
		elseif k == 'icon' then
			if value == 'square' then
				options.icon = itemData.types.icon_square
			elseif value == 'icon' then
				options.icon = itemData.types.icon_icon
			elseif value == 'tall' then
				options.icon = itemData.types.icon_tall
			elseif value == 'full' then
				options.icon = itemData.types.icon_full
			end
		elseif k == 'weapon' then
			options.weapon = value
		else
			if value == 'numleft' then
				options.showCountLeft = true
			elseif value == 'nolink' then
				options.showLink = false
			elseif value == 'notitle' then
				options.showTitle = false
			elseif value == 'titlebelow' then
				options.showTitleBelow = true
			elseif value == 'white' then
				options.forceWhite = true
			elseif value == 'png' then
				options.forceExt = 'png'
			elseif string.find(value, 'large') ~= nil then
				options.icon = itemData.types.icon_icon
				options.showTitleBelow = true
				if options.size == nil then
					local i, j = string.find(value, ',')
					if i ~= nil then
						local size = tonumber(string.sub(value, i+1))
						options.size = size or 110
					else
						options.size = 110
					end
				end
			else
				mw.log('Unknown value: "' .. mw.text.encode(value) .. '"')
			end
		end
	end

	return p.makeLink(options)
end

function p._renderList(args)
	local options = {
		element = 'any',
		weapon  = 'any',
		bullets = false,
		nolink = false,
		numleft = false,
	}
	
	local items = {}
	
	for k,v in pairs(args) do
		local value = mw.text.trim(v)
		if k == 'element' then
			if (itemData.elements[value] ~= nil) then
				options.element = value
			end
		elseif k == 'weapon' then
			if (itemData.weapons[value] ~= nil) then
				options.weapon = value
			end
		elseif k == 'numleft' then
			options.numleft = true
		elseif k == 'bullets' then
			options.bullets = true
		elseif k == 'nolink' then
			options.nolink = true
		elseif k == 'white' then -- Not supported. TODO: Remove completely
			-- do nothing
		elseif k == 'noifexist' then -- Not supported. TODO: Remove completely
			-- do nothing
		else
			local name
			local count
			local opt
			name, count, optstr = p.parseName(value)

			local item = {
				text = value,
				name = name,
				count = count,
				optstr = optstr,
			}
			
			mw.logObject(item)
			
		end
	end
end

function p.getItemGroup(name)
	local lc_name = string.lower(name)
	local group = itemData.groups[lc_name]
	while (group ~= nil) and (group.alias ~= nil) do
		lc_name = string.lower(group.alias)
		group = itemData.groups[lc_name]
	end
	return group
end

function p.makeLink(options)
	local name = options.name
	local categories = {}
	local itemCount = options.count or 0
	local iconMode = options.icon or itemData.types.icon_square
	local forceExt = options.forceExt or false
	local link = options.link or options.name or options.title
	local title = options.title or options.name or options.link
	local icon = options.name or options.link or options.title or ''

	local iconSize = options.size or 0

	local showCount = itemCount ~= 0
	local showCountLeft = showCount and (options.showCountLeft or false)
	local showLink = options.showLink
	if showLink == nil then showLink = true end
	local showTitle = options.showTitle
	if showTitle == nil then showTitle = true end
	local showTitleBelow = options.showTitleBelow or false

	-- To be deprecated
	local forceWhite = options.forceWhite or false
	if forceWhite then
		table.insert(categories, 'Cleanup: Remove forced white items.')
	end

	-- If we have no icon don't show one
	if icon == '' then
		iconMode = itemData.types.icon_none
	end
	
	if showCount and (itemCount < 0) then
		itemCount = '?'
	else
		itemCount = p.comma_value(itemCount)
	end
	
	-- Icon size
	if tonumber(iconSize) == nil then
		-- convert old px values to a number
		iconSize = tonumber(string.match(iconSize, '%d+'))
		if iconSize == nil then
			iconSize = 0
		end
	elseif type(iconSize) ~= 'number' then
		iconSize = tonumber(iconSize)
	end
	if iconSize <= 0 then iconSize = 25	end
	
	local result = {}
	
	local s = '<span class="image_link">'
	if forceWhite then s = '<span class="image_link white">' end
	table.insert(result, s)
	
	-- Count on left side
	if showCountLeft and not showTitleBelow then
		table.insert(result, itemCount .. '× ')
	end

	-- Item icon
	iconOptions = {}
	iconOptions.showLink = showLink
	iconOptions.forceExt = forceExt
	table.insert(result, p.makeImageTag(icon, iconMode, iconSize, link, iconOptions))
	
	if showTitleBelow then
		table.insert(result, '<br />') 
	end

	if showCountLeft and showTitleBelow then
		table.insert(result, itemCount .. '× ')
	end
	-- Item name
	if showTitle then
		if showLink then
			table.insert(result, ' [[' .. link .. '|' .. title .. ']]')
		else
			table.insert(result, ' ' .. title)
		end
	end
	
	-- Count on right side
	if showCount and (showCountLeft == false) then
		table.insert(result, ' ×' .. itemCount)
	end
	
	table.insert(result, '</span>')
	
	return table.concat(result, '')
	

--[[
}<span class="image_link {{ #if: {{ #var: itm_white }} | white }}">{{ 
  #if: {{ #var: itm_numleft }}
  | {{ 
    #if: {{ #var: itm_large }}
    | 
    | {{ #var: itm_count}}×&nbsp;
    }}
  }}~~File:{{ #var: itm_name }} {{ 
  #if: {{ #var: itm_large }}
  | icon.{{ #if: {{ #var: itm_png }} | png | jpg}}{{!}}{{ #var: itm_large_size }}px{{!}}link=
  | square.{{ #if: {{ #var: itm_png }} | png | jpg}}{{!}}25px{{!}}link=
  }}{{
  #if: {{ #var: itm_link }}
  | {{ #if: {{{link|}}} | {{{link}}} | {{ #var: itm_name }} }}
  }}~~ {{ 
  #ifeq: {{ #var: itm_notitle }} | true
  |
  | {{ 
    #if: {{ #var: itm_large }}
    | <br />{{ 
      #if: {{ #var: itm_numleft }}
      | {{ #var: itm_count}}×&nbsp;
      }}
    }}{{
    #if: {{ #var: itm_link }}
    | ~~{{ #if: {{{link|}}} | {{{link}}} | {{ #var: itm_name }} }}|{{ #if: {{ #var: itm_title }} | {{ #var: itm_title }} | {{ #var: itm_name }} }}~~
    | {{ #if: {{ #var: itm_title }} | {{ #var: itm_title }} | {{ #var: itm_name }} }}
    }}{{
    #if: {{ #var: itm_numright}}
    |&nbsp;×{{ #var: itm_count}} 
    }}
  }}</span>
--]]
end

function p.makeImageTag(icon, mode, size, link, options)
	if mode == itemData.types.icon_none then return nil end
	local image_name = icon
	local image_ext = nil

	if mode == itemData.types.icon_square then
		image_name = image_name .. ' square'
		image_ext = 'jpg'
	elseif mode == itemData.types.icon_icon then
		image_name = image_name .. ' icon'
		image_ext = 'jpg'
	elseif mode == itemData.types.icon_tall then
		image_name = image_name .. ' tall'
		image_ext = 'jpg'
	elseif mode == itemData.types.icon_full then
		image_ext = 'png'
	elseif mode == itemData.types.icon_wood then
		image_name = 'Icon Wood Chest'
		image_ext = 'png'
	elseif mode == itemData.types.icon_silver then
		image_name = 'Icon Silver Chest'
		image_ext = 'png'
	elseif mode == itemData.types.icon_gold then
		image_name = 'Icon Gold Chest'
		image_ext = 'png'
	elseif mode == itemData.types.icon_flip then
		image_name = 'Icon Gold Chest'
		image_ext = 'png'
	end
		
	if image_ext == nil then return nil end
	
	local forceExt = options.forceExt or false
	if forceExt then image_ext = forceExt end
	
	image_name = string.gsub(image_name, ':', '-')

	local result = {}
	table.insert(result, '[[File:' .. image_name .. '.' .. image_ext)
	if size > 0 then table.insert(result, '|' .. size .. 'px') end
	table.insert(result, '|link=')
	if options.showLink then
		table.insert(result, link)
	end
	table.insert(result, ']]')
	return table.concat(result, '')
end

function p.parseName(name)
	-- Extracts the name and count from an item name
	-- If the count is not a valid number then the comma is assumed to be part of the name
	-- "name" is only whatever portion is to the left of semicolon (;), dollar signs ($) and item count comma (,)
	local s = mw.text.trim(string.match(name, '[^;$]+'))
	local n = string.match(s, '^(.*),')
	local sop = string.find(name, '[$;]', 1)
	local so = ''
	if (sop ~= nil) then
		so = string.sub(name, sop+1)
	end
	if n ~= nil then
		local l = string.len(n) + 2
		-- trim after getting length
		n = mw.text.trim(n)
		--mw.log('n: "' .. n .. '"')
		--mw.log('l: "' .. l .. '"')
		local c = mw.text.trim(string.sub(s, l))
		if string.len(c) == 0 then
			return n, 0, so
		end
		if (c == '?') or (c == '??') then
			return n, -1, so
		else
			c = tonumber(c)
			if c ~= nil then
				--mw.log('c: "' .. c .. '"')
				return n, c, so
			end
		end
	end

	return s, 0, so
end

function p.comma_value(amount)
  local formatted = amount
  while true do  
    formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1,%2')
    if (k==0) then
      break
    end
  end
  return formatted
end

function p.testImage()
	options = {}
	options.showLink = true
	return p.makeImageTag('Half Elixir', itemData.types.icon_square, 25, 'Half Elixir', options)
end

function p.testElement()
	options = {}
	options[1] = 'urn'
	options['element'] = 'fire'
	return p._render(options)
end

function p.testWeaponStone()
	options = {}
	options[1] = 'weapon stone'
	options['weapon'] = 'sabre'
	return p._render(options)
end

function p.testAlias()
	options = {}
	options[1] = 'quartz'
	options['element'] = 'wind'
	return p._render(options)
end

function p.testGarula()
	options = {}
	options[1] = 'Garula, Shining Hawk'
	return p._render(options)
end

function p.testCount()
	options = {}
	options[1] = 'Kero-chan,33'
	return p._render(options)
end

function p.testCount2()
	options = {}
	options[1] = 'Kero-chan'
	options['count'] = '33,333'
	return p._render(options)
end

function p.testComma()
	options = {}
	options[1] = 'Kero-chan,'
	return p._render(options)
end

function p.testComma2()
	options = {}
	options[1] = 'Kero-chan,??'
	return p._render(options)
end

function p.testColon()
	options = {}
	options[1] = 'Kero-chan: The Skin: Fluffy: Fumoffu,'
	return p._render(options)
end

function p.testList()
	options = {
		'Half Elixir;flip',
		'Soul Berry;flip'
	}
	p._renderList(options)
end

return p