Module:PokemonSpawnData: Difference between revisions

From Pokemon Revolution Online Wiki
Jump to navigation Jump to search
Cae (talk | contribs)
No edit summary
Cae (talk | contribs)
No edit summary
Line 21: Line 21:


-- Load an External Data source and return true if at least one row was found.
-- Load an External Data source and return true if at least one row was found.
-- #get_file_data accumulates rows across calls, so we compare the table size
-- before and after to detect whether THIS call added any rows.
local function loadFileData(frame, params)
local function loadFileData(frame, params)
     local callParams = { [1] = 'source=' .. (params.source or 'data') }
     local callParams = { [1] = 'source=' .. (params.source or 'data') }
Line 26: Line 28:
         if k ~= 'source' then callParams[k] = v end
         if k ~= 'source' then callParams[k] = v end
     end
     end
    local before = tonumber(frame:callParserFunction('#external_table_size', { 'area' })) or 0
     frame:callParserFunction('#get_file_data', callParams)
     frame:callParserFunction('#get_file_data', callParams)
     local area = frame:callParserFunction('#external_value', { 'area' })
     local after  = tonumber(frame:callParserFunction('#external_table_size', { 'area' })) or 0
     return area ~= nil and area ~= ''
     return after > before
end
end


Line 36: Line 39:


