Please join this new Discord server!

Merge notice

If you are unable to edit, please stop in the Discord server and let us know.

Module:SkillTable

From Etrian Odyssey Wiki

Usage

{{#invoke:SkillTable|skill_table

--Mandatory Parameters--

|skill_name=English skill name
|skill_name_jp=Japanese skill name

|skill_type=In-game skill type
	(Class Skill, Weapon Skill, Passive Skill...)

|skill_desc=In-game skill description

|max_level=Maximum skill level excluding Boost and Grimoire Stone skills


--Optional Parameters—

|skill_name_hepburn=Romanized Japanese skill name

|skill_name_original=Original English skill name if this has changed in the HD games


|skill_desc_detail=In-game additional skill description if present

|desc_notes=Additional information about the skill

|prereq=List of prerequisite skills separated by "; "

|prereq_level=List of prerequisite skills level separated by "; "

|body_parts=Head, Arm and/or Leg

|skill_stats=Stat used by the skill
	(Level, HP, TP, STR, TEC, VIT, AGI, LUC, INT, WIS)


|level_label_override=Used to change the label "Level"
	This can be used to display how several instances of the same skill stack

|level_threshold=Used for grouping skill levels
	Used for Force Break and other skills that scale with the user's level

|tp_cost=TP Cost for every level separated by "; "
	The number of values used must match the value of max_level

|paramX=An additional parameter for the skill
	X must be 1, 2, 3, 4, 5, 6, 7, 8, 9 or 10
	Can be Damage, Accuracy, Ailment Rate, Speed Value, HP Recovery, Stat Increase,...

|paramX_type=Used to add symbols and/or text to the paramX values
	X must be 1, 2, 3, 4, 5, 6, 7, 8, 9 or 10

|paramX_value=ParamX value for each level separated by "; " without symbols or text
	X must be 1, 2, 3, 4, 5, 6, 7, 8, 9 or 10
	The number of values used must match the value of max_level

The paramX_value parameters will not display without a paramX value with the same X number. X values must be consecutive.

}}

Where to find in-game parameters in every EO games


Example

Skill Name
多元抜刀
Skill Type

Description

Desc Notes


  • Body part used: Arm, Leg, Head

  • Stat(s) used: TEC, STR

Prerequisite skill(s):

  • Prereq1, lv. 5
  • Prereq2, lv. 3
Level12345678910
TP Cost15
Damage140%145%150%155%160%165%175%190%250%
Sub-Effect 140%50%70%
HP Recovery (Base Value)3456789101112

local p = {}

function p.add_type_to_param(param,param_type)
	-- If the param_type is % and it doesn't start with "-", add it at the end of the number and before any "-"
	-- Else add param_type only at the end of the string
	if param_type == "%" and string.sub(param,1,1) ~= "-" then
		number_list = mw.text.split(param,"-")
		return table.concat(number_list, param_type .. "​-​") .. param_type
	else
		return param .. param_type
	end
end
	
