Module:Data

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

local p = {}
local utils = require("Module:Utils")
local constant = mw.loadJsonData("Module:Constant.json")
local data = mw.loadJsonData("Module:Data.json")
local id = mw.loadJsonData("Module:ObjectID.json")
local lootTable = mw.loadJsonData("Module:LootTable.json")

function p.createInfobox(frame)
	local name = frame.args.name
	if name == nil or name == "" then name = mw.title.getCurrentTitle().subpageText end
	local image = frame.args.image
	local obj = data[name]
	local category = utils.getCategory(name)
	
	local str = {
		image = image,
		type = category and category[1] .. ', ' .. category[2],
		rarity = obj.rare,
		level = obj.lv,
		mana = obj.eq and (obj.eq.mp and obj.eq.mp[1]),
		damage = utils.getDamage(obj),
		aps = '',
		effects = utils.getEffects(obj),
		seteffects = utils.getSetEffects(obj, frame),
		durability = obj.eq and obj.eq.dur,
		fullness = obj.eq and obj.eq.ful,
		cookable = obj.cook and 'Yes',
		paintable = obj.paint and 'Yes',
		description = obj.desc,
		value = obj.val
	}
	
	if obj.eq then
		str.aps = obj.eq.aps and obj.eq.aps or ''
	elseif obj.trap then
		str.aps = obj.trap.aps and obj.trap.aps or ''
	end
	
	return frame:expandTemplate{title = 'Object infobox', args = str}
end

function p.createDrops(frame)
	local name = frame.args.name
	if name == nil or name == "" then name = mw.title.getCurrentTitle().subpageText end
	local obj = data[name]
	local str = ""
	
	str = str .. '\n{| class="table table-dark" style="width:auto"'
	str = str .. '\n! Item !! Chance<br>(per roll) !! Chance<br>(at least 1)'
	if obj.loot then
		if obj.loot.ches or obj.loot.ches2 then
			str = str .. '\n|- class=subheader'
			str = str .. '\n! colspan=3 | Boss chest '
			if obj.loot.ches then
				local name2 = id[obj.loot.ches]
				str = str .. '\n|- '
				str = str .. '\n| colspan=3 | ' .. frame:expandTemplate{title = 'Icon', args = {name2}}
			end
			if obj.loot.ches2 then
				local name2 = id[obj.loot.ches2]
				str = str .. '\n|- '
				str = str .. '\n| colspan=3 | ' .. frame:expandTemplate{title = 'Icon', args = {name2}}
			end
		end
		if obj.loot.ot then
			str = str .. '\n|- class=subheader'
			str = str .. '\n! colspan=3 | 1 roll'
			for k, v in ipairs(obj.loot.ot) do
				local name2 = id[v.id]
				str = str .. '\n|- '
				str = str .. '\n| ' .. p.singleIcon(name2, v.amt, frame)
				str = str .. '\n| colspan=2 | ' .. obj.loot.otch * 100 .. '%'
			end
		end
		if obj.loot.tbl then
			local lootTableObj = lootTable[obj.loot.tbl]
			if utils.length(lootTableObj.gLoot) > 0 then
				str = str .. '\n|- class=subheader'
				str = str .. '\n! colspan=3 | 1 roll'
				for k, v in ipairs(lootTableObj.gLoot) do
					local name2 = id[v.id]
					str = str .. '\n|- '
					str = str .. '\n| ' .. p.singleIcon(name2, v.amt, frame)
					str = str .. '\n| colspan=2 | ' .. v.ch
				end
			end
			local roll = lootTableObj.roll
			local s = 's'
			if utils.length(lootTableObj.gLoot) > 0 then
				if type(roll) == 'table' then
					roll = roll[1] - 1 .. '-' .. roll[2] - 1
				else
					roll = roll - 1
					if roll < 2 then s = ''	end
				end
			else
				if type(roll) == 'table' then
					roll = roll[1] .. '-' .. roll[2]
				else
					if roll < 2 then s = ''	end
				end
			end
			str = str .. '\n|- class=subheader'
			str = str .. '\n! colspan=3 | ' .. roll .. ' roll' .. s
			for k, v in ipairs(lootTableObj.loot) do
				local name2 = id[v.id]
				local icon = v.id == 0 and 'Nothing' or p.singleIcon(name2, v.amt, frame)
				str = str .. '\n|- '
				str = str .. '\n| ' .. icon
				str = str .. '\n| ' .. v.ch
				str = str .. '\n| ' .. v.chOne
			end
		end
		if obj.loot.sea then
			for k, v in ipairs(obj.loot.sea) do
				str = str .. '\n|- class=subheader'
				str = str .. '\n! colspan=3 | 1 roll (season ' .. v.sea .. ')'
				for k2, v2 in ipairs(v.loot) do
					local name2 = id[v2.id]
					str = str .. '\n|- '
					str = str .. '\n| ' .. p.singleIcon(name2, v2.amt, frame)
					str = str .. '\n| colspan=2 | ' .. v2.ch .. '%'
				end
			end
		end
	end
	str = str .. '\n|}'
		
	return str
