Module:Gear

From Fantasy Life Wiki
Jump to navigation Jump to search

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

-- Module Gear contains functions to create the Infobox for gear
-- Uses Data stored in Module Gear/xxxxx/Data

local qualities = {'Nor', 'Good', 'Great', 'Top', 'Divine'}
local qualities2 = {'Normal', 'Good', 'Great', 'Top', 'Divine'}
local gear = {
	'Longswords', 'Greatswords', 'Bows', 'Staves', 'Daggers',
	'Pickaxes', 'Axes', 'FishingRods', 'FryingPans', 'Hammers', 'Saws', 'Needles', 'Flasks',
	'Head', 'Shields' , 'Accessories', 'Body', 'Legs', 'Hand', 'Feet'
}

--Function to add the Japanese Name under the Enligsh name if it founds the Japanese name in the Data Module
--	@function		japaneseName
--	@param			{data} Item data
--	@param			{name} Item name
--	@returns		{row} just the name in english or with the japanese name
local function japaneseName(data, name)
	if (data.Japanese == nil) then
		return mw.html.create():wikitext("'''".. name .."'''")
	end
	return mw.html.create():wikitext("'''".. name ..'<br><span lang="ja">'..data.Japanese.."</span>'''")
end

--Function that creates Brown table with name and Icon
--	@function		createTabber
--	@param			{data} Item data
--	@param			{name} Item name
--	@param			{i} index for the item quality
--	@param			{h} height of the cell where is the item image
--	@param			{hide} use to add class 'mobile-hidden'
--	@returns		{row} html table with Title, Image and Description information
local function createTabber(data, name,i,h,hide)
	local row = mw.html.create('table')
	if (hide ~= 1) then
		row:addClass('mobile-hidden')
	end
	return row:addClass('gearInfoTableIconRow'):css('border-radius', '6px'):attr('width', '100%')
		:tag('tr')
			:css('position', 'relative')
			:tag('td'):addClass('gearInfoTableIconRowName')
				:attr('width', '192px'):attr('height', h):css('align', 'center')
				:node(japaneseName(data, name))
			:done()
			:tag('td')
				:tag('span')
					:css('position', 'absolute'):css('bottom', '0'):css('right', '0'):addClass('mobile-hidden')
					:wikitext('[[File:Gear '..qualities2[i]..'.png]]')
				:done()
				:tag('span')
					:css('position', 'absolute'):css('bottom', '0'):css('right', '0')
					:wikitext('[[File:'.. name ..'.png]]')
				:done()
			:done()
		:done()
		:tag('tr')
			:attr('align', 'left')
			:tag('td')
				:addClass('gearInfoTableDesc'):css('border-radius', '3px'):css('padding-left', '7px'):css('padding-right', '7px')
				:attr('colspan', '2')
				:wikitext(data.Description)
			:done()
		:done()
end

--Function adds tabber for the different Icons Backgrounds If Item is craftable and has diferent Qualities
--	@function		makeQuality
--	@param			{data} Item data
--	@param			{name} Item name
--	@returns		{row} html table for mobile and non-craftable items or a tabber
local function makeQuality(data, name)
	local tabber = mw.html.create('tabber')
	if (data.CraftClass == nil) then
		return createTabber(data, name,1,72,1)
	end
	for i = 1, 5 do
		tabber:wikitext('|-|'..qualities[i]..'= ')
			:node(createTabber(data, name,i,85,i))
		:done()
	end
	return tabber
end

--Function to create the Table Row of the main Headers use in Rarity, Usable By, Stats, Information, etc.
--	@function		mainHeader
--	@param			{name} header Title
--	@param			{h} header height
--	@returns		{row} single html row for main headers
local function mainHeader(name, h)
	return mw.html.create('tr'):css('position', 'relative')
		:tag('td'):attr('height', h):addClass('mobile-hidden'):done()
		:tag('th'):addClass('gearInfoTableHeader'):css('border-top-right-radius', '6px'):css('border-top-left-radius', '6px')
			:css('display','inline'):css('position', 'absolute'):css('right', '18px'):attr('colspan', '4')
			:attr('width','256'):attr('height', h):wikitext(name)
		:done()
end

