Module:Sandbox/AttemptToCallNil

local p = {} local h = {}

-- 1) name; 2) top row color local locations = { {'921 Hoadly Garden', '#303B83'}, {'921 Hoadly Bathtub', '#303B83'}, {'1001 Hoadly Gazebo', '#252D6F'}, {'1003 Hoadly Closet', '#252D6F'}, {'Campfire', '#252D6F'}, {'1005 Hoadly Porch', '#252D6F'}, {'Old Growth Pathway', '#1F2560'}, {'Old Growth Basement', '#1F2560'}, {'Old Growth Cliff', '#1F2560'}, {'Old Growth Branches', '#1F2560'}, {'Dream Therapy Classroom', '#1F2560'}, {'Dream Therapy Ledge', '#1F2560'}, {'Somniloquy Light Fixture', '#1F2560'}, {'Dream Therapy Pipe', '#1F2560'}, {'String Relay Shelf', '#252D6F'}, {'Signal Relay Rafters (Right)', '#1F2560'}, {'Signal Relay Rafters (Left)', '#1F2560'}, {'Barracks Pipe', '#1F2560'}, {'Film Archives Shelf', '#1F2560'}, {'New Growth Floor', '#252D6F'}, {'Underneath Somniloquy', '#1F2560'}, {'The Twist Pillar', '#252D6F'}, {'Nerve Centre Beam', '#303B83'}, {'Sleeper Lockers Beam', '#303B83'}, {'Cryptogram Library Walkway', '#303B83'}, {'Instrument Supply Rafter', '#303B83'}, {'920 Observation Rafter', '#303B83'}, } local ciphers = {'TheCall', 'Gorgon', 'TheHunger', 'NoMoreShadows', 'PaperAngels'}

-- Taken a module argument with the row data as a string, processes them, and -- returns a table with the following fields: -- • locations: maps location numbers to the numeric ID of the type of cipher --  found there. -- • givesHalo: true/false if the conditions for the Halo (4 unique ciphers) are --  met. -- • numCiphers: 1..4 for valid input. function h.processRow(row) local rowData = { locations = {}, givesHalo = true, numCiphers = 0 }	local knownCiphers = {} for location, cipher in string.gmatch(row, "(%d+):(%d+)") do

local location = tonumber(location) local cipher = tonumber(cipher) if cipher <= #ciphers then rowData.numCiphers = rowData.numCiphers + 1 end rowData.locations[location] = cipher if knownCiphers[cipher] then rowData.givesHalo = false -- duplicate else knownCiphers[cipher] = true end end if rowData.numCiphers < 4 then rowData.givesHalo = false -- not enough ciphers end return rowData end

-- Styles for header cells. Might be better as classes. local headerCellStyle = 'style="min-width:35px; padding-right: 0; background-image:none !important;"' local headerCellStyle2 = 'style="min-width:35px; padding-right: 0; background-image:none !important; background-color:%s; position:relative;"' local headerSpanStyle = 'style="writing-mode: sideways-lr; white-space: nowrap; min-width: 20px;"' local headerDivStyle = 'style="position:absolute; top:2px; right:2px; font-size:9px; writing-mode: sideways-lr;"' -- Makes the header for the table and returns it as a string. function h.makeHeader local result = { '{| border="1" style="border-collapse:collapse;" cellpadding="2" class="sortable"', string.format('! %s | Game No. ', headerCellStyle, headerSpanStyle), string.format('! %s | Cipher Count ', headerCellStyle, headerSpanStyle) }	for locationNumber, locationData in ipairs(locations) do		local locationName = locationData[1] local cellStyle = headerCellStyle2:format(locationData[2]) result[#result + 1] = string.format("! %s | %s %d ",			cellStyle, headerSpanStyle, locationName, headerDivStyle, locationNumber) end return table.concat(result, '\n') end

local haloStyleRaw = 'background:linear-gradient(35deg, #BF953F, #FCF6BA, #B38728, #FBF5B7, #AA771C); color:#000;' local haloStyle = string.format('style="%s"', haloStyleRaw) local backgroundColorFormat = 'background-color:#%s;' local cipherFileFormat = '' -- Given a row, makes it into a string. function h.makeRow(rowNumber, rowData) local rowHeaderHaloStyle = rowData.givesHalo and haloStyle or '' local result = { '|- style="text-align: center;"', string.format('! %s | %d', rowHeaderHaloStyle, rowNumber), string.format('| %s | %d', rowHeaderHaloStyle, rowData.numCiphers) }	for locationNumber = 1, #locations do		local locationCipher = rowData.locations[locationNumber] local content = '✘' local backgroundColor = 'c00' local icon = '' local rowHaloStyle = '' if locationCipher == #ciphers + 1 then content = '❓' backgroundColor = '50c' elseif locationCipher then content = '✔' backgroundColor = '0c0' icon = cipherFileFormat:format(ciphers[locationCipher]) rowHaloStyle = rowData.givesHalo and haloStyleRaw or '' end local backgroundStyle = string.format('background-color:#%s;', backgroundColor) local style = string.format('style="%s%s"', backgroundStyle, rowHaloStyle) result[#result + 1] = string.format("| %s | %s%s", style, content, icon) end return table.concat(result, '\n') end

-- Given a list of rows, translates it into one string that has them all processed. function h.makeRows(data) local rows = {} for rowNumber, rowData in ipairs(data) do		rows[rowNumber] = h.makeRow(rowNumber, rowData) end return table.concat(rows, '\n') end

-- Entry point for Lua modules and the debug console. function p._table(args) local data = {} for i, rowData in ipairs(args) do		data[i] = h.processRow(rowData) end return table.concat({h.makeHeader, h.makeRows(data), '|}'}, '\n') end

-- Entry point for #invoke. function p.table(f) local args = require("Module:Arguments").getArgs(f, {parentFirst=true}) return p._table(args) end

return p