local function renderLandTable(frame)
local function renderLandTable(frame)
    local border    = getVar(frame, 'border')
    local background = getVar(frame, 'background')
    local cell      = getVar(frame, 'cell')
     local rows = frame:callParserFunction('#display_external_table', {
     local rows = frame:callParserFunction('#display_external_table', {
         [1]  = 'template=PokemonLandDataRow',
         [1]  = 'template=PokemonLandDataRow',
Line 47: Line 46:
     })
     })


     local t = mw.html.create('table')
    -- Pure wikitext — {{#var:border}} etc. are expanded by MediaWiki at render
        :attr('align', 'left')
    -- time, so the Trichrome colours work correctly without Lua string values.
        :css('width', '85%')
     local header = [=[
        :css('max-width', '90%')
<table align="left" style="width:85%;max-width:90%;text-align:center;margin:auto;border-radius:15px;border:3px solid {{#var:border}};background-color:{{#var:background}};padding:7px;">
        :css('text-align', 'center')
<tr style="background-color:{{#var:cell}};color:{{#var:border}};">
        :css('margin', 'auto')
<th style="border-top-left-radius:25px;width:15%;border:1px solid {{#var:border}};">Location</th>
        :css('border-radius', '15px')
<th style="width:7%;border:1px solid {{#var:border}};">Levels</th>
        :css('border', '3px solid ' .. border)
<th colspan="3" style="width:17%;border:1px solid {{#var:border}};">[[Pokétime|<span style="color:{{#var:border}};">Times</span>]]</th>
        :css('background-color', background)
<th style="width:20%;border:1px solid {{#var:border}};">Held Item</th>
        :css('padding', '7px')
<th style="border-top-right-radius:25px;width:10%;border:1px solid {{#var:border}};">[[List of Pokémon by Rarity Tier|<span style="color:{{#var:border}};">Rarity Tier</span>]]</th>
</tr>]=]


    -- Header row
     local footer = [=[
     local hRow = t:tag('tr')
<tr><td colspan="8" style="text-align:left;border-radius:1px 1px 25px 25px;border:1px solid {{#var:border}};background-color:{{#var:cell}};">
        :css('background-color', cell)
<p style="margin-top:8px;margin-left:10px;"><ul>
        :css('color', border)
    hRow:tag('th'):wikitext('Location')
        :css('border-top-left-radius', '25px')
        :css('width', '15%')
        :css('border', '1px solid ' .. border)
    hRow:tag('th'):wikitext('Levels')
        :css('width', '7%')
        :css('border', '1px solid ' .. border)
    hRow:tag('th'):attr('colspan', '3')
        :wikitext('[[Pokétime|<span style="color:' .. border .. ';">Times</span>]]')
        :css('width', '17%')
        :css('border', '1px solid ' .. border)
    hRow:tag('th'):wikitext('Held Item')
        :css('width', '20%')
        :css('border', '1px solid ' .. border)
    hRow:tag('th')
        :wikitext('[[List of Pokémon by Rarity Tier|<span style="color:' .. border .. ';">Rarity Tier</span>]]')
        :css('border-top-right-radius', '25px')
        :css('width', '10%')
        :css('border', '1px solid ' .. border)
 
    -- Data rows (rendered by #display_external_table via PokemonLandDataRow)
    -- We inject them as raw wikitext between the header and footer.
    local footer = t:tag('tr'):tag('td')
        :attr('colspan', '8')
        :css('text-align', 'left')
        :css('border-radius', '1px 1px 25px 25px')
        :css('border', '1px solid ' .. border)
        :css('background-color', cell)
        :wikitext([=[<p style="margin-top:8px;margin-left:10px;"><ul>
<li><span style="color:#FF00BF;font-weight:bold;">Pink-colored</span> areas denote that this spawn is [[membership]]-exclusive</li>
<li><span style="color:#FF00BF;font-weight:bold;">Pink-colored</span> areas denote that this spawn is [[membership]]-exclusive</li>
<li>'''Emboldened''' levels indicate they are isolatable with the [[Repel trick]]</li>
<li>'''Emboldened''' levels indicate they are isolatable with the [[Repel trick]]</li>
</ul></p>]=])
</ul></p></td></tr>
 
</table><br clear="all">]=]
    -- Splice the dynamic rows between header and footer
    local tableHtml = tostring(t)
    -- Insert rows just before the closing </table>
    tableHtml = tableHtml:gsub('</table>$', rows .. '</table>')


     return tableHtml .. '<br clear="all">'
     return header .. rows .. footer
end
end



Revision as of 07:12, 8 March 2026

Documentation for this module may be created at Module:PokemonSpawnData/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

-- Read a parser variable set by {{Trichrome}} (border, background, cell, etc.)
local function getVar(frame, name)
    return frame:callParserFunction('#var', { name }) or ''
end

-- Load an External Data source and return true if at least one row was found.
-- #get_file_data accumulates rows across calls, so we compare the table size
-- before and after to detect whether THIS call added any rows.
local function loadFileData(frame, params)
    local callParams = { [1] = 'source=' .. (params.source or 'data') }
    for k, v in pairs(params) do
        if k ~= 'source' then callParams[k] = v end
    end
    local before = tonumber(frame:callParserFunction('#external_table_size', { 'area' })) or 0
    frame:callParserFunction('#get_file_data', callParams)
    local after  = tonumber(frame:callParserFunction('#external_table_size', { 'area' })) or 0
    return after > before
end

-- ---------------------------------------------------------------------------
-- Land spawn table
-- ---------------------------------------------------------------------------

local function renderLandTable(frame)
    local rows = frame:callParserFunction('#display_external_table', {
        [1]  = 'template=PokemonLandDataRow',
        data = 'area=area,member=member,number=number,name=name,'
            .. 'morning=morning,day=day,night=night,'
            .. 'item=item,rarity=rarity,minlvl=minlvl,maxlvl=maxlvl',
    })

    -- Pure wikitext — {{#var:border}} etc. are expanded by MediaWiki at render
    -- time, so the Trichrome colours work correctly without Lua string values.
    local header = [=[
<table align="left" style="width:85%;max-width:90%;text-align:center;margin:auto;border-radius:15px;border:3px solid {{#var:border}};background-color:{{#var:background}};padding:7px;">
<tr style="background-color:{{#var:cell}};color:{{#var:border}};">
<th style="border-top-left-radius:25px;width:15%;border:1px solid {{#var:border}};">Location</th>
<th style="width:7%;border:1px solid {{#var:border}};">Levels</th>
<th colspan="3" style="width:17%;border:1px solid {{#var:border}};">[[Pokétime|<span style="color:{{#var:border}};">Times</span>]]</th>
<th style="width:20%;border:1px solid {{#var:border}};">Held Item</th>
<th style="border-top-right-radius:25px;width:10%;border:1px solid {{#var:border}};">[[List of Pokémon by Rarity Tier|<span style="color:{{#var:border}};">Rarity Tier</span>]]</th>
</tr>]=]

    local footer = [=[
<tr><td colspan="8" style="text-align:left;border-radius:1px 1px 25px 25px;border:1px solid {{#var:border}};background-color:{{#var:cell}};">
<p style="margin-top:8px;margin-left:10px;"><ul>
<li><span style="color:#FF00BF;font-weight:bold;">Pink-colored</span> areas denote that this spawn is [[membership]]-exclusive</li>
<li>'''Emboldened''' levels indicate they are isolatable with the [[Repel trick]]</li>
</ul></p></td></tr>
</table><br clear="all">]=]

    return header .. rows .. footer
end

-- ---------------------------------------------------------------------------
-- Surf/Fishing spawn table
-- ---------------------------------------------------------------------------

local WATER_DARK  = '{{Water_color_dark}}'
local WATER_BG    = '#{{Water_color}}'
local WATER_LIGHT = '#{{Water_color_light}}'

local function renderSurfTable(frame)
    local rows = frame:callParserFunction('#display_external_table', {
        [1]  = 'template=PokemonSurfingDataRow',
        data = 'area=area,number=number,name=name,time=time,'
            .. 'minlvl=minlvl,maxlvl=maxlvl,item=item,rarity=rarity,'
            .. 'rod=rod,fishable=fishable,member=member',
    })

    local header = [=[
<table align="left" style="width:88%;max-width:100%;text-align:center;margin:auto;border-radius:15px;border:4px solid #{{Water_color_dark}};background-color:#{{Water_color}};padding:7px;">
<tr><td colspan="8"><div style="margin:auto;width:53px;height:53px;border:3px solid #{{Water_color_dark}};border-radius:40px;background-color:#{{Water_color_light}};padding:5px;">[[File:PikachuSurf.png]]</div></td></tr>
<tr style="background-color:#{{Water_color_light}};">
<th scope="col" style="border-radius:15px 1px 1px 1px;width:15%;border:1px solid #{{Water_color_dark}};color:#{{Water_color_dark}};">Location</th>
<th scope="col" style="width:7%;border:1px solid #{{Water_color_dark}};color:#{{Water_color_dark}};">Levels</th>
<th colspan="3" scope="col" style="width:6%;border:1px solid #{{Water_color_dark}};">[[Pokétime|<span style="color:#{{Water_color_dark}};">Times</span>]]</th>
<th style="width:10%;border:1px solid #{{Water_color_dark}};color:#{{Water_color_dark}};">Held Item</th>
<th style="width:7%;border:1px solid #{{Water_color_dark}};color:#{{Water_color_dark}};">Rod</th>
<th style="border-radius:1px 15px 1px 1px;width:10%;border:1px solid #{{Water_color_dark}};">[[List of Pokémon by Rarity Tier|<span style="color:#{{Water_color_dark}};">Rarity Tier</span>]]</th>
</tr>]=]

    local footer = [=[
<tr><td colspan="9" style="text-align:left;border-radius:1px 1px 25px 25px;border:1px solid #{{Water_color_dark}};background-color:#{{Water_color_light}};"><ul style="margin-top:8px;margin-left:12px;padding:5px;">
<li>All rows with a fishing rod indicate that its corresponding Pokémon can also be [[Fishing|fished]] with the rod tier shown</li>
<li><span style="color:#FF00BF;font-weight:bold;">Pink-colored</span> areas denote that this area or inhabiting spawn is strictly [[membership]]-exclusive</li>
<li>'''Emboldened''' levels indicate they are isolatable with the [[Repel trick]]</li>
</ul></td></tr>
</table><br clear="all">]=]

    return header .. rows .. footer
end

-- ---------------------------------------------------------------------------
-- main()
-- ---------------------------------------------------------------------------

function p.main(frame)
    local args        = getArgs(frame)
    local pokemonName = args[1] or args.Name
                     or frame:callParserFunction('PAGENAME', {}) or ''

    local out     = {}
    local hasLand = false
    local hasSurf = false

    -- ── Land spawns ──────────────────────────────────────────────────────────
    hasLand = loadFileData(frame, {
        source        = 'spawns',
        ['file name'] = 'land_spawns.csv',
        format        = 'CSV with header',
        filters       = 'Pokemon=' .. pokemonName,
        data          = 'area=Map,member=Member,number=DexID,name=Pokemon,'
                     .. 'morning=Morning,day=Day,night=Night,'
                     .. 'item=Item,rarity=Tier,minlvl=MinLvl,maxlvl=MaxLvl',
    })
    if hasLand then
        table.insert(out, renderLandTable(frame))
    end

    -- ── Surf / Fishing spawns ─────────────────────────────────────────────────
    hasSurf = loadFileData(frame, {
        source        = 'spawns',
        ['file name'] = 'surf_spawns.json',
        format        = 'JSON',
        filters       = 'Pokemon=' .. pokemonName .. ',FishingOnly=0',
        data          = 'area=Map,member=MemberOnly,number=MonsterID,name=Pokemon,'
                     .. 'time=Daytime,item=Item,rarity=Tier,'
                     .. 'minlvl=MinLvl,maxlvl=MaxLvl,rod=RequiredRod,fishable=Fishing',
    })
    if hasSurf then
        table.insert(out, renderSurfTable(frame))
    end

    -- ── No spawns ─────────────────────────────────────────────────────────────
    if not hasLand and not hasSurf then
        table.insert(out,
            "<div style='padding:8px;font-style:italic;'>"
         .. pokemonName
         .. " has no wild spawn locations.</div>"
        )
    end

    return table.concat(out, '\n')
end

return p