end

function p.createAcquisition(frame)
	local name = frame.args.name
	if name == nil or name == "" then name = mw.title.getCurrentTitle().subpageText end
	local obj = data[name]
	local str = ""
	
	if obj.upol then
		local unpolishedName = id[obj.upol]
		local unpolishedObj = data[unpolishedName]
		local craft = unpolishedObj.acq.craf and unpolishedObj.acq.craf or unpolishedObj.acq.refi
		str = str .. '\n=== Craft ==='
		for k, v in ipairs(craft) do
			local name2 = id[craft[k]]
			local obj2 = data[name2]
			local result = utils.find(obj2.usg.craf.can, "id", unpolishedObj.id)
			str = str .. '\n{| class="table table-dark" style="width:auto"'
			str = str .. '\n| Crafting station'
			str = str .. '\n| ' .. (name2 ~= 'Player' and frame:expandTemplate{title = 'Icon', args = {name2}} or 'By hand')
			str = str .. '\n|-'
			str = str .. '\n| Result'
			str = str .. '\n| ' .. p.singleIcon(unpolishedName, result.amt, frame)
			str = str .. '\n|-'
			str = str .. '\n| Polished'
			str = str .. '\n| ' .. p.singleIcon(name, result.amt, frame)
			str = str .. '\n|-'
			str = str .. '\n| Materials'
			str = str .. '\n| ' .. p.icon(unpolishedObj.mat, "<br>", frame)
			str = str .. '\n|}'
		end
	end
	if obj.acq then
		if obj.acq.craf then
			local craft = obj.acq.craf and obj.acq.craf or obj.acq.refi
			str = str .. '\n=== Craft ==='
			for k, v in ipairs(craft) do
				local name2 = id[craft[k]]
				local obj2 = data[name2]
				local result = utils.find(obj2.usg.craf.can, "id", obj.id)
				str = str .. '\n{| class="table table-dark" style="width:auto"'
				str = str .. '\n| Crafting station'
				str = str .. '\n| ' .. (name2 ~= 'Player' and frame:expandTemplate{title = 'Icon', args = {name2}} or 'By hand')
				str = str .. '\n|-'
				str = str .. '\n| Result'
				str = str .. '\n| ' .. p.singleIcon(name, result.amt, frame)
				
				if obj.pol then
					local name3 = id[obj.pol]
					str = str .. '\n|-'
					str = str .. '\n| Polished'
					str = str .. '\n| ' .. p.singleIcon(name3, result.amt, frame)
				end
				
				str = str .. '\n|-'
				str = str .. '\n| Materials'
				str = str .. '\n| ' .. (obj.tag and obj.tag .. '<br>' or '') .. p.icon(obj.mat, '<br>', frame)
				str = str .. '\n|}'
			end
		end
		if obj.acq.refi then
			str = str .. '\n=== Refine ==='
			for k, v in ipairs(obj.acq.refi) do
				local name2 = id[obj.acq.refi[k]]
				local obj2 = data[name2]
				local result = utils.find(obj2.usg.craf.can, "id", obj.id)
				str = str .. '\n{| class="table table-dark" style="width:auto"'
				str = str .. '\n| Refiner'
				str = str .. '\n| ' .. frame:expandTemplate{title = 'Icon', args = {name2}}
				str = str .. '\n|-'
				str = str .. '\n| Result'
				str = str .. '\n| ' .. p.singleIcon(name, result.amt, frame)
				str = str .. '\n|-'
				str = str .. '\n| Materials'
				str = str .. '\n| ' .. (obj.tag and obj.tag .. '<br>' or '') .. p.icon(obj.mat, "<br>", frame)
				str = str .. '\n|}'
			end
		end
		if obj.acq.prod then
			str = str .. '\n=== Produce ==='
			for k, v in ipairs(obj.acq.prod) do
				local name2 = id[obj.acq.prod[k]]
				local obj2 = data[name2]
				local result = utils.find(obj2.usg.craf.can, "id", obj.id)
				str = str .. '\n{| class="table table-dark" style="width:auto"'
				str = str .. '\n| Cattle'
				str = str .. '\n| ' .. frame:expandTemplate{title = 'Icon', args = {name2}}
				str = str .. '\n|-'
				str = str .. '\n| Produce'
				str = str .. '\n| ' .. p.singleIcon(name, result.amt, frame)
				str = str .. '\n|}'
			end
		end
		if obj.acq.comb then
			str = str .. '\n=== Combine ==='
			for k, v in ipairs(obj.acq.comb) do
				local name2 = id[obj.acq.comb[k]]
				local obj2 = data[name2]
				local result = utils.find(obj2.usg.craf.can, "id", obj.id)
				if obj2.usg.craf.req > 0 then
					str = str .. '\nNote: Can only be combined near the ' .. id[obj2.usg.craf.req] .. '.'
				end
				str = str .. '\n{| class="table table-dark" style="width:auto"'
				str = str .. '\n| Casting item'
				str = str .. '\n| ' .. frame:expandTemplate{title = 'Icon', args = {name2}}
				str = str .. '\n|-'
				str = str .. '\n| Result'
				str = str .. '\n| ' .. p.singleIcon(name, result.amt, frame)
				str = str .. '\n|-'
				str = str .. '\n| Materials'
				str = str .. '\n| ' .. p.icon(obj.mat, "<br>", frame)
				str = str .. '\n|}'
			end
		end
		if obj.acq.fish then
			str = str .. '\n=== Fishing ==='
			str = str .. '\n{| class="table table-dark" style="width:auto"'
			str = str .. '\n! Water !! Location !! Type !! Amount !! Chance'
			for k, v in ipairs(obj.acq.fish) do
				local fish = constant.Acquisition.Fishing[v]
				local loot = utils.find(lootTable[v].loot, "id", obj.id)
				local amt = type(loot.amt) == 'table' and loot.amt[1] .. '-' .. loot.amt[2] or loot.amt
				str = str .. '\n|- '
				str = str .. '\n| ' .. fish.water
				str = str .. '\n| ' .. fish.location
				str = str .. '\n| ' .. fish.type
				str = str .. '\n| ' .. amt
				str = str .. '\n| ' .. loot.ch
			end
			str = str .. '\n|}'
		end
		if obj.acq.cont or obj.acq.contt then
			str = str .. '\n=== Container ==='
			str = str .. '\n{| class="table table-dark" style="width:auto"'
			str = str .. '\n! Item !! Amount !! Chance'
			if obj.acq.cont then
				for k, v in ipairs(obj.acq.cont) do
					local name2 = id[obj.acq.cont[k]]
					local obj2 = data[name2]
					local result = utils.find(obj2.usg.cont, "id", obj.id)
					local amt = type(result.amt) == 'table' and result.amt[1] .. '-' .. result.amt[2] or result.amt
					str = str .. '\n|- '
					str = str .. '\n| ' .. frame:expandTemplate{title = 'Icon', args = {name2}}
					str = str .. '\n| ' .. amt
					str = str .. '\n| ' .. result.ch .. '%'
				end
			end
			if obj.acq.contt then
				for k, v in ipairs(obj.acq.contt) do
					local name2 = id[obj.acq.contt[k]]
					local obj2 = data[name2]
					local loot = utils.find(lootTable[obj2.usg.contt].loot, "id", obj.id)
					local amt = type(loot.amt) == 'table' and loot.amt[1] .. '-' .. loot.amt[2] or loot.amt
					str = str .. '\n|- '
					str = str .. '\n| ' .. frame:expandTemplate{title = 'Icon', args = {name2}}
					str = str .. '\n| ' .. amt
					str = str .. '\n| ' .. loot.ch
				end
			end
			str = str .. '\n|}'
		end
		if obj.acq.shop then
			str = str .. '\n=== Shop ==='
			str = str .. '\n{| class="table table-dark" style="width:auto"'
			str = str .. '\n! Merchant !! Stock !! Price !! Requirement'
			for k, v in ipairs(obj.acq.shop) do
				local name2 = id[obj.acq.shop[k]]
				local obj2 = data[name2]
				local result = utils.find(obj2.shop, "id", obj.id)
				str = str .. '\n|- '
				str = str .. '\n| ' .. frame:expandTemplate{title = 'Icon', args = {name2}}
				str = str .. '\n| ' .. (result.amt > 0 and result.amt or 'No limit')
				str = str .. '\n| ' .. frame:expandTemplate{title = 'Ancient coin', args = {obj.buy}}
				str = str .. '\n| ' .. (result.req and result.req or 'None')
			end
			str = str .. '\n|}'
		end
		if obj.acq.dmg then
			str = str .. '\n=== Boulder ==='
			str = str .. '\nCan be mined with stationary drill from '
			for k, v in ipairs(obj.acq.dmg) do
				local name2 = id[obj.acq.dmg[k]]
				local obj2 = data[name2]
				str = str .. frame:expandTemplate{title = 'Icon', args = {name2}} .. ', '
			end
			str = str:sub(1, -3) .. '.'
		end
		-- if object.acquisition.inventory or object.acquisition.inventoryTable then
		if obj.acq.inv then
			str = str .. '\n=== Inventory ==='
			str = str .. '\n{| class="table table-dark" style="width:auto"'
			str = str .. '\n! Scene !! Container'
			if obj.acq.inv then
				for k, v in ipairs(obj.acq.inv) do
					local name2 = id[v.id]
					-- local object2 = data[name2]
					-- if object2.loot and object2.loot.inventory then
					-- 	local result = utils.find(object2.loot.inventory, "id", object.id)
					-- 	amount = type(result.amount) == 'table' and result.amount[1] .. '-' .. result.amount[2] or result.amount
					-- 	chance = result.chance .. '%'
					-- end
					str = str .. '\n|- '
					str = str .. '\n| ' .. v.scn
					str = str .. '\n| ' .. frame:expandTemplate{title = 'Icon', args = {name2}}
				end
			end
			-- if object.acquisition.inventoryTable then
			-- 	for k, v in ipairs(object.acquisition.inventoryTable) do
			-- 		local name2 = id[object.acquisition.inventoryTable[k]]
			-- 		local object2 = data[name2]
			-- 		local amount = '?'
			-- 		local chance = '?'
			-- 		if object2.loot and object2.loot.inventoryTable then
			-- 			local loot = utils.find(lootTable[object2.loot.inventoryTable].loot, "id", object.id)
			-- 			amount = type(loot.amount) == 'table' and loot.amount[1] .. '-' .. loot.amount[2] or loot.amount
			-- 			chance = loot.chance
			-- 		end
			-- 		str = str .. '\n|- '
			-- 		str = str .. '\n| ' .. frame:expandTemplate{title = 'Icon', args = {name2}}
			-- 		str = str .. '\n| ' .. amount
			-- 		str = str .. '\n| ' .. chance
			-- 	end
			-- end
			str = str .. '\n|}'
		end
		if obj.acq.lock then
			str = str .. '\n=== Locked chest ==='
			str = str .. '\n<div class="smallbox-b-grid">'
			for k, v in ipairs(obj.acq.lock) do
				local name2 = id[v]
				local obj2 = data[name2]
				str = str .. '<div><div class="smallbox-b-image ' .. obj2.rare .. '">[[File:' .. name2 .. '.png|link=' .. name2 .. '|' .. name2 .. ']]</div><div class="smallbox-b-text">[[' .. name2 .. ']]</div></div>'
			end
			str = str .. '</div>'
		end
		if obj.acq.arch == 1 then
			str = str .. '\n=== Archaeologist ==='
			str = str .. '\nCan be mined from any walls while having [[Archaeologist]] skill leveled. Higher level will increase chance of drop.'
		end
		if obj.acq.drop then
			str = str .. '\n=== Drop ==='
			str = str .. '\n{| class="table table-dark" style="width:auto"'
			str = str .. '\n! Object !! Type !! Amount !! Rolls !! Chance<br>(per roll) !! Chance<br>(at least 1)'
			for k, v in ipairs(obj.acq.drop) do
				local name2 = id[obj.acq.drop[k]]
				local obj2 = data[name2]
				if obj2 and obj2.loot then
					if obj2.loot.ches == obj.id or obj2.loot.ches2 == obj.id then
						str = str .. '\n|- '
						str = str .. '\n| ' .. frame:expandTemplate{title = 'Icon', args = {name2}}
						str = str .. '\n| Boss chest'
						str = str .. '\n| 1'
						str = str .. '\n| 1'
						str = str .. '\n| 100%'
						str = str .. '\n| 100%'
					end
					if obj2.loot.ot then
						local result = utils.find(obj2.loot.ot, "id", obj.id)
						if result then
							local amt = type(result.amt) == 'table' and result.amt[1] .. '-' .. result.amt[2] or result.amt
							str = str .. '\n|- '
							str = str .. '\n| ' .. frame:expandTemplate{title = 'Icon', args = {name2}}
							str = str .. '\n| Loot'
							str = str .. '\n| ' .. amt
							str = str .. '\n| 1'
							str = str .. '\n| ' .. obj2.loot.otch * 100 .. '%'
							str = str .. '\n| ' .. obj2.loot.otch * 100 .. '%'
						end
					end
					if obj2.loot.tbl then
						local lootTableObj = lootTable[obj2.loot.tbl]
						local loot = utils.find(lootTableObj.gLoot, "id", obj.id)
						if loot then
							local amt = type(loot.amt) == 'table' and loot.amt[1] .. '-' .. loot.amt[2] or loot.amt
							local ch = loot.ch
							str = str .. '\n|- '
							str = str .. '\n| ' .. frame:expandTemplate{title = 'Icon', args = {name2}}
							str = str .. '\n| Random loot - one guaranteed drop'
							str = str .. '\n| ' .. amt
							str = str .. '\n| 1'
							str = str .. '\n| ' .. ch
							str = str .. '\n| ' .. ch
						end
						loot = utils.find(lootTableObj.loot, "id", obj.id)
						if loot then
							local amt = type(loot.amt) == 'table' and loot.amt[1] .. '-' .. loot.amt[2] or loot.amt
							local roll = lootTableObj.roll
							if utils.length(lootTableObj.gLoot) > 0 then
								if type(roll) == 'table' then
									roll = roll[1] - 1 .. '-' .. roll[2] - 1
								else
									roll = roll - 1
								end
							else
								if type(roll) == 'table' then
									roll = roll[1] .. '-' .. roll[2]
								end
							end
							local ch = loot.ch
							local chOne = loot.chOne
							str = str .. '\n|- '
							str = str .. '\n| ' .. frame:expandTemplate{title = 'Icon', args = {name2}}
							str = str .. '\n| Random loot'
							str = str .. '\n| ' .. amt
							str = str .. '\n| ' .. roll
							str = str .. '\n| ' .. ch
							str = str .. '\n| ' .. chOne
						end
					end
					if obj2.loot.sea then
						for k2, v2 in ipairs(obj2.loot.sea) do
							local result = utils.find(v2.loot, "id", obj.id)
							if result then
								local amt = type(result.amt) == 'table' and result.amt[1] .. '-' .. result.amt[2] or result.amt
								local ch = result.ch .. "%"
								str = str .. '\n|- '
								str = str .. '\n| ' .. frame:expandTemplate{title = 'Icon', args = {name2}}
								str = str .. '\n| Seasonal loot - season ' .. v2.sea
								str = str .. '\n| ' .. amt
								str = str .. '\n| 1'
								str = str .. '\n| ' .. ch
								str = str .. '\n| ' .. ch
							end
						end
					end
				end
			end
			str = str .. '\n|}'
		end
		if obj.acq.batl then
			local battleArenaTable = lootTable[obj.acq.batl]
			local loot = utils.find(battleArenaTable.loot, "id", obj.id)
			local amt = type(loot.amt) == 'table' and loot.amt[1] .. '-' .. loot.amt[2] or loot.amt
			local roll = battleArenaTable.roll
			local ch = loot.ch
			local chOne = loot.chOne
			str = str .. '\n=== Ancient Battle Arena ==='
			str = str .. '\n{| class="table table-dark" style="width:auto"'
			str = str .. '\n! Type !! Amount !! Rolls !! Chance<br>(per roll) !! Chance<br>(at least 1)'
			str = str .. '\n|- '
			str = str .. '\n| Random loot'
			str = str .. '\n| ' .. amt
			str = str .. '\n| ' .. roll
			str = str .. '\n| ' .. ch
			str = str .. '\n| ' .. chOne
			str = str .. '\n|}'
		end
	end
	
	return str