--Function to fill in the right lives usable by the item
--	@function		usable
--	@param			{data} item data
--	@returns		{row} text with information on the item's Lives
local function usable(data)
	local lifeIcons = {	Paladin = '[[File:Paladin icon 0.png|link=Paladin]] ', 
		Mercenary = '[[File:Mercenary icon 0.png|link=Mercenary]] ',
		Hunter = '[[File:Hunter icon 0.png|link=Hunter]] ',
		Magician = '[[File:Magician icon 0.png|link=Magician]] ',
		Miner = '[[File:Miner icon 0.png|link=Miner]] ',
		Woodcutter = '[[File:Woodcutter icon 0.png|link=Woodcutter]] ',
		Angler = '[[File:Angler icon 0.png|link=Angler]] ',
		Cook = '[[File:Cook icon 0.png|link=Cook]] ',
		Blacksmith = '[[File:Blacksmith icon 0.png|link=Blacksmith]] ',
		Carpenter = '[[File:Carpenter icon 0.png|link=Carpenter]] ',
		Tailor = '[[File:Tailor icon 0.png|link=Tailor]] ',
		Alchemist = '[[File:Alchemist icon 0.png|link=Alchemist]] '}
	if (data.Usable[1] == "All") then
		return mw.html.create():wikitext('[[File:Paladin icon 1.png|link=Paladin]] [[File:Mercenary icon 1.png|link=Mercenary]] [[File:Hunter icon 1.png|link=Hunter]] [[File:Magician icon 1.png|link=Magician]] [[File:Miner icon 1.png|link=Miner]] [[File:Woodcutter icon 1.png|link=Woodcutter]] [[File:Angler icon 1.png|link=Angler]] [[File:Cook icon 1.png|link=Cook]] [[File:Blacksmith icon 1.png|link=Blacksmith]] [[File:Carpenter icon 1.png|link=Carpenter]] [[File:Tailor icon 1.png|link=Tailor]] [[File:Alchemist icon 1.png|link=Alchemist]]')
	end
	
	--LifeIcons [ Key -> item]
	for key, item in pairs(lifeIcons) do
		for i, live in pairs(data.Usable) do
			if (live == key) then
				-- If it finds the live it change the icon to 1
				lifeIcons[key] = '[[File:'..live..' icon 1.png|link='..live..']] '
			end
		end
	end
	return mw.html.create():wikitext(lifeIcons.Paladin..lifeIcons.Mercenary..lifeIcons.Hunter..lifeIcons.Magician
		..lifeIcons.Miner..lifeIcons.Woodcutter..lifeIcons.Angler..lifeIcons.Cook
		..lifeIcons.Blacksmith..lifeIcons.Carpenter..lifeIcons.Tailor..lifeIcons.Alchemist)
end

--Function to add Row for Gender if applied
--	@function		gender
--	@param			{data} item data
--	@returns		{row} additional row if item is only wearable by one gender (male or female)
local function gender(data)
	if (data.Gender == nil) then
		return
	end
	return mw.html.create('tr')
		:tag('td'):attr('colspan', '4'):attr('align', 'center')
			:wikitext('[[File:'..data.Gender..' only.png]]')
		:done()
end

--Function to fill in the right skill and level required by the item
--	@function		required
--	@param			{data} item data
--	@returns		{row} text with information about skill and skill level of the item
local function required(data)
	if ( (data.SkillLvl == nil) and (data.Skill == nil) or (data.SkillLvl == 0) ) then
		return mw.html.create():wikitext('------')
	end
	if ( (data.SkillLvl ~= nil) and (data.Skill == nil) ) then
		return mw.html.create():wikitext('Level '..data.SkillLvl)
	end
	return mw.html.create():wikitext(data.Skill..' Level '..data.SkillLvl)
end

--Funciton to create a cell
--	@function		cell
--	@param			{text} text displayed in cell
--	@param			{tp} typy of html tag (tr, td div)
--	@param			{class} cell's class to decide background color
--	@param			{align} cell's align
--	@param			{width} cell's width
--	@param			{colspan} cell's colspan
--	@param[opt]		{border} cell's border
--	@param[opt]		{value} cell's border value
--	@param[opt]		{border2} cell's second border
--	@param[opt]		{value2} cell's second border value
--	@returns		{row} single table cell with various options
local function cell(text, tp, class, align, width, colspan, border, value, border2, value2)
	local row = mw.html.create(tp):addClass(class)
		:attr('colspan', colspan):attr('width', width):attr('height', '25'):attr('align', align)
	if(border ~= nil) then
		row:css('border-'..border..'-radius', value)
	end
	if(border2 ~= nil) then
		row:css('border-'..border2..'-radius', value2)
	end
	return row:wikitext(text)
end

--Function to create rows for values of Stat1 and Sell prices Info
--	@function		valuesDisplay
--	@param			{first} text displayed in first cell
--	@param			{second} text displayed in second cell
--	@returns		{row} create two cells both in the same row using cell funcion
local function valuesDisplay(first, second)
	return mw.html.create('tr')
		:node(cell(first, 'th', 'gearInfoTableDesc', 'center', '71', '1'))
		:node(cell(second, 'td', 'gearInfoTableDesc', 'center', '72', '1'))
end

