Module:Survivors

From Risk of Rain 2 Wiki
Jump to navigation Jump to search

Survivors contains details of Risk of Rain 2's survivors.

Documentation

Package items

survivors.SurvivorExpansion(frame) (function)
Builds a template for a survivors's expansion.
Parameter: frame Frame object (table)
Returns: Preprocessed wikitext of expansion template. (string)
survivors.SurvivorExpansionNT(frame) (function)
Builds a template for a survivors's expansion without a tooltip.
Parameter: frame Frame object (table)
Returns: Preprocessed wikitext of expansion template. (string)
survivors.SurvivorGallery(frame) (function)
Builds a gallery of all survivors in alphabetical order.
Parameter: frame Frame object (table)
Returns: Preprocessed wikitext of resultant gallery (string)
Usage: p.SurvivorGallery(mw.getCurrentFrame()) or {{#invoke:Survivors|SurvivorGallery}}
survivors.SurvivorGalleryGameOrder(frame) (function)
Builds a gallery of all survivors.
Parameter: frame Frame object (table)
Returns: Preprocessed wikitext of resultant gallery (string)
Usage: p.SurvivorGalleryGameOrder(mw.getCurrentFrame()) or {{#invoke:Survivors|SurvivorGalleryGameOrder}}
survivors.SurvivorInfobox(frame) (function)
Builds a survivor infobox.
Parameter: frame Frame object (table)
Returns: Preprocessed wikitext of resultant infobox (string)
Usage: p.SurvivorInfobox(mw.getCurrentFrame()) or {{#invoke:Survivors|SurvivorInfobox}}
survivors.BuildAllSurvivorsTable(frame) (function)
Builds a wikitable of all survivors.
Parameter: frame Frame object (table)
Returns: Preprocessed wikitext of resultant wikitable (string)
Usage: p.BuildAllSurvivorsTable(mw.getCurrentFrame()) or {{#invoke:Survivors|BuildAllSurvivorsTable}}


---	'''Survivors''' contains details of Risk of Rain 2's survivors.
--	
--	@module		survivors
--	@alias		p
--	@author		[[User:Thundermaker300]]
--	@attribution	All who helped to update survivor infoboxes
--	@require	[[Module:Survivors/Data]]
--	@release	stable
--	<nowiki>

local SurvivorData = mw.loadData('Module:Survivors/Data').Survivors

local p = {}
table.unpack = unpack	-- pre-Lua 5.3 table library does not have unpack function

function pairsByKeys (t, f) -- Sort tables, copied from https://www.lua.org/pil/19.3.html
  local a = {}
  for n in pairs(t) do table.insert(a, n) end
  table.sort(a, f)
  local i = 0      -- iterator variable
  local iter = function ()   -- iterator function
    i = i + 1
    if a[i] == nil then return nil
    else return a[i], t[a[i]]
    end
  end
  return iter
end

---	Builds a template for a survivors's expansion.
--	@function		p.SurvivorExpansion
--	@param			{table} frame Frame object
--	@return			{string} Preprocessed wikitext of expansion template.
function p.SurvivorExpansion(frame)
	local data = SurvivorData[frame.args[1]]
	if data == nil then
		return ""
	end
	return data.Expansion and frame:preprocess("{{" .. data.Expansion .. "|" .. data.Name .. "}}") or ""
end

---	Builds a template for a survivors's expansion without a tooltip.
--	@function		p.SurvivorExpansionNT
--	@param			{table} frame Frame object
--	@return			{string} Preprocessed wikitext of expansion template.
function p.SurvivorExpansionNT(frame)
	local data = SurvivorData[frame.args[1]]
	if data == nil then
		return ""
	end
	return data.Expansion and frame:preprocess("{{" .. data.Expansion .. "|" .. data.Name .. "|noTooltip=true" .. "}}") or ""
end

local gallery = "<gallery class=\"nobackground\" widths=\"128px\" heights=\"128px\">%s</gallery>"
local galleryElement = "File:%s|link=%s|{{SurvivorLink|%s|displayIcon=false}}\n"

---	Builds a gallery of all survivors in alphabetical order.
--	@function		p.SurvivorGallery
--	@param			{table} frame Frame object
--	@return			{string} Preprocessed wikitext of resultant gallery
--	@usage			p.SurvivorGallery(mw.getCurrentFrame()) or {{#invoke:Survivors|SurvivorGallery}}
function p.SurvivorGallery(frame)
	local str = ""
	for _, entry in pairsByKeys(SurvivorData) do
		str = str .. string.format(galleryElement, entry.Image, entry.Name, entry.Name)
	end
	return frame:preprocess(string.format(gallery, str))
end

---	Builds a gallery of all survivors.
--	@function		p.SurvivorGalleryGameOrder
--	@param			{table} frame Frame object
--	@return			{string} Preprocessed wikitext of resultant gallery
--	@usage			p.SurvivorGalleryGameOrder(mw.getCurrentFrame()) or {{#invoke:Survivors|SurvivorGalleryGameOrder}}
function p.SurvivorGalleryGameOrder(frame)
	local str = ""
	for _, entry in pairs(SurvivorData) do
		str = str .. string.format(galleryElement, entry.Image, entry.Name, entry.Name)
	end
	return frame:preprocess(string.format(gallery, str))
end


local infobox_template_survivor = [=[
{{Survivor
| title = %s
| image = %s
| desc = %s
| class = %s
| health = %s (+%s per level)
| damage = %s (+%s per level)
| regen = [[File:Drizzle.png|18px|link=Difficulty]] {{Color|h|%s/s (%s per level)}}<br>[[File:Rainstorm.png|18px|link=Difficulty]] {{Color|d|%s/s (%s per level)}}<br>[[File:Monsoon.png|18px|link=Difficulty]] {{Color|hp|%s/s (%s per level)}}
| speed = %s m/s
| armor = %s ([[File:Drizzle.png|18px|link=Difficulty]] {{Color|h|%s}})
| unlock = %s
| umbra = %s
| ending = Escaped : %s

Vanished : %s
}}]=]

---	Builds a survivor infobox.
--	@function		p.SurvivorInfobox
--	@param			{table} frame Frame object
--	@return			{string} Preprocessed wikitext of resultant infobox
--	@usage			p.SurvivorInfobox(mw.getCurrentFrame()) or {{#invoke:Survivors|SurvivorInfobox}}
function p.SurvivorInfobox(frame)
	local data = SurvivorData[frame.args[1]]
	if data == nil then
		return error("Survivors.SurvivorInfobox: Invalid survivor!")
	end
	return frame:preprocess(string.format(
		infobox_template_survivor,
		data.Name or "",
		data.Image or "",
		data.Description or "",
		data.Class or "",
		data.BaseHealth or 0,
		data.ScalingHealth or 0,
		data.BaseDamage or 0,
		data.ScalingDamage or 0,
		-- Drizzle
		(data.BaseHealthRegen or 0) * 1.5,
		(data.ScalingHealthRegen > 0 and "+" or "") .. (data.ScalingHealthRegen or 0) * 1.5,
		-- Rainstorm
		(data.BaseHealthRegen or 0),
		(data.ScalingHealthRegen > 0 and "+" or "") ..(data.ScalingHealthRegen or 0),
		-- Monsoon
		(data.BaseHealthRegen or 0) * 0.6,
		(data.ScalingHealthRegen > 0 and "+" or "") .. (data.ScalingHealthRegen or 0) * 0.6,
		
		data.BaseSpeed or 0,
		data.BaseArmor or 0,
		(data.BaseArmor or 0) + 70,
		data.Unlock and ("[[" .. data.Unlock .. "]]") or "",
		data.Umbra or data.Name,
		data.PhraseEscape,
		data.PhraseVanish
	))
end


---	Builds a wikitable of all survivors.
--	@function		p.BuildAllSurvivorsTable
--	@param			{table} frame Frame object
--	@return			{string} Preprocessed wikitext of resultant wikitable
--	@usage			p.BuildAllSurvivorsTable(mw.getCurrentFrame()) or {{#invoke:Survivors|BuildAllSurvivorsTable}}
function p.BuildAllSurvivorsTable(frame)
	local wikitable = { [=[
{| class="wikitable sortable"
! Image
! Name
! data-sort-type="number" | Health
! data-sort-type="number" | Damage
! data-sort-type="number" | Health Regen
! Class
! data-sort-type="number" | Armor
! data-sort-type="number" | Movement Speed
! data-sort-type="number" | Mass
|-]=]
}
	
	-- Corresponding to key names in /Data
	-- Order will determine which where data will appear in below format string
	local keyNames = {
		"Image", "Name", "Name", "Health", 
		"Damage", "Regen", "Class", "BaseArmor", "BaseSpeed", "Mass",
	}
	
	-- Table row looks like format string: "| [[File:%s]] || [[%s|%s]]%s || %s || ... || %s"
	-- Would eventually become something like:
	-- | [[File:Commando.png]] || [[Commando|Commando]]{{SotV}} || 1000 || 300 || 12 || 2.4 || N/A || N/A || N/A || 12
	local tableRow = (function()
		local temp = { "| [[File:%s|40px|link=%s]] || {{SurvivorLink|%s|displayIcon=false}}" }
		
		-- For function chaining syntax
		temp.remove = function(self, elem)
			table.remove(self, #self)
			return self
		end
		
		for _, key in ipairs(keyNames) do
			table.insert(temp, " || %s")
		end
		-- Removing extra columns since first two columns have custom formatting
		temp:remove():remove():remove()
		
		table.insert(temp, "\n|-")
		return table.concat(temp, "")
	end)()
	
	for _, survivorEntry in pairsByKeys(SurvivorData) do
		local keyValues = {}
		for _, key in pairs(keyNames) do
			if (key == "Health") then
				table.insert(keyValues, (survivorEntry["BaseHealth"] or "N/A") .. " (+" .. (survivorEntry["ScalingHealth"] or "N/A") .. ")" )
			elseif (key == "Damage") then
				table.insert(keyValues, (survivorEntry["BaseDamage"] or "N/A") .. " (+" .. (survivorEntry["ScalingDamage"] or "N/A") .. ")" )
			elseif (key == "Regen") then
				table.insert(keyValues, (survivorEntry["BaseHealthRegen"] or "0") .. "/s (" .. (survivorEntry["ScalingHealthRegen"] > 0 and "+" or "") .. "" .. (survivorEntry["ScalingHealthRegen"] or "0") .. "/s)" )
			elseif (key == "BaseSpeed") then
				table.insert(keyValues, (survivorEntry["BaseSpeed"] or "0") .. " m/s")
			else
				table.insert(keyValues, survivorEntry[key] or "N/A")
			end
		end
		table.insert(wikitable, tableRow:format(table.unpack(keyValues)))
	end
	
	table.insert(wikitable, "|}")
	
	return frame:preprocess(table.concat(wikitable, "\n"))
end

return p