end

function p.createUsage(frame)
	local name = frame.args.name
	if name == nil or name == "" then name = mw.title.getCurrentTitle().subpageText end
	local obj = data[name]
	local str = ""
	
	if obj.use then
		if obj.use ~= 'Combine the materials' and obj.use ~= 'Hatch egg' and obj.use ~= 'Open container' then
			str = str .. '\n=== Other ==='
			str = str .. '\n' .. obj.use
		end
	end
	if obj.usg then
		if obj.usg.craf then
			str = str .. '\n=== ' .. obj.usg.craf.type .. ' ==='
			str = str .. '\n{| class="table table-dark" style="width:auto"'
			str = str .. '\n! Result !! Materials'
			for k, v in ipairs(obj.usg.craf.can) do
				local name2 = id[v.id]
				local obj2 = data[name2]
				local materials = (obj2.tag and obj2.tag .. ' ' or '') .. p.icon(obj2.mat, " " , frame)
				str = str .. '\n|- '
				str = str .. '\n| ' .. p.singleIcon(name2, v.amt, frame)
				str = str .. '\n| ' .. materials
			end
			if utils.length(obj.usg.craf.inc) > 0 then
				str = str .. '\n|- '
				str = str .. '\n| colspan=2 | Also includes all crafting recipes from ' .. p.iconIdOnly(obj.usg.craf.inc , frame)
			end
			str = str .. '\n|}'
		end
		if obj.usg.cmat then
			str = str .. '\n=== Crafting material ==='
			str = str .. '\n{| class="table table-dark" style="width:auto"'
			str = str .. '\n! Crafting station !! Result !! Materials'
			for k, v in ipairs(obj.usg.cmat) do
				local name2 = id[v]
				local obj2 = data[name2]
				for k2, v2 in ipairs(obj2.usg.craf.can) do
					local name3 = id[v2.id]
					local obj3 = data[name3]
					local find = utils.find(obj3.mat, "id", obj.id)
					if find then
						str = str .. '\n|- '
						str = str .. '\n| ' .. frame:expandTemplate{title = 'Icon', args = {name2}}
						str = str .. '\n| ' .. p.singleIcon(name3, v2.amt, frame)
						str = str .. '\n| ' .. (obj3.tag and obj3.tag .. ' ' or '') .. p.icon(obj3.mat, " " , frame)
					end
				end
			end
			str = str .. '\n|}'
		end
		if obj.usg.refi then
			str = str .. '\n=== Refining material ==='
			str = str .. '\n{| class="table table-dark" style="width:auto"'
			str = str .. '\n! Refiner !! Result !! Materials'
			for k, v in ipairs(obj.usg.refi) do
				local name2 = id[v]
				local obj2 = data[name2]
				for k2, v2 in ipairs(obj2.usg.craf.can) do
					local name3 = id[v2.id]
					local obj3 = data[name3]
					local find = utils.find(obj3.mat, "id", obj.id)
					if find then
						str = str .. '\n|- '
						str = str .. '\n| ' .. frame:expandTemplate{title = 'Icon', args = {name2}}
						str = str .. '\n| ' .. p.singleIcon(name3, v2.amt, frame)
						str = str .. '\n| ' .. (obj3.tag and obj3.tag .. ' ' or '') .. p.icon(obj3.mat, " " , frame)
					end
				end
			end
			str = str .. '\n|}'
		end
		if obj.usg.comb then
			str = str .. '\n=== Combining material ==='
			str = str .. '\n{| class="table table-dark" style="width:auto"'
			str = str .. '\n! Combiner !! Result !! Materials'
			for k, v in ipairs(obj.usg.comb) do
				local name2 = id[v]
				local obj2 = data[name2]
				for k2, v2 in ipairs(obj2.usg.craf.can) do
					local name3 = id[v2.id]
					local obj3 = data[name3]
					local find = utils.find(obj3.mat, "id", obj.id)
					if find then
						str = str .. '\n|- '
						str = str .. '\n| ' .. frame:expandTemplate{title = 'Icon', args = {name2}}
						str = str .. '\n| ' .. p.singleIcon(name3, v2.amt, frame)
						str = str .. '\n| ' .. p.icon(obj3.mat, " " , frame)
					end
				end
			end
			str = str .. '\n|}'
		end
		if obj.usg.cont then
			str = str .. '\n=== ' .. obj.use .. ' ==='
			str = str .. '\n{| class="table table-dark" style="width:auto"'
			str = str .. '\n! Result !! Chance'
			for k, v in ipairs(obj.usg.cont) do
				local name2 = id[v.id]
				str = str .. '\n|- '
				str = str .. '\n| ' .. p.singleIcon(name2, v.amt, frame)
				str = str .. '\n| ' .. v.ch .. '%'
			end
			str = str .. '\n|}'
		end
		if obj.usg.contt then
			str = str .. '\n=== ' .. obj.use .. ' ==='
			str = str .. '\n{| class="table table-dark" style="width:auto"'
			str = str .. '\n! Item !! Chance<br>(per roll) !! Chance<br>(at least 1)'
			local lootTableObj = lootTable[obj.usg.contt]
			if utils.length(lootTableObj.gLoot) > 0 then
				str = str .. '\n|- class=subheader'
				str = str .. '\n! colspan=3 | 1 roll '
				for k, v in ipairs(lootTableObj.gLoot) do
					local name2 = id[v.id]
					str = str .. '\n|- '
					str = str .. '\n| ' .. p.singleIcon(name2, v.amt, frame)
					str = str .. '\n| colspan=2 | ' .. v.ch
				end
			end
			local roll = lootTableObj.roll
			local s = 's'
			if utils.length(lootTableObj.guaranteedLoot) > 0 then
				if type(roll) == 'table' then
					roll = roll[1] - 1 .. '-' .. roll[2] - 1
				else
					roll = roll - 1
					if roll < 2 then s = ''	end
				end
			else
				if type(roll) == 'table' then
					roll = roll[1] .. '-' .. roll[2]
				else
					if roll < 2 then s = ''	end
				end
			end
			str = str .. '\n|- class=subheader'
			str = str .. '\n! colspan=3 | ' .. roll .. ' roll' .. s
			for k, v in ipairs(lootTableObj.loot) do
				local name2 = id[v.id]
				str = str .. '\n|- '
				str = str .. '\n| ' .. p.singleIcon(name2, v.amt, frame)
				str = str .. '\n| ' .. v.ch
				str = str .. '\n| ' .. v.chOne
			end
			str = str .. '\n|}'
		end
		if obj.usg.upg then
			str = str .. '\n=== Upgrade material ==='
			str = str .. '\n{| class="table table-dark" style="width:auto"'
			str = str .. '\n! Level !! Materials'
			for k, v in ipairs(obj.usg.upg) do
				local upgrade = constant.UpgradeCost[v]
				str = str .. '\n|- '
				str = str .. '\n| ' .. v
				str = str .. '\n| ' .. p.icon(upgrade, " " , frame)
			end
			str = str .. '\n|}'
		end
	end
	if obj.cooked then
		str = str .. '\n=== Cooking ingredient ===\n'
		str = str .. p.createCookingEffect(obj)
	end
	
	return str