--Function to create rows for second Stat Info
--	@function		stat2
--	@param			{data} item data
--	@returns		{row} create single row with two cells for the second stat if exists
local function stat2(data)
	if (data.Stat2 == nil) then
		return
	end
	return mw.html.create('tr')
		:node(cell(data.Stat2, 'th', 'gearInfoTableCell', 'center', '145', '2'))
		:node(cell(data.Stat2Value, 'td', 'gearInfoTableDesc', 'center', '145', '2'))
end

--Function to create rows for Recipe Info
--	@function		recipe
--	@param			{data} item data
--	@returns		{row} create block of rows for recipe class and respective ingredients if items is craftable
local function recipe(data)
	if (data.CraftClass == nil) then
		return mw.html.create():node(mainHeader('No Recipe', '25'))
	end
	if (data.Ingredients[2] == nil) then
		return mw.html.create()
			:node(mainHeader(data.CraftClass..'<br>'..data.CraftRank..' Recipe', '47'))
			:tag('tr'):attr('align', 'center')
				:node(cell(data.Ingredients[1], 'td', 'gearInfoTableCell', 'center', '218', '3', 'top-left','6px', 'bottom-left', '6px'))
				:node(cell('x '..data.Amount[1], 'td', 'gearInfoTableDesc', 'center', '72', '1', 'top-right', '6px', 'bottom-right', '6px'))
			:done()
	end
	if (data.Ingredients[3] == nil) then
		return mw.html.create()
			:node(mainHeader(data.CraftClass..'<br>'..data.CraftRank..' Recipe', '47'))
			:tag('tr')
				:node(cell(data.Ingredients[1], 'td', 'gearInfoTableCell', 'center', '218', '3', 'top-left','6px'))
				:node(cell('x '..data.Amount[1], 'td', 'gearInfoTableDesc', 'center', '72', '1', 'top-right', '6px'))
			:done()
			:tag('tr')
				:node(cell(data.Ingredients[2], 'td', 'gearInfoTableCell', 'center', '218', '3', 'bottom-left','6px'))
				:node(cell('x '..data.Amount[2], 'td', 'gearInfoTableDesc', 'center', '72', '1', 'bottom-right', '6px'))
			:done()
	end
	return mw.html.create()
		:node(mainHeader(data.CraftClass..'<br>'..data.CraftRank..' Recipe', '47'))
		:tag('tr')
			:node(cell(data.Ingredients[1], 'td', 'gearInfoTableCell', 'center', '218', '3', 'top-left','6px'))
			:node(cell('x '..data.Amount[1], 'td', 'gearInfoTableDesc', 'center', '72', '1', 'top-right', '6px'))
		:done()
		:tag('tr')
			:node(cell(data.Ingredients[2], 'td', 'gearInfoTableCell', 'center', '218', '3'))
			:node(cell('x '..data.Amount[2], 'td', 'gearInfoTableDesc', 'center', '72', '1'))
		:done()
		:tag('tr')
			:node(cell(data.Ingredients[3], 'td', 'gearInfoTableCell', 'center', '218', '3', 'bottom-left','6px'))
			:node(cell('x '..data.Amount[3], 'td', 'gearInfoTableDesc', 'center', '72', '1', 'bottom-right', '6px'))
		:done()
end

--Function to get all Data from item name
--	@function		recipe
--	@param			{name} item name
--	@returns		{data} return a lua table with all necessary item data available in Module Gear/xxxxx/Data
local function getData(name)
	for k = 1, #gear do
		local data = mw.loadData('Module:Gear/'..gear[k]..'/Data')
	    if (data[name] ~= nil) then
	    	return data[name]
	    end
	end
end

--Function to calculate the sell value of an item depending on its quality
--	@param			{value} the default sell value, {quality} the quality of the item, between 1 (good) and 4 (Divine)
--	@returns		{value} return the calculated value if the input value was an int, the unmodified input value otherwise
local function calculateSellValue(value, quality)
    if tonumber(value) then
        return math.floor(value*(1+(quality)/5))
    else
        return value
    end
end

--Function to calculate the Stat1Value value of an item depending on its quality
--	@param			{value} the default Stat1Value value, {quality} the quality of the item, between 1 (good) and 4 (Divine)
--	@returns		{value} return the calculated value if the input value was an int, the unmodified input value otherwise
function calculateStat1Value(value, quality)
    if tonumber(value) then
        return math.floor(value*(1+(quality)/10)) + quality
    else
        return value
    end
end

