Module:Sandbox/User:Elessar2/DisDataDump

Documentation for this module may be created at Module:Sandbox/User:Elessar2/DisDataDump/doc

--<nowiki>
local p = {}

local getDisData = require('Module:Disassembly material calculator')._getData
local yesno = require('Module:Yesno')
local dumpObj = require('Module:Logger').dumpObject


local geprices = mw.loadData('Module:GEPrices/data')
local info = mw.loadData('Module:Disassembly category calculator/data')
local matlist = mw.loadData('Module:Disassemble/mats')
local disdata = mw.loadData('Module:Component costs/itemdata')
local catdata = mw.loadData('Module:Disassemble/data')

local limitFilteredMaterials = {
	['Simple parts'] = true,
	['Organic parts'] = true,
	['Enhancing components'] = true,
	['Variable components'] = true
}


-- gecheck for potions
local function gep(item)
	item = info.gemwnames[item] or info.names[item] or item
	local price = geprices[item]
	if price then
		return price
	end
	return 0
end
-- special case: potions
-- cqty does not vary, it might actually idk
local function potions(data)
	local doses = {}
	
	local mdose = 2
	if gep( data['%PAGE%']..' (6)' ) > 0 then
		mdose = 6
	elseif gep( data['%PAGE%']..' (4)' ) > 0 then
		mdose = 4
	elseif data.calccomp then
		local cc = tonumber(data.calccomp)
		if cc and cc > 2 then
			mdose = cc
		end
	end
	
	for i = mdose, 1, -1 do
		local dosedata = {
			['%PAGE%'] = data['%PAGE%'],
			name = string.format('%s (%s)', data.name, i),
			subobj = string.format('(%s)', i),
			augmented = data.augmented,
			calcvalue = data.calcvalue,
			level = data.level,
			category = i..' dose'
		}
		
		if data.special and type(data.special) == 'table' then
			local spec = {}
			for j,k in pairs(data.special) do
				spec[j] = { k[1], k[2] }
			end
			dosedata.special = spec
		end
		
		table.insert(doses, dosedata)
	end
	
	return doses
end

local function getSMW(mat)
	local q = {
		'[[Category:Items with an alternate value]]',
		'[[Category:Items that disassemble into '..mat..']]',
		'?#-',
		'?Calculated value#-',
		'limit=500'
	}
	local res = mw.smw.ask(q) or {}
	--mw.logObject(res)

	local qsub = {
		'[[Calculated value::+]]',
		'[[-Has subobject::+]]',
		'?#-',
		'?Item name#-',
		'?Calculated value#-',
		'limit=500'
	}
	local subsmw = mw.smw.ask(qsub) or {}
	
	for _,v in ipairs(subsmw) do
		table.insert(res, {v['Item name'], ['Calculated value'] = v['Calculated value']})
	end
	--mw.logObject(res)
	
	return res
end

local function getData(mat)
	local calcvals, potcalcvals, runsmw = {}, {}, false
	local count, ret = getDisData(mat)
	
	local pots, potkey, potcnt = {}, {}, 0
	for i,v in ipairs(ret) do
		-- set name
		ret[i].name = v['%PAGE%']
		
		-- get needs unparsed calcvalue from smw
		if v.calcvalue then
			calcvals[v['%PAGE%']] = i
			runsmw = true
		end
		
		-- fix potion categories
		local cat = catdata[string.lower(v.category)] or {}
		local pot = v.potion or cat.potion or false
		pot = string.lower(tostring(pot))
		if yesno(pot) then
			local vpots = potions(v)
			table.insert(potkey, i)
			pots[i] = {}
			for j,k in ipairs( vpots ) do
				pots[i][j] = k
				potcnt = potcnt + 1
				if v.calcvalue then
					local item = v['%PAGE%']..' '..k.subobj
					potcalcvals[item] = {i, j}
				end
			end
		end
	end
	
	-- if calcvalues smw-ask them all, then set the values
	if runsmw then
		-- run smw
		local smwres = getSMW(mat)
		
		-- loop table to check results
		for _,v in pairs(smwres) do
			if calcvals[ v[1] ] then
				ret[ calcvals[ v[1] ] ].calcvalue = v['Calculated value']
			elseif potcalcvals[ v[1] ] then
				local pos = potcalcvals[ v[1] ]
				pots[ pos[1] ][ pos[2] ].calcvalue = v['Calculated value']
			end
		end
	end
	
	-- add potions back into to list
	local add = 0
	for _,v in ipairs(potkey) do
		local pos = v + add
		for j,k in ipairs(pots[v]) do
			if j == 1 then
				ret[v + add] = k
				potcnt = potcnt - 1
			else
				table.insert(ret, pos, k)
				add = add + 1
			end
		end
	end
	count = count + potcnt
	
	return count, ret
end

-- get the material name from a passed in string m
-- returns material name,true if successful
-- returns m (or the empty string), false if material not found
local function get_mat(m)
	local str = mw.text.trim(string.gsub(string.gsub(string.lower(m), ' parts?', ''), ' components?', ''))
 
	if matlist[str] then
		return matlist[str], true
	else
		return (m or ''), false
	end
end
local pagemat