end

function p.createStats(frame)
	local name = frame.args.name
	if name == nil or name == "" then name = mw.title.getCurrentTitle().subpageText end
	local obj = data[name]
	
	if obj.pet then
		return p.createPetStats(obj)
	end
	
	local level = obj.lv
	local str = ''
	if obj.type == 'PlaceablePrefab' then
		str = str .. '{| class="table table-dark" style="width:auto"\n'
		str = str .. '|-\n'
		str = str .. '! Health\n'
		str = str .. '| ' .. obj.hp .. '\n'
		str = str .. '|-\n'
		str = str .. '! Mining damage reduction\n'
		str = str .. '| ' .. obj.dmgr .. '\n'
		str = str .. '|-\n'
		str = str .. '! Mining exp. gain threshold\n'
		str = str .. '| ' .. obj.dmgr + 12 .. '+ mining damage\n'
		-- local threshold = (object.health / 12) + object.damageReduction
		-- str = str .. '|-\n'
		-- str = str .. '! Threshold for sharp sound effect\n'
		-- str = str .. '| ' .. object.type .. '\n'
		str = str .. '|}'
		return str
	end
	str = str .. '<div class="row">\n'
	str = str .. '<div class="col-6"><div class="darkbox grid-pattern">\n'
	str = str .. '<div class="text-center mb-3 h5" style="font-family:Mitr">Base level ' .. level .. '</div>\n'
	str = str .. p.statsText(obj, level, frame) .. '\n'
	str = str .. '</div></div><div class="col-6"><div class="darkbox grid-pattern">\n'
	str = str .. '<div class="text-center mb-3 h5" style="font-family:Mitr">Max level ' .. constant.MaxLevel .. '</div>\n'
	str = str .. p.statsText(obj, constant.MaxLevel, frame) .. '\n'
	str = str .. '</div></div>'
	
	local max = ''
	if level < constant.MaxLevel then
		for k, v in ipairs(constant.MaxUpgradeCost[level]) do
			max = max .. frame:expandTemplate{title = 'Icon', args = {id[v.id], v.amt}} .. ' '
		end
	end
	str = str .. '<div class="col-12"><div class="darkbox mt-4">\n'
	str = str .. '<div class="text-center mb-3 h5" style="font-family:Mitr">Max upgrade cost</div>\n'
	str = str .. max
	str = str .. '</div></div></div>'
	
	return str
