Module:Page/Item

From The Alchemist Code Wiki
Jump to: navigation, search

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

local render_item_icon   = require('Module:Render/Item')._icon
local render_recipe_table = require('Module:Render/Recipe')._table
local model = require('Module:Data').model
local enums = require('Module:Data/Enums')

local skillTypes = {
	['0'] = "Attack",
	['1'] = "Skill",
	['2'] = "Passive",
	['3'] = "Item",
	['4'] = "Reaction",
}


local p = {}

local types = {
	[0] = 'Consumable',
	[1] = 'Soul Shard',
	[2] = 'Diagram',
	[3] = 'Equipment',
	[4] = 'Material',
	[6] = 'Apple',
	[8] = 'Alchemia Pot',
	[9] = 'Ingot',
	[10] = 'Ticket',
	[11] = 'Equipment Piece',
	[12] = 'Other', -- Shop Item?  Bundles, Skins, Coins',
	[13] = 'Ore',
	[14] = 'Gear Shard',
	[17] = 'Event Currency',
	[18] = 'Selector',
	[20] = 'AP Gain',
	[21] = 'Memento Selector',
	[22] = 'Guild EXP',
	[23] = 'Discount Ticket',
}

local function getSkill(iname)
	if iname == nil then return end
	return model.query('Skill', '_pageName, aag,ab_rp_chg_ids,ab_rp_tgt_ids,abs_d_rate,ac_fr_ab_id,ac_is_reset,ac_is_self,ac_to_ab_id,ac_turn,ad_react,atk_det,atk_type,bdb,bo_id,cap,chran,ci_cc_id,combo_num,combo_rate,cond,cost,count,cs_height,cs_voice,cs_vp_df,ct_calc,ct_rate_ini,ct_rate_max,ct_spd_ini,ct_spd_max,ct_type,ct_val_ini,ct_val_max,ctbreak,ctrl_d_calc,ctrl_d_ini,ctrl_d_max,ctrl_d_rate_ini,ctrl_d_rate_max,cutin,dmg_atk,dmg_dt,dmg_formula,dsse_id,dtu_id,dupli,eff_calc,eff_durate,eff_h,eff_hprate,eff_htnrate,eff_lvrate,eff_mprate,eff_range_ini,eff_range_max,eff_rate_ini,eff_rate_max,eff_type,eff_val_ini,eff_val_max,effdef,effnm,ehpa,elem,elem_ini,elem_max,elem_tk,f_ulock,fhit,hbonus,hp_cost,hp_cost_rate,idr,ig_elem,iname,is_cri,is_fixed,is_htndiv,is_mhm_dmg,is_no_ccc,is_ob_react,is_pre_apply,isbtl,jdabs,jdtype,jdv,jhp_calc,jhp_over,jhp_val,jmp_tk,jmpbreak,job,kb_dir,kb_ds,kb_rate,kb_val,line,max_dmg,motnm,mpatk,pierce,rangemax,rangemin,rate,react_d_type,react_dets,rhit,rp_chg_ids,rp_tgt_ids,s_buff,s_cond,scn,scn_bu,scope,sdb,shield_d_type,shield_ini,shield_max,shield_reset,shield_turn_ini,shield_turn_max,shield_type,sm_id,sonoba,sran,ssco,sub_actuate,suicide,t_buff,t_cond,target,target_ex,timing,tkrate,tktag,tl_height,tl_is_mov,tl_target,tl_type,tr_id,tr_set,tsk_pos,type,utgt,wth_id,wth_rate', {where = 'iname = "'..iname..'" AND server = "gl"'})[1]
end

local function getBuff(iname)
	if iname == nil then return end
	return model.query('Buff', '_pageName, app_mct,app_type,birth,calc1,calc10,calc11,calc2,calc3,calc4,calc5,calc6,calc7,calc8,calc9,chktgt,cond,custom_targets,eff_range,elem,iname,is_no_bt,is_no_dis,is_up_rep,job,rate,sex,tag,timing,tktag1,tktag10,tktag11,tktag2,tktag3,tktag4,tktag5,tktag6,tktag7,tktag8,tktag9,turn,type1,type10,type11,type2,type3,type4,type5,type6,type7,type8,type9,un_group,up_timing,vini1,vini10,vini11,vini2,vini3,vini4,vini5,vini6,vini7,vini8,vini9,vmax1,vmax10,vmax11,vmax2,vmax3,vmax4,vmax5,vmax6,vmax7,vmax8,vmax9,vone1,vone11,vone2,vone3,vone4,vone5,vone6,vone7,vone8', {where = 'iname = "'..iname..'" AND server = "gl"'})[1]
end

