Module:Combat Achievements

From Roat Pkz
Revision as of 22:16, 30 March 2024 by Hefner (talk | contribs) (1 revision imported)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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

local tables = require('Module:Tables')
local VariablesLua = mw.ext.VariablesLua
local p = {}

local prose = {
	monster = '',
	taskamount = 0,
	ptsamount = 0
}

local headers = {
	monster = "Monster",
	name = "Name",
	description = { text = "Description", attr = { class = 'unsortable' } },
	tier = "Tier",
	_type = "Type",
	completion = '<span style="cursor:help; border-bottom:1px dotted;" title="Estimated percentage of players (with at least one CA completion) who have completed this achievement, based on wiki crowdsourcing">Comp%</span>'
}

local tiers = {
	easy = 1,
	medium = 2,
	hard = 3,
	elite = 4,
	master = 5,
	grandmaster = 6
}

local function getData(category)
	local out = {}
	local params = {
		category[1],
		"?Combat Achievement JSON",
		limit = 1000
	}
	local data = mw.smw.ask(params) or {}
	
	for _, task in ipairs(data) do
		local raw = task['Combat Achievement JSON']
		if raw ~= nil then
			local json = mw.text.jsonDecode(raw)
			table.insert(out, json)
		end
	end
	
	return out
end

local function sortByTierAndMonster(k1, k2) 
	local k1_tier = tiers[string.lower(k1.tier)]
	local k2_tier = tiers[string.lower(k2.tier)]
	if k1_tier < k2_tier then
		return true
	elseif k1_tier > k2_tier then
		return false
	elseif k1.monster < k2.monster then
		return true
	elseif k1.monster > k2.monster then
		return false
	else
		return false
	end
end

local function completionCell(id)
	local completion_percent = mw.loadJsonData("Module:Combat Achievements/completion.json")[tonumber(id)]
	if (completion_percent ~= nil) then
		local color = ""
		if (completion_percent < 0.1) then
			completion_percent = "<0.1"
			color = "red"
		elseif (completion_percent < 1) then
			color = "orange"
		elseif (completion_percent < 10) then
			color = "yellow"
		elseif (completion_percent < 50) then
			color = "green"
		elseif (completion_percent <= 100) then
			color = "blue"
		end
		return {text = tostring(completion_percent)..'%', class = "table-bg-" .. color}
	else
		return {text = "N/A", class="table-na nohighlight"}
	end	
end

local function makeTable(data, columns)
	local taskTable = mw.html.create('table'):addClass('wikitable lighttable sortable qc-active ca-tasks'):cssText('max-width: 800px')
	
	local columnValues = {}
	for _, v in ipairs(columns) do
		table.insert(columnValues, headers[v])
	end
	tables._row(taskTable:tag('tr'), columnValues, true)
	
	for _, v in ipairs(data) do
		local rowData = {
			monster = v.monster == "None" and "N/A" or string.format("[[%s]]", v.monster),
			name = string.format("[[%s]]", v.name),
			description = v.task,
			tier = { text = ( v.tier .. '&nbsp;(' .. tiers[v.tier:lower()] .. '&nbsp;' .. (tiers[v.tier:lower()] == 1 and 'pt' or 'pts') .. ')' ), attr = { ['data-sort-value'] = tiers[v.tier:lower()] } },
			_type = v["type"],
			completion = completionCell(v.id)
		}
		
		local row = {}
		for _, column in ipairs(columns) do
			table.insert(row, rowData[column])
		end
		
		local htmlRow = taskTable:tag('tr'):attr('data-ca-task-id', v.id)
		tables._row(htmlRow, row, false)
		
		prose.taskamount = prose.taskamount + 1
		prose.ptsamount = prose.ptsamount + tiers[v.tier:lower()]
	end

	return taskTable
end

function p.list(frame)
	local args = frame:getParent().args
	
	local columns = {"name", "description", "_type"}
	local category = {}
	if args[1] == 'all' then
		category = {"[[Category:Easy Combat Achievements tasks||Medium Combat Achievements tasks||Hard Combat Achievements tasks||Elite Combat Achievements tasks||Master Combat Achievements tasks||Grandmaster Combat Achievements tasks]]"}
		table.insert(columns, 1, "monster")
		table.insert(columns, "tier")
	elseif tiers[string.lower(args[1])] ~= nil then
		-- Get all Combat Achievement tasks for a tier and display its monster
		category = {string.format("[[Category:%s Combat Achievements tasks]]", args[1])}
		table.insert(columns, 1, "monster")
	else
		-- Get all Combat Achievement tasks for a boss and display its tier
		category = {string.format("[[Category:%s achievements]]", args[1])}
		table.insert(columns, "tier")
	end
	
	table.insert(columns, "completion")
	
	prose.monster = args.mobname or args[1]
	
	local data = getData(category)
	table.sort(data, sortByTierAndMonster)
	
	local rettbl = tostring( makeTable(data, columns) )
	local strplural = (prose.taskamount ~= 1)
	local moduleInvokedOnce = VariablesLua.varexists('caListModuleInvoked')
	local retstr = ( string.find( mw.title.getCurrentTitle().text, 'Combat Achievements') and '' or
		string.format('<p>There %s %s %s task%s (totalling %s point%s) available for %s.</p>',
			(strplural and 'are' or 'is'),
			prose.taskamount,
			(moduleInvokedOnce and 'Combat Achievement' or '[[Combat Achievements|Combat Achievement]]'),
			(strplural and 's' or ''),
			prose.ptsamount,
			(prose.ptsamount ~= 1 and 's' or ''),
			prose.monster
		) )
	
	VariablesLua.vardefine( 'caListModuleInvoked', 0 )

	return retstr .. rettbl
end

return p