end

function p.statsText(obj, level, frame)
	local currentLevel = level and level or obj.lv
	local arrValue = currentLevel - obj.lv + 1
	local str = ''
	
	str = str .. (obj.eq and (obj.eq.mp and '<span style="color:rgb(53 164 183)">Mana cost: ' .. obj.eq.mp[arrValue] .. '</span><br>' or ''))
	local damage = utils.getDamage(obj, currentLevel)
	str = str .. (damage ~= '' and damage .. '<br>' or '')
	str = str .. (obj.eq.aps and obj.eq.aps .. ' attacks per second<hr>' or '')
	local effects = utils.getEffects(obj, currentLevel)
	str = str .. (effects ~= '' and effects .. '<hr>' or '')
	local setEffects = utils.getSetEffects(obj, frame)
	str = str .. (setEffects ~= '' and setEffects .. '<hr>' or '')
	str = str:sub(1, -5)
	
	return str
end

function p.createPetStats(obj)
	local str = ''
	str = str .. '<div class="row">\n'
	str = str .. '<div class="col-6"><div class="darkbox grid-pattern">\n'
	str = str .. '<div class="text-center mb-3 h5" style="font-family:Mitr">Base level 1</div>\n'
	str = str .. utils.getDamage(obj) .. '<hr>'
	str = str .. utils.getEffects(obj)
	str = str .. '</div></div><div class="col-6"><div class="darkbox grid-pattern">\n'
	str = str .. '<div class="text-center mb-3 h5" style="font-family:Mitr">Max level 10</div>\n'
	str = str .. utils.getDamage(obj, constant.PetMaxLevel) .. '<hr>'
	str = str .. utils.getEffects(obj)
	str = str .. '</div></div></div>'
	return str