local renderSkill = function(root, iname)
	if iname == nil then return end
	local skill = getSkill(iname)
	if not skill then return end

	local t_buff = getBuff(skill.t_buff)
	if not t_buff then return end

	-- Render
	local headings = {
		['0'] = 'Attack Stats',
		['1'] = 'Skill Stats',
		['2'] = 'Passive Stats',
		['3'] = 'Equipment Stats',
		['4'] = 'Reaction Stats',
	}
	root:tag('h2'):wikitext(headings[tostring(skill.type)])
	local tbl = root:tag('table'):addClass('wikitable')
	local tr = tbl:tag('tr')
	tr:tag('th'):wikitext('Type')
	tr:tag('th'):wikitext('Min')
	tr:tag('th'):wikitext('Max')

	for i=1,11 do
		local tp = tonumber(t_buff['type'..i]) or 0
		local ini = tonumber(t_buff['vini'..i]) or 0
		local max = tonumber(t_buff['vmax'..i]) or 0
		if tp > 0 then
			local tr = tbl:tag('tr')
			tr:tag('td'):wikitext(enums.statNameFromType(tp))
			tr:tag('td'):wikitext(string.format('%+d', ini))
			tr:tag('td'):wikitext(string.format('%+d', max))
		end
	end
end

local renderEventRewardList = function(root, iname)
	if iname == nil then return end
	
	local cargo_query = mw.ext.cargo.query
	local sourceList = cargo_query('EventReward', '_pageName,source', {where = 'iname="'..iname..'"'}) or {}
	
	if #sourceList < 1 then return end
	
	root:tag('h2'):wikitext('Event Reward Sources')
	
	local ul = root:tag('ul')
	
	for ignore, sourceItem in ipairs(sourceList) do
	    ul:tag('li'):wikitext('[['..sourceItem['_pageName']..']] ('..(sourceItem['source'])..')')
	end
end

