Module:Enemy List

From Brighter Shores Wiki
Jump to navigation Jump to search
Module documentation
This documentation is transcluded from Module:Enemy List/doc. [edit] [history] [purge]
This module does not have any documentation. Please consider adding documentation at Module:Enemy List/doc. [edit]
Module:Enemy List's function main is invoked by Template:EnemyList.
Module:Enemy List loads data from Module:Experience/data.

require('strict')
require('Module:Mw.html extension')
local yesno = require('Module:Yesno')
local album_xp_data = mw.loadData('Module:Experience/data').album
local Array = require('Module:Array')
local lang = mw.language.getContentLanguage()
local purge = require('Module:Purge')._purge
local editbutton = require('Module:Edit button')

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('caption')
			:wikitext('This list is updated dynamically. '..purge())
		:done()
		:tr()
			:th{ 'Enemy', attr = { colspan = '2' } }:done()
			:th('Unlock<br>Level'):done()
			:th('Combat<br>Level'):done()
			:th('HP'):done()
			:th('Attack Style'):done()
			:th('Immune To'):done()
			:th('Vulnerable'):done()
			:th('Found At'):done()
			:th('XP'):done()
			:th('Album XP'):done()
		:done()

	for _, monster in ipairs(data) do
		local edit = editbutton("'''?''' (edit)", monster[1])
		local row = out:tr()
			:td{ monster.Image, addClass = 'plinkt-image no-border' }:done()
			:td{ ('[[%s|%s]]'):format(monster[1], monster['Name']), addClass = 'plinkt-link no-border'}:done()
			:td(monster['Unlock level'] or edit):done()
			:td(monster['Profession Level A'] or edit):done()
			:td((monster.Health and formatNum(monster.Health)) or edit):done()
			:td(format_attack_style(monster['Attack style'])):done()
			:td(format_attack_style(monster['Immune to'])):done()
			:td(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 == -1 and '?' or qty))
		end
		row
			:td(table.concat(location_text, ', ')):done()
			:td((monster.Experience and formatNum(monster.Experience)) or edit):done()
			:td((monster['Album XP'] and formatNum(monster['Album XP']) or editbutton("'''?''' (edit)", 'Module:Experience/data'))):done()
	end

	return out
end

local function passive_table(data)
	local out = mw.html.create('table')
		:addClass('wikitable sortable align-center-3 align-center-4 align-center-5')
		:tag('caption')
			:wikitext('This list is updated dynamically. '..purge())
		:done()
		:tr()
			:th{ 'Enemy', attr = { colspan = '2' } }:done()
			:th('Level'):done()
			:th('Weapon<br>Strength'):done()
			:th('[[File:Knowledge icon.png|16px|link=Knowledge]] KP'):done()
			:th('Location'):done()
			:th('XP'):done()
			:th('Album XP'):done()
		:done()

	for _, monster in ipairs(data) do
		local edit = editbutton("'''?''' (edit)", monster['Name'])
		local row = out:tag('tr')
			:td{ monster.Image, addClass = 'plinkt-image no-border' }:done()
			:td{ ('[[%s|%s]]'):format(monster[1], monster['Name']), addClass = 'plinkt-link no-border'}:done()
			:td(monster['Unlock level'] or edit):done()
			:td((monster['Unlock level'] and monster['Unlock level'] + 20) or edit):done()
			:td(monster.Knowledge or edit):done()

		local location_text = {}
		for location, qty in pairs(monster['Location JSON']) do
			-- Quantity unimportant
			table.insert(location_text, ('[[%s]]'):format(location))
		end
		row
			:td(table.concat(location_text, ', ')):done()
			:td((monster.Experience and formatNum(monster.Experience)) or edit):done()
			:td((monster['Album XP'] and formatNum(monster['Album XP']) or editbutton("'''?''' (edit)", 'Module:Experience/data'))):done()
	end

	return out
end

function p._main(profession, passive)
	local data = mw.smw.ask{
		'[[Infobox::Monster]]',
		('[[Unlock profession::%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',
		'?Name',
		'?Knowledge',
		'?Variant of#-',
		'?Version anchor',
		'?Version default',
		'?#-',
		'sort=Profession Level A',
		'order=asc',
		'limit=500'
	}

	data = Array.filter(data, function(monster)
		return monster['Version default'] or not(monster['Version anchor'] or false)
	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