end

function p.createCookingEffect(obj)
	local str = ''
	str = str .. '<div class="row">\n'
	str = str .. '<div class="col-12 col-md-4"><div class="darkbox checkerboard-pattern">\n'
	str = str .. '<div class="text-center mb-3 h5" style="font-family:Mitr">Regular</div>\n'
	str = str .. utils.concat(obj.cooked.reg, '<br>') .. '\n'
	str = str .. '</div></div><div class="col-12 col-md-4 mt-3 mt-md-0"><div class="darkbox checkerboard-pattern">\n'
	str = str .. '<div class="text-center mb-3 h5" style="font-family:Mitr">Rare</div>\n'
	str = str .. utils.concat(obj.cooked.rare, '<br>') .. '\n'
	str = str .. '</div></div><div class="col-12 col-md-4 mt-3 mt-md-0"><div class="darkbox checkerboard-pattern">\n'
	str = str .. '<div class="text-center mb-3 h5" style="font-family:Mitr">Epic</div>\n'
	str = str .. utils.concat(obj.cooked.epic, '<br>') .. '\n'
	str = str .. '</div></div></div>'
	
	return str
end

function p.createShop(frame)
	local name = frame.args.name
	if name == nil or name == "" then name = mw.title.getCurrentTitle().subpageText end
	local obj = data[name]
	local str = ''
	
	if obj.shop then
		str = str .. '{| class="table table-dark sortable" style="width:auto"'
		str = str .. '\n! Icon !! Name !! Stock !! Price !! Requirement'
		for k, v in ipairs(obj.shop) do
			local name = id[v.id]
			local item = data[name]
			str = str .. '\n|-'
			str = str .. '\n| align=center | [[File:' .. name .. '.png|link=' .. name .. '|' .. name .. ']]'
			str = str .. '\n| [[' .. name .. ']]'
			str = str .. '\n| ' .. (v.amt > 0 and v.amt or 'No limit')
			str = str .. '\n| ' .. frame:expandTemplate{title = 'Ancient coin', args = {item.buy}}
			str = str .. '\n| ' .. v.req
		end
		str = str .. '\n|}'
	end
	
	return str