local renderPage = function(iname, args)
	local data = model.query('Item','_pageName,server,ac,buy,cap,cmn_type,coin,encost,enpt,eqlv,icon,iname,invcap,is_valuables,mc,pp,quests,rare,recipe,sell,skill,tc,type,val',{where='iname="'..iname..'"'})
	data = data[1]
	local getLoc = function(param) return model.getLoc(data._pageName, param) end
	local name = getLoc('name')
	local rank = (data.rare or 0) + 1
	local tp = data.type and (types[data.type] or '??? ('..data.type..')') or '??? (Undefined type)'
	local expr = getLoc('expr')

	local INF = 9999999
	local buy = tonumber(data.buy) or 0
	local sell = tonumber(data.sell) or 0
	local arena_coin = tonumber(data.ac) or 0
	local tour_coin = tonumber(data.tc) or 0
	local multi_coin = tonumber(data.mc) or 0
	local soul_coin = tonumber(data.pp) or 0
	local gem = tonumber(data.coin) or 0
	local enhancer_cost = tonumber(data.encost) or 0
	local enhancer_pt = tonumber(data.enpt) or 0

	
	local root = mw.html.create()
	-- Info Box
	local function printRow(t, label, content)
		if content == nil then return end
		local tr = t:tag('tr')
		tr:tag('th'):wikitext(label)
		tr:tag('td'):wikitext(content)
	end
	local infobox = root:tag('table'):addClass('wikitable unit ibox'):cssText('float:right; margin-left: 15px;margin-bottom:0; width: 482px')
	infobox:tag('tr')
		:tag('td')
			:cssText('padding:0;width:128px;white-space: nowrap')
			:wikitext(render_item_icon({iname, data=data, size='large', name='none', link='none'}))
			:done()
		:tag('th')
			:cssText('padding:12px;font-size:140%;')
			:wikitext(name)
			:tag('p')
				:cssText('font-size:65%')
				:wikitext(rank .. '★‎ ' .. tp)
				:done()
			:tag('p')
				:cssText('font-size:65%')
				:wikitext('[http://www.alchemistcodedb.com/item/' .. string.lower(string.gsub(iname, '_', '-')) .. ' See on Alchemist Code Database]')
				:done()
			:done()
	if expr then
		infobox:tag('tr'):tag('td'):attr('colspan', 2):cssText('text-align:center'):wikitext(expr)
	end
	--[=[
{{#if: {{:Data:Item/Jobs|{{{1|}}}}}
| &#32;
{{!}}-
! colspan="2" {{!}} Used By
{{!}}-
{{!}} colspan="2" style="padding:0" {{!}}{{Item/Section/Jobs|{{{1|}}}}}
}}
	]=]--

	local labels = {
		[6] = 'Unit EXP', -- Apple
		-- [8] = '???', -- Alchemia Pot', -- seems to all be val == enpt. ACDB doesn't show this..?
		[12] = 'Player EXP', -- Clover
		[13] = 'Gear EXP', -- 
		[20] = 'AP Healed', -- Alchemy Drops & Alchemy Droplets.
	}
	printRow(infobox, labels[data.type], tonumber(data.val) and labels[data.type] and data.val or nil)
	printRow(infobox, 'Enhancer Pts', 0 < enhancer_pt and enhancer_pt or nil)
	-- if tonumber(data.encost) then -- It seems like there's some kind of multiplier involved...?
	-- 	printRow(infobox, 'Enhancer Cost', data.encost)
	-- end
	printRow(infobox, 'Zeni Cost', (0 < buy and buy < INF) and buy or nil)
	printRow(infobox, 'Zeni Sales Price', 0 < sell and sell < INF and sell or nil)
	printRow(infobox, 'Arena Coins', 0 < arena_coin and arena_coin < INF and arena_coin or nil)
	printRow(infobox, 'Tour Coins', 0 < tour_coin and tour_coin < INF and tour_coin or nil)
	printRow(infobox, 'Multi Coins', 0 < multi_coin and multi_coin < INF and multi_coin or nil)
	printRow(infobox, 'Soul Coins', 0 < soul_coin and soul_coin < INF and soul_coin or nil)
	printRow(infobox, 'Gems', 0 < gem and gem < INF and gem or nil)

    -- Handle piece links to created items
    if iname:sub(1, 6) == 'IT_AF_' then
        local createdItemData = model.query('Artifact','_pageName,server,rini,icon,iname',{where='kakera="'..iname..'"'})[1] or nil
        if createdItemData and createdItemData ~= nil then
            local render_gear_icon = require('Module:Render/Gear')._icon
            printRow(infobox, 'Gear', render_gear_icon({createdItemData.iname, data=createdItemData, size='small'}))
        end
    elseif iname:sub(1, 6) == 'IT_PI_' then
        local createdItemData = model.query('Unit','_pageName,server,rare,img,iname',{where='piece="'..iname..'"'})[1] or nil
        if createdItemData and createdItemData ~= nil then
            local render_unit_icon = require('Module:Render/Unit')._icon
            printRow(infobox, 'Unit', render_unit_icon({createdItemData.iname, data=createdItemData, size='small'}))
        end
    end
    
	-- Body
	root:tag('p'):wikitext(getLoc('flavor'))
	
	if data.recipe ~= nil and data.recipe ~= '' then
		root:tag('h2'):wikitext('Recipe')
		root:wikitext(render_recipe_table({data.recipe}))
	end
	
	local usedIn = model.query('Recipe', 'iname', {where='server="'..data.server..'" and mats__FULL REGEXP "([|]|^)'..iname..'([|]|$)"'})
	if #usedIn > 0 then
		root:tag('h2'):wikitext('Included in Recipes')
		for i, recipe in ipairs(usedIn) do
			for j, item in ipairs(model.query('Item', 'iname', {where= 'server="'..data.server..'" and recipe="'..recipe.iname..'"'})) do
				root:wikitext(render_item_icon({item.iname}))
			end
		end
	end

	-- Skill
	renderSkill(root, data.skill)

	-- Event Reward Sources
	renderEventRewardList(root, iname)
    
	-- Category
	local cats = {'Items'}
	if iname:find('^IT_EQ_') then
		cats[#cats+1] = 'Equipment'
		if iname:find('^IT_EQ_DIAGRAM_') then
			cats[#cats+1] = 'Equipment Diagram'
		elseif iname:find('^IT_EQ_DIAGRAMPIECE_') then
			cats[#cats+1] = 'Equipment Diagram Piece'
		elseif iname:find('^IT_EQ_PIECE_') then
			cats[#cats+1] = 'Equipment Piece'
		end
	end
	for i, cat in ipairs(cats) do
		root:wikitext('[[Category:'..cat..']]')
	end
	return tostring(root)
end

local renderFuncs = {}
renderFuncs.Icon = render_item_icon
renderFuncs.IconSmall = function(args)
	args.size = 'small'
	return render_item_icon(args)
end

p.renderPage = renderPage

local renderTransclude = function(iname, args)
	local type = mw.text.trim(args[1])
	mw.log('Module:Page/Item.renderTransclude: type =', type)
	args[1] = iname
	return (renderFuncs[type] or renderFuncs.Name)(args)
end

function p._main(iname, args) 
	if args.isPage then
		return p.renderPage(iname)
	else
		return renderTransclude(iname, args)
	end
end

return p