Module:Enemy List: Difference between revisions

(search will now include versions of monsters that have versions, and only display the default version, using the name of the overall monster and not the specific version)
(Use plinkt styling with no-border; Use Module:Mw.html extension methods; Always link to the page in case it's different from Name)
 
(4 intermediate revisions by 2 users not shown)
Line 1: Line 1:
require('strict')
require('strict')
require('Module:Mw.html extension')
local yesno = require('Module:Yesno')
local yesno = require('Module:Yesno')
local album_xp_data = mw.loadData('Module:Experience/data').album
local album_xp_data = mw.loadData('Module:Experience/data').album
Line 5: Line 6:
local lang = mw.language.getContentLanguage()
local lang = mw.language.getContentLanguage()
local purge = require('Module:Purge')._purge
local purge = require('Module:Purge')._purge
local editbutton = require('Module:Edit button')


local function formatNum(n)
local function formatNum(n)
Line 41: Line 43:
:wikitext('This list is updated dynamically. '..purge())
:wikitext('This list is updated dynamically. '..purge())
:done()
:done()
:tag('tr')
:tr()
:th{ 'Enemy', attr = { colspan = '2' } }:done()
:tag('th')
:th('Unlock<br>Level'):done()
:attr{ colspan = '2' }
:wikitext('Enemy')
:th('Combat<br>Level'):done()
:done()
:th('HP'):done()
:tag('th'):wikitext('Unlock<br>Level'):done()
:th('Attack Style'):done()
:tag('th'):wikitext('Combat<br>Level'):done()
:th('Immune To'):done()
:tag('th'):wikitext('HP'):done()
:th('Vulnerable'):done()
:tag('th'):wikitext('Attack Style'):done()
:th('Found At'):done()
:tag('th'):wikitext('Immune To'):done()
:th('XP'):done()
:tag('th'):wikitext('Vulnerable'):done()
:th('Album XP'):done()
:tag('th'):wikitext('Found At'):done()
:tag('th'):wikitext('XP'):done()
:tag('th'):wikitext('Album XP'):done()
:done()
:done()


for _, monster in ipairs(data) do
for _, monster in ipairs(data) do
local row = out:tag('tr')
local edit = editbutton("'''?''' (edit)", monster[1])
local row = out:tr()
:tag('td'):wikitext(monster.Image):done()
:tag('td'):wikitext(('[[%s]]'):format(monster['Name'])):done()
:td{ monster.Image, addClass = 'plinkt-image no-border' }:done()
:tag('td'):wikitext(monster['Unlock level']):done()
:td{ ('[[%s|%s]]'):format(monster[1], monster['Name']), addClass = 'plinkt-link no-border'}:done()
:tag('td'):wikitext(monster['Profession Level A']):done()
:td(monster['Unlock level'] or edit):done()
:td(monster['Profession Level A'] or edit):done()
:tag('td'):wikitext(formatNum(monster.Health)):done()
:tag('td'):wikitext(format_attack_style(monster['Attack style'])):done()
:td((monster.Health and formatNum(monster.Health)) or edit):done()
:tag('td'):wikitext(format_attack_style(monster['Immune to'])):done()
:td(format_attack_style(monster['Attack style'])):done()
:tag('td'):wikitext(format_attack_style(monster['Vulnerable to'])):done()
:td(format_attack_style(monster['Immune to'])):done()
:td(format_attack_style(monster['Vulnerable to'])):done()


local location_text = {}
local location_text = {}
Line 73: Line 73:
end
end
row
row
:tag('td'):wikitext(table.concat(location_text, ', ')):done()
:td(table.concat(location_text, ', ')):done()
:tag('td'):wikitext(formatNum(monster.Experience)):done()
:td((monster.Experience and formatNum(monster.Experience)) or edit):done()
:tag('td'):wikitext(formatNum(monster['Album XP'])):done()
:td((monster['Album XP'] and formatNum(monster['Album XP']) or editbutton("'''?''' (edit)", 'Module:Experience/data'))):done()
end
end


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


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


local location_text = {}
local location_text = {}
Line 111: Line 112:
end
end
row
row
:tag('td'):wikitext(table.concat(location_text, ', ')):done()
:td(table.concat(location_text, ', ')):done()
:tag('td'):wikitext(formatNum(monster.Experience)):done()
:td((monster.Experience and formatNum(monster.Experience)) or edit):done()
:tag('td'):wikitext(formatNum(monster['Album XP'])):done()
:td((monster['Album XP'] and formatNum(monster['Album XP']) or editbutton("'''?''' (edit)", 'Module:Experience/data'))):done()
end
end


Line 122: Line 123:
local data = mw.smw.ask{
local data = mw.smw.ask{
'[[Infobox::Monster]]',
'[[Infobox::Monster]]',
('[[Profession A::%s]]'):format(profession),
('[[Unlock profession::%s]]'):format(profession),
('[[Passive::%s]]'):format(passive and 'true' or 'false'),
('[[Passive::%s]]'):format(passive and 'true' or 'false'),
'?Image#70px;x70px',
'?Image#70px;x70px',
Line 133: Line 134:
'?Location JSON',
'?Location JSON',
'?Experience',
'?Experience',
'?Quest',
'?Name',
'?Name',
'?Knowledge',
'?Knowledge',
Line 139: Line 139:
'?Version anchor',
'?Version anchor',
'?Version default',
'?Version default',
'?#-',
'sort=Profession Level A',
'sort=Profession Level A',
'order=asc',
'order=asc',
Line 145: Line 146:


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



Latest revision as of 15:18, 3 January 2025

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