Module:Enemy List

Revision as of 12:42, 29 November 2024 by Artoire (talk | contribs) (Commas)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

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

require('strict')
local yesno = require('Module:Yesno')
local album_xp_data = require('Module:Experience/data').album
local Array = require('Module:Array')
local lang = mw.language.getContentLanguage()

local function formatNum(n)
	if n == nil then
		return ''
	end
	return lang:formatNum(n)
end

local p = {}

function p.main(frame)
	local args = frame:getParent().args
	local profession = args.profession or mw.title.getCurrentTitle()
	local passive = yesno(args.passive) and true or false
	return p._main(profession, passive)
end

-- Similar to Template:AttackStyle
local function format_attack_style(style)
	style = (style or ''):lower()
	if style == '' then
		return "''Unknown''"
	end
	if style == 'none' then
		return "''None''"
	end
	style = style:sub(1,1):upper() .. style:sub(2)
	return ('[[File:%s damage icon.png|18x18px|link=%s]] [[%s]]'):format(style, style, style)
end

local function active_table(data)
	local out = mw.html.create('table')
		:addClass('wikitable sortable align-center-3 align-center-4')
		:tag('tr')
			:tag('th')
				:attr{ colspan = '2' }
				:wikitext('Enemy')
			:done()
			:tag('th'):wikitext('Unlock\nLevel'):done()
			:tag('th'):wikitext('Combat\nLevel'):done()
			:tag('th'):wikitext('HP'):done()
			:tag('th'):wikitext('Attack Style'):done()
			:tag('th'):wikitext('Immume To'):done()
			:tag('th'):wikitext('Vulnerable'):done()
			:tag('th'):wikitext('Found At'):done()
			:tag('th'):wikitext('XP'):done()
			:tag('th'):wikitext('Album XP'):done()
		:done()

	for _, monster in ipairs(data) do
		local row = out:tag('tr')
			:tag('td'):wikitext(monster.Image):done()
			:tag('td'):wikitext(monster[1]):done()
			:tag('td'):wikitext(monster['Unlock level']):done()
			:tag('td'):wikitext(monster['Profession Level A']):done()
			:tag('td'):wikitext(formatNum(monster.Health)):done()
			:tag('td'):wikitext(format_attack_style(monster['Attack style'])):done()
			:tag('td'):wikitext(format_attack_style(monster['Immune to'])):done()
			:tag('td'):wikitext(format_attack_style(monster['Vulnerable to'])):done()

		local location_text = {}
		for location, qty in pairs(monster['Location JSON']) do
			table.insert(location_text, ('[[%s]] (%s)'):format(location, qty))
		end
		row
			:tag('td'):wikitext(table.concat(location_text, ', ')):done()
			:tag('td'):wikitext(formatNum(monster.Experience)):done()
			:tag('td'):wikitext(formatNum(monster['Album XP'])):done()
	end

	return out
end

local function passive_table(data)
	return 'TODO'
end

function p._main(profession, passive)
	local data = mw.smw.ask{
		'[[Category:Monsters]]',
		('[[Profession A::%s]]'):format(profession),
		('[[Passive::%s]]'):format(passive and 'true' or 'false'),
		'?Image#70px;x70px',
		'?Unlock level',
		'?Profession Level A',
		'?Health',
		'?Attack style',
		'?Immune to',
		'?Vulnerable to',
		'?Location JSON',
		'?Experience',
		'?Quest',
		'?Variant of#-',
		'sort=Profession Level A',
		'order=asc'
	}

	data = Array.filter(data, function(monster)
		return monster.Quest == nil and monster[1] ~= '[[:Training Dummy|Training Dummy]]'
	end)

	local location_cache = {}

	for _, monster in ipairs(data) do
		monster['Album XP'] = album_xp_data[monster['Profession Level A']]
		if monster['Location JSON'] == nil and monster['Variant of'] ~= nil then
			local variant_cat = monster['Variant of']
			if location_cache[variant_cat] == nil then
				local of_variant = mw.smw.ask{
					'[['..variant_cat..']]',
					'?Location JSON'
				}
				location_cache[variant_cat] = of_variant and of_variant[1]['Location JSON']
			end
			monster['Location JSON'] = location_cache[variant_cat]
		end
		monster['Location JSON'] = mw.text.jsonDecode(monster['Location JSON'] or '{}')
	end

	if passive then
		return passive_table(data)
	end
	return active_table(data)
end

return p