function parseSpec(spec, retobj)
	local _special = mw.text.split(spec, '%s*,%s*')
	local numsp = 1
	local chsp = nil
	local specmatcount = table.maxn(_special)
	local specstr,specobj = '', {}
	for i,v in ipairs(_special) do
		v = string.lower(v)
			:gsub(' ?components?','')
			:gsub(' ?parts?','')
		local _m,_q,_c = v:match('([%w -]+)%s*%[?(%d*)%]?%s*%{?(%d*%.?%d*/?%d*%.?%d*)%}?')
		local _name, matb = get_mat(_m)
		local _quant = tonumber(_q) or 1
		
		local _chance
		if type(_c) == 'string' and _c ~= '' then
			if _c:find('/') then
				_c = mw.text.split(_c,'/')
				if tonumber(_c[1]) and tonumber(_c[2]) then
				_chance = tonumber(_c[1]) / tonumber(_c[2])
				end
			else
				_c = tonumber(_c)
				if math.floor(100/_c) == 100/_c then
					_chance = _c / 100
					-- _chance = { 1, 100/_c }
				else
					_chance = _c / 100
				end
			end
		elseif _name and _quant then
			_chance = 1
		end
		
		_name = mw.text.trim(_name)
		if v:find('%S') and matb and _chance then
			specobj[_name] = {_chance, _quant}
			specstr = specstr..string.format("\n\t\t\t['%s'] = { %s, %s },", _name, _chance, _quant )
		end
	end
	
	if specstr ~= '' then
		specstr = ',\n\t\tspecs = {'..specstr..'\n\t\t}'
		
		if retobj then
			return specobj
		end
	end
	return specstr
end

function genCode(data)
	local other = ''
	if  yesno(data.augmented) then
		other = other..',\n\t\tisaugmented = true'
	end
	if data.calcvalue then
		other = other..string.format(",\n\t\tprice = '%s'", data.calcvalue)
	end
	if data.special then
		other = other..parseSpec(data.special)
	end
	local str = "\t['%s'] = {\n\t\tlevel = %s,\n\t\tcategory = '%s'%s\n\t},"
	return string.format(str, data.name, data.level, string.lower(data.category), other)
end

function genDiff(ret, data)
	local itemdata = disdata[data.name]
	
	if itemdata then
		local diffs = {}
		
		local itaug = not not itemdata.isaugmented
		local pgaug = yesno(data.augmented)
		if not itaug == pgaug then
			table.insert(diffs, {'Augmented?', data.augmented, itemdata.isaugmented})
		end
		local pgspec
		if data.special then
			pgspec = parseSpec(data.special, true)
		end
		local pgspecstr = dumpObj(pgspec, {clean=true})
		local itspecstr = dumpObj(itemdata.specs, {clean=true})
		if pgspecstr ~= itspecstr then
			table.insert(diffs, {'Special mats', pgspecstr, itspecstr})
		end
		if data.calcvalue ~= itemdata.price then
			table.insert(diffs, {'Price', data.calcvalue, itemdata.price})
		end
		if tonumber(data.level) ~= itemdata.level then
			table.insert(diffs, {'Level', data.level, itemdata.level})
		end
		if string.lower(data.category) ~= itemdata.category then
			table.insert(diffs, {'Category', string.lower(data.category), itemdata.category})
		end
		
		if #diffs > 0 then
			local dt = mw.html.create('table')
			dt	:addClass('wikitable')
				:tag('tr')
					:tag('th'):wikitext('Param'):done()
					:tag('th'):wikitext('Dis Temp'):done()
					:tag('th'):wikitext('Module'):done()
			
			for _,v in ipairs(diffs) do
				dt	:tag('tr')
						:tag('td'):wikitext(v[1]):done()
						:tag('td')
							:wikitext('\n')
							:tag('pre'):wikitext( v[2] ):done()
							:wikitext('\n')
							:done()
						:tag('td')
							:wikitext('\n')
							:tag('pre'):wikitext( v[3] ):done()
							:wikitext('\n')
							:done()
			end
			
			ret	:tag('tr')
					:tag('td'):wikitext( string.format('[[%s|%s]]', data['%PAGE%'], data.name) ):done()
					:tag('td'):node(dt):done()
					:tag('td')
						:wikitext('\n')
						:tag('pre'):wikitext( genCode(data) ):done()
						:wikitext('\n')
						:done()
		end
	end
end

function p.main(frame)
	local args = frame:getParent().args
	local mat = args[1]
	if not mat then error('No material provided') end
	
	if args[2] then
		return p._main(mat, true)
	end
	
	return p._main(mat, false)
end

function p._main(mat, diff)
	if mat == 'diff' then
		return p._diff()
	end
	
	local count,disdata = getData(mat)
	
	local ret = mw.html.create('table')
	ret:addClass('wikitable sticky-header sortable')
	
	if diff then
		ret	:tag('tr')
				:tag('th'):wikitext('Item'):done()
				:tag('th'):wikitext('Diff'):done()
				:tag('th'):wikitext('Module code'):done()
		for _,v in ipairs(disdata) do
			genDiff(ret, v)
		end
	else
		ret	:tag('tr')
				:tag('th'):wikitext('Item'):done()
				:tag('th'):wikitext('Module code'):done()
		for _,v in ipairs(disdata) do
			ret	:tag('tr')
					:tag('td'):wikitext( string.format('[[%s|%s]]', v['%PAGE%'], v.name) ):done()
					:tag('td')
						:wikitext('\n')
						:tag('pre'):wikitext( genCode(v) ):done()
						:wikitext('\n')
						:done()
		end
	end
		
	return ret
end

function p._diff()
	local ret = mw.html.create('table')
	ret	:addClass('wikitable sticky-header sortable')
	ret	:tag('tr')
		:tag('th'):wikitext('Item'):done()
		:tag('th'):wikitext('Diff'):done()
		:tag('th'):wikitext('Module code'):done()
	
	for _,v in pairs(matlist) do
		local count,disdata = getData(v)
		for _,k in ipairs(disdata) do
			genDiff(ret, k)
		end
	end
	
	return ret
end

return p