Module:Learnsets: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
No edit summary |
||
| Line 23: | Line 23: | ||
local moveDataCache = nil | local moveDataCache = nil | ||
local function blankToNil(v) | |||
if v == nil or v == '' then | |||
return nil | |||
end | |||
return v | |||
end | |||
local function loadMoveData() | local function loadMoveData() | ||
| Line 54: | Line 61: | ||
for _, row in ipairs(csvData) do | for _, row in ipairs(csvData) do | ||
moveDataCache[row.Name] = { | moveDataCache[row.Name] = { | ||
type = row.Type or 'Normal', | type = blankToNil(row.Type) or 'Normal', | ||
category = row.Category or 'Status', | category = blankToNil(row.Category) or 'Status', | ||
power = row.Power, | power = blankToNil(row.Power), | ||
accuracy = row.Accuracy | accuracy = blankToNil(row.Accuracy), | ||
pp = row.PP, | pp = blankToNil(row.PP), | ||
broken = row.Broken or 'N', | broken = row.Broken or 'N', | ||
typeless = row.Typeless or 'N', | typeless = row.Typeless or 'N', | ||
priority = row.Priority or '0', | priority = blankToNil(row.Priority) or '0', | ||
tm = row.TM, | tm = blankToNil(row.TM), | ||
move_tutor = row['Move Tutor'], | move_tutor = blankToNil(row['Move Tutor']), | ||
egg = row.Egg | egg = blankToNil(row.Egg) | ||
} | } | ||
end | end | ||
| Line 169: | Line 176: | ||
local function getBorderColor(primaryType) | local function getBorderColor(primaryType) | ||
return typeColors[primaryType] and typeColors[primaryType].border or "000000" | return typeColors[primaryType] and typeColors[primaryType].border or "000000" | ||
end | |||
local function getHeaderColor(primaryType) | |||
return typeColors[primaryType] and typeColors[primaryType].bg or "E0E0E0" | |||
end | end | ||
| Line 197: | Line 208: | ||
local header = table:tag('tr') | local header = table:tag('tr') | ||
:css('background-color', '# | :css('background-color', '#' .. getHeaderColor(primaryType)) | ||
header:tag('th'):wikitext('Level'):css('width', '14%'):css('border-radius', '15px 1px 1px 1px') | header:tag('th'):wikitext('Level'):css('width', '14%'):css('border-radius', '15px 1px 1px 1px') | ||
header:tag('th'):wikitext('Move'):css('width', '17%') | header:tag('th'):wikitext('Move'):css('width', '17%') | ||
| Line 279: | Line 290: | ||
local header = table:tag('tr') | local header = table:tag('tr') | ||
:css('background-color', '# | :css('background-color', '#' .. getHeaderColor(primaryType)) | ||
header:tag('th'):attr('colspan', '2'):wikitext('TM'):css('width', '11%'):css('border-top-left-radius', '25px') | header:tag('th'):attr('colspan', '2'):wikitext('TM'):css('width', '11%'):css('border-top-left-radius', '25px') | ||
header:tag('th'):wikitext('Move'):css('width', '18%') | header:tag('th'):wikitext('Move'):css('width', '18%') | ||
| Line 394: | Line 405: | ||
:css('padding', '7px') | :css('padding', '7px') | ||
local header = table:tag('tr'):css('background-color', '# | local header = table:tag('tr'):css('background-color', '#' .. getHeaderColor(primaryType)) | ||
header:tag('th'):wikitext('Move'):css('border-top-left-radius', '25px') | header:tag('th'):wikitext('Move'):css('border-top-left-radius', '25px') | ||
header:tag('th'):wikitext('Type') | header:tag('th'):wikitext('Type') | ||
| Line 401: | Line 412: | ||
header:tag('th'):wikitext('Accuracy') | header:tag('th'):wikitext('Accuracy') | ||
header:tag('th'):wikitext('PP'):css('border-top-right-radius', '25px') | header:tag('th'):wikitext('PP'):css('border-top-right-radius', '25px') | ||
for _, moveName in ipairs(moves) do | for _, moveName in ipairs(moves) do | ||
local moveInfo = moveData[moveName] or {} | local moveInfo = moveData[moveName] or {} | ||
local row = table:tag('tr'):css('background-color', '#FFFFFF') | local row = table:tag('tr'):css('background-color', '#FFFFFF') | ||
local moveLink = '[[' .. moveName .. ']]' | local moveLink = '[[' .. moveName .. ']]' | ||
if isSTAB(moveInfo.type, primaryType, secondaryType) and moveInfo.category ~= "Status" then | if isSTAB(moveInfo.type, primaryType, secondaryType) and moveInfo.category ~= "Status" then | ||
| Line 414: | Line 425: | ||
end | end | ||
row:tag('td'):wikitext(moveLink) | row:tag('td'):wikitext(moveLink) | ||
local typeColor = typeColors[moveInfo.type] or typeColors.Normal | local typeColor = typeColors[moveInfo.type] or typeColors.Normal | ||
row:tag('td') | row:tag('td') | ||
| Line 420: | Line 431: | ||
:css('border', '2px solid #' .. typeColor.border) | :css('border', '2px solid #' .. typeColor.border) | ||
:wikitext('[[' .. (moveInfo.type or 'Normal') .. '_(type)|<span style="color:#FFFFFF;">' .. (moveInfo.type or 'Normal') .. '</span>]]') | :wikitext('[[' .. (moveInfo.type or 'Normal') .. '_(type)|<span style="color:#FFFFFF;">' .. (moveInfo.type or 'Normal') .. '</span>]]') | ||
local catColor = categoryColors[moveInfo.category] or categoryColors.Status | local catColor = categoryColors[moveInfo.category] or categoryColors.Status | ||
row:tag('td') | row:tag('td') | ||
| Line 426: | Line 437: | ||
:css('border', '2px solid #' .. catColor.border) | :css('border', '2px solid #' .. catColor.border) | ||
:wikitext('[[' .. (moveInfo.category or 'Status') .. ' moves|<span style="color:#FFFFFF;">' .. (moveInfo.category or 'Status') .. '</span>]]') | :wikitext('[[' .. (moveInfo.category or 'Status') .. ' moves|<span style="color:#FFFFFF;">' .. (moveInfo.category or 'Status') .. '</span>]]') | ||
row:tag('td'):wikitext(moveInfo.power or '—') | row:tag('td'):wikitext(moveInfo.power or '—') | ||
row:tag('td'):wikitext(moveInfo.accuracy or '—') | row:tag('td'):wikitext(moveInfo.accuracy or '—') | ||
row:tag('td'):wikitext(moveInfo.pp or '—') | row:tag('td'):wikitext(moveInfo.pp or '—') | ||
end | end | ||
return tostring(html) .. '<br clear="all">' | return tostring(html) .. '<br clear="all">' | ||
end | end | ||
| Line 462: | Line 473: | ||
:css('padding', '7px') | :css('padding', '7px') | ||
local header = table:tag('tr'):css('background-color', '# | local header = table:tag('tr'):css('background-color', '#' .. getHeaderColor(primaryType)) | ||
header:tag('th'):wikitext('Move'):css('width', '15%'):css('border-top-left-radius', '25px') | header:tag('th'):wikitext('Move'):css('width', '15%'):css('border-top-left-radius', '25px') | ||
header:tag('th'):wikitext('Type'):css('width', '13%') | header:tag('th'):wikitext('Type'):css('width', '13%') | ||
Revision as of 15:03, 9 July 2026
Documentation for this module may be created at Module:Learnsets/doc
local p = {}
local function getArgs(frame)
local args = {}
local parent = frame:getParent()
if parent then
for k, v in pairs(parent.args) do
if v ~= '' then
args[k] = v
end
end
end
for k, v in pairs(frame.args) do
if v ~= '' then
args[k] = v
end
end
return args
end
local moveDataCache = nil
local function blankToNil(v)
if v == nil or v == '' then
return nil
end
return v
end
local function loadMoveData()
if moveDataCache then
return moveDataCache
end
local csvData = mw.ext.externalData.getExternalData({
url = 'https://wiki.pokemonrevolution.net/index.php?title=Special:GetData/RawMovesList',
format = 'CSV with header',
data = {
Name = 'Name',
Type = 'Type',
Category = 'Category',
Power = 'Power',
Accuracy = 'Accuracy',
PP = 'PP',
Broken = 'Broken',
Typeless = 'Typeless',
Priority = 'Priority',
TM = 'TM',
['Move Tutor'] = 'Move Tutor',
Egg = 'Egg',
},
})
-- getExternalData returns an array of row-tables here (csvData[i].Name),
-- not column-arrays (csvData.Name[i]).
moveDataCache = {}
if csvData then
for _, row in ipairs(csvData) do
moveDataCache[row.Name] = {
type = blankToNil(row.Type) or 'Normal',
category = blankToNil(row.Category) or 'Status',
power = blankToNil(row.Power),
accuracy = blankToNil(row.Accuracy),
pp = blankToNil(row.PP),
broken = row.Broken or 'N',
typeless = row.Typeless or 'N',
priority = blankToNil(row.Priority) or '0',
tm = blankToNil(row.TM),
move_tutor = blankToNil(row['Move Tutor']),
egg = blankToNil(row.Egg)
}
end
end
return moveDataCache
end
local function loadLearnset(pokemonName)
local jsonPath = '$[' .. mw.text.jsonEncode(pokemonName) .. ']'
local ok, result, errors = pcall(function()
return mw.ext.externalData.getFileData({
source = 'data',
['file name'] = 'Learnsets.json',
format = 'JSON',
['use jsonpath'] = true,
data = { poke = jsonPath },
})
end)
if not ok then
return nil, 'Lua error: ' .. tostring(result)
end
if errors and #errors > 0 then
return nil, 'ExternalData error: ' .. table.concat(errors, ' | ')
end
local raw = result and result.poke
if type(raw) ~= 'table' then
return nil, 'No learnset data found for ' .. pokemonName
end
return raw, nil
end
local learnsetCache = {}
local learnsetErrorCache = {}
local function getCachedLearnset(pokemonName)
if learnsetCache[pokemonName] == nil and learnsetErrorCache[pokemonName] == nil then
learnsetCache[pokemonName], learnsetErrorCache[pokemonName] = loadLearnset(pokemonName)
end
return learnsetCache[pokemonName], learnsetErrorCache[pokemonName]
end
-- Loads Type1/Type2 for every Pokemon from the PokemonRawList CSV.
local pokemonTypeCache = nil
local function loadPokemonTypes()
if pokemonTypeCache then return pokemonTypeCache end
local csvData = mw.ext.externalData.getExternalData({
url = 'https://wiki.pokemonrevolution.net/index.php?title=Special:GetData/PokemonRawList',
format = 'CSV with header',
data = {
Name = 'Name',
Type1 = 'Type1',
Type2 = 'Type2',
},
})
-- Same row-table shape as loadMoveData: csvData[i].Name, not csvData.Name[i].
pokemonTypeCache = {}
if csvData then
for _, row in ipairs(csvData) do
pokemonTypeCache[row.Name] = {
type1 = row.Type1 or '',
type2 = row.Type2 or '',
}
end
end
return pokemonTypeCache
end
local typeColors = {
Normal = { bg = "A8A878", border = "6D6D4E" },
Fire = { bg = "F08030", border = "9C531F" },
Water = { bg = "6890F0", border = "445E9C" },
Electric = { bg = "F8D030", border = "A1871F" },
Grass = { bg = "78C850", border = "4E8234" },
Ice = { bg = "98D8D8", border = "638D8D" },
Fighting = { bg = "C03028", border = "7D1F1A" },
Poison = { bg = "A040A0", border = "682A68" },
Ground = { bg = "E0C068", border = "927D44" },
Flying = { bg = "A890F0", border = "6D5E9C" },
Psychic = { bg = "F85888", border = "A13959" },
Bug = { bg = "A8B820", border = "6D7815" },
Rock = { bg = "B8A038", border = "786824" },
Ghost = { bg = "705898", border = "493963" },
Dragon = { bg = "7038F8", border = "4924A1" },
Dark = { bg = "705848", border = "49392F" },
Steel = { bg = "B8B8D0", border = "787887" },
Fairy = { bg = "EE99AC", border = "9B6470" },
Shadow = { bg = "5A5A5A", border = "2D2D2D" }
}
local categoryColors = {
Physical = { bg = "C92112", border = "7D1F1A" },
Special = { bg = "4F5870", border = "353B51" },
Status = { bg = "8C888C", border = "5A5A5A" }
}
local function isSTAB(moveType, primaryType, secondaryType)
return moveType == primaryType or moveType == secondaryType
end
local function getBorderColor(primaryType)
return typeColors[primaryType] and typeColors[primaryType].border or "000000"
end
local function getHeaderColor(primaryType)
return typeColors[primaryType] and typeColors[primaryType].bg or "E0E0E0"
end
function p.renderLevelUp(frame)
local args = getArgs(frame)
local pokemonName = args[1] or args.pokemon
local primaryType = args.type1 or ""
local secondaryType = args.type2 or ""
local pokemon, lsErr = getCachedLearnset(pokemonName)
local moveData = loadMoveData()
if not pokemon then
return "<span style='color:red'>Data load error: " .. (lsErr or 'unknown') .. "</span>"
end
local moves = pokemon.level_up or {}
local html = mw.html.create('div')
local table = html:tag('table')
:css('width', '77%')
:css('text-align', 'center')
:css('margin', 'auto')
:css('border-radius', '15px')
:css('border', '3px solid #' .. getBorderColor(primaryType))
:css('background-color', '#F5F5F5')
:css('padding', '7px')
local header = table:tag('tr')
:css('background-color', '#' .. getHeaderColor(primaryType))
header:tag('th'):wikitext('Level'):css('width', '14%'):css('border-radius', '15px 1px 1px 1px')
header:tag('th'):wikitext('Move'):css('width', '17%')
header:tag('th'):wikitext('Type'):css('width', '22%')
header:tag('th'):wikitext('Category'):css('width', '21%')
header:tag('th'):wikitext('Base Power'):css('width', '26%')
header:tag('th'):wikitext('Accuracy'):css('width', '13%')
header:tag('th'):wikitext('PP'):css('width', '5%'):css('border-radius', '1px 15px 1px 1px')
for _, move in ipairs(moves) do
local moveName = move.move
local level = move.level
local moveInfo = moveData[moveName] or {}
local row = table:tag('tr'):css('background-color', '#FFFFFF')
row:tag('td'):wikitext(tostring(level))
local moveLink = '[[' .. moveName .. ']]'
if isSTAB(moveInfo.type, primaryType, secondaryType) and moveInfo.category ~= "Status" then
moveLink = "'''" .. moveLink .. "'''"
end
if moveInfo.broken == "Y" then
moveLink = "''" .. moveLink .. "''"
end
row:tag('td'):wikitext(moveLink)
local typeColor = typeColors[moveInfo.type] or typeColors.Normal
row:tag('td')
:css('background-color', '#' .. typeColor.bg)
:css('border', '2px solid #' .. typeColor.border)
:wikitext('[[' .. (moveInfo.type or 'Normal') .. '_(type)|<span style="color:#FFFFFF;">' .. (moveInfo.type or 'Normal') .. '</span>]]')
local catColor = categoryColors[moveInfo.category] or categoryColors.Status
row:tag('td')
:css('background-color', '#' .. catColor.bg)
:css('border', '2px solid #' .. catColor.border)
:wikitext('[[' .. (moveInfo.category or 'Status') .. ' moves|<span style="color:#FFFFFF;">' .. (moveInfo.category or 'Status') .. '</span>]]')
row:tag('td'):wikitext(moveInfo.power or '—')
row:tag('td'):wikitext(moveInfo.accuracy or '—')
row:tag('td'):wikitext(moveInfo.pp or '—')
end
table:tag('tr'):tag('td'):attr('colspan', '7')
:css('text-align', 'left')
:css('background-color', '#E0E0E0')
:css('padding', '10px')
:css('border-radius', '1px 1px 25px 25px')
:wikitext([=[
* '''Emboldened''' moves denote this Pokémon avails from a STAB bonus for it.
* ''Italicized'' moves are [[Broken_Moves_%26_Abilities|broken]]; see their individual pages for more information.
* All moves subsumed on this list are relearnable via the [[Move Relearner]]s if lost.
]=])
return tostring(html) .. '<br clear="all">'
end
function p.renderTMsHMs(frame)
local args = getArgs(frame)
local pokemonName = args[1] or args.pokemon
local primaryType = args.type1 or ""
local secondaryType = args.type2 or ""
local pokemon = getCachedLearnset(pokemonName)
local moveData = loadMoveData()
if not pokemon then return '' end
local tms = pokemon.tms or {}
local hms = pokemon.hms or {}
local html = mw.html.create('div')
local table = html:tag('table')
:css('width', '77%')
:css('text-align', 'center')
:css('margin', 'auto')
:css('border-radius', '25px')
:css('border', '3px solid #' .. getBorderColor(primaryType))
:css('background-color', '#F5F5F5')
:css('padding', '7px')
local header = table:tag('tr')
:css('background-color', '#' .. getHeaderColor(primaryType))
header:tag('th'):attr('colspan', '2'):wikitext('TM'):css('width', '11%'):css('border-top-left-radius', '25px')
header:tag('th'):wikitext('Move'):css('width', '18%')
header:tag('th'):wikitext('Type'):css('width', '17%')
header:tag('th'):wikitext('Category'):css('width', '19%')
header:tag('th'):wikitext('Base Power'):css('width', '26%')
header:tag('th'):wikitext('Accuracy'):css('width', '20%')
header:tag('th'):wikitext('PP'):css('width', '7%'):css('border-top-right-radius', '25px')
for _, moveName in ipairs(tms) do
local moveInfo = moveData[moveName] or {}
local row = table:tag('tr'):css('background-color', '#FFFFFF')
local tmNum = moveInfo.tm or ''
row:tag('td'):attr('colspan', '2'):wikitext(tmNum ~= '' and tmNum or 'TM')
local moveLink = '[[' .. moveName .. ']]'
if isSTAB(moveInfo.type, primaryType, secondaryType) and moveInfo.category ~= "Status" then
moveLink = "'''" .. moveLink .. "'''"
end
if moveInfo.broken == "Y" then
moveLink = "''" .. moveLink .. "''"
end
row:tag('td'):wikitext(moveLink)
local typeColor = typeColors[moveInfo.type] or typeColors.Normal
row:tag('td')
:css('background-color', '#' .. typeColor.bg)
:css('border', '2px solid #' .. typeColor.border)
:wikitext('[[' .. (moveInfo.type or 'Normal') .. '_(type)|<span style="color:#FFFFFF;">' .. (moveInfo.type or 'Normal') .. '</span>]]')
local catColor = categoryColors[moveInfo.category] or categoryColors.Status
row:tag('td')
:css('background-color', '#' .. catColor.bg)
:css('border', '2px solid #' .. catColor.border)
:wikitext('[[' .. (moveInfo.category or 'Status') .. ' moves|<span style="color:#FFFFFF;">' .. (moveInfo.category or 'Status') .. '</span>]]')
row:tag('td'):wikitext(moveInfo.power or '—')
row:tag('td'):wikitext(moveInfo.accuracy or '—')
row:tag('td'):wikitext(moveInfo.pp or '—')
end
for _, moveName in ipairs(hms) do
local moveInfo = moveData[moveName] or {}
local row = table:tag('tr'):css('background-color', '#FFFFCC')
row:tag('td'):attr('colspan', '2'):wikitext('HM'):css('font-weight', 'bold')
local moveLink = '[[' .. moveName .. ']]'
if isSTAB(moveInfo.type, primaryType, secondaryType) and moveInfo.category ~= "Status" then
moveLink = "'''" .. moveLink .. "'''"
end
if moveInfo.broken == "Y" then
moveLink = "''" .. moveLink .. "''"
end
row:tag('td'):wikitext(moveLink)
local typeColor = typeColors[moveInfo.type] or typeColors.Normal
row:tag('td')
:css('background-color', '#' .. typeColor.bg)
:css('border', '2px solid #' .. typeColor.border)
:wikitext('[[' .. (moveInfo.type or 'Normal') .. '_(type)|<span style="color:#FFFFFF;">' .. (moveInfo.type or 'Normal') .. '</span>]]')
local catColor = categoryColors[moveInfo.category] or categoryColors.Status
row:tag('td')
:css('background-color', '#' .. catColor.bg)
:css('border', '2px solid #' .. catColor.border)
:wikitext('[[' .. (moveInfo.category or 'Status') .. ' moves|<span style="color:#FFFFFF;">' .. (moveInfo.category or 'Status') .. '</span>]]')
row:tag('td'):wikitext(moveInfo.power or '—')
row:tag('td'):wikitext(moveInfo.accuracy or '—')
row:tag('td'):wikitext(moveInfo.pp or '—')
end
table:tag('tr'):tag('td'):attr('colspan', '8')
:css('text-align', 'left')
:css('background-color', '#E0E0E0')
:css('padding', '10px')
:css('border-radius', '1px 1px 25px 25px')
:wikitext([=[
* '''Emboldened''' moves denote that this Pokémon avails from a STAB bonus for it.
* ''Italicized'' moves are [[Broken_Moves_%26_Abilities|broken]]; see their individual pages for more information.
* Refer to [[TMs and HMs]] for information on each move's obtainability.
]=])
return tostring(html) .. '<br clear="all">'
end
function p.renderMoveTutors(frame)
local args = getArgs(frame)
local pokemonName = args[1] or args.pokemon
local primaryType = args.type1 or ""
local secondaryType = args.type2 or ""
local pokemon = getCachedLearnset(pokemonName)
local moveData = loadMoveData()
if not pokemon then return '' end
local moves = pokemon.move_tutors or {}
if #moves == 0 then
return ""
end
local html = mw.html.create('div')
local table = html:tag('table')
:css('width', '77%')
:css('text-align', 'center')
:css('margin', 'auto')
:css('border-radius', '25px')
:css('border', '3px solid #' .. getBorderColor(primaryType))
:css('background-color', '#F5F5F5')
:css('padding', '7px')
local header = table:tag('tr'):css('background-color', '#' .. getHeaderColor(primaryType))
header:tag('th'):wikitext('Move'):css('border-top-left-radius', '25px')
header:tag('th'):wikitext('Type')
header:tag('th'):wikitext('Category')
header:tag('th'):wikitext('Base Power')
header:tag('th'):wikitext('Accuracy')
header:tag('th'):wikitext('PP'):css('border-top-right-radius', '25px')
for _, moveName in ipairs(moves) do
local moveInfo = moveData[moveName] or {}
local row = table:tag('tr'):css('background-color', '#FFFFFF')
local moveLink = '[[' .. moveName .. ']]'
if isSTAB(moveInfo.type, primaryType, secondaryType) and moveInfo.category ~= "Status" then
moveLink = "'''" .. moveLink .. "'''"
end
if moveInfo.broken == "Y" then
moveLink = "''" .. moveLink .. "''"
end
row:tag('td'):wikitext(moveLink)
local typeColor = typeColors[moveInfo.type] or typeColors.Normal
row:tag('td')
:css('background-color', '#' .. typeColor.bg)
:css('border', '2px solid #' .. typeColor.border)
:wikitext('[[' .. (moveInfo.type or 'Normal') .. '_(type)|<span style="color:#FFFFFF;">' .. (moveInfo.type or 'Normal') .. '</span>]]')
local catColor = categoryColors[moveInfo.category] or categoryColors.Status
row:tag('td')
:css('background-color', '#' .. catColor.bg)
:css('border', '2px solid #' .. catColor.border)
:wikitext('[[' .. (moveInfo.category or 'Status') .. ' moves|<span style="color:#FFFFFF;">' .. (moveInfo.category or 'Status') .. '</span>]]')
row:tag('td'):wikitext(moveInfo.power or '—')
row:tag('td'):wikitext(moveInfo.accuracy or '—')
row:tag('td'):wikitext(moveInfo.pp or '—')
end
return tostring(html) .. '<br clear="all">'
end
function p.renderEggMoves(frame)
local args = getArgs(frame)
local pokemonName = args[1] or args.pokemon
local primaryType = args.type1 or ""
local secondaryType = args.type2 or ""
local pokemon = getCachedLearnset(pokemonName)
local moveData = loadMoveData()
if not pokemon then return '' end
local moves = pokemon.egg_moves or {}
if #moves == 0 then
return ""
end
local html = mw.html.create('div')
local table = html:tag('table')
:css('width', '77%')
:css('text-align', 'center')
:css('margin', 'auto')
:css('border-radius', '25px')
:css('border', '3px solid #' .. getBorderColor(primaryType))
:css('background-color', '#F5F5F5')
:css('padding', '7px')
local header = table:tag('tr'):css('background-color', '#' .. getHeaderColor(primaryType))
header:tag('th'):wikitext('Move'):css('width', '15%'):css('border-top-left-radius', '25px')
header:tag('th'):wikitext('Type'):css('width', '13%')
header:tag('th'):wikitext('Category'):css('width', '14%')
header:tag('th'):wikitext('Base Power'):css('width', '15%')
header:tag('th'):wikitext('Accuracy'):css('width', '17%')
header:tag('th'):wikitext('PP'):css('width', '18%'):css('border-top-right-radius', '25px')
for _, moveName in ipairs(moves) do
local moveInfo = moveData[moveName] or {}
local row = table:tag('tr'):css('background-color', '#FFFFFF')
local moveLink = '[[' .. moveName .. ']]'
if isSTAB(moveInfo.type, primaryType, secondaryType) and moveInfo.category ~= "Status" then
moveLink = "'''" .. moveLink .. "'''"
end
if moveInfo.broken == "Y" then
moveLink = "''" .. moveLink .. "''"
end
row:tag('td'):wikitext(moveLink)
local typeColor = typeColors[moveInfo.type] or typeColors.Normal
row:tag('td')
:css('background-color', '#' .. typeColor.bg)
:css('border', '2px solid #' .. typeColor.border)
:wikitext('[[' .. (moveInfo.type or 'Normal') .. '_(type)|<span style="color:#FFFFFF;">' .. (moveInfo.type or 'Normal') .. '</span>]]')
local catColor = categoryColors[moveInfo.category] or categoryColors.Status
row:tag('td')
:css('background-color', '#' .. catColor.bg)
:css('border', '2px solid #' .. catColor.border)
:wikitext('[[' .. (moveInfo.category or 'Status') .. ' moves|<span style="color:#FFFFFF;">' .. (moveInfo.category or 'Status') .. '</span>]]')
row:tag('td'):wikitext(moveInfo.power or '—')
row:tag('td'):wikitext(moveInfo.accuracy or '—')
row:tag('td'):wikitext(moveInfo.pp or '—')
end
table:tag('tr'):tag('td'):attr('colspan', '6')
:css('text-align', 'left')
:css('background-color', '#E0E0E0')
:css('padding', '10px')
:css('border-radius', '1px 1px 25px 25px')
:wikitext([=[
* '''Emboldened''' moves denote that this Pokémon avails from a STAB bonus for it.
* ''Italicized'' moves are [[Broken_Moves_%26_Abilities|broken]]; see their individual pages for more information.
* For more information on egg-move-tutors, refer to: [[Egg Moves]].
]=])
return tostring(html) .. '<br clear="all">'
end
function p.main(frame)
local args = getArgs(frame)
local pokemonName = args[1] or args.pokemon or ''
if pokemonName == '' then
return "<span style='color:red'>Usage: {{Learnsets|PokemonName}}</span>"
end
local primaryType = args.type1 or ''
local secondaryType = args.type2 or ''
if primaryType == '' then
local typeData = loadPokemonTypes()
local pt = typeData[pokemonName]
if pt then
primaryType = pt.type1 or ''
secondaryType = pt.type2 or ''
end
end
local function callRender(fn)
return fn(frame:newChild({
title = frame:getTitle(),
args = { pokemonName, type1 = primaryType, type2 = secondaryType },
}))
end
local poke, lsErr = getCachedLearnset(pokemonName)
if not poke then
return "<span style='color:red'>Data load error: " .. (lsErr or 'unknown') .. "</span>"
end
local out = {}
if #(poke.level_up or {}) > 0 then
table.insert(out, "== Level-Up Moves ==")
table.insert(out, callRender(p.renderLevelUp))
end
if #(poke.tms or {}) > 0 or #(poke.hms or {}) > 0 then
table.insert(out, "== TM/HM Moves ==")
table.insert(out, callRender(p.renderTMsHMs))
end
if #(poke.move_tutors or {}) > 0 then
table.insert(out, "== Move Tutor Moves ==")
table.insert(out, callRender(p.renderMoveTutors))
end
if #(poke.egg_moves or {}) > 0 then
table.insert(out, "== Egg Moves ==")
table.insert(out, callRender(p.renderEggMoves))
end
return table.concat(out, '\n')
end
return p