-- Main function that creates Template for Item
--	@function		buildGearInfobox
--	@param			{Name} item name
--	@returns		{navTable} Fully build html Table with all needed info for the item infobox.
return {
buildGearInfobox = function(frame)
	local args = frame.args;
	local name = mw.text.decode(args['Name']);
	local data = getData(name);

    local navTable = mw.html.create('table'):addClass('gearInfoTable'):css('float', 'right')
    	:css('margin-left', '10px'):css('margin-bottom', '10px'):css('font-size', 'small')
    	:css('border-radius', '10px'):css('width', '300px')
		
    	--First Row (Brown) - Title, Image and Description
		:tag('tr'):css('text-align', 'center')
			:tag('td'):attr('colspan', '4')
				:node(makeQuality(data, name))
			:done()
		:done()
		
		--Second Row - Rarity
		:node(mainHeader('Rarity','25'))
		:tag('tr'):attr('align', 'center')
			:tag('td'):addClass('gearInfoTableDesc'):css('border-radius', '6px'):attr('colspan', '4'):attr('height', '25')
				:wikitext('[[File:'..data.Rarity..' Stars.png]]')
			:done()
		:done()
		
		--Third Row - Usable
		:node(mainHeader('Usable by','25'))
		:tag('tr'):attr('align', 'center')
			:tag('td'):addClass('gearInfoTableDesc'):css('border-radius', '6px'):attr('colspan', '4'):attr('height', '25')
				:node(usable(data))
			:done()
		:done()
		
		--Fourth Row - Gender If applied
		:node(gender(data))
		
		--Fifth Row - Skill and Skill Level Required
		:node(mainHeader('Required','25'))
		:tag('tr'):attr('align', 'center')
			:tag('td'):addClass('gearInfoTableDesc'):css('border-radius', '6px'):attr('colspan', '4'):attr('height', '25')
				:node(required(data))
			:done()
		:done()
		
		--Sixth Row - Stats. (Magic) Attack, (Magic) Defense and Special Effect
		:node(mainHeader('Stats','25'))
		:tag('tr'):attr('align', 'center')
			:tag('th'):addClass('gearInfoTableCell'):css('border-top-left-radius', '6px')
				:attr('colspan', '2'):attr('rowspan', '5'):attr('width', '145')
				:wikitext(data.Stat1)
			:done()
			:node(cell('Normal', 'th', 'gearInfoTableDesc', 'center', '71', '1'))
			:node(cell(data.Stat1Value, 'td', 'gearInfoTableDesc', 'center', '72', '1', 'top-right','6px'))
		:done()
		:node(valuesDisplay(qualities[2],calculateStat1Value(data.Stat1Value, 1)))
		:node(valuesDisplay(qualities[3],calculateStat1Value(data.Stat1Value, 2)))
		:node(valuesDisplay(qualities[4],calculateStat1Value(data.Stat1Value, 3)))
		:node(valuesDisplay(qualities[5],calculateStat1Value(data.Stat1Value, 4)))
		:node(stat2(data))
		:tag('tr')
			:node(cell('Special Effects', 'th', 'gearInfoTableCell', 'center', '145', '2', 'bottom-left','6px'))
			:node(cell(data.Special, 'td', 'gearInfoTableDesc', 'center', '145', '2', 'bottom-right','6px'))
		:done()
		
		--Seventh Row - Recipe
		:node(recipe(data))
		
		--Eighth Row (Last  Row) - Information
		:node(mainHeader('Information','25'))
		:tag('tr')
			:node(cell('Buy price [[Dosh]]', 'th', 'gearInfoTableCell', 'center', '145', '2', 'top-left','6px'))
			:node(cell(data.Sold, 'td', 'gearInfoTableDesc', 'center', '145', '2', 'top-right','6px'))
		:done()
		:tag('tr'):attr('align', 'center')
			:tag('th'):addClass('gearInfoTableCell')
				:attr('colspan', '2'):attr('rowspan', '5'):attr('width', '145')
				:wikitext('Sell price<br>[[Dosh]]')
			:done()
			:node(cell('Normal', 'th', 'gearInfoTableDesc', 'center', '71', '1'))
			:node(cell(data.Sell, 'td', 'gearInfoTableDesc', 'center', '72', '1'))
		:done()
		:node(valuesDisplay(qualities[2],calculateSellValue(data.Sell, 1)))
		:node(valuesDisplay(qualities[3],calculateSellValue(data.Sell, 2)))
		:node(valuesDisplay(qualities[4],calculateSellValue(data.Sell, 3)))
		:node(valuesDisplay(qualities[5],calculateSellValue(data.Sell, 4)))
		:tag('tr')
			:node(cell('Type', 'th', 'gearInfoTableCell', 'center', '145', '2', 'bottom-left','6px'))
			:node(cell(data.Type, 'td', 'gearInfoTableDesc', 'center', '145', '2', 'bottom-right','6px'))
		:done()
	return frame:preprocess(tostring(navTable))
end
}