Module:SkillTable

From Elwiki
Revision as of 10:30, 19 January 2025 by Shironsaki (talk | contribs)

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

require('Module:CommonFunctions')
local getArgs = require('Module:Arguments').getArgs
local p = {}

-- Main process
function p.main(frame)
    local args = getArgs(frame);

    -- Main block
    local skill_table = mw.html.create('div'):addClass('related-skills shown skill-table');

    local iterations = args['i'];
    if iterations == nil then
        iterations = 4
    end

    -- Predefine the subpage for mod skills.
    local l_mod_subpage = '/Mod'

    local lang = args.lang and ('/' .. args.lang) or ''

    -- Split into two tables for easier maintenance of the code.
    local skills = args.skills;
    if (skills == nil) then
        skills = args[1]
    end
    local skills = split(skills, ';')
    local image_name_table = {}
    local skill_name_table = {}
    local index = 1
    for k, v in ipairs(skills) do
        v = trim(v);
        if (index % 2 == 0) then
            -- Skill names
            table.insert(skill_name_table, v ~= '' and v or 'Unreleased');
        else
            -- Image names
            table.insert(image_name_table, v);
        end
        index = index + 1
    end

    -- Iterate through rows
    local i = 1;
    -- Spawn a table row.
    local row = skill_table:tag('div'):attr('data-type', 'table-row');
    while i <= #skill_name_table do
        local image = image_name_table[i];
        local name = skill_name_table[i];
        local lock = ''
        local mod_subpage = ''
        local cube = ''
        local prefix = ''
        local suffix = ''

        -- Locked skills
        if (string.find(name, ' Locked-')) then
            local lock_arg = name:gsub('.*%sLocked%-', '');
            name = name:gsub('%sLocked%-.*', '');
            lock = frame:expandTemplate{
                title = 'Locked Skill',
                args = {lock_arg}
            }
        end

        -- Cube
        if (string.find(name, 'ModCube')) then
            local o, j = string.find(name, 'ModCube[0-9]');
            local cube_arg = string.sub(name, j);
            name = name:gsub('%sModCube[0-9]', '');
            cube = frame:expandTemplate{
                title = 'Mod Cube',
                args = {cube_arg}
            }
        end

        -- Check if the user wants to render a header or not.
        local is_header = false;
        if (string.starts(image, '--')) then
            is_header = true;
            table.remove(image_name_table, i);
            table.remove(skill_name_table, i);
        end

        -- Make chunks of skill boxes based on user preference (default 4).
        if ((i-1) % iterations == 0 or image_name_table[i-1] == nil) then
            row = skill_table:tag('div'):attr('data-type', 'table-row');
        end

        -- Spawn regular cells
        if not (is_header) then
            -- Split images for situations with multiple icons.
            local full_name = name;
            image = split(image, '\\');
            -- Remove prefix, suffix and full name syntax from the display name
            name = split(name:gsub('%s?#%s?.*', ''):gsub('^.*%+%+', ''), '\\');
            local index = 1;

            local image_cell = row:tag('div'):attr('data-type', 'table-cell');
            if (args.skill_columns ~= nil) then
                image_cell:attr('style', 'grid-template-columns: repeat(' .. args.skill_columns .. ', auto)');
            end

            -- Set a display name if there is more than one image.
            if (#image > 1 and #name > 1) then
                image_cell:addClass('skill-columns');
                local name_match = full_name:match('%s?#%s?(.*)');
                if (name_match ~= nil) then
                    full_name = name_match;
                else
                    full_name = name[1]
                end
            end

            -- Iterate through split icons.
            while index <= #image do
                image[index] = trim(image[index]);
                name[index] = trim(name[index]);

-- Define a table with the E Mod base skills
local emods = {
    'Flame Geyser', 'Unlimited Blade', 'Gust Storm', 'Lightning Bolt',
    'Perfect Storm', 'Aero Tornado', 'Power Assault', 'Seven Burst',
    'Illusion Stinger', 'Guardian', 'Scare Chase', 'Aceldama',
    'Falling Dragon', 'Shadoweave', 'Wild Shock', 'Mega Buster',
    'Void Breaker', 'Particle Accelerator', 'Flick Shot', 'Soul Infest',
    'Barbecue!', 'M-3 Flamethrower', 'Explosion', 'Sakrosankt Zertreten',
    'Suplen', 'Splashy Splashy', 'Dark Moon', 'Quick Strike',
    'Spodumene', 'Rapid Burst'
}


            -- Mod skills
            if (string.find(name[index], '/Mod')) then
                name[index] = name[index]:gsub('%/Mod', '');
                mod_subpage = l_mod_subpage;
            else
                mod_subpage = '';
            end

            -- Decide which icon to spawn based on being a [Mod] or not.
            if (mod_subpage == '') then
                local found = false
                for emod, _ in pairs(emods) do
                    if (string.find(name[index], emod)) then
                        if not found then
                            image_cell:wikitext(frame:expandTemplate{
                                title = 'Force',
                                args = {image[index], link = name[index]}
                            });
                            found = true
                        end
                        break
                    end
                end
                if not found then
                    image_cell:wikitext('[[File:' .. image[index] .. '|link=' .. name[index] .. ']]')
                end
            else
                image_cell:wikitext(frame:expandTemplate{
                    title = 'Force',
                    args = {image[index], link = name[index]}
                });
            end
            index = index + 1
            end
            
            if (full_name:match('/Mod')) then
                full_name = full_name:gsub('/Mod', '');
                mod_subpage = l_mod_subpage
            end

            -- Prefixes and suffixes
            if (full_name:match('++')) then
                prefix = full_name:match('^(.*)%+%+');
                full_name = trim(full_name:gsub('^.*%+%+', ''));
            end

            if (full_name:match('##')) then
                suffix = full_name:match('##(.*)$');
                full_name = trim(full_name:gsub('##.*$', ''));
            end

            -- Spawn a name cell.
            local link = full_name .. mod_subpage .. lang
            local name_cell = row:tag('div'):attr('data-type', 'table-cell');
            local skill_wrap = name_cell:tag('div'):addClass('skill-wrap');
            skill_wrap:wikitext('[[' .. link .. '|.]]');

            -- Remove (Elsword), (Elesis), etc. in display name
            local display_name = full_name:gsub("%s%([%w%s%/]+%)", "");
            if not (mod_subpage == '') then
                display_name = '[Mod] ' .. display_name;
            end

            -- Remove the name of the Master Skill
            if (args.no_mc_names == 'true') then
                display_name = display_name:gsub('.*%/Stage%s([0-9])', 'Stage %1');
            end
            
            skill_wrap:tag('div'):addClass('skill-wrap-text'):wikitext('[[' .. link .. '|' .. prefix .. display_name .. ']] ' .. suffix .. lock .. cube );
            
            -- If a header is detected, it will not interrupt chunking.
            i = i + 1
        else
            -- Spawn a header
            local color = image:gsub('%-%-', '');
            -- Set color, either hardcoded or from the ColorSel template.
            if not (string.find(image, "#") or string.find(image, "rgb(") or string.find(image, "rgba(")) then
                color = frame:expandTemplate{
                    title = 'ColorSel',
                    args = {'Character', color}
                }
            end
            row = skill_table:tag('div'):attr('data-type', 'table-row'):attr('style', 'background-color: ' .. color):addClass('textfloat table-head');
            if (color == '&#35;') then
                row:addClass('related-title')
            end
            row:tag('div'):attr('data-type', 'table-head'):wikitext(name);
        end
    end

    -- Output point
    return tostring(skill_table);

end

return p