Animal Crossing: Pocket Camp Wiki
(WHEW)
 
m (we already made a sort key in SQL, use that.)
Line 83: Line 83:
 
name = row['C_Name'],
 
name = row['C_Name'],
 
class = row['C_Class'],
 
class = row['C_Class'],
−
sortKey = string.sub('0'..row['C_Class'], -4),
+
sortKey = row['ClassCourseSortKey'],
 
numFurnReq = row['C_NumFurnReq'],
 
numFurnReq = row['C_NumFurnReq'],
 
furnitures = {},
 
furnitures = {},

Revision as of 06:25, 13 February 2021

Documentation for this module may be created at Module:Happy Homeroom Normal Courses Table/doc

-- TODO: Use a module!
local cargo = {}
function cargo.query(args)
	for k, v in ipairs({'tables', 'fields', 'join'}) do
		if type(args[v]) == 'table' then
			args[v] = table.concat(args[v], ',')
		end
	end
	if type(args.where) == 'table' then
		local t = {}
		for i, v in pairs(args.where) do
			t[#t+1] = '('..v..')'
		end
		args.where = table.concat(t, ' AND ')
	end
	args.limit = args.limit or 5000
	local rows = mw.ext.cargo.query(
		args.tables,
		args.fields,
		args
	)
	for i, row in ipairs(rows) do
		for k, v in pairs(row) do
			if v == '' then
				row[k] = nil
			end
		end
	end
	return rows
end

local p = {}
local h = {}

local LANG =  mw.getContentLanguage()

function p.main(frame)
	local rows = cargo.query{
		tables = {
			'Class=C','Class__FurnReqAll=CFRA','Entities=E',
			'Furniture=F1',
			'Clothing=F2',
		},
		join = {
			'C._ID=CFRA._rowID','CFRA._value=E.Name',
			'E.Name=F1.Name',
			'E.Name=F2.Name',
		},
		fields = {
			'C._pageName=C_PAGENAME',
			'C.Image=C_Image',
			'C.Name=C_Name',
			'C.Class=C_Class',
			'C.NumFurnReq=C_NumFurnReq',
			'E.EntityType=EntityType',
			'CFRA._position=F_position',
			'COALESCE(F1._pageName,F2._pageName)=F_PAGENAME',
			'COALESCE(F1.Name, F2.Name)=F_Name',
			'COALESCE(F1.Image, F2.Image)=F_Image',
			'COALESCE(F1.MaterialCost, F2.MaterialCost)=F_MaterialCost',
			'COALESCE(F1.NumBells, F2.NumBells)=F_NumBells',
			'COALESCE(F1.CraftTimeSec, F2.CraftTimeSec)=F_CraftTimeSec',
			'COALESCE(F1.UnlockReq, F2.UnlockReq)=F_UnlockReq',
			'COALESCE(F1.Obtain, F2.Obtain)=F_Obtain',
			'SUBSTRING(CONCAT("0", Class), -4, 4)=ClassCourseSortKey',
		},
		where = {
			'C.type="Normal"',
			'(C.Class LIKE "%-%")',
		},
		orderBy = 'ClassCourseSortKey',
	}
	local t1 = {}
	for i, row in ipairs(rows) do
		if row['F_MaterialCost'] then
			string.gsub(row['F_MaterialCost'], '<br/><br/>', '<br/>')
		end
		
		local classKey = row['C_Class']
		t1[classKey] = t1[classKey] or {
			pagename = row['C_PAGENAME'],
			image = row['C_Image'],
			name = row['C_Name'],
			class = row['C_Class'],
			sortKey = row['ClassCourseSortKey'],
			numFurnReq = row['C_NumFurnReq'],
			furnitures = {},
		}
		local furnitures = t1[classKey].furnitures
		local furnitureKey = tonumber(row['F_position'])
		furnitures[furnitureKey] = furnitures[furnitureKey] or {
			pagename = row['F_PAGENAME'],
			name = row['F_Name'] or row['F_PAGENAME'],
			image = row['F_Image'],
			materialCost = row['F_MaterialCost'],
			numBells = row['F_NumBells'],
			craftTimeSec = row['F_CraftTimeSec'],
			unlockReq = row['F_UnlockReq'],
			obtain = row['F_Obtain'],
		}
	end
	local t2 = {}
	for k, v in pairs(t1) do
		t2[#t2+1] = v
	end
	table.sort(t2, function(a, b) return a.sortKey < b.sortKey end)

	local headers = {
		'Course Name',
		'Class',
		'On-Point Item',
		'Material Cost',
		'Bell Cost',
		'Craft Time',
		'How to Unlock',
	}

	local root = mw.html.create('table'):addClass('wikitable')
	h.printHeaders(root, headers)
	for i, classData in ipairs(t2) do
		h.printClass(root, classData)
	end
	return tostring(root)
end

function h.printHeaders(root, headers)
	local tr = root:tag('tr')
	for i, txt in ipairs(headers) do
		tr:tag('th'):wikitext(txt)
	end
end

function h.printClass(root, data)
	local rowspan = #data.furnitures
	for i, furniture in ipairs(data.furnitures) do
		local tr = root:tag('tr')
		local td
		if i == 1 then
			local classIcon = string.format(
				'[[File:%s.png|60px|alt=%s|link=%s]]<br>[[%s%s]]',
				data.image,
				data.name,
				data.pagename,
				data.pagename,
				data.pagename ~= data.name and '|'..data.name or ''
			)
			tr:css('border-top', '2px solid #c1b695')
			tr:tag('td')
				:attr('rowspan', rowspan)
				:css('text-align', 'center')
				:wikitext(classIcon)
			tr:tag('td')
				:attr('rowspan', rowspan)
				:attr('data-sort-value', data.sortKey)
				:wikitext(data.class)
		end
		local furnitureIcon = string.format(
			'[[File:%s.png|24px|alt=%s|link=]] %s',
			furniture.image or '???',
			furniture.name,
			furniture.name
		)
		tr:tag('td'):wikitext(furnitureIcon)
		
		if furniture.materialCost == 'N/A' or not furniture.numBells then
			tr:tag('td'):attr('colspan', 4):wikitext(furniture.obtain)
		else
			tr:tag('td'):wikitext(furniture.materialCost)
			tr:tag('td'):wikitext(h.bells(furniture.numBells))
			tr:tag('td'):wikitext(h.duration(furniture.craftTimeSec) or '-')
			tr:tag('td'):wikitext(furniture.unlockReq)
		end
	end
end

function h.bells(n)
	return ('%s&nbsp;[[File:Bells.png|24px|Bells|alt=Bells|link=]]'):format(n)
end

function h.duration(seconds)
	local seconds = tonumber(seconds)
	if not seconds then return end

	local hh = math.floor(seconds / 60 / 60)
	local mm = math.floor(seconds / 60 % 60)
	local ss = (seconds % 60)

	local t = {}
	if hh > 0 then
		t[#t+1] = LANG:plural(hh, '%d hour', '%d hours'):format(hh)
	end
	if mm > 0 then
		t[#t+1] = LANG:plural(mm, '%d minute', '%d minutes'):format(mm)
	end
	if hh == 0 and mm == 0 or ss > 0 then
		t[#t+1] = LANG:plural(ss, '%d second', '%d seconds'):format(ss)
	end
	return table.concat(t, ' ')
end

return p