function p.skill_table(frame)
	-- Adds anchors for linking
	local skill_name = "<span id='" .. frame.args["skill_name"] .. "'></span>" .. frame.args["skill_name"]
	
	-- Adds original name if there is a remake that changed it.
	if frame.args["skill_name_original"] ~= nil and frame.args["skill_name_original"] ~= "" then
		skill_name = skill_name .. " (" .. frame.args["skill_name_original"] .. ")"
	end
	
	-- Adds Japanese name below the English name
	if frame.args["skill_name_jp"] ~= nil and frame.args["skill_name_jp"] ~= "" then
		skill_name = skill_name .. "<br>"
	    -- Add the hepburn notation of the Japanese name if we have it
		if frame.args["skill_name_hepburn"] ~= nil and frame.args["skill_name_hepburn"] ~= "" then
			skill_name = skill_name .. "<span class=\"explain\" title=\"" .. frame.args["skill_name_hepburn"] .. ">" .. frame.args["skill_name_jp"] .. "</span>"
		else 
			skill_name = skill_name .. frame.args["skill_name_jp"]
		end
	end
	
	-- Frame arguments are strings, but we need this one as a number
    local max_lv = tonumber(frame.args["max_level"])
	
	-- "Real" level used to draw the table. Uses the max between max_level and the number of argument in param_x and tp_cost
	local nb_level = max_lv

	-- Split up TP cost input
	hasTp = frame.args["tp_cost"] ~= nil and frame.args["tp_cost"] ~= ""
    if hasTp then
        tp_costs = mw.text.split(frame.args["tp_cost"], ";%s")
    	nb_level = math.max(nb_level,#tp_costs)
    end
    
	-- Add in-game skill description
    local skill_desc = frame.args["skill_desc"]
    if frame.args["skill_desc_detail"] ~= nil and frame.args["skill_desc_detail"] ~= "" then
        skill_desc = skill_desc .. "<br><br>" .. frame.args["skill_desc_detail"]
    end
    skill_desc = skill_desc .. "\n"
    if frame.args["skill_type"] ~= nil and frame.args["skill_type"] ~= "" then
        skill_desc =  "''" .. frame.args["skill_type"] .. "''<br><br>" .. skill_desc
    end
    
    -- Add additional notes to skill description
    if frame.args["desc_notes"] ~= nil and frame.args["desc_notes"] ~= "" then
    	skill_desc = skill_desc .. "----\n" .. frame.args["desc_notes"] .. "\n"
    end
    
    -- Add body parts used to skill description
    if frame.args["body_parts"] ~= nil and frame.args["body_parts"] ~= "" then
    	skill_desc = skill_desc .. "----\n* '''Body part used:''' " .. frame.args["body_parts"] .. "\n"
    end
    
    -- Add stats used to skill description
    if frame.args["skill_stats"] ~= nil and frame.args["skill_stats"] ~= "" then
    	skill_desc = skill_desc .. "----\n* '''Stat(s) used:''' " .. frame.args["skill_stats"] .. "\n"
    end
    
    -- Split up prerequisite input, and add to skill description
    if frame.args["prereq"] ~= nil and frame.args["prereq"] ~= "" then
        prereq = mw.text.split(frame.args["prereq"], ";%s")
    	prereq_lv = mw.text.split(frame.args["prereq_level"], ";%s")
    	local prereq_data = ""
	    for i = 1, #prereq do
	    	prereq_data = prereq_data .. "\n* " .. prereq[i] .. ", lv. " .. prereq_lv[i]
	    end
	    skill_desc = skill_desc .. "----\n'''Prerequisite skill(s):'''" .. prereq_data
    end
    
	-- Split up param_x input and convert to store in "params" table for easier usage
    params = {}
    maxParam = 0
    for i = 1, 10 do
        if frame.args["param"..i] ~= nil and frame.args["param"..i] ~= "" then
        	maxParam = i
        	if frame.args["param"..i.."_type"] ~= nil then
	            params[i] = {
	                frame.args["param"..i],
	                frame.args["param"..i.."_type"],
	            	mw.text.split(frame.args["param"..i.."_value"], ";%s")
	            }
	        else
	        	params[i] = {
	                frame.args["param"..i],
	                "",
	            	mw.text.split(frame.args["param"..i.."_value"], ";%s")
	            }
	        end
	        nb_level = math.max(nb_level,#params[i][3])
        end
    end
    
	-- Convert level_threshold to list for easier usage
    level_threshold = nil
    if frame.args["level_threshold"] ~= nil and frame.args["level_threshold"] ~= "" then
    	level_threshold = mw.text.split(frame.args["level_threshold"], ";%s")
    end
    -- We can replace "Level" in the table by another string (for example "Instance") with the parmeter "level_label_override"
    level_label = "Level"
    if frame.args["level_label_override"] ~= nil and frame.args["level_label_override"] ~= "" then
    	level_label = frame.args["level_label_override"]
    end

	-- Start building the output table
    out_table = mw.html.create("table")
    	-- If the skill doesn't have 10 levels, make the table narrower, it looks better this way
        -- :addClass("wikitable"):css("width", math.min(math.max(100 / (10 / nb_level), 75), 100) .. "%")
        :addClass("wikitable"):css("width", "100%")
        :tag("tr")
            :tag("th"):attr("colspan", math.min(nb_level) + 1):wikitext(skill_name):done()
        :done()
            :tag("td"):attr("colspan", math.min(nb_level, 10) + 1):wikitext(skill_desc):done()
        :done():tag("tr")

    -- Checks if there is any need to add the level table (This table is unecessary for some Force Skill for example) 
	has_level_table = nb_level > 1 or hasTp or maxParam > 0
	
	if has_level_table then 
		numberOfRow = math.ceil(nb_level / 10)
	    -- Loop for skills with levels up to 20
		for rowId = 1, numberOfRow do
			out_table:tag("th"):css("width", "20%"):wikitext(level_label):done()
			-- Add level headings
		    for i = 1 + (10 * (rowId - 1)), math.min(nb_level, 10 * rowId) do
		    	level = i
		    	if level_threshold ~= nil then
		    		level = level_threshold[i]
		    	end
				if i > max_lv then
		        	out_table:tag("th"):css("width", (80 / math.min(nb_level, 10)) .."%"):css("background-color", "#b54f0a"):wikitext(level):done()
		        else
		        	out_table:tag("th"):css("width", (80 / math.min(nb_level, 10)) .."%"):wikitext(level):done()
		        end
		    end
		
			-- If skill has a TP cost, add it to the table
		    if tp_costs ~= nil then
		        local tr = out_table:tag("tr")
		            :tag("th"):wikitext("TP Cost"):done()
		        -- Loop through each item and merge identical adjacent values into a single cell
		        local colspan = 0
		        local prev_value = tp_costs[1 + (10 * (rowId - 1))]
		        for i = 1 + (10 * (rowId - 1)), math.min(nb_level, 10 * rowId) do
		        	if prev_value == tp_costs[i] then
		        		colspan = colspan + 1
		        	else
		        		tr:tag("td"):css("text-align", "center"):attr("colspan", colspan):wikitext(tp_costs[i-1]):done()
		        		prev_value = tp_costs[i]
		        		colspan = 1
		        	end
		        end
		        tr:tag("td"):css("text-align", "center"):attr("colspan", colspan):wikitext(tp_costs[math.min(nb_level, 10 * rowId)]):done()
		        tr:done()
		    end
		
			-- For each parameter input, add to the table
		    for i = 1, #params do
		        local tr = out_table:tag("tr")
		            :tag("th"):wikitext(params[i][1]):done()
		        -- Loop through each item and merge identical adjacent values into a single cell
				local colspan = 0
		        local prev_value = params[i][3][1 + (10 * (rowId - 1))]
		        for j = 1 + (10 * (rowId - 1)), math.min(nb_level, 10 * rowId) do
		        	if prev_value == params[i][3][j] then
		        		colspan = colspan + 1
		        	else
		        		tr:tag("td"):css("text-align", "center"):attr("colspan", colspan):wikitext(p.add_type_to_param(params[i][3][j-1], params[i][2])):done()
		        		prev_value = params[i][3][j]
		        		colspan = 1
		        	end
		        end
				tr:tag("td"):css("text-align", "center"):attr("colspan", colspan):wikitext(p.add_type_to_param(params[i][3][math.min(nb_level, 10 * rowId)], params[i][2])):done()
		        tr:done()
		    end
		end
	end

    return out_table:done()
end

return p