Module:Challenges

---	Challlenges stores details of Risk of Rain 2's achievements. --	--	@module		challenges --	@alias		p --	@author		Paradoxzyx --	@require	Module:Challenges/Data --	@release	stable -- local p = {}

local data = require("Module:Challenges/Data") local all_challenges = data.challenges

-- Infobox local infobox_template = [=[ ]=]

---	Builds infobox for challenge article. --	@function		p.Infobox --	@param			{table} frame Frame object w/ the first argument being challenge name --	@return			{string} Preprocessed wikitext of infobox function p.Infobox(frame) local challenge_name = frame.args[1] ~= "" and frame.args[1] or mw.title.getCurrentTitle.text -- HARDCODED for [REDACTED] if challenge_name == "REDACTED" then challenge_name = "[" .. challenge_name .. "]" end local challenge = all_challenges[challenge_name] -- unlock" .. i .. " =, [ [" .. v .. "] ]" 	else  	  unlocks = unlocks " = [ [" .. v .. "] ]"    end  end  -- return frame:preprocess(infobox_template:format( challenge_name, Description(challenge.Desc:gsub("\u(%x%x%x%x)", function(s) return mw.ustring.char(tonumber(s, 16)) end)), #challenge.Unlock == 1 and (challenge_name:match(":") and "2 = " .. challenge.Unlock[1] .. "\r\n| image = " .. challenge.Unlock[1]:gsub(":", "") .. ".png" or " = " .. challenge.Unlock[1]) or "2 = " .. challenge.Unlock[1] .. " & " .. challenge.Unlock[2] .. "\r\n| image = " .. challenge.Unlock[1] .. ".png\r\n| image2 = " .. challenge.Unlock[2] .. ".png" -- above line: made to handle the way Template:Challenge was converted from fandom to GP -- the template, way the template is used & code could be cleaned up but it's not broken, just ugly, like me )) end

-- Unlock -- unlock_base = standard unlock -- unlock_base_alt = challenges whose unlock does not have it's own page (Skills, Skins, Artifacts) -- unlock_two = wrapper for unlock_base for challenges with two unlocks (Runald & Kjaro, Heresy) local unlock_base = "%s" local unlock_base_alt = "%s" local unlock_two = "%s %s "

---	Builds the unlock string for the challenge. --	@function		Unlock --	@param			{table} u Array of names of things that are unlocked by completing challenge --	@param			{string} type The challenge type (e.g. "Skills") --	@param			{string} name Name of challenge --	@return			{string} Unlock string --	@local function Unlock(u, type, name) local unlock if type == "Skills" then local s = name:gsub(": .+", "#" .. u[1]) unlock = unlock_base_alt:format(u[1]:gsub(":", ""), s, s, u[1]) elseif type == "Skins" then local s = name:gsub(": .+", "#Gallery") unlock = unlock_base_alt:format(u[1], s, s, u[1]) elseif type == "Artifacts" then unlock = unlock_base_alt:format(u[1], "Artifacts", "Artifacts", u[1]) elseif #u == 1 then unlock = unlock_base:format(u[1], u[1], u[1]) else unlock = unlock_two:format(unlock_base:format(u[1], u[1], u[1]), unlock_base:format(u[2], u[2], u[2])) end return unlock end

-- Table local table_head = [=[ {| class="article-table sortable floatheader" style="width:100%;max-width:900px" ! style="width:20%" | Challenge ! class="unsortable" | Description ! style="width:20%" | Unlocks ]=]

local table_row = [=[ ]=]
 * %s
 * %s
 * style="text-align:center;white-space:nowrap" data-sort-value="%s" | %s
 * style="text-align:center;white-space:nowrap" data-sort-value="%s" | %s

---	Builds the wikitable for a challenge type as seen on Challenges. --	@function		p.Table --	@param			{table} frame Frame object w/ the first argument being the challenge type --							Possible values (case-sensitive): "Survivors", "Items", "Equipment", "Skills", "Skins", "Artifacts" --	@return			{string} Preprocessed wikitext of wikitable function p.Table(frame) local type = frame.args[1] local wikitable = table_head local t = type == "Skins" or type == "Artifacts" for i, challenge in ipairs(Sort(all_challenges)) do   if challenge.Type == type then wikitable = wikitable .. table_row:format(       -- HARDCODED for [REDACTED]        t and challenge.Name or "[%1]") .. "",        Description(challenge.Desc),        challenge.Unlock[1], Unlock(challenge.Unlock, type, challenge.Name)      ) end end return frame:preprocess(wikitable .. "|}") end