end

function p.createPetSkills(frame)
	local name = frame.args.name
	if name == nil or name == "" then name = mw.title.getCurrentTitle().subpageText end
	local obj = data[name]
	local str = ''
	
	if obj.pet then
		local pets = mw.loadJsonData("Module:Pets.json")
		local type = 't' .. obj.pet.type
		
		str = str .. '{| class="table table-dark sortable" style="width:auto"\n'
		str = str .. '! Icon !! Name !! Effects\n'
		for k, v in ipairs(obj.pet.skil) do
			local petSkill = pets['i' .. v][type]
			local iconName = petSkill.name
			if type == 't0' then
				iconName = petSkill.name .. ' (melee)'
			elseif type == 't1' then
				iconName = petSkill.name .. ' (range)'
			end
			str = str .. '|-\n'
			str = str .. '| align=center | [[File:' .. iconName .. '.png|' .. petSkill.name .. ']]\n'
			str = str .. '| ' .. petSkill.name .. '\n'
			str = str .. '| ' .. (type == 't2' and 'Buffs owner with: ' or '') .. utils.getCondition(petSkill.id, petSkill.val) .. '\n'
		end
		str = str .. '|}'
	end
	
	return str
end

function p.createNavbox(frame)
	local name = frame.args.name
	if name == nil or name == "" then name = mw.title.getCurrentTitle().subpageText end
	local navbox = ''
	
	local category = utils.getCategory(name)
	if category then
		if category[1] == 'Boss' then
			navbox = 'character'
		elseif category[1] == 'Creature' then
			navbox = 'character'
		elseif category[1] == 'Weapon' then
			navbox = 'weapon'
		elseif category[1] == 'Tool' then
			navbox = 'tools'
		elseif category[1] == 'Equipment' then
			if category[2] == 'Helm' or category[2] == 'Breast armor' or category[2] == 'Pants armor' then
				navbox = 'armor'
			else
				navbox = 'accessory'
			end
		elseif category[1] == 'Building' then
			navbox = 'building'
		elseif category[1] == 'Consumable' then
			navbox = 'consumable'
		elseif category[1] == 'Environment' then
			navbox = 'environment'
		elseif category[1] == 'Material' then
			navbox = 'material'
		elseif category[1] == 'Music' then
			navbox = 'music'
		elseif category[1] == 'Other' then
			navbox = 'material'
		elseif category[1] == 'Seasonal' then
			navbox = 'seasonal'
		elseif category[1] == 'Technology' then
			navbox = 'technology'
		elseif category[1] == 'Valuables' then
			navbox = 'valuable'
		end
		
		return frame:expandTemplate{title = 'Navbox ' .. navbox}
	end
end

function p.singleIcon(name, amt, frame)
	if type(amt) == 'table' then
		amt = amt[1] .. '-' .. amt[2]
	else
		amt = amt > 1 and amt or ""
	end
	
	return frame:expandTemplate{title = 'Icon', args = {name, amt}}
end

function p.icon(t, separator, frame)
	local str = ""
	separator = separator and separator or " "
	local length = -1 - #separator
	
	if t ~= nil then
		for k, v in ipairs(t) do
			local name = id[v.id]
			local amt = v.amt
			if type(amt) == 'table' then
				amt = amt[1] .. '-' .. amt[2]
			else
				amt = amt > 1 and amt or ""
			end
			str = str .. frame:expandTemplate{title = 'Icon', args = {name, amt}} .. separator
		end
		str = str:sub(1, length)
	end
	
	return str
end

function p.iconIdOnly(t, frame)
	local str = ""
	
	if t ~= nil then
		for k, v in ipairs(t) do
			local name = id[v]
			str = str .. frame:expandTemplate{title = 'Icon', args = {name}} .. ' '
		end
		str = str:sub(1, -2)
	end
	
	return str
end

return p