-- Description local link_patterns = {} link_patterns["Abandoned Aqueduct"] = { "Abandoned Aqueduct" } link_patterns["Planetarium"] = { "The Planetarium" } link_patterns["Rallypoint Delta"] = { "Rallypoint Delta" } link_patterns["Scorched Acres"] = { "Scorched Acres" } link_patterns["Siren's Call"] = { "Siren's Call" } link_patterns["Sky Meadow"] = { "Sky Meadow" } link_patterns["Void Fields"] = { "Void Fields" } link_patterns["Gilded Coast"] = { "Gilded Coast" }

link_patterns["Wetland Aspect#Altar to N'kuhana"] = { "Altar to N'kuhana" } link_patterns["A Moment, Fractured#Obelisk"] = { "Obelisk" } link_patterns["Bazaar Between Time#Survivor Suspended In Time"] = { "survivor suspended in time" }

link_patterns["Teleporter#Teleporter Event"] = { "Teleporter" } link_patterns["Interactibles#Drones"] = { "[Dd]rones?" } link_patterns["TC-280 Prototype"] = { "TC%-280 Prototype" } link_patterns["3D Printers"] = { "3D Printer" } link_patterns["Newt Altars"] = { "Newt Altars?" } link_patterns["Movement Speed"] = { "[Mm]ovespeed" } link_patterns["Prismatic Trial"] = { "Prismatic Trial" }

link_patterns["Items#Active Items"] = { "Equipment" } link_patterns["Items#Lunar"] = { "Lunar items" } link_patterns["Crowbar"] = { "Crowbars" } link_patterns["Fuel Array"] = { "Fuel Array" } link_patterns["Preon Accumulator"] = { "Preon Accumulator" }

link_patterns["Monsters#Bosses"] = { "[Bb]oss monsters?" } link_patterns["Hermit Crab"] = { "Hermit Crabs" } link_patterns["Beetle Queen"] = { "Beetle Queens?" } link_patterns["Clay Dunestrider"] = { "Clay Dunestrider" } link_patterns["Imp Overlord"] = { "Imp Overlord" } link_patterns["Overloading Worm"] = { "Overloading Worm" } link_patterns["Scavenger"] = { "Scavenger" }

link_patterns["Shrine of Chance"] = { "Shrine of Chance" } link_patterns["Shrine of Combat"] = { "Combat Shrines" } link_patterns["Shrine of the Mountain"] = { "Shrines of the Mountain" } link_patterns["Shrine of the Woods"] = { "Shrine of the Woods" }

---	Formats the challenge description, adding wikilinks based on `link_patterns`. --	@function		Description --	@param			{string} desc Raw challenge description --	@return			{string} Formatted challenge description function Description(desc) desc = desc:gsub("\u(%x%x%x%x)", function(s) return mw.ustring.char(tonumber(s, 16)) end) for link, patterns in pairs(link_patterns) do   for i, v in ipairs(patterns) do      local a, b = desc:find(v) if a then desc = desc:sub(1, a - 1) .. "" .. desc:sub(a, b) .. "" .. desc:sub(b + 1, desc:len) break end end end return desc end

-- Desc ---	Returns the challenge description. --	@function		p.Desc --	@param			{table} frame Frame object w/ the first argument being the challenge name --	@return			{string} Formatted challenge description function p.Desc(frame) return Description(all_challenges[frame.args[1]].Desc) end

-- Sort ---	Sorts challenges by name in ascending order. --	@function		Sort --	@param			{table} list A map of challenge names mapped to their challenge database entry --	@return			{table} Sorted challenges map function Sort(list) local challenges = {} for name, challenge in pairs(list) do   challenge.Name = name table.insert(challenges, challenge) end table.sort(challenges, function(a, b) return a.Name < b.Name end) return challenges end

return p --